From 0064d22386b99c047bbff3bcc73b6bfce9c29b4c Mon Sep 17 00:00:00 2001
From: John Baldwin <jhb@FreeBSD.org>
Date: Mon, 4 Jul 2016 19:19:48 -0700
Subject: [PATCH] Handle version 1a of FreeBSD's NT_PRSINFO.

Version 1a adds a pr_pid member containing the process ID of the
terminating process.  The presence of pr_pid is inferred from the
note's size.

bfd/ChangeLog:

	* elf.c (elfcore_grok_freebsd_psinfo): Check for minimum note size
	and handle pr_pid if present.
---
 bfd/ChangeLog |  5 +++++
 bfd/elf.c     | 42 +++++++++++++++++++++++++++++++-----------
 2 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index cbd65d50126..ddf29bf5e58 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2016-07-20  John Baldwin  <jhb@FreeBSD.org>
+
+	* elf.c (elfcore_grok_freebsd_psinfo): Check for minimum note size
+	and handle pr_pid if present.
+
 2016-07-20  Alan Modra  <amodra@gmail.com>
 
 	* elf64-ppc.c (ppc64_elf_howto_raw <R_PPC64_PLTREL32>): Put
diff --git a/bfd/elf.c b/bfd/elf.c
index 2cc64e8d524..ba1774e7b40 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -9590,25 +9590,34 @@ elfcore_grok_freebsd_psinfo (bfd *abfd, Elf_Internal_Note *note)
 {
   size_t offset;
 
-  /* Check for version 1 in pr_version. */
+  switch (abfd->arch_info->bits_per_word)
+    {
+    case 32:
+      if (note->descsz < 108)
+	return FALSE;
+      break;
+
+    case 64:
+      if (note->descsz < 120)
+	return FALSE;
+      break;
+
+    default:
+      return FALSE;
+    }
+
+  /* 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)
+  if (abfd->arch_info->bits_per_word == 32)
+    offset += 4;
+  else
     {
-    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.  */
@@ -9619,6 +9628,17 @@ elfcore_grok_freebsd_psinfo (bfd *abfd, Elf_Internal_Note *note)
   /* pr_psargs is PRARGSZ (80) + 1 bytes in size.  */
   elf_tdata (abfd)->core->command
     = _bfd_elfcore_strndup (abfd, note->descdata + offset, 81);
+  offset += 81;
+
+  /* Padding before pr_pid.  */
+  offset += 2;
+
+  /* The pr_pid field was added in version "1a".  */
+  if (note->descsz < offset + 4)
+    return TRUE;
+
+  elf_tdata (abfd)->core->pid
+    = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
 
   return TRUE;
 }