blob: 9b15b2a5bc576152916c478ba2277c8f17471bbb [file] [log] [blame]
Nick Kledzikabb69812012-05-31 22:34:00 +00001//===- lib/ReaderWriter/ELF/ReaderELF.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//===----------------------------------------------------------------------===//
Sid Manning1a601412012-07-25 16:27:21 +00009//
10// This file contains the ELF Reader and all helper sub classes
11// to consume an ELF file and produces atoms out of it.
12//
13//===----------------------------------------------------------------------===//
Nick Kledzikabb69812012-05-31 22:34:00 +000014
15#include "lld/ReaderWriter/ReaderELF.h"
16#include "lld/Core/File.h"
17
Sid Manning1a601412012-07-25 16:27:21 +000018#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/Object/ELF.h"
21#include "llvm/Object/ObjectFile.h"
22#include "llvm/Support/Allocator.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000023#include "llvm/Support/Casting.h"
Sid Manning1a601412012-07-25 16:27:21 +000024#include "llvm/Support/ELF.h"
25#include "llvm/Support/Endian.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000026#include "llvm/Support/ErrorHandling.h"
Sid Manning1a601412012-07-25 16:27:21 +000027#include "llvm/Support/MathExtras.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000028#include "llvm/Support/Memory.h"
29#include "llvm/Support/MemoryBuffer.h"
30#include "llvm/Support/raw_ostream.h"
31#include "llvm/Support/system_error.h"
32
Sid Manning1a601412012-07-25 16:27:21 +000033
Nick Kledzikabb69812012-05-31 22:34:00 +000034#include <map>
35#include <vector>
36
Sid Manning1a601412012-07-25 16:27:21 +000037using llvm::object::Elf_Sym_Impl;
38using namespace lld;
39
40namespace { // anonymous
41
42// This atom class corresponds to absolute symbol
43class ELFAbsoluteAtom: public AbsoluteAtom {
44
45public:
46 ELFAbsoluteAtom(const File &F,
47 llvm::StringRef N,
48 uint64_t V)
49 : OwningFile(F)
50 , Name(N)
51 , Value(V)
52 {}
53
54 virtual const class File &file() const {
55 return OwningFile;
56 }
57
58 virtual llvm::StringRef name() const {
59 return Name;
60 }
61
62 virtual uint64_t value() const {
63 return Value;
64 }
65
66private:
67 const File &OwningFile;
68 llvm::StringRef Name;
69 uint64_t Value;
70};
71
72
73// This atom corresponds to undefined symbols.
74template<llvm::support::endianness target_endianness, bool is64Bits>
75class ELFUndefinedAtom: public UndefinedAtom {
76
77 typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
78
79public:
80 ELFUndefinedAtom(const File &F,
81 llvm::StringRef N,
82 const Elf_Sym *E)
83 : OwningFile(F)
84 , Name(N)
85 , Symbol(E)
86 {}
87
88 virtual const class File &file() const {
89 return OwningFile;
90 }
91
92 virtual llvm::StringRef name() const {
93 return Name;
94 }
95
96 // FIXME What distinguishes a symbol in ELF that can help
97 // decide if the symbol is undefined only during build and not
98 // runtime? This will make us choose canBeNullAtBuildtime and
99 // canBeNullAtRuntime
100 //
101 virtual CanBeNull canBeNull() const {
102
103 if (Symbol->getBinding() == llvm::ELF::STB_WEAK)
104 return CanBeNull::canBeNullAtBuildtime;
105 else
106 return CanBeNull::canBeNullNever;
107 }
108
109private:
110 const File &OwningFile;
111 llvm::StringRef Name;
112 const Elf_Sym *Symbol;
113};
114
115
116// This atom corresponds to defined symbols.
117template<llvm::support::endianness target_endianness, bool is64Bits>
118class ELFDefinedAtom: public DefinedAtom {
119
120 typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
121 typedef llvm::object::Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
122
123public:
124 ELFDefinedAtom(const File &F,
125 llvm::StringRef N,
126 llvm::StringRef SN,
127 const Elf_Sym *E,
128 const Elf_Shdr *S,
129 llvm::ArrayRef<uint8_t> D)
130 : OwningFile(F)
131 , SymbolName(N)
132 , SectionName(SN)
133 , Symbol(E)
134 , Section(S)
Sid Manning429a4bc2012-07-27 14:52:18 +0000135 , ContentData(D) {
Sid Manning1a601412012-07-25 16:27:21 +0000136 static uint64_t ordernumber = 0;
137 _ordinal = ++ordernumber;
138 }
139
140 virtual const class File &file() const {
141 return OwningFile;
142 }
143
144 virtual llvm::StringRef name() const {
145 return SymbolName;
146 }
147
148 virtual uint64_t ordinal() const {
149 return _ordinal;
150 }
151
152 virtual uint64_t size() const {
153
154 // Common symbols are not allocated in object files so
155 // their size is zero.
156 if ((Symbol->getType() == llvm::ELF::STT_COMMON)
157 || Symbol->st_shndx == llvm::ELF::SHN_COMMON)
158 return (uint64_t)0;
159
Sid Manning429a4bc2012-07-27 14:52:18 +0000160 return ContentData.size();
Sid Manning1a601412012-07-25 16:27:21 +0000161
162 }
163
164 virtual Scope scope() const {
165 if (Symbol->st_other == llvm::ELF::STV_HIDDEN)
166 return scopeLinkageUnit;
167 else if (Symbol->getBinding() != llvm::ELF::STB_LOCAL)
168 return scopeGlobal;
169 else
170 return scopeTranslationUnit;
171 }
172
173 // FIXME Need to revisit this in future.
174
175 virtual Interposable interposable() const {
176 return interposeNo;
177 }
178
179 // FIXME What ways can we determine this in ELF?
180
181 virtual Merge merge() const {
182
183 if (Symbol->getBinding() == llvm::ELF::STB_WEAK)
184 return mergeAsWeak;
185
186 if ((Symbol->getType() == llvm::ELF::STT_COMMON)
187 || Symbol->st_shndx == llvm::ELF::SHN_COMMON)
188 return mergeAsTentative;
189
190 return mergeNo;
191 }
192
193 virtual ContentType contentType() const {
194
195 if (Symbol->getType() == llvm::ELF::STT_FUNC)
196 return typeCode;
197
198 if ((Symbol->getType() == llvm::ELF::STT_COMMON)
199 || Symbol->st_shndx == llvm::ELF::SHN_COMMON)
200 return typeZeroFill;
201
202 if (Symbol->getType() == llvm::ELF::STT_OBJECT)
203 return typeData;
204
205 return typeUnknown;
206 }
207
208 virtual Alignment alignment() const {
209
210 // Unallocated common symbols specify their alignment
211 // constraints in st_value.
212 if ((Symbol->getType() == llvm::ELF::STT_COMMON)
213 || Symbol->st_shndx == llvm::ELF::SHN_COMMON) {
214 return (Alignment(Symbol->st_value));
215 }
216
Hemant Kulkarni927bbc22012-09-14 16:11:34 +0000217 return Alignment(llvm::Log2_64(Section->sh_addralign));
Sid Manning1a601412012-07-25 16:27:21 +0000218 }
219
220 // Do we have a choice for ELF? All symbols
221 // live in explicit sections.
222 virtual SectionChoice sectionChoice() const {
223 if (Symbol->st_shndx > llvm::ELF::SHN_LORESERVE)
224 return sectionBasedOnContent;
225
226 return sectionCustomRequired;
227 }
228
229 virtual llvm::StringRef customSectionName() const {
230 return SectionName;
231 }
232
233 // It isn't clear that __attribute__((used)) is transmitted to
234 // the ELF object file.
235 virtual DeadStripKind deadStrip() const {
236 return deadStripNormal;
237 }
238
239 virtual ContentPermissions permissions() const {
240
241 switch (Section->sh_type) {
242 // permRW_L is for sections modified by the runtime
243 // loader.
244 case llvm::ELF::SHT_REL:
245 case llvm::ELF::SHT_RELA:
246 return permRW_L;
247
248 case llvm::ELF::SHT_DYNAMIC:
249 case llvm::ELF::SHT_PROGBITS:
250 switch (Section->sh_flags) {
251
252 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR):
253 return permR_X;
254
255 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE):
256 return permRW_;
257
258 case llvm::ELF::SHF_ALLOC:
259 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE):
260 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE
261 | llvm::ELF::SHF_STRINGS):
262 return permR__;
263 }
264 default:
265 return perm___;
266 }
267 }
268
269 // Many non ARM architectures use ELF file format
270 // This not really a place to put a architecture
271 // specific method in an atom. A better approach is
272 // needed.
273 //
274 virtual bool isThumb() const {
275 return false;
276 }
277
278 // FIXME Not Sure if ELF supports alias atoms. Find out more.
279 virtual bool isAlias() const {
280 return false;
281 }
282
283 virtual llvm::ArrayRef<uint8_t> rawContent() const {
Sid Manning429a4bc2012-07-27 14:52:18 +0000284 return ContentData;
Sid Manning1a601412012-07-25 16:27:21 +0000285 }
286
287 virtual reference_iterator begin() const {
288 return reference_iterator(*this, nullptr);
289 }
290
291 virtual reference_iterator end() const {
292 return reference_iterator(*this, nullptr);
293 }
294
295private:
296 virtual const Reference *derefIterator(const void *iter) const {
297 return nullptr;
298 }
299 virtual void incrementIterator(const void *&iter) const {
300 }
301
302 const File &OwningFile;
303 llvm::StringRef SymbolName;
304 llvm::StringRef SectionName;
305 const Elf_Sym *Symbol;
306 const Elf_Shdr *Section;
307
Sid Manning429a4bc2012-07-27 14:52:18 +0000308 // ContentData will hold the bits that make up the atom.
309 llvm::ArrayRef<uint8_t> ContentData;
Sid Manning1a601412012-07-25 16:27:21 +0000310
311 uint64_t _ordinal;
312};
313
314
315// FileELF will read a binary, find out based on the symbol table contents
316// what kind of symbol it is and create corresponding atoms for it
317
318template<llvm::support::endianness target_endianness, bool is64Bits>
319class FileELF: public File {
320
321 typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
322 typedef llvm::object::Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
323
324public:
325 FileELF(std::unique_ptr<llvm::MemoryBuffer> MB, llvm::error_code &EC) :
326 File(MB->getBufferIdentifier()) {
327
328 llvm::OwningPtr<llvm::object::Binary> Bin;
329 EC = llvm::object::createBinary(MB.release(), Bin);
330 if (EC)
331 return;
332
333 // Point Obj to correct class and bitwidth ELF object
334 Obj.reset(llvm::dyn_cast<llvm::object::ELFObjectFile<target_endianness,
335 is64Bits> >(Bin.get()));
336
337 if (!Obj) {
338 EC = make_error_code(llvm::object::object_error::invalid_file_type);
339 return;
340 }
341
342 Bin.take();
343
344 std::map< const Elf_Shdr *, std::vector<const Elf_Sym *>> SectionSymbols;
345
Sid Manning429a4bc2012-07-27 14:52:18 +0000346 llvm::object::symbol_iterator it(Obj->begin_symbols());
347 llvm::object::symbol_iterator ie(Obj->end_symbols());
Sid Manning1a601412012-07-25 16:27:21 +0000348
Sid Manning429a4bc2012-07-27 14:52:18 +0000349 for (; it != ie; it.increment(EC)) {
Sid Manning1a601412012-07-25 16:27:21 +0000350 if (EC)
Sid Manning429a4bc2012-07-27 14:52:18 +0000351 return;
Sid Manning1a601412012-07-25 16:27:21 +0000352 llvm::object::SectionRef SR;
353 llvm::object::section_iterator section(SR);
354
Sid Manning429a4bc2012-07-27 14:52:18 +0000355 if ((EC = it->getSection(section)))
356 return;
Sid Manning1a601412012-07-25 16:27:21 +0000357
358 const Elf_Shdr *Section = Obj->getElfSection(section);
Sid Manning429a4bc2012-07-27 14:52:18 +0000359 const Elf_Sym *Symbol = Obj->getElfSymbol(it);
Sid Manning1a601412012-07-25 16:27:21 +0000360
361 llvm::StringRef SymbolName;
Sid Manning429a4bc2012-07-27 14:52:18 +0000362 if ((EC = Obj->getSymbolName(Section, Symbol, SymbolName)))
363 return;
Sid Manning1a601412012-07-25 16:27:21 +0000364
365 if (Symbol->st_shndx == llvm::ELF::SHN_ABS) {
366 // Create an absolute atom.
367 AbsoluteAtoms._atoms.push_back(
368 new (AtomStorage.Allocate<ELFAbsoluteAtom> ())
369 ELFAbsoluteAtom(*this, SymbolName,
370 Symbol->st_value));
371
372 } else if (Symbol->st_shndx == llvm::ELF::SHN_UNDEF) {
373 // Create an undefined atom.
374 UndefinedAtoms._atoms.push_back(
375 new (AtomStorage.Allocate<ELFUndefinedAtom<
376 target_endianness, is64Bits>>())
377 ELFUndefinedAtom<target_endianness, is64Bits> (
378 *this, SymbolName, Symbol));
379 } else {
380 // This is actually a defined symbol. Add it to its section's list of
381 // symbols.
382 if (Symbol->getType() == llvm::ELF::STT_NOTYPE
383 || Symbol->getType() == llvm::ELF::STT_OBJECT
384 || Symbol->getType() == llvm::ELF::STT_FUNC
385 || Symbol->getType() == llvm::ELF::STT_SECTION
386 || Symbol->getType() == llvm::ELF::STT_FILE
387 || Symbol->getType() == llvm::ELF::STT_TLS
388 || Symbol->getType() == llvm::ELF::STT_COMMON
389 || Symbol->st_shndx == llvm::ELF::SHN_COMMON) {
390 SectionSymbols[Section].push_back(Symbol);
391 }
392 else {
393 llvm::errs() << "Unable to create atom for: " << SymbolName << "\n";
394 EC = llvm::object::object_error::parse_failed;
395 return;
396 }
397 }
398 }
399
400 for (auto &i : SectionSymbols) {
401 auto &Symbs = i.second;
402 llvm::StringRef SymbolName;
403 llvm::StringRef SectionName;
404 // Sort symbols by position.
405 std::stable_sort(Symbs.begin(), Symbs.end(),
406 // From ReaderCOFF.cpp:
407 // For some reason MSVC fails to allow the lambda in this context with
408 // a "illegal use of local type in type instantiation". MSVC is clearly
409 // wrong here. Force a conversion to function pointer to work around.
410 static_cast<bool(*)(const Elf_Sym*, const Elf_Sym*)>(
411 [](const Elf_Sym *A, const Elf_Sym *B) -> bool {
412 return A->st_value < B->st_value;
413 }));
414
415 // i.first is the section the symbol lives in
416 for (auto si = Symbs.begin(), se = Symbs.end(); si != se; ++si) {
417
418 StringRef symbolContents;
Sid Manning429a4bc2012-07-27 14:52:18 +0000419 if ((EC = Obj->getSectionContents(i.first, symbolContents)))
420 return;
Sid Manning1a601412012-07-25 16:27:21 +0000421
Sid Manning429a4bc2012-07-27 14:52:18 +0000422 if ((EC = Obj->getSymbolName(i.first, *si, SymbolName)))
423 return;
Sid Manning1a601412012-07-25 16:27:21 +0000424
Sid Manning429a4bc2012-07-27 14:52:18 +0000425 if ((EC = Obj->getSectionName(i.first, SectionName)))
426 return;
Sid Manning1a601412012-07-25 16:27:21 +0000427
428 bool IsCommon = false;
429 if (((*si)->getType() == llvm::ELF::STT_COMMON)
430 || (*si)->st_shndx == llvm::ELF::SHN_COMMON)
431 IsCommon = true;
432
433 // Get the symbol's content:
434 llvm::ArrayRef<uint8_t> SymbolData;
435 if (si + 1 == se) {
436 // if this is the last symbol, take up the remaining data.
437 SymbolData = llvm::ArrayRef<uint8_t>((uint8_t *)symbolContents.data()
438 + (*si)->st_value,
439 (IsCommon) ? 0 :
440 ((i.first)->sh_size - (*si)->st_value));
441 }
442 else {
443 SymbolData = llvm::ArrayRef<uint8_t>((uint8_t *)symbolContents.data()
444 + (*si)->st_value,
445 (IsCommon) ? 0 :
446 (*(si + 1))->st_value - (*si)->st_value);
447 }
448
449 DefinedAtoms._atoms.push_back(
450 new (AtomStorage.Allocate<ELFDefinedAtom<
451 target_endianness, is64Bits> > ())
452 ELFDefinedAtom<target_endianness, is64Bits> (*this,
453 SymbolName, SectionName,
454 *si, i.first, SymbolData));
455 }
456 }
457 }
458
459 virtual void addAtom(const Atom&) {
460 llvm_unreachable("cannot add atoms to native .o files");
461 }
462
463 virtual const atom_collection<DefinedAtom> &defined() const {
464 return DefinedAtoms;
465 }
466
467 virtual const atom_collection<UndefinedAtom> &undefined() const {
468 return UndefinedAtoms;
469 }
470
471 virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
472 return SharedLibraryAtoms;
473 }
474
475 virtual const atom_collection<AbsoluteAtom> &absolute() const {
476 return AbsoluteAtoms;
477 }
478
479private:
480 std::unique_ptr<llvm::object::ELFObjectFile<target_endianness, is64Bits> >
481 Obj;
482 atom_collection_vector<DefinedAtom> DefinedAtoms;
483 atom_collection_vector<UndefinedAtom> UndefinedAtoms;
484 atom_collection_vector<SharedLibraryAtom> SharedLibraryAtoms;
485 atom_collection_vector<AbsoluteAtom> AbsoluteAtoms;
486 llvm::BumpPtrAllocator AtomStorage;
487
488};
489
490// ReaderELF is reader object that will instantiate correct FileELF
491// by examining the memory buffer for ELF class and bitwidth
492
493class ReaderELF: public Reader {
494public:
Michael J. Spencer69ed53a2012-09-10 23:46:58 +0000495 ReaderELF(const ReaderOptionsELF &) {}
Sid Manning1a601412012-07-25 16:27:21 +0000496 error_code parseFile(std::unique_ptr<MemoryBuffer> mb, std::vector<
497 std::unique_ptr<File> > &result) {
498
499 std::pair<unsigned char, unsigned char> Ident =
500 llvm::object::getElfArchType(&*mb);
501 llvm::error_code ec;
502 // Instantiate the correct FileELF template instance
503 // based on the Ident pair. Once the File is created
504 // we push the file to the vector of files already
505 // created during parser's life.
506
507 std::unique_ptr<File> f;
508
509 if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
510 == llvm::ELF::ELFDATA2LSB) {
511 f.reset(new FileELF<llvm::support::little, false>(std::move(mb), ec));
512
513 } else if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
514 == llvm::ELF::ELFDATA2MSB) {
515 f.reset(new FileELF<llvm::support::big, false> (std::move(mb), ec));
516
517 } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
518 == llvm::ELF::ELFDATA2MSB) {
519 f.reset(new FileELF<llvm::support::big, true> (std::move(mb), ec));
520
521 } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
522 == llvm::ELF::ELFDATA2LSB) {
523 f.reset(new FileELF<llvm::support::little, true> (std::move(mb), ec));
524 }
525
526 if (ec)
527 return ec;
528
529 result.push_back(std::move(f));
530 return error_code::success();
531 }
Sid Manning1a601412012-07-25 16:27:21 +0000532};
533
534} // namespace anonymous
Nick Kledzikabb69812012-05-31 22:34:00 +0000535
536namespace lld {
537
538ReaderOptionsELF::ReaderOptionsELF() {
539}
540
541ReaderOptionsELF::~ReaderOptionsELF() {
542}
543
544
Sid Manning1a601412012-07-25 16:27:21 +0000545Reader *createReaderELF(const ReaderOptionsELF &options) {
546 return new ReaderELF(options);
Nick Kledzikabb69812012-05-31 22:34:00 +0000547}
548
Sid Manning1a601412012-07-25 16:27:21 +0000549} // namespace LLD