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