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/LD/LDSection.h> 10 #include <mcld/Target/OutputRelocSection.h> 11 12 using namespace mcld; 13 14 //========================== 15 // OutputRelocSection 16 17 18 OutputRelocSection::OutputRelocSection(LDSection& pSection, 19 llvm::MCSectionData& pSectionData, 20 unsigned int pEntrySize) 21 : m_pSection(&pSection), 22 m_pSectionData(&pSectionData), 23 m_EntryBytes(pEntrySize), 24 m_isVisit(false), 25 m_ValidEntryIterator(){ 26 } 27 28 OutputRelocSection::~OutputRelocSection() 29 { 30 } 31 32 void OutputRelocSection::reserveEntry(RelocationFactory& pRelFactory, 33 size_t pNum) 34 { 35 for(size_t i=0; i<pNum; i++) { 36 m_pSectionData->getFragmentList().push_back(pRelFactory.produceEmptyEntry()); 37 // update section size 38 m_pSection->setSize(m_pSection->size() + m_EntryBytes); 39 } 40 } 41 42 Relocation* OutputRelocSection::getEntry(const ResolveInfo& pSymbol, 43 bool isForGOT, 44 bool& pExist) 45 { 46 // first time visit this function, set m_ValidEntryIterator to 47 // Fragments.begin() 48 if(!m_isVisit) { 49 assert( !m_pSectionData->getFragmentList().empty() && 50 "DynRelSection contains no entries."); 51 m_ValidEntryIterator = m_pSectionData->getFragmentList().begin(); 52 m_isVisit = true; 53 } 54 55 assert(m_ValidEntryIterator != m_pSectionData->end() && 56 "No empty relocation entry for the incoming symbol."); 57 58 // if this relocation is used to relocate GOT (.got or .got.plt), 59 // check if we've gotten an entry for this symbol before. If yes, 60 // return the found entry in map. 61 // Otherwise, this relocation is used to relocate general section 62 // (data or text section), return an empty entry directly. 63 Relocation* result; 64 65 if(isForGOT) { 66 // get or create entry in m_SymRelMap 67 Relocation *&Entry = m_SymRelMap[&pSymbol]; 68 pExist = 1; 69 70 if(!Entry) { 71 pExist = 0; 72 Entry = llvm::cast<Relocation>(&(*m_ValidEntryIterator)); 73 ++m_ValidEntryIterator; 74 } 75 result = Entry; 76 } 77 else { 78 pExist = 0; 79 result = llvm::cast<Relocation>(&(*m_ValidEntryIterator)); 80 ++m_ValidEntryIterator; 81 } 82 return result; 83 } 84 85