diff options
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 1 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 27 | ||||
-rw-r--r-- | lld/test/elf2/pre_init_fini_array.s | 17 |
3 files changed, 28 insertions, 17 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 666755173cd..83645031fed 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -105,6 +105,7 @@ void SymbolTable::addSyntheticSym(StringRef Name, OutputSection<ELFT> &Section, } template <class ELFT> void SymbolTable::addIgnoredSym(StringRef Name) { + DefinedAbsolute<ELFT>::IgnoreUndef.setBinding(STB_WEAK); DefinedAbsolute<ELFT>::IgnoreUndef.setVisibility(STV_HIDDEN); auto Sym = new (Alloc) DefinedAbsolute<ELFT>(Name, DefinedAbsolute<ELFT>::IgnoreUndef); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 61683acee67..976632d265b 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -292,6 +292,23 @@ template <class ELFT> void Writer<ELFT>::createSections() { Map[{BssSec.getName(), BssSec.getType(), BssSec.getFlags()}] = &BssSec; SymbolTable &Symtab = SymTabSec.getSymTable(); + + // 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<ELFT>(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<ELFT>("__tls_get_addr"); + for (const std::unique_ptr<ObjectFileBase> &FileB : Symtab.getObjectFiles()) { auto &File = cast<ObjectFile<ELFT>>(*FileB); if (!Config->DiscardAll) { @@ -331,9 +348,6 @@ template <class ELFT> void Writer<ELFT>::createSections() { if (OS) { Symtab.addSyntheticSym<ELFT>(Start, *OS, 0); Symtab.addSyntheticSym<ELFT>(End, *OS, OS->getSize()); - } else { - Symtab.addIgnoredSym<ELFT>(Start); - Symtab.addIgnoredSym<ELFT>(End); } }; @@ -344,13 +358,6 @@ template <class ELFT> void Writer<ELFT>::createSections() { AddStartEnd("__fini_array_start", "__fini_array_end", DynamicSec.FiniArraySec); - // __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<ELFT>("__tls_get_addr"); - // 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 21c890eb2cb..d9d73a1e927 100644 --- a/lld/test/elf2/pre_init_fini_array.s +++ b/lld/test/elf2/pre_init_fini_array.s @@ -2,7 +2,7 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2 // RUN: lld -flavor gnu2 %t2 -o %t2.so -shared // RUN: lld -flavor gnu2 %t %t2.so -o %t2 -// RUN: llvm-readobj -symbols -sections -dynamic-table %t2 | FileCheck %s +// RUN: llvm-readobj -r -symbols -sections -dynamic-table %t2 | FileCheck %s // RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM %s // REQUIRES: x86 @@ -59,12 +59,15 @@ _start: // CHECK-NEXT: Offset: // CHECK-NEXT: Size: [[FINI_SIZE:.*]] +// CHECK: Relocations [ +// CHECK-NEXT: ] + // CHECK: Name: __fini_array_end // CHECK-NEXT: Value: 0x1301B // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Other: 2 // CHECK-NEXT: Section: .fini_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -73,7 +76,7 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Other: 2 // CHECK-NEXT: Section: .fini_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -82,7 +85,7 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Other: 2 // CHECK-NEXT: Section: .init_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -91,7 +94,7 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Other: 2 // CHECK-NEXT: Section: .init_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -100,7 +103,7 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Other: 2 // CHECK-NEXT: Section: .preinit_array // CHECK-NEXT: } // CHECK-NEXT: Symbol { @@ -109,7 +112,7 @@ _start: // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Other: 2 // CHECK-NEXT: Section: .preinit_array // CHECK-NEXT: } |