[PATCH] D18862: [ELF] Do not skip relocation scanning checkins if the symbol gets dynamic COPY relocation already

Rafael EspĂ­ndola via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 10 08:28:31 PDT 2016


LGTM with the i386 test case added.

Cheers,
Rafael


On 7 April 2016 at 10:51, Simon Atanasyan <simon at atanasyan.com> wrote:
> atanasyan created this revision.
> atanasyan added reviewers: rafael, ruiu.
> atanasyan added a subscriber: llvm-commits.
> atanasyan set the repository for this revision to rL LLVM.
> atanasyan added a project: lld.
>
> It is possible that the same symbol referenced by two kinds of relocations at the same time. The first type requires say GOT entry creation, the second type requires dynamic copy relocation. For MIPS targets they might be R_MIPS_GOT16 and R_MIPS_HI16 relocations. For X86 target they might be R_386_GOT32 and R_386_32 respectively.
>
> Now LLD never creates GOT entry for a symbol if this symbol already has related copy relocation. This patch solves this problem.
>
> Repository:
>   rL LLVM
>
> http://reviews.llvm.org/D18862
>
> Files:
>   ELF/Writer.cpp
>   test/ELF/got-and-copy.s
>
> Index: test/ELF/got-and-copy.s
> ===================================================================
> --- /dev/null
> +++ test/ELF/got-and-copy.s
> @@ -0,0 +1,51 @@
> +# REQUIRES: mips
> +
> +# If there are two relocations such that the first one requires
> +# dynamic COPY relocation, the second one requires GOT entry
> +# creation, linker should create both - dynamic relocation
> +# and GOT entry.
> +
> +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
> +# RUN:         %S/Inputs/mips-dynamic.s -o %t.so.o
> +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
> +# RUN: ld.lld %t.so.o -shared -o %t.so
> +# RUN: ld.lld %t.o %t.so -o %t.exe
> +# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
> +
> +# CHECK:      Relocations [
> +# CHECK-NEXT:   Section (7) .rel.dyn {
> +# CHECK-NEXT:     0x{{[0-9A-F]+}} R_MIPS_COPY data0
> +# CHECK-NEXT:     0x{{[0-9A-F]+}} R_MIPS_COPY data1
> +# CHECK-NEXT:   }
> +# CHECK-NEXT: ]
> +# CHECK-NEXT: Primary GOT {
> +# CHECK-NEXT:   Canonical gp value: 0x37FF0
> +# CHECK-NEXT:   Reserved entries [
> +# CHECK:        ]
> +# CHECK-NEXT:   Local entries [
> +# CHECK-NEXT:   ]
> +# CHECK-NEXT:   Global entries [
> +# CHECK-NEXT:     Entry {
> +# CHECK:            Section: .bss
> +# CHECK-NEXT:       Name: data0
> +# CHECK-NEXT:     }
> +# CHECK-NEXT:     Entry {
> +# CHECK:            Section: .bss
> +# CHECK-NEXT:       Name: data1
> +# CHECK-NEXT:     }
> +# CHECK-NEXT:   ]
> +# CHECK-NEXT:   Number of TLS and multi-GOT entries: 0
> +# CHECK-NEXT: }
> +
> +  .text
> +  .global __start
> +__start:
> +  # Case A: 'got' relocation goes before 'copy' relocation
> +  lui    $t0,%hi(data0)         # R_MIPS_HI16 - requires R_MISP_COPY relocation
> +  addi   $t0,$t0,%lo(data0)
> +  lw     $t0,%got(data0)($gp)   # R_MIPS_GOT16 - requires GOT entry
> +
> +  # Case B: 'copy' relocation goes before 'got' relocation
> +  lw     $t0,%got(data1)($gp)   # R_MIPS_GOT16 - requires GOT entry
> +  lui    $t0,%hi(data1)         # R_MIPS_HI16 - requires R_MISP_COPY relocation
> +  addi   $t0,$t0,%lo(data1)
> Index: ELF/Writer.cpp
> ===================================================================
> --- ELF/Writer.cpp
> +++ ELF/Writer.cpp
> @@ -370,10 +370,9 @@
>      // If a symbol in a DSO is referenced directly instead of through GOT,
>      // we need to create a copy relocation for the symbol.
>      if (auto *B = dyn_cast<SharedSymbol<ELFT>>(&Body)) {
> -      if (B->needsCopy())
> -        continue;
> -      if (Target->needsCopyRel<ELFT>(Type, *B)) {
> -        addCopyRelSymbol(B);
> +      if (Target->needsCopyRel<ELFT>(Type, Body)) {
> +        if (!B->needsCopy())
> +          addCopyRelSymbol(B);
>          continue;
>        }
>      }
>
>


More information about the llvm-commits mailing list