You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
9.3 KiB
279 lines
9.3 KiB
//===- 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
|