[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:
Arnaldo Carvalho de Melo 2006-11-17 23:43:08 -02:00
parent 84a05e88e1
commit 47845f0f9b
3 changed files with 28 additions and 6 deletions

View File

@ -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");
}

View File

@ -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;

View File

@ -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)