diff options
| -rw-r--r-- | lld/ELF/SymbolTable.cpp | 17 | ||||
| -rw-r--r-- | lld/ELF/SymbolTable.h | 2 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 3 | ||||
| -rw-r--r-- | lld/test/elf2/init_array_missing.s | 18 |
4 files changed, 36 insertions, 4 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 24070c880fa..b14c181bbda 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -81,6 +81,13 @@ void SymbolTable::addSyntheticSym(StringRef Name, OutputSection<ELFT> &Section, resolve<ELFT>(Sym); } +template <class ELFT> void SymbolTable::addIgnoredSym(StringRef Name) { + DefinedAbsolute<ELFT>::IgnoreUndef.setVisibility(STV_HIDDEN); + auto Sym = new (Alloc) + DefinedAbsolute<ELFT>(Name, DefinedAbsolute<ELFT>::IgnoreUndef); + resolve<ELFT>(Sym); +} + template <class ELFT> void SymbolTable::init(uint16_t EMachine) { Target.reset(createTarget(EMachine)); if (Config->Shared) @@ -102,10 +109,7 @@ template <class ELFT> void SymbolTable::init(uint16_t EMachine) { // an undefined symbol in the .o files. // Given that the symbol is effectively unused, we just create a dummy // hidden one to avoid the undefined symbol error. - DefinedAbsolute<ELFT>::IgnoreUndef.setVisibility(STV_HIDDEN); - auto Got = new (Alloc) DefinedAbsolute<ELFT>( - "_GLOBAL_OFFSET_TABLE_", DefinedAbsolute<ELFT>::IgnoreUndef); - resolve<ELFT>(Got); + addIgnoredSym<ELFT>("_GLOBAL_OFFSET_TABLE_"); } template <class ELFT> void SymbolTable::addELFFile(ELFFileBase *File) { @@ -249,5 +253,10 @@ template void SymbolTable::addSyntheticSym(StringRef, OutputSection<ELF64LE> &, ELFFile<ELF64LE>::uintX_t); template void SymbolTable::addSyntheticSym(StringRef, OutputSection<ELF64BE> &, ELFFile<ELF64BE>::uintX_t); + +template void SymbolTable::addIgnoredSym<ELF32LE>(StringRef); +template void SymbolTable::addIgnoredSym<ELF32BE>(StringRef); +template void SymbolTable::addIgnoredSym<ELF64LE>(StringRef); +template void SymbolTable::addIgnoredSym<ELF64BE>(StringRef); } } diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index 1e189f5dec5..c451a2d1b73 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -65,6 +65,8 @@ public: void addSyntheticSym(StringRef Name, OutputSection<ELFT> &Section, typename llvm::object::ELFFile<ELFT>::uintX_t Value); + template <class ELFT> void addIgnoredSym(StringRef Name); + private: Symbol *insert(SymbolBody *New); template <class ELFT> void addELFFile(ELFFileBase *File); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index f937d1c411d..7ffa6d2b9cc 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -332,6 +332,9 @@ template <class ELFT> void Writer<ELFT>::createSections() { Map.lookup({".init_array", SHT_INIT_ARRAY, SHF_WRITE | SHF_ALLOC})) { Symtab.addSyntheticSym<ELFT>("__init_array_start", *OS, 0); Symtab.addSyntheticSym<ELFT>("__init_array_end", *OS, OS->getSize()); + } else { + Symtab.addIgnoredSym<ELFT>("__init_array_start"); + Symtab.addIgnoredSym<ELFT>("__init_array_end"); } // FIXME: Try to avoid the extra walk over all global symbols. diff --git a/lld/test/elf2/init_array_missing.s b/lld/test/elf2/init_array_missing.s new file mode 100644 index 00000000000..38aa9cf8057 --- /dev/null +++ b/lld/test/elf2/init_array_missing.s @@ -0,0 +1,18 @@ +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +// RUN: lld -flavor gnu2 %t -o %t2 +// RUN: llvm-objdump -d %t2 | FileCheck %s +// REQUIRES: x86 + +.globl _start +_start: + call __init_array_start + call __init_array_end + +// With no .init_array section the symbols resolve to 0 +// 0 - (0x11000 + 5) = -69637 +// 0 - (0x11005 + 5) = -69642 + +// CHECK: Disassembly of section .text: +// CHECK-NEXT: _start: +// CHECK-NEXT: 11000: e8 fb ef fe ff callq -69637 +// CHECK-NEXT: 11005: e8 f6 ef fe ff callq -69642 |

