typename ELFT::SymRange ELFFileBase<ELFT>::getElfSymbols(bool OnlyGlobals) { if (!Symtab) return Elf_Sym_Range(nullptr, nullptr); 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) fatal("invalid sh_info in symbol table"); if (OnlyGlobals) return makeArrayRef(Syms.begin() + FirstNonLocal, Syms.end()); return makeArrayRef(Syms.begin(), Syms.end()); }
template <class ELFT> void elf::ObjectFile<ELFT>::initializeSymbols() { this->initStringTable(); 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) SymbolBodies.push_back(createSymbolBody(&Sym)); }
// Fully parse the shared object file. This must be called after parseSoName(). template <class ELFT> void SharedFile<ELFT>::parseRest() { 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) { StringRef Name = check(Sym.getName(this->StringTable)); if (Sym.isUndefined()) Undefs.push_back(Name); else SymbolBodies.emplace_back(this, Name, Sym); } }
static void reportUndefined(const SymbolTable<ELFT> &S, const SymbolBody &Sym) { typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; typedef typename ELFFile<ELFT>::Elf_Sym_Range Elf_Sym_Range; if (Config->Shared && !Config->NoUndefined) return; const Elf_Sym &SymE = cast<ELFSymbolBody<ELFT>>(Sym).Sym; ELFFileBase<ELFT> *SymFile = nullptr; for (const std::unique_ptr<ObjectFile<ELFT>> &File : S.getObjectFiles()) { Elf_Sym_Range Syms = File->getObj().symbols(File->getSymbolTable()); if (&SymE > Syms.begin() && &SymE < Syms.end()) SymFile = File.get(); } std::string Message = "undefined symbol: " + Sym.getName().str(); if (SymFile) Message += " in " + SymFile->getName().str(); if (Config->NoInhibitExec) warning(Message); else error(Message); }