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