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 std::unique_ptr<InputFile> lld::elf2::createFile(MemoryBufferRef MB) {
25   file_magic Magic = identify_magic(MB.getBuffer());
26   if (Magic == file_magic::archive)
27     return make_unique<ArchiveFile>(MB);
28   if (Magic == file_magic::elf_shared_object)
29     return createELFFile<SharedFile>(MB);
30   return createELFFile<ObjectFile>(MB);
31 }
32 
33 template <class ELFT> static uint16_t getEMachine(const ELFFileBase &B) {
34   bool IsShared = isa<SharedFileBase>(B);
35   if (IsShared)
36     return cast<SharedFile<ELFT>>(B).getEMachine();
37   return cast<ObjectFile<ELFT>>(B).getEMachine();
38 }
39 
40 uint16_t ELFFileBase::getEMachine() const {
41   switch (EKind) {
42   case ELF32BEKind:
43     return ::getEMachine<ELF32BE>(*this);
44   case ELF32LEKind:
45     return ::getEMachine<ELF32LE>(*this);
46   case ELF64BEKind:
47     return ::getEMachine<ELF64BE>(*this);
48   case ELF64LEKind:
49     return ::getEMachine<ELF64LE>(*this);
50   }
51   llvm_unreachable("Invalid kind");
52 }
53 
54 bool ELFFileBase::isCompatibleWith(const ELFFileBase &Other) const {
55   return getELFKind() == Other.getELFKind() &&
56          getEMachine() == Other.getEMachine();
57 }
58 
59 namespace {
60 class ECRAII {
61   std::error_code EC;
62 
63 public:
64   std::error_code &getEC() { return EC; }
65   ~ECRAII() { error(EC); }
66 };
67 }
68 
69 template <class ELFT>
70 ELFData<ELFT>::ELFData(MemoryBufferRef MB)
71     : ELFObj(MB.getBuffer(), ECRAII().getEC()) {}
72 
73 template <class ELFT>
74 typename ELFData<ELFT>::Elf_Sym_Range
75 ELFData<ELFT>::getSymbolsHelper(bool Local) {
76   if (!Symtab)
77     return Elf_Sym_Range(nullptr, nullptr);
78   Elf_Sym_Range Syms = ELFObj.symbols(Symtab);
79   uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
80   uint32_t FirstNonLocal = Symtab->sh_info;
81   if (FirstNonLocal > NumSymbols)
82     error("Invalid sh_info in symbol table");
83   if (!Local)
84     return make_range(Syms.begin() + FirstNonLocal, Syms.end());
85   // +1 to skip over dummy symbol.
86   return make_range(Syms.begin() + 1, Syms.begin() + FirstNonLocal);
87 }
88 
89 template <class ELFT>
90 typename ELFData<ELFT>::Elf_Sym_Range ELFData<ELFT>::getNonLocalSymbols() {
91   if (!Symtab)
92     return Elf_Sym_Range(nullptr, nullptr);
93   ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab);
94   error(StringTableOrErr.getError());
95   StringTable = *StringTableOrErr;
96   return getSymbolsHelper(false);
97 }
98 
99 template <class ELFT>
100 ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M)
101     : ObjectFileBase(getStaticELFKind<ELFT>(), M), ELFData<ELFT>(M) {}
102 
103 template <class ELFT>
104 typename ObjectFile<ELFT>::Elf_Sym_Range ObjectFile<ELFT>::getLocalSymbols() {
105   return this->getSymbolsHelper(true);
106 }
107 
108 template <class ELFT> void elf2::ObjectFile<ELFT>::parse() {
109   // Read section and symbol tables.
110   initializeSections();
111   initializeSymbols();
112 }
113 
114 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSections() {
115   uint64_t Size = this->ELFObj.getNumSections();
116   Sections.resize(Size);
117   unsigned I = 0;
118   for (const Elf_Shdr &Sec : this->ELFObj.sections()) {
119     switch (Sec.sh_type) {
120     case SHT_SYMTAB:
121       this->Symtab = &Sec;
122       break;
123     case SHT_SYMTAB_SHNDX: {
124       ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable =
125           this->ELFObj.getSHNDXTable(Sec);
126       error(ErrorOrTable);
127       SymtabSHNDX = *ErrorOrTable;
128       break;
129     }
130     case SHT_STRTAB:
131     case SHT_NULL:
132       break;
133     case SHT_RELA:
134     case SHT_REL: {
135       uint32_t RelocatedSectionIndex = Sec.sh_info;
136       if (RelocatedSectionIndex >= Size)
137         error("Invalid relocated section index");
138       InputSection<ELFT> *RelocatedSection = Sections[RelocatedSectionIndex];
139       if (!RelocatedSection)
140         error("Unsupported relocation reference");
141       RelocatedSection->RelocSections.push_back(&Sec);
142       break;
143     }
144     default:
145       Sections[I] = new (Alloc) InputSection<ELFT>(this, &Sec);
146       break;
147     }
148     ++I;
149   }
150 }
151 
152 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {
153   Elf_Sym_Range Syms = this->getNonLocalSymbols();
154   uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
155   SymbolBodies.reserve(NumSymbols);
156   for (const Elf_Sym &Sym : Syms)
157     SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym));
158 }
159 
160 template <class ELFT>
161 SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
162                                                      const Elf_Sym *Sym) {
163   ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable);
164   error(NameOrErr.getError());
165   StringRef Name = *NameOrErr;
166 
167   uint32_t SecIndex = Sym->st_shndx;
168   switch (SecIndex) {
169   case SHN_ABS:
170     return new (Alloc) DefinedAbsolute<ELFT>(Name, *Sym);
171   case SHN_UNDEF:
172     return new (Alloc) Undefined<ELFT>(Name, *Sym);
173   case SHN_COMMON:
174     return new (Alloc) DefinedCommon<ELFT>(Name, *Sym);
175   case SHN_XINDEX:
176     SecIndex = this->ELFObj.getExtendedSymbolTableIndex(Sym, this->Symtab,
177                                                         SymtabSHNDX);
178     break;
179   }
180 
181   if (SecIndex >= Sections.size() || (SecIndex != 0 && !Sections[SecIndex]))
182     error("Invalid section index");
183 
184   switch (Sym->getBinding()) {
185   default:
186     error("unexpected binding");
187   case STB_GLOBAL:
188   case STB_WEAK:
189     return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, *Sections[SecIndex]);
190   }
191 }
192 
193 void ArchiveFile::parse() {
194   ErrorOr<std::unique_ptr<Archive>> ArchiveOrErr = Archive::create(MB);
195   error(ArchiveOrErr, "Failed to parse archive");
196   File = std::move(*ArchiveOrErr);
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 template <class ELFT>
224 SharedFile<ELFT>::SharedFile(MemoryBufferRef M)
225     : SharedFileBase(getStaticELFKind<ELFT>(), M), ELFData<ELFT>(M) {}
226 
227 template <class ELFT> void SharedFile<ELFT>::parse() {
228   for (const Elf_Shdr &Sec : this->ELFObj.sections()) {
229     if (Sec.sh_type == SHT_DYNSYM) {
230       this->Symtab = &Sec;
231       break;
232     }
233   }
234 
235   Elf_Sym_Range Syms = this->getNonLocalSymbols();
236   uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
237   SymbolBodies.reserve(NumSymbols);
238   for (const Elf_Sym &Sym : Syms) {
239     if (Sym.isUndefined())
240       continue;
241 
242     ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable);
243     error(NameOrErr.getError());
244     StringRef Name = *NameOrErr;
245 
246     SymbolBodies.emplace_back(Name, Sym);
247   }
248 }
249 
250 namespace lld {
251 namespace elf2 {
252 
253 template class elf2::ObjectFile<llvm::object::ELF32LE>;
254 template class elf2::ObjectFile<llvm::object::ELF32BE>;
255 template class elf2::ObjectFile<llvm::object::ELF64LE>;
256 template class elf2::ObjectFile<llvm::object::ELF64BE>;
257 
258 template class elf2::SharedFile<llvm::object::ELF32LE>;
259 template class elf2::SharedFile<llvm::object::ELF32BE>;
260 template class elf2::SharedFile<llvm::object::ELF64LE>;
261 template class elf2::SharedFile<llvm::object::ELF64BE>;
262 }
263 }
264