xref: /linux/arch/s390/tools/relocs.c (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <stdio.h>
4 #include <stdarg.h>
5 #include <stdlib.h>
6 #include <stdint.h>
7 #include <inttypes.h>
8 #include <string.h>
9 #include <errno.h>
10 #include <unistd.h>
11 #include <elf.h>
12 #include <byteswap.h>
13 #define USE_BSD
14 #include <endian.h>
15 
16 #define ELF_BITS 64
17 
18 #define ELF_MACHINE		EM_S390
19 #define ELF_MACHINE_NAME	"IBM S/390"
20 #define SHT_REL_TYPE		SHT_RELA
21 #define Elf_Rel			Elf64_Rela
22 
23 #define ELF_CLASS		ELFCLASS64
24 #define ELF_ENDIAN		ELFDATA2MSB
25 #define ELF_R_SYM(val)		ELF64_R_SYM(val)
26 #define ELF_R_TYPE(val)		ELF64_R_TYPE(val)
27 #define ELF_ST_TYPE(o)		ELF64_ST_TYPE(o)
28 #define ELF_ST_BIND(o)		ELF64_ST_BIND(o)
29 #define ELF_ST_VISIBILITY(o)	ELF64_ST_VISIBILITY(o)
30 
31 #define ElfW(type)		_ElfW(ELF_BITS, type)
32 #define _ElfW(bits, type)	__ElfW(bits, type)
33 #define __ElfW(bits, type)	Elf##bits##_##type
34 
35 #define Elf_Addr		ElfW(Addr)
36 #define Elf_Ehdr		ElfW(Ehdr)
37 #define Elf_Phdr		ElfW(Phdr)
38 #define Elf_Shdr		ElfW(Shdr)
39 #define Elf_Sym			ElfW(Sym)
40 
41 static Elf_Ehdr		ehdr;
42 static unsigned long	shnum;
43 static unsigned int	shstrndx;
44 static unsigned int	shsymtabndx;
45 static unsigned int	shxsymtabndx;
46 
47 static int sym_index(Elf_Sym *sym);
48 
49 struct relocs {
50 	uint32_t	*offset;
51 	unsigned long	count;
52 	unsigned long	size;
53 };
54 
55 static struct relocs relocs64;
56 #define FMT PRIu64
57 
58 struct section {
59 	Elf_Shdr	shdr;
60 	struct section	*link;
61 	Elf_Sym		*symtab;
62 	Elf32_Word	*xsymtab;
63 	Elf_Rel		*reltab;
64 	char		*strtab;
65 };
66 
67 static struct section *secs;
68 
69 static const char *sec_name(unsigned shndx)
70 {
71 	const char *sec_strtab;
72 	const char *name = "<noname>";
73 	sec_strtab = secs[shstrndx].strtab;
74 
75 	if (shndx < shnum)
76 		name = sec_strtab + secs[shndx].shdr.sh_name;
77 	else if (shndx == SHN_ABS)
78 		name = "ABSOLUTE";
79 	else if (shndx == SHN_COMMON)
80 		name = "COMMON";
81 	return name;
82 }
83 
84 static const char *sym_name(const char *sym_strtab, Elf_Sym *sym)
85 {
86 	const char *name;
87 
88 	if (sym->st_name)
89 		name = sym_strtab + sym->st_name;
90 	else
91 		name = sec_name(sym_index(sym));
92 	return name;
93 }
94 
95 #if BYTE_ORDER == LITTLE_ENDIAN
96 #define le16_to_cpu(val)	(val)
97 #define le32_to_cpu(val)	(val)
98 #define le64_to_cpu(val)	(val)
99 #define be16_to_cpu(val)	bswap_16(val)
100 #define be32_to_cpu(val)	bswap_32(val)
101 #define be64_to_cpu(val)	bswap_64(val)
102 #endif
103 
104 #if BYTE_ORDER == BIG_ENDIAN
105 #define le16_to_cpu(val)	bswap_16(val)
106 #define le32_to_cpu(val)	bswap_32(val)
107 #define le64_to_cpu(val)	bswap_64(val)
108 #define be16_to_cpu(val)	(val)
109 #define be32_to_cpu(val)	(val)
110 #define be64_to_cpu(val)	(val)
111 #endif
112 
113 static uint16_t elf16_to_cpu(uint16_t val)
114 {
115 	if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
116 		return le16_to_cpu(val);
117 	else
118 		return be16_to_cpu(val);
119 }
120 
121 static uint32_t elf32_to_cpu(uint32_t val)
122 {
123 	if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
124 		return le32_to_cpu(val);
125 	else
126 		return be32_to_cpu(val);
127 }
128 
129 #define elf_half_to_cpu(x)	elf16_to_cpu(x)
130 #define elf_word_to_cpu(x)	elf32_to_cpu(x)
131 
132 static uint64_t elf64_to_cpu(uint64_t val)
133 {
134 	return be64_to_cpu(val);
135 }
136 
137 #define elf_addr_to_cpu(x)	elf64_to_cpu(x)
138 #define elf_off_to_cpu(x)	elf64_to_cpu(x)
139 #define elf_xword_to_cpu(x)	elf64_to_cpu(x)
140 
141 static int sym_index(Elf_Sym *sym)
142 {
143 	Elf_Sym *symtab = secs[shsymtabndx].symtab;
144 	Elf32_Word *xsymtab = secs[shxsymtabndx].xsymtab;
145 	unsigned long offset;
146 	int index;
147 
148 	if (sym->st_shndx != SHN_XINDEX)
149 		return sym->st_shndx;
150 
151 	/* calculate offset of sym from head of table. */
152 	offset = (unsigned long)sym - (unsigned long)symtab;
153 	index = offset / sizeof(*sym);
154 
155 	return elf32_to_cpu(xsymtab[index]);
156 }
157 
158 static void die(char *fmt, ...)
159 {
160 	va_list ap;
161 
162 	va_start(ap, fmt);
163 	vfprintf(stderr, fmt, ap);
164 	va_end(ap);
165 	exit(1);
166 }
167 
168 static void read_ehdr(FILE *fp)
169 {
170 	if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
171 		die("Cannot read ELF header: %s\n", strerror(errno));
172 	if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0)
173 		die("No ELF magic\n");
174 	if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
175 		die("Not a %d bit executable\n", ELF_BITS);
176 	if (ehdr.e_ident[EI_DATA] != ELF_ENDIAN)
177 		die("ELF endian mismatch\n");
178 	if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
179 		die("Unknown ELF version\n");
180 
181 	/* Convert the fields to native endian */
182 	ehdr.e_type	 = elf_half_to_cpu(ehdr.e_type);
183 	ehdr.e_machine	 = elf_half_to_cpu(ehdr.e_machine);
184 	ehdr.e_version	 = elf_word_to_cpu(ehdr.e_version);
185 	ehdr.e_entry	 = elf_addr_to_cpu(ehdr.e_entry);
186 	ehdr.e_phoff	 = elf_off_to_cpu(ehdr.e_phoff);
187 	ehdr.e_shoff	 = elf_off_to_cpu(ehdr.e_shoff);
188 	ehdr.e_flags	 = elf_word_to_cpu(ehdr.e_flags);
189 	ehdr.e_ehsize	 = elf_half_to_cpu(ehdr.e_ehsize);
190 	ehdr.e_phentsize = elf_half_to_cpu(ehdr.e_phentsize);
191 	ehdr.e_phnum	 = elf_half_to_cpu(ehdr.e_phnum);
192 	ehdr.e_shentsize = elf_half_to_cpu(ehdr.e_shentsize);
193 	ehdr.e_shnum	 = elf_half_to_cpu(ehdr.e_shnum);
194 	ehdr.e_shstrndx  = elf_half_to_cpu(ehdr.e_shstrndx);
195 
196 	shnum = ehdr.e_shnum;
197 	shstrndx = ehdr.e_shstrndx;
198 
199 	if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN))
200 		die("Unsupported ELF header type\n");
201 	if (ehdr.e_machine != ELF_MACHINE)
202 		die("Not for %s\n", ELF_MACHINE_NAME);
203 	if (ehdr.e_version != EV_CURRENT)
204 		die("Unknown ELF version\n");
205 	if (ehdr.e_ehsize != sizeof(Elf_Ehdr))
206 		die("Bad Elf header size\n");
207 	if (ehdr.e_phentsize != sizeof(Elf_Phdr))
208 		die("Bad program header entry\n");
209 	if (ehdr.e_shentsize != sizeof(Elf_Shdr))
210 		die("Bad section header entry\n");
211 
212 	if (shnum == SHN_UNDEF || shstrndx == SHN_XINDEX) {
213 		Elf_Shdr shdr;
214 
215 		if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0)
216 			die("Seek to %" FMT " failed: %s\n", ehdr.e_shoff, strerror(errno));
217 
218 		if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
219 			die("Cannot read initial ELF section header: %s\n", strerror(errno));
220 
221 		if (shnum == SHN_UNDEF)
222 			shnum = elf_xword_to_cpu(shdr.sh_size);
223 
224 		if (shstrndx == SHN_XINDEX)
225 			shstrndx = elf_word_to_cpu(shdr.sh_link);
226 	}
227 
228 	if (shstrndx >= shnum)
229 		die("String table index out of bounds\n");
230 }
231 
232 static void read_shdrs(FILE *fp)
233 {
234 	Elf_Shdr shdr;
235 	int i;
236 
237 	secs = calloc(shnum, sizeof(struct section));
238 	if (!secs)
239 		die("Unable to allocate %ld section headers\n", shnum);
240 
241 	if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0)
242 		die("Seek to %" FMT " failed: %s\n", ehdr.e_shoff, strerror(errno));
243 
244 	for (i = 0; i < shnum; i++) {
245 		struct section *sec = &secs[i];
246 
247 		if (fread(&shdr, sizeof(shdr), 1, fp) != 1) {
248 			die("Cannot read ELF section headers %d/%ld: %s\n",
249 			    i, shnum, strerror(errno));
250 		}
251 
252 		sec->shdr.sh_name      = elf_word_to_cpu(shdr.sh_name);
253 		sec->shdr.sh_type      = elf_word_to_cpu(shdr.sh_type);
254 		sec->shdr.sh_flags     = elf_xword_to_cpu(shdr.sh_flags);
255 		sec->shdr.sh_addr      = elf_addr_to_cpu(shdr.sh_addr);
256 		sec->shdr.sh_offset    = elf_off_to_cpu(shdr.sh_offset);
257 		sec->shdr.sh_size      = elf_xword_to_cpu(shdr.sh_size);
258 		sec->shdr.sh_link      = elf_word_to_cpu(shdr.sh_link);
259 		sec->shdr.sh_info      = elf_word_to_cpu(shdr.sh_info);
260 		sec->shdr.sh_addralign = elf_xword_to_cpu(shdr.sh_addralign);
261 		sec->shdr.sh_entsize   = elf_xword_to_cpu(shdr.sh_entsize);
262 
263 		if (sec->shdr.sh_link < shnum)
264 			sec->link = &secs[sec->shdr.sh_link];
265 	}
266 
267 }
268 
269 static void read_strtabs(FILE *fp)
270 {
271 	int i;
272 
273 	for (i = 0; i < shnum; i++) {
274 		struct section *sec = &secs[i];
275 
276 		if (sec->shdr.sh_type != SHT_STRTAB)
277 			continue;
278 
279 		sec->strtab = malloc(sec->shdr.sh_size);
280 		if (!sec->strtab)
281 			die("malloc of %" FMT " bytes for strtab failed\n", sec->shdr.sh_size);
282 
283 		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
284 			die("Seek to %" FMT " failed: %s\n", sec->shdr.sh_offset, strerror(errno));
285 
286 		if (fread(sec->strtab, 1, sec->shdr.sh_size, fp) != sec->shdr.sh_size)
287 			die("Cannot read symbol table: %s\n", strerror(errno));
288 	}
289 }
290 
291 static void read_symtabs(FILE *fp)
292 {
293 	int i, j;
294 
295 	for (i = 0; i < shnum; i++) {
296 		struct section *sec = &secs[i];
297 		int num_syms;
298 
299 		switch (sec->shdr.sh_type) {
300 		case SHT_SYMTAB_SHNDX:
301 			sec->xsymtab = malloc(sec->shdr.sh_size);
302 			if (!sec->xsymtab)
303 				die("malloc of %" FMT " bytes for xsymtab failed\n", sec->shdr.sh_size);
304 
305 			if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
306 				die("Seek to %" FMT " failed: %s\n", sec->shdr.sh_offset, strerror(errno));
307 
308 			if (fread(sec->xsymtab, 1, sec->shdr.sh_size, fp) != sec->shdr.sh_size)
309 				die("Cannot read extended symbol table: %s\n", strerror(errno));
310 
311 			shxsymtabndx = i;
312 			continue;
313 
314 		case SHT_SYMTAB:
315 			num_syms = sec->shdr.sh_size / sizeof(Elf_Sym);
316 
317 			sec->symtab = malloc(sec->shdr.sh_size);
318 			if (!sec->symtab)
319 				die("malloc of %" FMT " bytes for symtab failed\n", sec->shdr.sh_size);
320 
321 			if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
322 				die("Seek to %" FMT " failed: %s\n", sec->shdr.sh_offset, strerror(errno));
323 
324 			if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) != sec->shdr.sh_size)
325 				die("Cannot read symbol table: %s\n", strerror(errno));
326 
327 			for (j = 0; j < num_syms; j++) {
328 				Elf_Sym *sym = &sec->symtab[j];
329 
330 				sym->st_name  = elf_word_to_cpu(sym->st_name);
331 				sym->st_value = elf_addr_to_cpu(sym->st_value);
332 				sym->st_size  = elf_xword_to_cpu(sym->st_size);
333 				sym->st_shndx = elf_half_to_cpu(sym->st_shndx);
334 			}
335 			shsymtabndx = i;
336 			continue;
337 
338 		default:
339 			continue;
340 		}
341 	}
342 }
343 
344 static void read_relocs(FILE *fp)
345 {
346 	int i, j;
347 
348 	for (i = 0; i < shnum; i++) {
349 		struct section *sec = &secs[i];
350 
351 		if (sec->shdr.sh_type != SHT_REL_TYPE)
352 			continue;
353 
354 		sec->reltab = malloc(sec->shdr.sh_size);
355 		if (!sec->reltab)
356 			die("malloc of %" FMT " bytes for relocs failed\n", sec->shdr.sh_size);
357 
358 		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
359 			die("Seek to %" FMT " failed: %s\n", sec->shdr.sh_offset, strerror(errno));
360 
361 		if (fread(sec->reltab, 1, sec->shdr.sh_size, fp) != sec->shdr.sh_size)
362 			die("Cannot read symbol table: %s\n", strerror(errno));
363 
364 		for (j = 0; j < sec->shdr.sh_size / sizeof(Elf_Rel); j++) {
365 			Elf_Rel *rel = &sec->reltab[j];
366 
367 			rel->r_offset = elf_addr_to_cpu(rel->r_offset);
368 			rel->r_info   = elf_xword_to_cpu(rel->r_info);
369 #if (SHT_REL_TYPE == SHT_RELA)
370 			rel->r_addend = elf_xword_to_cpu(rel->r_addend);
371 #endif
372 		}
373 	}
374 }
375 
376 static void add_reloc(struct relocs *r, uint32_t offset)
377 {
378 	if (r->count == r->size) {
379 		unsigned long newsize = r->size + 50000;
380 		void *mem = realloc(r->offset, newsize * sizeof(r->offset[0]));
381 
382 		if (!mem)
383 			die("realloc of %ld entries for relocs failed\n", newsize);
384 
385 		r->offset = mem;
386 		r->size = newsize;
387 	}
388 	r->offset[r->count++] = offset;
389 }
390 
391 static int do_reloc(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
392 		    const char *symname)
393 {
394 	unsigned int r_type = ELF64_R_TYPE(rel->r_info);
395 	ElfW(Addr) offset = rel->r_offset;
396 
397 	switch (r_type) {
398 	case R_390_NONE:
399 	case R_390_PC32:
400 	case R_390_PC64:
401 	case R_390_PC16DBL:
402 	case R_390_PC32DBL:
403 	case R_390_PLT32DBL:
404 	case R_390_GOTENT:
405 	case R_390_GOTPCDBL:
406 	case R_390_GOTOFF64:
407 		break;
408 	case R_390_32: {
409 		static const char kcfipfx[] = "__kcfi_typeid_";
410 
411 		if (sym->st_shndx != SHN_ABS)
412 			die("Unsupported relocation type: %d\n", r_type);
413 		/*
414 		 * Symbols with __kcfi_typeid_ prefix have constant values,
415 		 * which do not change if bzImage is loaded at a different
416 		 * physical address than the address for which it has been
417 		 * compiled.
418 		 */
419 		if (!strncmp(kcfipfx, symname, sizeof(kcfipfx) - 1))
420 			break;
421 		die("Invalid absolute R_390_32 relocation: %s\n", symname);
422 		break;
423 	}
424 	case R_390_64:
425 		add_reloc(&relocs64, offset);
426 		break;
427 	default:
428 		die("Unsupported relocation type: %d\n", r_type);
429 		break;
430 	}
431 
432 	return 0;
433 }
434 
435 static void walk_relocs(void)
436 {
437 	int i;
438 
439 	/* Walk through the relocations */
440 	for (i = 0; i < shnum; i++) {
441 		char *sym_strtab;
442 		Elf_Sym *sh_symtab;
443 		struct section *sec_applies, *sec_symtab;
444 		int j;
445 		struct section *sec = &secs[i];
446 
447 		if (sec->shdr.sh_type != SHT_REL_TYPE)
448 			continue;
449 
450 		sec_symtab  = sec->link;
451 		sec_applies = &secs[sec->shdr.sh_info];
452 		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC))
453 			continue;
454 
455 		sh_symtab = sec_symtab->symtab;
456 		sym_strtab = sec_symtab->link->strtab;
457 
458 		for (j = 0; j < sec->shdr.sh_size / sizeof(Elf_Rel); j++) {
459 			Elf_Rel *rel = &sec->reltab[j];
460 			Elf_Sym *sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
461 			const char *symname = sym_name(sym_strtab, sym);
462 
463 			do_reloc(sec, rel, sym, symname);
464 		}
465 	}
466 }
467 
468 static int cmp_relocs(const void *va, const void *vb)
469 {
470 	const uint32_t *a, *b;
471 
472 	a = va; b = vb;
473 	return (*a == *b) ? 0 : (*a > *b) ? 1 : -1;
474 }
475 
476 static void sort_relocs(struct relocs *r)
477 {
478 	qsort(r->offset, r->count, sizeof(r->offset[0]), cmp_relocs);
479 }
480 
481 static int print_reloc(uint32_t v)
482 {
483 	return fprintf(stdout, "\t.long 0x%08"PRIx32"\n", v) > 0 ? 0 : -1;
484 }
485 
486 static void emit_relocs(void)
487 {
488 	int i;
489 
490 	walk_relocs();
491 	sort_relocs(&relocs64);
492 
493 	printf(".section \".vmlinux.relocs_64\",\"a\"\n");
494 	for (i = 0; i < relocs64.count; i++)
495 		print_reloc(relocs64.offset[i]);
496 }
497 
498 static void process(FILE *fp)
499 {
500 	read_ehdr(fp);
501 	read_shdrs(fp);
502 	read_strtabs(fp);
503 	read_symtabs(fp);
504 	read_relocs(fp);
505 	emit_relocs();
506 }
507 
508 static void usage(void)
509 {
510 	die("relocs vmlinux\n");
511 }
512 
513 int main(int argc, char **argv)
514 {
515 	unsigned char e_ident[EI_NIDENT];
516 	const char *fname;
517 	FILE *fp;
518 
519 	fname = NULL;
520 
521 	if (argc != 2)
522 		usage();
523 
524 	fname = argv[1];
525 
526 	fp = fopen(fname, "r");
527 	if (!fp)
528 		die("Cannot open %s: %s\n", fname, strerror(errno));
529 
530 	if (fread(&e_ident, 1, EI_NIDENT, fp) != EI_NIDENT)
531 		die("Cannot read %s: %s", fname, strerror(errno));
532 
533 	rewind(fp);
534 
535 	process(fp);
536 
537 	fclose(fp);
538 	return 0;
539 }
540