Mike:
  Your issue is that X64 version doesn't work on machine with UG feature. You 
find it can work when "call  dword .Base" is used instead of "o32 call    dword 
.Base". So, your question is why o32 prefix used. Right? 

Thanks
Liming
-----Original Message-----
From: Mike Maslenkin [mailto:miha...@parallels.com] 
Sent: Friday, August 29, 2014 1:33 AM
To: edk2-devel@lists.sourceforge.net
Subject: Re: [edk2] [PATCH 0/8] NASM: Object files; Thunk16; Require for 
non-MSVC


> 
> On Wed, Aug 27, 2014 at 5:18 AM, Sergey Isakov <isakov...@bk.ru> wrote:
> > Hi sirs,
> > I tested Thunk16.nasm too. For x86_64 there is no issue.
> > For ia32 compilation disasm shows not good codes
> > ---------
> > 00000000 <m16Start>:
> >    0: 00 00                 add    %al,(%eax)
> >    2: 00 00                 add    %al,(%eax)
> > ...
> >
> > 00000006 <_BackFromUserCode>:
> >    6: 16                   push   %ss
> >    7: 0e                   push   %cs
> >    8: 67 e8 00 00 66 9c     addr16 call 9c66000e
> > <InternalAsmThunk16+0x9c65ff36>
> >
> > 0000000c <_BackFromUserCode.Base>:
> >    c: 66 9c                 pushfw
> >    e: fa                   cli
> >
> > ---------
> > to compare gcc-4.9.1 cvompilation
> > ---------
> > 00000000 <m16Start>:
> >    0: 00 00                 add    %al,(%eax)
> >    2: 00 00                 add    %al,(%eax)
> > ...
> >
> > 00000006 <BackFromUserCode>:
> >    6: 16                   push   %ss
> >    7: 0e                   push   %cs
> >    8: 66 e8 00 00           callw  c <BackFromUserCode+0x6>
> > ...
> >
> > 0000000e <L_Base1>:
> >    e: 66 9c                 pushfw
> >   10: fa                   cli
> >
> > ----------
> > May be change a32 prefix to o32 in the line:
> > "a32 call    .Base                       ; push eip"
> > ?
> 
> In the X64 file, I used:
> call    dword .Base
> 
> I notice this produced the same code as:
> o32 call    dword .Base
> 
> But,
> o32 call    .Base
> seems to produce invalid code. (OVMF hangs.)
> 
> It does seem like:
> a32 call    .Base
> is functional as well, but I know we are attempting to make the new 
> nasm code produce similar code to the old asm code where reasonable.
> 
> I think I only changed it in the X64 file to try to match the old 'db' code.
This is a good point and new code matches to GAS mostly.
But in my case there were different offsets.
I can confirm now that a32 works but it's just because of additional
0x67 prefix used,
that adds one byte to offset.

Here is my story for this patchset begins.
For me this patchset works fine on IA32 and doesn't work for X64.
As a platform I used Parallels Virtual Machine and as build system GCC47
+NASM 2.09.08

original X64 version caused triple fault on
InternalAsmThunk16: mov ss, edx.

This is because of invalid LGDT loaded.
Meanwhile X64 version worked on machine without unrestricted guest feature.
Such situations workarounded by our emulation, but notification warning was 
produces.
So, this doesn't work for me on machine with UG feature and worked fine without.

After that I added log from AsmPrepareThunk16 printed all exported
values:
m16Start, mThunk16Attr, m16Gdt, m16GdtrBase, mTransition

And I saw that that values differed from GAS implementation.
And RealModeGdt was broken as well.

As a result I think there is a problem with how NASM processes prefixes and 
labels.
Here is tree different objects:
1. Original version
BITS    16
    push    ss
    push    cs
o32 call    dword .Base                 ; push eip
.Base:
    push    dword 0                     ; reserved high order 32 bits of
EFlags
    pushfd
    cli                                 ; disable interrupts
    push    gs

Disassembly of section .text:

0000000000000000 <m16Start>:
   0:   00 00                   add    %al,(%bx,%si)
   2:   00 00                   add    %al,(%bx,%si)
   4:   00 00                   add    %al,(%bx,%si)
   6:   00 00                   add    %al,(%bx,%si)
   8:   00 00                   add    %al,(%bx,%si)

000000000000000a <_BackFromUserCode>:
   a:   16                      push   %ss
   b:   0e                      push   %cs
   c:   66 e8 00 00 00 00       calll  12 <_BackFromUserCode+0x8>
  12:   66 6a 00                pushl  $0x0

