Skip to content

Commit ed32672

Browse files
[GR-58500] Incorrect address location for compressed hub references in DWARF debuginfo.
PullRequest: graal/18895
2 parents eb4dc58 + 5dbaddd commit ed32672

File tree

7 files changed

+157
-227
lines changed

7 files changed

+157
-227
lines changed

substratevm/debug/gdbpy/gdb-debughelpers.py

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ class SVMUtil:
100100
compressed_ref_prefix = '_z_.'
101101

102102
use_heap_base = try_or_else(lambda: bool(gdb.parse_and_eval('(int)__svm_use_heap_base')), True, gdb.error)
103-
compressed_shift = try_or_else(lambda: int(gdb.parse_and_eval('(int)__svm_compressed_shift')), 0, gdb.error)
104-
oop_tags_mask = try_or_else(lambda: int(gdb.parse_and_eval('(int)__svm_oop_tags_mask')), 0, gdb.error)
103+
compression_shift = try_or_else(lambda: int(gdb.parse_and_eval('(int)__svm_compression_shift')), 0, gdb.error)
104+
reserved_bits_mask = try_or_else(lambda: int(gdb.parse_and_eval('(int)__svm_reserved_bits_mask')), 0, gdb.error)
105105
object_alignment = try_or_else(lambda: int(gdb.parse_and_eval('(int)__svm_object_alignment')), 0, gdb.error)
106106

107107
string_type = gdb.lookup_type("java.lang.String")
@@ -190,31 +190,34 @@ def get_compressed_type(cls, t: gdb.Type) -> gdb.Type:
190190
return gdb.lookup_type(type_name)
191191

192192
@classmethod
193-
def get_compressed_adr(cls, obj: gdb.Value) -> int:
193+
def get_compressed_oop(cls, obj: gdb.Value) -> int:
194194
# use compressed ref if available - only compute it if necessary
195195
if obj.type.code == gdb.TYPE_CODE_PTR and cls.is_compressed(obj.type):
196196
return int(obj)
197197

198-
absolute_adr = adr(obj)
199-
if absolute_adr == 0:
200-
return absolute_adr
198+
obj_adr = adr(obj)
199+
if obj_adr == 0:
200+
return obj_adr
201201

202-
# recreate correct address for compressed oops
203-
# For an explanation of the conversion rules see com.oracle.svm.core.heap.ReferenceAccess
202+
# recreate compressed oop from the object address
203+
# this reverses the uncompress expression from
204+
# com.oracle.objectfile.elf.dwarf.DwarfInfoSectionImpl#writeIndirectOopConversionExpression
204205
is_hub = cls.get_rtt(obj) == cls.hub_type
205-
oop_compressed_shift = cls.compressed_shift
206-
oop_tag_shift = int.bit_count(cls.oop_tags_mask)
207-
oop_align_shift = int.bit_count(cls.object_alignment - 1)
208-
compressed_adr = absolute_adr
206+
compression_shift = cls.compression_shift
207+
num_reserved_bits = int.bit_count(cls.reserved_bits_mask)
208+
num_alignment_bits = int.bit_count(cls.object_alignment - 1)
209+
compressed_oop = obj_adr
209210
if cls.use_heap_base:
210-
compressed_adr -= int(SVMUtil.get_heap_base())
211-
if is_hub:
212-
if oop_compressed_shift == 0:
213-
oop_compressed_shift = oop_align_shift
214-
compressed_adr = compressed_adr << oop_tag_shift
215-
compressed_adr = compressed_adr >> oop_compressed_shift
211+
compressed_oop -= int(SVMUtil.get_heap_base())
212+
assert compression_shift >= 0
213+
compressed_oop = compressed_oop >> compression_shift
214+
if is_hub:
215+
assert num_alignment_bits >= 0
216+
compressed_oop = compressed_oop << num_alignment_bits
217+
assert num_reserved_bits >= 0
218+
compressed_oop = compressed_oop >> num_reserved_bits
216219

217-
return compressed_adr
220+
return compressed_oop
218221

