blob: 45b570224048fa2282a15232a53453bd5e94a90b [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
Sid Manning05c82a42012-10-03 21:46:48 +0000240 // Common symbols are not allocated in object files,
241 // so use st_size to tell how many bytes are required.
Sid Manning8caf4de2012-09-17 12:49:38 +0000242 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
243 || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
Sid Manning05c82a42012-10-03 21:46:48 +0000244 return (uint64_t)_symbol->st_size;
Sid Manning1a601412012-07-25 16:27:21 +0000245
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 Manninge861d432012-10-01 23:23:05 +0000281 ContentType ret = typeUnknown;
Sid Manning1a601412012-07-25 16:27:21 +0000282
Sid Manning1a601412012-07-25 16:27:21 +0000283
Sid Manninge861d432012-10-01 23:23:05 +0000284 switch (_section->sh_type) {
285 case llvm::ELF::SHT_PROGBITS:
286 case llvm::ELF::SHT_DYNAMIC:
287 switch (_section->sh_flags) {
288 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR):
289 ret = typeCode;
290 break;
291 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE):
292 ret = typeData;
293 break;
294 case llvm::ELF::SHF_ALLOC:
295 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE):
296 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE |
297 llvm::ELF::SHF_STRINGS):
298 ret = typeConstant;
299 break;
300 }
301 break;
302 case llvm::ELF::SHT_NOBITS:
303 ret = typeZeroFill;
304 break;
305 case llvm::ELF::SHT_NULL:
306 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
307 || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
308 ret = typeZeroFill;
309 break;
310 }
311 return ret;
Sid Manning1a601412012-07-25 16:27:21 +0000312 }
313
314 virtual Alignment alignment() const {
315
316 // Unallocated common symbols specify their alignment
317 // constraints in st_value.
Sid Manning8caf4de2012-09-17 12:49:38 +0000318 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
319 || _symbol->st_shndx == llvm::ELF::SHN_COMMON) {
Sid Manning05c82a42012-10-03 21:46:48 +0000320 return Alignment(llvm::Log2_64(_symbol->st_value));
Sid Manning1a601412012-07-25 16:27:21 +0000321 }
322
Sid Manning8caf4de2012-09-17 12:49:38 +0000323 return Alignment(llvm::Log2_64(_section->sh_addralign));
Sid Manning1a601412012-07-25 16:27:21 +0000324 }
325
326 // Do we have a choice for ELF? All symbols
327 // live in explicit sections.
328 virtual SectionChoice sectionChoice() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000329 if (_symbol->st_shndx > llvm::ELF::SHN_LORESERVE)
Sid Manning1a601412012-07-25 16:27:21 +0000330 return sectionBasedOnContent;
331
332 return sectionCustomRequired;
333 }
334
335 virtual llvm::StringRef customSectionName() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000336 return _sectionName;
Sid Manning1a601412012-07-25 16:27:21 +0000337 }
338
339 // It isn't clear that __attribute__((used)) is transmitted to
340 // the ELF object file.
341 virtual DeadStripKind deadStrip() const {
342 return deadStripNormal;
343 }
344
345 virtual ContentPermissions permissions() const {
346
Sid Manning8caf4de2012-09-17 12:49:38 +0000347 switch (_section->sh_type) {
Sid Manning1a601412012-07-25 16:27:21 +0000348 // permRW_L is for sections modified by the runtime
349 // loader.
350 case llvm::ELF::SHT_REL:
351 case llvm::ELF::SHT_RELA:
352 return permRW_L;
353
354 case llvm::ELF::SHT_DYNAMIC:
355 case llvm::ELF::SHT_PROGBITS:
Sid Manning8caf4de2012-09-17 12:49:38 +0000356 switch (_section->sh_flags) {
Sid Manning1a601412012-07-25 16:27:21 +0000357
358 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR):
359 return permR_X;
360
361 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE):
362 return permRW_;
363
364 case llvm::ELF::SHF_ALLOC:
365 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE):
366 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE
367 | llvm::ELF::SHF_STRINGS):
368 return permR__;
369 }
370 default:
371 return perm___;
372 }
373 }
374
375 // Many non ARM architectures use ELF file format
376 // This not really a place to put a architecture
377 // specific method in an atom. A better approach is
378 // needed.
379 //
380 virtual bool isThumb() const {
381 return false;
382 }
383
384 // FIXME Not Sure if ELF supports alias atoms. Find out more.
385 virtual bool isAlias() const {
386 return false;
387 }
388
389 virtual llvm::ArrayRef<uint8_t> rawContent() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000390 return _contentData;
Sid Manning1a601412012-07-25 16:27:21 +0000391 }
392
Sid Manning8caf4de2012-09-17 12:49:38 +0000393 DefinedAtom::reference_iterator begin() const {
394 uintptr_t index = _referenceStartIndex;
395 const void *it = reinterpret_cast<const void*>(index);
396 return reference_iterator(*this, it);
Sid Manning1a601412012-07-25 16:27:21 +0000397 }
398
Sid Manning8caf4de2012-09-17 12:49:38 +0000399 DefinedAtom::reference_iterator end() const {
400 uintptr_t index = _referenceEndIndex;
401 const void *it = reinterpret_cast<const void*>(index);
402 return reference_iterator(*this, it);
403 }
404
405 const Reference *derefIterator(const void *It) const {
406 uintptr_t index = reinterpret_cast<uintptr_t>(It);
407 assert(index >= _referenceStartIndex);
408 assert(index < _referenceEndIndex);
409 return ((_referenceList)[index]);
410 }
411
412 void incrementIterator(const void*& It) const {
413 uintptr_t index = reinterpret_cast<uintptr_t>(It);
414 ++index;
415 It = reinterpret_cast<const void*>(index);
Sid Manning1a601412012-07-25 16:27:21 +0000416 }
417
418private:
Sid Manning1a601412012-07-25 16:27:21 +0000419
Sid Manning8caf4de2012-09-17 12:49:38 +0000420 const File &_owningFile;
421 llvm::StringRef _symbolName;
422 llvm::StringRef _sectionName;
423 const Elf_Sym *_symbol;
424 const Elf_Shdr *_section;
Sid Manning1a601412012-07-25 16:27:21 +0000425
Sid Manning8caf4de2012-09-17 12:49:38 +0000426 // _contentData will hold the bits that make up the atom.
427 llvm::ArrayRef<uint8_t> _contentData;
Sid Manning1a601412012-07-25 16:27:21 +0000428
429 uint64_t _ordinal;
Sid Manning8caf4de2012-09-17 12:49:38 +0000430 unsigned int _referenceStartIndex;
431 unsigned int _referenceEndIndex;
432 std::vector<ELFReference<target_endianness, is64Bits> *> &_referenceList;
Sid Manning1a601412012-07-25 16:27:21 +0000433};
434
435
436// FileELF will read a binary, find out based on the symbol table contents
437// what kind of symbol it is and create corresponding atoms for it
438
439template<llvm::support::endianness target_endianness, bool is64Bits>
440class FileELF: public File {
441
Sid Manning8caf4de2012-09-17 12:49:38 +0000442 typedef llvm::object::Elf_Sym_Impl
443 <target_endianness, is64Bits> Elf_Sym;
444 typedef llvm::object::Elf_Shdr_Impl
445 <target_endianness, is64Bits> Elf_Shdr;
446 typedef llvm::object::Elf_Rel_Impl
447 <target_endianness, is64Bits, false> Elf_Rel;
448 typedef llvm::object::Elf_Rel_Impl
449 <target_endianness, is64Bits, true> Elf_Rela;
Sid Manning1a601412012-07-25 16:27:21 +0000450
451public:
452 FileELF(std::unique_ptr<llvm::MemoryBuffer> MB, llvm::error_code &EC) :
453 File(MB->getBufferIdentifier()) {
454
Sid Manning8caf4de2012-09-17 12:49:38 +0000455 llvm::OwningPtr<llvm::object::Binary> binaryFile;
456 EC = llvm::object::createBinary(MB.release(), binaryFile);
Sid Manning1a601412012-07-25 16:27:21 +0000457 if (EC)
458 return;
459
460 // Point Obj to correct class and bitwidth ELF object
Sid Manning8caf4de2012-09-17 12:49:38 +0000461 _objFile.reset(llvm::dyn_cast<llvm::object::ELFObjectFile<target_endianness,
462 is64Bits> >(binaryFile.get()));
Sid Manning1a601412012-07-25 16:27:21 +0000463
Sid Manning8caf4de2012-09-17 12:49:38 +0000464 if (!_objFile) {
Sid Manning1a601412012-07-25 16:27:21 +0000465 EC = make_error_code(llvm::object::object_error::invalid_file_type);
466 return;
467 }
468
Sid Manning8caf4de2012-09-17 12:49:38 +0000469 binaryFile.take();
Sid Manning1a601412012-07-25 16:27:21 +0000470
Sid Manning8caf4de2012-09-17 12:49:38 +0000471 std::map< const Elf_Shdr *, std::vector<const Elf_Sym *>> sectionSymbols;
Sid Manning1a601412012-07-25 16:27:21 +0000472
Sid Manning8caf4de2012-09-17 12:49:38 +0000473// Handle: SHT_REL and SHT_RELA sections:
474// Increment over the sections, when REL/RELA section types are
475// found add the contents to the RelocationReferences map.
476
477 llvm::object::section_iterator sit(_objFile->begin_sections());
478 llvm::object::section_iterator sie(_objFile->end_sections());
479 for (; sit != sie; sit.increment(EC)) {
480 if (EC)
481 return;
482
483 const Elf_Shdr *section = _objFile->getElfSection(sit);
484
485 if (section->sh_type == llvm::ELF::SHT_RELA) {
486 llvm::StringRef sectionName;
487 if ((EC = _objFile->getSectionName(section, sectionName)))
488 return;
489 // Get rid of the leading .rela so Atoms can use their own section
490 // name to find the relocs.
491 sectionName = sectionName.drop_front(5);
492
493 auto rai(_objFile->beginELFRela(section));
494 auto rae(_objFile->endELFRela(section));
495
496 auto &Ref = _relocationAddendRefences[sectionName];
497 for (; rai != rae; rai++) {
498 Ref.push_back(&*rai);
499 }
500 }
501
502 if (section->sh_type == llvm::ELF::SHT_REL) {
503 llvm::StringRef sectionName;
504 if ((EC = _objFile->getSectionName(section, sectionName)))
505 return;
506 // Get rid of the leading .rel so Atoms can use their own section
507 // name to find the relocs.
508 sectionName = sectionName.drop_front(4);
509
510 auto ri(_objFile->beginELFRel(section));
511 auto re(_objFile->endELFRel(section));
512
513 auto &Ref = _relocationReferences[sectionName];
514 for (; ri != re; ri++) {
515 Ref.push_back(&*ri);
516 }
517 }
518 }
519
520
521// Increment over all the symbols collecting atoms and symbol
522// names for later use.
523
524 llvm::object::symbol_iterator it(_objFile->begin_symbols());
525 llvm::object::symbol_iterator ie(_objFile->end_symbols());
Sid Manning1a601412012-07-25 16:27:21 +0000526
Sid Manning429a4bc2012-07-27 14:52:18 +0000527 for (; it != ie; it.increment(EC)) {
Sid Manning1a601412012-07-25 16:27:21 +0000528 if (EC)
Sid Manning429a4bc2012-07-27 14:52:18 +0000529 return;
Sid Manning1a601412012-07-25 16:27:21 +0000530
Sid Manning8caf4de2012-09-17 12:49:38 +0000531 if ((EC = it->getSection(sit)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000532 return;
Sid Manning1a601412012-07-25 16:27:21 +0000533
Sid Manning8caf4de2012-09-17 12:49:38 +0000534 const Elf_Shdr *section = _objFile->getElfSection(sit);
535 const Elf_Sym *symbol = _objFile->getElfSymbol(it);
Sid Manning1a601412012-07-25 16:27:21 +0000536
Sid Manning8caf4de2012-09-17 12:49:38 +0000537 llvm::StringRef symbolName;
538 if ((EC = _objFile->getSymbolName(section, symbol, symbolName)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000539 return;
Sid Manning1a601412012-07-25 16:27:21 +0000540
Sid Manning8caf4de2012-09-17 12:49:38 +0000541 if (symbol->st_shndx == llvm::ELF::SHN_ABS) {
Sid Manning1a601412012-07-25 16:27:21 +0000542 // Create an absolute atom.
Sid Manning8caf4de2012-09-17 12:49:38 +0000543 auto *newAtom = new (_readerStorage.Allocate
544 <ELFAbsoluteAtom<target_endianness, is64Bits> > ())
545 ELFAbsoluteAtom<target_endianness, is64Bits>
546 (*this, symbolName, symbol->st_value);
Sid Manning1a601412012-07-25 16:27:21 +0000547
Sid Manning8caf4de2012-09-17 12:49:38 +0000548 _absoluteAtoms._atoms.push_back(newAtom);
549 _symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));
550
551 } else if (symbol->st_shndx == llvm::ELF::SHN_UNDEF) {
Sid Manning1a601412012-07-25 16:27:21 +0000552 // Create an undefined atom.
Sid Manning8caf4de2012-09-17 12:49:38 +0000553 auto *newAtom = new (_readerStorage.Allocate
554 <ELFUndefinedAtom<target_endianness, is64Bits> > ())
555 ELFUndefinedAtom<target_endianness, is64Bits>
556 (*this, symbolName, symbol);
557
558 _undefinedAtoms._atoms.push_back(newAtom);
559 _symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));
560
Sid Manning1a601412012-07-25 16:27:21 +0000561 } else {
562 // This is actually a defined symbol. Add it to its section's list of
563 // symbols.
Sid Manning8caf4de2012-09-17 12:49:38 +0000564 if (symbol->getType() == llvm::ELF::STT_NOTYPE
565 || symbol->getType() == llvm::ELF::STT_OBJECT
566 || symbol->getType() == llvm::ELF::STT_FUNC
567 || symbol->getType() == llvm::ELF::STT_SECTION
568 || symbol->getType() == llvm::ELF::STT_FILE
569 || symbol->getType() == llvm::ELF::STT_TLS
570 || symbol->getType() == llvm::ELF::STT_COMMON
571 || symbol->st_shndx == llvm::ELF::SHN_COMMON) {
572 sectionSymbols[section].push_back(symbol);
Sid Manning1a601412012-07-25 16:27:21 +0000573 }
574 else {
Sid Manning8caf4de2012-09-17 12:49:38 +0000575 llvm::errs() << "Unable to create atom for: " << symbolName << "\n";
Sid Manning1a601412012-07-25 16:27:21 +0000576 EC = llvm::object::object_error::parse_failed;
577 return;
578 }
579 }
580 }
581
Sid Manning8caf4de2012-09-17 12:49:38 +0000582 for (auto &i : sectionSymbols) {
583 auto &symbols = i.second;
584 llvm::StringRef symbolName;
585 llvm::StringRef sectionName;
Sid Manning1a601412012-07-25 16:27:21 +0000586 // Sort symbols by position.
Sid Manning8caf4de2012-09-17 12:49:38 +0000587 std::stable_sort(symbols.begin(), symbols.end(),
Sid Manning1a601412012-07-25 16:27:21 +0000588 // From ReaderCOFF.cpp:
589 // For some reason MSVC fails to allow the lambda in this context with
590 // a "illegal use of local type in type instantiation". MSVC is clearly
591 // wrong here. Force a conversion to function pointer to work around.
592 static_cast<bool(*)(const Elf_Sym*, const Elf_Sym*)>(
593 [](const Elf_Sym *A, const Elf_Sym *B) -> bool {
594 return A->st_value < B->st_value;
595 }));
596
597 // i.first is the section the symbol lives in
Sid Manning8caf4de2012-09-17 12:49:38 +0000598 for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
Sid Manning1a601412012-07-25 16:27:21 +0000599
600 StringRef symbolContents;
Sid Manning8caf4de2012-09-17 12:49:38 +0000601 if ((EC = _objFile->getSectionContents(i.first, symbolContents)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000602 return;
Sid Manning1a601412012-07-25 16:27:21 +0000603
Sid Manning8caf4de2012-09-17 12:49:38 +0000604 if ((EC = _objFile->getSymbolName(i.first, *si, symbolName)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000605 return;
Sid Manning1a601412012-07-25 16:27:21 +0000606
Sid Manning8caf4de2012-09-17 12:49:38 +0000607 if ((EC = _objFile->getSectionName(i.first, sectionName)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000608 return;
Sid Manning1a601412012-07-25 16:27:21 +0000609
Sid Manning8caf4de2012-09-17 12:49:38 +0000610 bool isCommon = false;
Sid Manning1a601412012-07-25 16:27:21 +0000611 if (((*si)->getType() == llvm::ELF::STT_COMMON)
Sid Manning8caf4de2012-09-17 12:49:38 +0000612 || (*si)->st_shndx == llvm::ELF::SHN_COMMON)
613 isCommon = true;
Sid Manning1a601412012-07-25 16:27:21 +0000614
615 // Get the symbol's content:
Sid Manning8caf4de2012-09-17 12:49:38 +0000616 llvm::ArrayRef<uint8_t> symbolData;
617 uint64_t contentSize;
Sid Manning1a601412012-07-25 16:27:21 +0000618 if (si + 1 == se) {
619 // if this is the last symbol, take up the remaining data.
Sid Manning8caf4de2012-09-17 12:49:38 +0000620 contentSize = (isCommon) ? 0
621 : ((i.first)->sh_size - (*si)->st_value);
Sid Manning1a601412012-07-25 16:27:21 +0000622 }
623 else {
Sid Manning8caf4de2012-09-17 12:49:38 +0000624 contentSize = (isCommon) ? 0
625 : (*(si + 1))->st_value - (*si)->st_value;
Sid Manning1a601412012-07-25 16:27:21 +0000626 }
627
Sid Manning8caf4de2012-09-17 12:49:38 +0000628 symbolData = llvm::ArrayRef<uint8_t>((uint8_t *)symbolContents.data()
629 + (*si)->st_value, contentSize);
630
631
632 unsigned int referenceStart = _references.size();
633
634 // Only relocations that are inside the domain of the atom are
635 // added.
636
637 // Add Rela (those with r_addend) references:
638 for (auto &rai : _relocationAddendRefences[sectionName]) {
639 if ((rai->r_offset >= (*si)->st_value) &&
640 (rai->r_offset < (*si)->st_value+contentSize)) {
641
642 auto *ERef = new (_readerStorage.Allocate
643 <ELFReference<target_endianness, is64Bits> > ())
644 ELFReference<target_endianness, is64Bits> (
645 rai, rai->r_offset-(*si)->st_value, nullptr);
646
647 _references.push_back(ERef);
648 }
649 }
650
651 // Add Rel references:
652 for (auto &ri : _relocationReferences[sectionName]) {
653 if (((ri)->r_offset >= (*si)->st_value) &&
654 ((ri)->r_offset < (*si)->st_value+contentSize)) {
655
656 auto *ERef = new (_readerStorage.Allocate
657 <ELFReference<target_endianness, is64Bits> > ())
658 ELFReference<target_endianness, is64Bits> (
659 (ri), (ri)->r_offset-(*si)->st_value, nullptr);
660
661 _references.push_back(ERef);
662 }
663 }
664
665 // Create the DefinedAtom and add it to the list of DefinedAtoms.
666 auto *newAtom = new (_readerStorage.Allocate
667 <ELFDefinedAtom<target_endianness, is64Bits> > ())
668 ELFDefinedAtom<target_endianness, is64Bits>
669 (*this, symbolName, sectionName,
670 *si, i.first, symbolData,
671 referenceStart, _references.size(), _references);
672
673 _definedAtoms._atoms.push_back(newAtom);
674 _symbolToAtomMapping.insert(std::make_pair((*si), newAtom));
675
Sid Manning1a601412012-07-25 16:27:21 +0000676 }
677 }
Sid Manning8caf4de2012-09-17 12:49:38 +0000678
679// All the Atoms and References are created. Now update each Reference's
680// target with the Atom pointer it refers to.
681 for (auto &ri : _references) {
682 const Elf_Sym *Symbol = _objFile->getElfSymbol(ri->targetSymbolIndex());
683 ri->setTarget(findAtom (Symbol));
684 }
Sid Manning1a601412012-07-25 16:27:21 +0000685 }
686
687 virtual void addAtom(const Atom&) {
688 llvm_unreachable("cannot add atoms to native .o files");
689 }
690
691 virtual const atom_collection<DefinedAtom> &defined() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000692 return _definedAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000693 }
694
695 virtual const atom_collection<UndefinedAtom> &undefined() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000696 return _undefinedAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000697 }
698
699 virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000700 return _sharedLibraryAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000701 }
702
703 virtual const atom_collection<AbsoluteAtom> &absolute() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000704 return _absoluteAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000705 }
706
Sid Manning8caf4de2012-09-17 12:49:38 +0000707 Atom *findAtom(const Elf_Sym *symbol) {
708 return (_symbolToAtomMapping.lookup(symbol));
709 }
710
711
Sid Manning1a601412012-07-25 16:27:21 +0000712private:
713 std::unique_ptr<llvm::object::ELFObjectFile<target_endianness, is64Bits> >
Sid Manning8caf4de2012-09-17 12:49:38 +0000714 _objFile;
715 atom_collection_vector<DefinedAtom> _definedAtoms;
716 atom_collection_vector<UndefinedAtom> _undefinedAtoms;
717 atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
718 atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000719
Sid Manning8caf4de2012-09-17 12:49:38 +0000720/// \brief _relocationAddendRefences and _relocationReferences contain the list
721/// of relocations references. In ELF, if a section named, ".text" has
722/// relocations will also have a section named ".rel.text" or ".rela.text"
723/// which will hold the entries. -- .rel or .rela is prepended to create
724/// the SHT_REL(A) section name.
725///
726 std::map<llvm::StringRef, std::vector<const Elf_Rela *> >
727 _relocationAddendRefences;
728 std::map<llvm::StringRef, std::vector<const Elf_Rel *> >
729 _relocationReferences;
730
731 std::vector<ELFReference<target_endianness, is64Bits> *> _references;
732 llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
733
734 llvm::BumpPtrAllocator _readerStorage;
Sid Manning1a601412012-07-25 16:27:21 +0000735};
736
737// ReaderELF is reader object that will instantiate correct FileELF
738// by examining the memory buffer for ELF class and bitwidth
739
740class ReaderELF: public Reader {
741public:
Michael J. Spencer69ed53a2012-09-10 23:46:58 +0000742 ReaderELF(const ReaderOptionsELF &) {}
Sid Manning1a601412012-07-25 16:27:21 +0000743 error_code parseFile(std::unique_ptr<MemoryBuffer> mb, std::vector<
744 std::unique_ptr<File> > &result) {
745
746 std::pair<unsigned char, unsigned char> Ident =
747 llvm::object::getElfArchType(&*mb);
748 llvm::error_code ec;
749 // Instantiate the correct FileELF template instance
750 // based on the Ident pair. Once the File is created
751 // we push the file to the vector of files already
752 // created during parser's life.
753
754 std::unique_ptr<File> f;
755
756 if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
757 == llvm::ELF::ELFDATA2LSB) {
758 f.reset(new FileELF<llvm::support::little, false>(std::move(mb), ec));
759
760 } else if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
761 == llvm::ELF::ELFDATA2MSB) {
762 f.reset(new FileELF<llvm::support::big, false> (std::move(mb), ec));
763
764 } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
765 == llvm::ELF::ELFDATA2MSB) {
766 f.reset(new FileELF<llvm::support::big, true> (std::move(mb), ec));
767
768 } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
769 == llvm::ELF::ELFDATA2LSB) {
770 f.reset(new FileELF<llvm::support::little, true> (std::move(mb), ec));
771 }
772
773 if (ec)
774 return ec;
775
776 result.push_back(std::move(f));
777 return error_code::success();
778 }
Sid Manning1a601412012-07-25 16:27:21 +0000779};
780
781} // namespace anonymous
Nick Kledzikabb69812012-05-31 22:34:00 +0000782
783namespace lld {
784
785ReaderOptionsELF::ReaderOptionsELF() {
786}
787
788ReaderOptionsELF::~ReaderOptionsELF() {
789}
790
Sid Manning1a601412012-07-25 16:27:21 +0000791Reader *createReaderELF(const ReaderOptionsELF &options) {
792 return new ReaderELF(options);
Nick Kledzikabb69812012-05-31 22:34:00 +0000793}
794
Sid Manning1a601412012-07-25 16:27:21 +0000795} // namespace LLD