llvm - fastest way of checking if function A is calling function B - llvm

I need to check if function A in my file is calling function B. My current approach is to go through all the instructions in function A and see if any of the call/invoke instructions are calling B. Can anyone suggest a better approach?

LLVM Provides easy to use method to traverse in-memory IR's use-def/def-use chain using Users/Uses.
You can traverse B's Uses and then check if its parent function is A or not.
for(Value::Use_iterator ui = B.Use_Begin(); ui != B.Use_end(); ++ui) {
if(instruction* call = dyn_cast<Instruction>(ui->getUser())) {
Function* caller = call->getParent()->getParent();
// check if caller is A or not
}
}
above code snippet may work with few modifications.
See: LLVM Use Ref for more info.

Related

Instrumented code causing infinite recursion loop

How can I prevent a suspected infinite loop in the following scenario?
The entire C++ codebase is instrumented by clang at build time, using an LLVM pass that searches for llvm.memcpy intrinsics and inserting a post-call to the instrumentation runtime
The instrumentation runtime contains a std::map structure
The underlying libc++ code that implements std::map has been instrumented, and in turn calls the instrumentation runtime again
When I run the program, it freezes once the first instrumentation call is made. The suspected loop is trace_memcpy > std::map::operator[] > trace_memcpy > and so forth
Is there a way to short-circuit this loop, e.g. can the instrumentation library inspect the call stack to see that it is already in the call the stack and return early from the trace_memcpy function?
Thanks :)
Quick & dirty & probably not bulletproof - add a static variable to the implementation of trace_memcpy to avoid nesting.
void trace_memcpy(void)
{
static int nested;
if (nested)
{
return;
}
nested = 1;
// whatever your actual trace logic is
nested = 0;
}
If you need something more sophisticated, use the appropriate concurrency object as provided by your system.

How to convert function insertion module pass to intrinsic to inline

