jit with external functions

I have an application that is generating llvm assembler text files, these
are then loaded with ParseAssemblyFile. I am also using
ExecutionEngine::runFunction
to call functions in the loaded/created modules.

Can I place references to external functions in the assembler files? For example
I if my application has a function called fred() I would like to place
calls to fred
in the assembler text file. Can I do that and have the external function call
resolve to the address of fred() in my application?

Thanks for any assistance.
-Ram

Yes, you can do this. The JIT will transparently call dlsym on the main process to resolve external function calls. This allows it to find standard lib functions like printf, it also allows your code to call into your own functions.

-Chris

Will it also handle symbols that are in shared libraries loaded into
the process?

I am creating a python module that has the llvm functionality. This
module is loaded
into the process as a shared library. I want to generate llvm assembler that has
calls to functions in this shared library.

I just tried an experiment and I got this back:

ERROR: Program used external function 'rtcg_callback' which could not
be resolved!
Aborted

It looks like the additional shared libraries might not be searched. I
plan on looking at
the code to see if I can modify it to handle my case. Any suggestions
on how or where
I should make the change?

Thanks for the info.
-Ram

Will it also handle symbols that are in shared libraries loaded into
the process?

I'm not sure, but I thought so.

I am creating a python module that has the llvm functionality. This
module is loaded
into the process as a shared library. I want to generate llvm assembler that has
calls to functions in this shared library.

I just tried an experiment and I got this back:

ERROR: Program used external function 'rtcg_callback' which could not
be resolved!
Aborted

Guess not :). Are you sure that rtcg_callback isn't marked static and isn't hidden by an export map?

It looks like the additional shared libraries might not be searched. I plan on looking at the code to see if I can modify it to handle my case. Any suggestions on how or where I should make the change?

see llvm/lib/ExecutionEngine/JIT/Intercept.cpp: JIT::getPointerToNamedFunction. It ends up calling:

   // If it's an external function, look it up in the process image...
   void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);
   if (Ptr) return Ptr;

It also prepends a _ to the symbol name and tries that. Alternatively, you can use the ExecutionEngine::addGlobalMapping to say that specific functions/globals are at specific addresses.

-Chris

Thanks for the info. I believe the problem is in how python is loading
its shared
libraries. I think if the libraries were loaded with RTLD_GLOBAL then the
symbols in the shared library would be available to other libraries. For now its
enough that I can register the symbols I need.

Thank you.
-Ram