Hi all,
I encountered an error while compiling Linux kernel 5.3 to IR.
My LLVM version is 9.0.0 release.
This error said "invalid operand for inline asm constraint 'i'" in
arch/x86/include/asm/jump_table.h.
The source code is
static __always_inline bool arch_static_branch(struct static_key *key,
bool branch)
{
asm_volatile_goto("1:"
".byte " __stringify(STATIC_KEY_INIT_NOP) "\n\t"
".pushsection __jump_table, \"aw\" \n\t"
_ASM_ALIGN "\n\t"
".long 1b - ., %l[l_yes] - . \n\t"
_ASM_PTR "%c0 + %c1 - .\n\t"
".popsection \n\t"
: : "i" (key), "i" (branch) : : l_yes);
return false;
l_yes:
return true;
}
The error pointed to asm_volatile_goto("1:"
I'm not sure whether this error is related to asm goto support.
Hi Will,
I'm adding cfe-dev since this potentially covers both areas.
I encountered an error while compiling Linux kernel 5.3 to IR.
My LLVM version is 9.0.0 release.
The error message you quote can only be emitted after LLVM has started
turning IR into machine code. What's the actual Clang command that
produces this error?
This error said "invalid operand for inline asm constraint 'i'" in
arch/x86/include/asm/jump_table.h.
This is a pretty fragile use of that constraint, since it's declaring
that something must be a constant when that can only happen via
optimizations. I'm not convinced that's what's going on here though.
Kernels aren't usually compiled at -O0 and I think I trust the Linux
developers to make sure users are passing an obvious constant.
Hi Will,
I'm adding cfe-dev since this potentially covers both areas.
> I encountered an error while compiling Linux kernel 5.3 to IR.
> My LLVM version is 9.0.0 release.
The error message you quote can only be emitted after LLVM has started
turning IR into machine code. What's the actual Clang command that
produces this error?
I have checked the building process and find the error actually happened when
building a .o file, which is fs/nfs/flexfilelayout/flexfilelayout.o.
The Clang command is:
clang -Wp,-MD,fs/nfs/flexfilelayout/.flexfilelayout.o.d -nostdinc
-isystem /usr/local/lib/clang/9.0.0/include -I./arch/x86/include
-I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi
-I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi
-include ./include/linux/kconfig.h -include ./include/linux/compiler_types.h
-D__KERNEL__ -Qunused-arguments -Wall -Wundef -Werror=strict-prototypes
-Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE
-Werror=implicit-function-declaration -Werror=implicit-int -Wno-format-security
-std=gnu89 -no-integrated-as -Werror=unknown-warning-option -mno-sse
-mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -mno-80387 -mstack-alignment=8
-mtune=generic -mno-red-zone -mcmodel=kernel -DCONFIG_X86_X32_ABI
-DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1
-DCONFIG_AS_SSSE3=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1
-DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1
-Wno-sign-compare -fno-asynchronous-unwind-tables -mretpoline-external-thunk
-fno-delete-null-pointer-checks -Wno-address-of-packed-member -O0
-Wframe-larger-than=2048 -fstack-protector-strong -Wno-format-invalid-specifier
-Wno-gnu -Wno-tautological-compare -mno-global-merge -Wno-unused-const-variable
-fomit-frame-pointer -ftrivial-auto-var-init=pattern -g
-Wdeclaration-after-statement
-Wimplicit-fallthrough -Wvla -Wno-pointer-sign -fno-strict-overflow
-fno-merge-all-constants
-fno-stack-check -Werror=date-time -Werror=incompatible-pointer-types
-fcf-protection=none -Wno-initializer-overrides -Wno-format -Wno-sign-compare
-Wno-format-zero-length -DMODULE -DKBUILD_BASENAME='"flexfilelayout"'
-DKBUILD_MODNAME='"nfs_layout_flexfiles"' -c -o
fs/nfs/flexfilelayout/flexfilelayout.o fs/nfs/flexfilelayout/flexfilelayout.c
> This error said "invalid operand for inline asm constraint 'i'" in
> arch/x86/include/asm/jump_table.h.
This is a pretty fragile use of that constraint, since it's declaring
that something must be a constant when that can only happen via
optimizations. I'm not convinced that's what's going on here though.
Kernels aren't usually compiled at -O0 and I think I trust the Linux
developers to make sure users are passing an obvious constant.
I am doing an analysis of kernel, therefore I use -O0 to keep details of
source code.
Ah, these two together are probably not going to work with the code as
written (even GCC errors out on similar test-cases I've tried). You're
either going to have to avoid O0 when producing a .o file or modify
the source so it works (maybe by converting the function to a macro),
but I wouldn't be surprised if you hit other issues on that route.
Cheers.
Tim.
This is not expected to work, and does not. The kernel can only be compiled with optimizations on. That’s not a clang bug – that’s just how the kernel has been written, unfortunately.