I tried running nm - D | grep "puts" on the binary compiled by the
OCaml
compiler. It outputs the following:
08161b00 T camlRuntime__rt_fputs_208
08161a20 T camlRuntime__rt_puts_198
U fputs
I'm assuming this means that fputs is linked dynamically, and puts is
not. I tried modifying my code to use fputs instead of puts instead, but
had no success, however, I still get:
LLVM ERROR: Tried to execute an unknown external function: i32 (i8*,
i32)* fputs
There has to be some way of telling LLVM to get some symbols
dynamically. What's rather frustrating is that the OCaml LLVM tutorial
seems to be doing exactly what I want:
http://llvm.org/docs/tutorial/OCamlLangImpl4.html
They define some "extern" functions by using "declare
function", which
are then linked dynamically by the JIT. Unfortunately, this is already
what I'm doing, and I can't seem to spot what they are doing
differently!
- Maxime
Jeffrey Yasskin wrote:> In C, on Linux, you would have to link your JIT compiler with
> -rdynamic or -Wl,-export-dynamic (they're synonyms). I'm not sure
what
> the equivalent linker flag is for OCaml.
>
> You can see what symbols are available to the JIT with `nm -D`.
>
> On Sun, Apr 4, 2010 at 8:41 AM, Nyx <mcheva at cs.mcgill.ca> wrote:
>
>> I'm coding a JIT compiler for C source in OCaml, using LLVM.
I'm pretty much
>> done with the LLVM code generation. The problem is that I can't
seem to call
>> C library functions. I was told that all I needed to do to be able to
link
>> with libc functions was to declare them in my module and give them
external
>> linkage, but this does not seem to work. Please note that this is a JIT
>> compiler. I am not generating a binary, but running the code generated
in
>> memory. It should be possible to dynamically link with the libc
functions
>> because the ocaml executable is linked with them.
>>
>> The three libc functions I declared appear in my module dump as such:
>> declare i8* @malloc(i32)
>> declare void @free(i8*)
>> declare i32 @puts(i8*)
>>
>> However, when trying to run my program, I get the following:
>> LLVM ERROR: Tried to execute an unknown external function: i32 (i8*)*
puts
>>
>> I'm not quite sure how to go about this. Any help would be
appreciated.
>>
>> - Maxime
>>
On Sun, Apr 4, 2010 at 5:24 PM, Maxime Chevalier-Boisvert <mcheva at cs.mcgill.ca> wrote:> I tried running nm - D | grep "puts" on the binary compiled by the OCaml > compiler. It outputs the following: > > 08161b00 T camlRuntime__rt_fputs_208 > 08161a20 T camlRuntime__rt_puts_198 > U fputs > > I'm assuming this means that fputs is linked dynamically, and puts is not.Don't assume; ask `man nm`. http://www.linuxcommand.org/man_pages/nm1.html says that a 'U' in that column means "The symbol is undefined." (It's there so the dynamic loader knows to pull it out of a .so, I think.) You need to figure out how to pass -rdynamic to the linker, like I said before. http://llvm.org/docs/tutorial/OCamlLangImpl7.html mentions it, but I don't know enough about the ocaml build process to say whether that'll work.> I > tried modifying my code to use fputs instead of puts instead, but had no > success, however, I still get: > > LLVM ERROR: Tried to execute an unknown external function: i32 (i8*, i32)* > fputs > > There has to be some way of telling LLVM to get some symbols dynamically. > What's rather frustrating is that the OCaml LLVM tutorial seems to be doing > exactly what I want: > > http://llvm.org/docs/tutorial/OCamlLangImpl4.html > > They define some "extern" functions by using "declare function", which are > then linked dynamically by the JIT. Unfortunately, this is already what I'm > doing, and I can't seem to spot what they are doing differently! > > - Maxime > > Jeffrey Yasskin wrote: >> >> In C, on Linux, you would have to link your JIT compiler with >> -rdynamic or -Wl,-export-dynamic (they're synonyms). I'm not sure what >> the equivalent linker flag is for OCaml. >> >> You can see what symbols are available to the JIT with `nm -D`. >> >> On Sun, Apr 4, 2010 at 8:41 AM, Nyx <mcheva at cs.mcgill.ca> wrote: >> >>> >>> I'm coding a JIT compiler for C source in OCaml, using LLVM. I'm pretty >>> much >>> done with the LLVM code generation. The problem is that I can't seem to >>> call >>> C library functions. I was told that all I needed to do to be able to >>> link >>> with libc functions was to declare them in my module and give them >>> external >>> linkage, but this does not seem to work. Please note that this is a JIT >>> compiler. I am not generating a binary, but running the code generated in >>> memory. It should be possible to dynamically link with the libc functions >>> because the ocaml executable is linked with them. >>> >>> The three libc functions I declared appear in my module dump as such: >>> declare i8* @malloc(i32) >>> declare void @free(i8*) >>> declare i32 @puts(i8*) >>> >>> However, when trying to run my program, I get the following: >>> LLVM ERROR: Tried to execute an unknown external function: i32 (i8*)* >>> puts >>> >>> I'm not quite sure how to go about this. Any help would be appreciated. >>> >>> - Maxime >>> > >
>> You need to figure out how to pass -rdynamic to the linker, like Isaid before. http://llvm.org/docs/tutorial/OCamlLangImpl7.html mentions it, but I don't know enough about the ocaml build process to say whether that'll work. I believe I'm already doing that, properly by passing -ccopt -rdynamic to ocamlopt: ocamlopt -cc g++ -ccopt -rdynamic -linkall $(LIBFILES) -o alpha $(OBJFILES) I've also tried writing a dummy "puts" function in a C file and linking that with my executable. nm -D then shows the following: 000000000054b690 T camlRuntime__rt_fputs_208 000000000054b590 T camlRuntime__rt_puts_198 U fputs 0000000000c43044 T puts However, LLVM *still* gives me: LLVM ERROR: Tried to execute an unknown external function: i32 (i8*)* puts Something really wrong is happening. The following thread seems to indicate that this should all work easily: http://old.nabble.com/jit-with-external-functions-td7769793.html -- View this message in context: http://old.nabble.com/Linking-with-C-Library-tp28133460p28145523.html Sent from the LLVM - Dev mailing list archive at Nabble.com.