dwarves/dwarves.h

1145 lines
33 KiB
C
Raw Normal View History

#ifndef _DWARVES_H_
#define _DWARVES_H_ 1
/*
Copyright (C) 2006 Mandriva Conectiva S.A.
Copyright (C) 2006..2009 Arnaldo Carvalho de Melo <acme@redhat.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 <obstack.h>
#include <dwarf.h>
#include <elfutils/libdwfl.h>
#include "dutil.h"
#include "list.h"
#include "rbtree.h"
#include "strings.h"
struct cu;
enum load_steal_kind {
LSK__KEEPIT,
LSK__DELETE,
LSK__STOP_LOADING,
};
/** struct conf_load - load configuration
* @extra_dbg_info - keep original debugging format extra info
* (e.g. DWARF's decl_{line,file}, id, etc)
* @fixup_silly_bitfields - Fixup silly things such as "int foo:32;"
dwarves: Allow avoiding loading addr information As, for instance, pahole doesn't need it at all. Down from: [acme@doppio pahole]$ perf stat -r 5 pahole object_samples/zweinberg\@mozilla.com/libgklayout.so > /dev/null Performance counter stats for 'pahole object_samples/zweinberg@mozilla.com/libgklayout.so' (5 runs): 17233.989563 task-clock-msecs # 0.994 CPUs ( +- 0.076% ) 1880 context-switches # 0.000 M/sec ( +- 0.159% ) 0 CPU-migrations # 0.000 M/sec ( +- 0.000% ) 26248 page-faults # 0.002 M/sec ( +- 0.000% ) 34244461105 cycles # 1987.030 M/sec ( +- 0.078% ) 34510583834 instructions # 1.008 IPC ( +- 0.001% ) 445937867 cache-references # 25.875 M/sec ( +- 0.160% ) 56898165 cache-misses # 3.302 M/sec ( +- 0.074% ) 17.335292038 seconds time elapsed ( +- 0.076% ) [acme@doppio pahole]$ To: [acme@doppio pahole]$ perf stat -r 5 pahole object_samples/zweinberg\@mozilla.com/libgklayout.so > /dev/null Performance counter stats for 'pahole object_samples/zweinberg@mozilla.com/libgklayout.so' (5 runs): 16511.627334 task-clock-msecs # 0.992 CPUs ( +- 0.208% ) 1922 context-switches # 0.000 M/sec ( +- 3.068% ) 0 CPU-migrations # 0.000 M/sec ( +- 0.000% ) 25570 page-faults # 0.002 M/sec ( +- 0.000% ) 32807624343 cycles # 1986.941 M/sec ( +- 0.208% ) 32711598374 instructions # 0.997 IPC ( +- 0.001% ) 436345377 cache-references # 26.427 M/sec ( +- 0.178% ) 54044997 cache-misses # 3.273 M/sec ( +- 0.685% ) 16.652951166 seconds time elapsed ( +- 0.304% ) [acme@doppio pahole]$ Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-07-06 18:44:57 +02:00
* @get_addr_info - wheter to load DW_AT_location and other addr info
*/
struct conf_load {
enum load_steal_kind (*steal)(struct cu *cu,
struct conf_load *conf);
void *cookie;
char *format_path;
bool extra_dbg_info;
bool fixup_silly_bitfields;
dwarves: Allow avoiding loading addr information As, for instance, pahole doesn't need it at all. Down from: [acme@doppio pahole]$ perf stat -r 5 pahole object_samples/zweinberg\@mozilla.com/libgklayout.so > /dev/null Performance counter stats for 'pahole object_samples/zweinberg@mozilla.com/libgklayout.so' (5 runs): 17233.989563 task-clock-msecs # 0.994 CPUs ( +- 0.076% ) 1880 context-switches # 0.000 M/sec ( +- 0.159% ) 0 CPU-migrations # 0.000 M/sec ( +- 0.000% ) 26248 page-faults # 0.002 M/sec ( +- 0.000% ) 34244461105 cycles # 1987.030 M/sec ( +- 0.078% ) 34510583834 instructions # 1.008 IPC ( +- 0.001% ) 445937867 cache-references # 25.875 M/sec ( +- 0.160% ) 56898165 cache-misses # 3.302 M/sec ( +- 0.074% ) 17.335292038 seconds time elapsed ( +- 0.076% ) [acme@doppio pahole]$ To: [acme@doppio pahole]$ perf stat -r 5 pahole object_samples/zweinberg\@mozilla.com/libgklayout.so > /dev/null Performance counter stats for 'pahole object_samples/zweinberg@mozilla.com/libgklayout.so' (5 runs): 16511.627334 task-clock-msecs # 0.992 CPUs ( +- 0.208% ) 1922 context-switches # 0.000 M/sec ( +- 3.068% ) 0 CPU-migrations # 0.000 M/sec ( +- 0.000% ) 25570 page-faults # 0.002 M/sec ( +- 0.000% ) 32807624343 cycles # 1986.941 M/sec ( +- 0.208% ) 32711598374 instructions # 0.997 IPC ( +- 0.001% ) 436345377 cache-references # 26.427 M/sec ( +- 0.178% ) 54044997 cache-misses # 3.273 M/sec ( +- 0.685% ) 16.652951166 seconds time elapsed ( +- 0.304% ) [acme@doppio pahole]$ Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-07-06 18:44:57 +02:00
bool get_addr_info;
};
/** struct conf_fprintf - hints to the __fprintf routines
*
* @flat_arrays - a->foo[10][2] becomes a->foo[20]
* @classes_as_structs - class f becomes struct f, CTF doesn't have a "class"
dwarves_fprintf: Fixup cacheline boundary printing on expanded structs A diff for 'pahole -EC task_struct vmlinux' should clarify what this fixes: [acme@jouet linux]$ diff -u /tmp/before.c /tmp/after.c | head -30 --- /tmp/before.c 2016-06-29 17:00:38.082647281 -0300 +++ /tmp/a.c 2016-06-29 17:03:36.913124779 -0300 @@ -43,8 +43,8 @@ struct list_head * prev; /* 176 8 */ } group_node; /* 168 16 */ unsigned int on_rq; /* 184 4 */ + /* --- cacheline 3 boundary (192 bytes) --- */ /* typedef u64 */ long long unsigned int exec_start; /* 192 8 */ - /* --- cacheline 1 boundary (64 bytes) was 4 bytes ago --- */ /* typedef u64 */ long long unsigned int sum_exec_runtime; /* 200 8 */ /* typedef u64 */ long long unsigned int vruntime; /* 208 8 */ /* typedef u64 */ long long unsigned int prev_sum_exec_runtime; /* 216 8 */ @@ -53,40 +53,40 @@ /* typedef u64 */ long long unsigned int wait_start; /* 232 8 */ /* typedef u64 */ long long unsigned int wait_max; /* 240 8 */ /* typedef u64 */ long long unsigned int wait_count; /* 248 8 */ + /* --- cacheline 4 boundary (256 bytes) --- */ /* typedef u64 */ long long unsigned int wait_sum; /* 256 8 */ /* typedef u64 */ long long unsigned int iowait_count; /* 264 8 */ /* typedef u64 */ long long unsigned int iowait_sum; /* 272 8 */ /* typedef u64 */ long long unsigned int sleep_start; /* 280 8 */ /* typedef u64 */ long long unsigned int sleep_max; /* 288 8 */ - /* --- cacheline 1 boundary (64 bytes) --- */ /* typedef s64 */ long long int sum_sleep_runtime; /* 296 8 */ /* typedef u64 */ long long unsigned int block_start; /* 304 8 */ /* typedef u64 */ long long unsigned int block_max; /* 312 8 */ + /* --- cacheline 5 boundary (320 bytes) --- */ /* typedef u64 */ long long unsigned int exec_max; /* 320 8 */ /* typedef u64 */ long long unsigned int slice_max; /* 328 8 */ /* typedef u64 */ long long unsigned int nr_migrations_cold; /* 336 8 */ [acme@jouet linux]$ I.e. the boundary detection was being reset at each expanded struct, do the math globally, using the member offset, that was already done globally and correctly. Reported-and-Tested-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-06-29 22:27:51 +02:00
* @cachelinep - pointer to current cacheline, so that when expanding types we keep track of it,
* needs to be "global", i.e. not set at each recursion.
*/
struct conf_fprintf {
const char *prefix;
const char *suffix;
int32_t type_spacing;
int32_t name_spacing;
uint32_t base_offset;
dwarves_fprintf: Fixup cacheline boundary printing on expanded structs A diff for 'pahole -EC task_struct vmlinux' should clarify what this fixes: [acme@jouet linux]$ diff -u /tmp/before.c /tmp/after.c | head -30 --- /tmp/before.c 2016-06-29 17:00:38.082647281 -0300 +++ /tmp/a.c 2016-06-29 17:03:36.913124779 -0300 @@ -43,8 +43,8 @@ struct list_head * prev; /* 176 8 */ } group_node; /* 168 16 */ unsigned int on_rq; /* 184 4 */ + /* --- cacheline 3 boundary (192 bytes) --- */ /* typedef u64 */ long long unsigned int exec_start; /* 192 8 */ - /* --- cacheline 1 boundary (64 bytes) was 4 bytes ago --- */ /* typedef u64 */ long long unsigned int sum_exec_runtime; /* 200 8 */ /* typedef u64 */ long long unsigned int vruntime; /* 208 8 */ /* typedef u64 */ long long unsigned int prev_sum_exec_runtime; /* 216 8 */ @@ -53,40 +53,40 @@ /* typedef u64 */ long long unsigned int wait_start; /* 232 8 */ /* typedef u64 */ long long unsigned int wait_max; /* 240 8 */ /* typedef u64 */ long long unsigned int wait_count; /* 248 8 */ + /* --- cacheline 4 boundary (256 bytes) --- */ /* typedef u64 */ long long unsigned int wait_sum; /* 256 8 */ /* typedef u64 */ long long unsigned int iowait_count; /* 264 8 */ /* typedef u64 */ long long unsigned int iowait_sum; /* 272 8 */ /* typedef u64 */ long long unsigned int sleep_start; /* 280 8 */ /* typedef u64 */ long long unsigned int sleep_max; /* 288 8 */ - /* --- cacheline 1 boundary (64 bytes) --- */ /* typedef s64 */ long long int sum_sleep_runtime; /* 296 8 */ /* typedef u64 */ long long unsigned int block_start; /* 304 8 */ /* typedef u64 */ long long unsigned int block_max; /* 312 8 */ + /* --- cacheline 5 boundary (320 bytes) --- */ /* typedef u64 */ long long unsigned int exec_max; /* 320 8 */ /* typedef u64 */ long long unsigned int slice_max; /* 328 8 */ /* typedef u64 */ long long unsigned int nr_migrations_cold; /* 336 8 */ [acme@jouet linux]$ I.e. the boundary detection was being reset at each expanded struct, do the math globally, using the member offset, that was already done globally and correctly. Reported-and-Tested-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-06-29 22:27:51 +02:00
uint32_t *cachelinep;
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;
uint8_t flat_arrays:1;
uint8_t no_parm_names:1;
uint8_t classes_as_structs:1;
uint8_t hex_fmt:1;
};
struct cus {
struct list_head cus;
};
struct cus *cus__new(void);
void cus__delete(struct cus *cus);
int cus__load_file(struct cus *cus, struct conf_load *conf,
const char *filename);
int cus__load_files(struct cus *cus, struct conf_load *conf,
char *filenames[]);
int cus__fprintf_load_files_err(struct cus *cus, const char *tool,
char *argv[], int err, FILE *output);
int cus__load_dir(struct cus *cus, struct conf_load *conf,
const char *dirname, const char *filename_mask,
const int recursive);
void cus__add(struct cus *cus, struct cu *cu);
void cus__print_error_msg(const char *progname, const struct cus *cus,
const char *filename, const int err);
struct cu *cus__find_cu_by_name(const struct cus *cus, const char *name);
struct tag *cus__find_struct_by_name(const struct cus *cus, struct cu **cu,
const char *name, const int include_decls,
uint16_t *id);
struct function *cus__find_function_at_addr(const struct cus *cus,
uint64_t addr, struct cu **cu);
void cus__for_each_cu(struct cus *cus, int (*iterator)(struct cu *cu, void *cookie),
void *cookie,
struct cu *(*filter)(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
struct ptr_table {
void **entries;
uint32_t nr_entries;
uint32_t allocated_entries;
};
struct function;
struct tag;
struct cu;
struct variable;
/* Same as DW_LANG, so that we don't have to include dwarf.h in CTF */
enum dwarf_languages {
LANG_C89 = 0x01, /* ISO C:1989 */
LANG_C = 0x02, /* C */
LANG_Ada83 = 0x03, /* ISO Ada:1983 */
LANG_C_plus_plus = 0x04, /* ISO C++:1998 */
LANG_Cobol74 = 0x05, /* ISO Cobol:1974 */
LANG_Cobol85 = 0x06, /* ISO Cobol:1985 */
LANG_Fortran77 = 0x07, /* ISO FORTRAN 77 */
LANG_Fortran90 = 0x08, /* ISO Fortran 90 */
LANG_Pascal83 = 0x09, /* ISO Pascal:1983 */
LANG_Modula2 = 0x0a, /* ISO Modula-2:1996 */
LANG_Java = 0x0b, /* Java */
LANG_C99 = 0x0c, /* ISO C:1999 */
LANG_Ada95 = 0x0d, /* ISO Ada:1995 */
LANG_Fortran95 = 0x0e, /* ISO Fortran 95 */
LANG_PL1 = 0x0f, /* ISO PL/1:1976 */
LANG_Objc = 0x10, /* Objective-C */
LANG_ObjC_plus_plus = 0x11, /* Objective-C++ */
LANG_UPC = 0x12, /* Unified Parallel C */
LANG_D = 0x13, /* D */
};
/** struct debug_fmt_ops - specific to the underlying debug file format
*
* @function__name - will be called by function__name(), giving a chance to
* formats such as CTF to get this from some other place
* than the global strings table. CTF does this by storing
* GElf_Sym->st_name in function->name, and by using
* function->name as an index into the .strtab ELF section.
* @variable__name - will be called by variable__name(), see @function_name
* cu__delete - called at cu__delete(), to give a chance to formats such as
* CTF to keep the .strstab ELF section available till the cu is
* deleted. See @function__name
*/
struct debug_fmt_ops {
const char *name;
int (*init)(void);
void (*exit)(void);
int (*load_file)(struct cus *cus,
struct conf_load *conf,
const char *filename);
const char *(*tag__decl_file)(const struct tag *tag,
const struct cu *cu);
uint32_t (*tag__decl_line)(const struct tag *tag,
const struct cu *cu);
unsigned long long (*tag__orig_id)(const struct tag *tag,
const struct cu *cu);
void (*tag__free_orig_info)(struct tag *tag,
struct cu *cu);
const char *(*function__name)(struct function *tag,
const struct cu *cu);
const char *(*variable__name)(const struct variable *var,
const struct cu *cu);
const char *(*strings__ptr)(const struct cu *cu, strings_t s);
void (*cu__delete)(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 */
struct ptr_table types_table;
struct ptr_table functions_table;
struct ptr_table tags_table;
struct rb_root functions;
char *name;
char *filename;
void *priv;
struct obstack obstack;
struct debug_fmt_ops *dfops;
Elf *elf;
Dwfl_Module *dwfl;
uint32_t cached_symtab_nr_entries;
uint8_t addr_size;
uint8_t extra_dbg_info:1;
dwarves: Allow avoiding loading addr information As, for instance, pahole doesn't need it at all. Down from: [acme@doppio pahole]$ perf stat -r 5 pahole object_samples/zweinberg\@mozilla.com/libgklayout.so > /dev/null Performance counter stats for 'pahole object_samples/zweinberg@mozilla.com/libgklayout.so' (5 runs): 17233.989563 task-clock-msecs # 0.994 CPUs ( +- 0.076% ) 1880 context-switches # 0.000 M/sec ( +- 0.159% ) 0 CPU-migrations # 0.000 M/sec ( +- 0.000% ) 26248 page-faults # 0.002 M/sec ( +- 0.000% ) 34244461105 cycles # 1987.030 M/sec ( +- 0.078% ) 34510583834 instructions # 1.008 IPC ( +- 0.001% ) 445937867 cache-references # 25.875 M/sec ( +- 0.160% ) 56898165 cache-misses # 3.302 M/sec ( +- 0.074% ) 17.335292038 seconds time elapsed ( +- 0.076% ) [acme@doppio pahole]$ To: [acme@doppio pahole]$ perf stat -r 5 pahole object_samples/zweinberg\@mozilla.com/libgklayout.so > /dev/null Performance counter stats for 'pahole object_samples/zweinberg@mozilla.com/libgklayout.so' (5 runs): 16511.627334 task-clock-msecs # 0.992 CPUs ( +- 0.208% ) 1922 context-switches # 0.000 M/sec ( +- 3.068% ) 0 CPU-migrations # 0.000 M/sec ( +- 0.000% ) 25570 page-faults # 0.002 M/sec ( +- 0.000% ) 32807624343 cycles # 1986.941 M/sec ( +- 0.208% ) 32711598374 instructions # 0.997 IPC ( +- 0.001% ) 436345377 cache-references # 26.427 M/sec ( +- 0.178% ) 54044997 cache-misses # 3.273 M/sec ( +- 0.685% ) 16.652951166 seconds time elapsed ( +- 0.304% ) [acme@doppio pahole]$ Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-07-06 18:44:57 +02:00
uint8_t has_addr_info:1;
uint8_t uses_global_strings:1;
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];
};
struct cu *cu__new(const char *name, uint8_t addr_size,
const unsigned char *build_id, int build_id_len,
const char *filename);
void cu__delete(struct cu *cu);
const char *cu__string(const struct cu *cu, strings_t s);
static inline int cu__cache_symtab(struct cu *cu)
{
int err = dwfl_module_getsymtab(cu->dwfl);
if (err > 0)
cu->cached_symtab_nr_entries = dwfl_module_getsymtab(cu->dwfl);
return err;
}
static inline __pure bool cu__is_c_plus_plus(const struct cu *cu)
{
return cu->language == LANG_C_plus_plus;
}
/**
* cu__for_each_cached_symtab_entry - iterate thru the cached symtab entries
* @cu: struct cu instance
* @id: uint32_t tag id
* @pos: struct GElf_Sym iterator
* @name: char pointer where the symbol_name will be stored
*/
#define cu__for_each_cached_symtab_entry(cu, id, pos, name) \
for (id = 1, \
name = dwfl_module_getsym(cu->dwfl, id, &sym, NULL); \
id < cu->cached_symtab_nr_entries; \
++id, name = dwfl_module_getsym(cu->dwfl, id, &sym, NULL))
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_type - iterate thru all the type tags
* @cu: struct cu instance to iterate
* @id: uint16_t tag id
* @pos: struct tag iterator
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
*
* 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; id < cu->types_table.nr_entries; ++id) \
if (!(pos = cu->types_table.entries[id])) \
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
/**
* 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 = 1; id < cu->types_table.nr_entries; ++id) \
if (!(pos = tag__class(cu->types_table.entries[id])) || \
!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; id < cu->functions_table.nr_entries; ++id) \
if (!(pos = tag__function(cu->functions_table.entries[id]))) \
continue; \
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
else
/**
* cu__for_each_variable - iterate thru all the global variable tags
* @cu: struct cu instance to iterate
* @pos: struct tag iterator
* @id: uint32_t tag id
*/
#define cu__for_each_variable(cu, id, pos) \
for (id = 0; id < cu->tags_table.nr_entries; ++id) \
if (!(pos = cu->tags_table.entries[id]) || \
!tag__is_variable(pos)) \
continue; \
else
int cu__add_tag(struct cu *cu, struct tag *tag, long *id);
int cu__table_add_tag(struct cu *cu, struct tag *tag, long *id);
int cu__table_nullify_type_entry(struct cu *cu, uint32_t id);
struct tag *cu__find_base_type_by_name(const struct cu *cu, const char *name,
uint16_t *id);
struct tag *cu__find_base_type_by_sname_and_size(const struct cu *cu,
strings_t name,
uint16_t bit_size,
uint16_t *idp);
struct tag *cu__find_enumeration_by_sname_and_size(const struct cu *cu,
strings_t sname,
uint16_t bit_size,
uint16_t *idp);
struct tag *cu__find_first_typedef_of_type(const struct cu *cu,
const uint16_t type);
struct tag *cu__find_function_by_name(const struct cu *cu, const char *name);
struct tag *cu__find_struct_by_sname(const struct cu *cu, strings_t sname,
const int include_decls, uint16_t *idp);
struct function *cu__find_function_at_addr(const struct cu *cu,
uint64_t addr);
struct tag *cu__function(const struct cu *cu, const uint32_t id);
struct tag *cu__tag(const struct cu *cu, const uint32_t id);
struct tag *cu__type(const struct cu *cu, const uint16_t id);
struct tag *cu__find_struct_by_name(const struct cu *cu, const char *name,
const int include_decls, uint16_t *id);
bool cu__same_build_id(const struct cu *cu, const struct cu *other);
void cu__account_inline_expansions(struct cu *cu);
int cu__for_all_tags(struct cu *cu,
int (*iterator)(struct tag *tag,
struct cu *cu, void *cookie),
void *cookie);
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 -
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 {
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;
bool visited;
bool top_level;
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 recursivity_level;
void *priv;
};
void tag__delete(struct tag *tag, struct cu *cu);
static inline int tag__is_enumeration(const struct tag *tag)
{
return tag->tag == DW_TAG_enumeration_type;
}
static inline int tag__is_namespace(const struct tag *tag)
{
return tag->tag == DW_TAG_namespace;
}
static inline int tag__is_struct(const struct tag *tag)
{
return tag->tag == DW_TAG_structure_type ||
tag->tag == DW_TAG_interface_type ||
tag->tag == DW_TAG_class_type;
}
static inline int tag__is_typedef(const struct tag *tag)
{
return tag->tag == DW_TAG_typedef;
}
static inline int tag__is_rvalue_reference_type(const struct tag *tag)
{
return tag->tag == DW_TAG_rvalue_reference_type;
}
static inline int tag__is_union(const struct tag *tag)
{
return tag->tag == DW_TAG_union_type;
}
static inline int tag__is_const(const struct tag *tag)
{
return tag->tag == DW_TAG_const_type;
}
static inline bool tag__is_variable(const struct tag *tag)
{
return tag->tag == DW_TAG_variable;
}
static inline bool tag__is_volatile(const struct tag *tag)
{
return tag->tag == DW_TAG_volatile_type;
}
static inline bool tag__has_namespace(const struct tag *tag)
{
return tag__is_struct(tag) ||
tag__is_union(tag) ||
tag__is_namespace(tag) ||
tag__is_enumeration(tag);
}
/**
* tag__is_tag_type - is this tag derived from the 'type' class?
* @tag - tag queried
*/
static inline int tag__is_type(const struct tag *tag)
{
return tag__is_union(tag) ||
tag__is_struct(tag) ||
tag__is_typedef(tag) ||
tag__is_rvalue_reference_type(tag) ||
tag__is_enumeration(tag);
}
/**
* 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 *tag)
{
return tag__is_type(tag) ||
tag->tag == DW_TAG_array_type ||
tag->tag == DW_TAG_base_type ||
tag->tag == DW_TAG_const_type ||
tag->tag == DW_TAG_pointer_type ||
tag->tag == DW_TAG_rvalue_reference_type ||
tag->tag == DW_TAG_ptr_to_member_type ||
tag->tag == DW_TAG_reference_type ||
dwarf_loader: Add support for DW_TAG_restrict_type I.e. supporting the 'restrict' keyword, emitted by recent compilers: [acme@jouet pahole]$ pfunct -P ~/bin/perf |& grep -w restrict inline int vprintf(const char * restrict __fmt, struct __va_list_tag * __ap); inline size_t fread(void * restrict __ptr, size_t __size, size_t __n, FILE * restrict __stream); inline int vfprintf(FILE * restrict __stream, const char * restrict __fmt, struct __va_list_tag * __ap); inline int vasprintf(char * * restrict __ptr, const char * restrict __fmt, struct __va_list_tag * __ap); inline char * realpath(const char * restrict __name, char * restrict __resolved); inline ssize_t readlink(const char * restrict __path, char * restrict __buf, size_t __len); inline char * strcat(char * restrict __dest, const char * restrict __src); inline char * fgets(char * restrict __s, int __n, FILE * restrict __stream); inline int snprintf(char * restrict __s, size_t __n, const char * restrict __fmt, ...); inline int sprintf(char * restrict __s, const char * restrict __fmt, ...); inline char * strcpy(char * restrict __dest, const char * restrict __src); inline int asprintf(char * * restrict __ptr, const char * restrict __fmt, ...); inline char * strncpy(char * restrict __dest, const char * restrict __src, size_t __len); inline int fprintf(FILE * restrict __stream, const char * restrict __fmt, ...); inline int vsnprintf(char * restrict __s, size_t __n, const char * restrict __fmt, struct __va_list_tag * __ap); inline int printf(const char * restrict __fmt, ...); [acme@jouet pahole]$ Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-06 20:02:17 +02:00
tag->tag == DW_TAG_restrict_type ||
tag->tag == DW_TAG_subroutine_type ||
tag->tag == DW_TAG_unspecified_type ||
tag->tag == DW_TAG_volatile_type;
}
static inline const char *tag__decl_file(const struct tag *tag,
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 struct cu *cu)
{
if (cu->dfops && cu->dfops->tag__decl_file)
return cu->dfops->tag__decl_file(tag, cu);
return NULL;
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 uint32_t tag__decl_line(const struct tag *tag,
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 struct cu *cu)
{
if (cu->dfops && cu->dfops->tag__decl_line)
return cu->dfops->tag__decl_line(tag, cu);
return 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
}
static inline unsigned long long tag__orig_id(const struct tag *tag,
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 struct cu *cu)
{
if (cu->dfops && cu->dfops->tag__orig_id)
return cu->dfops->tag__orig_id(tag, cu);
return 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
}
static inline void tag__free_orig_info(struct tag *tag, struct cu *cu)
{
if (cu->dfops && cu->dfops->tag__free_orig_info)
cu->dfops->tag__free_orig_info(tag, cu);
}
size_t tag__fprintf_decl_info(const struct tag *tag,
const struct cu *cu, FILE *fp);
size_t tag__fprintf(struct tag *tag, const struct cu *cu,
const struct conf_fprintf *conf, FILE *fp);
const char *tag__name(const struct tag *tag, const struct cu *cu,
char *bf, size_t len, const struct conf_fprintf *conf);
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)
size_t tag__size(const struct tag *tag, const struct cu *cu);
size_t tag__nr_cachelines(const struct tag *tag, const struct cu *cu);
struct tag *tag__follow_typedef(const struct tag *tag, const struct cu *cu);
size_t __tag__id_not_found_fprintf(FILE *fp, uint16_t id,
const char *fn, int line);
#define tag__id_not_found_fprintf(fp, id) \
__tag__id_not_found_fprintf(fp, id, __func__, __LINE__)
int __tag__has_type_loop(const struct tag *tag, const struct tag *type,
char *bf, size_t len, FILE *fp,
const char *fn, int line);
#define tag__has_type_loop(tag, type, bf, len, fp) \
__tag__has_type_loop(tag, type, bf, len, fp, __func__, __LINE__)
struct ptr_to_member_type {
struct tag tag;
uint16_t containing_type;
};
static inline struct ptr_to_member_type *
tag__ptr_to_member_type(const struct tag *tag)
{
return (struct ptr_to_member_type *)tag;
}
/** struct namespace - base class for enums, structs, unions, typedefs, etc
*
* @sname - for clones, for instance, where we can't always add a new string
* @tags - class_member, enumerators, etc
* @shared_tags: if this bit is set, don't free the entries in @tags
*/
struct namespace {
struct tag tag;
strings_t name;
uint16_t nr_tags;
uint8_t shared_tags;
char * sname;
struct list_head tags;
};
static inline struct namespace *tag__namespace(const struct tag *tag)
{
return (struct namespace *)tag;
}
void namespace__delete(struct namespace *nspace, struct cu *cu);
/**
* namespace__for_each_tag - iterate thru all the tags
* @nspace: struct namespace instance to iterate
* @pos: struct tag iterator
*/
#define namespace__for_each_tag(nspace, pos) \
list_for_each_entry(pos, &(nspace)->tags, node)
/**
* namespace__for_each_tag_safe_reverse - safely iterate thru all the tags, in reverse order
* @nspace: struct namespace instance to iterate
* @pos: struct tag iterator
* @n: struct class_member temp iterator
*/
#define namespace__for_each_tag_safe_reverse(nspace, pos, n) \
list_for_each_entry_safe_reverse(pos, n, &(nspace)->tags, node)
void namespace__add_tag(struct namespace *nspace, struct tag *tag);
struct ip_tag {
struct tag tag;
uint64_t addr;
};
struct inline_expansion {
struct ip_tag ip;
size_t size;
uint64_t high_pc;
};
static inline struct inline_expansion *
tag__inline_expansion(const struct tag *tag)
{
return (struct inline_expansion *)tag;
}
struct label {
struct ip_tag ip;
strings_t name;
};
static inline struct label *tag__label(const struct tag *tag)
{
return (struct label *)tag;
}
static inline const char *label__name(const struct label *label,
const struct cu *cu)
{
return cu__string(cu, label->name);
}
enum vscope {
VSCOPE_UNKNOWN,
VSCOPE_LOCAL,
VSCOPE_GLOBAL,
VSCOPE_REGISTER,
VSCOPE_OPTIMIZED
} __attribute__((packed));
struct location {
Dwarf_Op *expr;
size_t exprlen;
};
struct variable {
struct ip_tag ip;
strings_t name;
uint8_t external:1;
uint8_t declaration:1;
enum vscope scope;
struct location location;
struct hlist_node tool_hnode;
};
static inline struct variable *tag__variable(const struct tag *tag)
{
return (struct variable *)tag;
}
enum vscope variable__scope(const struct variable *var);
const char *variable__name(const struct variable *var, const struct cu *cu);
const char *variable__type_name(const struct variable *var,
const struct cu *cu, char *bf, size_t len);
struct lexblock {
struct ip_tag ip;
struct list_head tags;
uint32_t size;
uint16_t nr_inline_expansions;
uint16_t nr_labels;
uint16_t nr_variables;
uint16_t nr_lexblocks;
uint32_t size_inline_expansions;
};
static inline struct lexblock *tag__lexblock(const struct tag *tag)
{
return (struct lexblock *)tag;
}
void lexblock__delete(struct lexblock *lexblock, struct cu *cu);
struct function;
void lexblock__add_inline_expansion(struct lexblock *lexblock,
struct inline_expansion *exp);
void lexblock__add_label(struct lexblock *lexblock, struct label *label);
void lexblock__add_lexblock(struct lexblock *lexblock, struct lexblock *child);
void lexblock__add_tag(struct lexblock *lexblock, struct tag *tag);
void lexblock__add_variable(struct lexblock *lexblock, struct variable *var);
size_t lexblock__fprintf(const struct lexblock *lexblock, const struct cu *cu,
struct function *function, uint16_t indent,
const struct conf_fprintf *conf, FILE *fp);
struct parameter {
struct tag tag;
strings_t name;
};
static inline struct parameter *tag__parameter(const struct tag *tag)
{
return (struct parameter *)tag;
}
static inline const char *parameter__name(const struct parameter *parm,
const struct cu *cu)
{
return cu__string(cu, parm->name);
}
/*
* 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 *tag)
{
return (struct ftype *)tag;
}
void ftype__delete(struct ftype *ftype, struct cu *cu);
/**
* ftype__for_each_parameter - iterate thru all the parameters
* @ftype: struct ftype instance to iterate
* @pos: struct parameter iterator
*/
#define ftype__for_each_parameter(ftype, pos) \
list_for_each_entry(pos, &(ftype)->parms, tag.node)
/**
* ftype__for_each_parameter_safe - safely iterate thru all the parameters
* @ftype: struct ftype instance to iterate
* @pos: struct parameter iterator
* @n: struct parameter temp iterator
*/
#define ftype__for_each_parameter_safe(ftype, pos, n) \
list_for_each_entry_safe(pos, n, &(ftype)->parms, tag.node)
/**
* ftype__for_each_parameter_safe_reverse - safely iterate thru all the parameters, in reverse order
* @ftype: struct ftype instance to iterate
* @pos: struct parameter iterator
* @n: struct parameter temp iterator
*/
#define ftype__for_each_parameter_safe_reverse(ftype, pos, n) \
list_for_each_entry_safe_reverse(pos, n, &(ftype)->parms, tag.node)
void ftype__add_parameter(struct ftype *ftype, struct parameter *parm);
size_t ftype__fprintf(const struct ftype *ftype, const struct cu *cu,
const char *name, const int inlined,
const int is_pointer, const int type_spacing,
const struct conf_fprintf *conf, FILE *fp);
size_t ftype__fprintf_parms(const struct ftype *ftype,
const struct cu *cu, int indent,
const struct conf_fprintf *conf, FILE *fp);
int ftype__has_parm_of_type(const struct ftype *ftype, const uint16_t target,
const struct cu *cu);
struct function {
struct ftype proto;
struct lexblock lexblock;
struct rb_node rb_node;
strings_t name;
strings_t linkage_name;
uint32_t cu_total_size_inline_expansions;
uint16_t cu_total_nr_inline_expansions;
uint8_t inlined:2;
uint8_t abstract_origin:1;
uint8_t external:1;
uint8_t accessibility:2; /* DW_ACCESS_{public,protected,private} */
uint8_t virtuality:2; /* DW_VIRTUALITY_{none,virtual,pure_virtual} */
int32_t vtable_entry;
struct list_head vtable_node;
/* fields used by tools */
ctf_encoder: Convert DWARF functions to CTF Finally we can use the Elf file already opened in dwarf_load, call cu__for_each_cached_symtab_entry to iterate over the symtab entries, this iterator will first call dwfl_module_getsymtab, that will do the relocation that will allow us to go from the symtab address to the one in the DWARF DW_TAG_subprogram tag DW_AT_low_pc attribute. And voila, for a relatively complex single unit Linux kernel object file, kernel/sched.o, we go from: Just DWARF (gcc -g): $ ls -la kernel/sched.o 1979011 kernel/sched.o Then we run this to encode the CTF section: $ pahole -Z kernel/sched.o And get a file with both DWARF and CTF ELF sections: $ ls -la kernel/sched.o 2019848 kernel/sched.o We still need to encode the "OBJECTS", i.e. variables, but this gets us from 1979011 (just DWARF) to: $ strip--strip-debug kernel/sched.o $ ls -la kernel/sched.o -rw-rw-r-- 1 acme acme 507008 2009-03-30 23:01 kernel/sched.o 25% of the original size. Of course we don't have inline expansion information, parameter names, goto labels, etc, but should be good enough for most use cases. See, without DWARF data, if we ask for it to use DWARF, nothing will be printed, if we don't speficy the format, it will try first DWARF, it will not find anything, it will try CTF: $ pahole -F dwarf kernel/sched.o $ pahole -C seq_operations kernel/sched.o struct seq_operations { void * (*start)(struct seq_file *, loff_t *); /* 0 8 */ void (*stop)(struct seq_file *, void *); /* 8 8 */ void * (*next)(struct seq_file *, void *, loff_t *); /* 16 8 */ int (*show)(struct seq_file *, void *); /* 24 8 */ /* size: 32, cachelines: 1, members: 4 */ /* last cacheline: 32 bytes */ }; $ $ pfunct -Vi -f schedule kernel/sched.o void schedule(void); { /* low_pc=0xe01 */ }/* size: 83 */ $ Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-31 03:54:29 +02:00
union {
struct list_head tool_node;
struct hlist_node tool_hnode;
};
void *priv;
};
static inline struct function *tag__function(const struct tag *tag)
{
return (struct function *)tag;
}
static inline struct tag *function__tag(const struct function *func)
{
return (struct tag *)func;
}
void function__delete(struct function *func, struct cu *cu);
static __pure inline int tag__is_function(const struct tag *tag)
{
return tag->tag == DW_TAG_subprogram;
}
/**
* function__for_each_parameter - iterate thru all the parameters
* @func: struct function instance to iterate
* @pos: struct parameter iterator
*/
#define function__for_each_parameter(func, pos) \
ftype__for_each_parameter(&func->proto, pos)
const char *function__name(struct function *func, const struct cu *cu);
static inline const char *function__linkage_name(const struct function *func,
const struct cu *cu)
{
return cu__string(cu, func->linkage_name);
}
size_t function__fprintf_stats(const struct tag *tag_func,
const struct cu *cu,
const struct conf_fprintf *conf,
FILE *fp);
const char *function__prototype(const struct function *func,
const struct cu *cu, char *bf, size_t len);
static __pure inline uint64_t function__addr(const struct function *func)
{
return func->lexblock.ip.addr;
}
static __pure inline uint32_t function__size(const struct function *func)
{
return func->lexblock.size;
}
static inline int function__declared_inline(const struct function *func)
{
return (func->inlined == DW_INL_declared_inlined ||
func->inlined == DW_INL_declared_not_inlined);
}
static inline int function__inlined(const struct function *func)
{
return (func->inlined == DW_INL_inlined ||
func->inlined == DW_INL_declared_inlined);
}
/* struct class_member - struct, union, class member
*
* @bit_offset - offset in bits from the start of the struct
* @bit_size - cached bit size, can be smaller than the integral type if in a bitfield
* @byte_offset - offset in bytes from the start of the struct
* @byte_size - cached byte size, integral type byte size for bitfields
* @bitfield_offset - offset in the current bitfield
* @bitfield_offset - size in the current bitfield
* @bit_hole - If there is a bit hole before the next one (or the end of the struct)
* @bitfield_end - Is this the last entry in a bitfield?
* @accessibility - DW_ACCESS_{public,protected,private}
* @virtuality - DW_VIRTUALITY_{none,virtual,pure_virtual}
* @hole - If there is a hole before the next one (or the end of the struct)
*/
struct class_member {
struct tag tag;
strings_t name;
uint32_t bit_offset;
uint32_t bit_size;
uint32_t byte_offset;
size_t byte_size;
uint8_t bitfield_offset;
uint8_t bitfield_size;
uint8_t bit_hole;
uint8_t bitfield_end:1;
uint64_t const_value;
uint8_t visited:1;
uint8_t is_static:1;
uint8_t accessibility:2;
uint8_t virtuality:2;
uint16_t hole;
[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
};
void class_member__delete(struct class_member *member, struct cu *cu);
static inline struct class_member *tag__class_member(const struct tag *tag)
{
return (struct class_member *)tag;
}
static inline const char *class_member__name(const struct class_member *member,
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__string(cu, member->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
}
static __pure inline int tag__is_class_member(const struct tag *tag)
{
return tag->tag == DW_TAG_member;
}
/**
* struct type - base type for enumerations, structs and unions
*
* @nnr_members: number of non static DW_TAG_member entries
* @nr_static_members: number of static DW_TAG_member entries
* @nr_tags: number of tags
*/
struct type {
struct namespace namespace;
struct list_head node;
uint32_t size;
int32_t size_diff;
uint16_t nr_static_members;
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 *type)
{
return (struct class *)type;
}
[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
void type__delete(struct type *type, struct cu *cu);
/**
* type__for_each_tag - iterate thru all the tags
* @type: struct type instance to iterate
* @pos: struct tag iterator
*/
#define type__for_each_tag(type, pos) \
list_for_each_entry(pos, &(type)->namespace.tags, node)
/**
* type__for_each_enumerator - iterate thru the enumerator entries
* @type: struct type instance to iterate
* @pos: struct enumerator iterator
*/
#define type__for_each_enumerator(type, pos) \
struct list_head *__type__for_each_enumerator_head = \
(type)->namespace.shared_tags ? \
(type)->namespace.tags.next : \
&(type)->namespace.tags; \
list_for_each_entry(pos, __type__for_each_enumerator_head, tag.node)
/**
* type__for_each_enumerator_safe_reverse - safely iterate thru the enumerator entries, in reverse order
* @type: struct type instance to iterate
* @pos: struct enumerator iterator
* @n: struct enumerator temp iterator
*/
#define type__for_each_enumerator_safe_reverse(type, pos, n) \
if ((type)->namespace.shared_tags) /* Do nothing */ ; else \
list_for_each_entry_safe_reverse(pos, n, &(type)->namespace.tags, tag.node)
/**
* type__for_each_member - iterate thru the entries that use space
* (data members and inheritance entries)
* @type: struct type instance to iterate
* @pos: struct class_member iterator
*/
#define type__for_each_member(type, pos) \
list_for_each_entry(pos, &(type)->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
* @type: struct type instance to iterate
* @pos: struct class_member iterator
*/
#define type__for_each_data_member(type, pos) \
list_for_each_entry(pos, &(type)->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)
* @type: struct type instance to iterate
* @pos: struct class_member iterator
* @n: struct class_member temp iterator
*/
#define type__for_each_member_safe(type, pos, n) \
list_for_each_entry_safe(pos, n, &(type)->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
* @type: struct type instance to iterate
* @pos: struct class_member iterator
* @n: struct class_member temp iterator
*/
#define type__for_each_data_member_safe(type, pos, n) \
list_for_each_entry_safe(pos, n, &(type)->namespace.tags, tag.node) \
if (pos->tag.tag != DW_TAG_member) \
continue; \
else
/**
* type__for_each_tag_safe_reverse - safely iterate thru all tags in a type, in reverse order
* @type: struct type instance to iterate
* @pos: struct class_member iterator
* @n: struct class_member temp iterator
*/
#define type__for_each_tag_safe_reverse(type, pos, n) \
list_for_each_entry_safe_reverse(pos, n, &(type)->namespace.tags, tag.node)
void type__add_member(struct type *type, struct class_member *member);
struct class_member *
type__find_first_biggest_size_base_type_member(struct type *type,
const struct cu *cu);
struct class_member *type__find_member_by_name(const struct type *type,
const struct cu *cu,
const char *name);
uint32_t type__nr_members_of_type(const struct type *type, const uint16_t oftype);
struct class_member *type__last_member(struct type *type);
size_t typedef__fprintf(const struct tag *tag_type, const struct cu *cu,
const struct conf_fprintf *conf, FILE *fp);
static inline struct type *tag__type(const struct tag *tag)
{
return (struct type *)tag;
}
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;
bool holes_searched;
void *priv;
};
static inline struct class *tag__class(const struct tag *tag)
{
return (struct class *)tag;
}
static inline struct tag *class__tag(const struct class *cls)
{
return (struct tag *)cls;
}
struct class *class__clone(const struct class *from,
const char *new_class_name, struct cu *cu);
void class__delete(struct class *cls, struct cu *cu);
static inline struct list_head *class__tags(struct class *cls)
{
return &cls->type.namespace.tags;
}
static __pure inline const char *namespace__name(const struct namespace *nspace,
const struct cu *cu)
{
return nspace->sname ?: cu__string(cu, nspace->name);
}
static __pure inline const char *type__name(const struct type *type,
const struct cu *cu)
{
return namespace__name(&type->namespace, cu);
}
static __pure inline const char *class__name(struct class *cls,
const struct cu *cu)
{
return type__name(&cls->type, cu);
}
static inline int class__is_struct(const struct class *cls)
{
return tag__is_struct(&cls->type.namespace.tag);
}
void class__find_holes(struct class *cls);
int class__has_hole_ge(const struct class *cls, const uint16_t size);
size_t class__fprintf(struct class *cls, const struct cu *cu, FILE *fp);
void class__add_vtable_entry(struct class *cls, struct function *vtable_entry);
static inline struct class_member *
class__find_member_by_name(const struct class *cls,
const struct cu *cu, const char *name)
{
return type__find_member_by_name(&cls->type, cu, name);
}
static inline uint16_t class__nr_members(const struct class *cls)
{
return cls->type.nr_members;
}
static inline uint32_t class__size(const struct class *cls)
{
return cls->type.size;
}
static inline int class__is_declaration(const struct class *cls)
{
return cls->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
const struct class_member *class__find_bit_hole(const struct class *cls,
const struct class_member *trailer,
const uint16_t bit_hole_size);
enum base_type_float_type {
BT_FP_SINGLE = 1,
BT_FP_DOUBLE,
BT_FP_CMPLX,
BT_FP_CMPLX_DBL,
BT_FP_CMPLX_LDBL,
BT_FP_LDBL,
BT_FP_INTVL,
BT_FP_INTVL_DBL,
BT_FP_INTVL_LDBL,
BT_FP_IMGRY,
BT_FP_IMGRY_DBL,
BT_FP_IMGRY_LDBL
};
struct base_type {
struct tag tag;
strings_t name;
uint16_t bit_size;
uint8_t name_has_encoding:1;
uint8_t is_signed:1;
uint8_t is_bool:1;
uint8_t is_varargs:1;
uint8_t float_type:4;
};
static inline struct base_type *tag__base_type(const struct tag *tag)
{
return (struct base_type *)tag;
}
static inline uint16_t base_type__size(const struct tag *tag)
{
return tag__base_type(tag)->bit_size / 8;
}
const char *base_type__name(const struct base_type *btype, const struct cu *cu,
char *bf, size_t len);
void base_type_name_to_size_table__init(struct strings *strings);
size_t base_type__name_to_size(struct base_type *btype, struct cu *cu);
struct array_type {
struct tag tag;
uint32_t *nr_entries;
uint8_t dimensions;
bool is_vector;
};
static inline struct array_type *tag__array_type(const struct tag *tag)
{
return (struct array_type *)tag;
}
struct enumerator {
struct tag tag;
strings_t name;
uint32_t value;
};
static inline const char *enumerator__name(const struct enumerator *enumerator,
const struct cu *cu)
{
return cu__string(cu, enumerator->name);
}
void enumeration__delete(struct type *type, struct cu *cu);
void enumeration__add(struct type *type, struct enumerator *enumerator);
size_t enumeration__fprintf(const struct tag *tag_enum, const struct cu *cu,
const struct conf_fprintf *conf, FILE *fp);
int dwarves__init(uint16_t user_cacheline_size);
void dwarves__exit(void);
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_ */