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