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