15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- RelocationFactory.cpp ----------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/RelocationFactory.h> 10d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LinkerConfig.h> 11d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Target/TargetLDBackend.h> 12d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Support/MsgHandling.h> 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Host.h> 15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 16d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <cstring> 17d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <cassert> 18cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 21cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// RelocationFactory 23cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 24d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocationFactory::RelocationFactory() 25d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao : GCFactory<Relocation, MCLD_RELOCATIONS_PER_INPUT>(), m_pConfig(NULL) { 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 28d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaovoid RelocationFactory::setConfig(const LinkerConfig& pConfig) 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 30d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_pConfig = &pConfig; 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocation* RelocationFactory::produce(RelocationFactory::Type pType, 34cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef& pFragRef, 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Address pAddend) 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 37d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (NULL == m_pConfig) { 38d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::reloc_factory_has_not_config); 39d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return NULL; 40d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 41d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // target_data is the place where the relocation applys to. 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Use TargetDataFactory to generate temporary data, and copy the 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // content of the fragment into this data. 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao DWord target_data = 0; 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // byte swapping if the host and target have different endian 48d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if(llvm::sys::isLittleEndianHost() != m_pConfig->targets().isLittleEndian()) { 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint32_t tmp_data; 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 51d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao switch (m_pConfig->targets().bitclass()) { 52d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case 32: { 53d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pFragRef.memcpy(&tmp_data, 4); 54d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao tmp_data = mcld::bswap32(tmp_data); 55d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao target_data = tmp_data; 56d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao break; 57d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 58d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case 64: { 59d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pFragRef.memcpy(&target_data, 8); 60d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao target_data = mcld::bswap64(target_data); 61d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao break; 62d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 63d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao default: { 64d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::unsupported_bitclass) << m_pConfig->targets().triple().str() 65d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao << m_pConfig->targets().bitclass(); 66d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return NULL; 67d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 68d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } // end of switch 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 71d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pFragRef.memcpy(&target_data, (m_pConfig->targets().bitclass()/8)); 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Relocation* result = allocate(); 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao new (result) Relocation(pType, &pFragRef, pAddend, target_data); 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocation* RelocationFactory::produceEmptyEntry() 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Relocation* result = allocate(); 826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines new (result) Relocation(0, 0, 0, 0); 836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return result; 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid RelocationFactory::destroy(Relocation* pRelocation) 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /** GCFactory will recycle the relocation **/ 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 91