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 
12 #include "lldb/Symbol/ObjectFile.h"
13 #include "lldb/Symbol/UnwindPlan.h"
15 #include "lldb/Utility/RangeMap.h"
16 #include "lldb/lldb-private.h"
17 #include <mutex>
18 #include <vector>
19 
20 namespace 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 
37 public:
38  CompactUnwindInfo(ObjectFile &objfile, lldb::SectionSP &section);
39 
41 
42  bool GetUnwindPlan(Target &target, Address addr, UnwindPlan &unwind_plan);
43 
44  bool IsValid(const lldb::ProcessSP &process_sp);
45 
46 private:
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
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 
68  bool operator<(const CompactUnwindInfo::UnwindIndex &rhs) const {
69  return function_offset < rhs.function_offset;
70  }
71 
72  bool operator==(const CompactUnwindInfo::UnwindIndex &rhs) const {
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
90  };
91 
92  struct UnwindHeader {
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 
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 
140  lldb::SectionSP m_section_sp;
141  lldb::DataBufferSP m_section_contents_if_encrypted; // if the binary is
142  // encrypted, read the
143  // sect contents
144  // out of live memory and cache them here
145  std::mutex m_mutex;
146  std::vector<UnwindIndex> m_indexes;
147 
148  LazyBool m_indexes_computed; // eLazyBoolYes once we've tried to parse the
149  // unwind info
150  // eLazyBoolNo means we cannot parse the unwind info & should not retry
151  // eLazyBoolCalculate means we haven't tried to parse it yet
152 
154  bool m_unwindinfo_data_computed; // true once we've mapped in the unwindinfo
155  // data
156 
158 };
159 
160 } // namespace lldb_private
161 
162 #endif // LLDB_SYMBOL_COMPACTUNWINDINFO_H
lldb_private::CompactUnwindInfo::UnwindIndex::second_level
uint32_t second_level
Definition: CompactUnwindInfo.h:55
lldb_private::CompactUnwindInfo::UnwindIndex::UnwindIndex
UnwindIndex()=default
lldb_private::CompactUnwindInfo::CreateUnwindPlan_i386
bool CreateUnwindPlan_i386(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
Definition: CompactUnwindInfo.cpp:1006
lldb_private::CompactUnwindInfo::m_indexes_computed
LazyBool m_indexes_computed
Definition: CompactUnwindInfo.h:148
lldb_private::CompactUnwindInfo::IsValid
bool IsValid(const lldb::ProcessSP &process_sp)
Definition: CompactUnwindInfo.cpp:232
lldb_private::CompactUnwindInfo::m_indexes
std::vector< UnwindIndex > m_indexes
Definition: CompactUnwindInfo.h:146
lldb_private::CompactUnwindInfo::UnwindHeader::common_encodings_array_offset
uint32_t common_encodings_array_offset
Definition: CompactUnwindInfo.h:94
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
lldb_private::CompactUnwindInfo::GetCompactUnwindInfoForFunction
bool GetCompactUnwindInfoForFunction(Target &target, Address address, FunctionInfo &unwind_info)
Definition: CompactUnwindInfo.cpp:491
lldb_private::CompactUnwindInfo::UnwindHeader::UnwindHeader
UnwindHeader()=default
lldb_private::LazyBool
LazyBool
Definition: lldb-private-enumerations.h:115
RangeMap.h
lldb_private::Target
Definition: Target.h:450
lldb_private::CompactUnwindInfo::CreateUnwindPlan_arm64
bool CreateUnwindPlan_arm64(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
Definition: CompactUnwindInfo.cpp:1303
lldb_private::CompactUnwindInfo
Definition: CompactUnwindInfo.h:36
lldb_private::CompactUnwindInfo::GetUnwindPlan
bool GetUnwindPlan(Target &target, Address addr, UnwindPlan &unwind_plan)
Definition: CompactUnwindInfo.cpp:172
lldb_private::CompactUnwindInfo::m_unwindinfo_data_computed
bool m_unwindinfo_data_computed
Definition: CompactUnwindInfo.h:154
lldb_private::CompactUnwindInfo::m_section_sp
lldb::SectionSP m_section_sp
Definition: CompactUnwindInfo.h:140
lldb_private::CompactUnwindInfo::UnwindHeader::personality_array_offset
uint32_t personality_array_offset
Definition: CompactUnwindInfo.h:96
lldb_private::CompactUnwindInfo::BinarySearchRegularSecondPage
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)
Definition: CompactUnwindInfo.cpp:411
lldb_private::DataExtractor
Definition: DataExtractor.h:48
lldb_private::CompactUnwindInfo::FunctionInfo
Definition: CompactUnwindInfo.h:79
lldb_private::CompactUnwindInfo::UnwindIndex::operator==
bool operator==(const CompactUnwindInfo::UnwindIndex &rhs) const
Definition: CompactUnwindInfo.h:72
lldb_private::CompactUnwindInfo::UnwindHeader::version
uint32_t version
Definition: CompactUnwindInfo.h:93
lldb_private::CompactUnwindInfo::FunctionInfo::FunctionInfo
FunctionInfo()
Definition: CompactUnwindInfo.h:89
lldb_private::CompactUnwindInfo::CreateUnwindPlan_x86_64
bool CreateUnwindPlan_x86_64(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
Definition: CompactUnwindInfo.cpp:734
lldb_private::CompactUnwindInfo::UnwindHeader
Definition: CompactUnwindInfo.h:92
lldb_private::CompactUnwindInfo::UnwindIndex::sentinal_entry
bool sentinal_entry
Definition: CompactUnwindInfo.h:62
lldb_private::CompactUnwindInfo::UnwindIndex::function_offset
uint32_t function_offset
Definition: CompactUnwindInfo.h:53
lldb_private::CompactUnwindInfo::m_unwindinfo_data
DataExtractor m_unwindinfo_data
Definition: CompactUnwindInfo.h:153
UnwindPlan.h
lldb_private::CompactUnwindInfo::FunctionInfo::personality_ptr_address
Address personality_ptr_address
Definition: CompactUnwindInfo.h:82
lldb_private::CompactUnwindInfo::~CompactUnwindInfo
~CompactUnwindInfo()
ObjectFile.h
lldb-private.h
lldb_private::CompactUnwindInfo::BinarySearchCompressedSecondPage
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)
Definition: CompactUnwindInfo.cpp:451
lldb_private::CompactUnwindInfo::UnwindHeader::common_encodings_array_count
uint32_t common_encodings_array_count
Definition: CompactUnwindInfo.h:95
lldb_private::CompactUnwindInfo::m_section_contents_if_encrypted
lldb::DataBufferSP m_section_contents_if_encrypted
Definition: CompactUnwindInfo.h:141
lldb_private::CompactUnwindInfo::m_unwind_header
UnwindHeader m_unwind_header
Definition: CompactUnwindInfo.h:157
lldb_private::CompactUnwindInfo::CreateUnwindPlan_armv7
bool CreateUnwindPlan_armv7(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
Definition: CompactUnwindInfo.cpp:1437
lldb_private::CompactUnwindInfo::FunctionInfo::valid_range_offset_start
uint32_t valid_range_offset_start
Definition: CompactUnwindInfo.h:85
uint32_t
lldb_private::CompactUnwindInfo::FunctionInfo::valid_range_offset_end
uint32_t valid_range_offset_end
Definition: CompactUnwindInfo.h:87
lldb_private::Address
Definition: Address.h:59
lldb_private::CompactUnwindInfo::m_objfile
ObjectFile & m_objfile
Definition: CompactUnwindInfo.h:139
lldb_private::CompactUnwindInfo::CompactUnwindInfo
CompactUnwindInfo(ObjectFile &objfile, lldb::SectionSP &section)
Definition: CompactUnwindInfo.cpp:162
lldb_private::CompactUnwindInfo::FunctionInfo::encoding
uint32_t encoding
Definition: CompactUnwindInfo.h:80
lldb_private::CompactUnwindInfo::UnwindHeader::personality_array_count
uint32_t personality_array_count
Definition: CompactUnwindInfo.h:97
DataExtractor.h
lldb_private::CompactUnwindInfo::UnwindIndex::lsda_array_start
uint32_t lsda_array_start
Definition: CompactUnwindInfo.h:58
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::CompactUnwindInfo::m_mutex
std::mutex m_mutex
Definition: CompactUnwindInfo.h:145
lldb_private::CompactUnwindInfo::ScanIndex
void ScanIndex(const lldb::ProcessSP &process_sp)
Definition: CompactUnwindInfo.cpp:244
lldb_private::CompactUnwindInfo::FunctionInfo::lsda_address
Address lsda_address
Definition: CompactUnwindInfo.h:81
lldb_private::CompactUnwindInfo::UnwindIndex
Definition: CompactUnwindInfo.h:52
lldb_private::UnwindPlan
Definition: UnwindPlan.h:53
lldb_private::CompactUnwindInfo::UnwindIndex::operator<
bool operator<(const CompactUnwindInfo::UnwindIndex &rhs) const
Definition: CompactUnwindInfo.h:68
lldb_private::ObjectFile
Definition: ObjectFile.h:58
lldb_private::CompactUnwindInfo::GetLSDAForFunctionOffset
uint32_t GetLSDAForFunctionOffset(uint32_t lsda_offset, uint32_t lsda_count, uint32_t function_offset)
Definition: CompactUnwindInfo.cpp:382
lldb_private::CompactUnwindInfo::UnwindIndex::lsda_array_end
uint32_t lsda_array_end
Definition: CompactUnwindInfo.h:60