aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/module.c')
-rw-r--r--arch/arm/kernel/module.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 4f14b5ce6535..80254b47dc34 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -155,8 +155,17 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
155 break; 155 break;
156 156
157 case R_ARM_PREL31: 157 case R_ARM_PREL31:
158 offset = *(u32 *)loc + sym->st_value - loc; 158 offset = (*(s32 *)loc << 1) >> 1; /* sign extend */
159 *(u32 *)loc = offset & 0x7fffffff; 159 offset += sym->st_value - loc;
160 if (offset >= 0x40000000 || offset < -0x40000000) {
161 pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
162 module->name, relindex, i, symname,
163 ELF32_R_TYPE(rel->r_info), loc,
164 sym->st_value);
165 return -ENOEXEC;
166 }
167 *(u32 *)loc &= 0x80000000;
168 *(u32 *)loc |= offset & 0x7fffffff;
160 break; 169 break;
161 170
162 case R_ARM_MOVW_ABS_NC: 171 case R_ARM_MOVW_ABS_NC: