OutputRelocSection.cpp revision 5460a1f25d9ddecb5c70667267d66d51af177a99
1//===- OutputRelocSection.cpp ---------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include <mcld/LD/LDSection.h>
10#include <mcld/Target/OutputRelocSection.h>
11
12using namespace mcld;
13
14//==========================
15// OutputRelocSection
16
17
18OutputRelocSection::OutputRelocSection(LDSection& pSection,
19                                       llvm::MCSectionData& pSectionData,
20                                       unsigned int pEntrySize)
21  : m_pSection(&pSection),
22    m_pSectionData(&pSectionData),
23    m_EntryBytes(pEntrySize),
24    m_isVisit(false),
25    m_ValidEntryIterator(){
26}
27
28OutputRelocSection::~OutputRelocSection()
29{
30}
31
32void OutputRelocSection::reserveEntry(RelocationFactory& pRelFactory,
33                                      size_t pNum)
34{
35  for(size_t i=0; i<pNum; i++) {
36    m_pSectionData->getFragmentList().push_back(pRelFactory.produceEmptyEntry());
37    // update section size
38    m_pSection->setSize(m_pSection->size() + m_EntryBytes);
39  }
40}
41
42Relocation* OutputRelocSection::getEntry(const ResolveInfo& pSymbol,
43                                         bool isForGOT,
44                                         bool& pExist)
45{
46  // first time visit this function, set m_ValidEntryIterator to
47  // Fragments.begin()
48  if(!m_isVisit) {
49    assert( !m_pSectionData->getFragmentList().empty() &&
50             "DynRelSection contains no entries.");
51    m_ValidEntryIterator = m_pSectionData->getFragmentList().begin();
52    m_isVisit = true;
53  }
54
55  assert(m_ValidEntryIterator != m_pSectionData->end() &&
56         "No empty relocation entry for the incoming symbol.");
57
58  // if this relocation is used to relocate GOT (.got or .got.plt),
59  // check if we've gotten an entry for this symbol before. If yes,
60  // return the found entry in map.
61  // Otherwise, this relocation is used to relocate general section
62  // (data or text section), return an empty entry directly.
63  Relocation* result;
64
65  if(isForGOT) {
66    // get or create entry in m_SymRelMap
67    Relocation *&Entry = m_SymRelMap[&pSymbol];
68    pExist = 1;
69
70    if(!Entry) {
71      pExist = 0;
72      Entry = llvm::cast<Relocation>(&(*m_ValidEntryIterator));
73      ++m_ValidEntryIterator;
74    }
75    result = Entry;
76  }
77  else {
78    pExist = 0;
79    result = llvm::cast<Relocation>(&(*m_ValidEntryIterator));
80    ++m_ValidEntryIterator;
81  }
82  return result;
83}
84
85