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//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Relocation.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSection.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSymbol.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/RelocationFactory.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/Relocator.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ResolveInfo.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/SectionData.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 18d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 19d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <llvm/Support/ManagedStatic.h> 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 23d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaostatic llvm::ManagedStatic<RelocationFactory> g_RelocationFactory; 24d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 25d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===// 26d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao// Relocation Factory Methods 27d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===// 28d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// Initialize - set up the relocation factory 2937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Relocation::SetUp(const LinkerConfig& pConfig) { 30d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao g_RelocationFactory->setConfig(pConfig); 31d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 32d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 33d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// Clear - Clean up the relocation factory 3437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Relocation::Clear() { 35d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao g_RelocationFactory->clear(); 36d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 37d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 38d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// Create - produce an empty relocation entry 3937b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocation* Relocation::Create() { 40d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return g_RelocationFactory->produceEmptyEntry(); 41d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 42d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 43d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// Create - produce a relocation entry 44d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// @param pType [in] the type of the relocation entry 45d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// @param pFragRef [in] the place to apply the relocation 46d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// @param pAddend [in] the addend of the relocation entry 4737b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocation* Relocation::Create(Type pType, 4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines FragmentRef& pFragRef, 4937b74a387bb3993387029859c2d9d051c41c724eStephen Hines Address pAddend) { 50d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return g_RelocationFactory->produce(pType, pFragRef, pAddend); 51d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 52d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 53d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// Destroy - destroy a relocation entry 5437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Relocation::Destroy(Relocation*& pRelocation) { 55d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao g_RelocationFactory->destroy(pRelocation); 56d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pRelocation = NULL; 57d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 58d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 59d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===// 60d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao// Relocation 61d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===// 62d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocation::Relocation() 6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines : m_Type(0x0), m_TargetData(0x0), m_pSymInfo(NULL), m_Addend(0x0) { 64d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao} 65d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocation::Relocation(Relocation::Type pType, 67cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* pTargetRef, 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation::Address pAddend, 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation::DWord pTargetData) 7037b74a387bb3993387029859c2d9d051c41c724eStephen Hines : m_Type(pType), 7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_TargetData(pTargetData), 7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_pSymInfo(NULL), 7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_Addend(pAddend) { 7437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pTargetRef != NULL) 7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines m_TargetAddress.assign(*pTargetRef->frag(), pTargetRef->offset()); 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7837b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocation::~Relocation() { 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8137b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocation::Address Relocation::place() const { 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Address sect_addr = m_TargetAddress.frag()->getParent()->getSection().addr(); 8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return sect_addr + m_TargetAddress.getOutputOffset(); 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8637b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocation::Address Relocation::symValue() const { 87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (m_pSymInfo->type() == ResolveInfo::Section && 88f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_pSymInfo->outSymbol()->hasFragRef()) { 89f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const FragmentRef* fragRef = m_pSymInfo->outSymbol()->fragRef(); 90f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return fragRef->frag()->getParent()->getSection().addr() + 91f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines fragRef->getOutputOffset(); 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_pSymInfo->outSymbol()->value(); 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Relocation::apply(Relocator& pRelocator) { 97d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao Relocator::Result result = pRelocator.applyRelocation(*this); 9867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao 9967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao switch (result) { 100d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case Relocator::OK: { 10167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao // do nothing 10267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return; 10367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 104d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case Relocator::Overflow: { 105d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao error(diag::result_overflow) << pRelocator.getName(type()) 10667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao << symInfo()->name(); 10767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return; 10867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 109d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case Relocator::BadReloc: { 110d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao error(diag::result_badreloc) << pRelocator.getName(type()) 11167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao << symInfo()->name(); 11267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return; 11367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 11437b74a387bb3993387029859c2d9d051c41c724eStephen Hines case Relocator::Unsupported: { 11567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao fatal(diag::unsupported_relocation) << type() 11667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao << "mclinker@googlegroups.com"; 11767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao return; 11867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao } 119d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case Relocator::Unknown: { 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::unknown_relocation) << type() << symInfo()->name(); 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 12337b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 12637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Relocation::setType(Type pType) { 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Type = pType; 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Relocation::setAddend(Address pAddend) { 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Addend = pAddend; 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Relocation::setSymInfo(ResolveInfo* pSym) { 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pSymInfo = pSym; 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13837b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocation::Size Relocation::size(Relocator& pRelocator) const { 1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return pRelocator.getSize(m_Type); 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Relocation::updateAddend() { 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Update value keep in addend if we meet a section symbol 14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_pSymInfo->type() == ResolveInfo::Section) { 14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t offset = m_pSymInfo->outSymbol()->fragRef()->getOutputOffset(); 14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Addend += offset; 14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 14937b74a387bb3993387029859c2d9d051c41c724eStephen Hines 15037b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 151