David:
  I have some comments. 
1. This patch just cleans up hard coded offset. So, it should still be compiled 
to the same binary instruction to original one. Have you compared the binary 
instruction? If the binary is different, how to make sure its functionality is 
same?
2. I see Andrew mentions llvm doesn't support 16-bit mode. So, this change will 
cause llvm/clang/Xcode build failure. Right?
3. I see your another change to simplify the code. What's the benefit of this 
change? 
4. For MdePkg\Library\BaseLib\X64\Thunk16.S, have you found the similar issue? 

Thanks
Liming
-----Original Message-----
From: David Woodhouse [mailto:dw...@infradead.org] 
Sent: Saturday, November 30, 2013 12:14 AM
To: edk2-devel@lists.sourceforge.net
Cc: Gao, Liming
Subject: [PATCH] Clean up hard-coded offsets and other utter bogosity in 
Thunk16.S.

Again.

Properly this time.

In r12889 we attempted to clean this up, but we missed a vital part of
it, so it was reverted in r12898.

What we missed was the fact that much of this is 16-bit code, and the
assembler didn't *know* that — it thought it was compiling 32-bit code
and we had even gone out of our way to entertain that fiction, for
example writing:
    mov     %edx, %cs:0xffffffc5(%esi)
when we really meant:
    mov     %dx, %cs:(SavedSs - L_Base)(%bp)

Note that even the *registers* are different here. The address really is
based on %bp, not %esi. We only said %esi to trick the assembler.

If we're lying to the assembler about the context and it doesn't even
know whether operands are 32-bit or 16-bit, how on earth did we expect
it to calculate offsets correctly for us? Of *course* it went wrong!

So this brings back the fixes from r12889, and also fixes up the 16-bit
code to be sane again. Doing a direct comparison of the output I see
some minor changes, mostly because the compiler can't output 8-bit
relocations in x86_32 ELF, so even if an offset does fit in 8 bits, the
assembler will use a 16-bit offset instead. So we get minor differences
in the output such as:

-  ab:  8d 46 0c                lea    0xc(%bp),%ax
+  ab:  8d 86 0d 00             lea    0xd(%bp),%ax

but those really are harmless — at least they are now that we aren't
hard-coding addresses and breaking because code moves around by a single
byte!

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Woodhouse <david.woodho...@intel.com>
---
 MdePkg/Library/BaseLib/Ia32/Thunk16.S | 121 ++++++++++++++++++++--------------
 1 file changed, 71 insertions(+), 50 deletions(-)

diff --git a/MdePkg/Library/BaseLib/Ia32/Thunk16.S 
b/MdePkg/Library/BaseLib/Ia32/Thunk16.S
index 8356c5a..331ea16 100644
--- a/MdePkg/Library/BaseLib/Ia32/Thunk16.S
+++ b/MdePkg/Library/BaseLib/Ia32/Thunk16.S
@@ -24,6 +24,28 @@
 ASM_GLOBAL ASM_PFX(m16Start), ASM_PFX(m16Size), ASM_PFX(mThunk16Attr), 
ASM_PFX(m16Gdt), ASM_PFX(m16GdtrBase), ASM_PFX(mTransition)
 ASM_GLOBAL ASM_PFX(InternalAsmThunk16)
 
+# define the structure of IA32_REGS
+.set  _EDI, 0       #size 4
+.set  _ESI, 4       #size 4
+.set  _EBP, 8       #size 4
+.set  _ESP, 12      #size 4
+.set  _EBX, 16      #size 4
+.set  _EDX, 20      #size 4
+.set  _ECX, 24      #size 4
+.set  _EAX, 28      #size 4
+.set  _DS,  32      #size 2
+.set  _ES,  34      #size 2
+.set  _FS,  36      #size 2
+.set  _GS,  38      #size 2
+.set  _EFLAGS, 40   #size 4
+.set  _EIP, 44      #size 4
+.set  _CS, 48       #size 2
+.set  _SS, 50       #size 2
+.set  IA32_REGS_SIZE, 52
+
+    .text
+    .code16
+
 ASM_PFX(m16Start):
 
 SavedGdt:     .space  6
@@ -31,21 +53,22 @@ SavedGdt:     .space  6
 ASM_PFX(BackFromUserCode):
     push    %ss
     push    %cs
