1 //===- Layout.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
10 #include <llvm/ADT/Twine.h>
11 #include <llvm/Support/ErrorHandling.h>
12 #include <mcld/ADT/SizeTraits.h>
13 #include <mcld/LD/Layout.h>
14 #include <mcld/LD/LDFileFormat.h>
15 #include <mcld/MC/MCLinker.h>
16 #include <mcld/MC/MCLDInfo.h>
17 #include <mcld/LD/LDSection.h>
18 #include <mcld/LD/LDContext.h>
19 #include <mcld/Target/TargetLDBackend.h>
20 #include <cassert>
21
22 using namespace mcld;
23
24 //===----------------------------------------------------------------------===//
25 // Range
Range()26 Layout::Range::Range()
27 : header(NULL),
28 prevRear(NULL) {
29 }
30
Range(const LDSection & pHdr)31 Layout::Range::Range(const LDSection& pHdr)
32 : header(const_cast<LDSection*>(&pHdr)),
33 prevRear(NULL) {
34 }
35
~Range()36 Layout::Range::~Range()
37 {
38 }
39
40 //===----------------------------------------------------------------------===//
41 // Layout
Layout()42 Layout::Layout()
43 : m_FragRefFactory(32) /** magic number **/ {
44 }
45
~Layout()46 Layout::~Layout()
47 {
48 }
49
setFragmentLayoutOrder(llvm::MCFragment * pFrag)50 void Layout::setFragmentLayoutOrder(llvm::MCFragment* pFrag)
51 {
52 if (NULL == pFrag)
53 return;
54 // compute the most-recent fragment whose order was set.
55 llvm::MCFragment* first = pFrag;
56
57 while (!hasLayoutOrder(*first)) {
58 if (NULL == first->getPrevNode())
59 break;
60 first = first->getPrevNode();
61 }
62
63 // set all layout order
64 unsigned int layout_order = 0;
65 llvm::MCFragment* frag_not_set = NULL;
66
67 if (NULL == first->getPrevNode()) {
68 layout_order = 0;
69 frag_not_set = first;
70 }
71 else {
72 layout_order = first->getLayoutOrder();
73 frag_not_set = first->getNextNode();
74 }
75
76 // set up all layout order
77 while(NULL != frag_not_set) {
78 frag_not_set->setLayoutOrder(layout_order);
79 ++layout_order;
80 frag_not_set = frag_not_set->getNextNode();
81 }
82 }
83
84 /// setFragmentLayoutOffset - set the fragment's layout offset. This function
85 /// also set up the layout offsets of all the fragments in the same range.
86 /// If the offset of the fragment was set before, return immediately.
setFragmentLayoutOffset(llvm::MCFragment * pFrag)87 void Layout::setFragmentLayoutOffset(llvm::MCFragment* pFrag)
88 {
89 if (NULL == pFrag)
90 return;
91 // compute the most-recent fragment whose offset was set.
92 llvm::MCFragment* first = pFrag;
93
94 while (!hasLayoutOffset(*first)) {
95 if (NULL == first->getPrevNode())
96 break;
97 first = first->getPrevNode();
98 }
99
100 // set all layout order
101 uint64_t offset = 0;
102 llvm::MCFragment* frag_not_set = NULL;
103 if (NULL == first->getPrevNode()) {
104 offset = 0;
105 frag_not_set = first;
106 }
107 else {
108 offset = first->Offset;
109 offset += computeFragmentSize(*this, *first);
110 frag_not_set = first->getNextNode();
111 }
112
113 while(NULL != frag_not_set) {
114 frag_not_set->Offset = offset;
115 offset += computeFragmentSize(*this, *frag_not_set);
116 frag_not_set = frag_not_set->getNextNode();
117 }
118 }
119
120 /// addInputRange
121 /// 1. add a new range <pInputHdr, previous rear fragment>
122 /// 2. compute the layout order of all previous ranges.
addInputRange(const llvm::MCSectionData & pSD,const LDSection & pInputHdr)123 void Layout::addInputRange(const llvm::MCSectionData& pSD,
124 const LDSection& pInputHdr)
125 {
126 RangeList* range_list = NULL;
127
128 // get or create the range_list
129 if (pSD.getFragmentList().empty() || 0 == m_SDRangeMap.count(&pSD)) {
130 range_list = new RangeList();
131 m_SDRangeMap[&pSD] = range_list;
132 }
133 else {
134 range_list = m_SDRangeMap[&pSD];
135 #ifdef MCLD_DEBUG
136 RangeList::iterator rangeIter, rangeEnd = range_list->end();
137 for (rangeIter = range_list->begin(); rangeIter != rangeEnd; ++rangeIter) {
138 if (&pInputHdr == rangeIter->header) {
139 llvm::report_fatal_error(llvm::Twine("Trying to map the same LDSection: ") +
140 pInputHdr.name() +
141 llvm::Twine(" into the different ranges.\n"));
142 }
143 }
144 #endif
145 }
146
147 // make a range and push it into the range list
148 Range* range = new Range(pInputHdr);
149 range_list->push_back(range);
150
151 // set up previous rear of the range.
152 // FIXME: in current design, we can not add a range before finishing adding
153 // fragments in the previous range. If the limitation keeps, we can set
154 // prevRear to the last fragment in the MCSectionData simply.
155 //
156 // if the pSD's fragment list is empty, the range.prevRear keeps NULL.
157 if (!pSD.getFragmentList().empty()) {
158 range->prevRear =
159 const_cast<llvm::MCFragment*>(&pSD.getFragmentList().back());
160 }
161
162 // compute the layout order of the previous range.
163 if (!isFirstRange(*range)) {
164 setFragmentLayoutOrder(range->prevRear);
165 setFragmentLayoutOffset(range->prevRear);
166 }
167 }
168
169 /// appendFragment - append the given MCFragment to the given MCSectionData,
170 /// and insert a MCAlignFragment to preserve the required align constraint if
171 /// needed
appendFragment(llvm::MCFragment & pFrag,llvm::MCSectionData & pSD,uint32_t pAlignConstraint)172 uint64_t Layout::appendFragment(llvm::MCFragment& pFrag,
173 llvm::MCSectionData& pSD,
174 uint32_t pAlignConstraint)
175 {
176 // insert MCAlignFragment into MCSectionData first if needed
177 llvm::MCAlignFragment* align_frag = NULL;
178 if (pAlignConstraint > 1) {
179 align_frag = new llvm::MCAlignFragment(pAlignConstraint, // alignment
180 0x0, // the filled value
181 1u, // the size of filled value
182 pAlignConstraint - 1, // max bytes to emit
183 &pSD);
184 }
185
186 // append the fragment to the MCSectionData
187 pFrag.setParent(&pSD);
188 pSD.getFragmentList().push_back(&pFrag);
189
190 // update the alignment of associated output LDSection if needed
191 LDSection* output_sect = getOutputLDSection(pFrag);
192 assert(NULL != output_sect);
193 if (pAlignConstraint > output_sect->align())
194 output_sect->setAlign(pAlignConstraint);
195
196 // compute the fragment order and offset
197 setFragmentLayoutOrder(&pFrag);
198 setFragmentLayoutOffset(&pFrag);
199
200 if (NULL != align_frag)
201 return pFrag.Offset - align_frag->Offset + computeFragmentSize(*this, pFrag);
202 else
203 return computeFragmentSize(*this, pFrag);
204 }
205
206 /// getInputLDSection - give a MCFragment, return the corresponding input
207 /// LDSection*
208 LDSection*
getInputLDSection(const llvm::MCFragment & pFrag)209 Layout::getInputLDSection(const llvm::MCFragment& pFrag)
210 {
211 const llvm::MCSectionData* sect_data = pFrag.getParent();
212 // check the MCSectionData
213 if (NULL == sect_data) {
214 llvm::report_fatal_error(llvm::Twine("the fragment does not belong to") +
215 llvm::Twine(" any MCSectionData.\n"));
216 }
217
218 // check the MCSectionData's range list
219 if (0 == m_SDRangeMap.count(sect_data)) {
220 llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
221 llvm::Twine("the input's MCSectionData is not ") +
222 llvm::Twine("registered in the Layout.\nPlease ") +
223 llvm::Twine("use MCLinker::getOrCreateSectData() ") +
224 llvm::Twine("to get input's MCSectionData.\n"));
225 }
226
227 RangeList* range_list = m_SDRangeMap[sect_data];
228 // the fragment who has the layout order is not in the last range.
229 if (hasLayoutOrder(pFrag)) {
230 Range range = range_list->back();
231 if (isFirstRange(range)) {
232 return range.header;
233 }
234 while(range.prevRear->getLayoutOrder() > pFrag.getLayoutOrder()) {
235 if (NULL != range.getPrevNode())
236 range = *range.getPrevNode();
237 else
238 return NULL;
239 }
240 return range.header;
241 }
242 // the fragment who has no layout order should be in the last range
243 else {
244 if (range_list->empty())
245 return NULL;
246 return range_list->back().header;
247 }
248 }
249
250 /// getInputLDSection - give a MCFragment, return the corresponding input
251 /// LDSection*
252 const LDSection*
getInputLDSection(const llvm::MCFragment & pFrag) const253 Layout::getInputLDSection(const llvm::MCFragment& pFrag) const
254 {
255 const llvm::MCSectionData* sect_data = pFrag.getParent();
256 // check the MCSectionData
257 if (NULL == sect_data) {
258 llvm::report_fatal_error(llvm::Twine("the fragment does not belong to") +
259 llvm::Twine(" any MCSectionData.\n"));
260 }
261
262 // check the MCSectionData's range list
263 if (0 == m_SDRangeMap.count(sect_data)) {
264 llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
265 llvm::Twine("the input's MCSectionData is not ") +
266 llvm::Twine("registered in the Layout.\nPlease ") +
267 llvm::Twine("use MCLinker::getOrCreateSectData() ") +
268 llvm::Twine("to get input's MCSectionData.\n"));
269 }
270
271 SDRangeMap::const_iterator range_list_iter = m_SDRangeMap.find(sect_data);
272 const RangeList* range_list = range_list_iter->second;
273 // the fragment who has the layout order is not in the last range.
274 if (hasLayoutOrder(pFrag)) {
275 Range range = range_list->back();
276 if (isFirstRange(range)) {
277 return range.header;
278 }
279 while(range.prevRear->getLayoutOrder() > pFrag.getLayoutOrder()) {
280 if (NULL != range.getPrevNode())
281 range = *range.getPrevNode();
282 else
283 return NULL;
284 }
285 return range.header;
286 }
287 // the fragment who has no layout order should be in the last range
288 else {
289 if (range_list->empty())
290 return NULL;
291 return range_list->back().header;
292 }
293 }
294
295 /// getOutputLDSection
getOutputLDSection(const llvm::MCFragment & pFrag)296 LDSection* Layout::getOutputLDSection(const llvm::MCFragment& pFrag)
297 {
298 llvm::MCSectionData* sect_data = pFrag.getParent();
299 if (NULL == sect_data)
300 return NULL;
301
302 return const_cast<LDSection*>(llvm::cast<LDSection>(§_data->getSection()));
303 }
304
305 /// getOutputLDSection
getOutputLDSection(const llvm::MCFragment & pFrag) const306 const LDSection* Layout::getOutputLDSection(const llvm::MCFragment& pFrag) const
307 {
308 const llvm::MCSectionData* sect_data = pFrag.getParent();
309 if (NULL == sect_data)
310 return NULL;
311
312 return llvm::cast<LDSection>(§_data->getSection());
313 }
314
315 /// getFragmentRef - assume the ragne exist, find the fragment reference
316 MCFragmentRef*
getFragmentRef(Layout::Range & pRange,uint64_t pOffset)317 Layout::getFragmentRef(Layout::Range& pRange, uint64_t pOffset)
318 {
319 if (isEmptyRange(pRange))
320 return NULL;
321
322 llvm::MCFragment* front = getFront(pRange);
323 if (NULL == front)
324 return NULL;
325
326 llvm::MCFragment* rear = getRear(pRange);
327 if (NULL == rear)
328 return NULL;
329
330 return getFragmentRef(*front, *rear, pOffset);
331 }
332
333 // @param pFront is the first fragment in the range.
334 // @param pRear is the last fragment in the range.
335 // @pOffset is the offset started from pFront.
336 MCFragmentRef*
getFragmentRef(llvm::MCFragment & pFront,llvm::MCFragment & pRear,uint64_t pOffset)337 Layout::getFragmentRef(llvm::MCFragment& pFront,
338 llvm::MCFragment& pRear,
339 uint64_t pOffset)
340 {
341 llvm::MCFragment* front = &pFront;
342 llvm::MCFragment* rear = &pRear;
343
344 if (!hasLayoutOffset(*rear)) {
345 // compute layout order, offset
346 setFragmentLayoutOrder(rear);
347 setFragmentLayoutOffset(rear);
348 }
349
350 // compute the offset from overall start fragment.
351 uint64_t target_offset = pFront.Offset + pOffset;
352
353 // from front to rear, find the offset which is as large as possible
354 // but smaller than the target_offset.
355 while (front != rear) {
356 if (llvm::MCFragment::FT_Align == front->getKind()) {
357 // alignment fragments were not counted in target_offset.
358 // Count in the size of alignment fragmen in target_offset here.
359 uint64_t align_size = 0x0;
360 if (NULL == front->getNextNode()) {
361 // If the alignment fragment is the last fragment, increase
362 // the target_offset by the alignment fragment's size.
363 align_size = computeFragmentSize(*this, *front);
364 }
365 else {
366 // If the alignment fragment is not the last fragment, the alignment
367 // fragment's size is the distance between the two fragment.
368 align_size = front->getNextNode()->Offset - front->Offset;
369 }
370 target_offset += align_size;
371 front = front->getNextNode();
372 continue;
373 }
374
375 if (target_offset >= front->getNextNode()->Offset) {
376 front = front->getNextNode();
377 }
378 else {
379 // found
380 MCFragmentRef* result = m_FragRefFactory.allocate();
381 new (result) MCFragmentRef(*front, target_offset - front->Offset);
382 return result;
383 }
384 }
385
386 if (front == rear) {
387 if (llvm::MCFragment::FT_Align == front->getKind())
388 return NULL;
389
390 if (!isValidOffset(*front, target_offset))
391 return NULL;
392
393 MCFragmentRef* result = m_FragRefFactory.allocate();
394 new (result) MCFragmentRef(*front, target_offset - front->Offset);
395 return result;
396 }
397 return NULL;
398 }
399
400 /// getFragmentRef - give a LDSection in input file and an offset, return
401 /// the fragment reference.
402 MCFragmentRef*
getFragmentRef(const LDSection & pInputSection,uint64_t pOffset)403 Layout::getFragmentRef(const LDSection& pInputSection, uint64_t pOffset)
404 {
405 // find out which SectionData covers the range of input section header
406 const llvm::MCSectionData* sect_data = pInputSection.getSectionData();
407
408 // check range list
409 if (0 == m_SDRangeMap.count(sect_data))
410 return NULL;
411
412 if (sect_data->getFragmentList().empty())
413 return NULL;
414
415 RangeList* range_list = m_SDRangeMap[sect_data];
416
417 // find out the specific part in SectionData range
418 RangeList::iterator range, rangeEnd = range_list->end();
419 for (range = range_list->begin(); range != rangeEnd; ++range) {
420 // found the range
421 if (&pInputSection == range->header) {
422 break;
423 }
424 }
425
426 // range not found
427 if (range == rangeEnd) {
428 llvm::report_fatal_error(llvm::Twine("section ") +
429 pInputSection.name() +
430 llvm::Twine(" never be in the range list.\n"));
431 }
432
433 return getFragmentRef(*range, pOffset);
434 }
435
436 /// getFragmentRef - give a fragment and a big offset, return the fragment
437 /// reference in the section data.
438 ///
439 /// @param pFrag - the given fragment
440 /// @param pBigOffset - the offset, can be larger than the fragment, but can
441 /// not larger than this input section.
442 /// @return if found, return the fragment. Otherwise, return NULL.
443 MCFragmentRef*
getFragmentRef(const llvm::MCFragment & pFrag,uint64_t pBigOffset)444 Layout::getFragmentRef(const llvm::MCFragment& pFrag, uint64_t pBigOffset)
445 {
446 if (!hasLayoutOffset(pFrag)) {
447 // compute layout order, offset
448 setFragmentLayoutOrder(const_cast<llvm::MCFragment*>(&pFrag));
449 setFragmentLayoutOffset(const_cast<llvm::MCFragment*>(&pFrag));
450 }
451
452 // find out which SectionData covers the range of input section header
453 const llvm::MCSectionData* sect_data = pFrag.getParent();
454
455 // check range list
456 if (0 == m_SDRangeMap.count(sect_data)) {
457 llvm::report_fatal_error(llvm::Twine("MCSectionData has no") +
458 llvm::Twine(" correponding range list.\n"));
459 }
460
461 if (sect_data->getFragmentList().empty())
462 return NULL;
463
464 RangeList* range_list = m_SDRangeMap[sect_data];
465
466 // find out the specific part in SectionData range
467 uint64_t target_offset = pBigOffset + pFrag.Offset;
468
469 RangeList::iterator range, rangeEnd = range_list->end();
470 for (range = range_list->begin(); range != rangeEnd; ++range) {
471 if (isEmptyRange(*range))
472 continue;
473 if (getRear(*range)->Offset >= target_offset) {
474 break;
475 }
476 }
477
478 // range not found
479 if (range == rangeEnd) {
480 llvm::report_fatal_error(llvm::Twine("the offset is too big that") +
481 llvm::Twine(" never be in the range list.\n"));
482 }
483
484 return getFragmentRef(*range, target_offset);
485 }
486
getOutputOffset(const llvm::MCFragment & pFrag)487 uint64_t Layout::getOutputOffset(const llvm::MCFragment& pFrag)
488 {
489 if (!hasLayoutOffset(pFrag)) {
490 // compute layout order, offset
491 setFragmentLayoutOrder(const_cast<llvm::MCFragment*>(&pFrag));
492 setFragmentLayoutOffset(const_cast<llvm::MCFragment*>(&pFrag));
493 }
494 return pFrag.Offset;
495 }
496
getOutputOffset(const llvm::MCFragment & pFrag) const497 uint64_t Layout::getOutputOffset(const llvm::MCFragment& pFrag) const
498 {
499 if (!hasLayoutOffset(pFrag)) {
500 llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
501 llvm::Twine("the function ") +
502 llvm::Twine(__func__) +
503 llvm::Twine(" can not be used before layout().\n"));
504 }
505 return pFrag.Offset;
506 }
507
getOutputOffset(const MCFragmentRef & pFragRef)508 uint64_t Layout::getOutputOffset(const MCFragmentRef& pFragRef)
509 {
510 return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset();
511 }
512
getOutputOffset(const MCFragmentRef & pFragRef) const513 uint64_t Layout::getOutputOffset(const MCFragmentRef& pFragRef) const
514 {
515 return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset();
516 }
517
sortSectionOrder(const Output & pOutput,const TargetLDBackend & pBackend)518 void Layout::sortSectionOrder(const Output& pOutput,
519 const TargetLDBackend& pBackend)
520 {
521 typedef std::pair<LDSection*, unsigned int> SectOrder;
522 typedef std::vector<SectOrder > SectListTy;
523 SectListTy sect_list;
524 // get section order from backend
525 for (size_t index = 0; index < m_SectionOrder.size(); ++index)
526 sect_list.push_back(std::make_pair(
527 m_SectionOrder[index],
528 pBackend.getSectionOrder(pOutput, *m_SectionOrder[index])));
529
530 // simple insertion sort should be fine for general cases such as so and exec
531 for (unsigned int i = 1; i < sect_list.size(); ++i) {
532 SectOrder order = sect_list[i];
533 int j = i - 1;
534 while (j >= 0 && sect_list[j].second > order.second) {
535 sect_list[j + 1] = sect_list[j];
536 --j;
537 }
538 sect_list[j + 1] = order;
539 }
540
541 // update the sorted ordering to m_SectionOrder
542 m_SectionOrder.clear();
543 for (size_t index = 0; index < sect_list.size(); ++index) {
544 m_SectionOrder.push_back(sect_list[index].first);
545 }
546 }
547
layout(Output & pOutput,const TargetLDBackend & pBackend)548 bool Layout::layout(Output& pOutput, const TargetLDBackend& pBackend)
549 {
550 // determine what sections in output context will go into final output, and
551 // push the needed sections into m_SectionOrder for later processing
552 assert(pOutput.hasContext());
553 LDContext& output_context = *pOutput.context();
554 LDContext::sect_iterator it, itEnd = output_context.sectEnd();
555 for (it = output_context.sectBegin(); it != itEnd; ++it) {
556 LDSection* sect = *it;
557
558 switch (sect->kind()) {
559 // ignore if there is no SectionData for certain section kinds
560 case LDFileFormat::Regular:
561 case LDFileFormat::Note:
562 case LDFileFormat::Target:
563 case LDFileFormat::MetaData:
564 case LDFileFormat::BSS:
565 if (0 != sect->size()) {
566 if (NULL != sect->getSectionData() &&
567 !sect->getSectionData()->getFragmentList().empty()) {
568 // make sure that all fragments are valid
569 llvm::MCFragment& frag =
570 sect->getSectionData()->getFragmentList().back();
571 setFragmentLayoutOrder(&frag);
572 setFragmentLayoutOffset(&frag);
573 }
574 m_SectionOrder.push_back(sect);
575 }
576 break;
577 // take NULL directly
578 case LDFileFormat::Null:
579 m_SectionOrder.push_back(sect);
580 break;
581 // ignore if section size is 0
582 case LDFileFormat::NamePool:
583 case LDFileFormat::Relocation:
584 if (0 != sect->size())
585 m_SectionOrder.push_back(sect);
586 break;
587 case LDFileFormat::Group:
588 if (MCLDFile::Object == pOutput.type()) {
589 //TODO: support incremental linking
590 ;
591 }
592 break;
593 case LDFileFormat::Debug:
594 if (0 != sect->size()) {
595 m_SectionOrder.push_back(sect);
596 llvm::errs() << "WARNING: DWRAF debugging has not been fully supported yet.\n"
597 << "section `" << sect->name() << "'.\n";
598 }
599 break;
600 case LDFileFormat::Exception:
601 if (0 != sect->size()) {
602 llvm::errs() << "WARNING: Exception handling has not been fully supported yet.\n"
603 << "section `" << sect->name() << "'.\n";
604 if (NULL != sect->getSectionData() &&
605 !sect->getSectionData()->getFragmentList().empty()) {
606 // make sure that all fragments are valid
607 llvm::MCFragment& frag =
608 sect->getSectionData()->getFragmentList().back();
609 setFragmentLayoutOrder(&frag);
610 setFragmentLayoutOffset(&frag);
611 }
612 m_SectionOrder.push_back(sect);
613 }
614 break;
615 case LDFileFormat::Version:
616 if (0 != sect->size()) {
617 m_SectionOrder.push_back(sect);
618 llvm::errs() << "WARNING: Symbolic versioning has not been fully supported yet.\n"
619 << "section `" << sect->name() << "'.\n";
620 }
621 break;
622 default:
623 llvm::report_fatal_error(llvm::Twine("Unsupported section kind of `") +
624 sect->name() +
625 llvm::Twine("': ") +
626 llvm::Twine(sect->kind()) +
627 llvm::Twine(".\n"));
628 break;
629 }
630 }
631
632 // perform sorting on m_SectionOrder to get a ordering for final layout
633 sortSectionOrder(pOutput, pBackend);
634
635 // Backend defines the section start offset for section 1.
636 uint64_t offset = pBackend.sectionStartOffset();
637 // compute the section offset and handle alignment also. And ignore section 0
638 // (NULL in ELF/COFF), and MachO starts from section 1.
639 for (size_t index = 1; index < m_SectionOrder.size(); ++index) {
640 // we should not preserve file space for the BSS section.
641 if (LDFileFormat::BSS != m_SectionOrder[index - 1]->kind())
642 offset += m_SectionOrder[index - 1]->size();
643
644 alignAddress(offset, m_SectionOrder[index]->align());
645
646 m_SectionOrder[index]->setOffset(offset);
647 }
648
649 // FIXME: Currently Writer bases on the section table in output context to
650 // write out sections, so we have to update its content..
651 output_context.getSectionTable().clear();
652 for (size_t index = 0; index < m_SectionOrder.size(); ++index) {
653 output_context.getSectionTable().push_back(m_SectionOrder[index]);
654 // after sorting, update the correct output section indices
655 m_SectionOrder[index]->setIndex(index);
656 }
657 return true;
658 }
659
isValidOffset(const llvm::MCFragment & pFrag,uint64_t pTargetOffset) const660 bool Layout::isValidOffset(const llvm::MCFragment& pFrag, uint64_t pTargetOffset) const
661 {
662 uint64_t size = computeFragmentSize(*this, pFrag);
663 if (0x0 == size)
664 return (pTargetOffset == pFrag.Offset);
665
666 if (NULL != pFrag.getNextNode())
667 return (pTargetOffset >= pFrag.Offset && pTargetOffset < pFrag.getNextNode()->Offset);
668
669 return (pTargetOffset >= pFrag.Offset && pTargetOffset < (pFrag.Offset + size));
670 }
671
672