zoecarver
zoecarver

Reputation: 6433

How to implement implicit extern c - LLVM

I am trying to build a way to use extern C++ functions in my LLVM code - for example:

extern "C" DLLEXPORT double printd(double X) {
  fprintf(stderr, "%f\n", X);
  return 0;
}

I would like to be able to call printd in my LLVM IR code.

I know that I have to implement a JIT to get this working, but I am not exactly sure what elements of a JIT enable calling functions from C++ code or how to link that code to my IR code.


Edit

IR Code (out.ll)
declare double @printd(double)

define double @__anon_expr() {
entry:
  %calltmp = call double @printd(double 1.000000e+01)
  ret double %calltmp
}
define i32 @main() {
call double @__anon_expr()
ret i32 0
}

I generate the above code using C++:

IR->print(llvm::errs());

Finally I run it using:

$ lli out.ll

And I get this error:

LLVM ERROR: Program used external function '_printd' which could not be resolved!

Edit 2

When I run clang out.ll -lmylib -o a.out

warning: overriding the module target triple with x86_64-apple-macosx10.12.0 [-Woverride-module]
1 warning generated.
ld: library not found for -lmylib
clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)

Edit 3

$ clang out

Undefined symbols for architecture x86_64:
  "_printd", referenced from:
      ___anon_expr in out
ld: symbol(s) not found for architecture x86_64
clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)

$ lli out

lli: out:1:1: error: expected top-level entity
���� �� �__text__TEXT ��__literal8__TEXT@__compact_unwind__LD(@H�__eh_frame__TEXThX�
                                                                                    h$

Upvotes: 0

Views: 1716

Answers (1)

sepp2k
sepp2k

Reputation: 370455

C++ functions that are declared as extern "C" can be called just like regular C functions (that's what extern "C" does), so all you need to is a declaration and then a regular call instruction. So that'd be:

; At the top-level:
declare double @printd(double)

; Somewhere inside the definition of a function that calls printd:
%42 = call double @printd(double %23)

Then all you need is to link against your library when creating the final executable.

I know that I have to implement a JIT to get this working

Calling external functions works perfectly well in AOT-compiled code. You don't need to JIT-compile in order to call external functions.

Upvotes: 2

Related Questions