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 | } |