X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FObject%2FELFObjectFile.h;h=b2c22336b7ba03d406c23bda163566e4cfdc98e3;hb=9917d2e7add65704f708ad71f08ed99e1854468d;hp=1b6661f815333062fb4158895f49cb2d9ce4ea8e;hpb=0bd9423c276026b9b1bb35dd6c268d90a305e96e;p=oota-llvm.git diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 1b6661f8153..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) @@ -71,11 +84,6 @@ protected: 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; @@ -178,7 +186,7 @@ protected: bool isDyldELFObject; public: - ELFObjectFile(std::unique_ptr Object, std::error_code &EC); + ELFObjectFile(MemoryBufferRef Object, std::error_code &EC); const Elf_Sym *getSymbol(DataRefImpl Symb) const; @@ -191,12 +199,10 @@ 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; - - std::error_code getRelocationAddend(DataRefImpl Rel, int64_t &Res) const; + std::error_code getRelocationAddend(DataRefImpl Rel, + int64_t &Res) const override; std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, - bool &IsDefault) const; + bool &IsDefault) const override; uint8_t getBytesInAddress() const override; StringRef getFileFormatName() const override; @@ -215,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 @@ -786,13 +797,13 @@ ELFObjectFile::getRela(DataRefImpl Rela) const { } template -ELFObjectFile::ELFObjectFile(std::unique_ptr Object, - std::error_code &EC) - : ObjectFile(getELFType(static_cast(ELFT::TargetEndianness) == - support::little, - ELFT::Is64Bits), - std::move(Object)), - EF(Data->getBuffer(), 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 { @@ -837,44 +848,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 -std::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 -std::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; @@ -967,73 +940,34 @@ unsigned ELFObjectFile::getArch() const { } } -/// FIXME: Maybe we should have a base ElfObjectFile that is not a template -/// and make these member functions? +template +std::pair +ELFObjectFile::getELFDynamicSymbolIterators() const { + return std::make_pair(dynamic_symbol_begin(), dynamic_symbol_end()); +} + +template bool ELFObjectFile::isRelocatableObject() const { + return EF.getHeader()->e_type == ELF::ET_REL; +} + inline std::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); - - // Big-endian 64-bit - if (const ELF64BEObjectFile *ELFObj = dyn_cast(Obj)) - return ELFObj->getRelocationAddend(DRI, Addend); - - llvm_unreachable("Object passed to getELFRelocationAddend() is not ELF"); + 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"); + return cast(Obj)->getELFDynamicSymbolIterators(); } -/// This is a generic interface for retrieving GNU symbol version -/// information from an ELFObjectFile. 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(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"); + return cast(Obj) + ->getSymbolVersion(Sym, Version, IsDefault); } } }