CompactUnwindInfo.h revision 314564
1263712Sdes//===-- CompactUnwindInfo.h -------------------------------------*- C++ -*-===// 2224638Sbrooks// 360573Skris// The LLVM Compiler Infrastructure 492555Sdes// 560573Skris// This file is distributed under the University of Illinois Open Source 660573Skris// License. See LICENSE.TXT for details. 760573Skris// 860573Skris//===----------------------------------------------------------------------===// 960573Skris 1060573Skris#ifndef liblldb_CompactUnwindInfo_h_ 1160573Skris#define liblldb_CompactUnwindInfo_h_ 1260573Skris 1360573Skris#include <mutex> 1460573Skris#include <vector> 1560573Skris 1660573Skris#include "lldb/Core/DataExtractor.h" 1760573Skris#include "lldb/Core/RangeMap.h" 1860573Skris#include "lldb/Symbol/ObjectFile.h" 1960573Skris#include "lldb/Symbol/UnwindPlan.h" 2060573Skris#include "lldb/lldb-private.h" 2160573Skris 2260573Skrisnamespace lldb_private { 2360573Skris 2460573Skris// Compact Unwind info is an unwind format used on Darwin. The unwind 2560573Skris// instructions 2660573Skris// for typical compiler-generated functions can be expressed in a 32-bit 2760573Skris// encoding. 28263691Sdes// The format includes a two-level index so the unwind information for a 2960573Skris// function 30162852Sdes// can be found by two binary searches in the section. It can represent both 31162852Sdes// stack frames that use a frame-pointer register and frameless functions, on 32162852Sdes// i386/x86_64 for instance. When a function is too complex to be represented 33162852Sdes// in 34162852Sdes// the compact unwind format, it calls out to eh_frame unwind instructions. 35162852Sdes 36162852Sdes// On Mac OS X / iOS, a function will have either a compact unwind 37162852Sdes// representation 3876259Sgreen// or an eh_frame representation. If lldb is going to benefit from the 3976259Sgreen// compiler's 40162852Sdes// description about saved register locations, it must be able to read both 4160573Skris// sources of information. 4260573Skris 4361209Skrisclass CompactUnwindInfo { 4460573Skrispublic: 4576259Sgreen CompactUnwindInfo(ObjectFile &objfile, lldb::SectionSP §ion); 46162852Sdes 4760573Skris ~CompactUnwindInfo(); 4876259Sgreen 4976259Sgreen bool GetUnwindPlan(Target &target, Address addr, UnwindPlan &unwind_plan); 5076259Sgreen 5176259Sgreen bool IsValid(const lldb::ProcessSP &process_sp); 5298675Sdes 53204917Sdesprivate: 54261320Sdes // The top level index entries of the compact unwind info 5560573Skris // (internal representation of struct 56162852Sdes // unwind_info_section_header_index_entry) 57162852Sdes // There are relatively few of these (one per 500/1000 functions, depending on 58162852Sdes // format) so 59162852Sdes // creating them on first scan will not be too costly. 60162852Sdes struct UnwindIndex { 61162852Sdes uint32_t function_offset; // The offset of the first function covered by 62162852Sdes // this index 63162852Sdes uint32_t second_level; // The offset (inside unwind_info sect) to the second 6492555Sdes // level page for this index 6592555Sdes // (either UNWIND_SECOND_LEVEL_REGULAR or UNWIND_SECOND_LEVEL_COMPRESSED) 6692555Sdes uint32_t lsda_array_start; // The offset (inside unwind_info sect) LSDA 6776259Sgreen // array for this index 68255767Sdes uint32_t lsda_array_end; // The offset to the LSDA array for the NEXT index 69255767Sdes bool sentinal_entry; // There is an empty index at the end which provides 70255767Sdes // the upper bound of 71255767Sdes // function addresses that are described 72261320Sdes 73255767Sdes UnwindIndex() 74255767Sdes : function_offset(0), second_level(0), lsda_array_start(0), 75261320Sdes lsda_array_end(0), sentinal_entry(false) {} 76261320Sdes 77261320Sdes bool operator<(const CompactUnwindInfo::UnwindIndex &rhs) const { 78255767Sdes return function_offset < rhs.function_offset; 79261320Sdes } 80255767Sdes 81255767Sdes bool operator==(const CompactUnwindInfo::UnwindIndex &rhs) const { 82261320Sdes return function_offset == rhs.function_offset; 83261320Sdes } 84261320Sdes }; 85261320Sdes 86261320Sdes // An internal object used to store the information we retrieve about a 87261320Sdes // function -- 88261320Sdes // the encoding bits and possibly the LSDA/personality function. 89261320Sdes struct FunctionInfo { 90255767Sdes uint32_t encoding; // compact encoding 32-bit value for this function 91261320Sdes Address lsda_address; // the address of the LSDA data for this function 92261320Sdes Address personality_ptr_address; // the address where the personality 93261320Sdes // routine addr can be found 94261320Sdes 95261320Sdes uint32_t valid_range_offset_start; // first offset that this encoding is 96255767Sdes // valid for (start of the function) 97255767Sdes uint32_t 98255767Sdes valid_range_offset_end; // the offset of the start of the next function 99261320Sdes FunctionInfo() 100255767Sdes : encoding(0), lsda_address(), personality_ptr_address(), 101255767Sdes valid_range_offset_start(0), valid_range_offset_end(0) {} 102255767Sdes }; 103255767Sdes 104255767Sdes struct UnwindHeader { 105255767Sdes uint32_t version; 106255767Sdes uint32_t common_encodings_array_offset; 107261320Sdes uint32_t common_encodings_array_count; 108255767Sdes uint32_t personality_array_offset; 109255767Sdes uint32_t personality_array_count; 110255767Sdes 111255767Sdes UnwindHeader() 112255767Sdes : common_encodings_array_offset(0), common_encodings_array_count(0), 113255767Sdes personality_array_offset(0), personality_array_count(0) {} 114255767Sdes }; 115255767Sdes 116255767Sdes void ScanIndex(const lldb::ProcessSP &process_sp); 117255767Sdes 118255767Sdes bool GetCompactUnwindInfoForFunction(Target &target, Address address, 119255767Sdes FunctionInfo &unwind_info); 120255767Sdes 121255767Sdes lldb::offset_t 122255767Sdes BinarySearchRegularSecondPage(uint32_t entry_page_offset, 123255767Sdes uint32_t entry_count, uint32_t function_offset, 124255767Sdes uint32_t *entry_func_start_offset, 125255767Sdes uint32_t *entry_func_end_offset); 126255767Sdes 127255767Sdes uint32_t BinarySearchCompressedSecondPage(uint32_t entry_page_offset, 128221420Sdes uint32_t entry_count, 129221420Sdes uint32_t function_offset_to_find, 130221420Sdes uint32_t function_offset_base, 131221420Sdes uint32_t *entry_func_start_offset, 132221420Sdes uint32_t *entry_func_end_offset); 133221420Sdes 134221420Sdes uint32_t GetLSDAForFunctionOffset(uint32_t lsda_offset, uint32_t lsda_count, 135221420Sdes uint32_t function_offset); 136221420Sdes 137221420Sdes bool CreateUnwindPlan_x86_64(Target &target, FunctionInfo &function_info, 138221420Sdes UnwindPlan &unwind_plan, 139255767Sdes Address pc_or_function_start); 140221420Sdes 141255767Sdes bool CreateUnwindPlan_i386(Target &target, FunctionInfo &function_info, 142221420Sdes UnwindPlan &unwind_plan, 143221420Sdes Address pc_or_function_start); 144221420Sdes 145221420Sdes bool CreateUnwindPlan_arm64(Target &target, FunctionInfo &function_info, 146255767Sdes UnwindPlan &unwind_plan, 147221420Sdes Address pc_or_function_start); 148221420Sdes 149221420Sdes bool CreateUnwindPlan_armv7(Target &target, FunctionInfo &function_info, 150240075Sdes UnwindPlan &unwind_plan, 151224638Sbrooks Address pc_or_function_start); 15292555Sdes 153224638Sbrooks ObjectFile &m_objfile; 154224638Sbrooks lldb::SectionSP m_section_sp; 155224638Sbrooks lldb::DataBufferSP m_section_contents_if_encrypted; // if the binary is 156224638Sbrooks // encrypted, read the 15776259Sgreen // sect contents 15860573Skris // out of live memory and cache them here 159149749Sdes std::mutex m_mutex; 16076259Sgreen std::vector<UnwindIndex> m_indexes; 16176259Sgreen 16298675Sdes LazyBool m_indexes_computed; // eLazyBoolYes once we've tried to parse the 16398675Sdes // unwind info 16498675Sdes // eLazyBoolNo means we cannot parse the unwind info & should not retry 16598675Sdes // eLazyBoolCalculate means we haven't tried to parse it yet 16698675Sdes 16798675Sdes DataExtractor m_unwindinfo_data; 16860573Skris bool m_unwindinfo_data_computed; // true once we've mapped in the unwindinfo 16976259Sgreen // data 17076259Sgreen 17176259Sgreen UnwindHeader m_unwind_header; 17260573Skris}; 17360573Skris 17476259Sgreen} // namespace lldb_private 17592555Sdes 176113908Sdes#endif // liblldb_CompactUnwindInfo_h_ 17761209Skris