This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RFA: [revised] Core file support for x86 SSE registers



[I left out some doc fixes to gdbcore.h.]

I'm not sure who the maintainer for this is.  

This change factors out some repeated code into a function, cleans it
up a bit, and then adds a new use of that function.  It allows GDB to
understand '.reg-xfp' notes in Linux core files.  I've submitted
corresponding patches to BFD and the Linux kernel itself, but this
change should be harmless until those patches are applied.


1999-11-04  Jim Blandy  <jimb@zenia.red-bean.com>

	* corelow.c (get_core_register_section): New function.
	(get_core_registers): Fetch the new ".reg-xfp" sections,
	in addition to the traditional ".reg" and ".reg2" sections.
	Check for per-thread variants of all three.  Use
	get_core_register_section, instead of writing it out over and over
	again.
	* gdbcore.h: (struct core_fns): Doc fix.

Index: gdb/corelow.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/corelow.c,v
retrieving revision 2.47
retrieving revision 2.47.10.1
diff -c -r2.47 -r2.47.10.1
*** gdb/corelow.c	1999/09/29 20:14:50	2.47
--- gdb/corelow.c	1999/11/04 07:11:03	2.47.10.1
***************
*** 373,378 ****
--- 373,440 ----
      printf_filtered ("No core file now.\n");
  }
  
+ 
+ /* Try to retrieve registers from a section in core_bfd, and supply
+    them to core_vec->core_read_registers, as the register set numbered
+    WHICH.
+ 
+    If inferior_pid is zero, do the single-threaded thing: look for a
+    section named NAME.  If inferior_pid is non-zero, do the
+    multi-threaded thing: look for a section named "NAME/PID", where
+    PID is the shortest ASCII decimal representation of inferior_pid.
+ 
+    HUMAN_NAME is a human-readable name for the kind of registers the
+    NAME section contains, for use in error messages.
+ 
+    If REQUIRED is non-zero, print an error if the core file doesn't
+    have a section by the appropriate name.  Otherwise, just do nothing.  */
+ 
+ static void
+ get_core_register_section (char *name,
+ 			   int which,
+ 			   char *human_name,
+ 			   int required)
+ {
+   char section_name[100];
+   sec_ptr section;
+   bfd_size_type size;
+   char *contents;
+ 
+   if (inferior_pid)
+     sprintf (section_name, "%s/%d", name, inferior_pid);
+   else
+     strcpy (section_name, name);
+ 
+   section = bfd_get_section_by_name (core_bfd, section_name);
+   if (! section)
+     {
+       if (required)
+ 	fprintf_filtered (gdb_stderr,
+ 			  "Couldn't find %s registers in core file.\n",
+ 			  human_name);
+       return;
+     }
+ 
+   size = bfd_section_size (core_bfd, section);
+   contents = alloca (size);
+   if (! bfd_get_section_contents (core_bfd, section, contents,
+ 				  (file_ptr) 0, size))
+     {
+       fprintf_filtered (gdb_stderr,
+ 			"Couldn't read %s registers from %s section in "
+ 			"core file.\n",
+ 			human_name, name);
+       return;
+     }
+ 
+   core_vec->core_read_registers (contents, size, which, 
+ 				 ((CORE_ADDR)
+ 				  bfd_section_vma (core_bfd, section)));
+ 
+   return 0;
+ }
+ 
+ 
  /* Get the registers out of a core file.  This is the machine-
     independent part.  Fetch_core_registers is the machine-dependent
     part, typically implemented in the xm-file for each architecture.  */
