//===- RelocationFactory.cpp ----------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include <mcld/LD/RelocationFactory.h> #include <cstring> #include <cassert> #include <llvm/Support/Host.h> #include <mcld/Target/GOT.h> #include <mcld/Target/TargetLDBackend.h> using namespace mcld; //===----------------------------------------------------------------------===// // RelocationFactory //===----------------------------------------------------------------------===// RelocationFactory::RelocationFactory(size_t pNum) : GCFactory<Relocation, 0>(pNum), m_pLayout(NULL) { } RelocationFactory::~RelocationFactory() { } Relocation* RelocationFactory::produce(RelocationFactory::Type pType, FragmentRef& pFragRef, Address pAddend) { // target_data is the place where the relocation applys to. // Use TargetDataFactory to generate temporary data, and copy the // content of the fragment into this data. DWord target_data = 0; // byte swapping if the host and target have different endian if(llvm::sys::isLittleEndianHost() != getTarget().isLittleEndian()) { uint32_t tmp_data; switch(getTarget().bitclass()) { case 32u: pFragRef.memcpy(&tmp_data, 4); tmp_data = bswap32(tmp_data); target_data = tmp_data; break; case 64u: pFragRef.memcpy(&target_data, 8); target_data = bswap64(target_data); break; default: break; } } else { pFragRef.memcpy(&target_data, (getTarget().bitclass()/8)); } Relocation *result = allocate(); new (result) Relocation(pType, &pFragRef, pAddend, target_data); return result; } Relocation* RelocationFactory::produceEmptyEntry() { // FIXME: To prevent relocations from double free by both iplist and // GCFactory, currently we new relocations directly and let iplist // delete them. return new Relocation(0, 0, 0, 0); } void RelocationFactory::destroy(Relocation* pRelocation) { /** GCFactory will recycle the relocation **/ } void RelocationFactory::setLayout(const Layout& pLayout) { m_pLayout = &pLayout; } const Layout& RelocationFactory::getLayout() const { assert(0 != m_pLayout); return *m_pLayout; }