Relocation.cpp revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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#include <mcld/Fragment/Relocation.h> 10#include <mcld/LD/RelocationFactory.h> 11#include <mcld/LD/ResolveInfo.h> 12#include <mcld/LD/LDSymbol.h> 13#include <mcld/LD/LDSection.h> 14#include <mcld/LD/SectionData.h> 15#include <mcld/Support/MsgHandling.h> 16 17using namespace mcld; 18 19Relocation::Relocation(Relocation::Type pType, 20 FragmentRef* pTargetRef, 21 Relocation::Address pAddend, 22 Relocation::DWord pTargetData) 23 : Fragment(Fragment::Relocation), 24 m_Type(pType), 25 m_TargetData(pTargetData), 26 m_pSymInfo(NULL), 27 m_Addend(pAddend) 28{ 29 if(NULL != pTargetRef) 30 m_TargetAddress.assign(*pTargetRef->frag(), pTargetRef->offset()) ; 31} 32 33Relocation::~Relocation() 34{ 35} 36 37Relocation::Address Relocation::place() const 38{ 39 Address sect_addr = m_TargetAddress.frag()->getParent()->getSection().addr(); 40 return sect_addr + m_TargetAddress.getOutputOffset(); 41} 42 43Relocation::Address Relocation::symValue() const 44{ 45 if (m_pSymInfo->type() == ResolveInfo::Section && 46 m_pSymInfo->outSymbol()->hasFragRef()) { 47 return m_pSymInfo->outSymbol()->fragRef()->frag()->getParent()->getSection().addr(); 48 } 49 return m_pSymInfo->outSymbol()->value(); 50} 51 52void Relocation::apply(RelocationFactory& pRelocFactory) 53{ 54 RelocationFactory::Result result = pRelocFactory.applyRelocation(*this); 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 case RelocationFactory::Unknown: { 77 fatal(diag::unknown_relocation) << type() << symInfo()->name(); 78 return; 79 } 80 } // end of switch 81} 82 83void Relocation::setType(Type pType) 84{ 85 m_Type = pType; 86} 87 88void Relocation::setAddend(Address pAddend) 89{ 90 m_Addend = pAddend; 91} 92 93void Relocation::setSymInfo(ResolveInfo* pSym) 94{ 95 m_pSymInfo = pSym; 96} 97 98size_t Relocation::size() const 99{ 100 // TODO: the size of Relocation fragment is handled by backend 101 return 0; 102} 103 104void Relocation::updateAddend() 105{ 106 // Update value keep in addend if we meet a section symbol 107 if (m_pSymInfo->type() == ResolveInfo::Section) { 108 uint32_t offset = m_pSymInfo->outSymbol()->fragRef()->getOutputOffset(); 109 m_Addend += offset; 110 } 111} 112 113