1551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===- ARMGOT.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#include "ARMGOT.h" 10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h> 12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSection.h> 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDFileFormat.h> 15affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace { 1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const unsigned int ARMGOT0Num = 3; 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // end of anonymous namespace 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ARMGOT 2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoARMGOT::ARMGOT(LDSection& pSection) 2687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines : GOT(pSection), m_pGOTPLTFront(NULL), m_pGOTFront(NULL) 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // create GOT0, and put them into m_SectionData immediately 2987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (unsigned int i = 0; i < ARMGOT0Num; ++i) 3087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines new ARMGOTEntry(0, m_SectionData); 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoARMGOT::~ARMGOT() 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ARMGOT::hasGOT1() const 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return ((!m_GOT.empty()) || (!m_GOTPLT.empty())); 40d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 41d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 4287f34658dec9097d987d254a990ea7f311bfc95fStephen HinesARMGOTEntry* ARMGOT::createGOT() 43d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 4487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ARMGOTEntry* entry = new ARMGOTEntry(0, NULL); 4587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_GOT.push_back(entry); 4687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return entry; 47d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 48d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 4987f34658dec9097d987d254a990ea7f311bfc95fStephen HinesARMGOTEntry* ARMGOT::createGOTPLT() 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ARMGOTEntry* entry = new ARMGOTEntry(0, NULL); 5287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_GOTPLT.push_back(entry); 5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return entry; 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5687f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid ARMGOT::finalizeSectionSize() 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t offset = 0; 5987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData::FragmentListType& frag_list = m_SectionData->getFragmentList(); 6087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // setup GOT0 offset 6187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData::iterator frag, fragEnd = m_SectionData->end(); 6287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (frag = m_SectionData->begin(); frag != fragEnd; ++frag) { 6387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines frag->setOffset(offset); 6487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset += frag->size(); 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // push GOTPLT into the SectionData and setup the offset 6887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!m_GOTPLT.empty()) { 6987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOTPLTFront = m_GOTPLT.front(); 7087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines entry_iterator it, end = m_GOTPLT.end(); 7187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (it = m_GOTPLT.begin(); it != end; ++it) { 7287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ARMGOTEntry* entry = *it; 7387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines frag_list.push_back(entry); 7487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines entry->setParent(m_SectionData); 7587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines entry->setOffset(offset); 7687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset += entry->size(); 7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 7987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_GOTPLT.clear(); 8087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 8187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // push GOT into the SectionData and setup the offset 8287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!m_GOT.empty()) { 8387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOTFront = m_GOT.front(); 8487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines entry_iterator it, end = m_GOT.end(); 8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (it = m_GOT.begin(); it != end; ++it) { 8687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ARMGOTEntry* entry = *it; 8787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines frag_list.push_back(entry); 8887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines entry->setParent(m_SectionData); 8987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines entry->setOffset(offset); 9087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset += entry->size(); 9187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 9387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_GOT.clear(); 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set section size 9687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_Section.setSize(offset); 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid ARMGOT::applyGOT0(uint64_t pAddress) 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 101d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao llvm::cast<ARMGOTEntry> 102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (*(m_SectionData->getFragmentList().begin())).setValue(pAddress); 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid ARMGOT::applyGOTPLT(uint64_t pPLTBase) 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 10787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (NULL == m_pGOTPLTFront) 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData::iterator entry(m_pGOTPLTFront); 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData::iterator e_end; 11287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (NULL == m_pGOTFront) 11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao e_end = m_SectionData->end(); 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 11587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines e_end = SectionData::iterator(m_pGOTFront); 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao while (entry != e_end) { 118d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao llvm::cast<ARMGOTEntry>(entry)->setValue(pPLTBase); 11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++entry; 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ARMGOT::emit(MemoryRegion& pRegion) 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 12587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 127d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ARMGOTEntry* got = NULL; 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = 0x0; 12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) { 130d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao got = &(llvm::cast<ARMGOTEntry>((*it))); 131d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao *buffer = static_cast<uint32_t>(got->getValue()); 132d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao result += ARMGOTEntry::EntrySize; 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 137