/* instrumenting (instruction level) */ VOID instrument_ppm(INS ins, VOID* v){ char cat[50]; strcpy(cat,CATEGORY_StringShort(INS_Category(ins)).c_str()); if(strcmp(cat,"COND_BR") == 0){ instrument_ppm_cond_br(ins); } /* inserting calls for counting instructions (full) is done in mica.cpp */ if(interval_size != -1){ INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)ppm_instr_intervals,IARG_END); /* only called if interval is 'full' */ INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)ppm_instr_interval,IARG_END); } }
/* ===================================================================== */ VOID DumpStats(ofstream& out, STATS& stats, const string& title) { out << "#\n" "# " << title << "\n" "#\n" "#num category count-unpredicated count-predicated count-predicated-true\n" "#\n"; for ( UINT32 i = 0; i < MAX_INDEX; i++) { if( stats.unpredicated[i] == 0 && stats.predicated[i] == 0 ) continue; out << decstr(i,3) << " " << ljstr(CATEGORY_StringShort(i),15) << decstr( stats.unpredicated[i],12) << decstr( stats.predicated[i],12) << decstr( stats.predicated_true[i],12) << endl; } }
/* instrumenting (instruction level) */ VOID instrument_itypes(INS ins, VOID* v){ int i,j; char cat[50]; char opcode[50]; strcpy(cat,CATEGORY_StringShort(INS_Category(ins)).c_str()); strcpy(opcode,INS_Mnemonic(ins).c_str()); BOOL categorized = false; // go over all groups, increase group count if instruction matches that group // group counts are increased at most once per instruction executed, // even if the instruction matches multiple identifiers in that group for(i=0; i < number_of_groups; i++){ for(j=0; j < group_ids_cnt[i]; j++){ if(group_identifiers[i][j].type == identifier_type::ID_TYPE_CATEGORY){ if(strcmp(group_identifiers[i][j].str, cat) == 0){ INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)itypes_count, IARG_UINT32, i, IARG_END); categorized = true; break; } } else{ if(group_identifiers[i][j].type == identifier_type::ID_TYPE_OPCODE){ if(strcmp(group_identifiers[i][j].str, opcode) == 0){ INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)itypes_count, IARG_UINT32, i, IARG_END); categorized = true; break; } } else{ if(group_identifiers[i][j].type == identifier_type::ID_TYPE_SPECIAL){ if(strcmp(group_identifiers[i][j].str, "mem_read") == 0 && INS_IsMemoryRead(ins) ){ INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)itypes_count, IARG_UINT32, i, IARG_END); categorized = true; break; } else{ if(strcmp(group_identifiers[i][j].str, "mem_write") == 0 && INS_IsMemoryWrite(ins) ){ INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)itypes_count, IARG_UINT32, i, IARG_END); categorized = true; break; } else{ } } } else{ cerr << "ERROR! Unknown identifier type specified (" << group_identifiers[i][j].type << ")." << endl; } } } } } // count instruction that don't fit in any of the specified categories in the last group if( !categorized ){ INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)itypes_count, IARG_UINT32, (unsigned int)number_of_groups, IARG_END); // check whether this category is already known in the 'other' group for(i=0; i < other_ids_cnt; i++){ if(strcmp(other_group_identifiers[i].str, cat) == 0) break; } // if a new instruction category is found, add it to the set if(i == other_ids_cnt){ other_group_identifiers[other_ids_cnt].type = identifier_type::ID_TYPE_CATEGORY; other_group_identifiers[other_ids_cnt].str = (char*)malloc((strlen(cat)+1)*sizeof(char)); strcpy(other_group_identifiers[other_ids_cnt].str, cat); other_ids_cnt++; } // prepare for (possible) next category if(other_ids_cnt >= other_ids_max_cnt){ other_ids_max_cnt *= 2; other_group_identifiers = (identifier*)realloc(other_group_identifiers, other_ids_max_cnt*sizeof(identifier)); } } /* inserting calls for counting instructions is done in mica.cpp */ if(interval_size != -1){ INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)itypes_instr_intervals,IARG_END); /* only called if interval is 'full' */ INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)itypes_instr_interval,IARG_END); } }
static const char *CATEGORY_StringShort_detour(uint32_t num) { return strdup(CATEGORY_StringShort(num).c_str()); }