From nobody Thu Mar 10 23:41:34 2022 X-Original-To: dev-commits-src-main@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 789F519F8F1D; Thu, 10 Mar 2022 23:41:35 +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 4KF5Dv19nVz3jGc; Thu, 10 Mar 2022 23:41:35 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1646955695; 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=IhuU5Bdsu2jFATpvEoY3sNplM+s5c3ION24RhEzOBN4=; b=GhQ7yPC1xPvSrw/zkQr/cudV9V9JNvEX40X6MqOwwUu+WMlgXmC5G0BfNg8nuNJNnem1wb w26F44s4MY+C3A3cD0czVwvqvLCPP1Aa6MoNs56o6GUyNRP0Z/xur8HbyxGhdIuG+HhKNf DZleBIToRfFK4p17eMGXnFVdn688QJJ05XJa0ZpCO4q8JvYsO2zipjTEpxe5l/rJ29XNR2 cNwsoevxwIXeN8WGMH1olcfQplPxSo93HFHyjZWyW+qu6MJS3+5pb4SvhJnhf9h0MU7UWM dHO1sK474kUYXlX2W/1LgpJ/XhE0jcGVVuhUWiaDwnbx/QOWv4cSLmT+pmbLFw== 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 EBEF666B7; Thu, 10 Mar 2022 23:41:34 +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 22ANfY7H025065; Thu, 10 Mar 2022 23:41:34 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 22ANfYd3025064; Thu, 10 Mar 2022 23:41:34 GMT (envelope-from git) Date: Thu, 10 Mar 2022 23:41:34 GMT Message-Id: <202203102341.22ANfYd3025064@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: John Baldwin Subject: git: 6b71405bfe8d - main - Store core dump notes for all valid register sets for FreeBSD processes. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@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/main X-Git-Reftype: branch X-Git-Commit: 6b71405bfe8dc76834603f8f9e48346c3f49eae0 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1646955695; 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=IhuU5Bdsu2jFATpvEoY3sNplM+s5c3ION24RhEzOBN4=; b=tvEAZn0Io0zfA6nCKjabp4PnSxxn7HCheSE3CHlLdd190a1jToD+3WRsaW1UPIOntDJ30k 1aFLq5UzX5LH4D9zli2Hh295glwtSAtXSgOBV90Mr7HL/iBNHyXIEx6RHc/GbtKmcXetM/ ikuD9SsdMY2rOMBQ+rD2lMy/HfhX4w6uB1O714OByx8bicc6sxs03ophfzHuWahrgcDuen T75rmK/ApLrzukIzPuI9r2u7tz6AJZ3FH9SCdie82FpM63ki7DJZTBHSpV2ZsbGlFehgaT jzAaz+qznd+yvki5+ZtKmkCXU4YJVxyXh6cxJ1i4rHbz5iLspqE+BK9Qd3ogKg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1646955695; a=rsa-sha256; cv=none; b=hP9sgPPMLzgQvxsBVdFeckL82igG7mizk7iNx0eLrZZ5ANTwQxxpivwbKnoY3oewJY/V7O jifJYdMPyYMTzd0PRVnUMaXq0zz9O3/hF59grCmNNo21X72vqzap5nYP9c/tKEP1mMCLKk r02/FWFUvyREpAl0t+U2fpykkvLw557xTy4NCb8S0McmTDT+tOv4RHZnTBk5BqZ4obq81m er7u9J3Pnt4kZdCVsfW3euBPKU92YjKFXxHzAcYRlnyv/hoKRdjlTtxJlMTv7j0Jw2uESK k3Kk3enf3Q1h+JfRFCvaCksgfEfvmVb6UqlIYF+HAyHJq1WEtkQC8Yz1lWsdzA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=6b71405bfe8dc76834603f8f9e48346c3f49eae0 commit 6b71405bfe8dc76834603f8f9e48346c3f49eae0 Author: John Baldwin AuthorDate: 2022-03-10 23:40:19 +0000 Commit: John Baldwin CommitDate: 2022-03-10 23:40:19 +0000 Store core dump notes for all valid register sets for FreeBSD processes. In particular, use a generic wrapper around struct regset rather than requiring per-regset helpers. This helper replaces the MI __elfN(note_prstatus) and __elfN(note_fpregset) helpers. It also removes the need to explicitly dump NT_ARM_ADDR_MASK in the arm64 __elfN(dump_thread). Reviewed by: markj, emaste Sponsored by: University of Cambridge, Google, Inc. Differential Revision: https://reviews.freebsd.org/D34446 --- sys/arm64/arm64/elf_machdep.c | 20 +------- sys/kern/imgact_elf.c | 110 +++++++++++++++++++++++++++--------------- 2 files changed, 74 insertions(+), 56 deletions(-) diff --git a/sys/arm64/arm64/elf_machdep.c b/sys/arm64/arm64/elf_machdep.c index 383a0911b7fe..57c43ed8206d 100644 --- a/sys/arm64/arm64/elf_machdep.c +++ b/sys/arm64/arm64/elf_machdep.c @@ -143,25 +143,9 @@ static struct regset regset_arm64_addr_mask = { ELF_REGSET(regset_arm64_addr_mask); void -elf64_dump_thread(struct thread *td, void *dst, size_t *off) +elf64_dump_thread(struct thread *td __unused, void *dst __unused, + size_t *off __unused) { - struct arm64_addr_mask addr_mask; - size_t len, mask_size; - - len = 0; - if (dst != NULL) { - mask_size = sizeof(addr_mask); - get_arm64_addr_mask(®set_arm64_addr_mask, td, &addr_mask, - &mask_size); - - len += elf64_populate_note(NT_ARM_ADDR_MASK, &addr_mask, dst, - sizeof(addr_mask), NULL); - } else { - len += elf64_populate_note(NT_ARM_ADDR_MASK, NULL, NULL, - sizeof(addr_mask), NULL); - } - - *off += len; } bool diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 332bb221e746..0f60835ce5e2 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -102,6 +102,8 @@ static bool __elfN(check_note)(struct image_params *imgp, uint32_t *fctl0); static vm_prot_t __elfN(trans_prot)(Elf_Word); static Elf_Word __elfN(untrans_prot)(vm_prot_t); +static size_t __elfN(prepare_register_notes)(struct thread *td, + struct note_info_list *list, struct thread *target_td); SYSCTL_NODE(_kern, OID_AUTO, __CONCAT(elf, __ELF_WORD_SIZE), CTLFLAG_RW | CTLFLAG_MPSAFE, 0, @@ -1519,6 +1521,7 @@ struct phdr_closure { struct note_info { int type; /* Note type. */ + struct regset *regset; /* Register set. */ outfunc_t outfunc; /* Output function. */ void *outarg; /* Argument for the output function. */ size_t outsize; /* Output size. */ @@ -1538,9 +1541,7 @@ static int __elfN(corehdr)(struct coredump_params *, int, void *, size_t, struct note_info_list *, size_t, int); static void __elfN(putnote)(struct thread *td, struct note_info *, struct sbuf *); -static void __elfN(note_fpregset)(void *, struct sbuf *, size_t *); static void __elfN(note_prpsinfo)(void *, struct sbuf *, size_t *); -static void __elfN(note_prstatus)(void *, struct sbuf *, size_t *); static void __elfN(note_threadmd)(void *, struct sbuf *, size_t *); static void __elfN(note_thrmisc)(void *, struct sbuf *, size_t *); static void __elfN(note_ptlwpinfo)(void *, struct sbuf *, size_t *); @@ -1833,7 +1834,8 @@ __elfN(prepare_notes)(struct thread *td, struct note_info_list *list, p = td->td_proc; size = 0; - size += __elfN(register_note)(td, list, NT_PRPSINFO, __elfN(note_prpsinfo), p); + size += __elfN(register_note)(td, list, NT_PRPSINFO, + __elfN(note_prpsinfo), p); /* * To have the debugger select the right thread (LWP) as the initial @@ -1843,10 +1845,7 @@ __elfN(prepare_notes)(struct thread *td, struct note_info_list *list, */ thr = td; while (thr != NULL) { - size += __elfN(register_note)(td, list, NT_PRSTATUS, - __elfN(note_prstatus), thr); - size += __elfN(register_note)(td, list, NT_FPREGSET, - __elfN(note_fpregset), thr); + size += __elfN(prepare_register_notes)(td, list, thr); size += __elfN(register_note)(td, list, NT_THRMISC, __elfN(note_thrmisc), thr); size += __elfN(register_note)(td, list, NT_PTLWPINFO, @@ -1968,6 +1967,34 @@ __elfN(puthdr)(struct thread *td, void *hdr, size_t hdrsize, int numsegs, each_dumpable_segment(td, cb_put_phdr, &phc, flags); } +static size_t +__elfN(register_regset_note)(struct thread *td, struct note_info_list *list, + struct regset *regset, struct thread *target_td) +{ + const struct sysentvec *sv; + struct note_info *ninfo; + size_t size, notesize; + + size = 0; + if (!regset->get(regset, target_td, NULL, &size) || size == 0) + return (0); + + ninfo = malloc(sizeof(*ninfo), M_TEMP, M_ZERO | M_WAITOK); + ninfo->type = regset->note; + ninfo->regset = regset; + ninfo->outarg = target_td; + ninfo->outsize = size; + TAILQ_INSERT_TAIL(list, ninfo, link); + + sv = td->td_proc->p_sysent; + notesize = sizeof(Elf_Note) + /* note header */ + roundup2(strlen(sv->sv_elf_core_abi_vendor) + 1, ELF_NOTE_ROUNDSIZE) + + /* note name */ + roundup2(size, ELF_NOTE_ROUNDSIZE); /* note description */ + + return (notesize); +} + size_t __elfN(register_note)(struct thread *td, struct note_info_list *list, int type, outfunc_t out, void *arg) @@ -2066,7 +2093,16 @@ __elfN(putnote)(struct thread *td, struct note_info *ninfo, struct sbuf *sb) if (note.n_descsz == 0) return; sbuf_start_section(sb, &old_len); - ninfo->outfunc(ninfo->outarg, sb, &ninfo->outsize); + if (ninfo->regset != NULL) { + struct regset *regset = ninfo->regset; + void *buf; + + buf = malloc(ninfo->outsize, M_TEMP, M_ZERO | M_WAITOK); + (void)regset->get(regset, ninfo->outarg, buf, &ninfo->outsize); + sbuf_bcat(sb, buf, ninfo->outsize); + free(buf, M_TEMP); + } else + ninfo->outfunc(ninfo->outarg, sb, &ninfo->outsize); sect_len = sbuf_end_section(sb, old_len, ELF_NOTE_ROUNDSIZE, 0); if (sect_len < 0) return; @@ -2237,24 +2273,6 @@ static struct regset __elfN(regset_prstatus) = { }; ELF_REGSET(__elfN(regset_prstatus)); -static void -__elfN(note_prstatus)(void *arg, struct sbuf *sb, size_t *sizep) -{ - struct thread *td; - elf_prstatus_t *status; - - td = arg; - if (sb != NULL) { - KASSERT(*sizep == sizeof(*status), ("%s: invalid size", - __func__)); - status = malloc(sizeof(*status), M_TEMP, M_ZERO | M_WAITOK); - __elfN(get_prstatus)(NULL, td, status, sizep); - sbuf_bcat(sb, status, sizeof(*status)); - free(status, M_TEMP); - } - *sizep = sizeof(*status); -} - static bool __elfN(get_fpregset)(struct regset *rs, struct thread *td, void *buf, size_t *sizep) @@ -2299,21 +2317,37 @@ static struct regset __elfN(regset_fpregset) = { }; ELF_REGSET(__elfN(regset_fpregset)); -static void -__elfN(note_fpregset)(void *arg, struct sbuf *sb, size_t *sizep) +static size_t +__elfN(prepare_register_notes)(struct thread *td, struct note_info_list *list, + struct thread *target_td) { - struct thread *td; - elf_prfpregset_t *fpregset; + struct sysentvec *sv = td->td_proc->p_sysent; + struct regset **regsetp, **regset_end, *regset; + size_t size; - td = arg; - if (sb != NULL) { - KASSERT(*sizep == sizeof(*fpregset), ("invalid size")); - fpregset = malloc(sizeof(*fpregset), M_TEMP, M_ZERO | M_WAITOK); - __elfN(get_fpregset)(NULL, td, fpregset, sizep); - sbuf_bcat(sb, fpregset, sizeof(*fpregset)); - free(fpregset, M_TEMP); + size = 0; + + /* NT_PRSTATUS must be the first register set note. */ + size += __elfN(register_regset_note)(td, list, &__elfN(regset_prstatus), + target_td); + + regsetp = sv->sv_regset_begin; + if (regsetp == NULL) { + /* XXX: This shouldn't be true for any FreeBSD ABIs. */ + size += __elfN(register_regset_note)(td, list, + &__elfN(regset_fpregset), target_td); + return (size); } - *sizep = sizeof(*fpregset); + regset_end = sv->sv_regset_end; + MPASS(regset_end != NULL); + for (; regsetp < regset_end; regsetp++) { + regset = *regsetp; + if (regset->note == NT_PRSTATUS) + continue; + size += __elfN(register_regset_note)(td, list, regset, + target_td); + } + return (size); } static void