FragmentRef.cpp revision f7ac0f19a1c8d0ad14bcf6456ce368b830fea886
1cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===- FragmentRef.cpp --------------------------------------------------===// 2cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// 3cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// The MCLinker Project 4cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// 5cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// This file is distributed under the University of Illinois Open Source 6cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// License. See LICENSE.TXT for details. 7cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// 8cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentRef.h> 10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cstring> 12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cassert> 13cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h> 1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/ManagedStatic.h> 16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/Fragment.h> 1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSection.h> 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/SectionData.h> 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrame.h> 2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/GCFactory.h> 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/RegionFragment.h> 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/Stub.h> 25cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 26cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaousing namespace mcld; 27cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaotypedef GCFactory<FragmentRef, MCLD_SECTIONS_PER_INPUT> FragRefFactory; 29cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaostatic llvm::ManagedStatic<FragRefFactory> g_FragRefFactory; 31cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoFragmentRef FragmentRef::g_NullFragmentRef; 33cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 34cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 35cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// FragmentRef 36cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 37cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoFragmentRef::FragmentRef() 38cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao : m_pFragment(NULL), m_Offset(0) { 39cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 40cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 41cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoFragmentRef::FragmentRef(Fragment& pFrag, 42cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef::Offset pOffset) 43cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao : m_pFragment(&pFrag), m_Offset(pOffset) { 44cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 45cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// Create - create a fragment reference for a given fragment. 4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// 4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @param pFrag - the given fragment 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @param pOffset - the offset, can be larger than the fragment, but can not 5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// be larger than the section size. 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// @return if the offset is legal, return the fragment reference. Otherwise, 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// return NULL. 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoFragmentRef* FragmentRef::Create(Fragment& pFrag, uint64_t pOffset) 54cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao int64_t offset = pOffset; 5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Fragment* frag = &pFrag; 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao while (NULL != frag) { 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao offset -= frag->size(); 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (offset <= 0) 6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao frag = frag->getNextNode(); 6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == frag) 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Null(); 6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentRef* result = g_FragRefFactory->allocate(); 7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao new (result) FragmentRef(*frag, offset + frag->size()); 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return result; 7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoFragmentRef* FragmentRef::Create(LDSection& pSection, uint64_t pOffset) 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao SectionData* data = NULL; 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (pSection.kind()) { 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Relocation: 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // No fragment reference refers to a relocation section 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::EhFrame: 8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pSection.hasEhFrame()) 84f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines data = pSection.getEhFrame()->getSectionData(); 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao data = pSection.getSectionData(); 8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == data || data->empty()) { 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Null(); 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Create(data->front(), pOffset); 9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid FragmentRef::Clear() 9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao g_FragRefFactory->clear(); 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoFragmentRef* FragmentRef::Null() 10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return &g_NullFragmentRef; 106cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 107cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 108cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoFragmentRef& FragmentRef::assign(const FragmentRef& pCopy) 109cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 110cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao m_pFragment = const_cast<Fragment*>(pCopy.m_pFragment); 111cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao m_Offset = pCopy.m_Offset; 112cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return *this; 113cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 114cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 115cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoFragmentRef& FragmentRef::assign(Fragment& pFrag, FragmentRef::Offset pOffset) 116cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 117cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao m_pFragment = &pFrag; 118cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao m_Offset = pOffset; 119cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return *this; 120cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 121cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 122cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaovoid FragmentRef::memcpy(void* pDest, size_t pNBytes, Offset pOffset) const 123cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 124cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // check if the offset is still in a legal range. 125cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (NULL == m_pFragment) 126cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return; 127cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao unsigned int total_offset = m_Offset + pOffset; 128cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao switch(m_pFragment->getKind()) { 129cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Region: { 130cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao RegionFragment* region_frag = static_cast<RegionFragment*>(m_pFragment); 131cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao unsigned int total_length = region_frag->getRegion().size(); 132cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (total_length < (total_offset+pNBytes)) 133cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pNBytes = total_length - total_offset; 134cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 135cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao std::memcpy(pDest, region_frag->getRegion().getBuffer(total_offset), pNBytes); 136cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return; 137cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case Fragment::Stub: { 13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Stub* stub_frag = static_cast<Stub*>(m_pFragment); 14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao unsigned int total_length = stub_frag->size(); 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (total_length < (total_offset+pNBytes)) 14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pNBytes = total_length - total_offset; 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao std::memcpy(pDest, stub_frag->getContent() + total_offset, pNBytes); 14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 146cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Alignment: 147cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Fillment: 148cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao default: 149cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return; 150cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 151cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 152cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 153cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoFragmentRef::Address FragmentRef::deref() 154cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 155cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (NULL == m_pFragment) 156cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return NULL; 157cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao Address base = NULL; 158cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao switch(m_pFragment->getKind()) { 159cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Region: 160cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao base = static_cast<RegionFragment*>(m_pFragment)->getRegion().getBuffer(); 161cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao break; 162cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Alignment: 163cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Fillment: 164cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao default: 165cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return NULL; 166cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 167cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return base + m_Offset; 168cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 169cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 170cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoFragmentRef::ConstAddress FragmentRef::deref() const 171cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 172cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if (NULL == m_pFragment) 173cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return NULL; 174cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao ConstAddress base = NULL; 175cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao switch(m_pFragment->getKind()) { 176cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Region: 177cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao base = static_cast<const RegionFragment*>(m_pFragment)->getRegion().getBuffer(); 178cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao break; 179cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Alignment: 180cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Fillment: 181cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao default: 182cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return NULL; 183cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 184cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return base + m_Offset; 185cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 186cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoFragmentRef::Offset FragmentRef::getOutputOffset() const 18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Offset result = 0; 19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL != m_pFragment) 19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result = m_pFragment->getOffset(); 19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return (result + m_Offset); 19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 195