[v2] gdb: generate NT_PROCSTAT_AUXV in FreeBSD coredumps
Commit Message
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
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.
@@ -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;
}