public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 7/8] Create psuedo sections for FreeBSD NT_PTLWPINFO core notes.
  2017-06-29 23:33 [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
                   ` (4 preceding siblings ...)
  2017-06-29 23:33 ` [PATCH 3/8] Move the thread_section_name class to gdbcore.h John Baldwin
@ 2017-06-29 23:33 ` John Baldwin
  2017-06-30  3:20   ` Alan Modra
  2017-06-29 23:41 ` [PATCH 4/8] Add a new gdbarch method to fetch signal information from core files John Baldwin
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 13+ messages in thread
From: John Baldwin @ 2017-06-29 23:33 UTC (permalink / raw)
  To: gdb-patches, binutils

bfd/ChangeLog:

	* elf.c (elfcore_grok_freebsd_note): Handle NT_FREEBSD_PTLWPINFO.
---
 bfd/ChangeLog | 4 ++++
 bfd/elf.c     | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 5177bc749d..7001b8624d 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,7 @@
+2017-06-28  John Baldwin  <jhb@FreeBSD.org>
+
+	* elf.c (elfcore_grok_freebsd_note): Handle NT_FREEBSD_PTLWPINFO.
+
 2017-06-19  Nick Clifton  <nickc@redhat.com>
 
 	PR binutils/21618
diff --git a/bfd/elf.c b/bfd/elf.c
index fb106e9449..cb7bedd66c 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -9946,6 +9946,10 @@ elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note)
       else
 	return TRUE;
 
+    case NT_FREEBSD_PTLWPINFO:
+      return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.lwpinfo",
+					      note);
+
     default:
       return TRUE;
     }
-- 
2.11.0

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 8/8] Read signal information from FreeBSD core dumps.
  2017-06-29 23:33 [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
  2017-06-29 23:33 ` [PATCH 6/8] Recognize the recently-added FreeBSD core dump note for LWP info John Baldwin
  2017-06-29 23:33 ` [PATCH 1/8] Implement the "get_siginfo_type" gdbarch method for FreeBSD architectures John Baldwin
@ 2017-06-29 23:33 ` John Baldwin
  2017-06-29 23:33 ` [PATCH 2/8] Fetch signal information for native FreeBSD processes John Baldwin
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: John Baldwin @ 2017-06-29 23:33 UTC (permalink / raw)
  To: gdb-patches, binutils

FreeBSD recently added a new ELF core note which dumps the entire LWP
info structure (the same structure returned by the ptrace PT_LWPINFO
operation) for each thread.  The plan is for this note to eventually
supplant the older "thrmisc" ELF core note as it contains more
information and it permits new information to be exported via both
ptrace() and core dumps using the same structure.

For signal information, the implementation is similar to the native
implementation for FreeBSD processes.  The PL_FLAG_SI flag must be
checked to determine if the embedded siginfo_t structure is valid, and
if so it is transferred into the caller's buffer.

gdb/ChangeLog:

	* fbsd-tdep.c (LWPINFO_OFFSET, LWPINFO_PL_FLAGS)
	(LWPINFO64_PL_SIGINFO, LWPINFO32_PL_SIGINFO, PL_FLAG_SI)
	(SIZE64_SIGINFO_T, SIZE32_SIGINFO_T, fbsd_core_xfer_siginfo): New.
	(fbsd_init_abi): Install gdbarch "core_xfer_siginfo" method.
---
 gdb/ChangeLog   |  7 ++++++
 gdb/fbsd-tdep.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 840383d06d..d57658a48e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
 2017-06-28  John Baldwin  <jhb@FreeBSD.org>
 
+	* fbsd-tdep.c (LWPINFO_OFFSET, LWPINFO_PL_FLAGS)
+	(LWPINFO64_PL_SIGINFO, LWPINFO32_PL_SIGINFO, PL_FLAG_SI)
+	(SIZE64_SIGINFO_T, SIZE32_SIGINFO_T, fbsd_core_xfer_siginfo): New.
+	(fbsd_init_abi): Install gdbarch "core_xfer_siginfo" method.
+
+2017-06-28  John Baldwin  <jhb@FreeBSD.org>
+
 	* fbsd-tdep.c (fbsd_core_thread_name): Use thread_section_name.
 
 2017-06-28  John Baldwin  <jhb@FreeBSD.org>
diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
index 32df104208..6f30197a83 100644
--- a/gdb/fbsd-tdep.c
+++ b/gdb/fbsd-tdep.c
@@ -30,6 +30,28 @@
 #include "fbsd-tdep.h"
 
 
+/* FreeBSD kernels 12.0 and later include a copy of the
+   'ptrace_lwpinfo' structure returned by the PT_LWPINFO ptrace
+   operation in an ELF core note (NT_FREEBSD_PTLWPINFO) for each LWP.
+   The constants below define the offset of field members and flags in
+   this structure used by methods in this file.  Note that the
+   'ptrace_lwpinfo' struct in the note is preceded by a 4 byte integer
+   containing the size of the structure.  */
+
+#define	LWPINFO_OFFSET		0x4
+
+/* Offsets in ptrace_lwpinfo.  */
+#define	LWPINFO_PL_FLAGS	0x8
+#define	LWPINFO64_PL_SIGINFO	0x30
+#define	LWPINFO32_PL_SIGINFO	0x2c
+
+/* Flags in pl_flags.  */
+#define	PL_FLAG_SI	0x20	/* siginfo is valid */
+
+/* Sizes of siginfo_t.	*/
+#define	SIZE64_SIGINFO_T	80
+#define	SIZE32_SIGINFO_T	64
+
 static struct gdbarch_data *fbsd_gdbarch_data_handle;
 
 struct fbsd_gdbarch_data
@@ -113,6 +135,51 @@ fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr)
   return NULL;
 }
 
+/* Implement the "core_xfer_siginfo" gdbarch method.  */
+
+static LONGEST
+fbsd_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf,
+			ULONGEST offset, ULONGEST len)
+{
+  size_t siginfo_size;
+
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+    siginfo_size = SIZE32_SIGINFO_T;
+  else
+    siginfo_size = SIZE64_SIGINFO_T;
+  if (offset > siginfo_size)
+    return -1;
+
+  thread_section_name section_name (".note.freebsdcore.lwpinfo", inferior_ptid);
+  asection *section = bfd_get_section_by_name (core_bfd, section_name.c_str ());
+  if (section == NULL)
+    return -1;
+
+  gdb_byte buf[4];
+  if (!bfd_get_section_contents (core_bfd, section, buf,
+				 LWPINFO_OFFSET + LWPINFO_PL_FLAGS, 4))
+    return -1;
+
+  int pl_flags = extract_signed_integer (buf, 4, gdbarch_byte_order (gdbarch));
+  if (!(pl_flags & PL_FLAG_SI))
+    return -1;
+
+  if (offset + len > siginfo_size)
+    len = siginfo_size - offset;
+
+  ULONGEST siginfo_offset;
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+    siginfo_offset = LWPINFO_OFFSET + LWPINFO32_PL_SIGINFO;
+  else
+    siginfo_offset = LWPINFO_OFFSET + LWPINFO64_PL_SIGINFO;
+
+  if (!bfd_get_section_contents (core_bfd, section, readbuf,
+				 siginfo_offset + offset, len))
+    return -1;
+
+  return len;
+}
+
 static int
 find_signalled_thread (struct thread_info *info, void *data)
 {
@@ -447,6 +514,7 @@ fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   set_gdbarch_core_pid_to_str (gdbarch, fbsd_core_pid_to_str);
   set_gdbarch_core_thread_name (gdbarch, fbsd_core_thread_name);
+  set_gdbarch_core_xfer_siginfo (gdbarch, fbsd_core_xfer_siginfo);
   set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes);
   set_gdbarch_print_auxv_entry (gdbarch, fbsd_print_auxv_entry);
   set_gdbarch_get_siginfo_type (gdbarch, fbsd_get_siginfo_type);
-- 
2.11.0

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 0/8] Add support for $_siginfo on FreeBSD
@ 2017-06-29 23:33 John Baldwin
  2017-06-29 23:33 ` [PATCH 6/8] Recognize the recently-added FreeBSD core dump note for LWP info John Baldwin
                   ` (8 more replies)
  0 siblings, 9 replies; 13+ messages in thread
From: John Baldwin @ 2017-06-29 23:33 UTC (permalink / raw)
  To: gdb-patches, binutils

This series adds support for $_siginfo for both live processes and
process cores.  siginfo_t for threads is only stored in a per-thread
ELF core note on FreeBSD 12.0 and later.

The existing code in corelow.c for siginfo_t assumed the Linux-specific
NT_SIGINFO ELF core note, but FreeBSD stores siginfo as one member of a
larger ELF core note.  To accomodate this, I added a new gdbarch method
that is used to fetch the signal information from a core dump.  I moved
the body of the existing core_get_siginfo function into an implementation
of the new gdbarch method in linux-tdep.c.

Tested on FreeBSD/amd64 (64-bit and 32-bit binaries), FreeBSD/i386,
and Centos/x86-64 (no regressions in test suite for this last).

John Baldwin (8):
  Implement the "get_siginfo_type" gdbarch method for FreeBSD
    architectures.
  Fetch signal information for native FreeBSD processes.
  Move the thread_section_name class to gdbcore.h.
  Add a new gdbarch method to fetch signal information from core files.
  Use the thread_section_name helper class in fbsd_core_thread_name.
  Recognize the recently-added FreeBSD core dump note for LWP info.
  Create psuedo sections for FreeBSD NT_PTLWPINFO core notes.
  Read signal information from FreeBSD core dumps.

 bfd/ChangeLog        |   4 ++
 bfd/elf.c            |   4 ++
 binutils/ChangeLog   |   4 ++
 binutils/readelf.c   |   2 +
 gdb/ChangeLog        |  43 +++++++++++
 gdb/corelow.c        |  82 ++++-----------------
 gdb/fbsd-nat.c       | 155 ++++++++++++++++++++++++++++++++++++++++
 gdb/fbsd-tdep.c      | 197 +++++++++++++++++++++++++++++++++++++++++++++++++--
 gdb/gdbarch.c        |  32 +++++++++
 gdb/gdbarch.h        |  10 +++
 gdb/gdbarch.sh       |   5 ++
 gdb/gdbcore.h        |  45 ++++++++++++
 gdb/linux-tdep.c     |  21 ++++++
 include/ChangeLog    |   4 ++
 include/elf/common.h |   1 +
 15 files changed, 536 insertions(+), 73 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/8] Implement the "get_siginfo_type" gdbarch method for FreeBSD architectures.
  2017-06-29 23:33 [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
  2017-06-29 23:33 ` [PATCH 6/8] Recognize the recently-added FreeBSD core dump note for LWP info John Baldwin
@ 2017-06-29 23:33 ` John Baldwin
  2017-06-29 23:33 ` [PATCH 8/8] Read signal information from FreeBSD core dumps John Baldwin
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: John Baldwin @ 2017-06-29 23:33 UTC (permalink / raw)
  To: gdb-patches, binutils

As with Linux architectures, cache the created type in the gdbarch when it
is first created.  Currently FreeBSD uses an identical siginfo type on
all architectures, so there is no support for architecture-specific fields.

gdb/ChangeLog:

	* fbsd-tdep.c (fbsd_gdbarch_data_handle, struct fbsd_gdbarch_data)
	(init_fbsd_gdbarch_data, get_fbsd_gdbarch_data)
	(fbsd_get_siginfo_type): New.
	(fbsd_init_abi): Install gdbarch "get_siginfo_type" method.
	(_initialize_fbsd_tdep): New.
---
 gdb/ChangeLog   |   8 ++++
 gdb/fbsd-tdep.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 130 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4e091d7e40..43d422b4ab 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2017-06-28  John Baldwin  <jhb@FreeBSD.org>
+
+	* fbsd-tdep.c (fbsd_gdbarch_data_handle, struct fbsd_gdbarch_data)
+	(init_fbsd_gdbarch_data, get_fbsd_gdbarch_data)
+	(fbsd_get_siginfo_type): New.
+	(fbsd_init_abi): Install gdbarch "get_siginfo_type" method.
+	(_initialize_fbsd_tdep): New.
+
 2017-06-19  John Baldwin  <jhb@FreeBSD.org>
 
 	* mips-tdep.c (print_gp_register_row): Don't error for unavailable
diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
index b834ce38b4..24a3c20dd6 100644
--- a/gdb/fbsd-tdep.c
+++ b/gdb/fbsd-tdep.c
@@ -30,6 +30,26 @@
 #include "fbsd-tdep.h"
 
 
+static struct gdbarch_data *fbsd_gdbarch_data_handle;
+
+struct fbsd_gdbarch_data
+  {
+    struct type *siginfo_type;
+  };
+
+static void *
+init_fbsd_gdbarch_data (struct gdbarch *gdbarch)
+{
+  return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct fbsd_gdbarch_data);
+}
+
+static struct fbsd_gdbarch_data *
+get_fbsd_gdbarch_data (struct gdbarch *gdbarch)
+{
+  return ((struct fbsd_gdbarch_data *)
+	  gdbarch_data (gdbarch, fbsd_gdbarch_data_handle));
+}
+
 /* This is how we want PTIDs from core files to be printed.  */
 
 static const char *
