From f3ab753677478d4bc8d58d805740f913a4ef251d Mon Sep 17 00:00:00 2001
From: jdh8d <jdh8d@git.zephyr-software.com>
Date: Mon, 5 Feb 2018 19:45:35 +0000
Subject: [PATCH] libIRDB IR-builder separation from BEA

Former-commit-id: 563a2ec0a5c1b14cc52d54caf74058e60e8513aa
---
 .gitattributes                     |   6 +
 libIRDB/include/decode/decode.hpp  |  52 +++++
 libIRDB/include/decode/operand.hpp |  46 ++++
 libIRDB/include/libIRDB-decode.hpp |   8 +
 libIRDB/src/SConscript             |   1 +
 libIRDB/src/decode/SConscript      |  28 +++
 libIRDB/src/decode/decode.cpp      | 154 +++++++++++++
 libIRDB/src/decode/operand.cpp     | 168 ++++++++++++++
 libIRDB/test/SConscript            |   2 +-
 libIRDB/test/fill_in_cfg.cpp       |  71 +++---
 libIRDB/test/fill_in_indtargs.cpp  | 345 ++++++++++++++++-------------
 libIRDB/test/split_eh_frame.cpp    |  19 +-
 12 files changed, 704 insertions(+), 196 deletions(-)
 create mode 100644 libIRDB/include/decode/decode.hpp
 create mode 100644 libIRDB/include/decode/operand.hpp
 create mode 100644 libIRDB/include/libIRDB-decode.hpp
 create mode 100644 libIRDB/src/decode/SConscript
 create mode 100644 libIRDB/src/decode/decode.cpp
 create mode 100644 libIRDB/src/decode/operand.cpp

diff --git a/.gitattributes b/.gitattributes
index 9e2ff2e43..37d9e0189 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -223,8 +223,11 @@ libIRDB/include/core/reloc.hpp -text
 libIRDB/include/core/scoop.hpp -text
 libIRDB/include/core/type.hpp -text
 libIRDB/include/core/variantid.hpp -text
+libIRDB/include/decode/decode.hpp -text
+libIRDB/include/decode/operand.hpp -text
 libIRDB/include/libIRDB-cfg.hpp -text
 libIRDB/include/libIRDB-core.hpp -text
+libIRDB/include/libIRDB-decode.hpp -text
 libIRDB/include/libIRDB-syscall.hpp -text
 libIRDB/include/libIRDB-util.hpp -text
 libIRDB/include/syscall/syscall.hpp -text
@@ -260,6 +263,9 @@ libIRDB/src/core/reloc.cpp -text
 libIRDB/src/core/scoop.cpp -text
 libIRDB/src/core/type.cpp -text
 libIRDB/src/core/variantid.cpp -text
+libIRDB/src/decode/SConscript -text
+libIRDB/src/decode/decode.cpp -text
+libIRDB/src/decode/operand.cpp -text
 libIRDB/src/syscall/Makefile.in -text
 libIRDB/src/syscall/SConscript -text
 libIRDB/src/syscall/SConstruct -text
diff --git a/libIRDB/include/decode/decode.hpp b/libIRDB/include/decode/decode.hpp
new file mode 100644
index 000000000..8dd3ff32f
--- /dev/null
+++ b/libIRDB/include/decode/decode.hpp
@@ -0,0 +1,52 @@
+#ifndef libirdb_decode_hpp
+#define libirdb_decode_hpp
+
+#include <stdint.h>
+
+namespace libIRDB
+{
+
+using namespace libIRDB;
+using namespace std;
+
+class DecodedOperand_t;
+
+class DecodedInstruction_t
+{
+	public:
+		DecodedInstruction_t()=delete;
+		DecodedInstruction_t(const Instruction_t*);
+		DecodedInstruction_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len);
+		DecodedInstruction_t(const virtual_offset_t start_addr, const void *data, const void* endptr);
+		DecodedInstruction_t(const DecodedInstruction_t& copy);
+		DecodedInstruction_t& operator=(const DecodedInstruction_t& copy);
+
+		virtual ~DecodedInstruction_t();
+
+		string getDisassembly() const;
+		bool valid() const;
+		uint32_t length() const;
+		bool isBranch() const;
+		bool isUnconditionalBranch() const;
+		bool isConditionalBranch() const;
+		bool isReturn() const;
+		string getMnemonic() const;
+		virtual_offset_t getImmediate() const;
+		virtual_offset_t getAddress() const;
+
+
+
+
+		// 0-based.  first operand is numbered 0.
+		DecodedOperand_t getOperand(const int op_num) 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/decode/operand.hpp b/libIRDB/include/decode/operand.hpp
new file mode 100644
index 000000000..797c0e087
--- /dev/null
+++ b/libIRDB/include/decode/operand.hpp
@@ -0,0 +1,46 @@
+#ifndef libRIDB_decodedoperand_hpp
+#define libRIDB_decodedoperand_hpp
+
+namespace libIRDB
+{
+
+using namespace std;
+using namespace libIRDB;
+
+
+class DecodedOperand_t
+{
+	public:
+		DecodedOperand_t() =delete;
+		DecodedOperand_t& operator=(const DecodedOperand_t& copy);
+		DecodedOperand_t(const DecodedOperand_t& copy);
+		virtual ~DecodedOperand_t();
+
+		bool isConstant() const;
+		string getString() const;
+		bool isWrite() const;
+		bool isRegister() const;
+		uint32_t getRegNumber() const;
+		bool isMemory() const;
+		bool hasBaseRegister() const;
+		bool hasIndexRegister() const;
+		uint32_t getBaseRegister() const;
+		uint32_t getIndexRegister() const;
+		virtual_offset_t getMemoryDisplacement() const;
+		bool isPcrel() const;
+		uint32_t getScaleValue() const;
+
+
+
+	private:
+
+
+		void* arg_data;
+		DecodedOperand_t(void* arg_p);
+
+		friend class DecodedInstruction_t;
+
+};
+
+}
+#endif
diff --git a/libIRDB/include/libIRDB-decode.hpp b/libIRDB/include/libIRDB-decode.hpp
new file mode 100644
index 000000000..f05189c36
--- /dev/null
+++ b/libIRDB/include/libIRDB-decode.hpp
@@ -0,0 +1,8 @@
+#ifndef libIRDB_core_hpp
+#define libIRDB_core_hpp
+
+#include <libIRDB-core.hpp>
+#include <decode/operand.hpp>
+#include <decode/decode.hpp>
+
+#endif
diff --git a/libIRDB/src/SConscript b/libIRDB/src/SConscript
index 83fb1fa65..ded23c7cb 100644
--- a/libIRDB/src/SConscript
+++ b/libIRDB/src/SConscript
@@ -7,6 +7,7 @@ dirs='''
 	core  
 	syscall  
 	util
+	decode
 	'''
 
 for i in Split(dirs):
diff --git a/libIRDB/src/decode/SConscript b/libIRDB/src/decode/SConscript
new file mode 100644
index 000000000..b2dab0b2a
--- /dev/null
+++ b/libIRDB/src/decode/SConscript
@@ -0,0 +1,28 @@
+import os
+
+Import('env')
+myenv=env
+myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME'])
+
+
+libname="IRDB-decode"
+files=  '''
+	decode.cpp
+	operand.cpp
+	'''
+cpppath=''' 
+	$SECURITY_TRANSFORMS_HOME/include/
+	$SECURITY_TRANSFORMS_HOME/libIRDB/include/
+	$SECURITY_TRANSFORMS_HOME/beaengine/include
+	$SECURITY_TRANSFORMS_HOME/beaengine/beaengineSources/Includes/
+	'''
+
+#myenv.Append(CCFLAGS=" -Wall -W -Wextra -Wconversion ")
+
+myenv=myenv.Clone(CPPPATH=Split(cpppath))
+myenv.Append(CXXFLAGS = " -std=c++11 ")
+lib=myenv.Library(libname, Split(files))
+
+install=env.Install("$SECURITY_TRANSFORMS_HOME/lib/", lib)
+Default(install)
+
diff --git a/libIRDB/src/decode/decode.cpp b/libIRDB/src/decode/decode.cpp
new file mode 100644
index 000000000..a21f2d647
--- /dev/null
+++ b/libIRDB/src/decode/decode.cpp
@@ -0,0 +1,154 @@
+
+#include <libIRDB-decode.hpp>
+
+#include <bea_deprecated.hpp>
+
+using namespace libIRDB;
+using namespace std;
+
+
+DecodedInstruction_t::DecodedInstruction_t(const Instruction_t* i)
+{
+	disasm_data=static_cast<void*>(new DISASM({}));
+	DISASM* d=(DISASM*)disasm_data;
+	disasm_length=::Disassemble(i,*d);
+}
+
+DecodedInstruction_t::DecodedInstruction_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);
+}
+
+DecodedInstruction_t::DecodedInstruction_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;
+	Disassemble(start_addr,data,length);
+}
+
+DecodedInstruction_t::DecodedInstruction_t(const DecodedInstruction_t& copy)
+{
+	DISASM* d=static_cast<DISASM*>(copy.disasm_data);
+	disasm_data=static_cast<void*>(new DISASM(*d));
+	disasm_length=copy.disasm_length;
+}
+
+DecodedInstruction_t::~DecodedInstruction_t()
+{
+	DISASM* d=static_cast<DISASM*>(disasm_data);
+	delete d;
+	disasm_data=NULL;
+}
+
+DecodedInstruction_t& DecodedInstruction_t::operator=(const DecodedInstruction_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;
+}
+
+void DecodedInstruction_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);
+
+}
+
+string DecodedInstruction_t::getDisassembly() const
+{
+	assert(valid());
+	DISASM* d=static_cast<DISASM*>(disasm_data);
+	return string(d->CompleteInstr);
+}
+
+bool DecodedInstruction_t::valid() const
+{
+	return disasm_length>=0;
+}
+
+uint32_t DecodedInstruction_t::length() const
+{
+	assert(valid());
+	return disasm_length;
+}
+
+
+bool DecodedInstruction_t::isBranch() const
+{
+	DISASM* d=static_cast<DISASM*>(disasm_data);
+	return d->Instruction.BranchType!=0;
+}
+
+bool DecodedInstruction_t::isUnconditionalBranch() const
+{
+	DISASM* d=static_cast<DISASM*>(disasm_data);
+	return d->Instruction.BranchType==JmpType;
+}
+
+bool DecodedInstruction_t::isConditionalBranch() const
+{
+	DISASM* d=static_cast<DISASM*>(disasm_data);
+	assert(0);
+}
+
+bool DecodedInstruction_t::isReturn() const
+{
+	DISASM* d=static_cast<DISASM*>(disasm_data);
+	return d->Instruction.BranchType==RetType;
+}
+
+
+// 0-based.  first operand is numbered 0.
+DecodedOperand_t DecodedInstruction_t::getOperand(const int op_num) const
+{
+	DISASM* d=static_cast<DISASM*>(disasm_data);
+	switch(op_num+1)
+	{
+		case 1:
+			return DecodedOperand_t(&d->Argument1);
+		case 2:
+			return DecodedOperand_t(&d->Argument2);
+		case 3:
+			return DecodedOperand_t(&d->Argument3);
+		case 4:
+			return DecodedOperand_t(&d->Argument4);
+		default:
+			throw std::out_of_range("op_num");
+	}
+}
+
+
+string DecodedInstruction_t::getMnemonic() const
+{
+	DISASM* d=static_cast<DISASM*>(disasm_data);
+	const auto mnemonic=string(d->Instruction.Mnemonic);
+	return mnemonic.substr(0,mnemonic.size()-1);
+}
+
+virtual_offset_t DecodedInstruction_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 DecodedInstruction_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;
+}
diff --git a/libIRDB/src/decode/operand.cpp b/libIRDB/src/decode/operand.cpp
new file mode 100644
index 000000000..b2d3c8125
--- /dev/null
+++ b/libIRDB/src/decode/operand.cpp
@@ -0,0 +1,168 @@
+
+#include <libIRDB-decode.hpp>
+#include <bea_deprecated.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: 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
+DecodedOperand_t::DecodedOperand_t(void* arg_voidptr)
+{
+	ARGTYPE *arg_ptr=static_cast<ARGTYPE*>(arg_voidptr);
+	arg_data=(void*)new ARGTYPE(*arg_ptr);
+}
+
+DecodedOperand_t::DecodedOperand_t(const DecodedOperand_t& copy)
+{
+	ARGTYPE *arg_ptr=static_cast<ARGTYPE*>(copy.arg_data);
+	arg_data=(void*)new ARGTYPE(*arg_ptr);
+}
+
+DecodedOperand_t::~DecodedOperand_t()
+{
+	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
+	delete t;
+	arg_data=NULL;
+}
+
+DecodedOperand_t& DecodedOperand_t::operator=(const DecodedOperand_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 DecodedOperand_t::isConstant() const
+{
+	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
+	assert(t);
+	return (t->ArgType & CONSTANT_TYPE)!=0;
+}
+
+string DecodedOperand_t::getString() const
+{
+	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
+	assert(t);
+	return t->ArgMnemonic;
+}
+
+		
+bool DecodedOperand_t::isWrite() const
+{
+	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
+	return t->AccessMode==WRITE;
+}
+
+bool DecodedOperand_t::isRegister() const
+{
+	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
+	return (t->ArgType&REGISTER_TYPE)==REGISTER_TYPE;
+}
+
+
+
+uint32_t DecodedOperand_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 DecodedOperand_t::isMemory() const
+{
+	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
+	return (t->ArgType&MEMORY_TYPE)==MEMORY_TYPE;
+}
+
+bool DecodedOperand_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 DecodedOperand_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 DecodedOperand_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 DecodedOperand_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 DecodedOperand_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 */
+}
+
+virtual_offset_t DecodedOperand_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 DecodedOperand_t::isPcrel() const
+{
+	ARGTYPE *t=static_cast<ARGTYPE*>(arg_data);
+	return (t->ArgType&RELATIVE_)==RELATIVE_;
+}
diff --git a/libIRDB/test/SConscript b/libIRDB/test/SConscript
index 01ec9b4d8..0670b8c24 100644
--- a/libIRDB/test/SConscript
+++ b/libIRDB/test/SConscript
@@ -18,7 +18,7 @@ if 'build_tools' not in myenv or myenv['build_tools'] is None or int(myenv['buil
 		'''
 
 	LIBPATH="$SECURITY_TRANSFORMS_HOME/lib"
-	LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " IRDB-cfg IRDB-util MEDSannotation")
+	LIBS=Split( env.subst('$BASE_IRDB_LIBS')+ " IRDB-cfg IRDB-util IRDB-decode MEDSannotation")
 
 	print "The libs for libIRDB/tests are:"
 	print LIBS
diff --git a/libIRDB/test/fill_in_cfg.cpp b/libIRDB/test/fill_in_cfg.cpp
index 9326b23fd..a93f559bd 100644
--- a/libIRDB/test/fill_in_cfg.cpp
+++ b/libIRDB/test/fill_in_cfg.cpp
@@ -30,9 +30,9 @@
 #include <exeio.h>
 #include "elfio/elfio.hpp"
 #include "elfio/elfio_dump.hpp"
-#include "beaengine/BeaEngine.h"
 #include "eh_frame.hpp"
-#include <bea_deprecated.hpp>
+// #include <bea_deprecated.hpp>
+#include <libIRDB-decode.hpp>
 
 int odd_target_count=0;
 int bad_target_count=0;
@@ -80,7 +80,7 @@ void populate_instruction_map
 void set_fallthrough
 	(
 	map< pair<db_id_t,virtual_offset_t>, Instruction_t*> &insnMap,
-	DISASM *disasm, Instruction_t *insn, FileIR_t *firp
+	DecodedInstruction_t *disasm, Instruction_t *insn, FileIR_t *firp
 	)
 {
 	assert(disasm);
@@ -91,8 +91,11 @@ void set_fallthrough
 	
 	// check for branches with targets 
 	if(
-		(disasm->Instruction.BranchType==JmpType) ||			// it is a unconditional branch 
-		(disasm->Instruction.BranchType==RetType)			// or a return
+		//(disasm->Instruction.BranchType==JmpType) ||			// it is a unconditional branch 
+		//(disasm->Instruction.BranchType==RetType)			// or a return
+
+		(disasm->isUnconditionalBranch() ) ||	// it is a unconditional branch 
+		(disasm->isReturn())			// or a return
 	  )
 	{
 		// this is a branch with no fallthrough instruction
@@ -128,7 +131,7 @@ void set_fallthrough
 void set_target
 	(
 	map< pair<db_id_t,virtual_offset_t>, Instruction_t*> &insnMap,
-	DISASM *disasm, Instruction_t *insn, FileIR_t *firp
+	DecodedInstruction_t *disasm, Instruction_t *insn, FileIR_t *firp
 	)
 {
 
@@ -140,9 +143,12 @@ void set_target
 	
 	// check for branches with targets 
 	if(
-		(disasm->Instruction.BranchType!=0) &&			// it is a branch 
-		(disasm->Instruction.BranchType!=RetType) && 		// and not a return
-		(disasm->Argument1.ArgType & CONSTANT_TYPE)!=0		// and has a constant argument type 1
+		//(disasm->Instruction.BranchType!=0) &&			// it is a branch 
+		//(disasm->Instruction.BranchType!=RetType) && 		// and not a return
+		//(disasm->Argument1.ArgType & CONSTANT_TYPE)!=0		// and has a constant argument type 1
+		(disasm->isBranch()) &&			// it is a branch 
+		(!disasm->isReturn()) && 		// and not a return
+		(disasm->getOperand(0).isConstant())		// and has a constant argument type 1
 	  )
 	{
 //		cout<<"Found direct jump with addr=" << insn->GetAddress()->GetVirtualOffset() <<
@@ -150,7 +156,8 @@ void set_target
 //			disasm->Argument1.ArgMnemonic<<"."<<endl;
 
 		/* get the offset */
-		virtual_offset_t virtual_offset=strtoul(disasm->Argument1.ArgMnemonic, NULL, 16);
+		// virtual_offset_t virtual_offset=strtoul(disasm->Argument1.ArgMnemonic, NULL, 16);
+		virtual_offset_t virtual_offset=strtoul(disasm->getOperand(0).getString().c_str(), NULL, 16);
 
 		/* create a pair of offset/file */
 		pair<db_id_t,virtual_offset_t> p(insn->GetAddress()->GetFileID(),virtual_offset);
@@ -267,30 +274,37 @@ void add_new_instructions(FileIR_t *firp)
 				virtual_offset_t offset_into_section=missed_address-elfiop->sections[secndx]->get_address();
 	
 				/* disassemble the instruction */
-				DISASM disasm;
-                		memset(&disasm, 0, sizeof(DISASM));
+				DecodedInstruction_t disasm(missed_address, (void*)&data[offset_into_section], elfiop->sections[secndx]->get_size()-offset_into_section );
+
+				/*
+                		memset(&disasm, 0, sizeof(DecodeInstruction_t));
 
                 		disasm.Options = NasmSyntax + PrefixedNumeral;
                 		disasm.Archi = firp->GetArchitectureBitWidth();
                 		disasm.EIP = (UIntPtr) &data[offset_into_section];
 				disasm.SecurityBlock=elfiop->sections[secndx]->get_size()-offset_into_section;
                 		disasm.VirtualAddr = missed_address;
-                		int instr_len = Disasm(&disasm);
+				*/
+
+
+				
+
+                		const auto instr_len = disasm.length();
 
 
 /* bea docs say OUT_OF_RANGE and UNKNOWN_OPCODE are defined, but they aren't */
-#define OUT_OF_RANGE (0)
-#define UNKNOWN_OPCODE (-1) 
+// #define OUT_OF_RANGE (0)
+// #define UNKNOWN_OPCODE (-1) 
 
 				/* if we found the instruction, but can't disassemble it, then we skip out for now */
-				if(instr_len==OUT_OF_RANGE || instr_len==UNKNOWN_OPCODE)
+				if(!disasm.valid()) // instr_len==OUT_OF_RANGE || instr_len==UNKNOWN_OPCODE)
 				{
 					if(getenv("VERBOSE_CFG"))
 						cout<<"Found invalid insn at "<<missed_address<<endl;
 					break;
 				}
 				else if(getenv("VERBOSE_CFG"))
-					cout<<"Found valid insn at "<<missed_address<<": "<<disasm.CompleteInstr<<endl;
+					cout<<"Found valid insn at "<<missed_address<<": "<<disasm.getDisassembly()<<endl;
 
 				/* intel instructions have a max size of 16 */
 				assert(1<=instr_len && instr_len<=16);
@@ -316,7 +330,7 @@ void add_new_instructions(FileIR_t *firp)
 				assert(newinsn);
 				newinsn->SetAddress(newaddr);
 				newinsn->SetDataBits(newinsnbits);
-				newinsn->SetComment(string(disasm.CompleteInstr)+string(" from fill_in_cfg "));
+				newinsn->SetComment(disasm.getDisassembly()+string(" from fill_in_cfg "));
 				newinsn->SetAddress(newaddr);
 				/* fallthrough/target/is indirect will be set later */
 
@@ -365,10 +379,10 @@ void fill_in_cfg(FileIR_t *firp)
 	   	   )
 		{
 			Instruction_t *insn=*it;
-      			DISASM disasm;
-      			memset(&disasm, 0, sizeof(DISASM));
+      			DecodedInstruction_t disasm(insn);
+      			//memset(&disasm, 0, sizeof(DISASM));
 	
-      			int instr_len = Disassemble(insn,disasm);
+      			const auto instr_len = disasm.length();
 	
 			assert(instr_len==insn->GetDataBits().size());
 	
@@ -494,21 +508,6 @@ void fill_in_scoops(FileIR_t *firp)
 			cout<<"Skipping scoop for section (executable) "<<elfiop->sections[secndx]->get_name()<<endl;
                 	continue;
 		}
-#if 0
-		// we decided to skip BSS for a bad reason.  trying again.
-        	if(elfiop->sections[secndx]->isBSS())
-		{
-			cout<<"Skipping bss section: "<<elfiop->sections[secndx]->get_name()<<endl;
-                	continue;
-		}
-		// we decided to skip tls for a bad reason.  trying again.
-        	if(elfiop->sections[secndx]->isThreadLocal())
-		{
-			cout<<"Skipping tls section (executable) "<<elfiop->sections[secndx]->get_name()<<endl;
-                	continue;
-		}
-#endif
-
 		/* name */
 		string name=elfiop->sections[secndx]->get_name();
 
diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp
index cbc8aa6f4..869a9b0a6 100644
--- a/libIRDB/test/fill_in_indtargs.cpp
+++ b/libIRDB/test/fill_in_indtargs.cpp
@@ -38,11 +38,10 @@
 #include <elf.h>
 
 #include <exeio.h>
-#include "beaengine/BeaEngine.h"
 #include "check_thunks.hpp"
 #include "fill_in_indtargs.hpp"
 #include "libMEDSAnnotation.h"
-#include <bea_deprecated.hpp>
+#include <libIRDB-decode.hpp>
 
 using namespace libIRDB;
 using namespace std;
@@ -89,12 +88,12 @@ static long total_unpins=0;
  */
 
 
-static void check_for_PIC_switch_table32_type2(Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t>& thunk_bases);
-static void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t>& thunk_bases);
-static void check_for_PIC_switch_table32(FileIR_t*, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t>& thunk_bases);
-static void check_for_PIC_switch_table64(FileIR_t*, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop);
-static void check_for_nonPIC_switch_table(FileIR_t*, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop);
-static void check_for_nonPIC_switch_table_pattern2(FileIR_t*, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop);
+static void check_for_PIC_switch_table32_type2(Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t>& thunk_bases);
+static void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t>& thunk_bases);
+static void check_for_PIC_switch_table32(FileIR_t*, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t>& thunk_bases);
+static void check_for_PIC_switch_table64(FileIR_t*, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop);
+static void check_for_nonPIC_switch_table(FileIR_t*, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop);
+static void check_for_nonPIC_switch_table_pattern2(FileIR_t*, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop);
 
 extern void read_ehframe(FileIR_t* firp, EXEIO::exeio* );
 
@@ -205,20 +204,20 @@ EXEIO::section*  find_section(virtual_offset_t addr, EXEIO::exeio *elfiop)
 	return NULL;
 }
 
-void handle_argument(ARGTYPE *arg, Instruction_t* insn, ibt_provenance_t::provtype_t pt = ibt_provenance_t::ibtp_text)
+void handle_argument(const DecodedOperand_t *arg, Instruction_t* insn, ibt_provenance_t::provtype_t pt = ibt_provenance_t::ibtp_text)
 {
-	if( (arg->ArgType&MEMORY_TYPE) == MEMORY_TYPE ) 
+	if(arg->isMemory()) //  (arg->ArgType&MEMORY_TYPE) == MEMORY_TYPE ) 
 	{
-		if((arg->ArgType&RELATIVE_)==RELATIVE_)
+		if(arg->isPcrel()) // (arg->ArgType&RELATIVE_)==RELATIVE_)
 		{
 			assert(insn);
 			assert(insn->GetAddress());
-			possible_target(arg->Memory.Displacement+insn->GetAddress()->GetVirtualOffset()+
+			possible_target(arg->getMemoryDisplacement() /*arg->Memory.Displacement*/+insn->GetAddress()->GetVirtualOffset()+
 				insn->GetDataBits().length(), insn->GetAddress()->GetVirtualOffset(), pt);
 		}
 		else
 		{
-			possible_target(arg->Memory.Displacement, insn->GetAddress()->GetVirtualOffset(), pt);
+			possible_target(arg->getMemoryDisplacement() /* arg->Memory.Displacement*/, insn->GetAddress()->GetVirtualOffset(), pt);
 		}
 	}
 }
@@ -286,9 +285,9 @@ void mark_targets(FileIR_t *firp)
 #ifdef MOMVED
 bool IsParameterWrite(FileIR_t *firp,Instruction_t* insn, string& output_dst)
 {
-	DISASM d;
-	Disassemble(insn,d);
-	if(d.Argument1.AccessMode!=WRITE)
+	DecodedInstruction_t d(insn);
+	(void)WRITE; // makes ure bea header isn't included.
+	if(!d.getOperand(0).IsWrite()) // d.Argument1.AccessMode!=WRITE)
 	{
 		return false;
 	}
@@ -297,17 +296,18 @@ bool IsParameterWrite(FileIR_t *firp,Instruction_t* insn, string& output_dst)
 	if(firp->GetArchitectureBitWidth()==64)
 	{
 		// if it's a register
-		if((d.Argument1.ArgType&REGISTER_TYPE)==REGISTER_TYPE)
+		if(d.getOperand(0).isRegister()) // (d.Argument1.ArgType&REGISTER_TYPE)==REGISTER_TYPE)
 		{
-			int regno=(d.Argument1.ArgType)&0xFFFF;
+			// int regno=(d.Argument1.ArgType)&0xFFFF
+			const auto regno=d.getOperand(0).getRegNumber();
 			switch(regno)
 			{
-				case REG7:	// rdi
-				case REG6:	// rsi
-				case REG2:	// rdx
-				case REG1:	// rcx
-				case REG8:	// r8
-				case REG9:	// r9
+				case 7 /*REG7*/:	// rdi
+				case 6 /*REG6*/:	// rsi
+				case 2 /*REG2*/:	// rdx
+				case 1 /*REG1*/:	// rcx
+				case 8 /*REG8*/:	// r8
+				case 9 /*REG9*/:	// r9
 					output_dst=d.Argument1.ArgMnemonic;
 					return true;
 
@@ -323,19 +323,19 @@ bool IsParameterWrite(FileIR_t *firp,Instruction_t* insn, string& output_dst)
 
 
 	// check for memory type
-	if((d.Argument1.ArgType&MEMORY_TYPE)!=MEMORY_TYPE)
+	if(!d.isMemory()) // (d.Argument1.ArgType&MEMORY_TYPE)!=MEMORY_TYPE)
 		return false;
 
 	// check that base reg is esp.
-	if(d.Argument1.Memory.BaseRegister != REG4)
+	if(d->getOperand(0)->hasBaseRegister() && d->getOperand(0)->getBaseRegister() != 4) // d.Argument1.Memory.BaseRegister != REG4)
 		return false;
 
 	// check that there's no index reg
-	if(d.Argument1.Memory.IndexRegister != 0)
+	if(! d->getOperand(0).hasIndexRegister()) // d.Argument1.Memory.IndexRegister != 0)
 		return false;
 
 	// get k out of [esp + k ]
-	unsigned int k=d.Argument1.Memory.Displacement;
+	unsigned int k=d->getOperand(0).getMemoryDisplacement(); // d.Argument1.Memory.Displacement;
 
 	// check that we know the frame layout.
 	if(insn->GetFunction() == NULL)
@@ -343,7 +343,7 @@ bool IsParameterWrite(FileIR_t *firp,Instruction_t* insn, string& output_dst)
 
 	if(k < insn->GetFunction()->GetOutArgsRegionSize())
 	{
-		output_dst=string("[")+d.Argument1.ArgMnemonic+string("]");
+		output_dst=string("[")+d->getOperand(0).getString() /* d.Argument1.ArgMnemonic*/ +string("]");
 		return true;
 	}
 
@@ -357,9 +357,9 @@ bool CallToPrintfFollows(FileIR_t *firp, Instruction_t* insn, const string& arg_
 {
 	for(Instruction_t* ptr=insn->GetFallthrough(); ptr!=NULL; ptr=ptr->GetFallthrough())
 	{
-		DISASM d;
-		Disassemble(ptr,d);
-		if(d.Instruction.Mnemonic == string("call "))
+		DecodedInstruction_t d(ptr);
+		// Disassemble(ptr,d);
+		if(d.getMnemonic() == string("call"))
 		{
 			// check we have a target
 			if(ptr->GetTarget()==NULL)
@@ -378,7 +378,7 @@ bool CallToPrintfFollows(FileIR_t *firp, Instruction_t* insn, const string& arg_
 		}
 
 		// found reference to argstring, assume it's a write and exit
-		if(string(d.CompleteInstr).find(arg_str)!= string::npos)
+		if(d.getDisassembly()/*string(d.CompleteInstr)*/.find(arg_str)!= string::npos)
 			return false;
 	}
 
@@ -406,8 +406,9 @@ void get_instruction_targets(FileIR_t *firp, EXEIO::exeio* elfiop, const set<vir
            )
         {
                 Instruction_t *insn=*it;
-                DISASM disasm;
-                virtual_offset_t instr_len = Disassemble(insn,disasm);
+                // DISASM disasm;
+		DecodedInstruction_t disasm(insn);
+                virtual_offset_t instr_len = disasm.length(); // Disassemble(insn,disasm);
 
                 assert(instr_len==insn->GetDataBits().size());
 
@@ -426,7 +427,7 @@ void get_instruction_targets(FileIR_t *firp, EXEIO::exeio* elfiop, const set<vir
 		check_for_nonPIC_switch_table_pattern2(firp, insn,disasm, elfiop);
 
 		/* other branches can't indicate an indirect branch target */
-		if(disasm.Instruction.BranchType)
+		if(disasm.isBranch()) // disasm.Instruction.BranchType)
 			continue;
 
 		ibt_provenance_t::provtype_t prov=0;
@@ -436,15 +437,19 @@ void get_instruction_targets(FileIR_t *firp, EXEIO::exeio* elfiop, const set<vir
 		}
 		else
 		{
-			cout<<"TextToPrintf analysis of '"<<disasm.CompleteInstr<<"' successful at " <<hex<<insn->GetAddress()->GetVirtualOffset()<<endl;
+			cout<<"TextToPrintf analysis of '"<<disasm.getDisassembly()<<"' successful at " <<hex<<insn->GetAddress()->GetVirtualOffset()<<endl;
 			prov=ibt_provenance_t::ibtp_texttoprintf;
 		}
 		/* otherwise, any immediate is a possible branch target */
-		possible_target(disasm.Instruction.Immediat,0, prov);
-		handle_argument(&disasm.Argument1, insn, prov);
-		handle_argument(&disasm.Argument2, insn, prov);
-		handle_argument(&disasm.Argument3, insn, prov);
-		handle_argument(&disasm.Argument4, insn, prov);
+		possible_target(disasm.getImmediate() /* Instruction.Immediat*/ ,0, prov);
+		const auto op0=disasm.getOperand(0);
+		const auto op1=disasm.getOperand(1);
+		const auto op2=disasm.getOperand(2);
+		const auto op3=disasm.getOperand(3);
+		handle_argument(&op0, insn, prov);
+		handle_argument(&op1, insn, prov);
+		handle_argument(&op2, insn, prov);
+		handle_argument(&op3, insn, prov);
 	}
 }
 
@@ -566,7 +571,6 @@ void print_targets_oneline()
 
 set<Instruction_t*> find_in_function(string needle, Function_t *haystack)
 {
-	DISASM disasm;
 	regex_t preg;
 	set<Instruction_t*>::const_iterator fit;
 	set<Instruction_t*> found_instructions;
@@ -577,10 +581,12 @@ set<Instruction_t*> find_in_function(string needle, Function_t *haystack)
 	for (fit; fit != haystack->GetInstructions().end(); fit++)
 	{
 		Instruction_t *candidate = *fit;
-		Disassemble(candidate,disasm);
+		//DISASM disasm;
+		//Disassemble(candidate,disasm);
+		DecodedInstruction_t disasm(candidate);
 
 		// check it's the requested type
-		if(regexec(&preg, disasm.CompleteInstr, 0, NULL, 0) == 0)
+		if(regexec(&preg, disasm.getDisassembly().c_str() /*CompleteInstr*/, 0, NULL, 0) == 0)
 		{
 			found_instructions.insert(candidate);
 		}
@@ -591,7 +597,6 @@ set<Instruction_t*> find_in_function(string needle, Function_t *haystack)
 
 bool backup_until(const char* insn_type_regex, Instruction_t *& prev, Instruction_t* orig, bool recursive=false)
 {
-	DISASM disasm;
 	prev=orig;
 	regex_t preg;
 
@@ -606,10 +611,12 @@ bool backup_until(const char* insn_type_regex, Instruction_t *& prev, Instructio
 	
 
        		// get I7's disassembly
-       		Disassemble(prev,disasm);
+		//DISASM disasm;
+       		//Disassemble(prev,disasm);
+		DecodedInstruction_t disasm(prev);
 
        		// check it's the requested type
-       		if(regexec(&preg, disasm.CompleteInstr, 0, NULL, 0) == 0)
+       		if(regexec(&preg, disasm.getDisassembly().c_str() /*CompleteInstr*/, 0, NULL, 0) == 0)
 		{
 			regfree(&preg);
 			return true;
@@ -625,10 +632,10 @@ bool backup_until(const char* insn_type_regex, Instruction_t *& prev, Instructio
 			it!=preds[myprev].end(); ++it)
 		{
 			Instruction_t* pred=*it;
-       		
-			Disassemble(pred,disasm);
+			//Disassemble(pred,disasm);
+			DecodedInstruction_t disasm(pred);
        			// check it's the requested type
-       			if(regexec(&preg, disasm.CompleteInstr, 0, NULL, 0) == 0)
+       			if(regexec(&preg, disasm.getDisassembly().c_str()/*CompleteInstr*/, 0, NULL, 0) == 0)
 			{
 				regfree(&preg);
 				return true;
@@ -650,7 +657,7 @@ bool backup_until(const char* insn_type_regex, Instruction_t *& prev, Instructio
 /*
  * check_for_PIC_switch_table32 - look for switch tables in PIC code for 32-bit code.
  */
-static void check_for_PIC_switch_table32(FileIR_t *firp, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t> &thunk_bases)
+static void check_for_PIC_switch_table32(FileIR_t *firp, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t> &thunk_bases)
 {
 
 	ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type1;
@@ -683,15 +690,15 @@ I7: 08069391 <_gedit_app_ready+0x91> ret
         Instruction_t* I4=NULL;
         Instruction_t* I3=NULL;
         // check if I5 is a jump
-        if(strstr(disasm.Instruction.Mnemonic, "jmp")==NULL)
+        if(strstr(disasm.getMnemonic().c_str() /*Instruction.Mnemonic*/, "jmp")==NULL)
 		return;
 
 	// return if it's a jump to a constant address, these are common
-        if(disasm.Argument1.ArgType&CONSTANT_TYPE)
+        if(disasm.getOperand(0).isConstant() /*disasm.Argument1.ArgType&CONSTANT_TYPE*/)
 		return;
 
 	// return if it's a jump to a memory address
-        if(disasm.Argument1.ArgType&MEMORY_TYPE)
+        if(disasm.getOperand(0).isMemory() /*disasm.Argument1.ArgType&MEMORY_TYPE*/)
 		return;
 
 	// has to be a jump to a register now
@@ -713,23 +720,26 @@ I7: 08069391 <_gedit_app_ready+0x91> ret
 	}
 	else
 	{
-		DISASM dcmp;
-		Disassemble(Icmp,dcmp);
-		table_size = dcmp.Instruction.Immediat;
+		//DISASM dcmp;
+		//Disassemble(Icmp,dcmp);
+		DecodedInstruction_t dcmp(Icmp);	
+		table_size = dcmp.getImmediate(); //Instruction.Immediat;
 		if(table_size<=0)
 			table_size=std::numeric_limits<int>::max();
 	}
 
 	// grab the offset out of the lea.
-	DISASM d2;
-	Disassemble(I3,d2);
+	//DISASM d2;
+	//Disassemble(I3,d2);
+	DecodedInstruction_t d2(I3);
 
 	// get the offset from the thunk
-	virtual_offset_t table_offset=d2.Instruction.AddrValue;
+	virtual_offset_t table_offset=d2.getAddress(); // d2.Instruction.AddrValue;
 	if(table_offset==0)
 		return;
 
-cout<<hex<<"Found switch dispatch at "<<I3->GetAddress()->GetVirtualOffset()<< " with table_offset="<<table_offset<<" and table_size="<<table_size<<endl;
+	cout<<hex<<"Found switch dispatch at "<<I3->GetAddress()->GetVirtualOffset()<< " with table_offset="<<table_offset
+	    <<" and table_size="<<table_size<<endl;
 		
 	/* iterate over all thunk_bases/module_starts */
 	for(set<virtual_offset_t>::iterator it=thunk_bases.begin(); it!=thunk_bases.end(); ++it)
@@ -813,7 +823,7 @@ cout<<hex<<"Found switch dispatch at "<<I3->GetAddress()->GetVirtualOffset()<< "
 
 }
 
-static void check_for_PIC_switch_table32_type2(Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t> &thunk_bases)
+static void check_for_PIC_switch_table32_type2(Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t> &thunk_bases)
 {
 	ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type2;
 #if 0
@@ -830,15 +840,16 @@ I5:   0x809900e <text_handler+51>: jmp    ecx
         Instruction_t* I4=NULL;
         Instruction_t* I3=NULL;
         // check if I5 is a jump
-        if(strstr(disasm.Instruction.Mnemonic, "jmp")==NULL)
+        if(strstr(disasm.getMnemonic().c_str() /*disasm.Instruction.Mnemonic*/, "jmp")==NULL)
 		return;
 
 	// return if it's a jump to a constant address, these are common
-        if(disasm.Argument1.ArgType&CONSTANT_TYPE)
+        if(disasm.getOperand(0).isConstant() /*disasm.Argument1.ArgType&CONSTANT_TYPE*/)
 		return;
 
 	// return if it's a jump to a memory address
-        if(disasm.Argument1.ArgType&MEMORY_TYPE)
+        //if(disasm.Argument1.ArgType&MEMORY_TYPE)
+        if(disasm.getOperand(0).isMemory())
 		return;
 
 	// has to be a jump to a register now
@@ -852,11 +863,12 @@ I5:   0x809900e <text_handler+51>: jmp    ecx
 		return;
 
 	// grab the offset out of the lea.
-	DISASM d2;
-	Disassemble(I3,d2);
+	//DISASM d2;
+	//Disassemble(I3,d2);
+	DecodedInstruction_t d2(I3);
 
 	// get the offset from the thunk
-	virtual_offset_t table_offset=d2.Instruction.AddrValue;
+	virtual_offset_t table_offset=d2.getAddress(); // d2.Instruction.AddrValue;
 	if(table_offset==0)
 		return;
 
@@ -933,30 +945,36 @@ cout<<hex<<"Found (type2) switch dispatch at "<<I3->GetAddress()->GetVirtualOffs
  *
  * nb: also works for 64-bit.
  */
-static void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t> &thunk_bases)
+static void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop, const set<virtual_offset_t> &thunk_bases)
 {
 	int ptrsize=firp->GetArchitectureBitWidth()/8;
 	ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type3;
 
         Instruction_t* I5=insn;
         // check if I5 is a jump
-        if(strstr(disasm.Instruction.Mnemonic, "jmp")==NULL)
+        //if(strstr(disasm.Instruction.Mnemonic, "jmp")==NULL)
+        if(strstr(disasm.getMnemonic().c_str()/*Instruction.Mnemonic*/, "jmp")==NULL)
 		return;
 
 	// return if it's not a jump to a memory address
-        if(!(disasm.Argument1.ArgType&MEMORY_TYPE))
+        //if(!(disasm.Argument1.ArgType&MEMORY_TYPE))
+        if(!(disasm.getOperand(0).isMemory()))
 		return;
 
 	/* return if there's no displacement */
-        if(disasm.Argument1.Memory.Displacement==0)
+        //if(disasm.Argument1.Memory.Displacement==0)
+        if(disasm.getOperand(0).getMemoryDisplacement()==0)
 		return;
 
-        if(disasm.Argument1.Memory.Scale!=ptrsize)
+        //if(disasm.Argument1.Memory.Scale!=ptrsize)
+        // if(disasm.getOperand(0).getScaleValue()!=ptrsize)
+        if(!disasm.getOperand(0).hasIndexRegister() || disasm.getOperand(0).getScaleValue()!=ptrsize)
 		return;
 
 	// grab the table base out of the jmp.
-	virtual_offset_t table_base=disasm.Argument1.Memory.Displacement;
-        if((disasm.Argument1.ArgType&RELATIVE_))
+	virtual_offset_t table_base=disasm.getOperand(0).getMemoryDisplacement();//disasm.Argument1.Memory.Displacement;
+        //if((disasm.Argument1.ArgType&RELATIVE_))
+        if(disasm.getOperand(0).isPcrel())
 		table_base+=insn->GetDataBits().size()+insn->GetAddress()->GetVirtualOffset();
 
 	if(table_base==0)
@@ -1049,13 +1067,12 @@ static void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* in
 
 		/* if there's no base register and no index reg, */
 		/* then this jmp can't have more than one valid table entry */
-		if( disasm.Argument1.Memory.BaseRegister==0 && disasm.Argument1.Memory.IndexRegister==0 ) 
+		//if( disasm.Argument1.Memory.BaseRegister==0 && disasm.Argument1.Memory.IndexRegister==0 ) 
+		if( !disasm.getOperand(0).hasBaseRegister() && !disasm.getOperand(0).hasIndexRegister()) 
 		{
 			/* but the table can have 1 valid entry. */
 			if(pSec->get_name()==".got.plt")
 			{	
-
-
 	                        Instruction_t *ibtarget = lookupInstruction(firp, table_entry);
 				if(ibtarget)
 				{
@@ -1067,7 +1084,7 @@ static void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* in
 #endif
 					possible_target(table_entry,table_base+0*ptrsize, ibt_provenance_t::ibtp_gotplt);
 					if(getenv("IB_VERBOSE")!=0)
-						cout<<hex<<"Found  plt dispatch ("<<disasm.CompleteInstr<<"') at "<<I5->GetAddress()->GetVirtualOffset()<< endl;
+						cout<<hex<<"Found  plt dispatch ("<<disasm.getDisassembly()<<"') at "<<I5->GetAddress()->GetVirtualOffset()<< endl;
 					return;
 				}
 			}
@@ -1076,14 +1093,16 @@ static void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* in
 			else
 				possible_target(table_entry,table_base+0*ptrsize, ibt_provenance_t::ibtp_rodata);
 			if(getenv("IB_VERBOSE")!=0)
-				cout<<hex<<"Found  constant-memory dispatch from non- .got.plt location ("<<disasm.CompleteInstr<<"') at "<<I5->GetAddress()->GetVirtualOffset()<< endl;
+				cout<<hex<<"Found  constant-memory dispatch from non- .got.plt location ("<<disasm.getDisassembly()<<"') at "
+				    <<I5->GetAddress()->GetVirtualOffset()<< endl;
 			return;
 		}
 		if(!is_possible_target(table_entry,table_base+i*ptrsize))
 		{
 			if(getenv("IB_VERBOSE")!=0)
 			{
-				cout<<hex<<"Found (type3) candidate for switch dispatch for '"<<disasm.CompleteInstr<<"' at "<<I5->GetAddress()->GetVirtualOffset()<< " with table_base="<<table_base<<endl;
+				cout<<hex<<"Found (type3) candidate for switch dispatch for '"<<disasm.getDisassembly()<<"' at "
+				    <<I5->GetAddress()->GetVirtualOffset()<< " with table_base="<<table_base<<endl;
 				cout<<"Found table_entry "<<hex<<table_entry<<" is not valid\n"<<endl;
 			}
 			return;	
@@ -1146,7 +1165,7 @@ static void check_for_PIC_switch_table32_type3(FileIR_t* firp, Instruction_t* in
  * if so, see if we can trace back a few instructions to find a
  * the start of the table.
  */
-static void check_for_PIC_switch_table64(FileIR_t* firp, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop)
+static void check_for_PIC_switch_table64(FileIR_t* firp, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop)
 {
 	ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type4;
 /* here's the pattern we're looking for */
@@ -1219,14 +1238,14 @@ Note: Here the operands of the add are reversed, so lookup code was not finding
 	Instruction_t* I5=NULL;
 	Instruction_t* I1=NULL;
 	// check if I8 is a jump
-	if(strstr(disasm.Instruction.Mnemonic, "jmp")==NULL)
+	if(strstr(disasm.getMnemonic().c_str()/*Instruction.Mnemonic*/, "jmp")==NULL)
 		return;
 
 	// return if it's a jump to a constant address, these are common
-	if(disasm.Argument1.ArgType&CONSTANT_TYPE)
+	if(disasm.getOperand(0).isConstant()) //disasm.Argument1.ArgType&CONSTANT_TYPE)
 		return;
 	// return if it's a jump to a memory address
-	if(disasm.Argument1.ArgType&MEMORY_TYPE)
+	if(disasm.getOperand(0).isMemory()) // Argument1.ArgType&MEMORY_TYPE)
 		return;
 
 	// has to be a jump to a register now
@@ -1239,25 +1258,26 @@ Note: Here the operands of the add are reversed, so lookup code was not finding
 	 * Backup and find the instruction that's an add or lea before I8.
 	 */
 	table_index_str = "(add ";
-	table_index_str += disasm.Argument1.ArgMnemonic;
+	table_index_str += disasm.getOperand(0).getString(); //Argument1.ArgMnemonic;
 	table_index_str += "|lea ";
-	table_index_str += disasm.Argument1.ArgMnemonic;
+	table_index_str += disasm.getOperand(0).getString(); //Argument1.ArgMnemonic;
 	table_index_str += ")";
 
-	const auto cmp_str = string("cmp ") + disasm.Argument1.ArgMnemonic;
-	const auto cmp_str2 = string("cmp ") + disasm.Argument2.ArgMnemonic;
+	const auto cmp_str = string("cmp ") + disasm.getOperand(0).getString(); //Argument1.ArgMnemonic;
+	const auto cmp_str2 = string("cmp ") + disasm.getOperand(1).getString(); //Argument2.ArgMnemonic;
 
 	if(!backup_until(table_index_str.c_str(), I7, I8))
 		return;
 
-	Disassemble(I7,disasm);
+	// Disassemble(I7,disasm);
+	disasm=DecodedInstruction_t(I7);
 
 	// Check if lea instruction is being used as add (scale=1, disp=0)
-	if(strstr(disasm.Instruction.Mnemonic, "lea"))
+	if(strstr(disasm.getMnemonic().c_str() /* Instruction.Mnemonic*/, "lea"))
 	{
-		if(!(disasm.Argument2.ArgType&MEMORY_TYPE))
+		if(!(disasm.getOperand(1).isMemory() /*disasm.Argument2.ArgType&MEMORY_TYPE)*/))
 			return;
-		if(!(disasm.Argument2.Memory.Scale == 1 && disasm.Argument2.Memory.Displacement == 0))
+		if(!(disasm.getOperand(1).getScaleValue() /* .Argument2.Memory.Scale */ == 1 && disasm.getOperand(1).getMemoryDisplacement() /*Argument2.Memory.Displacement*/ == 0))
 			return;
 	} 
 	// backup and find the instruction that's an movsxd before I7
@@ -1270,8 +1290,9 @@ Note: Here the operands of the add are reversed, so lookup code was not finding
 
 	string lea_string="lea ";
 	
-	Disassemble(I6,disasm);
-	if( (disasm.Argument2.ArgType&MEMORY_TYPE)	 == MEMORY_TYPE)
+	// Disassemble(I6,disasm);
+	disasm=DecodedInstruction_t(I6);
+	if( disasm.getOperand(1).isMemory() /* (disasm.Argument2.ArgType&MEMORY_TYPE)	 == MEMORY_TYPE*/)
 	{
 		// try to be smarter for memory types.
 
@@ -1281,24 +1302,26 @@ Note: Here the operands of the add are reversed, so lookup code was not finding
 		 * for the base of the jump table.
 		 */
 		string base_reg="";
-		switch(disasm.Argument2.Memory.BaseRegister)
-		{
-			case REG0: base_reg="rax"; break;
-			case REG1: base_reg="rcx"; break;
-			case REG2: base_reg="rdx"; break;
-			case REG3: base_reg="rbx"; break;
-			case REG4: base_reg="rsp"; break;
-			case REG5: base_reg="rbp"; break;
-			case REG6: base_reg="rsi"; break;
-			case REG7: base_reg="rdi"; break;
-			case REG8: base_reg="r8"; break;
-			case REG9: base_reg="r9"; break;
-			case REG10: base_reg="r10"; break;
-			case REG11: base_reg="r11"; break;
-			case REG12: base_reg="r12"; break;
-			case REG13: base_reg="r13"; break;
-			case REG14: base_reg="r14"; break;
-			case REG15: base_reg="r15"; break;
+		if(!disasm.getOperand(1).hasBaseRegister() /*Argument2.Memory.BaseRegister*/)
+			return;
+		switch(disasm.getOperand(1).getBaseRegister() /*Argument2.Memory.BaseRegister*/)
+		{
+			case 0/*REG0*/: base_reg="rax"; break;
+			case 1/*REG1*/: base_reg="rcx"; break;
+			case 2/*REG2*/: base_reg="rdx"; break;
+			case 3/*REG3*/: base_reg="rbx"; break;
+			case 4/*REG4*/: base_reg="rsp"; break;
+			case 5/*REG5*/: base_reg="rbp"; break;
+			case 6/*REG6*/: base_reg="rsi"; break;
+			case 7/*REG7*/: base_reg="rdi"; break;
+			case 8/*REG8*/: base_reg="r8"; break;
+			case 9/*REG9*/: base_reg="r9"; break;
+			case 10/*REG10*/: base_reg="r10"; break;
+			case 11/*REG11*/: base_reg="r11"; break;
+			case 12/*REG12*/: base_reg="r12"; break;
+			case 13/*REG13*/: base_reg="r13"; break;
+			case 14/*REG14*/: base_reg="r14"; break;
+			case 15/*REG15*/: base_reg="r15"; break;
 			default: 
 				// no base register;
 				return;
@@ -1352,12 +1375,13 @@ Note: Here the operands of the add are reversed, so lookup code was not finding
 	for (found_leas_it; found_leas_it != found_leas.end(); found_leas_it++) 
 	{
 		Instruction_t *I5_cur = *found_leas_it;
-		Disassemble(I5_cur,disasm);
+		//Disassemble(I5_cur,disasm);
+		disasm=DecodedInstruction_t(I5_cur);
 
-		if(!(disasm.Argument2.ArgType&MEMORY_TYPE))
+		if(!(disasm.getOperand(1).isMemory() /*Argument2.ArgType&MEMORY_TYPE*/))
 			//return;
 			continue;
-		if(!(disasm.Argument2.ArgType&RELATIVE_))
+		if(!(disasm.getOperand(1).isPcrel() /*Argument2.ArgType&RELATIVE_*/))
 			//return;
 			continue;
 
@@ -1365,7 +1389,7 @@ Note: Here the operands of the add are reversed, so lookup code was not finding
 		// instruction address (and include the instruction's size, etc.
 		// but, fix_calls has already removed this oddity so we can relocate
 		// the instruction.
-		virtual_offset_t D1=strtol(disasm.Argument2.ArgMnemonic, NULL, 16);
+		virtual_offset_t D1=strtol(disasm.getOperand(1).getString().c_str()/*Argument2.ArgMnemonic*/, NULL, 16);
 
 		// find the section with the data table
 		EXEIO::section *pSec=find_section(D1,elfiop);
@@ -1385,25 +1409,27 @@ Note: Here the operands of the add are reversed, so lookup code was not finding
 		int table_size = 0;
 		if(backup_until(cmp_str.c_str(), I1, I8))
 		{
-			DISASM d1;
-			Disassemble(I1,d1);
-			table_size = d1.Instruction.Immediat;
+			//DISASM d1;
+			//Disassemble(I1,d1);
+			DecodedInstruction_t d1(I1);
+			table_size = d1.getImmediate(); // Instruction.Immediat;
 			if (table_size <= 0)
 			{
-				cout<<"pic64: found I1 ('"<<d1.CompleteInstr<<"'), but could not find size of switch table"<<endl;
+				cout<<"pic64: found I1 ('"<<d1.getDisassembly()/*CompleteInstr*/<<"'), but could not find size of switch table"<<endl;
 				// set table_size to be very large, so we can still do pinning appropriately
 				table_size=std::numeric_limits<int>::max();
 			}
 		}
 		else if(backup_until(cmp_str2.c_str(), I1, I8))
 		{
-			DISASM d1;
-			Disassemble(I1,d1);
-			table_size = d1.Instruction.Immediat;
+			//DISASM d1;
+			//Disassemble(I1,d1);
+			DecodedInstruction_t d1(I1);
+			table_size = d1.getImmediate()/*Instruction.Immediat*/;
 			if (table_size <= 0)
 			{
 				// set table_size to be very large, so we can still do pinning appropriately
-				cout<<"pic64: found I1 ('"<<d1.CompleteInstr<<"'), but could not find size of switch table"<<endl;
+				cout<<"pic64: found I1 ('"<<d1.getDisassembly()/*CompleteInstr*/<<"'), but could not find size of switch table"<<endl;
 				table_size=std::numeric_limits<int>::max();
 			}
 		}
@@ -1441,7 +1467,7 @@ Note: Here the operands of the add are reversed, so lookup code was not finding
 			if(getenv("IB_VERBOSE"))
 			{
 				cout<<"Found possible table entry, at: "<< std::hex << I8->GetAddress()->GetVirtualOffset()
-			    		<< " insn: " << disasm.CompleteInstr<< " d1: "
+			    		<< " insn: " << disasm.getDisassembly()/*CompleteInstr*/<< " d1: "
 			    		<< D1 << " table_entry:" << table_entry 
 			    		<< " target: "<< D1+table_entry << std::dec << endl;
 			}
@@ -1497,7 +1523,7 @@ Note: Here the operands of the add are reversed, so lookup code was not finding
 
 	nb: handles both 32 and 64 bit
 */
-static void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop)
+static void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop)
 {
 	ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type5;
 	Instruction_t *I1 = NULL;
@@ -1506,19 +1532,23 @@ static void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t
 	assert(IJ);
 
 	// check if IJ is a jump
-	if(strstr(disasm.Instruction.Mnemonic, "jmp")==NULL)
+	//if(strstr(disasm.Instruction.Mnemonic, "jmp")==NULL)
+	if(strstr(disasm.getMnemonic().c_str(), "jmp")==NULL)
 		return;
 
 	// look for a memory type
-	if(!(disasm.Argument1.ArgType&MEMORY_TYPE))
+	//if(!(disasm.Argument1.ArgType&MEMORY_TYPE))
+	if(!(disasm.getOperand(0).isMemory()))
 		return;
 
 	// make sure there's a scaling factor
-	if (disasm.Argument1.Memory.Scale < 4)
+	//if (disasm.Argument1.Memory.Scale < 4)
+	//if (disasm.getOperand(0).getScaleValue() < 4) assumes scale is meaningful here?  
+	if (!disasm.getOperand(0).hasIndexRegister() || disasm.getOperand(0).getScaleValue() < 4)
 		return;
 
 	// extract start of jmp table
-	virtual_offset_t table_offset = disasm.Instruction.AddrValue;
+	virtual_offset_t table_offset = disasm.getAddress(); // disasm.Instruction.AddrValue;
 	if(table_offset==0)
 		return;
 
@@ -1532,9 +1562,10 @@ static void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t
 
 	// extract size off the comparison
 	// make sure not off by one
-	DISASM d1;
-	Disassemble(I1,d1);
-	virtual_offset_t table_size = d1.Instruction.Immediat;
+	//DISASM d1;
+	//Disassemble(I1,d1);
+	DecodedInstruction_t d1(I1);
+	virtual_offset_t table_size = d1.getImmediate()/*d1.Instruction.Immediat*/;
 
 	if (table_size <= 0) return;
 
@@ -1601,7 +1632,7 @@ static void check_for_nonPIC_switch_table_pattern2(FileIR_t* firp, Instruction_t
 
 	nb: handles both 32 and 64 bit
 */
-static void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DISASM disasm, EXEIO::exeio* elfiop)
+static void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, DecodedInstruction_t disasm, EXEIO::exeio* elfiop)
 {
 	ibt_provenance_t prov=ibt_provenance_t::ibtp_switchtable_type6;
 	Instruction_t *I1 = NULL;
@@ -1612,15 +1643,15 @@ static void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, D
 	if (!IJ) return;
 
 	// check if IJ is a jump
-	if(strstr(disasm.Instruction.Mnemonic, "jmp")==NULL)
+	if(strstr(disasm.getMnemonic().c_str()/*disasm.Instruction.Mnemonic*/, "jmp")==NULL)
 		return;
 
 	// return if it's a jump to a constant address, these are common
-	if(disasm.Argument1.ArgType&CONSTANT_TYPE)
+	if(disasm.getOperand(0).isConstant() /*disasm.Argument1.ArgType&CONSTANT_TYPE*/)
 		return;
 
 	// return if it's a jump to a memory address
-	if(disasm.Argument1.ArgType&MEMORY_TYPE)
+	if(disasm.getOperand(0).isMemory() /*disasm.Argument1.ArgType&MEMORY_TYPE*/)
 		return;
 
 	// has to be a jump to a register now
@@ -1630,14 +1661,15 @@ static void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, D
 		return;
 
 	// extract start of jmp table
-	DISASM d4;
-	Disassemble(I4,d4);
+	// DISASM d4;
+	// Disassemble(I4,d4);
+	DecodedInstruction_t d4(I4);
 
 	// make sure there's a scaling factor
-	if (d4.Argument2.Memory.Scale < 4)
+	if (d4.getOperand(1).isMemory() && d4.getOperand(1).getScaleValue() /*d4.Argument2.Memory.Scale*/ < 4)
 		return;
 
-	virtual_offset_t table_offset=d4.Instruction.AddrValue;
+	virtual_offset_t table_offset=d4.getAddress(); // d4.Instruction.AddrValue;
 	if(table_offset==0)
 		return;
 
@@ -1652,9 +1684,10 @@ static void check_for_nonPIC_switch_table(FileIR_t* firp, Instruction_t* insn, D
 
 	// extract size off the comparison
 	// make sure not off by one
-	DISASM d1;
-	Disassemble(I1,d1);
-	virtual_offset_t table_size = d1.Instruction.Immediat;
+	//DISASM d1;
+	//Disassemble(I1,d1);
+	DecodedInstruction_t d1(I1);
+	virtual_offset_t table_size = d1.getImmediate(); // d1.Instruction.Immediat;
 	if (table_size <= 0) return;
 
 	if(getenv("IB_VERBOSE"))
@@ -2114,9 +2147,10 @@ void mark_return_points(FileIR_t* firp)
            )
 	{
 		Instruction_t* insn=*it;
-		DISASM d;
-		Disassemble(insn,d);
-		if(string("call ")==d.Instruction.Mnemonic && insn->GetFallthrough())
+		//DISASM d;
+		//Disassemble(insn,d);
+		DecodedInstruction_t d(insn);
+		if(string("call")==d.getMnemonic() /*.Instruction.Mnemonic*/ && insn->GetFallthrough())
 		{
 			targets[insn->GetFallthrough()->GetAddress()->GetVirtualOffset()].add(ibt_provenance_t::ibtp_ret);
 		}
@@ -2226,22 +2260,25 @@ void setup_icfs(FileIR_t* firp, EXEIO::exeio* elfiop)
 		}
 
 		// disassemble the instruction, and figure out which type of hell node we need.
-		DISASM d;
-		Disassemble(insn,d);
-		if(string("ret ")==d.Instruction.Mnemonic || string("retn ")==d.Instruction.Mnemonic)
+		//DISASM d;
+		//Disassemble(insn,d);
+		DecodedInstruction_t d(insn);
+		if(string("ret")==d.getMnemonic() /*Instruction.Mnemonic*/ || string("retn")==d.getMnemonic() /*d.Instruction.Mnemonic*/)
 		{
 			if(getenv("IB_VERBOSE")!=0)
 				cout<<"using ret hell node for "<<hex<<insn->GetAddress()->GetVirtualOffset()<<endl;
 			insn->SetIBTargets(ret_hell);
 		}
-		else if ( (string("call ")==d.Instruction.Mnemonic) && ((d.Argument1.ArgType&0xffff0000&CONSTANT_TYPE)!=CONSTANT_TYPE))
+		//else if ( (string("call ")==d.Instruction.Mnemonic) && ((d.Argument1.ArgType&0xffff0000&CONSTANT_TYPE)!=CONSTANT_TYPE))
+		else if ( (string("call")==d.getMnemonic()) && (!d.getOperand(0).isConstant()))
 		{
 			if(getenv("IB_VERBOSE")!=0)
 				cout<<"using call hell node for "<<hex<<insn->GetAddress()->GetVirtualOffset()<<endl;
 			// indirect call 
 			insn->SetIBTargets(call_hell);
 		}
-		else if ( (string("jmp ")==d.Instruction.Mnemonic) && ((d.Argument1.ArgType&0xffff0000&CONSTANT_TYPE)!=CONSTANT_TYPE))
+		//else if ( (string("jmp ")==d.Instruction.Mnemonic) && ((d.Argument1.ArgType&0xffff0000&CONSTANT_TYPE)!=CONSTANT_TYPE))
+		else if ( (string("jmp")==d.getMnemonic()) && (!d.getOperand(0).isConstant()))
 		{
 			if(getenv("IB_VERBOSE")!=0)
 				cout<<"using jmp hell node for "<<hex<<insn->GetAddress()->GetVirtualOffset()<<endl;
diff --git a/libIRDB/test/split_eh_frame.cpp b/libIRDB/test/split_eh_frame.cpp
index 22a6b55c0..559ec1e99 100644
--- a/libIRDB/test/split_eh_frame.cpp
+++ b/libIRDB/test/split_eh_frame.cpp
@@ -1939,13 +1939,22 @@ void split_eh_frame_impl_t<ptrsize>::build_ir() const
 				assert(newreloc);	
 
 				if(personality_obj==NULL)
-					cout<<"Null personality obj: 0x"<<hex<<personality<<endl;
+				{
+					if(getenv("EHIR_VERBOSE")!=NULL)
+						cout<<"Null personality obj: 0x"<<hex<<personality<<endl;
+				}
 				else if(personality_scoop)
-					cout<<"Found personality scoop: 0x"<<hex<<personality<<" -> "
-					    <<personality_scoop->GetName()<<"+0x"<<hex<<addend<<endl;
+				{
+					if(getenv("EHIR_VERBOSE")!=NULL)
+						cout<<"Found personality scoop: 0x"<<hex<<personality<<" -> "
+						    <<personality_scoop->GetName()<<"+0x"<<hex<<addend<<endl;
+				}
 				else if(personality_insn)
-					cout<<"Found personality insn: 0x"<<hex<<personality<<" -> "
-					    <<personality_insn->GetBaseID()<<":"<<personality_insn->getDisassembly()<<endl;
+				{
+					if(getenv("EHIR_VERBOSE")!=NULL)
+						cout<<"Found personality insn: 0x"<<hex<<personality<<" -> "
+						    <<personality_insn->GetBaseID()<<":"<<personality_insn->getDisassembly()<<endl;
+				}
 				else
 					assert(0);
 
-- 
GitLab