[PATCH] D47098: [ELF] Make R_GOTONLY_PC_FROM_END R_GOTREL_FROM_END relative to _GLOBAL_OFFSET_TABLE_ instead of end of .got
George Rimar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon May 28 08:20:17 PDT 2018
grimar added a comment.
Ok. After additional investigation (you mentioned TLS and I found a good sample for test),
I think we do the correct thing now.
I investigated pr20308 sample from gold. Below is asm code + output produced by gold as
well as relocations emitted for inputs.
> .text
> .p2align 4,,15
>
> .globl set_gd
> .type set_gd, @function
> set_gd:
>
> pushl %ebx #push %ebx
> nop #nop
> movl (%esp), %ebx #mov (%esp),%ebx
> addl $_GLOBAL_OFFSET_TABLE_, %ebx #add $0x199f,%ebx, R_386_GOTPC
> subl $8, %esp #sub $0x8,%esp
> leal gd at tlsgd(%ebx), %eax #lea -0x10(%ebx),%eax, R_386_TLS_GD
> leal gd2 at tlsgd(%ebx), %eax #lea -0x8(%ebx),%eax, R_386_TLS_GD
> call ___tls_get_addr at PLT #call 510 <___tls_get_addr at plt>, R_386_PLT32
> nop #nop
> movl 16(%esp), %edx #mov 0x10(%esp),%edx
> movl %edx, (%eax) #mov %edx,(%eax)
> addl $8, %esp #add $0x8,%esp
> popl %ebx #pop %ebx
> ret #ret
> .size set_gd, .-set_gd
_GLOBAL_OFFSET_TABLE_ has value 00001ff4:
> 21: 00001ff4 24 OBJECT LOCAL HIDDEN 22 _GLOBAL_OFFSET_TABLE_
It is at the end of `.got` (equal to `.got.plt`):
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[21] .got PROGBITS 00001fd0 000fd0 000024 00 WA 0 0 4
[22] .got.plt PROGBITS 00001ff4 000ff4 000020 00 WA 0 0 4
As you can see, `_GLOBAL_OFFSET_TABLE_` is used for calculating indexes in
`.got` for TLS symbols (2 slots per symbol for TLS GD mode):
> addl $_GLOBAL_OFFSET_TABLE_, %ebx #add $0x199f,%ebx, R_386_GOTPC
> ...
> leal gd at tlsgd(%ebx), %eax #lea -0x10(%ebx),%eax, R_386_TLS_GD
> leal gd2 at tlsgd(%ebx), %eax #lea -0x8(%ebx),%eax, R_386_TLS_GD
Relocations for them are expected to be always relative to the end of `.got`, and not end of `.got.plt`.
Otherwise, the loader would try to use .got.plt slots instead of allocated pairs and would fail.
That returns me to what I said initially:
> It does not seem correct to me to resolve relocations relative to _GLOBAL_OFFSET_TABLE_ generally. There is an issue with resolving
> relocations against particular _GLOBAL_OFFSET_TABLE_ symbol, but I am not sure that fix should affect anything else.
Repository:
rLLD LLVM Linker
https://reviews.llvm.org/D47098
More information about the llvm-commits
mailing list