From ebf726190861ea973045be9934cc6d625b1b8455 Mon Sep 17 00:00:00 2001
From: Jason Hiser <jdhiser@gmail.com>
Date: Mon, 17 Dec 2018 20:09:43 -0500
Subject: [PATCH] rearranging for arm

Former-commit-id: 344772f2b5fd06f97f53b1e066ccd8cd005bd6c0
---
 libEXEIO/include/exeio.h                      |   3 +
 libEXEIO/{include => src}/exeio_elf.h         |  17 +-
 libEXEIO/{include => src}/exeio_pe.h          |   5 +
 libIRDB/include/core/archdesc.hpp             |  21 +-
 libIRDB/include/core/decode.hpp               |  26 +-
 libIRDB/include/core/decode_bea.hpp           |  62 ----
 .../core/{decode_cs.hpp => decode_csx86.hpp}  |  28 +-
 libIRDB/include/core/decode_dispatch.hpp      |  63 ++++
 libIRDB/include/core/decode_meta.hpp          |  66 -----
 libIRDB/include/core/fileir.hpp               |   2 +-
 libIRDB/include/core/operand_bea.hpp          |  59 ----
 .../{operand_cs.hpp => operand_csx86.hpp}     |  14 +-
 ...{operand_meta.hpp => operand_dispatch.hpp} |  25 +-
 libIRDB/src/core/SConscript                   |   8 +-
 libIRDB/src/core/decode_bea.cpp               | 280 ------------------
 .../core/{decode_cs.cpp => decode_csx86.cpp}  |  66 ++---
 libIRDB/src/core/decode_dispatch.cpp          | 106 +++++++
 libIRDB/src/core/decode_meta.cpp              | 167 -----------
 libIRDB/src/core/fileir.cpp                   |  38 ++-
 libIRDB/src/core/operand_bea.cpp              | 258 ----------------
 .../{operand_cs.cpp => operand_csx86.cpp}     |  82 ++---
 ...{operand_meta.cpp => operand_dispatch.cpp} |  29 +-
 tools/rida/rida.cpp                           |  79 +++--
 xform/elfreader.cpp                           |   6 +-
 xform/elfreader.h                             |  50 ++--
 xform/rewriter.cpp                            |   3 +
 26 files changed, 467 insertions(+), 1096 deletions(-)
 rename libEXEIO/{include => src}/exeio_elf.h (90%)
 rename libEXEIO/{include => src}/exeio_pe.h (98%)
 delete mode 100644 libIRDB/include/core/decode_bea.hpp
 rename libIRDB/include/core/{decode_cs.hpp => decode_csx86.hpp} (69%)
 create mode 100644 libIRDB/include/core/decode_dispatch.hpp
 delete mode 100644 libIRDB/include/core/decode_meta.hpp
 delete mode 100644 libIRDB/include/core/operand_bea.hpp
 rename libIRDB/include/core/{operand_cs.hpp => operand_csx86.hpp} (75%)
 rename libIRDB/include/core/{operand_meta.hpp => operand_dispatch.hpp} (62%)
 delete mode 100644 libIRDB/src/core/decode_bea.cpp
 rename libIRDB/src/core/{decode_cs.cpp => decode_csx86.cpp} (87%)
 create mode 100644 libIRDB/src/core/decode_dispatch.cpp
 delete mode 100644 libIRDB/src/core/decode_meta.cpp
 delete mode 100644 libIRDB/src/core/operand_bea.cpp
 rename libIRDB/src/core/{operand_cs.cpp => operand_csx86.cpp} (88%)
 rename libIRDB/src/core/{operand_meta.cpp => operand_dispatch.cpp} (63%)

diff --git a/libEXEIO/include/exeio.h b/libEXEIO/include/exeio.h
index 1380e42ff..b434d90f2 100644
--- a/libEXEIO/include/exeio.h
+++ b/libEXEIO/include/exeio.h
@@ -13,6 +13,7 @@ namespace EXEIO
 	class exeio_t; // forward decl
 
 	typedef enum { ELF64, ELF32, PE32, PE64 } execlass_t;
+	typedef enum {  mtX86_64, mtI386, mtArm32, mtAarch64 } MachineType_t; 
 
 	typedef uintptr_t virtual_offset_t;
 
@@ -46,6 +47,7 @@ namespace EXEIO
 			virtual void dump_section_headers(std::ostream& stream) =0;
 			virtual void load(exeio_t* main, const char* filename) =0;
                         virtual execlass_t get_class() =0;
+                        virtual MachineType_t getMachineType() const =0;
 			virtual virtual_offset_t get_entry() =0;
 			virtual void* get_elfio() { return NULL; }
 			virtual bool isDLL() =0;
@@ -116,6 +118,7 @@ namespace EXEIO
 			virtual void dump_header(std::ostream& stream) { assert(backend); backend->dump_header(stream); }
 			virtual void dump_section_headers(std::ostream& stream) { assert(backend); backend->dump_section_headers(stream); }
                         virtual execlass_t get_class() { assert(backend); return backend->get_class(); }
+                        virtual MachineType_t getMachineType() const { assert(backend); return backend->getMachineType(); }
 			virtual void* get_elfio() { assert(backend); return backend->get_elfio(); }
 			virtual bool isDLL() { assert(backend); return backend->isDLL(); }
 			virtual bool isDynamicallyLinked() { assert(backend); return backend->isDynamicallyLinked(); }
diff --git a/libEXEIO/include/exeio_elf.h b/libEXEIO/src/exeio_elf.h
similarity index 90%
rename from libEXEIO/include/exeio_elf.h
rename to libEXEIO/src/exeio_elf.h
index 0b3dd175a..6b2ae5a6e 100644
--- a/libEXEIO/include/exeio_elf.h
+++ b/libEXEIO/src/exeio_elf.h
@@ -5,17 +5,15 @@
 #include <vector>
 #include <assert.h>
 
-
-// #include "targ-config.h"
 #pragma GCC diagnostic ignored "-Wsign-compare"
 #include "elfio/elfio.hpp"
 #include "elfio/elfio_dump.hpp"
+#include "elf.h"
 #pragma GCC diagnostic pop
 
 class exeio_backend;
 class exeio_section;
 
-
 namespace EXEIO
 {
 	class exeio_elf_section_t : public exeio_section_t
@@ -94,6 +92,19 @@ namespace EXEIO
 					default: assert(0);
 				};
 			}
+			virtual MachineType_t getMachineType() const
+			{
+				assert(e);
+				switch(e->get_machine())
+				{
+					case EM_ARM	: return mtArm32;
+					case EM_AARCH64	: return mtAarch64;
+					case EM_386     : return mtI386;
+					case EM_X86_64	: return mtX86_64;
+					default: assert(0);
+				}
+				assert(0);
+			}
 
 			// get entry point of function.
                         virtual virtual_offset_t get_entry()
diff --git a/libEXEIO/include/exeio_pe.h b/libEXEIO/src/exeio_pe.h
similarity index 98%
rename from libEXEIO/include/exeio_pe.h
rename to libEXEIO/src/exeio_pe.h
index 78f78d619..f4ab2eff6 100644
--- a/libEXEIO/include/exeio_pe.h
+++ b/libEXEIO/src/exeio_pe.h
@@ -129,6 +129,11 @@ namespace EXEIO
                 		}
 
 			}
+			virtual MachineType_t getMachineType() const
+			{
+				assert(0);
+			}
+
                         virtual execlass_t get_class() 
 			{
 				assert(e);
diff --git a/libIRDB/include/core/archdesc.hpp b/libIRDB/include/core/archdesc.hpp
index 89c2b40e1..dc84aee5d 100644
--- a/libIRDB/include/core/archdesc.hpp
+++ b/libIRDB/include/core/archdesc.hpp
@@ -19,23 +19,28 @@
  */
 
 
-enum AD_FileType_t { AD_ELF, AD_CGC, AD_PE };
+enum ADFileType_t { AD_ELF, AD_CGC, AD_PE, AD_NONE };
+enum ADMachineType_t { admtAarch64,  admtX86_64, admtI386, admtNone }; 
 
 class ArchitectureDescription_t
 {
 	public:
 
-	ArchitectureDescription_t() : bits(0) {}
+		ArchitectureDescription_t() : bits(0), ft(AD_NONE), mt(admtNone) {}
 
-	int GetBitWidth() 		{ return bits; }	
-	void SetBitWidth(int _bits) 	{ bits=_bits; }	
+		int GetBitWidth() const 		{ return bits; }	
+		void SetBitWidth(const int _bits) 	{ bits=_bits; }	
 
-	AD_FileType_t GetFileType() 		{ return ft; }	
-	void SetFileType(AD_FileType_t t) 	{ ft=t; }
+		ADFileType_t GetFileType() const	{ return ft; }	
+		void SetFileType(const ADFileType_t t) 	{ ft=t; }
+
+		ADMachineType_t getMachineType() const 		{ return mt; }	
+		void setMachineType(const ADMachineType_t t) 	{ mt=t; }
 
 	private:
 
-		int bits;
-		AD_FileType_t ft;
+		size_t bits;
+		ADFileType_t ft;
+		ADMachineType_t mt;
 };
 
diff --git a/libIRDB/include/core/decode.hpp b/libIRDB/include/core/decode.hpp
index 8a59d7d9a..c78aed0fc 100644
--- a/libIRDB/include/core/decode.hpp
+++ b/libIRDB/include/core/decode.hpp
@@ -1,18 +1,14 @@
 #ifndef libdecode_decode_hpp
 #define libdecode_decode_hpp
 
-#define USECS 
+#define USEMETA 
 
 #if defined(USEMETA)
-#include <core/decode_meta.hpp>
-#include <core/operand_meta.hpp>
+#include <core/decode_dispatch.hpp>
+#include <core/operand_dispatch.hpp>
 #elif defined(USECS)
-#include <core/decode_cs.hpp>
-#include <core/operand_cs.hpp>
-#elif defined(USEBEA)
-#include <core/decode_bea.hpp>
-#include <core/operand_bea.hpp>
-#else
+#include <core/decode_csx86.hpp>
+#include <core/operand_csx86.hpp>
 #pragma "Error:  Source did not adaquately specify a disassembler. "
 #endif
 
@@ -25,17 +21,13 @@ using namespace libIRDB;
 
 
 #if defined(USEMETA)
-typedef DecodedInstructionMeta_t DecodedInstruction_t;
-typedef DecodedOperandMeta_t DecodedOperand_t;
+typedef DecodedInstructionDispatcher_t DecodedInstruction_t;
+typedef DecodedOperandDispatcher_t DecodedOperand_t;
 typedef DecodedOperandMetaVector_t DecodedOperandVector_t;
 #elif defined(USECS)
-typedef DecodedInstructionCapstone_t DecodedInstruction_t;
-typedef DecodedOperandCapstone_t DecodedOperand_t;
+typedef DecodedInstructionCapstoneX86_t DecodedInstruction_t;
+typedef DecodedOperandCapstoneX86_t DecodedOperand_t;
 typedef DecodedOperandCapstoneVector_t DecodedOperandVector_t;
-#elif defined(USEBEA)
-typedef DecodedInstructionBea_t DecodedInstruction_t;
-typedef DecodedOperandBea_t DecodedOperand_t;
-typedef DecodedOperandBeaVector_t DecodedOperandVector_t;
 #else
 #pragma "Error:  Source did not adaquately specify a disassembler. "
 #endif
diff --git a/libIRDB/include/core/decode_bea.hpp b/libIRDB/include/core/decode_bea.hpp
deleted file mode 100644
index 800cdd625..000000000
--- a/libIRDB/include/core/decode_bea.hpp
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef libirdb_decodebea_hpp
-#define libirdb_decodebea_hpp
-
-#include <stdint.h>
-#include <vector>
-
-namespace libIRDB
-{
-
-using namespace libIRDB;
-using namespace std;
-
-class DecodedOperandBea_t;
-typedef std::vector<DecodedOperandBea_t> DecodedOperandBeaVector_t;
-
-class DecodedInstructionBea_t
-{
-	public:
-		DecodedInstructionBea_t()=delete;
-		DecodedInstructionBea_t(const Instruction_t*);
-		DecodedInstructionBea_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len);
-		DecodedInstructionBea_t(const virtual_offset_t start_addr, const void *data, const void* endptr);
-		DecodedInstructionBea_t(const DecodedInstructionBea_t& copy);
-		DecodedInstructionBea_t& operator=(const DecodedInstructionBea_t& copy);
-
-		virtual ~DecodedInstructionBea_t();
-
-		string getDisassembly() const;
-		bool valid() const;
-		uint32_t length() const;
-		bool isBranch() const;
-		bool isCall() const;
-		bool isUnconditionalBranch() const;
-		bool isConditionalBranch() const;
-		bool isReturn() const;
-		string getMnemonic() const;
-		int64_t getImmediate() const;
-		virtual_offset_t getAddress() const;
-		bool setsStackPointer() const;
-		uint32_t getPrefixCount() const;
-		bool hasRelevantRepPrefix() const;
-		bool hasRelevantRepnePrefix() const;
-		bool hasRelevantOperandSizePrefix() const;
-		bool hasRexWPrefix() const;
-		bool hasImplicitlyModifiedRegs() const;
-		virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandBea_t& t, const libIRDB::Instruction_t*) const;
-
-		// 0-based.  first operand is numbered 0.
-		bool hasOperand(const int op_num) const;
-		DecodedOperandBea_t getOperand(const int op_num) const;
-		DecodedOperandBeaVector_t getOperands() const;
-
-	private:
-
-		void Disassemble(const virtual_offset_t start_addr, const void *, uint32_t max_len);
-		void *disasm_data;
-		uint32_t disasm_length;
-};
-
-}
-
-#endif
diff --git a/libIRDB/include/core/decode_cs.hpp b/libIRDB/include/core/decode_csx86.hpp
similarity index 69%
rename from libIRDB/include/core/decode_cs.hpp
rename to libIRDB/include/core/decode_csx86.hpp
index efc713238..6579af621 100644
--- a/libIRDB/include/core/decode_cs.hpp
+++ b/libIRDB/include/core/decode_csx86.hpp
@@ -11,20 +11,20 @@ namespace libIRDB
 using namespace libIRDB;
 using namespace std;
 
