From nobody Thu May 12 22:56:37 2022 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id DF37D1AE5086; Thu, 12 May 2022 22:56:38 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4KznFy40rrz3GbR; Thu, 12 May 2022 22:56:38 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1652396198; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=HTCWVoZ+mmCh5ht+NoxLZU5YPQrJPr6jQT9uAZ+OTHI=; b=c0GvSucB8H/bgS7ul0NN4JhLWoKnYKLE+bJbC4f7znpUrp1zJBOfwLsOI0joJ9ycYz3iAh RudOG36FQjX+4InAsia2XYUDkNiE8y9FUwrH4BjyLIXgcb3COL3eCMBp/K+tea9jir5eit QNg9YPyuXUJPkUvttdPLpH9LDppvOPHXm78fFiYWhwVJTld4APRA1SrmCwgN97T7l5GBsC lil/4yduUMnfqxZ6idXqfIwk+N6BvBJPYRtcNTNo/OptebETTbJmU7qFNG90uLOV0HVJle 0Q7HqCZCE0UQyggEE0wOHPjy6GTD4+N4/Y+Nk+bb2Zvid8o2El2S2HhCOjPRAQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id F095816FDD; Thu, 12 May 2022 22:56:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 24CMubx3020744; Thu, 12 May 2022 22:56:37 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 24CMubbu020743; Thu, 12 May 2022 22:56:37 GMT (envelope-from git) Date: Thu, 12 May 2022 22:56:37 GMT Message-Id: <202205122256.24CMubbu020743@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: John Baldwin Subject: git: 6c2ea7f890b1 - stable/13 - gcore: Use PT_GETREGSET to fetch NT_PRSTATUS and NT_FPREGSET. List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jhb X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 6c2ea7f890b135ff393322d40e4600b3910c9890 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1652396198; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=HTCWVoZ+mmCh5ht+NoxLZU5YPQrJPr6jQT9uAZ+OTHI=; b=QhPqs58VjeF/ydbz+wF2I3ETnFB6w/2OSUs95PCJ5J1Edg3H8rdQ0TIxaqIIFLcikTXCk5 mRIBxho6cT8YznGA0tTlydgWPzJIlZlGduizB40FS10nTl7Y1mPUUy70vWDJ740Ff7Bkml laGmKV/exJ3Q+s9/0eoOTGR5x9Gh/YZXDdr18rTh/l14Fcb2uoAFv0loy/UuualMSCng8i 9LMO7oQ+uT3k+4ts47Y/zaHfpHOXVb1dw4Dn9djpNzQ4CZejtqh1clbp7z4tqjMKMT/nTc KcfaT/5CzPjDS7Y9xYDXF4e1fTCaqAHU2pm/jmi9U+iHSWkZ/thmHb3uOoAc3A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1652396198; a=rsa-sha256; cv=none; b=Pf6nfT7VzBCzAjGtV4DTHWC51rK71z83hIq+b59NJBxXmQgjmaWA26yQE7LJySoOFT4SWa RDorxWBVAVhEdwrPNKPEtl0lwebif1cDSR0ka1KeAvsCUGt9rQf81tMiacDgv95CILzTLv gjB5gcxgz5+6b8RzxtmxY09w3p5QsPX92DD1m7g/TSUgfXPitjauacDlDzwISBU7NmPcxW hvYeJACUKLzvwk3Q0SRIlZ0vZJLi9Vz5iG22F6nWuobUblhC/wHx2Rk0PC5SGyTI2Pa6l6 1gAuq91dOeVDm1EXOPH/6LX10chghm+l4pWmYWiaQaeWL2dLV/HbHKs9kcFxQQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=6c2ea7f890b135ff393322d40e4600b3910c9890 commit 6c2ea7f890b135ff393322d40e4600b3910c9890 Author: John Baldwin AuthorDate: 2022-03-10 23:40:44 +0000 Commit: John Baldwin CommitDate: 2022-05-12 22:13:00 +0000 gcore: Use PT_GETREGSET to fetch NT_PRSTATUS and NT_FPREGSET. Add a elf_putregnote() helper to build the ELF note for a register set. Once nice result of this approach is that this reuses the kernel's support for generating 32-bit register sets for 32-bit processes avoiding the need to duplicate that logic in elf32core.c. Reviewed by: markj Sponsored by: University of Cambridge, Google, Inc. Differential Revision: https://reviews.freebsd.org/D34447 (cherry picked from commit 4965ac059da1ff7f3dac8f9556dd82c619063105) --- usr.bin/gcore/elf32core.c | 59 -------------------------------- usr.bin/gcore/elfcore.c | 87 ++++++++++++++++++++--------------------------- 2 files changed, 37 insertions(+), 109 deletions(-) diff --git a/usr.bin/gcore/elf32core.c b/usr.bin/gcore/elf32core.c index 4e91fb0bc065..98e2408c4aa9 100644 --- a/usr.bin/gcore/elf32core.c +++ b/usr.bin/gcore/elf32core.c @@ -12,65 +12,6 @@ #define ELFCORE_COMPAT_32 1 #include "elfcore.c" -static void -elf_convert_gregset(elfcore_gregset_t *rd, struct reg *rs) -{ -#ifdef __amd64__ - rd->r_gs = rs->r_gs; - rd->r_fs = rs->r_fs; - rd->r_es = rs->r_es; - rd->r_ds = rs->r_ds; - rd->r_edi = rs->r_rdi; - rd->r_esi = rs->r_rsi; - rd->r_ebp = rs->r_rbp; - rd->r_ebx = rs->r_rbx; - rd->r_edx = rs->r_rdx; - rd->r_ecx = rs->r_rcx; - rd->r_eax = rs->r_rax; - rd->r_eip = rs->r_rip; - rd->r_cs = rs->r_cs; - rd->r_eflags = rs->r_rflags; - rd->r_esp = rs->r_rsp; - rd->r_ss = rs->r_ss; -#elif defined(__aarch64__) - int i; - - for (i = 0; i < 13; i++) - rd->r[i] = rs->x[i]; - rd->r_sp = rs->x[13]; - rd->r_lr = rs->x[14]; - rd->r_pc = rs->elr; - rd->r_cpsr = rs->spsr; -#elif defined(__powerpc64__) - int i; - - for (i = 0; i < 32; i++) - rd->fixreg[i] = rs->fixreg[i]; - rd->lr = rs->lr; - rd->cr = rs->cr; - rd->xer = rs->xer; - rd->ctr = rs->ctr; - rd->pc = rs->pc; -#else -#error Unsupported architecture -#endif -} - -static void -elf_convert_fpregset(elfcore_fpregset_t *rd, struct fpreg *rs) -{ -#ifdef __amd64__ - /* XXX this is wrong... */ - memcpy(rd, rs, sizeof(*rd)); -#elif defined(__aarch64__) - /* ARM64TODO */ -#elif defined(__powerpc64__) - memcpy(rd, rs, sizeof(*rd)); -#else -#error Unsupported architecture -#endif -} - static void elf_convert_siginfo(struct siginfo32 *sid, siginfo_t *sis) { diff --git a/usr.bin/gcore/elfcore.c b/usr.bin/gcore/elfcore.c index 9c5be76cfd7c..b93ef7ed92d6 100644 --- a/usr.bin/gcore/elfcore.c +++ b/usr.bin/gcore/elfcore.c @@ -89,8 +89,6 @@ typedef struct reg32 elfcore_gregset_t; typedef struct prpsinfo32 elfcore_prpsinfo_t; typedef struct prstatus32 elfcore_prstatus_t; typedef struct ptrace_lwpinfo32 elfcore_lwpinfo_t; -static void elf_convert_gregset(elfcore_gregset_t *rd, struct reg *rs); -static void elf_convert_fpregset(elfcore_fpregset_t *rd, struct fpreg *rs); static void elf_convert_lwpinfo(struct ptrace_lwpinfo32 *pld, struct ptrace_lwpinfo *pls); #else @@ -99,8 +97,6 @@ typedef gregset_t elfcore_gregset_t; typedef prpsinfo_t elfcore_prpsinfo_t; typedef prstatus_t elfcore_prstatus_t; typedef struct ptrace_lwpinfo elfcore_lwpinfo_t; -#define elf_convert_gregset(d,s) *d = *s -#define elf_convert_fpregset(d,s) *d = *s #define elf_convert_lwpinfo(d,s) *d = *s #endif @@ -111,9 +107,7 @@ static void cb_size_segment(struct map_entry *, void *); static void each_dumpable_segment(struct map_entry *, segment_callback, void *closure); static void elf_detach(void); /* atexit() handler. */ -static void *elf_note_fpregset(void *, size_t *); static void *elf_note_prpsinfo(void *, size_t *); -static void *elf_note_prstatus(void *, size_t *); static void *elf_note_thrmisc(void *, size_t *); static void *elf_note_ptlwpinfo(void *, size_t *); #if defined(__arm__) @@ -139,6 +133,7 @@ static void elf_puthdr(int, pid_t, struct map_entry *, void *, size_t, size_t, size_t, int); static void elf_putnote(int, notefunc_t, void *, struct sbuf *); static void elf_putnotes(pid_t, struct sbuf *, size_t *); +static void elf_putregnote(int, lwpid_t, struct sbuf *); static void freemap(struct map_entry *); static struct map_entry *readmap(pid_t); static void *procstat_sysctl(void *, int, size_t, size_t *sizep); @@ -376,8 +371,8 @@ elf_putnotes(pid_t pid, struct sbuf *sb, size_t *sizep) elf_putnote(NT_PRPSINFO, elf_note_prpsinfo, &pid, sb); for (i = 0; i < threads; ++i) { - elf_putnote(NT_PRSTATUS, elf_note_prstatus, tids + i, sb); - elf_putnote(NT_FPREGSET, elf_note_fpregset, tids + i, sb); + elf_putregnote(NT_PRSTATUS, tids[i], sb); + elf_putregnote(NT_FPREGSET, tids[i], sb); elf_putnote(NT_THRMISC, elf_note_thrmisc, tids + i, sb); elf_putnote(NT_PTLWPINFO, elf_note_ptlwpinfo, tids + i, sb); #if defined(__arm__) @@ -414,6 +409,40 @@ elf_putnotes(pid_t pid, struct sbuf *sb, size_t *sizep) *sizep = size; } +/* + * Emit one register set note section to sbuf. + */ +static void +elf_putregnote(int type, lwpid_t tid, struct sbuf *sb) +{ + Elf_Note note; + struct iovec iov; + ssize_t old_len; + + iov.iov_base = NULL; + iov.iov_len = 0; + if (ptrace(PT_GETREGSET, tid, (void *)&iov, type) != 0) + return; + iov.iov_base = calloc(1, iov.iov_len); + if (iov.iov_base == NULL) + errx(1, "out of memory"); + if (ptrace(PT_GETREGSET, tid, (void *)&iov, type) != 0) + errx(1, "failed to fetch register set %d", type); + + note.n_namesz = 8; /* strlen("FreeBSD") + 1 */ + note.n_descsz = iov.iov_len; + note.n_type = type; + + sbuf_bcat(sb, ¬e, sizeof(note)); + sbuf_start_section(sb, &old_len); + sbuf_bcat(sb, "FreeBSD", note.n_namesz); + sbuf_end_section(sb, old_len, sizeof(Elf32_Size), 0); + sbuf_start_section(sb, &old_len); + sbuf_bcat(sb, iov.iov_base, iov.iov_len); + sbuf_end_section(sb, old_len, sizeof(Elf32_Size), 0); + free(iov.iov_base); +} + /* * Emit one note section to sbuf. */ @@ -654,48 +683,6 @@ elf_note_prpsinfo(void *arg, size_t *sizep) return (psinfo); } -static void * -elf_note_prstatus(void *arg, size_t *sizep) -{ - lwpid_t tid; - elfcore_prstatus_t *status; - struct reg greg; - - tid = *(lwpid_t *)arg; - status = calloc(1, sizeof(*status)); - if (status == NULL) - errx(1, "out of memory"); - status->pr_version = PRSTATUS_VERSION; - status->pr_statussz = sizeof(*status); - status->pr_gregsetsz = sizeof(elfcore_gregset_t); - status->pr_fpregsetsz = sizeof(elfcore_fpregset_t); - status->pr_osreldate = __FreeBSD_version; - status->pr_pid = tid; - ptrace(PT_GETREGS, tid, (void *)&greg, 0); - elf_convert_gregset(&status->pr_reg, &greg); - - *sizep = sizeof(*status); - return (status); -} - -static void * -elf_note_fpregset(void *arg, size_t *sizep) -{ - lwpid_t tid; - elfcore_fpregset_t *fpregset; - fpregset_t fpreg; - - tid = *(lwpid_t *)arg; - fpregset = calloc(1, sizeof(*fpregset)); - if (fpregset == NULL) - errx(1, "out of memory"); - ptrace(PT_GETFPREGS, tid, (void *)&fpreg, 0); - elf_convert_fpregset(fpregset, &fpreg); - - *sizep = sizeof(*fpregset); - return (fpregset); -} - static void * elf_note_thrmisc(void *arg, size_t *sizep) {