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 "Error.h" 13 #include "Symbols.h" 14 #include "llvm/ADT/STLExtras.h" 15 16 using namespace llvm; 17 using namespace llvm::ELF; 18 using namespace llvm::object; 19 20 using namespace lld; 21 using namespace lld::elf2; 22 23 template <class ELFT> static uint16_t getEMachine(const ELFFileBase &B) { 24 bool IsShared = isa<SharedFileBase>(B); 25 if (IsShared) 26 return cast<SharedFile<ELFT>>(B).getEMachine(); 27 return cast<ObjectFile<ELFT>>(B).getEMachine(); 28 } 29 30 static uint16_t getEMachine(const ELFFileBase &B) { 31 ELFKind K = B.getELFKind(); 32 switch (K) { 33 case ELF32BEKind: 34 return getEMachine<ELF32BE>(B); 35 case ELF32LEKind: 36 return getEMachine<ELF32LE>(B); 37 case ELF64BEKind: 38 return getEMachine<ELF64BE>(B); 39 case ELF64LEKind: 40 return getEMachine<ELF64LE>(B); 41 } 42 llvm_unreachable("Invalid kind"); 43 } 44 45 bool ELFFileBase::isCompatibleWith(const ELFFileBase &Other) const { 46 return getELFKind() == Other.getELFKind() && 47 getEMachine(*this) == getEMachine(Other); 48 } 49 50 template <class ELFT> void ELFData<ELFT>::openELF(MemoryBufferRef MB) { 51 // Parse a memory buffer as a ELF file. 52 std::error_code EC; 53 ELFObj = llvm::make_unique<ELFFile<ELFT>>(MB.getBuffer(), EC); 54 error(EC); 55 } 56 57 template <class ELFT> 58 typename ELFData<ELFT>::Elf_Sym_Range ELFData<ELFT>::getNonLocalSymbols() { 59 if (!Symtab) 60 return Elf_Sym_Range(nullptr, nullptr); 61 62 ErrorOr<StringRef> StringTableOrErr = 63 ELFObj->getStringTableForSymtab(*Symtab); 64 error(StringTableOrErr.getError()); 65 StringTable = *StringTableOrErr; 66 67 Elf_Sym_Range Syms = ELFObj->symbols(Symtab); 68 uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); 69 uint32_t FirstNonLocal = Symtab->sh_info; 70 if (FirstNonLocal > NumSymbols) 71 error("Invalid sh_info in symbol table"); 72 return llvm::make_range(Syms.begin() + FirstNonLocal, Syms.end()); 73 } 74 75 template <class ELFT> void elf2::ObjectFile<ELFT>::parse() { 76 this->openELF(MB); 77 78 // Read section and symbol tables. 79 initializeChunks(); 80 initializeSymbols(); 81 } 82 83 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeChunks() { 84 uint64_t Size = this->ELFObj->getNumSections(); 85 Chunks.resize(Size); 86 unsigned I = 0; 87 for (const Elf_Shdr &Sec : this->ELFObj->sections()) { 88 switch (Sec.sh_type) { 89 case SHT_SYMTAB: 90 this->Symtab = &Sec; 91 break; 92 case SHT_SYMTAB_SHNDX: { 93 ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = 94 this->ELFObj->getSHNDXTable(Sec); 95 error(ErrorOrTable); 96 SymtabSHNDX = *ErrorOrTable; 97 break; 98 } 99 case SHT_STRTAB: 100 case SHT_NULL: 101 break; 102 case SHT_RELA: 103 case SHT_REL: { 104 uint32_t RelocatedSectionIndex = Sec.sh_info; 105 if (RelocatedSectionIndex >= Size) 106 error("Invalid relocated section index"); 107 SectionChunk<ELFT> *RelocatedSection = Chunks[RelocatedSectionIndex]; 108 if (!RelocatedSection) 109 error("Unsupported relocation reference"); 110 RelocatedSection->RelocSections.push_back(&Sec); 111 break; 112 } 113 default: 114 Chunks[I] = new (Alloc) SectionChunk<ELFT>(this, &Sec); 115 break; 116 } 117 ++I; 118 } 119 } 120 121 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() { 122 Elf_Sym_Range Syms = this->getNonLocalSymbols(); 123 uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); 124 SymbolBodies.reserve(NumSymbols); 125 for (const Elf_Sym &Sym : Syms) 126 SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym)); 127 } 128 129 template <class ELFT> 130 SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, 131 const Elf_Sym *Sym) { 132 ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable); 133 error(NameOrErr.getError()); 134 StringRef Name = *NameOrErr; 135 136 uint32_t SecIndex = Sym->st_shndx; 137 switch (SecIndex) { 138 case SHN_ABS: 139 return new (Alloc) DefinedAbsolute<ELFT>(Name, *Sym); 140 case SHN_UNDEF: 141 return new (Alloc) Undefined<ELFT>(Name, *Sym); 142 case SHN_COMMON: 143 return new (Alloc) DefinedCommon<ELFT>(Name, *Sym); 144 case SHN_XINDEX: 145 SecIndex = this->ELFObj->getExtendedSymbolTableIndex(Sym, this->Symtab, 146 SymtabSHNDX); 147 break; 148 } 149 150 if (SecIndex >= Chunks.size() || 151 (SecIndex != 0 && !Chunks[SecIndex])) 152 error("Invalid section index"); 153 154 switch (Sym->getBinding()) { 155 default: 156 error("unexpected binding"); 157 case STB_GLOBAL: 158 case STB_WEAK: 159 return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, *Chunks[SecIndex]); 160 } 161 } 162 163 void ArchiveFile::parse() { 164 auto ArchiveOrErr = Archive::create(MB); 165 error(ArchiveOrErr, "Failed to parse archive"); 166 File = std::move(*ArchiveOrErr); 167 168 // Allocate a buffer for Lazy objects. 169 size_t NumSyms = File->getNumberOfSymbols(); 170 LazySymbols.reserve(NumSyms); 171 172 // Read the symbol table to construct Lazy objects. 173 for (const Archive::Symbol &Sym : File->symbols()) 174 LazySymbols.emplace_back(this, Sym); 175 } 176 177 // Returns a buffer pointing to a member file containing a given symbol. 178 MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) { 179 ErrorOr<Archive::child_iterator> ItOrErr = Sym->getMember(); 180 error(ItOrErr, 181 Twine("Could not get the member for symbol ") + Sym->getName()); 182 Archive::child_iterator It = *ItOrErr; 183 184 if (!Seen.insert(It->getChildOffset()).second) 185 return MemoryBufferRef(); 186 187 ErrorOr<MemoryBufferRef> Ret = It->getMemoryBufferRef(); 188 error(Ret, Twine("Could not get the buffer for the member defining symbol ") + 189 Sym->getName()); 190 return *Ret; 191 } 192 193 template <class ELFT> void SharedFile<ELFT>::parse() { 194 this->openELF(MB); 195 196 for (const Elf_Shdr &Sec : this->ELFObj->sections()) { 197 if (Sec.sh_type == SHT_DYNSYM) { 198 this->Symtab = &Sec; 199 break; 200 } 201 } 202 203 Elf_Sym_Range Syms = this->getNonLocalSymbols(); 204 uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); 205 SymbolBodies.reserve(NumSymbols); 206 for (const Elf_Sym &Sym : Syms) { 207 if (Sym.isUndefined()) 208 continue; 209 210 ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable); 211 error(NameOrErr.getError()); 212 StringRef Name = *NameOrErr; 213 214 SymbolBodies.emplace_back(Name, Sym); 215 } 216 } 217 218 namespace lld { 219 namespace elf2 { 220 template class elf2::ObjectFile<llvm::object::ELF32LE>; 221 template class elf2::ObjectFile<llvm::object::ELF32BE>; 222 template class elf2::ObjectFile<llvm::object::ELF64LE>; 223 template class elf2::ObjectFile<llvm::object::ELF64BE>; 224 225 template class elf2::SharedFile<llvm::object::ELF32LE>; 226 template class elf2::SharedFile<llvm::object::ELF32BE>; 227 template class elf2::SharedFile<llvm::object::ELF64LE>; 228 template class elf2::SharedFile<llvm::object::ELF64BE>; 229 } 230 } 231