CommandAction.cpp revision f33f6de54db174aa679a4b6d1e040d37e95541c0
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 17using namespace mcld; 18 19//===----------------------------------------------------------------------===// 20// Derived Positional Option 21//===----------------------------------------------------------------------===// 22// InputFileAction 23//===----------------------------------------------------------------------===// 24InputFileAction::InputFileAction(unsigned int pPosition, 25 const sys::fs::Path &pPath) 26 : InputAction(pPosition), m_Path(pPath) { 27} 28 29bool InputFileAction::activate(InputBuilder& pBuilder) const 30{ 31 pBuilder.createNode<InputTree::Positional>(path().stem().native(), path()); 32 return true; 33} 34 35//===----------------------------------------------------------------------===// 36// NamespecAction 37//===----------------------------------------------------------------------===// 38NamespecAction::NamespecAction(unsigned int pPosition, 39 const std::string &pNamespec, 40 const SearchDirs& pSearchDirs) 41 : InputAction(pPosition), m_Namespec(pNamespec), m_SearchDirs(pSearchDirs) { 42} 43 44bool 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//===----------------------------------------------------------------------===// 79BitcodeAction::BitcodeAction(unsigned int pPosition, const sys::fs::Path &pPath) 80 : InputAction(pPosition), m_Path(pPath) { 81} 82 83bool BitcodeAction::activate(InputBuilder& pBuilder) const 84{ 85 pBuilder.createNode<InputTree::Positional>("bitcode", path(), Input::External); 86 return true; 87} 88 89//===----------------------------------------------------------------------===// 90// StartGroupAction 91//===----------------------------------------------------------------------===// 92StartGroupAction::StartGroupAction(unsigned int pPosition) 93 : InputAction(pPosition) { 94} 95 96bool 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//===----------------------------------------------------------------------===// 109EndGroupAction::EndGroupAction(unsigned int pPosition) 110 : InputAction(pPosition) { 111} 112 113bool EndGroupAction::activate(InputBuilder& pBuilder) const 114{ 115 pBuilder.exitGroup(); 116 return true; 117} 118 119//===----------------------------------------------------------------------===// 120// WholeArchiveAction 121//===----------------------------------------------------------------------===// 122WholeArchiveAction::WholeArchiveAction(unsigned int pPosition) 123 : InputAction(pPosition) { 124} 125 126bool WholeArchiveAction::activate(InputBuilder& pBuilder) const 127{ 128 pBuilder.getAttributes().setWholeArchive(); 129 return true; 130} 131 132//===----------------------------------------------------------------------===// 133// NoWholeArchiveAction 134//===----------------------------------------------------------------------===// 135NoWholeArchiveAction::NoWholeArchiveAction(unsigned int pPosition) 136 : InputAction(pPosition) { 137} 138 139bool NoWholeArchiveAction::activate(InputBuilder& pBuilder) const 140{ 141 pBuilder.getAttributes().unsetWholeArchive(); 142 return true; 143} 144 145//===----------------------------------------------------------------------===// 146// AsNeededAction 147//===----------------------------------------------------------------------===// 148AsNeededAction::AsNeededAction(unsigned int pPosition) 149 : InputAction(pPosition) { 150} 151 152bool AsNeededAction::activate(InputBuilder& pBuilder) const 153{ 154 pBuilder.getAttributes().setAsNeeded(); 155 return true; 156} 157 158//===----------------------------------------------------------------------===// 159// NoAsNeededAction 160//===----------------------------------------------------------------------===// 161NoAsNeededAction::NoAsNeededAction(unsigned int pPosition) 162 : InputAction(pPosition) { 163} 164 165bool NoAsNeededAction::activate(InputBuilder& pBuilder) const 166{ 167 pBuilder.getAttributes().unsetAsNeeded(); 168 return true; 169} 170 171//===----------------------------------------------------------------------===// 172// AddNeededAction 173//===----------------------------------------------------------------------===// 174AddNeededAction::AddNeededAction(unsigned int pPosition) 175 : InputAction(pPosition) { 176} 177 178bool AddNeededAction::activate(InputBuilder& pBuilder) const 179{ 180 pBuilder.getAttributes().setAddNeeded(); 181 return true; 182} 183 184//===----------------------------------------------------------------------===// 185// NoAddNeededAction 186//===----------------------------------------------------------------------===// 187NoAddNeededAction::NoAddNeededAction(unsigned int pPosition) 188 : InputAction(pPosition) { 189} 190 191bool NoAddNeededAction::activate(InputBuilder& pBuilder) const 192{ 193 pBuilder.getAttributes().unsetAddNeeded(); 194 return true; 195} 196 197//===----------------------------------------------------------------------===// 198// BDynamicAction 199//===----------------------------------------------------------------------===// 200BDynamicAction::BDynamicAction(unsigned int pPosition) 201 : InputAction(pPosition) { 202} 203 204bool BDynamicAction::activate(InputBuilder& pBuilder) const 205{ 206 pBuilder.getAttributes().setDynamic(); 207 return true; 208} 209 210//===----------------------------------------------------------------------===// 211// BStaticAction 212//===----------------------------------------------------------------------===// 213BStaticAction::BStaticAction(unsigned int pPosition) 214 : InputAction(pPosition) { 215} 216 217bool BStaticAction::activate(InputBuilder& pBuilder) const 218{ 219 pBuilder.getAttributes().setStatic(); 220 return true; 221} 222 223//===----------------------------------------------------------------------===// 224// DefSymAction 225//===----------------------------------------------------------------------===// 226DefSymAction::DefSymAction(unsigned int pPosition, std::string& pAssignment) 227 : InputAction(pPosition), m_Assignment(pAssignment) { 228} 229 230bool 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//===----------------------------------------------------------------------===// 244ScriptAction::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 254bool 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