]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/Symbol/CompactUnwindInfo.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / include / lldb / Symbol / CompactUnwindInfo.h
1 //===-- CompactUnwindInfo.h -------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef liblldb_CompactUnwindInfo_h_
11 #define liblldb_CompactUnwindInfo_h_
12
13 #include <mutex>
14 #include <vector>
15
16 #include "lldb/Core/RangeMap.h"
17 #include "lldb/Symbol/ObjectFile.h"
18 #include "lldb/Symbol/UnwindPlan.h"
19 #include "lldb/Utility/DataExtractor.h"
20 #include "lldb/lldb-private.h"
21
22 namespace lldb_private {
23
24 // Compact Unwind info is an unwind format used on Darwin.  The unwind
25 // instructions for typical compiler-generated functions can be expressed in a
26 // 32-bit encoding. The format includes a two-level index so the unwind
27 // information for a function can be found by two binary searches in the
28 // section.  It can represent both stack frames that use a frame-pointer
29 // register and frameless functions, on i386/x86_64 for instance.  When a
30 // function is too complex to be represented in the compact unwind format, it
31 // calls out to eh_frame unwind instructions.
32
33 // On Mac OS X / iOS, a function will have either a compact unwind
34 // representation or an eh_frame representation.  If lldb is going to benefit
35 // from the compiler's description about saved register locations, it must be
36 // able to read both sources of information.
37
38 class CompactUnwindInfo {
39 public:
40   CompactUnwindInfo(ObjectFile &objfile, lldb::SectionSP &section);
41
42   ~CompactUnwindInfo();
43
44   bool GetUnwindPlan(Target &target, Address addr, UnwindPlan &unwind_plan);
45
46   bool IsValid(const lldb::ProcessSP &process_sp);
47
48 private:
49   // The top level index entries of the compact unwind info
50   //   (internal representation of struct
51   //   unwind_info_section_header_index_entry)
52   // There are relatively few of these (one per 500/1000 functions, depending
53   // on format) so creating them on first scan will not be too costly.
54   struct UnwindIndex {
55     uint32_t function_offset; // The offset of the first function covered by
56                               // this index
57     uint32_t second_level; // The offset (inside unwind_info sect) to the second
58                            // level page for this index
59     // (either UNWIND_SECOND_LEVEL_REGULAR or UNWIND_SECOND_LEVEL_COMPRESSED)
60     uint32_t lsda_array_start; // The offset (inside unwind_info sect) LSDA
61                                // array for this index
62     uint32_t lsda_array_end; // The offset to the LSDA array for the NEXT index
63     bool sentinal_entry; // There is an empty index at the end which provides
64                          // the upper bound of
65     // function addresses that are described
66
67     UnwindIndex()
68         : function_offset(0), second_level(0), lsda_array_start(0),
69           lsda_array_end(0), sentinal_entry(false) {}
70
71     bool operator<(const CompactUnwindInfo::UnwindIndex &rhs) const {
72       return function_offset < rhs.function_offset;
73     }
74
75     bool operator==(const CompactUnwindInfo::UnwindIndex &rhs) const {
76       return function_offset == rhs.function_offset;
77     }
78   };
79
80   // An internal object used to store the information we retrieve about a
81   // function -- the encoding bits and possibly the LSDA/personality function.
82   struct FunctionInfo {
83     uint32_t encoding;    // compact encoding 32-bit value for this function
84     Address lsda_address; // the address of the LSDA data for this function
85     Address personality_ptr_address; // the address where the personality
86                                      // routine addr can be found
87
88     uint32_t valid_range_offset_start; // first offset that this encoding is
89                                        // valid for (start of the function)
90     uint32_t
91         valid_range_offset_end; // the offset of the start of the next function
92     FunctionInfo()
93         : encoding(0), lsda_address(), personality_ptr_address(),
94           valid_range_offset_start(0), valid_range_offset_end(0) {}
95   };
96
97   struct UnwindHeader {
98     uint32_t version;
99     uint32_t common_encodings_array_offset;
100     uint32_t common_encodings_array_count;
101     uint32_t personality_array_offset;
102     uint32_t personality_array_count;
103
104     UnwindHeader()
105         : common_encodings_array_offset(0), common_encodings_array_count(0),
106           personality_array_offset(0), personality_array_count(0) {}
107   };
108
109   void ScanIndex(const lldb::ProcessSP &process_sp);
110
111   bool GetCompactUnwindInfoForFunction(Target &target, Address address,
112                                        FunctionInfo &unwind_info);
113
114   lldb::offset_t
115   BinarySearchRegularSecondPage(uint32_t entry_page_offset,
116                                 uint32_t entry_count, uint32_t function_offset,
117                                 uint32_t *entry_func_start_offset,
118                                 uint32_t *entry_func_end_offset);
119
120   uint32_t BinarySearchCompressedSecondPage(uint32_t entry_page_offset,
121                                             uint32_t entry_count,
122                                             uint32_t function_offset_to_find,
123                                             uint32_t function_offset_base,
124                                             uint32_t *entry_func_start_offset,
125                                             uint32_t *entry_func_end_offset);
126
127   uint32_t GetLSDAForFunctionOffset(uint32_t lsda_offset, uint32_t lsda_count,
128                                     uint32_t function_offset);
129
130   bool CreateUnwindPlan_x86_64(Target &target, FunctionInfo &function_info,
131                                UnwindPlan &unwind_plan,
132                                Address pc_or_function_start);
133
134   bool CreateUnwindPlan_i386(Target &target, FunctionInfo &function_info,
135                              UnwindPlan &unwind_plan,
136                              Address pc_or_function_start);
137
138   bool CreateUnwindPlan_arm64(Target &target, FunctionInfo &function_info,
139                               UnwindPlan &unwind_plan,
140                               Address pc_or_function_start);
141
142   bool CreateUnwindPlan_armv7(Target &target, FunctionInfo &function_info,
143                               UnwindPlan &unwind_plan,
144                               Address pc_or_function_start);
145
146   ObjectFile &m_objfile;
147   lldb::SectionSP m_section_sp;
148   lldb::DataBufferSP m_section_contents_if_encrypted; // if the binary is
149                                                       // encrypted, read the
150                                                       // sect contents
151   // out of live memory and cache them here
152   std::mutex m_mutex;
153   std::vector<UnwindIndex> m_indexes;
154
155   LazyBool m_indexes_computed; // eLazyBoolYes once we've tried to parse the
156                                // unwind info
157   // eLazyBoolNo means we cannot parse the unwind info & should not retry
158   // eLazyBoolCalculate means we haven't tried to parse it yet
159
160   DataExtractor m_unwindinfo_data;
161   bool m_unwindinfo_data_computed; // true once we've mapped in the unwindinfo
162                                    // data
163
164   UnwindHeader m_unwind_header;
165 };
166
167 } // namespace lldb_private
168
169 #endif // liblldb_CompactUnwindInfo_h_