summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Labath <labath@google.com>2016-07-13 10:55:24 +0000
committerPavel Labath <labath@google.com>2016-07-13 10:55:24 +0000
commit1ee89eb8d9cbee88595c6715c53bd74983722048 (patch)
treece1c7e13fe4cc870329ffe34f194bd9bf56f0663
parent10e9e59898faab77fbb7a4e8a8034130ca3216c4 (diff)
downloadbcm5719-llvm-1ee89eb8d9cbee88595c6715c53bd74983722048.tar.gz
bcm5719-llvm-1ee89eb8d9cbee88595c6715c53bd74983722048.zip
Add "support" for DW_CFA_GNU_args_size to the unwinder
Summary: This adds the knowledge of the DW_CFA_GNU_args_size instruction to the eh_frame parsing code. Right now it is ignored as I am unsure how is it supposed to be handled, but now we are at least able to parse the rest of the FDE containing this instruction. I also add a fix for a bug which was exposed by this instruction. Namely, a mismatched sequence of remember/restore instructions in the input could cause us to pop an empty stack and crash. Now we just log the error and ignore the offending instruction. Reviewers: jasonmolenda Subscribers: lldb-commits Differential Revision: http://reviews.llvm.org/D22266 llvm-svn: 275260
-rw-r--r--lldb/source/Symbol/DWARFCallFrameInfo.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/lldb/source/Symbol/DWARFCallFrameInfo.cpp b/lldb/source/Symbol/DWARFCallFrameInfo.cpp
index 671fe0020ee..51934daefbf 100644
--- a/lldb/source/Symbol/DWARFCallFrameInfo.cpp
+++ b/lldb/source/Symbol/DWARFCallFrameInfo.cpp
@@ -408,6 +408,7 @@ DWARFCallFrameInfo::GetFDEIndex ()
bool
DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr, UnwindPlan& unwind_plan)
{
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND);
lldb::offset_t offset = dwarf_offset;
lldb::offset_t current_entry = offset;
@@ -648,6 +649,15 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr
// the stack and place them in the current row. (This operation is
// useful for compilers that move epilogue code into the body of a
// function.)
+ if (stack.empty())
+ {
+ if (log)
+ log->Printf(
+ "DWARFCallFrameInfo::%s(dwarf_offset: %" PRIx32 ", startaddr: %" PRIx64
+ " encountered DW_CFA_restore_state but state stack is empty. Corrupt unwind info?",
+ __FUNCTION__, dwarf_offset, startaddr.GetFileAddress());
+ break;
+ }
lldb::addr_t offset = row->GetOffset ();
row = stack.back ();
stack.pop_back ();
@@ -655,6 +665,16 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr
break;
}
+ case DW_CFA_GNU_args_size: // 0x2e
+ {
+ // The DW_CFA_GNU_args_size instruction takes an unsigned LEB128 operand
+ // representing an argument size. This instruction specifies the total of
+ // the size of the arguments which have been pushed onto the stack.
+
+ // TODO: Figure out how we should handle this.
+ m_cfi_data.GetULEB128(&offset);
+ }
+
case DW_CFA_val_offset : // 0x14
case DW_CFA_val_offset_sf : // 0x15
default:
OpenPOWER on IntegriCloud