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