//===- X86GOTPLT.cpp ------------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "X86GOTPLT.h" #include <new> #include <llvm/Support/Casting.h> #include <mcld/LD/LDFileFormat.h> #include <mcld/Support/MsgHandling.h> namespace { const uint64_t X86GOTPLTEntrySize = 4; } namespace mcld { //===----------------------------------------------------------------------===// // X86GOTPLT //===----------------------------------------------------------------------===// X86GOTPLT::X86GOTPLT(LDSection& pSection, SectionData& pSectionData) : GOT(pSection, pSectionData, X86GOTPLTEntrySize), m_GOTPLTIterator() { GOTEntry* Entry = 0; // Create GOT0 entries. for (size_t i = 0; i < X86GOTPLT0Num; i++) { Entry = new (std::nothrow) GOTEntry(0, X86GOTPLTEntrySize, &m_SectionData); if (!Entry) fatal(diag::fail_allocate_memory_got); m_Section.setSize(m_Section.size() + X86GOTPLTEntrySize); } // Skip GOT0 entries. iterator it = m_SectionData.begin(); for (size_t i = 1; i < X86GOTPLT0Num; ++i) { assert((it != m_SectionData.end()) && "Generation of GOT0 entries is incomplete!"); ++it; } m_GOTPLTIterator = it; } X86GOTPLT::~X86GOTPLT() { } X86GOTPLT::iterator X86GOTPLT::begin() { return m_SectionData.begin(); } X86GOTPLT::const_iterator X86GOTPLT::begin() const { return m_SectionData.begin(); } X86GOTPLT::iterator X86GOTPLT::end() { return m_SectionData.end(); } X86GOTPLT::const_iterator X86GOTPLT::end() const { return m_SectionData.end(); } void X86GOTPLT::applyGOT0(uint64_t pAddress) { llvm::cast<GOTEntry> (*(m_SectionData.getFragmentList().begin())).setContent(pAddress); } void X86GOTPLT::reserveEntry(size_t pNum) { GOTEntry* got_entry = NULL; for (size_t i = 0; i < pNum; ++i) { got_entry = new GOTEntry(0, getEntrySize(),&(getSectionData())); if (!got_entry) fatal(diag::fail_allocate_memory_got); m_Section.setSize(m_Section.size() + getEntrySize()); } } void X86GOTPLT::applyAllGOTPLT(uint64_t pPLTBase, unsigned int pPLT0Size, unsigned int pPLT1Size) { iterator it = begin(); // skip GOT0 for (size_t i = 0; i < X86GOTPLT0Num; ++i) ++it; // address of corresponding plt entry uint64_t plt_addr = pPLTBase + pPLT0Size; for (; it != end() ; ++it) { llvm::cast<GOTEntry>(*it).setContent(plt_addr + 6); plt_addr += pPLT1Size; } } GOTEntry*& X86GOTPLT::lookupGOTPLTMap(const ResolveInfo& pSymbol) { return m_GOTPLTMap[&pSymbol]; } GOTEntry* X86GOTPLT::getEntry(const ResolveInfo& pInfo, bool& pExist) { GOTEntry *&Entry = m_GOTPLTMap[&pInfo]; pExist = 1; if (!Entry) { pExist = 0; ++m_GOTPLTIterator; assert(m_GOTPLTIterator != m_SectionData.getFragmentList().end() && "The number of GOT Entries and ResolveInfo doesn't match!"); Entry = llvm::cast<GOTEntry>(&(*m_GOTPLTIterator)); } return Entry; } } //end mcld namespace