From 7bb8e091ab33bcf51712be0b9e4c9bd5efc7408b Mon Sep 17 00:00:00 2001
From: Jason Hiser <jdhiser@gmail.com>
Date: Tue, 18 Dec 2018 14:44:14 -0500
Subject: [PATCH] first, sorta-working ARM64 version

Former-commit-id: 689b64ef83a0b5cd584a30ab1b15b43f52d377d1
---
 libIRDB/include/core/decode_base.hpp      |   7 +
 libIRDB/include/core/decode_csarm.hpp     |  22 +--
 libIRDB/include/core/decode_dispatch.hpp  |   2 +-
 libIRDB/include/core/fileir.hpp           |   1 +
 libIRDB/include/core/operand_csarm.hpp    |  10 +-
 libIRDB/include/core/operand_dispatch.hpp |   2 +-
 libIRDB/src/core/SConscript               |   1 +
 libIRDB/src/core/decode_base.cpp          |  39 ++++
 libIRDB/src/core/decode_csarm.cpp         |  75 ++++----
 libIRDB/src/core/decode_dispatch.cpp      |  14 +-
 libIRDB/src/core/operand_csarm.cpp        | 215 ++++++++++++++++------
 libIRDB/src/core/operand_dispatch.cpp     |   9 +-
 libehp                                    |   2 +-
 xform/rewriter.cpp                        |   4 +
 14 files changed, 278 insertions(+), 125 deletions(-)
 create mode 100644 libIRDB/src/core/decode_base.cpp

diff --git a/libIRDB/include/core/decode_base.hpp b/libIRDB/include/core/decode_base.hpp
index 4e53bef9c..f3aaf2e60 100644
--- a/libIRDB/include/core/decode_base.hpp
+++ b/libIRDB/include/core/decode_base.hpp
@@ -12,6 +12,7 @@ using namespace libIRDB;
 using namespace std;
 
 class DecodedOperandCapstone_t;
+class DecodedInstructionDispatcher_t;
 typedef std::vector<shared_ptr<DecodedOperandCapstone_t> > DecodedOperandCapstoneVector_t;
 
 class DecodedInstructionCapstone_t
@@ -44,6 +45,12 @@ class DecodedInstructionCapstone_t
 
 	private:
 
+		static std::shared_ptr<DecodedInstructionCapstone_t> factory(const libIRDB::Instruction_t* i);
+		static std::shared_ptr<DecodedInstructionCapstone_t> factory(const virtual_offset_t start_addr, const void *data, uint32_t max_len);
+		static std::shared_ptr<DecodedInstructionCapstone_t> factory(const virtual_offset_t start_addr, const void *data, const void* endptr);
+
+		friend class DecodedInstructionDispatcher_t;
+
 };
 
 }
diff --git a/libIRDB/include/core/decode_csarm.hpp b/libIRDB/include/core/decode_csarm.hpp
index 356386e0d..9a1201357 100644
--- a/libIRDB/include/core/decode_csarm.hpp
+++ b/libIRDB/include/core/decode_csarm.hpp
@@ -13,18 +13,18 @@ namespace libIRDB
 using namespace libIRDB;
 using namespace std;
 
-class DecodedOperandCapstoneARM_t;
-class DecodedInstructionCapstoneARM_t : public DecodedInstructionCapstone_t
+class DecodedOperandCapstoneARM64_t;
+class DecodedInstructionCapstoneARM64_t : public DecodedInstructionCapstone_t
 {
 	public:
-		DecodedInstructionCapstoneARM_t()=delete;
-		DecodedInstructionCapstoneARM_t(const Instruction_t*);
-		DecodedInstructionCapstoneARM_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len);
-		DecodedInstructionCapstoneARM_t(const virtual_offset_t start_addr, const void *data, const void* endptr);
-		DecodedInstructionCapstoneARM_t(const DecodedInstructionCapstoneARM_t& copy);
-		DecodedInstructionCapstoneARM_t& operator=(const DecodedInstructionCapstoneARM_t& copy);
+		DecodedInstructionCapstoneARM64_t()=delete;
+		DecodedInstructionCapstoneARM64_t(const Instruction_t*);
+		DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len);
+		DecodedInstructionCapstoneARM64_t(const virtual_offset_t start_addr, const void *data, const void* endptr);
+		DecodedInstructionCapstoneARM64_t(const DecodedInstructionCapstoneARM64_t& copy);
+		DecodedInstructionCapstoneARM64_t& operator=(const DecodedInstructionCapstoneARM64_t& copy);
 
-		virtual ~DecodedInstructionCapstoneARM_t();
+		virtual ~DecodedInstructionCapstoneARM64_t();
 
 		virtual string getDisassembly() const override;
 		virtual bool valid() const override;
@@ -70,9 +70,9 @@ class DecodedInstructionCapstoneARM_t : public DecodedInstructionCapstone_t
 		static CapstoneHandle_t *cs_handle;
 
 
-		friend class DecodedOperandCapstoneARM_t;
+		friend class DecodedOperandCapstoneARM64_t;
 
-		DecodedInstructionCapstoneARM_t(const shared_ptr<void> &my_insn);
+		DecodedInstructionCapstoneARM64_t(const shared_ptr<void> &my_insn);
 
 };
 
diff --git a/libIRDB/include/core/decode_dispatch.hpp b/libIRDB/include/core/decode_dispatch.hpp
index 1a5ef9f05..2e4e64b7f 100644
--- a/libIRDB/include/core/decode_dispatch.hpp
+++ b/libIRDB/include/core/decode_dispatch.hpp
@@ -56,7 +56,7 @@ class DecodedInstructionDispatcher_t
 
 	private:
 
