gdb: make gdbarch_make_corefile_notes return a unique ptr
authorSimon Marchi <simon.marchi@polymtl.ca>
Wed, 21 Oct 2020 14:43:48 +0000 (10:43 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Wed, 21 Oct 2020 14:43:48 +0000 (10:43 -0400)
This patch starts by making the gdbarch_make_corefile_notes function
return a gdb::unique_xmalloc_ptr<char> and takes care of the fallouts,
mostly in linux-tdep.c and fbsd-tdep.c.

The difficulty in these files is that they use the BFD API for writing
core files, where you pass in a pointer to a malloc-ed buffer (or NULL
in the beginning), it re-allocs it if needed, and returns you the
possibly updated pointer.  I therefore used this pattern everywhere:

  note_data.reset (elfcore_write_note (obfd, note_data.release (), ...)

This hands over the ownership of note_data to the BFD function for the
duration of the call, and then puts its back in note_data right after
the call.

gdb/ChangeLog:

* gdbarch.sh (make_corefile_notes): Return unique pointer.
* gdbarch.c: Re-generate.
* gdbarch.h: Re-generate.
* gcore.c (write_gcore_file_1): Adjust.
* fbsd-tdep.c (struct fbsd_collect_regset_section_cb_data): Add
constructor.
<note_data>: Change type to unique pointer.
<abort_iteration>: Change type to bool.
(fbsd_collect_regset_section_cb): Adjust to unique pointer.
(fbsd_collect_thread_registers): Return void, adjust.
(struct fbsd_corefile_thread_data): Add construtor.
<note_data>: Change type to unique pointer.
(fbsd_corefile_thread): Adjust.
(fbsd_make_corefile_notes): Return unique pointer, adjust.
* linux-tdep.c (linux_make_mappings_corefile_notes): Change type
to unique pointer, adjust.
(struct linux_collect_regset_section_cb_data): Add constructor.
<note_data>: Change type to unique pointer.
<abort_iteration>: Change type to bool.
(linux_collect_thread_registers): Return void, adjust.
(struct linux_corefile_thread_data): Add constructor.
<note_data>: Change type to unique pointer.
(linux_corefile_thread): Adjust.
(linux_make_corefile_notes): Return unique pointer, adjust.

Change-Id: I1e03476bb47b87c6acb3e12204d193f38cc4e02b

gdb/ChangeLog
gdb/fbsd-tdep.c
gdb/gcore.c
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/linux-tdep.c

index 1ea6780418074462d021256c27158e45e5a9529b..89dff4bbd89d186bffd02701281dc559dd9a2cb0 100644 (file)
@@ -1,3 +1,30 @@
+2020-10-21  Simon Marchi  <simon.marchi@polymtl.ca>
+
+       * gdbarch.sh (make_corefile_notes): Return unique pointer.
+       * gdbarch.c: Re-generate.
+       * gdbarch.h: Re-generate.
+       * gcore.c (write_gcore_file_1): Adjust.
+       * fbsd-tdep.c (struct fbsd_collect_regset_section_cb_data): Add
+       constructor.
+       <note_data>: Change type to unique pointer.
+       <abort_iteration>: Change type to bool.
+       (fbsd_collect_regset_section_cb): Adjust to unique pointer.
+       (fbsd_collect_thread_registers): Return void, adjust.
+       (struct fbsd_corefile_thread_data): Add construtor.
+       <note_data>: Change type to unique pointer.
+       (fbsd_corefile_thread): Adjust.
+       (fbsd_make_corefile_notes): Return unique pointer, adjust.
+       * linux-tdep.c (linux_make_mappings_corefile_notes): Change type
+       to unique pointer, adjust.
+       (struct linux_collect_regset_section_cb_data): Add constructor.
+       <note_data>: Change type to unique pointer.
+       <abort_iteration>: Change type to bool.
+       (linux_collect_thread_registers): Return void, adjust.
+       (struct linux_corefile_thread_data): Add constructor.
+       <note_data>: Change type to unique pointer.
+       (linux_corefile_thread): Adjust.
+       (linux_make_corefile_notes): Return unique pointer, adjust.
+
 2020-10-20  Simon Marchi  <simon.marchi@polymtl.ca>
 
        * gdbarch.sh (displaced_step_hw_singlestep): Return bool.
index a462e4d4ee2fc83c7703b21033318a75e2a86aa7..f7ee35b39d4808be8355fb485bcd461feedacf95 100644 (file)
@@ -589,13 +589,27 @@ find_signalled_thread (struct thread_info *info, void *data)
 
 struct fbsd_collect_regset_section_cb_data
 {
+  fbsd_collect_regset_section_cb_data (const struct regcache *regcache,
+                                      bfd *obfd,
+                                      gdb::unique_xmalloc_ptr<char> &note_data,
+                                      int *note_size,
+                                      unsigned long lwp,
+                                      gdb_signal stop_signal)
+    : regcache (regcache),
+      obfd (obfd),
+      note_data (note_data),
+      note_size (note_size),
+      lwp (lwp),
+      stop_signal (stop_signal)
+  {}
+
   const struct regcache *regcache;
   bfd *obfd;
-  char *note_data;
+  gdb::unique_xmalloc_ptr<char> &note_data;
   int *note_size;
   unsigned long lwp;
   enum gdb_signal stop_signal;
-  int abort_iteration;
+  bool abort_iteration = false;
 };
 
 static void
@@ -617,50 +631,58 @@ fbsd_collect_regset_section_cb (const char *sect_name, int supply_size,
 
   /* PRSTATUS still needs to be treated specially.  */
   if (strcmp (sect_name, ".reg") == 0)
-    data->note_data = (char *) elfcore_write_prstatus
-      (data->obfd, data->note_data, data->note_size, data->lwp,
-       gdb_signal_to_host (data->stop_signal), buf);
+    data->note_data.reset (elfcore_write_prstatus
+                            (data->obfd, data->note_data.release (),
+                             data->note_size, data->lwp,
+                             gdb_signal_to_host (data->stop_signal),
+                             buf));
   else
-    data->note_data = (char *) elfcore_write_register_note
-      (data->obfd, data->note_data, data->note_size,
-       sect_name, buf, collect_size);
+    data->note_data.reset (elfcore_write_register_note
+                            (data->obfd, data->note_data.release (),
+                             data->note_size, sect_name, buf,
+                             collect_size));
   xfree (buf);
 
   if (data->note_data == NULL)
-    data->abort_iteration = 1;
+    data->abort_iteration = true;
 }
 
 /* Records the thread's register state for the corefile note
    section.  */
 
-static char *
+static void
 fbsd_collect_thread_registers (const struct regcache *regcache,
                               ptid_t ptid, bfd *obfd,
-                              char *note_data, int *note_size,
+                              gdb::unique_xmalloc_ptr<char> &note_data,
+                              int *note_size,
                               enum gdb_signal stop_signal)
 {
-  struct gdbarch *gdbarch = regcache->arch ();
-  struct fbsd_collect_regset_section_cb_data data;
-
-  data.regcache = regcache;
-  data.obfd = obfd;
-  data.note_data = note_data;
-  data.note_size = note_size;
-  data.stop_signal = stop_signal;
-  data.abort_iteration = 0;
-  data.lwp = ptid.lwp ();
-
-  gdbarch_iterate_over_regset_sections (gdbarch,
+  fbsd_collect_regset_section_cb_data data (regcache, obfd, note_data,
+                                           note_size, ptid.lwp (),
+                                           stop_signal);
+
+  gdbarch_iterate_over_regset_sections (regcache->arch (),
                                        fbsd_collect_regset_section_cb,
                                        &data, regcache);
-  return data.note_data;
 }
 
 struct fbsd_corefile_thread_data
 {
+  fbsd_corefile_thread_data (struct gdbarch *gdbarch,
+                            bfd *obfd,
+                            gdb::unique_xmalloc_ptr<char> &note_data,
+                            int *note_size,
+                            gdb_signal stop_signal)
+    : gdbarch (gdbarch),
+      obfd (obfd),
+      note_data (note_data),
+      note_size (note_size),
+      stop_signal (stop_signal)
+  {}
+
   struct gdbarch *gdbarch;
   bfd *obfd;
-  char *note_data;
+  gdb::unique_xmalloc_ptr<char> &note_data;
   int *note_size;
   enum gdb_signal stop_signal;
 };
@@ -679,9 +701,9 @@ fbsd_corefile_thread (struct thread_info *info,
 
   target_fetch_registers (regcache, -1);
 
-  args->note_data = fbsd_collect_thread_registers
-    (regcache, info->ptid, args->obfd, args->note_data,
-     args->note_size, args->stop_signal);
+  fbsd_collect_thread_registers (regcache, info->ptid, args->obfd,
+                                args->note_data, args->note_size,
+                                args->stop_signal);
 }
 
 /* Return a byte_vector containing the contents of a core dump note
@@ -709,11 +731,10 @@ fbsd_make_note_desc (enum target_object object, uint32_t structsize)
 /* Create appropriate note sections for a corefile, returning them in
    allocated memory.  */
 
-static char *
+static gdb::unique_xmalloc_ptr<char>
 fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
 {
-  struct fbsd_corefile_thread_data thread_args;
-  char *note_data = NULL;
+  gdb::unique_xmalloc_ptr<char> note_data;
   Elf_Internal_Ehdr *i_ehdrp;
   struct thread_info *curr_thr, *signalled_thr;
 
@@ -732,8 +753,9 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
       if (infargs != NULL)
        psargs = psargs + " " + infargs;
 
-      note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
-                                         fname, psargs.c_str ());
+      note_data.reset (elfcore_write_prpsinfo (obfd, note_data.release (),
+                                              note_size, fname,
+                                              psargs.c_str ()));
     }
 
   /* Thread register information.  */
@@ -760,11 +782,8 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
        signalled_thr = curr_thr;
     }
 
-  thread_args.gdbarch = gdbarch;
-  thread_args.obfd = obfd;
-  thread_args.note_data = note_data;
-  thread_args.note_size = note_size;
-  thread_args.stop_signal = signalled_thr->suspend.stop_signal;
+  fbsd_corefile_thread_data thread_args (gdbarch, obfd, note_data, note_size,
+                                        signalled_thr->suspend.stop_signal);
 
   fbsd_corefile_thread (signalled_thr, &thread_args);
   for (thread_info *thr : current_inferior ()->non_exited_threads ())
@@ -775,17 +794,17 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
       fbsd_corefile_thread (thr, &thread_args);
     }
 
