From d236c967f93ed7d0b6f5c9249551d13ca2a331f6 Mon Sep 17 00:00:00 2001
From: jdh8d <jdh8d@git.zephyr-software.com>
Date: Sun, 21 Feb 2016 01:05:34 +0000
Subject: [PATCH] first draft of unpinning

Former-commit-id: 8ca350cb1deaab663a1ff542508601dcc9006b7f
---
 libIRDB/include/core/reloc.hpp    |  2 +-
 libIRDB/src/core/fileir.cpp       | 16 ++++++--
 libIRDB/src/core/scoop.cpp        | 12 +++++-
 libIRDB/test/fill_in_indtargs.cpp | 65 ++++++++++++++++++++++++++++++-
 libIRDB/test/fill_in_indtargs.hpp | 15 ++++---
 5 files changed, 98 insertions(+), 12 deletions(-)

diff --git a/libIRDB/include/core/reloc.hpp b/libIRDB/include/core/reloc.hpp
index 91b6149b6..cae7cb362 100644
--- a/libIRDB/include/core/reloc.hpp
+++ b/libIRDB/include/core/reloc.hpp
@@ -32,7 +32,7 @@ class Relocation_t : public BaseObj_t
 
         Relocation_t(db_id_t reloc_id) : BaseObj_t(NULL) { assert(0);}          // read from DB       
         void WriteToDB() { assert(0); }   // writes to DB ID is not -1.
-        std::string WriteToDB(File_t* fid, Instruction_t* insn);    // writes to DB, ID is not -1.
+        std::string WriteToDB(File_t* fid, BaseObj_t* insn);    // writes to DB, ID is not -1.
 
 	void SetOffset(int off) { offset=off;}
 	int GetOffset() { return offset; }
diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp
index c623be425..8e7c3860f 100644
--- a/libIRDB/src/core/fileir.cpp
+++ b/libIRDB/src/core/fileir.cpp
@@ -478,7 +478,7 @@ void FileIR_t::ReadRelocsFromDB
                 db_id_t wrt_id=atoi(dbintr->GetResultColumn("wrt_id").c_str());
 
 
-		BaseObj_t* wrt_obj=objMap[wrt_id];
+		BaseObj_t* wrt_obj=objMap[wrt_id];	 // might be null.
 		Relocation_t *reloc=new Relocation_t(reloc_id,reloc_offset,reloc_type,wrt_obj);
 
 		assert(objMap[instruction_id]!=NULL);
@@ -634,7 +634,15 @@ void FileIR_t::WriteToDB()
 		DataScoop_t* scoop = *it;
 		assert(scoop);
 		string q = scoop->WriteToDB(fileptr,j);
+
+                const std::set<Relocation_t*> &the_relocs = scoop->GetRelocations();
+                for(set<Relocation_t*>::const_iterator rit=the_relocs.begin(); rit!=the_relocs.end(); ++rit)
+                {
+                        Relocation_t* reloc=*rit;
+                        q+=reloc->WriteToDB(fileptr,scoop);
+                }
 		dbintr->IssueQuery(q);
+
 	}
 }
 
@@ -687,16 +695,18 @@ void FileIR_t::SetBaseIDS()
 			(*i)->SetBaseID(j++);
 }
 
-std::string Relocation_t::WriteToDB(File_t* fid, Instruction_t* myinsn)
+std::string Relocation_t::WriteToDB(File_t* fid, BaseObj_t* myinsn)
 {
 	string q;
+	db_id_t wrt_id=wrt_obj ? wrt_obj->GetBaseID() : BaseObj_t::NOT_IN_DATABASE;
         q ="insert into " + fid->relocs_table_name;
-	q+="(reloc_id,reloc_offset,reloc_type,instruction_id,doip_id) "+
+	q+="(reloc_id,reloc_offset,reloc_type,instruction_id,wrt_id,doip_id) "+
                 string(" VALUES (") +
                 string("'") + to_string(GetBaseID())          + string("', ") +
                 string("'") + to_string(offset)               + string("', ") +
                 string("'") + (type)                          + string("', ") +
                 string("'") + to_string(myinsn->GetBaseID())  + string("', ") +
+                string("'") + to_string(wrt_id)  + string("', ") +
                 string("'") + to_string(GetDoipID())          + string("') ; ") ;
 	return q;	
 }
diff --git a/libIRDB/src/core/scoop.cpp b/libIRDB/src/core/scoop.cpp
index 878a52aec..31f3a5017 100644
--- a/libIRDB/src/core/scoop.cpp
+++ b/libIRDB/src/core/scoop.cpp
@@ -1,5 +1,8 @@
 #include "all.hpp"
 #include <utils.hpp>
+#include <sstream>
+#include <iomanip>
+
 
 using namespace std;
 using namespace libIRDB;
@@ -21,14 +24,21 @@ string DataScoop_t::WriteToDB(File_t *fid, db_id_t newid)
 
 	db_id_t type_id=(GetType() ? GetType()->GetBaseID() : BaseObj_t::NOT_IN_DATABASE);
 
+        ostringstream hex_data;
+        hex_data << setfill('0') << hex;;
+        for (size_t i = 0; i < contents.length(); ++i)
+                hex_data << setw(2) << (int)(contents[i]&0xff);
+
+
         string q=string("insert into ")+fid->scoop_table_name +
