xref: /openbmc/linux/arch/ia64/kernel/module.c (revision 9ac8d3fb)
1 /*
2  * IA-64-specific support for kernel module loader.
3  *
4  * Copyright (C) 2003 Hewlett-Packard Co
5  *	David Mosberger-Tang <davidm@hpl.hp.com>
6  *
7  * Loosely based on patch by Rusty Russell.
8  */
9 
10 /* relocs tested so far:
11 
12    DIR64LSB
13    FPTR64LSB
14    GPREL22
15    LDXMOV
16    LDXMOV
17    LTOFF22
18    LTOFF22X
19    LTOFF22X
20    LTOFF_FPTR22
21    PCREL21B	(for br.call only; br.cond is not supported out of modules!)
22    PCREL60B	(for brl.cond only; brl.call is not supported for modules!)
23    PCREL64LSB
24    SECREL32LSB
25    SEGREL64LSB
26  */
27 
28 
29 #include <linux/kernel.h>
30 #include <linux/sched.h>
31 #include <linux/elf.h>
32 #include <linux/moduleloader.h>
33 #include <linux/string.h>
34 #include <linux/vmalloc.h>
35 
36 #include <asm/patch.h>
37 #include <asm/unaligned.h>
38 
39 #define ARCH_MODULE_DEBUG 0
40 
41 #if ARCH_MODULE_DEBUG
42 # define DEBUGP printk
43 # define inline
44 #else
45 # define DEBUGP(fmt , a...)
46 #endif
47 
48 #ifdef CONFIG_ITANIUM
49 # define USE_BRL	0
50 #else
51 # define USE_BRL	1
52 #endif
53 
54 #define MAX_LTOFF	((uint64_t) (1 << 22))	/* max. allowable linkage-table offset */
55 
56 /* Define some relocation helper macros/types: */
57 
58 #define FORMAT_SHIFT	0
59 #define FORMAT_BITS	3
60 #define FORMAT_MASK	((1 << FORMAT_BITS) - 1)
61 #define VALUE_SHIFT	3
62 #define VALUE_BITS	5
63 #define VALUE_MASK	((1 << VALUE_BITS) - 1)
64 
65 enum reloc_target_format {
66 	/* direct encoded formats: */
67 	RF_NONE = 0,
68 	RF_INSN14 = 1,
69 	RF_INSN22 = 2,
70 	RF_INSN64 = 3,
71 	RF_32MSB = 4,
72 	RF_32LSB = 5,
73 	RF_64MSB = 6,
74 	RF_64LSB = 7,
75 
76 	/* formats that cannot be directly decoded: */
77 	RF_INSN60,
78 	RF_INSN21B,	/* imm21 form 1 */
79 	RF_INSN21M,	/* imm21 form 2 */
80 	RF_INSN21F	/* imm21 form 3 */
81 };
82 
83 enum reloc_value_formula {
84 	RV_DIRECT = 4,		/* S + A */
85 	RV_GPREL = 5,		/* @gprel(S + A) */
86 	RV_LTREL = 6,		/* @ltoff(S + A) */
87 	RV_PLTREL = 7,		/* @pltoff(S + A) */
88 	RV_FPTR = 8,		/* @fptr(S + A) */
89 	RV_PCREL = 9,		/* S + A - P */
90 	RV_LTREL_FPTR = 10,	/* @ltoff(@fptr(S + A)) */
91 	RV_SEGREL = 11,		/* @segrel(S + A) */
92 	RV_SECREL = 12,		/* @secrel(S + A) */
93 	RV_BDREL = 13,		/* BD + A */
94 	RV_LTV = 14,		/* S + A (like RV_DIRECT, except frozen at static link-time) */
95 	RV_PCREL2 = 15,		/* S + A - P */
96 	RV_SPECIAL = 16,	/* various (see below) */
97 	RV_RSVD17 = 17,
98 	RV_TPREL = 18,		/* @tprel(S + A) */
99 	RV_LTREL_TPREL = 19,	/* @ltoff(@tprel(S + A)) */
100 	RV_DTPMOD = 20,		/* @dtpmod(S + A) */
101 	RV_LTREL_DTPMOD = 21,	/* @ltoff(@dtpmod(S + A)) */
102 	RV_DTPREL = 22,		/* @dtprel(S + A) */
103 	RV_LTREL_DTPREL = 23,	/* @ltoff(@dtprel(S + A)) */
104 	RV_RSVD24 = 24,
105 	RV_RSVD25 = 25,
106 	RV_RSVD26 = 26,
107 	RV_RSVD27 = 27
108 	/* 28-31 reserved for implementation-specific purposes.  */
109 };
110 
111 #define N(reloc)	[R_IA64_##reloc] = #reloc
112 
113 static const char *reloc_name[256] = {
114 	N(NONE),		N(IMM14),		N(IMM22),		N(IMM64),
115 	N(DIR32MSB),		N(DIR32LSB),		N(DIR64MSB),		N(DIR64LSB),
116 	N(GPREL22),		N(GPREL64I),		N(GPREL32MSB),		N(GPREL32LSB),
117 	N(GPREL64MSB),		N(GPREL64LSB),		N(LTOFF22),		N(LTOFF64I),
118 	N(PLTOFF22),		N(PLTOFF64I),		N(PLTOFF64MSB),		N(PLTOFF64LSB),
119 	N(FPTR64I),		N(FPTR32MSB),		N(FPTR32LSB),		N(FPTR64MSB),
120 	N(FPTR64LSB),		N(PCREL60B),		N(PCREL21B),		N(PCREL21M),
121 	N(PCREL21F),		N(PCREL32MSB),		N(PCREL32LSB),		N(PCREL64MSB),
122 	N(PCREL64LSB),		N(LTOFF_FPTR22),	N(LTOFF_FPTR64I),	N(LTOFF_FPTR32MSB),
123 	N(LTOFF_FPTR32LSB),	N(LTOFF_FPTR64MSB),	N(LTOFF_FPTR64LSB),	N(SEGREL32MSB),
124 	N(SEGREL32LSB),		N(SEGREL64MSB),		N(SEGREL64LSB),		N(SECREL32MSB),
125 	N(SECREL32LSB),		N(SECREL64MSB),		N(SECREL64LSB),		N(REL32MSB),
126 	N(REL32LSB),		N(REL64MSB),		N(REL64LSB),		N(LTV32MSB),
127 	N(LTV32LSB),		N(LTV64MSB),		N(LTV64LSB),		N(PCREL21BI),
128 	N(PCREL22),		N(PCREL64I),		N(IPLTMSB),		N(IPLTLSB),
129 	N(COPY),		N(LTOFF22X),		N(LDXMOV),		N(TPREL14),
130 	N(TPREL22),		N(TPREL64I),		N(TPREL64MSB),		N(TPREL64LSB),
131 	N(LTOFF_TPREL22),	N(DTPMOD64MSB),		N(DTPMOD64LSB),		N(LTOFF_DTPMOD22),
132 	N(DTPREL14),		N(DTPREL22),		N(DTPREL64I),		N(DTPREL32MSB),
133 	N(DTPREL32LSB),		N(DTPREL64MSB),		N(DTPREL64LSB),		N(LTOFF_DTPREL22)
134 };
135 
136 #undef N
137 
138 /* Opaque struct for insns, to protect against derefs. */
139 struct insn;
140 
141 static inline uint64_t
142 bundle (const struct insn *insn)
143 {
144 	return (uint64_t) insn & ~0xfUL;
145 }
146 
147 static inline int
148 slot (const struct insn *insn)
149 {
150 	return (uint64_t) insn & 0x3;
151 }
152 
153 static int
154 apply_imm64 (struct module *mod, struct insn *insn, uint64_t val)
155 {
156 	if (slot(insn) != 2) {
157 		printk(KERN_ERR "%s: invalid slot number %d for IMM64\n",
158 		       mod->name, slot(insn));
159 		return 0;
160 	}
161 	ia64_patch_imm64((u64) insn, val);
162 	return 1;
163 }
164 
165 static int
166 apply_imm60 (struct module *mod, struct insn *insn, uint64_t val)
167 {
168 	if (slot(insn) != 2) {
169 		printk(KERN_ERR "%s: invalid slot number %d for IMM60\n",
170 		       mod->name, slot(insn));
171 		return 0;
172 	}
173 	if (val + ((uint64_t) 1 << 59) >= (1UL << 60)) {
174 		printk(KERN_ERR "%s: value %ld out of IMM60 range\n", mod->name, (int64_t) val);
175 		return 0;
176 	}
177 	ia64_patch_imm60((u64) insn, val);
178 	return 1;
179 }
180 
181 static int
182 apply_imm22 (struct module *mod, struct insn *insn, uint64_t val)
183 {
184 	if (val + (1 << 21) >= (1 << 22)) {
185 		printk(KERN_ERR "%s: value %li out of IMM22 range\n", mod->name, (int64_t)val);
186 		return 0;
187 	}
188 	ia64_patch((u64) insn, 0x01fffcfe000UL, (  ((val & 0x200000UL) << 15) /* bit 21 -> 36 */
189 					         | ((val & 0x1f0000UL) <<  6) /* bit 16 -> 22 */
190 					         | ((val & 0x00ff80UL) << 20) /* bit  7 -> 27 */
191 					         | ((val & 0x00007fUL) << 13) /* bit  0 -> 13 */));
192 	return 1;
193 }
194 
195 static int
196 apply_imm21b (struct module *mod, struct insn *insn, uint64_t val)
197 {
198 	if (val + (1 << 20) >= (1 << 21)) {
199 		printk(KERN_ERR "%s: value %li out of IMM21b range\n", mod->name, (int64_t)val);
200 		return 0;
201 	}
202 	ia64_patch((u64) insn, 0x11ffffe000UL, (  ((val & 0x100000UL) << 16) /* bit 20 -> 36 */
203 					        | ((val & 0x0fffffUL) << 13) /* bit  0 -> 13 */));
204 	return 1;
205 }
206 
207 #if USE_BRL
208 
209 struct plt_entry {
210 	/* Three instruction bundles in PLT. */
211  	unsigned char bundle[2][16];
212 };
213 
214 static const struct plt_entry ia64_plt_template = {
215 	{
216 		{
217 			0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
218 			0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /*	     movl gp=TARGET_GP */
219 			0x00, 0x00, 0x00, 0x60
220 		},
221 		{
222 			0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
223 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*	     brl.many gp=TARGET_GP */
224 			0x08, 0x00, 0x00, 0xc0
225 		}
226 	}
227 };
228 
229 static int
230 patch_plt (struct module *mod, struct plt_entry *plt, long target_ip, unsigned long target_gp)
231 {
232 	if (apply_imm64(mod, (struct insn *) (plt->bundle[0] + 2), target_gp)
233 	    && apply_imm60(mod, (struct insn *) (plt->bundle[1] + 2),
234 			   (target_ip - (int64_t) plt->bundle[1]) / 16))
235 		return 1;
236 	return 0;
237 }
238 
239 unsigned long
240 plt_target (struct plt_entry *plt)
241 {
242 	uint64_t b0, b1, *b = (uint64_t *) plt->bundle[1];
243 	long off;
244 
245 	b0 = b[0]; b1 = b[1];
246 	off = (  ((b1 & 0x00fffff000000000UL) >> 36)		/* imm20b -> bit 0 */
247 	       | ((b0 >> 48) << 20) | ((b1 & 0x7fffffUL) << 36)	/* imm39 -> bit 20 */
248 	       | ((b1 & 0x0800000000000000UL) << 0));		/* i -> bit 59 */
249 	return (long) plt->bundle[1] + 16*off;
250 }
251 
252 #else /* !USE_BRL */
253 
254 struct plt_entry {
255 	/* Three instruction bundles in PLT. */
256  	unsigned char bundle[3][16];
257 };
258 
259 static const struct plt_entry ia64_plt_template = {
260 	{
261 		{
262 			0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
263 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*	     movl r16=TARGET_IP */
264 			0x02, 0x00, 0x00, 0x60
265 		},
266 		{
267 			0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
268 			0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /*	     movl gp=TARGET_GP */
269 			0x00, 0x00, 0x00, 0x60
270 		},
271 		{
272 			0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
273 			0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /*	     mov b6=r16 */
274 			0x60, 0x00, 0x80, 0x00		    /*	     br.few b6 */
275 		}
276 	}
277 };
278 
279 static int
280 patch_plt (struct module *mod, struct plt_entry *plt, long target_ip, unsigned long target_gp)
281 {
282 	if (apply_imm64(mod, (struct insn *) (plt->bundle[0] + 2), target_ip)
283 	    && apply_imm64(mod, (struct insn *) (plt->bundle[1] + 2), target_gp))
284 		return 1;
285 	return 0;
286 }
287 
288 unsigned long
289 plt_target (struct plt_entry *plt)
290 {
291 	uint64_t b0, b1, *b = (uint64_t *) plt->bundle[0];
292 
293 	b0 = b[0]; b1 = b[1];
294 	return (  ((b1 & 0x000007f000000000) >> 36)		/* imm7b -> bit 0 */
295 		| ((b1 & 0x07fc000000000000) >> 43)		/* imm9d -> bit 7 */
296 		| ((b1 & 0x0003e00000000000) >> 29)		/* imm5c -> bit 16 */
297 		| ((b1 & 0x0000100000000000) >> 23)		/* ic -> bit 21 */
298 		| ((b0 >> 46) << 22) | ((b1 & 0x7fffff) << 40)	/* imm41 -> bit 22 */
299 		| ((b1 & 0x0800000000000000) <<  4));		/* i -> bit 63 */
300 }
301 
302 #endif /* !USE_BRL */
303 
304 void *
305 module_alloc (unsigned long size)
306 {
307 	if (!size)
308 		return NULL;
309 	return vmalloc(size);
310 }
311 
312 void
313 module_free (struct module *mod, void *module_region)
314 {
315 	if (mod && mod->arch.init_unw_table &&
316 	    module_region == mod->module_init) {
317 		unw_remove_unwind_table(mod->arch.init_unw_table);
318 		mod->arch.init_unw_table = NULL;
319 	}
320 	vfree(module_region);
321 }
322 
323 /* Have we already seen one of these relocations? */
324 /* FIXME: we could look in other sections, too --RR */
325 static int
326 duplicate_reloc (const Elf64_Rela *rela, unsigned int num)
327 {
328 	unsigned int i;
329 
330 	for (i = 0; i < num; i++) {
331 		if (rela[i].r_info == rela[num].r_info && rela[i].r_addend == rela[num].r_addend)
332 			return 1;
333 	}
334 	return 0;
335 }
336 
337 /* Count how many GOT entries we may need */
338 static unsigned int
339 count_gots (const Elf64_Rela *rela, unsigned int num)
340 {
341 	unsigned int i, ret = 0;
342 
343 	/* Sure, this is order(n^2), but it's usually short, and not
344            time critical */
345 	for (i = 0; i < num; i++) {
346 		switch (ELF64_R_TYPE(rela[i].r_info)) {
347 		      case R_IA64_LTOFF22:
348 		      case R_IA64_LTOFF22X:
349 		      case R_IA64_LTOFF64I:
350 		      case R_IA64_LTOFF_FPTR22:
351 		      case R_IA64_LTOFF_FPTR64I:
352 		      case R_IA64_LTOFF_FPTR32MSB:
353 		      case R_IA64_LTOFF_FPTR32LSB:
354 		      case R_IA64_LTOFF_FPTR64MSB:
355 		      case R_IA64_LTOFF_FPTR64LSB:
356 			if (!duplicate_reloc(rela, i))
357 				ret++;
358 			break;
359 		}
360 	}
361 	return ret;
362 }
363 
364 /* Count how many PLT entries we may need */
365 static unsigned int
366 count_plts (const Elf64_Rela *rela, unsigned int num)
367 {
368 	unsigned int i, ret = 0;
369 
370 	/* Sure, this is order(n^2), but it's usually short, and not
371            time critical */
372 	for (i = 0; i < num; i++) {
373 		switch (ELF64_R_TYPE(rela[i].r_info)) {
374 		      case R_IA64_PCREL21B:
375 		      case R_IA64_PLTOFF22:
376 		      case R_IA64_PLTOFF64I:
377 		      case R_IA64_PLTOFF64MSB:
378 		      case R_IA64_PLTOFF64LSB:
379 		      case R_IA64_IPLTMSB:
380 		      case R_IA64_IPLTLSB:
381 			if (!duplicate_reloc(rela, i))
382 				ret++;
383 			break;
384 		}
385 	}
386 	return ret;
387 }
388 
389 /* We need to create an function-descriptors for any internal function
390    which is referenced. */
391 static unsigned int
392 count_fdescs (const Elf64_Rela *rela, unsigned int num)
393 {
394 	unsigned int i, ret = 0;
395 
396 	/* Sure, this is order(n^2), but it's usually short, and not time critical.  */
397 	for (i = 0; i < num; i++) {
398 		switch (ELF64_R_TYPE(rela[i].r_info)) {
399 		      case R_IA64_FPTR64I:
400 		      case R_IA64_FPTR32LSB:
401 		      case R_IA64_FPTR32MSB:
402 		      case R_IA64_FPTR64LSB:
403 		      case R_IA64_FPTR64MSB:
404 		      case R_IA64_LTOFF_FPTR22:
405 		      case R_IA64_LTOFF_FPTR32LSB:
406 		      case R_IA64_LTOFF_FPTR32MSB:
407 		      case R_IA64_LTOFF_FPTR64I:
408 		      case R_IA64_LTOFF_FPTR64LSB:
409 		      case R_IA64_LTOFF_FPTR64MSB:
410 		      case R_IA64_IPLTMSB:
411 		      case R_IA64_IPLTLSB:
412 			/*
413 			 * Jumps to static functions sometimes go straight to their
414 			 * offset.  Of course, that may not be possible if the jump is
415 			 * from init -> core or vice. versa, so we need to generate an
416 			 * FDESC (and PLT etc) for that.
417 			 */
418 		      case R_IA64_PCREL21B:
419 			if (!duplicate_reloc(rela, i))
420 				ret++;
421 			break;
422 		}
423 	}
424 	return ret;
425 }
426 
427 int
428 module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings,
429 			   struct module *mod)
430 {
431 	unsigned long core_plts = 0, init_plts = 0, gots = 0, fdescs = 0;
432 	Elf64_Shdr *s, *sechdrs_end = sechdrs + ehdr->e_shnum;
433 
434 	/*
435 	 * To store the PLTs and function-descriptors, we expand the .text section for
436 	 * core module-code and the .init.text section for initialization code.
437 	 */
438 	for (s = sechdrs; s < sechdrs_end; ++s)
439 		if (strcmp(".core.plt", secstrings + s->sh_name) == 0)
440 			mod->arch.core_plt = s;
441 		else if (strcmp(".init.plt", secstrings + s->sh_name) == 0)
442 			mod->arch.init_plt = s;
443 		else if (strcmp(".got", secstrings + s->sh_name) == 0)
444 			mod->arch.got = s;
445 		else if (strcmp(".opd", secstrings + s->sh_name) == 0)
446 			mod->arch.opd = s;
447 		else if (strcmp(".IA_64.unwind", secstrings + s->sh_name) == 0)
448 			mod->arch.unwind = s;
449 
450 	if (!mod->arch.core_plt || !mod->arch.init_plt || !mod->arch.got || !mod->arch.opd) {
451 		printk(KERN_ERR "%s: sections missing\n", mod->name);
452 		return -ENOEXEC;
453 	}
454 
455 	/* GOT and PLTs can occur in any relocated section... */
456 	for (s = sechdrs + 1; s < sechdrs_end; ++s) {
457 		const Elf64_Rela *rels = (void *)ehdr + s->sh_offset;
458 		unsigned long numrels = s->sh_size/sizeof(Elf64_Rela);
459 
460 		if (s->sh_type != SHT_RELA)
461 			continue;
462 
463 		gots += count_gots(rels, numrels);
464 		fdescs += count_fdescs(rels, numrels);
465 		if (strstr(secstrings + s->sh_name, ".init"))
466 			init_plts += count_plts(rels, numrels);
467 		else
468 			core_plts += count_plts(rels, numrels);
469 	}
470 
471 	mod->arch.core_plt->sh_type = SHT_NOBITS;
472 	mod->arch.core_plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
473 	mod->arch.core_plt->sh_addralign = 16;
474 	mod->arch.core_plt->sh_size = core_plts * sizeof(struct plt_entry);
475 	mod->arch.init_plt->sh_type = SHT_NOBITS;
476 	mod->arch.init_plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
477 	mod->arch.init_plt->sh_addralign = 16;
478 	mod->arch.init_plt->sh_size = init_plts * sizeof(struct plt_entry);
479 	mod->arch.got->sh_type = SHT_NOBITS;
480 	mod->arch.got->sh_flags = ARCH_SHF_SMALL | SHF_ALLOC;
481 	mod->arch.got->sh_addralign = 8;
482 	mod->arch.got->sh_size = gots * sizeof(struct got_entry);
483 	mod->arch.opd->sh_type = SHT_NOBITS;
484 	mod->arch.opd->sh_flags = SHF_ALLOC;
485 	mod->arch.opd->sh_addralign = 8;
486 	mod->arch.opd->sh_size = fdescs * sizeof(struct fdesc);
487 	DEBUGP("%s: core.plt=%lx, init.plt=%lx, got=%lx, fdesc=%lx\n",
488 	       __func__, mod->arch.core_plt->sh_size, mod->arch.init_plt->sh_size,
489 	       mod->arch.got->sh_size, mod->arch.opd->sh_size);
490 	return 0;
491 }
492 
493 static inline int
494 in_init (const struct module *mod, uint64_t addr)
495 {
496 	return addr - (uint64_t) mod->module_init < mod->init_size;
497 }
498 
499 static inline int
500 in_core (const struct module *mod, uint64_t addr)
501 {
502 	return addr - (uint64_t) mod->module_core < mod->core_size;
503 }
504 
505 static inline int
506 is_internal (const struct module *mod, uint64_t value)
507 {
508 	return in_init(mod, value) || in_core(mod, value);
509 }
510 
511 /*
512  * Get gp-relative offset for the linkage-table entry of VALUE.
513  */
514 static uint64_t
515 get_ltoff (struct module *mod, uint64_t value, int *okp)
516 {
517 	struct got_entry *got, *e;
518 
519 	if (!*okp)
520 		return 0;
521 
522 	got = (void *) mod->arch.got->sh_addr;
523 	for (e = got; e < got + mod->arch.next_got_entry; ++e)
524 		if (e->val == value)
525 			goto found;
526 
527 	/* Not enough GOT entries? */
528 	if (e >= (struct got_entry *) (mod->arch.got->sh_addr + mod->arch.got->sh_size))
529 		BUG();
530 
531 	e->val = value;
532 	++mod->arch.next_got_entry;
533   found:
534 	return (uint64_t) e - mod->arch.gp;
535 }
536 
537 static inline int
538 gp_addressable (struct module *mod, uint64_t value)
539 {
540 	return value - mod->arch.gp + MAX_LTOFF/2 < MAX_LTOFF;
541 }
542 
543 /* Get PC-relative PLT entry for this value.  Returns 0 on failure. */
544 static uint64_t
545 get_plt (struct module *mod, const struct insn *insn, uint64_t value, int *okp)
546 {
547 	struct plt_entry *plt, *plt_end;
548 	uint64_t target_ip, target_gp;
549 
550 	if (!*okp)
551 		return 0;
552 
553 	if (in_init(mod, (uint64_t) insn)) {
554 		plt = (void *) mod->arch.init_plt->sh_addr;
555 		plt_end = (void *) plt + mod->arch.init_plt->sh_size;
556 	} else {
557 		plt = (void *) mod->arch.core_plt->sh_addr;
558 		plt_end = (void *) plt + mod->arch.core_plt->sh_size;
559 	}
560 
561 	/* "value" is a pointer to a function-descriptor; fetch the target ip/gp from it: */
562 	target_ip = ((uint64_t *) value)[0];
563 	target_gp = ((uint64_t *) value)[1];
564 
565 	/* Look for existing PLT entry. */
566 	while (plt->bundle[0][0]) {
567 		if (plt_target(plt) == target_ip)
568 			goto found;
569 		if (++plt >= plt_end)
570 			BUG();
571 	}
572 	*plt = ia64_plt_template;
573 	if (!patch_plt(mod, plt, target_ip, target_gp)) {
574 		*okp = 0;
575 		return 0;
576 	}
577 #if ARCH_MODULE_DEBUG
578 	if (plt_target(plt) != target_ip) {
579 		printk("%s: mistargeted PLT: wanted %lx, got %lx\n",
580 		       __func__, target_ip, plt_target(plt));
581 		*okp = 0;
582 		return 0;
583 	}
584 #endif
585   found:
586 	return (uint64_t) plt;
587 }
588 
589 /* Get function descriptor for VALUE. */
590 static uint64_t
591 get_fdesc (struct module *mod, uint64_t value, int *okp)
592 {
593 	struct fdesc *fdesc = (void *) mod->arch.opd->sh_addr;
594 
595 	if (!*okp)
596 		return 0;
597 
598 	if (!value) {
599 		printk(KERN_ERR "%s: fdesc for zero requested!\n", mod->name);
600 		return 0;
601 	}
602 
603 	if (!is_internal(mod, value))
604 		/*
605 		 * If it's not a module-local entry-point, "value" already points to a
606 		 * function-descriptor.
607 		 */
608 		return value;
609 
610 	/* Look for existing function descriptor. */
611 	while (fdesc->ip) {
612 		if (fdesc->ip == value)
613 			return (uint64_t)fdesc;
614 		if ((uint64_t) ++fdesc >= mod->arch.opd->sh_addr + mod->arch.opd->sh_size)
615 			BUG();
616 	}
617 
618 	/* Create new one */
619 	fdesc->ip = value;
620 	fdesc->gp = mod->arch.gp;
621 	return (uint64_t) fdesc;
622 }
623 
624 static inline int
625 do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend,
626 	  Elf64_Shdr *sec, void *location)
627 {
628 	enum reloc_target_format format = (r_type >> FORMAT_SHIFT) & FORMAT_MASK;
629 	enum reloc_value_formula formula = (r_type >> VALUE_SHIFT) & VALUE_MASK;
630 	uint64_t val;
631 	int ok = 1;
632 
633 	val = sym->st_value + addend;
634 
635 	switch (formula) {
636 	      case RV_SEGREL:	/* segment base is arbitrarily chosen to be 0 for kernel modules */
637 	      case RV_DIRECT:
638 		break;
639 
640 	      case RV_GPREL:	  val -= mod->arch.gp; break;
641 	      case RV_LTREL:	  val = get_ltoff(mod, val, &ok); break;
642 	      case RV_PLTREL:	  val = get_plt(mod, location, val, &ok); break;
643 	      case RV_FPTR:	  val = get_fdesc(mod, val, &ok); break;
644 	      case RV_SECREL:	  val -= sec->sh_addr; break;
645 	      case RV_LTREL_FPTR: val = get_ltoff(mod, get_fdesc(mod, val, &ok), &ok); break;
646 
647 	      case RV_PCREL:
648 		switch (r_type) {
649 		      case R_IA64_PCREL21B:
650 			if ((in_init(mod, val) && in_core(mod, (uint64_t)location)) ||
651 			    (in_core(mod, val) && in_init(mod, (uint64_t)location))) {
652 				/*
653 				 * Init section may have been allocated far away from core,
654 				 * if the branch won't reach, then allocate a plt for it.
655 				 */
656 				uint64_t delta = ((int64_t)val - (int64_t)location) / 16;
657 				if (delta + (1 << 20) >= (1 << 21)) {
658 					val = get_fdesc(mod, val, &ok);
659 					val = get_plt(mod, location, val, &ok);
660 				}
661 			} else if (!is_internal(mod, val))
662 				val = get_plt(mod, location, val, &ok);
663 			/* FALL THROUGH */
664 		      default:
665 			val -= bundle(location);
666 			break;
667 
668 		      case R_IA64_PCREL32MSB:
669 		      case R_IA64_PCREL32LSB:
670 		      case R_IA64_PCREL64MSB:
671 		      case R_IA64_PCREL64LSB:
672 			val -= (uint64_t) location;
673 			break;
674 
675 		}
676 		switch (r_type) {
677 		      case R_IA64_PCREL60B: format = RF_INSN60; break;
678 		      case R_IA64_PCREL21B: format = RF_INSN21B; break;
679 		      case R_IA64_PCREL21M: format = RF_INSN21M; break;
680 		      case R_IA64_PCREL21F: format = RF_INSN21F; break;
681 		      default: break;
682 		}
683 		break;
684 
685 	      case RV_BDREL:
686 		val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
687 		break;
688 
689 	      case RV_LTV:
690 		/* can link-time value relocs happen here?  */
691 		BUG();
692 		break;
693 
694 	      case RV_PCREL2:
695 		if (r_type == R_IA64_PCREL21BI) {
696 			if (!is_internal(mod, val)) {
697 				printk(KERN_ERR "%s: %s reloc against non-local symbol (%lx)\n",
698 				       __func__, reloc_name[r_type], val);
699 				return -ENOEXEC;
700 			}
701 			format = RF_INSN21B;
702 		}
703 		val -= bundle(location);
704 		break;
705 
706 	      case RV_SPECIAL:
707 		switch (r_type) {
708 		      case R_IA64_IPLTMSB:
709 		      case R_IA64_IPLTLSB:
710 			val = get_fdesc(mod, get_plt(mod, location, val, &ok), &ok);
711 			format = RF_64LSB;
712 			if (r_type == R_IA64_IPLTMSB)
713 				format = RF_64MSB;
714 			break;
715 
716 		      case R_IA64_SUB:
717 			val = addend - sym->st_value;
718 			format = RF_INSN64;
719 			break;
720 
721 		      case R_IA64_LTOFF22X:
722 			if (gp_addressable(mod, val))
723 				val -= mod->arch.gp;
724 			else
725 				val = get_ltoff(mod, val, &ok);
726 			format = RF_INSN22;
727 			break;
728 
729 		      case R_IA64_LDXMOV:
730 			if (gp_addressable(mod, val)) {
731 				/* turn "ld8" into "mov": */
732 				DEBUGP("%s: patching ld8 at %p to mov\n", __func__, location);
733 				ia64_patch((u64) location, 0x1fff80fe000UL, 0x10000000000UL);
734 			}
735 			return 0;
736 
737 		      default:
738 			if (reloc_name[r_type])
739 				printk(KERN_ERR "%s: special reloc %s not supported",
740 				       mod->name, reloc_name[r_type]);
741 			else
742 				printk(KERN_ERR "%s: unknown special reloc %x\n",
743 				       mod->name, r_type);
744 			return -ENOEXEC;
745 		}
746 		break;
747 
748 	      case RV_TPREL:
749 	      case RV_LTREL_TPREL:
750 	      case RV_DTPMOD:
751 	      case RV_LTREL_DTPMOD:
752 	      case RV_DTPREL:
753 	      case RV_LTREL_DTPREL:
754 		printk(KERN_ERR "%s: %s reloc not supported\n",
755 		       mod->name, reloc_name[r_type] ? reloc_name[r_type] : "?");
756 		return -ENOEXEC;
757 
758 	      default:
759 		printk(KERN_ERR "%s: unknown reloc %x\n", mod->name, r_type);
760 		return -ENOEXEC;
761 	}
762 
763 	if (!ok)
764 		return -ENOEXEC;
765 
766 	DEBUGP("%s: [%p]<-%016lx = %s(%lx)\n", __func__, location, val,
767 	       reloc_name[r_type] ? reloc_name[r_type] : "?", sym->st_value + addend);
768 
769 	switch (format) {
770 	      case RF_INSN21B:	ok = apply_imm21b(mod, location, (int64_t) val / 16); break;
771 	      case RF_INSN22:	ok = apply_imm22(mod, location, val); break;
772 	      case RF_INSN64:	ok = apply_imm64(mod, location, val); break;
773 	      case RF_INSN60:	ok = apply_imm60(mod, location, (int64_t) val / 16); break;
774 	      case RF_32LSB:	put_unaligned(val, (uint32_t *) location); break;
775 	      case RF_64LSB:	put_unaligned(val, (uint64_t *) location); break;
776 	      case RF_32MSB:	/* ia64 Linux is little-endian... */
777 	      case RF_64MSB:	/* ia64 Linux is little-endian... */
778 	      case RF_INSN14:	/* must be within-module, i.e., resolved by "ld -r" */
779 	      case RF_INSN21M:	/* must be within-module, i.e., resolved by "ld -r" */
780 	      case RF_INSN21F:	/* must be within-module, i.e., resolved by "ld -r" */
781 		printk(KERN_ERR "%s: format %u needed by %s reloc is not supported\n",
782 		       mod->name, format, reloc_name[r_type] ? reloc_name[r_type] : "?");
783 		return -ENOEXEC;
784 
785 	      default:
786 		printk(KERN_ERR "%s: relocation %s resulted in unknown format %u\n",
787 		       mod->name, reloc_name[r_type] ? reloc_name[r_type] : "?", format);
788 		return -ENOEXEC;
789 	}
790 	return ok ? 0 : -ENOEXEC;
791 }
792 
793 int
794 apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex,
795 		    unsigned int relsec, struct module *mod)
796 {
797 	unsigned int i, n = sechdrs[relsec].sh_size / sizeof(Elf64_Rela);
798 	Elf64_Rela *rela = (void *) sechdrs[relsec].sh_addr;
799 	Elf64_Shdr *target_sec;
800 	int ret;
801 
802 	DEBUGP("%s: applying section %u (%u relocs) to %u\n", __func__,
803 	       relsec, n, sechdrs[relsec].sh_info);
804 
805 	target_sec = sechdrs + sechdrs[relsec].sh_info;
806 
807 	if (target_sec->sh_entsize == ~0UL)
808 		/*
809 		 * If target section wasn't allocated, we don't need to relocate it.
810 		 * Happens, e.g., for debug sections.
811 		 */
812 		return 0;
813 
814 	if (!mod->arch.gp) {
815 		/*
816 		 * XXX Should have an arch-hook for running this after final section
817 		 *     addresses have been selected...
818 		 */
819 		uint64_t gp;
820 		if (mod->core_size > MAX_LTOFF)
821 			/*
822 			 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
823 			 * at the end of the module.
824 			 */
825 			gp = mod->core_size - MAX_LTOFF / 2;
826 		else
827 			gp = mod->core_size / 2;
828 		gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
829 		mod->arch.gp = gp;
830 		DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
831 	}
832 
833 	for (i = 0; i < n; i++) {
834 		ret = do_reloc(mod, ELF64_R_TYPE(rela[i].r_info),
835 			       ((Elf64_Sym *) sechdrs[symindex].sh_addr
836 				+ ELF64_R_SYM(rela[i].r_info)),
837 			       rela[i].r_addend, target_sec,
838 			       (void *) target_sec->sh_addr + rela[i].r_offset);
839 		if (ret < 0)
840 			return ret;
841 	}
842 	return 0;
843 }
844 
845 int
846 apply_relocate (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex,
847 		unsigned int relsec, struct module *mod)
848 {
849 	printk(KERN_ERR "module %s: REL relocs in section %u unsupported\n", mod->name, relsec);
850 	return -ENOEXEC;
851 }
852 
853 /*
854  * Modules contain a single unwind table which covers both the core and the init text
855  * sections but since the two are not contiguous, we need to split this table up such that
856  * we can register (and unregister) each "segment" separately.  Fortunately, this sounds
857  * more complicated than it really is.
858  */
859 static void
860 register_unwind_table (struct module *mod)
861 {
862 	struct unw_table_entry *start = (void *) mod->arch.unwind->sh_addr;
863 	struct unw_table_entry *end = start + mod->arch.unwind->sh_size / sizeof (*start);
864 	struct unw_table_entry tmp, *e1, *e2, *core, *init;
865 	unsigned long num_init = 0, num_core = 0;
866 
867 	/* First, count how many init and core unwind-table entries there are.  */
868 	for (e1 = start; e1 < end; ++e1)
869 		if (in_init(mod, e1->start_offset))
870 			++num_init;
871 		else
872 			++num_core;
873 	/*
874 	 * Second, sort the table such that all unwind-table entries for the init and core
875 	 * text sections are nicely separated.  We do this with a stupid bubble sort
876 	 * (unwind tables don't get ridiculously huge).
877 	 */
878 	for (e1 = start; e1 < end; ++e1) {
879 		for (e2 = e1 + 1; e2 < end; ++e2) {
880 			if (e2->start_offset < e1->start_offset) {
881 				tmp = *e1;
882 				*e1 = *e2;
883 				*e2 = tmp;
884 			}
885 		}
886 	}
887 	/*
888 	 * Third, locate the init and core segments in the unwind table:
889 	 */
890 	if (in_init(mod, start->start_offset)) {
891 		init = start;
892 		core = start + num_init;
893 	} else {
894 		core = start;
895 		init = start + num_core;
896 	}
897 
898 	DEBUGP("%s: name=%s, gp=%lx, num_init=%lu, num_core=%lu\n", __func__,
899 	       mod->name, mod->arch.gp, num_init, num_core);
900 
901 	/*
902 	 * Fourth, register both tables (if not empty).
903 	 */
904 	if (num_core > 0) {
905 		mod->arch.core_unw_table = unw_add_unwind_table(mod->name, 0, mod->arch.gp,
906 								core, core + num_core);
907 		DEBUGP("%s:  core: handle=%p [%p-%p)\n", __func__,
908 		       mod->arch.core_unw_table, core, core + num_core);
909 	}
910 	if (num_init > 0) {
911 		mod->arch.init_unw_table = unw_add_unwind_table(mod->name, 0, mod->arch.gp,
912 								init, init + num_init);
913 		DEBUGP("%s:  init: handle=%p [%p-%p)\n", __func__,
914 		       mod->arch.init_unw_table, init, init + num_init);
915 	}
916 }
917 
918 int
919 module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod)
920 {
921 	DEBUGP("%s: init: entry=%p\n", __func__, mod->init);
922 	if (mod->arch.unwind)
923 		register_unwind_table(mod);
924 	return 0;
925 }
926 
927 void
928 module_arch_cleanup (struct module *mod)
929 {
930 	if (mod->arch.init_unw_table)
931 		unw_remove_unwind_table(mod->arch.init_unw_table);
932 	if (mod->arch.core_unw_table)
933 		unw_remove_unwind_table(mod->arch.core_unw_table);
934 }
935