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 //===----------------------------------------------------------------------===// 25 InputFileAction::InputFileAction(unsigned int pPosition, 26 const sys::fs::Path& pPath) 27 : InputAction(pPosition), m_Path(pPath) { 28 } 29 30 InputFileAction::InputFileAction(unsigned int pPosition, 31 const char* pPath) 32 : InputAction(pPosition), m_Path(pPath) { 33 } 34 35 bool InputFileAction::activate(InputBuilder& pBuilder) const { 36 pBuilder.createNode<InputTree::Positional>(path().stem().native(), path()); 37 return true; 38 } 39 40 //===----------------------------------------------------------------------===// 41 // NamespecAction 42 //===----------------------------------------------------------------------===// 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 49 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 //===----------------------------------------------------------------------===// 81 BitcodeAction::BitcodeAction(unsigned int pPosition, const sys::fs::Path& pPath) 82 : InputAction(pPosition), m_Path(pPath) { 83 } 84 85 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 //===----------------------------------------------------------------------===// 94 StartGroupAction::StartGroupAction(unsigned int pPosition) 95 : InputAction(pPosition) { 96 } 97 98 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 //===----------------------------------------------------------------------===// 110 EndGroupAction::EndGroupAction(unsigned int pPosition) 111 : InputAction(pPosition) { 112 } 113 114 bool EndGroupAction::activate(InputBuilder& pBuilder) const { 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 pBuilder.getAttributes().setWholeArchive(); 128 return true; 129 } 130 131 //===----------------------------------------------------------------------===// 132 // NoWholeArchiveAction 133 //===----------------------------------------------------------------------===// 134 NoWholeArchiveAction::NoWholeArchiveAction(unsigned int pPosition) 135 : InputAction(pPosition) { 136 } 137 138 bool NoWholeArchiveAction::activate(InputBuilder& pBuilder) const { 139 pBuilder.getAttributes().unsetWholeArchive(); 140 return true; 141 } 142 143 //===----------------------------------------------------------------------===// 144 // AsNeededAction 145 //===----------------------------------------------------------------------===// 146 AsNeededAction::AsNeededAction(unsigned int pPosition) 147 : InputAction(pPosition) { 148 } 149 150 bool AsNeededAction::activate(InputBuilder& pBuilder) const { 151 pBuilder.getAttributes().setAsNeeded(); 152 return true; 153 } 154 155 //===----------------------------------------------------------------------===// 156 // NoAsNeededAction 157 //===----------------------------------------------------------------------===// 158 NoAsNeededAction::NoAsNeededAction(unsigned int pPosition) 159 : InputAction(pPosition) { 160 } 161 162 bool NoAsNeededAction::activate(InputBuilder& pBuilder) const { 163 pBuilder.getAttributes().unsetAsNeeded(); 164 return true; 165 } 166 167 //===----------------------------------------------------------------------===// 168 // AddNeededAction 169 //===----------------------------------------------------------------------===// 170 AddNeededAction::AddNeededAction(unsigned int pPosition) 171 : InputAction(pPosition) { 172 } 173 174 bool AddNeededAction::activate(InputBuilder& pBuilder) const { 175 pBuilder.getAttributes().setAddNeeded(); 176 return true; 177 } 178 179 //===----------------------------------------------------------------------===// 180 // NoAddNeededAction 181 //===----------------------------------------------------------------------===// 182 NoAddNeededAction::NoAddNeededAction(unsigned int pPosition) 183 : InputAction(pPosition) { 184 } 185 186 bool NoAddNeededAction::activate(InputBuilder& pBuilder) const { 187 pBuilder.getAttributes().unsetAddNeeded(); 188 return true; 189 } 190 191 //===----------------------------------------------------------------------===// 192 // BDynamicAction 193 //===----------------------------------------------------------------------===// 194 BDynamicAction::BDynamicAction(unsigned int pPosition) 195 : InputAction(pPosition) { 196 } 197 198 bool BDynamicAction::activate(InputBuilder& pBuilder) const { 199 pBuilder.getAttributes().setDynamic(); 200 return true; 201 } 202 203 //===----------------------------------------------------------------------===// 204 // BStaticAction 205 //===----------------------------------------------------------------------===// 206 BStaticAction::BStaticAction(unsigned int pPosition) : InputAction(pPosition) { 207 } 208 209 bool BStaticAction::activate(InputBuilder& pBuilder) const { 210 pBuilder.getAttributes().setStatic(); 211 return true; 212 } 213 214 //===----------------------------------------------------------------------===// 215 // DefSymAction 216 //===----------------------------------------------------------------------===// 217 DefSymAction::DefSymAction(unsigned int pPosition, 218 const std::string& pAssignment) 219 : InputAction(pPosition), m_Assignment(pAssignment) { 220 } 221 222 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 //===----------------------------------------------------------------------===// 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 246 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