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