blob: ed6bb838181b808c7221aa7ae3eb369de89c7a4f [file] [log] [blame]
Michael J. Spencer84487f12015-07-24 21:03:07 +00001//===- 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"
Rafael Espindola9d06ab62015-09-22 00:01:39 +000011#include "InputSection.h"
Rafael Espindola192e1fa2015-08-06 15:08:23 +000012#include "Error.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000013#include "Symbols.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000014#include "llvm/ADT/STLExtras.h"
15
Michael J. Spencer1b348a62015-09-04 22:28:10 +000016using namespace llvm;
Michael J. Spencer84487f12015-07-24 21:03:07 +000017using namespace llvm::ELF;
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000018using namespace llvm::object;
Rui Ueyamaf5c4aca2015-09-30 17:06:09 +000019using namespace llvm::sys::fs;
Michael J. Spencer84487f12015-07-24 21:03:07 +000020
21using namespace lld;
22using namespace lld::elf2;
23
Rafael Espindolae1901cc2015-09-24 15:11:50 +000024namespace {
25class ECRAII {
Michael J. Spencer84487f12015-07-24 21:03:07 +000026 std::error_code EC;
Rafael Espindolae1901cc2015-09-24 15:11:50 +000027
28public:
29 std::error_code &getEC() { return EC; }
30 ~ECRAII() { error(EC); }
31};
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000032}
33
Rafael Espindola18173d42015-09-08 15:50:05 +000034template <class ELFT>
Rafael Espindola2a4b2712015-10-13 01:17:02 +000035ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef M)
36 : InputFile(K, M), ELFObj(MB.getBuffer(), ECRAII().getEC()) {}
Rafael Espindolae1901cc2015-09-24 15:11:50 +000037
38template <class ELFT>
Rafael Espindolaaf707642015-10-12 01:55:32 +000039typename ELFFileBase<ELFT>::Elf_Sym_Range
40ELFFileBase<ELFT>::getSymbolsHelper(bool Local) {
Rafael Espindola18173d42015-09-08 15:50:05 +000041 if (!Symtab)
42 return Elf_Sym_Range(nullptr, nullptr);
Rafael Espindolae1901cc2015-09-24 15:11:50 +000043 Elf_Sym_Range Syms = ELFObj.symbols(Symtab);
Rafael Espindola18173d42015-09-08 15:50:05 +000044 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");
Davide Italiano6d328d32015-09-16 20:45:57 +000048 if (!Local)
Rui Ueyama90b3daa2015-09-30 02:37:51 +000049 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);
Davide Italiano6d328d32015-09-16 20:45:57 +000052}
53
Rafael Espindola115f0f32015-11-03 14:13:40 +000054template <class ELFT>
55uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const {
56 uint32_t Index = Sym.st_shndx;
57 if (Index == ELF::SHN_XINDEX)
58 Index = this->ELFObj.getExtendedSymbolTableIndex(&Sym, this->Symtab,
59 SymtabSHNDX);
60 else if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
61 return 0;
62
63 if (!Index)
64 error("Invalid section index");
65 return Index;
66}
67
Rafael Espindolaaf707642015-10-12 01:55:32 +000068template <class ELFT> void ELFFileBase<ELFT>::initStringTable() {
Rafael Espindola3e603792015-10-01 20:26:37 +000069 if (!Symtab)
70 return;
Rafael Espindolae1901cc2015-09-24 15:11:50 +000071 ErrorOr<StringRef> StringTableOrErr = ELFObj.getStringTableForSymtab(*Symtab);
Davide Italiano6d328d32015-09-16 20:45:57 +000072 error(StringTableOrErr.getError());
73 StringTable = *StringTableOrErr;
Rafael Espindola6a3b5de2015-10-01 19:52:48 +000074}
75
76template <class ELFT>
Rafael Espindolaaf707642015-10-12 01:55:32 +000077typename ELFFileBase<ELFT>::Elf_Sym_Range
78ELFFileBase<ELFT>::getNonLocalSymbols() {
Davide Italiano6d328d32015-09-16 20:45:57 +000079 return getSymbolsHelper(false);
80}
81
82template <class ELFT>
Rafael Espindolae1901cc2015-09-24 15:11:50 +000083ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M)
Rafael Espindola2a4b2712015-10-13 01:17:02 +000084 : ELFFileBase<ELFT>(Base::ObjectKind, M) {}
Rafael Espindolae1901cc2015-09-24 15:11:50 +000085
86template <class ELFT>
Davide Italiano6d328d32015-09-16 20:45:57 +000087typename ObjectFile<ELFT>::Elf_Sym_Range ObjectFile<ELFT>::getLocalSymbols() {
88 return this->getSymbolsHelper(true);
Rafael Espindola18173d42015-09-08 15:50:05 +000089}
90
Rafael Espindola444576d2015-10-09 19:25:07 +000091template <class ELFT>
Rui Ueyamac4aaed92015-10-22 18:49:53 +000092const typename ObjectFile<ELFT>::Elf_Sym *
93ObjectFile<ELFT>::getLocalSymbol(uintX_t SymIndex) {
94 uint32_t FirstNonLocal = this->Symtab->sh_info;
95 if (SymIndex >= FirstNonLocal)
96 return nullptr;
97 Elf_Sym_Range Syms = this->ELFObj.symbols(this->Symtab);
98 return Syms.begin() + SymIndex;
99}
100
101template <class ELFT>
Rafael Espindola444576d2015-10-09 19:25:07 +0000102void elf2::ObjectFile<ELFT>::parse(DenseSet<StringRef> &Comdats) {
Michael J. Spencer84487f12015-07-24 21:03:07 +0000103 // Read section and symbol tables.
Rafael Espindola444576d2015-10-09 19:25:07 +0000104 initializeSections(Comdats);
Michael J. Spencer84487f12015-07-24 21:03:07 +0000105 initializeSymbols();
106}
107
Rafael Espindola444576d2015-10-09 19:25:07 +0000108template <class ELFT>
109StringRef ObjectFile<ELFT>::getShtGroupSignature(const Elf_Shdr &Sec) {
110 const ELFFile<ELFT> &Obj = this->ELFObj;
111 uint32_t SymtabdSectionIndex = Sec.sh_link;
112 ErrorOr<const Elf_Shdr *> SecOrErr = Obj.getSection(SymtabdSectionIndex);
113 error(SecOrErr);
114 const Elf_Shdr *SymtabSec = *SecOrErr;
115 uint32_t SymIndex = Sec.sh_info;
116 const Elf_Sym *Sym = Obj.getSymbol(SymtabSec, SymIndex);
117 ErrorOr<StringRef> StringTableOrErr = Obj.getStringTableForSymtab(*SymtabSec);
118 error(StringTableOrErr);
119 ErrorOr<StringRef> SignatureOrErr = Sym->getName(*StringTableOrErr);
120 error(SignatureOrErr);
121 return *SignatureOrErr;
122}
123
124template <class ELFT>
125ArrayRef<typename ObjectFile<ELFT>::GroupEntryType>
126ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) {
127 const ELFFile<ELFT> &Obj = this->ELFObj;
128 ErrorOr<ArrayRef<GroupEntryType>> EntriesOrErr =
129 Obj.template getSectionContentsAsArray<GroupEntryType>(&Sec);
130 error(EntriesOrErr.getError());
131 ArrayRef<GroupEntryType> Entries = *EntriesOrErr;
132 if (Entries.empty() || Entries[0] != GRP_COMDAT)
133 error("Unsupported SHT_GROUP format");
134 return Entries.slice(1);
135}
136
137template <class ELFT>
Rafael Espindolaf82ed2a2015-10-24 22:51:01 +0000138static bool shouldMerge(const typename ELFFile<ELFT>::Elf_Shdr &Sec) {
139 typedef typename ELFFile<ELFT>::uintX_t uintX_t;
140 uintX_t Flags = Sec.sh_flags;
141 if (!(Flags & SHF_MERGE))
142 return false;
143 if (Flags & SHF_WRITE)
144 error("Writable SHF_MERGE sections are not supported");
145 uintX_t EntSize = Sec.sh_entsize;
146 if (Sec.sh_size % EntSize)
147 error("SHF_MERGE section size must be a multiple of sh_entsize");
148
149 // Don't try to merge if the aligment is larger than the sh_entsize.
150 //
151 // If this is not a SHF_STRINGS, we would need to pad after every entity. It
152 // would be equivalent for the producer of the .o to just set a larger
153 // sh_entsize.
154 //
155 // If this is a SHF_STRINGS, the larger alignment makes sense. Unfortunately
156 // it would complicate tail merging. This doesn't seem that common to
157 // justify the effort.
158 if (Sec.sh_addralign > EntSize)
159 return false;
160
161 return true;
162}
163
164template <class ELFT>
Rafael Espindola444576d2015-10-09 19:25:07 +0000165void elf2::ObjectFile<ELFT>::initializeSections(DenseSet<StringRef> &Comdats) {
Rafael Espindolae1901cc2015-09-24 15:11:50 +0000166 uint64_t Size = this->ELFObj.getNumSections();
Rafael Espindola71675852015-09-22 00:16:19 +0000167 Sections.resize(Size);
Rafael Espindola444576d2015-10-09 19:25:07 +0000168 unsigned I = -1;
Rafael Espindolad42f4e52015-10-08 12:02:38 +0000169 const ELFFile<ELFT> &Obj = this->ELFObj;
170 for (const Elf_Shdr &Sec : Obj.sections()) {
Rafael Espindola444576d2015-10-09 19:25:07 +0000171 ++I;
172 if (Sections[I] == &InputSection<ELFT>::Discarded)
173 continue;
174
Rafael Espindolacde25132015-08-13 14:45:44 +0000175 switch (Sec.sh_type) {
Rafael Espindola444576d2015-10-09 19:25:07 +0000176 case SHT_GROUP:
177 Sections[I] = &InputSection<ELFT>::Discarded;
178 if (Comdats.insert(getShtGroupSignature(Sec)).second)
179 continue;
180 for (GroupEntryType E : getShtGroupEntries(Sec)) {
181 uint32_t SecIndex = E;
182 if (SecIndex >= Size)
183 error("Invalid section index in group");
184 Sections[SecIndex] = &InputSection<ELFT>::Discarded;
185 }
186 break;
Rafael Espindolacde25132015-08-13 14:45:44 +0000187 case SHT_SYMTAB:
Rafael Espindola18173d42015-09-08 15:50:05 +0000188 this->Symtab = &Sec;
Rafael Espindolacde25132015-08-13 14:45:44 +0000189 break;
Rafael Espindola20348222015-08-24 21:43:25 +0000190 case SHT_SYMTAB_SHNDX: {
Rafael Espindolad42f4e52015-10-08 12:02:38 +0000191 ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = Obj.getSHNDXTable(Sec);
Rafael Espindola20348222015-08-24 21:43:25 +0000192 error(ErrorOrTable);
Rafael Espindola115f0f32015-11-03 14:13:40 +0000193 this->SymtabSHNDX = *ErrorOrTable;
Rafael Espindola20348222015-08-24 21:43:25 +0000194 break;
195 }
Rafael Espindolacde25132015-08-13 14:45:44 +0000196 case SHT_STRTAB:
197 case SHT_NULL:
Rafael Espindolacde25132015-08-13 14:45:44 +0000198 break;
Michael J. Spencer67bc8d62015-08-27 23:15:56 +0000199 case SHT_RELA:
200 case SHT_REL: {
201 uint32_t RelocatedSectionIndex = Sec.sh_info;
202 if (RelocatedSectionIndex >= Size)
203 error("Invalid relocated section index");
Rafael Espindolac159c962015-10-19 21:00:02 +0000204 InputSectionBase<ELFT> *RelocatedSection =
205 Sections[RelocatedSectionIndex];
Michael J. Spencer67bc8d62015-08-27 23:15:56 +0000206 if (!RelocatedSection)
207 error("Unsupported relocation reference");
Rafael Espindolac159c962015-10-19 21:00:02 +0000208 if (auto *S = dyn_cast<InputSection<ELFT>>(RelocatedSection))
209 S->RelocSections.push_back(&Sec);
210 else
211 error("Relocations pointing to SHF_MERGE are not supported");
Michael J. Spencer67bc8d62015-08-27 23:15:56 +0000212 break;
213 }
Rafael Espindolaf82ed2a2015-10-24 22:51:01 +0000214 default:
215 if (shouldMerge<ELFT>(Sec))
Rafael Espindolac159c962015-10-19 21:00:02 +0000216 Sections[I] = new (this->Alloc) MergeInputSection<ELFT>(this, &Sec);
Rafael Espindolaf82ed2a2015-10-24 22:51:01 +0000217 else
Rafael Espindolac159c962015-10-19 21:00:02 +0000218 Sections[I] = new (this->Alloc) InputSection<ELFT>(this, &Sec);
Rafael Espindolacde25132015-08-13 14:45:44 +0000219 break;
Michael J. Spencer84487f12015-07-24 21:03:07 +0000220 }
221 }
222}
223
224template <class ELFT> void elf2::ObjectFile<ELFT>::initializeSymbols() {
Rafael Espindola6a3b5de2015-10-01 19:52:48 +0000225 this->initStringTable();
Rafael Espindola18173d42015-09-08 15:50:05 +0000226 Elf_Sym_Range Syms = this->getNonLocalSymbols();
Reid Klecknerf7b85e02015-08-11 20:06:51 +0000227 uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
Rafael Espindolaaf707642015-10-12 01:55:32 +0000228 this->SymbolBodies.reserve(NumSymbols);
Rafael Espindola30318512015-08-04 14:00:56 +0000229 for (const Elf_Sym &Sym : Syms)
Rafael Espindolaaf707642015-10-12 01:55:32 +0000230 this->SymbolBodies.push_back(createSymbolBody(this->StringTable, &Sym));
Michael J. Spencer84487f12015-07-24 21:03:07 +0000231}
232
233template <class ELFT>
Rafael Espindolac159c962015-10-19 21:00:02 +0000234InputSectionBase<ELFT> *
Rafael Espindola4cda5812015-10-16 15:29:48 +0000235elf2::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const {
Rafael Espindola115f0f32015-11-03 14:13:40 +0000236 uint32_t Index = this->getSectionIndex(Sym);
237 if (Index == 0)
Rafael Espindola4cda5812015-10-16 15:29:48 +0000238 return nullptr;
Rafael Espindola115f0f32015-11-03 14:13:40 +0000239 if (Index >= Sections.size() || !Sections[Index])
Rafael Espindola4cda5812015-10-16 15:29:48 +0000240 error("Invalid section index");
241 return Sections[Index];
242}
243
244template <class ELFT>
Michael J. Spencer84487f12015-07-24 21:03:07 +0000245SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
246 const Elf_Sym *Sym) {
247 ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable);
248 error(NameOrErr.getError());
249 StringRef Name = *NameOrErr;
Rafael Espindola20348222015-08-24 21:43:25 +0000250
Rafael Espindola4cda5812015-10-16 15:29:48 +0000251 switch (Sym->st_shndx) {
Rafael Espindola51d46902015-08-28 21:26:51 +0000252 case SHN_ABS:
Rafael Espindolaaf707642015-10-12 01:55:32 +0000253 return new (this->Alloc) DefinedAbsolute<ELFT>(Name, *Sym);
Rafael Espindola51d46902015-08-28 21:26:51 +0000254 case SHN_UNDEF:
Rafael Espindolaaf707642015-10-12 01:55:32 +0000255 return new (this->Alloc) Undefined<ELFT>(Name, *Sym);
Rafael Espindola51d46902015-08-28 21:26:51 +0000256 case SHN_COMMON:
Rafael Espindolaaf707642015-10-12 01:55:32 +0000257 return new (this->Alloc) DefinedCommon<ELFT>(Name, *Sym);
Rafael Espindola51d46902015-08-28 21:26:51 +0000258 }
Rafael Espindola20348222015-08-24 21:43:25 +0000259
Rafael Espindolab13df652015-08-11 17:33:02 +0000260 switch (Sym->getBinding()) {
261 default:
262 error("unexpected binding");
263 case STB_GLOBAL:
Rafael Espindola3a63f3f2015-08-28 20:19:34 +0000264 case STB_WEAK:
Rafael Espindola444576d2015-10-09 19:25:07 +0000265 case STB_GNU_UNIQUE: {
Rafael Espindolac159c962015-10-19 21:00:02 +0000266 InputSectionBase<ELFT> *Sec = getSection(*Sym);
Rafael Espindola444576d2015-10-09 19:25:07 +0000267 if (Sec == &InputSection<ELFT>::Discarded)
Rafael Espindolaaf707642015-10-12 01:55:32 +0000268 return new (this->Alloc) Undefined<ELFT>(Name, *Sym);
269 return new (this->Alloc) DefinedRegular<ELFT>(Name, *Sym, *Sec);
Rafael Espindola444576d2015-10-09 19:25:07 +0000270 }
Rafael Espindolab13df652015-08-11 17:33:02 +0000271 }
Michael J. Spencer84487f12015-07-24 21:03:07 +0000272}
273
Igor Kudrin2696bbe2015-10-01 18:02:21 +0000274static std::unique_ptr<Archive> openArchive(MemoryBufferRef MB) {
Rui Ueyamad0e5aeb2015-09-30 02:42:27 +0000275 ErrorOr<std::unique_ptr<Archive>> ArchiveOrErr = Archive::create(MB);
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000276 error(ArchiveOrErr, "Failed to parse archive");
Igor Kudrin2696bbe2015-10-01 18:02:21 +0000277 return std::move(*ArchiveOrErr);
278}
279
280void ArchiveFile::parse() {
281 File = openArchive(MB);
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000282
283 // Allocate a buffer for Lazy objects.
284 size_t NumSyms = File->getNumberOfSymbols();
285 LazySymbols.reserve(NumSyms);
286
287 // Read the symbol table to construct Lazy objects.
288 for (const Archive::Symbol &Sym : File->symbols())
289 LazySymbols.emplace_back(this, Sym);
290}
291
292// Returns a buffer pointing to a member file containing a given symbol.
293MemoryBufferRef ArchiveFile::getMember(const Archive::Symbol *Sym) {
Rafael Espindola8f3a6ae2015-11-05 14:40:28 +0000294 ErrorOr<Archive::Child> COrErr = Sym->getMember();
295 error(COrErr, "Could not get the member for symbol " + Sym->getName());
296 const Archive::Child &C = *COrErr;
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000297
Rafael Espindola8f3a6ae2015-11-05 14:40:28 +0000298 if (!Seen.insert(C.getChildOffset()).second)
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000299 return MemoryBufferRef();
Michael J. Spencer88f0d632015-09-08 20:36:20 +0000300
Rafael Espindola8f3a6ae2015-11-05 14:40:28 +0000301 ErrorOr<MemoryBufferRef> Ret = C.getMemoryBufferRef();
Rui Ueyama1c42afc2015-10-12 15:49:06 +0000302 error(Ret, "Could not get the buffer for the member defining symbol " +
Michael J. Spencer1b348a62015-09-04 22:28:10 +0000303 Sym->getName());
304 return *Ret;
305}
306
Igor Kudrin2696bbe2015-10-01 18:02:21 +0000307std::vector<MemoryBufferRef> ArchiveFile::getMembers() {
308 File = openArchive(MB);
309
310 std::vector<MemoryBufferRef> Result;
311 for (const Archive::Child &Child : File->children()) {
312 ErrorOr<MemoryBufferRef> MbOrErr = Child.getMemoryBufferRef();
Rui Ueyama1c42afc2015-10-12 15:49:06 +0000313 error(MbOrErr, "Could not get the buffer for a child of the archive " +
314 File->getFileName());
Igor Kudrin2696bbe2015-10-01 18:02:21 +0000315 Result.push_back(MbOrErr.get());
316 }
317 return Result;
318}
319
Rafael Espindolae1901cc2015-09-24 15:11:50 +0000320template <class ELFT>
321SharedFile<ELFT>::SharedFile(MemoryBufferRef M)
Rafael Espindola2a4b2712015-10-13 01:17:02 +0000322 : ELFFileBase<ELFT>(Base::SharedKind, M) {
Rafael Espindoladfce5a22015-10-12 02:22:58 +0000323 AsNeeded = Config->AsNeeded;
324}
Rafael Espindola18173d42015-09-08 15:50:05 +0000325
Rafael Espindola115f0f32015-11-03 14:13:40 +0000326template <class ELFT>
327const typename ELFFile<ELFT>::Elf_Shdr *
328SharedFile<ELFT>::getSection(const Elf_Sym &Sym) const {
329 uint32_t Index = this->getSectionIndex(Sym);
330 if (Index == 0)
331 return nullptr;
332 ErrorOr<const Elf_Shdr *> Ret = this->ELFObj.getSection(Index);
333 error(Ret);
334 return *Ret;
335}
336
Rafael Espindola6a3b5de2015-10-01 19:52:48 +0000337template <class ELFT> void SharedFile<ELFT>::parseSoName() {
Rafael Espindolac8b15812015-10-01 15:47:50 +0000338 typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn;
339 typedef typename ELFFile<ELFT>::uintX_t uintX_t;
340 const Elf_Shdr *DynamicSec = nullptr;
341
342 const ELFFile<ELFT> Obj = this->ELFObj;
343 for (const Elf_Shdr &Sec : Obj.sections()) {
Rafael Espindola115f0f32015-11-03 14:13:40 +0000344 switch (Sec.sh_type) {
345 default:
346 continue;
347 case SHT_DYNSYM:
Rafael Espindola18173d42015-09-08 15:50:05 +0000348 this->Symtab = &Sec;
Rafael Espindola115f0f32015-11-03 14:13:40 +0000349 break;
350 case SHT_DYNAMIC:
Rafael Espindolac8b15812015-10-01 15:47:50 +0000351 DynamicSec = &Sec;
Rafael Espindola115f0f32015-11-03 14:13:40 +0000352 break;
353 case SHT_SYMTAB_SHNDX: {
354 ErrorOr<ArrayRef<Elf_Word>> ErrorOrTable = Obj.getSHNDXTable(Sec);
355 error(ErrorOrTable);
356 this->SymtabSHNDX = *ErrorOrTable;
357 break;
358 }
359 }
Rafael Espindolac8b15812015-10-01 15:47:50 +0000360 }
361
Rafael Espindola6a3b5de2015-10-01 19:52:48 +0000362 this->initStringTable();
Rafael Espindolaaf707642015-10-12 01:55:32 +0000363 this->SoName = this->getName();
Rafael Espindolac8b15812015-10-01 15:47:50 +0000364
Rui Ueyama361d8b92015-10-12 15:49:02 +0000365 if (!DynamicSec)
366 return;
367 auto *Begin =
368 reinterpret_cast<const Elf_Dyn *>(Obj.base() + DynamicSec->sh_offset);
369 const Elf_Dyn *End = Begin + DynamicSec->sh_size / sizeof(Elf_Dyn);
Rafael Espindolac8b15812015-10-01 15:47:50 +0000370
Rui Ueyama361d8b92015-10-12 15:49:02 +0000371 for (const Elf_Dyn &Dyn : make_range(Begin, End)) {
372 if (Dyn.d_tag == DT_SONAME) {
373 uintX_t Val = Dyn.getVal();
374 if (Val >= this->StringTable.size())
375 error("Invalid DT_SONAME entry");
376 this->SoName = StringRef(this->StringTable.data() + Val);
377 return;
Rafael Espindola18173d42015-09-08 15:50:05 +0000378 }
379 }
Rafael Espindola6a3b5de2015-10-01 19:52:48 +0000380}
Rafael Espindola18173d42015-09-08 15:50:05 +0000381
Rafael Espindola6a3b5de2015-10-01 19:52:48 +0000382template <class ELFT> void SharedFile<ELFT>::parse() {
383 Elf_Sym_Range Syms = this->getNonLocalSymbols();
Rafael Espindola18173d42015-09-08 15:50:05 +0000384 uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
385 SymbolBodies.reserve(NumSymbols);
386 for (const Elf_Sym &Sym : Syms) {
Rafael Espindola18173d42015-09-08 15:50:05 +0000387 ErrorOr<StringRef> NameOrErr = Sym.getName(this->StringTable);
388 error(NameOrErr.getError());
389 StringRef Name = *NameOrErr;
390
Rui Ueyamaf8432d92015-10-13 16:34:14 +0000391 if (Sym.isUndefined())
392 Undefs.push_back(Name);
393 else
394 SymbolBodies.emplace_back(this, Name, Sym);
Rafael Espindola18173d42015-09-08 15:50:05 +0000395 }
396}
Rafael Espindolaf98d6d82015-09-03 20:03:54 +0000397
Rui Ueyamac4b65062015-10-12 15:31:09 +0000398template <typename T>
399static std::unique_ptr<InputFile> createELFFileAux(MemoryBufferRef MB) {
400 std::unique_ptr<T> Ret = llvm::make_unique<T>(MB);
401
402 if (!Config->FirstElf)
403 Config->FirstElf = Ret.get();
404
Rui Ueyamae717a712015-10-13 16:20:50 +0000405 if (Config->EKind == ELFNoneKind) {
406 Config->EKind = Ret->getELFKind();
Rui Ueyamac4b65062015-10-12 15:31:09 +0000407 Config->EMachine = Ret->getEMachine();
408 }
409
410 return std::move(Ret);
411}
412
413template <template <class> class T>
414std::unique_ptr<InputFile> lld::elf2::createELFFile(MemoryBufferRef MB) {
415 using namespace llvm;
416
417 std::pair<unsigned char, unsigned char> Type =
418 object::getElfArchType(MB.getBuffer());
419 if (Type.second != ELF::ELFDATA2LSB && Type.second != ELF::ELFDATA2MSB)
420 error("Invalid data encoding: " + MB.getBufferIdentifier());
421
422 if (Type.first == ELF::ELFCLASS32) {
423 if (Type.second == ELF::ELFDATA2LSB)
424 return createELFFileAux<T<object::ELF32LE>>(MB);
425 return createELFFileAux<T<object::ELF32BE>>(MB);
426 }
427 if (Type.first == ELF::ELFCLASS64) {
428 if (Type.second == ELF::ELFDATA2LSB)
429 return createELFFileAux<T<object::ELF64LE>>(MB);
430 return createELFFileAux<T<object::ELF64BE>>(MB);
431 }
432 error("Invalid file class: " + MB.getBufferIdentifier());
433}
434
Michael J. Spencer84487f12015-07-24 21:03:07 +0000435namespace lld {
436namespace elf2 {
Rafael Espindolaaf707642015-10-12 01:55:32 +0000437template class ELFFileBase<llvm::object::ELF32LE>;
438template class ELFFileBase<llvm::object::ELF32BE>;
439template class ELFFileBase<llvm::object::ELF64LE>;
440template class ELFFileBase<llvm::object::ELF64BE>;
Davide Italiano6d328d32015-09-16 20:45:57 +0000441
Rui Ueyama2ee8e112015-10-12 15:27:09 +0000442template class ObjectFile<llvm::object::ELF32LE>;
443template class ObjectFile<llvm::object::ELF32BE>;
444template class ObjectFile<llvm::object::ELF64LE>;
445template class ObjectFile<llvm::object::ELF64BE>;
Rafael Espindolaf98d6d82015-09-03 20:03:54 +0000446
Rui Ueyama2ee8e112015-10-12 15:27:09 +0000447template class SharedFile<llvm::object::ELF32LE>;
448template class SharedFile<llvm::object::ELF32BE>;
449template class SharedFile<llvm::object::ELF64LE>;
450template class SharedFile<llvm::object::ELF64BE>;
Rui Ueyamac4b65062015-10-12 15:31:09 +0000451
452template std::unique_ptr<InputFile> createELFFile<ObjectFile>(MemoryBufferRef);
453template std::unique_ptr<InputFile> createELFFile<SharedFile>(MemoryBufferRef);
Michael J. Spencer84487f12015-07-24 21:03:07 +0000454}
455}