]> Pileus Git - ~andy/linux/commitdiff
x86, relocs: Add manual debug mode
authorMichael Davidson <md@google.com>
Tue, 21 Jan 2014 20:32:23 +0000 (12:32 -0800)
committerH. Peter Anvin <hpa@linux.intel.com>
Wed, 22 Jan 2014 12:21:45 +0000 (04:21 -0800)
Improve the debuggability of relocations output. When trying to compare
the output between different linkers, it's handy to be able to see the
section names in output.

Signed-off-by: Michael Davidson <md@google.com>
Link: http://lkml.kernel.org/r/20140121203223.GA12649@www.outflux.net
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
arch/x86/tools/relocs.c
arch/x86/tools/relocs.h
arch/x86/tools/relocs_common.c

index f7bab68a4b83e4094db9b70c50292fddd88098c1..9c2ab06dc4f2a6fcac6d1940288138ed4c5f132b 100644 (file)
@@ -1015,6 +1015,29 @@ static void emit_relocs(int as_text, int use_real_mode)
        }
 }
 
+/*
+ * As an aid to debugging problems with different linkers
+ * print summary information about the relocs.
+ * Since different linkers tend to emit the sections in
+ * different orders we use the section names in the output.
+ */
+static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
+                               const char *symname)
+{
+       printf("%s\t%s\t%s\t%s\n",
+               sec_name(sec->shdr.sh_info),
+               rel_type(ELF_R_TYPE(rel->r_info)),
+               symname,
+               sec_name(sym->st_shndx));
+       return 0;
+}
+
+static void print_reloc_info(void)
+{
+       printf("reloc section\treloc type\tsymbol\tsymbol section\n");
+       walk_relocs(do_reloc_info);
+}
+
 #if ELF_BITS == 64
 # define process process_64
 #else
@@ -1022,7 +1045,8 @@ static void emit_relocs(int as_text, int use_real_mode)
 #endif
 
 void process(FILE *fp, int use_real_mode, int as_text,
-            int show_absolute_syms, int show_absolute_relocs)
+            int show_absolute_syms, int show_absolute_relocs,
+            int show_reloc_info)
 {
        regex_init(use_real_mode);
        read_ehdr(fp);
@@ -1040,5 +1064,9 @@ void process(FILE *fp, int use_real_mode, int as_text,
                print_absolute_relocs();
                return;
        }
+       if (show_reloc_info) {
+               print_reloc_info();
+               return;
+       }
        emit_relocs(as_text, use_real_mode);
 }
index 07cdb1eca4fa60dcd80a06b5f032c97f786d4b36..f59590645b68641e4de9da7278b6f1c07f2e3b82 100644 (file)
@@ -29,8 +29,9 @@ enum symtype {
 };
 
 void process_32(FILE *fp, int use_real_mode, int as_text,
-               int show_absolute_syms, int show_absolute_relocs);
+               int show_absolute_syms, int show_absolute_relocs,
+               int show_reloc_info);
 void process_64(FILE *fp, int use_real_mode, int as_text,
-               int show_absolute_syms, int show_absolute_relocs);
-
+               int show_absolute_syms, int show_absolute_relocs,
+               int show_reloc_info);
 #endif /* RELOCS_H */
index 44d396823a53095ace215c49815cdb9cfa3614ed..acab636bcb348191794e0b8a4343c1874daa45a1 100644 (file)
@@ -11,12 +11,13 @@ void die(char *fmt, ...)
 
 static void usage(void)
 {
-       die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n");
+       die("relocs [--abs-syms|--abs-relocs|--reloc-info|--text|--realmode]" \
+           " vmlinux\n");
 }
 
 int main(int argc, char **argv)
 {
-       int show_absolute_syms, show_absolute_relocs;
+       int show_absolute_syms, show_absolute_relocs, show_reloc_info;
        int as_text, use_real_mode;
        const char *fname;
        FILE *fp;
@@ -25,6 +26,7 @@ int main(int argc, char **argv)
 
        show_absolute_syms = 0;
        show_absolute_relocs = 0;
+       show_reloc_info = 0;
        as_text = 0;
        use_real_mode = 0;
        fname = NULL;
@@ -39,6 +41,10 @@ int main(int argc, char **argv)
                                show_absolute_relocs = 1;
                                continue;
                        }
+                       if (strcmp(arg, "--reloc-info") == 0) {
+                               show_reloc_info = 1;
+                               continue;
+                       }
                        if (strcmp(arg, "--text") == 0) {
                                as_text = 1;
                                continue;
@@ -67,10 +73,12 @@ int main(int argc, char **argv)
        rewind(fp);
        if (e_ident[EI_CLASS] == ELFCLASS64)
                process_64(fp, use_real_mode, as_text,
-                          show_absolute_syms, show_absolute_relocs);
+                          show_absolute_syms, show_absolute_relocs,
+                          show_reloc_info);
        else
                process_32(fp, use_real_mode, as_text,
-                          show_absolute_syms, show_absolute_relocs);
+                          show_absolute_syms, show_absolute_relocs,
+                          show_reloc_info);
        fclose(fp);
        return 0;
 }