--- gdb-7.6/gdb/symtab.c 2016-04-04 15:27:06.147600736 +0300 +++ gdb-7.6/gdb/symtab.c 2016-04-04 15:22:20.155596448 +0300 @@ -3405,6 +3405,130 @@ return !data->preg_p || regexec (&data->preg, symname, 0, NULL, 0) == 0; } +#ifdef CRASH_MERGE +int +lookup_struct_contents(struct main_type *main_type, const char *field) +{ + int i; + struct field *f; + struct main_type *m; + const char *n; + + if (!main_type) + return 0; + + for (i = 0; i < main_type->nfields; i++) + { + f = main_type->flds_bnds.fields + i; + if (!f->type) + continue; + m = f->type->main_type; + + /* Here is a recursion. + * If we have struct variable (not pointer), + * scan this inner structure + */ + if (m->code == TYPE_CODE_STRUCT) { + if (lookup_struct_contents(m, field) == 1) + return 1; + } + + if ((m->code == TYPE_CODE_PTR || m->code == TYPE_CODE_ARRAY) + && m->target_type) + m = m->target_type->main_type; + if (m->name) + n = m->name; + else if (m->tag_name) + n = m->tag_name; + else + continue; + + if (strstr(n, field)) + return 1; + } + + return 0; +} + +void +append_struct_symbol (const char *n, int sz, const char ***out_name, + int **out_size, int *csz, int *cix) +{ + int i; + + for (i = 0; i < *cix; i++) + if ((*out_name)[i] == n) + break; + + if (i < *cix) // We've already collected this type + return; + + if (*cix == *csz) { + *csz *= 3; + *out_name = xrealloc(*out_name, sizeof(*out_name) * (*csz)); + *out_size = xrealloc(*out_size, sizeof(*out_size) * (*csz)); + } + (*out_name)[*cix] = n; + (*out_size)[*cix] = sz; + (*cix)++; +} + +int +search_matched_struct_symbols (const char *field, int lowest, int highest, + const char ***out_name, int **out_size) +{ + struct symtab *s; + struct blockvector *bv; + struct block *b; + struct block_iterator iter; + struct symbol *sym; + struct objfile *objfile; + struct minimal_symbol *msymbol; + const char *name; + int size; + int i = 0; + int cix = 0, csz = 16; + struct partial_symtab *ps; + + *out_name = xmalloc(sizeof(*out_name) * csz); + *out_size = xmalloc(sizeof(*out_size) * csz); + + ALL_OBJFILES (objfile) + { + if (objfile->sf) + objfile->sf->qf->expand_all_symtabs(objfile); + } + + ALL_PRIMARY_SYMTABS (objfile, s) + { + bv = BLOCKVECTOR (s); + for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++) + { + b = BLOCKVECTOR_BLOCK (bv, i); + ALL_BLOCK_SYMBOLS (b, iter, sym) + { + QUIT; + + if (SYMBOL_CLASS (sym) == LOC_TYPEDEF) + { + name = sym->ginfo.name; + size = sym->type->length; + if (lowest >= 0 && size < lowest) + continue; + if (highest >= 0 && highest < size) + continue; + if (field && !lookup_struct_contents(sym->type->main_type, field)) + continue; + append_struct_symbol(name, size, out_name, out_size, &csz, &cix); + } + } + } + } + + return cix; +} +#endif + /* Search the symbol table for matches to the regular expression REGEXP, returning the results in *MATCHES. --- gdb-7.6/gdb/symtab.h 2013-02-03 18:54:16.000000000 +0300 +++ gdb-7.6/gdb/symtab.h 2016-04-04 16:05:53.335635633 +0300 @@ -1318,4 +1318,11 @@ struct cleanup *demangle_for_lookup (const char *name, enum language lang, const char **result_name); +#ifdef CRASH_MERGE +void append_struct_symbol (const char *, int, const char ***, int **, int *, int *); +int search_matched_struct_symbols (const char *, int, int, const char ***, int **); +int lookup_struct_contents(struct main_type *, const char *); +#endif + + #endif /* !defined(SYMTAB_H) */ -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility