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