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
28using namespace mcld;
29
30//===----------------------------------------------------------------------===//
31// Range
32//===----------------------------------------------------------------------===//
33Layout::Range::Range()
34  : header(NULL),
35    prevRear(NULL) {
36}
37
38Layout::Range::Range(const LDSection& pHdr)
39  : header(const_cast<LDSection*>(&pHdr)),
40    prevRear(NULL) {
41}
42
43Layout::Range::~Range()
44{
45}
46
47//===----------------------------------------------------------------------===//
48// Layout
49//===----------------------------------------------------------------------===//
50Layout::Layout()
51  : m_FragRefFactory(32) /** magic number **/ {
52}
53
54Layout::~Layout()
55{
56}
57
58void 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.
97void 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.
135void 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
174uint64_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*
210LDSection*
211Layout::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*
254const LDSection*
255Layout::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
298LDSection* 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*>(&sect_data->getSection());
305}
306
307/// getOutputLDSection
308const 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 &sect_data->getSection();
315}
316
317/// getFragmentRef - assume the ragne exist, find the fragment reference
318FragmentRef* 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.
337FragmentRef*
338Layout::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.
401FragmentRef*
402Layout::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.
440FragmentRef*
441Layout::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
484uint64_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
494uint64_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
505uint64_t Layout::getOutputOffset(const FragmentRef& pFragRef)
506{
507  return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset();
508}
509
510uint64_t Layout::getOutputOffset(const FragmentRef& pFragRef) const
511{
512  return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset();
513}
514
515void 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
550bool 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
645bool 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