diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2015-10-19 15:21:42 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2015-10-19 15:21:42 +0000 |
commit | 334c3e11e6fc62742d125eb703f4b644a5dd91ad (patch) | |
tree | 7a8e4822b33dc06b11bd69a9d4db3975476b7679 | |
parent | bd715d4702380c48a86ced92589d7457eaa1cc9f (diff) | |
download | bcm5719-llvm-334c3e11e6fc62742d125eb703f4b644a5dd91ad.tar.gz bcm5719-llvm-334c3e11e6fc62742d125eb703f4b644a5dd91ad.zip |
Delay the relocation scan.
We have to scan the relaxations after every symbol is defined.
This fixes pr25218.
llvm-svn: 250702
-rw-r--r-- | lld/ELF/Writer.cpp | 40 | ||||
-rw-r--r-- | lld/test/elf2/pre_init_fini_array.s | 12 | ||||
-rw-r--r-- | lld/test/elf2/startstop.s | 37 |
3 files changed, 48 insertions, 41 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 65f57f38b9e..5be9afcce13 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -396,22 +396,6 @@ template <class ELFT> void Writer<ELFT>::createSections() { Map[{Out<ELFT>::Bss->getName(), Out<ELFT>::Bss->getType(), Out<ELFT>::Bss->getFlags()}] = Out<ELFT>::Bss; - // Declare linker generated symbols. - // This must be done before the relocation scan to make sure we can correctly - // decide if a dynamic relocation is needed or not. - // FIXME: Make this more declarative. - for (StringRef Name : - {"__preinit_array_start", "__preinit_array_end", "__init_array_start", - "__init_array_end", "__fini_array_start", "__fini_array_end"}) - Symtab.addIgnoredSym(Name); - - // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For - // static linking the linker is required to optimize away any references to - // __tls_get_addr, so it's not defined anywhere. Create a hidden definition - // to avoid the undefined symbol error. - if (!isOutputDynamic()) - Symtab.addIgnoredSym("__tls_get_addr"); - std::vector<OutputSectionBase<ELFT> *> RegularSections; for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) { @@ -430,13 +414,9 @@ template <class ELFT> void Writer<ELFT>::createSections() { RegularSections.push_back(Sec); } Sec->addSection(C); - scanRelocs(*C); } } - for (OutputSectionBase<ELFT> *Sec : RegularSections) - addStartStopSymbols(Sec); - Out<ELFT>::Dynamic->PreInitArraySec = Map.lookup({".preinit_array", SHT_PREINIT_ARRAY, SHF_WRITE | SHF_ALLOC}); Out<ELFT>::Dynamic->InitArraySec = @@ -449,6 +429,9 @@ template <class ELFT> void Writer<ELFT>::createSections() { if (OS) { Symtab.addSyntheticSym(Start, *OS, 0); Symtab.addSyntheticSym(End, *OS, OS->getSize()); + } else { + Symtab.addIgnoredSym(Start); + Symtab.addIgnoredSym(End); } }; @@ -459,6 +442,23 @@ template <class ELFT> void Writer<ELFT>::createSections() { AddStartEnd("__fini_array_start", "__fini_array_end", Out<ELFT>::Dynamic->FiniArraySec); + for (OutputSectionBase<ELFT> *Sec : RegularSections) + addStartStopSymbols(Sec); + + // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For + // static linking the linker is required to optimize away any references to + // __tls_get_addr, so it's not defined anywhere. Create a hidden definition + // to avoid the undefined symbol error. + if (!isOutputDynamic()) + Symtab.addIgnoredSym("__tls_get_addr"); + + // Scan relocations. This must be done after every symbol is declared so that + // we can correctly decide if a dynamic relocation is needed. + for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) + for (InputSection<ELFT> *S : F->getSections()) + if (S && S != &InputSection<ELFT>::Discarded) + scanRelocs(*S); + // FIXME: Try to avoid the extra walk over all global symbols. std::vector<DefinedCommon<ELFT> *> CommonSymbols; for (auto &P : Symtab.getSymbols()) { diff --git a/lld/test/elf2/pre_init_fini_array.s b/lld/test/elf2/pre_init_fini_array.s index 5bee585691b..7d00bedc22b 100644 --- a/lld/test/elf2/pre_init_fini_array.s +++ b/lld/test/elf2/pre_init_fini_array.s @@ -67,7 +67,7 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .fini_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -76,7 +76,7 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .fini_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -85,7 +85,7 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .init_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -94,7 +94,7 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .init_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -103,7 +103,7 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .preinit_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -112,7 +112,7 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 2 +// CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .preinit_array // CHECK-NEXT: } diff --git a/lld/test/elf2/startstop.s b/lld/test/elf2/startstop.s index 328468a7129..784c237bb31 100644 --- a/lld/test/elf2/startstop.s +++ b/lld/test/elf2/startstop.s @@ -1,41 +1,48 @@ // REQUIRES: x86 // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -// RUN: ld.lld2 %t -o %tout +// RUN: ld.lld2 %t -o %tout -shared // RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s -// RUN: llvm-readobj -symbols %tout | FileCheck -check-prefix=SYMBOL %s +// RUN: llvm-readobj -symbols -r %tout | FileCheck -check-prefix=SYMBOL %s // DISASM: _start: -// DISASM: 11000: e8 0a 00 00 00 callq 10 -// DISASM: 11005: e8 08 00 00 00 callq 8 -// DISASM: 1100a: e8 03 00 00 00 callq 3 +// DISASM: 1000: {{.*}} callq 10 +// DISASM: 1005: {{.*}} callq 8 +// DISASM: 100a: {{.*}} callq 3 // DISASM: Disassembly of section foo: // DISASM: __start_foo: -// DISASM: 1100f: 90 nop -// DISASM: 11010: 90 nop -// DISASM: 11011: 90 nop +// DISASM: 100f: 90 nop +// DISASM: 1010: 90 nop +// DISASM: 1011: 90 nop // DISASM: Disassembly of section bar: // DISASM: __start_bar: -// DISASM: 11012: 90 nop -// DISASM: 11013: 90 nop -// DISASM: 11014: 90 nop +// DISASM: 1012: 90 nop +// DISASM: 1013: 90 nop +// DISASM: 1014: 90 nop + + +// SYMBOL: Relocations [ +// SYMBOL-NEXT: ] // SYMBOL: Symbol { // SYMBOL: Name: __start_bar -// SYMBOL: Value: 0x11012 +// SYMBOL: Value: 0x1012 // SYMBOL: Section: bar // SYMBOL: } // SYMBOL-NOT: Section: __stop_bar // SYMBOL: Symbol { // SYMBOL: Name: __start_foo -// SYMBOL: Value: 0x1100F +// SYMBOL: Value: 0x100F // SYMBOL: Section: foo // SYMBOL: } // SYMBOL: Symbol { // SYMBOL: Name: __stop_foo -// SYMBOL: Value: 0x11012 -// SYMBOL: Section: foo (0x2) +// SYMBOL: Value: 0x1012 +// SYMBOL: Section: foo // SYMBOL: } +.hidden __start_foo +.hidden __stop_foo +.hidden __start_bar .global _start .text _start: |