@@ -314,6 +334,97 @@ fbsd_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file,
   fprint_auxv_entry (file, name, description, format, type, val);
 }
 
+/* Implement the "get_siginfo_type" gdbarch method.  */
+
+static struct type *
+fbsd_get_siginfo_type (struct gdbarch *gdbarch)
+{
+  struct fbsd_gdbarch_data *fbsd_gdbarch_data;
+  struct type *int_type, *int32_type, *uint32_type, *long_type, *void_ptr_type;
+  struct type *uid_type, *pid_type;
+  struct type *sigval_type, *reason_type;
+  struct type *siginfo_type;
+  struct type *type;
+
+  fbsd_gdbarch_data = get_fbsd_gdbarch_data (gdbarch);
+  if (fbsd_gdbarch_data->siginfo_type != NULL)
+    return fbsd_gdbarch_data->siginfo_type;
+
+  int_type = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch),
+				0, "int");
+  int32_type = arch_integer_type (gdbarch, 32, 0, "int32_t");
+  uint32_type = arch_integer_type (gdbarch, 32, 1, "uint32_t");
+  long_type = arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch),
+				 0, "long");
+  void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
+
+  /* union sigval */
+  sigval_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+  TYPE_NAME (sigval_type) = xstrdup ("sigval");
+  append_composite_type_field (sigval_type, "sival_int", int_type);
+  append_composite_type_field (sigval_type, "sival_ptr", void_ptr_type);
+
+  /* __pid_t */
+  pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+			TYPE_LENGTH (int32_type), "__pid_t");
+  TYPE_TARGET_TYPE (pid_type) = int32_type;
+  TYPE_TARGET_STUB (pid_type) = 1;
+
+  /* __uid_t */
+  uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
+			TYPE_LENGTH (uint32_type), "__uid_t");
+  TYPE_TARGET_TYPE (uid_type) = uint32_type;
+  TYPE_TARGET_STUB (uid_type) = 1;
+
+  /* _reason */
+  reason_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_UNION);
+
+  /* _fault */
+  type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (type, "si_trapno", int_type);
+  append_composite_type_field (reason_type, "_fault", type);
+
+  /* _timer */
+  type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (type, "si_timerid", int_type);
+  append_composite_type_field (type, "si_overrun", int_type);
+  append_composite_type_field (reason_type, "_timer", type);
+
+  /* _mesgq */
+  type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (type, "si_mqd", int_type);
+  append_composite_type_field (reason_type, "_mesgq", type);
+
+  /* _poll */
+  type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (type, "si_band", long_type);
+  append_composite_type_field (reason_type, "_poll", type);
+
+  /* __spare__ */
+  type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  append_composite_type_field (type, "__spare1__", long_type);
+  append_composite_type_field (type, "__spare2__",
+			       init_vector_type (int_type, 7));
+  append_composite_type_field (reason_type, "__spare__", type);
+
+  /* struct siginfo */
+  siginfo_type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+  TYPE_NAME (siginfo_type) = xstrdup ("siginfo");
+  append_composite_type_field (siginfo_type, "si_signo", int_type);
+  append_composite_type_field (siginfo_type, "si_errno", int_type);
+  append_composite_type_field (siginfo_type, "si_code", int_type);
+  append_composite_type_field (siginfo_type, "si_pid", pid_type);
+  append_composite_type_field (siginfo_type, "si_uid", uid_type);
+  append_composite_type_field (siginfo_type, "si_status", int_type);
+  append_composite_type_field (siginfo_type, "si_addr", void_ptr_type);
+  append_composite_type_field (siginfo_type, "si_value", sigval_type);
+  append_composite_type_field (siginfo_type, "_reason", reason_type);
+
+  fbsd_gdbarch_data->siginfo_type = siginfo_type;
+
+  return siginfo_type;
+}
+
 /* Implement the "get_syscall_number" gdbarch method.  */
 
 static LONGEST
