Home | History | Annotate | Download | only in X86
      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 #include "X86GOTPLT.h"
     10 #include "mcld/LD/LDFileFormat.h"
     11 #include <llvm/Support/ErrorHandling.h>
     12 #include <new>
     13 
     14 namespace {
     15   const uint64_t X86GOTPLTEntrySize = 4;
     16 }
     17 
     18 namespace mcld {
     19 
     20 //===----------------------------------------------------------------------===//
     21 // X86GOTPLT
     22 X86GOTPLT::X86GOTPLT(LDSection& pSection, llvm::MCSectionData& pSectionData)
     23   : GOT(pSection, pSectionData, X86GOTPLTEntrySize), m_GOTPLTIterator()
     24 {
     25   GOTEntry* Entry = 0;
     26 
     27   // Create GOT0 entries.
     28   for (int i = 0; i < 3; i++) {
     29     Entry = new (std::nothrow) GOTEntry(0, X86GOTPLTEntrySize,
     30                                         &m_SectionData);
     31 
     32     if (!Entry)
     33       llvm::report_fatal_error("Allocating GOT0 entries failed!");
     34 
     35     m_Section.setSize(m_Section.size() + X86GOTPLTEntrySize);
     36   }
     37 
     38   // Skip GOT0 entries.
     39   iterator it = m_SectionData.begin();
     40   iterator ie = m_SectionData.end();
     41 
     42   for (size_t i = 1; i < X86GOT0Num; ++i) {
     43     if (it == ie)
     44       llvm::report_fatal_error("Generation of GOT0 entries is incomplete!");
     45 
     46     ++it;
     47   }
     48 
     49   m_GOTPLTIterator = it;
     50 }
     51 
     52 X86GOTPLT::~X86GOTPLT()
     53 {
     54 }
     55 
     56 X86GOTPLT::iterator X86GOTPLT::begin()
     57 {
     58   return m_SectionData.begin();
     59 }
     60 
     61 X86GOTPLT::const_iterator X86GOTPLT::begin() const
     62 {
     63   return m_SectionData.begin();
     64 }
     65 
     66 X86GOTPLT::iterator X86GOTPLT::end()
     67 {
     68   return m_SectionData.end();
     69 }
     70 
     71 X86GOTPLT::const_iterator X86GOTPLT::end() const
     72 {
     73   return m_SectionData.end();
     74 }
     75 
     76 void X86GOTPLT::applyGOT0(const uint64_t pAddress)
     77 {
     78   llvm::cast<GOTEntry>
     79     (*(m_SectionData.getFragmentList().begin())).setContent(pAddress);
     80 }
     81 
     82 void X86GOTPLT::reserveGOTPLTEntry()
     83 {
     84     GOTEntry* got_entry = 0;
     85 
     86     got_entry= new GOTEntry(0, getEntrySize(),&(getSectionData()));
     87 
     88     if (!got_entry)
     89       llvm::report_fatal_error("Allocating new memory for GOT failed!");
     90 
     91     m_Section.setSize(m_Section.size() + getEntrySize());
     92 }
     93 
     94 void X86GOTPLT::applyAllGOTPLT(const uint64_t pPLTBase)
     95 {
     96   iterator gotplt_it = begin();
     97   iterator gotplt_ie = end();
     98 
     99   for (; gotplt_it != gotplt_ie; ++gotplt_it)
    100     llvm::cast<GOTEntry>(*gotplt_it).setContent(pPLTBase);
    101 }
    102 
    103 GOTEntry*& X86GOTPLT::lookupGOTPLTMap(const ResolveInfo& pSymbol)
    104 {
    105   return m_GOTPLTMap[&pSymbol];
    106 }
    107 
    108 X86GOTPLT::iterator X86GOTPLT::getNextGOTPLTEntry()
    109 {
    110   return ++m_GOTPLTIterator;
    111 }
    112 
    113 } //end mcld namespace
    114