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
19 namespace mcld {
20
21 //===----------------------------------------------------------------------===//
22 // OutputRelocSection
23 //===----------------------------------------------------------------------===//
OutputRelocSection(Module & pModule,LDSection & pSection)24 OutputRelocSection::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
~OutputRelocSection()34 OutputRelocSection::~OutputRelocSection() {
35 }
36
create()37 Relocation* OutputRelocSection::create() {
38 Relocation* reloc = Relocation::Create();
39 m_pRelocData->append(*reloc);
40 return reloc;
41 }
42
reserveEntry(size_t pNum)43 void OutputRelocSection::reserveEntry(size_t pNum) {
44 for (size_t i = 0; i < pNum; ++i)
45 m_pRelocData->append(*Relocation::Create());
46 }
47
consumeEntry()48 Relocation* 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
numOfRelocs()70 size_t OutputRelocSection::numOfRelocs() {
71 return m_pRelocData->size();
72 }
73
addSymbolToDynSym(LDSymbol & pSymbol)74 bool OutputRelocSection::addSymbolToDynSym(LDSymbol& pSymbol) {
75 m_Module.getSymbolTable().changeToDynamic(pSymbol);
76 return true;
77 }
78
79 } // namespace mcld
80