219222
@classmethod
220223
def get_unqualified_type_name(cls, qualified_type_name: str) -> str:
@@ -237,7 +240,7 @@ def is_compressed(cls, t: gdb.Type) -> bool:
237240
@classmethod
238241
def adr_str(cls, obj: gdb.Value) -> str:
239242
if not svm_print_address.absolute_adr and cls.is_compressed(obj.type):
240-
result = f' @z({hex(cls.get_compressed_adr(obj))})'
243+
result = f' @z({hex(cls.get_compressed_oop(obj))})'
241244
else:
242245
result = f' @({hex(adr(obj))})'
243246
trace(f'<SVMUtil> - adr_str({hex(adr(obj))}) = {result}')
@@ -440,9 +443,9 @@ def cast_to(cls, obj: gdb.Value, t: gdb.Type) -> gdb.Value:
440443

441444
# get objects address, take care of compressed oops
442445
if cls.is_compressed(t):
443-
obj_adr = cls.get_compressed_adr(obj)
446+
obj_oop = cls.get_compressed_oop(obj)
444447
else:
445-
obj_adr = adr(obj)
448+
obj_oop = adr(obj)
446449

447450
trace(f'<SVMUtil> - cast_to({hex(adr(obj))}, {t})')
448451
if t.code != gdb.TYPE_CODE_PTR:
@@ -451,7 +454,7 @@ def cast_to(cls, obj: gdb.Value, t: gdb.Type) -> gdb.Value:
451454
trace(f'<SVMUtil> - cast_to({hex(adr(obj))}, {t}) returned')
452455
# just use the raw pointer value and cast it instead the obj
453456
# casting the obj directly results in issues with compressed oops
454-
return obj if t == obj.type else gdb.Value(obj_adr).cast(t)
457+
return obj if t == obj.type else gdb.Value(obj_oop).cast(t)
455458

456459
@classmethod
457460
def get_symbol_adr(cls, symbol: str) -> int:
@@ -1236,8 +1239,8 @@ def cast_to_rtt(obj: gdb.Value, obj_str: str) -> tuple: # tuple[gdb.Value, str]
12361239
if static_type.name == rtt.name:
12371240
return obj, obj_str
12381241
else:
1239-
obj_adr = SVMUtil.get_compressed_adr(obj) if SVMUtil.is_compressed(rtt) else adr(obj)
1240-
return obj, f"(('{rtt.name}' *)({obj_adr}))"
1242+
obj_oop = SVMUtil.get_compressed_oop(obj) if SVMUtil.is_compressed(rtt) else adr(obj)
1243+
return obj, f"(('{rtt.name}' *)({obj_oop}))"
12411244

