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//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/RelocationFactory.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/TargetLDBackend.h" 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Host.h> 16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 17d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <cassert> 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <cstring> 19cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 22cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// RelocationFactory 24cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 25d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocationFactory::RelocationFactory() 2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines : GCFactory<Relocation, MCLD_RELOCATIONS_PER_INPUT>(), m_pConfig(NULL) { 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid RelocationFactory::setConfig(const LinkerConfig& pConfig) { 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, 3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines Address pAddend) { 3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (m_pConfig == NULL) { 37d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao fatal(diag::reloc_factory_has_not_config); 38d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return NULL; 39d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao } 40d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // target_data is the place where the relocation applys to. 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Use TargetDataFactory to generate temporary data, and copy the 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // content of the fragment into this data. 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao DWord target_data = 0; 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // byte swapping if the host and target have different endian 47551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (llvm::sys::IsLittleEndianHost != m_pConfig->targets().isLittleEndian()) { 48551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines uint32_t tmp_data; 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 50551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines switch (m_pConfig->targets().bitclass()) { 51551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines case 32: { 52551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines pFragRef.memcpy(&tmp_data, 4); 53551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines tmp_data = mcld::bswap32(tmp_data); 54551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines target_data = tmp_data; 55551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines break; 56551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 57551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines case 64: { 58551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines pFragRef.memcpy(&target_data, 8); 59551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines target_data = mcld::bswap64(target_data); 60551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines break; 61551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 62551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines default: { 63551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines fatal(diag::unsupported_bitclass) << m_pConfig->targets().triple().str() 64551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines << m_pConfig->targets().bitclass(); 65551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines return NULL; 66551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 6737b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of switch 6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 6937b74a387bb3993387029859c2d9d051c41c724eStephen Hines pFragRef.memcpy(&target_data, (m_pConfig->targets().bitclass() / 8)); 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Relocation* result = allocate(); 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao new (result) Relocation(pType, &pFragRef, pAddend, target_data); 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7737b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocation* RelocationFactory::produceEmptyEntry() { 786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Relocation* result = allocate(); 796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines new (result) Relocation(0, 0, 0, 0); 806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return result; 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid RelocationFactory::destroy(Relocation* pRelocation) { 8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines /** GCFactory will recycle the relocation **/ 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8737b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 88