Page MenuHomeFreeBSD

Use <stdarg.h> instead of <machine/stdarg.h> in userland.
ClosedPublic

Authored by jhb on Mar 20 2018, 7:02 PM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Nov 7, 4:05 PM
Unknown Object (File)
Tue, Nov 5, 11:14 AM
Unknown Object (File)
Oct 19 2024, 7:36 AM
Unknown Object (File)
Oct 18 2024, 4:16 AM
Unknown Object (File)
Oct 18 2024, 3:02 AM
Unknown Object (File)
Oct 15 2024, 7:14 AM
Unknown Object (File)
Oct 14 2024, 9:08 AM
Unknown Object (File)
Oct 13 2024, 2:36 AM
Subscribers
None

Details

Summary

<machine/stdarg.h> is a kernel-only header. The standard header for
userland is <stdarg.h>. Using the standard header in userland avoids
weird build errors when building with external compilers that include
their own stdarg.h header.

Test Plan
  • build with external GCC patched by D14627 and a world then patched to only use --sysroot (so no -nostdinc, etc.)
  • I'm guessing the same issue affects building with external llvm since it also ships its own stdarg.h.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

This revision is now accepted and ready to land.Mar 20 2018, 7:46 PM

I don't like ifdefs like this, but cannot recommend anything less distasteful and it fixes a real problem.

LGTM. Hopefully this means I no longer need D14248.

I wonder if machine/stdarg.h should have an #error if _KERNEL is not defined to avoid strange error messages?

LGTM. Hopefully this means I no longer need D14248.

I wonder if machine/stdarg.h should have an #error if _KERNEL is not defined to avoid strange error messages?

It's often included indirectly, so that would be a bad idea.

btw, do we still need this after r329163 where we start to use _stdarg.h which is the standardized version of this stuff?

In D14776#310498, @imp wrote:

btw, do we still need this after r329163 where we start to use _stdarg.h which is the standardized version of this stuff?

Yes, that commit didn't change anything in this problem space. The problem is that the compiler's own <stdarg.h> might not be compatible with our <sys/_stdarg.h> and trying to teach the N compiler versions of <stdarg.h> to try to avoid declaring anything if our <machine/stdarg.h> has been included and vice versa is not really feasible long-term. (And by compatible I mean that they have some mutual agreement to avoid redefining symbols or types already defined, they are already using the same meaning for the symbols and types even when they clash.) In practice, it is the compiler that actually defines the layout of a va_list, so it's header is the one we should normally be using. The kernel only declares one because it wants to be freestanding. (E.g. GCC's stdarg.h unconditionally defines va_list and only has conditional checks for the va_start, etc. macros and we'd have to patch GCC's stdarg.h as well as clangs if we want to mix the two headers). The C standard says that the include for va_list is <stdarg.h>. We can get by with using a different one in a freestanding environment (the kernel), but in userland we should be conformant. The same is probably true of any other std* headers that in the kernel we use <sys/stdfoo.h> but in userland we need to use <stdfoo.h> (e.g. stdint.h).

In D14776#310497, @imp wrote:

LGTM. Hopefully this means I no longer need D14248.

I wonder if machine/stdarg.h should have an #error if _KERNEL is not defined to avoid strange error messages?

It's often included indirectly, so that would be a bad idea.

Actually, I don't think it is as otherwise I would have had more build failures. I think that sort of #error probably wouldn't fail after this commit. Most headers that are shared between the kernel and userland aren't also using va_list. Very few places actually try to share function prototypes between kernel and userland (cam and sbuf are two that do) and it is only those that are at a risk of using va_list.

This revision was automatically updated to reflect the committed changes.