llvm2cranelift
llvm2cranelift copied to clipboard
What is the correct reloc for function imports?
I'm a complete novice when it comes to relocations.
Working with test.ll
:
define void @foo(i32 %arg, i32 %arg1) {
bb:
%tmp = icmp ult i32 %arg, 4
%tmp2 = icmp eq i32 %arg1, 0
%tmp3 = or i1 %tmp2, %tmp
br i1 %tmp3, label %bb4, label %bb6
bb4:
%tmp5 = call i32 @bar()
ret void
bb6:
ret void
}
declare i32 @bar()
I get the following relocation type:
Relocation section '.reloc.foo' at offset 0x15b contains 1 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000030 000400000002 R_X86_64_PC32 0000000000000000 bar + 0
When I compile an equivalent(ish) test.c
with clang:
extern int bar();
void foo(int arg, int arg1) {
if (arg < 4 || arg1 == 0) {
bar();
}
}
I get the following relocation type:
Relocation section '.rela.text' at offset 0x128 contains 1 entries:
Offset Info Type Sym. Value Sym. Name + Addend
00000000000d 000300000004 R_X86_64_PLT32 0000000000000000 bar - 4
The correct relocation depends on how the code will be used. If the code is going to be included in a shared library, it's desirable to avoid patching the code at startup time, so it wants the PLT32 relocation, which creates a procedure-linkage-table (PLT) entry, which is a level of indirection that allows for address patching without modifying the main code of the library. However use of the PLT has some overhead, so when a PLT isn't needed, a PC32 relocation is preferred, which just patches in the pc-relative offset of the callee into the call instruction so that it calls the callee directly.
I wouldn't be surprised if somewhere between cretonne, llvm2cretonne, and faerie, we don't consider all these details yet.