//===- 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 refers 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;
friend class IRBuilder;
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