From 055906e1e50ddc35d6c8cdccab48ed83e93b47eb Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 20 May 2019 15:25:01 +0000 Subject: [PATCH] [ELF] -z combreloc: sort dynamic relocations by (!is_relative,symbol_index,r_offset) We currently sort dynamic relocations by (!is_relative,symbol_index). Add r_offset as the third key. This makes `readelf -r` debugging easier (relocations to the same symbol are ordered by r_offset). Refactor the test combreloc.s (renamed from combrelocs.s) to check R_X86_64_RELATIVE, and delete --expand-relocs. The difference from the reverted D61477 is that we keep !is_relative as the first key. In local dynamic TLS model, DTPMOD (e.g. R_ARM_TLS_DTPMOD32 R_X86_64_DTPMOD and R_PPC{,64}_DTPMOD) may use 0 as the symbol index. Reviewed By: grimar Differential Revision: https://reviews.llvm.org/D62141 llvm-svn: 361164 --- lld/ELF/SyntheticSections.cpp | 18 +++--- lld/test/ELF/combreloc.s | 48 ++++++++++++++++ lld/test/ELF/combrelocs.s | 95 -------------------------------- lld/test/ELF/i386-got-and-copy.s | 2 +- 4 files changed, 58 insertions(+), 105 deletions(-) create mode 100644 lld/test/ELF/combreloc.s delete mode 100644 lld/test/ELF/combrelocs.s diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 4ecf05ede4a5..7e4acccdd52c 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1488,17 +1488,17 @@ RelocationSection::RelocationSection(StringRef Name, bool Sort) this->Entsize = Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); } -static bool compRelocations(const DynamicReloc &A, const DynamicReloc &B) { - bool AIsRel = A.Type == Target->RelativeRel; - bool BIsRel = B.Type == Target->RelativeRel; - if (AIsRel != BIsRel) - return AIsRel; - return A.getSymIndex() < B.getSymIndex(); -} - template void RelocationSection::writeTo(uint8_t *Buf) { + // Sort by (!IsRelative,SymIndex,r_offset). DT_REL[A]COUNT requires us to + // place R_*_RELATIVE first. SymIndex is to improve locality, while r_offset + // is to make results easier to read. if (Sort) - llvm::stable_sort(Relocs, compRelocations); + llvm::stable_sort(Relocs, [](const DynamicReloc &A, const DynamicReloc &B) { + return std::make_tuple(A.Type != Target->RelativeRel, A.getSymIndex(), + A.getOffset()) < + std::make_tuple(B.Type != Target->RelativeRel, B.getSymIndex(), + B.getOffset()); + }); for (const DynamicReloc &Rel : Relocs) { encodeDynamicReloc(reinterpret_cast(Buf), Rel); diff --git a/lld/test/ELF/combreloc.s b/lld/test/ELF/combreloc.s new file mode 100644 index 000000000000..b8c751792862 --- /dev/null +++ b/lld/test/ELF/combreloc.s @@ -0,0 +1,48 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o +# RUN: echo 'mov aaa@gotpcrel(%rip), %rax' | llvm-mc -filetype=obj -triple=x86_64 - -o %t1.o + +# RUN: ld.lld -shared %t.o %t1.o -o %t.so +# RUN: llvm-readobj -r --dynamic-table %t.so | FileCheck %s +# RUN: ld.lld -shared %t.o %t1.o -o %t.so -z combreloc +# RUN: llvm-readobj -r --dynamic-table %t.so | FileCheck %s + +# -z combreloc is the default: sort relocations by (!IsRelative,SymIndex,r_offset), +# and emit DT_RELACOUNT (except on MIPS) to indicate the number of relative +# relocations. + +# CHECK: Relocations [ +# CHECK-NEXT: Section ({{.*}}) .rela.dyn { +# CHECK-NEXT: 0x3020 R_X86_64_RELATIVE - 0x3028 +# CHECK-NEXT: 0x20B0 R_X86_64_GLOB_DAT aaa 0x0 +# CHECK-NEXT: 0x3000 R_X86_64_64 aaa 0x0 +# CHECK-NEXT: 0x3018 R_X86_64_64 aaa 0x0 +# CHECK-NEXT: 0x3010 R_X86_64_64 bbb 0x0 +# CHECK-NEXT: 0x3008 R_X86_64_64 ccc 0x0 +# CHECK-NEXT: } +# CHECK: DynamicSection [ +# CHECK: RELACOUNT 1 + +# RUN: ld.lld -z nocombreloc -shared %t.o %t1.o -o %t.so +# RUN: llvm-readobj -r --dynamic-table %t.so | FileCheck --check-prefix=NOCOMB %s + +# NOCOMB: Relocations [ +# NOCOMB-NEXT: Section ({{.*}}) .rela.dyn { +# NOCOMB-NEXT: 0x3000 R_X86_64_64 aaa 0x0 +# NOCOMB-NEXT: 0x3008 R_X86_64_64 ccc 0x0 +# NOCOMB-NEXT: 0x3010 R_X86_64_64 bbb 0x0 +# NOCOMB-NEXT: 0x3018 R_X86_64_64 aaa 0x0 +# NOCOMB-NEXT: 0x3020 R_X86_64_RELATIVE - 0x3028 +# NOCOMB-NEXT: 0x20A0 R_X86_64_GLOB_DAT aaa 0x0 +# NOCOMB-NEXT: } +# NOCOMB: DynamicSection [ +# NOCOMB-NOT: RELACOUNT + +.data + .quad aaa + .quad ccc + .quad bbb + .quad aaa + .quad relative +relative: diff --git a/lld/test/ELF/combrelocs.s b/lld/test/ELF/combrelocs.s deleted file mode 100644 index e2164511bd62..000000000000 --- a/lld/test/ELF/combrelocs.s +++ /dev/null @@ -1,95 +0,0 @@ -# REQUIRES: x86 - -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -# RUN: ld.lld -shared %t.o -o %t.out -# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | FileCheck %s - -# RUN: ld.lld -shared %t.o -o %t.out -z combreloc -# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | FileCheck %s - -# CHECK: Relocations [ -# CHECK-NEXT: Section ({{.*}}) .rela.dyn { -# CHECK-NEXT: Relocation { -# CHECK-NEXT: Offset: 0x2000 -# CHECK-NEXT: Type: R_X86_64_64 -# CHECK-NEXT: Symbol: aaa (1) -# CHECK-NEXT: Addend: 0x0 -# CHECK-NEXT: } -# CHECK-NEXT: Relocation { -# CHECK-NEXT: Offset: 0x2018 -# CHECK-NEXT: Type: R_X86_64_64 -# CHECK-NEXT: Symbol: aaa (1) -# CHECK-NEXT: Addend: 0x0 -# CHECK-NEXT: } -# CHECK-NEXT: Relocation { -# CHECK-NEXT: Offset: 0x2010 -# CHECK-NEXT: Type: R_X86_64_64 -# CHECK-NEXT: Symbol: bbb (2) -# CHECK-NEXT: Addend: 0x0 -# CHECK-NEXT: } -# CHECK-NEXT: Relocation { -# CHECK-NEXT: Offset: 0x2008 -# CHECK-NEXT: Type: R_X86_64_64 -# CHECK-NEXT: Symbol: ccc (3) -# CHECK-NEXT: Addend: 0x0 -# CHECK-NEXT: } -# CHECK-NEXT: Relocation { -# CHECK-NEXT: Offset: 0x2020 -# CHECK-NEXT: Type: R_X86_64_64 -# CHECK-NEXT: Symbol: ddd (4) -# CHECK-NEXT: Addend: 0x0 -# CHECK-NEXT: } -# CHECK-NEXT: } -# CHECK-NEXT: ] -# CHECK: DynamicSection [ -# CHECK-NEXT: Tag -# CHECK-NOT: RELACOUNT - -# RUN: ld.lld -z nocombreloc -shared %t.o -o %t.out -# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | \ -# RUN: FileCheck --check-prefix=NOCOMB %s - -# NOCOMB: Relocations [ -# NOCOMB-NEXT: Section ({{.*}}) .rela.dyn { -# NOCOMB-NEXT: Relocation { -# NOCOMB-NEXT: Offset: 0x2000 -# NOCOMB-NEXT: Type: R_X86_64_64 -# NOCOMB-NEXT: Symbol: aaa (1) -# NOCOMB-NEXT: Addend: 0x0 -# NOCOMB-NEXT: } -# NOCOMB-NEXT: Relocation { -# NOCOMB-NEXT: Offset: 0x2008 -# NOCOMB-NEXT: Type: R_X86_64_64 -# NOCOMB-NEXT: Symbol: ccc (3) -# NOCOMB-NEXT: Addend: 0x0 -# NOCOMB-NEXT: } -# NOCOMB-NEXT: Relocation { -# NOCOMB-NEXT: Offset: 0x2010 -# NOCOMB-NEXT: Type: R_X86_64_64 -# NOCOMB-NEXT: Symbol: bbb (2) -# NOCOMB-NEXT: Addend: 0x0 -# NOCOMB-NEXT: } -# NOCOMB-NEXT: Relocation { -# NOCOMB-NEXT: Offset: 0x2018 -# NOCOMB-NEXT: Type: R_X86_64_64 -# NOCOMB-NEXT: Symbol: aaa (1) -# NOCOMB-NEXT: Addend: 0x0 -# NOCOMB-NEXT: } -# NOCOMB-NEXT: Relocation { -# NOCOMB-NEXT: Offset: 0x2020 -# NOCOMB-NEXT: Type: R_X86_64_64 -# NOCOMB-NEXT: Symbol: ddd (4) -# NOCOMB-NEXT: Addend: 0x0 -# NOCOMB-NEXT: } -# NOCOMB-NEXT: } -# NOCOMB-NEXT: ] -# NOCOMB: DynamicSection [ -# NOCOMB-NEXT: Tag -# NOCOMB-NOT: RELACOUNT - -.data - .quad aaa - .quad ccc - .quad bbb - .quad aaa - .quad ddd diff --git a/lld/test/ELF/i386-got-and-copy.s b/lld/test/ELF/i386-got-and-copy.s index 78788a55f23c..9c2f60f68929 100644 --- a/lld/test/ELF/i386-got-and-copy.s +++ b/lld/test/ELF/i386-got-and-copy.s @@ -14,8 +14,8 @@ # 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: 0x{{[0-9A-F]+}} R_386_COPY foo # CHECK-NEXT: } # CHECK-NEXT: ]