cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

module.c (27166B)


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