]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ARM: 9471/1: module: fix unwind section relocation out of range error
authorWilliam Zhang <william.zhang@broadcom.com>
Thu, 2 Apr 2026 01:43:25 +0000 (02:43 +0100)
committerRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Thu, 9 Apr 2026 10:51:52 +0000 (11:51 +0100)
In an armv7 system that uses non-3G/1G split and with more than 512MB physical memory, driver load may fail with following error:
   section 29 reloc 0 sym '': relocation 42 out of range (0xc2ab9be8 ->
0x7fad5998)

This happens when relocation R_ARM_PREL31 from the unwind section
.ARM.extab and .ARM.exidx are allocated from the VMALLOC space while
.text section is from MODULES_VADDR space. It exceeds the +/-1GB
relocation requirement of R_ARM_PREL31 hence triggers the error.

The fix is to mark .ARM.extab and .ARM.exidx sections as executable so
they can be allocated along with .text section and always meet range
requirement.

Co-developed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: William Zhang <william.zhang@broadcom.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
arch/arm/kernel/module-plts.c

index 354ce16d83cb5ac1734af9bf0eff1f7f8e15f9f4..b5338fe59706a8c7cbeeef593fbfbfd11ec418d7 100644 (file)
@@ -225,6 +225,18 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
                        mod->arch.init.plt = s;
                else if (s->sh_type == SHT_SYMTAB)
                        syms = (Elf32_Sym *)s->sh_addr;
+#if defined(CONFIG_ARM_UNWIND) && !defined(CONFIG_VMSPLIT_3G)
+               else if (s->sh_type == ELF_SECTION_UNWIND ||
+                        (strncmp(".ARM.extab", secstrings + s->sh_name, 10) == 0)) {
+                       /*
+                        * To avoid the possible relocation out of range issue for
+                        * R_ARM_PREL31, mark unwind section .ARM.extab and .ARM.exidx as
+                        * executable so they will be allocated along with .text section to
+                        * meet +/-1GB range requirement of the R_ARM_PREL31 relocation
+                        */
+                       s->sh_flags |= SHF_EXECINSTR;
+               }
+#endif
        }
 
        if (!mod->arch.core.plt || !mod->arch.init.plt) {