-class DecodedOperandCapstone_t;
-typedef std::vector<DecodedOperandCapstone_t> DecodedOperandCapstoneVector_t;
+class DecodedOperandCapstoneX86_t;
+typedef std::vector<DecodedOperandCapstoneX86_t> DecodedOperandCapstoneVector_t;
 
-class DecodedInstructionCapstone_t
+class DecodedInstructionCapstoneX86_t
 {
 	public:
-		DecodedInstructionCapstone_t()=delete;
-		DecodedInstructionCapstone_t(const Instruction_t*);
-		DecodedInstructionCapstone_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len);
-		DecodedInstructionCapstone_t(const virtual_offset_t start_addr, const void *data, const void* endptr);
-		DecodedInstructionCapstone_t(const DecodedInstructionCapstone_t& copy);
-		DecodedInstructionCapstone_t& operator=(const DecodedInstructionCapstone_t& copy);
+		DecodedInstructionCapstoneX86_t()=delete;
+		DecodedInstructionCapstoneX86_t(const Instruction_t*);
+		DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len);
+		DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, const void* endptr);
+		DecodedInstructionCapstoneX86_t(const DecodedInstructionCapstoneX86_t& copy);
+		DecodedInstructionCapstoneX86_t& operator=(const DecodedInstructionCapstoneX86_t& copy);
 
-		virtual ~DecodedInstructionCapstone_t();
+		virtual ~DecodedInstructionCapstoneX86_t();
 
 		string getDisassembly() const;
 		bool valid() const;
@@ -44,11 +44,11 @@ class DecodedInstructionCapstone_t
 		bool hasRelevantOperandSizePrefix() const;
 		bool hasRexWPrefix() const;
 		bool hasImplicitlyModifiedRegs() const;
-		virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t, const Instruction_t* insn) const;
+		virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandCapstoneX86_t& t, const Instruction_t* insn) const;
 
 		// 0-based.  first operand is numbered 0.
 		bool hasOperand(const int op_num) const;
-		DecodedOperandCapstone_t getOperand(const int op_num) const;
+		DecodedOperandCapstoneX86_t getOperand(const int op_num) const;
 		DecodedOperandCapstoneVector_t getOperands() const;
 
 	private:
@@ -89,9 +89,9 @@ class DecodedInstructionCapstone_t
 		static CapstoneHandle_t *cs_handle;
 
 
-		friend class DecodedOperandCapstone_t;
+		friend class DecodedOperandCapstoneX86_t;
 
-		DecodedInstructionCapstone_t(const shared_ptr<void> &my_insn);
+		DecodedInstructionCapstoneX86_t(const shared_ptr<void> &my_insn);
 
 };
 
diff --git a/libIRDB/include/core/decode_dispatch.hpp b/libIRDB/include/core/decode_dispatch.hpp
new file mode 100644
index 000000000..f201881fe
--- /dev/null
+++ b/libIRDB/include/core/decode_dispatch.hpp
@@ -0,0 +1,63 @@
+#ifndef libirdb_decode_dispatch_hpp
+#define libirdb_decode_dispatch_hpp
+
+#include <stdint.h>
+#include <vector>
+#include <core/decode_csx86.hpp>
+#include <core/operand_csx86.hpp>
+
+namespace libIRDB
+{
+
+using namespace libIRDB;
+using namespace std;
+
+class DecodedOperandDispatcher_t;
+typedef std::vector<DecodedOperandDispatcher_t> DecodedOperandMetaVector_t;
+
+class DecodedInstructionDispatcher_t
+{
+	public:
+		DecodedInstructionDispatcher_t()=delete;
+		DecodedInstructionDispatcher_t(const Instruction_t*);
+		DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len);
+		DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, const void* endptr);
+		DecodedInstructionDispatcher_t(const DecodedInstructionDispatcher_t& copy);
+		DecodedInstructionDispatcher_t& operator=(const DecodedInstructionDispatcher_t& copy);
+
+		virtual ~DecodedInstructionDispatcher_t();
+
+		string getDisassembly() const;
+		bool valid() const;
+		uint32_t length() const;
+		bool isBranch() const;
+		bool isCall() const;
+		bool isUnconditionalBranch() const;
+		bool isConditionalBranch() const;
+		bool isReturn() const;
+		string getMnemonic() const;
+		int64_t getImmediate() const;
+		virtual_offset_t getAddress() const;
+		bool setsStackPointer() const;
+		uint32_t getPrefixCount() const;
+		bool hasRelevantRepPrefix() const;
+		bool hasRelevantRepnePrefix() const;
+		bool hasRelevantOperandSizePrefix() const;
+		bool hasRexWPrefix() const;
+		bool hasImplicitlyModifiedRegs() const;
+		virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandDispatcher_t& t, const Instruction_t* insn) const;
+
+		// 0-based.  first operand is numbered 0.
+		bool hasOperand(const int op_num) const;
+		DecodedOperandDispatcher_t getOperand(const int op_num) const;
+		DecodedOperandMetaVector_t getOperands() const;
+
+	private:
+
+		std::unique_ptr<DecodedInstructionCapstoneX86_t> cs;
+
+};
+
+}
+
+#endif
diff --git a/libIRDB/include/core/decode_meta.hpp b/libIRDB/include/core/decode_meta.hpp
deleted file mode 100644
index fe62bb089..000000000
--- a/libIRDB/include/core/decode_meta.hpp
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef libirdb_decodemeta_hpp
-#define libirdb_decodemeta_hpp
-
-#include <stdint.h>
-#include <vector>
-#include <core/decode_bea.hpp>
-#include <core/operand_bea.hpp>
-#include <core/decode_cs.hpp>
-#include <core/operand_cs.hpp>
-
-namespace libIRDB
-{
-
-using namespace libIRDB;
-using namespace std;
-
-class DecodedOperandMeta_t;
-typedef std::vector<DecodedOperandMeta_t> DecodedOperandMetaVector_t;
-
-class DecodedInstructionMeta_t
-{
-	public:
-		DecodedInstructionMeta_t()=delete;
-		DecodedInstructionMeta_t(const Instruction_t*);
-		DecodedInstructionMeta_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len);
-		DecodedInstructionMeta_t(const virtual_offset_t start_addr, const void *data, const void* endptr);
-		DecodedInstructionMeta_t(const DecodedInstructionMeta_t& copy);
-		DecodedInstructionMeta_t& operator=(const DecodedInstructionMeta_t& copy);
-
-		virtual ~DecodedInstructionMeta_t();
-
-		string getDisassembly() const;
-		bool valid() const;
-		uint32_t length() const;
-		bool isBranch() const;
-		bool isCall() const;
-		bool isUnconditionalBranch() const;
-		bool isConditionalBranch() const;
-		bool isReturn() const;
-		string getMnemonic() const;
-		int64_t getImmediate() const;
-		virtual_offset_t getAddress() const;
-		bool setsStackPointer() const;
-		uint32_t getPrefixCount() const;
-		bool hasRelevantRepPrefix() const;
-		bool hasRelevantRepnePrefix() const;
-		bool hasRelevantOperandSizePrefix() const;
-		bool hasRexWPrefix() const;
-		bool hasImplicitlyModifiedRegs() const;
-		virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandMeta_t& t, const Instruction_t* insn) const;
-
-		// 0-based.  first operand is numbered 0.
-		bool hasOperand(const int op_num) const;
-		DecodedOperandMeta_t getOperand(const int op_num) const;
-		DecodedOperandMetaVector_t getOperands() const;
-
-	private:
-
-		DecodedInstructionBea_t bea;
-		DecodedInstructionCapstone_t cs;
-
-};
-
-}
-
-#endif
diff --git a/libIRDB/include/core/fileir.hpp b/libIRDB/include/core/fileir.hpp
index d0b70244b..c61fe787f 100644
--- a/libIRDB/include/core/fileir.hpp
+++ b/libIRDB/include/core/fileir.hpp
@@ -92,7 +92,7 @@ class FileIR_t : public BaseObj_t
 		void ChangeRegistryKey(Instruction_t* orig, Instruction_t* updated);
 
 		static int GetArchitectureBitWidth() ;
-		static void SetArchitectureBitWidth(const int width);
+		static void SetArchitecture(const int width, const ADMachineType_t mt);
 		void SetArchitecture();
 
 		// Lookup a scoop by address
diff --git a/libIRDB/include/core/operand_bea.hpp b/libIRDB/include/core/operand_bea.hpp
deleted file mode 100644
index 2650a1865..000000000
--- a/libIRDB/include/core/operand_bea.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef libRIDB_decodedoperandbea_hpp
-#define libRIDB_decodedoperandbea_hpp
-
-namespace libIRDB
-{
-
-using namespace std;
-using namespace libIRDB;
-
-
-class DecodedOperandBea_t
-{
-	public:
-		DecodedOperandBea_t() =delete;
-		DecodedOperandBea_t& operator=(const DecodedOperandBea_t& copy);
-		DecodedOperandBea_t(const DecodedOperandBea_t& copy);
-		virtual ~DecodedOperandBea_t();
-
-		bool isConstant() const;
-		string getString() const;
-		bool isRegister() const;
-		bool isGeneralPurposeRegister() const;
-		bool isMmxRegister() const;
-		bool isFpuRegister() const;
-		bool isSseRegister() const;
-		bool isAvxRegister() const;
-		bool isSpecialRegister() const;
-		bool isSegmentRegister() const;
-		uint32_t getRegNumber() const;
-		bool isMemory() const;
-		bool hasSegmentRegister() const;
-		uint32_t getSegmentRegister() const;
-		bool hasBaseRegister() const;
-		bool hasIndexRegister() const;
-		uint32_t getBaseRegister() const;
-		uint32_t getIndexRegister() const;
-		bool hasMemoryDisplacement() const;
-		virtual_offset_t getMemoryDisplacement() const;
-		bool isPcrel() const;
-		uint32_t getScaleValue() const;
-		uint32_t getMemoryDisplacementEncodingSize() const;
-		uint32_t getArgumentSizeInBytes() const;
-		uint32_t getArgumentSizeInBits() const;
-		bool isRead() const; 
-		bool isWritten() const; 
-
-
-	private:
-
-
-		void* arg_data;
-		DecodedOperandBea_t(void* arg_p);
-
-		friend class DecodedInstructionBea_t;
-
-};
-
-}
-#endif
diff --git a/libIRDB/include/core/operand_cs.hpp b/libIRDB/include/core/operand_csx86.hpp
similarity index 75%
rename from libIRDB/include/core/operand_cs.hpp
rename to libIRDB/include/core/operand_csx86.hpp
index 0d4e5e78b..712461d1e 100644
--- a/libIRDB/include/core/operand_cs.hpp
+++ b/libIRDB/include/core/operand_csx86.hpp
@@ -9,13 +9,13 @@ using namespace std;
 using namespace libIRDB;
 
 
