Relocation.cpp revision d0fbbb227051be16931a1aa9b4a7722ac039c698
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 &&
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao     m_pSymInfo->outSymbol()->hasFragRef()) {
95cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    return m_pSymInfo->outSymbol()->fragRef()->frag()->getParent()->getSection().addr();
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pSymInfo->outSymbol()->value();
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
100d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaovoid Relocation::apply(Relocator& pRelocator)
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Relocator::Result result = pRelocator.applyRelocation(*this);
10367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
10467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  switch (result) {
105d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case Relocator::OK: {
10667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      // do nothing
10767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      return;
10867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    }
109d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case Relocator::Overflow: {
110d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      error(diag::result_overflow) << pRelocator.getName(type())
11167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                   << symInfo()->name();
11267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      return;
11367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    }
114d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case Relocator::BadReloc: {
115d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      error(diag::result_badreloc) << pRelocator.getName(type())
11667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                   << symInfo()->name();
11767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      return;
11867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    }
119d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case Relocator::Unsupport: {
12067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      fatal(diag::unsupported_relocation) << type()
12167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                          << "mclinker@googlegroups.com";
12267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      return;
12367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao    }
124d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case Relocator::Unknown: {
12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      fatal(diag::unknown_relocation) << type() << symInfo()->name();
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return;
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
12867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  } // end of switch
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Relocation::setType(Type pType)
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_Type = pType;
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Relocation::setAddend(Address pAddend)
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_Addend = pAddend;
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Relocation::setSymInfo(ResolveInfo* pSym)
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_pSymInfo = pSym;
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaosize_t Relocation::size() const
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
14822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // TODO: the size of Relocation fragment is handled by backend
14922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return 0;
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid Relocation::updateAddend()
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Update value keep in addend if we meet a section symbol
15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_pSymInfo->type() == ResolveInfo::Section) {
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    uint32_t offset = m_pSymInfo->outSymbol()->fragRef()->getOutputOffset();
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_Addend += offset;
15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
161