This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[rfc] Wrap addresses in spu-gdb
- From: Markus Deuling <deuling at de dot ibm dot com>
- To: GDB Patches <gdb-patches at sourceware dot org>, Ulrich Weigand <uweigand at de dot ibm dot com>
- Date: Wed, 08 Aug 2007 08:44:29 +0200
- Subject: [rfc] Wrap addresses in spu-gdb
Hi,
this patch makes GDB aware of a special feature of the SPU hardware. Every SPU has its own dedicated memory, called the Local Store (LS). Currently this is 256K of memory. If accessing memory above this 256K, the address is wrapped to fit in 256K (modulo calculation). So every memory address is valid. The size of the Local Store is found in the SPU's LSLR register.
This examples tries to access an address > LS size and runs into an error which is fixed by this patch:
(gdb) p *0xfffd0162
Error accessing memory address 0xfffd0162: Invalid argument.
The patch introduces three new functions to spu-tdep for address conversion which also will be used by the Cell Broadband Engine combined debugger.
ChangeLog:
* spu-tdep.c (spu_address_to_pointer): New function.
(spu_pointer_to_address): Likewise.
(spu_integer_to_address): Likewise.
(spu_gdbarch_init): Add spu_address_to_pointer, spu_pointer_to_address
and spu_integer_to_address to gdbarch.
Tested on spu-elf. Testsuite showed no regression.
Ok to commit?
--
Markus Deuling
GNU Toolchain for Linux on Cell BE
deuling@de.ibm.com
diff -urpN src/gdb/spu-tdep.c dev/gdb/spu-tdep.c
--- src/gdb/spu-tdep.c 2007-06-18 05:36:44.000000000 +0200
+++ dev/gdb/spu-tdep.c 2007-08-08 08:39:41.000000000 +0200
@@ -324,6 +324,47 @@ spu_register_reggroup_p (struct gdbarch
return default_register_reggroup_p (gdbarch, regnum, group);
}
+/* Address conversion. */
+
+static void
+spu_address_to_pointer (struct type *type, gdb_byte *buf, CORE_ADDR addr)
+{
+ store_unsigned_integer (buf, TYPE_LENGTH (type), addr);
+}
+
+static CORE_ADDR
+spu_pointer_to_address (struct type *type, const gdb_byte *buf)
+{
+ ULONGEST addr = extract_unsigned_integer (buf, TYPE_LENGTH (type));
+ ULONGEST lslr = SPU_LS_SIZE - 1; /* Hard-wired LS size. */
+
+ if (target_has_registers && target_has_stack && target_has_memory)
+ {
+ struct frame_info *frame = get_selected_frame (NULL);
+ lslr = get_frame_register_unsigned (frame, SPU_LSLR_REGNUM);
+ }
+
+ return addr & lslr;
+}
+
+static CORE_ADDR
+spu_integer_to_address (struct gdbarch *gdbarch,
+ struct type *type, const gdb_byte *buf)
+{
+ ULONGEST addr = unpack_long (type, buf);
+ ULONGEST lslr = SPU_LS_SIZE - 1; /* Hard-wired LS size. */
+
+ if (target_has_registers && target_has_stack && target_has_memory
+ /* FIXME: Currently needed for dwarf2_read_address to work. */
+ && type != builtin_type_uint32)
+ {
+ struct frame_info *frame = get_selected_frame (NULL);
+ lslr = get_frame_register_unsigned (frame, SPU_LSLR_REGNUM);
+ }
+
+ return addr & lslr;
+}
+
/* Decoding SPU instructions. */
@@ -2008,6 +2049,11 @@ spu_gdbarch_init (struct gdbarch_info in
set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);
+ /* Address conversion. */
+ set_gdbarch_address_to_pointer (gdbarch, spu_address_to_pointer);
+ set_gdbarch_pointer_to_address (gdbarch, spu_pointer_to_address);
+ set_gdbarch_integer_to_address (gdbarch, spu_integer_to_address);
+
/* Inferior function calls. */
set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
set_gdbarch_frame_align (gdbarch, spu_frame_align);