dwarves: Make all the tags that have an IP to be derived from ip_tag

Next we'll add a new kind of tag, DW_TAG_perf_counter, that will come
from perf.data generated by 'perf report'.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2009-06-04 17:30:06 -03:00
parent e429f8efbb
commit 7c6603189e
7 changed files with 62 additions and 61 deletions

View File

@ -218,7 +218,7 @@ static struct function *hashaddr__find_function(const struct hlist_head hashtabl
const struct hlist_head *head = &hashtable[bucket]; const struct hlist_head *head = &hashtable[bucket];
hlist_for_each_entry(function, pos, head, tool_hnode) { hlist_for_each_entry(function, pos, head, tool_hnode) {
if (function->lexblock.low_pc == addr) if (function->lexblock.ip.addr == addr)
return function; return function;
} }
@ -234,7 +234,7 @@ static struct variable *hashaddr__find_variable(const struct hlist_head hashtabl
const struct hlist_head *head = &hashtable[bucket]; const struct hlist_head *head = &hashtable[bucket];
hlist_for_each_entry(variable, pos, head, tool_hnode) { hlist_for_each_entry(variable, pos, head, tool_hnode) {
if (variable->addr == addr) if (variable->ip.addr == addr)
return variable; return variable;
} }
@ -269,7 +269,7 @@ int cu__encode_ctf(struct cu *self)
struct function *function; struct function *function;
cu__for_each_function(self, id, function) { cu__for_each_function(self, id, function) {
uint64_t addr = function->lexblock.low_pc; uint64_t addr = function->lexblock.ip.addr;
struct hlist_head *head = &hash_addr[hashaddr__fn(addr)]; struct hlist_head *head = &hash_addr[hashaddr__fn(addr)];
hlist_add_head(&function->tool_hnode, head); hlist_add_head(&function->tool_hnode, head);
} }
@ -318,7 +318,7 @@ int cu__encode_ctf(struct cu *self)
var = tag__variable(pos); var = tag__variable(pos);
if (var->location != LOCATION_GLOBAL) if (var->location != LOCATION_GLOBAL)
continue; continue;
struct hlist_head *head = &hash_addr[hashaddr__fn(var->addr)]; struct hlist_head *head = &hash_addr[hashaddr__fn(var->ip.addr)];
hlist_add_head(&var->tool_hnode, head); hlist_add_head(&var->tool_hnode, head);
} }
@ -339,7 +339,7 @@ int cu__encode_ctf(struct cu *self)
continue; continue;
} }
err = ctf__add_object(ctf, var->tag.type); err = ctf__add_object(ctf, var->ip.tag.type);
if (err != 0) if (err != 0)
goto out_err_ctf; goto out_err_ctf;
} }

View File

