[InstCombine] Signed saturation patterns
[llvm-core.git] / include / llvm / Object / ELFObjectFile.h
blob424289a9ccaa7f5fae4ffaf06fa175e631261cac
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.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_OBJECT_ELFOBJECTFILE_H
14 #define LLVM_OBJECT_ELFOBJECTFILE_H
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>
41 namespace llvm {
42 namespace object {
44 constexpr int NumElfSymbolTypes = 16;
45 extern const llvm::EnumEntry<unsigned> ElfSymbolTypes[NumElfSymbolTypes];
47 class elf_symbol_iterator;
49 class ELFObjectFileBase : public ObjectFile {
50 friend class ELFRelocationRef;
51 friend class ELFSectionRef;
52 friend class ELFSymbolRef;
54 protected:
55 ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
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;
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;
66 virtual Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
67 virtual Error getBuildAttributes(ARMAttributeParser &Attributes) const = 0;
69 public:
70 using elf_symbol_iterator_range = iterator_range<elf_symbol_iterator>;
72 virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
74 /// Returns platform-specific object flags, if any.
75 virtual unsigned getPlatformFlags() const = 0;
77 elf_symbol_iterator_range symbols() const;
79 static bool classof(const Binary *v) { return v->isELF(); }
81 SubtargetFeatures getFeatures() const override;
83 SubtargetFeatures getMIPSFeatures() const;
85 SubtargetFeatures getARMFeatures() const;
87 SubtargetFeatures getRISCVFeatures() const;
89 void setARMSubArch(Triple &TheTriple) const override;
91 virtual uint16_t getEType() const = 0;
93 virtual uint16_t getEMachine() const = 0;
95 std::vector<std::pair<DataRefImpl, uint64_t>> getPltAddresses() const;
98 class ELFSectionRef : public SectionRef {
99 public:
100 ELFSectionRef(const SectionRef &B) : SectionRef(B) {
101 assert(isa<ELFObjectFileBase>(SectionRef::getObject()));
104 const ELFObjectFileBase *getObject() const {
105 return cast<ELFObjectFileBase>(SectionRef::getObject());
108 uint32_t getType() const {
109 return getObject()->getSectionType(getRawDataRefImpl());
112 uint64_t getFlags() const {
113 return getObject()->getSectionFlags(getRawDataRefImpl());
116 uint64_t getOffset() const {
117 return getObject()->getSectionOffset(getRawDataRefImpl());
121 class elf_section_iterator : public section_iterator {
122 public:
123 elf_section_iterator(const section_iterator &B) : section_iterator(B) {
124 assert(isa<ELFObjectFileBase>(B->getObject()));
127 const ELFSectionRef *operator->() const {
128 return static_cast<const ELFSectionRef *>(section_iterator::operator->());
131 const ELFSectionRef &operator*() const {
132 return static_cast<const ELFSectionRef &>(section_iterator::operator*());
136 class ELFSymbolRef : public SymbolRef {
137 public:
138 ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) {
139 assert(isa<ELFObjectFileBase>(SymbolRef::getObject()));
142 const ELFObjectFileBase *getObject() const {
143 return cast<ELFObjectFileBase>(BasicSymbolRef::getObject());
146 uint64_t getSize() const {
147 return getObject()->getSymbolSize(getRawDataRefImpl());
150 uint8_t getBinding() const {
151 return getObject()->getSymbolBinding(getRawDataRefImpl());
154 uint8_t getOther() const {
155 return getObject()->getSymbolOther(getRawDataRefImpl());
158 uint8_t getELFType() const {
159 return getObject()->getSymbolELFType(getRawDataRefImpl());
162 StringRef getELFTypeName() const {
163 uint8_t Type = getELFType();
164 for (auto &EE : ElfSymbolTypes) {
165 if (EE.Value == Type) {
166 return EE.AltName;
169 return "";
173 class elf_symbol_iterator : public symbol_iterator {
174 public:
175 elf_symbol_iterator(const basic_symbol_iterator &B)
176 : symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
177 cast<ELFObjectFileBase>(B->getObject()))) {}
179 const ELFSymbolRef *operator->() const {
180 return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->());
183 const ELFSymbolRef &operator*() const {
184 return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*());
188 class ELFRelocationRef : public RelocationRef {
189 public:
190 ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) {
191 assert(isa<ELFObjectFileBase>(RelocationRef::getObject()));
194 const ELFObjectFileBase *getObject() const {
195 return cast<ELFObjectFileBase>(RelocationRef::getObject());
198 Expected<int64_t> getAddend() const {
199 return getObject()->getRelocationAddend(getRawDataRefImpl());
203 class elf_relocation_iterator : public relocation_iterator {
204 public:
205 elf_relocation_iterator(const relocation_iterator &B)
206 : relocation_iterator(RelocationRef(
207 B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {}
209 const ELFRelocationRef *operator->() const {
210 return static_cast<const ELFRelocationRef *>(
211 relocation_iterator::operator->());
214 const ELFRelocationRef &operator*() const {
215 return static_cast<const ELFRelocationRef &>(
216 relocation_iterator::operator*());
220 inline ELFObjectFileBase::elf_symbol_iterator_range
221 ELFObjectFileBase::symbols() const {
222 return elf_symbol_iterator_range(symbol_begin(), symbol_end());
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;
230 public:
231 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
233 using uintX_t = typename ELFT::uint;
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;
242 SectionRef toSectionRef(const Elf_Shdr *Sec) const {
243 return SectionRef(toDRI(Sec), this);
246 private:
247 ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
248 const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec,
249 ArrayRef<Elf_Word> ShndxTable);
251 protected:
252 ELFFile<ELFT> EF;
254 const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
255 const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
256 ArrayRef<Elf_Word> ShndxTable;
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;
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;
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;
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;
306 /// Get the relocation section that contains \a 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;
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;
321 assert(SymTable->sh_type == ELF::SHT_SYMTAB ||
322 SymTable->sh_type == ELF::SHT_DYNSYM);
324 auto SectionsOrErr = EF.sections();
325 if (!SectionsOrErr) {
326 DRI.d.a = 0;
327 DRI.d.b = 0;
328 return DRI;
330 uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
331 unsigned SymTableIndex =
332 (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr);
334 DRI.d.a = SymTableIndex;
335 DRI.d.b = SymbolNum;
336 return DRI;
339 const Elf_Shdr *toELFShdrIter(DataRefImpl Sec) const {
340 return reinterpret_cast<const Elf_Shdr *>(Sec.p);
343 DataRefImpl toDRI(const Elf_Shdr *Sec) const {
344 DataRefImpl DRI;
345 DRI.p = reinterpret_cast<uintptr_t>(Sec);
346 return DRI;
349 DataRefImpl toDRI(const Elf_Dyn *Dyn) const {
350 DataRefImpl DRI;
351 DRI.p = reinterpret_cast<uintptr_t>(Dyn);
352 return DRI;
355 bool isExportedToOtherDSO(const Elf_Sym *ESym) const {
356 unsigned char Binding = ESym->getBinding();
357 unsigned char Visibility = ESym->getVisibility();
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));
368 Error getBuildAttributes(ARMAttributeParser &Attributes) const override {
369 auto SectionsOrErr = EF.sections();
370 if (!SectionsOrErr)
371 return SectionsOrErr.takeError();
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();
379 auto Contents = ErrorOrContents.get();
380 if (Contents[0] != ARMBuildAttrs::Format_Version || Contents.size() == 1)
381 return Error::success();
383 Attributes.Parse(Contents, ELFT::TargetEndianness == support::little);
384 break;
387 return Error::success();
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;
395 public:
396 ELFObjectFile(ELFObjectFile<ELFT> &&Other);
397 static Expected<ELFObjectFile<ELFT>> create(MemoryBufferRef Object);
399 const Elf_Rel *getRel(DataRefImpl Rel) const;
400 const Elf_Rela *getRela(DataRefImpl Rela) const;
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;
409 const Elf_Shdr *getSection(DataRefImpl Sec) const {
410 return reinterpret_cast<const Elf_Shdr *>(Sec.p);
413 basic_symbol_iterator symbol_begin() const override;
414 basic_symbol_iterator symbol_end() const override;
416 elf_symbol_iterator dynamic_symbol_begin() const;
417 elf_symbol_iterator dynamic_symbol_end() const;
419 section_iterator section_begin() const override;
420 section_iterator section_end() const override;
422 Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const override;
424 uint8_t getBytesInAddress() const override;
425 StringRef getFileFormatName() const override;
426 Triple::ArchType getArch() const override;
427 Expected<uint64_t> getStartAddress() const override;
429 unsigned getPlatformFlags() const override { return EF.getHeader()->e_flags; }
431 const ELFFile<ELFT> *getELFFile() const { return &EF; }
433 bool isDyldType() const { return isDyldELFObject; }
434 static bool classof(const Binary *v) {
435 return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
436 ELFT::Is64Bits);
439 elf_symbol_iterator_range getDynamicSymbolIterators() const override;
441 bool isRelocatableObject() const override;
444 using ELF32LEObjectFile = ELFObjectFile<ELF32LE>;
445 using ELF64LEObjectFile = ELFObjectFile<ELF64LE>;
446 using ELF32BEObjectFile = ELFObjectFile<ELF32BE>;
447 using ELF64BEObjectFile = ELFObjectFile<ELF64BE>;
449 template <class ELFT>
450 void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
451 ++Sym.d.b;
454 template <class ELFT>
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;
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();
479 return Name;
482 template <class ELFT>
483 uint64_t ELFObjectFile<ELFT>::getSectionFlags(DataRefImpl Sec) const {
484 return getSection(Sec)->sh_flags;
487 template <class ELFT>
488 uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const {
489 return getSection(Sec)->sh_type;
492 template <class ELFT>
493 uint64_t ELFObjectFile<ELFT>::getSectionOffset(DataRefImpl Sec) const {
494 return getSection(Sec)->sh_offset;
497 template <class ELFT>
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;
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;
510 return Ret;
513 template <class ELFT>
514 Expected<uint64_t>
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;
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;
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;
540 return Result;
543 template <class ELFT>
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;
551 template <class ELFT>
552 uint16_t ELFObjectFile<ELFT>::getEMachine() const {
553 return EF.getHeader()->e_machine;
556 template <class ELFT> uint16_t ELFObjectFile<ELFT>::getEType() const {
557 return EF.getHeader()->e_type;
560 template <class ELFT>
561 uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
562 return getSymbol(Sym)->st_size;
565 template <class ELFT>
566 uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
567 return getSymbol(Symb)->st_size;
570 template <class ELFT>
571 uint8_t ELFObjectFile<ELFT>::getSymbolBinding(DataRefImpl Symb) const {
572 return getSymbol(Symb)->getBinding();
575 template <class ELFT>
576 uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const {
577 return getSymbol(Symb)->st_other;
580 template <class ELFT>
581 uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const {
582 return getSymbol(Symb)->getType();
585 template <class ELFT>
586 Expected<SymbolRef::Type>
587 ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
588 const Elf_Sym *ESym = getSymbol(Symb);
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;
608 template <class ELFT>
609 uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
610 const Elf_Sym *ESym = getSymbol(Sym);
612 uint32_t Result = SymbolRef::SF_None;
614 if (ESym->getBinding() != ELF::STB_LOCAL)
615 Result |= SymbolRef::SF_Global;
617 if (ESym->getBinding() == ELF::STB_WEAK)
618 Result |= SymbolRef::SF_Weak;
620 if (ESym->st_shndx == ELF::SHN_ABS)
621 Result |= SymbolRef::SF_Absolute;
623 if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION)
624 Result |= SymbolRef::SF_FormatSpecific;
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;
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());
643 if (ESym->getType() == ELF::STT_FUNC && (ESym->st_value & 1) == 1)
644 Result |= SymbolRef::SF_Thumb;
647 if (ESym->st_shndx == ELF::SHN_UNDEF)
648 Result |= SymbolRef::SF_Undefined;
650 if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON)
651 Result |= SymbolRef::SF_Common;
653 if (isExportedToOtherDSO(ESym))
654 Result |= SymbolRef::SF_Exported;
656 if (ESym->getVisibility() == ELF::STV_HIDDEN)
657 Result |= SymbolRef::SF_Hidden;
659 return Result;
662 template <class ELFT>
663 Expected<section_iterator>
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();
670 const Elf_Shdr *ESec = *ESecOrErr;
671 if (!ESec)
672 return section_end();
674 DataRefImpl Sec;
675 Sec.p = reinterpret_cast<intptr_t>(ESec);
676 return section_iterator(SectionRef(Sec, this));
679 template <class ELFT>
680 Expected<section_iterator>
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);
690 template <class ELFT>
691 void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
692 const Elf_Shdr *ESec = getSection(Sec);
693 Sec = toDRI(++ESec);
696 template <class ELFT>
697 Expected<StringRef> ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec) const {
698 return EF.getSectionName(&*getSection(Sec));
701 template <class ELFT>
702 uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const {
703 return getSection(Sec)->sh_addr;
706 template <class ELFT>
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");
713 const Elf_Shdr *First = SectionsOrErr->begin();
714 return getSection(Sec) - First;
717 template <class ELFT>
718 uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
719 return getSection(Sec)->sh_size;
722 template <class ELFT>
723 Expected<ArrayRef<uint8_t>>
724 ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec) const {
725 const Elf_Shdr *EShdr = getSection(Sec);
726 if (std::error_code EC =
727 checkOffset(getMemoryBufferRef(),
728 (uintptr_t)base() + EShdr->sh_offset, EShdr->sh_size))
729 return errorCodeToError(EC);
730 return makeArrayRef((const uint8_t *)base() + EShdr->sh_offset,
731 EShdr->sh_size);
734 template <class ELFT>
735 uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const {
736 return getSection(Sec)->sh_addralign;
739 template <class ELFT>
740 bool ELFObjectFile<ELFT>::isSectionCompressed(DataRefImpl Sec) const {
741 return getSection(Sec)->sh_flags & ELF::SHF_COMPRESSED;
744 template <class ELFT>
745 bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
746 return getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR;
749 template <class ELFT>
750 bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const {
751 const Elf_Shdr *EShdr = getSection(Sec);
752 return EShdr->sh_type == ELF::SHT_PROGBITS &&
753 EShdr->sh_flags & ELF::SHF_ALLOC &&
754 !(EShdr->sh_flags & ELF::SHF_EXECINSTR);
757 template <class ELFT>
758 bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const {
759 const Elf_Shdr *EShdr = getSection(Sec);
760 return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
761 EShdr->sh_type == ELF::SHT_NOBITS;
764 template <class ELFT>
765 std::vector<SectionRef>
766 ELFObjectFile<ELFT>::dynamic_relocation_sections() const {
767 std::vector<SectionRef> Res;
768 std::vector<uintptr_t> Offsets;
770 auto SectionsOrErr = EF.sections();
771 if (!SectionsOrErr)
772 return Res;
774 for (const Elf_Shdr &Sec : *SectionsOrErr) {
775 if (Sec.sh_type != ELF::SHT_DYNAMIC)
776 continue;
777 Elf_Dyn *Dynamic =
778 reinterpret_cast<Elf_Dyn *>((uintptr_t)base() + Sec.sh_offset);
779 for (; Dynamic->d_tag != ELF::DT_NULL; Dynamic++) {
780 if (Dynamic->d_tag == ELF::DT_REL || Dynamic->d_tag == ELF::DT_RELA ||
781 Dynamic->d_tag == ELF::DT_JMPREL) {
782 Offsets.push_back(Dynamic->d_un.d_val);
786 for (const Elf_Shdr &Sec : *SectionsOrErr) {
787 if (is_contained(Offsets, Sec.sh_addr))
788 Res.emplace_back(toDRI(&Sec), this);
790 return Res;
793 template <class ELFT>
794 bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
795 return getSection(Sec)->sh_type == ELF::SHT_NOBITS;
798 template <class ELFT>
799 bool ELFObjectFile<ELFT>::isBerkeleyText(DataRefImpl Sec) const {
800 return getSection(Sec)->sh_flags & ELF::SHF_ALLOC &&
801 (getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR ||
802 !(getSection(Sec)->sh_flags & ELF::SHF_WRITE));
805 template <class ELFT>
806 bool ELFObjectFile<ELFT>::isBerkeleyData(DataRefImpl Sec) const {
807 const Elf_Shdr *EShdr = getSection(Sec);
808 return !isBerkeleyText(Sec) && EShdr->sh_type != ELF::SHT_NOBITS &&
809 EShdr->sh_flags & ELF::SHF_ALLOC;
812 template <class ELFT>
813 relocation_iterator
814 ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
815 DataRefImpl RelData;
816 auto SectionsOrErr = EF.sections();
817 if (!SectionsOrErr)
818 return relocation_iterator(RelocationRef());
819 uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
820 RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
821 RelData.d.b = 0;
822 return relocation_iterator(RelocationRef(RelData, this));
825 template <class ELFT>
826 relocation_iterator
827 ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
828 const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
829 relocation_iterator Begin = section_rel_begin(Sec);
830 if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
831 return Begin;
832 DataRefImpl RelData = Begin->getRawDataRefImpl();
833 const Elf_Shdr *RelSec = getRelSection(RelData);
835 // Error check sh_link here so that getRelocationSymbol can just use it.
836 auto SymSecOrErr = EF.getSection(RelSec->sh_link);
837 if (!SymSecOrErr)
838 report_fatal_error(errorToErrorCode(SymSecOrErr.takeError()).message());
840 RelData.d.b += S->sh_size / S->sh_entsize;
841 return relocation_iterator(RelocationRef(RelData, this));
844 template <class ELFT>
845 Expected<section_iterator>
846 ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
847 if (EF.getHeader()->e_type != ELF::ET_REL)
848 return section_end();
850 const Elf_Shdr *EShdr = getSection(Sec);
851 uintX_t Type = EShdr->sh_type;
852 if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
853 return section_end();
855 Expected<const Elf_Shdr *> SecOrErr = EF.getSection(EShdr->sh_info);
856 if (!SecOrErr)
857 return SecOrErr.takeError();
858 return section_iterator(SectionRef(toDRI(*SecOrErr), this));
861 // Relocations
862 template <class ELFT>
863 void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
864 ++Rel.d.b;
867 template <class ELFT>
868 symbol_iterator
869 ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
870 uint32_t symbolIdx;
871 const Elf_Shdr *sec = getRelSection(Rel);
872 if (sec->sh_type == ELF::SHT_REL)
873 symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
874 else
875 symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
876 if (!symbolIdx)
877 return symbol_end();
879 // FIXME: error check symbolIdx
880 DataRefImpl SymbolData;
881 SymbolData.d.a = sec->sh_link;
882 SymbolData.d.b = symbolIdx;
883 return symbol_iterator(SymbolRef(SymbolData, this));
886 template <class ELFT>
887 uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
888 const Elf_Shdr *sec = getRelSection(Rel);
889 if (sec->sh_type == ELF::SHT_REL)
890 return getRel(Rel)->r_offset;
892 return getRela(Rel)->r_offset;
895 template <class ELFT>
896 uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const {
897 const Elf_Shdr *sec = getRelSection(Rel);
898 if (sec->sh_type == ELF::SHT_REL)
899 return getRel(Rel)->getType(EF.isMips64EL());
900 else
901 return getRela(Rel)->getType(EF.isMips64EL());
904 template <class ELFT>
905 StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
906 return getELFRelocationTypeName(EF.getHeader()->e_machine, Type);
909 template <class ELFT>
910 void ELFObjectFile<ELFT>::getRelocationTypeName(
911 DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
912 uint32_t type = getRelocationType(Rel);
913 EF.getRelocationTypeName(type, Result);
916 template <class ELFT>
917 Expected<int64_t>
918 ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const {
919 if (getRelSection(Rel)->sh_type != ELF::SHT_RELA)
920 return createError("Section is not SHT_RELA");
921 return (int64_t)getRela(Rel)->r_addend;
924 template <class ELFT>
925 const typename ELFObjectFile<ELFT>::Elf_Rel *
926 ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
927 assert(getRelSection(Rel)->sh_type == ELF::SHT_REL);
928 auto Ret = EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
929 if (!Ret)
930 report_fatal_error(errorToErrorCode(Ret.takeError()).message());
931 return *Ret;
934 template <class ELFT>
935 const typename ELFObjectFile<ELFT>::Elf_Rela *
936 ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
937 assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA);
938 auto Ret = EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
939 if (!Ret)
940 report_fatal_error(errorToErrorCode(Ret.takeError()).message());
941 return *Ret;
944 template <class ELFT>
945 Expected<ELFObjectFile<ELFT>>
946 ELFObjectFile<ELFT>::create(MemoryBufferRef Object) {
947 auto EFOrErr = ELFFile<ELFT>::create(Object.getBuffer());
948 if (Error E = EFOrErr.takeError())
949 return std::move(E);
950 auto EF = std::move(*EFOrErr);
952 auto SectionsOrErr = EF.sections();
953 if (!SectionsOrErr)
954 return SectionsOrErr.takeError();
956 const Elf_Shdr *DotDynSymSec = nullptr;
957 const Elf_Shdr *DotSymtabSec = nullptr;
958 ArrayRef<Elf_Word> ShndxTable;
959 for (const Elf_Shdr &Sec : *SectionsOrErr) {
960 switch (Sec.sh_type) {
961 case ELF::SHT_DYNSYM: {
962 if (!DotDynSymSec)
963 DotDynSymSec = &Sec;
964 break;
966 case ELF::SHT_SYMTAB: {
967 if (!DotSymtabSec)
968 DotSymtabSec = &Sec;
969 break;
971 case ELF::SHT_SYMTAB_SHNDX: {
972 auto TableOrErr = EF.getSHNDXTable(Sec);
973 if (!TableOrErr)
974 return TableOrErr.takeError();
975 ShndxTable = *TableOrErr;
976 break;
980 return ELFObjectFile<ELFT>(Object, EF, DotDynSymSec, DotSymtabSec,
981 ShndxTable);
984 template <class ELFT>
985 ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
986 const Elf_Shdr *DotDynSymSec,
987 const Elf_Shdr *DotSymtabSec,
988 ArrayRef<Elf_Word> ShndxTable)
989 : ELFObjectFileBase(
990 getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
991 Object),
992 EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec),
993 ShndxTable(ShndxTable) {}
995 template <class ELFT>
996 ELFObjectFile<ELFT>::ELFObjectFile(ELFObjectFile<ELFT> &&Other)
997 : ELFObjectFile(Other.Data, Other.EF, Other.DotDynSymSec,
998 Other.DotSymtabSec, Other.ShndxTable) {}
1000 template <class ELFT>
1001 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const {
1002 DataRefImpl Sym =
1003 toDRI(DotSymtabSec,
1004 DotSymtabSec && DotSymtabSec->sh_size >= sizeof(Elf_Sym) ? 1 : 0);
1005 return basic_symbol_iterator(SymbolRef(Sym, this));
1008 template <class ELFT>
1009 basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end() const {
1010 const Elf_Shdr *SymTab = DotSymtabSec;
1011 if (!SymTab)
1012 return symbol_begin();
1013 DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
1014 return basic_symbol_iterator(SymbolRef(Sym, this));
1017 template <class ELFT>
1018 elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
1019 DataRefImpl Sym = toDRI(DotDynSymSec, 0);
1020 return symbol_iterator(SymbolRef(Sym, this));
1023 template <class ELFT>
1024 elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
1025 const Elf_Shdr *SymTab = DotDynSymSec;
1026 if (!SymTab)
1027 return dynamic_symbol_begin();
1028 DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
1029 return basic_symbol_iterator(SymbolRef(Sym, this));
1032 template <class ELFT>
1033 section_iterator ELFObjectFile<ELFT>::section_begin() const {
1034 auto SectionsOrErr = EF.sections();
1035 if (!SectionsOrErr)
1036 return section_iterator(SectionRef());
1037 return section_iterator(SectionRef(toDRI((*SectionsOrErr).begin()), this));
1040 template <class ELFT>
1041 section_iterator ELFObjectFile<ELFT>::section_end() const {
1042 auto SectionsOrErr = EF.sections();
1043 if (!SectionsOrErr)
1044 return section_iterator(SectionRef());
1045 return section_iterator(SectionRef(toDRI((*SectionsOrErr).end()), this));
1048 template <class ELFT>
1049 uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
1050 return ELFT::Is64Bits ? 8 : 4;
1053 template <class ELFT>
1054 StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
1055 bool IsLittleEndian = ELFT::TargetEndianness == support::little;
1056 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
1057 case ELF::ELFCLASS32:
1058 switch (EF.getHeader()->e_machine) {
1059 case ELF::EM_386:
1060 return "ELF32-i386";
1061 case ELF::EM_IAMCU:
1062 return "ELF32-iamcu";
1063 case ELF::EM_X86_64:
1064 return "ELF32-x86-64";
1065 case ELF::EM_ARM:
1066 return (IsLittleEndian ? "ELF32-arm-little" : "ELF32-arm-big");
1067 case ELF::EM_AVR:
1068 return "ELF32-avr";
1069 case ELF::EM_HEXAGON:
1070 return "ELF32-hexagon";
1071 case ELF::EM_LANAI:
1072 return "ELF32-lanai";
1073 case ELF::EM_MIPS:
1074 return "ELF32-mips";
1075 case ELF::EM_MSP430:
1076 return "ELF32-msp430";
1077 case ELF::EM_PPC:
1078 return "ELF32-ppc";
1079 case ELF::EM_RISCV:
1080 return "ELF32-riscv";
1081 case ELF::EM_SPARC:
1082 case ELF::EM_SPARC32PLUS:
1083 return "ELF32-sparc";
1084 case ELF::EM_AMDGPU:
1085 return "ELF32-amdgpu";
1086 default:
1087 return "ELF32-unknown";
1089 case ELF::ELFCLASS64:
1090 switch (EF.getHeader()->e_machine) {
1091 case ELF::EM_386:
1092 return "ELF64-i386";
1093 case ELF::EM_X86_64:
1094 return "ELF64-x86-64";
1095 case ELF::EM_AARCH64:
1096 return (IsLittleEndian ? "ELF64-aarch64-little" : "ELF64-aarch64-big");
1097 case ELF::EM_PPC64:
1098 return "ELF64-ppc64";
1099 case ELF::EM_RISCV:
1100 return "ELF64-riscv";
1101 case ELF::EM_S390:
1102 return "ELF64-s390";
1103 case ELF::EM_SPARCV9:
1104 return "ELF64-sparc";
1105 case ELF::EM_MIPS:
1106 return "ELF64-mips";
1107 case ELF::EM_AMDGPU:
1108 return "ELF64-amdgpu";
1109 case ELF::EM_BPF:
1110 return "ELF64-BPF";
1111 default:
1112 return "ELF64-unknown";
1114 default:
1115 // FIXME: Proper error handling.
1116 report_fatal_error("Invalid ELFCLASS!");
1120 template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
1121 bool IsLittleEndian = ELFT::TargetEndianness == support::little;
1122 switch (EF.getHeader()->e_machine) {
1123 case ELF::EM_386:
1124 case ELF::EM_IAMCU:
1125 return Triple::x86;
1126 case ELF::EM_X86_64:
1127 return Triple::x86_64;
1128 case ELF::EM_AARCH64:
1129 return IsLittleEndian ? Triple::aarch64 : Triple::aarch64_be;
1130 case ELF::EM_ARM:
1131 return Triple::arm;
1132 case ELF::EM_AVR:
1133 return Triple::avr;
1134 case ELF::EM_HEXAGON:
1135 return Triple::hexagon;
1136 case ELF::EM_LANAI:
1137 return Triple::lanai;
1138 case ELF::EM_MIPS:
1139 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
1140 case ELF::ELFCLASS32:
1141 return IsLittleEndian ? Triple::mipsel : Triple::mips;
1142 case ELF::ELFCLASS64:
1143 return IsLittleEndian ? Triple::mips64el : Triple::mips64;
1144 default:
1145 report_fatal_error("Invalid ELFCLASS!");
1147 case ELF::EM_MSP430:
1148 return Triple::msp430;
1149 case ELF::EM_PPC:
1150 return Triple::ppc;
1151 case ELF::EM_PPC64:
1152 return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
1153 case ELF::EM_RISCV:
1154 switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
1155 case ELF::ELFCLASS32:
1156 return Triple::riscv32;
1157 case ELF::ELFCLASS64:
1158 return Triple::riscv64;
1159 default:
1160 report_fatal_error("Invalid ELFCLASS!");
1162 case ELF::EM_S390:
1163 return Triple::systemz;
1165 case ELF::EM_SPARC:
1166 case ELF::EM_SPARC32PLUS:
1167 return IsLittleEndian ? Triple::sparcel : Triple::sparc;
1168 case ELF::EM_SPARCV9:
1169 return Triple::sparcv9;
1171 case ELF::EM_AMDGPU: {
1172 if (!IsLittleEndian)
1173 return Triple::UnknownArch;
1175 unsigned MACH = EF.getHeader()->e_flags & ELF::EF_AMDGPU_MACH;
1176 if (MACH >= ELF::EF_AMDGPU_MACH_R600_FIRST &&
1177 MACH <= ELF::EF_AMDGPU_MACH_R600_LAST)
1178 return Triple::r600;
1179 if (MACH >= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST &&
1180 MACH <= ELF::EF_AMDGPU_MACH_AMDGCN_LAST)
1181 return Triple::amdgcn;
1183 return Triple::UnknownArch;
1186 case ELF::EM_BPF:
1187 return IsLittleEndian ? Triple::bpfel : Triple::bpfeb;
1189 default:
1190 return Triple::UnknownArch;
1194 template <class ELFT>
1195 Expected<uint64_t> ELFObjectFile<ELFT>::getStartAddress() const {
1196 return EF.getHeader()->e_entry;
1199 template <class ELFT>
1200 ELFObjectFileBase::elf_symbol_iterator_range
1201 ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
1202 return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
1205 template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
1206 return EF.getHeader()->e_type == ELF::ET_REL;
1209 } // end namespace object
1210 } // end namespace llvm
1212 #endif // LLVM_OBJECT_ELFOBJECTFILE_H