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*>(§_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 §_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