diff options
| author | Miguel Ojeda <ojeda@kernel.org> | 2026-08-16 15:32:33 +0200 |
|---|---|---|
| committer | Miguel Ojeda <ojeda@kernel.org> | 2026-08-23 21:27:17 +0200 |
| commit | 5febf432df1cfa5b25d99b54c32103fafbdd0eb9 (patch) | |
| tree | 93a1ed1d337bc53adf1e572c2586d347703b286e /lib/crc/crc32-main.c | |
| download | linux-stable-5febf432df1cfa5b25d99b54c32103fafbdd0eb9.tar.gz linux-stable-5febf432df1cfa5b25d99b54c32103fafbdd0eb9.zip | |
kbuild: rust: keep Rust objects out of Clang LTO with inline helpersgrafted
Under `CONFIG_LTO_CLANG` + `CONFIG_RUST_INLINE_HELPERS`, one may hit
`objtool` errors such as:
vmlinux.o: error: objtool: _R..._3Gsp4boot+0xd6a:
can't find jump dest instruction at .text._R..._3Gsp4boot+0x1dfd
The reason is that in such builds, the Clang invocation that compiles
the combined Rust plus helpers bitcode emits LLVM bitcode (again) --
the final code generation happens in the linker's LTO step, which the
`-mllvm` trap options passed to Clang do not reach.
This, in turn, means that unreachable traps are missing, and the
impossible paths do not merely fallthrough to the next symbol, but past
the end of their own section, since LTO builds place each function in
its own section.
Thus filter `CC_FLAGS_LTO` out of the Clang invocation, so that it always
emits machine code directly, with the traps in place.
Assisted-by: LLM
Cc: Gary Guo <gary@garyguo.net>
Cc: Boqun Feng <boqun@kernel.org>
Cc: Alice Ryhl <aliceryhl@google.com>
Cc: Matthew Maurer <mmaurer@google.com>
Cc: Josh Poimboeuf <jpoimboe@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: stable@vger.kernel.org
Fixes: 3a2486cc1da5 ("kbuild: rust: provide an option to inline C helpers into Rust")
Acked-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260816133233.197500-2-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'lib/crc/crc32-main.c')
| -rw-r--r-- | lib/crc/crc32-main.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/lib/crc/crc32-main.c b/lib/crc/crc32-main.c new file mode 100644 index 000000000..fbb90c900 --- /dev/null +++ b/lib/crc/crc32-main.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Aug 8, 2011 Bob Pearson with help from Joakim Tjernlund and George Spelvin + * cleaned up code to current version of sparse and added the slicing-by-8 + * algorithm to the closely similar existing slicing-by-4 algorithm. + * + * Oct 15, 2000 Matt Domsch <Matt_Domsch@dell.com> + * Nicer crc32 functions/docs submitted by linux@horizon.com. Thanks! + * Code was from the public domain, copyright abandoned. Code was + * subsequently included in the kernel, thus was re-licensed under the + * GNU GPL v2. + * + * Oct 12, 2000 Matt Domsch <Matt_Domsch@dell.com> + * Same crc32 function was used in 5 other places in the kernel. + * I made one version, and deleted the others. + * There are various incantations of crc32(). Some use a seed of 0 or ~0. + * Some xor at the end with ~0. The generic crc32() function takes + * seed as an argument, and doesn't xor at the end. Then individual + * users can do whatever they need. + * drivers/net/smc9194.c uses seed ~0, doesn't xor with ~0. + * fs/jffs2 uses seed 0, doesn't xor with ~0. + * fs/partitions/efi.c uses seed ~0, xor's with ~0. + */ + +/* see: Documentation/staging/crc32.rst for a description of algorithms */ + +#include <linux/crc32.h> +#include <linux/export.h> +#include <linux/module.h> +#include <linux/types.h> + +#include "crc32table.h" + +static inline u32 __maybe_unused +crc32_le_base(u32 crc, const u8 *p, size_t len) +{ + while (len--) + crc = (crc >> 8) ^ crc32table_le[(crc & 255) ^ *p++]; + return crc; +} + +static inline u32 __maybe_unused +crc32_be_base(u32 crc, const u8 *p, size_t len) +{ + while (len--) + crc = (crc << 8) ^ crc32table_be[(crc >> 24) ^ *p++]; + return crc; +} + +static inline u32 __maybe_unused +crc32c_base(u32 crc, const u8 *p, size_t len) +{ + while (len--) + crc = (crc >> 8) ^ crc32ctable_le[(crc & 255) ^ *p++]; + return crc; +} + +#ifdef CONFIG_CRC32_ARCH +#include "crc32.h" /* $(SRCARCH)/crc32.h */ + +u32 crc32_optimizations(void) +{ + return crc32_optimizations_arch(); +} +EXPORT_SYMBOL(crc32_optimizations); +#else +#define crc32_le_arch crc32_le_base +#define crc32_be_arch crc32_be_base +#define crc32c_arch crc32c_base +#endif + +u32 crc32_le(u32 crc, const void *p, size_t len) +{ + return crc32_le_arch(crc, p, len); +} +EXPORT_SYMBOL(crc32_le); + +u32 crc32_be(u32 crc, const void *p, size_t len) +{ + return crc32_be_arch(crc, p, len); +} +EXPORT_SYMBOL(crc32_be); + +u32 crc32c(u32 crc, const void *p, size_t len) +{ + return crc32c_arch(crc, p, len); +} +EXPORT_SYMBOL(crc32c); + +#ifdef crc32_mod_init_arch +static int __init crc32_mod_init(void) +{ + crc32_mod_init_arch(); + return 0; +} +subsys_initcall(crc32_mod_init); + +static void __exit crc32_mod_exit(void) +{ +} +module_exit(crc32_mod_exit); +#endif + +MODULE_DESCRIPTION("CRC32 library functions"); +MODULE_LICENSE("GPL"); |
