armv7 R_ARM_PREL31 relocation out of range error when loading module

Ard Biesheuvel ardb at kernel.org
Wed Sep 17 03:10:55 PDT 2025


On Wed, 17 Sept 2025 at 04:55, William Zhang <william.zhang at broadcom.com> wrote:
>
> Hi,
>
> We recently ran into the driver loading error resulting from
> apply_relocate function when it handle the R_ARM_PREL31 case in
> arch/arm/kernel/module.c:
> section 29 reloc 0 sym '': relocation 42 out of range (0xc2ab9be8 ->
> 0x7fad5998)
>
> After some dig, it seems this issue is caused by this change:
> ac3b43283923 ("module: replace module_layout with module_memory")
>
> I can see the necessity of this change but it seems it can cause this
> kind of error under certain configurations. In our particular case, we
> use the 2G/2G split and our armv7 board has 1GB ddr memory. This means
> the kernel lower memory is from 0x8000-0000 to 0xc000-0000 and vmalloc
> range is from 0xc000-0000 and above.
>
> Before this module layout change, the module is loaded through two
> layout sections: core and init. The driver in the test is fairly big
> and core module layout(text, data, rodata, sections) can not fit into
> the 16MB MODULE memory so both text, data and rodata fallback to
> vmalloc range. But with this change, it will text, data and rodata one
> by one. So it ends up text in the MODULES memory but rodata is
> allocated in VMALLOC and the distance is more than 1GB hence we
> believe it causes the above error when R_ARM_PREL31 relocation can not
> support more than 1GB offset.
>
> Since the default split is 1G/3G model, the distance between vmalloc
> and module memory is always below 1G so we won't see this issue. But
> it seems to us the problem is real when use 2G/2G split.
>
> It appears the sections containing R_ARM_PREL31 in our driver are
> mostly in .ARM.exidx section. Some search shows this is used by ARM
> C++ exception handling but our driver does not use C++. Is there a way
> to disable such section for R_ARM_PREL31? If not, is there any
> workaround or fix to handle this run-time R_ARM_PREL31 relocation
> issue? The same apply_relocate function can handle R_ARM_JUMP24 out of
> range using PLTS. Can this apply to R_ARM_PREL31?
>

Hi William,

Two options come to mind:

1) use the frame pointer for unwind information instead of the C++
exception metadata, i.e., enable CONFIG_UNWINDER_FRAME_POINTER

2) ensure that ARM.exidx sections are allocated from the same bucket
as the .text sections they annotate, e.g., something like the below

--- a/arch/arm/kernel/module-plts.c
+++ b/arch/arm/kernel/module-plts.c
@@ -225,6 +225,11 @@
                        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)
+                       s->sh_flags |= SHF_EXECINSTR;
+#endif
+
        }

        if (!mod->arch.core.plt || !mod->arch.init.plt) {



More information about the linux-arm-kernel mailing list