[v2] gdb: generate NT_PROCSTAT_AUXV in FreeBSD coredumps

Message ID DsvZCQi5DJ32KksR9jwlYvYqMoQmwYXnwATfUit1nOqUMCtNTTS0DQoMGkgOXux78GurVo4sMmSLrX4TUhYANWigZnMRAC7kCsXJKqoDoqo=@emersion.fr
State New, archived
Headers

Commit Message

Simon Ser July 10, 2018, 3:55 p.m. UTC
  gcore generates NT_AUXV notes for Linux targets. On FreeBSD the
auxv is stored in a NT_PROCSTAT_AUXV section, and is prefixed with
the struct size.
---

Changes from v1 to v2: added missing struct size.

I missed this when sending v1. The struct sizes are hardcoded,
let me know if it's better to e.g. copy them over.

 gdb/fbsd-tdep.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)
  

Comments

John Baldwin July 10, 2018, 4:24 p.m. UTC | #1
On 7/10/18 8:55 AM, Simon Ser wrote:
> gcore generates NT_AUXV notes for Linux targets. On FreeBSD the
> auxv is stored in a NT_PROCSTAT_AUXV section, and is prefixed with
> the struct size.
> ---
> 
> Changes from v1 to v2: added missing struct size.
> 
> I missed this when sending v1. The struct sizes are hardcoded,
> let me know if it's better to e.g. copy them over.
> 
>  gdb/fbsd-tdep.c | 32 ++++++++++++++++++++++++++++++++
>  1 file changed, 32 insertions(+)
> 
> diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
> index 9cea0098..37e52bbc 100644
> --- a/gdb/fbsd-tdep.c
> +++ b/gdb/fbsd-tdep.c
> @@ -29,6 +29,15 @@
>  #include "elf-bfd.h"
>  #include "fbsd-tdep.h"
>  
> +#define NT_PROCSTAT_PROC        8       /* Procstat proc data. */
> +#define NT_PROCSTAT_FILES       9       /* Procstat files data. */
> +#define NT_PROCSTAT_VMMAP       10      /* Procstat vmmap data. */
> +#define NT_PROCSTAT_GROUPS      11      /* Procstat groups data. */
> +#define NT_PROCSTAT_UMASK       12      /* Procstat umask data. */
> +#define NT_PROCSTAT_RLIMIT      13      /* Procstat rlimit data. */
> +#define NT_PROCSTAT_OSREL       14      /* Procstat osreldate data. */
> +#define NT_PROCSTAT_PSSTRINGS   15      /* Procstat ps_strings data. */
> +#define NT_PROCSTAT_AUXV        16      /* Procstat auxv data. */

These are already defined (albeit with a slightly different name) in
include/elf/common.h as NT_FREEBSD_PROCSTAT_* already, so you can just
use NT_FREEBSD_PROCSTAT_AUXV below and drop these added defines.

>  /* FreeBSD kernels 12.0 and later include a copy of the
>     'ptrace_lwpinfo' structure returned by the PT_LWPINFO ptrace
> @@ -586,6 +595,29 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
>  
>    note_data = thread_args.note_data;
>  
> +  /* Auxillary vector.  */
> +  gdb::optional<gdb::byte_vector> auxv =
> +    target_read_alloc (current_top_target (), TARGET_OBJECT_AUXV, NULL);
> +  if (auxv && !auxv->empty ())
> +    {
> +      size_t note_desc_size = sizeof (uint32_t) + auxv->size ();
> +      char *note_desc = (char *)malloc (note_desc_size);

This should probably use gdb::unique_xmalloc_ptr() in which case you don't
need free() (and also don't need the cast).

> +      if (!note_desc)
> +        return NULL;
> +      uint32_t auxv_info_size = 8;
> +      if (gdbarch_addr_bit (gdbarch) == 64)
> +        auxv_info_size = 16;

You could perhaps simplify this as:

    auxv_info_size = gdbarch_addr_bit (gdbarch) / 8;

or possibly

    auxv_info_size = gdbarch_pointer_bit (gdbarch) / 8;

> +      memcpy (note_desc, &auxv_info_size, sizeof (uint32_t));
> +      memcpy (note_desc + sizeof (uint32_t), auxv->data (), auxv->size ());
> +      note_data = elfcore_write_note (obfd, note_data, note_size,
> +                                      "FreeBSD", NT_PROCSTAT_AUXV,
> +                                      note_desc, note_desc_size);
> +      free(note_desc);
> +
> +      if (!note_data)
> +        return NULL;
> +    }
> +
>    return note_data;
>  }

Also, you will need a suitable ChangeLog entry in gdb/ChangeLog, something like:

	* fbsd-tdep.c (fbsd_make_corefile_notes): Write
	NT_FREEBSD_PROCSTAT_AUXV note.
  

Patch

diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
index 9cea0098..37e52bbc 100644
--- a/gdb/fbsd-tdep.c
+++ b/gdb/fbsd-tdep.c
@@ -29,6 +29,15 @@ 
 #include "elf-bfd.h"
 #include "fbsd-tdep.h"
 
+#define NT_PROCSTAT_PROC        8       /* Procstat proc data. */
+#define NT_PROCSTAT_FILES       9       /* Procstat files data. */
+#define NT_PROCSTAT_VMMAP       10      /* Procstat vmmap data. */
+#define NT_PROCSTAT_GROUPS      11      /* Procstat groups data. */
+#define NT_PROCSTAT_UMASK       12      /* Procstat umask data. */
+#define NT_PROCSTAT_RLIMIT      13      /* Procstat rlimit data. */
+#define NT_PROCSTAT_OSREL       14      /* Procstat osreldate data. */
+#define NT_PROCSTAT_PSSTRINGS   15      /* Procstat ps_strings data. */
+#define NT_PROCSTAT_AUXV        16      /* Procstat auxv data. */
 
 /* FreeBSD kernels 12.0 and later include a copy of the
    'ptrace_lwpinfo' structure returned by the PT_LWPINFO ptrace
@@ -586,6 +595,29 @@  fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
 
   note_data = thread_args.note_data;
 
+  /* Auxillary vector.  */
+  gdb::optional<gdb::byte_vector> auxv =
+    target_read_alloc (current_top_target (), TARGET_OBJECT_AUXV, NULL);
+  if (auxv && !auxv->empty ())
+    {
+      size_t note_desc_size = sizeof (uint32_t) + auxv->size ();
+      char *note_desc = (char *)malloc (note_desc_size);
+      if (!note_desc)
+        return NULL;
+      uint32_t auxv_info_size = 8;
+      if (gdbarch_addr_bit (gdbarch) == 64)
+        auxv_info_size = 16;
+      memcpy (note_desc, &auxv_info_size, sizeof (uint32_t));
+      memcpy (note_desc + sizeof (uint32_t), auxv->data (), auxv->size ());
+      note_data = elfcore_write_note (obfd, note_data, note_size,
+                                      "FreeBSD", NT_PROCSTAT_AUXV,
+                                      note_desc, note_desc_size);
+      free(note_desc);
+
+      if (!note_data)
+        return NULL;
+    }
+
   return note_data;
 }