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/InputTree.h>
     18 #include <mcld/Linker.h>
     19 #include <mcld/IRBuilder.h>
     20 #include <mcld/MC/InputBuilder.h>
     21 #include <mcld/MC/FileAction.h>
     22 #include <mcld/MC/CommandAction.h>
     23 #include <mcld/Object/ObjectLinker.h>
     24 #include <mcld/Support/CommandLine.h>
     25 #include <mcld/Support/FileSystem.h>
     26 #include <mcld/Support/MsgHandling.h>
     27 #include <mcld/Support/FileHandle.h>
     28 #include <mcld/Support/raw_ostream.h>
     29 #include <mcld/Support/MemoryArea.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 // MCLinker
    190 //===----------------------------------------------------------------------===//
    191 MCLinker::MCLinker(LinkerConfig& pConfig,
    192                    mcld::Module& pModule,
    193                    MemoryArea& pOutput)
    194   : MachineFunctionPass(m_ID),
    195     m_Config(pConfig),
    196     m_Module(pModule),
    197     m_Output(pOutput),
    198     m_pBuilder(NULL),
    199     m_pLinker(NULL) {
    200 }
    201 
    202 MCLinker::~MCLinker()
    203 {
    204   delete m_pLinker;
    205   delete m_pBuilder;
    206 }
    207 
    208 bool MCLinker::doInitialization(llvm::Module &pM)
    209 {
    210   // Now, all input arguments are prepared well, send it into ObjectLinker
    211   m_pLinker = new Linker();
    212 
    213   if (!m_pLinker->config(m_Config))
    214     return false;
    215 
    216   m_pBuilder = new IRBuilder(m_Module, m_Config);
    217 
    218   initializeInputTree(*m_pBuilder);
    219 
    220   return true;
    221 }
    222 
    223 bool MCLinker::doFinalization(llvm::Module &pM)
    224 {
    225   if (!m_pLinker->link(m_Module, *m_pBuilder))
    226     return true;
    227 
    228   if (!m_pLinker->emit(m_Output))
    229     return true;
    230 
    231   return false;
    232 }
    233 
    234 bool MCLinker::runOnMachineFunction(MachineFunction& pF)
    235 {
    236   // basically, linkers do nothing during function is generated.
    237   return false;
    238 }
    239 
    240 void MCLinker::initializeInputTree(IRBuilder& pBuilder)
    241 {
    242   if (0 == ArgInputObjectFiles.size() &&
    243       0 == ArgNameSpecList.size() &&
    244       !m_Config.bitcode().hasDefined()) {
    245     fatal(diag::err_no_inputs);
    246     return;
    247   }
    248 
    249   size_t num_actions = ArgInputObjectFiles.size() +
    250                        ArgNameSpecList.size() +
    251                        ArgWholeArchiveList.size() +
    252                        ArgNoWholeArchiveList.size() +
    253                        ArgAsNeededList.size() +
    254                        ArgNoAsNeededList.size() +
    255                        ArgAddNeededList.size() +
    256                        ArgNoAddNeededList.size() +
    257                        ArgBDynamicList.size() +
    258                        ArgBStaticList.size() +
    259                        ArgStartGroupList.size() +
    260                        ArgEndGroupList.size() +
    261                        1; // bitcode
    262   std::vector<InputAction*> actions;
    263   actions.reserve(num_actions);
    264 
    265   // -----  inputs  ----- //
    266   cl::list<mcld::sys::fs::Path>::iterator input, inBegin, inEnd;
    267   inBegin = ArgInputObjectFiles.begin();
    268   inEnd = ArgInputObjectFiles.end();
    269   for (input = inBegin; input != inEnd; ++input) {
    270     unsigned int pos = ArgInputObjectFiles.getPosition(input - inBegin);
    271     actions.push_back(new InputFileAction(pos, *input));
    272     actions.push_back(new ContextAction(pos));
    273     actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
    274   }
    275 
    276   // -----  namespecs  ----- //
    277   cl::list<std::string>::iterator namespec, nsBegin, nsEnd;
    278   nsBegin = ArgNameSpecList.begin();
    279   nsEnd = ArgNameSpecList.end();
    280   for (namespec = nsBegin; namespec != nsEnd; ++namespec) {
    281     unsigned int pos = ArgNameSpecList.getPosition(namespec - nsBegin);
    282     actions.push_back(new NamespecAction(pos, *namespec,
    283                                          m_Config.options().directories()));
    284     actions.push_back(new ContextAction(pos));
    285     actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly));
    286   }
    287 
    288   // -----  attributes  ----- //
    289   /// --whole-archive
    290   cl::list<bool>::iterator attr, attrBegin, attrEnd;
    291   attrBegin = ArgWholeArchiveList.begin();
    292   attrEnd   = ArgWholeArchiveList.end();
    293   for (attr = attrBegin; attr != attrEnd; ++attr) {
    294     unsigned int pos = ArgWholeArchiveList.getPosition(attr - attrBegin);
    295     actions.push_back(new WholeArchiveAction(pos));
    296   }
    297 
    298   /// --no-whole-archive
    299   attrBegin = ArgNoWholeArchiveList.begin();
    300   attrEnd   = ArgNoWholeArchiveList.end();
    301   for (attr = attrBegin; attr != attrEnd; ++attr) {
    302     unsigned int pos = ArgNoWholeArchiveList.getPosition(attr - attrBegin);
    303     actions.push_back(new NoWholeArchiveAction(pos));
    304   }
    305 
    306   /// --as-needed
    307   attrBegin = ArgAsNeededList.begin();
    308   attrEnd   = ArgAsNeededList.end();
    309   for (attr = attrBegin; attr != attrEnd; ++attr) {
    310     unsigned int pos = ArgAsNeededList.getPosition(attr - attrBegin);
    311     actions.push_back(new AsNeededAction(pos));
    312   }
    313 
    314   /// --no-as-needed
    315   attrBegin = ArgNoAsNeededList.begin();
    316   attrEnd   = ArgNoAsNeededList.end();
    317   for (attr = attrBegin; attr != attrEnd; ++attr) {
    318     unsigned int pos = ArgNoAsNeededList.getPosition(attr - attrBegin);
    319     actions.push_back(new NoAsNeededAction(pos));
    320   }
    321 
    322   /// --add--needed
    323   attrBegin = ArgAddNeededList.begin();
    324   attrEnd   = ArgAddNeededList.end();
    325   for (attr = attrBegin; attr != attrEnd; ++attr) {
    326     unsigned int pos = ArgAddNeededList.getPosition(attr - attrBegin);
    327     actions.push_back(new AddNeededAction(pos));
    328   }
    329 
    330   /// --no-add--needed
    331   attrBegin = ArgNoAddNeededList.begin();
    332   attrEnd   = ArgNoAddNeededList.end();
    333   for (attr = attrBegin; attr != attrEnd; ++attr) {
    334     unsigned int pos = ArgNoAddNeededList.getPosition(attr - attrBegin);
    335     actions.push_back(new NoAddNeededAction(pos));
    336   }
    337 
    338   /// --Bdynamic
    339   attrBegin = ArgBDynamicList.begin();
    340   attrEnd   = ArgBDynamicList.end();
    341   for (attr = attrBegin; attr != attrEnd; ++attr) {
    342     unsigned int pos = ArgBDynamicList.getPosition(attr - attrBegin);
    343     actions.push_back(new BDynamicAction(pos));
    344   }
    345 
    346   /// --Bstatic
    347   attrBegin = ArgBStaticList.begin();
    348   attrEnd   = ArgBStaticList.end();
    349   for (attr = attrBegin; attr != attrEnd; ++attr) {
    350     unsigned int pos = ArgBStaticList.getPosition(attr - attrBegin);
    351     actions.push_back(new BStaticAction(pos));
    352   }
    353 
    354   // -----  groups  ----- //
    355   /// --start-group
    356   cl::list<bool>::iterator group, gsBegin, gsEnd;
    357   gsBegin = ArgStartGroupList.begin();
    358   gsEnd   = ArgStartGroupList.end();
    359   for (group = gsBegin; group != gsEnd; ++group) {
    360     unsigned int pos = ArgStartGroupList.getPosition(group - gsBegin);
    361     actions.push_back(new StartGroupAction(pos));
    362   }
    363 
    364   /// --end-group
    365   gsBegin = ArgEndGroupList.begin();
    366   gsEnd   = ArgEndGroupList.end();
    367   for (group = gsBegin; group != gsEnd; ++group) {
    368     unsigned int pos = ArgEndGroupList.getPosition(group - gsBegin);
    369     actions.push_back(new EndGroupAction(pos));
    370   }
    371 
    372   // -----  bitcode  ----- //
    373   if (m_Config.bitcode().hasDefined()) {
    374     actions.push_back(new BitcodeAction(m_Config.bitcode().getPosition(),
    375                                         m_Config.bitcode().getPath()));
    376   }
    377 
    378   // stable sort
    379   std::stable_sort(actions.begin(), actions.end(), CompareAction);
    380 
    381   // build up input tree
    382   std::vector<InputAction*>::iterator action, actionEnd = actions.end();
    383   for (action = actions.begin(); action != actionEnd; ++action) {
    384     (*action)->activate(pBuilder.getInputBuilder());
    385     delete *action;
    386   }
    387 
    388   if (pBuilder.getInputBuilder().isInGroup())
    389     report_fatal_error("no matched --start-group and --end-group");
    390 }
    391 
    392