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