X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FObject%2FELFObjectFile.h;h=e7eba976fd4f2820a10e6f420f5085b8178e3db0;hb=f23883936ce24b16df2ee86559f6d24f51faecb6;hp=2592df2c5069b03e2363b0876b1fd8b8381b2ebd;hpb=da7ea68f0d5b6ca3e187ee463864c36a30a238f0;p=oota-llvm.git diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 2592df2c506..e7eba976fd4 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,26 @@ 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; + + virtual uint64_t getSectionFlags(SectionRef Sec) const = 0; + virtual uint32_t getSectionType(SectionRef Sec) const = 0; + + static inline bool classof(const Binary *v) { return v->isELF(); } +}; + +template class ELFObjectFile : public ELFObjectFileBase { public: LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) @@ -57,51 +75,51 @@ protected: ELFFile EF; void moveSymbolNext(DataRefImpl &Symb) const override; - error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const override; - error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; - error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const override; - error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) 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; - error_code getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Res) const override; - error_code getSymbolSection(DataRefImpl Symb, - section_iterator &Res) const override; - - error_code getLibraryNext(DataRefImpl Data, - LibraryRef &Result) const override; - error_code getLibraryPath(DataRefImpl Data, StringRef &Res) 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; - error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override; - error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const override; - error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override; - error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override; - error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const override; - error_code isSectionText(DataRefImpl Sec, bool &Res) const override; - error_code isSectionData(DataRefImpl Sec, bool &Res) const override; - error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override; - error_code isSectionRequiredForExecution(DataRefImpl Sec, - bool &Res) const override; - error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override; - error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override; - error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const override; - error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, - bool &Result) const override; + std::error_code getSectionName(DataRefImpl Sec, + StringRef &Res) const override; + uint64_t getSectionAddress(DataRefImpl Sec) const override; + uint64_t getSectionSize(DataRefImpl Sec) const override; + std::error_code getSectionContents(DataRefImpl Sec, + StringRef &Res) const override; + uint64_t getSectionAlignment(DataRefImpl Sec) const override; + bool isSectionText(DataRefImpl Sec) const override; + bool isSectionData(DataRefImpl Sec) const override; + bool isSectionBSS(DataRefImpl Sec) const override; + bool isSectionVirtual(DataRefImpl Sec) const override; + bool sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; - bool section_rel_empty(DataRefImpl Sec) const override; section_iterator getRelocatedSection(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; - error_code getRelocationAddress(DataRefImpl Rel, - uint64_t &Res) const override; - error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) 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; - error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override; - error_code getRelocationTypeName(DataRefImpl Rel, - SmallVectorImpl &Result) const override; - error_code getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl &Result) 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; @@ -159,13 +177,27 @@ protected: return DRI; } + bool isExportedToOtherDSO(const Elf_Sym *ESym) const { + unsigned char Binding = ESym->getBinding(); + unsigned char Visibility = ESym->getVisibility(); + + // A symbol is exported if its binding is either GLOBAL or WEAK, and its + // visibility is either DEFAULT or PROTECTED. All other symbols are not + // exported. + if ((Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK) && + (Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED)) + return true; + + return false; + } + // This flag is used for classof, to distinguish ELFObjectFile from // its subclass. If more subclasses will be created, this flag will // have to become an enum. 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; @@ -178,18 +210,23 @@ public: section_iterator section_begin() const override; section_iterator section_end() const override; - 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 override; + std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, + bool &IsDefault) const override; + uint64_t getSectionFlags(SectionRef Sec) const override; + uint32_t getSectionType(SectionRef Sec) const override; uint8_t getBytesInAddress() const override; StringRef getFileFormatName() const override; unsigned getArch() const override; - StringRef getLoadName() const override; + StringRef getLoadName() const; + + std::error_code getPlatformFlags(unsigned &Result) const override { + Result = EF.getHeader()->e_flags; + return object_error::success; + } const ELFFile *getELFFile() const { return &EF; } @@ -198,6 +235,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 @@ -213,8 +255,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(); @@ -223,9 +265,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 = @@ -237,8 +279,20 @@ error_code ELFObjectFile::getSymbolVersion(SymbolRef SymRef, } template -error_code ELFObjectFile::getSymbolAddress(DataRefImpl Symb, - uint64_t &Result) const { +uint64_t ELFObjectFile::getSectionFlags(SectionRef Sec) const { + DataRefImpl DRI = Sec.getRawDataRefImpl(); + return toELFShdrIter(DRI)->sh_flags; +} + +template +uint32_t ELFObjectFile::getSectionType(SectionRef Sec) const { + DataRefImpl DRI = Sec.getRawDataRefImpl(); + return toELFShdrIter(DRI)->sh_type; +} + +template +std::error_code ELFObjectFile::getSymbolAddress(DataRefImpl Symb, + uint64_t &Result) const { const Elf_Sym *ESym = getSymbol(Symb); switch (EF.getSymbolTableIndex(ESym)) { case ELF::SHN_COMMON: @@ -255,19 +309,23 @@ error_code ELFObjectFile::getSymbolAddress(DataRefImpl Symb, const Elf_Ehdr *Header = EF.getHeader(); Result = ESym->st_value; - // Clear the ARM/Thumb indicator flag. - if (Header->e_machine == ELF::EM_ARM && ESym->getType() == ELF::STT_FUNC) + // Clear the ARM/Thumb or microMIPS indicator flag. + if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) && + ESym->getType() == ELF::STT_FUNC) Result &= ~1; - if (Header->e_type == ELF::ET_REL) - Result += EF.getSection(ESym)->sh_addr; + if (Header->e_type == ELF::ET_REL) { + const typename ELFFile::Elf_Shdr * Section = EF.getSection(ESym); + if (Section != nullptr) + Result += Section->sh_addr; + } 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; @@ -277,15 +335,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()) { @@ -340,12 +406,16 @@ uint32_t ELFObjectFile::getSymbolFlags(DataRefImpl Symb) const { EF.getSymbolTableIndex(ESym) == ELF::SHN_COMMON) Result |= SymbolRef::SF_Common; + if (isExportedToOtherDSO(ESym)) + Result |= SymbolRef::SF_Exported; + return Result; } 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) @@ -364,8 +434,8 @@ void ELFObjectFile::moveSectionNext(DataRefImpl &Sec) const { } 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(); @@ -374,100 +444,62 @@ error_code ELFObjectFile::getSectionName(DataRefImpl Sec, } template -error_code ELFObjectFile::getSectionAddress(DataRefImpl Sec, - uint64_t &Result) const { - Result = toELFShdrIter(Sec)->sh_addr; - return object_error::success; +uint64_t ELFObjectFile::getSectionAddress(DataRefImpl Sec) const { + return toELFShdrIter(Sec)->sh_addr; } template -error_code ELFObjectFile::getSectionSize(DataRefImpl Sec, - uint64_t &Result) const { - Result = toELFShdrIter(Sec)->sh_size; - return object_error::success; +uint64_t ELFObjectFile::getSectionSize(DataRefImpl Sec) const { + return toELFShdrIter(Sec)->sh_size; } 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 { - Result = toELFShdrIter(Sec)->sh_addralign; - return object_error::success; +uint64_t ELFObjectFile::getSectionAlignment(DataRefImpl Sec) const { + return toELFShdrIter(Sec)->sh_addralign; } template -error_code ELFObjectFile::isSectionText(DataRefImpl Sec, - bool &Result) const { - Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR; - return object_error::success; +bool ELFObjectFile::isSectionText(DataRefImpl Sec) const { + return toELFShdrIter(Sec)->sh_flags & ELF::SHF_EXECINSTR; } template -error_code ELFObjectFile::isSectionData(DataRefImpl Sec, - bool &Result) const { +bool ELFObjectFile::isSectionData(DataRefImpl Sec) const { Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); - Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && - EShdr->sh_type == ELF::SHT_PROGBITS; - return object_error::success; + return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && + EShdr->sh_type == ELF::SHT_PROGBITS; } template -error_code ELFObjectFile::isSectionBSS(DataRefImpl Sec, - bool &Result) const { +bool ELFObjectFile::isSectionBSS(DataRefImpl Sec) const { Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); - Result = EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && - EShdr->sh_type == ELF::SHT_NOBITS; - return object_error::success; -} - -template -error_code -ELFObjectFile::isSectionRequiredForExecution(DataRefImpl Sec, - bool &Result) const { - Result = toELFShdrIter(Sec)->sh_flags & ELF::SHF_ALLOC; - return object_error::success; -} - -template -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 { - Result = toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS; - return object_error::success; + return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && + EShdr->sh_type == ELF::SHT_NOBITS; } template -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; +bool ELFObjectFile::isSectionVirtual(DataRefImpl Sec) const { + return toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS; } template -error_code ELFObjectFile::sectionContainsSymbol(DataRefImpl Sec, - DataRefImpl Symb, - bool &Result) const { +bool ELFObjectFile::sectionContainsSymbol(DataRefImpl Sec, + DataRefImpl Symb) const { Elf_Sym_Iter ESym = toELFSymIter(Symb); uintX_t Index = ESym->st_shndx; bool Reserved = Index >= ELF::SHN_LORESERVE && Index <= ELF::SHN_HIRESERVE; - Result = !Reserved && (&*toELFShdrIter(Sec) == EF.getSection(ESym->st_shndx)); - return object_error::success; + return !Reserved && (&*toELFShdrIter(Sec) == EF.getSection(ESym->st_shndx)); } template @@ -495,12 +527,6 @@ ELFObjectFile::section_rel_end(DataRefImpl Sec) const { return relocation_iterator(RelocationRef(RelData, this)); } -template -bool ELFObjectFile::section_rel_empty(DataRefImpl Sec) const { - const Elf_Shdr *S = reinterpret_cast(Sec.p); - return S->sh_size == 0; -} - template section_iterator ELFObjectFile::getRelocatedSection(DataRefImpl Sec) const { @@ -560,18 +586,27 @@ ELFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { } template -error_code ELFObjectFile::getRelocationAddress(DataRefImpl Rel, - uint64_t &Result) const { - assert((EF.getHeader()->e_type == ELF::ET_EXEC || - EF.getHeader()->e_type == ELF::ET_DYN) && - "Only executable and shared objects files have relocation addresses"); - 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); @@ -592,8 +627,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: @@ -616,7 +651,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; @@ -638,8 +673,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: @@ -656,7 +692,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; @@ -722,6 +758,7 @@ error_code ELFObjectFile::getRelocationValueString( Result.append(fmtbuf.begin(), fmtbuf.end()); break; } + case ELF::EM_386: case ELF::EM_ARM: case ELF::EM_HEXAGON: case ELF::EM_MIPS: @@ -754,13 +791,13 @@ 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 basic_symbol_iterator ELFObjectFile::symbol_begin_impl() const { @@ -805,44 +842,6 @@ StringRef ELFObjectFile::getLoadName() const { return ""; } -template -library_iterator ELFObjectFile::needed_library_begin() 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::needed_library_end() const { - return library_iterator(LibraryRef(toDRI(EF.end_dynamic_table()), this)); -} - template uint8_t ELFObjectFile::getBytesInAddress() const { return ELFT::Is64Bits ? 8 : 4; @@ -850,6 +849,7 @@ uint8_t ELFObjectFile::getBytesInAddress() const { template StringRef ELFObjectFile::getFileFormatName() const { + bool IsLittleEndian = ELFT::TargetEndianness == support::little; switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) { case ELF::ELFCLASS32: switch (EF.getHeader()->e_machine) { @@ -858,7 +858,7 @@ StringRef ELFObjectFile::getFileFormatName() const { case ELF::EM_X86_64: return "ELF32-x86-64"; case ELF::EM_ARM: - return "ELF32-arm"; + return (IsLittleEndian ? "ELF32-arm-little" : "ELF32-arm-big"); case ELF::EM_HEXAGON: return "ELF32-hexagon"; case ELF::EM_MIPS: @@ -878,7 +878,7 @@ StringRef ELFObjectFile::getFileFormatName() const { case ELF::EM_X86_64: return "ELF64-x86-64"; case ELF::EM_AARCH64: - return "ELF64-aarch64"; + return (IsLittleEndian ? "ELF64-aarch64-little" : "ELF64-aarch64-big"); case ELF::EM_PPC64: return "ELF64-ppc64"; case ELF::EM_S390: @@ -898,6 +898,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; @@ -910,11 +911,18 @@ 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_PPC: + return Triple::ppc; 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; @@ -929,72 +937,34 @@ unsigned ELFObjectFile::getArch() const { } } -/// FIXME: Maybe we should have a base ElfObjectFile that is not a template -/// and make these member functions? -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); - - // Little-endian 64-bit - if (const ELF64LEObjectFile *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()); +} - // Big-endian 64-bit - if (const ELF64BEObjectFile *ELFObj = dyn_cast(Obj)) - return ELFObj->getRelocationAddend(DRI, Addend); +template bool ELFObjectFile::isRelocatableObject() const { + return EF.getHeader()->e_type == ELF::ET_REL; +} - llvm_unreachable("Object passed to getELFRelocationAddend() is not ELF"); +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); } inline std::pair -getELFDynamicSymbolIterators(SymbolicFile *Obj) { - if (const ELF32LEObjectFile *ELF = dyn_cast(Obj)) - return std::make_pair(ELF->dynamic_symbol_begin(), - ELF->dynamic_symbol_end()); - if (const ELF64LEObjectFile *ELF = dyn_cast(Obj)) - return std::make_pair(ELF->dynamic_symbol_begin(), - ELF->dynamic_symbol_end()); - if (const ELF32BEObjectFile *ELF = dyn_cast(Obj)) - return std::make_pair(ELF->dynamic_symbol_begin(), - ELF->dynamic_symbol_end()); - if (const ELF64BEObjectFile *ELF = cast(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. -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"); +getELFDynamicSymbolIterators(const SymbolicFile *Obj) { + return cast(Obj)->getELFDynamicSymbolIterators(); +} + +inline std::error_code GetELFSymbolVersion(const ObjectFile *Obj, + const SymbolRef &Sym, + StringRef &Version, + bool &IsDefault) { + return cast(Obj) + ->getSymbolVersion(Sym, Version, IsDefault); } } }