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