sys/boot includes amd64 headers

Bruce Evans brde at optusnet.com.au
Wed Jul 28 16:25:15 UTC 2010


On Wed, 28 Jul 2010, Tijl Coosemans wrote:

> While working on cc -m32 support I added the following to all headers
> in sys/amd64/include to make sure none of my changes have an effect on
> building world+kernel:
>
> #ifndef __x86_64__
> #error bla
> #endif
>
> This exposed some problems in sys/boot. The Makefiles there create a
> symlink .OBJDIR/machine -> sys/i386/includes and add -I. to the CFLAGS
> such that including <machine/header.h> includes the i386 header.
>
> The problem is that <stdarg.h> is also included and is a symlink in
> WORLDTMP/usr/include to the machine/stdarg.h there, which is for amd64.
> There should be a symlink .OBJDIR/stdarg.h -> machine/stdarg.h to fix
> this.

No, <stdarg.h> means the host machine's stdarg.h, while <machine/stdarg.h>
means the target's.  It may be wrong for boot code to ever use the
former.  Only things like assemblers of boot code should use it.
btxld is an example, but it isn't under /sys/boot.  It is under usr.sbin
and thus necessarily uses the host's includes unless it does something
nasty to get the target's.  Maybe it needs both.  I think it doesn't
actually work as a cross-tool, except possibly for x86_32 under x86_64.

It is certainly a bug for the <stsarg.h> to be used as much as it is.
There are 72 lines matching include.*stdarg.h in files in /sys/boot,
and only 26 lines matching the usually-correct include.*machine/stdarg.h.
svn files complicate recursive searches so the above counts are more
than double the correct counts.

> Another case is sys/boot/i386/kgzldr which includes <sys/types.h> and
> that in turn includes headers from machine, so it needs the machine
> symlink.

I think it is a a bug to ever be missing the machine symlink.

> Could somebody review the attached patch to make sure it does the right
> thing?

> diff --git a/sys/boot/ficl/Makefile b/sys/boot/ficl/Makefile
> index cdc8f7e..bb9c04c 100644
> --- a/sys/boot/ficl/Makefile
> +++ b/sys/boot/ficl/Makefile
> @@ -57,12 +57,15 @@ softcore.c: ${SOFTWORDS} softcore.awk
>  	    | awk -f softcore.awk -v datestamp="`LC_ALL=C date`") > ${.TARGET}
> 
>  .if ${MACHINE_ARCH} == "amd64"
> -${SRCS:M*.c:R:S/$/.o/g}: machine
> +${SRCS:M*.c:R:S/$/.o/g}: machine stdarg.h
> 
> -beforedepend ${OBJS}: machine
> +beforedepend ${OBJS}: machine stdarg.h
> 
>  machine:
>  	ln -sf ${.CURDIR}/../../i386/include machine
> 
> -CLEANFILES+=	machine
> +stdarg.h:
> +	ln -sf machine/stdarg.h stdarg.h
> +
> +CLEANFILES+=	machine stdarg.h
>  .endif
> diff --git a/sys/boot/i386/boot2/Makefile b/sys/boot/i386/boot2/Makefile
> index ab5a69a..4196115 100644
> --- a/sys/boot/i386/boot2/Makefile
> +++ b/sys/boot/i386/boot2/Makefile
> @@ -95,10 +95,12 @@ boot2.h: boot1.out
>  	    REL1=`printf "%d" ${REL1}` > ${.TARGET}
> 
>  .if ${MACHINE_ARCH} == "amd64"
> -beforedepend boot2.s: machine
> -CLEANFILES+=	machine
> +beforedepend boot2.s: machine stdarg.h
> +CLEANFILES+=	machine stdarg.h
>  machine:
>  	ln -sf ${.CURDIR}/../../../i386/include machine
> +stdarg.h:
> +	ln -sf machine/stdarg.h stdarg.h
>  .endif
> 
>  .include <bsd.prog.mk>
> ...

Old i386 boot Makefiles are of much higher quality than the current
ones and don't repeat the rules for the machine symlink like the
current ones.  There are currently 11 Makefiles under /sys/boot that
creates the symlink, and you just found another one that should have
the rules.  Here is the old top-level i386 boot Makefile[.inc] where
the rules are centralized:

% # $FreeBSD: src/sys/i386/boot/Makefile.inc,v 1.6 1999/08/28 00:43:08 peter Exp $
% 
% BINDIR?=	/usr/mdec
% CFLAGS+=	-aout
% .if exists(${.CURDIR}/../../../../include)
% CFLAGS+=	-nostdinc -I${.CURDIR}/../../../../include

It also prevents use of <stdarg.h>, as in kernel and module makefiles.
These also use "-I." and used to use -I- to enforce non-ambiguous
include paths.  Now they have tons of -Ifoo's to break this and make
make output unreadable.

% .endif
% CFLAGS+=	-I${.CURDIR}/../../.. -I${.OBJDIR}

...except when built outside of the sys tree.  This case is a hack to make
that sort of work.

% CLEANFILES+=	machine
% 
% .if defined(SRCS)
% ${SRCS:M*.[sS]:R:S/$/.o/g} ${SRCS:M*.c:R:S/$/.o/g}: machine
% ${SRCS:M*.cc:R:S/$/.o/g}   ${SRCS:M*.C:R:S/$/.o/g}: machine
% ${SRCS:M*.cxx:R:S/$/.o/g}  ${SRCS:N*.h:R:S/$/.o/g}: machine
% .endif
% .if defined(OBJS)
% ${OBJS}: machine
% .endif

Everything except man pages might depend on machine.

% 
% beforedepend: machine
% machine:
% 	ln -s ${.CURDIR}/../../include ${.OBJDIR}/machine

There is not much that is so general that it can be centralized here.  But
modules makefiles use kmod.mk which does quite a bit more than this.  It
also handles the @ symlink and puts -I@ in CFLAGS so that <sys> includes
work right, and has better support than the above for building outside of
the sys tree.

Bruce


More information about the freebsd-amd64 mailing list