ProfilerInformation.cpp 5.06 KiB
#include <cstdlib>
#include "ProfilerInformation.h"
#define qfeof feof
/*
* ascii-to-longlong conversion; Visual Studio 2005 lacks atoll() library func
*
* no error checking; assumes decimal digits
*
* efficient conversion:
* start with value = 0
* then, starting at first character, repeat the following
* until the end of the string:
*
* new value = (10 * (old value)) + decimal value of next character
*
*/
long long my_atoll(char *instr) {
long long retval = 0;
for (; *instr; ++instr) {
retval = 10*retval + (*instr - '0');
}
return retval;
}
#ifdef WIN32
#define atoll my_atoll
#endif
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(fout);
}
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((int) nc);
if (pc)
ii->setPointerCount((int) pc);
if (oc)
ii->setOtherCount((int) 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));
}