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> 10d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/Relocator.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> 16d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LD/RelocationFactory.h> 17d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 18d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <llvm/Support/ManagedStatic.h> 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 22d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaostatic llvm::ManagedStatic<RelocationFactory> g_RelocationFactory; 23d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 24d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===// 25d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao// Relocation Factory Methods 26d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===// 27d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// Initialize - set up the relocation factory 28d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaovoid Relocation::SetUp(const LinkerConfig& pConfig) 29d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 30d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao g_RelocationFactory->setConfig(pConfig); 31d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 32d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 33d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// Clear - Clean up the relocation factory 34d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaovoid Relocation::Clear() 35d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 36d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao g_RelocationFactory->clear(); 37d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 38d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 39d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// Create - produce an empty relocation entry 40d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocation* Relocation::Create() 41d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 42d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return g_RelocationFactory->produceEmptyEntry(); 43d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 44d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 45d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// Create - produce a relocation entry 46d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// @param pType [in] the type of the relocation entry 47d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// @param pFragRef [in] the place to apply the relocation 48d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// @param pAddend [in] the addend of the relocation entry 49d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocation* Relocation::Create(Type pType, FragmentRef& pFragRef, Address pAddend) 50d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 51d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return g_RelocationFactory->produce(pType, pFragRef, pAddend); 52d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 53d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 54d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// Destroy - destroy a relocation entry 55d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaovoid Relocation::Destroy(Relocation*& pRelocation) 56d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{ 57d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao g_RelocationFactory->destroy(pRelocation); 58d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pRelocation = NULL; 59d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 60d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 61d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===// 62d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao// Relocation 63d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===// 64d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocation::Relocation() 65d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao : m_Type(0x0), m_TargetData(0x0), m_pSymInfo(NULL), m_Addend(0x0) { 66d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 67d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocation::Relocation(Relocation::Type pType, 69cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* pTargetRef, 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation::Address pAddend, 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation::DWord pTargetData) 72d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao : m_Type(pType), 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_TargetData(pTargetData), 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pSymInfo(NULL), 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Addend(pAddend) 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(NULL != pTargetRef) 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_TargetAddress.assign(*pTargetRef->frag(), pTargetRef->offset()) ; 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocation::~Relocation() 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoRelocation::Address Relocation::place() const 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Address sect_addr = m_TargetAddress.frag()->getParent()->getSection().addr(); 8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return sect_addr + m_TargetAddress.getOutputOffset(); 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocation::Address Relocation::symValue() const 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_pSymInfo->type() == ResolveInfo::Section && 94f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pSymInfo->outSymbol()->hasFragRef()) { 95f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const FragmentRef* fragRef = m_pSymInfo->outSymbol()->fragRef(); 96f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return fragRef->frag()->getParent()->getSection().addr() + 97f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines fragRef->getOutputOffset(); 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_pSymInfo->outSymbol()->value(); 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaovoid Relocation::apply(Relocator& pRelocator) 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 104d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao Relocator::Result result = pRelocator.applyRelocation(*this); 10567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao 10667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao switch (result) { 107d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case Relocator::OK: { 10867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao // do nothing 10967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return; 11067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 111d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case Relocator::Overflow: { 112d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao error(diag::result_overflow) << pRelocator.getName(type()) 11367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao << symInfo()->name(); 11467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return; 11567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 116d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case Relocator::BadReloc: { 117d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao error(diag::result_badreloc) << pRelocator.getName(type()) 11867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao << symInfo()->name(); 11967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return; 12067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 121d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case Relocator::Unsupport: { 12267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao fatal(diag::unsupported_relocation) << type() 12367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao << "mclinker@googlegroups.com"; 12467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return; 12567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 126d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case Relocator::Unknown: { 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unknown_relocation) << type() << symInfo()->name(); 12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 13067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } // end of switch 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Relocation::setType(Type pType) 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Type = pType; 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Relocation::setAddend(Address pAddend) 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Addend = pAddend; 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Relocation::setSymInfo(ResolveInfo* pSym) 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pSymInfo = pSym; 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesRelocation::Size Relocation::size(Relocator& pRelocator) const 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return pRelocator.getSize(m_Type); 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid Relocation::updateAddend() 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Update value keep in addend if we meet a section symbol 15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_pSymInfo->type() == ResolveInfo::Section) { 15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t offset = m_pSymInfo->outSymbol()->fragRef()->getOutputOffset(); 15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Addend += offset; 15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 161