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