// Writes the image load event to the file "imgLog" static void LogImageLoad(IMG img, void *v) { // Ensure that we can't overflow when we read it back. ASSERTX (IMG_Name(img).length() < MAX_FILENAME_LENGTH); ADDRESS_RANGE range = FindImageTextMargin(img); // Log the data needed to restore it fprintf(imgLog, "L '%s' %llx %lx %llx %d \n", IMG_Name(img).c_str(), (unsigned long long)range._low, (long)(range._high - range._low), (unsigned long long)IMG_LoadOffset(img), (int)IMG_IsMainExecutable(img)); for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (SEC_Type(sec) != SEC_TYPE_EXEC) { continue; } for (RTN rtn=SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { if (RTN_IsArtificial(rtn)) { continue; } fprintf(imgLog, "\t'%s' %llx\n", RTN_Name(rtn).c_str(), (unsigned long long)RTN_Address(rtn)); } } fprintf(imgLog, "%s", END_RTN_LIST); }
RTN RTN_FindLoop(IMG img, string rtn_name) { SEC temp=IMG_SecHead(img); while(SEC_Valid(temp)) { //we pick only executable code segment if(SEC_Type(temp)==SEC_TYPE_EXEC){ RTN myrtn=SEC_RtnHead(temp); DBG_TRACE("RTNs to be instrumented"); while(RTN_Valid(myrtn)) { cerr<<RTN_Name(myrtn)<<endl; if(RTN_Name(myrtn)==rtn_name) { cerr<<"Rtn Found:"<<rtn_name<<endl; return myrtn; } myrtn=RTN_Next(myrtn); } } temp=SEC_Next(temp); } RTN empty; return empty; }
// Prints all RTNs in a given IMG to the trace file. // We use that file later on to see if the record and replay went the same static VOID PrintRTNs(IMG img) { for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (SEC_Type(sec) != SEC_TYPE_EXEC) { continue; } for (RTN rtn=SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { if (RTN_IsArtificial(rtn)) { continue; } fprintf(trace, "Function '%s' loaded at %llx\n", RTN_Name(rtn).c_str(), (unsigned long long)RTN_Address(rtn)); } } }
// Find and return the memory region of an image's executable section static ADDRESS_RANGE FindImageTextMargin(IMG img) { ADDRESS_RANGE res; ADDRINT low = ~0L; ADDRINT high = 0L; for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (SEC_Type(sec) != SEC_TYPE_EXEC) { continue; } low = MIN(low, SEC_Address(sec)); high = MAX(high, SEC_Address(sec) + SEC_Size(sec)); } res._low = low; res._high = high; return res; }
VOID ImageUnload(IMG img, VOID * v) { if ( KnobNoSharedLibs.Value() && IMG_Type(img) == IMG_TYPE_SHAREDLIB) return; out << "Image: " << IMG_Name(img) << endl; // Visit all the sections of the image that are executable for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (SEC_Type(sec) != SEC_TYPE_EXEC) continue; out << " Section: " << SEC_Name(sec) << endl; // Print the addresses of instructions that were not executed PrintUntouchedRanges(sec); } }
// Count the number of RTN objects inside an IMG static int CountImageRtns(IMG img) { int numRtns = 0; for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (SEC_Type(sec) != SEC_TYPE_EXEC) { continue; } for (RTN rtn=SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { if (RTN_IsArtificial(rtn)) { continue; } numRtns++; } } return numRtns; }
VOID ImageLoad (IMG img, VOID *v) { uint32_t id = IMG_Id (img); std::string iname = IMG_Name(img); if (id==1) // this is the first image, extract the path and the name of the executable { string ename, epath; MIAMIU::ExtractNameAndPath(iname, epath, ename); MIAMI::MiamiOptions *mo = MIAMI::mdriver.getProgramOptions(); mo->addExecutableName(ename); mo->addExecutablePath(epath); } // print info about the sections in this image, for debugging // comment out in production runs #if DEBUG_CFG_COUNTS DEBUG_CFG(4, cerr << "Image: " << iname << ", id " << id << hex << " load offser=0x" << IMG_LoadOffset(img) << ", low addr=0x" << IMG_LowAddress(img) << ", high addr=0x" << IMG_HighAddress(img) << ", start addr=0x" << IMG_StartAddress(img) << ", mapped size=0x" << IMG_SizeMapped(img) << dec << ", has the following sections:" << endl; for (SEC sec= IMG_SecHead(img) ; SEC_Valid(sec) ; sec = SEC_Next(sec)) { cerr << "Section " << SEC_Name(sec) << " of type " << SEC_Type(sec) << " at address 0x" << hex << SEC_Address(sec) << " of size 0x" << SEC_Size(sec) << dec << "/" << SEC_Size(sec) << " bytes:" << " valid? " << SEC_Valid(sec) << ", mapped? " << SEC_Mapped(sec) << ", executable? " << SEC_IsExecutable(sec) << ", readable? " << SEC_IsReadable(sec) << ", writable? " << SEC_IsWriteable(sec) << endl; } )
void TraceManager::InstApply(IMG img) { DBG_TRACE("before check"); DBG_TRACE(IMG_Name(img)); if(mySpec==NULL){ cerr<<"Spec manager is Null"<<endl; return; } string imgname=ImageTrim(IMG_Name(img)); cerr<<imgname<<endl; /*!!! if(imgname.compare(MPI_LIB)==0) { //if the module is mpi dll then //MpiInst(img); return; } */ //for rest of the modules it goes ahead here //checks if it's to be instrumented //leaves if it's not suppose to be if(!mySpec->InstImage(imgname)) { DBG_TRACE("Not to be instrumented"); return; } //cerr<<"After approved for image inst"<<endl; //Start enumarting all the routines in the image to be instrumented SEC temp=IMG_SecHead(img); while(SEC_Valid(temp)) { //we pick only executable code segment if(SEC_Type(temp)==SEC_TYPE_EXEC){ RTN myrtn=SEC_RtnHead(temp); DBG_TRACE("RTNs to be instrumented"); while(RTN_Valid(myrtn)) { DBG_TRACE(RTN_Name(myrtn)); //cerr<<RTN_Name(myrtn)<<endl; if(IsMpiRtn(RTN_Name(myrtn))) { #ifndef NOMPI MpiInstRtn(myrtn); #endif myrtn=RTN_Next(myrtn); continue; } if(RTN_Name(myrtn).length()==0 || !IsInstSafe(RTN_Name(myrtn))) { myrtn=RTN_Next(myrtn); continue; } if(mySpec->InstRtn(RTN_Name(myrtn),imgname)) { //if the routine is to be instrumented //apply the instrumentation here RTN_Open(myrtn); if(!IsNormal(myrtn)) { RTN_Close(myrtn); myrtn=RTN_Next(myrtn); continue; } //DBG_TRACE(RTN_Name(myrtn)); RtnTrack * brtntr = new RtnTrack; brtntr->img=imgname; brtntr->rtn=RTN_Name(myrtn); brtntr->stage=0; brtntr->flag=mySpec->GetProfileFlag(brtntr->rtn,brtntr->img); //insert the instrumentation at the exit point RTN_InsertCall(myrtn, IPOINT_AFTER, (AFUNPTR)HookHandleAfter, IARG_PTR ,brtntr, IARG_END); //RTN_InsertCallProbed(myrtn, IPOINT_AFTER, (AFUNPTR)HookHandleAfter, IARG_PTR ,brtntr, IARG_END); //insert the instrumentation at the entry point RTN_InsertCall(myrtn, IPOINT_BEFORE, (AFUNPTR)HookHandleBefore, IARG_PTR ,brtntr, IARG_END); //RTN_InsertCallProbed(myrtn, IPOINT_BEFORE, (AFUNPTR)HookHandleBefore, IARG_PTR ,brtntr, IARG_END); //cerr<<"Name::"<<RTN_Name(myrtn)<<" Start::"<<RTN_Address(myrtn)<<" End::"<<RTN_Address(myrtn)+RTN_Size(myrtn)<<endl; RTN_Close(myrtn); } myrtn=RTN_Next(myrtn); } } temp=SEC_Next(temp); } }