OutputRelocSection.cpp revision 37b74a387bb3993387029859c2d9d051c41c724e
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/Target/OutputRelocSection.h"
10
11#include "mcld/IRBuilder.h"
12#include "mcld/LD/LDSection.h"
13#include "mcld/LD/RelocationFactory.h"
14#include "mcld/Support/MsgHandling.h"
15#include "mcld/Module.h"
16
17#include <llvm/Support/Casting.h>
18
19namespace mcld {
20
21//===----------------------------------------------------------------------===//
22// OutputRelocSection
23//===----------------------------------------------------------------------===//
24OutputRelocSection::OutputRelocSection(Module& pModule, LDSection& pSection)
25    : m_Module(pModule),
26      m_pRelocData(NULL),
27      m_isVisit(false),
28      m_ValidEntryIterator() {
29  assert(!pSection.hasRelocData() &&
30         "Given section is not a relocation section");
31  m_pRelocData = IRBuilder::CreateRelocData(pSection);
32}
33
34OutputRelocSection::~OutputRelocSection() {
35}
36
37Relocation* OutputRelocSection::create() {
38  Relocation* reloc = Relocation::Create();
39  m_pRelocData->append(*reloc);
40  return reloc;
41}
42
43void OutputRelocSection::reserveEntry(size_t pNum) {
44  for (size_t i = 0; i < pNum; ++i)
45    m_pRelocData->append(*Relocation::Create());
46}
47
48Relocation* OutputRelocSection::consumeEntry() {
49  // first time visit this function, set m_ValidEntryIterator to
50  // Fragments.begin()
51  if (!m_isVisit) {
52    assert(!m_pRelocData->getRelocationList().empty() &&
53           "DynRelSection contains no entries.");
54    m_ValidEntryIterator = m_pRelocData->begin();
55    m_isVisit = true;
56  } else {
57    // Add m_ValidEntryIterator here instead of at the end of this function.
58    // We may reserve an entry and then consume it immediately, e.g. for COPY
59    // relocation, so we need to avoid setting this iterator to
60    // RelocData->end() in any case, or when reserve and consume again,
61    // ++m_ValidEntryIterator will still be RelocData->end().
62    ++m_ValidEntryIterator;
63  }
64  assert(m_ValidEntryIterator != m_pRelocData->end() &&
65         "No empty relocation entry for the incoming symbol.");
66
67  return &(*m_ValidEntryIterator);
68}
69
70size_t OutputRelocSection::numOfRelocs() {
71  return m_pRelocData->size();
72}
73
74bool OutputRelocSection::addSymbolToDynSym(LDSymbol& pSymbol) {
75  m_Module.getSymbolTable().changeToDynamic(pSymbol);
76  return true;
77}
78
79}  // namespace mcld
80