blob: f710202ee11d24da239ddf0e80e79b791ce80c0e [file] [log] [blame]
Michael J. Spencer6344b322012-12-20 00:37:10 +00001//===- lib/ReaderWriter/ELF/ReaderELF.cpp ---------------------------------===//
Nick Kledzikabb69812012-05-31 22:34:00 +00002//
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//===----------------------------------------------------------------------===//
Michael J. Spencer6344b322012-12-20 00:37:10 +00009///
10/// \file
11/// \brief Defines the ELF Reader and all helper sub classes to consume an ELF
12/// file and produces atoms out of it.
13///
Sid Manning1a601412012-07-25 16:27:21 +000014//===----------------------------------------------------------------------===//
Michael J. Spencer6344b322012-12-20 00:37:10 +000015
Nick Kledzikabb69812012-05-31 22:34:00 +000016#include "lld/ReaderWriter/ReaderELF.h"
Shankar Easwaran70b4dcf2012-11-13 18:39:10 +000017#include "lld/ReaderWriter/ReaderArchive.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000018#include "lld/Core/File.h"
Sid Manning8caf4de2012-09-17 12:49:38 +000019#include "lld/Core/Reference.h"
Michael J. Spencer6344b322012-12-20 00:37:10 +000020
Sid Manning1a601412012-07-25 16:27:21 +000021#include "llvm/ADT/ArrayRef.h"
Sid Manning8caf4de2012-09-17 12:49:38 +000022#include "llvm/ADT/SmallString.h"
Sid Manning1a601412012-07-25 16:27:21 +000023#include "llvm/ADT/StringRef.h"
24#include "llvm/Object/ELF.h"
25#include "llvm/Object/ObjectFile.h"
26#include "llvm/Support/Allocator.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000027#include "llvm/Support/Casting.h"
Sid Manning1a601412012-07-25 16:27:21 +000028#include "llvm/Support/ELF.h"
29#include "llvm/Support/Endian.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000030#include "llvm/Support/ErrorHandling.h"
Sid Manning1a601412012-07-25 16:27:21 +000031#include "llvm/Support/MathExtras.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000032#include "llvm/Support/Memory.h"
33#include "llvm/Support/MemoryBuffer.h"
Michael J. Spencer6344b322012-12-20 00:37:10 +000034#include "llvm/Support/Path.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000035#include "llvm/Support/raw_ostream.h"
36#include "llvm/Support/system_error.h"
Sid Manning1a601412012-07-25 16:27:21 +000037
Nick Kledzikabb69812012-05-31 22:34:00 +000038#include <map>
39#include <vector>
40
Sid Manning1a601412012-07-25 16:27:21 +000041using namespace lld;
Michael J. Spencer6344b322012-12-20 00:37:10 +000042using llvm::object::Elf_Sym_Impl;
43using llvm::support::endianness;
Sid Manning1a601412012-07-25 16:27:21 +000044
Michael J. Spencer6344b322012-12-20 00:37:10 +000045namespace {
46/// \brief Relocation References: Defined Atoms may contain references that will
47/// need to be patched before the executable is written.
48template <endianness target_endianness, bool is64Bits>
Sid Manning8caf4de2012-09-17 12:49:38 +000049class ELFReference final : public Reference {
Sid Manning8caf4de2012-09-17 12:49:38 +000050 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
Sid Manning8caf4de2012-09-17 12:49:38 +000070 virtual uint64_t offsetInAtom() const {
71 return _offsetInAtom;
Sid Manning1a601412012-07-25 16:27:21 +000072 }
73
Sid Manning8caf4de2012-09-17 12:49:38 +000074 virtual Kind kind() const {
75 return _kind;
Sid Manning1a601412012-07-25 16:27:21 +000076 }
77
Sid Manning8caf4de2012-09-17 12:49:38 +000078 virtual void setKind(Kind kind) {
79 _kind = kind;
Sid Manning1a601412012-07-25 16:27:21 +000080 }
81
Sid Manning8caf4de2012-09-17 12:49:38 +000082 virtual const Atom *target() const {
83 return _target;
84 }
85
Michael J. Spencer6344b322012-12-20 00:37:10 +000086 /// \brief The symbol table index that contains the target reference.
Sid Manning8caf4de2012-09-17 12:49:38 +000087 uint64_t targetSymbolIndex() const {
88 return _targetSymbolIndex;
89 }
90
91 virtual Addend addend() const {
92 return _addend;
93 }
94
95 virtual void setAddend(Addend A) {
96 _addend = A;
97 }
98
99 virtual void setTarget(const Atom *newAtom) {
100 _target = newAtom;
101 }
Sid Manning1a601412012-07-25 16:27:21 +0000102private:
Sid Manning8caf4de2012-09-17 12:49:38 +0000103 const Atom *_target;
104 uint64_t _targetSymbolIndex;
105 uint64_t _offsetInAtom;
106 Addend _addend;
107 Kind _kind;
Sid Manning1a601412012-07-25 16:27:21 +0000108};
109
Michael J. Spencer6344b322012-12-20 00:37:10 +0000110/// \brief These atoms store symbols that are fixed to a particular address.
111/// This atom has no content its address will be used by the writer to fixup
112/// references that point to it.
113template<endianness target_endianness, bool is64Bits>
Sid Manning2a590242012-10-18 17:16:19 +0000114class ELFAbsoluteAtom final : public AbsoluteAtom {
Sid Manning2a590242012-10-18 17:16:19 +0000115 typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
Sid Manning8caf4de2012-09-17 12:49:38 +0000116
117public:
118 ELFAbsoluteAtom(const File &file,
119 llvm::StringRef name,
Sid Manning2a590242012-10-18 17:16:19 +0000120 const Elf_Sym *symbol,
Sid Manning8caf4de2012-09-17 12:49:38 +0000121 uint64_t value)
122 : _owningFile(file)
123 , _name(name)
Sid Manning2a590242012-10-18 17:16:19 +0000124 , _symbol(symbol)
Sid Manning8caf4de2012-09-17 12:49:38 +0000125 , _value(value)
126 {}
127
128 virtual const class File &file() const {
129 return _owningFile;
130 }
131
Sid Manning2a590242012-10-18 17:16:19 +0000132 virtual Scope scope() const {
133 if (_symbol->st_other == llvm::ELF::STV_HIDDEN)
134 return scopeLinkageUnit;
135 if (_symbol->getBinding() == llvm::ELF::STB_LOCAL)
136 return scopeTranslationUnit;
137 else
138 return scopeGlobal;
139 }
140
Sid Manning8caf4de2012-09-17 12:49:38 +0000141 virtual llvm::StringRef name() const {
142 return _name;
143 }
144
145 virtual uint64_t value() const {
146 return _value;
147 }
148
149private:
150 const File &_owningFile;
151 llvm::StringRef _name;
Sid Manning2a590242012-10-18 17:16:19 +0000152 const Elf_Sym *_symbol;
Sid Manning8caf4de2012-09-17 12:49:38 +0000153 uint64_t _value;
154};
155
Michael J. Spencer6344b322012-12-20 00:37:10 +0000156/// \brief ELFUndefinedAtom: These atoms store undefined symbols and are place
157/// holders that will be replaced by defined atoms later in the linking process.
158template<endianness target_endianness, bool is64Bits>
Sid Manning8caf4de2012-09-17 12:49:38 +0000159class ELFUndefinedAtom final: public UndefinedAtom {
Sid Manning1a601412012-07-25 16:27:21 +0000160 typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
161
162public:
Sid Manning8caf4de2012-09-17 12:49:38 +0000163 ELFUndefinedAtom(const File &file,
164 llvm::StringRef name,
165 const Elf_Sym *symbol)
166 : _owningFile(file)
167 , _name(name)
168 , _symbol(symbol)
Sid Manning1a601412012-07-25 16:27:21 +0000169 {}
170
171 virtual const class File &file() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000172 return _owningFile;
Sid Manning1a601412012-07-25 16:27:21 +0000173 }
174
175 virtual llvm::StringRef name() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000176 return _name;
Sid Manning1a601412012-07-25 16:27:21 +0000177 }
178
Michael J. Spencer6344b322012-12-20 00:37:10 +0000179 // FIXME: What distinguishes a symbol in ELF that can help decide if the
180 // symbol is undefined only during build and not runtime? This will make us
181 // choose canBeNullAtBuildtime and canBeNullAtRuntime.
Sid Manning1a601412012-07-25 16:27:21 +0000182 virtual CanBeNull canBeNull() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000183 if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
Sid Manning1a601412012-07-25 16:27:21 +0000184 return CanBeNull::canBeNullAtBuildtime;
185 else
186 return CanBeNull::canBeNullNever;
187 }
188
189private:
Sid Manning8caf4de2012-09-17 12:49:38 +0000190 const File &_owningFile;
191 llvm::StringRef _name;
192 const Elf_Sym *_symbol;
Sid Manning1a601412012-07-25 16:27:21 +0000193};
194
Michael J. Spencer6344b322012-12-20 00:37:10 +0000195/// \brief This atom stores defined symbols and will contain either data or
196/// code.
197template<endianness target_endianness, bool is64Bits>
Sid Manning8caf4de2012-09-17 12:49:38 +0000198class ELFDefinedAtom final: public DefinedAtom {
Sid Manning1a601412012-07-25 16:27:21 +0000199 typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
200 typedef llvm::object::Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;
201
202public:
Sid Manning8caf4de2012-09-17 12:49:38 +0000203 ELFDefinedAtom(const File &file,
204 llvm::StringRef symbolName,
205 llvm::StringRef sectionName,
206 const Elf_Sym *symbol,
207 const Elf_Shdr *section,
208 llvm::ArrayRef<uint8_t> contentData,
209 unsigned int referenceStart,
210 unsigned int referenceEnd,
211 std::vector<ELFReference
212 <target_endianness, is64Bits> *> &referenceList)
213
214 : _owningFile(file)
215 , _symbolName(symbolName)
216 , _sectionName(sectionName)
217 , _symbol(symbol)
218 , _section(section)
Michael J. Spencer6344b322012-12-20 00:37:10 +0000219 , _contentData(contentData)
Sid Manning8caf4de2012-09-17 12:49:38 +0000220 , _referenceStartIndex(referenceStart)
221 , _referenceEndIndex(referenceEnd)
222 , _referenceList(referenceList) {
223 static uint64_t orderNumber = 0;
224 _ordinal = ++orderNumber;
Sid Manning1a601412012-07-25 16:27:21 +0000225 }
226
227 virtual const class File &file() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000228 return _owningFile;
Sid Manning1a601412012-07-25 16:27:21 +0000229 }
230
231 virtual llvm::StringRef name() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000232 return _symbolName;
Sid Manning1a601412012-07-25 16:27:21 +0000233 }
234
235 virtual uint64_t ordinal() const {
236 return _ordinal;
237 }
238
239 virtual uint64_t size() const {
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 virtual Scope scope() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000250 if (_symbol->st_other == llvm::ELF::STV_HIDDEN)
Sid Manning1a601412012-07-25 16:27:21 +0000251 return scopeLinkageUnit;
Sid Manning8caf4de2012-09-17 12:49:38 +0000252 else if (_symbol->getBinding() != llvm::ELF::STB_LOCAL)
Sid Manning1a601412012-07-25 16:27:21 +0000253 return scopeGlobal;
254 else
255 return scopeTranslationUnit;
256 }
257
Michael J. Spencer6344b322012-12-20 00:37:10 +0000258 // FIXME: Need to revisit this in future.
Sid Manning1a601412012-07-25 16:27:21 +0000259 virtual Interposable interposable() const {
260 return interposeNo;
261 }
262
Michael J. Spencer6344b322012-12-20 00:37:10 +0000263 // FIXME: What ways can we determine this in ELF?
Sid Manning1a601412012-07-25 16:27:21 +0000264 virtual Merge merge() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000265 if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
Sid Manning1a601412012-07-25 16:27:21 +0000266 return mergeAsWeak;
267
Sid Manning8caf4de2012-09-17 12:49:38 +0000268 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
269 || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
Sid Manning1a601412012-07-25 16:27:21 +0000270 return mergeAsTentative;
271
272 return mergeNo;
273 }
274
275 virtual ContentType contentType() const {
Sid Manninge861d432012-10-01 23:23:05 +0000276 ContentType ret = typeUnknown;
Sid Manning1a601412012-07-25 16:27:21 +0000277
Sid Manninge861d432012-10-01 23:23:05 +0000278 switch (_section->sh_type) {
279 case llvm::ELF::SHT_PROGBITS:
280 case llvm::ELF::SHT_DYNAMIC:
281 switch (_section->sh_flags) {
Hemant Kulkarni736f7fb2012-11-21 21:07:36 +0000282 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR
283 | llvm::ELF::SHF_WRITE):
284 ret = typeCode;
285 break;
Sid Manninge861d432012-10-01 23:23:05 +0000286 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR):
287 ret = typeCode;
288 break;
289 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE):
290 ret = typeData;
291 break;
292 case llvm::ELF::SHF_ALLOC:
293 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE):
294 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE |
295 llvm::ELF::SHF_STRINGS):
296 ret = typeConstant;
297 break;
298 }
299 break;
300 case llvm::ELF::SHT_NOBITS:
301 ret = typeZeroFill;
302 break;
303 case llvm::ELF::SHT_NULL:
304 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
305 || _symbol->st_shndx == llvm::ELF::SHN_COMMON)
306 ret = typeZeroFill;
307 break;
308 }
Sid Manning2a590242012-10-18 17:16:19 +0000309
Sid Manninge861d432012-10-01 23:23:05 +0000310 return ret;
Sid Manning1a601412012-07-25 16:27:21 +0000311 }
312
313 virtual Alignment alignment() const {
Michael J. Spencer6344b322012-12-20 00:37:10 +0000314 // Unallocated common symbols specify their alignment constraints in
315 // st_value.
Sid Manning8caf4de2012-09-17 12:49:38 +0000316 if ((_symbol->getType() == llvm::ELF::STT_COMMON)
317 || _symbol->st_shndx == llvm::ELF::SHN_COMMON) {
Sid Manning05c82a42012-10-03 21:46:48 +0000318 return Alignment(llvm::Log2_64(_symbol->st_value));
Sid Manning1a601412012-07-25 16:27:21 +0000319 }
Sid Manning8caf4de2012-09-17 12:49:38 +0000320 return Alignment(llvm::Log2_64(_section->sh_addralign));
Sid Manning1a601412012-07-25 16:27:21 +0000321 }
322
Michael J. Spencer6344b322012-12-20 00:37:10 +0000323 // Do we have a choice for ELF? All symbols live in explicit sections.
Sid Manning1a601412012-07-25 16:27:21 +0000324 virtual SectionChoice sectionChoice() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000325 if (_symbol->st_shndx > llvm::ELF::SHN_LORESERVE)
Sid Manning1a601412012-07-25 16:27:21 +0000326 return sectionBasedOnContent;
327
328 return sectionCustomRequired;
329 }
330
331 virtual llvm::StringRef customSectionName() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000332 return _sectionName;
Sid Manning1a601412012-07-25 16:27:21 +0000333 }
334
Michael J. Spencer6344b322012-12-20 00:37:10 +0000335 // It isn't clear that __attribute__((used)) is transmitted to the ELF object
336 // file.
Sid Manning1a601412012-07-25 16:27:21 +0000337 virtual DeadStripKind deadStrip() const {
338 return deadStripNormal;
339 }
340
341 virtual ContentPermissions permissions() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000342 switch (_section->sh_type) {
Michael J. Spencer6344b322012-12-20 00:37:10 +0000343 // permRW_L is for sections modified by the runtime loader.
Sid Manning1a601412012-07-25 16:27:21 +0000344 case llvm::ELF::SHT_REL:
345 case llvm::ELF::SHT_RELA:
346 return permRW_L;
347
348 case llvm::ELF::SHT_DYNAMIC:
349 case llvm::ELF::SHT_PROGBITS:
Sid Manning8caf4de2012-09-17 12:49:38 +0000350 switch (_section->sh_flags) {
Sid Manning1a601412012-07-25 16:27:21 +0000351 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR):
352 return permR_X;
353
354 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE):
355 return permRW_;
356
357 case llvm::ELF::SHF_ALLOC:
358 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE):
359 case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_MERGE
360 | llvm::ELF::SHF_STRINGS):
361 return permR__;
362 }
363 default:
364 return perm___;
365 }
366 }
367
Michael J. Spencer6344b322012-12-20 00:37:10 +0000368 // Many non ARM architectures use ELF file format This not really a place to
369 // put a architecture specific method in an atom. A better approach is needed.
Sid Manning1a601412012-07-25 16:27:21 +0000370 virtual bool isThumb() const {
371 return false;
372 }
373
Michael J. Spencer6344b322012-12-20 00:37:10 +0000374 // FIXME: Not Sure if ELF supports alias atoms. Find out more.
Sid Manning1a601412012-07-25 16:27:21 +0000375 virtual bool isAlias() const {
376 return false;
377 }
378
379 virtual llvm::ArrayRef<uint8_t> rawContent() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000380 return _contentData;
Sid Manning1a601412012-07-25 16:27:21 +0000381 }
382
Sid Manning8caf4de2012-09-17 12:49:38 +0000383 DefinedAtom::reference_iterator begin() const {
384 uintptr_t index = _referenceStartIndex;
385 const void *it = reinterpret_cast<const void*>(index);
386 return reference_iterator(*this, it);
Sid Manning1a601412012-07-25 16:27:21 +0000387 }
388
Sid Manning8caf4de2012-09-17 12:49:38 +0000389 DefinedAtom::reference_iterator end() const {
390 uintptr_t index = _referenceEndIndex;
391 const void *it = reinterpret_cast<const void*>(index);
392 return reference_iterator(*this, it);
393 }
394
395 const Reference *derefIterator(const void *It) const {
396 uintptr_t index = reinterpret_cast<uintptr_t>(It);
397 assert(index >= _referenceStartIndex);
398 assert(index < _referenceEndIndex);
399 return ((_referenceList)[index]);
400 }
401
402 void incrementIterator(const void*& It) const {
403 uintptr_t index = reinterpret_cast<uintptr_t>(It);
404 ++index;
405 It = reinterpret_cast<const void*>(index);
Sid Manning1a601412012-07-25 16:27:21 +0000406 }
407
408private:
Sid Manning1a601412012-07-25 16:27:21 +0000409
Sid Manning8caf4de2012-09-17 12:49:38 +0000410 const File &_owningFile;
411 llvm::StringRef _symbolName;
412 llvm::StringRef _sectionName;
413 const Elf_Sym *_symbol;
414 const Elf_Shdr *_section;
Michael J. Spencer6344b322012-12-20 00:37:10 +0000415 /// \brief Holds the bits that make up the atom.
Sid Manning8caf4de2012-09-17 12:49:38 +0000416 llvm::ArrayRef<uint8_t> _contentData;
Sid Manning1a601412012-07-25 16:27:21 +0000417
418 uint64_t _ordinal;
Sid Manning8caf4de2012-09-17 12:49:38 +0000419 unsigned int _referenceStartIndex;
420 unsigned int _referenceEndIndex;
421 std::vector<ELFReference<target_endianness, is64Bits> *> &_referenceList;
Sid Manning1a601412012-07-25 16:27:21 +0000422};
423
Michael J. Spencer6344b322012-12-20 00:37:10 +0000424// \brief Read a binary, find out based on the symbol table contents what kind
425// of symbol it is and create corresponding atoms for it
426template<endianness target_endianness, bool is64Bits>
Sid Manning1a601412012-07-25 16:27:21 +0000427class FileELF: public File {
Sid Manning8caf4de2012-09-17 12:49:38 +0000428 typedef llvm::object::Elf_Sym_Impl
429 <target_endianness, is64Bits> Elf_Sym;
430 typedef llvm::object::Elf_Shdr_Impl
431 <target_endianness, is64Bits> Elf_Shdr;
432 typedef llvm::object::Elf_Rel_Impl
433 <target_endianness, is64Bits, false> Elf_Rel;
434 typedef llvm::object::Elf_Rel_Impl
435 <target_endianness, is64Bits, true> Elf_Rela;
Sid Manning1a601412012-07-25 16:27:21 +0000436
437public:
Michael J. Spencer6344b322012-12-20 00:37:10 +0000438 FileELF(std::unique_ptr<llvm::MemoryBuffer> MB, llvm::error_code &EC)
439 : File(MB->getBufferIdentifier()) {
Sid Manning8caf4de2012-09-17 12:49:38 +0000440 llvm::OwningPtr<llvm::object::Binary> binaryFile;
441 EC = llvm::object::createBinary(MB.release(), binaryFile);
Sid Manning1a601412012-07-25 16:27:21 +0000442 if (EC)
443 return;
444
445 // Point Obj to correct class and bitwidth ELF object
Sid Manning8caf4de2012-09-17 12:49:38 +0000446 _objFile.reset(llvm::dyn_cast<llvm::object::ELFObjectFile<target_endianness,
447 is64Bits> >(binaryFile.get()));
Sid Manning1a601412012-07-25 16:27:21 +0000448
Sid Manning8caf4de2012-09-17 12:49:38 +0000449 if (!_objFile) {
Sid Manning1a601412012-07-25 16:27:21 +0000450 EC = make_error_code(llvm::object::object_error::invalid_file_type);
451 return;
452 }
453
Sid Manning8caf4de2012-09-17 12:49:38 +0000454 binaryFile.take();
Sid Manning1a601412012-07-25 16:27:21 +0000455
Sid Manning8caf4de2012-09-17 12:49:38 +0000456 std::map< const Elf_Shdr *, std::vector<const Elf_Sym *>> sectionSymbols;
Sid Manning1a601412012-07-25 16:27:21 +0000457
Michael J. Spencer6344b322012-12-20 00:37:10 +0000458 // Handle: SHT_REL and SHT_RELA sections:
459 // Increment over the sections, when REL/RELA section types are found add
460 // the contents to the RelocationReferences map.
Sid Manning8caf4de2012-09-17 12:49:38 +0000461 llvm::object::section_iterator sit(_objFile->begin_sections());
462 llvm::object::section_iterator sie(_objFile->end_sections());
463 for (; sit != sie; sit.increment(EC)) {
464 if (EC)
465 return;
466
467 const Elf_Shdr *section = _objFile->getElfSection(sit);
468
469 if (section->sh_type == llvm::ELF::SHT_RELA) {
470 llvm::StringRef sectionName;
471 if ((EC = _objFile->getSectionName(section, sectionName)))
472 return;
473 // Get rid of the leading .rela so Atoms can use their own section
474 // name to find the relocs.
475 sectionName = sectionName.drop_front(5);
476
477 auto rai(_objFile->beginELFRela(section));
478 auto rae(_objFile->endELFRela(section));
479
480 auto &Ref = _relocationAddendRefences[sectionName];
481 for (; rai != rae; rai++) {
482 Ref.push_back(&*rai);
483 }
484 }
485
486 if (section->sh_type == llvm::ELF::SHT_REL) {
487 llvm::StringRef sectionName;
488 if ((EC = _objFile->getSectionName(section, sectionName)))
489 return;
490 // Get rid of the leading .rel so Atoms can use their own section
491 // name to find the relocs.
492 sectionName = sectionName.drop_front(4);
493
494 auto ri(_objFile->beginELFRel(section));
495 auto re(_objFile->endELFRel(section));
496
497 auto &Ref = _relocationReferences[sectionName];
498 for (; ri != re; ri++) {
499 Ref.push_back(&*ri);
500 }
501 }
502 }
503
Michael J. Spencer6344b322012-12-20 00:37:10 +0000504 // Increment over all the symbols collecting atoms and symbol names for
505 // later use.
Sid Manning8caf4de2012-09-17 12:49:38 +0000506 llvm::object::symbol_iterator it(_objFile->begin_symbols());
507 llvm::object::symbol_iterator ie(_objFile->end_symbols());
Sid Manning1a601412012-07-25 16:27:21 +0000508
Sid Manning429a4bc2012-07-27 14:52:18 +0000509 for (; it != ie; it.increment(EC)) {
Sid Manning1a601412012-07-25 16:27:21 +0000510 if (EC)
Sid Manning429a4bc2012-07-27 14:52:18 +0000511 return;
Sid Manning1a601412012-07-25 16:27:21 +0000512
Sid Manning8caf4de2012-09-17 12:49:38 +0000513 if ((EC = it->getSection(sit)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000514 return;
Sid Manning1a601412012-07-25 16:27:21 +0000515
Sid Manning8caf4de2012-09-17 12:49:38 +0000516 const Elf_Shdr *section = _objFile->getElfSection(sit);
517 const Elf_Sym *symbol = _objFile->getElfSymbol(it);
Sid Manning1a601412012-07-25 16:27:21 +0000518
Sid Manning8caf4de2012-09-17 12:49:38 +0000519 llvm::StringRef symbolName;
520 if ((EC = _objFile->getSymbolName(section, symbol, symbolName)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000521 return;
Sid Manning1a601412012-07-25 16:27:21 +0000522
Sid Manning8caf4de2012-09-17 12:49:38 +0000523 if (symbol->st_shndx == llvm::ELF::SHN_ABS) {
Sid Manning1a601412012-07-25 16:27:21 +0000524 // Create an absolute atom.
Sid Manning8caf4de2012-09-17 12:49:38 +0000525 auto *newAtom = new (_readerStorage.Allocate
Michael J. Spencer6344b322012-12-20 00:37:10 +0000526 <ELFAbsoluteAtom<target_endianness, is64Bits> > ())
Sid Manning8caf4de2012-09-17 12:49:38 +0000527 ELFAbsoluteAtom<target_endianness, is64Bits>
Sid Manning2a590242012-10-18 17:16:19 +0000528 (*this, symbolName, symbol, symbol->st_value);
Sid Manning1a601412012-07-25 16:27:21 +0000529
Sid Manning8caf4de2012-09-17 12:49:38 +0000530 _absoluteAtoms._atoms.push_back(newAtom);
531 _symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));
Sid Manning8caf4de2012-09-17 12:49:38 +0000532 } else if (symbol->st_shndx == llvm::ELF::SHN_UNDEF) {
Sid Manning1a601412012-07-25 16:27:21 +0000533 // Create an undefined atom.
Sid Manning8caf4de2012-09-17 12:49:38 +0000534 auto *newAtom = new (_readerStorage.Allocate
Michael J. Spencer6344b322012-12-20 00:37:10 +0000535 <ELFUndefinedAtom<target_endianness, is64Bits> > ())
Sid Manning8caf4de2012-09-17 12:49:38 +0000536 ELFUndefinedAtom<target_endianness, is64Bits>
537 (*this, symbolName, symbol);
538
539 _undefinedAtoms._atoms.push_back(newAtom);
540 _symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));
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);
Michael J. Spencer6344b322012-12-20 00:37:10 +0000553 } else {
Sid Manning8caf4de2012-09-17 12:49:38 +0000554 llvm::errs() << "Unable to create atom for: " << symbolName << "\n";
Sid Manning1a601412012-07-25 16:27:21 +0000555 EC = llvm::object::object_error::parse_failed;
556 return;
557 }
558 }
559 }
560
Sid Manning8caf4de2012-09-17 12:49:38 +0000561 for (auto &i : sectionSymbols) {
562 auto &symbols = i.second;
563 llvm::StringRef symbolName;
564 llvm::StringRef sectionName;
Sid Manning1a601412012-07-25 16:27:21 +0000565 // Sort symbols by position.
Sid Manning8caf4de2012-09-17 12:49:38 +0000566 std::stable_sort(symbols.begin(), symbols.end(),
Michael J. Spencer6344b322012-12-20 00:37:10 +0000567 [](const Elf_Sym *A, const Elf_Sym *B) {
Sid Manning1a601412012-07-25 16:27:21 +0000568 return A->st_value < B->st_value;
Michael J. Spencer6344b322012-12-20 00:37:10 +0000569 });
Sid Manning1a601412012-07-25 16:27:21 +0000570
571 // i.first is the section the symbol lives in
Sid Manning8caf4de2012-09-17 12:49:38 +0000572 for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
Sid Manning1a601412012-07-25 16:27:21 +0000573 StringRef symbolContents;
Sid Manning8caf4de2012-09-17 12:49:38 +0000574 if ((EC = _objFile->getSectionContents(i.first, symbolContents)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000575 return;
Sid Manning1a601412012-07-25 16:27:21 +0000576
Sid Manning8caf4de2012-09-17 12:49:38 +0000577 if ((EC = _objFile->getSymbolName(i.first, *si, symbolName)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000578 return;
Sid Manning1a601412012-07-25 16:27:21 +0000579
Sid Manning8caf4de2012-09-17 12:49:38 +0000580 if ((EC = _objFile->getSectionName(i.first, sectionName)))
Sid Manning429a4bc2012-07-27 14:52:18 +0000581 return;
Sid Manning1a601412012-07-25 16:27:21 +0000582
Sid Manning8caf4de2012-09-17 12:49:38 +0000583 bool isCommon = false;
Sid Manning1a601412012-07-25 16:27:21 +0000584 if (((*si)->getType() == llvm::ELF::STT_COMMON)
Sid Manning8caf4de2012-09-17 12:49:38 +0000585 || (*si)->st_shndx == llvm::ELF::SHN_COMMON)
586 isCommon = true;
Sid Manning1a601412012-07-25 16:27:21 +0000587
588 // Get the symbol's content:
Sid Manning8caf4de2012-09-17 12:49:38 +0000589 llvm::ArrayRef<uint8_t> symbolData;
590 uint64_t contentSize;
Sid Manning1a601412012-07-25 16:27:21 +0000591 if (si + 1 == se) {
592 // if this is the last symbol, take up the remaining data.
Michael J. Spencer6344b322012-12-20 00:37:10 +0000593 contentSize = (isCommon) ? 0
Sid Manning8caf4de2012-09-17 12:49:38 +0000594 : ((i.first)->sh_size - (*si)->st_value);
Sid Manning1a601412012-07-25 16:27:21 +0000595 }
596 else {
Michael J. Spencer6344b322012-12-20 00:37:10 +0000597 contentSize = (isCommon) ? 0
Sid Manning8caf4de2012-09-17 12:49:38 +0000598 : (*(si + 1))->st_value - (*si)->st_value;
Sid Manning1a601412012-07-25 16:27:21 +0000599 }
600
Sid Manning8caf4de2012-09-17 12:49:38 +0000601 symbolData = llvm::ArrayRef<uint8_t>((uint8_t *)symbolContents.data()
602 + (*si)->st_value, contentSize);
603
Sid Manning8caf4de2012-09-17 12:49:38 +0000604 unsigned int referenceStart = _references.size();
605
Michael J. Spencer6344b322012-12-20 00:37:10 +0000606 // Only relocations that are inside the domain of the atom are added.
Sid Manning8caf4de2012-09-17 12:49:38 +0000607
608 // Add Rela (those with r_addend) references:
609 for (auto &rai : _relocationAddendRefences[sectionName]) {
610 if ((rai->r_offset >= (*si)->st_value) &&
611 (rai->r_offset < (*si)->st_value+contentSize)) {
Sid Manning8caf4de2012-09-17 12:49:38 +0000612 auto *ERef = new (_readerStorage.Allocate
613 <ELFReference<target_endianness, is64Bits> > ())
614 ELFReference<target_endianness, is64Bits> (
615 rai, rai->r_offset-(*si)->st_value, nullptr);
616
617 _references.push_back(ERef);
618 }
619 }
620
Michael J. Spencer6344b322012-12-20 00:37:10 +0000621 // Add Rel references.
Sid Manning8caf4de2012-09-17 12:49:38 +0000622 for (auto &ri : _relocationReferences[sectionName]) {
623 if (((ri)->r_offset >= (*si)->st_value) &&
624 ((ri)->r_offset < (*si)->st_value+contentSize)) {
Sid Manning8caf4de2012-09-17 12:49:38 +0000625 auto *ERef = new (_readerStorage.Allocate
626 <ELFReference<target_endianness, is64Bits> > ())
627 ELFReference<target_endianness, is64Bits> (
628 (ri), (ri)->r_offset-(*si)->st_value, nullptr);
629
630 _references.push_back(ERef);
631 }
632 }
633
634 // Create the DefinedAtom and add it to the list of DefinedAtoms.
635 auto *newAtom = new (_readerStorage.Allocate
Michael J. Spencer6344b322012-12-20 00:37:10 +0000636 <ELFDefinedAtom<target_endianness, is64Bits> > ())
Sid Manning8caf4de2012-09-17 12:49:38 +0000637 ELFDefinedAtom<target_endianness, is64Bits>
638 (*this, symbolName, sectionName,
639 *si, i.first, symbolData,
640 referenceStart, _references.size(), _references);
641
642 _definedAtoms._atoms.push_back(newAtom);
643 _symbolToAtomMapping.insert(std::make_pair((*si), newAtom));
Sid Manning1a601412012-07-25 16:27:21 +0000644 }
645 }
Sid Manning8caf4de2012-09-17 12:49:38 +0000646
Michael J. Spencer6344b322012-12-20 00:37:10 +0000647 // All the Atoms and References are created. Now update each Reference's
648 // target with the Atom pointer it refers to.
Sid Manning8caf4de2012-09-17 12:49:38 +0000649 for (auto &ri : _references) {
650 const Elf_Sym *Symbol = _objFile->getElfSymbol(ri->targetSymbolIndex());
651 ri->setTarget(findAtom (Symbol));
652 }
Sid Manning1a601412012-07-25 16:27:21 +0000653 }
654
655 virtual void addAtom(const Atom&) {
656 llvm_unreachable("cannot add atoms to native .o files");
657 }
658
659 virtual const atom_collection<DefinedAtom> &defined() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000660 return _definedAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000661 }
662
663 virtual const atom_collection<UndefinedAtom> &undefined() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000664 return _undefinedAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000665 }
666
667 virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000668 return _sharedLibraryAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000669 }
670
671 virtual const atom_collection<AbsoluteAtom> &absolute() const {
Sid Manning8caf4de2012-09-17 12:49:38 +0000672 return _absoluteAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000673 }
674
Sid Manning8caf4de2012-09-17 12:49:38 +0000675 Atom *findAtom(const Elf_Sym *symbol) {
676 return (_symbolToAtomMapping.lookup(symbol));
677 }
678
Sid Manning1a601412012-07-25 16:27:21 +0000679private:
680 std::unique_ptr<llvm::object::ELFObjectFile<target_endianness, is64Bits> >
Sid Manning8caf4de2012-09-17 12:49:38 +0000681 _objFile;
682 atom_collection_vector<DefinedAtom> _definedAtoms;
683 atom_collection_vector<UndefinedAtom> _undefinedAtoms;
684 atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
685 atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
Sid Manning1a601412012-07-25 16:27:21 +0000686
Michael J. Spencer6344b322012-12-20 00:37:10 +0000687 /// \brief _relocationAddendRefences and _relocationReferences contain the
688 /// list of relocations references. In ELF, if a section named, ".text" has
689 /// relocations will also have a section named ".rel.text" or ".rela.text"
690 /// which will hold the entries. -- .rel or .rela is prepended to create
691 /// the SHT_REL(A) section name.
Sid Manning8caf4de2012-09-17 12:49:38 +0000692 std::map<llvm::StringRef, std::vector<const Elf_Rela *> >
693 _relocationAddendRefences;
694 std::map<llvm::StringRef, std::vector<const Elf_Rel *> >
695 _relocationReferences;
696
697 std::vector<ELFReference<target_endianness, is64Bits> *> _references;
698 llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
699
700 llvm::BumpPtrAllocator _readerStorage;
Sid Manning1a601412012-07-25 16:27:21 +0000701};
702
Michael J. Spencer6344b322012-12-20 00:37:10 +0000703// \brief A reader object that will instantiate correct FileELF by examining the
704// memory buffer for ELF class and bitwidth
Sid Manning1a601412012-07-25 16:27:21 +0000705class ReaderELF: public Reader {
706public:
Michael J. Spencera5d22812012-11-13 19:58:58 +0000707 ReaderELF(const ReaderOptionsELF &,
Shankar Easwaran70b4dcf2012-11-13 18:39:10 +0000708 ReaderOptionsArchive &readerOptionsArchive)
Michael J. Spencera5d22812012-11-13 19:58:58 +0000709 : _readerOptionsArchive(readerOptionsArchive)
Michael J. Spencer6344b322012-12-20 00:37:10 +0000710 , _readerArchive(_readerOptionsArchive) {
Shankar Easwaran70b4dcf2012-11-13 18:39:10 +0000711 _readerOptionsArchive.setReader(this);
712 }
713
Sid Manning1a601412012-07-25 16:27:21 +0000714 error_code parseFile(std::unique_ptr<MemoryBuffer> mb, std::vector<
Shankar Easwaran70b4dcf2012-11-13 18:39:10 +0000715 std::unique_ptr<File> > &result) {
Michael J. Spencer6344b322012-12-20 00:37:10 +0000716 llvm::error_code ec;
Sid Manning1a601412012-07-25 16:27:21 +0000717 std::unique_ptr<File> f;
Shankar Easwaran70b4dcf2012-11-13 18:39:10 +0000718 std::pair<unsigned char, unsigned char> Ident;
Sid Manning1a601412012-07-25 16:27:21 +0000719
Michael J. Spencer6344b322012-12-20 00:37:10 +0000720 llvm::sys::LLVMFileType fileType =
Shankar Easwaran70b4dcf2012-11-13 18:39:10 +0000721 llvm::sys::IdentifyFileType(mb->getBufferStart(),
722 static_cast<unsigned>(mb->getBufferSize()));
723 switch (fileType) {
Michael J. Spencera5d22812012-11-13 19:58:58 +0000724 case llvm::sys::ELF_Relocatable_FileType:
725 Ident = llvm::object::getElfArchType(&*mb);
Michael J. Spencer6344b322012-12-20 00:37:10 +0000726 // Instantiate the correct FileELF template instance based on the Ident
727 // pair. Once the File is created we push the file to the vector of files
728 // already created during parser's life.
Michael J. Spencera5d22812012-11-13 19:58:58 +0000729 if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
730 == llvm::ELF::ELFDATA2LSB) {
731 f.reset(new FileELF<llvm::support::little, false>(std::move(mb), ec));
Michael J. Spencera5d22812012-11-13 19:58:58 +0000732 } else if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second
733 == llvm::ELF::ELFDATA2MSB) {
734 f.reset(new FileELF<llvm::support::big, false> (std::move(mb), ec));
Michael J. Spencera5d22812012-11-13 19:58:58 +0000735 } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
736 == llvm::ELF::ELFDATA2MSB) {
737 f.reset(new FileELF<llvm::support::big, true> (std::move(mb), ec));
Michael J. Spencera5d22812012-11-13 19:58:58 +0000738 } else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second
739 == llvm::ELF::ELFDATA2LSB) {
740 f.reset(new FileELF<llvm::support::little, true> (std::move(mb), ec));
741 }
742 if (!ec)
743 result.push_back(std::move(f));
744 break;
Shankar Easwaran70b4dcf2012-11-13 18:39:10 +0000745
Michael J. Spencera5d22812012-11-13 19:58:58 +0000746 case llvm::sys::Archive_FileType:
747 ec = _readerArchive.parseFile(std::move(mb), result);
748 break;
Shankar Easwaran70b4dcf2012-11-13 18:39:10 +0000749
Michael J. Spencera5d22812012-11-13 19:58:58 +0000750 default:
751 llvm_unreachable("not supported format");
752 break;
Sid Manning1a601412012-07-25 16:27:21 +0000753 }
754
755 if (ec)
756 return ec;
757
Sid Manning1a601412012-07-25 16:27:21 +0000758 return error_code::success();
759 }
Shankar Easwaran70b4dcf2012-11-13 18:39:10 +0000760
761private:
Shankar Easwaran70b4dcf2012-11-13 18:39:10 +0000762 ReaderOptionsArchive &_readerOptionsArchive;
763 ReaderArchive _readerArchive;
Sid Manning1a601412012-07-25 16:27:21 +0000764};
Michael J. Spencer6344b322012-12-20 00:37:10 +0000765} // end anon namespace.
Nick Kledzikabb69812012-05-31 22:34:00 +0000766
767namespace lld {
Nick Kledzikabb69812012-05-31 22:34:00 +0000768ReaderOptionsELF::ReaderOptionsELF() {
769}
770
771ReaderOptionsELF::~ReaderOptionsELF() {
772}
773
Shankar Easwaran70b4dcf2012-11-13 18:39:10 +0000774Reader *createReaderELF(const ReaderOptionsELF &options,
775 ReaderOptionsArchive &optionsArchive) {
776 return new ReaderELF(options, optionsArchive);
Nick Kledzikabb69812012-05-31 22:34:00 +0000777}
Michael J. Spencer6344b322012-12-20 00:37:10 +0000778} // end namespace lld