//===- Relocation.cpp -----------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include <mcld/LD/Relocation.h> #include <mcld/LD/RelocationFactory.h> #include <mcld/LD/Layout.h> #include <mcld/Support/MsgHandling.h> using namespace mcld; Relocation::Relocation(Relocation::Type pType, FragmentRef* pTargetRef, Relocation::Address pAddend, Relocation::DWord pTargetData) : Fragment(Fragment::Relocation), m_Type(pType), m_TargetData(pTargetData), m_pSymInfo(NULL), m_Addend(pAddend) { if(NULL != pTargetRef) m_TargetAddress.assign(*pTargetRef->frag(), pTargetRef->offset()) ; } Relocation::~Relocation() { } Relocation::Address Relocation::place(const Layout& pLayout) const { Address sect_addr = pLayout.getOutputLDSection(*(m_TargetAddress.frag()))->addr(); return sect_addr + pLayout.getOutputOffset(m_TargetAddress); } Relocation::Address Relocation::symValue() const { if (m_pSymInfo->type() == ResolveInfo::Section && m_pSymInfo->outSymbol()->hasFragRef()) { return m_pSymInfo->outSymbol()->fragRef()->frag()->getParent()->getSection().addr(); } return m_pSymInfo->outSymbol()->value(); } void Relocation::apply(RelocationFactory& pRelocFactory, const MCLDInfo& pLDInfo) { RelocationFactory::Result result = pRelocFactory.applyRelocation(*this, pLDInfo); switch (result) { case RelocationFactory::OK: { // do nothing return; } case RelocationFactory::Overflow: { error(diag::result_overflow) << pRelocFactory.getName(type()) << symInfo()->name(); return; } case RelocationFactory::BadReloc: { error(diag::result_badreloc) << pRelocFactory.getName(type()) << symInfo()->name(); return; } case RelocationFactory::Unsupport: { fatal(diag::unsupported_relocation) << type() << "mclinker@googlegroups.com"; return; } } // end of switch } void Relocation::setType(Type pType) { m_Type = pType; } void Relocation::setAddend(Address pAddend) { m_Addend = pAddend; } void Relocation::setSymInfo(ResolveInfo* pSym) { m_pSymInfo = pSym; } Relocation::DWord& Relocation::target() { return m_TargetData; } const Relocation::DWord& Relocation::target() const { return m_TargetData; }