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 //===----------------------------------------------------------------------===// 24 InputFileAction::InputFileAction(unsigned int pPosition, 25 const sys::fs::Path &pPath) 26 : InputAction(pPosition), m_Path(pPath) { 27 } 28 29 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 //===----------------------------------------------------------------------===// 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 44 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 //===----------------------------------------------------------------------===// 79 BitcodeAction::BitcodeAction(unsigned int pPosition, const sys::fs::Path &pPath) 80 : InputAction(pPosition), m_Path(pPath) { 81 } 82 83 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 //===----------------------------------------------------------------------===// 92 StartGroupAction::StartGroupAction(unsigned int pPosition) 93 : InputAction(pPosition) { 94 } 95 96 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 //===----------------------------------------------------------------------===// 109 EndGroupAction::EndGroupAction(unsigned int pPosition) 110 : InputAction(pPosition) { 111 } 112 113 bool EndGroupAction::activate(InputBuilder& pBuilder) const 114 { 115 pBuilder.exitGroup(); 116 return true; 117 } 118 119 //===----------------------------------------------------------------------===// 120 // WholeArchiveAction 121 //===----------------------------------------------------------------------===// 122 WholeArchiveAction::WholeArchiveAction(unsigned int pPosition) 123 : InputAction(pPosition) { 124 } 125 126 bool WholeArchiveAction::activate(InputBuilder& pBuilder) const 127 { 128 pBuilder.getAttributes().setWholeArchive(); 129 return true; 130 } 131 132 //===----------------------------------------------------------------------===// 133 // NoWholeArchiveAction 134 //===----------------------------------------------------------------------===// 135 NoWholeArchiveAction::NoWholeArchiveAction(unsigned int pPosition) 136 : InputAction(pPosition) { 137 } 138 139 bool NoWholeArchiveAction::activate(InputBuilder& pBuilder) const 140 { 141 pBuilder.getAttributes().unsetWholeArchive(); 142 return true; 143 } 144 145 //===----------------------------------------------------------------------===// 146 // AsNeededAction 147 //===----------------------------------------------------------------------===// 148 AsNeededAction::AsNeededAction(unsigned int pPosition) 149 : InputAction(pPosition) { 150 } 151 152 bool AsNeededAction::activate(InputBuilder& pBuilder) const 153 { 154 pBuilder.getAttributes().setAsNeeded(); 155 return true; 156 } 157 158 //===----------------------------------------------------------------------===// 159 // NoAsNeededAction 160 //===----------------------------------------------------------------------===// 161 NoAsNeededAction::NoAsNeededAction(unsigned int pPosition) 162 : InputAction(pPosition) { 163 } 164 165 bool NoAsNeededAction::activate(InputBuilder& pBuilder) const 166 { 167 pBuilder.getAttributes().unsetAsNeeded(); 168 return true; 169 } 170 171 //===----------------------------------------------------------------------===// 172 // AddNeededAction 173 //===----------------------------------------------------------------------===// 174 AddNeededAction::AddNeededAction(unsigned int pPosition) 175 : InputAction(pPosition) { 176 } 177 178 bool AddNeededAction::activate(InputBuilder& pBuilder) const 179 { 180 pBuilder.getAttributes().setAddNeeded(); 181 return true; 182 } 183 184 //===----------------------------------------------------------------------===// 185 // NoAddNeededAction 186 //===----------------------------------------------------------------------===// 187 NoAddNeededAction::NoAddNeededAction(unsigned int pPosition) 188 : InputAction(pPosition) { 189 } 190 191 bool NoAddNeededAction::activate(InputBuilder& pBuilder) const 192 { 193 pBuilder.getAttributes().unsetAddNeeded(); 194 return true; 195 } 196 197 //===----------------------------------------------------------------------===// 198 // BDynamicAction 199 //===----------------------------------------------------------------------===// 200 BDynamicAction::BDynamicAction(unsigned int pPosition) 201 : InputAction(pPosition) { 202 } 203 204 bool BDynamicAction::activate(InputBuilder& pBuilder) const 205 { 206 pBuilder.getAttributes().setDynamic(); 207 return true; 208 } 209 210 //===----------------------------------------------------------------------===// 211 // BStaticAction 212 //===----------------------------------------------------------------------===// 213 BStaticAction::BStaticAction(unsigned int pPosition) 214 : InputAction(pPosition) { 215 } 216 217 bool BStaticAction::activate(InputBuilder& pBuilder) const 218 { 219 pBuilder.getAttributes().setStatic(); 220 return true; 221 } 222 223 //===----------------------------------------------------------------------===// 224 // DefSymAction 225 //===----------------------------------------------------------------------===// 226 DefSymAction::DefSymAction(unsigned int pPosition, std::string& pAssignment) 227 : InputAction(pPosition), m_Assignment(pAssignment) { 228 } 229 230 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 //===----------------------------------------------------------------------===// 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 254 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