1 //===- ELFObjectFile.h - ELF object file implementation ---------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares the ELFObjectFile template class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_OBJECT_ELFOBJECTFILE_H
14 #define LLVM_OBJECT_ELFOBJECTFILE_H
15
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/Triple.h"
21 #include "llvm/ADT/iterator_range.h"
22 #include "llvm/BinaryFormat/ELF.h"
23 #include "llvm/MC/SubtargetFeature.h"
24 #include "llvm/Object/Binary.h"
25 #include "llvm/Object/ELF.h"
26 #include "llvm/Object/ELFTypes.h"
27 #include "llvm/Object/Error.h"
28 #include "llvm/Object/ObjectFile.h"
29 #include "llvm/Object/SymbolicFile.h"
30 #include "llvm/Support/ARMAttributeParser.h"
31 #include "llvm/Support/ARMBuildAttributes.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/Endian.h"
34 #include "llvm/Support/Error.h"
35 #include "llvm/Support/ErrorHandling.h"
36 #include "llvm/Support/MemoryBuffer.h"
37 #include <cassert>
38 #include <cstdint>
39 #include <system_error>
40
41 namespace llvm {
42 namespace object {
43
44 constexpr int NumElfSymbolTypes = 16;
45 extern const llvm::EnumEntry<unsigned> ElfSymbolTypes[NumElfSymbolTypes];
46
47 class elf_symbol_iterator;
48
49 class ELFObjectFileBase : public ObjectFile {
50 friend class ELFRelocationRef;
51 friend class ELFSectionRef;
52 friend class ELFSymbolRef;
53
54 protected:
55 ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
56
57 virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
58 virtual uint8_t getSymbolBinding(DataRefImpl Symb) const = 0;
59 virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0;
60 virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0;
61
62 virtual uint32_t getSectionType(DataRefImpl Sec) const = 0;
63 virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0;
64 virtual uint64_t getSectionOffset(DataRefImpl Sec) const = 0;
65
66 virtual Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
67 virtual Error getBuildAttributes(ARMAttributeParser &Attributes) const = 0;
68
69 public:
70 using elf_symbol_iterator_range = iterator_range<elf_symbol_iterator>;
71
72 virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
73
74 /// Returns platform-specific object flags, if any.
75 virtual unsigned getPlatformFlags() const = 0;
76
77 elf_symbol_iterator_range symbols() const;
78
classof(const Binary * v)79 static bool classof(const Binary *v) { return v->isELF(); }
80
81 SubtargetFeatures getFeatures() const override;
82
83 SubtargetFeatures getMIPSFeatures() const;
84
85 SubtargetFeatures getARMFeatures() const;
86
87 SubtargetFeatures getRISCVFeatures() const;
88
89 void setARMSubArch(Triple &TheTriple) const override;
90
91 virtual uint16_t getEType() const = 0;
92
93 virtual uint16_t getEMachine() const = 0;
94
95 std::vector<std::pair<DataRefImpl, uint64_t>> getPltAddresses() const;
96 };
97
98 class ELFSectionRef : public SectionRef {
99 public:
ELFSectionRef(const SectionRef & B)100 ELFSectionRef(const SectionRef &B) : SectionRef(B) {
101 assert(isa<ELFObjectFileBase>(SectionRef::getObject()));
102 }
103
getObject()104 const ELFObjectFileBase *getObject() const {
105 return cast<ELFObjectFileBase>(SectionRef::getObject());
106 }
107
getType()108 uint32_t getType() const {
109 return getObject()->getSectionType(getRawDataRefImpl());
110 }
111
getFlags()112 uint64_t getFlags() const {
113 return getObject()->getSectionFlags(getRawDataRefImpl());
114 }
115
getOffset()116 uint64_t getOffset() const {
117 return getObject()->getSectionOffset(getRawDataRefImpl());
118 }
119 };
120
121 class elf_section_iterator : public section_iterator {
122 public:
elf_section_iterator(const section_iterator & B)123 elf_section_iterator(const section_iterator &B) : section_iterator(B) {
124 assert(isa<ELFObjectFileBase>(B->getObject()));
125 }
126
127 const ELFSectionRef *operator->() const {
128 return static_cast<const ELFSectionRef *>(section_iterator::operator->());
129 }
130
131 const ELFSectionRef &operator*() const {
132 return static_cast<const ELFSectionRef &>(section_iterator::operator*());
133 }
134 };
135
136 class ELFSymbolRef : public SymbolRef {
137 public:
ELFSymbolRef(const SymbolRef & B)138 ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) {
139 assert(isa<ELFObjectFileBase>(SymbolRef::getObject()));
140 }
141
getObject()142 const ELFObjectFileBase *getObject() const {
143 return cast<ELFObjectFileBase>(BasicSymbolRef::getObject());
144 }
145
getSize()146 uint64_t getSize() const {
147 return getObject()->getSymbolSize(getRawDataRefImpl());
148 }
149
getBinding()150 uint8_t getBinding() const {
151 return getObject()->getSymbolBinding(getRawDataRefImpl());
152 }
153
getOther()154 uint8_t getOther() const {
155 return getObject()->getSymbolOther(getRawDataRefImpl());
156 }
157
getELFType()158 uint8_t getELFType() const {
159 return getObject()->getSymbolELFType(getRawDataRefImpl());
160 }
161
getELFTypeName()162 StringRef getELFTypeName() const {
163 uint8_t Type = getELFType();
164 for (auto &EE : ElfSymbolTypes) {
165 if (EE.Value == Type) {
166 return EE.AltName;
167 }
168 }
169 return "";
170 }
171 };
172
173 class elf_symbol_iterator : public symbol_iterator {
174 public:
elf_symbol_iterator(const basic_symbol_iterator & B)175 elf_symbol_iterator(const basic_symbol_iterator &B)
176 : symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
177 cast<ELFObjectFileBase>(B->getObject()))) {}
178
179 const ELFSymbolRef *operator->() const {
180 return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->());
181 }
182
183 const ELFSymbolRef &operator*() const {
184 return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*());
185 }
186 };
187
188 class ELFRelocationRef : public RelocationRef {
189 public:
ELFRelocationRef(const RelocationRef & B)190 ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) {
191 assert(isa<ELFObjectFileBase>(RelocationRef::getObject()));
192 }
193
getObject()194 const ELFObjectFileBase *getObject() const {
195 return cast<ELFObjectFileBase>(RelocationRef::getObject());
196 }
197
getAddend()198 Expected<int64_t> getAddend() const {
199 return getObject()->getRelocationAddend(getRawDataRefImpl());
200 }
201 };
202
203 class elf_relocation_iterator : public relocation_iterator {
204 public:
elf_relocation_iterator(const relocation_iterator & B)205 elf_relocation_iterator(const relocation_iterator &B)
206 : relocation_iterator(RelocationRef(
207 B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {}
208
209 const ELFRelocationRef *operator->() const {
210 return static_cast<const ELFRelocationRef *>(
211 relocation_iterator::operator->());
212 }
213
214 const ELFRelocationRef &operator*() const {
215 return static_cast<const ELFRelocationRef &>(
216 relocation_iterator::operator*());
217 }
218 };
219
220 inline ELFObjectFileBase::elf_symbol_iterator_range
symbols()221 ELFObjectFileBase::symbols() const {
222 return elf_symbol_iterator_range(symbol_begin(), symbol_end());
223 }
224
225 template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
226 uint16_t getEMachine() const override;
227 uint16_t getEType() const override;
228 uint64_t getSymbolSize(DataRefImpl Sym) const override;
229
230 public:
231 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
232
233 using uintX_t = typename ELFT::uint;
234
235 using Elf_Sym = typename ELFT::Sym;
236 using Elf_Shdr = typename ELFT::Shdr;
237 using Elf_Ehdr = typename ELFT::Ehdr;
238 using Elf_Rel = typename ELFT::Rel;
239 using Elf_Rela = typename ELFT::Rela;
240 using Elf_Dyn = typename ELFT::Dyn;
241
toSectionRef(const Elf_Shdr * Sec)242 SectionRef toSectionRef(const Elf_Shdr *Sec) const {
243 return SectionRef(toDRI(Sec), this);
244 }
245
246 private:
247 ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
248 const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec,
249 ArrayRef<Elf_Word> ShndxTable);
250
251 protected:
252 ELFFile<ELFT> EF;
253
254 const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
255 const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
256 ArrayRef<Elf_Word> ShndxTable;
257
258 void moveSymbolNext(DataRefImpl &Symb) const override;
259 Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
260 Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
261 uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
262 uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
263 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
264 uint32_t getSymbolFlags(DataRefImpl Symb) const override;
265 uint8_t getSymbolBinding(DataRefImpl Symb) const override;
266 uint8_t getSymbolOther(DataRefImpl Symb) const override;
267 uint8_t getSymbolELFType(DataRefImpl Symb) const override;
268 Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
269 Expected<section_iterator> getSymbolSection(const Elf_Sym *Symb,
270 const Elf_Shdr *SymTab) const;
271 Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
272
273 void moveSectionNext(DataRefImpl &Sec) const override;
274 Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
275 uint64_t getSectionAddress(DataRefImpl Sec) const override;
276 uint64_t getSectionIndex(DataRefImpl Sec) const override;
277 uint64_t getSectionSize(DataRefImpl Sec) const override;
278 Expected<ArrayRef<uint8_t>>
279 getSectionContents(DataRefImpl Sec) const override;
280 uint64_t getSectionAlignment(DataRefImpl Sec) const override;
281 bool isSectionCompressed(DataRefImpl Sec) const override;
282 bool isSectionText(DataRefImpl Sec) const override;
283 bool isSectionData(DataRefImpl Sec) const override;
284 bool isSectionBSS(DataRefImpl Sec) const override;
285 bool isSectionVirtual(DataRefImpl Sec) const override;
286 bool isBerkeleyText(DataRefImpl Sec) const override;
287 bool isBerkeleyData(DataRefImpl Sec) const override;
288 relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
289 relocation_iterator section_rel_end(DataRefImpl Sec) const override;
290 std::vector<SectionRef> dynamic_relocation_sections() const override;
291 Expected<section_iterator>
292 getRelocatedSection(DataRefImpl Sec) const override;
293
294 void moveRelocationNext(DataRefImpl &Rel) const override;
295 uint64_t getRelocationOffset(DataRefImpl Rel) const override;
296 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
297 uint64_t getRelocationType(DataRefImpl Rel) const override;
298 void getRelocationTypeName(DataRefImpl Rel,
299 SmallVectorImpl<char> &Result) const override;
300
301 uint32_t getSectionType(DataRefImpl Sec) const override;
302 uint64_t getSectionFlags(DataRefImpl Sec) const override;
303 uint64_t getSectionOffset(DataRefImpl Sec) const override;
304 StringRef getRelocationTypeName(uint32_t Type) const;
305
306 /// Get the relocation section that contains \a Rel.
getRelSection(DataRefImpl Rel)307 const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
308 auto RelSecOrErr = EF.getSection(Rel.d.a);
309 if (!RelSecOrErr)
310 report_fatal_error(errorToErrorCode(RelSecOrErr.takeError()).message());
311 return *RelSecOrErr;
312 }
313
toDRI(const Elf_Shdr * SymTable,unsigned SymbolNum)314 DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
315 DataRefImpl DRI;
316 if (!SymTable) {
317 DRI.d.a = 0;
318 DRI.d.b = 0;
319 return DRI;
320 }
321 assert(SymTable->sh_type == ELF::SHT_SYMTAB ||
322 SymTable->sh_type == ELF::SHT_DYNSYM);
323
324 auto SectionsOrErr = EF.sections();
325 if (!SectionsOrErr) {
326 DRI.d.a = 0;
327 DRI.d.b = 0;
328 return DRI;
329 }
330 uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
331 unsigned SymTableIndex =
332 (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr);
333
334 DRI.d.a = SymTableIndex;
335 DRI.d.b = SymbolNum;
336 return DRI;
337 }
338
toELFShdrIter(DataRefImpl Sec)339 const Elf_Shdr *toELFShdrIter(DataRefImpl Sec) const {
340 return reinterpret_cast<const Elf_Shdr *>(Sec.p);
341 }
342
toDRI(const Elf_Shdr * Sec)343 DataRefImpl toDRI(const Elf_Shdr *Sec) const {
344 DataRefImpl DRI;
345 DRI.p = reinterpret_cast<uintptr_t>(Sec);
346 return DRI;
347 }
348
toDRI(const Elf_Dyn * Dyn)349 DataRefImpl toDRI(const Elf_Dyn *Dyn) const {
350 DataRefImpl DRI;
351 DRI.p = reinterpret_cast<uintptr_t>(Dyn);
352 return DRI;
353 }
354
isExportedToOtherDSO(const Elf_Sym * ESym)355 bool isExportedToOtherDSO(const Elf_Sym *ESym) const {
356 unsigned char Binding = ESym->getBinding();
357 unsigned char Visibility = ESym->getVisibility();
358
359 // A symbol is exported if its binding is either GLOBAL or WEAK, and its
360 // visibility is either DEFAULT or PROTECTED. All other symbols are not
361 // exported.
362 return (
363 (Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK ||
364 Binding == ELF::STB_GNU_UNIQUE) &&
365 (Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED));
366 }
367
getBuildAttributes(ARMAttributeParser & Attributes)368 Error getBuildAttributes(ARMAttributeParser &Attributes) const override {
369 auto SectionsOrErr = EF.sections();
370 if (!SectionsOrErr)
371 return SectionsOrErr.takeError();
372
373 for (const Elf_Shdr &Sec : *SectionsOrErr) {
374 if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES) {
375 auto ErrorOrContents = EF.getSectionContents(&Sec);
376 if (!ErrorOrContents)
377 return ErrorOrContents.takeError();
378
379 auto Contents = ErrorOrContents.get();
380 if (Contents[0] != ARMBuildAttrs::Format_Version || Contents.size() == 1)
381 return Error::success();
382
383 Attributes.Parse(Contents, ELFT::TargetEndianness == support::little);
384 break;
385 }
386 }
387 return Error::success();
388 }
389
390 // This flag is used for classof, to distinguish ELFObjectFile from
391 // its subclass. If more subclasses will be created, this flag will
392 // have to become an enum.
393 bool isDyldELFObject;
394
395 public:
396 ELFObjectFile(ELFObjectFile<ELFT> &&Other);
397 static Expected<ELFObjectFile<ELFT>> create(MemoryBufferRef Object);
398
399 const Elf_Rel *getRel(DataRefImpl Rel) const;
400 const Elf_Rela *getRela(DataRefImpl Rela) const;
401
getSymbol(DataRefImpl Sym)402 const Elf_Sym *getSymbol(DataRefImpl Sym) const {
403 auto Ret = EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
404 if (!Ret)
405 report_fatal_error(errorToErrorCode(Ret.takeError()).message());
406 return *Ret;
407 }
408
getSection(DataRefImpl Sec)409 const Elf_Shdr *getSection(DataRefImpl Sec) const {
410 return reinterpret_cast<const Elf_Shdr *>(Sec.p);
411 }
412
413 basic_symbol_iterator symbol_begin() const override;
414 basic_symbol_iterator symbol_end() const override;
415
416 elf_symbol_iterator dynamic_symbol_begin() const;
417 elf_symbol_iterator dynamic_symbol_end() const;
418
419 section_iterator section_begin() const override;
420 section_iterator section_end() const override;
421
422 Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const override;
423
424 uint8_t getBytesInAddress() const override;
425 StringRef getFileFormatName() const override;
426 Triple::ArchType getArch() const override;
427 Expected<uint64_t> getStartAddress() const override;
428
getPlatformFlags()429 unsigned getPlatformFlags() const override { return EF.getHeader()->e_flags; }
430
getELFFile()431 const ELFFile<ELFT> *getELFFile() const { return &EF; }
432
isDyldType()433 bool isDyldType() const { return isDyldELFObject; }
classof(const Binary * v)434 static bool classof(const Binary *v) {
435 return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
436 ELFT::Is64Bits);
437 }
438
439 elf_symbol_iterator_range getDynamicSymbolIterators() const override;
440
441 bool isRelocatableObject() const override;
442 };
443
444 using ELF32LEObjectFile = ELFObjectFile<ELF32LE>;
445 using ELF64LEObjectFile = ELFObjectFile<ELF64LE>;
446 using ELF32BEObjectFile = ELFObjectFile<ELF32BE>;
447 using ELF64BEObjectFile = ELFObjectFile<ELF64BE>;
448
449 template <class ELFT>
moveSymbolNext(DataRefImpl & Sym)450 void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
451 ++Sym.d.b;
452 }
453
454 template <class ELFT>
getSymbolName(DataRefImpl Sym)455 Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
456 const Elf_Sym *ESym = getSymbol(Sym);
457 auto SymTabOrErr = EF.getSection(Sym.d.a);
458 if (!SymTabOrErr)
459 return SymTabOrErr.takeError();
460 const Elf_Shdr *SymTableSec = *SymTabOrErr;
461 auto StrTabOrErr = EF.getSection(SymTableSec->sh_link);
462 if (!StrTabOrErr)
463 return StrTabOrErr.takeError();
464 const Elf_Shdr *StringTableSec = *StrTabOrErr;
465 auto SymStrTabOrErr = EF.getStringTable(StringTableSec);
466 if (!SymStrTabOrErr)
467 return SymStrTabOrErr.takeError();
468 Expected<StringRef> Name = ESym->getName(*SymStrTabOrErr);
469 if (Name && !Name->empty())
470 return Name;
471
472 // If the symbol name is empty use the section name.
473 if (ESym->getType() == ELF::STT_SECTION) {
474 if (Expected<section_iterator> SecOrErr = getSymbolSection(Sym)) {
475 consumeError(Name.takeError());
476 return (*SecOrErr)->getName();
477 }
478 }
479 return Name;
480 }
481
482 template <class ELFT>
getSectionFlags(DataRefImpl Sec)483 uint64_t ELFObjectFile<ELFT>::getSectionFlags(DataRefImpl Sec) const {
484 return getSection(Sec)->sh_flags;
485 }
486
487 template <class ELFT>
getSectionType(DataRefImpl Sec)488 uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const {
489 return getSection(Sec)->sh_type;
490 }
491
492 template <class ELFT>
getSectionOffset(DataRefImpl Sec)493 uint64_t ELFObjectFile<ELFT>::getSectionOffset(DataRefImpl Sec) const {
494 return getSection(Sec)->sh_offset;
495 }
496
497 template <class ELFT>
getSymbolValueImpl(DataRefImpl Symb)498 uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
499 const Elf_Sym *ESym = getSymbol(Symb);
500 uint64_t Ret = ESym->st_value;
501 if (ESym->st_shndx == ELF::SHN_ABS)
502 return Ret;
503
504 const Elf_Ehdr *Header = EF.getHeader();
505 // Clear the ARM/Thumb or microMIPS indicator flag.
506 if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) &&
507 ESym->getType() == ELF::STT_FUNC)
508 Ret &= ~1;
509
510 return Ret;
511 }
512
513 template <class ELFT>
514 Expected<uint64_t>
getSymbolAddress(DataRefImpl Symb)515 ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
516 uint64_t Result = getSymbolValue(Symb);
517 const Elf_Sym *ESym = getSymbol(Symb);
518 switch (ESym->st_shndx) {
519 case ELF::SHN_COMMON:
520 case ELF::SHN_UNDEF:
521 case ELF::SHN_ABS:
522 return Result;
523 }
524
525 const Elf_Ehdr *Header = EF.getHeader();
526 auto SymTabOrErr = EF.getSection(Symb.d.a);
527 if (!SymTabOrErr)
528 return SymTabOrErr.takeError();
529 const Elf_Shdr *SymTab = *SymTabOrErr;
530
531 if (Header->e_type == ELF::ET_REL) {
532 auto SectionOrErr = EF.getSection(ESym, SymTab, ShndxTable);
533 if (!SectionOrErr)
534 return SectionOrErr.takeError();
535 const Elf_Shdr *Section = *SectionOrErr;
536 if (Section)
537 Result += Section->sh_addr;
538 }
539
540 return Result;
541 }
542
543 template <class ELFT>
getSymbolAlignment(DataRefImpl Symb)544 uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
545 const Elf_Sym *Sym = getSymbol(Symb);
546 if (Sym->st_shndx == ELF::SHN_COMMON)
547 return Sym->st_value;
548 return 0;
549 }
550
551 template <class ELFT>
getEMachine()552 uint16_t ELFObjectFile<ELFT>::getEMachine() const {
553 return EF.getHeader()->e_machine;
554 }
555
getEType()556 template <class ELFT> uint16_t ELFObjectFile<ELFT>::getEType() const {
557 return EF.getHeader()->e_type;
558 }
559
560 template <class ELFT>
getSymbolSize(DataRefImpl Sym)561 uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
562 return getSymbol(Sym)->st_size;
563 }
564
565 template <class ELFT>
getCommonSymbolSizeImpl(DataRefImpl Symb)566 uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
567 return getSymbol(Symb)->st_size;
568 }
569
570 template <class ELFT>
getSymbolBinding(DataRefImpl Symb)571 uint8_t ELFObjectFile<ELFT>::getSymbolBinding(DataRefImpl Symb) const {
572 return getSymbol(Symb)->getBinding();
573 }
574
575 template <class ELFT>
getSymbolOther(DataRefImpl Symb)576 uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const {
577 return getSymbol(Symb)->st_other;
578 }
579
580 template <class ELFT>
getSymbolELFType(DataRefImpl Symb)581 uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const {
582 return getSymbol(Symb)->getType();
583 }
584
585 template <class ELFT>
586 Expected<SymbolRef::Type>
getSymbolType(DataRefImpl Symb)587 ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
588 const Elf_Sym *ESym = getSymbol(Symb);
589
590 switch (ESym->getType()) {
591 case ELF::STT_NOTYPE:
592 return SymbolRef::ST_Unknown;
593 case ELF::STT_SECTION:
594 return SymbolRef::ST_Debug;
595 case ELF::STT_FILE:
596 return SymbolRef::ST_File;
597 case ELF::STT_FUNC:
598 return SymbolRef::ST_Function;
599 case ELF::STT_OBJECT:
600 case ELF::STT_COMMON:
601 case ELF::STT_TLS:
602 return SymbolRef::ST_Data;
603 default:
604 return SymbolRef::ST_Other;
605 }
606 }
607
608 template <class ELFT>
getSymbolFlags(DataRefImpl Sym)609 uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
610 const Elf_Sym *ESym = getSymbol(Sym);
611
612 uint32_t Result = SymbolRef::SF_None;
613
614 if (ESym->getBinding() != ELF::STB_LOCAL)
615 Result |= SymbolRef::SF_Global;
616
617 if (ESym->getBinding() == ELF::STB_WEAK)
618 Result |= SymbolRef::SF_Weak;
619
620 if (ESym->st_shndx == ELF::SHN_ABS)
621 Result |= SymbolRef::SF_Absolute;
622
623 if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION)
624 Result |= SymbolRef::SF_FormatSpecific;
625
626 auto DotSymtabSecSyms = EF.symbols(DotSymtabSec);
627 if (DotSymtabSecSyms && ESym == (*DotSymtabSecSyms).begin())
628 Result |= SymbolRef::SF_FormatSpecific;
629 auto DotDynSymSecSyms = EF.symbols(DotDynSymSec);
630 if (DotDynSymSecSyms && ESym == (*DotDynSymSecSyms).begin())
631 Result |= SymbolRef::SF_FormatSpecific;
632
633 if (EF.getHeader()->e_machine == ELF::EM_ARM) {
634 if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
635 StringRef Name = *NameOrErr;
636 if (Name.startswith("$d") || Name.startswith("$t") ||
637 Name.startswith("$a"))
638 Result |= SymbolRef::SF_FormatSpecific;
639 } else {
640 // TODO: Actually report errors helpfully.
641 consumeError(NameOrErr.takeError());
642 }
643 if (ESym->getType() == ELF::STT_FUNC && (ESym->st_value & 1) == 1)
644 Result |= SymbolRef::SF_Thumb;
645 }
646
647 if (ESym->st_shndx == ELF::SHN_UNDEF)
648 Result |= SymbolRef::SF_Undefined;
649
650 if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON)
651 Result |= SymbolRef::SF_Common;
652
653 if (isExportedToOtherDSO(ESym))
654 Result |= SymbolRef::SF_Exported;
655
656 if (ESym->getVisibility() == ELF::STV_HIDDEN)
657 Result |= SymbolRef::SF_Hidden;
658
659 return Result;
660 }
661
662 template <class ELFT>
663 Expected<section_iterator>
getSymbolSection(const Elf_Sym * ESym,const Elf_Shdr * SymTab)664 ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
665 const Elf_Shdr *SymTab) const {
666 auto ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable);
667 if (!ESecOrErr)
668 return ESecOrErr.takeError();
669
670 const Elf_Shdr *ESec = *ESecOrErr;
671 if (!ESec)
672 return section_end();
673
674 DataRefImpl Sec;
675 Sec.p = reinterpret_cast<intptr_t>(ESec);
676 return section_iterator(SectionRef(Sec, this));
677 }
678
679 template <class ELFT>
680 Expected<section_iterator>
getSymbolSection(DataRefImpl Symb)681 ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
682 const Elf_Sym *Sym = getSymbol(Symb);
683 auto SymTabOrErr = EF.getSection(Symb.d.a);
684 if (!SymTabOrErr)
685 return SymTabOrErr.takeError();
686 const Elf_Shdr *SymTab = *SymTabOrErr;
687 return getSymbolSection(Sym, SymTab);
688 }
689
690 template <class ELFT>
moveSectionNext(DataRefImpl & Sec)691 void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
692 const Elf_Shdr *ESec = getSection(Sec);
693 Sec = toDRI(++ESec);
694 }
695
696 template <class ELFT>
getSectionName(DataRefImpl Sec)697 Expected<StringRef> ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec) const {
698 return EF.getSectionName(&*getSection(Sec));
699 }
700
701 template <class ELFT>
getSectionAddress(DataRefImpl Sec)702 uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const {
703 return getSection(Sec)->sh_addr;
704 }
705
706 template <class ELFT>
getSectionIndex(DataRefImpl Sec)707 uint64_t ELFObjectFile<ELFT>::getSectionIndex(DataRefImpl Sec) const {
708 auto SectionsOrErr = EF.sections();
709 handleAllErrors(std::move(SectionsOrErr.takeError()),
710 [](const ErrorInfoBase &) {
711 llvm_unreachable("unable to get section index");
712 });
713 const Elf_Shdr *First = SectionsOrErr->begin();
714 return getSection(Sec) - First;
715 }
716
717 template <class ELFT>
getSectionSize(DataRefImpl Sec)718 uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
719 return getSection(Sec)->sh_size;
720 }
721
722 template <class ELFT>
723 Expected<ArrayRef<uint8_t>>
getSectionContents(DataRefImpl Sec)724 ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec) const {
725 const Elf_Shdr *EShdr = getSection(Sec);
726 if (EShdr->sh_type == ELF::SHT_NOBITS)
727 return makeArrayRef((const uint8_t *)base(), 0);
728 if (std::error_code EC =
729 checkOffset(getMemoryBufferRef(),
730 (uintptr_t)base() + EShdr->sh_offset, EShdr->sh_size))
731 return errorCodeToError(EC);
732 return makeArrayRef((const uint8_t *)base() + EShdr->sh_offset,
733 EShdr->sh_size);
734 }
735
736 template <class ELFT>
getSectionAlignment(DataRefImpl Sec)737 uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const {
738 return getSection(Sec)->sh_addralign;
739 }
740
741 template <class ELFT>
isSectionCompressed(DataRefImpl Sec)742 bool ELFObjectFile<ELFT>::isSectionCompressed(DataRefImpl Sec) const {
743 return getSection(Sec)->sh_flags & ELF::SHF_COMPRESSED;
744 }
745
746 template <class ELFT>
isSectionText(DataRefImpl Sec)747 bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
748 return getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR;
749 }
750
751 template <class ELFT>
isSectionData(DataRefImpl Sec)752 bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const {
753 const Elf_Shdr *EShdr = getSection(Sec);
754 return EShdr->sh_type == ELF::SHT_PROGBITS &&
755 EShdr->sh_flags & ELF::SHF_ALLOC &&
756 !(EShdr->sh_flags & ELF::SHF_EXECINSTR);
757 }
758
759 template <class ELFT>
isSectionBSS(DataRefImpl Sec)760 bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const {
761 const Elf_Shdr *EShdr = getSection(Sec);
762 return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
763 EShdr->sh_type == ELF::SHT_NOBITS;
764 }
765
766 template <class ELFT>
767 std::vector<SectionRef>
dynamic_relocation_sections()768 ELFObjectFile<ELFT>::dynamic_relocation_sections() const {
769 std::vector<SectionRef> Res;
770 std::vector<uintptr_t> Offsets;
771
772 auto SectionsOrErr = EF.sections();
773 if (!SectionsOrErr)
774 return Res;
775
776 for (const Elf_Shdr &Sec : *SectionsOrErr) {
777 if (Sec.sh_type != ELF::SHT_DYNAMIC)
778 continue;
779 Elf_Dyn *Dynamic =
780 reinterpret_cast<Elf_Dyn *>((uintptr_t)base() + Sec.sh_offset);
781 for (; Dynamic->d_tag != ELF::DT_NULL; Dynamic++) {
782 if (Dynamic->d_tag == ELF::DT_REL || Dynamic->d_tag == ELF::DT_RELA ||
783 Dynamic->d_tag == ELF::DT_JMPREL) {
784 Offsets.push_back(Dynamic->d_un.d_val);
785 }
786 }
787 }
788 for (const Elf_Shdr &Sec : *SectionsOrErr) {
789 if (is_contained(Offsets, Sec.sh_addr))
790 Res.emplace_back(toDRI(&Sec), this);
791 }
792 return Res;
793 }
794
795 template <class ELFT>
isSectionVirtual(DataRefImpl Sec)796 bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
797 return getSection(Sec)->sh_type == ELF::SHT_NOBITS;
798 }
799
800 template <class ELFT>
isBerkeleyText(DataRefImpl Sec)801 bool ELFObjectFile<ELFT>::isBerkeleyText(DataRefImpl Sec) const {
802 return getSection(Sec)->sh_flags & ELF::SHF_ALLOC &&
803 (getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR ||
804 !(getSection(Sec)->sh_flags & ELF::SHF_WRITE));
805 }
806
807 template <class ELFT>
isBerkeleyData(DataRefImpl Sec)808 bool ELFObjectFile<ELFT>::isBerkeleyData(DataRefImpl Sec) const {
809 const Elf_Shdr *EShdr = getSection(Sec);
810 return !isBerkeleyText(Sec) && EShdr->sh_type != ELF::SHT_NOBITS &&
811 EShdr->sh_flags & ELF::SHF_ALLOC;
812 }
813
814 template <class ELFT>
815 relocation_iterator
section_rel_begin(DataRefImpl Sec)816 ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
817 DataRefImpl RelData;
818 auto SectionsOrErr = EF.sections();
819 if (!SectionsOrErr)
820 return relocation_iterator(RelocationRef());
821 uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
822 RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
823 RelData.d.b = 0;
824 return relocation_iterator(RelocationRef(RelData, this));
825 }
826
827 template <class ELFT>
828 relocation_iterator
section_rel_end(DataRefImpl Sec)829 ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
830 const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
831 relocation_iterator Begin = section_rel_begin(Sec);
832 if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
833 return Begin;
834 DataRefImpl RelData = Begin->getRawDataRefImpl();
835 const Elf_Shdr *RelSec = getRelSection(RelData);
836
837 // Error check sh_link here so that getRelocationSymbol can just use it.
838 auto SymSecOrErr = EF.getSection(RelSec->sh_link);
839 if (!SymSecOrErr)
840 report_fatal_error(errorToErrorCode(SymSecOrErr.takeError()).message());
841
842 RelData.d.b += S->sh_size / S->sh_entsize;
843 return relocation_iterator(RelocationRef(RelData, this));
844 }
845
846 template <class ELFT>
847 Expected<section_iterator>
getRelocatedSection(DataRefImpl Sec)848 ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
849 if (EF.getHeader()->e_type != ELF::ET_REL)
850 return section_end();
851
852 const Elf_Shdr *EShdr = getSection(Sec);
853 uintX_t Type = EShdr->sh_type;
854 if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
855 return section_end();
856
857 Expected<const Elf_Shdr *> SecOrErr = EF.getSection(EShdr->sh_info);
858 if (!SecOrErr)
859 return SecOrErr.takeError();
860 return section_iterator(SectionRef(toDRI(*SecOrErr), this));
861 }
862
863 // Relocations
864 template <class ELFT>
moveRelocationNext(DataRefImpl & Rel)865 void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
866 ++Rel.d.b;
867 }
868
869 template <class ELFT>
870 symbol_iterator
getRelocationSymbol(DataRefImpl Rel)871 ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
872 uint32_t symbolIdx;
873 const Elf_Shdr *sec = getRelSection(Rel);
874 if (sec->sh_type == ELF::SHT_REL)
875 symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
876 else
877 symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
878 if (!symbolIdx)
879 return symbol_end();
880
881 // FIXME: error check symbolIdx
882 DataRefImpl SymbolData;
883 SymbolData.d.a = sec->sh_link;
884 SymbolData.d.b = symbolIdx;
885 return symbol_iterator(SymbolRef(SymbolData, this));
886 }
887
888 template <class ELFT>
getRelocationOffset(DataRefImpl Rel)889 uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
890 const Elf_Shdr *sec = getRelSection(Rel);
891 if (sec->sh_type == ELF::SHT_REL)
892 return getRel(Rel)->r_offset;
893
894 return getRela(Rel)->r_offset;
895 }
896
897 template <class ELFT>
getRelocationType(DataRefImpl Rel)898 uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const {
899 const Elf_Shdr *sec = getRelSection(Rel);
900 if (sec->sh_type == ELF::SHT_REL)
901 return getRel(Rel)->getType(EF.isMips64EL());
902 else
903 return getRela(Rel)->getType(EF.isMips64EL());
904 }
905
906 template <class ELFT>
getRelocationTypeName(uint32_t Type)907 StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
908 return getELFRelocationTypeName(EF.getHeader()->e_machine, Type);
909 }
910
911 template <class ELFT>
getRelocationTypeName(DataRefImpl Rel,SmallVectorImpl<char> & Result)912 void ELFObjectFile<ELFT>::getRelocationTypeName(
913 DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
914 uint32_t type = getRelocationType(Rel);
915 EF.getRelocationTypeName(type, Result);
916 }
917
918 template <class ELFT>
919 Expected<int64_t>
getRelocationAddend(DataRefImpl Rel)920 ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const {
921 if (getRelSection(Rel)->sh_type != ELF::SHT_RELA)
922 return createError("Section is not SHT_RELA");
923 return (int64_t)getRela(Rel)->r_addend;
924 }
925
926 template <class ELFT>
927 const typename ELFObjectFile<ELFT>::Elf_Rel *
getRel(DataRefImpl Rel)928 ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
929 assert(getRelSection(Rel)->sh_type == ELF::SHT_REL);
930 auto Ret = EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
931 if (!Ret)
932 report_fatal_error(errorToErrorCode(Ret.takeError()).message());
933 return *Ret;
934 }
935
936 template <class ELFT>
937 const typename ELFObjectFile<ELFT>::Elf_Rela *
getRela(DataRefImpl Rela)938 ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
939 assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA);
940 auto Ret = EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
941 if (!Ret)
942 report_fatal_error(errorToErrorCode(Ret.takeError()).message());
943 return *Ret;
944 }
945
946 template <class ELFT>
947 Expected<ELFObjectFile<ELFT>>
create(MemoryBufferRef Object)948 ELFObjectFile<ELFT>::create(MemoryBufferRef Object) {
949 auto EFOrErr = ELFFile<ELFT>::create(Object.getBuffer());
950 if (Error E = EFOrErr.takeError())
951 return std::move(E);
952 auto EF = std::move(*EFOrErr);
953
954 auto SectionsOrErr = EF.sections();
955 if (!SectionsOrErr)
956 return SectionsOrErr.takeError();
957
958 const Elf_Shdr *DotDynSymSec = nullptr;
959 const Elf_Shdr *DotSymtabSec = nullptr;
960 ArrayRef<Elf_Word> ShndxTable;
961 for (const Elf_Shdr &Sec : *SectionsOrErr) {
962 switch (Sec.sh_type) {
963 case ELF::SHT_DYNSYM: {
964 if (!DotDynSymSec)
965 DotDynSymSec = &Sec;
966 break;
967 }
968 case ELF::SHT_SYMTAB: {
969 if (!DotSymtabSec)
970 DotSymtabSec = &Sec;
971 break;
972 }
973 case ELF::SHT_SYMTAB_SHNDX: {
974 auto TableOrErr = EF.getSHNDXTable(Sec);
975 if (!TableOrErr)
976 return TableOrErr.takeError();
977 ShndxTable = *TableOrErr;
978 break;
979 }
980 }
981 }
982 return ELFObjectFile<ELFT>(Object, EF, DotDynSymSec, DotSymtabSec,
983 ShndxTable);
984 }
985
986 template <class ELFT>
ELFObjectFile(MemoryBufferRef Object,ELFFile<ELFT> EF,const Elf_Shdr * DotDynSymSec,const Elf_Shdr * DotSymtabSec,ArrayRef<Elf_Word> ShndxTable)987 ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
988 const Elf_Shdr *DotDynSymSec,
989 const Elf_Shdr *DotSymtabSec,
990 ArrayRef<Elf_Word> ShndxTable)
991 : ELFObjectFileBase(
992 getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
993 Object),
994 EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec),
995 ShndxTable(ShndxTable) {}
996
997 template <class ELFT>
ELFObjectFile(ELFObjectFile<ELFT> && Other)998 ELFObjectFile<ELFT>::ELFObjectFile(ELFObjectFile<ELFT> &&Other)
999 : ELFObjectFile(Other.Data, Other.EF, Other.DotDynSymSec,
1000 Other.DotSymtabSec, Other.ShndxTable) {}
1001
1002 template <class ELFT>
symbol_begin()1003 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const {
1004 DataRefImpl Sym =
1005 toDRI(DotSymtabSec,
1006 DotSymtabSec && DotSymtabSec->sh_size >= sizeof(Elf_Sym) ? 1 : 0);
1007 return basic_symbol_iterator(SymbolRef(Sym, this));
1008 }
1009
1010 template <class ELFT>
symbol_end()1011 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end() const {
1012 const Elf_Shdr *SymTab = DotSymtabSec;
1013 if (!SymTab)
1014 return symbol_begin();
1015 DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
1016 return basic_symbol_iterator(SymbolRef(Sym, this));
1017 }
1018
1019 template <class ELFT>
dynamic_symbol_begin()1020 elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
1021 DataRefImpl Sym = toDRI(DotDynSymSec, 0);
1022 return symbol_iterator(SymbolRef(Sym, this));
1023 }
1024
1025 template <class ELFT>
dynamic_symbol_end()1026 elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
1027 const Elf_Shdr *SymTab = DotDynSymSec;
1028 if (!SymTab)
1029 return dynamic_symbol_begin();
1030 DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
1031 return basic_symbol_iterator(SymbolRef(Sym, this));
1032 }
1033
1034 template <class ELFT>
section_begin()1035 section_iterator ELFObjectFile<ELFT>::section_begin() const {
1036 auto SectionsOrErr = EF.sections();
1037 if (!SectionsOrErr)
1038 return section_iterator(SectionRef());
1039 return section_iterator(SectionRef(toDRI((*SectionsOrErr).begin()), this));
1040 }
1041
1042 template <class ELFT>
section_end()1043 section_iterator ELFObjectFile<ELFT>::section_end() const {
1044 auto SectionsOrErr = EF.sections();
1045 if (!SectionsOrErr)
1046 return section_iterator(SectionRef());
1047 return section_iterator(SectionRef(toDRI((*SectionsOrErr).end()), this));
1048 }
1049
1050 template <class ELFT>
getBytesInAddress()1051 uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
1052 return ELFT::Is64Bits ? 8 : 4;
1053 }
1054
1055 template <class ELFT>
getFileFormatName()1056 StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
1057 bool IsLittleEndian = ELFT::TargetEndianness == support::little;
1058 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
1059 case ELF::ELFCLASS32:
1060 switch (EF.getHeader()->e_machine) {
1061 case ELF::EM_386:
1062 return "ELF32-i386";
1063 case ELF::EM_IAMCU:
1064 return "ELF32-iamcu";
1065 case ELF::EM_X86_64:
1066 return "ELF32-x86-64";
1067 case ELF::EM_ARM:
1068 return (IsLittleEndian ? "ELF32-arm-little" : "ELF32-arm-big");
1069 case ELF::EM_AVR:
1070 return "ELF32-avr";
1071 case ELF::EM_HEXAGON:
1072 return "ELF32-hexagon";
1073 case ELF::EM_LANAI:
1074 return "ELF32-lanai";
1075 case ELF::EM_MIPS:
1076 return "ELF32-mips";
1077 case ELF::EM_MSP430:
1078 return "ELF32-msp430";
1079 case ELF::EM_PPC:
1080 return "ELF32-ppc";
1081 case ELF::EM_RISCV:
1082 return "ELF32-riscv";
1083 case ELF::EM_SPARC:
1084 case ELF::EM_SPARC32PLUS:
1085 return "ELF32-sparc";
1086 case ELF::EM_AMDGPU:
1087 return "ELF32-amdgpu";
1088 default:
1089 return "ELF32-unknown";
1090 }
1091 case ELF::ELFCLASS64:
1092 switch (EF.getHeader()->e_machine) {
1093 case ELF::EM_386:
1094 return "ELF64-i386";
1095 case ELF::EM_X86_64:
1096 return "ELF64-x86-64";
1097 case ELF::EM_AARCH64:
1098 return (IsLittleEndian ? "ELF64-aarch64-little" : "ELF64-aarch64-big");
1099 case ELF::EM_PPC64:
1100 return "ELF64-ppc64";
1101 case ELF::EM_RISCV:
1102 return "ELF64-riscv";
1103 case ELF::EM_S390:
1104 return "ELF64-s390";
1105 case ELF::EM_SPARCV9:
1106 return "ELF64-sparc";
1107 case ELF::EM_MIPS:
1108 return "ELF64-mips";
1109 case ELF::EM_AMDGPU:
1110 return "ELF64-amdgpu";
1111 case ELF::EM_BPF:
1112 return "ELF64-BPF";
1113 default:
1114 return "ELF64-unknown";
1115 }
1116 default:
1117 // FIXME: Proper error handling.
1118 report_fatal_error("Invalid ELFCLASS!");
1119 }
1120 }
1121
getArch()1122 template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
1123 bool IsLittleEndian = ELFT::TargetEndianness == support::little;
1124 switch (EF.getHeader()->e_machine) {
1125 case ELF::EM_386:
1126 case ELF::EM_IAMCU:
1127 return Triple::x86;
1128 case ELF::EM_X86_64:
1129 return Triple::x86_64;
1130 case ELF::EM_AARCH64:
1131 return IsLittleEndian ? Triple::aarch64 : Triple::aarch64_be;
1132 case ELF::EM_ARM:
1133 return Triple::arm;
1134 case ELF::EM_AVR:
1135 return Triple::avr;
1136 case ELF::EM_HEXAGON:
1137 return Triple::hexagon;
1138 case ELF::EM_LANAI:
1139 return Triple::lanai;
1140 case ELF::EM_MIPS:
1141 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
1142 case ELF::ELFCLASS32:
1143 return IsLittleEndian ? Triple::mipsel : Triple::mips;
1144 case ELF::ELFCLASS64:
1145 return IsLittleEndian ? Triple::mips64el : Triple::mips64;
1146 default:
1147 report_fatal_error("Invalid ELFCLASS!");
1148 }
1149 case ELF::EM_MSP430:
1150 return Triple::msp430;
1151 case ELF::EM_PPC:
1152 return Triple::ppc;
1153 case ELF::EM_PPC64:
1154 return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
1155 case ELF::EM_RISCV:
1156 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
1157 case ELF::ELFCLASS32:
1158 return Triple::riscv32;
1159 case ELF::ELFCLASS64:
1160 return Triple::riscv64;
1161 default:
1162 report_fatal_error("Invalid ELFCLASS!");
1163 }
1164 case ELF::EM_S390:
1165 return Triple::systemz;
1166
1167 case ELF::EM_SPARC:
1168 case ELF::EM_SPARC32PLUS:
1169 return IsLittleEndian ? Triple::sparcel : Triple::sparc;
1170 case ELF::EM_SPARCV9:
1171 return Triple::sparcv9;
1172
1173 case ELF::EM_AMDGPU: {
1174 if (!IsLittleEndian)
1175 return Triple::UnknownArch;
1176
1177 unsigned MACH = EF.getHeader()->e_flags & ELF::EF_AMDGPU_MACH;
1178 if (MACH >= ELF::EF_AMDGPU_MACH_R600_FIRST &&
1179 MACH <= ELF::EF_AMDGPU_MACH_R600_LAST)
1180 return Triple::r600;
1181 if (MACH >= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST &&
1182 MACH <= ELF::EF_AMDGPU_MACH_AMDGCN_LAST)
1183 return Triple::amdgcn;
1184
1185 return Triple::UnknownArch;
1186 }
1187
1188 case ELF::EM_BPF:
1189 return IsLittleEndian ? Triple::bpfel : Triple::bpfeb;
1190
1191 default:
1192 return Triple::UnknownArch;
1193 }
1194 }
1195
1196 template <class ELFT>
getStartAddress()1197 Expected<uint64_t> ELFObjectFile<ELFT>::getStartAddress() const {
1198 return EF.getHeader()->e_entry;
1199 }
1200
1201 template <class ELFT>
1202 ELFObjectFileBase::elf_symbol_iterator_range
getDynamicSymbolIterators()1203 ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
1204 return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
1205 }
1206
isRelocatableObject()1207 template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
1208 return EF.getHeader()->e_type == ELF::ET_REL;
1209 }
1210
1211 } // end namespace object
1212 } // end namespace llvm
1213
1214 #endif // LLVM_OBJECT_ELFOBJECTFILE_H
1215