| //===- 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 |