diff options
| author | H. Peter Anvin <hpa@linux.intel.com> | 2013-04-16 19:02:58 -0400 |
|---|---|---|
| committer | H. Peter Anvin <hpa@linux.intel.com> | 2013-04-16 19:02:58 -0400 |
| commit | c889ba801dc3b3a0155fa77d567f2c3a6097de1c (patch) | |
| tree | 257878e1eb565fc9765dd8fed20815f7781d116a /arch | |
| parent | 17c961f7702ff6037b66bb2e5f3ddd58de4ce7e5 (diff) | |
x86, relocs: Refactor the relocs tool to merge 32- and 64-bit ELF
Refactor the relocs tool so that the same tool can handle 32- and
64-bit ELF.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: Kees Cook <keescook@chromium.org>
Link: http://lkml.kernel.org/r/1365797627-20874-5-git-send-email-keescook@chromium.org
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86/boot/compressed/Makefile | 2 | ||||
| -rw-r--r-- | arch/x86/realmode/rm/Makefile | 2 | ||||
| -rw-r--r-- | arch/x86/tools/.gitignore | 3 | ||||
| -rw-r--r-- | arch/x86/tools/Makefile | 21 | ||||
| -rw-r--r-- | arch/x86/tools/relocs.c | 162 | ||||
| -rw-r--r-- | arch/x86/tools/relocs.h | 36 | ||||
| -rw-r--r-- | arch/x86/tools/relocs_32.c | 17 | ||||
| -rw-r--r-- | arch/x86/tools/relocs_64.c | 17 | ||||
| -rw-r--r-- | arch/x86/tools/relocs_common.c | 76 |
9 files changed, 183 insertions, 153 deletions
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 0dac17528099..5ef205c5f37b 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile | |||
| @@ -44,7 +44,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE | |||
| 44 | 44 | ||
| 45 | targets += $(patsubst $(obj)/%,%,$(VMLINUX_OBJS)) vmlinux.bin.all vmlinux.relocs | 45 | targets += $(patsubst $(obj)/%,%,$(VMLINUX_OBJS)) vmlinux.bin.all vmlinux.relocs |
| 46 | 46 | ||
| 47 | CMD_RELOCS = arch/x86/tools/relocs_$(BITS) | 47 | CMD_RELOCS = arch/x86/tools/relocs |
| 48 | quiet_cmd_relocs = RELOCS $@ | 48 | quiet_cmd_relocs = RELOCS $@ |
| 49 | cmd_relocs = $(CMD_RELOCS) $< > $@;$(CMD_RELOCS) --abs-relocs $< | 49 | cmd_relocs = $(CMD_RELOCS) $< > $@;$(CMD_RELOCS) --abs-relocs $< |
| 50 | $(obj)/vmlinux.relocs: vmlinux FORCE | 50 | $(obj)/vmlinux.relocs: vmlinux FORCE |
diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile index 2b1e4294b8b9..88692871823f 100644 --- a/arch/x86/realmode/rm/Makefile +++ b/arch/x86/realmode/rm/Makefile | |||
| @@ -56,7 +56,7 @@ $(obj)/realmode.bin: $(obj)/realmode.elf $(obj)/realmode.relocs | |||
| 56 | $(call if_changed,objcopy) | 56 | $(call if_changed,objcopy) |
| 57 | 57 | ||
| 58 | quiet_cmd_relocs = RELOCS $@ | 58 | quiet_cmd_relocs = RELOCS $@ |
| 59 | cmd_relocs = arch/x86/tools/relocs_32 --realmode $< > $@ | 59 | cmd_relocs = arch/x86/tools/relocs --realmode $< > $@ |
| 60 | 60 | ||
| 61 | targets += realmode.relocs | 61 | targets += realmode.relocs |
| 62 | $(obj)/realmode.relocs: $(obj)/realmode.elf FORCE | 62 | $(obj)/realmode.relocs: $(obj)/realmode.elf FORCE |
diff --git a/arch/x86/tools/.gitignore b/arch/x86/tools/.gitignore index 2b45d5f063ba..be0ed065249b 100644 --- a/arch/x86/tools/.gitignore +++ b/arch/x86/tools/.gitignore | |||
| @@ -1,2 +1 @@ | |||
| 1 | relocs_32* | relocs | |
| 2 | relocs_64* | ||
diff --git a/arch/x86/tools/Makefile b/arch/x86/tools/Makefile index a8cb70c6b8a1..e8120346903b 100644 --- a/arch/x86/tools/Makefile +++ b/arch/x86/tools/Makefile | |||
| @@ -37,22 +37,7 @@ $(obj)/test_get_len.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/in | |||
| 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 | 39 | ||
| 40 | HOSTCFLAGS_relocs_32.o += -DELF_BITS=32 | ||
| 41 | HOSTCFLAGS_relocs_64.o += -DELF_BITS=64 | ||
| 42 | |||
| 43 | quiet_cmd_cp_reloc = GEN $@ | ||
| 44 | cmd_cp_reloc = cp $< $@ | ||
| 45 | |||
| 46 | $(obj)/relocs_%.c: $(srctree)/arch/x86/tools/relocs.c | ||
| 47 | $(call cmd,cp_reloc) | ||
| 48 | |||
| 49 | HOST_EXTRACFLAGS += -I$(srctree)/tools/include | 40 | HOST_EXTRACFLAGS += -I$(srctree)/tools/include |
| 50 | hostprogs-y += relocs_$(BITS) | 41 | hostprogs-y += relocs |
| 51 | relocs_binaries = relocs_$(BITS) | 42 | relocs-objs := relocs_32.o relocs_64.o relocs_common.o |
| 52 | ifeq ($(CONFIG_64BIT),y) | 43 | relocs: $(obj)/relocs |
| 53 | hostprogs-y += relocs_32 | ||
| 54 | relocs_binaries += relocs_32 | ||
| 55 | endif | ||
| 56 | relocs: $(relocs_binaries) | ||
| 57 | relocs_32: $(obj)/relocs_32 | ||
| 58 | relocs_64: $(obj)/relocs_64 | ||
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c index 1f7ff3d11a05..590be1090892 100644 --- a/arch/x86/tools/relocs.c +++ b/arch/x86/tools/relocs.c | |||
| @@ -1,63 +1,15 @@ | |||
| 1 | #include <stdio.h> | 1 | /* This is included from relocs_32/64.c */ |
| 2 | #include <stdarg.h> | ||
| 3 | #include <stdlib.h> | ||
| 4 | #include <stdint.h> | ||
| 5 | #include <inttypes.h> | ||
| 6 | #include <string.h> | ||
| 7 | #include <errno.h> | ||
| 8 | #include <unistd.h> | ||
| 9 | #include <elf.h> | ||
| 10 | #include <byteswap.h> | ||
| 11 | #define USE_BSD | ||
| 12 | #include <endian.h> | ||
| 13 | #include <regex.h> | ||
| 14 | #include <tools/le_byteshift.h> | ||
| 15 | 2 | ||
| 16 | #define ElfW(type) _ElfW(ELF_BITS, type) | 3 | #define ElfW(type) _ElfW(ELF_BITS, type) |
| 17 | #define _ElfW(bits, type) __ElfW(bits, type) | 4 | #define _ElfW(bits, type) __ElfW(bits, type) |
| 18 | #define __ElfW(bits, type) Elf##bits##_##type | 5 | #define __ElfW(bits, type) Elf##bits##_##type |
| 19 | 6 | ||
| 20 | #ifndef ELF_BITS | ||
| 21 | #define ELF_BITS 32 | ||
| 22 | #endif | ||
| 23 | |||
| 24 | #if (ELF_BITS == 64) | ||
| 25 | #define ELF_MACHINE EM_X86_64 | ||
| 26 | #define ELF_MACHINE_NAME "x86_64" | ||
| 27 | #define SHT_REL_TYPE SHT_RELA | ||
| 28 | #define Elf_Rel Elf64_Rela | ||
| 29 | #else | ||
| 30 | #define ELF_MACHINE EM_386 | ||
| 31 | #define ELF_MACHINE_NAME "i386" | ||
| 32 | #define SHT_REL_TYPE SHT_REL | ||
| 33 | #define Elf_Rel ElfW(Rel) | ||
| 34 | #endif | ||
| 35 | |||
| 36 | #if (ELF_BITS == 64) | ||
| 37 | #define ELF_CLASS ELFCLASS64 | ||
| 38 | #define ELF_R_SYM(val) ELF64_R_SYM(val) | ||
| 39 | #define ELF_R_TYPE(val) ELF64_R_TYPE(val) | ||
| 40 | #define ELF_ST_TYPE(o) ELF64_ST_TYPE(o) | ||
| 41 | #define ELF_ST_BIND(o) ELF64_ST_BIND(o) | ||
| 42 | #define ELF_ST_VISIBILITY(o) ELF64_ST_VISIBILITY(o) | ||
| 43 | #else | ||
| 44 | #define ELF_CLASS ELFCLASS32 | ||
| 45 | #define ELF_R_SYM(val) ELF32_R_SYM(val) | ||
| 46 | #define ELF_R_TYPE(val) ELF32_R_TYPE(val) | ||
| 47 | #define ELF_ST_TYPE(o) ELF32_ST_TYPE(o) | ||
| 48 | #define ELF_ST_BIND(o) ELF32_ST_BIND(o) | ||
| 49 | #define ELF_ST_VISIBILITY(o) ELF32_ST_VISIBILITY(o) | ||
| 50 | #endif | ||
| 51 | |||
| 52 | #define Elf_Addr ElfW(Addr) | 7 | #define Elf_Addr ElfW(Addr) |
| 53 | #define Elf_Ehdr ElfW(Ehdr) | 8 | #define Elf_Ehdr ElfW(Ehdr) |
| 54 | #define Elf_Phdr ElfW(Phdr) | 9 | #define Elf_Phdr ElfW(Phdr) |
| 55 | #define Elf_Shdr ElfW(Shdr) | 10 | #define Elf_Shdr ElfW(Shdr) |
| 56 | #define Elf_Sym ElfW(Sym) | 11 | #define Elf_Sym ElfW(Sym) |
| 57 | 12 | ||
| 58 | static void die(char *fmt, ...); | ||
| 59 | |||
| 60 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
| 61 | static Elf_Ehdr ehdr; | 13 | static Elf_Ehdr ehdr; |
| 62 | 14 | ||
| 63 | struct relocs { | 15 | struct relocs { |
| @@ -79,14 +31,6 @@ struct section { | |||
| 79 | }; | 31 | }; |
| 80 | static struct section *secs; | 32 | static struct section *secs; |
| 81 | 33 | ||
| 82 | enum symtype { | ||
| 83 | S_ABS, | ||
| 84 | S_REL, | ||
| 85 | S_SEG, | ||
| 86 | S_LIN, | ||
| 87 | S_NSYMTYPES | ||
| 88 | }; | ||
| 89 | |||
| 90 | static const char * const sym_regex_kernel[S_NSYMTYPES] = { | 34 | static const char * const sym_regex_kernel[S_NSYMTYPES] = { |
| 91 | /* | 35 | /* |
| 92 | * Following symbols have been audited. There values are constant and do | 36 | * Following symbols have been audited. There values are constant and do |
| @@ -98,7 +42,7 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = { | |||
| 98 | "^(xen_irq_disable_direct_reloc$|" | 42 | "^(xen_irq_disable_direct_reloc$|" |
| 99 | "xen_save_fl_direct_reloc$|" | 43 | "xen_save_fl_direct_reloc$|" |
| 100 | "VDSO|" | 44 | "VDSO|" |
| 101 | #if (ELF_BITS == 64) | 45 | #if ELF_BITS == 64 |
| 102 | "__vvar_page|" | 46 | "__vvar_page|" |
| 103 | #endif | 47 | #endif |
| 104 | "__crc_)", | 48 | "__crc_)", |
| @@ -124,7 +68,7 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = { | |||
| 124 | "__end_rodata|" | 68 | "__end_rodata|" |
| 125 | "__initramfs_start|" | 69 | "__initramfs_start|" |
| 126 | "(jiffies|jiffies_64)|" | 70 | "(jiffies|jiffies_64)|" |
| 127 | #if (ELF_BITS == 64) | 71 | #if ELF_BITS == 64 |
| 128 | "__per_cpu_load|" | 72 | "__per_cpu_load|" |
| 129 | "init_per_cpu__.*|" | 73 | "init_per_cpu__.*|" |
| 130 | "__end_rodata_hpage_align|" | 74 | "__end_rodata_hpage_align|" |
| @@ -189,15 +133,6 @@ static void regex_init(int use_real_mode) | |||
| 189 | } | 133 | } |
| 190 | } | 134 | } |
| 191 | 135 | ||
| 192 | static void die(char *fmt, ...) | ||
| 193 | { | ||
| 194 | va_list ap; | ||
| 195 | va_start(ap, fmt); | ||
| 196 | vfprintf(stderr, fmt, ap); | ||
| 197 | va_end(ap); | ||
| 198 | exit(1); | ||
| 199 | } | ||
| 200 | |||
| 201 | static const char *sym_type(unsigned type) | 136 | static const char *sym_type(unsigned type) |
| 202 | { | 137 | { |
| 203 | static const char *type_name[] = { | 138 | static const char *type_name[] = { |
| @@ -255,7 +190,7 @@ static const char *rel_type(unsigned type) | |||
| 255 | { | 190 | { |
| 256 | static const char *type_name[] = { | 191 | static const char *type_name[] = { |
| 257 | #define REL_TYPE(X) [X] = #X | 192 | #define REL_TYPE(X) [X] = #X |
| 258 | #if (ELF_BITS == 64) | 193 | #if ELF_BITS == 64 |
| 259 | REL_TYPE(R_X86_64_NONE), | 194 | REL_TYPE(R_X86_64_NONE), |
| 260 | REL_TYPE(R_X86_64_64), | 195 | REL_TYPE(R_X86_64_64), |
| 261 | REL_TYPE(R_X86_64_PC32), | 196 | REL_TYPE(R_X86_64_PC32), |
| @@ -380,7 +315,7 @@ static uint32_t elf32_to_cpu(uint32_t val) | |||
| 380 | #define elf_half_to_cpu(x) elf16_to_cpu(x) | 315 | #define elf_half_to_cpu(x) elf16_to_cpu(x) |
| 381 | #define elf_word_to_cpu(x) elf32_to_cpu(x) | 316 | #define elf_word_to_cpu(x) elf32_to_cpu(x) |
| 382 | 317 | ||
| 383 | #if (ELF_BITS == 64) | 318 | #if ELF_BITS == 64 |
| 384 | static uint64_t elf64_to_cpu(uint64_t val) | 319 | static uint64_t elf64_to_cpu(uint64_t val) |
| 385 | { | 320 | { |
| 386 | return le64_to_cpu(val); | 321 | return le64_to_cpu(val); |
| @@ -582,7 +517,7 @@ static void print_absolute_symbols(void) | |||
| 582 | int i; | 517 | int i; |
| 583 | const char *format; | 518 | const char *format; |
| 584 | 519 | ||
| 585 | if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) | 520 | if (ELF_BITS == 64) |
| 586 | format = "%5d %016"PRIx64" %5"PRId64" %10s %10s %12s %s\n"; | 521 | format = "%5d %016"PRIx64" %5"PRId64" %10s %10s %12s %s\n"; |
| 587 | else | 522 | else |
| 588 | format = "%5d %08"PRIx32" %5"PRId32" %10s %10s %12s %s\n"; | 523 | format = "%5d %08"PRIx32" %5"PRId32" %10s %10s %12s %s\n"; |
| @@ -622,7 +557,7 @@ static void print_absolute_relocs(void) | |||
| 622 | int i, printed = 0; | 557 | int i, printed = 0; |
| 623 | const char *format; | 558 | const char *format; |
| 624 | 559 | ||
| 625 | if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) | 560 | if (ELF_BITS == 64) |
| 626 | format = "%016"PRIx64" %016"PRIx64" %10s %016"PRIx64" %s\n"; | 561 | format = "%016"PRIx64" %016"PRIx64" %10s %016"PRIx64" %s\n"; |
| 627 | else | 562 | else |
| 628 | format = "%08"PRIx32" %08"PRIx32" %10s %08"PRIx32" %s\n"; | 563 | format = "%08"PRIx32" %08"PRIx32" %10s %08"PRIx32" %s\n"; |
| @@ -785,6 +720,8 @@ static void percpu_init(void) | |||
| 785 | } | 720 | } |
| 786 | } | 721 | } |
| 787 | 722 | ||
| 723 | #if ELF_BITS == 64 | ||
| 724 | |||
| 788 | /* | 725 | /* |
| 789 | * Check to see if a symbol lies in the .data..percpu section. | 726 | * Check to see if a symbol lies in the .data..percpu section. |
| 790 | * For some as yet not understood reason the "__init_begin" | 727 | * For some as yet not understood reason the "__init_begin" |
| @@ -798,6 +735,7 @@ static int is_percpu_sym(ElfW(Sym) *sym, const char *symname) | |||
| 798 | strcmp(symname, "__init_begin"); | 735 | strcmp(symname, "__init_begin"); |
| 799 | } | 736 | } |
| 800 | 737 | ||
| 738 | |||
| 801 | static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, | 739 | static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, |
| 802 | const char *symname) | 740 | const char *symname) |
| 803 | { | 741 | { |
| @@ -869,6 +807,7 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, | |||
| 869 | return 0; | 807 | return 0; |
| 870 | } | 808 | } |
| 871 | 809 | ||
| 810 | #else | ||
| 872 | 811 | ||
| 873 | static int do_reloc32(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, | 812 | static int do_reloc32(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, |
| 874 | const char *symname) | 813 | const char *symname) |
| @@ -984,6 +923,8 @@ static int do_reloc_real(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, | |||
| 984 | return 0; | 923 | return 0; |
| 985 | } | 924 | } |
| 986 | 925 | ||
| 926 | #endif | ||
| 927 | |||
| 987 | static int cmp_relocs(const void *va, const void *vb) | 928 | static int cmp_relocs(const void *va, const void *vb) |
| 988 | { | 929 | { |
| 989 | const uint32_t *a, *b; | 930 | const uint32_t *a, *b; |
| @@ -1016,12 +957,17 @@ static void emit_relocs(int as_text, int use_real_mode) | |||
| 1016 | int (*do_reloc)(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, | 957 | int (*do_reloc)(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, |
| 1017 | const char *symname); | 958 | const char *symname); |
| 1018 | 959 | ||
| 1019 | if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) | 960 | #if ELF_BITS == 64 |
| 961 | if (!use_real_mode) | ||
| 1020 | do_reloc = do_reloc64; | 962 | do_reloc = do_reloc64; |
| 1021 | else if (!use_real_mode) | 963 | else |
| 964 | die("--realmode not valid for a 64-bit ELF file"); | ||
| 965 | #else | ||
| 966 | if (!use_real_mode) | ||
| 1022 | do_reloc = do_reloc32; | 967 | do_reloc = do_reloc32; |
| 1023 | else | 968 | else |
| 1024 | do_reloc = do_reloc_real; | 969 | do_reloc = do_reloc_real; |
| 970 | #endif | ||
| 1025 | 971 | ||
| 1026 | /* Collect up the relocations */ | 972 | /* Collect up the relocations */ |
| 1027 | walk_relocs(do_reloc); | 973 | walk_relocs(do_reloc); |
| @@ -1053,7 +999,7 @@ static void emit_relocs(int as_text, int use_real_mode) | |||
| 1053 | for (i = 0; i < relocs32.count; i++) | 999 | for (i = 0; i < relocs32.count; i++) |
| 1054 | write_reloc(relocs32.offset[i], stdout); | 1000 | write_reloc(relocs32.offset[i], stdout); |
| 1055 | } else { | 1001 | } else { |
| 1056 | if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) { | 1002 | if (ELF_BITS == 64) { |
| 1057 | /* Print a stop */ | 1003 | /* Print a stop */ |
| 1058 | write_reloc(0, stdout); | 1004 | write_reloc(0, stdout); |
| 1059 | 1005 | ||
| @@ -1071,76 +1017,30 @@ static void emit_relocs(int as_text, int use_real_mode) | |||
| 1071 | } | 1017 | } |
| 1072 | } | 1018 | } |
| 1073 | 1019 | ||
| 1074 | static void usage(void) | 1020 | #if ELF_BITS == 64 |
| 1075 | { | 1021 | # define process process_64 |
| 1076 | die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n"); | 1022 | #else |
| 1077 | } | 1023 | # define process process_32 |
| 1024 | #endif | ||
| 1078 | 1025 | ||
| 1079 | int main(int argc, char **argv) | 1026 | void process(FILE *fp, int use_real_mode, int as_text, |
| 1027 | int show_absolute_syms, int show_absolute_relocs) | ||
| 1080 | { | 1028 | { |
| 1081 | int show_absolute_syms, show_absolute_relocs; | ||
| 1082 | int as_text, use_real_mode; | ||
| 1083 | const char *fname; | ||
| 1084 | FILE *fp; | ||
| 1085 | int i; | ||
| 1086 | |||
| 1087 | show_absolute_syms = 0; | ||
| 1088 | show_absolute_relocs = 0; | ||
| 1089 | as_text = 0; | ||
| 1090 | use_real_mode = 0; | ||
| 1091 | fname = NULL; | ||
| 1092 | for (i = 1; i < argc; i++) { | ||
| 1093 | char *arg = argv[i]; | ||
| 1094 | if (*arg == '-') { | ||
| 1095 | if (strcmp(arg, "--abs-syms") == 0) { | ||
| 1096 | show_absolute_syms = 1; | ||
| 1097 | continue; | ||
| 1098 | } | ||
| 1099 | if (strcmp(arg, "--abs-relocs") == 0) { | ||
| 1100 | show_absolute_relocs = 1; | ||
| 1101 | continue; | ||
| 1102 | } | ||
| 1103 | if (strcmp(arg, "--text") == 0) { | ||
| 1104 | as_text = 1; | ||
| 1105 | continue; | ||
| 1106 | } | ||
| 1107 | if (strcmp(arg, "--realmode") == 0) { | ||
| 1108 | use_real_mode = 1; | ||
| 1109 | continue; | ||
| 1110 | } | ||
| 1111 | } | ||
| 1112 | else if (!fname) { | ||
| 1113 | fname = arg; | ||
| 1114 | continue; | ||
| 1115 | } | ||
| 1116 | usage(); | ||
| 1117 | } | ||
| 1118 | if (!fname) { | ||
| 1119 | usage(); | ||
| 1120 | } | ||
| 1121 | regex_init(use_real_mode); | 1029 | regex_init(use_real_mode); |
| 1122 | fp = fopen(fname, "r"); | ||
| 1123 | if (!fp) { | ||
| 1124 | die("Cannot open %s: %s\n", | ||
| 1125 | fname, strerror(errno)); | ||
| 1126 | } | ||
| 1127 | read_ehdr(fp); | 1030 | read_ehdr(fp); |
| 1128 | read_shdrs(fp); | 1031 | read_shdrs(fp); |
| 1129 | read_strtabs(fp); | 1032 | read_strtabs(fp); |
| 1130 | read_symtabs(fp); | 1033 | read_symtabs(fp); |
| 1131 | read_relocs(fp); | 1034 | read_relocs(fp); |
| 1132 | if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) | 1035 | if (ELF_BITS == 64) |
| 1133 | percpu_init(); | 1036 | percpu_init(); |
| 1134 | if (show_absolute_syms) { | 1037 | if (show_absolute_syms) { |
| 1135 | print_absolute_symbols(); | 1038 | print_absolute_symbols(); |
| 1136 | goto out; | 1039 | return; |
| 1137 | } | 1040 | } |
| 1138 | if (show_absolute_relocs) { | 1041 | if (show_absolute_relocs) { |
| 1139 | print_absolute_relocs(); | 1042 | print_absolute_relocs(); |
| 1140 | goto out; | 1043 | return; |
| 1141 | } | 1044 | } |
| 1142 | emit_relocs(as_text, use_real_mode); | 1045 | emit_relocs(as_text, use_real_mode); |
| 1143 | out: | ||
| 1144 | fclose(fp); | ||
| 1145 | return 0; | ||
| 1146 | } | 1046 | } |
diff --git a/arch/x86/tools/relocs.h b/arch/x86/tools/relocs.h new file mode 100644 index 000000000000..07cdb1eca4fa --- /dev/null +++ b/arch/x86/tools/relocs.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | #ifndef RELOCS_H | ||
| 2 | #define RELOCS_H | ||
| 3 | |||
| 4 | #include <stdio.h> | ||
| 5 | #include <stdarg.h> | ||
| 6 | #include <stdlib.h> | ||
| 7 | #include <stdint.h> | ||
| 8 | #include <inttypes.h> | ||
| 9 | #include <string.h> | ||
| 10 | #include <errno.h> | ||
| 11 | #include <unistd.h> | ||
| 12 | #include <elf.h> | ||
| 13 | #include <byteswap.h> | ||
| 14 | #define USE_BSD | ||
| 15 | #include <endian.h> | ||
| 16 | #include <regex.h> | ||
| 17 | #include <tools/le_byteshift.h> | ||
| 18 | |||
| 19 | void die(char *fmt, ...); | ||
| 20 | |||
| 21 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||
| 22 | |||
| 23 | enum symtype { | ||
| 24 | S_ABS, | ||
| 25 | S_REL, | ||
| 26 | S_SEG, | ||
| 27 | S_LIN, | ||
| 28 | S_NSYMTYPES | ||
| 29 | }; | ||
| 30 | |||
| 31 | void process_32(FILE *fp, int use_real_mode, int as_text, | ||
| 32 | int show_absolute_syms, int show_absolute_relocs); | ||
| 33 | void process_64(FILE *fp, int use_real_mode, int as_text, | ||
| 34 | int show_absolute_syms, int show_absolute_relocs); | ||
| 35 | |||
| 36 | #endif /* RELOCS_H */ | ||
diff --git a/arch/x86/tools/relocs_32.c b/arch/x86/tools/relocs_32.c new file mode 100644 index 000000000000..b2ade2bb4162 --- /dev/null +++ b/arch/x86/tools/relocs_32.c | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | #include "relocs.h" | ||
| 2 | |||
| 3 | #define ELF_BITS 32 | ||
| 4 | |||
| 5 | #define ELF_MACHINE EM_386 | ||
| 6 | #define ELF_MACHINE_NAME "i386" | ||
| 7 | #define SHT_REL_TYPE SHT_REL | ||
| 8 | #define Elf_Rel ElfW(Rel) | ||
| 9 | |||
| 10 | #define ELF_CLASS ELFCLASS32 | ||
| 11 | #define ELF_R_SYM(val) ELF32_R_SYM(val) | ||
| 12 | #define ELF_R_TYPE(val) ELF32_R_TYPE(val) | ||
| 13 | #define ELF_ST_TYPE(o) ELF32_ST_TYPE(o) | ||
| 14 | #define ELF_ST_BIND(o) ELF32_ST_BIND(o) | ||
| 15 | #define ELF_ST_VISIBILITY(o) ELF32_ST_VISIBILITY(o) | ||
| 16 | |||
| 17 | #include "relocs.c" | ||
diff --git a/arch/x86/tools/relocs_64.c b/arch/x86/tools/relocs_64.c new file mode 100644 index 000000000000..56b61b743c4c --- /dev/null +++ b/arch/x86/tools/relocs_64.c | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | #include "relocs.h" | ||
| 2 | |||
| 3 | #define ELF_BITS 64 | ||
| 4 | |||
| 5 | #define ELF_MACHINE EM_X86_64 | ||
| 6 | #define ELF_MACHINE_NAME "x86_64" | ||
| 7 | #define SHT_REL_TYPE SHT_RELA | ||
| 8 | #define Elf_Rel Elf64_Rela | ||
| 9 | |||
| 10 | #define ELF_CLASS ELFCLASS64 | ||
| 11 | #define ELF_R_SYM(val) ELF64_R_SYM(val) | ||
| 12 | #define ELF_R_TYPE(val) ELF64_R_TYPE(val) | ||
| 13 | #define ELF_ST_TYPE(o) ELF64_ST_TYPE(o) | ||
| 14 | #define ELF_ST_BIND(o) ELF64_ST_BIND(o) | ||
| 15 | #define ELF_ST_VISIBILITY(o) ELF64_ST_VISIBILITY(o) | ||
| 16 | |||
| 17 | #include "relocs.c" | ||
diff --git a/arch/x86/tools/relocs_common.c b/arch/x86/tools/relocs_common.c new file mode 100644 index 000000000000..44d396823a53 --- /dev/null +++ b/arch/x86/tools/relocs_common.c | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | #include "relocs.h" | ||
| 2 | |||
| 3 | void die(char *fmt, ...) | ||
| 4 | { | ||
| 5 | va_list ap; | ||
| 6 | va_start(ap, fmt); | ||
| 7 | vfprintf(stderr, fmt, ap); | ||
| 8 | va_end(ap); | ||
| 9 | exit(1); | ||
| 10 | } | ||
| 11 | |||
| 12 | static void usage(void) | ||
| 13 | { | ||
| 14 | die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n"); | ||
| 15 | } | ||
| 16 | |||
| 17 | int main(int argc, char **argv) | ||
| 18 | { | ||
| 19 | int show_absolute_syms, show_absolute_relocs; | ||
| 20 | int as_text, use_real_mode; | ||
| 21 | const char *fname; | ||
| 22 | FILE *fp; | ||
| 23 | int i; | ||
| 24 | unsigned char e_ident[EI_NIDENT]; | ||
| 25 | |||
| 26 | show_absolute_syms = 0; | ||
| 27 | show_absolute_relocs = 0; | ||
| 28 | as_text = 0; | ||
| 29 | use_real_mode = 0; | ||
| 30 | fname = NULL; | ||
| 31 | for (i = 1; i < argc; i++) { | ||
| 32 | char *arg = argv[i]; | ||
| 33 | if (*arg == '-') { | ||
| 34 | if (strcmp(arg, "--abs-syms") == 0) { | ||
| 35 | show_absolute_syms = 1; | ||
| 36 | continue; | ||
| 37 | } | ||
| 38 | if (strcmp(arg, "--abs-relocs") == 0) { | ||
| 39 | show_absolute_relocs = 1; | ||
| 40 | continue; | ||
| 41 | } | ||
| 42 | if (strcmp(arg, "--text") == 0) { | ||
| 43 | as_text = 1; | ||
| 44 | continue; | ||
| 45 | } | ||
| 46 | if (strcmp(arg, "--realmode") == 0) { | ||
| 47 | use_real_mode = 1; | ||
| 48 | continue; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | else if (!fname) { | ||
| 52 | fname = arg; | ||
| 53 | continue; | ||
| 54 | } | ||
| 55 | usage(); | ||
| 56 | } | ||
| 57 | if (!fname) { | ||
| 58 | usage(); | ||
| 59 | } | ||
| 60 | fp = fopen(fname, "r"); | ||
| 61 | if (!fp) { | ||
| 62 | die("Cannot open %s: %s\n", fname, strerror(errno)); | ||
| 63 | } | ||
| 64 | if (fread(&e_ident, 1, EI_NIDENT, fp) != EI_NIDENT) { | ||
| 65 | die("Cannot read %s: %s", fname, strerror(errno)); | ||
| 66 | } | ||
| 67 | rewind(fp); | ||
| 68 | if (e_ident[EI_CLASS] == ELFCLASS64) | ||
| 69 | process_64(fp, use_real_mode, as_text, | ||
| 70 | show_absolute_syms, show_absolute_relocs); | ||
| 71 | else | ||
| 72 | process_32(fp, use_real_mode, as_text, | ||
| 73 | show_absolute_syms, show_absolute_relocs); | ||
| 74 | fclose(fp); | ||
| 75 | return 0; | ||
| 76 | } | ||
