1e8d8bef9SDimitry Andric //===- UnwindInfoSection.cpp ----------------------------------------------===// 2e8d8bef9SDimitry Andric // 3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e8d8bef9SDimitry Andric // 7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 8e8d8bef9SDimitry Andric 9e8d8bef9SDimitry Andric #include "UnwindInfoSection.h" 10e8d8bef9SDimitry Andric #include "InputSection.h" 1106c3fb27SDimitry Andric #include "Layout.h" 12e8d8bef9SDimitry Andric #include "OutputSection.h" 13e8d8bef9SDimitry Andric #include "OutputSegment.h" 14fe6060f1SDimitry Andric #include "SymbolTable.h" 15e8d8bef9SDimitry Andric #include "Symbols.h" 16e8d8bef9SDimitry Andric #include "SyntheticSections.h" 17e8d8bef9SDimitry Andric #include "Target.h" 18e8d8bef9SDimitry Andric 19e8d8bef9SDimitry Andric #include "lld/Common/ErrorHandler.h" 20fe6060f1SDimitry Andric #include "lld/Common/Memory.h" 21349cc55cSDimitry Andric #include "llvm/ADT/DenseMap.h" 22fe6060f1SDimitry Andric #include "llvm/ADT/STLExtras.h" 23e8d8bef9SDimitry Andric #include "llvm/BinaryFormat/MachO.h" 24349cc55cSDimitry Andric #include "llvm/Support/Parallel.h" 25349cc55cSDimitry Andric 26bdd1243dSDimitry Andric #include "mach-o/compact_unwind_encoding.h" 27bdd1243dSDimitry Andric 28349cc55cSDimitry Andric #include <numeric> 29e8d8bef9SDimitry Andric 30e8d8bef9SDimitry Andric using namespace llvm; 31e8d8bef9SDimitry Andric using namespace llvm::MachO; 3281ad6265SDimitry Andric using namespace llvm::support::endian; 33e8d8bef9SDimitry Andric using namespace lld; 34e8d8bef9SDimitry Andric using namespace lld::macho; 35e8d8bef9SDimitry Andric 36e8d8bef9SDimitry Andric #define COMMON_ENCODINGS_MAX 127 37e8d8bef9SDimitry Andric #define COMPACT_ENCODINGS_MAX 256 38e8d8bef9SDimitry Andric 39e8d8bef9SDimitry Andric #define SECOND_LEVEL_PAGE_BYTES 4096 40e8d8bef9SDimitry Andric #define SECOND_LEVEL_PAGE_WORDS (SECOND_LEVEL_PAGE_BYTES / sizeof(uint32_t)) 41e8d8bef9SDimitry Andric #define REGULAR_SECOND_LEVEL_ENTRIES_MAX \ 42e8d8bef9SDimitry Andric ((SECOND_LEVEL_PAGE_BYTES - \ 43e8d8bef9SDimitry Andric sizeof(unwind_info_regular_second_level_page_header)) / \ 44e8d8bef9SDimitry Andric sizeof(unwind_info_regular_second_level_entry)) 45e8d8bef9SDimitry Andric #define COMPRESSED_SECOND_LEVEL_ENTRIES_MAX \ 46e8d8bef9SDimitry Andric ((SECOND_LEVEL_PAGE_BYTES - \ 47e8d8bef9SDimitry Andric sizeof(unwind_info_compressed_second_level_page_header)) / \ 48e8d8bef9SDimitry Andric sizeof(uint32_t)) 49e8d8bef9SDimitry Andric 50e8d8bef9SDimitry Andric #define COMPRESSED_ENTRY_FUNC_OFFSET_BITS 24 51e8d8bef9SDimitry Andric #define COMPRESSED_ENTRY_FUNC_OFFSET_MASK \ 52e8d8bef9SDimitry Andric UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(~0) 53e8d8bef9SDimitry Andric 5406c3fb27SDimitry Andric static_assert(static_cast<uint32_t>(UNWIND_X86_64_DWARF_SECTION_OFFSET) == 5506c3fb27SDimitry Andric static_cast<uint32_t>(UNWIND_ARM64_DWARF_SECTION_OFFSET) && 5606c3fb27SDimitry Andric static_cast<uint32_t>(UNWIND_X86_64_DWARF_SECTION_OFFSET) == 5706c3fb27SDimitry Andric static_cast<uint32_t>(UNWIND_X86_DWARF_SECTION_OFFSET)); 5806c3fb27SDimitry Andric 5906c3fb27SDimitry Andric constexpr uint64_t DWARF_SECTION_OFFSET = UNWIND_X86_64_DWARF_SECTION_OFFSET; 6006c3fb27SDimitry Andric 61e8d8bef9SDimitry Andric // Compact Unwind format is a Mach-O evolution of DWARF Unwind that 62e8d8bef9SDimitry Andric // optimizes space and exception-time lookup. Most DWARF unwind 63e8d8bef9SDimitry Andric // entries can be replaced with Compact Unwind entries, but the ones 64e8d8bef9SDimitry Andric // that cannot are retained in DWARF form. 65e8d8bef9SDimitry Andric // 66e8d8bef9SDimitry Andric // This comment will address macro-level organization of the pre-link 67e8d8bef9SDimitry Andric // and post-link compact unwind tables. For micro-level organization 68e8d8bef9SDimitry Andric // pertaining to the bitfield layout of the 32-bit compact unwind 69e8d8bef9SDimitry Andric // entries, see libunwind/include/mach-o/compact_unwind_encoding.h 70e8d8bef9SDimitry Andric // 71e8d8bef9SDimitry Andric // Important clarifying factoids: 72e8d8bef9SDimitry Andric // 73e8d8bef9SDimitry Andric // * __LD,__compact_unwind is the compact unwind format for compiler 74e8d8bef9SDimitry Andric // output and linker input. It is never a final output. It could be 75e8d8bef9SDimitry Andric // an intermediate output with the `-r` option which retains relocs. 76e8d8bef9SDimitry Andric // 77e8d8bef9SDimitry Andric // * __TEXT,__unwind_info is the compact unwind format for final 78e8d8bef9SDimitry Andric // linker output. It is never an input. 79e8d8bef9SDimitry Andric // 80e8d8bef9SDimitry Andric // * __TEXT,__eh_frame is the DWARF format for both linker input and output. 81e8d8bef9SDimitry Andric // 82e8d8bef9SDimitry Andric // * __TEXT,__unwind_info entries are divided into 4 KiB pages (2nd 83e8d8bef9SDimitry Andric // level) by ascending address, and the pages are referenced by an 84e8d8bef9SDimitry Andric // index (1st level) in the section header. 85e8d8bef9SDimitry Andric // 86e8d8bef9SDimitry Andric // * Following the headers in __TEXT,__unwind_info, the bulk of the 87e8d8bef9SDimitry Andric // section contains a vector of compact unwind entries 88e8d8bef9SDimitry Andric // `{functionOffset, encoding}` sorted by ascending `functionOffset`. 89e8d8bef9SDimitry Andric // Adjacent entries with the same encoding can be folded to great 90e8d8bef9SDimitry Andric // advantage, achieving a 3-order-of-magnitude reduction in the 91e8d8bef9SDimitry Andric // number of entries. 92e8d8bef9SDimitry Andric // 93fe6060f1SDimitry Andric // Refer to the definition of unwind_info_section_header in 94fe6060f1SDimitry Andric // compact_unwind_encoding.h for an overview of the format we are encoding 95fe6060f1SDimitry Andric // here. 96e8d8bef9SDimitry Andric 97e8d8bef9SDimitry Andric // TODO(gkm): how do we align the 2nd-level pages? 98e8d8bef9SDimitry Andric 9906c3fb27SDimitry Andric // The various fields in the on-disk representation of each compact unwind 10006c3fb27SDimitry Andric // entry. 10106c3fb27SDimitry Andric #define FOR_EACH_CU_FIELD(DO) \ 10206c3fb27SDimitry Andric DO(Ptr, functionAddress) \ 10306c3fb27SDimitry Andric DO(uint32_t, functionLength) \ 10406c3fb27SDimitry Andric DO(compact_unwind_encoding_t, encoding) \ 10506c3fb27SDimitry Andric DO(Ptr, personality) \ 10606c3fb27SDimitry Andric DO(Ptr, lsda) 10781ad6265SDimitry Andric 10806c3fb27SDimitry Andric CREATE_LAYOUT_CLASS(CompactUnwind, FOR_EACH_CU_FIELD); 10981ad6265SDimitry Andric 11006c3fb27SDimitry Andric #undef FOR_EACH_CU_FIELD 11181ad6265SDimitry Andric 11281ad6265SDimitry Andric // LLD's internal representation of a compact unwind entry. 11381ad6265SDimitry Andric struct CompactUnwindEntry { 11481ad6265SDimitry Andric uint64_t functionAddress; 11581ad6265SDimitry Andric uint32_t functionLength; 11681ad6265SDimitry Andric compact_unwind_encoding_t encoding; 11781ad6265SDimitry Andric Symbol *personality; 11881ad6265SDimitry Andric InputSection *lsda; 11981ad6265SDimitry Andric }; 120349cc55cSDimitry Andric 121fe6060f1SDimitry Andric using EncodingMap = DenseMap<compact_unwind_encoding_t, size_t>; 122fe6060f1SDimitry Andric 123fe6060f1SDimitry Andric struct SecondLevelPage { 124fe6060f1SDimitry Andric uint32_t kind; 125fe6060f1SDimitry Andric size_t entryIndex; 126fe6060f1SDimitry Andric size_t entryCount; 127fe6060f1SDimitry Andric size_t byteCount; 128fe6060f1SDimitry Andric std::vector<compact_unwind_encoding_t> localEncodings; 129fe6060f1SDimitry Andric EncodingMap localEncodingIndexes; 130fe6060f1SDimitry Andric }; 131fe6060f1SDimitry Andric 13281ad6265SDimitry Andric // UnwindInfoSectionImpl allows us to avoid cluttering our header file with a 13381ad6265SDimitry Andric // lengthy definition of UnwindInfoSection. 134fe6060f1SDimitry Andric class UnwindInfoSectionImpl final : public UnwindInfoSection { 135fe6060f1SDimitry Andric public: 13606c3fb27SDimitry Andric UnwindInfoSectionImpl() : cuLayout(target->wordSize) {} 13781ad6265SDimitry Andric uint64_t getSize() const override { return unwindInfoSize; } 138f3fd488fSDimitry Andric void prepare() override; 139fe6060f1SDimitry Andric void finalize() override; 140fe6060f1SDimitry Andric void writeTo(uint8_t *buf) const override; 141fe6060f1SDimitry Andric 142fe6060f1SDimitry Andric private: 14381ad6265SDimitry Andric void prepareRelocations(ConcatInputSection *); 14481ad6265SDimitry Andric void relocateCompactUnwind(std::vector<CompactUnwindEntry> &); 14581ad6265SDimitry Andric void encodePersonalities(); 146f3fd488fSDimitry Andric Symbol *canonicalizePersonality(Symbol *); 14781ad6265SDimitry Andric 14881ad6265SDimitry Andric uint64_t unwindInfoSize = 0; 14906c3fb27SDimitry Andric SmallVector<decltype(symbols)::value_type, 0> symbolsVec; 15006c3fb27SDimitry Andric CompactUnwindLayout cuLayout; 151fe6060f1SDimitry Andric std::vector<std::pair<compact_unwind_encoding_t, size_t>> commonEncodings; 152fe6060f1SDimitry Andric EncodingMap commonEncodingIndexes; 153349cc55cSDimitry Andric // The entries here will be in the same order as their originating symbols 154349cc55cSDimitry Andric // in symbolsVec. 15581ad6265SDimitry Andric std::vector<CompactUnwindEntry> cuEntries; 156349cc55cSDimitry Andric // Indices into the cuEntries vector. 157349cc55cSDimitry Andric std::vector<size_t> cuIndices; 15881ad6265SDimitry Andric std::vector<Symbol *> personalities; 159fe6060f1SDimitry Andric SmallDenseMap<std::pair<InputSection *, uint64_t /* addend */>, Symbol *> 160fe6060f1SDimitry Andric personalityTable; 161349cc55cSDimitry Andric // Indices into cuEntries for CUEs with a non-null LSDA. 162349cc55cSDimitry Andric std::vector<size_t> entriesWithLsda; 163349cc55cSDimitry Andric // Map of cuEntries index to an index within the LSDA array. 164349cc55cSDimitry Andric DenseMap<size_t, uint32_t> lsdaIndex; 165fe6060f1SDimitry Andric std::vector<SecondLevelPage> secondLevelPages; 166fe6060f1SDimitry Andric uint64_t level2PagesOffset = 0; 167bdd1243dSDimitry Andric // The highest-address function plus its size. The unwinder needs this to 168bdd1243dSDimitry Andric // determine the address range that is covered by unwind info. 169bdd1243dSDimitry Andric uint64_t cueEndBoundary = 0; 170fe6060f1SDimitry Andric }; 171fe6060f1SDimitry Andric 172e8d8bef9SDimitry Andric UnwindInfoSection::UnwindInfoSection() 173e8d8bef9SDimitry Andric : SyntheticSection(segment_names::text, section_names::unwindInfo) { 174fe6060f1SDimitry Andric align = 4; 175e8d8bef9SDimitry Andric } 176e8d8bef9SDimitry Andric 177349cc55cSDimitry Andric // Record function symbols that may need entries emitted in __unwind_info, which 178349cc55cSDimitry Andric // stores unwind data for address ranges. 179349cc55cSDimitry Andric // 1806246ae0bSDimitry Andric // Note that if several adjacent functions have the same unwind encoding and 1816246ae0bSDimitry Andric // personality function and no LSDA, they share one unwind entry. For this to 1826246ae0bSDimitry Andric // work, functions without unwind info need explicit "no unwind info" unwind 1836246ae0bSDimitry Andric // entries -- else the unwinder would think they have the unwind info of the 1846246ae0bSDimitry Andric // closest function with unwind info right before in the image. Thus, we add 1856246ae0bSDimitry Andric // function symbols for each unique address regardless of whether they have 1866246ae0bSDimitry Andric // associated unwind info. 187349cc55cSDimitry Andric void UnwindInfoSection::addSymbol(const Defined *d) { 188*0fca6ea1SDimitry Andric if (d->unwindEntry()) 189349cc55cSDimitry Andric allEntriesAreOmitted = false; 190349cc55cSDimitry Andric // We don't yet know the final output address of this symbol, but we know that 191349cc55cSDimitry Andric // they are uniquely determined by a combination of the isec and value, so 192349cc55cSDimitry Andric // we use that as the key here. 193*0fca6ea1SDimitry Andric auto p = symbols.insert({{d->isec(), d->value}, d}); 194349cc55cSDimitry Andric // If we have multiple symbols at the same address, only one of them can have 195fcaf7f86SDimitry Andric // an associated unwind entry. 196*0fca6ea1SDimitry Andric if (!p.second && d->unwindEntry()) { 197*0fca6ea1SDimitry Andric assert(p.first->second == d || !p.first->second->unwindEntry()); 198349cc55cSDimitry Andric p.first->second = d; 199349cc55cSDimitry Andric } 200fe6060f1SDimitry Andric } 201fe6060f1SDimitry Andric 202f3fd488fSDimitry Andric void UnwindInfoSectionImpl::prepare() { 20381ad6265SDimitry Andric // This iteration needs to be deterministic, since prepareRelocations may add 20481ad6265SDimitry Andric // entries to the GOT. Hence the use of a MapVector for 20581ad6265SDimitry Andric // UnwindInfoSection::symbols. 20681ad6265SDimitry Andric for (const Defined *d : make_second_range(symbols)) 207*0fca6ea1SDimitry Andric if (d->unwindEntry()) { 208*0fca6ea1SDimitry Andric if (d->unwindEntry()->getName() == section_names::compactUnwind) { 209*0fca6ea1SDimitry Andric prepareRelocations(d->unwindEntry()); 210f3fd488fSDimitry Andric } else { 211f3fd488fSDimitry Andric // We don't have to add entries to the GOT here because FDEs have 212f3fd488fSDimitry Andric // explicit GOT relocations, so Writer::scanRelocations() will add those 213f3fd488fSDimitry Andric // GOT entries. However, we still need to canonicalize the personality 214f3fd488fSDimitry Andric // pointers (like prepareRelocations() does for CU entries) in order 215f3fd488fSDimitry Andric // to avoid overflowing the 3-personality limit. 216*0fca6ea1SDimitry Andric FDE &fde = cast<ObjFile>(d->getFile())->fdes[d->unwindEntry()]; 217f3fd488fSDimitry Andric fde.personality = canonicalizePersonality(fde.personality); 218f3fd488fSDimitry Andric } 219f3fd488fSDimitry Andric } 22081ad6265SDimitry Andric } 22181ad6265SDimitry Andric 222fe6060f1SDimitry Andric // Compact unwind relocations have different semantics, so we handle them in a 223fe6060f1SDimitry Andric // separate code path from regular relocations. First, we do not wish to add 224fe6060f1SDimitry Andric // rebase opcodes for __LD,__compact_unwind, because that section doesn't 225fe6060f1SDimitry Andric // actually end up in the final binary. Second, personality pointers always 226fe6060f1SDimitry Andric // reside in the GOT and must be treated specially. 22781ad6265SDimitry Andric void UnwindInfoSectionImpl::prepareRelocations(ConcatInputSection *isec) { 228fe6060f1SDimitry Andric assert(!isec->shouldOmitFromOutput() && 229fe6060f1SDimitry Andric "__compact_unwind section should not be omitted"); 230fe6060f1SDimitry Andric 231fe6060f1SDimitry Andric // FIXME: Make this skip relocations for CompactUnwindEntries that 232fe6060f1SDimitry Andric // point to dead-stripped functions. That might save some amount of 233fe6060f1SDimitry Andric // work. But since there are usually just few personality functions 234fe6060f1SDimitry Andric // that are referenced from many places, at least some of them likely 235fe6060f1SDimitry Andric // live, it wouldn't reduce number of got entries. 236fe6060f1SDimitry Andric for (size_t i = 0; i < isec->relocs.size(); ++i) { 237fe6060f1SDimitry Andric Reloc &r = isec->relocs[i]; 238fe6060f1SDimitry Andric assert(target->hasAttr(r.type, RelocAttrBits::UNSIGNED)); 239bdd1243dSDimitry Andric // Since compact unwind sections aren't part of the inputSections vector, 240bdd1243dSDimitry Andric // they don't get canonicalized by scanRelocations(), so we have to do the 241bdd1243dSDimitry Andric // canonicalization here. 242bdd1243dSDimitry Andric if (auto *referentIsec = r.referent.dyn_cast<InputSection *>()) 243bdd1243dSDimitry Andric r.referent = referentIsec->canonical(); 244fe6060f1SDimitry Andric 245349cc55cSDimitry Andric // Functions and LSDA entries always reside in the same object file as the 246349cc55cSDimitry Andric // compact unwind entries that references them, and thus appear as section 247349cc55cSDimitry Andric // relocs. There is no need to prepare them. We only prepare relocs for 248349cc55cSDimitry Andric // personality functions. 24906c3fb27SDimitry Andric if (r.offset != cuLayout.personalityOffset) 250fe6060f1SDimitry Andric continue; 251fe6060f1SDimitry Andric 252fe6060f1SDimitry Andric if (auto *s = r.referent.dyn_cast<Symbol *>()) { 253349cc55cSDimitry Andric // Personality functions are nearly always system-defined (e.g., 254349cc55cSDimitry Andric // ___gxx_personality_v0 for C++) and relocated as dylib symbols. When an 255349cc55cSDimitry Andric // application provides its own personality function, it might be 256349cc55cSDimitry Andric // referenced by an extern Defined symbol reloc, or a local section reloc. 257349cc55cSDimitry Andric if (auto *defined = dyn_cast<Defined>(s)) { 258bdd1243dSDimitry Andric // XXX(vyng) This is a special case for handling duplicate personality 259349cc55cSDimitry Andric // symbols. Note that LD64's behavior is a bit different and it is 260349cc55cSDimitry Andric // inconsistent with how symbol resolution usually work 261349cc55cSDimitry Andric // 262349cc55cSDimitry Andric // So we've decided not to follow it. Instead, simply pick the symbol 263349cc55cSDimitry Andric // with the same name from the symbol table to replace the local one. 264349cc55cSDimitry Andric // 265349cc55cSDimitry Andric // (See discussions/alternatives already considered on D107533) 266349cc55cSDimitry Andric if (!defined->isExternal()) 2674824e7fdSDimitry Andric if (Symbol *sym = symtab->find(defined->getName())) 26804eeddc0SDimitry Andric if (!sym->isLazy()) 2694824e7fdSDimitry Andric r.referent = s = sym; 270349cc55cSDimitry Andric } 271fe6060f1SDimitry Andric if (auto *undefined = dyn_cast<Undefined>(s)) { 27281ad6265SDimitry Andric treatUndefinedSymbol(*undefined, isec, r.offset); 273fe6060f1SDimitry Andric // treatUndefinedSymbol() can replace s with a DylibSymbol; re-check. 274fe6060f1SDimitry Andric if (isa<Undefined>(s)) 275fe6060f1SDimitry Andric continue; 276fe6060f1SDimitry Andric } 277349cc55cSDimitry Andric 278f3fd488fSDimitry Andric // Similar to canonicalizePersonality(), but we also register a GOT entry. 279fe6060f1SDimitry Andric if (auto *defined = dyn_cast<Defined>(s)) { 280fe6060f1SDimitry Andric // Check if we have created a synthetic symbol at the same address. 281fe6060f1SDimitry Andric Symbol *&personality = 282*0fca6ea1SDimitry Andric personalityTable[{defined->isec(), defined->value}]; 283fe6060f1SDimitry Andric if (personality == nullptr) { 284fe6060f1SDimitry Andric personality = defined; 285fe6060f1SDimitry Andric in.got->addEntry(defined); 286fe6060f1SDimitry Andric } else if (personality != defined) { 287fe6060f1SDimitry Andric r.referent = personality; 288fe6060f1SDimitry Andric } 289fe6060f1SDimitry Andric continue; 290fe6060f1SDimitry Andric } 291f3fd488fSDimitry Andric 292fe6060f1SDimitry Andric assert(isa<DylibSymbol>(s)); 293fe6060f1SDimitry Andric in.got->addEntry(s); 294fe6060f1SDimitry Andric continue; 295fe6060f1SDimitry Andric } 296fe6060f1SDimitry Andric 297fe6060f1SDimitry Andric if (auto *referentIsec = r.referent.dyn_cast<InputSection *>()) { 298fe6060f1SDimitry Andric assert(!isCoalescedWeak(referentIsec)); 299fe6060f1SDimitry Andric // Personality functions can be referenced via section relocations 300fe6060f1SDimitry Andric // if they live in the same object file. Create placeholder synthetic 301*0fca6ea1SDimitry Andric // symbols for them in the GOT. If the corresponding symbol is already 302*0fca6ea1SDimitry Andric // in the GOT, use that to avoid creating a duplicate entry. All GOT 303*0fca6ea1SDimitry Andric // entries needed by non-unwind sections will have already been added 304*0fca6ea1SDimitry Andric // by this point. 305fe6060f1SDimitry Andric Symbol *&s = personalityTable[{referentIsec, r.addend}]; 306fe6060f1SDimitry Andric if (s == nullptr) { 307*0fca6ea1SDimitry Andric Defined *const *gotEntry = 308*0fca6ea1SDimitry Andric llvm::find_if(referentIsec->symbols, [&](Defined const *d) { 309*0fca6ea1SDimitry Andric return d->value == static_cast<uint64_t>(r.addend) && 310*0fca6ea1SDimitry Andric d->isInGot(); 311*0fca6ea1SDimitry Andric }); 312*0fca6ea1SDimitry Andric if (gotEntry != referentIsec->symbols.end()) { 313*0fca6ea1SDimitry Andric s = *gotEntry; 314*0fca6ea1SDimitry Andric } else { 315*0fca6ea1SDimitry Andric // This runs after dead stripping, so the noDeadStrip argument does 316*0fca6ea1SDimitry Andric // not matter. 317fe6060f1SDimitry Andric s = make<Defined>("<internal>", /*file=*/nullptr, referentIsec, 318fe6060f1SDimitry Andric r.addend, /*size=*/0, /*isWeakDef=*/false, 319fe6060f1SDimitry Andric /*isExternal=*/false, /*isPrivateExtern=*/false, 32081ad6265SDimitry Andric /*includeInSymtab=*/true, 32106c3fb27SDimitry Andric /*isReferencedDynamically=*/false, 322fe6060f1SDimitry Andric /*noDeadStrip=*/false); 32381ad6265SDimitry Andric s->used = true; 324fe6060f1SDimitry Andric in.got->addEntry(s); 325fe6060f1SDimitry Andric } 326*0fca6ea1SDimitry Andric } 327fe6060f1SDimitry Andric r.referent = s; 328fe6060f1SDimitry Andric r.addend = 0; 329fe6060f1SDimitry Andric } 330fe6060f1SDimitry Andric } 331fe6060f1SDimitry Andric } 332fe6060f1SDimitry Andric 333f3fd488fSDimitry Andric Symbol *UnwindInfoSectionImpl::canonicalizePersonality(Symbol *personality) { 334f3fd488fSDimitry Andric if (auto *defined = dyn_cast_or_null<Defined>(personality)) { 335f3fd488fSDimitry Andric // Check if we have created a synthetic symbol at the same address. 336*0fca6ea1SDimitry Andric Symbol *&synth = personalityTable[{defined->isec(), defined->value}]; 337f3fd488fSDimitry Andric if (synth == nullptr) 338f3fd488fSDimitry Andric synth = defined; 339f3fd488fSDimitry Andric else if (synth != defined) 340f3fd488fSDimitry Andric return synth; 341f3fd488fSDimitry Andric } 342f3fd488fSDimitry Andric return personality; 343f3fd488fSDimitry Andric } 344f3fd488fSDimitry Andric 345fe6060f1SDimitry Andric // We need to apply the relocations to the pre-link compact unwind section 346fe6060f1SDimitry Andric // before converting it to post-link form. There should only be absolute 347fe6060f1SDimitry Andric // relocations here: since we are not emitting the pre-link CU section, there 348fe6060f1SDimitry Andric // is no source address to make a relative location meaningful. 34981ad6265SDimitry Andric void UnwindInfoSectionImpl::relocateCompactUnwind( 35081ad6265SDimitry Andric std::vector<CompactUnwindEntry> &cuEntries) { 35181ad6265SDimitry Andric parallelFor(0, symbolsVec.size(), [&](size_t i) { 35281ad6265SDimitry Andric CompactUnwindEntry &cu = cuEntries[i]; 353349cc55cSDimitry Andric const Defined *d = symbolsVec[i].second; 35481ad6265SDimitry Andric cu.functionAddress = d->getVA(); 355*0fca6ea1SDimitry Andric if (!d->unwindEntry()) 356349cc55cSDimitry Andric return; 357fe6060f1SDimitry Andric 35806c3fb27SDimitry Andric // If we have DWARF unwind info, create a slimmed-down CU entry that points 35906c3fb27SDimitry Andric // to it. 360*0fca6ea1SDimitry Andric if (d->unwindEntry()->getName() == section_names::ehFrame) { 36106c3fb27SDimitry Andric // The unwinder will look for the DWARF entry starting at the hint, 36206c3fb27SDimitry Andric // assuming the hint points to a valid CFI record start. If it 36306c3fb27SDimitry Andric // fails to find the record, it proceeds in a linear search through the 36406c3fb27SDimitry Andric // contiguous CFI records from the hint until the end of the section. 36506c3fb27SDimitry Andric // Ideally, in the case where the offset is too large to be encoded, we 36606c3fb27SDimitry Andric // would instead encode the largest possible offset to a valid CFI record, 36706c3fb27SDimitry Andric // but since we don't keep track of that, just encode zero -- the start of 36806c3fb27SDimitry Andric // the section is always the start of a CFI record. 36906c3fb27SDimitry Andric uint64_t dwarfOffsetHint = 370*0fca6ea1SDimitry Andric d->unwindEntry()->outSecOff <= DWARF_SECTION_OFFSET 371*0fca6ea1SDimitry Andric ? d->unwindEntry()->outSecOff 37206c3fb27SDimitry Andric : 0; 37306c3fb27SDimitry Andric cu.encoding = target->modeDwarfEncoding | dwarfOffsetHint; 374*0fca6ea1SDimitry Andric const FDE &fde = cast<ObjFile>(d->getFile())->fdes[d->unwindEntry()]; 37581ad6265SDimitry Andric cu.functionLength = fde.funcLength; 37606c3fb27SDimitry Andric // Omit the DWARF personality from compact-unwind entry so that we 37706c3fb27SDimitry Andric // don't need to encode it. 37806c3fb27SDimitry Andric cu.personality = nullptr; 37981ad6265SDimitry Andric cu.lsda = fde.lsda; 38081ad6265SDimitry Andric return; 38181ad6265SDimitry Andric } 38281ad6265SDimitry Andric 383*0fca6ea1SDimitry Andric assert(d->unwindEntry()->getName() == section_names::compactUnwind); 38481ad6265SDimitry Andric 385*0fca6ea1SDimitry Andric auto buf = 386*0fca6ea1SDimitry Andric reinterpret_cast<const uint8_t *>(d->unwindEntry()->data.data()) - 38781ad6265SDimitry Andric target->wordSize; 38881ad6265SDimitry Andric cu.functionLength = 38906c3fb27SDimitry Andric support::endian::read32le(buf + cuLayout.functionLengthOffset); 39006c3fb27SDimitry Andric cu.encoding = support::endian::read32le(buf + cuLayout.encodingOffset); 391*0fca6ea1SDimitry Andric for (const Reloc &r : d->unwindEntry()->relocs) { 39206c3fb27SDimitry Andric if (r.offset == cuLayout.personalityOffset) 39381ad6265SDimitry Andric cu.personality = r.referent.get<Symbol *>(); 39406c3fb27SDimitry Andric else if (r.offset == cuLayout.lsdaOffset) 39506c3fb27SDimitry Andric cu.lsda = r.getReferentInputSection(); 396fe6060f1SDimitry Andric } 397349cc55cSDimitry Andric }); 398fe6060f1SDimitry Andric } 399fe6060f1SDimitry Andric 400fe6060f1SDimitry Andric // There should only be a handful of unique personality pointers, so we can 401fe6060f1SDimitry Andric // encode them as 2-bit indices into a small array. 40281ad6265SDimitry Andric void UnwindInfoSectionImpl::encodePersonalities() { 403349cc55cSDimitry Andric for (size_t idx : cuIndices) { 40481ad6265SDimitry Andric CompactUnwindEntry &cu = cuEntries[idx]; 40581ad6265SDimitry Andric if (cu.personality == nullptr) 406fe6060f1SDimitry Andric continue; 407fe6060f1SDimitry Andric // Linear search is fast enough for a small array. 408349cc55cSDimitry Andric auto it = find(personalities, cu.personality); 409fe6060f1SDimitry Andric uint32_t personalityIndex; // 1-based index 410fe6060f1SDimitry Andric if (it != personalities.end()) { 411fe6060f1SDimitry Andric personalityIndex = std::distance(personalities.begin(), it) + 1; 412fe6060f1SDimitry Andric } else { 413349cc55cSDimitry Andric personalities.push_back(cu.personality); 414fe6060f1SDimitry Andric personalityIndex = personalities.size(); 415fe6060f1SDimitry Andric } 416349cc55cSDimitry Andric cu.encoding |= 41706c3fb27SDimitry Andric personalityIndex << llvm::countr_zero( 418fe6060f1SDimitry Andric static_cast<compact_unwind_encoding_t>(UNWIND_PERSONALITY_MASK)); 419fe6060f1SDimitry Andric } 420fe6060f1SDimitry Andric if (personalities.size() > 3) 42181ad6265SDimitry Andric error("too many personalities (" + Twine(personalities.size()) + 422fe6060f1SDimitry Andric ") for compact unwind to encode"); 423fe6060f1SDimitry Andric } 424fe6060f1SDimitry Andric 425fe6060f1SDimitry Andric static bool canFoldEncoding(compact_unwind_encoding_t encoding) { 426fe6060f1SDimitry Andric // From compact_unwind_encoding.h: 427fe6060f1SDimitry Andric // UNWIND_X86_64_MODE_STACK_IND: 428fe6060f1SDimitry Andric // A "frameless" (RBP not used as frame pointer) function large constant 429fe6060f1SDimitry Andric // stack size. This case is like the previous, except the stack size is too 430fe6060f1SDimitry Andric // large to encode in the compact unwind encoding. Instead it requires that 431fe6060f1SDimitry Andric // the function contains "subq $nnnnnnnn,RSP" in its prolog. The compact 432fe6060f1SDimitry Andric // encoding contains the offset to the nnnnnnnn value in the function in 433fe6060f1SDimitry Andric // UNWIND_X86_64_FRAMELESS_STACK_SIZE. 434fe6060f1SDimitry Andric // Since this means the unwinder has to look at the `subq` in the function 435fe6060f1SDimitry Andric // of the unwind info's unwind address, two functions that have identical 436fe6060f1SDimitry Andric // unwind info can't be folded if it's using this encoding since both 437fe6060f1SDimitry Andric // entries need unique addresses. 43861cfbce3SDimitry Andric static_assert(static_cast<uint32_t>(UNWIND_X86_64_MODE_STACK_IND) == 439bdd1243dSDimitry Andric static_cast<uint32_t>(UNWIND_X86_MODE_STACK_IND)); 440fe6060f1SDimitry Andric if ((target->cpuType == CPU_TYPE_X86_64 || target->cpuType == CPU_TYPE_X86) && 441bdd1243dSDimitry Andric (encoding & UNWIND_MODE_MASK) == UNWIND_X86_64_MODE_STACK_IND) { 442fe6060f1SDimitry Andric // FIXME: Consider passing in the two function addresses and getting 443fe6060f1SDimitry Andric // their two stack sizes off the `subq` and only returning false if they're 444fe6060f1SDimitry Andric // actually different. 445fe6060f1SDimitry Andric return false; 446fe6060f1SDimitry Andric } 447fe6060f1SDimitry Andric return true; 448e8d8bef9SDimitry Andric } 449e8d8bef9SDimitry Andric 450e8d8bef9SDimitry Andric // Scan the __LD,__compact_unwind entries and compute the space needs of 4511fd87a68SDimitry Andric // __TEXT,__unwind_info and __TEXT,__eh_frame. 45281ad6265SDimitry Andric void UnwindInfoSectionImpl::finalize() { 453349cc55cSDimitry Andric if (symbols.empty()) 454e8d8bef9SDimitry Andric return; 455e8d8bef9SDimitry Andric 456e8d8bef9SDimitry Andric // At this point, the address space for __TEXT,__text has been 457e8d8bef9SDimitry Andric // assigned, so we can relocate the __LD,__compact_unwind entries 458e8d8bef9SDimitry Andric // into a temporary buffer. Relocation is necessary in order to sort 459e8d8bef9SDimitry Andric // the CU entries by function address. Sorting is necessary so that 4606246ae0bSDimitry Andric // we can fold adjacent CU entries with identical encoding+personality 4616246ae0bSDimitry Andric // and without any LSDA. Folding is necessary because it reduces the 4626246ae0bSDimitry Andric // number of CU entries by as much as 3 orders of magnitude! 463349cc55cSDimitry Andric cuEntries.resize(symbols.size()); 464349cc55cSDimitry Andric // The "map" part of the symbols MapVector was only needed for deduplication 465349cc55cSDimitry Andric // in addSymbol(). Now that we are done adding, move the contents to a plain 466349cc55cSDimitry Andric // std::vector for indexed access. 467349cc55cSDimitry Andric symbolsVec = symbols.takeVector(); 468349cc55cSDimitry Andric relocateCompactUnwind(cuEntries); 469e8d8bef9SDimitry Andric 470e8d8bef9SDimitry Andric // Rather than sort & fold the 32-byte entries directly, we create a 471349cc55cSDimitry Andric // vector of indices to entries and sort & fold that instead. 472349cc55cSDimitry Andric cuIndices.resize(cuEntries.size()); 473349cc55cSDimitry Andric std::iota(cuIndices.begin(), cuIndices.end(), 0); 474349cc55cSDimitry Andric llvm::sort(cuIndices, [&](size_t a, size_t b) { 475349cc55cSDimitry Andric return cuEntries[a].functionAddress < cuEntries[b].functionAddress; 476e8d8bef9SDimitry Andric }); 477e8d8bef9SDimitry Andric 478bdd1243dSDimitry Andric // Record the ending boundary before we fold the entries. 479bdd1243dSDimitry Andric cueEndBoundary = cuEntries[cuIndices.back()].functionAddress + 480bdd1243dSDimitry Andric cuEntries[cuIndices.back()].functionLength; 481bdd1243dSDimitry Andric 4826246ae0bSDimitry Andric // Fold adjacent entries with matching encoding+personality and without LSDA 483349cc55cSDimitry Andric // We use three iterators on the same cuIndices to fold in-situ: 484e8d8bef9SDimitry Andric // (1) `foldBegin` is the first of a potential sequence of matching entries 485e8d8bef9SDimitry Andric // (2) `foldEnd` is the first non-matching entry after `foldBegin`. 486e8d8bef9SDimitry Andric // The semi-open interval [ foldBegin .. foldEnd ) contains a range 487e8d8bef9SDimitry Andric // entries that can be folded into a single entry and written to ... 488e8d8bef9SDimitry Andric // (3) `foldWrite` 489349cc55cSDimitry Andric auto foldWrite = cuIndices.begin(); 490349cc55cSDimitry Andric for (auto foldBegin = cuIndices.begin(); foldBegin < cuIndices.end();) { 491e8d8bef9SDimitry Andric auto foldEnd = foldBegin; 4926246ae0bSDimitry Andric // Common LSDA encodings (e.g. for C++ and Objective-C) contain offsets from 4936246ae0bSDimitry Andric // a base address. The base address is normally not contained directly in 4946246ae0bSDimitry Andric // the LSDA, and in that case, the personality function treats the starting 4956246ae0bSDimitry Andric // address of the function (which is computed by the unwinder) as the base 4966246ae0bSDimitry Andric // address and interprets the LSDA accordingly. The unwinder computes the 4976246ae0bSDimitry Andric // starting address of a function as the address associated with its CU 4986246ae0bSDimitry Andric // entry. For this reason, we cannot fold adjacent entries if they have an 4996246ae0bSDimitry Andric // LSDA, because folding would make the unwinder compute the wrong starting 5006246ae0bSDimitry Andric // address for the functions with the folded entries, which in turn would 5016246ae0bSDimitry Andric // cause the personality function to misinterpret the LSDA for those 5026246ae0bSDimitry Andric // functions. In the very rare case where the base address is encoded 5036246ae0bSDimitry Andric // directly in the LSDA, two functions at different addresses would 5046246ae0bSDimitry Andric // necessarily have different LSDAs, so their CU entries would not have been 5056246ae0bSDimitry Andric // folded anyway. 506349cc55cSDimitry Andric while (++foldEnd < cuIndices.end() && 507349cc55cSDimitry Andric cuEntries[*foldBegin].encoding == cuEntries[*foldEnd].encoding && 5086246ae0bSDimitry Andric !cuEntries[*foldBegin].lsda && !cuEntries[*foldEnd].lsda && 5096246ae0bSDimitry Andric // If we've gotten to this point, we don't have an LSDA, which should 5106246ae0bSDimitry Andric // also imply that we don't have a personality function, since in all 5116246ae0bSDimitry Andric // likelihood a personality function needs the LSDA to do anything 5126246ae0bSDimitry Andric // useful. It can be technically valid to have a personality function 5136246ae0bSDimitry Andric // and no LSDA though (e.g. the C++ personality __gxx_personality_v0 5146246ae0bSDimitry Andric // is just a no-op without LSDA), so we still check for personality 5156246ae0bSDimitry Andric // function equivalence to handle that case. 516349cc55cSDimitry Andric cuEntries[*foldBegin].personality == 517349cc55cSDimitry Andric cuEntries[*foldEnd].personality && 51881ad6265SDimitry Andric canFoldEncoding(cuEntries[*foldEnd].encoding)) 51981ad6265SDimitry Andric ; 520e8d8bef9SDimitry Andric *foldWrite++ = *foldBegin; 521e8d8bef9SDimitry Andric foldBegin = foldEnd; 522e8d8bef9SDimitry Andric } 523349cc55cSDimitry Andric cuIndices.erase(foldWrite, cuIndices.end()); 524e8d8bef9SDimitry Andric 525349cc55cSDimitry Andric encodePersonalities(); 526fe6060f1SDimitry Andric 527e8d8bef9SDimitry Andric // Count frequencies of the folded encodings 528e8d8bef9SDimitry Andric EncodingMap encodingFrequencies; 529349cc55cSDimitry Andric for (size_t idx : cuIndices) 530349cc55cSDimitry Andric encodingFrequencies[cuEntries[idx].encoding]++; 531e8d8bef9SDimitry Andric 532e8d8bef9SDimitry Andric // Make a vector of encodings, sorted by descending frequency 533e8d8bef9SDimitry Andric for (const auto &frequency : encodingFrequencies) 534e8d8bef9SDimitry Andric commonEncodings.emplace_back(frequency); 535fe6060f1SDimitry Andric llvm::sort(commonEncodings, 536e8d8bef9SDimitry Andric [](const std::pair<compact_unwind_encoding_t, size_t> &a, 537e8d8bef9SDimitry Andric const std::pair<compact_unwind_encoding_t, size_t> &b) { 538e8d8bef9SDimitry Andric if (a.second == b.second) 539e8d8bef9SDimitry Andric // When frequencies match, secondarily sort on encoding 540e8d8bef9SDimitry Andric // to maintain parity with validate-unwind-info.py 541e8d8bef9SDimitry Andric return a.first > b.first; 542e8d8bef9SDimitry Andric return a.second > b.second; 543e8d8bef9SDimitry Andric }); 544e8d8bef9SDimitry Andric 545e8d8bef9SDimitry Andric // Truncate the vector to 127 elements. 546e8d8bef9SDimitry Andric // Common encoding indexes are limited to 0..126, while encoding 547e8d8bef9SDimitry Andric // indexes 127..255 are local to each second-level page 548e8d8bef9SDimitry Andric if (commonEncodings.size() > COMMON_ENCODINGS_MAX) 549e8d8bef9SDimitry Andric commonEncodings.resize(COMMON_ENCODINGS_MAX); 550e8d8bef9SDimitry Andric 551e8d8bef9SDimitry Andric // Create a map from encoding to common-encoding-table index 552e8d8bef9SDimitry Andric for (size_t i = 0; i < commonEncodings.size(); i++) 553e8d8bef9SDimitry Andric commonEncodingIndexes[commonEncodings[i].first] = i; 554e8d8bef9SDimitry Andric 555e8d8bef9SDimitry Andric // Split folded encodings into pages, where each page is limited by ... 556e8d8bef9SDimitry Andric // (a) 4 KiB capacity 557e8d8bef9SDimitry Andric // (b) 24-bit difference between first & final function address 558e8d8bef9SDimitry Andric // (c) 8-bit compact-encoding-table index, 559e8d8bef9SDimitry Andric // for which 0..126 references the global common-encodings table, 560e8d8bef9SDimitry Andric // and 127..255 references a local per-second-level-page table. 561e8d8bef9SDimitry Andric // First we try the compact format and determine how many entries fit. 562e8d8bef9SDimitry Andric // If more entries fit in the regular format, we use that. 563349cc55cSDimitry Andric for (size_t i = 0; i < cuIndices.size();) { 564349cc55cSDimitry Andric size_t idx = cuIndices[i]; 565e8d8bef9SDimitry Andric secondLevelPages.emplace_back(); 566fe6060f1SDimitry Andric SecondLevelPage &page = secondLevelPages.back(); 567e8d8bef9SDimitry Andric page.entryIndex = i; 568753f127fSDimitry Andric uint64_t functionAddressMax = 569349cc55cSDimitry Andric cuEntries[idx].functionAddress + COMPRESSED_ENTRY_FUNC_OFFSET_MASK; 570e8d8bef9SDimitry Andric size_t n = commonEncodings.size(); 571e8d8bef9SDimitry Andric size_t wordsRemaining = 572e8d8bef9SDimitry Andric SECOND_LEVEL_PAGE_WORDS - 573e8d8bef9SDimitry Andric sizeof(unwind_info_compressed_second_level_page_header) / 574e8d8bef9SDimitry Andric sizeof(uint32_t); 575349cc55cSDimitry Andric while (wordsRemaining >= 1 && i < cuIndices.size()) { 576349cc55cSDimitry Andric idx = cuIndices[i]; 57781ad6265SDimitry Andric const CompactUnwindEntry *cuPtr = &cuEntries[idx]; 57806c3fb27SDimitry Andric if (cuPtr->functionAddress >= functionAddressMax) 579e8d8bef9SDimitry Andric break; 58006c3fb27SDimitry Andric if (commonEncodingIndexes.count(cuPtr->encoding) || 581e8d8bef9SDimitry Andric page.localEncodingIndexes.count(cuPtr->encoding)) { 582e8d8bef9SDimitry Andric i++; 583e8d8bef9SDimitry Andric wordsRemaining--; 584e8d8bef9SDimitry Andric } else if (wordsRemaining >= 2 && n < COMPACT_ENCODINGS_MAX) { 585e8d8bef9SDimitry Andric page.localEncodings.emplace_back(cuPtr->encoding); 586e8d8bef9SDimitry Andric page.localEncodingIndexes[cuPtr->encoding] = n++; 587e8d8bef9SDimitry Andric i++; 588e8d8bef9SDimitry Andric wordsRemaining -= 2; 589e8d8bef9SDimitry Andric } else { 590e8d8bef9SDimitry Andric break; 591e8d8bef9SDimitry Andric } 592e8d8bef9SDimitry Andric } 593e8d8bef9SDimitry Andric page.entryCount = i - page.entryIndex; 594e8d8bef9SDimitry Andric 595bdd1243dSDimitry Andric // If this is not the final page, see if it's possible to fit more entries 596bdd1243dSDimitry Andric // by using the regular format. This can happen when there are many unique 597bdd1243dSDimitry Andric // encodings, and we saturated the local encoding table early. 598349cc55cSDimitry Andric if (i < cuIndices.size() && 599e8d8bef9SDimitry Andric page.entryCount < REGULAR_SECOND_LEVEL_ENTRIES_MAX) { 600e8d8bef9SDimitry Andric page.kind = UNWIND_SECOND_LEVEL_REGULAR; 601e8d8bef9SDimitry Andric page.entryCount = std::min(REGULAR_SECOND_LEVEL_ENTRIES_MAX, 602349cc55cSDimitry Andric cuIndices.size() - page.entryIndex); 603e8d8bef9SDimitry Andric i = page.entryIndex + page.entryCount; 604e8d8bef9SDimitry Andric } else { 605e8d8bef9SDimitry Andric page.kind = UNWIND_SECOND_LEVEL_COMPRESSED; 606e8d8bef9SDimitry Andric } 607e8d8bef9SDimitry Andric } 608e8d8bef9SDimitry Andric 609349cc55cSDimitry Andric for (size_t idx : cuIndices) { 610349cc55cSDimitry Andric lsdaIndex[idx] = entriesWithLsda.size(); 61181ad6265SDimitry Andric if (cuEntries[idx].lsda) 612349cc55cSDimitry Andric entriesWithLsda.push_back(idx); 613fe6060f1SDimitry Andric } 614fe6060f1SDimitry Andric 615e8d8bef9SDimitry Andric // compute size of __TEXT,__unwind_info section 616349cc55cSDimitry Andric level2PagesOffset = sizeof(unwind_info_section_header) + 617e8d8bef9SDimitry Andric commonEncodings.size() * sizeof(uint32_t) + 618e8d8bef9SDimitry Andric personalities.size() * sizeof(uint32_t) + 619e8d8bef9SDimitry Andric // The extra second-level-page entry is for the sentinel 620e8d8bef9SDimitry Andric (secondLevelPages.size() + 1) * 621e8d8bef9SDimitry Andric sizeof(unwind_info_section_header_index_entry) + 622349cc55cSDimitry Andric entriesWithLsda.size() * 623349cc55cSDimitry Andric sizeof(unwind_info_section_header_lsda_index_entry); 624e8d8bef9SDimitry Andric unwindInfoSize = 625e8d8bef9SDimitry Andric level2PagesOffset + secondLevelPages.size() * SECOND_LEVEL_PAGE_BYTES; 626e8d8bef9SDimitry Andric } 627e8d8bef9SDimitry Andric 628e8d8bef9SDimitry Andric // All inputs are relocated and output addresses are known, so write! 629e8d8bef9SDimitry Andric 63081ad6265SDimitry Andric void UnwindInfoSectionImpl::writeTo(uint8_t *buf) const { 631349cc55cSDimitry Andric assert(!cuIndices.empty() && "call only if there is unwind info"); 632fe6060f1SDimitry Andric 633e8d8bef9SDimitry Andric // section header 634e8d8bef9SDimitry Andric auto *uip = reinterpret_cast<unwind_info_section_header *>(buf); 635e8d8bef9SDimitry Andric uip->version = 1; 636e8d8bef9SDimitry Andric uip->commonEncodingsArraySectionOffset = sizeof(unwind_info_section_header); 637e8d8bef9SDimitry Andric uip->commonEncodingsArrayCount = commonEncodings.size(); 638e8d8bef9SDimitry Andric uip->personalityArraySectionOffset = 639e8d8bef9SDimitry Andric uip->commonEncodingsArraySectionOffset + 640e8d8bef9SDimitry Andric (uip->commonEncodingsArrayCount * sizeof(uint32_t)); 641e8d8bef9SDimitry Andric uip->personalityArrayCount = personalities.size(); 642e8d8bef9SDimitry Andric uip->indexSectionOffset = uip->personalityArraySectionOffset + 643e8d8bef9SDimitry Andric (uip->personalityArrayCount * sizeof(uint32_t)); 644e8d8bef9SDimitry Andric uip->indexCount = secondLevelPages.size() + 1; 645e8d8bef9SDimitry Andric 646e8d8bef9SDimitry Andric // Common encodings 647e8d8bef9SDimitry Andric auto *i32p = reinterpret_cast<uint32_t *>(&uip[1]); 648e8d8bef9SDimitry Andric for (const auto &encoding : commonEncodings) 649e8d8bef9SDimitry Andric *i32p++ = encoding.first; 650e8d8bef9SDimitry Andric 651e8d8bef9SDimitry Andric // Personalities 65281ad6265SDimitry Andric for (const Symbol *personality : personalities) 65381ad6265SDimitry Andric *i32p++ = personality->getGotVA() - in.header->addr; 654e8d8bef9SDimitry Andric 655bdd1243dSDimitry Andric // FIXME: LD64 checks and warns aboutgaps or overlapse in cuEntries address 656bdd1243dSDimitry Andric // ranges. We should do the same too 657bdd1243dSDimitry Andric 658e8d8bef9SDimitry Andric // Level-1 index 659e8d8bef9SDimitry Andric uint32_t lsdaOffset = 660e8d8bef9SDimitry Andric uip->indexSectionOffset + 661e8d8bef9SDimitry Andric uip->indexCount * sizeof(unwind_info_section_header_index_entry); 662e8d8bef9SDimitry Andric uint64_t l2PagesOffset = level2PagesOffset; 663e8d8bef9SDimitry Andric auto *iep = reinterpret_cast<unwind_info_section_header_index_entry *>(i32p); 664e8d8bef9SDimitry Andric for (const SecondLevelPage &page : secondLevelPages) { 665349cc55cSDimitry Andric size_t idx = cuIndices[page.entryIndex]; 666349cc55cSDimitry Andric iep->functionOffset = cuEntries[idx].functionAddress - in.header->addr; 667e8d8bef9SDimitry Andric iep->secondLevelPagesSectionOffset = l2PagesOffset; 668fe6060f1SDimitry Andric iep->lsdaIndexArraySectionOffset = 669349cc55cSDimitry Andric lsdaOffset + lsdaIndex.lookup(idx) * 670fe6060f1SDimitry Andric sizeof(unwind_info_section_header_lsda_index_entry); 671e8d8bef9SDimitry Andric iep++; 672e8d8bef9SDimitry Andric l2PagesOffset += SECOND_LEVEL_PAGE_BYTES; 673e8d8bef9SDimitry Andric } 674e8d8bef9SDimitry Andric // Level-1 sentinel 675bdd1243dSDimitry Andric // XXX(vyng): Note that LD64 adds +1 here. 676bdd1243dSDimitry Andric // Unsure whether it's a bug or it's their workaround for something else. 677bdd1243dSDimitry Andric // See comments from https://reviews.llvm.org/D138320. 678bdd1243dSDimitry Andric iep->functionOffset = cueEndBoundary - in.header->addr; 679e8d8bef9SDimitry Andric iep->secondLevelPagesSectionOffset = 0; 680fe6060f1SDimitry Andric iep->lsdaIndexArraySectionOffset = 681349cc55cSDimitry Andric lsdaOffset + entriesWithLsda.size() * 682349cc55cSDimitry Andric sizeof(unwind_info_section_header_lsda_index_entry); 683e8d8bef9SDimitry Andric iep++; 684e8d8bef9SDimitry Andric 685e8d8bef9SDimitry Andric // LSDAs 686349cc55cSDimitry Andric auto *lep = 687349cc55cSDimitry Andric reinterpret_cast<unwind_info_section_header_lsda_index_entry *>(iep); 688349cc55cSDimitry Andric for (size_t idx : entriesWithLsda) { 68981ad6265SDimitry Andric const CompactUnwindEntry &cu = cuEntries[idx]; 69081ad6265SDimitry Andric lep->lsdaOffset = cu.lsda->getVA(/*off=*/0) - in.header->addr; 691349cc55cSDimitry Andric lep->functionOffset = cu.functionAddress - in.header->addr; 692349cc55cSDimitry Andric lep++; 693349cc55cSDimitry Andric } 694e8d8bef9SDimitry Andric 695e8d8bef9SDimitry Andric // Level-2 pages 696349cc55cSDimitry Andric auto *pp = reinterpret_cast<uint32_t *>(lep); 697e8d8bef9SDimitry Andric for (const SecondLevelPage &page : secondLevelPages) { 698e8d8bef9SDimitry Andric if (page.kind == UNWIND_SECOND_LEVEL_COMPRESSED) { 699e8d8bef9SDimitry Andric uintptr_t functionAddressBase = 700349cc55cSDimitry Andric cuEntries[cuIndices[page.entryIndex]].functionAddress; 701e8d8bef9SDimitry Andric auto *p2p = 702e8d8bef9SDimitry Andric reinterpret_cast<unwind_info_compressed_second_level_page_header *>( 703e8d8bef9SDimitry Andric pp); 704e8d8bef9SDimitry Andric p2p->kind = page.kind; 705e8d8bef9SDimitry Andric p2p->entryPageOffset = 706e8d8bef9SDimitry Andric sizeof(unwind_info_compressed_second_level_page_header); 707e8d8bef9SDimitry Andric p2p->entryCount = page.entryCount; 708e8d8bef9SDimitry Andric p2p->encodingsPageOffset = 709e8d8bef9SDimitry Andric p2p->entryPageOffset + p2p->entryCount * sizeof(uint32_t); 710e8d8bef9SDimitry Andric p2p->encodingsCount = page.localEncodings.size(); 711e8d8bef9SDimitry Andric auto *ep = reinterpret_cast<uint32_t *>(&p2p[1]); 712e8d8bef9SDimitry Andric for (size_t i = 0; i < page.entryCount; i++) { 71381ad6265SDimitry Andric const CompactUnwindEntry &cue = 714349cc55cSDimitry Andric cuEntries[cuIndices[page.entryIndex + i]]; 715349cc55cSDimitry Andric auto it = commonEncodingIndexes.find(cue.encoding); 716e8d8bef9SDimitry Andric if (it == commonEncodingIndexes.end()) 717349cc55cSDimitry Andric it = page.localEncodingIndexes.find(cue.encoding); 718e8d8bef9SDimitry Andric *ep++ = (it->second << COMPRESSED_ENTRY_FUNC_OFFSET_BITS) | 719349cc55cSDimitry Andric (cue.functionAddress - functionAddressBase); 720e8d8bef9SDimitry Andric } 721349cc55cSDimitry Andric if (!page.localEncodings.empty()) 722e8d8bef9SDimitry Andric memcpy(ep, page.localEncodings.data(), 723e8d8bef9SDimitry Andric page.localEncodings.size() * sizeof(uint32_t)); 724e8d8bef9SDimitry Andric } else { 725e8d8bef9SDimitry Andric auto *p2p = 726e8d8bef9SDimitry Andric reinterpret_cast<unwind_info_regular_second_level_page_header *>(pp); 727e8d8bef9SDimitry Andric p2p->kind = page.kind; 728e8d8bef9SDimitry Andric p2p->entryPageOffset = 729e8d8bef9SDimitry Andric sizeof(unwind_info_regular_second_level_page_header); 730e8d8bef9SDimitry Andric p2p->entryCount = page.entryCount; 731e8d8bef9SDimitry Andric auto *ep = reinterpret_cast<uint32_t *>(&p2p[1]); 732e8d8bef9SDimitry Andric for (size_t i = 0; i < page.entryCount; i++) { 73381ad6265SDimitry Andric const CompactUnwindEntry &cue = 734349cc55cSDimitry Andric cuEntries[cuIndices[page.entryIndex + i]]; 735349cc55cSDimitry Andric *ep++ = cue.functionAddress; 736349cc55cSDimitry Andric *ep++ = cue.encoding; 737e8d8bef9SDimitry Andric } 738e8d8bef9SDimitry Andric } 739e8d8bef9SDimitry Andric pp += SECOND_LEVEL_PAGE_WORDS; 740e8d8bef9SDimitry Andric } 741e8d8bef9SDimitry Andric } 742fe6060f1SDimitry Andric 743fe6060f1SDimitry Andric UnwindInfoSection *macho::makeUnwindInfoSection() { 74481ad6265SDimitry Andric return make<UnwindInfoSectionImpl>(); 745fe6060f1SDimitry Andric } 746