21 #include <linux/bitops.h>
22 #include <linux/elf.h>
24 #include <linux/kernel.h>
33 __builtin_return_address(0));
49 return val - (
u64)place;
51 return (val & ~0xfff) - ((
u64)place & ~0xfff);
56 pr_err(
"do_reloc: unknown relocation operation %d\n", reloc_op);
62 u64 imm_mask = (1 << len) - 1;
63 s64 sval = do_reloc(op, place, val);
76 pr_err(
"Invalid length (%d) for data relocation\n", len);
84 sval = (
s64)(sval & ~(imm_mask >> 1)) >> (len - 1);
91 if ((
u64)(sval + 1) > 2)
111 u32 immlo, immhi, lomask, himask,
mask;
141 immlo = imm & lomask;
143 immhi = imm & himask;
144 imm = (immlo << 24) | (immhi);
145 mask = (lomask << 24) | (himask);
173 pr_err(
"encode_insn_immediate: unknown immediate encoding %d\n",
179 insn &= ~(mask << shift);
180 insn |= (imm &
mask) << shift;
192 sval = do_reloc(op, place, val);
197 *(
u32 *)place = encode_insn_immediate(imm_type, insn, imm);
228 sval = do_reloc(op, place, val);
232 imm_mask = (
BIT(lsb + len) - 1) >> lsb;
233 imm = sval & imm_mask;
236 *(
u32 *)place = encode_insn_immediate(imm_type, insn, imm);
242 sval = (
s64)(sval & ~(imm_mask >> 1)) >> (len - 1);
248 if ((
u64)(sval + 1) >= 2)
256 unsigned int symindex,
266 Elf64_Rela *rel = (
void *)sechdrs[relsec].sh_addr;
268 for (i = 0; i < sechdrs[relsec].
sh_size /
sizeof(*rel); i++) {
270 loc = (
void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
274 sym = (
Elf64_Sym *)sechdrs[symindex].sh_addr
281 overflow_check =
true;
293 overflow_check =
false;
303 overflow_check =
false;
315 overflow_check =
false;
321 overflow_check =
false;
327 overflow_check =
false;
334 overflow_check =
false;
351 overflow_check =
false;
360 overflow_check =
false;
369 overflow_check =
false;
379 overflow_check =
false;
394 overflow_check =
false;
401 overflow_check =
false;
406 overflow_check =
false;
411 overflow_check =
false;
416 overflow_check =
false;
421 overflow_check =
false;
440 pr_err(
"module %s: unsupported RELA relocation: %llu\n",
445 if (overflow_check && ovf == -
ERANGE)
453 pr_err(
"module %s: overflow in relocation type %d val %Lx\n",