RelocationFactory.cpp revision cedee4b38f4786845183be7f5916dd520a170ae0
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
20using namespace mcld;
21
22//===----------------------------------------------------------------------===//
23// RelocationFactory
24//===----------------------------------------------------------------------===//
25RelocationFactory::RelocationFactory(size_t pNum)
26  : GCFactory<Relocation, 0>(pNum),
27    m_pLayout(NULL) {
28}
29
30RelocationFactory::~RelocationFactory()
31{
32}
33
34Relocation* 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
72Relocation* 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
81void RelocationFactory::destroy(Relocation* pRelocation)
82{
83   /** GCFactory will recycle the relocation **/
84}
85
86void RelocationFactory::setLayout(const Layout& pLayout)
87{
88  m_pLayout = &pLayout;
89}
90
91const Layout& RelocationFactory::getLayout() const
92{
93  assert(0 != m_pLayout);
94  return *m_pLayout;
95}
96
97