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