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