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