-  note_data = thread_args.note_data;
-
   /* Auxiliary vector.  */
   uint32_t structsize = gdbarch_ptr_bit (gdbarch) / 4; /* Elf_Auxinfo  */
   gdb::optional<gdb::byte_vector> note_desc =
     fbsd_make_note_desc (TARGET_OBJECT_AUXV, structsize);
   if (note_desc && !note_desc->empty ())
     {
-      note_data = elfcore_write_note (obfd, note_data, note_size, "FreeBSD",
-                                     NT_FREEBSD_PROCSTAT_AUXV,
-                                     note_desc->data (), note_desc->size ());
+      note_data.reset (elfcore_write_note (obfd, note_data.release (),
+                                          note_size, "FreeBSD",
+                                          NT_FREEBSD_PROCSTAT_AUXV,
+                                          note_desc->data (),
+                                          note_desc->size ()));
       if (!note_data)
        return NULL;
     }
@@ -794,9 +813,11 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
   note_desc = fbsd_make_note_desc (TARGET_OBJECT_FREEBSD_VMMAP, 0);
   if (note_desc && !note_desc->empty ())
     {
-      note_data = elfcore_write_note (obfd, note_data, note_size, "FreeBSD",
-                                     NT_FREEBSD_PROCSTAT_VMMAP,
-                                     note_desc->data (), note_desc->size ());
+      note_data.reset (elfcore_write_note (obfd, note_data.release (),
+                                          note_size, "FreeBSD",
+                                          NT_FREEBSD_PROCSTAT_VMMAP,
+                                          note_desc->data (),
+                                          note_desc->size ()));
       if (!note_data)
        return NULL;
     }
