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

Reply via email to