diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-08-17 17:52:10 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-08-17 17:52:10 +0000 |
| commit | ab73774c4771a7e310d403934d0c961eb0ad213b (patch) | |
| tree | 742dea19aa38a7a7faf49106892a3d9ee2459ec9 | |
| parent | e45c74037051370faa1987ae385105b21f7463f3 (diff) | |
| download | bcm5719-llvm-ab73774c4771a7e310d403934d0c961eb0ad213b.tar.gz bcm5719-llvm-ab73774c4771a7e310d403934d0c961eb0ad213b.zip | |
Add a non-templated ELFObjectFileBase class.
Use it to implement some ELF only virtual interfaces instead of using error
prone series of dyn_casts.
llvm-svn: 215838
| -rw-r--r-- | llvm/include/llvm/Object/ELFObjectFile.h | 101 | ||||
| -rw-r--r-- | llvm/lib/Object/ELFObjectFile.cpp | 4 |
2 files changed, 42 insertions, 63 deletions
diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 977f9c3f39c..0ca4c7cb173 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -35,8 +35,21 @@ namespace llvm { namespace object { -template <class ELFT> -class ELFObjectFile : public ObjectFile { +class ELFObjectFileBase : public ObjectFile { +protected: + ELFObjectFileBase(unsigned int Type, std::unique_ptr<MemoryBuffer> Source); + +public: + virtual std::error_code getRelocationAddend(DataRefImpl Rel, + int64_t &Res) const = 0; + virtual std::pair<symbol_iterator, symbol_iterator> + getELFDynamicSymbolIterators() const = 0; + + virtual std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, + bool &IsDefault) const = 0; +}; + +template <class ELFT> 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<symbol_iterator, symbol_iterator> + getELFDynamicSymbolIterators() const override; }; // Use an alignment of 2 for the typedefs since that is the worst case for @@ -780,10 +797,11 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const { template <class ELFT> ELFObjectFile<ELFT>::ELFObjectFile(std::unique_ptr<MemoryBuffer> Object, std::error_code &EC) - : ObjectFile(getELFType(static_cast<endianness>(ELFT::TargetEndianness) == - support::little, - ELFT::Is64Bits), - std::move(Object)), + : ELFObjectFileBase( + getELFType(static_cast<endianness>(ELFT::TargetEndianness) == + support::little, + ELFT::Is64Bits), + std::move(Object)), EF(Data->getBuffer(), EC) {} template <class ELFT> @@ -921,73 +939,30 @@ unsigned ELFObjectFile<ELFT>::getArch() const { } } -/// FIXME: Maybe we should have a base ElfObjectFile that is not a template -/// and make these member functions? +template <class ELFT> +std::pair<symbol_iterator, symbol_iterator> +ELFObjectFile<ELFT>::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<ELF32LEObjectFile>(Obj)) - return ELFObj->getRelocationAddend(DRI, Addend); - - // Big-endian 32-bit - if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj)) - return ELFObj->getRelocationAddend(DRI, Addend); - - // Little-endian 64-bit - if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj)) - return ELFObj->getRelocationAddend(DRI, Addend); - - // Big-endian 64-bit - if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj)) - return ELFObj->getRelocationAddend(DRI, Addend); - - llvm_unreachable("Object passed to getELFRelocationAddend() is not ELF"); + return cast<ELFObjectFileBase>(Obj)->getRelocationAddend(DRI, Addend); } 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. + return cast<ELFObjectFileBase>(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<ELF32LEObjectFile>(Obj)) - return ELFObj->getSymbolVersion(Sym, Version, IsDefault); - - // Big-endian 32-bit - if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj)) - return ELFObj->getSymbolVersion(Sym, Version, IsDefault); - - // Little-endian 64-bit - if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj)) - return ELFObj->getSymbolVersion(Sym, Version, IsDefault); - - // Big-endian 64-bit - if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj)) - return ELFObj->getSymbolVersion(Sym, Version, IsDefault); - - llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF"); + return cast<ELFObjectFileBase>(Obj) + ->getSymbolVersion(Sym, Version, IsDefault); } } } diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp index 199ea35d9e7..2e5e3c8836c 100644 --- a/llvm/lib/Object/ELFObjectFile.cpp +++ b/llvm/lib/Object/ELFObjectFile.cpp @@ -17,6 +17,10 @@ namespace llvm { using namespace object; +ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, + std::unique_ptr<MemoryBuffer> Source) + : ObjectFile(Type, std::move(Source)) {} + ErrorOr<std::unique_ptr<ObjectFile>> ObjectFile::createELFObjectFile(std::unique_ptr<MemoryBuffer> &Obj) { std::pair<unsigned char, unsigned char> Ident = |

