FuncUnwinders.cpp revision 309124
155714Skris//===-- FuncUnwinders.cpp ----------------------------------*- C++ -*-===//
255714Skris//
355714Skris//                     The LLVM Compiler Infrastructure
455714Skris//
555714Skris// This file is distributed under the University of Illinois Open Source
655714Skris// License. See LICENSE.TXT for details.
755714Skris//
8280304Sjkim//===----------------------------------------------------------------------===//
9280304Sjkim
1055714Skris#include "lldb/Core/AddressRange.h"
11280304Sjkim#include "lldb/Core/Address.h"
12280304Sjkim#include "lldb/Symbol/FuncUnwinders.h"
13280304Sjkim#include "lldb/Symbol/ArmUnwindInfo.h"
14280304Sjkim#include "lldb/Symbol/DWARFCallFrameInfo.h"
15280304Sjkim#include "lldb/Symbol/CompactUnwindInfo.h"
16280304Sjkim#include "lldb/Symbol/ObjectFile.h"
17280304Sjkim#include "lldb/Symbol/UnwindPlan.h"
18280304Sjkim#include "lldb/Symbol/UnwindTable.h"
19280304Sjkim#include "lldb/Target/ABI.h"
20280304Sjkim#include "lldb/Target/ExecutionContext.h"
21280304Sjkim#include "lldb/Target/Process.h"
22280304Sjkim#include "lldb/Target/Thread.h"
2355714Skris#include "lldb/Target/Target.h"
2455714Skris#include "lldb/Target/UnwindAssembly.h"
25280304Sjkim#include "lldb/Utility/RegisterNumber.h"
26280304Sjkim
27280304Sjkimusing namespace lldb;
2855714Skrisusing namespace lldb_private;
29280304Sjkim
30280304Sjkim//------------------------------------------------
3155714Skris/// constructor
32280304Sjkim//------------------------------------------------
33280304Sjkim
3455714SkrisFuncUnwinders::FuncUnwinders(UnwindTable &unwind_table, AddressRange range)
3555714Skris    : m_unwind_table(unwind_table),
36280304Sjkim      m_range(range),
37280304Sjkim      m_mutex(),
38280304Sjkim      m_unwind_plan_assembly_sp(),
39280304Sjkim      m_unwind_plan_eh_frame_sp(),
40280304Sjkim      m_unwind_plan_eh_frame_augmented_sp(),
41280304Sjkim      m_unwind_plan_compact_unwind(),
42280304Sjkim      m_unwind_plan_arm_unwind_sp(),
43280304Sjkim      m_unwind_plan_fast_sp(),
44280304Sjkim      m_unwind_plan_arch_default_sp(),
45280304Sjkim      m_unwind_plan_arch_default_at_func_entry_sp(),
46280304Sjkim      m_tried_unwind_plan_assembly(false),
47280304Sjkim      m_tried_unwind_plan_eh_frame(false),
48280304Sjkim      m_tried_unwind_plan_eh_frame_augmented(false),
49280304Sjkim      m_tried_unwind_plan_compact_unwind(false),
5055714Skris      m_tried_unwind_plan_arm_unwind(false),
5155714Skris      m_tried_unwind_fast(false),
52280304Sjkim      m_tried_unwind_arch_default(false),
53280304Sjkim      m_tried_unwind_arch_default_at_func_entry(false),
54280304Sjkim      m_first_non_prologue_insn()
5555714Skris{
56280304Sjkim}
57280304Sjkim
58280304Sjkim//------------------------------------------------
59280304Sjkim/// destructor
60280304Sjkim//------------------------------------------------
61280304Sjkim
62280304SjkimFuncUnwinders::~FuncUnwinders ()
63280304Sjkim{
64280304Sjkim}
65280304Sjkim
66280304SjkimUnwindPlanSP
67FuncUnwinders::GetUnwindPlanAtCallSite (Target &target, int current_offset)
68{
69    std::lock_guard<std::recursive_mutex> guard(m_mutex);
70
71    UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan (target, current_offset);
72    if (unwind_plan_sp)
73        return unwind_plan_sp;
74
75    unwind_plan_sp = GetCompactUnwindUnwindPlan (target, current_offset);
76    if (unwind_plan_sp)
77        return unwind_plan_sp;
78
79    unwind_plan_sp = GetArmUnwindUnwindPlan (target, current_offset);
80    if (unwind_plan_sp)
81        return unwind_plan_sp;
82
83    return nullptr;
84}
85
86UnwindPlanSP
87FuncUnwinders::GetCompactUnwindUnwindPlan (Target &target, int current_offset)
88{
89    if (m_unwind_plan_compact_unwind.size() > 0)
90        return m_unwind_plan_compact_unwind[0];    // FIXME support multiple compact unwind plans for one func
91    if (m_tried_unwind_plan_compact_unwind)
92        return UnwindPlanSP();
93
94    std::lock_guard<std::recursive_mutex> guard(m_mutex);
95    m_tried_unwind_plan_compact_unwind = true;
96    if (m_range.GetBaseAddress().IsValid())
97    {
98        Address current_pc (m_range.GetBaseAddress ());
99        if (current_offset != -1)
100            current_pc.SetOffset (current_pc.GetOffset() + current_offset);
101        CompactUnwindInfo *compact_unwind = m_unwind_table.GetCompactUnwindInfo();
102        if (compact_unwind)
103        {
104            UnwindPlanSP unwind_plan_sp (new UnwindPlan (lldb::eRegisterKindGeneric));
105            if (compact_unwind->GetUnwindPlan (target, current_pc, *unwind_plan_sp))
106            {
107                m_unwind_plan_compact_unwind.push_back (unwind_plan_sp);
108                return m_unwind_plan_compact_unwind[0];    // FIXME support multiple compact unwind plans for one func
109            }
110        }
111    }
112    return UnwindPlanSP();
113}
114
115UnwindPlanSP
116FuncUnwinders::GetEHFrameUnwindPlan (Target &target, int current_offset)
117{
118    if (m_unwind_plan_eh_frame_sp.get() || m_tried_unwind_plan_eh_frame)
119        return m_unwind_plan_eh_frame_sp;
120
121    std::lock_guard<std::recursive_mutex> guard(m_mutex);
122    m_tried_unwind_plan_eh_frame = true;
123    if (m_range.GetBaseAddress().IsValid())
124    {
125        Address current_pc (m_range.GetBaseAddress ());
126        if (current_offset != -1)
127            current_pc.SetOffset (current_pc.GetOffset() + current_offset);
128        DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo();
129        if (eh_frame)
130        {
131            m_unwind_plan_eh_frame_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
132            if (!eh_frame->GetUnwindPlan (current_pc, *m_unwind_plan_eh_frame_sp))
133                m_unwind_plan_eh_frame_sp.reset();
134        }
135    }
136    return m_unwind_plan_eh_frame_sp;
137}
138
139UnwindPlanSP
140FuncUnwinders::GetArmUnwindUnwindPlan (Target &target, int current_offset)
141{
142    if (m_unwind_plan_arm_unwind_sp.get() || m_tried_unwind_plan_arm_unwind)
143        return m_unwind_plan_arm_unwind_sp;
144
145    std::lock_guard<std::recursive_mutex> guard(m_mutex);
146    m_tried_unwind_plan_arm_unwind = true;
147    if (m_range.GetBaseAddress().IsValid())
148    {
149        Address current_pc (m_range.GetBaseAddress ());
150        if (current_offset != -1)
151            current_pc.SetOffset (current_pc.GetOffset() + current_offset);
152        ArmUnwindInfo *arm_unwind_info = m_unwind_table.GetArmUnwindInfo();
153        if (arm_unwind_info)
154        {
155            m_unwind_plan_arm_unwind_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
156            if (!arm_unwind_info->GetUnwindPlan (target, current_pc, *m_unwind_plan_arm_unwind_sp))
157                m_unwind_plan_arm_unwind_sp.reset();
158        }
159    }
160    return m_unwind_plan_arm_unwind_sp;
161}
162
163UnwindPlanSP
164FuncUnwinders::GetEHFrameAugmentedUnwindPlan (Target &target, Thread &thread, int current_offset)
165{
166    if (m_unwind_plan_eh_frame_augmented_sp.get() || m_tried_unwind_plan_eh_frame_augmented)
167        return m_unwind_plan_eh_frame_augmented_sp;
168
169    // Only supported on x86 architectures where we get eh_frame from the compiler that describes
170    // the prologue instructions perfectly, and sometimes the epilogue instructions too.
171    if (target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_32_i386
172        && target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64
173        && target.GetArchitecture().GetCore() != ArchSpec::eCore_x86_64_x86_64h)
174    {
175            m_tried_unwind_plan_eh_frame_augmented = true;
176            return m_unwind_plan_eh_frame_augmented_sp;
177    }
178
179    std::lock_guard<std::recursive_mutex> guard(m_mutex);
180    m_tried_unwind_plan_eh_frame_augmented = true;
181
182    UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan (target, current_offset);
183    if (!eh_frame_plan)
184        return m_unwind_plan_eh_frame_augmented_sp;
185
186    m_unwind_plan_eh_frame_augmented_sp.reset(new UnwindPlan(*eh_frame_plan));
187
188    // Augment the eh_frame instructions with epilogue descriptions if necessary so the
189    // UnwindPlan can be used at any instruction in the function.
190
191    UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
192    if (assembly_profiler_sp)
193    {
194        if (!assembly_profiler_sp->AugmentUnwindPlanFromCallSite (m_range, thread, *m_unwind_plan_eh_frame_augmented_sp))
195        {
196            m_unwind_plan_eh_frame_augmented_sp.reset();
197        }
198    }
199    else
200    {
201        m_unwind_plan_eh_frame_augmented_sp.reset();
202    }
203    return m_unwind_plan_eh_frame_augmented_sp;
204}
205
206
207UnwindPlanSP
208FuncUnwinders::GetAssemblyUnwindPlan (Target &target, Thread &thread, int current_offset)
209{
210    if (m_unwind_plan_assembly_sp.get()
211        || m_tried_unwind_plan_assembly
212        || m_unwind_table.GetAllowAssemblyEmulationUnwindPlans () == false)
213    {
214        return m_unwind_plan_assembly_sp;
215    }
216
217    std::lock_guard<std::recursive_mutex> guard(m_mutex);
218    m_tried_unwind_plan_assembly = true;
219
220    UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
221    if (assembly_profiler_sp)
222    {
223        m_unwind_plan_assembly_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
224        if (!assembly_profiler_sp->GetNonCallSiteUnwindPlanFromAssembly (m_range, thread, *m_unwind_plan_assembly_sp))
225        {
226            m_unwind_plan_assembly_sp.reset();
227        }
228    }
229    return m_unwind_plan_assembly_sp;
230}
231
232// This method compares the pc unwind rule in the first row of two UnwindPlans.
233// If they have the same way of getting the pc value (e.g. "CFA - 8" + "CFA is sp"),
234// then it will return LazyBoolTrue.
235LazyBool
236FuncUnwinders::CompareUnwindPlansForIdenticalInitialPCLocation (Thread& thread, const UnwindPlanSP &a, const UnwindPlanSP &b)
237{
238    LazyBool plans_are_identical = eLazyBoolCalculate;
239
240    RegisterNumber pc_reg (thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
241    uint32_t pc_reg_lldb_regnum = pc_reg.GetAsKind (eRegisterKindLLDB);
242
243    if (a.get() && b.get())
244    {
245        UnwindPlan::RowSP a_first_row = a->GetRowAtIndex (0);
246        UnwindPlan::RowSP b_first_row = b->GetRowAtIndex (0);
247
248        if (a_first_row.get() && b_first_row.get())
249        {
250            UnwindPlan::Row::RegisterLocation a_pc_regloc;
251            UnwindPlan::Row::RegisterLocation b_pc_regloc;
252
253            a_first_row->GetRegisterInfo (pc_reg_lldb_regnum, a_pc_regloc);
254            b_first_row->GetRegisterInfo (pc_reg_lldb_regnum, b_pc_regloc);
255
256            plans_are_identical = eLazyBoolYes;
257
258            if (a_first_row->GetCFAValue() != b_first_row->GetCFAValue())
259            {
260                plans_are_identical = eLazyBoolNo;
261            }
262            if (a_pc_regloc != b_pc_regloc)
263            {
264                plans_are_identical = eLazyBoolNo;
265            }
266        }
267    }
268    return plans_are_identical;
269}
270
271UnwindPlanSP
272FuncUnwinders::GetUnwindPlanAtNonCallSite (Target& target, Thread& thread, int current_offset)
273{
274    UnwindPlanSP eh_frame_sp = GetEHFrameUnwindPlan (target, current_offset);
275    UnwindPlanSP arch_default_at_entry_sp = GetUnwindPlanArchitectureDefaultAtFunctionEntry (thread);
276    UnwindPlanSP arch_default_sp = GetUnwindPlanArchitectureDefault (thread);
277    UnwindPlanSP assembly_sp = GetAssemblyUnwindPlan (target, thread, current_offset);
278
279    // This point of this code is to detect when a function is using a non-standard ABI, and the eh_frame
280    // correctly describes that alternate ABI.  This is addressing a specific situation on x86_64 linux
281    // systems where one function in a library pushes a value on the stack and jumps to another function.
282    // So using an assembly instruction based unwind will not work when you're in the second function -
283    // the stack has been modified in a non-ABI way.  But we have eh_frame that correctly describes how to
284    // unwind from this location.  So we're looking to see if the initial pc register save location from
285    // the eh_frame is different from the assembly unwind, the arch default unwind, and the arch default at
286    // initial function entry.
287    //
288    // We may have eh_frame that describes the entire function -- or we may have eh_frame that only describes
289    // the unwind after the prologue has executed -- so we need to check both the arch default (once the prologue
290    // has executed) and the arch default at initial function entry.  And we may be running on a target where
291    // we have only some of the assembly/arch default unwind plans available.
292
293    if (CompareUnwindPlansForIdenticalInitialPCLocation (thread, eh_frame_sp, arch_default_at_entry_sp) == eLazyBoolNo
294        && CompareUnwindPlansForIdenticalInitialPCLocation (thread, eh_frame_sp, arch_default_sp) == eLazyBoolNo
295        && CompareUnwindPlansForIdenticalInitialPCLocation (thread, assembly_sp, arch_default_sp) == eLazyBoolNo)
296    {
297        return eh_frame_sp;
298    }
299
300    UnwindPlanSP eh_frame_augmented_sp = GetEHFrameAugmentedUnwindPlan (target, thread, current_offset);
301    if (eh_frame_augmented_sp)
302    {
303        return eh_frame_augmented_sp;
304    }
305
306    return assembly_sp;
307}
308
309UnwindPlanSP
310FuncUnwinders::GetUnwindPlanFastUnwind (Target& target, Thread& thread)
311{
312    if (m_unwind_plan_fast_sp.get() || m_tried_unwind_fast)
313        return m_unwind_plan_fast_sp;
314
315    std::lock_guard<std::recursive_mutex> guard(m_mutex);
316    m_tried_unwind_fast = true;
317
318    UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
319    if (assembly_profiler_sp)
320    {
321        m_unwind_plan_fast_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
322        if (!assembly_profiler_sp->GetFastUnwindPlan (m_range, thread, *m_unwind_plan_fast_sp))
323        {
324            m_unwind_plan_fast_sp.reset();
325        }
326    }
327    return m_unwind_plan_fast_sp;
328}
329
330UnwindPlanSP
331FuncUnwinders::GetUnwindPlanArchitectureDefault (Thread& thread)
332{
333    if (m_unwind_plan_arch_default_sp.get() || m_tried_unwind_arch_default)
334        return m_unwind_plan_arch_default_sp;
335
336    std::lock_guard<std::recursive_mutex> guard(m_mutex);
337    m_tried_unwind_arch_default = true;
338
339    Address current_pc;
340    ProcessSP process_sp (thread.CalculateProcess());
341    if (process_sp)
342    {
343        ABI *abi = process_sp->GetABI().get();
344        if (abi)
345        {
346            m_unwind_plan_arch_default_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
347            if (!abi->CreateDefaultUnwindPlan(*m_unwind_plan_arch_default_sp))
348            {
349                m_unwind_plan_arch_default_sp.reset();
350            }
351        }
352    }
353
354    return m_unwind_plan_arch_default_sp;
355}
356
357UnwindPlanSP
358FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry (Thread& thread)
359{
360    if (m_unwind_plan_arch_default_at_func_entry_sp.get() || m_tried_unwind_arch_default_at_func_entry)
361        return m_unwind_plan_arch_default_at_func_entry_sp;
362
363    std::lock_guard<std::recursive_mutex> guard(m_mutex);
364    m_tried_unwind_arch_default_at_func_entry = true;
365
366    Address current_pc;
367    ProcessSP process_sp (thread.CalculateProcess());
368    if (process_sp)
369    {
370        ABI *abi = process_sp->GetABI().get();
371        if (abi)
372        {
373            m_unwind_plan_arch_default_at_func_entry_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
374            if (!abi->CreateFunctionEntryUnwindPlan(*m_unwind_plan_arch_default_at_func_entry_sp))
375            {
376                m_unwind_plan_arch_default_at_func_entry_sp.reset();
377            }
378        }
379    }
380
381    return m_unwind_plan_arch_default_at_func_entry_sp;
382}
383
384
385Address&
386FuncUnwinders::GetFirstNonPrologueInsn (Target& target)
387{
388    if (m_first_non_prologue_insn.IsValid())
389        return m_first_non_prologue_insn;
390
391    std::lock_guard<std::recursive_mutex> guard(m_mutex);
392    ExecutionContext exe_ctx (target.shared_from_this(), false);
393    UnwindAssemblySP assembly_profiler_sp (GetUnwindAssemblyProfiler(target));
394    if (assembly_profiler_sp)
395        assembly_profiler_sp->FirstNonPrologueInsn (m_range, exe_ctx, m_first_non_prologue_insn);
396    return m_first_non_prologue_insn;
397}
398
399const Address&
400FuncUnwinders::GetFunctionStartAddress () const
401{
402    return m_range.GetBaseAddress();
403}
404
405lldb::UnwindAssemblySP
406FuncUnwinders::GetUnwindAssemblyProfiler (Target& target)
407{
408    UnwindAssemblySP assembly_profiler_sp;
409    ArchSpec arch;
410    if (m_unwind_table.GetArchitecture (arch))
411    {
412        arch.MergeFrom (target.GetArchitecture ());
413        assembly_profiler_sp = UnwindAssembly::FindPlugin (arch);
414    }
415    return assembly_profiler_sp;
416}
417
418Address
419FuncUnwinders::GetLSDAAddress (Target &target)
420{
421    Address lsda_addr;
422
423    UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan (target, -1);
424    if (unwind_plan_sp.get() == nullptr)
425    {
426        unwind_plan_sp = GetCompactUnwindUnwindPlan (target, -1);
427    }
428    if (unwind_plan_sp.get() && unwind_plan_sp->GetLSDAAddress().IsValid())
429    {
430        lsda_addr = unwind_plan_sp->GetLSDAAddress();
431    }
432    return lsda_addr;
433}
434
435
436Address
437FuncUnwinders::GetPersonalityRoutinePtrAddress (Target &target)
438{
439    Address personality_addr;
440
441    UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan (target, -1);
442    if (unwind_plan_sp.get() == nullptr)
443    {
444        unwind_plan_sp = GetCompactUnwindUnwindPlan (target, -1);
445    }
446    if (unwind_plan_sp.get() && unwind_plan_sp->GetPersonalityFunctionPtr().IsValid())
447    {
448        personality_addr = unwind_plan_sp->GetPersonalityFunctionPtr();
449    }
450
451    return personality_addr;
452}
453