[Bug gdb/34416] New: Incorrect loss of sign in 64-bit multiply (e.g.: DW_OP_mul in DWARF evaluation)
wmessmer at microsoft dot com via Gdb-prs <[email protected]>
| Newsgroups | gmane.comp.gdb.bugs.discuss |
|---|---|
| Message-ID | <[email protected]/bugzilla/> |
https://sourceware.org/bugzilla/show_bug.cgi?id=34416
Bug ID: 34416
Summary: Incorrect loss of sign in 64-bit multiply (e.g.:
DW_OP_mul in DWARF evaluation)
Product: gdb
Version: HEAD
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: gdb
Assignee: unassigned at sourceware dot org
Reporter: wmessmer at microsoft dot com
Target Milestone: ---
Created attachment 16853
--> https://sourceware.org/bugzilla/attachment.cgi?id=16853&action=edit
Zip of repro binary / core dump / test source
I was debugging some copilot generated test code intended utilize/fill APX
registers on the HEAD of GDB (with the APX support patch set) to compare
against WinDbg's handling of APX on Linux. In any case, GDB and WinDbg were
showing different values for some of the local variables in the test.
Unfortunately, copilot had generated code where the test core dump was
collected after the APX registers were reused and all of the variables ended up
as long DWARF expressions.
In tracking this down via observation & copilot, it would appear that GDB is
mishandling DW_OP_mul with signed values where the result of the multiplication
spills over 64-bits.
You can see this in the EE of GDB directly:
(gdb) print (long long)0x2000000000000001 * (long long)-8
$1 = 8
For the more problematic version (the variable), please see the attached
binary/source/core dump:
(gdb) break apx_leaf
Breakpoint 1 at 0x1060: file main.cpp, line 81.
(gdb) run
Starting program: /home/wmessmer/test/APX_WSL/apx_test
Breakpoint 1, apx_leaf (a=a@entry=15529827852863206509,
b=b@entry=17326333736759811083, c=c@entry=9017087056300321936,
d=d@entry=9975881037687807339) at main.cpp:81
81 uint64_t v00 = mix64(a, 0x716F6F7200000000ULL);
(gdb) disassem apx_leaf
Dump of assembler code for function apx_leaf(uint64_t, uint64_t, uint64_t,
uint64_t):
...
0x0000555555555571 <+1297>: mov %rax,%r22
0x0000555555555575 <+1301>: ror $0x13,%r22
0x000055555555557a <+1306>: xor %r22,%r21
0x000055555555557e <+1310>: add %r21,%rdx
...
(gdb) break *0x000055555555557a
Breakpoint 2 at 0x55555555557a: file main.cpp, line 118.
(gdb) cont
Continuing.
Breakpoint 2, 0x000055555555557a in apx_leaf (a=a@entry=15529827852863206509,
b=b@entry=17326333736759811083,
c=c@entry=9017087056300321936, d=d@entry=9975881037687807339) at
main.cpp:118
118 uint64_t w07 = rotr64(tag, 19) ^ v07;
(gdb) print v07
$1 = 16568925713597422312
(gdb) set output-radix 16
Output radix now set to decimal 16, hex 10, octal 20.
(gdb) print v07
$2 = 0xe5f0a6268ccf5ae8
(gdb) info address v07
Symbol "v07" is multi-location:
Base address 0x1284 Range 0x555555555284-0x55555555557e: a variable in $
Range 0x55555555557e-0x55555555563d: a complex DWARF expression:
0: DW_OP_entry_value
2: DW_OP_reg4 [$rsi]
3: DW_OP_plus_uconst 8173874384117694471
13: DW_OP_entry_value
15: DW_OP_reg4 [$rsi]
16: DW_OP_plus_uconst 8173874384117694471
26: DW_OP_lit17
27: DW_OP_shr
28: DW_OP_xor
29: DW_OP_consts -49064778989728563
39: DW_OP_mul
40: DW_OP_entry_value
42: DW_OP_reg4 [$rsi]
43: DW_OP_plus_uconst 8173874384117694471
53: DW_OP_entry_value
55: DW_OP_reg4 [$rsi]
56: DW_OP_plus_uconst 8173874384117694471
66: DW_OP_lit17
67: DW_OP_shr
68: DW_OP_xor
69: DW_OP_consts -49064778989728563
79: DW_OP_mul
80: DW_OP_lit31
81: DW_OP_shr
82: DW_OP_xor
83: DW_OP_consts -4265267296055464877
93: DW_OP_mul
94: DW_OP_entry_value
96: DW_OP_reg4 [$rsi]
97: DW_OP_plus_uconst 8173874384117694471
107: DW_OP_entry_value
109: DW_OP_reg4 [$rsi]
110: DW_OP_plus_uconst 8173874384117694471
120: DW_OP_lit17
121: DW_OP_shr
122: DW_OP_xor
123: DW_OP_consts -49064778989728563
133: DW_OP_mul
134: DW_OP_entry_value
136: DW_OP_reg4 [$rsi]
137: DW_OP_plus_uconst 8173874384117694471
147: DW_OP_entry_value
149: DW_OP_reg4 [$rsi]
150: DW_OP_plus_uconst 8173874384117694471
160: DW_OP_lit17
161: DW_OP_shr
162: DW_OP_xor
163: DW_OP_consts -49064778989728563
173: DW_OP_mul
174: DW_OP_lit31
175: DW_OP_shr
176: DW_OP_xor
177: DW_OP_consts -4265267296055464877
187: DW_OP_mul
188: DW_OP_const1u 32
190: DW_OP_shr
191: DW_OP_xor
192: DW_OP_stack_value
.
(gdb) ni
0x000055555555557e 137 w05 + w06 + w07
+ w08 + w09 +
(gdb) print v07
$3 = 0x3cf688b6bf336197
At the point where the two loclist locations for v07 diverge (from a simple r21
to a way more complex DWARF expression), you'll note that GDB is printing two
very different values for v07's value:
0xe5f0a6268ccf5ae8 (in r21)
0x3cf688b6bf336197 (the result of DWARF evaluation)
The value hasn't changed.... if you look at the operations in the complex
DWARF expression GCC emitted here, you'll note that the same problem as that
print is occuring. The signed DW_OP_mul is ending up as a * |b| and not (a *
b) because of this.
The attached ZIP should contain source / binary / core dump for the copilot
generated test which was erroneous for what I wanted but repro'd this
particular problem. The variable DIE in question is 0x11ac in apx_test.
--
You are receiving this mail because:
You are on the CC list for the bug.