Skip to contentSkip to conversation

Fix cross compiling x86 with clang

PATCH Applied Nathan Chancellor 5 participants 10 messages Mar 26, 2021

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover Fix cross compiling x86 with clang

Hi all,

This series fixes cross compiling x86 with clang, which was initially brought up by John here:

https://lore.kernel.org/r/[email protected]/

I have picked up that patch and added the same fix in a couple of other places where it is needed.

I have tested this on an ARM based server with both defconfig and allmodconfig, where the build now passes.

Please let me know if there are any problems.

Cheers,
Nathan

John Millikin (1):
x86: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

Nathan Chancellor (2):
x86/boot: Add $(CLANG_FLAGS) to compressed KBUILD_CFLAGS efi/libstub: Add $(CLANG_FLAGS) to x86 flags

 arch/x86/Makefile                     | 1 +
 arch/x86/boot/compressed/Makefile     | 1 +
 drivers/firmware/efi/libstub/Makefile | 3 ++-
 3 files changed, 4 insertions(+), 1 deletion(-)

base-commit: 0d02ec6b3136c73c09e7859f0d0e4e2c4c07b49b

Signature · 1 line
2.31.0
#1 lore raw

PATCH 1/3 x86: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

From: John Millikin <[email protected]>

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.

---
 arch/x86/Makefile | 1 +
 1 file changed, 1 insertion(+)
arch/x86/Makefile +1 -0
index 2d6d5a28c3bf..9a73e0cea19c 100644
@@ -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
Signature · 1 line
2.31.0
Tested-by on v1 1/3
#2 lore raw

Re: [PATCH 1/3] x86: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

Quoted 26 lines · Nathan Chancellor

From: John Millikin <[email protected]>

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.

Quoted 8 lines

* -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.

I had John's v2 of this patch in my custom 5.11 patchset. Thanks for bringing this up again, Nathan.

Later, I will test the triple patchset series.

Feel free to add for this one:

- Sedat -

Quoted 19 lines
---
 arch/x86/Makefile | 1 +
 1 file changed, 1 insertion(+)
arch/x86/Makefile +1 -1
index 2d6d5a28c3bf..9a73e0cea19c 100644
@@ -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.31.0

merge bot Applied
#3 lore raw

[tip: x86/build] x86/build: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

In reply to Nathan Chancellor
The following commit has been merged into the x86/build branch of tip:

The following commit has been merged into the x86/build branch of tip:

Commit-ID:     8abe7fc26ad8f28bfdf78adbed56acd1fa93f82d
Gitweb:        https://git.kernel.org/tip/8abe7fc26ad8f28bfdf78adbed56acd1fa93f82d
Author:        John Millikin <[email protected]>
AuthorDate:    Thu, 25 Mar 2021 17:04:33 -07:00
Committer:     Borislav Petkov <[email protected]>
CommitterDate: Fri, 26 Mar 2021 11:32:47 +01:00

x86/build: 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)' 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.

---
 arch/x86/Makefile | 1 +
 1 file changed, 1 insertion(+)
arch/x86/Makefile +1 -0
index 2d6d5a2..9a73e0c 100644
@@ -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
#4 lore raw

Re: [PATCH 1/3] x86: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

In reply to Nathan Chancellor
Quoted 43 lines · Nathan Chancellor

From: John Millikin <[email protected]>

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.

---
 arch/x86/Makefile | 1 +
 1 file changed, 1 insertion(+)
arch/x86/Makefile +0 -0
index 2d6d5a28c3bf..9a73e0cea19c 100644

arch/x86/Makefile REALMODE_CFLAGS += -ffreestanding · line 39

Quoted 7 lines
arch/x86/Makefile +1 -0
@@ -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

Just wanted to say "thank you" for picking this up -- I ran into some real-life situations and didn't have time to debug why my patch was failing the Git validity check (presumed to be an email client misconfiguration).

#5 lore raw

PATCH 2/3 x86/boot: Add $(CLANG_FLAGS) to compressed KBUILD_CFLAGS

In reply to Nathan Chancellor

