2020-12-26 07:34:19

by John Millikin

[permalink] [raw]
Subject: [PATCH] arch/x86: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

When compiling with Clang, the `$(CLANG_FLAGS)' variable contains
additional flags needed to cross-compile C and Assembly sources:

* `-no-integrated-as' tells clang to assemble with GNU Assembler
  instead of its built-in LLVM assembler. This flag is set by default
  unless `LLVM_IAS=1' is set, because the LLVM assembler can't yet
  parse certain GNU extensions.

* `--target' sets the target architecture when cross-compiling. This
  flag must be set for both compilation and assembly (`KBUILD_AFLAGS')
  to support architecture-specific assembler directives.

Signed-off-by: John Millikin <[email protected]>
---
 arch/x86/Makefile | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 7116da3980be..725c65532482 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -33,6 +33,11 @@ REALMODE_CFLAGS += -ffreestanding
 REALMODE_CFLAGS += -fno-stack-protector
 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -Wno-address-of-packed-member)
 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4))
+
+ifdef CONFIG_CC_IS_CLANG
+REALMODE_CFLAGS += $(CLANG_FLAGS)
+endif
+
 export REALMODE_CFLAGS
 
 # BITS is used as extension for files which are available in a 32 bit
--
2.29.2



2020-12-26 07:37:37

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH] arch/x86: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

On December 25, 2020 11:29:30 PM PST, John Millikin <[email protected]> wrote:
>When compiling with Clang, the `$(CLANG_FLAGS)' variable contains
>additional flags needed to cross-compile C and Assembly sources:
>
>* `-no-integrated-as' tells clang to assemble with GNU Assembler
>  instead of its built-in LLVM assembler. This flag is set by default
>  unless `LLVM_IAS=1' is set, because the LLVM assembler can't yet
>  parse certain GNU extensions.
>
>* `--target' sets the target architecture when cross-compiling. This
>  flag must be set for both compilation and assembly (`KBUILD_AFLAGS')
>  to support architecture-specific assembler directives.
>
>Signed-off-by: John Millikin <[email protected]>
>---
> arch/x86/Makefile | 5 +++++
> 1 file changed, 5 insertions(+)
>
>diff --git a/arch/x86/Makefile b/arch/x86/Makefile
>index 7116da3980be..725c65532482 100644
>--- a/arch/x86/Makefile
>+++ b/arch/x86/Makefile
>@@ -33,6 +33,11 @@ REALMODE_CFLAGS += -ffreestanding
> REALMODE_CFLAGS += -fno-stack-protector
> REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS),
>-Wno-address-of-packed-member)
> REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS),
>$(cc_stack_align4))
>+
>+ifdef CONFIG_CC_IS_CLANG
>+REALMODE_CFLAGS += $(CLANG_FLAGS)
>+endif
>+
> export REALMODE_CFLAGS

> # BITS is used as extension for files which are available in a 32 bit

Why is CLANG_FLAGS non-null when unused? It would be better to centralize that.
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

2020-12-26 07:53:55

by John Millikin

[permalink] [raw]
Subject: Re: [PATCH] arch/x86: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

On 12/26/20 16:35, [email protected] wrote:
> Why is CLANG_FLAGS non-null when unused? It would be better to centralize that.
CLANG_FLAGS normally propagates through inclusion in the default KBUILD_CFLAGS and KBUILD_AFLAGS, set in `/Makefile':

    # Makefile
    KBUILD_CFLAGS += $(CLANG_FLAGS)
    KBUILD_AFLAGS += $(CLANG_FLAGS)
    export CLANG_FLAGS

This default can be overridden by explicit assignment, as is done in some of the arch/x86 makefiles:

    # arch/x86/realmode/rm/Makefile
    KBUILD_CFLAGS    := $(REALMODE_CFLAGS) -D_SETUP -D_WAKEUP \
               -I$(srctree)/arch/x86/boot
    KBUILD_AFLAGS    := $(KBUILD_CFLAGS) -D__ASSEMBLY__
    KBUILD_CFLAGS    += -fno-asynchronous-unwind-tables

Since REALMODE_CFLAGS is being built up from a plain assignment, the Clang flags get lost. As a result Clang fails to compile the real-mode code when cross-compiling for an x86 target.

    arch/x86/realmode/rm/header.S:36:1: error: unknown directive
    .type real_mode_header STT_OBJECT ; .size real_mode_header, .-real_mode_header
    ^
    arch/x86/realmode/rm/header.S:36:37: error: unknown directive
    .type real_mode_header STT_OBJECT ; .size real_mode_header, .-real_mode_header
                                        ^
    arch/x86/realmode/rm/header.S:41:62: error: unknown directive
    .globl end_signature ; ; end_signature: ; .long 0x65a22c82 ; .type end_signature STT_OBJECT ; .size end_signature, .-end_signature
                                                                 ^
    arch/x86/realmode/rm/header.S:41:95: error: unknown directive
    .globl end_signature ; ; end_signature: ; .long 0x65a22c82 ; .type end_signature STT_OBJECT ; .size end_signature, .-end_signature
                                                                                                ^

This patch allows the Clang-specific flags to propagate through the REALMODE_CFLAGS variable set in `arch/x86/Makefile' and consumed by certain arch/x86 targets, which fixes cross-compilation of x86 kernels.

