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