Home | History | Annotate | Download | only in Target
      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