[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] fixed one bug, found another :) (was: another tcg bug? tes
From: |
Juergen Lock |
Subject: |
[Qemu-devel] fixed one bug, found another :) (was: another tcg bug? test r, r case in tcg_out_brcond2()) |
Date: |
Sat, 5 Jul 2008 23:29:46 +0200 |
User-agent: |
Mutt/1.5.17 (2007-11-01) |
On Fri, Jul 04, 2008 at 09:32:04PM +0200, Juergen Lock wrote:
> Hi!
>[...]
> Unfortunately that patch doesnt seem to be enough i.e. /usr still fails
> to mount. Have I missed another case of this problem? The following
> if (bp->bio_offset > pp->mediasize)
> line that might also cause the mount failure gets translated like the
> follwoing, can anyone see a bug there?
>
> IN:
> 0xffffffff8044b2d5: cmp 0x48(%rdi),%r8
> 0xffffffff8044b2d9: jle 0xffffffff8044b33a
>
> OUT: [size=227]
> 0x29487ec0: mov 0x38(%ebp),%eax
> 0x29487ec3: mov 0x3c(%ebp),%edx
> 0x29487ec6: add $0x48,%eax
> 0x29487ec9: adc $0x0,%edx
> 0x29487ecc: mov %eax,%ecx
> 0x29487ece: mov %edx,%ebx
> 0x29487ed0: mov %ecx,%edx
> 0x29487ed2: mov %ecx,%eax
> 0x29487ed4: shr $0x7,%edx
> 0x29487ed7: and $0xfffff007,%eax
> 0x29487edd: and $0x1fe0,%edx
> 0x29487ee3: lea 0x460(%edx,%ebp,1),%edx
> 0x29487eea: cmp (%edx),%eax
> 0x29487eec: mov %ecx,%eax
> 0x29487eee: jne 0x29487ef5
> 0x29487ef0: cmp 0x4(%edx),%ebx
> 0x29487ef3: je 0x29487f00
> 0x29487ef5: mov %ebx,%edx
> 0x29487ef7: xor %ecx,%ecx
> 0x29487ef9: call 0x8157a18
> 0x29487efe: jmp 0x29487f0a
> 0x29487f00: add 0x18(%edx),%eax
> 0x29487f03: mov %eax,%edx
> 0x29487f05: mov (%edx),%eax
> 0x29487f07: mov 0x4(%edx),%edx
> 0x29487f0a: mov 0x40(%ebp),%ecx
> 0x29487f0d: mov 0x44(%ebp),%ebx
> 0x29487f10: mov %eax,%esi
> 0x29487f12: mov %edx,%edi
> 0x29487f14: sub %eax,%ecx
> 0x29487f16: sbb %edx,%ebx
> 0x29487f18: mov %ecx,%eax
> 0x29487f1a: mov %ebx,%edx
> 0x29487f1c: add %esi,%eax
> 0x29487f1e: adc %edi,%edx
> 0x29487f20: mov %ecx,0x98(%ebp)
> 0x29487f26: mov $0x11,%ecx
> 0x29487f2b: mov %ecx,0xa0(%ebp)
> 0x29487f31: mov %esi,0x90(%ebp)
> 0x29487f37: mov %edi,0x94(%ebp)
> 0x29487f3d: mov %ebx,0x9c(%ebp)
> 0x29487f43: cmp %edi,%edx
> 0x29487f45: jl 0x29487f7e
> 0x29487f4b: jne 0x29487f59
> 0x29487f51: cmp %esi,%eax
> 0x29487f53: jle 0x29487f7e
^^^ wrong!
> 0x29487f59: jmp 0x29487f5e
> 0x29487f5e: mov $0x8044b2db,%eax
> 0x29487f63: mov %eax,0x80(%ebp)
> 0x29487f69: mov $0xffffffff,%eax
> 0x29487f6e: mov %eax,0x84(%ebp)
> 0x29487f74: mov $0x112f1328,%eax
> 0x29487f79: jmp 0x83bd948
> 0x29487f7e: jmp 0x29487f83
> 0x29487f83: mov $0x8044b33a,%eax
> 0x29487f88: mov %eax,0x80(%ebp)
> 0x29487f8e: mov $0xffffffff,%eax
> 0x29487f93: mov %eax,0x84(%ebp)
> 0x29487f99: mov $0x112f1329,%eax
> 0x29487f9e: jmp 0x83bd948
OK so I was confused, the real problem was the use of signed conditions for
the lower half, they need to be unsigned... But some of the `test r,r'
special handling in my original patch is still useful as an optimization,
so here is the updated patch that now at least lets the mentioned guest mount
its /usr and finish booting:
Index: qemu/tcg/i386/tcg-target.c
@@ -359,25 +359,36 @@
break;
case TCG_COND_LT:
tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3],
args[5]);
+ if (const_args[2] && !args[2])
+ /* test r,r - carry can never be set */
+ break;
tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_LT, args[0], args[2], const_args[2],
args[5]);
+ tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2],
args[5]);
break;
case TCG_COND_LE:
tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3],
args[5]);
tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_LE, args[0], args[2], const_args[2],
args[5]);
+ tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2],
args[5]);
break;
case TCG_COND_GT:
tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3],
args[5]);
tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_GT, args[0], args[2], const_args[2],
args[5]);
+ tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2],
args[5]);
break;
case TCG_COND_GE:
+ if (const_args[2] && !args[2]) {
+ /* test r,r - carry can never be set */
+ tcg_out_brcond(s, TCG_COND_GE, args[1], args[3], const_args[3],
args[5]);
+ break;
+ }
tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3],
args[5]);
tcg_out_jxx(s, JCC_JNE, label_next);
- tcg_out_brcond(s, TCG_COND_GE, args[0], args[2], const_args[2],
args[5]);
+ tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2],
args[5]);
break;
case TCG_COND_LTU:
+ if (const_args[2] && !args[2])
+ /* test r,r - carry can never be set */
+ break;
tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3],
args[5]);
tcg_out_jxx(s, JCC_JNE, label_next);
tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2],
args[5]);
@@ -393,6 +404,11 @@
tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2],
args[5]);
break;
case TCG_COND_GEU:
+ if (const_args[2] && !args[2]) {
+ /* test r,r - carry can never be set */
+ tcg_out_jxx(s, JCC_JMP, args[5]);
+ break;
+ }
tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3],
args[5]);
tcg_out_jxx(s, JCC_JNE, label_next);
tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2],
args[5]);
(if you don't want the optimizations for sake of code clarity just remove
the `if (const_args[2] && !args[2])' clauses.)
Ok while writing this I was waiting for a Linux/amd64 guest to boot, which
still failed, and the reason seems to be that either floats or conversion
of floats to integers are also broken for amd64 guests on i386 hosts,
as can be seen by:
(gdb) p 1.
$1 = -nan(0x8000000000000)
The quickest way to reproduce this is probably a FreeBSD/amd64 livefs iso:
ftp://ftp.freebsd.org/pub/FreeBSD/ISO-IMAGES-amd64/7.0/7.0-RELEASE-amd64-livefs.iso
start as:
qemu-system-x86_64 -cdrom 7.0-RELEASE-amd64-livefs.iso
select fixit -> cdrom in the menu after the keymap configuration, then
you can invoke gdb.
Thanx,
Juergen