Skip to content

Commit 47d10f8

Browse files
committed
[GR-34179] Upgrade CE debug info feature to provide information about Java types for Windows/PECOFF.
PullRequest: graal/13335
2 parents 147e12f + 9aea657 commit 47d10f8

File tree

13 files changed

+2065
-121
lines changed

13 files changed

+2065
-121
lines changed

substratevm/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This changelog summarizes major changes to GraalVM Native Image.
1010
* (GR-41100) Add support for `-XX:HeapDumpPath` to control where heap dumps are created.
1111
* (GR-42148) Adjust build output to report types (primitives, classes, interfaces, and arrays) instead of classes and revise the output schema of `-H:BuildOutputJSONFile`.
1212
* (GR-42375) Add `-H:±GenerateBuildArtifactsFile` option, which generates a `build-artifacts.json` file with a list of all artifacts produced by Native Image. `.build_artifacts.txt` files are now deprecated, disabled (can be re-enabled with env setting `NATIVE_IMAGE_DEPRECATED_BUILD_ARTIFACTS_TXT=true`), and will be removed in a future release.
13+
* (GR-34179) Improved debugging support on Windows: Debug information now includes information about Java types (contributed by Red Hat).
1314

1415
## Version 22.3.0
1516
* (GR-35721) Remove old build output style and the `-H:±BuildOutputUseNewStyle` option.

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ public String getFileName() {
244244
}
245245

