1 //===- UnwindInfoSection.h ------------------------------------------------===// 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 #ifndef LLD_MACHO_UNWIND_INFO_H 10 #define LLD_MACHO_UNWIND_INFO_H 11 12 #include "MergedOutputSection.h" 13 #include "SyntheticSections.h" 14 15 #include "mach-o/compact_unwind_encoding.h" 16 #include "llvm/ADT/DenseMap.h" 17 18 #include <vector> 19 20 // In 2020, we mostly care about 64-bit targets: x86_64 and arm64 21 struct CompactUnwindEntry64 { 22 uint64_t functionAddress; 23 uint32_t functionLength; 24 compact_unwind_encoding_t encoding; 25 uint64_t personality; 26 uint64_t lsda; 27 }; 28 29 // FIXME(gkm): someday we might care about 32-bit targets: x86 & arm 30 struct CompactUnwindEntry32 { 31 uint32_t functionAddress; 32 uint32_t functionLength; 33 compact_unwind_encoding_t encoding; 34 uint32_t personality; 35 uint32_t lsda; 36 }; 37 38 namespace lld { 39 namespace macho { 40 41 class UnwindInfoSection : public SyntheticSection { 42 public: 43 UnwindInfoSection(); getSize()44 uint64_t getSize() const override { return unwindInfoSize; } 45 bool isNeeded() const override; 46 void finalize() override; 47 void writeTo(uint8_t *buf) const override; setCompactUnwindSection(MergedOutputSection * cuSection)48 void setCompactUnwindSection(MergedOutputSection *cuSection) { 49 compactUnwindSection = cuSection; 50 } 51 52 private: 53 std::vector<std::pair<compact_unwind_encoding_t, size_t>> commonEncodings; 54 std::vector<uint32_t> personalities; 55 std::vector<unwind_info_section_header_lsda_index_entry> lsdaEntries; 56 std::vector<CompactUnwindEntry64> cuVector; 57 std::vector<const CompactUnwindEntry64 *> cuPtrVector; 58 std::vector<std::vector<const CompactUnwindEntry64 *>::const_iterator> 59 pageBounds; 60 MergedOutputSection *compactUnwindSection = nullptr; 61 uint64_t level2PagesOffset = 0; 62 uint64_t unwindInfoSize = 0; 63 }; 64 65 #define UNWIND_INFO_COMMON_ENCODINGS_MAX 127 66 67 #define UNWIND_INFO_SECOND_LEVEL_PAGE_SIZE 4096 68 #define UNWIND_INFO_REGULAR_SECOND_LEVEL_ENTRIES_MAX \ 69 ((UNWIND_INFO_SECOND_LEVEL_PAGE_SIZE - \ 70 sizeof(unwind_info_regular_second_level_page_header)) / \ 71 sizeof(unwind_info_regular_second_level_entry)) 72 #define UNWIND_INFO_COMPRESSED_SECOND_LEVEL_ENTRIES_MAX \ 73 ((UNWIND_INFO_SECOND_LEVEL_PAGE_SIZE - \ 74 sizeof(unwind_info_compressed_second_level_page_header)) / \ 75 sizeof(uint32_t)) 76 77 #define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET_BITS 24 78 #define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET_MASK \ 79 UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(~0) 80 81 } // namespace macho 82 } // namespace lld 83 84 #endif 85