1 //===- UnwindInfoSection.cpp ----------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "UnwindInfoSection.h" 10 #include "ConcatOutputSection.h" 11 #include "Config.h" 12 #include "InputSection.h" 13 #include "OutputSection.h" 14 #include "OutputSegment.h" 15 #include "SymbolTable.h" 16 #include "Symbols.h" 17 #include "SyntheticSections.h" 18 #include "Target.h" 19 20 #include "lld/Common/ErrorHandler.h" 21 #include "lld/Common/Memory.h" 22 #include "llvm/ADT/STLExtras.h" 23 #include "llvm/ADT/SmallVector.h" 24 #include "llvm/BinaryFormat/MachO.h" 25 26 using namespace llvm; 27 using namespace llvm::MachO; 28 using namespace lld; 29 using namespace lld::macho; 30 31 #define COMMON_ENCODINGS_MAX 127 32 #define COMPACT_ENCODINGS_MAX 256 33 34 #define SECOND_LEVEL_PAGE_BYTES 4096 35 #define SECOND_LEVEL_PAGE_WORDS (SECOND_LEVEL_PAGE_BYTES / sizeof(uint32_t)) 36 #define REGULAR_SECOND_LEVEL_ENTRIES_MAX \ 37 ((SECOND_LEVEL_PAGE_BYTES - \ 38 sizeof(unwind_info_regular_second_level_page_header)) / \ 39 sizeof(unwind_info_regular_second_level_entry)) 40 #define COMPRESSED_SECOND_LEVEL_ENTRIES_MAX \ 41 ((SECOND_LEVEL_PAGE_BYTES - \ 42 sizeof(unwind_info_compressed_second_level_page_header)) / \ 43 sizeof(uint32_t)) 44 45 #define COMPRESSED_ENTRY_FUNC_OFFSET_BITS 24 46 #define COMPRESSED_ENTRY_FUNC_OFFSET_MASK \ 47 UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(~0) 48 49 // Compact Unwind format is a Mach-O evolution of DWARF Unwind that 50 // optimizes space and exception-time lookup. Most DWARF unwind 51 // entries can be replaced with Compact Unwind entries, but the ones 52 // that cannot are retained in DWARF form. 53 // 54 // This comment will address macro-level organization of the pre-link 55 // and post-link compact unwind tables. For micro-level organization 56 // pertaining to the bitfield layout of the 32-bit compact unwind 57 // entries, see libunwind/include/mach-o/compact_unwind_encoding.h 58 // 59 // Important clarifying factoids: 60 // 61 // * __LD,__compact_unwind is the compact unwind format for compiler 62 // output and linker input. It is never a final output. It could be 63 // an intermediate output with the `-r` option which retains relocs. 64 // 65 // * __TEXT,__unwind_info is the compact unwind format for final 66 // linker output. It is never an input. 67 // 68 // * __TEXT,__eh_frame is the DWARF format for both linker input and output. 69 // 70 // * __TEXT,__unwind_info entries are divided into 4 KiB pages (2nd 71 // level) by ascending address, and the pages are referenced by an 72 // index (1st level) in the section header. 73 // 74 // * Following the headers in __TEXT,__unwind_info, the bulk of the 75 // section contains a vector of compact unwind entries 76 // `{functionOffset, encoding}` sorted by ascending `functionOffset`. 77 // Adjacent entries with the same encoding can be folded to great 78 // advantage, achieving a 3-order-of-magnitude reduction in the 79 // number of entries. 80 // 81 // * The __TEXT,__unwind_info format can accommodate up to 127 unique 82 // encodings for the space-efficient compressed format. In practice, 83 // fewer than a dozen unique encodings are used by C++ programs of 84 // all sizes. Therefore, we don't even bother implementing the regular 85 // non-compressed format. Time will tell if anyone in the field ever 86 // overflows the 127-encodings limit. 87 // 88 // Refer to the definition of unwind_info_section_header in 89 // compact_unwind_encoding.h for an overview of the format we are encoding 90 // here. 91 92 // TODO(gkm): prune __eh_frame entries superseded by __unwind_info, PR50410 93 // TODO(gkm): how do we align the 2nd-level pages? 94 95 using EncodingMap = llvm::DenseMap<compact_unwind_encoding_t, size_t>; 96 97 struct SecondLevelPage { 98 uint32_t kind; 99 size_t entryIndex; 100 size_t entryCount; 101 size_t byteCount; 102 std::vector<compact_unwind_encoding_t> localEncodings; 103 EncodingMap localEncodingIndexes; 104 }; 105 106 template <class Ptr> class UnwindInfoSectionImpl : public UnwindInfoSection { 107 public: 108 void prepareRelocations(ConcatInputSection *) override; 109 void finalize() override; 110 void writeTo(uint8_t *buf) const override; 111 112 private: 113 std::vector<std::pair<compact_unwind_encoding_t, size_t>> commonEncodings; 114 EncodingMap commonEncodingIndexes; 115 // Indices of personality functions within the GOT. 116 std::vector<uint32_t> personalities; 117 SmallDenseMap<std::pair<InputSection *, uint64_t /* addend */>, Symbol *> 118 personalityTable; 119 std::vector<unwind_info_section_header_lsda_index_entry> lsdaEntries; 120 // Map of function offset (from the image base) to an index within the LSDA 121 // array. 122 llvm::DenseMap<uint32_t, uint32_t> functionToLsdaIndex; 123 std::vector<CompactUnwindEntry<Ptr>> cuVector; 124 std::vector<CompactUnwindEntry<Ptr> *> cuPtrVector; 125 std::vector<SecondLevelPage> secondLevelPages; 126 uint64_t level2PagesOffset = 0; 127 }; 128 129 // Compact unwind relocations have different semantics, so we handle them in a 130 // separate code path from regular relocations. First, we do not wish to add 131 // rebase opcodes for __LD,__compact_unwind, because that section doesn't 132 // actually end up in the final binary. Second, personality pointers always 133 // reside in the GOT and must be treated specially. 134 template <class Ptr> 135 void UnwindInfoSectionImpl<Ptr>::prepareRelocations(ConcatInputSection *isec) { 136 assert(isec->segname == segment_names::ld && 137 isec->name == section_names::compactUnwind); 138 assert(!isec->shouldOmitFromOutput() && 139 "__compact_unwind section should not be omitted"); 140 141 // FIXME: Make this skip relocations for CompactUnwindEntries that 142 // point to dead-stripped functions. That might save some amount of 143 // work. But since there are usually just few personality functions 144 // that are referenced from many places, at least some of them likely 145 // live, it wouldn't reduce number of got entries. 146 for (size_t i = 0; i < isec->relocs.size(); ++i) { 147 Reloc &r = isec->relocs[i]; 148 assert(target->hasAttr(r.type, RelocAttrBits::UNSIGNED)); 149 if (r.offset % sizeof(CompactUnwindEntry<Ptr>) != 150 offsetof(CompactUnwindEntry<Ptr>, personality)) 151 continue; 152 153 Reloc &rFunc = isec->relocs[++i]; 154 assert(r.offset == 155 rFunc.offset + offsetof(CompactUnwindEntry<Ptr>, personality)); 156 auto *referentIsec = 157 cast<ConcatInputSection>(rFunc.referent.get<InputSection *>()); 158 referentIsec->hasPersonality = true; 159 160 if (auto *s = r.referent.dyn_cast<Symbol *>()) { 161 if (auto *undefined = dyn_cast<Undefined>(s)) { 162 treatUndefinedSymbol(*undefined); 163 // treatUndefinedSymbol() can replace s with a DylibSymbol; re-check. 164 if (isa<Undefined>(s)) 165 continue; 166 } 167 if (auto *defined = dyn_cast<Defined>(s)) { 168 // Check if we have created a synthetic symbol at the same address. 169 Symbol *&personality = 170 personalityTable[{defined->isec, defined->value}]; 171 if (personality == nullptr) { 172 personality = defined; 173 in.got->addEntry(defined); 174 } else if (personality != defined) { 175 r.referent = personality; 176 } 177 continue; 178 } 179 assert(isa<DylibSymbol>(s)); 180 in.got->addEntry(s); 181 continue; 182 } 183 184 if (auto *referentIsec = r.referent.dyn_cast<InputSection *>()) { 185 assert(!isCoalescedWeak(referentIsec)); 186 // Personality functions can be referenced via section relocations 187 // if they live in the same object file. Create placeholder synthetic 188 // symbols for them in the GOT. 189 Symbol *&s = personalityTable[{referentIsec, r.addend}]; 190 if (s == nullptr) { 191 // This runs after dead stripping, so the noDeadStrip argument does not 192 // matter. 193 s = make<Defined>("<internal>", /*file=*/nullptr, referentIsec, 194 r.addend, /*size=*/0, /*isWeakDef=*/false, 195 /*isExternal=*/false, /*isPrivateExtern=*/false, 196 /*isThumb=*/false, /*isReferencedDynamically=*/false, 197 /*noDeadStrip=*/false); 198 in.got->addEntry(s); 199 } 200 r.referent = s; 201 r.addend = 0; 202 } 203 } 204 } 205 206 // Unwind info lives in __DATA, and finalization of __TEXT will occur before 207 // finalization of __DATA. Moreover, the finalization of unwind info depends on 208 // the exact addresses that it references. So it is safe for compact unwind to 209 // reference addresses in __TEXT, but not addresses in any other segment. 210 static ConcatInputSection *checkTextSegment(InputSection *isec) { 211 if (isec->segname != segment_names::text) 212 error("compact unwind references address in " + toString(isec) + 213 " which is not in segment __TEXT"); 214 // __text should always be a ConcatInputSection. 215 return cast<ConcatInputSection>(isec); 216 } 217 218 // We need to apply the relocations to the pre-link compact unwind section 219 // before converting it to post-link form. There should only be absolute 220 // relocations here: since we are not emitting the pre-link CU section, there 221 // is no source address to make a relative location meaningful. 222 template <class Ptr> 223 static void 224 relocateCompactUnwind(ConcatOutputSection *compactUnwindSection, 225 std::vector<CompactUnwindEntry<Ptr>> &cuVector) { 226 for (const ConcatInputSection *isec : compactUnwindSection->inputs) { 227 assert(isec->parent == compactUnwindSection); 228 229 uint8_t *buf = 230 reinterpret_cast<uint8_t *>(cuVector.data()) + isec->outSecOff; 231 memcpy(buf, isec->data.data(), isec->data.size()); 232 233 for (const Reloc &r : isec->relocs) { 234 uint64_t referentVA = 0; 235 if (auto *referentSym = r.referent.dyn_cast<Symbol *>()) { 236 if (!isa<Undefined>(referentSym)) { 237 assert(referentSym->isInGot()); 238 if (auto *defined = dyn_cast<Defined>(referentSym)) 239 checkTextSegment(defined->isec); 240 // At this point in the link, we may not yet know the final address of 241 // the GOT, so we just encode the index. We make it a 1-based index so 242 // that we can distinguish the null pointer case. 243 referentVA = referentSym->gotIndex + 1; 244 } 245 } else if (auto *referentIsec = r.referent.dyn_cast<InputSection *>()) { 246 ConcatInputSection *concatIsec = checkTextSegment(referentIsec); 247 if (concatIsec->shouldOmitFromOutput()) 248 referentVA = UINT64_MAX; // Tombstone value 249 else 250 referentVA = referentIsec->getVA(r.addend); 251 } 252 253 writeAddress(buf + r.offset, referentVA, r.length); 254 } 255 } 256 } 257 258 // There should only be a handful of unique personality pointers, so we can 259 // encode them as 2-bit indices into a small array. 260 template <class Ptr> 261 static void 262 encodePersonalities(const std::vector<CompactUnwindEntry<Ptr> *> &cuPtrVector, 263 std::vector<uint32_t> &personalities) { 264 for (CompactUnwindEntry<Ptr> *cu : cuPtrVector) { 265 if (cu->personality == 0) 266 continue; 267 // Linear search is fast enough for a small array. 268 auto it = find(personalities, cu->personality); 269 uint32_t personalityIndex; // 1-based index 270 if (it != personalities.end()) { 271 personalityIndex = std::distance(personalities.begin(), it) + 1; 272 } else { 273 personalities.push_back(cu->personality); 274 personalityIndex = personalities.size(); 275 } 276 cu->encoding |= 277 personalityIndex << countTrailingZeros( 278 static_cast<compact_unwind_encoding_t>(UNWIND_PERSONALITY_MASK)); 279 } 280 if (personalities.size() > 3) 281 error("too many personalities (" + std::to_string(personalities.size()) + 282 ") for compact unwind to encode"); 283 } 284 285 // __unwind_info stores unwind data for address ranges. If several 286 // adjacent functions have the same unwind encoding, LSDA, and personality 287 // function, they share one unwind entry. For this to work, functions without 288 // unwind info need explicit "no unwind info" unwind entries -- else the 289 // unwinder would think they have the unwind info of the closest function 290 // with unwind info right before in the image. 291 template <class Ptr> 292 static void addEntriesForFunctionsWithoutUnwindInfo( 293 std::vector<CompactUnwindEntry<Ptr>> &cuVector) { 294 DenseSet<Ptr> hasUnwindInfo; 295 for (CompactUnwindEntry<Ptr> &cuEntry : cuVector) 296 if (cuEntry.functionAddress != UINT64_MAX) 297 hasUnwindInfo.insert(cuEntry.functionAddress); 298 299 // Add explicit "has no unwind info" entries for all global and local symbols 300 // without unwind info. 301 auto markNoUnwindInfo = [&cuVector, &hasUnwindInfo](const Defined *d) { 302 if (d->isLive() && d->isec && isCodeSection(d->isec)) { 303 Ptr ptr = d->getVA(); 304 if (!hasUnwindInfo.count(ptr)) 305 cuVector.push_back({ptr, 0, 0, 0, 0}); 306 } 307 }; 308 for (Symbol *sym : symtab->getSymbols()) 309 if (auto *d = dyn_cast<Defined>(sym)) 310 markNoUnwindInfo(d); 311 for (const InputFile *file : inputFiles) 312 if (auto *objFile = dyn_cast<ObjFile>(file)) 313 for (Symbol *sym : objFile->symbols) 314 if (auto *d = dyn_cast_or_null<Defined>(sym)) 315 if (!d->isExternal()) 316 markNoUnwindInfo(d); 317 } 318 319 // Scan the __LD,__compact_unwind entries and compute the space needs of 320 // __TEXT,__unwind_info and __TEXT,__eh_frame 321 template <class Ptr> void UnwindInfoSectionImpl<Ptr>::finalize() { 322 if (compactUnwindSection == nullptr) 323 return; 324 325 // At this point, the address space for __TEXT,__text has been 326 // assigned, so we can relocate the __LD,__compact_unwind entries 327 // into a temporary buffer. Relocation is necessary in order to sort 328 // the CU entries by function address. Sorting is necessary so that 329 // we can fold adjacent CU entries with identical 330 // encoding+personality+lsda. Folding is necessary because it reduces 331 // the number of CU entries by as much as 3 orders of magnitude! 332 compactUnwindSection->finalize(); 333 assert(compactUnwindSection->getSize() % sizeof(CompactUnwindEntry<Ptr>) == 334 0); 335 size_t cuCount = 336 compactUnwindSection->getSize() / sizeof(CompactUnwindEntry<Ptr>); 337 cuVector.resize(cuCount); 338 relocateCompactUnwind(compactUnwindSection, cuVector); 339 340 addEntriesForFunctionsWithoutUnwindInfo(cuVector); 341 342 // Rather than sort & fold the 32-byte entries directly, we create a 343 // vector of pointers to entries and sort & fold that instead. 344 cuPtrVector.reserve(cuCount); 345 for (CompactUnwindEntry<Ptr> &cuEntry : cuVector) 346 cuPtrVector.emplace_back(&cuEntry); 347 llvm::sort(cuPtrVector, [](const CompactUnwindEntry<Ptr> *a, 348 const CompactUnwindEntry<Ptr> *b) { 349 return a->functionAddress < b->functionAddress; 350 }); 351 352 // Dead-stripped functions get a functionAddress of UINT64_MAX in 353 // relocateCompactUnwind(). Filter them out here. 354 // FIXME: This doesn't yet collect associated data like LSDAs kept 355 // alive only by a now-removed CompactUnwindEntry or other comdat-like 356 // data (`kindNoneGroupSubordinate*` in ld64). 357 CompactUnwindEntry<Ptr> tombstone; 358 tombstone.functionAddress = static_cast<Ptr>(UINT64_MAX); 359 cuPtrVector.erase( 360 std::lower_bound(cuPtrVector.begin(), cuPtrVector.end(), &tombstone, 361 [](const CompactUnwindEntry<Ptr> *a, 362 const CompactUnwindEntry<Ptr> *b) { 363 return a->functionAddress < b->functionAddress; 364 }), 365 cuPtrVector.end()); 366 367 // Fold adjacent entries with matching encoding+personality+lsda 368 // We use three iterators on the same cuPtrVector to fold in-situ: 369 // (1) `foldBegin` is the first of a potential sequence of matching entries 370 // (2) `foldEnd` is the first non-matching entry after `foldBegin`. 371 // The semi-open interval [ foldBegin .. foldEnd ) contains a range 372 // entries that can be folded into a single entry and written to ... 373 // (3) `foldWrite` 374 auto foldWrite = cuPtrVector.begin(); 375 for (auto foldBegin = cuPtrVector.begin(); foldBegin < cuPtrVector.end();) { 376 auto foldEnd = foldBegin; 377 while (++foldEnd < cuPtrVector.end() && 378 (*foldBegin)->encoding == (*foldEnd)->encoding && 379 (*foldBegin)->personality == (*foldEnd)->personality && 380 (*foldBegin)->lsda == (*foldEnd)->lsda) 381 ; 382 *foldWrite++ = *foldBegin; 383 foldBegin = foldEnd; 384 } 385 cuPtrVector.erase(foldWrite, cuPtrVector.end()); 386 387 encodePersonalities(cuPtrVector, personalities); 388 389 // Count frequencies of the folded encodings 390 EncodingMap encodingFrequencies; 391 for (const CompactUnwindEntry<Ptr> *cuPtrEntry : cuPtrVector) 392 encodingFrequencies[cuPtrEntry->encoding]++; 393 394 // Make a vector of encodings, sorted by descending frequency 395 for (const auto &frequency : encodingFrequencies) 396 commonEncodings.emplace_back(frequency); 397 llvm::sort(commonEncodings, 398 [](const std::pair<compact_unwind_encoding_t, size_t> &a, 399 const std::pair<compact_unwind_encoding_t, size_t> &b) { 400 if (a.second == b.second) 401 // When frequencies match, secondarily sort on encoding 402 // to maintain parity with validate-unwind-info.py 403 return a.first > b.first; 404 return a.second > b.second; 405 }); 406 407 // Truncate the vector to 127 elements. 408 // Common encoding indexes are limited to 0..126, while encoding 409 // indexes 127..255 are local to each second-level page 410 if (commonEncodings.size() > COMMON_ENCODINGS_MAX) 411 commonEncodings.resize(COMMON_ENCODINGS_MAX); 412 413 // Create a map from encoding to common-encoding-table index 414 for (size_t i = 0; i < commonEncodings.size(); i++) 415 commonEncodingIndexes[commonEncodings[i].first] = i; 416 417 // Split folded encodings into pages, where each page is limited by ... 418 // (a) 4 KiB capacity 419 // (b) 24-bit difference between first & final function address 420 // (c) 8-bit compact-encoding-table index, 421 // for which 0..126 references the global common-encodings table, 422 // and 127..255 references a local per-second-level-page table. 423 // First we try the compact format and determine how many entries fit. 424 // If more entries fit in the regular format, we use that. 425 for (size_t i = 0; i < cuPtrVector.size();) { 426 secondLevelPages.emplace_back(); 427 SecondLevelPage &page = secondLevelPages.back(); 428 page.entryIndex = i; 429 uintptr_t functionAddressMax = 430 cuPtrVector[i]->functionAddress + COMPRESSED_ENTRY_FUNC_OFFSET_MASK; 431 size_t n = commonEncodings.size(); 432 size_t wordsRemaining = 433 SECOND_LEVEL_PAGE_WORDS - 434 sizeof(unwind_info_compressed_second_level_page_header) / 435 sizeof(uint32_t); 436 while (wordsRemaining >= 1 && i < cuPtrVector.size()) { 437 const CompactUnwindEntry<Ptr> *cuPtr = cuPtrVector[i]; 438 if (cuPtr->functionAddress >= functionAddressMax) { 439 break; 440 } else if (commonEncodingIndexes.count(cuPtr->encoding) || 441 page.localEncodingIndexes.count(cuPtr->encoding)) { 442 i++; 443 wordsRemaining--; 444 } else if (wordsRemaining >= 2 && n < COMPACT_ENCODINGS_MAX) { 445 page.localEncodings.emplace_back(cuPtr->encoding); 446 page.localEncodingIndexes[cuPtr->encoding] = n++; 447 i++; 448 wordsRemaining -= 2; 449 } else { 450 break; 451 } 452 } 453 page.entryCount = i - page.entryIndex; 454 455 // If this is not the final page, see if it's possible to fit more 456 // entries by using the regular format. This can happen when there 457 // are many unique encodings, and we we saturated the local 458 // encoding table early. 459 if (i < cuPtrVector.size() && 460 page.entryCount < REGULAR_SECOND_LEVEL_ENTRIES_MAX) { 461 page.kind = UNWIND_SECOND_LEVEL_REGULAR; 462 page.entryCount = std::min(REGULAR_SECOND_LEVEL_ENTRIES_MAX, 463 cuPtrVector.size() - page.entryIndex); 464 i = page.entryIndex + page.entryCount; 465 } else { 466 page.kind = UNWIND_SECOND_LEVEL_COMPRESSED; 467 } 468 } 469 470 for (const CompactUnwindEntry<Ptr> *cu : cuPtrVector) { 471 uint32_t functionOffset = cu->functionAddress - in.header->addr; 472 functionToLsdaIndex[functionOffset] = lsdaEntries.size(); 473 if (cu->lsda != 0) 474 lsdaEntries.push_back( 475 {functionOffset, static_cast<uint32_t>(cu->lsda - in.header->addr)}); 476 } 477 478 // compute size of __TEXT,__unwind_info section 479 level2PagesOffset = 480 sizeof(unwind_info_section_header) + 481 commonEncodings.size() * sizeof(uint32_t) + 482 personalities.size() * sizeof(uint32_t) + 483 // The extra second-level-page entry is for the sentinel 484 (secondLevelPages.size() + 1) * 485 sizeof(unwind_info_section_header_index_entry) + 486 lsdaEntries.size() * sizeof(unwind_info_section_header_lsda_index_entry); 487 unwindInfoSize = 488 level2PagesOffset + secondLevelPages.size() * SECOND_LEVEL_PAGE_BYTES; 489 } 490 491 // All inputs are relocated and output addresses are known, so write! 492 493 template <class Ptr> 494 void UnwindInfoSectionImpl<Ptr>::writeTo(uint8_t *buf) const { 495 // section header 496 auto *uip = reinterpret_cast<unwind_info_section_header *>(buf); 497 uip->version = 1; 498 uip->commonEncodingsArraySectionOffset = sizeof(unwind_info_section_header); 499 uip->commonEncodingsArrayCount = commonEncodings.size(); 500 uip->personalityArraySectionOffset = 501 uip->commonEncodingsArraySectionOffset + 502 (uip->commonEncodingsArrayCount * sizeof(uint32_t)); 503 uip->personalityArrayCount = personalities.size(); 504 uip->indexSectionOffset = uip->personalityArraySectionOffset + 505 (uip->personalityArrayCount * sizeof(uint32_t)); 506 uip->indexCount = secondLevelPages.size() + 1; 507 508 // Common encodings 509 auto *i32p = reinterpret_cast<uint32_t *>(&uip[1]); 510 for (const auto &encoding : commonEncodings) 511 *i32p++ = encoding.first; 512 513 // Personalities 514 for (const uint32_t &personality : personalities) 515 *i32p++ = 516 in.got->addr + (personality - 1) * target->wordSize - in.header->addr; 517 518 // Level-1 index 519 uint32_t lsdaOffset = 520 uip->indexSectionOffset + 521 uip->indexCount * sizeof(unwind_info_section_header_index_entry); 522 uint64_t l2PagesOffset = level2PagesOffset; 523 auto *iep = reinterpret_cast<unwind_info_section_header_index_entry *>(i32p); 524 for (const SecondLevelPage &page : secondLevelPages) { 525 iep->functionOffset = 526 cuPtrVector[page.entryIndex]->functionAddress - in.header->addr; 527 iep->secondLevelPagesSectionOffset = l2PagesOffset; 528 iep->lsdaIndexArraySectionOffset = 529 lsdaOffset + functionToLsdaIndex.lookup(iep->functionOffset) * 530 sizeof(unwind_info_section_header_lsda_index_entry); 531 iep++; 532 l2PagesOffset += SECOND_LEVEL_PAGE_BYTES; 533 } 534 // Level-1 sentinel 535 const CompactUnwindEntry<Ptr> &cuEnd = cuVector.back(); 536 iep->functionOffset = cuEnd.functionAddress + cuEnd.functionLength; 537 iep->secondLevelPagesSectionOffset = 0; 538 iep->lsdaIndexArraySectionOffset = 539 lsdaOffset + 540 lsdaEntries.size() * sizeof(unwind_info_section_header_lsda_index_entry); 541 iep++; 542 543 // LSDAs 544 size_t lsdaBytes = 545 lsdaEntries.size() * sizeof(unwind_info_section_header_lsda_index_entry); 546 if (lsdaBytes > 0) 547 memcpy(iep, lsdaEntries.data(), lsdaBytes); 548 549 // Level-2 pages 550 auto *pp = reinterpret_cast<uint32_t *>(reinterpret_cast<uint8_t *>(iep) + 551 lsdaBytes); 552 for (const SecondLevelPage &page : secondLevelPages) { 553 if (page.kind == UNWIND_SECOND_LEVEL_COMPRESSED) { 554 uintptr_t functionAddressBase = 555 cuPtrVector[page.entryIndex]->functionAddress; 556 auto *p2p = 557 reinterpret_cast<unwind_info_compressed_second_level_page_header *>( 558 pp); 559 p2p->kind = page.kind; 560 p2p->entryPageOffset = 561 sizeof(unwind_info_compressed_second_level_page_header); 562 p2p->entryCount = page.entryCount; 563 p2p->encodingsPageOffset = 564 p2p->entryPageOffset + p2p->entryCount * sizeof(uint32_t); 565 p2p->encodingsCount = page.localEncodings.size(); 566 auto *ep = reinterpret_cast<uint32_t *>(&p2p[1]); 567 for (size_t i = 0; i < page.entryCount; i++) { 568 const CompactUnwindEntry<Ptr> *cuep = cuPtrVector[page.entryIndex + i]; 569 auto it = commonEncodingIndexes.find(cuep->encoding); 570 if (it == commonEncodingIndexes.end()) 571 it = page.localEncodingIndexes.find(cuep->encoding); 572 *ep++ = (it->second << COMPRESSED_ENTRY_FUNC_OFFSET_BITS) | 573 (cuep->functionAddress - functionAddressBase); 574 } 575 if (page.localEncodings.size() != 0) 576 memcpy(ep, page.localEncodings.data(), 577 page.localEncodings.size() * sizeof(uint32_t)); 578 } else { 579 auto *p2p = 580 reinterpret_cast<unwind_info_regular_second_level_page_header *>(pp); 581 p2p->kind = page.kind; 582 p2p->entryPageOffset = 583 sizeof(unwind_info_regular_second_level_page_header); 584 p2p->entryCount = page.entryCount; 585 auto *ep = reinterpret_cast<uint32_t *>(&p2p[1]); 586 for (size_t i = 0; i < page.entryCount; i++) { 587 const CompactUnwindEntry<Ptr> *cuep = cuPtrVector[page.entryIndex + i]; 588 *ep++ = cuep->functionAddress; 589 *ep++ = cuep->encoding; 590 } 591 } 592 pp += SECOND_LEVEL_PAGE_WORDS; 593 } 594 } 595 596 UnwindInfoSection *macho::makeUnwindInfoSection() { 597 if (target->wordSize == 8) 598 return make<UnwindInfoSectionImpl<uint64_t>>(); 599 else 600 return make<UnwindInfoSectionImpl<uint32_t>>(); 601 } 602