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