diff mbox

[edk2,2/2] ArmPkg/DefaultExceptionHandlerLib AARCH64: add minimal backtrace to crash dump

Message ID 1473236515-8318-2-git-send-email-ard.biesheuvel@linaro.org
State Accepted
Commit 960d0de80b288c7cd9cbccfde7a12a48935055b4
Headers show

Commit Message

Ard Biesheuvel Sept. 7, 2016, 8:21 a.m. UTC
When dumping the CPU state after an unhandled fault, walk the stack
frames and decode the return addresses so we can show a minimal
backtrace. Unfortunately, we do not have sufficient information to
show the function names, but at least we can see the modules and the
return addresses inside the modules.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

---

Example output:

Synchronous Exception at 0x00000000F5EA4C8C
/home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe/DEBUG/ArmVeNorFlashDxe.dll loaded at 0x00000000F5E90000
called from /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe/DEBUG/ArmVeNorFlashDxe.dll (0x00000000F5EA4AE8) loaded at 0x00000000F5E90000
called from /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe/DEBUG/ArmVeNorFlashDxe.dll (0x00000000F5EA1BFC) loaded at 0x00000000F5E90000
called from /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe/DEBUG/ArmVeNorFlashDxe.dll (0x00000000F5EA23F4) loaded at 0x00000000F5E90000
called from /work/jenkins/workspace/ap-uefi-bin/EDK2_ARCH/ARM/EDK2_BINARY/FatPkg/label/sas-sw/Build/Fat/RELEASE_GCC49/AARCH64/FatPkg/EnhancedFatDxe/Fat/DEBUG/Fat.dll (0x00000000FADC454C) loaded at 0x00000000FADC3000
called from /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll (0x00000000FE47C868) loaded at 0x00000000FE471000
called from /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll (0x00000000FAE2C50C) loaded at 0x00000000FAE01000
called from /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll (0x00000000FAE2C674) loaded at 0x00000000FAE01000
called from /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll (0x00000000FAE2C264) loaded at 0x00000000FAE01000
called from /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll (0x00000000FAE36998) loaded at 0x00000000FAE01000
called from /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll (0x00000000FAE03668) loaded at 0x00000000FAE01000
called from /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll (0x00000000FE4733F0) loaded at 0x00000000FE471000
called from /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll (0x00000000FE4724A0) loaded at 0x00000000FE471000
called from /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll (0x00000000FE472024) loaded at 0x00000000FE471000
---
 .../AArch64/DefaultExceptionHandler.c               | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

-- 
2.7.4

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Comments

Ard Biesheuvel Sept. 7, 2016, 11:03 a.m. UTC | #1
On 7 September 2016 at 10:48, Michael Zimmermann
<sigmaepsilon92@gmail.com> wrote:
> nice, can we do this for ARM too? I usually need to add DEBUG((...))'s all

> over the place for hours until I found the reason for a fault.

>


This is going to be tricky. Unlike AARCH64, which unambiguously
describes in the AAPCS how to link the stack frames using x29, the
AAPCS for ARM does not standardise this, and so different compilers
may do different things, also depending on whether you are executing
in ARM or Thumb mode. For instance, the following prologue was snipped
from a BdsDxe.dll build using GCC5 in Thumb2 mode.

