| //===- ResolveInfo.h ------------------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #ifndef MCLD_RESOLVE_INFO_H |
| #define MCLD_RESOLVE_INFO_H |
| #ifdef ENABLE_UNITTEST |
| #include <gtest.h> |
| #endif |
| |
| #include <llvm/Support/DataTypes.h> |
| #include <llvm/ADT/StringRef.h> |
| |
| namespace mcld { |
| |
| class LDSymbol; |
| |
| /** \class ResolveInfo |
| * \brief ResolveInfo records the information about how to resolve a symbol. |
| * |
| * A symbol must have some `attributes': |
| * - Desc - Defined, Reference, Common or Indirect |
| * - Binding - Global, Local, Weak |
| * - IsDyn - appear in dynamic objects or regular objects |
| * - Type - what the symbol points to |
| * - Size - the size of the symbol point to |
| * - Value - the pointer to another LDSymbol |
| * In order to save the memory and speed up the performance, FragmentLinker uses |
| * a bit field to store all attributes. |
| * |
| * The maximum string length is (2^16 - 1) |
| */ |
| class ResolveInfo |
| { |
| friend class FragmentLinker; |
| public: |
| typedef uint64_t SizeType; |
| |
| /** \enum Type |
| * \brief What the symbol stand for |
| * |
| * It is like ELF32_ST_TYPE |
| * MachO does not need this, and can not jump between Thumb and ARM code. |
| */ |
| enum Type { |
| NoType = 0, |
| Object = 1, |
| Function = 2, |
| Section = 3, |
| File = 4, |
| CommonBlock = 5, |
| ThreadLocal = 6, |
| IndirectFunc = 10, |
| LoProc = 13, |
| HiProc = 15 |
| }; |
| |
| /** \enum Desc |
| * \brief Description of the symbols. |
| * |
| * Follow the naming in MachO. Like MachO nlist::n_desc |
| * In ELF, is a part of st_shndx |
| */ |
| enum Desc { |
| Undefined = 0, |
| Define = 1, |
| Common = 2, |
| Indirect = 3, |
| NoneDesc |
| }; |
| |
| enum Binding { |
| Global = 0, |
| Weak = 1, |
| Local = 2, |
| Absolute = 3, |
| NoneBinding |
| }; |
| |
| enum Visibility { |
| Default = 0, |
| Internal = 1, |
| Hidden = 2, |
| Protected = 3 |
| }; |
| |
| // ----- For HashTable ----- // |
| typedef llvm::StringRef key_type; |
| |
| public: |
| // ----- factory method ----- // |
| static ResolveInfo* Create(const key_type& pKey); |
| |
| static void Destroy(ResolveInfo*& pInfo); |
| |
| static ResolveInfo* Null(); |
| |
| // ----- modifiers ----- // |
| /// setRegular - set the source of the file is a regular object |
| void setRegular(); |
| |
| /// setDynamic - set the source of the file is a dynamic object |
| void setDynamic(); |
| |
| /// setSource - set the source of the file |
| /// @param pIsDyn is the source from a dynamic object? |
| void setSource(bool pIsDyn); |
| |
| void setType(uint32_t pType); |
| |
| void setDesc(uint32_t pDesc); |
| |
| void setBinding(uint32_t pBinding); |
| |
| void setOther(uint32_t pOther); |
| |
| void setVisibility(Visibility pVisibility); |
| |
| void setIsSymbol(bool pIsSymbol); |
| |
| void setReserved(uint32_t pReserved); |
| |
| void setSize(SizeType pSize) |
| { m_Size = pSize; } |
| |
| void override(const ResolveInfo& pForm); |
| |
| void overrideAttributes(const ResolveInfo& pFrom); |
| |
| void overrideVisibility(const ResolveInfo& pFrom); |
| |
| void setSymPtr(const LDSymbol* pSymPtr) |
| { m_Ptr.sym_ptr = const_cast<LDSymbol*>(pSymPtr); } |
| |
| void setLink(const ResolveInfo* pTarget) { |
| m_Ptr.info_ptr = const_cast<ResolveInfo*>(pTarget); |
| m_BitField |= indirect_flag; |
| } |
| |
| |
| // ----- observers ----- // |
| bool isNull() const; |
| |
| bool isSymbol() const; |
| |
| bool isString() const; |
| |
| bool isGlobal() const; |
| |
| bool isWeak() const; |
| |
| bool isLocal() const; |
| |
| bool isAbsolute() const; |
| |
| bool isDefine() const; |
| |
| bool isUndef() const; |
| |
| bool isDyn() const; |
| |
| bool isCommon() const; |
| |
| bool isIndirect() const; |
| |
| uint32_t type() const; |
| |
| uint32_t desc() const; |
| |
| uint32_t binding() const; |
| |
| uint32_t reserved() const; |
| |
| uint8_t other() const |
| { return (uint8_t)visibility(); } |
| |
| Visibility visibility() const; |
| |
| LDSymbol* outSymbol() |
| { return m_Ptr.sym_ptr; } |
| |
| const LDSymbol* outSymbol() const |
| { return m_Ptr.sym_ptr; } |
| |
| ResolveInfo* link() |
| { return m_Ptr.info_ptr; } |
| |
| const ResolveInfo* link() const |
| { return m_Ptr.info_ptr; } |
| |
| SizeType size() const |
| { return m_Size; } |
| |
| const char* name() const |
| { return m_Name; } |
| |
| unsigned int nameSize() const |
| { return (m_BitField >> NAME_LENGTH_OFFSET); } |
| |
| uint32_t info() const |
| { return (m_BitField & INFO_MASK); } |
| |
| uint32_t bitfield() const |
| { return m_BitField; } |
| |
| // ----- For HashTable ----- // |
| bool compare(const key_type& pKey); |
| |
| private: |
| static const uint32_t GLOBAL_OFFSET = 0; |
| static const uint32_t GLOBAL_MASK = 1; |
| |
| static const uint32_t DYN_OFFSET = 1; |
| static const uint32_t DYN_MASK = 1 << DYN_OFFSET; |
| |
| static const uint32_t DESC_OFFSET = 2; |
| static const uint32_t DESC_MASK = 0x3 << DESC_OFFSET; |
| |
| static const uint32_t LOCAL_OFFSET = 4; |
| static const uint32_t LOCAL_MASK = 1 << LOCAL_OFFSET; |
| |
| static const uint32_t BINDING_MASK = GLOBAL_MASK | LOCAL_MASK; |
| |
| static const uint32_t VISIBILITY_OFFSET = 5; |
| static const uint32_t VISIBILITY_MASK = 0x3 << VISIBILITY_OFFSET; |
| |
| static const uint32_t TYPE_OFFSET = 7; |
| static const uint32_t TYPE_MASK = 0xF << TYPE_OFFSET; |
| |
| static const uint32_t SYMBOL_OFFSET = 11; |
| static const uint32_t SYMBOL_MASK = 1 << SYMBOL_OFFSET; |
| |
| static const uint32_t RESERVED_OFFSET = 12; |
| static const uint32_t RESERVED_MASK = 0xF << RESERVED_OFFSET; |
| static const uint32_t NAME_LENGTH_OFFSET = 16; |
| static const uint32_t INFO_MASK = 0xF; |
| static const uint32_t RESOLVE_MASK = 0xFFFF; |
| |
| union SymOrInfo { |
| LDSymbol* sym_ptr; |
| ResolveInfo* info_ptr; |
| }; |
| |
| public: |
| static const uint32_t global_flag = 0 << GLOBAL_OFFSET; |
| static const uint32_t weak_flag = 1 << GLOBAL_OFFSET; |
| static const uint32_t regular_flag = 0 << DYN_OFFSET; |
| static const uint32_t dynamic_flag = 1 << DYN_OFFSET; |
| static const uint32_t undefine_flag = 0 << DESC_OFFSET; |
| static const uint32_t define_flag = 1 << DESC_OFFSET; |
| static const uint32_t common_flag = 2 << DESC_OFFSET; |
| static const uint32_t indirect_flag = 3 << DESC_OFFSET; |
| static const uint32_t local_flag = 1 << LOCAL_OFFSET; |
| static const uint32_t absolute_flag = BINDING_MASK; |
| static const uint32_t object_flag = Object << TYPE_OFFSET; |
| static const uint32_t function_flag = Function << TYPE_OFFSET; |
| static const uint32_t section_flag = Section << TYPE_OFFSET; |
| static const uint32_t file_flag = File << TYPE_OFFSET; |
| static const uint32_t string_flag = 0 << SYMBOL_OFFSET; |
| static const uint32_t symbol_flag = 1 << SYMBOL_OFFSET; |
| |
| private: |
| ResolveInfo(); |
| ResolveInfo(const ResolveInfo& pCopy); |
| ResolveInfo& operator=(const ResolveInfo& pCopy); |
| ~ResolveInfo(); |
| |
| private: |
| SizeType m_Size; |
| SymOrInfo m_Ptr; |
| |
| /** m_BitField |
| * 31 ... 16 15 12 11 10..7 6 .. 5 4 3 2 1 0 |
| * |length of m_Name|reserved|Symbol|Type |ELF visibility|Local|Com|Def|Dyn|Weak| |
| */ |
| uint32_t m_BitField; |
| char m_Name[]; |
| }; |
| |
| } // namespace of mcld |
| |
| #endif |
| |