-class DecodedOperandCapstone_t
+class DecodedOperandCapstoneX86_t
 {
 	public:
-		DecodedOperandCapstone_t() =delete;
-		//DecodedOperandCapstone_t& operator=(const DecodedOperandCapstone_t& copy);
-		//DecodedOperandCapstone_t(const DecodedOperandCapstone_t& copy);
-		virtual ~DecodedOperandCapstone_t();
+		DecodedOperandCapstoneX86_t() =delete;
+		//DecodedOperandCapstoneX86_t& operator=(const DecodedOperandCapstoneX86_t& copy);
+		//DecodedOperandCapstoneX86_t(const DecodedOperandCapstoneX86_t& copy);
+		virtual ~DecodedOperandCapstoneX86_t();
 
 		bool isConstant() const;
 		uint64_t getConstant() const;
@@ -50,12 +50,12 @@ class DecodedOperandCapstone_t
 
 	private:
 
-		DecodedOperandCapstone_t( const shared_ptr<void> &my_insn, uint8_t op_num);
+		DecodedOperandCapstoneX86_t( const shared_ptr<void> &my_insn, uint8_t op_num);
 
 		shared_ptr<void> my_insn;
 		uint8_t op_num;
 
-		friend class DecodedInstructionCapstone_t;
+		friend class DecodedInstructionCapstoneX86_t;
 
 };
 
diff --git a/libIRDB/include/core/operand_meta.hpp b/libIRDB/include/core/operand_dispatch.hpp
similarity index 62%
rename from libIRDB/include/core/operand_meta.hpp
rename to libIRDB/include/core/operand_dispatch.hpp
index 38080e08f..6fee67bcd 100644
--- a/libIRDB/include/core/operand_meta.hpp
+++ b/libIRDB/include/core/operand_dispatch.hpp
@@ -1,8 +1,8 @@
-#ifndef libRIDB_decodedoperandmeta_hpp
-#define libRIDB_decodedoperandmeta_hpp
+#ifndef libRIDB_decodedoperand_dispatch_hpp
+#define libRIDB_decodedoperand_dispatch_hpp
 
-#include <core/decode_bea.hpp>
-#include <core/operand_bea.hpp>
+#include <core/decode_csx86.hpp>
+#include <core/operand_csx86.hpp>
 namespace libIRDB
 {
 
@@ -10,15 +10,16 @@ using namespace std;
 using namespace libIRDB;
 
 
-class DecodedOperandMeta_t
+class DecodedOperandDispatcher_t
 {
 	public:
-		DecodedOperandMeta_t() =delete;
-		DecodedOperandMeta_t& operator=(const DecodedOperandMeta_t& copy);
-		DecodedOperandMeta_t(const DecodedOperandMeta_t& copy);
-		virtual ~DecodedOperandMeta_t();
+		DecodedOperandDispatcher_t() =delete;
+		DecodedOperandDispatcher_t& operator=(const DecodedOperandDispatcher_t& copy);
+		DecodedOperandDispatcher_t(const DecodedOperandDispatcher_t& copy);
+		virtual ~DecodedOperandDispatcher_t();
 
 		bool isConstant() const;
+		uint64_t getConstant() const;
 		string getString() const;
 		bool isRegister() const;
 		bool isGeneralPurposeRegister() const;
@@ -48,11 +49,11 @@ class DecodedOperandMeta_t
 
 
 	private:
-		DecodedOperandMeta_t(const DecodedOperandCapstone_t& in);
+		DecodedOperandDispatcher_t(const DecodedOperandCapstoneX86_t& in);
 
-		DecodedOperandCapstone_t cs;
+		std::unique_ptr<DecodedOperandCapstoneX86_t> cs;
 
-		friend class DecodedInstructionMeta_t;
+		friend class DecodedInstructionDispatcher_t;
 
 };
 
diff --git a/libIRDB/src/core/SConscript b/libIRDB/src/core/SConscript
index b538b5836..101499941 100644
--- a/libIRDB/src/core/SConscript
+++ b/libIRDB/src/core/SConscript
@@ -23,15 +23,15 @@ files=  '''
 	variantid.cpp
 	eh.cpp
 	reloc.cpp
-	decode_cs.cpp
-	operand_cs.cpp
+	decode_csx86.cpp
+	operand_csx86.cpp
 	IRDB_Objects.cpp
+	decode_dispatch.cpp
+	operand_dispatch.cpp
 '''
 unused_files='''
 	decode_bea.cpp
 	operand_bea.cpp
-	decode_meta.cpp
-	operand_meta.cpp
 	'''
 
 # bea engine listed for core components.
diff --git a/libIRDB/src/core/decode_bea.cpp b/libIRDB/src/core/decode_bea.cpp
deleted file mode 100644
index 0b7fafb7a..000000000
--- a/libIRDB/src/core/decode_bea.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-
-#include <libIRDB-core.hpp>
-
-#include <bea_deprecated.hpp>
-#include <core/decode_bea.hpp>
-#include <core/operand_bea.hpp>
-
-using namespace libIRDB;
-using namespace std;
-
-// static functions
-static inline bool my_SetsStackPointer(const ARGTYPE* arg)
-{
-        if((arg->AccessMode & WRITE ) == 0)
-                return false;
-        int access_type=arg->ArgType;
-
-        if(access_type==REGISTER_TYPE + GENERAL_REG +REG4)
-                return true;
-        return false;
-
-}
-
-// constructors, destructors, operators.
-
-DecodedInstructionBea_t::DecodedInstructionBea_t(const Instruction_t* i)
-{
-	disasm_data=static_cast<void*>(new DISASM({}));
-	DISASM* d=(DISASM*)disasm_data;
-	disasm_length=::Disassemble(i,*d);
-}
-
-DecodedInstructionBea_t::DecodedInstructionBea_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len)
-{
-	disasm_data=static_cast<void*>(new DISASM({}));
-	const auto endptr=data+max_len;
-	Disassemble(start_addr, data, max_len);
-}
-
-DecodedInstructionBea_t::DecodedInstructionBea_t(const virtual_offset_t start_addr, const void *data, const void* endptr)
-{
-	disasm_data=static_cast<void*>(new DISASM({}));
-	const auto length=(char*)endptr-(char*)data + 1;
-	Disassemble(start_addr,data,length);
-}
-
-DecodedInstructionBea_t::DecodedInstructionBea_t(const DecodedInstructionBea_t& copy)
-{
-	DISASM* d=static_cast<DISASM*>(copy.disasm_data);
-	disasm_data=static_cast<void*>(new DISASM(*d));
-	disasm_length=copy.disasm_length;
-}
-
-DecodedInstructionBea_t::~DecodedInstructionBea_t()
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	delete d;
-	disasm_data=NULL;
-}
-
-DecodedInstructionBea_t& DecodedInstructionBea_t::operator=(const DecodedInstructionBea_t& copy)
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	delete d;
-	disasm_data=NULL;
-
-	d=static_cast<DISASM*>(copy.disasm_data);
-	disasm_data=static_cast<void*>(new DISASM(*d));
-	disasm_length=copy.disasm_length;
-	return *this;
-}
-
-// private methods
-
-void DecodedInstructionBea_t::Disassemble(const virtual_offset_t start_addr, const void *data, uint32_t max_len)
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	memset(d, 0, sizeof(DISASM));
-	d->Options = NasmSyntax + PrefixedNumeral;
-	d->Archi = FileIR_t::GetArchitectureBitWidth();
-	d->EIP = (UIntPtr)data;
-	d->SecurityBlock=max_len;
-	d->VirtualAddr = start_addr;
-	disasm_length=Disasm(d);
-
-}
-
-// public methods
-
-string DecodedInstructionBea_t::getDisassembly() const
-{
-	assert(valid());
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	return string(d->CompleteInstr);
-}
-
-bool DecodedInstructionBea_t::valid() const
-{
-	return disasm_length>=0;
-}
-
-uint32_t DecodedInstructionBea_t::length() const
-{
-	assert(valid());
-	return disasm_length;
-}
-
-
-bool DecodedInstructionBea_t::isBranch() const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	return d->Instruction.BranchType!=0;
-}
-
-bool DecodedInstructionBea_t::isCall() const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	return d->Instruction.BranchType==CallType;
-}
-
-bool DecodedInstructionBea_t::isUnconditionalBranch() const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	return d->Instruction.BranchType==JmpType;
-}
-
-bool DecodedInstructionBea_t::isConditionalBranch() const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	assert(0);
-}
-
-bool DecodedInstructionBea_t::isReturn() const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	return d->Instruction.BranchType==RetType;
-}
-
-
-bool DecodedInstructionBea_t::hasOperand(const int op_num) const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	switch(op_num+1)
-	{
-		case 1:
-			return d->Argument1.ArgType!=NO_ARGUMENT;
-		case 2:
-			return d->Argument2.ArgType!=NO_ARGUMENT;
-		case 3:
-			return d->Argument3.ArgType!=NO_ARGUMENT;
-		case 4:
-			return d->Argument4.ArgType!=NO_ARGUMENT;
-		default:
-			return false;
-	}
-}
-
-
-// 0-based.  first operand is numbered 0.
-DecodedOperandBea_t DecodedInstructionBea_t::getOperand(const int op_num) const
-{
-	if(!hasOperand(op_num))
-		throw std::out_of_range("op_num");
-
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	switch(op_num+1)
-	{
-		case 1:
-			return DecodedOperandBea_t(&d->Argument1);
-		case 2:
-			return DecodedOperandBea_t(&d->Argument2);
-		case 3:
-			return DecodedOperandBea_t(&d->Argument3);
-		case 4:
-			return DecodedOperandBea_t(&d->Argument4);
-	}
-}
-
-DecodedOperandBeaVector_t DecodedInstructionBea_t::getOperands() const
-{
-	auto ret_val=DecodedOperandBeaVector_t();
-	for(auto i=0;i<4;i++)
-	{
-		if(hasOperand(i))
-			ret_val.push_back(getOperand(i));
-		else
-			break;
-	}
-	return ret_val;
-}
-
-
-string DecodedInstructionBea_t::getMnemonic() const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	const auto mnemonic=string(d->Instruction.Mnemonic);
-	return mnemonic.substr(0,mnemonic.size()-1);
-}
-
-int64_t DecodedInstructionBea_t::getImmediate() const
-{
-	// find and return an immediate operand from this instruction
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	return d->Instruction.Immediat;
-}
-
-
-virtual_offset_t DecodedInstructionBea_t::getAddress() const
-{
-	// return anything that's explicitly an address, like a jmp/call target 
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	return d->Instruction.AddrValue;
-}
-
-
-bool DecodedInstructionBea_t::setsStackPointer() const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-
-        if(getMnemonic()== "push")
-                return true;
-        if(getMnemonic()== "pop")
-                return true;
-        if(getMnemonic()== "call")
-                return true;
-        if(d->Instruction.ImplicitModifiedRegs==REGISTER_TYPE+GENERAL_REG+REG4)
-                return true;
-
-        if(my_SetsStackPointer(&d->Argument1)) return true;
-        if(my_SetsStackPointer(&d->Argument2)) return true;
-        if(my_SetsStackPointer(&d->Argument3)) return true;
-        if(my_SetsStackPointer(&d->Argument4)) return true;
-
-        return false;
-}
-
-uint32_t DecodedInstructionBea_t::getPrefixCount() const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	return d->Prefix.Number;
-}
-
-virtual_offset_t DecodedInstructionBea_t::getMemoryDisplacementOffset(const DecodedOperandBea_t& t, const libIRDB::Instruction_t*) const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	ARGTYPE* the_arg=static_cast<ARGTYPE*>(t.arg_data);
-	return the_arg->Memory.DisplacementAddr-d->EIP;
-}
-
-
-bool DecodedInstructionBea_t::hasRelevantRepPrefix() const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	return d->Prefix.RepPrefix==InUsePrefix;
-}
-
-bool DecodedInstructionBea_t::hasRelevantRepnePrefix() const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	return d->Prefix.RepnePrefix==InUsePrefix;
-}
-
-bool DecodedInstructionBea_t::hasRelevantOperandSizePrefix() const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	return d->Prefix.OperandSize!=NotUsedPrefix;
-}
-
-bool DecodedInstructionBea_t::hasRexWPrefix() const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	return d->Prefix.REX.W_;
-}
-
-bool DecodedInstructionBea_t::hasImplicitlyModifiedRegs() const
-{
-	DISASM* d=static_cast<DISASM*>(disasm_data);
-	return d->Instruction.ImplicitModifiedRegs!=0;
-}
-
diff --git a/libIRDB/src/core/decode_cs.cpp b/libIRDB/src/core/decode_csx86.cpp
similarity index 87%
rename from libIRDB/src/core/decode_cs.cpp
rename to libIRDB/src/core/decode_csx86.cpp
index ec8242935..fa968e211 100644
--- a/libIRDB/src/core/decode_cs.cpp
+++ b/libIRDB/src/core/decode_csx86.cpp
@@ -14,9 +14,9 @@ using namespace std;
 
 #define ALLOF(a) begin(a),end(a)
 
