15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- Layout.cpp ---------------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Twine.h>
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ErrorHandling.h>
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/SizeTraits.h>
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/Layout.h>
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDFileFormat.h>
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSection.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDContext.h>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/TargetLDBackend.h>
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cassert>
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Range
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::Range::Range()
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : header(NULL),
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    prevRear(NULL) {
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::Range::Range(const LDSection& pHdr)
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : header(const_cast<LDSection*>(&pHdr)),
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    prevRear(NULL) {
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::Range::~Range()
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Layout
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::Layout()
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_FragRefFactory(32) /** magic number **/ {
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::~Layout()
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Layout::setFragmentLayoutOrder(llvm::MCFragment* pFrag)
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == pFrag)
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return;
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute the most-recent fragment whose order was set.
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::MCFragment* first = pFrag;
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while (!hasLayoutOrder(*first)) {
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (NULL == first->getPrevNode())
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    first = first->getPrevNode();
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set all layout order
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  unsigned int layout_order = 0;
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::MCFragment* frag_not_set = NULL;
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == first->getPrevNode()) {
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    layout_order = 0;
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set = first;
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    layout_order = first->getLayoutOrder();
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set = first->getNextNode();
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up all layout order
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while(NULL != frag_not_set) {
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set->setLayoutOrder(layout_order);
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++layout_order;
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set = frag_not_set->getNextNode();
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// setFragmentLayoutOffset - set the fragment's layout offset. This function
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// also set up the layout offsets of all the fragments in the same range.
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// If the offset of the fragment was set before, return immediately.
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Layout::setFragmentLayoutOffset(llvm::MCFragment* pFrag)
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == pFrag)
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return;
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute the most-recent fragment whose offset was set.
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::MCFragment* first = pFrag;
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while (!hasLayoutOffset(*first)) {
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (NULL == first->getPrevNode())
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    first = first->getPrevNode();
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set all layout order
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t offset = 0;
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::MCFragment* frag_not_set = NULL;
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == first->getPrevNode()) {
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    offset = 0;
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set = first;
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    offset = first->Offset;
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    offset += computeFragmentSize(*this, *first);
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set = first->getNextNode();
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while(NULL != frag_not_set) {
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set->Offset = offset;
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    offset += computeFragmentSize(*this, *frag_not_set);
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set = frag_not_set->getNextNode();
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// addInputRange
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///   1. add a new range <pInputHdr, previous rear fragment>
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///   2. compute the layout order of all previous ranges.
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Layout::addInputRange(const llvm::MCSectionData& pSD,
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           const LDSection& pInputHdr)
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RangeList* range_list = NULL;
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get or create the range_list
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSD.getFragmentList().empty() || 0 == m_SDRangeMap.count(&pSD)) {
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    range_list = new RangeList();
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_SDRangeMap[&pSD] = range_list;
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    range_list = m_SDRangeMap[&pSD];
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifdef MCLD_DEBUG
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    RangeList::iterator rangeIter, rangeEnd = range_list->end();
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    for (rangeIter = range_list->begin(); rangeIter != rangeEnd; ++rangeIter) {
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (&pInputHdr == rangeIter->header) {
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        llvm::report_fatal_error(llvm::Twine("Trying to map the same LDSection: ") +
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                 pInputHdr.name() +
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                 llvm::Twine(" into the different ranges.\n"));
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make a range and push it into the range list
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Range* range = new Range(pInputHdr);
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  range_list->push_back(range);
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up previous rear of the range.
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: in current design, we can not add a range before finishing adding
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // fragments in the previous range. If the limitation keeps, we can set
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // prevRear to the last fragment in the MCSectionData simply.
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // if the pSD's fragment list is empty, the range.prevRear keeps NULL.
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!pSD.getFragmentList().empty()) {
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    range->prevRear =
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                  const_cast<llvm::MCFragment*>(&pSD.getFragmentList().back());
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute the layout order of the previous range.
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!isFirstRange(*range)) {
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    setFragmentLayoutOrder(range->prevRear);
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    setFragmentLayoutOffset(range->prevRear);
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// appendFragment - append the given MCFragment to the given MCSectionData,
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// and insert a MCAlignFragment to preserve the required align constraint if
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// needed
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t Layout::appendFragment(llvm::MCFragment& pFrag,
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                llvm::MCSectionData& pSD,
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                uint32_t pAlignConstraint)
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // insert MCAlignFragment into MCSectionData first if needed
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::MCAlignFragment* align_frag = NULL;
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pAlignConstraint > 1) {
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    align_frag = new llvm::MCAlignFragment(pAlignConstraint, // alignment
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           0x0, // the filled value
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           1u,  // the size of filled value
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           pAlignConstraint - 1, // max bytes to emit
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           &pSD);
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // append the fragment to the MCSectionData
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pFrag.setParent(&pSD);
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pSD.getFragmentList().push_back(&pFrag);
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // update the alignment of associated output LDSection if needed
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* output_sect = getOutputLDSection(pFrag);
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != output_sect);
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pAlignConstraint > output_sect->align())
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sect->setAlign(pAlignConstraint);
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute the fragment order and offset
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  setFragmentLayoutOrder(&pFrag);
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  setFragmentLayoutOffset(&pFrag);
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != align_frag)
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return pFrag.Offset - align_frag->Offset + computeFragmentSize(*this, pFrag);
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return computeFragmentSize(*this, pFrag);
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getInputLDSection - give a MCFragment, return the corresponding input
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// LDSection*
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSection*
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::getInputLDSection(const llvm::MCFragment& pFrag)
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const llvm::MCSectionData* sect_data = pFrag.getParent();
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // check the MCSectionData
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == sect_data) {
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("the fragment does not belong to") +
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(" any MCSectionData.\n"));
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // check the MCSectionData's range list
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == m_SDRangeMap.count(sect_data)) {
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("the input's MCSectionData is not ") +
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("registered in the Layout.\nPlease ") +
2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("use MCLinker::getOrCreateSectData() ") +
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("to get input's MCSectionData.\n"));
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RangeList* range_list = m_SDRangeMap[sect_data];
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the fragment who has the layout order is not in the last range.
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (hasLayoutOrder(pFrag)) {
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Range range = range_list->back();
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (isFirstRange(range)) {
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return range.header;
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    while(range.prevRear->getLayoutOrder() > pFrag.getLayoutOrder()) {
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (NULL != range.getPrevNode())
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        range = *range.getPrevNode();
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return NULL;
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return range.header;
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the fragment who has no layout order should be in the last range
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (range_list->empty())
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return NULL;
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return range_list->back().header;
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getInputLDSection - give a MCFragment, return the corresponding input
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// LDSection*
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst LDSection*
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::getInputLDSection(const llvm::MCFragment& pFrag) const
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const llvm::MCSectionData* sect_data = pFrag.getParent();
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // check the MCSectionData
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == sect_data) {
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("the fragment does not belong to") +
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(" any MCSectionData.\n"));
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // check the MCSectionData's range list
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == m_SDRangeMap.count(sect_data)) {
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("the input's MCSectionData is not ") +
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("registered in the Layout.\nPlease ") +
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("use MCLinker::getOrCreateSectData() ") +
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("to get input's MCSectionData.\n"));
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SDRangeMap::const_iterator range_list_iter = m_SDRangeMap.find(sect_data);
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const RangeList* range_list = range_list_iter->second;
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the fragment who has the layout order is not in the last range.
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (hasLayoutOrder(pFrag)) {
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Range range = range_list->back();
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (isFirstRange(range)) {
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return range.header;
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    while(range.prevRear->getLayoutOrder() > pFrag.getLayoutOrder()) {
2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (NULL != range.getPrevNode())
2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        range = *range.getPrevNode();
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else
2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return NULL;
2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return range.header;
2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the fragment who has no layout order should be in the last range
2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (range_list->empty())
2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return NULL;
2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return range_list->back().header;
2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getOutputLDSection
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSection* Layout::getOutputLDSection(const llvm::MCFragment& pFrag)
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::MCSectionData* sect_data = pFrag.getParent();
2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == sect_data)
3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return const_cast<LDSection*>(llvm::cast<LDSection>(&sect_data->getSection()));
3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getOutputLDSection
3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst LDSection* Layout::getOutputLDSection(const llvm::MCFragment& pFrag) const
3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const llvm::MCSectionData* sect_data = pFrag.getParent();
3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == sect_data)
3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return llvm::cast<LDSection>(&sect_data->getSection());
3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getFragmentRef - assume the ragne exist, find the fragment reference
3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMCFragmentRef*
3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::getFragmentRef(Layout::Range& pRange, uint64_t pOffset)
3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (isEmptyRange(pRange))
3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::MCFragment* front = getFront(pRange);
3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == front)
3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::MCFragment* rear = getRear(pRange);
3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == rear)
3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return getFragmentRef(*front, *rear, pOffset);
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// @param pFront is the first fragment in the range.
3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// @param pRear is the last fragment in the range.
3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// @pOffset is the offset started from pFront.
3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMCFragmentRef*
3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::getFragmentRef(llvm::MCFragment& pFront,
3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                       llvm::MCFragment& pRear,
3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                       uint64_t pOffset)
3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::MCFragment* front = &pFront;
3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::MCFragment* rear  = &pRear;
3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!hasLayoutOffset(*rear)) {
3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // compute layout order, offset
3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    setFragmentLayoutOrder(rear);
3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    setFragmentLayoutOffset(rear);
3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute the offset from overall start fragment.
3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t target_offset = pFront.Offset + pOffset;
3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // from front to rear, find the offset which is as large as possible
3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // but smaller than the target_offset.
3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while (front != rear) {
3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (llvm::MCFragment::FT_Align == front->getKind()) {
3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // alignment fragments were not counted in target_offset.
3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Count in the size of alignment fragmen in target_offset here.
3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      uint64_t align_size = 0x0;
3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (NULL == front->getNextNode()) {
3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // If the alignment fragment is the last fragment, increase
3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // the target_offset by the alignment fragment's size.
3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        align_size = computeFragmentSize(*this, *front);
3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else {
3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // If the alignment fragment is not the last fragment, the alignment
3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // fragment's size is the distance between the two fragment.
3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        align_size = front->getNextNode()->Offset - front->Offset;
3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      target_offset += align_size;
3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      front = front->getNextNode();
3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (target_offset >= front->getNextNode()->Offset) {
3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      front = front->getNextNode();
3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else {
3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // found
3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      MCFragmentRef* result = m_FragRefFactory.allocate();
3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      new (result) MCFragmentRef(*front, target_offset - front->Offset);
3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return result;
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (front == rear) {
3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (llvm::MCFragment::FT_Align == front->getKind())
3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return NULL;
3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!isValidOffset(*front, target_offset))
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return NULL;
3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    MCFragmentRef* result = m_FragRefFactory.allocate();
3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    new (result) MCFragmentRef(*front, target_offset - front->Offset);
3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return result;
3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return NULL;
3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getFragmentRef - give a LDSection in input file and an offset, return
4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the fragment reference.
4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMCFragmentRef*
4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::getFragmentRef(const LDSection& pInputSection, uint64_t pOffset)
4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // find out which SectionData covers the range of input section header
4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const llvm::MCSectionData* sect_data = pInputSection.getSectionData();
4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // check range list
4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == m_SDRangeMap.count(sect_data))
4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (sect_data->getFragmentList().empty())
4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RangeList* range_list = m_SDRangeMap[sect_data];
4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // find out the specific part in SectionData range
4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RangeList::iterator range, rangeEnd = range_list->end();
4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (range = range_list->begin(); range != rangeEnd; ++range) {
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // found the range
4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (&pInputSection == range->header) {
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // range not found
4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (range == rangeEnd) {
4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("section ") +
4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             pInputSection.name() +
4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(" never be in the range list.\n"));
4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return getFragmentRef(*range, pOffset);
4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getFragmentRef - give a fragment and a big offset, return the fragment
4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// reference in the section data.
4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @param pFrag - the given fragment
4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @param pBigOffset - the offset, can be larger than the fragment, but can
4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///                     not larger than this input section.
4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @return if found, return the fragment. Otherwise, return NULL.
4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMCFragmentRef*
4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::getFragmentRef(const llvm::MCFragment& pFrag, uint64_t pBigOffset)
4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!hasLayoutOffset(pFrag)) {
4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // compute layout order, offset
4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    setFragmentLayoutOrder(const_cast<llvm::MCFragment*>(&pFrag));
4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    setFragmentLayoutOffset(const_cast<llvm::MCFragment*>(&pFrag));
4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // find out which SectionData covers the range of input section header
4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const llvm::MCSectionData* sect_data = pFrag.getParent();
4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // check range list
4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == m_SDRangeMap.count(sect_data)) {
4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("MCSectionData has no") +
4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(" correponding range list.\n"));
4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (sect_data->getFragmentList().empty())
4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RangeList* range_list = m_SDRangeMap[sect_data];
4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // find out the specific part in SectionData range
4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t target_offset = pBigOffset + pFrag.Offset;
4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RangeList::iterator range, rangeEnd = range_list->end();
4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (range = range_list->begin(); range != rangeEnd; ++range) {
4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (isEmptyRange(*range))
4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (getRear(*range)->Offset >= target_offset) {
4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // range not found
4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (range == rangeEnd) {
4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("the offset is too big that") +
4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(" never be in the range list.\n"));
4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return getFragmentRef(*range, target_offset);
4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t Layout::getOutputOffset(const llvm::MCFragment& pFrag)
4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!hasLayoutOffset(pFrag)) {
4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // compute layout order, offset
4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    setFragmentLayoutOrder(const_cast<llvm::MCFragment*>(&pFrag));
4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    setFragmentLayoutOffset(const_cast<llvm::MCFragment*>(&pFrag));
4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pFrag.Offset;
4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t Layout::getOutputOffset(const llvm::MCFragment& pFrag) const
4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!hasLayoutOffset(pFrag)) {
5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("the function ") +
5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(__func__) +
5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(" can not be used before layout().\n"));
5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pFrag.Offset;
5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t Layout::getOutputOffset(const MCFragmentRef& pFragRef)
5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset();
5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t Layout::getOutputOffset(const MCFragmentRef& pFragRef) const
5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset();
5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Layout::sortSectionOrder(const Output& pOutput,
5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                              const TargetLDBackend& pBackend)
5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef std::pair<LDSection*, unsigned int> SectOrder;
5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef std::vector<SectOrder > SectListTy;
5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SectListTy sect_list;
5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get section order from backend
5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t index = 0; index < m_SectionOrder.size(); ++index)
5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    sect_list.push_back(std::make_pair(
5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                    m_SectionOrder[index],
5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                    pBackend.getSectionOrder(pOutput, *m_SectionOrder[index])));
5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // simple insertion sort should be fine for general cases such as so and exec
5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (unsigned int i = 1; i < sect_list.size(); ++i) {
5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SectOrder order = sect_list[i];
5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    int j = i - 1;
5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    while (j >= 0 && sect_list[j].second > order.second) {
5355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      sect_list[j + 1] = sect_list[j];
5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      --j;
5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    sect_list[j + 1] = order;
5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // update the sorted ordering to m_SectionOrder
5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_SectionOrder.clear();
5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t index = 0; index < sect_list.size(); ++index) {
5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_SectionOrder.push_back(sect_list[index].first);
5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool Layout::layout(Output& pOutput, const TargetLDBackend& pBackend)
5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // determine what sections in output context will go into final output, and
5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // push the needed sections into m_SectionOrder for later processing
5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pOutput.hasContext());
5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDContext& output_context = *pOutput.context();
5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDContext::sect_iterator it, itEnd = output_context.sectEnd();
5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (it = output_context.sectBegin(); it != itEnd; ++it) {
5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    LDSection* sect = *it;
5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    switch (sect->kind()) {
5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // ignore if there is no SectionData for certain section kinds
5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Regular:
5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Note:
5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Target:
5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::MetaData:
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::BSS:
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (0 != sect->size()) {
5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          if (NULL != sect->getSectionData() &&
5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              !sect->getSectionData()->getFragmentList().empty()) {
5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            // make sure that all fragments are valid
5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            llvm::MCFragment& frag =
5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              sect->getSectionData()->getFragmentList().back();
5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            setFragmentLayoutOrder(&frag);
5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            setFragmentLayoutOffset(&frag);
5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          }
5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_SectionOrder.push_back(sect);
5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // take NULL directly
5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Null:
5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_SectionOrder.push_back(sect);
5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // ignore if section size is 0
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::NamePool:
5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Relocation:
5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (0 != sect->size())
5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_SectionOrder.push_back(sect);
5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Group:
5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (MCLDFile::Object == pOutput.type()) {
5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          //TODO: support incremental linking
5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          ;
5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Debug:
5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (0 != sect->size()) {
5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_SectionOrder.push_back(sect);
5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          llvm::errs() << "WARNING: DWRAF debugging has not been fully supported yet.\n"
5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                       << "section `" << sect->name() << "'.\n";
5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Exception:
6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (0 != sect->size()) {
6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          llvm::errs() << "WARNING: Exception handling has not been fully supported yet.\n"
6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                       << "section `" << sect->name() << "'.\n";
6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          if (NULL != sect->getSectionData() &&
6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              !sect->getSectionData()->getFragmentList().empty()) {
6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            // make sure that all fragments are valid
6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            llvm::MCFragment& frag =
6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              sect->getSectionData()->getFragmentList().back();
6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            setFragmentLayoutOrder(&frag);
6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            setFragmentLayoutOffset(&frag);
6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          }
6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_SectionOrder.push_back(sect);
6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Version:
6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (0 != sect->size()) {
6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_SectionOrder.push_back(sect);
6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          llvm::errs() << "WARNING: Symbolic versioning has not been fully supported yet.\n"
6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                       << "section `" << sect->name() << "'.\n";
6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      default:
6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        llvm::report_fatal_error(llvm::Twine("Unsupported section kind of `") +
6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                 sect->name() +
6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                 llvm::Twine("': ") +
6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                 llvm::Twine(sect->kind()) +
6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                 llvm::Twine(".\n"));
6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // perform sorting on m_SectionOrder to get a ordering for final layout
6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sortSectionOrder(pOutput, pBackend);
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Backend defines the section start offset for section 1.
6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t offset = pBackend.sectionStartOffset();
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute the section offset and handle alignment also. And ignore section 0
6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // (NULL in ELF/COFF), and MachO starts from section 1.
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t index = 1; index < m_SectionOrder.size(); ++index) {
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // we should not preserve file space for the BSS section.
6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (LDFileFormat::BSS != m_SectionOrder[index - 1]->kind())
6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      offset += m_SectionOrder[index - 1]->size();
6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    alignAddress(offset, m_SectionOrder[index]->align());
6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_SectionOrder[index]->setOffset(offset);
6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: Currently Writer bases on the section table in output context to
6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // write out sections, so we have to update its content..
6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  output_context.getSectionTable().clear();
6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t index = 0; index < m_SectionOrder.size(); ++index) {
6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_context.getSectionTable().push_back(m_SectionOrder[index]);
6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // after sorting, update the correct output section indices
6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_SectionOrder[index]->setIndex(index);
6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool Layout::isValidOffset(const llvm::MCFragment& pFrag, uint64_t pTargetOffset) const
6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t size = computeFragmentSize(*this, pFrag);
6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0x0 == size)
6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return (pTargetOffset == pFrag.Offset);
6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != pFrag.getNextNode())
6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return (pTargetOffset >= pFrag.Offset && pTargetOffset < pFrag.getNextNode()->Offset);
6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return (pTargetOffset >= pFrag.Offset && pTargetOffset < (pFrag.Offset + size));
6705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
672