summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
diff options
context:
space:
mode:
authorPavel Labath <pavel@labath.sk>2019-04-23 09:57:14 +0000
committerPavel Labath <pavel@labath.sk>2019-04-23 09:57:14 +0000
commit2359429168a8f8882cd9caaac7c4e24803fabbb8 (patch)
tree2ee2f40090721a91dbf336dc7425792725e254dc /lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
parent1cdc3dbc58923f66758b9b718175db2e41e80b0d (diff)
downloadbcm5719-llvm-2359429168a8f8882cd9caaac7c4e24803fabbb8.tar.gz
bcm5719-llvm-2359429168a8f8882cd9caaac7c4e24803fabbb8.zip
FuncUnwinders: remove "current_offset" from function arguments
Summary: This argument was added back in 2010 (r118882) to support the ability to unwind from functions whose eh_frame entry does not cover the entire range of the function. However, due to the caching happening in FuncUnwinders, this solution is very fragile. FuncUnwinders will cache the plan it got from eh_frame regardless of the value of the current_offset, so our ability to unwind from a given function depended what was the value of "current_offset" the first time that this function was called. Furthermore, since the "image show-unwind" command did not know what's the right offset to pass, this created an unfortunate situation where "image show-unwind" would show no valid plans for a function, even though they were available and being used. In this patch I implement the feature slightly differently. Instead of giving just a base address to the eh_frame unwinder, I give it the entire range we are interested in. Then, I change the unwinder to return the first plan that covers (even partially) that range. This way even a partial plan will be returned, regardless of the address in the function where we are stopped at. This solution is still not 100% correct, as it will not handle a function which is covered by two independent fde entries. However, I don't expect anybody will write this kind of functions, and this wasn't handled by the previous implementation either. If this is ever needed in the future. The eh_frame unwinder can be extended to return "composite" unwind plans created by merging sevelar fde entries. I also create a test which triggers this scenario. As doing this is virtually impossible without hand-written assembly, the test only works on x86 linux. Reviewers: jasonmolenda, clayborg Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D60829 llvm-svn: 358964
Diffstat (limited to 'lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp')
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp26
1 files changed, 12 insertions, 14 deletions
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index f328361e7bf..fc37cd33bd8 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -244,8 +244,8 @@ void RegisterContextLLDB::InitializeZerothFrame() {
}
if (func_unwinders_sp.get() != nullptr)
- call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(
- process->GetTarget(), m_current_offset_backed_up_one);
+ call_site_unwind_plan =
+ func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget());
if (call_site_unwind_plan.get() != nullptr) {
m_fallback_unwind_plan_sp = call_site_unwind_plan;
@@ -822,8 +822,8 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
// unwind out of sigtramp.
if (m_frame_type == eTrapHandlerFrame && process) {
m_fast_unwind_plan_sp.reset();
- unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan(
- process->GetTarget(), m_current_offset_backed_up_one);
+ unwind_plan_sp =
+ func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc) &&
unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) {
return unwind_plan_sp;
@@ -844,8 +844,8 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
// normally we would call GetUnwindPlanAtCallSite() -- because CallSite may
// return an unwind plan sourced from either eh_frame (that's what we
// intend) or compact unwind (this won't work)
- unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan(
- process->GetTarget(), m_current_offset_backed_up_one);
+ unwind_plan_sp =
+ func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
UnwindLogMsgVerbose("frame uses %s for full UnwindPlan because the "
"DynamicLoader suggested we prefer it",
@@ -858,7 +858,7 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
// the assembly language instructions
if (behaves_like_zeroth_frame && process) {
unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
- process->GetTarget(), m_thread, m_current_offset_backed_up_one);
+ process->GetTarget(), m_thread);
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
// We probably have an UnwindPlan created by inspecting assembly
@@ -873,8 +873,7 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
// location what helps in the most common cases when the instruction
// emulation fails.
UnwindPlanSP call_site_unwind_plan =
- func_unwinders_sp->GetUnwindPlanAtCallSite(
- process->GetTarget(), m_current_offset_backed_up_one);
+ func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget());
if (call_site_unwind_plan &&
call_site_unwind_plan.get() != unwind_plan_sp.get() &&
call_site_unwind_plan->GetSourceName() !=
@@ -893,8 +892,8 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
// Typically this is unwind info from an eh_frame section intended for
// exception handling; only valid at call sites
if (process) {
- unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite(
- process->GetTarget(), m_current_offset_backed_up_one);
+ unwind_plan_sp =
+ func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget());
}
int valid_offset = -1;
if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) {
@@ -908,7 +907,7 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
// call-site assembly inspection UnwindPlan if possible.
if (process) {
unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
- process->GetTarget(), m_thread, m_current_offset_backed_up_one);
+ process->GetTarget(), m_thread);
}
if (unwind_plan_sp &&
unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
@@ -923,8 +922,7 @@ UnwindPlanSP RegisterContextLLDB::GetFullUnwindPlanForFrame() {
// code it is often written in a way that it valid at all location what
// helps in the most common cases when the instruction emulation fails.
UnwindPlanSP call_site_unwind_plan =
- func_unwinders_sp->GetUnwindPlanAtCallSite(
- process->GetTarget(), m_current_offset_backed_up_one);
+ func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget());
if (call_site_unwind_plan &&
call_site_unwind_plan.get() != unwind_plan_sp.get() &&
call_site_unwind_plan->GetSourceName() !=
OpenPOWER on IntegriCloud