12421245
# Define the token specifications
12431246
token_specification = [

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

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2020, 2020, Red Hat Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
@@ -167,27 +167,31 @@ public abstract class DebugInfoBase {
167167
/**
168168
* Number of bits oops are left shifted by when using compressed oops.
169169
*/
170-
private int oopCompressShift;
170+
private int compressionShift;
171+
/**
172+
* Bit mask used for tagging oops.
173+
*/
174+
private int reservedBitsMask;
171175
/**
172176
* Number of low order bits used for tagging oops.
173177
*/
174-
private int oopTagsCount;
178+
private int numReservedBits;
175179
/**
176180
* Number of bytes used to store an oop reference.
177181
*/
178-
private int oopReferenceSize;
182+
private int referenceSize;
179183
/**
180184
* Number of bytes used to store a raw pointer.
181185
*/
182186
private int pointerSize;
183187
/**
184188
* Alignment of object memory area (and, therefore, of any oop) in bytes.
185189
*/
186-
private int oopAlignment;
190+
private int objectAlignment;
187191
/**
188192
* Number of bits in oop which are guaranteed 0 by virtue of alignment.
189193
*/
190-
private int oopAlignShift;
194+
private int numAlignmentBits;
191195
/**
192196
* The compilation directory in which to look for source files as a {@link String}.
193197
*/
@@ -207,12 +211,13 @@ public abstract class DebugInfoBase {
207211
public DebugInfoBase(ByteOrder byteOrder) {
208212
this.byteOrder = byteOrder;
209213
this.useHeapBase = true;
210-
this.oopTagsCount = 0;
211-
this.oopCompressShift = 0;
212-
this.oopReferenceSize = 0;
214+
this.reservedBitsMask = 0;
215+
this.numReservedBits = 0;
216+
this.compressionShift = 0;
217+
this.referenceSize = 0;
213218
this.pointerSize = 0;
214-
this.oopAlignment = 0;
215-
this.oopAlignShift = 0;
219+
this.objectAlignment = 0;
220+
this.numAlignmentBits = 0;
216221
this.hubClassEntry = null;
217222
this.compiledCodeMax = 0;
218223
// create and index an empty dir with index 0.
@@ -245,35 +250,33 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) {
245250
/*
246251
* Save count of low order tag bits that may appear in references.
247252
*/
248-
int oopTagsMask = debugInfoProvider.oopTagsMask();
253+
reservedBitsMask = debugInfoProvider.reservedBitsMask();
249254

250-
/* Tag bits must be between 0 and 32 for us to emit as DW_OP_lit<n>. */
251-
assert oopTagsMask >= 0 && oopTagsMask < 32;
252255
/* Mask must be contiguous from bit 0. */
253-
assert ((oopTagsMask + 1) & oopTagsMask) == 0;
256+
assert ((reservedBitsMask + 1) & reservedBitsMask) == 0;
254257

255-
oopTagsCount = Integer.bitCount(oopTagsMask);
258+
numReservedBits = Integer.bitCount(reservedBitsMask);
256259

257260
/* Save amount we need to shift references by when loading from an object field. */
258-
oopCompressShift = debugInfoProvider.oopCompressShift();
261+
compressionShift = debugInfoProvider.compressionShift();
259262

260263
/* shift bit count must be either 0 or 3 */
261-
assert (oopCompressShift == 0 || oopCompressShift == 3);
264+
assert (compressionShift == 0 || compressionShift == 3);
262265

263266
/* Save number of bytes in a reference field. */
264-
oopReferenceSize = debugInfoProvider.oopReferenceSize();
267+
referenceSize = debugInfoProvider.referenceSize();
265268

266269
/* Save pointer size of current target. */
267270
pointerSize = debugInfoProvider.pointerSize();
268271

269272
/* Save alignment of a reference. */
270-
oopAlignment = debugInfoProvider.oopAlignment();
273+
objectAlignment = debugInfoProvider.objectAlignment();
271274

272275
/* Save alignment of a reference. */
273-
oopAlignShift = Integer.bitCount(oopAlignment - 1);
276+
numAlignmentBits = Integer.bitCount(objectAlignment - 1);
274277

275278
/* Reference alignment must be 8 bytes. */
276-
assert oopAlignment == 8;
279+
assert objectAlignment == 8;
277280

278281
/* retrieve limit for Java code address range */
279282
compiledCodeMax = debugInfoProvider.compiledCodeMax();
@@ -702,32 +705,32 @@ public boolean useHeapBase() {
702705
return useHeapBase;
703706
}
704707

705-
public byte oopTagsMask() {
706-
return (byte) ((1 << oopTagsCount) - 1);
708+
public int reservedBitsMask() {
709+
return reservedBitsMask;
707710
}
708711

709-
public byte oopTagsShift() {
710-
return (byte) oopTagsCount;
712+
public int numReservedBits() {
713+
return numReservedBits;
711714
}
712715

713-
public int oopCompressShift() {
714-
return oopCompressShift;
716+
public int compressionShift() {
717+
return compressionShift;
715718
}
716719

717-
public int oopReferenceSize() {
718-
return oopReferenceSize;
720+
public int referenceSize() {
721+
return referenceSize;
719722
}
720723

721724
public int pointerSize() {
722725
return pointerSize;
723726
}
724727

725-
public int oopAlignment() {
726-
return oopAlignment;
728+
public int objectAlignment() {
729+
return objectAlignment;
727730
}
728731

729-
public int oopAlignShift() {
730-
return oopAlignShift;
732+
public int numAlignmentBits() {
733+
return numAlignmentBits;
731734
}
732735

733736
public String getCachePath() {

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2020, 2020, Red Hat Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
@@ -47,17 +47,17 @@ public interface DebugInfoProvider {
4747
/**
4848
* Number of bits oops are left shifted by when using compressed oops.
4949
*/
50-
int oopCompressShift();
50+
int compressionShift();
5151

5252
/**
5353
* Mask selecting low order bits used for tagging oops.
5454
*/
55-
int oopTagsMask();
55+
int reservedBitsMask();
5656

5757
/**
5858
* Number of bytes used to store an oop reference.
5959
*/
60-
int oopReferenceSize();
60+
int referenceSize();
6161

6262
/**
6363
* Number of bytes used to store a raw pointer.
@@ -67,7 +67,7 @@ public interface DebugInfoProvider {
6767
/**
6868
* Alignment of object memory area (and, therefore, of any oop) in bytes.
6969
*/
70-
int oopAlignment();
70+
int objectAlignment();
7171

7272
int compiledCodeMax();
7373

0 commit comments

Comments
 (0)