diff options
author | Jason Molenda <jmolenda@apple.com> | 2015-01-13 06:04:04 +0000 |
---|---|---|
committer | Jason Molenda <jmolenda@apple.com> | 2015-01-13 06:04:04 +0000 |
commit | 34549b8f75e3a772d8a99011452de1de7e4cceb6 (patch) | |
tree | 8379521b4459d05ded2a64ea481ac37d53ae4a1e /lldb/source/Commands | |
parent | d5bb5c2bfeda4b9ae6e998ba02a5e81fe6423590 (diff) | |
download | bcm5719-llvm-34549b8f75e3a772d8a99011452de1de7e4cceb6.tar.gz bcm5719-llvm-34549b8f75e3a772d8a99011452de1de7e4cceb6.zip |
Change the x86 assembly instruction unwind parser to
step through the complete function looking for any epilogue
instructions. If we find an epilogue sequence, re-instate
the correct unwind instructions if there is more code past
that epilogue -- this will correctly handle an x86 function
with multiple epilogues in it.
NB there is still a bug with the "eh_frame augmented"
UnwindPlans and mid-function epilogues. Looking at that next.
<rdar://problem/18863406>
llvm-svn: 225770
Diffstat (limited to 'lldb/source/Commands')
-rw-r--r-- | lldb/source/Commands/CommandObjectTarget.cpp | 84 |
1 files changed, 62 insertions, 22 deletions
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index d48a29bc0a3..0d9ffda1e96 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -3744,45 +3744,85 @@ protected: if (func_unwinders_sp.get() == NULL) continue; - Address first_non_prologue_insn (func_unwinders_sp->GetFirstNonPrologueInsn(*target)); - if (first_non_prologue_insn.IsValid()) - { - result.GetOutputStream().Printf("First non-prologue instruction is at address 0x%" PRIx64 " or offset %" PRId64 " into the function.\n", first_non_prologue_insn.GetLoadAddress(target), first_non_prologue_insn.GetLoadAddress(target) - start_addr); - result.GetOutputStream().Printf ("\n"); - } + result.GetOutputStream().Printf("UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread.get(), -1); if (non_callsite_unwind_plan.get()) { - result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); - non_callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); - result.GetOutputStream().Printf ("\n"); + result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", non_callsite_unwind_plan->GetSourceName().AsCString()); } - UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1); if (callsite_unwind_plan.get()) { - result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); - callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); - result.GetOutputStream().Printf ("\n"); + result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString()); + } + UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get()); + if (fast_unwind_plan.get()) + { + result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString()); } - UnwindPlanSP arch_default_unwind_plan = func_unwinders_sp->GetUnwindPlanArchitectureDefault(*thread.get()); - if (arch_default_unwind_plan.get()) + result.GetOutputStream().Printf("\n"); + + UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread.get(), 0); + if (assembly_sp) { - result.GetOutputStream().Printf("Architecture default UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); - arch_default_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); - result.GetOutputStream().Printf ("\n"); + result.GetOutputStream().Printf("Assembly language inspection UnwindPlan:\n"); + assembly_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); + result.GetOutputStream().Printf("\n"); } + - UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get()); - if (fast_unwind_plan.get()) + UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0); + if (ehframe_sp) + { + result.GetOutputStream().Printf("eh_frame UnwindPlan:\n"); + ehframe_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); + result.GetOutputStream().Printf("\n"); + } + + UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread.get(), 0); + if (ehframe_augmented_sp) { - result.GetOutputStream().Printf("Fast UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); + result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n"); + ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); + result.GetOutputStream().Printf("\n"); + } + + UnwindPlanSP compact_unwind_sp = func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0); + if (compact_unwind_sp) + { + result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n"); + compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); + result.GetOutputStream().Printf("\n"); + } + + if (fast_unwind_plan) + { + result.GetOutputStream().Printf("Fast UnwindPlan:\n"); fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); - result.GetOutputStream().Printf ("\n"); + result.GetOutputStream().Printf("\n"); } + ABISP abi_sp = process->GetABI(); + if (abi_sp) + { + UnwindPlan arch_default(lldb::eRegisterKindGeneric); + if (abi_sp->CreateDefaultUnwindPlan (arch_default)) + { + result.GetOutputStream().Printf("Arch default UnwindPlan:\n"); + arch_default.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); + result.GetOutputStream().Printf("\n"); + } + + UnwindPlan arch_entry(lldb::eRegisterKindGeneric); + if (abi_sp->CreateFunctionEntryUnwindPlan (arch_entry)) + { + result.GetOutputStream().Printf("Arch default at entry point UnwindPlan:\n"); + arch_entry.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); + result.GetOutputStream().Printf("\n"); + } + } result.GetOutputStream().Printf ("\n"); } |