From: "Paulo Alcantara" <pcacjr@zytor.com>
To: "Yao, Jiewen" <jiewen.yao@intel.com>
Cc: "Paulo Alcantara" <pcacjr@zytor.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
"Laszlo Ersek" <lersek@redhat.com>,
"Dong, Eric" <eric.dong@intel.com>
Subject: Re: [RFC v2 1/3] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
Date: Thu, 16 Nov 2017 20:13:16 -0200 [thread overview]
Message-ID: <f2bb8a290f25b5989fb6026944b0709f.squirrel@www.zytor.com> (raw)
In-Reply-To: <74D8A39837DF1E4DA445A8C0B3885C503AA1E9D1@shsmsx102.ccr.corp.intel.com>
Hi Jiewen,
On Wed, November 15, 2017 11:57 pm, Yao, Jiewen wrote:
> Hi Paulo
> Thanks to bring this cool feature.
>
> I have same feeling as Jeff Fan. It is great!
>
> I have some questions, hope you can clarify.
> 1) Would you please let us know which tool change is validated? Such as
> MSVC, or GCC?
GCC only. This should not work on MSVC because it relies on frame pointers.
> 2) Would you please let us know which phase is validated? Such as PEI
> PreMemory, PEI PostMemory, DXE, SMM?
DXE. I'm currently testing it by placing a random "CpuBreakpoint ()" in
PartitionDxe driver.
> 3) Would you please let us know if there is any special condition
> validated? Such as code is in an interrupt handler, SMM initialization
> code, thunk code during mode switch, etc.
> I ask this because I have seen lots of discussion on sanity check, to
> avoid double exception.
At the moment I'm only ensuring proper aligned RSP and ESP values. But we
still need to validate the RIP values, etc. as Andrew and Brian suggested.
> 4) We supported some security feature to create a hole in normal memory
> map, such as PageGuard, StackGuard, SMM communication protection, etc.
> Accessing those memory directly will cause #PF immediately.
> Would you please let us know how we detect that case, to avoid RIP or RSP
> fail to the non-present page?
Sorry. I have no idea :-( I'd hope to get some help from you guys.
> 5) May I know why we check RIP < ImageBase? Is that legal or illegal if
> RIP > ImageBase+ImageSize, but RIP in another PE/COFF image?
That check was a wrong assumption that I had in the beginning. RIP may
point to either lower or higher addresses where the other PE/COFF images
are located. Fixed it in v3.
Sorry for the delay in the response. I'm only able to work on this in my
free time.
Thanks!
Paulo
>> + //
>> + // Check if RIP is within another PE/COFF image base address
>> + //
>> + if (Rip < ImageBase) {
>> + //
>> + // Search for the respective PE/COFF image based on RIP
>> + //
>
> Thank you
> Yao Jiewen
>
>
>> -----Original Message-----
>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
>> Paulo
>> Alcantara
>> Sent: Thursday, November 16, 2017 9:18 AM
>> To: edk2-devel@lists.01.org
>> Cc: Laszlo Ersek <lersek@redhat.com>; Dong, Eric <eric.dong@intel.com>
>> Subject: [edk2] [RFC v2 1/3] 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 Dong <eric.dong@intel.com>
>> Cc: Laszlo Ersek <lersek@redhat.com>
>> Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
>> ---
>> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c |
>> 369
>> +++++++++++++++++++-
>> 1 file changed, 367 insertions(+), 2 deletions(-)
>>
>> diff --git
>> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
>> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
>> index 65f0cff680..11cd7c9e1c 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.
>> @@ -242,6 +247,350 @@ DumpCpuContext (
>> );
>> }
>>
>> +/**
>> + Get absolute path and file name of PDB file in PE/COFF image.
>> +
>> + @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 = (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 INTN UnwondStacksCount
>> + )
>> +{
>> + //
>> + // Check for proper stack pointer alignment
>> + //
>> + if (((UINTN)CurrentRsp & (CPU_STACK_ALIGNMENT - 1)) != 0) {
>> + InternalPrintMessage ("!!!! Unaligned stack pointer. !!!!\n");
>> + 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)
>> + );
>> +
>> + //
>> + // Point to next stack
>> + //
>> + CurrentRsp += CPU_STACK_ALIGNMENT;
>> + }
>> +}
>> +
>> +/**
>> + 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;
>> +
>> + //
>> + // Check for proper frame pointer alignment
>> + //
>> + if (((UINTN)Rbp & (CPU_STACK_ALIGNMENT - 1)) != 0) {
>> + InternalPrintMessage ("!!!! Unaligned frame pointer. !!!!\n");
>> + return;
>> + }
>> +
>> + //
>> + // 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, &EntryPoint);
>> + if (EFI_ERROR (Status)) {
>> + EntryPoint = NULL;
>> + }
>> +
>> + //
>> + // Get file name and absolute path of initial PDB file
>> + //
>> + GetPdbFileName (ImageBase, &PdbAbsoluteFilePath, &PdbFileName);
>> +
>> + //
>> + // 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);
>> +
>> + //
>> + // If RIP is zero, then stop unwinding the stack
>> + //
>> + if (Rip == 0) {
>> + break;
>> + }
>> +
>> + //
>> + // Check if RIP is within another PE/COFF image base address
>> + //
>> + if (Rip < ImageBase) {
>> + //
>> + // Search for the respective PE/COFF image based on RIP
>> + //
>> + ImageBase = PeCoffSearchImageBase (Rip);
>> + if (ImageBase == 0) {
>> + //
>> + // Stop stack trace
>> + //
>> + break;
>> + }
>> +
>> + //
>> + // Get PE/COFF image's entry point
>> + //
>> + Status = PeCoffLoaderGetEntryPoint ((VOID *)ImageBase,
>> &EntryPoint);
>> + if (EFI_ERROR (Status)) {
>> + EntryPoint = NULL;
>> + }
>> +
>> + //
>> + // Get file name and absolute path of PDB file
>> + //
>> + GetPdbFileName (ImageBase, &PdbAbsoluteFilePath, &PdbFileName);
>> +
>> + //
>> + // Print out image module name (if any)
>> + //
>> + if (PdbAbsoluteFilePath != NULL) {
>> + InternalPrintMessage (
>> + "%a (ImageBase=0x%016lx, EntryPoint=0x%016lx):\n",
>> + PdbFileName,
>> + ImageBase,
>> + (UINTN)EntryPoint
>> + );
>> + InternalPrintMessage ("%a\n", PdbAbsoluteFilePath);
>> + }
>> + }
>> +
>> + //
>> + // Unwind the stack
>> + //
>> + Rbp = *(UINT64 *)(UINTN)Rbp;
>> + }
>> +}
>> +
>> +/**
>> + Dump stack trace.
>> +
>> + @param[in] SystemContext Pointer to EFI_SYSTEM_CONTEXT.
>> + @param[out] UnwondStacksCount Count of unwond stack frames.
>> +**/
>> +STATIC
>> +VOID
>> +DumpStackTrace (
>> + IN EFI_SYSTEM_CONTEXT SystemContext,
>> + OUT INTN *UnwondStacksCount
>> + )
>> +{
>> + UINT64 Rip;
>> + UINT64 Rbp;
>> + UINTN ImageBase;
>> + CHAR8 *PdbFileName;
>> +
>> + //
>> + // 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 backtrace information.
>> !!!!");
>> + return;
>> + }
>> +
>> + //
>> + // Get PDB file name from initial PE/COFF image
>> + //
>> + GetPdbFileName (ImageBase, NULL, &PdbFileName);
>> +
>> + //
>> + // Initialize count of unwond stacks
>> + //
>> + *UnwondStacksCount = 1;
>> +
>> + //
>> + // Print out back trace
>> + //
>> + InternalPrintMessage ("\nCall trace:\n");
>> +
>> + for (;;) {
>> + //
>> + // Print stack frame in the following format:
>> + //
>> + // # <RIP> @ <ImageBase>+<RelOffset> (RBP) in [<ModuleName> | ????]
>> + //
>> + InternalPrintMessage (
>> + "%d 0x%016lx @ 0x%016lx+0x%x (0x%016lx) in %a\n",
>> + *UnwondStacksCount - 1,
>> + Rip,
>> + ImageBase,
>> + Rip - ImageBase - 1,
>> + Rbp,
>> + PdbFileName
>> + );
>> +
>> + //
>> + // Set RIP with return address from current stack frame
>> + //
>> + Rip = *(UINT64 *)((UINTN)Rbp + 8);
>> +
>> + //
>> + // If RIP is zero, then stop unwinding the stack
>> + //
>> + if (Rip == 0) {
>> + break;
>> + }
>> +
>> + //
>> + // Check if RIP is within another PE/COFF image base address
>> + //
>> + if (Rip < ImageBase) {
>> + //
>> + // Search for the respective PE/COFF image based on RIP
>> + //
>> + ImageBase = PeCoffSearchImageBase (Rip);
>> + if (ImageBase == 0) {
>> + //
>> + // Stop stack trace
>> + //
>> + break;
>> + }
>> +
>> + //
>> + // Get PDB file name
>> + //
>> + GetPdbFileName (ImageBase, NULL, &PdbFileName);
>> + }
>> +
>> + //
>> + // Unwind the stack
>> + //
>> + Rbp = *(UINT64 *)(UINTN)Rbp;
>> +
>> + //
>> + // Increment count of unwond stacks
>> + //
>> + (*UnwondStacksCount)++;
>> + }
>> +}
>> +
>> /**
>> Display CPU information.
>>
>> @@ -254,9 +603,25 @@ DumpImageAndCpuContent (
>> IN EFI_SYSTEM_CONTEXT SystemContext
>> )
>> {
>> + INTN UnwondStacksCount;
>> +
>> + //
>> + // Dump CPU context
>> + //
>> DumpCpuContext (ExceptionType, SystemContext);
>> +
>> + //
>> + // Dump stack trace
>> + //
>> + DumpStackTrace (SystemContext, &UnwondStacksCount);
>> +
>> + //
>> + // Dump image module names
>> + //
>> + DumpImageModuleNames (SystemContext);
>> +
>> //
>> - // Dump module image base and module entry point by RIP
>> + // Dump stack contents
>> //
>> - DumpModuleImageInfo (SystemContext.SystemContextX64->Rip);
>> + DumpStackContents (SystemContext.SystemContextX64->Rsp,
>> UnwondStacksCount);
>> }
>> --
>> 2.14.3
>>
>> _______________________________________________
>> edk2-devel mailing list
>> edk2-devel@lists.01.org
>> https://lists.01.org/mailman/listinfo/edk2-devel
>
>
--
Paulo Alcantara, HP Inc.
Speaking for myself only.
next prev parent reply other threads:[~2017-11-16 22:10 UTC|newest]
Thread overview: 82+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-14 12:47 [RFC 0/1] Stack trace support in X64 exception handling Paulo Alcantara
2017-11-14 12:47 ` [RFC 1/1] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support Paulo Alcantara
2017-11-14 14:01 ` Andrew Fish
2017-11-14 14:26 ` 答复: " Fan Jeff
2017-11-14 14:38 ` Andrew Fish
2017-11-14 15:30 ` Paulo Alcantara
2017-11-14 16:51 ` Brian J. Johnson
2017-12-29 3:48 ` [RFC v4 0/6] Stack trace support in X64 exception handling Paulo Alcantara
2017-12-29 4:39 ` [RFC v4 1/6] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support Paulo Alcantara
2018-01-03 8:53 ` 答复: " Fan Jeff
2018-01-03 14:51 ` Paulo Alcantara
2017-12-29 4:39 ` [RFC v4 2/6] UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName() Paulo Alcantara
2017-12-29 4:39 ` [RFC v4 3/6] UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support Paulo Alcantara
2017-12-29 4:39 ` [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add helper to valid memory addresses Paulo Alcantara
2018-01-03 8:42 ` 答复: " Fan Jeff
2018-01-03 14:45 ` Paulo Alcantara
2018-01-03 16:59 ` Brian J. Johnson
2018-01-04 13:03 ` Paulo Alcantara
2018-01-04 1:36 ` Yao, Jiewen
2018-01-04 1:58 ` Yao, Jiewen
2018-01-04 13:29 ` Paulo Alcantara
2018-01-04 14:35 ` Yao, Jiewen
2018-01-04 15:15 ` Paulo Alcantara
2018-01-04 13:18 ` Paulo Alcantara
2017-12-29 4:39 ` [RFC v4 5/6] UefiCpuPkg/CpuExceptionHandlerLib: Ensure valid frame/stack pointers Paulo Alcantara
2018-01-03 8:45 ` 答复: " Fan Jeff
2018-01-03 14:48 ` Paulo Alcantara
2018-01-04 1:07 ` Yao, Jiewen
2017-12-29 4:39 ` [RFC v4 6/6] UefiCpuPkg/CpuExceptionHandlerLib: Correctly print IP addresses Paulo Alcantara
2018-01-03 8:46 ` 答复: " Fan Jeff
2018-01-04 0:59 ` [RFC v4 0/6] Stack trace support in X64 exception handling Yao, Jiewen
2018-01-04 13:36 ` Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 0/8] " Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 1/8] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 2/8] UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName() Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 3/8] UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 4/8] UefiCpuPkg/CpuExceptionHandlerLib: Add helper to validate memory addresses Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 5/8] UefiCpuPkg/CpuExceptionHandlerLib: Ensure valid frame/stack pointers Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 6/8] UefiCpuPkg/CpuExceptionHandlerLib: Correctly print IP addresses Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 7/8] UefiCpuPkg/CpuExceptionHandlerLib: Validate memory address ranges Paulo Alcantara
2018-01-15 0:23 ` [RFC v5 8/8] UefiCpuPkg/CpuExceptionHandlerLib: Add early check in DumpStackContents Paulo Alcantara
2018-01-17 12:57 ` [RFC v5 0/8] Stack trace support in X64 exception handling Yao, Jiewen
2018-01-17 22:48 ` Yao, Jiewen
2018-01-19 0:09 ` Paulo Alcantara
2018-01-19 0:02 ` Paulo Alcantara
2018-01-19 0:15 ` Paulo Alcantara
2018-01-29 13:38 ` Paulo Alcantara
2018-01-31 5:56 ` Yao, Jiewen
2018-01-31 19:05 ` Paulo Alcantara
2017-11-14 13:21 ` [RFC 0/1] " Paulo Alcantara
2017-11-14 14:03 ` 答复: " Fan Jeff
2017-11-14 14:12 ` 答复: " Fan Jeff
2017-11-14 15:37 ` Paulo Alcantara
2017-11-14 16:33 ` Brian J. Johnson
2017-11-14 17:23 ` Andrew Fish
2017-11-14 17:41 ` Brian J. Johnson
2017-11-14 17:56 ` Paulo Alcantara
2017-11-15 13:21 ` 答复: 答复: " Fan Jeff
2017-11-15 14:41 ` Paulo Alcantara
2017-11-15 14:52 ` 答复: " Fan Jeff
2017-11-16 1:18 ` [RFC v2 0/3] " Paulo Alcantara
2017-11-16 1:18 ` [RFC v2 1/3] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support Paulo Alcantara
2017-11-16 1:57 ` Yao, Jiewen
2017-11-16 22:13 ` Paulo Alcantara [this message]
2017-11-17 3:43 ` Yao, Jiewen
2017-11-20 14:51 ` Paulo Alcantara
2017-11-16 15:43 ` Brian J. Johnson
2017-11-16 22:19 ` Paulo Alcantara
2017-11-16 1:18 ` [RFC v2 2/3] UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName() Paulo Alcantara
2017-11-16 1:18 ` [RFC v2 3/3] UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support Paulo Alcantara
2017-11-16 1:46 ` [RFC v2 0/3] Stack trace support in X64 exception handling Paulo Alcantara
2017-11-16 5:01 ` Andrew Fish
2017-11-16 22:02 ` Paulo Alcantara
2017-11-16 21:56 ` [RFC v3 " Paulo Alcantara
2017-11-16 21:56 ` [RFC v3 1/3] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support Paulo Alcantara
2017-11-17 7:24 ` 答复: " Fan Jeff
2017-11-20 14:59 ` Paulo Alcantara
2017-11-23 14:27 ` 答复: " Fan Jeff
2017-11-23 18:34 ` Andrew Fish
2017-11-23 19:49 ` Fan Jeff
2017-11-16 21:56 ` [RFC v3 2/3] UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName() Paulo Alcantara
2017-11-16 21:56 ` [RFC v3 3/3] UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support Paulo Alcantara
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f2bb8a290f25b5989fb6026944b0709f.squirrel@www.zytor.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox