[PFUNCT]: Implement --externals
That uses the DW_AT_external attribute, that tells if the DW_TAG_subprogram (a function) is visible externally. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
This commit is contained in:
parent
84a05e88e1
commit
47845f0f9b
12
classes.c
12
classes.c
|
@ -406,7 +406,7 @@ static struct class *class__new(const unsigned int tag,
|
|||
uint64_t cu_offset, uint64_t type,
|
||||
const char *name, uint64_t size,
|
||||
const char *decl_file, unsigned int decl_line,
|
||||
unsigned short inlined,
|
||||
unsigned short inlined, char external,
|
||||
uint64_t low_pc, uint64_t high_pc)
|
||||
{
|
||||
struct class *self = malloc(sizeof(*self));
|
||||
|
@ -432,6 +432,7 @@ static struct class *class__new(const unsigned int tag,
|
|||
self->nr_inline_expansions = 0;
|
||||
self->size_inline_expansions = 0;
|
||||
self->inlined = inlined;
|
||||
self->external = external;
|
||||
self->low_pc = low_pc;
|
||||
self->high_pc = high_pc;
|
||||
self->cu_total_nr_inline_expansions = 0;
|
||||
|
@ -961,6 +962,7 @@ static void cu__process_die(Dwarf *dwarf, Dwarf_Die *die)
|
|||
} else {
|
||||
uint64_t size = attr_numeric(die, DW_AT_byte_size);
|
||||
const unsigned short inlined = attr_numeric(die, DW_AT_inline);
|
||||
const char external = dwarf_hasattr(die, DW_AT_external);
|
||||
Dwarf_Addr high_pc, low_pc;
|
||||
if (dwarf_highpc(die, &high_pc)) high_pc = 0;
|
||||
if (dwarf_lowpc(die, &low_pc)) low_pc = 0;
|
||||
|
@ -972,10 +974,10 @@ static void cu__process_die(Dwarf *dwarf, Dwarf_Die *die)
|
|||
if (cu__current_class != NULL)
|
||||
cu__add_class(current_cu, cu__current_class);
|
||||
|
||||
cu__current_class = class__new(tag, cu_offset,
|
||||
type, name, size,
|
||||
decl_file, decl_line,
|
||||
inlined, low_pc, high_pc);
|
||||
cu__current_class = class__new(tag, cu_offset, type, name,
|
||||
size, decl_file, decl_line,
|
||||
inlined, external,
|
||||
low_pc, high_pc);
|
||||
if (cu__current_class == NULL)
|
||||
oom("class__new");
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ struct class {
|
|||
unsigned short padding;
|
||||
unsigned short inlined;
|
||||
unsigned short nr_inline_expansions;
|
||||
unsigned char external:1;
|
||||
unsigned int refcnt;
|
||||
unsigned int size_inline_expansions;
|
||||
signed int diff;
|
||||
|
|
21
pfunct.c
21
pfunct.c
|
@ -88,6 +88,7 @@ static void print_total_inline_stats(void)
|
|||
|
||||
static struct option long_options[] = {
|
||||
{ "class", required_argument, NULL, 'c' },
|
||||
{ "externals", no_argument, NULL, 'e' },
|
||||
{ "cu_inline_expansions_stats", no_argument, NULL, 'C' },
|
||||
{ "function_name_len", no_argument, NULL, 'N' },
|
||||
{ "goto_labels", no_argument, NULL, 'g' },
|
||||
|
@ -110,6 +111,7 @@ static void usage(void)
|
|||
" where: \n"
|
||||
" -c, --class=<class> functions that have <class> "
|
||||
"pointer parameters\n"
|
||||
" -e, --externals show just external functions\n"
|
||||
" -g, --goto_labels show number of goto labels\n"
|
||||
" -i, --inline_expansions show inline expansions\n"
|
||||
" -I, --inline_expansions_stats show inline expansions stats\n"
|
||||
|
@ -180,6 +182,19 @@ static int cu_sizes_iterator(struct cu *cu, void *cookie)
|
|||
return cu__for_each_class(cu, sizes_iterator, cookie);
|
||||
}
|
||||
|
||||
static int externals_iterator(struct class *class, void *cookie)
|
||||
{
|
||||
if (class->tag == DW_TAG_subprogram && !class->inlined && class->external)
|
||||
puts(class->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cu_externals_iterator(struct cu *cu, void *cookie)
|
||||
{
|
||||
return cu__for_each_class(cu, externals_iterator, cookie);
|
||||
}
|
||||
|
||||
static int variables_iterator(struct class *class, void *cookie)
|
||||
{
|
||||
if (class->tag != DW_TAG_subprogram || class->inlined)
|
||||
|
@ -311,6 +326,7 @@ int main(int argc, char *argv[])
|
|||
struct cus *cus;
|
||||
char *class_name = NULL;
|
||||
char *function_name = NULL;
|
||||
int show_externals = 0;
|
||||
int show_sizes = 0;
|
||||
int show_nr_variables = 0;
|
||||
int show_goto_labels = 0;
|
||||
|
@ -320,11 +336,12 @@ int main(int argc, char *argv[])
|
|||
int show_inline_stats = 0;
|
||||
int show_total_inline_expansion_stats = 0;
|
||||
|
||||
while ((option = getopt_long(argc, argv, "c:CgiINpsStTV",
|
||||
while ((option = getopt_long(argc, argv, "c:CegiINpsStTV",
|
||||
long_options, &option_index)) >= 0)
|
||||
switch (option) {
|
||||
case 'c': class_name = optarg; break;
|
||||
case 'C': show_inline_stats = 1; break;
|
||||
case 'e': show_externals = 1; break;
|
||||
case 's': show_sizes = 1; break;
|
||||
case 'S': show_nr_variables = 1; break;
|
||||
case 'p': show_nr_parameters = 1; break;
|
||||
|
@ -376,6 +393,8 @@ int main(int argc, char *argv[])
|
|||
cus__for_each_cu(cus, cu_goto_labels_iterator, NULL);
|
||||
else if (show_sizes)
|
||||
cus__for_each_cu(cus, cu_sizes_iterator, NULL);
|
||||
else if (show_externals)
|
||||
cus__for_each_cu(cus, cu_externals_iterator, NULL);
|
||||
else if (show_function_name_len)
|
||||
cus__for_each_cu(cus, cu_function_name_len_iterator, NULL);
|
||||
else if (class_name != NULL)
|
||||
|
|
Loading…
Reference in New Issue