diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86/Makefile | 3 | ||||
| -rw-r--r-- | arch/x86/boot/compressed/Makefile | 9 | ||||
| -rw-r--r-- | arch/x86/tools/.gitignore | 1 | ||||
| -rw-r--r-- | arch/x86/tools/Makefile | 4 | ||||
| -rw-r--r-- | arch/x86/tools/relocs.c (renamed from arch/x86/boot/compressed/relocs.c) | 242 |
5 files changed, 197 insertions, 62 deletions
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 41a7237606a3..94e91e401da9 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
| @@ -134,6 +134,9 @@ KBUILD_CFLAGS += $(call cc-option,-mno-avx,) | |||
| 134 | KBUILD_CFLAGS += $(mflags-y) | 134 | KBUILD_CFLAGS += $(mflags-y) |
| 135 | KBUILD_AFLAGS += $(mflags-y) | 135 | KBUILD_AFLAGS += $(mflags-y) |
| 136 | 136 | ||
| 137 | archscripts: | ||
| 138 | $(Q)$(MAKE) $(build)=arch/x86/tools relocs | ||
| 139 | |||
| 137 | ### | 140 | ### |
| 138 | # Syscall table generation | 141 | # Syscall table generation |
| 139 | 142 | ||
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index fd55a2ff3ad8..e398bb5d63bb 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile | |||
| @@ -40,13 +40,12 @@ OBJCOPYFLAGS_vmlinux.bin := -R .comment -S | |||
| 40 | $(obj)/vmlinux.bin: vmlinux FORCE | 40 | $(obj)/vmlinux.bin: vmlinux FORCE |
| 41 | $(call if_changed,objcopy) | 41 | $(call if_changed,objcopy) |
| 42 | 42 | ||
| 43 | targets += vmlinux.bin.all vmlinux.relocs | ||
| 43 | 44 | ||
| 44 | targets += vmlinux.bin.all vmlinux.relocs relocs | 45 | CMD_RELOCS = arch/x86/tools/relocs |
| 45 | hostprogs-$(CONFIG_X86_NEED_RELOCS) += relocs | ||
| 46 | |||
| 47 | quiet_cmd_relocs = RELOCS $@ | 46 | quiet_cmd_relocs = RELOCS $@ |
| 48 | cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $< | 47 | cmd_relocs = $(CMD_RELOCS) $< > $@;$(CMD_RELOCS) --abs-relocs $< |
| 49 | $(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE | 48 | $(obj)/vmlinux.relocs: vmlinux FORCE |
| 50 | $(call if_changed,relocs) | 49 | $(call if_changed,relocs) |
| 51 | 50 | ||
| 52 | vmlinux.bin.all-y := $(obj)/vmlinux.bin | 51 | vmlinux.bin.all-y := $(obj)/vmlinux.bin |
diff --git a/arch/x86/tools/.gitignore b/arch/x86/tools/.gitignore new file mode 100644 index 000000000000..be0ed065249b --- /dev/null +++ b/arch/x86/tools/.gitignore | |||
| @@ -0,0 +1 @@ | |||
| relocs | |||
diff --git a/arch/x86/tools/Makefile b/arch/x86/tools/Makefile index d511aa97533a..733057b435b0 100644 --- a/arch/x86/tools/Makefile +++ b/arch/x86/tools/Makefile | |||
| @@ -36,3 +36,7 @@ HOSTCFLAGS_insn_sanity.o := -Wall -I$(objtree)/arch/x86/lib/ -I$(srctree)/arch/x | |||
| 36 | $(obj)/test_get_len.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c | 36 | $(obj)/test_get_len.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c |
| 37 | 37 | ||
| 38 | $(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c | 38 | $(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/inat.c $(srctree)/arch/x86/include/asm/inat_types.h $(srctree)/arch/x86/include/asm/inat.h $(srctree)/arch/x86/include/asm/insn.h $(objtree)/arch/x86/lib/inat-tables.c |
| 39 | |||
| 40 | HOST_EXTRACFLAGS += -I$(srctree)/tools/include | ||
| 41 | hostprogs-y += relocs | ||
| 42 | relocs: $(obj)/relocs | ||
diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/tools/relocs.c index fb7117a4ade1..b43cfcd9bf40 100644 --- a/arch/x86/boot/compressed/relocs.c +++ b/arch/x86/tools/relocs.c | |||
| @@ -18,6 +18,8 @@ static void die(char *fmt, ...); | |||
| 18 | static Elf32_Ehdr ehdr; | 18 | static Elf32_Ehdr ehdr; |
| 19 | static unsigned long reloc_count, reloc_idx; | 19 | static unsigned long reloc_count, reloc_idx; |
| 20 | static unsigned long *relocs; | 20 | static unsigned long *relocs; |
| 21 | static unsigned long reloc16_count, reloc16_idx; | ||
| 22 | static unsigned long *relocs16; | ||
| 21 | 23 | ||
| 22 | struct section { | 24 | struct section { |
| 23 | Elf32_Shdr shdr; | 25 | Elf32_Shdr shdr; |
| @@ -28,52 +30,86 @@ struct section { | |||
| 28 | }; | 30 | }; |
| 29 | static struct section *secs; | 31 | static struct section *secs; |
| 30 | 32 | ||
| 33 | enum symtype { | ||
| 34 | S_ABS, | ||
| 35 | S_REL, | ||
| 36 | S_SEG, | ||
| 37 | S_LIN, | ||
| 38 | S_NSYMTYPES | ||
| 39 | }; | ||
| 40 | |||
| 41 | static const char * const sym_regex_kernel[S_NSYMTYPES] = { | ||
| 31 | /* | 42 | /* |
| 32 | * Following symbols have been audited. There values are constant and do | 43 | * Following symbols have been audited. There values are constant and do |
| 33 | * not change if bzImage is loaded at a different physical address than | 44 | * not change if bzImage is loaded at a different physical address than |
| 34 | * the address for which it has been compiled. Don't warn user about | 45 | * the address for which it has been compiled. Don't warn user about |
| 35 | * absolute relocations present w.r.t these symbols. | 46 | * absolute relocations present w.r.t these symbols. |
| 36 | */ | 47 | */ |
| 37 | static const char abs_sym_regex[] = | 48 | [S_ABS] = |
| 38 | "^(xen_irq_disable_direct_reloc$|" | 49 | "^(xen_irq_disable_direct_reloc$|" |
| 39 | "xen_save_fl_direct_reloc$|" | 50 | "xen_save_fl_direct_reloc$|" |
| 40 | "VDSO|" | 51 | "VDSO|" |
| 41 | "__crc_)"; | 52 | "__crc_)", |
| 42 | static regex_t abs_sym_regex_c; | ||
| 43 | static int is_abs_reloc(const char *sym_name) | ||
| 44 | { | ||
| 45 | return !regexec(&abs_sym_regex_c, sym_name, 0, NULL, 0); | ||
| 46 | } | ||
| 47 | 53 | ||
| 48 | /* | 54 | /* |
| 49 | * These symbols are known to be relative, even if the linker marks them | 55 | * These symbols are known to be relative, even if the linker marks them |
| 50 | * as absolute (typically defined outside any section in the linker script.) | 56 | * as absolute (typically defined outside any section in the linker script.) |
| 51 | */ | 57 | */ |
| 52 | static const char rel_sym_regex[] = | 58 | [S_REL] = |
| 53 | "^_end$"; | 59 | "^(__init_(begin|end)|" |
| 54 | static regex_t rel_sym_regex_c; | 60 | "__x86_cpu_dev_(start|end)|" |
| 55 | static int is_rel_reloc(const char *sym_name) | 61 | "(__parainstructions|__alt_instructions)(|_end)|" |
| 62 | "(__iommu_table|__apicdrivers|__smp_locks)(|_end)|" | ||
| 63 | "_end)$" | ||
| 64 | }; | ||
| 65 | |||
| 66 | |||
| 67 | static const char * const sym_regex_realmode[S_NSYMTYPES] = { | ||
| 68 | /* | ||
| 69 | * These are 16-bit segment symbols when compiling 16-bit code. | ||
| 70 | */ | ||
| 71 | [S_SEG] = | ||
| 72 | "^real_mode_seg$", | ||
| 73 | |||
| 74 | /* | ||
| 75 | * These are offsets belonging to segments, as opposed to linear addresses, | ||
| 76 | * when compiling 16-bit code. | ||
| 77 | */ | ||
| 78 | [S_LIN] = | ||
| 79 | "^pa_", | ||
| 80 | }; | ||
| 81 | |||
| 82 | static const char * const *sym_regex; | ||
| 83 | |||
| 84 | static regex_t sym_regex_c[S_NSYMTYPES]; | ||
| 85 | static int is_reloc(enum symtype type, const char *sym_name) | ||
| 56 | { | 86 | { |
| 57 | return !regexec(&rel_sym_regex_c, sym_name, 0, NULL, 0); | 87 | return sym_regex[type] && |
| 88 | !regexec(&sym_regex_c[type], sym_name, 0, NULL, 0); | ||
| 58 | } | 89 | } |
| 59 | 90 | ||
| 60 | static void regex_init(void) | 91 | static void regex_init(int use_real_mode) |
| 61 | { | 92 | { |
| 62 | char errbuf[128]; | 93 | char errbuf[128]; |
| 63 | int err; | 94 | int err; |
| 64 | 95 | int i; | |
| 65 | err = regcomp(&abs_sym_regex_c, abs_sym_regex, | 96 | |
| 66 | REG_EXTENDED|REG_NOSUB); | 97 | if (use_real_mode) |
| 67 | if (err) { | 98 | sym_regex = sym_regex_realmode; |
| 68 | regerror(err, &abs_sym_regex_c, errbuf, sizeof errbuf); | 99 | else |
| 69 | die("%s", errbuf); | 100 | sym_regex = sym_regex_kernel; |
| 70 | } | ||
| 71 | 101 | ||
| 72 | err = regcomp(&rel_sym_regex_c, rel_sym_regex, | 102 | for (i = 0; i < S_NSYMTYPES; i++) { |
| 73 | REG_EXTENDED|REG_NOSUB); | 103 | if (!sym_regex[i]) |
| 74 | if (err) { | 104 | continue; |
| 75 | regerror(err, &rel_sym_regex_c, errbuf, sizeof errbuf); | 105 | |
| 76 | die("%s", errbuf); | 106 | err = regcomp(&sym_regex_c[i], sym_regex[i], |
| 107 | REG_EXTENDED|REG_NOSUB); | ||
| 108 | |||
| 109 | if (err) { | ||
| 110 | regerror(err, &sym_regex_c[i], errbuf, sizeof errbuf); | ||
| 111 | die("%s", errbuf); | ||
| 112 | } | ||
| 77 | } | 113 | } |
| 78 | } | 114 | } |
| 79 | 115 | ||
| @@ -154,6 +190,10 @@ static const char *rel_type(unsigned type) | |||
| 154 | REL_TYPE(R_386_RELATIVE), | 190 | REL_TYPE(R_386_RELATIVE), |
| 155 | REL_TYPE(R_386_GOTOFF), | 191 | REL_TYPE(R_386_GOTOFF), |
| 156 | REL_TYPE(R_386_GOTPC), | 192 | REL_TYPE(R_386_GOTPC), |
| 193 | REL_TYPE(R_386_8), | ||
| 194 | REL_TYPE(R_386_PC8), | ||
| 195 | REL_TYPE(R_386_16), | ||
| 196 | REL_TYPE(R_386_PC16), | ||
| 157 | #undef REL_TYPE | 197 | #undef REL_TYPE |
| 158 | }; | 198 | }; |
| 159 | const char *name = "unknown type rel type name"; | 199 | const char *name = "unknown type rel type name"; |
| @@ -189,7 +229,7 @@ static const char *sym_name(const char *sym_strtab, Elf32_Sym *sym) | |||
| 189 | name = sym_strtab + sym->st_name; | 229 | name = sym_strtab + sym->st_name; |
| 190 | } | 230 | } |
| 191 | else { | 231 | else { |
| 192 | name = sec_name(secs[sym->st_shndx].shdr.sh_name); | 232 | name = sec_name(sym->st_shndx); |
| 193 | } | 233 | } |
| 194 | return name; | 234 | return name; |
| 195 | } | 235 | } |
| @@ -472,7 +512,7 @@ static void print_absolute_relocs(void) | |||
| 472 | * Before warning check if this absolute symbol | 512 | * Before warning check if this absolute symbol |
| 473 | * relocation is harmless. | 513 | * relocation is harmless. |
| 474 | */ | 514 | */ |
| 475 | if (is_abs_reloc(name) || is_rel_reloc(name)) | 515 | if (is_reloc(S_ABS, name) || is_reloc(S_REL, name)) |
| 476 | continue; | 516 | continue; |
| 477 | 517 | ||
| 478 | if (!printed) { | 518 | if (!printed) { |
| @@ -496,7 +536,8 @@ static void print_absolute_relocs(void) | |||
| 496 | printf("\n"); | 536 | printf("\n"); |
| 497 | } | 537 | } |
| 498 | 538 | ||
| 499 | static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) | 539 | static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym), |
| 540 | int use_real_mode) | ||
| 500 | { | 541 | { |
| 501 | int i; | 542 | int i; |
| 502 | /* Walk through the relocations */ | 543 | /* Walk through the relocations */ |
| @@ -521,30 +562,67 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) | |||
| 521 | Elf32_Rel *rel; | 562 | Elf32_Rel *rel; |
| 522 | Elf32_Sym *sym; | 563 | Elf32_Sym *sym; |
| 523 | unsigned r_type; | 564 | unsigned r_type; |
| 565 | const char *symname; | ||
| 566 | int shn_abs; | ||
| 567 | |||
| 524 | rel = &sec->reltab[j]; | 568 | rel = &sec->reltab[j]; |
| 525 | sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; | 569 | sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; |
| 526 | r_type = ELF32_R_TYPE(rel->r_info); | 570 | r_type = ELF32_R_TYPE(rel->r_info); |
| 527 | /* Don't visit relocations to absolute symbols */ | 571 | |
| 528 | if (sym->st_shndx == SHN_ABS && | 572 | shn_abs = sym->st_shndx == SHN_ABS; |
| 529 | !is_rel_reloc(sym_name(sym_strtab, sym))) { | 573 | |
| 530 | continue; | ||
| 531 | } | ||
| 532 | switch (r_type) { | 574 | switch (r_type) { |
| 533 | case R_386_NONE: | 575 | case R_386_NONE: |
| 534 | case R_386_PC32: | 576 | case R_386_PC32: |
| 577 | case R_386_PC16: | ||
| 578 | case R_386_PC8: | ||
| 535 | /* | 579 | /* |
| 536 | * NONE can be ignored and and PC relative | 580 | * NONE can be ignored and and PC relative |
| 537 | * relocations don't need to be adjusted. | 581 | * relocations don't need to be adjusted. |
| 538 | */ | 582 | */ |
| 539 | break; | 583 | break; |
| 584 | |||
| 585 | case R_386_16: | ||
| 586 | symname = sym_name(sym_strtab, sym); | ||
| 587 | if (!use_real_mode) | ||
| 588 | goto bad; | ||
| 589 | if (shn_abs) { | ||
| 590 | if (is_reloc(S_ABS, symname)) | ||
| 591 | break; | ||
| 592 | else if (!is_reloc(S_SEG, symname)) | ||
| 593 | goto bad; | ||
| 594 | } else { | ||
| 595 | if (is_reloc(S_LIN, symname)) | ||
| 596 | goto bad; | ||
| 597 | else | ||
| 598 | break; | ||
| 599 | } | ||
| 600 | visit(rel, sym); | ||
| 601 | break; | ||
| 602 | |||
| 540 | case R_386_32: | 603 | case R_386_32: |
| 541 | /* Visit relocations that need to be adjusted */ | 604 | symname = sym_name(sym_strtab, sym); |
| 605 | if (shn_abs) { | ||
| 606 | if (is_reloc(S_ABS, symname)) | ||
| 607 | break; | ||
| 608 | else if (!is_reloc(S_REL, symname)) | ||
| 609 | goto bad; | ||
| 610 | } else { | ||
| 611 | if (use_real_mode && | ||
| 612 | !is_reloc(S_LIN, symname)) | ||
| 613 | break; | ||
| 614 | } | ||
| 542 | visit(rel, sym); | 615 | visit(rel, sym); |
| 543 | break; | 616 | break; |
| 544 | default: | 617 | default: |
| 545 | die("Unsupported relocation type: %s (%d)\n", | 618 | die("Unsupported relocation type: %s (%d)\n", |
| 546 | rel_type(r_type), r_type); | 619 | rel_type(r_type), r_type); |
| 547 | break; | 620 | break; |
| 621 | bad: | ||
| 622 | symname = sym_name(sym_strtab, sym); | ||
| 623 | die("Invalid %s %s relocation: %s\n", | ||
| 624 | shn_abs ? "absolute" : "relative", | ||
| 625 | rel_type(r_type), symname); | ||
| 548 | } | 626 | } |
| 549 | } | 627 | } |
| 550 | } | 628 | } |
| @@ -552,13 +630,19 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) | |||
| 552 | 630 | ||
| 553 | static void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym) | 631 | static void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym) |
| 554 | { | 632 | { |
| 555 | reloc_count += 1; | 633 | if (ELF32_R_TYPE(rel->r_info) == R_386_16) |
| 634 | reloc16_count++; | ||
| 635 | else | ||
| 636 | reloc_count++; | ||
| 556 | } | 637 | } |
| 557 | 638 | ||
| 558 | static void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym) | 639 | static void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym) |
| 559 | { | 640 | { |
| 560 | /* Remember the address that needs to be adjusted. */ | 641 | /* Remember the address that needs to be adjusted. */ |
| 561 | relocs[reloc_idx++] = rel->r_offset; | 642 | if (ELF32_R_TYPE(rel->r_info) == R_386_16) |
| 643 | relocs16[reloc16_idx++] = rel->r_offset; | ||
| 644 | else | ||
| 645 | relocs[reloc_idx++] = rel->r_offset; | ||
| 562 | } | 646 | } |
| 563 | 647 | ||
| 564 | static int cmp_relocs(const void *va, const void *vb) | 648 | static int cmp_relocs(const void *va, const void *vb) |
| @@ -568,23 +652,41 @@ static int cmp_relocs(const void *va, const void *vb) | |||
| 568 | return (*a == *b)? 0 : (*a > *b)? 1 : -1; | 652 | return (*a == *b)? 0 : (*a > *b)? 1 : -1; |
| 569 | } | 653 | } |
| 570 | 654 | ||
| 571 | static void emit_relocs(int as_text) | 655 | static int write32(unsigned int v, FILE *f) |
| 656 | { | ||
| 657 | unsigned char buf[4]; | ||
| 658 | |||
| 659 | put_unaligned_le32(v, buf); | ||
| 660 | return fwrite(buf, 1, 4, f) == 4 ? 0 : -1; | ||
| 661 | } | ||
| 662 | |||
| 663 | static void emit_relocs(int as_text, int use_real_mode) | ||
| 572 | { | 664 | { |
| 573 | int i; | 665 | int i; |
| 574 | /* Count how many relocations I have and allocate space for them. */ | 666 | /* Count how many relocations I have and allocate space for them. */ |
| 575 | reloc_count = 0; | 667 | reloc_count = 0; |
| 576 | walk_relocs(count_reloc); | 668 | walk_relocs(count_reloc, use_real_mode); |
| 577 | relocs = malloc(reloc_count * sizeof(relocs[0])); | 669 | relocs = malloc(reloc_count * sizeof(relocs[0])); |
| 578 | if (!relocs) { | 670 | if (!relocs) { |
| 579 | die("malloc of %d entries for relocs failed\n", | 671 | die("malloc of %d entries for relocs failed\n", |
| 580 | reloc_count); | 672 | reloc_count); |
| 581 | } | 673 | } |
| 674 | |||
| 675 | relocs16 = malloc(reloc16_count * sizeof(relocs[0])); | ||
| 676 | if (!relocs16) { | ||
| 677 | die("malloc of %d entries for relocs16 failed\n", | ||
| 678 | reloc16_count); | ||
| 679 | } | ||
| 582 | /* Collect up the relocations */ | 680 | /* Collect up the relocations */ |
| 583 | reloc_idx = 0; | 681 | reloc_idx = 0; |
| 584 | walk_relocs(collect_reloc); | 682 | walk_relocs(collect_reloc, use_real_mode); |
| 683 | |||
| 684 | if (reloc16_count && !use_real_mode) | ||
| 685 | die("Segment relocations found but --realmode not specified\n"); | ||
| 585 | 686 | ||
| 586 | /* Order the relocations for more efficient processing */ | 687 | /* Order the relocations for more efficient processing */ |
| 587 | qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs); | 688 | qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs); |
| 689 | qsort(relocs16, reloc16_count, sizeof(relocs16[0]), cmp_relocs); | ||
| 588 | 690 | ||
| 589 | /* Print the relocations */ | 691 | /* Print the relocations */ |
| 590 | if (as_text) { | 692 | if (as_text) { |
| @@ -593,58 +695,83 @@ static void emit_relocs(int as_text) | |||
| 593 | */ | 695 | */ |
| 594 | printf(".section \".data.reloc\",\"a\"\n"); | 696 | printf(".section \".data.reloc\",\"a\"\n"); |
| 595 | printf(".balign 4\n"); | 697 | printf(".balign 4\n"); |
| 596 | for (i = 0; i < reloc_count; i++) { | 698 | if (use_real_mode) { |
| 597 | printf("\t .long 0x%08lx\n", relocs[i]); | 699 | printf("\t.long %lu\n", reloc16_count); |
| 700 | for (i = 0; i < reloc16_count; i++) | ||
| 701 | printf("\t.long 0x%08lx\n", relocs16[i]); | ||
| 702 | printf("\t.long %lu\n", reloc_count); | ||
| 703 | for (i = 0; i < reloc_count; i++) { | ||
| 704 | printf("\t.long 0x%08lx\n", relocs[i]); | ||
| 705 | } | ||
| 706 | } else { | ||
| 707 | /* Print a stop */ | ||
| 708 | printf("\t.long 0x%08lx\n", (unsigned long)0); | ||
| 709 | for (i = 0; i < reloc_count; i++) { | ||
| 710 | printf("\t.long 0x%08lx\n", relocs[i]); | ||
| 711 | } | ||
| 598 | } | 712 | } |
| 713 | |||
| 599 | printf("\n"); | 714 | printf("\n"); |
| 600 | } | 715 | } |
| 601 | else { | 716 | else { |
| 602 | unsigned char buf[4]; | 717 | if (use_real_mode) { |
| 603 | /* Print a stop */ | 718 | write32(reloc16_count, stdout); |
| 604 | fwrite("\0\0\0\0", 4, 1, stdout); | 719 | for (i = 0; i < reloc16_count; i++) |
| 605 | /* Now print each relocation */ | 720 | write32(relocs16[i], stdout); |
| 606 | for (i = 0; i < reloc_count; i++) { | 721 | write32(reloc_count, stdout); |
| 607 | put_unaligned_le32(relocs[i], buf); | 722 | |
| 608 | fwrite(buf, 4, 1, stdout); | 723 | /* Now print each relocation */ |
| 724 | for (i = 0; i < reloc_count; i++) | ||
| 725 | write32(relocs[i], stdout); | ||
| 726 | } else { | ||
| 727 | /* Print a stop */ | ||
| 728 | write32(0, stdout); | ||
| 729 | |||
| 730 | /* Now print each relocation */ | ||
| 731 | for (i = 0; i < reloc_count; i++) { | ||
| 732 | write32(relocs[i], stdout); | ||
| 733 | } | ||
| 609 | } | 734 | } |
| 610 | } | 735 | } |
| 611 | } | 736 | } |
| 612 | 737 | ||
| 613 | static void usage(void) | 738 | static void usage(void) |
| 614 | { | 739 | { |
| 615 | die("relocs [--abs-syms |--abs-relocs | --text] vmlinux\n"); | 740 | die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n"); |
| 616 | } | 741 | } |
| 617 | 742 | ||
| 618 | int main(int argc, char **argv) | 743 | int main(int argc, char **argv) |
| 619 | { | 744 | { |
| 620 | int show_absolute_syms, show_absolute_relocs; | 745 | int show_absolute_syms, show_absolute_relocs; |
| 621 | int as_text; | 746 | int as_text, use_real_mode; |
| 622 | const char *fname; | 747 | const char *fname; |
| 623 | FILE *fp; | 748 | FILE *fp; |
| 624 | int i; | 749 | int i; |
| 625 | 750 | ||
| 626 | regex_init(); | ||
| 627 | |||
| 628 | show_absolute_syms = 0; | 751 | show_absolute_syms = 0; |
| 629 | show_absolute_relocs = 0; | 752 | show_absolute_relocs = 0; |
| 630 | as_text = 0; | 753 | as_text = 0; |
| 754 | use_real_mode = 0; | ||
| 631 | fname = NULL; | 755 | fname = NULL; |
| 632 | for (i = 1; i < argc; i++) { | 756 | for (i = 1; i < argc; i++) { |
| 633 | char *arg = argv[i]; | 757 | char *arg = argv[i]; |
| 634 | if (*arg == '-') { | 758 | if (*arg == '-') { |
| 635 | if (strcmp(argv[1], "--abs-syms") == 0) { | 759 | if (strcmp(arg, "--abs-syms") == 0) { |
| 636 | show_absolute_syms = 1; | 760 | show_absolute_syms = 1; |
| 637 | continue; | 761 | continue; |
| 638 | } | 762 | } |
| 639 | 763 | if (strcmp(arg, "--abs-relocs") == 0) { | |
| 640 | if (strcmp(argv[1], "--abs-relocs") == 0) { | ||
| 641 | show_absolute_relocs = 1; | 764 | show_absolute_relocs = 1; |
| 642 | continue; | 765 | continue; |
| 643 | } | 766 | } |
| 644 | else if (strcmp(argv[1], "--text") == 0) { | 767 | if (strcmp(arg, "--text") == 0) { |
| 645 | as_text = 1; | 768 | as_text = 1; |
| 646 | continue; | 769 | continue; |
| 647 | } | 770 | } |
| 771 | if (strcmp(arg, "--realmode") == 0) { | ||
| 772 | use_real_mode = 1; | ||
| 773 | continue; | ||
| 774 | } | ||
| 648 | } | 775 | } |
| 649 | else if (!fname) { | 776 | else if (!fname) { |
| 650 | fname = arg; | 777 | fname = arg; |
| @@ -655,6 +782,7 @@ int main(int argc, char **argv) | |||
| 655 | if (!fname) { | 782 | if (!fname) { |
| 656 | usage(); | 783 | usage(); |
| 657 | } | 784 | } |
| 785 | regex_init(use_real_mode); | ||
| 658 | fp = fopen(fname, "r"); | 786 | fp = fopen(fname, "r"); |
| 659 | if (!fp) { | 787 | if (!fp) { |
| 660 | die("Cannot open %s: %s\n", | 788 | die("Cannot open %s: %s\n", |
| @@ -673,6 +801,6 @@ int main(int argc, char **argv) | |||
| 673 | print_absolute_relocs(); | 801 | print_absolute_relocs(); |
| 674 | return 0; | 802 | return 0; |
| 675 | } | 803 | } |
| 676 | emit_relocs(as_text); | 804 | emit_relocs(as_text, use_real_mode); |
| 677 | return 0; | 805 | return 0; |
| 678 | } | 806 | } |
