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
59 ELFData<ELFT>::getSymbolsHelper(bool Local) {
60   if (!Symtab)
61     return Elf_Sym_Range(nullptr, nullptr);
62   Elf_Sym_Range Syms = ELFObj->symbols(Symtab);
63   uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
64   uint32_t FirstNonLocal = Symtab->sh_info;
65   if (FirstNonLocal > NumSymbols)
66     error("Invalid sh_info in symbol table");
67   if (!Local)
68     return llvm::make_range(Syms.begin() + FirstNonLocal, Syms.end());
69   else
70     // Skip over dummy symbol.
71     return llvm::make_range(Syms.begin() + 1, Syms.begin() + FirstNonLocal);
72 }
73 
74 template <class ELFT>
75 typename ELFData<ELFT>::Elf_Sym_Range ELFData<ELFT>::getNonLocalSymbols() {
76   if (!Symtab)
77     return Elf_Sym_Range(nullptr, nullptr);
78   ErrorOr<StringRef> StringTableOrErr =
79       ELFObj->getStringTableForSymtab(*Symtab);
80   error(StringTableOrErr.getError());
81   StringTable = *StringTableOrErr;
82   return getSymbolsHelper(false);
83 }
84 
85 template <class ELFT>
86 typename ObjectFile<ELFT>::Elf_Sym_Range ObjectFile<ELFT>::getLocalSymbols() {
87   return this->getSymbolsHelper(true);
88 }
89 
90 template <class ELFT> void elf2::ObjectFile<ELFT>::parse() {
91   this->openELF(MB);
92 
93   // Read section and symbol tables.
94   initializeChunks();
95   initializeSymbols();
96 }
97 
98 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeChunks() {
99   uint64_t Size = this->ELFObj->getNumSections();
100   Chunks.resize(Size);
101   unsigned I = 0;
102   for (const Elf_Shdr &Sec : this->ELFObj->sections()) {
103     switch (Sec.sh_type) {
104     case SHT_SYMTAB:
105       this->Symtab = &Sec;
106       break;
107     case SHT_SYMTAB_SHNDX: {
108       ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable =
109           this->ELFObj->getSHNDXTable(Sec);
110       error(ErrorOrTable);
111       SymtabSHNDX = *ErrorOrTable;
112       break;
113     }
114     case SHT_STRTAB:
115     case SHT_NULL:
116       break;
117     case SHT_RELA:
118     case SHT_REL: {
119       uint32_t RelocatedSectionIndex = Sec.sh_info;
120       if (RelocatedSectionIndex >= Size)
121         error("Invalid relocated section index");
122       InputSection<ELFT> *RelocatedSection = Chunks[RelocatedSectionIndex];
123       if (!RelocatedSection)
124         error("Unsupported relocation reference");
125       RelocatedSection->RelocSections.push_back(&Sec);
126       break;
127     }
128     default:
129       Chunks[I] = new (Alloc) InputSection<ELFT>(this, &Sec);
130       break;
131     }
132     ++I;
133   }
134 }
135 
136 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {
137   Elf_Sym_Range Syms = this->getNonLocalSymbols();
138   uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
139   SymbolBodies.reserve(NumSymbols);
140   for (const Elf_Sym &Sym : Syms)
141     SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym));
142 }
143 
144 template <class ELFT>
145 SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
146                                                      const Elf_Sym *Sym) {
147   ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable);
148   error(NameOrErr.getError());
149   StringRef Name = *NameOrErr;
150 
151   uint32_t SecIndex = Sym->st_shndx;
152   switch (SecIndex) {
153   case SHN_ABS:
154     return new (Alloc) DefinedAbsolute<ELFT>(Name, *Sym);
155   case SHN_UNDEF:
156     return new (Alloc) Undefined<ELFT>(Name, *Sym);
157   case SHN_COMMON:
158     return new (Alloc) DefinedCommon<ELFT>(Name, *Sym);
159   case SHN_XINDEX:
160     SecIndex = this->ELFObj->getExtendedSymbolTableIndex(Sym, this->Symtab,
161                                                          SymtabSHNDX);
162     break;
163   }
164 
165   if (SecIndex >= Chunks.size() ||
166       (SecIndex != 0 && !Chunks[SecIndex]))
167     error("Invalid section index");
168 
169   switch (Sym->getBinding()) {
170   default:
171     error("unexpected binding");
172   case STB_GLOBAL:
173   case STB_WEAK:
174     return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, *Chunks[SecIndex]);
175   }
176 }
177 
178 void ArchiveFile::parse() {
179   auto ArchiveOrErr = Archive::create(MB);
180   error(ArchiveOrErr, "Failed to parse archive");
181   File = std::move(*ArchiveOrErr);
182 
183   // Allocate a buffer for Lazy objects.
184   size_t NumSyms = File->getNumberOfSymbols();
185   LazySymbols.reserve(NumSyms);
186 
187   // Read the symbol table to construct Lazy objects.
188   for (const Archive::Symbol &Sym : File->symbols())
189     LazySymbols.emplace_back(this, Sym);
190 }
191 
192 // Returns a buffer pointing to a member file containing a given symbol.
193 MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) {
194   ErrorOr<Archive::child_iterator> ItOrErr = Sym->getMember();
195   error(ItOrErr,
196         Twine("Could not get the member for symbol ") + Sym->getName());
197   Archive::child_iterator It = *ItOrErr;
198 
199   if (!Seen.insert(It->getChildOffset()).second)
200     return MemoryBufferRef();
201 
202   ErrorOr<MemoryBufferRef> Ret = It->getMemoryBufferRef();
203   error(Ret, Twine("Could not get the buffer for the member defining symbol ") +
204                  Sym->getName());
205   return *Ret;
206 }
207 
208 template <class ELFT> void SharedFile<ELFT>::parse() {
209   this->openELF(MB);
210 
211   for (const Elf_Shdr &Sec : this->ELFObj->sections()) {
212     if (Sec.sh_type == SHT_DYNSYM) {
213       this->Symtab = &Sec;
214       break;
215     }
216   }
217 
218   Elf_Sym_Range Syms = this->getNonLocalSymbols();
219   uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
220   SymbolBodies.reserve(NumSymbols);
221   for (const Elf_Sym &Sym : Syms) {
222     if (Sym.isUndefined())
223       continue;
224 
225     ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable);
226     error(NameOrErr.getError());
227     StringRef Name = *NameOrErr;
228 
229     SymbolBodies.emplace_back(Name, Sym);
230   }
231 }
232 
233 namespace lld {
234 namespace elf2 {
235 
236 template class elf2::ObjectFile<llvm::object::ELF32LE>;
237 template class elf2::ObjectFile<llvm::object::ELF32BE>;
238 template class elf2::ObjectFile<llvm::object::ELF64LE>;
239 template class elf2::ObjectFile<llvm::object::ELF64BE>;
240 
241 template class elf2::SharedFile<llvm::object::ELF32LE>;
242 template class elf2::SharedFile<llvm::object::ELF32BE>;
243 template class elf2::SharedFile<llvm::object::ELF64LE>;
244 template class elf2::SharedFile<llvm::object::ELF64BE>;
245 }
246 }
247