Linking LLVM JIT code to external C++ functions - linker

I'm writing a LLVM scripting engine that JIT compiles scripting code in a custom language. My problem is that I'm unable to call external functions (even the C99 erf() function is failing).
For example if I extern "C" the erf function,
extern "C" double erft(double x){
return erf(x);
}
and create a function with external linkage
std::vector<const Type*> Double1(1,Type::getDoubleTy(getGlobalContext()));
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),Double1,false);
Function *erft = Function::Create(FT,Function::ExternalLinkage,"erft",TheModule);
get the following error message when running my script with erft(0.0) :
LLVM ERROR: Program used external function 'erft' which could not be resolved!
Doing the mapping manually,
void ExecutionEngine::addGlobalMapping( const GlobalValue * erfF, void * erft);
will get me the following error:
declaration of `void llvm::ExecutionEngine::addGlobalMapping(const llvm::GlobalValue*, void*)' outside of class is not definition
Obviously I'm doing something very wrong. Any help would be much appreciated

Assuming you haven't disabled it (by calling EE->DisableSymbolSearching()) then LLVM will use dlsym() to find the symbols in the JIT program itself. Depending on your platform, that might mean that you need to build your JIT with -fPIC, or that it might not be available at all (such as on Windows).
Aside from automatic symbol searching, you can always register the individual functions yourself using EE->addGlobalMapping(GV, &function) where GV = the llvm::Function* function declaration that matches the native function you're calling. In your case with ertf() that's:
EE->addGlobalMapping(erft, &::erft);
Note that you named the global function erft() and the local variable erft, hence the "::". Please pick different names next time!

This might be happening because you forgot to add the "libm" depedency, try using:
[your module]->addLibrary("m");
See here for more information about the Module::addLibrary().

I don't know llvm, but this make no sense:
void ExecutionEngine::addGlobalMapping( const GlobalValue * erfF, void * erft);
That defines a new function in C++. What you need to do is somehow register your function with LLVM. Defining that function is like trying to add new methods to the LLVM classes, not what you want to do.

Related

override/redefine a C-Function which has a section attribute

I have the case where I need to overwrite some C-Functions of an SDK we use. The SDK is compiled as a lib and the functions we need to override are marked with
__attribute__((weak))
This works as it should when linking.
We override those functions then later in our files with the wanted definition.
Background:
The reason is that the SDK is not working in a standalone way but always needs a special tool which generates some global objects which are needed in the init-functions of the SDK. And we wanted to get rid of the tool and thus need new init-functions which do not rely on the global objects but on passing the configuration via pointer. Those functions are added additionally and no SDK-functions are removed.
Also the SDK shall not be altered in a way you can't use it anymore with the tool. So it must support both features, with the smallest changes possible which will not break the API and add support for the new API by us without the tool.
So following up, if we now have a function which has already an attribute defined, which references to a section like
void __attribute__((section(".text.random"))) Random_init(){}
it is not possible to override Random_init.
I do not get errors like it was redefined or anything but undefined symbols while linking which refer to those global objects, which of course are not generated anymore and are only used by the function which shall be overriden. And this works for all other 20 init-functions only for this one it does not and the only difference is the attribute already there.
I tried adding it together:
void __attribute__((weak, section(".text.random"))) Random_init()
which also does not work.
I also tried to add the attribute to the redefinition, but this also does not help.
We cannot just erase the section-attribute since it needs to be there for all the entities using the tool.
The compiler we use is a clang based TI LTS1.3.1-compiler.
I would like to provide a minimal example but since this combination only works with the sdk-code beeing compiled to a lib first, I just cannot.
I just try to show it:
SDK-function which is compiled inside the lib, c-file "Random.c":
extern RandConfig gRandConfig[];
extern int32_t gRandConfigNum;
void __attribute__((weak, section(".text.random"))) Random_init()
{
uint32_t i;
for (i = 0; i < gRandConfigNum; i++)
{
Random_setSpecial(i,
(void*)gRandConfig[i].baseAddr,
gRandConfig[i].size,
&gRandConfig[i].attrs
);
}
}
related Header-file, Random.h:
void Random_init();
The gRandConfig and gRandSpecialConfig are produced in code by the tool, which are then linked against the library and we don't want to use them anymore.
All the context where this shall happen is in C but the libs are used from C++-context.
So for example this is how the override would look like in our .cpp-files:
#include "Random.h"
extern "C"
{
void Random_init()
{
}
}
The result when linking:
undefined first referenced
symbol in file
--------- ----------------
gRandConfig ../../../../sdk-build/sdk.lib<Random.obj>
gRandConfigNum ../../../../sdk-build/sdk.lib<Random.obj>
The included header by the sdk also has guards for __cplusplus. So it shouldn't be a language issue.
Also we issued the compiler to compile with -ffunction-sections which shall at least help to sort unneeded functions out later on. But anyway it does not. Even when the function gets never called by anyone.
A dirty solution would be to just add dummy-variables for this one, so it's satisfied and does not complain but as you can imagine, that would be a workaround which produces a lot of problems later on and also takes space where we need every Byte of space.
Could it be that an section-function-attribute prevents the function from being overriden? I did not find anything at the gnu-documantation which says that one cannot override a function with an attribute.

Alias for a C function in IAR

I need a symbol alias to be the alias for the function function as described in this question, but for IAR compiler/linker. I have tried answers for GCC, but those don't work, obviously:
// source code
void alias(void) __attribute__ ((alias ("function")));
Error[Pe130]: expected a "{" C:\project\test.c 61
void alias(void) asm("function");
Error[Pe065]: expected a ";" C:\project\test.c 61
#pragma weak alias=function
Error[e46]: Undefined external "alias" referred in ?ABS_ENTRY_MOD ( )
// linker options:
-Dalias=function
Fatal Error[e163]: The command line symbol "function" in -Dalias=function is not defined.
Does anyone know how I can define a function alias in IAR/Xlink?
A little background: I'm responsible for a module which is used in several projects. In order to test it, I have developed test cases for testIDEA tool which validate assertions at certain breakpoints. However, some common functions have different names in different projects (e.g. the initialization function could be called init(), init_mcu(), startup() etc.) so every time my module is integrated in a new project, I have to modify my test cases to match the new function names. What I'd like to do instead is to define a common alias (e.g. test_init()) to whatever the init function is called, so that my test cases can always set a breakpoint using this common name. I expect this symbol to make it to the ELF file, where it can be seen by the debugger.
From the IAR C/C++ Development Guide (p. 258):
To make the definition of foo a weak definition, write:
#pragma weak foo
To make NMI_Handler a weak alias for Default_Handler, write:
#pragma weak NMI_Handler=Default_Handler
If NMI_Handler is not defined elsewhere in the program, all references to NMI_Handler will refer to Default_Handler.
So, try something like this:
void f1(void);
void f2(void);
#pragma weak f1=f2
void f2(void) {}
After a close look at xlink options I've found the one which sort of suits my needs:
-e -enew=old [,old] …
Use -e to configure a program at link time by redirecting a function call from one function to another.
This can also be used for creating stub functions; i.e. when a system is not yet complete, undefined function calls can be directed to a dummy routine until the real function has been written.
I ended up with this code:
void alias(void) {
// copy the body of function()
}
// Linker parameters
-ealias=function
This redirects all calls to function() to alias(), regardless the actual name function has. Sure it's an ugly hack because I have to copy the code, but I get what I wanted: I can set a breakpoint to alias() by name.

Is there a way in C to have the compiler/linker give an error if a function is not defined?

In my case I am writing a simple plugin system in C using dlfcn.h (linux). The plugins are compiled separately from the main program and result in a bunch of .so files.
There are certain functions that must be defined in the plugin in order for the the plugin to be called properly by the main program. Ideally I would like each plugin to have included in it a .h file or something that somehow states what functions a valid plugin must have, if these functions are not defined in the plugin I would like the plugin to fail compilation.
I don't think you can enforce that a function be defined at compile time. However, if you use gcc toolchain, you can use the --undefined flag when linking to enforce that a symbol be defined.
ld --undefined foo
will treat foo as though it is an undefined symbol that must be defined for the linker to succeed.
You cannot do that.
It's common practice, to only define two exported functions in a library opened by dlopen(), one to import functions in your plugin and one to export functions of your plugin.
A few lines of code are better than any explanation:
struct plugin_import {
void (*draw)(float);
void (*update)(float);
};
struct plugin_export {
int (*get_version)(void);
void (*set_version)(int);
};
extern void import(struct plugin_import *);
extern void export(struct plugin_export *);
int setup(void)
{
struct plugin_export out = {0};
struct plugin_import in;
/* give the plugin our function pointers */
in.draw = &draw, in.update = &update;
import(&in);
/* get our functions out of the plugin */
export(&out);
/* verify that all functions are defined */
if (out.get_version == NULL || out.set_version == NULL)
return 1;
return 0;
}
This is very similar to the system Quake 2 used. You can look at the source here.
With the only difference, Quake 2 only exported a single function, which im- and exports the functions defined by the dynamic library at once.
Well after doing some research and asking a few people that I know of on IRC I have found the following solution:
Since I am using gcc I am able to use a linker script.
linker.script:
ASSERT(DEFINED(funcA), "must define funcA" ) ;
ASSERT(DEFINED(funcB), "must define funcB" ) ;
If either of those functions are not defined, then a custom error message will be output when the program tries to link.
(more info on linker script syntax can be found here: http://www.math.utah.edu/docs/info/ld_3.html)
When compiling simply add the linker script file after the source file:
gcc -o test main.c linker.script
Another possibility:
Something that I didn't think of (seems a bit obvious now) that was brought to my attention is you can create small program that loads your plugin and checks to see that you have valid function pointers to all of the functions that you want your plugin to have. Then incorporate this into your build system, be it a makefile or a script or whatever. This has the benefit that you are no longer limited to using a particular compiler to make this work. As well as you can do some more sophisticated checks for other other things. The only downside being you have a little more work to do to get it set up.

having the same function in multiple c source files

I'm having a hard time finding out why i can't have the same function in several C source files.
I always thought that i can't access functions in another source file as long as they ain't declared in a header file.
Lets assume i have the following:
main.c -> includes thread1.h & thread2.h
thread1.h -> declares e.g. void * thread1();
thread1.c -> defines void * thread1(){} and defines void lock(){}
thread2.h -> declares e.g. void * thread2();
thread2.c -> defines void * thread2(){} and defines void lock(){}
Now gcc tells me i can't do that!
gcc -pthread -Wall -o executable main.c thread1.c thread2.c
ERROR: multiple definition of `lock'
So my question now is:
How can I accomplish what i want?
I don't think that this is meant to be impossible. Otherwise all that C source code available within all the many C libraries would need to be unique. (nah would make no sense, or would it?)
So i thought to myself about 3h ago that there must be a solution. That i must be missing something here.
Well I tried googling it ... but somehow my google skills didn't help me this time.
Is there really no way of doing this? Or am I just to stupid to search for it?
Thanks in advance,
leep
You'll need that function lock() to be static.
static void lock() {..}
The reason is that functions with static are not visible outside of the "translation unit". In other (probably wrong) words, the static functions are private to the *.c file. Hence they dont cause linking errors in the linking stage, as you are currently having.
You must declare lock as static void lock(){}.
Otherwise the function name will be visible all over the program and you'll get a name collision (although you still won't be able to call it without a function prototype).

Use a C struct in C++/CLI, calling conventions issue

I'm using lib_usb in my C++/CLI project, and I need to use it's functions usb_get_busses and some others in my managed C++/CLI code.
Using a managed AutoPtr to create the usb_bus struct as follows:
AutoPtr<struct usb_bus> bus;
now I need to call the usb_get_busses function, however the linker seems to be unhappy as to the calling conventions. The CLR uses the clrcall calling convention, and obviously C using __cdecl.
usb_bus* usb_get_busses(void) <--- the signature of the C function.
Now how do I make myself able to use the lib_usb in C++/CLI? Do I have to create a C++/CLI wrapper or something?
The linker spits out this message:
error LNK2031: unable to generate p/invoke for "extern "C" struct
usb_bus * __clrcall usb_get_busses(void)"
(?usb_get_busses##$$J0YMPAUusb_bus##XZ); calling convention missing in
metadata
That's not specified with __cdecl at all. Look at the linker error- it clearly states __clrcall. Try explicitly specifying it with __cdecl.

Resources