1 //===- InputFiles.cpp -----------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "InputFiles.h" 11 #include "Chunks.h" 12 #include "Symbols.h" 13 #include "Driver.h" 14 #include "llvm/ADT/STLExtras.h" 15 16 using namespace llvm::ELF; 17 18 using namespace lld; 19 using namespace lld::elf2; 20 21 template <class ELFT> void elf2::ObjectFile<ELFT>::parse() { 22 // Parse a memory buffer as a ELF file. 23 std::error_code EC; 24 ELFObj = llvm::make_unique<ELFFile<ELFT>>(MB.getBuffer(), EC); 25 error(EC); 26 27 // Read section and symbol tables. 28 initializeChunks(); 29 initializeSymbols(); 30 } 31 32 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeChunks() { 33 uint64_t Size = ELFObj->getNumSections(); 34 Chunks.reserve(Size); 35 for (const Elf_Shdr &Sec : ELFObj->sections()) { 36 if (Sec.sh_flags & SHF_ALLOC) { 37 auto *C = new (Alloc) SectionChunk<ELFT>(this->getObj(), &Sec); 38 Chunks.push_back(C); 39 } 40 } 41 } 42 43 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() { 44 const Elf_Shdr *Symtab = ELFObj->getDotSymtabSec(); 45 ErrorOr<StringRef> StringTableOrErr = 46 ELFObj->getStringTableForSymtab(*Symtab); 47 error(StringTableOrErr.getError()); 48 StringRef StringTable = *StringTableOrErr; 49 50 Elf_Sym_Range Syms = ELFObj->symbols(); 51 Syms = Elf_Sym_Range(Syms.begin() + 1, Syms.end()); 52 auto NumSymbols = std::distance(Syms.begin(), Syms.end()); 53 SymbolBodies.reserve(NumSymbols); 54 for (const Elf_Sym &Sym : Syms) { 55 if (SymbolBody *Body = createSymbolBody(StringTable, &Sym)) 56 SymbolBodies.push_back(Body); 57 } 58 } 59 60 template <class ELFT> 61 SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, 62 const Elf_Sym *Sym) { 63 ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable); 64 error(NameOrErr.getError()); 65 StringRef Name = *NameOrErr; 66 if (Sym->isUndefined()) 67 return new (Alloc) Undefined(Name); 68 return new (Alloc) DefinedRegular<ELFT>(this, Sym); 69 } 70 71 namespace lld { 72 namespace elf2 { 73 template class elf2::ObjectFile<llvm::object::ELF32LE>; 74 template class elf2::ObjectFile<llvm::object::ELF32BE>; 75 template class elf2::ObjectFile<llvm::object::ELF64LE>; 76 template class elf2::ObjectFile<llvm::object::ELF64BE>; 77 } 78 } 79