X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FObject%2FELFObjectFile.h;h=b2c22336b7ba03d406c23bda163566e4cfdc98e3;hb=9917d2e7add65704f708ad71f08ed99e1854468d;hp=fe63277830b476410940e3e361b799a7238f093f;hpb=19a4033c68bc2e2f57695b05242ad0f38c468a22;p=oota-llvm.git diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index fe63277830b..b2c22336b7b 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_OBJECT_ELF_OBJECT_FILE_H -#define LLVM_OBJECT_ELF_OBJECT_FILE_H +#ifndef LLVM_OBJECT_ELFOBJECTFILE_H +#define LLVM_OBJECT_ELFOBJECTFILE_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" @@ -35,8 +35,21 @@ namespace llvm { namespace object { -template -class ELFObjectFile : public ObjectFile { +class ELFObjectFileBase : public ObjectFile { +protected: + ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source); + +public: + virtual std::error_code getRelocationAddend(DataRefImpl Rel, + int64_t &Res) const = 0; + virtual std::pair + getELFDynamicSymbolIterators() const = 0; + + virtual std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, + bool &IsDefault) const = 0; +}; + +template class ELFObjectFile : public ELFObjectFileBase { public: LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) @@ -44,6 +57,7 @@ public: typedef typename ELFFile::Elf_Sym Elf_Sym; typedef typename ELFFile::Elf_Shdr Elf_Shdr; + typedef typename ELFFile::Elf_Ehdr Elf_Ehdr; typedef typename ELFFile::Elf_Rel Elf_Rel; typedef typename ELFFile::Elf_Rela Elf_Rela; typedef typename ELFFile::Elf_Dyn Elf_Dyn; @@ -55,64 +69,60 @@ public: protected: ELFFile EF; - void moveSymbolNext(DataRefImpl &Symb) const LLVM_OVERRIDE; - error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const - LLVM_OVERRIDE; - error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const - LLVM_OVERRIDE; - error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const - LLVM_OVERRIDE; - error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const - LLVM_OVERRIDE; - error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const LLVM_OVERRIDE; - uint32_t getSymbolFlags(DataRefImpl Symb) const LLVM_OVERRIDE; - error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const - LLVM_OVERRIDE; - error_code getSymbolSection(DataRefImpl Symb, section_iterator &Res) const - LLVM_OVERRIDE; - error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; - - error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const - LLVM_OVERRIDE; - error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const - LLVM_OVERRIDE; - - void moveSectionNext(DataRefImpl &Sec) const LLVM_OVERRIDE; - error_code getSectionName(DataRefImpl Sec, StringRef &Res) const - LLVM_OVERRIDE; - error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const - LLVM_OVERRIDE; - error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const LLVM_OVERRIDE; - error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; - error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const - LLVM_OVERRIDE; - error_code isSectionText(DataRefImpl Sec, bool &Res) const LLVM_OVERRIDE; - error_code isSectionData(DataRefImpl Sec, bool &Res) const; - error_code isSectionBSS(DataRefImpl Sec, bool &Res) const LLVM_OVERRIDE; - error_code isSectionRequiredForExecution(DataRefImpl Sec, bool &Res) const - LLVM_OVERRIDE; - error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; - error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const LLVM_OVERRIDE; - error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const; - error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, - bool &Result) const LLVM_OVERRIDE; - relocation_iterator section_rel_begin(DataRefImpl Sec) const; - relocation_iterator section_rel_end(DataRefImpl Sec) const LLVM_OVERRIDE; - section_iterator getRelocatedSection(DataRefImpl Sec) const LLVM_OVERRIDE; - - void moveRelocationNext(DataRefImpl &Rel) const LLVM_OVERRIDE; - error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const - LLVM_OVERRIDE; - error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const - LLVM_OVERRIDE; - symbol_iterator getRelocationSymbol(DataRefImpl Rel) const LLVM_OVERRIDE; - error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const; - error_code getRelocationTypeName(DataRefImpl Rel, - SmallVectorImpl &Result) const - LLVM_OVERRIDE; - error_code getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl &Result) const - LLVM_OVERRIDE; + 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; + + 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 &Result) const override; + std::error_code + getRelocationValueString(DataRefImpl Rel, + SmallVectorImpl &Result) const override; uint64_t getROffset(DataRefImpl Rel) const; StringRef getRelocationTypeName(uint32_t Type) const; @@ -176,31 +186,33 @@ protected: bool isDyldELFObject; public: - ELFObjectFile(MemoryBuffer *Object, error_code &EC, bool BufferOwned = true); + ELFObjectFile(MemoryBufferRef Object, std::error_code &EC); const Elf_Sym *getSymbol(DataRefImpl Symb) const; - symbol_iterator begin_symbols() const LLVM_OVERRIDE; - symbol_iterator end_symbols() const LLVM_OVERRIDE; - - symbol_iterator begin_dynamic_symbols() const; - symbol_iterator end_dynamic_symbols() const; + basic_symbol_iterator symbol_begin_impl() const override; + basic_symbol_iterator symbol_end_impl() const override; - section_iterator begin_sections() const LLVM_OVERRIDE; - section_iterator end_sections() const LLVM_OVERRIDE; + symbol_iterator dynamic_symbol_begin() const; + symbol_iterator dynamic_symbol_end() const; - library_iterator begin_libraries_needed() const LLVM_OVERRIDE; - library_iterator end_libraries_needed() const LLVM_OVERRIDE; + section_iterator section_begin() const override; + section_iterator section_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 override; + std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, + bool &IsDefault) const override; + uint8_t getBytesInAddress() const override; + StringRef getFileFormatName() const override; + unsigned getArch() const override; + StringRef getLoadName() const; - uint8_t getBytesInAddress() const LLVM_OVERRIDE; - StringRef getFileFormatName() const LLVM_OVERRIDE; - unsigned getArch() const LLVM_OVERRIDE; - StringRef getLoadName() const LLVM_OVERRIDE; + std::error_code getPlatformFlags(unsigned &Result) const override { + Result = EF.getHeader()->e_flags; + return object_error::success; + } const ELFFile *getELFFile() const { return &EF; } @@ -209,6 +221,11 @@ public: return v->getType() == getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits); } + + std::pair + getELFDynamicSymbolIterators() const override; + + bool isRelocatableObject() const override; }; // Use an alignment of 2 for the typedefs since that is the worst case for @@ -224,8 +241,8 @@ void ELFObjectFile::moveSymbolNext(DataRefImpl &Symb) const { } template -error_code ELFObjectFile::getSymbolName(DataRefImpl Symb, - StringRef &Result) const { +std::error_code ELFObjectFile::getSymbolName(DataRefImpl Symb, + StringRef &Result) const { ErrorOr Name = EF.getSymbolName(toELFSymIter(Symb)); if (!Name) return Name.getError(); @@ -234,9 +251,9 @@ error_code ELFObjectFile::getSymbolName(DataRefImpl Symb, } template -error_code ELFObjectFile::getSymbolVersion(SymbolRef SymRef, - StringRef &Version, - bool &IsDefault) const { +std::error_code ELFObjectFile::getSymbolVersion(SymbolRef SymRef, + StringRef &Version, + bool &IsDefault) const { DataRefImpl Symb = SymRef.getRawDataRefImpl(); const Elf_Sym *symb = getSymbol(Symb); ErrorOr Ver = @@ -248,13 +265,11 @@ error_code ELFObjectFile::getSymbolVersion(SymbolRef SymRef, } template -error_code ELFObjectFile::getSymbolFileOffset(DataRefImpl Symb, - uint64_t &Result) const { +std::error_code ELFObjectFile::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; @@ -262,76 +277,25 @@ error_code ELFObjectFile::getSymbolFileOffset(DataRefImpl Symb, Result = ESym->st_value; return object_error::success; default: - ESec = EF.getSection(ESym); - } - - 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; + break; } -} -template -error_code ELFObjectFile::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); - } + const Elf_Ehdr *Header = EF.getHeader(); + Result = ESym->st_value; - 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: - case ELF::STT_TLS: - 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 -error_code ELFObjectFile::getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const { +std::error_code ELFObjectFile::getSymbolAlignment(DataRefImpl Symb, + uint32_t &Res) const { Elf_Sym_Iter Sym = toELFSymIter(Symb); if (Sym->st_shndx == ELF::SHN_COMMON) Res = Sym->st_value; @@ -341,15 +305,23 @@ error_code ELFObjectFile::getSymbolAlignment(DataRefImpl Symb, } template -error_code ELFObjectFile::getSymbolSize(DataRefImpl Symb, - uint64_t &Result) const { +std::error_code ELFObjectFile::getSymbolSize(DataRefImpl Symb, + uint64_t &Result) const { Result = toELFSymIter(Symb)->st_size; return object_error::success; } template -error_code ELFObjectFile::getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Result) const { +std::error_code ELFObjectFile::getSymbolOther(DataRefImpl Symb, + uint8_t &Result) const { + Result = toELFSymIter(Symb)->st_other; + return object_error::success; +} + +template +std::error_code +ELFObjectFile::getSymbolType(DataRefImpl Symb, + SymbolRef::Type &Result) const { const Elf_Sym *ESym = getSymbol(Symb); switch (ESym->getType()) { @@ -408,12 +380,13 @@ uint32_t ELFObjectFile::getSymbolFlags(DataRefImpl Symb) const { } template -error_code ELFObjectFile::getSymbolSection(DataRefImpl Symb, - section_iterator &Res) const { +std::error_code +ELFObjectFile::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(ESec); @@ -422,22 +395,14 @@ error_code ELFObjectFile::getSymbolSection(DataRefImpl Symb, return object_error::success; } -template -error_code ELFObjectFile::getSymbolValue(DataRefImpl Symb, - uint64_t &Val) const { - const Elf_Sym *ESym = getSymbol(Symb); - Val = ESym->st_value; - return object_error::success; -} - template void ELFObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec = toDRI(++toELFShdrIter(Sec)); } template -error_code ELFObjectFile::getSectionName(DataRefImpl Sec, - StringRef &Result) const { +std::error_code ELFObjectFile::getSectionName(DataRefImpl Sec, + StringRef &Result) const { ErrorOr Name = EF.getSectionName(&*toELFShdrIter(Sec)); if (!Name) return Name.getError(); @@ -446,44 +411,46 @@ error_code ELFObjectFile::getSectionName(DataRefImpl Sec, } template -error_code ELFObjectFile::getSectionAddress(DataRefImpl Sec, - uint64_t &Result) const { +std::error_code ELFObjectFile::getSectionAddress(DataRefImpl Sec, + uint64_t &Result) const { Result = toELFShdrIter(Sec)->sh_addr; return object_error::success; } template -error_code ELFObjectFile::getSectionSize(DataRefImpl Sec, - uint64_t &Result) const { +std::error_code ELFObjectFile::getSectionSize(DataRefImpl Sec, + uint64_t &Result) const { Result = toELFShdrIter(Sec)->sh_size; return object_error::success; } template -error_code ELFObjectFile::getSectionContents(DataRefImpl Sec, - StringRef &Result) const { +std::error_code +ELFObjectFile::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 -error_code ELFObjectFile::getSectionAlignment(DataRefImpl Sec, - uint64_t &Result) const { +std::error_code +ELFObjectFile::getSectionAlignment(DataRefImpl Sec, + uint64_t &Result) const { Result = toELFShdrIter(Sec)->sh_addralign; return object_error::success; } template -error_code ELFObjectFile::isSectionText(DataRefImpl Sec, - bool &Result) const { +std::error_code ELFObjectFile::isSectionText(DataRefImpl Sec, + bool &Result) const { Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR; return object_error::success; } template -error_code ELFObjectFile::isSectionData(DataRefImpl Sec, - bool &Result) const { +std::error_code ELFObjectFile::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; @@ -491,8 +458,8 @@ error_code ELFObjectFile::isSectionData(DataRefImpl Sec, } template -error_code ELFObjectFile::isSectionBSS(DataRefImpl Sec, - bool &Result) const { +std::error_code ELFObjectFile::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; @@ -500,7 +467,7 @@ error_code ELFObjectFile::isSectionBSS(DataRefImpl Sec, } template -error_code +std::error_code ELFObjectFile::isSectionRequiredForExecution(DataRefImpl Sec, bool &Result) const { Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_ALLOC; @@ -508,31 +475,31 @@ ELFObjectFile::isSectionRequiredForExecution(DataRefImpl Sec, } template -error_code ELFObjectFile::isSectionVirtual(DataRefImpl Sec, - bool &Result) const { +std::error_code ELFObjectFile::isSectionVirtual(DataRefImpl Sec, + bool &Result) const { Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS; return object_error::success; } template -error_code ELFObjectFile::isSectionZeroInit(DataRefImpl Sec, - bool &Result) const { +std::error_code ELFObjectFile::isSectionZeroInit(DataRefImpl Sec, + bool &Result) const { Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS; return object_error::success; } template -error_code ELFObjectFile::isSectionReadOnlyData(DataRefImpl Sec, - bool &Result) const { +std::error_code ELFObjectFile::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 -error_code ELFObjectFile::sectionContainsSymbol(DataRefImpl Sec, - DataRefImpl Symb, - bool &Result) const { +std::error_code ELFObjectFile::sectionContainsSymbol(DataRefImpl Sec, + DataRefImpl Symb, + bool &Result) const { Elf_Sym_Iter ESym = toELFSymIter(Symb); uintX_t Index = ESym->st_shndx; @@ -571,12 +538,12 @@ template section_iterator ELFObjectFile::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)); @@ -606,7 +573,7 @@ ELFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { } } if (!symbolIdx) - return end_symbols(); + return symbol_end(); const Elf_Shdr *SymSec = EF.getSection(sec->sh_link); @@ -626,15 +593,29 @@ ELFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { } template -error_code ELFObjectFile::getRelocationAddress(DataRefImpl Rel, - uint64_t &Result) const { - Result = getROffset(Rel); +std::error_code +ELFObjectFile::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 -error_code ELFObjectFile::getRelocationOffset(DataRefImpl Rel, - uint64_t &Result) const { +std::error_code +ELFObjectFile::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; } @@ -653,8 +634,8 @@ uint64_t ELFObjectFile::getROffset(DataRefImpl Rel) const { } template -error_code ELFObjectFile::getRelocationType(DataRefImpl Rel, - uint64_t &Result) const { +std::error_code ELFObjectFile::getRelocationType(DataRefImpl Rel, + uint64_t &Result) const { const Elf_Shdr *sec = getRelSection(Rel); switch (sec->sh_type) { default: @@ -677,7 +658,7 @@ StringRef ELFObjectFile::getRelocationTypeName(uint32_t Type) const { } template -error_code ELFObjectFile::getRelocationTypeName( +std::error_code ELFObjectFile::getRelocationTypeName( DataRefImpl Rel, SmallVectorImpl &Result) const { const Elf_Shdr *sec = getRelSection(Rel); uint32_t type; @@ -699,8 +680,9 @@ error_code ELFObjectFile::getRelocationTypeName( } template -error_code ELFObjectFile::getRelocationAddend(DataRefImpl Rel, - int64_t &Result) const { +std::error_code +ELFObjectFile::getRelocationAddend(DataRefImpl Rel, + int64_t &Result) const { const Elf_Shdr *sec = getRelSection(Rel); switch (sec->sh_type) { default: @@ -717,7 +699,7 @@ error_code ELFObjectFile::getRelocationAddend(DataRefImpl Rel, } template -error_code ELFObjectFile::getRelocationValueString( +std::error_code ELFObjectFile::getRelocationValueString( DataRefImpl Rel, SmallVectorImpl &Result) const { const Elf_Shdr *sec = getRelSection(Rel); uint8_t type; @@ -815,41 +797,41 @@ ELFObjectFile::getRela(DataRefImpl Rela) const { } template -ELFObjectFile::ELFObjectFile(MemoryBuffer *Object, error_code &ec, - bool BufferOwned) - : ObjectFile(getELFType(static_cast(ELFT::TargetEndianness) == - support::little, - ELFT::Is64Bits), - Object, BufferOwned), - EF(Object, ec) {} +ELFObjectFile::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC) + : ELFObjectFileBase( + getELFType(static_cast(ELFT::TargetEndianness) == + support::little, + ELFT::Is64Bits), + Object), + EF(Data.getBuffer(), EC) {} template -symbol_iterator ELFObjectFile::begin_symbols() const { - return symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this)); +basic_symbol_iterator ELFObjectFile::symbol_begin_impl() const { + return basic_symbol_iterator(SymbolRef(toDRI(EF.begin_symbols()), this)); } template -symbol_iterator ELFObjectFile::end_symbols() const { - return symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this)); +basic_symbol_iterator ELFObjectFile::symbol_end_impl() const { + return basic_symbol_iterator(SymbolRef(toDRI(EF.end_symbols()), this)); } template -symbol_iterator ELFObjectFile::begin_dynamic_symbols() const { +symbol_iterator ELFObjectFile::dynamic_symbol_begin() const { return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this)); } template -symbol_iterator ELFObjectFile::end_dynamic_symbols() const { +symbol_iterator ELFObjectFile::dynamic_symbol_end() const { return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this)); } template -section_iterator ELFObjectFile::begin_sections() const { +section_iterator ELFObjectFile::section_begin() const { return section_iterator(SectionRef(toDRI(EF.begin_sections()), this)); } template -section_iterator ELFObjectFile::end_sections() const { +section_iterator ELFObjectFile::section_end() const { return section_iterator(SectionRef(toDRI(EF.end_sections()), this)); } @@ -866,44 +848,6 @@ StringRef ELFObjectFile::getLoadName() const { return ""; } -template -library_iterator ELFObjectFile::begin_libraries_needed() const { - Elf_Dyn_Iter DI = EF.begin_dynamic_table(); - Elf_Dyn_Iter DE = EF.end_dynamic_table(); - - while (DI != DE && DI->getTag() != ELF::DT_SONAME) - ++DI; - - return library_iterator(LibraryRef(toDRI(DI), this)); -} - -template -error_code ELFObjectFile::getLibraryNext(DataRefImpl Data, - LibraryRef &Result) const { - Elf_Dyn_Iter DI = toELFDynIter(Data); - Elf_Dyn_Iter DE = EF.end_dynamic_table(); - - // Skip to the next DT_NEEDED entry. - do - ++DI; - while (DI != DE && DI->getTag() != ELF::DT_NEEDED); - - Result = LibraryRef(toDRI(DI), this); - return object_error::success; -} - -template -error_code ELFObjectFile::getLibraryPath(DataRefImpl Data, - StringRef &Res) const { - Res = EF.getDynamicString(toELFDynIter(Data)->getVal()); - return object_error::success; -} - -template -library_iterator ELFObjectFile::end_libraries_needed() const { - return library_iterator(LibraryRef(toDRI(EF.end_dynamic_table()), this)); -} - template uint8_t ELFObjectFile::getBytesInAddress() const { return ELFT::Is64Bits ? 8 : 4; @@ -946,6 +890,8 @@ StringRef ELFObjectFile::getFileFormatName() const { return "ELF64-s390"; case ELF::EM_SPARCV9: return "ELF64-sparc"; + case ELF::EM_MIPS: + return "ELF64-mips"; default: return "ELF64-unknown"; } @@ -957,6 +903,7 @@ StringRef ELFObjectFile::getFileFormatName() const { template unsigned ELFObjectFile::getArch() const { + bool IsLittleEndian = ELFT::TargetEndianness == support::little; switch (EF.getHeader()->e_machine) { case ELF::EM_386: return Triple::x86; @@ -969,11 +916,16 @@ unsigned ELFObjectFile::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; @@ -988,54 +940,34 @@ unsigned ELFObjectFile::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) { - const ObjectFile *Obj = R.getObjectFile(); - DataRefImpl DRI = R.getRawDataRefImpl(); - // Little-endian 32-bit - if (const ELF32LEObjectFile *ELFObj = dyn_cast(Obj)) - return ELFObj->getRelocationAddend(DRI, Addend); - - // Big-endian 32-bit - if (const ELF32BEObjectFile *ELFObj = dyn_cast(Obj)) - return ELFObj->getRelocationAddend(DRI, Addend); +template +std::pair +ELFObjectFile::getELFDynamicSymbolIterators() const { + return std::make_pair(dynamic_symbol_begin(), dynamic_symbol_end()); +} - // Little-endian 64-bit - if (const ELF64LEObjectFile *ELFObj = dyn_cast(Obj)) - return ELFObj->getRelocationAddend(DRI, Addend); +template bool ELFObjectFile::isRelocatableObject() const { + return EF.getHeader()->e_type == ELF::ET_REL; +} - // Big-endian 64-bit - if (const ELF64BEObjectFile *ELFObj = dyn_cast(Obj)) - return ELFObj->getRelocationAddend(DRI, Addend); +inline std::error_code getELFRelocationAddend(const RelocationRef R, + int64_t &Addend) { + const ObjectFile *Obj = R.getObjectFile(); + DataRefImpl DRI = R.getRawDataRefImpl(); + return cast(Obj)->getRelocationAddend(DRI, Addend); +} - llvm_unreachable("Object passed to getELFRelocationAddend() is not ELF"); +inline std::pair +getELFDynamicSymbolIterators(SymbolicFile *Obj) { + return cast(Obj)->getELFDynamicSymbolIterators(); } -/// 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) { - // Little-endian 32-bit - if (const ELF32LEObjectFile *ELFObj = dyn_cast(Obj)) - return ELFObj->getSymbolVersion(Sym, Version, IsDefault); - - // Big-endian 32-bit - if (const ELF32BEObjectFile *ELFObj = dyn_cast(Obj)) - return ELFObj->getSymbolVersion(Sym, Version, IsDefault); - - // Little-endian 64-bit - if (const ELF64LEObjectFile *ELFObj = dyn_cast(Obj)) - return ELFObj->getSymbolVersion(Sym, Version, IsDefault); - - // Big-endian 64-bit - if (const ELF64BEObjectFile *ELFObj = dyn_cast(Obj)) - return ELFObj->getSymbolVersion(Sym, Version, IsDefault); - - llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF"); +inline std::error_code GetELFSymbolVersion(const ObjectFile *Obj, + const SymbolRef &Sym, + StringRef &Version, + bool &IsDefault) { + return cast(Obj) + ->getSymbolVersion(Sym, Version, IsDefault); } } }