diff options
author | Peter Zijlstra <peterz@infradead.org> | 2020-03-12 11:26:29 +0300 |
---|---|---|
committer | Peter Zijlstra <peterz@infradead.org> | 2020-03-25 20:28:28 +0300 |
commit | 1e11f3fdc326d7466e43185ea943b6156143387c (patch) | |
tree | 5a4ee402d9becc5691eef8b30cde9aff8fc31d0b /tools/objtool | |
parent | 65fb11a7f6aeae678043738d06248a4e21f4e4e4 (diff) | |
download | linux-1e11f3fdc326d7466e43185ea943b6156143387c.tar.xz |
objtool: Add a statistics mode
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
Diffstat (limited to 'tools/objtool')
-rw-r--r-- | tools/objtool/builtin-check.c | 3 | ||||
-rw-r--r-- | tools/objtool/builtin.h | 2 | ||||
-rw-r--r-- | tools/objtool/check.c | 5 | ||||
-rw-r--r-- | tools/objtool/elf.c | 18 |
4 files changed, 25 insertions, 3 deletions
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index c807984a03c1..10fbe75ab43d 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -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(), }; diff --git a/tools/objtool/builtin.h b/tools/objtool/builtin.h index a32736f8d2a4..0b907902ee79 100644 --- a/tools/objtool/builtin.h +++ b/tools/objtool/builtin.h @@ -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); diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 43f7d3c2e8b2..6df1bae2f961 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -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: diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index b188b3e075be..ff293064b469 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -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; |