From 4d619ac4cb562fc13abf227a4eece0e71831095d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 2 Apr 2009 18:46:54 -0300 Subject: [PATCH] core: Only DWARF uses the global strings table, so move it there There is still the problem of handing the strings table to the CTF encoder, but that will be fixed another day. Signed-off-by: Arnaldo Carvalho de Melo --- codiff.c | 7 ++-- ctf_encoder.c | 6 +++ ctf_loader.c | 2 +- dwarf_loader.c | 19 +++++++++- dwarves.c | 100 ++++++++++++++++++++++--------------------------- dwarves.h | 26 +++++++------ 6 files changed, 88 insertions(+), 72 deletions(-) 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 {