-DecodedInstructionCapstone_t::CapstoneHandle_t* DecodedInstructionCapstone_t::cs_handle=NULL ;
+DecodedInstructionCapstoneX86_t::CapstoneHandle_t* DecodedInstructionCapstoneX86_t::cs_handle=NULL ;
 
-DecodedInstructionCapstone_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp)
+DecodedInstructionCapstoneX86_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp)
 {
 	const auto width=FileIR_t::GetArchitectureBitWidth();
 	const auto mode = (width==64) ? CS_MODE_64: CS_MODE_32;
@@ -120,7 +120,7 @@ static inline type insnToImmedHelper(cs_insn* the_insn, csh handle)
 // shared code 
 // constructors, destructors, operators.
 
-void DecodedInstructionCapstone_t::Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len)
+void DecodedInstructionCapstoneX86_t::Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len)
 {
 	using namespace std::placeholders;
 	auto insn=cs_malloc(cs_handle->getHandle());
@@ -192,7 +192,7 @@ void DecodedInstructionCapstone_t::Disassemble(const virtual_offset_t start_addr
 	my_insn.reset(insn,cs_freer);
 }
 
-DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const Instruction_t* i)
+DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const Instruction_t* i)
 {
 	if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL);
 	if(!i) throw std::invalid_argument("No instruction given to DecodedInstruction_t(Instruction_t*)");
@@ -206,35 +206,35 @@ DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const Instruction_t*
 	if(!valid()) throw std::invalid_argument("The Instruction_t::GetDataBits field is not a valid instruction.");
 }
 
-DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len)
+DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len)
 {
 	if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL);
         Disassemble(start_addr, data, max_len);
 }
 
-DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const virtual_offset_t start_addr, const void *data, const void* endptr)
+DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, const void* endptr)
 {
 	if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL);
         const auto length=(char*)endptr-(char*)data;
         Disassemble(start_addr,data,length);
 }
 
-DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const DecodedInstructionCapstone_t& copy)
+DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const DecodedInstructionCapstoneX86_t& copy)
 {
 	*this=copy;
 }
 
-DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const shared_ptr<void> &p_my_insn)
+DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const shared_ptr<void> &p_my_insn)
 	: my_insn(p_my_insn)
 {
 }
 
-DecodedInstructionCapstone_t::~DecodedInstructionCapstone_t()
+DecodedInstructionCapstoneX86_t::~DecodedInstructionCapstoneX86_t()
 {
 	// no need to cs_free(my_insn) because shared pointer will do that for us!
 }
 
-DecodedInstructionCapstone_t& DecodedInstructionCapstone_t::operator=(const DecodedInstructionCapstone_t& copy)
+DecodedInstructionCapstoneX86_t& DecodedInstructionCapstoneX86_t::operator=(const DecodedInstructionCapstoneX86_t& copy)
 {
 	my_insn=copy.my_insn;
 	return *this;
@@ -242,7 +242,7 @@ DecodedInstructionCapstone_t& DecodedInstructionCapstone_t::operator=(const Deco
 
 // public methods
 
-string DecodedInstructionCapstone_t::getDisassembly() const
+string DecodedInstructionCapstoneX86_t::getDisassembly() const
 {
 	const auto myReplace=[](std::string &str,
 		       const std::string& oldStr,
@@ -338,27 +338,27 @@ string DecodedInstructionCapstone_t::getDisassembly() const
 	return full_str;
 }
 
-bool DecodedInstructionCapstone_t::valid() const
+bool DecodedInstructionCapstoneX86_t::valid() const
 {
 	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
 	return the_insn->size!=0;
 }
 
-uint32_t DecodedInstructionCapstone_t::length() const
+uint32_t DecodedInstructionCapstoneX86_t::length() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
 	return the_insn->size;
 }
 
-bool DecodedInstructionCapstone_t::isBranch() const
+bool DecodedInstructionCapstoneX86_t::isBranch() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
 	return isCall() || isReturn() || isJmp(the_insn);
 }
 
-bool DecodedInstructionCapstone_t::isCall() const
+bool DecodedInstructionCapstoneX86_t::isCall() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 
@@ -366,7 +366,7 @@ bool DecodedInstructionCapstone_t::isCall() const
 	return isPartOfGroup(the_insn,X86_GRP_CALL);
 }
 
-bool DecodedInstructionCapstone_t::isUnconditionalBranch() const
+bool DecodedInstructionCapstoneX86_t::isUnconditionalBranch() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
@@ -374,21 +374,21 @@ bool DecodedInstructionCapstone_t::isUnconditionalBranch() const
 	return isJmp(the_insn) && !isConditionalBranch();
 }
 
-bool DecodedInstructionCapstone_t::isConditionalBranch() const
+bool DecodedInstructionCapstoneX86_t::isConditionalBranch() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
 	return isJmp(the_insn) && getMnemonic()!="jmp";
 }
 
-bool DecodedInstructionCapstone_t::isReturn() const
+bool DecodedInstructionCapstoneX86_t::isReturn() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
 	return isPartOfGroup(the_insn,X86_GRP_RET);
 }
 
-bool DecodedInstructionCapstone_t::hasOperand(const int op_num) const
+bool DecodedInstructionCapstoneX86_t::hasOperand(const int op_num) const
 {
 	if(op_num<0) throw std::logic_error(string("Called ")+ __FUNCTION__+" with opnum="+to_string(op_num));
 	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
@@ -397,16 +397,16 @@ bool DecodedInstructionCapstone_t::hasOperand(const int op_num) const
 }
 
 // 0-based.  first operand is numbered 0.
-DecodedOperandCapstone_t DecodedInstructionCapstone_t::getOperand(const int op_num) const
+DecodedOperandCapstoneX86_t DecodedInstructionCapstoneX86_t::getOperand(const int op_num) const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	if(!hasOperand(op_num)) throw std::logic_error(string("Called ")+__FUNCTION__+" on without hasOperand()==true");
 
-	return DecodedOperandCapstone_t(my_insn,(uint8_t)op_num);
+	return DecodedOperandCapstoneX86_t(my_insn,(uint8_t)op_num);
 	
 }
 
-DecodedOperandCapstoneVector_t DecodedInstructionCapstone_t::getOperands() const
+DecodedOperandCapstoneVector_t DecodedInstructionCapstoneX86_t::getOperands() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
@@ -421,7 +421,7 @@ DecodedOperandCapstoneVector_t DecodedInstructionCapstone_t::getOperands() const
 	return ret_val;
 }
 
-string DecodedInstructionCapstone_t::getMnemonic() const
+string DecodedInstructionCapstoneX86_t::getMnemonic() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 
@@ -471,7 +471,7 @@ string DecodedInstructionCapstone_t::getMnemonic() const
 }
 
 
-int64_t DecodedInstructionCapstone_t::getImmediate() const
+int64_t DecodedInstructionCapstoneX86_t::getImmediate() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 
@@ -485,7 +485,7 @@ int64_t DecodedInstructionCapstone_t::getImmediate() const
 }
 
 
-virtual_offset_t DecodedInstructionCapstone_t::getAddress() const
+virtual_offset_t DecodedInstructionCapstoneX86_t::getAddress() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 
@@ -514,7 +514,7 @@ virtual_offset_t DecodedInstructionCapstone_t::getAddress() const
 }
 
 
-bool DecodedInstructionCapstone_t::setsStackPointer() const
+bool DecodedInstructionCapstoneX86_t::setsStackPointer() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 
@@ -577,7 +577,7 @@ bool DecodedInstructionCapstone_t::setsStackPointer() const
 	return is_op0;
 }
 
-uint32_t DecodedInstructionCapstone_t::getPrefixCount() const
+uint32_t DecodedInstructionCapstoneX86_t::getPrefixCount() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 
@@ -588,7 +588,7 @@ uint32_t DecodedInstructionCapstone_t::getPrefixCount() const
 	return count_with_rex;
 }
 
-virtual_offset_t DecodedInstructionCapstone_t::getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t, const Instruction_t* insn) const
+virtual_offset_t DecodedInstructionCapstoneX86_t::getMemoryDisplacementOffset(const DecodedOperandCapstoneX86_t& t, const Instruction_t* insn) const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 
@@ -654,35 +654,35 @@ virtual_offset_t DecodedInstructionCapstone_t::getMemoryDisplacementOffset(const
 
 
 
-bool DecodedInstructionCapstone_t::hasRelevantRepPrefix() const
+bool DecodedInstructionCapstoneX86_t::hasRelevantRepPrefix() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
 	return hasPrefix(the_insn,X86_PREFIX_REP);
 }
 
-bool DecodedInstructionCapstone_t::hasRelevantRepnePrefix() const
+bool DecodedInstructionCapstoneX86_t::hasRelevantRepnePrefix() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
 	return hasPrefix(the_insn,X86_PREFIX_REPNE);
 }
 
-bool DecodedInstructionCapstone_t::hasRelevantOperandSizePrefix() const
+bool DecodedInstructionCapstoneX86_t::hasRelevantOperandSizePrefix() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
 	return hasPrefix(the_insn,X86_PREFIX_OPSIZE);
 }
 
-bool DecodedInstructionCapstone_t::hasRexWPrefix() const
+bool DecodedInstructionCapstoneX86_t::hasRexWPrefix() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
 	return (the_insn->detail->x86.rex & 0x8) == 0x8;
 }
 