@@ -339,8 +450,19 @@ fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_core_thread_name (gdbarch, fbsd_core_thread_name);
   set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes);
   set_gdbarch_print_auxv_entry (gdbarch, fbsd_print_auxv_entry);
+  set_gdbarch_get_siginfo_type (gdbarch, fbsd_get_siginfo_type);
 
   /* `catch syscall' */
   set_xml_syscall_file_name (gdbarch, "syscalls/freebsd.xml");
   set_gdbarch_get_syscall_number (gdbarch, fbsd_get_syscall_number);
 }
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern initialize_file_ftype _initialize_fbsd_tdep;
+
+void
+_initialize_fbsd_tdep (void)
+{
+  fbsd_gdbarch_data_handle =
+    gdbarch_data_register_post_init (init_fbsd_gdbarch_data);
+}
-- 
2.11.0

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 2/8] Fetch signal information for native FreeBSD processes.
  2017-06-29 23:33 [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
                   ` (2 preceding siblings ...)
  2017-06-29 23:33 ` [PATCH 8/8] Read signal information from FreeBSD core dumps John Baldwin
@ 2017-06-29 23:33 ` John Baldwin
  2017-06-29 23:33 ` [PATCH 3/8] Move the thread_section_name class to gdbcore.h John Baldwin
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: John Baldwin @ 2017-06-29 23:33 UTC (permalink / raw)
  To: gdb-patches, binutils

Use the `pl_siginfo' field in the `struct ptrace_lwpinfo' object returned
by the PT_LWPINFO ptrace() request to supply the current contents of
$_siginfo for each thread.  Note that FreeBSD does not supply a way to
modify the signal information for a thread, so $_siginfo is read-only for
FreeBSD.

To handle 32-bit processes on a 64-bit host, define types for 32-bit
compatible siginfo_t and convert the 64-bit siginfo_t to the 32-bit
equivalent when supplying information for a 32-bit process.

gdb/ChangeLog:

	* fbsd-nat.c [PT_LWPINFO && __LP64__] (union sigval32)
	(struct siginfo32): New.
	[PT_LWPINFO] (fbsd_siginfo_size, fbsd_convert_siginfo): New.
	(fbsd_xfer_partial) [PT_LWPINFO]: Handle TARGET_OBJECT_SIGNAL_INFO
	via ptrace(PT_LWPINFO).
---
 gdb/ChangeLog  |   8 +++
 gdb/fbsd-nat.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 163 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 43d422b4ab..1e624d3667 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,13 @@
 2017-06-28  John Baldwin  <jhb@FreeBSD.org>
 
+	* fbsd-nat.c [PT_LWPINFO && __LP64__] (union sigval32)
+	(struct siginfo32): New.
+	[PT_LWPINFO] (fbsd_siginfo_size, fbsd_convert_siginfo): New.
+	(fbsd_xfer_partial) [PT_LWPINFO]: Handle TARGET_OBJECT_SIGNAL_INFO
+	via ptrace(PT_LWPINFO).
+
+2017-06-28  John Baldwin  <jhb@FreeBSD.org>
+
 	* fbsd-tdep.c (fbsd_gdbarch_data_handle, struct fbsd_gdbarch_data)
 	(init_fbsd_gdbarch_data, get_fbsd_gdbarch_data)
 	(fbsd_get_siginfo_type): New.
diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index ef5ad1ec92..3852b8e48d 100644
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -28,6 +28,7 @@
 #include <sys/types.h>
 #include <sys/procfs.h>
 #include <sys/ptrace.h>
+#include <sys/signal.h>
 #include <sys/sysctl.h>
 #ifdef HAVE_KINFO_GETVMMAP
 #include <sys/user.h>
@@ -216,6 +217,128 @@ static enum target_xfer_status (*super_xfer_partial) (struct target_ops *ops,
 						      ULONGEST len,
 						      ULONGEST *xfered_len);
 
+#ifdef PT_LWPINFO
+/* Return the size of siginfo for the current inferior.  */
+
+#ifdef __LP64__
+union sigval32 {
+  int sival_int;
+  uint32_t sival_ptr;
+};
+
+/* This structure matches the naming and layout of `siginfo_t' in
+   <sys/signal.h>.  In particular, the `si_foo' macros defined in that
+   header can be used with both types to copy fields in the `_reason'
+   union.  */
+
+struct siginfo32 {
+  int si_signo;
+  int si_errno;
+  int si_code;
+  __pid_t si_pid;
+  __uid_t si_uid;
+  int si_status;
+  uint32_t si_addr;
+  union sigval32 si_value;
+  union {
+    struct {
+      int _trapno;
+    } _fault;
+    struct {
+      int _timerid;
+      int _overrun;
+    } _timer;
+    struct {
+      int _mqd;
+    } _mesgq;
+    struct {
+      int32_t _band;
+    } _poll;
+    struct {
+      int32_t __spare1__;
+      int __spare2__[7];
+    } __spare__;
+  } _reason;
+};
+#endif
+
+static size_t
+fbsd_siginfo_size ()
+{
+#ifdef __LP64__
+  struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
+
+  /* Is the inferior 32-bit?  If so, use the 32-bit siginfo size.  */
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+    return sizeof (struct siginfo32);
+#endif
+  return sizeof (siginfo_t);
+} 
+
+/* Convert a native 64-bit siginfo object to a 32-bit object.  Note
+   that FreeBSD doesn't support writing to $_siginfo, so this only
+   needs to convert one way.  */
+
+static void
+fbsd_convert_siginfo (siginfo_t *si)
+{
+#ifdef __LP64__
+  struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
+
+  /* Is the inferior 32-bit?  If not, nothing to do.  */
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word != 32)
+    return;
+
+  struct siginfo32 si32;
+
+  si32.si_signo = si->si_signo;
+  si32.si_errno = si->si_errno;
+  si32.si_code = si->si_code;
+  si32.si_pid = si->si_pid;
+  si32.si_uid = si->si_uid;
+  si32.si_status = si->si_status;
+  si32.si_addr = (uintptr_t) si->si_addr;
+
+  /* If sival_ptr is being used instead of sival_int on a big-endian
+     platform, then sival_int will be zero since it holds the upper
+     32-bits of the pointer value.  */
+#if _BYTE_ORDER == _BIG_ENDIAN
+  if (si->si_value.sival_int == 0)
+    si32->si_value.sival_ptr = (uintptr_t) si->si_value.sival_ptr;
+  else
+    si32.si_value.sival_int = si->si_value.sival_int;
+#else
+  si32.si_value.sival_int = si->si_value.sival_int;
+#endif
+
+  /* Always copy the spare fields and then possibly overwrite them for
+     signal-specific or code-specific fields.  */
+  si32._reason.__spare__.__spare1__ = si->_reason.__spare__.__spare1__;
+  for (int i = 0; i < 7; i++)
+    si32._reason.__spare__.__spare2__[i] = si->_reason.__spare__.__spare2__[i];
+  switch (si->si_signo) {
+  case SIGILL:
+  case SIGFPE:
+  case SIGSEGV:
+  case SIGBUS:
+    si32.si_trapno = si->si_trapno;
+    break;
+  }
+  switch (si->si_code) {
+  case SI_TIMER:
+    si32.si_timerid = si->si_timerid;
+    si32.si_overrun = si->si_overrun;
+    break;
+  case SI_MESGQ:
+    si32.si_mqd = si->si_mqd;
+    break;
+  }
+
+  memcpy(si, &si32, sizeof (si32));
+#endif
+}
+#endif
+
 /* Implement the "to_xfer_partial target_ops" method.  */
 
 static enum target_xfer_status
