aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/tools/relocs.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/tools/relocs.c')
-rw-r--r--arch/x86/tools/relocs.c50
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 */
730static int is_percpu_sym(ElfW(Sym) *sym, const char *symname) 738static 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 */
1034static 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
1045static 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
1024void process(FILE *fp, int use_real_mode, int as_text, 1057void 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}