1 //===-- CompactUnwindInfo.h -------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_CompactUnwindInfo_h_
11 #define liblldb_CompactUnwindInfo_h_
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"
22 namespace lldb_private {
24 // Compact Unwind info is an unwind format used on Darwin. The unwind
26 // for typical compiler-generated functions can be expressed in a 32-bit
28 // The format includes a two-level index so the unwind information for a
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
34 // the compact unwind format, it calls out to eh_frame unwind instructions.
36 // On Mac OS X / iOS, a function will have either a compact unwind
38 // or an eh_frame representation. If lldb is going to benefit from the
40 // description about saved register locations, it must be able to read both
41 // sources of information.
43 class CompactUnwindInfo {
45 CompactUnwindInfo(ObjectFile &objfile, lldb::SectionSP §ion);
49 bool GetUnwindPlan(Target &target, Address addr, UnwindPlan &unwind_plan);
51 bool IsValid(const lldb::ProcessSP &process_sp);
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
59 // creating them on first scan will not be too costly.
61 uint32_t function_offset; // The offset of the first function covered by
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
71 // function addresses that are described
74 : function_offset(0), second_level(0), lsda_array_start(0),
75 lsda_array_end(0), sentinal_entry(false) {}
77 bool operator<(const CompactUnwindInfo::UnwindIndex &rhs) const {
78 return function_offset < rhs.function_offset;
81 bool operator==(const CompactUnwindInfo::UnwindIndex &rhs) const {
82 return function_offset == rhs.function_offset;
86 // An internal object used to store the information we retrieve about a
88 // the encoding bits and possibly the LSDA/personality function.
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
95 uint32_t valid_range_offset_start; // first offset that this encoding is
96 // valid for (start of the function)
98 valid_range_offset_end; // the offset of the start of the next function
100 : encoding(0), lsda_address(), personality_ptr_address(),
101 valid_range_offset_start(0), valid_range_offset_end(0) {}
104 struct UnwindHeader {
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;
112 : common_encodings_array_offset(0), common_encodings_array_count(0),
113 personality_array_offset(0), personality_array_count(0) {}
116 void ScanIndex(const lldb::ProcessSP &process_sp);
118 bool GetCompactUnwindInfoForFunction(Target &target, Address address,
119 FunctionInfo &unwind_info);
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);
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);
134 uint32_t GetLSDAForFunctionOffset(uint32_t lsda_offset, uint32_t lsda_count,
135 uint32_t function_offset);
137 bool CreateUnwindPlan_x86_64(Target &target, FunctionInfo &function_info,
138 UnwindPlan &unwind_plan,
139 Address pc_or_function_start);
141 bool CreateUnwindPlan_i386(Target &target, FunctionInfo &function_info,
142 UnwindPlan &unwind_plan,
143 Address pc_or_function_start);
145 bool CreateUnwindPlan_arm64(Target &target, FunctionInfo &function_info,
146 UnwindPlan &unwind_plan,
147 Address pc_or_function_start);
149 bool CreateUnwindPlan_armv7(Target &target, FunctionInfo &function_info,
150 UnwindPlan &unwind_plan,
151 Address pc_or_function_start);
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
158 // out of live memory and cache them here
160 std::vector<UnwindIndex> m_indexes;
162 LazyBool m_indexes_computed; // eLazyBoolYes once we've tried to parse the
164 // eLazyBoolNo means we cannot parse the unwind info & should not retry
165 // eLazyBoolCalculate means we haven't tried to parse it yet
167 DataExtractor m_unwindinfo_data;
168 bool m_unwindinfo_data_computed; // true once we've mapped in the unwindinfo
171 UnwindHeader m_unwind_header;
174 } // namespace lldb_private
176 #endif // liblldb_CompactUnwindInfo_h_