Home | History | Annotate | Download | only in MC
      1 //===- CommandAction.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/CommandAction.h>
     10 #include <mcld/MC/InputBuilder.h>
     11 #include <mcld/MC/SearchDirs.h>
     12 #include <mcld/MC/Attribute.h>
     13 #include <mcld/Support/MsgHandling.h>
     14 #include <mcld/Support/FileSystem.h>
     15 #include <mcld/LinkerConfig.h>
     16 
     17 using namespace mcld;
     18 
     19 //===----------------------------------------------------------------------===//
     20 // Derived Positional Option
     21 //===----------------------------------------------------------------------===//
     22 // InputFileAction
     23 //===----------------------------------------------------------------------===//
     24 InputFileAction::InputFileAction(unsigned int pPosition,
     25                                  const sys::fs::Path &pPath)
     26   : InputAction(pPosition), m_Path(pPath) {
     27 }
     28 
     29 bool InputFileAction::activate(InputBuilder& pBuilder) const
     30 {
     31   pBuilder.createNode<InputTree::Positional>(path().stem().native(), path());
     32   return true;
     33 }
     34 
     35 //===----------------------------------------------------------------------===//
     36 // NamespecAction
     37 //===----------------------------------------------------------------------===//
     38 NamespecAction::NamespecAction(unsigned int pPosition,
     39                                const std::string &pNamespec,
     40                                const SearchDirs& pSearchDirs)
     41   : InputAction(pPosition), m_Namespec(pNamespec), m_SearchDirs(pSearchDirs) {
     42 }
     43 
     44 bool NamespecAction::activate(InputBuilder& pBuilder) const
     45 {
     46   const sys::fs::Path* path = NULL;
     47   // find out the real path of the namespec.
     48   if (pBuilder.getConstraint().isSharedSystem()) {
     49     // In the system with shared object support, we can find both archive
     50     // and shared object.
     51 
     52     if (pBuilder.getAttributes().isStatic()) {
     53       // with --static, we must search an archive.
     54       path = m_SearchDirs.find(namespec(), Input::Archive);
     55     }
     56     else {
     57       // otherwise, with --Bdynamic, we can find either an archive or a
     58       // shared object.
     59       path = m_SearchDirs.find(namespec(), Input::DynObj);
     60     }
     61   }
     62   else {
     63     // In the system without shared object support, we only look for an archive
     64     path = m_SearchDirs.find(namespec(), Input::Archive);
     65   }
     66 
     67   if (NULL == path) {
     68     fatal(diag::err_cannot_find_namespec) << namespec();
     69     return false;
     70   }
     71 
     72   pBuilder.createNode<InputTree::Positional>(namespec(), *path);
     73   return true;
     74 }
     75 
     76 //===----------------------------------------------------------------------===//
     77 // BitcodeAction
     78 //===----------------------------------------------------------------------===//
     79 BitcodeAction::BitcodeAction(unsigned int pPosition, const sys::fs::Path &pPath)
     80   : InputAction(pPosition), m_Path(pPath) {
     81 }
     82 
     83 bool BitcodeAction::activate(InputBuilder& pBuilder) const
     84 {
     85   pBuilder.createNode<InputTree::Positional>("bitcode", path(), Input::External);
     86   return true;
     87 }
     88 
     89 //===----------------------------------------------------------------------===//
     90 // StartGroupAction
     91 //===----------------------------------------------------------------------===//
     92 StartGroupAction::StartGroupAction(unsigned int pPosition)
     93   : InputAction(pPosition) {
     94 }
     95 
     96 bool StartGroupAction::activate(InputBuilder& pBuilder) const
     97 {
     98   if (pBuilder.isInGroup()) {
     99     fatal(diag::fatal_forbid_nest_group);
    100     return false;
    101   }
    102   pBuilder.enterGroup();
    103   return true;
    104 }
    105 
    106 //===----------------------------------------------------------------------===//
    107 // EndGroupAction
    108 //===----------------------------------------------------------------------===//
    109 EndGroupAction::EndGroupAction(unsigned int pPosition)
    110   : InputAction(pPosition) {
    111 }
    112 
    113 bool EndGroupAction::activate(InputBuilder& pBuilder) const
    114 {
    115   pBuilder.exitGroup();
    116   return true;
    117 }
    118 
    119 //===----------------------------------------------------------------------===//
    120 // WholeArchiveAction
    121 //===----------------------------------------------------------------------===//
    122 WholeArchiveAction::WholeArchiveAction(unsigned int pPosition)
    123   : InputAction(pPosition) {
    124 }
    125 
    126 bool WholeArchiveAction::activate(InputBuilder& pBuilder) const
    127 {
    128   pBuilder.getAttributes().setWholeArchive();
    129   return true;
    130 }
    131 
    132 //===----------------------------------------------------------------------===//
    133 // NoWholeArchiveAction
    134 //===----------------------------------------------------------------------===//
    135 NoWholeArchiveAction::NoWholeArchiveAction(unsigned int pPosition)
    136   : InputAction(pPosition) {
    137 }
    138 
    139 bool NoWholeArchiveAction::activate(InputBuilder& pBuilder) const
    140 {
    141   pBuilder.getAttributes().unsetWholeArchive();
    142   return true;
    143 }
    144 
    145 //===----------------------------------------------------------------------===//
    146 // AsNeededAction
    147 //===----------------------------------------------------------------------===//
    148 AsNeededAction::AsNeededAction(unsigned int pPosition)
    149   : InputAction(pPosition) {
    150 }
    151 
    152 bool AsNeededAction::activate(InputBuilder& pBuilder) const
    153 {
    154   pBuilder.getAttributes().setAsNeeded();
    155   return true;
    156 }
    157 
    158 //===----------------------------------------------------------------------===//
    159 // NoAsNeededAction
    160 //===----------------------------------------------------------------------===//
    161 NoAsNeededAction::NoAsNeededAction(unsigned int pPosition)
    162   : InputAction(pPosition) {
    163 }
    164 
    165 bool NoAsNeededAction::activate(InputBuilder& pBuilder) const
    166 {
    167   pBuilder.getAttributes().unsetAsNeeded();
    168   return true;
    169 }
    170 
    171 //===----------------------------------------------------------------------===//
    172 // AddNeededAction
    173 //===----------------------------------------------------------------------===//
    174 AddNeededAction::AddNeededAction(unsigned int pPosition)
    175   : InputAction(pPosition) {
    176 }
    177 
    178 bool AddNeededAction::activate(InputBuilder& pBuilder) const
    179 {
    180   pBuilder.getAttributes().setAddNeeded();
    181   return true;
    182 }
    183 
    184 //===----------------------------------------------------------------------===//
    185 // NoAddNeededAction
    186 //===----------------------------------------------------------------------===//
    187 NoAddNeededAction::NoAddNeededAction(unsigned int pPosition)
    188   : InputAction(pPosition) {
    189 }
    190 
    191 bool NoAddNeededAction::activate(InputBuilder& pBuilder) const
    192 {
    193   pBuilder.getAttributes().unsetAddNeeded();
    194   return true;
    195 }
    196 
    197 //===----------------------------------------------------------------------===//
    198 // BDynamicAction
    199 //===----------------------------------------------------------------------===//
    200 BDynamicAction::BDynamicAction(unsigned int pPosition)
    201   : InputAction(pPosition) {
    202 }
    203 
    204 bool BDynamicAction::activate(InputBuilder& pBuilder) const
    205 {
    206   pBuilder.getAttributes().setDynamic();
    207   return true;
    208 }
    209 
    210 //===----------------------------------------------------------------------===//
    211 // BStaticAction
    212 //===----------------------------------------------------------------------===//
    213 BStaticAction::BStaticAction(unsigned int pPosition)
    214   : InputAction(pPosition) {
    215 }
    216 
    217 bool BStaticAction::activate(InputBuilder& pBuilder) const
    218 {
    219   pBuilder.getAttributes().setStatic();
    220   return true;
    221 }
    222 
    223 //===----------------------------------------------------------------------===//
    224 // DefSymAction
    225 //===----------------------------------------------------------------------===//
    226 DefSymAction::DefSymAction(unsigned int pPosition, std::string& pAssignment)
    227   : InputAction(pPosition), m_Assignment(pAssignment) {
    228 }
    229 
    230 bool DefSymAction::activate(InputBuilder& pBuilder) const
    231 {
    232   pBuilder.createNode<InputTree::Positional>("defsym", "NAN");
    233   Input* input = *pBuilder.getCurrentNode();
    234   pBuilder.setContext(*input, false);
    235 
    236   m_Assignment.append(";");
    237   pBuilder.setMemory(*input, &m_Assignment[0], m_Assignment.size());
    238   return true;
    239 }
    240 
    241 //===----------------------------------------------------------------------===//
    242 // ScriptAction
    243 //===----------------------------------------------------------------------===//
    244 ScriptAction::ScriptAction(unsigned int pPosition,
    245                            const std::string& pFileName,
    246                            ScriptFile::Kind pKind,
    247                            const SearchDirs& pSearchDirs)
    248   : InputAction(pPosition),
    249     m_FileName(pFileName),
    250     m_Kind(pKind),
    251     m_SearchDirs(pSearchDirs) {
    252 }
    253 
    254 bool ScriptAction::activate(InputBuilder& pBuilder) const
    255 {
    256   sys::fs::Path path(m_FileName);
    257 
    258   if (!exists(path)) {
    259     const sys::fs::Path* res = m_SearchDirs.find(m_FileName, Input::Script);
    260     if (res == NULL) {
    261       switch (m_Kind) {
    262       case ScriptFile::LDScript:
    263         fatal(diag::err_cannot_find_scriptfile) << "linker script" << m_FileName;
    264         break;
    265       case ScriptFile::VersionScript:
    266         fatal(diag::err_cannot_find_scriptfile) << "version script" << m_FileName;
    267         break;
    268       case ScriptFile::DynamicList:
    269         fatal(diag::err_cannot_find_scriptfile) << "dynamic list" << m_FileName;
    270         break;
    271       default:
    272         break;
    273       }
    274       return false;
    275     }
    276     path.assign(res->native());
    277   }
    278 
    279   pBuilder.createNode<InputTree::Positional>(path.stem().native(), path);
    280 
    281   return true;
    282 }
    283