Linux Audio

Check our new training course

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