• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 using namespace mcld;
20 
21 //===----------------------------------------------------------------------===//
22 // RelocationFactory
23 //===----------------------------------------------------------------------===//
RelocationFactory()24 RelocationFactory::RelocationFactory()
25   : GCFactory<Relocation, MCLD_RELOCATIONS_PER_INPUT>(), m_pConfig(NULL) {
26 }
27 
setConfig(const LinkerConfig & pConfig)28 void RelocationFactory::setConfig(const LinkerConfig& pConfig)
29 {
30   m_pConfig = &pConfig;
31 }
32 
produce(RelocationFactory::Type pType,FragmentRef & pFragRef,Address pAddend)33 Relocation* 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 
produceEmptyEntry()79 Relocation* RelocationFactory::produceEmptyEntry()
80 {
81   Relocation* result = allocate();
82   new (result) Relocation(0, 0, 0, 0);
83   return result;
84 }
85 
destroy(Relocation * pRelocation)86 void RelocationFactory::destroy(Relocation* pRelocation)
87 {
88    /** GCFactory will recycle the relocation **/
89 }
90 
91