• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 using namespace mcld;
18 
19 //===----------------------------------------------------------------------===//
20 // OutputRelocSection
21 //===----------------------------------------------------------------------===//
OutputRelocSection(LDSection & pSection,SectionData & pSectionData,unsigned int pEntrySize)22 OutputRelocSection::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 
~OutputRelocSection()32 OutputRelocSection::~OutputRelocSection()
33 {
34 }
35 
reserveEntry(RelocationFactory & pRelFactory,size_t pNum)36 void 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 
getEntry(const ResolveInfo & pSymbol,bool isForGOT,bool & pExist)46 Relocation* 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