Module Name: src Committed By: mrg Date: Sat Apr 17 00:05:31 UTC 2021
Modified Files: src/sys/kern: subr_evcnt.c Log Message: avoid an error in the recent sys/evcnt.h change to drop the 0 array size from evcnt_sysctl:ev_strings that clang does not like. the previous "struct xevcnt_sysctl" was well defined as the evcnt_sysctl with array length of 0 could be placed as the anywhere in other structures, but with [] it must remain last and xevcnt_sysctl then places a char array afterwards. avoid this entirely by removing struct xevcnt_sysctl, combining the string array + struct evcnt_sysctl size manually for the allocation, and moving all "ev_string" accesses to be via the new [] array. To generate a diff of this commit: cvs rdiff -u -r1.16 -r1.17 src/sys/kern/subr_evcnt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/subr_evcnt.c diff -u src/sys/kern/subr_evcnt.c:1.16 src/sys/kern/subr_evcnt.c:1.17 --- src/sys/kern/subr_evcnt.c:1.16 Thu Apr 15 00:37:31 2021 +++ src/sys/kern/subr_evcnt.c Sat Apr 17 00:05:31 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_evcnt.c,v 1.16 2021/04/15 00:37:31 rin Exp $ */ +/* $NetBSD: subr_evcnt.c,v 1.17 2021/04/17 00:05:31 mrg Exp $ */ /* * Copyright (c) 1996, 2000 Christopher G. Demetriou @@ -77,7 +77,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_evcnt.c,v 1.16 2021/04/15 00:37:31 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_evcnt.c,v 1.17 2021/04/17 00:05:31 mrg Exp $"); #include <sys/param.h> #include <sys/evcnt.h> @@ -214,13 +214,10 @@ evcnt_detach(struct evcnt *ev) mutex_exit(&evcnt_lock); } -struct xevcnt_sysctl { - struct evcnt_sysctl evs; - char ev_strings[2*EVCNT_STRING_MAX]; -}; +typedef char ev_strings[2*EVCNT_STRING_MAX]; static size_t -sysctl_fillevcnt(const struct evcnt *ev, struct xevcnt_sysctl *xevs, +sysctl_fillevcnt(const struct evcnt *ev, struct evcnt_sysctl *evs, size_t *copylenp) { const bool allowaddr = get_expose_address(curproc); @@ -228,17 +225,17 @@ sysctl_fillevcnt(const struct evcnt *ev, + ev->ev_grouplen + 1 + ev->ev_namelen + 1; const size_t len = roundup2(copylen, sizeof(uint64_t)); - if (xevs != NULL) { - xevs->evs.ev_count = ev->ev_count; - COND_SET_VALUE(xevs->evs.ev_addr, PTRTOUINT64(ev), allowaddr); - COND_SET_VALUE(xevs->evs.ev_parent, PTRTOUINT64(ev->ev_parent), + if (evs != NULL) { + evs->ev_count = ev->ev_count; + COND_SET_VALUE(evs->ev_addr, PTRTOUINT64(ev), allowaddr); + COND_SET_VALUE(evs->ev_parent, PTRTOUINT64(ev->ev_parent), allowaddr); - xevs->evs.ev_type = ev->ev_type; - xevs->evs.ev_grouplen = ev->ev_grouplen; - xevs->evs.ev_namelen = ev->ev_namelen; - xevs->evs.ev_len = len / sizeof(uint64_t); - strcpy(xevs->evs.ev_strings, ev->ev_group); - strcpy(xevs->evs.ev_strings + ev->ev_grouplen + 1, ev->ev_name); + evs->ev_type = ev->ev_type; + evs->ev_grouplen = ev->ev_grouplen; + evs->ev_namelen = ev->ev_namelen; + evs->ev_len = len / sizeof(uint64_t); + strcpy(evs->ev_strings, ev->ev_group); + strcpy(evs->ev_strings + ev->ev_grouplen + 1, ev->ev_name); } *copylenp = copylen; @@ -248,7 +245,8 @@ sysctl_fillevcnt(const struct evcnt *ev, static int sysctl_doevcnt(SYSCTLFN_ARGS) { - struct xevcnt_sysctl *xevs0 = NULL, *xevs; + struct evcnt_sysctl *evs0 = NULL, *evs; + const size_t xevcnt_size = sizeof(*evs0) + sizeof(ev_strings); const struct evcnt *ev; int error; int retries; @@ -278,14 +276,14 @@ sysctl_doevcnt(SYSCTLFN_ARGS) sysctl_unlock(); - if (oldp != NULL && xevs0 == NULL) - xevs0 = kmem_zalloc(sizeof(*xevs0), KM_SLEEP); + if (oldp != NULL) + evs0 = kmem_zalloc(xevcnt_size, KM_SLEEP); retries = 100; retry: dp = oldp; len = (oldp != NULL) ? *oldlenp : 0; - xevs = xevs0; + evs = evs0; error = 0; needed = 0; @@ -300,22 +298,22 @@ sysctl_doevcnt(SYSCTLFN_ARGS) continue; /* - * Prepare to copy. If xevs is NULL, fillevcnt will just + * Prepare to copy. If evs is NULL, fillevcnt will just * how big the item is. */ size_t copylen; - const size_t elem_size = sysctl_fillevcnt(ev, xevs, ©len); + const size_t elem_size = sysctl_fillevcnt(ev, evs, ©len); needed += elem_size; if (len < elem_size) { - xevs = NULL; + evs = NULL; continue; } - KASSERT(xevs != NULL); - KASSERT(xevs->evs.ev_grouplen != 0); - KASSERT(xevs->evs.ev_namelen != 0); - KASSERT(xevs->evs.ev_strings[0] != 0); + KASSERT(evs != NULL); + KASSERT(evs->ev_grouplen != 0); + KASSERT(evs->ev_namelen != 0); + KASSERT(evs->ev_strings[0] != 0); const uint32_t last_generation = evcnt_generation; mutex_exit(&evcnt_lock); @@ -325,7 +323,7 @@ sysctl_doevcnt(SYSCTLFN_ARGS) * number. If we did the latter we'd have to zero them * first or we'd leak random kernel memory. */ - error = copyout(xevs, dp, copylen); + error = copyout(evs, dp, copylen); mutex_enter(&evcnt_lock); if (error) @@ -354,8 +352,8 @@ sysctl_doevcnt(SYSCTLFN_ARGS) } mutex_exit(&evcnt_lock); - if (xevs0 != NULL) - kmem_free(xevs0, sizeof(*xevs0)); + if (evs0 != NULL) + kmem_free(evs0, xevcnt_size); sysctl_relock();