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