• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //===----------------------------------------------------------------------===//
OutputSectDesc(const std::string & pName,const Prolog & pProlog)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 
~OutputSectDesc()33 OutputSectDesc::~OutputSectDesc()
34 {
35   for (iterator it = begin(), ie = end(); it != ie; ++it) {
36     if (*it != NULL)
37       delete *it;
38   }
39 }
40 
dump() const41 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 
push_back(ScriptCommand * pCommand)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 
setEpilog(const Epilog & pEpilog)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 
activate(Module & pModule)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