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();
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;
48   void setCompactUnwindSection(MergedOutputSection *cuSection) {
49     compactUnwindSection = cuSection;
50   }
51 
52   using EncodingMap = llvm::DenseMap<compact_unwind_encoding_t, size_t>;
53 
54   struct SecondLevelPage {
55     uint32_t kind;
56     size_t entryIndex;
57     size_t entryCount;
58     size_t byteCount;
59     std::vector<compact_unwind_encoding_t> localEncodings;
60     EncodingMap localEncodingIndexes;
61   };
62 
63 private:
64   std::vector<std::pair<compact_unwind_encoding_t, size_t>> commonEncodings;
65   EncodingMap commonEncodingIndexes;
66   std::vector<uint32_t> personalities;
67   std::vector<unwind_info_section_header_lsda_index_entry> lsdaEntries;
68   std::vector<CompactUnwindEntry64> cuVector;
69   std::vector<const CompactUnwindEntry64 *> cuPtrVector;
70   std::vector<SecondLevelPage> secondLevelPages;
71   MergedOutputSection *compactUnwindSection = nullptr;
72   uint64_t level2PagesOffset = 0;
73   uint64_t unwindInfoSize = 0;
74 };
75 
76 } // namespace macho
77 } // namespace lld
78 
79 #endif
80