Skip to content

Commit

Permalink
[ELF] Do not skip relocation scanning checking if the symbol gets dyn…
Browse files Browse the repository at this point in the history
…amic COPY relocation already

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.

Differential Revision: http://reviews.llvm.org/D18862

llvm-svn: 265910
atanasyan committed Apr 10, 2016
1 parent f9e4576 commit 2615c38
Showing 3 changed files with 80 additions and 4 deletions.
7 changes: 3 additions & 4 deletions lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
@@ -382,10 +382,9 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
// 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;
}
}
26 changes: 26 additions & 0 deletions lld/test/ELF/i386-got-and-copy.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# REQUIRES: x86

# 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=i386-pc-linux \
# RUN: %S/Inputs/copy-in-shared.s -o %t.so.o
# RUN: llvm-mc -filetype=obj -triple=i386-pc-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 %t.exe | FileCheck %s

# CHECK: Relocations [
# CHECK-NEXT: Section (4) .rel.dyn {
# CHECK-NEXT: 0x{{[0-9A-F]+}} R_386_COPY foo
# CHECK-NEXT: 0x{{[0-9A-F]+}} R_386_GLOB_DAT foo
# CHECK-NEXT: }
# CHECK-NEXT: ]

.text
.global _start
_start:
movl $foo, (%esp) # R_386_32 - requires R_386_COPY relocation
movl foo@GOT, %eax # R_386_GOT32 - requires GOT entry
51 changes: 51 additions & 0 deletions lld/test/ELF/mips-got-and-copy.s
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit 2615c38

Please sign in to comment.