[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