When cross compiling x86 on an ARM machine with clang, there are several errors along the lines of:

arch/x86/include/asm/string_64.h:27:10: error: invalid output constraint '=&c' in asm

This happens because the compressed boot Makefile reassigns KBUILD_CFLAGS and drops the clang flags that set the target architecture ('--target=') and the path to the GNU cross tools ('--prefix='), meaning that the host architecture is targeted.

These flags are available as $(CLANG_FLAGS) from the main Makefile so add them to the compressed boot folder's KBUILD_CFLAGS so that cross compiling works as expected.

---
 arch/x86/boot/compressed/Makefile | 1 +
 1 file changed, 1 insertion(+)
arch/x86/boot/compressed/Makefile +1 -0
index e0bc3988c3fa..6e5522aebbbd 100644
@@ -46,6 +46,7 @@ KBUILD_CFLAGS += -D__DISABLE_EXPORTS
 # Disable relocation relaxation in case the link is not PIE.
 KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mrelax-relocations=no)
 KBUILD_CFLAGS += -include $(srctree)/include/linux/hidden.h
+KBUILD_CFLAGS += $(CLANG_FLAGS)
 
 # sev-es.c indirectly inludes inat-table.h which is generated during
 # compilation and stored in $(objtree). Add the directory to the includes so
Signature · 1 line
2.31.0
#6 lore raw

[tip: x86/build] x86/boot: Add $(CLANG_FLAGS) to compressed KBUILD_CFLAGS

The following commit has been merged into the x86/build branch of tip:

The following commit has been merged into the x86/build branch of tip:

Commit-ID:     d5cbd80e302dfea59726c44c56ab7957f822409f
Gitweb:        https://git.kernel.org/tip/d5cbd80e302dfea59726c44c56ab7957f822409f
Author:        Nathan Chancellor <[email protected]>
AuthorDate:    Thu, 25 Mar 2021 17:04:34 -07:00
Committer:     Borislav Petkov <[email protected]>
CommitterDate: Fri, 26 Mar 2021 11:32:55 +01:00

x86/boot: Add $(CLANG_FLAGS) to compressed KBUILD_CFLAGS

When cross compiling x86 on an ARM machine with clang, there are several errors along the lines of:

arch/x86/include/asm/string_64.h:27:10: error: invalid output constraint '=&c' in asm

This happens because the compressed boot Makefile reassigns KBUILD_CFLAGS and drops the clang flags that set the target architecture ('--target=') and the path to the GNU cross tools ('--prefix='), meaning that the host architecture is targeted.

These flags are available as $(CLANG_FLAGS) from the main Makefile so add them to the compressed boot folder's KBUILD_CFLAGS so that cross compiling works as expected.

---
 arch/x86/boot/compressed/Makefile | 1 +
 1 file changed, 1 insertion(+)
arch/x86/boot/compressed/Makefile +1 -0
index e0bc398..6e5522a 100644
@@ -46,6 +46,7 @@ KBUILD_CFLAGS += -D__DISABLE_EXPORTS
 # Disable relocation relaxation in case the link is not PIE.
 KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mrelax-relocations=no)
 KBUILD_CFLAGS += -include $(srctree)/include/linux/hidden.h
+KBUILD_CFLAGS += $(CLANG_FLAGS)
 
 # sev-es.c indirectly inludes inat-table.h which is generated during
 # compilation and stored in $(objtree). Add the directory to the includes so
#7 lore raw

PATCH 3/3 efi/libstub: Add $(CLANG_FLAGS) to x86 flags

In reply to Nathan Chancellor

When cross compiling x86 on an ARM machine with clang, there are several errors along the lines of:

arch/x86/include/asm/page_64.h:52:7: error: invalid output constraint '=D' in asm

This happens because the x86 flags in the EFI stub are not derived from KBUILD_CFLAGS like the other architectures are and the clang flags that set the target architecture ('--target=') and the path to the GNU cross tools ('--prefix=') are not present, meaning that the host architecture is targeted.

