From cd8052ecbddb6c4b80af55e8d836cc99e397d2e8 Mon Sep 17 00:00:00 2001
From: an7s <an7s@git.zephyr-software.com>
Date: Tue, 13 Oct 2015 14:43:55 +0000
Subject: [PATCH] Handle out-of-order FUNC <--> INSTR annotations.

Former-commit-id: 62896a8f9ce0f3e13a83455722e8e6485931b1f6
---
 xform/function_descriptor.cpp  | 25 ++++++++++------
 xform/function_descriptor.h    | 25 ++++++++++------
 xform/instruction_descriptor.h | 24 ++++++++--------
 xform/rewriter.cpp             | 52 ++++++++++++++++++++++++++++------
 xform/rewriter.h               |  6 +++-
 5 files changed, 93 insertions(+), 39 deletions(-)

diff --git a/xform/function_descriptor.cpp b/xform/function_descriptor.cpp
index ddadad023..ae0a062ee 100644
--- a/xform/function_descriptor.cpp
+++ b/xform/function_descriptor.cpp
@@ -23,7 +23,7 @@
 
 #include "function_descriptor.h"
 
-wahoo::Function::Function()
+void wahoo::Function::_init()
 {
   m_name = "";
   m_address = -1;
@@ -34,20 +34,27 @@ wahoo::Function::Function()
   m_functionID = -1;
 }
 
+wahoo::Function::Function()
+{
+  _init();
+}
+
+wahoo::Function::Function(app_iaddr_t p_start)
+{
+  _init();
+  setAddress(p_start);
+}
+
 wahoo::Function::Function(string p_name, app_iaddr_t p_start, int p_size)
 {
-  m_name = p_name;
-  m_address = p_start;
-  m_size = p_size;
-  m_isSafe = false;
-  m_useFP = false;
-  m_outArgsRegionSize = 0;
-  m_functionID = -1;
+  _init();
+  setName(p_name);
+  setAddress(p_start);
+  setSize(p_size);
 }
 
 wahoo::Function::~Function()
 {
-
 }
 
 bool wahoo::Function::operator == (const Function &other)
