HexagonLDBackend.cpp revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
1//===- HexagonLDBackend.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 "Hexagon.h"
10#include "HexagonELFDynamic.h"
11#include "HexagonLDBackend.h"
12#include "HexagonRelocator.h"
13#include "HexagonGNUInfo.h"
14
15#include <llvm/ADT/Triple.h>
16#include <llvm/Support/Casting.h>
17
18#include <mcld/LinkerConfig.h>
19#include <mcld/IRBuilder.h>
20#include <mcld/Fragment/FillFragment.h>
21#include <mcld/Fragment/RegionFragment.h>
22#include <mcld/Support/MemoryRegion.h>
23#include <mcld/Support/MsgHandling.h>
24#include <mcld/Support/TargetRegistry.h>
25#include <mcld/Object/ObjectBuilder.h>
26
27#include <cstring>
28
29using namespace mcld;
30
31//===----------------------------------------------------------------------===//
32// HexagonLDBackend
33//===----------------------------------------------------------------------===//
34HexagonLDBackend::HexagonLDBackend(const LinkerConfig& pConfig,
35                                   HexagonGNUInfo* pInfo)
36  : GNULDBackend(pConfig, pInfo),
37    m_pRelocator(NULL),
38    m_pGOT(NULL),
39    m_pPLT(NULL),
40    m_pRelDyn(NULL),
41    m_pRelPLT(NULL),
42    m_pDynamic(NULL),
43    m_pGOTSymbol(NULL) {
44}
45
46HexagonLDBackend::~HexagonLDBackend()
47{
48  delete m_pRelocator;
49  delete m_pGOT;
50  delete m_pPLT;
51  delete m_pRelDyn;
52  delete m_pRelPLT;
53  delete m_pDynamic;
54}
55
56bool HexagonLDBackend::initRelocator()
57{
58  if (NULL == m_pRelocator) {
59    m_pRelocator = new HexagonRelocator(*this);
60  }
61  return true;
62}
63
64Relocator* HexagonLDBackend::getRelocator()
65{
66  assert(NULL != m_pRelocator);
67  return m_pRelocator;
68}
69
70void HexagonLDBackend::doPreLayout(IRBuilder& pBuilder)
71{
72  // initialize .dynamic data
73  if (!config().isCodeStatic() && NULL == m_pDynamic)
74    m_pDynamic = new HexagonELFDynamic(*this, config());
75}
76
77void HexagonLDBackend::doPostLayout(Module& pModule, IRBuilder& pBuilder)
78{
79}
80
81/// dynamic - the dynamic section of the target machine.
82/// Use co-variant return type to return its own dynamic section.
83HexagonELFDynamic& HexagonLDBackend::dynamic()
84{
85  assert(NULL != m_pDynamic);
86  return *m_pDynamic;
87}
88
89/// dynamic - the dynamic section of the target machine.
90/// Use co-variant return type to return its own dynamic section.
91const HexagonELFDynamic& HexagonLDBackend::dynamic() const
92{
93  assert(NULL != m_pDynamic);
94  return *m_pDynamic;
95}
96
97void HexagonLDBackend::scanRelocation(Relocation& pReloc,
98                                      IRBuilder& pBuilder,
99                                      Module& pModule,
100                                      LDSection& pSection)
101{
102  pReloc.updateAddend();
103}
104
105uint64_t HexagonLDBackend::emitSectionData(const LDSection& pSection,
106                                          MemoryRegion& pRegion) const
107{
108  return 0;
109}
110
111HexagonGOT& HexagonLDBackend::getGOT()
112{
113  assert(NULL != m_pGOT);
114  return *m_pGOT;
115}
116
117const HexagonGOT& HexagonLDBackend::getGOT() const
118{
119  assert(NULL != m_pGOT);
120  return *m_pGOT;
121}
122
123HexagonPLT& HexagonLDBackend::getPLT()
124{
125  assert(NULL != m_pPLT && "PLT section not exist");
126  return *m_pPLT;
127}
128
129const HexagonPLT& HexagonLDBackend::getPLT() const
130{
131  assert(NULL != m_pPLT && "PLT section not exist");
132  return *m_pPLT;
133}
134
135OutputRelocSection& HexagonLDBackend::getRelDyn()
136{
137  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
138  return *m_pRelDyn;
139}
140
141const OutputRelocSection& HexagonLDBackend::getRelDyn() const
142{
143  assert(NULL != m_pRelDyn && ".rel.dyn section not exist");
144  return *m_pRelDyn;
145}
146
147OutputRelocSection& HexagonLDBackend::getRelPLT()
148{
149  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
150  return *m_pRelPLT;
151}
152
153const OutputRelocSection& HexagonLDBackend::getRelPLT() const
154{
155  assert(NULL != m_pRelPLT && ".rel.plt section not exist");
156  return *m_pRelPLT;
157}
158
159unsigned int
160HexagonLDBackend::getTargetSectionOrder(const LDSection& pSectHdr) const
161{
162  const ELFFileFormat* file_format = getOutputFormat();
163
164  if (&pSectHdr == &file_format->getGOT()) {
165    if (config().options().hasNow())
166      return SHO_RELRO;
167    return SHO_RELRO_LAST;
168  }
169
170  if (&pSectHdr == &file_format->getPLT())
171    return SHO_PLT;
172
173  return SHO_UNDEFINED;
174}
175
176void HexagonLDBackend::initTargetSections(Module& pModule,
177                                          ObjectBuilder& pBuilder)
178{
179  if (LinkerConfig::Object != config().codeGenType()) {
180    ELFFileFormat* file_format = getOutputFormat();
181    // initialize .got
182    LDSection& got = file_format->getGOT();
183    m_pGOT = new HexagonGOT(got);
184
185    // initialize .plt
186    LDSection& plt = file_format->getPLT();
187    m_pPLT = new HexagonPLT(plt,
188                        *m_pGOT,
189                        config());
190
191    // initialize .rel.plt
192    LDSection& relplt = file_format->getRelPlt();
193    relplt.setLink(&plt);
194    m_pRelPLT = new OutputRelocSection(pModule, relplt);
195
196    // initialize .rel.dyn
197    LDSection& reldyn = file_format->getRelDyn();
198    m_pRelDyn = new OutputRelocSection(pModule, reldyn);
199
200  }
201}
202
203void HexagonLDBackend::initTargetSymbols(IRBuilder& pBuilder, Module& pModule)
204{
205  if (LinkerConfig::Object != config().codeGenType()) {
206    // Define the symbol _GLOBAL_OFFSET_TABLE_ if there is a symbol with the
207    // same name in input
208    m_pGOTSymbol = pBuilder.AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
209                                                    "_GLOBAL_OFFSET_TABLE_",
210                                                    ResolveInfo::Object,
211                                                    ResolveInfo::Define,
212                                                    ResolveInfo::Local,
213                                                    0x0,  // size
214                                                    0x0,  // value
215                                                    FragmentRef::Null(),
216                                                    ResolveInfo::Hidden);
217  }
218}
219
220/// finalizeSymbol - finalize the symbol value
221bool HexagonLDBackend::finalizeTargetSymbols()
222{
223  return true;
224}
225
226/// doCreateProgramHdrs - backend can implement this function to create the
227/// target-dependent segments
228void HexagonLDBackend::doCreateProgramHdrs(Module& pModule)
229{
230  // TODO
231}
232
233namespace mcld {
234
235//===----------------------------------------------------------------------===//
236/// createHexagonLDBackend - the help funtion to create corresponding
237/// HexagonLDBackend
238TargetLDBackend* createHexagonLDBackend(const llvm::Target& pTarget,
239                                    const LinkerConfig& pConfig)
240{
241  if (pConfig.targets().triple().isOSDarwin()) {
242    assert(0 && "MachO linker is not supported yet");
243    /**
244    return new HexagonMachOLDBackend(createHexagonMachOArchiveReader,
245                               createHexagonMachOObjectReader,
246                               createHexagonMachOObjectWriter);
247    **/
248  }
249  if (pConfig.targets().triple().isOSWindows()) {
250    assert(0 && "COFF linker is not supported yet");
251    /**
252    return new HexagonCOFFLDBackend(createHexagonCOFFArchiveReader,
253                               createHexagonCOFFObjectReader,
254                               createHexagonCOFFObjectWriter);
255    **/
256  }
257  return new HexagonLDBackend(pConfig,
258                              new HexagonGNUInfo(pConfig.targets().triple()));
259}
260
261} // namespace of mcld
262
263//===----------------------------------------------------------------------===//
264// Force static initialization.
265//===----------------------------------------------------------------------===//
266extern "C" void MCLDInitializeHexagonLDBackend() {
267  // Register the linker backend
268  mcld::TargetRegistry::RegisterTargetLDBackend(TheHexagonTarget,
269                                                createHexagonLDBackend);
270}
271