MIPS: Make the extracted stack offset signed in the prologue scanner
Make the extracted stack offset signed in the standard MIPS prologue scanner, to simplify handling and make sure register offsets are correct in all cases, especially where $fp equals the virtual frame pointer (old GCC frames) and therefore offsets to save slots are negative. * mips-tdep.c (mips32_scan_prologue): Make the extracted stack offset signed.
This commit is contained in:
parent
0300bbc7c5
commit
eaa6a9a482
2 changed files with 16 additions and 10 deletions
|
@ -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.
|
||||
|
|
|
@ -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) */
|
||||
|
|
Loading…
Add table
Reference in a new issue