> On Oct 31, 2014, at 2:36 PM, Jordan Justen <[email protected]> wrote:
>
> On Fri, Oct 31, 2014 at 1:18 PM, Andrew Fish <[email protected]> wrote:
>>
>>> On Oct 31, 2014, at 12:38 PM, Jordan Justen <[email protected]> wrote:
>>>
>>> Andrew,
>>>
>>> Back in February 2011, you added this assembly file to (apparently)
>>> work around a gdb bug. Do you think it is still required? (Did the bug
>>> get fixed?)
>>>
>>
>> It is not a bug. It is how the stack unwind logic works in gdb/lldb. For
>> clang the default is to emit frame pointers, so this means you can always
>> walk the stack frame. So for example an exception handler lib can print the
>> stack trace for the exception.
>>
>
> I see. Sort of.
>
The stack walking code looks for the frame pointer and the return address
stored on the stack. A return address of zero means stop the walk.
>>> It seems like we ought to be able to use C here, and, in my opinion,
>>> less assembly is generally better than more. :)
>>>
>>
>> It is probably possible to adjust the stack frame in the C code to be
>> compatible.
>
> I guess what confuses me is that C functions generally work, so what
> was it about this C routine that messes things up? (Yeah, I know. I
> guess it is not surprising that there is a snag when switching
> stacks... :)
>
The stack just needs to be in the correct state.
> So, if I change to the C code, then I'd probably see backtrace issues
> with gdb in EmulatorPkg? Do you think this is CLANG specific, or
> should GCC also show the issue?
>
It will show up in any IA32/X64 compiler that emits a frame pointer. The
caller pushes the return address and the callee saves the frame pointer next to
it.
pushl %ebp
movl %esp, %ebp
…
popl %ebp
retl
> Do you have ideas for tweaking the C code to fix it there?
>
It may be as simple as simulating the push of zero on the stack that is handed
into LongJump. I’ll try to find some time to take a look.
Thanks,
Andrew Fish
> Thanks,
>
> -Jordan
>
>>> On Mon, Jul 11, 2011 at 8:01 PM, <[email protected]> wrote:
>>>> Revision: 12007
>>>> http://edk2.svn.sourceforge.net/edk2/?rev=12007&view=rev
>>>> Author: andrewfish
>>>> Date: 2011-07-12 03:01:34 +0000 (Tue, 12 Jul 2011)
>>>>
>>>> Log Message:
>>>> -----------
>>>> MdePkg: Fix X64 clang compile issues.
>>>>
>>>> Fixed issues with X64 clang, and also make StackSwitch push a zero on the
>>>> new stack to prevent a stack unwind into memory that is no longer valid.
>>>>
>>>> signed-off-by: andrewfish
>>>> reviewed-by: lgao4
>>>> reviewed-by: mdkinney
>>>>
>>>> Modified Paths:
>>>> --------------
>>>> trunk/edk2/MdePkg/Library/BaseLib/BaseLib.inf
>>>> trunk/edk2/MdePkg/Library/BaseLib/X64/SwitchStack.S
>>>> trunk/edk2/MdePkg/Library/BaseLib/X64/Thunk16.S
>>>> trunk/edk2/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
>>>>
>>>> Added Paths:
>>>> -----------
>>>> trunk/edk2/MdePkg/Library/BaseLib/Ia32/InternalSwitchStack.S
>>>>
>>>> Modified: trunk/edk2/MdePkg/Library/BaseLib/BaseLib.inf
>>>> ===================================================================
>>>> --- trunk/edk2/MdePkg/Library/BaseLib/BaseLib.inf 2011-07-12
>>>> 02:57:30 UTC (rev 12006)
>>>> +++ trunk/edk2/MdePkg/Library/BaseLib/BaseLib.inf 2011-07-12
>>>> 03:01:34 UTC (rev 12007)
>>>> @@ -277,7 +277,9 @@
>>>> Ia32/DisableCache.S | GCC
>>>>
>>>> Ia32/DivS64x64Remainder.c
>>>> - Ia32/InternalSwitchStack.c
>>>> + Ia32/InternalSwitchStack.c | MSFT
>>>> + Ia32/InternalSwitchStack.c | INTEL
>>>> + Ia32/InternalSwitchStack.S | GCC
>>>> Ia32/Non-existing.c
>>>> Unaligned.c
>>>> X86WriteIdtr.c
>>>>
>>>> Added: trunk/edk2/MdePkg/Library/BaseLib/Ia32/InternalSwitchStack.S
>>>> ===================================================================
>>>> --- trunk/edk2/MdePkg/Library/BaseLib/Ia32/InternalSwitchStack.S
>>>> (rev 0)
>>>> +++ trunk/edk2/MdePkg/Library/BaseLib/Ia32/InternalSwitchStack.S
>>>> 2011-07-12 03:01:34 UTC (rev 12007)
>>>> @@ -0,0 +1,48 @@
>>>> +#------------------------------------------------------------------------------
>>>> +#
>>>> +# Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
>>>> +# Portions copyright (c) 2011, Apple Inc. All rights reserved.
>>>> +# This program and the accompanying materials
>>>> +# are licensed and made available under the terms and conditions of the
>>>> BSD License
>>>> +# which accompanies this distribution. The full text of the license may
>>>> be found at
>>>> +# http://opensource.org/licenses/bsd-license.php.
>>>> +#
>>>> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
>>>> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
>>>> IMPLIED.
>>>> +#
>>>> +# Module Name:
>>>> +#
>>>> +# InternalSwitchStack.S
>>>> +#
>>>> +# Abstract:
>>>> +#
>>>> +# Implementation of a stack switch on IA-32.
>>>> +#
>>>> +#------------------------------------------------------------------------------
>>>> +
>>>> +ASM_GLOBAL ASM_PFX(InternalSwitchStack)
>>>> +
>>>> +#------------------------------------------------------------------------------
>>>> +# VOID
>>>> +# EFIAPI
>>>> +# InternalSwitchStack (
>>>> +# IN SWITCH_STACK_ENTRY_POINT EntryPoint,
>>>> +# IN VOID *Context1, OPTIONAL
>>>> +# IN VOID *Context2, OPTIONAL
>>>> +# IN VOID *NewStack
>>>> +# );
>>>> +#------------------------------------------------------------------------------
>>>> +ASM_PFX(InternalSwitchStack):
>>>> + pushl %ebp
>>>> + movl %esp, %ebp
>>>> +
>>>> + movl 20(%ebp), %esp # switch stack
>>>> + subl $8, %esp
>>>> +
>>>> + movl 16(%ebp), %eax
>>>> + movl %eax, 4(%esp)
>>>> + movl 12(%ebp), %eax
>>>> + movl %eax, (%esp)
>>>> + pushl $0 # keeps gdb from unwinding stack
>>>> + jmp *8(%ebp) # call and never return
>>>> +
>>>>
>>>> Modified: trunk/edk2/MdePkg/Library/BaseLib/X64/SwitchStack.S
>>>> ===================================================================
>>>> --- trunk/edk2/MdePkg/Library/BaseLib/X64/SwitchStack.S 2011-07-12
>>>> 02:57:30 UTC (rev 12006)
>>>> +++ trunk/edk2/MdePkg/Library/BaseLib/X64/SwitchStack.S 2011-07-12
>>>> 03:01:34 UTC (rev 12007)
>>>> @@ -37,7 +37,10 @@
>>>> #------------------------------------------------------------------------------
>>>> ASM_GLOBAL ASM_PFX(InternalSwitchStack)
>>>> ASM_PFX(InternalSwitchStack):
>>>> - mov %rcx, %rax
>>>> + pushq %rbp
>>>> + movq %rsp, %rbp
>>>> +
>>>> + mov %rcx, %rax // Shift registers for new call
>>>> mov %rdx, %rcx
>>>> mov %r8, %rdx
>>>> #
>>>> @@ -45,4 +48,5 @@
>>>> # in case the callee wishes to spill them.
>>>> #
>>>> lea -0x20(%r9), %rsp
>>>> - call *%rax
>>>> + pushq $0 // stop gdb stack unwind
>>>> + jmp *%rax // call EntryPoint ()
>>>>
>>>> Modified: trunk/edk2/MdePkg/Library/BaseLib/X64/Thunk16.S
>>>> ===================================================================
>>>> --- trunk/edk2/MdePkg/Library/BaseLib/X64/Thunk16.S 2011-07-12
>>>> 02:57:30 UTC (rev 12006)
>>>> +++ trunk/edk2/MdePkg/Library/BaseLib/X64/Thunk16.S 2011-07-12
>>>> 03:01:34 UTC (rev 12007)
>>>> @@ -49,13 +49,18 @@
>>>> .set IA32_REGS_SIZE, 56
>>>>
>>>> .data
>>>> +
>>>> +.set Lm16Size, ASM_PFX(InternalAsmThunk16) - ASM_PFX(m16Start)
>>>> +ASM_PFX(m16Size): .word Lm16Size
>>>> +.set LmThunk16Attr, L_ThunkAttr - ASM_PFX(m16Start)
>>>> +ASM_PFX(mThunk16Attr): .word LmThunk16Attr
>>>> +.set Lm16Gdt, ASM_PFX(NullSeg) - ASM_PFX(m16Start)
>>>> +ASM_PFX(m16Gdt): .word Lm16Gdt
>>>> +.set Lm16GdtrBase, _16GdtrBase - ASM_PFX(m16Start)
>>>> +ASM_PFX(m16GdtrBase): .word Lm16GdtrBase
>>>> +.set LmTransition, _EntryPoint - ASM_PFX(m16Start)
>>>> +ASM_PFX(mTransition): .word LmTransition
>>>>
>>>> -ASM_PFX(m16Size): .word ASM_PFX(InternalAsmThunk16) -
>>>> ASM_PFX(m16Start)
>>>> -ASM_PFX(mThunk16Attr): .word _ThunkAttr - ASM_PFX(m16Start)
>>>> -ASM_PFX(m16Gdt): .word ASM_PFX(NullSeg) - ASM_PFX(m16Start)
>>>> -ASM_PFX(m16GdtrBase): .word _16GdtrBase - ASM_PFX(m16Start)
>>>> -ASM_PFX(mTransition): .word _EntryPoint - ASM_PFX(m16Start)
>>>> -
>>>> .text
>>>>
>>>> ASM_PFX(m16Start):
>>>> @@ -91,7 +96,7 @@
>>>> .byte 0x1e # push ds
>>>> .byte 0x66,0x60 # pushad
>>>> .byte 0x66,0xba # mov edx, imm32
>>>> -_ThunkAttr: .space 4
>>>> +L_ThunkAttr: .space 4
>>>> testb $THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15, %dl
>>>> jz L_1
>>>> movl $0x15cd2401,%eax # mov ax, 2401h & int 15h
>>>> @@ -120,7 +125,7 @@
>>>> .byte 0x66,0x2e,0x89,0x87 # mov cs:[bx + (L_64Eip - L_Base)],
>>>> eax
>>>> .word L_64Eip - L_Base
>>>> .byte 0x66,0xb8 # mov eax, imm32
>>>> -SavedCr4: .space 4
>>>> +L_SavedCr4: .long 0
>>>> movq %rax, %cr4
>>>> #
>>>> # rdi in the instruction below is indeed bx in 16-bit code
>>>> @@ -133,15 +138,15 @@
>>>> orb $1,%ah
>>>> wrmsr
>>>> .byte 0x66,0xb8 # mov eax, imm32
>>>> -SavedCr0: .space 4
>>>> +L_SavedCr0: .long
>>>> movq %rax, %cr0
>>>> .byte 0x66,0xea # jmp far cs:L_64Bit
>>>> -L_64Eip: .space 4
>>>> -SavedCs: .space 2
>>>> +L_64Eip: .long 0
>>>> +L_SavedCs: .space 2
>>>> L_64BitCode:
>>>> .byte 0x90
>>>> .byte 0x67,0xbc # mov esp, imm32
>>>> -SavedSp: .space 4 # restore stack
>>>> +L_SavedSp: .long # restore stack
>>>> nop
>>>> ret
>>>>
>>>> @@ -258,19 +263,20 @@
>>>> popq %rcx
>>>> rep
>>>> movsl # copy RegSet
>>>> - lea (SavedCr4 - ASM_PFX(m16Start))(%rdx), %ecx
>>>> + lea (L_SavedCr4 - ASM_PFX(m16Start))(%rdx), %ecx
>>>> movl %edx,%eax # eax <- transition code address
>>>> andl $0xf,%edx
>>>> shll $12,%eax # segment address in high order 16
>>>> bits
>>>> - lea (ASM_PFX(BackFromUserCode) - ASM_PFX(m16Start))(%rdx), %ax
>>>> + .set LBackFromUserCodeDelta, ASM_PFX(BackFromUserCode) -
>>>> ASM_PFX(m16Start)
>>>> + lea (LBackFromUserCodeDelta)(%rdx), %ax
>>>> stosl # [edi] <- return address of user
>>>> code
>>>> sgdt 0x60(%rsp) # save GDT stack in argument space
>>>> movzwq 0x60(%rsp), %r10 # r10 <- GDT limit
>>>> - lea ((ASM_PFX(InternalAsmThunk16) - SavedCr4) + 0xf)(%rcx), %r11
>>>> + lea ((ASM_PFX(InternalAsmThunk16) - L_SavedCr4) + 0xf)(%rcx), %r11
>>>> andq $0xfffffffffffffff0, %r11 # r11 <- 16-byte aligned shadowed
>>>> GDT table in real mode buffer
>>>>
>>>> - movw %r10w, (SavedGdt - SavedCr4)(%rcx) # save the limit of
>>>> shadowed GDT table
>>>> - movq %r11, (SavedGdt - SavedCr4 + 0x2)(%rcx) # save the base
>>>> address of shadowed GDT table
>>>> + movw %r10w, (SavedGdt - L_SavedCr4)(%rcx) # save the limit
>>>> of shadowed GDT table
>>>> + movq %r11, (SavedGdt - L_SavedCr4 + 0x2)(%rcx) # save the base
>>>> address of shadowed GDT table
>>>>
>>>> movq 0x62(%rsp) ,%rsi # rsi <- the original GDT base
>>>> address
>>>> xchg %r10, %rcx # save rcx to r10 and initialize
>>>> rcx to be the limit of GDT table
>>>> @@ -283,7 +289,8 @@
>>>>
>>>> sidt 0x50(%rsp)
>>>> movq %cr0, %rax
>>>> - movl %eax, (SavedCr0 - SavedCr4)(%rcx)
>>>> + .set LSavedCrDelta, L_SavedCr0 - L_SavedCr4
>>>> + movl %eax, (LSavedCrDelta)(%rcx)
>>>> andl $0x7ffffffe,%eax # clear PE, PG bits
>>>> movq %cr4, %rbp
>>>> movl %ebp, (%rcx) # save CR4 in SavedCr4
>>>> @@ -291,17 +298,18 @@
>>>> movl %r8d, %esi # esi <- 16-bit stack segment
>>>> .byte 0x6a, DATA32
>>>> popq %rdx
>>>> - lgdt (_16Gdtr - SavedCr4)(%rcx)
>>>> + lgdt (_16Gdtr - L_SavedCr4)(%rcx)
>>>> movl %edx,%ss
>>>> pushfq
>>>> lea -8(%rdx), %edx
>>>> lea L_RetFromRealMode(%rip), %r8
>>>> pushq %r8
>>>> movl %cs, %r8d
>>>> - movw %r8w, (SavedCs - SavedCr4)(%rcx)
>>>> - movl %esp, (SavedSp - SavedCr4)(%rcx)
>>>> - .byte 0xff, 0x69 # jmp (_EntryPoint -
>>>> SavedCr4)(%rcx)
>>>> - .byte _EntryPoint - SavedCr4
>>>> + movw %r8w, (L_SavedCs - L_SavedCr4)(%rcx)
>>>> + movl %esp, (L_SavedSp - L_SavedCr4)(%rcx)
>>>> + .byte 0xff, 0x69 # jmp (_EntryPoint -
>>>> L_SavedCr4)(%rcx)
>>>> + .set Ltemp1, _EntryPoint - L_SavedCr4
>>>> + .byte Ltemp1
>>>> L_RetFromRealMode:
>>>> popfq
>>>> lgdt 0x60(%rsp) # restore protected mode GDTR
>>>>
>>>> Modified: trunk/edk2/MdePkg/Library/BasePeCoffLib/BasePeCoff.c
>>>> ===================================================================
>>>> --- trunk/edk2/MdePkg/Library/BasePeCoffLib/BasePeCoff.c 2011-07-12
>>>> 02:57:30 UTC (rev 12006)
>>>> +++ trunk/edk2/MdePkg/Library/BasePeCoffLib/BasePeCoff.c 2011-07-12
>>>> 03:01:34 UTC (rev 12007)
>>>> @@ -829,6 +829,7 @@
>>>> EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *ResourceDirectoryEntry;
>>>> EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;
>>>> EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;
>>>> + CHAR16 *String;
>>>>
>>>>
>>>> ASSERT (ImageContext != NULL);
>>>> @@ -1209,11 +1210,12 @@
>>>> for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries;
>>>> Index++) {
>>>> if (ResourceDirectoryEntry->u1.s.NameIsString) {
>>>> ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING
>>>> *) (Base + ResourceDirectoryEntry->u1.s.NameOffset);
>>>> + String = &ResourceDirectoryString->String[0];
>>>>
>>>> if (ResourceDirectoryString->Length == 3 &&
>>>> - ResourceDirectoryString->String[0] == L'H' &&
>>>> - ResourceDirectoryString->String[1] == L'I' &&
>>>> - ResourceDirectoryString->String[2] == L'I') {
>>>> + String[0] == L'H' &&
>>>> + String[1] == L'I' &&
>>>> + String[2] == L'I') {
>>>> //
>>>> // Resource Type "HII" found
>>>> //
>>>>
>>>>
>>>> This was sent by the SourceForge.net collaborative development platform,
>>>> the world's largest Open Source development site.
>>>>
>>>> ------------------------------------------------------------------------------
>>>> All of the data generated in your IT infrastructure is seriously valuable.
>>>> Why? It contains a definitive record of application performance, security
>>>> threats, fraudulent activity, and more. Splunk takes this data and makes
>>>> sense of it. IT sense. And common sense.
>>>> http://p.sf.net/sfu/splunk-d2d-c2
>>>> _______________________________________________
>>>> edk2-commits mailing list
>>>> [email protected]
>>>> https://lists.sourceforge.net/lists/listinfo/edk2-commits
>>
------------------------------------------------------------------------------
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel