|
@@ -155,8 +155,17 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
|
|
|
break;
|
|
|
|
|
|
case R_ARM_PREL31:
|
|
|
- offset = *(u32 *)loc + sym->st_value - loc;
|
|
|
- *(u32 *)loc = offset & 0x7fffffff;
|
|
|
+ offset = (*(s32 *)loc << 1) >> 1; /* sign extend */
|
|
|
+ offset += sym->st_value - loc;
|
|
|
+ if (offset >= 0x40000000 || offset < -0x40000000) {
|
|
|
+ pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
|
|
|
+ module->name, relindex, i, symname,
|
|
|
+ ELF32_R_TYPE(rel->r_info), loc,
|
|
|
+ sym->st_value);
|
|
|
+ return -ENOEXEC;
|
|
|
+ }
|
|
|
+ *(u32 *)loc &= 0x80000000;
|
|
|
+ *(u32 *)loc |= offset & 0x7fffffff;
|
|
|
break;
|
|
|
|
|
|
case R_ARM_MOVW_ABS_NC:
|