FreeBSD kernel - linking

hi

I successfully compile FreeBSD kernel but it does not link :slight_smile:

there are two problems

1) clang is forcing many .o to use "memmove" which is not defined
for kernel (kernel does not link with libc). I believe it might
be for static initalization of structure or something

can this be avoided/altered?

2) it seems that clang does not know about __attribute__((__section__(x)))
or it groks it wrong

can someone comment on that? btw.. this is on amd64

thnx!

roman

1) clang is forcing many .o to use "memmove" which is not defined
for kernel (kernel does not link with libc). I believe it might
be for static initalization of structure or something

can this be avoided/altered?

Yes. Please file a bug for this issue; I'm not exactly sure how to
deal with this.

2) it seems that clang does not know about __attribute__((__section__(x)))
or it groks it wrong

Fixed here: http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20090209/012195.html

- Daniel

The canonical ways would be:

-mkernel, -ffreestanding, -fhosted, -fno-builtin-memmove -fno-builtin...

that won't help, clang generates these for structure copies.

-Chris

That’s actually not sufficient. See the Apple bug 6251520 (sorry others).

The gist is that -ffreestanding still requires some library functions be implemented, for instance to implement structure zeroing on the stack. Specifically (and I know this is GCC documentation) <http://gcc.gnu.org/onlinedocs/gcc/Standards.html#Standards>:

GCC requires the freestanding environment provide memcpy, memmove, memset and memcmp

clang may wish to interpret -ffreestanding or -fno-builtin differently, but the reality is that gcc (and I think llvm-gcc) still require some library calls. clang may want to rely on the same assumptions to simplify its implementation.

Shantonu Sen
ssen@apple.com

There are only a couple of options. One, clang is documented to require memmove, and we require the kernel to have one. Two, clang is documented as not requiring it, and we generate inline code, or calls to a runtime library that is linked against. Three, we generate calls to a clang internal routine, and emit it linkonce (comdat) in every translation unit that references it. Now, the canonical solution _is_ -fno-builtin-memmove, if implemented, it would do something indistinguishable from the last. Why do you say it won't help?

all I want from clang is to state the position. I have a preliminary
ok to introduce memmove() to freebsd kernel

I just need to know the official position.

that won't help, clang generates these for structure copies.

There are only a couple of options. One, clang is documented to
require memmove, and we require the kernel to have one. Two, clang is
documented as not requiring it, and we generate inline code, or calls
to a runtime library that is linked against. Three, we generate calls
to a clang internal routine, and emit it linkonce (comdat) in every
translation unit that references it. Now, the canonical solution _is_
-fno-builtin-memmove, if implemented, it would do something
indistinguishable from the last. Why do you say it won't help?

GCC probably "happens to work" because it optimizes out the memmoves in cases that clang isn't yet. It is definitely unportable to assume that the compiler won't emit those.

all I want from clang is to state the position. I have a preliminary
ok to introduce memmove() to freebsd kernel

I just need to know the official position.

The best thing to do is add memmove to the kernel. We can treat each individual memmove that still exists as a "missed optimization" though.

-Chris

gcc will generate memmoves in certain cases, for example
16172 – simple function generates an memmove() call instead of inlining. It definitely
reserves the right to generate them. So FreeBSD is just lucky that
they haven't hit this with gcc yet.

Probably worth quoting again
(Standards - Using the GNU Compiler Collection (GCC)): "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."

Note that the reason you're seening memcpy in places gcc doesn't
generate it is that gcc normally uses memcpy instead of memmove for
struct copies. The standard makes some allowance for this (C99
6.5.16.1):

"If the value being stored in an object is read from another object
that overlaps in any way
the storage of the first object, then the overlap shall be exact and
the two objects shall
have qualified or unqualified versions of a compatible type;
otherwise, the behavior is
undefined."

That said, we decided to make clang generate memmove of memcpy instead
for a couple of reasons: one, it's safer (it's quite easy to arrange
such an illegal assignment with unions), and two, calling memcpy is
technically incorrect for the case of assigning a struct to itself.

If the FreeBSD developers want compiler-generated memory moves to call
some function other than memmove, that can probably be arranged with a
command-line option.

-Eli

I'll introduce memmove into the FreeBSD kernel, thanks for your great
arguments that will come to a good use :slight_smile: