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 //===----------------------------------------------------------------------===//
InputFileAction(unsigned int pPosition,const sys::fs::Path & pPath)24 InputFileAction::InputFileAction(unsigned int pPosition,
25 const sys::fs::Path &pPath)
26 : InputAction(pPosition), m_Path(pPath) {
27 }
28
activate(InputBuilder & pBuilder) const29 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 //===----------------------------------------------------------------------===//
NamespecAction(unsigned int pPosition,const std::string & pNamespec,const SearchDirs & pSearchDirs)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
activate(InputBuilder & pBuilder) const44 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 //===----------------------------------------------------------------------===//
BitcodeAction(unsigned int pPosition,const sys::fs::Path & pPath)79 BitcodeAction::BitcodeAction(unsigned int pPosition, const sys::fs::Path &pPath)
80 : InputAction(pPosition), m_Path(pPath) {
81 }
82
activate(InputBuilder & pBuilder) const83 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 //===----------------------------------------------------------------------===//
StartGroupAction(unsigned int pPosition)92 StartGroupAction::StartGroupAction(unsigned int pPosition)
93 : InputAction(pPosition) {
94 }
95
activate(InputBuilder & pBuilder) const96 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 //===----------------------------------------------------------------------===//
EndGroupAction(unsigned int pPosition)109 EndGroupAction::EndGroupAction(unsigned int pPosition)
110 : InputAction(pPosition) {
111 }
112
activate(InputBuilder & pBuilder) const113 bool EndGroupAction::activate(InputBuilder& pBuilder) const
114 {
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 {
128 pBuilder.getAttributes().setWholeArchive();
129 return true;
130 }
131
132 //===----------------------------------------------------------------------===//
133 // NoWholeArchiveAction
134 //===----------------------------------------------------------------------===//
NoWholeArchiveAction(unsigned int pPosition)135 NoWholeArchiveAction::NoWholeArchiveAction(unsigned int pPosition)
136 : InputAction(pPosition) {
137 }
138
activate(InputBuilder & pBuilder) const139 bool NoWholeArchiveAction::activate(InputBuilder& pBuilder) const
140 {
141 pBuilder.getAttributes().unsetWholeArchive();
142 return true;
143 }
144
145 //===----------------------------------------------------------------------===//
146 // AsNeededAction
147 //===----------------------------------------------------------------------===//
AsNeededAction(unsigned int pPosition)148 AsNeededAction::AsNeededAction(unsigned int pPosition)
149 : InputAction(pPosition) {
150 }
151
activate(InputBuilder & pBuilder) const152 bool AsNeededAction::activate(InputBuilder& pBuilder) const
153 {
154 pBuilder.getAttributes().setAsNeeded();
155 return true;
156 }
157
158 //===----------------------------------------------------------------------===//
159 // NoAsNeededAction
160 //===----------------------------------------------------------------------===//
NoAsNeededAction(unsigned int pPosition)161 NoAsNeededAction::NoAsNeededAction(unsigned int pPosition)
162 : InputAction(pPosition) {
163 }
164
activate(InputBuilder & pBuilder) const165 bool NoAsNeededAction::activate(InputBuilder& pBuilder) const
166 {
167 pBuilder.getAttributes().unsetAsNeeded();
168 return true;
169 }
170
171 //===----------------------------------------------------------------------===//
172 // AddNeededAction
173 //===----------------------------------------------------------------------===//
AddNeededAction(unsigned int pPosition)174 AddNeededAction::AddNeededAction(unsigned int pPosition)
175 : InputAction(pPosition) {
176 }
177
activate(InputBuilder & pBuilder) const178 bool AddNeededAction::activate(InputBuilder& pBuilder) const
179 {
180 pBuilder.getAttributes().setAddNeeded();
181 return true;
182 }
183
184 //===----------------------------------------------------------------------===//
185 // NoAddNeededAction
186 //===----------------------------------------------------------------------===//
NoAddNeededAction(unsigned int pPosition)187 NoAddNeededAction::NoAddNeededAction(unsigned int pPosition)
188 : InputAction(pPosition) {
189 }
190
activate(InputBuilder & pBuilder) const191 bool NoAddNeededAction::activate(InputBuilder& pBuilder) const
192 {
193 pBuilder.getAttributes().unsetAddNeeded();
194 return true;
195 }
196
197 //===----------------------------------------------------------------------===//
198 // BDynamicAction
199 //===----------------------------------------------------------------------===//
BDynamicAction(unsigned int pPosition)200 BDynamicAction::BDynamicAction(unsigned int pPosition)
201 : InputAction(pPosition) {
202 }
203
activate(InputBuilder & pBuilder) const204 bool BDynamicAction::activate(InputBuilder& pBuilder) const
205 {
206 pBuilder.getAttributes().setDynamic();
207 return true;
208 }
209
210 //===----------------------------------------------------------------------===//
211 // BStaticAction
212 //===----------------------------------------------------------------------===//
BStaticAction(unsigned int pPosition)213 BStaticAction::BStaticAction(unsigned int pPosition)
214 : InputAction(pPosition) {
215 }
216
activate(InputBuilder & pBuilder) const217 bool BStaticAction::activate(InputBuilder& pBuilder) const
218 {
219 pBuilder.getAttributes().setStatic();
220 return true;
221 }
222
223 //===----------------------------------------------------------------------===//
224 // DefSymAction
225 //===----------------------------------------------------------------------===//
DefSymAction(unsigned int pPosition,std::string & pAssignment)226 DefSymAction::DefSymAction(unsigned int pPosition, std::string& pAssignment)
227 : InputAction(pPosition), m_Assignment(pAssignment) {
228 }
229
activate(InputBuilder & pBuilder) const230 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 //===----------------------------------------------------------------------===//
ScriptAction(unsigned int pPosition,const std::string & pFileName,ScriptFile::Kind pKind,const SearchDirs & pSearchDirs)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
activate(InputBuilder & pBuilder) const254 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