I suspect that this will end up linker related, but looking for any suggestions.
Have a simple C++ code that loads an llvm IR file as a module, compiles it and executes a function from that module. IR module conversely declares a C function from the main executable as an external, and calls that one.
This works fine on MacOS (llvm 12).
On FreeBSD the code crashes when IR function is invoked.
If I move the C function into a shared library, and link with it - IR code is able to run and invoke the function from back in the main program.
I suspect that something about FreeBSD runtime linker makes function in the program itself unavailable to the IR code. Any suggestions on how to remedy that appreciated.
Sample C++ code (skipped includes):
extern "C" {
int test_fun(int arg)
{
printf("Super test fun %d\n", arg);
return arg + 1;
}
}
int main(int ac, char **av)
{
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
llvm::LLVMContext ctx;
llvm::SMDiagnostic diag;
auto M = parseIRFile( av[1], diag, ctx );
printf("Module %llx\n", (uint64_t)M.get());
std::string err;
llvm::EngineBuilder EB(std::move(M));
EB.setEngineKind(llvm::EngineKind::JIT).setErrorStr(&err);
llvm::ExecutionEngine* EE = EB.create();
if (!EE) return 0;
EE->finalizeObject();
const auto fa = (int(*)())EE->getFunctionAddress(av[2]);
printf("IR fun '%s' returned %d\n", av[2], fa());
return 0;
}
Sample IR code:
declare i32 @test_fun(i32)
define i32 @test_ll() {
%v1 = mul i32 4, 5
%v2 = add i32 3, %v1
%v3 = call i32(i32) @test_fun(i32 %v2)
ret i32 %v3
}