From db7cdc8eb06485bb36e6cac1105d40cc3930021a Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 17 Aug 2014 17:52:10 +0000 Subject: [PATCH] Add a non-templated ELFObjectFileBase class. Use it to implement some ELF only virtual interfaces instead of using error prone series of dyn_casts. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215838 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/ELFObjectFile.h | 101 ++++++++++++++---------------------- lib/Object/ELFObjectFile.cpp | 4 ++ 2 files changed, 42 insertions(+), 63 deletions(-) diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 977f9c3f39c..0ca4c7cb173 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -35,8 +35,21 @@ namespace llvm { namespace object { -template -class ELFObjectFile : public ObjectFile { +class ELFObjectFileBase : public ObjectFile { +protected: + ELFObjectFileBase(unsigned int Type, std::unique_ptr 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) @@ -186,9 +199,10 @@ public: section_iterator section_begin() const override; section_iterator section_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; @@ -207,6 +221,9 @@ public: return v->getType() == getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits); } + + std::pair + getELFDynamicSymbolIterators() const override; }; // Use an alignment of 2 for the typedefs since that is the worst case for @@ -780,10 +797,11 @@ 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)), + : ELFObjectFileBase( + getELFType(static_cast(ELFT::TargetEndianness) == + support::little, + ELFT::Is64Bits), + std::move(Object)), EF(Data->getBuffer(), EC) {} template @@ -921,73 +939,30 @@ 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()); +} + 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"); -} - -/// This is a generic interface for retrieving GNU symbol version -/// information from an ELFObjectFile. + return cast(Obj)->getELFDynamicSymbolIterators(); +} + 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); } } } diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index 199ea35d9e7..2e5e3c8836c 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -17,6 +17,10 @@ namespace llvm { using namespace object; +ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, + std::unique_ptr Source) + : ObjectFile(Type, std::move(Source)) {} + ErrorOr> ObjectFile::createELFObjectFile(std::unique_ptr &Obj) { std::pair Ident = -- 2.11.0