Index: db_command.c =================================================================== RCS file: /cvs/src/sys/ddb/db_command.c,v retrieving revision 1.75 diff -u -p -r1.75 db_command.c --- db_command.c 14 Aug 2017 19:57:05 -0000 1.75 +++ db_command.c 4 Sep 2017 23:14:09 -0000 @@ -110,7 +110,7 @@ void db_dmesg_cmd(db_expr_t, int, db_exp void db_show_panic_cmd(db_expr_t, int, db_expr_t, char *); void db_bcstats_print_cmd(db_expr_t, int, db_expr_t, char *); void db_struct_offset_cmd(db_expr_t, int, db_expr_t, char *); -void db_struct_layout_cmd(db_expr_t, int, db_expr_t, char *); +void db_ctf_show_struct(db_expr_t, int, db_expr_t, char *); void db_show_regs(db_expr_t, boolean_t, db_expr_t, char *); void db_write_cmd(db_expr_t, boolean_t, db_expr_t, char *); void db_witness_display(db_expr_t, int, db_expr_t, char *); @@ -590,9 +590,7 @@ struct db_command db_show_cmds[] = { { "proc", db_proc_print_cmd, 0, NULL }, { "registers", db_show_regs, 0, NULL }, { "socket", db_socket_print_cmd, 0, NULL }, -#ifdef DDB_STRUCT - { "struct", db_struct_layout_cmd, CS_OWN, NULL }, -#endif + { "struct", db_ctf_show_struct, CS_OWN, NULL }, { "uvmexp", db_uvmexp_print_cmd, 0, NULL }, { "vnode", db_vnode_print_cmd, 0, NULL }, { "watches", db_listwatch_cmd, 0, NULL }, Index: db_ctf.c =================================================================== RCS file: /cvs/src/sys/ddb/db_ctf.c,v retrieving revision 1.16 diff -u -p -r1.16 db_ctf.c --- db_ctf.c 14 Aug 2017 19:58:32 -0000 1.16 +++ db_ctf.c 4 Sep 2017 23:14:09 -0000 @@ -55,6 +55,7 @@ static const char *db_ctf_off2name(uint3 static Elf_Sym *db_ctf_idx2sym(size_t *, uint8_t); static char *db_ctf_decompress(const char *, size_t, off_t); +const struct ctf_type *db_ctf_type_by_name(const char *, unsigned int); const struct ctf_type *db_ctf_type_by_symbol(Elf_Sym *); const struct ctf_type *db_ctf_type_by_index(uint16_t); void db_ctf_pprint_struct(const struct ctf_type *, vaddr_t); @@ -268,6 +269,41 @@ db_ctf_type_by_symbol(Elf_Sym *st) return NULL; } +const struct ctf_type * +db_ctf_type_by_name(const char *name, unsigned int kind) +{ + struct ctf_header *cth; + const struct ctf_type *ctt; + const char *tname; + uint32_t off, toff; + + if (!db_ctf.ctf_found) + return (NULL); + + cth = db_ctf.cth; + + for (off = cth->cth_typeoff; off < cth->cth_stroff; off += toff) { + ctt = (struct ctf_type *)(db_ctf.data + off); + toff = db_ctf_type_len(ctt); + if (toff == 0) { + db_printf("incorrect type at offset %u", off); + break; + } + + if (CTF_INFO_KIND(ctt->ctt_info) != kind) + continue; + + tname = db_ctf_off2name(ctt->ctt_name); + if (tname == NULL) + continue; + + if (strcmp(name, tname) == 0) + return (ctt); + } + + return (NULL); +} + /* * Return the CTF type corresponding to a given index in the type section. */ @@ -537,4 +573,56 @@ db_ctf_pprint_cmd(db_expr_t addr, int ha db_printf("%s:\t", db_tok_string); db_ctf_pprint(ctt, addr); db_printf("\n"); +} + +/* + * show struct [addr]: displays the data starting at addr + * (`dot' if unspecified) as a struct of the given type. + */ +void +db_ctf_show_struct(db_expr_t addr, int have_addr, db_expr_t count, + char *modifiers) +{ + const struct ctf_type *ctt; + const char *name; + uint64_t sz; + int t; + + /* + * Read the struct name from the debugger input. + */ + t = db_read_token(); + if (t != tIDENT) { + db_printf("Bad struct name\n"); + db_flush_lex(); + return; + } + name = db_tok_string; + + ctt = db_ctf_type_by_name(name, CTF_K_STRUCT); + if (ctt == NULL) { + db_printf("unknown struct %s\n", name); + db_flush_lex(); + return; + } + + /* + * Read the address, if any, from the debugger input. + * In that case, update `dot' value. + */ + if (db_expression(&addr)) { + db_dot = (db_addr_t)addr; + db_last_addr = db_dot; + } else + addr = (db_expr_t)db_dot; + + db_skip_to_eol(); + + /* + * Display the structure contents. + */ + sz = (ctt->ctt_size <= CTF_MAX_SIZE) ? + ctt->ctt_size : CTF_TYPE_LSIZE(ctt); + db_printf("struct %s at %p (%llu bytes) ", name, (void *)addr, sz); + db_ctf_pprint_struct(ctt, addr); } Index: db_sym.h =================================================================== RCS file: /cvs/src/sys/ddb/db_sym.h,v retrieving revision 1.32 diff -u -p -r1.32 db_sym.h --- db_sym.h 11 Aug 2017 20:50:15 -0000 1.32 +++ db_sym.h 4 Sep 2017 23:14:09 -0000 @@ -96,6 +96,5 @@ bool db_dwarf_line_at_pc(const char *, s struct ctf_type; int db_ctf_func_numargs(Elf_Sym *); -const struct ctf_type *db_ctf_type_by_name(char *); #endif /* _DDB_DB_SYM_H_ */