svn commit: r195627 - head/sys/cddl/contrib/opensolaris/common/nvpair

Marcel Moolenaar marcel at
Sat Jul 11 22:43:21 UTC 2009

Author: marcel
Date: Sat Jul 11 22:43:20 2009
New Revision: 195627

  In nvpair_native_embedded_array(), meaningless pointers are zeroed.
  The programmer was aware that alignment was not guaranteed in the
  packed structure and used bzero() to NULL out the pointers.
  However, on ia64, the compiler is quite agressive in finding ILP
  and calls to bzero() are often replaced by simple assignments (i.e.
  stores). Especially when the width or size in question corresponds
  with a store instruction (i.e. st1, st2, st4 or st8).
  The problem here is not a compiler bug. The address of the memory
  to zero-out was given by '&packed->nvl_priv' and given the type of
  the 'packed' pointer the compiler could assume proper alignment for
  the replacement of bzero() with an 8-byte wide store to be valid.
  The problem is with the programmer. The programmer knew that the
  address did not have the alignment guarantees needed for a regular
  assignment, but failed to inform the compiler of that fact. In
  fact, the programmer told the compiler the opposite: alignment is
  The fix is to avoid using a pointer of type "nvlist_t *" and
  instead use a "char *" pointer as the basis for calculating the
  address. This tells the compiler that only 1-byte alignment can
  be assumed and the compiler will either keep the bzero() call
  or instead replace it with a sequence of byte-wise stores. Both
  are valid.
  Approved by:	re (kib)


Modified: head/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c
--- head/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c	Sat Jul 11 22:30:37 2009	(r195626)
+++ head/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c	Sat Jul 11 22:43:20 2009	(r195627)
@@ -2543,7 +2543,6 @@ nvpair_native_embedded_array(nvstream_t 
 		nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
 		char *value = native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp);
 		size_t len = NVP_NELEM(nvp) * sizeof (uint64_t);
-		nvlist_t *packed = (nvlist_t *)((uintptr_t)value + len);
 		int i;
 		 * Null out pointers that are meaningless in the packed
@@ -2552,13 +2551,17 @@ nvpair_native_embedded_array(nvstream_t 
 		bzero(value, len);
-		for (i = 0; i < NVP_NELEM(nvp); i++, packed++)
+		value += len;
+		for (i = 0; i < NVP_NELEM(nvp); i++) {
 			 * Null out the pointer that is meaningless in the
 			 * packed structure. The address may not be aligned,
 			 * so we have to use bzero.
-			bzero(&packed->nvl_priv, sizeof (packed->nvl_priv));
+			bzero(value + offsetof(nvlist_t, nvl_priv),
+			    sizeof(((nvlist_t *)NULL)->nvl_priv));
+			value += sizeof(nvlist_t);
+		}
 	return (nvs_embedded_nvl_array(nvs, nvp, NULL));

More information about the svn-src-head mailing list