-    .byte   0x66
-    call    L_Base1                     # push eip
+
+    calll   L_Base1                     # push eip
 L_Base1:
-    pushfw                              # pushfd actually
+    pushfl
     cli                                 # disable interrupts
     push    %gs
     push    %fs
     push    %es
     push    %ds
-    pushaw                              # pushad actually
+    pushal
     .byte   0x66, 0xba                  # mov edx, imm32
 ASM_PFX(ThunkAttr): .space  4
     testb   $THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15, %dl
     jz      1f
-    movl    $0x15cd2401, %eax           # mov ax, 2401h & int 15h
+    movw    $0x2401, %ax
+    int     $0x15
     cli                                 # disable interrupts
     jnc     2f
 1:
@@ -55,27 +78,26 @@ ASM_PFX(ThunkAttr): .space  4
     orb     $2, %al
     outb    %al, $0x92                  # deactivate A20M#
 2:
-    xorw    %ax, %ax                    # xor eax, eax
-    movl    %ss, %eax                   # mov ax, ss
-    .byte   0x67, 0x66, 0x8d, 0x6c, 0x24, 0x34, 0x66
-    mov     %ebp, 0xffffffd8(%esi)
-    mov     0xfffffff8(%esi), %ebx
-    shlw    $4, %ax                     # shl eax, 4
-    addw    %ax, %bp                    # add ebp, eax
-    .byte   0x66, 0xb8                   # mov eax, imm32
+    xorl    %eax, %eax
+    movw    %ss, %ax
+    leal    IA32_REGS_SIZE(%esp), %ebp
+    mov     %ebp, (_ESP - IA32_REGS_SIZE)(%bp)
+    mov     (_EIP - IA32_REGS_SIZE)(%bp), %bx
+    shll    $4, %eax
+    addl    %eax, %ebp
+    .byte   0x66, 0xb8                  # mov eax, imm32
 SavedCr4:   .space  4
     movl    %eax, %cr4
-    lgdtw   %cs:0xfffffff2(%edi)
-    .byte   0x66, 0xb8                   # mov eax, imm32
+    lgdtl   %cs:(SavedGdt - L_Base1)(%bx)
+    .byte   0x66, 0xb8                  # mov eax, imm32
 SavedCr0:   .space  4
     movl    %eax, %cr0
     .byte   0xb8                        # mov ax, imm16
 SavedSs:    .space  2
     movl    %eax, %ss
-    .byte   0x66, 0xbc                   # mov esp, imm32
+    .byte   0x66, 0xbc                  # mov esp, imm32
 SavedEsp:   .space  4
-    .byte   0x66
-    lret                                # return to protected mode
+    lretl                               # return to protected mode
 
 _EntryPoint:    .long      ASM_PFX(ToUserCode) - ASM_PFX(m16Start)
                 .word      0x8
@@ -85,37 +107,35 @@ _16Gdtr:        .word      GdtEnd - _NullSegDesc - 1
 _16GdtrBase:    .long      _NullSegDesc
 
 ASM_PFX(ToUserCode):
-    movl    %ss, %edx
-    movl    %ecx, %ss                   # set new segment selectors
-    movl    %ecx, %ds
-    movl    %ecx, %es
-    movl    %ecx, %fs
-    movl    %ecx, %gs
+    movw    %ss, %dx
+    movw    %cx, %ss                    # set new segment selectors
+    movw    %cx, %ds
+    movw    %cx, %es
+    movw    %cx, %fs
+    movw    %cx, %gs
     movl    %eax, %cr0
     movl    %ebp, %cr4                  # real mode starts at next instruction
-    movl    %esi, %ss                   # set up 16-bit stack segment
-    xchgw   %bx, %sp                    # set up 16-bit stack pointer
-    .byte   0x66
-    call    L_Base                      # push eip
+    movw    %si, %ss                    # set up 16-bit stack segment
+    xchgl   %ebx, %esp                  # set up 16-bit stack pointer
+    calll   L_Base                      # push eip
 L_Base:
