From: Simon Marchi Date: Wed, 21 Oct 2020 14:43:48 +0000 (-0400) Subject: gdb: make gdbarch_make_corefile_notes return a unique ptr X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c21f37a889dbf57077981970a1b6167a0dcb39af;p=binutils-gdb.git gdb: make gdbarch_make_corefile_notes return a unique ptr This patch starts by making the gdbarch_make_corefile_notes function return a gdb::unique_xmalloc_ptr 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. : Change type to unique pointer. : 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. : 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. : Change type to unique pointer. : Change type to bool. (linux_collect_thread_registers): Return void, adjust. (struct linux_corefile_thread_data): Add constructor. : Change type to unique pointer. (linux_corefile_thread): Adjust. (linux_make_corefile_notes): Return unique pointer, adjust. Change-Id: I1e03476bb47b87c6acb3e12204d193f38cc4e02b --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1ea67804180..89dff4bbd89 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,30 @@ +2020-10-21 Simon Marchi + + * 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. + : Change type to unique pointer. + : 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. + : 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. + : Change type to unique pointer. + : Change type to bool. + (linux_collect_thread_registers): Return void, adjust. + (struct linux_corefile_thread_data): Add constructor. + : Change type to unique pointer. + (linux_corefile_thread): Adjust. + (linux_make_corefile_notes): Return unique pointer, adjust. + 2020-10-20 Simon Marchi * gdbarch.sh (displaced_step_hw_singlestep): Return bool. diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c index a462e4d4ee2..f7ee35b39d4 100644 --- a/gdb/fbsd-tdep.c +++ b/gdb/fbsd-tdep.c @@ -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 ¬e_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 ¬e_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 ¬e_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 ¬e_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 ¬e_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 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 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 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; } diff --git a/gdb/gcore.c b/gdb/gcore.c index db82eaac3dd..4a305ba95a8 100644 --- a/gdb/gcore.c +++ b/gdb/gcore.c @@ -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, ¬e_size)); else - note_data.reset (gdbarch_make_corefile_notes (target_gdbarch (), obfd, - ¬e_size)); + note_data = gdbarch_make_corefile_notes (target_gdbarch (), obfd, + ¬e_size); if (note_data == NULL || note_size == 0) error (_("Target does not support core file generation.")); diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 3a55820f72c..285d9f9b46d 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -3700,7 +3700,7 @@ gdbarch_make_corefile_notes_p (struct gdbarch *gdbarch) return gdbarch->make_corefile_notes != NULL; } -char * +gdb::unique_xmalloc_ptr gdbarch_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) { gdb_assert (gdbarch != NULL); diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index d126dfcd6dd..ae65f290fc8 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -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 (gdbarch_make_corefile_notes_ftype) (struct gdbarch *gdbarch, bfd *obfd, int *note_size); +extern gdb::unique_xmalloc_ptr 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 */ diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 0b59ef05ff1..5f1e2f9d958 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -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;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 diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index 439f583a802..cce75474d7a 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -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 ¬e_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 ¬e_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 ¬e_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 ¬e_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 ¬e_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 ¬e_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 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 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; }