From patchwork Sat Jan 2 20:35:38 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: call insn not truncated on x86_64 Date: Sat, 02 Jan 2010 10:35:38 -0000 From: Aurelien Jarno X-Patchwork-Id: 42024 Message-Id: <20100102203538.GB5837@hall.aurel32.net> To: Kevin O'Connor Cc: qemu-devel@nongnu.org On Sat, Jan 02, 2010 at 01:26:54PM -0500, Kevin O'Connor wrote: > I'm running into an issue with SeaBIOS compiled with older versions of > gcc. I'm seeing: > > $ qemu-system-x86_64 -d in_asm,int,exec,cpu,pcall > > IN: > 0x00000000000f1096: mov %ebx,%eax > 0x00000000000f1098: call 0xffff0f80 > > qemu: fatal: Trying to execute code outside RAM or ROM at 0xffffffffffff0f80 > > > The emulator dies at this point. This code sequence is used to jump > into the copy of SeaBIOS at the permanent rom location (at > 0xfffe0000-0xffffffff) so it can safely enable ram in the > 0xe0000-0x100000 memory area. The call insn looks okay to me: > > f1098: e8 e3 fe ef ff calll ffff0f80 > > So, I'm not sure why qemu dies. This is what I see on the i386 > version of qemu: > > $ qemu -d in_asm,int,exec,cpu,pcall > > IN: > 0x000f1096: mov %ebx,%eax > 0x000f1098: call 0xffff0f80 > > IN: > 0xffff0f80: push %ebp > 0xffff0f81: push %edi > [...] > > > Newer versions of gcc emit code a little different and thus don't run > into the issue - I see: > > $ qemu-system-x86_64 -d in_asm,int,exec,cpu,pcall > > IN: > 0x00000000000f365e: mov %ecx,%eax > 0x00000000000f3660: mov $0xfffeddea,%edx > 0x00000000000f3665: call *%edx > > IN: > 0x00000000fffeddea: push %ebp > 0x00000000fffeddeb: push %edi > [...] > > > and: > > $ qemu -d in_asm,int,exec,cpu,pcall > > IN: > 0x000f365e: mov %ecx,%eax > 0x000f3660: mov $0xfffeddea,%edx > 0x000f3665: call *%edx > > IN: > 0xfffeddea: push %ebp > 0xfffeddeb: push %edi > [...] > > > As a guess, qemu is not truncating the instruction pointer to 32bits > in the 64bit emulator. In all of the above cases, the machine was in > 32bit mode and running 32bit only code. > The problem has been fixed in 32938e127f50a40844a0fb9c5abb8691aeeccf7e for jmp imm. I guess the same patch applies for call. Could you confirm? diff --git a/pc-bios/openbios-sparc64 b/pc-bios/openbios-sparc64 index 0e91cab..ec47b5f 100644 Binary files a/pc-bios/openbios-sparc64 and b/pc-bios/openbios-sparc64 differ diff --git a/target-i386/translate.c b/target-i386/translate.c index 64bc0a3..511a4ea 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -6259,6 +6259,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) tval += next_eip; if (s->dflag == 0) tval &= 0xffff; + else if(!CODE64(s)) + tval &= 0xffffffff; gen_movtl_T0_im(next_eip); gen_push_T0(s); gen_jmp(s, tval);