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