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