* alpha-tdep.c (heuristic_proc_desc): Add heuristic to
determine the return address register, needed for OSF/1-3.2C. * config/alpha/tm-alpha.h (T7_REGNUM, T9_REGNUM): Define.
This commit is contained in:
parent
6ceb561287
commit
82a38509d8
|
@ -1,3 +1,9 @@
|
||||||
|
Sat Dec 2 03:02:21 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
|
||||||
|
|
||||||
|
* alpha-tdep.c (heuristic_proc_desc): Add heuristic to
|
||||||
|
determine the return address register, needed for OSF/1-3.2C.
|
||||||
|
* config/alpha/tm-alpha.h (T7_REGNUM, T9_REGNUM): Define.
|
||||||
|
|
||||||
Fri Dec 1 07:23:57 1995 Michael Meissner <meissner@tiktok.cygnus.com>
|
Fri Dec 1 07:23:57 1995 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||||
|
|
||||||
* ppcbug-rom.c (ppcbug_cmds): Turn on MO_GETMEM_READ_SINGLE
|
* ppcbug-rom.c (ppcbug_cmds): Turn on MO_GETMEM_READ_SINGLE
|
||||||
|
|
|
@ -359,6 +359,7 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
|
||||||
int frame_size;
|
int frame_size;
|
||||||
int has_frame_reg = 0;
|
int has_frame_reg = 0;
|
||||||
unsigned long reg_mask = 0;
|
unsigned long reg_mask = 0;
|
||||||
|
int pcreg = -1;
|
||||||
|
|
||||||
if (start_pc == 0)
|
if (start_pc == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -388,17 +389,68 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
|
||||||
int reg = (word & 0x03e00000) >> 21;
|
int reg = (word & 0x03e00000) >> 21;
|
||||||
reg_mask |= 1 << reg;
|
reg_mask |= 1 << reg;
|
||||||
temp_saved_regs.regs[reg] = sp + (short)word;
|
temp_saved_regs.regs[reg] = sp + (short)word;
|
||||||
|
|
||||||
|
/* Starting with OSF/1-3.2C, the system libraries are shipped
|
||||||
|
without local symbols, but they still contain procedure
|
||||||
|
descriptors without a symbol reference. GDB is currently
|
||||||
|
unable to find these procedure descriptors and uses
|
||||||
|
heuristic_proc_desc instead.
|
||||||
|
As some low level compiler support routines (__div*, __add*)
|
||||||
|
use a non-standard return address register, we have to
|
||||||
|
add some heuristics to determine the return address register,
|
||||||
|
or stepping over these routines will fail.
|
||||||
|
Usually the return address register is the first register
|
||||||
|
saved on the stack, but assembler optimization might
|
||||||
|
rearrange the register saves.
|
||||||
|
So we recognize only a few registers (t7, t9, ra) within
|
||||||
|
the procedure prologue as valid return address registers.
|
||||||
|
|
||||||
|
FIXME: Rewriting GDB to access the procedure descriptors,
|
||||||
|
e.g. via the minimal symbol table, might obviate this hack. */
|
||||||
|
if (pcreg == -1
|
||||||
|
&& cur_pc < (start_pc + 20)
|
||||||
|
&& (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM))
|
||||||
|
pcreg = reg;
|
||||||
}
|
}
|
||||||
else if (word == 0x47de040f) /* bis sp,sp fp */
|
else if (word == 0x47de040f) /* bis sp,sp fp */
|
||||||
has_frame_reg = 1;
|
has_frame_reg = 1;
|
||||||
}
|
}
|
||||||
|
if (pcreg == -1)
|
||||||
|
{
|
||||||
|
/* If we haven't found a valid return address register yet,
|
||||||
|
keep searching in the procedure prologue. */
|
||||||
|
while (cur_pc < (limit_pc + 20) && cur_pc < (start_pc + 20))
|
||||||
|
{
|
||||||
|
char buf[4];
|
||||||
|
unsigned long word;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = read_memory_nobpt (cur_pc, buf, 4);
|
||||||
|
if (status)
|
||||||
|
memory_error (status, cur_pc);
|
||||||
|
cur_pc += 4;
|
||||||
|
word = extract_unsigned_integer (buf, 4);
|
||||||
|
|
||||||
|
if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */
|
||||||
|
&& (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */
|
||||||
|
{
|
||||||
|
int reg = (word & 0x03e00000) >> 21;
|
||||||
|
if (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM)
|
||||||
|
{
|
||||||
|
pcreg = reg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (has_frame_reg)
|
if (has_frame_reg)
|
||||||
PROC_FRAME_REG(&temp_proc_desc) = GCC_FP_REGNUM;
|
PROC_FRAME_REG(&temp_proc_desc) = GCC_FP_REGNUM;
|
||||||
else
|
else
|
||||||
PROC_FRAME_REG(&temp_proc_desc) = SP_REGNUM;
|
PROC_FRAME_REG(&temp_proc_desc) = SP_REGNUM;
|
||||||
PROC_FRAME_OFFSET(&temp_proc_desc) = frame_size;
|
PROC_FRAME_OFFSET(&temp_proc_desc) = frame_size;
|
||||||
PROC_REG_MASK(&temp_proc_desc) = reg_mask;
|
PROC_REG_MASK(&temp_proc_desc) = reg_mask;
|
||||||
PROC_PC_REG(&temp_proc_desc) = RA_REGNUM;
|
PROC_PC_REG(&temp_proc_desc) = (pcreg == -1) ? RA_REGNUM : pcreg;
|
||||||
PROC_LOCALOFF(&temp_proc_desc) = 0; /* XXX - bogus */
|
PROC_LOCALOFF(&temp_proc_desc) = 0; /* XXX - bogus */
|
||||||
return &temp_proc_desc;
|
return &temp_proc_desc;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue