From 311125cee2cbf44f8e92ddfa2f6bf78fef758a54 Mon Sep 17 00:00:00 2001 From: jdh8d <jdh8d@git.zephyr-software.com> Date: Wed, 14 May 2008 23:23:47 +0000 Subject: [PATCH] *** empty log message *** --- .gitattributes | 2 + ProfilerInformation.cpp | 215 ++++++++++++++++++++++++++++++++++++++++ ProfilerInformation.h | 70 +++++++++++++ 3 files changed, 287 insertions(+) create mode 100644 ProfilerInformation.cpp create mode 100644 ProfilerInformation.h diff --git a/.gitattributes b/.gitattributes index 47d84484..6998f5d3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,8 @@ * text=auto !eol /Build.sh -text /Makefile.in -text +/ProfilerInformation.cpp -text +/ProfilerInformation.h -text /README.txt -text /SMP-analyze.sh -text /SMP.idc -text diff --git a/ProfilerInformation.cpp b/ProfilerInformation.cpp new file mode 100644 index 00000000..766d1827 --- /dev/null +++ b/ProfilerInformation.cpp @@ -0,0 +1,215 @@ + + + + +#include "ProfilerInformation.h" + + +#define qfeof feof + +ProfilerInformation::ProfilerInformation(const char* fn) + : filename(std::string(fn)) +{ + + FILE* fin; + int addr; + union { int size, type;} size_type_u; + char type[200]; + char scope[200]; + char remainder[2000]; + int line=0; + + if(fn[0]==0) + return; + + fin=qfopen(fn, "r"); + + if(!fin) + { + msg("Cannot open strata annotation file %s\n", fn); + return; + } + + + + do + { + qfscanf(fin, "%x %d\n", &addr, &size_type_u); + + if(qfeof(fin)) // deal with blank lines at the EOF + break; + + qfscanf(fin, "%s%s", type,scope); + + /* if the size > 0, then this is a declaration of a variable */ + if(strcmp(type,"FUNC")==0) + { + // no useful info for the SA. + + } + else if(strcmp(type,"MEMORYHOLE")==0) + { + // no useful info for the SA. + } + else if(strcmp(type,"INSTR")==0) + { + // no useful info for the SA. + } + else if(strcmp(type,"PTRIMMEDEBP")==0 || + strcmp(type,"PTRIMMEDESP")==0 || + strcmp(type,"PTRIMMEDESP2")==0 || + strcmp(type,"PTRIMMEDABSOLUTE")==0 + ) + { + int the_const; + int real_const=0; + char field[100]; + assert(strcmp(scope,"STACK")==0 || strcmp(scope,"GLOBAL")==0); + + /* remaining params are <const> <field> <real_const_if_global> <comment> */ + qfscanf(fin, "%d %s", &the_const, field); + if( strcmp(type,"PTRIMMEDESP2")==0 || + strcmp(type,"PTRIMMEDABSOLUTE")==0 + ) + qfscanf(fin, "%x", &real_const); + else + real_const=the_const; + + // successfully read in, but, ignoring for now. + if(strcmp(type,"PTRIMMEDESP2")==0 || strcmp(type,"PTRIMMEDABSOLUTE")==0 ) + { + profileAddressingInformation(addr,size_type_u.size,type, scope,the_const,field,real_const); + } + + } + else if(strcmp(type,"DATAREF")==0) + { + // no useful info for the SA. + + } + else if (strcmp(type,"DEALLOC")==0) + { + // no useful info for the SA. + assert(strcmp(scope,"STACK")==0); + /* remaining params: comment */ + } + else if(strcmp(type,"PROFILEDNUMERIC")==0) + { + /* profiler generated information */ + addProfileInformation(addr,atoll(scope),0,0); + } + else if(strcmp(type,"PROFILEDPOINTER")==0 ) + { + /* profiler generated information */ + addProfileInformation(addr,0,atoll(scope),0); + } + else if(strcmp(type,"PROFILEDOTHER")==0 ) + { + /* profiler generated information */ + addProfileInformation(addr,0,0,atoll(scope)); + } + else + { + assert(0); + } + + qfgets(remainder, sizeof(remainder), fin); + line++; + } while(!qfeof(fin)); + qfclose(fin); + + msg("Successfully loaded annotation file %s\n", fn); +} + +ProfilerInformation::~ProfilerInformation() +{ + FILE* fout=qfopen(filename.c_str(), "a+"); + + if(!fout) + { + msg("Cannot open annotations file (%s) for output\n", filename.c_str()); + assert(0); + } + + for( std::set<std::string>::iterator iter=constant_info.begin(); + iter != constant_info.end(); + ++iter + ) + { + qfprintf(fout, "%s", (*iter).c_str()); + } + + for( std::map<ea_t,InstructionInformation*>::iterator iter=the_map.begin(); + iter != the_map.end(); + ++iter + ) + { + ea_t addr=(*iter).first; + InstructionInformation *ii=(*iter).second; + if(ii) + { + + if(ii->getNumericCount()) + { + qfprintf(fout, "%x %d %s %d Profiler generated, summarized by idal\n", + addr, 0, "PROFILEDNUMERIC", ii->getNumericCount()); + } + if(ii->getPointerCount()) + { + qfprintf(fout, "%x %d %s %d Profiler generated, summarized by idal\n", + addr, 0, "PROFILEDPOINTER", ii->getPointerCount()); + } + if(ii->getOtherCount()) + { + qfprintf(fout, "%x %d %s %d Profiler generated, summarized by idal\n", + addr, 0, "PROFILEDOTHER", ii->getOtherCount()); + } + delete ii; + } + } + + qfclose(fout); + +} + +void ProfilerInformation::addProfileInformation(ea_t addr, long long nc, long long pc, long long oc) +{ + InstructionInformation *ii=GetInfo(addr); + + if(!ii) + { + ii = new InstructionInformation; + SetInfo(addr,ii); + } + + if(nc) + ii->setNumericCount(nc); + if(pc) + ii->setPointerCount(pc); + if(oc) + ii->setOtherCount(oc); + +// msg("Profiled %x to be nc:%lld pc:%lld oc:%lld\n", addr, +// ii->getNumericCount(), +// ii->getPointerCount(), +// ii->getOtherCount()); + + return; +} + +void ProfilerInformation::profileAddressingInformation + ( + ea_t addr, + int size, + char *type, + char *scope, + ea_t the_const, + char* field, + ea_t real_const + ) +{ + char buffer[1000]; + qsnprintf(buffer, sizeof(buffer), "%x %d %s %s %d %s %x Profiler generated, idal summarized\n", + addr, size, type, scope,the_const,field,real_const); + constant_info.insert(std::string(buffer)); +} diff --git a/ProfilerInformation.h b/ProfilerInformation.h new file mode 100644 index 00000000..125ae09c --- /dev/null +++ b/ProfilerInformation.h @@ -0,0 +1,70 @@ +#ifndef PROFILERINFORMATION_H +#define PROFILERINFORMATION_H + +#include <utility> +#include <list> +#include <vector> +#include <map> +#include <set> +#include <string> + +#include <cstddef> + +#include <pro.h> +#include <ida.hpp> +#include <ua.hpp> + + +class InstructionInformation +{ + public: + InstructionInformation() : numeric_count(0), pointer_count(0), other_count(0) {}; + virtual ~InstructionInformation() {}; + + inline int isNumeric() { return numeric_count>0 && pointer_count==0 && other_count==0; } + inline void setNumericCount(int nc) { numeric_count=nc;} + inline void setPointerCount(int pc) { pointer_count=pc;} + inline void setOtherCount(int oc) { other_count=oc;} + inline long long getNumericCount() { return numeric_count; } + inline long long getPointerCount() { return pointer_count; } + inline long long getOtherCount() { return other_count; } + + private: + + long long numeric_count; + long long pointer_count; + long long other_count; +}; + +class ProfilerInformation +{ + public: + ProfilerInformation(const char*); + virtual ~ProfilerInformation(); + + inline InstructionInformation* GetInfo(ea_t addr) { return the_map[addr]; } + + protected: + // add type information from profiler about loads + void addProfileInformation(ea_t addr, long long nc, long long pc, long long oc); + + // add pre-dec info from profiler + void profileAddressingInformation ( ea_t addr, int size, char *type, + char *scope, ea_t the_const, char* field, ea_t real_const); + + inline void SetInfo(ea_t addr, InstructionInformation* ii) { the_map[addr]=ii; } + + private: + + // annotations that are used for numeric type propogation. + std::map<ea_t,InstructionInformation*> the_map; + + // annotations to spew back out verbatim. + std::set<std::string> constant_info; + + std::string filename; + +}; + +#endif + -- GitLab