Linker.cpp revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
1//===- Linker.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/Linker.h>
10#include <mcld/LinkerConfig.h>
11#include <mcld/Module.h>
12#include <mcld/IRBuilder.h>
13
14#include <mcld/Support/MsgHandling.h>
15#include <mcld/Support/TargetRegistry.h>
16#include <mcld/Support/FileHandle.h>
17#include <mcld/Support/MemoryArea.h>
18#include <mcld/Support/raw_ostream.h>
19
20#include <mcld/Object/ObjectLinker.h>
21#include <mcld/MC/InputBuilder.h>
22#include <mcld/Target/TargetLDBackend.h>
23#include <mcld/LD/LDSection.h>
24#include <mcld/LD/LDSymbol.h>
25#include <mcld/LD/SectionData.h>
26#include <mcld/LD/RelocData.h>
27#include <mcld/Fragment/Relocation.h>
28#include <mcld/Fragment/FragmentRef.h>
29
30#include <cassert>
31
32using namespace mcld;
33
34Linker::Linker()
35  : m_pConfig(NULL), m_pIRBuilder(NULL),
36    m_pTarget(NULL), m_pBackend(NULL), m_pObjLinker(NULL) {
37}
38
39Linker::~Linker()
40{
41  reset();
42}
43
44bool Linker::config(LinkerConfig& pConfig)
45{
46  m_pConfig = &pConfig;
47
48  if (!initTarget())
49    return false;
50
51  if (!initBackend())
52    return false;
53
54  m_pObjLinker = new ObjectLinker(*m_pConfig,
55                                  *m_pBackend);
56
57  if (!initEmulator())
58    return false;
59
60  if (!initOStream())
61    return false;
62
63  return true;
64}
65
66bool Linker::link(Module& pModule, IRBuilder& pBuilder)
67{
68  if (!resolve(pModule, pBuilder))
69    return false;
70
71  return layout();
72}
73
74bool Linker::resolve(Module& pModule, IRBuilder& pBuilder)
75{
76  assert(NULL != m_pConfig);
77
78  m_pIRBuilder = &pBuilder;
79  assert(m_pObjLinker!=NULL);
80  m_pObjLinker->setup(pModule, pBuilder);
81
82  // 2. - initialize FragmentLinker
83  if (!m_pObjLinker->initFragmentLinker())
84    return false;
85
86  // 3. - initialize output's standard sections
87  if (!m_pObjLinker->initStdSections())
88    return false;
89
90  if (!Diagnose())
91    return false;
92
93  // 4. - normalize the input tree
94  //   read out sections and symbol/string tables (from the files) and
95  //   set them in Module. When reading out the symbol, resolve their symbols
96  //   immediately and set their ResolveInfo (i.e., Symbol Resolution).
97  m_pObjLinker->normalize();
98
99  if (m_pConfig->options().trace()) {
100    static int counter = 0;
101    mcld::outs() << "** name\ttype\tpath\tsize (" << pModule.getInputTree().size() << ")\n";
102    InputTree::const_dfs_iterator input, inEnd = pModule.getInputTree().dfs_end();
103    for (input=pModule.getInputTree().dfs_begin(); input!=inEnd; ++input) {
104      mcld::outs() << counter++ << " *  " << (*input)->name();
105      switch((*input)->type()) {
106      case Input::Archive:
107        mcld::outs() << "\tarchive\t(";
108        break;
109      case Input::Object:
110        mcld::outs() << "\tobject\t(";
111        break;
112      case Input::DynObj:
113        mcld::outs() << "\tshared\t(";
114        break;
115      case Input::Script:
116        mcld::outs() << "\tscript\t(";
117        break;
118      case Input::External:
119        mcld::outs() << "\textern\t(";
120        break;
121      default:
122        unreachable(diag::err_cannot_trace_file) << (*input)->type()
123                                                 << (*input)->name()
124                                                 << (*input)->path();
125      }
126      mcld::outs() << (*input)->path() << ")\n";
127    }
128  }
129
130  // 5. - set up code position
131  if (LinkerConfig::DynObj == m_pConfig->codeGenType() ||
132      m_pConfig->options().isPIE()) {
133    m_pConfig->setCodePosition(LinkerConfig::Independent);
134  }
135  else if (pModule.getLibraryList().empty()) {
136    // If the output is dependent on its loaded address, and it does not need
137    // to call outside functions, then we can treat the output static dependent
138    // and perform better optimizations.
139    m_pConfig->setCodePosition(LinkerConfig::StaticDependent);
140  }
141  else {
142    m_pConfig->setCodePosition(LinkerConfig::DynamicDependent);
143  }
144
145  if (!m_pObjLinker->linkable())
146    return Diagnose();
147
148  // 6. - read all relocation entries from input files
149  //   For all relocation sections of each input file (in the tree),
150  //   read out reloc entry info from the object file and accordingly
151  //   initiate their reloc entries in SectOrRelocData of LDSection.
152  m_pObjLinker->readRelocations();
153
154  // 7. - merge all sections
155  //   Push sections into Module's SectionTable.
156  //   Merge sections that have the same name.
157  //   Maintain them as fragments in the section.
158  if (!m_pObjLinker->mergeSections())
159    return false;
160
161  // 8. - allocateCommonSymbols
162  //   Allocate fragments for common symbols to the corresponding sections.
163  if (!m_pObjLinker->allocateCommonSymbols())
164    return false;
165  return true;
166}
167
168bool Linker::layout()
169{
170  assert(NULL != m_pConfig && NULL != m_pObjLinker);
171
172  // 9. - add standard symbols, target-dependent symbols and script symbols
173  // m_pObjLinker->addUndefSymbols();
174  if (!m_pObjLinker->addStandardSymbols() ||
175      !m_pObjLinker->addTargetSymbols() ||
176      !m_pObjLinker->addScriptSymbols())
177    return false;
178
179  // 10. - scan all relocation entries by output symbols.
180  //   reserve GOT space for layout.
181  //   the space info is needed by pre-layout to compute the section size
182  m_pObjLinker->scanRelocations();
183
184  // 11.a - init relaxation stuff.
185  m_pObjLinker->initStubs();
186
187  // 11.b - pre-layout
188  m_pObjLinker->prelayout();
189
190  // 11.c - linear layout
191  //   Decide which sections will be left in. Sort the sections according to
192  //   a given order. Then, create program header accordingly.
193  //   Finally, set the offset for sections (@ref LDSection)
194  //   according to the new order.
195  m_pObjLinker->layout();
196
197  // 11.d - post-layout (create segment, instruction relaxing)
198  m_pObjLinker->postlayout();
199
200  // 12. - finalize symbol value
201  m_pObjLinker->finalizeSymbolValue();
202
203  // 13. - apply relocations
204  m_pObjLinker->relocation();
205
206  if (!Diagnose())
207    return false;
208  return true;
209}
210
211bool Linker::emit(MemoryArea& pOutput)
212{
213  // 13. - write out output
214  m_pObjLinker->emitOutput(pOutput);
215
216  // 14. - post processing
217  m_pObjLinker->postProcessing(pOutput);
218
219  if (!Diagnose())
220    return false;
221
222  return true;
223}
224
225bool Linker::emit(const std::string& pPath)
226{
227  FileHandle file;
228  FileHandle::Permission perm = 0755;
229  if (!file.open(pPath,
230            FileHandle::ReadWrite | FileHandle::Truncate | FileHandle::Create,
231            perm)) {
232    error(diag::err_cannot_open_output_file) << "Linker::emit()" << pPath;
233    return false;
234  }
235
236  MemoryArea* output = new MemoryArea(file);
237
238  bool result = emit(*output);
239
240  delete output;
241  file.close();
242  return result;
243}
244
245bool Linker::emit(int pFileDescriptor)
246{
247  FileHandle file;
248  file.delegate(pFileDescriptor);
249  MemoryArea* output = new MemoryArea(file);
250
251  bool result = emit(*output);
252
253  delete output;
254  file.close();
255  return result;
256}
257
258bool Linker::reset()
259{
260  m_pConfig = NULL;
261  m_pIRBuilder = NULL;
262  m_pTarget = NULL;
263
264  // Because llvm::iplist will touch the removed node, we must clear
265  // RelocData before deleting target backend.
266  RelocData::Clear();
267  SectionData::Clear();
268  EhFrame::Clear();
269
270  delete m_pBackend;
271  m_pBackend = NULL;
272
273  delete m_pObjLinker;
274  m_pObjLinker = NULL;
275
276  LDSection::Clear();
277  LDSymbol::Clear();
278  FragmentRef::Clear();
279  Relocation::Clear();
280  return true;
281}
282
283bool Linker::initTarget()
284{
285  assert(NULL != m_pConfig);
286
287  std::string error;
288  m_pTarget = mcld::TargetRegistry::lookupTarget(m_pConfig->targets().triple().str(), error);
289  if (NULL == m_pTarget) {
290    fatal(diag::fatal_cannot_init_target) << m_pConfig->targets().triple().str() << error;
291    return false;
292  }
293  return true;
294}
295
296bool Linker::initBackend()
297{
298  assert(NULL != m_pTarget);
299  m_pBackend = m_pTarget->createLDBackend(*m_pConfig);
300  if (NULL == m_pBackend) {
301    fatal(diag::fatal_cannot_init_backend) << m_pConfig->targets().triple().str();
302    return false;
303  }
304  return true;
305}
306
307bool Linker::initEmulator()
308{
309  assert(NULL != m_pTarget && NULL != m_pConfig);
310  bool result = m_pTarget->emulate(m_pConfig->targets().triple().str(),
311                                   *m_pConfig);
312
313  // Relocation should be set up after emulation.
314  Relocation::SetUp(*m_pConfig);
315  return result;
316}
317
318bool Linker::initOStream()
319{
320  assert(NULL != m_pConfig);
321
322  mcld::outs().setColor(m_pConfig->options().color());
323  mcld::errs().setColor(m_pConfig->options().color());
324
325  return true;
326}
327
328