PROBLEM:
I currently have a traditional module instrumentation pass that
inserts new function calls into a given IR according to some logic
(inserted functions are external from a small lib that is later linked
to given program). Running experiments, my overhead is from
the cost of executing a function call to the library function.
What I am trying to do:
I would like to inline these function bodies into the IR of
the given program to get rid of this bottleneck. I assume an intrinsic
would be a clean way of doing this, since an intrinsic function would
be expanded to its function body when being lowered to ASM (please
correct me if my understanding is incorrect here, this is my first
time working with intrinsics/LTO).
Current Status:
My original library call definition:
void register_my_mem(void *user_vaddr){
... C code ...
}
So far:
I have created a def in: llvm-project/llvm/include/llvm/IR/IntrinsicsX86.td
let TargetPrefix = "x86" in {
def int_x86_register_mem : GCCBuiltin<"__builtin_register_my_mem">,
Intrinsic<[], [llvm_anyint_ty], []>;
}
Added another def in:
otwm/llvm-project/clang/include/clang/Basic/BuiltinsX86.def
TARGET_BUILTIN(__builtin_register_my_mem, "vv*", "", "")
Added my library source (*.c, *.h) to the compiler-rt/lib/test_lib
and added to CMakeLists.txt
Replaced the function insertion with trying to insert the intrinsic
instead in: llvm/lib/Transforms/Instrumentation/myModulePass.cpp
WAS:
FunctionCallee sm_func =
curr_inst->getModule()->getOrInsertFunction("register_my_mem",
func_type);
ArrayRef<Value*> args = {
builder.CreatePointerCast(sm_arg_val, currType->getPointerTo())
};
builder.CreateCall(sm_func, args);
NEW:
Intrinsic::ID aREGISTER(Intrinsic::x86_register_my_mem);
Function *sm_func = Intrinsic::getDeclaration(currFunc->getParent(),
aREGISTER, func_type);
ArrayRef<Value*> args = {
builder.CreatePointerCast(sm_arg_val, currType->getPointerTo())
};
builder.CreateCall(sm_func, args);
Questions:
If my logic for inserting the intrinsic functions shouldnt be a
module pass, where do i put it?
Am I confusing LTO with intrinsics?
Do I put my library function definitions into the following files as mentioned in
http://lists.llvm.org/pipermail/llvm-dev/2017-June/114322.html as for example EmitRegisterMyMem()?
clang/lib/CodeGen/CodeGenFunction.cpp - define llvm::Instrinsic::ID
clang/lib/CodeGen/CodeGenFunction.h - declare llvm::Intrinsic::ID
My LLVM compiles, so it is semantically correct, but currently when
trying to insert this function call, LLVM segfaults saying "Not a valid type for function argument!"
I'm seeing multiple issues here.
Indeed, you're confusing LTO with intrinsics. Intrinsics are special "functions" that are either expanded into special instructions by a backend or lowered to library function calls. This is certainly not something you're going to achieve. You don't need an intrinsic at all, you'd just need to inline the function call in question: either by hands (from your module pass) or via LTO, indeed.
The particular error comes because you're declaring your intrinsic as receiving an integer argument (and this is how the declaration would look like), but:
asking the declaration of variadic intrinsic with invalid type (I'd assume your func_type is a non-integer type)
passing pointer argument
Hope this makes an issue clear.
See also: https://llvm.org/docs/LinkTimeOptimization.html
Thanks you for clearing up the issue #Anton Korobeynikov.
After reading your explanation, I also believe that I have to use LTO to accomplish what I am trying to do. I especially found this link very useful: https://llvm.org/docs/LinkTimeOptimization.html. It seems that I am now on a right path.

Get class annotation using gcc plugins

I am creating a gcc plugin that analyse a C++ file after parsing it.
The plugin walks through the classes and generate some information about them.
The plug-in is working, this is how I walk through classes.
cp_binding_level* level(NAMESPACE_LEVEL(nameSpace));
for (decl = level->names; decl != 0; decl = TREE_CHAIN(decl)) {
tree type(TREE_TYPE(decl));
tree_code dc(TREE_CODE(decl));
tree_code tc;
if (dc == TYPE_DECL&& tc == RECORD_TYPE &&
!DECL_IS_BUILTIN (decl) && DECL_ARTIFICIAL (decl)) {
//Now we know this is a class
//Do something
}
}
I would like to choose which class he can analyse and which one he can't.
My first idea is to add some sort of annotation, that I would read when I parse the class, and decide to analyze it or not.
I never used any sort of annotation in C++, so I don't know if this is possible. If so how would you recommend me to use them, and to get the annotation inside the plug-in ?
If it's not, is there a good way to do what I need ?
It can be done, it is not too hard, and it is a pretty common thing to do using a GCC plugin.
First you must register a new attribute. GCC provides the PLUGIN_ATTRIBUTES callback as a convenient time to do so. Your callback function can then call register_attribute to register attributes. This is documented in the manual, just one link away from the spot you linked to.
With this function you register another callback that is called when your attribute is applied. You'll have to read some GCC header files or source to really understand what this function should do. But, it can easily track whether it is being applied to a class and, if so, make a note of this for later processing.

Running Function Inside Stub. Passing Function Pointer

I'm working on creating a user-level thread library and what I want to do is run a function inside a stub and so I would like to pass the function pointer to the stub function.
Here is my stub function:
void _ut_function_stub(void (*f)(void), int id)
{
(*f)();
DeleteThread(id);
}
This is what the user calls. What I want to do is get pointer of _ut_function_stub to assign to pc and I've tried various different options including casting but the compiler keeps saying "invalid use of void expression".
int CreateThread (void (*f) (void), int weight)
{
... more code
pc = (address_t)(_ut_function_stub(f, tcb->id));
... more code
}
Any help is appreciated. Thanks!
If you're interested in implementing your own user-level-threads library, I'd suggest looking into the (now deprecated) ucontext implementation. Specifically, looking at the definitions for the structs used in ucontext.h will help you see all the stuff you actually need to capture to get a valid snapshot of the thread state.
What you're really trying to capture with the erroneous (address_t) cast in your example is the current continuation. Unfortunately, C doesn't support first-class continuations, so you're going to be stuck doing something much more low-level, like swapping stacks and dumping registers (hence why I pointed you to ucontext as a reference—it's going to be kind of complicated if you really want to get this right).

How to invoke an Objective-C Block via the LLVM C++ API?

Say, for example, I have an Objective-C compiled Module that contains something like the following:
typedef bool (^BoolBlock)(void);
BoolBlock returnABlock(void)
{
return Block_copy(^bool(void){
printf("Block executing.\n");
return YES;
});
}
...then, using the LLVM C++ API, I load that Module and create a CallInst to call the returnABlock() function:
Function *returnABlockFunction = returnABlockModule->getFunction(std::string("returnABlock"));
CallInst *returnABlockCall = CallInst::Create(returnABlockFunction, "returnABlockCall", entryBlock);
How can I then invoke the Block returned via the returnABlockCall object?
Not an easy answer here, I'm afraid. Blocks are lowered by the front-end into calls into the blocks runtime. In the case of clang, the relevant code is at clang/lib/CodeGen/CGBlocks.[h|cpp].
It would be worth asking on the cfe-dev list if there's a way to factor this code out for reuse in other front-ends.
In C, I just act as if the var I assigned the block to was a function pointer. Using your code as an example, after you assign the result of the function to "returnABlockCall", you could just write:
returnABlockCall();
and it should work.
Warning, this is untested in C++, but I see no reason why it wouldn't work.