diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2003-10-23 22:06:37 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2003-10-23 22:06:37 +0000 |
commit | 4afcc5985a050978c2811a89e7dc561abf2e563f (patch) | |
tree | 5ce410d130c562625652f8be9e2b159816171cf1 /gdb/ia64-tdep.c | |
parent | 6cfae0bc979800cc8d68cf429d351b4334cd885a (diff) | |
download | gdb-4afcc5985a050978c2811a89e7dc561abf2e563f.zip gdb-4afcc5985a050978c2811a89e7dc561abf2e563f.tar.gz gdb-4afcc5985a050978c2811a89e7dc561abf2e563f.tar.bz2 |
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.
Diffstat (limited to 'gdb/ia64-tdep.c')
-rw-r--r-- | gdb/ia64-tdep.c | 220 |
1 files changed, 175 insertions, 45 deletions
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index 703493f..7f973b9 100644 --- a/gdb/ia64-tdep.c +++ b/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,18 +1653,20 @@ 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) { - CORE_ADDR cfm = 0; - frame_unwind_register (next_frame, IA64_PFS_REGNUM, valuep); + *lvalp = lval_memory; + *addrp = addr; + read_memory (addr, valuep, register_size (current_gdbarch, regnum)); } - else + else if (cache->prev_cfm) + store_unsigned_integer (valuep, register_size (current_gdbarch, regnum), cache->prev_cfm); + else if (cache->frameless) { - addr = cache->saved_regs[IA64_CFM_REGNUM]; - if (addr != 0) - read_memory (addr, valuep, register_size (current_gdbarch, regnum)); + CORE_ADDR cfm = 0; + frame_unwind_register (next_frame, IA64_PFS_REGNUM, valuep); } } 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) { - frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf); + *lvalp = lval_memory; + *addrp = addr; + read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM)); pc = extract_unsigned_integer (buf, 8); } - else + else if (cache->frameless) { - 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); - } + frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf); + 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) { - CORE_ADDR pc; - frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf); + *lvalp = lval_memory; + *addrp = addr; + read_memory (addr, buf, register_size (current_gdbarch, IA64_IP_REGNUM)); pc = extract_unsigned_integer (buf, 8); } - else + else if (cache->frameless) { - 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); - } + CORE_ADDR pc; + frame_unwind_register (next_frame, IA64_BR0_REGNUM, buf); + 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]; + + 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)); + } + } - ia64_frame_prev_register (next_frame, this_cache, regnum, - optimizedp, lvalp, addrp, realnump, valuep); + 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 |