blob: 4941c325e49cfead9a9f9bf29ef36cf9c258d788 [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)
135 , Data(D) {
136 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
160 return Data.size();
161
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
217 return Alignment(1);
218 }
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 {
284 return Data;
285 }
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
308 // Data will hold the bits that make up the atom.
309 llvm::ArrayRef<uint8_t> Data;
310
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
346 llvm::object::SectionRef SR;
347 llvm::object::section_iterator section(SR);
348 llvm::object::symbol_iterator si(Obj->begin_symbols());
349 llvm::object::symbol_iterator se(Obj->end_symbols());
350
351 for (; si != se; si.increment(EC)) {
352 if (EC)
353 llvm::report_fatal_error("Could not read all symbols");
354 llvm::object::SectionRef SR;
355 llvm::object::section_iterator section(SR);
356
357 EC = si->getSection(section);
358 if (EC)
359 llvm::report_fatal_error("Could not get section iterator");
360
361 const Elf_Shdr *Section = Obj->getElfSection(section);
362 const Elf_Sym *Symbol = Obj->getElfSymbol(si);
363
364 llvm::StringRef SymbolName;
365 EC = Obj->getSymbolName(Section, Symbol, SymbolName);
366 if (EC)
367 llvm::report_fatal_error("Could not get symbol name");
368
369 if (Symbol->st_shndx == llvm::ELF::SHN_ABS) {
370 // Create an absolute atom.
371 AbsoluteAtoms._atoms.push_back(
372 new (AtomStorage.Allocate<ELFAbsoluteAtom> ())
373 ELFAbsoluteAtom(*this, SymbolName,
374 Symbol->st_value));
375
376 } else if (Symbol->st_shndx == llvm::ELF::SHN_UNDEF) {
377 // Create an undefined atom.
378 UndefinedAtoms._atoms.push_back(
379 new (AtomStorage.Allocate<ELFUndefinedAtom<
380 target_endianness, is64Bits>>())
381 ELFUndefinedAtom<target_endianness, is64Bits> (
382 *this, SymbolName, Symbol));
383 } else {
384 // This is actually a defined symbol. Add it to its section's list of
385 // symbols.
386 if (Symbol->getType() == llvm::ELF::STT_NOTYPE
387 || Symbol->getType() == llvm::ELF::STT_OBJECT
388 || Symbol->getType() == llvm::ELF::STT_FUNC
389 || Symbol->getType() == llvm::ELF::STT_SECTION
390 || Symbol->getType() == llvm::ELF::STT_FILE
391 || Symbol->getType() == llvm::ELF::STT_TLS
392 || Symbol->getType() == llvm::ELF::STT_COMMON
393 || Symbol->st_shndx == llvm::ELF::SHN_COMMON) {
394 SectionSymbols[Section].push_back(Symbol);
395 }
396 else {
397 llvm::errs() << "Unable to create atom for: " << SymbolName << "\n";
398 EC = llvm::object::object_error::parse_failed;
399 return;
400 }
401 }
402 }
403
404 for (auto &i : SectionSymbols) {
405 auto &Symbs = i.second;
406 llvm::StringRef SymbolName;
407 llvm::StringRef SectionName;
408 // Sort symbols by position.
409 std::stable_sort(Symbs.begin(), Symbs.end(),
410 // From ReaderCOFF.cpp:
411 // For some reason MSVC fails to allow the lambda in this context with
412 // a "illegal use of local type in type instantiation". MSVC is clearly
413 // wrong here. Force a conversion to function pointer to work around.
414 static_cast<bool(*)(const Elf_Sym*, const Elf_Sym*)>(
415 [](const Elf_Sym *A, const Elf_Sym *B) -> bool {
416 return A->st_value < B->st_value;
417 }));
418
419 // i.first is the section the symbol lives in
420 for (auto si = Symbs.begin(), se = Symbs.end(); si != se; ++si) {
421
422 StringRef symbolContents;
423 EC = Obj->getSectionContents(i.first, symbolContents);
424 if (EC)
425 llvm::report_fatal_error("Could not get section iterator");
426
427 EC = Obj->getSymbolName(i.first, *si, SymbolName);
428 if (EC)
429 llvm::report_fatal_error("Could not get symbol name");
430
431 EC = Obj->getSectionName(i.first, SectionName);
432 if (EC)
433 llvm::report_fatal_error("Could not get section name");
434
435 bool IsCommon = false;
436 if (((*si)->getType() == llvm::ELF::STT_COMMON)
437 || (*si)->st_shndx == llvm::ELF::SHN_COMMON)
438 IsCommon = true;
439
440 // Get the symbol's content:
441 llvm::ArrayRef<uint8_t> SymbolData;
442 if (si + 1 == se) {
443 // if this is the last symbol, take up the remaining data.
444 SymbolData = llvm::ArrayRef<uint8_t>((uint8_t *)symbolContents.data()
445 + (*si)->st_value,
446 (IsCommon) ? 0 :
447 ((i.first)->sh_size - (*si)->st_value));
448 }
449 else {
450 SymbolData = llvm::ArrayRef<uint8_t>((uint8_t *)symbolContents.data()
451 + (*si)->st_value,
452 (IsCommon) ? 0 :
453 (*(si + 1))->st_value - (*si)->st_value);
454 }
455
456 DefinedAtoms._atoms.push_back(
457 new (AtomStorage.Allocate<ELFDefinedAtom<
458 target_endianness, is64Bits> > ())
459 ELFDefinedAtom<target_endianness, is64Bits> (*this,
460 SymbolName, SectionName,
461 *si, i.first, SymbolData));
462 }
463 }
464 }
465
466 virtual void addAtom(const Atom&) {
467 llvm_unreachable("cannot add atoms to native .o files");
468 }
469
470 virtual const atom_collection<DefinedAtom> &defined() const {
471 return DefinedAtoms;
472 }
473
474 virtual const atom_collection<UndefinedAtom> &undefined() const {
475 return UndefinedAtoms;
476 }
477
478 virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
479 return SharedLibraryAtoms;
480 }
481
482 virtual const atom_collection<AbsoluteAtom> &absolute() const {
483 return AbsoluteAtoms;
484 }
485
486private:
487 std::unique_ptr<llvm::object::ELFObjectFile<target_endianness, is64Bits> >
488 Obj;
489 atom_collection_vector<DefinedAtom> DefinedAtoms;
490 atom_collection_vector<UndefinedAtom> UndefinedAtoms;
491 atom_collection_vector<SharedLibraryAtom> SharedLibraryAtoms;
492 atom_collection_vector<AbsoluteAtom> AbsoluteAtoms;
493 llvm::BumpPtrAllocator AtomStorage;
494
495};
496
497// ReaderELF is reader object that will instantiate correct FileELF
498// by examining the memory buffer for ELF class and bitwidth
499
500class ReaderELF: public Reader {
501public:
502 ReaderELF(const ReaderOptionsELF &options) :
503 _options(options) {
504 }
505 error_code parseFile(std::unique_ptr<MemoryBuffer> mb, std::vector<
506 std::unique_ptr<File> > &result) {
507
508 std::pair<unsigned char, unsigned char> Ident =
509 llvm::object::getElfArchType(&*mb);
510 llvm::error_code ec;
511 // Instantiate the correct FileELF template instance
512 // based on the Ident pair. Once the File is created
513 // we push the file to the vector of files already
514 // created during parser's life.
515
516 std::unique_ptr<File> f;
517
518 if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
519 == llvm::ELF::ELFDATA2LSB) {
520 f.reset(new FileELF<llvm::support::little, false>(std::move(mb), ec));
521
522 } else if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
523 == llvm::ELF::ELFDATA2MSB) {
524 f.reset(new FileELF<llvm::support::big, false> (std::move(mb), ec));
525
526 } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
527 == llvm::ELF::ELFDATA2MSB) {
528 f.reset(new FileELF<llvm::support::big, true> (std::move(mb), ec));
529
530 } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
531 == llvm::ELF::ELFDATA2LSB) {
532 f.reset(new FileELF<llvm::support::little, true> (std::move(mb), ec));
533 }
534
535 if (ec)
536 return ec;
537
538 result.push_back(std::move(f));
539 return error_code::success();
540 }
541private:
542 const ReaderOptionsELF &_options;
543};
544
545} // namespace anonymous
Nick Kledzikabb69812012-05-31 22:34:00 +0000546
547namespace lld {
548
549ReaderOptionsELF::ReaderOptionsELF() {
550}
551
552ReaderOptionsELF::~ReaderOptionsELF() {
553}
554
555
Sid Manning1a601412012-07-25 16:27:21 +0000556Reader *createReaderELF(const ReaderOptionsELF &options) {
557 return new ReaderELF(options);
Nick Kledzikabb69812012-05-31 22:34:00 +0000558}
559
Sid Manning1a601412012-07-25 16:27:21 +0000560} // namespace LLD