[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Libunwind-devel] [PATCH] dwarf: Fix incorrect application of restore_st
From: |
Dave Watson |
Subject: |
[Libunwind-devel] [PATCH] dwarf: Fix incorrect application of restore_state |
Date: |
Fri, 18 Aug 2017 08:16:34 -0700 |
User-agent: |
Mutt/1.6.0 (2016-04-01) |
Repro for a multilib binary on host x86_64:
CFLAGS="-m32" LDFLAGS="-m32" ./configure --enable-debug --
host=i686-pc-linux-gnu --target=i686-pc-linux-gnu --libdur=/usr/lib32
--prefix=/usr --disable-documentation
make check
Gtest-init function fails trying to step through libc_start_main. The CFA
function is:
DW_CFA_def_cfa_offset: 112
DW_CFA_advance_loc: 5 to ...643
DW_CFA_restore state
Where the return address is 643.
Generally, it appears we apply all ip <= end_ip, which is incorrect in some
circumstances.
libgcc only applies ip < end_ip + is_signal_frame, but that seems to break
async signal handling
tests in libunwind for unknown reasons.
This is somewhat simlar to the fix in e9e8ed73e for GNU_args_size,
where the same ip check was added.
---
src/dwarf/Gparser.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c
index e8eaeac8..9d405e76 100644
--- a/src/dwarf/Gparser.c
+++ b/src/dwarf/Gparser.c
@@ -289,8 +289,10 @@ run_cfi_program (struct dwarf_cursor *c,
dwarf_state_record_t *sr,
ret = -UNW_EINVAL;
break;
}
- memcpy (&sr->rs_current, &(*rs_stack)->state, sizeof
(sr->rs_current));
- pop_rstate_stack(rs_stack);
+ if (*ip < end_ip) {
+ memcpy (&sr->rs_current, &(*rs_stack)->state, sizeof
(sr->rs_current));
+ pop_rstate_stack(rs_stack);
+ }
Debug (15, "CFA_restore_state\n");
break;
--
2.13.5
- [Libunwind-devel] [PATCH] dwarf: Fix incorrect application of restore_state,
Dave Watson <=