@ -86,7 +86,7 @@ static struct function *function__new(uint16_t **ptr, GElf_Sym *sym,
struct function *self = tag__alloc(sizeof(*self)); struct function *self = tag__alloc(sizeof(*self));
if (self != NULL) { if (self != NULL) {
self->lexblock.low_pc = elf_sym__value(sym); self->lexblock.ip.addr = elf_sym__value(sym);
self->lexblock.size = elf_sym__size(sym); self->lexblock.size = elf_sym__size(sym);
self->name = sym->st_name; self->name = sym->st_name;
self->vtable_entry = -1; self->vtable_entry = -1;
@ -554,13 +554,13 @@ static struct variable *variable__new(uint16_t type, GElf_Sym *sym,
if (self != NULL) { if (self != NULL) {
self->location = LOCATION_GLOBAL; self->location = LOCATION_GLOBAL;
self->addr = elf_sym__value(sym); self->ip.addr = elf_sym__value(sym);
self->name = sym->st_name; self->name = sym->st_name;
self->external = elf_sym__bind(sym) == STB_GLOBAL; self->external = elf_sym__bind(sym) == STB_GLOBAL;
self->tag.tag = DW_TAG_variable; self->ip.tag.tag = DW_TAG_variable;
self->tag.type = type; self->ip.tag.type = type;
long id = -1; /* FIXME: not needed for variables... */ long id = -1; /* FIXME: not needed for variables... */
cu__add_tag(ctf->priv, &self->tag, &id); cu__add_tag(ctf->priv, &self->ip.tag, &id);
} }
return self; return self;

View File

@ -469,16 +469,16 @@ static struct variable *variable__new(Dwarf_Die *die)
struct variable *self = tag__alloc(sizeof(*self)); struct variable *self = tag__alloc(sizeof(*self));
if (self != NULL) { if (self != NULL) {
tag__init(&self->tag, die); tag__init(&self->ip.tag, die);
self->name = strings__add(strings, attr_string(die, DW_AT_name)); self->name = strings__add(strings, attr_string(die, DW_AT_name));
/* variable is visible outside of its enclosing cu */ /* variable is visible outside of its enclosing cu */
self->external = dwarf_hasattr(die, DW_AT_external); self->external = dwarf_hasattr(die, DW_AT_external);
/* non-defining declaration of an object */ /* non-defining declaration of an object */
self->declaration = dwarf_hasattr(die, DW_AT_declaration); self->declaration = dwarf_hasattr(die, DW_AT_declaration);
self->location = LOCATION_UNKNOWN; self->location = LOCATION_UNKNOWN;
self->addr = 0; self->ip.addr = 0;
if (!self->declaration) if (!self->declaration)
self->location = dwarf__location(die, &self->addr); self->location = dwarf__location(die, &self->ip.addr);
} }
return self; return self;
@ -655,20 +655,20 @@ static struct inline_expansion *inline_expansion__new(Dwarf_Die *die)
struct inline_expansion *self = tag__alloc(sizeof(*self)); struct inline_expansion *self = tag__alloc(sizeof(*self));
if (self != NULL) { if (self != NULL) {
struct dwarf_tag *dtag = self->tag.priv; struct dwarf_tag *dtag = self->ip.tag.priv;
tag__init(&self->tag, die); tag__init(&self->ip.tag, die);
dtag->decl_file = dtag->decl_file =
strings__add(strings, attr_string(die, DW_AT_call_file)); strings__add(strings, attr_string(die, DW_AT_call_file));
dtag->decl_line = attr_numeric(die, DW_AT_call_line); dtag->decl_line = attr_numeric(die, DW_AT_call_line);
dtag->type = attr_type(die, DW_AT_abstract_origin); dtag->type = attr_type(die, DW_AT_abstract_origin);
if (dwarf_lowpc(die, &self->low_pc)) if (dwarf_lowpc(die, &self->ip.addr))
self->low_pc = 0; self->ip.addr = 0;
if (dwarf_lowpc(die, &self->high_pc)) if (dwarf_lowpc(die, &self->high_pc))
self->high_pc = 0; self->high_pc = 0;
self->size = self->high_pc - self->low_pc; self->size = self->high_pc - self->ip.addr;
if (self->size == 0) { if (self->size == 0) {
Dwarf_Addr base, start; Dwarf_Addr base, start;
ptrdiff_t offset = 0; ptrdiff_t offset = 0;
@ -681,8 +681,8 @@ static struct inline_expansion *inline_expansion__new(Dwarf_Die *die)
if (offset <= 0) if (offset <= 0)
break; break;
self->size += self->high_pc - start; self->size += self->high_pc - start;
if (self->low_pc == 0) if (self->ip.addr == 0)
self->low_pc = start; self->ip.addr = start;
} }
} }
} }
@ -695,10 +695,10 @@ static struct label *label__new(Dwarf_Die *die)
struct label *self = tag__alloc(sizeof(*self)); struct label *self = tag__alloc(sizeof(*self));
if (self != NULL) { if (self != NULL) {
tag__init(&self->tag, die); tag__init(&self->ip.tag, die);
self->name = strings__add(strings, attr_string(die, DW_AT_name)); self->name = strings__add(strings, attr_string(die, DW_AT_name));
if (dwarf_lowpc(die, &self->low_pc)) if (dwarf_lowpc(die, &self->ip.addr))
self->low_pc = 0; self->ip.addr = 0;
} }
return self; return self;
@ -726,13 +726,13 @@ static void lexblock__init(struct lexblock *self, Dwarf_Die *die)
{ {
Dwarf_Off high_pc; Dwarf_Off high_pc;
if (dwarf_lowpc(die, &self->low_pc)) if (dwarf_lowpc(die, &self->ip.addr))
self->low_pc = 0; self->ip.addr = 0;
if (dwarf_highpc(die, &high_pc)) if (dwarf_highpc(die, &high_pc))
self->size = 0; self->size = 0;
else else
self->size = high_pc - self->low_pc; self->size = high_pc - self->ip.addr;
INIT_LIST_HEAD(&self->tags); INIT_LIST_HEAD(&self->tags);
@ -748,7 +748,7 @@ static struct lexblock *lexblock__new(Dwarf_Die *die)
struct lexblock *self = tag__alloc(sizeof(*self)); struct lexblock *self = tag__alloc(sizeof(*self));
if (self != NULL) { if (self != NULL) {
tag__init(&self->tag, die); tag__init(&self->ip.tag, die);
lexblock__init(self, die); lexblock__init(self, die);
} }
@ -1017,14 +1017,14 @@ static struct tag *die__create_new_label(Dwarf_Die *die,
return NULL; return NULL;
lexblock__add_label(lexblock, label); lexblock__add_label(lexblock, label);
return &label->tag; return &label->ip.tag;
} }
static struct tag *die__create_new_variable(Dwarf_Die *die) static struct tag *die__create_new_variable(Dwarf_Die *die)
{ {
struct variable *var = variable__new(die); struct variable *var = variable__new(die);
return var ? &var->tag : NULL; return var ? &var->ip.tag : NULL;
} }
static struct tag *die__create_new_subroutine_type(Dwarf_Die *die, static struct tag *die__create_new_subroutine_type(Dwarf_Die *die,
@ -1297,7 +1297,7 @@ static struct tag *die__create_new_inline_expansion(Dwarf_Die *die,
if (lexblock != NULL) if (lexblock != NULL)
lexblock__add_inline_expansion(lexblock, exp); lexblock__add_inline_expansion(lexblock, exp);
return &exp->tag; return &exp->ip.tag;
} }
static int die__process_function(Dwarf_Die *die, struct ftype *ftype, static int die__process_function(Dwarf_Die *die, struct ftype *ftype,

View File

@ -53,7 +53,7 @@ static void lexblock__delete_tags(struct tag *tself)
void lexblock__delete(struct lexblock *self) void lexblock__delete(struct lexblock *self)
{ {
lexblock__delete_tags(&self->tag); lexblock__delete_tags(&self->ip.tag);
free(self); free(self);
} }
@ -379,7 +379,7 @@ static void cu__insert_function(struct cu *self, struct tag *tag)
while (*p != NULL) { while (*p != NULL) {
parent = *p; parent = *p;
f = rb_entry(parent, struct function, rb_node); f = rb_entry(parent, struct function, rb_node);
if (function->lexblock.low_pc < f->lexblock.low_pc) if (function->lexblock.ip.addr < f->lexblock.ip.addr)
p = &(*p)->rb_left; p = &(*p)->rb_left;
else else
p = &(*p)->rb_right; p = &(*p)->rb_right;
@ -726,9 +726,9 @@ struct function *cu__find_function_at_addr(const struct cu *self,
while (n) { while (n) {
struct function *f = rb_entry(n, struct function, rb_node); struct function *f = rb_entry(n, struct function, rb_node);
if (addr < f->lexblock.low_pc) if (addr < f->lexblock.ip.addr)
n = n->rb_left; n = n->rb_left;
else if (addr >= f->lexblock.low_pc + f->lexblock.size) else if (addr >= f->lexblock.ip.addr + f->lexblock.size)
n = n->rb_right; n = n->rb_right;
else else
return f; return f;
@ -846,7 +846,7 @@ const char *variable__type_name(const struct variable *self,
const struct cu *cu, const struct cu *cu,
char *bf, size_t len) char *bf, size_t len)
{ {
const struct tag *tag = cu__type(cu, self->tag.type); const struct tag *tag = cu__type(cu, self->ip.tag.type);
return tag != NULL ? tag__name(tag, cu, bf, len) : NULL; return tag != NULL ? tag__name(tag, cu, bf, len) : NULL;
} }
@ -982,7 +982,7 @@ void enumeration__add(struct type *self, struct enumerator *enumerator)
void lexblock__add_lexblock(struct lexblock *self, struct lexblock *child) void lexblock__add_lexblock(struct lexblock *self, struct lexblock *child)
{ {
++self->nr_lexblocks; ++self->nr_lexblocks;
list_add_tail(&child->tag.node, &self->tags); list_add_tail(&child->ip.tag.node, &self->tags);
} }
const char *function__name(struct function *self, const struct cu *cu) const char *function__name(struct function *self, const struct cu *cu)
@ -1013,7 +1013,7 @@ void ftype__delete(struct ftype *self)
void function__delete(struct function *self) void function__delete(struct function *self)
{ {
lexblock__delete_tags(&self->lexblock.tag); lexblock__delete_tags(&self->lexblock.ip.tag);
ftype__delete(&self->proto); ftype__delete(&self->proto);
} }
@ -1049,19 +1049,19 @@ void lexblock__add_inline_expansion(struct lexblock *self,
{ {
++self->nr_inline_expansions; ++self->nr_inline_expansions;
self->size_inline_expansions += exp->size; self->size_inline_expansions += exp->size;
lexblock__add_tag(self, &exp->tag); lexblock__add_tag(self, &exp->ip.tag);
} }
void lexblock__add_variable(struct lexblock *self, struct variable *var) void lexblock__add_variable(struct lexblock *self, struct variable *var)
{ {
++self->nr_variables; ++self->nr_variables;
lexblock__add_tag(self, &var->tag); lexblock__add_tag(self, &var->ip.tag);
} }
void lexblock__add_label(struct lexblock *self, struct label *label) void lexblock__add_label(struct lexblock *self, struct label *label)
{ {
++self->nr_labels; ++self->nr_labels;
lexblock__add_tag(self, &label->tag); lexblock__add_tag(self, &label->ip.tag);
} }
const struct class_member *class__find_bit_hole(const struct class *self, const struct class_member *class__find_bit_hole(const struct class *self,

View File

@ -483,10 +483,14 @@ void namespace__delete(struct namespace *self);
void namespace__add_tag(struct namespace *self, struct tag *tag); void namespace__add_tag(struct namespace *self, struct tag *tag);
struct ip_tag {
struct tag tag;
uint64_t addr;
};
struct inline_expansion { struct inline_expansion {
struct tag tag; struct ip_tag ip;
size_t size; size_t size;
uint64_t low_pc;
uint64_t high_pc; uint64_t high_pc;
}; };
@ -497,9 +501,8 @@ static inline struct inline_expansion *
} }
struct label { struct label {
struct tag tag; struct ip_tag ip;
strings_t name; strings_t name;
uint64_t low_pc;
}; };
static inline struct label *tag__label(const struct tag *self) static inline struct label *tag__label(const struct tag *self)
@ -516,12 +519,11 @@ enum vlocation {
} __attribute__((packed)); } __attribute__((packed));
struct variable { struct variable {
struct tag tag; struct ip_tag ip;
strings_t name; strings_t name;
uint8_t external:1; uint8_t external:1;
uint8_t declaration:1; uint8_t declaration:1;
enum vlocation location; enum vlocation location;
uint64_t addr;
struct hlist_node tool_hnode; struct hlist_node tool_hnode;
}; };
@ -536,9 +538,8 @@ const char *variable__type_name(const struct variable *self,
const struct cu *cu, char *bf, size_t len); const struct cu *cu, char *bf, size_t len);
struct lexblock { struct lexblock {
struct tag tag; struct ip_tag ip;
struct list_head tags; struct list_head tags;
uint64_t low_pc;
uint32_t size; uint32_t size;
uint16_t nr_inline_expansions; uint16_t nr_inline_expansions;
uint16_t nr_labels; uint16_t nr_labels;

View File

@ -843,12 +843,12 @@ static size_t function__tag_fprintf(const struct tag *tag, const struct cu *cu,
switch (tag->tag) { switch (tag->tag) {
case DW_TAG_inlined_subroutine: { case DW_TAG_inlined_subroutine: {
const struct inline_expansion *exp = vtag; const struct inline_expansion *exp = vtag;
const struct tag *talias = cu__function(cu, exp->tag.type); const struct tag *talias = cu__function(cu, exp->ip.tag.type);
struct function *alias = tag__function(talias); struct function *alias = tag__function(talias);
const char *name; const char *name;
if (alias == NULL) { if (alias == NULL) {
printed += tag__id_not_found_fprintf(fp, exp->tag.type); printed += tag__id_not_found_fprintf(fp, exp->ip.tag.type);
break; break;
} }
printed = fprintf(fp, "%.*s", indent, tabs); printed = fprintf(fp, "%.*s", indent, tabs);
@ -861,11 +861,11 @@ static size_t function__tag_fprintf(const struct tag *tag, const struct cu *cu,
indent + (namelen + 7) / 8, indent + (namelen + 7) / 8,
conf, fp); conf, fp);
n += fprintf(fp, "; /* size=%zd, low_pc=%#llx */", n += fprintf(fp, "; /* size=%zd, low_pc=%#llx */",
exp->size, (unsigned long long)exp->low_pc); exp->size, (unsigned long long)exp->ip.addr);
#if 0 #if 0
n = fprintf(fp, "%s(); /* size=%zd, low_pc=%#llx */", n = fprintf(fp, "%s(); /* size=%zd, low_pc=%#llx */",
function__name(alias, cu), exp->size, function__name(alias, cu), exp->size,
(unsigned long long)exp->low_pc); (unsigned long long)exp->ip.addr);
#endif #endif
c = 69; c = 69;
printed += n; printed += n;
@ -915,12 +915,12 @@ size_t lexblock__fprintf(const struct lexblock *self, const struct cu *cu,
if (indent >= sizeof(tabs)) if (indent >= sizeof(tabs))
indent = sizeof(tabs) - 1; indent = sizeof(tabs) - 1;
printed = fprintf(fp, "%.*s{", indent, tabs); printed = fprintf(fp, "%.*s{", indent, tabs);
if (self->low_pc != 0) { if (self->ip.addr != 0) {
uint64_t offset = self->low_pc - function->lexblock.low_pc; uint64_t offset = self->ip.addr - function->lexblock.ip.addr;
if (offset == 0) if (offset == 0)
printed += fprintf(fp, " /* low_pc=%#llx */", printed += fprintf(fp, " /* low_pc=%#llx */",
(unsigned long long)self->low_pc); (unsigned long long)self->ip.addr);
else else
printed += fprintf(fp, " /* %s+%#llx */", printed += fprintf(fp, " /* %s+%#llx */",
function__name(function, cu), function__name(function, cu),
@ -932,7 +932,7 @@ size_t lexblock__fprintf(const struct lexblock *self, const struct cu *cu,
conf, fp); conf, fp);
printed += fprintf(fp, "%.*s}", indent, tabs); printed += fprintf(fp, "%.*s}", indent, tabs);
if (function->lexblock.low_pc != self->low_pc) if (function->lexblock.ip.addr != self->ip.addr)
printed += fprintf(fp, " /* lexblock size=%d */", self->size); printed += fprintf(fp, " /* lexblock size=%d */", self->size);
return printed; return printed;
@ -1406,7 +1406,7 @@ static size_t variable__fprintf(const struct tag *tag, const struct cu *cu,
size_t printed = 0; size_t printed = 0;
if (name != NULL) { if (name != NULL) {
struct tag *type = cu__type(cu, var->tag.type); struct tag *type = cu__type(cu, var->ip.tag.type);
if (type != NULL) { if (type != NULL) {
const char *varprefix = variable__prefix(var); const char *varprefix = variable__prefix(var);

View File

@ -43,8 +43,8 @@ static void refcnt_parameter(const struct parameter *parameter,
static void refcnt_variable(const struct variable *variable, static void refcnt_variable(const struct variable *variable,
const struct cu *cu) const struct cu *cu)
{ {
if (variable->tag.type != 0) { /* if not void */ if (variable->ip.tag.type != 0) { /* if not void */
struct tag *type = cu__type(cu, variable->tag.type); struct tag *type = cu__type(cu, variable->ip.tag.type);
if (type != NULL) if (type != NULL)
refcnt_tag(type, cu); refcnt_tag(type, cu);
} }
@ -53,8 +53,8 @@ static void refcnt_variable(const struct variable *variable,
static void refcnt_inline_expansion(const struct inline_expansion *exp, static void refcnt_inline_expansion(const struct inline_expansion *exp,
const struct cu *cu) const struct cu *cu)
{ {
if (exp->tag.type != 0) { /* if not void */ if (exp->ip.tag.type != 0) { /* if not void */
struct tag *type = cu__function(cu, exp->tag.type); struct tag *type = cu__function(cu, exp->ip.tag.type);
if (type != NULL) if (type != NULL)
refcnt_tag(type, cu); refcnt_tag(type, cu);
} }