/* ===================================================================== */ VOID DumpHistogram(std::ostream& out) { const UINT64 cutoff = KnobCutoff.Value(); const UINT64 maxlines = KnobMaxLines.Value(); FLT64 factor = KnobDecayFactor.Value(); out << "\033[0;0H"; out << "\033[2J"; out << "\033[44m"; out << "Functions with at least " << cutoff << " invocations in the last " << KnobThreshold.Value() << " calls "; out << "\033[0m"; out << endl; VEC CountMap; for (ADDR_CNT_MAP::iterator bi = RtnMap.begin(); bi != RtnMap.end(); bi++) { if( bi->second < cutoff ) continue; CountMap.push_back(*bi); #if 0 out << setw(18) << (void *)(bi->first) << " " << setw(10) << bi->second << " " << Target2String(bi->first) << endl; #endif } sort( CountMap.begin(), CountMap.end(), CompareLess ); UINT64 lines = 0; for (VEC::iterator bi = CountMap.begin(); bi != CountMap.end(); bi++) { out << setw(18) << (void *)(bi->first) << " " << setw(10) << bi->second << " " << Target2String(bi->first) << endl; lines++; if (lines >= maxlines) break; } for (ADDR_CNT_MAP::iterator bi = RtnMap.begin(); bi != RtnMap.end(); bi++) { bi->second = UINT64(bi->second * factor); } //out << "Total Functions: " << CountMap.size() << endl; }
VOID do_call_args_indirect(ADDRINT target, BOOL taken, ADDRINT arg0) { if( !taken ) return; const string *s = Target2String(target); do_call_args(s, arg0); if (s != &invalid) delete s; }
VOID Trace(TRACE trace, VOID *v) { const BOOL print_args = KnobPrintArgs.Value(); for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { INS tail = BBL_InsTail(bbl); if( INS_IsCall(tail) ) { if( INS_IsDirectBranchOrCall(tail) ) { const ADDRINT target = INS_DirectBranchOrCallTargetAddress(tail); if( print_args ) { INS_InsertPredicatedCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_args), IARG_PTR, Target2String(target), IARG_G_ARG0_CALLER, IARG_END); } else { INS_InsertPredicatedCall(tail, IPOINT_BEFORE, AFUNPTR(do_call), IARG_PTR, Target2String(target), IARG_END); } } else { if( print_args ) { INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_args_indirect), IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_G_ARG0_CALLER, IARG_END); } else { INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_indirect), IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_END); } } } else { // sometimes code is not in an image RTN rtn = TRACE_Rtn(trace); // also track stup jumps into share libraries if( RTN_Valid(rtn) && !INS_IsDirectBranchOrCall(tail) && ".plt" == SEC_Name( RTN_Sec( rtn ) )) { if( print_args ) { INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_args_indirect), IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_G_ARG0_CALLER, IARG_END); } else { INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(do_call_indirect), IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_END); } } } } }
VOID trace_instrument(TRACE trace, VOID *v){ for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)){ /* iterate over all basic blocks */ string codelet_string = ""; // this writes disassembly char codelet_buffer[65536*2]; int cbs = 0; INS head = BBL_InsHead(bbl); INS tail = BBL_InsTail(bbl); ADDRINT stage_entry = INS_Address( head ); ADDRINT target = 0; if (INS_IsCall(tail)){ if( INS_IsDirectBranchOrCall(tail)){ target = INS_DirectBranchOrCallTargetAddress(tail);}} INS cur ; int branch_id = slp_count; /* If compression is turned off (default), only output the addresses of * the BBL once */ if (!KnobNoCompress){ /* Instrument the head instruction right before it is called, but also * before we instrument the instructions in the basic block */ string msg_pre = "\n@@BBL(" + decstr( branch_id ) + ") STAGE " + Target2String(stage_entry)->c_str() + "\n" ; INS_InsertCall(head, IPOINT_BEFORE, AFUNPTR(string_report), IARG_PTR, new string(msg_pre), IARG_END); } /* Walk the list of instructions inside the BBL. Disassemble each, and add * it to the codelet string. Also, instrument each instruction at the * point before it is called with the do_count function. */ for ( cur = head; INS_Valid( cur ); cur = INS_Next(cur ) ){ cbs += sprintf( codelet_buffer + cbs , "\n\t@%llx\t%s", INS_Address( cur ), INS_Disassemble( cur ).c_str() ); INS_InsertCall(cur, IPOINT_BEFORE, (AFUNPTR)do_count, IARG_ADDRINT, INS_Address( cur ), IARG_END); } /* Finish off the codelet assembly string with an out message and * address ranges of the BBL */ cbs += sprintf( codelet_buffer + cbs , "\n\t}BBL.OUT [%d] %llx - %llx\n", branch_id, INS_Address( head ), INS_Address( tail )); /* If compression is turned on, output the codelet every single time we * hit the same block. */ if(KnobNoCompress){ INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(string_report), IARG_PTR, new string(codelet_buffer), IARG_END); slp_count ++; } else{ /* add the mapped BBL to output */ TraceFile.write(codelet_buffer, cbs); /* Instrument the tail instruction by inserting just before it is called */ string msg_post = "+@@BBL(" + decstr( branch_id ) + ") ACHIEVE : GOTO " + Target2String(target)->c_str(); INS_InsertCall(tail, IPOINT_BEFORE, AFUNPTR(string_report), IARG_PTR, new string(msg_post), IARG_END); slp_count ++; } } }