diff options
Diffstat (limited to 'contrib/llvm/include/llvm/Object/ELFObjectFile.h')
-rw-r--r-- | contrib/llvm/include/llvm/Object/ELFObjectFile.h | 482 |
1 files changed, 242 insertions, 240 deletions
diff --git a/contrib/llvm/include/llvm/Object/ELFObjectFile.h b/contrib/llvm/include/llvm/Object/ELFObjectFile.h index 075ca5a..069f381 100644 --- a/contrib/llvm/include/llvm/Object/ELFObjectFile.h +++ b/contrib/llvm/include/llvm/Object/ELFObjectFile.h @@ -44,6 +44,7 @@ public: typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr; + typedef typename ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr; typedef typename ELFFile<ELFT>::Elf_Rel Elf_Rel; typedef typename ELFFile<ELFT>::Elf_Rela Elf_Rela; typedef typename ELFFile<ELFT>::Elf_Dyn Elf_Dyn; @@ -55,53 +56,65 @@ public: protected: ELFFile<ELFT> EF; - virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; - virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; - virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const; - virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; - virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const; - virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; - virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; - virtual error_code getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Res) const; - virtual error_code getSymbolSection(DataRefImpl Symb, - section_iterator &Res) const; - virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; - - virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const; - virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const; - - virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; - virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; - virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; - virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; - virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; - virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const; - virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; - virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; - virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; - virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, - bool &Res) const; - virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; - virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; - virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const; - virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, - bool &Result) const; - virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const; - virtual relocation_iterator section_rel_end(DataRefImpl Sec) const; - virtual section_iterator getRelocatedSection(DataRefImpl Sec) const; - - virtual error_code getRelocationNext(DataRefImpl Rel, - RelocationRef &Res) const; - virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const; - virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const; - virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const; - virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const; - virtual error_code getRelocationTypeName(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const; - virtual error_code + void moveSymbolNext(DataRefImpl &Symb) const override; + std::error_code getSymbolName(DataRefImpl Symb, + StringRef &Res) const override; + std::error_code getSymbolAddress(DataRefImpl Symb, + uint64_t &Res) const override; + std::error_code getSymbolAlignment(DataRefImpl Symb, + uint32_t &Res) const override; + std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; + uint32_t getSymbolFlags(DataRefImpl Symb) const override; + std::error_code getSymbolOther(DataRefImpl Symb, uint8_t &Res) const override; + std::error_code getSymbolType(DataRefImpl Symb, + SymbolRef::Type &Res) const override; + std::error_code getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const override; + + std::error_code getLibraryNext(DataRefImpl Data, + LibraryRef &Result) const override; + std::error_code getLibraryPath(DataRefImpl Data, + StringRef &Res) const override; + + void moveSectionNext(DataRefImpl &Sec) const override; + std::error_code getSectionName(DataRefImpl Sec, + StringRef &Res) const override; + std::error_code getSectionAddress(DataRefImpl Sec, + uint64_t &Res) const override; + std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override; + std::error_code getSectionContents(DataRefImpl Sec, + StringRef &Res) const override; + std::error_code getSectionAlignment(DataRefImpl Sec, + uint64_t &Res) const override; + std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override; + std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override; + std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override; + std::error_code isSectionRequiredForExecution(DataRefImpl Sec, + bool &Res) const override; + std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override; + std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override; + std::error_code isSectionReadOnlyData(DataRefImpl Sec, + bool &Res) const override; + std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, + bool &Result) const override; + relocation_iterator section_rel_begin(DataRefImpl Sec) const override; + relocation_iterator section_rel_end(DataRefImpl Sec) const override; + section_iterator getRelocatedSection(DataRefImpl Sec) const override; + + void moveRelocationNext(DataRefImpl &Rel) const override; + std::error_code getRelocationAddress(DataRefImpl Rel, + uint64_t &Res) const override; + std::error_code getRelocationOffset(DataRefImpl Rel, + uint64_t &Res) const override; + symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; + std::error_code getRelocationType(DataRefImpl Rel, + uint64_t &Res) const override; + std::error_code + getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl<char> &Result) const override; + std::error_code getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const; + SmallVectorImpl<char> &Result) const override; uint64_t getROffset(DataRefImpl Rel) const; StringRef getRelocationTypeName(uint32_t Type) const; @@ -165,31 +178,35 @@ protected: bool isDyldELFObject; public: - ELFObjectFile(MemoryBuffer *Object, error_code &ec); + ELFObjectFile(std::unique_ptr<MemoryBuffer> Object, std::error_code &EC); const Elf_Sym *getSymbol(DataRefImpl Symb) const; - virtual symbol_iterator begin_symbols() const; - virtual symbol_iterator end_symbols() const; + basic_symbol_iterator symbol_begin_impl() const override; + basic_symbol_iterator symbol_end_impl() const override; - virtual symbol_iterator begin_dynamic_symbols() const; - virtual symbol_iterator end_dynamic_symbols() const; + symbol_iterator dynamic_symbol_begin() const; + symbol_iterator dynamic_symbol_end() const; - virtual section_iterator begin_sections() const; - virtual section_iterator end_sections() const; + section_iterator section_begin() const override; + section_iterator section_end() const override; - virtual library_iterator begin_libraries_needed() const; - virtual library_iterator end_libraries_needed() const; + library_iterator needed_library_begin() const override; + library_iterator needed_library_end() const override; - error_code getRelocationAddend(DataRefImpl Rel, int64_t &Res) const; - error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, - bool &IsDefault) const; + std::error_code getRelocationAddend(DataRefImpl Rel, int64_t &Res) const; + std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, + bool &IsDefault) const; - virtual uint8_t getBytesInAddress() const; - virtual StringRef getFileFormatName() const; - virtual StringRef getObjectType() const { return "ELF"; } - virtual unsigned getArch() const; - virtual StringRef getLoadName() const; + uint8_t getBytesInAddress() const override; + StringRef getFileFormatName() const override; + unsigned getArch() const override; + StringRef getLoadName() const override; + + std::error_code getPlatformFlags(unsigned &Result) const override { + Result = EF.getHeader()->e_flags; + return object_error::success; + } const ELFFile<ELFT> *getELFFile() const { return &EF; } @@ -208,44 +225,40 @@ typedef ELFObjectFile<ELFType<support::big, 2, false> > ELF32BEObjectFile; typedef ELFObjectFile<ELFType<support::big, 2, true> > ELF64BEObjectFile; template <class ELFT> -error_code ELFObjectFile<ELFT>::getSymbolNext(DataRefImpl Symb, - SymbolRef &Result) const { - Result = SymbolRef(toDRI(++toELFSymIter(Symb)), this); - return object_error::success; +void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Symb) const { + Symb = toDRI(++toELFSymIter(Symb)); } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb, - StringRef &Result) const { +std::error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb, + StringRef &Result) const { ErrorOr<StringRef> Name = EF.getSymbolName(toELFSymIter(Symb)); if (!Name) - return Name; + return Name.getError(); Result = *Name; return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef, - StringRef &Version, - bool &IsDefault) const { +std::error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef, + StringRef &Version, + bool &IsDefault) const { DataRefImpl Symb = SymRef.getRawDataRefImpl(); const Elf_Sym *symb = getSymbol(Symb); ErrorOr<StringRef> Ver = EF.getSymbolVersion(EF.getSection(Symb.d.b), symb, IsDefault); if (!Ver) - return Ver; + return Ver.getError(); Version = *Ver; return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSymbolFileOffset(DataRefImpl Symb, - uint64_t &Result) const { +std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, + uint64_t &Result) const { const Elf_Sym *ESym = getSymbol(Symb); - const Elf_Shdr *ESec; switch (EF.getSymbolTableIndex(ESym)) { case ELF::SHN_COMMON: - // Unintialized symbols have no offset in the object file case ELF::SHN_UNDEF: Result = UnknownAddressOrSize; return object_error::success; @@ -253,75 +266,25 @@ error_code ELFObjectFile<ELFT>::getSymbolFileOffset(DataRefImpl Symb, Result = ESym->st_value; return object_error::success; default: - ESec = EF.getSection(ESym); + break; } - switch (ESym->getType()) { - case ELF::STT_SECTION: - Result = ESec ? ESec->sh_offset : UnknownAddressOrSize; - return object_error::success; - case ELF::STT_FUNC: - case ELF::STT_OBJECT: - case ELF::STT_NOTYPE: - Result = ESym->st_value + (ESec ? ESec->sh_offset : 0); - return object_error::success; - default: - Result = UnknownAddressOrSize; - return object_error::success; - } -} + const Elf_Ehdr *Header = EF.getHeader(); + Result = ESym->st_value; -template <class ELFT> -error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, - uint64_t &Result) const { - const Elf_Sym *ESym = getSymbol(Symb); - const Elf_Shdr *ESec; - switch (EF.getSymbolTableIndex(ESym)) { - case ELF::SHN_COMMON: - case ELF::SHN_UNDEF: - Result = UnknownAddressOrSize; - return object_error::success; - case ELF::SHN_ABS: - Result = ESym->st_value; - return object_error::success; - default: - ESec = EF.getSection(ESym); - } - - switch (ESym->getType()) { - case ELF::STT_SECTION: - Result = ESec ? ESec->sh_addr : UnknownAddressOrSize; - return object_error::success; - case ELF::STT_FUNC: - case ELF::STT_OBJECT: - case ELF::STT_NOTYPE: - bool IsRelocatable; - switch (EF.getHeader()->e_type) { - case ELF::ET_EXEC: - case ELF::ET_DYN: - IsRelocatable = false; - break; - default: - IsRelocatable = true; - } - Result = ESym->st_value; + // Clear the ARM/Thumb indicator flag. + if (Header->e_machine == ELF::EM_ARM && ESym->getType() == ELF::STT_FUNC) + Result &= ~1; - // Clear the ARM/Thumb indicator flag. - if (EF.getHeader()->e_machine == ELF::EM_ARM) - Result &= ~1; + if (Header->e_type == ELF::ET_REL) + Result += EF.getSection(ESym)->sh_addr; - if (IsRelocatable && ESec != 0) - Result += ESec->sh_addr; - return object_error::success; - default: - Result = UnknownAddressOrSize; - return object_error::success; - } + return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const { +std::error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb, + uint32_t &Res) const { Elf_Sym_Iter Sym = toELFSymIter(Symb); if (Sym->st_shndx == ELF::SHN_COMMON) Res = Sym->st_value; @@ -331,15 +294,23 @@ error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb, } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb, - uint64_t &Result) const { +std::error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb, + uint64_t &Result) const { Result = toELFSymIter(Symb)->st_size; return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Result) const { +std::error_code ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb, + uint8_t &Result) const { + Result = toELFSymIter(Symb)->st_other; + return object_error::success; +} + +template <class ELFT> +std::error_code +ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb, + SymbolRef::Type &Result) const { const Elf_Sym *ESym = getSymbol(Symb); switch (ESym->getType()) { @@ -368,11 +339,11 @@ error_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb, } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb, - uint32_t &Result) const { - const Elf_Sym *ESym = getSymbol(Symb); +uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb) const { + Elf_Sym_Iter EIter = toELFSymIter(Symb); + const Elf_Sym *ESym = &*EIter; - Result = SymbolRef::SF_None; + uint32_t Result = SymbolRef::SF_None; if (ESym->getBinding() != ELF::STB_LOCAL) Result |= SymbolRef::SF_Global; @@ -384,7 +355,7 @@ error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb, Result |= SymbolRef::SF_Absolute; if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION || - ESym == &*EF.begin_symbols()) + EIter == EF.begin_symbols() || EIter == EF.begin_dynamic_symbols()) Result |= SymbolRef::SF_FormatSpecific; if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF) @@ -394,19 +365,17 @@ error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb, EF.getSymbolTableIndex(ESym) == ELF::SHN_COMMON) Result |= SymbolRef::SF_Common; - if (ESym->getType() == ELF::STT_TLS) - Result |= SymbolRef::SF_ThreadLocal; - - return object_error::success; + return Result; } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, - section_iterator &Res) const { +std::error_code +ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const { const Elf_Sym *ESym = getSymbol(Symb); const Elf_Shdr *ESec = EF.getSection(ESym); if (!ESec) - Res = end_sections(); + Res = section_end(); else { DataRefImpl Sec; Sec.p = reinterpret_cast<intptr_t>(ESec); @@ -416,69 +385,61 @@ error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb, - uint64_t &Val) const { - const Elf_Sym *ESym = getSymbol(Symb); - Val = ESym->st_value; - return object_error::success; -} - -template <class ELFT> -error_code ELFObjectFile<ELFT>::getSectionNext(DataRefImpl Sec, - SectionRef &Result) const { - Result = SectionRef(toDRI(++toELFShdrIter(Sec)), this); - return object_error::success; +void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const { + Sec = toDRI(++toELFShdrIter(Sec)); } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec, - StringRef &Result) const { +std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec, + StringRef &Result) const { ErrorOr<StringRef> Name = EF.getSectionName(&*toELFShdrIter(Sec)); if (!Name) - return Name; + return Name.getError(); Result = *Name; return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec, - uint64_t &Result) const { +std::error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec, + uint64_t &Result) const { Result = toELFShdrIter(Sec)->sh_addr; return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec, - uint64_t &Result) const { +std::error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec, + uint64_t &Result) const { Result = toELFShdrIter(Sec)->sh_size; return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec, - StringRef &Result) const { +std::error_code +ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec, + StringRef &Result) const { Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size); return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec, - uint64_t &Result) const { +std::error_code +ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec, + uint64_t &Result) const { Result = toELFShdrIter(Sec)->sh_addralign; return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec, - bool &Result) const { +std::error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec, + bool &Result) const { Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR; return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec, - bool &Result) const { +std::error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec, + bool &Result) const { Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && EShdr->sh_type == ELF::SHT_PROGBITS; @@ -486,8 +447,8 @@ error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec, } template <class ELFT> -error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec, - bool &Result) const { +std::error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec, + bool &Result) const { Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && EShdr->sh_type == ELF::SHT_NOBITS; @@ -495,7 +456,7 @@ error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec, } template <class ELFT> -error_code +std::error_code ELFObjectFile<ELFT>::isSectionRequiredForExecution(DataRefImpl Sec, bool &Result) const { Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_ALLOC; @@ -503,31 +464,31 @@ ELFObjectFile<ELFT>::isSectionRequiredForExecution(DataRefImpl Sec, } template <class ELFT> -error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec, - bool &Result) const { +std::error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec, + bool &Result) const { Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS; return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec, - bool &Result) const { +std::error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec, + bool &Result) const { Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS; return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec, - bool &Result) const { +std::error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec, + bool &Result) const { Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); Result = !(EShdr->sh_flags & (ELF::SHF_WRITE | ELF::SHF_EXECINSTR)); return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec, - DataRefImpl Symb, - bool &Result) const { +std::error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec, + DataRefImpl Symb, + bool &Result) const { Elf_Sym_Iter ESym = toELFSymIter(Symb); uintX_t Index = ESym->st_shndx; @@ -566,12 +527,12 @@ template <class ELFT> section_iterator ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const { if (EF.getHeader()->e_type != ELF::ET_REL) - return end_sections(); + return section_end(); Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); uintX_t Type = EShdr->sh_type; if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA) - return end_sections(); + return section_end(); const Elf_Shdr *R = EF.getSection(EShdr->sh_info); return section_iterator(SectionRef(toDRI(R), this)); @@ -579,11 +540,8 @@ ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const { // Relocations template <class ELFT> -error_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel, - RelocationRef &Result) const { +void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const { ++Rel.d.b; - Result = RelocationRef(Rel, this); - return object_error::success; } template <class ELFT> @@ -604,7 +562,7 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const { } } if (!symbolIdx) - return end_symbols(); + return symbol_end(); const Elf_Shdr *SymSec = EF.getSection(sec->sh_link); @@ -624,15 +582,29 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const { } template <class ELFT> -error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, - uint64_t &Result) const { - Result = getROffset(Rel); +std::error_code +ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, + uint64_t &Result) const { + uint64_t ROffset = getROffset(Rel); + const Elf_Ehdr *Header = EF.getHeader(); + + if (Header->e_type == ELF::ET_REL) { + const Elf_Shdr *RelocationSec = getRelSection(Rel); + const Elf_Shdr *RelocatedSec = EF.getSection(RelocationSec->sh_info); + Result = ROffset + RelocatedSec->sh_addr; + } else { + Result = ROffset; + } + return object_error::success; } template <class ELFT> -error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel, - uint64_t &Result) const { +std::error_code +ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel, + uint64_t &Result) const { + assert(EF.getHeader()->e_type == ELF::ET_REL && + "Only relocatable object files have relocation offsets"); Result = getROffset(Rel); return object_error::success; } @@ -651,8 +623,8 @@ uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const { } template <class ELFT> -error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel, - uint64_t &Result) const { +std::error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel, + uint64_t &Result) const { const Elf_Shdr *sec = getRelSection(Rel); switch (sec->sh_type) { default: @@ -675,7 +647,7 @@ StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const { } template <class ELFT> -error_code ELFObjectFile<ELFT>::getRelocationTypeName( +std::error_code ELFObjectFile<ELFT>::getRelocationTypeName( DataRefImpl Rel, SmallVectorImpl<char> &Result) const { const Elf_Shdr *sec = getRelSection(Rel); uint32_t type; @@ -697,8 +669,9 @@ error_code ELFObjectFile<ELFT>::getRelocationTypeName( } template <class ELFT> -error_code ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel, - int64_t &Result) const { +std::error_code +ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel, + int64_t &Result) const { const Elf_Shdr *sec = getRelSection(Rel); switch (sec->sh_type) { default: @@ -715,7 +688,7 @@ error_code ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel, } template <class ELFT> -error_code ELFObjectFile<ELFT>::getRelocationValueString( +std::error_code ELFObjectFile<ELFT>::getRelocationValueString( DataRefImpl Rel, SmallVectorImpl<char> &Result) const { const Elf_Shdr *sec = getRelSection(Rel); uint8_t type; @@ -743,7 +716,7 @@ error_code ELFObjectFile<ELFT>::getRelocationValueString( ErrorOr<StringRef> SymName = EF.getSymbolName(EF.getSection(sec->sh_link), symb); if (!SymName) - return SymName; + return SymName.getError(); switch (EF.getHeader()->e_machine) { case ELF::EM_X86_64: switch (type) { @@ -783,6 +756,7 @@ error_code ELFObjectFile<ELFT>::getRelocationValueString( } case ELF::EM_ARM: case ELF::EM_HEXAGON: + case ELF::EM_MIPS: res = *SymName; break; default: @@ -812,40 +786,41 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const { } template <class ELFT> -ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec) +ELFObjectFile<ELFT>::ELFObjectFile(std::unique_ptr<MemoryBuffer> Object, + std::error_code &EC) : ObjectFile(getELFType(static_cast<endianness>(ELFT::TargetEndianness) == support::little, ELFT::Is64Bits), - Object), - EF(Object, ec) {} + std::move(Object)), + EF(Data->getBuffer(), EC) {} template <class ELFT> -symbol_iterator ELFObjectFile<ELFT>::begin_symbols() const { - return symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this)); +basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const { + return basic_symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this)); } template <class ELFT> -symbol_iterator ELFObjectFile<ELFT>::end_symbols() const { - return symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this)); +basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const { + return basic_symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this)); } template <class ELFT> -symbol_iterator ELFObjectFile<ELFT>::begin_dynamic_symbols() const { +symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const { return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this)); } template <class ELFT> -symbol_iterator ELFObjectFile<ELFT>::end_dynamic_symbols() const { +symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const { return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this)); } template <class ELFT> -section_iterator ELFObjectFile<ELFT>::begin_sections() const { +section_iterator ELFObjectFile<ELFT>::section_begin() const { return section_iterator(SectionRef(toDRI(EF.begin_sections()), this)); } template <class ELFT> -section_iterator ELFObjectFile<ELFT>::end_sections() const { +section_iterator ELFObjectFile<ELFT>::section_end() const { return section_iterator(SectionRef(toDRI(EF.end_sections()), this)); } @@ -863,7 +838,7 @@ StringRef ELFObjectFile<ELFT>::getLoadName() const { } template <class ELFT> -library_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const { +library_iterator ELFObjectFile<ELFT>::needed_library_begin() const { Elf_Dyn_Iter DI = EF.begin_dynamic_table(); Elf_Dyn_Iter DE = EF.end_dynamic_table(); @@ -874,8 +849,8 @@ library_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const { } template <class ELFT> -error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data, - LibraryRef &Result) const { +std::error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data, + LibraryRef &Result) const { Elf_Dyn_Iter DI = toELFDynIter(Data); Elf_Dyn_Iter DE = EF.end_dynamic_table(); @@ -889,14 +864,14 @@ error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data, } template <class ELFT> -error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data, - StringRef &Res) const { +std::error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data, + StringRef &Res) const { Res = EF.getDynamicString(toELFDynIter(Data)->getVal()); return object_error::success; } template <class ELFT> -library_iterator ELFObjectFile<ELFT>::end_libraries_needed() const { +library_iterator ELFObjectFile<ELFT>::needed_library_end() const { return library_iterator(LibraryRef(toDRI(EF.end_dynamic_table()), this)); } @@ -942,6 +917,8 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const { return "ELF64-s390"; case ELF::EM_SPARCV9: return "ELF64-sparc"; + case ELF::EM_MIPS: + return "ELF64-mips"; default: return "ELF64-unknown"; } @@ -953,6 +930,7 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const { template <class ELFT> unsigned ELFObjectFile<ELFT>::getArch() const { + bool IsLittleEndian = ELFT::TargetEndianness == support::little; switch (EF.getHeader()->e_machine) { case ELF::EM_386: return Triple::x86; @@ -965,11 +943,16 @@ unsigned ELFObjectFile<ELFT>::getArch() const { case ELF::EM_HEXAGON: return Triple::hexagon; case ELF::EM_MIPS: - return (ELFT::TargetEndianness == support::little) ? Triple::mipsel - : Triple::mips; + switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) { + case ELF::ELFCLASS32: + return IsLittleEndian ? Triple::mipsel : Triple::mips; + case ELF::ELFCLASS64: + return IsLittleEndian ? Triple::mips64el : Triple::mips64; + default: + report_fatal_error("Invalid ELFCLASS!"); + } case ELF::EM_PPC64: - return (ELFT::TargetEndianness == support::little) ? Triple::ppc64le - : Triple::ppc64; + return IsLittleEndian ? Triple::ppc64le : Triple::ppc64; case ELF::EM_S390: return Triple::systemz; @@ -986,8 +969,8 @@ unsigned ELFObjectFile<ELFT>::getArch() const { /// FIXME: Maybe we should have a base ElfObjectFile that is not a template /// and make these member functions? -static inline error_code getELFRelocationAddend(const RelocationRef R, - int64_t &Addend) { +inline std::error_code getELFRelocationAddend(const RelocationRef R, + int64_t &Addend) { const ObjectFile *Obj = R.getObjectFile(); DataRefImpl DRI = R.getRawDataRefImpl(); // Little-endian 32-bit @@ -1009,12 +992,31 @@ static inline error_code getELFRelocationAddend(const RelocationRef R, llvm_unreachable("Object passed to getELFRelocationAddend() is not ELF"); } +inline std::pair<symbol_iterator, symbol_iterator> +getELFDynamicSymbolIterators(SymbolicFile *Obj) { + if (const ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(Obj)) + return std::make_pair(ELF->dynamic_symbol_begin(), + ELF->dynamic_symbol_end()); + if (const ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(Obj)) + return std::make_pair(ELF->dynamic_symbol_begin(), + ELF->dynamic_symbol_end()); + if (const ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(Obj)) + return std::make_pair(ELF->dynamic_symbol_begin(), + ELF->dynamic_symbol_end()); + if (const ELF64BEObjectFile *ELF = cast<ELF64BEObjectFile>(Obj)) + return std::make_pair(ELF->dynamic_symbol_begin(), + ELF->dynamic_symbol_end()); + + llvm_unreachable( + "Object passed to getELFDynamicSymbolIterators() is not ELF"); +} + /// This is a generic interface for retrieving GNU symbol version /// information from an ELFObjectFile. -static inline error_code GetELFSymbolVersion(const ObjectFile *Obj, - const SymbolRef &Sym, - StringRef &Version, - bool &IsDefault) { +inline std::error_code GetELFSymbolVersion(const ObjectFile *Obj, + const SymbolRef &Sym, + StringRef &Version, + bool &IsDefault) { // Little-endian 32-bit if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj)) return ELFObj->getSymbolVersion(Sym, Version, IsDefault); |