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/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 //===----------------------------------------------------------------------===//
     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 
     34 OutputRelocSection::~OutputRelocSection() {
     35 }
     36 
     37 Relocation* OutputRelocSection::create() {
     38   Relocation* reloc = Relocation::Create();
     39   m_pRelocData->append(*reloc);
     40   return reloc;
     41 }
     42 
     43 void OutputRelocSection::reserveEntry(size_t pNum) {
     44   for (size_t i = 0; i < pNum; ++i)
     45     m_pRelocData->append(*Relocation::Create());
     46 }
     47 
     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 
     70 size_t OutputRelocSection::numOfRelocs() {
     71   return m_pRelocData->size();
     72 }
     73 
     74 bool OutputRelocSection::addSymbolToDynSym(LDSymbol& pSymbol) {
     75   m_Module.getSymbolTable().changeToDynamic(pSymbol);
     76   return true;
     77 }
     78 
     79 }  // namespace mcld
     80