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