1254721Semaste#ifndef liblldb_FuncUnwinders_h
2254721Semaste#define liblldb_FuncUnwinders_h
3254721Semaste
4280031Sdim#include <vector>
5280031Sdim
6254721Semaste#include "lldb/Core/AddressRange.h"
7254721Semaste#include "lldb/Core/ArchSpec.h"
8254721Semaste#include "lldb/Core/AddressRange.h"
9254721Semaste#include "lldb/Host/Mutex.h"
10254721Semaste
11254721Semastenamespace lldb_private {
12254721Semaste
13254721Semasteclass UnwindTable;
14254721Semaste
15254721Semasteclass FuncUnwinders
16254721Semaste{
17254721Semastepublic:
18254721Semaste    // FuncUnwinders objects are used to track UnwindPlans for a function
19254721Semaste    // (named or not - really just an address range)
20254721Semaste
21280031Sdim    // We'll record four different UnwindPlans for each address range:
22280031Sdim    //
23254721Semaste    //   1. Unwinding from a call site (a valid exception throw location)
24254721Semaste    //      This is often sourced from the eh_frame exception handling info
25254721Semaste    //   2. Unwinding from a non-call site (any location in the function)
26254721Semaste    //      This is often done by analyzing the function prologue assembly
27276479Sdim    //      language instructions
28254721Semaste    //   3. A fast unwind method for this function which only retrieves a
29254721Semaste    //      limited set of registers necessary to walk the stack
30254721Semaste    //   4. An architectural default unwind plan when none of the above are
31254721Semaste    //      available for some reason.
32254721Semaste
33254721Semaste    // Additionally, FuncUnwinds object can be asked where the prologue
34254721Semaste    // instructions are finished for migrating breakpoints past the
35254721Semaste    // stack frame setup instructions when we don't have line table information.
36254721Semaste
37276479Sdim    FuncUnwinders (lldb_private::UnwindTable& unwind_table, AddressRange range);
38254721Semaste
39254721Semaste    ~FuncUnwinders ();
40254721Semaste
41254721Semaste    // current_offset is the byte offset into the function.
42254721Semaste    // 0 means no instructions have executed yet.  -1 means the offset is unknown.
43254721Semaste    // On architectures where the pc points to the next instruction that will execute, this
44254721Semaste    // offset value will have already been decremented by 1 to stay within the bounds of the
45254721Semaste    // correct function body.
46254721Semaste    lldb::UnwindPlanSP
47280031Sdim    GetUnwindPlanAtCallSite (Target &target, int current_offset);
48254721Semaste
49254721Semaste    lldb::UnwindPlanSP
50276479Sdim    GetUnwindPlanAtNonCallSite (Target& target, lldb_private::Thread& thread, int current_offset);
51254721Semaste
52254721Semaste    lldb::UnwindPlanSP
53288943Sdim    GetUnwindPlanFastUnwind (Target& target, lldb_private::Thread& thread);
54254721Semaste
55254721Semaste    lldb::UnwindPlanSP
56254721Semaste    GetUnwindPlanArchitectureDefault (lldb_private::Thread& thread);
57254721Semaste
58254721Semaste    lldb::UnwindPlanSP
59254721Semaste    GetUnwindPlanArchitectureDefaultAtFunctionEntry (lldb_private::Thread& thread);
60254721Semaste
61254721Semaste    Address&
62254721Semaste    GetFirstNonPrologueInsn (Target& target);
63254721Semaste
64254721Semaste    const Address&
65254721Semaste    GetFunctionStartAddress () const;
66254721Semaste
67254721Semaste    bool
68254721Semaste    ContainsAddress (const Address& addr) const
69254721Semaste    {
70254721Semaste        return m_range.ContainsFileAddress (addr);
71254721Semaste    }
72254721Semaste
73280031Sdim    // A function may have a Language Specific Data Area specified -- a block of data in
74280031Sdim    // the object file which is used in the processing of an exception throw / catch.
75280031Sdim    // If any of the UnwindPlans have the address of the LSDA region for this function,
76280031Sdim    // this will return it.
77280031Sdim    Address
78280031Sdim    GetLSDAAddress (Target &target);
79254721Semaste
80280031Sdim    // A function may have a Personality Routine associated with it -- used in the
81280031Sdim    // processing of throwing an exception.  If any of the UnwindPlans have the
82280031Sdim    // address of the personality routine, this will return it.  Read the target-pointer
83280031Sdim    // at this address to get the personality function address.
84280031Sdim    Address
85280031Sdim    GetPersonalityRoutinePtrAddress (Target &target);
86280031Sdim
87280031Sdim
88280031Sdim
89280031Sdim    // The following methods to retrieve specific unwind plans should rarely be used.
90280031Sdim    // Instead, clients should ask for the *behavior* they are looking for, using one
91280031Sdim    // of the above UnwindPlan retrieval methods.
92280031Sdim
93280031Sdim    lldb::UnwindPlanSP
94280031Sdim    GetAssemblyUnwindPlan (Target &target, Thread &thread, int current_offset);
95280031Sdim
96280031Sdim    lldb::UnwindPlanSP
97280031Sdim    GetEHFrameUnwindPlan (Target &target, int current_offset);
98280031Sdim
99280031Sdim    lldb::UnwindPlanSP
100280031Sdim    GetEHFrameAugmentedUnwindPlan (Target &target, Thread &thread, int current_offset);
101280031Sdim
102280031Sdim    lldb::UnwindPlanSP
103280031Sdim    GetCompactUnwindUnwindPlan (Target &target, int current_offset);
104280031Sdim
105280031Sdim    lldb::UnwindPlanSP
106296417Sdim    GetArmUnwindUnwindPlan (Target &target, int current_offset);
107296417Sdim
108296417Sdim    lldb::UnwindPlanSP
109280031Sdim    GetArchDefaultUnwindPlan (Thread &thread);
110280031Sdim
111280031Sdim    lldb::UnwindPlanSP
112280031Sdim    GetArchDefaultAtFuncEntryUnwindPlan (Thread &thread);
113280031Sdim
114254721Semasteprivate:
115276479Sdim
116276479Sdim    lldb::UnwindAssemblySP
117288943Sdim    GetUnwindAssemblyProfiler (Target& target);
118276479Sdim
119254721Semaste    UnwindTable& m_unwind_table;
120254721Semaste    AddressRange m_range;
121254721Semaste
122254721Semaste    Mutex m_mutex;
123254721Semaste
124280031Sdim    lldb::UnwindPlanSP              m_unwind_plan_assembly_sp;
125280031Sdim    lldb::UnwindPlanSP              m_unwind_plan_eh_frame_sp;
126280031Sdim    lldb::UnwindPlanSP              m_unwind_plan_eh_frame_augmented_sp;   // augmented by assembly inspection so it's valid everywhere
127280031Sdim    std::vector<lldb::UnwindPlanSP> m_unwind_plan_compact_unwind;
128296417Sdim    lldb::UnwindPlanSP              m_unwind_plan_arm_unwind_sp;
129280031Sdim    lldb::UnwindPlanSP              m_unwind_plan_fast_sp;
130280031Sdim    lldb::UnwindPlanSP              m_unwind_plan_arch_default_sp;
131280031Sdim    lldb::UnwindPlanSP              m_unwind_plan_arch_default_at_func_entry_sp;
132280031Sdim
133280031Sdim    // Fetching the UnwindPlans can be expensive - if we've already attempted
134280031Sdim    // to get one & failed, don't try again.
135280031Sdim    bool m_tried_unwind_plan_assembly:1,
136280031Sdim         m_tried_unwind_plan_eh_frame:1,
137280031Sdim         m_tried_unwind_plan_eh_frame_augmented:1,
138280031Sdim         m_tried_unwind_plan_compact_unwind:1,
139296417Sdim         m_tried_unwind_plan_arm_unwind:1,
140254721Semaste         m_tried_unwind_fast:1,
141254721Semaste         m_tried_unwind_arch_default:1,
142254721Semaste         m_tried_unwind_arch_default_at_func_entry:1;
143280031Sdim
144254721Semaste    Address m_first_non_prologue_insn;
145254721Semaste
146254721Semaste    DISALLOW_COPY_AND_ASSIGN (FuncUnwinders);
147254721Semaste
148254721Semaste}; // class FuncUnwinders
149254721Semaste
150254721Semaste} // namespace lldb_private
151254721Semaste
152254721Semaste
153254721Semaste#endif //liblldb_FuncUnwinders_h
154