Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Feb 2010 19:15:08 +0100
From:      Julian Stecklina <jsteckli@os.inf.tu-dresden.de>
To:        freebsd-current@freebsd.org
Subject:   Aliasing bug in FICL (may break loader with gcc>4.4)
Message-ID:  <87tyti8ixf.fsf@monat.inf.tu-dresden.de>

next in thread | raw e-mail | index | archive | help
--==-=-=
Content-Type: multipart/mixed; boundary="=-=-="

--=-=-=
Content-Transfer-Encoding: quoted-printable

Hello,

while porting FICL, I noticed an aliasing bug which manifests (at least)
with gcc 4.4.2 and 4.4.3 when strict-aliasing is enabled. The root cause is

#define LVALUEtoCELL(v) (*(CELL *)&v)

in sys/boot/ficl/ficl.h. CELL is a union:

typedef union _cell
{
    FICL_INT i;
    FICL_UNS u;
[...]
    void *p;
    void (*fn)(void);
} CELL;

If you compile the attached C file with gcc-4.4.3 and -O3, all stores to
i are optimized out and the result is bogus. A ficl built with this gcc
is inoperable.

Giving the union the may_alias attribute works around this, but is GCC
specific (patch is attached). Just using ((CELL)v) does not work without
casting all over the place or extending the union.

Regards, Julian
=2D-=20
"Actually I made up the term 'object-oriented', and I can tell you I
did not have C++ in mind." - Alan Kay (OOPSLA 1997 Keynote)

--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=ficl-aliasing-bug.patch
Content-Transfer-Encoding: quoted-printable

=2D-- ficl.h	2010-02-15 18:46:27.020120933 +0100
+++ /home/julian/src/nova/ficl/ficl.h	2010-02-15 18:16:32.370312051 +0100
@@ -269,13 +269,17 @@
 #endif
     void *p;
     void (*fn)(void);
=2D} CELL;
+} __attribute__((may_alias)) CELL;
=20
 /*
 ** LVALUEtoCELL does a little pointer trickery to cast any CELL sized
 ** lvalue (informal definition: an expression whose result has an
 ** address) to CELL. Remember that constants and casts are NOT
 ** themselves lvalues!
+**
+** XXX This only works as long as the strict-aliasing rule is
+** circumvented (see attribute above). Otherwise GCC >4.4 will
+** silently throw away v and just put garbage into the CELL.
 */
 #define LVALUEtoCELL(v) (*(CELL *)&v)
=20

--=-=-=--

--==-=-=
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (GNU/Linux)

iEYEARECAAYFAkt5jzAACgkQ2EtjUdW3H9k9ewCgyfmYaR7FrkHfD9GI6WYNqfAI
ST8AoJ04SnGVNBzWy0laH6sKJ9q/37iE
=DXdC
-----END PGP SIGNATURE-----
--==-=-=--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?87tyti8ixf.fsf>