@@ -228,6 +351,38 @@ fbsd_xfer_partial (struct target_ops *ops, enum target_object object,
 
   switch (object)
     {
+#ifdef PT_LWPINFO
+    case TARGET_OBJECT_SIGNAL_INFO:
+      {
+	struct ptrace_lwpinfo pl;
+	size_t siginfo_size;
+
+	/* FreeBSD doesn't support writing to $_siginfo.  */
+	if (writebuf != NULL)
+	  return TARGET_XFER_E_IO;
+
+	if (inferior_ptid.lwp_p ())
+	  pid = inferior_ptid.lwp ();
+
+	siginfo_size = fbsd_siginfo_size ();
+	if (offset > siginfo_size)
+	  return TARGET_XFER_E_IO;
+
+	if (ptrace (PT_LWPINFO, pid, (PTRACE_TYPE_ARG3) &pl, sizeof (pl)) == -1)
+	  return TARGET_XFER_E_IO;
+
+	if (!(pl.pl_flags & PL_FLAG_SI))
+	  return TARGET_XFER_E_IO;
+
+	fbsd_convert_siginfo (&pl.pl_siginfo);
+	if (offset + len > siginfo_size)
+	  len = siginfo_size - offset;
+
+	memcpy (readbuf, ((gdb_byte *) &pl.pl_siginfo) + offset, len);
+	*xfered_len = len;
+	return TARGET_XFER_OK;
+      }
+#endif
     case TARGET_OBJECT_AUXV:
       {
 	struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
-- 
2.11.0

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 3/8] Move the thread_section_name class to gdbcore.h.
  2017-06-29 23:33 [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
                   ` (3 preceding siblings ...)
  2017-06-29 23:33 ` [PATCH 2/8] Fetch signal information for native FreeBSD processes John Baldwin
@ 2017-06-29 23:33 ` John Baldwin
  2017-06-29 23:33 ` [PATCH 7/8] Create psuedo sections for FreeBSD NT_PTLWPINFO core notes John Baldwin
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: John Baldwin @ 2017-06-29 23:33 UTC (permalink / raw)
  To: gdb-patches, binutils

This allows it to be used outside of corelow.c.
---
 gdb/ChangeLog |  5 +++++
 gdb/corelow.c | 45 ---------------------------------------------
 gdb/gdbcore.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+), 45 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 1e624d3667..bdedb63435 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
 2017-06-28  John Baldwin  <jhb@FreeBSD.org>
 
+	* corelow.c (thread_section_name): Move to ...
+	* gdbcore.h (thread_section_name): ... here.
+
+2017-06-28  John Baldwin  <jhb@FreeBSD.org>
+
 	* fbsd-nat.c [PT_LWPINFO && __LP64__] (union sigval32)
 	(struct siginfo32): New.
 	[PT_LWPINFO] (fbsd_siginfo_size, fbsd_convert_siginfo): New.
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 0aff02d4db..578c910bb5 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -485,51 +485,6 @@ core_detach (struct target_ops *ops, const char *args, int from_tty)
     printf_filtered (_("No core file now.\n"));
 }
 
-/* Build either a single-thread or multi-threaded section name for
-   PTID.
-
-   If ptid's lwp member is zero, we want to do the single-threaded
-   thing: look for a section named NAME (as passed to the
-   constructor).  If ptid's lwp member is non-zero, we'll want do the
-   multi-threaded thing: look for a section named "NAME/LWP", where
-   LWP is the shortest ASCII decimal representation of ptid's lwp
-   member.  */
-
-class thread_section_name
-{
-public:
-  /* NAME is the single-threaded section name.  If PTID represents an
-     LWP, then the build section name is "NAME/LWP", otherwise it's
-     just "NAME" unmodified.  */
-  thread_section_name (const char *name, ptid_t ptid)
-  {
-    if (ptid.lwp_p ())
-      {
-	m_storage = string_printf ("%s/%ld", name, ptid.lwp ());
-	m_section_name = m_storage.c_str ();
-      }
-    else
-      m_section_name = name;
-  }
-
-  /* Return the computed section name.  The result is valid as long as
-     this thread_section_name object is live.  */
-  const char *c_str () const
-  { return m_section_name; }
-
-  /* Disable copy.  */
-  thread_section_name (const thread_section_name &) = delete;
-  void operator= (const thread_section_name &) = delete;
-
-private:
-  /* Either a pointer into M_STORAGE, or a pointer to the name passed
-     as parameter to the constructor.  */
-  const char *m_section_name;
-  /* If we need to build a new section name, this is where we store
-     it.  */
-  std::string m_storage;
-};
-
 /* 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.
diff --git a/gdb/gdbcore.h b/gdb/gdbcore.h
index e3eed0395d..87f3dcd64d 100644
--- a/gdb/gdbcore.h
+++ b/gdb/gdbcore.h
@@ -226,6 +226,51 @@ struct core_fns
 
   };
 
+/* Build either a single-thread or multi-threaded section name for
+   PTID.
+
+   If ptid's lwp member is zero, we want to do the single-threaded
+   thing: look for a section named NAME (as passed to the
+   constructor).  If ptid's lwp member is non-zero, we'll want do the
+   multi-threaded thing: look for a section named "NAME/LWP", where
+   LWP is the shortest ASCII decimal representation of ptid's lwp
+   member.  */
+
+class thread_section_name
+{
+public:
+  /* NAME is the single-threaded section name.  If PTID represents an
+     LWP, then the build section name is "NAME/LWP", otherwise it's
+     just "NAME" unmodified.  */
+  thread_section_name (const char *name, ptid_t ptid)
+  {
+    if (ptid.lwp_p ())
+      {
+	m_storage = string_printf ("%s/%ld", name, ptid.lwp ());
+	m_section_name = m_storage.c_str ();
+      }
+    else
+      m_section_name = name;
+  }
+
+  /* Return the computed section name.  The result is valid as long as
+     this thread_section_name object is live.  */
+  const char *c_str () const
+  { return m_section_name; }
+
+  /* Disable copy.  */
+  thread_section_name (const thread_section_name &) = delete;
+  void operator= (const thread_section_name &) = delete;
+
+private:
+  /* Either a pointer into M_STORAGE, or a pointer to the name passed
+     as parameter to the constructor.  */
+  const char *m_section_name;
+  /* If we need to build a new section name, this is where we store
+     it.  */
+  std::string m_storage;
+};
+
 /* NOTE: cagney/2004-04-05: Replaced by "regset.h" and
    regset_from_core_section().  */
 extern void deprecated_add_core_fns (struct core_fns *cf);
-- 
2.11.0

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 6/8] Recognize the recently-added FreeBSD core dump note for LWP info.
  2017-06-29 23:33 [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
@ 2017-06-29 23:33 ` John Baldwin
  2017-06-30  3:19   ` Alan Modra
  2017-06-29 23:33 ` [PATCH 1/8] Implement the "get_siginfo_type" gdbarch method for FreeBSD architectures John Baldwin
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 13+ messages in thread
From: John Baldwin @ 2017-06-29 23:33 UTC (permalink / raw)
  To: gdb-patches, binutils

This core dump note contains the same information returned by the
ptrace PT_LWPINFO operation for each LWP belonging to a process.

binutils/ChangeLog:

	* readelf.c (get_freebsd_elfcore_note_type): Handle
	NT_FREEBSD_PTLWPINFO.

include/ChangeLog:

	* elf/common.h (NT_FREEBSD_PTLWPINFO): Define.
---
 binutils/ChangeLog   | 4 ++++
 binutils/readelf.c   | 2 ++
 include/ChangeLog    | 4 ++++
 include/elf/common.h | 1 +
 4 files changed, 11 insertions(+)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 6997db969c..94d2be4554 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,7 @@
+2017-06-28  John Baldwin  <jhb@FreeBSD.org>
+	* readelf.c (get_freebsd_elfcore_note_type): Handle
+	NT_FREEBSD_PTLWPINFO.
+
 2017-06-19  Nick Clifton  <nickc@redhat.com>
 
 	PR binutils/21619
diff --git a/binutils/readelf.c b/binutils/readelf.c
index bb6bb79d4e..74d116b88e 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -16710,6 +16710,8 @@ get_freebsd_elfcore_note_type (unsigned e_type)
       return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
     case NT_FREEBSD_PROCSTAT_AUXV:
       return _("NT_PROCSTAT_AUXV (auxv data)");
+    case NT_FREEBSD_PTLWPINFO:
+      return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
     }
   return get_note_type (e_type);
 }
diff --git a/include/ChangeLog b/include/ChangeLog
index 44905d7da9..250747e282 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2017-06-28  John Baldwin  <jhb@FreeBSD.org>
+
+	* elf/common.h (NT_FREEBSD_PTLWPINFO): Define.
+
 2017-06-16  Alan Modra  <amodra@gmail.com>
 
 	PR ld/20022
diff --git a/include/elf/common.h b/include/elf/common.h
index 484cb48f96..b98c5eac4b 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -637,6 +637,7 @@
 #define	NT_FREEBSD_PROCSTAT_OSREL	14	/* Procstat osreldate data. */
 #define	NT_FREEBSD_PROCSTAT_PSSTRINGS	15	/* Procstat ps_strings data. */
 #define	NT_FREEBSD_PROCSTAT_AUXV	16	/* Procstat auxv data. */
+#define	NT_FREEBSD_PTLWPINFO	17	/* Thread ptrace miscellaneous info. */
 
 /* Note segments for core files on NetBSD systems.  Note name
    must start with "NetBSD-CORE".  */
-- 
2.11.0

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 4/8] Add a new gdbarch method to fetch signal information from core files.
  2017-06-29 23:33 [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
                   ` (5 preceding siblings ...)
  2017-06-29 23:33 ` [PATCH 7/8] Create psuedo sections for FreeBSD NT_PTLWPINFO core notes John Baldwin
@ 2017-06-29 23:41 ` John Baldwin
  2017-06-29 23:41 ` [PATCH 5/8] Use the thread_section_name helper class in fbsd_core_thread_name John Baldwin
  2017-07-06 11:17 ` [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
  8 siblings, 0 replies; 13+ messages in thread
From: John Baldwin @ 2017-06-29 23:41 UTC (permalink / raw)
  To: gdb-patches, binutils

Previously the core_xfer_partial method used core_get_siginfo to handle
TARGET_OBJECT_SIGNAL_INFO requests.  However, core_get_siginfo looked for
Linux-specific sections in the core file.  To support fetching siginfo
from cores on other systems, add a new gdbarch method (`core_xfer_siginfo`)
and move the body of the existing core_get_siginfo into a
linux_core_xfer_siginfo implementation of this method in linux-tdep.c.

gdb/ChangeLog:

	* corelow.c (get_core_siginfo): Remove.
	(core_xfer_partial): Use the gdbarch "core_xfer_siginfo" method
	instead of get_core_siginfo.
	* gdbarch.sh (core_xfer_siginfo): New gdbarch callback.
	* gdbarch.h: Re-generate.
	* gdbarch.c: Re-generate.
	* linux-tdep.c (linux_core_xfer_siginfo): New.
	(linux_init_abi): Install gdbarch "core_xfer_siginfo" method.
---
 gdb/ChangeLog    | 11 +++++++++++
 gdb/corelow.c    | 37 +++++++++++++------------------------
 gdb/gdbarch.c    | 32 ++++++++++++++++++++++++++++++++
 gdb/gdbarch.h    | 10 ++++++++++
 gdb/gdbarch.sh   |  5 +++++
 gdb/linux-tdep.c | 21 +++++++++++++++++++++
 6 files changed, 92 insertions(+), 24 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index bdedb63435..a06b0a461f 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,16 @@
 2017-06-28  John Baldwin  <jhb@FreeBSD.org>
 
+	* corelow.c (get_core_siginfo): Remove.
+	(core_xfer_partial): Use the gdbarch "core_xfer_siginfo" method
+	instead of get_core_siginfo.
+	* gdbarch.sh (core_xfer_siginfo): New gdbarch callback.
+	* gdbarch.h: Re-generate.
+	* gdbarch.c: Re-generate.
+	* linux-tdep.c (linux_core_xfer_siginfo): New.
+	(linux_init_abi): Install gdbarch "core_xfer_siginfo" method.
+
+2017-06-28  John Baldwin  <jhb@FreeBSD.org>
+
 	* corelow.c (thread_section_name): Move to ...
 	* gdbcore.h (thread_section_name): ... here.
 
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 578c910bb5..5dbabc79e6 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -668,25 +668,6 @@ add_to_spuid_list (bfd *abfd, asection *asect, void *list_p)
   list->pos += 4;
 }
 
-/* Read siginfo data from the core, if possible.  Returns -1 on
-   failure.  Otherwise, returns the number of bytes read.  ABFD is the
-   core file's BFD; READBUF, OFFSET, and LEN are all as specified by
-   the to_xfer_partial interface.  */
-
-static LONGEST
-get_core_siginfo (bfd *abfd, gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
-{
-  thread_section_name section_name (".note.linuxcore.siginfo", inferior_ptid);
-  asection *section = bfd_get_section_by_name (abfd, section_name.c_str ());
-  if (section == NULL)
-    return -1;
-
-  if (!bfd_get_section_contents (abfd, section, readbuf, offset, len))
-    return -1;
-
-  return len;
-}
-
 static enum target_xfer_status
 core_xfer_partial (struct target_ops *ops, enum target_object object,
 		   const char *annex, gdb_byte *readbuf,
@@ -874,12 +855,20 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
     case TARGET_OBJECT_SIGNAL_INFO:
       if (readbuf)
 	{
-	  LONGEST l = get_core_siginfo (core_bfd, readbuf, offset, len);
-
-	  if (l > 0)
+	  if (core_gdbarch
+	      && gdbarch_core_xfer_siginfo_p (core_gdbarch))
 	    {
-	      *xfered_len = len;
-	      return TARGET_XFER_OK;
+	      LONGEST l = gdbarch_core_xfer_siginfo  (core_gdbarch, readbuf,
+						      offset, len);
+
+	      if (l >= 0)
+		{
+		  *xfered_len = l;
+		  if (l == 0)
+		    return TARGET_XFER_EOF;
+		  else
+		    return TARGET_XFER_OK;
+		}
 	    }
 	}
       return TARGET_XFER_E_IO;
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index e5efdfbb26..24521b5e23 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -287,6 +287,7 @@ struct gdbarch
   gdbarch_core_xfer_shared_libraries_aix_ftype *core_xfer_shared_libraries_aix;
   gdbarch_core_pid_to_str_ftype *core_pid_to_str;
   gdbarch_core_thread_name_ftype *core_thread_name;
+  gdbarch_core_xfer_siginfo_ftype *core_xfer_siginfo;
   const char * gcore_bfd_target;
   int vtable_function_descriptors;
   int vbit_in_delta;
@@ -646,6 +647,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of core_xfer_shared_libraries_aix, has predicate.  */
   /* Skip verify of core_pid_to_str, has predicate.  */
   /* Skip verify of core_thread_name, has predicate.  */
+  /* Skip verify of core_xfer_siginfo, has predicate.  */
   /* Skip verify of gcore_bfd_target, has predicate.  */
   /* Skip verify of vtable_function_descriptors, invalid_p == 0 */
   /* Skip verify of vbit_in_delta, invalid_p == 0 */
@@ -884,6 +886,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
                       "gdbarch_dump: core_xfer_shared_libraries_aix = <%s>\n",
                       host_address_to_string (gdbarch->core_xfer_shared_libraries_aix));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_core_xfer_siginfo_p() = %d\n",
+                      gdbarch_core_xfer_siginfo_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: core_xfer_siginfo = <%s>\n",
+                      host_address_to_string (gdbarch->core_xfer_siginfo));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: decr_pc_after_break = %s\n",
                       core_addr_to_string_nz (gdbarch->decr_pc_after_break));
   fprintf_unfiltered (file,
@@ -3797,6 +3805,30 @@ set_gdbarch_core_thread_name (struct gdbarch *gdbarch,
 }
 
 int
+gdbarch_core_xfer_siginfo_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->core_xfer_siginfo != NULL;
+}
+
+LONGEST
+gdbarch_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->core_xfer_siginfo != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_core_xfer_siginfo called\n");
+  return gdbarch->core_xfer_siginfo (gdbarch,  readbuf, offset, len);
+}
+
+void
+set_gdbarch_core_xfer_siginfo (struct gdbarch *gdbarch,
+                               gdbarch_core_xfer_siginfo_ftype core_xfer_siginfo)
+{
+  gdbarch->core_xfer_siginfo = core_xfer_siginfo;
+}
+
+int
 gdbarch_gcore_bfd_target_p (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != NULL);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index ab7561f851..1c95301f6f 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -933,6 +933,16 @@ typedef const char * (gdbarch_core_thread_name_ftype) (struct gdbarch *gdbarch,
 extern const char * gdbarch_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr);
 extern void set_gdbarch_core_thread_name (struct gdbarch *gdbarch, gdbarch_core_thread_name_ftype *core_thread_name);
 
