blob: 5aa5e91a78c56874d5af7763a3df030381d01198 [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"
Sid Manning8caf4de2012-09-17 12:49:38 +000017#include "lld/Core/Reference.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000018
Sid Manning1a601412012-07-25 16:27:21 +000019#include "llvm/ADT/ArrayRef.h"
Sid Manning8caf4de2012-09-17 12:49:38 +000020#include "llvm/ADT/SmallString.h"
Sid Manning1a601412012-07-25 16:27:21 +000021#include "llvm/ADT/StringRef.h"
22#include "llvm/Object/ELF.h"
23#include "llvm/Object/ObjectFile.h"
24#include "llvm/Support/Allocator.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000025#include "llvm/Support/Casting.h"
Sid Manning1a601412012-07-25 16:27:21 +000026#include "llvm/Support/ELF.h"
27#include "llvm/Support/Endian.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000028#include "llvm/Support/ErrorHandling.h"
Sid Manning1a601412012-07-25 16:27:21 +000029#include "llvm/Support/MathExtras.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000030#include "llvm/Support/Memory.h"
31#include "llvm/Support/MemoryBuffer.h"
32#include "llvm/Support/raw_ostream.h"
33#include "llvm/Support/system_error.h"
34
Sid Manning1a601412012-07-25 16:27:21 +000035
Nick Kledzikabb69812012-05-31 22:34:00 +000036#include <map>
37#include <vector>
38
Sid Manning1a601412012-07-25 16:27:21 +000039using llvm::object::Elf_Sym_Impl;
40using namespace lld;
41
42namespace { // anonymous
43
Sid Manning1a601412012-07-25 16:27:21 +000044
Sid Manning8caf4de2012-09-17 12:49:38 +000045/// \brief Relocation References: Defined Atoms may contain
46/// references that will need to be patched before
47/// the executable is written.
48template <llvm::support::endianness target_endianness, bool is64Bits>
49class ELFReference final : public Reference {
50
51 typedef llvm::object::Elf_Rel_Impl
52 <target_endianness, is64Bits, false> Elf_Rel;
53 typedef llvm::object::Elf_Rel_Impl
54 <target_endianness, is64Bits, true> Elf_Rela;
Sid Manning1a601412012-07-25 16:27:21 +000055public:
Sid Manning1a601412012-07-25 16:27:21 +000056
Sid Manning8caf4de2012-09-17 12:49:38 +000057 ELFReference(const Elf_Rela *rela, uint64_t offset, const Atom *target)
58 : _target(target)
59 , _targetSymbolIndex(rela->getSymbol())
60 , _offsetInAtom(offset)
61 , _addend(rela->r_addend)
62 , _kind(rela->getType()) {}
63
64 ELFReference(const Elf_Rel *rel, uint64_t offset, const Atom *target)
65 : _target(target)
66 , _targetSymbolIndex(rel->getSymbol())
67 , _offsetInAtom(offset)
68 , _addend(0)
69 , _kind(rel->getType()) {}
70
71
72 virtual uint64_t offsetInAtom() const {
73 return _offsetInAtom;
Sid Manning1a601412012-07-25 16:27:21 +000074 }
75
Sid Manning8caf4de2012-09-17 12:49:38 +000076 virtual Kind kind() const {
77 return _kind;
Sid Manning1a601412012-07-25 16:27:21 +000078 }
79
Sid Manning8caf4de2012-09-17 12:49:38 +000080 virtual void setKind(Kind kind) {
81 _kind = kind;
Sid Manning1a601412012-07-25 16:27:21 +000082 }
83
Sid Manning8caf4de2012-09-17 12:49:38 +000084 virtual const Atom *target() const {
85 return _target;
86 }
87
88/// \brief targetSymbolIndex: This is the symbol table index that contains
89/// the target reference.
90 uint64_t targetSymbolIndex() const {
91 return _targetSymbolIndex;
92 }
93
94 virtual Addend addend() const {
95 return _addend;
96 }
97
98 virtual void setAddend(Addend A) {
99 _addend = A;
100 }
101
102 virtual void setTarget(const Atom *newAtom) {
103 _target = newAtom;
104 }
Sid Manning1a601412012-07-25 16:27:21 +0000105private:
Sid Manning8caf4de2012-09-17 12:49:38 +0000106 const Atom *_target;
107 uint64_t _targetSymbolIndex;
108 uint64_t _offsetInAtom;
109 Addend _addend;
110 Kind _kind;
Sid Manning1a601412012-07-25 16:27:21 +0000111};
112
113
Sid Manning8caf4de2012-09-17 12:49:38 +0000114/// \brief ELFAbsoluteAtom: These atoms store symbols that are fixed to a
115/// particular address. This atom has no content its address will be used by
116/// the writer to fixup references that point to it.
Sid Manning1a601412012-07-25 16:27:21 +0000117template<llvm::support::endianness target_endianness, bool is64Bits>
Sid Manning8caf4de2012-09-17 12:49:38 +0000118class ELFAbsoluteAtom final: public AbsoluteAtom {
119
120public:
121 ELFAbsoluteAtom(const File &file,
122 llvm::StringRef name,
123 uint64_t value)
124 : _owningFile(file)
125 , _name(name)
126 , _value(value)
127 {}
128
129 virtual const class File &file() const {
130 return _owningFile;
131 }
132
133 virtual llvm::StringRef name() const {
134 return _name;
135 }
136
137 virtual uint64_t value() const {
138 return _value;
139 }
140
141private:
142 const File &_owningFile;
143 llvm::StringRef _name;
144 uint64_t _value;
145};
146
147
148/// \brief ELFUndefinedAtom: These atoms store undefined symbols and are
149/// place holders that will be replaced by defined atoms later in the
150/// linking process.
151template<llvm::support::endianness target_endianness, bool is64Bits>
152class ELFUndefinedAtom final: public UndefinedAtom {
Sid Manning1a601412012-07-25 16:27:21 +0000153
154 typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
155
156public:
Sid Manning8caf4de2012-09-17 12:49:38 +0000157 ELFUndefinedAtom(const File &file,
158 llvm::StringRef name,
159 const Elf_Sym *symbol)
160 : _owningFile(file)
161 , _name(name)
162 , _symbol(symbol)
Sid Manning1a601412012-07-25 16:27:21 +0000163 {}
164
165 virtual const class File &file() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000166 return _owningFile;
Sid Manning1a601412012-07-25 16:27:21 +0000167 }
168
169 virtual llvm::StringRef name() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000170 return _name;
Sid Manning1a601412012-07-25 16:27:21 +0000171 }
172
173 // FIXME What distinguishes a symbol in ELF that can help
174 // decide if the symbol is undefined only during build and not
175 // runtime? This will make us choose canBeNullAtBuildtime and
176 // canBeNullAtRuntime
177 //
178 virtual CanBeNull canBeNull() const {
179
Sid Manning8caf4de2012-09-17 12:49:38 +0000180 if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
Sid Manning1a601412012-07-25 16:27:21 +0000181 return CanBeNull::canBeNullAtBuildtime;
182 else
183 return CanBeNull::canBeNullNever;
184 }
185
186private:
Sid Manning8caf4de2012-09-17 12:49:38 +0000187 const File &_owningFile;
188 llvm::StringRef _name;
189 const Elf_Sym *_symbol;
Sid Manning1a601412012-07-25 16:27:21 +0000190};
191
192
Sid Manning8caf4de2012-09-17 12:49:38 +0000193/// \brief ELFDefinedAtom: This atom stores defined symbols and will contain
194/// either data or code.
Sid Manning1a601412012-07-25 16:27:21 +0000195template<llvm::support::endianness target_endianness, bool is64Bits>
Sid Manning8caf4de2012-09-17 12:49:38 +0000196class ELFDefinedAtom final: public DefinedAtom {
Sid Manning1a601412012-07-25 16:27:21 +0000197
198 typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
199 typedef llvm::object::Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
200
201public:
Sid Manning8caf4de2012-09-17 12:49:38 +0000202 ELFDefinedAtom(const File &file,
203 llvm::StringRef symbolName,
204 llvm::StringRef sectionName,
205 const Elf_Sym *symbol,
206 const Elf_Shdr *section,
207 llvm::ArrayRef<uint8_t> contentData,
208 unsigned int referenceStart,
209 unsigned int referenceEnd,
210 std::vector<ELFReference
211 <target_endianness, is64Bits> *> &referenceList)
212
213 : _owningFile(file)
214 , _symbolName(symbolName)
215 , _sectionName(sectionName)
216 , _symbol(symbol)
217 , _section(section)
218 , _contentData(contentData)
219 , _referenceStartIndex(referenceStart)
220 , _referenceEndIndex(referenceEnd)
221 , _referenceList(referenceList) {
222 static uint64_t orderNumber = 0;
223 _ordinal = ++orderNumber;
Sid Manning1a601412012-07-25 16:27:21 +0000224 }
225
226 virtual const class File &file() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000227 return _owningFile;
Sid Manning1a601412012-07-25 16:27:21 +0000228 }
229
230 virtual llvm::StringRef name() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000231 return _symbolName;
Sid Manning1a601412012-07-25 16:27:21 +0000232 }
233
234 virtual uint64_t ordinal() const {
235 return _ordinal;
236 }
237
238 virtual uint64_t size() const {
239
240 // Common symbols are not allocated in object files so
241 // their size is zero.
Sid Manning8caf4de2012-09-17 12:49:38 +0000242 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
243 || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
Sid Manning1a601412012-07-25 16:27:21 +0000244 return (uint64_t)0;
245
Sid Manning8caf4de2012-09-17 12:49:38 +0000246 return _contentData.size();
Sid Manning1a601412012-07-25 16:27:21 +0000247
248 }
249
250 virtual Scope scope() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000251 if (_symbol->st_other == llvm::ELF::STV_HIDDEN)
Sid Manning1a601412012-07-25 16:27:21 +0000252 return scopeLinkageUnit;
Sid Manning8caf4de2012-09-17 12:49:38 +0000253 else if (_symbol->getBinding() != llvm::ELF::STB_LOCAL)
Sid Manning1a601412012-07-25 16:27:21 +0000254 return scopeGlobal;
255 else
256 return scopeTranslationUnit;
257 }
258
259 // FIXME Need to revisit this in future.
260
261 virtual Interposable interposable() const {
262 return interposeNo;
263 }
264
265 // FIXME What ways can we determine this in ELF?
266
267 virtual Merge merge() const {
268
Sid Manning8caf4de2012-09-17 12:49:38 +0000269 if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
Sid Manning1a601412012-07-25 16:27:21 +0000270 return mergeAsWeak;
271
Sid Manning8caf4de2012-09-17 12:49:38 +0000272 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
273 || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
Sid Manning1a601412012-07-25 16:27:21 +0000274 return mergeAsTentative;
275
276 return mergeNo;
277 }
278
279 virtual ContentType contentType() const {
280
Sid Manning8caf4de2012-09-17 12:49:38 +0000281 if (_symbol->getType() == llvm::ELF::STT_FUNC)
Sid Manning1a601412012-07-25 16:27:21 +0000282 return typeCode;
283
Sid Manning8caf4de2012-09-17 12:49:38 +0000284 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
285 || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
Sid Manning1a601412012-07-25 16:27:21 +0000286 return typeZeroFill;
287
Sid Manning8caf4de2012-09-17 12:49:38 +0000288 if (_symbol->getType() == llvm::ELF::STT_OBJECT)
Sid Manning1a601412012-07-25 16:27:21 +0000289 return typeData;
290
291 return typeUnknown;
292 }
293
294 virtual Alignment alignment() const {
295
296 // Unallocated common symbols specify their alignment
297 // constraints in st_value.
Sid Manning8caf4de2012-09-17 12:49:38 +0000298 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
299 || _symbol->st_shndx == llvm::ELF::SHN_COMMON) {
300 return (Alignment(_symbol->st_value));
Sid Manning1a601412012-07-25 16:27:21 +0000301 }
302
Sid Manning8caf4de2012-09-17 12:49:38 +0000303 return Alignment(llvm::Log2_64(_section->sh_addralign));
Sid Manning1a601412012-07-25 16:27:21 +0000304 }
305
306 // Do we have a choice for ELF? All symbols
307 // live in explicit sections.
308 virtual SectionChoice sectionChoice() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000309 if (_symbol->st_shndx > llvm::ELF::SHN_LORESERVE)
Sid Manning1a601412012-07-25 16:27:21 +0000310 return sectionBasedOnContent;
311
312 return sectionCustomRequired;
313 }
314
315 virtual llvm::StringRef customSectionName() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000316 return _sectionName;
Sid Manning1a601412012-07-25 16:27:21 +0000317 }
318
319 // It isn't clear that __attribute__((used)) is transmitted to
320 // the ELF object file.
321 virtual DeadStripKind deadStrip() const {
322 return deadStripNormal;
323 }
324
325 virtual ContentPermissions permissions() const {
326
Sid Manning8caf4de2012-09-17 12:49:38 +0000327 switch (_section->sh_type) {
Sid Manning1a601412012-07-25 16:27:21 +0000328 // permRW_L is for sections modified by the runtime
329 // loader.
330 case llvm::ELF::SHT_REL:
331 case llvm::ELF::SHT_RELA:
332 return permRW_L;
333
334 case llvm::ELF::SHT_DYNAMIC:
335 case llvm::ELF::SHT_PROGBITS:
Sid Manning8caf4de2012-09-17 12:49:38 +0000336 switch (_section->sh_flags) {
Sid Manning1a601412012-07-25 16:27:21 +0000337
338 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR):
339 return permR_X;
340
341 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE):
342 return permRW_;
343
344 case llvm::ELF::SHF_ALLOC:
345 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE):
346 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE
347 | llvm::ELF::SHF_STRINGS):
348 return permR__;
349 }
350 default:
351 return perm___;
352 }
353 }
354
355 // Many non ARM architectures use ELF file format
356 // This not really a place to put a architecture
357 // specific method in an atom. A better approach is
358 // needed.
359 //
360 virtual bool isThumb() const {
361 return false;
362 }
363
364 // FIXME Not Sure if ELF supports alias atoms. Find out more.
365 virtual bool isAlias() const {
366 return false;
367 }
368
369 virtual llvm::ArrayRef<uint8_t> rawContent() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000370 return _contentData;
Sid Manning1a601412012-07-25 16:27:21 +0000371 }
372
Sid Manning8caf4de2012-09-17 12:49:38 +0000373 DefinedAtom::reference_iterator begin() const {
374 uintptr_t index = _referenceStartIndex;
375 const void *it = reinterpret_cast<const void*>(index);
376 return reference_iterator(*this, it);
Sid Manning1a601412012-07-25 16:27:21 +0000377 }
378
Sid Manning8caf4de2012-09-17 12:49:38 +0000379 DefinedAtom::reference_iterator end() const {
380 uintptr_t index = _referenceEndIndex;
381 const void *it = reinterpret_cast<const void*>(index);
382 return reference_iterator(*this, it);
383 }
384
385 const Reference *derefIterator(const void *It) const {
386 uintptr_t index = reinterpret_cast<uintptr_t>(It);
387 assert(index >= _referenceStartIndex);
388 assert(index < _referenceEndIndex);
389 return ((_referenceList)[index]);
390 }
391
392 void incrementIterator(const void*& It) const {
393 uintptr_t index = reinterpret_cast<uintptr_t>(It);
394 ++index;
395 It = reinterpret_cast<const void*>(index);
Sid Manning1a601412012-07-25 16:27:21 +0000396 }
397
398private:
Sid Manning1a601412012-07-25 16:27:21 +0000399
Sid Manning8caf4de2012-09-17 12:49:38 +0000400 const File &_owningFile;
401 llvm::StringRef _symbolName;
402 llvm::StringRef _sectionName;
403 const Elf_Sym *_symbol;
404 const Elf_Shdr *_section;
Sid Manning1a601412012-07-25 16:27:21 +0000405
Sid Manning8caf4de2012-09-17 12:49:38 +0000406 // _contentData will hold the bits that make up the atom.
407 llvm::ArrayRef<uint8_t> _contentData;
Sid Manning1a601412012-07-25 16:27:21 +0000408
409 uint64_t _ordinal;
Sid Manning8caf4de2012-09-17 12:49:38 +0000410 unsigned int _referenceStartIndex;
411 unsigned int _referenceEndIndex;
412 std::vector<ELFReference<target_endianness, is64Bits> *> &_referenceList;
Sid Manning1a601412012-07-25 16:27:21 +0000413};
414
415
416// FileELF will read a binary, find out based on the symbol table contents
417// what kind of symbol it is and create corresponding atoms for it
418
419template<llvm::support::endianness target_endianness, bool is64Bits>
420class FileELF: public File {
421
Sid Manning8caf4de2012-09-17 12:49:38 +0000422 typedef llvm::object::Elf_Sym_Impl
423 <target_endianness, is64Bits> Elf_Sym;
424 typedef llvm::object::Elf_Shdr_Impl
425 <target_endianness, is64Bits> Elf_Shdr;
426 typedef llvm::object::Elf_Rel_Impl
427 <target_endianness, is64Bits, false> Elf_Rel;
428 typedef llvm::object::Elf_Rel_Impl
429 <target_endianness, is64Bits, true> Elf_Rela;
Sid Manning1a601412012-07-25 16:27:21 +0000430
431public:
432 FileELF(std::unique_ptr<llvm::MemoryBuffer> MB, llvm::error_code &EC) :
433 File(MB->getBufferIdentifier()) {
434
Sid Manning8caf4de2012-09-17 12:49:38 +0000435 llvm::OwningPtr<llvm::object::Binary> binaryFile;
436 EC = llvm::object::createBinary(MB.release(), binaryFile);
Sid Manning1a601412012-07-25 16:27:21 +0000437 if (EC)
438 return;
439
440 // Point Obj to correct class and bitwidth ELF object
Sid Manning8caf4de2012-09-17 12:49:38 +0000441 _objFile.reset(llvm::dyn_cast<llvm::object::ELFObjectFile<target_endianness,
442 is64Bits> >(binaryFile.get()));
Sid Manning1a601412012-07-25 16:27:21 +0000443
Sid Manning8caf4de2012-09-17 12:49:38 +0000444 if (!_objFile) {
Sid Manning1a601412012-07-25 16:27:21 +0000445 EC = make_error_code(llvm::object::object_error::invalid_file_type);
446 return;
447 }
448
Sid Manning8caf4de2012-09-17 12:49:38 +0000449 binaryFile.take();
Sid Manning1a601412012-07-25 16:27:21 +0000450
Sid Manning8caf4de2012-09-17 12:49:38 +0000451 std::map< const Elf_Shdr *, std::vector<const Elf_Sym *>> sectionSymbols;
Sid Manning1a601412012-07-25 16:27:21 +0000452
Sid Manning8caf4de2012-09-17 12:49:38 +0000453// Handle: SHT_REL and SHT_RELA sections:
454// Increment over the sections, when REL/RELA section types are
455// found add the contents to the RelocationReferences map.
456
457 llvm::object::section_iterator sit(_objFile->begin_sections());
458 llvm::object::section_iterator sie(_objFile->end_sections());
459 for (; sit != sie; sit.increment(EC)) {
460 if (EC)
461 return;
462
463 const Elf_Shdr *section = _objFile->getElfSection(sit);
464
465 if (section->sh_type == llvm::ELF::SHT_RELA) {
466 llvm::StringRef sectionName;
467 if ((EC = _objFile->getSectionName(section, sectionName)))
468 return;
469 // Get rid of the leading .rela so Atoms can use their own section
470 // name to find the relocs.
471 sectionName = sectionName.drop_front(5);
472
473 auto rai(_objFile->beginELFRela(section));
474 auto rae(_objFile->endELFRela(section));
475
476 auto &Ref = _relocationAddendRefences[sectionName];
477 for (; rai != rae; rai++) {
478 Ref.push_back(&*rai);
479 }
480 }
481
482 if (section->sh_type == llvm::ELF::SHT_REL) {
483 llvm::StringRef sectionName;
484 if ((EC = _objFile->getSectionName(section, sectionName)))
485 return;
486 // Get rid of the leading .rel so Atoms can use their own section
487 // name to find the relocs.
488 sectionName = sectionName.drop_front(4);
489
490 auto ri(_objFile->beginELFRel(section));
491 auto re(_objFile->endELFRel(section));
492
493 auto &Ref = _relocationReferences[sectionName];
494 for (; ri != re; ri++) {
495 Ref.push_back(&*ri);
496 }
497 }
498 }
499
500
501// Increment over all the symbols collecting atoms and symbol
502// names for later use.
503
504 llvm::object::symbol_iterator it(_objFile->begin_symbols());
505 llvm::object::symbol_iterator ie(_objFile->end_symbols());
Sid Manning1a601412012-07-25 16:27:21 +0000506
Sid Manning429a4bc2012-07-27 14:52:18 +0000507 for (; it != ie; it.increment(EC)) {
Sid Manning1a601412012-07-25 16:27:21 +0000508 if (EC)
Sid Manning429a4bc2012-07-27 14:52:18 +0000509 return;
Sid Manning1a601412012-07-25 16:27:21 +0000510
Sid Manning8caf4de2012-09-17 12:49:38 +0000511 if ((EC = it->getSection(sit)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000512 return;
Sid Manning1a601412012-07-25 16:27:21 +0000513
Sid Manning8caf4de2012-09-17 12:49:38 +0000514 const Elf_Shdr *section = _objFile->getElfSection(sit);
515 const Elf_Sym *symbol = _objFile->getElfSymbol(it);
Sid Manning1a601412012-07-25 16:27:21 +0000516
Sid Manning8caf4de2012-09-17 12:49:38 +0000517 llvm::StringRef symbolName;
518 if ((EC = _objFile->getSymbolName(section, symbol, symbolName)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000519 return;
Sid Manning1a601412012-07-25 16:27:21 +0000520
Sid Manning8caf4de2012-09-17 12:49:38 +0000521 if (symbol->st_shndx == llvm::ELF::SHN_ABS) {
Sid Manning1a601412012-07-25 16:27:21 +0000522 // Create an absolute atom.
Sid Manning8caf4de2012-09-17 12:49:38 +0000523 auto *newAtom = new (_readerStorage.Allocate
524 <ELFAbsoluteAtom<target_endianness, is64Bits> > ())
525 ELFAbsoluteAtom<target_endianness, is64Bits>
526 (*this, symbolName, symbol->st_value);
Sid Manning1a601412012-07-25 16:27:21 +0000527
Sid Manning8caf4de2012-09-17 12:49:38 +0000528 _absoluteAtoms._atoms.push_back(newAtom);
529 _symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));
530
531 } else if (symbol->st_shndx == llvm::ELF::SHN_UNDEF) {
Sid Manning1a601412012-07-25 16:27:21 +0000532 // Create an undefined atom.
Sid Manning8caf4de2012-09-17 12:49:38 +0000533 auto *newAtom = new (_readerStorage.Allocate
534 <ELFUndefinedAtom<target_endianness, is64Bits> > ())
535 ELFUndefinedAtom<target_endianness, is64Bits>
536 (*this, symbolName, symbol);
537
538 _undefinedAtoms._atoms.push_back(newAtom);
539 _symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));
540
Sid Manning1a601412012-07-25 16:27:21 +0000541 } else {
542 // This is actually a defined symbol. Add it to its section's list of
543 // symbols.
Sid Manning8caf4de2012-09-17 12:49:38 +0000544 if (symbol->getType() == llvm::ELF::STT_NOTYPE
545 || symbol->getType() == llvm::ELF::STT_OBJECT
546 || symbol->getType() == llvm::ELF::STT_FUNC
547 || symbol->getType() == llvm::ELF::STT_SECTION
548 || symbol->getType() == llvm::ELF::STT_FILE
549 || symbol->getType() == llvm::ELF::STT_TLS
550 || symbol->getType() == llvm::ELF::STT_COMMON
551 || symbol->st_shndx == llvm::ELF::SHN_COMMON) {
552 sectionSymbols[section].push_back(symbol);
Sid Manning1a601412012-07-25 16:27:21 +0000553 }
554 else {
Sid Manning8caf4de2012-09-17 12:49:38 +0000555 llvm::errs() << "Unable to create atom for: " << symbolName << "\n";
Sid Manning1a601412012-07-25 16:27:21 +0000556 EC = llvm::object::object_error::parse_failed;
557 return;
558 }
559 }
560 }
561
Sid Manning8caf4de2012-09-17 12:49:38 +0000562 for (auto &i : sectionSymbols) {
563 auto &symbols = i.second;
564 llvm::StringRef symbolName;
565 llvm::StringRef sectionName;
Sid Manning1a601412012-07-25 16:27:21 +0000566 // Sort symbols by position.
Sid Manning8caf4de2012-09-17 12:49:38 +0000567 std::stable_sort(symbols.begin(), symbols.end(),
Sid Manning1a601412012-07-25 16:27:21 +0000568 // From ReaderCOFF.cpp:
569 // For some reason MSVC fails to allow the lambda in this context with
570 // a "illegal use of local type in type instantiation". MSVC is clearly
571 // wrong here. Force a conversion to function pointer to work around.
572 static_cast<bool(*)(const Elf_Sym*, const Elf_Sym*)>(
573 [](const Elf_Sym *A, const Elf_Sym *B) -> bool {
574 return A->st_value < B->st_value;
575 }));
576
577 // i.first is the section the symbol lives in
Sid Manning8caf4de2012-09-17 12:49:38 +0000578 for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
Sid Manning1a601412012-07-25 16:27:21 +0000579
580 StringRef symbolContents;
Sid Manning8caf4de2012-09-17 12:49:38 +0000581 if ((EC = _objFile->getSectionContents(i.first, symbolContents)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000582 return;
Sid Manning1a601412012-07-25 16:27:21 +0000583
Sid Manning8caf4de2012-09-17 12:49:38 +0000584 if ((EC = _objFile->getSymbolName(i.first, *si, symbolName)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000585 return;
Sid Manning1a601412012-07-25 16:27:21 +0000586
Sid Manning8caf4de2012-09-17 12:49:38 +0000587 if ((EC = _objFile->getSectionName(i.first, sectionName)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000588 return;
Sid Manning1a601412012-07-25 16:27:21 +0000589
Sid Manning8caf4de2012-09-17 12:49:38 +0000590 bool isCommon = false;
Sid Manning1a601412012-07-25 16:27:21 +0000591 if (((*si)->getType() == llvm::ELF::STT_COMMON)
Sid Manning8caf4de2012-09-17 12:49:38 +0000592 || (*si)->st_shndx == llvm::ELF::SHN_COMMON)
593 isCommon = true;
Sid Manning1a601412012-07-25 16:27:21 +0000594
595 // Get the symbol's content:
Sid Manning8caf4de2012-09-17 12:49:38 +0000596 llvm::ArrayRef<uint8_t> symbolData;
597 uint64_t contentSize;
Sid Manning1a601412012-07-25 16:27:21 +0000598 if (si + 1 == se) {
599 // if this is the last symbol, take up the remaining data.
Sid Manning8caf4de2012-09-17 12:49:38 +0000600 contentSize = (isCommon) ? 0
601 : ((i.first)->sh_size - (*si)->st_value);
Sid Manning1a601412012-07-25 16:27:21 +0000602 }
603 else {
Sid Manning8caf4de2012-09-17 12:49:38 +0000604 contentSize = (isCommon) ? 0
605 : (*(si + 1))->st_value - (*si)->st_value;
Sid Manning1a601412012-07-25 16:27:21 +0000606 }
607
Sid Manning8caf4de2012-09-17 12:49:38 +0000608 symbolData = llvm::ArrayRef<uint8_t>((uint8_t *)symbolContents.data()
609 + (*si)->st_value, contentSize);
610
611
612 unsigned int referenceStart = _references.size();
613
614 // Only relocations that are inside the domain of the atom are
615 // added.
616
617 // Add Rela (those with r_addend) references:
618 for (auto &rai : _relocationAddendRefences[sectionName]) {
619 if ((rai->r_offset >= (*si)->st_value) &&
620 (rai->r_offset < (*si)->st_value+contentSize)) {
621
622 auto *ERef = new (_readerStorage.Allocate
623 <ELFReference<target_endianness, is64Bits> > ())
624 ELFReference<target_endianness, is64Bits> (
625 rai, rai->r_offset-(*si)->st_value, nullptr);
626
627 _references.push_back(ERef);
628 }
629 }
630
631 // Add Rel references:
632 for (auto &ri : _relocationReferences[sectionName]) {
633 if (((ri)->r_offset >= (*si)->st_value) &&
634 ((ri)->r_offset < (*si)->st_value+contentSize)) {
635
636 auto *ERef = new (_readerStorage.Allocate
637 <ELFReference<target_endianness, is64Bits> > ())
638 ELFReference<target_endianness, is64Bits> (
639 (ri), (ri)->r_offset-(*si)->st_value, nullptr);
640
641 _references.push_back(ERef);
642 }
643 }
644
645 // Create the DefinedAtom and add it to the list of DefinedAtoms.
646 auto *newAtom = new (_readerStorage.Allocate
647 <ELFDefinedAtom<target_endianness, is64Bits> > ())
648 ELFDefinedAtom<target_endianness, is64Bits>
649 (*this, symbolName, sectionName,
650 *si, i.first, symbolData,
651 referenceStart, _references.size(), _references);
652
653 _definedAtoms._atoms.push_back(newAtom);
654 _symbolToAtomMapping.insert(std::make_pair((*si), newAtom));
655
Sid Manning1a601412012-07-25 16:27:21 +0000656 }
657 }
Sid Manning8caf4de2012-09-17 12:49:38 +0000658
659// All the Atoms and References are created. Now update each Reference's
660// target with the Atom pointer it refers to.
661 for (auto &ri : _references) {
662 const Elf_Sym *Symbol = _objFile->getElfSymbol(ri->targetSymbolIndex());
663 ri->setTarget(findAtom (Symbol));
664 }
Sid Manning1a601412012-07-25 16:27:21 +0000665 }
666
667 virtual void addAtom(const Atom&) {
668 llvm_unreachable("cannot add atoms to native .o files");
669 }
670
671 virtual const atom_collection<DefinedAtom> &defined() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000672 return _definedAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000673 }
674
675 virtual const atom_collection<UndefinedAtom> &undefined() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000676 return _undefinedAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000677 }
678
679 virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000680 return _sharedLibraryAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000681 }
682
683 virtual const atom_collection<AbsoluteAtom> &absolute() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000684 return _absoluteAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000685 }
686
Sid Manning8caf4de2012-09-17 12:49:38 +0000687 Atom *findAtom(const Elf_Sym *symbol) {
688 return (_symbolToAtomMapping.lookup(symbol));
689 }
690
691
Sid Manning1a601412012-07-25 16:27:21 +0000692private:
693 std::unique_ptr<llvm::object::ELFObjectFile<target_endianness, is64Bits> >
Sid Manning8caf4de2012-09-17 12:49:38 +0000694 _objFile;
695 atom_collection_vector<DefinedAtom> _definedAtoms;
696 atom_collection_vector<UndefinedAtom> _undefinedAtoms;
697 atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
698 atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000699
Sid Manning8caf4de2012-09-17 12:49:38 +0000700/// \brief _relocationAddendRefences and _relocationReferences contain the list
701/// of relocations references. In ELF, if a section named, ".text" has
702/// relocations will also have a section named ".rel.text" or ".rela.text"
703/// which will hold the entries. -- .rel or .rela is prepended to create
704/// the SHT_REL(A) section name.
705///
706 std::map<llvm::StringRef, std::vector<const Elf_Rela *> >
707 _relocationAddendRefences;
708 std::map<llvm::StringRef, std::vector<const Elf_Rel *> >
709 _relocationReferences;
710
711 std::vector<ELFReference<target_endianness, is64Bits> *> _references;
712 llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
713
714 llvm::BumpPtrAllocator _readerStorage;
Sid Manning1a601412012-07-25 16:27:21 +0000715};
716
717// ReaderELF is reader object that will instantiate correct FileELF
718// by examining the memory buffer for ELF class and bitwidth
719
720class ReaderELF: public Reader {
721public:
Michael J. Spencer69ed53a2012-09-10 23:46:58 +0000722 ReaderELF(const ReaderOptionsELF &) {}
Sid Manning1a601412012-07-25 16:27:21 +0000723 error_code parseFile(std::unique_ptr<MemoryBuffer> mb, std::vector<
724 std::unique_ptr<File> > &result) {
725
726 std::pair<unsigned char, unsigned char> Ident =
727 llvm::object::getElfArchType(&*mb);
728 llvm::error_code ec;
729 // Instantiate the correct FileELF template instance
730 // based on the Ident pair. Once the File is created
731 // we push the file to the vector of files already
732 // created during parser's life.
733
734 std::unique_ptr<File> f;
735
736 if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
737 == llvm::ELF::ELFDATA2LSB) {
738 f.reset(new FileELF<llvm::support::little, false>(std::move(mb), ec));
739
740 } else if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
741 == llvm::ELF::ELFDATA2MSB) {
742 f.reset(new FileELF<llvm::support::big, false> (std::move(mb), ec));
743
744 } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
745 == llvm::ELF::ELFDATA2MSB) {
746 f.reset(new FileELF<llvm::support::big, true> (std::move(mb), ec));
747
748 } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
749 == llvm::ELF::ELFDATA2LSB) {
750 f.reset(new FileELF<llvm::support::little, true> (std::move(mb), ec));
751 }
752
753 if (ec)
754 return ec;
755
756 result.push_back(std::move(f));
757 return error_code::success();
758 }
Sid Manning1a601412012-07-25 16:27:21 +0000759};
760
761} // namespace anonymous
Nick Kledzikabb69812012-05-31 22:34:00 +0000762
763namespace lld {
764
765ReaderOptionsELF::ReaderOptionsELF() {
766}
767
768ReaderOptionsELF::~ReaderOptionsELF() {
769}
770
Sid Manning1a601412012-07-25 16:27:21 +0000771Reader *createReaderELF(const ReaderOptionsELF &options) {
772 return new ReaderELF(options);
Nick Kledzikabb69812012-05-31 22:34:00 +0000773}
774
Sid Manning1a601412012-07-25 16:27:21 +0000775} // namespace LLD