@@ -804,9 +825,11 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
   note_desc = fbsd_make_note_desc (TARGET_OBJECT_FREEBSD_PS_STRINGS, 0);
   if (note_desc && !note_desc->empty ())
     {
-      note_data = elfcore_write_note (obfd, note_data, note_size, "FreeBSD",
-                                     NT_FREEBSD_PROCSTAT_PSSTRINGS,
-                                     note_desc->data (), note_desc->size ());
+      note_data.reset (elfcore_write_note (obfd, note_data.release (),
+                                          note_size, "FreeBSD",
+                                          NT_FREEBSD_PROCSTAT_PSSTRINGS,
+                                          note_desc->data (),
+                                          note_desc->size ()));
       if (!note_data)
        return NULL;
     }
index db82eaac3dd8b3c06bc1a3770f65f5ddbc590ff5..4a305ba95a8478573d88aac0b9d6f33c80413735 100644 (file)
@@ -80,8 +80,8 @@ write_gcore_file_1 (bfd *obfd)
   if (!gdbarch_make_corefile_notes_p (target_gdbarch ()))
     note_data.reset (target_make_corefile_notes (obfd, &note_size));
   else
-    note_data.reset (gdbarch_make_corefile_notes (target_gdbarch (), obfd,
-                                                 &note_size));
+    note_data = gdbarch_make_corefile_notes (target_gdbarch (), obfd,
+                                            &note_size);
 
   if (note_data == NULL || note_size == 0)
     error (_("Target does not support core file generation."));
