From owner-svn-src-projects@FreeBSD.ORG  Sun Jan 19 13:48:04 2014
Return-Path: <owner-svn-src-projects@FreeBSD.ORG>
Delivered-To: svn-src-projects@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 AE74EB5E;
 Sun, 19 Jan 2014 13:48:03 +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 137461E59;
 Sun, 19 Jan 2014 13:48:03 +0000 (UTC)
Received: from svn.freebsd.org ([127.0.1.70])
 by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id s0JDm21O028581;
 Sun, 19 Jan 2014 13:48:02 GMT (envelope-from kaiw@svn.freebsd.org)
Received: (from kaiw@localhost)
 by svn.freebsd.org (8.14.7/8.14.7/Submit) id s0JDm2ZS028579;
 Sun, 19 Jan 2014 13:48:02 GMT (envelope-from kaiw@svn.freebsd.org)
Message-Id: <201401191348.s0JDm2ZS028579@svn.freebsd.org>
From: Kai Wang <kaiw@FreeBSD.org>
Date: Sun, 19 Jan 2014 13:48:02 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject: svn commit: r260880 -
 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 &quot; projects&quot;
 tree" <svn-src-projects.freebsd.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/options/svn-src-projects>, 
 <mailto:svn-src-projects-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-projects/>
List-Post: <mailto:svn-src-projects@freebsd.org>
List-Help: <mailto:svn-src-projects-request@freebsd.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-projects>, 
 <mailto:svn-src-projects-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Sun, 19 Jan 2014 13:48:04 -0000

Author: kaiw
Date: Sun Jan 19 13:48:02 2014
New Revision: 260880
URL: http://svnweb.freebsd.org/changeset/base/260880

Log:
  * 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].

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 13:42:49 2014	(r260879)
+++ projects/elftoolchain/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c	Sun Jan 19 13:48:02 2014	(r260880)
@@ -492,23 +492,71 @@ die_mem_offset(dwarf_t *dw, Dwarf_Die di
 	Dwarf_Locdesc *loc = NULL;
 	Dwarf_Signed locnum = 0;
 	Dwarf_Attribute at;
+	Dwarf_Half form;
+
+	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 (dwarf_loclist(at, &loc, &locnum, &dw->dw_err) != DW_DLV_OK)
+	if (dwarf_whatform(at, &form, &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));
-	}
+	switch (form) {
+	case DW_FORM_sec_offset:
+	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_loclist(at, &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 with "
+			    "operator other than DW_OP_plus_uconst\n",
+			    die_off(dw, die));
+		}
+		*valp = loc->ld_s->lr_number;
+		if (loc != NULL) {
+			dwarf_dealloc(dw->dw_dw, loc->ld_s, DW_DLA_LOC_BLOCK);
+			dwarf_dealloc(dw->dw_dw, loc, DW_DLA_LOCDESC);
+		}
+		break;
 
-	*valp = loc->ld_s->lr_number;
+	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.
+		 *
+		 * However, note that DW_FORM_data[48] in DWARF version 2 or 3
+		 * could be used as a section offset (offset into .debug_loc in
+		 * this case). Here we assume the attribute always stores a
+		 * constant because we know Clang 3.4 does this and GCC in
+		 * base won't emit DW_FORM_data[48] for this attribute. This
+		 * code will remain correct if future vesrions of Clang and
+		 * GCC conform to DWARF4 standard and only use the form
+		 * DW_FORM_sec_offset for section offset.
+		 */
+		if (dwarf_attrval_unsigned(die, name, valp, &dw->dw_err) !=
+		    DW_DLV_OK)
+			return (0);
+		break;
 
-	if (loc != NULL) {
-		dwarf_dealloc(dw->dw_dw, loc->ld_s, DW_DLA_LOC_BLOCK);
-		dwarf_dealloc(dw->dw_dw, loc, DW_DLA_LOCDESC);
+	default:
+		terminate("die %llu: cannot parse member offset with form "
+		    "%u\n", die_off(dw, die), form);
 	}
 
 	return (1);