diff --git a/dtagnames.c b/dtagnames.c index 943fbd7..5ca632d 100644 --- a/dtagnames.c +++ b/dtagnames.c @@ -40,7 +40,7 @@ static void cus__dump_class_tag_names(struct cus *self) int main(int argc, char *argv[]) { - int err, remaining; + int err; struct cus *cus = cus__new(NULL, NULL); if (cus == NULL) { @@ -48,7 +48,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - err = cus__loadfl(cus, NULL, argc, argv, &remaining); + err = cus__loadfl(cus, NULL, argc, argv); if (err != 0) return EXIT_FAILURE; diff --git a/dwarves.c b/dwarves.c index d51225a..4737c8c 100644 --- a/dwarves.c +++ b/dwarves.c @@ -3425,12 +3425,68 @@ out: return err; } -int cus__loadfl(struct cus *self, struct argp *argp, int argc, char *argv[], - int *remaining) +static const struct argp_option cus__check_executable_options[] = { + { + .key = 'e', + }, + { + .key = '?', + .name = "help", + }, + { + .key = '?', + .name = "usage", + }, + { + .name = NULL, + } +}; + +static error_t cus__check_executable_parser(int key, char *arg __unused, + struct argp_state *state) +{ + if (key == 'e' || key == '?') + *(int *)state->input = 1; + + return 0; +} + +static const struct argp cus__check_executable_argp = { + .options = cus__check_executable_options, + .parser = cus__check_executable_parser, +}; + +int cus__loadfl(struct cus *self, struct argp *argp, int argc, char *argv[]) { Dwfl *dwfl = NULL; Dwarf_Die *cu_die = NULL; Dwarf_Addr dwbias; + int found_executable_option = 0; + char **new_argv = NULL; + int err = -1; + + if (argc == 1) { + argp_help(argp ? : dwfl_standard_argp(), stderr, + ARGP_HELP_SEE, argv[0]); + return -1; + } + + argp_parse(&cus__check_executable_argp, argc, argv, ARGP_SILENT, + NULL, &found_executable_option); + + if (!found_executable_option) { + new_argv = malloc((argc + 2) * sizeof(char *)); + if (new_argv == NULL) { + fprintf(stderr, "%s: not enough memory!\n", __func__); + return -1; + } + memcpy(new_argv, argv, (argc - 1) * sizeof(char *)); + new_argv[argc - 1] = "-e"; + new_argv[argc] = argv[argc - 1]; + new_argv[argc + 1] = NULL; + argv = new_argv; + argc++; + } if (argp != NULL) { const struct argp_child argp_children[] = { @@ -3438,12 +3494,12 @@ int cus__loadfl(struct cus *self, struct argp *argp, int argc, char *argv[], { .argp = NULL } }; argp->children = argp_children; - argp_parse(argp, argc, argv, 0, remaining, &dwfl); + argp_parse(argp, argc, argv, 0, NULL, &dwfl); } else - argp_parse(dwfl_standard_argp(), argc, argv, 0, remaining, &dwfl); + argp_parse(dwfl_standard_argp(), argc, argv, 0, NULL, &dwfl); if (dwfl == NULL) - return -1; + goto out; while ((cu_die = dwfl_nextcu(dwfl, cu_die, &dwbias)) != NULL) { Dwarf_Die tmp; @@ -3460,7 +3516,10 @@ int cus__loadfl(struct cus *self, struct argp *argp, int argc, char *argv[], } dwfl_end(dwfl); - return 0; + err = 0; +out: + free(new_argv); + return err; } void cus__print_error_msg(const char *progname, const char *filename, diff --git a/dwarves.h b/dwarves.h index 4c8b0dc..f8c6755 100644 --- a/dwarves.h +++ b/dwarves.h @@ -288,7 +288,7 @@ extern size_t lexblock__fprintf(const struct lexblock *self, extern struct cus *cus__new(struct list_head *definitions, struct list_head *fwd_decls); extern int cus__loadfl(struct cus *self, struct argp *argp, - int argc, char *argv[], int *remaining); + int argc, char *argv[]); extern int cus__load(struct cus *self, const char *filename); extern int cus__load_dir(struct cus *self, const char *dirname, const char *filename_mask, const int recursive); diff --git a/pahole.c b/pahole.c index 67f389e..ab9989e 100644 --- a/pahole.c +++ b/pahole.c @@ -37,6 +37,7 @@ static uint8_t expand_types; static size_t cacheline_size; static int reorganize; static int show_reorg_steps; +static char *class_name; struct structure { struct list_head node; @@ -72,9 +73,9 @@ static struct structure *structures__find(const char *name) list_for_each_entry(pos, &structures__list, node) { const struct class *c = pos->class; - const char *class_name = class__name(c); + const char *cname = class__name(c); - if (class_name == NULL) { + if (cname == NULL) { if (class__include_anonymous) { const struct tag *tdef = cu__find_first_typedef_of_type(pos->cu, @@ -82,14 +83,14 @@ static struct structure *structures__find(const char *name) if (tdef == NULL) continue; - class_name = class__name(tag__class(tdef)); - if (class_name == NULL) + cname = class__name(tag__class(tdef)); + if (cname == NULL) continue; } else continue; } - if (strcmp(class_name, name) == 0) + if (strcmp(cname, name) == 0) return pos; } @@ -416,6 +417,12 @@ static const struct argp_option pahole__options[] = { .arg = "SIZE", .doc = "set cacheline size to SIZE" }, + { + .name = "class_name", + .key = 'C', + .arg = "CLASS_NAME", + .doc = "Show just this class" + }, { .name = "holes", .key = 'H', @@ -513,6 +520,7 @@ static error_t pahole__options_parser(int key, char *arg, switch (key) { case ARGP_KEY_INIT: state->child_inputs[0] = state->input; break; case 'c': cacheline_size = atoi(arg); break; + case 'C': class_name = arg; break; case 'H': nr_holes = atoi(arg); break; case 'B': nr_bit_holes = atoi(arg); break; case 'E': expand_types = 1; break; @@ -542,7 +550,7 @@ static error_t pahole__options_parser(int key, char *arg, return 0; } -static const char pahole__args_doc[] = "-e [FILE] {[CLASS]}"; +static const char pahole__args_doc[] = "[FILE]"; static struct argp pahole__argp = { .options = pahole__options, @@ -554,8 +562,6 @@ int main(int argc, char *argv[]) { int err; struct cus *cus; - char *class_name = NULL; - int remaining; cus = cus__new(NULL, NULL); if (cus == NULL) { @@ -563,18 +569,10 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - err = cus__loadfl(cus, &pahole__argp, argc, argv, &remaining); + err = cus__loadfl(cus, &pahole__argp, argc, argv); if (err != 0) return EXIT_FAILURE; - switch (argc - remaining) { - case 0: break; - case 1: class_name = argv[remaining++]; break; - default: - argp_help(&pahole__argp, stderr, ARGP_HELP_SEE, "pahole"); - return EXIT_FAILURE; - } - dwarves__init(cacheline_size); cus__for_each_cu(cus, cu_unique_iterator, NULL, cu__filter); diff --git a/pdwtags.c b/pdwtags.c index 53f0099..b8f0bae 100644 --- a/pdwtags.c +++ b/pdwtags.c @@ -51,7 +51,7 @@ static void cus__emit_tags(struct cus *self) int main(int argc, char *argv[]) { - int err, remaining; + int err; struct cus *cus = cus__new(NULL, NULL); if (cus == NULL) { @@ -59,7 +59,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - err = cus__loadfl(cus, NULL, argc, argv, &remaining); + err = cus__loadfl(cus, NULL, argc, argv); if (err != 0) return EXIT_FAILURE; diff --git a/pfunct.c b/pfunct.c index 20e4826..6a84be2 100644 --- a/pfunct.c +++ b/pfunct.c @@ -329,6 +329,12 @@ static const struct argp_option pfunct__options[] = { .name = "externals", .doc = "show just external functions", }, + { + .key = 'f', + .name = "function", + .arg = "FUNCTION", + .doc = "show just FUNCTION", + }, { .key = 'g', .name = "goto_labels", @@ -405,6 +411,7 @@ static error_t pfunct__options_parser(int key, char *arg, switch (key) { case ARGP_KEY_INIT: state->child_inputs[0] = state->input; break; case 'c': class_name = arg; break; + case 'f': function_name = arg; break; case 'E': show_externals = 1; break; case 's': formatter = fn_stats_size_fmtr; break; case 'S': formatter = fn_stats_variables_fmtr; break; @@ -434,7 +441,7 @@ static struct argp pfunct__argp = { int main(int argc, char *argv[]) { - int remaining, err; + int err; struct cus *cus = cus__new(NULL, NULL); if (cus == NULL) { @@ -442,17 +449,10 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - err = cus__loadfl(cus, &pfunct__argp, argc, argv, &remaining); + err = cus__loadfl(cus, &pfunct__argp, argc, argv); if (err != 0) return EXIT_FAILURE; - switch (argc - remaining) { - case 0: break; - case 1: function_name = argv[remaining++]; break; - default: argp_help(&pfunct__argp, stderr, ARGP_HELP_SEE, "pfunct"); - return EXIT_FAILURE; - } - dwarves__init(0); cus__for_each_cu(cus, cu_unique_iterator, NULL, NULL); diff --git a/pglobal.c b/pglobal.c index 86ceb71..b9c9730 100644 --- a/pglobal.c +++ b/pglobal.c @@ -309,7 +309,7 @@ static struct argp pglobal__argp = { int main(int argc, char *argv[]) { - int remaining, err; + int err; struct cus *cus = cus__new(NULL, NULL); if (cus == NULL) { @@ -317,7 +317,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - err = cus__loadfl(cus, &pglobal__argp, argc, argv, &remaining); + err = cus__loadfl(cus, &pglobal__argp, argc, argv); if (err != 0) return EXIT_FAILURE; diff --git a/prefcnt.c b/prefcnt.c index f0362dd..2e2f81d 100644 --- a/prefcnt.c +++ b/prefcnt.c @@ -140,7 +140,7 @@ static int cu_lost_iterator(struct cu *cu, void *cookie) int main(int argc, char *argv[]) { - int err, remaining; + int err; struct cus *cus = cus__new(NULL, NULL); if (cus == NULL) { @@ -148,7 +148,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - err = cus__loadfl(cus, NULL, argc, argv, &remaining); + err = cus__loadfl(cus, NULL, argc, argv); if (err != 0) return EXIT_FAILURE;