@@ -331,18 +331,34 @@ private int writeStructField(DebugContext context, FieldEntry fieldEntry, byte[]
331331 TypeEntry valueType = fieldEntry .getValueType ();
332332 int valueTypeIdx ;
333333 if (fieldEntry .isEmbedded ()) {
334- assert valueType instanceof ClassEntry ;
334+ // the field type must be a foreign type
335+ ForeignTypeEntry foreignValueType = (ForeignTypeEntry ) valueType ;
335336 /* use the indirect layout type for the field */
336337 /* handle special case when the field is an array */
337338 int fieldSize = fieldEntry .getSize ();
338- int valueSize = valueType .getSize ();
339- if (fieldEntry .getSize () != valueType .getSize ()) {
339+ int valueSize = foreignValueType .getSize ();
340+ if (fieldEntry .getSize () != foreignValueType .getSize ()) {
340341 assert (fieldSize % valueSize == 0 ) : "embedded field size is not a multiple of value type size!" ;
341342 // declare a local array of the embedded type and use it as the value type
342343 valueTypeIdx = pos ;
343- pos = writeEmbeddedArrayDataType (context , ( ClassEntry ) valueType , valueSize , fieldSize / valueSize , buffer , pos );
344+ pos = writeEmbeddedArrayDataType (context , foreignValueType , valueSize , fieldSize / valueSize , buffer , pos );
344345 } else {
345- valueTypeIdx = getIndirectLayoutIndex ((ClassEntry ) valueType );
346+ if (foreignValueType .isPointer ()) {
347+ // type the array using the referent of the pointer type
348+ //
349+ // n.b it is critical for correctness to use the index of the referent rather
350+ // than the layout type of the referring type even though the latter will
351+ // (eventually) be set to the same value. the type index of the referent is
352+ // guaranteed to be set on the first sizing pass before it is consumed here
353+ // on the second writing pass.
354+ // However, if this embedded struct field definition precedes the definition
355+ // of the referring type and the latter precedes the definition of the
356+ // referent type then the layout index of the referring type may still be unset
357+ // at this point.
358+ valueTypeIdx = getTypeIndex (foreignValueType .getPointerTo ());
359+ } else {
360+ valueTypeIdx = getIndirectLayoutIndex (foreignValueType );
361+ }
346362 }
347363 } else {
348364 /* use the indirect type for the field so pointers get translated */
@@ -538,6 +554,7 @@ private int writeClassLayout(DebugContext context, ClassEntry classEntry, byte[]
538554 */
539555 pos = writeAttrNull (buffer , pos );
540556 } else {
557+ log (context , " [0x%08x] setIndirectLayoutIndex %s 0x%x" , pos , classEntry .getTypeName (), pos );
541558 setIndirectLayoutIndex (classEntry , layoutIndex );
542559 }
543560
@@ -906,14 +923,12 @@ private int writeForeignLayout(DebugContext context, ForeignTypeEntry foreignTyp
906923 pos = writeForeignStructLayout (context , foreignTypeEntry , size , buffer , pos );
907924 } else {
908925 // this must be a pointer. if the target type is known use it to declare the pointer
909- // type
910- // otherwise default to 'void *'
926+ // type, otherwise default to 'void *'
911927 layoutOffset = voidOffset ;
912928 String referentName = "void" ;
913929 if (foreignTypeEntry .isPointer ()) {
914930 TypeEntry pointerTo = foreignTypeEntry .getPointerTo ();
915931 if (pointerTo != null ) {
916- // define this type as a typedef for a pointer to the referent
917932 layoutOffset = getTypeIndex (foreignTypeEntry .getPointerTo ());
918933 referentName = foreignTypeEntry .getTypeName ();
919934 }
@@ -1326,7 +1341,7 @@ private int writeArrayDataType(DebugContext context, TypeEntry elementType, byte
13261341 return pos ;
13271342 }
13281343
1329- private int writeEmbeddedArrayDataType (DebugContext context , ClassEntry elementType , int valueSize , int arraySize , byte [] buffer , int p ) {
1344+ private int writeEmbeddedArrayDataType (DebugContext context , ForeignTypeEntry foreignValueType , int valueSize , int arraySize , byte [] buffer , int p ) {
13301345 int pos = p ;
13311346 log (context , " [0x%08x] embedded array element data type" , pos );
13321347 int abbrevCode = DwarfDebugInfo .DW_ABBREV_CODE_array_data_type2 ;
@@ -1336,9 +1351,23 @@ private int writeEmbeddedArrayDataType(DebugContext context, ClassEntry elementT
13361351 int size = arraySize * valueSize ;
13371352 log (context , " [0x%08x] byte_size 0x%x" , pos , size );
13381353 pos = writeAttrData4 (size , buffer , pos );
1339- String elementTypeName = elementType .getTypeName ();
1340- /* use the indirect layout type for the element */
1341- int elementTypeIdx = getIndirectLayoutIndex (elementType );
1354+ String elementTypeName = foreignValueType .getTypeName ();
1355+ int elementTypeIdx ;
1356+ if (foreignValueType .isPointer ()) {
1357+ // type the array using the referent of the pointer type
1358+ //
1359+ // n.b it is critical for correctness to use the index of the referent rather than
1360+ // the layout type of the referring type even though the latter will (eventually)
1361+ // be set to the same value. the type index of the referent is guaranteed to be set
1362+ // on the first sizing pass before it is consumed here on the second writing pass.
1363+ // However, if this embedded struct field definition precedes the definition of the
1364+ // referring type and the latter precedes the definition of the referent type then
1365+ // the layout index of the referring type may still be unset at this point.
1366+ elementTypeIdx = getTypeIndex (foreignValueType .getPointerTo ());
1367+ } else {
1368+ // type the array using the layout type
1369+ elementTypeIdx = getIndirectLayoutIndex (foreignValueType );
1370+ }
13421371 log (context , " [0x%08x] type idx 0x%x (%s)" , pos , elementTypeIdx , elementTypeName );
13431372 pos = writeInfoSectionOffset (elementTypeIdx , buffer , pos );
13441373 // write subrange child DIE
0 commit comments