[LIB]: Introduce struct namespace
For now its just the direct ancestor of struct type. But it will exists by itself, to represent the DW_TAG_namespace DWARF tag, that is how the C++ 'namespace' (and other languages too, heck, I'd love to get my hands on a binary with DWARF info built from, say, ADA source code, objectiveC... COBOL! :-P). Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
This commit is contained in:
parent
c1eff2b2ca
commit
9bf0fda9b0
35
dwarves.c
35
dwarves.c
|
@ -356,18 +356,23 @@ static size_t array_type__fprintf(const struct tag *tag_self,
|
||||||
return printed;
|
return printed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void type__init(struct type *self, Dwarf_Die *die)
|
static void namespace__init(struct namespace *self, Dwarf_Die *die)
|
||||||
{
|
{
|
||||||
tag__init(&self->tag, die);
|
tag__init(&self->tag, die);
|
||||||
INIT_LIST_HEAD(&self->node);
|
|
||||||
INIT_LIST_HEAD(&self->tags);
|
INIT_LIST_HEAD(&self->tags);
|
||||||
self->name = strings__add(attr_string(die, DW_AT_name));
|
self->name = strings__add(attr_string(die, DW_AT_name));
|
||||||
|
self->nr_tags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void type__init(struct type *self, Dwarf_Die *die)
|
||||||
|
{
|
||||||
|
namespace__init(&self->namespace, die);
|
||||||
|
INIT_LIST_HEAD(&self->node);
|
||||||
self->size = attr_numeric(die, DW_AT_byte_size);
|
self->size = attr_numeric(die, DW_AT_byte_size);
|
||||||
self->declaration = attr_numeric(die, DW_AT_declaration);
|
self->declaration = attr_numeric(die, DW_AT_declaration);
|
||||||
self->definition_emitted = 0;
|
self->definition_emitted = 0;
|
||||||
self->fwd_decl_emitted = 0;
|
self->fwd_decl_emitted = 0;
|
||||||
self->nr_members = 0;
|
self->nr_members = 0;
|
||||||
self->nr_tags = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct type *type__new(Dwarf_Die *die)
|
static struct type *type__new(Dwarf_Die *die)
|
||||||
|
@ -1353,7 +1358,7 @@ void class__delete(struct class *self)
|
||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void type__add_tag(struct type *self, struct tag *tag)
|
static void namespace__add_tag(struct namespace *self, struct tag *tag)
|
||||||
{
|
{
|
||||||
++self->nr_tags;
|
++self->nr_tags;
|
||||||
list_add_tail(&tag->node, &self->tags);
|
list_add_tail(&tag->node, &self->tags);
|
||||||
|
@ -1362,14 +1367,14 @@ static void type__add_tag(struct type *self, struct tag *tag)
|
||||||
static void type__add_member(struct type *self, struct class_member *member)
|
static void type__add_member(struct type *self, struct class_member *member)
|
||||||
{
|
{
|
||||||
++self->nr_members;
|
++self->nr_members;
|
||||||
type__add_tag(self, &member->tag);
|
namespace__add_tag(&self->namespace, &member->tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct class_member *type__last_member(struct type *self)
|
struct class_member *type__last_member(struct type *self)
|
||||||
{
|
{
|
||||||
struct class_member *pos;
|
struct class_member *pos;
|
||||||
|
|
||||||
list_for_each_entry_reverse(pos, &self->tags, tag.node)
|
list_for_each_entry_reverse(pos, &self->namespace.tags, tag.node)
|
||||||
if (pos->tag.tag == DW_TAG_member)
|
if (pos->tag.tag == DW_TAG_member)
|
||||||
return pos;
|
return pos;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1380,7 +1385,7 @@ static int type__clone_members(struct type *self, const struct type *from)
|
||||||
struct class_member *pos;
|
struct class_member *pos;
|
||||||
|
|
||||||
self->nr_members = 0;
|
self->nr_members = 0;
|
||||||
INIT_LIST_HEAD(&self->tags);
|
INIT_LIST_HEAD(&self->namespace.tags);
|
||||||
|
|
||||||
type__for_each_member(from, pos) {
|
type__for_each_member(from, pos) {
|
||||||
struct class_member *member_clone = class_member__clone(pos);
|
struct class_member *member_clone = class_member__clone(pos);
|
||||||
|
@ -1405,7 +1410,7 @@ struct class *class__clone(const struct class *from,
|
||||||
self = NULL;
|
self = NULL;
|
||||||
}
|
}
|
||||||
if (new_class_name != NULL)
|
if (new_class_name != NULL)
|
||||||
self->type.name = strings__add(new_class_name);
|
self->type.namespace.name = strings__add(new_class_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -1414,7 +1419,7 @@ struct class *class__clone(const struct class *from,
|
||||||
static void enumeration__add(struct type *self, struct enumerator *enumerator)
|
static void enumeration__add(struct type *self, struct enumerator *enumerator)
|
||||||
{
|
{
|
||||||
++self->nr_members;
|
++self->nr_members;
|
||||||
type__add_tag(self, &enumerator->tag);
|
namespace__add_tag(&self->namespace, &enumerator->tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lexblock__init(struct lexblock *self, Dwarf_Die *die)
|
static void lexblock__init(struct lexblock *self, Dwarf_Die *die)
|
||||||
|
@ -2373,7 +2378,7 @@ static struct tag *die__create_new_class(Dwarf_Die *die, struct cu *cu)
|
||||||
if (dwarf_haschildren(die) != 0 && dwarf_child(die, &child) == 0)
|
if (dwarf_haschildren(die) != 0 && dwarf_child(die, &child) == 0)
|
||||||
die__process_class(&child, &class->type, cu);
|
die__process_class(&child, &class->type, cu);
|
||||||
|
|
||||||
return &class->type.tag;
|
return &class->type.namespace.tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct tag *die__create_new_union(Dwarf_Die *die, struct cu *cu)
|
static struct tag *die__create_new_union(Dwarf_Die *die, struct cu *cu)
|
||||||
|
@ -2387,7 +2392,7 @@ static struct tag *die__create_new_union(Dwarf_Die *die, struct cu *cu)
|
||||||
if (dwarf_haschildren(die) != 0 && dwarf_child(die, &child) == 0)
|
if (dwarf_haschildren(die) != 0 && dwarf_child(die, &child) == 0)
|
||||||
die__process_class(&child, utype, cu);
|
die__process_class(&child, utype, cu);
|
||||||
|
|
||||||
return &utype->tag;
|
return &utype->namespace.tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct tag *die__create_new_base_type(Dwarf_Die *die)
|
static struct tag *die__create_new_base_type(Dwarf_Die *die)
|
||||||
|
@ -2415,7 +2420,7 @@ static struct tag *die__create_new_typedef(Dwarf_Die *die)
|
||||||
fprintf(stderr, "%s: DW_TAG_typedef WITH children!\n",
|
fprintf(stderr, "%s: DW_TAG_typedef WITH children!\n",
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
|
|
||||||
return &tdef->tag;
|
return &tdef->namespace.tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct tag *die__create_new_array(Dwarf_Die *die)
|
static struct tag *die__create_new_array(Dwarf_Die *die)
|
||||||
|
@ -2560,7 +2565,7 @@ static struct tag *die__create_new_enumeration(Dwarf_Die *die)
|
||||||
enumeration__add(enumeration, enumerator);
|
enumeration__add(enumeration, enumerator);
|
||||||
} while (dwarf_siblingof(die, die) == 0);
|
} while (dwarf_siblingof(die, die) == 0);
|
||||||
|
|
||||||
return &enumeration->tag;
|
return &enumeration->namespace.tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void die__process_class(Dwarf_Die *die, struct type *class,
|
static void die__process_class(Dwarf_Die *die, struct type *class,
|
||||||
|
@ -2582,7 +2587,7 @@ static void die__process_class(Dwarf_Die *die, struct type *class,
|
||||||
struct tag *tag = die__process_tag(die, cu);
|
struct tag *tag = die__process_tag(die, cu);
|
||||||
|
|
||||||
if (tag != NULL)
|
if (tag != NULL)
|
||||||
type__add_tag(class, tag);
|
namespace__add_tag(&class->namespace, tag);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
26
dwarves.h
26
dwarves.h
|
@ -57,6 +57,13 @@ struct tag {
|
||||||
uint32_t refcnt;
|
uint32_t refcnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct namespace {
|
||||||
|
struct tag tag;
|
||||||
|
const char *name;
|
||||||
|
struct list_head tags;
|
||||||
|
uint16_t nr_tags;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct type - base type for enumerations, structs and unions
|
* struct type - base type for enumerations, structs and unions
|
||||||
*
|
*
|
||||||
|
@ -64,12 +71,9 @@ struct tag {
|
||||||
* @nr_tags: number of tags
|
* @nr_tags: number of tags
|
||||||
*/
|
*/
|
||||||
struct type {
|
struct type {
|
||||||
struct tag tag;
|
struct namespace namespace;
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
const char *name;
|
|
||||||
size_t size;
|
size_t size;
|
||||||
struct list_head tags;
|
|
||||||
uint16_t nr_tags;
|
|
||||||
uint16_t nr_members;
|
uint16_t nr_members;
|
||||||
uint8_t declaration; /* only one bit used */
|
uint8_t declaration; /* only one bit used */
|
||||||
uint8_t definition_emitted:1;
|
uint8_t definition_emitted:1;
|
||||||
|
@ -82,7 +86,7 @@ struct type {
|
||||||
* @pos: struct tag iterator
|
* @pos: struct tag iterator
|
||||||
*/
|
*/
|
||||||
#define type__for_each_tag(self, pos) \
|
#define type__for_each_tag(self, pos) \
|
||||||
list_for_each_entry(pos, &(self)->tags, node)
|
list_for_each_entry(pos, &(self)->namespace.tags, node)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* type__for_each_enumerator - iterate thru the enumerator entries
|
* type__for_each_enumerator - iterate thru the enumerator entries
|
||||||
|
@ -90,7 +94,7 @@ struct type {
|
||||||
* @pos: struct enumerator iterator
|
* @pos: struct enumerator iterator
|
||||||
*/
|
*/
|
||||||
#define type__for_each_enumerator(self, pos) \
|
#define type__for_each_enumerator(self, pos) \
|
||||||
list_for_each_entry(pos, &(self)->tags, tag.node)
|
list_for_each_entry(pos, &(self)->namespace.tags, tag.node)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* type__for_each_member - iterate thru the DW_TAG_member entries
|
* type__for_each_member - iterate thru the DW_TAG_member entries
|
||||||
|
@ -98,7 +102,7 @@ struct type {
|
||||||
* @pos: struct class_member iterator
|
* @pos: struct class_member iterator
|
||||||
*/
|
*/
|
||||||
#define type__for_each_member(self, pos) \
|
#define type__for_each_member(self, pos) \
|
||||||
list_for_each_entry(pos, &(self)->tags, tag.node) \
|
list_for_each_entry(pos, &(self)->namespace.tags, tag.node) \
|
||||||
if (pos->tag.tag != DW_TAG_member) \
|
if (pos->tag.tag != DW_TAG_member) \
|
||||||
continue; \
|
continue; \
|
||||||
else
|
else
|
||||||
|
@ -110,7 +114,7 @@ struct type {
|
||||||
* @n: struct class_member temp iterator
|
* @n: struct class_member temp iterator
|
||||||
*/
|
*/
|
||||||
#define type__for_each_member_safe(self, pos, n) \
|
#define type__for_each_member_safe(self, pos, n) \
|
||||||
list_for_each_entry_safe(pos, n, &(self)->tags, tag.node) \
|
list_for_each_entry_safe(pos, n, &(self)->namespace.tags, tag.node) \
|
||||||
if (pos->tag.tag != DW_TAG_member) \
|
if (pos->tag.tag != DW_TAG_member) \
|
||||||
continue; \
|
continue; \
|
||||||
else
|
else
|
||||||
|
@ -145,12 +149,12 @@ extern void class__delete(struct class *self);
|
||||||
|
|
||||||
static inline struct list_head *class__tags(struct class *self)
|
static inline struct list_head *class__tags(struct class *self)
|
||||||
{
|
{
|
||||||
return &self->type.tags;
|
return &self->type.namespace.tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char *type__name(const struct type *self)
|
static inline const char *type__name(const struct type *self)
|
||||||
{
|
{
|
||||||
return self->name;
|
return self->namespace.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char *class__name(const struct class *self)
|
static inline const char *class__name(const struct class *self)
|
||||||
|
@ -160,7 +164,7 @@ static inline const char *class__name(const struct class *self)
|
||||||
|
|
||||||
static inline uint16_t class__tag_type(const struct class *self)
|
static inline uint16_t class__tag_type(const struct class *self)
|
||||||
{
|
{
|
||||||
return self->type.tag.tag;
|
return self->type.namespace.tag.tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct base_type {
|
struct base_type {
|
||||||
|
|
|
@ -189,7 +189,7 @@ int cus__emit_fwd_decl(struct cus *self, struct type *ctype, FILE *fp)
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fp, "%s %s;\n",
|
fprintf(fp, "%s %s;\n",
|
||||||
ctype->tag.tag == DW_TAG_union_type ? "union" : "struct",
|
ctype->namespace.tag.tag == DW_TAG_union_type ? "union" : "struct",
|
||||||
type__name(ctype));
|
type__name(ctype));
|
||||||
cus__add_fwd_decl(self, ctype);
|
cus__add_fwd_decl(self, ctype);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
2
pahole.c
2
pahole.c
|
@ -436,7 +436,7 @@ static char tab[128];
|
||||||
static void print_containers(const struct structure *s, int ident)
|
static void print_containers(const struct structure *s, int ident)
|
||||||
{
|
{
|
||||||
struct structure *pos;
|
struct structure *pos;
|
||||||
const Dwarf_Off type = s->class->type.tag.id;
|
const Dwarf_Off type = s->class->type.namespace.tag.id;
|
||||||
|
|
||||||
list_for_each_entry(pos, &structures__list, node) {
|
list_for_each_entry(pos, &structures__list, node) {
|
||||||
const struct class *c = pos->class;
|
const struct class *c = pos->class;
|
||||||
|
|
Loading…
Reference in New Issue