LLDB mainline
CompactUnwindInfo.h
Go to the documentation of this file.
1//===-- CompactUnwindInfo.h -------------------------------------*- C++ -*-===//
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 LLDB_SYMBOL_COMPACTUNWINDINFO_H
10#define LLDB_SYMBOL_COMPACTUNWINDINFO_H
11
16#include "lldb/lldb-private.h"
17#include <mutex>
18#include <vector>
19
20namespace lldb_private {
21
22// Compact Unwind info is an unwind format used on Darwin. The unwind
23// instructions for typical compiler-generated functions can be expressed in a
24// 32-bit encoding. The format includes a two-level index so the unwind
25// information for a function can be found by two binary searches in the
26// section. It can represent both stack frames that use a frame-pointer
27// register and frameless functions, on i386/x86_64 for instance. When a
28// function is too complex to be represented in the compact unwind format, it
29// calls out to eh_frame unwind instructions.
30
31// On Mac OS X / iOS, a function will have either a compact unwind
32// representation or an eh_frame representation. If lldb is going to benefit
33// from the compiler's description about saved register locations, it must be
34// able to read both sources of information.
35
37public:
39
41
42 bool GetUnwindPlan(Target &target, Address addr, UnwindPlan &unwind_plan);
43
44 bool IsValid(const lldb::ProcessSP &process_sp);
45
46private:
47 // The top level index entries of the compact unwind info
48 // (internal representation of struct
49 // unwind_info_section_header_index_entry)
50 // There are relatively few of these (one per 500/1000 functions, depending
51 // on format) so creating them on first scan will not be too costly.
52 struct UnwindIndex {
53 uint32_t function_offset = 0; // The offset of the first function covered by
54 // this index
55 uint32_t second_level = 0; // The offset (inside unwind_info sect) to the
56 // second level page for this index
57 // (either UNWIND_SECOND_LEVEL_REGULAR or UNWIND_SECOND_LEVEL_COMPRESSED)
58 uint32_t lsda_array_start = 0; // The offset (inside unwind_info sect) LSDA
59 // array for this index
60 uint32_t lsda_array_end =
61 0; // The offset to the LSDA array for the NEXT index
62 bool sentinal_entry = false; // There is an empty index at the end which
63 // provides the upper bound of
64 // function addresses that are described
65
66 UnwindIndex() = default;
67
70 }
71
73 return function_offset == rhs.function_offset;
74 }
75 };
76
77 // An internal object used to store the information we retrieve about a
78 // function -- the encoding bits and possibly the LSDA/personality function.
79 struct FunctionInfo {
80 uint32_t encoding = 0; // compact encoding 32-bit value for this function
81 Address lsda_address; // the address of the LSDA data for this function
82 Address personality_ptr_address; // the address where the personality
83 // routine addr can be found
84
85 uint32_t valid_range_offset_start = 0; // first offset that this encoding is
86 // valid for (start of the function)
88 0; // the offset of the start of the next function
89 FunctionInfo() = default;
90 };
91
92 struct UnwindHeader {
93 uint32_t version;
98
99 UnwindHeader() = default;
100 };
101
102 void ScanIndex(const lldb::ProcessSP &process_sp);
103
104 bool GetCompactUnwindInfoForFunction(Target &target, Address address,
105 FunctionInfo &unwind_info);
106
108 BinarySearchRegularSecondPage(uint32_t entry_page_offset,
109 uint32_t entry_count, uint32_t function_offset,
110 uint32_t *entry_func_start_offset,
111 uint32_t *entry_func_end_offset);
112
113 uint32_t BinarySearchCompressedSecondPage(uint32_t entry_page_offset,
114 uint32_t entry_count,
115 uint32_t function_offset_to_find,
116 uint32_t function_offset_base,
117 uint32_t *entry_func_start_offset,
118 uint32_t *entry_func_end_offset);
119
120 uint32_t GetLSDAForFunctionOffset(uint32_t lsda_offset, uint32_t lsda_count,
121 uint32_t function_offset);
122
123 bool CreateUnwindPlan_x86_64(Target &target, FunctionInfo &function_info,
124 UnwindPlan &unwind_plan,
125 Address pc_or_function_start);
126
127 bool CreateUnwindPlan_i386(Target &target, FunctionInfo &function_info,
128 UnwindPlan &unwind_plan,
129 Address pc_or_function_start);
130
131 bool CreateUnwindPlan_arm64(Target &target, FunctionInfo &function_info,
132 UnwindPlan &unwind_plan,
133 Address pc_or_function_start);
134
135 bool CreateUnwindPlan_armv7(Target &target, FunctionInfo &function_info,
136 UnwindPlan &unwind_plan,
137 Address pc_or_function_start);
138
143 // encrypted, read the
144 // sect contents
145 // out of live memory and cache them here
146 std::mutex m_mutex;
147 std::vector<UnwindIndex> m_indexes;
148
149 LazyBool m_indexes_computed; // eLazyBoolYes once we've tried to parse the
150 // unwind info
151 // eLazyBoolNo means we cannot parse the unwind info & should not retry
152 // eLazyBoolCalculate means we haven't tried to parse it yet
153
155 bool m_unwindinfo_data_computed; // true once we've mapped in the unwindinfo
156 // data
157
159};
160
161} // namespace lldb_private
162
163#endif // LLDB_SYMBOL_COMPACTUNWINDINFO_H
A section + offset based address class.
Definition: Address.h:62
bool CreateUnwindPlan_arm64(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
bool CreateUnwindPlan_x86_64(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
uint32_t BinarySearchCompressedSecondPage(uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset_to_find, uint32_t function_offset_base, uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset)
bool IsValid(const lldb::ProcessSP &process_sp)
uint32_t GetLSDAForFunctionOffset(uint32_t lsda_offset, uint32_t lsda_count, uint32_t function_offset)
bool CreateUnwindPlan_armv7(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
bool GetUnwindPlan(Target &target, Address addr, UnwindPlan &unwind_plan)
bool CreateUnwindPlan_i386(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
lldb::offset_t BinarySearchRegularSecondPage(uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset, uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset)
std::vector< UnwindIndex > m_indexes
void ScanIndex(const lldb::ProcessSP &process_sp)
bool GetCompactUnwindInfoForFunction(Target &target, Address address, FunctionInfo &unwind_info)
lldb::WritableDataBufferSP m_section_contents_if_encrypted
An data extractor class.
Definition: DataExtractor.h:48
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:44
A class that represents a running process on the host machine.
uint64_t offset_t
Definition: lldb-types.h:85
std::shared_ptr< lldb_private::Process > ProcessSP
Definition: lldb-forward.h:389
std::shared_ptr< lldb_private::Section > SectionSP
Definition: lldb-forward.h:418
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
Definition: lldb-forward.h:337
bool operator==(const CompactUnwindInfo::UnwindIndex &rhs) const
bool operator<(const CompactUnwindInfo::UnwindIndex &rhs) const