blob: 615c4937df85b33e1dd9edccb3cb0dfefd213165 [file] [log] [blame]
Shih-wei Liao22add6f2012-12-15 17:21:00 -08001//===- SectionMap.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//===----------------------------------------------------------------------===//
Stephen Hines37b74a32014-11-26 18:48:20 -08009#include "mcld/Object/SectionMap.h"
10
11#include "mcld/Fragment/NullFragment.h"
12#include "mcld/LD/LDSection.h"
13#include "mcld/LD/SectionData.h"
14#include "mcld/Script/Assignment.h"
15#include "mcld/Script/Operand.h"
16#include "mcld/Script/Operator.h"
17#include "mcld/Script/RpnExpr.h"
18#include "mcld/Script/StringList.h"
19#include "mcld/Script/WildcardPattern.h"
20
Stephen Hines87f34652014-02-14 18:00:16 -080021#include <llvm/Support/Casting.h>
Stephen Hines37b74a32014-11-26 18:48:20 -080022
Shih-wei Liao22add6f2012-12-15 17:21:00 -080023#include <cassert>
24#include <cstring>
Stephen Hines87f34652014-02-14 18:00:16 -080025#include <climits>
26#if !defined(MCLD_ON_WIN32)
27#include <fnmatch.h>
Stephen Hines37b74a32014-11-26 18:48:20 -080028#define fnmatch0(pattern, string) (fnmatch(pattern, string, 0) == 0)
Stephen Hines87f34652014-02-14 18:00:16 -080029#else
30#include <windows.h>
31#include <shlwapi.h>
Stephen Hines37b74a32014-11-26 18:48:20 -080032#define fnmatch0(pattern, string) (PathMatchSpec(string, pattern) == true)
Stephen Hines87f34652014-02-14 18:00:16 -080033#endif
Shih-wei Liao22add6f2012-12-15 17:21:00 -080034
Stephen Hines37b74a32014-11-26 18:48:20 -080035namespace mcld {
36
Shih-wei Liao22add6f2012-12-15 17:21:00 -080037//===----------------------------------------------------------------------===//
Stephen Hines87f34652014-02-14 18:00:16 -080038// SectionMap::Input
Shih-wei Liao22add6f2012-12-15 17:21:00 -080039//===----------------------------------------------------------------------===//
Stephen Hines87f34652014-02-14 18:00:16 -080040SectionMap::Input::Input(const std::string& pName,
41 InputSectDesc::KeepPolicy pPolicy)
Stephen Hines37b74a32014-11-26 18:48:20 -080042 : m_Policy(pPolicy) {
Stephen Hines87f34652014-02-14 18:00:16 -080043 m_Spec.m_pWildcardFile =
Stephen Hines37b74a32014-11-26 18:48:20 -080044 WildcardPattern::create("*", WildcardPattern::SORT_NONE);
Stephen Hines87f34652014-02-14 18:00:16 -080045 m_Spec.m_pExcludeFiles = NULL;
46
47 StringList* sections = StringList::create();
48 sections->push_back(
Stephen Hines37b74a32014-11-26 18:48:20 -080049 WildcardPattern::create(pName, WildcardPattern::SORT_NONE));
Stephen Hines87f34652014-02-14 18:00:16 -080050 m_Spec.m_pWildcardSections = sections;
51
Stephen Hines0dea6bc2014-07-15 18:33:32 -070052 m_pSection = LDSection::Create(pName, LDFileFormat::TEXT, 0, 0);
Stephen Hines87f34652014-02-14 18:00:16 -080053 SectionData* sd = SectionData::Create(*m_pSection);
54 m_pSection->setSectionData(sd);
55 new NullFragment(sd);
56 new NullFragment(sd);
57}
58
59SectionMap::Input::Input(const InputSectDesc& pInputDesc)
Stephen Hines37b74a32014-11-26 18:48:20 -080060 : m_Policy(pInputDesc.policy()) {
Stephen Hines87f34652014-02-14 18:00:16 -080061 m_Spec.m_pWildcardFile = pInputDesc.spec().m_pWildcardFile;
62 m_Spec.m_pExcludeFiles = pInputDesc.spec().m_pExcludeFiles;
63 m_Spec.m_pWildcardSections = pInputDesc.spec().m_pWildcardSections;
Stephen Hines0dea6bc2014-07-15 18:33:32 -070064 m_pSection = LDSection::Create("", LDFileFormat::TEXT, 0, 0);
Stephen Hines87f34652014-02-14 18:00:16 -080065 SectionData* sd = SectionData::Create(*m_pSection);
66 m_pSection->setSectionData(sd);
67 new NullFragment(sd);
68 new NullFragment(sd);
69}
70
71//===----------------------------------------------------------------------===//
72// SectionMap::Output
73//===----------------------------------------------------------------------===//
74SectionMap::Output::Output(const std::string& pName)
Stephen Hines37b74a32014-11-26 18:48:20 -080075 : m_Name(pName), m_Order(UINT_MAX) {
Stephen Hines87f34652014-02-14 18:00:16 -080076 m_Prolog.m_pVMA = NULL;
77 m_Prolog.m_Type = OutputSectDesc::LOAD;
78 m_Prolog.m_pLMA = NULL;
79 m_Prolog.m_pAlign = NULL;
80 m_Prolog.m_pSubAlign = NULL;
81 m_Prolog.m_Constraint = OutputSectDesc::NO_CONSTRAINT;
82
83 m_Epilog.m_pRegion = NULL;
84 m_Epilog.m_pLMARegion = NULL;
85 m_Epilog.m_pPhdrs = NULL;
86 m_Epilog.m_pFillExp = NULL;
87
Stephen Hines0dea6bc2014-07-15 18:33:32 -070088 m_pSection = LDSection::Create(pName, LDFileFormat::TEXT, 0, 0);
Stephen Hines87f34652014-02-14 18:00:16 -080089 SectionData* sd = SectionData::Create(*m_pSection);
90 m_pSection->setSectionData(sd);
91
92 m_bIsDiscard = pName.compare("/DISCARD/") == 0;
93}
94
95SectionMap::Output::Output(const OutputSectDesc& pOutputDesc)
Stephen Hines37b74a32014-11-26 18:48:20 -080096 : m_Name(pOutputDesc.name()),
97 m_Prolog(pOutputDesc.prolog()),
98 m_Epilog(pOutputDesc.epilog()),
99 m_Order(UINT_MAX) {
Stephen Hines0dea6bc2014-07-15 18:33:32 -0700100 m_pSection = LDSection::Create(m_Name, LDFileFormat::TEXT, 0, 0);
Stephen Hines87f34652014-02-14 18:00:16 -0800101 SectionData* sd = SectionData::Create(*m_pSection);
102 m_pSection->setSectionData(sd);
103
104 m_bIsDiscard = m_Name.compare("/DISCARD/") == 0;
105}
106
Stephen Hines37b74a32014-11-26 18:48:20 -0800107bool SectionMap::Output::hasContent() const {
Stephen Hines87f34652014-02-14 18:00:16 -0800108 return m_pSection != NULL && m_pSection->size() != 0;
109}
110
111SectionMap::Output::const_dot_iterator
Stephen Hines37b74a32014-11-26 18:48:20 -0800112SectionMap::Output::find_first_explicit_dot() const {
Stephen Hines87f34652014-02-14 18:00:16 -0800113 for (const_dot_iterator it = dot_begin(), ie = dot_end(); it != ie; ++it) {
114 if ((*it).type() == Assignment::DEFAULT)
115 return it;
116 }
117 return dot_end();
118}
119
Stephen Hines37b74a32014-11-26 18:48:20 -0800120SectionMap::Output::dot_iterator SectionMap::Output::find_first_explicit_dot() {
Stephen Hines87f34652014-02-14 18:00:16 -0800121 for (dot_iterator it = dot_begin(), ie = dot_end(); it != ie; ++it) {
122 if ((*it).type() == Assignment::DEFAULT)
123 return it;
124 }
125 return dot_end();
126}
127
128SectionMap::Output::const_dot_iterator
Stephen Hines37b74a32014-11-26 18:48:20 -0800129SectionMap::Output::find_last_explicit_dot() const {
Stephen Hines87f34652014-02-14 18:00:16 -0800130 typedef DotAssignments::const_reverse_iterator CONST_RIT;
131 for (CONST_RIT rit = dotAssignments().rbegin(), rie = dotAssignments().rend();
Stephen Hines37b74a32014-11-26 18:48:20 -0800132 rit != rie;
133 ++rit) {
Stephen Hines87f34652014-02-14 18:00:16 -0800134 if ((*rit).type() == Assignment::DEFAULT) {
135 return dot_begin() +
136 (dotAssignments().size() - (rit - dotAssignments().rbegin()) - 1);
137 }
138 }
139 return dot_end();
140}
141
Stephen Hines37b74a32014-11-26 18:48:20 -0800142SectionMap::Output::dot_iterator SectionMap::Output::find_last_explicit_dot() {
Stephen Hines87f34652014-02-14 18:00:16 -0800143 typedef DotAssignments::reverse_iterator RIT;
144 for (RIT rit = dotAssignments().rbegin(), rie = dotAssignments().rend();
Stephen Hines37b74a32014-11-26 18:48:20 -0800145 rit != rie;
146 ++rit) {
Stephen Hines87f34652014-02-14 18:00:16 -0800147 if ((*rit).type() == Assignment::DEFAULT) {
148 return dot_begin() +
149 (dotAssignments().size() - (rit - dotAssignments().rbegin()) - 1);
150 }
151 }
152 return dot_end();
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800153}
154
155//===----------------------------------------------------------------------===//
156// SectionMap
157//===----------------------------------------------------------------------===//
Stephen Hines37b74a32014-11-26 18:48:20 -0800158SectionMap::~SectionMap() {
Stephen Hines87f34652014-02-14 18:00:16 -0800159 iterator out, outBegin = begin(), outEnd = end();
160 for (out = outBegin; out != outEnd; ++out) {
161 if (*out != NULL) {
162 Output::iterator in, inBegin = (*out)->begin(), inEnd = (*out)->end();
163 for (in = inBegin; in != inEnd; ++in) {
164 if (*in != NULL)
165 delete *in;
166 }
167 delete *out;
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800168 }
169 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800170}
171
Stephen Hines37b74a32014-11-26 18:48:20 -0800172SectionMap::const_mapping SectionMap::find(
173 const std::string& pInputFile,
174 const std::string& pInputSection) const {
Stephen Hines87f34652014-02-14 18:00:16 -0800175 const_iterator out, outBegin = begin(), outEnd = end();
176 for (out = outBegin; out != outEnd; ++out) {
177 Output::const_iterator in, inBegin = (*out)->begin(), inEnd = (*out)->end();
178 for (in = inBegin; in != inEnd; ++in) {
179 if (matched(**in, pInputFile, pInputSection))
180 return std::make_pair(*out, *in);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800181 }
182 }
Stephen Hines87f34652014-02-14 18:00:16 -0800183 return std::make_pair((const Output*)NULL, (const Input*)NULL);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800184}
185
Stephen Hines87f34652014-02-14 18:00:16 -0800186SectionMap::mapping SectionMap::find(const std::string& pInputFile,
Stephen Hines37b74a32014-11-26 18:48:20 -0800187 const std::string& pInputSection) {
Stephen Hines87f34652014-02-14 18:00:16 -0800188 iterator out, outBegin = begin(), outEnd = end();
189 for (out = outBegin; out != outEnd; ++out) {
190 Output::iterator in, inBegin = (*out)->begin(), inEnd = (*out)->end();
191 for (in = inBegin; in != inEnd; ++in) {
192 if (matched(**in, pInputFile, pInputSection))
193 return std::make_pair(*out, *in);
194 }
195 }
Stephen Hines37b74a32014-11-26 18:48:20 -0800196 return std::make_pair(reinterpret_cast<Output*>(NULL),
197 reinterpret_cast<Input*>(NULL));
Stephen Hines87f34652014-02-14 18:00:16 -0800198}
199
Stephen Hines37b74a32014-11-26 18:48:20 -0800200SectionMap::const_iterator SectionMap::find(
201 const std::string& pOutputSection) const {
Stephen Hines87f34652014-02-14 18:00:16 -0800202 const_iterator out, outBegin = begin(), outEnd = end();
203 for (out = outBegin; out != outEnd; ++out) {
204 if ((*out)->name().compare(pOutputSection) == 0)
205 return out;
206 }
207 return outEnd;
208}
209
Stephen Hines37b74a32014-11-26 18:48:20 -0800210SectionMap::iterator SectionMap::find(const std::string& pOutputSection) {
Stephen Hines87f34652014-02-14 18:00:16 -0800211 iterator out, outBegin = begin(), outEnd = end();
212 for (out = outBegin; out != outEnd; ++out) {
213 if ((*out)->name().compare(pOutputSection) == 0)
214 return out;
215 }
216 return outEnd;
217}
218
Stephen Hines37b74a32014-11-26 18:48:20 -0800219std::pair<SectionMap::mapping, bool> SectionMap::insert(
220 const std::string& pInputSection,
221 const std::string& pOutputSection,
222 InputSectDesc::KeepPolicy pPolicy) {
Stephen Hines87f34652014-02-14 18:00:16 -0800223 iterator out, outBegin = begin(), outEnd = end();
224 for (out = outBegin; out != outEnd; ++out) {
225 if ((*out)->name().compare(pOutputSection) == 0)
226 break;
227 }
228 if (out != end()) {
229 Output::iterator in, inBegin = (*out)->begin(), inEnd = (*out)->end();
230 for (in = inBegin; in != inEnd; ++in) {
231 if ((*in)->getSection()->name().compare(pInputSection) == 0)
232 break;
233 }
234
235 if (in != (*out)->end()) {
236 return std::make_pair(std::make_pair(*out, *in), false);
237 } else {
238 Input* input = new Input(pInputSection, pPolicy);
239 (*out)->append(input);
240 return std::make_pair(std::make_pair(*out, input), true);
241 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800242 }
243
Stephen Hines87f34652014-02-14 18:00:16 -0800244 Output* output = new Output(pOutputSection);
245 m_OutputDescList.push_back(output);
246 Input* input = new Input(pInputSection, pPolicy);
247 output->append(input);
248
249 return std::make_pair(std::make_pair(output, input), true);
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800250}
251
Stephen Hines37b74a32014-11-26 18:48:20 -0800252std::pair<SectionMap::mapping, bool> SectionMap::insert(
253 const InputSectDesc& pInputDesc,
254 const OutputSectDesc& pOutputDesc) {
Stephen Hines87f34652014-02-14 18:00:16 -0800255 iterator out, outBegin = begin(), outEnd = end();
256 for (out = outBegin; out != outEnd; ++out) {
257 if ((*out)->name().compare(pOutputDesc.name()) == 0 &&
258 (*out)->prolog() == pOutputDesc.prolog() &&
259 (*out)->epilog() == pOutputDesc.epilog())
260 break;
261 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800262
Stephen Hines87f34652014-02-14 18:00:16 -0800263 if (out != end()) {
264 Output::iterator in, inBegin = (*out)->begin(), inEnd = (*out)->end();
265 for (in = inBegin; in != inEnd; ++in) {
266 if ((*in)->policy() == pInputDesc.policy() &&
267 (*in)->spec() == pInputDesc.spec())
268 break;
269 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800270
Stephen Hines87f34652014-02-14 18:00:16 -0800271 if (in != (*out)->end()) {
272 return std::make_pair(std::make_pair(*out, *in), false);
273 } else {
274 Input* input = new Input(pInputDesc);
275 (*out)->append(input);
276 return std::make_pair(std::make_pair(*out, input), true);
277 }
278 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800279
Stephen Hines87f34652014-02-14 18:00:16 -0800280 Output* output = new Output(pOutputDesc);
281 m_OutputDescList.push_back(output);
282 Input* input = new Input(pInputDesc);
283 output->append(input);
284
285 return std::make_pair(std::make_pair(output, input), true);
286}
287
Stephen Hines37b74a32014-11-26 18:48:20 -0800288SectionMap::iterator SectionMap::insert(iterator pPosition,
289 LDSection* pSection) {
Stephen Hines87f34652014-02-14 18:00:16 -0800290 Output* output = new Output(pSection->name());
291 output->append(new Input(pSection->name(), InputSectDesc::NoKeep));
292 output->setSection(pSection);
293 return m_OutputDescList.insert(pPosition, output);
294}
295
296bool SectionMap::matched(const SectionMap::Input& pInput,
297 const std::string& pInputFile,
Stephen Hines37b74a32014-11-26 18:48:20 -0800298 const std::string& pInputSection) const {
Stephen Hines87f34652014-02-14 18:00:16 -0800299 if (pInput.spec().hasFile() && !matched(pInput.spec().file(), pInputFile))
Stephen Hines37b74a32014-11-26 18:48:20 -0800300 return false;
Stephen Hines87f34652014-02-14 18:00:16 -0800301
302 if (pInput.spec().hasExcludeFiles()) {
303 StringList::const_iterator file, fileEnd;
304 fileEnd = pInput.spec().excludeFiles().end();
305 for (file = pInput.spec().excludeFiles().begin(); file != fileEnd; ++file) {
306 if (matched(llvm::cast<WildcardPattern>(**file), pInputFile)) {
307 return false;
308 }
309 }
310 }
311
312 if (pInput.spec().hasSections()) {
313 StringList::const_iterator sect, sectEnd = pInput.spec().sections().end();
314 for (sect = pInput.spec().sections().begin(); sect != sectEnd; ++sect) {
315 if (matched(llvm::cast<WildcardPattern>(**sect), pInputSection)) {
316 return true;
317 }
318 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800319 }
320
321 return false;
322}
323
Stephen Hines87f34652014-02-14 18:00:16 -0800324bool SectionMap::matched(const WildcardPattern& pPattern,
Stephen Hines37b74a32014-11-26 18:48:20 -0800325 const std::string& pName) const {
Stephen Hines87f34652014-02-14 18:00:16 -0800326 if (pPattern.isPrefix()) {
327 llvm::StringRef name(pName);
328 return name.startswith(pPattern.prefix());
329 } else {
330 return fnmatch0(pPattern.name().c_str(), pName.c_str());
331 }
Shih-wei Liao22add6f2012-12-15 17:21:00 -0800332}
333
Stephen Hines87f34652014-02-14 18:00:16 -0800334// fixupDotSymbols - ensure the dot symbols are valid
Stephen Hines37b74a32014-11-26 18:48:20 -0800335void SectionMap::fixupDotSymbols() {
Stephen Hines87f34652014-02-14 18:00:16 -0800336 for (iterator it = begin() + 1, ie = end(); it != ie; ++it) {
337 // fixup the 1st explicit dot assignment if needed
338 if (!(*it)->dotAssignments().empty()) {
339 Output::dot_iterator dot = (*it)->find_first_explicit_dot();
Stephen Hines37b74a32014-11-26 18:48:20 -0800340 if (dot != (*it)->dot_end() && (*dot).symbol().isDot() &&
Stephen Hines87f34652014-02-14 18:00:16 -0800341 (*dot).getRpnExpr().hasDot()) {
342 Assignment assign(Assignment::OUTPUT_SECTION,
343 Assignment::DEFAULT,
344 *SymOperand::create("."),
345 *RpnExpr::buildHelperExpr(it - 1));
346 Output::dot_iterator ref = (*it)->dotAssignments().insert(dot, assign);
347 for (RpnExpr::iterator tok = (*dot).getRpnExpr().begin(),
Stephen Hines37b74a32014-11-26 18:48:20 -0800348 tokEnd = (*dot).getRpnExpr().end();
349 tok != tokEnd;
350 ++tok) {
Stephen Hines87f34652014-02-14 18:00:16 -0800351 if ((*tok)->kind() == ExprToken::OPERAND &&
352 llvm::cast<Operand>(*tok)->isDot())
353 *tok = &((*ref).symbol());
Stephen Hines37b74a32014-11-26 18:48:20 -0800354 } // for each token in the RHS expr of the dot assignment
Stephen Hines87f34652014-02-14 18:00:16 -0800355 }
356 }
357
358 // fixup dot in output VMA if needed
359 if ((*it)->prolog().hasVMA() && (*it)->prolog().vma().hasDot()) {
360 Output::dot_iterator dot = (*it)->find_last_explicit_dot();
361 if (dot == (*it)->dot_end()) {
362 Assignment assign(Assignment::OUTPUT_SECTION,
363 Assignment::DEFAULT,
364 *SymOperand::create("."),
365 *RpnExpr::buildHelperExpr(it - 1));
366 dot = (*it)->dotAssignments().insert(dot, assign);
367 }
368 for (RpnExpr::iterator tok = (*it)->prolog().vma().begin(),
Stephen Hines37b74a32014-11-26 18:48:20 -0800369 tokEnd = (*it)->prolog().vma().end();
370 tok != tokEnd;
371 ++tok) {
Stephen Hines87f34652014-02-14 18:00:16 -0800372 if ((*tok)->kind() == ExprToken::OPERAND &&
373 llvm::cast<Operand>(*tok)->isDot())
374 *tok = &((*dot).symbol());
Stephen Hines37b74a32014-11-26 18:48:20 -0800375 } // for each token in the RHS expr of the dot assignment
Stephen Hines87f34652014-02-14 18:00:16 -0800376 }
Stephen Hines37b74a32014-11-26 18:48:20 -0800377 } // for each output section
Stephen Hines87f34652014-02-14 18:00:16 -0800378}
Stephen Hines37b74a32014-11-26 18:48:20 -0800379
380} // namespace mcld