diff --git a/ctfdwdiff b/ctfdwdiff index 2a6590e..8a49a43 100755 --- a/ctfdwdiff +++ b/ctfdwdiff @@ -6,8 +6,8 @@ ctf=/tmp/$obj.ctf.c dwarf=/tmp/$obj.dwarf.c pahole -Z $obj pahole -F ctf $obj > $ctf -pahole -F dwarf $obj > $dwarf -diff -u $ctf $dwarf > $diff +pahole --flat_arrays -F dwarf $obj > $dwarf +diff -up $ctf $dwarf > $diff if [ -s $diff ] ; then # vim /tmp/$obj.diff exit 0 diff --git a/dwarves.c b/dwarves.c index 8ed9da6..8d2f5af 100644 --- a/dwarves.c +++ b/dwarves.c @@ -273,14 +273,26 @@ static size_t array_type__fprintf(const struct tag *tag_self, struct array_type *self = tag__array_type(tag_self); struct tag *type = cu__type(cu, tag_self->type); size_t printed; + unsigned long long flat_dimensions = 0; int i; if (type == NULL) return tag__id_not_found_fprintf(fp, tag_self->type); printed = type__fprintf(type, cu, name, conf, fp); - for (i = 0; i < self->dimensions; ++i) - printed += fprintf(fp, "[%u]", self->nr_entries[i]); + for (i = 0; i < self->dimensions; ++i) { + if (conf->flat_arrays) { + if (!flat_dimensions) + flat_dimensions = self->nr_entries[i]; + else + flat_dimensions *= self->nr_entries[i]; + } else + printed += fprintf(fp, "[%u]", self->nr_entries[i]); + } + + if (conf->flat_arrays) + printed += fprintf(fp, "[%llu]", flat_dimensions); + return printed; } diff --git a/dwarves.h b/dwarves.h index 627bc69..4eafd43 100644 --- a/dwarves.h +++ b/dwarves.h @@ -41,6 +41,10 @@ struct conf_load { char *format_path; }; +/** struct conf_fprintf - hints to the __fprintf routines + * + * @flat_arrays - a->foo[10][2] becomes a->foo[20] + */ struct conf_fprintf { const char *prefix; const char *suffix; @@ -58,6 +62,7 @@ struct conf_fprintf { uint8_t show_only_data_members:1; uint8_t no_semicolon:1; uint8_t show_first_biggest_size_base_type_member:1; + uint8_t flat_arrays:1; }; struct cus { diff --git a/man-pages/pahole.1 b/man-pages/pahole.1 index 7e6c36c..145d1cf 100644 --- a/man-pages/pahole.1 +++ b/man-pages/pahole.1 @@ -159,6 +159,12 @@ Show how many times struct was defined. .B \-u, \-\-defined_in Show CUs where CLASS_NAME (-C) is defined. +.TP +.B \-\-flat_arrays +Flatten arrays, so that array[10][2] becomes array[20]. +Useful when generating from both CTF and DWARF encodings +for the same binary for testing purposes. + .TP .B \-V, \-\-verbose be verbose diff --git a/pahole.c b/pahole.c index 8710f0d..b6218c8 100644 --- a/pahole.c +++ b/pahole.c @@ -703,6 +703,8 @@ static void print_containers(const struct cu *cu, uint16_t type, int ident) /* Name and version of program. */ ARGP_PROGRAM_VERSION_HOOK_DEF = dwarves_print_version; +#define ARGP_flat_arrays 300 + static const struct argp_option pahole__options[] = { { .name = "bit_holes", @@ -900,6 +902,11 @@ static const struct argp_option pahole__options[] = { .key = 'Z', .doc = "Encode as CTF", }, + { + .name = "flat_arrays", + .key = ARGP_flat_arrays, + .doc = "Flat arrays", + }, { .name = NULL, } @@ -968,9 +975,8 @@ static error_t pahole__options_parser(int key, char *arg, if (!global_verbose) formatter = class_name_formatter; break; - case 'Z': - ctf_encode = 1; - break; + case 'Z': ctf_encode = 1; break; + case ARGP_flat_arrays: conf.flat_arrays = 1; break; default: return ARGP_ERR_UNKNOWN; }