From owner-p4-projects@FreeBSD.ORG Sat Mar 8 19:58:02 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D03831065686; Sat, 8 Mar 2008 19:58:01 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8B351106567B for ; Sat, 8 Mar 2008 19:58:01 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 6ECA38FC1A for ; Sat, 8 Mar 2008 19:58:01 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m28Jw1eB053929 for ; Sat, 8 Mar 2008 19:58:01 GMT (envelope-from jb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m28Jw1EW053927 for perforce@freebsd.org; Sat, 8 Mar 2008 19:58:01 GMT (envelope-from jb@freebsd.org) Date: Sat, 8 Mar 2008 19:58:01 GMT Message-Id: <200803081958.m28Jw1EW053927@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jb@freebsd.org using -f From: John Birrell To: Perforce Change Reviews Cc: Subject: PERFORCE change 137185 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 08 Mar 2008 19:58:02 -0000 http://perforce.freebsd.org/chv.cgi?CH=137185 Change 137185 by jb@jb_freebsd8 on 2008/03/08 19:57:26 Add the code to print the type with struct/union field info a bit like a debugger would. Affected files ... .. //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_consume.c#15 edit Differences ... ==== //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_consume.c#15 (text) ==== @@ -810,14 +810,240 @@ nbytes, 50, quiet, 1)); } -int +typedef struct dt_type_cbdata { + dtrace_hdl_t *dtp; + dtrace_typeinfo_t dtt; + caddr_t addr; + caddr_t addrend; + const char *name; + int f_type; + int indent; + int type_width; + int name_width; + FILE *fp; +} dt_type_cbdata_t; + +static int dt_print_type_data(dt_type_cbdata_t *, ctf_id_t); + +static int +dt_print_type_member(const char *name, ctf_id_t type, ulong_t off, void *arg) +{ + dt_type_cbdata_t cbdata; + dt_type_cbdata_t *cbdatap = arg; + ssize_t ssz; + + if ((ssz = ctf_type_size(cbdatap->dtt.dtt_ctfp, type)) <= 0) + return (0); + + off /= 8; + + cbdata = *cbdatap; + cbdata.name = name; + cbdata.addr += off; + cbdata.addrend = cbdata.addr + ssz; + + return (dt_print_type_data(&cbdata, type)); +} + +static int +dt_print_type_width(const char *name, ctf_id_t type, ulong_t off, void *arg) +{ + char buf[DT_TYPE_NAMELEN]; + char *p; + dt_type_cbdata_t *cbdatap = arg; + size_t sz = strlen(name); + + ctf_type_name(cbdatap->dtt.dtt_ctfp, type, buf, sizeof (buf)); + + if ((p = strchr(buf, '[')) != NULL) + p[-1] = '\0'; + else + p = ""; + + sz += strlen(p); + + if (sz > cbdatap->name_width) + cbdatap->name_width = sz; + + sz = strlen(buf); + + if (sz > cbdatap->type_width) + cbdatap->type_width = sz; + + return (0); +} + +static int +dt_print_type_data(dt_type_cbdata_t *cbdatap, ctf_id_t type) +{ + caddr_t addr = cbdatap->addr; + caddr_t addrend = cbdatap->addrend; + char buf[DT_TYPE_NAMELEN]; + char *p; + int cnt = 0; + uint_t kind = ctf_type_kind(cbdatap->dtt.dtt_ctfp, type); + ssize_t ssz = ctf_type_size(cbdatap->dtt.dtt_ctfp, type); + + ctf_type_name(cbdatap->dtt.dtt_ctfp, type, buf, sizeof (buf)); + + if ((p = strchr(buf, '[')) != NULL) + p[-1] = '\0'; + else + p = ""; + + if (cbdatap->f_type) { + int type_width = roundup(cbdatap->type_width + 1, 4); + int name_width = roundup(cbdatap->name_width + 1, 4); + + name_width -= strlen(cbdatap->name); + + dt_printf(cbdatap->dtp, cbdatap->fp, "%*s%-*s%s%-*s = ",cbdatap->indent * 4,"",type_width,buf,cbdatap->name,name_width,p); + } + + while (addr < addrend) { + dt_type_cbdata_t cbdata; + ctf_arinfo_t arinfo; + ctf_encoding_t cte; + void *vp = addr; + cbdata = *cbdatap; + cbdata.name = ""; + cbdata.addr = addr; + cbdata.addrend = addr + ssz; + cbdata.f_type = 0; + cbdata.indent++; + cbdata.type_width = 0; + cbdata.name_width = 0; + + if (cnt > 0) + dt_printf(cbdatap->dtp, cbdatap->fp, "%*s", cbdatap->indent * 4,""); + + switch (kind) { + case CTF_K_INTEGER: + if (ctf_type_encoding(cbdatap->dtt.dtt_ctfp, type, &cte) != 0) + return (-1); + if ((cte.cte_format & CTF_INT_SIGNED) != 0) + switch (cte.cte_bits) { + case 8: + if (isprint(*((char *) vp))) + dt_printf(cbdatap->dtp, cbdatap->fp, "'%c', ", *((char *) vp)); + dt_printf(cbdatap->dtp, cbdatap->fp, "%d (0x%x);\n", *((char *) vp), *((char *) vp)); + break; + case 16: + dt_printf(cbdatap->dtp, cbdatap->fp, "%hd (0x%hx);\n", *((short *) vp), *((u_short *) vp)); + break; + case 32: + dt_printf(cbdatap->dtp, cbdatap->fp, "%d (0x%x);\n", *((int *) vp), *((u_int *) vp)); + break; + case 64: + dt_printf(cbdatap->dtp, cbdatap->fp, "%jd (0x%jx);\n", *((long long *) vp), *((unsigned long long *) vp)); + break; + default: + dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_INTEGER: format %x offset %u bits %u\n",cte.cte_format,cte.cte_offset,cte.cte_bits); + break; + } + else + switch (cte.cte_bits) { + case 8: + dt_printf(cbdatap->dtp, cbdatap->fp, "%u (0x%x);\n", *((uint8_t *) vp) & 0xff, *((uint8_t *) vp) & 0xff); + break; + case 16: + dt_printf(cbdatap->dtp, cbdatap->fp, "%hu (0x%hx);\n", *((u_short *) vp), *((u_short *) vp)); + break; + case 32: + dt_printf(cbdatap->dtp, cbdatap->fp, "%u (0x%x);\n", *((u_int *) vp), *((u_int *) vp)); + break; + case 64: + dt_printf(cbdatap->dtp, cbdatap->fp, "%ju (0x%jx);\n", *((unsigned long long *) vp), *((unsigned long long *) vp)); + break; + default: + dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_INTEGER: format %x offset %u bits %u\n",cte.cte_format,cte.cte_offset,cte.cte_bits); + break; + } + break; + case CTF_K_FLOAT: + dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_FLOAT: format %x offset %u bits %u\n",cte.cte_format,cte.cte_offset,cte.cte_bits); + break; + case CTF_K_POINTER: + dt_printf(cbdatap->dtp, cbdatap->fp, "%p;\n", *((char *) addr)); + break; + case CTF_K_ARRAY: + if (ctf_array_info(cbdatap->dtt.dtt_ctfp, type, &arinfo) != 0) + return (-1); + dt_printf(cbdatap->dtp, cbdatap->fp, "{\n%*s",cbdata.indent * 4,""); + dt_print_type_data(&cbdata, arinfo.ctr_contents); + dt_printf(cbdatap->dtp, cbdatap->fp, "%*s};\n",cbdatap->indent * 4,""); + break; + case CTF_K_FUNCTION: + dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_FUNCTION:\n"); + break; + case CTF_K_STRUCT: + cbdata.f_type = 1; + if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type, + dt_print_type_width, &cbdata) != 0) + return (-1); + dt_printf(cbdatap->dtp, cbdatap->fp, "{\n"); + if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type, + dt_print_type_member, &cbdata) != 0) + return (-1); + dt_printf(cbdatap->dtp, cbdatap->fp, "%*s};\n",cbdatap->indent * 4,""); + break; + case CTF_K_UNION: + cbdata.f_type = 1; + if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type, + dt_print_type_width, &cbdata) != 0) + return (-1); + dt_printf(cbdatap->dtp, cbdatap->fp, "{\n"); + if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type, + dt_print_type_member, &cbdata) != 0) + return (-1); + dt_printf(cbdatap->dtp, cbdatap->fp, "%*s};\n",cbdatap->indent * 4,""); + break; + case CTF_K_ENUM: + dt_printf(cbdatap->dtp, cbdatap->fp, "%s;\n", ctf_enum_name(cbdatap->dtt.dtt_ctfp, type, *((int *) vp))); + break; + case CTF_K_TYPEDEF: + dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type)); + break; + case CTF_K_VOLATILE: + if (cbdatap->f_type) + dt_printf(cbdatap->dtp, cbdatap->fp, "volatile "); + dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type)); + break; + case CTF_K_CONST: + if (cbdatap->f_type) + dt_printf(cbdatap->dtp, cbdatap->fp, "const "); + dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type)); + break; + case CTF_K_RESTRICT: + if (cbdatap->f_type) + dt_printf(cbdatap->dtp, cbdatap->fp, "restrict "); + dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type)); + break; + default: + break; + } + + addr += ssz; + cnt++; + } + + return (0); +} + +static int dt_print_type(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr) { + caddr_t addrend; + char *p; dtrace_typeinfo_t dtt; - char *p; + dt_type_cbdata_t cbdata; int num = 0; int quiet = (dtp->dt_options[DTRACEOPT_QUIET] != DTRACEOPT_UNSET); + ssize_t ssz; + if (!quiet) + dt_printf(dtp, fp, "\n"); + /* Get the total number of bytes of data buffered. */ size_t nbytes = *((uintptr_t *) addr); addr += sizeof(uintptr_t); @@ -860,13 +1086,25 @@ /* Offset the buffer address to the start of the data... */ addr += offset; - /* - * XXX Here we need code to expand the type and print the data - * elements based on the member types. - */ + ssz = ctf_type_size(dtt.dtt_ctfp, dtt.dtt_type); + + if (typs != ssz) { + printf("Expected type size from buffer (%lu) to match type size looked up now (%ld)\n", (u_long) typs, (long) ssz); + return (-1); + } + + cbdata.dtp = dtp; + cbdata.dtt = dtt; + cbdata.name = ""; + cbdata.addr = addr; + cbdata.addrend = addr + nbytes; + cbdata.indent = 1; + cbdata.f_type = 1; + cbdata.type_width = 0; + cbdata.name_width = 0; + cbdata.fp = fp; - /* XXX Just print the data for now. */ - return (dt_print_bytes(dtp, fp, addr, nbytes, 50, quiet, 1)); + return (dt_print_type_data(&cbdata, dtt.dtt_type)); } static int