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 template <class ELFT> static uint16_t getEMachine(const ELFFileBase &B) { 25 bool IsShared = isa<SharedFileBase>(B); 26 if (IsShared) 27 return cast<SharedFile<ELFT>>(B).getEMachine(); 28 return cast<ObjectFile<ELFT>>(B).getEMachine(); 29 } 30 31 uint16_t ELFFileBase::getEMachine() const { 32 switch (EKind) { 33 case ELF32BEKind: 34 return ::getEMachine<ELF32BE>(*this); 35 case ELF32LEKind: 36 return ::getEMachine<ELF32LE>(*this); 37 case ELF64BEKind: 38 return ::getEMachine<ELF64BE>(*this); 39 case ELF64LEKind: 40 return ::getEMachine<ELF64LE>(*this); 41 } 42 llvm_unreachable("Invalid kind"); 43 } 44 45 bool ELFFileBase::isCompatibleWith(const ELFFileBase &Other) const { 46 return getELFKind() == Other.getELFKind() && 47 getEMachine() == Other.getEMachine(); 48 } 49 50 namespace { 51 class ECRAII { 52 std::error_code EC; 53 54 public: 55 std::error_code &getEC() { return EC; } 56 ~ECRAII() { error(EC); } 57 }; 58 } 59 60 template <class ELFT> 61 ELFData<ELFT>::ELFData(MemoryBufferRef MB) 62 : ELFObj(MB.getBuffer(), ECRAII().getEC()) {} 63 64 template <class ELFT> 65 typename ELFData<ELFT>::Elf_Sym_Range 66 ELFData<ELFT>::getSymbolsHelper(bool Local) { 67 if (!Symtab) 68 return Elf_Sym_Range(nullptr, nullptr); 69 Elf_Sym_Range Syms = ELFObj.symbols(Symtab); 70 uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); 71 uint32_t FirstNonLocal = Symtab->sh_info; 72 if (FirstNonLocal > NumSymbols) 73 error("Invalid sh_info in symbol table"); 74 if (!Local) 75 return make_range(Syms.begin() + FirstNonLocal, Syms.end()); 76 // +1 to skip over dummy symbol. 77 return make_range(Syms.begin() + 1, Syms.begin() + FirstNonLocal); 78 } 79 80 template <class ELFT> void ELFData<ELFT>::initStringTable() { 81 if (!Symtab) 82 return; 83 ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab); 84 error(StringTableOrErr.getError()); 85 StringTable = *StringTableOrErr; 86 } 87 88 template <class ELFT> 89 typename ELFData<ELFT>::Elf_Sym_Range ELFData<ELFT>::getNonLocalSymbols() { 90 return getSymbolsHelper(false); 91 } 92 93 template <class ELFT> 94 ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M) 95 : ObjectFileBase(getStaticELFKind<ELFT>(), M), ELFData<ELFT>(M) {} 96 97 template <class ELFT> 98 typename ObjectFile<ELFT>::Elf_Sym_Range ObjectFile<ELFT>::getLocalSymbols() { 99 return this->getSymbolsHelper(true); 100 } 101 102 template <class ELFT> void elf2::ObjectFile<ELFT>::parse() { 103 // Read section and symbol tables. 104 initializeSections(); 105 initializeSymbols(); 106 } 107 108 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSections() { 109 uint64_t Size = this->ELFObj.getNumSections(); 110 Sections.resize(Size); 111 unsigned I = 0; 112 for (const Elf_Shdr &Sec : this->ELFObj.sections()) { 113 switch (Sec.sh_type) { 114 case SHT_SYMTAB: 115 this->Symtab = &Sec; 116 break; 117 case SHT_SYMTAB_SHNDX: { 118 ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = 119 this->ELFObj.getSHNDXTable(Sec); 120 error(ErrorOrTable); 121 SymtabSHNDX = *ErrorOrTable; 122 break; 123 } 124 case SHT_STRTAB: 125 case SHT_NULL: 126 break; 127 case SHT_RELA: 128 case SHT_REL: { 129 uint32_t RelocatedSectionIndex = Sec.sh_info; 130 if (RelocatedSectionIndex >= Size) 131 error("Invalid relocated section index"); 132 InputSection<ELFT> *RelocatedSection = Sections[RelocatedSectionIndex]; 133 if (!RelocatedSection) 134 error("Unsupported relocation reference"); 135 RelocatedSection->RelocSections.push_back(&Sec); 136 break; 137 } 138 default: 139 Sections[I] = new (Alloc) InputSection<ELFT>(this, &Sec); 140 break; 141 } 142 ++I; 143 } 144 } 145 146 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() { 147 this->initStringTable(); 148 Elf_Sym_Range Syms = this->getNonLocalSymbols(); 149 uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); 150 SymbolBodies.reserve(NumSymbols); 151 for (const Elf_Sym &Sym : Syms) 152 SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym)); 153 } 154 155 template <class ELFT> 156 SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable, 157 const Elf_Sym *Sym) { 158 ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable); 159 error(NameOrErr.getError()); 160 StringRef Name = *NameOrErr; 161 162 uint32_t SecIndex = Sym->st_shndx; 163 switch (SecIndex) { 164 case SHN_ABS: 165 return new (Alloc) DefinedAbsolute<ELFT>(Name, *Sym); 166 case SHN_UNDEF: 167 return new (Alloc) Undefined<ELFT>(Name, *Sym); 168 case SHN_COMMON: 169 return new (Alloc) DefinedCommon<ELFT>(Name, *Sym); 170 case SHN_XINDEX: 171 SecIndex = this->ELFObj.getExtendedSymbolTableIndex(Sym, this->Symtab, 172 SymtabSHNDX); 173 break; 174 } 175 176 if (SecIndex >= Sections.size() || (SecIndex != 0 && !Sections[SecIndex])) 177 error("Invalid section index"); 178 179 switch (Sym->getBinding()) { 180 default: 181 error("unexpected binding"); 182 case STB_GLOBAL: 183 case STB_WEAK: 184 case STB_GNU_UNIQUE: 185 return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, *Sections[SecIndex]); 186 } 187 } 188 189 static std::unique_ptr<Archive> openArchive(MemoryBufferRef MB) { 190 ErrorOr<std::unique_ptr<Archive>> ArchiveOrErr = Archive::create(MB); 191 error(ArchiveOrErr, "Failed to parse archive"); 192 return std::move(*ArchiveOrErr); 193 } 194 195 void ArchiveFile::parse() { 196 File = openArchive(MB); 197 198 // Allocate a buffer for Lazy objects. 199 size_t NumSyms = File->getNumberOfSymbols(); 200 LazySymbols.reserve(NumSyms); 201 202 // Read the symbol table to construct Lazy objects. 203 for (const Archive::Symbol &Sym : File->symbols()) 204 LazySymbols.emplace_back(this, Sym); 205 } 206 207 // Returns a buffer pointing to a member file containing a given symbol. 208 MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) { 209 ErrorOr<Archive::child_iterator> ItOrErr = Sym->getMember(); 210 error(ItOrErr, 211 Twine("Could not get the member for symbol ") + Sym->getName()); 212 Archive::child_iterator It = *ItOrErr; 213 214 if (!Seen.insert(It->getChildOffset()).second) 215 return MemoryBufferRef(); 216 217 ErrorOr<MemoryBufferRef> Ret = It->getMemoryBufferRef(); 218 error(Ret, Twine("Could not get the buffer for the member defining symbol ") + 219 Sym->getName()); 220 return *Ret; 221 } 222 223 std::vector<MemoryBufferRef> ArchiveFile::getMembers() { 224 File = openArchive(MB); 225 226 std::vector<MemoryBufferRef> Result; 227 for (const Archive::Child &Child : File->children()) { 228 ErrorOr<MemoryBufferRef> MbOrErr = Child.getMemoryBufferRef(); 229 error(MbOrErr, 230 Twine("Could not get the buffer for a child of the archive ") + 231 File->getFileName()); 232 Result.push_back(MbOrErr.get()); 233 } 234 return Result; 235 } 236 237 template <class ELFT> 238 SharedFile<ELFT>::SharedFile(MemoryBufferRef M) 239 : SharedFileBase(getStaticELFKind<ELFT>(), M), ELFData<ELFT>(M) {} 240 241 template <class ELFT> void SharedFile<ELFT>::parseSoName() { 242 typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn; 243 typedef typename ELFFile<ELFT>::uintX_t uintX_t; 244 const Elf_Shdr *DynamicSec = nullptr; 245 246 const ELFFile<ELFT> Obj = this->ELFObj; 247 for (const Elf_Shdr &Sec : Obj.sections()) { 248 uint32_t Type = Sec.sh_type; 249 if (Type == SHT_DYNSYM) 250 this->Symtab = &Sec; 251 else if (Type == SHT_DYNAMIC) 252 DynamicSec = &Sec; 253 } 254 255 this->initStringTable(); 256 SoName = getName(); 257 258 if (DynamicSec) { 259 auto *Begin = 260 reinterpret_cast<const Elf_Dyn *>(Obj.base() + DynamicSec->sh_offset); 261 const Elf_Dyn *End = Begin + DynamicSec->sh_size / sizeof(Elf_Dyn); 262 263 for (const Elf_Dyn &Dyn : make_range(Begin, End)) { 264 if (Dyn.d_tag == DT_SONAME) { 265 uintX_t Val = Dyn.getVal(); 266 if (Val >= this->StringTable.size()) 267 error("Invalid DT_SONAME entry"); 268 SoName = StringRef(this->StringTable.data() + Val); 269 break; 270 } 271 } 272 } 273 } 274 275 template <class ELFT> void SharedFile<ELFT>::parse() { 276 Elf_Sym_Range Syms = this->getNonLocalSymbols(); 277 uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end()); 278 SymbolBodies.reserve(NumSymbols); 279 for (const Elf_Sym &Sym : Syms) { 280 if (Sym.isUndefined()) 281 continue; 282 283 ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable); 284 error(NameOrErr.getError()); 285 StringRef Name = *NameOrErr; 286 287 SymbolBodies.emplace_back(Name, Sym); 288 } 289 } 290 291 namespace lld { 292 namespace elf2 { 293 294 template class elf2::ObjectFile<llvm::object::ELF32LE>; 295 template class elf2::ObjectFile<llvm::object::ELF32BE>; 296 template class elf2::ObjectFile<llvm::object::ELF64LE>; 297 template class elf2::ObjectFile<llvm::object::ELF64BE>; 298 299 template class elf2::SharedFile<llvm::object::ELF32LE>; 300 template class elf2::SharedFile<llvm::object::ELF32BE>; 301 template class elf2::SharedFile<llvm::object::ELF64LE>; 302 template class elf2::SharedFile<llvm::object::ELF64BE>; 303 } 304 } 305