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. There are some trivial differences in the output,
mostly because the x86_32 ELF format doesn't allow 8-bit relocations 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

Attachment: smime.p7s
Description: S/MIME cryptographic signature

------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&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