-		std::shared_ptr<DecodedInstructionCapstoneX86_t> cs;
+		std::shared_ptr<DecodedInstructionCapstone_t> cs;
 
 };
 
diff --git a/libIRDB/include/core/fileir.hpp b/libIRDB/include/core/fileir.hpp
index c61fe787f..be61b6b23 100644
--- a/libIRDB/include/core/fileir.hpp
+++ b/libIRDB/include/core/fileir.hpp
@@ -94,6 +94,7 @@ class FileIR_t : public BaseObj_t
 		static int GetArchitectureBitWidth() ;
 		static void SetArchitecture(const int width, const ADMachineType_t mt);
 		void SetArchitecture();
+		static const ArchitectureDescription_t* GetArchitecture() { return archdesc; }
 
 		// Lookup a scoop by address
 		DataScoop_t* FindScoop(const libIRDB::virtual_offset_t &addr);
diff --git a/libIRDB/include/core/operand_csarm.hpp b/libIRDB/include/core/operand_csarm.hpp
index ad57f58f8..c7bbe8529 100644
--- a/libIRDB/include/core/operand_csarm.hpp
+++ b/libIRDB/include/core/operand_csarm.hpp
@@ -12,11 +12,11 @@ using namespace std;
 using namespace libIRDB;
 
 
-class DecodedOperandCapstoneARM_t : public DecodedOperandCapstone_t
+class DecodedOperandCapstoneARM64_t : public DecodedOperandCapstone_t
 {
 	public:
-		DecodedOperandCapstoneARM_t() =delete;
-		virtual ~DecodedOperandCapstoneARM_t();
+		DecodedOperandCapstoneARM64_t() =delete;
+		virtual ~DecodedOperandCapstoneARM64_t();
 
 		virtual bool isConstant() const override;
 		virtual uint64_t getConstant() const override;
@@ -51,12 +51,12 @@ class DecodedOperandCapstoneARM_t : public DecodedOperandCapstone_t
 
 	private:
 
-		DecodedOperandCapstoneARM_t( const shared_ptr<void> &my_insn, uint8_t op_num);
+		DecodedOperandCapstoneARM64_t( const shared_ptr<void> &my_insn, uint8_t op_num);
 
 		shared_ptr<void> my_insn;
 		uint8_t op_num;
 
-		friend class DecodedInstructionCapstoneARM_t;
+		friend class DecodedInstructionCapstoneARM64_t;
 
 };
 
diff --git a/libIRDB/include/core/operand_dispatch.hpp b/libIRDB/include/core/operand_dispatch.hpp
index 78cf5b167..e7edd8c9c 100644
--- a/libIRDB/include/core/operand_dispatch.hpp
+++ b/libIRDB/include/core/operand_dispatch.hpp
@@ -51,7 +51,7 @@ class DecodedOperandDispatcher_t
 	private:
 		DecodedOperandDispatcher_t(const shared_ptr<DecodedOperandCapstone_t> in);
 
-		std::shared_ptr<DecodedOperandCapstoneX86_t> cs;
+		std::shared_ptr<DecodedOperandCapstone_t> cs;
 
 		friend class DecodedInstructionDispatcher_t;
 
