From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id CBT3HlrsF2BXBQAAWB0awg (envelope-from ) for ; Mon, 01 Feb 2021 06:56:10 -0500 Received: by simark.ca (Postfix, from userid 112) id 7C5EF1EF80; Mon, 1 Feb 2021 06:56:10 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-1.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 7A7131E590 for ; Mon, 1 Feb 2021 06:56:08 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E973D385801D; Mon, 1 Feb 2021 11:56:07 +0000 (GMT) Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by sourceware.org (Postfix) with ESMTPS id F3D42383F840 for ; Mon, 1 Feb 2021 11:56:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org F3D42383F840 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=andrew.burgess@embecosm.com Received: by mail-wr1-x42f.google.com with SMTP id m13so16261664wro.12 for ; Mon, 01 Feb 2021 03:56:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=3XxHBQ4CFbyV5fS7eUzrilXHSzatHj+kkiF5njlJHOY=; b=KG86nnFTW4B851NpJIhHTTX8EErPbBiQ/6gtpcRBgrs/QoXmiaGaCH3Pqm/AY1N6SR XsHP1TvXPagwuyMXHIfMCqHWBs1y49gkSr+1YvBpoXMaOTvCGE1zmUJshpK7Ua4j5M75 ezzsxMDHc/njqXQ4Ks4q8Q2qktC1rMAp3BmE7e8LigEfEM2ahasjTvyrk668zotgv8EP dnfrU2zOaxPXzpfOFJfEgS5PO9DUUtTDpJAx9P/2tD8a8YxaOgJevLZZ7hNCU+32c3kU WmY2mUaRzCIjOxdllbHSZv2nLf3HzFdJnE+l1nGmyfk0AGcQy05RlBpf1t8ICOGvHbbW 6S7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=3XxHBQ4CFbyV5fS7eUzrilXHSzatHj+kkiF5njlJHOY=; b=lRzWzwleLwR516jseUjSAElFb95SHemlLyhRGt2V8n8l8IUkcVx2hHXZWmMZnSg4UE INlctFGcrojp5AkMN5ncbQ0RtHazygg1YHLxsMHfn86OzrPvwEeuV0GgiEbAMpPHmXbg 15mjJjv/aLL4opxXoQA6QqzzbvsaqZ344ftQX7j2kt1nsBUmNOPktyr4qsz+CglziRJJ IUXmcng/FmQQgMA1MGXo0U6rqQLhosALcPX3Dp24AlA7GeyPFKg0ZMH+zcFo3e9yWZt0 slSCVtDoGQH08sFSlVt8+N96MfscP9wHQJkBfwaf/pig2nfJmMqJkMQs6AcaAgBNrAej ZO4g== X-Gm-Message-State: AOAM531QLyFR8enwceTgon4GnzzMV2z8nEz/5/UKOf/JPif1ONLEQZMw 2g5RoicJWSXCi8wK80IzIFgCEcLOrA2NeA== X-Google-Smtp-Source: ABdhPJx7XibsK/Fe54uBMU+DUOsZrOAJ1FHL0eyTPN6NXaME35xvjoowVI+w0p/z1UQqMmojpY3j1A== X-Received: by 2002:adf:e48b:: with SMTP id i11mr17875582wrm.406.1612180562619; Mon, 01 Feb 2021 03:56:02 -0800 (PST) Received: from localhost (host86-191-239-31.range86-191.btcentralplus.com. [86.191.239.31]) by smtp.gmail.com with ESMTPSA id z1sm21382528wrp.62.2021.02.01.03.56.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Feb 2021 03:56:01 -0800 (PST) Date: Mon, 1 Feb 2021 11:56:00 +0000 From: Andrew Burgess To: gdb-patches@sourceware.org, binutils@sourceware.org Subject: Re: [PATCHv2 1/9] gdb: unify parts of the Linux and FreeBSD core dumping code Message-ID: <20210201115600.GS265215@embecosm.com> References: <1d4520c35b2aa9c7eadf015ac6af4dd955253660.1611172468.git.andrew.burgess@embecosm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1d4520c35b2aa9c7eadf015ac6af4dd955253660.1611172468.git.andrew.burgess@embecosm.com> X-Operating-System: Linux/5.8.13-100.fc31.x86_64 (x86_64) X-Uptime: 11:55:15 up 54 days, 16:39, X-Editor: GNU Emacs [ http://www.gnu.org/software/emacs ] X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Fredrik Hederstierna Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" I have pushed this patch only so far as this is a nice clean up in its own right. Thanks, Andrew * Andrew Burgess [2021-01-20 20:23:07 +0000]: > While reviewing the Linux and FreeBSD core dumping code within GDB for > another patch series, I noticed that the code that collects the > registers for each thread and writes these into ELF note format is > basically identical between Linux and FreeBSD. > > This commit merges this code and moves it into the gcore.c file, > which seemed like the right place for generic writing a core file > code. > > The function find_signalled_thread is moved from linux-tdep.c despite > not being shared. A later commit will make use of this function. > > There are a couple of minor changes to the FreeBSD target after this > commit, but I believe that these are changes for the better: > > (1) For FreeBSD we always used to record the thread-id in the core file by > using ptid_t.lwp (). In contrast the Linux code did this: > > /* For remote targets the LWP may not be available, so use the TID. */ > long lwp = ptid.lwp (); > if (lwp == 0) > lwp = ptid.tid (); > > Both target now do this: > > /* The LWP is often not available for bare metal target, in which case > use the tid instead. */ > if (ptid.lwp_p ()) > lwp = ptid.lwp (); > else > lwp = ptid.tid (); > > Which is equivalent for Linux, but is a change for FreeBSD. I think > that all this means is that in some cases where GDB might have > previously recorded a thread-id of 0 for each thread, we might now get > something more useful. > > (2) When collecting the registers for Linux we collected into a zero > initialised buffer. By contrast on FreeBSD the buffer is left > uninitialised. In the new code the buffer is always zero initialised. > I suspect once the registers are copied into the buffer there's > probably no gaps left so this makes no difference, but if it does then > using zeros rather than random bits of GDB's memory is probably a good > thing. > > Otherwise, there should be no other user visible changes after this > commit. > > Tested this on x86-64/GNU-Linux and x86-64/FreeBSD-12.2 with no > regressions. > > gdb/ChangeLog: > > * Makefile.in (HFILES_NO_SRCDIR): Add corefile.h. > * gcore.c (struct gcore_collect_regset_section_cb_data): Moved > here from linux-tdep.c and given a new name. Minor cleanups. > (gcore_collect_regset_section_cb): Likewise. > (gcore_collect_thread_registers): Likewise. > (gcore_build_thread_register_notes): Likewise. > (gcore_find_signalled_thread): Likewise. > * gcore.h (gcore_build_thread_register_notes): Declare. > (gcore_find_signalled_thread): Declare. > * fbsd-tdep.c: Add 'gcore.h' include. > (struct fbsd_collect_regset_section_cb_data): Delete. > (fbsd_collect_regset_section_cb): Delete. > (fbsd_collect_thread_registers): Delete. > (struct fbsd_corefile_thread_data): Delete. > (fbsd_corefile_thread): Delete. > (fbsd_make_corefile_notes): Call > gcore_build_thread_register_notes instead of the now deleted > FreeBSD code. > * linux-tdep.c: Add 'gcore.h' include. > (struct linux_collect_regset_section_cb_data): Delete. > (linux_collect_regset_section_cb): Delete. > (linux_collect_thread_registers): Delete. > (linux_corefile_thread): Call > gcore_build_thread_register_notes. > (find_signalled_thread): Delete. > (linux_make_corefile_notes): Call gcore_find_signalled_thread. > --- > gdb/ChangeLog | 29 ++++++++++ > gdb/fbsd-tdep.c | 135 +++------------------------------------------ > gdb/gcore.c | 136 +++++++++++++++++++++++++++++++++++++++++++++ > gdb/gcore.h | 20 +++++++ > gdb/linux-tdep.c | 141 +++-------------------------------------------- > 5 files changed, 199 insertions(+), 262 deletions(-) > > diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c > index cc51e921ae2..edd3edc4220 100644 > --- a/gdb/fbsd-tdep.c > +++ b/gdb/fbsd-tdep.c > @@ -32,6 +32,7 @@ > > #include "elf-bfd.h" > #include "fbsd-tdep.h" > +#include "gcore.h" > > /* This enum is derived from FreeBSD's . */ > > @@ -583,129 +584,6 @@ find_signalled_thread (struct thread_info *info, void *data) > return 0; > } > > -/* Structure for passing information from > - fbsd_collect_thread_registers via an iterator to > - fbsd_collect_regset_section_cb. */ > - > -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; > - gdb::unique_xmalloc_ptr ¬e_data; > - int *note_size; > - unsigned long lwp; > - enum gdb_signal stop_signal; > - bool abort_iteration = false; > -}; > - > -static void > -fbsd_collect_regset_section_cb (const char *sect_name, int supply_size, > - int collect_size, const struct regset *regset, > - const char *human_name, void *cb_data) > -{ > - char *buf; > - struct fbsd_collect_regset_section_cb_data *data > - = (struct fbsd_collect_regset_section_cb_data *) cb_data; > - > - if (data->abort_iteration) > - return; > - > - gdb_assert (regset->collect_regset); > - > - buf = (char *) xmalloc (collect_size); > - regset->collect_regset (regset, data->regcache, -1, buf, collect_size); > - > - /* PRSTATUS still needs to be treated specially. */ > - if (strcmp (sect_name, ".reg") == 0) > - 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.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 = true; > -} > - > -/* Records the thread's register state for the corefile note > - section. */ > - > -static void > -fbsd_collect_thread_registers (const struct regcache *regcache, > - ptid_t ptid, bfd *obfd, > - gdb::unique_xmalloc_ptr ¬e_data, > - int *note_size, > - enum gdb_signal stop_signal) > -{ > - 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); > -} > - > -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; > - gdb::unique_xmalloc_ptr ¬e_data; > - int *note_size; > - enum gdb_signal stop_signal; > -}; > - > -/* Records the thread's register state for the corefile note > - section. */ > - > -static void > -fbsd_corefile_thread (struct thread_info *info, > - struct fbsd_corefile_thread_data *args) > -{ > - struct regcache *regcache; > - > - regcache = get_thread_arch_regcache (info->inf->process_target (), > - info->ptid, args->gdbarch); > - > - target_fetch_registers (regcache, -1); > - > - 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 > for the target object of type OBJECT. If STRUCTSIZE is non-zero, > the data is prefixed with a 32-bit integer size to match the format > @@ -782,16 +660,17 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) > signalled_thr = curr_thr; > } > > - fbsd_corefile_thread_data thread_args (gdbarch, obfd, note_data, note_size, > - signalled_thr->suspend.stop_signal); > - > - fbsd_corefile_thread (signalled_thr, &thread_args); > + gcore_build_thread_register_notes (gdbarch, signalled_thr, > + signalled_thr->suspend.stop_signal, > + obfd, ¬e_data, note_size); > for (thread_info *thr : current_inferior ()->non_exited_threads ()) > { > if (thr == signalled_thr) > continue; > > - fbsd_corefile_thread (thr, &thread_args); > + gcore_build_thread_register_notes (gdbarch, thr, > + signalled_thr->suspend.stop_signal, > + obfd, ¬e_data, note_size); > } > > /* Auxiliary vector. */ > diff --git a/gdb/gcore.c b/gdb/gcore.c > index 73ac6b09c70..d62aa3a7109 100644 > --- a/gdb/gcore.c > +++ b/gdb/gcore.c > @@ -579,6 +579,142 @@ gcore_memory_sections (bfd *obfd) > return 1; > } > > +/* Structure for passing information from GCORE_COLLECT_THREAD_REGISTERS > + via an iterator to GCORE_COLLECT_REGSET_SECTION_CB. */ > + > +struct gcore_collect_regset_section_cb_data > +{ > + gcore_collect_regset_section_cb_data (struct gdbarch *gdbarch, > + const struct regcache *regcache, > + bfd *obfd, ptid_t ptid, > + gdb_signal stop_signal, > + gdb::unique_xmalloc_ptr *note_data, > + int *note_size) > + > + : gdbarch (gdbarch), regcache (regcache), obfd (obfd), > + note_data (note_data), note_size (note_size), > + stop_signal (stop_signal) > + { > + /* The LWP is often not available for bare metal target, in which case > + use the tid instead. */ > + if (ptid.lwp_p ()) > + lwp = ptid.lwp (); > + else > + lwp = ptid.tid (); > + } > + > + struct gdbarch *gdbarch; > + const struct regcache *regcache; > + bfd *obfd; > + gdb::unique_xmalloc_ptr *note_data; > + int *note_size; > + unsigned long lwp; > + enum gdb_signal stop_signal; > + bool abort_iteration = false; > +}; > + > +/* Callback for ITERATE_OVER_REGSET_SECTIONS that records a single > + regset in the core file note section. */ > + > +static void > +gcore_collect_regset_section_cb (const char *sect_name, int supply_size, > + int collect_size, > + const struct regset *regset, > + const char *human_name, void *cb_data) > +{ > + struct gcore_collect_regset_section_cb_data *data > + = (struct gcore_collect_regset_section_cb_data *) cb_data; > + bool variable_size_section = (regset != NULL > + && regset->flags & REGSET_VARIABLE_SIZE); > + > + gdb_assert (variable_size_section || supply_size == collect_size); > + > + if (data->abort_iteration) > + return; > + > + gdb_assert (regset != nullptr && regset->collect_regset != nullptr); > + > + /* This is intentionally zero-initialized by using std::vector, so > + that any padding bytes in the core file will show as 0. */ > + std::vector buf (collect_size); > + > + regset->collect_regset (regset, data->regcache, -1, buf.data (), > + collect_size); > + > + /* PRSTATUS still needs to be treated specially. */ > + if (strcmp (sect_name, ".reg") == 0) > + 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->reset (elfcore_write_register_note > + (data->obfd, data->note_data->release (), > + data->note_size, sect_name, buf.data (), > + collect_size)); > + > + if (data->note_data == nullptr) > + data->abort_iteration = true; > +} > + > +/* Records the register state of thread PTID out of REGCACHE into the note > + buffer represented by *NOTE_DATA and NOTE_SIZE. OBFD is the bfd into > + which the core file is being created, and STOP_SIGNAL is the signal that > + cause thread PTID to stop. */ > + > +static void > +gcore_collect_thread_registers (const struct regcache *regcache, > + ptid_t ptid, bfd *obfd, > + gdb::unique_xmalloc_ptr *note_data, > + int *note_size, > + enum gdb_signal stop_signal) > +{ > + struct gdbarch *gdbarch = regcache->arch (); > + gcore_collect_regset_section_cb_data data (gdbarch, regcache, obfd, ptid, > + stop_signal, note_data, > + note_size); > + gdbarch_iterate_over_regset_sections (gdbarch, > + gcore_collect_regset_section_cb, > + &data, regcache); > +} > + > +/* See gcore.h. */ > + > +void > +gcore_build_thread_register_notes > + (struct gdbarch *gdbarch, struct thread_info *info, gdb_signal stop_signal, > + bfd *obfd, gdb::unique_xmalloc_ptr *note_data, int *note_size) > +{ > + struct regcache *regcache > + = get_thread_arch_regcache (info->inf->process_target (), > + info->ptid, gdbarch); > + target_fetch_registers (regcache, -1); > + gcore_collect_thread_registers (regcache, info->ptid, obfd, note_data, > + note_size, stop_signal); > +} > + > +/* See gcore.h. */ > + > +thread_info * > +gcore_find_signalled_thread () > +{ > + thread_info *curr_thr = inferior_thread (); > + if (curr_thr->state != THREAD_EXITED > + && curr_thr->suspend.stop_signal != GDB_SIGNAL_0) > + return curr_thr; > + > + for (thread_info *thr : current_inferior ()->non_exited_threads ()) > + if (thr->suspend.stop_signal != GDB_SIGNAL_0) > + return thr; > + > + /* Default to the current thread, unless it has exited. */ > + if (curr_thr->state != THREAD_EXITED) > + return curr_thr; > + > + return nullptr; > +} > + > void _initialize_gcore (); > void > _initialize_gcore () > diff --git a/gdb/gcore.h b/gdb/gcore.h > index af37ff39b41..ce60841c1a5 100644 > --- a/gdb/gcore.h > +++ b/gdb/gcore.h > @@ -21,6 +21,10 @@ > #define GCORE_H 1 > > #include "gdb_bfd.h" > +#include "gdbsupport/gdb_signals.h" > + > +struct gdbarch; > +struct thread_info; > > extern gdb_bfd_ref_ptr create_gcore_bfd (const char *filename); > extern void write_gcore_file (bfd *obfd); > @@ -28,4 +32,20 @@ extern int objfile_find_memory_regions (struct target_ops *self, > find_memory_region_ftype func, > void *obfd); > > +/* Add content to *NOTE_DATA (and update *NOTE_SIZE) to describe the > + registers of thread INFO. Report the thread as having stopped with > + STOP_SIGNAL. The core file is being written to OFD, and GDBARCH is the > + architecture for which the core file is being generated. */ > + > +extern void gcore_build_thread_register_notes > + (struct gdbarch *gdbarch, struct thread_info *info, gdb_signal stop_signal, > + bfd *obfd, gdb::unique_xmalloc_ptr *note_data, int *note_size); > + > +/* Find the signalled thread. In case there's more than one signalled > + thread, prefer the current thread, if it is signalled. If no thread was > + signalled, default to the current thread, unless it has exited, in which > + case return NULL. */ > + > +extern thread_info *gcore_find_signalled_thread (); > + > #endif /* GCORE_H */ > diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c > index 5b3b8874d11..de814fc6832 100644 > --- a/gdb/linux-tdep.c > +++ b/gdb/linux-tdep.c > @@ -39,6 +39,7 @@ > #include "gdb_regex.h" > #include "gdbsupport/enum-flags.h" > #include "gdbsupport/gdb_optional.h" > +#include "gcore.h" > > #include > > @@ -1599,104 +1600,6 @@ linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, > } > } > > -/* Structure for passing information from > - linux_collect_thread_registers via an iterator to > - linux_collect_regset_section_cb. */ > - > -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; > - gdb::unique_xmalloc_ptr ¬e_data; > - int *note_size; > - unsigned long lwp; > - enum gdb_signal stop_signal; > - bool abort_iteration = false; > -}; > - > -/* Callback for iterate_over_regset_sections that records a single > - regset in the corefile note section. */ > - > -static void > -linux_collect_regset_section_cb (const char *sect_name, int supply_size, > - int collect_size, const struct regset *regset, > - const char *human_name, void *cb_data) > -{ > - struct linux_collect_regset_section_cb_data *data > - = (struct linux_collect_regset_section_cb_data *) cb_data; > - bool variable_size_section = (regset != NULL > - && regset->flags & REGSET_VARIABLE_SIZE); > - > - if (!variable_size_section) > - gdb_assert (supply_size == collect_size); > - > - if (data->abort_iteration) > - return; > - > - gdb_assert (regset && regset->collect_regset); > - > - /* This is intentionally zero-initialized by using std::vector, so > - that any padding bytes in the core file will show as 0. */ > - std::vector buf (collect_size); > - > - regset->collect_regset (regset, data->regcache, -1, buf.data (), > - collect_size); > - > - /* PRSTATUS still needs to be treated specially. */ > - if (strcmp (sect_name, ".reg") == 0) > - 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.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 = true; > -} > - > -/* Records the thread's register state for the corefile note > - section. */ > - > -static void > -linux_collect_thread_registers (const struct regcache *regcache, > - ptid_t ptid, bfd *obfd, > - gdb::unique_xmalloc_ptr ¬e_data, > - int *note_size, > - enum gdb_signal stop_signal) > -{ > - struct gdbarch *gdbarch = regcache->arch (); > - > - /* For remote targets the LWP may not be available, so use the 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); > -} > - > /* Fetch the siginfo data for the specified thread, if it exists. If > there is no data, or we could not read it, return an empty > buffer. */ > @@ -1748,22 +1651,16 @@ static void > linux_corefile_thread (struct thread_info *info, > struct linux_corefile_thread_data *args) > { > - struct regcache *regcache; > - > - regcache = get_thread_arch_regcache (info->inf->process_target (), > - info->ptid, args->gdbarch); > - > - target_fetch_registers (regcache, -1); > - gdb::byte_vector siginfo_data = linux_get_siginfo_data (info, args->gdbarch); > - > - linux_collect_thread_registers (regcache, info->ptid, args->obfd, > - args->note_data, args->note_size, > - args->stop_signal); > + gcore_build_thread_register_notes (args->gdbarch, info, args->stop_signal, > + args->obfd, &args->note_data, > + args->note_size); > > /* Don't return anything if we got no register information above, > such a core file is useless. */ > if (args->note_data != NULL) > { > + gdb::byte_vector siginfo_data > + = linux_get_siginfo_data (info, args->gdbarch); > if (!siginfo_data.empty ()) > args->note_data.reset (elfcore_write_note (args->obfd, > args->note_data.release (), > @@ -1962,30 +1859,6 @@ linux_fill_prpsinfo (struct elf_internal_linux_prpsinfo *p) > return 1; > } > > -/* Find the signalled thread. In case there's more than one signalled > - thread, prefer the current thread, if it is signalled. If no > - thread was signalled, default to the current thread, unless it has > - exited, in which case return NULL. */ > - > -static thread_info * > -find_signalled_thread () > -{ > - thread_info *curr_thr = inferior_thread (); > - if (curr_thr->state != THREAD_EXITED > - && curr_thr->suspend.stop_signal != GDB_SIGNAL_0) > - return curr_thr; > - > - for (thread_info *thr : current_inferior ()->non_exited_threads ()) > - if (thr->suspend.stop_signal != GDB_SIGNAL_0) > - return thr; > - > - /* Default to the current thread, unless it has exited. */ > - if (curr_thr->state != THREAD_EXITED) > - return curr_thr; > - > - return nullptr; > -} > - > /* Build the note section for a corefile, and return it in a malloc > buffer. */ > > @@ -2023,7 +1896,7 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) > /* Like the kernel, prefer dumping the signalled thread first. > "First thread" is what tools use to infer the signalled > thread. */ > - thread_info *signalled_thr = find_signalled_thread (); > + thread_info *signalled_thr = gcore_find_signalled_thread (); > gdb_signal stop_signal; > if (signalled_thr != nullptr) > stop_signal = signalled_thr->suspend.stop_signal; > -- > 2.25.4 >