diff options
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/mips-tdep.c | 21 |
2 files changed, 16 insertions, 10 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8b016dc..1d1e32c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2015-01-02 Maciej W. Rozycki <macro@codesourcery.com> + + * mips-tdep.c (mips32_scan_prologue): Keep the extracted stack + offset signed. + 2015-01-02 Doug Evans <dje@google.com> * dwarf2read.c (setup_type_unit_groups): Remove outdated comment. diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 5cd66a1..bd8faef 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -3438,7 +3438,8 @@ restart: frame_offset = 0; for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS_INSN32_SIZE) { - unsigned long inst, high_word, low_word; + unsigned long inst, high_word; + long offset; int reg; this_non_prologue_insn = 0; @@ -3450,15 +3451,15 @@ restart: /* Save some code by pre-extracting some useful fields. */ high_word = (inst >> 16) & 0xffff; - low_word = inst & 0xffff; + offset = ((inst & 0xffff) ^ 0x8000) - 0x8000; reg = high_word & 0x1f; if (high_word == 0x27bd /* addiu $sp,$sp,-i */ || high_word == 0x23bd /* addi $sp,$sp,-i */ || high_word == 0x67bd) /* daddiu $sp,$sp,-i */ { - if (low_word & 0x8000) /* Negative stack adjustment? */ - frame_offset += 0x10000 - low_word; + if (offset < 0) /* Negative stack adjustment? */ + frame_offset -= offset; else /* Exit loop if a positive stack adjustment is found, which usually means that the stack cleanup code in the function @@ -3469,19 +3470,19 @@ restart: else if (((high_word & 0xFFE0) == 0xafa0) /* sw reg,offset($sp) */ && !regsize_is_64_bits) { - set_reg_offset (gdbarch, this_cache, reg, sp + low_word); + set_reg_offset (gdbarch, this_cache, reg, sp + offset); } else if (((high_word & 0xFFE0) == 0xffa0) /* sd reg,offset($sp) */ && regsize_is_64_bits) { /* Irix 6.2 N32 ABI uses sd instructions for saving $gp and $ra. */ - set_reg_offset (gdbarch, this_cache, reg, sp + low_word); + set_reg_offset (gdbarch, this_cache, reg, sp + offset); } else if (high_word == 0x27be) /* addiu $30,$sp,size */ { /* Old gcc frame, r30 is virtual frame pointer. */ - if ((long) low_word != frame_offset) - frame_addr = sp + low_word; + if (offset != frame_offset) + frame_addr = sp + offset; else if (this_frame && frame_reg == MIPS_SP_REGNUM) { unsigned alloca_adjust; @@ -3491,7 +3492,7 @@ restart: (this_frame, gdbarch_num_regs (gdbarch) + 30); frame_offset = 0; - alloca_adjust = (unsigned) (frame_addr - (sp + low_word)); + alloca_adjust = (unsigned) (frame_addr - (sp + offset)); if (alloca_adjust > 0) { /* FP > SP + frame_size. This may be because of @@ -3540,7 +3541,7 @@ restart: else if ((high_word & 0xFFE0) == 0xafc0 /* sw reg,offset($30) */ && !regsize_is_64_bits) { - set_reg_offset (gdbarch, this_cache, reg, frame_addr + low_word); + set_reg_offset (gdbarch, this_cache, reg, frame_addr + offset); } else if ((high_word & 0xFFE0) == 0xE7A0 /* swc1 freg,n($sp) */ || (high_word & 0xF3E0) == 0xA3C0 /* sx reg,n($s8) */ |