1254721Semaste#ifndef liblldb_FuncUnwinders_h 2254721Semaste#define liblldb_FuncUnwinders_h 3254721Semaste 4327952Sdim#include "lldb/Core/AddressRange.h" 5327952Sdim#include "lldb/lldb-private-enumerations.h" 6309124Sdim#include <mutex> 7280031Sdim#include <vector> 8280031Sdim 9254721Semastenamespace lldb_private { 10254721Semaste 11254721Semasteclass UnwindTable; 12254721Semaste 13314564Sdimclass FuncUnwinders { 14254721Semastepublic: 15341825Sdim // FuncUnwinders objects are used to track UnwindPlans for a function (named 16341825Sdim // or not - really just an address range) 17254721Semaste 18314564Sdim // We'll record four different UnwindPlans for each address range: 19314564Sdim // 20314564Sdim // 1. Unwinding from a call site (a valid exception throw location) 21314564Sdim // This is often sourced from the eh_frame exception handling info 22314564Sdim // 2. Unwinding from a non-call site (any location in the function) 23314564Sdim // This is often done by analyzing the function prologue assembly 24314564Sdim // language instructions 25314564Sdim // 3. A fast unwind method for this function which only retrieves a 26314564Sdim // limited set of registers necessary to walk the stack 27314564Sdim // 4. An architectural default unwind plan when none of the above are 28314564Sdim // available for some reason. 29254721Semaste 30314564Sdim // Additionally, FuncUnwinds object can be asked where the prologue 31341825Sdim // instructions are finished for migrating breakpoints past the stack frame 32341825Sdim // setup instructions when we don't have line table information. 33254721Semaste 34314564Sdim FuncUnwinders(lldb_private::UnwindTable &unwind_table, AddressRange range); 35254721Semaste 36314564Sdim ~FuncUnwinders(); 37254721Semaste 38353358Sdim lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target, Thread &thread); 39254721Semaste 40314564Sdim lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite(Target &target, 41353358Sdim lldb_private::Thread &thread); 42254721Semaste 43314564Sdim lldb::UnwindPlanSP GetUnwindPlanFastUnwind(Target &target, 44314564Sdim lldb_private::Thread &thread); 45254721Semaste 46314564Sdim lldb::UnwindPlanSP 47314564Sdim GetUnwindPlanArchitectureDefault(lldb_private::Thread &thread); 48254721Semaste 49314564Sdim lldb::UnwindPlanSP 50314564Sdim GetUnwindPlanArchitectureDefaultAtFunctionEntry(lldb_private::Thread &thread); 51254721Semaste 52314564Sdim Address &GetFirstNonPrologueInsn(Target &target); 53254721Semaste 54314564Sdim const Address &GetFunctionStartAddress() const; 55254721Semaste 56314564Sdim bool ContainsAddress(const Address &addr) const { 57314564Sdim return m_range.ContainsFileAddress(addr); 58314564Sdim } 59254721Semaste 60314564Sdim // A function may have a Language Specific Data Area specified -- a block of 61314564Sdim // data in 62314564Sdim // the object file which is used in the processing of an exception throw / 63341825Sdim // catch. If any of the UnwindPlans have the address of the LSDA region for 64341825Sdim // this function, this will return it. 65314564Sdim Address GetLSDAAddress(Target &target); 66254721Semaste 67314564Sdim // A function may have a Personality Routine associated with it -- used in the 68314564Sdim // processing of throwing an exception. If any of the UnwindPlans have the 69341825Sdim // address of the personality routine, this will return it. Read the target- 70341825Sdim // pointer at this address to get the personality function address. 71314564Sdim Address GetPersonalityRoutinePtrAddress(Target &target); 72280031Sdim 73314564Sdim // The following methods to retrieve specific unwind plans should rarely be 74341825Sdim // used. Instead, clients should ask for the *behavior* they are looking for, 75341825Sdim // using one of the above UnwindPlan retrieval methods. 76280031Sdim 77353358Sdim lldb::UnwindPlanSP GetAssemblyUnwindPlan(Target &target, Thread &thread); 78280031Sdim 79360784Sdim lldb::UnwindPlanSP GetObjectFileUnwindPlan(Target &target); 80360784Sdim 81360784Sdim lldb::UnwindPlanSP GetObjectFileAugmentedUnwindPlan(Target &target, 82360784Sdim Thread &thread); 83360784Sdim 84353358Sdim lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target); 85280031Sdim 86314564Sdim lldb::UnwindPlanSP GetEHFrameAugmentedUnwindPlan(Target &target, 87353358Sdim Thread &thread); 88280031Sdim 89353358Sdim lldb::UnwindPlanSP GetDebugFrameUnwindPlan(Target &target); 90321369Sdim 91321369Sdim lldb::UnwindPlanSP GetDebugFrameAugmentedUnwindPlan(Target &target, 92353358Sdim Thread &thread); 93321369Sdim 94353358Sdim lldb::UnwindPlanSP GetCompactUnwindUnwindPlan(Target &target); 95280031Sdim 96353358Sdim lldb::UnwindPlanSP GetArmUnwindUnwindPlan(Target &target); 97280031Sdim 98353358Sdim lldb::UnwindPlanSP GetSymbolFileUnwindPlan(Thread &thread); 99353358Sdim 100314564Sdim lldb::UnwindPlanSP GetArchDefaultUnwindPlan(Thread &thread); 101280031Sdim 102314564Sdim lldb::UnwindPlanSP GetArchDefaultAtFuncEntryUnwindPlan(Thread &thread); 103296417Sdim 104254721Semasteprivate: 105314564Sdim lldb::UnwindAssemblySP GetUnwindAssemblyProfiler(Target &target); 106276479Sdim 107341825Sdim // Do a simplistic comparison for the register restore rule for getting the 108341825Sdim // caller's pc value on two UnwindPlans -- returns LazyBoolYes if they have 109341825Sdim // the same unwind rule for the pc, LazyBoolNo if they do not have the same 110341825Sdim // unwind rule for the pc, and LazyBoolCalculate if it was unable to 111341825Sdim // determine this for some reason. 112314564Sdim lldb_private::LazyBool CompareUnwindPlansForIdenticalInitialPCLocation( 113314564Sdim Thread &thread, const lldb::UnwindPlanSP &a, const lldb::UnwindPlanSP &b); 114276479Sdim 115314564Sdim UnwindTable &m_unwind_table; 116314564Sdim AddressRange m_range; 117309124Sdim 118314564Sdim std::recursive_mutex m_mutex; 119254721Semaste 120314564Sdim lldb::UnwindPlanSP m_unwind_plan_assembly_sp; 121360784Sdim lldb::UnwindPlanSP m_unwind_plan_object_file_sp; 122314564Sdim lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp; 123321369Sdim lldb::UnwindPlanSP m_unwind_plan_debug_frame_sp; 124321369Sdim 125321369Sdim // augmented by assembly inspection so it's valid everywhere 126360784Sdim lldb::UnwindPlanSP m_unwind_plan_object_file_augmented_sp; 127321369Sdim lldb::UnwindPlanSP m_unwind_plan_eh_frame_augmented_sp; 128321369Sdim lldb::UnwindPlanSP m_unwind_plan_debug_frame_augmented_sp; 129321369Sdim 130314564Sdim std::vector<lldb::UnwindPlanSP> m_unwind_plan_compact_unwind; 131314564Sdim lldb::UnwindPlanSP m_unwind_plan_arm_unwind_sp; 132353358Sdim lldb::UnwindPlanSP m_unwind_plan_symbol_file_sp; 133314564Sdim lldb::UnwindPlanSP m_unwind_plan_fast_sp; 134314564Sdim lldb::UnwindPlanSP m_unwind_plan_arch_default_sp; 135314564Sdim lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp; 136254721Semaste 137341825Sdim // Fetching the UnwindPlans can be expensive - if we've already attempted to 138341825Sdim // get one & failed, don't try again. 139314564Sdim bool m_tried_unwind_plan_assembly : 1, m_tried_unwind_plan_eh_frame : 1, 140360784Sdim m_tried_unwind_plan_object_file : 1, 141321369Sdim m_tried_unwind_plan_debug_frame : 1, 142360784Sdim m_tried_unwind_plan_object_file_augmented : 1, 143314564Sdim m_tried_unwind_plan_eh_frame_augmented : 1, 144321369Sdim m_tried_unwind_plan_debug_frame_augmented : 1, 145314564Sdim m_tried_unwind_plan_compact_unwind : 1, 146353358Sdim m_tried_unwind_plan_arm_unwind : 1, m_tried_unwind_plan_symbol_file : 1, 147353358Sdim m_tried_unwind_fast : 1, m_tried_unwind_arch_default : 1, 148314564Sdim m_tried_unwind_arch_default_at_func_entry : 1; 149280031Sdim 150314564Sdim Address m_first_non_prologue_insn; 151280031Sdim 152314564Sdim DISALLOW_COPY_AND_ASSIGN(FuncUnwinders); 153254721Semaste 154254721Semaste}; // class FuncUnwinders 155254721Semaste 156254721Semaste} // namespace lldb_private 157254721Semaste 158314564Sdim#endif // liblldb_FuncUnwinders_h 159