1//===- Layout.cpp ---------------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include <mcld/LD/Layout.h> 11 12#include <cassert> 13 14#include <llvm/ADT/Twine.h> 15 16#include <mcld/ADT/SizeTraits.h> 17#include <mcld/LD/LDContext.h> 18#include <mcld/LD/LDFileFormat.h> 19#include <mcld/LD/LDSection.h> 20#include <mcld/LD/Fragment.h> 21#include <mcld/LD/FillFragment.h> 22#include <mcld/LD/AlignFragment.h> 23#include <mcld/MC/MCLinker.h> 24#include <mcld/MC/MCLDInfo.h> 25#include <mcld/Support/MsgHandling.h> 26#include <mcld/Target/TargetLDBackend.h> 27 28using namespace mcld; 29 30//===----------------------------------------------------------------------===// 31// Range 32//===----------------------------------------------------------------------===// 33Layout::Range::Range() 34 : header(NULL), 35 prevRear(NULL) { 36} 37 38Layout::Range::Range(const LDSection& pHdr) 39 : header(const_cast<LDSection*>(&pHdr)), 40 prevRear(NULL) { 41} 42 43Layout::Range::~Range() 44{ 45} 46 47//===----------------------------------------------------------------------===// 48// Layout 49//===----------------------------------------------------------------------===// 50Layout::Layout() 51 : m_FragRefFactory(32) /** magic number **/ { 52} 53 54Layout::~Layout() 55{ 56} 57 58void Layout::setFragmentLayoutOrder(Fragment* pFrag) 59{ 60 if (NULL == pFrag) 61 return; 62 63 /// find the most-recent fragment whose order was set. 64 Fragment* first = pFrag; 65 while (!hasLayoutOrder(*first)) { 66 if (NULL == first->getPrevNode()) 67 break; 68 first = first->getPrevNode(); 69 } 70 71 /// set all layout order 72 73 // find the first fragment who has no order. 74 // find the last order of the fragment 75 unsigned int layout_order = 0; 76 Fragment* frag_not_set = NULL; 77 if (NULL == first->getPrevNode()) { 78 layout_order = 0; 79 frag_not_set = first; 80 } 81 else { 82 layout_order = first->getLayoutOrder(); 83 frag_not_set = first->getNextNode(); 84 } 85 86 // for all fragments that has no order, set up its order 87 while(NULL != frag_not_set) { 88 frag_not_set->setLayoutOrder(layout_order); 89 ++layout_order; 90 frag_not_set = frag_not_set->getNextNode(); 91 } 92} 93 94/// setFragmentLayoutOffset - set the fragment's layout offset. This function 95/// also set up the layout offsets of all the fragments in the same range. 96/// If the offset of the fragment was set before, return immediately. 97void Layout::setFragmentLayoutOffset(Fragment* pFrag) 98{ 99 if (NULL == pFrag) 100 return; 101 102 // find the most-recent fragment whose offset was set. 103 Fragment* first = pFrag; 104 105 while (!hasLayoutOffset(*first)) { 106 if (NULL == first->getPrevNode()) 107 break; 108 first = first->getPrevNode(); 109 } 110 111 // set all layout order 112 uint64_t offset = 0; 113 Fragment* frag_not_set = NULL; 114 if (NULL == first->getPrevNode()) { 115 offset = 0; 116 frag_not_set = first; 117 } 118 else { 119 offset = first->getOffset(); 120 offset += computeFragmentSize(*this, *first); 121 frag_not_set = first->getNextNode(); 122 } 123 124 while(NULL != frag_not_set) { 125 frag_not_set->setOffset(offset); 126 offset += computeFragmentSize(*this, *frag_not_set); 127 frag_not_set = frag_not_set->getNextNode(); 128 } 129} 130 131/// addInputRange 132/// 1. add a new range <pInputHdr, previous rear fragment> 133/// 2. compute the layout order of all previous ranges. 134/// 2. compute the layout offset of all previous ranges. 135void Layout::addInputRange(const SectionData& pSD, 136 const LDSection& pInputHdr) 137{ 138 RangeList* range_list = NULL; 139 140 // get or create the range_list 141 if (pSD.getFragmentList().empty() || 0 == m_SDRangeMap.count(&pSD)) { 142 range_list = new RangeList(); 143 m_SDRangeMap[&pSD] = range_list; 144 } 145 else { 146 range_list = m_SDRangeMap[&pSD]; 147 } 148 149 // make a range and push it into the range list 150 Range* range = new Range(pInputHdr); 151 range_list->push_back(range); 152 153 // set up previous rear of the range. 154 // FIXME: in current design, we can not add a range before finishing adding 155 // fragments in the previous range. If the limitation keeps, we can set 156 // prevRear to the last fragment in the SectionData simply. 157 // 158 // if the pSD's fragment list is empty, the range.prevRear keeps NULL. 159 if (!pSD.getFragmentList().empty()) { 160 range->prevRear = 161 const_cast<Fragment*>(&pSD.getFragmentList().back()); 162 } 163 164 // compute the layout order of the previous range. 165 if (!isFirstRange(*range)) { 166 setFragmentLayoutOrder(range->prevRear); 167 setFragmentLayoutOffset(range->prevRear); 168 } 169} 170 171/// appendFragment - append the given Fragment to the given SectionData, 172/// and insert a MCAlignFragment to preserve the required align constraint if 173/// needed 174uint64_t Layout::appendFragment(Fragment& pFrag, 175 SectionData& pSD, 176 uint32_t pAlignConstraint) 177{ 178 // insert MCAlignFragment into SectionData first if needed 179 AlignFragment* align_frag = NULL; 180 if (pAlignConstraint > 1) { 181 align_frag = new AlignFragment(pAlignConstraint, // alignment 182 0x0, // the filled value 183 1u, // the size of filled value 184 pAlignConstraint - 1, // max bytes to emit 185 &pSD); 186 } 187 188 // append the fragment to the SectionData 189 pFrag.setParent(&pSD); 190 pSD.getFragmentList().push_back(&pFrag); 191 192 // update the alignment of associated output LDSection if needed 193 LDSection* output_sect = getOutputLDSection(pFrag); 194 assert(NULL != output_sect); 195 if (pAlignConstraint > output_sect->align()) 196 output_sect->setAlign(pAlignConstraint); 197 198 // compute the fragment order and offset 199 setFragmentLayoutOrder(&pFrag); 200 setFragmentLayoutOffset(&pFrag); 201 202 if (NULL != align_frag) 203 return pFrag.getOffset() - align_frag->getOffset() + computeFragmentSize(*this, pFrag); 204 else 205 return computeFragmentSize(*this, pFrag); 206} 207 208/// getInputLDSection - give a Fragment, return the corresponding input 209/// LDSection* 210LDSection* 211Layout::getInputLDSection(const Fragment& pFrag) 212{ 213 const SectionData* sect_data = pFrag.getParent(); 214 // check the SectionData 215 if (NULL == sect_data) { 216 llvm::report_fatal_error(llvm::Twine("the fragment does not belong to") + 217 llvm::Twine(" any SectionData.\n")); 218 } 219 220 // check the SectionData's range list 221 if (0 == m_SDRangeMap.count(sect_data)) { 222 llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") + 223 llvm::Twine("the input's SectionData is not ") + 224 llvm::Twine("registered in the Layout.\nPlease ") + 225 llvm::Twine("use MCLinker::getOrCreateSectData() ") + 226 llvm::Twine("to get input's SectionData.\n")); 227 } 228 229 RangeList* range_list = m_SDRangeMap[sect_data]; 230 // the fragment who has the layout order is not in the last range. 231 if (hasLayoutOrder(pFrag)) { 232 Range range = range_list->back(); 233 if (isFirstRange(range)) { 234 return range.header; 235 } 236 while(range.prevRear->getLayoutOrder() > pFrag.getLayoutOrder()) { 237 if (NULL != range.getPrevNode()) 238 range = *range.getPrevNode(); 239 else 240 return NULL; 241 } 242 return range.header; 243 } 244 // the fragment who has no layout order should be in the last range 245 else { 246 if (range_list->empty()) 247 return NULL; 248 return range_list->back().header; 249 } 250} 251 252/// getInputLDSection - give a Fragment, return the corresponding input 253/// LDSection* 254const LDSection* 255Layout::getInputLDSection(const Fragment& pFrag) const 256{ 257 const SectionData* sect_data = pFrag.getParent(); 258 // check the SectionData 259 if (NULL == sect_data) { 260 llvm::report_fatal_error(llvm::Twine("the fragment does not belong to") + 261 llvm::Twine(" any SectionData.\n")); 262 } 263 264 // check the SectionData's range list 265 if (0 == m_SDRangeMap.count(sect_data)) { 266 llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") + 267 llvm::Twine("the input's SectionData is not ") + 268 llvm::Twine("registered in the Layout.\nPlease ") + 269 llvm::Twine("use MCLinker::getOrCreateSectData() ") + 270 llvm::Twine("to get input's SectionData.\n")); 271 } 272 273 SDRangeMap::const_iterator range_list_iter = m_SDRangeMap.find(sect_data); 274 const RangeList* range_list = range_list_iter->second; 275 // the fragment who has the layout order is not in the last range. 276 if (hasLayoutOrder(pFrag)) { 277 Range range = range_list->back(); 278 if (isFirstRange(range)) { 279 return range.header; 280 } 281 while(range.prevRear->getLayoutOrder() > pFrag.getLayoutOrder()) { 282 if (NULL != range.getPrevNode()) 283 range = *range.getPrevNode(); 284 else 285 return NULL; 286 } 287 return range.header; 288 } 289 // the fragment who has no layout order should be in the last range 290 else { 291 if (range_list->empty()) 292 return NULL; 293 return range_list->back().header; 294 } 295} 296 297/// getOutputLDSection 298LDSection* Layout::getOutputLDSection(const Fragment& pFrag) 299{ 300 SectionData* sect_data = pFrag.getParent(); 301 if (NULL == sect_data) 302 return NULL; 303 304 return const_cast<LDSection*>(§_data->getSection()); 305} 306 307/// getOutputLDSection 308const LDSection* Layout::getOutputLDSection(const Fragment& pFrag) const 309{ 310 const SectionData* sect_data = pFrag.getParent(); 311 if (NULL == sect_data) 312 return NULL; 313 314 return §_data->getSection(); 315} 316 317/// getFragmentRef - assume the ragne exist, find the fragment reference 318FragmentRef* Layout::getFragmentRef(Layout::Range& pRange, uint64_t pOffset) 319{ 320 if (isEmptyRange(pRange)) 321 return NULL; 322 323 Fragment* front = getFront(pRange); 324 if (NULL == front) 325 return NULL; 326 327 Fragment* rear = getRear(pRange); 328 if (NULL == rear) 329 return NULL; 330 331 return getFragmentRef(*front, *rear, pOffset); 332} 333 334// @param pFront is the first fragment in the range. 335// @param pRear is the last fragment in the range. 336// @pOffset is the offset started from pFront. 337FragmentRef* 338Layout::getFragmentRef(Fragment& pFront, Fragment& pRear, uint64_t pOffset) 339{ 340 Fragment* front = &pFront; 341 Fragment* rear = &pRear; 342 343 if (!hasLayoutOffset(*rear)) { 344 // compute layout order, offset 345 setFragmentLayoutOrder(rear); 346 setFragmentLayoutOffset(rear); 347 } 348 349 // compute the offset from overall start fragment. 350 uint64_t target_offset = pFront.getOffset() + pOffset; 351 352 // from front to rear, find the offset which is as large as possible 353 // but smaller than the target_offset. 354 while (front != rear) { 355 if (Fragment::Alignment == front->getKind()) { 356 // alignment fragments were not counted in target_offset. 357 // Count in the size of alignment fragmen in target_offset here. 358 uint64_t align_size = 0x0; 359 if (NULL == front->getNextNode()) { 360 // If the alignment fragment is the last fragment, increase 361 // the target_offset by the alignment fragment's size. 362 align_size = computeFragmentSize(*this, *front); 363 } 364 else { 365 // If the alignment fragment is not the last fragment, the alignment 366 // fragment's size is the distance between the two fragment. 367 align_size = front->getNextNode()->getOffset() - front->getOffset(); 368 } 369 target_offset += align_size; 370 front = front->getNextNode(); 371 continue; 372 } 373 374 if (target_offset >= front->getNextNode()->getOffset()) { 375 front = front->getNextNode(); 376 } 377 else { 378 // found 379 FragmentRef* result = m_FragRefFactory.allocate(); 380 new (result) FragmentRef(*front, target_offset - front->getOffset()); 381 return result; 382 } 383 } 384 385 if (front == rear) { 386 if (Fragment::Alignment == front->getKind()) 387 return NULL; 388 389 if (!isValidOffset(*front, target_offset)) 390 return NULL; 391 392 FragmentRef* result = m_FragRefFactory.allocate(); 393 new (result) FragmentRef(*front, target_offset - front->getOffset()); 394 return result; 395 } 396 return NULL; 397} 398 399/// getFragmentRef - give a LDSection in input file and an offset, return 400/// the fragment reference. 401FragmentRef* 402Layout::getFragmentRef(const LDSection& pInputSection, uint64_t pOffset) 403{ 404 // find out which SectionData covers the range of input section header 405 const SectionData* sect_data = pInputSection.getSectionData(); 406 407 // check range list 408 if (0 == m_SDRangeMap.count(sect_data)) 409 return NULL; 410 411 if (sect_data->getFragmentList().empty()) 412 return NULL; 413 414 RangeList* range_list = m_SDRangeMap[sect_data]; 415 416 // find out the specific part in SectionData range 417 RangeList::iterator range, rangeEnd = range_list->end(); 418 for (range = range_list->begin(); range != rangeEnd; ++range) { 419 // found the range 420 if (&pInputSection == range->header) { 421 break; 422 } 423 } 424 425 // range not found 426 if (range == rangeEnd) { 427 fatal(diag::err_section_not_laid_out) << pInputSection.name(); 428 } 429 430 return getFragmentRef(*range, pOffset); 431} 432 433/// getFragmentRef - give a fragment and a big offset, return the fragment 434/// reference in the section data. 435/// 436/// @param pFrag - the given fragment 437/// @param pBigOffset - the offset, can be larger than the fragment, but can 438/// not larger than this input section. 439/// @return if found, return the fragment. Otherwise, return NULL. 440FragmentRef* 441Layout::getFragmentRef(const Fragment& pFrag, uint64_t pBigOffset) 442{ 443 if (!hasLayoutOffset(pFrag)) { 444 // compute layout order, offset 445 setFragmentLayoutOrder(const_cast<Fragment*>(&pFrag)); 446 setFragmentLayoutOffset(const_cast<Fragment*>(&pFrag)); 447 } 448 449 // find out which SectionData covers the range of input section header 450 const SectionData* sect_data = pFrag.getParent(); 451 452 // check range list 453 if (0 == m_SDRangeMap.count(sect_data)) { 454 llvm::report_fatal_error(llvm::Twine("SectionData has no") + 455 llvm::Twine(" correponding range list.\n")); 456 } 457 458 if (sect_data->getFragmentList().empty()) 459 return NULL; 460 461 RangeList* range_list = m_SDRangeMap[sect_data]; 462 463 // find out the specific part in SectionData range 464 uint64_t target_offset = pBigOffset + pFrag.getOffset(); 465 466 RangeList::iterator range, rangeEnd = range_list->end(); 467 for (range = range_list->begin(); range != rangeEnd; ++range) { 468 if (isEmptyRange(*range)) 469 continue; 470 if (getRear(*range)->getOffset() >= target_offset) { 471 break; 472 } 473 } 474 475 // range not found 476 if (range == rangeEnd) { 477 llvm::report_fatal_error(llvm::Twine("the offset is too big that") + 478 llvm::Twine(" never be in the range list.\n")); 479 } 480 481 return getFragmentRef(*range, pBigOffset); 482} 483 484uint64_t Layout::getOutputOffset(const Fragment& pFrag) 485{ 486 if (!hasLayoutOffset(pFrag)) { 487 // compute layout order, offset 488 setFragmentLayoutOrder(const_cast<Fragment*>(&pFrag)); 489 setFragmentLayoutOffset(const_cast<Fragment*>(&pFrag)); 490 } 491 return pFrag.getOffset(); 492} 493 494uint64_t Layout::getOutputOffset(const Fragment& pFrag) const 495{ 496 if (!hasLayoutOffset(pFrag)) { 497 llvm::report_fatal_error(llvm::Twine("INTERNAL BACKEND ERROR: ") + 498 llvm::Twine("the function ") + 499 llvm::Twine(__func__) + 500 llvm::Twine(" can not be used before layout().\n")); 501 } 502 return pFrag.getOffset(); 503} 504 505uint64_t Layout::getOutputOffset(const FragmentRef& pFragRef) 506{ 507 return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset(); 508} 509 510uint64_t Layout::getOutputOffset(const FragmentRef& pFragRef) const 511{ 512 return getOutputOffset(*(pFragRef.frag())) + pFragRef.offset(); 513} 514 515void Layout::sortSectionOrder(const Output& pOutput, 516 const TargetLDBackend& pBackend, 517 const MCLDInfo& pInfo) 518{ 519 typedef std::pair<LDSection*, unsigned int> SectOrder; 520 typedef std::vector<SectOrder > SectListTy; 521 SectListTy sect_list; 522 // get section order from backend 523 for (size_t index = 0; index < m_SectionOrder.size(); ++index) 524 sect_list.push_back(std::make_pair( 525 m_SectionOrder[index], 526 pBackend.getSectionOrder(pOutput, *m_SectionOrder[index], pInfo))); 527 528 // simple insertion sort should be fine for general cases such as so and exec 529 for (unsigned int i = 1; i < sect_list.size(); ++i) { 530 SectOrder order = sect_list[i]; 531 int j = i - 1; 532 while (j >= 0 && sect_list[j].second > order.second) { 533 sect_list[j + 1] = sect_list[j]; 534 --j; 535 } 536 sect_list[j + 1] = order; 537 } 538 539 // update the sorted ordering to m_SectionOrder 540 m_SectionOrder.clear(); 541 for (size_t index = 0; index < sect_list.size(); ++index) { 542 m_SectionOrder.push_back(sect_list[index].first); 543 } 544} 545 546/// layout - layout the sections 547/// 1. finalize fragment offset 548/// 2. compute section order 549/// 3. finalize section offset 550bool Layout::layout(Output& pOutput, 551 const TargetLDBackend& pBackend, 552 const MCLDInfo& pInfo) 553{ 554 // determine what sections in output context will go into final output, and 555 // push the needed sections into m_SectionOrder for later processing 556 assert(pOutput.hasContext()); 557 LDContext& output_context = *pOutput.context(); 558 LDContext::sect_iterator it, itEnd = output_context.sectEnd(); 559 for (it = output_context.sectBegin(); it != itEnd; ++it) { 560 // calculate 1. all fragment offset, and 2. the section order 561 LDSection* sect = *it; 562 563 switch (sect->kind()) { 564 // ignore if there is no SectionData for certain section kinds 565 case LDFileFormat::Regular: 566 case LDFileFormat::Target: 567 case LDFileFormat::MetaData: 568 case LDFileFormat::BSS: 569 case LDFileFormat::Debug: 570 case LDFileFormat::EhFrame: 571 case LDFileFormat::GCCExceptTable: 572 if (0 != sect->size()) { 573 if (NULL != sect->getSectionData() && 574 !sect->getSectionData()->getFragmentList().empty()) { 575 // make sure that all fragments are valid 576 Fragment& frag = sect->getSectionData()->getFragmentList().back(); 577 setFragmentLayoutOrder(&frag); 578 setFragmentLayoutOffset(&frag); 579 } 580 m_SectionOrder.push_back(sect); 581 } 582 break; 583 // take NULL directly 584 case LDFileFormat::Null: 585 m_SectionOrder.push_back(sect); 586 break; 587 // ignore if section size is 0 588 case LDFileFormat::NamePool: 589 case LDFileFormat::Relocation: 590 case LDFileFormat::Note: 591 case LDFileFormat::EhFrameHdr: 592 if (0 != sect->size()) 593 m_SectionOrder.push_back(sect); 594 break; 595 case LDFileFormat::Group: 596 if (MCLDFile::Object == pOutput.type()) { 597 //TODO: support incremental linking 598 ; 599 } 600 break; 601 case LDFileFormat::Version: 602 if (0 != sect->size()) { 603 m_SectionOrder.push_back(sect); 604 warning(diag::warn_unsupported_symbolic_versioning) << sect->name(); 605 } 606 break; 607 default: 608 if (0 != sect->size()) { 609 error(diag::err_unsupported_section) << sect->name() << sect->kind(); 610 } 611 break; 612 } 613 } 614 615 // perform sorting on m_SectionOrder to get a ordering for final layout 616 sortSectionOrder(pOutput, pBackend, pInfo); 617 618 // Backend defines the section start offset for section 1. 619 uint64_t offset = pBackend.sectionStartOffset(); 620 621 for (size_t index = 1; index < m_SectionOrder.size(); ++index) { 622 // compute the section offset and handle alignment also. And ignore section 0 623 // (NULL in ELF/COFF), and MachO starts from section 1. 624 625 if (LDFileFormat::BSS != m_SectionOrder[index - 1]->kind()) { 626 // we should not preserve file space for the BSS section. 627 offset += m_SectionOrder[index - 1]->size(); 628 } 629 630 alignAddress(offset, m_SectionOrder[index]->align()); 631 m_SectionOrder[index]->setOffset(offset); 632 } 633 634 // FIXME: Currently Writer bases on the section table in output context to 635 // write out sections, so we have to update its content.. 636 output_context.getSectionTable().clear(); 637 for (size_t index = 0; index < m_SectionOrder.size(); ++index) { 638 output_context.getSectionTable().push_back(m_SectionOrder[index]); 639 // after sorting, update the correct output section indices 640 m_SectionOrder[index]->setIndex(index); 641 } 642 return true; 643} 644 645bool Layout::isValidOffset(const Fragment& pFrag, uint64_t pTargetOffset) const 646{ 647 uint64_t size = computeFragmentSize(*this, pFrag); 648 if (0x0 == size) 649 return (pTargetOffset == pFrag.getOffset()); 650 651 if (NULL != pFrag.getNextNode()) 652 return (pTargetOffset >= pFrag.getOffset() && pTargetOffset < pFrag.getNextNode()->getOffset()); 653 654 return (pTargetOffset >= pFrag.getOffset() && pTargetOffset < (pFrag.getOffset() + size)); 655} 656 657