[PATCH] Add ELF core dump notes sections for extra s390 registers

Martin Schwidefsky schwidefsky@de.ibm.com
Mon Feb 8 17:33:00 GMT 2010


Greetings,

A s390 ELF core dump currently only contains the PSW, the general purpose
registers, the floating point registers and the access registers stored
in PRSTATUS/PRFPREG note sections.
For analyzing s390 kernel problems additional registers are important.
In order to be able to include these registers to a kernel ELF core dump,
this patch adds the following five new note sections:

* NT_S390_TIMER:   S390 timer
* NT_S390_TODCMP:  S390 TOD comparator register
* NT_S390_TODPREG: S390 TOD programmable register
* NT_S390_CTRS:    S390 control registers
* NT_S390_PREFIX:  S390 prefix register

With this patch the output of readelf -n on a s390 ELF kernel dump with
two CPUs will show the following:

$ readelf -n /mnt/dump.elf 
Notes at offset 0x00000120 with length 0x00000694:
  Owner		Data size	Description
  CORE		0x00000088	NT_PRPSINFO (prpsinfo structure)
  CORE		0x00000150	NT_PRSTATUS (prstatus structure)
  CORE		0x00000088	NT_FPREGSET (floating point registers)
  LINUX		0x00000008	NT_S390_TIMER (s390 timer register)
  LINUX		0x00000008	NT_S390_TODCMP (s390 TOD comparator register)
  LINUX		0x00000004	NT_S390_TODPREG (s390 TOD programmable register)
  LINUX		0x00000080	NT_S390_CTRS (s390 control registers)
  LINUX		0x00000004	NT_S390_PREFIX (s390 prefix register)
  CORE		0x00000150	NT_PRSTATUS (prstatus structure)
  CORE		0x00000088	NT_FPREGSET (floating point registers)
  LINUX		0x00000008	NT_S390_TIMER (s390 timer register)
  LINUX		0x00000008	NT_S390_TODCMP (s390 TOD comparator register)
  LINUX		0x00000004	NT_S390_TODPREG (s390 TOD programmable register)
  LINUX		0x00000080	NT_S390_CTRS (s390 control registers)
  LINUX		0x00000004	NT_S390_PREFIX (s390 prefix register)


Any objections?

blue skies,
  Martin.
---

2010-02-08  Michael Holzheu  <holzheu@de.ibm.com>

	* elf-bfd.h (elfcore_write_s390_timer, elfcore_write_s390_todcmp,
	elfcore_write_s390_todpreg, elfcore_write_s390_ctrs,
	elfcore_write_s390_prefix): New.
	* elf.c (elfcore_write_s390_timer, elfcore_write_s390_todcmp,
	elfcore_write_s390_todpreg, elfcore_write_s390_ctrs,
	elfcore_write_s390_prefix): New.
	(elfcore_grok_note): Handle NT_S390_TIMER, NT_S390_TODCMP,
	NT_S390_TODPREG, NT_S390_CTRS and NT_S390_PREFIX.
	(elfcore_write_register_note): Handle .reg-s390-timer, 
	.reg-s390-todcmp, .reg-s390-todpreg, .reg-s390-ctrs,
	.reg-s390-prefix section.

2010-02-08  Michael Holzheu  <holzheu@de.ibm.com>

	* readelf.c (get_note_type): Handle NT_S390_TIMER, NT_S390_TODCMP,
	NT_S390_TODPREG, NT_S390_CTRS and NT_S390_PREFIX.

2010-02-08  Michael Holzheu  <holzheu@de.ibm.com>

	* common.h (NT_S390_TIMER, NT_S390_TODCMP, NT_S390_TODPREG,
	NT_S390_CTRS and NT_S390_PREFIX): Define.

