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, &copylen);
+		const size_t elem_size = sysctl_fillevcnt(ev, evs, &copylen);
 		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();
 

Reply via email to