From patchwork Tue Aug 21 14:45:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Ser X-Patchwork-Id: 29000 Received: (qmail 54404 invoked by alias); 21 Aug 2018 14:45:49 -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 53964 invoked by uid 89); 21 Aug 2018 14:45:26 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-27.1 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=ser, H*F:U*contact, H*R:U*contact, Possible X-HELO: mail4.protonmail.ch Received: from mail4.protonmail.ch (HELO mail4.protonmail.ch) (185.70.40.27) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 21 Aug 2018 14:45:17 +0000 Date: Tue, 21 Aug 2018 14:45:09 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=emersion.fr; s=protonmail; t=1534862712; bh=nVBaoqVCJZ5duzuOQxTsQa267LHOCOS54pGZbeabv4c=; h=Date:To:From:Cc:Reply-To:Subject:In-Reply-To:References: Feedback-ID:From; b=zmFnMcFRZfmgmqQeKEmNL02ei25g9sKDOb4veZoZ5QBEFSRu1opdLhjJ6zxNhC6A8 WX9hEIZEHKfKuglNAKts5jeWOVFN5+fegZtUCo42GoCSwTp4PgO6YMF+KGkdtPvqZy yq/E/77S2SoLxtNKcvORJwjcPbnRmJHb+BB0E7xY= To: gdb-patches@sourceware.org From: Simon Ser Cc: Simon Ser , jhb@FreeBSD.org Reply-To: Simon Ser Subject: [PATCH v3] Generate NT_PROCSTAT_{AUXV, VMMAP, PS_STRINGS} in FreeBSD coredumps Message-ID: In-Reply-To: <_LRTDYZchE3m5uYvETytJBLgsrWRhqIDAXHnzDsU6kJBhItMetbpfxGe8OJD9a4K4b9brDxF9YvXWOzdDfTRBRfrZI-4XLl8mWwlrEpqmm0=@emersion.fr> 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, file mappings are stored in a NT_PROCSTAT_VMMAP and both are prefixed with the struct size. 2018-08-21 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 v2 to v3: - Remove constants, prepend struct size for FreeBSD-specific objects - Use gdbarch_ptr_bit instead of gdbarch_addr_bit - Fixed typo This addresses all of John's comments except the VMMAP packed one. John, you said coredumps use the unpacked format, but looking at the `gcore` utility source code (in usr.bin/gcore/elfcore.c) I believe it uses the packed format for coredumps. It also makes more sense to me to use the packed format for coredumps because it allows us not to store PATH_MAX zeros for each entry. I may be wrong though, let me know what you think. gdb/fbsd-nat.c | 50 ++++++++++++++++++++++++++++++++++++++++++ gdb/fbsd-tdep.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ gdb/target.h | 4 ++++ 3 files changed, 112 insertions(+) diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c index 115deac0..7cd325e4 100644 --- a/gdb/fbsd-nat.c +++ b/gdb/fbsd-nat.c @@ -751,6 +751,56 @@ 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; + + buflen = sizeof (struct_size) + offset + len; + buf_storage.resize (buflen); + buf = buf_storage.data (); + + memcpy (buf, &struct_size, sizeof (struct_size)); + + if (sysctl (mib, 4, buf + sizeof (struct_size), &buflen, NULL, 0) == 0) + { + buflen += sizeof (struct_size); + if (buflen > offset) + { + buflen -= offset; + memcpy (readbuf, buf + offset, buflen); + } + else + buflen = 0; + *xfered_len = buflen; + return (buflen == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK; + } + return TARGET_XFER_E_IO; + } 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..659e64b6 100644 --- a/gdb/fbsd-tdep.c +++ b/gdb/fbsd-tdep.c @@ -25,6 +25,9 @@ #include "regset.h" #include "gdbthread.h" #include "xml-syscall.h" +#include +#include +#include #include "elf-bfd.h" #include "fbsd-tdep.h" @@ -512,6 +515,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 +606,44 @@ 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; + } + + /* File 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..83f1172c 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 file mappings */ + TARGET_OBJECT_FREEBSD_VMMAP, + /* FreeBSD process strings */ + TARGET_OBJECT_FREEBSD_PS_STRINGS, /* Possible future objects: TARGET_OBJECT_FILE, ... */ };