00000254 <_ModuleEntryPoint>:
     254:       e96d 7e02       strd    r7, lr, [sp, #-8]!
     258:       b084            sub     sp, #16
     25a:       af00            add     r7, sp, #0

Googling around, i can indeed find sources that describe how GCC uses
r7 as the frame pointer for Thumb2 code. However, looking at this
code, this is still not sufficient to find the *next* frame pointer on
the stack. IOW, there is no standardised layout to find the next frame
pointer inside the stack frame.

The only way to do this reliably is using unwind tables, but this is
*much* more complicated than the 20 line patch that enables it for
AArch64

Ard.


> On Wed, Sep 7, 2016 at 10:21 AM, Ard Biesheuvel <ard.biesheuvel@linaro.org>

> wrote:

>>

>> When dumping the CPU state after an unhandled fault, walk the stack

>> frames and decode the return addresses so we can show a minimal

>> backtrace. Unfortunately, we do not have sufficient information to

>> show the function names, but at least we can see the modules and the

>> return addresses inside the modules.

>>

>> Contributed-under: TianoCore Contribution Agreement 1.0

>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

>> ---

>>

>> Example output:

>>

>> Synchronous Exception at 0x00000000F5EA4C8C

>>

>> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe/DEBUG/ArmVeNorFlashDxe.dll

>> loaded at 0x00000000F5E90000

>> called from

>> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe/DEBUG/ArmVeNorFlashDxe.dll

>> (0x00000000F5EA4AE8) loaded at 0x00000000F5E90000

>> called from

>> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe/DEBUG/ArmVeNorFlashDxe.dll

>> (0x00000000F5EA1BFC) loaded at 0x00000000F5E90000

>> called from

>> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe/DEBUG/ArmVeNorFlashDxe.dll

>> (0x00000000F5EA23F4) loaded at 0x00000000F5E90000

>> called from

>> /work/jenkins/workspace/ap-uefi-bin/EDK2_ARCH/ARM/EDK2_BINARY/FatPkg/label/sas-sw/Build/Fat/RELEASE_GCC49/AARCH64/FatPkg/EnhancedFatDxe/Fat/DEBUG/Fat.dll

>> (0x00000000FADC454C) loaded at 0x00000000FADC3000

>> called from

>> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll

>> (0x00000000FE47C868) loaded at 0x00000000FE471000

>> called from

>> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll

>> (0x00000000FAE2C50C) loaded at 0x00000000FAE01000

>> called from

>> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll

>> (0x00000000FAE2C674) loaded at 0x00000000FAE01000

>> called from

>> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll

>> (0x00000000FAE2C264) loaded at 0x00000000FAE01000

>> called from

>> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll

>> (0x00000000FAE36998) loaded at 0x00000000FAE01000

>> called from

>> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll

>> (0x00000000FAE03668) loaded at 0x00000000FAE01000

>> called from

>> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll

>> (0x00000000FE4733F0) loaded at 0x00000000FE471000

>> called from

>> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll

>> (0x00000000FE4724A0) loaded at 0x00000000FE471000

>> called from

>> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll

>> (0x00000000FE472024) loaded at 0x00000000FE471000

>> ---

>>  .../AArch64/DefaultExceptionHandler.c               | 21

>> +++++++++++++++++++++

>>  1 file changed, 21 insertions(+)

>>

>> diff --git

>> a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c

>> b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c

>> index 31fc936b21ff..84b442f2b6f4 100644

>> ---

>> a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c

>> +++

>> b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c

>> @@ -152,9 +152,30 @@ DefaultExceptionHandler (

>>      CHAR8  *Pdb;

>>      UINTN  ImageBase;

>>      UINTN  PeCoffSizeOfHeader;

>> +    UINT64 *Fp;

>> +

>>      Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR,

>> &ImageBase, &PeCoffSizeOfHeader);

>>      if (Pdb != NULL) {

>>        DEBUG ((EFI_D_ERROR, "%a loaded at 0x%016lx \n", Pdb, ImageBase));

>> +

>> +      Pdb = GetImageName (SystemContext.SystemContextAArch64->LR,

>> &ImageBase,

>> +              &PeCoffSizeOfHeader);

>> +      if (Pdb != NULL) {

>> +        DEBUG ((EFI_D_ERROR, "called from %a (0x%016lx) loaded at

>> 0x%016lx \n",

>> +          Pdb, SystemContext.SystemContextAArch64->LR, ImageBase));

>> +      }

>> +      for (Fp = (UINT64 *)SystemContext.SystemContextAArch64->FP;

>> +           *Fp != 0;

>> +           Fp = (UINT64 *)Fp[0]) {

>> +        if (Fp[1] == SystemContext.SystemContextAArch64->LR) {

>> +         continue;

>> +        }

>> +        Pdb = GetImageName (Fp[1], &ImageBase, &PeCoffSizeOfHeader);

>> +        if (Pdb != NULL) {

>> +          DEBUG ((EFI_D_ERROR, "called from %a (0x%016lx) loaded at

>> 0x%016lx \n",

>> +            Pdb, Fp[1], ImageBase));

>> +        }

>> +      }

>>      }

>>    DEBUG_CODE_END ();

>>

>> --

>> 2.7.4

>>

>> _______________________________________________

>> edk2-devel mailing list

>> edk2-devel@lists.01.org

>> https://lists.01.org/mailman/listinfo/edk2-devel

>

>

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Ard Biesheuvel Sept. 7, 2016, 11:32 a.m. UTC | #2
On 7 September 2016 at 12:25, Michael Zimmermann
<sigmaepsilon92@gmail.com> wrote:
>> However, looking at this

>> code, this is still not sufficient to find the *next* frame pointer on

>> the stack.

> are you sure about that? this code looks like it does just that:

> https://github.com/torvalds/linux/blob/master/arch/arm/kernel/stacktrace.c

>


First of all, that comment makes little sense:

* With framepointer enabled, a simple function prologue looks like this:
* mov ip, sp
* stmdb sp!, {fp, ip, lr, pc}

I assume this should be

stmdb sp!, {fp, ip, lr}

* sub fp, ip, #4
*
* A simple function epilogue looks like this:
* ldm sp, {fp, sp, pc}

But then, it looks like GCC in ARM mode happens to generate stack
frames that are easily unwound.

However, in EDK2 we use Thumb2 primarily, and the code I snipped is
actually from a -fno-omit-frame-pointer Thumb2 build, and it does not
look like whatever is pushed onto the stack can be decoded
unambiguously like that.


> On Wed, Sep 7, 2016 at 1:03 PM, Ard Biesheuvel <ard.biesheuvel@linaro.org>

> wrote:

>>

>> On 7 September 2016 at 10:48, Michael Zimmermann

>> <sigmaepsilon92@gmail.com> wrote:

>> > nice, can we do this for ARM too? I usually need to add DEBUG((...))'s

>> > all

>> > over the place for hours until I found the reason for a fault.

>> >

>>

>> This is going to be tricky. Unlike AARCH64, which unambiguously

>> describes in the AAPCS how to link the stack frames using x29, the

>> AAPCS for ARM does not standardise this, and so different compilers

>> may do different things, also depending on whether you are executing

>> in ARM or Thumb mode. For instance, the following prologue was snipped

>> from a BdsDxe.dll build using GCC5 in Thumb2 mode.

>>

>> 00000254 <_ModuleEntryPoint>:

>>      254:       e96d 7e02       strd    r7, lr, [sp, #-8]!

>>      258:       b084            sub     sp, #16

>>      25a:       af00            add     r7, sp, #0

>>

>> Googling around, i can indeed find sources that describe how GCC uses

>> r7 as the frame pointer for Thumb2 code. However, looking at this

>> code, this is still not sufficient to find the *next* frame pointer on

>> the stack. IOW, there is no standardised layout to find the next frame

>> pointer inside the stack frame.

>>

>> The only way to do this reliably is using unwind tables, but this is

>> *much* more complicated than the 20 line patch that enables it for

>> AArch64

>>

>> Ard.

>>

>>

>> > On Wed, Sep 7, 2016 at 10:21 AM, Ard Biesheuvel

>> > <ard.biesheuvel@linaro.org>

>> > wrote:

>> >>

>> >> When dumping the CPU state after an unhandled fault, walk the stack

>> >> frames and decode the return addresses so we can show a minimal

>> >> backtrace. Unfortunately, we do not have sufficient information to

>> >> show the function names, but at least we can see the modules and the

>> >> return addresses inside the modules.

>> >>

>> >> Contributed-under: TianoCore Contribution Agreement 1.0

>> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

>> >> ---

>> >>

>> >> Example output:

>> >>

>> >> Synchronous Exception at 0x00000000F5EA4C8C

>> >>

>> >>

>> >> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe/DEBUG/ArmVeNorFlashDxe.dll

>> >> loaded at 0x00000000F5E90000

>> >> called from

>> >>

>> >> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe/DEBUG/ArmVeNorFlashDxe.dll

>> >> (0x00000000F5EA4AE8) loaded at 0x00000000F5E90000

>> >> called from

>> >>

>> >> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe/DEBUG/ArmVeNorFlashDxe.dll

>> >> (0x00000000F5EA1BFC) loaded at 0x00000000F5E90000

>> >> called from

>> >>

>> >> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe/DEBUG/ArmVeNorFlashDxe.dll

>> >> (0x00000000F5EA23F4) loaded at 0x00000000F5E90000

>> >> called from

>> >>

>> >> /work/jenkins/workspace/ap-uefi-bin/EDK2_ARCH/ARM/EDK2_BINARY/FatPkg/label/sas-sw/Build/Fat/RELEASE_GCC49/AARCH64/FatPkg/EnhancedFatDxe/Fat/DEBUG/Fat.dll

>> >> (0x00000000FADC454C) loaded at 0x00000000FADC3000

>> >> called from

>> >>

>> >> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll

>> >> (0x00000000FE47C868) loaded at 0x00000000FE471000

>> >> called from

>> >>

>> >> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll

>> >> (0x00000000FAE2C50C) loaded at 0x00000000FAE01000

>> >> called from

>> >>

>> >> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll

>> >> (0x00000000FAE2C674) loaded at 0x00000000FAE01000

>> >> called from

>> >>

>> >> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll

>> >> (0x00000000FAE2C264) loaded at 0x00000000FAE01000

>> >> called from

>> >>

>> >> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll

>> >> (0x00000000FAE36998) loaded at 0x00000000FAE01000

>> >> called from

>> >>

>> >> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe/DEBUG/BdsDxe.dll

>> >> (0x00000000FAE03668) loaded at 0x00000000FAE01000

>> >> called from

>> >>

>> >> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll

>> >> (0x00000000FE4733F0) loaded at 0x00000000FE471000

>> >> called from

>> >>

>> >> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll

>> >> (0x00000000FE4724A0) loaded at 0x00000000FE471000

>> >> called from

>> >>

>> >> /home/ard/build/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/AARCH64/MdeModulePkg/Core/Dxe/DxeMain/DEBUG/DxeCore.dll

>> >> (0x00000000FE472024) loaded at 0x00000000FE471000

>> >> ---

>> >>  .../AArch64/DefaultExceptionHandler.c               | 21

>> >> +++++++++++++++++++++

>> >>  1 file changed, 21 insertions(+)

>> >>

>> >> diff --git

>> >>

>> >> a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c

>> >>

>> >> b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c

>> >> index 31fc936b21ff..84b442f2b6f4 100644

>> >> ---

>> >>

>> >> a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c

>> >> +++

>> >>

>> >> b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c

>> >> @@ -152,9 +152,30 @@ DefaultExceptionHandler (

>> >>      CHAR8  *Pdb;

>> >>      UINTN  ImageBase;

>> >>      UINTN  PeCoffSizeOfHeader;

>> >> +    UINT64 *Fp;

>> >> +

>> >>      Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR,

>> >> &ImageBase, &PeCoffSizeOfHeader);

>> >>      if (Pdb != NULL) {

>> >>        DEBUG ((EFI_D_ERROR, "%a loaded at 0x%016lx \n", Pdb,

>> >> ImageBase));

>> >> +

>> >> +      Pdb = GetImageName (SystemContext.SystemContextAArch64->LR,

>> >> &ImageBase,

>> >> +              &PeCoffSizeOfHeader);

>> >> +      if (Pdb != NULL) {

>> >> +        DEBUG ((EFI_D_ERROR, "called from %a (0x%016lx) loaded at

>> >> 0x%016lx \n",

>> >> +          Pdb, SystemContext.SystemContextAArch64->LR, ImageBase));

>> >> +      }

>> >> +      for (Fp = (UINT64 *)SystemContext.SystemContextAArch64->FP;

>> >> +           *Fp != 0;

>> >> +           Fp = (UINT64 *)Fp[0]) {

>> >> +        if (Fp[1] == SystemContext.SystemContextAArch64->LR) {

>> >> +         continue;

>> >> +        }

>> >> +        Pdb = GetImageName (Fp[1], &ImageBase, &PeCoffSizeOfHeader);

>> >> +        if (Pdb != NULL) {

>> >> +          DEBUG ((EFI_D_ERROR, "called from %a (0x%016lx) loaded at

>> >> 0x%016lx \n",

>> >> +            Pdb, Fp[1], ImageBase));

>> >> +        }

>> >> +      }

>> >>      }

>> >>    DEBUG_CODE_END ();

>> >>

>> >> --

>> >> 2.7.4

>> >>

>> >> _______________________________________________

>> >> edk2-devel mailing list

>> >> edk2-devel@lists.01.org

>> >> https://lists.01.org/mailman/listinfo/edk2-devel

>> >

>> >

>

>

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Ard Biesheuvel Sept. 9, 2016, 1:08 p.m. UTC | #3
On 7 September 2016 at 12:32, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> On 7 September 2016 at 12:25, Michael Zimmermann

> <sigmaepsilon92@gmail.com> wrote:

>>> However, looking at this

>>> code, this is still not sufficient to find the *next* frame pointer on

>>> the stack.

>> are you sure about that? this code looks like it does just that:

>> https://github.com/torvalds/linux/blob/master/arch/arm/kernel/stacktrace.c

>>

>

> First of all, that comment makes little sense:

>

> * With framepointer enabled, a simple function prologue looks like this:

> * mov ip, sp

> * stmdb sp!, {fp, ip, lr, pc}

>

> I assume this should be

>

> stmdb sp!, {fp, ip, lr}

>

> * sub fp, ip, #4

> *

> * A simple function epilogue looks like this:

> * ldm sp, {fp, sp, pc}

>


OK, I spoke a bit too soon. The 'pop' does not actually increment the
stack pointer, so while the push does make sense (and pushing the pc
in addition is just informational), the pop should actually be
implemented as

ldm sp, {fp, sp, lr}

... do other stuff including incrementing the sp to its original value ...

bx lr

In any case, unless you have any information that suggests that GCC in
Thumb2 mode can be coerced into managing the frame pointer in a way
that allows us to do something similar in EDK2, I am going to stick
with my assertion that this is not currently possible on ARM.

Thanks,
Ard.
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
diff mbox

Patch

diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c
index 31fc936b21ff..84b442f2b6f4 100644
--- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c
+++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c
@@ -152,9 +152,30 @@  DefaultExceptionHandler (
     CHAR8  *Pdb;
     UINTN  ImageBase;
     UINTN  PeCoffSizeOfHeader;
+    UINT64 *Fp;
+
     Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase, &PeCoffSizeOfHeader);
     if (Pdb != NULL) {
       DEBUG ((EFI_D_ERROR, "%a loaded at 0x%016lx \n", Pdb, ImageBase));
+
+      Pdb = GetImageName (SystemContext.SystemContextAArch64->LR, &ImageBase,
+              &PeCoffSizeOfHeader);
+      if (Pdb != NULL) {
+        DEBUG ((EFI_D_ERROR, "called from %a (0x%016lx) loaded at 0x%016lx \n",
+          Pdb, SystemContext.SystemContextAArch64->LR, ImageBase));
+      }
+      for (Fp = (UINT64 *)SystemContext.SystemContextAArch64->FP;
+           *Fp != 0;
+           Fp = (UINT64 *)Fp[0]) {
+        if (Fp[1] == SystemContext.SystemContextAArch64->LR) {
+         continue;
+        }
+        Pdb = GetImageName (Fp[1], &ImageBase, &PeCoffSizeOfHeader);
+        if (Pdb != NULL) {
+          DEBUG ((EFI_D_ERROR, "called from %a (0x%016lx) loaded at 0x%016lx \n",
+            Pdb, Fp[1], ImageBase));
+        }
+      }
     }
   DEBUG_CODE_END ();