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 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSection.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDFileFormat.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/Support/Casting.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace { 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst unsigned int ARMGOT0Num = 3; 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // end of anonymous namespace 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ARMGOT 2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoARMGOT::ARMGOT(LDSection& pSection) 2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines : GOT(pSection), m_pGOTPLTFront(NULL), m_pGOTFront(NULL) { 2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // create GOT0, and put them into m_SectionData immediately 2887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (unsigned int i = 0; i < ARMGOT0Num; ++i) 2987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines new ARMGOTEntry(0, m_SectionData); 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3237b74a387bb3993387029859c2d9d051c41c724eStephen HinesARMGOT::~ARMGOT() { 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ARMGOT::hasGOT1() const { 3687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return ((!m_GOT.empty()) || (!m_GOTPLT.empty())); 37d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 38d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 3937b74a387bb3993387029859c2d9d051c41c724eStephen HinesARMGOTEntry* ARMGOT::createGOT() { 4087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ARMGOTEntry* entry = new ARMGOTEntry(0, NULL); 4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_GOT.push_back(entry); 4287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return entry; 43d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 44d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 4537b74a387bb3993387029859c2d9d051c41c724eStephen HinesARMGOTEntry* ARMGOT::createGOTPLT() { 4687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ARMGOTEntry* entry = new ARMGOTEntry(0, NULL); 4787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_GOTPLT.push_back(entry); 4887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return entry; 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ARMGOT::finalizeSectionSize() { 5287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t offset = 0; 5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData::FragmentListType& frag_list = m_SectionData->getFragmentList(); 5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // setup GOT0 offset 5587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData::iterator frag, fragEnd = m_SectionData->end(); 5687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (frag = m_SectionData->begin(); frag != fragEnd; ++frag) { 5787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines frag->setOffset(offset); 5887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset += frag->size(); 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // push GOTPLT into the SectionData and setup the offset 6287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!m_GOTPLT.empty()) { 6387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOTPLTFront = m_GOTPLT.front(); 6487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines entry_iterator it, end = m_GOTPLT.end(); 6587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (it = m_GOTPLT.begin(); it != end; ++it) { 6687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ARMGOTEntry* entry = *it; 6787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines frag_list.push_back(entry); 6887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines entry->setParent(m_SectionData); 6987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines entry->setOffset(offset); 7087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset += entry->size(); 7187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 7387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_GOTPLT.clear(); 7487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 7587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // push GOT into the SectionData and setup the offset 7687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (!m_GOT.empty()) { 7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_pGOTFront = m_GOT.front(); 7887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines entry_iterator it, end = m_GOT.end(); 7987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (it = m_GOT.begin(); it != end; ++it) { 8087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ARMGOTEntry* entry = *it; 8187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines frag_list.push_back(entry); 8287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines entry->setParent(m_SectionData); 8387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines entry->setOffset(offset); 8487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset += entry->size(); 8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 8787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_GOT.clear(); 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // set section size 9087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines m_Section.setSize(offset); 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ARMGOT::applyGOT0(uint64_t pAddress) { 9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::cast<ARMGOTEntry>(*(m_SectionData->getFragmentList().begin())) 9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines .setValue(pAddress); 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ARMGOT::applyGOTPLT(uint64_t pPLTBase) { 9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pGOTPLTFront == NULL) 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines SectionData::iterator entry(m_pGOTPLTFront); 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData::iterator e_end; 10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pGOTFront == NULL) 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao e_end = m_SectionData->end(); 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 10787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines e_end = SectionData::iterator(m_pGOTFront); 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao while (entry != e_end) { 110d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao llvm::cast<ARMGOTEntry>(entry)->setValue(pPLTBase); 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ++entry; 11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t ARMGOT::emit(MemoryRegion& pRegion) { 11687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin()); 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 118d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ARMGOTEntry* got = NULL; 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = 0x0; 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) { 12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines got = &(llvm::cast<ARMGOTEntry>((*it))); 12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines *buffer = static_cast<uint32_t>(got->getValue()); 12337b74a387bb3993387029859c2d9d051c41c724eStephen Hines result += ARMGOTEntry::EntrySize; 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 12837b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 129