//===- InputFiles.cpp -----------------------------------------------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "InputFiles.h" #include "Chunks.h" #include "Symbols.h" #include "Driver.h" #include "llvm/ADT/STLExtras.h" using namespace llvm::ELF; using namespace lld; using namespace lld::elf2; template void elf2::ObjectFile::parse() { // Parse a memory buffer as a ELF file. std::error_code EC; ELFObj = llvm::make_unique>(MB.getBuffer(), EC); error(EC); // Read section and symbol tables. initializeChunks(); initializeSymbols(); } template void elf2::ObjectFile::initializeChunks() { uint64_t Size = ELFObj->getNumSections(); Chunks.reserve(Size); for (const Elf_Shdr &Sec : ELFObj->sections()) { if (Sec.sh_flags & SHF_ALLOC) { auto *C = new (Alloc) SectionChunk(this->getObj(), &Sec); Chunks.push_back(C); } } } template void elf2::ObjectFile::initializeSymbols() { const Elf_Shdr *Symtab = ELFObj->getDotSymtabSec(); ErrorOr StringTableOrErr = ELFObj->getStringTableForSymtab(*Symtab); error(StringTableOrErr.getError()); StringRef StringTable = *StringTableOrErr; Elf_Sym_Range Syms = ELFObj->symbols(); Syms = Elf_Sym_Range(Syms.begin() + 1, Syms.end()); auto NumSymbols = std::distance(Syms.begin(), Syms.end()); SymbolBodies.reserve(NumSymbols); for (const Elf_Sym &Sym : Syms) { if (SymbolBody *Body = createSymbolBody(StringTable, &Sym)) SymbolBodies.push_back(Body); } } template SymbolBody *elf2::ObjectFile::createSymbolBody(StringRef StringTable, const Elf_Sym *Sym) { ErrorOr NameOrErr = Sym->getName(StringTable); error(NameOrErr.getError()); StringRef Name = *NameOrErr; if (Sym->isUndefined()) return new (Alloc) Undefined(Name); return new (Alloc) DefinedRegular(this, Sym); } namespace lld { namespace elf2 { template class elf2::ObjectFile; template class elf2::ObjectFile; template class elf2::ObjectFile; template class elf2::ObjectFile; } }