1//===- MCLinker.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// This file implements the MCLinker class 11// 12//===----------------------------------------------------------------------===// 13#include <mcld/MC/MCLinker.h> 14 15#include <llvm/Support/Host.h> 16#include <llvm/Support/raw_ostream.h> 17 18#include <mcld/MC/MCLDInput.h> 19#include <mcld/MC/MCLDInfo.h> 20#include <mcld/LD/Resolver.h> 21#include <mcld/LD/LDContext.h> 22#include <mcld/LD/LDSymbol.h> 23#include <mcld/LD/LDSectionFactory.h> 24#include <mcld/LD/SectionMap.h> 25#include <mcld/LD/RelocationFactory.h> 26#include <mcld/LD/FillFragment.h> 27#include <mcld/LD/RegionFragment.h> 28#include <mcld/LD/EhFrame.h> 29#include <mcld/LD/EhFrameHdr.h> 30#include <mcld/Support/MemoryRegion.h> 31#include <mcld/Support/MsgHandling.h> 32#include <mcld/Target/TargetLDBackend.h> 33 34using namespace mcld; 35 36/// Constructor 37MCLinker::MCLinker(TargetLDBackend& pBackend, 38 MCLDInfo& pInfo, 39 SectionMap& pSectionMap) 40: m_Backend(pBackend), 41 m_LDInfo(pInfo), 42 m_SectionMap(pSectionMap), 43 m_LDSymbolFactory(128), 44 m_LDSectHdrFactory(10), // the average number of sections. (assuming 10.) 45 m_LDSectDataFactory(10), 46 m_pSectionMerger(NULL) 47{ 48} 49 50/// Destructor 51MCLinker::~MCLinker() 52{ 53 if (NULL != m_pSectionMerger) 54 delete m_pSectionMerger; 55} 56 57//===----------------------------------------------------------------------===// 58// Symbol Operations 59//===----------------------------------------------------------------------===// 60/// addSymbolFromObject - add a symbol from object file and resolve it 61/// immediately 62LDSymbol* MCLinker::addSymbolFromObject(const llvm::StringRef& pName, 63 ResolveInfo::Type pType, 64 ResolveInfo::Desc pDesc, 65 ResolveInfo::Binding pBinding, 66 ResolveInfo::SizeType pSize, 67 LDSymbol::ValueType pValue, 68 FragmentRef* pFragmentRef, 69 ResolveInfo::Visibility pVisibility) 70{ 71 72 // resolved_result is a triple <resolved_info, existent, override> 73 Resolver::Result resolved_result; 74 ResolveInfo old_info; // used for arrange output symbols 75 76 if (pBinding == ResolveInfo::Local) { 77 // if the symbol is a local symbol, create a LDSymbol for input, but do not 78 // resolve them. 79 resolved_result.info = m_LDInfo.getNamePool().createSymbol(pName, 80 false, 81 pType, 82 pDesc, 83 pBinding, 84 pSize, 85 pVisibility); 86 87 // No matter if there is a symbol with the same name, insert the symbol 88 // into output symbol table. So, we let the existent false. 89 resolved_result.existent = false; 90 resolved_result.overriden = true; 91 } 92 else { 93 // if the symbol is not local, insert and resolve it immediately 94 m_LDInfo.getNamePool().insertSymbol(pName, false, pType, pDesc, pBinding, 95 pSize, pVisibility, 96 &old_info, resolved_result); 97 } 98 99 // the return ResolveInfo should not NULL 100 assert(NULL != resolved_result.info); 101 102 // create a LDSymbol for the input file. 103 LDSymbol* input_sym = m_LDSymbolFactory.allocate(); 104 new (input_sym) LDSymbol(); 105 106 // set the relation between input LDSymbol and its ResolveInfo 107 input_sym->setResolveInfo(*resolved_result.info); 108 109 // set up input LDSymbol 110 input_sym->setFragmentRef(pFragmentRef); 111 input_sym->setValue(pValue); 112 113 LDSymbol* output_sym = resolved_result.info->outSymbol(); 114 bool has_output_sym = (NULL != output_sym); 115 if (!resolved_result.existent || !has_output_sym) { 116 // it is a new symbol, the output_sym should be NULL. 117 assert(NULL == output_sym); 118 119 // if it is a new symbol, create a LDSymbol for the output 120 output_sym = m_LDSymbolFactory.allocate(); 121 new (output_sym) LDSymbol(); 122 123 // set up the relation between output LDSymbol and its ResolveInfo 124 output_sym->setResolveInfo(*resolved_result.info); 125 resolved_result.info->setSymPtr(output_sym); 126 } 127 128 if (resolved_result.overriden || !has_output_sym) { 129 // symbol can be overriden only if it exists. 130 assert(output_sym != NULL); 131 132 // should override output LDSymbol 133 output_sym->setFragmentRef(pFragmentRef); 134 output_sym->setValue(pValue); 135 } 136 137 // After symbol resolution, visibility is changed to the most restrict one. 138 // we need to arrange its position in the output symbol . 139 if (pType != ResolveInfo::Section) { 140 if (!has_output_sym) { 141 // We merge sections when reading them. So we do not need to output symbols 142 // with section type 143 144 // No matter the symbol is already in the output or not, add it if it 145 // should be forcefully set local. 146 if (shouldForceLocal(*resolved_result.info)) 147 m_OutputSymbols.forceLocal(*output_sym); 148 else { 149 // the symbol should not be forcefully local. 150 m_OutputSymbols.add(*output_sym); 151 } 152 } 153 else if (resolved_result.overriden) { 154 if (!shouldForceLocal(old_info) || 155 !shouldForceLocal(*resolved_result.info)) { 156 // If the old info and the new info are both forcefully local, then 157 // we should keep the output_sym in forcefully local category. Else, 158 // we should re-sort the output_sym 159 m_OutputSymbols.arrange(*output_sym, old_info); 160 } 161 } 162 } 163 164 return input_sym; 165} 166 167/// addSymbolFromDynObj - add a symbol from object file and resolve it 168/// immediately 169LDSymbol* MCLinker::addSymbolFromDynObj(const llvm::StringRef& pName, 170 ResolveInfo::Type pType, 171 ResolveInfo::Desc pDesc, 172 ResolveInfo::Binding pBinding, 173 ResolveInfo::SizeType pSize, 174 LDSymbol::ValueType pValue, 175 FragmentRef* pFragmentRef, 176 ResolveInfo::Visibility pVisibility) 177{ 178 // We merge sections when reading them. So we do not need symbols with 179 // section type 180 if (pType == ResolveInfo::Section) 181 return NULL; 182 183 // ignore symbols with local binding or that have internal or hidden 184 // visibility 185 if (pBinding == ResolveInfo::Local || 186 pVisibility == ResolveInfo::Internal || 187 pVisibility == ResolveInfo::Hidden) 188 return NULL; 189 190 // A protected symbol in a shared library must be treated as a 191 // normal symbol when viewed from outside the shared library. 192 if (pVisibility == ResolveInfo::Protected) 193 pVisibility = ResolveInfo::Default; 194 195 // insert symbol and resolve it immediately 196 // resolved_result is a triple <resolved_info, existent, override> 197 Resolver::Result resolved_result; 198 m_LDInfo.getNamePool().insertSymbol(pName, true, pType, pDesc, 199 pBinding, pSize, pVisibility, 200 NULL, resolved_result); 201 202 // the return ResolveInfo should not NULL 203 assert(NULL != resolved_result.info); 204 205 // create a LDSymbol for the input file. 206 LDSymbol* input_sym = m_LDSymbolFactory.allocate(); 207 new (input_sym) LDSymbol(); 208 209 // set up the relation between input LDSymbol and its ResolveInfo 210 input_sym->setResolveInfo(*resolved_result.info); 211 212 // set up input LDSymbol 213 input_sym->setFragmentRef(pFragmentRef); 214 input_sym->setValue(pValue); 215 216 LDSymbol* output_sym = NULL; 217 if (!resolved_result.existent) { 218 // we get a new symbol, leave it as NULL 219 resolved_result.info->setSymPtr(NULL); 220 } 221 else { 222 // we saw the symbol before, but the output_sym still may be NULL. 223 output_sym = resolved_result.info->outSymbol(); 224 } 225 226 if (output_sym != NULL) { 227 // After symbol resolution, visibility is changed to the most restrict one. 228 // If we are not doing incremental linking, then any symbol with hidden 229 // or internal visibility is forcefully set as a local symbol. 230 if (shouldForceLocal(*resolved_result.info)) { 231 m_OutputSymbols.forceLocal(*output_sym); 232 } 233 } 234 235 return input_sym; 236} 237 238/// defineSymbolForcefully - define an output symbol and override it immediately 239LDSymbol* MCLinker::defineSymbolForcefully(const llvm::StringRef& pName, 240 bool pIsDyn, 241 ResolveInfo::Type pType, 242 ResolveInfo::Desc pDesc, 243 ResolveInfo::Binding pBinding, 244 ResolveInfo::SizeType pSize, 245 LDSymbol::ValueType pValue, 246 FragmentRef* pFragmentRef, 247 ResolveInfo::Visibility pVisibility) 248{ 249 ResolveInfo* info = m_LDInfo.getNamePool().findInfo(pName); 250 LDSymbol* output_sym = NULL; 251 if (NULL == info) { 252 // the symbol is not in the pool, create a new one. 253 // create a ResolveInfo 254 Resolver::Result result; 255 m_LDInfo.getNamePool().insertSymbol(pName, pIsDyn, pType, pDesc, 256 pBinding, pSize, pVisibility, 257 NULL, result); 258 assert(!result.existent); 259 260 // create a output LDSymbol 261 output_sym = m_LDSymbolFactory.allocate(); 262 new (output_sym) LDSymbol(); 263 264 output_sym->setResolveInfo(*result.info); 265 result.info->setSymPtr(output_sym); 266 267 if (shouldForceLocal(*result.info)) 268 m_OutputSymbols.forceLocal(*output_sym); 269 else 270 m_OutputSymbols.add(*output_sym); 271 } 272 else { 273 // the symbol is already in the pool, override it 274 ResolveInfo old_info; 275 old_info.override(*info); 276 277 info->setSource(pIsDyn); 278 info->setType(pType); 279 info->setDesc(pDesc); 280 info->setBinding(pBinding); 281 info->setVisibility(pVisibility); 282 info->setIsSymbol(true); 283 info->setSize(pSize); 284 285 output_sym = info->outSymbol(); 286 if (NULL != output_sym) 287 m_OutputSymbols.arrange(*output_sym, old_info); 288 else { 289 // create a output LDSymbol 290 output_sym = m_LDSymbolFactory.allocate(); 291 new (output_sym) LDSymbol(); 292 293 output_sym->setResolveInfo(*info); 294 info->setSymPtr(output_sym); 295 296 m_OutputSymbols.add(*output_sym); 297 } 298 } 299 300 if (NULL != output_sym) { 301 output_sym->setFragmentRef(pFragmentRef); 302 output_sym->setValue(pValue); 303 } 304 305 return output_sym; 306} 307 308/// defineSymbolAsRefered - define an output symbol and override it immediately 309LDSymbol* MCLinker::defineSymbolAsRefered(const llvm::StringRef& pName, 310 bool pIsDyn, 311 ResolveInfo::Type pType, 312 ResolveInfo::Desc pDesc, 313 ResolveInfo::Binding pBinding, 314 ResolveInfo::SizeType pSize, 315 LDSymbol::ValueType pValue, 316 FragmentRef* pFragmentRef, 317 ResolveInfo::Visibility pVisibility) 318{ 319 ResolveInfo* info = m_LDInfo.getNamePool().findInfo(pName); 320 321 if (NULL == info || !(info->isUndef() || info->isDyn())) { 322 // only undefined symbol and dynamic symbol can make a reference. 323 return NULL; 324 } 325 326 // the symbol is already in the pool, override it 327 ResolveInfo old_info; 328 old_info.override(*info); 329 330 info->setSource(pIsDyn); 331 info->setType(pType); 332 info->setDesc(pDesc); 333 info->setBinding(pBinding); 334 info->setVisibility(pVisibility); 335 info->setIsSymbol(true); 336 info->setSize(pSize); 337 338 LDSymbol* output_sym = info->outSymbol(); 339 if (NULL != output_sym) { 340 output_sym->setFragmentRef(pFragmentRef); 341 output_sym->setValue(pValue); 342 m_OutputSymbols.arrange(*output_sym, old_info); 343 } 344 else { 345 // create a output LDSymbol 346 output_sym = m_LDSymbolFactory.allocate(); 347 new (output_sym) LDSymbol(); 348 349 output_sym->setResolveInfo(*info); 350 info->setSymPtr(output_sym); 351 352 m_OutputSymbols.add(*output_sym); 353 } 354 355 return output_sym; 356} 357 358/// defineAndResolveSymbolForcefully - define an output symbol and resolve it 359/// immediately 360LDSymbol* MCLinker::defineAndResolveSymbolForcefully(const llvm::StringRef& pName, 361 bool pIsDyn, 362 ResolveInfo::Type pType, 363 ResolveInfo::Desc pDesc, 364 ResolveInfo::Binding pBinding, 365 ResolveInfo::SizeType pSize, 366 LDSymbol::ValueType pValue, 367 FragmentRef* pFragmentRef, 368 ResolveInfo::Visibility pVisibility) 369{ 370 // Result is <info, existent, override> 371 Resolver::Result result; 372 ResolveInfo old_info; 373 m_LDInfo.getNamePool().insertSymbol(pName, pIsDyn, pType, pDesc, pBinding, 374 pSize, pVisibility, 375 &old_info, result); 376 377 LDSymbol* output_sym = result.info->outSymbol(); 378 bool has_output_sym = (NULL != output_sym); 379 380 if (!result.existent || !has_output_sym) { 381 output_sym = m_LDSymbolFactory.allocate(); 382 new (output_sym) LDSymbol(); 383 output_sym->setResolveInfo(*result.info); 384 result.info->setSymPtr(output_sym); 385 } 386 387 if (result.overriden || !has_output_sym) { 388 output_sym->setFragmentRef(pFragmentRef); 389 output_sym->setValue(pValue); 390 } 391 392 // After symbol resolution, the visibility is changed to the most restrict. 393 // arrange the output position 394 if (shouldForceLocal(*result.info)) 395 m_OutputSymbols.forceLocal(*output_sym); 396 else if (has_output_sym) 397 m_OutputSymbols.arrange(*output_sym, old_info); 398 else 399 m_OutputSymbols.add(*output_sym); 400 401 return output_sym; 402} 403 404/// defineAndResolveSymbolAsRefered - define an output symbol and resolve it 405/// immediately. 406LDSymbol* MCLinker::defineAndResolveSymbolAsRefered(const llvm::StringRef& pName, 407 bool pIsDyn, 408 ResolveInfo::Type pType, 409 ResolveInfo::Desc pDesc, 410 ResolveInfo::Binding pBinding, 411 ResolveInfo::SizeType pSize, 412 LDSymbol::ValueType pValue, 413 FragmentRef* pFragmentRef, 414 ResolveInfo::Visibility pVisibility) 415{ 416 ResolveInfo* info = m_LDInfo.getNamePool().findInfo(pName); 417 418 if (NULL == info || !(info->isUndef() || info->isDyn())) { 419 // only undefined symbol and dynamic symbol can make a reference. 420 return NULL; 421 } 422 423 return defineAndResolveSymbolForcefully(pName, 424 pIsDyn, 425 pType, 426 pDesc, 427 pBinding, 428 pSize, 429 pValue, 430 pFragmentRef, 431 pVisibility); 432} 433 434bool MCLinker::finalizeSymbols() 435{ 436 SymbolCategory::iterator symbol, symEnd = m_OutputSymbols.end(); 437 for (symbol = m_OutputSymbols.begin(); symbol != symEnd; ++symbol) { 438 439 if ((*symbol)->resolveInfo()->isAbsolute() || 440 (*symbol)->resolveInfo()->type() == ResolveInfo::File) { 441 // absolute symbols or symbols with function type should have 442 // zero value 443 (*symbol)->setValue(0x0); 444 continue; 445 } 446 447 if ((*symbol)->hasFragRef()) { 448 // set the virtual address of the symbol. If the output file is 449 // relocatable object file, the section's virtual address becomes zero. 450 // And the symbol's value become section relative offset. 451 uint64_t value = getLayout().getOutputOffset(*(*symbol)->fragRef()); 452 assert(NULL != (*symbol)->fragRef()->frag()); 453 uint64_t addr = getLayout().getOutputLDSection(*(*symbol)->fragRef()->frag())->addr(); 454 (*symbol)->setValue(value + addr); 455 continue; 456 } 457 } 458 459 // finialize target-dependent symbols 460 return m_Backend.finalizeSymbols(*this, m_LDInfo.output()); 461} 462 463bool MCLinker::shouldForceLocal(const ResolveInfo& pInfo) const 464{ 465 // forced local symbol matches all rules: 466 // 1. We are not doing incremental linking. 467 // 2. The symbol is with Hidden or Internal visibility. 468 // 3. The symbol should be global or weak. Otherwise, local symbol is local. 469 // 4. The symbol is defined or common 470 if (m_LDInfo.output().type() != Output::Object && 471 (pInfo.visibility() == ResolveInfo::Hidden || 472 pInfo.visibility() == ResolveInfo::Internal) && 473 (pInfo.isGlobal() || pInfo.isWeak()) && 474 (pInfo.isDefine() || pInfo.isCommon())) 475 return true; 476 return false; 477} 478 479//===----------------------------------------------------------------------===// 480// Section Operations 481//===----------------------------------------------------------------------===// 482/// createSectHdr - create the input section header 483LDSection& MCLinker::createSectHdr(const std::string& pName, 484 LDFileFormat::Kind pKind, 485 uint32_t pType, 486 uint32_t pFlag) 487{ 488 assert(m_LDInfo.output().hasContext()); 489 490 // for user such as reader, standard/target fromat 491 LDSection* result = 492 m_LDSectHdrFactory.produce(pName, pKind, pType, pFlag); 493 494 // check if we need to create a output section for output LDContext 495 std::string sect_name = m_SectionMap.getOutputSectName(pName); 496 LDSection* output_sect = m_LDInfo.output().context()->getSection(sect_name); 497 498 if (NULL == output_sect) { 499 // create a output section and push it into output LDContext 500 output_sect = 501 m_LDSectHdrFactory.produce(sect_name, pKind, pType, pFlag); 502 m_LDInfo.output().context()->getSectionTable().push_back(output_sect); 503 m_pSectionMerger->addMapping(pName, output_sect); 504 } 505 return *result; 506} 507 508/// getOrCreateOutputSectHdr - for reader and standard/target format to get 509/// or create the output's section header 510LDSection& MCLinker::getOrCreateOutputSectHdr(const std::string& pName, 511 LDFileFormat::Kind pKind, 512 uint32_t pType, 513 uint32_t pFlag, 514 uint32_t pAlign) 515{ 516 assert(m_LDInfo.output().hasContext()); 517 518 // check if we need to create a output section for output LDContext 519 std::string sect_name = m_SectionMap.getOutputSectName(pName); 520 LDSection* output_sect = m_LDInfo.output().context()->getSection(sect_name); 521 522 if (NULL == output_sect) { 523 // create a output section and push it into output LDContext 524 output_sect = 525 m_LDSectHdrFactory.produce(sect_name, pKind, pType, pFlag); 526 output_sect->setAlign(pAlign); 527 m_LDInfo.output().context()->getSectionTable().push_back(output_sect); 528 m_pSectionMerger->addMapping(pName, output_sect); 529 } 530 return *output_sect; 531} 532 533/// getOrCreateSectData - get or create SectionData 534/// pSection is input LDSection 535SectionData& MCLinker::getOrCreateSectData(LDSection& pSection) 536{ 537 // if there is already a section data pointed by section, return it. 538 SectionData* sect_data = pSection.getSectionData(); 539 if (NULL != sect_data) { 540 m_Layout.addInputRange(*sect_data, pSection); 541 return *sect_data; 542 } 543 544 // try to get one from output LDSection 545 LDSection* output_sect = 546 m_pSectionMerger->getOutputSectHdr(pSection.name()); 547 548 assert(NULL != output_sect); 549 550 sect_data = output_sect->getSectionData(); 551 552 if (NULL != sect_data) { 553 pSection.setSectionData(sect_data); 554 m_Layout.addInputRange(*sect_data, pSection); 555 return *sect_data; 556 } 557 558 // if the output LDSection also has no SectionData, then create one. 559 sect_data = m_LDSectDataFactory.allocate(); 560 new (sect_data) SectionData(*output_sect); 561 pSection.setSectionData(sect_data); 562 output_sect->setSectionData(sect_data); 563 m_Layout.addInputRange(*sect_data, pSection); 564 return *sect_data; 565} 566 567void MCLinker::initSectionMap() 568{ 569 assert(m_LDInfo.output().hasContext()); 570 if (NULL == m_pSectionMerger) 571 m_pSectionMerger = new SectionMerger(m_SectionMap, *m_LDInfo.output().context()); 572} 573 574bool MCLinker::layout() 575{ 576 return m_Layout.layout(m_LDInfo.output(), m_Backend, m_LDInfo); 577} 578 579//===----------------------------------------------------------------------===// 580// Relocation Operations 581//===----------------------------------------------------------------------===// 582/// addRelocation - add a relocation entry in MCLinker (only for object file) 583/// 584/// All symbols should be read and resolved before calling this function. 585Relocation* MCLinker::addRelocation(Relocation::Type pType, 586 const LDSymbol& pSym, 587 ResolveInfo& pResolveInfo, 588 FragmentRef& pFragmentRef, 589 const LDSection& pSection, 590 Relocation::Address pAddend) 591{ 592 // FIXME: we should dicard sections and symbols first instead 593 // if the symbol is in the discarded input section, then we also need to 594 // discard this relocation. 595 if (pSym.fragRef() == NULL && 596 pResolveInfo.type() == ResolveInfo::Section && 597 pResolveInfo.desc() == ResolveInfo::Undefined) 598 return NULL; 599 600 Relocation* relocation = m_Backend.getRelocFactory()->produce(pType, 601 pFragmentRef, 602 pAddend); 603 604 relocation->setSymInfo(&pResolveInfo); 605 606 m_RelocationList.push_back(relocation); 607 608 m_Backend.scanRelocation(*relocation, pSym, *this, m_LDInfo, 609 m_LDInfo.output(), pSection); 610 611 if (pResolveInfo.isUndef() && !pResolveInfo.isDyn() && !pResolveInfo.isWeak()) 612 fatal(diag::undefined_reference) << pResolveInfo.name(); 613 return relocation; 614} 615 616bool MCLinker::applyRelocations() 617{ 618 RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end(); 619 620 for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) { 621 Fragment* frag = (Fragment*)relocIter; 622 static_cast<Relocation*>(frag)->apply(*m_Backend.getRelocFactory(), m_LDInfo); 623 } 624 return true; 625} 626 627void MCLinker::syncRelocationResult() 628{ 629 630 MemoryRegion* region = m_LDInfo.output().memArea()->request(0, 631 m_LDInfo.output().memArea()->handler()->size()); 632 633 uint8_t* data = region->getBuffer(); 634 635 RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end(); 636 for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) { 637 638 Fragment* frag = (Fragment*)relocIter; 639 Relocation* reloc = static_cast<Relocation*>(frag); 640 641 // get output file offset 642 size_t out_offset = m_Layout.getOutputLDSection(*reloc->targetRef().frag())->offset() + 643 m_Layout.getOutputOffset(reloc->targetRef()); 644 645 uint8_t* target_addr = data + out_offset; 646 // byte swapping if target and host has different endian, and then write back 647 if(llvm::sys::isLittleEndianHost() != m_Backend.isLittleEndian()) { 648 uint64_t tmp_data = 0; 649 650 switch(m_Backend.bitclass()) { 651 case 32u: 652 tmp_data = bswap32(reloc->target()); 653 std::memcpy(target_addr, &tmp_data, 4); 654 break; 655 656 case 64u: 657 tmp_data = bswap64(reloc->target()); 658 std::memcpy(target_addr, &tmp_data, 8); 659 break; 660 661 default: 662 break; 663 } 664 } 665 else { 666 std::memcpy(target_addr, &reloc->target(), m_Backend.bitclass()/8); 667 } 668 } // end of for 669 670 m_LDInfo.output().memArea()->clear(); 671} 672 673//===----------------------------------------------------------------------===// 674// Exception Handling Operations 675//===----------------------------------------------------------------------===// 676/// addEhFrame - add an exception handling section 677/// @param pSection - the input section 678/// @param pArea - the memory area which pSection is within. 679uint64_t MCLinker::addEhFrame(const Input& pInput, 680 LDSection& pSection, 681 MemoryArea& pArea) 682{ 683 uint64_t size = 0; 684 685 // get the SectionData of this eh_frame 686 SectionData& sect_data = getOrCreateSectData(pSection); 687 688 // parse the eh_frame if the option --eh-frame-hdr is given 689 if (m_LDInfo.options().hasEhFrameHdr()) { 690 EhFrame* ehframe = m_Backend.getEhFrame(); 691 assert(NULL != ehframe); 692 if (ehframe->canRecognizeAllEhFrame()) { 693 size = ehframe->readEhFrame(m_Layout, m_Backend, sect_data, pInput, 694 pSection, pArea); 695 // zero size indicate that this is an empty section or we can't recognize 696 // this eh_frame, handle it as a regular section. 697 if (0 != size) 698 return size; 699 } 700 } 701 702 // handle eh_frame as a regular section 703 MemoryRegion* region = pArea.request(pInput.fileOffset() + pSection.offset(), 704 pSection.size()); 705 706 Fragment* frag = NULL; 707 if (NULL == region) { 708 // If the input section's size is zero, we got a NULL region. 709 // use a virtual fill fragment 710 frag = new FillFragment(0x0, 0, 0); 711 } 712 else 713 frag = new RegionFragment(*region); 714 715 size = m_Layout.appendFragment(*frag, sect_data, pSection.align()); 716 return size; 717} 718 719