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