diff options
Diffstat (limited to 'arch/x86/tools/relocs.c')
-rw-r--r-- | arch/x86/tools/relocs.c | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c index f7bab68a4b83..cfbdbdb4e173 100644 --- a/arch/x86/tools/relocs.c +++ b/arch/x86/tools/relocs.c | |||
@@ -722,15 +722,25 @@ static void percpu_init(void) | |||
722 | 722 | ||
723 | /* | 723 | /* |
724 | * Check to see if a symbol lies in the .data..percpu section. | 724 | * Check to see if a symbol lies in the .data..percpu section. |
725 | * For some as yet not understood reason the "__init_begin" | 725 | * |
726 | * symbol which immediately preceeds the .data..percpu section | 726 | * The linker incorrectly associates some symbols with the |
727 | * also shows up as it it were part of it so we do an explict | 727 | * .data..percpu section so we also need to check the symbol |
728 | * check for that symbol name and ignore it. | 728 | * name to make sure that we classify the symbol correctly. |
729 | * | ||
730 | * The GNU linker incorrectly associates: | ||
731 | * __init_begin | ||
732 | * __per_cpu_load | ||
733 | * | ||
734 | * The "gold" linker incorrectly associates: | ||
735 | * init_per_cpu__irq_stack_union | ||
736 | * init_per_cpu__gdt_page | ||
729 | */ | 737 | */ |
730 | static int is_percpu_sym(ElfW(Sym) *sym, const char *symname) | 738 | static int is_percpu_sym(ElfW(Sym) *sym, const char *symname) |
731 | { | 739 | { |
732 | return (sym->st_shndx == per_cpu_shndx) && | 740 | return (sym->st_shndx == per_cpu_shndx) && |
733 | strcmp(symname, "__init_begin"); | 741 | strcmp(symname, "__init_begin") && |
742 | strcmp(symname, "__per_cpu_load") && | ||
743 | strncmp(symname, "init_per_cpu_", 13); | ||
734 | } | 744 | } |
735 | 745 | ||
736 | 746 | ||
@@ -1015,6 +1025,29 @@ static void emit_relocs(int as_text, int use_real_mode) | |||
1015 | } | 1025 | } |
1016 | } | 1026 | } |
1017 | 1027 | ||
1028 | /* | ||
1029 | * As an aid to debugging problems with different linkers | ||
1030 | * print summary information about the relocs. | ||
1031 | * Since different linkers tend to emit the sections in | ||
1032 | * different orders we use the section names in the output. | ||
1033 | */ | ||
1034 | static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, | ||
1035 | const char *symname) | ||
1036 | { | ||
1037 | printf("%s\t%s\t%s\t%s\n", | ||
1038 | sec_name(sec->shdr.sh_info), | ||
1039 | rel_type(ELF_R_TYPE(rel->r_info)), | ||
1040 | symname, | ||
1041 | sec_name(sym->st_shndx)); | ||
1042 | return 0; | ||
1043 | } | ||
1044 | |||
1045 | static void print_reloc_info(void) | ||
1046 | { | ||
1047 | printf("reloc section\treloc type\tsymbol\tsymbol section\n"); | ||
1048 | walk_relocs(do_reloc_info); | ||
1049 | } | ||
1050 | |||
1018 | #if ELF_BITS == 64 | 1051 | #if ELF_BITS == 64 |
1019 | # define process process_64 | 1052 | # define process process_64 |
1020 | #else | 1053 | #else |
@@ -1022,7 +1055,8 @@ static void emit_relocs(int as_text, int use_real_mode) | |||
1022 | #endif | 1055 | #endif |
1023 | 1056 | ||
1024 | void process(FILE *fp, int use_real_mode, int as_text, | 1057 | void process(FILE *fp, int use_real_mode, int as_text, |
1025 | int show_absolute_syms, int show_absolute_relocs) | 1058 | int show_absolute_syms, int show_absolute_relocs, |
1059 | int show_reloc_info) | ||
1026 | { | 1060 | { |
1027 | regex_init(use_real_mode); | 1061 | regex_init(use_real_mode); |
1028 | read_ehdr(fp); | 1062 | read_ehdr(fp); |
@@ -1040,5 +1074,9 @@ void process(FILE *fp, int use_real_mode, int as_text, | |||
1040 | print_absolute_relocs(); | 1074 | print_absolute_relocs(); |
1041 | return; | 1075 | return; |
1042 | } | 1076 | } |
1077 | if (show_reloc_info) { | ||
1078 | print_reloc_info(); | ||
1079 | return; | ||
1080 | } | ||
1043 | emit_relocs(as_text, use_real_mode); | 1081 | emit_relocs(as_text, use_real_mode); |
1044 | } | 1082 | } |