From owner-svn-src-projects@FreeBSD.ORG Mon Jan 20 01:35:15 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 45267F07; Mon, 20 Jan 2014 01:35:15 +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)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 179C21F95; Mon, 20 Jan 2014 01:35:15 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id s0K1ZEYn004246; Mon, 20 Jan 2014 01:35:14 GMT (envelope-from kaiw@svn.freebsd.org) Received: (from kaiw@localhost) by svn.freebsd.org (8.14.7/8.14.7/Submit) id s0K1ZEwm004244; Mon, 20 Jan 2014 01:35:14 GMT (envelope-from kaiw@svn.freebsd.org) Message-Id: <201401200135.s0K1ZEwm004244@svn.freebsd.org> From: Kai Wang Date: Mon, 20 Jan 2014 01:35:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r260897 - projects/elftoolchain/cddl/contrib/opensolaris/tools/ctf/cvt X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Jan 2014 01:35:15 -0000 Author: kaiw Date: Mon Jan 20 01:35:14 2014 New Revision: 260897 URL: http://svnweb.freebsd.org/changeset/base/260897 Log: Clang 3.4 will sometimes emit DIE for struct/union member before emitting the DIE for the type of that member. ctfconvert can not handle this properly and will calculate a wrong member bit offset. Same struct/union type from different .o file will be treated as different types when their member bit offsets are different, and gets added/merged multiple times. This will in turn cause many other structs/pointers/typedefs that refer to the duplicated struct/union gets added/merged multiple times and eventually causes numerous duplicated CTF types in the kernel.debug file. The simple workaround here is to make use of DW_AT_byte_size attribute of the member DIE to calculate the bits occupied by the member's type, without actually resolving the type. Modified: projects/elftoolchain/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c Modified: projects/elftoolchain/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c ============================================================================== --- projects/elftoolchain/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c Sun Jan 19 22:25:57 2014 (r260896) +++ projects/elftoolchain/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c Mon Jan 20 01:35:14 2014 (r260897) @@ -938,7 +938,7 @@ static void die_sou_create(dwarf_t *dw, Dwarf_Die str, Dwarf_Off off, tdesc_t *tdp, int type, const char *typename) { - Dwarf_Unsigned sz, bitsz, bitoff, maxsz=0; + Dwarf_Unsigned sz, bysz, bitsz, bitoff, maxsz=0; Dwarf_Die mem; mlist_t *ml, **mlastp; iidesc_t *ii; @@ -1013,8 +1013,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 }