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 "InputSection.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 using namespace llvm::sys::fs; 20 21 using namespace lld; 22 using namespace lld::elf2; 23 24 namespace { 25 class ECRAII { 26 std::error_code EC; 27 28 public: 29 std::error_code &getEC() { return EC; } 30 ~ECRAII() { error(EC); } 31 }; 32 } 33 34 template <class ELFT> 35 ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef M) 36 : InputFile(K, M), ELFObj(MB.getBuffer(), ECRAII().getEC()) {} 37 38 template <class ELFT> 39 typename ELFFileBase<ELFT>::Elf_Sym_Range 40 ELFFileBase<ELFT>::getSymbolsHelper(bool Local) { 41 if (!Symtab) 42 return Elf_Sym_Range(nullptr, nullptr); 43 Elf_Sym_Range Syms = ELFObj.symbols(Symtab); 44 uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); 45 uint32_t FirstNonLocal = Symtab->sh_info; 46 if (FirstNonLocal > NumSymbols) 47 error("Invalid sh_info in symbol table"); 48 if (!Local) 49 return make_range(Syms.begin() + FirstNonLocal, Syms.end()); 50 // +1 to skip over dummy symbol. 51 return make_range(Syms.begin() + 1, Syms.begin() + FirstNonLocal); 52 } 53 54 template <class ELFT> void ELFFileBase<ELFT>::initStringTable() { 55 if (!Symtab) 56 return; 57 ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab); 58 error(StringTableOrErr.getError()); 59 StringTable = *StringTableOrErr; 60 } 61 62 template <class ELFT> 63 typename ELFFileBase<ELFT>::Elf_Sym_Range 64 ELFFileBase<ELFT>::getNonLocalSymbols() { 65 return getSymbolsHelper(false); 66 } 67 68 template <class ELFT> 69 ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M) 70 : ELFFileBase<ELFT>(Base::ObjectKind, M) {} 71 72 template <class ELFT> 73 typename ObjectFile<ELFT>::Elf_Sym_Range ObjectFile<ELFT>::getLocalSymbols() { 74 return this->getSymbolsHelper(true); 75 } 76 77 template <class ELFT> 78 void elf2::ObjectFile<ELFT>::parse(DenseSet<StringRef> &Comdats) { 79 // Read section and symbol tables. 80 initializeSections(Comdats); 81 initializeSymbols(); 82 } 83 84 template <class ELFT> 85 StringRef ObjectFile<ELFT>::getShtGroupSignature(const Elf_Shdr &Sec) { 86 const ELFFile<ELFT> &Obj = this->ELFObj; 87 uint32_t SymtabdSectionIndex = Sec.sh_link; 88 ErrorOr<const Elf_Shdr *> SecOrErr = Obj.getSection(SymtabdSectionIndex); 89 error(SecOrErr); 90 const Elf_Shdr *SymtabSec = *SecOrErr; 91 uint32_t SymIndex = Sec.sh_info; 92 const Elf_Sym *Sym = Obj.getSymbol(SymtabSec, SymIndex); 93 ErrorOr<StringRef> StringTableOrErr = Obj.getStringTableForSymtab(*SymtabSec); 94 error(StringTableOrErr); 95 ErrorOr<StringRef> SignatureOrErr = Sym->getName(*StringTableOrErr); 96 error(SignatureOrErr); 97 return *SignatureOrErr; 98 } 99 100 template <class ELFT> 101 ArrayRef<typename ObjectFile<ELFT>::GroupEntryType> 102 ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) { 103 const ELFFile<ELFT> &Obj = this->ELFObj; 104 ErrorOr<ArrayRef<GroupEntryType>> EntriesOrErr = 105 Obj.template getSectionContentsAsArray<GroupEntryType>(&Sec); 106 error(EntriesOrErr.getError()); 107 ArrayRef<GroupEntryType> Entries = *EntriesOrErr; 108 if (Entries.empty() || Entries[0] != GRP_COMDAT) 109 error("Unsupported SHT_GROUP format"); 110 return Entries.slice(1); 111 } 112 113 template <class ELFT> 114 void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) { 115 uint64_t Size = this->ELFObj.getNumSections(); 116 Sections.resize(Size); 117 unsigned I = -1; 118 const ELFFile<ELFT> &Obj = this->ELFObj; 119 for (const Elf_Shdr &Sec : Obj.sections()) { 120 ++I; 121 if (Sections[I] == &InputSection<ELFT>::Discarded) 122 continue; 123 124 switch (Sec.sh_type) { 125 case SHT_GROUP: 126 Sections[I] = &InputSection<ELFT>::Discarded; 127 if (Comdats.insert(getShtGroupSignature(Sec)).second) 128 continue; 129 for (GroupEntryType E : getShtGroupEntries(Sec)) { 130 uint32_t SecIndex = E; 131 if (SecIndex >= Size) 132 error("Invalid section index in group"); 133 Sections[SecIndex] = &InputSection<ELFT>::Discarded; 134 } 135 break; 136 case SHT_SYMTAB: 137 this->Symtab = &Sec; 138 break; 139 case SHT_SYMTAB_SHNDX: { 140 ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = Obj.getSHNDXTable(Sec); 141 error(ErrorOrTable); 142 SymtabSHNDX = *ErrorOrTable; 143 break; 144 } 145 case SHT_STRTAB: 146 case SHT_NULL: 147 break; 148 case SHT_RELA: 149 case SHT_REL: { 150 uint32_t RelocatedSectionIndex = Sec.sh_info; 151 if (RelocatedSectionIndex >= Size) 152 error("Invalid relocated section index"); 153 InputSection<ELFT> *RelocatedSection = Sections[RelocatedSectionIndex]; 154 if (!RelocatedSection) 155 error("Unsupported relocation reference"); 156 RelocatedSection->RelocSections.push_back(&Sec); 157 break; 158 } 159 default: 160 Sections[I] = new (this->Alloc) InputSection<ELFT>(this, &Sec); 161 break; 162 } 163 } 164 } 165 166 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() { 167 this->initStringTable(); 168 Elf_Sym_Range Syms = this->getNonLocalSymbols(); 169 uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); 170 this->SymbolBodies.reserve(NumSymbols); 171 for (const Elf_Sym &Sym : Syms) 172 this->SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym)); 173 } 174 175 template <class ELFT> 176 SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, 177 const Elf_Sym *Sym) { 178 ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable); 179 error(NameOrErr.getError()); 180 StringRef Name = *NameOrErr; 181 182 uint32_t SecIndex = Sym->st_shndx; 183 switch (SecIndex) { 184 case SHN_ABS: 185 return new (this->Alloc) DefinedAbsolute<ELFT>(Name, *Sym); 186 case SHN_UNDEF: 187 return new (this->Alloc) Undefined<ELFT>(Name, *Sym); 188 case SHN_COMMON: 189 return new (this->Alloc) DefinedCommon<ELFT>(Name, *Sym); 190 case SHN_XINDEX: 191 SecIndex = this->ELFObj.getExtendedSymbolTableIndex(Sym, this->Symtab, 192 SymtabSHNDX); 193 break; 194 } 195 196 if (SecIndex >= Sections.size() || !SecIndex || !Sections[SecIndex]) 197 error("Invalid section index"); 198 199 switch (Sym->getBinding()) { 200 default: 201 error("unexpected binding"); 202 case STB_GLOBAL: 203 case STB_WEAK: 204 case STB_GNU_UNIQUE: { 205 InputSection<ELFT> *Sec = Sections[SecIndex]; 206 if (Sec == &InputSection<ELFT>::Discarded) 207 return new (this->Alloc) Undefined<ELFT>(Name, *Sym); 208 return new (this->Alloc) DefinedRegular<ELFT>(Name, *Sym, *Sec); 209 } 210 } 211 } 212 213 static std::unique_ptr<Archive> openArchive(MemoryBufferRef MB) { 214 ErrorOr<std::unique_ptr<Archive>> ArchiveOrErr = Archive::create(MB); 215 error(ArchiveOrErr, "Failed to parse archive"); 216 return std::move(*ArchiveOrErr); 217 } 218 219 void ArchiveFile::parse() { 220 File = openArchive(MB); 221 222 // Allocate a buffer for Lazy objects. 223 size_t NumSyms = File->getNumberOfSymbols(); 224 LazySymbols.reserve(NumSyms); 225 226 // Read the symbol table to construct Lazy objects. 227 for (const Archive::Symbol &Sym : File->symbols()) 228 LazySymbols.emplace_back(this, Sym); 229 } 230 231 // Returns a buffer pointing to a member file containing a given symbol. 232 MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) { 233 ErrorOr<Archive::child_iterator> ItOrErr = Sym->getMember(); 234 error(ItOrErr, "Could not get the member for symbol " + Sym->getName()); 235 Archive::child_iterator It = *ItOrErr; 236 237 if (!Seen.insert(It->getChildOffset()).second) 238 return MemoryBufferRef(); 239 240 ErrorOr<MemoryBufferRef> Ret = It->getMemoryBufferRef(); 241 error(Ret, "Could not get the buffer for the member defining symbol " + 242 Sym->getName()); 243 return *Ret; 244 } 245 246 std::vector<MemoryBufferRef> ArchiveFile::getMembers() { 247 File = openArchive(MB); 248 249 std::vector<MemoryBufferRef> Result; 250 for (const Archive::Child &Child : File->children()) { 251 ErrorOr<MemoryBufferRef> MbOrErr = Child.getMemoryBufferRef(); 252 error(MbOrErr, "Could not get the buffer for a child of the archive " + 253 File->getFileName()); 254 Result.push_back(MbOrErr.get()); 255 } 256 return Result; 257 } 258 259 template <class ELFT> 260 SharedFile<ELFT>::SharedFile(MemoryBufferRef M) 261 : ELFFileBase<ELFT>(Base::SharedKind, M) { 262 AsNeeded = Config->AsNeeded; 263 } 264 265 template <class ELFT> void SharedFile<ELFT>::parseSoName() { 266 typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn; 267 typedef typename ELFFile<ELFT>::uintX_t uintX_t; 268 const Elf_Shdr *DynamicSec = nullptr; 269 270 const ELFFile<ELFT> Obj = this->ELFObj; 271 for (const Elf_Shdr &Sec : Obj.sections()) { 272 uint32_t Type = Sec.sh_type; 273 if (Type == SHT_DYNSYM) 274 this->Symtab = &Sec; 275 else if (Type == SHT_DYNAMIC) 276 DynamicSec = &Sec; 277 } 278 279 this->initStringTable(); 280 this->SoName = this->getName(); 281 282 if (!DynamicSec) 283 return; 284 auto *Begin = 285 reinterpret_cast<const Elf_Dyn *>(Obj.base() + DynamicSec->sh_offset); 286 const Elf_Dyn *End = Begin + DynamicSec->sh_size / sizeof(Elf_Dyn); 287 288 for (const Elf_Dyn &Dyn : make_range(Begin, End)) { 289 if (Dyn.d_tag == DT_SONAME) { 290 uintX_t Val = Dyn.getVal(); 291 if (Val >= this->StringTable.size()) 292 error("Invalid DT_SONAME entry"); 293 this->SoName = StringRef(this->StringTable.data() + Val); 294 return; 295 } 296 } 297 } 298 299 template <class ELFT> void SharedFile<ELFT>::parse() { 300 Elf_Sym_Range Syms = this->getNonLocalSymbols(); 301 uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); 302 SymbolBodies.reserve(NumSymbols); 303 for (const Elf_Sym &Sym : Syms) { 304 ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable); 305 error(NameOrErr.getError()); 306 StringRef Name = *NameOrErr; 307 308 if (Sym.isUndefined()) 309 Undefs.push_back(Name); 310 else 311 SymbolBodies.emplace_back(this, Name, Sym); 312 } 313 } 314 315 template <typename T> 316 static std::unique_ptr<InputFile> createELFFileAux(MemoryBufferRef MB) { 317 std::unique_ptr<T> Ret = llvm::make_unique<T>(MB); 318 319 if (!Config->FirstElf) 320 Config->FirstElf = Ret.get(); 321 322 if (Config->EKind == ELFNoneKind) { 323 Config->EKind = Ret->getELFKind(); 324 Config->EMachine = Ret->getEMachine(); 325 } 326 327 return std::move(Ret); 328 } 329 330 template <template <class> class T> 331 std::unique_ptr<InputFile> lld::elf2::createELFFile(MemoryBufferRef MB) { 332 using namespace llvm; 333 334 std::pair<unsigned char, unsigned char> Type = 335 object::getElfArchType(MB.getBuffer()); 336 if (Type.second != ELF::ELFDATA2LSB && Type.second != ELF::ELFDATA2MSB) 337 error("Invalid data encoding: " + MB.getBufferIdentifier()); 338 339 if (Type.first == ELF::ELFCLASS32) { 340 if (Type.second == ELF::ELFDATA2LSB) 341 return createELFFileAux<T<object::ELF32LE>>(MB); 342 return createELFFileAux<T<object::ELF32BE>>(MB); 343 } 344 if (Type.first == ELF::ELFCLASS64) { 345 if (Type.second == ELF::ELFDATA2LSB) 346 return createELFFileAux<T<object::ELF64LE>>(MB); 347 return createELFFileAux<T<object::ELF64BE>>(MB); 348 } 349 error("Invalid file class: " + MB.getBufferIdentifier()); 350 } 351 352 namespace lld { 353 namespace elf2 { 354 template class ELFFileBase<llvm::object::ELF32LE>; 355 template class ELFFileBase<llvm::object::ELF32BE>; 356 template class ELFFileBase<llvm::object::ELF64LE>; 357 template class ELFFileBase<llvm::object::ELF64BE>; 358 359 template class ObjectFile<llvm::object::ELF32LE>; 360 template class ObjectFile<llvm::object::ELF32BE>; 361 template class ObjectFile<llvm::object::ELF64LE>; 362 template class ObjectFile<llvm::object::ELF64BE>; 363 364 template class SharedFile<llvm::object::ELF32LE>; 365 template class SharedFile<llvm::object::ELF32BE>; 366 template class SharedFile<llvm::object::ELF64LE>; 367 template class SharedFile<llvm::object::ELF64BE>; 368 369 template std::unique_ptr<InputFile> createELFFile<ObjectFile>(MemoryBufferRef); 370 template std::unique_ptr<InputFile> createELFFile<SharedFile>(MemoryBufferRef); 371 } 372 } 373