• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- 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 //===----------------------------------------------------------------------===//
9 
10 #include <mcld/LD/Relocation.h>
11 #include <mcld/LD/RelocationFactory.h>
12 #include <mcld/LD/Layout.h>
13 #include <mcld/Support/MsgHandling.h>
14 
15 using namespace mcld;
16 
Relocation(Relocation::Type pType,FragmentRef * pTargetRef,Relocation::Address pAddend,Relocation::DWord pTargetData)17 Relocation::Relocation(Relocation::Type pType,
18                        FragmentRef* pTargetRef,
19                        Relocation::Address pAddend,
20                        Relocation::DWord pTargetData)
21   : Fragment(Fragment::Relocation),
22     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 
~Relocation()31 Relocation::~Relocation()
32 {
33 }
34 
place(const Layout & pLayout) const35 Relocation::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 
symValue() const41 Relocation::Address Relocation::symValue() const
42 {
43   if (m_pSymInfo->type() == ResolveInfo::Section &&
44      m_pSymInfo->outSymbol()->hasFragRef()) {
45     return m_pSymInfo->outSymbol()->fragRef()->frag()->getParent()->getSection().addr();
46   }
47   return m_pSymInfo->outSymbol()->value();
48 }
49 
apply(RelocationFactory & pRelocFactory,const MCLDInfo & pLDInfo)50 void Relocation::apply(RelocationFactory& pRelocFactory,
51                        const MCLDInfo& pLDInfo)
52 {
53   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
77 }
78 
setType(Type pType)79 void Relocation::setType(Type pType)
80 {
81   m_Type = pType;
82 }
83 
setAddend(Address pAddend)84 void Relocation::setAddend(Address pAddend)
85 {
86   m_Addend = pAddend;
87 }
88 
setSymInfo(ResolveInfo * pSym)89 void Relocation::setSymInfo(ResolveInfo* pSym)
90 {
91   m_pSymInfo = pSym;
92 }
93 
target()94 Relocation::DWord& Relocation::target()
95 {
96   return m_TargetData;
97 }
98 
target() const99 const Relocation::DWord& Relocation::target() const
100 {
101   return m_TargetData;
102 }
103 
104