//===- OutputRelocSection.cpp ---------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "mcld/Target/OutputRelocSection.h" #include "mcld/IRBuilder.h" #include "mcld/LD/LDSection.h" #include "mcld/LD/RelocationFactory.h" #include "mcld/Support/MsgHandling.h" #include "mcld/Module.h" #include <llvm/Support/Casting.h> namespace mcld { //===----------------------------------------------------------------------===// // OutputRelocSection //===----------------------------------------------------------------------===// OutputRelocSection::OutputRelocSection(Module& pModule, LDSection& pSection) : m_Module(pModule), m_pRelocData(NULL), m_isVisit(false), m_ValidEntryIterator() { assert(!pSection.hasRelocData() && "Given section is not a relocation section"); m_pRelocData = IRBuilder::CreateRelocData(pSection); } OutputRelocSection::~OutputRelocSection() { } Relocation* OutputRelocSection::create() { Relocation* reloc = Relocation::Create(); m_pRelocData->append(*reloc); return reloc; } void OutputRelocSection::reserveEntry(size_t pNum) { for (size_t i = 0; i < pNum; ++i) m_pRelocData->append(*Relocation::Create()); } Relocation* OutputRelocSection::consumeEntry() { // first time visit this function, set m_ValidEntryIterator to // Fragments.begin() if (!m_isVisit) { assert(!m_pRelocData->getRelocationList().empty() && "DynRelSection contains no entries."); m_ValidEntryIterator = m_pRelocData->begin(); m_isVisit = true; } else { // Add m_ValidEntryIterator here instead of at the end of this function. // We may reserve an entry and then consume it immediately, e.g. for COPY // relocation, so we need to avoid setting this iterator to // RelocData->end() in any case, or when reserve and consume again, // ++m_ValidEntryIterator will still be RelocData->end(). ++m_ValidEntryIterator; } assert(m_ValidEntryIterator != m_pRelocData->end() && "No empty relocation entry for the incoming symbol."); return &(*m_ValidEntryIterator); } size_t OutputRelocSection::numOfRelocs() { return m_pRelocData->size(); } bool OutputRelocSection::addSymbolToDynSym(LDSymbol& pSymbol) { m_Module.getSymbolTable().changeToDynamic(pSymbol); return true; } } // namespace mcld