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
X86GOT(LDSection & pSection,llvm::MCSectionData & pSectionData)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
~X86GOT()56 X86GOT::~X86GOT()
57 {
58 }
59
reserveEntry(size_t pNum)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
getEntry(const ResolveInfo & pInfo,bool & pExist)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
applyGOT0(uint64_t pAddress)95 void X86GOT::applyGOT0(uint64_t pAddress)
96 {
97 llvm::cast<GOTEntry>
98 (*(m_SectionData.getFragmentList().begin())).setContent(pAddress);
99 }
100
begin()101 X86GOT::iterator X86GOT::begin()
102 {
103 return m_SectionData.getFragmentList().begin();
104 }
105
begin() const106 X86GOT::const_iterator X86GOT::begin() const
107 {
108 return m_SectionData.getFragmentList().begin();
109 }
110
end()111 X86GOT::iterator X86GOT::end()
112 {
113 return m_SectionData.getFragmentList().end();
114 }
115
end() const116 X86GOT::const_iterator X86GOT::end() const
117 {
118 return m_SectionData.getFragmentList().end();
119 }
120
getGOTPLTNum() const121 unsigned int X86GOT::getGOTPLTNum() const
122 { return m_GOTPLTNum; }
123
getLastGOT0()124 X86GOT::iterator X86GOT::getLastGOT0()
125 { return m_LastGOT0; }
126
getLastGOT0() const127 const X86GOT::iterator X86GOT::getLastGOT0() const
128 { return m_LastGOT0; }
129