From 9bb29daac4568a202d5f6e6c667f116fc2094615 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 2 Apr 2009 16:12:36 -0300 Subject: [PATCH] base_type: Don't combine names with attributes Such as signed, etc. This is in preparation for using directly ctf_strings. Instead of duplicating it in the global strings table. Signed-off-by: Arnaldo Carvalho de Melo --- ctf_loader.c | 41 ++++++++------------ dwarf_loader.c | 6 +++ dwarves.c | 89 ++++++++++++++++++++++++++++++++++++-------- dwarves.h | 26 +++++++++++-- dwarves_reorganize.c | 20 +++++++--- libctf.c | 25 ------------- libctf.h | 2 - pdwtags.c | 4 +- syscse.c | 8 +++- 9 files changed, 141 insertions(+), 80 deletions(-) diff --git a/ctf_loader.c b/ctf_loader.c index d094645..0be5a2e 100644 --- a/ctf_loader.c +++ b/ctf_loader.c @@ -144,13 +144,19 @@ static int ctf__load_funcs(struct ctf *self) return 0; } -static struct base_type *base_type__new(const char *name, size_t size) +static struct base_type *base_type__new(const char *name, uint32_t attrs, + uint8_t float_type, size_t size) { struct base_type *self = tag__alloc(sizeof(*self)); if (self != NULL) { self->name = strings__add(strings, name); self->bit_size = size; + self->is_signed = attrs & CTF_TYPE_INT_SIGNED; + self->is_bool = attrs & CTF_TYPE_INT_BOOL; + self->is_varargs = attrs & CTF_TYPE_INT_VARARGS; + self->name_has_encoding = false; + self->float_type = float_type; } return self; } @@ -190,22 +196,12 @@ static struct class *class__new(const char *name, size_t size) static int create_new_base_type(struct ctf *self, void *ptr, struct ctf_full_type *tp, long id) { - uint32_t *enc = ptr, name_idx; - char name[64], *buf = name; + uint32_t *enc = ptr; uint32_t eval = ctf__get32(self, enc); uint32_t attrs = CTF_TYPE_INT_ATTRS(eval); - struct base_type *base; - - if (attrs & CTF_TYPE_INT_SIGNED) - buf += sprintf(buf, "signed "); - if (attrs & CTF_TYPE_INT_BOOL) - buf += sprintf(buf, "bool "); - if (attrs & CTF_TYPE_INT_VARARGS) - buf += sprintf(buf, "varargs "); - - name_idx = ctf__get32(self, &tp->base.ctf_name); - buf += sprintf(buf, "%s", ctf__string(self, name_idx)); - base = base_type__new(name, CTF_TYPE_INT_BITS(eval)); + char *name = ctf__string(self, ctf__get32(self, &tp->base.ctf_name)); + struct base_type *base = base_type__new(name, attrs, 0, + CTF_TYPE_INT_BITS(eval)); if (base == NULL) return -ENOMEM; @@ -219,16 +215,10 @@ static int create_new_base_type_float(struct ctf *self, void *ptr, struct ctf_full_type *tp, long id) { - uint32_t *enc = ptr, eval; - char name[64]; - struct base_type *base; - - eval = ctf__get32(self, enc); - size_t len = ctf__format_flt_attrs(eval, name, sizeof(name)); - snprintf(name + len, sizeof(name) - len, "%s", - ctf__string32(self, &tp->base.ctf_name)); - - base = base_type__new(name, CTF_TYPE_FP_BITS(eval)); + char *name = ctf__string32(self, &tp->base.ctf_name); + uint32_t *enc = ptr, eval = ctf__get32(self, enc); + struct base_type *base = base_type__new(name, 0, eval, + CTF_TYPE_FP_BITS(eval)); if (base == NULL) return -ENOMEM; @@ -735,6 +725,7 @@ int ctf__load_file(struct cus *self, struct conf_load *conf, if (cu == NULL) return -1; + cu->uses_global_strings = false; cu->dfops = &ctf__ops; cu->priv = state; state->priv = cu; diff --git a/dwarf_loader.c b/dwarf_loader.c index f966dd4..f3ddc89 100644 --- a/dwarf_loader.c +++ b/dwarf_loader.c @@ -333,6 +333,11 @@ static struct base_type *base_type__new(Dwarf_Die *die) tag__init(&self->tag, die); self->name = strings__add(strings, attr_string(die, DW_AT_name)); self->bit_size = attr_numeric(die, DW_AT_byte_size) * 8; + uint64_t encoding = attr_numeric(die, DW_AT_encoding); + self->is_bool = encoding == DW_ATE_boolean; + self->is_signed = encoding == DW_ATE_signed; + self->is_varargs = false; + self->name_has_encoding = true; } return self; @@ -1868,6 +1873,7 @@ static int cus__load_module(struct cus *self, struct conf_load *conf, build_id, build_id_len, filename); if (cu == NULL) return DWARF_CB_ABORT; + cu->uses_global_strings = true; cu->elf = elf; cu->dwfl = mod; cu->extra_dbg_info = conf ? conf->extra_dbg_info : 0; diff --git a/dwarves.c b/dwarves.c index 738d2ad..7a37555 100644 --- a/dwarves.c +++ b/dwarves.c @@ -281,20 +281,66 @@ void base_type_name_to_size_table__init(void) size_t base_type__name_to_size(struct base_type *self, struct cu *cu) { int i = 0; + char bf[64]; + const char *name; + + if (self->name_has_encoding) + name = s(self->name); + else + name = base_type__name(self, bf, sizeof(bf)); while (base_type_name_to_size_table[i].name != NULL) { - if (base_type_name_to_size_table[i].sname == self->name) { - size_t size = base_type_name_to_size_table[i].size; + if (self->name_has_encoding) { + if (base_type_name_to_size_table[i].sname == self->name) { + size_t size; +found: + size = base_type_name_to_size_table[i].size; - return size ?: ((size_t)cu->addr_size * 8); - } + return size ?: ((size_t)cu->addr_size * 8); + } + } else if (strcmp(base_type_name_to_size_table[i].name, + name) == 0) + goto found; ++i; } fprintf(stderr, "%s: %s %s\n", - __func__, dwarf_tag_name(self->tag.tag), s(self->name)); + __func__, dwarf_tag_name(self->tag.tag), name); return 0; } +static const char *base_type_fp_type_str[] = { + [BT_FP_SINGLE] = "single", + [BT_FP_DOUBLE] = "double", + [BT_FP_CMPLX] = "complex", + [BT_FP_CMPLX_DBL] = "complex double", + [BT_FP_CMPLX_LDBL] = "complex long double", + [BT_FP_LDBL] = "long double", + [BT_FP_INTVL] = "interval", + [BT_FP_INTVL_DBL] = "interval double", + [BT_FP_INTVL_LDBL] = "interval long double", + [BT_FP_IMGRY] = "imaginary", + [BT_FP_IMGRY_DBL] = "imaginary double", + [BT_FP_IMGRY_LDBL] = "imaginary long double", +}; + +const char *base_type__name(const struct base_type *self, char *bf, size_t len) +{ + if (self->name_has_encoding) + return s(self->name); + + if (self->float_type) + snprintf(bf, len, "%s %s", + base_type_fp_type_str[self->float_type], + s(self->name)); + else + snprintf(bf, len, "%s%s%s%s", + self->is_signed ? "signed " : "", + self->is_bool ? "bool " : "", + self->is_varargs ? "... " : "", + s(self->name)); + return bf; +} + static size_t type__fprintf(struct tag *type, const struct cu *cu, const char *name, const struct conf_fprintf *conf, FILE *fp); @@ -789,20 +835,33 @@ struct tag *cu__find_base_type_by_name(const struct cu *self, if (self == NULL || name == NULL) return NULL; - strings_t sname = strings__find(strings, name); - if (sname == 0) - 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) { - const struct base_type *bt = tag__base_type(pos); + if (pos->tag != DW_TAG_base_type) + continue; - if (bt->name == sname) { - if (idp != NULL) - *idp = id; - return pos; - } + 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, bf, sizeof(bf)); + + if (strcmp(bname, name) != 0) + continue; } + + if (idp != NULL) + *idp = id; + return pos; } return NULL; diff --git a/dwarves.h b/dwarves.h index 2179a23..0816b1a 100644 --- a/dwarves.h +++ b/dwarves.h @@ -150,6 +150,7 @@ struct cu { uint32_t cached_symtab_nr_entries; uint8_t addr_size; uint8_t extra_dbg_info:1; + uint8_t uses_global_strings:1; uint16_t language; unsigned long nr_inline_expansions; size_t size_inline_expansions; @@ -922,10 +923,30 @@ const struct class_member *class__find_bit_hole(const struct class *self, const struct class_member *trailer, const uint16_t bit_hole_size); +enum base_type_float_type { + BT_FP_SINGLE = 1, + BT_FP_DOUBLE, + BT_FP_CMPLX, + BT_FP_CMPLX_DBL, + BT_FP_CMPLX_LDBL, + BT_FP_LDBL, + BT_FP_INTVL, + BT_FP_INTVL_DBL, + BT_FP_INTVL_LDBL, + BT_FP_IMGRY, + BT_FP_IMGRY_DBL, + BT_FP_IMGRY_LDBL +}; + struct base_type { struct tag tag; strings_t name; uint16_t bit_size; + uint8_t name_has_encoding:1; + uint8_t is_signed:1; + uint8_t is_bool:1; + uint8_t is_varargs:1; + uint8_t float_type; }; static inline struct base_type *tag__base_type(const struct tag *self) @@ -938,10 +959,7 @@ static inline uint16_t base_type__size(const struct tag *self) return tag__base_type(self)->bit_size / 8; } -static inline const char *base_type__name(const struct base_type *self) -{ - return strings__ptr(strings, self->name); -} +const char *base_type__name(const struct base_type *self, char *bf, size_t len); void base_type_name_to_size_table__init(void); size_t base_type__name_to_size(struct base_type *self, struct cu *cu); diff --git a/dwarves_reorganize.c b/dwarves_reorganize.c index ecfe55b..ae66839 100644 --- a/dwarves_reorganize.c +++ b/dwarves_reorganize.c @@ -544,13 +544,17 @@ static int class__demote_bitfields(struct class *class, const struct cu *cu, "%zd bytes base type */\n\n", bytes_needed); continue; } - if (verbose) + if (verbose) { + char old_bf[64], new_bf[64]; fprintf(fp, "/* Demoting bitfield ('%s' ... '%s') " "from '%s' to '%s' */\n", class_member__name(bitfield_head), class_member__name(member), - base_type__name(tag__base_type(old_type_tag)), - base_type__name(tag__base_type(new_type_tag))); + base_type__name(tag__base_type(old_type_tag), + old_bf, sizeof(old_bf)), + base_type__name(tag__base_type(new_type_tag), + new_bf, sizeof(new_bf))); + } class__demote_bitfield_members(class, bitfield_head, member, @@ -594,12 +598,16 @@ static int class__demote_bitfields(struct class *class, const struct cu *cu, tag__assert_search_result(old_type_tag); tag__assert_search_result(new_type_tag); - if (verbose) + if (verbose) { + char old_bf[64], new_bf[64]; fprintf(fp, "/* Demoting bitfield ('%s') " "from '%s' to '%s' */\n", class_member__name(member), - base_type__name(tag__base_type(old_type_tag)), - base_type__name(tag__base_type(new_type_tag))); + base_type__name(tag__base_type(old_type_tag), + old_bf, sizeof(old_bf)), + base_type__name(tag__base_type(new_type_tag), + new_bf, sizeof(new_bf))); + } class__demote_bitfield_members(class, member, member, tag__base_type(old_type_tag), diff --git a/libctf.c b/libctf.c index cfd6a1c..6d79983 100644 --- a/libctf.c +++ b/libctf.c @@ -14,21 +14,6 @@ #include "dutil.h" #include "gobuffer.h" -static const char *ctf_type_fp_str[] = { - [CTF_TYPE_FP_SINGLE] = "single", - [CTF_TYPE_FP_DOUBLE] = "double", - [CTF_TYPE_FP_CMPLX] = "complex", - [CTF_TYPE_FP_CMPLX_DBL] = "complex double", - [CTF_TYPE_FP_CMPLX_LDBL] = "complex long double", - [CTF_TYPE_FP_LDBL] = "long double", - [CTF_TYPE_FP_INTVL] = "interval", - [CTF_TYPE_FP_INTVL_DBL] = "interval double", - [CTF_TYPE_FP_INTVL_LDBL] = "interval long double", - [CTF_TYPE_FP_IMGRY] = "imaginary", - [CTF_TYPE_FP_IMGRY_DBL] = "imaginary double", - [CTF_TYPE_FP_IMGRY_LDBL] = "imaginary long double", -}; - bool ctf__ignore_symtab_function(const GElf_Sym *sym, const char *sym_name) { return (!elf_sym__is_local_function(sym) || @@ -45,16 +30,6 @@ bool ctf__ignore_symtab_object(const GElf_Sym *sym, const char *sym_name) strchr(sym_name, '.') != NULL); } -size_t ctf__format_flt_attrs(uint32_t eval, char *bf, size_t len) -{ - const uint32_t attrs = CTF_TYPE_FP_ATTRS(eval); - - if (attrs < CTF_TYPE_FP_SINGLE || attrs > CTF_TYPE_FP_MAX) - return snprintf(bf, len, "0x%02x ", attrs); - - return snprintf(bf, len, "%s ", ctf_type_fp_str[attrs]); -} - uint16_t ctf__get16(struct ctf *self, uint16_t *p) { uint16_t val = *p; diff --git a/libctf.h b/libctf.h index 8dc6649..a4023ff 100644 --- a/libctf.h +++ b/libctf.h @@ -78,8 +78,6 @@ int ctf__encode(struct ctf *self, uint8_t flags); char *ctf__string(struct ctf *self, uint32_t ref); char *ctf__string32(struct ctf *self, uint32_t *refp); -size_t ctf__format_flt_attrs(uint32_t eval, char *bf, size_t len); - /** * ctf__for_each_symtab_function - iterate thru all the symtab functions * diff --git a/pdwtags.c b/pdwtags.c index 964dcb3..aa88e16 100644 --- a/pdwtags.c +++ b/pdwtags.c @@ -23,7 +23,9 @@ static void emit_tag(struct tag *self, uint32_t tag_id, struct cu *cu) printf("/* %d */\n", tag_id); if (self->tag == DW_TAG_base_type) { - const char *name = base_type__name(tag__base_type(self)); + char bf[64]; + const char *name = base_type__name(tag__base_type(self), + bf, sizeof(bf)); if (name == NULL) printf("anonymous base_type\n"); diff --git a/syscse.c b/syscse.c index f6e0e82..bbbe569 100644 --- a/syscse.c +++ b/syscse.c @@ -49,9 +49,11 @@ static void zero_extend(const int regparm, const struct base_type *bt, break; } + char bf[64]; printf("\t%s\t$a%d, $a%d, 0" "\t/* zero extend $a%d(%s %s) from %d to 64-bit */\n", - instr, regparm, regparm, regparm, base_type__name(bt), + instr, regparm, regparm, regparm, + base_type__name(bt, bf, sizeof(bf)), parm, bt->bit_size); } @@ -68,9 +70,11 @@ static void emit_wrapper(struct function *f, struct cu *cu) tag__assert_search_result(type); if (type->tag == DW_TAG_base_type) { struct base_type *bt = tag__base_type(type); + char bf[64]; if (bt->bit_size < 64 && - strncmp(base_type__name(bt), "unsigned", 8) == 0) { + strncmp(base_type__name(bt, bf, sizeof(bf)), + "unsigned", 8) == 0) { if (!needs_wrapper) { printf("wrap_%s:\n", name); needs_wrapper = 1;