0000000000000013 <_BackFromUserCode.Base>:
  13:   6a 00                   push   $0x0
  15:   66 9c                   pushfl 
  17:   fa                      cli    
  18:   0f a8                   push   %gs

2: with a32 prefix:
BITS    16
    push    ss
    push    cs
a32 call    dword .Base                 ; push eip
.Base:
    push    dword 0                     ; reserved high order 32 bits of
EFlags
    pushfd
    cli                                 ; disable interrupts
    push    gs
  
Disassembly of section .text:

0000000000000000 <m16Start>:
   0:   00 00                   add    %al,(%bx,%si)
   2:   00 00                   add    %al,(%bx,%si)
   4:   00 00                   add    %al,(%bx,%si)
   6:   00 00                   add    %al,(%bx,%si)
   8:   00 00                   add    %al,(%bx,%si)

000000000000000a <_BackFromUserCode>:
   a:   16                      push   %ss
   b:   0e                      push   %cs
   c:   67 66 e8 00 00 00 00    addr32 calll 13 <_BackFromUserCode.Base>

0000000000000013 <_BackFromUserCode.Base>:
  13:   66 6a 00                pushl  $0x0
  16:   66 9c                   pushfl 
  18:   fa                      cli    
  19:   0f a8                   push   %gs

3. Without any prefixes:
BITS    16
    push    ss
    push    cs
    call    dword .Base                 ; push eip
.Base:
    push    dword 0                     ; reserved high order 32 bits of
EFlags
    pushfd
    cli                                 ; disable interrupts
    push    gs


Disassembly of section .text:

0000000000000000 <m16Start>:
   0:   00 00                   add    %al,(%bx,%si)
   2:   00 00                   add    %al,(%bx,%si)
   4:   00 00                   add    %al,(%bx,%si)
   6:   00 00                   add    %al,(%bx,%si)
   8:   00 00                   add    %al,(%bx,%si)

000000000000000a <_BackFromUserCode>:
   a:   16                      push   %ss
   b:   0e                      push   %cs
   c:   66 e8 00 00 00 00       calll  12 <_BackFromUserCode.Base>

0000000000000012 <_BackFromUserCode.Base>:
  12:   66 6a 00                pushl  $0x0
  15:   66 9c                   pushfl 
  17:   fa                      cli    
  18:   0f a8                   push   %gs


As objdump shows _BackFromUserCode.Base offset differs...
And it is very strange in original case because it points to the ending of 
instruction bytes. Look, it's offset 13.

And looks like that NASM inserts opcodes 0x66, 0x67 after it used symbol offset 
anywhere.
instructions:
    lea     eax, [eax + ebx + (.X64JmpEnd - .Base)]
    mov     [cs:bx + (.X64JmpEnd - 6 - .Base)], eax

are pretty same for all of the tree cases:
  5f:   67 66 8d 84 18 89 00    lea    0x89(%eax,%eax,1),%eax
  66:   00 00 
  68:   2e 66 89 87 83 00       mov    %eax,%cs:0x83(%bx)

But for case 2 (a32 prefix used) there is another offset
  60:   67 66 8d 84 18 89 00    lea    0x89(%eax,%eax,1),%eax
  67:   00 00 
  69:   2e 66 89 87 83 00       mov    %eax,%cs:0x83(%bx)

Jordan, could you check this issue too? Might be I missed something.
So here is a question, why o32 prefix used? 
o32 call    dword .Base                 ; push eip

I got working version without this prefix.
Unfortunately currently I can not check how many bytes of EIP pushed onto stack 
in all cases. I believe there is same instruction, because of 16RM code + 0x66 
prefix :)

Thank you. NASM version looks very simple and clever, but could you add a some 
comments to magic values used for proper offset
calculation:
ASM_PFX(mThunk16Attr)    DW      _BackFromUserCode.ThunkAttrEnd - 4 -
m16Start
mov     [cs:bx + (.X64JmpEnd - 6 - .Base)], eax
push    word [dword esp + IA32_REGS.size + 2]
mov     [rcx + (_BackFromUserCode.SavedCr0End - 4 -
_BackFromUserCode.SavedCr4End)], eax
mov     [rcx + (_BackFromUserCode.X64JmpEnd - 2 -
_BackFromUserCode.SavedCr4End)], r8w
mov     [rcx + (_BackFromUserCode.SavedSpEnd - 8 -
_BackFromUserCode.SavedCr4End)], rsp

It takes a time to get what actually these mean.


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to