-bool DecodedInstructionCapstone_t::hasImplicitlyModifiedRegs() const
+bool DecodedInstructionCapstoneX86_t::hasImplicitlyModifiedRegs() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 
diff --git a/libIRDB/src/core/decode_dispatch.cpp b/libIRDB/src/core/decode_dispatch.cpp
new file mode 100644
index 000000000..cb888facc
--- /dev/null
+++ b/libIRDB/src/core/decode_dispatch.cpp
@@ -0,0 +1,106 @@
+
+#include <libIRDB-core.hpp>
+#include <core/decode_dispatch.hpp>
+#include <core/operand_dispatch.hpp>
+
+using namespace libIRDB;
+using namespace std;
+
+// constructors, destructors, operators.
+
+DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const Instruction_t* i) 
+{
+	cs.reset(new DecodedInstructionCapstoneX86_t(i));
+}
+
+DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) 
+{
+	cs.reset(new DecodedInstructionCapstoneX86_t(start_addr,data,max_len));
+}
+
+DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, const void* endptr) 
+{
+	cs.reset(new DecodedInstructionCapstoneX86_t(start_addr,data,endptr));
+}
+
+DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const DecodedInstructionDispatcher_t& copy) 
+{
+	cs.reset(new DecodedInstructionCapstoneX86_t(*copy.cs));
+}
+
+DecodedInstructionDispatcher_t::~DecodedInstructionDispatcher_t()
+{
+}
+
+DecodedInstructionDispatcher_t& DecodedInstructionDispatcher_t::operator=(const DecodedInstructionDispatcher_t& copy)
+{
+	cs.reset(new DecodedInstructionCapstoneX86_t(*copy.cs));
+	return *this;
+}
+
+
+
+#define passthrough_to_cs(ret_type, method_name) 						\
+	ret_type DecodedInstructionDispatcher_t::method_name() const 					\
+	{ 											\
+		return cs->method_name(); 							\
+	} 
+
+// public methods
+
+/* demonstrating things are the same */
+passthrough_to_cs(bool, valid);
+passthrough_to_cs(uint32_t, length);
+passthrough_to_cs(bool, isBranch);
+passthrough_to_cs(bool, isCall);
+passthrough_to_cs(bool, isUnconditionalBranch);
+passthrough_to_cs(bool, isConditionalBranch);
+passthrough_to_cs(bool, isReturn);
+passthrough_to_cs(uint32_t, getPrefixCount);
+passthrough_to_cs(bool, hasRexWPrefix);
+passthrough_to_cs(bool, setsStackPointer);
+passthrough_to_cs(bool, hasRelevantRepPrefix);		// rep ret disagreement.
+passthrough_to_cs(bool, hasRelevantRepnePrefix);
+passthrough_to_cs(bool, hasRelevantOperandSizePrefix);
+
+/* demonstrating when capstone is better */
+passthrough_to_cs(string, getMnemonic);
+passthrough_to_cs(string,getDisassembly);
+passthrough_to_cs(virtual_offset_t, getAddress);	 
+passthrough_to_cs(int64_t, getImmediate);
+
+// demonstrating they different and trying to determine which is better.
+passthrough_to_cs(bool, hasImplicitlyModifiedRegs); 	
+
+// not yet completed
+// needs more complicated impl.
+
+
+bool DecodedInstructionDispatcher_t::hasOperand(const int op_num) const
+{
+	const auto cs_res = cs->hasOperand(op_num);
+	return cs_res; 									
+}
+
+// 0-based.  first operand is numbered 0.
+DecodedOperandDispatcher_t DecodedInstructionDispatcher_t::getOperand(const int op_num) const
+{
+	return DecodedOperandDispatcher_t(cs->getOperand(op_num));
+}
+
+DecodedOperandMetaVector_t DecodedInstructionDispatcher_t::getOperands() const
+{
+	auto ret_val=DecodedOperandMetaVector_t();
+	auto cs_operands=cs->getOperands();
+	for(const auto &op : cs_operands ) 
+		ret_val.push_back(DecodedOperandDispatcher_t(op));
+	return ret_val;
+}
+
+virtual_offset_t DecodedInstructionDispatcher_t::getMemoryDisplacementOffset(const DecodedOperandDispatcher_t& t, const Instruction_t* insn) const
+{
+	return cs->getMemoryDisplacementOffset(*t.cs, insn);
+}
+
+
+
diff --git a/libIRDB/src/core/decode_meta.cpp b/libIRDB/src/core/decode_meta.cpp
deleted file mode 100644
index 0bd7a0f2e..000000000
--- a/libIRDB/src/core/decode_meta.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-
-#include <libIRDB-core.hpp>
-#include <core/decode_meta.hpp>
-#include <core/operand_meta.hpp>
-
-using namespace libIRDB;
-using namespace std;
-
-// constructors, destructors, operators.
-
-DecodedInstructionMeta_t::DecodedInstructionMeta_t(const Instruction_t* i) :
-	bea(i),
-	cs(i)
-{
-}
-
-DecodedInstructionMeta_t::DecodedInstructionMeta_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) :
-	bea(start_addr,data,max_len),
-	cs(start_addr,data,max_len)
-{
-}
-
-DecodedInstructionMeta_t::DecodedInstructionMeta_t(const virtual_offset_t start_addr, const void *data, const void* endptr) :
-	bea(start_addr,data,endptr),
-	cs(start_addr,data,endptr)
-{
-}
-
-DecodedInstructionMeta_t::DecodedInstructionMeta_t(const DecodedInstructionMeta_t& copy) :
-	bea(copy.bea),
-	cs(copy.cs)
-{
-}
-
-DecodedInstructionMeta_t::~DecodedInstructionMeta_t()
-{
-}
-
-DecodedInstructionMeta_t& DecodedInstructionMeta_t::operator=(const DecodedInstructionMeta_t& copy)
-{
-	bea=copy.bea;
-	cs=copy.cs;
-}
-
-
-void do_breakpoint(const char* s) { (void)s; }
-
-
-#define passthrough_to_bea(ret_type, method_name) 						\
-	ret_type DecodedInstructionMeta_t::method_name() const 					\
-	{ 											\
-		return bea.method_name(); 							\
-	} 
-
-
-#define compare_decoders(ret_type, method_name) \
-	ret_type DecodedInstructionMeta_t::method_name() const 					\
-	{ 											\
-		const auto bea_res= bea.method_name(); 						\
-		const auto cs_res= cs.method_name(); 						\
-		if(bea_res!=cs_res)  								\
-		{ 										\
-			cerr<<"Bea/Capstone miscompare: bea='"<<bea_res<<"'"			\
-			                             <<" cs='"<<cs_res <<"'";	 		\
-			cerr<<" in bea="<<bea.getDisassembly();					\
-			cerr<<" or cs="<<bea.getDisassembly();					\
-			cerr<<" at " <<__FUNCTION__<<endl;					\
-			do_breakpoint(__FUNCTION__);						\
-		} 										\
-		return cs_res; 									\
-	} 
-
-#define compare_decoders_assert(ret_type, method_name) \
-	ret_type DecodedInstructionMeta_t::method_name() const 					\
-	{ 											\
-		const auto bea_res= bea.method_name(); 						\
-		const auto cs_res= cs.method_name(); 						\
-		if(bea_res!=cs_res)  								\
-		{ 										\
-			cerr<<"Bea/Capstone miscompare: bea='"<<bea_res<<"'"			\
-			                             <<" cs='"<<cs_res <<"'"<<endl; 		\
-			cerr<<" in bea="<<bea.getDisassembly();					\
-			cerr<<" or cs="<<bea.getDisassembly();					\
-			cerr<<" at " <<__FUNCTION__<<endl;					\
-			abort(); 								\
-		} 										\
-		return cs_res; 									\
-	} 
-
-
-#define passthrough_to_cs(ret_type, method_name) 						\
-	ret_type DecodedInstructionMeta_t::method_name() const 					\
-	{ 											\
-		return cs.method_name(); 							\
-	} 
-
-// public methods
-
-/* demonstrating things are the same */
-compare_decoders_assert(bool, valid);
-compare_decoders_assert(uint32_t, length);
-compare_decoders_assert(bool, isBranch);
-compare_decoders_assert(bool, isCall);
-compare_decoders_assert(bool, isUnconditionalBranch);
-compare_decoders_assert(bool, isConditionalBranch);
-compare_decoders_assert(bool, isReturn);
-compare_decoders_assert(uint32_t, getPrefixCount);
-compare_decoders_assert(bool, hasRexWPrefix);
-compare_decoders_assert(bool, setsStackPointer);
-compare_decoders_assert(bool, hasRelevantRepPrefix);		// rep ret disagreement.
-compare_decoders_assert(bool, hasRelevantRepnePrefix);
-compare_decoders_assert(bool, hasRelevantOperandSizePrefix);
-
-/* demonstrating when capstone is better */
-passthrough_to_cs(string, getMnemonic);
-passthrough_to_cs(string,getDisassembly);
-passthrough_to_cs(virtual_offset_t, getAddress);	 // bea sometimes calcs this wrong.  way wrong.
-passthrough_to_cs(int64_t, getImmediate);
-
-// demonstrating they different and trying to determine which is better.
-compare_decoders(bool, hasImplicitlyModifiedRegs); 	// found div %sil insn that bea gets wrong.
-
-// not yet completed
-// needs more complicated impl.
-
-
-bool DecodedInstructionMeta_t::hasOperand(const int op_num) const
-{
-	const auto cs_res =cs .hasOperand(op_num);
-/*
-	const auto bea_res=bea.hasOperand(op_num);
-	if(bea_res!=cs_res)  								
-	{ 										
-		cerr<<"Bea/Capstone miscompare: bea='"<<bea_res<<"'"			
-					     <<" cs='"<<cs_res <<"'"<<endl; 		
-		cerr<<" in bea="<<bea.getDisassembly();					
-		cerr<<" or cs="<<bea.getDisassembly();					
-		cerr<<" at " <<__FUNCTION__<<endl;					
-		abort(); 								
-	} 										
-	return bea_res;
-*/
-	return cs_res; 									
-}
-
-// 0-based.  first operand is numbered 0.
-DecodedOperandMeta_t DecodedInstructionMeta_t::getOperand(const int op_num) const
-{
-	return DecodedOperandMeta_t(cs.getOperand(op_num));
-}
-
-DecodedOperandMetaVector_t DecodedInstructionMeta_t::getOperands() const
-{
-	auto ret_val=DecodedOperandMetaVector_t();
-	auto cs_operands=cs.getOperands();
-	for(const auto &op : cs_operands ) 
-		ret_val.push_back(DecodedOperandMeta_t(op));
-	return ret_val;
-}
-
-virtual_offset_t DecodedInstructionMeta_t::getMemoryDisplacementOffset(const DecodedOperandMeta_t& t, const Instruction_t* insn) const
-{
-	return cs.getMemoryDisplacementOffset(t.cs, insn);
-}
-
-
-
diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp
index 59ec13bcf..39c1a6f74 100644
--- a/libIRDB/src/core/fileir.cpp
+++ b/libIRDB/src/core/fileir.cpp
@@ -990,27 +990,35 @@ int FileIR_t::GetArchitectureBitWidth()
 	return archdesc->GetBitWidth();
 }
 
