mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 18:14:13 +08:00
2003-10-23 Jeff Johnston <jjohnstn@redhat.com>
* ia64-tdep.c: (ia64_frame_cache): Add new prev_cfm field. (pseudo_regs): Add comment regarding register stack registers. (ia64_alloc_frame_cache): Initialize new prev_cfm field to 0. (floatformat_valid): New static routine. (floatformat_ia64_ext): Add name field and set up is_valid routine to floatformat_valid(). (examine_prologue): For the previous cfm, use frame_unwind_register() if the cfm is not stored in a register-stack register. Save the previous cfm value in the prev_cfm field. Add debug output. (ia64_frame_this_id): Use frame_id_build_special() to also register the bsp. Add debug output. (ia64_sigtramp_frame_this_id): Ditto. (ia64_frame_prev_register): Look at cache saved_regs for a few more registers and also add some checks for framelessness before accepting current register values for fields such as return address. For cfm, use the cached prev_cfm field if available. Add comment to explain PSR logic. Add debug output. (ia64_sigtramp_frame_init_saved_regs): Save the bsp and sp addresses as part of initialization. (ia64_sigtramp_frame_cache): Hard-code stack size as it can't be calculated. Cache the bsp and cfm values. (ia64_sigtramp_frame_prev_register): Add logic to this routine out instead of using ia64_frame_prev_register() which doesn't expect most registers to be saved. The saved values for bsp and sp can be taken from the cache. Add debug output. (ia64_push_dummy_call): Use frame_id_build_special() to also register the bsp.
This commit is contained in:
parent
6cfae0bc97
commit
4afcc5985a
@ -1,3 +1,34 @@
|
||||
2003-10-23 Jeff Johnston <jjohnstn@redhat.com>
|
||||
|
||||
* ia64-tdep.c: (ia64_frame_cache): Add new prev_cfm field.
|
||||
(pseudo_regs): Add comment regarding register stack registers.
|
||||
(ia64_alloc_frame_cache): Initialize new prev_cfm field to 0.
|
||||
(floatformat_valid): New static routine.
|
||||
(floatformat_ia64_ext): Add name field and set up is_valid routine
|
||||
to floatformat_valid().
|
||||
(examine_prologue): For the previous cfm, use
|
||||
frame_unwind_register()
|
||||
if the cfm is not stored in a register-stack register. Save the
|
||||
previous cfm value in the prev_cfm field. Add debug output.
|
||||
(ia64_frame_this_id): Use frame_id_build_special() to also register
|
||||
the bsp. Add debug output.
|
||||
(ia64_sigtramp_frame_this_id): Ditto.
|
||||
(ia64_frame_prev_register): Look at cache saved_regs for a few more
|
||||
registers and also add some checks for framelessness before accepting
|
||||
current register values for fields such as return address. For cfm,
|
||||
use the cached prev_cfm field if available. Add comment to explain
|
||||
PSR logic. Add debug output.
|
||||
(ia64_sigtramp_frame_init_saved_regs): Save the bsp and sp addresses
|
||||
as part of initialization.
|
||||
(ia64_sigtramp_frame_cache): Hard-code stack size as it can't be
|
||||
calculated. Cache the bsp and cfm values.
|
||||
(ia64_sigtramp_frame_prev_register): Add logic to this routine out
|
||||
instead of using ia64_frame_prev_register() which doesn't expect most
|
||||
registers to be saved. The saved values for bsp and sp
|
||||
can be taken from the cache. Add debug output.
|
||||
(ia64_push_dummy_call): Use frame_id_build_special() to also register
|
||||
the bsp.
|
||||
|
||||
2003-10-23 Jim Blandy <jimb@redhat.com>
|
||||
|
||||
* osabi.c (gdbarch_init_osabi): A handler is okay if it's for an
|
||||
|
222
gdb/ia64-tdep.c
222
gdb/ia64-tdep.c
@ -108,7 +108,7 @@ static int fp_regnum = IA64_VFP_REGNUM;
|
||||
static int lr_regnum = IA64_VRAP_REGNUM;
|
||||
|
||||
/* NOTE: we treat the register stack registers r32-r127 as pseudo-registers because
|
||||
they are in memory and must be calculated via the bsp register. */
|
||||
they may not be accessible via the ptrace register get/set interfaces. */
|
||||
enum pseudo_regs { FIRST_PSEUDO_REGNUM = NUM_IA64_RAW_REGS, VBOF_REGNUM = IA64_NAT127_REGNUM + 1, V32_REGNUM,
|
||||
V127_REGNUM = V32_REGNUM + 95,
|
||||
VP0_REGNUM, VP16_REGNUM = VP0_REGNUM + 16, VP63_REGNUM = VP0_REGNUM + 63, LAST_PSEUDO_REGNUM };
|
||||
@ -232,6 +232,7 @@ struct ia64_frame_cache
|
||||
CORE_ADDR saved_sp; /* stack pointer for frame */
|
||||
CORE_ADDR bsp; /* points at r32 for the current frame */
|
||||
CORE_ADDR cfm; /* cfm value for current frame */
|
||||
CORE_ADDR prev_cfm; /* cfm value for previous frame */
|
||||
int frameless;
|
||||
int sof; /* Size of frame (decoded from cfm value) */
|
||||
int sol; /* Size of locals (decoded from cfm value) */
|
||||
@ -316,10 +317,18 @@ ia64_dwarf_reg_to_regnum (int reg)
|
||||
return reg;
|
||||
}
|
||||
|
||||
static int
|
||||
floatformat_valid (fmt, from)
|
||||
const struct floatformat *fmt;
|
||||
const char *from;
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const struct floatformat floatformat_ia64_ext =
|
||||
{
|
||||
floatformat_little, 82, 0, 1, 17, 65535, 0x1ffff, 18, 64,
|
||||
floatformat_intbit_yes
|
||||
floatformat_intbit_yes, "floatformat_ia64_ext", floatformat_valid
|
||||
};
|
||||
|
||||
|
||||
@ -1030,6 +1039,7 @@ ia64_alloc_frame_cache (void)
|
||||
cache->base = 0;
|
||||
cache->pc = 0;
|
||||
cache->cfm = 0;
|
||||
cache->prev_cfm = 0;
|
||||
cache->sof = 0;
|
||||
cache->sol = 0;
|
||||
cache->sor = 0;
|
||||
@ -1450,9 +1460,20 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *next_frame,
|
||||
|
||||
/* For the previous argument registers we require the previous bof.
|
||||
If we can't find the previous cfm, then we can do nothing. */
|
||||
cfm = 0;
|
||||
if (cache->saved_regs[IA64_CFM_REGNUM] != 0)
|
||||
{
|
||||
cfm = read_memory_integer (cache->saved_regs[IA64_CFM_REGNUM], 8);
|
||||
}
|
||||
else if (cfm_reg != 0)
|
||||
{
|
||||
frame_unwind_register (next_frame, cfm_reg, buf);
|
||||
cfm = extract_unsigned_integer (buf, 8);
|
||||
}
|
||||
cache->prev_cfm = cfm;
|
||||
|
||||
if (cfm != 0)
|
||||
{
|
||||
sor = ((cfm >> 14) & 0xf) * 8;
|
||||
sof = (cfm & 0x7f);
|
||||
sol = (cfm >> 7) & 0x7f;
|
||||
@ -1564,7 +1585,11 @@ ia64_frame_this_id (struct frame_info *next_frame, void **this_cache,
|
||||
if (cache->base == 0)
|
||||
return;
|
||||
|
||||
(*this_id) = frame_id_build (cache->base, cache->pc);
|
||||
(*this_id) = frame_id_build_special (cache->base, cache->pc, cache->bsp);
|
||||
if (gdbarch_debug >= 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"regular frame id: code %lx, stack %lx, special %lx, next_frame %p\n",
|
||||
this_id->code_addr, this_id->stack_addr, cache->bsp, next_frame);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1628,19 +1653,21 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
|
||||
}
|
||||
else if (regnum == IA64_CFM_REGNUM)
|
||||
{
|
||||
CORE_ADDR addr = 0;
|
||||
|
||||
if (cache->frameless)
|
||||
CORE_ADDR addr = cache->saved_regs[IA64_CFM_REGNUM];
|
||||
|
||||
if (addr != 0)
|
||||
{
|
||||
*lvalp = lval_memory;
|
||||
*addrp = addr;
|
||||
read_memory (addr, valuep, register_size (current_gdbarch, regnum));
|
||||
}
|
||||
else if (cache->prev_cfm)
|
||||
store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), cache->prev_cfm);
|
||||
else if (cache->frameless)
|
||||
{
|
||||
CORE_ADDR cfm = 0;
|
||||
frame_unwind_register (next_frame, IA64_PFS_REGNUM, valuep);
|
||||
}
|
||||
else
|
||||
{
|
||||
addr = cache->saved_regs[IA64_CFM_REGNUM];
|
||||
if (addr != 0)
|
||||
read_memory (addr, valuep, register_size (current_gdbarch, regnum));
|
||||
}
|
||||
}
|
||||
else if (regnum == IA64_VFP_REGNUM)
|
||||
{
|
||||
@ -1727,53 +1754,68 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
|
||||
else if (regnum == IA64_IP_REGNUM)
|
||||
{
|
||||
CORE_ADDR pc = 0;
|
||||
CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
|
||||
|
||||
if (cache->frameless)
|
||||
if (addr != 0)
|
||||
{
|
||||
*lvalp = lval_memory;
|
||||
*addrp = addr;
|
||||
read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
|
||||
pc = extract_unsigned_integer (buf, 8);
|
||||
}
|
||||
else if (cache->frameless)
|
||||
{
|
||||
frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
|
||||
pc = extract_unsigned_integer (buf, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
|
||||
if (addr != 0)
|
||||
{
|
||||
read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
|
||||
pc = extract_unsigned_integer (buf, 8);
|
||||
}
|
||||
}
|
||||
pc &= ~0xf;
|
||||
store_unsigned_integer (valuep, 8, pc);
|
||||
}
|
||||
else if (regnum == IA64_PSR_REGNUM)
|
||||
{
|
||||
/* We don't know how to get the complete previous PSR, but we need it for
|
||||
the slot information when we unwind the pc (pc is formed of IP register
|
||||
plus slot information from PSR). To get the previous slot information,
|
||||
we mask it off the return address. */
|
||||
ULONGEST slot_num = 0;
|
||||
CORE_ADDR pc= 0;
|
||||
CORE_ADDR psr = 0;
|
||||
CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
|
||||
|
||||
frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
|
||||
psr = extract_unsigned_integer (buf, 8);
|
||||
|
||||
if (cache->frameless)
|
||||
if (addr != 0)
|
||||
{
|
||||
*lvalp = lval_memory;
|
||||
*addrp = addr;
|
||||
read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
|
||||
pc = extract_unsigned_integer (buf, 8);
|
||||
}
|
||||
else if (cache->frameless)
|
||||
{
|
||||
CORE_ADDR pc;
|
||||
frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf);
|
||||
pc = extract_unsigned_integer (buf, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
|
||||
if (addr != 0)
|
||||
{
|
||||
read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
|
||||
pc = extract_unsigned_integer (buf, 8);
|
||||
}
|
||||
}
|
||||
psr &= ~(3LL << 41);
|
||||
slot_num = pc & 0x3LL;
|
||||
psr |= (CORE_ADDR)slot_num << 41;
|
||||
store_unsigned_integer (valuep, 8, psr);
|
||||
}
|
||||
else if (regnum == IA64_BR0_REGNUM)
|
||||
{
|
||||
CORE_ADDR br0 = 0;
|
||||
CORE_ADDR addr = cache->saved_regs[IA64_BR0_REGNUM];
|
||||
if (addr != 0)
|
||||
{
|
||||
*lvalp = lval_memory;
|
||||
*addrp = addr;
|
||||
read_memory (addr, buf, register_size (current_gdbarch, IA64_BR0_REGNUM));
|
||||
br0 = extract_unsigned_integer (buf, 8);
|
||||
}
|
||||
store_unsigned_integer (valuep, 8, br0);
|
||||
}
|
||||
else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) ||
|
||||
(regnum >= V32_REGNUM && regnum <= V127_REGNUM))
|
||||
{
|
||||
@ -1839,6 +1881,12 @@ ia64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
|
||||
else
|
||||
frame_unwind_register (next_frame, regnum, valuep);
|
||||
}
|
||||
|
||||
if (gdbarch_debug >= 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"regular prev register <%d> <%s> is %lx\n", regnum,
|
||||
(((unsigned) regnum <= IA64_NAT127_REGNUM)
|
||||
? ia64_register_names[regnum] : "r??"), extract_unsigned_integer (valuep, 8));
|
||||
}
|
||||
|
||||
static const struct frame_unwind ia64_frame_unwind =
|
||||
@ -1869,10 +1917,8 @@ ia64_sigtramp_frame_init_saved_regs (struct ia64_frame_cache *cache)
|
||||
SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_CFM_REGNUM);
|
||||
cache->saved_regs[IA64_PSR_REGNUM] =
|
||||
SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_PSR_REGNUM);
|
||||
#if 0
|
||||
cache->saved_regs[IA64_BSP_REGNUM] =
|
||||
SIGCONTEXT_REGISTER_ADDRESS (frame->frame, IA64_BSP_REGNUM);
|
||||
#endif
|
||||
SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_BSP_REGNUM);
|
||||
cache->saved_regs[IA64_RNAT_REGNUM] =
|
||||
SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_RNAT_REGNUM);
|
||||
cache->saved_regs[IA64_CCV_REGNUM] =
|
||||
@ -1886,9 +1932,8 @@ ia64_sigtramp_frame_init_saved_regs (struct ia64_frame_cache *cache)
|
||||
cache->saved_regs[IA64_LC_REGNUM] =
|
||||
SIGCONTEXT_REGISTER_ADDRESS (cache->base, IA64_LC_REGNUM);
|
||||
for (regno = IA64_GR1_REGNUM; regno <= IA64_GR31_REGNUM; regno++)
|
||||
if (regno != sp_regnum)
|
||||
cache->saved_regs[regno] =
|
||||
SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
|
||||
cache->saved_regs[regno] =
|
||||
SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
|
||||
for (regno = IA64_BR0_REGNUM; regno <= IA64_BR7_REGNUM; regno++)
|
||||
cache->saved_regs[regno] =
|
||||
SIGCONTEXT_REGISTER_ADDRESS (cache->base, regno);
|
||||
@ -1912,7 +1957,16 @@ ia64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
|
||||
cache = ia64_alloc_frame_cache ();
|
||||
|
||||
frame_unwind_register (next_frame, sp_regnum, buf);
|
||||
cache->base = extract_unsigned_integer (buf, 8) + cache->mem_stack_frame_size;
|
||||
/* Note that frame size is hard-coded below. We cannot calculate it
|
||||
via prologue examination. */
|
||||
cache->base = extract_unsigned_integer (buf, 8) + 16;
|
||||
|
||||
frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
|
||||
cache->bsp = extract_unsigned_integer (buf, 8);
|
||||
|
||||
frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
|
||||
cache->cfm = extract_unsigned_integer (buf, 8);
|
||||
cache->sof = cache->cfm & 0x7f;
|
||||
|
||||
ia64_sigtramp_frame_init_saved_regs (cache);
|
||||
|
||||
@ -1927,7 +1981,11 @@ ia64_sigtramp_frame_this_id (struct frame_info *next_frame,
|
||||
struct ia64_frame_cache *cache =
|
||||
ia64_sigtramp_frame_cache (next_frame, this_cache);
|
||||
|
||||
(*this_id) = frame_id_build (cache->base, frame_pc_unwind (next_frame));
|
||||
(*this_id) = frame_id_build_special (cache->base, frame_pc_unwind (next_frame), cache->bsp);
|
||||
if (gdbarch_debug >= 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"sigtramp frame id: code %lx, stack %lx, special %lx, next_frame %p\n",
|
||||
this_id->code_addr, this_id->stack_addr, cache->bsp, next_frame);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1937,11 +1995,75 @@ ia64_sigtramp_frame_prev_register (struct frame_info *next_frame,
|
||||
enum lval_type *lvalp, CORE_ADDR *addrp,
|
||||
int *realnump, void *valuep)
|
||||
{
|
||||
/* Make sure we've initialized the cache. */
|
||||
ia64_sigtramp_frame_cache (next_frame, this_cache);
|
||||
char dummy_valp[MAX_REGISTER_SIZE];
|
||||
char buf[MAX_REGISTER_SIZE];
|
||||
|
||||
ia64_frame_prev_register (next_frame, this_cache, regnum,
|
||||
optimizedp, lvalp, addrp, realnump, valuep);
|
||||
struct ia64_frame_cache *cache =
|
||||
ia64_sigtramp_frame_cache (next_frame, this_cache);
|
||||
|
||||
gdb_assert (regnum >= 0);
|
||||
|
||||
if (!target_has_registers)
|
||||
error ("No registers.");
|
||||
|
||||
*optimizedp = 0;
|
||||
*addrp = 0;
|
||||
*lvalp = not_lval;
|
||||
*realnump = -1;
|
||||
|
||||
/* Rather than check each time if valuep is non-null, supply a dummy buffer
|
||||
when valuep is not supplied. */
|
||||
if (!valuep)
|
||||
valuep = dummy_valp;
|
||||
|
||||
memset (valuep, 0, register_size (current_gdbarch, regnum));
|
||||
|
||||
if (regnum == IA64_IP_REGNUM)
|
||||
{
|
||||
CORE_ADDR pc = 0;
|
||||
CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
|
||||
|
||||
if (addr != 0)
|
||||
{
|
||||
*lvalp = lval_memory;
|
||||
*addrp = addr;
|
||||
read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM));
|
||||
pc = extract_unsigned_integer (buf, 8);
|
||||
}
|
||||
pc &= ~0xf;
|
||||
store_unsigned_integer (valuep, 8, pc);
|
||||
}
|
||||
else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM) ||
|
||||
(regnum >= V32_REGNUM && regnum <= V127_REGNUM))
|
||||
{
|
||||
CORE_ADDR addr = 0;
|
||||
if (regnum >= V32_REGNUM)
|
||||
regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
|
||||
addr = cache->saved_regs[regnum];
|
||||
if (addr != 0)
|
||||
{
|
||||
*lvalp = lval_memory;
|
||||
*addrp = addr;
|
||||
read_memory (addr, valuep, register_size (current_gdbarch, regnum));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* All other registers not listed above. */
|
||||
CORE_ADDR addr = cache->saved_regs[regnum];
|
||||
if (addr != 0)
|
||||
{
|
||||
*lvalp = lval_memory;
|
||||
*addrp = addr;
|
||||
read_memory (addr, valuep, register_size (current_gdbarch, regnum));
|
||||
}
|
||||
}
|
||||
|
||||
if (gdbarch_debug >= 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"sigtramp prev register <%s> is %lx\n",
|
||||
(((unsigned) regnum <= IA64_NAT127_REGNUM)
|
||||
? ia64_register_names[regnum] : "r??"), extract_unsigned_integer (valuep, 8));
|
||||
}
|
||||
|
||||
static const struct frame_unwind ia64_sigtramp_frame_unwind =
|
||||
@ -2474,12 +2596,20 @@ static struct frame_id
|
||||
ia64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
|
||||
{
|
||||
char buf[8];
|
||||
CORE_ADDR sp;
|
||||
CORE_ADDR sp, bsp;
|
||||
|
||||
frame_unwind_register (next_frame, sp_regnum, buf);
|
||||
sp = extract_unsigned_integer (buf, 8);
|
||||
|
||||
return frame_id_build (sp, frame_pc_unwind (next_frame));
|
||||
frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
|
||||
bsp = extract_unsigned_integer (buf, 8);
|
||||
|
||||
if (gdbarch_debug >= 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"dummy frame id: code %lx, stack %lx, special %lx\n",
|
||||
frame_pc_unwind (next_frame), sp, bsp);
|
||||
|
||||
return frame_id_build_special (sp, frame_pc_unwind (next_frame), bsp);
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
|
Loading…
Reference in New Issue
Block a user