xref: /openbmc/linux/arch/ia64/kernel/module.c (revision f42b3800)
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->arch.init_unw_table && module_region == mod->module_init) {
325 		unw_remove_unwind_table(mod->arch.init_unw_table);
326 		mod->arch.init_unw_table = NULL;
327 	}
328 	vfree(module_region);
329 }
330 
331 /* Have we already seen one of these relocations? */
332 /* FIXME: we could look in other sections, too --RR */
333 static int
334 duplicate_reloc (const Elf64_Rela *rela, unsigned int num)
335 {
336 	unsigned int i;
337 
338 	for (i = 0; i < num; i++) {
339 		if (rela[i].r_info == rela[num].r_info && rela[i].r_addend == rela[num].r_addend)
340 			return 1;
341 	}
342 	return 0;
343 }
344 
345 /* Count how many GOT entries we may need */
346 static unsigned int
347 count_gots (const Elf64_Rela *rela, unsigned int num)
348 {
349 	unsigned int i, ret = 0;
350 
351 	/* Sure, this is order(n^2), but it's usually short, and not
352            time critical */
353 	for (i = 0; i < num; i++) {
354 		switch (ELF64_R_TYPE(rela[i].r_info)) {
355 		      case R_IA64_LTOFF22:
356 		      case R_IA64_LTOFF22X:
357 		      case R_IA64_LTOFF64I:
358 		      case R_IA64_LTOFF_FPTR22:
359 		      case R_IA64_LTOFF_FPTR64I:
360 		      case R_IA64_LTOFF_FPTR32MSB:
361 		      case R_IA64_LTOFF_FPTR32LSB:
362 		      case R_IA64_LTOFF_FPTR64MSB:
363 		      case R_IA64_LTOFF_FPTR64LSB:
364 			if (!duplicate_reloc(rela, i))
365 				ret++;
366 			break;
367 		}
368 	}
369 	return ret;
370 }
371 
372 /* Count how many PLT entries we may need */
373 static unsigned int
374 count_plts (const Elf64_Rela *rela, unsigned int num)
375 {
376 	unsigned int i, ret = 0;
377 
378 	/* Sure, this is order(n^2), but it's usually short, and not
379            time critical */
380 	for (i = 0; i < num; i++) {
381 		switch (ELF64_R_TYPE(rela[i].r_info)) {
382 		      case R_IA64_PCREL21B:
383 		      case R_IA64_PLTOFF22:
384 		      case R_IA64_PLTOFF64I:
385 		      case R_IA64_PLTOFF64MSB:
386 		      case R_IA64_PLTOFF64LSB:
387 		      case R_IA64_IPLTMSB:
388 		      case R_IA64_IPLTLSB:
389 			if (!duplicate_reloc(rela, i))
390 				ret++;
391 			break;
392 		}
393 	}
394 	return ret;
395 }
396 
397 /* We need to create an function-descriptors for any internal function
398    which is referenced. */
399 static unsigned int
400 count_fdescs (const Elf64_Rela *rela, unsigned int num)
401 {
402 	unsigned int i, ret = 0;
403 
404 	/* Sure, this is order(n^2), but it's usually short, and not time critical.  */
405 	for (i = 0; i < num; i++) {
406 		switch (ELF64_R_TYPE(rela[i].r_info)) {
407 		      case R_IA64_FPTR64I:
408 		      case R_IA64_FPTR32LSB:
409 		      case R_IA64_FPTR32MSB:
410 		      case R_IA64_FPTR64LSB:
411 		      case R_IA64_FPTR64MSB:
412 		      case R_IA64_LTOFF_FPTR22:
413 		      case R_IA64_LTOFF_FPTR32LSB:
414 		      case R_IA64_LTOFF_FPTR32MSB:
415 		      case R_IA64_LTOFF_FPTR64I:
416 		      case R_IA64_LTOFF_FPTR64LSB:
417 		      case R_IA64_LTOFF_FPTR64MSB:
418 		      case R_IA64_IPLTMSB:
419 		      case R_IA64_IPLTLSB:
420 			/*
421 			 * Jumps to static functions sometimes go straight to their
422 			 * offset.  Of course, that may not be possible if the jump is
423 			 * from init -> core or vice. versa, so we need to generate an
424 			 * FDESC (and PLT etc) for that.
425 			 */
426 		      case R_IA64_PCREL21B:
427 			if (!duplicate_reloc(rela, i))
428 				ret++;
429 			break;
430 		}
431 	}
432 	return ret;
433 }
434 
435 int
436 module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings,
437 			   struct module *mod)
438 {
439 	unsigned long core_plts = 0, init_plts = 0, gots = 0, fdescs = 0;
440 	Elf64_Shdr *s, *sechdrs_end = sechdrs + ehdr->e_shnum;
441 
442 	/*
443 	 * To store the PLTs and function-descriptors, we expand the .text section for
444 	 * core module-code and the .init.text section for initialization code.
445 	 */
446 	for (s = sechdrs; s < sechdrs_end; ++s)
447 		if (strcmp(".core.plt", secstrings + s->sh_name) == 0)
448 			mod->arch.core_plt = s;
449 		else if (strcmp(".init.plt", secstrings + s->sh_name) == 0)
450 			mod->arch.init_plt = s;
451 		else if (strcmp(".got", secstrings + s->sh_name) == 0)
452 			mod->arch.got = s;
453 		else if (strcmp(".opd", secstrings + s->sh_name) == 0)
454 			mod->arch.opd = s;
455 		else if (strcmp(".IA_64.unwind", secstrings + s->sh_name) == 0)
456 			mod->arch.unwind = s;
457 
458 	if (!mod->arch.core_plt || !mod->arch.init_plt || !mod->arch.got || !mod->arch.opd) {
459 		printk(KERN_ERR "%s: sections missing\n", mod->name);
460 		return -ENOEXEC;
461 	}
462 
463 	/* GOT and PLTs can occur in any relocated section... */
464 	for (s = sechdrs + 1; s < sechdrs_end; ++s) {
465 		const Elf64_Rela *rels = (void *)ehdr + s->sh_offset;
466 		unsigned long numrels = s->sh_size/sizeof(Elf64_Rela);
467 
468 		if (s->sh_type != SHT_RELA)
469 			continue;
470 
471 		gots += count_gots(rels, numrels);
472 		fdescs += count_fdescs(rels, numrels);
473 		if (strstr(secstrings + s->sh_name, ".init"))
474 			init_plts += count_plts(rels, numrels);
475 		else
476 			core_plts += count_plts(rels, numrels);
477 	}
478 
479 	mod->arch.core_plt->sh_type = SHT_NOBITS;
480 	mod->arch.core_plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
481 	mod->arch.core_plt->sh_addralign = 16;
482 	mod->arch.core_plt->sh_size = core_plts * sizeof(struct plt_entry);
483 	mod->arch.init_plt->sh_type = SHT_NOBITS;
484 	mod->arch.init_plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
485 	mod->arch.init_plt->sh_addralign = 16;
486 	mod->arch.init_plt->sh_size = init_plts * sizeof(struct plt_entry);
487 	mod->arch.got->sh_type = SHT_NOBITS;
488 	mod->arch.got->sh_flags = ARCH_SHF_SMALL | SHF_ALLOC;
489 	mod->arch.got->sh_addralign = 8;
490 	mod->arch.got->sh_size = gots * sizeof(struct got_entry);
491 	mod->arch.opd->sh_type = SHT_NOBITS;
492 	mod->arch.opd->sh_flags = SHF_ALLOC;
493 	mod->arch.opd->sh_addralign = 8;
494 	mod->arch.opd->sh_size = fdescs * sizeof(struct fdesc);
495 	DEBUGP("%s: core.plt=%lx, init.plt=%lx, got=%lx, fdesc=%lx\n",
496 	       __func__, mod->arch.core_plt->sh_size, mod->arch.init_plt->sh_size,
497 	       mod->arch.got->sh_size, mod->arch.opd->sh_size);
498 	return 0;
499 }
500 
501 static inline int
502 in_init (const struct module *mod, uint64_t addr)
503 {
504 	return addr - (uint64_t) mod->module_init < mod->init_size;
505 }
506 
507 static inline int
508 in_core (const struct module *mod, uint64_t addr)
509 {
510 	return addr - (uint64_t) mod->module_core < mod->core_size;
511 }
512 
513 static inline int
514 is_internal (const struct module *mod, uint64_t value)
515 {
516 	return in_init(mod, value) || in_core(mod, value);
517 }
518 
519 /*
520  * Get gp-relative offset for the linkage-table entry of VALUE.
521  */
522 static uint64_t
523 get_ltoff (struct module *mod, uint64_t value, int *okp)
524 {
525 	struct got_entry *got, *e;
526 
527 	if (!*okp)
528 		return 0;
529 
530 	got = (void *) mod->arch.got->sh_addr;
531 	for (e = got; e < got + mod->arch.next_got_entry; ++e)
532 		if (e->val == value)
533 			goto found;
534 
535 	/* Not enough GOT entries? */
536 	if (e >= (struct got_entry *) (mod->arch.got->sh_addr + mod->arch.got->sh_size))
537 		BUG();
538 
539 	e->val = value;
540 	++mod->arch.next_got_entry;
541   found:
542 	return (uint64_t) e - mod->arch.gp;
543 }
544 
545 static inline int
546 gp_addressable (struct module *mod, uint64_t value)
547 {
548 	return value - mod->arch.gp + MAX_LTOFF/2 < MAX_LTOFF;
549 }
550 
551 /* Get PC-relative PLT entry for this value.  Returns 0 on failure. */
552 static uint64_t
553 get_plt (struct module *mod, const struct insn *insn, uint64_t value, int *okp)
554 {
555 	struct plt_entry *plt, *plt_end;
556 	uint64_t target_ip, target_gp;
557 
558 	if (!*okp)
559 		return 0;
560 
561 	if (in_init(mod, (uint64_t) insn)) {
562 		plt = (void *) mod->arch.init_plt->sh_addr;
563 		plt_end = (void *) plt + mod->arch.init_plt->sh_size;
564 	} else {
565 		plt = (void *) mod->arch.core_plt->sh_addr;
566 		plt_end = (void *) plt + mod->arch.core_plt->sh_size;
567 	}
568 
569 	/* "value" is a pointer to a function-descriptor; fetch the target ip/gp from it: */
570 	target_ip = ((uint64_t *) value)[0];
571 	target_gp = ((uint64_t *) value)[1];
572 
573 	/* Look for existing PLT entry. */
574 	while (plt->bundle[0][0]) {
575 		if (plt_target(plt) == target_ip)
576 			goto found;
577 		if (++plt >= plt_end)
578 			BUG();
579 	}
580 	*plt = ia64_plt_template;
581 	if (!patch_plt(mod, plt, target_ip, target_gp)) {
582 		*okp = 0;
583 		return 0;
584 	}
585 #if ARCH_MODULE_DEBUG
586 	if (plt_target(plt) != target_ip) {
587 		printk("%s: mistargeted PLT: wanted %lx, got %lx\n",
588 		       __func__, target_ip, plt_target(plt));
589 		*okp = 0;
590 		return 0;
591 	}
592 #endif
593   found:
594 	return (uint64_t) plt;
595 }
596 
597 /* Get function descriptor for VALUE. */
598 static uint64_t
599 get_fdesc (struct module *mod, uint64_t value, int *okp)
600 {
601 	struct fdesc *fdesc = (void *) mod->arch.opd->sh_addr;
602 
603 	if (!*okp)
604 		return 0;
605 
606 	if (!value) {
607 		printk(KERN_ERR "%s: fdesc for zero requested!\n", mod->name);
608 		return 0;
609 	}
610 
611 	if (!is_internal(mod, value))
612 		/*
613 		 * If it's not a module-local entry-point, "value" already points to a
614 		 * function-descriptor.
615 		 */
616 		return value;
617 
618 	/* Look for existing function descriptor. */
619 	while (fdesc->ip) {
620 		if (fdesc->ip == value)
621 			return (uint64_t)fdesc;
622 		if ((uint64_t) ++fdesc >= mod->arch.opd->sh_addr + mod->arch.opd->sh_size)
623 			BUG();
624 	}
625 
626 	/* Create new one */
627 	fdesc->ip = value;
628 	fdesc->gp = mod->arch.gp;
629 	return (uint64_t) fdesc;
630 }
631 
632 static inline int
633 do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend,
634 	  Elf64_Shdr *sec, void *location)
635 {
636 	enum reloc_target_format format = (r_type >> FORMAT_SHIFT) & FORMAT_MASK;
637 	enum reloc_value_formula formula = (r_type >> VALUE_SHIFT) & VALUE_MASK;
638 	uint64_t val;
639 	int ok = 1;
640 
641 	val = sym->st_value + addend;
642 
643 	switch (formula) {
644 	      case RV_SEGREL:	/* segment base is arbitrarily chosen to be 0 for kernel modules */
645 	      case RV_DIRECT:
646 		break;
647 
648 	      case RV_GPREL:	  val -= mod->arch.gp; break;
649 	      case RV_LTREL:	  val = get_ltoff(mod, val, &ok); break;
650 	      case RV_PLTREL:	  val = get_plt(mod, location, val, &ok); break;
651 	      case RV_FPTR:	  val = get_fdesc(mod, val, &ok); break;
652 	      case RV_SECREL:	  val -= sec->sh_addr; break;
653 	      case RV_LTREL_FPTR: val = get_ltoff(mod, get_fdesc(mod, val, &ok), &ok); break;
654 
655 	      case RV_PCREL:
656 		switch (r_type) {
657 		      case R_IA64_PCREL21B:
658 			if ((in_init(mod, val) && in_core(mod, (uint64_t)location)) ||
659 			    (in_core(mod, val) && in_init(mod, (uint64_t)location))) {
660 				/*
661 				 * Init section may have been allocated far away from core,
662 				 * if the branch won't reach, then allocate a plt for it.
663 				 */
664 				uint64_t delta = ((int64_t)val - (int64_t)location) / 16;
665 				if (delta + (1 << 20) >= (1 << 21)) {
666 					val = get_fdesc(mod, val, &ok);
667 					val = get_plt(mod, location, val, &ok);
668 				}
669 			} else if (!is_internal(mod, val))
670 				val = get_plt(mod, location, val, &ok);
671 			/* FALL THROUGH */
672 		      default:
673 			val -= bundle(location);
674 			break;
675 
676 		      case R_IA64_PCREL32MSB:
677 		      case R_IA64_PCREL32LSB:
678 		      case R_IA64_PCREL64MSB:
679 		      case R_IA64_PCREL64LSB:
680 			val -= (uint64_t) location;
681 			break;
682 
683 		}
684 		switch (r_type) {
685 		      case R_IA64_PCREL60B: format = RF_INSN60; break;
686 		      case R_IA64_PCREL21B: format = RF_INSN21B; break;
687 		      case R_IA64_PCREL21M: format = RF_INSN21M; break;
688 		      case R_IA64_PCREL21F: format = RF_INSN21F; break;
689 		      default: break;
690 		}
691 		break;
692 
693 	      case RV_BDREL:
694 		val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
695 		break;
696 
697 	      case RV_LTV:
698 		/* can link-time value relocs happen here?  */
699 		BUG();
700 		break;
701 
702 	      case RV_PCREL2:
703 		if (r_type == R_IA64_PCREL21BI) {
704 			if (!is_internal(mod, val)) {
705 				printk(KERN_ERR "%s: %s reloc against non-local symbol (%lx)\n",
706 				       __func__, reloc_name[r_type], val);
707 				return -ENOEXEC;
708 			}
709 			format = RF_INSN21B;
710 		}
711 		val -= bundle(location);
712 		break;
713 
714 	      case RV_SPECIAL:
715 		switch (r_type) {
716 		      case R_IA64_IPLTMSB:
717 		      case R_IA64_IPLTLSB:
718 			val = get_fdesc(mod, get_plt(mod, location, val, &ok), &ok);
719 			format = RF_64LSB;
720 			if (r_type == R_IA64_IPLTMSB)
721 				format = RF_64MSB;
722 			break;
723 
724 		      case R_IA64_SUB:
725 			val = addend - sym->st_value;
726 			format = RF_INSN64;
727 			break;
728 
729 		      case R_IA64_LTOFF22X:
730 			if (gp_addressable(mod, val))
731 				val -= mod->arch.gp;
732 			else
733 				val = get_ltoff(mod, val, &ok);
734 			format = RF_INSN22;
735 			break;
736 
737 		      case R_IA64_LDXMOV:
738 			if (gp_addressable(mod, val)) {
739 				/* turn "ld8" into "mov": */
740 				DEBUGP("%s: patching ld8 at %p to mov\n", __func__, location);
741 				ia64_patch((u64) location, 0x1fff80fe000UL, 0x10000000000UL);
742 			}
743 			return 0;
744 
745 		      default:
746 			if (reloc_name[r_type])
747 				printk(KERN_ERR "%s: special reloc %s not supported",
748 				       mod->name, reloc_name[r_type]);
749 			else
750 				printk(KERN_ERR "%s: unknown special reloc %x\n",
751 				       mod->name, r_type);
752 			return -ENOEXEC;
753 		}
754 		break;
755 
756 	      case RV_TPREL:
757 	      case RV_LTREL_TPREL:
758 	      case RV_DTPMOD:
759 	      case RV_LTREL_DTPMOD:
760 	      case RV_DTPREL:
761 	      case RV_LTREL_DTPREL:
762 		printk(KERN_ERR "%s: %s reloc not supported\n",
763 		       mod->name, reloc_name[r_type] ? reloc_name[r_type] : "?");
764 		return -ENOEXEC;
765 
766 	      default:
767 		printk(KERN_ERR "%s: unknown reloc %x\n", mod->name, r_type);
768 		return -ENOEXEC;
769 	}
770 
771 	if (!ok)
772 		return -ENOEXEC;
773 
774 	DEBUGP("%s: [%p]<-%016lx = %s(%lx)\n", __func__, location, val,
775 	       reloc_name[r_type] ? reloc_name[r_type] : "?", sym->st_value + addend);
776 
777 	switch (format) {
778 	      case RF_INSN21B:	ok = apply_imm21b(mod, location, (int64_t) val / 16); break;
779 	      case RF_INSN22:	ok = apply_imm22(mod, location, val); break;
780 	      case RF_INSN64:	ok = apply_imm64(mod, location, val); break;
781 	      case RF_INSN60:	ok = apply_imm60(mod, location, (int64_t) val / 16); break;
782 	      case RF_32LSB:	put_unaligned(val, (uint32_t *) location); break;
783 	      case RF_64LSB:	put_unaligned(val, (uint64_t *) location); break;
784 	      case RF_32MSB:	/* ia64 Linux is little-endian... */
785 	      case RF_64MSB:	/* ia64 Linux is little-endian... */
786 	      case RF_INSN14:	/* must be within-module, i.e., resolved by "ld -r" */
787 	      case RF_INSN21M:	/* must be within-module, i.e., resolved by "ld -r" */
788 	      case RF_INSN21F:	/* must be within-module, i.e., resolved by "ld -r" */
789 		printk(KERN_ERR "%s: format %u needed by %s reloc is not supported\n",
790 		       mod->name, format, reloc_name[r_type] ? reloc_name[r_type] : "?");
791 		return -ENOEXEC;
792 
793 	      default:
794 		printk(KERN_ERR "%s: relocation %s resulted in unknown format %u\n",
795 		       mod->name, reloc_name[r_type] ? reloc_name[r_type] : "?", format);
796 		return -ENOEXEC;
797 	}
798 	return ok ? 0 : -ENOEXEC;
799 }
800 
801 int
802 apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex,
803 		    unsigned int relsec, struct module *mod)
804 {
805 	unsigned int i, n = sechdrs[relsec].sh_size / sizeof(Elf64_Rela);
806 	Elf64_Rela *rela = (void *) sechdrs[relsec].sh_addr;
807 	Elf64_Shdr *target_sec;
808 	int ret;
809 
810 	DEBUGP("%s: applying section %u (%u relocs) to %u\n", __func__,
811 	       relsec, n, sechdrs[relsec].sh_info);
812 
813 	target_sec = sechdrs + sechdrs[relsec].sh_info;
814 
815 	if (target_sec->sh_entsize == ~0UL)
816 		/*
817 		 * If target section wasn't allocated, we don't need to relocate it.
818 		 * Happens, e.g., for debug sections.
819 		 */
820 		return 0;
821 
822 	if (!mod->arch.gp) {
823 		/*
824 		 * XXX Should have an arch-hook for running this after final section
825 		 *     addresses have been selected...
826 		 */
827 		uint64_t gp;
828 		if (mod->core_size > MAX_LTOFF)
829 			/*
830 			 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
831 			 * at the end of the module.
832 			 */
833 			gp = mod->core_size - MAX_LTOFF / 2;
834 		else
835 			gp = mod->core_size / 2;
836 		gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
837 		mod->arch.gp = gp;
838 		DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
839 	}
840 
841 	for (i = 0; i < n; i++) {
842 		ret = do_reloc(mod, ELF64_R_TYPE(rela[i].r_info),
843 			       ((Elf64_Sym *) sechdrs[symindex].sh_addr
844 				+ ELF64_R_SYM(rela[i].r_info)),
845 			       rela[i].r_addend, target_sec,
846 			       (void *) target_sec->sh_addr + rela[i].r_offset);
847 		if (ret < 0)
848 			return ret;
849 	}
850 	return 0;
851 }
852 
853 int
854 apply_relocate (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex,
855 		unsigned int relsec, struct module *mod)
856 {
857 	printk(KERN_ERR "module %s: REL relocs in section %u unsupported\n", mod->name, relsec);
858 	return -ENOEXEC;
859 }
860 
861 /*
862  * Modules contain a single unwind table which covers both the core and the init text
863  * sections but since the two are not contiguous, we need to split this table up such that
864  * we can register (and unregister) each "segment" separately.  Fortunately, this sounds
865  * more complicated than it really is.
866  */
867 static void
868 register_unwind_table (struct module *mod)
869 {
870 	struct unw_table_entry *start = (void *) mod->arch.unwind->sh_addr;
871 	struct unw_table_entry *end = start + mod->arch.unwind->sh_size / sizeof (*start);
872 	struct unw_table_entry tmp, *e1, *e2, *core, *init;
873 	unsigned long num_init = 0, num_core = 0;
874 
875 	/* First, count how many init and core unwind-table entries there are.  */
876 	for (e1 = start; e1 < end; ++e1)
877 		if (in_init(mod, e1->start_offset))
878 			++num_init;
879 		else
880 			++num_core;
881 	/*
882 	 * Second, sort the table such that all unwind-table entries for the init and core
883 	 * text sections are nicely separated.  We do this with a stupid bubble sort
884 	 * (unwind tables don't get ridiculously huge).
885 	 */
886 	for (e1 = start; e1 < end; ++e1) {
887 		for (e2 = e1 + 1; e2 < end; ++e2) {
888 			if (e2->start_offset < e1->start_offset) {
889 				tmp = *e1;
890 				*e1 = *e2;
891 				*e2 = tmp;
892 			}
893 		}
894 	}
895 	/*
896 	 * Third, locate the init and core segments in the unwind table:
897 	 */
898 	if (in_init(mod, start->start_offset)) {
899 		init = start;
900 		core = start + num_init;
901 	} else {
902 		core = start;
903 		init = start + num_core;
904 	}
905 
906 	DEBUGP("%s: name=%s, gp=%lx, num_init=%lu, num_core=%lu\n", __func__,
907 	       mod->name, mod->arch.gp, num_init, num_core);
908 
909 	/*
910 	 * Fourth, register both tables (if not empty).
911 	 */
912 	if (num_core > 0) {
913 		mod->arch.core_unw_table = unw_add_unwind_table(mod->name, 0, mod->arch.gp,
914 								core, core + num_core);
915 		DEBUGP("%s:  core: handle=%p [%p-%p)\n", __func__,
916 		       mod->arch.core_unw_table, core, core + num_core);
917 	}
918 	if (num_init > 0) {
919 		mod->arch.init_unw_table = unw_add_unwind_table(mod->name, 0, mod->arch.gp,
920 								init, init + num_init);
921 		DEBUGP("%s:  init: handle=%p [%p-%p)\n", __func__,
922 		       mod->arch.init_unw_table, init, init + num_init);
923 	}
924 }
925 
926 int
927 module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod)
928 {
929 	DEBUGP("%s: init: entry=%p\n", __func__, mod->init);
930 	if (mod->arch.unwind)
931 		register_unwind_table(mod);
932 	return 0;
933 }
934 
935 void
936 module_arch_cleanup (struct module *mod)
937 {
938 	if (mod->arch.init_unw_table)
939 		unw_remove_unwind_table(mod->arch.init_unw_table);
940 	if (mod->arch.core_unw_table)
941 		unw_remove_unwind_table(mod->arch.core_unw_table);
942 }
943