diff options
Diffstat (limited to 'arch/arm/lib32/module.c')
-rw-r--r-- | arch/arm/lib32/module.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/arch/arm/lib32/module.c b/arch/arm/lib32/module.c index be7965d59c..7214e3c73c 100644 --- a/arch/arm/lib32/module.c +++ b/arch/arm/lib32/module.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: 2002 Russell King + /* - * linux/arch/arm/kernel/module.c - * - * Copyright (C) 2002 Russell King. - * Modified for nommu by Hyok S. Choi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. + * linux/arch/arm/kernel/module.c * + * Modified for nommu by Hyok S. Choi * Module allocation method suggested by Andi Kleen. */ @@ -41,7 +38,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, sym = ((Elf32_Sym *)symsec->sh_addr) + offset; - if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) { + if (rel->r_offset > dstsec->sh_size - sizeof(u32)) { printf("%s: out of bounds relocation, " "section %u reloc %u offset %d size %d\n", module->name, relindex, i, rel->r_offset, @@ -64,6 +61,20 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, offset -= 0x04000000; offset += sym->st_value - loc; + + /* + * Route through a PLT entry if 'offset' exceeds the + * supported range. Note that 'offset + loc + 8' + * contains the absolute jump target, i.e., + * @sym + addend, corrected for the +8 PC bias. + */ + if (IS_ENABLED(CONFIG_ARM_MODULE_PLTS) && + (offset <= (s32)0xfe000000 || + offset >= (s32)0x02000000)) + offset = get_module_plt(module, loc, + offset + loc + 8) + - loc - 8; + if (offset & 3 || offset <= (s32)0xfe000000 || offset >= (s32)0x02000000) { |