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