2007-01-29 13:42:03 +01:00
|
|
|
#ifndef _DWARVES_H_
|
|
|
|
#define _DWARVES_H_ 1
|
2009-03-14 17:50:36 +01:00
|
|
|
/*
|
2006-10-28 18:45:59 +02:00
|
|
|
Copyright (C) 2006 Mandriva Conectiva S.A.
|
|
|
|
Copyright (C) 2006 Arnaldo Carvalho de Melo <acme@mandriva.com>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it
|
|
|
|
under the terms of version 2 of the GNU General Public License as
|
|
|
|
published by the Free Software Foundation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
2007-02-01 16:50:28 +01:00
|
|
|
#include <stdio.h>
|
2006-11-18 22:02:55 +01:00
|
|
|
#include <dwarf.h>
|
2009-03-31 03:45:55 +02:00
|
|
|
#include <elfutils/libdwfl.h>
|
2006-10-28 18:45:59 +02:00
|
|
|
|
2009-03-06 14:57:41 +01:00
|
|
|
#include "dutil.h"
|
2006-10-28 18:45:59 +02:00
|
|
|
#include "list.h"
|
2008-10-02 19:34:42 +02:00
|
|
|
#include "strings.h"
|
|
|
|
|
2009-03-13 18:59:32 +01:00
|
|
|
struct cu;
|
|
|
|
|
|
|
|
enum load_steal_kind {
|
|
|
|
LSK__KEEPIT,
|
|
|
|
LSK__STOLEN,
|
|
|
|
LSK__STOP_LOADING,
|
|
|
|
};
|
|
|
|
|
2009-03-09 18:43:47 +01:00
|
|
|
/** struct conf_load - load configuration
|
|
|
|
* @extra_dbg_info - keep original debugging format extra info
|
|
|
|
* (e.g. DWARF's decl_{line,file}, id, etc)
|
2009-03-20 17:54:04 +01:00
|
|
|
* @fixup_silly_bitfields - Fixup silly things such as "int foo:32;"
|
2009-03-09 18:43:47 +01:00
|
|
|
*/
|
|
|
|
struct conf_load {
|
2009-03-13 18:59:32 +01:00
|
|
|
enum load_steal_kind (*steal)(struct cu *self,
|
|
|
|
struct conf_load *conf);
|
|
|
|
void *cookie;
|
2009-03-19 16:19:37 +01:00
|
|
|
char *format_path;
|
2009-03-20 17:54:04 +01:00
|
|
|
bool extra_dbg_info;
|
|
|
|
bool fixup_silly_bitfields;
|
2009-03-09 18:43:47 +01:00
|
|
|
};
|
|
|
|
|
2009-03-20 14:29:50 +01:00
|
|
|
/** struct conf_fprintf - hints to the __fprintf routines
|
|
|
|
*
|
|
|
|
* @flat_arrays - a->foo[10][2] becomes a->foo[20]
|
|
|
|
*/
|
2009-03-14 18:48:20 +01:00
|
|
|
struct conf_fprintf {
|
|
|
|
const char *prefix;
|
|
|
|
const char *suffix;
|
|
|
|
int32_t type_spacing;
|
|
|
|
int32_t name_spacing;
|
|
|
|
uint32_t base_offset;
|
|
|
|
uint8_t indent;
|
|
|
|
uint8_t expand_types:1;
|
|
|
|
uint8_t expand_pointers:1;
|
|
|
|
uint8_t rel_offset:1;
|
|
|
|
uint8_t emit_stats:1;
|
|
|
|
uint8_t suppress_comments:1;
|
|
|
|
uint8_t suppress_offset_comment:1;
|
|
|
|
uint8_t show_decl_info:1;
|
|
|
|
uint8_t show_only_data_members:1;
|
|
|
|
uint8_t no_semicolon:1;
|
|
|
|
uint8_t show_first_biggest_size_base_type_member:1;
|
2009-03-20 14:29:50 +01:00
|
|
|
uint8_t flat_arrays:1;
|
2009-03-31 02:47:59 +02:00
|
|
|
uint8_t no_parm_names:1;
|
2009-03-14 18:48:20 +01:00
|
|
|
};
|
|
|
|
|
2006-11-11 19:31:04 +01:00
|
|
|
struct cus {
|
2008-10-01 16:26:51 +02:00
|
|
|
struct list_head cus;
|
2006-11-11 19:31:04 +01:00
|
|
|
};
|
|
|
|
|
2008-10-01 17:47:42 +02:00
|
|
|
struct cus *cus__new(void);
|
2009-03-11 16:31:17 +01:00
|
|
|
void cus__delete(struct cus *self);
|
2008-10-01 16:26:51 +02:00
|
|
|
|
2009-03-24 20:48:41 +01:00
|
|
|
int cus__load_file(struct cus *self, struct conf_load *conf, char *filename);
|
2009-03-14 18:48:20 +01:00
|
|
|
int cus__load_files(struct cus *self, struct conf_load *conf,
|
|
|
|
char *filenames[]);
|
|
|
|
int cus__load_dir(struct cus *self, struct conf_load *conf,
|
|
|
|
const char *dirname, const char *filename_mask,
|
|
|
|
const int recursive);
|
|
|
|
void cus__add(struct cus *self, 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 *self, const char *name);
|
|
|
|
struct tag *cus__find_struct_by_name(const struct cus *self, struct cu **cu,
|
|
|
|
const char *name, const int include_decls,
|
|
|
|
uint16_t *id);
|
|
|
|
void cus__for_each_cu(struct cus *self, 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;
|
|
|
|
};
|
|
|
|
|
2009-04-02 16:46:26 +02:00
|
|
|
struct function;
|
2009-03-14 18:48:20 +01:00
|
|
|
struct tag;
|
|
|
|
struct cu;
|
2009-04-02 17:40:33 +02:00
|
|
|
struct variable;
|
2009-03-14 18:48:20 +01:00
|
|
|
|
2009-04-02 16:46:26 +02:00
|
|
|
/** 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.
|
2009-04-02 17:40:33 +02:00
|
|
|
* @variable__name - will be called by variable__name(), see @function_name
|
2009-04-02 16:46:26 +02:00
|
|
|
* 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
|
|
|
|
*/
|
2009-04-02 16:12:02 +02:00
|
|
|
struct debug_fmt_ops {
|
2009-04-04 19:56:39 +02:00
|
|
|
const char *name;
|
|
|
|
int (*init)(void);
|
|
|
|
void (*exit)(void);
|
|
|
|
int (*load_file)(struct cus *self,
|
|
|
|
struct conf_load *conf,
|
|
|
|
const char *filename);
|
2009-03-14 18:48:20 +01:00
|
|
|
const char *(*tag__decl_file)(const struct tag *self,
|
|
|
|
const struct cu *cu);
|
|
|
|
uint32_t (*tag__decl_line)(const struct tag *self,
|
|
|
|
const struct cu *cu);
|
|
|
|
unsigned long long (*tag__orig_id)(const struct tag *self,
|
|
|
|
const struct cu *cu);
|
|
|
|
unsigned long long (*tag__orig_type)(const struct tag *self,
|
|
|
|
const struct cu *cu);
|
|
|
|
void (*tag__free_orig_info)(struct tag *self,
|
|
|
|
struct cu *cu);
|
2009-04-02 16:46:26 +02:00
|
|
|
const char *(*function__name)(struct function *self,
|
|
|
|
const struct cu *cu);
|
2009-04-02 17:40:33 +02:00
|
|
|
const char *(*variable__name)(const struct variable *self,
|
|
|
|
const struct cu *cu);
|
2009-04-02 22:55:17 +02:00
|
|
|
const char *(*strings__ptr)(const struct cu *self, strings_t s);
|
2009-04-02 16:46:26 +02:00
|
|
|
void (*cu__delete)(struct cu *self);
|
2009-03-14 18:48:20 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
2009-03-25 00:12:59 +01:00
|
|
|
struct ptr_table functions_table;
|
2009-03-14 18:48:20 +01:00
|
|
|
struct ptr_table tags_table;
|
|
|
|
char *name;
|
2009-03-19 02:35:54 +01:00
|
|
|
char *filename;
|
2009-03-14 18:48:20 +01:00
|
|
|
void *priv;
|
2009-04-02 16:12:02 +02:00
|
|
|
struct debug_fmt_ops *dfops;
|
2009-03-31 20:15:08 +02:00
|
|
|
Elf *elf;
|
|
|
|
Dwfl_Module *dwfl;
|
|
|
|
uint32_t cached_symtab_nr_entries;
|
2009-03-14 18:48:20 +01:00
|
|
|
uint8_t addr_size;
|
|
|
|
uint8_t extra_dbg_info:1;
|
2009-04-02 21:12:36 +02:00
|
|
|
uint8_t uses_global_strings:1;
|
2009-03-14 18:48:20 +01:00
|
|
|
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,
|
2009-03-19 02:35:54 +01:00
|
|
|
const unsigned char *build_id, int build_id_len,
|
|
|
|
const char *filename);
|
2009-03-14 18:48:20 +01:00
|
|
|
void cu__delete(struct cu *self);
|
|
|
|
|
2009-04-02 22:54:43 +02:00
|
|
|
const char *cu__string(const struct cu *self, strings_t s);
|
|
|
|
|
2009-03-31 20:15:08 +02:00
|
|
|
static inline void cu__cache_symtab(struct cu *self)
|
|
|
|
{
|
|
|
|
self->cached_symtab_nr_entries = dwfl_module_getsymtab(self->dwfl);
|
|
|
|
}
|
|
|
|
|
2009-03-31 03:45:55 +02:00
|
|
|
/**
|
|
|
|
* 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); \
|
2009-03-31 20:15:08 +02:00
|
|
|
id < cu->cached_symtab_nr_entries; \
|
2009-03-31 03:45:55 +02:00
|
|
|
++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
|
2009-03-31 03:45:55 +02:00
|
|
|
* @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) \
|
2009-04-01 18:46:11 +02:00
|
|
|
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
|
|
|
|
|
2009-03-06 15:48:33 +01:00
|
|
|
/**
|
|
|
|
* 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) \
|
2009-04-01 18:46:11 +02:00
|
|
|
for (id = 1; id < cu->types_table.nr_entries; ++id) \
|
|
|
|
if (!(pos = tag__class(cu->types_table.entries[id])) || \
|
2009-03-06 15:48:33 +01:00
|
|
|
!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
|
|
|
|
*/
|
2009-03-25 00:12:59 +01:00
|
|
|
#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
|
|
|
|
|
2009-03-31 20:58:07 +02:00
|
|
|
/**
|
|
|
|
* 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) \
|
2009-03-31 22:50:19 +02:00
|
|
|
for (id = 0; id < cu->tags_table.nr_entries; ++id) \
|
|
|
|
if (!(pos = cu->tags_table.entries[id]) || \
|
2009-03-31 20:58:07 +02:00
|
|
|
!tag__is_variable(pos)) \
|
|
|
|
continue; \
|
|
|
|
else
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
int cu__add_tag(struct cu *self, struct tag *tag, long *id);
|
|
|
|
int cu__table_add_tag(struct cu *self, struct tag *tag, long *id);
|
|
|
|
int cu__table_nullify_type_entry(struct cu *self, uint32_t id);
|
|
|
|
struct tag *cu__find_base_type_by_name(const struct cu *self, const char *name,
|
|
|
|
uint16_t *id);
|
|
|
|
struct tag *cu__find_base_type_by_sname_and_size(const struct cu *self,
|
|
|
|
strings_t name,
|
|
|
|
uint16_t bit_size,
|
|
|
|
uint16_t *idp);
|
2009-03-18 15:52:29 +01:00
|
|
|
struct tag *cu__find_enumeration_by_sname_and_size(const struct cu *self,
|
|
|
|
strings_t sname,
|
|
|
|
uint16_t bit_size,
|
|
|
|
uint16_t *idp);
|
2009-03-14 18:48:20 +01:00
|
|
|
struct tag *cu__find_first_typedef_of_type(const struct cu *self,
|
|
|
|
const Dwarf_Off 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 *self, strings_t sname,
|
|
|
|
const int include_decls, uint16_t *idp);
|
2009-03-25 00:12:59 +01:00
|
|
|
struct tag *cu__function(const struct cu *self, const uint32_t id);
|
2009-03-18 16:17:07 +01:00
|
|
|
struct tag *cu__tag(const struct cu *self, const uint32_t id);
|
|
|
|
struct tag *cu__type(const struct cu *self, const uint16_t id);
|
2009-03-14 18:48:20 +01:00
|
|
|
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 *self, const struct cu *other);
|
|
|
|
void cu__account_inline_expansions(struct cu *self);
|
|
|
|
int cu__for_all_tags(struct cu *self,
|
|
|
|
int (*iterator)(struct tag *tag,
|
|
|
|
struct cu *cu, void *cookie),
|
|
|
|
void *cookie);
|
2006-10-28 18:45:59 +02:00
|
|
|
|
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}
|
2009-03-14 17:50:36 +01:00
|
|
|
* @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
|
|
|
*/
|
2006-11-18 14:54:02 +01:00
|
|
|
struct tag {
|
2006-10-28 18:45:59 +02:00
|
|
|
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;
|
2007-03-07 16:10:56 +01:00
|
|
|
uint16_t tag;
|
2009-03-03 14:56:37 +01:00
|
|
|
uint16_t visited:1;
|
dwarves: Remove some more DWARF details from the core
Had to be a big sweeping change, but the regression tests shows just
improvements :-)
Now we stop using an id in struct tag, only storing the type, that now
uses 16 bits only, as CTF does.
Each format loader has to go on adding the types to the core, that
figures out if it is a tag that can be on the tag->type field
(tag__is_tag_type).
Formats that already have the types separated and in sequence, such as
CTF, just ask the core to insert in the types_table directly with its
original ID.
For DWARF, we ask the core to put it on the table, in sequence, and return the
index, that is then stashed with the DWARF specific info (original id, type,
decl_line, etc) and hashed by the original id. Later we recode everything,
looking up via the original type, getting the small_id to put on the tag->type.
The underlying debugging info not needed by the core is stashed in tag->priv,
and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of
the core tag and points it there, and makes that info available thru
cu->orig_info. In the future we can ask, when loading a cu, that this info be
trown away, so that we reduce the memory footprint for big multi-cu files such
as the Linux kernel.
There is also a routine to ask for inserting a NULL, as we still have
bugs in the CTF decoding and thus some entries are being lost, to avoid
using an undefined pointer when traversing the types_table the ctf
loader puts a NULL there via cu__table_nullify_type_entry() and then
cu__for_each_type skips those.
There is some more cleanups for leftovers that I avoided cleaning to
reduce this changeset.
And also while doing this I saw that enums can appear without any
enumerators and that an array with DW_TAG_GNU_vector is actually a
different tag, encoded this way till we get to DWARF4 ;-)
So now we don't have to lookup on a hash table looking for DWARF
offsets, we can do the more sensible thing of just indexing the
types_tags array.
Now to do some cleanups and try to get the per cu encoder done. Then
order all the cus per number of type entries, pick the one with more,
then go on merging/recoding the types of the others and putting the
parent linkage in place.
Just to show the extent of the changes:
$ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0
/home/acme/git/pahole/dwarves.c:
struct cu | -4048
struct tag | -32
struct ptr_to_member_type | -32
struct namespace | -32
struct type | -32
struct class | -32
struct base_type | -32
struct array_type | -32
struct class_member | -32
struct lexblock | -32
struct ftype | -32
struct function | -64
struct parameter | -32
struct variable | -32
struct inline_expansion | -32
struct label | -32
struct enumerator | -32
17 structs changed
tag__follow_typedef | +3
tag__fprintf_decl_info | +25
array_type__fprintf | +6
type__name | -126
type__find_first_biggest_size_base_type_member | -3
typedef__fprintf | +16
imported_declaration__fprintf | +6
imported_module__fprintf | +3
cu__new | +26
cu__delete | +26
hashtags__hash | -65
hash_64 | -124
hlist_add_head | -78
hashtags__find | -157
cu__hash | -80
cu__add_tag | +20
tag__prefix | -3
cu__find_tag_by_id | -2
cu__find_type_by_id | -3
cu__find_first_typedef_of_type | +38
cu__find_base_type_by_name | +68
cu__find_base_type_by_name_and_size | +72
cu__find_struct_by_name | +59
cus__find_struct_by_name | +8
cus__find_tag_by_id | +5
cus__find_cu_by_name | -6
lexblock__find_tag_by_id | -173
cu__find_variable_by_id | -197
list__find_tag_by_id | -308
cu__find_parameter_by_id | -60
tag__ptr_name | +6
tag__name | +15
variable__type | +13
variable__name | +7
class_member__size | +6
parameter__name | -119
tag__parameter | -14
parameter__type | -143
type__fprintf | -29
union__fprintf | +6
class__add_vtable_entry | -9
type__add_member | -6
type__clone_members | -3
enumeration__add | -6
function__name | -156
ftype__has_parm_of_type | -39
class__find_holes | -27
class__has_hole_ge | -3
type__nr_members_of_type | +3
lexblock__account_inline_expansions | +3
cu__account_inline_expansions | -18
ftype__fprintf_parms | +46
function__tag_fprintf | +24
lexblock__fprintf | -6
ftype__fprintf | +3
function__fprintf_stats | -18
function__size | -6
class__vtable_fprintf | -11
class__fprintf | -21
tag__fprintf | -35
60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541
/home/acme/git/pahole/ctf_loader.c:
struct ctf_short_type | +0
14 structs changed
type__init | -14
type__new | -9
class__new | -12
create_new_base_type | -7
create_new_base_type_float | -7
create_new_array | -8
create_new_subroutine_type | -9
create_full_members | -18
create_short_members | -18
create_new_class | +1
create_new_union | +1
create_new_enumeration | -19
create_new_forward_decl | -2
create_new_typedef | +3
create_new_tag | -5
load_types | +16
class__fixup_ctf_bitfields | -3
17 functions changed, 21 bytes added, 131 bytes removed, diff: -110
/home/acme/git/pahole/dwarf_loader.c:
17 structs changed
zalloc | -56
tag__init | +3
array_type__new | +20
type__init | -24
class_member__new | +46
inline_expansion__new | +12
class__new | +81
lexblock__init | +19
function__new | +43
die__create_new_array | +20
die__create_new_parameter | +4
die__create_new_label | +4
die__create_new_subroutine_type | +113
die__create_new_enumeration | -21
die__process_class | +79
die__process_namespace | +76
die__create_new_inline_expansion | +4
die__process_function | +147
__die__process_tag | +34
die__process_unit | +56
die__process | +90
21 functions changed, 851 bytes added, 101 bytes removed, diff: +750
/home/acme/git/pahole/dwarves.c:
struct ptr_table | +16
struct cu_orig_info | +32
2 structs changed
tag__decl_line | +68
tag__decl_file | +70
tag__orig_id | +71
ptr_table__init | +46
ptr_table__exit | +37
ptr_table__add | +183
ptr_table__add_with_id | +165
ptr_table__entry | +64
cu__table_add_tag | +171
cu__table_nullify_type_entry | +38
10 functions changed, 913 bytes added, diff: +913
/home/acme/git/pahole/ctf_loader.c:
2 structs changed
tag__alloc | +52
1 function changed, 52 bytes added, diff: +52
/home/acme/git/pahole/dwarf_loader.c:
struct dwarf_tag | +48
struct dwarf_cu | +4104
4 structs changed
dwarf_cu__init | +83
hashtags__hash | +61
hash_64 | +124
hlist_add_head | +78
hashtags__find | +161
cu__hash | +95
tag__is_tag_type | +171
tag__is_type | +85
tag__is_union | +28
tag__is_struct | +57
tag__is_typedef | +28
tag__is_enumeration | +28
dwarf_cu__find_tag_by_id | +56
dwarf_cu__find_type_by_id | +63
tag__alloc | +114
__tag__print_type_not_found | +108
namespace__recode_dwarf_types | +346
tag__namespace | +14
tag__has_namespace | +86
tag__is_namespace | +28
type__recode_dwarf_specification | +182
tag__type | +14
__tag__print_abstract_origin_not_found | +105
ftype__recode_dwarf_types | +322
tag__ftype | +14
tag__parameter | +14
lexblock__recode_dwarf_types | +736
tag__lexblock | +14
tag__label | +14
tag__recode_dwarf_type | +766
tag__ptr_to_member_type | +14
cu__recode_dwarf_types_table | +88
cu__recode_dwarf_types | +48
dwarf_tag__decl_file | +77
strings__ptr | +33
dwarf_tag__decl_line | +59
dwarf_tag__orig_id | +59
dwarf_tag__orig_type | +59
38 functions changed, 4432 bytes added, diff: +4432
build/libdwarves.so.1.0.0:
147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
|
|
|
uint16_t top_level:1;
|
|
|
|
uint16_t recursivity_level;
|
|
|
|
void *priv;
|
2006-11-18 14:54:02 +01:00
|
|
|
};
|
2007-05-31 06:53:01 +02:00
|
|
|
|
2009-03-25 17:06:29 +01:00
|
|
|
void tag__delete(struct tag *self);
|
|
|
|
|
2007-05-31 07:21:36 +02:00
|
|
|
static inline int tag__is_enumeration(const struct tag *self)
|
|
|
|
{
|
|
|
|
return self->tag == DW_TAG_enumeration_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int tag__is_namespace(const struct tag *self)
|
|
|
|
{
|
|
|
|
return self->tag == DW_TAG_namespace;
|
|
|
|
}
|
|
|
|
|
2007-05-31 06:53:01 +02:00
|
|
|
static inline int tag__is_struct(const struct tag *self)
|
|
|
|
{
|
2008-04-21 03:12:03 +02:00
|
|
|
return self->tag == DW_TAG_structure_type ||
|
|
|
|
self->tag == DW_TAG_class_type;
|
2007-05-31 06:53:01 +02:00
|
|
|
}
|
2007-05-31 07:21:36 +02:00
|
|
|
|
2008-09-30 19:21:03 +02:00
|
|
|
static inline int tag__is_typedef(const struct tag *self)
|
|
|
|
{
|
|
|
|
return self->tag == DW_TAG_typedef;
|
|
|
|
}
|
|
|
|
|
2007-05-31 07:21:36 +02:00
|
|
|
static inline int tag__is_union(const struct tag *self)
|
|
|
|
{
|
2007-06-07 20:58:33 +02:00
|
|
|
return self->tag == DW_TAG_union_type;
|
2007-05-31 07:21:36 +02:00
|
|
|
}
|
pfunct: Implement --expand_types
So that one can get an skeleton from where a function can be
reimplemented, or a probe can be written to attach to a tracepoint.
Right now it will only expand the types for
struct/union/typedef/enumeration types, but it is a good start.
[acme@doppio pahole]$ pfunct --expand_types --function inet6_ioctl ipv6.ko > a.c
[acme@doppio pahole]$ echo "int main(void) { return 0; }" >> a.c
[acme@doppio pahole]$ gcc -Wall -g a.c -o a
[acme@doppio pahole]$ grep ^#include a.c
[acme@doppio pahole]$
No errors, no includes.
This is present in ctracer, where we don't want to _require_ any header
files, just the object file with the function we want to probe. From
there we get the function signature, and reconstruct the types needed to
access members of structs passed as parameters.
We still need to add padding to reconstruct __attribute__ alignment
effects.
Also, if we can detect what are the exact members accessed in the probe,
we can reconstruct just what is needed to access those members,
hopefully reducing the time needed for gcc to digest the resulting
source code. And also reducing the size of the output, which can
hopefully be interesting to help focus on what the probe is doing.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-09-30 22:30:42 +02:00
|
|
|
|
2009-03-31 20:58:07 +02:00
|
|
|
static inline bool tag__is_variable(const struct tag *self)
|
|
|
|
{
|
|
|
|
return self->tag == DW_TAG_variable;
|
|
|
|
}
|
|
|
|
|
2009-04-02 18:58:46 +02:00
|
|
|
static inline bool tag__is_volatile(const struct tag *self)
|
|
|
|
{
|
|
|
|
return self->tag == DW_TAG_volatile_type;
|
|
|
|
}
|
|
|
|
|
2009-03-03 13:38:27 +01:00
|
|
|
static inline bool tag__has_namespace(const struct tag *self)
|
|
|
|
{
|
|
|
|
return tag__is_struct(self) ||
|
|
|
|
tag__is_union(self) ||
|
|
|
|
tag__is_namespace(self) ||
|
|
|
|
tag__is_enumeration(self);
|
|
|
|
}
|
|
|
|
|
2009-03-03 17:18:51 +01:00
|
|
|
/**
|
|
|
|
* tag__is_tag_type - is this tag derived from the 'type' class?
|
|
|
|
* @tag - tag queried
|
|
|
|
*/
|
pfunct: Implement --expand_types
So that one can get an skeleton from where a function can be
reimplemented, or a probe can be written to attach to a tracepoint.
Right now it will only expand the types for
struct/union/typedef/enumeration types, but it is a good start.
[acme@doppio pahole]$ pfunct --expand_types --function inet6_ioctl ipv6.ko > a.c
[acme@doppio pahole]$ echo "int main(void) { return 0; }" >> a.c
[acme@doppio pahole]$ gcc -Wall -g a.c -o a
[acme@doppio pahole]$ grep ^#include a.c
[acme@doppio pahole]$
No errors, no includes.
This is present in ctracer, where we don't want to _require_ any header
files, just the object file with the function we want to probe. From
there we get the function signature, and reconstruct the types needed to
access members of structs passed as parameters.
We still need to add padding to reconstruct __attribute__ alignment
effects.
Also, if we can detect what are the exact members accessed in the probe,
we can reconstruct just what is needed to access those members,
hopefully reducing the time needed for gcc to digest the resulting
source code. And also reducing the size of the output, which can
hopefully be interesting to help focus on what the probe is doing.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-09-30 22:30:42 +02:00
|
|
|
static inline int tag__is_type(const struct tag *self)
|
|
|
|
{
|
|
|
|
return tag__is_union(self) ||
|
|
|
|
tag__is_struct(self) ||
|
|
|
|
tag__is_typedef(self) ||
|
|
|
|
tag__is_enumeration(self);
|
|
|
|
}
|
2009-03-14 17:50:36 +01:00
|
|
|
|
2009-03-03 17:18:51 +01:00
|
|
|
/**
|
|
|
|
* tag__is_tag_type - is this one of the possible types for a tag?
|
|
|
|
* @tag - tag queried
|
|
|
|
*/
|
|
|
|
static inline int tag__is_tag_type(const struct tag *self)
|
|
|
|
{
|
|
|
|
return tag__is_type(self) ||
|
|
|
|
self->tag == DW_TAG_array_type ||
|
|
|
|
self->tag == DW_TAG_base_type ||
|
|
|
|
self->tag == DW_TAG_const_type ||
|
|
|
|
self->tag == DW_TAG_pointer_type ||
|
2009-03-03 19:12:29 +01:00
|
|
|
self->tag == DW_TAG_ptr_to_member_type ||
|
2009-03-03 18:56:38 +01:00
|
|
|
self->tag == DW_TAG_reference_type ||
|
2009-03-03 17:18:51 +01:00
|
|
|
self->tag == DW_TAG_subroutine_type ||
|
|
|
|
self->tag == DW_TAG_volatile_type;
|
|
|
|
}
|
2008-10-02 19:34:42 +02:00
|
|
|
|
dwarves: Remove some more DWARF details from the core
Had to be a big sweeping change, but the regression tests shows just
improvements :-)
Now we stop using an id in struct tag, only storing the type, that now
uses 16 bits only, as CTF does.
Each format loader has to go on adding the types to the core, that
figures out if it is a tag that can be on the tag->type field
(tag__is_tag_type).
Formats that already have the types separated and in sequence, such as
CTF, just ask the core to insert in the types_table directly with its
original ID.
For DWARF, we ask the core to put it on the table, in sequence, and return the
index, that is then stashed with the DWARF specific info (original id, type,
decl_line, etc) and hashed by the original id. Later we recode everything,
looking up via the original type, getting the small_id to put on the tag->type.
The underlying debugging info not needed by the core is stashed in tag->priv,
and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of
the core tag and points it there, and makes that info available thru
cu->orig_info. In the future we can ask, when loading a cu, that this info be
trown away, so that we reduce the memory footprint for big multi-cu files such
as the Linux kernel.
There is also a routine to ask for inserting a NULL, as we still have
bugs in the CTF decoding and thus some entries are being lost, to avoid
using an undefined pointer when traversing the types_table the ctf
loader puts a NULL there via cu__table_nullify_type_entry() and then
cu__for_each_type skips those.
There is some more cleanups for leftovers that I avoided cleaning to
reduce this changeset.
And also while doing this I saw that enums can appear without any
enumerators and that an array with DW_TAG_GNU_vector is actually a
different tag, encoded this way till we get to DWARF4 ;-)
So now we don't have to lookup on a hash table looking for DWARF
offsets, we can do the more sensible thing of just indexing the
types_tags array.
Now to do some cleanups and try to get the per cu encoder done. Then
order all the cus per number of type entries, pick the one with more,
then go on merging/recoding the types of the others and putting the
parent linkage in place.
Just to show the extent of the changes:
$ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0
/home/acme/git/pahole/dwarves.c:
struct cu | -4048
struct tag | -32
struct ptr_to_member_type | -32
struct namespace | -32
struct type | -32
struct class | -32
struct base_type | -32
struct array_type | -32
struct class_member | -32
struct lexblock | -32
struct ftype | -32
struct function | -64
struct parameter | -32
struct variable | -32
struct inline_expansion | -32
struct label | -32
struct enumerator | -32
17 structs changed
tag__follow_typedef | +3
tag__fprintf_decl_info | +25
array_type__fprintf | +6
type__name | -126
type__find_first_biggest_size_base_type_member | -3
typedef__fprintf | +16
imported_declaration__fprintf | +6
imported_module__fprintf | +3
cu__new | +26
cu__delete | +26
hashtags__hash | -65
hash_64 | -124
hlist_add_head | -78
hashtags__find | -157
cu__hash | -80
cu__add_tag | +20
tag__prefix | -3
cu__find_tag_by_id | -2
cu__find_type_by_id | -3
cu__find_first_typedef_of_type | +38
cu__find_base_type_by_name | +68
cu__find_base_type_by_name_and_size | +72
cu__find_struct_by_name | +59
cus__find_struct_by_name | +8
cus__find_tag_by_id | +5
cus__find_cu_by_name | -6
lexblock__find_tag_by_id | -173
cu__find_variable_by_id | -197
list__find_tag_by_id | -308
cu__find_parameter_by_id | -60
tag__ptr_name | +6
tag__name | +15
variable__type | +13
variable__name | +7
class_member__size | +6
parameter__name | -119
tag__parameter | -14
parameter__type | -143
type__fprintf | -29
union__fprintf | +6
class__add_vtable_entry | -9
type__add_member | -6
type__clone_members | -3
enumeration__add | -6
function__name | -156
ftype__has_parm_of_type | -39
class__find_holes | -27
class__has_hole_ge | -3
type__nr_members_of_type | +3
lexblock__account_inline_expansions | +3
cu__account_inline_expansions | -18
ftype__fprintf_parms | +46
function__tag_fprintf | +24
lexblock__fprintf | -6
ftype__fprintf | +3
function__fprintf_stats | -18
function__size | -6
class__vtable_fprintf | -11
class__fprintf | -21
tag__fprintf | -35
60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541
/home/acme/git/pahole/ctf_loader.c:
struct ctf_short_type | +0
14 structs changed
type__init | -14
type__new | -9
class__new | -12
create_new_base_type | -7
create_new_base_type_float | -7
create_new_array | -8
create_new_subroutine_type | -9
create_full_members | -18
create_short_members | -18
create_new_class | +1
create_new_union | +1
create_new_enumeration | -19
create_new_forward_decl | -2
create_new_typedef | +3
create_new_tag | -5
load_types | +16
class__fixup_ctf_bitfields | -3
17 functions changed, 21 bytes added, 131 bytes removed, diff: -110
/home/acme/git/pahole/dwarf_loader.c:
17 structs changed
zalloc | -56
tag__init | +3
array_type__new | +20
type__init | -24
class_member__new | +46
inline_expansion__new | +12
class__new | +81
lexblock__init | +19
function__new | +43
die__create_new_array | +20
die__create_new_parameter | +4
die__create_new_label | +4
die__create_new_subroutine_type | +113
die__create_new_enumeration | -21
die__process_class | +79
die__process_namespace | +76
die__create_new_inline_expansion | +4
die__process_function | +147
__die__process_tag | +34
die__process_unit | +56
die__process | +90
21 functions changed, 851 bytes added, 101 bytes removed, diff: +750
/home/acme/git/pahole/dwarves.c:
struct ptr_table | +16
struct cu_orig_info | +32
2 structs changed
tag__decl_line | +68
tag__decl_file | +70
tag__orig_id | +71
ptr_table__init | +46
ptr_table__exit | +37
ptr_table__add | +183
ptr_table__add_with_id | +165
ptr_table__entry | +64
cu__table_add_tag | +171
cu__table_nullify_type_entry | +38
10 functions changed, 913 bytes added, diff: +913
/home/acme/git/pahole/ctf_loader.c:
2 structs changed
tag__alloc | +52
1 function changed, 52 bytes added, diff: +52
/home/acme/git/pahole/dwarf_loader.c:
struct dwarf_tag | +48
struct dwarf_cu | +4104
4 structs changed
dwarf_cu__init | +83
hashtags__hash | +61
hash_64 | +124
hlist_add_head | +78
hashtags__find | +161
cu__hash | +95
tag__is_tag_type | +171
tag__is_type | +85
tag__is_union | +28
tag__is_struct | +57
tag__is_typedef | +28
tag__is_enumeration | +28
dwarf_cu__find_tag_by_id | +56
dwarf_cu__find_type_by_id | +63
tag__alloc | +114
__tag__print_type_not_found | +108
namespace__recode_dwarf_types | +346
tag__namespace | +14
tag__has_namespace | +86
tag__is_namespace | +28
type__recode_dwarf_specification | +182
tag__type | +14
__tag__print_abstract_origin_not_found | +105
ftype__recode_dwarf_types | +322
tag__ftype | +14
tag__parameter | +14
lexblock__recode_dwarf_types | +736
tag__lexblock | +14
tag__label | +14
tag__recode_dwarf_type | +766
tag__ptr_to_member_type | +14
cu__recode_dwarf_types_table | +88
cu__recode_dwarf_types | +48
dwarf_tag__decl_file | +77
strings__ptr | +33
dwarf_tag__decl_line | +59
dwarf_tag__orig_id | +59
dwarf_tag__orig_type | +59
38 functions changed, 4432 bytes added, diff: +4432
build/libdwarves.so.1.0.0:
147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
|
|
|
static inline const char *tag__decl_file(const struct tag *self,
|
|
|
|
const struct cu *cu)
|
|
|
|
{
|
2009-04-02 17:05:50 +02:00
|
|
|
if (cu->dfops && cu->dfops->tag__decl_file)
|
|
|
|
return cu->dfops->tag__decl_file(self, 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 *self,
|
|
|
|
const struct cu *cu)
|
|
|
|
{
|
2009-04-02 17:05:50 +02:00
|
|
|
if (cu->dfops && cu->dfops->tag__decl_line)
|
|
|
|
return cu->dfops->tag__decl_line(self, 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 *self,
|
|
|
|
const struct cu *cu)
|
|
|
|
{
|
2009-04-02 17:05:50 +02:00
|
|
|
if (cu->dfops && cu->dfops->tag__orig_id)
|
|
|
|
return cu->dfops->tag__orig_id(self, 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_type(const struct tag *self,
|
|
|
|
const struct cu *cu)
|
2008-10-02 19:34:42 +02:00
|
|
|
{
|
2009-04-02 17:05:50 +02:00
|
|
|
if (cu->dfops && cu->dfops->tag__orig_type)
|
|
|
|
return cu->dfops->tag__orig_type(self, cu);
|
|
|
|
return 0;
|
2008-10-02 19:34:42 +02:00
|
|
|
}
|
2009-03-11 16:31:17 +01:00
|
|
|
|
|
|
|
static inline void tag__free_orig_info(struct tag *self, struct cu *cu)
|
|
|
|
{
|
2009-04-02 17:05:50 +02:00
|
|
|
if (cu->dfops && cu->dfops->tag__free_orig_info)
|
|
|
|
cu->dfops->tag__free_orig_info(self, cu);
|
2009-03-11 16:31:17 +01:00
|
|
|
}
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
size_t tag__fprintf_decl_info(const struct tag *self,
|
|
|
|
const struct cu *cu, FILE *fp);
|
|
|
|
size_t tag__fprintf(struct tag *self, const struct cu *cu,
|
|
|
|
const struct conf_fprintf *conf, FILE *fp);
|
|
|
|
|
|
|
|
const char *tag__name(const struct tag *self, const struct cu *cu,
|
|
|
|
char *bf, size_t len);
|
|
|
|
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 *self, const struct cu *cu);
|
|
|
|
size_t tag__nr_cachelines(const struct tag *self, const struct cu *cu);
|
2009-03-23 20:30:20 +01:00
|
|
|
struct tag *tag__follow_typedef(const struct tag *tag, const struct cu *cu);
|
2009-03-14 18:48:20 +01:00
|
|
|
|
2009-04-19 18:48:51 +02:00
|
|
|
size_t __tag__id_not_found_fprintf(FILE *fp, uint16_t id, const char *fn);
|
|
|
|
#define tag__id_not_found_fprintf(fp, id) \
|
|
|
|
__tag__id_not_found_fprintf(fp, id, __func__)
|
|
|
|
|
2008-04-21 22:28:06 +02:00
|
|
|
struct ptr_to_member_type {
|
|
|
|
struct tag tag;
|
2009-04-19 19:04:59 +02:00
|
|
|
uint16_t containing_type;
|
2008-04-21 22:28:06 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static inline struct ptr_to_member_type *
|
|
|
|
tag__ptr_to_member_type(const struct tag *self)
|
|
|
|
{
|
|
|
|
return (struct ptr_to_member_type *)self;
|
|
|
|
}
|
2009-03-14 17:50:36 +01:00
|
|
|
|
2009-03-20 16:53:43 +01:00
|
|
|
/** struct namespace - base class for enums, structs, unions, typedefs, etc
|
|
|
|
*
|
2009-04-02 23:46:54 +02:00
|
|
|
* @sname - for clones, for instance, where we can't always add a new string
|
2009-03-20 16:53:43 +01:00
|
|
|
* @tags - class_member, enumerators, etc
|
|
|
|
* @shared_tags: if this bit is set, don't free the entries in @tags
|
|
|
|
*/
|
2007-05-24 17:16:59 +02:00
|
|
|
struct namespace {
|
|
|
|
struct tag tag;
|
2008-10-02 19:34:42 +02:00
|
|
|
strings_t name;
|
2009-04-02 23:46:54 +02:00
|
|
|
char * sname;
|
2007-05-24 17:16:59 +02:00
|
|
|
uint16_t nr_tags;
|
2009-03-20 16:53:43 +01:00
|
|
|
uint8_t shared_tags:1;
|
2008-10-02 19:34:42 +02:00
|
|
|
struct list_head tags;
|
2007-05-24 17:16:59 +02:00
|
|
|
};
|
2006-11-18 14:54:02 +01:00
|
|
|
|
2007-05-24 17:31:40 +02:00
|
|
|
static inline struct namespace *tag__namespace(const struct tag *self)
|
|
|
|
{
|
|
|
|
return (struct namespace *)self;
|
|
|
|
}
|
|
|
|
|
2009-03-25 18:54:02 +01:00
|
|
|
void namespace__delete(struct namespace *self);
|
|
|
|
|
2008-01-14 23:04:57 +01:00
|
|
|
/**
|
2007-05-24 17:40:43 +02:00
|
|
|
* namespace__for_each_tag - iterate thru all the tags
|
|
|
|
* @self: struct namespace instance to iterate
|
|
|
|
* @pos: struct tag iterator
|
|
|
|
*/
|
|
|
|
#define namespace__for_each_tag(self, pos) \
|
|
|
|
list_for_each_entry(pos, &(self)->tags, node)
|
|
|
|
|
2008-01-14 23:04:57 +01:00
|
|
|
/**
|
|
|
|
* namespace__for_each_tag_safe - safely iterate thru all the tags
|
|
|
|
* @self: struct namespace instance to iterate
|
|
|
|
* @pos: struct tag iterator
|
|
|
|
* @n: struct class_member temp iterator
|
|
|
|
*/
|
|
|
|
#define namespace__for_each_tag_safe(self, pos, n) \
|
|
|
|
list_for_each_entry_safe(pos, n, &(self)->tags, node)
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
void namespace__add_tag(struct namespace *self, struct tag *tag);
|
|
|
|
|
|
|
|
struct inline_expansion {
|
|
|
|
struct tag tag;
|
|
|
|
size_t size;
|
|
|
|
Dwarf_Addr low_pc;
|
|
|
|
Dwarf_Addr high_pc;
|
2007-01-07 15:30:58 +01:00
|
|
|
};
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
static inline struct inline_expansion *
|
|
|
|
tag__inline_expansion(const struct tag *self)
|
2007-07-09 01:57:23 +02:00
|
|
|
{
|
2009-03-14 18:48:20 +01:00
|
|
|
return (struct inline_expansion *)self;
|
2007-07-09 01:57:23 +02:00
|
|
|
}
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
struct label {
|
|
|
|
struct tag tag;
|
|
|
|
strings_t name;
|
|
|
|
Dwarf_Addr low_pc;
|
|
|
|
};
|
2007-05-24 03:38:29 +02:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
static inline struct label *tag__label(const struct tag *self)
|
|
|
|
{
|
|
|
|
return (struct label *)self;
|
|
|
|
}
|
2007-05-24 03:38:29 +02:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
enum vlocation {
|
|
|
|
LOCATION_UNKNOWN,
|
|
|
|
LOCATION_LOCAL,
|
|
|
|
LOCATION_GLOBAL,
|
|
|
|
LOCATION_REGISTER,
|
|
|
|
LOCATION_OPTIMIZED
|
2009-03-31 21:03:23 +02:00
|
|
|
} __attribute__((packed));
|
2007-05-29 19:06:33 +02:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
struct variable {
|
2006-11-18 14:54:02 +01:00
|
|
|
struct tag tag;
|
2008-10-02 19:34:42 +02:00
|
|
|
strings_t name;
|
2009-03-14 18:48:20 +01:00
|
|
|
uint8_t external:1;
|
|
|
|
uint8_t declaration:1;
|
|
|
|
enum vlocation location;
|
2009-03-31 21:03:23 +02:00
|
|
|
uint64_t addr;
|
2009-03-31 21:12:00 +02:00
|
|
|
struct hlist_node tool_hnode;
|
2006-10-28 18:45:59 +02:00
|
|
|
};
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
static inline struct variable *tag__variable(const struct tag *self)
|
2008-10-02 19:34:42 +02:00
|
|
|
{
|
2009-03-14 18:48:20 +01:00
|
|
|
return (struct variable *)self;
|
2008-10-02 19:34:42 +02:00
|
|
|
}
|
|
|
|
|
2009-04-02 17:40:33 +02:00
|
|
|
const char *variable__name(const struct variable *self, const struct cu *cu);
|
2009-03-14 19:19:33 +01:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
const char *variable__type_name(const struct variable *self,
|
|
|
|
const struct cu *cu, char *bf, size_t len);
|
2007-01-30 16:32:55 +01:00
|
|
|
|
2006-11-20 19:38:47 +01:00
|
|
|
struct lexblock {
|
2007-01-02 16:25:56 +01:00
|
|
|
struct tag tag;
|
2007-01-03 01:26:01 +01:00
|
|
|
struct list_head tags;
|
2007-01-02 16:25:56 +01:00
|
|
|
Dwarf_Addr low_pc;
|
2009-03-07 21:37:33 +01:00
|
|
|
uint32_t size;
|
2006-12-28 14:18:43 +01:00
|
|
|
uint16_t nr_inline_expansions;
|
|
|
|
uint16_t nr_labels;
|
|
|
|
uint16_t nr_variables;
|
2007-01-02 16:25:56 +01:00
|
|
|
uint16_t nr_lexblocks;
|
2009-03-07 20:45:09 +01:00
|
|
|
uint32_t size_inline_expansions;
|
2006-11-20 19:38:47 +01:00
|
|
|
};
|
|
|
|
|
2007-01-03 01:26:01 +01:00
|
|
|
static inline struct lexblock *tag__lexblock(const struct tag *self)
|
|
|
|
{
|
|
|
|
return (struct lexblock *)self;
|
|
|
|
}
|
|
|
|
|
2009-03-25 18:54:02 +01:00
|
|
|
void lexblock__delete(struct lexblock *self);
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
struct function;
|
|
|
|
|
|
|
|
void lexblock__add_inline_expansion(struct lexblock *self,
|
|
|
|
struct inline_expansion *exp);
|
|
|
|
void lexblock__add_label(struct lexblock *self, struct label *label);
|
|
|
|
void lexblock__add_lexblock(struct lexblock *self, struct lexblock *child);
|
|
|
|
void lexblock__add_tag(struct lexblock *self, struct tag *tag);
|
|
|
|
void lexblock__add_variable(struct lexblock *self, struct variable *var);
|
|
|
|
size_t lexblock__fprintf(const struct lexblock *self, const struct cu *cu,
|
2009-03-31 02:47:59 +02:00
|
|
|
struct function *function, uint16_t indent,
|
|
|
|
const struct conf_fprintf *conf, FILE *fp);
|
2009-03-14 18:48:20 +01:00
|
|
|
|
|
|
|
struct parameter {
|
|
|
|
struct tag tag;
|
|
|
|
strings_t name;
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline struct parameter *tag__parameter(const struct tag *self)
|
|
|
|
{
|
|
|
|
return (struct parameter *)self;
|
|
|
|
}
|
|
|
|
|
2009-04-02 22:54:43 +02:00
|
|
|
static inline const char *parameter__name(const struct parameter *self,
|
|
|
|
const struct cu *cu)
|
2009-03-14 18:48:20 +01:00
|
|
|
{
|
2009-04-02 22:54:43 +02:00
|
|
|
return cu__string(cu, self->name);
|
2009-03-14 18:48:20 +01:00
|
|
|
}
|
|
|
|
|
2006-12-30 19:34:20 +01:00
|
|
|
/*
|
|
|
|
* tag.tag can be DW_TAG_subprogram_type or DW_TAG_subroutine_type.
|
|
|
|
*/
|
|
|
|
struct ftype {
|
2006-11-18 17:33:48 +01:00
|
|
|
struct tag tag;
|
2006-12-30 19:34:20 +01:00
|
|
|
struct list_head parms;
|
|
|
|
uint16_t nr_parms;
|
[CLASSES]: Introduce DW_TAG_subroutine_type specific parser
So that we handle DW_TAG_formal_parameters in this tag, fixing
these cases:
--- /tmp/ctracer.c.before 2006-12-29 13:27:24.000000000 -0200
+++ /tmp/ctracer.c 2007-01-02 02:34:18.000000000 -0200
<SNIP>
@@ -62,7 +62,7 @@
}; /* size: 68, cachelines: 3 */
/* last cacheline: 4 bytes */
-typedef int (*kretprobe_handler_t)(void /* FIXME: add parm list */);
+typedef int (*kretprobe_handler_t)(struct kretprobe_instance *, struct pt_regs *);
/* /pub/scm/linux/kernel/git/acme/linux-2.6/include/linux/list.h:607 */
struct hlist_head {
struct hlist_node * first; /* 0 4 */
[acme@newtoy ctracer_example]$
--- /tmp/pfunct.before 2006-12-30 16:18:25.000000000 -0200
+++ /tmp/pfunct.after 2007-01-02 02:08:50.000000000 -0200
@@ -249,7 +249,7 @@
/* definitions: 1 */
/* /pub/scm/linux/kernel/git/acme/linux-2.6/lib/klist.c:57 */
-void klist_init(struct klist * k, * get, * put);
+void klist_init(struct klist * k, void (*get)(struct klist_node *), void (*put)(struct klist_node *));
/* size: 12, inline expansions: 1 (5 bytes) */
/* definitions: 1 */
The struct/union case still needs fixing, but we're getting there...
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-02 05:42:33 +01:00
|
|
|
uint8_t unspec_parms; /* just one bit is needed */
|
2006-12-30 19:34:20 +01:00
|
|
|
};
|
|
|
|
|
[CLASSES]: Introduce DW_TAG_subroutine_type specific parser
So that we handle DW_TAG_formal_parameters in this tag, fixing
these cases:
--- /tmp/ctracer.c.before 2006-12-29 13:27:24.000000000 -0200
+++ /tmp/ctracer.c 2007-01-02 02:34:18.000000000 -0200
<SNIP>
@@ -62,7 +62,7 @@
}; /* size: 68, cachelines: 3 */
/* last cacheline: 4 bytes */
-typedef int (*kretprobe_handler_t)(void /* FIXME: add parm list */);
+typedef int (*kretprobe_handler_t)(struct kretprobe_instance *, struct pt_regs *);
/* /pub/scm/linux/kernel/git/acme/linux-2.6/include/linux/list.h:607 */
struct hlist_head {
struct hlist_node * first; /* 0 4 */
[acme@newtoy ctracer_example]$
--- /tmp/pfunct.before 2006-12-30 16:18:25.000000000 -0200
+++ /tmp/pfunct.after 2007-01-02 02:08:50.000000000 -0200
@@ -249,7 +249,7 @@
/* definitions: 1 */
/* /pub/scm/linux/kernel/git/acme/linux-2.6/lib/klist.c:57 */
-void klist_init(struct klist * k, * get, * put);
+void klist_init(struct klist * k, void (*get)(struct klist_node *), void (*put)(struct klist_node *));
/* size: 12, inline expansions: 1 (5 bytes) */
/* definitions: 1 */
The struct/union case still needs fixing, but we're getting there...
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-02 05:42:33 +01:00
|
|
|
static inline struct ftype *tag__ftype(const struct tag *self)
|
|
|
|
{
|
|
|
|
return (struct ftype *)self;
|
|
|
|
}
|
|
|
|
|
2009-03-25 15:40:05 +01:00
|
|
|
void ftype__delete(struct ftype *self);
|
|
|
|
|
2009-03-14 17:50:36 +01:00
|
|
|
/**
|
2007-06-12 20:01:23 +02:00
|
|
|
* ftype__for_each_parameter - iterate thru all the parameters
|
|
|
|
* @self: struct ftype instance to iterate
|
|
|
|
* @pos: struct parameter iterator
|
|
|
|
*/
|
|
|
|
#define ftype__for_each_parameter(self, pos) \
|
|
|
|
list_for_each_entry(pos, &(self)->parms, tag.node)
|
|
|
|
|
2009-03-25 15:39:26 +01:00
|
|
|
/**
|
|
|
|
* ftype__for_each_parameter_safe - safely iterate thru all the parameters
|
|
|
|
* @self: struct ftype instance to iterate
|
|
|
|
* @pos: struct parameter iterator
|
|
|
|
* @n: struct parameter temp iterator
|
|
|
|
*/
|
|
|
|
#define ftype__for_each_parameter_safe(self, pos, n) \
|
|
|
|
list_for_each_entry_safe(pos, n, &(self)->parms, tag.node)
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
void ftype__add_parameter(struct ftype *self, struct parameter *parm);
|
|
|
|
size_t ftype__fprintf(const struct ftype *self, const struct cu *cu,
|
|
|
|
const char *name, const int inlined,
|
2009-03-31 02:47:59 +02:00
|
|
|
const int is_pointer, const int type_spacing,
|
|
|
|
const struct conf_fprintf *conf, FILE *fp);
|
2009-03-14 18:48:20 +01:00
|
|
|
int ftype__has_parm_of_type(const struct ftype *self, const uint16_t target,
|
|
|
|
const struct cu *cu);
|
|
|
|
|
2006-12-30 19:34:20 +01:00
|
|
|
struct function {
|
|
|
|
struct ftype proto;
|
2006-11-20 19:38:47 +01:00
|
|
|
struct lexblock lexblock;
|
2007-01-13 14:37:41 +01:00
|
|
|
Dwarf_Off specification;
|
2008-10-02 19:34:42 +02:00
|
|
|
strings_t name;
|
|
|
|
strings_t linkage_name;
|
2009-03-07 20:45:09 +01:00
|
|
|
uint32_t cu_total_size_inline_expansions;
|
2006-12-30 19:34:20 +01:00
|
|
|
uint16_t cu_total_nr_inline_expansions;
|
2007-05-25 21:42:49 +02:00
|
|
|
uint8_t inlined:2;
|
2009-03-15 02:42:34 +01:00
|
|
|
uint8_t abstract_origin:1;
|
2007-05-25 21:42:49 +02:00
|
|
|
uint8_t external:1;
|
|
|
|
uint8_t accessibility:2; /* DW_ACCESS_{public,protected,private} */
|
|
|
|
uint8_t virtuality:2; /* DW_VIRTUALITY_{none,virtual,pure_virtual} */
|
2007-07-09 01:35:49 +02:00
|
|
|
int16_t vtable_entry;
|
2007-07-09 01:57:23 +02:00
|
|
|
struct list_head vtable_node;
|
2006-12-28 15:27:12 +01:00
|
|
|
/* 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;
|
|
|
|
};
|
2007-01-04 04:41:11 +01:00
|
|
|
void *priv;
|
2006-11-18 17:33:48 +01:00
|
|
|
};
|
|
|
|
|
2007-01-04 00:29:24 +01:00
|
|
|
static inline struct function *tag__function(const struct tag *self)
|
|
|
|
{
|
|
|
|
return (struct function *)self;
|
|
|
|
}
|
|
|
|
|
2008-07-31 00:33:33 +02:00
|
|
|
static inline struct tag *function__tag(const struct function *self)
|
|
|
|
{
|
|
|
|
return (struct tag *)self;
|
|
|
|
}
|
|
|
|
|
2009-03-25 18:54:02 +01:00
|
|
|
void function__delete(struct function *self);
|
|
|
|
|
2009-03-06 15:12:00 +01:00
|
|
|
static __pure inline int tag__is_function(const struct tag *self)
|
|
|
|
{
|
|
|
|
return self->tag == DW_TAG_subprogram;
|
|
|
|
}
|
|
|
|
|
2009-03-14 17:50:36 +01:00
|
|
|
/**
|
2007-06-12 20:01:23 +02:00
|
|
|
* function__for_each_parameter - iterate thru all the parameters
|
|
|
|
* @self: struct function instance to iterate
|
|
|
|
* @pos: struct parameter iterator
|
|
|
|
*/
|
|
|
|
#define function__for_each_parameter(self, pos) \
|
|
|
|
ftype__for_each_parameter(&self->proto, pos)
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
const char *function__name(struct function *self, const struct cu *cu);
|
|
|
|
size_t function__fprintf_stats(const struct tag *tag_self,
|
2009-03-31 02:47:59 +02:00
|
|
|
const struct cu *cu,
|
|
|
|
const struct conf_fprintf *conf,
|
|
|
|
FILE *fp);
|
2009-03-14 18:48:20 +01:00
|
|
|
const char *function__prototype(const struct function *self,
|
|
|
|
const struct cu *cu, char *bf, size_t len);
|
2006-11-18 17:33:48 +01:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
static __pure inline uint32_t function__size(const struct function *self)
|
2007-01-07 20:57:00 +01:00
|
|
|
{
|
2009-03-14 18:48:20 +01:00
|
|
|
return self->lexblock.size;
|
2007-01-07 20:57:00 +01:00
|
|
|
}
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
static inline int function__declared_inline(const struct function *self)
|
2009-03-06 13:27:40 +01:00
|
|
|
{
|
2009-03-14 18:48:20 +01:00
|
|
|
return (self->inlined == DW_INL_declared_inlined ||
|
|
|
|
self->inlined == DW_INL_declared_not_inlined);
|
2009-03-06 13:27:40 +01:00
|
|
|
}
|
2007-01-29 13:42:03 +01:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
static inline int function__inlined(const struct function *self)
|
2007-01-03 01:26:01 +01:00
|
|
|
{
|
2009-03-14 18:48:20 +01:00
|
|
|
return (self->inlined == DW_INL_inlined ||
|
|
|
|
self->inlined == DW_INL_declared_inlined);
|
2007-01-03 01:26:01 +01:00
|
|
|
}
|
|
|
|
|
2009-03-17 15:43:17 +01:00
|
|
|
/* struct class_member - struct, union, class member
|
|
|
|
*
|
2009-03-18 15:58:32 +01:00
|
|
|
* @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
|
2009-03-17 15:43:17 +01:00
|
|
|
* @byte_offset - offset in bytes from the start of the struct
|
2009-03-17 17:57:40 +01:00
|
|
|
* @byte_size - cached byte size, integral type byte size for bitfields
|
2009-03-17 15:43:17 +01:00
|
|
|
* @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)
|
|
|
|
*/
|
2009-03-14 18:48:20 +01:00
|
|
|
struct class_member {
|
2006-11-18 14:54:02 +01:00
|
|
|
struct tag tag;
|
2009-03-14 18:48:20 +01:00
|
|
|
strings_t name;
|
2009-03-18 15:58:32 +01:00
|
|
|
uint32_t bit_offset;
|
|
|
|
uint32_t bit_size;
|
2009-03-17 15:43:17 +01:00
|
|
|
uint32_t byte_offset;
|
2009-03-17 17:57:40 +01:00
|
|
|
size_t byte_size;
|
2009-03-17 15:43:17 +01:00
|
|
|
uint8_t bitfield_offset;
|
|
|
|
uint8_t bitfield_size;
|
|
|
|
uint8_t bit_hole;
|
|
|
|
uint8_t bitfield_end:1;
|
2009-03-14 18:48:20 +01:00
|
|
|
uint8_t visited:1;
|
2009-03-17 15:43:17 +01:00
|
|
|
uint8_t accessibility:2;
|
|
|
|
uint8_t virtuality:2;
|
|
|
|
uint16_t hole;
|
2006-11-03 16:41:19 +01:00
|
|
|
};
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
void class_member__delete(struct class_member *self);
|
|
|
|
|
|
|
|
static inline struct class_member *tag__class_member(const struct tag *self)
|
2007-01-03 01:26:01 +01:00
|
|
|
{
|
2009-03-14 18:48:20 +01:00
|
|
|
return (struct class_member *)self;
|
2007-01-03 01:26:01 +01:00
|
|
|
}
|
|
|
|
|
2009-04-02 22:54:43 +02:00
|
|
|
static inline const char *class_member__name(const struct class_member *self,
|
|
|
|
const struct cu *cu)
|
dwarves: Remove some more DWARF details from the core
Had to be a big sweeping change, but the regression tests shows just
improvements :-)
Now we stop using an id in struct tag, only storing the type, that now
uses 16 bits only, as CTF does.
Each format loader has to go on adding the types to the core, that
figures out if it is a tag that can be on the tag->type field
(tag__is_tag_type).
Formats that already have the types separated and in sequence, such as
CTF, just ask the core to insert in the types_table directly with its
original ID.
For DWARF, we ask the core to put it on the table, in sequence, and return the
index, that is then stashed with the DWARF specific info (original id, type,
decl_line, etc) and hashed by the original id. Later we recode everything,
looking up via the original type, getting the small_id to put on the tag->type.
The underlying debugging info not needed by the core is stashed in tag->priv,
and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of
the core tag and points it there, and makes that info available thru
cu->orig_info. In the future we can ask, when loading a cu, that this info be
trown away, so that we reduce the memory footprint for big multi-cu files such
as the Linux kernel.
There is also a routine to ask for inserting a NULL, as we still have
bugs in the CTF decoding and thus some entries are being lost, to avoid
using an undefined pointer when traversing the types_table the ctf
loader puts a NULL there via cu__table_nullify_type_entry() and then
cu__for_each_type skips those.
There is some more cleanups for leftovers that I avoided cleaning to
reduce this changeset.
And also while doing this I saw that enums can appear without any
enumerators and that an array with DW_TAG_GNU_vector is actually a
different tag, encoded this way till we get to DWARF4 ;-)
So now we don't have to lookup on a hash table looking for DWARF
offsets, we can do the more sensible thing of just indexing the
types_tags array.
Now to do some cleanups and try to get the per cu encoder done. Then
order all the cus per number of type entries, pick the one with more,
then go on merging/recoding the types of the others and putting the
parent linkage in place.
Just to show the extent of the changes:
$ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0
/home/acme/git/pahole/dwarves.c:
struct cu | -4048
struct tag | -32
struct ptr_to_member_type | -32
struct namespace | -32
struct type | -32
struct class | -32
struct base_type | -32
struct array_type | -32
struct class_member | -32
struct lexblock | -32
struct ftype | -32
struct function | -64
struct parameter | -32
struct variable | -32
struct inline_expansion | -32
struct label | -32
struct enumerator | -32
17 structs changed
tag__follow_typedef | +3
tag__fprintf_decl_info | +25
array_type__fprintf | +6
type__name | -126
type__find_first_biggest_size_base_type_member | -3
typedef__fprintf | +16
imported_declaration__fprintf | +6
imported_module__fprintf | +3
cu__new | +26
cu__delete | +26
hashtags__hash | -65
hash_64 | -124
hlist_add_head | -78
hashtags__find | -157
cu__hash | -80
cu__add_tag | +20
tag__prefix | -3
cu__find_tag_by_id | -2
cu__find_type_by_id | -3
cu__find_first_typedef_of_type | +38
cu__find_base_type_by_name | +68
cu__find_base_type_by_name_and_size | +72
cu__find_struct_by_name | +59
cus__find_struct_by_name | +8
cus__find_tag_by_id | +5
cus__find_cu_by_name | -6
lexblock__find_tag_by_id | -173
cu__find_variable_by_id | -197
list__find_tag_by_id | -308
cu__find_parameter_by_id | -60
tag__ptr_name | +6
tag__name | +15
variable__type | +13
variable__name | +7
class_member__size | +6
parameter__name | -119
tag__parameter | -14
parameter__type | -143
type__fprintf | -29
union__fprintf | +6
class__add_vtable_entry | -9
type__add_member | -6
type__clone_members | -3
enumeration__add | -6
function__name | -156
ftype__has_parm_of_type | -39
class__find_holes | -27
class__has_hole_ge | -3
type__nr_members_of_type | +3
lexblock__account_inline_expansions | +3
cu__account_inline_expansions | -18
ftype__fprintf_parms | +46
function__tag_fprintf | +24
lexblock__fprintf | -6
ftype__fprintf | +3
function__fprintf_stats | -18
function__size | -6
class__vtable_fprintf | -11
class__fprintf | -21
tag__fprintf | -35
60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541
/home/acme/git/pahole/ctf_loader.c:
struct ctf_short_type | +0
14 structs changed
type__init | -14
type__new | -9
class__new | -12
create_new_base_type | -7
create_new_base_type_float | -7
create_new_array | -8
create_new_subroutine_type | -9
create_full_members | -18
create_short_members | -18
create_new_class | +1
create_new_union | +1
create_new_enumeration | -19
create_new_forward_decl | -2
create_new_typedef | +3
create_new_tag | -5
load_types | +16
class__fixup_ctf_bitfields | -3
17 functions changed, 21 bytes added, 131 bytes removed, diff: -110
/home/acme/git/pahole/dwarf_loader.c:
17 structs changed
zalloc | -56
tag__init | +3
array_type__new | +20
type__init | -24
class_member__new | +46
inline_expansion__new | +12
class__new | +81
lexblock__init | +19
function__new | +43
die__create_new_array | +20
die__create_new_parameter | +4
die__create_new_label | +4
die__create_new_subroutine_type | +113
die__create_new_enumeration | -21
die__process_class | +79
die__process_namespace | +76
die__create_new_inline_expansion | +4
die__process_function | +147
__die__process_tag | +34
die__process_unit | +56
die__process | +90
21 functions changed, 851 bytes added, 101 bytes removed, diff: +750
/home/acme/git/pahole/dwarves.c:
struct ptr_table | +16
struct cu_orig_info | +32
2 structs changed
tag__decl_line | +68
tag__decl_file | +70
tag__orig_id | +71
ptr_table__init | +46
ptr_table__exit | +37
ptr_table__add | +183
ptr_table__add_with_id | +165
ptr_table__entry | +64
cu__table_add_tag | +171
cu__table_nullify_type_entry | +38
10 functions changed, 913 bytes added, diff: +913
/home/acme/git/pahole/ctf_loader.c:
2 structs changed
tag__alloc | +52
1 function changed, 52 bytes added, diff: +52
/home/acme/git/pahole/dwarf_loader.c:
struct dwarf_tag | +48
struct dwarf_cu | +4104
4 structs changed
dwarf_cu__init | +83
hashtags__hash | +61
hash_64 | +124
hlist_add_head | +78
hashtags__find | +161
cu__hash | +95
tag__is_tag_type | +171
tag__is_type | +85
tag__is_union | +28
tag__is_struct | +57
tag__is_typedef | +28
tag__is_enumeration | +28
dwarf_cu__find_tag_by_id | +56
dwarf_cu__find_type_by_id | +63
tag__alloc | +114
__tag__print_type_not_found | +108
namespace__recode_dwarf_types | +346
tag__namespace | +14
tag__has_namespace | +86
tag__is_namespace | +28
type__recode_dwarf_specification | +182
tag__type | +14
__tag__print_abstract_origin_not_found | +105
ftype__recode_dwarf_types | +322
tag__ftype | +14
tag__parameter | +14
lexblock__recode_dwarf_types | +736
tag__lexblock | +14
tag__label | +14
tag__recode_dwarf_type | +766
tag__ptr_to_member_type | +14
cu__recode_dwarf_types_table | +88
cu__recode_dwarf_types | +48
dwarf_tag__decl_file | +77
strings__ptr | +33
dwarf_tag__decl_line | +59
dwarf_tag__orig_id | +59
dwarf_tag__orig_type | +59
38 functions changed, 4432 bytes added, diff: +4432
build/libdwarves.so.1.0.0:
147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 00:29:35 +01:00
|
|
|
{
|
2009-04-02 22:54:43 +02:00
|
|
|
return cu__string(cu, self->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
|
|
|
}
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
/**
|
|
|
|
* struct type - base type for enumerations, structs and unions
|
|
|
|
*
|
|
|
|
* @nr_members: number of DW_TAG_member entries
|
|
|
|
* @nr_tags: number of tags
|
|
|
|
*/
|
|
|
|
struct type {
|
|
|
|
struct namespace namespace;
|
|
|
|
struct list_head node;
|
|
|
|
Dwarf_Off specification;
|
|
|
|
uint32_t size;
|
|
|
|
int32_t size_diff;
|
|
|
|
uint16_t nr_members;
|
|
|
|
uint8_t declaration; /* only one bit used */
|
|
|
|
uint8_t definition_emitted:1;
|
|
|
|
uint8_t fwd_decl_emitted:1;
|
|
|
|
uint8_t resized:1;
|
2007-04-28 21:13:35 +02:00
|
|
|
};
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
static inline struct class *type__class(const struct type *self)
|
|
|
|
{
|
|
|
|
return (struct class *)self;
|
|
|
|
}
|
2006-11-05 18:34:54 +01:00
|
|
|
|
2009-03-25 16:00:30 +01:00
|
|
|
void type__delete(struct type *self);
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
/**
|
|
|
|
* type__for_each_tag - iterate thru all the tags
|
|
|
|
* @self: struct type instance to iterate
|
|
|
|
* @pos: struct tag iterator
|
|
|
|
*/
|
|
|
|
#define type__for_each_tag(self, pos) \
|
|
|
|
list_for_each_entry(pos, &(self)->namespace.tags, node)
|
2007-01-07 20:13:39 +01:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
/**
|
|
|
|
* type__for_each_enumerator - iterate thru the enumerator entries
|
|
|
|
* @self: struct type instance to iterate
|
|
|
|
* @pos: struct enumerator iterator
|
|
|
|
*/
|
|
|
|
#define type__for_each_enumerator(self, pos) \
|
2009-03-20 16:53:43 +01:00
|
|
|
struct list_head *__type__for_each_enumerator_head = \
|
|
|
|
(self)->namespace.shared_tags ? \
|
|
|
|
(self)->namespace.tags.next : \
|
|
|
|
&(self)->namespace.tags; \
|
|
|
|
list_for_each_entry(pos, __type__for_each_enumerator_head, tag.node)
|
2006-10-28 23:22:42 +02:00
|
|
|
|
2009-03-25 16:17:50 +01:00
|
|
|
/**
|
|
|
|
* type__for_each_enumerator_safe - safely iterate thru the enumerator entries
|
|
|
|
* @self: struct type instance to iterate
|
|
|
|
* @pos: struct enumerator iterator
|
|
|
|
* @n: struct enumerator temp iterator
|
|
|
|
*/
|
|
|
|
#define type__for_each_enumerator_safe(self, pos, n) \
|
|
|
|
if ((self)->namespace.shared_tags) /* Do nothing */ ; else \
|
|
|
|
list_for_each_entry_safe(pos, n, &(self)->namespace.tags, tag.node)
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
/**
|
|
|
|
* type__for_each_member - iterate thru the entries that use space
|
|
|
|
* (data members and inheritance entries)
|
|
|
|
* @self: struct type instance to iterate
|
|
|
|
* @pos: struct class_member iterator
|
|
|
|
*/
|
|
|
|
#define type__for_each_member(self, pos) \
|
|
|
|
list_for_each_entry(pos, &(self)->namespace.tags, tag.node) \
|
|
|
|
if (!(pos->tag.tag == DW_TAG_member || \
|
|
|
|
pos->tag.tag == DW_TAG_inheritance)) \
|
|
|
|
continue; \
|
|
|
|
else
|
2007-01-13 13:57:19 +01:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
/**
|
|
|
|
* type__for_each_data_member - iterate thru the data member entries
|
|
|
|
* @self: struct type instance to iterate
|
|
|
|
* @pos: struct class_member iterator
|
|
|
|
*/
|
|
|
|
#define type__for_each_data_member(self, pos) \
|
|
|
|
list_for_each_entry(pos, &(self)->namespace.tags, tag.node) \
|
|
|
|
if (pos->tag.tag != DW_TAG_member) \
|
|
|
|
continue; \
|
|
|
|
else
|
2006-12-23 22:29:27 +01:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
/**
|
|
|
|
* type__for_each_member_safe - safely iterate thru the entries that use space
|
|
|
|
* (data members and inheritance entries)
|
|
|
|
* @self: struct type instance to iterate
|
|
|
|
* @pos: struct class_member iterator
|
|
|
|
* @n: struct class_member temp iterator
|
|
|
|
*/
|
|
|
|
#define type__for_each_member_safe(self, pos, n) \
|
|
|
|
list_for_each_entry_safe(pos, n, &(self)->namespace.tags, tag.node) \
|
|
|
|
if (pos->tag.tag != DW_TAG_member) \
|
|
|
|
continue; \
|
|
|
|
else
|
2008-01-14 23:04:57 +01:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
/**
|
|
|
|
* type__for_each_data_member_safe - safely iterate thru the data member entries
|
|
|
|
* @self: struct type instance to iterate
|
|
|
|
* @pos: struct class_member iterator
|
|
|
|
* @n: struct class_member temp iterator
|
|
|
|
*/
|
|
|
|
#define type__for_each_data_member_safe(self, pos, n) \
|
|
|
|
list_for_each_entry_safe(pos, n, &(self)->namespace.tags, tag.node) \
|
|
|
|
if (pos->tag.tag != DW_TAG_member) \
|
|
|
|
continue; \
|
|
|
|
else
|
2006-10-28 23:22:42 +02:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
void type__add_member(struct type *self, struct class_member *member);
|
|
|
|
struct class_member *
|
|
|
|
type__find_first_biggest_size_base_type_member(struct type *self,
|
|
|
|
const struct cu *cu);
|
2006-12-07 19:11:47 +01:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
struct class_member *type__find_member_by_name(const struct type *self,
|
2009-04-02 23:46:54 +02:00
|
|
|
const struct cu *cu,
|
2009-03-14 18:48:20 +01:00
|
|
|
const char *name);
|
|
|
|
uint32_t type__nr_members_of_type(const struct type *self,
|
|
|
|
const Dwarf_Off type);
|
|
|
|
struct class_member *type__last_member(struct type *self);
|
2006-11-18 17:33:48 +01:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
size_t typedef__fprintf(const struct tag *tag_self, const struct cu *cu,
|
|
|
|
const struct conf_fprintf *conf, FILE *fp);
|
|
|
|
|
|
|
|
static inline struct type *tag__type(const struct tag *self)
|
2006-11-11 19:31:04 +01:00
|
|
|
{
|
2009-03-14 18:48:20 +01:00
|
|
|
return (struct type *)self;
|
2006-11-11 19:31:04 +01:00
|
|
|
}
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
struct class {
|
|
|
|
struct type type;
|
|
|
|
struct list_head vtable;
|
|
|
|
uint16_t nr_vtable_entries;
|
|
|
|
uint8_t nr_holes;
|
|
|
|
uint8_t nr_bit_holes;
|
|
|
|
uint16_t padding;
|
|
|
|
uint8_t bit_padding;
|
|
|
|
void *priv;
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline struct class *tag__class(const struct tag *self)
|
2006-11-18 22:02:55 +01:00
|
|
|
{
|
2009-03-14 18:48:20 +01:00
|
|
|
return (struct class *)self;
|
2006-11-18 22:02:55 +01:00
|
|
|
}
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
static inline struct tag *class__tag(const struct class *self)
|
2006-11-18 22:02:55 +01:00
|
|
|
{
|
2009-03-14 18:48:20 +01:00
|
|
|
return (struct tag *)self;
|
2006-11-18 22:02:55 +01:00
|
|
|
}
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
struct class *class__clone(const struct class *from,
|
|
|
|
const char *new_class_name);
|
|
|
|
void class__delete(struct class *self);
|
2006-12-20 15:03:12 +01:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
static inline struct list_head *class__tags(struct class *self)
|
|
|
|
{
|
|
|
|
return &self->type.namespace.tags;
|
|
|
|
}
|
2008-01-13 18:18:39 +01:00
|
|
|
|
2009-04-02 23:46:54 +02:00
|
|
|
static __pure inline const char *namespace__name(const struct namespace *self,
|
|
|
|
const struct cu *cu)
|
|
|
|
{
|
|
|
|
return self->sname ?: cu__string(cu, self->name);
|
|
|
|
}
|
|
|
|
|
2009-04-02 22:54:43 +02:00
|
|
|
static __pure inline const char *type__name(const struct type *self,
|
|
|
|
const struct cu *cu)
|
2009-03-14 18:48:20 +01:00
|
|
|
{
|
2009-04-02 23:46:54 +02:00
|
|
|
return namespace__name(&self->namespace, cu);
|
2009-03-14 18:48:20 +01:00
|
|
|
}
|
2008-04-20 23:56:36 +02:00
|
|
|
|
2009-04-02 22:54:43 +02:00
|
|
|
static __pure inline const char *class__name(struct class *self,
|
|
|
|
const struct cu *cu)
|
2009-03-14 18:48:20 +01:00
|
|
|
{
|
2009-04-02 23:46:54 +02:00
|
|
|
return type__name(&self->type, cu);
|
2009-03-14 18:48:20 +01:00
|
|
|
}
|
2008-04-20 23:56:36 +02:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
static inline int class__is_struct(const struct class *self)
|
|
|
|
{
|
|
|
|
return tag__is_struct(&self->type.namespace.tag);
|
|
|
|
}
|
2006-12-19 12:11:17 +01:00
|
|
|
|
2009-03-17 18:31:18 +01:00
|
|
|
void class__find_holes(struct class *self);
|
2009-03-14 18:48:20 +01:00
|
|
|
int class__has_hole_ge(const struct class *self, const uint16_t size);
|
|
|
|
size_t class__fprintf(struct class *self, const struct cu *cu,
|
|
|
|
const struct conf_fprintf *conf, FILE *fp);
|
2007-01-09 13:00:47 +01:00
|
|
|
|
2008-03-03 17:50:44 +01:00
|
|
|
void class__add_vtable_entry(struct class *self, struct function *vtable_entry);
|
2007-01-09 13:00:47 +01:00
|
|
|
static inline struct class_member *
|
2009-04-02 23:46:54 +02:00
|
|
|
class__find_member_by_name(const struct class *self,
|
|
|
|
const struct cu *cu, const char *name)
|
2007-01-09 13:00:47 +01:00
|
|
|
{
|
2009-04-02 23:46:54 +02:00
|
|
|
return type__find_member_by_name(&self->type, cu, name);
|
2007-01-09 13:00:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint16_t class__nr_members(const struct class *self)
|
|
|
|
{
|
|
|
|
return self->type.nr_members;
|
|
|
|
}
|
|
|
|
|
2009-03-07 20:45:09 +01:00
|
|
|
static inline uint32_t class__size(const struct class *self)
|
2007-01-09 13:00:47 +01:00
|
|
|
{
|
|
|
|
return self->type.size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int class__is_declaration(const struct class *self)
|
|
|
|
{
|
|
|
|
return self->type.declaration;
|
|
|
|
}
|
[CODIFF]: Detect and print all sorts of changes in structs
[acme@newtoy examples]$ cat struct.c
static struct foo {
char a:2;
unsigned int b;
unsigned long c;
unsigned long d;
unsigned long e;
} bar;
int main(int argc, char *argv[])
{
printf("%d", bar.a);
}
[acme@newtoy examples]$
Then change "a:2" to "a:4":
[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
struct foo | +0
a:2;
from: char /* 0(6) 1(2) */
to: char /* 0(4) 1(4) */
1 struct changed
Now, on top of that move a after b:
[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
struct foo | +0
a:2;
from: char /* 0(6) 1(2) */
to: char /* 4(4) 1(4) */
b;
from: unsigned int /* 4(0) 4(0) */
to: unsigned int /* 0(0) 4(0) */
1 struct changed
[acme@newtoy examples]$
Move it back a to before b and change the type of e without changing its size,
i.e. from unsigned long to long:
[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
struct foo | +0
a:2;
from: char /* 0(6) 1(2) */
to: char /* 0(4) 1(4) */
e;
from: long unsigned int /* 16(0) 4(0) */
to: long int /* 16(0) 4(0) */
1 struct changed
[acme@newtoy examples]$
Now on top of this lets delete the c member:
[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
struct foo | -4
nr_members: -1
-long unsigned int c; /* 8 4 */
a:2;
from: char /* 0(6) 1(2) */
to: char /* 0(4) 1(4) */
d;
from: long unsigned int /* 12(0) 4(0) */
to: long unsigned int /* 8(0) 4(0) */
e;
from: long unsigned int /* 16(0) 4(0) */
to: long int /* 12(0) 4(0) */
1 struct changed
[acme@newtoy examples]$
WOW, many changes, what an ABI breakage, no? :-)
It started as:
[acme@newtoy examples]$ pahole old_struct foo
/* /home/acme/pahole/examples/struct.c:3 */
struct foo {
char a:2; /* 0 1 */
/* XXX 3 bytes hole, try to pack */
unsigned int b; /* 4 4 */
long unsigned int c; /* 8 4 */
long unsigned int d; /* 12 4 */
long unsigned int e; /* 16 4 */
}; /* size: 20, sum members: 17, holes: 1, sum holes: 3 */
And ended up as:
[acme@newtoy examples]$ pahole new_struct foo
/* /home/acme/pahole/examples/struct.c:3 */
struct foo {
char a:4; /* 0 1 */
/* XXX 3 bytes hole, try to pack */
unsigned int b; /* 4 4 */
long unsigned int d; /* 8 4 */
long int e; /* 12 4 */
}; /* size: 16, sum members: 13, holes: 1, sum holes: 3 */
[acme@newtoy examples]$
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 18:07:21 +01:00
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
const struct class_member *class__find_bit_hole(const struct class *self,
|
|
|
|
const struct class_member *trailer,
|
|
|
|
const uint16_t bit_hole_size);
|
2008-03-03 17:50:44 +01:00
|
|
|
|
2009-04-02 21:12:36 +02:00
|
|
|
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
|
|
|
|
};
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
struct base_type {
|
|
|
|
struct tag tag;
|
|
|
|
strings_t name;
|
|
|
|
uint16_t bit_size;
|
2009-04-02 21:12:36 +02:00
|
|
|
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;
|
2009-03-14 18:48:20 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static inline struct base_type *tag__base_type(const struct tag *self)
|
|
|
|
{
|
|
|
|
return (struct base_type *)self;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint16_t base_type__size(const struct tag *self)
|
|
|
|
{
|
|
|
|
return tag__base_type(self)->bit_size / 8;
|
|
|
|
}
|
|
|
|
|
2009-04-02 22:54:43 +02:00
|
|
|
const char *base_type__name(const struct base_type *self, const struct cu *cu,
|
|
|
|
char *bf, size_t len);
|
2009-03-14 18:48:20 +01:00
|
|
|
|
2009-04-02 23:46:54 +02:00
|
|
|
void base_type_name_to_size_table__init(struct strings *strings);
|
2009-03-18 15:48:40 +01:00
|
|
|
size_t base_type__name_to_size(struct base_type *self, struct cu *cu);
|
|
|
|
|
2009-03-14 18:48:20 +01:00
|
|
|
struct array_type {
|
|
|
|
struct tag tag;
|
|
|
|
uint32_t *nr_entries;
|
|
|
|
uint8_t dimensions;
|
2009-03-23 20:56:57 +01:00
|
|
|
bool is_vector;
|
2009-03-14 18:48:20 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static inline struct array_type *tag__array_type(const struct tag *self)
|
|
|
|
{
|
|
|
|
return (struct array_type *)self;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct enumerator {
|
|
|
|
struct tag tag;
|
|
|
|
strings_t name;
|
|
|
|
uint32_t value;
|
|
|
|
};
|
|
|
|
|
2009-03-25 16:17:50 +01:00
|
|
|
void enumeration__delete(struct type *self);
|
2009-03-14 18:48:20 +01:00
|
|
|
void enumeration__add(struct type *self, struct enumerator *enumerator);
|
2009-04-02 22:54:43 +02:00
|
|
|
size_t enumeration__fprintf(const struct tag *tag_self, const struct cu *cu,
|
2009-03-14 18:48:20 +01:00
|
|
|
const struct conf_fprintf *conf, FILE *fp);
|
|
|
|
|
|
|
|
int dwarves__init(uint16_t user_cacheline_size);
|
|
|
|
void dwarves__exit(void);
|
2006-11-20 18:43:39 +01:00
|
|
|
|
2009-03-14 17:37:14 +01:00
|
|
|
const char *dwarf_tag_name(const uint32_t tag);
|
2008-03-03 17:50:44 +01:00
|
|
|
|
2009-02-13 13:57:23 +01:00
|
|
|
struct argp_state;
|
|
|
|
|
|
|
|
void dwarves_print_version(FILE *fp, struct argp_state *state);
|
|
|
|
|
2007-01-29 13:42:03 +01:00
|
|
|
#endif /* _DWARVES_H_ */
|