//===- Relocation.h ----------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MCLD_FRAGMENT_RELOCATION_H #define MCLD_FRAGMENT_RELOCATION_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif #include <mcld/Config/Config.h> #include <mcld/Fragment/FragmentRef.h> #include <mcld/Support/GCFactoryListTraits.h> #include <llvm/ADT/ilist_node.h> #include <llvm/Support/DataTypes.h> namespace mcld { class ResolveInfo; class Relocator; class LinkerConfig; class Relocation : public llvm::ilist_node<Relocation> { friend class RelocationFactory; friend class GCFactoryListTraits<Relocation>; friend class Chunk<Relocation, MCLD_RELOCATIONS_PER_INPUT>; public: typedef uint64_t Address; // FIXME: use SizeTrait<T>::Address instead typedef uint64_t DWord; // FIXME: use SizeTrait<T>::Word instead typedef int64_t SWord; // FIXME: use SizeTrait<T>::SWord instead typedef uint8_t Type; typedef uint32_t Size; private: Relocation(); Relocation(Type pType, FragmentRef* pTargetRef, Address pAddend, DWord pTargetData); ~Relocation(); public: /// Initialize - set up the relocation factory static void SetUp(const LinkerConfig& pConfig); /// Clear - Clean up the relocation factory static void Clear(); /// Create - produce an empty relocation entry static Relocation* Create(); /// Create - produce a relocation entry /// @param pType [in] the type of the relocation entry /// @param pFragRef [in] the place to apply the relocation /// @param pAddend [in] the addend of the relocation entry static Relocation* Create(Type pType, FragmentRef& pFragRef, Address pAddend = 0); /// Destroy - destroy a relocation entry static void Destroy(Relocation*& pRelocation); /// type - relocation type Type type() const { return m_Type; } /// symValue - S value - the symbol address Address symValue() const; /// addend - A value Address addend() const { return m_Addend; } /// place - P value - address of the place being relocated Address place() const; /// size - the size of the relocation in bit Size size(Relocator& pRelocator) const; /// symbol info - binding, type const ResolveInfo* symInfo() const { return m_pSymInfo; } ResolveInfo* symInfo() { return m_pSymInfo; } /// target - the target data to relocate const DWord& target() const { return m_TargetData; } DWord& target() { return m_TargetData; } /// targetRef - the reference of the target data const FragmentRef& targetRef() const { return m_TargetAddress; } FragmentRef& targetRef() { return m_TargetAddress; } void apply(Relocator& pRelocator); /// updateAddend - A relocation with a section symbol must update addend /// before reading its value. void updateAddend(); /// ----- modifiers ----- /// void setType(Type pType); void setAddend(Address pAddend); void setSymInfo(ResolveInfo* pSym); private: /// m_Type - the type of the relocation entries Type m_Type; /// m_TargetData - target data of the place being relocated DWord m_TargetData; /// m_pSymInfo - resolved symbol info of relocation target symbol ResolveInfo* m_pSymInfo; /// m_TargetAddress - FragmentRef of the place being relocated FragmentRef m_TargetAddress; /// m_Addend - the addend Address m_Addend; }; } // namespace of mcld #endif