From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26434 invoked by alias); 8 Feb 2008 21:42:47 -0000 Received: (qmail 26422 invoked by uid 22791); 8 Feb 2008 21:42:44 -0000 X-Spam-Check-By: sourceware.org Received: from igw3.br.ibm.com (HELO igw3.br.ibm.com) (32.104.18.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 08 Feb 2008 21:42:06 +0000 Received: from mailhub1.br.ibm.com (unknown [9.18.232.109]) by igw3.br.ibm.com (Postfix) with ESMTP id 74F703900B5 for ; Fri, 8 Feb 2008 19:32:33 -0200 (BRDT) Received: from d24av01.br.ibm.com (d24av01.br.ibm.com [9.18.232.46]) by mailhub1.br.ibm.com (8.13.8/8.13.8/NCO v8.7) with ESMTP id m18Lg20v4087816 for ; Fri, 8 Feb 2008 19:42:02 -0200 Received: from d24av01.br.ibm.com (loopback [127.0.0.1]) by d24av01.br.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m18Lg2Gq019730 for ; Fri, 8 Feb 2008 19:42:02 -0200 Received: from [9.8.15.127] ([9.8.15.127]) by d24av01.br.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id m18Lg1rW019719; Fri, 8 Feb 2008 19:42:01 -0200 Message-ID: <47ACCCAF.4080200@linux.vnet.ibm.com> Date: Fri, 08 Feb 2008 21:42:00 -0000 From: Carlos Eduardo Seo User-Agent: Thunderbird 2.0.0.9 (X11/20071116) MIME-Version: 1.0 To: Ulrich Weigand CC: GDB Patches Mailing List Subject: Re: [RFC] Add support for PPC Altivec registers in gcore References: <200710312135.l9VLZiSf011567@d12av02.megacenter.de.ibm.com> In-Reply-To: <200710312135.l9VLZiSf011567@d12av02.megacenter.de.ibm.com> OpenPGP: id=8BFFA900 Content-Type: multipart/mixed; boundary="------------030501020603030805010504" X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-02/txt/msg00157.txt.bz2 This is a multi-part message in MIME format. --------------030501020603030805010504 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 898 Ulrich Weigand wrote: > Yes, exactly. You'll have to update the list in gdbarch.sh, > and run the script to regenerate gdbarch.c and gdbarch.h. > Ok, here's my first shot at this new approach for writing core files. I had to add a new BFD function (binutils patch is attached as well - I'll submit this to the binutils mailing list later) and I didn't include the fill_register fallbacks in the new implementation. I believe a similar loop could also be used in -tdep.c files to read the core files as well, right? Only wrote the code for ppc, but this could be easily expanded to other archs, adding modifications similar to those I did in ppc-linux-tdep.c. I think this first code is very raw, but I believe we can improve it and use this approach for all archs in the future. Opinions / suggestions? Regards, -- Carlos Eduardo Seo Software Engineer IBM Linux Technology Center --------------030501020603030805010504 Content-Type: text/x-patch; name="gdbarch-core-regset.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="gdbarch-core-regset.diff" Content-length: 9845 2008-02-08 Carlos Eduardo Seo * gdbarch.c: Refreshed. * gdbarch.h: Refreshed. * gdbarch.sh: Added new gdbarch struct core_regset_sections. * regset.h (core_regset_section): Declare. * ppc-linux-tdep.c: (ppc_regset_sections): Declare. (ppc_linux_init_abi): Initialized new gdbarch struct core_regset_sections. * linux-nat.c (linux_nat_do_thread_registers): Added support to the new gdbarch struct core_regset_sections. Index: src/gdb/gdbarch.c =================================================================== --- src.orig/gdb/gdbarch.c +++ src/gdb/gdbarch.c @@ -222,6 +222,7 @@ struct gdbarch gdbarch_register_reggroup_p_ftype *register_reggroup_p; gdbarch_fetch_pointer_argument_ftype *fetch_pointer_argument; gdbarch_regset_from_core_section_ftype *regset_from_core_section; + struct core_regset_section * core_regset_sections; gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries; int vtable_function_descriptors; int vbit_in_delta; @@ -344,6 +345,7 @@ struct gdbarch startup_gdbarch = default_register_reggroup_p, /* register_reggroup_p */ 0, /* fetch_pointer_argument */ 0, /* regset_from_core_section */ + 0, /* core_regset_sections */ 0, /* core_xfer_shared_libraries */ 0, /* vtable_function_descriptors */ 0, /* vbit_in_delta */ @@ -694,6 +696,9 @@ gdbarch_dump (struct gdbarch *gdbarch, s "gdbarch_dump: core_read_description = <0x%lx>\n", (long) gdbarch->core_read_description); fprintf_unfiltered (file, + "gdbarch_dump: core_regset_sections = %s\n", + (char *) gdbarch->core_regset_sections); + fprintf_unfiltered (file, "gdbarch_dump: gdbarch_core_xfer_shared_libraries_p() = %d\n", gdbarch_core_xfer_shared_libraries_p (gdbarch)); fprintf_unfiltered (file, @@ -2810,6 +2815,22 @@ set_gdbarch_regset_from_core_section (st gdbarch->regset_from_core_section = regset_from_core_section; } +struct core_regset_section * +gdbarch_core_regset_sections (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_core_regset_sections called\n"); + return gdbarch->core_regset_sections; +} + +void +set_gdbarch_core_regset_sections (struct gdbarch *gdbarch, + struct core_regset_section * core_regset_sections) +{ + gdbarch->core_regset_sections = core_regset_sections; +} + int gdbarch_core_xfer_shared_libraries_p (struct gdbarch *gdbarch) { Index: src/gdb/gdbarch.h =================================================================== --- src.orig/gdb/gdbarch.h +++ src/gdb/gdbarch.h @@ -50,6 +50,7 @@ struct target_ops; struct obstack; struct bp_target_info; struct target_desc; +struct core_regset_section; extern struct gdbarch *current_gdbarch; @@ -626,6 +627,11 @@ typedef const struct regset * (gdbarch_r extern const struct regset * gdbarch_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name, size_t sect_size); extern void set_gdbarch_regset_from_core_section (struct gdbarch *gdbarch, gdbarch_regset_from_core_section_ftype *regset_from_core_section); +/* Supported register notes in core files */ + +extern struct core_regset_section * gdbarch_core_regset_sections (struct gdbarch *gdbarch); +extern void set_gdbarch_core_regset_sections (struct gdbarch *gdbarch, struct core_regset_section * core_regset_sections); + /* Read offset OFFSET of TARGET_OBJECT_LIBRARIES formatted shared libraries list from core file into buffer READBUF with length LEN. */ Index: src/gdb/gdbarch.sh =================================================================== --- src.orig/gdb/gdbarch.sh +++ src/gdb/gdbarch.sh @@ -594,6 +594,9 @@ F:CORE_ADDR:fetch_pointer_argument:struc # name SECT_NAME and size SECT_SIZE. M:const struct regset *:regset_from_core_section:const char *sect_name, size_t sect_size:sect_name, sect_size +# Supported register notes in core files +v:struct core_regset_section *:core_regset_sections:const char *name, int len::::::(char *) gdbarch->core_regset_sections + # Read offset OFFSET of TARGET_OBJECT_LIBRARIES formatted shared libraries list from # core file into buffer READBUF with length LEN. M:LONGEST:core_xfer_shared_libraries:gdb_byte *readbuf, ULONGEST offset, LONGEST len:readbuf, offset, len @@ -729,6 +732,7 @@ struct target_ops; struct obstack; struct bp_target_info; struct target_desc; +struct core_regset_section; extern struct gdbarch *current_gdbarch; EOF Index: src/gdb/regset.h =================================================================== --- src.orig/gdb/regset.h +++ src/gdb/regset.h @@ -20,6 +20,12 @@ #ifndef REGSET_H #define REGSET_H 1 +struct core_regset_section +{ + const char *sect_name; + int size; +}; + struct gdbarch; struct regcache; Index: src/gdb/ppc-linux-tdep.c =================================================================== --- src.orig/gdb/ppc-linux-tdep.c +++ src/gdb/ppc-linux-tdep.c @@ -38,6 +38,13 @@ #include "frame-unwind.h" #include "tramp-frame.h" +static struct core_regset_section ppc_regset_sections[] = +{ + {".reg2", 264}, + {".reg-ppc-vmx", 544}, + {NULL, 0} +}; + static CORE_ADDR ppc_linux_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) { @@ -945,6 +952,10 @@ ppc_linux_init_abi (struct gdbarch_info tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sigaction_tramp_frame); tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sighandler_tramp_frame); } + + /* Register sections. */ + set_gdbarch_core_regset_sections (gdbarch, ppc_regset_sections); + set_gdbarch_regset_from_core_section (gdbarch, ppc_linux_regset_from_core_section); /* Enable TLS support. */ Index: src/gdb/linux-nat.c =================================================================== --- src.orig/gdb/linux-nat.c +++ src/gdb/linux-nat.c @@ -2631,6 +2631,9 @@ linux_nat_do_thread_registers (bfd *obfd const struct regset *regset; int core_regset_p; struct cleanup *old_chain; + struct core_regset_section *sect_list; + char *gdb_regset; + int i = 0; old_chain = save_inferior_ptid (); inferior_ptid = ptid; @@ -2638,6 +2641,8 @@ linux_nat_do_thread_registers (bfd *obfd do_cleanups (old_chain); core_regset_p = gdbarch_regset_from_core_section_p (gdbarch); + sect_list = gdbarch_core_regset_sections (gdbarch); + if (core_regset_p && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg", sizeof (gregs))) != NULL @@ -2653,35 +2658,69 @@ linux_nat_do_thread_registers (bfd *obfd lwp, stop_signal, &gregs); - if (core_regset_p - && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2", - sizeof (fpregs))) != NULL - && regset->collect_regset != NULL) - regset->collect_regset (regset, regcache, -1, - &fpregs, sizeof (fpregs)); + /* The loop below uses the new struct core_regset_section, which stores + the supported section names and sizes for the core file. Note that + note PRSTATUS needs to be treated specially. But the other notes are + structurally the same, so they can benefit from the new struct. */ + + if (core_regset_p && sect_list != NULL) + while ((sect_list + i)->sect_name != NULL) + { + if ((regset = gdbarch_regset_from_core_section (gdbarch, + (sect_list + i)->sect_name, + (*(sect_list + i)).size)) + != NULL && regset->collect_regset != NULL) + { + gdb_regset = xmalloc ((*(sect_list + i)).size); + regset->collect_regset (regset, regcache, -1, + gdb_regset, (*(sect_list + i)).size); + note_data = (char *) elfcore_write_register_note (obfd, + note_data, + note_size, + (sect_list + i)->sect_name, + gdb_regset, + (*(sect_list + i)).size); + xfree (gdb_regset); + } + i++; + } + + /* For architectures that does not have the struct core_regset_section implemented, + we use the old method. When all the architectures have the new support, the code + below should be deprecated. */ + else - fill_fpregset (regcache, &fpregs, -1); + { + if (core_regset_p + && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2", + sizeof (fpregs))) != NULL + && regset->collect_regset != NULL) + regset->collect_regset (regset, regcache, -1, + &fpregs, sizeof (fpregs)); + else + fill_fpregset (regcache, &fpregs, -1); - note_data = (char *) elfcore_write_prfpreg (obfd, - note_data, - note_size, - &fpregs, sizeof (fpregs)); + note_data = (char *) elfcore_write_prfpreg (obfd, + note_data, + note_size, + &fpregs, sizeof (fpregs)); #ifdef FILL_FPXREGSET - if (core_regset_p - && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg-xfp", - sizeof (fpxregs))) != NULL - && regset->collect_regset != NULL) - regset->collect_regset (regset, regcache, -1, - &fpxregs, sizeof (fpxregs)); - else - fill_fpxregset (regcache, &fpxregs, -1); + if (core_regset_p + && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg-xfp", + sizeof (fpxregs))) != NULL + && regset->collect_regset != NULL) + regset->collect_regset (regset, regcache, -1, + &fpxregs, sizeof (fpxregs)); + else + fill_fpxregset (regcache, &fpxregs, -1); - note_data = (char *) elfcore_write_prxfpreg (obfd, - note_data, - note_size, - &fpxregs, sizeof (fpxregs)); + note_data = (char *) elfcore_write_prxfpreg (obfd, + note_data, + note_size, + &fpxregs, sizeof (fpxregs)); #endif + } return note_data; } --------------030501020603030805010504 Content-Type: text/x-patch; name="write-register-note.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="write-register-note.patch" Content-length: 1566 2008-02-03 Carlos Eduardo Seo * elf.c (elfcore_write_register_note): New function. * elf-bfd.h (elfcore_write_register_note): New prototype. Index: src/bfd/elf.c =================================================================== --- src.orig/bfd/elf.c +++ src/bfd/elf.c @@ -8438,6 +8438,23 @@ elfcore_write_ppc_vmx (bfd *abfd, note_name, NT_PPC_VMX, ppc_vmx, size); } +char * +elfcore_write_register_note (bfd *abfd, + char *buf, + int *bufsiz, + const char *section, + const void *data, + int size) +{ + if (strcmp (section, ".reg2") == 0) + return elfcore_write_prfpreg (abfd, buf, bufsiz, data, size); + if (strcmp (section, ".reg-xfp") == 0) + return elfcore_write_prxfpreg (abfd, buf, bufsiz, data, size); + if (strcmp (section, ".reg-ppc-vmx") == 0) + return elfcore_write_ppc_vmx (abfd, buf, bufsiz, data, size); + return NULL; +} + static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset) { Index: src/bfd/elf-bfd.h =================================================================== --- src.orig/bfd/elf-bfd.h +++ src/bfd/elf-bfd.h @@ -2109,6 +2109,8 @@ extern char *elfcore_write_ppc_vmx (bfd *, char *, int *, const void *, int); extern char *elfcore_write_lwpstatus (bfd *, char *, int *, long, int, const void *); +extern char *elfcore_write_register_note + (bfd *, char *, int *, const char *, const void *, int); extern bfd *_bfd_elf32_bfd_from_remote_memory (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, --------------030501020603030805010504--