Skip to content

Improve BUILD_BUG_ON error message with clang #1173

@pcc

Description

@pcc

With clang BUILD_BUG_ON failures only appear at link time due to a lack of support for __attribute__((error)). The error messages look like this:

ld.lld: error: undefined symbol: __compiletime_assert_296
>>> referenced by signal_compat.c
>>>               kernel/signal_compat.o:(sigaction_compat_abi) in archive arch/x86/built-in.a

and it can be hard to trace them back to the caller.

I had the idea of putting the error message in the symbol name so that it survives until link time. Here's a quick proof of concept:

diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h
index 4e035aca6f7e..f553ad004e5b 100644
--- a/include/linux/bitfield.h
+++ b/include/linux/bitfield.h
@@ -109,10 +109,9 @@
                (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
        })
 
-extern void __compiletime_error("value doesn't fit into mask")
-__field_overflow(void);
-extern void __compiletime_error("bad bitfield mask")
-__bad_mask(void);
+extern void __field_overflow(void)
+       __compiletime_error("value doesn't fit into mask");
+extern void __bad_mask(void) __compiletime_error("bad bitfield mask");
 static __always_inline u64 field_multiplier(u64 field)
 {
        if ((field | (field - 1)) & ((field | (field - 1)) + 1))
diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h
index cee0c728d39a..f4ad81f6f75e 100644
--- a/include/linux/compiler-clang.h
+++ b/include/linux/compiler-clang.h
@@ -61,3 +61,5 @@
 #if __has_feature(shadow_call_stack)
 # define __noscs       __attribute__((__no_sanitize__("shadow-call-stack")))
 #endif
+
+#define __compiletime_error(msg) __asm__(msg)
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index e93e249a4e9b..e6476b1be8cc 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -124,10 +124,10 @@ static inline void check_object_size(const void *ptr, unsigned long n,
 { }
 #endif /* CONFIG_HARDENED_USERCOPY */
 
-extern void __compiletime_error("copy source size is too small")
-__bad_copy_from(void);
-extern void __compiletime_error("copy destination size is too small")
-__bad_copy_to(void);
+extern void __bad_copy_from(void)
+       __compiletime_error("copy source size is too small");
+extern void __bad_copy_to(void)
+       __compiletime_error("copy destination size is too small");
 
 static inline void copy_overflow(int size, unsigned long count)
 {

With that and an artificial BUILD_BUG_ON failure injected into the kernel:

diff --git a/arch/x86/kernel/signal_compat.c b/arch/x86/kernel/signal_compat.c
index 862e69f6054f..5dfba690cf6b 100644
--- a/arch/x86/kernel/signal_compat.c
+++ b/arch/x86/kernel/signal_compat.c
@@ -164,7 +164,7 @@ static inline void signal_compat_build_tests(void)
        BUILD_BUG_ON(offsetof(siginfo_t, si_arch)      != 0x1C);
        BUILD_BUG_ON(offsetof(compat_siginfo_t, si_call_addr) != 0x0C);
        BUILD_BUG_ON(offsetof(compat_siginfo_t, si_syscall)   != 0x10);
-       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_arch)      != 0x14);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_arch)      != 0x18);
 
        /* any new si_fields should be added here */
 }

the error message looks like this:

ld.lld: error: undefined symbol: BUILD_BUG_ON failed: offsetof(compat_siginfo_t, si_arch) != 0x18
>>> referenced by signal_compat.c
>>>               kernel/signal_compat.o:(sigaction_compat_abi) in archive arch/x86/built-in.a

Not perfect but at least you can see the error message. It does require LLVM_IAS=1 because GNU as doesn't like these weird symbol names. I don't know if the kernel folks will go for this though.

Metadata

Metadata

Labels

Reported upstreamThis bug was filed on LLVM’s issue tracker, Phabricator, or the kernel mailing list.[FIXED][LINUX] 5.15This bug was fixed in Linux 5.15[FIXED][LLVM] 14This bug was fixed in LLVM 14.xfeature-requestNot a bug per-se

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions