Start adding support for symbols in shared libraries.
llvm-svn: 247019
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index eedacfa..db14ed5 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -54,6 +54,24 @@
error(EC);
}
+template <class ELFT>
+typename ELFData<ELFT>::Elf_Sym_Range ELFData<ELFT>::getNonLocalSymbols() {
+ if (!Symtab)
+ return Elf_Sym_Range(nullptr, nullptr);
+
+ ErrorOr<StringRef> StringTableOrErr =
+ ELFObj->getStringTableForSymtab(*Symtab);
+ error(StringTableOrErr.getError());
+ StringTable = *StringTableOrErr;
+
+ Elf_Sym_Range Syms = ELFObj->symbols(Symtab);
+ uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
+ uint32_t FirstNonLocal = Symtab->sh_info;
+ if (FirstNonLocal > NumSymbols)
+ error("Invalid sh_info in symbol table");
+ return llvm::make_range(Syms.begin() + FirstNonLocal, Syms.end());
+}
+
template <class ELFT> void elf2::ObjectFile<ELFT>::parse() {
this->openELF(MB);
@@ -69,7 +87,7 @@
for (const Elf_Shdr &Sec : this->ELFObj->sections()) {
switch (Sec.sh_type) {
case SHT_SYMTAB:
- Symtab = &Sec;
+ this->Symtab = &Sec;
break;
case SHT_SYMTAB_SHNDX: {
ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable =
@@ -101,20 +119,11 @@
}
template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {
- ErrorOr<StringRef> StringTableOrErr =
- this->ELFObj->getStringTableForSymtab(*Symtab);
- error(StringTableOrErr.getError());
- StringRef StringTable = *StringTableOrErr;
-
- Elf_Sym_Range Syms = this->ELFObj->symbols(Symtab);
+ Elf_Sym_Range Syms = this->getNonLocalSymbols();
uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
- uint32_t FirstNonLocal = Symtab->sh_info;
- if (FirstNonLocal > NumSymbols)
- error("Invalid sh_info in symbol table");
- Syms = llvm::make_range(Syms.begin() + FirstNonLocal, Syms.end());
- SymbolBodies.reserve(NumSymbols - FirstNonLocal);
+ SymbolBodies.reserve(NumSymbols);
for (const Elf_Sym &Sym : Syms)
- SymbolBodies.push_back(createSymbolBody(StringTable, &Sym));
+ SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym));
}
template <class ELFT>
@@ -133,8 +142,8 @@
case SHN_COMMON:
return new (Alloc) DefinedCommon<ELFT>(Name, *Sym);
case SHN_XINDEX:
- SecIndex =
- this->ELFObj->getExtendedSymbolTableIndex(Sym, Symtab, SymtabSHNDX);
+ SecIndex = this->ELFObj->getExtendedSymbolTableIndex(Sym, this->Symtab,
+ SymtabSHNDX);
break;
}
@@ -181,7 +190,30 @@
return *Ret;
}
-template <class ELFT> void SharedFile<ELFT>::parse() { this->openELF(MB); }
+template <class ELFT> void SharedFile<ELFT>::parse() {
+ this->openELF(MB);
+
+ for (const Elf_Shdr &Sec : this->ELFObj->sections()) {
+ if (Sec.sh_type == SHT_DYNSYM) {
+ this->Symtab = &Sec;
+ break;
+ }
+ }
+
+ Elf_Sym_Range Syms = this->getNonLocalSymbols();
+ uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
+ SymbolBodies.reserve(NumSymbols);
+ for (const Elf_Sym &Sym : Syms) {
+ if (Sym.isUndefined())
+ continue;
+
+ ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable);
+ error(NameOrErr.getError());
+ StringRef Name = *NameOrErr;
+
+ SymbolBodies.emplace_back(Name, Sym);
+ }
+}
namespace lld {
namespace elf2 {