atom_application_instrumentatiatom_application_instrumentation(5)
atom_application_instrumentation, AddCallProto, AddCallProgram,
AddCallObj, AddCallProc, AddCallEntry, AddCallBlock,
AddCallInst, ReplaceProto, ReplaceEntry, ReplaceProcedure
- Allows an Atom tool's instrumentation routine
to add, within an application program, calls to analysis
routines
#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 * );
The Atom application instrumentation routines allow you to
add arbitrary 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 [Toc] [Back]
You must use the AddCallProto routine to specify the prototype
of each procedure call to be added to the program.
In other words, an AddCallProto 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 definition. The name of the analysis procedure
is followed by a parenthesized 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, especially 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 instrumentation. If your instrumentation
code passes a stable buffer to AddCallObj, 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: GetObjName, 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 during 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 following table. For such
arguments, specify VALUE in the AddCallProto call and the
argument's symbolic name in the call to AddCallObj, AddCallProc,
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 argument
is valid only on load or store instructions
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 argument
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 runtime
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 runtime
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 routine for each added call requires a slightly
different prototype. This usually occurs when you pass an
array argument and the number of elements in the array
depends on the contents of the object. Normally, it is
illegal to reprototype an analysis routine, but Atom makes
an exception for array parameters. If the only difference
between the new prototype 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 [Toc] [Back]
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 PlaceType 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 execution. If ProgramAfter is specified,
Atom calls the analysis procedure after each child process
completes execution and after the parent process completes
execution.
AddCallObj Routine [Toc] [Back]
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 something 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 procedure 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 procedures 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 execution).
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 [Toc] [Back]
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 ProcAfter as the instrumentation
point, followed by the name of the analysis 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 analysis 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 [Toc] [Back]
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 instrumentation point, followed by
the name of the analysis procedure and a list of its arguments.
AddCallBlock Routine [Toc] [Back]
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 BlockAfter 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 [Toc] [Back]
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 executes. 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 [Toc] [Back]
An implied PlaceType hierarchy exists in the execution
ordering of calls to analysis procedures when the calls
occur at the same instrumentation 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. Multiple 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 [Toc] [Back]
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 procedure should emulate the replaced entry
point by accepting all the same arguments and returning a
comparable return value. Replacement procedures 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 translation 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 [Toc] [Back]
You must use the ReplaceProto routine to declare the procedural
interface 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 superset of AddCallProto's
procedural interface arguments, to allow application
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 argument 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 runtime
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 [Toc] [Back]
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 earlier releases,
but using ReplaceEntry (above) is recommended.
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);
}
These routines have no return values.
Header file containing external definitions of Atom routines
Commands: atom(1)
Functions: atom_application_navigation(5), atom_application_query(5), atom_application_symbols(5), atom_description_file(5), atom_instrumentation_routines(5),
atom_object_management(5), AnalHeapBase(5), Thread(5),
Xlate(5)
Programmer's Guide
atom_application_instrumentation(5)
[ Back ] |