246246
@SuppressWarnings("unused")
247-
String getFullFileName() {
247+
public String getFullFileName() {
248248
if (fileEntry != null) {
249249
return fileEntry.getFullName();
250250
} else {

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/cv/CVConstants.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,13 @@ public abstract class CVConstants {
3535

3636
/* CodeView section header signature */
3737
static final int CV_SIGNATURE_C13 = 4;
38+
39+
static final int CV_AMD64_R8 = 336;
40+
static final int CV_AMD64_R9 = 337;
41+
static final int CV_AMD64_R10 = 338;
42+
static final int CV_AMD64_R11 = 339;
43+
static final int CV_AMD64_R12 = 340;
44+
static final int CV_AMD64_R13 = 341;
45+
static final int CV_AMD64_R14 = 342;
46+
static final int CV_AMD64_R15 = 343;
3847
}

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/cv/CVDebugConstants.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,13 @@ public abstract class CVDebugConstants {
3535

3636
/* Subcommands in DEBUG_S_SYMBOLS section. */
3737
static final short S_END = 0x0006;
38-
static final short S_OBJNAME = 0x1101;
3938
static final short S_FRAMEPROC = 0x1012;
40-
static final short S_GPROC32 = 0x1110;
39+
static final short S_OBJNAME = 0x1101;
40+
static final short S_UDT = 0x1108;
41+
static final short S_LDATA32 = 0x110c; /* Local static. */
42+
static final short S_GDATA32 = 0x110d; /* Global static. */
43+
static final short S_GPROC32 = 0x1110; /* Global procedure. */
44+
static final short S_REGREL32 = 0x1111;
4145
static final short S_COMPILE3 = 0x113c;
4246
static final short S_ENVBLOCK = 0x113d;
4347
}

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/cv/CVDebugInfo.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,23 @@ public final class CVDebugInfo extends DebugInfoBase {
4343
private final CVTypeSectionImpl cvTypeSection;
4444
private DebugContext debugContext;
4545

46+
/* Register constants for Windows x86_64 */
47+
/* See AMD64ReservedRegisters.java. */
48+
public static final byte RHEAPBASE_X86 = (byte) 14;
49+
public static final byte RTHREAD_X86 = (byte) 15;
50+
51+
private final byte heapbaseRegister;
52+
private final byte threadRegister;
53+
4654
public CVDebugInfo(PECoffMachine machine, ByteOrder byteOrder) {
4755
super(byteOrder);
4856
cvSymbolSection = new CVSymbolSectionImpl(this);
4957
cvTypeSection = new CVTypeSectionImpl(this);
50-
if (machine != PECoffMachine.X86_64) {
51-
/* room for future aarch64 port */
58+
if (machine == PECoffMachine.X86_64) {
59+
this.heapbaseRegister = RHEAPBASE_X86;
60+
this.threadRegister = RTHREAD_X86;
61+
} else {
62+
/* room for future aach64 port */
5263
throw GraalError.shouldNotReachHere("Unsupported architecture on Windows");
5364
}
5465
}
@@ -61,6 +72,15 @@ public CVTypeSectionImpl getCVTypeSection() {
6172
return cvTypeSection;
6273
}
6374

75+
public byte getHeapbaseRegister() {
76+
return heapbaseRegister;
77+
}
78+
79+
@SuppressWarnings("unused")
80+
public byte getThreadRegister() {
81+
return threadRegister;
82+
}
83+
6484
public DebugContext getDebugContext() {
6585
return debugContext;
6686
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2020, 2020, Red Hat Inc. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation. Oracle designates this
9+
* particular file as subject to the "Classpath" exception as provided
10+
* by Oracle in the LICENSE file that accompanied this code.
11+
*
12+
* This code is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15+
* version 2 for more details (a copy is included in the LICENSE file that
16+
* accompanied this code).
17+
*
18+
* You should have received a copy of the GNU General Public License version
19+
* 2 along with this work; if not, write to the Free Software Foundation,
20+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21+
*
22+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23+
* or visit www.oracle.com if you need additional information or have any
24+
* questions.
25+
*/
26+
27+
package com.oracle.objectfile.pecoff.cv;
28+
29+
import com.oracle.objectfile.debugentry.FieldEntry;
30+
import com.oracle.objectfile.debugentry.MethodEntry;
31+
import com.oracle.objectfile.debugentry.TypeEntry;
32+
33+
final class CVNames {
34+
35+
static String typeNameToCodeViewName(String typeName) {
36+
return typeName.replace('.', '_').replace("[]", "_array");
37+
}
38+
39+
static String typeNameToCodeViewName(TypeEntry typeEntry) {
40+
return typeNameToCodeViewName(typeEntry.getTypeName());
41+
}
42+
43+
static String methodNameToCodeViewName(MethodEntry memberEntry) {
44+
return typeNameToCodeViewName(memberEntry.ownerType()) + "::" + memberEntry.methodName();
45+
}
46+
47+
static String fieldNameToCodeViewName(FieldEntry memberEntry) {
48+
return typeNameToCodeViewName(memberEntry.ownerType()) + "::" + memberEntry.fieldName();
49+
}
50+
}

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/cv/CVSymbolSubrecord.java

Lines changed: 115 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,92 @@ public String toString() {
245245
}
246246
}
247247

248+
private abstract static class CVSymbolData32Record extends CVSymbolSubrecord {
249+
250+
protected final int typeIndex;
251+
protected final int offset;
252+
protected final short segment;
253+
protected final String displayName;
254+
protected final String symbolName;
255+
256+
protected CVSymbolData32Record(CVDebugInfo cvDebugInfo, short cmd, String symbolName, String displayName, int typeIndex, int offset, short segment) {
257+
super(cvDebugInfo, cmd);
258+
assert symbolName != null;
259+
this.displayName = displayName;
260+
this.symbolName = symbolName;
261+
this.typeIndex = typeIndex;
262+
this.offset = offset;
263+
this.segment = segment;
264+
}
265+
266+
@Override
267+
protected int computeContents(byte[] buffer, int initialPos) {
268+
int pos = CVUtil.putInt(typeIndex, buffer, initialPos);
269+
pos = cvDebugInfo.getCVSymbolSection().markRelocationSite(buffer, pos, symbolName, offset);
270+
pos = CVUtil.putUTF8StringBytes(displayName, buffer, pos);
271+
return pos;
272+
}
273+
}
274+
275+
public static class CVSymbolGData32Record extends CVSymbolData32Record {
276+
277+
CVSymbolGData32Record(CVDebugInfo cvDebugInfo, String symbolName, String displayName, int typeIndex, int offset, short segment) {
278+
super(cvDebugInfo, CVDebugConstants.S_GDATA32, symbolName, displayName, typeIndex, offset, segment);
279+
}
280+
281+
@Override
282+
public String toString() {
283+
return String.format("S_GDATA32 name=%s(%s) offset=0x%x type=0x%x", symbolName, displayName, offset, typeIndex);
284+
}
285+
}
286+
287+
@SuppressWarnings("unused")
288+
public static class CVSymbolLData32Record extends CVSymbolData32Record {
289+
290+
CVSymbolLData32Record(CVDebugInfo cvDebugInfo, String symbolName, String displayName, int typeIndex, int offset, short segment) {
291+
super(cvDebugInfo, CVDebugConstants.S_LDATA32, symbolName, displayName, typeIndex, offset, segment);
292+
}
293+
294+
CVSymbolLData32Record(CVDebugInfo cvDebugInfo, String symbolName, int typeIndex, int offset, short segment) {
295+
super(cvDebugInfo, CVDebugConstants.S_LDATA32, symbolName, symbolName, typeIndex, offset, segment);
296+
}
297+
298+
@Override
299+
public String toString() {
300+
return String.format("S_LDATA32 name=%s(%s) offset=0x%x type=0x%x", symbolName, displayName, offset, typeIndex);
301+
}
302+
}
303+
304+
public static class CVSymbolRegRel32Record extends CVSymbolSubrecord {
305+
306+
private final String name;
307+
private final int typeIndex;
308+
private final int offset;
309+
private final short register;
310+
311+
CVSymbolRegRel32Record(CVDebugInfo debugInfo, String name, int typeIndex, int offset, short register) {
312+
super(debugInfo, CVDebugConstants.S_REGREL32);
313+
this.name = name;
314+
this.typeIndex = typeIndex;
315+
this.offset = offset;
316+
this.register = register;
317+
}
318+
319+
@Override
320+
protected int computeContents(byte[] buffer, int initialPos) {
321+
int pos = CVUtil.putInt(offset, buffer, initialPos);
322+
pos = CVUtil.putInt(typeIndex, buffer, pos);
323+
pos = CVUtil.putShort(register, buffer, pos);
324+
pos = CVUtil.putUTF8StringBytes(name, buffer, pos);
325+
return pos;
326+
}
327+
328+
@Override
329+
public String toString() {
330+
return String.format("S_REGREL32 name=%s offset=(r%d + 0x%x) type=0x%x)", name, register, offset, typeIndex);
331+
}
332+
}
333+
248334
/*
249335
* Creating a proc32 record has a side effect: two relocation entries are added to the section
250336
* relocation table; they refer back to the global symbol.
@@ -258,15 +344,14 @@ public static class CVSymbolGProc32Record extends CVSymbolSubrecord {
258344
private final int debugStart;
259345
private final int debugEnd;
260346
private final int typeIndex;
261-
private final int offset;
262347
private final short segment;
263348
private final byte flags;
264349
private final String symbolName;
265350
private final String displayName;
266351

267-
CVSymbolGProc32Record(CVDebugInfo cvDebugInfo, short cmd, String symbolName, String displayName, int pparent, int pend, int pnext, int proclen, int debugStart, int debugEnd, int typeIndex,
268-
int offset, short segment, byte flags) {
269-
super(cvDebugInfo, cmd);
352+
CVSymbolGProc32Record(CVDebugInfo cvDebugInfo, String symbolName, String displayName, int pparent, int pend, int pnext, int proclen, int debugStart, int debugEnd, int typeIndex,
353+
short segment, byte flags) {
354+
super(cvDebugInfo, CVDebugConstants.S_GPROC32);
270355
this.symbolName = symbolName;
271356
this.displayName = displayName;
272357
this.pparent = pparent;
@@ -276,16 +361,10 @@ public static class CVSymbolGProc32Record extends CVSymbolSubrecord {
276361
this.debugStart = debugStart;
277362
this.debugEnd = debugEnd;
278363
this.typeIndex = typeIndex;
279-
this.offset = offset;
280364
this.segment = segment;
281365
this.flags = flags;
282366
}
283367

284-
CVSymbolGProc32Record(CVDebugInfo cvDebugInfo, String symbolName, String displayName, int pparent, int pend, int pnext, int proclen, int debugStart, int debugEnd, int typeIndex, int offset,
285-
short segment, byte flags) {
286-
this(cvDebugInfo, CVDebugConstants.S_GPROC32, symbolName, displayName, pparent, pend, pnext, proclen, debugStart, debugEnd, typeIndex, offset, segment, flags);
287-
}
288-
289368
@Override
290369
protected int computeContents(byte[] buffer, int initialPos) {
291370
int pos = CVUtil.putInt(pparent, buffer, initialPos);
@@ -303,8 +382,8 @@ protected int computeContents(byte[] buffer, int initialPos) {
303382

304383
@Override
305384
public String toString() {
306-
return String.format("S_GPROC32 name=%s/%s parent=%d debugstart=0x%x debugend=0x%x len=0x%x seg:offset=0x%x:0x%x type=0x%x flags=0x%x)", displayName, symbolName, pparent, debugStart,
307-
debugEnd, proclen, segment, offset, typeIndex, flags);
385+
return String.format("S_GPROC32 name=%s/%s parent=%d debugstart=0x%x debugend=0x%x len=0x%x seg:offset=0x%x:0 type=0x%x flags=0x%x)", displayName, symbolName, pparent, debugStart,
386+
debugEnd, proclen, segment, typeIndex, flags);
308387
}
309388
}
310389

@@ -351,6 +430,30 @@ public String toString() {
351430
}
352431
}
353432

433+
public static final class CVSymbolUDTRecord extends CVSymbolSubrecord {
434+
435+
private final int typeIdx;
436+
private final String typeName;
437+
438+
CVSymbolUDTRecord(CVDebugInfo cvDebugInfo, int typeIdx, String typeName) {
439+
super(cvDebugInfo, CVDebugConstants.S_UDT);
440+
this.typeIdx = typeIdx;
441+
this.typeName = typeName;
442+
}
443+
444+
@Override
445+
protected int computeContents(byte[] buffer, int initialPos) {
446+
int pos = CVUtil.putInt(typeIdx, buffer, initialPos);
447+
pos = CVUtil.putUTF8StringBytes(typeName, buffer, pos);
448+
return pos;
449+
}
450+
451+
@Override
452+
public String toString() {
453+
return String.format("S_UDT type=0x%x typename=%s", typeIdx, typeName);
454+
}
455+
}
456+
354457
public static class CVSymbolEndRecord extends CVSymbolSubrecord {
355458

356459
CVSymbolEndRecord(CVDebugInfo cvDebugInfo, short cmd) {

0 commit comments

Comments
 (0)