X86GOTPLT.cpp revision 67e37f1be98c926645219cfb47fab9e90d8c725c
1//===- X86GOTPLT.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 "X86GOTPLT.h" 10#include <mcld/LD/LDFileFormat.h> 11#include <mcld/Support/MsgHandling.h> 12#include <new> 13 14namespace { 15 const uint64_t X86GOTPLTEntrySize = 4; 16} 17 18namespace mcld { 19 20//===----------------------------------------------------------------------===// 21// X86GOTPLT 22X86GOTPLT::X86GOTPLT(LDSection& pSection, llvm::MCSectionData& pSectionData) 23 : GOT(pSection, pSectionData, X86GOTPLTEntrySize), m_GOTPLTIterator() 24{ 25 GOTEntry* Entry = 0; 26 27 // Create GOT0 entries. 28 for (size_t i = 0; i < X86GOTPLT0Num; i++) { 29 Entry = new (std::nothrow) GOTEntry(0, X86GOTPLTEntrySize, 30 &m_SectionData); 31 32 if (!Entry) 33 fatal(diag::fail_allocate_memory) << "GOT0"; 34 35 m_Section.setSize(m_Section.size() + X86GOTPLTEntrySize); 36 } 37 38 // Skip GOT0 entries. 39 iterator it = m_SectionData.begin(); 40 41 for (size_t i = 1; i < X86GOTPLT0Num; ++i) { 42 assert((it != m_SectionData.end()) && 43 "Generation of GOT0 entries is incomplete!"); 44 45 ++it; 46 } 47 48 m_GOTPLTIterator = it; 49} 50 51X86GOTPLT::~X86GOTPLT() 52{ 53} 54 55X86GOTPLT::iterator X86GOTPLT::begin() 56{ 57 return m_SectionData.begin(); 58} 59 60X86GOTPLT::const_iterator X86GOTPLT::begin() const 61{ 62 return m_SectionData.begin(); 63} 64 65X86GOTPLT::iterator X86GOTPLT::end() 66{ 67 return m_SectionData.end(); 68} 69 70X86GOTPLT::const_iterator X86GOTPLT::end() const 71{ 72 return m_SectionData.end(); 73} 74 75void X86GOTPLT::applyGOT0(uint64_t pAddress) 76{ 77 llvm::cast<GOTEntry> 78 (*(m_SectionData.getFragmentList().begin())).setContent(pAddress); 79} 80 81void X86GOTPLT::reserveEntry(size_t pNum) 82{ 83 GOTEntry* got_entry = NULL; 84 for (size_t i = 0; i < pNum; ++i) { 85 got_entry = new GOTEntry(0, getEntrySize(),&(getSectionData())); 86 if (!got_entry) 87 fatal(diag::fail_allocate_memory) << "GOT"; 88 89 m_Section.setSize(m_Section.size() + getEntrySize()); 90 } 91} 92 93void X86GOTPLT::applyAllGOTPLT(uint64_t pPLTBase, 94 unsigned int pPLT0Size, 95 unsigned int pPLT1Size) 96{ 97 iterator it = begin(); 98 // skip GOT0 99 for (size_t i = 0; i < X86GOTPLT0Num; ++i) 100 ++it; 101 // address of corresponding plt entry 102 uint64_t plt_addr = pPLTBase + pPLT0Size; 103 for (; it != end() ; ++it) { 104 llvm::cast<GOTEntry>(*it).setContent(plt_addr + 6); 105 plt_addr += pPLT1Size; 106 } 107} 108 109GOTEntry*& X86GOTPLT::lookupGOTPLTMap(const ResolveInfo& pSymbol) 110{ 111 return m_GOTPLTMap[&pSymbol]; 112} 113 114GOTEntry* X86GOTPLT::getEntry(const ResolveInfo& pInfo, bool& pExist) 115{ 116 GOTEntry *&Entry = m_GOTPLTMap[&pInfo]; 117 pExist = 1; 118 119 if (!Entry) { 120 pExist = 0; 121 122 ++m_GOTPLTIterator; 123 assert(m_GOTPLTIterator != m_SectionData.getFragmentList().end() 124 && "The number of GOT Entries and ResolveInfo doesn't match!"); 125 126 Entry = llvm::cast<GOTEntry>(&(*m_GOTPLTIterator)); 127 } 128 129 return Entry; 130} 131 132} //end mcld namespace 133