llvm2cranelift icon indicating copy to clipboard operation
llvm2cranelift copied to clipboard

What is the correct reloc for function imports?

Open djg opened this issue 7 years ago • 1 comments

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

djg avatar Jan 03 '18 07:01 djg

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.

sunfishcode avatar Jan 05 '18 22:01 sunfishcode