-    popw    %bp                         # ebp <- offset L_Base
-    .byte   0x67;                       # address size override
-    push    54(%esp)
-    lea     0xc(%esi), %eax
-    push    %eax
+    popl    %ebp                        # ebp <- offset L_Base
+    push    (IA32_REGS_SIZE + 2)(%esp)
+    lea (L_RealMode - L_Base)(%bp), %ax
+    push    %ax
     lret
 
 L_RealMode:
-    mov     %edx, %cs:0xffffffc5(%esi)
-    mov     %bx, %cs:0xffffffcb(%esi)
-    lidtw   %cs:0xffffffd7(%esi)
-    popaw                               # popad actually
+    mov     %dx, %cs:(SavedSs - L_Base)(%bp)
+    mov     %ebx, %cs:(SavedEsp - L_Base)(%bp)
+    lidtl   %cs:(_16Idtr - L_Base)(%bp)
+    popal
     pop     %ds
     pop     %es
     pop     %fs
     pop     %gs
-    popfw                               # popfd
-    lretw                               # transfer control to user code
+    popfl
+    lretl                               # transfer control to user code
 
 _NullSegDesc:   .quad   0
 _16CsDesc:
@@ -134,6 +154,7 @@ _16DsDesc:
                 .byte   0
 GdtEnd:
 
+    .code32
 #
 #   @param  RegSet  The pointer to a IA32_DWORD_REGS structure
 #   @param  Transition  The pointer to the transition code
@@ -149,41 +170,41 @@ ASM_PFX(InternalAsmThunk16):
     push    %fs
     push    %gs
     movl    36(%esp), %esi              # esi <- RegSet
-    movzwl  0x32(%esi), %edx
-    mov     0xc(%esi), %edi
-    add     $0xffffffc8, %edi
+    movzwl  _SS(%esi), %edx
+    mov     _ESP(%esi), %edi
+    add     $(-(IA32_REGS_SIZE + 4)), %edi
     movl    %edi, %ebx                  # ebx <- stack offset
     imul    $0x10, %edx, %eax
-    push    $0xd
+    push    $(IA32_REGS_SIZE / 4)
     addl    %eax, %edi                  # edi <- linear address of 16-bit stack
     pop     %ecx
     rep
     movsl                               # copy RegSet
     movl    40(%esp), %eax              # eax <- address of transition code
     movl    %edx, %esi                  # esi <- 16-bit stack segment
-    lea     0x61(%eax), %edx
+    lea     (SavedCr0 - ASM_PFX(m16Start))(%eax), %edx
     movl    %eax, %ecx
     andl    $0xf, %ecx
     shll    $12, %eax
-    lea     0x6(%ecx), %ecx
+    lea     (ASM_PFX(BackFromUserCode) - ASM_PFX(m16Start))(%ecx), %ecx
     movw    %cx, %ax
     stosl                               # [edi] <- return address of user code
-    sgdtl   0xffffff9f(%edx)
+    sgdtl   (SavedGdt - SavedCr0)(%edx)
     sidtl   0x24(%esp)
     movl    %cr0, %eax
     movl    %eax, (%edx)                # save CR0 in SavedCr0
     andl    $0x7ffffffe, %eax           # clear PE, PG bits
     movl    %cr4, %ebp
-    mov     %ebp, 0xfffffff1(%edx)
+    mov     %ebp, (SavedCr4 - SavedCr0)(%edx)
     andl    $0xffffffcf, %ebp           # clear PAE, PSE bits
     pushl   $0x10
     pop     %ecx                        # ecx <- selector for data segments
-    lgdtl   0x20(%edx)
+    lgdtl   (_16Gdtr - SavedCr0)(%edx)
     pushfl
-    lcall   *0x14(%edx)
+    lcall   *(_EntryPoint - SavedCr0)(%edx)
     popfl
     lidtl   0x24(%esp)
-    lea     0xffffffcc(%ebp), %eax
+    lea     -IA32_REGS_SIZE(%ebp), %eax
     pop     %gs
     pop     %fs
     pop     %es
-- 
1.8.3.1


-- 
David Woodhouse                            Open Source Technology Centre
david.woodho...@intel.com                              Intel Corporation
------------------------------------------------------------------------------
Sponsored by Intel(R) XDK 
Develop, test and display web and hybrid apps with a single code base.
Download it for free now!
http://pubads.g.doubleclick.net/gampad/clk?id=111408631&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to