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