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/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"
22 namespace lldb_private {
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.
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.
38 class CompactUnwindInfo {
40 CompactUnwindInfo(ObjectFile &objfile, lldb::SectionSP §ion);
44 bool GetUnwindPlan(Target &target, Address addr, UnwindPlan &unwind_plan);
46 bool IsValid(const lldb::ProcessSP &process_sp);
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.
55 uint32_t function_offset; // The offset of the first function covered by
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
65 // function addresses that are described
68 : function_offset(0), second_level(0), lsda_array_start(0),
69 lsda_array_end(0), sentinal_entry(false) {}
71 bool operator<(const CompactUnwindInfo::UnwindIndex &rhs) const {
72 return function_offset < rhs.function_offset;
75 bool operator==(const CompactUnwindInfo::UnwindIndex &rhs) const {
76 return function_offset == rhs.function_offset;
80 // An internal object used to store the information we retrieve about a
81 // function -- the encoding bits and possibly the LSDA/personality function.
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
88 uint32_t valid_range_offset_start; // first offset that this encoding is
89 // valid for (start of the function)
91 valid_range_offset_end; // the offset of the start of the next function
93 : encoding(0), lsda_address(), personality_ptr_address(),
94 valid_range_offset_start(0), valid_range_offset_end(0) {}
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;
105 : common_encodings_array_offset(0), common_encodings_array_count(0),
106 personality_array_offset(0), personality_array_count(0) {}
109 void ScanIndex(const lldb::ProcessSP &process_sp);
111 bool GetCompactUnwindInfoForFunction(Target &target, Address address,
112 FunctionInfo &unwind_info);
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);
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);
127 uint32_t GetLSDAForFunctionOffset(uint32_t lsda_offset, uint32_t lsda_count,
128 uint32_t function_offset);
130 bool CreateUnwindPlan_x86_64(Target &target, FunctionInfo &function_info,
131 UnwindPlan &unwind_plan,
132 Address pc_or_function_start);
134 bool CreateUnwindPlan_i386(Target &target, FunctionInfo &function_info,
135 UnwindPlan &unwind_plan,
136 Address pc_or_function_start);
138 bool CreateUnwindPlan_arm64(Target &target, FunctionInfo &function_info,
139 UnwindPlan &unwind_plan,
140 Address pc_or_function_start);
142 bool CreateUnwindPlan_armv7(Target &target, FunctionInfo &function_info,
143 UnwindPlan &unwind_plan,
144 Address pc_or_function_start);
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
151 // out of live memory and cache them here
153 std::vector<UnwindIndex> m_indexes;
155 LazyBool m_indexes_computed; // eLazyBoolYes once we've tried to parse the
157 // eLazyBoolNo means we cannot parse the unwind info & should not retry
158 // eLazyBoolCalculate means we haven't tried to parse it yet
160 DataExtractor m_unwindinfo_data;
161 bool m_unwindinfo_data_computed; // true once we've mapped in the unwindinfo
164 UnwindHeader m_unwind_header;
167 } // namespace lldb_private
169 #endif // liblldb_CompactUnwindInfo_h_