summaryrefslogtreecommitdiffstats
path: root/scripts/mod/modpost.h
diff options
context:
space:
mode:
authorMasahiro Yamada <masahiroy@kernel.org>2024-12-25 16:33:37 +0100
committerMasahiro Yamada <masahiroy@kernel.org>2024-12-28 15:31:09 +0100
commit8fe1a63d3d99d86f1bdc034505aad6fc70424737 (patch)
treeb21803dee7aff501a86e6be194c1812ac3178b14 /scripts/mod/modpost.h
parentmodpost: refactor do_vmbus_entry() (diff)
downloadlinux-8fe1a63d3d99d86f1bdc034505aad6fc70424737.tar.xz
linux-8fe1a63d3d99d86f1bdc034505aad6fc70424737.zip
modpost: work around unaligned data access error
With the latest binutils, modpost fails with a bus error on some architectures such as ARM and sparc64. Since binutils commit 1f1b5e506bf0 ("bfd/ELF: restrict file alignment for object files"), the byte offset to each section (sh_offset) in relocatable ELF is no longer guaranteed to be aligned. modpost parses MODULE_DEVICE_TABLE() data structures, which are usually located in the .rodata section. If it is not properly aligned, unaligned access errors may occur. To address the issue, this commit imports the get_unaligned() helper from include/linux/unaligned.h. The get_unaligned_native() helper caters to the endianness in addition to handling the unaligned access. I slightly refactored do_pcmcia_entry() and do_input() to avoid writing back to an unaligned address. (We would need the put_unaligned() helper to do that.) The addend_*_rel() functions need similar adjustments because the .text sections are not aligned either. It seems that the .symtab, .rel.* and .rela.* sections are still aligned. Keep normal pointer access for these sections to avoid unnecessary performance costs. Reported-by: Paulo Pisati <paolo.pisati@canonical.com> Reported-by: Matthias Klose <doko@debian.org> Closes: https://sourceware.org/bugzilla/show_bug.cgi?id=32435 Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> Closes: https://sourceware.org/bugzilla/show_bug.cgi?id=32493 Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Tested-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Diffstat (limited to 'scripts/mod/modpost.h')
-rw-r--r--scripts/mod/modpost.h14
1 files changed, 14 insertions, 0 deletions
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 8b72c227ebf4..ffd0a52a606e 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -65,6 +65,20 @@
#define TO_NATIVE(x) \
(target_is_big_endian == host_is_big_endian ? x : bswap(x))
+#define __get_unaligned_t(type, ptr) ({ \
+ const struct { type x; } __attribute__((__packed__)) *__pptr = \
+ (typeof(__pptr))(ptr); \
+ __pptr->x; \
+})
+
+#define get_unaligned(ptr) __get_unaligned_t(typeof(*(ptr)), (ptr))
+
+#define get_unaligned_native(ptr) \
+({ \
+ typeof(*(ptr)) _val = get_unaligned(ptr); \
+ TO_NATIVE(_val); \
+})
+
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)