//===- lib/ReaderWriter/ELF/ReferenceKinds.h ------------------------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "llvm/ADT/DenseMap.h" #include "lld/Core/LLVM.h" #include "lld/Core/Reference.h" #include "lld/ReaderWriter/WriterELF.h" #include #include #include #ifndef LLD_READER_WRITER_ELF_REFERENCE_KINDS_H_ #define LLD_READER_WRITER_ELF_REFERENCE_KINDS_H_ namespace lld { namespace elf { /// /// The KindHandler class is the abstract interface to Reference::Kind /// values for ELF files. Particular Kind values (e.g. 3) has a different /// meaning for each architecture. /// TODO: Needs to be updated for ELF, stubs for now. /// class KindHandler { public: typedef Reference::Kind Kind; static std::unique_ptr makeHandler(uint16_t arch, llvm::support::endianness endian); virtual ~KindHandler(); virtual Kind stringToKind(StringRef str) = 0; virtual StringRef kindToString(Kind) = 0; virtual bool isCallSite(Kind) = 0; virtual bool isPointer(Kind) = 0; virtual bool isLazyImmediate(Kind) = 0; virtual bool isLazyTarget(Kind) = 0; virtual void applyFixup(int32_t reloc, uint64_t addend, uint8_t *location, uint64_t fixupAddress, uint64_t targetAddress) = 0; protected: KindHandler(); }; class HexagonKindHandler : public KindHandler { public: // Note: Reference::Kinds are a another representation of // relocation types, using negative values to represent architecture // independent reference type. // The positive values are the same ones defined in ELF.h and that // is what we are using. enum Kinds { none = llvm::ELF::R_HEX_NONE, invalid=255, // used to denote an error creating a Reference }; enum RelocationError { NoError, Overflow }; virtual ~HexagonKindHandler(); HexagonKindHandler(); virtual Kind stringToKind(StringRef str); virtual StringRef kindToString(Kind); virtual bool isCallSite(Kind); virtual bool isPointer(Kind); virtual bool isLazyImmediate(Kind); virtual bool isLazyTarget(Kind); virtual void applyFixup(int32_t reloc, uint64_t addend, uint8_t *location, uint64_t fixupAddress, uint64_t targetAddress); // A map is used here and in the other handlers but if performace overhead // becomes an issue this could be implemented as an array of function pointers. private: llvm::DenseMap > _fixupHandler; }; class X86KindHandler : public KindHandler { public: enum Kinds { invalid, // used to denote an error creating a Reference none, }; enum RelocationError { NoError, }; virtual ~X86KindHandler(); X86KindHandler(); virtual Kind stringToKind(StringRef str); virtual StringRef kindToString(Kind); virtual bool isCallSite(Kind); virtual bool isPointer(Kind); virtual bool isLazyImmediate(Kind); virtual bool isLazyTarget(Kind); virtual void applyFixup(int32_t reloc, uint64_t addend, uint8_t *location, uint64_t fixupAddress, uint64_t targetAddress); private: llvm::DenseMap > _fixupHandler; }; class PPCKindHandler : public KindHandler { public: // Note: Reference::Kinds are a another representation of // relocation types, using negative values to represent architecture // independent reference type. // The positive values are the same ones defined in ELF.h and that // is what we are using. enum Kinds { none = llvm::ELF::R_PPC_NONE, invalid=255, // used to denote an error creating a Reference }; enum RelocationError { NoError, Overflow }; virtual ~PPCKindHandler(); PPCKindHandler(llvm::support::endianness endian); virtual Kind stringToKind(StringRef str); virtual StringRef kindToString(Kind); virtual bool isCallSite(Kind); virtual bool isPointer(Kind); virtual bool isLazyImmediate(Kind); virtual bool isLazyTarget(Kind); virtual void applyFixup(int32_t reloc, uint64_t addend, uint8_t *location, uint64_t fixupAddress, uint64_t targetAddress); private: llvm::DenseMap > _fixupHandler; }; } // namespace elf } // namespace lld #endif // LLD_READER_WRITER_ELF_REFERENCE_KINDS_H_