The COEMS Instrumentation Tool is a command-line tool, which can be used for instrumenting C-Code, for example to generate outputs via the ITM-Interface of an Intel processor.
Usage
The tool receives a C source-file as well as a JSON-file, containing the instrumentation configuration, as inputs.
It generates the instrumented C-file, which can be used for compilation and an additional header-file, where the user-specific callbacks can be inserted.
Example code and instrumentation configuration can be found here
The basic tool usage is the following:
USAGE: coems-instrumentation [options] <source0> [... <sourceN>]
OPTIONS:
Generic Options:
-help - Display available options (-help-hidden for more)
-help-list - Display list of available options (-help-list-hidden for more)
-version - Display the version of this program
Instrumentation:
-extra-arg=<string> - Additional argument to append to the compiler command line
-extra-arg-before=<string> - Additional argument to prepend to the compiler command line
-inst=<string> - JSON file containing information, which code shall be instrumented
-out-dir=<string> - Output directory
-p=<string> - Build path
The code parts which shall be instrumented are described in a json-file, which is passed to the tool via the -inst
option. The format of the json is as follows:
SPEC ::= "{" ASSIGNMENTS "," VARREADS "," FUNCTIONCALLS "," FUNCTIONCALLED "," FUNCTIONRETURNS "," FUNCTIONRETURNED "}"
ASSIGNMENTS ::= "\"Assignments\" : [" (PATTERN ("," PATTERN)*)? "]"
VARREADS ::= "\"VarReads\" : [" (PATTERN ("," PATTERN)*)? "]"
FUNCTIONCALLS ::= "\"FunctionCalls\" : [" (FUNCDESCR ("," FUNCDESCR)*)? "]"
FUNCTIONCALLED ::= "\"FunctionCalled\" : [" (FUNCDESCR ("," FUNCDESCR)*)? "]"
FUNCTIONRETURNS ::= "\"FunctionReturns\" : [" (FUNCDESCR ("," FUNCDESCR)*)? "]"
FUNCTIONRETURNED ::= "\"FunctionReturned\" : [" (FUNCDESCR ("," FUNCDESCR)*)? "]"
PATTERN ::= VAR | ARRAY | STRUCTUNION | REF | DEREF
VAR ::= "{ \"Variable\" : {\"VarName\" :" STRING (", \"Function\" :" STRING)? "}" [", \"code\" : " STRING ] "}"
ARRAY ::= "{ \"ArrayAccess\" : PATTERN [", \"code\" : " STRING ] "}"
STRUCTUNION ::= "{ \"StructUnionAccess\" : {{\"Base\" :" PATTERN ", \"Field\" :" STRING "}" [", \"code\" : " STRING ] "}"
REF ::= "{ \"Ref\" :" PATTERN [", \"code\" : " STRING ] "}"
DEREF ::= "{ \"DeRef\" :" PATTERN [", \"code\" : " STRING ] "}"
FUNCDESCR ::= "{\"FunctionName\" : " STRING [", \"code\" : " STRING ] "}"
Such a json-file could look like this:
{
"Assignments" :
[
{"Variable" : {"VarName" : "a", "Function" : "main"} },
{"DeRef" : {"Variable" : {"VarName" : "aa", "Function" : "main"} } },
{"Variable" : {"VarName" : "x"} },
{"ArrayAccess" : {"Variable" : {"VarName" : "b", "Function" : "main"} } }
],
"VarReads" :
[
{"Ref" : {"Variable" : {"VarName" : "x"} } },
{"StructUnionAccess" : {"Base" : {"Variable" : {"VarName" : "a", "Function" :
"main"}}, "Field" : "a"} }
],
"FunctionCalls" :
[
{"FunctionName" : "f1"}
],
"FunctionCalled" :
[
{"FunctionName" : "add"},
{"FunctionName" : "main"}
],
"FunctionReturns" :
[
{"FunctionName" : "add"}
],
"FunctionReturned" :
[
{"FunctionName" : "add"}
]
}
- All expression pattern listed in the Assignments-section will be instrumented at each write.
- All expression pattern listed in the VarReads-section will be instrumented when the variable value is returned (does not include ++/- – calls).
- All functions listed in the FunctionCalls-section will be instrumented at each call. The instrumentation takes place in the calling code.
- All functions listed in the FunctionCalled-section will be instrumented at each call. The instrumentation takes place as first command in the called code.
- All functions listed in the FunctionReturns-section will be instrumented at each return statement.
- All functions listed in the FunctionReturned-section will be instrumented after a function call returned. The instrumentation is inserted in the code part where the function is called.
- The
Variable
pattern matches a certain variable. If theFunction
attribute is set, a local variable is matched, otherwise a global one.
- The
ArrayAccess
pattern matches an array access (a[b]), where a can be further described in the json. b’s value will be passed to the callback function as well.
- The
StructUnionAccess
pattern matches an access of a field of a struct or union (a.b / a->b), where a is a certain expression and b a fixed string.
- The
Ref
pattern matches the reference-operator in front of another expression (&a).
- The
DeRef
pattern matches the dereference-operator in front of another expression (*a).
- The
code
field can be used optionally to place code, which is automatically included in the auto-generated header.
The code given to coemsIntrument
MAY NOT CONTAIN MACROS. Use clang -E <sourcefile>
to resolve all macros before executing coemsIntrument
.
The generated code is calling user callbacks e.g. cb_f1_call(arg0)
. Implement them!
Function overview
- Instrumentation of expression (vars, var-refs, var-derefs, array accesses, struct/union accesses) read/writes at any position
- Instrumentation of function calls (in calling code as well as in called code) with parameter values
- instrumentation after function calls return
- Instrumentation of function returns
- Instrumentation of variable reads
Obtaining coems-instrumentation
The COEMS instrumentation tool is available as stand-alone tool as well as part of the TeSSLa bundle, where instrumentations can be triggered automatically by annotations in the TeSSLa source.
To receive any of these tools in binary form feel free to contact us.
Contact
In case of any questions regarding the COEMS instrumentation tool please do not hesitate to contact the development team via info@tessla.io.