FuncUnwinders.cpp revision 269024
1//===-- FuncUnwinders.cpp ----------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Core/AddressRange.h"
11#include "lldb/Core/Address.h"
12#include "lldb/Symbol/FuncUnwinders.h"
13#include "lldb/Symbol/DWARFCallFrameInfo.h"
14#include "lldb/Symbol/ObjectFile.h"
15#include "lldb/Symbol/UnwindPlan.h"
16#include "lldb/Symbol/UnwindTable.h"
17#include "lldb/Target/ABI.h"
18#include "lldb/Target/ExecutionContext.h"
19#include "lldb/Target/Process.h"
20#include "lldb/Target/Thread.h"
21#include "lldb/Target/Target.h"
22#include "lldb/Target/UnwindAssembly.h"
23
24using namespace lldb;
25using namespace lldb_private;
26
27
28FuncUnwinders::FuncUnwinders
29(
30    UnwindTable& unwind_table,
31    const lldb::UnwindAssemblySP& assembly_profiler,
32    AddressRange range
33) :
34    m_unwind_table(unwind_table),
35    m_assembly_profiler(assembly_profiler),
36    m_range(range),
37    m_mutex (Mutex::eMutexTypeNormal),
38    m_unwind_plan_call_site_sp (),
39    m_unwind_plan_non_call_site_sp (),
40    m_unwind_plan_fast_sp (),
41    m_unwind_plan_arch_default_sp (),
42    m_tried_unwind_at_call_site (false),
43    m_tried_unwind_at_non_call_site (false),
44    m_tried_unwind_fast (false),
45    m_tried_unwind_arch_default (false),
46    m_tried_unwind_arch_default_at_func_entry (false),
47    m_first_non_prologue_insn()
48{
49}
50
51FuncUnwinders::~FuncUnwinders ()
52{
53}
54
55UnwindPlanSP
56FuncUnwinders::GetUnwindPlanAtCallSite (int current_offset)
57{
58    // Lock the mutex to ensure we can always give out the most appropriate
59    // information. We want to make sure if someone requests a call site unwind
60    // plan, that they get one and don't run into a race condition where one
61    // thread has started to create the unwind plan and has put it into
62    // m_unwind_plan_call_site_sp, and have another thread enter this function
63    // and return the partially filled in m_unwind_plan_call_site_sp pointer.
64    // We also want to make sure that we lock out other unwind plans from
65    // being accessed until this one is done creating itself in case someone
66    // had some code like:
67    //  UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
68    //  if (best_unwind_plan == NULL)
69    //      best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
70    Mutex::Locker locker (m_mutex);
71    if (m_tried_unwind_at_call_site == false && m_unwind_plan_call_site_sp.get() == NULL)
72    {
73        m_tried_unwind_at_call_site = true;
74        // We have cases (e.g. with _sigtramp on Mac OS X) where the hand-written eh_frame unwind info for a
75        // function does not cover the entire range of the function and so the FDE only lists a subset of the
76        // address range.  If we try to look up the unwind info by the starting address of the function
77        // (i.e. m_range.GetBaseAddress()) we may not find the eh_frame FDE.  We need to use the actual byte offset
78        // into the function when looking it up.
79
80        if (m_range.GetBaseAddress().IsValid())
81        {
82            Address current_pc (m_range.GetBaseAddress ());
83            if (current_offset != -1)
84                current_pc.SetOffset (current_pc.GetOffset() + current_offset);
85
86            DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo();
87            if (eh_frame)
88            {
89                m_unwind_plan_call_site_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
90                if (!eh_frame->GetUnwindPlan (current_pc, *m_unwind_plan_call_site_sp))
91                    m_unwind_plan_call_site_sp.reset();
92            }
93        }
94    }
95    return m_unwind_plan_call_site_sp;
96}
97
98UnwindPlanSP
99FuncUnwinders::GetUnwindPlanAtNonCallSite (Thread& thread)
100{
101    // Lock the mutex to ensure we can always give out the most appropriate
102    // information. We want to make sure if someone requests an unwind
103    // plan, that they get one and don't run into a race condition where one
104    // thread has started to create the unwind plan and has put it into
105    // the unique pointer member variable, and have another thread enter this function
106    // and return the partially filled pointer contained in the unique pointer.
107    // We also want to make sure that we lock out other unwind plans from
108    // being accessed until this one is done creating itself in case someone
109    // had some code like:
110    //  UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
111    //  if (best_unwind_plan == NULL)
112    //      best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
113    Mutex::Locker locker (m_mutex);
114    if (m_tried_unwind_at_non_call_site == false && m_unwind_plan_non_call_site_sp.get() == NULL)
115    {
116        m_tried_unwind_at_non_call_site = true;
117        if (m_assembly_profiler)
118        {
119            m_unwind_plan_non_call_site_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
120            if (!m_assembly_profiler->GetNonCallSiteUnwindPlanFromAssembly (m_range, thread, *m_unwind_plan_non_call_site_sp))
121                m_unwind_plan_non_call_site_sp.reset();
122        }
123    }
124    return m_unwind_plan_non_call_site_sp;
125}
126
127UnwindPlanSP
128FuncUnwinders::GetUnwindPlanFastUnwind (Thread& thread)
129{
130    // Lock the mutex to ensure we can always give out the most appropriate
131    // information. We want to make sure if someone requests an unwind
132    // plan, that they get one and don't run into a race condition where one
133    // thread has started to create the unwind plan and has put it into
134    // the unique pointer member variable, and have another thread enter this function
135    // and return the partially filled pointer contained in the unique pointer.
136    // We also want to make sure that we lock out other unwind plans from
137    // being accessed until this one is done creating itself in case someone
138    // had some code like:
139    //  UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
140    //  if (best_unwind_plan == NULL)
141    //      best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
142    Mutex::Locker locker (m_mutex);
143    if (m_tried_unwind_fast == false && m_unwind_plan_fast_sp.get() == NULL)
144    {
145        m_tried_unwind_fast = true;
146        if (m_assembly_profiler)
147        {
148            m_unwind_plan_fast_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
149            if (!m_assembly_profiler->GetFastUnwindPlan (m_range, thread, *m_unwind_plan_fast_sp))
150                m_unwind_plan_fast_sp.reset();
151        }
152    }
153    return m_unwind_plan_fast_sp;
154}
155
156UnwindPlanSP
157FuncUnwinders::GetUnwindPlanArchitectureDefault (Thread& thread)
158{
159    // Lock the mutex to ensure we can always give out the most appropriate
160    // information. We want to make sure if someone requests an unwind
161    // plan, that they get one and don't run into a race condition where one
162    // thread has started to create the unwind plan and has put it into
163    // the unique pointer member variable, and have another thread enter this function
164    // and return the partially filled pointer contained in the unique pointer.
165    // We also want to make sure that we lock out other unwind plans from
166    // being accessed until this one is done creating itself in case someone
167    // had some code like:
168    //  UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
169    //  if (best_unwind_plan == NULL)
170    //      best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
171    Mutex::Locker locker (m_mutex);
172    if (m_tried_unwind_arch_default == false && m_unwind_plan_arch_default_sp.get() == NULL)
173    {
174        m_tried_unwind_arch_default = true;
175        Address current_pc;
176        ProcessSP process_sp (thread.CalculateProcess());
177        if (process_sp)
178        {
179            ABI *abi = process_sp->GetABI().get();
180            if (abi)
181            {
182                m_unwind_plan_arch_default_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
183                if (m_unwind_plan_arch_default_sp)
184                    abi->CreateDefaultUnwindPlan(*m_unwind_plan_arch_default_sp);
185            }
186        }
187    }
188
189    return m_unwind_plan_arch_default_sp;
190}
191
192UnwindPlanSP
193FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry (Thread& thread)
194{
195    // Lock the mutex to ensure we can always give out the most appropriate
196    // information. We want to make sure if someone requests an unwind
197    // plan, that they get one and don't run into a race condition where one
198    // thread has started to create the unwind plan and has put it into
199    // the unique pointer member variable, and have another thread enter this function
200    // and return the partially filled pointer contained in the unique pointer.
201    // We also want to make sure that we lock out other unwind plans from
202    // being accessed until this one is done creating itself in case someone
203    // had some code like:
204    //  UnwindPlan *best_unwind_plan = ...GetUnwindPlanAtCallSite (...)
205    //  if (best_unwind_plan == NULL)
206    //      best_unwind_plan = GetUnwindPlanAtNonCallSite (...)
207    Mutex::Locker locker (m_mutex);
208    if (m_tried_unwind_arch_default_at_func_entry == false && m_unwind_plan_arch_default_at_func_entry_sp.get() == NULL)
209    {
210        m_tried_unwind_arch_default_at_func_entry = true;
211        Address current_pc;
212        ProcessSP process_sp (thread.CalculateProcess());
213        if (process_sp)
214        {
215            ABI *abi = process_sp->GetABI().get();
216            if (abi)
217            {
218                m_unwind_plan_arch_default_at_func_entry_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
219                if (m_unwind_plan_arch_default_at_func_entry_sp)
220                    abi->CreateFunctionEntryUnwindPlan(*m_unwind_plan_arch_default_at_func_entry_sp);
221            }
222        }
223    }
224
225    return m_unwind_plan_arch_default_at_func_entry_sp;
226}
227
228
229Address&
230FuncUnwinders::GetFirstNonPrologueInsn (Target& target)
231{
232    if (m_first_non_prologue_insn.IsValid())
233        return m_first_non_prologue_insn;
234    ExecutionContext exe_ctx (target.shared_from_this(), false);
235    if (m_assembly_profiler)
236        m_assembly_profiler->FirstNonPrologueInsn (m_range, exe_ctx, m_first_non_prologue_insn);
237    return m_first_non_prologue_insn;
238}
239
240const Address&
241FuncUnwinders::GetFunctionStartAddress () const
242{
243    return m_range.GetBaseAddress();
244}
245
246void
247FuncUnwinders::InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& thread)
248{
249    UnwindPlanSP arch_default = GetUnwindPlanArchitectureDefault (thread);
250    if (arch_default && m_tried_unwind_at_call_site)
251    {
252        m_unwind_plan_call_site_sp = arch_default;
253    }
254}
255