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