-                string(" (scoop_id, name, type_id, start_address_id, end_address_id, permissions) ")+
+                string(" (scoop_id, name, type_id, start_address_id, end_address_id, data, permissions) ")+
                 string(" VALUES (") +
                 string("'") + to_string(GetBaseID()) + string("', ") +
                 string("'") + GetName()  + string("', ") +
                 string("'") + to_string(type_id) + string("', ") +
                 string("'") + to_string(GetStart()->GetBaseID()) + string("', ") +
                 string("'") + to_string(GetEnd()->GetBaseID()) + string("', ") +
+                string("decode('") + hex_data.str() + string("', 'hex'), ") +
                 string("'") + to_string(permissions) + string("'); ") ;
 
 	return q;
diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp
index 98be6f7be..dc587376e 100644
--- a/libIRDB/test/fill_in_indtargs.cpp
+++ b/libIRDB/test/fill_in_indtargs.cpp
@@ -1019,7 +1019,9 @@ DN:   0x4824XX: .long 0x4824e0-LN
 		case REG13: base_reg="r13"; break;
 		case REG14: base_reg="r14"; break;
 		case REG15: base_reg="r15"; break;
-		default: assert(0);
+		default: 
+			// no base register;
+			return;
 	}
 	string lea_string="lea ";
 	lea_string+=base_reg;
@@ -1883,6 +1885,64 @@ cout<<"using jmp hell node for "<<hex<<insn->GetAddress()->GetVirtualOffset()<<e
 }
 
 
+void unpin_init_array(FileIR_t *firp)
+{
+	for(
+		DataScoopSet_t::iterator it=firp->GetDataScoops().begin();
+		it!=firp->GetDataScoops().end();
+		++it
+	   )
+	{
+		// 4 or 8 
+		int ptrsize=firp->GetArchitectureBitWidth()/8;
+
+		DataScoop_t* scoop=*it;
+		const char *scoop_contents=scoop->GetContents().c_str();
+		if(scoop->GetName()==".init_array")
+		{
+			for(int i=0; i+ptrsize <= scoop->GetSize() ; i+=ptrsize)
+			{
+				virtual_offset_t vo;
+				if(ptrsize==4)
+					/* get int, 4 bytes */
+					vo=(virtual_offset_t)*(int*)&scoop_contents[i];
+				else if(ptrsize==8)
+					/* get long long, 8 bytes */
+					vo=(virtual_offset_t)*(long long*)&scoop_contents[i];
+				else
+					assert(0);	
+
+
+				Instruction_t* insn=lookupInstruction(firp,vo);
+
+
+				cout<<"Unpinning entry at offset "<<dec<<i<<endl;
+				// these asserts are probably overkill, but want them for sanity checking for now.
+				assert(insn);
+				assert(targets.find(vo)!=targets.end());
+				assert(targets[vo].areOnlyTheseSet(
+					ibt_provenance_t::ibtp_initarray | ibt_provenance_t::ibtp_stars_data));
+				// when/if they fail, convert to if and guard the reloc creation.
+
+				Relocation_t* nr=new Relocation_t();
+				assert(nr);
+				nr->SetType("init_array_entry");
+				nr->SetOffset(i);
+				nr->SetWRT(insn);
+
+				// add reloc to IR.
+				firp->GetRelocations().insert(nr);
+				scoop->GetRelocations().insert(nr);
+			}
+		}
+	}
+}
+
+void unpin_well_analyzed_ibts(FileIR_t *firp)
+{
+	unpin_init_array(firp);
+}
+
 
 
 /*
@@ -1951,6 +2011,9 @@ void fill_in_indtargs(FileIR_t* firp, exeio* elfiop, std::list<virtual_offset_t>
 
 	// try to setup an ICFS for every IB.
 	setup_icfs(firp);
+
+
+	unpin_well_analyzed_ibts(firp);
 }
 
 
diff --git a/libIRDB/test/fill_in_indtargs.hpp b/libIRDB/test/fill_in_indtargs.hpp
index 7fea34de9..1f14c2760 100644
--- a/libIRDB/test/fill_in_indtargs.hpp
+++ b/libIRDB/test/fill_in_indtargs.hpp
@@ -95,12 +95,15 @@ class ibt_provenance_t
 		static const provtype_t ibtp_unknown=1<<28;	// completely unknown
 		static const provtype_t ibtp_got=1<<29;	// got is 0 init'd, shouldn't see this one.
 
-		void add(provtype_t t) { value |=t; }
-		void add(ibt_provenance_t t) { value |=t.value; }
-		bool isFullySet(provtype_t t) { return (value&t) == t; }
-		bool isFullySet(ibt_provenance_t t) { return (value&t.value) == t.value; }
-		bool isPartiallySet(provtype_t t) { return (value&t) != 0; }
-		bool isPartiallySet(ibt_provenance_t t) { return (value&t.value) != 0; }
+		void add(const provtype_t t) { value |=t; }
+		void add(const ibt_provenance_t t) { value |=t.value; }
+		bool isFullySet(const provtype_t t) const { return (value&t) == t; }
+		bool isFullySet(const ibt_provenance_t t) const { return (value&t.value) == t.value; }
+		bool isPartiallySet(const provtype_t t) const { return (value&t) != 0; }
+		bool isPartiallySet(const ibt_provenance_t t) const { return (value&t.value) != 0; }
+
+		bool areOnlyTheseSet(const provtype_t t) const { return (value&~t) == 0; }
+		bool areOnlyTheseSet(const ibt_provenance_t t) const { return (value&~t.value) == 0; }
 
 	private:
 
-- 
GitLab