Patchwork call insn not truncated on x86_64

login
register
mail settings
Submitter Aurelien Jarno
Date Jan. 2, 2010, 8:35 p.m.
Message ID <20100102203538.GB5837@hall.aurel32.net>
Download mbox | patch
Permalink /patch/42024/
State New
Headers show

Comments

Aurelien Jarno - Jan. 2, 2010, 8:35 p.m.
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?
Kevin O'Connor - Jan. 2, 2010, 10:28 p.m.
On Sat, Jan 02, 2010 at 09:35:38PM +0100, Aurelien Jarno wrote:
> 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 problem has been fixed in 32938e127f50a40844a0fb9c5abb8691aeeccf7e
> for jmp imm. I guess the same patch applies for call. Could you confirm?

Your patch fixes the problem.

Thanks,
-Kevin

Patch

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);