• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  //===----------------------------------------------------------------------===//
InputFileAction(unsigned int pPosition,const sys::fs::Path & pPath)25  InputFileAction::InputFileAction(unsigned int pPosition,
26                                   const sys::fs::Path& pPath)
27      : InputAction(pPosition), m_Path(pPath) {
28  }
29  
InputFileAction(unsigned int pPosition,const char * pPath)30  InputFileAction::InputFileAction(unsigned int pPosition,
31                                   const char* pPath)
32      : InputAction(pPosition), m_Path(pPath) {
33  }
34  
activate(InputBuilder & pBuilder) const35  bool InputFileAction::activate(InputBuilder& pBuilder) const {
36    pBuilder.createNode<InputTree::Positional>(path().stem().native(), path());
37    return true;
38  }
39  
40  //===----------------------------------------------------------------------===//
41  // NamespecAction
42  //===----------------------------------------------------------------------===//
NamespecAction(unsigned int pPosition,const std::string & pNamespec,const SearchDirs & pSearchDirs)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  
activate(InputBuilder & pBuilder) const49  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  //===----------------------------------------------------------------------===//
BitcodeAction(unsigned int pPosition,const sys::fs::Path & pPath)81  BitcodeAction::BitcodeAction(unsigned int pPosition, const sys::fs::Path& pPath)
82      : InputAction(pPosition), m_Path(pPath) {
83  }
84  
activate(InputBuilder & pBuilder) const85  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  //===----------------------------------------------------------------------===//
StartGroupAction(unsigned int pPosition)94  StartGroupAction::StartGroupAction(unsigned int pPosition)
95      : InputAction(pPosition) {
96  }
97  
activate(InputBuilder & pBuilder) const98  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  //===----------------------------------------------------------------------===//
EndGroupAction(unsigned int pPosition)110  EndGroupAction::EndGroupAction(unsigned int pPosition)
111      : InputAction(pPosition) {
112  }
113  
activate(InputBuilder & pBuilder) const114  bool EndGroupAction::activate(InputBuilder& pBuilder) const {
115    pBuilder.exitGroup();
116    return true;
117  }
118  
119  //===----------------------------------------------------------------------===//
120  // WholeArchiveAction
121  //===----------------------------------------------------------------------===//
WholeArchiveAction(unsigned int pPosition)122  WholeArchiveAction::WholeArchiveAction(unsigned int pPosition)
123      : InputAction(pPosition) {
124  }
125  
activate(InputBuilder & pBuilder) const126  bool WholeArchiveAction::activate(InputBuilder& pBuilder) const {
127    pBuilder.getAttributes().setWholeArchive();
128    return true;
129  }
130  
131  //===----------------------------------------------------------------------===//
132  // NoWholeArchiveAction
133  //===----------------------------------------------------------------------===//
NoWholeArchiveAction(unsigned int pPosition)134  NoWholeArchiveAction::NoWholeArchiveAction(unsigned int pPosition)
135      : InputAction(pPosition) {
136  }
137  
activate(InputBuilder & pBuilder) const138  bool NoWholeArchiveAction::activate(InputBuilder& pBuilder) const {
139    pBuilder.getAttributes().unsetWholeArchive();
140    return true;
141  }
142  
143  //===----------------------------------------------------------------------===//
144  // AsNeededAction
145  //===----------------------------------------------------------------------===//
AsNeededAction(unsigned int pPosition)146  AsNeededAction::AsNeededAction(unsigned int pPosition)
147      : InputAction(pPosition) {
148  }
149  
activate(InputBuilder & pBuilder) const150  bool AsNeededAction::activate(InputBuilder& pBuilder) const {
151    pBuilder.getAttributes().setAsNeeded();
152    return true;
153  }
154  
155  //===----------------------------------------------------------------------===//
156  // NoAsNeededAction
157  //===----------------------------------------------------------------------===//
NoAsNeededAction(unsigned int pPosition)158  NoAsNeededAction::NoAsNeededAction(unsigned int pPosition)
159      : InputAction(pPosition) {
160  }
161  
activate(InputBuilder & pBuilder) const162  bool NoAsNeededAction::activate(InputBuilder& pBuilder) const {
163    pBuilder.getAttributes().unsetAsNeeded();
164    return true;
165  }
166  
167  //===----------------------------------------------------------------------===//
168  // AddNeededAction
169  //===----------------------------------------------------------------------===//
AddNeededAction(unsigned int pPosition)170  AddNeededAction::AddNeededAction(unsigned int pPosition)
171      : InputAction(pPosition) {
172  }
173  
activate(InputBuilder & pBuilder) const174  bool AddNeededAction::activate(InputBuilder& pBuilder) const {
175    pBuilder.getAttributes().setAddNeeded();
176    return true;
177  }
178  
179  //===----------------------------------------------------------------------===//
180  // NoAddNeededAction
181  //===----------------------------------------------------------------------===//
NoAddNeededAction(unsigned int pPosition)182  NoAddNeededAction::NoAddNeededAction(unsigned int pPosition)
183      : InputAction(pPosition) {
184  }
185  
activate(InputBuilder & pBuilder) const186  bool NoAddNeededAction::activate(InputBuilder& pBuilder) const {
187    pBuilder.getAttributes().unsetAddNeeded();
188    return true;
189  }
190  
191  //===----------------------------------------------------------------------===//
192  // BDynamicAction
193  //===----------------------------------------------------------------------===//
BDynamicAction(unsigned int pPosition)194  BDynamicAction::BDynamicAction(unsigned int pPosition)
195      : InputAction(pPosition) {
196  }
197  
activate(InputBuilder & pBuilder) const198  bool BDynamicAction::activate(InputBuilder& pBuilder) const {
199    pBuilder.getAttributes().setDynamic();
200    return true;
201  }
202  
203  //===----------------------------------------------------------------------===//
204  // BStaticAction
205  //===----------------------------------------------------------------------===//
BStaticAction(unsigned int pPosition)206  BStaticAction::BStaticAction(unsigned int pPosition) : InputAction(pPosition) {
207  }
208  
activate(InputBuilder & pBuilder) const209  bool BStaticAction::activate(InputBuilder& pBuilder) const {
210    pBuilder.getAttributes().setStatic();
211    return true;
212  }
213  
214  //===----------------------------------------------------------------------===//
215  // DefSymAction
216  //===----------------------------------------------------------------------===//
DefSymAction(unsigned int pPosition,const std::string & pAssignment)217  DefSymAction::DefSymAction(unsigned int pPosition,
218                             const std::string& pAssignment)
219      : InputAction(pPosition), m_Assignment(pAssignment) {
220  }
221  
activate(InputBuilder & pBuilder) const222  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  //===----------------------------------------------------------------------===//
ScriptAction(unsigned int pPosition,const std::string & pFileName,ScriptFile::Kind pKind,const SearchDirs & pSearchDirs)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  
activate(InputBuilder & pBuilder) const246  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