Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:51

0001 #ifndef LLDB_SYMBOL_FUNCUNWINDERS_H
0002 #define LLDB_SYMBOL_FUNCUNWINDERS_H
0003 
0004 #include "lldb/Core/AddressRange.h"
0005 #include "lldb/lldb-private-enumerations.h"
0006 #include <mutex>
0007 #include <vector>
0008 
0009 namespace lldb_private {
0010 
0011 class UnwindTable;
0012 
0013 class FuncUnwinders {
0014 public:
0015   // FuncUnwinders objects are used to track UnwindPlans for a function (named
0016   // or not - really just an address range)
0017 
0018   // We'll record four different UnwindPlans for each address range:
0019   //
0020   //   1. Unwinding from a call site (a valid exception throw location)
0021   //      This is often sourced from the eh_frame exception handling info
0022   //   2. Unwinding from a non-call site (any location in the function)
0023   //      This is often done by analyzing the function prologue assembly
0024   //      language instructions
0025   //   3. A fast unwind method for this function which only retrieves a
0026   //      limited set of registers necessary to walk the stack
0027   //   4. An architectural default unwind plan when none of the above are
0028   //      available for some reason.
0029 
0030   // Additionally, FuncUnwinds object can be asked where the prologue
0031   // instructions are finished for migrating breakpoints past the stack frame
0032   // setup instructions when we don't have line table information.
0033 
0034   FuncUnwinders(lldb_private::UnwindTable &unwind_table, AddressRange range);
0035 
0036   ~FuncUnwinders();
0037 
0038   lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target, Thread &thread);
0039 
0040   lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite(Target &target,
0041                                                 lldb_private::Thread &thread);
0042 
0043   lldb::UnwindPlanSP GetUnwindPlanFastUnwind(Target &target,
0044                                              lldb_private::Thread &thread);
0045 
0046   lldb::UnwindPlanSP
0047   GetUnwindPlanArchitectureDefault(lldb_private::Thread &thread);
0048 
0049   lldb::UnwindPlanSP
0050   GetUnwindPlanArchitectureDefaultAtFunctionEntry(lldb_private::Thread &thread);
0051 
0052   Address &GetFirstNonPrologueInsn(Target &target);
0053 
0054   const Address &GetFunctionStartAddress() const;
0055 
0056   bool ContainsAddress(const Address &addr) const {
0057     return m_range.ContainsFileAddress(addr);
0058   }
0059 
0060   // A function may have a Language Specific Data Area specified -- a block of
0061   // data in
0062   // the object file which is used in the processing of an exception throw /
0063   // catch. If any of the UnwindPlans have the address of the LSDA region for
0064   // this function, this will return it.
0065   Address GetLSDAAddress(Target &target);
0066 
0067   // A function may have a Personality Routine associated with it -- used in the
0068   // processing of throwing an exception.  If any of the UnwindPlans have the
0069   // address of the personality routine, this will return it.  Read the target-
0070   // pointer at this address to get the personality function address.
0071   Address GetPersonalityRoutinePtrAddress(Target &target);
0072 
0073   // The following methods to retrieve specific unwind plans should rarely be
0074   // used. Instead, clients should ask for the *behavior* they are looking for,
0075   // using one of the above UnwindPlan retrieval methods.
0076 
0077   lldb::UnwindPlanSP GetAssemblyUnwindPlan(Target &target, Thread &thread);
0078 
0079   lldb::UnwindPlanSP GetObjectFileUnwindPlan(Target &target);
0080 
0081   lldb::UnwindPlanSP GetObjectFileAugmentedUnwindPlan(Target &target,
0082                                                       Thread &thread);
0083 
0084   lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target);
0085 
0086   lldb::UnwindPlanSP GetEHFrameAugmentedUnwindPlan(Target &target,
0087                                                    Thread &thread);
0088 
0089   lldb::UnwindPlanSP GetDebugFrameUnwindPlan(Target &target);
0090 
0091   lldb::UnwindPlanSP GetDebugFrameAugmentedUnwindPlan(Target &target,
0092                                                       Thread &thread);
0093 
0094   lldb::UnwindPlanSP GetCompactUnwindUnwindPlan(Target &target);
0095 
0096   lldb::UnwindPlanSP GetArmUnwindUnwindPlan(Target &target);
0097 
0098   lldb::UnwindPlanSP GetSymbolFileUnwindPlan(Thread &thread);
0099 
0100   lldb::UnwindPlanSP GetArchDefaultUnwindPlan(Thread &thread);
0101 
0102   lldb::UnwindPlanSP GetArchDefaultAtFuncEntryUnwindPlan(Thread &thread);
0103 
0104 private:
0105   lldb::UnwindAssemblySP GetUnwindAssemblyProfiler(Target &target);
0106 
0107   // Do a simplistic comparison for the register restore rule for getting the
0108   // caller's pc value on two UnwindPlans -- returns LazyBoolYes if they have
0109   // the same unwind rule for the pc, LazyBoolNo if they do not have the same
0110   // unwind rule for the pc, and LazyBoolCalculate if it was unable to
0111   // determine this for some reason.
0112   lldb_private::LazyBool CompareUnwindPlansForIdenticalInitialPCLocation(
0113       Thread &thread, const lldb::UnwindPlanSP &a, const lldb::UnwindPlanSP &b);
0114 
0115   UnwindTable &m_unwind_table;
0116   AddressRange m_range;
0117 
0118   std::recursive_mutex m_mutex;
0119 
0120   lldb::UnwindPlanSP m_unwind_plan_assembly_sp;
0121   lldb::UnwindPlanSP m_unwind_plan_object_file_sp;
0122   lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp;
0123   lldb::UnwindPlanSP m_unwind_plan_debug_frame_sp;
0124 
0125   // augmented by assembly inspection so it's valid everywhere
0126   lldb::UnwindPlanSP m_unwind_plan_object_file_augmented_sp;
0127   lldb::UnwindPlanSP m_unwind_plan_eh_frame_augmented_sp;
0128   lldb::UnwindPlanSP m_unwind_plan_debug_frame_augmented_sp;
0129 
0130   std::vector<lldb::UnwindPlanSP> m_unwind_plan_compact_unwind;
0131   lldb::UnwindPlanSP m_unwind_plan_arm_unwind_sp;
0132   lldb::UnwindPlanSP m_unwind_plan_symbol_file_sp;
0133   lldb::UnwindPlanSP m_unwind_plan_fast_sp;
0134   lldb::UnwindPlanSP m_unwind_plan_arch_default_sp;
0135   lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp;
0136 
0137   // Fetching the UnwindPlans can be expensive - if we've already attempted to
0138   // get one & failed, don't try again.
0139   bool m_tried_unwind_plan_assembly : 1, m_tried_unwind_plan_eh_frame : 1,
0140       m_tried_unwind_plan_object_file : 1,
0141       m_tried_unwind_plan_debug_frame : 1,
0142       m_tried_unwind_plan_object_file_augmented : 1,
0143       m_tried_unwind_plan_eh_frame_augmented : 1,
0144       m_tried_unwind_plan_debug_frame_augmented : 1,
0145       m_tried_unwind_plan_compact_unwind : 1,
0146       m_tried_unwind_plan_arm_unwind : 1, m_tried_unwind_plan_symbol_file : 1,
0147       m_tried_unwind_fast : 1, m_tried_unwind_arch_default : 1,
0148       m_tried_unwind_arch_default_at_func_entry : 1;
0149 
0150   Address m_first_non_prologue_insn;
0151 
0152   FuncUnwinders(const FuncUnwinders &) = delete;
0153   const FuncUnwinders &operator=(const FuncUnwinders &) = delete;
0154 
0155 }; // class FuncUnwinders
0156 
0157 } // namespace lldb_private
0158 
0159 #endif // LLDB_SYMBOL_FUNCUNWINDERS_H