* libunwind-frame.h (struct regcache): Add forward declaration.
(libunwind_get_reg_special): Add REGCACHE argument. * libunwind-frame.c (libunwind_get_reg_special): Add REGCACHE argument. Pass it to unw_init_remote_p. * ia64-tdep.c (ia64_pseudo_register_read): Pass regcache to libunwind_get_reg_special. (ia64_access_reg): Remove "write" case. (ia64_access_fpreg): Likewise. Read from next_frame passed as callback argument instead of from current_regcache. (ia64_access_rse_reg): Remove "write" case. Read from regcache passed as callback argument instead of from current_regcache. (ia64_access_rse_fpreg): New function. (ia64_unw_rse_acce): Use it instead of ia64_access_fpreg.
This commit is contained in:
parent
26f43351a7
commit
45ecac4b41
@ -1,3 +1,20 @@
|
||||
2007-05-11 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* libunwind-frame.h (struct regcache): Add forward declaration.
|
||||
(libunwind_get_reg_special): Add REGCACHE argument.
|
||||
* libunwind-frame.c (libunwind_get_reg_special): Add REGCACHE
|
||||
argument. Pass it to unw_init_remote_p.
|
||||
|
||||
* ia64-tdep.c (ia64_pseudo_register_read): Pass regcache to
|
||||
libunwind_get_reg_special.
|
||||
(ia64_access_reg): Remove "write" case.
|
||||
(ia64_access_fpreg): Likewise. Read from next_frame passed
|
||||
as callback argument instead of from current_regcache.
|
||||
(ia64_access_rse_reg): Remove "write" case. Read from regcache
|
||||
passed as callback argument instead of from current_regcache.
|
||||
(ia64_access_rse_fpreg): New function.
|
||||
(ia64_unw_rse_acce): Use it instead of ia64_access_fpreg.
|
||||
|
||||
2007-05-11 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* NEWS: Mention SPU overlay support.
|
||||
|
288
gdb/ia64-tdep.c
288
gdb/ia64-tdep.c
@ -692,7 +692,7 @@ ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
|
||||
/* First try and use the libunwind special reg accessor, otherwise fallback to
|
||||
standard logic. */
|
||||
if (!libunwind_is_initialized ()
|
||||
|| libunwind_get_reg_special (gdbarch, regnum, buf) != 0)
|
||||
|| libunwind_get_reg_special (gdbarch, regcache, regnum, buf) != 0)
|
||||
#endif
|
||||
{
|
||||
/* The fallback position is to assume that r32-r127 are found sequentially
|
||||
@ -2218,106 +2218,53 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
|
||||
long new_sof, old_sof;
|
||||
char buf[MAX_REGISTER_SIZE];
|
||||
|
||||
if (write)
|
||||
{
|
||||
if (regnum < 0)
|
||||
/* ignore writes to pseudo-registers such as UNW_IA64_PROC_STARTI. */
|
||||
return 0;
|
||||
|
||||
switch (uw_regnum)
|
||||
{
|
||||
case UNW_REG_IP:
|
||||
ia64_write_pc (*val, inferior_ptid);
|
||||
break;
|
||||
/* We never call any libunwind routines that need to write registers. */
|
||||
gdb_assert (!write);
|
||||
|
||||
case UNW_IA64_AR_BSPSTORE:
|
||||
write_register (IA64_BSP_REGNUM, *val);
|
||||
break;
|
||||
|
||||
case UNW_IA64_AR_BSP:
|
||||
case UNW_IA64_BSP:
|
||||
/* Account for the fact that ptrace() expects bsp to point
|
||||
after the current register frame. */
|
||||
cfm = read_register (IA64_CFM_REGNUM);
|
||||
sof = (cfm & 0x7f);
|
||||
bsp = ia64_rse_skip_regs (*val, sof);
|
||||
write_register (IA64_BSP_REGNUM, bsp);
|
||||
break;
|
||||
|
||||
case UNW_IA64_CFM:
|
||||
/* If we change CFM, we need to adjust ptrace's notion of
|
||||
bsp accordingly, so that the real bsp remains
|
||||
unchanged. */
|
||||
bsp = read_register (IA64_BSP_REGNUM);
|
||||
cfm = read_register (IA64_CFM_REGNUM);
|
||||
old_sof = (cfm & 0x7f);
|
||||
new_sof = (*val & 0x7f);
|
||||
if (old_sof != new_sof)
|
||||
{
|
||||
bsp = ia64_rse_skip_regs (bsp, -old_sof + new_sof);
|
||||
write_register (IA64_BSP_REGNUM, bsp);
|
||||
}
|
||||
write_register (IA64_CFM_REGNUM, *val);
|
||||
break;
|
||||
|
||||
default:
|
||||
write_register (regnum, *val);
|
||||
break;
|
||||
}
|
||||
if (gdbarch_debug >= 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
" access_reg: to cache: %4s=0x%s\n",
|
||||
(((unsigned) regnum <= IA64_NAT127_REGNUM)
|
||||
? ia64_register_names[regnum] : "r??"),
|
||||
paddr_nz (*val));
|
||||
switch (uw_regnum)
|
||||
{
|
||||
case UNW_REG_IP:
|
||||
/* Libunwind expects to see the pc value which means the slot number
|
||||
from the psr must be merged with the ip word address. */
|
||||
frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
|
||||
ip = extract_unsigned_integer (buf, 8);
|
||||
frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
|
||||
psr = extract_unsigned_integer (buf, 8);
|
||||
*val = ip | ((psr >> 41) & 0x3);
|
||||
break;
|
||||
|
||||
case UNW_IA64_AR_BSP:
|
||||
/* Libunwind expects to see the beginning of the current register
|
||||
frame so we must account for the fact that ptrace() will return a value
|
||||
for bsp that points *after* the current register frame. */
|
||||
frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
|
||||
bsp = extract_unsigned_integer (buf, 8);
|
||||
frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
|
||||
cfm = extract_unsigned_integer (buf, 8);
|
||||
sof = (cfm & 0x7f);
|
||||
*val = ia64_rse_skip_regs (bsp, -sof);
|
||||
break;
|
||||
|
||||
case UNW_IA64_AR_BSPSTORE:
|
||||
/* Libunwind wants bspstore to be after the current register frame.
|
||||
This is what ptrace() and gdb treats as the regular bsp value. */
|
||||
frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
|
||||
*val = extract_unsigned_integer (buf, 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* For all other registers, just unwind the value directly. */
|
||||
frame_unwind_register (next_frame, regnum, buf);
|
||||
*val = extract_unsigned_integer (buf, 8);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (uw_regnum)
|
||||
{
|
||||
case UNW_REG_IP:
|
||||
/* Libunwind expects to see the pc value which means the slot number
|
||||
from the psr must be merged with the ip word address. */
|
||||
frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
|
||||
ip = extract_unsigned_integer (buf, 8);
|
||||
frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
|
||||
psr = extract_unsigned_integer (buf, 8);
|
||||
*val = ip | ((psr >> 41) & 0x3);
|
||||
break;
|
||||
|
||||
case UNW_IA64_AR_BSP:
|
||||
/* Libunwind expects to see the beginning of the current register
|
||||
frame so we must account for the fact that ptrace() will return a value
|
||||
for bsp that points *after* the current register frame. */
|
||||
frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
|
||||
bsp = extract_unsigned_integer (buf, 8);
|
||||
frame_unwind_register (next_frame, IA64_CFM_REGNUM, buf);
|
||||
cfm = extract_unsigned_integer (buf, 8);
|
||||
sof = (cfm & 0x7f);
|
||||
*val = ia64_rse_skip_regs (bsp, -sof);
|
||||
break;
|
||||
|
||||
case UNW_IA64_AR_BSPSTORE:
|
||||
/* Libunwind wants bspstore to be after the current register frame.
|
||||
This is what ptrace() and gdb treats as the regular bsp value. */
|
||||
frame_unwind_register (next_frame, IA64_BSP_REGNUM, buf);
|
||||
*val = extract_unsigned_integer (buf, 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* For all other registers, just unwind the value directly. */
|
||||
frame_unwind_register (next_frame, regnum, buf);
|
||||
*val = extract_unsigned_integer (buf, 8);
|
||||
break;
|
||||
}
|
||||
|
||||
if (gdbarch_debug >= 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
" access_reg: from cache: %4s=0x%s\n",
|
||||
(((unsigned) regnum <= IA64_NAT127_REGNUM)
|
||||
? ia64_register_names[regnum] : "r??"),
|
||||
paddr_nz (*val));
|
||||
}
|
||||
if (gdbarch_debug >= 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
" access_reg: from cache: %4s=0x%s\n",
|
||||
(((unsigned) regnum <= IA64_NAT127_REGNUM)
|
||||
? ia64_register_names[regnum] : "r??"),
|
||||
paddr_nz (*val));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2327,11 +2274,13 @@ ia64_access_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_fpreg_t *val
|
||||
int write, void *arg)
|
||||
{
|
||||
int regnum = ia64_uw2gdb_regnum (uw_regnum);
|
||||
struct frame_info *next_frame = arg;
|
||||
|
||||
if (write)
|
||||
regcache_cooked_write (current_regcache, regnum, (char *) val);
|
||||
else
|
||||
regcache_cooked_read (current_regcache, regnum, (char *) val);
|
||||
/* We never call any libunwind routines that need to write registers. */
|
||||
gdb_assert (!write);
|
||||
|
||||
frame_unwind_register (next_frame, regnum, (char *) val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2342,94 +2291,49 @@ ia64_access_rse_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *va
|
||||
{
|
||||
int regnum = ia64_uw2gdb_regnum (uw_regnum);
|
||||
unw_word_t bsp, sof, sol, cfm, psr, ip;
|
||||
struct regcache *regcache = arg;
|
||||
long new_sof, old_sof;
|
||||
char buf[MAX_REGISTER_SIZE];
|
||||
|
||||
if (write)
|
||||
{
|
||||
if (regnum < 0)
|
||||
/* ignore writes to pseudo-registers such as UNW_IA64_PROC_STARTI. */
|
||||
return 0;
|
||||
|
||||
switch (uw_regnum)
|
||||
{
|
||||
case UNW_REG_IP:
|
||||
ia64_write_pc (*val, inferior_ptid);
|
||||
break;
|
||||
/* We never call any libunwind routines that need to write registers. */
|
||||
gdb_assert (!write);
|
||||
|
||||
case UNW_IA64_AR_BSPSTORE:
|
||||
write_register (IA64_BSP_REGNUM, *val);
|
||||
break;
|
||||
|
||||
case UNW_IA64_AR_BSP:
|
||||
case UNW_IA64_BSP:
|
||||
/* Account for the fact that ptrace() expects bsp to point
|
||||
after the current register frame. */
|
||||
cfm = read_register (IA64_CFM_REGNUM);
|
||||
sof = (cfm & 0x7f);
|
||||
bsp = ia64_rse_skip_regs (*val, sof);
|
||||
write_register (IA64_BSP_REGNUM, bsp);
|
||||
break;
|
||||
|
||||
case UNW_IA64_CFM:
|
||||
/* If we change CFM, we need to adjust ptrace's notion of
|
||||
bsp accordingly, so that the real bsp remains
|
||||
unchanged. */
|
||||
bsp = read_register (IA64_BSP_REGNUM);
|
||||
cfm = read_register (IA64_CFM_REGNUM);
|
||||
old_sof = (cfm & 0x7f);
|
||||
new_sof = (*val & 0x7f);
|
||||
if (old_sof != new_sof)
|
||||
{
|
||||
bsp = ia64_rse_skip_regs (bsp, -old_sof + new_sof);
|
||||
write_register (IA64_BSP_REGNUM, bsp);
|
||||
}
|
||||
write_register (IA64_CFM_REGNUM, *val);
|
||||
break;
|
||||
|
||||
default:
|
||||
write_register (regnum, *val);
|
||||
break;
|
||||
}
|
||||
if (gdbarch_debug >= 1)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
" access_rse_reg: to cache: %4s=0x%s\n",
|
||||
(((unsigned) regnum <= IA64_NAT127_REGNUM)
|
||||
? ia64_register_names[regnum] : "r??"),
|
||||
paddr_nz (*val));
|
||||
}
|
||||
else
|
||||
switch (uw_regnum)
|
||||
{
|
||||
switch (uw_regnum)
|
||||
{
|
||||
case UNW_REG_IP:
|
||||
/* Libunwind expects to see the pc value which means the slot number
|
||||
from the psr must be merged with the ip word address. */
|
||||
ip = read_register (IA64_IP_REGNUM);
|
||||
psr = read_register (IA64_PSR_REGNUM);
|
||||
*val = ip | ((psr >> 41) & 0x3);
|
||||
break;
|
||||
case UNW_REG_IP:
|
||||
/* Libunwind expects to see the pc value which means the slot number
|
||||
from the psr must be merged with the ip word address. */
|
||||
regcache_cooked_read (regcache, IA64_IP_REGNUM, buf);
|
||||
ip = extract_unsigned_integer (buf, 8);
|
||||
regcache_cooked_read (regcache, IA64_PSR_REGNUM, buf);
|
||||
psr = extract_unsigned_integer (buf, 8);
|
||||
*val = ip | ((psr >> 41) & 0x3);
|
||||
break;
|
||||
|
||||
case UNW_IA64_AR_BSP:
|
||||
/* Libunwind expects to see the beginning of the current register
|
||||
frame so we must account for the fact that ptrace() will return a value
|
||||
for bsp that points *after* the current register frame. */
|
||||
bsp = read_register (IA64_BSP_REGNUM);
|
||||
cfm = read_register (IA64_CFM_REGNUM);
|
||||
sof = (cfm & 0x7f);
|
||||
*val = ia64_rse_skip_regs (bsp, -sof);
|
||||
break;
|
||||
case UNW_IA64_AR_BSP:
|
||||
/* Libunwind expects to see the beginning of the current register
|
||||
frame so we must account for the fact that ptrace() will return a value
|
||||
for bsp that points *after* the current register frame. */
|
||||
regcache_cooked_read (regcache, IA64_BSP_REGNUM, buf);
|
||||
bsp = extract_unsigned_integer (buf, 8);
|
||||
regcache_cooked_read (regcache, IA64_CFM_REGNUM, buf);
|
||||
cfm = extract_unsigned_integer (buf, 8);
|
||||
sof = (cfm & 0x7f);
|
||||
*val = ia64_rse_skip_regs (bsp, -sof);
|
||||
break;
|
||||
|
||||
case UNW_IA64_AR_BSPSTORE:
|
||||
/* Libunwind wants bspstore to be after the current register frame.
|
||||
This is what ptrace() and gdb treats as the regular bsp value. */
|
||||
*val = read_register (IA64_BSP_REGNUM);
|
||||
break;
|
||||
case UNW_IA64_AR_BSPSTORE:
|
||||
/* Libunwind wants bspstore to be after the current register frame.
|
||||
This is what ptrace() and gdb treats as the regular bsp value. */
|
||||
regcache_cooked_read (regcache, IA64_BSP_REGNUM, buf);
|
||||
*val = extract_unsigned_integer (buf, 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* For all other registers, just read the value directly. */
|
||||
*val = read_register (regnum);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* For all other registers, just unwind the value directly. */
|
||||
regcache_cooked_read (regcache, regnum, buf);
|
||||
*val = extract_unsigned_integer (buf, 8);
|
||||
break;
|
||||
}
|
||||
|
||||
if (gdbarch_debug >= 1)
|
||||
@ -2442,6 +2346,22 @@ ia64_access_rse_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *va
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Libunwind callback accessor function for top-level fp registers. */
|
||||
static int
|
||||
ia64_access_rse_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum,
|
||||
unw_fpreg_t *val, int write, void *arg)
|
||||
{
|
||||
int regnum = ia64_uw2gdb_regnum (uw_regnum);
|
||||
struct regcache *regcache = arg;
|
||||
|
||||
/* We never call any libunwind routines that need to write registers. */
|
||||
gdb_assert (!write);
|
||||
|
||||
regcache_cooked_read (regcache, regnum, (char *) val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Libunwind callback accessor function for accessing memory. */
|
||||
static int
|
||||
ia64_access_mem (unw_addr_space_t as,
|
||||
@ -2976,7 +2896,7 @@ static unw_accessors_t ia64_unw_rse_accessors =
|
||||
ia64_get_dyn_info_list,
|
||||
ia64_access_mem,
|
||||
ia64_access_rse_reg,
|
||||
ia64_access_fpreg,
|
||||
ia64_access_rse_fpreg,
|
||||
/* resume */
|
||||
/* get_proc_name */
|
||||
};
|
||||
|
@ -395,7 +395,8 @@ libunwind_sigtramp_frame_sniffer (struct frame_info *next_frame)
|
||||
are usually located at BOF, this is not always true and only the libunwind
|
||||
info can decipher where they actually are. */
|
||||
int
|
||||
libunwind_get_reg_special (struct gdbarch *gdbarch, int regnum, void *buf)
|
||||
libunwind_get_reg_special (struct gdbarch *gdbarch, struct regcache *regcache,
|
||||
int regnum, void *buf)
|
||||
{
|
||||
unw_cursor_t cursor;
|
||||
unw_accessors_t *acc;
|
||||
@ -415,7 +416,7 @@ libunwind_get_reg_special (struct gdbarch *gdbarch, int regnum, void *buf)
|
||||
? __BIG_ENDIAN
|
||||
: __LITTLE_ENDIAN);
|
||||
|
||||
ret = unw_init_remote_p (&cursor, as, NULL);
|
||||
ret = unw_init_remote_p (&cursor, as, regcache);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
struct frame_info;
|
||||
struct frame_id;
|
||||
struct regcache;
|
||||
struct gdbarch;
|
||||
|
||||
#ifndef LIBUNWIND_FRAME_H
|
||||
@ -62,7 +63,9 @@ int libunwind_search_unwind_table (void *as, long ip, void *di,
|
||||
unw_word_t libunwind_find_dyn_list (unw_addr_space_t, unw_dyn_info_t *,
|
||||
void *);
|
||||
|
||||
int libunwind_get_reg_special (struct gdbarch *gdbarch, int regnum, void *buf);
|
||||
int libunwind_get_reg_special (struct gdbarch *gdbarch,
|
||||
struct regcache *regcache,
|
||||
int regnum, void *buf);
|
||||
|
||||
#endif /* libunwind-frame.h */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user