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