• 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/Target/GOT.h>
11 #include <mcld/Target/TargetLDBackend.h>
12 #include <llvm/Support/Host.h>
13 #include <cstring>
14 #include <cassert>
15 
16 using namespace mcld;
17 
18 //==========================
19 // RelocationFactory
RelocationFactory(size_t pNum)20 RelocationFactory::RelocationFactory(size_t pNum)
21   : GCFactory<Relocation, 0>(pNum),
22     m_pLayout(NULL) {
23 }
24 
~RelocationFactory()25 RelocationFactory::~RelocationFactory()
26 {
27 }
28 
produce(RelocationFactory::Type pType,MCFragmentRef & pFragRef,Address pAddend)29 Relocation* RelocationFactory::produce(RelocationFactory::Type pType,
30                                        MCFragmentRef& pFragRef,
31                                        Address pAddend)
32 {
33   // target_data is the place where the relocation applys to.
34   // Use TargetDataFactory to generate temporary data, and copy the
35   // content of the fragment into this data.
36   DWord target_data = 0;
37 
38   // byte swapping if the host and target have different endian
39   if(llvm::sys::isLittleEndianHost() != getTarget().isLittleEndian()) {
40      uint32_t tmp_data;
41 
42      switch(getTarget().bitclass()) {
43       case 32u:
44         pFragRef.memcpy(&tmp_data, 4);
45         tmp_data = bswap32(tmp_data);
46         target_data = tmp_data;
47         break;
48 
49       case 64u:
50         pFragRef.memcpy(&target_data, 8);
51         target_data = bswap64(target_data);
52         break;
53 
54       default:
55         break;
56     }
57   }
58   else {
59     pFragRef.memcpy(&target_data, (getTarget().bitclass()/8));
60   }
61 
62   Relocation *result = allocate();
63   new (result) Relocation(pType, &pFragRef, pAddend, target_data);
64   return result;
65 }
66 
produceEmptyEntry()67 Relocation* RelocationFactory::produceEmptyEntry()
68 {
69   // FIXME: To prevent relocations from double free by both iplist and
70   // GCFactory, currently we new relocations directly and let iplist
71   // delete them.
72 
73   return new Relocation(0, 0, 0, 0);
74 }
75 
destroy(Relocation * pRelocation)76 void RelocationFactory::destroy(Relocation* pRelocation)
77 {
78    /** GCFactory will recycle the relocation **/
79 }
80 
setLayout(const Layout & pLayout)81 void RelocationFactory::setLayout(const Layout& pLayout)
82 {
83   m_pLayout = &pLayout;
84 }
85 
getLayout() const86 const Layout& RelocationFactory::getLayout() const
87 {
88   assert(0 != m_pLayout);
89   return *m_pLayout;
90 }
91 
92