summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/SymbolTable.cpp17
-rw-r--r--lld/ELF/SymbolTable.h2
-rw-r--r--lld/ELF/Writer.cpp3
-rw-r--r--lld/test/elf2/init_array_missing.s18
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
OpenPOWER on IntegriCloud