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 #include <mcld/Script/RpnExpr.h>
     11 #include <mcld/Script/StringList.h>
     12 #include <mcld/Script/StrToken.h>
     13 #include <mcld/Script/InputSectDesc.h>
     14 #include <mcld/Support/raw_ostream.h>
     15 #include <mcld/LinkerScript.h>
     16 #include <mcld/Module.h>
     17 #include <llvm/Support/Casting.h>
     18 #include <cassert>
     19 
     20 using namespace mcld;
     21 
     22 //===----------------------------------------------------------------------===//
     23 // OutputSectDesc
     24 //===----------------------------------------------------------------------===//
     25 OutputSectDesc::OutputSectDesc(const std::string& pName,
     26                                const Prolog& pProlog)
     27   : ScriptCommand(ScriptCommand::OUTPUT_SECT_DESC),
     28     m_Name(pName),
     29     m_Prolog(pProlog)
     30 {
     31 }
     32 
     33 OutputSectDesc::~OutputSectDesc()
     34 {
     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 {
     43   mcld::outs() << m_Name << "\t";
     44 
     45   if (m_Prolog.hasVMA()) {
     46     m_Prolog.vma().dump();
     47     mcld::outs() << "\t";
     48   }
     49 
     50   switch (m_Prolog.type()) {
     51   case NOLOAD:
     52     mcld::outs() << "(NOLOAD)";
     53     break;
     54   case DSECT:
     55     mcld::outs() << "(DSECT)";
     56     break;
     57   case COPY:
     58     mcld::outs() << "(COPY)";
     59     break;
     60   case INFO:
     61     mcld::outs() << "(INFO)";
     62     break;
     63   case OVERLAY:
     64     mcld::outs() << "(OVERLAY)";
     65     break;
     66   default:
     67     break;
     68   }
     69   mcld::outs() << ":\n";
     70 
     71   if (m_Prolog.hasLMA()) {
     72     mcld::outs() << "\tAT ( ";
     73     m_Prolog.lma().dump();
     74     mcld::outs() << " )\n";
     75   }
     76 
     77   if (m_Prolog.hasAlign()) {
     78     mcld::outs() << "\tALIGN ( ";
     79     m_Prolog.align().dump();
     80     mcld::outs() << " )\n";
     81   }
     82 
     83   if (m_Prolog.hasSubAlign()) {
     84     mcld::outs() << "\tSUBALIGN ( ";
     85     m_Prolog.subAlign().dump();
     86     mcld::outs() << " )\n";
     87   }
     88 
     89   switch (m_Prolog.constraint()) {
     90   case ONLY_IF_RO:
     91     mcld::outs() << "\tONLY_IF_RO\n";
     92     break;
     93   case ONLY_IF_RW:
     94     mcld::outs() << "\tONLY_IF_RW\n";
     95     break;
     96   default:
     97     break;
     98   }
     99 
    100   mcld::outs() << "\t{\n";
    101   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
    102     switch ((*it)->getKind()) {
    103     case ScriptCommand::ASSIGNMENT:
    104     case ScriptCommand::INPUT_SECT_DESC:
    105       mcld::outs() << "\t\t";
    106       (*it)->dump();
    107       break;
    108     default:
    109       assert(0);
    110       break;
    111     }
    112   }
    113   mcld::outs() << "\t}";
    114 
    115   if (m_Epilog.hasRegion())
    116     mcld::outs() << "\t>" << m_Epilog.region();
    117   if (m_Epilog.hasLMARegion())
    118     mcld::outs() << "\tAT>" << m_Epilog.lmaRegion();
    119 
    120   if (m_Epilog.hasPhdrs()) {
    121     for (StringList::const_iterator it = m_Epilog.phdrs().begin(),
    122       ie = m_Epilog.phdrs().end(); it != ie; ++it) {
    123       assert((*it)->kind() == StrToken::String);
    124       mcld::outs() << ":" << (*it)->name() << " ";
    125     }
    126   }
    127 
    128   if (m_Epilog.hasFillExp()) {
    129     mcld::outs() << "= ";
    130     m_Epilog.fillExp().dump();
    131   }
    132   mcld::outs() << "\n";
    133 }
    134 
    135 void OutputSectDesc::push_back(ScriptCommand* pCommand)
    136 {
    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 {
    150   m_Epilog.m_pRegion    = pEpilog.m_pRegion;
    151   m_Epilog.m_pLMARegion = pEpilog.m_pLMARegion;
    152   m_Epilog.m_pPhdrs     = pEpilog.m_pPhdrs;
    153   m_Epilog.m_pFillExp   = pEpilog.m_pFillExp;
    154 }
    155 
    156 void OutputSectDesc::activate(Module& pModule)
    157 {
    158   // Assignment in an output section
    159   OutputSectCmds assignments;
    160 
    161   for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
    162     switch ((*it)->getKind()) {
    163     case ScriptCommand::ASSIGNMENT:
    164       assignments.push_back(*it);
    165       break;
    166     case ScriptCommand::INPUT_SECT_DESC: {
    167       (*it)->activate(pModule);
    168 
    169       for (iterator assign = assignments.begin(), assignEnd = assignments.end();
    170         assign != assignEnd; ++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; ++assign) {
    192       (*assign)->activate(pModule);
    193     }
    194     assignments.clear();
    195   }
    196 }
    197