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