dwarves/dwarves.h

821 lines
23 KiB
C
Raw Normal View History

#ifndef _DWARVES_H_
#define _DWARVES_H_ 1
/*
Copyright (C) 2006 Mandriva Conectiva S.A.
Copyright (C) 2006 Arnaldo Carvalho de Melo <acme@mandriva.com>
This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation.
*/
#include <stdint.h>
#include <stdio.h>
#include <dwarf.h>
#include <elfutils/libdw.h>
#include "dutil.h"
#include "list.h"
#include "strings.h"
extern struct strings *strings;
struct cus {
struct list_head cus;
};
struct cus *cus__new(void);
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
struct ptr_table {
void **entries;
uint32_t nr_entries;
uint32_t allocated_entries;
};
/**
* cu__for_each_type - iterate thru all the type tags
* @cu: struct cu instance to iterate
* @pos: struct tag iterator
* @id: uint16_t tag id
*
* See cu__table_nullify_type_entry and users for the reason for
* the NULL test (hint: CTF Unknown types)
*/
#define cu__for_each_type(cu, id, pos) \
for (id = 1, pos = cu->types_table.entries[id]; \
id < cu->types_table.nr_entries; \
pos = cu->types_table.entries[++id]) \
if (pos == NULL) \
continue; \
else
/**
* cu__for_each_struct - iterate thru all the struct tags
* @cu: struct cu instance to iterate
* @pos: struct class iterator
* @id: uint16_t tag id
*/
#define cu__for_each_struct(cu, id, pos) \
for (id = 0, pos = tag__class(cu->types_table.entries[id]); \
id < cu->types_table.nr_entries; \
pos = tag__class(cu->types_table.entries[++id])) \
if (pos == NULL || \
!tag__is_struct(class__tag(pos))) \
continue; \
else
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
/**
* cu__for_each_function - iterate thru all the function tags
* @cu: struct cu instance to iterate
* @pos: struct function iterator
* @id: uint32_t tag id
*/
#define cu__for_each_function(cu, id, pos) \
for (id = 0, pos = tag__function(cu->tags_table.entries[id]); \
id < cu->tags_table.nr_entries; \
pos = tag__function(cu->tags_table.entries[++id])) \
if (pos == NULL || \
pos->proto.tag.tag != DW_TAG_subprogram) \
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
continue; \
else
struct tag;
struct cu;
struct cu_orig_info {
const char *(*tag__decl_file)(const struct tag *self,
const struct cu *cu);
uint32_t (*tag__decl_line)(const struct tag *self,
const struct cu *cu);
unsigned long long (*tag__orig_id)(const struct tag *self,
const struct cu *cu);
unsigned long long (*tag__orig_type)(const struct tag *self,
const struct cu *cu);
};
struct cu {
struct list_head node;
struct list_head tags;
struct list_head tool_list; /* To be used by tools such as ctracer */
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
struct ptr_table types_table;
struct ptr_table tags_table;
char *name;
void *priv;
struct cu_orig_info *orig_info;
uint8_t addr_size;
uint16_t language;
unsigned long nr_inline_expansions;
size_t size_inline_expansions;
uint32_t nr_functions_changed;
uint32_t nr_structures_changed;
size_t max_len_changed_item;
size_t function_bytes_added;
size_t function_bytes_removed;
int build_id_len;
unsigned char build_id[0];
};
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
/** struct tag - basic representation of a debug info element
* @priv - extra data, for instance, DWARF offset, id, decl_{file,line}
* @top_level -
*/
struct tag {
struct list_head node;
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
uint16_t type;
[LIB]: Reorganize struct tag Erm, eating my dog food now that I have access to a 64bit machine here at home: [acme@mica pahole]$ pahole build/libdwarves.so.1.0.0 tag /* <b7e> /home/acme/git/pahole/dwarves.h:48 */ struct tag { struct list_head node; /* 0 16 */ Dwarf_Off type; /* 16 8 */ Dwarf_Off id; /* 24 8 */ uint16_t tag; /* 32 2 */ uint16_t decl_line; /* 34 2 */ /* XXX 4 bytes hole, try to pack */ const char * decl_file; /* 40 8 */ uint32_t refcnt; /* 48 4 */ }; /* size: 56, cachelines: 1 */ /* sum members: 48, holes: 1, sum holes: 4 */ /* padding: 4 */ /* last cacheline: 56 bytes */ [acme@mica pahole]$ [acme@mica pahole]$ pahole --reorganize build/libdwarves.so.1.0.0 tag /* <b7e> /home/acme/git/pahole/dwarves.h:48 */ struct tag { struct list_head node; /* 0 16 */ Dwarf_Off type; /* 16 8 */ Dwarf_Off id; /* 24 8 */ uint16_t tag; /* 32 2 */ uint16_t decl_line; /* 34 2 */ uint32_t refcnt; /* 36 4 */ const char * decl_file; /* 40 8 */ }; /* size: 48, cachelines: 1 */ /* last cacheline: 48 bytes */ /* saved 8 bytes! */ [acme@mica pahole]$ [acme@mica pahole]$ codiff build/libdwarves.so.1.0.0.before build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct tag | -8 struct type | -8 struct class | -8 struct base_type | -8 struct array_type | -8 struct class_member | -8 struct lexblock | -8 struct ftype | -8 struct function | -16 struct parameter | -8 struct variable | -8 struct inline_expansion | -8 struct label | -8 struct enumerator | -8 14 structs changed class_member__clone | -8 class__clone | -8 2 functions changed, 16 bytes removed [acme@mica pahole]$ Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-03-07 16:10:56 +01:00
uint16_t tag;
uint16_t visited:1;
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
uint16_t top_level:1;
uint16_t recursivity_level;
void *priv;
};
static inline int tag__is_enumeration(const struct tag *self)
{
return self->tag == DW_TAG_enumeration_type;
}
static inline int tag__is_namespace(const struct tag *self)
{
return self->tag == DW_TAG_namespace;
}
static inline int tag__is_struct(const struct tag *self)
{
return self->tag == DW_TAG_structure_type ||
self->tag == DW_TAG_class_type;
}
static inline int tag__is_typedef(const struct tag *self)
{
return self->tag == DW_TAG_typedef;
}
static inline int tag__is_union(const struct tag *self)
{
return self->tag == DW_TAG_union_type;
}
static inline bool tag__has_namespace(const struct tag *self)
{
return tag__is_struct(self) ||
tag__is_union(self) ||
tag__is_namespace(self) ||
tag__is_enumeration(self);
}
/**
* tag__is_tag_type - is this tag derived from the 'type' class?
* @tag - tag queried
*/
static inline int tag__is_type(const struct tag *self)
{
return tag__is_union(self) ||
tag__is_struct(self) ||
tag__is_typedef(self) ||
tag__is_enumeration(self);
}
/**
* tag__is_tag_type - is this one of the possible types for a tag?
* @tag - tag queried
*/
static inline int tag__is_tag_type(const struct tag *self)
{
return tag__is_type(self) ||
tag__is_enumeration(self) ||
self->tag == DW_TAG_array_type ||
self->tag == DW_TAG_base_type ||
self->tag == DW_TAG_const_type ||
self->tag == DW_TAG_pointer_type ||
self->tag == DW_TAG_ptr_to_member_type ||
self->tag == DW_TAG_reference_type ||
self->tag == DW_TAG_subroutine_type ||
self->tag == DW_TAG_volatile_type;
}
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
static inline const char *tag__decl_file(const struct tag *self,
const struct cu *cu)
{
return cu->orig_info ? cu->orig_info->tag__decl_file(self, cu) : NULL;
}
static inline uint32_t tag__decl_line(const struct tag *self,
const struct cu *cu)
{
return cu->orig_info ? cu->orig_info->tag__decl_line(self, cu) : 0;
}
static inline unsigned long long tag__orig_id(const struct tag *self,
const struct cu *cu)
{
return cu->orig_info ? cu->orig_info->tag__orig_id(self, cu) : 0;
}
static inline unsigned long long tag__orig_type(const struct tag *self,
const struct cu *cu)
{
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
return cu->orig_info ? cu->orig_info->tag__orig_type(self, cu) : 0;
}
struct ptr_to_member_type {
struct tag tag;
Dwarf_Off containing_type;
};
static inline struct ptr_to_member_type *
tag__ptr_to_member_type(const struct tag *self)
{
return (struct ptr_to_member_type *)self;
}
struct namespace {
struct tag tag;
strings_t name;
uint16_t nr_tags;
struct list_head tags;
};
static inline struct namespace *tag__namespace(const struct tag *self)
{
return (struct namespace *)self;
}
/**
* namespace__for_each_tag - iterate thru all the tags
* @self: struct namespace instance to iterate
* @pos: struct tag iterator
*/
#define namespace__for_each_tag(self, pos) \
list_for_each_entry(pos, &(self)->tags, node)
/**
* namespace__for_each_tag_safe - safely iterate thru all the tags
* @self: struct namespace instance to iterate
* @pos: struct tag iterator
* @n: struct class_member temp iterator
*/
#define namespace__for_each_tag_safe(self, pos, n) \
list_for_each_entry_safe(pos, n, &(self)->tags, node)
/**
* struct type - base type for enumerations, structs and unions
*
* @nr_members: number of DW_TAG_member entries
* @nr_tags: number of tags
*/
struct type {
struct namespace namespace;
struct list_head node;
Dwarf_Off specification;
size_t size;
[PAHOLE]: Allow changing the architecture word-size Using a x86_64 binary: [acme@doppio pahole]$ build/pahole -C restart_block /usr/lib/debug/lib/modules/2.6.21-65.el5rt/kernel/drivers/net/e1000/e1000.ko.debug struct restart_block { long int (*fn)(struct restart_block *); /* 0 8 */ union { struct { long unsigned int arg0; /* 8 8 */ long unsigned int arg1; /* 16 8 */ long unsigned int arg2; /* 24 8 */ long unsigned int arg3; /* 32 8 */ }; /* 32 */ struct { u32 * uaddr; /* 8 8 */ u32 val; /* 16 4 */ u32 flags; /* 20 4 */ u64 time; /* 24 8 */ } fu; /* 24 */ }; /* 8 32 */ /* size: 40, cachelines: 1 */ /* last cacheline: 40 bytes */ }; Changing the word-size from 8 to 4 bytes: [acme@doppio pahole]$ build/pahole -w 4 -C restart_block /usr/lib/debug/lib/modules/2.6.21-65.el5rt/kernel/drivers/net/e1000/e1000.ko.debug struct restart_block { long int (*fn)(struct restart_block *); /* 0 4 */ union { struct { long unsigned int arg0; /* 4 4 */ long unsigned int arg1; /* 8 4 */ long unsigned int arg2; /* 12 4 */ long unsigned int arg3; /* 16 4 */ }; /* 16 */ struct { u32 * uaddr; /* 4 4 */ u32 val; /* 8 4 */ u32 flags; /* 12 4 */ u64 time; /* 16 8 */ } fu; /* 20 */ }; /* 4 20 */ /* size: 24, cachelines: 1 */ /* last cacheline: 24 bytes */ }; And from 8 to 16: [acme@doppio pahole]$ build/pahole -w 16 -C restart_block /usr/lib/debug/lib/modules/2.6.21-65.el5rt/kernel/drivers/net/e1000/e1000.ko.debug struct restart_block { long int (*fn)(struct restart_block *); /* 0 16 */ union { struct { long unsigned int arg0; /* 16 16 */ long unsigned int arg1; /* 32 16 */ long unsigned int arg2; /* 48 16 */ long unsigned int arg3; /* 64 16 */ /* --- cacheline 1 boundary (64 bytes) --- */ }; /* 64 */ struct { u32 * uaddr; /* 16 16 */ u32 val; /* 32 4 */ u32 flags; /* 36 4 */ u64 time; /* 40 8 */ } fu; /* 32 */ }; /* 16 64 */ /* --- cacheline 1 boundary (64 bytes) was 16 bytes ago --- */ /* size: 80, cachelines: 2 */ /* last cacheline: 16 bytes */ }; More work is required to specify different alignment rules. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-01-12 16:14:40 +01:00
size_t size_diff;
uint16_t nr_members;
uint8_t declaration; /* only one bit used */
uint8_t definition_emitted:1;
uint8_t fwd_decl_emitted:1;
uint8_t resized:1;
};
static inline struct class *type__class(const struct type *self)
{
return (struct class *)self;
}
/**
* type__for_each_tag - iterate thru all the tags
* @self: struct type instance to iterate
* @pos: struct tag iterator
*/
#define type__for_each_tag(self, pos) \
list_for_each_entry(pos, &(self)->namespace.tags, node)
/**
* type__for_each_enumerator - iterate thru the enumerator entries
* @self: struct type instance to iterate
* @pos: struct enumerator iterator
*/
#define type__for_each_enumerator(self, pos) \
list_for_each_entry(pos, &(self)->namespace.tags, tag.node)
/**
* type__for_each_member - iterate thru the entries that use space
* (data members and inheritance entries)
* @self: struct type instance to iterate
* @pos: struct class_member iterator
*/
#define type__for_each_member(self, pos) \
list_for_each_entry(pos, &(self)->namespace.tags, tag.node) \
if (!(pos->tag.tag == DW_TAG_member || \
pos->tag.tag == DW_TAG_inheritance)) \
continue; \
else
/**
* type__for_each_data_member - iterate thru the data member entries
* @self: struct type instance to iterate
* @pos: struct class_member iterator
*/
#define type__for_each_data_member(self, pos) \
list_for_each_entry(pos, &(self)->namespace.tags, tag.node) \
if (pos->tag.tag != DW_TAG_member) \
continue; \
else
/**
* type__for_each_member_safe - safely iterate thru the entries that use space
* (data members and inheritance entries)
* @self: struct type instance to iterate
* @pos: struct class_member iterator
* @n: struct class_member temp iterator
*/
#define type__for_each_member_safe(self, pos, n) \
list_for_each_entry_safe(pos, n, &(self)->namespace.tags, tag.node) \
if (pos->tag.tag != DW_TAG_member) \
continue; \
else
/**
* type__for_each_data_member_safe - safely iterate thru the data member entries
* @self: struct type instance to iterate
* @pos: struct class_member iterator
* @n: struct class_member temp iterator
*/
#define type__for_each_data_member_safe(self, pos, n) \
list_for_each_entry_safe(pos, n, &(self)->namespace.tags, tag.node) \
if (pos->tag.tag != DW_TAG_member) \
continue; \
else
static inline struct type *tag__type(const struct tag *self)
{
return (struct type *)self;
}
struct class {
struct type type;
struct list_head vtable;
uint16_t nr_vtable_entries;
uint8_t nr_holes;
uint8_t nr_bit_holes;
uint16_t padding;
uint8_t bit_padding;
void *priv;
};
static inline struct class *tag__class(const struct tag *self)
{
return (struct class *)self;
}
static inline struct tag *class__tag(const struct class *self)
{
return (struct tag *)self;
}
extern struct class *class__clone(const struct class *from,
const char *new_class_name);
extern void class__delete(struct class *self);
static inline struct list_head *class__tags(struct class *self)
{
return &self->type.namespace.tags;
}
static __pure inline const char *type__name(const struct type *self)
{
return strings__ptr(strings, self->namespace.name);
}
static __pure inline const char *class__name(struct class *self)
{
return strings__ptr(strings, self->type.namespace.name);
}
static inline int class__is_struct(const struct class *self)
{
return tag__is_struct(&self->type.namespace.tag);
}
struct base_type {
struct tag tag;
strings_t name;
size_t bit_size;
};
static inline struct base_type *tag__base_type(const struct tag *self)
{
return (struct base_type *)self;
}
static inline size_t base_type__size(const struct tag *self)
{
return tag__base_type(self)->bit_size / 8;
}
static inline const char *base_type__name(const struct base_type *self)
{
return strings__ptr(strings, self->name);
}
struct array_type {
struct tag tag;
uint32_t *nr_entries;
uint8_t dimensions;
};
static inline struct array_type *tag__array_type(const struct tag *self)
{
return (struct array_type *)self;
}
struct class_member {
struct tag tag;
strings_t name;
uint32_t offset;
uint8_t bit_offset;
uint8_t bit_size;
uint8_t bit_hole; /* If there is a bit hole before the next
one (or the end of the struct) */
uint8_t bitfield_end:1; /* Is this the last entry in a bitfield? */
uint8_t visited:1;
uint8_t accessibility:2; /* DW_ACCESS_{public,protected,private} */
uint8_t virtuality:2; /* DW_VIRTUALITY_{none,virtual,pure_virtual} */
uint16_t hole; /* If there is a hole before the next
[CLASSES]: Find bit holes An example is worth a thousand words, look for "XXX ... bit hole, try to pack" and the stats at the bottom: [acme@newtoy net-2.6]$ pahole ../OUTPUT/qemu/net-2.6/fs/inode.o task_struct /* include2/asm/system.h:11 */ struct task_struct { volatile long int state; /* 0 4 */ struct thread_info * thread_info; /* 4 4 */ atomic_t usage; /* 8 4 */ long unsigned int flags; /* 12 4 */ long unsigned int ptrace; /* 16 4 */ int lock_depth; /* 20 4 */ int load_weight; /* 24 4 */ int prio; /* 28 4 */ /* --- cacheline 1 boundary (32 bytes) --- */ int static_prio; /* 32 4 */ int normal_prio; /* 36 4 */ struct list_head run_list; /* 40 8 */ struct prio_array * array; /* 48 4 */ short unsigned int ioprio; /* 52 2 */ /* XXX 2 bytes hole, try to pack */ long unsigned int sleep_avg; /* 56 4 */ long long unsigned int timestamp; /* 60 8 */ /* --- cacheline 2 boundary (64 bytes) was 4 bytes ago --- */ long long unsigned int last_ran; /* 68 8 */ long long unsigned int sched_time; /* 76 8 */ enum sleep_type sleep_type; /* 84 4 */ long unsigned int policy; /* 88 4 */ cpumask_t cpus_allowed; /* 92 4 */ /* --- cacheline 3 boundary (96 bytes) --- */ unsigned int time_slice; /* 96 4 */ unsigned int first_time_slice; /* 100 4 */ struct list_head tasks; /* 104 8 */ struct list_head ptrace_children; /* 112 8 */ struct list_head ptrace_list; /* 120 8 */ /* --- cacheline 4 boundary (128 bytes) --- */ struct mm_struct * mm; /* 128 4 */ struct mm_struct * active_mm; /* 132 4 */ struct linux_binfmt * binfmt; /* 136 4 */ long int exit_state; /* 140 4 */ int exit_code; /* 144 4 */ int exit_signal; /* 148 4 */ int pdeath_signal; /* 152 4 */ long unsigned int personality; /* 156 4 */ /* --- cacheline 5 boundary (160 bytes) --- */ unsigned int did_exec:1; /* 160 4 */ /* XXX 31 bits hole, try to pack */ pid_t pid; /* 164 4 */ pid_t tgid; /* 168 4 */ struct task_struct * real_parent; /* 172 4 */ struct task_struct * parent; /* 176 4 */ struct list_head children; /* 180 8 */ struct list_head sibling; /* 188 8 */ /* --- cacheline 6 boundary (192 bytes) was 4 bytes ago --- */ struct task_struct * group_leader; /* 196 4 */ struct pid_link pids[3]; /* 200 36 */ /* --- cacheline 7 boundary (224 bytes) was 12 bytes ago --- */ struct list_head thread_group; /* 236 8 */ struct completion * vfork_done; /* 244 4 */ int * set_child_tid; /* 248 4 */ int * clear_child_tid; /* 252 4 */ /* --- cacheline 8 boundary (256 bytes) --- */ long unsigned int rt_priority; /* 256 4 */ cputime_t utime; /* 260 4 */ cputime_t stime; /* 264 4 */ long unsigned int nvcsw; /* 268 4 */ long unsigned int nivcsw; /* 272 4 */ struct timespec start_time; /* 276 8 */ long unsigned int min_flt; /* 284 4 */ /* --- cacheline 9 boundary (288 bytes) --- */ long unsigned int maj_flt; /* 288 4 */ cputime_t it_prof_expires; /* 292 4 */ cputime_t it_virt_expires; /* 296 4 */ long long unsigned int it_sched_expires; /* 300 8 */ struct list_head cpu_timers[3]; /* 308 24 */ /* --- cacheline 10 boundary (320 bytes) was 12 bytes ago --- */ uid_t uid; /* 332 4 */ uid_t euid; /* 336 4 */ uid_t suid; /* 340 4 */ uid_t fsuid; /* 344 4 */ gid_t gid; /* 348 4 */ /* --- cacheline 11 boundary (352 bytes) --- */ gid_t egid; /* 352 4 */ gid_t sgid; /* 356 4 */ gid_t fsgid; /* 360 4 */ struct group_info * group_info; /* 364 4 */ kernel_cap_t cap_effective; /* 368 4 */ kernel_cap_t cap_inheritable; /* 372 4 */ kernel_cap_t cap_permitted; /* 376 4 */ unsigned int keep_capabilities:1; /* 380 4 */ /* XXX 31 bits hole, try to pack */ /* --- cacheline 12 boundary (384 bytes) --- */ struct user_struct * user; /* 384 4 */ struct key * request_key_auth; /* 388 4 */ struct key * thread_keyring; /* 392 4 */ unsigned char jit_keyring; /* 396 1 */ unsigned char fpu_counter; /* 397 1 */ /* XXX 2 bytes hole, try to pack */ int oomkilladj; /* 400 4 */ char comm[16]; /* 404 16 */ /* --- cacheline 13 boundary (416 bytes) was 4 bytes ago --- */ int link_count; /* 420 4 */ int total_link_count; /* 424 4 */ struct sysv_sem sysvsem; /* 428 4 */ struct thread_struct thread; /* 432 656 */ /* --- cacheline 34 boundary (1088 bytes) --- */ struct fs_struct * fs; /* 1088 4 */ struct files_struct * files; /* 1092 4 */ struct nsproxy * nsproxy; /* 1096 4 */ struct signal_struct * signal; /* 1100 4 */ struct sighand_struct * sighand; /* 1104 4 */ sigset_t blocked; /* 1108 8 */ sigset_t real_blocked; /* 1116 8 */ /* --- cacheline 35 boundary (1120 bytes) was 4 bytes ago --- */ sigset_t saved_sigmask; /* 1124 8 */ struct sigpending pending; /* 1132 16 */ long unsigned int sas_ss_sp; /* 1148 4 */ /* --- cacheline 36 boundary (1152 bytes) --- */ size_t sas_ss_size; /* 1152 4 */ int (*notifier)(); /* 1156 4 */ void * notifier_data; /* 1160 4 */ sigset_t * notifier_mask; /* 1164 4 */ void * security; /* 1168 4 */ struct audit_context * audit_context; /* 1172 4 */ seccomp_t seccomp; /* 1176 0 */ u32 parent_exec_id; /* 1176 4 */ u32 self_exec_id; /* 1180 4 */ /* --- cacheline 37 boundary (1184 bytes) --- */ spinlock_t alloc_lock; /* 1184 40 */ /* --- cacheline 38 boundary (1216 bytes) was 8 bytes ago --- */ spinlock_t pi_lock; /* 1224 40 */ /* --- cacheline 39 boundary (1248 bytes) was 16 bytes ago --- */ struct plist_head pi_waiters; /* 1264 20 */ /* --- cacheline 40 boundary (1280 bytes) was 4 bytes ago --- */ struct rt_mutex_waiter * pi_blocked_on; /* 1284 4 */ struct mutex_waiter * blocked_on; /* 1288 4 */ unsigned int irq_events; /* 1292 4 */ int hardirqs_enabled; /* 1296 4 */ long unsigned int hardirq_enable_ip; /* 1300 4 */ unsigned int hardirq_enable_event; /* 1304 4 */ long unsigned int hardirq_disable_ip; /* 1308 4 */ /* --- cacheline 41 boundary (1312 bytes) --- */ unsigned int hardirq_disable_event; /* 1312 4 */ int softirqs_enabled; /* 1316 4 */ long unsigned int softirq_disable_ip; /* 1320 4 */ unsigned int softirq_disable_event; /* 1324 4 */ long unsigned int softirq_enable_ip; /* 1328 4 */ unsigned int softirq_enable_event; /* 1332 4 */ int hardirq_context; /* 1336 4 */ int softirq_context; /* 1340 4 */ /* --- cacheline 42 boundary (1344 bytes) --- */ u64 curr_chain_key; /* 1344 8 */ int lockdep_depth; /* 1352 4 */ struct held_lock held_locks[30]; /* 1356 1200 */ /* --- cacheline 79 boundary (2528 bytes) was 28 bytes ago --- */ unsigned int lockdep_recursion; /* 2556 4 */ /* --- cacheline 80 boundary (2560 bytes) --- */ void * journal_info; /* 2560 4 */ struct reclaim_state * reclaim_state; /* 2564 4 */ struct backing_dev_info * backing_dev_info; /* 2568 4 */ struct io_context * io_context; /* 2572 4 */ long unsigned int ptrace_message; /* 2576 4 */ siginfo_t * last_siginfo; /* 2580 4 */ wait_queue_t * io_wait; /* 2584 4 */ u64 rchar; /* 2588 8 */ /* --- cacheline 81 boundary (2592 bytes) was 4 bytes ago --- */ u64 wchar; /* 2596 8 */ u64 syscr; /* 2604 8 */ u64 syscw; /* 2612 8 */ struct robust_list_head * robust_list; /* 2620 4 */ /* --- cacheline 82 boundary (2624 bytes) --- */ struct list_head pi_state_list; /* 2624 8 */ struct futex_pi_state * pi_state_cache; /* 2632 4 */ atomic_t fs_excl; /* 2636 4 */ struct rcu_head rcu; /* 2640 8 */ struct pipe_inode_info * splice_pipe; /* 2648 4 */ }; /* size: 2656, cachelines: 83 */ /* sum members: 2648, holes: 2, sum holes: 4 */ /* bit holes: 2, sum bit holes: 62 bits */ /* padding: 4 */ Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 15:26:50 +01:00
one (or the end of the struct) */
};
static inline struct class_member *tag__class_member(const struct tag *self)
{
return (struct class_member *)self;
}
extern size_t class_member__size(const struct class_member *self,
const struct cu *cu);
static inline const char *class_member__name(const struct class_member *self)
{
return strings__ptr(strings, self->name);
}
extern void class_member__delete(struct class_member *self);
struct lexblock {
struct tag tag;
struct list_head tags;
Dwarf_Addr low_pc;
Dwarf_Addr high_pc;
uint16_t nr_inline_expansions;
uint16_t nr_labels;
uint16_t nr_variables;
uint16_t nr_lexblocks;
size_t size_inline_expansions;
};
static inline struct lexblock *tag__lexblock(const struct tag *self)
{
return (struct lexblock *)self;
}
/*
* tag.tag can be DW_TAG_subprogram_type or DW_TAG_subroutine_type.
*/
struct ftype {
struct tag tag;
struct list_head parms;
uint16_t nr_parms;
uint8_t unspec_parms; /* just one bit is needed */
};
static inline struct ftype *tag__ftype(const struct tag *self)
{
return (struct ftype *)self;
}
/**
* ftype__for_each_parameter - iterate thru all the parameters
* @self: struct ftype instance to iterate
* @pos: struct parameter iterator
*/
#define ftype__for_each_parameter(self, pos) \
list_for_each_entry(pos, &(self)->parms, tag.node)
struct function {
struct ftype proto;
struct lexblock lexblock;
Dwarf_Off abstract_origin;
Dwarf_Off specification;
strings_t name;
strings_t linkage_name;
size_t cu_total_size_inline_expansions;
uint16_t cu_total_nr_inline_expansions;
uint8_t inlined:2;
uint8_t external:1;
uint8_t accessibility:2; /* DW_ACCESS_{public,protected,private} */
uint8_t virtuality:2; /* DW_VIRTUALITY_{none,virtual,pure_virtual} */
int16_t vtable_entry;
struct list_head vtable_node;
/* fields used by tools */
struct list_head tool_node;
void *priv;
};
static inline struct function *tag__function(const struct tag *self)
{
return (struct function *)self;
}
static inline struct tag *function__tag(const struct function *self)
{
return (struct tag *)self;
}
static __pure inline int tag__is_function(const struct tag *self)
{
return self->tag == DW_TAG_subprogram;
}
/**
* function__for_each_parameter - iterate thru all the parameters
* @self: struct function instance to iterate
* @pos: struct parameter iterator
*/
#define function__for_each_parameter(self, pos) \
ftype__for_each_parameter(&self->proto, pos)
struct parameter {
struct tag tag;
strings_t name;
Dwarf_Off abstract_origin;
};
static inline struct parameter *tag__parameter(const struct tag *self)
{
return (struct parameter *)self;
}
static inline const char *parameter__name(const struct parameter *self)
{
return strings__ptr(strings, self->name);
}
enum vlocation {
LOCATION_UNKNOWN,
LOCATION_LOCAL,
LOCATION_GLOBAL,
LOCATION_REGISTER,
LOCATION_OPTIMIZED
};
struct variable {
struct tag tag;
Dwarf_Off abstract_origin;
strings_t name;
uint8_t external:1;
uint8_t declaration:1;
enum vlocation location;
};
static inline struct variable *tag__variable(const struct tag *self)
{
return (struct variable *)self;
}
[CLASSES]: Add support for DW_TAG_inlined_subroutine Output of pfunct using this information (all for a make allyesconfig build): Top 5 functions by size of inlined functions in net/ipv4: [acme@newtoy guinea_pig-2.6]$ pfunct -I net/ipv4/built-in.o | sort -k3 -nr | head -5 ip_route_input: 19 7086 tcp_ack: 33 6415 do_ip_vs_set_ctl: 23 4193 q931_help: 8 3822 ip_defrag: 19 3318 [acme@newtoy guinea_pig-2.6]$ And by number of inline expansions: [acme@newtoy guinea_pig-2.6]$ pfunct -I net/ipv4/built-in.o | sort -k2 -nr | head -5 dump_packet: 35 905 tcp_v4_rcv: 34 1773 tcp_recvmsg: 34 928 tcp_ack: 33 6415 tcp_rcv_established: 31 1195 [acme@newtoy guinea_pig-2.6]$ And the list of expansions on a specific function: [acme@newtoy guinea_pig-2.6]$ pfunct -i net/ipv4/built-in.o tcp_v4_rcv /* net/ipv4/tcp_ipv4.c:1054 */ int tcp_v4_rcv(struct sk_buff * skb); /* size: 2189, variables: 8, goto labels: 6, inline expansions: 34 (1773 bytes) */ /* inline expansions in tcp_v4_rcv: current_thread_info: 8 pskb_may_pull: 36 pskb_may_pull: 29 tcp_v4_checksum_init: 139 __fswab32: 2 __fswab32: 2 inet_iif: 12 __inet_lookup: 292 __fswab16: 20 inet_ehashfn: 25 inet_ehash_bucket: 18 prefetch: 4 prefetch: 4 prefetch: 4 sock_hold: 4 xfrm4_policy_check: 59 nf_reset: 66 sk_filter: 135 __skb_trim: 20 get_softnet_dma: 68 tcp_prequeue: 257 sk_add_backlog: 40 sock_put: 27 xfrm4_policy_check: 46 tcp_checksum_complete: 29 current_thread_info: 8 sock_put: 20 xfrm4_policy_check: 50 tcp_checksum_complete: 29 current_thread_info: 8 inet_iif: 9 inet_lookup_listener: 36 inet_twsk_put: 114 tcp_v4_timewait_ack: 153 */ [acme@newtoy guinea_pig-2.6]$ Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 16:41:19 +01:00
struct inline_expansion {
struct tag tag;
size_t size;
Dwarf_Addr low_pc;
Dwarf_Addr high_pc;
[CLASSES]: Add support for DW_TAG_inlined_subroutine Output of pfunct using this information (all for a make allyesconfig build): Top 5 functions by size of inlined functions in net/ipv4: [acme@newtoy guinea_pig-2.6]$ pfunct -I net/ipv4/built-in.o | sort -k3 -nr | head -5 ip_route_input: 19 7086 tcp_ack: 33 6415 do_ip_vs_set_ctl: 23 4193 q931_help: 8 3822 ip_defrag: 19 3318 [acme@newtoy guinea_pig-2.6]$ And by number of inline expansions: [acme@newtoy guinea_pig-2.6]$ pfunct -I net/ipv4/built-in.o | sort -k2 -nr | head -5 dump_packet: 35 905 tcp_v4_rcv: 34 1773 tcp_recvmsg: 34 928 tcp_ack: 33 6415 tcp_rcv_established: 31 1195 [acme@newtoy guinea_pig-2.6]$ And the list of expansions on a specific function: [acme@newtoy guinea_pig-2.6]$ pfunct -i net/ipv4/built-in.o tcp_v4_rcv /* net/ipv4/tcp_ipv4.c:1054 */ int tcp_v4_rcv(struct sk_buff * skb); /* size: 2189, variables: 8, goto labels: 6, inline expansions: 34 (1773 bytes) */ /* inline expansions in tcp_v4_rcv: current_thread_info: 8 pskb_may_pull: 36 pskb_may_pull: 29 tcp_v4_checksum_init: 139 __fswab32: 2 __fswab32: 2 inet_iif: 12 __inet_lookup: 292 __fswab16: 20 inet_ehashfn: 25 inet_ehash_bucket: 18 prefetch: 4 prefetch: 4 prefetch: 4 sock_hold: 4 xfrm4_policy_check: 59 nf_reset: 66 sk_filter: 135 __skb_trim: 20 get_softnet_dma: 68 tcp_prequeue: 257 sk_add_backlog: 40 sock_put: 27 xfrm4_policy_check: 46 tcp_checksum_complete: 29 current_thread_info: 8 sock_put: 20 xfrm4_policy_check: 50 tcp_checksum_complete: 29 current_thread_info: 8 inet_iif: 9 inet_lookup_listener: 36 inet_twsk_put: 114 tcp_v4_timewait_ack: 153 */ [acme@newtoy guinea_pig-2.6]$ Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 16:41:19 +01:00
};
static inline struct inline_expansion *
tag__inline_expansion(const struct tag *self)
{
return (struct inline_expansion *)self;
}
struct label {
struct tag tag;
strings_t name;
Dwarf_Addr low_pc;
Dwarf_Off abstract_origin;
};
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
static inline struct label *tag__label(const struct tag *self)
{
return (struct label *)self;
}
struct enumerator {
struct tag tag;
strings_t name;
uint32_t value;
};
struct conf_fprintf {
const char *prefix;
const char *suffix;
int32_t type_spacing;
int32_t name_spacing;
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;
uint8_t suppress_offset_comment:1;
uint8_t show_decl_info:1;
uint8_t show_only_data_members:1;
uint8_t no_semicolon:1;
uint8_t show_first_biggest_size_base_type_member:1;
};
int dwarves__init(size_t user_cacheline_size);
[PAHOLE]: Print cacheline boundaries Cacheline size defaults to 32, sample output changing the default to 64 bytes: pahole --cacheline=64 ../../acme/OUTPUT/qemu/net-2.6/net/ipv4/tcp.o inode /* /pub/scm/linux/kernel/git/acme/net-2.6/include/linux/dcache.h:86 */ struct inode { struct hlist_node i_hash; /* 0 8 */ struct list_head i_list; /* 8 8 */ struct list_head i_sb_list; /* 16 8 */ struct list_head i_dentry; /* 24 8 */ long unsigned int i_ino; /* 32 4 */ atomic_t i_count; /* 36 4 */ umode_t i_mode; /* 40 2 */ /* XXX 2 bytes hole, try to pack */ unsigned int i_nlink; /* 44 4 */ uid_t i_uid; /* 48 4 */ gid_t i_gid; /* 52 4 */ dev_t i_rdev; /* 56 4 */ loff_t i_size; /* 60 8 */ struct timespec i_atime; /* 68 8 */ struct timespec i_mtime; /* 76 8 */ struct timespec i_ctime; /* 84 8 */ unsigned int i_blkbits; /* 92 4 */ long unsigned int i_version; /* 96 4 */ blkcnt_t i_blocks; /* 100 4 */ short unsigned int i_bytes; /* 104 2 */ spinlock_t i_lock; /* 106 0 */ /* XXX 2 bytes hole, try to pack */ struct mutex i_mutex; /* 108 24 */ /* ---------- cacheline 2 boundary ---------- */ struct rw_semaphore i_alloc_sem; /* 132 12 */ struct inode_operations * i_op; /* 144 4 */ const struct file_operations * i_fop; /* 148 4 */ struct super_block * i_sb; /* 152 4 */ struct file_lock * i_flock; /* 156 4 */ struct address_space * i_mapping; /* 160 4 */ struct address_space i_data; /* 164 72 */ struct list_head i_devices; /* 236 8 */ union ; /* 244 4 */ int i_cindex; /* 248 4 */ __u32 i_generation; /* 252 4 */ long unsigned int i_dnotify_mask; /* 256 4 */ /* ---------- cacheline 4 boundary ---------- */ struct dnotify_struct * i_dnotify; /* 260 4 */ struct list_head inotify_watches; /* 264 8 */ struct mutex inotify_mutex; /* 272 24 */ long unsigned int i_state; /* 296 4 */ long unsigned int dirtied_when; /* 300 4 */ unsigned int i_flags; /* 304 4 */ atomic_t i_writecount; /* 308 4 */ void * i_private; /* 312 4 */ }; /* size: 316, sum members: 312, holes: 2, sum holes: 4 */ Has to be improved to show the other cacheline boundaries, that may be buried into a included struct or union. Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-05 18:34:54 +01:00
extern void class__find_holes(struct class *self, const struct cu *cu);
[LIB]: Introduce class__has_hole_ge() That returns if the class has a hole greater or equal to the size specified. Pahole now has a --hole_size_ge command line option to use it. Example on a linux kernel built for x86_64 where we list the structs that have holes bigger than 32 bytes, that provides an approximation of structs with ____cacheline_aligned_in_smp annotated members: [acme@filo pahole]$ pahole --hole_size_ge 32 examples/vmlinux-x86_64 inet_hashinfo rcu_ctrlblk hh_cache net_device files_struct module zone For instance, look at struct zone clever use of such construct: _pad1_ is defined with ZONE_PADDING(_pad1_), that is: /* <40e> /home/acme/git/net-2.6.22/include/linux/mmzone.h:179 */ struct zone { long unsigned int pages_min; /* 0 8 */ long unsigned int pages_low; /* 8 8 */ long unsigned int pages_high; /* 16 8 */ long unsigned int lowmem_reserve[3]; /* 24 24 */ int node; /* 48 4 */ /* XXX 4 bytes hole, try to pack */ long unsigned int min_unmapped_pages; /* 56 8 */ /* --- cacheline 1 boundary (64 bytes) --- */ long unsigned int min_slab_pages; /* 64 8 */ struct per_cpu_pageset * pageset[255]; /* 72 2040 */ /* --- cacheline 33 boundary (2112 bytes) --- */ spinlock_t lock; /* 2112 4 */ /* XXX 4 bytes hole, try to pack */ struct free_area free_area[11]; /* 2120 264 */ /* XXX 48 bytes hole, try to pack */ /* --- cacheline 38 boundary (2432 bytes) --- */ struct zone_padding _pad1_; /* 2432 0 */ spinlock_t lru_lock; /* 2432 4 */ /* XXX 4 bytes hole, try to pack */ struct list_head active_list; /* 2440 16 */ struct list_head inactive_list; /* 2456 16 */ long unsigned int nr_scan_active; /* 2472 8 */ long unsigned int nr_scan_inactive; /* 2480 8 */ long unsigned int pages_scanned; /* 2488 8 */ /* --- cacheline 39 boundary (2496 bytes) --- */ int all_unreclaimable; /* 2496 4 */ atomic_t reclaim_in_progress; /* 2500 4 */ atomic_long_t vm_stat[20]; /* 2504 160 */ /* --- cacheline 41 boundary (2624 bytes) was 40 bytes ago --- */ int prev_priority; /* 2664 4 */ /* XXX 20 bytes hole, try to pack */ /* --- cacheline 42 boundary (2688 bytes) --- */ struct zone_padding _pad2_; /* 2688 0 */ wait_queue_head_t * wait_table; /* 2688 8 */ long unsigned int wait_table_hash_nr_entries; /* 2696 8 */ long unsigned int wait_table_bits; /* 2704 8 */ struct pglist_data * zone_pgdat; /* 2712 8 */ long unsigned int zone_start_pfn; /* 2720 8 */ long unsigned int spanned_pages; /* 2728 8 */ long unsigned int present_pages; /* 2736 8 */ const char * name; /* 2744 8 */ /* --- cacheline 43 boundary (2752 bytes) --- */ }; /* size: 2752, cachelines: 43 */ /* sum members: 2672, holes: 5, sum holes: 80 */ /* definitions: 933 */ Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-11 18:32:53 +02:00
extern int class__has_hole_ge(const struct class *self, const uint16_t size);
extern size_t class__fprintf(struct class *self, const struct cu *cu,
const struct conf_fprintf *conf, FILE *fp);
void enumeration__add(struct type *self, struct enumerator *enumerator);
extern size_t enumeration__fprintf(const struct tag *tag_self,
const struct conf_fprintf *conf, FILE *fp);
extern size_t typedef__fprintf(const struct tag *tag_self, const struct cu *cu,
const struct conf_fprintf *conf, FILE *fp);
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
size_t tag__fprintf_decl_info(const struct tag *self,
const struct cu *cu, FILE *fp);
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);
extern size_t function__fprintf_stats(const struct tag *tag_self,
const struct cu *cu,
FILE *fp);
extern const char *function__prototype(const struct function *self,
const struct cu *cu,
char *bf, size_t len);
void lexblock__add_inline_expansion(struct lexblock *self,
struct inline_expansion *exp);
void lexblock__add_label(struct lexblock *self, struct label *label);
void lexblock__add_lexblock(struct lexblock *self, struct lexblock *child);
void lexblock__add_tag(struct lexblock *self, struct tag *tag);
void lexblock__add_variable(struct lexblock *self, struct variable *var);
extern size_t lexblock__fprintf(const struct lexblock *self,
const struct cu *cu, struct function *function,
uint16_t indent, FILE *fp);
extern int cus__loadfl(struct cus *self, char *filenames[]);
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);
void cus__add(struct cus *self, struct cu *cu);
extern void cus__print_error_msg(const char *progname, const struct cus *cus,
const char *filename, const int err);
extern struct cu *cus__find_cu_by_name(const struct cus *self,
const char *name);
extern struct tag *cu__find_base_type_by_name(const struct cu *self,
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
const char *name,
uint16_t *id);
struct tag *cu__find_base_type_by_name_and_size(const struct cu *self,
const char *name,
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
size_t bit_size,
uint16_t *id);
extern struct tag *cus__find_struct_by_name(const struct cus *self,
struct cu **cu,
const char *name,
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
const int include_decls,
uint16_t *id);
extern struct tag *cus__find_function_by_name(const struct cus *self,
struct cu **cu,
const char *name);
extern struct tag *cus__find_tag_by_id(const struct cus *self,
struct cu **cu, const Dwarf_Off id);
struct cu *cu__new(const char *name, uint8_t addr_size,
const unsigned char *build_id, int build_id_len);
extern void cu__delete(struct cu *self);
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
int cu__add_tag(struct cu *self, struct tag *tag, long *id);
int cu__table_add_tag(struct cu *self, struct tag *tag, long *id);
int cu__table_nullify_type_entry(struct cu *self, uint32_t id);
extern struct tag *cu__find_tag_by_id(const struct cu *self,
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
const uint32_t id);
struct tag *cu__find_type_by_id(const struct cu *self, const uint16_t id);
extern struct tag *cu__find_first_typedef_of_type(const struct cu *self,
const Dwarf_Off type);
extern struct tag *cu__find_struct_by_name(const struct cu *cu,
const char *name,
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
const int include_decls,
uint16_t *id);
extern bool cu__same_build_id(const struct cu *self, const struct cu *other);
extern void cu__account_inline_expansions(struct cu *self);
extern int cu__for_each_tag(struct cu *self,
int (*iterator)(struct tag *tag,
struct cu *cu,
void *cookie),
void *cookie,
struct tag *(*filter)(struct tag *tag,
struct cu *cu,
void *cookie));
extern void cus__for_each_cu(struct cus *self,
int (*iterator)(struct cu *cu,
void *cookie),
void *cookie,
struct cu *(*filter)(struct cu *cu));
extern const struct class_member *
class__find_bit_hole(const struct class *self,
const struct class_member *trailer,
const size_t bit_hole_size);
extern struct tag *cu__find_function_by_name(const struct cu *cu,
const char *name);
static inline size_t function__size(const struct function *self)
{
return self->lexblock.high_pc - self->lexblock.low_pc;
}
static inline int function__declared_inline(const struct function *self)
{
return (self->inlined == DW_INL_declared_inlined ||
self->inlined == DW_INL_declared_not_inlined);
}
static inline int function__inlined(const struct function *self)
{
return (self->inlined == DW_INL_inlined ||
self->inlined == DW_INL_declared_inlined);
}
void ftype__add_parameter(struct ftype *self, struct parameter *parm);
extern size_t ftype__fprintf(const struct ftype *self, const struct cu *cu,
const char *name, const int inlined,
const int is_pointer, const int type_spacing,
FILE *fp);
extern int ftype__has_parm_of_type(const struct ftype *self,
dwarves: Remove some more DWARF details from the core Had to be a big sweeping change, but the regression tests shows just improvements :-) Now we stop using an id in struct tag, only storing the type, that now uses 16 bits only, as CTF does. Each format loader has to go on adding the types to the core, that figures out if it is a tag that can be on the tag->type field (tag__is_tag_type). Formats that already have the types separated and in sequence, such as CTF, just ask the core to insert in the types_table directly with its original ID. For DWARF, we ask the core to put it on the table, in sequence, and return the index, that is then stashed with the DWARF specific info (original id, type, decl_line, etc) and hashed by the original id. Later we recode everything, looking up via the original type, getting the small_id to put on the tag->type. The underlying debugging info not needed by the core is stashed in tag->priv, and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of the core tag and points it there, and makes that info available thru cu->orig_info. In the future we can ask, when loading a cu, that this info be trown away, so that we reduce the memory footprint for big multi-cu files such as the Linux kernel. There is also a routine to ask for inserting a NULL, as we still have bugs in the CTF decoding and thus some entries are being lost, to avoid using an undefined pointer when traversing the types_table the ctf loader puts a NULL there via cu__table_nullify_type_entry() and then cu__for_each_type skips those. There is some more cleanups for leftovers that I avoided cleaning to reduce this changeset. And also while doing this I saw that enums can appear without any enumerators and that an array with DW_TAG_GNU_vector is actually a different tag, encoded this way till we get to DWARF4 ;-) So now we don't have to lookup on a hash table looking for DWARF offsets, we can do the more sensible thing of just indexing the types_tags array. Now to do some cleanups and try to get the per cu encoder done. Then order all the cus per number of type entries, pick the one with more, then go on merging/recoding the types of the others and putting the parent linkage in place. Just to show the extent of the changes: $ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0 /home/acme/git/pahole/dwarves.c: struct cu | -4048 struct tag | -32 struct ptr_to_member_type | -32 struct namespace | -32 struct type | -32 struct class | -32 struct base_type | -32 struct array_type | -32 struct class_member | -32 struct lexblock | -32 struct ftype | -32 struct function | -64 struct parameter | -32 struct variable | -32 struct inline_expansion | -32 struct label | -32 struct enumerator | -32 17 structs changed tag__follow_typedef | +3 tag__fprintf_decl_info | +25 array_type__fprintf | +6 type__name | -126 type__find_first_biggest_size_base_type_member | -3 typedef__fprintf | +16 imported_declaration__fprintf | +6 imported_module__fprintf | +3 cu__new | +26 cu__delete | +26 hashtags__hash | -65 hash_64 | -124 hlist_add_head | -78 hashtags__find | -157 cu__hash | -80 cu__add_tag | +20 tag__prefix | -3 cu__find_tag_by_id | -2 cu__find_type_by_id | -3 cu__find_first_typedef_of_type | +38 cu__find_base_type_by_name | +68 cu__find_base_type_by_name_and_size | +72 cu__find_struct_by_name | +59 cus__find_struct_by_name | +8 cus__find_tag_by_id | +5 cus__find_cu_by_name | -6 lexblock__find_tag_by_id | -173 cu__find_variable_by_id | -197 list__find_tag_by_id | -308 cu__find_parameter_by_id | -60 tag__ptr_name | +6 tag__name | +15 variable__type | +13 variable__name | +7 class_member__size | +6 parameter__name | -119 tag__parameter | -14 parameter__type | -143 type__fprintf | -29 union__fprintf | +6 class__add_vtable_entry | -9 type__add_member | -6 type__clone_members | -3 enumeration__add | -6 function__name | -156 ftype__has_parm_of_type | -39 class__find_holes | -27 class__has_hole_ge | -3 type__nr_members_of_type | +3 lexblock__account_inline_expansions | +3 cu__account_inline_expansions | -18 ftype__fprintf_parms | +46 function__tag_fprintf | +24 lexblock__fprintf | -6 ftype__fprintf | +3 function__fprintf_stats | -18 function__size | -6 class__vtable_fprintf | -11 class__fprintf | -21 tag__fprintf | -35 60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541 /home/acme/git/pahole/ctf_loader.c: struct ctf_short_type | +0 14 structs changed type__init | -14 type__new | -9 class__new | -12 create_new_base_type | -7 create_new_base_type_float | -7 create_new_array | -8 create_new_subroutine_type | -9 create_full_members | -18 create_short_members | -18 create_new_class | +1 create_new_union | +1 create_new_enumeration | -19 create_new_forward_decl | -2 create_new_typedef | +3 create_new_tag | -5 load_types | +16 class__fixup_ctf_bitfields | -3 17 functions changed, 21 bytes added, 131 bytes removed, diff: -110 /home/acme/git/pahole/dwarf_loader.c: 17 structs changed zalloc | -56 tag__init | +3 array_type__new | +20 type__init | -24 class_member__new | +46 inline_expansion__new | +12 class__new | +81 lexblock__init | +19 function__new | +43 die__create_new_array | +20 die__create_new_parameter | +4 die__create_new_label | +4 die__create_new_subroutine_type | +113 die__create_new_enumeration | -21 die__process_class | +79 die__process_namespace | +76 die__create_new_inline_expansion | +4 die__process_function | +147 __die__process_tag | +34 die__process_unit | +56 die__process | +90 21 functions changed, 851 bytes added, 101 bytes removed, diff: +750 /home/acme/git/pahole/dwarves.c: struct ptr_table | +16 struct cu_orig_info | +32 2 structs changed tag__decl_line | +68 tag__decl_file | +70 tag__orig_id | +71 ptr_table__init | +46 ptr_table__exit | +37 ptr_table__add | +183 ptr_table__add_with_id | +165 ptr_table__entry | +64 cu__table_add_tag | +171 cu__table_nullify_type_entry | +38 10 functions changed, 913 bytes added, diff: +913 /home/acme/git/pahole/ctf_loader.c: 2 structs changed tag__alloc | +52 1 function changed, 52 bytes added, diff: +52 /home/acme/git/pahole/dwarf_loader.c: struct dwarf_tag | +48 struct dwarf_cu | +4104 4 structs changed dwarf_cu__init | +83 hashtags__hash | +61 hash_64 | +124 hlist_add_head | +78 hashtags__find | +161 cu__hash | +95 tag__is_tag_type | +171 tag__is_type | +85 tag__is_union | +28 tag__is_struct | +57 tag__is_typedef | +28 tag__is_enumeration | +28 dwarf_cu__find_tag_by_id | +56 dwarf_cu__find_type_by_id | +63 tag__alloc | +114 __tag__print_type_not_found | +108 namespace__recode_dwarf_types | +346 tag__namespace | +14 tag__has_namespace | +86 tag__is_namespace | +28 type__recode_dwarf_specification | +182 tag__type | +14 __tag__print_abstract_origin_not_found | +105 ftype__recode_dwarf_types | +322 tag__ftype | +14 tag__parameter | +14 lexblock__recode_dwarf_types | +736 tag__lexblock | +14 tag__label | +14 tag__recode_dwarf_type | +766 tag__ptr_to_member_type | +14 cu__recode_dwarf_types_table | +88 cu__recode_dwarf_types | +48 dwarf_tag__decl_file | +77 strings__ptr | +33 dwarf_tag__decl_line | +59 dwarf_tag__orig_id | +59 dwarf_tag__orig_type | +59 38 functions changed, 4432 bytes added, diff: +4432 build/libdwarves.so.1.0.0: 147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
const uint16_t target,
const struct cu *cu);
void type__add_member(struct type *self, struct class_member *member);
extern struct class_member *
type__find_first_biggest_size_base_type_member(struct type *self,
const struct cu *cu);
extern const char *tag__name(const struct tag *self, const struct cu *cu,
char *bf, size_t len);
extern void tag__not_found_die(const char *file, int line, const char *func);
#define tag__assert_search_result(tag) \
do { if (!tag) tag__not_found_die(__FILE__,\
__LINE__, __func__); } while (0)
extern size_t tag__size(const struct tag *self, const struct cu *cu);
extern size_t tag__nr_cachelines(const struct tag *self, const struct cu *cu);
extern struct tag *tag__follow_typedef(struct tag *tag, const struct cu *cu);
extern struct class_member *type__find_member_by_name(const struct type *self,
const char *name);
extern uint32_t type__nr_members_of_type(const struct type *self,
const Dwarf_Off type);
extern struct class_member *type__last_member(struct type *self);
void class__add_vtable_entry(struct class *self, struct function *vtable_entry);
static inline struct class_member *
class__find_member_by_name(const struct class *self, const char *name)
{
return type__find_member_by_name(&self->type, name);
}
static inline uint16_t class__nr_members(const struct class *self)
{
return self->type.nr_members;
}
static inline size_t class__size(const struct class *self)
{
return self->type.size;
}
static inline int class__is_declaration(const struct class *self)
{
return self->type.declaration;
}
[CODIFF]: Detect and print all sorts of changes in structs [acme@newtoy examples]$ cat struct.c static struct foo { char a:2; unsigned int b; unsigned long c; unsigned long d; unsigned long e; } bar; int main(int argc, char *argv[]) { printf("%d", bar.a); } [acme@newtoy examples]$ Then change "a:2" to "a:4": [acme@newtoy examples]$ codiff -V old_struct new_struct struct.c: struct foo | +0 a:2; from: char /* 0(6) 1(2) */ to: char /* 0(4) 1(4) */ 1 struct changed Now, on top of that move a after b: [acme@newtoy examples]$ codiff -V old_struct new_struct struct.c: struct foo | +0 a:2; from: char /* 0(6) 1(2) */ to: char /* 4(4) 1(4) */ b; from: unsigned int /* 4(0) 4(0) */ to: unsigned int /* 0(0) 4(0) */ 1 struct changed [acme@newtoy examples]$ Move it back a to before b and change the type of e without changing its size, i.e. from unsigned long to long: [acme@newtoy examples]$ codiff -V old_struct new_struct struct.c: struct foo | +0 a:2; from: char /* 0(6) 1(2) */ to: char /* 0(4) 1(4) */ e; from: long unsigned int /* 16(0) 4(0) */ to: long int /* 16(0) 4(0) */ 1 struct changed [acme@newtoy examples]$ Now on top of this lets delete the c member: [acme@newtoy examples]$ codiff -V old_struct new_struct struct.c: struct foo | -4 nr_members: -1 -long unsigned int c; /* 8 4 */ a:2; from: char /* 0(6) 1(2) */ to: char /* 0(4) 1(4) */ d; from: long unsigned int /* 12(0) 4(0) */ to: long unsigned int /* 8(0) 4(0) */ e; from: long unsigned int /* 16(0) 4(0) */ to: long int /* 12(0) 4(0) */ 1 struct changed [acme@newtoy examples]$ WOW, many changes, what an ABI breakage, no? :-) It started as: [acme@newtoy examples]$ pahole old_struct foo /* /home/acme/pahole/examples/struct.c:3 */ struct foo { char a:2; /* 0 1 */ /* XXX 3 bytes hole, try to pack */ unsigned int b; /* 4 4 */ long unsigned int c; /* 8 4 */ long unsigned int d; /* 12 4 */ long unsigned int e; /* 16 4 */ }; /* size: 20, sum members: 17, holes: 1, sum holes: 3 */ And ended up as: [acme@newtoy examples]$ pahole new_struct foo /* /home/acme/pahole/examples/struct.c:3 */ struct foo { char a:4; /* 0 1 */ /* XXX 3 bytes hole, try to pack */ unsigned int b; /* 4 4 */ long unsigned int d; /* 8 4 */ long int e; /* 12 4 */ }; /* size: 16, sum members: 13, holes: 1, sum holes: 3 */ [acme@newtoy examples]$ Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 18:07:21 +01:00
void namespace__add_tag(struct namespace *self, struct tag *tag);
extern const char *variable__name(const struct variable *self,
const struct cu *cu);
extern const char *variable__type_name(const struct variable *self,
const struct cu *cu,
char *bf, size_t len);
extern const char *dwarf_tag_name(const uint32_t tag);
struct argp_state;
void dwarves_print_version(FILE *fp, struct argp_state *state);
#endif /* _DWARVES_H_ */