blob: 544b5e9e9580905edc6c171871adcb50b737c724 [file] [log] [blame]
//===- impl.cpp -----------------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "X86GOT.h"
#include <mcld/LD/LDFileFormat.h>
#include <llvm/Support/ErrorHandling.h>
#include <new>
namespace {
const size_t X86GOTEntrySize = 4;
}
using namespace mcld;
//===----------------------------------------------------------------------===//
// X86GOT
X86GOT::X86GOT(LDSection& pSection, llvm::MCSectionData& pSectionData)
: GOT(pSection, pSectionData, X86GOTEntrySize),
m_GeneralGOTNum(0), m_GOTPLTNum(0), m_GeneralGOTIterator(),
m_GOTPLTIterator(), m_LastGOT0()
{
GOTEntry* Entry = 0;
// Create GOT0 entries.
for (unsigned int i = 0; i < X86GOT0Num; i++) {
Entry = new (std::nothrow) GOTEntry(0, X86GOTEntrySize,
&m_SectionData);
if (!Entry)
llvm::report_fatal_error("Allocating GOT0 entries failed!");
m_Section.setSize(m_Section.size() + X86GOTEntrySize);
}
// Skip GOT0 entries.
iterator it = m_SectionData.begin();
iterator ie = m_SectionData.end();
for (unsigned int i = 1; i < X86GOT0Num; ++i) {
if (it == ie)
llvm::report_fatal_error("Generation of GOT0 entries is incomplete!");
++it;
}
m_LastGOT0 = it;
m_GeneralGOTIterator = it;
m_GOTPLTIterator = it;
}
X86GOT::~X86GOT()
{
}
void X86GOT::reserveEntry(size_t pNum)
{
GOTEntry* Entry = 0;
for (size_t i = 0; i < pNum; i++) {
Entry = new (std::nothrow) GOTEntry(0, X86GOTEntrySize,
&m_SectionData);
if (!Entry)
llvm::report_fatal_error("Allocating new memory for GOTEntry failed");
m_Section.setSize(m_Section.size() + X86GOTEntrySize);
++m_GeneralGOTNum;
}
}
GOTEntry* X86GOT::getEntry(const ResolveInfo& pInfo, bool& pExist)
{
GOTEntry *&Entry = m_GeneralGOTMap[&pInfo];
pExist = 1;
if (!Entry) {
pExist = 0;
++m_GeneralGOTIterator;
assert(m_GeneralGOTIterator != m_SectionData.getFragmentList().end()
&& "The number of GOT Entries and ResolveInfo doesn't match!");
Entry = llvm::cast<GOTEntry>(&(*m_GeneralGOTIterator));
}
return Entry;
}
void X86GOT::applyGOT0(uint64_t pAddress)
{
llvm::cast<GOTEntry>
(*(m_SectionData.getFragmentList().begin())).setContent(pAddress);
}
X86GOT::iterator X86GOT::begin()
{
return m_SectionData.getFragmentList().begin();
}
X86GOT::const_iterator X86GOT::begin() const
{
return m_SectionData.getFragmentList().begin();
}
X86GOT::iterator X86GOT::end()
{
return m_SectionData.getFragmentList().end();
}
X86GOT::const_iterator X86GOT::end() const
{
return m_SectionData.getFragmentList().end();
}
unsigned int X86GOT::getGOTPLTNum() const
{ return m_GOTPLTNum; }
X86GOT::iterator X86GOT::getLastGOT0()
{ return m_LastGOT0; }
const X86GOT::iterator X86GOT::getLastGOT0() const
{ return m_LastGOT0; }