These flags are available as $(CLANG_FLAGS) from the main Makefile so add them to the cflags for x86 so that cross compiling works as expected.

---
 drivers/firmware/efi/libstub/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/firmware/efi/libstub/Makefile +2 -1
index c23466e05e60..d0537573501e 100644
@@ -13,7 +13,8 @@ cflags-$(CONFIG_X86)		+= -m$(BITS) -D__KERNEL__ \
 				   -Wno-pointer-sign \
 				   $(call cc-disable-warning, address-of-packed-member) \
 				   $(call cc-disable-warning, gnu) \
-				   -fno-asynchronous-unwind-tables
+				   -fno-asynchronous-unwind-tables \
+				   $(CLANG_FLAGS)
 
 # arm64 uses the full KBUILD_CFLAGS so it's necessary to explicitly
 # disable the stackleak plugin
Signature · 1 line
2.31.0
#8 lore raw

[tip: x86/build] efi/libstub: Add $(CLANG_FLAGS) to x86 flags

The following commit has been merged into the x86/build branch of tip:

The following commit has been merged into the x86/build branch of tip:

Commit-ID:     58d746c119dfa28e72fc35aacaf3d2a3ac625cd0
Gitweb:        https://git.kernel.org/tip/58d746c119dfa28e72fc35aacaf3d2a3ac625cd0
Author:        Nathan Chancellor <[email protected]>
AuthorDate:    Thu, 25 Mar 2021 17:04:35 -07:00
Committer:     Borislav Petkov <[email protected]>
CommitterDate: Fri, 26 Mar 2021 11:34:58 +01:00

efi/libstub: Add $(CLANG_FLAGS) to x86 flags

When cross compiling x86 on an ARM machine with clang, there are several errors along the lines of:

arch/x86/include/asm/page_64.h:52:7: error: invalid output constraint '=D' in asm

This happens because the x86 flags in the EFI stub are not derived from KBUILD_CFLAGS like the other architectures are and the clang flags that set the target architecture ('--target=') and the path to the GNU cross tools ('--prefix=') are not present, meaning that the host architecture is targeted.

These flags are available as $(CLANG_FLAGS) from the main Makefile so add them to the cflags for x86 so that cross compiling works as expected.

---
 drivers/firmware/efi/libstub/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/firmware/efi/libstub/Makefile +2 -1
index c23466e..d053757 100644
@@ -13,7 +13,8 @@ cflags-$(CONFIG_X86)		+= -m$(BITS) -D__KERNEL__ \
 				   -Wno-pointer-sign \
 				   $(call cc-disable-warning, address-of-packed-member) \
 				   $(call cc-disable-warning, gnu) \
-				   -fno-asynchronous-unwind-tables
+				   -fno-asynchronous-unwind-tables \
+				   $(CLANG_FLAGS)
 
 # arm64 uses the full KBUILD_CFLAGS so it's necessary to explicitly
 # disable the stackleak plugin
maintainer Acked-by on the v1 series
#9 lore raw
In reply to Nathan Chancellor
Quoted 19 lines · Nathan Chancellor

Hi all,

This series fixes cross compiling x86 with clang, which was initially brought up by John here:

https://lore.kernel.org/r/[email protected]/

I have picked up that patch and added the same fix in a couple of other places where it is needed.

I have tested this on an ARM based server with both defconfig and allmodconfig, where the build now passes.

Please let me know if there are any problems.

Cheers,
Nathan

Quoted 7 lines

John Millikin (1):
x86: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS)

Nathan Chancellor (2):
x86/boot: Add $(CLANG_FLAGS) to compressed KBUILD_CFLAGS efi/libstub: Add $(CLANG_FLAGS) to x86 flags

Quoted 10 lines
 arch/x86/Makefile                     | 1 +
 arch/x86/boot/compressed/Makefile     | 1 +
 drivers/firmware/efi/libstub/Makefile | 3 ++-
 3 files changed, 4 insertions(+), 1 deletion(-)

base-commit: 0d02ec6b3136c73c09e7859f0d0e4e2c4c07b49b --
2.31.0