+/* Read offset OFFSET of TARGET_OBJECT_SIGNAL_INFO signal information
+   from core file into buffer READBUF with length LEN.  Return the number
+   of bytes read (zero indicates EOF, a negative value indicates failure). */
+
+extern int gdbarch_core_xfer_siginfo_p (struct gdbarch *gdbarch);
+
+typedef LONGEST (gdbarch_core_xfer_siginfo_ftype) (struct gdbarch *gdbarch, gdb_byte *readbuf, ULONGEST offset, ULONGEST len);
+extern LONGEST gdbarch_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf, ULONGEST offset, ULONGEST len);
+extern void set_gdbarch_core_xfer_siginfo (struct gdbarch *gdbarch, gdbarch_core_xfer_siginfo_ftype *core_xfer_siginfo);
+
 /* BFD target to use when generating a core file. */
 
 extern int gdbarch_gcore_bfd_target_p (struct gdbarch *gdbarch);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 22f5715037..3aab17f958 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -755,6 +755,11 @@ M;const char *;core_pid_to_str;ptid_t ptid;ptid
 # How the core target extracts the name of a thread from a core file.
 M;const char *;core_thread_name;struct thread_info *thr;thr
 
+# Read offset OFFSET of TARGET_OBJECT_SIGNAL_INFO signal information
+# from core file into buffer READBUF with length LEN.  Return the number
+# of bytes read (zero indicates EOF, a negative value indicates failure).
+M;LONGEST;core_xfer_siginfo;gdb_byte *readbuf, ULONGEST offset, ULONGEST len; readbuf, offset, len
+
 # BFD target to use when generating a core file.
 V;const char *;gcore_bfd_target;;;0;0;;;pstring (gdbarch->gcore_bfd_target)
 
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 1afa8d7b35..15b7ba17fe 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -1127,6 +1127,26 @@ linux_core_info_proc (struct gdbarch *gdbarch, const char *args,
     error (_("unable to handle request"));
 }
 
