1f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===- OutputSectDesc.cpp -------------------------------------------------===//
2f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//
3f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//                     The MCLinker Project
4f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//
5f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// This file is distributed under the University of Illinois Open Source
6f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// License. See LICENSE.TXT for details.
7f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//
8f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/OutputSectDesc.h"
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/InputSectDesc.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/RpnExpr.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/StringList.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Script/StrToken.h"
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/raw_ostream.h"
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerScript.h"
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h"
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines
19f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/Support/Casting.h>
2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
21f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <cassert>
22f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
2337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
24f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
25f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===//
26f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// OutputSectDesc
27f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===//
2837b74a387bb3993387029859c2d9d051c41c724eStephen HinesOutputSectDesc::OutputSectDesc(const std::string& pName, const Prolog& pProlog)
2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : ScriptCommand(ScriptCommand::OUTPUT_SECT_DESC),
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_Name(pName),
3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_Prolog(pProlog) {
32f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
33f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
3437b74a387bb3993387029859c2d9d051c41c724eStephen HinesOutputSectDesc::~OutputSectDesc() {
35f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  for (iterator it = begin(), ie = end(); it != ie; ++it) {
36f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    if (*it != NULL)
37f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      delete *it;
38f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
39f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
40f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
4137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid OutputSectDesc::dump() const {
42f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  mcld::outs() << m_Name << "\t";
43f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
44f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (m_Prolog.hasVMA()) {
45f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    m_Prolog.vma().dump();
46f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    mcld::outs() << "\t";
47f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
48f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
49f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  switch (m_Prolog.type()) {
5037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case NOLOAD:
5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      mcld::outs() << "(NOLOAD)";
5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
5337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case DSECT:
5437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      mcld::outs() << "(DSECT)";
5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
5637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case COPY:
5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      mcld::outs() << "(COPY)";
5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case INFO:
6037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      mcld::outs() << "(INFO)";
6137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case OVERLAY:
6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      mcld::outs() << "(OVERLAY)";
6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
6537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    default:
6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
67f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
68f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  mcld::outs() << ":\n";
69f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
70f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (m_Prolog.hasLMA()) {
71f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    mcld::outs() << "\tAT ( ";
72f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    m_Prolog.lma().dump();
73f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    mcld::outs() << " )\n";
74f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
75f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
76f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (m_Prolog.hasAlign()) {
77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    mcld::outs() << "\tALIGN ( ";
78f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    m_Prolog.align().dump();
79f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    mcld::outs() << " )\n";
80f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
81f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
82f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (m_Prolog.hasSubAlign()) {
83f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    mcld::outs() << "\tSUBALIGN ( ";
84f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    m_Prolog.subAlign().dump();
85f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    mcld::outs() << " )\n";
86f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
87f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
88f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  switch (m_Prolog.constraint()) {
8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case ONLY_IF_RO:
9037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      mcld::outs() << "\tONLY_IF_RO\n";
9137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case ONLY_IF_RW:
9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      mcld::outs() << "\tONLY_IF_RW\n";
9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    default:
9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
97f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
98f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
99f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  mcld::outs() << "\t{\n";
100f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
101f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    switch ((*it)->getKind()) {
10237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case ScriptCommand::ASSIGNMENT:
10337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case ScriptCommand::INPUT_SECT_DESC:
10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        mcld::outs() << "\t\t";
10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        (*it)->dump();
10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      default:
10837b74a387bb3993387029859c2d9d051c41c724eStephen Hines        assert(0);
10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
110f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    }
111f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
112f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  mcld::outs() << "\t}";
113f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
114f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (m_Epilog.hasRegion())
115f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    mcld::outs() << "\t>" << m_Epilog.region();
116f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (m_Epilog.hasLMARegion())
117f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    mcld::outs() << "\tAT>" << m_Epilog.lmaRegion();
118f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
119f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (m_Epilog.hasPhdrs()) {
120f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    for (StringList::const_iterator it = m_Epilog.phdrs().begin(),
12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                    ie = m_Epilog.phdrs().end();
12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines         it != ie;
12337b74a387bb3993387029859c2d9d051c41c724eStephen Hines         ++it) {
124f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      assert((*it)->kind() == StrToken::String);
125f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      mcld::outs() << ":" << (*it)->name() << " ";
126f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    }
127f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
128f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
129f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (m_Epilog.hasFillExp()) {
130f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    mcld::outs() << "= ";
131f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    m_Epilog.fillExp().dump();
132f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
133f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  mcld::outs() << "\n";
134f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
135f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
13637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid OutputSectDesc::push_back(ScriptCommand* pCommand) {
137f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  switch (pCommand->getKind()) {
13837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case ScriptCommand::ASSIGNMENT:
13937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case ScriptCommand::INPUT_SECT_DESC:
14037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_OutputSectCmds.push_back(pCommand);
14137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
14237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    default:
14337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      assert(0);
14437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
145f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
146f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
147f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
14837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid OutputSectDesc::setEpilog(const Epilog& pEpilog) {
14937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  m_Epilog.m_pRegion = pEpilog.m_pRegion;
150f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  m_Epilog.m_pLMARegion = pEpilog.m_pLMARegion;
15137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  m_Epilog.m_pPhdrs = pEpilog.m_pPhdrs;
15237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  m_Epilog.m_pFillExp = pEpilog.m_pFillExp;
153f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
154f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
15537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid OutputSectDesc::activate(Module& pModule) {
156f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // Assignment in an output section
157f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  OutputSectCmds assignments;
158f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
159f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
160f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    switch ((*it)->getKind()) {
16137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case ScriptCommand::ASSIGNMENT:
16237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        assignments.push_back(*it);
16337b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
16437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case ScriptCommand::INPUT_SECT_DESC: {
16537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        (*it)->activate(pModule);
16637b74a387bb3993387029859c2d9d051c41c724eStephen Hines
16737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        for (iterator assign = assignments.begin(),
16837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                      assignEnd = assignments.end();
16937b74a387bb3993387029859c2d9d051c41c724eStephen Hines             assign != assignEnd;
17037b74a387bb3993387029859c2d9d051c41c724eStephen Hines             ++assign) {
17137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          (*assign)->activate(pModule);
17237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        }
17337b74a387bb3993387029859c2d9d051c41c724eStephen Hines        assignments.clear();
17437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
175f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      }
17637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      default:
17737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        assert(0);
17837b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
179f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    }
180f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
181f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
182f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (!assignments.empty()) {
18337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    InputSectDesc::Spec spec;
184f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    spec.m_pWildcardFile = NULL;
185f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    spec.m_pExcludeFiles = NULL;
186f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    spec.m_pWildcardSections = NULL;
187f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    InputSectDesc inputDesc(InputSectDesc::Keep, spec, *this);
188f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    pModule.getScript().sectionMap().insert(inputDesc, *this);
189f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
190f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    for (iterator assign = assignments.begin(), assignEnd = assignments.end();
19137b74a387bb3993387029859c2d9d051c41c724eStephen Hines         assign != assignEnd;
19237b74a387bb3993387029859c2d9d051c41c724eStephen Hines         ++assign) {
193f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines      (*assign)->activate(pModule);
194f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    }
195f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    assignments.clear();
196f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  }
197f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines}
19837b74a387bb3993387029859c2d9d051c41c724eStephen Hines
19937b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
200