From 8d776b38a983d9c7bc07f8f086b15ffe96381c29 Mon Sep 17 00:00:00 2001
From: jdh8d <jdh8d@git.zephyr-software.com>
Date: Mon, 25 Nov 2013 18:57:25 +0000
Subject: [PATCH] Former-commit-id: e2ed64da3e8549c0bfda33d0015976b16f4c4321

---
 libIRDB/include/core/fileir.hpp    |  8 ++++-
 libIRDB/include/libIRDB-core.hpp   |  1 +
 libIRDB/src/core/fileir.cpp        | 57 +++++++++++++++++++++++++++---
 libIRDB/src/core/generate_spri.cpp | 10 ++----
 libIRDB/src/core/instruction.cpp   |  6 +---
 libIRDB/test/fill_in_cfg.cpp       |  9 +----
 libIRDB/test/fill_in_indtargs.cpp  | 22 ++++++++----
 7 files changed, 81 insertions(+), 32 deletions(-)

diff --git a/libIRDB/include/core/fileir.hpp b/libIRDB/include/core/fileir.hpp
index d5c8b5f18..3f8e250b2 100644
--- a/libIRDB/include/core/fileir.hpp
+++ b/libIRDB/include/core/fileir.hpp
@@ -37,7 +37,7 @@ class FileIR_t : public BaseObj_t
 	void AssembleRegistry();
 	void RegisterAssembly(Instruction_t *instr, std::string assembly);
 	void UnregisterAssembly(Instruction_t *instr);
-    std::string LookupAssembly(Instruction_t *instr);
+	std::string LookupAssembly(Instruction_t *instr);
 
 	//Needed for inserting assembly before an instruction. 
 	//if orig is not registered, the function returns, otherwise
@@ -46,7 +46,13 @@ class FileIR_t : public BaseObj_t
 	//removes the mapping for orig->assembly from the map. 
 	void ChangeRegistryKey(Instruction_t* orig, Instruction_t* updated);
 
+	static int GetArchitectureBitWidth();
+	void SetArchitecture();
+
 	private:
+
+	static ArchitectureDescription_t *archdesc;
+
 	#define ASM_REG_MAX_SIZE 500000
 
 	typedef std::map<Instruction_t*,std::string> registry_type;
diff --git a/libIRDB/include/libIRDB-core.hpp b/libIRDB/include/libIRDB-core.hpp
index 05064f88c..2cbded135 100644
--- a/libIRDB/include/libIRDB-core.hpp
+++ b/libIRDB/include/libIRDB-core.hpp
@@ -26,6 +26,7 @@ class Instruction_t; // forward decl for many classes
 #include <core/file.hpp>
 #include <core/function.hpp>
 #include <core/variantid.hpp>
+#include <core/archdesc.hpp>
 #include <core/fileir.hpp>
 #include <core/pqxxdb.hpp>
 
diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp
index 523d6a97f..9535dcdef 100644
--- a/libIRDB/src/core/fileir.cpp
+++ b/libIRDB/src/core/fileir.cpp
@@ -4,6 +4,7 @@
 #include <cstdlib>
 #include <map>
 #include <fstream>
+#include <elf.h>
 using namespace libIRDB;
 using namespace std;
 
@@ -40,7 +41,10 @@ FileIR_t::FileIR_t(const VariantID_t &newprogid, File_t* fid) : BaseObj_t(NULL)
 		fileptr=fid;
 
 	if(progid.IsRegistered())
+	{
 		ReadFromDB();
+		SetArchitecture();
+	}
 
 }
 
@@ -142,10 +146,7 @@ void FileIR_t::AssembleRegistry()
 	
 	DISASM disasm;
 	memset(&disasm, 0, sizeof(DISASM));
-	if(sizeof(void*)==8)
-		disasm.Archi=64;
-	else
-		disasm.Archi=32;
+	disasm.Archi=GetArchitectureBitWidth();
 
 	ifstream binreader;
 	unsigned int filesize;
