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