hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/x86/tools/relocs.c
....@@ -11,7 +11,9 @@
1111 #define Elf_Shdr ElfW(Shdr)
1212 #define Elf_Sym ElfW(Sym)
1313
14
-static Elf_Ehdr ehdr;
14
+static Elf_Ehdr ehdr;
15
+static unsigned long shnum;
16
+static unsigned int shstrndx;
1517
1618 struct relocs {
1719 uint32_t *offset;
....@@ -131,7 +133,7 @@
131133 REG_EXTENDED|REG_NOSUB);
132134
133135 if (err) {
134
- regerror(err, &sym_regex_c[i], errbuf, sizeof errbuf);
136
+ regerror(err, &sym_regex_c[i], errbuf, sizeof(errbuf));
135137 die("%s", errbuf);
136138 }
137139 }
....@@ -197,6 +199,7 @@
197199 #if ELF_BITS == 64
198200 REL_TYPE(R_X86_64_NONE),
199201 REL_TYPE(R_X86_64_64),
202
+ REL_TYPE(R_X86_64_PC64),
200203 REL_TYPE(R_X86_64_PC32),
201204 REL_TYPE(R_X86_64_GOT32),
202205 REL_TYPE(R_X86_64_PLT32),
....@@ -241,9 +244,9 @@
241244 {
242245 const char *sec_strtab;
243246 const char *name;
244
- sec_strtab = secs[ehdr.e_shstrndx].strtab;
247
+ sec_strtab = secs[shstrndx].strtab;
245248 name = "<noname>";
246
- if (shndx < ehdr.e_shnum) {
249
+ if (shndx < shnum) {
247250 name = sec_strtab + secs[shndx].shdr.sh_name;
248251 }
249252 else if (shndx == SHN_ABS) {
....@@ -271,7 +274,7 @@
271274 static Elf_Sym *sym_lookup(const char *symname)
272275 {
273276 int i;
274
- for (i = 0; i < ehdr.e_shnum; i++) {
277
+ for (i = 0; i < shnum; i++) {
275278 struct section *sec = &secs[i];
276279 long nsyms;
277280 char *strtab;
....@@ -366,27 +369,41 @@
366369 ehdr.e_shnum = elf_half_to_cpu(ehdr.e_shnum);
367370 ehdr.e_shstrndx = elf_half_to_cpu(ehdr.e_shstrndx);
368371
369
- if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) {
372
+ shnum = ehdr.e_shnum;
373
+ shstrndx = ehdr.e_shstrndx;
374
+
375
+ if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN))
370376 die("Unsupported ELF header type\n");
371
- }
372
- if (ehdr.e_machine != ELF_MACHINE) {
377
+ if (ehdr.e_machine != ELF_MACHINE)
373378 die("Not for %s\n", ELF_MACHINE_NAME);
374
- }
375
- if (ehdr.e_version != EV_CURRENT) {
379
+ if (ehdr.e_version != EV_CURRENT)
376380 die("Unknown ELF version\n");
377
- }
378
- if (ehdr.e_ehsize != sizeof(Elf_Ehdr)) {
381
+ if (ehdr.e_ehsize != sizeof(Elf_Ehdr))
379382 die("Bad Elf header size\n");
380
- }
381
- if (ehdr.e_phentsize != sizeof(Elf_Phdr)) {
383
+ if (ehdr.e_phentsize != sizeof(Elf_Phdr))
382384 die("Bad program header entry\n");
383
- }
384
- if (ehdr.e_shentsize != sizeof(Elf_Shdr)) {
385
+ if (ehdr.e_shentsize != sizeof(Elf_Shdr))
385386 die("Bad section header entry\n");
387
+
388
+
389
+ if (shnum == SHN_UNDEF || shstrndx == SHN_XINDEX) {
390
+ Elf_Shdr shdr;
391
+
392
+ if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0)
393
+ die("Seek to %d failed: %s\n", ehdr.e_shoff, strerror(errno));
394
+
395
+ if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
396
+ die("Cannot read initial ELF section header: %s\n", strerror(errno));
397
+
398
+ if (shnum == SHN_UNDEF)
399
+ shnum = elf_xword_to_cpu(shdr.sh_size);
400
+
401
+ if (shstrndx == SHN_XINDEX)
402
+ shstrndx = elf_word_to_cpu(shdr.sh_link);
386403 }
387
- if (ehdr.e_shstrndx >= ehdr.e_shnum) {
404
+
405
+ if (shstrndx >= shnum)
388406 die("String table index out of bounds\n");
389
- }
390407 }
391408
392409 static void read_shdrs(FILE *fp)
....@@ -394,20 +411,20 @@
394411 int i;
395412 Elf_Shdr shdr;
396413
397
- secs = calloc(ehdr.e_shnum, sizeof(struct section));
414
+ secs = calloc(shnum, sizeof(struct section));
398415 if (!secs) {
399416 die("Unable to allocate %d section headers\n",
400
- ehdr.e_shnum);
417
+ shnum);
401418 }
402419 if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) {
403420 die("Seek to %d failed: %s\n",
404421 ehdr.e_shoff, strerror(errno));
405422 }
406
- for (i = 0; i < ehdr.e_shnum; i++) {
423
+ for (i = 0; i < shnum; i++) {
407424 struct section *sec = &secs[i];
408
- if (fread(&shdr, sizeof shdr, 1, fp) != 1)
425
+ if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
409426 die("Cannot read ELF section headers %d/%d: %s\n",
410
- i, ehdr.e_shnum, strerror(errno));
427
+ i, shnum, strerror(errno));
411428 sec->shdr.sh_name = elf_word_to_cpu(shdr.sh_name);
412429 sec->shdr.sh_type = elf_word_to_cpu(shdr.sh_type);
413430 sec->shdr.sh_flags = elf_xword_to_cpu(shdr.sh_flags);
....@@ -418,7 +435,7 @@
418435 sec->shdr.sh_info = elf_word_to_cpu(shdr.sh_info);
419436 sec->shdr.sh_addralign = elf_xword_to_cpu(shdr.sh_addralign);
420437 sec->shdr.sh_entsize = elf_xword_to_cpu(shdr.sh_entsize);
421
- if (sec->shdr.sh_link < ehdr.e_shnum)
438
+ if (sec->shdr.sh_link < shnum)
422439 sec->link = &secs[sec->shdr.sh_link];
423440 }
424441
....@@ -427,7 +444,7 @@
427444 static void read_strtabs(FILE *fp)
428445 {
429446 int i;
430
- for (i = 0; i < ehdr.e_shnum; i++) {
447
+ for (i = 0; i < shnum; i++) {
431448 struct section *sec = &secs[i];
432449 if (sec->shdr.sh_type != SHT_STRTAB) {
433450 continue;
....@@ -452,7 +469,7 @@
452469 static void read_symtabs(FILE *fp)
453470 {
454471 int i,j;
455
- for (i = 0; i < ehdr.e_shnum; i++) {
472
+ for (i = 0; i < shnum; i++) {
456473 struct section *sec = &secs[i];
457474 if (sec->shdr.sh_type != SHT_SYMTAB) {
458475 continue;
....@@ -485,7 +502,7 @@
485502 static void read_relocs(FILE *fp)
486503 {
487504 int i,j;
488
- for (i = 0; i < ehdr.e_shnum; i++) {
505
+ for (i = 0; i < shnum; i++) {
489506 struct section *sec = &secs[i];
490507 if (sec->shdr.sh_type != SHT_REL_TYPE) {
491508 continue;
....@@ -528,7 +545,7 @@
528545
529546 printf("Absolute symbols\n");
530547 printf(" Num: Value Size Type Bind Visibility Name\n");
531
- for (i = 0; i < ehdr.e_shnum; i++) {
548
+ for (i = 0; i < shnum; i++) {
532549 struct section *sec = &secs[i];
533550 char *sym_strtab;
534551 int j;
....@@ -566,7 +583,7 @@
566583 else
567584 format = "%08"PRIx32" %08"PRIx32" %10s %08"PRIx32" %s\n";
568585
569
- for (i = 0; i < ehdr.e_shnum; i++) {
586
+ for (i = 0; i < shnum; i++) {
570587 struct section *sec = &secs[i];
571588 struct section *sec_applies, *sec_symtab;
572589 char *sym_strtab;
....@@ -650,7 +667,7 @@
650667 {
651668 int i;
652669 /* Walk through the relocations */
653
- for (i = 0; i < ehdr.e_shnum; i++) {
670
+ for (i = 0; i < shnum; i++) {
654671 char *sym_strtab;
655672 Elf_Sym *sh_symtab;
656673 struct section *sec_applies, *sec_symtab;
....@@ -706,7 +723,7 @@
706723 static void percpu_init(void)
707724 {
708725 int i;
709
- for (i = 0; i < ehdr.e_shnum; i++) {
726
+ for (i = 0; i < shnum; i++) {
710727 ElfW(Sym) *sym;
711728 if (strcmp(sec_name(i), ".data..percpu"))
712729 continue;
....@@ -738,7 +755,7 @@
738755 * __per_cpu_load
739756 *
740757 * The "gold" linker incorrectly associates:
741
- * init_per_cpu__irq_stack_union
758
+ * init_per_cpu__fixed_percpu_data
742759 * init_per_cpu__gdt_page
743760 */
744761 static int is_percpu_sym(ElfW(Sym) *sym, const char *symname)
....@@ -783,6 +800,15 @@
783800 add_reloc(&relocs32neg, offset);
784801 break;
785802
803
+ case R_X86_64_PC64:
804
+ /*
805
+ * Only used by jump labels
806
+ */
807
+ if (is_percpu_sym(sym, symname))
808
+ die("Invalid R_X86_64_PC64 relocation against per-CPU symbol %s\n",
809
+ symname);
810
+ break;
811
+
786812 case R_X86_64_8:
787813 if (!shn_abs || !is_reloc(S_ABS, symname))
788814 die("Non-whitelisted %s relocation: %s\n",