xref: /linux/arch/s390/kernel/module.c (revision 95f28190aa012b18eab14799b905b6db3cf31529)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  Kernel module help for s390.
4  *
5  *  S390 version
6  *    Copyright IBM Corp. 2002, 2003
7  *    Author(s): Arnd Bergmann (arndb@de.ibm.com)
8  *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
9  *
10  *  based on i386 version
11  *    Copyright (C) 2001 Rusty Russell.
12  */
13 #include <linux/module.h>
14 #include <linux/elf.h>
15 #include <linux/vmalloc.h>
16 #include <linux/fs.h>
17 #include <linux/string.h>
18 #include <linux/kernel.h>
19 #include <linux/moduleloader.h>
20 #include <linux/bug.h>
21 #include <asm/alternative.h>
22 
23 #if 0
24 #define DEBUGP printk
25 #else
26 #define DEBUGP(fmt , ...)
27 #endif
28 
29 #define PLT_ENTRY_SIZE 20
30 
31 void *module_alloc(unsigned long size)
32 {
33 	if (PAGE_ALIGN(size) > MODULES_LEN)
34 		return NULL;
35 	return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
36 				    GFP_KERNEL, PAGE_KERNEL_EXEC,
37 				    0, NUMA_NO_NODE,
38 				    __builtin_return_address(0));
39 }
40 
41 void module_arch_freeing_init(struct module *mod)
42 {
43 	if (is_livepatch_module(mod) &&
44 	    mod->state == MODULE_STATE_LIVE)
45 		return;
46 
47 	vfree(mod->arch.syminfo);
48 	mod->arch.syminfo = NULL;
49 }
50 
51 static void check_rela(Elf_Rela *rela, struct module *me)
52 {
53 	struct mod_arch_syminfo *info;
54 
55 	info = me->arch.syminfo + ELF_R_SYM (rela->r_info);
56 	switch (ELF_R_TYPE (rela->r_info)) {
57 	case R_390_GOT12:	/* 12 bit GOT offset.  */
58 	case R_390_GOT16:	/* 16 bit GOT offset.  */
59 	case R_390_GOT20:	/* 20 bit GOT offset.  */
60 	case R_390_GOT32:	/* 32 bit GOT offset.  */
61 	case R_390_GOT64:	/* 64 bit GOT offset.  */
62 	case R_390_GOTENT:	/* 32 bit PC rel. to GOT entry shifted by 1. */
63 	case R_390_GOTPLT12:	/* 12 bit offset to jump slot.	*/
64 	case R_390_GOTPLT16:	/* 16 bit offset to jump slot.  */
65 	case R_390_GOTPLT20:	/* 20 bit offset to jump slot.  */
66 	case R_390_GOTPLT32:	/* 32 bit offset to jump slot.  */
67 	case R_390_GOTPLT64:	/* 64 bit offset to jump slot.	*/
68 	case R_390_GOTPLTENT:	/* 32 bit rel. offset to jump slot >> 1. */
69 		if (info->got_offset == -1UL) {
70 			info->got_offset = me->arch.got_size;
71 			me->arch.got_size += sizeof(void*);
72 		}
73 		break;
74 	case R_390_PLT16DBL:	/* 16 bit PC rel. PLT shifted by 1.  */
75 	case R_390_PLT32DBL:	/* 32 bit PC rel. PLT shifted by 1.  */
76 	case R_390_PLT32:	/* 32 bit PC relative PLT address.  */
77 	case R_390_PLT64:	/* 64 bit PC relative PLT address.  */
78 	case R_390_PLTOFF16:	/* 16 bit offset from GOT to PLT. */
79 	case R_390_PLTOFF32:	/* 32 bit offset from GOT to PLT. */
80 	case R_390_PLTOFF64:	/* 16 bit offset from GOT to PLT. */
81 		if (info->plt_offset == -1UL) {
82 			info->plt_offset = me->arch.plt_size;
83 			me->arch.plt_size += PLT_ENTRY_SIZE;
84 		}
85 		break;
86 	case R_390_COPY:
87 	case R_390_GLOB_DAT:
88 	case R_390_JMP_SLOT:
89 	case R_390_RELATIVE:
90 		/* Only needed if we want to support loading of
91 		   modules linked with -shared. */
92 		break;
93 	}
94 }
95 
96 /*
97  * Account for GOT and PLT relocations. We can't add sections for
98  * got and plt but we can increase the core module size.
99  */
100 int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
101 			      char *secstrings, struct module *me)
102 {
103 	Elf_Shdr *symtab;
104 	Elf_Sym *symbols;
105 	Elf_Rela *rela;
106 	char *strings;
107 	int nrela, i, j;
108 
109 	/* Find symbol table and string table. */
110 	symtab = NULL;
111 	for (i = 0; i < hdr->e_shnum; i++)
112 		switch (sechdrs[i].sh_type) {
113 		case SHT_SYMTAB:
114 			symtab = sechdrs + i;
115 			break;
116 		}
117 	if (!symtab) {
118 		printk(KERN_ERR "module %s: no symbol table\n", me->name);
119 		return -ENOEXEC;
120 	}
121 
122 	/* Allocate one syminfo structure per symbol. */
123 	me->arch.nsyms = symtab->sh_size / sizeof(Elf_Sym);
124 	me->arch.syminfo = vmalloc(me->arch.nsyms *
125 				   sizeof(struct mod_arch_syminfo));
126 	if (!me->arch.syminfo)
127 		return -ENOMEM;
128 	symbols = (void *) hdr + symtab->sh_offset;
129 	strings = (void *) hdr + sechdrs[symtab->sh_link].sh_offset;
130 	for (i = 0; i < me->arch.nsyms; i++) {
131 		if (symbols[i].st_shndx == SHN_UNDEF &&
132 		    strcmp(strings + symbols[i].st_name,
133 			   "_GLOBAL_OFFSET_TABLE_") == 0)
134 			/* "Define" it as absolute. */
135 			symbols[i].st_shndx = SHN_ABS;
136 		me->arch.syminfo[i].got_offset = -1UL;
137 		me->arch.syminfo[i].plt_offset = -1UL;
138 		me->arch.syminfo[i].got_initialized = 0;
139 		me->arch.syminfo[i].plt_initialized = 0;
140 	}
141 
142 	/* Search for got/plt relocations. */
143 	me->arch.got_size = me->arch.plt_size = 0;
144 	for (i = 0; i < hdr->e_shnum; i++) {
145 		if (sechdrs[i].sh_type != SHT_RELA)
146 			continue;
147 		nrela = sechdrs[i].sh_size / sizeof(Elf_Rela);
148 		rela = (void *) hdr + sechdrs[i].sh_offset;
149 		for (j = 0; j < nrela; j++)
150 			check_rela(rela + j, me);
151 	}
152 
153 	/* Increase core size by size of got & plt and set start
154 	   offsets for got and plt. */
155 	me->core_layout.size = ALIGN(me->core_layout.size, 4);
156 	me->arch.got_offset = me->core_layout.size;
157 	me->core_layout.size += me->arch.got_size;
158 	me->arch.plt_offset = me->core_layout.size;
159 	me->core_layout.size += me->arch.plt_size;
160 	return 0;
161 }
162 
163 static int apply_rela_bits(Elf_Addr loc, Elf_Addr val,
164 			   int sign, int bits, int shift)
165 {
166 	unsigned long umax;
167 	long min, max;
168 
169 	if (val & ((1UL << shift) - 1))
170 		return -ENOEXEC;
171 	if (sign) {
172 		val = (Elf_Addr)(((long) val) >> shift);
173 		min = -(1L << (bits - 1));
174 		max = (1L << (bits - 1)) - 1;
175 		if ((long) val < min || (long) val > max)
176 			return -ENOEXEC;
177 	} else {
178 		val >>= shift;
179 		umax = ((1UL << (bits - 1)) << 1) - 1;
180 		if ((unsigned long) val > umax)
181 			return -ENOEXEC;
182 	}
183 
184 	if (bits == 8)
185 		*(unsigned char *) loc = val;
186 	else if (bits == 12)
187 		*(unsigned short *) loc = (val & 0xfff) |
188 			(*(unsigned short *) loc & 0xf000);
189 	else if (bits == 16)
190 		*(unsigned short *) loc = val;
191 	else if (bits == 20)
192 		*(unsigned int *) loc = (val & 0xfff) << 16 |
193 			(val & 0xff000) >> 4 |
194 			(*(unsigned int *) loc & 0xf00000ff);
195 	else if (bits == 32)
196 		*(unsigned int *) loc = val;
197 	else if (bits == 64)
198 		*(unsigned long *) loc = val;
199 	return 0;
200 }
201 
202 static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
203 		      const char *strtab, struct module *me)
204 {
205 	struct mod_arch_syminfo *info;
206 	Elf_Addr loc, val;
207 	int r_type, r_sym;
208 	int rc = -ENOEXEC;
209 
210 	/* This is where to make the change */
211 	loc = base + rela->r_offset;
212 	/* This is the symbol it is referring to.  Note that all
213 	   undefined symbols have been resolved.  */
214 	r_sym = ELF_R_SYM(rela->r_info);
215 	r_type = ELF_R_TYPE(rela->r_info);
216 	info = me->arch.syminfo + r_sym;
217 	val = symtab[r_sym].st_value;
218 
219 	switch (r_type) {
220 	case R_390_NONE:	/* No relocation.  */
221 		rc = 0;
222 		break;
223 	case R_390_8:		/* Direct 8 bit.   */
224 	case R_390_12:		/* Direct 12 bit.  */
225 	case R_390_16:		/* Direct 16 bit.  */
226 	case R_390_20:		/* Direct 20 bit.  */
227 	case R_390_32:		/* Direct 32 bit.  */
228 	case R_390_64:		/* Direct 64 bit.  */
229 		val += rela->r_addend;
230 		if (r_type == R_390_8)
231 			rc = apply_rela_bits(loc, val, 0, 8, 0);
232 		else if (r_type == R_390_12)
233 			rc = apply_rela_bits(loc, val, 0, 12, 0);
234 		else if (r_type == R_390_16)
235 			rc = apply_rela_bits(loc, val, 0, 16, 0);
236 		else if (r_type == R_390_20)
237 			rc = apply_rela_bits(loc, val, 1, 20, 0);
238 		else if (r_type == R_390_32)
239 			rc = apply_rela_bits(loc, val, 0, 32, 0);
240 		else if (r_type == R_390_64)
241 			rc = apply_rela_bits(loc, val, 0, 64, 0);
242 		break;
243 	case R_390_PC16:	/* PC relative 16 bit.  */
244 	case R_390_PC16DBL:	/* PC relative 16 bit shifted by 1.  */
245 	case R_390_PC32DBL:	/* PC relative 32 bit shifted by 1.  */
246 	case R_390_PC32:	/* PC relative 32 bit.  */
247 	case R_390_PC64:	/* PC relative 64 bit.	*/
248 		val += rela->r_addend - loc;
249 		if (r_type == R_390_PC16)
250 			rc = apply_rela_bits(loc, val, 1, 16, 0);
251 		else if (r_type == R_390_PC16DBL)
252 			rc = apply_rela_bits(loc, val, 1, 16, 1);
253 		else if (r_type == R_390_PC32DBL)
254 			rc = apply_rela_bits(loc, val, 1, 32, 1);
255 		else if (r_type == R_390_PC32)
256 			rc = apply_rela_bits(loc, val, 1, 32, 0);
257 		else if (r_type == R_390_PC64)
258 			rc = apply_rela_bits(loc, val, 1, 64, 0);
259 		break;
260 	case R_390_GOT12:	/* 12 bit GOT offset.  */
261 	case R_390_GOT16:	/* 16 bit GOT offset.  */
262 	case R_390_GOT20:	/* 20 bit GOT offset.  */
263 	case R_390_GOT32:	/* 32 bit GOT offset.  */
264 	case R_390_GOT64:	/* 64 bit GOT offset.  */
265 	case R_390_GOTENT:	/* 32 bit PC rel. to GOT entry shifted by 1. */
266 	case R_390_GOTPLT12:	/* 12 bit offset to jump slot.	*/
267 	case R_390_GOTPLT20:	/* 20 bit offset to jump slot.  */
268 	case R_390_GOTPLT16:	/* 16 bit offset to jump slot.  */
269 	case R_390_GOTPLT32:	/* 32 bit offset to jump slot.  */
270 	case R_390_GOTPLT64:	/* 64 bit offset to jump slot.	*/
271 	case R_390_GOTPLTENT:	/* 32 bit rel. offset to jump slot >> 1. */
272 		if (info->got_initialized == 0) {
273 			Elf_Addr *gotent;
274 
275 			gotent = me->core_layout.base + me->arch.got_offset +
276 				info->got_offset;
277 			*gotent = val;
278 			info->got_initialized = 1;
279 		}
280 		val = info->got_offset + rela->r_addend;
281 		if (r_type == R_390_GOT12 ||
282 		    r_type == R_390_GOTPLT12)
283 			rc = apply_rela_bits(loc, val, 0, 12, 0);
284 		else if (r_type == R_390_GOT16 ||
285 			 r_type == R_390_GOTPLT16)
286 			rc = apply_rela_bits(loc, val, 0, 16, 0);
287 		else if (r_type == R_390_GOT20 ||
288 			 r_type == R_390_GOTPLT20)
289 			rc = apply_rela_bits(loc, val, 1, 20, 0);
290 		else if (r_type == R_390_GOT32 ||
291 			 r_type == R_390_GOTPLT32)
292 			rc = apply_rela_bits(loc, val, 0, 32, 0);
293 		else if (r_type == R_390_GOT64 ||
294 			 r_type == R_390_GOTPLT64)
295 			rc = apply_rela_bits(loc, val, 0, 64, 0);
296 		else if (r_type == R_390_GOTENT ||
297 			 r_type == R_390_GOTPLTENT) {
298 			val += (Elf_Addr) me->core_layout.base - loc;
299 			rc = apply_rela_bits(loc, val, 1, 32, 1);
300 		}
301 		break;
302 	case R_390_PLT16DBL:	/* 16 bit PC rel. PLT shifted by 1.  */
303 	case R_390_PLT32DBL:	/* 32 bit PC rel. PLT shifted by 1.  */
304 	case R_390_PLT32:	/* 32 bit PC relative PLT address.  */
305 	case R_390_PLT64:	/* 64 bit PC relative PLT address.  */
306 	case R_390_PLTOFF16:	/* 16 bit offset from GOT to PLT. */
307 	case R_390_PLTOFF32:	/* 32 bit offset from GOT to PLT. */
308 	case R_390_PLTOFF64:	/* 16 bit offset from GOT to PLT. */
309 		if (info->plt_initialized == 0) {
310 			unsigned int *ip;
311 			ip = me->core_layout.base + me->arch.plt_offset +
312 				info->plt_offset;
313 			ip[0] = 0x0d10e310; /* basr 1,0; lg 1,10(1); br 1 */
314 			ip[1] = 0x100a0004;
315 			ip[2] = 0x07f10000;
316 			ip[3] = (unsigned int) (val >> 32);
317 			ip[4] = (unsigned int) val;
318 			info->plt_initialized = 1;
319 		}
320 		if (r_type == R_390_PLTOFF16 ||
321 		    r_type == R_390_PLTOFF32 ||
322 		    r_type == R_390_PLTOFF64)
323 			val = me->arch.plt_offset - me->arch.got_offset +
324 				info->plt_offset + rela->r_addend;
325 		else {
326 			if (!((r_type == R_390_PLT16DBL &&
327 			       val - loc + 0xffffUL < 0x1ffffeUL) ||
328 			      (r_type == R_390_PLT32DBL &&
329 			       val - loc + 0xffffffffULL < 0x1fffffffeULL)))
330 				val = (Elf_Addr) me->core_layout.base +
331 					me->arch.plt_offset +
332 					info->plt_offset;
333 			val += rela->r_addend - loc;
334 		}
335 		if (r_type == R_390_PLT16DBL)
336 			rc = apply_rela_bits(loc, val, 1, 16, 1);
337 		else if (r_type == R_390_PLTOFF16)
338 			rc = apply_rela_bits(loc, val, 0, 16, 0);
339 		else if (r_type == R_390_PLT32DBL)
340 			rc = apply_rela_bits(loc, val, 1, 32, 1);
341 		else if (r_type == R_390_PLT32 ||
342 			 r_type == R_390_PLTOFF32)
343 			rc = apply_rela_bits(loc, val, 0, 32, 0);
344 		else if (r_type == R_390_PLT64 ||
345 			 r_type == R_390_PLTOFF64)
346 			rc = apply_rela_bits(loc, val, 0, 64, 0);
347 		break;
348 	case R_390_GOTOFF16:	/* 16 bit offset to GOT.  */
349 	case R_390_GOTOFF32:	/* 32 bit offset to GOT.  */
350 	case R_390_GOTOFF64:	/* 64 bit offset to GOT. */
351 		val = val + rela->r_addend -
352 			((Elf_Addr) me->core_layout.base + me->arch.got_offset);
353 		if (r_type == R_390_GOTOFF16)
354 			rc = apply_rela_bits(loc, val, 0, 16, 0);
355 		else if (r_type == R_390_GOTOFF32)
356 			rc = apply_rela_bits(loc, val, 0, 32, 0);
357 		else if (r_type == R_390_GOTOFF64)
358 			rc = apply_rela_bits(loc, val, 0, 64, 0);
359 		break;
360 	case R_390_GOTPC:	/* 32 bit PC relative offset to GOT. */
361 	case R_390_GOTPCDBL:	/* 32 bit PC rel. off. to GOT shifted by 1. */
362 		val = (Elf_Addr) me->core_layout.base + me->arch.got_offset +
363 			rela->r_addend - loc;
364 		if (r_type == R_390_GOTPC)
365 			rc = apply_rela_bits(loc, val, 1, 32, 0);
366 		else if (r_type == R_390_GOTPCDBL)
367 			rc = apply_rela_bits(loc, val, 1, 32, 1);
368 		break;
369 	case R_390_COPY:
370 	case R_390_GLOB_DAT:	/* Create GOT entry.  */
371 	case R_390_JMP_SLOT:	/* Create PLT entry.  */
372 	case R_390_RELATIVE:	/* Adjust by program base.  */
373 		/* Only needed if we want to support loading of
374 		   modules linked with -shared. */
375 		return -ENOEXEC;
376 	default:
377 		printk(KERN_ERR "module %s: unknown relocation: %u\n",
378 		       me->name, r_type);
379 		return -ENOEXEC;
380 	}
381 	if (rc) {
382 		printk(KERN_ERR "module %s: relocation error for symbol %s "
383 		       "(r_type %i, value 0x%lx)\n",
384 		       me->name, strtab + symtab[r_sym].st_name,
385 		       r_type, (unsigned long) val);
386 		return rc;
387 	}
388 	return 0;
389 }
390 
391 int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
392 		       unsigned int symindex, unsigned int relsec,
393 		       struct module *me)
394 {
395 	Elf_Addr base;
396 	Elf_Sym *symtab;
397 	Elf_Rela *rela;
398 	unsigned long i, n;
399 	int rc;
400 
401 	DEBUGP("Applying relocate section %u to %u\n",
402 	       relsec, sechdrs[relsec].sh_info);
403 	base = sechdrs[sechdrs[relsec].sh_info].sh_addr;
404 	symtab = (Elf_Sym *) sechdrs[symindex].sh_addr;
405 	rela = (Elf_Rela *) sechdrs[relsec].sh_addr;
406 	n = sechdrs[relsec].sh_size / sizeof(Elf_Rela);
407 
408 	for (i = 0; i < n; i++, rela++) {
409 		rc = apply_rela(rela, base, symtab, strtab, me);
410 		if (rc)
411 			return rc;
412 	}
413 	return 0;
414 }
415 
416 int module_finalize(const Elf_Ehdr *hdr,
417 		    const Elf_Shdr *sechdrs,
418 		    struct module *me)
419 {
420 	const Elf_Shdr *s;
421 	char *secstrings;
422 
423 	secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
424 	for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
425 		if (!strcmp(".altinstructions", secstrings + s->sh_name)) {
426 			/* patch .altinstructions */
427 			void *aseg = (void *)s->sh_addr;
428 
429 			apply_alternatives(aseg, aseg + s->sh_size);
430 		}
431 	}
432 
433 	jump_label_apply_nops(me);
434 	return 0;
435 }
436