Relocation.cpp revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- Relocation.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//===----------------------------------------------------------------------===// 922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/Relocation.h> 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/RelocationFactory.h> 1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ResolveInfo.h> 1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSymbol.h> 1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/LDSection.h> 1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/SectionData.h> 1567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <mcld/Support/MsgHandling.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocation::Relocation(Relocation::Type pType, 20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* pTargetRef, 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation::Address pAddend, 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation::DWord pTargetData) 23cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao : Fragment(Fragment::Relocation), 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Type(pType), 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_TargetData(pTargetData), 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pSymInfo(NULL), 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Addend(pAddend) 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(NULL != pTargetRef) 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_TargetAddress.assign(*pTargetRef->frag(), pTargetRef->offset()) ; 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocation::~Relocation() 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoRelocation::Address Relocation::place() const 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Address sect_addr = m_TargetAddress.frag()->getParent()->getSection().addr(); 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return sect_addr + m_TargetAddress.getOutputOffset(); 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocation::Address Relocation::symValue() const 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 45affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_pSymInfo->type() == ResolveInfo::Section && 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pSymInfo->outSymbol()->hasFragRef()) { 47cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao return m_pSymInfo->outSymbol()->fragRef()->frag()->getParent()->getSection().addr(); 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_pSymInfo->outSymbol()->value(); 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid Relocation::apply(RelocationFactory& pRelocFactory) 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao RelocationFactory::Result result = pRelocFactory.applyRelocation(*this); 5567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao 5667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao switch (result) { 5767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao case RelocationFactory::OK: { 5867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao // do nothing 5967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return; 6067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 6167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao case RelocationFactory::Overflow: { 6267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao error(diag::result_overflow) << pRelocFactory.getName(type()) 6367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao << symInfo()->name(); 6467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return; 6567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 6667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao case RelocationFactory::BadReloc: { 6767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao error(diag::result_badreloc) << pRelocFactory.getName(type()) 6867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao << symInfo()->name(); 6967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return; 7067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 7167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao case RelocationFactory::Unsupport: { 7267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao fatal(diag::unsupported_relocation) << type() 7367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao << "mclinker@googlegroups.com"; 7467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return; 7567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case RelocationFactory::Unknown: { 7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unknown_relocation) << type() << symInfo()->name(); 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 8067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } // end of switch 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Relocation::setType(Type pType) 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Type = pType; 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Relocation::setAddend(Address pAddend) 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Addend = pAddend; 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Relocation::setSymInfo(ResolveInfo* pSym) 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pSymInfo = pSym; 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaosize_t Relocation::size() const 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // TODO: the size of Relocation fragment is handled by backend 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return 0; 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid Relocation::updateAddend() 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Update value keep in addend if we meet a section symbol 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_pSymInfo->type() == ResolveInfo::Section) { 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t offset = m_pSymInfo->outSymbol()->fragRef()->getOutputOffset(); 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Addend += offset; 11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 113