index 3a55820f72ce5b004c1c4810a06b14292bac577f..285d9f9b46d44beebe870dae77008741c602eb56 100644 (file)
@@ -3700,7 +3700,7 @@ gdbarch_make_corefile_notes_p (struct gdbarch *gdbarch)
   return gdbarch->make_corefile_notes != NULL;
 }
 
-char *
+gdb::unique_xmalloc_ptr<char>
 gdbarch_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
 {
   gdb_assert (gdbarch != NULL);
index d126dfcd6dda8f4711e4d9f32a99b93d6d087198..ae65f290fc847ab8e1029c161063945f7b020cea 100644 (file)
@@ -912,8 +912,8 @@ extern void set_gdbarch_iterate_over_regset_sections (struct gdbarch *gdbarch, g
 
 extern bool gdbarch_make_corefile_notes_p (struct gdbarch *gdbarch);
 
-typedef char * (gdbarch_make_corefile_notes_ftype) (struct gdbarch *gdbarch, bfd *obfd, int *note_size);
-extern char * gdbarch_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size);
+typedef gdb::unique_xmalloc_ptr<char> (gdbarch_make_corefile_notes_ftype) (struct gdbarch *gdbarch, bfd *obfd, int *note_size);
+extern gdb::unique_xmalloc_ptr<char> gdbarch_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size);
 extern void set_gdbarch_make_corefile_notes (struct gdbarch *gdbarch, gdbarch_make_corefile_notes_ftype *make_corefile_notes);
 
 /* Find core file memory regions */
index 0b59ef05ff17ad42edff80ed3a0bc126c7f4b792..5f1e2f9d9583c202d334b82dac7b2fddedc92ea2 100755 (executable)
@@ -715,7 +715,7 @@ F;CORE_ADDR;fetch_pointer_argument;struct frame_info *frame, int argi, struct ty
 M;void;iterate_over_regset_sections;iterate_over_regset_sections_cb *cb, void *cb_data, const struct regcache *regcache;cb, cb_data, regcache
 
 # Create core file notes
-M;char *;make_corefile_notes;bfd *obfd, int *note_size;obfd, note_size
+M;gdb::unique_xmalloc_ptr<char>;make_corefile_notes;bfd *obfd, int *note_size;obfd, note_size
 
 # Find core file memory regions
 M;int;find_memory_regions;find_memory_region_ftype func, void *data;func, data
index 439f583a8027ce6c28568196da47a6963042e4e6..cce75474d7a95b0ffff417d15147e6d91486b981 100644 (file)
@@ -1548,12 +1548,12 @@ linux_make_mappings_callback (ULONGEST vaddr, ULONGEST size,
 
 /* Write the file mapping data to the core file, if possible.  OBFD is
    the output BFD.  NOTE_DATA is the current note data, and NOTE_SIZE
-   is a pointer to the note size.  Returns the new NOTE_DATA and
-   updates NOTE_SIZE.  */
+   is a pointer to the note size.  Updates NOTE_DATA and NOTE_SIZE.  */
 
-static char *
+static void
 linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd,
-                                   char *note_data, int *note_size)
+                                   gdb::unique_xmalloc_ptr<char> &note_data,
+                                   int *note_size)
 {
   struct linux_make_mappings_data mapping_data;
   struct type *long_type
@@ -1590,13 +1590,12 @@ linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd,
       obstack_grow (&data_obstack, obstack_base (&filename_obstack),
                    size);
 
-      note_data = elfcore_write_note (obfd, note_data, note_size,
-                                     "CORE", NT_FILE,
-                                     obstack_base (&data_obstack),
-                                     obstack_object_size (&data_obstack));
+      note_data.reset (elfcore_write_note
+                        (obfd, note_data.release (),
+                         note_size, "CORE", NT_FILE,
+                         obstack_base (&data_obstack),
+                         obstack_object_size (&data_obstack)));
     }
