--- crash-7.1.4/defs.h 2015-12-16 18:59:36.000000000 +0300 +++ crash-7.1.4.test/defs.h 2016-04-04 09:46:42.615294482 +0300 @@ -4340,6 +4340,7 @@ void cmd_pointer(void); /* symbols.c */ void cmd_whatis(void); /* symbols.c */ void cmd_p(void); /* symbols.c */ +void cmd_types(void); /* symbols.c */ void cmd_mount(void); /* filesys.c */ void cmd_files(void); /* filesys.c */ void cmd_fuser(void); /* filesys.c */ @@ -4874,6 +4875,7 @@ extern char *help_sys[]; extern char *help_task[]; extern char *help_timer[]; +extern char *help_types[]; extern char *help_union[]; extern char *help_vm[]; extern char *help_vtop[]; @@ -6235,7 +6237,7 @@ * gdb/symtab.c */ extern void gdb_command_funnel(struct gnu_request *); - +extern int search_matched_struct_symbols (const char *, int, int, const char ***, int **); /* * gdb/symfile.c */ --- crash-7.1.4/global_data.c 2015-12-16 18:59:36.000000000 +0300 +++ crash-7.1.4.test/global_data.c 2016-03-31 16:35:25.753285231 +0300 @@ -114,6 +114,7 @@ {"task", cmd_task, help_task, REFRESH_TASK_TABLE}, {"test", cmd_test, NULL, HIDDEN_COMMAND}, {"timer", cmd_timer, help_timer, 0}, + {"types", cmd_types, help_types, 0}, {"union", cmd_union, help_union, 0}, {"vm", cmd_vm, help_vm, REFRESH_TASK_TABLE}, {"vtop", cmd_vtop, help_vtop, REFRESH_TASK_TABLE}, --- crash-7.1.4/help.c 2015-12-16 18:59:36.000000000 +0300 +++ crash-7.1.4.test/help.c 2016-04-01 13:08:48.878755448 +0300 @@ -5658,6 +5658,62 @@ NULL }; +char *help_types[] = { +"types", +"search declared structures with particular size and contents", +"[-f field] -r range", +"The arguments are as follows:\n", +" -f field The field type (or substruct of type name) which the", +" structure should contain", +" -r range The range or the exact size of the structure we're", +" looking for.", +"\nEXAMPLES:", +"\n1. Find all structures which have size from 190 up to 200 bytes\n\n" +" %s> types -r 190-200", +"192 apic", +"192 ata_eh_context", +"192 cper_sec_proc_generic", +"192 cpuinfo_x86", +"192 pebs_record_hsw", +"196 ethtool_drvinfo", +"196 kioctx", +"196 vm86plus_struct", +"200 apple_sc", +"200 cper_pstore_record", +"200 kernel_vm86_struct", +"200 linux_binprm", +"200 scsi_transport_template", +"\n2. Find all structures which have size from 190 up to 200 bytes and", +"which contain member of type '*list*'\n", +" %s> types -r 190-200 -f list", +"196 kioctx", +"200 scsi_transport_template", +"", +"`struct kioctx` really has members of types `hlist_node`, `list_head`.", +"However, the last structure is more subtle. It contains field of type", +"`list_head` within itself.", +"That is:", +"`scsi_transport_template` contains member of type `transport_container`", +"`transport_container` has `attribute_container`", +"`attribute_container` has `list_head`.", +"Structure `list_head` has poiners to `list_head`", +"This is the place where algorithm triggers. It delves into the structure", +"_only_ if the particular member is a structure, not a pointer.", +"If it is a pointer, we only match name of type against the given pattern.", +"\n3. Find all ths structures which have size exactly 36 bytes and which", +"contain member of type '*list_head*'\n", +" %s> types -r 36 -f list_head", +"36 agp_front_data", +"36 audit_watch", +"36 blkio_cgroup", +"36 blkio_policy_type", +"36 device_domain_info", +"36 dmar_drhd_unit", +"36 dmar_rmrr_unit", +"........", +NULL +}; + char *help_ptob[] = { "ptob", "page to bytes", --- crash-7.1.4/symbols.c 2015-12-16 18:59:36.000000000 +0300 +++ crash-7.1.4.test/symbols.c 2016-04-04 10:12:40.271317840 +0300 @@ -33,6 +33,7 @@ static int compare_syms(const void *, const void *); static int compare_mods(const void *, const void *); static int compare_prios(const void *v1, const void *v2); +static int compare_size_name(const void *, const void *); static asection *get_kernel_section(char *); static char * get_section(ulong vaddr, char *buf); static void symbol_dump(ulong, char *); @@ -5976,6 +5977,74 @@ return TRUE; } +static int +compare_size_name(const void *va, const void *vb) { + const struct { + char *n; int s; + } *a = va, *b = vb; + + if (a->s == b->s) + return strcmp(a->n, b->n); + else + return a->s < b->s ? -1 : 1; +} + +void +cmd_types(void) +{ + const char *field = NULL, **out_name = NULL; + char *sep, tmp[16]; + + int lowest, highest, i, c; + int *out_size = NULL; + struct { const char *n; int s; } *struct_output; + + lowest = highest = UNUSED; + + while ((c = getopt(argcnt, args, "f:r:")) != EOF) { + switch (c) + { + case 'f': + field = optarg; + break; + case 'r': + strncpy(tmp, optarg, 15); + if ((sep = strstr(tmp, "-")) != NULL) + *(sep++) = '\0'; + + lowest = stol(tmp, FAULT_ON_ERROR, NULL); + + if (sep) + highest = stol(sep, FAULT_ON_ERROR, NULL); + else + highest = lowest; + + break; + default: + cmd_usage(pc->curcmd, SYNOPSIS); + } + } + + if (lowest == UNUSED || highest == UNUSED) + error(FATAL, "You should specify range\n"); + + c = search_matched_struct_symbols(field, lowest, highest, + &out_name, &out_size); + + struct_output = malloc(sizeof(*struct_output) * c); + for (i = 0; i < c; i++) { + struct_output[i].n = out_name[i]; + struct_output[i].s = out_size[i]; + } + + qsort(struct_output, c, sizeof(*struct_output), compare_size_name); + + for (i = 0; i < c; i++) + fprintf(fp, "%d\t%s\n", struct_output[i].s, struct_output[i].n); + + free(struct_output); + return; +} static void cmd_datatype_common(ulong flags) { -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility