RelocationFactory.cpp revision d0fbbb227051be16931a1aa9b4a7722ac039c698
1//===- RelocationFactory.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/LD/RelocationFactory.h> 10#include <mcld/LinkerConfig.h> 11#include <mcld/Target/TargetLDBackend.h> 12#include <mcld/Support/MsgHandling.h> 13 14#include <llvm/Support/Host.h> 15 16#include <cstring> 17#include <cassert> 18 19using namespace mcld; 20 21//===----------------------------------------------------------------------===// 22// RelocationFactory 23//===----------------------------------------------------------------------===// 24RelocationFactory::RelocationFactory() 25 : GCFactory<Relocation, MCLD_RELOCATIONS_PER_INPUT>(), m_pConfig(NULL) { 26} 27 28void RelocationFactory::setConfig(const LinkerConfig& pConfig) 29{ 30 m_pConfig = &pConfig; 31} 32 33Relocation* RelocationFactory::produce(RelocationFactory::Type pType, 34 FragmentRef& pFragRef, 35 Address pAddend) 36{ 37 if (NULL == m_pConfig) { 38 fatal(diag::reloc_factory_has_not_config); 39 return NULL; 40 } 41 42 // target_data is the place where the relocation applys to. 43 // Use TargetDataFactory to generate temporary data, and copy the 44 // content of the fragment into this data. 45 DWord target_data = 0; 46 47 // byte swapping if the host and target have different endian 48 if(llvm::sys::isLittleEndianHost() != m_pConfig->targets().isLittleEndian()) { 49 uint32_t tmp_data; 50 51 switch (m_pConfig->targets().bitclass()) { 52 case 32: { 53 pFragRef.memcpy(&tmp_data, 4); 54 tmp_data = mcld::bswap32(tmp_data); 55 target_data = tmp_data; 56 break; 57 } 58 case 64: { 59 pFragRef.memcpy(&target_data, 8); 60 target_data = mcld::bswap64(target_data); 61 break; 62 } 63 default: { 64 fatal(diag::unsupported_bitclass) << m_pConfig->targets().triple().str() 65 << m_pConfig->targets().bitclass(); 66 return NULL; 67 } 68 } // end of switch 69 } 70 else { 71 pFragRef.memcpy(&target_data, (m_pConfig->targets().bitclass()/8)); 72 } 73 74 Relocation *result = allocate(); 75 new (result) Relocation(pType, &pFragRef, pAddend, target_data); 76 return result; 77} 78 79Relocation* RelocationFactory::produceEmptyEntry() 80{ 81 // FIXME: To prevent relocations from double free by both iplist and 82 // GCFactory, currently we new relocations directly and let iplist 83 // delete them. 84 85 return new Relocation(0, 0, 0, 0); 86} 87 88void RelocationFactory::destroy(Relocation* pRelocation) 89{ 90 /** GCFactory will recycle the relocation **/ 91} 92 93