+/* Read siginfo data from the core, if possible.  Returns -1 on
+   failure.  Otherwise, returns the number of bytes read.  READBUF,
+   OFFSET, and LEN are all as specified by the to_xfer_partial
+   interface.  */
+
+static LONGEST
+linux_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf,
+			 ULONGEST offset, ULONGEST len)
+{
+  thread_section_name section_name (".note.linuxcore.siginfo", inferior_ptid);
+  asection *section = bfd_get_section_by_name (core_bfd, section_name.c_str ());
+  if (section == NULL)
+    return -1;
+
+  if (!bfd_get_section_contents (core_bfd, section, readbuf, offset, len))
+    return -1;
+
+  return len;
+}
+
 typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size,
 					    ULONGEST offset, ULONGEST inode,
 					    int read, int write,
@@ -2521,6 +2541,7 @@ linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_core_pid_to_str (gdbarch, linux_core_pid_to_str);
   set_gdbarch_info_proc (gdbarch, linux_info_proc);
   set_gdbarch_core_info_proc (gdbarch, linux_core_info_proc);
+  set_gdbarch_core_xfer_siginfo (gdbarch, linux_core_xfer_siginfo);
   set_gdbarch_find_memory_regions (gdbarch, linux_find_memory_regions);
   set_gdbarch_make_corefile_notes (gdbarch, linux_make_corefile_notes);
   set_gdbarch_has_shared_address_space (gdbarch,
-- 
2.11.0

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 5/8] Use the thread_section_name helper class in fbsd_core_thread_name.
  2017-06-29 23:33 [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
                   ` (6 preceding siblings ...)
  2017-06-29 23:41 ` [PATCH 4/8] Add a new gdbarch method to fetch signal information from core files John Baldwin
@ 2017-06-29 23:41 ` John Baldwin
  2017-07-06 11:17 ` [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
  8 siblings, 0 replies; 13+ messages in thread
From: John Baldwin @ 2017-06-29 23:41 UTC (permalink / raw)
  To: gdb-patches, binutils

gdb/ChangeLog:

	* fbsd-tdep.c (fbsd_core_thread_name): Use thread_section_name.
---
 gdb/ChangeLog   | 4 ++++
 gdb/fbsd-tdep.c | 7 +++----
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a06b0a461f..840383d06d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,9 @@
 2017-06-28  John Baldwin  <jhb@FreeBSD.org>
 
+	* fbsd-tdep.c (fbsd_core_thread_name): Use thread_section_name.
+
+2017-06-28  John Baldwin  <jhb@FreeBSD.org>
+
 	* corelow.c (get_core_siginfo): Remove.
 	(core_xfer_partial): Use the gdbarch "core_xfer_siginfo" method
 	instead of get_core_siginfo.
diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
index 24a3c20dd6..32df104208 100644
--- a/gdb/fbsd-tdep.c
+++ b/gdb/fbsd-tdep.c
@@ -75,7 +75,6 @@ fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr)
   static char buf[80];
   struct bfd_section *section;
   bfd_size_type size;
-  char sectionstr[32];
 
   if (ptid_get_lwp (thr->ptid) != 0)
     {
@@ -86,9 +85,9 @@ fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr)
 	 structure.  Rather than define the full structure here, just
 	 extract the null-terminated name from the start of the
 	 note.  */
-      xsnprintf (sectionstr, sizeof sectionstr, ".thrmisc/%ld",
-		ptid_get_lwp (thr->ptid));
-      section = bfd_get_section_by_name (core_bfd, sectionstr);
+      thread_section_name section_name (".thrmisc", thr->ptid);
+
+      section = bfd_get_section_by_name (core_bfd, section_name.c_str ());
       if (section != NULL && bfd_section_size (core_bfd, section) > 0)
 	{
 	  /* Truncate the name if it is longer than "buf".  */
-- 
2.11.0

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 6/8] Recognize the recently-added FreeBSD core dump note for LWP info.
  2017-06-29 23:33 ` [PATCH 6/8] Recognize the recently-added FreeBSD core dump note for LWP info John Baldwin
@ 2017-06-30  3:19   ` Alan Modra
  0 siblings, 0 replies; 13+ messages in thread
From: Alan Modra @ 2017-06-30  3:19 UTC (permalink / raw)
  To: John Baldwin; +Cc: gdb-patches, binutils

On Thu, Jun 29, 2017 at 04:32:24PM -0700, John Baldwin wrote:
> This core dump note contains the same information returned by the
> ptrace PT_LWPINFO operation for each LWP belonging to a process.
> 
> binutils/ChangeLog:
> 
> 	* readelf.c (get_freebsd_elfcore_note_type): Handle
> 	NT_FREEBSD_PTLWPINFO.
> 
> include/ChangeLog:
> 
> 	* elf/common.h (NT_FREEBSD_PTLWPINFO): Define.

OK.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 7/8] Create psuedo sections for FreeBSD NT_PTLWPINFO core notes.
  2017-06-29 23:33 ` [PATCH 7/8] Create psuedo sections for FreeBSD NT_PTLWPINFO core notes John Baldwin
@ 2017-06-30  3:20   ` Alan Modra
  0 siblings, 0 replies; 13+ messages in thread
