summaryrefslogtreecommitdiff
path: root/lib/LD/LDSymbol.cpp
blob: 900223530f4a374e39ffde61415ee927c8ee0471 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//===- LDSymbol.cpp -------------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/LD/LDSymbol.h>

#include <mcld/Config/Config.h>
#include <mcld/Fragment/FragmentRef.h>
#include <mcld/Fragment/NullFragment.h>
#include <mcld/Support/GCFactory.h>

#include <cstring>

#include <llvm/Support/ManagedStatic.h>

using namespace mcld;

typedef GCFactory<LDSymbol, MCLD_SYMBOLS_PER_INPUT> LDSymbolFactory;

static llvm::ManagedStatic<LDSymbol> g_NullSymbol;
static llvm::ManagedStatic<NullFragment> g_NullSymbolFragment;
static llvm::ManagedStatic<LDSymbolFactory> g_LDSymbolFactory;

//===----------------------------------------------------------------------===//
// LDSymbol
//===----------------------------------------------------------------------===//
LDSymbol::LDSymbol()
  : m_pResolveInfo(NULL), m_pFragRef(NULL), m_Value(0) {
}

LDSymbol::~LDSymbol()
{
}

LDSymbol::LDSymbol(const LDSymbol& pCopy)
  : m_pResolveInfo(pCopy.m_pResolveInfo),
    m_pFragRef(pCopy.m_pFragRef),
    m_Value(pCopy.m_Value) {
}

LDSymbol& LDSymbol::operator=(const LDSymbol& pCopy)
{
  m_pResolveInfo = pCopy.m_pResolveInfo;
  m_pFragRef = pCopy.m_pFragRef;
  m_Value = pCopy.m_Value;
  return (*this);
}

LDSymbol* LDSymbol::Create(ResolveInfo& pResolveInfo)
{
  LDSymbol* result = g_LDSymbolFactory->allocate();
  new (result) LDSymbol();
  result->setResolveInfo(pResolveInfo);
  return result;
}

void LDSymbol::Destroy(LDSymbol*& pSymbol)
{
  pSymbol->~LDSymbol();
  g_LDSymbolFactory->deallocate(pSymbol);
  pSymbol = NULL;
}

void LDSymbol::Clear()
{
  g_LDSymbolFactory->clear();
}

LDSymbol* LDSymbol::Null()
{
  // lazy initialization
  if (NULL == g_NullSymbol->resolveInfo()) {
    g_NullSymbol->setResolveInfo(*ResolveInfo::Null());
    g_NullSymbol->setFragmentRef(FragmentRef::Create(*g_NullSymbolFragment, 0));
    ResolveInfo::Null()->setSymPtr(&*g_NullSymbol);
  }
  return &*g_NullSymbol;
}

void LDSymbol::setFragmentRef(FragmentRef* pFragmentRef)
{
  m_pFragRef = pFragmentRef;
}

void LDSymbol::setResolveInfo(const ResolveInfo& pInfo)
{
  m_pResolveInfo = const_cast<ResolveInfo*>(&pInfo);
}

bool LDSymbol::isNull() const
{
  return (this == Null());
}

bool LDSymbol::hasFragRef() const
{
  return !m_pFragRef->isNull();
}