From owner-svn-src-all@FreeBSD.ORG Sat Mar 29 17:18:24 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 236B03A9; Sat, 29 Mar 2014 17:18:24 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 03753856; Sat, 29 Mar 2014 17:18:24 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s2THINWn087362; Sat, 29 Mar 2014 17:18:23 GMT (envelope-from dim@svn.freebsd.org) Received: (from dim@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s2THINAZ087361; Sat, 29 Mar 2014 17:18:23 GMT (envelope-from dim@svn.freebsd.org) Message-Id: <201403291718.s2THINAZ087361@svn.freebsd.org> From: Dimitry Andric Date: Sat, 29 Mar 2014 17:18:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r263915 - in stable: 10/cddl/contrib/opensolaris/tools/ctf/cvt 9/cddl/contrib/opensolaris/tools/ctf/cvt X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 29 Mar 2014 17:18:24 -0000 Author: dim Date: Sat Mar 29 17:18:23 2014 New Revision: 263915 URL: http://svnweb.freebsd.org/changeset/base/263915 Log: MFC r260880 (by kaiw, from projects/elftoolchain): * Make die_mem_offset() be able to handle DW_AT_data_member_location attributes generated by Clang 3.4. * Document how different compilers generate DW_AT_data_member_location attributes differently. * Document the quirks about DW_FORM_data[48]. This is a slightly modified version, adapted to work with the old libdwarf in stable/9 and stable/10. It should fix DTrace on these branches, when the kernel is compiled with clang 3.4. Note that you have to build *and* install the CTF tools first, before building the kernel. Otherwise you can possibly still get error messages similar to "failed to copy type of 'pr_uid': Type information is in parent and unavailable", when attempting to run dtrace(1). Submitted by: kaiw Modified: stable/10/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c Directory Properties: stable/10/ (props changed) Changes in other areas also in this revision: Modified: stable/9/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c Directory Properties: stable/9/cddl/contrib/opensolaris/ (props changed) Modified: stable/10/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c ============================================================================== --- stable/10/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c Sat Mar 29 14:35:36 2014 (r263914) +++ stable/10/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c Sat Mar 29 17:18:23 2014 (r263915) @@ -489,16 +489,59 @@ die_mem_offset(dwarf_t *dw, Dwarf_Die di { Dwarf_Locdesc *loc = NULL; Dwarf_Signed locnum = 0; + Dwarf_Attribute at; + Dwarf_Half form; - if (dwarf_locdesc(die, name, &loc, &locnum, &dw->dw_err) != DW_DLV_OK) + if (name != DW_AT_data_member_location) + terminate("die %llu: can only process attribute " + "DW_AT_data_member_location\n", die_off(dw, die)); + + if ((at = die_attr(dw, die, name, 0)) == NULL) return (0); - if (locnum != 1 || loc->ld_s->lr_atom != DW_OP_plus_uconst) { - terminate("die %llu: cannot parse member offset\n", - die_off(dw, die)); - } + if (dwarf_whatform(at, &form, &dw->dw_err) != DW_DLV_OK) + return (0); - *valp = loc->ld_s->lr_number; + switch (form) { + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + /* + * GCC in base and Clang (3.3 or below) generates + * DW_AT_data_member_location attribute with DW_FORM_block* + * form. The attribute contains one DW_OP_plus_uconst + * operator. The member offset stores in the operand. + */ + if (dwarf_locdesc(die, name, &loc, &locnum, &dw->dw_err) != + DW_DLV_OK) + return (0); + if (locnum != 1 || loc->ld_s->lr_atom != DW_OP_plus_uconst) { + terminate("die %llu: cannot parse member offset\n", + die_off(dw, die)); + } + *valp = loc->ld_s->lr_number; + break; + + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + case DW_FORM_udata: + /* + * Clang 3.4 generates DW_AT_data_member_location attribute + * with DW_FORM_data* form (constant class). The attribute + * stores a contant value which is the member offset. + */ + if (dwarf_attrval_unsigned(die, name, valp, &dw->dw_err) != + DW_DLV_OK) + return (0); + break; + + default: + terminate("die %llu: cannot parse member offset with form " + "%u\n", die_off(dw, die), form); + } if (loc != NULL) if (dwarf_locdesc_free(loc, &dw->dw_err) != DW_DLV_OK) @@ -885,6 +928,9 @@ die_sou_create(dwarf_t *dw, Dwarf_Die st int type, const char *typename) { Dwarf_Unsigned sz, bitsz, bitoff, maxsz=0; +#if BYTE_ORDER == _LITTLE_ENDIAN + Dwarf_Unsigned bysz; +#endif Dwarf_Die mem; mlist_t *ml, **mlastp; iidesc_t *ii; @@ -959,8 +1005,26 @@ die_sou_create(dwarf_t *dw, Dwarf_Die st #if BYTE_ORDER == _BIG_ENDIAN ml->ml_offset += bitoff; #else - ml->ml_offset += tdesc_bitsize(ml->ml_type) - bitoff - - ml->ml_size; + /* + * Note that Clang 3.4 will sometimes generate + * member DIE before generating the DIE for the + * member's type. The code can not handle this + * properly so that tdesc_bitsize(ml->ml_type) will + * return 0 because ml->ml_type is unknown. As a + * result, a wrong member offset will be calculated. + * To workaround this, we can instead try to + * retrieve the value of DW_AT_byte_size attribute + * which stores the byte size of the space occupied + * by the type. If this attribute exists, its value + * should equal to tdesc_bitsize(ml->ml_type)/NBBY. + */ + if (die_unsigned(dw, mem, DW_AT_byte_size, &bysz, 0) && + bysz > 0) + ml->ml_offset += bysz * NBBY - bitoff - + ml->ml_size; + else + ml->ml_offset += tdesc_bitsize(ml->ml_type) - + bitoff - ml->ml_size; #endif }