-
-  return note_data;
 }
 
 /* Structure for passing information from
@@ -1605,14 +1604,26 @@ linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd,
 
 struct linux_collect_regset_section_cb_data
 {
+  linux_collect_regset_section_cb_data (struct gdbarch *gdbarch,
+                                       const struct regcache *regcache,
+                                       bfd *obfd,
+                                       gdb::unique_xmalloc_ptr<char> &note_data,
+                                       int *note_size,
+                                       unsigned long lwp,
+                                       gdb_signal stop_signal)
+    : gdbarch (gdbarch), regcache (regcache), obfd (obfd),
+      note_data (note_data), note_size (note_size), lwp (lwp),
+      stop_signal (stop_signal)
+  {}
+
   struct gdbarch *gdbarch;
   const struct regcache *regcache;
   bfd *obfd;
-  char *note_data;
+  gdb::unique_xmalloc_ptr<char> &note_data;
   int *note_size;
   unsigned long lwp;
   enum gdb_signal stop_signal;
-  int abort_iteration;
+  bool abort_iteration = false;
 };
 
 /* Callback for iterate_over_regset_sections that records a single
@@ -1645,47 +1656,44 @@ linux_collect_regset_section_cb (const char *sect_name, int supply_size,
 
   /* PRSTATUS still needs to be treated specially.  */
   if (strcmp (sect_name, ".reg") == 0)
-    data->note_data = (char *) elfcore_write_prstatus
-      (data->obfd, data->note_data, data->note_size, data->lwp,
-       gdb_signal_to_host (data->stop_signal), buf.data ());
+    data->note_data.reset (elfcore_write_prstatus
+                            (data->obfd, data->note_data.release (),
+                             data->note_size, data->lwp,
+                             gdb_signal_to_host (data->stop_signal),
+                             buf.data ()));
   else
-    data->note_data = (char *) elfcore_write_register_note
-      (data->obfd, data->note_data, data->note_size,
-       sect_name, buf.data (), collect_size);
+    data->note_data.reset (elfcore_write_register_note
+                          (data->obfd, data->note_data.release (),
+                           data->note_size, sect_name, buf.data (),
+                           collect_size));
 
   if (data->note_data == NULL)
-    data->abort_iteration = 1;
+    data->abort_iteration = true;
 }
 
 /* Records the thread's register state for the corefile note
    section.  */
 
-static char *
+static void
 linux_collect_thread_registers (const struct regcache *regcache,
                                ptid_t ptid, bfd *obfd,
-                               char *note_data, int *note_size,
+                               gdb::unique_xmalloc_ptr<char> &note_data,
+                               int *note_size,
                                enum gdb_signal stop_signal)
 {
   struct gdbarch *gdbarch = regcache->arch ();
-  struct linux_collect_regset_section_cb_data data;
-
-  data.gdbarch = gdbarch;
-  data.regcache = regcache;
-  data.obfd = obfd;
-  data.note_data = note_data;
-  data.note_size = note_size;
-  data.stop_signal = stop_signal;
-  data.abort_iteration = 0;
 
   /* For remote targets the LWP may not be available, so use the TID.  */
-  data.lwp = ptid.lwp ();
-  if (!data.lwp)
-    data.lwp = ptid.tid ();
+  long lwp = ptid.lwp ();
+  if (lwp == 0)
+    lwp = ptid.tid ();
+
+  linux_collect_regset_section_cb_data data (gdbarch, regcache, obfd, note_data,
+                                            note_size, lwp, stop_signal);
 
   gdbarch_iterate_over_regset_sections (gdbarch,
                                        linux_collect_regset_section_cb,
                                        &data, regcache);
-  return data.note_data;
 }
 
 /* Fetch the siginfo data for the specified thread, if it exists.  If
@@ -1718,9 +1726,16 @@ linux_get_siginfo_data (thread_info *thread, struct gdbarch *gdbarch)
 
 struct linux_corefile_thread_data
 {
+  linux_corefile_thread_data (struct gdbarch *gdbarch, bfd *obfd,
+                             gdb::unique_xmalloc_ptr<char> &note_data,
+                             int *note_size, gdb_signal stop_signal)
+    : gdbarch (gdbarch), obfd (obfd), note_data (note_data),
+      note_size (note_size), stop_signal (stop_signal)
+  {}
+
   struct gdbarch *gdbarch;
   bfd *obfd;
-  char *note_data;
+  gdb::unique_xmalloc_ptr<char> &note_data;
   int *note_size;
   enum gdb_signal stop_signal;
 };
@@ -1740,20 +1755,22 @@ linux_corefile_thread (struct thread_info *info,
   target_fetch_registers (regcache, -1);
   gdb::byte_vector siginfo_data = linux_get_siginfo_data (info, args->gdbarch);
 
-  args->note_data = linux_collect_thread_registers
-    (regcache, info->ptid, args->obfd, args->note_data,
-     args->note_size, args->stop_signal);
+  linux_collect_thread_registers (regcache, info->ptid, args->obfd,
+                                 args->note_data, args->note_size,
+                                 args->stop_signal);
 
   /* Don't return anything if we got no register information above,
      such a core file is useless.  */
   if (args->note_data != NULL)
