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