Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Jul 2016 19:24:51 +1000
From:      Jan Mikkelsen <janm@transactionware.com>
To:        Andriy Gapon <avg@FreeBSD.org>
Cc:        Dimitry Andric <dim@FreeBSD.org>, "freebsd-hackers@freebsd.org" <freebsd-hackers@FreeBSD.org>
Subject:   Re: problem when compiling zfs.ko with clang with O1 on amd64
Message-ID:  <39ABE4A1-70C6-4096-AF1D-97495F0D2BE6@transactionware.com>
In-Reply-To: <667ac922-533f-2d37-706e-93fa9b069034@FreeBSD.org>
References:  <667ac922-533f-2d37-706e-93fa9b069034@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi,

Yes, there is serious namespace pollution in the amd64 kernel linker. =
File statics are like globals but without multiple definition detection. =
I find this a bit scary.

See this thread for an example that affected me about a year ago:

=
https://docs.freebsd.org/cgi/getmsg.cgi?fetch=3D395455+0+archive/2015/free=
bsd-stable/20150719.freebsd-stable =
<https://docs.freebsd.org/cgi/getmsg.cgi?fetch=3D395455+0+archive/2015/fre=
ebsd-stable/20150719.freebsd-stable>

There are lots of possible silent failures here. Static functions with =
the same name, as you have discovered. Static variables silently being =
shared.

The easiest solution I saw was decorating the local names to avoid a =
clash. I started looking at it as a post kernel module link step but =
couldn=E2=80=99t dedicate the time to get far enough.

Regards,

Jan.


> On 27 Jul 2016, at 16:44, Andriy Gapon <avg@FreeBSD.org> wrote:
>=20
>=20
> First of all, what I describe next happens only when compiling with =
-O1
> which is a non-standard option that I used to get better debugging.
>=20
> So, I compile zfs module with clang on amd64 head.
> Clang is:
> FreeBSD clang version 3.8.0 (tags/RELEASE_380/final 262564) (based on
> LLVM 3.8.0)
>=20
> When -O1 is used I see that statements like 'T x =3D { 0 };' are
> translated to calls to external memset function with the standard =
arguments.
>=20
> On the other hand, since recently a few ZFS source files (all hash
> related: sha256c.c, sha512c.c, skein.c) have explicit calls to =
memset(x,
> 0, s).  Those get inlined but in a particular fashion: a local memset
> function is generated in each file, the function is a very thin =
wrapper
> around bzero and it expects the same argument as bzero.
>=20
> Because of how kernel loadable modules are implemented on amd64 the
> external calls to memset get resolved to the first of the local
> functions.  Because of the mismatch between the arguments provided and
> the arguments expected the effective calls are 'bzero(x, 0)', NOPs =
that is.
>=20
> I am not sure if I can blame clang here.  It is probably correct to
> expect that it can generate a _local_ function named 'memset' without
> interfering without other compilation units.  However, that can be
> unhelpful as we can see.
>=20
> Some data:
> $ nm -A --defined-only *.o | fgrep -w memset
> sha256c.o:0000000000000e60 t memset
> sha512c.o:00000000000010f0 t memset
> skein.o:0000000000000120 t memset
>=20
> $ nm /boot/kernel.z/zfs.ko | fgrep -w memset
> 0000000000019030 t memset
> 0000000000017e60 t memset
> 0000000000019500 t memset
>                 U memset
>=20
>=20
> Assembly of one of the local memset functions:
> .align 16, 0x90
> .type  memset, @function
>=20
> memset:
> # @memset
> .Lfunc_begin6:
> 	.file 5 "/usr/src/sys/sys" "libkern.h"
> 	.loc  5 187 0                 # /usr/src/sys/sys/libkern.h:187:0
> 	.cfi_startproc
>=20
> # BB#0:                                 # %entry
> 	pushq %rbp
>=20
> .Ltmp105:
> 	.cfi_def_cfa_offset 16
>=20
> .Ltmp106:
> 	.cfi_offset %rbp, -16
> 	movq %rsp, %rbp
>=20
> .Ltmp107:
> 	.cfi_def_cfa_register %rbp
>=20
> #DEBUG_VALUE: memset:c <- 0
> .loc 5 191 3 prologue_end    # /usr/src/sys/sys/libkern.h:191:3
>=20
> .Ltmp108:
> 	popq %rbp
> 	jmp  bzero                   # TAILCALL
>=20
> .Ltmp109:
> .Lfunc_end6:
> 	.size memset, .Lfunc_end6-memset
> 	.cfi_endproc
>=20
>=20
> --=20
> Andriy Gapon
> _______________________________________________
> freebsd-hackers@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to =
"freebsd-hackers-unsubscribe@freebsd.org"




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?39ABE4A1-70C6-4096-AF1D-97495F0D2BE6>