summaryrefslogtreecommitdiffstats
path: root/arch/arm/lib32/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/lib32/module.c')
-rw-r--r--arch/arm/lib32/module.c29
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) {