diff --git a/xform/function_descriptor.h b/xform/function_descriptor.h
index fc10ebd76..9e30733fa 100644
--- a/xform/function_descriptor.h
+++ b/xform/function_descriptor.h
@@ -15,29 +15,34 @@ class Function
 {
   public:
     Function();
+    Function(app_iaddr_t);
     Function(string, app_iaddr_t, int);
     ~Function();
 
-    string            getName() { return m_name; }
-    app_iaddr_t       getAddress() { return m_address; }
-    int               getSize() { return m_size; }
-    int               getFunctionID() { return m_functionID; }
+    string            getName() const { return m_name; }
+    void              setName(const string p_name) { m_name = p_name; }
+    app_iaddr_t       getAddress() const { return m_address; }
+    void              setAddress(const app_iaddr_t p_address) { m_address = p_address; }
+    int               getSize() const { return m_size; }
+    void              setSize(const int p_size) { m_size = p_size; }
+    int               getFunctionID() const { return m_functionID; }
     void              setFunctionID(const int id) { m_functionID = id; }
 
+	
     bool operator == (const Function &);
     bool operator == (const app_iaddr_t);
     bool operator != (const Function &);
     bool operator != (const app_iaddr_t);
 
-    bool isSafe() { return m_isSafe; }
+    bool isSafe() const { return m_isSafe; }
     void setSafe() { m_isSafe = true; }
     void setUnsafe() { m_isSafe = false; }
 
-    void setOutArgsRegionSize(int p_size) { m_outArgsRegionSize = p_size; }
-    int getOutArgsRegionSize() { return m_outArgsRegionSize; }
+    void setOutArgsRegionSize(const int p_size) { m_outArgsRegionSize = p_size; }
+    int getOutArgsRegionSize() const { return m_outArgsRegionSize; }
 
-    void setUseFramePointer(bool p_useFP) { m_useFP = p_useFP; }
-    bool getUseFramePointer() { return m_useFP; }
+    void setUseFramePointer(const bool p_useFP) { m_useFP = p_useFP; }
+    bool getUseFramePointer() const { return m_useFP; }
 
     void addInstruction(wahoo::Instruction *);
     void addStackAllocationInstruction(wahoo::Instruction *);
@@ -56,6 +61,8 @@ class Function
     double getInstructionCoverage(int*, int*);
 
   private:
+    void _init();
+
     int            m_functionID;
     string         m_name;
     app_iaddr_t    m_address;
diff --git a/xform/instruction_descriptor.h b/xform/instruction_descriptor.h
index 6aed3dabc..e09c6bfd7 100644
--- a/xform/instruction_descriptor.h
+++ b/xform/instruction_descriptor.h
@@ -15,7 +15,7 @@ class Function;
 class Instruction {
   public:
     Instruction();
-    Instruction(app_iaddr_t, int, Function* = NULL);
+    Instruction(app_iaddr_t, int p_size = -1, Function* = NULL);
     ~Instruction();
 
     void setSize(int p_size) { m_size = p_size; }
@@ -26,25 +26,25 @@ class Instruction {
     void markStackRef();
     void markVarStackRef();
 
-    app_iaddr_t     getAddress() { return m_address; }
-    app_iaddr_t     getIBTAddress() { return m_ibt_address; }
-    int             getSize() { return m_size; }
-    Function*       getFunction() { return m_function; }
-    string          getAsm() { return m_asm; }
+    app_iaddr_t     getAddress() const { return m_address; }
+    app_iaddr_t     getIBTAddress() const { return m_ibt_address; }
+    int             getSize() const { return m_size; }
+    Function*       getFunction() const { return m_function; }
+    string          getAsm() const { return m_asm; }
     void            setAsm(string p_str) { m_asm = p_str; }
     void            setData(void *dataPtr, int len);
-    unsigned char*  getData() { return m_data; }
+    unsigned char*  getData() const { return m_data; }
     void            setData(void *data) { m_data = (unsigned char*) data; }
     void     	    setIBTAddress(app_iaddr_t v) { m_ibt_address=v; }
 
-    bool isStackRef() { return m_stackRef; }
-    bool isVarStackRef() { return m_varStackRef; }
-    bool isAllocSite() { return m_allocSite; }
-    bool isDeallocSite() { return m_deallocSite; }
+    bool isStackRef() const { return m_stackRef; }
+    bool isVarStackRef() const { return m_varStackRef; }
+    bool isAllocSite() const { return m_allocSite; }
+    bool isDeallocSite() const { return m_deallocSite; }
 
     // keep track of whether instruction has been visited during execution
     void setVisited() { m_isVisited = true; }
-    bool isVisited() { return m_isVisited; }
+    bool isVisited() const { return m_isVisited; }
 
   private:
     app_iaddr_t     m_address;
diff --git a/xform/rewriter.cpp b/xform/rewriter.cpp
index a7ed292b4..9b7e6ab81 100644
--- a/xform/rewriter.cpp
+++ b/xform/rewriter.cpp
@@ -52,6 +52,28 @@ Rewriter::~Rewriter()
 {
 }
 
+wahoo::Function* Rewriter::ensureFunctionExists(const app_iaddr_t p_addr)
+{
+	if (m_functions.count(p_addr) > 0)
+		return m_functions[p_addr];
+
+    wahoo::Function *fn = new wahoo::Function(p_addr);
+	m_functions[p_addr] = fn;
+
+	return fn;
+}
+
+wahoo::Instruction* Rewriter::ensureInstructionExists(const app_iaddr_t p_addr)
+{
+	if (m_instructions.count(p_addr) > 0)
+		return m_instructions[p_addr];
+
+    wahoo::Instruction *instr = new wahoo::Instruction(p_addr);
+	m_instructions[p_addr] = instr;
+
+	return instr;
+}
+
 /*
 * Read MEDS annotation file and populate relevant hash table & data structures
 */
@@ -132,7 +154,10 @@ void Rewriter::readAnnotationFile(char p_filename[])
 //				fprintf(stderr, "Adding name=%s pc=%x to funclist hash table\n", flhk->name, flhv->pc);
 				Hashtable_put(funclists_hash, flhk, flhv);	
 
-				wahoo::Function *fn = new wahoo::Function(name, addr, size_type_u.size);
+				wahoo::Function *fn = ensureFunctionExists(addr);
+				fn->setAddress(addr);
+				fn->setSize(size_type_u.size);
+//				wahoo::Function *fn = new wahoo::Function(name, addr, size_type_u.size);
 				fgets(remainder, sizeof(remainder), fin);
 				if (strstr(remainder, "FUNC_SAFE"))
 					fn->setSafe();
@@ -146,7 +171,6 @@ void Rewriter::readAnnotationFile(char p_filename[])
 
 				line++;
 				continue;
-
 			}
 			else if(strcmp(scope,"FRAMERESTORE")==0)
 			{
@@ -249,6 +273,7 @@ void Rewriter::readAnnotationFile(char p_filename[])
 				stackref_hash_key_t sshk;
 				stackref_hash_value_t *sshv;
 				sshk.pc = addr;
+				ensureInstructionExists(addr);
 				m_instructions[addr]->setSize(size_type_u.size);
 				if (sshv = (stackref_hash_value_t*) Hashtable_get(stackrefs_hash, &sshk))
 				{
@@ -308,7 +333,8 @@ void Rewriter::readAnnotationFile(char p_filename[])
                     		Hashtable_put(instrmaps_hash,key,val); 
 
 				// rely on the fact that INST BELONGTO is the first INST annotation in a MEDS file (warning: but it is not required to be there)
-				assert(m_functions[func_addr]);
+//				assert(m_functions[func_addr]);
+				wahoo::Function *fn = ensureFunctionExists(func_addr);
 				wahoo::Instruction* instr = new wahoo::Instruction(addr, -1, m_functions[func_addr]);
 				m_instructions[addr] = instr;
 
@@ -320,14 +346,16 @@ void Rewriter::readAnnotationFile(char p_filename[])
 			{
 
               			assert(strcmp(scope,"LOCAL")==0);
+						ensureInstructionExists(addr);
 
+/*
                         	if (!m_instructions[addr])
                         	{
                                 	// unknown size, unknown function
                                 	wahoo::Instruction* instr = new wahoo::Instruction(addr, -1, NULL);
                                 	m_instructions[addr] = instr;
                         	}
-
+*/
 
                     		switch(annot_type)
                     		{
@@ -447,12 +475,15 @@ MEDS doesn't mark this as a stack reference
 			/* add to hashtable */
 			Hashtable_put(constants_hash, chk,chv);	
 	
+			ensureInstructionExists(addr);
+/*
 			if (!m_instructions[addr])
 			{
  				// unknown size, unknown function
 				wahoo::Instruction* instr = new wahoo::Instruction(addr, -1, NULL);
 				m_instructions[addr] = instr;
 			}
+*/
 
 //			fprintf(stderr,"@ 0x%x marking instruction as stack reference\n", addr);
 			m_instructions[addr]->markStackRef();
@@ -531,6 +562,8 @@ any esp access outside this region (esp + K) >= (esp + size) can be xformed
 					if (strstr(remainder,"OutArgsRegion"))
 					{
 //fprintf(stderr," found OutArgsRegion @ 0x%08x\n", addr);
+						ensureInstructionExists(addr);
+						assert(m_instructions[addr]->getFunction());
 						m_instructions[addr]->getFunction()->setOutArgsRegionSize(size_type_u.size);
 					}
 					line++;
@@ -552,7 +585,8 @@ any esp access outside this region (esp + K) >= (esp + size) can be xformed
 			if (addr - prevStackDeallocPC == 3 || addr - prevStackDeallocPC == 6)
 			{
 //				fprintf(stderr, "Detected nice stack deallocation instruction at 0x%x\n", prevStackDeallocPC);
-				assert(m_instructions[prevStackDeallocPC]);
+//				assert(m_instructions[prevStackDeallocPC]);
+				ensureInstructionExists(prevStackDeallocPC);
 				m_instructions[prevStackDeallocPC]->markDeallocSite();
 				m_instructions[prevStackDeallocPC]->setSize(addr - prevStackDeallocPC);
 			
@@ -560,7 +594,8 @@ any esp access outside this region (esp + K) >= (esp + size) can be xformed
 			// handle leave/ret
 			else if (addr - prevStackDeallocPC == 1)
 			{
-				assert(m_instructions[prevStackDeallocPC]);
+//				assert(m_instructions[prevStackDeallocPC]);
+				ensureInstructionExists(prevStackDeallocPC);
 				m_instructions[prevStackDeallocPC]->markDeallocSite();
 				m_instructions[prevStackDeallocPC]->setSize(1);
 			}
@@ -600,7 +635,7 @@ void Rewriter::readXrefsFile(char p_filename[])
 
         if(!fin)
         {
-                fprintf(stderr,"Cannot open xref enotation file %s\n", p_filename);
+                fprintf(stderr,"Cannot open xref annotation file %s\n", p_filename);
                 return;
         }
 
@@ -627,7 +662,8 @@ void Rewriter::readXrefsFile(char p_filename[])
 		assert(strcmp(scope,"XREF")==0);
 		fscanf(fin, "%s%s%s", ibt,fromib,dest);
 		assert(strcmp(ibt,"IBT")==0);
-		assert(strcmp(fromib,"FROMIB")==0 || strcmp(fromib,"FROMDATA")==0);
+		assert(strcmp(fromib,"FROMIB")==0 || strcmp(fromib,"FROMDATA")==0 
+			|| strcmp(fromib,"FROMUNKNOWN")==0);
 	
 		
       		wahoo::Instruction *instr = addr_to_insn_map[addr];
diff --git a/xform/rewriter.h b/xform/rewriter.h
index d2726b6fb..417c29501 100644
--- a/xform/rewriter.h
+++ b/xform/rewriter.h
@@ -26,7 +26,7 @@ class Rewriter
     void readAnnotationFile(char []);
     void readXrefsFile(char []);
     void readElfFile(char []);
-    ElfReader *getElfReader() { return m_elfReader; }
+    ElfReader *getElfReader() const { return m_elfReader; }
     FILE* getAsmSpri() { return m_spri; };
     void setAsmSpri(FILE *p_spri) { m_spri = p_spri; };
 
@@ -43,6 +43,10 @@ class Rewriter
     map<app_iaddr_t, wahoo::Function*> m_functions;
     map<app_iaddr_t, wahoo::Instruction*> m_instructions;
 
+  private:
+    wahoo::Function*     ensureFunctionExists(const app_iaddr_t);
+    wahoo::Instruction*  ensureInstructionExists(const app_iaddr_t);
+
   private:
     ElfReader*    m_elfReader;   
     FILE*         m_spri; 
-- 
GitLab