blob: df994caab5153812b1f0c7b99ca1ce7f324cb2c8 [file] [log] [blame]
//===- 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