aboutsummaryrefslogtreecommitdiff
path: root/gdb/corelow.c
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2009-07-31 15:25:22 +0000
committerUlrich Weigand <uweigand@de.ibm.com>2009-07-31 15:25:22 +0000
commitefcbbd1428e455c9ca59a590a91e4db200b3813c (patch)
tree7565c0101e30d632a24d9e59157649e0cb938d59 /gdb/corelow.c
parentf4d9badee6725f50cb4ebc607fad078a7da64584 (diff)
downloadgdb-efcbbd1428e455c9ca59a590a91e4db200b3813c.zip
gdb-efcbbd1428e455c9ca59a590a91e4db200b3813c.tar.gz
gdb-efcbbd1428e455c9ca59a590a91e4db200b3813c.tar.bz2
ChangeLog:
* linux-nat.c: Include <sys/vfs.h>. (SPUFS_MAGIC): Define. (spu_enumerate_spu_ids): New function. (linux_proc_xfer_spu): New function. (linux_xfer_partial): Handle TARGET_OBJECT_SPU. (iterate_over_spus): New function. (struct linux_spu_corefile_data): New data type. (linux_spu_corefile_callback): New function. (linux_spu_make_corefile_notes): New function. (linux_nat_make_corefile_notes): Call it. * corelow.c (struct spuid_list): New data type. (add_to_spuid_list): New function. (core_xfer_partial): Handle TARGET_OBJECT_SPU. gdbserver/ChangeLog: * linux-low.c: Include <sys/stat.h> and <sys/vfs.h>. (SPUFS_MAGIC): Define. (spu_enumerate_spu_ids): New function. (linux_qxfer_spu): New function. (linux_target_ops): Install linux_qxfer_spu.
Diffstat (limited to 'gdb/corelow.c')
-rw-r--r--gdb/corelow.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 4dbcef0..49de82d 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -592,6 +592,36 @@ core_files_info (struct target_ops *t)
print_section_info (core_data, core_bfd);
}
+struct spuid_list
+{
+ gdb_byte *buf;
+ ULONGEST offset;
+ LONGEST len;
+ ULONGEST pos;
+ ULONGEST written;
+};
+
+static void
+add_to_spuid_list (bfd *abfd, asection *asect, void *list_p)
+{
+ struct spuid_list *list = list_p;
+ enum bfd_endian byte_order
+ = bfd_big_endian (abfd)? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
+ int fd, pos = 0;
+
+ sscanf (bfd_section_name (abfd, asect), "SPU/%d/regs%n", &fd, &pos);
+ if (pos == 0)
+ return;
+
+ if (list->pos >= list->offset && list->pos + 4 <= list->offset + list->len)
+ {
+ store_unsigned_integer (list->buf + list->pos - list->offset,
+ 4, byte_order, fd);
+ list->written += 4;
+ }
+ list->pos += 4;
+}
+
static LONGEST
core_xfer_partial (struct target_ops *ops, enum target_object object,
const char *annex, gdb_byte *readbuf,
@@ -682,6 +712,53 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
}
/* FALL THROUGH */
+ case TARGET_OBJECT_SPU:
+ if (readbuf && annex)
+ {
+ /* When the SPU contexts are stored in a core file, BFD
+ represents this with a fake section called "SPU/<annex>". */
+
+ struct bfd_section *section;
+ bfd_size_type size;
+ char *contents;
+
+ char sectionstr[100];
+ xsnprintf (sectionstr, sizeof sectionstr, "SPU/%s", annex);
+
+ section = bfd_get_section_by_name (core_bfd, sectionstr);
+ if (section == NULL)
+ return -1;
+
+ size = bfd_section_size (core_bfd, section);
+ if (offset >= size)
+ return 0;
+ size -= offset;
+ if (size > len)
+ size = len;
+ if (size > 0
+ && !bfd_get_section_contents (core_bfd, section, readbuf,
+ (file_ptr) offset, size))
+ {
+ warning (_("Couldn't read SPU section in core file."));
+ return -1;
+ }
+
+ return size;
+ }
+ else if (readbuf)
+ {
+ /* NULL annex requests list of all present spuids. */
+ struct spuid_list list;
+ list.buf = readbuf;
+ list.offset = offset;
+ list.len = len;
+ list.pos = 0;
+ list.written = 0;
+ bfd_map_over_sections (core_bfd, add_to_spuid_list, &list);
+ return list.written;
+ }
+ return -1;
+
default:
if (ops->beneath != NULL)
return ops->beneath->to_xfer_partial (ops->beneath, object, annex,