objtool: Add a statistics mode
authorPeter Zijlstra <peterz@infradead.org>
Thu, 12 Mar 2020 08:26:29 +0000 (09:26 +0100)
committerPeter Zijlstra <peterz@infradead.org>
Wed, 25 Mar 2020 17:28:28 +0000 (18:28 +0100)
Have it print a few numbers which can be used to size the hashtables.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Acked-by: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lkml.kernel.org/r/20200324160924.321381240@infradead.org
tools/objtool/builtin-check.c
tools/objtool/builtin.h
tools/objtool/check.c
tools/objtool/elf.c

index c807984..10fbe75 100644 (file)
@@ -17,7 +17,7 @@
 #include "builtin.h"
 #include "check.h"
 
-bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess;
+bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats;
 
 static const char * const check_usage[] = {
        "objtool check [<options>] file.o",
@@ -31,6 +31,7 @@ const struct option check_options[] = {
        OPT_BOOLEAN('m', "module", &module, "Indicates the object will be part of a kernel module"),
        OPT_BOOLEAN('b', "backtrace", &backtrace, "unwind on error"),
        OPT_BOOLEAN('a', "uaccess", &uaccess, "enable uaccess checking"),
+       OPT_BOOLEAN('s', "stats", &stats, "print statistics"),
        OPT_END(),
 };
 
index a32736f..0b90790 100644 (file)
@@ -8,7 +8,7 @@
 #include <subcmd/parse-options.h>
 
 extern const struct option check_options[];
-extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess;
+extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats;
 
 extern int cmd_check(int argc, const char **argv);
 extern int cmd_orc(int argc, const char **argv);
index 43f7d3c..6df1bae 100644 (file)
@@ -239,6 +239,7 @@ static int decode_instructions(struct objtool_file *file)
        struct symbol *func;
        unsigned long offset;
        struct instruction *insn;
+       unsigned long nr_insns = 0;
        int ret;
 
        for_each_sec(file, sec) {
@@ -274,6 +275,7 @@ static int decode_instructions(struct objtool_file *file)
 
                        hash_add(file->insn_hash, &insn->hash, insn->offset);
                        list_add_tail(&insn->list, &file->insn_list);
+                       nr_insns++;
                }
 
                list_for_each_entry(func, &sec->symbol_list, list) {
@@ -291,6 +293,9 @@ static int decode_instructions(struct objtool_file *file)
                }
        }
 
+       if (stats)
+               printf("nr_insns: %lu\n", nr_insns);
+
        return 0;
 
 err:
index b188b3e..ff29306 100644 (file)
@@ -15,6 +15,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
+#include "builtin.h"
 
 #include "elf.h"
 #include "warn.h"
@@ -202,6 +203,9 @@ static int read_sections(struct elf *elf)
                sec->len = sec->sh.sh_size;
        }
 
+       if (stats)
+               printf("nr_sections: %lu\n", (unsigned long)sections_nr);
+
        /* sanity check, one more call to elf_nextscn() should return NULL */
        if (elf_nextscn(elf->elf, s)) {
                WARN("section entry mismatch");
@@ -299,6 +303,9 @@ static int read_symbols(struct elf *elf)
                hash_add(elf->symbol_hash, &sym->hash, sym->idx);
        }
 
+       if (stats)
+               printf("nr_symbols: %lu\n", (unsigned long)symbols_nr);
+
        /* Create parent/child links for any cold subfunctions */
        list_for_each_entry(sec, &elf->sections, list) {
                list_for_each_entry(sym, &sec->symbol_list, list) {
@@ -360,6 +367,7 @@ static int read_relas(struct elf *elf)
        struct rela *rela;
        int i;
        unsigned int symndx;
+       unsigned long nr_rela, max_rela = 0, tot_rela = 0;
 
        list_for_each_entry(sec, &elf->sections, list) {
                if (sec->sh.sh_type != SHT_RELA)
@@ -374,6 +382,7 @@ static int read_relas(struct elf *elf)
 
                sec->base->rela = sec;
 
+               nr_rela = 0;
                for (i = 0; i < sec->sh.sh_size / sec->sh.sh_entsize; i++) {
                        rela = malloc(sizeof(*rela));
                        if (!rela) {
@@ -401,8 +410,15 @@ static int read_relas(struct elf *elf)
 
                        list_add_tail(&rela->list, &sec->rela_list);
                        hash_add(sec->rela_hash, &rela->hash, rela->offset);
-
+                       nr_rela++;
                }
+               max_rela = max(max_rela, nr_rela);
+               tot_rela += nr_rela;
+       }
+
+       if (stats) {
+               printf("max_rela: %lu\n", max_rela);
+               printf("tot_rela: %lu\n", tot_rela);
        }
 
        return 0;