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];
hlist_for_each_entry(function, pos, head, tool_hnode) {
if (function->lexblock.low_pc == addr)
if (function->lexblock.ip.addr == addr)
return function;
}
@ -234,7 +234,7 @@ static struct variable *hashaddr__find_variable(const struct hlist_head hashtabl
const struct hlist_head *head = &hashtable[bucket];
hlist_for_each_entry(variable, pos, head, tool_hnode) {
if (variable->addr == addr)
if (variable->ip.addr == addr)
return variable;
}
@ -269,7 +269,7 @@ int cu__encode_ctf(struct cu *self)
struct function *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)];
hlist_add_head(&function->tool_hnode, head);
}
@ -318,7 +318,7 @@ int cu__encode_ctf(struct cu *self)
var = tag__variable(pos);
if (var->location != LOCATION_GLOBAL)
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);
}
@ -339,7 +339,7 @@ int cu__encode_ctf(struct cu *self)
continue;
}
err = ctf__add_object(ctf, var->tag.type);
err = ctf__add_object(ctf, var->ip.tag.type);
if (err != 0)
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));
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->name = sym->st_name;
self->vtable_entry = -1;
@ -554,13 +554,13 @@ static struct variable *variable__new(uint16_t type, GElf_Sym *sym,
if (self != NULL) {
self->location = LOCATION_GLOBAL;
self->addr = elf_sym__value(sym);
self->ip.addr = elf_sym__value(sym);
self->name = sym->st_name;
self->external = elf_sym__bind(sym) == STB_GLOBAL;
self->tag.tag = DW_TAG_variable;
self->tag.type = type;
self->ip.tag.tag = DW_TAG_variable;
self->ip.tag.type = type;
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;

View File

@ -469,16 +469,16 @@ static struct variable *variable__new(Dwarf_Die *die)
struct variable *self = tag__alloc(sizeof(*self));
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));
/* variable is visible outside of its enclosing cu */
self->external = dwarf_hasattr(die, DW_AT_external);
/* non-defining declaration of an object */
self->declaration = dwarf_hasattr(die, DW_AT_declaration);
self->location = LOCATION_UNKNOWN;
self->addr = 0;
self->ip.addr = 0;
if (!self->declaration)
self->location = dwarf__location(die, &self->addr);
self->location = dwarf__location(die, &self->ip.addr);
}
return self;
@ -655,20 +655,20 @@ static struct inline_expansion *inline_expansion__new(Dwarf_Die *die)
struct inline_expansion *self = tag__alloc(sizeof(*self));
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 =
strings__add(strings, attr_string(die, DW_AT_call_file));
dtag->decl_line = attr_numeric(die, DW_AT_call_line);
dtag->type = attr_type(die, DW_AT_abstract_origin);
if (dwarf_lowpc(die, &self->low_pc))
self->low_pc = 0;
if (dwarf_lowpc(die, &self->ip.addr))
self->ip.addr = 0;
if (dwarf_lowpc(die, &self->high_pc))
self->high_pc = 0;
self->size = self->high_pc - self->low_pc;
self->size = self->high_pc - self->ip.addr;
if (self->size == 0) {
Dwarf_Addr base, start;
ptrdiff_t offset = 0;
@ -681,8 +681,8 @@ static struct inline_expansion *inline_expansion__new(Dwarf_Die *die)
if (offset <= 0)
break;
self->size += self->high_pc - start;
if (self->low_pc == 0)
self->low_pc = start;
if (self->ip.addr == 0)
self->ip.addr = start;
}
}
}
@ -695,10 +695,10 @@ static struct label *label__new(Dwarf_Die *die)
struct label *self = tag__alloc(sizeof(*self));
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));
if (dwarf_lowpc(die, &self->low_pc))
self->low_pc = 0;
if (dwarf_lowpc(die, &self->ip.addr))
self->ip.addr = 0;
}
return self;
@ -726,13 +726,13 @@ static void lexblock__init(struct lexblock *self, Dwarf_Die *die)
{
Dwarf_Off high_pc;
if (dwarf_lowpc(die, &self->low_pc))
self->low_pc = 0;
if (dwarf_lowpc(die, &self->ip.addr))
self->ip.addr = 0;
if (dwarf_highpc(die, &high_pc))
self->size = 0;
else
self->size = high_pc - self->low_pc;
self->size = high_pc - self->ip.addr;
INIT_LIST_HEAD(&self->tags);
@ -748,7 +748,7 @@ static struct lexblock *lexblock__new(Dwarf_Die *die)
struct lexblock *self = tag__alloc(sizeof(*self));
if (self != NULL) {
tag__init(&self->tag, die);
tag__init(&self->ip.tag, die);
lexblock__init(self, die);
}
@ -1017,14 +1017,14 @@ static struct tag *die__create_new_label(Dwarf_Die *die,
return NULL;
lexblock__add_label(lexblock, label);
return &label->tag;
return &label->ip.tag;
}
static struct tag *die__create_new_variable(Dwarf_Die *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,
@ -1297,7 +1297,7 @@ static struct tag *die__create_new_inline_expansion(Dwarf_Die *die,
if (lexblock != NULL)
lexblock__add_inline_expansion(lexblock, exp);
return &exp->tag;
return &exp->ip.tag;
}
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)
{
lexblock__delete_tags(&self->tag);
lexblock__delete_tags(&self->ip.tag);
free(self);
}
@ -379,7 +379,7 @@ static void cu__insert_function(struct cu *self, struct tag *tag)
while (*p != NULL) {
parent = *p;
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;
else
p = &(*p)->rb_right;
@ -726,9 +726,9 @@ struct function *cu__find_function_at_addr(const struct cu *self,
while (n) {
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;
else if (addr >= f->lexblock.low_pc + f->lexblock.size)
else if (addr >= f->lexblock.ip.addr + f->lexblock.size)
n = n->rb_right;
else
return f;
@ -846,7 +846,7 @@ const char *variable__type_name(const struct variable *self,
const struct cu *cu,
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;
}
@ -982,7 +982,7 @@ void enumeration__add(struct type *self, struct enumerator *enumerator)
void lexblock__add_lexblock(struct lexblock *self, struct lexblock *child)
{
++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)
@ -1013,7 +1013,7 @@ void ftype__delete(struct ftype *self)
void function__delete(struct function *self)
{
lexblock__delete_tags(&self->lexblock.tag);
lexblock__delete_tags(&self->lexblock.ip.tag);
ftype__delete(&self->proto);
}
@ -1049,19 +1049,19 @@ void lexblock__add_inline_expansion(struct lexblock *self,
{
++self->nr_inline_expansions;
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)
{
++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)
{
++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,

View File

@ -483,10 +483,14 @@ void namespace__delete(struct namespace *self);
void namespace__add_tag(struct namespace *self, struct tag *tag);
struct ip_tag {
struct tag tag;
uint64_t addr;
};
struct inline_expansion {
struct tag tag;
struct ip_tag ip;
size_t size;
uint64_t low_pc;
uint64_t high_pc;
};
@ -497,9 +501,8 @@ static inline struct inline_expansion *
}
struct label {
struct tag tag;
struct ip_tag ip;
strings_t name;
uint64_t low_pc;
};
static inline struct label *tag__label(const struct tag *self)
@ -516,12 +519,11 @@ enum vlocation {
} __attribute__((packed));
struct variable {
struct tag tag;
struct ip_tag ip;
strings_t name;
uint8_t external:1;
uint8_t declaration:1;
enum vlocation location;
uint64_t addr;
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);
struct lexblock {
struct tag tag;
struct ip_tag ip;
struct list_head tags;
uint64_t low_pc;
uint32_t size;
uint16_t nr_inline_expansions;
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) {
case DW_TAG_inlined_subroutine: {
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);
const char *name;
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;
}
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,
conf, fp);
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
n = fprintf(fp, "%s(); /* size=%zd, low_pc=%#llx */",
function__name(alias, cu), exp->size,
(unsigned long long)exp->low_pc);
(unsigned long long)exp->ip.addr);
#endif
c = 69;
printed += n;
@ -915,12 +915,12 @@ size_t lexblock__fprintf(const struct lexblock *self, const struct cu *cu,
if (indent >= sizeof(tabs))
indent = sizeof(tabs) - 1;
printed = fprintf(fp, "%.*s{", indent, tabs);
if (self->low_pc != 0) {
uint64_t offset = self->low_pc - function->lexblock.low_pc;
if (self->ip.addr != 0) {
uint64_t offset = self->ip.addr - function->lexblock.ip.addr;
if (offset == 0)
printed += fprintf(fp, " /* low_pc=%#llx */",
(unsigned long long)self->low_pc);
(unsigned long long)self->ip.addr);
else
printed += fprintf(fp, " /* %s+%#llx */",
function__name(function, cu),
@ -932,7 +932,7 @@ size_t lexblock__fprintf(const struct lexblock *self, const struct cu *cu,
conf, fp);
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);
return printed;
@ -1406,7 +1406,7 @@ static size_t variable__fprintf(const struct tag *tag, const struct cu *cu,
size_t printed = 0;
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) {
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,
const struct cu *cu)
{
if (variable->tag.type != 0) { /* if not void */
struct tag *type = cu__type(cu, variable->tag.type);
if (variable->ip.tag.type != 0) { /* if not void */
struct tag *type = cu__type(cu, variable->ip.tag.type);
if (type != NULL)
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,
const struct cu *cu)
{
if (exp->tag.type != 0) { /* if not void */
struct tag *type = cu__function(cu, exp->tag.type);
if (exp->ip.tag.type != 0) { /* if not void */
struct tag *type = cu__function(cu, exp->ip.tag.type);
if (type != NULL)
refcnt_tag(type, cu);
}