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
10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/Layout.h>
11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cassert>
13cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Twine.h>
15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/SizeTraits.h>
17affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/LDContext.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDFileFormat.h>
19affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/LDSection.h>
20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/Fragment.h>
21cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/FillFragment.h>
22cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/AlignFragment.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h>
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h>
25affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/TargetLDBackend.h>
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Range
32cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::Range::Range()
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : header(NULL),
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    prevRear(NULL) {
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::Range::Range(const LDSection& pHdr)
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : header(const_cast<LDSection*>(&pHdr)),
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    prevRear(NULL) {
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::Range::~Range()
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Layout
49cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::Layout()
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_FragRefFactory(32) /** magic number **/ {
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::~Layout()
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
58cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaovoid Layout::setFragmentLayoutOrder(Fragment* pFrag)
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == pFrag)
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return;
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
63cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  /// find the most-recent fragment whose order was set.
64cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  Fragment* first = pFrag;
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while (!hasLayoutOrder(*first)) {
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (NULL == first->getPrevNode())
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    first = first->getPrevNode();
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
71cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  /// set all layout order
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
73cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // find the first fragment who has no order.
74cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // find the last order of the fragment
75cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  unsigned int layout_order = 0;
76cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  Fragment* frag_not_set = NULL;
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == first->getPrevNode()) {
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    layout_order = 0;
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set = first;
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    layout_order = first->getLayoutOrder();
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set = first->getNextNode();
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
86cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // for all fragments that has no order, set up its order
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while(NULL != frag_not_set) {
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set->setLayoutOrder(layout_order);
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++layout_order;
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set = frag_not_set->getNextNode();
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// setFragmentLayoutOffset - set the fragment's layout offset. This function
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// also set up the layout offsets of all the fragments in the same range.
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// If the offset of the fragment was set before, return immediately.
97cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaovoid Layout::setFragmentLayoutOffset(Fragment* pFrag)
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == pFrag)
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return;
101cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
102cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // find the most-recent fragment whose offset was set.
103cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  Fragment* first = pFrag;
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while (!hasLayoutOffset(*first)) {
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (NULL == first->getPrevNode())
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    first = first->getPrevNode();
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set all layout order
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t offset = 0;
113cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  Fragment* frag_not_set = NULL;
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == first->getPrevNode()) {
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    offset = 0;
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set = first;
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
119cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    offset = first->getOffset();
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    offset += computeFragmentSize(*this, *first);
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set = first->getNextNode();
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while(NULL != frag_not_set) {
125cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    frag_not_set->setOffset(offset);
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    offset += computeFragmentSize(*this, *frag_not_set);
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    frag_not_set = frag_not_set->getNextNode();
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// addInputRange
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///   1. add a new range <pInputHdr, previous rear fragment>
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///   2. compute the layout order of all previous ranges.
134cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao///   2. compute the layout offset of all previous ranges.
135cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaovoid Layout::addInputRange(const SectionData& pSD,
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           const LDSection& pInputHdr)
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RangeList* range_list = NULL;
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get or create the range_list
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pSD.getFragmentList().empty() || 0 == m_SDRangeMap.count(&pSD)) {
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    range_list = new RangeList();
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_SDRangeMap[&pSD] = range_list;
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    range_list = m_SDRangeMap[&pSD];
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // make a range and push it into the range list
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Range* range = new Range(pInputHdr);
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  range_list->push_back(range);
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up previous rear of the range.
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: in current design, we can not add a range before finishing adding
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // fragments in the previous range. If the limitation keeps, we can set
156cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // prevRear to the last fragment in the SectionData simply.
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // if the pSD's fragment list is empty, the range.prevRear keeps NULL.
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!pSD.getFragmentList().empty()) {
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    range->prevRear =
161cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                  const_cast<Fragment*>(&pSD.getFragmentList().back());
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute the layout order of the previous range.
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!isFirstRange(*range)) {
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    setFragmentLayoutOrder(range->prevRear);
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    setFragmentLayoutOffset(range->prevRear);
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
171cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// appendFragment - append the given Fragment to the given SectionData,
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// and insert a MCAlignFragment to preserve the required align constraint if
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// needed
174cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaouint64_t Layout::appendFragment(Fragment& pFrag,
175cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                SectionData& pSD,
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                uint32_t pAlignConstraint)
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
178cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // insert MCAlignFragment into SectionData first if needed
179cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  AlignFragment* align_frag = NULL;
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pAlignConstraint > 1) {
181cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    align_frag = new AlignFragment(pAlignConstraint, // alignment
182cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                   0x0, // the filled value
183cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                   1u,  // the size of filled value
184cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                   pAlignConstraint - 1, // max bytes to emit
185cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                   &pSD);
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
188cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // append the fragment to the SectionData
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pFrag.setParent(&pSD);
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pSD.getFragmentList().push_back(&pFrag);
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // update the alignment of associated output LDSection if needed
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* output_sect = getOutputLDSection(pFrag);
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != output_sect);
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pAlignConstraint > output_sect->align())
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sect->setAlign(pAlignConstraint);
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute the fragment order and offset
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  setFragmentLayoutOrder(&pFrag);
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  setFragmentLayoutOffset(&pFrag);
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != align_frag)
203cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    return pFrag.getOffset() - align_frag->getOffset() + computeFragmentSize(*this, pFrag);
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return computeFragmentSize(*this, pFrag);
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
208cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// getInputLDSection - give a Fragment, return the corresponding input
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// LDSection*
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSection*
211cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoLayout::getInputLDSection(const Fragment& pFrag)
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
213cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  const SectionData* sect_data = pFrag.getParent();
214cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // check the SectionData
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == sect_data) {
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("the fragment does not belong to") +
217cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                             llvm::Twine(" any SectionData.\n"));
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
220cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // check the SectionData's range list
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == m_SDRangeMap.count(sect_data)) {
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
223cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                             llvm::Twine("the input's SectionData is not ") +
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("registered in the Layout.\nPlease ") +
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("use MCLinker::getOrCreateSectData() ") +
226cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                             llvm::Twine("to get input's SectionData.\n"));
2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RangeList* range_list = m_SDRangeMap[sect_data];
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the fragment who has the layout order is not in the last range.
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (hasLayoutOrder(pFrag)) {
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Range range = range_list->back();
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (isFirstRange(range)) {
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return range.header;
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    while(range.prevRear->getLayoutOrder() > pFrag.getLayoutOrder()) {
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (NULL != range.getPrevNode())
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        range = *range.getPrevNode();
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return NULL;
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return range.header;
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the fragment who has no layout order should be in the last range
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (range_list->empty())
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return NULL;
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return range_list->back().header;
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
252cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// getInputLDSection - give a Fragment, return the corresponding input
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// LDSection*
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst LDSection*
255cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoLayout::getInputLDSection(const Fragment& pFrag) const
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
257cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  const SectionData* sect_data = pFrag.getParent();
258cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // check the SectionData
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == sect_data) {
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("the fragment does not belong to") +
261cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                             llvm::Twine(" any SectionData.\n"));
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
264cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // check the SectionData's range list
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == m_SDRangeMap.count(sect_data)) {
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
267cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                             llvm::Twine("the input's SectionData is not ") +
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("registered in the Layout.\nPlease ") +
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("use MCLinker::getOrCreateSectData() ") +
270cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                             llvm::Twine("to get input's SectionData.\n"));
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SDRangeMap::const_iterator range_list_iter = m_SDRangeMap.find(sect_data);
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const RangeList* range_list = range_list_iter->second;
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the fragment who has the layout order is not in the last range.
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (hasLayoutOrder(pFrag)) {
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Range range = range_list->back();
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (isFirstRange(range)) {
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return range.header;
2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    while(range.prevRear->getLayoutOrder() > pFrag.getLayoutOrder()) {
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (NULL != range.getPrevNode())
2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        range = *range.getPrevNode();
2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else
2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return NULL;
2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return range.header;
2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the fragment who has no layout order should be in the last range
2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (range_list->empty())
2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return NULL;
2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return range_list->back().header;
2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getOutputLDSection
298cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoLDSection* Layout::getOutputLDSection(const Fragment& pFrag)
2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
300cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  SectionData* sect_data = pFrag.getParent();
3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == sect_data)
3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
304cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  return const_cast<LDSection*>(&sect_data->getSection());
3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getOutputLDSection
308cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaoconst LDSection* Layout::getOutputLDSection(const Fragment& pFrag) const
3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
310cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  const SectionData* sect_data = pFrag.getParent();
3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == sect_data)
3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
314cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  return &sect_data->getSection();
3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getFragmentRef - assume the ragne exist, find the fragment reference
318cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoFragmentRef* Layout::getFragmentRef(Layout::Range& pRange, uint64_t pOffset)
3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (isEmptyRange(pRange))
3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
323cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  Fragment* front = getFront(pRange);
3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == front)
3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
327cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  Fragment* rear = getRear(pRange);
3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == rear)
3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return getFragmentRef(*front, *rear, pOffset);
3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// @param pFront is the first fragment in the range.
3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// @param pRear is the last fragment in the range.
3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// @pOffset is the offset started from pFront.
337cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoFragmentRef*
338cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoLayout::getFragmentRef(Fragment& pFront, Fragment& pRear, uint64_t pOffset)
3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
340cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  Fragment* front = &pFront;
341cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  Fragment* rear  = &pRear;
3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!hasLayoutOffset(*rear)) {
3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // compute layout order, offset
3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    setFragmentLayoutOrder(rear);
3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    setFragmentLayoutOffset(rear);
3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // compute the offset from overall start fragment.
350cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  uint64_t target_offset = pFront.getOffset() + pOffset;
3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // from front to rear, find the offset which is as large as possible
3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // but smaller than the target_offset.
3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while (front != rear) {
355cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    if (Fragment::Alignment == front->getKind()) {
3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // alignment fragments were not counted in target_offset.
3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // Count in the size of alignment fragmen in target_offset here.
3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      uint64_t align_size = 0x0;
3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (NULL == front->getNextNode()) {
3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // If the alignment fragment is the last fragment, increase
3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // the target_offset by the alignment fragment's size.
3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        align_size = computeFragmentSize(*this, *front);
3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else {
3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // If the alignment fragment is not the last fragment, the alignment
3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // fragment's size is the distance between the two fragment.
367cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        align_size = front->getNextNode()->getOffset() - front->getOffset();
3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      target_offset += align_size;
3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      front = front->getNextNode();
3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
374cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    if (target_offset >= front->getNextNode()->getOffset()) {
3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      front = front->getNextNode();
3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else {
3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // found
379cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      FragmentRef* result = m_FragRefFactory.allocate();
380cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      new (result) FragmentRef(*front, target_offset - front->getOffset());
3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return result;
3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (front == rear) {
386cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    if (Fragment::Alignment == front->getKind())
3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return NULL;
3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!isValidOffset(*front, target_offset))
3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      return NULL;
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
392cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    FragmentRef* result = m_FragRefFactory.allocate();
393cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    new (result) FragmentRef(*front, target_offset - front->getOffset());
3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return result;
3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return NULL;
3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getFragmentRef - give a LDSection in input file and an offset, return
4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// the fragment reference.
401cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoFragmentRef*
4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLayout::getFragmentRef(const LDSection& pInputSection, uint64_t pOffset)
4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // find out which SectionData covers the range of input section header
405cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  const SectionData* sect_data = pInputSection.getSectionData();
4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // check range list
4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == m_SDRangeMap.count(sect_data))
4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (sect_data->getFragmentList().empty())
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RangeList* range_list = m_SDRangeMap[sect_data];
4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // find out the specific part in SectionData range
4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RangeList::iterator range, rangeEnd = range_list->end();
4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (range = range_list->begin(); range != rangeEnd; ++range) {
4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // found the range
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (&pInputSection == range->header) {
4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // range not found
4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (range == rangeEnd) {
427affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    fatal(diag::err_section_not_laid_out) << pInputSection.name();
4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return getFragmentRef(*range, pOffset);
4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getFragmentRef - give a fragment and a big offset, return the fragment
4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// reference in the section data.
4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @param pFrag - the given fragment
4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @param pBigOffset - the offset, can be larger than the fragment, but can
4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///                     not larger than this input section.
4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @return if found, return the fragment. Otherwise, return NULL.
440cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoFragmentRef*
441cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoLayout::getFragmentRef(const Fragment& pFrag, uint64_t pBigOffset)
4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!hasLayoutOffset(pFrag)) {
4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // compute layout order, offset
445cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    setFragmentLayoutOrder(const_cast<Fragment*>(&pFrag));
446cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    setFragmentLayoutOffset(const_cast<Fragment*>(&pFrag));
4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // find out which SectionData covers the range of input section header
450cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  const SectionData* sect_data = pFrag.getParent();
4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // check range list
4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == m_SDRangeMap.count(sect_data)) {
454cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("SectionData has no") +
4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(" correponding range list.\n"));
4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (sect_data->getFragmentList().empty())
4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RangeList* range_list = m_SDRangeMap[sect_data];
4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // find out the specific part in SectionData range
464cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  uint64_t target_offset = pBigOffset + pFrag.getOffset();
4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RangeList::iterator range, rangeEnd = range_list->end();
4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (range = range_list->begin(); range != rangeEnd; ++range) {
4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (isEmptyRange(*range))
4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
470cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    if (getRear(*range)->getOffset() >= target_offset) {
4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      break;
4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // range not found
4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (range == rangeEnd) {
4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("the offset is too big that") +
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(" never be in the range list.\n"));
4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
481affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return getFragmentRef(*range, pBigOffset);
4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
484cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaouint64_t Layout::getOutputOffset(const Fragment& pFrag)
4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!hasLayoutOffset(pFrag)) {
4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // compute layout order, offset
488cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    setFragmentLayoutOrder(const_cast<Fragment*>(&pFrag));
489cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    setFragmentLayoutOffset(const_cast<Fragment*>(&pFrag));
4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
491cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  return pFrag.getOffset();
4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
494cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaouint64_t Layout::getOutputOffset(const Fragment& pFrag) const
4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!hasLayoutOffset(pFrag)) {
4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") +
4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine("the function ") +
4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(__func__) +
5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(" can not be used before layout().\n"));
5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
502cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  return pFrag.getOffset();
5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
505cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaouint64_t Layout::getOutputOffset(const FragmentRef& pFragRef)
5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset();
5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
510cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaouint64_t Layout::getOutputOffset(const FragmentRef& pFragRef) const
5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset();
5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Layout::sortSectionOrder(const Output& pOutput,
516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                              const TargetLDBackend& pBackend,
517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                              const MCLDInfo& pInfo)
5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef std::pair<LDSection*, unsigned int> SectOrder;
5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef std::vector<SectOrder > SectListTy;
5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SectListTy sect_list;
5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // get section order from backend
5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t index = 0; index < m_SectionOrder.size(); ++index)
5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    sect_list.push_back(std::make_pair(
5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                    m_SectionOrder[index],
526affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                    pBackend.getSectionOrder(pOutput, *m_SectionOrder[index], pInfo)));
5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // simple insertion sort should be fine for general cases such as so and exec
5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (unsigned int i = 1; i < sect_list.size(); ++i) {
5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    SectOrder order = sect_list[i];
5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    int j = i - 1;
5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    while (j >= 0 && sect_list[j].second > order.second) {
5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      sect_list[j + 1] = sect_list[j];
5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      --j;
5355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    sect_list[j + 1] = order;
5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // update the sorted ordering to m_SectionOrder
5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_SectionOrder.clear();
5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t index = 0; index < sect_list.size(); ++index) {
5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_SectionOrder.push_back(sect_list[index].first);
5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
546cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// layout - layout the sections
547cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao///   1. finalize fragment offset
548cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao///   2. compute section order
549cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao///   3. finalize section offset
550affc150dc44fab1911775a49636d0ce85333b634Zonr Changbool Layout::layout(Output& pOutput,
551affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                    const TargetLDBackend& pBackend,
552affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                    const MCLDInfo& pInfo)
5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // determine what sections in output context will go into final output, and
5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // push the needed sections into m_SectionOrder for later processing
5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pOutput.hasContext());
5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDContext& output_context = *pOutput.context();
5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDContext::sect_iterator it, itEnd = output_context.sectEnd();
5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (it = output_context.sectBegin(); it != itEnd; ++it) {
560cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    // calculate 1. all fragment offset, and 2. the section order
5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    LDSection* sect = *it;
5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    switch (sect->kind()) {
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // ignore if there is no SectionData for certain section kinds
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Regular:
5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Target:
5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::MetaData:
5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::BSS:
569affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Debug:
570affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::EhFrame:
571affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::GCCExceptTable:
5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (0 != sect->size()) {
5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          if (NULL != sect->getSectionData() &&
5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              !sect->getSectionData()->getFragmentList().empty()) {
5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            // make sure that all fragments are valid
576cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao            Fragment& frag = sect->getSectionData()->getFragmentList().back();
5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            setFragmentLayoutOrder(&frag);
5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            setFragmentLayoutOffset(&frag);
5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          }
5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_SectionOrder.push_back(sect);
5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // take NULL directly
5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Null:
5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_SectionOrder.push_back(sect);
5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // ignore if section size is 0
5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::NamePool:
5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Relocation:
590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Note:
591affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::EhFrameHdr:
5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (0 != sect->size())
5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_SectionOrder.push_back(sect);
5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Group:
5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (MCLDFile::Object == pOutput.type()) {
5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          //TODO: support incremental linking
5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          ;
5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Version:
6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (0 != sect->size()) {
6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          m_SectionOrder.push_back(sect);
604affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          warning(diag::warn_unsupported_symbolic_versioning) << sect->name();
6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      default:
608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (0 != sect->size()) {
609affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          error(diag::err_unsupported_section) << sect->name() << sect->kind();
610affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // perform sorting on m_SectionOrder to get a ordering for final layout
616affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  sortSectionOrder(pOutput, pBackend, pInfo);
6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Backend defines the section start offset for section 1.
6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t offset = pBackend.sectionStartOffset();
620cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t index = 1; index < m_SectionOrder.size(); ++index) {
622cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    // compute the section offset and handle alignment also. And ignore section 0
623cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    // (NULL in ELF/COFF), and MachO starts from section 1.
624cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
625cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    if (LDFileFormat::BSS != m_SectionOrder[index - 1]->kind()) {
626cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      // we should not preserve file space for the BSS section.
6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      offset += m_SectionOrder[index - 1]->size();
628cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    }
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    alignAddress(offset, m_SectionOrder[index]->align());
6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_SectionOrder[index]->setOffset(offset);
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // FIXME: Currently Writer bases on the section table in output context to
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // write out sections, so we have to update its content..
6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  output_context.getSectionTable().clear();
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (size_t index = 0; index < m_SectionOrder.size(); ++index) {
6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_context.getSectionTable().push_back(m_SectionOrder[index]);
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // after sorting, update the correct output section indices
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_SectionOrder[index]->setIndex(index);
6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
645cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool Layout::isValidOffset(const Fragment& pFrag, uint64_t pTargetOffset) const
6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t size = computeFragmentSize(*this, pFrag);
6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0x0 == size)
649cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    return (pTargetOffset == pFrag.getOffset());
6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != pFrag.getNextNode())
652cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    return (pTargetOffset >= pFrag.getOffset() && pTargetOffset < pFrag.getNextNode()->getOffset());
6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
654cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  return (pTargetOffset >= pFrag.getOffset() && pTargetOffset < (pFrag.getOffset() + size));
6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
657