Skip to content

Commit 6bb3fc7

Browse files
committed
fix problem typing embedded pointer fields
1 parent 241d3d7 commit 6bb3fc7

File tree

2 files changed

+45
-12
lines changed

2 files changed

+45
-12
lines changed

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfDebugInfo.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,7 @@ private DwarfMethodProperties lookupMethodProperties(MethodEntry methodEntry) {
582582
}
583583

584584
void setTypeIndex(TypeEntry typeEntry, int idx) {
585+
assert idx >= 0;
585586
DwarfTypeProperties typeProperties = lookupTypeProperties(typeEntry);
586587
assert typeProperties.getTypeInfoIndex() == -1 || typeProperties.getTypeInfoIndex() == idx;
587588
typeProperties.setTypeInfoIndex(idx);
@@ -598,6 +599,7 @@ int getTypeIndex(DwarfTypeProperties typeProperties) {
598599
}
599600

600601
void setIndirectTypeIndex(TypeEntry typeEntry, int idx) {
602+
assert idx >= 0;
601603
DwarfTypeProperties typeProperties = lookupTypeProperties(typeEntry);
602604
assert typeProperties.getIndirectTypeInfoIndex() == -1 || typeProperties.getIndirectTypeInfoIndex() == idx;
603605
typeProperties.setIndirectTypeInfoIndex(idx);
@@ -614,6 +616,7 @@ int getIndirectTypeIndex(DwarfTypeProperties typeProperties) {
614616
}
615617

616618
void setLayoutIndex(ClassEntry classEntry, int idx) {
619+
assert idx >= 0;
617620
DwarfClassProperties classProperties = lookupClassProperties(classEntry);
618621
assert classProperties.getTypeEntry() == classEntry;
619622
assert classProperties.layoutIndex == -1 || classProperties.layoutIndex == idx;
@@ -629,6 +632,7 @@ int getLayoutIndex(ClassEntry classEntry) {
629632
}
630633

631634
void setIndirectLayoutIndex(ClassEntry classEntry, int idx) {
635+
assert idx >= 0;
632636
DwarfClassProperties classProperties = lookupClassProperties(classEntry);
633637
assert classProperties.getTypeEntry() == classEntry;
634638
assert classProperties.indirectLayoutIndex == -1 || classProperties.indirectLayoutIndex == idx;

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)