blob: 6fa30252993c8fd3fc63433348c267d8251fbf7f [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#include "lld/ReaderWriter/ReaderELF.h"
15#include "lld/Core/File.h"
Sid Manning8caf4de2012-09-17 12:49:38 +000016#include "lld/Core/Reference.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000017
Sid Manning1a601412012-07-25 16:27:21 +000018#include "llvm/ADT/ArrayRef.h"
Sid Manning8caf4de2012-09-17 12:49:38 +000019#include "llvm/ADT/SmallString.h"
Sid Manning1a601412012-07-25 16:27:21 +000020#include "llvm/ADT/StringRef.h"
21#include "llvm/Object/ELF.h"
22#include "llvm/Object/ObjectFile.h"
23#include "llvm/Support/Allocator.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000024#include "llvm/Support/Casting.h"
Sid Manning1a601412012-07-25 16:27:21 +000025#include "llvm/Support/ELF.h"
26#include "llvm/Support/Endian.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000027#include "llvm/Support/ErrorHandling.h"
Sid Manning1a601412012-07-25 16:27:21 +000028#include "llvm/Support/MathExtras.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000029#include "llvm/Support/Memory.h"
30#include "llvm/Support/MemoryBuffer.h"
31#include "llvm/Support/raw_ostream.h"
32#include "llvm/Support/system_error.h"
33
Sid Manning1a601412012-07-25 16:27:21 +000034
Nick Kledzikabb69812012-05-31 22:34:00 +000035#include <map>
36#include <vector>
37
Sid Manning1a601412012-07-25 16:27:21 +000038using llvm::object::Elf_Sym_Impl;
39using namespace lld;
40
41namespace { // anonymous
42
Sid Manning1a601412012-07-25 16:27:21 +000043
Sid Manning8caf4de2012-09-17 12:49:38 +000044/// \brief Relocation References: Defined Atoms may contain
45/// references that will need to be patched before
46/// the executable is written.
47template <llvm::support::endianness target_endianness, bool is64Bits>
48class ELFReference final : public Reference {
49
50 typedef llvm::object::Elf_Rel_Impl
51 <target_endianness, is64Bits, false> Elf_Rel;
52 typedef llvm::object::Elf_Rel_Impl
53 <target_endianness, is64Bits, true> Elf_Rela;
Sid Manning1a601412012-07-25 16:27:21 +000054public:
Sid Manning1a601412012-07-25 16:27:21 +000055
Sid Manning8caf4de2012-09-17 12:49:38 +000056 ELFReference(const Elf_Rela *rela, uint64_t offset, const Atom *target)
57 : _target(target)
58 , _targetSymbolIndex(rela->getSymbol())
59 , _offsetInAtom(offset)
60 , _addend(rela->r_addend)
61 , _kind(rela->getType()) {}
62
63 ELFReference(const Elf_Rel *rel, uint64_t offset, const Atom *target)
64 : _target(target)
65 , _targetSymbolIndex(rel->getSymbol())
66 , _offsetInAtom(offset)
67 , _addend(0)
68 , _kind(rel->getType()) {}
69
70
71 virtual uint64_t offsetInAtom() const {
72 return _offsetInAtom;
Sid Manning1a601412012-07-25 16:27:21 +000073 }
74
Sid Manning8caf4de2012-09-17 12:49:38 +000075 virtual Kind kind() const {
76 return _kind;
Sid Manning1a601412012-07-25 16:27:21 +000077 }
78
Sid Manning8caf4de2012-09-17 12:49:38 +000079 virtual void setKind(Kind kind) {
80 _kind = kind;
Sid Manning1a601412012-07-25 16:27:21 +000081 }
82
Sid Manning8caf4de2012-09-17 12:49:38 +000083 virtual const Atom *target() const {
84 return _target;
85 }
86
87/// \brief targetSymbolIndex: This is the symbol table index that contains
88/// the target reference.
89 uint64_t targetSymbolIndex() const {
90 return _targetSymbolIndex;
91 }
92
93 virtual Addend addend() const {
94 return _addend;
95 }
96
97 virtual void setAddend(Addend A) {
98 _addend = A;
99 }
100
101 virtual void setTarget(const Atom *newAtom) {
102 _target = newAtom;
103 }
Sid Manning1a601412012-07-25 16:27:21 +0000104private:
Sid Manning8caf4de2012-09-17 12:49:38 +0000105 const Atom *_target;
106 uint64_t _targetSymbolIndex;
107 uint64_t _offsetInAtom;
108 Addend _addend;
109 Kind _kind;
Sid Manning1a601412012-07-25 16:27:21 +0000110};
111
112
Sid Manning8caf4de2012-09-17 12:49:38 +0000113/// \brief ELFAbsoluteAtom: These atoms store symbols that are fixed to a
114/// particular address. This atom has no content its address will be used by
115/// the writer to fixup references that point to it.
Sid Manning1a601412012-07-25 16:27:21 +0000116template<llvm::support::endianness target_endianness, bool is64Bits>
Sid Manning2a590242012-10-18 17:16:19 +0000117class ELFAbsoluteAtom final : public AbsoluteAtom {
118
119 typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
Sid Manning8caf4de2012-09-17 12:49:38 +0000120
121public:
122 ELFAbsoluteAtom(const File &file,
123 llvm::StringRef name,
Sid Manning2a590242012-10-18 17:16:19 +0000124 const Elf_Sym *symbol,
Sid Manning8caf4de2012-09-17 12:49:38 +0000125 uint64_t value)
126 : _owningFile(file)
127 , _name(name)
Sid Manning2a590242012-10-18 17:16:19 +0000128 , _symbol(symbol)
Sid Manning8caf4de2012-09-17 12:49:38 +0000129 , _value(value)
130 {}
131
132 virtual const class File &file() const {
133 return _owningFile;
134 }
135
Sid Manning2a590242012-10-18 17:16:19 +0000136 virtual Scope scope() const {
137 if (_symbol->st_other == llvm::ELF::STV_HIDDEN)
138 return scopeLinkageUnit;
139 if (_symbol->getBinding() == llvm::ELF::STB_LOCAL)
140 return scopeTranslationUnit;
141 else
142 return scopeGlobal;
143 }
144
Sid Manning8caf4de2012-09-17 12:49:38 +0000145 virtual llvm::StringRef name() const {
146 return _name;
147 }
148
149 virtual uint64_t value() const {
150 return _value;
151 }
152
153private:
154 const File &_owningFile;
155 llvm::StringRef _name;
Sid Manning2a590242012-10-18 17:16:19 +0000156 const Elf_Sym *_symbol;
Sid Manning8caf4de2012-09-17 12:49:38 +0000157 uint64_t _value;
158};
159
160
161/// \brief ELFUndefinedAtom: These atoms store undefined symbols and are
162/// place holders that will be replaced by defined atoms later in the
163/// linking process.
164template<llvm::support::endianness target_endianness, bool is64Bits>
165class ELFUndefinedAtom final: public UndefinedAtom {
Sid Manning1a601412012-07-25 16:27:21 +0000166
167 typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
168
169public:
Sid Manning8caf4de2012-09-17 12:49:38 +0000170 ELFUndefinedAtom(const File &file,
171 llvm::StringRef name,
172 const Elf_Sym *symbol)
173 : _owningFile(file)
174 , _name(name)
175 , _symbol(symbol)
Sid Manning1a601412012-07-25 16:27:21 +0000176 {}
177
178 virtual const class File &file() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000179 return _owningFile;
Sid Manning1a601412012-07-25 16:27:21 +0000180 }
181
182 virtual llvm::StringRef name() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000183 return _name;
Sid Manning1a601412012-07-25 16:27:21 +0000184 }
185
186 // FIXME What distinguishes a symbol in ELF that can help
187 // decide if the symbol is undefined only during build and not
188 // runtime? This will make us choose canBeNullAtBuildtime and
189 // canBeNullAtRuntime
190 //
191 virtual CanBeNull canBeNull() const {
192
Sid Manning8caf4de2012-09-17 12:49:38 +0000193 if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
Sid Manning1a601412012-07-25 16:27:21 +0000194 return CanBeNull::canBeNullAtBuildtime;
195 else
196 return CanBeNull::canBeNullNever;
197 }
198
199private:
Sid Manning8caf4de2012-09-17 12:49:38 +0000200 const File &_owningFile;
201 llvm::StringRef _name;
202 const Elf_Sym *_symbol;
Sid Manning1a601412012-07-25 16:27:21 +0000203};
204
205
Sid Manning8caf4de2012-09-17 12:49:38 +0000206/// \brief ELFDefinedAtom: This atom stores defined symbols and will contain
207/// either data or code.
Sid Manning1a601412012-07-25 16:27:21 +0000208template<llvm::support::endianness target_endianness, bool is64Bits>
Sid Manning8caf4de2012-09-17 12:49:38 +0000209class ELFDefinedAtom final: public DefinedAtom {
Sid Manning1a601412012-07-25 16:27:21 +0000210
211 typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
212 typedef llvm::object::Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
213
214public:
Sid Manning8caf4de2012-09-17 12:49:38 +0000215 ELFDefinedAtom(const File &file,
216 llvm::StringRef symbolName,
217 llvm::StringRef sectionName,
218 const Elf_Sym *symbol,
219 const Elf_Shdr *section,
220 llvm::ArrayRef<uint8_t> contentData,
221 unsigned int referenceStart,
222 unsigned int referenceEnd,
223 std::vector<ELFReference
224 <target_endianness, is64Bits> *> &referenceList)
225
226 : _owningFile(file)
227 , _symbolName(symbolName)
228 , _sectionName(sectionName)
229 , _symbol(symbol)
230 , _section(section)
231 , _contentData(contentData)
232 , _referenceStartIndex(referenceStart)
233 , _referenceEndIndex(referenceEnd)
234 , _referenceList(referenceList) {
235 static uint64_t orderNumber = 0;
236 _ordinal = ++orderNumber;
Sid Manning1a601412012-07-25 16:27:21 +0000237 }
238
239 virtual const class File &file() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000240 return _owningFile;
Sid Manning1a601412012-07-25 16:27:21 +0000241 }
242
243 virtual llvm::StringRef name() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000244 return _symbolName;
Sid Manning1a601412012-07-25 16:27:21 +0000245 }
246
247 virtual uint64_t ordinal() const {
248 return _ordinal;
249 }
250
251 virtual uint64_t size() const {
252
Sid Manning05c82a42012-10-03 21:46:48 +0000253 // Common symbols are not allocated in object files,
254 // so use st_size to tell how many bytes are required.
Sid Manning8caf4de2012-09-17 12:49:38 +0000255 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
256 || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
Sid Manning05c82a42012-10-03 21:46:48 +0000257 return (uint64_t)_symbol->st_size;
Sid Manning1a601412012-07-25 16:27:21 +0000258
Sid Manning8caf4de2012-09-17 12:49:38 +0000259 return _contentData.size();
Sid Manning1a601412012-07-25 16:27:21 +0000260
261 }
262
263 virtual Scope scope() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000264 if (_symbol->st_other == llvm::ELF::STV_HIDDEN)
Sid Manning1a601412012-07-25 16:27:21 +0000265 return scopeLinkageUnit;
Sid Manning8caf4de2012-09-17 12:49:38 +0000266 else if (_symbol->getBinding() != llvm::ELF::STB_LOCAL)
Sid Manning1a601412012-07-25 16:27:21 +0000267 return scopeGlobal;
268 else
269 return scopeTranslationUnit;
270 }
271
272 // FIXME Need to revisit this in future.
273
274 virtual Interposable interposable() const {
275 return interposeNo;
276 }
277
278 // FIXME What ways can we determine this in ELF?
279
280 virtual Merge merge() const {
281
Sid Manning8caf4de2012-09-17 12:49:38 +0000282 if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
Sid Manning1a601412012-07-25 16:27:21 +0000283 return mergeAsWeak;
284
Sid Manning8caf4de2012-09-17 12:49:38 +0000285 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
286 || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
Sid Manning1a601412012-07-25 16:27:21 +0000287 return mergeAsTentative;
288
289 return mergeNo;
290 }
291
292 virtual ContentType contentType() const {
293
Sid Manninge861d432012-10-01 23:23:05 +0000294 ContentType ret = typeUnknown;
Sid Manning1a601412012-07-25 16:27:21 +0000295
Sid Manning1a601412012-07-25 16:27:21 +0000296
Sid Manninge861d432012-10-01 23:23:05 +0000297 switch (_section->sh_type) {
298 case llvm::ELF::SHT_PROGBITS:
299 case llvm::ELF::SHT_DYNAMIC:
300 switch (_section->sh_flags) {
301 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR):
302 ret = typeCode;
303 break;
304 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE):
305 ret = typeData;
306 break;
307 case llvm::ELF::SHF_ALLOC:
308 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE):
309 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE |
310 llvm::ELF::SHF_STRINGS):
311 ret = typeConstant;
312 break;
313 }
314 break;
315 case llvm::ELF::SHT_NOBITS:
316 ret = typeZeroFill;
317 break;
318 case llvm::ELF::SHT_NULL:
319 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
320 || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
321 ret = typeZeroFill;
322 break;
323 }
Sid Manning2a590242012-10-18 17:16:19 +0000324
Sid Manninge861d432012-10-01 23:23:05 +0000325 return ret;
Sid Manning1a601412012-07-25 16:27:21 +0000326 }
327
328 virtual Alignment alignment() const {
329
330 // Unallocated common symbols specify their alignment
331 // constraints in st_value.
Sid Manning8caf4de2012-09-17 12:49:38 +0000332 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
333 || _symbol->st_shndx == llvm::ELF::SHN_COMMON) {
Sid Manning05c82a42012-10-03 21:46:48 +0000334 return Alignment(llvm::Log2_64(_symbol->st_value));
Sid Manning1a601412012-07-25 16:27:21 +0000335 }
Sid Manning8caf4de2012-09-17 12:49:38 +0000336 return Alignment(llvm::Log2_64(_section->sh_addralign));
Sid Manning1a601412012-07-25 16:27:21 +0000337 }
338
339 // Do we have a choice for ELF? All symbols
340 // live in explicit sections.
341 virtual SectionChoice sectionChoice() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000342 if (_symbol->st_shndx > llvm::ELF::SHN_LORESERVE)
Sid Manning1a601412012-07-25 16:27:21 +0000343 return sectionBasedOnContent;
344
345 return sectionCustomRequired;
346 }
347
348 virtual llvm::StringRef customSectionName() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000349 return _sectionName;
Sid Manning1a601412012-07-25 16:27:21 +0000350 }
351
352 // It isn't clear that __attribute__((used)) is transmitted to
353 // the ELF object file.
354 virtual DeadStripKind deadStrip() const {
355 return deadStripNormal;
356 }
357
358 virtual ContentPermissions permissions() const {
359
Sid Manning8caf4de2012-09-17 12:49:38 +0000360 switch (_section->sh_type) {
Sid Manning1a601412012-07-25 16:27:21 +0000361 // permRW_L is for sections modified by the runtime
362 // loader.
363 case llvm::ELF::SHT_REL:
364 case llvm::ELF::SHT_RELA:
365 return permRW_L;
366
367 case llvm::ELF::SHT_DYNAMIC:
368 case llvm::ELF::SHT_PROGBITS:
Sid Manning8caf4de2012-09-17 12:49:38 +0000369 switch (_section->sh_flags) {
Sid Manning1a601412012-07-25 16:27:21 +0000370
371 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR):
372 return permR_X;
373
374 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE):
375 return permRW_;
376
377 case llvm::ELF::SHF_ALLOC:
378 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE):
379 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE
380 | llvm::ELF::SHF_STRINGS):
381 return permR__;
382 }
383 default:
384 return perm___;
385 }
386 }
387
388 // Many non ARM architectures use ELF file format
389 // This not really a place to put a architecture
390 // specific method in an atom. A better approach is
391 // needed.
392 //
393 virtual bool isThumb() const {
394 return false;
395 }
396
397 // FIXME Not Sure if ELF supports alias atoms. Find out more.
398 virtual bool isAlias() const {
399 return false;
400 }
401
402 virtual llvm::ArrayRef<uint8_t> rawContent() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000403 return _contentData;
Sid Manning1a601412012-07-25 16:27:21 +0000404 }
405
Sid Manning8caf4de2012-09-17 12:49:38 +0000406 DefinedAtom::reference_iterator begin() const {
407 uintptr_t index = _referenceStartIndex;
408 const void *it = reinterpret_cast<const void*>(index);
409 return reference_iterator(*this, it);
Sid Manning1a601412012-07-25 16:27:21 +0000410 }
411
Sid Manning8caf4de2012-09-17 12:49:38 +0000412 DefinedAtom::reference_iterator end() const {
413 uintptr_t index = _referenceEndIndex;
414 const void *it = reinterpret_cast<const void*>(index);
415 return reference_iterator(*this, it);
416 }
417
418 const Reference *derefIterator(const void *It) const {
419 uintptr_t index = reinterpret_cast<uintptr_t>(It);
420 assert(index >= _referenceStartIndex);
421 assert(index < _referenceEndIndex);
422 return ((_referenceList)[index]);
423 }
424
425 void incrementIterator(const void*& It) const {
426 uintptr_t index = reinterpret_cast<uintptr_t>(It);
427 ++index;
428 It = reinterpret_cast<const void*>(index);
Sid Manning1a601412012-07-25 16:27:21 +0000429 }
430
431private:
Sid Manning1a601412012-07-25 16:27:21 +0000432
Sid Manning8caf4de2012-09-17 12:49:38 +0000433 const File &_owningFile;
434 llvm::StringRef _symbolName;
435 llvm::StringRef _sectionName;
436 const Elf_Sym *_symbol;
437 const Elf_Shdr *_section;
Sid Manning8caf4de2012-09-17 12:49:38 +0000438 // _contentData will hold the bits that make up the atom.
439 llvm::ArrayRef<uint8_t> _contentData;
Sid Manning1a601412012-07-25 16:27:21 +0000440
441 uint64_t _ordinal;
Sid Manning8caf4de2012-09-17 12:49:38 +0000442 unsigned int _referenceStartIndex;
443 unsigned int _referenceEndIndex;
444 std::vector<ELFReference<target_endianness, is64Bits> *> &_referenceList;
Sid Manning1a601412012-07-25 16:27:21 +0000445};
446
447
448// FileELF will read a binary, find out based on the symbol table contents
449// what kind of symbol it is and create corresponding atoms for it
450
451template<llvm::support::endianness target_endianness, bool is64Bits>
452class FileELF: public File {
453
Sid Manning8caf4de2012-09-17 12:49:38 +0000454 typedef llvm::object::Elf_Sym_Impl
455 <target_endianness, is64Bits> Elf_Sym;
456 typedef llvm::object::Elf_Shdr_Impl
457 <target_endianness, is64Bits> Elf_Shdr;
458 typedef llvm::object::Elf_Rel_Impl
459 <target_endianness, is64Bits, false> Elf_Rel;
460 typedef llvm::object::Elf_Rel_Impl
461 <target_endianness, is64Bits, true> Elf_Rela;
Sid Manning1a601412012-07-25 16:27:21 +0000462
463public:
464 FileELF(std::unique_ptr<llvm::MemoryBuffer> MB, llvm::error_code &EC) :
465 File(MB->getBufferIdentifier()) {
466
Sid Manning8caf4de2012-09-17 12:49:38 +0000467 llvm::OwningPtr<llvm::object::Binary> binaryFile;
468 EC = llvm::object::createBinary(MB.release(), binaryFile);
Sid Manning1a601412012-07-25 16:27:21 +0000469 if (EC)
470 return;
471
472 // Point Obj to correct class and bitwidth ELF object
Sid Manning8caf4de2012-09-17 12:49:38 +0000473 _objFile.reset(llvm::dyn_cast<llvm::object::ELFObjectFile<target_endianness,
474 is64Bits> >(binaryFile.get()));
Sid Manning1a601412012-07-25 16:27:21 +0000475
Sid Manning8caf4de2012-09-17 12:49:38 +0000476 if (!_objFile) {
Sid Manning1a601412012-07-25 16:27:21 +0000477 EC = make_error_code(llvm::object::object_error::invalid_file_type);
478 return;
479 }
480
Sid Manning8caf4de2012-09-17 12:49:38 +0000481 binaryFile.take();
Sid Manning1a601412012-07-25 16:27:21 +0000482
Sid Manning8caf4de2012-09-17 12:49:38 +0000483 std::map< const Elf_Shdr *, std::vector<const Elf_Sym *>> sectionSymbols;
Sid Manning1a601412012-07-25 16:27:21 +0000484
Sid Manning8caf4de2012-09-17 12:49:38 +0000485// Handle: SHT_REL and SHT_RELA sections:
486// Increment over the sections, when REL/RELA section types are
487// found add the contents to the RelocationReferences map.
488
489 llvm::object::section_iterator sit(_objFile->begin_sections());
490 llvm::object::section_iterator sie(_objFile->end_sections());
491 for (; sit != sie; sit.increment(EC)) {
492 if (EC)
493 return;
494
495 const Elf_Shdr *section = _objFile->getElfSection(sit);
496
497 if (section->sh_type == llvm::ELF::SHT_RELA) {
498 llvm::StringRef sectionName;
499 if ((EC = _objFile->getSectionName(section, sectionName)))
500 return;
501 // Get rid of the leading .rela so Atoms can use their own section
502 // name to find the relocs.
503 sectionName = sectionName.drop_front(5);
504
505 auto rai(_objFile->beginELFRela(section));
506 auto rae(_objFile->endELFRela(section));
507
508 auto &Ref = _relocationAddendRefences[sectionName];
509 for (; rai != rae; rai++) {
510 Ref.push_back(&*rai);
511 }
512 }
513
514 if (section->sh_type == llvm::ELF::SHT_REL) {
515 llvm::StringRef sectionName;
516 if ((EC = _objFile->getSectionName(section, sectionName)))
517 return;
518 // Get rid of the leading .rel so Atoms can use their own section
519 // name to find the relocs.
520 sectionName = sectionName.drop_front(4);
521
522 auto ri(_objFile->beginELFRel(section));
523 auto re(_objFile->endELFRel(section));
524
525 auto &Ref = _relocationReferences[sectionName];
526 for (; ri != re; ri++) {
527 Ref.push_back(&*ri);
528 }
529 }
530 }
531
532
533// Increment over all the symbols collecting atoms and symbol
534// names for later use.
535
536 llvm::object::symbol_iterator it(_objFile->begin_symbols());
537 llvm::object::symbol_iterator ie(_objFile->end_symbols());
Sid Manning1a601412012-07-25 16:27:21 +0000538
Sid Manning429a4bc2012-07-27 14:52:18 +0000539 for (; it != ie; it.increment(EC)) {
Sid Manning1a601412012-07-25 16:27:21 +0000540 if (EC)
Sid Manning429a4bc2012-07-27 14:52:18 +0000541 return;
Sid Manning1a601412012-07-25 16:27:21 +0000542
Sid Manning8caf4de2012-09-17 12:49:38 +0000543 if ((EC = it->getSection(sit)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000544 return;
Sid Manning1a601412012-07-25 16:27:21 +0000545
Sid Manning8caf4de2012-09-17 12:49:38 +0000546 const Elf_Shdr *section = _objFile->getElfSection(sit);
547 const Elf_Sym *symbol = _objFile->getElfSymbol(it);
Sid Manning1a601412012-07-25 16:27:21 +0000548
Sid Manning8caf4de2012-09-17 12:49:38 +0000549 llvm::StringRef symbolName;
550 if ((EC = _objFile->getSymbolName(section, symbol, symbolName)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000551 return;
Sid Manning1a601412012-07-25 16:27:21 +0000552
Sid Manning8caf4de2012-09-17 12:49:38 +0000553 if (symbol->st_shndx == llvm::ELF::SHN_ABS) {
Sid Manning1a601412012-07-25 16:27:21 +0000554 // Create an absolute atom.
Sid Manning8caf4de2012-09-17 12:49:38 +0000555 auto *newAtom = new (_readerStorage.Allocate
556 <ELFAbsoluteAtom<target_endianness, is64Bits> > ())
557 ELFAbsoluteAtom<target_endianness, is64Bits>
Sid Manning2a590242012-10-18 17:16:19 +0000558 (*this, symbolName, symbol, symbol->st_value);
Sid Manning1a601412012-07-25 16:27:21 +0000559
Sid Manning8caf4de2012-09-17 12:49:38 +0000560 _absoluteAtoms._atoms.push_back(newAtom);
561 _symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));
562
563 } else if (symbol->st_shndx == llvm::ELF::SHN_UNDEF) {
Sid Manning1a601412012-07-25 16:27:21 +0000564 // Create an undefined atom.
Sid Manning8caf4de2012-09-17 12:49:38 +0000565 auto *newAtom = new (_readerStorage.Allocate
566 <ELFUndefinedAtom<target_endianness, is64Bits> > ())
567 ELFUndefinedAtom<target_endianness, is64Bits>
568 (*this, symbolName, symbol);
569
570 _undefinedAtoms._atoms.push_back(newAtom);
571 _symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));
572
Sid Manning1a601412012-07-25 16:27:21 +0000573 } else {
574 // This is actually a defined symbol. Add it to its section's list of
575 // symbols.
Sid Manning8caf4de2012-09-17 12:49:38 +0000576 if (symbol->getType() == llvm::ELF::STT_NOTYPE
577 || symbol->getType() == llvm::ELF::STT_OBJECT
578 || symbol->getType() == llvm::ELF::STT_FUNC
579 || symbol->getType() == llvm::ELF::STT_SECTION
580 || symbol->getType() == llvm::ELF::STT_FILE
581 || symbol->getType() == llvm::ELF::STT_TLS
582 || symbol->getType() == llvm::ELF::STT_COMMON
583 || symbol->st_shndx == llvm::ELF::SHN_COMMON) {
584 sectionSymbols[section].push_back(symbol);
Sid Manning1a601412012-07-25 16:27:21 +0000585 }
586 else {
Sid Manning8caf4de2012-09-17 12:49:38 +0000587 llvm::errs() << "Unable to create atom for: " << symbolName << "\n";
Sid Manning1a601412012-07-25 16:27:21 +0000588 EC = llvm::object::object_error::parse_failed;
589 return;
590 }
591 }
592 }
593
Sid Manning8caf4de2012-09-17 12:49:38 +0000594 for (auto &i : sectionSymbols) {
595 auto &symbols = i.second;
596 llvm::StringRef symbolName;
597 llvm::StringRef sectionName;
Sid Manning1a601412012-07-25 16:27:21 +0000598 // Sort symbols by position.
Sid Manning8caf4de2012-09-17 12:49:38 +0000599 std::stable_sort(symbols.begin(), symbols.end(),
Sid Manning1a601412012-07-25 16:27:21 +0000600 // From ReaderCOFF.cpp:
601 // For some reason MSVC fails to allow the lambda in this context with
602 // a "illegal use of local type in type instantiation". MSVC is clearly
603 // wrong here. Force a conversion to function pointer to work around.
604 static_cast<bool(*)(const Elf_Sym*, const Elf_Sym*)>(
605 [](const Elf_Sym *A, const Elf_Sym *B) -> bool {
606 return A->st_value < B->st_value;
607 }));
608
609 // i.first is the section the symbol lives in
Sid Manning8caf4de2012-09-17 12:49:38 +0000610 for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
Sid Manning1a601412012-07-25 16:27:21 +0000611
612 StringRef symbolContents;
Sid Manning8caf4de2012-09-17 12:49:38 +0000613 if ((EC = _objFile->getSectionContents(i.first, symbolContents)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000614 return;
Sid Manning1a601412012-07-25 16:27:21 +0000615
Sid Manning8caf4de2012-09-17 12:49:38 +0000616 if ((EC = _objFile->getSymbolName(i.first, *si, symbolName)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000617 return;
Sid Manning1a601412012-07-25 16:27:21 +0000618
Sid Manning8caf4de2012-09-17 12:49:38 +0000619 if ((EC = _objFile->getSectionName(i.first, sectionName)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000620 return;
Sid Manning1a601412012-07-25 16:27:21 +0000621
Sid Manning8caf4de2012-09-17 12:49:38 +0000622 bool isCommon = false;
Sid Manning1a601412012-07-25 16:27:21 +0000623 if (((*si)->getType() == llvm::ELF::STT_COMMON)
Sid Manning8caf4de2012-09-17 12:49:38 +0000624 || (*si)->st_shndx == llvm::ELF::SHN_COMMON)
625 isCommon = true;
Sid Manning1a601412012-07-25 16:27:21 +0000626
627 // Get the symbol's content:
Sid Manning8caf4de2012-09-17 12:49:38 +0000628 llvm::ArrayRef<uint8_t> symbolData;
629 uint64_t contentSize;
Sid Manning1a601412012-07-25 16:27:21 +0000630 if (si + 1 == se) {
631 // if this is the last symbol, take up the remaining data.
Sid Manning8caf4de2012-09-17 12:49:38 +0000632 contentSize = (isCommon) ? 0
633 : ((i.first)->sh_size - (*si)->st_value);
Sid Manning1a601412012-07-25 16:27:21 +0000634 }
635 else {
Sid Manning8caf4de2012-09-17 12:49:38 +0000636 contentSize = (isCommon) ? 0
637 : (*(si + 1))->st_value - (*si)->st_value;
Sid Manning1a601412012-07-25 16:27:21 +0000638 }
639
Sid Manning8caf4de2012-09-17 12:49:38 +0000640 symbolData = llvm::ArrayRef<uint8_t>((uint8_t *)symbolContents.data()
641 + (*si)->st_value, contentSize);
642
643
644 unsigned int referenceStart = _references.size();
645
646 // Only relocations that are inside the domain of the atom are
647 // added.
648
649 // Add Rela (those with r_addend) references:
650 for (auto &rai : _relocationAddendRefences[sectionName]) {
651 if ((rai->r_offset >= (*si)->st_value) &&
652 (rai->r_offset < (*si)->st_value+contentSize)) {
653
654 auto *ERef = new (_readerStorage.Allocate
655 <ELFReference<target_endianness, is64Bits> > ())
656 ELFReference<target_endianness, is64Bits> (
657 rai, rai->r_offset-(*si)->st_value, nullptr);
658
659 _references.push_back(ERef);
660 }
661 }
662
663 // Add Rel references:
664 for (auto &ri : _relocationReferences[sectionName]) {
665 if (((ri)->r_offset >= (*si)->st_value) &&
666 ((ri)->r_offset < (*si)->st_value+contentSize)) {
667
668 auto *ERef = new (_readerStorage.Allocate
669 <ELFReference<target_endianness, is64Bits> > ())
670 ELFReference<target_endianness, is64Bits> (
671 (ri), (ri)->r_offset-(*si)->st_value, nullptr);
672
673 _references.push_back(ERef);
674 }
675 }
676
677 // Create the DefinedAtom and add it to the list of DefinedAtoms.
678 auto *newAtom = new (_readerStorage.Allocate
679 <ELFDefinedAtom<target_endianness, is64Bits> > ())
680 ELFDefinedAtom<target_endianness, is64Bits>
681 (*this, symbolName, sectionName,
682 *si, i.first, symbolData,
683 referenceStart, _references.size(), _references);
684
685 _definedAtoms._atoms.push_back(newAtom);
686 _symbolToAtomMapping.insert(std::make_pair((*si), newAtom));
687
Sid Manning1a601412012-07-25 16:27:21 +0000688 }
689 }
Sid Manning8caf4de2012-09-17 12:49:38 +0000690
691// All the Atoms and References are created. Now update each Reference's
692// target with the Atom pointer it refers to.
693 for (auto &ri : _references) {
694 const Elf_Sym *Symbol = _objFile->getElfSymbol(ri->targetSymbolIndex());
695 ri->setTarget(findAtom (Symbol));
696 }
Sid Manning1a601412012-07-25 16:27:21 +0000697 }
698
699 virtual void addAtom(const Atom&) {
700 llvm_unreachable("cannot add atoms to native .o files");
701 }
702
703 virtual const atom_collection<DefinedAtom> &defined() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000704 return _definedAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000705 }
706
707 virtual const atom_collection<UndefinedAtom> &undefined() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000708 return _undefinedAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000709 }
710
711 virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000712 return _sharedLibraryAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000713 }
714
715 virtual const atom_collection<AbsoluteAtom> &absolute() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000716 return _absoluteAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000717 }
718
Sid Manning8caf4de2012-09-17 12:49:38 +0000719 Atom *findAtom(const Elf_Sym *symbol) {
720 return (_symbolToAtomMapping.lookup(symbol));
721 }
722
723
Sid Manning1a601412012-07-25 16:27:21 +0000724private:
725 std::unique_ptr<llvm::object::ELFObjectFile<target_endianness, is64Bits> >
Sid Manning8caf4de2012-09-17 12:49:38 +0000726 _objFile;
727 atom_collection_vector<DefinedAtom> _definedAtoms;
728 atom_collection_vector<UndefinedAtom> _undefinedAtoms;
729 atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
730 atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000731
Sid Manning8caf4de2012-09-17 12:49:38 +0000732/// \brief _relocationAddendRefences and _relocationReferences contain the list
733/// of relocations references. In ELF, if a section named, ".text" has
734/// relocations will also have a section named ".rel.text" or ".rela.text"
735/// which will hold the entries. -- .rel or .rela is prepended to create
736/// the SHT_REL(A) section name.
737///
738 std::map<llvm::StringRef, std::vector<const Elf_Rela *> >
739 _relocationAddendRefences;
740 std::map<llvm::StringRef, std::vector<const Elf_Rel *> >
741 _relocationReferences;
742
743 std::vector<ELFReference<target_endianness, is64Bits> *> _references;
744 llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
745
746 llvm::BumpPtrAllocator _readerStorage;
Sid Manning1a601412012-07-25 16:27:21 +0000747};
748
749// ReaderELF is reader object that will instantiate correct FileELF
750// by examining the memory buffer for ELF class and bitwidth
751
752class ReaderELF: public Reader {
753public:
Michael J. Spencer69ed53a2012-09-10 23:46:58 +0000754 ReaderELF(const ReaderOptionsELF &) {}
Sid Manning1a601412012-07-25 16:27:21 +0000755 error_code parseFile(std::unique_ptr<MemoryBuffer> mb, std::vector<
756 std::unique_ptr<File> > &result) {
757
758 std::pair<unsigned char, unsigned char> Ident =
759 llvm::object::getElfArchType(&*mb);
760 llvm::error_code ec;
761 // Instantiate the correct FileELF template instance
762 // based on the Ident pair. Once the File is created
763 // we push the file to the vector of files already
764 // created during parser's life.
765
766 std::unique_ptr<File> f;
767
768 if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
769 == llvm::ELF::ELFDATA2LSB) {
770 f.reset(new FileELF<llvm::support::little, false>(std::move(mb), ec));
771
772 } else if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
773 == llvm::ELF::ELFDATA2MSB) {
774 f.reset(new FileELF<llvm::support::big, false> (std::move(mb), ec));
775
776 } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
777 == llvm::ELF::ELFDATA2MSB) {
778 f.reset(new FileELF<llvm::support::big, true> (std::move(mb), ec));
779
780 } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
781 == llvm::ELF::ELFDATA2LSB) {
782 f.reset(new FileELF<llvm::support::little, true> (std::move(mb), ec));
783 }
784
785 if (ec)
786 return ec;
787
788 result.push_back(std::move(f));
789 return error_code::success();
790 }
Sid Manning1a601412012-07-25 16:27:21 +0000791};
792
793} // namespace anonymous
Nick Kledzikabb69812012-05-31 22:34:00 +0000794
795namespace lld {
796
797ReaderOptionsELF::ReaderOptionsELF() {
798}
799
800ReaderOptionsELF::~ReaderOptionsELF() {
801}
802
Sid Manning1a601412012-07-25 16:27:21 +0000803Reader *createReaderELF(const ReaderOptionsELF &options) {
804 return new ReaderELF(options);
Nick Kledzikabb69812012-05-31 22:34:00 +0000805}
806
Sid Manning1a601412012-07-25 16:27:21 +0000807} // namespace LLD