[llvm] To link or not to link


I have migrated an LLVM front-end from LLVM 3.5 to 3.8 and now to 3.9 and ORC, and there is a concept which I could not transfer. Consider:

extern "C" { void somefunc() {} }

auto llvmfunc = llvm::Function::Create(type, llvmFunction::PrivateLinkage, "bla", module));
executionengine.addGlobalMapping(llvmfunc, &somefunc);
// now I have llvmfunc to work with and don't need to consider anything else

The GlobalMappingLayer class seems to provide the functionality I want. I oriented myself on the example from cayman/llvm_orc_initial.cpp at aaa809c3758eed3fad5ef213a18e1a8575e3121f · AndySomogyi/cayman · GitHub (just oriented, because at least on 3.9, I can not stack the GlobalMappingLayer on the ObjectLinkingLayer. I have to put it onto the IRCompileLayer. One question I'd have: How does that order matter?)

The problem I have with that conceptually is: The name seems to matter. The abstraction I'd like is that I get an llvm::Function*, and that is mapped to &somefunc, the name "bla" I gave it should be irrelevant. (And that's what I'd like that to be like for all functions and function calls and whatnot: The name I give them is irrelevant, only the llvm::Function*/llvm::Value* matters.) Am I using the wrong API and there is a way to do this without the names, without any symbol resolution at all? (I don't want to use symbols from the current executable or anywhere else, either.)

The problem I have with that implementationally: It just doesn't work. I get a LLVM ERROR: Undefined temporary symbol from the ELFObjectWriter (and the error is actually about that symbol I'm trying to map), none of the llvm assertions fail. I compiled a minimal example of what I'm doing and attached it. The curious part is that the lambda resolver does not even get invoked… Can anybody tell me what I am doing wrong?

Thank you

PS: Related thread: http://lists.llvm.org/pipermail/llvm-dev/2015-August/thread.html#89230

The whole thing I'm building is supposed to be a script engine for a game. As the scripts aren't supposed to have any access outside the game, I'd like as little linking magic as possible.
It's still in early stages. https://git.openclonk.org/jcaesar/experimental.git/blob/7be141ce667f4689428943592bae0a7568134213:/src/script/C4AulCompiler.cpp

mex.cpp (5.7 KB)

CMakeLists.txt (764 Bytes)

Hi Julius, I had similar questions a while ago. First of all: the GlobalMappingLayer is used for explicit mappings from strings to function pointers, so that your generated code can access these functions. It doesn’t do much more.

I didn’t inspect your attached example, but I think you can look at one of my examples to find out how I wire it up. Maybe that helps:
Just query the name of your llvm::Function and pass it also to the GlobalMappingLayer (if you want to use it). I think the ExecutionEngine just did the query and pass on implicitly. Query your mapping during symbol resolution like this: If you want your generated code to have implicit access to functions in your binary, then have a look at these two lines:

Hi Stefan,

Okay, thanks to having your code as a working example, I figured out how to fix my problem. The reason was simply that my symbol name began with a ".".

I think the ExecutionEngine just did the query and pass on implicitly.

If it did, it did something to get around this… some day, I'll look into what that was. For now, I'll just use different names.

If you want your generated code to have implicit access to functions in
your binary, then have a look at these two lines:

I precisely do not want that to happen. Anything implicit stinks of magic I have no control over, especially across 5 compilers on three platforms.


PS: Your example doesn't compile with gcc-5.4 (because of the DataLayout DataLayout-declaration), and the assertion that the mangled symbol name starts with an underscore does not hold, at least not on my system.