Skip to content

Commit 242387e

Browse files
committed
Implement PR #3732 Add Java type information to Windows debug
1 parent 4560e45 commit 242387e

File tree

12 files changed

+2078
-94
lines changed

12 files changed

+2078
-94
lines changed

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
@@ -226,7 +226,7 @@ public String getFileName() {
226226
}
227227

228228
@SuppressWarnings("unused")
229-
String getFullFileName() {
229+
public String getFullFileName() {
230230
if (fileEntry != null) {
231231
return fileEntry.getFullName();
232232
} 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: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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+
import java.util.Arrays;
34+
import java.util.stream.Collectors;
35+
36+
final class CVNames {
37+
38+
static String typeNameToCodeViewName(String typeName) {
39+
return typeName.replace('.', '_').replace("[]", "_array");
40+
}
41+
42+
static String typeNameToCodeViewName(TypeEntry typeEntry) {
43+
return typeNameToCodeViewName(typeEntry.getTypeName());
44+
}
45+
46+
static String staticFieldNameToCodeViewName(FieldEntry fieldEntry) {
47+
return typeNameToCodeViewName(fieldEntry.ownerType()) + "_" + fieldEntry.fieldName();
48+
}
49+
50+
static String staticFunctionNameToCodeViewName(MethodEntry methodEntry) {
51+
return typeNameToCodeViewName(methodEntry.ownerType()) + "::" + methodEntry.methodName();
52+
}
53+
54+
static String staticFunctionNameAndArgsToCodeViewName(MethodEntry methodEntry) {
55+
return functionNameAndArgsToCodeViewName(methodEntry);
56+
}
57+
58+
static String functionNameToCodeViewName(MethodEntry methodEntry) {
59+
return typeNameToCodeViewName(methodEntry.ownerType()) + "::" + methodEntry.methodName();
60+
}
61+
62+
static String functionNameAndArgsToCodeViewName(MethodEntry methodEntry) {
63+
final String paramString;
64+
if (methodEntry.getParamCount() > 0) {
65+
paramString = "_" + Arrays.stream(methodEntry.getParamTypes()).map(CVNames::typeNameToCodeViewName).collect(Collectors.joining("_"));
66+
} else {
67+
paramString = "";
68+
}
69+
return functionNameToCodeViewName(methodEntry) + paramString;
70+
}
71+
}

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

Lines changed: 111 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,88 @@ 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, int typeIndex, int offset, short segment) {
291+
super(cvDebugInfo, CVDebugConstants.S_LDATA32, symbolName, symbolName, typeIndex, offset, segment);
292+
}
293+
294+
@Override
295+
public String toString() {
296+
return String.format("S_LDATA32 name=%s offset=0x%x type=0x%x", symbolName, offset, typeIndex);
297+
}
298+
}
299+
300+
public static class CVSymbolRegRel32Record extends CVSymbolSubrecord {
301+
302+
private final String name;
303+
private final int typeIndex;
304+
private final int offset;
305+
private final short register;
306+
307+
CVSymbolRegRel32Record(CVDebugInfo debugInfo, String name, int typeIndex, int offset, short register) {
308+
super(debugInfo, CVDebugConstants.S_REGREL32);
309+
this.name = name;
310+
this.typeIndex = typeIndex;
311+
this.offset = offset;
312+
this.register = register;
313+
}
314+
315+
@Override
316+
protected int computeContents(byte[] buffer, int initialPos) {
317+
int pos = CVUtil.putInt(offset, buffer, initialPos);
318+
pos = CVUtil.putInt(typeIndex, buffer, pos);
319+
pos = CVUtil.putShort(register, buffer, pos);
320+
pos = CVUtil.putUTF8StringBytes(name, buffer, pos);
321+
return pos;
322+
}
323+
324+
@Override
325+
public String toString() {
326+
return String.format("S_REGREL32 name=%s offset=(r%d + 0x%x) type=0x%x)", name, register, offset, typeIndex);
327+
}
328+
}
329+
248330
/*
249331
* Creating a proc32 record has a side effect: two relocation entries are added to the section
250332
* relocation table; they refer back to the global symbol.
@@ -258,15 +340,14 @@ public static class CVSymbolGProc32Record extends CVSymbolSubrecord {
258340
private final int debugStart;
259341
private final int debugEnd;
260342
private final int typeIndex;
261-
private final int offset;
262343
private final short segment;
263344
private final byte flags;
264345
private final String symbolName;
265346
private final String displayName;
266347

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);
348+
CVSymbolGProc32Record(CVDebugInfo cvDebugInfo, String symbolName, String displayName, int pparent, int pend, int pnext, int proclen, int debugStart, int debugEnd, int typeIndex,
349+
short segment, byte flags) {
350+
super(cvDebugInfo, CVDebugConstants.S_GPROC32);
270351
this.symbolName = symbolName;
271352
this.displayName = displayName;
272353
this.pparent = pparent;
@@ -276,16 +357,10 @@ public static class CVSymbolGProc32Record extends CVSymbolSubrecord {
276357
this.debugStart = debugStart;
277358
this.debugEnd = debugEnd;
278359
this.typeIndex = typeIndex;
279-
this.offset = offset;
280360
this.segment = segment;
281361
this.flags = flags;
282362
}
283363

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-
289364
@Override
290365
protected int computeContents(byte[] buffer, int initialPos) {
291366
int pos = CVUtil.putInt(pparent, buffer, initialPos);
@@ -303,8 +378,8 @@ protected int computeContents(byte[] buffer, int initialPos) {
303378

304379
@Override
305380
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);
381+
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,
382+
debugEnd, proclen, segment, typeIndex, flags);
308383
}
309384
}
310385

@@ -351,6 +426,30 @@ public String toString() {
351426
}
352427
}
353428

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

356455
CVSymbolEndRecord(CVDebugInfo cvDebugInfo, short cmd) {

0 commit comments

Comments
 (0)