16 #include <linux/module.h>
18 #include <linux/elf.h>
21 #include <linux/string.h>
22 #include <linux/kernel.h>
28 decode_calln_opcode (
unsigned char *
location)
31 return (location[0] & 0xf0) == 0x50;
34 return (location[0] & 0xf) == 0x5;
39 decode_l32r_opcode (
unsigned char *location)
42 return (location[0] & 0xf0) == 0x10;
45 return (location[0] & 0xf) == 0x1;
51 unsigned int symindex,
56 Elf32_Rela *rela = (
void *)sechdrs[relsec].sh_addr;
62 printk(
"Applying relocate section %u to %u\n", relsec,
63 sechdrs[relsec].sh_info);
65 for (i = 0; i < sechdrs[relsec].
sh_size /
sizeof(*rela); i++) {
66 location = (
char *)sechdrs[sechdrs[relsec].sh_info].sh_addr
68 sym = (
Elf32_Sym *)sechdrs[symindex].sh_addr
86 if (decode_calln_opcode(location)) {
87 value -= ((
unsigned long)location & -4) + 4;
88 if ((value & 3) != 0 ||
89 ((value + (1 << 19)) >> 20) != 0) {
90 printk(
"%s: relocation out of range, "
91 "section %d reloc %d "
97 value = (
signed int)value >> 2;
99 location[0] = ((location[0] & ~0x3) |
100 ((value >> 16) & 0x3));
101 location[1] = (value >> 8) & 0xff;
102 location[2] = value & 0xff;
105 location[0] = ((location[0] & ~0xc0) |
106 ((value << 6) & 0xc0));
107 location[1] = (value >> 2) & 0xff;
108 location[2] = (value >> 10) & 0xff;
110 }
else if (decode_l32r_opcode(location)) {
111 value -= (((
unsigned long)location + 3) & -4);
112 if ((value & 3) != 0 ||
113 (
signed int)value >> 18 != -1) {
114 printk(
"%s: relocation out of range, "
115 "section %d reloc %d "
117 mod->
name, relsec, i,
121 value = (
signed int)value >> 2;
124 location[1] = (value >> 8) & 0xff;
125 location[2] = value & 0xff;
128 location[1] = value & 0xff;
129 location[2] = (value >> 8) & 0xff;
159 printk(
"%s: unexpected FLIX relocation: %u\n",
179 printk(
"%s: unexpected ALT relocation: %u\n",
185 printk(
"%s: unexpected relocation: %u\n",