-void FileIR_t::SetArchitectureBitWidth(int width) 
+void FileIR_t::SetArchitecture(const int width, const ADMachineType_t mt) 
 {
 	if(archdesc==NULL)
 		archdesc=new ArchitectureDescription_t;
-	archdesc->SetBitWidth(width);
+	archdesc->SetBitWidth(width); 
+	archdesc->setMachineType(mt); 
 }	
 
 void FileIR_t::SetArchitecture()
 {
 
 	/* the first 16 bytes of an ELF file define the magic number and ELF Class. */
-    	unsigned char e_ident[16];
+    	// unsigned char e_ident[16];
+	union 
+	{
+		Elf32_Ehdr ehdr32;
+		Elf64_Ehdr ehdr64;
+	} hdr_union;
 
-	DBinterface_t* myinter=BaseObj_t::GetInterface();
-	pqxxDB_t *mypqxxintr=dynamic_cast<pqxxDB_t*>(myinter);
+	auto myinter=BaseObj_t::GetInterface();
+	auto *mypqxxintr=dynamic_cast<pqxxDB_t*>(myinter);
 
-	int elfoid=GetFile()->GetELFOID();
+	const auto elfoid=GetFile()->GetELFOID();
         pqxx::largeobjectaccess loa(mypqxxintr->GetTransaction(), elfoid, PGSTD::ios::in);
 
 
-        loa.cread((char*)&e_ident, sizeof(e_ident));
+        loa.cread((char*)&hdr_union, sizeof(hdr_union));
+
+	const auto e_ident=hdr_union.ehdr32.e_ident;
 
 	archdesc=new ArchitectureDescription_t;
 
@@ -1042,20 +1050,32 @@ void FileIR_t::SetArchitecture()
 
 	if (archdesc->GetFileType() == AD_PE)
 	{
-		// just assume 64 bit for Windows, o/w could also extract from file
+		// just assume x86-64 bit for Windows, o/w could also extract from file
 		archdesc->SetBitWidth(64);
+		archdesc->setMachineType(admtX86_64);
 	}
 	else
 	{
 		switch(e_ident[4])
 		{
 			case ELFCLASS32:
+			{
 				archdesc->SetBitWidth(32);
+				if(hdr_union.ehdr32.e_machine!=EM_386)
+					throw std::invalid_argument("Arch not supported.  32-bit archs supported:  I386");
+				archdesc->setMachineType(admtI386);
 				break;
+			}
 			case ELFCLASS64:
+			{
 				archdesc->SetBitWidth(64);
+				const auto mt= 
+					hdr_union.ehdr64.e_machine==EM_AARCH64 ? admtAarch64 : 
+					hdr_union.ehdr64.e_machine==EM_X86_64  ? admtX86_64 : 
+					throw std::invalid_argument("Arch not supported.  64-bit archs supported:  Aarch64, X86-64");
+				archdesc->setMachineType(mt);
 				break;
-			case ELFCLASSNONE:
+			}
 			default:
 				cerr << "Unknown ELF class " <<endl;
 				exit(-1);
diff --git a/libIRDB/src/core/operand_bea.cpp b/libIRDB/src/core/operand_bea.cpp
deleted file mode 100644
index 422752dfc..000000000
--- a/libIRDB/src/core/operand_bea.cpp
+++ /dev/null
@@ -1,258 +0,0 @@
-
-#include <libIRDB-core.hpp>
-#include <bea_deprecated.hpp>
-
-#include <core/decode_bea.hpp>
-#include <core/operand_bea.hpp>
-
-using namespace std;
-using namespace libIRDB;
-
-// static functions 
-static uint32_t beaRegNoToIRDBRegNo(uint32_t regno)
-{
-	switch(regno)
-	{
-		case 0: return -1;	// no reg -> -1
-		case REG0+REG2: /* eax:edx pair -- call it reg 0 */ return 0;
-		case REG0: return 0;
-		case REG1: return 1;
-		case REG2: return 2;
-		case REG3: return 3;
-		case REG4: return 4;
-		case REG5: return 5;
-		case REG6: return 6;
-		case REG7: return 7;
-		case REG8: return 8;
-		case REG9: return 9;
-		case REG10: return 10;
-		case REG11: return 11;
-		case REG12: return 12;
-		case REG13: return 13;
-		case REG14: return 14;
-		case REG15: return 15;
-		default: assert(0); // odd number from BEA?
-	};
-}
-
-
-// methods
-DecodedOperandBea_t::DecodedOperandBea_t(void* arg_voidptr)
-{
-	ARGTYPE *arg_ptr=static_cast<ARGTYPE*>(arg_voidptr);
-	arg_data=(void*)new ARGTYPE(*arg_ptr);
-}
-
-DecodedOperandBea_t::DecodedOperandBea_t(const DecodedOperandBea_t& copy)
-{
-	ARGTYPE *arg_ptr=static_cast<ARGTYPE*>(copy.arg_data);
-	arg_data=(void*)new ARGTYPE(*arg_ptr);
-}
-
-DecodedOperandBea_t::~DecodedOperandBea_t()
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	delete t;
-	arg_data=NULL;
-}
-
-DecodedOperandBea_t& DecodedOperandBea_t::operator=(const DecodedOperandBea_t& copy)
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	delete t;
-	arg_data=NULL;
-	ARGTYPE *arg_ptr=static_cast<ARGTYPE*>(copy.arg_data);
-	arg_data=(void*)new ARGTYPE(*arg_ptr);
-
-	return *this;
-}
-
-bool DecodedOperandBea_t::isConstant() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	assert(t);
-	return (t->ArgType & CONSTANT_TYPE)!=0;
-}
-
-string DecodedOperandBea_t::getString() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	assert(t);
-	return t->ArgMnemonic;
-}
-
-bool DecodedOperandBea_t::isRegister() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return (t->ArgType&REGISTER_TYPE)==REGISTER_TYPE;
-}
-
-bool DecodedOperandBea_t::isGeneralPurposeRegister() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return isRegister() && (t->ArgType&GENERAL_REG)==GENERAL_REG;
-}
-
-bool DecodedOperandBea_t::isMmxRegister() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return isRegister() && (t->ArgType&MMX_REG)==MMX_REG;
-}
-
-bool DecodedOperandBea_t::isFpuRegister() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return isRegister() && (t->ArgType&FPU_REG)==FPU_REG;
-}
-
-bool DecodedOperandBea_t::isSseRegister() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return isRegister() && (t->ArgType&SSE_REG)==SSE_REG;
-}
-
-bool DecodedOperandBea_t::isAvxRegister() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return isRegister() && (t->ArgType&AVX_REG)==AVX_REG;
-}
-
-bool DecodedOperandBea_t::isSpecialRegister() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return isRegister() && (t->ArgType&SPECIAL_REG)==SPECIAL_REG;
-}
-
-bool DecodedOperandBea_t::isSegmentRegister() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return isRegister() && (t->ArgType&SEGMENT_REG)==SEGMENT_REG;
-}
-
-uint32_t DecodedOperandBea_t::getRegNumber() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	if(!isRegister())
-		throw std::logic_error("getRegNumber called on not register");
-	const auto regno=(t->ArgType)&0xFFFF;
-
-	return beaRegNoToIRDBRegNo(regno);
-}
-
-bool DecodedOperandBea_t::isMemory() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return (t->ArgType&MEMORY_TYPE)==MEMORY_TYPE;
-}
-
-bool DecodedOperandBea_t::hasBaseRegister() const
-{
-	if(!isMemory())
-		throw std::logic_error("hasBaseRegister called on not memory operand");
-
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return t->Memory.BaseRegister!=0;
-}
-
-bool DecodedOperandBea_t::hasIndexRegister() const
-{
-	if(!isMemory())
-		throw std::logic_error("hasIndexRegister called on not memory operand");
-
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return t->Memory.IndexRegister!=0;
-}
-
-uint32_t DecodedOperandBea_t::getBaseRegister() const
-{
-	if(!isMemory() || !hasBaseRegister())
-		throw std::logic_error("getBaseRegister called on not memory operand");
-
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return beaRegNoToIRDBRegNo(t->Memory.BaseRegister);
-}
-
-uint32_t DecodedOperandBea_t::getIndexRegister() const
-{
-	if(!isMemory() || !hasIndexRegister())
-		throw std::logic_error("getIndexRegister called on not memory operand");
-
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return beaRegNoToIRDBRegNo(t->Memory.IndexRegister);
-}
-
-uint32_t DecodedOperandBea_t::getScaleValue() const
-{
-	if(!isMemory())
-		throw std::logic_error("getScaleValue called on not memory operand");
-
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return t->Memory.Scale; 	/* 0 indicates no scale */
-}
-
-bool DecodedOperandBea_t::hasMemoryDisplacement() const
-{
-	if(!isMemory())
-		throw std::logic_error("GetBaseRegister called on not memory operand");
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return t->Memory.DisplacementAddr!=0;
-}
-
-virtual_offset_t DecodedOperandBea_t::getMemoryDisplacement() const
-{
-	if(!isMemory())
-		throw std::logic_error("GetBaseRegister called on not memory operand");
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return (virtual_offset_t)t->Memory.Displacement;
-}
-
-bool DecodedOperandBea_t::isPcrel() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return (t->ArgType&RELATIVE_)==RELATIVE_;
-}
-
-uint32_t DecodedOperandBea_t::getMemoryDisplacementEncodingSize() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return t->Memory.DisplacementSize;
-}
-
-uint32_t DecodedOperandBea_t::getArgumentSizeInBytes() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return t->ArgSize/8;
-}
-
-uint32_t DecodedOperandBea_t::getArgumentSizeInBits() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return t->ArgSize;
-}
-
-bool DecodedOperandBea_t::hasSegmentRegister() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return t->SegmentReg!=0;
-
-}
-
-uint32_t DecodedOperandBea_t::getSegmentRegister() const
-{
-	if(!hasSegmentRegister())
-		throw std::logic_error("getSegmentRegisterNumber called with no segment register");
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return t->SegmentReg;
-}
-
-bool DecodedOperandBea_t::isRead() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return (t->AccessMode&READ)==READ;
-}
-
-bool DecodedOperandBea_t::isWritten() const
-{
-	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
-	return (t->AccessMode&WRITE)==WRITE;
-}
diff --git a/libIRDB/src/core/operand_cs.cpp b/libIRDB/src/core/operand_csx86.cpp
similarity index 88%
rename from libIRDB/src/core/operand_cs.cpp
rename to libIRDB/src/core/operand_csx86.cpp
index f74aff7b9..d7d6c9784 100644
--- a/libIRDB/src/core/operand_cs.cpp
+++ b/libIRDB/src/core/operand_csx86.cpp
@@ -1,8 +1,8 @@
 
 #include <libIRDB-core.hpp>
 #include <memory>
-#include <core/operand_cs.hpp>
-#include <core/decode_cs.hpp>
+#include <core/operand_csx86.hpp>
+#include <core/decode_csx86.hpp>
 
 using namespace std;
 using namespace libIRDB;
@@ -138,17 +138,17 @@ static uint32_t to_reg_number(const x86_reg &reg)
 
 // methods
 
-//DecodedOperandCapstone_t& DecodedOperandCapstone_t::operator=(const DecodedOperandCapstone_t& copy)
+//DecodedOperandCapstoneX86_t& DecodedOperandCapstoneX86_t::operator=(const DecodedOperandCapstoneX86_t& copy)
 //{
 //	return *this;
 //}
 //
-//DecodedOperandCapstone_t::DecodedOperandCapstone_t(const DecodedOperandCapstone_t& copy)
+//DecodedOperandCapstoneX86_t::DecodedOperandCapstoneX86_t(const DecodedOperandCapstoneX86_t& copy)
 //{
 //	*this=copy;
 //}
 
-DecodedOperandCapstone_t::DecodedOperandCapstone_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num)
+DecodedOperandCapstoneX86_t::DecodedOperandCapstoneX86_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num)
 	:
 	my_insn(p_my_insn),
 	op_num(p_op_num)
@@ -156,12 +156,12 @@ DecodedOperandCapstone_t::DecodedOperandCapstone_t( const shared_ptr<void> & p_m
 	
 }
 
-DecodedOperandCapstone_t::~DecodedOperandCapstone_t()
+DecodedOperandCapstoneX86_t::~DecodedOperandCapstoneX86_t()
 {
 }
 
 
-bool DecodedOperandCapstone_t::isConstant() const
+bool DecodedOperandCapstoneX86_t::isConstant() const
 {
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
         const auto &op = (the_insn->detail->x86.operands[op_num]);
@@ -169,7 +169,7 @@ bool DecodedOperandCapstone_t::isConstant() const
 	return op.type==X86_OP_IMM;
 }
 
