Home | History | Annotate | Download | only in CodeGen
      1 //===- MCLinker.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 //
     10 // This file implements the MCLinker class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 #include <mcld/CodeGen/MCLinker.h>
     14 
     15 #include <mcld/Module.h>
     16 #include <mcld/LinkerConfig.h>
     17 #include <mcld/LinkerScript.h>
     18 #include <mcld/InputTree.h>
     19 #include <mcld/Linker.h>
     20 #include <mcld/IRBuilder.h>
     21 #include <mcld/MC/InputBuilder.h>
     22 #include <mcld/MC/FileAction.h>
     23 #include <mcld/MC/CommandAction.h>
     24 #include <mcld/Object/ObjectLinker.h>
     25 #include <mcld/Support/CommandLine.h>
     26 #include <mcld/Support/FileSystem.h>
     27 #include <mcld/Support/MsgHandling.h>
     28 #include <mcld/Support/FileHandle.h>
     29 #include <mcld/Support/raw_ostream.h>
     30 
     31 #include <llvm/IR/Module.h>
     32 #include <llvm/Support/CommandLine.h>
     33 
     34 #include <algorithm>
     35 #include <vector>
     36 #include <string>
     37 
     38 using namespace mcld;
     39 using namespace llvm;
     40 
     41 char MCLinker::m_ID = 0;
     42 
     43 //===----------------------------------------------------------------------===//
     44 // Help Functions
     45 //===----------------------------------------------------------------------===//
     46 static inline bool CompareAction(const InputAction* X, const InputAction* Y)
     47 {
     48   return (X->position() < Y->position());
     49 }
     50 
     51 //===----------------------------------------------------------------------===//
     52 // Positional Options
     53 // There are four kinds of positional options:
     54 //   1. Inputs, object files, such as /tmp/XXXX.o
     55 //   2. Namespecs, short names of libraries. A namespec may refer to an archive
     56 //      or a shared library. For example, -lm.
     57 //   3. Attributes of inputs. Attributes describe inputs appears after them.
     58 //      For example, --as-needed and --whole-archive.
     59 //   4. Groups. A Group is a set of archives. Linkers repeatedly read archives
     60 //      in groups until there is no new undefined symbols.
     61 //   5. Bitcode. Bitcode is a kind of object files. MCLinker compiles it to
     62 //      object file first, then link it as a object file. (Bitcode is recorded
     63 //      in BitcodeOption, not be read by LLVM Command Line library.)
     64 //===----------------------------------------------------------------------===//
     65 // Inputs
     66 //===----------------------------------------------------------------------===//
     67 static cl::list<mcld::sys::fs::Path>
     68 ArgInputObjectFiles(cl::Positional,
     69                     cl::desc("[input object files]"),
     70                     cl::ZeroOrMore);
     71 
     72 //===----------------------------------------------------------------------===//
     73 // Namespecs
     74 //===----------------------------------------------------------------------===//
     75 static cl::list<std::string>
     76 ArgNameSpecList("l",
     77             cl::ZeroOrMore,
     78             cl::desc("Add the archive or object file specified by namespec to "
     79                      "the list of files to link."),
     80             cl::value_desc("namespec"),
     81             cl::Prefix);
     82 
     83 static cl::alias
     84 ArgNameSpecListAlias("library",
     85                  cl::desc("alias for -l"),
     86                  cl::aliasopt(ArgNameSpecList));
     87 
     88 //===----------------------------------------------------------------------===//
     89 // Attributes
     90 //===----------------------------------------------------------------------===//
     91 static cl::list<bool>
     92 ArgWholeArchiveList("whole-archive",
     93                cl::ValueDisallowed,
     94                cl::desc("For each archive mentioned on the command line after "
     95                         "the --whole-archive option, include all object files "
     96                         "in the archive."));
     97 
     98 static cl::list<bool>
     99 ArgNoWholeArchiveList("no-whole-archive",
    100                cl::ValueDisallowed,
    101                cl::desc("Turn off the effect of the --whole-archive option for "
    102                         "subsequent archive files."));
    103 
    104 static cl::list<bool>
    105 ArgAsNeededList("as-needed",
    106                cl::ValueDisallowed,
    107                cl::desc("This option affects ELF DT_NEEDED tags for dynamic "
    108                         "libraries mentioned on the command line after the "
    109                         "--as-needed option."));
    110 
    111 static cl::list<bool>
    112 ArgNoAsNeededList("no-as-needed",
    113                cl::ValueDisallowed,
    114                cl::desc("Turn off the effect of the --as-needed option for "
    115                         "subsequent dynamic libraries"));
    116 
    117 static cl::list<bool>
    118 ArgAddNeededList("add-needed",
    119                 cl::ValueDisallowed,
    120                 cl::desc("--add-needed causes DT_NEEDED tags are always "
    121                          "emitted for those libraries from DT_NEEDED tags. "
    122                          "This is the default behavior."));
    123 
    124 static cl::list<bool>
    125 ArgNoAddNeededList("no-add-needed",
    126                 cl::ValueDisallowed,
    127                 cl::desc("--no-add-needed causes DT_NEEDED tags will never be "
    128                          "emitted for those libraries from DT_NEEDED tags"));
    129 
    130 static cl::list<bool>
    131 ArgBDynamicList("Bdynamic",
    132                 cl::ValueDisallowed,
    133                 cl::desc("Link against dynamic library"));
    134 
    135 static cl::alias
    136 ArgBDynamicListAlias1("dy",
    137                 cl::desc("alias for --Bdynamic"),
    138                 cl::aliasopt(ArgBDynamicList));
    139 
    140 static cl::alias
    141 ArgBDynamicListAlias2("call_shared",
    142                 cl::desc("alias for --Bdynamic"),
    143                 cl::aliasopt(ArgBDynamicList));
    144 
    145 static cl::list<bool>
    146 ArgBStaticList("Bstatic",
    147                 cl::ValueDisallowed,
    148                 cl::desc("Link against static library"));
    149 
    150 static cl::alias
    151 ArgBStaticListAlias1("dn",
    152                 cl::desc("alias for --Bstatic"),
    153                 cl::aliasopt(ArgBStaticList));
    154 
    155 static cl::alias
    156 ArgBStaticListAlias2("static",
    157                 cl::desc("alias for --Bstatic"),
    158                 cl::aliasopt(ArgBStaticList));
    159 
    160 static cl::alias
    161 ArgBStaticListAlias3("non_shared",
    162                 cl::desc("alias for --Bstatic"),
    163                 cl::aliasopt(ArgBStaticList));
    164 
    165 //===----------------------------------------------------------------------===//
    166 // Groups
    167 //===----------------------------------------------------------------------===//
    168 static cl::list<bool>
    169 ArgStartGroupList("start-group",
    170                   cl::ValueDisallowed,
    171                   cl::desc("start to record a group of archives"));
    172 
    173 static cl::alias
    174 ArgStartGroupListAlias("(",
    175                        cl::desc("alias for --start-group"),
    176                        cl::aliasopt(ArgStartGroupList));
    177 
    178 static cl::list<bool>
    179 ArgEndGroupList("end-group",
    180                 cl::ValueDisallowed,
    181                 cl::desc("stop recording a group of archives"));
    182 
    183 static cl::alias
    184 ArgEndGroupListAlias(")",
    185                      cl::desc("alias for --end-group"),
    186                      cl::aliasopt(ArgEndGroupList));
    187 
    188 //===----------------------------------------------------------------------===//
    189 // --defsym
    190 //===----------------------------------------------------------------------===//
    191 static cl::list<std::string>
    192 ArgDefSymList("defsym",
    193               cl::ZeroOrMore,
    194               cl::desc("Define a symbol"),
    195               cl::value_desc("symbol=expression"));
    196 
    197 //===----------------------------------------------------------------------===//
    198 // MCLinker
    199 //===----------------------------------------------------------------------===//
    200 MCLinker::MCLinker(LinkerConfig& pConfig,
    201                    mcld::Module& pModule,
    202                    FileHandle& pFileHandle)
    203   : MachineFunctionPass(m_ID),
    204     m_Config(pConfig),
    205     m_Module(pModule),
    206     m_FileHandle(pFileHandle),
    207     m_pBuilder(NULL),
    208     m_pLinker(NULL) {
    209 }
    210 
    211 MCLinker::~MCLinker()
    212 {
    213   delete m_pLinker;
    214   delete m_pBuilder;
    215 }
    216 
    217 bool MCLinker::doInitialization(llvm::Module &pM)
    218 {
    219   // Now, all input arguments are prepared well, send it into ObjectLinker
    220   m_pLinker = new Linker();
    221 
    222   if (!m_pLinker->emulate(m_Module.getScript(), m_Config))
    223     return false;
    224 
    225   m_pBuilder = new IRBuilder(m_Module, m_Config);
    226 
    227   initializeInputTree(*m_pBuilder);
    228 
    229   return true;
    230 }
    231 
    232 bool MCLinker::doFinalization(llvm::Module &pM)
    233 {
    234   if (!m_pLinker->link(m_Module, *m_pBuilder))
    235     return true;
    236 
    237   if (!m_pLinker->emit(m_Module, m_FileHandle.handler()))
    238     return true;
    239 
    240   return false;
    241 }
    242 
    243 bool MCLinker::runOnMachineFunction(MachineFunction& pF)
    244 {
    245   // basically, linkers do nothing during function is generated.
    246   return false;
    247 }
    248 
    249 void MCLinker::initializeInputTree(IRBuilder& pBuilder)
    250 {
    251   if (0 == ArgInputObjectFiles.size() &&
    252       0 == ArgNameSpecList.size() &&
    253       !m_Config.bitcode().hasDefined()) {
    254     fatal(diag::err_no_inputs);
    255     return;
    256   }
    257 
    258   size_t num_actions = ArgInputObjectFiles.size() +
    259                        ArgNameSpecList.size() +
    260                        ArgWholeArchiveList.size() +
    261                        ArgNoWholeArchiveList.size() +
    262                        ArgAsNeededList.size() +
    263                        ArgNoAsNeededList.size() +
    264                        ArgAddNeededList.size() +
    265                        ArgNoAddNeededList.size() +
    266                        ArgBDynamicList.size() +
    267                        ArgBStaticList.size() +
    268                        ArgStartGroupList.size() +
    269                        ArgEndGroupList.size() +
    270                        ArgDefSymList.size() +
    271                        1; // bitcode
    272   std::vector<InputAction*> actions;
    273   actions.reserve(num_actions);
    274 
    275   // -----  scripts  ----- //
    276   /// -T
    277   if (!m_Config.options().getScriptList().empty()) {
    278     GeneralOptions::const_script_iterator ii, ie = m_Config.options().script_end();
    279     for (ii = m_Config.options().script_begin(); ii != ie; ++ii) {
    280       actions.push_back(new ScriptAction(0x0,
    281                                          *ii,
    282                                          ScriptFile::LDScript,
    283                                          m_Module.getScript().directories()));
    284       actions.push_back(new ContextAction(0x0));
    285       actions.push_back(new MemoryAreaAction(0x0, FileHandle::ReadOnly));
    286     }
    287   }
    288 
    289   /// --defsym
    290   cl::list<std::string>::iterator defsym, dsBegin, dsEnd;
    291   dsBegin = ArgDefSymList.begin();
    292   dsEnd = ArgDefSymList.end();
    293   for (defsym = dsBegin; defsym != dsEnd; ++defsym) {
    294     unsigned int pos = ArgDefSymList.getPosition(defsym - dsBegin);
    295     actions.push_back(new DefSymAction(pos, *defsym));
    296   }
    297 
    298   // -----  inputs  ----- //
    299   cl::list<mcld::sys::fs::Path>::iterator input, inBegin, inEnd;
    300   inBegin = ArgInputObjectFiles.begin();
    301   inEnd = ArgInputObjectFiles.end();
    302   for (input = inBegin; input != inEnd; ++input) {
    303     unsigned int pos = ArgInputObjectFiles.getPosition(input - inBegin);
    304     actions.push_back(new InputFileAction(pos, *input));
    305     actions.push_back(new ContextAction(pos));
    306     actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
    307   }
    308 
    309   // -----  namespecs  ----- //
    310   cl::list<std::string>::iterator namespec, nsBegin, nsEnd;
    311   nsBegin = ArgNameSpecList.begin();
    312   nsEnd = ArgNameSpecList.end();
    313   for (namespec = nsBegin; namespec != nsEnd; ++namespec) {
    314     unsigned int pos = ArgNameSpecList.getPosition(namespec - nsBegin);
    315     actions.push_back(new NamespecAction(pos, *namespec,
    316                                          m_Module.getScript().directories()));
    317     actions.push_back(new ContextAction(pos));
    318     actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
    319   }
    320 
    321   // -----  attributes  ----- //
    322   /// --whole-archive
    323   cl::list<bool>::iterator attr, attrBegin, attrEnd;
    324   attrBegin = ArgWholeArchiveList.begin();
    325   attrEnd   = ArgWholeArchiveList.end();
    326   for (attr = attrBegin; attr != attrEnd; ++attr) {
    327     unsigned int pos = ArgWholeArchiveList.getPosition(attr - attrBegin);
    328     actions.push_back(new WholeArchiveAction(pos));
    329   }
    330 
    331   /// --no-whole-archive
    332   attrBegin = ArgNoWholeArchiveList.begin();
    333   attrEnd   = ArgNoWholeArchiveList.end();
    334   for (attr = attrBegin; attr != attrEnd; ++attr) {
    335     unsigned int pos = ArgNoWholeArchiveList.getPosition(attr - attrBegin);
    336     actions.push_back(new NoWholeArchiveAction(pos));
    337   }
    338 
    339   /// --as-needed
    340   attrBegin = ArgAsNeededList.begin();
    341   attrEnd   = ArgAsNeededList.end();
    342   for (attr = attrBegin; attr != attrEnd; ++attr) {
    343     unsigned int pos = ArgAsNeededList.getPosition(attr - attrBegin);
    344     actions.push_back(new AsNeededAction(pos));
    345   }
    346 
    347   /// --no-as-needed
    348   attrBegin = ArgNoAsNeededList.begin();
    349   attrEnd   = ArgNoAsNeededList.end();
    350   for (attr = attrBegin; attr != attrEnd; ++attr) {
    351     unsigned int pos = ArgNoAsNeededList.getPosition(attr - attrBegin);
    352     actions.push_back(new NoAsNeededAction(pos));
    353   }
    354 
    355   /// --add--needed
    356   attrBegin = ArgAddNeededList.begin();
    357   attrEnd   = ArgAddNeededList.end();
    358   for (attr = attrBegin; attr != attrEnd; ++attr) {
    359     unsigned int pos = ArgAddNeededList.getPosition(attr - attrBegin);
    360     actions.push_back(new AddNeededAction(pos));
    361   }
    362 
    363   /// --no-add--needed
    364   attrBegin = ArgNoAddNeededList.begin();
    365   attrEnd   = ArgNoAddNeededList.end();
    366   for (attr = attrBegin; attr != attrEnd; ++attr) {
    367     unsigned int pos = ArgNoAddNeededList.getPosition(attr - attrBegin);
    368     actions.push_back(new NoAddNeededAction(pos));
    369   }
    370 
    371   /// --Bdynamic
    372   attrBegin = ArgBDynamicList.begin();
    373   attrEnd   = ArgBDynamicList.end();
    374   for (attr = attrBegin; attr != attrEnd; ++attr) {
    375     unsigned int pos = ArgBDynamicList.getPosition(attr - attrBegin);
    376     actions.push_back(new BDynamicAction(pos));
    377   }
    378 
    379   /// --Bstatic
    380   attrBegin = ArgBStaticList.begin();
    381   attrEnd   = ArgBStaticList.end();
    382   for (attr = attrBegin; attr != attrEnd; ++attr) {
    383     unsigned int pos = ArgBStaticList.getPosition(attr - attrBegin);
    384     actions.push_back(new BStaticAction(pos));
    385   }
    386 
    387   // -----  groups  ----- //
    388   /// --start-group
    389   cl::list<bool>::iterator group, gsBegin, gsEnd;
    390   gsBegin = ArgStartGroupList.begin();
    391   gsEnd   = ArgStartGroupList.end();
    392   for (group = gsBegin; group != gsEnd; ++group) {
    393     unsigned int pos = ArgStartGroupList.getPosition(group - gsBegin);
    394     actions.push_back(new StartGroupAction(pos));
    395   }
    396 
    397   /// --end-group
    398   gsBegin = ArgEndGroupList.begin();
    399   gsEnd   = ArgEndGroupList.end();
    400   for (group = gsBegin; group != gsEnd; ++group) {
    401     unsigned int pos = ArgEndGroupList.getPosition(group - gsBegin);
    402     actions.push_back(new EndGroupAction(pos));
    403   }
    404 
    405   // -----  bitcode  ----- //
    406   if (m_Config.bitcode().hasDefined()) {
    407     actions.push_back(new BitcodeAction(m_Config.bitcode().getPosition(),
    408                                         m_Config.bitcode().getPath()));
    409   }
    410 
    411   // stable sort
    412   std::stable_sort(actions.begin(), actions.end(), CompareAction);
    413 
    414   // build up input tree
    415   std::vector<InputAction*>::iterator action, actionEnd = actions.end();
    416   for (action = actions.begin(); action != actionEnd; ++action) {
    417     (*action)->activate(pBuilder.getInputBuilder());
    418     delete *action;
    419   }
    420 
    421   if (pBuilder.getInputBuilder().isInGroup())
    422     report_fatal_error("no matched --start-group and --end-group");
    423 }
    424 
    425