Using FIT is fairly straightforward. We've designed it to be compatible with ATOM's interface, so if you've ever used that, using FIT should not be a problem. In this section we will give a high-level overview of the process of creating a custom instrumentor. For a detailed description of how to use FIT, we refer to the MANUAL file included in the FIT distribution.

Suppose you want to create btrace, an instrumentor that prints out a basic block trace of the instrumented program to a file. To do this, you need to create two files, btrace.anal.c and btrace.inst.c. The first file describes the analysis procedures your instrumentor will insert into the program, and the second file describes where to insert them, and what parameters you want to pass to them.

The code in those files is pretty self-explanatory, so let's just take a look at it:

btrace.anal.c
void * fd;

void Init()
{
  fd = fopen("trace.out","w");
}

void Fini()
{
  fclose(fd);
}

void TraceBlock(void * block_address)
{
  fprintf(fd,"0x%x\n",block_address);
}
	
btrace.inst.c
#include <cmplrs/atom.inst.h>

void InstrumentInit(int argc, char ** argv)
{
  AddCallProto("Init()");
  AddCallProto("Fini()");
  AddCallProto("TraceBlock(REGV)");
}

void Instrument(int argc, char ** argv, Obj *obj)
{
  Proc *p; Block *b;
  AddCallProgram(ProgramBefore, "Init");
  AddCallProgram(ProgramAfter , "Fini");
  for (p = GetFirstObjProc(obj); p != NULL; p = GetNextProc(p))
    for (b = GetFirstBlock(p); b != NULL; b = GetNextBlock(b))
      AddCallBlock(b,BlockBefore,"TraceBlock",REG_PC);
}
	
In the analysis file, we've defined an Init() procedure that opens the trace file, a Fini() procedure that closes the file after the tracing is done, and a TraceBlock() procedure that takes the address of a basic block as an argument and then prints it in the file.
In the instrumentation file, there are two procedures:

The following diagram shows how FIT builds an instrumentor based on the analysis and instrumentation files:


The instrumentation file is compiled and linked to the instrumentation backend to provide the actual instrumentor, btrace. The analysis file is cross-compiled to the target architecture, and btrace will link this file and some support code into the program to be instrumented. btrace then adds calls to the analysis routines at the appropriate program points, and emits the final, instrumented program.