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