• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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