[LIB]: Add conf->expand_pointers
So that we can expand pointer types, useful for ABI signature checking. And to fully browse a type, when using --expand_types is also of interest. I have yet to disable printing the offsets when expanding pointers, where the information is not useful at all, for now just ignore it, it gets back to a sane state in the next field, after the pointer type expansion. Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
This commit is contained in:
parent
ad5390df84
commit
d653039ef4
48
dwarves.c
48
dwarves.c
|
@ -299,6 +299,7 @@ static void tag__init(struct tag *self, Dwarf_Die *die)
|
|||
self->decl_file = strings__add(dwarf_decl_file(die));
|
||||
dwarf_decl_line(die, &decl_line);
|
||||
self->decl_line = decl_line;
|
||||
self->recursivity_level = 0;
|
||||
}
|
||||
|
||||
static struct tag *tag__new(Dwarf_Die *die)
|
||||
|
@ -1276,14 +1277,44 @@ static size_t type__fprintf(struct tag *type, const struct cu *cu,
|
|||
FILE *fp)
|
||||
{
|
||||
char tbf[128];
|
||||
char namebf[256];
|
||||
struct type *ctype;
|
||||
struct conf_fprintf tconf;
|
||||
size_t printed = 0;
|
||||
int expand_types = conf->expand_types;
|
||||
|
||||
if (type == NULL)
|
||||
goto out_type_not_found;
|
||||
|
||||
if (conf->expand_types) {
|
||||
if (conf->expand_pointers) {
|
||||
int nr_indirections = 0;
|
||||
|
||||
while (type->tag == DW_TAG_pointer_type && type->type != 0) {
|
||||
type = cu__find_tag_by_id(cu, type->type);
|
||||
if (type == NULL)
|
||||
goto out_type_not_found;
|
||||
++nr_indirections;
|
||||
}
|
||||
|
||||
if (nr_indirections > 0) {
|
||||
const size_t len = strlen(name);
|
||||
if (len + nr_indirections >= sizeof(namebf))
|
||||
goto out_type_not_found;
|
||||
memset(namebf, '*', nr_indirections);
|
||||
memcpy(namebf + nr_indirections, name, len);
|
||||
namebf[len + nr_indirections] = '\0';
|
||||
name = namebf;
|
||||
}
|
||||
|
||||
expand_types = nr_indirections;
|
||||
|
||||
/* Avoid loops */
|
||||
if (type->recursivity_level != 0)
|
||||
expand_types = 0;
|
||||
++type->recursivity_level;
|
||||
}
|
||||
|
||||
if (expand_types) {
|
||||
int typedef_expanded = 0;
|
||||
|
||||
while (type->tag == DW_TAG_typedef) {
|
||||
|
@ -1342,7 +1373,7 @@ static size_t type__fprintf(struct tag *type, const struct cu *cu,
|
|||
case DW_TAG_structure_type:
|
||||
ctype = tag__type(type);
|
||||
|
||||
if (type__name(ctype, cu) != NULL && !conf->expand_types)
|
||||
if (type__name(ctype, cu) != NULL && !expand_types)
|
||||
printed += fprintf(fp, "struct %-*s %s",
|
||||
conf->type_spacing - 7,
|
||||
type__name(ctype, cu), name);
|
||||
|
@ -1353,7 +1384,7 @@ static size_t type__fprintf(struct tag *type, const struct cu *cu,
|
|||
case DW_TAG_union_type:
|
||||
ctype = tag__type(type);
|
||||
|
||||
if (type__name(ctype, cu) != NULL && !conf->expand_types)
|
||||
if (type__name(ctype, cu) != NULL && !expand_types)
|
||||
printed += fprintf(fp, "union %-*s %s",
|
||||
conf->type_spacing - 6,
|
||||
type__name(ctype, cu), name);
|
||||
|
@ -1372,6 +1403,9 @@ static size_t type__fprintf(struct tag *type, const struct cu *cu,
|
|||
break;
|
||||
}
|
||||
out:
|
||||
if (conf->expand_types)
|
||||
--type->recursivity_level;
|
||||
|
||||
return printed;
|
||||
out_type_not_found:
|
||||
printed = fprintf(fp, "%-*s %s", conf->type_spacing, "<ERROR>", name);
|
||||
|
@ -2458,7 +2492,7 @@ static size_t namespace__fprintf(const struct tag *tself, const struct cu *cu,
|
|||
return printed + fprintf(fp, "}");
|
||||
}
|
||||
|
||||
size_t tag__fprintf(const struct tag *self, const struct cu *cu,
|
||||
size_t tag__fprintf(struct tag *self, const struct cu *cu,
|
||||
const struct conf_fprintf *conf, FILE *fp)
|
||||
{
|
||||
size_t printed = 0;
|
||||
|
@ -2488,6 +2522,9 @@ size_t tag__fprintf(const struct tag *self, const struct cu *cu,
|
|||
tconf.type_spacing = 26;
|
||||
}
|
||||
|
||||
if (pconf->expand_types)
|
||||
++self->recursivity_level;
|
||||
|
||||
if (pconf->show_decl_info) {
|
||||
printed += fprintf(fp, "%.*s", pconf->indent, tabs);
|
||||
printed += tag__fprintf_decl_info(self, fp);
|
||||
|
@ -2533,6 +2570,9 @@ size_t tag__fprintf(const struct tag *self, const struct cu *cu,
|
|||
++printed;
|
||||
}
|
||||
|
||||
if (pconf->expand_types)
|
||||
--self->recursivity_level;
|
||||
|
||||
return printed;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,8 @@ struct tag {
|
|||
const char *decl_file;
|
||||
uint16_t decl_line;
|
||||
uint16_t tag;
|
||||
uint32_t refcnt;
|
||||
uint16_t refcnt;
|
||||
uint16_t recursivity_level;
|
||||
};
|
||||
|
||||
static inline int tag__is_enumeration(const struct tag *self)
|
||||
|
@ -410,6 +411,7 @@ struct conf_fprintf {
|
|||
uint32_t base_offset;
|
||||
uint8_t indent;
|
||||
uint8_t expand_types:1;
|
||||
uint8_t expand_pointers:1;
|
||||
uint8_t rel_offset:1;
|
||||
uint8_t emit_stats:1;
|
||||
uint8_t suppress_comments:1;
|
||||
|
@ -430,7 +432,7 @@ extern size_t enumeration__fprintf(const struct tag *tag_self,
|
|||
extern size_t typedef__fprintf(const struct tag *tag_self, const struct cu *cu,
|
||||
const struct conf_fprintf *conf, FILE *fp);
|
||||
extern size_t tag__fprintf_decl_info(const struct tag *self, FILE *fp);
|
||||
extern size_t tag__fprintf(const struct tag *self, const struct cu *cu,
|
||||
extern size_t tag__fprintf(struct tag *self, const struct cu *cu,
|
||||
const struct conf_fprintf *conf, FILE *fp);
|
||||
|
||||
extern const char *function__name(struct function *self, const struct cu *cu);
|
||||
|
|
6
pahole.c
6
pahole.c
|
@ -548,6 +548,11 @@ static const struct argp_option pahole__options[] = {
|
|||
.key = 'M',
|
||||
.doc = "show only the members that use space in the class layout",
|
||||
},
|
||||
{
|
||||
.name = "expand_pointers",
|
||||
.key = 'p',
|
||||
.doc = "expand class pointer members",
|
||||
},
|
||||
{
|
||||
.name = "sizes",
|
||||
.key = 's',
|
||||
|
@ -634,6 +639,7 @@ static error_t pahole__options_parser(int key, char *arg,
|
|||
break;
|
||||
case 'B': nr_bit_holes = atoi(arg); break;
|
||||
case 'E': conf.expand_types = 1; break;
|
||||
case 'p': conf.expand_pointers = 1; break;
|
||||
case 'r': conf.rel_offset = 1; break;
|
||||
case 'R': reorganize = 1; break;
|
||||
case 'S': show_reorg_steps = 1; break;
|
||||
|
|
Loading…
Reference in New Issue