I am writing my first LLVM sample. I am trying to build a small LLVM module consisting of a function which takes in a name of a function and returns a pointer to it. The problem is I don't know how to generate function pointers in LLVM. I have got a Function object by calling getDeclaration(...). Is there some way I can get a pointer to it?
Function is a GlobalValue, so it is the pointer by itself. In the meantime, you can use LLVM's C++ backend to generate the C++ API calls which will recreate the IR you're feeding to llc.
For example, feed the following code into http://llvm.org/demo:
void foo(int (*bar)(int));
int factorial(int X);
int main(int argc, char **argv) {
foo(factorial);
}
Make sure you have the "Show LLVM C++ API code" checkbox selected and you'll see the corresponding LLVM IR and the C++ API calls which will recreate it.
Related
For my programming language, the entry of a program is like C/C++ main function:
int main(int argc, char **argv) {
return 0
}
Suppose:
The IR code for main is generated into llvm::Function, using llvm::IRBuilder
I have llvm::LLVMContext and llvm::Module created
Question:
If I want to compile this code into binary prog, how do use llvm to generate the part that passes the commandline arguments to argc and argv and then call main, which are provided by users when running prog?
Thanks to arnt's comment:
If that function actually is called main() and actually has those arguments, then it should just work. If it isn't, then you'll need to generate a bridge function that actually is called main() and calls the function you want to be called, in the way you want it to be called. – arnt
It works!
I am a bit confused about implementing a code injection function in LLVM Clang. I basically want to add a function before a variable or a pointer is created in the source code. Example:
#include <iostream>
int main() {
int a;
return 0;
}
to
#include <iostream>
int main() {
foo();
int a;
return 0;
}
I read the LLVM docs to find an answer but couldn't. Please help me.
Thank you in advance.
First step is to decide whether you want to do this in Clang or LLVM. Although they are "connected", they are not the same thing. At clang you can do it at AST level, in which case you need to write a recursive AST-visitor, and from that identify the function definitions that you want to instrument - inserting the AST to call your foo function. This will only work for functions implemented by the compiler.
There is information on how to write such a visitor here:
https://clang.llvm.org/docs/RAVFrontendAction.html
In LLVM you could write a function-pass, that inserts code into each function. This obviously works for ANY functions, regardless of language.
How to write an LLVM pass:
http://llvm.org/docs/WritingAnLLVMPass.html
However, while this may seem trivial at the beginning, there are some interesting quirks. In an LLVM function, the alloca instructions should be first, so you would have to "skip" those functions. There may be functions that "shouldbn't be instrumented" - for example, if your function foo prints something using cout << something;, it would be rather terrible idea to insert foo into the operator<<(ostream&, ...) type functions... ;) And you obviously don't want to instrument foo itself, or any functions it calls.
There are ways in Clang that you can determine if the source is the "main file" or some header-file - although that may not be enough in your case. It is much harder to determine "which function is this" in LLVM.
I'm trying to run a c++ script from IDL using the CALL_EXTERNAL function. I've been able to get it to work without arguments, but when I try to add an arg, such as a single IDL LONG INT, IDL crashes. with the error:
% CALL_EXTERNAL: Error loading sharable executable.
Symbol: main, File = /home/inspired/workspace/TestCode/main.
so
/home/inspired/workspace/TestCode/main.so: wrong ELF class:
ELFCLASS64
% Execution halted at: TEST_EXTERNAL 7
/home/inspired/IDLWorkspace/Analyze Data/test_external.pro
% $MAIN$
The test code I'm using is as follows.
The C++ code:
#include <iostream>
int main(int argc, char *argv[]) {
int temp = (int) strtod(argv[1], NULL);
std:cout<<temp;
return temp;
}
The IDL code:
pro test_external
c= call_external('/home/inspired/workspace/TestCode/main.so','main', long(2), /AUTO_GLUE)
print,c
end
This code is of course practice code, but if I can't get this to work, then there's no way I'll be able to pass a mixture of arrays, and values.
I am aware that IDL passes everything by reference unless stated otherwise. So I've tried both treating the passed argument as a pointer in the C++ code, and setting the /ALL_VALUE keyword to pass the arg as a value. Neither works resulting in the same error as above. I've read about "glue functions" but I have not been able to find a guide to making them (despite every source indicating that it's 'easy for most programmers'" >.>
Anyway, my options are as follows, and if you can help me with any, I'd be eternally grateful:
Get this CALL_EXTERNAL function to work
Have the C code grab the data it needs from memory somehow
Rewrite everything in C++ (you don't need to help with this one)
Thanks in advance.
I think you are trying to mix 32-bit and 64-bit code. It looks like you are compiling your code as 64-bit, but you are running 32-bit IDL. To check this, IDL prints it when it launches or you can check manually:
IDL> print, !version.memory_bits
64
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.
In some of the LLVM tutorials I'm seen where it's fairly easy to bind C function into a custom language based on LLVM. LLVM hands the programmer a pointer to the function that can be then be mixed in with the code being generated by LLVM.
What's the best method to do this with C++ libraries. Let's say I have a fairly complex library like Qt or Boost that I want to bind to my custom language. Do I need to create a stub library (like Python or Lua require), or does LLVM offer some sort of foreign function interface (FFI)?
In my LLVM code, I create extern "C" wrapper functions for this, and insert LLVM function declarations into the module in order to call them. Then, a good way to make LLVM know about the functions is not to let it use dlopen and search for the function name in the executing binary (this is a pain in the ass, since the function names need to be in the .dynsym section, and it is slow too), but to do the mapping manually, using ExecutionEngine::addGlobalMapping.
Just get the llvm::Function* of that declaration and the address of the function as given in C++ by &functionname converted to void* and pass these two things along to LLVM. The JIT executing your stuff will then know where to find the function.
For example, if you wanted to wrap QString you could create several functions that create, destroy and call functions of such an object
extern "C" void createQString(void *p, char const*v) {
new (p) QString(v); // placement-new
}
extern "C" int32_t countQString(void *p) {
QString *q = static_cast<QString*>(p);
return q->count();
}
extern "C" void destroyQString(void *p) {
QString *q = static_cast<QString*>(p);
q->~QString();
}
And create proper declarations and a mapping. Then you can call these functions, passing along a memory region suitably aligned and sized for QString (possibly alloca'ed) and a i8* pointing to the C string data for initialization.
If you compile some code in C++ and some in another language to LLVM bitcode, it should be perfectly possible to link these together and let one call the other... in theory.
In practice, you will need glue code to convert between the different language's types (e.g. there is no equivalent to a Python string in C++ unless you use CPython, so for void reverse(std::string s) to be callable with a str you need a conversion - worse, the whole object model is very different). And Qt specifically has a lot of magic that may require much more effort to expose after compilations. Also, there may be further potential problems I'm not aware of.
And even if that works, it's potentially very ugly to use. There are still get* and set* functions all over PyQt despite Python's very convenient descriptors - and much effort went into PyQt, they didn't just create some stubs.