svn commit: r195627 -
head/sys/cddl/contrib/opensolaris/common/nvpair
Marcel Moolenaar
marcel at FreeBSD.org
Sat Jul 11 22:43:21 UTC 2009
Author: marcel
Date: Sat Jul 11 22:43:20 2009
New Revision: 195627
URL: http://svn.freebsd.org/changeset/base/195627
Log:
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
guaranteed.
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
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-all
mailing list