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