Hi,<br><br>when I try to generate LLVM-IR which calls back to native C functions the jit compiler generates invalid code on 64-bit linux. The same code works fine on 32-bit linux, 32-bit OS X and 64-bit OS X. A reproduction case is attached to this mail. It is a simple modification of the "How to use jit" example adding a call to a native function.<br>
<br>I am currently using EE->addGlobalMapping to register the native functions. This appears to be nessecary because the native functions will be part of a .so/.dylib so the jit will not find them using dlsym on linux and we would prefer to stripp all symbols.<br>
<br>I'm using LLVM 2.4, which I compiled using EXTRA_OPTIONS="-m64/-m32 -fPIC".<br><br>Below you can see the code generated by the jit on different platforms. On 64-bit linux the 'call' instruction uses a completely wrong address. This invalid address appears to be related to the address of the call instruction itself (e.g. it is always a 'close' address). To my knowledge the call instruction's address argument is a relative address and thus needs to be within 2^24 bytes of the instruction. It looks like the code generator should generate a jump using a function pointer in this situation and fails to handle this.<br>
<br>Am I doing something wrong in my code or is this an LLVM bug?<br><br>Jan<br><br>Linux 64-bit:<br>(gdb) print addone_addr<br>$1 = (void *) 0x406018<br>(gdb) x/10i foo_addr<br>0x2b7184072030:    sub    $0x8,%rsp<br>0x2b7184072034:    mov    $0x14,%edi<br>
0x2b7184072039:    callq  0x2b7200406018 <--- absolutely not ok<br>0x2b718407203e:    add    $0x8,%rsp<br>0x2b7184072042:    retq   <br>(gdb) x/10i nfoo_addr<br>0x40603a <nativefoo>:    push   %rbp<br>0x40603b <nativefoo+1>:    mov    %rsp,%rbp<br>
0x40603e <nativefoo+4>:    mov    $0x1e,%edi<br>0x406043 <nativefoo+9>:    callq  0x406018 <addOne> <--- ok<br>0x406048 <nativefoo+14>:    leaveq<br>0x406049 <nativefoo+15>:    retq   <br>
<br>OS X 64-bit:<br>(gdb) print addone_addr<br>$1 = (void *) 0x100000d56<br>(gdb) x/10i foo_addr<br>x/10i foo_addr<br>0x102080030:    sub    $0x8,%rsp<br>0x102080034:    mov    $0x14,%edi<br>0x102080039:    callq  0x100000d56 <addOne> <--- ok<br>
0x10208003e:    add    $0x8,%rsp<br>0x102080042:    retq   <br>(gdb) x/10i nfoo_addr<br>x/10i nfoo_addr<br>0x100000d78 <nativefoo>:    push   %rbp<br>0x100000d79 <nativefoo+1>:    mov    %rsp,%rbp<br>0x100000d7c <nativefoo+4>:    mov    $0x1e,%edi<br>
0x100000d81 <nativefoo+9>:    callq  0x100000d56 <addOne> <--- ok<br>0x100000d86 <nativefoo+14>:    leaveq<br>0x100000d87 <nativefoo+15>:    retq   <br><br>Linux 32-bit:<br>(gdb) print addone_addr<br>
print addone_addr<br>$1 = (void *) 0x805aa74<br>(gdb) x/10i foo_addr<br>x/10i foo_addr<br>0xc26020:    sub    $0x4,%esp<br>0xc26023:    movl   $0x14,(%esp)<br>0xc2602a:    call   0x805aa74 <addOne> <--- ok<br>0xc2602f:    add    $0x4,%esp<br>
0xc26032:    ret    <br>(gdb) x/10i nfoo_addr<br>x/10i nfoo_addr<br>0x805aa8c <nativefoo>:    push   %ebp<br>0x805aa8d <nativefoo+1>:    mov    %esp,%ebp<br>0x805aa8f <nativefoo+3>:    push   $0x1e<br>0x805aa91 <nativefoo+5>:    call   0x805aa74 <addOne> <--- ok<br>
0x805aa96 <nativefoo+10>:    add    $0x4,%esp<br>0x805aa99 <nativefoo+13>:    leave  <br>0x805aa9a <nativefoo+14>:    ret    <br><br>OS X 32-bit:<br>(gdb) print addone_addr<br>print addone_addr<br>$1 = (void *) 0x1e62<br>
(gdb) x/10i foo_addr<br>x/10i foo_addr<br>0x2080020:    sub    $0xc,%esp<br>0x2080023:    movl   $0x14,(%esp)<br>0x208002a:    call   0x1e62 <addOne> <--- ok<br>0x208002f:    add    $0xc,%esp<br>0x2080032:    ret    <br>
(gdb) x/10i nfoo_addr<br>x/10i nfoo_addr<br>0x1e80 <nativefoo>:    push   %ebp<br>0x1e81 <nativefoo+1>:    mov    %esp,%ebp<br>0x1e83 <nativefoo+3>:    sub    $0x18,%esp<br>0x1e86 <nativefoo+6>:    movl   $0x1e,(%esp)<br>
0x1e8d <nativefoo+13>:    call   0x1e62 <addOne> <--- ok<br>0x1e92 <nativefoo+18>:    leave  <br>0x1e93 <nativefoo+19>:    ret<br><br><br>