• 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 #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