Home | History | Annotate | Download | only in X86
      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