Home | History | Annotate | Download | only in Script
      1 //===- OutputSectDesc.cpp -------------------------------------------------===//
      2 //
      3 //                     The MCLinker Project
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #include "mcld/Script/OutputSectDesc.h"
     10 
     11 #include "mcld/Script/InputSectDesc.h"
     12 #include "mcld/Script/RpnExpr.h"
     13 #include "mcld/Script/StringList.h"
     14 #include "mcld/Script/StrToken.h"
     15 #include "mcld/Support/raw_ostream.h"
     16 #include "mcld/LinkerScript.h"
     17 #include "mcld/Module.h"
     18 
     19 #include <llvm/Support/Casting.h>
     20 
     21 #include <cassert>
     22 
     23 namespace mcld {
     24 
     25 //===----------------------------------------------------------------------===//
     26 // OutputSectDesc
     27 //===----------------------------------------------------------------------===//
     28 OutputSectDesc::OutputSectDesc(const std::string& pName, const Prolog& pProlog)
     29     : ScriptCommand(ScriptCommand::OUTPUT_SECT_DESC),
     30       m_Name(pName),
     31       m_Prolog(pProlog) {
     32 }
     33 
     34 OutputSectDesc::~OutputSectDesc() {
     35   for (iterator it = begin(), ie = end(); it != ie; ++it) {
     36     if (*it != NULL)
     37       delete *it;
     38   }
     39 }
     40 
     41 void OutputSectDesc::dump() const {
     42   mcld::outs() << m_Name << "\t";
     43 
     44   if (m_Prolog.hasVMA()) {
     45     m_Prolog.vma().dump();
     46     mcld::outs() << "\t";
     47   }
     48 
     49   switch (m_Prolog.type()) {
     50     case NOLOAD:
     51       mcld::outs() << "(NOLOAD)";
     52       break;
     53     case DSECT:
     54       mcld::outs() << "(DSECT)";
     55       break;
     56     case COPY:
     57       mcld::outs() << "(COPY)";
     58       break;
     59     case INFO:
     60       mcld::outs() << "(INFO)";
     61       break;
     62     case OVERLAY:
     63       mcld::outs() << "(OVERLAY)";
     64       break;
     65     default:
     66       break;
     67   }
     68   mcld::outs() << ":\n";
     69 
     70   if (m_Prolog.hasLMA()) {
     71     mcld::outs() << "\tAT ( ";
     72     m_Prolog.lma().dump();
     73     mcld::outs() << " )\n";
     74   }
     75 
     76   if (m_Prolog.hasAlign()) {
     77     mcld::outs() << "\tALIGN ( ";
     78     m_Prolog.align().dump();
     79     mcld::outs() << " )\n";
     80   }
     81 
     82   if (m_Prolog.hasSubAlign()) {
     83     mcld::outs() << "\tSUBALIGN ( ";
     84     m_Prolog.subAlign().dump();
     85     mcld::outs() << " )\n";
     86   }
     87 
     88   switch (m_Prolog.constraint()) {
     89     case ONLY_IF_RO:
     90       mcld::outs() << "\tONLY_IF_RO\n";
     91       break;
     92     case ONLY_IF_RW:
     93       mcld::outs() << "\tONLY_IF_RW\n";
     94       break;
     95     default:
     96       break;
     97   }
     98 
     99   mcld::outs() << "\t{\n";
    100   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
    101     switch ((*it)->getKind()) {
    102       case ScriptCommand::ASSIGNMENT:
    103       case ScriptCommand::INPUT_SECT_DESC:
    104         mcld::outs() << "\t\t";
    105         (*it)->dump();
    106         break;
    107       default:
    108         assert(0);
    109         break;
    110     }
    111   }
    112   mcld::outs() << "\t}";
    113 
    114   if (m_Epilog.hasRegion())
    115     mcld::outs() << "\t>" << m_Epilog.region();
    116   if (m_Epilog.hasLMARegion())
    117     mcld::outs() << "\tAT>" << m_Epilog.lmaRegion();
    118 
    119   if (m_Epilog.hasPhdrs()) {
    120     for (StringList::const_iterator it = m_Epilog.phdrs().begin(),
    121                                     ie = m_Epilog.phdrs().end();
    122          it != ie;
    123          ++it) {
    124       assert((*it)->kind() == StrToken::String);
    125       mcld::outs() << ":" << (*it)->name() << " ";
    126     }
    127   }
    128 
    129   if (m_Epilog.hasFillExp()) {
    130     mcld::outs() << "= ";
    131     m_Epilog.fillExp().dump();
    132   }
    133   mcld::outs() << "\n";
    134 }
    135 
    136 void OutputSectDesc::push_back(ScriptCommand* pCommand) {
    137   switch (pCommand->getKind()) {
    138     case ScriptCommand::ASSIGNMENT:
    139     case ScriptCommand::INPUT_SECT_DESC:
    140       m_OutputSectCmds.push_back(pCommand);
    141       break;
    142     default:
    143       assert(0);
    144       break;
    145   }
    146 }
    147 
    148 void OutputSectDesc::setEpilog(const Epilog& pEpilog) {
    149   m_Epilog.m_pRegion = pEpilog.m_pRegion;
    150   m_Epilog.m_pLMARegion = pEpilog.m_pLMARegion;
    151   m_Epilog.m_pPhdrs = pEpilog.m_pPhdrs;
    152   m_Epilog.m_pFillExp = pEpilog.m_pFillExp;
    153 }
    154 
    155 void OutputSectDesc::activate(Module& pModule) {
    156   // Assignment in an output section
    157   OutputSectCmds assignments;
    158 
    159   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
    160     switch ((*it)->getKind()) {
    161       case ScriptCommand::ASSIGNMENT:
    162         assignments.push_back(*it);
    163         break;
    164       case ScriptCommand::INPUT_SECT_DESC: {
    165         (*it)->activate(pModule);
    166 
    167         for (iterator assign = assignments.begin(),
    168                       assignEnd = assignments.end();
    169              assign != assignEnd;
    170              ++assign) {
    171           (*assign)->activate(pModule);
    172         }
    173         assignments.clear();
    174         break;
    175       }
    176       default:
    177         assert(0);
    178         break;
    179     }
    180   }
    181 
    182   if (!assignments.empty()) {
    183     InputSectDesc::Spec spec;
    184     spec.m_pWildcardFile = NULL;
    185     spec.m_pExcludeFiles = NULL;
    186     spec.m_pWildcardSections = NULL;
    187     InputSectDesc inputDesc(InputSectDesc::Keep, spec, *this);
    188     pModule.getScript().sectionMap().insert(inputDesc, *this);
    189 
    190     for (iterator assign = assignments.begin(), assignEnd = assignments.end();
    191          assign != assignEnd;
    192          ++assign) {
    193       (*assign)->activate(pModule);
    194     }
    195     assignments.clear();
    196   }
    197 }
    198 
    199 }  // namespace mcld
    200