//===- CommandAction.cpp --------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "mcld/MC/CommandAction.h" #include "mcld/LinkerConfig.h" #include "mcld/MC/Attribute.h" #include "mcld/MC/InputBuilder.h" #include "mcld/MC/SearchDirs.h" #include "mcld/Support/MsgHandling.h" #include "mcld/Support/FileSystem.h" namespace mcld { //===----------------------------------------------------------------------===// // Derived Positional Option //===----------------------------------------------------------------------===// // InputFileAction //===----------------------------------------------------------------------===// InputFileAction::InputFileAction(unsigned int pPosition, const sys::fs::Path& pPath) : InputAction(pPosition), m_Path(pPath) { } InputFileAction::InputFileAction(unsigned int pPosition, const char* pPath) : InputAction(pPosition), m_Path(pPath) { } bool InputFileAction::activate(InputBuilder& pBuilder) const { pBuilder.createNode<InputTree::Positional>(path().stem().native(), path()); return true; } //===----------------------------------------------------------------------===// // NamespecAction //===----------------------------------------------------------------------===// NamespecAction::NamespecAction(unsigned int pPosition, const std::string& pNamespec, const SearchDirs& pSearchDirs) : InputAction(pPosition), m_Namespec(pNamespec), m_SearchDirs(pSearchDirs) { } bool NamespecAction::activate(InputBuilder& pBuilder) const { const sys::fs::Path* path = NULL; // find out the real path of the namespec. if (pBuilder.getConstraint().isSharedSystem()) { // In the system with shared object support, we can find both archive // and shared object. if (pBuilder.getAttributes().isStatic()) { // with --static, we must search an archive. path = m_SearchDirs.find(namespec(), Input::Archive); } else { // otherwise, with --Bdynamic, we can find either an archive or a // shared object. path = m_SearchDirs.find(namespec(), Input::DynObj); } } else { // In the system without shared object support, we only look for an archive path = m_SearchDirs.find(namespec(), Input::Archive); } if (path == NULL) { fatal(diag::err_cannot_find_namespec) << namespec(); return false; } pBuilder.createNode<InputTree::Positional>(namespec(), *path); return true; } //===----------------------------------------------------------------------===// // BitcodeAction //===----------------------------------------------------------------------===// BitcodeAction::BitcodeAction(unsigned int pPosition, const sys::fs::Path& pPath) : InputAction(pPosition), m_Path(pPath) { } bool BitcodeAction::activate(InputBuilder& pBuilder) const { pBuilder.createNode<InputTree::Positional>( "bitcode", path(), Input::External); return true; } //===----------------------------------------------------------------------===// // StartGroupAction //===----------------------------------------------------------------------===// StartGroupAction::StartGroupAction(unsigned int pPosition) : InputAction(pPosition) { } bool StartGroupAction::activate(InputBuilder& pBuilder) const { if (pBuilder.isInGroup()) { fatal(diag::fatal_forbid_nest_group); return false; } pBuilder.enterGroup(); return true; } //===----------------------------------------------------------------------===// // EndGroupAction //===----------------------------------------------------------------------===// EndGroupAction::EndGroupAction(unsigned int pPosition) : InputAction(pPosition) { } bool EndGroupAction::activate(InputBuilder& pBuilder) const { pBuilder.exitGroup(); return true; } //===----------------------------------------------------------------------===// // WholeArchiveAction //===----------------------------------------------------------------------===// WholeArchiveAction::WholeArchiveAction(unsigned int pPosition) : InputAction(pPosition) { } bool WholeArchiveAction::activate(InputBuilder& pBuilder) const { pBuilder.getAttributes().setWholeArchive(); return true; } //===----------------------------------------------------------------------===// // NoWholeArchiveAction //===----------------------------------------------------------------------===// NoWholeArchiveAction::NoWholeArchiveAction(unsigned int pPosition) : InputAction(pPosition) { } bool NoWholeArchiveAction::activate(InputBuilder& pBuilder) const { pBuilder.getAttributes().unsetWholeArchive(); return true; } //===----------------------------------------------------------------------===// // AsNeededAction //===----------------------------------------------------------------------===// AsNeededAction::AsNeededAction(unsigned int pPosition) : InputAction(pPosition) { } bool AsNeededAction::activate(InputBuilder& pBuilder) const { pBuilder.getAttributes().setAsNeeded(); return true; } //===----------------------------------------------------------------------===// // NoAsNeededAction //===----------------------------------------------------------------------===// NoAsNeededAction::NoAsNeededAction(unsigned int pPosition) : InputAction(pPosition) { } bool NoAsNeededAction::activate(InputBuilder& pBuilder) const { pBuilder.getAttributes().unsetAsNeeded(); return true; } //===----------------------------------------------------------------------===// // AddNeededAction //===----------------------------------------------------------------------===// AddNeededAction::AddNeededAction(unsigned int pPosition) : InputAction(pPosition) { } bool AddNeededAction::activate(InputBuilder& pBuilder) const { pBuilder.getAttributes().setAddNeeded(); return true; } //===----------------------------------------------------------------------===// // NoAddNeededAction //===----------------------------------------------------------------------===// NoAddNeededAction::NoAddNeededAction(unsigned int pPosition) : InputAction(pPosition) { } bool NoAddNeededAction::activate(InputBuilder& pBuilder) const { pBuilder.getAttributes().unsetAddNeeded(); return true; } //===----------------------------------------------------------------------===// // BDynamicAction //===----------------------------------------------------------------------===// BDynamicAction::BDynamicAction(unsigned int pPosition) : InputAction(pPosition) { } bool BDynamicAction::activate(InputBuilder& pBuilder) const { pBuilder.getAttributes().setDynamic(); return true; } //===----------------------------------------------------------------------===// // BStaticAction //===----------------------------------------------------------------------===// BStaticAction::BStaticAction(unsigned int pPosition) : InputAction(pPosition) { } bool BStaticAction::activate(InputBuilder& pBuilder) const { pBuilder.getAttributes().setStatic(); return true; } //===----------------------------------------------------------------------===// // DefSymAction //===----------------------------------------------------------------------===// DefSymAction::DefSymAction(unsigned int pPosition, const std::string& pAssignment) : InputAction(pPosition), m_Assignment(pAssignment) { } bool DefSymAction::activate(InputBuilder& pBuilder) const { pBuilder.createNode<InputTree::Positional>("defsym", sys::fs::Path("NAN")); Input* input = *pBuilder.getCurrentNode(); pBuilder.setContext(*input, false); // FIXME void* base = static_cast<void*>(const_cast<char*>(m_Assignment.data())); pBuilder.setMemory(*input, base, m_Assignment.size()); return true; } //===----------------------------------------------------------------------===// // ScriptAction //===----------------------------------------------------------------------===// ScriptAction::ScriptAction(unsigned int pPosition, const std::string& pFileName, ScriptFile::Kind pKind, const SearchDirs& pSearchDirs) : InputAction(pPosition), m_FileName(pFileName), m_Kind(pKind), m_SearchDirs(pSearchDirs) { } bool ScriptAction::activate(InputBuilder& pBuilder) const { sys::fs::Path path(m_FileName); if (!exists(path)) { const sys::fs::Path* res = m_SearchDirs.find(m_FileName, Input::Script); if (res == NULL) { switch (m_Kind) { case ScriptFile::LDScript: fatal(diag::err_cannot_find_scriptfile) << "linker script" << m_FileName; break; case ScriptFile::VersionScript: fatal(diag::err_cannot_find_scriptfile) << "version script" << m_FileName; break; case ScriptFile::DynamicList: fatal(diag::err_cannot_find_scriptfile) << "dynamic list" << m_FileName; break; default: break; } return false; } path.assign(res->native()); } pBuilder.createNode<InputTree::Positional>(path.stem().native(), path); return true; } } // namespace mcld