aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2007-05-12 00:07:45 +0000
committerUlrich Weigand <uweigand@de.ibm.com>2007-05-12 00:07:45 +0000
commit45ecac4b41626c5f43dd90d0174f56c3d1350cc9 (patch)
tree6ffe6ac6417d3ed0b8a7ea03f569ab933c0d08f8
parent26f43351a71c25e48de61bb586fe4d492603e609 (diff)
downloadgdb-45ecac4b41626c5f43dd90d0174f56c3d1350cc9.zip
gdb-45ecac4b41626c5f43dd90d0174f56c3d1350cc9.tar.gz
gdb-45ecac4b41626c5f43dd90d0174f56c3d1350cc9.tar.bz2
* 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.
-rw-r--r--gdb/ChangeLog17
-rw-r--r--gdb/ia64-tdep.c292
-rw-r--r--gdb/libunwind-frame.c5
-rw-r--r--gdb/libunwind-frame.h5
4 files changed, 130 insertions, 189 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d161566..ba1b51d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,22 @@
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.
2007-05-11 Ulrich Weigand <uweigand@de.ibm.com>
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index a8af64b..526926c 100644
--- a/gdb/ia64-tdep.c
+++ b/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);
+
+ 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:
- 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));
- }
- 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;
+ 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));
+ 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));
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;
-
- 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)
- {
- 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;
+ /* We never call any libunwind routines that need to write registers. */
+ gdb_assert (!write);
+
+ 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. */
+ 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 */
};
diff --git a/gdb/libunwind-frame.c b/gdb/libunwind-frame.c
index 66ffb8e..0b92853 100644
--- a/gdb/libunwind-frame.c
+++ b/gdb/libunwind-frame.c
@@ -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;
diff --git a/gdb/libunwind-frame.h b/gdb/libunwind-frame.h
index f32e4c4..499055a 100644
--- a/gdb/libunwind-frame.h
+++ b/gdb/libunwind-frame.h
@@ -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 */