From: Alan Modra @ 2017-06-30  3:20 UTC (permalink / raw)
  To: John Baldwin; +Cc: gdb-patches, binutils

On Thu, Jun 29, 2017 at 04:32:25PM -0700, John Baldwin wrote:
> bfd/ChangeLog:
> 
> 	* elf.c (elfcore_grok_freebsd_note): Handle NT_FREEBSD_PTLWPINFO.

OK.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/8] Add support for $_siginfo on FreeBSD
  2017-06-29 23:33 [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
                   ` (7 preceding siblings ...)
  2017-06-29 23:41 ` [PATCH 5/8] Use the thread_section_name helper class in fbsd_core_thread_name John Baldwin
@ 2017-07-06 11:17 ` John Baldwin
  2017-07-06 13:29   ` Pedro Alves
  8 siblings, 1 reply; 13+ messages in thread
From: John Baldwin @ 2017-07-06 11:17 UTC (permalink / raw)
  To: gdb-patches

On 6/29/17 7:32 PM, John Baldwin wrote:
> This series adds support for $_siginfo for both live processes and
> process cores.  siginfo_t for threads is only stored in a per-thread
> ELF core note on FreeBSD 12.0 and later.
> 
> The existing code in corelow.c for siginfo_t assumed the Linux-specific
> NT_SIGINFO ELF core note, but FreeBSD stores siginfo as one member of a
> larger ELF core note.  To accomodate this, I added a new gdbarch method
> that is used to fetch the signal information from a core dump.  I moved
> the body of the existing core_get_siginfo function into an implementation
> of the new gdbarch method in linux-tdep.c.
> 
> Tested on FreeBSD/amd64 (64-bit and 32-bit binaries), FreeBSD/i386,
> and Centos/x86-64 (no regressions in test suite for this last).

Ping?  The binutils patches (6 and 7) have been approved, but some of the
GDB patches (3 and 4) are not FreeBSD-specific (e.g. a new gdbarch method
for fetching siginfo from a core).

> John Baldwin (8):
>   Implement the "get_siginfo_type" gdbarch method for FreeBSD
>     architectures.
>   Fetch signal information for native FreeBSD processes.
>   Move the thread_section_name class to gdbcore.h.
>   Add a new gdbarch method to fetch signal information from core files.
>   Use the thread_section_name helper class in fbsd_core_thread_name.
>   Recognize the recently-added FreeBSD core dump note for LWP info.
>   Create psuedo sections for FreeBSD NT_PTLWPINFO core notes.
>   Read signal information from FreeBSD core dumps.
> 
>  bfd/ChangeLog        |   4 ++
>  bfd/elf.c            |   4 ++
>  binutils/ChangeLog   |   4 ++
>  binutils/readelf.c   |   2 +
>  gdb/ChangeLog        |  43 +++++++++++
>  gdb/corelow.c        |  82 ++++-----------------
>  gdb/fbsd-nat.c       | 155 ++++++++++++++++++++++++++++++++++++++++
>  gdb/fbsd-tdep.c      | 197 +++++++++++++++++++++++++++++++++++++++++++++++++--
>  gdb/gdbarch.c        |  32 +++++++++
>  gdb/gdbarch.h        |  10 +++
>  gdb/gdbarch.sh       |   5 ++
>  gdb/gdbcore.h        |  45 ++++++++++++
>  gdb/linux-tdep.c     |  21 ++++++
>  include/ChangeLog    |   4 ++
>  include/elf/common.h |   1 +
>  15 files changed, 536 insertions(+), 73 deletions(-)
> 


-- 
John Baldwin

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/8] Add support for $_siginfo on FreeBSD
  2017-07-06 11:17 ` [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
@ 2017-07-06 13:29   ` Pedro Alves
  0 siblings, 0 replies; 13+ messages in thread
