Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 28 Feb 2009 18:43:54 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Alexander Kabaev <kabaev@gmail.com>
Cc:        Ed Schouten <ed@80386.nl>, Roman Divacky <rdivacky@freebsd.org>, FreeBSD@freebsd.org, Andriy Gapon <avg@icyb.net.ua>, Arch <freebsd-arch@freebsd.org>
Subject:   Re: Making LLVM happy: memmove() in the kernel
Message-ID:  <20090228175724.D14305@delplex.bde.org>
In-Reply-To: <20090227132242.4ef6a633@kan.dnsalias.net>
References:  <20090227131155.GE19161@hoeg.nl> <20090227131221.GA60215@freebsd.org> <49A80F4D.8000406@icyb.net.ua> <20090227132242.4ef6a633@kan.dnsalias.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 27 Feb 2009, Alexander Kabaev wrote:

> On Fri, 27 Feb 2009 18:05:33 +0200
> Andriy Gapon <avg@icyb.net.ua> wrote:
>
>> on 27/02/2009 15:12 Roman Divacky said the following:
>>> On Fri, Feb 27, 2009 at 02:11:55PM +0100, Ed Schouten wrote:
>>>> Hi all,
>>>>
>>>> The FreeBSD+LLVM folks* noticed Clang generates calls to memmove()
>>>> by itself. I have yet to confirm this, but I assume this is done
>>>> when performing copies of structs greater than a certain size. In

Why would Clang be that broken?  Structs cannot overlap, so they can
be copied by memcpy() which should be faster.  (However, in the FreeBSD
kernel, use of memcpy() is only approved for fixed-sized copies small
enough to be inlined, so memcpy() is only a placeholder for the
non-inlined case and for abuse, and extensive optimizations are only
applied to bcopy() and bcopy() might be faster; however2, the optimizations
don't work for any current hardware so memcpy() should be faster than
bcopy() because it is simpler.  The inlining also fails in all cases
since _all_ gcc builtins were turned off many years as a side effect
of using -ffreestanding (see below for more details).  The loss was
so insignficant that no one noticed it.  Even now, with the placeholders
for memcpy() and memset() abused a lot, fixing their inlining makes no
significant difference.)

>>>> our kernel, we don't have a memmove() function, but we do have a
>>>> bcopy().
>>>
>>> also.. quoting from
>>> (http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Standards.html):
>>>
>>> Most of the compiler support routines used by GCC are present in
>>> libgcc, but there are a few exceptions. GCC requires the
>>> freestanding environment provide memcpy, memmove, memset and memcmp.
>>>
>>> we were just lucky to not run into this

Since this is a bug in gcc, we were unlucky to run into it.  These functions
are in the application namespace in freestanding environments.  Compiler
support functions must be named something like __memmove().

FreeBSD started using -ffreestanding mainly to avoid related bugs.
The gcc builtin for printf() sometimes translates printf() to use
puts() and perhaps any function in stdio.  FreeBSD has printf() but
not puts() in the kernel so linkage started failing when gcc implemented
builtin printf (similarly for a couple of other standard library
functions).  The problem was fixed by compiling all FreeBSD kernels
with -ffreestanding, which was implemented in gcc at about the same
time that builtin printf was implemented.  -ffreestanding must kill
all standard library functions.  But them it necessarily kills all
builtins for such functions and thus prevents automatic inlining of
everything in <string.h>.

>> Some people actually were not that lucky and had to use similar
>> workarounds.
>
> I think we should use this opportunity and make sure we have external
> symbols for all of the above mem* functions, not just memmove. Please :)

How do you make them fully external so that they are only used by broken
external software?

Bruce



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