blob: 0c95e0632947a18c5fa351f284cea8854a5cc7dc [file] [log] [blame]
Shih-wei Liao5460a1f2012-03-16 22:41:16 -07001//===- Relocation.cpp -----------------------------------------------------===//
2//
3// The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Shih-wei Liaocedee4b2012-08-02 23:13:03 -07009
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070010#include <mcld/LD/Relocation.h>
11#include <mcld/LD/RelocationFactory.h>
12#include <mcld/LD/Layout.h>
Shih-wei Liao67e37f12012-07-27 03:50:34 -070013#include <mcld/Support/MsgHandling.h>
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070014
15using namespace mcld;
16
17Relocation::Relocation(Relocation::Type pType,
Shih-wei Liaocedee4b2012-08-02 23:13:03 -070018 FragmentRef* pTargetRef,
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070019 Relocation::Address pAddend,
20 Relocation::DWord pTargetData)
Shih-wei Liaocedee4b2012-08-02 23:13:03 -070021 : Fragment(Fragment::Relocation),
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070022 m_Type(pType),
23 m_TargetData(pTargetData),
24 m_pSymInfo(NULL),
25 m_Addend(pAddend)
26{
27 if(NULL != pTargetRef)
28 m_TargetAddress.assign(*pTargetRef->frag(), pTargetRef->offset()) ;
29}
30
31Relocation::~Relocation()
32{
33}
34
35Relocation::Address Relocation::place(const Layout& pLayout) const
36{
37 Address sect_addr = pLayout.getOutputLDSection(*(m_TargetAddress.frag()))->addr();
38 return sect_addr + pLayout.getOutputOffset(m_TargetAddress);
39}
40
41Relocation::Address Relocation::symValue() const
42{
Zonr Changaffc1502012-07-16 14:28:23 +080043 if (m_pSymInfo->type() == ResolveInfo::Section &&
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070044 m_pSymInfo->outSymbol()->hasFragRef()) {
Shih-wei Liaocedee4b2012-08-02 23:13:03 -070045 return m_pSymInfo->outSymbol()->fragRef()->frag()->getParent()->getSection().addr();
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070046 }
47 return m_pSymInfo->outSymbol()->value();
48}
49
50void Relocation::apply(RelocationFactory& pRelocFactory,
51 const MCLDInfo& pLDInfo)
52{
Shih-wei Liao67e37f12012-07-27 03:50:34 -070053 RelocationFactory::Result result =
54 pRelocFactory.applyRelocation(*this, pLDInfo);
55
56 switch (result) {
57 case RelocationFactory::OK: {
58 // do nothing
59 return;
60 }
61 case RelocationFactory::Overflow: {
62 error(diag::result_overflow) << pRelocFactory.getName(type())
63 << symInfo()->name();
64 return;
65 }
66 case RelocationFactory::BadReloc: {
67 error(diag::result_badreloc) << pRelocFactory.getName(type())
68 << symInfo()->name();
69 return;
70 }
71 case RelocationFactory::Unsupport: {
72 fatal(diag::unsupported_relocation) << type()
73 << "mclinker@googlegroups.com";
74 return;
75 }
76 } // end of switch
Shih-wei Liao5460a1f2012-03-16 22:41:16 -070077}
78
79void Relocation::setType(Type pType)
80{
81 m_Type = pType;
82}
83
84void Relocation::setAddend(Address pAddend)
85{
86 m_Addend = pAddend;
87}
88
89void Relocation::setSymInfo(ResolveInfo* pSym)
90{
91 m_pSymInfo = pSym;
92}
93
94Relocation::DWord& Relocation::target()
95{
96 return m_TargetData;
97}
98
99const Relocation::DWord& Relocation::target() const
100{
101 return m_TargetData;
102}
103