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