atom_application_instrumentation(5)atom_application_instrumentation(5)NAME
atom_application_instrumentation, AddCallProto, AddCallProgram, AddCal‐
lObj, AddCallProc, AddCallEntry, AddCallBlock, AddCallInst, Replace‐
Proto, ReplaceEntry, ReplaceProcedure - Allows an Atom tool's instru‐
mentation routine to add, within an application program, calls to anal‐
ysis routines
SYNOPSIS
#include <cmplrs/atom.inst.h>
void AddCallProto(
const char * ); void AddCallProgram(
PlaceType,
const char *, ... ); void AddCallObj(
Obj *,
PlaceType,
const char *, ... ); void AddCallProc(
Proc *,
PlaceType,
const char *, ... ); void AddCallEntry(
Entry *,
PlaceType,
const char *, ... ); void AddCallBlock(
Block *,
PlaceType,
const char *, ... ); void AddCallInst(
Inst *,
PlaceType,
const char *, ... ); void ReplaceProto(
const char * ); void ReplaceEntry(
Entry *,
const char *, ... ); void ReplaceProcedure(
Proc *,
const char * );
DESCRIPTION
The Atom application instrumentation routines allow you to add arbi‐
trary procedure calls before and after objects, procedures, basic
blocks, and instructions. You can also add procedure calls before a
main or alternate entry point. In addition, you can add procedure calls
before and after the application program executes.
You can use these routines only from an Atom tool's instrumentation
file. See atom(1) for a description of Atom.
AddCallProto Routine
You must use the AddCallProto routine to specify the prototype of each
procedure call to be added to the program. In other words, an AddCall‐
Proto call must define the procedural interface for each call to an
analysis procedure to be added to the program by subsequent calls to
AddCallProgram, AddCallObj, AddCallProc, AddCallEntry, AddCallBlock,
and AddCallInst.
The format of the prototype is similar to a C language function defini‐
tion. The name of the analysis procedure is followed by a parenthe‐
sized list of arguments.
There are four basic argument types: Constants Computed values (VALUE)
Register values (REGV and FREGV) Address translation structure (*XLATE)
Constant types include char, int, long, char *, char[], int[], and
long[]. Often, arrays are used to communicate static information, espe‐
cially large data structures, to analysis procedures. Three special
keywords exist to facilitate the passing of array and string arguments:
Indicates that the analysis routine cannot modify or write to the
passed array or string. Atom allocates the memory for such a string or
array in the instrumented program's read-only memory. Using const can
thus greatly reduce the memory usage of instrumented programs that have
multiple images active simultaneously. Indicates that Atom does not
need to make a copy of the data for the string or array during instru‐
mentation. If your instrumentation code passes a stable buffer to Add‐
CallObj, AddCallProc, AddCallEntry, AddCallBlock, or AddCallInst, it
must not modify or free the buffer until after WriteObj is called for
the object containing the given Obj, Proc, Entry, Block, or Inst. If
you pass a stable buffer to AddCallProgram, you must never modify or
free the buffer.
Strings returned by the following routines can be considered
stable for the duration of the instrumentation process: GetObj‐
Name, GetObjOutName, GetAnalName, GetObjInstArray, ProcName,
ProcFileName, and GetInstProcCalled. Indicates that Atom does
not need to make a copy of the data for the string or array dur‐
ing instrumentation and that it will deallocate the buffer (by
calling free) when it is done with it. Instrumentation code
should never modify or free such a buffer after it has been
passed to AddCallObj, AddCallProc, AddCallEntry, AddCallBlock,
AddCallInst, or AddCallProgram.
You can use the const keyword with either stable or free. The stable
and free keywords are mutually exclusive.
The VALUE argument type defines an argument with a 64-bit value that
Atom must compute before passing it to the analysis procedure. There
are two arguments of the VALUE argument type, as listed in the follow‐
ing table. For such arguments, specify VALUE in the AddCallProto call
and the argument's symbolic name in the call to AddCallObj, AddCall‐
Proc, AddCallEntry, AddCallBlock, AddCallInst, or AddCallProgram.
─────────────────────────────────────────────────────────────────────
Type Argument Description
─────────────────────────────────────────────────────────────────────
VALUE EffAddrValue Effective load-time address of a load or
store instruction. This is the sum of the
64-bit address contained in the base register
and the signed 16-bit displacement. (Note
that, for a shared library, the run-time PC
differs from the compile-time PC.) This argu‐
ment is valid only on load or store instruc‐
tions instrumented by an AddCallInst call
with InstBefore specified. Otherwise, Atom
reports an error.
VALUE BrCondValue Outcome of a conditional branch instruction.
Returns a zero (0) if the branch condition
will evaluate to false or a 64-bit nonzero
value if it will evaluate to true. This argu‐
ment is valid only on conditional branch
instructions instrumented by an AddCallInst
call with InstBefore specified. Otherwise,
Atom reports an error.
─────────────────────────────────────────────────────────────────────
The REGV and FREGV argument types define an argument representing the
contents of a register. FREGV is used for floating-point registers;
REGV is used for all other registers. There are several arguments of
the REGV and FREGV argument types, as listed in the following table.
For such arguments, specify REGV or FREGV in the AddCallProto call and
the argument's symbolic name in the call to AddCallObj, AddCallProc,
AddCallEntry, AddCallBlock, AddCallInst, or AddCallProgram.
────────────────────────────────────────────────────────────────────
Type Argument Description
────────────────────────────────────────────────────────────────────
REGV REG_n Integer register n, where n is a value from 0
to 31.
REGV REG_RA Return address register.
REGV REG_GP Global pointer.
REGV REG_SP Stack pointer.
REGV REG_ZERO Integer register 31.
REGV REG_CC Processor cycle counter.
REGV REG_PC Pure compile-time (that is, noninstrumented)
program counter at the instrumentation point.
(Note that, for a shared library, the run-
time PC differs from the compile-time PC.)
REGV REG_IPC Instrumented program counter at run-time If
the call is from a shared library, the run-
time PC is passed.
REGV REG_ARG_n Integer argument register n, where n is a
value from 1 to 6.
REGV REG_RETVAL Integer function return value.
REGV FREG_n Floating-point register n, where n is a value
from 0 to 31.
FREGV FREG_ZERO Floating-point register 31.
FREGV FREG_ARG_n Floating-point argument register n, where n
is a value from 1 to 6.
FREGV FREG_RETVAL Floating-point function return value.
────────────────────────────────────────────────────────────────────
Note that the special REGV-type value REG_NOTUSED is also defined as a
return value from GetInstRegEnum. You cannot pass it as an argument to
AddCallObj, AddCallProc, AddCallEntry, AddCallBlock, AddCallInst, or
AddCallProgram.
Note
When you use AddCallObj, you will sometimes find that the analysis rou‐
tine for each added call requires a slightly different prototype. This
usually occurs when you pass an array argument and the number of ele‐
ments in the array depends on the contents of the object. Normally, it
is illegal to reprototype an analysis routine, but Atom makes an excep‐
tion for array parameters. If the only difference between the new pro‐
totype and the old prototype is the length of an array parameter, Atom
allows you to use AddCallProto to reprototype the analysis routine.
Subsequent calls to that analysis routine will use the new array
length.
AddCallProgram Routine
Use the AddCallProgram routine in an InstrumentInit or InstrumentAll
routine to add a call to an analysis procedure before a program starts
execution or after it completes execution. Typically such an analysis
procedure does something that applies to the whole program, such as
opening an output file or parsing command line options. Supply a Place‐
Type value of ProgramBefore or ProgramAfter as the instrumentation
point, followed by the name of the analysis procedure and a list of its
arguments. Since ProgramAfter actions are executed after the program
is complete, library routines requiring system services should not be
used in ProgramAfter analysis routines.
Because the Instrument routine is called for each object in a program,
avoid calling AddCallProgram from the Instrument routine.
If the program forks and ProgramBefore is specified, Atom calls the
analysis procedure only once - before the parent process starts execu‐
tion. If ProgramAfter is specified, Atom calls the analysis procedure
after each child process completes execution and after the parent
process completes execution.
AddCallObj Routine
Use the AddCallObj routine in an instrumentation routine to add a call
to an analysis procedure before an object starts execution or after it
completes execution. Typically such an analysis procedure does some‐
thing that applies to the single object, such as initializing some data
for its procedures. Supply a PlaceType value of ObjBefore or ObjAfter
as the instrumentation point, followed by the name of the analysis pro‐
cedure and a list of its arguments.
Instrumentation code added at the beginning of an object is executed
immediately after the object is loaded into memory (before any proce‐
dures in that object are executed). Instrumentation code added at the
end of an object is executed immediately before that object is unloaded
from memory (after all procedures from that object have finished execu‐
tion).
Note
An InstrumentAll routine must call the BuildObj routine before calling
AddCallObj, AddCallProc, AddCallEntry, AddCallBlock, or AddCallInst to
add analysis routine calls, and before traversing the procedures in the
object. BuildObj builds the internal data structures Atom uses to
manipulate the object. After the Atom tool traverses and instruments
the object, the InstrumentAll routine must call the WriteObj routine to
write out the instrumented version of the object. See the
atom_object_management(5) reference page for additional information.
AddCallProc Routine
Use the AddCallProc routine in an instrumentation routine to add a call
to an analysis procedure before a procedure starts execution or after
it completes execution. Supply a PlaceType value of ProcBefore or Pro‐
cAfter as the instrumentation point, followed by the name of the analy‐
sis procedure and a list of its arguments. The following factors
determine when the analysis procedures are called: If the procedure has
multiple entry points and ProcBefore is specified, Atom calls the anal‐
ysis procedure at each entry point. If the procedure has multiple exit
points and ProcAfter is specified, Atom calls the analysis procedure
each time it issues a return. If the procedure contains interprocedural
branches or interprocedural jumps, the call to the analysis procedure
will occur before the branch or jump. Compilers can optimize return
statements or non-returning function calls to interprocedural branches.
To avoid this, recompile with -O0 or -no_inline. If the procedure does
not issue a return (for example, it calls exit or longjmp), Atom does
not call the analysis procedure.
AddCallEntry Routine
Use the AddCallEntry routine in an instrumentation routine to add a
call to an analysis routine before a main or alternate entry starts
execution. Supply a PlaceType value of EntryBefore as the instrumenta‐
tion point, followed by the name of the analysis procedure and a list
of its arguments.
AddCallBlock Routine
Use the AddCallBlock routine in an instrumentation routine to add a
call to an analysis procedure before a basic block starts execution or
after it completes execution. Supply a PlaceType value of BlockBefore
or BlockAfter as the instrumentation point, followed by the name of the
analysis procedure and a list of its arguments.
If the basic block ends with an unconditional branch or jump and Block‐
After is specified, Atom calls the analysis procedure after the basic
block completes execution. However, if the basic block ends with a jump
to a subroutine that does not return (for instance, the subroutine
calls exit or longjmp), Atom does not call the analysis procedure.
AddCallInst Routine
Use the AddCallInst routine in an instrumentation routine to add a call
to an analysis procedure before a given instruction executes or after
it executes. Supply a PlaceType value of InstBefore or InstAfter as the
instrumentation point, followed by the name of the analysis procedure
and a list of its arguments.
If the instruction is an unconditional branch or jump and InstAfter is
specified, Atom calls the analysis procedure after the instruction exe‐
cutes. However, if the instruction is a jump to a subroutine that does
not return (for example, the subroutine calls exit or longjmp), Atom
does not call the analysis procedure.
PlaceType Hierarchy
An implied PlaceType hierarchy exists in the execution ordering of
calls to analysis procedures when the calls occur at the same instru‐
mentation point. By enforcing an ordering, Atom guarantees, for
instance, that a call to an analysis procedure added at BlockBefore
executes before a call to an analysis procedure added at InstBefore
when the Inst and the Block identify the same instrumentation point.
The before PlaceType ordering of calls is:
ProgramBefore
ObjBefore
ProcBefore or EntryBefore
BlockBefore
InstBefore
The after PlaceType ordering of calls is:
InstAfter
BlockAfter
ProcAfter
ObjAfter
ProgramAfter
Multiple calls added at the same instrumentation point via the same
PlaceType will be executed in the order they were instrumented. Multi‐
ple calls added at the same instrumentation point via the ProcBefore
and EntryBefore PlaceTypes will also be executed in the order they were
instrumented since the ProcBefore and EntryBefore PlaceTypes have the
same before PlaceType ordering.
ReplaceEntry Routine
Use the ReplaceEntry routine to intercept an application's calls to a
given main or alternate entry point. Only calls that follow the Alpha
Calling Standard can be intercepted, and calls that have been expanded
inline by compiler optimizations cannot be intercepted.
The char * argument indicates the name of the replacement procedure in
the tool's analysis code that will be called instead of the replaced
entry point. Only the specified entry point is replaced; other entry
points in the same procedure may be replaced by using additional
ReplaceEntry calls.
In addition to performing the desired analysis, the replacement proce‐
dure should emulate the replaced entry point by accepting all the same
arguments and returning a comparable return value. Replacement proce‐
dures usually implement this emulation by calling the replaced entry
point through a function pointer that is either passed into the
replacement procedure as the ReplAddrValue argument (see below) or is
initialized by calling the XlateAddr routine with an address transla‐
tion buffer set up via the AddXlateEntry routine.
Note that replacing entry points containing thread cancellation points
is not supported.
The tool's instrumentation code must call the ReplaceProto routine
first, in the same way that the AddCallProto routine must be called
before the AddCallProc routine. ReplaceProto must be called before the
main executable is written.
ReplaceProto Routine
You must use the ReplaceProto routine to declare the procedural inter‐
face to any replacement procedure before making the associated
ReplaceEntry call. ReplaceProto's single string pointer argument has
the same format as that of AddCallProto. ReplaceProto accepts a super‐
set of AddCallProto's procedural interface arguments, to allow applica‐
tion and analysis data to be passed into the replacement procedure.
The following two additional arguments can be used to provide the
replacement procedure with the application arguments and the address of
the replaced entry point. These arguments have VALUE argument types and
are similar to those supported by the AddCallProto routine. Note that
currently only fixed arguments are supported, not "..." variable argu‐
ment lists.
──────────────────────────────────────────────────────────────────────
Type Argument Description
──────────────────────────────────────────────────────────────────────
VALUE ArgValue A fixed argument of the replaced entry point.
For an entry point with N arguments, the
first N arguments in the ReplaceProto string,
the ReplaceEntry call (after the Entry
pointer and replacement name), and the
replacement routine's definition must match
the N arguments of the replaced entry point.
VALUE ReplAddrValue The address of the replaced entry point in
the running instrumented application. This
address is equivalent to an Xlate address
generated by AddXlateEntry.
──────────────────────────────────────────────────────────────────────
For example, the following pair of ReplaceProto and ReplaceEntry calls
intercepts calloc(3) library calls, passing two application arguments
and three additional analysis arguments (the return address of the
application's call to calloc, the replaced library routine's run-time
address, and the ObjID of the object that contains calloc).
ReplaceProto("replacement_calloc(VALUE, VALUE, REGV, VALUE, long)");
ReplaceEntry(FindEntry(obj,"calloc"), "replacement_calloc",
ArgValue, ArgValue, REG_RA, ReplAddrValue,
GetObjInfo(obj,ObjID));
The associated replacement routine would be declared like this:
int replacement_calloc(size_t num, size_t size, long ra,
void *(*replaced_calloc)(size_t, size_t),
long obj_id);
ReplaceProcedure Routine
Use the ReplaceProcedure routine to replace a procedure with a routine
that has the same arguments and return type but is linked with your
analysis code. The named replacement code should emulate the replaced
procedure, and it will usually also analyze all the calls made to it by
applications. Any alternate entry points are also replaced and are
assumed to have the same arguments and return type.
The ReplaceProcedure routine does not support replacing undocumented
library routines, and it does not support replacement routines that are
optimized in certain ways. It is retained for compatibility with ear‐
lier releases, but using ReplaceEntry (above) is recommended.
EXAMPLES
The following example accumulates wall-clock and per-process time for a
procedure. The instrumentation routine defines the prototypes for calls
to analysis procedures and identifies the instrumentation points at
which those calls take place:
AddCallProto("Start(REGV)");
AddCallProto("Stop(REGV)");
.
.
.
AddCallProc(p,ProcBefore,"Start",REG_CC);
AddCallProc(p,ProcAfter,"Stop",REG_CC);
.
.
.
The analysis routine is complicated by the format of the cycle counter.
The low-order 32 bits contain a free running cycle count. The high-
order 32 bits of the counter are an offset that, when added to the low-
order 32 bits, produces a cycle count for this process. The low-order
32 bits can be used directly to determine wall clock times:
long total;
long process;
int ccStart;
int ccStartProcess;
void Start(unsigned long cc) {
ccStart = cc;
ccStartProcess = ((cc << 32) + cc) >> 32;
}
void Stop(unsigned long cc) {
int ccEnd = cc;
int ccEndProcess = ((cc << 32) + cc) >> 32;
total += (unsigned) (ccEnd - ccStart);
process += (unsigned) (ccEndProcess - ccStartProcess);
}
RETURN VALUES
These routines have no return values.
FILES
Header file containing external definitions of Atom routines
SEE ALSO
Commands: atom(1)
Functions: atom_application_navigation(5), atom_application_query(5),
atom_application_symbols(5), atom_description_file(5), atom_instrumen‐
tation_routines(5), atom_object_management(5), AnalHeapBase(5),
Thread(5), Xlate(5)
Programmer's Guide
atom_application_instrumentation(5)