MipsGOT.cpp revision 5460a1f25d9ddecb5c70667267d66d51af177a99
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MipsGOT.cpp --------------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ErrorHandling.h>
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ResolveInfo.h>
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h>
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "MipsGOT.h"
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace {
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const size_t MipsGOTEntrySize = 4;
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const size_t MipsGOT0Num = 1;
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// MipsGOT
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT::MipsGOT(LDSection& pSection, llvm::MCSectionData& pSectionData)
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : GOT(pSection, pSectionData, MipsGOTEntrySize),
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pLocalNum(0)
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Create GOT0 entries.
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t i = 0; i < MipsGOT0Num; ++i) {
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    GOTEntry* entry =
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      new (std::nothrow) GOTEntry(0, MipsGOTEntrySize, &m_SectionData);
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (NULL == entry)
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::report_fatal_error("Allocating GOT0 entries failed!");
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_Section.setSize(m_Section.size() + MipsGOTEntrySize);
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Skip GOT0 entries.
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  iterator it = m_SectionData.begin();
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  iterator ie = m_SectionData.end();
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t i = 1; i < MipsGOT0Num; ++i) {
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (it == ie)
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::report_fatal_error("Generation of GOT0 entries is incomplete!");
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++it;
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_LocalGOTIterator = it;
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_GlobalGOTIterator = it;
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pLocalNum = MipsGOT0Num;
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT::iterator MipsGOT::begin()
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_SectionData.getFragmentList().begin();
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT::iterator MipsGOT::end()
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_SectionData.getFragmentList().end();
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT::const_iterator MipsGOT::begin() const
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_SectionData.getFragmentList().begin();
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMipsGOT::const_iterator MipsGOT::end() const
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_SectionData.getFragmentList().end();
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t MipsGOT::emit(MemoryRegion& pRegion)
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer());
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t entry_size = getEntrySize();
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t result = 0;
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (iterator it = begin(), ie = end();
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       it != ie; ++it, ++buffer) {
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    GOTEntry* got = &(llvm::cast<GOTEntry>((*it)));
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    *buffer = static_cast<uint32_t>(got->getContent());
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result += entry_size;
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGOT::reserveEntry(size_t pNum)
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t i = 0; i < pNum; ++i) {
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    GOTEntry* entry =
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      new (std::nothrow) GOTEntry(0, MipsGOTEntrySize, &m_SectionData);
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (NULL == entry)
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      llvm::report_fatal_error("Allocating new GOTEntry failed");
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_Section.setSize(m_Section.size() + MipsGOTEntrySize);
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGOT::reserveLocalEntry()
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  reserveEntry(1);
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ++m_pLocalNum;
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Move global entries iterator forward.
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // We need to put global GOT entries after all local ones.
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ++m_GlobalGOTIterator;
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MipsGOT::reserveGlobalEntry()
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  reserveEntry(1);
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoGOTEntry* MipsGOT::getEntry(const ResolveInfo& pInfo, bool& pExist)
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  GOTEntry*& entry = m_GeneralGOTMap[&pInfo];
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pExist = NULL != entry;
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!pExist) {
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    iterator& it = pInfo.isLocal() ? m_LocalGOTIterator : m_GlobalGOTIterator;
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++it;
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(it != m_SectionData.getFragmentList().end() &&
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           "The number of GOT Entries and ResolveInfo doesn't match");
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    entry = llvm::cast<GOTEntry>(&(*it));
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return entry;
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t MipsGOT::getTotalNum() const
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_SectionData.getFragmentList().size();
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t MipsGOT::getLocalNum() const
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pLocalNum;
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
149