1 // SPDX-License-Identifier: GPL-2.0
2 /* This is included from relocs_32/64.c */
3 
4 #define ElfW(type)		_ElfW(ELF_BITS, type)
5 #define _ElfW(bits, type)	__ElfW(bits, type)
6 #define __ElfW(bits, type)	Elf##bits##_##type
7 
8 #define Elf_Addr		ElfW(Addr)
9 #define Elf_Ehdr		ElfW(Ehdr)
10 #define Elf_Phdr		ElfW(Phdr)
11 #define Elf_Shdr		ElfW(Shdr)
12 #define Elf_Sym			ElfW(Sym)
13 
14 static Elf_Ehdr ehdr;
15 
16 struct relocs {
17 	uint32_t	*offset;
18 	unsigned long	count;
19 	unsigned long	size;
20 };
21 
22 static struct relocs relocs;
23 
24 struct section {
25 	Elf_Shdr       shdr;
26 	struct section *link;
27 	Elf_Sym        *symtab;
28 	Elf_Rel        *reltab;
29 	char           *strtab;
30 	long           shdr_offset;
31 };
32 static struct section *secs;
33 
34 static const char * const regex_sym_kernel = {
35 /* Symbols matching these regex's should never be relocated */
36 	"^(__crc_)",
37 };
38 
39 static regex_t sym_regex_c;
40 
regex_skip_reloc(const char *sym_name)41 static int regex_skip_reloc(const char *sym_name)
42 {
43 	return !regexec(&sym_regex_c, sym_name, 0, NULL, 0);
44 }
45 
regex_init(void)46 static void regex_init(void)
47 {
48 	char errbuf[128];
49 	int err;
50 
51 	err = regcomp(&sym_regex_c, regex_sym_kernel,
52 			REG_EXTENDED|REG_NOSUB);
53 
54 	if (err) {
55 		regerror(err, &sym_regex_c, errbuf, sizeof(errbuf));
56 		die("%s", errbuf);
57 	}
58 }
59 
rel_type(unsigned type)60 static const char *rel_type(unsigned type)
61 {
62 	static const char * const type_name[] = {
63 #define REL_TYPE(X)[X] = #X
64 		REL_TYPE(R_LARCH_NONE),
65 		REL_TYPE(R_LARCH_32),
66 		REL_TYPE(R_LARCH_64),
67 		REL_TYPE(R_LARCH_MARK_LA),
68 		REL_TYPE(R_LARCH_MARK_PCREL),
69 		REL_TYPE(R_LARCH_SOP_PUSH_PCREL),
70 		REL_TYPE(R_LARCH_SOP_PUSH_ABSOLUTE),
71 		REL_TYPE(R_LARCH_SOP_PUSH_DUP),
72 		REL_TYPE(R_LARCH_SOP_PUSH_PLT_PCREL),
73 		REL_TYPE(R_LARCH_SOP_SUB),
74 		REL_TYPE(R_LARCH_SOP_SL),
75 		REL_TYPE(R_LARCH_SOP_SR),
76 		REL_TYPE(R_LARCH_SOP_ADD),
77 		REL_TYPE(R_LARCH_SOP_AND),
78 		REL_TYPE(R_LARCH_SOP_IF_ELSE),
79 		REL_TYPE(R_LARCH_SOP_POP_32_S_10_5),
80 		REL_TYPE(R_LARCH_SOP_POP_32_U_10_12),
81 		REL_TYPE(R_LARCH_SOP_POP_32_S_10_12),
82 		REL_TYPE(R_LARCH_SOP_POP_32_S_10_16),
83 		REL_TYPE(R_LARCH_SOP_POP_32_S_10_16_S2),
84 		REL_TYPE(R_LARCH_SOP_POP_32_S_5_20),
85 		REL_TYPE(R_LARCH_SOP_POP_32_S_0_5_10_16_S2),
86 		REL_TYPE(R_LARCH_SOP_POP_32_S_0_10_10_16_S2),
87 		REL_TYPE(R_LARCH_SOP_POP_32_U),
88 		REL_TYPE(R_LARCH_ADD32),
89 		REL_TYPE(R_LARCH_ADD64),
90 		REL_TYPE(R_LARCH_SUB32),
91 		REL_TYPE(R_LARCH_SUB64),
92 #undef REL_TYPE
93 	};
94 	const char *name = "unknown type rel type name";
95 
96 	if (type < ARRAY_SIZE(type_name) && type_name[type])
97 		name = type_name[type];
98 	return name;
99 }
100 
sec_name(unsigned shndx)101 static const char *sec_name(unsigned shndx)
102 {
103 	const char *sec_strtab;
104 	const char *name;
105 
106 	sec_strtab = secs[ehdr.e_shstrndx].strtab;
107 	if (shndx < ehdr.e_shnum)
108 		name = sec_strtab + secs[shndx].shdr.sh_name;
109 	else if (shndx == SHN_ABS)
110 		name = "ABSOLUTE";
111 	else if (shndx == SHN_COMMON)
112 		name = "COMMON";
113 	else
114 		name = "<noname>";
115 	return name;
116 }
117 
sec_lookup(const char *secname)118 static struct section *sec_lookup(const char *secname)
119 {
120 	int i;
121 
122 	for (i = 0; i < ehdr.e_shnum; i++)
123 		if (strcmp(secname, sec_name(i)) == 0)
124 			return &secs[i];
125 
126 	return NULL;
127 }
128 
sym_name(const char *sym_strtab, Elf_Sym *sym)129 static const char *sym_name(const char *sym_strtab, Elf_Sym *sym)
130 {
131 	const char *name;
132 
133 	if (sym->st_name)
134 		name = sym_strtab + sym->st_name;
135 	else
136 		name = sec_name(sym->st_shndx);
137 	return name;
138 }
139 
read_ehdr(FILE *fp)140 static void read_ehdr(FILE *fp)
141 {
142 	if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
143 		die("Cannot read ELF header: %s\n", strerror(errno));
144 
145 	if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0)
146 		die("No ELF magic\n");
147 
148 	if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
149 		die("Not a %d bit executable\n", ELF_BITS);
150 
151 	if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
152 		die("Unsupported ELF Endianness\n");
153 
154 	if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
155 		die("Unknown ELF version\n");
156 
157 	if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN))
158 		die("Unsupported ELF header type\n");
159 
160 	if (ehdr.e_machine != ELF_MACHINE)
161 		die("Not for %s\n", ELF_MACHINE_NAME);
162 
163 	if (ehdr.e_version != EV_CURRENT)
164 		die("Unknown ELF version\n");
165 
166 	if (ehdr.e_ehsize != sizeof(Elf_Ehdr))
167 		die("Bad Elf header size\n");
168 
169 	if (ehdr.e_phentsize != sizeof(Elf_Phdr))
170 		die("Bad program header entry\n");
171 
172 	if (ehdr.e_shentsize != sizeof(Elf_Shdr))
173 		die("Bad section header entry\n");
174 
175 	if (ehdr.e_shstrndx >= ehdr.e_shnum)
176 		die("String table index out of bounds\n");
177 }
178 
read_shdrs(FILE *fp)179 static void read_shdrs(FILE *fp)
180 {
181 	int i;
182 
183 	secs = calloc(ehdr.e_shnum, sizeof(struct section));
184 	if (!secs)
185 		die("Unable to allocate %d section headers\n", ehdr.e_shnum);
186 
187 	if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0)
188 		die("Seek to %d failed: %s\n", ehdr.e_shoff, strerror(errno));
189 
190 	for (i = 0; i < ehdr.e_shnum; i++) {
191 		struct section *sec = &secs[i];
192 
193 		sec->shdr_offset = ftell(fp);
194 		if (fread(&sec->shdr, sizeof(Elf_Shdr), 1, fp) != 1)
195 			die("Cannot read ELF section headers %d/%d: %s\n",
196 			    i, ehdr.e_shnum, strerror(errno));
197 
198 		if (sec->shdr.sh_link < ehdr.e_shnum)
199 			sec->link = &secs[sec->shdr.sh_link];
200 	}
201 }
202 
read_strtabs(FILE *fp)203 static void read_strtabs(FILE *fp)
204 {
205 	int i;
206 
207 	for (i = 0; i < ehdr.e_shnum; i++) {
208 		struct section *sec = &secs[i];
209 
210 		if (sec->shdr.sh_type != SHT_STRTAB)
211 			continue;
212 
213 		sec->strtab = malloc(sec->shdr.sh_size);
214 		if (!sec->strtab)
215 			die("malloc of %d bytes for strtab failed\n",
216 			    sec->shdr.sh_size);
217 
218 		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
219 			die("Seek to %d failed: %s\n",
220 			    sec->shdr.sh_offset, strerror(errno));
221 
222 		if (fread(sec->strtab, 1, sec->shdr.sh_size, fp) !=
223 		    sec->shdr.sh_size)
224 			die("Cannot read symbol table: %s\n", strerror(errno));
225 	}
226 }
227 
read_symtabs(FILE *fp)228 static void read_symtabs(FILE *fp)
229 {
230 	int i;
231 
232 	for (i = 0; i < ehdr.e_shnum; i++) {
233 		struct section *sec = &secs[i];
234 		if (sec->shdr.sh_type != SHT_SYMTAB)
235 			continue;
236 
237 		sec->symtab = malloc(sec->shdr.sh_size);
238 		if (!sec->symtab)
239 			die("malloc of %d bytes for symtab failed\n",
240 			    sec->shdr.sh_size);
241 
242 		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
243 			die("Seek to %d failed: %s\n",
244 			    sec->shdr.sh_offset, strerror(errno));
245 
246 		if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) !=
247 		    sec->shdr.sh_size)
248 			die("Cannot read symbol table: %s\n", strerror(errno));
249 	}
250 }
251 
read_relocs(FILE *fp)252 static void read_relocs(FILE *fp)
253 {
254 	static unsigned long base = 0;
255 	int i, j;
256 
257 	if (!base) {
258 		struct section *sec = sec_lookup(".text");
259 
260 		if (!sec)
261 			die("Could not find .text section\n");
262 
263 		base = sec->shdr.sh_addr;
264 	}
265 
266 	for (i = 0; i < ehdr.e_shnum; i++) {
267 		struct section *sec = &secs[i];
268 
269 		if (sec->shdr.sh_type != SHT_REL_TYPE)
270 			continue;
271 
272 		sec->reltab = malloc(sec->shdr.sh_size);
273 		if (!sec->reltab)
274 			die("malloc of %d bytes for relocs failed\n",
275 			    sec->shdr.sh_size);
276 
277 		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
278 			die("Seek to %d failed: %s\n",
279 			    sec->shdr.sh_offset, strerror(errno));
280 
281 		if (fread(sec->reltab, 1, sec->shdr.sh_size, fp) !=
282 		    sec->shdr.sh_size)
283 			die("Cannot read symbol table: %s\n", strerror(errno));
284 
285 		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
286 			Elf_Rel *rel = &sec->reltab[j];
287 
288 			/* Set offset into kernel image */
289 			rel->r_offset -= base;
290 		}
291 	}
292 }
293 
remove_relocs(FILE *fp)294 static void remove_relocs(FILE *fp)
295 {
296 	int i;
297 	Elf_Shdr shdr;
298 
299 	for (i = 0; i < ehdr.e_shnum; i++) {
300 		struct section *sec = &secs[i];
301 
302 		if (sec->shdr.sh_type != SHT_REL_TYPE)
303 			continue;
304 
305 		if (fseek(fp, sec->shdr_offset, SEEK_SET) < 0)
306 			die("Seek to %d failed: %s\n",
307 			    sec->shdr_offset, strerror(errno));
308 
309 		if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
310 			die("Cannot read ELF section headers %d/%d: %s\n",
311 			    i, ehdr.e_shnum, strerror(errno));
312 
313 		/* Set relocation section size to 0, effectively removing it.
314 		 * This is necessary due to lack of support for relocations
315 		 * in objcopy when creating 32bit elf from 64bit elf.
316 		 */
317 		shdr.sh_size = 0;
318 
319 		if (fseek(fp, sec->shdr_offset, SEEK_SET) < 0)
320 			die("Seek to %d failed: %s\n",
321 			    sec->shdr_offset, strerror(errno));
322 
323 		if (fwrite(&shdr, sizeof(shdr), 1, fp) != 1)
324 			die("Cannot write ELF section headers %d/%d: %s\n",
325 			    i, ehdr.e_shnum, strerror(errno));
326 	}
327 }
328 
add_reloc(struct relocs *r, uint32_t offset, unsigned type)329 static void add_reloc(struct relocs *r, uint32_t offset, unsigned type)
330 {
331 	/* Relocation representation in binary table:
332 	 * |76543210|76543210|76543210|76543210|
333 	 * |  Type  |  offset from _text >> 2  |
334 	 */
335 	offset >>= 2;
336 	if (offset > 0x00FFFFFF)
337 		die("Kernel image exceeds maximum size for relocation!\n");
338 
339 	offset = (offset & 0x00FFFFFF) | ((type & 0xFF) << 24);
340 
341 	if (r->count == r->size) {
342 		unsigned long newsize = r->size + 50000;
343 		void *mem = realloc(r->offset, newsize * sizeof(r->offset[0]));
344 
345 		if (!mem)
346 			die("realloc failed\n");
347 
348 		r->offset = mem;
349 		r->size = newsize;
350 	}
351 	r->offset[r->count++] = offset;
352 }
353 
walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, const char *symname))354 static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel,
355 			Elf_Sym *sym, const char *symname))
356 {
357 	int i;
358 
359 	/* Walk through the relocations */
360 	for (i = 0; i < ehdr.e_shnum; i++) {
361 		char *sym_strtab;
362 		Elf_Sym *sh_symtab;
363 		struct section *sec_applies, *sec_symtab;
364 		int j;
365 		struct section *sec = &secs[i];
366 
367 		if (sec->shdr.sh_type != SHT_REL_TYPE)
368 			continue;
369 
370 		sec_symtab  = sec->link;
371 		sec_applies = &secs[sec->shdr.sh_info];
372 		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC))
373 			continue;
374 
375 		sh_symtab = sec_symtab->symtab;
376 		sym_strtab = sec_symtab->link->strtab;
377 		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
378 			Elf_Rel *rel = &sec->reltab[j];
379 			Elf_Sym *sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
380 			const char *symname = sym_name(sym_strtab, sym);
381 
382 			process(sec, rel, sym, symname);
383 		}
384 	}
385 }
386 
do_reloc(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, const char *symname)387 static int do_reloc(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
388 		      const char *symname)
389 {
390 	unsigned r_type = ELF_R_TYPE(rel->r_info);
391 	unsigned bind = ELF_ST_BIND(sym->st_info);
392 
393 	if ((bind == STB_WEAK) && (sym->st_value == 0)) {
394 		/* Don't relocate weak symbols without a target */
395 		return 0;
396 	}
397 
398 	if (regex_skip_reloc(symname))
399 		return 0;
400 
401 	switch (r_type) {
402 	case R_LARCH_NONE:
403 	case R_LARCH_MARK_PCREL:
404 	case R_LARCH_SOP_PUSH_PCREL:
405 	case R_LARCH_SOP_PUSH_ABSOLUTE:
406 	case R_LARCH_SOP_PUSH_DUP:
407 	case R_LARCH_SOP_PUSH_PLT_PCREL:
408 	case R_LARCH_SOP_SUB:
409 	case R_LARCH_SOP_SL:
410 	case R_LARCH_SOP_SR:
411 	case R_LARCH_SOP_ADD:
412 	case R_LARCH_SOP_AND:
413 	case R_LARCH_SOP_IF_ELSE:
414 	case R_LARCH_SOP_POP_32_S_10_5:
415 	case R_LARCH_SOP_POP_32_U_10_12:
416 	case R_LARCH_SOP_POP_32_S_10_12:
417 	case R_LARCH_SOP_POP_32_S_10_16:
418 	case R_LARCH_SOP_POP_32_S_10_16_S2:
419 	case R_LARCH_SOP_POP_32_S_5_20:
420 	case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
421 	case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
422 	case R_LARCH_SOP_POP_32_U:
423 	case R_LARCH_ADD32:
424 	case R_LARCH_ADD64:
425 	case R_LARCH_SUB32:
426 	case R_LARCH_SUB64:
427 		break;
428 
429 	case R_LARCH_32:
430 	case R_LARCH_64:
431 	case R_LARCH_MARK_LA:
432 		add_reloc(&relocs, rel->r_offset, r_type);
433 		break;
434 
435 	default:
436 		die("Unsupported relocation type: %s (%d)\n", rel_type(r_type), r_type);
437 		break;
438 	}
439 
440 	return 0;
441 }
442 
write_reloc_as_bin(uint32_t v, FILE *f)443 static int write_reloc_as_bin(uint32_t v, FILE *f)
444 {
445 	return fwrite(&v, 4, 1, f);
446 }
447 
write_reloc_as_text(uint32_t v, FILE *f)448 static int write_reloc_as_text(uint32_t v, FILE *f)
449 {
450 	int res;
451 
452 	res = fprintf(f, "\t.long 0x%08"PRIx32"\n", v);
453 	if (res < 0)
454 		return res;
455 	else
456 		return sizeof(uint32_t);
457 }
458 
emit_relocs(int as_text, int as_bin, FILE *outf)459 static void emit_relocs(int as_text, int as_bin, FILE *outf)
460 {
461 	int i;
462 	int (*write_reloc)(uint32_t, FILE *) = write_reloc_as_bin;
463 	int size = 0;
464 	int size_reserved;
465 	struct section *sec_reloc;
466 
467 	sec_reloc = sec_lookup(".data.reloc");
468 	if (!sec_reloc)
469 		die("Could not find relocation section\n");
470 
471 	size_reserved = sec_reloc->shdr.sh_size;
472 
473 	/* Collect up the relocations */
474 	walk_relocs(do_reloc);
475 
476 	/* Print the relocations */
477 	if (as_text) {
478 		/* Print the relocations in a form suitable that
479 		 * gas will like.
480 		 */
481 		printf(".section \".data.reloc\",\"a\"\n");
482 		printf(".balign 4\n");
483 		/* Output text to stdout */
484 		write_reloc = write_reloc_as_text;
485 		outf = stdout;
486 	} else if (as_bin) {
487 		/* Output raw binary to stdout */
488 		outf = stdout;
489 	} else {
490 		/* Seek to offset of the relocation section.
491 		 * Each relocation is then written into the
492 		 * vmlinux kernel image.
493 		 */
494 		if (fseek(outf, sec_reloc->shdr.sh_offset, SEEK_SET) < 0) {
495 			die("Seek to %d failed: %s\n",
496 				sec_reloc->shdr.sh_offset, strerror(errno));
497 		}
498 	}
499 
500 	for (i = 0; i < relocs.count; i++)
501 		size += write_reloc(relocs.offset[i], outf);
502 
503 	/* Print a stop, but only if we've actually written some relocs */
504 	if (size)
505 		size += write_reloc(0, outf);
506 
507 	if (size > size_reserved)
508 		/* Die, but suggest a value for CONFIG_RELOCATION_TABLE_SIZE
509 		 * which will fix this problem and allow a bit of headroom
510 		 * if more kernel features are enabled
511 		 */
512 		die("Relocations overflow available space!\n" \
513 		    "Please adjust CONFIG_RELOCATION_TABLE_SIZE " \
514 		    "to at least 0x%08x\n", (size + 0x1000) & ~0xFFF);
515 }
516 
517 /*
518  * As an aid to debugging problems with different linkers
519  * print summary information about the relocs.
520  * Since different linkers tend to emit the sections in
521  * different orders we use the section names in the output.
522  */
do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, const char *symname)523 static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
524 				const char *symname)
525 {
526 	printf("%-16s  0x%08x  %-35s  %-40s  %-16s\n",
527 		sec_name(sec->shdr.sh_info),
528 		(unsigned int)rel->r_offset,
529 		rel_type(ELF_R_TYPE(rel->r_info)),
530 		symname,
531 		sec_name(sym->st_shndx));
532 	return 0;
533 }
534 
print_reloc_info(void)535 static void print_reloc_info(void)
536 {
537 	printf("%-16s  %-10s  %-35s  %-40s  %-16s\n",
538 		"reloc section",
539 		"offset",
540 		"reloc type",
541 		"symbol",
542 		"symbol section");
543 	walk_relocs(do_reloc_info);
544 }
545 
546 #if ELF_BITS == 64
547 # define process process_64
548 #else
549 # define process process_32
550 #endif
551 
process(FILE *fp, int as_text, int as_bin, int show_reloc_info, int keep_relocs)552 void process(FILE *fp, int as_text, int as_bin,
553 	     int show_reloc_info, int keep_relocs)
554 {
555 	regex_init();
556 	read_ehdr(fp);
557 	read_shdrs(fp);
558 	read_strtabs(fp);
559 	read_symtabs(fp);
560 	read_relocs(fp);
561 	if (show_reloc_info) {
562 		print_reloc_info();
563 		return;
564 	}
565 	emit_relocs(as_text, as_bin, fp);
566 	if (!keep_relocs)
567 		remove_relocs(fp);
568 }
569