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.
200 lines
4.9 KiB
200 lines
4.9 KiB
//===- OutputSectDesc.cpp -------------------------------------------------===//
|
|
//
|
|
// The MCLinker Project
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "mcld/Script/OutputSectDesc.h"
|
|
|
|
#include "mcld/Script/InputSectDesc.h"
|
|
#include "mcld/Script/RpnExpr.h"
|
|
#include "mcld/Script/StringList.h"
|
|
#include "mcld/Script/StrToken.h"
|
|
#include "mcld/Support/raw_ostream.h"
|
|
#include "mcld/LinkerScript.h"
|
|
#include "mcld/Module.h"
|
|
|
|
#include <llvm/Support/Casting.h>
|
|
|
|
#include <cassert>
|
|
|
|
namespace mcld {
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// OutputSectDesc
|
|
//===----------------------------------------------------------------------===//
|
|
OutputSectDesc::OutputSectDesc(const std::string& pName, const Prolog& pProlog)
|
|
: ScriptCommand(ScriptCommand::OUTPUT_SECT_DESC),
|
|
m_Name(pName),
|
|
m_Prolog(pProlog) {
|
|
}
|
|
|
|
OutputSectDesc::~OutputSectDesc() {
|
|
for (iterator it = begin(), ie = end(); it != ie; ++it) {
|
|
if (*it != NULL)
|
|
delete *it;
|
|
}
|
|
}
|
|
|
|
void OutputSectDesc::dump() const {
|
|
mcld::outs() << m_Name << "\t";
|
|
|
|
if (m_Prolog.hasVMA()) {
|
|
m_Prolog.vma().dump();
|
|
mcld::outs() << "\t";
|
|
}
|
|
|
|
switch (m_Prolog.type()) {
|
|
case NOLOAD:
|
|
mcld::outs() << "(NOLOAD)";
|
|
break;
|
|
case DSECT:
|
|
mcld::outs() << "(DSECT)";
|
|
break;
|
|
case COPY:
|
|
mcld::outs() << "(COPY)";
|
|
break;
|
|
case INFO:
|
|
mcld::outs() << "(INFO)";
|
|
break;
|
|
case OVERLAY:
|
|
mcld::outs() << "(OVERLAY)";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
mcld::outs() << ":\n";
|
|
|
|
if (m_Prolog.hasLMA()) {
|
|
mcld::outs() << "\tAT ( ";
|
|
m_Prolog.lma().dump();
|
|
mcld::outs() << " )\n";
|
|
}
|
|
|
|
if (m_Prolog.hasAlign()) {
|
|
mcld::outs() << "\tALIGN ( ";
|
|
m_Prolog.align().dump();
|
|
mcld::outs() << " )\n";
|
|
}
|
|
|
|
if (m_Prolog.hasSubAlign()) {
|
|
mcld::outs() << "\tSUBALIGN ( ";
|
|
m_Prolog.subAlign().dump();
|
|
mcld::outs() << " )\n";
|
|
}
|
|
|
|
switch (m_Prolog.constraint()) {
|
|
case ONLY_IF_RO:
|
|
mcld::outs() << "\tONLY_IF_RO\n";
|
|
break;
|
|
case ONLY_IF_RW:
|
|
mcld::outs() << "\tONLY_IF_RW\n";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
mcld::outs() << "\t{\n";
|
|
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
|
|
switch ((*it)->getKind()) {
|
|
case ScriptCommand::ASSIGNMENT:
|
|
case ScriptCommand::INPUT_SECT_DESC:
|
|
mcld::outs() << "\t\t";
|
|
(*it)->dump();
|
|
break;
|
|
default:
|
|
assert(0);
|
|
break;
|
|
}
|
|
}
|
|
mcld::outs() << "\t}";
|
|
|
|
if (m_Epilog.hasRegion())
|
|
mcld::outs() << "\t>" << m_Epilog.region();
|
|
if (m_Epilog.hasLMARegion())
|
|
mcld::outs() << "\tAT>" << m_Epilog.lmaRegion();
|
|
|
|
if (m_Epilog.hasPhdrs()) {
|
|
for (StringList::const_iterator it = m_Epilog.phdrs().begin(),
|
|
ie = m_Epilog.phdrs().end();
|
|
it != ie;
|
|
++it) {
|
|
assert((*it)->kind() == StrToken::String);
|
|
mcld::outs() << ":" << (*it)->name() << " ";
|
|
}
|
|
}
|
|
|
|
if (m_Epilog.hasFillExp()) {
|
|
mcld::outs() << "= ";
|
|
m_Epilog.fillExp().dump();
|
|
}
|
|
mcld::outs() << "\n";
|
|
}
|
|
|
|
void OutputSectDesc::push_back(ScriptCommand* pCommand) {
|
|
switch (pCommand->getKind()) {
|
|
case ScriptCommand::ASSIGNMENT:
|
|
case ScriptCommand::INPUT_SECT_DESC:
|
|
m_OutputSectCmds.push_back(pCommand);
|
|
break;
|
|
default:
|
|
assert(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void OutputSectDesc::setEpilog(const Epilog& pEpilog) {
|
|
m_Epilog.m_pRegion = pEpilog.m_pRegion;
|
|
m_Epilog.m_pLMARegion = pEpilog.m_pLMARegion;
|
|
m_Epilog.m_pPhdrs = pEpilog.m_pPhdrs;
|
|
m_Epilog.m_pFillExp = pEpilog.m_pFillExp;
|
|
}
|
|
|
|
void OutputSectDesc::activate(Module& pModule) {
|
|
// Assignment in an output section
|
|
OutputSectCmds assignments;
|
|
|
|
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
|
|
switch ((*it)->getKind()) {
|
|
case ScriptCommand::ASSIGNMENT:
|
|
assignments.push_back(*it);
|
|
break;
|
|
case ScriptCommand::INPUT_SECT_DESC: {
|
|
(*it)->activate(pModule);
|
|
|
|
for (iterator assign = assignments.begin(),
|
|
assignEnd = assignments.end();
|
|
assign != assignEnd;
|
|
++assign) {
|
|
(*assign)->activate(pModule);
|
|
}
|
|
assignments.clear();
|
|
break;
|
|
}
|
|
default:
|
|
assert(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!assignments.empty()) {
|
|
InputSectDesc::Spec spec;
|
|
spec.m_pWildcardFile = NULL;
|
|
spec.m_pExcludeFiles = NULL;
|
|
spec.m_pWildcardSections = NULL;
|
|
InputSectDesc inputDesc(InputSectDesc::Keep, spec, *this);
|
|
pModule.getScript().sectionMap().insert(inputDesc, *this);
|
|
|
|
for (iterator assign = assignments.begin(), assignEnd = assignments.end();
|
|
assign != assignEnd;
|
|
++assign) {
|
|
(*assign)->activate(pModule);
|
|
}
|
|
assignments.clear();
|
|
}
|
|
}
|
|
|
|
} // namespace mcld
|