diff -urpN src/bfd/elf-bfd.h src-s390/bfd/elf-bfd.h
--- src/bfd/elf-bfd.h	2010-02-08 15:36:12.000000000 +0100
+++ src-s390/bfd/elf-bfd.h	2010-02-08 15:42:15.000000000 +0100
@@ -2175,6 +2175,16 @@ extern char *elfcore_write_ppc_vmx
   (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_ppc_vsx
   (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_timer
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_todcmp
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_todpreg
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_ctrs
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_prefix
+  (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_lwpstatus
   (bfd *, char *, int *, long, int, const void *);
 extern char *elfcore_write_register_note
diff -urpN src/bfd/elf.c src-s390/bfd/elf.c
--- src/bfd/elf.c	2010-02-08 15:36:12.000000000 +0100
+++ src-s390/bfd/elf.c	2010-02-08 15:43:13.000000000 +0100
@@ -7672,6 +7672,36 @@ elfcore_grok_s390_high_gprs (bfd *abfd, 
   return elfcore_make_note_pseudosection (abfd, ".reg-s390-high-gprs", note);
 }
 
+static bfd_boolean
+elfcore_grok_s390_timer (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-s390-timer", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_todcmp (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-s390-todcmp", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_todpreg (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-s390-todpreg", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_ctrs (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-s390-ctrs", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_prefix (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-s390-prefix", note);
+}
+
 #if defined (HAVE_PRPSINFO_T)
 typedef prpsinfo_t   elfcore_psinfo_t;
 #if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
@@ -8050,6 +8080,41 @@ elfcore_grok_note (bfd *abfd, Elf_Intern
       else
         return TRUE;
 
+    case NT_S390_TIMER:
+      if (note->namesz == 6
+          && strcmp (note->namedata, "LINUX") == 0)
+        return elfcore_grok_s390_timer (abfd, note);
+      else
+        return TRUE;
+
+    case NT_S390_TODCMP:
+      if (note->namesz == 6
+          && strcmp (note->namedata, "LINUX") == 0)
+        return elfcore_grok_s390_todcmp (abfd, note);
+      else
+        return TRUE;
+
+    case NT_S390_TODPREG:
+      if (note->namesz == 6
+          && strcmp (note->namedata, "LINUX") == 0)
+        return elfcore_grok_s390_todpreg (abfd, note);
+      else
+        return TRUE;
+
+    case NT_S390_CTRS:
+      if (note->namesz == 6
+          && strcmp (note->namedata, "LINUX") == 0)
+        return elfcore_grok_s390_ctrs (abfd, note);
+      else
+        return TRUE;
+
+    case NT_S390_PREFIX:
+      if (note->namesz == 6
+          && strcmp (note->namedata, "LINUX") == 0)
+        return elfcore_grok_s390_prefix (abfd, note);
+      else
+        return TRUE;
+
     case NT_PRPSINFO:
     case NT_PSINFO:
       if (bed->elf_backend_grok_psinfo)
@@ -8715,6 +8780,66 @@ elfcore_write_s390_high_gprs (bfd *abfd,
 }
 
 char *
+elfcore_write_s390_timer (bfd *abfd,
+                          char *buf,
+                          int *bufsiz,
+                          const void *s390_timer,
+                          int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                             note_name, NT_S390_TIMER, s390_timer, size);
+}
+
+char *
+elfcore_write_s390_todcmp (bfd *abfd,
+                           char *buf,
+                           int *bufsiz,
+                           const void *s390_todcmp,
+                           int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                             note_name, NT_S390_TODCMP, s390_todcmp, size);
+}
+
+char *
+elfcore_write_s390_todpreg (bfd *abfd,
+                            char *buf,
+                            int *bufsiz,
+                            const void *s390_todpreg,
+                            int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                             note_name, NT_S390_TODPREG, s390_todpreg, size);
+}
+
+char *
+elfcore_write_s390_ctrs (bfd *abfd,
+                         char *buf,
+                         int *bufsiz,
+                         const void *s390_ctrs,
+                         int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                             note_name, NT_S390_CTRS, s390_ctrs, size);
+}
+
+char *
+elfcore_write_s390_prefix (bfd *abfd,
+                           char *buf,
+                           int *bufsiz,
+                           const void *s390_prefix,
+                           int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                             note_name, NT_S390_PREFIX, s390_prefix, size);
+}
+
+char *
 elfcore_write_register_note (bfd *abfd,
 			     char *buf,
 			     int *bufsiz,
@@ -8734,6 +8859,16 @@ elfcore_write_register_note (bfd *abfd,
     return elfcore_write_ppc_vsx (abfd, buf, bufsiz, data, size);
   if (strcmp (section, ".reg-s390-high-gprs") == 0)
     return elfcore_write_s390_high_gprs (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-s390-timer") == 0)
+    return elfcore_write_s390_timer (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-s390-todcmp") == 0)
+    return elfcore_write_s390_todcmp (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-s390-todpreg") == 0)
+    return elfcore_write_s390_todpreg (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-s390-ctrs") == 0)
+    return elfcore_write_s390_ctrs (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-s390-prefix") == 0)
+    return elfcore_write_s390_prefix (abfd, buf, bufsiz, data, size);
   return NULL;
 }
 
diff -urpN src/binutils/readelf.c src-s390/binutils/readelf.c
--- src/binutils/readelf.c	2010-02-08 15:36:13.000000000 +0100
+++ src-s390/binutils/readelf.c	2010-02-08 15:43:48.000000000 +0100
@@ -10419,6 +10419,16 @@ get_note_type (unsigned e_type)
 	return _("NT_X86_XSTATE (x86 XSAVE extended state)");
       case NT_S390_HIGH_GPRS:
 	return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
+      case NT_S390_TIMER:
+	return _("NT_S390_TIMER (s390 timer register)");
+      case NT_S390_TODCMP:
+	return _("NT_S390_TODCMP (s390 TOD comparator register)");
+      case NT_S390_TODPREG:
+	return _("NT_S390_TODPREG (s390 TOD programmable register)");
+      case NT_S390_CTRS:
+	return _("NT_S390_CTRS (s390 control registers)");
+      case NT_S390_PREFIX:
+	return _("NT_S390_PREFIX (s390 prefix register)");
       case NT_PSTATUS:
 	return _("NT_PSTATUS (pstatus structure)");
       case NT_FPREGS:
diff -urpN src/include/elf/common.h src-s390/include/elf/common.h
--- src/include/elf/common.h	2010-02-08 15:36:19.000000000 +0100
+++ src-s390/include/elf/common.h	2010-02-08 15:42:15.000000000 +0100
@@ -517,6 +517,16 @@
 					/*   note name must be "LINUX".  */
 #define NT_S390_HIGH_GPRS 0x300		/* S/390 upper halves of GPRs  */
 					/*   note name must be "LINUX".  */
+#define NT_S390_TIMER	0x301		/* S390 timer */
+					/*   note name must be "LINUX".  */
+#define NT_S390_TODCMP	0x302		/* S390 TOD clock comparator */
+					/*   note name must be "LINUX".  */
+#define NT_S390_TODPREG	0x303		/* S390 TOD programmable register */
+					/*   note name must be "LINUX".  */
+#define NT_S390_CTRS	0x304		/* S390 control registers */
+					/*   note name must be "LINUX".  */
+#define NT_S390_PREFIX	0x305		/* S390 prefix register */
+					/*   note name must be "LINUX".  */
 
 /* Note segments for core files on dir-style procfs systems.  */
 



More information about the Binutils mailing list