| //===- ResolveInfo.cpp ----------------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #include "mcld/LD/ResolveInfo.h" |
| #include <cstring> |
| |
| using namespace mcld; |
| |
| //========================== |
| // ResolveInfo |
| ResolveInfo::ResolveInfo() |
| : m_Size(0), m_BitField(0) { |
| m_Ptr.sym_ptr = 0; |
| } |
| |
| ResolveInfo::~ResolveInfo() |
| { |
| } |
| |
| void ResolveInfo::override(const ResolveInfo& pFrom) |
| { |
| m_Size = pFrom.m_Size; |
| overrideAttributes(pFrom); |
| overrideVisibility(pFrom); |
| } |
| |
| void ResolveInfo::overrideAttributes(const ResolveInfo& pFrom) |
| { |
| m_BitField &= ~RESOLVE_MASK; |
| m_BitField |= (pFrom.m_BitField & RESOLVE_MASK); |
| } |
| |
| /// overrideVisibility - override the visibility |
| /// always use the most strict visibility |
| void ResolveInfo::overrideVisibility(const ResolveInfo& pFrom) |
| { |
| // Reference: Google gold linker: resolve.cc |
| // |
| // The rule for combining visibility is that we always choose the |
| // most constrained visibility. In order of increasing constraint, |
| // visibility goes PROTECTED, HIDDEN, INTERNAL. This is the reverse |
| // of the numeric values, so the effect is that we always want the |
| // smallest non-zero value. |
| // |
| // enum { |
| // STV_DEFAULT = 0, |
| // STV_INTERNAL = 1, |
| // STV_HIDDEN = 2, |
| // STV_PROTECTED = 3 |
| // }; |
| |
| Visibility from_vis = pFrom.visibility(); |
| Visibility cur_vis = visibility(); |
| if (0 != from_vis ) { |
| if (0 == cur_vis) |
| setVisibility(from_vis); |
| else if (cur_vis > from_vis) |
| setVisibility(from_vis); |
| } |
| } |
| |
| void ResolveInfo::setRegular() |
| { |
| m_BitField &= (~dynamic_flag); |
| } |
| |
| void ResolveInfo::setDynamic() |
| { |
| m_BitField |= dynamic_flag; |
| } |
| |
| void ResolveInfo::setSource(bool pIsDyn) |
| { |
| if (pIsDyn) |
| m_BitField |= dynamic_flag; |
| else |
| m_BitField &= (~dynamic_flag); |
| } |
| |
| void ResolveInfo::setType(uint32_t pType) |
| { |
| m_BitField &= ~TYPE_MASK; |
| m_BitField |= ((pType << TYPE_OFFSET) & TYPE_MASK); |
| } |
| |
| void ResolveInfo::setDesc(uint32_t pDesc) |
| { |
| m_BitField &= ~DESC_MASK; |
| m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK); |
| } |
| |
| void ResolveInfo::setBinding(uint32_t pBinding) |
| { |
| m_BitField &= ~BINDING_MASK; |
| if (pBinding == Local || pBinding == Absolute) |
| m_BitField |= local_flag; |
| if (pBinding == Weak || pBinding == Absolute) |
| m_BitField |= weak_flag; |
| } |
| |
| void ResolveInfo::setReserved(uint32_t pReserved) |
| { |
| m_BitField &= ~RESERVED_MASK; |
| m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK); |
| } |
| |
| void ResolveInfo::setOther(uint32_t pOther) |
| { |
| setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3)); |
| } |
| |
| void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility) |
| { |
| m_BitField &= ~VISIBILITY_MASK; |
| m_BitField |= pVisibility << VISIBILITY_OFFSET; |
| } |
| |
| void ResolveInfo::setIsSymbol(bool pIsSymbol) |
| { |
| if (pIsSymbol) |
| m_BitField |= symbol_flag; |
| else |
| m_BitField &= ~symbol_flag; |
| } |
| |
| bool ResolveInfo::isDyn() const |
| { |
| return (dynamic_flag == (m_BitField & DYN_MASK)); |
| } |
| |
| bool ResolveInfo::isUndef() const |
| { |
| return (undefine_flag == (m_BitField & DESC_MASK)); |
| } |
| |
| bool ResolveInfo::isDefine() const |
| { |
| return (define_flag == (m_BitField & DESC_MASK)); |
| } |
| |
| bool ResolveInfo::isCommon() const |
| { |
| return (common_flag == (m_BitField & DESC_MASK)); |
| } |
| |
| bool ResolveInfo::isIndirect() const |
| { |
| return (indirect_flag == (m_BitField & DESC_MASK)); |
| } |
| |
| // isGlobal - [L,W] == [0, 0] |
| bool ResolveInfo::isGlobal() const |
| { |
| return (global_flag == (m_BitField & BINDING_MASK)); |
| } |
| |
| // isWeak - [L,W] == [0, 1] |
| bool ResolveInfo::isWeak() const |
| { |
| return (weak_flag == (m_BitField & BINDING_MASK)); |
| } |
| |
| // isLocal - [L,W] == [1, 0] |
| bool ResolveInfo::isLocal() const |
| { |
| return (local_flag == (m_BitField & BINDING_MASK)); |
| } |
| |
| // isAbsolute - [L,W] == [1, 1] |
| bool ResolveInfo::isAbsolute() const |
| { |
| return (absolute_flag == (m_BitField & BINDING_MASK)); |
| } |
| |
| bool ResolveInfo::isSymbol() const |
| { |
| return (symbol_flag == (m_BitField & SYMBOL_MASK)); |
| } |
| |
| bool ResolveInfo::isString() const |
| { |
| return (string_flag == (m_BitField & SYMBOL_MASK)); |
| } |
| |
| uint32_t ResolveInfo::type() const |
| { |
| return (m_BitField & TYPE_MASK) >> TYPE_OFFSET; |
| } |
| |
| uint32_t ResolveInfo::desc() const |
| { |
| return (m_BitField & DESC_MASK) >> DESC_OFFSET; |
| } |
| |
| uint32_t ResolveInfo::binding() const |
| { |
| if (m_BitField & LOCAL_MASK) { |
| if (m_BitField & GLOBAL_MASK) { |
| return ResolveInfo::Absolute; |
| } |
| return ResolveInfo::Local; |
| } |
| return m_BitField & GLOBAL_MASK; |
| } |
| |
| uint32_t ResolveInfo::reserved() const |
| { |
| return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET; |
| } |
| |
| ResolveInfo::Visibility ResolveInfo::visibility() const |
| { |
| return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >> VISIBILITY_OFFSET); |
| } |
| |
| bool ResolveInfo::compare(const ResolveInfo::key_type& pKey) |
| { |
| size_t length = nameSize(); |
| if (length != pKey.size()) |
| return false; |
| return (0 == std::memcmp(m_Name, pKey.data(), length)); |
| } |
| |