@@ -528,3 +529,51 @@ std::string Relocation_t::WriteToDB(File_t* fid, Instruction_t* myinsn)
                 string("'") + to_string(GetDoipID())          + string("') ; ") ;
 	return q;	
 }
+
+int FileIR_t::GetArchitectureBitWidth()
+{
+	return archdesc->GetBitWidth();
+}
+
+void FileIR_t::SetArchitecture()
+{
+
+	/* the first 16 bytes of an ELF file define the magic number and ELF Class. */
+    	unsigned char e_ident[16];
+
+	DBinterface_t* myinter=BaseObj_t::GetInterface();
+	pqxxDB_t *mypqxxintr=dynamic_cast<pqxxDB_t*>(myinter);
+
+	int elfoid=GetFile()->GetELFOID();
+        pqxx::largeobjectaccess loa(mypqxxintr->GetTransaction(), elfoid, PGSTD::ios::in);
+
+
+        loa.cread((char*)&e_ident, sizeof(e_ident));
+
+	if((e_ident[EI_MAG0]!=ELFMAG0) || 
+	   (e_ident[EI_MAG1]!=ELFMAG1) || 
+	   (e_ident[EI_MAG2]!=ELFMAG2) || 
+	   (e_ident[EI_MAG3]!=ELFMAG3))
+	{
+		cerr << "ELF magic number wrong:  is this an ELF file? " <<endl;
+		exit(-1);
+	}
+
+	archdesc=new ArchitectureDescription_t;
+
+	switch(e_ident[4])
+	{
+		case ELFCLASS32:
+			archdesc->SetBitWidth(32);
+			break;
+		case ELFCLASS64:
+			archdesc->SetBitWidth(64);
+			break;
+		case ELFCLASSNONE:
+		default:
+			cerr << "Unknown ELF class " <<endl;
+			exit(-1);
+	}
+}
+
+ArchitectureDescription_t* FileIR_t::archdesc=NULL;
diff --git a/libIRDB/src/core/generate_spri.cpp b/libIRDB/src/core/generate_spri.cpp
index 31fca4df5..b4d094965 100644
--- a/libIRDB/src/core/generate_spri.cpp
+++ b/libIRDB/src/core/generate_spri.cpp
@@ -386,10 +386,7 @@ static string emit_spri_instruction(FileIR_t* fileIRp, Instruction_t *newinsn, o
 		memset(&disasm, 0, sizeof(DISASM));
 
 		disasm.Options = NasmSyntax + PrefixedNumeral + ShowSegmentRegs;
-		if(sizeof(void*)==8)
-			disasm.Archi = 64;
-		else
-			disasm.Archi = 32;
+		disasm.Archi = fileIRp->GetArchitectureBitWidth();
 		disasm.EIP = (UIntPtr)newinsn->GetDataBits().c_str();
 		disasm.VirtualAddr = old_insn ? old_insn->GetAddress()->GetVirtualOffset() : 0;
 
@@ -666,10 +663,7 @@ static void emit_spri_rule(FileIR_t* fileIRp, Instruction_t* newinsn, ostream& f
 	{
 		DISASM disasm;
 		disasm.Options = NasmSyntax + PrefixedNumeral + ShowSegmentRegs;
-		if(sizeof(void*)==8)
-			disasm.Archi = 64;
-		else
-			disasm.Archi = 32;
+		disasm.Archi = fileIRp->GetArchitectureBitWidth();
 		disasm.EIP = (UIntPtr)newinsn->GetDataBits().c_str();
 		disasm.VirtualAddr = old_insn ? old_insn->GetAddress()->GetVirtualOffset() : 0;
 
diff --git a/libIRDB/src/core/instruction.cpp b/libIRDB/src/core/instruction.cpp
index 7065b6529..838916009 100644
--- a/libIRDB/src/core/instruction.cpp
+++ b/libIRDB/src/core/instruction.cpp
@@ -51,11 +51,7 @@ int Instruction_t::Disassemble(DISASM &disasm){
   	memset(&disasm, 0, sizeof(DISASM));
   
   	disasm.Options = NasmSyntax + PrefixedNumeral;
-	if(sizeof(void*)==8)
-  		disasm.Archi = 64;
-	else
-  		disasm.Archi = 32;
-		
+	disasm.Archi = FileIR_t::GetArchitectureBitWidth();
   	disasm.EIP = (UIntPtr) GetDataBits().c_str();
   	disasm.VirtualAddr = GetAddress()->GetVirtualOffset();
   	int instr_len = Disasm(&disasm);
diff --git a/libIRDB/test/fill_in_cfg.cpp b/libIRDB/test/fill_in_cfg.cpp
index f234afe28..8321c580a 100644
--- a/libIRDB/test/fill_in_cfg.cpp
+++ b/libIRDB/test/fill_in_cfg.cpp
@@ -278,7 +278,7 @@ void add_new_instructions(FileIR_t *firp)
                 		memset(&disasm, 0, sizeof(DISASM));
 
                 		disasm.Options = NasmSyntax + PrefixedNumeral;
-                		disasm.Archi = sizeof(void*)*8;	// 32 or 64
+                		disasm.Archi = firp->GetArchitectureBitWidth();
                 		disasm.EIP = (UIntPtr) &data[offset_into_section];
                 		disasm.VirtualAddr = missed_address;
                 		int instr_len = Disasm(&disasm);
@@ -373,13 +373,6 @@ void fill_in_cfg(FileIR_t *firp)
       			DISASM disasm;
       			memset(&disasm, 0, sizeof(DISASM));
 	
-#if 0
-      			disasm.Options = NasmSyntax + PrefixedNumeral;
-      			disasm.Archi = 32;
-      			disasm.EIP = (UIntPtr) insn->GetDataBits().c_str();
-      			disasm.VirtualAddr = insn->GetAddress()->GetVirtualOffset();
-      			int instr_len = Disasm(&disasm);
-#endif
       			int instr_len = insn->Disassemble(disasm);
 	
 			assert(instr_len==insn->GetDataBits().size());
diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp
index 81821808b..83370ce0d 100644
--- a/libIRDB/test/fill_in_indtargs.cpp
+++ b/libIRDB/test/fill_in_indtargs.cpp
@@ -100,10 +100,20 @@ void possible_target(int p)
 	}
 }
 
-void handle_argument(ARGTYPE *arg)
+void handle_argument(ARGTYPE *arg, Instruction_t* insn)
 {
-	if( arg->ArgType == MEMORY_TYPE ) 
-		possible_target(arg->Memory.Displacement);
+	if( (arg->ArgType&MEMORY_TYPE) == MEMORY_TYPE ) 
+	{
+		if((arg->ArgType&RELATIVE_)==RELATIVE_)
+		{
+			assert(insn);
+			assert(insn->GetAddress());
+			possible_target(arg->Memory.Displacement+insn->GetAddress()->GetVirtualOffset()+
+				insn->GetDataBits().length());
+		}
+		else
+			possible_target(arg->Memory.Displacement);
+	}
 }
 
 void mark_targets(FileIR_t *firp)
@@ -156,9 +166,9 @@ void get_instruction_targets(FileIR_t *firp)
 		/* otherwise, any immediate is a possible branch target */
 		possible_target(disasm.Instruction.Immediat);
 
-		handle_argument(&disasm.Argument1);
-		handle_argument(&disasm.Argument2);
-		handle_argument(&disasm.Argument3);
+		handle_argument(&disasm.Argument1, insn);
+		handle_argument(&disasm.Argument2, insn);
+		handle_argument(&disasm.Argument3, insn);
 	}
 
 }
-- 
GitLab