From 2157664745ddff0d34e8b0d620d14e0912f4296d Mon Sep 17 00:00:00 2001 From: Sim Sun Date: Thu, 26 Mar 2020 16:59:29 -0700 Subject: arm: clear ip thumb/arm mode bit before move to previous instruction (#131) --- src/arm/Gstep.c | 3 ++- src/dwarf/Gparser.c | 9 ++++++++- src/mi/Gget_proc_name.c | 10 +++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/arm/Gstep.c b/src/arm/Gstep.c index adec02e0..895e8a89 100644 --- a/src/arm/Gstep.c +++ b/src/arm/Gstep.c @@ -46,7 +46,8 @@ arm_exidx_step (struct cursor *c) c->dwarf.loc[UNW_ARM_R15] = DWARF_NULL_LOC; unw_word_t ip = c->dwarf.ip; if (c->dwarf.use_prev_instr) - --ip; + /* The least bit denotes thumb/arm mode, clear it. */ + ip = (ip & ~(unw_word_t)0x1) - 1; /* check dynamic info first --- it overrides everything else */ ret = unwi_find_dynamic_proc_info (c->dwarf.as, ip, &c->dwarf.pi, 1, diff --git a/src/dwarf/Gparser.c b/src/dwarf/Gparser.c index fe7c5817..28fd73c6 100644 --- a/src/dwarf/Gparser.c +++ b/src/dwarf/Gparser.c @@ -440,8 +440,15 @@ fetch_proc_info (struct dwarf_cursor *c, unw_word_t ip) continue, and it's important we get this right, as 'ip' could be right at the function entry and hence FDE edge, or at instruction that manipulates CFA (push/pop). */ + if (c->use_prev_instr) - --ip; + { +#if defined(__arm__) + /* On arm, the least bit denotes thumb/arm mode, clear it. */ + ip &= ~(unw_word_t)0x1; +#endif + --ip; + } memset (&c->pi, 0, sizeof (c->pi)); diff --git a/src/mi/Gget_proc_name.c b/src/mi/Gget_proc_name.c index 840d9007..0b77fa59 100644 --- a/src/mi/Gget_proc_name.c +++ b/src/mi/Gget_proc_name.c @@ -106,7 +106,15 @@ unw_get_proc_name (unw_cursor_t *cursor, char *buf, size_t buf_len, ip = tdep_get_ip (c); #if !defined(__ia64__) if (c->dwarf.use_prev_instr) - --ip; + { +#if defined(__arm__) + /* On arm, the least bit denotes thumb/arm mode, clear it. */ + ip &= ~(unw_word_t)0x1; +#endif + --ip; + } + + #endif error = get_proc_name (tdep_get_as (c), ip, buf, buf_len, offp, tdep_get_as_arg (c)); -- cgit v1.2.1