-    if (!siginfo_data.empty ())
-      args->note_data = elfcore_write_note (args->obfd,
-                                           args->note_data,
-                                           args->note_size,
-                                           "CORE", NT_SIGINFO,
-                                           siginfo_data.data (),
-                                           siginfo_data.size ());
+    {
+      if (!siginfo_data.empty ())
+       args->note_data.reset (elfcore_write_note (args->obfd,
+                                                  args->note_data.release (),
+                                                  args->note_size,
+                                                  "CORE", NT_SIGINFO,
+                                                  siginfo_data.data (),
+                                                  siginfo_data.size ()));
+    }
 }
 
 /* Fill the PRPSINFO structure with information about the process being
@@ -1971,12 +1988,11 @@ find_signalled_thread ()
 /* Build the note section for a corefile, and return it in a malloc
    buffer.  */
 
-static char *
+static gdb::unique_xmalloc_ptr<char>
 linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
 {
-  struct linux_corefile_thread_data thread_args;
   struct elf_internal_linux_prpsinfo prpsinfo;
-  char *note_data = NULL;
+  gdb::unique_xmalloc_ptr<char> note_data;
 
   if (! gdbarch_iterate_over_regset_sections_p (gdbarch))
     return NULL;
@@ -1984,13 +2000,13 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
   if (linux_fill_prpsinfo (&prpsinfo))
     {
       if (gdbarch_ptr_bit (gdbarch) == 64)
-       note_data = elfcore_write_linux_prpsinfo64 (obfd,
-                                                   note_data, note_size,
-                                                   &prpsinfo);
+       note_data.reset (elfcore_write_linux_prpsinfo64 (obfd,
+                                                        note_data.release (),
+                                                        note_size, &prpsinfo));
       else
-       note_data = elfcore_write_linux_prpsinfo32 (obfd,
-                                                   note_data, note_size,
-                                                   &prpsinfo);
+       note_data.reset (elfcore_write_linux_prpsinfo32 (obfd,
+                                                        note_data.release (),
+                                                        note_size, &prpsinfo));
     }
 
   /* Thread register information.  */
@@ -2007,15 +2023,14 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
      "First thread" is what tools use to infer the signalled
      thread.  */
   thread_info *signalled_thr = find_signalled_thread ();
-
-  thread_args.gdbarch = gdbarch;
-  thread_args.obfd = obfd;
-  thread_args.note_data = note_data;
-  thread_args.note_size = note_size;
+  gdb_signal stop_signal;
   if (signalled_thr != nullptr)
-    thread_args.stop_signal = signalled_thr->suspend.stop_signal;
+    stop_signal = signalled_thr->suspend.stop_signal;
   else
-    thread_args.stop_signal = GDB_SIGNAL_0;
+    stop_signal = GDB_SIGNAL_0;
+
+  linux_corefile_thread_data thread_args (gdbarch, obfd, note_data, note_size,
+                                         stop_signal);
 
   if (signalled_thr != nullptr)
     linux_corefile_thread (signalled_thr, &thread_args);
@@ -2027,7 +2042,6 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
       linux_corefile_thread (thr, &thread_args);
     }
 
-  note_data = thread_args.note_data;
   if (!note_data)
     return NULL;
 
@@ -2036,17 +2050,16 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
     target_read_alloc (current_top_target (), TARGET_OBJECT_AUXV, NULL);
   if (auxv && !auxv->empty ())
     {
-      note_data = elfcore_write_note (obfd, note_data, note_size,
-                                     "CORE", NT_AUXV, auxv->data (),
-                                     auxv->size ());
+      note_data.reset (elfcore_write_note (obfd, note_data.release (),
+                                          note_size, "CORE", NT_AUXV,
+                                          auxv->data (), auxv->size ()));
 
       if (!note_data)
        return NULL;
     }
 
   /* File mappings.  */
-  note_data = linux_make_mappings_corefile_notes (gdbarch, obfd,
-                                                 note_data, note_size);
+  linux_make_mappings_corefile_notes (gdbarch, obfd, note_data, note_size);
 
   return note_data;
 }