diff --git a/codiff.c b/codiff.c index 7ca72ec..9a4a680 100644 --- a/codiff.c +++ b/codiff.c @@ -193,7 +193,8 @@ static int check_print_members_changes(const struct class *structure, type__for_each_member(&structure->type, member) { const char *member_name = class_member__name(member, cu); struct class_member *twin = - class__find_member_by_name(new_structure, member_name); + class__find_member_by_name(new_structure, new_cu, + member_name); if (twin != NULL) { twin->tag.visited = 1; ++nr_twins_found; @@ -427,7 +428,7 @@ static void show_nr_members_changes(const struct class *structure, /* Find the removed ones */ type__for_each_member(&structure->type, member) { struct class_member *twin = - class__find_member_by_name(new_structure, + class__find_member_by_name(new_structure, new_cu, class_member__name(member, cu)); if (twin == NULL) show_changed_member('-', member, cu); @@ -436,7 +437,7 @@ static void show_nr_members_changes(const struct class *structure, /* Find the new ones */ type__for_each_member(&new_structure->type, member) { struct class_member *twin = - class__find_member_by_name(structure, + class__find_member_by_name(structure, cu, class_member__name(member, new_cu)); if (twin == NULL) show_changed_member('+', member, new_cu); diff --git a/ctf_encoder.c b/ctf_encoder.c index c02701f..d65b39c 100644 --- a/ctf_encoder.c +++ b/ctf_encoder.c @@ -241,6 +241,12 @@ static struct variable *hashaddr__find_variable(const struct hlist_head hashtabl return NULL; } +/* + * FIXME: Its in the DWARF loader, we have to find a better handoff + * mechanizm... + */ +extern struct strings *strings; + int cu__encode_ctf(struct cu *self) { int err = -1; diff --git a/ctf_loader.c b/ctf_loader.c index 9b8485f..d28f7ce 100644 --- a/ctf_loader.c +++ b/ctf_loader.c @@ -169,6 +169,7 @@ static void type__init(struct type *self, uint16_t tag, self->size = size; self->namespace.tag.tag = tag; self->namespace.name = name; + self->namespace.sname = 0; } static struct type *type__new(uint16_t tag, strings_t name, size_t size) @@ -740,7 +741,6 @@ int ctf__load_file(struct cus *self, struct conf_load *conf, return err; } - base_type_name_to_size_table__init(); err = cu__fixup_ctf_bitfields(cu); /* * The app stole this cu, possibly deleting it, diff --git a/dwarf_loader.c b/dwarf_loader.c index f3ddc89..88e9ff9 100644 --- a/dwarf_loader.c +++ b/dwarf_loader.c @@ -27,6 +27,8 @@ #include "strings.h" #include "hash.h" +struct strings *strings; + #ifndef DW_AT_GNU_vector #define DW_AT_GNU_vector 0x2107 #endif @@ -361,6 +363,7 @@ static void namespace__init(struct namespace *self, Dwarf_Die *die) { tag__init(&self->tag, die); INIT_LIST_HEAD(&self->tags); + self->sname = 0; self->name = strings__add(strings, attr_string(die, DW_AT_name)); self->nr_tags = 0; self->shared_tags = 0; @@ -1744,7 +1747,14 @@ static void dwarf_tag__free_orig_info(struct tag *self, struct cu *cu __unused) self->priv = NULL; } +static const char *dwarf__strings_ptr(const struct cu *cu __unused, + strings_t s) +{ + return strings__ptr(strings, s); +} + static struct debug_fmt_ops dwarf_ops = { + .strings__ptr = dwarf__strings_ptr, .tag__decl_file = dwarf_tag__decl_file, .tag__decl_line = dwarf_tag__decl_line, .tag__orig_id = dwarf_tag__orig_id, @@ -1879,7 +1889,7 @@ static int cus__load_module(struct cus *self, struct conf_load *conf, cu->extra_dbg_info = conf ? conf->extra_dbg_info : 0; if (die__process(cu_die, cu) != 0) return DWARF_CB_ABORT; - base_type_name_to_size_table__init(); + base_type_name_to_size_table__init(strings); cu__for_all_tags(cu, class_member__cache_byte_size, conf); off = noff; if (conf && conf->steal) { @@ -2001,6 +2011,13 @@ int dwarf__load_file(struct cus *self, struct conf_load *conf, { int fd, err; + if (strings == NULL) { + strings = strings__new(); + + if (strings == NULL) + return -ENOMEM; + } + elf_version(EV_CURRENT); fd = open(filename, O_RDONLY); diff --git a/dwarves.c b/dwarves.c index 9837b74..92488cb 100644 --- a/dwarves.c +++ b/dwarves.c @@ -30,13 +30,11 @@ #include "dutil.h" #include "strings.h" -struct strings *strings; - const char *cu__string(const struct cu *self, strings_t s) { if (self->dfops && self->dfops->strings__ptr) return self->dfops->strings__ptr(self, s); - return strings__ptr(strings, s); + return NULL; } static inline const char *s(const struct cu *self, strings_t i) @@ -272,7 +270,7 @@ static struct base_type_name_to_size { { .name = NULL }, }; -void base_type_name_to_size_table__init(void) +void base_type_name_to_size_table__init(struct strings *strings) { int i = 0; @@ -568,7 +566,7 @@ static size_t imported_module__fprintf(const struct tag *self, const char *name = ""; if (tag__is_namespace(module)) - name = s(cu, tag__namespace(module)->name); + name = namespace__name(tag__namespace(module), cu); return fprintf(fp, "using namespace %s", name); } @@ -844,29 +842,15 @@ struct tag *cu__find_base_type_by_name(const struct cu *self, if (self == NULL || name == NULL) return NULL; - strings_t sname; - if (self->uses_global_strings) { - sname = strings__find(strings, name); - if (sname == 0) - return NULL; - } - cu__for_each_type(self, id, pos) { if (pos->tag != DW_TAG_base_type) continue; const struct base_type *bt = tag__base_type(pos); - - if (self->uses_global_strings) { - if (bt->name != sname) - continue; - } else { - char bf[64]; - const char *bname = base_type__name(bt, self, bf, - sizeof(bf)); - if (strcmp(bname, name) != 0) - continue; - } + char bf[64]; + const char *bname = base_type__name(bt, self, bf, sizeof(bf)); + if (strcmp(bname, name) != 0) + continue; if (idp != NULL) *idp = id; @@ -903,19 +887,6 @@ struct tag *cu__find_base_type_by_sname_and_size(const struct cu *self, return NULL; } -struct tag *cu__find_base_type_by_name_and_size(const struct cu *self, - const char *name, - uint16_t bit_size, - uint16_t *idp) -{ - if (self == NULL || name == NULL) - return NULL; - - strings_t sname = strings__find(strings, name); - - return cu__find_base_type_by_sname_and_size(self, sname, bit_size, idp); -} - struct tag *cu__find_enumeration_by_sname_and_size(const struct cu *self, strings_t sname, uint16_t bit_size, @@ -982,11 +953,29 @@ struct tag *cu__find_struct_by_name(const struct cu *self, const char *name, if (self == NULL || name == NULL) return NULL; - strings_t sname = strings__find(strings, name); - if (sname == 0) - return NULL; + uint16_t id; + struct tag *pos; + cu__for_each_type(self, id, pos) { + struct type *type; - return cu__find_struct_by_sname(self, sname, include_decls, idp); + if (!tag__is_struct(pos)) + continue; + + type = tag__type(pos); + if (strcmp(type__name(type, self), name) == 0) { + if (!type->declaration) + goto found; + + if (include_decls) + goto found; + } + } + + return NULL; +found: + if (idp != NULL) + *idp = id; + return pos; } struct tag *cus__find_struct_by_name(const struct cus *self, @@ -1548,6 +1537,8 @@ static void type__delete_class_members(struct type *self) void class__delete(struct class *self) { + if (self->type.namespace.sname != NULL) + free(self->type.namespace.sname); type__delete_class_members(&self->type); free(self); } @@ -1625,13 +1616,18 @@ struct class *class__clone(const struct class *from, if (self != NULL) { memcpy(self, from, sizeof(*self)); + if (new_class_name != NULL) { + self->type.namespace.name = 0; + self->type.namespace.sname = strdup(new_class_name); + if (self->type.namespace.sname == NULL) { + free(self); + return NULL; + } + } if (type__clone_members(&self->type, &from->type) != 0) { class__delete(self); self = NULL; } - if (new_class_name != NULL) - self->type.namespace.name = strings__add(strings, - new_class_name); } return self; @@ -1870,19 +1866,18 @@ int class__has_hole_ge(const struct class *self, const uint16_t size) } struct class_member *type__find_member_by_name(const struct type *self, + const struct cu *cu, const char *name) { if (name == NULL) return NULL; - strings_t sname = strings__find(strings, name); - if (sname == 0) - return NULL; - struct class_member *pos; - type__for_each_data_member(self, pos) - if (pos->name == sname) + type__for_each_data_member(self, pos) { + const char *curr_name = class_member__name(pos, cu); + if (curr_name && strcmp(curr_name, name) == 0) return pos; + } return NULL; } @@ -2960,11 +2955,6 @@ void cus__delete(struct cus *self) int dwarves__init(uint16_t user_cacheline_size) { - strings = strings__new(); - - if (strings == NULL) - return -ENOMEM; - if (user_cacheline_size == 0) { long sys_cacheline_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); @@ -2980,8 +2970,6 @@ int dwarves__init(uint16_t user_cacheline_size) void dwarves__exit(void) { - strings__delete(strings); - strings = NULL; } struct argp_state; diff --git a/dwarves.h b/dwarves.h index 027ec63..d3762e5 100644 --- a/dwarves.h +++ b/dwarves.h @@ -19,8 +19,6 @@ #include "list.h" #include "strings.h" -extern struct strings *strings; - struct cu; enum load_steal_kind { @@ -247,10 +245,6 @@ 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_name_and_size(const struct cu *self, - const char *name, - uint16_t bit_size, - uint16_t *id); struct tag *cu__find_base_type_by_sname_and_size(const struct cu *self, strings_t name, uint16_t bit_size, @@ -433,12 +427,14 @@ static inline struct ptr_to_member_type * /** struct namespace - base class for enums, structs, unions, typedefs, etc * + * @sname - for clones, for instance, where we can't always add a new string * @tags - class_member, enumerators, etc * @shared_tags: if this bit is set, don't free the entries in @tags */ struct namespace { struct tag tag; strings_t name; + char * sname; uint16_t nr_tags; uint8_t shared_tags:1; struct list_head tags; @@ -839,6 +835,7 @@ struct class_member * const struct cu *cu); struct class_member *type__find_member_by_name(const struct type *self, + const struct cu *cu, const char *name); uint32_t type__nr_members_of_type(const struct type *self, const Dwarf_Off type); @@ -882,16 +879,22 @@ static inline struct list_head *class__tags(struct class *self) return &self->type.namespace.tags; } +static __pure inline const char *namespace__name(const struct namespace *self, + const struct cu *cu) +{ + return self->sname ?: cu__string(cu, self->name); +} + static __pure inline const char *type__name(const struct type *self, const struct cu *cu) { - return cu__string(cu, self->namespace.name); + return namespace__name(&self->namespace, cu); } static __pure inline const char *class__name(struct class *self, const struct cu *cu) { - return cu__string(cu, self->type.namespace.name); + return type__name(&self->type, cu); } static inline int class__is_struct(const struct class *self) @@ -906,9 +909,10 @@ size_t class__fprintf(struct class *self, const struct cu *cu, void class__add_vtable_entry(struct class *self, struct function *vtable_entry); static inline struct class_member * - class__find_member_by_name(const struct class *self, const char *name) + class__find_member_by_name(const struct class *self, + const struct cu *cu, const char *name) { - return type__find_member_by_name(&self->type, name); + return type__find_member_by_name(&self->type, cu, name); } static inline uint16_t class__nr_members(const struct class *self) @@ -969,7 +973,7 @@ static inline uint16_t base_type__size(const struct tag *self) const char *base_type__name(const struct base_type *self, const struct cu *cu, char *bf, size_t len); -void base_type_name_to_size_table__init(void); +void base_type_name_to_size_table__init(struct strings *strings); size_t base_type__name_to_size(struct base_type *self, struct cu *cu); struct array_type {