Re: [edk2] [RFC 1/1] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
On 11/14/2017 09:30 AM, Paulo Alcantara wrote: Hi Andrew, On 14/11/2017 12:01, Andrew Fish wrote: C> Paulo, Cool feature. How does this code deal with VC++ that code does not store the frame pointer and requires symbols to unwind. I haven't tested in with MSVC, so I'd hope to get some help from Intel's guys to help supporting and testing it :-) Regarding the symbols, I performed some tests by writing a userspace PE/COFF application [1] and tried to: (a) handle the RUNTIME_FUNCTION entries in exception table (.pdata section) to find the function starting address and then its respective symbol name in COFF symbol table. (b) Walk through UNWIND_INFO entries in .xdata section to figure out which CPU register a function used as a frame pointer or if it didn't use any at all. The problem I had with (a) was that the COFF symbol table is not mapped directory into the image's address space -- that is, the "PointerToSymbolTable" in File Header *should* be 0 as per PE/COFF format specific when handling an executable file rather a object file. Additionally, if it's non-zero, it contains a file offset rather than a RVA address, so impossible to parse it at runtime. In (b), I realized that the CodeView format data in debug directory should be kept in a separate file (PDB file?) and they aren't mapped into image's address space as well. I don't have so much experience with PE/COFF format, so please correct me if I'm mistaken. You are correct that unfortunately, Microsoft's compilers don't put symbolic information in the executable file, they put it in a separate PDB file. And the PDB file format is not documented (although the Wine project has reverse engineered parts of it) and changes with different compiler versions. I've struggled with it before, and concluded that the only feasible way to parse it is to use the APIs Microsoft provides for that purpose, such as dbghelp.dll. That doesn't work inside a BIOS, of course. It is possible to define a simple, compiler-agnostic symbol table format and write a build-time tool to extract symbol data from the PDB files, convert it, and insert it into each module. GenFw is a handy place to generate symbol data, since it's reformatting the images already. I actually have code which does this I'd have to get permission from my company's Open Source Review Board to release it, though. That would take time. Brian IMHO, there should be exist a function like AsmGetFrameAddress() and/or AsmGetStackAddress() which would get implemented for both GCC and MSVC toolchains. Thank you very much for your comments! Also on the page fault you can print the fault address since it is in CR2. Good point! We should also do that. It should be possible to post process the text file and make a symbolicated backtrace. Yes. Thanks! Paulo Thanks, Andrew Fish On Nov 14, 2017, at 4:47 AM, Paulo Alcantarawrote: This patch adds stack trace support during a X64 CPU exception. It will dump out back trace, stack contents as well as image module names that were part of the call stack. Contributed-under: TianoCore Contribution Agreement 1.1 Cc: Eric Dong Cc: Laszlo Ersek Signed-off-by: Paulo Alcantara --- UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 344 +++- 1 file changed, 342 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index 65f0cff680..7048247be3 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -14,6 +14,11 @@ #include "CpuExceptionCommon.h" +// +// Unknown PDB file name +// +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mUnknownPdbFileName = ""; + /** Return address map of exception handler template so that C code can generate exception tables. @@ -243,6 +248,325 @@ DumpCpuContext ( } /** + Dump stack contents. + + @param[in] ImageBase Base address of PE/COFF image. + @param[out] PdbAbsoluteFilePath Absolute path of PDB file. + @param[out] PdbFileName File name of PDB file. +**/ +STATIC +VOID +GetPdbFileName ( + IN UINTN ImageBase, + OUT CHAR8 **PdbAbsoluteFilePath, + OUT CHAR8 **PdbFileName + ) +{ + VOID *PdbPointer; + CHAR8 *Str; + + // + // Get PDB file name from PE/COFF image + // + PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)ImageBase); + if (PdbPointer == NULL) { + // + // No PDB file name found. Set it to an unknown file name. + // + *PdbFileName = (CHAR8 *)mUnknownPdbFileName; + if (PdbAbsoluteFilePath != NULL) { + *PdbAbsoluteFilePath = NULL; + } + } else { + // + // Get file name portion out of PDB file in PE/COFF image + // + Str =
Re: [edk2] [RFC 1/1] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
Hi Andrew, On 14/11/2017 12:01, Andrew Fish wrote: C> Paulo, Cool feature. How does this code deal with VC++ that code does not store the frame pointer and requires symbols to unwind. I haven't tested in with MSVC, so I'd hope to get some help from Intel's guys to help supporting and testing it :-) Regarding the symbols, I performed some tests by writing a userspace PE/COFF application [1] and tried to: (a) handle the RUNTIME_FUNCTION entries in exception table (.pdata section) to find the function starting address and then its respective symbol name in COFF symbol table. (b) Walk through UNWIND_INFO entries in .xdata section to figure out which CPU register a function used as a frame pointer or if it didn't use any at all. The problem I had with (a) was that the COFF symbol table is not mapped directory into the image's address space -- that is, the "PointerToSymbolTable" in File Header *should* be 0 as per PE/COFF format specific when handling an executable file rather a object file. Additionally, if it's non-zero, it contains a file offset rather than a RVA address, so impossible to parse it at runtime. In (b), I realized that the CodeView format data in debug directory should be kept in a separate file (PDB file?) and they aren't mapped into image's address space as well. I don't have so much experience with PE/COFF format, so please correct me if I'm mistaken. IMHO, there should be exist a function like AsmGetFrameAddress() and/or AsmGetStackAddress() which would get implemented for both GCC and MSVC toolchains. Thank you very much for your comments! Also on the page fault you can print the fault address since it is in CR2. Good point! We should also do that. It should be possible to post process the text file and make a symbolicated backtrace. Yes. Thanks! Paulo Thanks, Andrew Fish On Nov 14, 2017, at 4:47 AM, Paulo Alcantarawrote: This patch adds stack trace support during a X64 CPU exception. It will dump out back trace, stack contents as well as image module names that were part of the call stack. Contributed-under: TianoCore Contribution Agreement 1.1 Cc: Eric Dong Cc: Laszlo Ersek Signed-off-by: Paulo Alcantara --- UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 344 +++- 1 file changed, 342 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index 65f0cff680..7048247be3 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -14,6 +14,11 @@ #include "CpuExceptionCommon.h" +// +// Unknown PDB file name +// +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mUnknownPdbFileName = ""; + /** Return address map of exception handler template so that C code can generate exception tables. @@ -243,6 +248,325 @@ DumpCpuContext ( } /** + Dump stack contents. + + @param[in] ImageBaseBase address of PE/COFF image. + @param[out] PdbAbsoluteFilePath Absolute path of PDB file. + @param[out] PdbFileName File name of PDB file. +**/ +STATIC +VOID +GetPdbFileName ( + IN UINTNImageBase, + OUT CHAR8**PdbAbsoluteFilePath, + OUT CHAR8**PdbFileName + ) +{ + VOID *PdbPointer; + CHAR8 *Str; + + // + // Get PDB file name from PE/COFF image + // + PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)ImageBase); + if (PdbPointer == NULL) { +// +// No PDB file name found. Set it to an unknown file name. +// +*PdbFileName = (CHAR8 *)mUnknownPdbFileName; +if (PdbAbsoluteFilePath != NULL) { + *PdbAbsoluteFilePath = NULL; +} + } else { +// +// Get file name portion out of PDB file in PE/COFF image +// +Str = (CHAR8 *)((UINTN)PdbPointer + +AsciiStrLen ((CHAR8 *)PdbPointer) - sizeof *Str); +for (; *Str != '/' && *Str != '\\'; Str--) { + ; +} + +// +// Set PDB file name (also skip trailing path separator: '/' or '\\') +// +*PdbFileName = Str + 1; + +if (PdbAbsoluteFilePath != NULL) { + // + // Set absolute file path of PDB file + // + *PdbAbsoluteFilePath = PdbPointer; +} + } +} + +/** + Dump stack contents. + + @param[in] CurrentRsp Current stack pointer address. + @param[in] UnwondStacksCount Count of unwond stack frames. +**/ +STATIC +VOID +DumpStackContents ( + IN UINT64 CurrentRsp, + IN INTNUnwondStacksCount + ) +{ + if (UnwondStacksCount == 0) { +return; + } + + // + // Dump out stack contents + // + InternalPrintMessage ("\nStack dump:\n"); + while (UnwondStacksCount-- > 0) { +InternalPrintMessage ( + "0x%016lx: %016lx %016lx\n", + CurrentRsp, + *(UINT64 *)CurrentRsp, + *(UINT64
Re: [edk2] [RFC 1/1] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
> On Nov 14, 2017, at 6:26 AM, Fan Jeff <vanjeff_...@hotmail.com> wrote: > > Andrew, > > We could use he EIP offset in Paul’s trace message and work with the > generated map file under debug directory for debug trace. It would also be possible to use gdb. Given 0 0x7E510F7F @ 0x7E509000+0x7F7E (0x7F762CB0) in PartitionDxe.dll If you load PartitionDxe.dll into gdb you can then do "l *0x7F7E" to dump the source. I'm mapping lldb behavior to gdb, but it should be close. Thanks, Andrew Fish > > Jeff > > 发件人: Andrew Fish <mailto:af...@apple.com> > 发送时间: 2017年11月14日 22:01 > 收件人: Paulo Alcantara <mailto:pca...@zytor.com> > 抄送: edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org>; Laszlo Ersek > <mailto:ler...@redhat.com>; Eric Dong <mailto:eric.d...@intel.com> > 主题: Re: [edk2] [RFC 1/1] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack > trace support > > Paulo, > > Cool feature. How does this code deal with VC++ that code does not store the > frame pointer and requires symbols to unwind. > > Also on the page fault you can print the fault address since it is in CR2. > > It should be possible to post process the text file and make a symbolicated > backtrace. > > Thanks, > > Andrew Fish > > > On Nov 14, 2017, at 4:47 AM, Paulo Alcantara <pca...@zytor.com> wrote: > > > > This patch adds stack trace support during a X64 CPU exception. > > > > It will dump out back trace, stack contents as well as image module > > names that were part of the call stack. > > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > Cc: Eric Dong <eric.d...@intel.com> > > Cc: Laszlo Ersek <ler...@redhat.com> > > Signed-off-by: Paulo Alcantara <pca...@zytor.com> > > --- > > UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 344 > > +++- > > 1 file changed, 342 insertions(+), 2 deletions(-) > > > > diff --git > > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c > > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c > > index 65f0cff680..7048247be3 100644 > > --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c > > +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c > > @@ -14,6 +14,11 @@ > > > > #include "CpuExceptionCommon.h" > > > > +// > > +// Unknown PDB file name > > +// > > +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mUnknownPdbFileName = ""; > > + > > /** > > Return address map of exception handler template so that C code can > > generate > > exception tables. > > @@ -243,6 +248,325 @@ DumpCpuContext ( > > } > > > > /** > > + Dump stack contents. > > + > > + @param[in] ImageBaseBase address of PE/COFF image. > > + @param[out] PdbAbsoluteFilePath Absolute path of PDB file. > > + @param[out] PdbFileName File name of PDB file. > > +**/ > > +STATIC > > +VOID > > +GetPdbFileName ( > > + IN UINTNImageBase, > > + OUT CHAR8**PdbAbsoluteFilePath, > > + OUT CHAR8**PdbFileName > > + ) > > +{ > > + VOID *PdbPointer; > > + CHAR8 *Str; > > + > > + // > > + // Get PDB file name from PE/COFF image > > + // > > + PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)ImageBase); > > + if (PdbPointer == NULL) { > > +// > > +// No PDB file name found. Set it to an unknown file name. > > +// > > +*PdbFileName = (CHAR8 *)mUnknownPdbFileName; > > +if (PdbAbsoluteFilePath != NULL) { > > + *PdbAbsoluteFilePath = NULL; > > +} > > + } else { > > +// > > +// Get file name portion out of PDB file in PE/COFF image > > +// > > +Str = (CHAR8 *)((UINTN)PdbPointer + > > +AsciiStrLen ((CHAR8 *)PdbPointer) - sizeof *Str); > > +for (; *Str != '/' && *Str != '\\'; Str--) { > > + ; > > +} > > + > > +// > > +// Set PDB file name (also skip trailing path separator: '/' or '\\') > > +// > > +*PdbFileName = Str + 1; > > + > > +if (PdbAbsoluteFilePath != NULL) { > > + // > > + // Set absolute file path of PDB file > > + // > > + *PdbAbsoluteFilePath = PdbPointer; > > +} > > + } > > +} > > + > > +/** > > + Dump stack contents. > > + > > +
Re: [edk2] [RFC 1/1] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
Paulo, Cool feature. How does this code deal with VC++ that code does not store the frame pointer and requires symbols to unwind. Also on the page fault you can print the fault address since it is in CR2. It should be possible to post process the text file and make a symbolicated backtrace. Thanks, Andrew Fish > On Nov 14, 2017, at 4:47 AM, Paulo Alcantarawrote: > > This patch adds stack trace support during a X64 CPU exception. > > It will dump out back trace, stack contents as well as image module > names that were part of the call stack. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Cc: Eric Dong > Cc: Laszlo Ersek > Signed-off-by: Paulo Alcantara > --- > UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 344 > +++- > 1 file changed, 342 insertions(+), 2 deletions(-) > > diff --git > a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c > b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c > index 65f0cff680..7048247be3 100644 > --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c > +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c > @@ -14,6 +14,11 @@ > > #include "CpuExceptionCommon.h" > > +// > +// Unknown PDB file name > +// > +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mUnknownPdbFileName = ""; > + > /** > Return address map of exception handler template so that C code can generate > exception tables. > @@ -243,6 +248,325 @@ DumpCpuContext ( > } > > /** > + Dump stack contents. > + > + @param[in] ImageBaseBase address of PE/COFF image. > + @param[out] PdbAbsoluteFilePath Absolute path of PDB file. > + @param[out] PdbFileName File name of PDB file. > +**/ > +STATIC > +VOID > +GetPdbFileName ( > + IN UINTNImageBase, > + OUT CHAR8**PdbAbsoluteFilePath, > + OUT CHAR8**PdbFileName > + ) > +{ > + VOID *PdbPointer; > + CHAR8 *Str; > + > + // > + // Get PDB file name from PE/COFF image > + // > + PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)ImageBase); > + if (PdbPointer == NULL) { > +// > +// No PDB file name found. Set it to an unknown file name. > +// > +*PdbFileName = (CHAR8 *)mUnknownPdbFileName; > +if (PdbAbsoluteFilePath != NULL) { > + *PdbAbsoluteFilePath = NULL; > +} > + } else { > +// > +// Get file name portion out of PDB file in PE/COFF image > +// > +Str = (CHAR8 *)((UINTN)PdbPointer + > +AsciiStrLen ((CHAR8 *)PdbPointer) - sizeof *Str); > +for (; *Str != '/' && *Str != '\\'; Str--) { > + ; > +} > + > +// > +// Set PDB file name (also skip trailing path separator: '/' or '\\') > +// > +*PdbFileName = Str + 1; > + > +if (PdbAbsoluteFilePath != NULL) { > + // > + // Set absolute file path of PDB file > + // > + *PdbAbsoluteFilePath = PdbPointer; > +} > + } > +} > + > +/** > + Dump stack contents. > + > + @param[in] CurrentRsp Current stack pointer address. > + @param[in] UnwondStacksCount Count of unwond stack frames. > +**/ > +STATIC > +VOID > +DumpStackContents ( > + IN UINT64 CurrentRsp, > + IN INTNUnwondStacksCount > + ) > +{ > + if (UnwondStacksCount == 0) { > +return; > + } > + > + // > + // Dump out stack contents > + // > + InternalPrintMessage ("\nStack dump:\n"); > + while (UnwondStacksCount-- > 0) { > +InternalPrintMessage ( > + "0x%016lx: %016lx %016lx\n", > + CurrentRsp, > + *(UINT64 *)CurrentRsp, > + *(UINT64 *)((UINTN)CurrentRsp + 8) > + ); > + > +// > +// As per Microsoft x64 ABI, the stack pointer must be aligned on a 16 > byte > +// boundary. > +// > +CurrentRsp = CurrentRsp + 16; > + } > +} > + > +/** > + Dump all image module names from call stack. > + > + @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. > +**/ > +STATIC > +VOID > +DumpImageModuleNames ( > + IN EFI_SYSTEM_CONTEXT SystemContext > + ) > +{ > + EFI_STATUS Status; > + UINT64 Rip; > + UINTN ImageBase; > + VOID*EntryPoint; > + CHAR8 *PdbAbsoluteFilePath; > + CHAR8 *PdbFileName; > + UINT64 Rbp; > + > + // > + // Set current RIP address > + // > + Rip = SystemContext.SystemContextX64->Rip; > + > + // > + // Set current frame pointer address > + // > + Rbp = SystemContext.SystemContextX64->Rbp; > + > + // > + // Get initial PE/COFF image base address from current RIP > + // > + ImageBase = PeCoffSearchImageBase (Rip); > + if (ImageBase == 0) { > +InternalPrintMessage (" Could not find image module names. "); > +return; > + } > + > + // > + // Get initial PE/COFF image's entry point > + // > + Status = PeCoffLoaderGetEntryPoint ((VOID *)ImageBase, ); > + if (EFI_ERROR (Status)) { > +EntryPoint = NULL; > + } > + > + // >
[edk2] [RFC 1/1] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
This patch adds stack trace support during a X64 CPU exception. It will dump out back trace, stack contents as well as image module names that were part of the call stack. Contributed-under: TianoCore Contribution Agreement 1.1 Cc: Eric DongCc: Laszlo Ersek Signed-off-by: Paulo Alcantara --- UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 344 +++- 1 file changed, 342 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index 65f0cff680..7048247be3 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -14,6 +14,11 @@ #include "CpuExceptionCommon.h" +// +// Unknown PDB file name +// +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mUnknownPdbFileName = ""; + /** Return address map of exception handler template so that C code can generate exception tables. @@ -243,6 +248,325 @@ DumpCpuContext ( } /** + Dump stack contents. + + @param[in] ImageBaseBase address of PE/COFF image. + @param[out] PdbAbsoluteFilePath Absolute path of PDB file. + @param[out] PdbFileName File name of PDB file. +**/ +STATIC +VOID +GetPdbFileName ( + IN UINTNImageBase, + OUT CHAR8**PdbAbsoluteFilePath, + OUT CHAR8**PdbFileName + ) +{ + VOID *PdbPointer; + CHAR8 *Str; + + // + // Get PDB file name from PE/COFF image + // + PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)ImageBase); + if (PdbPointer == NULL) { +// +// No PDB file name found. Set it to an unknown file name. +// +*PdbFileName = (CHAR8 *)mUnknownPdbFileName; +if (PdbAbsoluteFilePath != NULL) { + *PdbAbsoluteFilePath = NULL; +} + } else { +// +// Get file name portion out of PDB file in PE/COFF image +// +Str = (CHAR8 *)((UINTN)PdbPointer + +AsciiStrLen ((CHAR8 *)PdbPointer) - sizeof *Str); +for (; *Str != '/' && *Str != '\\'; Str--) { + ; +} + +// +// Set PDB file name (also skip trailing path separator: '/' or '\\') +// +*PdbFileName = Str + 1; + +if (PdbAbsoluteFilePath != NULL) { + // + // Set absolute file path of PDB file + // + *PdbAbsoluteFilePath = PdbPointer; +} + } +} + +/** + Dump stack contents. + + @param[in] CurrentRsp Current stack pointer address. + @param[in] UnwondStacksCount Count of unwond stack frames. +**/ +STATIC +VOID +DumpStackContents ( + IN UINT64 CurrentRsp, + IN INTNUnwondStacksCount + ) +{ + if (UnwondStacksCount == 0) { +return; + } + + // + // Dump out stack contents + // + InternalPrintMessage ("\nStack dump:\n"); + while (UnwondStacksCount-- > 0) { +InternalPrintMessage ( + "0x%016lx: %016lx %016lx\n", + CurrentRsp, + *(UINT64 *)CurrentRsp, + *(UINT64 *)((UINTN)CurrentRsp + 8) + ); + +// +// As per Microsoft x64 ABI, the stack pointer must be aligned on a 16 byte +// boundary. +// +CurrentRsp = CurrentRsp + 16; + } +} + +/** + Dump all image module names from call stack. + + @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT. +**/ +STATIC +VOID +DumpImageModuleNames ( + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + EFI_STATUS Status; + UINT64 Rip; + UINTN ImageBase; + VOID*EntryPoint; + CHAR8 *PdbAbsoluteFilePath; + CHAR8 *PdbFileName; + UINT64 Rbp; + + // + // Set current RIP address + // + Rip = SystemContext.SystemContextX64->Rip; + + // + // Set current frame pointer address + // + Rbp = SystemContext.SystemContextX64->Rbp; + + // + // Get initial PE/COFF image base address from current RIP + // + ImageBase = PeCoffSearchImageBase (Rip); + if (ImageBase == 0) { +InternalPrintMessage (" Could not find image module names. "); +return; + } + + // + // Get initial PE/COFF image's entry point + // + Status = PeCoffLoaderGetEntryPoint ((VOID *)ImageBase, ); + if (EFI_ERROR (Status)) { +EntryPoint = NULL; + } + + // + // Get file name and absolute path of initial PDB file + // + GetPdbFileName (ImageBase, , ); + + // + // Print out initial image module name (if any) + // + if (PdbAbsoluteFilePath != NULL) { +InternalPrintMessage ( + "\n%a (ImageBase=0x%016lx, EntryPoint=0x%016lx):\n", + PdbFileName, + ImageBase, + (UINTN)EntryPoint + ); +InternalPrintMessage ("%a\n", PdbAbsoluteFilePath); + } + + // + // Walk through call stack and find next module names + // + for (;;) { +// +// Set RIP with return address from current stack frame +// +Rip = *(UINT64 *)((UINTN)Rbp + 8); + +// +// Check if RIP is within another PE/COFF image base address +// +if (Rip < ImageBase) {