From patchwork Thu Aug 23 17:10:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Ser X-Patchwork-Id: 29028 Received: (qmail 19673 invoked by alias); 23 Aug 2018 17:11:10 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 19370 invoked by uid 89); 23 Aug 2018 17:11:10 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-27.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail1.protonmail.ch Received: from mail1.protonmail.ch (HELO mail1.protonmail.ch) (185.70.40.18) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 23 Aug 2018 17:11:08 +0000 Date: Thu, 23 Aug 2018 17:10:55 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=emersion.fr; s=protonmail; t=1535044261; bh=quzTmWnu86VuiF2x78rwar5fpkXl3qn3u7yvAe5SNVI=; h=Date:To:From:Cc:Reply-To:Subject:In-Reply-To:References: Feedback-ID:From; b=gkcd7VoenXZ3JgMwG778eS/ogbIS+DIgyGM7Cz6mI9iFKawGmfoBU9NJ2fWvZic0i pn3uY1QH2cSwY5eqXR/pkKcD1KDq+5eA9ma7xTOYDcmd3A0FLbn3VUfjYFKM7e/luY M6yYdtCWi4Wj+Kxe63BuQcuiQ6mvycufYoDF4XmQ= To: gdb-patches@sourceware.org From: Simon Ser Cc: Simon Ser , John Baldwin Reply-To: Simon Ser Subject: [PATCH v5] Generate NT_PROCSTAT_{AUXV, VMMAP, PS_STRINGS} in FreeBSD coredumps Message-ID: In-Reply-To: References: <_LRTDYZchE3m5uYvETytJBLgsrWRhqIDAXHnzDsU6kJBhItMetbpfxGe8OJD9a4K4b9brDxF9YvXWOzdDfTRBRfrZI-4XLl8mWwlrEpqmm0=@emersion.fr> MIME-Version: 1.0 gcore generates NT_AUXV and NT_FILE notes for Linux targets. On FreeBSD auxv is stored in a NT_PROCSTAT_AUXV section, virtual memory mappings are stored in a NT_PROCSTAT_VMMAP and both are prefixed with the struct size. 2018-08-23 Simon Ser * target.h (enum target_object): add FreeBSD-specific TARGET_OBJECT_FREEBSD_VMMAP and TARGET_OBJECT_FREEBSD_PS_STRINGS * fbsd-nat.c (fbsd_nat_target::xfer_partial): add support for TARGET_OBJECT_FREEBSD_VMMAP and TARGET_OBJECT_FREEBSD_PS_STRINGS * fbsd-tdep.c (fbsd_make_corefile_notes): write NT_PROCSTAT_AUXV, NT_PROCSTAT_VMMAP and NT_PROCSTAT_PS_STRINGS notes --- Changes from v4 to v5: - Fixed buflen too large before sysctl gdb/fbsd-nat.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ gdb/fbsd-tdep.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ gdb/target.h | 4 ++++ 3 files changed, 113 insertions(+) diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c index 115deac0..3c1904a1 100644 --- a/gdb/fbsd-nat.c +++ b/gdb/fbsd-nat.c @@ -751,6 +751,61 @@ fbsd_nat_target::xfer_partial (enum target_object object, } return TARGET_XFER_E_IO; } + case TARGET_OBJECT_FREEBSD_VMMAP: + case TARGET_OBJECT_FREEBSD_PS_STRINGS: + { + gdb::byte_vector buf_storage; + gdb_byte *buf; + size_t buflen; + int mib[4]; + + int proc_target; + uint32_t struct_size; + switch (object) + { + case TARGET_OBJECT_FREEBSD_VMMAP: + proc_target = KERN_PROC_VMMAP; + struct_size = sizeof (struct kinfo_vmentry); + break; + case TARGET_OBJECT_FREEBSD_PS_STRINGS: + proc_target = KERN_PROC_PS_STRINGS; + struct_size = sizeof (void *); + break; + } + + if (writebuf != NULL) + return TARGET_XFER_E_IO; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = proc_target; + mib[3] = pid; + + if (sysctl (mib, 4, NULL, &buflen, NULL, 0) != 0) + return TARGET_XFER_E_IO; + buflen += sizeof (struct_size); + + if (offset >= buflen) + { + *xfered_len = 0; + return TARGET_XFER_EOF; + } + + buf_storage.resize (buflen); + buf = buf_storage.data (); + + memcpy (buf, &struct_size, sizeof (struct_size)); + buflen -= sizeof (struct_size); + if (sysctl (mib, 4, buf + sizeof (struct_size), &buflen, NULL, 0) != 0) + return TARGET_XFER_E_IO; + buflen += sizeof (struct_size); + + if (offset + len > buflen) + len = buflen - offset; + memcpy (readbuf, buf + offset, len); + *xfered_len = len; + return TARGET_XFER_OK; + } default: return inf_ptrace_target::xfer_partial (object, annex, readbuf, writebuf, offset, diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c index 9cea0098..9242c244 100644 --- a/gdb/fbsd-tdep.c +++ b/gdb/fbsd-tdep.c @@ -512,6 +512,23 @@ fbsd_corefile_thread (struct thread_info *info, args->note_size, args->stop_signal); } +static gdb::optional +fbsd_make_note_desc (enum target_object object, uint32_t structsize) +{ + gdb::optional buf = + target_read_alloc (current_top_target (), object, NULL); + if (!buf || buf->empty ()) + return {}; + + if (structsize == 0) + return buf; + + gdb::byte_vector desc (sizeof (structsize) + buf->size ()); + memcpy (desc.data (), &structsize, sizeof (structsize)); + memcpy (desc.data () + sizeof (structsize), buf->data (), buf->size ()); + return desc; +} + /* Create appropriate note sections for a corefile, returning them in allocated memory. */ @@ -586,6 +603,43 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) note_data = thread_args.note_data; + pid_t pid = inferior_ptid.pid (); + + /* 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 ()); + if (!note_data) + return NULL; + } + + /* Virtual memory mappings */ + 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 ()); + if (!note_data) + return NULL; + } + + 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 ()); + if (!note_data) + return NULL; + } + return note_data; } diff --git a/gdb/target.h b/gdb/target.h index 18c4a84c..c584af54 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -203,6 +203,10 @@ enum target_object of the process ID of the process in question, in hexadecimal format. */ TARGET_OBJECT_EXEC_FILE, + /* FreeBSD virtual memory mappings */ + TARGET_OBJECT_FREEBSD_VMMAP, + /* FreeBSD process strings */ + TARGET_OBJECT_FREEBSD_PS_STRINGS, /* Possible future objects: TARGET_OBJECT_FILE, ... */ };