2020-12-26 07:56:46

by Nathan Chancellor

[permalink] [raw]
Subject: Re: [PATCH] arch/x86: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

On Fri, Dec 25, 2020 at 11:35:28PM -0800, [email protected] wrote:
> On December 25, 2020 11:29:30 PM PST, John Millikin <[email protected]> wrote:
> >When compiling with Clang, the `$(CLANG_FLAGS)' variable contains
> >additional flags needed to cross-compile C and Assembly sources:

I am not sure how or if others agree but it took me a second to realize
the purpose of this change was cross compiling even though I read the
commit message so I think it should be called out a bit more. I would
argue that it is not very common to see x86 cross compiled (I know
Stephen Rothwell does) :) x86 is one of the most tested architectures
for building with clang and we have see no recent failures in the boot
or realmode code.

> >* `-no-integrated-as' tells clang to assemble with GNU Assembler
> >? instead of its built-in LLVM assembler. This flag is set by default
> >? unless `LLVM_IAS=1' is set, because the LLVM assembler can't yet
> >? parse certain GNU extensions.
> >
> >* `--target' sets the target architecture when cross-compiling. This
> >? flag must be set for both compilation and assembly (`KBUILD_AFLAGS')
> >? to support architecture-specific assembler directives.
> >
> >Signed-off-by: John Millikin <[email protected]>
> >---
> >?arch/x86/Makefile | 5 +++++
> >?1 file changed, 5 insertions(+)
> >
> >diff --git a/arch/x86/Makefile b/arch/x86/Makefile
> >index 7116da3980be..725c65532482 100644
> >--- a/arch/x86/Makefile
> >+++ b/arch/x86/Makefile
> >@@ -33,6 +33,11 @@ REALMODE_CFLAGS += -ffreestanding
> >?REALMODE_CFLAGS += -fno-stack-protector
> >?REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS),
> >-Wno-address-of-packed-member)
> >?REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS),
> >$(cc_stack_align4))
> >+
> >+ifdef CONFIG_CC_IS_CLANG
> >+REALMODE_CFLAGS += $(CLANG_FLAGS)
> >+endif
> >+
> >?export REALMODE_CFLAGS
> >?
> >?# BITS is used as extension for files which are available in a 32 bit
>
> Why is CLANG_FLAGS non-null when unused? It would be better to centralize that.

It isn't.

$ rg "CLANG_FLAGS :=" Makefile
507:CLANG_FLAGS :=

$ rg "CLANG_FLAGS\t" Makefile
564:CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%))
566:CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE))
570:CLANG_FLAGS += --gcc-toolchain=$(GCC_TOOLCHAIN)
573:CLANG_FLAGS += -no-integrated-as
575:CLANG_FLAGS += -Werror=unknown-warning-option

The ifdef can be dropped and unconditonally add CLANG_FLAGS to
REALMODE_CFLAGS, as is done in a few arch directories:

$ rg "\(CLANG_FLAGS\)" arch | cat
arch/s390/purgatory/Makefile:KBUILD_CFLAGS += $(CLANG_FLAGS)
arch/s390/Makefile:KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__
arch/s390/Makefile:KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2
arch/powerpc/boot/Makefile:BOOTCFLAGS += $(CLANG_FLAGS)
arch/powerpc/boot/Makefile:BOOTAFLAGS += $(CLANG_FLAGS)

Cheers,
Nathan

2020-12-26 08:44:45

by John Millikin

[permalink] [raw]
Subject: [PATCH v2] arch/x86: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

When cross-compiling with Clang, the `$(CLANG_FLAGS)' variable
contains additional flags needed to build C and assembly sources
for the target platform. Normally this variable is automatically
included in `$(KBUILD_CFLAGS)' by via the top-level Makefile.

The x86 real-mode makefile builds `$(REALMODE_CFLAGS)' from a
plain assignment and therefore drops the Clang flags. This causes
Clang to not recognize x86-specific assembler directives:

  arch/x86/realmode/rm/header.S:36:1: error: unknown directive
  .type real_mode_header STT_OBJECT ; .size real_mode_header, .-real_mode_header
  ^

Explicit propagation of `$(CLANG_FLAGS)' to `$(REALMODE_CFLAGS)',
which is inherited by real-mode make rules, fixes cross-compilation
with Clang for x86 targets.

Relevant flags:

* `--target' sets the target architecture when cross-compiling. This
  flag must be set for both compilation and assembly (`KBUILD_AFLAGS')
  to support architecture-specific assembler directives.

* `-no-integrated-as' tells clang to assemble with GNU Assembler
  instead of its built-in LLVM assembler. This flag is set by default
  unless `LLVM_IAS=1' is set, because the LLVM assembler can't yet
  parse certain GNU extensions.

Signed-off-by: John Millikin <[email protected]>
---
Changes in v2:
  - Reworded the commit message to highlight that this is for
    cross-compilation.
  - Removed the `ifdef CONFIG_CC_IS_CLANG' guard.

 arch/x86/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 7116da3980be..412b849063ec 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -33,6 +33,7 @@ REALMODE_CFLAGS += -ffreestanding
 REALMODE_CFLAGS += -fno-stack-protector
 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -Wno-address-of-packed-member)
 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4))
+REALMODE_CFLAGS += $(CLANG_FLAGS)
 export REALMODE_CFLAGS
 
 # BITS is used as extension for files which are available in a 32 bit
--
2.29.2


2020-12-27 03:32:57

by Nathan Chancellor

[permalink] [raw]
Subject: Re: [PATCH v2] arch/x86: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

On Sat, Dec 26, 2020 at 05:41:25PM +0900, John Millikin wrote:
> When cross-compiling with Clang, the `$(CLANG_FLAGS)' variable
> contains additional flags needed to build C and assembly sources
> for the target platform. Normally this variable is automatically
> included in `$(KBUILD_CFLAGS)' by via the top-level Makefile.
>
> The x86 real-mode makefile builds `$(REALMODE_CFLAGS)' from a
> plain assignment and therefore drops the Clang flags. This causes
> Clang to not recognize x86-specific assembler directives:
>
> ? arch/x86/realmode/rm/header.S:36:1: error: unknown directive
> ? .type real_mode_header STT_OBJECT ; .size real_mode_header, .-real_mode_header
> ? ^
>
> Explicit propagation of `$(CLANG_FLAGS)' to `$(REALMODE_CFLAGS)',
> which is inherited by real-mode make rules, fixes cross-compilation
> with Clang for x86 targets.
>
> Relevant flags:
>
> * `--target' sets the target architecture when cross-compiling. This
> ? flag must be set for both compilation and assembly (`KBUILD_AFLAGS')
> ? to support architecture-specific assembler directives.
>
> * `-no-integrated-as' tells clang to assemble with GNU Assembler
> ? instead of its built-in LLVM assembler. This flag is set by default
> ? unless `LLVM_IAS=1' is set, because the LLVM assembler can't yet
> ? parse certain GNU extensions.
>
> Signed-off-by: John Millikin <[email protected]>

Reviewed-by: Nathan Chancellor <[email protected]>

> ---
> Changes in v2:
> ? - Reworded the commit message to highlight that this is for
> ??? cross-compilation.
> ? - Removed the `ifdef CONFIG_CC_IS_CLANG' guard.
>
> ?arch/x86/Makefile | 1 +
> ?1 file changed, 1 insertion(+)
>
> diff --git a/arch/x86/Makefile b/arch/x86/Makefile
> index 7116da3980be..412b849063ec 100644
> --- a/arch/x86/Makefile
> +++ b/arch/x86/Makefile
> @@ -33,6 +33,7 @@ REALMODE_CFLAGS += -ffreestanding
> ?REALMODE_CFLAGS += -fno-stack-protector
> ?REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -Wno-address-of-packed-member)
> ?REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4))
> +REALMODE_CFLAGS += $(CLANG_FLAGS)
> ?export REALMODE_CFLAGS
> ?
> ?# BITS is used as extension for files which are available in a 32 bit
> --
> 2.29.2
>
>

2021-02-03 12:21:52

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v2] arch/x86: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

On Sat, Dec 26, 2020 at 05:41:25PM +0900, John Millikin wrote:
> When cross-compiling with Clang, the `$(CLANG_FLAGS)' variable
> contains additional flags needed to build C and assembly sources
> for the target platform. Normally this variable is automatically
> included in `$(KBUILD_CFLAGS)' by via the top-level Makefile.
>
> The x86 real-mode makefile builds `$(REALMODE_CFLAGS)' from a
> plain assignment and therefore drops the Clang flags. This causes
> Clang to not recognize x86-specific assembler directives:
>
>   arch/x86/realmode/rm/header.S:36:1: error: unknown directive
>   .type real_mode_header STT_OBJECT ; .size real_mode_header, .-real_mode_header
>   ^
>
> Explicit propagation of `$(CLANG_FLAGS)' to `$(REALMODE_CFLAGS)',
> which is inherited by real-mode make rules, fixes cross-compilation
> with Clang for x86 targets.
>
> Relevant flags:
>
> * `--target' sets the target architecture when cross-compiling. This
>   flag must be set for both compilation and assembly (`KBUILD_AFLAGS')
>   to support architecture-specific assembler directives.
>
> * `-no-integrated-as' tells clang to assemble with GNU Assembler
>   instead of its built-in LLVM assembler. This flag is set by default
>   unless `LLVM_IAS=1' is set, because the LLVM assembler can't yet
>   parse certain GNU extensions.
>
> Signed-off-by: John Millikin <[email protected]>
> ---
> Changes in v2:
>   - Reworded the commit message to highlight that this is for
>     cross-compilation.
>   - Removed the `ifdef CONFIG_CC_IS_CLANG' guard.
>
>  arch/x86/Makefile | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/x86/Makefile b/arch/x86/Makefile
> index 7116da3980be..412b849063ec 100644
> --- a/arch/x86/Makefile
> +++ b/arch/x86/Makefile
> @@ -33,6 +33,7 @@ REALMODE_CFLAGS += -ffreestanding
>  REALMODE_CFLAGS += -fno-stack-protector

This one too:

checking file arch/x86/Makefile
patch: **** malformed patch at line 62:  REALMODE_CFLAGS += -fno-stack-protector

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette

2021-02-03 12:28:29

by Sedat Dilek

[permalink] [raw]
Subject: Re: [PATCH v2] arch/x86: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

On Wed, Feb 3, 2021 at 1:19 PM Borislav Petkov <[email protected]> wrote:
>
> On Sat, Dec 26, 2020 at 05:41:25PM +0900, John Millikin wrote:
> > When cross-compiling with Clang, the `$(CLANG_FLAGS)' variable
> > contains additional flags needed to build C and assembly sources
> > for the target platform. Normally this variable is automatically
> > included in `$(KBUILD_CFLAGS)' by via the top-level Makefile.
> >
> > The x86 real-mode makefile builds `$(REALMODE_CFLAGS)' from a
> > plain assignment and therefore drops the Clang flags. This causes
> > Clang to not recognize x86-specific assembler directives:
> >
> > arch/x86/realmode/rm/header.S:36:1: error: unknown directive
> > .type real_mode_header STT_OBJECT ; .size real_mode_header, .-real_mode_header
> > ^
> >
> > Explicit propagation of `$(CLANG_FLAGS)' to `$(REALMODE_CFLAGS)',
> > which is inherited by real-mode make rules, fixes cross-compilation
> > with Clang for x86 targets.
> >
> > Relevant flags:
> >
> > * `--target' sets the target architecture when cross-compiling. This
> > flag must be set for both compilation and assembly (`KBUILD_AFLAGS')
> > to support architecture-specific assembler directives.
> >
> > * `-no-integrated-as' tells clang to assemble with GNU Assembler
> > instead of its built-in LLVM assembler. This flag is set by default
> > unless `LLVM_IAS=1' is set, because the LLVM assembler can't yet
> > parse certain GNU extensions.
> >
> > Signed-off-by: John Millikin <[email protected]>
> > ---
> > Changes in v2:
> > - Reworded the commit message to highlight that this is for
> > cross-compilation.
> > - Removed the `ifdef CONFIG_CC_IS_CLANG' guard.
> >
> > arch/x86/Makefile | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/arch/x86/Makefile b/arch/x86/Makefile
> > index 7116da3980be..412b849063ec 100644
> > --- a/arch/x86/Makefile
> > +++ b/arch/x86/Makefile
> > @@ -33,6 +33,7 @@ REALMODE_CFLAGS += -ffreestanding
> > REALMODE_CFLAGS += -fno-stack-protector
>
> This one too:
>
> checking file arch/x86/Makefile
> patch: **** malformed patch at line 62: REALMODE_CFLAGS += -fno-stack-protector
>

I needed to touch this as it was "malformed" and did not apply cleanly.

If it is not too late, feel free to add my:

Tested-by: Sedat Dilek <[email protected]>

- Sedat -