Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Jan 2014 01:35:14 +0000 (UTC)
From:      Kai Wang <kaiw@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r260897 - projects/elftoolchain/cddl/contrib/opensolaris/tools/ctf/cvt
Message-ID:  <201401200135.s0K1ZEwm004244@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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
 		}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401200135.s0K1ZEwm004244>