***************
*** 384,450 ****
  get_core_registers (regno)
       int regno;
  {
!   sec_ptr reg_sec;
!   unsigned size;
!   char *the_regs;
!   char secname[30];
  
!   if (core_vec == NULL)
      {
        fprintf_filtered (gdb_stderr,
  		     "Can't fetch registers from this type of core file\n");
        return;
      }
- 
-   /* Thread support.  If inferior_pid is non-zero, then we have found a core
-      file with threads (or multiple processes).  In that case, we need to
-      use the appropriate register section, else we just use `.reg'. */
  
!   /* XXX - same thing needs to be done for floating-point (.reg2) sections. */
  
-   if (inferior_pid)
-     sprintf (secname, ".reg/%d", inferior_pid);
-   else
-     strcpy (secname, ".reg");
- 
-   reg_sec = bfd_get_section_by_name (core_bfd, secname);
-   if (!reg_sec)
-     goto cant;
-   size = bfd_section_size (core_bfd, reg_sec);
-   the_regs = alloca (size);
-   if (bfd_get_section_contents (core_bfd, reg_sec, the_regs, (file_ptr) 0, size) &&
-       core_vec->core_read_registers != NULL)
-     {
-       (core_vec->core_read_registers (the_regs, size, 0,
- 				(unsigned) bfd_section_vma (abfd, reg_sec)));
-     }
-   else
-     {
-     cant:
-       fprintf_filtered (gdb_stderr,
- 			"Couldn't fetch registers from core file: %s\n",
- 			bfd_errmsg (bfd_get_error ()));
-     }
- 
-   /* Now do it again for the float registers, if they exist.  */
-   reg_sec = bfd_get_section_by_name (core_bfd, ".reg2");
-   if (reg_sec)
-     {
-       size = bfd_section_size (core_bfd, reg_sec);
-       the_regs = alloca (size);
-       if (bfd_get_section_contents (core_bfd, reg_sec, the_regs, (file_ptr) 0, size) &&
- 	  core_vec->core_read_registers != NULL)
- 	{
- 	  (core_vec->core_read_registers (the_regs, size, 2,
- 			       (unsigned) bfd_section_vma (abfd, reg_sec)));
- 	}
-       else
- 	{
- 	  fprintf_filtered (gdb_stderr,
- 		       "Couldn't fetch register set 2 from core file: %s\n",
- 			    bfd_errmsg (bfd_get_error ()));
- 	}
-     }
    registers_fetched ();
  }
  
--- 446,465 ----
  get_core_registers (regno)
       int regno;
  {
!   int status;
  
!   if (core_vec == NULL
!       || core_vec->core_read_registers == NULL)
      {
        fprintf_filtered (gdb_stderr,
  		     "Can't fetch registers from this type of core file\n");
        return;
      }
  
!   get_core_register_section (".reg", 0, "general-purpose", 1);
!   get_core_register_section (".reg2", 2, "floating-point", 0);
!   get_core_register_section (".reg-xfp", 3, "extended floating-point", 0);
  
    registers_fetched ();
  }
  
Index: gdb/gdbcore.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/gdbcore.h,v
retrieving revision 1.22.10.1
retrieving revision 1.22.10.2
diff -c -r1.22.10.1 -r1.22.10.2
*** gdb/gdbcore.h	1999/10/29 22:42:44	1.22.10.1
--- gdb/gdbcore.h	1999/11/04 07:11:03	1.22.10.2
***************
*** 163,177 ****
  
         CORE_REG_SIZE is the size of that area.
  
!        WHICH says which set of registers we are handling (0 = int, 2 = float on
!        machines where they are discontiguous).
  
         REG_ADDR is the offset from u.u_ar0 to the register values relative to
         core_reg_sect.  This is used with old-fashioned core files to locate the
         registers in a large upage-plus-stack ".reg" section.  Original upage
         address X is at location core_reg_sect+x+reg_addr. */
  
!     void (*core_read_registers) PARAMS ((char *core_reg_sect, unsigned core_reg_size,
  					 int which, CORE_ADDR reg_addr));
  
      /* Finds the next struct core_fns.  They are allocated and initialized
--- 163,183 ----
  
         CORE_REG_SIZE is the size of that area.
  
!        WHICH says which set of registers we are handling:
!          0 --- integer registers
!          2 --- floating-point registers, on machines where they are
!                discontiguous
!          3 --- extended floating-point registers, on machines where these
!                are present in yet a third area.  (Linux uses this to get at
! 	       the SSE registers.)
  
         REG_ADDR is the offset from u.u_ar0 to the register values relative to
         core_reg_sect.  This is used with old-fashioned core files to locate the
         registers in a large upage-plus-stack ".reg" section.  Original upage
         address X is at location core_reg_sect+x+reg_addr. */
  
!     void (*core_read_registers) PARAMS ((char *core_reg_sect,
! 					 unsigned core_reg_size,
  					 int which, CORE_ADDR reg_addr));
  
      /* Finds the next struct core_fns.  They are allocated and initialized

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]