Add elfcore_grok_freebsd_note to parse FreeBSD ELF core notes.
authorJohn Baldwin <jhb@FreeBSD.org>
Sun, 12 Jun 2016 15:56:31 +0000 (08:56 -0700)
committerJohn Baldwin <jhb@FreeBSD.org>
Fri, 24 Jun 2016 17:32:15 +0000 (10:32 -0700)
Move parsing of FreeBSD-specific ELF core notes out of elfcore_grok_note
into a new elfcore_grok_freebsd_note function.  Add core note grok routines
for FreeBSD's psinfo and prstatus notes while here rather than depending
on the native handling in elfcore_grok_note.

bfd/ChangeLog:

* elf.c (elfcore_grok_note): Remove handling of NT_X86_XSTATE for
FreeBSD.  Remove case for NT_FREEBSD_THRMISC.
(elfcore_grok_freebsd_psinfo): New function.
(elfcore_grok_freebsd_prstatus): New function.
(elfcore_grok_freebsd_note): New function.
(elf_parse_notes): Use "elfcore_grok_freebsd_note" for "FreeBSD"
notes.

bfd/ChangeLog
bfd/elf.c

index a1d8ea9644cedacd44db342ab2d4587fad6b20df..4822e30124697fa6087ac3e6c1ad1b5f0ad4d81a 100644 (file)
@@ -1,3 +1,13 @@
+2016-06-24  John Baldwin  <jhb@FreeBSD.org>
+
+       * elf.c (elfcore_grok_note): Remove handling of NT_X86_XSTATE for
+       FreeBSD.  Remove case for NT_FREEBSD_THRMISC.
+       (elfcore_grok_freebsd_psinfo): New function.
+       (elfcore_grok_freebsd_prstatus): New function.
+       (elfcore_grok_freebsd_note): New function.
+       (elf_parse_notes): Use "elfcore_grok_freebsd_note" for "FreeBSD"
+       notes.
+
 2016-06-24  Joel Brobecker  <brobecker@adacore.com>
 
        * elflink.c: Check the value of BFD_SUPPORTS_PLUGINS rather
index aaf2b5351d326f5b2312aaf698b959bd253d1136..cfcafaad90e6fb6fa78c2ae55d1f690486b7e2fe 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -9327,9 +9327,6 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
       if (note->namesz == 6
          && strcmp (note->namedata, "LINUX") == 0)
        return elfcore_grok_xstatereg (abfd, note);
-      else if (note->namesz == 8
-         && strcmp (note->namedata, "FreeBSD") == 0)
-       return elfcore_grok_xstatereg (abfd, note);
       else
        return TRUE;
 
@@ -9485,12 +9482,6 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
       return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo",
                                              note);
 
-    case NT_FREEBSD_THRMISC:
-      if (note->namesz == 8
-         && strcmp (note->namedata, "FreeBSD") == 0)
-       return elfcore_make_note_pseudosection (abfd, ".thrmisc", note);
-      else
-       return TRUE;
     }
 }
 
@@ -9555,6 +9546,134 @@ elfobj_grok_stapsdt_note (bfd *abfd, Elf_Internal_Note *note)
     }
 }
 
+static bfd_boolean
+elfcore_grok_freebsd_psinfo (bfd *abfd, Elf_Internal_Note *note)
+{
+  size_t offset;
+
+  /* Check for version 1 in pr_version. */
+  if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1)
+    return FALSE;
+  offset = 4;
+
+  /* Skip over pr_psinfosz. */
+  switch (abfd->arch_info->bits_per_word)
+    {
+    case 32:
+      offset += 4;
+      break;
+
+    case 64:
+      offset += 4;     /* Padding before pr_psinfosz. */
+      offset += 8;
+      break;
+
+    default:
+      return FALSE;
+    }
+
+  /* pr_fname is PRFNAMESZ (16) + 1 bytes in size.  */
+  elf_tdata (abfd)->core->program
+    = _bfd_elfcore_strndup (abfd, note->descdata + offset, 17);
+  offset += 17;
+
+  /* pr_psargs is PRARGSZ (80) + 1 bytes in size.  */
+  elf_tdata (abfd)->core->command
+    = _bfd_elfcore_strndup (abfd, note->descdata + offset, 81);
+
+  return TRUE;
+}
+
+static bfd_boolean
+elfcore_grok_freebsd_prstatus (bfd *abfd, Elf_Internal_Note *note)
+{
+  size_t offset;
+  size_t size;
+
+  /* Check for version 1 in pr_version. */
+  if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1)
+    return FALSE;
+  offset = 4;
+
+  /* Skip over pr_statussz.  */
+  switch (abfd->arch_info->bits_per_word)
+    {
+    case 32:
+      offset += 4;
+      break;
+
+    case 64:
+      offset += 4;     /* Padding before pr_statussz. */
+      offset += 8;
+      break;
+
+    default:
+      return FALSE;
+    }
+
+  /* Extract size of pr_reg from pr_gregsetsz.  */
+  if (abfd->arch_info->bits_per_word == 32)
+    size = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
+  else
+    size = bfd_h_get_64 (abfd, (bfd_byte *) note->descdata + offset);
+
+  /* Skip over pr_gregsetsz and pr_fpregsetsz. */
+  offset += (abfd->arch_info->bits_per_word / 8) * 2;
+
+  /* Skip over pr_osreldate. */
+  offset += 4;
+
+  /* Read signal from pr_cursig. */
+  if (elf_tdata (abfd)->core->signal == 0)
+    elf_tdata (abfd)->core->signal
+      = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
+  offset += 4;
+
+  /* Read TID from pr_pid. */
+  elf_tdata (abfd)->core->lwpid
+      = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
+  offset += 4;
+
+  /* Padding before pr_reg. */
+  if (abfd->arch_info->bits_per_word == 64)
+    offset += 4;
+
+  /* Make a ".reg/999" section and a ".reg" section.  */
+  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+                                         size, note->descpos + offset);
+}
+
+static bfd_boolean
+elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note)
+{
+  switch (note->type)
+    {
+    case NT_PRSTATUS:
+      return elfcore_grok_freebsd_prstatus (abfd, note);
+
+    case NT_FPREGSET:
+      return elfcore_grok_prfpreg (abfd, note);
+
+    case NT_PRPSINFO:
+      return elfcore_grok_freebsd_psinfo (abfd, note);
+
+    case NT_FREEBSD_THRMISC:
+      if (note->namesz == 8)
+       return elfcore_make_note_pseudosection (abfd, ".thrmisc", note);
+      else
+       return TRUE;
+
+    case NT_X86_XSTATE:
+      if (note->namesz == 8)
+       return elfcore_grok_xstatereg (abfd, note);
+      else
+       return TRUE;
+
+    default:
+      return TRUE;
+    }
+}
+
 static bfd_boolean
 elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp)
 {
@@ -10467,6 +10586,7 @@ elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
            grokers[] =
            {
              GROKER_ELEMENT ("", elfcore_grok_note),
+             GROKER_ELEMENT ("FreeBSD", elfcore_grok_freebsd_note),
              GROKER_ELEMENT ("NetBSD-CORE", elfcore_grok_netbsd_note),
              GROKER_ELEMENT ( "OpenBSD", elfcore_grok_openbsd_note),
              GROKER_ELEMENT ("QNX", elfcore_grok_nto_note),