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