problem when compiling zfs.ko with clang with O1 on amd64
Jan Mikkelsen
janm at transactionware.com
Wed Jul 27 09:46:33 UTC 2016
Hi,
(Resend because I was subscribed with the wrong address …)
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://lists.freebsd.org/pipermail/freebsd-stable/2015-July/082751.html
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’t dedicate the time to get far enough.
Regards,
Jan.
> On 27 Jul 2016, at 16:44, Andriy Gapon <avg at FreeBSD.org> wrote:
>
>
> 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.
>
> 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)
>
> When -O1 is used I see that statements like 'T x = { 0 };' are
> translated to calls to external memset function with the standard arguments.
>
> 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.
>
> 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.
>
> 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.
>
> 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
>
> $ nm /boot/kernel.z/zfs.ko | fgrep -w memset
> 0000000000019030 t memset
> 0000000000017e60 t memset
> 0000000000019500 t memset
> U memset
>
>
> Assembly of one of the local memset functions:
> .align 16, 0x90
> .type memset, @function
>
> 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
>
> # BB#0: # %entry
> pushq %rbp
>
> .Ltmp105:
> .cfi_def_cfa_offset 16
>
> .Ltmp106:
> .cfi_offset %rbp, -16
> movq %rsp, %rbp
>
> .Ltmp107:
> .cfi_def_cfa_register %rbp
>
> #DEBUG_VALUE: memset:c <- 0
> .loc 5 191 3 prologue_end # /usr/src/sys/sys/libkern.h:191:3
>
> .Ltmp108:
> popq %rbp
> jmp bzero # TAILCALL
>
> .Ltmp109:
> .Lfunc_end6:
> .size memset, .Lfunc_end6-memset
> .cfi_endproc
>
>
> --
> Andriy Gapon
> _______________________________________________
> freebsd-hackers at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe at freebsd.org"
More information about the freebsd-hackers
mailing list