• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- MCLDDriver.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/MC/InputTree.h>
10 #include <mcld/MC/MCLinker.h>
11 #include <mcld/MC/MCLDDriver.h>
12 #include <mcld/MC/MCLDInfo.h>
13 #include <mcld/LD/ArchiveReader.h>
14 #include <mcld/LD/ObjectReader.h>
15 #include <mcld/LD/DynObjReader.h>
16 #include <mcld/LD/ObjectWriter.h>
17 #include <mcld/LD/DynObjWriter.h>
18 #include <mcld/LD/ExecWriter.h>
19 #include <mcld/LD/ResolveInfo.h>
20 #include <mcld/Support/RealPath.h>
21 #include <mcld/Support/MemoryAreaFactory.h>
22 #include <mcld/Target/TargetLDBackend.h>
23 #include <mcld/Support/MsgHandling.h>
24 #include <mcld/LD/Archive.h>
25 
26 using namespace llvm;
27 using namespace mcld;
28 
MCLDDriver(MCLDInfo & pLDInfo,TargetLDBackend & pLDBackend,MemoryAreaFactory & pAreaFactory)29 MCLDDriver::MCLDDriver(MCLDInfo& pLDInfo,
30                        TargetLDBackend& pLDBackend,
31                        MemoryAreaFactory& pAreaFactory)
32   : m_LDInfo(pLDInfo),
33     m_LDBackend(pLDBackend),
34     m_pLinker(NULL),
35     m_AreaFactory(pAreaFactory) {
36 
37 }
38 
~MCLDDriver()39 MCLDDriver::~MCLDDriver()
40 {
41   if (NULL != m_pLinker)
42     delete m_pLinker;
43 }
44 
45 /// initMCLinker - initialize MCLinker
46 ///  Connect all components with MCLinker
initMCLinker()47 bool MCLDDriver::initMCLinker()
48 {
49   if (0 == m_pLinker)
50     m_pLinker = new MCLinker(m_LDBackend,
51                              m_LDInfo,
52                              m_SectionMap);
53 
54   // initialize the readers and writers
55   // Because constructor can not be failed, we initalize all readers and
56   // writers outside the MCLinker constructors.
57   if (!m_LDBackend.initObjectReader(*m_pLinker) ||
58       !m_LDBackend.initArchiveReader(*m_pLinker, m_LDInfo, m_AreaFactory) ||
59       !m_LDBackend.initObjectReader(*m_pLinker) ||
60       !m_LDBackend.initDynObjReader(*m_pLinker) ||
61       !m_LDBackend.initObjectWriter(*m_pLinker) ||
62       !m_LDBackend.initDynObjWriter(*m_pLinker) ||
63       !m_LDBackend.initExecWriter(*m_pLinker))
64     return false;
65 
66   // initialize RelocationFactory
67   m_LDBackend.initRelocFactory(*m_pLinker);
68   return true;
69 }
70 
71 /// initStdSections - initialize standard sections
initStdSections()72 bool MCLDDriver::initStdSections()
73 {
74   /// initialize section mapping for standard format, target-dependent section,
75   /// (and user-defined mapping)
76   if (!m_SectionMap.initStdSectionMap() ||
77       !m_LDBackend.initTargetSectionMap(m_SectionMap))
78     return false;
79 
80   /// A technical debt. We need to initialize section map here because
81   /// we do not separate output file and temporary data structure. So far,
82   /// MCLinker directly use output file's LDContext as the temporary data
83   /// structure. We will create a new data structure mcld::Module to collect
84   /// all temporary data structures togather.
85   m_pLinker->initSectionMap();
86 
87   // initialize standard sections
88   switch (m_LDInfo.output().type()) {
89     case Output::DynObj: {
90       // intialize standard and target-dependent sections
91       if (!m_LDBackend.initDynObjSections(*m_pLinker))
92         return false;
93       break;
94     }
95     case Output::Exec: {
96       // intialize standard and target-dependent sections
97       if (!m_LDBackend.initExecSections(*m_pLinker))
98         return false;
99       break;
100     }
101     case Output::Object: {
102       llvm::report_fatal_error(llvm::Twine("output type is not implemented yet. file: `") +
103                                m_LDInfo.output().name() +
104                                llvm::Twine("'."));
105       return false;
106     }
107     default: {
108       llvm::report_fatal_error(llvm::Twine("unknown output type of file `") +
109                                m_LDInfo.output().name() +
110                                llvm::Twine("'."));
111        return false;
112     }
113   } // end of switch
114 
115   // initialize target-dependent sections
116   m_LDBackend.initTargetSections(*m_pLinker);
117 
118   return true;
119 }
120 
normalize()121 void MCLDDriver::normalize()
122 {
123   // -----  set up inputs  ----- //
124   InputTree::iterator input, inEnd = m_LDInfo.inputs().end();
125   for (input = m_LDInfo.inputs().begin(); input!=inEnd; ++input) {
126     // already got type - for example, bitcode or external OIR (object
127     // intermediate representation)
128     if ((*input)->type() == Input::Script ||
129         (*input)->type() == Input::Object ||
130         (*input)->type() == Input::DynObj  ||
131         (*input)->type() == Input::Archive ||
132         (*input)->type() == Input::External)
133       continue;
134 
135     // is a relocatable object file
136     if (m_LDBackend.getObjectReader()->isMyFormat(**input)) {
137       (*input)->setType(Input::Object);
138       m_LDBackend.getObjectReader()->readObject(**input);
139       m_LDBackend.getObjectReader()->readSections(**input);
140       m_LDBackend.getObjectReader()->readSymbols(**input);
141     }
142     // is a shared object file
143     else if (m_LDBackend.getDynObjReader()->isMyFormat(**input)) {
144       (*input)->setType(Input::DynObj);
145       m_LDBackend.getDynObjReader()->readDSO(**input);
146       m_LDBackend.getDynObjReader()->readSymbols(**input);
147     }
148     // is an archive
149     else if (m_LDBackend.getArchiveReader()->isMyFormat(**input)) {
150       (*input)->setType(Input::Archive);
151       Archive archive(**input, m_LDInfo.inputFactory());
152       m_LDBackend.getArchiveReader()->readArchive(archive);
153       if(archive.numOfObjectMember() > 0) {
154         m_LDInfo.inputs().merge<InputTree::Inclusive>(input, archive.inputs());
155       }
156     }
157     else {
158       fatal(diag::err_unrecognized_input_file) << (*input)->path()
159                                                << m_LDInfo.triple().str();
160     }
161   } // end of for
162 }
163 
linkable() const164 bool MCLDDriver::linkable() const
165 {
166   // check we have input and output files
167   if (m_LDInfo.inputs().empty()) {
168     error(diag::err_no_inputs);
169     return false;
170   }
171 
172   // check all attributes are legal
173   mcld::AttributeFactory::const_iterator attr, attrEnd = m_LDInfo.attrFactory().end();
174   for (attr=m_LDInfo.attrFactory().begin(); attr!=attrEnd; ++attr) {
175     if (!m_LDInfo.attrFactory().constraint().isLegal((**attr))) {
176       return false;
177     }
178   }
179 
180   // can not mix -static with shared objects
181   mcld::InputTree::const_bfs_iterator input, inEnd = m_LDInfo.inputs().bfs_end();
182   for (input=m_LDInfo.inputs().bfs_begin(); input!=inEnd; ++input) {
183     if ((*input)->type() == mcld::Input::DynObj) {
184       if((*input)->attribute()->isStatic()) {
185         error(diag::err_mixed_shared_static_objects)
186                                         << (*input)->name() << (*input)->path();
187         return false;
188       }
189     }
190   }
191 
192   // can not mix -r with shared objects
193   return true;
194 }
195 
196 /// mergeSections - put allinput sections into output sections
mergeSections()197 bool MCLDDriver::mergeSections()
198 {
199   // TODO: when MCLinker can read other object files, we have to merge
200   // sections
201   return true;
202 }
203 
204 /// addStandardSymbols - shared object and executable files need some
205 /// standard symbols
206 ///   @return if there are some input symbols with the same name to the
207 ///   standard symbols, return false
addStandardSymbols()208 bool MCLDDriver::addStandardSymbols()
209 {
210   return m_LDBackend.initStandardSymbols(*m_pLinker, m_LDInfo.output());
211 }
212 
213 /// addTargetSymbols - some targets, such as MIPS and ARM, need some
214 /// target-dependent symbols
215 ///   @return if there are some input symbols with the same name to the
216 ///   target symbols, return false
addTargetSymbols()217 bool MCLDDriver::addTargetSymbols()
218 {
219   m_LDBackend.initTargetSymbols(*m_pLinker, m_LDInfo.output());
220   return true;
221 }
222 
223 /// readRelocations - read all relocation entries
224 ///
225 /// All symbols should be read and resolved before this function.
readRelocations()226 bool MCLDDriver::readRelocations()
227 {
228   // Bitcode is read by the other path. This function reads relocation sections
229   // in object files.
230   mcld::InputTree::bfs_iterator input, inEnd = m_LDInfo.inputs().bfs_end();
231   for (input=m_LDInfo.inputs().bfs_begin(); input!=inEnd; ++input) {
232     if ((*input)->type() == Input::Object) {
233       if (!m_LDBackend.getObjectReader()->readRelocations(**input))
234         return false;
235     }
236     // ignore the other kinds of files.
237   }
238   return true;
239 }
240 
241 /// prelayout - help backend to do some modification before layout
prelayout()242 bool MCLDDriver::prelayout()
243 {
244   m_LDBackend.preLayout(m_LDInfo.output(),
245                         m_LDInfo,
246                         *m_pLinker);
247 
248   m_LDBackend.allocateCommonSymbols(m_LDInfo, *m_pLinker);
249 
250   /// check program interpreter - computer the name size of the runtime dyld
251   /// FIXME: check if we are doing static linking!
252   if (m_LDInfo.output().type() == Output::Exec)
253     m_LDBackend.sizeInterp(m_LDInfo.output(), m_LDInfo);
254 
255   /// measure NamePools - compute the size of name pool sections
256   /// In ELF, will compute  the size of.symtab, .strtab, .dynsym, .dynstr,
257   /// and .hash sections.
258   ///
259   /// dump all symbols and strings from MCLinker and build the format-dependent
260   /// hash table.
261   m_LDBackend.sizeNamePools(m_LDInfo.output(), m_pLinker->getOutputSymbols(), m_LDInfo);
262 
263   return true;
264 }
265 
266 /// layout - linearly layout all output sections and reserve some space
267 /// for GOT/PLT
268 ///   Because we do not support instruction relaxing in this early version,
269 ///   if there is a branch can not jump to its target, we return false
270 ///   directly
layout()271 bool MCLDDriver::layout()
272 {
273   return m_pLinker->layout();
274 }
275 
276 /// prelayout - help backend to do some modification after layout
postlayout()277 bool MCLDDriver::postlayout()
278 {
279   m_LDBackend.postLayout(m_LDInfo.output(),
280                          m_LDInfo,
281                          *m_pLinker);
282   return true;
283 }
284 
285 /// finalizeSymbolValue - finalize the resolved symbol value.
286 ///   Before relocate(), after layout(), MCLinker should correct value of all
287 ///   symbol.
finalizeSymbolValue()288 bool MCLDDriver::finalizeSymbolValue()
289 {
290   return m_pLinker->finalizeSymbols();
291 }
292 
293 /// relocate - applying relocation entries and create relocation
294 /// section in the output files
295 /// Create relocation section, asking TargetLDBackend to
296 /// read the relocation information into RelocationEntry
297 /// and push_back into the relocation section
relocation()298 bool MCLDDriver::relocation()
299 {
300   return m_pLinker->applyRelocations();
301 }
302 
303 /// emitOutput - emit the output file.
emitOutput()304 bool MCLDDriver::emitOutput()
305 {
306   switch(m_LDInfo.output().type()) {
307     case Output::Object:
308       m_LDBackend.getObjectWriter()->writeObject(m_LDInfo.output());
309       return true;
310     case Output::DynObj:
311       m_LDBackend.getDynObjWriter()->writeDynObj(m_LDInfo.output());
312       return true;
313     case Output::Exec:
314       m_LDBackend.getExecWriter()->writeExecutable(m_LDInfo.output());
315       return true;
316   }
317   return false;
318 }
319 
320 /// postProcessing - do modification after all processes
postProcessing()321 bool MCLDDriver::postProcessing()
322 {
323   m_pLinker->syncRelocationResult();
324 
325   m_LDBackend.postProcessing(m_LDInfo.output(),
326                              m_LDInfo,
327                              *m_pLinker);
328   return true;
329 }
330