The following is a small example of assembly code instrumentation. The goal of this piece of code is to instrument basic blocks to obtain a basic block invocation count. SALTO adds a comment before each basic block using the COMMENT_ATT attribute and adds instrumentation code at the beginning of each block. The code added saves some register values before calling the function bbcount which performs the counting proper. This function may be written in a high-level language. In our example, it is written in C. The function is linked with the generated assembly code to produce an executable.
The function called for each block is
#include "salto.h" void add_code(BB *bb, int cpt) { INST *nop; char instcode[STR_MAX]; nop = bb -> newNOP(); sprintf(ch, "\t save register values \n" "\t mov %d,%%o0\n" "\t call _bbcount \n" "\t restore values \n", cpt); nop ->addAttribute(UNPARSE_ATT, strdup(ch), strlen(ch)); bb -> insertAsm(0, nop); } void Salto_hook() { CFG *proc; BB *bb; int i, j, ncfg, nbb, cpt=0; char ch[20]; ncfg = numberOfCFG(); for(i=0; i < ncfg; i++) { // for each procedure proc = getCFG(i); nbb = proc -> numberOfBB(); for(j=0; j < nbb; j++) { // for each basic block bb = proc -> getBB(j); sprintf(ch, "bb %d", ++cpt); // comment to add to a BB bb -> addAttribute(COMMENT_ATT, strdup(ch), strlen(ch)); add_code(bb, cpt); } } produceCode(stdout); // Finished, now dumps instrumented code on stdout }