Create a SymbolBody for locals.
pr26878 shows a case where locals have to be in the got.
llvm-svn: 263222
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 7925695..6060de6 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -46,7 +46,7 @@
template <class ELFT>
typename ELFFileBase<ELFT>::Elf_Sym_Range
-ELFFileBase<ELFT>::getSymbolsHelper(bool Local) {
+ELFFileBase<ELFT>::getElfSymbols(bool OnlyGlobals) {
if (!Symtab)
return Elf_Sym_Range(nullptr, nullptr);
Elf_Sym_Range Syms = ELFObj.symbols(Symtab);
@@ -54,10 +54,10 @@
uint32_t FirstNonLocal = Symtab->sh_info;
if (FirstNonLocal > NumSymbols)
fatal("Invalid sh_info in symbol table");
- if (!Local)
+
+ if (OnlyGlobals)
return make_range(Syms.begin() + FirstNonLocal, Syms.end());
- // +1 to skip over dummy symbol.
- return make_range(Syms.begin() + 1, Syms.begin() + FirstNonLocal);
+ return make_range(Syms.begin(), Syms.end());
}
template <class ELFT>
@@ -77,19 +77,30 @@
}
template <class ELFT>
-typename ELFFileBase<ELFT>::Elf_Sym_Range
-ELFFileBase<ELFT>::getNonLocalSymbols() {
- return getSymbolsHelper(false);
-}
-
-template <class ELFT>
elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M)
: ELFFileBase<ELFT>(Base::ObjectKind, M) {}
template <class ELFT>
-typename elf::ObjectFile<ELFT>::Elf_Sym_Range
-elf::ObjectFile<ELFT>::getLocalSymbols() {
- return this->getSymbolsHelper(true);
+ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getNonLocalSymbols() {
+ if (!this->Symtab)
+ return this->SymbolBodies;
+ uint32_t FirstNonLocal = this->Symtab->sh_info;
+ return makeArrayRef(this->SymbolBodies).slice(FirstNonLocal);
+}
+
+template <class ELFT>
+ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getLocalSymbols() {
+ if (!this->Symtab)
+ return this->SymbolBodies;
+ uint32_t FirstNonLocal = this->Symtab->sh_info;
+ return makeArrayRef(this->SymbolBodies).slice(1, FirstNonLocal - 1);
+}
+
+template <class ELFT>
+ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getSymbols() {
+ if (!this->Symtab)
+ return this->SymbolBodies;
+ return makeArrayRef(this->SymbolBodies).slice(1);
}
template <class ELFT> uint32_t elf::ObjectFile<ELFT>::getMipsGp0() const {
@@ -99,16 +110,6 @@
}
template <class ELFT>
-const typename elf::ObjectFile<ELFT>::Elf_Sym *
-elf::ObjectFile<ELFT>::getLocalSymbol(uintX_t SymIndex) {
- uint32_t FirstNonLocal = this->Symtab->sh_info;
- if (SymIndex >= FirstNonLocal)
- return nullptr;
- Elf_Sym_Range Syms = this->ELFObj.symbols(this->Symtab);
- return Syms.begin() + SymIndex;
-}
-
-template <class ELFT>
void elf::ObjectFile<ELFT>::parse(DenseSet<StringRef> &ComdatGroups) {
// Read section and symbol tables.
initializeSections(ComdatGroups);
@@ -266,7 +267,7 @@
template <class ELFT> void elf::ObjectFile<ELFT>::initializeSymbols() {
this->initStringTable();
- Elf_Sym_Range Syms = this->getNonLocalSymbols();
+ Elf_Sym_Range Syms = this->getElfSymbols(false);
uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
SymbolBodies.reserve(NumSymbols);
for (const Elf_Sym &Sym : Syms)
@@ -289,6 +290,10 @@
template <class ELFT>
SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
+ unsigned char Binding = Sym->getBinding();
+ if (Binding == STB_LOCAL)
+ return new (Alloc) LocalSymbol<ELFT>(*Sym);
+
StringRef Name = check(Sym->getName(this->StringTable));
switch (Sym->st_shndx) {
@@ -300,7 +305,7 @@
Sym->getVisibility());
}
- switch (Sym->getBinding()) {
+ switch (Binding) {
default:
fatal("Unexpected binding");
case STB_GLOBAL:
@@ -399,7 +404,7 @@
// Fully parse the shared object file. This must be called after parseSoName().
template <class ELFT> void SharedFile<ELFT>::parseRest() {
- Elf_Sym_Range Syms = this->getNonLocalSymbols();
+ Elf_Sym_Range Syms = this->getElfSymbols(true);
uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
SymbolBodies.reserve(NumSymbols);
for (const Elf_Sym &Sym : Syms) {