19 #include <linux/elf.h>
22 #include <linux/string.h>
23 #include <linux/kernel.h>
24 #include <linux/slab.h>
29 #define DEBUGP(fmt...)
52 for (g = chains + r_sym; g ; g = g->
next)
66 chains[r_sym].
next = g;
77 char *secstrings,
struct module *me)
82 unsigned long nsyms, nrela,
i;
84 esechdrs = sechdrs + hdr->
e_shnum;
90 for (s = sechdrs; s < esechdrs; ++
s)
95 me->arch.gotsecindex = s - sechdrs;
111 "module %s: no memory for symbol chain buffer\n",
122 for (s = sechdrs; s < esechdrs; ++
s)
126 for (i = 0; i < nrela; ++
i)
127 process_reloc_for_got(rela+i, chains,
132 for (i = 0; i < nsyms; ++
i) {
134 for (g = chains[i].
next; g ; g =
n) {
146 unsigned int symindex,
unsigned int relsec,
149 Elf64_Rela *rela = (
void *)sechdrs[relsec].sh_addr;
150 unsigned long i,
n = sechdrs[relsec].
sh_size /
sizeof(*rela);
153 unsigned long got,
gp;
155 DEBUGP(
"Applying relocate section %u to %u\n", relsec,
156 sechdrs[relsec].sh_info);
158 base = (
void *)sechdrs[sechdrs[relsec].sh_info].sh_addr;
159 symtab = (
Elf64_Sym *)sechdrs[symindex].sh_addr;
163 gp = (
u64)me->module_core + me->core_size - 0x8000;
164 got = sechdrs[me->arch.gotsecindex].
sh_addr;
166 for (i = 0; i <
n; i++) {
167 unsigned long r_sym =
ELF64_R_SYM (rela[i].r_info);
169 unsigned long r_got_offset = r_type >> 8;
178 sym = symtab + r_sym;
187 ((
u32 *)location)[1] = value >> 32;
191 if ((
int)value !=
value)
193 *(
u32 *)location = value;
196 hi = got + r_got_offset;
200 *(
u16 *)location = lo;
206 value = gp - (
u64)location;
208 hi = (
int)(value - lo);
209 if (hi + lo != value)
211 *(
u16 *)location = hi >> 16;
212 *(
u16 *)(location + rela[i].r_addend) = lo;
226 value -= (
u64)location + 4;
229 value = (
long)value >> 2;
230 if (value + (1<<21) >= 1<<22)
233 value |= *(
u32 *)location & ~0x1fffff;
234 *(
u32 *)location = value;
239 value -= (
u64)location;
240 if ((
int)value !=
value)
242 *(
u32 *)location = value;
245 value -= (
u64)location;
246 *(
u64 *)location = value;
249 value = (
long)(value - gp + 0x8000) >> 16;
250 if ((
short) value !=
value)
252 *(
u16 *)location = value;
256 *(
u16 *)location = value;
260 if ((
short) value !=
value)
262 *(
u16 *)location = value;
271 "module %s: Relocation (type %lu) overflow vs section %d\n",
275 "module %s: Relocation (type %lu) overflow vs %s\n",