-uint64_t DecodedOperandCapstone_t::getConstant() const
+uint64_t DecodedOperandCapstoneX86_t::getConstant() const
 {
 	if(!isConstant()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-constant operand");
 	
@@ -178,11 +178,11 @@ uint64_t DecodedOperandCapstone_t::getConstant() const
 	return op.imm;
 }
 
-string DecodedOperandCapstone_t::getString() const
+string DecodedOperandCapstoneX86_t::getString() const
 {
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
         const auto &op = (the_insn->detail->x86.operands[op_num]);
-	const auto handle=DecodedInstructionCapstone_t::cs_handle->getHandle();
+	const auto handle=DecodedInstructionCapstoneX86_t::cs_handle->getHandle();
 
 	switch(op.type)
 	{
@@ -227,14 +227,14 @@ string DecodedOperandCapstone_t::getString() const
 	}
 }
 
-bool DecodedOperandCapstone_t::isRegister() const
+bool DecodedOperandCapstoneX86_t::isRegister() const
 {
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
         const auto &op = (the_insn->detail->x86.operands[op_num]);
 	return op.type==X86_OP_REG;
 }
 
-bool DecodedOperandCapstone_t::isGeneralPurposeRegister() const
+bool DecodedOperandCapstoneX86_t::isGeneralPurposeRegister() const
 {
 
 	const auto gp_regs=set<x86_reg>({
@@ -261,7 +261,7 @@ bool DecodedOperandCapstone_t::isGeneralPurposeRegister() const
 	return isRegister() &&  gp_regs.find(op.reg)!=end(gp_regs);
 }
 
-bool DecodedOperandCapstone_t::isMmxRegister() const
+bool DecodedOperandCapstoneX86_t::isMmxRegister() const
 {
 	const auto regs=set<x86_reg>({
 		X86_REG_MM0, X86_REG_MM1,
@@ -272,7 +272,7 @@ bool DecodedOperandCapstone_t::isMmxRegister() const
 	return isRegister() &&  regs.find(op.reg)!=end(regs);
 }
 
-bool DecodedOperandCapstone_t::isFpuRegister() const
+bool DecodedOperandCapstoneX86_t::isFpuRegister() const
 {
 	const auto regs=set<x86_reg>({
 		X86_REG_ST0, X86_REG_ST1, X86_REG_ST2, X86_REG_ST3,
@@ -283,7 +283,7 @@ bool DecodedOperandCapstone_t::isFpuRegister() const
 	return isRegister() &&  regs.find(op.reg)!=end(regs);
 }
 
-bool DecodedOperandCapstone_t::isSseRegister() const
+bool DecodedOperandCapstoneX86_t::isSseRegister() const
 {
 	const auto regs=set<x86_reg>({
 		X86_REG_XMM0, X86_REG_XMM1, X86_REG_XMM2, X86_REG_XMM3, X86_REG_XMM4,
@@ -299,7 +299,7 @@ bool DecodedOperandCapstone_t::isSseRegister() const
 	return isRegister() &&  regs.find(op.reg)!=end(regs);
 }
 
-bool DecodedOperandCapstone_t::isAvxRegister() const
+bool DecodedOperandCapstoneX86_t::isAvxRegister() const
 {
 	const auto regs=set<x86_reg>({
 		X86_REG_YMM0, X86_REG_YMM1, X86_REG_YMM2,
@@ -315,7 +315,7 @@ bool DecodedOperandCapstone_t::isAvxRegister() const
 	return isRegister() &&  regs.find(op.reg)!=end(regs);
 }
 
-bool DecodedOperandCapstone_t::isZmmRegister() const
+bool DecodedOperandCapstoneX86_t::isZmmRegister() const
 {
 	const auto regs=set<x86_reg>({
 		X86_REG_ZMM0, X86_REG_ZMM1, X86_REG_ZMM2,
@@ -331,7 +331,7 @@ bool DecodedOperandCapstone_t::isZmmRegister() const
 	return isRegister() &&  regs.find(op.reg)!=end(regs);
 }
 
-bool DecodedOperandCapstone_t::isSpecialRegister() const
+bool DecodedOperandCapstoneX86_t::isSpecialRegister() const
 {
 	const auto regs=set<x86_reg>({
 		X86_REG_CR1, X86_REG_CR2, X86_REG_CR3, X86_REG_CR4, X86_REG_CR5,
@@ -345,7 +345,7 @@ bool DecodedOperandCapstone_t::isSpecialRegister() const
 	return isRegister() &&  regs.find(op.reg)!=end(regs);
 }
 
-bool DecodedOperandCapstone_t::isSegmentRegister() const
+bool DecodedOperandCapstoneX86_t::isSegmentRegister() const
 {
 	const auto regs=set<x86_reg>({
 		X86_REG_CS,
@@ -362,7 +362,7 @@ bool DecodedOperandCapstone_t::isSegmentRegister() const
 
 
 
-uint32_t DecodedOperandCapstone_t::getRegNumber() const
+uint32_t DecodedOperandCapstoneX86_t::getRegNumber() const
 {
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
         const auto &op = (the_insn->detail->x86.operands[op_num]);
@@ -384,28 +384,28 @@ uint32_t DecodedOperandCapstone_t::getRegNumber() const
 		assert(0);
 }
 
-bool DecodedOperandCapstone_t::isMemory() const
+bool DecodedOperandCapstoneX86_t::isMemory() const
 {
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
         const auto &op = (the_insn->detail->x86.operands[op_num]);
 	return op.type==X86_OP_MEM;
 }
 
-bool DecodedOperandCapstone_t::hasBaseRegister() const
+bool DecodedOperandCapstoneX86_t::hasBaseRegister() const
 {
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
         const auto &op = (the_insn->detail->x86.operands[op_num]);
 	return isMemory() && op.mem.base!=X86_REG_INVALID && op.mem.base!=X86_REG_RIP;
 }
 
-bool DecodedOperandCapstone_t::hasIndexRegister() const
+bool DecodedOperandCapstoneX86_t::hasIndexRegister() const
 {
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
         const auto &op = (the_insn->detail->x86.operands[op_num]);
 	return isMemory() && op.mem.index!=X86_REG_INVALID;
 }
 
-uint32_t DecodedOperandCapstone_t::getBaseRegister() const
+uint32_t DecodedOperandCapstoneX86_t::getBaseRegister() const
 {
 	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
@@ -413,7 +413,7 @@ uint32_t DecodedOperandCapstone_t::getBaseRegister() const
 	return to_reg_number((x86_reg)op.mem.base);
 }
 
-uint32_t DecodedOperandCapstone_t::getIndexRegister() const
+uint32_t DecodedOperandCapstoneX86_t::getIndexRegister() const
 {
 	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
@@ -421,7 +421,7 @@ uint32_t DecodedOperandCapstone_t::getIndexRegister() const
 	return to_reg_number((x86_reg)op.mem.index);
 }
 
-uint32_t DecodedOperandCapstone_t::getScaleValue() const
+uint32_t DecodedOperandCapstoneX86_t::getScaleValue() const
 {
 	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
@@ -429,7 +429,7 @@ uint32_t DecodedOperandCapstone_t::getScaleValue() const
 	return op.mem.scale;
 }
 
-bool DecodedOperandCapstone_t::hasMemoryDisplacement() const
+bool DecodedOperandCapstoneX86_t::hasMemoryDisplacement() const
 {
 
 	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
@@ -470,9 +470,9 @@ bool DecodedOperandCapstone_t::hasMemoryDisplacement() const
 			assert(0); //unreachable
 	}
 	assert(0); // unreachable
-} // end of DecodedOperandCapstone_t::hasMemoryDisplacement()
+} // end of DecodedOperandCapstoneX86_t::hasMemoryDisplacement()
 
-virtual_offset_t DecodedOperandCapstone_t::getMemoryDisplacement() const
+virtual_offset_t DecodedOperandCapstoneX86_t::getMemoryDisplacement() const
 {
 	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
@@ -480,7 +480,7 @@ virtual_offset_t DecodedOperandCapstone_t::getMemoryDisplacement() const
 	return op.mem.disp;
 }
 
-bool DecodedOperandCapstone_t::isPcrel() const
+bool DecodedOperandCapstoneX86_t::isPcrel() const
 {
 	if(!isMemory())	return false;
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
@@ -490,7 +490,7 @@ bool DecodedOperandCapstone_t::isPcrel() const
 }
 
 /* in bytes */
-uint32_t DecodedOperandCapstone_t::getMemoryDisplacementEncodingSize() const
+uint32_t DecodedOperandCapstoneX86_t::getMemoryDisplacementEncodingSize() const
 {
 	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
@@ -526,19 +526,19 @@ uint32_t DecodedOperandCapstone_t::getMemoryDisplacementEncodingSize() const
 	assert(0);
 }
 
-uint32_t DecodedOperandCapstone_t::getArgumentSizeInBytes() const
+uint32_t DecodedOperandCapstoneX86_t::getArgumentSizeInBytes() const
 {
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
         const auto &op = (the_insn->detail->x86.operands[op_num]);
 	return op.size;
 }
 
-uint32_t DecodedOperandCapstone_t::getArgumentSizeInBits() const
+uint32_t DecodedOperandCapstoneX86_t::getArgumentSizeInBits() const
 {
 	return getArgumentSizeInBytes()*8;
 }
 
-bool DecodedOperandCapstone_t::hasSegmentRegister() const
+bool DecodedOperandCapstoneX86_t::hasSegmentRegister() const
 {
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
         const auto &op = (the_insn->detail->x86.operands[op_num]);
@@ -546,7 +546,7 @@ bool DecodedOperandCapstone_t::hasSegmentRegister() const
 
 }
 
-uint32_t DecodedOperandCapstone_t::getSegmentRegister() const
+uint32_t DecodedOperandCapstoneX86_t::getSegmentRegister() const
 {
 	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of operand without memory operand");
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
@@ -725,12 +725,12 @@ set<string> read_only_operand_mnemonics=
 
 
 
-bool DecodedOperandCapstone_t::isRead() const
+bool DecodedOperandCapstoneX86_t::isRead() const
 {
 	if(!isWritten())
 		return true;
 
-	const auto d=DecodedInstructionCapstone_t(my_insn);
+	const auto d=DecodedInstructionCapstoneX86_t(my_insn);
 	const auto d_mnemonic=d.getMnemonic();
 	const auto woom_it=write_only_operand_mnemonics.find(d_mnemonic);
 	const auto in_woom=(woom_it!=end(write_only_operand_mnemonics));
@@ -744,7 +744,7 @@ bool DecodedOperandCapstone_t::isRead() const
 	if(op_num!=0)
 		return true;
 
-	const auto d=DecodedInstructionCapstone_t(my_insn);
+	const auto d=DecodedInstructionCapstoneX86_t(my_insn);
 	if(d.isBranch())	
 		return true;	
 
@@ -763,9 +763,9 @@ bool DecodedOperandCapstone_t::isRead() const
 */
 }
 
-bool DecodedOperandCapstone_t::isWritten() const
+bool DecodedOperandCapstoneX86_t::isWritten() const
 {	
-	const auto d=DecodedInstructionCapstone_t(my_insn);
+	const auto d=DecodedInstructionCapstoneX86_t(my_insn);
 	const auto d_mnemonic=d.getMnemonic();
 
 	// special case check:  all operands are reads
@@ -802,7 +802,7 @@ bool DecodedOperandCapstone_t::isWritten() const
 /*
 	if(op_num!=0)
 		return false;
-	const auto d=DecodedInstructionCapstone_t(my_insn);
+	const auto d=DecodedInstructionCapstoneX86_t(my_insn);
 	if(d.isBranch())	
 		return false;	
 
diff --git a/libIRDB/src/core/operand_meta.cpp b/libIRDB/src/core/operand_dispatch.cpp
similarity index 63%
rename from libIRDB/src/core/operand_meta.cpp
rename to libIRDB/src/core/operand_dispatch.cpp
index c75220bd9..b6203eb7e 100644
--- a/libIRDB/src/core/operand_meta.cpp
+++ b/libIRDB/src/core/operand_dispatch.cpp
@@ -1,42 +1,41 @@
 
 #include <libIRDB-core.hpp>
-#include <core/operand_cs.hpp>
-#include <core/decode_cs.hpp>
-#include <core/operand_bea.hpp>
-#include <core/decode_bea.hpp>
-#include <core/operand_meta.hpp>
-#include <core/decode_meta.hpp>
+#include <core/operand_csx86.hpp>
+#include <core/decode_csx86.hpp>
+#include <core/operand_dispatch.hpp>
+#include <core/decode_dispatch.hpp>
 
 using namespace std;
 using namespace libIRDB;
 
-DecodedOperandMeta_t::DecodedOperandMeta_t(const DecodedOperandCapstone_t& copy_cs)  :
-	cs(copy_cs)
+DecodedOperandDispatcher_t::DecodedOperandDispatcher_t(const DecodedOperandCapstoneX86_t& copy_cs)  
 {
+	cs.reset(new DecodedOperandCapstoneX86_t(copy_cs));
 } 
 
-DecodedOperandMeta_t::DecodedOperandMeta_t(const DecodedOperandMeta_t& copy) : 
-	cs(copy.cs)
+DecodedOperandDispatcher_t::DecodedOperandDispatcher_t(const DecodedOperandDispatcher_t& copy) 
 {
+	cs.reset(new DecodedOperandCapstoneX86_t(*copy.cs));
 }
 
-DecodedOperandMeta_t::~DecodedOperandMeta_t()
+DecodedOperandDispatcher_t::~DecodedOperandDispatcher_t()
 {
 }
 
-DecodedOperandMeta_t& DecodedOperandMeta_t::operator=(const DecodedOperandMeta_t& copy)
+DecodedOperandDispatcher_t& DecodedOperandDispatcher_t::operator=(const DecodedOperandDispatcher_t& copy)
 {
-	cs=copy.cs;
+	cs.reset(new DecodedOperandCapstoneX86_t(*copy.cs));
 	return *this;
 }
 
 #define passthrough_to_cs(ret_type, method_name) \
-	ret_type DecodedOperandMeta_t::method_name() const \
+	ret_type DecodedOperandDispatcher_t::method_name() const \
 	{ \
-		return cs.method_name(); \
+		return cs->method_name(); \
 	} 
 
 passthrough_to_cs(bool, isConstant);
+passthrough_to_cs(uint64_t, getConstant);
 passthrough_to_cs(string, getString);
 passthrough_to_cs(bool, isRegister);
 passthrough_to_cs(bool, isGeneralPurposeRegister);
diff --git a/tools/rida/rida.cpp b/tools/rida/rida.cpp
index 08f9a9b1d..a307377ff 100644
--- a/tools/rida/rida.cpp
+++ b/tools/rida/rida.cpp
@@ -9,7 +9,6 @@
 #include <string>
 #include "capstone/capstone.h"
 #include <fstream>
-//#include <elfio/elfio.hpp>
 #include <elf.h>
 #include <functional>
 
@@ -48,6 +47,7 @@ class CreateFunctions_t
 		csh cshandle;
 		ofstream outfile;
 		execlass_t file_class;
+		MachineType_t machine_type;
 		friend ostream& operator<<(ostream& os, const CreateFunctions_t::RangeSet_t& rs);
 	public:
 		CreateFunctions_t(const string &input_pgm, const string &output_annot, const bool p_verbose)
@@ -55,7 +55,8 @@ class CreateFunctions_t
 			verbose(p_verbose),
 			exeio(input_pgm),
 			cshandle(),
-			file_class(exeio.get_class())
+			file_class(exeio.get_class()),
+			machine_type(exeio.getMachineType())
 		{
 			outfile.open(output_annot.c_str(), ofstream::out);
 			if(!outfile.is_open())
@@ -73,8 +74,19 @@ class CreateFunctions_t
 				exit(1);
 			}
 
-			const auto cs_mode= file_class==ELF64 ? CS_MODE_64 : CS_MODE_32 ;
-			if (cs_open(CS_ARCH_X86, cs_mode , &cshandle) != CS_ERR_OK)
+			const auto cs_mode= 
+				machine_type==mtAarch64 ? CS_MODE_LITTLE_ENDIAN :
+				file_class==ELF64 ? CS_MODE_64 : 
+				file_class==ELF32 ? CS_MODE_32 : 
+				throw std::runtime_error("Cannot handle ELF class");
+
+			const auto my_cs_arch = 
+				machine_type == mtX86_64  ?  CS_ARCH_X86 : 
+				machine_type == mtI386    ?  CS_ARCH_X86 :
+				machine_type == mtAarch64 ?  CS_ARCH_ARM64 : 
+				throw std::runtime_error("Cannot handle architecture");
+
+			if (cs_open(my_cs_arch, cs_mode , &cshandle) != CS_ERR_OK)
 			{
 				cerr<<"Cannot initialize capstone"<<endl;
 				exit(1);
@@ -356,26 +368,57 @@ class CreateFunctions_t
 			if(verbose)
 				cout<<"Found plt function range is "<<hex<<startAddr<<"-"<<endAddr<<endl;
 
-			auto pltRange_it=find_if(ALLOF(sccs), [&](const RangeSet_t& s) 
+			const auto pltRange_it=find_if(ALLOF(sccs), [&](const RangeSet_t& s) 
 				{ 
 					return find_if(ALLOF(s), [&](const Range_t& r) { return r.contains(startAddr); }) != s.end(); 
 				});
-			assert(pltRange_it!=sccs.end());
-			sccs.erase(pltRange_it);	// invalidates all iterators
-
-			const auto plt_skip=16;
-			const auto plt_header_size=12;
-			const auto plt_entry_size=16;
-			const auto plt_entry_size_first_part=6;
+			// erase startAddr if found.
+			if(pltRange_it!=sccs.end())
+				sccs.erase(pltRange_it);	// invalidates all iterators
 
-			addRange(startAddr,plt_header_size);
 			auto dynsymEntryIndex=0;
-			for(auto i=startAddr+plt_skip; i<endAddr; i+=plt_skip) 
+
+			const auto handle_x86_plt=[&]()
 			{
-				addRange(i,plt_entry_size_first_part);
-				addRange(i+6,plt_entry_size-plt_entry_size_first_part);
-				addName(i,dynsymEntryIndex++);
-			}
+				const auto plt_skip=16;
+				const auto plt_header_size=12;
+				const auto plt_entry_size=16;
+				const auto plt_entry_size_first_part=6;
+
+				addRange(startAddr,plt_header_size);
+				for(auto i=startAddr+plt_skip; i<endAddr; i+=plt_skip) 
+				{
+					addRange(i,plt_entry_size_first_part);
+					addRange(i+6,plt_entry_size-plt_entry_size_first_part);
+					addName(i,dynsymEntryIndex++);
+				}
+			};
+			const auto handle_arm_plt=[&]()
+			{
+				const auto plt_entry_size=16;
+				const auto plt_header_size=8*4;
+
+				addRange(startAddr,plt_header_size);
+				for(auto i=startAddr+plt_header_size; i<endAddr; i+=plt_entry_size) 
+				{
+					addRange(i,plt_entry_size);
+					addName(i,dynsymEntryIndex++);
+				}
+			};
+
+			switch(machine_type)
+			{
+				case mtX86_64:
+				case mtI386: 
+					handle_x86_plt();
+					break;
+				case mtAarch64:
+					handle_arm_plt();
+					break;
+				default:
+					assert(0);
+
+			};
 			cout<<"#ATTRIBUTE plt_entries="<<dec<<dynsymEntryIndex<<endl;
 
 
diff --git a/xform/elfreader.cpp b/xform/elfreader.cpp
index 799533edb..0f748e1a5 100644
--- a/xform/elfreader.cpp
+++ b/xform/elfreader.cpp
@@ -86,7 +86,7 @@ ElfReader::~ElfReader()
 /*
 * Read <p_numBytes> from ELF file for location <p_pc>
 */
-string ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes)
+string ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes) const
 {
   for ( int i = 0; i < m_reader->sections.size(); ++i ) 
   {    
@@ -109,7 +109,7 @@ string ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes)
 * No bounds checking is done on <p_buf>
 * Return false if address not in valid sections
 */
-bool ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf)
+bool ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf) const
 {
   for ( int i = 0; i < m_reader->sections.size(); ++i ) 
   {    
@@ -130,7 +130,7 @@ bool ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf)
 /*
 * Return buffer for instruction off the ELF file
 */
-char* ElfReader::getInstructionBuffer(app_iaddr_t p_pc)
+const char* ElfReader::getInstructionBuffer(app_iaddr_t p_pc) const
 {
   for ( int i = 0; i < m_reader->sections.size(); ++i ) 
   {    
diff --git a/xform/elfreader.h b/xform/elfreader.h
index 23ae15bd4..20e1edf13 100644
--- a/xform/elfreader.h
+++ b/xform/elfreader.h
@@ -2,10 +2,11 @@
 #define _elfreader_H_
 
 #include <vector>
-// #include "elfio/elfio.hpp"
 #include "exeio.h"
 #include "targ-config.h"
 #include <assert.h>
+#include <exception>
+#include <libIRDB-core.hpp>
 
 
 // doing this is very bad.
@@ -14,24 +15,35 @@
 
 class ElfReader 
 {
-  public:
-    ElfReader(char *);
-    virtual ~ElfReader();
-
-    std::string read(app_iaddr_t p_pc, unsigned p_numBytes);
-    bool read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf);
-    char* getInstructionBuffer(app_iaddr_t p_pc);
-
-    bool isElf32() { assert(m_reader); return m_reader->get_class()==EXEIO::ELF32; }
-    bool isElf64() { assert(m_reader); return m_reader->get_class()==EXEIO::ELF64; }
-    bool isPe32() { assert(m_reader); return m_reader->get_class()==EXEIO::PE32; }
-    bool isPe64() { assert(m_reader); return m_reader->get_class()==EXEIO::PE64; }
-
-  private:
-//    ELFIO::elfio*                       m_reader;
-    EXEIO::exeio*                       m_reader;
-    
-//    std::vector < const ELFIO::section* >    m_sections;
+	public:
+
+	ElfReader(char *);
+	virtual ~ElfReader();
+
+	std::string read(app_iaddr_t p_pc, unsigned p_numBytes) const ;
+	bool read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf) const ;
+	const char* getInstructionBuffer(app_iaddr_t p_pc) const ;
+
+	bool isElf32() const { assert(m_reader); return m_reader->get_class()==EXEIO::ELF32; }
+	bool isElf64() const { assert(m_reader); return m_reader->get_class()==EXEIO::ELF64; }
+	bool isPe32() const { assert(m_reader); return m_reader->get_class()==EXEIO::PE32; }
+	bool isPe64() const { assert(m_reader); return m_reader->get_class()==EXEIO::PE64; }
+	void SetArchitecture() 
+	{ 
+		const auto width = 
+			(isElf32() || isPe32()) ? 32 : 
+			(isElf64() || isPe64()) ? 64 :
+			throw std::invalid_argument("Unknown architecture."); 
+		const auto mt = m_reader->getMachineType() == EXEIO::mtI386 ? libIRDB::admtI386 :
+				m_reader->getMachineType() == EXEIO::mtX86_64 ? libIRDB::admtX86_64 :
+				m_reader->getMachineType() == EXEIO::mtAarch64 ? libIRDB::admtAarch64 : 
+				throw std::invalid_argument("Unknown architecture."); 
+
+		libIRDB::FileIR_t::SetArchitecture(width,mt); 
+	}
+
+  	private:
+	EXEIO::exeio*                       m_reader;
 
 };
 
diff --git a/xform/rewriter.cpp b/xform/rewriter.cpp
index c5fe4c302..e31f2d9c5 100644
--- a/xform/rewriter.cpp
+++ b/xform/rewriter.cpp
@@ -669,10 +669,13 @@ void Rewriter::readElfFile(char p_filename[])
 */
 void Rewriter::disassemble()
 {
+	getElfReader()->SetArchitecture();
+	/*
 	if(getElfReader()->isElf64() || getElfReader()->isPe64())
 		FileIR_t::SetArchitectureBitWidth(64);
 	else
 		FileIR_t::SetArchitectureBitWidth(32);
+		*/
 
   	// for every instruction, grab from ELF
   	// disassemble
-- 
GitLab