From: Pedro Alves @ 2017-07-06 13:29 UTC (permalink / raw)
  To: John Baldwin, gdb-patches

On 07/06/2017 12:17 PM, John Baldwin wrote:
> On 6/29/17 7:32 PM, John Baldwin wrote:
>> This series adds support for $_siginfo for both live processes and
>> process cores.  siginfo_t for threads is only stored in a per-thread
>> ELF core note on FreeBSD 12.0 and later.
>>
>> The existing code in corelow.c for siginfo_t assumed the Linux-specific
>> NT_SIGINFO ELF core note, but FreeBSD stores siginfo as one member of a
>> larger ELF core note.  To accomodate this, I added a new gdbarch method
>> that is used to fetch the signal information from a core dump.  I moved
>> the body of the existing core_get_siginfo function into an implementation
>> of the new gdbarch method in linux-tdep.c.
>>
>> Tested on FreeBSD/amd64 (64-bit and 32-bit binaries), FreeBSD/i386,
>> and Centos/x86-64 (no regressions in test suite for this last).
> 
> Ping?  The binutils patches (6 and 7) have been approved, but some of the
> GDB patches (3 and 4) are not FreeBSD-specific (e.g. a new gdbarch method
> for fetching siginfo from a core).

LGTM.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2017-07-06 13:29 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-29 23:33 [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
2017-06-29 23:33 ` [PATCH 6/8] Recognize the recently-added FreeBSD core dump note for LWP info John Baldwin
2017-06-30  3:19   ` Alan Modra
2017-06-29 23:33 ` [PATCH 1/8] Implement the "get_siginfo_type" gdbarch method for FreeBSD architectures John Baldwin
2017-06-29 23:33 ` [PATCH 8/8] Read signal information from FreeBSD core dumps John Baldwin
2017-06-29 23:33 ` [PATCH 2/8] Fetch signal information for native FreeBSD processes John Baldwin
2017-06-29 23:33 ` [PATCH 3/8] Move the thread_section_name class to gdbcore.h John Baldwin
2017-06-29 23:33 ` [PATCH 7/8] Create psuedo sections for FreeBSD NT_PTLWPINFO core notes John Baldwin
2017-06-30  3:20   ` Alan Modra
2017-06-29 23:41 ` [PATCH 4/8] Add a new gdbarch method to fetch signal information from core files John Baldwin
2017-06-29 23:41 ` [PATCH 5/8] Use the thread_section_name helper class in fbsd_core_thread_name John Baldwin
2017-07-06 11:17 ` [PATCH 0/8] Add support for $_siginfo on FreeBSD John Baldwin
2017-07-06 13:29   ` Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).