diff --git a/libIRDB/src/core/SConscript b/libIRDB/src/core/SConscript
index 9a0381744..af03160b9 100644
--- a/libIRDB/src/core/SConscript
+++ b/libIRDB/src/core/SConscript
@@ -29,6 +29,7 @@ files=  '''
 	operand_csarm.cpp
 	IRDB_Objects.cpp
 	decode_dispatch.cpp
+	decode_base.cpp
 	operand_dispatch.cpp
 '''
 unused_files='''
diff --git a/libIRDB/src/core/decode_base.cpp b/libIRDB/src/core/decode_base.cpp
new file mode 100644
index 000000000..09a3b6aaa
--- /dev/null
+++ b/libIRDB/src/core/decode_base.cpp
@@ -0,0 +1,39 @@
+
+#include <libIRDB-core.hpp>
+#include <core/decode_base.hpp>
+#include <core/operand_base.hpp>
+#include <core/decode_csx86.hpp>
+#include <core/operand_csx86.hpp>
+#include <core/decode_csarm.hpp>
+#include <core/operand_csarm.hpp>
+#include <exception>
+
+using namespace std;
+using namespace libIRDB;
+
+
+std::shared_ptr<DecodedInstructionCapstone_t> DecodedInstructionCapstone_t::factory(const libIRDB::Instruction_t* i)
+{
+	auto op=FileIR_t::GetArchitecture()->getMachineType()==admtAarch64 ? (DecodedInstructionCapstone_t*)new DecodedInstructionCapstoneARM64_t(i) : 
+		FileIR_t::GetArchitecture()->getMachineType()==admtX86_64  ? (DecodedInstructionCapstone_t*)new DecodedInstructionCapstoneX86_t  (i) : 
+		FileIR_t::GetArchitecture()->getMachineType()==admtI386    ? (DecodedInstructionCapstone_t*)new DecodedInstructionCapstoneX86_t  (i) : 
+		throw invalid_argument("Unknown machine type");
+	return shared_ptr<DecodedInstructionCapstone_t>(op);
+}
+std::shared_ptr<DecodedInstructionCapstone_t> DecodedInstructionCapstone_t::factory(const virtual_offset_t start_addr, const void *data, uint32_t max_len)
+{
+	auto op=FileIR_t::GetArchitecture()->getMachineType()==admtAarch64 ? (DecodedInstructionCapstone_t*)new DecodedInstructionCapstoneARM64_t(start_addr,data,max_len) : 
+		FileIR_t::GetArchitecture()->getMachineType()==admtX86_64  ? (DecodedInstructionCapstone_t*)new DecodedInstructionCapstoneX86_t  (start_addr,data,max_len) : 
+		FileIR_t::GetArchitecture()->getMachineType()==admtI386    ? (DecodedInstructionCapstone_t*)new DecodedInstructionCapstoneX86_t  (start_addr,data,max_len) : 
+		throw invalid_argument("Unknown machine type");
+	return shared_ptr<DecodedInstructionCapstone_t>(op);
+}
+std::shared_ptr<DecodedInstructionCapstone_t> DecodedInstructionCapstone_t::factory(const virtual_offset_t start_addr, const void *data, const void* endptr)
+{
+	auto op=FileIR_t::GetArchitecture()->getMachineType()==admtAarch64 ? (DecodedInstructionCapstone_t*)new DecodedInstructionCapstoneARM64_t(start_addr,data,endptr) : 
+		FileIR_t::GetArchitecture()->getMachineType()==admtX86_64  ? (DecodedInstructionCapstone_t*)new DecodedInstructionCapstoneX86_t  (start_addr,data,endptr) : 
+		FileIR_t::GetArchitecture()->getMachineType()==admtI386    ? (DecodedInstructionCapstone_t*)new DecodedInstructionCapstoneX86_t  (start_addr,data,endptr) : 
+		throw invalid_argument("Unknown machine type");
+	return shared_ptr<DecodedInstructionCapstone_t>(op);
+}
+
diff --git a/libIRDB/src/core/decode_csarm.cpp b/libIRDB/src/core/decode_csarm.cpp
index 00fc4ce30..f056121f4 100644
--- a/libIRDB/src/core/decode_csarm.cpp
+++ b/libIRDB/src/core/decode_csarm.cpp
@@ -14,9 +14,9 @@ using namespace std;
 
 #define ALLOF(a) begin(a),end(a)
 
-DecodedInstructionCapstoneARM_t::CapstoneHandle_t* DecodedInstructionCapstoneARM_t::cs_handle=NULL ;
+DecodedInstructionCapstoneARM64_t::CapstoneHandle_t* DecodedInstructionCapstoneARM64_t::cs_handle=NULL ;
 
-DecodedInstructionCapstoneARM_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp)
+DecodedInstructionCapstoneARM64_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp)
 {
 	const auto mode = CS_MODE_LITTLE_ENDIAN;
 	static_assert(sizeof(csh)==sizeof(handle), "Capstone handle size is unexpected.  Has CS changed?");
@@ -53,7 +53,7 @@ template<class type>
 static inline type insnToImmedHelper(cs_insn* the_insn, csh handle)
 {
         const auto count = cs_op_count(handle, the_insn, ARM64_OP_IMM);
-	const auto arm = &(the_insn->detail->arm);
+	const auto arm = &(the_insn->detail->arm64);
 
         if (count==0) 
 		return 0;	 /* no immediate is the same as an immediate of 0, i guess? */
@@ -71,7 +71,7 @@ static inline type insnToImmedHelper(cs_insn* the_insn, csh handle)
 // shared code 
 // constructors, destructors, operators.
 
-void DecodedInstructionCapstoneARM_t::Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len)
+void DecodedInstructionCapstoneARM64_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());
@@ -92,7 +92,7 @@ void DecodedInstructionCapstoneARM_t::Disassemble(const virtual_offset_t start_a
 	my_insn.reset(insn,cs_freer);
 }
 
-DecodedInstructionCapstoneARM_t::DecodedInstructionCapstoneARM_t(const Instruction_t* i)
+DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_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*)");
@@ -106,35 +106,35 @@ DecodedInstructionCapstoneARM_t::DecodedInstructionCapstoneARM_t(const Instructi
 	if(!valid()) throw std::invalid_argument("The Instruction_t::GetDataBits field is not a valid instruction.");
 }
 
-DecodedInstructionCapstoneARM_t::DecodedInstructionCapstoneARM_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len)
+DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_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);
 }
 
-DecodedInstructionCapstoneARM_t::DecodedInstructionCapstoneARM_t(const virtual_offset_t start_addr, const void *data, const void* endptr)
+DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_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);
 }
 
-DecodedInstructionCapstoneARM_t::DecodedInstructionCapstoneARM_t(const DecodedInstructionCapstoneARM_t& copy)
+DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const DecodedInstructionCapstoneARM64_t& copy)
 {
 	*this=copy;
 }
 
-DecodedInstructionCapstoneARM_t::DecodedInstructionCapstoneARM_t(const shared_ptr<void> &p_my_insn)
+DecodedInstructionCapstoneARM64_t::DecodedInstructionCapstoneARM64_t(const shared_ptr<void> &p_my_insn)
 	: my_insn(p_my_insn)
 {
 }
 
-DecodedInstructionCapstoneARM_t::~DecodedInstructionCapstoneARM_t()
+DecodedInstructionCapstoneARM64_t::~DecodedInstructionCapstoneARM64_t()
 {
 	// no need to cs_free(my_insn) because shared pointer will do that for us!
 }
 
-DecodedInstructionCapstoneARM_t& DecodedInstructionCapstoneARM_t::operator=(const DecodedInstructionCapstoneARM_t& copy)
+DecodedInstructionCapstoneARM64_t& DecodedInstructionCapstoneARM64_t::operator=(const DecodedInstructionCapstoneARM64_t& copy)
 {
 	my_insn=copy.my_insn;
 	return *this;
@@ -142,7 +142,7 @@ DecodedInstructionCapstoneARM_t& DecodedInstructionCapstoneARM_t::operator=(cons
 
 // public methods
 
-string DecodedInstructionCapstoneARM_t::getDisassembly() const
+string DecodedInstructionCapstoneARM64_t::getDisassembly() const
 {
 
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
@@ -152,27 +152,27 @@ string DecodedInstructionCapstoneARM_t::getDisassembly() const
 	return full_str;
 }
 
-bool DecodedInstructionCapstoneARM_t::valid() const
+bool DecodedInstructionCapstoneARM64_t::valid() const
 {
 	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
 	return the_insn->size!=0;
 }
 
-uint32_t DecodedInstructionCapstoneARM_t::length() const
+uint32_t DecodedInstructionCapstoneARM64_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 DecodedInstructionCapstoneARM_t::isBranch() const
+bool DecodedInstructionCapstoneARM64_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 DecodedInstructionCapstoneARM_t::isCall() const
+bool DecodedInstructionCapstoneARM64_t::isCall() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 
@@ -180,7 +180,7 @@ bool DecodedInstructionCapstoneARM_t::isCall() const
 	return isPartOfGroup(the_insn,ARM64_GRP_CALL);
 }
 
-bool DecodedInstructionCapstoneARM_t::isUnconditionalBranch() const
+bool DecodedInstructionCapstoneARM64_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());
@@ -188,39 +188,39 @@ bool DecodedInstructionCapstoneARM_t::isUnconditionalBranch() const
 	return isJmp(the_insn) && !isConditionalBranch();
 }
 
-bool DecodedInstructionCapstoneARM_t::isConditionalBranch() const
+bool DecodedInstructionCapstoneARM64_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";
+	return isJmp(the_insn) && getMnemonic()!="br";
 }
 
-bool DecodedInstructionCapstoneARM_t::isReturn() const
+bool DecodedInstructionCapstoneARM64_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,ARM64_GRP_RET);
 }
 
-bool DecodedInstructionCapstoneARM_t::hasOperand(const int op_num) const
+bool DecodedInstructionCapstoneARM64_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());
-	const auto &arm = (the_insn->detail->arm);
+	const auto &arm = (the_insn->detail->arm64);
 	return 0 <= op_num  && op_num < arm.op_count;
 }
 
 // 0-based.  first operand is numbered 0.
-shared_ptr<DecodedOperandCapstone_t> DecodedInstructionCapstoneARM_t::getOperand(const int op_num) const
+shared_ptr<DecodedOperandCapstone_t> DecodedInstructionCapstoneARM64_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 shared_ptr<DecodedOperandCapstone_t>(new DecodedOperandCapstoneARM_t(my_insn,(uint8_t)op_num));
+	return shared_ptr<DecodedOperandCapstone_t>(new DecodedOperandCapstoneARM64_t(my_insn,(uint8_t)op_num));
 	
 }
 
-DecodedOperandCapstoneVector_t DecodedInstructionCapstoneARM_t::getOperands() const
+DecodedOperandCapstoneVector_t DecodedInstructionCapstoneARM64_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());
@@ -235,7 +235,7 @@ DecodedOperandCapstoneVector_t DecodedInstructionCapstoneARM_t::getOperands() co
 	return ret_val;
 }
 
-string DecodedInstructionCapstoneARM_t::getMnemonic() const
+string DecodedInstructionCapstoneARM64_t::getMnemonic() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 
@@ -247,7 +247,7 @@ string DecodedInstructionCapstoneARM_t::getMnemonic() const
 }
 
 
-int64_t DecodedInstructionCapstoneARM_t::getImmediate() const
+int64_t DecodedInstructionCapstoneARM64_t::getImmediate() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 
@@ -261,28 +261,31 @@ int64_t DecodedInstructionCapstoneARM_t::getImmediate() const
 }
 
 
-virtual_offset_t DecodedInstructionCapstoneARM_t::getAddress() const
+virtual_offset_t DecodedInstructionCapstoneARM64_t::getAddress() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+	if(isCall() || isJmp(the_insn))
+		return insnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle());
 	assert(0);
 
 }
 
 
-bool DecodedInstructionCapstoneARM_t::setsStackPointer() const
+bool DecodedInstructionCapstoneARM64_t::setsStackPointer() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 
 	assert (0);
 }
 
-uint32_t DecodedInstructionCapstoneARM_t::getPrefixCount() const
+uint32_t DecodedInstructionCapstoneARM64_t::getPrefixCount() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	return 0;
 }
 
-virtual_offset_t DecodedInstructionCapstoneARM_t::getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t, const Instruction_t* insn) const
+virtual_offset_t DecodedInstructionCapstoneARM64_t::getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t, const Instruction_t* insn) const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	assert(0);
@@ -290,31 +293,31 @@ virtual_offset_t DecodedInstructionCapstoneARM_t::getMemoryDisplacementOffset(co
 
 
 
-bool DecodedInstructionCapstoneARM_t::hasRelevantRepPrefix() const
+bool DecodedInstructionCapstoneARM64_t::hasRelevantRepPrefix() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	return false;
 }
 
-bool DecodedInstructionCapstoneARM_t::hasRelevantRepnePrefix() const
+bool DecodedInstructionCapstoneARM64_t::hasRelevantRepnePrefix() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	return false;
 }
 
-bool DecodedInstructionCapstoneARM_t::hasRelevantOperandSizePrefix() const
+bool DecodedInstructionCapstoneARM64_t::hasRelevantOperandSizePrefix() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	return false;
 }
 
-bool DecodedInstructionCapstoneARM_t::hasRexWPrefix() const
+bool DecodedInstructionCapstoneARM64_t::hasRexWPrefix() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	return false;
 }
 
-bool DecodedInstructionCapstoneARM_t::hasImplicitlyModifiedRegs() const
+bool DecodedInstructionCapstoneARM64_t::hasImplicitlyModifiedRegs() const
 {
 	if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction");
 	return false;
diff --git a/libIRDB/src/core/decode_dispatch.cpp b/libIRDB/src/core/decode_dispatch.cpp
index 4e2c237b7..ad7fd9f87 100644
--- a/libIRDB/src/core/decode_dispatch.cpp
+++ b/libIRDB/src/core/decode_dispatch.cpp
@@ -10,23 +10,22 @@ using namespace std;
 
 DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const Instruction_t* i) 
 {
-	cs.reset(new DecodedInstructionCapstoneX86_t(i));
+	cs=DecodedInstructionCapstone_t::factory(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));
+	cs=DecodedInstructionCapstone_t::factory(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));
+	cs=DecodedInstructionCapstone_t::factory(start_addr,data,endptr);
 }
 
 DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const DecodedInstructionDispatcher_t& copy) 
 {
-	const auto copy_cs_casted=dynamic_cast<DecodedInstructionCapstoneX86_t*>(copy.cs.get());
-	cs.reset(new DecodedInstructionCapstoneX86_t(*copy_cs_casted));
+	cs=copy.cs; 
 }
 
 DecodedInstructionDispatcher_t::~DecodedInstructionDispatcher_t()
@@ -35,15 +34,14 @@ DecodedInstructionDispatcher_t::~DecodedInstructionDispatcher_t()
 
 DecodedInstructionDispatcher_t& DecodedInstructionDispatcher_t::operator=(const DecodedInstructionDispatcher_t& copy)
 {
-	const auto copy_cs_casted=dynamic_cast<DecodedInstructionCapstoneX86_t*>(copy.cs.get());
-	cs.reset(new DecodedInstructionCapstoneX86_t(*copy_cs_casted));
+	cs=copy.cs; 
 	return *this;
 }
 
 
 
 #define passthrough_to_cs(ret_type, method_name) 						\
-	ret_type DecodedInstructionDispatcher_t::method_name() const 					\
+	ret_type DecodedInstructionDispatcher_t::method_name() const 				\
 	{ 											\
 		return cs->method_name(); 							\
 	} 
diff --git a/libIRDB/src/core/operand_csarm.cpp b/libIRDB/src/core/operand_csarm.cpp
index 4ff216a5f..41be6b281 100644
--- a/libIRDB/src/core/operand_csarm.cpp
+++ b/libIRDB/src/core/operand_csarm.cpp
@@ -1,8 +1,8 @@
 
 #include <libIRDB-core.hpp>
 #include <memory>
-#include <core/operand_csx86.hpp>
-#include <core/decode_csx86.hpp>
+#include <core/operand_csarm.hpp>
+#include <core/decode_csarm.hpp>
 
 using namespace std;
 using namespace libIRDB;
@@ -11,7 +11,7 @@ using namespace libIRDB;
 
 
 
-DecodedOperandCapstoneARM_t::DecodedOperandCapstoneARM_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num)
+DecodedOperandCapstoneARM64_t::DecodedOperandCapstoneARM64_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num)
 	:
 	my_insn(p_my_insn),
 	op_num(p_op_num)
@@ -19,169 +19,272 @@ DecodedOperandCapstoneARM_t::DecodedOperandCapstoneARM_t( const shared_ptr<void>
 	
 }
 
-DecodedOperandCapstoneARM_t::~DecodedOperandCapstoneARM_t()
+DecodedOperandCapstoneARM64_t::~DecodedOperandCapstoneARM64_t()
 {
 }
 
 
-bool DecodedOperandCapstoneARM_t::isConstant() const
+bool DecodedOperandCapstoneARM64_t::isConstant() const
 {
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
-        const auto &op = (the_insn->detail->arm.operands[op_num]);
-
-	return op.type==ARM_OP_IMM;
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+	return op.type==ARM64_OP_IMM;
 }
 
-uint64_t DecodedOperandCapstoneARM_t::getConstant() const
+uint64_t DecodedOperandCapstoneARM64_t::getConstant() const
 {
 	if(!isConstant()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-constant operand");
 	
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
-        const auto &op = (the_insn->detail->arm.operands[op_num]);
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
 	return op.imm;
 }
 
-string DecodedOperandCapstoneARM_t::getString() const
+string DecodedOperandCapstoneARM64_t::getString() const
 {
-	assert(0);
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+        const auto handle=DecodedInstructionCapstoneARM64_t::cs_handle->getHandle();
+
+        switch(op.type)
+        {
+                case ARM64_OP_REG:
+                        return string(cs_reg_name(handle, op.reg));
+                case ARM64_OP_IMM:
+                        return to_string(op.imm);
+                case ARM64_OP_MEM:
+                {
+			string ret_val;
+			if (op.mem.base != ARM64_REG_INVALID)
+				ret_val+=cs_reg_name(handle, op.mem.base);
+
+			if (op.mem.index != ARM64_REG_INVALID)
+				ret_val+=string(" + ") +cs_reg_name(handle, op.mem.index);
+
+			if (op.mem.disp != 0)
+				ret_val+=" + "+ to_string(op.mem.disp);
+
+			if(ret_val=="")
+				return "0";
+
+			return ret_val;
+		}
+                default:
+                        assert(0);
+        }
 }
 
-bool DecodedOperandCapstoneARM_t::isRegister() const
+bool DecodedOperandCapstoneARM64_t::isRegister() const
 {
-	assert(0);
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+	return op.type==ARM64_OP_REG;
 }
 
-bool DecodedOperandCapstoneARM_t::isGeneralPurposeRegister() const
+bool DecodedOperandCapstoneARM64_t::isGeneralPurposeRegister() const
 {
-	assert(0);
+	const auto gp_regs=set<arm64_reg>({
+		ARM64_REG_X29, ARM64_REG_X30, ARM64_REG_SP, ARM64_REG_WSP, ARM64_REG_WZR, ARM64_REG_XZR,
+		ARM64_REG_W0, ARM64_REG_W1, ARM64_REG_W2, ARM64_REG_W3, ARM64_REG_W4, ARM64_REG_W5, ARM64_REG_W6, ARM64_REG_W7,
+        	ARM64_REG_W8, ARM64_REG_W9, ARM64_REG_W10, ARM64_REG_W11, ARM64_REG_W12, ARM64_REG_W13, ARM64_REG_W14, ARM64_REG_W15,
+        	ARM64_REG_W16, ARM64_REG_W17, ARM64_REG_W18, ARM64_REG_W19, ARM64_REG_W20, ARM64_REG_W21, ARM64_REG_W22, ARM64_REG_W23, 
+		ARM64_REG_W24, ARM64_REG_W25, ARM64_REG_W26, ARM64_REG_W27, ARM64_REG_W28, ARM64_REG_W29, ARM64_REG_W30, 
+		ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X4, ARM64_REG_X5, ARM64_REG_X6, ARM64_REG_X7,
+		ARM64_REG_X8, ARM64_REG_X9, ARM64_REG_X10, ARM64_REG_X11, ARM64_REG_X12, ARM64_REG_X13, ARM64_REG_X14, ARM64_REG_X15,
+		ARM64_REG_X16, ARM64_REG_X17, ARM64_REG_X18, ARM64_REG_X19, ARM64_REG_X20, ARM64_REG_X21, ARM64_REG_X22, ARM64_REG_X23,
+		ARM64_REG_X24, ARM64_REG_X25, ARM64_REG_X26, ARM64_REG_X27, ARM64_REG_X28,
+	});
+
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+        return isRegister() &&  gp_regs.find(op.reg)!=end(gp_regs);
+
 }
 
-bool DecodedOperandCapstoneARM_t::isMmxRegister() const
+bool DecodedOperandCapstoneARM64_t::isMmxRegister() const
 {
 	return false;
 }
 
-bool DecodedOperandCapstoneARM_t::isFpuRegister() const
+bool DecodedOperandCapstoneARM64_t::isFpuRegister() const
 {
-	return false;
+	const auto fpu_regs=set<arm64_reg>({
+		ARM64_REG_B0, ARM64_REG_B1, ARM64_REG_B2, ARM64_REG_B3, ARM64_REG_B4, ARM64_REG_B5, ARM64_REG_B6, ARM64_REG_B7,
+        	ARM64_REG_B8, ARM64_REG_B9, ARM64_REG_B10, ARM64_REG_B11, ARM64_REG_B12, ARM64_REG_B13, ARM64_REG_B14, ARM64_REG_B15,
+        	ARM64_REG_B16, ARM64_REG_B17, ARM64_REG_B18, ARM64_REG_B19, ARM64_REG_B20, ARM64_REG_B21, ARM64_REG_B22, ARM64_REG_B23,
+        	ARM64_REG_B24, ARM64_REG_B25, ARM64_REG_B26, ARM64_REG_B27, ARM64_REG_B28, ARM64_REG_B29, ARM64_REG_B30, ARM64_REG_B31,
+		ARM64_REG_H0, ARM64_REG_H1, ARM64_REG_H2, ARM64_REG_H3, ARM64_REG_H4, ARM64_REG_H5, ARM64_REG_H6, ARM64_REG_H7, 
+		ARM64_REG_H8, ARM64_REG_H9, ARM64_REG_H10, ARM64_REG_H11, ARM64_REG_H12, ARM64_REG_H13, ARM64_REG_H14, ARM64_REG_H15, 
+		ARM64_REG_H16, ARM64_REG_H17, ARM64_REG_H18, ARM64_REG_H19, ARM64_REG_H20, ARM64_REG_H21, ARM64_REG_H22, ARM64_REG_H23, 
+		ARM64_REG_H24, ARM64_REG_H25, ARM64_REG_H26, ARM64_REG_H27, ARM64_REG_H28, ARM64_REG_H29, ARM64_REG_H30, ARM64_REG_H31, 
+	        ARM64_REG_D0, ARM64_REG_D1, ARM64_REG_D2, ARM64_REG_D3, ARM64_REG_D4, ARM64_REG_D5, ARM64_REG_D6, ARM64_REG_D7,
+        	ARM64_REG_D8, ARM64_REG_D9, ARM64_REG_D10, ARM64_REG_D11, ARM64_REG_D12, ARM64_REG_D13, ARM64_REG_D14, ARM64_REG_D15,
+		ARM64_REG_D16, ARM64_REG_D17, ARM64_REG_D18, ARM64_REG_D19, ARM64_REG_D20, ARM64_REG_D21, ARM64_REG_D22, ARM64_REG_D23,
+		ARM64_REG_D24, ARM64_REG_D25, ARM64_REG_D26, ARM64_REG_D27, ARM64_REG_D28, ARM64_REG_D29, ARM64_REG_D30, ARM64_REG_D31,
+	        ARM64_REG_H0, ARM64_REG_H1, ARM64_REG_H2, ARM64_REG_H3, ARM64_REG_H4, ARM64_REG_H5, ARM64_REG_H6, ARM64_REG_H7,
+		ARM64_REG_H8, ARM64_REG_H9, ARM64_REG_H10, ARM64_REG_H11, ARM64_REG_H12, ARM64_REG_H13, ARM64_REG_H14, ARM64_REG_H15,
+		ARM64_REG_H16, ARM64_REG_H17, ARM64_REG_H18, ARM64_REG_H19, ARM64_REG_H20, ARM64_REG_H21, ARM64_REG_H22, ARM64_REG_H23,
+		ARM64_REG_H24, ARM64_REG_H25, ARM64_REG_H26, ARM64_REG_H27, ARM64_REG_H28, ARM64_REG_H29, ARM64_REG_H30, ARM64_REG_H31,
+	        ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_Q6, ARM64_REG_Q7,
+		ARM64_REG_Q8, ARM64_REG_Q9, ARM64_REG_Q10, ARM64_REG_Q11, ARM64_REG_Q12, ARM64_REG_Q13, ARM64_REG_Q14, ARM64_REG_Q15,
+		ARM64_REG_Q16, ARM64_REG_Q17, ARM64_REG_Q18, ARM64_REG_Q19, ARM64_REG_Q20, ARM64_REG_Q21, ARM64_REG_Q22, ARM64_REG_Q23,
+		ARM64_REG_Q24, ARM64_REG_Q25, ARM64_REG_Q26, ARM64_REG_Q27, ARM64_REG_Q28, ARM64_REG_Q29, ARM64_REG_Q30, ARM64_REG_Q31,
+		ARM64_REG_S0, ARM64_REG_S1, ARM64_REG_S2, ARM64_REG_S3, ARM64_REG_S4, ARM64_REG_S5, ARM64_REG_S6, ARM64_REG_S7,
+		ARM64_REG_S8, ARM64_REG_S9, ARM64_REG_S10, ARM64_REG_S11, ARM64_REG_S12, ARM64_REG_S13, ARM64_REG_S14, ARM64_REG_S15,
+		ARM64_REG_S16, ARM64_REG_S17, ARM64_REG_S18, ARM64_REG_S19, ARM64_REG_S20, ARM64_REG_S21, ARM64_REG_S22, ARM64_REG_S23,
+		ARM64_REG_S24, ARM64_REG_S25, ARM64_REG_S26, ARM64_REG_S27, ARM64_REG_S28, ARM64_REG_S29, ARM64_REG_S30, ARM64_REG_S31,
+	});
+
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+        return isRegister() &&  fpu_regs.find(op.reg)!=end(fpu_regs);
 }
 
-bool DecodedOperandCapstoneARM_t::isSseRegister() const
+bool DecodedOperandCapstoneARM64_t::isSseRegister() const
 {
 	return false;
 }
 
-bool DecodedOperandCapstoneARM_t::isAvxRegister() const
+bool DecodedOperandCapstoneARM64_t::isAvxRegister() const
 {
 	return false;
 }
 
-bool DecodedOperandCapstoneARM_t::isZmmRegister() const
+bool DecodedOperandCapstoneARM64_t::isZmmRegister() const
 {
 	return false;
 }
 
-bool DecodedOperandCapstoneARM_t::isSpecialRegister() const
+bool DecodedOperandCapstoneARM64_t::isSpecialRegister() const
 {
+	const auto special_regs=set<arm64_reg>({
+		ARM64_REG_NZCV,
+	});
+
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+        return isRegister() &&  special_regs.find(op.reg)!=end(special_regs);
 	return false;
 }
 
-bool DecodedOperandCapstoneARM_t::isSegmentRegister() const
+bool DecodedOperandCapstoneARM64_t::isSegmentRegister() const
 {
 	return false;
 }
 
 
 
-uint32_t DecodedOperandCapstoneARM_t::getRegNumber() const
+uint32_t DecodedOperandCapstoneARM64_t::getRegNumber() const
 {
-	assert(0);
+        const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+	return op.reg;
 }
 
-bool DecodedOperandCapstoneARM_t::isMemory() const
+bool DecodedOperandCapstoneARM64_t::isMemory() const
 {
-	assert(0);
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+        return op.type==ARM64_OP_MEM;
+
 }
 
-bool DecodedOperandCapstoneARM_t::hasBaseRegister() const
+bool DecodedOperandCapstoneARM64_t::hasBaseRegister() const
 {
-	assert(0);
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+        return isMemory() && op.mem.base!=ARM64_REG_INVALID;
+
 }
 
-bool DecodedOperandCapstoneARM_t::hasIndexRegister() const
+bool DecodedOperandCapstoneARM64_t::hasIndexRegister() const
 {
-	assert(0);
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+        return isMemory() && op.mem.index!=ARM64_REG_INVALID;
 }
 
-uint32_t DecodedOperandCapstoneARM_t::getBaseRegister() const
+uint32_t DecodedOperandCapstoneARM64_t::getBaseRegister() const
 {
-	assert(0);
+	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+        return op.mem.base;
 }
 
-uint32_t DecodedOperandCapstoneARM_t::getIndexRegister() const
+uint32_t DecodedOperandCapstoneARM64_t::getIndexRegister() const
 {
-	assert(0);
+	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+        return op.mem.index;
 }
 
-uint32_t DecodedOperandCapstoneARM_t::getScaleValue() const
+uint32_t DecodedOperandCapstoneARM64_t::getScaleValue() const
 {
 	assert(0);
 }
 
-bool DecodedOperandCapstoneARM_t::hasMemoryDisplacement() const
+bool DecodedOperandCapstoneARM64_t::hasMemoryDisplacement() const
 {
-	assert(0);
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+        return op.mem.disp!=0;
 
-} // end of DecodedOperandCapstoneARM_t::hasMemoryDisplacement()
+} // end of DecodedOperandCapstoneARM64_t::hasMemoryDisplacement()
 
-virtual_offset_t DecodedOperandCapstoneARM_t::getMemoryDisplacement() const
+virtual_offset_t DecodedOperandCapstoneARM64_t::getMemoryDisplacement() const
 {
-	assert(0);
+	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
+	const auto the_insn=static_cast<cs_insn*>(my_insn.get());
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
+        return op.mem.disp;
 }
 
-bool DecodedOperandCapstoneARM_t::isPcrel() const
+bool DecodedOperandCapstoneARM64_t::isPcrel() const
 {
-	assert(0);
+        if(!isMemory()) return false;
+	return false;	 // no PC as general purpose reg.
 }
 
 /* in bytes */
-uint32_t DecodedOperandCapstoneARM_t::getMemoryDisplacementEncodingSize() const
+uint32_t DecodedOperandCapstoneARM64_t::getMemoryDisplacementEncodingSize() const
 {
 	if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+"  of non-memory operand");
 	assert(0);
 }
 
-uint32_t DecodedOperandCapstoneARM_t::getArgumentSizeInBytes() const
+uint32_t DecodedOperandCapstoneARM64_t::getArgumentSizeInBytes() const
 {
-	assert(0);
+	return false;
 }
 
-uint32_t DecodedOperandCapstoneARM_t::getArgumentSizeInBits() const
+uint32_t DecodedOperandCapstoneARM64_t::getArgumentSizeInBits() const
 {
-	assert(0);
+        return getArgumentSizeInBytes()*8;
 }
 
-bool DecodedOperandCapstoneARM_t::hasSegmentRegister() const
+bool DecodedOperandCapstoneARM64_t::hasSegmentRegister() const
 {
 	return false;
 }
 
-uint32_t DecodedOperandCapstoneARM_t::getSegmentRegister() const
+uint32_t DecodedOperandCapstoneARM64_t::getSegmentRegister() const
 {
-	assert(0);
+	throw std::logic_error(string("Cannot ")+__FUNCTION__+"  on ARM architecture");
 }
 
-bool DecodedOperandCapstoneARM_t::isRead() const
+bool DecodedOperandCapstoneARM64_t::isRead() const
 {
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
-        const auto &op = (the_insn->detail->arm.operands[op_num]);
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
 	return (op.access & CS_AC_READ)!=0;
 }
 
-bool DecodedOperandCapstoneARM_t::isWritten() const
+bool DecodedOperandCapstoneARM64_t::isWritten() const
 {	
 	// default: use capstone's advice.
         const auto the_insn=static_cast<cs_insn*>(my_insn.get());
-        const auto &op = (the_insn->detail->x86.operands[op_num]);
+        const auto &op = (the_insn->detail->arm64.operands[op_num]);
 	return (op.access & CS_AC_WRITE)!=0;
 }
diff --git a/libIRDB/src/core/operand_dispatch.cpp b/libIRDB/src/core/operand_dispatch.cpp
index 3c37b8222..bf6c75146 100644
--- a/libIRDB/src/core/operand_dispatch.cpp
+++ b/libIRDB/src/core/operand_dispatch.cpp
@@ -10,14 +10,12 @@ using namespace libIRDB;
 
 DecodedOperandDispatcher_t::DecodedOperandDispatcher_t(const shared_ptr<DecodedOperandCapstone_t> copy_cs)  
 {
-	const auto copy_cs_casted=dynamic_cast<DecodedOperandCapstoneX86_t*>(copy_cs.get());
-	cs.reset(new DecodedOperandCapstoneX86_t(*copy_cs_casted));
+	cs=copy_cs;
 } 
 
 DecodedOperandDispatcher_t::DecodedOperandDispatcher_t(const DecodedOperandDispatcher_t& copy) 
 {
-	const auto copy_cs_casted=dynamic_cast<DecodedOperandCapstoneX86_t*>(copy.cs.get());
-	cs.reset(new DecodedOperandCapstoneX86_t(*copy_cs_casted));
+	cs=copy.cs;
 }
 
 DecodedOperandDispatcher_t::~DecodedOperandDispatcher_t()
@@ -26,8 +24,7 @@ DecodedOperandDispatcher_t::~DecodedOperandDispatcher_t()
 
 DecodedOperandDispatcher_t& DecodedOperandDispatcher_t::operator=(const DecodedOperandDispatcher_t& copy)
 {
-	const auto copy_cs_casted=dynamic_cast<DecodedOperandCapstoneX86_t*>(copy.cs.get());
-	cs.reset(new DecodedOperandCapstoneX86_t(*copy_cs_casted));
+	cs=copy.cs;
 	return *this;
 }
 
diff --git a/libehp b/libehp
index 844394fef..bd396bff6 160000
--- a/libehp
+++ b/libehp
@@ -1 +1 @@
-Subproject commit 844394fefeb8197007510824e71c905dafb0e5d9
+Subproject commit bd396bff642ca89bc4c169749f721d8652ec8b79
diff --git a/xform/rewriter.cpp b/xform/rewriter.cpp
index e31f2d9c5..fed74f5a9 100644
--- a/xform/rewriter.cpp
+++ b/xform/rewriter.cpp
@@ -639,6 +639,7 @@ void Rewriter::readElfFile(char p_filename[])
 	if(!objdump)
 		objdump=strdup("objdump");
 	sprintf(buf, "%s -d --prefix-addresses %s | grep \"^[0-9]\"", objdump, p_filename);
+	printf("Running objdump, like so: %s\n", buf);
 	FILE* pin=popen(buf, "r");
 	app_iaddr_t addr;
 
@@ -652,7 +653,10 @@ void Rewriter::readElfFile(char p_filename[])
 	do 
 	{
 		if(m_instructions[addr]==NULL)
+		{
+			cout<<"Found instruction from objdump at "<<hex<<addr<<endl;
 			m_instructions[addr]=new wahoo::Instruction(addr,-1,NULL);
+		}
 		ignore_result(fscanf(pin,"%p", &tmp));
 		addr=(app_iaddr_t)tmp;
 		ignore_result(fgets(buf,sizeof(buf),pin));
-- 
GitLab