Skip to content

Commit d42a173

Browse files
committed
purego: fix ARM64 struct register corruption on alignment flush
Fix a critical bug in ARM64 struct argument packing where the register value (val) and class were not being reset after flushing due to alignment requirements. When packing struct fields into registers, if a field's alignment causes shift >= 64, the current register is flushed. However, the code was not resetting 'val' and 'class' after the flush, causing subsequent fields to be ORed with stale data from previous fields. Example bug with FourInt32s{1, 2, 3, 4}: - Fields 0,1 packed: val = 0x0000000200000001 - Flush at field 2 due to shift >= 64 - BUG: val still contains 0x0000000200000001 - Field 2 packs: val |= 3 becomes 0x0000000200000003 (should be 0x03) - Field 3 packs: val |= (4<<32) becomes 0x0000000400000003 - Result: field 3 = 6 instead of 4 (bit 1 from field 1 leaked) This fix ensures val and class are properly reset after each flush, preventing data corruption between register boundaries. Fixes the FourInt32s test case that was failing with f3=6 instead of f3=4.
1 parent 198e2b1 commit d42a173

File tree

1 file changed

+2
-0
lines changed

1 file changed

+2
-0
lines changed

struct_arm64.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ func placeRegisters(v reflect.Value, addFloat func(uintptr), addInt func(uintptr
117117
} else {
118118
addInt(uintptr(val))
119119
}
120+
val = 0
121+
class = _NO_CLASS
120122
}
121123
switch f.Type().Kind() {
122124
case reflect.Struct:

0 commit comments

Comments
 (0)