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:
parent
e429f8efbb
commit
7c6603189e
|
@ -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;
|
||||
}
|
||||
|
|
10
ctf_loader.c
10
ctf_loader.c
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
20
dwarves.c
20
dwarves.c
|
@ -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,
|
||||
|
|
17
dwarves.h
17
dwarves.h
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue