Re: [edk2] UEFI Shell + startup.nsh

2019-01-24 Thread Paulo Alcantara
Rafael Machado  writes:

> I have a question.
> Considering I have a PXE server that my client downloads a shell.efi app.
> Considering also that  I need to execute a .nsh script, but I their is no
> media at the system.  (no usb or storage device attached)
>
> Is there any way to embed a startup.nsh at the shell.efi application?
> As far as I know with PXE just one file is downloaded and executed. (I am
> also checking how to use the EfiRamDisk protocol to create a temporary
> place for the .nsh generated files.)

You'd probably need to format your UEFI RAM disk with an FAT file
system, download the .nsh script into it, then UEFI shell application
would look for the startup script and then execute it.

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


Re: [edk2] [PATCH v3 1/3] MdeModulePkg/UdfDxe: Check 'Component Type' within a Path Component

2018-10-29 Thread Paulo Alcantara
Hi Hao Wu,

On October 29, 2018 10:26:15 PM GMT-03:00, Hao Wu  wrote:
>REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1279
>
>According to the ECMA-167 standard (3rd Edition - June 1997), Section
>14.16.1.1, valid values are 1 to 5. All other values will be treated as
>a
>corrupted volume.
>
>This commit will add such check within function ResolveSymlink().
>
>Cc: Leif Lindholm 
>Cc: Ruiyu Ni 
>Contributed-under: TianoCore Contribution Agreement 1.1
>Signed-off-by: Hao Wu 
>Reviewed-by: Paulo Alcantara 
>Reviewed-by: Star Zeng 
>---
> MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 7 +++
> 1 file changed, 7 insertions(+)
>
>diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>index b9ebddfe62..c15741a032 100644
>--- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>+++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>@@ -2257,6 +2257,13 @@ ResolveSymlink (
>   }
>   FileName[Index] = L'\0';
>   break;
>+default:
>+  //
>+  // Accoring to the ECMA-167 standard (3rd Edition - June 1997),
>Section

Minor typo: s/Accoring/According/

Paulo

>+  // 14.16.1.1, all other values are reserved.
>+  //
>+  Status = EFI_VOLUME_CORRUPTED;
>+  goto Error_Find_File;
> }
> 
> //

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] [PATCH] MdeModulePkg/UdfDxe: Additional checks for ResolveSymlink()

2018-10-26 Thread Paulo Alcantara
Hao Wu  writes:

> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1279
>
> The commit will add 3 types of checks for function ResolveSymlink():
>
> A. Check for the value of 'Component Type' field within a Path Component
>
> According to the ECMA-167 standard (3rd Edition - June 1997), Section
> 14.16.1.1, valid values are 1 to 5. All other values will be treated as a
> corrupted volume.
>
> B. Check for the content pointed by 'File'
>
> Since content within 'File' is the output data for ResolveSymlink().
> Checks is added to ensure the content in 'File' is valid. Otherwise,
> possible null pointer dereference issue will occur during the subsequent
> usage of the data returned by ResolveSymlink().
>
> C. Check for possible memory double free/use after free case
>
> For codes:
>
> if (CompareMem ((VOID *), (VOID *)Parent,
> sizeof (UDF_FILE_INFO)) != 0) {
>   CleanupFileInformation ();
> }
>
> CopyMem ((VOID *), (VOID *)File, sizeof (UDF_FILE_INFO));
>
> If the contents in 'PreviousFile' and 'File' are the same, call to
> "CleanupFileInformation ();" will free the buffers in 'File'
> as well. This will lead to potential memory double free/use after free
> issues.
>
> Cc: Paulo Alcantara 
> Cc: Paulo Alcantara 
> Cc: Ruiyu Ni 
> Cc: Star Zeng 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Hao Wu 
> ---
>  .../Universal/Disk/UdfDxe/FileSystemOperations.c   | 30 
> --
>  1 file changed, 28 insertions(+), 2 deletions(-)
>
> diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c 
> b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> index b9ebddfe62..a89e5ba9ff 100644
> --- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> +++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
> @@ -2145,6 +2145,8 @@ ResolveSymlink (
>UINT8   CompressionId;
>UDF_FILE_INFO   PreviousFile;
>  
> +  ZeroMem ((VOID *)File, sizeof (UDF_FILE_INFO));
> +
>//
>// Symlink files on UDF volumes do not contain so much data other than
>// Path Components which resolves to real filenames, so it's OK to read in
> @@ -2257,6 +2259,13 @@ ResolveSymlink (
>}
>FileName[Index] = L'\0';
>break;
> +default:
> +  //
> +  // Accoring to the ECMA-167 standard (3rd Edition - June 1997), Section
> +  // 14.16.1.1, all other values are reserved.
> +  //
> +  Status = EFI_VOLUME_CORRUPTED;
> +  goto Error_Find_File;
>  }
>  
>  //
> @@ -2281,8 +2290,18 @@ ResolveSymlink (
>break;
>  }
>  
> -if (CompareMem ((VOID *), (VOID *)Parent,
> -sizeof (UDF_FILE_INFO)) != 0) {
> +//
> +// Check the content in the file info pointed by File.
> +//
> +if ((File->FileEntry == NULL) || (File->FileIdentifierDesc == NULL)) {
> +  Status = EFI_VOLUME_CORRUPTED;
> +  goto Error_Find_File;
> +}
> +
> +if ((CompareMem ((VOID *), (VOID *)Parent,
> +sizeof (UDF_FILE_INFO)) != 0) &&
> +(CompareMem ((VOID *), (VOID *)File,
> +sizeof (UDF_FILE_INFO)) != 0)) {
>CleanupFileInformation ();
>  }
>  
> @@ -2294,6 +2313,13 @@ ResolveSymlink (
>    //
>FreePool (ReadFileInfo.FileData);
>  
> +  //
> +  // Check the content in the resolved file info.
> +  //
> +  if ((File->FileEntry == NULL) || (File->FileIdentifierDesc == NULL)) {
> +return EFI_VOLUME_CORRUPTED;
> +  }
> +
>return EFI_SUCCESS;
>  
>  Error_Find_File:

Reviewed-by: Paulo Alcantara 

Thanks!
Paulo
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] [PATCH v1 00/10] UDF: Bugfixes

2018-10-22 Thread Paulo Alcantara
Hao Wu  writes:

> The series will address a couple of bugs within the UDF related codes.
>
> Please refer to the log message of each commit for more details.
>
> Cc: Paulo Alcantara 
> Cc: Ruiyu Ni 
> Cc: Jiewen Yao 
> Cc: Star Zeng 
>
> Hao Wu (10):
>   MdeModulePkg/PartitionDxe: Add check for underlying device block size
>   MdeModulePkg/UdfDxe: Refine boundary checks for file/path name string
>   MdeModulePkg/UdfDxe: Add boundary check the read of FE/EFE
>   MdeModulePkg/UdfDxe: Add boundary check for ComponentIdentifier decode
>   MdeModulePkg/UdfDxe: Add boundary check for getting volume (free) size
>   MdeModulePkg/UdfDxe: Correct behavior for UdfSetPosition()
>   MdeModulePkg/UdfDxe: Fix a typo within SetFileInfo()
>   MdeModulePkg/UdfDxe: Update GetInfo() for FS VolumeLabel info request
>   MdeModulePkg/UdfDxe: Add more check when getting PD from LongAd
>   MdeModulePkg/UdfDxe: Avoid possible use of already-freed data
>
>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c|  28 +++
>  MdeModulePkg/Universal/Disk/UdfDxe/File.c |  96 
>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 253 
> ++--
>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  |  63 -
>  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf |   1 +
>  5 files changed, 362 insertions(+), 79 deletions(-)

For the series:

Reviewed-by: Paulo Alcantara 

Thanks!
Paulo
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] [PATCH v1 0/7] Code refinements in UdfDxe

2018-10-15 Thread Paulo Alcantara
Hi,

Hao Wu  writes:

> This series will refine the codes in MdeModulePkg/Universal/Disk/UdfDxe
> for:
>
> A. Refine asserts used for memory allocation failure and error cases that
>are possible to happen. Will use error handling logic for them;
>
> B. Address some dead codes within this module.
>
> Cc: Paulo Alcantara 
> Cc: Ruiyu Ni 
> Cc: Star Zeng 
>
> Hao Wu (7):
>   MdeModulePkg/UdfDxe: Use error handling for memory allocation failure
>   MdeModulePkg/UdfDxe: ASSERT for false positives of NULL ptr deref
>   MdeModulePkg/UdfDxe: Use error handling when fail to return LSN
>   MdeModulePkg/UdfDxe: Use debug msg instead of ASSERT in UdfOpen()
>   MdeModulePkg/UdfDxe: Handle dead codes in File.c
>   MdeModulePkg/UdfDxe: Remove dead codes in FileName.c
>   MdeModulePkg/UdfDxe: Handle dead codes in FileSystemOperations.c
>
>  MdeModulePkg/Universal/Disk/UdfDxe/File.c |  19 ++-
>  MdeModulePkg/Universal/Disk/UdfDxe/FileName.c |  15 --
>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 162 
> +++-
>  3 files changed, 142 insertions(+), 54 deletions(-)

Looks good to me. Thanks!

For the series:

Reviewed-by: Paulo Alcantara 

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


Re: [edk2] [RFC v5 0/8] Stack trace support in X64 exception handling

2018-01-31 Thread Paulo Alcantara
"Yao, Jiewen"  writes:

Hi Jiewen,

> ===
> OVMF IA32: DXE worked, but SMM not.
>
> Since the page fault is only occurring in IA32 with no paging enabled 
> (default case), I suspect that when we don't have paging, we are unable 
> to successfully validate the memory address when it's i.e. outside SMRAM 
> - that is, we don't know when to stop unwinding the stack.
> ===
>
> For IA32 SMM, I am a little confused.
> We unconditionally setup page table for SMM, no matter it is IA32 or X64.
>
> If you find a SMM driver running in a page-disable environment, it means, the 
> SMM CORE load the driver in SMRAM, but the SMM CPU driver has not rebased the 
> CPU yet.
> SMM driver is still using the PageTable/GDT/IDT setup by DXE CPU
> driver, not SMM CPU driver.

OK - thanks for clarifying that.

> Would you please double confirm what you have observed?
>
> You can just check the boot log file to see if PiSmmCpu driver has run
> or not.

Sure. I will do it and then get back to you once I got the results.

Thanks
Paulo
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] [RFC v5 0/8] Stack trace support in X64 exception handling

2018-01-29 Thread Paulo Alcantara
ers and, when we find an 
invalid return address (e.g. last valid frame), we stop the trace. With 
that, SMM is now working in X64.


Since the page fault is only occurring in IA32 with no paging enabled 
(default case), I suspect that when we don't have paging, we are unable 
to successfully validate the memory address when it's i.e. outside SMRAM 
- that is, we don't know when to stop unwinding the stack.


Any ideas on what might be causing that?

Other than that, I'll try to do some more tests this weekend and come 
back with the results. (That's why I didn't send out the v6 yet)


Repo:   https://git.paulo.ac/pub/edk2.git
Branch: stacktrace_v6

Thanks
Paulo




Thank you
Yao Jiewen


-Original Message-
From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Paulo
Alcantara
Sent: Monday, January 15, 2018 8:23 AM
To: edk2-devel@lists.01.org
Cc: Rick Bramley <richard.bram...@hp.com>; Dong, Eric
<eric.d...@intel.com>; Kimon Berlin <kimon.ber...@hp.com>; Andrew Fish
<af...@apple.com>; Yao, Jiewen <jiewen@intel.com>; Diego Medaglia
<diego.meag...@hp.com>; Laszlo Ersek <ler...@redhat.com>
Subject: [edk2] [RFC v5 0/8] Stack trace support in X64 exception handling

Hi,

This series adds stack trace support during IA32 and X64 CPU exceptions.

Informations like back trace, stack contents and image module names
(that were part of the call stack) will be dumped out.

The current limitation is that it relies on available frame pointers
(GCC only) in order to successfully unwind the stack.

Jiewen,

Thank you very much for your time on this. I've applied the changes you
suggested, as well as tested it on IA32 PAE paging mode - it worked as
expected.

Other than that, I also tested the stack trace in SMM code by manually
calling CpuBreakPoint() and then it broke with another exception
(page fault). I didn't have much time to look into that, but what I've
observed is that the page fault ocurred during the search of PE/COFF
image base address (in PeCoffSearchImageBase). The function attempts to
search for the image base from "Address" through 0, so any of those
dereferenced addresses triggers the page fault.

Do you know how we could fix that issue? Perhaps introducing a
AddressValidationLib (as Brian suggested previously) and use it within
PeCoffSearchImageBase()?

I'd also like to thank Brian & Jeff for all the support!

Thanks
Paulo

Repo:   https://github.com/pcacjr/edk2.git
Branch: stacktrace_v5

Cc: Rick Bramley <richard.bram...@hp.com>
Cc: Kimon Berlin <kimon.ber...@hp.com>
Cc: Diego Medaglia <diego.meag...@hp.com>
Cc: Andrew Fish <af...@apple.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Brian Johnson <brian.john...@hpe.com>
Cc: Jeff Fan <vanjeff_...@hotmail.com>
Cc: Jiewen Yao <jiewen@intel.com>
Cc: Paulo Alcantara <pa...@hp.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---

v1 -> v2:
   * Add IA32 arch support (GCC toolchain only)
   * Replace hard-coded stack alignment value (16) with
 CPU_STACK_ALIGNMENT.
   * Check for proper stack and frame pointer alignments.
   * Fix initialization of UnwoundStacksCount to 1.
   * Move GetPdbFileName() to common code since it will be used by both
 IA32 and X64 implementations.

v2 -> v3:
   * Fixed wrong assumption about "RIP < ImageBase" to start searching
 for another PE/COFF image. That is, RIP may point to lower and
 higher addresses for any other PE/COFF images. Both IA32 & X64.
 (Thanks Andrew & Jiewen)
   * Fixed typo: unwond -> unwound. Both IA32 & X64. (Thanks Brian)

v3 -> v4:
   * Validate all frame/stack pointer addresses before dereferencing them
 as requested by Brian & Jiewen.
   * Correctly print out IP addresses during the stack traces (by Jeff)

v4 -> v5:
   * Fixed address calculations and improved code as suggested by Jiewen.
   * Fixed parameter validation as suggested by Brian.
   * Tested stack stack with IA32 PAE paging mode.

Paulo Alcantara (8):
   UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
   UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName()
   UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support
   UefiCpuPkg/CpuExceptionHandlerLib: Add helper to validate memory
 addresses
   UefiCpuPkg/CpuExceptionHandlerLib: Ensure valid frame/stack pointers
   UefiCpuPkg/CpuExceptionHandlerLib: Correctly print IP addresses
   UefiCpuPkg/CpuExceptionHandlerLib: Validate memory address ranges
   UefiCpuPkg/CpuExceptionHandlerLib: Add early check in
 DumpStackContents

  UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
| 537 ++--
  UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
|  59 ++-
  UefiCpuPkg/Library/CpuEx

Re: [edk2] DMA Buffer write operation not persisted

2018-01-25 Thread Paulo Alcantara


On January 25, 2018 4:53:06 PM GMT-02:00, Rafael Machado 
 wrote:
>Hi everyone.
>
>I'm currently work on a task, and I need to write some data at a DMA
>buffer.
>At the UEFI Driver Writer's guide, at page 359 there is a sample code
>of
>how to do that.
>
>Considering that code and adapting to my scenario I got the following
>function (some debug prints are present for clarification):
>
>EFI_STATUS
>EFIAPI
>DoBusMasterWrite (
>  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciIo,
>  IN UINT8 *HostAddress,
>  IN UINTN *Length,
>  IN UINT32 Value
>)
>{
>  EFI_STATUS Status;
>  UINTN NumberOfBytes;
>  EFI_PHYSICAL_ADDRESS DeviceAddress;
>  VOID *Mapping;
>  UINT64 ReadValue;
>
>  //
>  // Call Map() to retrieve the DeviceAddress to use for the bus
>  // master write operation. The Map() function may not support
>  // performing a DMA operation for the entire length, so it may
>  // be broken up into smaller DMA operations.
>  //
>  NumberOfBytes = *Length;
>  Status = PciIo->Map (PciIo, // This
>
> EfiPciIoOperationBusMasterCommonBuffer, // Operation
>(VOID *)HostAddress, // HostAddress
> , // NumberOfBytes
> , //DeviceAddress
>  //Mapping);
>
>  if (EFI_ERROR (Status)) {
>return Status;
>  }
>
>  //
>  // Write the data to the desired address
>  // This write operation also starts the DMA transaction
>  //
>  Status = PciIo->Mem.Write (PciIo, // This
>  EfiPciIoWidthUint32, // Width
>   *HostAddress,
>   1, // Count
>// Buffer
>   );

I'm not sure, but I think you're passing the wrong value to the 3rd parameter 
(Address). Shouldn't that be "(UINT64)(UINTN)HostAddress"?

Paulo

>
>  Print(L"NumberOfBytes: %d\r\n", NumberOfBytes);
>  Print(L"address: 0x%x\r\n", HostAddress);
>  Print(L"Value: 0x%x\r\n", Value);
>  Print(L"Status: %r\r\n", Status);
>
>  if (EFI_ERROR (Status)) {
>return Status;
>  }
>
>  //
>  // The operations performed by PollMem() also flush all posted
>  // writes from the PCI bus master and through PCI-to-PCI bridges.
>  //
>  Status = PciIo->PollMem (PciIo, // This
>  EfiPciIoWidthUint32, // Width
>   *HostAddress, // Offset
>   0x,// Mask
>   Value,// Value
>   EFI_TIMER_PERIOD_SECONDS
>(1), // Timeout
>// Result
>   );
>  Print(L"Status2: %r\r\n", Status);
>
>  if (EFI_ERROR (Status)) {
>return Status;
>  }
>
>  //
>  // Call Flush() to flush all write transactions to system memory
>  //
>  Status = PciIo->Flush (PciIo);
>  Print(L"Status3: %r\r\n", Status);
>
>  if (EFI_ERROR (Status)) {
>return Status;
>  }
>
>  //
>  // Call Unmap() to complete the bus master write operation
>  //
>  Status = PciIo->Unmap (PciIo, Mapping);
>  Print(L"Status4: %r\r\n", Status);
>
>  if (EFI_ERROR (Status)) {
>return Status;
>  }
>  return Status;
>}
>
>The output of this function is this:
>  NumberOfBytes: 4
>  address: 0xCCCAC000
>  Value: 0xA
>  Status: Success
>  Status2: Success
>  Status3: Success
>  Status4: Success
>
>The problem is that when I try to read this memory content using the
>dmem
>command at the efiShell the value 0xA cannot be found. Seems
>something
>is locking the DMA trasaction.
>Can someone give me some light?
>
>Thanks and Regard
>Rafael R. Machado
>___
>edk2-devel mailing list
>edk2-devel@lists.01.org
>https://lists.01.org/mailman/listinfo/edk2-devel

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] EDK II debug question

2018-01-22 Thread Paulo Alcantara

On 1/20/2018 4:58 AM, JUNWEN JIA wrote:


Hi:
 Could you please tell how to build assembly language using EDK2?
I tried to create a .c file in AppPkg, but it goes like this:
#include
Void main()
{
_asm{}
}
I used X64 to compile this project, but it seems content like _asm{} is not 
supported.
Do I need to add extra files? And  where should I add them?


AFAIK, inline assembly is not supported in X64 MSFT compiler.

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


Re: [edk2] [RFC v5 0/8] Stack trace support in X64 exception handling

2018-01-18 Thread Paulo Alcantara
Paulo Alcantara <pa...@paulo.ac> writes:

>> 3) I am a little surprised on PeCoffSearchImageBase() issue.
>>
>> We have 4 PeCoffSearchImageBase() call in each arch. DumpImageModuleNames() 
>> calls twice and DumpStacktrace() calls twice.
>> Do you know which specific one triggers the zero address #PF issue?
>>
>>   
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\Ia32\ArchExceptionHandler.c(547):
>>   ImageBase = PeCoffSearchImageBase (Eip);
>>   
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\Ia32\ArchExceptionHandler.c(613):
>> ImageBase = PeCoffSearchImageBase (Eip);
>>   
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\Ia32\ArchExceptionHandler.c(682):
>>   ImageBase = PeCoffSearchImageBase (Eip);
>>   
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\Ia32\ArchExceptionHandler.c(741):
>> ImageBase = PeCoffSearchImageBase (Eip);
>>   
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchExceptionHandler.c(540):
>>   ImageBase = PeCoffSearchImageBase (Rip);
>>   
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchExceptionHandler.c(613):
>> ImageBase = PeCoffSearchImageBase (Rip);
>>   
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchExceptionHandler.c(710):
>>   ImageBase = PeCoffSearchImageBase (Rip);
>>   
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\ArchExceptionHandler.c(779):
>> ImageBase = PeCoffSearchImageBase (Rip);
>>
>
> When I saw the #PF when testing stack trace in SMM, I was running out of
> time and I just saved the log file with the trace. I'm attaching the
> log for you, but I'm still going to look into that issue when time
> permits.

Forgot to attach the log file. Done. :-)
 X64 Exception Type - 03(#BP - Breakpoint)  CPU Apic ID -  
RIP  - 7FF48151, CS  - 0038, RFLAGS - 0046
RAX  - , RCX - 7FEBB020, RDX - 0004
RBX  - , RSP - 7FF7B760, RBP - 7FF7B760
RSI  - 7FF44018, RDI - 7FEBB018
R8   - 00FF, R9  - 00048400, R10 - 00C9
R11  - 0069, R12 - , R13 - 
R14  - , R15 - 
DS   - 0020, ES  - 0020, FS  - 0020
GS   - 0020, SS  - 0020
CR0  - 80010033, CR2 - , CR3 - 7FF6C000
CR4  - 0668, CR8 - 
DR0  - , DR1 - , DR2 - 
DR3  - , DR6 - 0FF0, DR7 - 0400
GDTR - 7FF6B000 004F, LDTR - 
IDTR - 7FF75000 01FF,   TR - 0040
FXSAVE_STATE - 7FF7B3C0

Call trace:
0 0x7FF48151 @ 0x7FF46000+0x2151 (0x7FF7B760) in 
VariableSmm.dll
1 0x7FF54E35 @ 0x7FF46000+0xEE35 (0x7FF7B7D0) in 
VariableSmm.dll
2 0x7FF5659E @ 0x7FF46000+0x1059E (0x7FF7B800) in 
VariableSmm.dll
3 0x7FF4BCFE @ 0x7FF46000+0x5CFE (0x7FF7B840) in 
VariableSmm.dll
4 0x7FFE9BFA @ 0x7FFDB000+0xEBFA (0x7FF7B8A0) in 
PiSmmCore.dll
5 0x7FFEAAC4 @ 0x7FFDB000+0xFAC4 (0x7FF7B9C0) in 
PiSmmCore.dll
6 0x7FFEADD1 @ 0x7FFDB000+0xFDD1 (0x7FF7BA20) in 
PiSmmCore.dll
7 0x7FFE43F8 @ 0x7FFDB000+0x93F8 (0x7FF7BA90) in 
PiSmmCore.dll
8 0x7FFA8B9A @ 0x7FF9C000+0xCB9A (0x7FF7BD50) in 
PiSmmCpuDxeSmm.dll
9 0x7FFA9E92 @ 0x7FF9C000+0xDE92 (0x7FF7BDC0) in 
PiSmmCpuDxeSmm.dll
 X64 Exception Type - 0E(#PF - Page-Fault)  CPU Apic ID -  
ExceptionData -   I:0 R:0 U:0 W:0 P:0 PK:0 S:0
RIP  - 7FFA1BBE, CS  - 0038, RFLAGS - 00010006
RAX  - 7FF89FFC, RCX - 7FF8E149, RDX - 
RBX  - , RSP - 7FF7B1A0, RBP - 7FF7B1E0
RSI  - 7FFA9E92, RDI - 7FF9C000
R8   - 0001, R9  - , R10 - 
R11  - 0069, R12 - , R13 - 
R14  - , R15 - 
DS   - 0020, ES  - 0020, FS  - 0020
GS   - 0020, SS  - 0020
CR0  - 80010033, CR2 - 7FF89FFC, CR3 - 7FF6C000
CR4  - 0668, CR8 - 
DR0  - , DR1 - , DR2 - 
DR3  - , DR6 - 0FF0, DR7 - 000

Re: [edk2] [RFC v5 0/8] Stack trace support in X64 exception handling

2018-01-18 Thread Paulo Alcantara
Hi Jiewen,

"Yao, Jiewen" <jiewen@intel.com> writes:

> I have some more thought on #3 for your consideration.
>
> Given the situation that we are doing heap guard feature, a *valid*
> EIP address might not be enough to guarantee the address is inside of
> an *executable* page.

OK.

>
> I am thinking if we need check the non-executable bit (BIT63) as well for 
> DumpImageModuleNames(). (No need for DumpStacktrace()).
> We can add IsLogicalAddressExecutable() on top of
> IsLogicalAddressValid().

OK. I can do that.

> Also I do not object the idea to add check inside of PeCoffSearchImageBase().
> I am thinking in another way - we can let *caller* to input a validation 
> function for the PeCoffLib, instead of let PeCoffLib depend on another 
> library.
>
> For example:
> PeCoffSearchImageBaseEx (Address, ValidateAddressFunc)

Looks good to me! Whether or not we're making it into a external library
in the future, we should at least get it working and well tested for the
stack trace support.

Thanks!
Paulo

>> -Original Message-
>> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Yao,
>> Jiewen
>> Sent: Wednesday, January 17, 2018 8:57 PM
>> To: Paulo Alcantara <pa...@paulo.ac>; edk2-devel@lists.01.org
>> Cc: Rick Bramley <richard.bram...@hp.com>; Dong, Eric
>> <eric.d...@intel.com>; Kimon Berlin <kimon.ber...@hp.com>; Andrew Fish
>> <af...@apple.com>; Diego Medaglia <diego.meag...@hp.com>; Laszlo Ersek
>> <ler...@redhat.com>
>> Subject: Re: [edk2] [RFC v5 0/8] Stack trace support in X64 exception 
>> handling
>> 
>> Thanks Paulo.
>> 
>> The series looks really good. I give it thumb up. :-)
>> 
>> The 8 patches keep updating 4 files, so I squash them when I review. The
>> comment below is for the final code, not for a specific patch.
>> 
>> 1) CpuExceptionCommon.c: IsLinearAddressRangeValid().
>>   //
>>   // Check for valid input parameters
>>   //
>>   if (LinearAddressStart == 0 || LinearAddressEnd == 0 ||
>>   LinearAddressStart > LinearAddressEnd) {
>> return FALSE;
>>   }
>> 
>> I think LinearAddressStart is a valid case. In BIOS, we do update IVT in 0 
>> address
>> when CSM is enabled.
>> I do not think we need exclude it here. If we enabled ZeroPointer 
>> protection, it
>> can be excluded in page table parsing.
>> 
>> 2) I found below logic appears in 2 functions - DumpImageModuleNames() and
>> DumpStacktrace(). Is that possible to merge them?
>> We can calculate in DumpImageAndCpuContent() and use Eip as parameter. Just
>> in case there is 3rd function need use EIP, it won't miss the calculation.
>> (It is a bug fix we did recently.)
>> 
>>   //
>>   // Set current EIP address
>>   //
>>   if ((ExceptionType == EXCEPT_IA32_PAGE_FAULT) &&
>>   ((SystemContext.SystemContextIa32->ExceptionData &
>> IA32_PF_EC_ID) != 0)) {
>> //
>> // The EIP in SystemContext could not be used
>> // if it is page fault with I/D set.
>> //
>> Eip = *(UINT32 *)(UINTN)SystemContext.SystemContextIa32->Esp;
>>   } else {
>> Eip = SystemContext.SystemContextIa32->Eip;
>>   }
>> 
>> 3) I am a little surprised on PeCoffSearchImageBase() issue.
>> 
>> We have 4 PeCoffSearchImageBase() call in each arch.
>> DumpImageModuleNames() calls twice and DumpStacktrace() calls twice.
>> Do you know which specific one triggers the zero address #PF issue?
>> 
>> 
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\Ia32\Arch
>> ExceptionHandler.c(547):  ImageBase = PeCoffSearchImageBase (Eip);
>> 
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\Ia32\Arch
>> ExceptionHandler.c(613):ImageBase = PeCoffSearchImageBase (Eip);
>> 
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\Ia32\Arch
>> ExceptionHandler.c(682):  ImageBase = PeCoffSearchImageBase (Eip);
>> 
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\Ia32\Arch
>> ExceptionHandler.c(741):ImageBase = PeCoffSearchImageBase (Eip);
>> 
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\Arch
>> ExceptionHandler.c(540):  ImageBase = PeCoffSearchImageBase (Rip);
>> 
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\Arch
>> ExceptionHandler.c(613):ImageBase = PeCoffSearchImageBase (Rip);
>> 
>> C:\home\EdkIIGit\edk2\UefiCpuPkg\Library\CpuExceptionHandlerLib\X64\Arch
>> ExceptionHandl

Re: [edk2] [RFC v5 0/8] Stack trace support in X64 exception handling

2018-01-18 Thread Paulo Alcantara
 EIP is zero, then stop unwinding the stack
> //
> if (Eip == 0) {
>   break;
> }
>
> //
> // Search for the respective PE/COFF image based on EIP
> //
> ImageBase = PeCoffSearchImageBase (Eip);

I think so. There is no guarantee that the return address (Eip) will be
valid even if we're handling a valid frame pointer. It might get
corrupted at some point. Thanks for pointing it out! I'll validate
them.

> If you can help us do some more investigation on the root-cause and narrow 
> down the issue, I will appreciate that.
>
> We can decide how to fix once it is root-caused.

Sure. I will.

Thanks for the comments! I learnt a lot of with them :-)

Paulo

>
>> -Original Message-
>> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Paulo
>> Alcantara
>> Sent: Monday, January 15, 2018 8:23 AM
>> To: edk2-devel@lists.01.org
>> Cc: Rick Bramley <richard.bram...@hp.com>; Dong, Eric
>> <eric.d...@intel.com>; Kimon Berlin <kimon.ber...@hp.com>; Andrew Fish
>> <af...@apple.com>; Yao, Jiewen <jiewen@intel.com>; Diego Medaglia
>> <diego.meag...@hp.com>; Laszlo Ersek <ler...@redhat.com>
>> Subject: [edk2] [RFC v5 0/8] Stack trace support in X64 exception handling
>> 
>> Hi,
>> 
>> This series adds stack trace support during IA32 and X64 CPU exceptions.
>> 
>> Informations like back trace, stack contents and image module names
>> (that were part of the call stack) will be dumped out.
>> 
>> The current limitation is that it relies on available frame pointers
>> (GCC only) in order to successfully unwind the stack.
>> 
>> Jiewen,
>> 
>> Thank you very much for your time on this. I've applied the changes you
>> suggested, as well as tested it on IA32 PAE paging mode - it worked as
>> expected.
>> 
>> Other than that, I also tested the stack trace in SMM code by manually
>> calling CpuBreakPoint() and then it broke with another exception
>> (page fault). I didn't have much time to look into that, but what I've
>> observed is that the page fault ocurred during the search of PE/COFF
>> image base address (in PeCoffSearchImageBase). The function attempts to
>> search for the image base from "Address" through 0, so any of those
>> dereferenced addresses triggers the page fault.
>> 
>> Do you know how we could fix that issue? Perhaps introducing a
>> AddressValidationLib (as Brian suggested previously) and use it within
>> PeCoffSearchImageBase()?
>> 
>> I'd also like to thank Brian & Jeff for all the support!
>> 
>> Thanks
>> Paulo
>> 
>> Repo:   https://github.com/pcacjr/edk2.git
>> Branch: stacktrace_v5
>> 
>> Cc: Rick Bramley <richard.bram...@hp.com>
>> Cc: Kimon Berlin <kimon.ber...@hp.com>
>> Cc: Diego Medaglia <diego.meag...@hp.com>
>> Cc: Andrew Fish <af...@apple.com>
>> Cc: Eric Dong <eric.d...@intel.com>
>> Cc: Laszlo Ersek <ler...@redhat.com>
>> Cc: Brian Johnson <brian.john...@hpe.com>
>> Cc: Jeff Fan <vanjeff_...@hotmail.com>
>> Cc: Jiewen Yao <jiewen@intel.com>
>> Cc: Paulo Alcantara <pa...@hp.com>
>> Contributed-under: TianoCore Contribution Agreement 1.1
>> Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
>> ---
>> 
>> v1 -> v2:
>>   * Add IA32 arch support (GCC toolchain only)
>>   * Replace hard-coded stack alignment value (16) with
>> CPU_STACK_ALIGNMENT.
>>   * Check for proper stack and frame pointer alignments.
>>   * Fix initialization of UnwoundStacksCount to 1.
>>   * Move GetPdbFileName() to common code since it will be used by both
>> IA32 and X64 implementations.
>> 
>> v2 -> v3:
>>   * Fixed wrong assumption about "RIP < ImageBase" to start searching
>> for another PE/COFF image. That is, RIP may point to lower and
>> higher addresses for any other PE/COFF images. Both IA32 & X64.
>> (Thanks Andrew & Jiewen)
>>   * Fixed typo: unwond -> unwound. Both IA32 & X64. (Thanks Brian)
>> 
>> v3 -> v4:
>>   * Validate all frame/stack pointer addresses before dereferencing them
>> as requested by Brian & Jiewen.
>>   * Correctly print out IP addresses during the stack traces (by Jeff)
>> 
>> v4 -> v5:
>>   * Fixed address calculations and improved code as suggested by Jiewen.
>>   * Fixed parameter validation as suggested by Brian.
>>   * Tested stack stack wi

[edk2] [RFC v5 4/8] UefiCpuPkg/CpuExceptionHandlerLib: Add helper to validate memory addresses

2018-01-14 Thread Paulo Alcantara
Introduce IsLinearAddressValid() function that will be used for
validating memory addresses that would get dereferenced during stack
traces in IA32 and X64 CPU exceptions.

Contributed-under: TianoCore Contribution Agreement 1.1
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Requested-by: Brian Johnson <brian.john...@hpe.com>
Requested-by: Jiewen Yao <jiewen@intel.com>
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c | 395 

 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h |  16 +
 2 files changed, 411 insertions(+)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index 66892320c8..7ac13640de 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -14,6 +14,8 @@
 
 #include "CpuExceptionCommon.h"
 
+#include 
+
 //
 // Error code flag indicating whether or not an error code will be
 // pushed on the stack if an exception occurs.
@@ -59,6 +61,24 @@ CONST CHAR8 *mExceptionNameStr[] = {
 //
 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mUnknownPdbFileName = "";
 
+//
+// IA32 virtual memory bit definitions
+//
+#define IA32_PG_P   BIT0
+#define IA32_PG_PS  BIT7
+
+//
+// IA32 control register bit definitions
+//
+#define IA32_CR0_PG   BIT31
+#define IA32_CR4_PAE  BIT5
+#define IA32_CR0_PE   BIT0
+
+//
+// IA32 CPUID 01h EDX bit definitions
+//
+#define IA32_CPUID1_EDX_PAE BIT6
+
 /**
   Get ASCII format string exception name by exception type.
 
@@ -194,3 +214,378 @@ GetPdbFileName (
 }
   }
 }
+
+/**
+  Check if a linear address is valid by walking the page tables in 4-level
+  paging mode.
+
+  @param[in]  Cr3 CR3 control register.
+  @param[in]  MaxPhyAddrBits  MAXPHYADDR bits.
+  @param[in]  LinearAddress   Linear address to be checked.
+**/
+STATIC
+BOOLEAN
+Do4LevelPagingModeCheck (
+  IN UINTNCr3,
+  IN UINT8MaxPhyAddrBits,
+  IN UINTNLinearAddress
+  )
+{
+  UINT64  PhysicalAddressMask;
+  UINTN   IndexMask;
+  UINTN   Index;
+  UINT64  *Pml4Table;
+  UINT64  *TableEntry;
+  UINT64  *PageDirPtrTable;
+  UINT64  *PageDirTable;
+  UINT64  *PageTable;
+
+  //
+  // In 4-level paging mode, linear addresses are 48 bits wide
+  //
+  if ((UINT64)LinearAddress > 0xULL) {
+return FALSE;
+  }
+
+  //
+  // Calculate physical address mask (bits M-1:12)
+  //
+  PhysicalAddressMask = (LShiftU64 (1, MaxPhyAddrBits) - 1) & ~0xFFF;
+  //
+  // 9 bits for masking page table indexes out of linear addresses
+  //
+  IndexMask = 0x1FF;
+
+  //
+  // Calculate physical address of PML4 table and index of PML4E
+  //
+  Pml4Table = (UINT64 *)(UINTN)((UINT64)Cr3 & PhysicalAddressMask);
+  Index = (UINTN)(RShiftU64 ((UINT64)LinearAddress, 39) & IndexMask);
+
+  //
+  // Select PML4E
+  //
+  TableEntry = [Index];
+
+  //
+  // Check if a PDPTE is present
+  //
+  if ((*TableEntry & IA32_PG_P) == 0) {
+return FALSE;
+  }
+
+  //
+  // Calculate physical address of page-directory-pointer table and index of
+  // PDPTE.
+  //
+  PageDirPtrTable = (UINT64 *)(UINTN)(*TableEntry & PhysicalAddressMask);
+  Index = (UINTN)(RShiftU64 ((UINT64)LinearAddress, 30) & IndexMask);
+
+  //
+  // Select PDPTE
+  //
+  TableEntry = [Index];
+
+  //
+  // Check whether a PDPTE or 1GiB page entry is present
+  //
+  if ((*TableEntry & IA32_PG_P) == 0) {
+return FALSE;
+  }
+
+  //
+  // Check if PDPTE maps an 1GiB page
+  //
+  if ((*TableEntry & IA32_PG_PS) != 0) {
+return TRUE;
+  }
+
+  //
+  // Calculate physical address of page directory table and index of PDE
+  //
+  PageDirTable = (UINT64 *)(UINTN)(*TableEntry & PhysicalAddressMask);
+  Index = (UINTN)(RShiftU64 ((UINT64)LinearAddress, 21) & IndexMask);
+
+  //
+  // Select PDE
+  //
+  TableEntry = [Index];
+
+  //
+  // Check whether a PDE or a 2MiB page entry is present
+  //
+  if ((*TableEntry & IA32_PG_P) == 0) {
+return FALSE;
+  }
+
+  //
+  // Check if PDE maps a 2MiB page
+  //
+  if ((*TableEntry & IA32_PG_PS) != 0) {
+return TRUE;
+  }
+
+  //
+  // Calculate physical address of page table and index of PTE
+  //
+  PageTable = (UINT64 *)(UINTN)(*TableEntry & PhysicalAddressMask);
+  Index = (UINTN)(RShiftU64 ((UINT64)LinearAddress, 12) & IndexMask);
+
+  //
+  // Select PTE
+  //
+  TableEntry = [Index];
+
+  //
+  // Check if PTE maps a 4KiB page
+  //
+  if ((*TableEntry & IA32_PG_P) == 0) {
+return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  Check if a linear address is valid by walking the page tables in 32-bit 
paging
+  mode.
+
+  NOTE: Current UEFI implementations do not support IA32 non-PAE paging mode.
+
+  @param[in]  Cr3 CR3 con

[edk2] [RFC v5 8/8] UefiCpuPkg/CpuExceptionHandlerLib: Add early check in DumpStackContents

2018-01-14 Thread Paulo Alcantara
Add an early check in DumpStackContens() to abort in case of no unwound
stacks.

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 <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 7 
+++
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c  | 7 
+++
 2 files changed, 14 insertions(+)

diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
index 31fbd4a164..ac3801f704 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -805,6 +805,13 @@ DumpStackContents (
 {
   UINT32 CurrentEsp;
 
+  //
+  // Do nothing in case there wasn't any unwound stack.
+  //
+  if (UnwoundStacksCount == 0) {
+return;
+  }
+
   //
   // Get current stack pointer
   //
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index 4d8c9b0a89..6c3bad01a6 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
@@ -418,6 +418,13 @@ DumpStackContents (
   UINTN   RspAddressStart;
   UINTN   RspAddressEnd;
 
+  //
+  // Do nothing in case there wasn't any unwound stack.
+  //
+  if (UnwoundStacksCount == 0) {
+return;
+  }
+
   //
   // Get current stack pointer
   //
-- 
2.14.3

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


[edk2] [RFC v5 7/8] UefiCpuPkg/CpuExceptionHandlerLib: Validate memory address ranges

2018-01-14 Thread Paulo Alcantara
Introduce a new IsLinearAddressRangeValid() function to validate a given
address range and check whether or not it is valid.

This function is useful for validating ranges of memory addresses during
stack traces in X64.

Contributed-under: TianoCore Contribution Agreement 1.1
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Requested-by: Brian Johnson <brian.john...@hpe.com>
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c   | 40 

 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h   | 18 
+
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 40 

 3 files changed, 83 insertions(+), 15 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index 7ac13640de..e1dd054259 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -589,3 +589,43 @@ IsLinearAddressValid (
 
   return AddressValid;
 }
+
+/**
+  Check if a linear address range is valid.
+
+  @param[in]  Cr0 CR0 control register.
+  @param[in]  Cr3 CR3 control register.
+  @param[in]  Cr4 CR4 control register.
+  @param[in]  LinearAddressStart  Linear address start.
+  @param[in]  LinearAddressEndLinear address end.
+**/
+BOOLEAN
+IsLinearAddressRangeValid (
+  IN  UINTN  Cr0,
+  IN  UINTN  Cr3,
+  IN  UINTN  Cr4,
+  IN  UINTN  LinearAddressStart,
+  IN  UINTN  LinearAddressEnd
+  )
+{
+  //
+  // Check for valid input parameters
+  //
+  if (LinearAddressStart == 0 || LinearAddressEnd == 0 ||
+  LinearAddressStart > LinearAddressEnd) {
+return FALSE;
+  }
+
+  //
+  // Validate all linear addresses within the given range
+  //
+  for (LinearAddressStart &= ~(SIZE_4KB - 1);
+   LinearAddressStart <= LinearAddressEnd;
+   LinearAddressStart += SIZE_4KB) {
+if (!IsLinearAddressValid (Cr0, Cr3, Cr4, LinearAddressStart)) {
+  return FALSE;
+}
+  }
+
+  return TRUE;
+}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 1b51034c25..075f668290 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -346,5 +346,23 @@ IsLinearAddressValid (
   IN  UINTN  LinearAddress
   );
 
+/**
+  Check if a linear address range is valid.
+
+  @param[in]  Cr0 CR0 control register.
+  @param[in]  Cr3 CR3 control register.
+  @param[in]  Cr4 CR4 control register.
+  @param[in]  LinearAddressStart  Linear address start.
+  @param[in]  LinearAddressEndLinear address end.
+**/
+BOOLEAN
+IsLinearAddressRangeValid (
+  IN  UINTN  Cr0,
+  IN  UINTN  Cr3,
+  IN  UINTN  Cr4,
+  IN  UINTN  LinearAddressStart,
+  IN  UINTN  LinearAddressEnd
+  );
+
 #endif
 
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index 71d2d2f5d4..4d8c9b0a89 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
@@ -415,6 +415,8 @@ DumpStackContents (
   UINTN   Cr0;
   UINTN   Cr3;
   UINTN   Cr4;
+  UINTN   RspAddressStart;
+  UINTN   RspAddressEnd;
 
   //
   // Get current stack pointer
@@ -436,21 +438,29 @@ DumpStackContents (
   Cr3 = SystemContext.SystemContextX64->Cr3;
   Cr4 = SystemContext.SystemContextX64->Cr4;
 
+  //
+  // Calculate address range of the stack pointers
+  //
+  RspAddressStart = (UINTN)CurrentRsp;
+  RspAddressEnd =
+RspAddressStart + (UINTN)UnwoundStacksCount * CPU_STACK_ALIGNMENT;
+
+  //
+  // Validate address range of stack pointers
+  //
+  if (!IsLinearAddressRangeValid (Cr0, Cr3, Cr4, RspAddressStart,
+  RspAddressEnd)) {
+InternalPrintMessage ("%a: attempted to dereference an invalid stack "
+  "pointer at 0x%016lx - 0x%016lx\n", __FUNCTION__,
+  RspAddressStart, RspAddressEnd);
+return;
+  }
+
   //
   // Dump out stack contents
   //
   InternalPrintMessage ("\nStack dump:\n");
   while (UnwoundStacksCount-- > 0) {
-//
-// Check for a valid stack pointer address
-//
-if (!IsLinearAddressValid (Cr0, Cr3, Cr4, (UINTN)CurrentRsp) ||
-!IsLinearAddressValid (Cr0, Cr3, Cr4, (UINTN)CurrentRsp + 8)) {
-  InternalPrintMessage ("%a: attempted to dereference an inva

[edk2] [RFC v5 0/8] Stack trace support in X64 exception handling

2018-01-14 Thread Paulo Alcantara
Hi,

This series adds stack trace support during IA32 and X64 CPU exceptions.

Informations like back trace, stack contents and image module names
(that were part of the call stack) will be dumped out.

The current limitation is that it relies on available frame pointers
(GCC only) in order to successfully unwind the stack.

Jiewen,

Thank you very much for your time on this. I've applied the changes you
suggested, as well as tested it on IA32 PAE paging mode - it worked as
expected.

Other than that, I also tested the stack trace in SMM code by manually
calling CpuBreakPoint() and then it broke with another exception
(page fault). I didn't have much time to look into that, but what I've
observed is that the page fault ocurred during the search of PE/COFF
image base address (in PeCoffSearchImageBase). The function attempts to
search for the image base from "Address" through 0, so any of those
dereferenced addresses triggers the page fault.

Do you know how we could fix that issue? Perhaps introducing a
AddressValidationLib (as Brian suggested previously) and use it within
PeCoffSearchImageBase()?

I'd also like to thank Brian & Jeff for all the support!

Thanks
Paulo

Repo:   https://github.com/pcacjr/edk2.git
Branch: stacktrace_v5

Cc: Rick Bramley <richard.bram...@hp.com>
Cc: Kimon Berlin <kimon.ber...@hp.com>
Cc: Diego Medaglia <diego.meag...@hp.com>
Cc: Andrew Fish <af...@apple.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Brian Johnson <brian.john...@hpe.com>
Cc: Jeff Fan <vanjeff_...@hotmail.com>
Cc: Jiewen Yao <jiewen@intel.com>
Cc: Paulo Alcantara <pa...@hp.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---

v1 -> v2:
  * Add IA32 arch support (GCC toolchain only)
  * Replace hard-coded stack alignment value (16) with
CPU_STACK_ALIGNMENT.
  * Check for proper stack and frame pointer alignments.
  * Fix initialization of UnwoundStacksCount to 1.
  * Move GetPdbFileName() to common code since it will be used by both
IA32 and X64 implementations.

v2 -> v3:
  * Fixed wrong assumption about "RIP < ImageBase" to start searching
for another PE/COFF image. That is, RIP may point to lower and
higher addresses for any other PE/COFF images. Both IA32 & X64.
(Thanks Andrew & Jiewen)
  * Fixed typo: unwond -> unwound. Both IA32 & X64. (Thanks Brian)

v3 -> v4:
  * Validate all frame/stack pointer addresses before dereferencing them
as requested by Brian & Jiewen.
  * Correctly print out IP addresses during the stack traces (by Jeff)

v4 -> v5:
  * Fixed address calculations and improved code as suggested by Jiewen.
  * Fixed parameter validation as suggested by Brian.
  * Tested stack stack with IA32 PAE paging mode.

Paulo Alcantara (8):
  UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
  UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName()
  UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support
  UefiCpuPkg/CpuExceptionHandlerLib: Add helper to validate memory
addresses
  UefiCpuPkg/CpuExceptionHandlerLib: Ensure valid frame/stack pointers
  UefiCpuPkg/CpuExceptionHandlerLib: Correctly print IP addresses
  UefiCpuPkg/CpuExceptionHandlerLib: Validate memory address ranges
  UefiCpuPkg/CpuExceptionHandlerLib: Add early check in
DumpStackContents

 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c| 537 
++--
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h|  59 ++-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 483 
+-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c  | 426 
+++-
 4 files changed, 1435 insertions(+), 70 deletions(-)

-- 
2.14.3

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


[edk2] [RFC v5 6/8] UefiCpuPkg/CpuExceptionHandlerLib: Correctly print IP addresses

2018-01-14 Thread Paulo Alcantara
Remove the supurious '- 1' when calculating the IP addresses during the
stack traces.

Contributed-under: TianoCore Contribution Agreement 1.1
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Requested-by: Jeff Fan <vanjeff_...@hotmail.com>
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 2 +-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
index 3b92512b92..31fbd4a164 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -590,7 +590,7 @@ DumpStacktrace (
   *UnwoundStacksCount - 1,
   Eip,
   ImageBase,
-  Eip - ImageBase - 1,
+  Eip - ImageBase,
   Ebp,
   PdbFileName
   );
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index c81f4c00eb..71d2d2f5d4 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
@@ -739,7 +739,7 @@ DumpStacktrace (
   *UnwoundStacksCount - 1,
   Rip,
   ImageBase,
-  Rip - ImageBase - 1,
+  Rip - ImageBase,
   Rbp,
   PdbFileName
   );
-- 
2.14.3

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


[edk2] [RFC v5 1/8] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

2018-01-14 Thread Paulo Alcantara
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 <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 401 
+++-
 1 file changed, 393 insertions(+), 8 deletions(-)

diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index 56180f4c17..4db9f6465e 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.
@@ -399,20 +404,281 @@ DumpCpuContext (
 }
 
 /**
-  Display CPU information.
+  Get absolute path and file name of PDB file in PE/COFF image.
 
-  @param ExceptionType  Exception type.
-  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
+  @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
-DumpImageAndCpuContent (
+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]  UnwoundStacksCount  Count of unwound stack frames.
+**/
+STATIC
+VOID
+DumpStackContents (
+  IN UINT64  CurrentRsp,
+  IN INTNUnwoundStacksCount
+  )
+{
+  //
+  // 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 (UnwoundStacksCount-- > 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]  ExceptionType  Exception type.
+  @param[in]  SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
+**/
+STATIC
+VOID
+DumpImageModuleNames (
   IN EFI_EXCEPTION_TYPE   ExceptionType,
   IN EFI_SYSTEM_CONTEXT   SystemContext
   )
 {
-  DumpCpuContext (ExceptionType, SystemContext);
+  EFI_STATUS  Status;
+  UINT64  Rip;
+  UINTN   ImageBase;
+  VOID*EntryPoint;
+  CHAR8   *PdbAbsoluteFilePath;
+  CHAR8   *PdbFileName;
+  UINT64  Rbp;
+  UINTN   LastImageBase;
+
+  //
+  // Set current RIP address
+  //
+  if ((ExceptionType == EXCEPT_IA32_PAGE_FAULT) &&
+  ((SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0)) {
+//
+// The RIP in SystemContext could not be used
+// if it is page fault with I/D set.
+//
+Rip = *(UINT64 *)(UINTN)SystemContext.SystemContextX64->Rsp;
+  } else {
+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 addr

[edk2] [RFC v5 3/8] UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support

2018-01-14 Thread Paulo Alcantara
This patch adds stack trace support during a IA32 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 <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c|  42 ---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h|  11 -
 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 335 
+++-
 3 files changed, 327 insertions(+), 61 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index d9abbd772d..66892320c8 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -109,48 +109,6 @@ InternalPrintMessage (
   SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
 }
 
-/**
-  Find and display image base address and return image base and its entry 
point.
-
-  @param CurrentEip  Current instruction pointer.
-
-**/
-VOID
-DumpModuleImageInfo (
-  IN  UINTN  CurrentEip
-  )
-{
-  EFI_STATUS   Status;
-  UINTNPe32Data;
-  VOID *PdbPointer;
-  VOID *EntryPoint;
-
-  Pe32Data = PeCoffSearchImageBase (CurrentEip);
-  if (Pe32Data == 0) {
-InternalPrintMessage (" Can't find image information. \n");
-  } else {
-//
-// Find Image Base entry point
-//
-Status = PeCoffLoaderGetEntryPoint ((VOID *) Pe32Data, );
-if (EFI_ERROR (Status)) {
-  EntryPoint = NULL;
-}
-InternalPrintMessage (" Find image based on IP(0x%x) ", CurrentEip);
-PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);
-if (PdbPointer != NULL) {
-  InternalPrintMessage ("%a", PdbPointer);
-} else {
-  InternalPrintMessage ("(No PDB) " );
-}
-InternalPrintMessage (
-  " (ImageBase=%016lp, EntryPoint=%016p) \n",
-  (VOID *) Pe32Data,
-  EntryPoint
-  );
-  }
-}
-
 /**
   Read and save reserved vector information
 
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 64c7094513..ec46c2d9d3 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -130,17 +130,6 @@ InternalPrintMessage (
   ...
   );
 
-/**
-  Find and display image base address and return image base and its entry 
point.
-
-  @param CurrentEip  Current instruction pointer.
-
-**/
-VOID
-DumpModuleImageInfo (
-  IN  UINTN  CurrentEip
-  );
-
 /**
   Display CPU information.
 
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
index 04f2ab593c..c5d6ea0939 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -399,20 +399,156 @@ DumpCpuContext (
 }
 
 /**
-  Display CPU information.
+  Dump stack trace.
 
-  @param ExceptionType  Exception type.
-  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
+  @param[in]  ExceptionType  Exception type.
+  @param[in]  SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
+  @param[out] UnwoundStacksCount Count of unwound stack frames.
 **/
+STATIC
 VOID
-DumpImageAndCpuContent (
+DumpStacktrace (
+  IN  EFI_EXCEPTION_TYPE   ExceptionType,
+  IN  EFI_SYSTEM_CONTEXT   SystemContext,
+  OUT INTN *UnwoundStacksCount
+  )
+{
+  UINT32  Eip;
+  UINT32  Ebp;
+  UINTN   ImageBase;
+  CHAR8   *PdbFileName;
+
+  //
+  // Set current EIP address
+  //
+  if ((ExceptionType == EXCEPT_IA32_PAGE_FAULT) &&
+  ((SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0)) 
{
+//
+// The EIP in SystemContext could not be used
+// if it is page fault with I/D set.
+//
+Eip = *(UINT32 *)(UINTN)SystemContext.SystemContextIa32->Esp;
+  } else {
+Eip = SystemContext.SystemContextIa32->Eip;
+  }
+
+  //
+  // Set current frame pointer address
+  //
+  Ebp = SystemContext.SystemContextIa32->Ebp;
+
+  //
+  // Check for proper frame pointer alignment
+  //
+  if (((UINTN)Ebp & (CPU_STACK_ALIGNMENT - 1)) != 0) {
+InternalPrintMessage (" Unaligned frame pointer. \n");
+return;
+  }
+
+  //
+  // Get initial PE/COFF image base address from current EIP
+  //
+  ImageBase = PeCoffSearchImageBase (Eip);
+  if (ImageBase == 0) {
+InternalPrintMessage (

[edk2] [RFC v5 5/8] UefiCpuPkg/CpuExceptionHandlerLib: Ensure valid frame/stack pointers

2018-01-14 Thread Paulo Alcantara
Validate all possible memory dereferences during stack traces in IA32
and X64 CPU exceptions.

Contributed-under: TianoCore Contribution Agreement 1.1
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Requested-by: Brian Johnson <brian.john...@hpe.com>
Requested-by: Jiewen Yao <jiewen@intel.com>
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 149 
+++-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c  |  75 
+-
 2 files changed, 216 insertions(+), 8 deletions(-)

diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
index c5d6ea0939..3b92512b92 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -14,6 +14,11 @@
 
 #include "CpuExceptionCommon.h"
 
+//
+// IA32 Segment Selector bit definitions
+//
+#define IA32_SEGSEL_TI BIT2
+
 /**
   Return address map of exception handler template so that C code can generate
   exception tables.
@@ -398,6 +403,97 @@ DumpCpuContext (
 );
 }
 
+/**
+  Check if a logical address is valid.
+
+  @param[in]  SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
+  @param[in]  SegmentSelectorSegment selector.
+  @param[in]  Offset Offset or logical address.
+**/
+STATIC
+BOOLEAN
+IsLogicalAddressValid (
+  IN  EFI_SYSTEM_CONTEXT   SystemContext,
+  IN  UINT16   SegmentSelector,
+  IN  UINTNOffset
+  )
+{
+  IA32_SEGMENT_DESCRIPTOR  *SegmentDescriptor;
+  UINT32   SegDescBase;
+  UINT32   SegDescLimit;
+  UINT64   SegDescLimitInBytes;
+
+  //
+  // Check for valid input parameters
+  //
+  if (SegmentSelector == 0 || Offset == 0) {
+return FALSE;
+  }
+
+  //
+  // Look for a segment descriptor in a GDT or LDT table depending on TI
+  // (Table Indicator) bit in segment selector.
+  //
+  if ((SegmentSelector & IA32_SEGSEL_TI) == 0) {
+//
+// Get segment descriptor from GDT table
+//
+SegmentDescriptor =
+  (IA32_SEGMENT_DESCRIPTOR *)(
+(UINTN)SystemContext.SystemContextIa32->Gdtr[0] +
+(SegmentSelector & ~7)
+);
+  } else {
+//
+// Get segment descriptor from LDT table
+//
+SegmentDescriptor =
+  (IA32_SEGMENT_DESCRIPTOR *)(
+(UINTN)SystemContext.SystemContextIa32->Ldtr +
+(SegmentSelector & ~7)
+);
+  }
+
+  //
+  // Get segment descriptor's base address
+  //
+  SegDescBase = SegmentDescriptor->Bits.BaseLow |
+(SegmentDescriptor->Bits.BaseMid << 16) |
+(SegmentDescriptor->Bits.BaseHigh << 24);
+
+  //
+  // Get segment descriptor's limit
+  //
+  SegDescLimit = SegmentDescriptor->Bits.LimitLow |
+(SegmentDescriptor->Bits.LimitHigh << 16);
+
+  //
+  // Calculate segment descriptor's limit in bytes
+  //
+  if (SegmentDescriptor->Bits.G == 1) {
+SegDescLimitInBytes = (UINT64)SegDescLimit * SIZE_4KB + (SIZE_4KB - 1);
+  } else {
+SegDescLimitInBytes = SegDescLimit;
+  }
+
+  //
+  // Make sure to not access beyond a segment limit boundary
+  //
+  if ((UINT64)Offset + SegDescBase > SegDescLimitInBytes) {
+return FALSE;
+  }
+
+  //
+  // Check if the translated logical address (or linear address) is valid
+  //
+  return IsLinearAddressValid (
+SystemContext.SystemContextIa32->Cr0,
+SystemContext.SystemContextIa32->Cr3,
+SystemContext.SystemContextIa32->Cr4,
+Offset + SegDescBase
+);
+}
+
 /**
   Dump stack trace.
 
@@ -470,6 +566,20 @@ DumpStacktrace (
   InternalPrintMessage ("\nCall trace:\n");
 
   for (;;) {
+//
+// Check for valid frame pointer
+//
+if (!IsLogicalAddressValid (SystemContext,
+SystemContext.SystemContextIa32->Ss,
+(UINTN)Ebp + 4) ||
+!IsLogicalAddressValid (SystemContext,
+SystemContext.SystemContextIa32->Ss,
+(UINTN)Ebp)) {
+  InternalPrintMessage ("%a: attempted to dereference an invalid frame "
+"pointer at 0x%08x\n", __FUNCTION__, Ebp);
+  break;
+}
+
 //
 // Print stack frame in the following format:
 //
@@ -610,6 +720,16 @@ DumpImageModuleNames (
   // Walk through call stack and find next module names
   //
   for (;;) {
+if (!IsLogicalAddressValid (SystemContext,
+SystemContext.SystemContextIa32->Ss,
+(UINTN)Ebp) ||
+!IsLogicalAddressValid (SystemContext,
+SystemContext.SystemContextIa32->Ss,
+

[edk2] [RFC v5 2/8] UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName()

2018-01-14 Thread Paulo Alcantara
This function will be used by both IA32 and X64 exception handling in
order to print out image module names during stack unwinding.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c   | 60 
+++-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h   | 14 +
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 59 
---
 3 files changed, 73 insertions(+), 60 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index 01b0610364..d9abbd772d 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -54,6 +54,11 @@ CONST CHAR8 *mExceptionNameStr[] = {
 
 #define EXCEPTION_KNOWN_NAME_NUM  (sizeof (mExceptionNameStr) / sizeof (CHAR8 
*))
 
+//
+// Unknown PDB file name
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mUnknownPdbFileName = "";
+
 /**
   Get ASCII format string exception name by exception type.
 
@@ -177,4 +182,57 @@ ReadAndVerifyVectorInfo (
 VectorInfo ++;
   }
   return EFI_SUCCESS;
-}
\ No newline at end of file
+}
+
+/**
+  Get absolute path and file name of PDB file in PE/COFF image.
+
+  @param[in]  ImageBaseBase address of PE/COFF image.
+  @param[out] PdbAbsoluteFilePath  Absolute path of PDB file.
+  @param[out] PdbFileName  File name of PDB file.
+**/
+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;
+}
+  }
+}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index e10d9379d5..64c7094513 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -327,5 +327,19 @@ AsmGetTssTemplateMap (
   OUT EXCEPTION_HANDLER_TEMPLATE_MAP  *AddressMap
   );
 
+/**
+  Get absolute path and file name of PDB file in PE/COFF image.
+
+  @param[in]  ImageBaseBase address of PE/COFF image.
+  @param[out] PdbAbsoluteFilePath  Absolute path of PDB file.
+  @param[out] PdbFileName  File name of PDB file.
+**/
+VOID
+GetPdbFileName (
+  IN  UINTNImageBase,
+  OUT CHAR8**PdbAbsoluteFilePath,
+  OUT CHAR8**PdbFileName
+  );
+
 #endif
 
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index 4db9f6465e..523dce95c9 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
@@ -14,11 +14,6 @@
 
 #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.
@@ -403,60 +398,6 @@ DumpCpuContext (
 );
 }
 
-/**
-  Get absolute path and file name of PDB file in PE/COFF image.
-
-  @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 = (C

Re: [edk2] [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add helper to valid memory addresses

2018-01-04 Thread Paulo Alcantara
"Yao, Jiewen" <jiewen@intel.com> writes:

Hi Jiewen,

> For 7), you are right that we disable IA32 paging by default.
> However, we do support IA32 PAE in DxeIpl. Please refer to 
> MdeModulePkg\Core\DxeIplPeim\Ia32\DxeLoadFunc.c
> ==
> PageTables = 0;
> BuildPageTablesIa32Pae = (BOOLEAN) (PcdGetBool (PcdSetNxForStack) && 
> IsIa32PaeSupport () && IsExecuteDisableBitAvailable ());
> if (BuildPageTablesIa32Pae) {
>   PageTables = Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE);
>   EnableExecuteDisableBit ();
> }
> ==
>
> Please notice that we only support IA32 PAE, we do not support IA32
> non-PAE mode so far. (no matter PSE is ON/OFF)

Cool! I didn't know about it.

>
> So, I suggest:
> 7.1) Please validate IA32 PAE mode. (You can enable PcdSetNxForStack)

I will. Thanks!

> 7.2) If we cannot validate the IA32 non-PAE code, please remove
> them. You can just print "IA32 non-PAE - UNSUPPORTED" and return
> invalid address. Then it can save our development time, review time,
> and validation time. The key is that we only want to check in the
> validated code.

You're right. I'll keep only the code that we were able to validate its
implementation (e.g. 4-level & 32-bit PAE).

Thanks!
Paulo

>> -Original Message-
>> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Paulo
>> Alcantara
>> Sent: Thursday, January 4, 2018 9:30 PM
>> To: Yao, Jiewen <jiewen@intel.com>; Yao, Jiewen <jiewen@intel.com>;
>> edk2-devel@lists.01.org
>> Cc: Laszlo Ersek <ler...@redhat.com>; Dong, Eric <eric.d...@intel.com>
>> Subject: Re: [edk2] [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add
>> helper to valid memory addresses
>> 
>> "Yao, Jiewen" <jiewen@intel.com> writes:
>> 
>> > 5) For CR4, please use meaning definition for BIT4/BIT5.
>> >   if ((Cr4 & BIT4) != 0 && (*PageDirEntry & BIT7) != 0) {
>> > if (((Cr4 & BIT5) != 0 && (UINT64)LinearAddress > 0xFULL) ||
>> 
>> OK.
>> 
>> >
>> > 6) For IA32 PAE/PSE calculation, same comment for 3 and 4.
>> 
>> OK.
>> 
>> >
>> > 7) Last but not least important, would you please share the information on
>> how do you validate the 32bit PAE/PSE/normal 4K page table?
>> 
>> Since on IA32 we use 32-bit protected flat model and paging disabled
>> (OK?), I wasn't able to validate the paging modes other than 4-level
>> paging mode in X64. The memory validation code I wrote is heavily based
>> upon what I read from Intel SDM Vol 3A manual.
>> 
>> If you do have any idea on how to validate it -- whether it's a PoC or
>> test code -- please let me know, and then I validate it.
>> 
>> Thanks again for your review!
>> 
>> Paulo
>> 
>> >
>> > Thank you
>> > Yao Jiewen
>> >
>> >> -Original Message-
>> >> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of
>> Yao,
>> >> Jiewen
>> >> Sent: Thursday, January 4, 2018 9:36 AM
>> >> To: Paulo Alcantara <pa...@paulo.ac>; edk2-devel@lists.01.org
>> >> Cc: Laszlo Ersek <ler...@redhat.com>; Dong, Eric <eric.d...@intel.com>
>> >> Subject: Re: [edk2] [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add
>> >> helper to valid memory addresses
>> >>
>> >> Some suggestion:
>> >>
>> >> 1) I am not sure if it is proper to use ASSERT in an exception handler, 
>> >> because
>> we
>> >> know something is wrong.
>> >>
>> >>   ASSERT ((PhysicalAddress & (sizeof (*Pml4TableEntry) - 1)) == 0);
>> >>
>> >> I suggest we just do the check, and return FALSE, if the prerequisite is 
>> >> not
>> >> satisfied.
>> >>
>> >> 2) Can we use meaningful definition for BIT0, BIT7?
>> >>
>> >>   if ((*Pml4TableEntry & BIT0) == 0) {
>> >>   if ((*PageDirPtrTableEntry & BIT7) != 0) {
>> >>
>> >> 3) I am not sure if I understand below code.
>> >>
>> >>   PhysicalAddress = (UINT64)Cr3 & (((1ULL << MaxPhyAddrBits) - 1) << 12);
>> >>   PhysicalAddress = *Pml4TableEntry & (((1ULL << MaxPhyAddrBits) - 1) <<
>> 12);
>> >>   PhysicalAddress = *PageDirPtrTableEntry & (((1ULL << MaxPhyAddrBits) -
>> 1)
>> >&

Re: [edk2] [RFC v4 0/6] Stack trace support in X64 exception handling

2018-01-04 Thread Paulo Alcantara
"Yao, Jiewen" <jiewen@intel.com> writes:

Hi Jiewen,

> I tried to apply the patch series to latest code, but fail with below message.
>
> Have you rebased to latest code?

Hrm - I thought I did before sending out v4. Sorry for that. I'll make
sure to rebase it against latest master before sending out v5.

Thanks
Paulo

>
> ===
> git.exe am --3way --ignore-space-change --keep-cr 
> "C:\home\EdkIIGit\edk2\[edk2]-[RFC-v4-1-6]-UefiCpuPkg-CpuExceptionHandlerLib-X64-Add-stack-trace-support.patch"
> Applying: UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
> Using index info to reconstruct a base tree...
> M UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
> Falling back to patching base and 3-way merge...
> Auto-merging 
> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
> CONFLICT (content): Merge conflict in 
> UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
> Patch failed at 0001 UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace 
> support
> The copy of the patch that failed is found in: .git/rebase-apply/patch
> When you have resolved this problem, run "git am --continue".
> If you prefer to skip this patch, run "git am --skip" instead.
> To restore the original branch and stop patching, run "git am --abort".
>
> .git/rebase-apply/patch:13: trailing whitespace.
> //
> .git/rebase-apply/patch:14: trailing whitespace.
> // Unknown PDB file name
> .git/rebase-apply/patch:15: trailing whitespace.
> //
> .git/rebase-apply/patch:16: trailing whitespace.
> GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mUnknownPdbFileName = "";
> .git/rebase-apply/patch:17: trailing whitespace.
>
> warning: squelched 369 whitespace errors
> warning: 374 lines add whitespace errors.
> error: Failed to merge in the changes.
>
> Fail
> =
>
>> -Original Message-
>> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Paulo
>> Alcantara
>> Sent: Friday, December 29, 2017 11:49 AM
>> To: edk2-devel@lists.01.org
>> Cc: Rick Bramley <richard.bram...@hp.com>; Dong, Eric
>> <eric.d...@intel.com>; Andrew Fish <af...@apple.com>; Yao, Jiewen
>> <jiewen@intel.com>; Laszlo Ersek <ler...@redhat.com>
>> Subject: [edk2] [RFC v4 0/6] Stack trace support in X64 exception handling
>> 
>> Hi,
>> 
>> This series adds stack trace support during IA32 and X64 CPU exceptions.
>> 
>> Informations like back trace, stack contents and image module names
>> (that were part of the call stack) will be dumped out.
>> 
>> The current limitation is that it relies on available frame pointers
>> (GCC only) in order to successfully unwind the stack.
>> 
>> (Sorry for the very long delay - I was very busy working on something
>>  else and then went to vacations)
>> 
>> Jiewen,
>> 
>> I have tested it with VS2015x86 and the stack trace just hanged when
>> printing out the first EIP (that is, no frame pointer at all).
>> 
>> Thanks!
>> Paulo
>> 
>> Repo:   https://github.com/pcacjr/edk2.git
>> Branch: stacktrace_v4
>> 
>> Cc: Rick Bramley <richard.bram...@hp.com>
>> Cc: Andrew Fish <af...@apple.com>
>> Cc: Eric Dong <eric.d...@intel.com>
>> Cc: Laszlo Ersek <ler...@redhat.com>
>> Cc: Brian Johnson <brian.john...@hpe.com>
>> Cc: Jeff Fan <vanjeff_...@hotmail.com>
>> Cc: Jiewen Yao <jiewen@intel.com>
>> Contributed-under: TianoCore Contribution Agreement 1.1
>> Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
>> ---
>> 
>> v1 -> v2:
>>   * Add IA32 arch support (GCC toolchain only)
>>   * Replace hard-coded stack alignment value (16) with
>> CPU_STACK_ALIGNMENT.
>>   * Check for proper stack and frame pointer alignments.
>>   * Fix initialization of UnwoundStacksCount to 1.
>>   * Move GetPdbFileName() to common code since it will be used by both
>> IA32 and X64 implementations.
>> 
>> v2 -> v3:
>>   * Fixed wrong assumption about "RIP < ImageBase" to start searching
>> for another PE/COFF image. That is, RIP may point to lower and
>> higher addresses for any other PE/COFF images. Both IA32 & X64.
>> (Thanks Andrew & Jiewen)
>>   * Fixed typo: unwond -> unwound. Both IA32 & X64. (Thanks Brian)
>> 
>> v3 -> v4:
>>   * Validate all frame/stack pointer addresses before dereferencing them
>> as 

Re: [edk2] [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add helper to valid memory addresses

2018-01-04 Thread Paulo Alcantara
"Yao, Jiewen" <jiewen@intel.com> writes:

> 5) For CR4, please use meaning definition for BIT4/BIT5.
>   if ((Cr4 & BIT4) != 0 && (*PageDirEntry & BIT7) != 0) {
> if (((Cr4 & BIT5) != 0 && (UINT64)LinearAddress > 0xFULL) ||

OK.

>
> 6) For IA32 PAE/PSE calculation, same comment for 3 and 4.

OK.

>
> 7) Last but not least important, would you please share the information on 
> how do you validate the 32bit PAE/PSE/normal 4K page table?

Since on IA32 we use 32-bit protected flat model and paging disabled
(OK?), I wasn't able to validate the paging modes other than 4-level
paging mode in X64. The memory validation code I wrote is heavily based
upon what I read from Intel SDM Vol 3A manual.

If you do have any idea on how to validate it -- whether it's a PoC or
test code -- please let me know, and then I validate it.

Thanks again for your review!

Paulo

>
> Thank you
> Yao Jiewen
>
>> -Original Message-
>> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Yao,
>> Jiewen
>> Sent: Thursday, January 4, 2018 9:36 AM
>> To: Paulo Alcantara <pa...@paulo.ac>; edk2-devel@lists.01.org
>> Cc: Laszlo Ersek <ler...@redhat.com>; Dong, Eric <eric.d...@intel.com>
>> Subject: Re: [edk2] [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add
>> helper to valid memory addresses
>> 
>> Some suggestion:
>> 
>> 1) I am not sure if it is proper to use ASSERT in an exception handler, 
>> because we
>> know something is wrong.
>> 
>>   ASSERT ((PhysicalAddress & (sizeof (*Pml4TableEntry) - 1)) == 0);
>> 
>> I suggest we just do the check, and return FALSE, if the prerequisite is not
>> satisfied.
>> 
>> 2) Can we use meaningful definition for BIT0, BIT7?
>> 
>>   if ((*Pml4TableEntry & BIT0) == 0) {
>>   if ((*PageDirPtrTableEntry & BIT7) != 0) {
>> 
>> 3) I am not sure if I understand below code.
>> 
>>   PhysicalAddress = (UINT64)Cr3 & (((1ULL << MaxPhyAddrBits) - 1) << 12);
>>   PhysicalAddress = *Pml4TableEntry & (((1ULL << MaxPhyAddrBits) - 1) << 12);
>>   PhysicalAddress = *PageDirPtrTableEntry & (((1ULL << MaxPhyAddrBits) - 1)
>> << 12);
>>   PhysicalAddress = *PageDirEntry & (((1ULL << MaxPhyAddrBits) - 1) << 12);
>> 
>> If MaxPhyAddrBits is 48, you will get "Cr3 & 0x0000". Is that 
>> what
>> you want? I think we need "Cr3 & 0xF000"
>> Should it be: PhysicalAddress = (UINT64)Cr3 & ((1ULL << MaxPhyAddrBits) - 1) 
>> &
>> (~0xFFF);
>> 
>> 4) Can we use a more readable way to below? Personally, I do not suggest "<< 
>> 3",
>> which is just the index calculation.
>> 
>>   PhysicalAddress = (UINT64)Cr3 & (((1ULL << MaxPhyAddrBits) - 1) << 12);
>>   PhysicalAddress |= (((UINT64)LinearAddress >> 39) & 0x1FF) << 3;
>>   Pml4TableEntry = (UINT64 *)(UINTN)PhysicalAddress;
>>   PhysicalAddress = *Pml4TableEntry & (((1ULL << MaxPhyAddrBits) - 1) << 12);
>> 
>> For example:
>>   PhysicalAddress = (UINT64)Cr3 & ((1ULL << MaxPhyAddrBits) - 1) & (~0xFFF);
>>   Pml4TableEntry = (UINT64 *)(UINTN)PhysicalAddress;
>>   Index= (UINTN)(((UINT64)LinearAddress >> 39) & 0x1FF);
>>   PhysicalAddress = Pml4TableEntry[Index] & ((1ULL << MaxPhyAddrBits) - 1) &
>> (~0xFFF);
>> 
>> 
>> 
>> Thank you
>> Yao Jiewen
>> 
>> 
>> > -Original Message-
>> > From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of
>> Paulo
>> > Alcantara
>> > Sent: Friday, December 29, 2017 12:40 PM
>> > To: edk2-devel@lists.01.org
>> > Cc: Laszlo Ersek <ler...@redhat.com>; Dong, Eric <eric.d...@intel.com>
>> > Subject: [edk2] [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add helper
>> to
>> > valid memory addresses
>> >
>> > Introduce IsLinearAddressValid() function that will be used for
>> > validating memory addresses that would get dereferenced during stack
>> > traces in IA32 and X64 CPU exceptions.
>> >
>> > Contributed-under: TianoCore Contribution Agreement 1.1
>> > Cc: Eric Dong <eric.d...@intel.com>
>> > Cc: Laszlo Ersek <ler...@redhat.com>
>> > Requested-by: Brian Johnson <brian.john...@hpe.com>
>> > Requested-by: Jiewen Yao <jiewen@intel.com>
>> > Si

Re: [edk2] [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add helper to valid memory addresses

2018-01-04 Thread Paulo Alcantara
"Yao, Jiewen" <jiewen@intel.com> writes:

Hi Jiewen,

> Some suggestion:
>
> 1) I am not sure if it is proper to use ASSERT in an exception handler, 
> because we know something is wrong.
>
>   ASSERT ((PhysicalAddress & (sizeof (*Pml4TableEntry) - 1)) == 0);
>
> I suggest we just do the check, and return FALSE, if the prerequisite is not 
> satisfied.

OK.

>
> 2) Can we use meaningful definition for BIT0, BIT7?
>
>   if ((*Pml4TableEntry & BIT0) == 0) {
>   if ((*PageDirPtrTableEntry & BIT7) != 0) {

Sure. Sorry for missing that.

>
> 3) I am not sure if I understand below code.
>
>   PhysicalAddress = (UINT64)Cr3 & (((1ULL << MaxPhyAddrBits) - 1) << 12);
>   PhysicalAddress = *Pml4TableEntry & (((1ULL << MaxPhyAddrBits) - 1) << 12);
>   PhysicalAddress = *PageDirPtrTableEntry & (((1ULL << MaxPhyAddrBits) - 1) 
> << 12);
>   PhysicalAddress = *PageDirEntry & (((1ULL << MaxPhyAddrBits) - 1) << 12);
>
> If MaxPhyAddrBits is 48, you will get "Cr3 & 0x0000". Is that 
> what you want? I think we need "Cr3 & 0xF000"
> Should it be: PhysicalAddress = (UINT64)Cr3 & ((1ULL << MaxPhyAddrBits) - 1) 
> & (~0xFFF);

Yes, it should. I've just re-checked the Intel SDM Vol 3A and your
calculation is correct. Thanks! I'll fix that up in next series.

>
> 4) Can we use a more readable way to below? Personally, I do not suggest "<< 
> 3", which is just the index calculation.
>
>   PhysicalAddress = (UINT64)Cr3 & (((1ULL << MaxPhyAddrBits) - 1) << 12);
>   PhysicalAddress |= (((UINT64)LinearAddress >> 39) & 0x1FF) << 3;
>   Pml4TableEntry = (UINT64 *)(UINTN)PhysicalAddress;
>   PhysicalAddress = *Pml4TableEntry & (((1ULL << MaxPhyAddrBits) - 1) << 12);
>
> For example:
>   PhysicalAddress = (UINT64)Cr3 & ((1ULL << MaxPhyAddrBits) - 1) & (~0xFFF);
>   Pml4TableEntry = (UINT64 *)(UINTN)PhysicalAddress;
>   Index= (UINTN)(((UINT64)LinearAddress >> 39) & 0x1FF);
>   PhysicalAddress = Pml4TableEntry[Index] & ((1ULL << MaxPhyAddrBits) - 1) & 
> (~0xFFF);

Sure. This way is much clearer, indeed.

Thank you very much for the effort on reviewing this!

Paulo

>> -Original Message-
>> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Paulo
>> Alcantara
>> Sent: Friday, December 29, 2017 12:40 PM
>> To: edk2-devel@lists.01.org
>> Cc: Laszlo Ersek <ler...@redhat.com>; Dong, Eric <eric.d...@intel.com>
>> Subject: [edk2] [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add helper to
>> valid memory addresses
>> 
>> Introduce IsLinearAddressValid() function that will be used for
>> validating memory addresses that would get dereferenced during stack
>> traces in IA32 and X64 CPU exceptions.
>> 
>> Contributed-under: TianoCore Contribution Agreement 1.1
>> Cc: Eric Dong <eric.d...@intel.com>
>> Cc: Laszlo Ersek <ler...@redhat.com>
>> Requested-by: Brian Johnson <brian.john...@hpe.com>
>> Requested-by: Jiewen Yao <jiewen@intel.com>
>> Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
>> ---
>>  UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c | 382
>> 
>>  UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h |  16 +
>>  2 files changed, 398 insertions(+)
>> 
>> diff --git
>> a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
>> b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
>> index 867c5c01d6..52b3eb1463 100644
>> --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
>> +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
>> @@ -14,6 +14,9 @@
>> 
>>  #include "CpuExceptionCommon.h"
>> 
>> +#include 
>> +#include 
>> +
>>  //
>>  // Error code flag indicating whether or not an error code will be
>>  // pushed on the stack if an exception occurs.
>> @@ -194,3 +197,382 @@ GetPdbFileName (
>>  }
>>}
>>  }
>> +
>> +/**
>> +  Check if a linear address is valid by walking the page tables in 4-level
>> +  paging mode.
>> +
>> +  @param[in]  Cr3 CR3 control register.
>> +  @param[in]  MaxPhyAddrBits  MAXPHYADDRBITS bits.
>> +  @param[in]  LinearAddress   Linear address to be checked.
>> +**/
>> +STATIC
>> +BOOLEAN
>> +Do4LevelPagingModeCheck (
>> +  IN UINTNCr3,
>> +  IN U

Re: [edk2] [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add helper to valid memory addresses

2018-01-04 Thread Paulo Alcantara
"Brian J. Johnson" <brian.john...@hpe.com> writes:

Hi Brian,

> On 12/28/2017 10:39 PM, Paulo Alcantara wrote:
>> +  //
>> +  // Check if paging is disabled
>> +  //
>> +  if ((Cr0 & BIT31) == 0) {
>> +//
>> +// If CR4.PAE bit is set, then the linear (or physical) address supports
>> +// only up to 36 bits.
>> +//
>> +if (((Cr4 & BIT5) != 0 && (UINT64)LinearAddress > 0xFULL) ||
>> +LinearAddress > 0x) {
>> +  return FALSE;
>> +}
>> +
>> +return TRUE;
>> +  }
>
> Paulo,
>
> The logic there doesn't look quite right:  if LinearAddress is between 
> 2^32 and 2^36-1, this code will always return FALSE, even if CR4.PAE is 
> set.  Shouldn't it be:
>
> if ((UINT64)LinearAddress > 0xFULL ||
> ((Cr4 & BIT5) == 0 && LinearAddress > 0x)) {
>   return FALSE;
> }

You're right. The check is bogus and I'll fix it up in the next version.

>
> (I haven't examined all the code in detail, I just happened to notice 
> this issue.)

No problem. Your comments are very appreciable.

> This bug should get fixed before pushing this series.  I also have some 
> more general design questions, which shouldn't hold up pushing the 
> series, but I think merit some discussion:
>
> This is great code for validating addresses in general, especially when 
> guard pages are in use for NULL pointers, stack overflow, etc.  Thanks 
> for adding it!  But for [er]sp and [er]bp validation, don't you really 
> just want to know if the address is in the expected stack range?  Maybe 
> the code which sets up the stack could communicate the valid range to 
> CpuExceptionHandlerLib somehow.  It could use special debug register 
> values like 
> SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c 
> does.  Or perhaps it could use dynamic PCDs (although I don't know that 
> it's a good idea to go looking up PCDs in an exception handler.)  Or 
> maybe there's a more straightforward way  It would have to take AP 
> stacks into account, and probably SetJump/LongJump as well.  That may or 
> may not be simpler than the current code

I'm not quite sure if I understood you correctly when you say that I
should be checking whether the address is in the expected range, but
using the debug registers to save call stack information seems like a
good idea, although it doesn't seem to be that simple as you mentioned.

>
> More generally, I'd like to see some sort of platform-specific callout 
> to further validate addresses.  Not all mapped addresses, or addresses 
> up to the architectural limit, are safe to access.  For instance, reads 
> to SMRAM outside of SMM will cause exceptions.  Also, we wouldn't want 
> to go backtracing through MMIO or MMCFG space:  reads there could 
> potentially have side effects on the hardware.

Yes - we should ensure that those regions are not accessed during the
stacktrace, as well as test this implementation a lot more.

>
> The rules can also vary at different points in boot.  For example, 
> before memory is initialized, Intel Xeon processors generally execute 
> 32-bit code in cache-as-RAM mode, where the caches are jury-rigged to 
> operate as temporary storage while the memory setup code is running.  In 
> CAR mode, only a few address ranges can be accessed without causing 
> machine checks:  the cache-as-RAM range containing the stack, heap, and 
> HOB list, the architectural firmware range below 4G, and a few specific 
> MMCFG and MMIO ranges.

Really great info. Thanks. We should take that into account as well.

>
> So I'd like to suggest that you define an AddressValidationLib library 
> class, which provides a routine which takes an address (or an address 
> range?) and an indication of the intended use (memory read, memory 
> write, execute/disassemble code, stack dump, IO, ...), and returns a 
> value specifying if the access is:
> - safe (IsLinearAddressValid() should return TRUE)
> - unsafe (IsLinearAddressValid() should return FALSE)
> - unknown (IsLinearAddressValid() should perform its other tests)
>
> You can supply a NULL instance which always returns "unknown" for 
> platforms which don't want to perform their own validation.

Great idea! I can do that for sure, but first of all, I'd like to make
sure the memory validation code is working correctly for IA32 and X64
platforms before introducing the AddressValidationLib library.

Thank you very much for the review and comments!

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


Re: [edk2] 答复: [RFC v4 1/6] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

2018-01-03 Thread Paulo Alcantara

Hi Jeff,

On 1/3/2018 6:53 AM, Fan Jeff wrote:

Paulo,

I did not receive your #0 patch. So, I reply #1 here.

Your serial of patches should work for IA32/X64 GCC and IA32 MSFT. I 
suggest you could push this serial of patches as soon as pass UefiCpuPkg 
owner/reviewers’ review and validation,


OK - That would be really appreciable if you could test it with IA32 
MSFT toolchain and see if the stacktrace is printed out correctly when 
passing the '/Oy-' compile option.




And then I could send my x64 MSFT support later.


Cool.

Thanks
Paulo



*From:* edk2-devel <edk2-devel-boun...@lists.01.org> on behalf of Paulo 
Alcantara <pa...@paulo.ac>

*Sent:* Friday, December 29, 2017 12:39:34 PM
*To:* edk2-devel@lists.01.org
*Cc:* Laszlo Ersek; Eric Dong
*Subject:* [edk2] [RFC v4 1/6] 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.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---
  UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 
376 +++-

  1 file changed, 374 insertions(+), 2 deletions(-)

diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c

index 1dcf4277de..19bfaa329a 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.
@@ -398,6 +403,357 @@ 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]  UnwoundStacksCount  Count of unwound stack frames.
+**/
+STATIC
+VOID
+DumpStackContents (
+  IN UINT64  CurrentRsp,
+  IN INTN    UnwoundStacksCount
+  )
+{
+  //
+  // 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 (UnwoundStacksCount-- > 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;
+  UINTN   LastImageBase;
+
+  //
+  // Set current RIP address
+  //
+  Rip = SystemContext.SystemContextX64->Rip;
+
+  //
+  // Set current frame pointer address
+  //
+ 

Re: [edk2] 答复: [RFC v4 5/6] UefiCpuPkg/CpuExceptionHandlerLib: Ensure valid frame/stack pointers

2018-01-03 Thread Paulo Alcantara

On 1/3/2018 6:45 AM, Fan Jeff wrote:

Paulo,

+    if (!IsLogicalAddressValid (SystemContext,
+    SystemContext.SystemContextIa32->Ss,
+    (UINTN)Ebp) ||
+    !IsLogicalAddressValid (SystemContext,
+    SystemContext.SystemContextIa32->Ss,
+    (UINTN)Ebp + 4)) {

I don’t understand why you check both ebp and ebp+4, I think it’s enough 
to only check EBP (saved stack pointer address)


Isn't it possible that EBP + 4 might potentially point to another page 
frame? If not, then I will drop it out in v5.


Thanks
Paulo



Jeff

*发件人: *Paulo Alcantara <mailto:pa...@paulo.ac>
*发送时间: *2017年12月29日12:41
*收件人: *edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org>
*抄送: *Laszlo Ersek <mailto:ler...@redhat.com>; Eric Dong 
<mailto:eric.d...@intel.com>
*主题: *[edk2] [RFC v4 5/6] UefiCpuPkg/CpuExceptionHandlerLib: Ensure 
valid frame/stack pointers


Validate all possible memory dereferences during stack traces in IA32
and X64 CPU exceptions.

Contributed-under: TianoCore Contribution Agreement 1.1
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Requested-by: Brian Johnson <brian.john...@hpe.com>
Requested-by: Jiewen Yao <jiewen@intel.com>
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---
  UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c 
| 143 +++-
  UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c  
|  75 +-

  2 files changed, 210 insertions(+), 8 deletions(-)

diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c

index 25e02fbbc1..9b52d4f6d2 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -398,6 +398,96 @@ DumpCpuContext (
  );
  }

+/**
+  Check if a logical address is valid.
+
+  @param[in]  SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
+  @param[in]  SegmentSelector    Segment selector.
+  @param[in]  Offset Offset or logical address.
+**/
+STATIC
+BOOLEAN
+IsLogicalAddressValid (
+  IN  EFI_SYSTEM_CONTEXT   SystemContext,
+  IN  UINT16   SegmentSelector,
+  IN  UINTN    Offset
+  )
+{
+  IA32_SEGMENT_DESCRIPTOR  *SegmentDescriptor;
+  UINT32   SegDescBase;
+  UINT32   SegDescLimit;
+  UINTN    SegDescLimitInBytes;
+
+  //
+  // Check for valid input parameters
+  //
+  if (SegmentSelector == 0 || Offset == 0) {
+    return FALSE;
+  }
+
+  //
+  // Check whether to look for a segment descriptor in GDT or LDT table
+  //
+  if ((SegmentSelector & BIT2) == 0) {
+    //
+    // Get segment descriptor from GDT table
+    //
+    SegmentDescriptor =
+  (IA32_SEGMENT_DESCRIPTOR *)(
+    (UINTN)SystemContext.SystemContextIa32->Gdtr[0] +
+    ((SegmentSelector >> 3) * 8)
+    );
+  } else {
+    //
+    // Get segment descriptor from LDT table
+    //
+    SegmentDescriptor =
+  (IA32_SEGMENT_DESCRIPTOR *)(
+    (UINTN)SystemContext.SystemContextIa32->Ldtr +
+    ((SegmentSelector >> 3) * 8)
+    );
+  }
+
+  //
+  // Get segment descriptor's base address
+  //
+  SegDescBase = SegmentDescriptor->Bits.BaseLow |
+    (SegmentDescriptor->Bits.BaseMid << 16) |
+    (SegmentDescriptor->Bits.BaseHigh << 24);
+
+  //
+  // Get segment descriptor's limit
+  //
+  SegDescLimit = SegmentDescriptor->Bits.LimitLow |
+    (SegmentDescriptor->Bits.LimitHigh << 16);
+
+  //
+  // Calculate segment descriptor's limit in bytes
+  //
+  if (SegmentDescriptor->Bits.G == 1) {
+    SegDescLimitInBytes = (UINTN)SegDescLimit * SIZE_4KB;
+  } else {
+    SegDescLimitInBytes = SegDescLimit;
+  }
+
+  //
+  // Make sure to not access beyond a segment limit boundary
+  //
+  if (Offset + SegDescBase > SegDescLimitInBytes) {
+    return FALSE;
+  }
+
+  //
+  // Check if the translated logical address (or linear address) is valid
+  //
+  return IsLinearAddressValid (
+    SystemContext.SystemContextIa32->Cr0,
+    SystemContext.SystemContextIa32->Cr3,
+    SystemContext.SystemContextIa32->Cr4,
+    Offset + SegDescBase
+    );
+}
+
  /**
    Dump stack trace.

@@ -459,6 +549,20 @@ DumpStackTrace (
    InternalPrintMessage ("\nCall trace:\n");

    for (;;) {
+    //
+    // Check for valid frame pointer
+    //
+    if (!IsLogicalAddressValid (SystemContext,
+    SystemContext.SystemContextIa32->Ss,
+    (UINTN)Ebp + 4) ||
+    !IsLogicalAddressValid (SystemContext,
+    SystemContext.SystemContextIa32->Ss,
+    (UINTN)Ebp)) {
+  

Re: [edk2] 答复: [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add helper to valid memory addresses

2018-01-03 Thread Paulo Alcantara

Hi Jeff,

On 1/3/2018 6:42 AM, Fan Jeff wrote:

Paul,

+  //
+  // Calculate physical address of PML4E
+  //
+  PhysicalAddress = (UINT64)Cr3 & (((1ULL << MaxPhyAddrBits) - 1) << 12);
+  PhysicalAddress |= (((UINT64)LinearAddress >> 39) & 0x1FF) << 3;
+

Should not pass VS build, instead you could use LShiftU64/RShiftU64 to 
do 64bit shift operation as below:


   PhysicalAddress = (UINT64)Cr3 & LShiftU64 (LShiftU64 (1, 
MaxPhyAddrBits) - 1, 12);


   PhysicalAddress |= LShiftU64 (RShiftU64((UINT64)LinearAddress, 39) & 
0x1FF), 3);


OK - I'll fix them up and then build-test it with IA32/X64 MSFT toolchain.

Thanks
Paulo



Jeff

*发件人: *Paulo Alcantara <mailto:pa...@paulo.ac>
*发送时间: *2017年12月29日12:41
*收件人: *edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org>
*抄送: *Laszlo Ersek <mailto:ler...@redhat.com>; Eric Dong 
<mailto:eric.d...@intel.com>
*主题: *[edk2] [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add 
helper to valid memory addresses


Introduce IsLinearAddressValid() function that will be used for
validating memory addresses that would get dereferenced during stack
traces in IA32 and X64 CPU exceptions.

Contributed-under: TianoCore Contribution Agreement 1.1
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Requested-by: Brian Johnson <brian.john...@hpe.com>
Requested-by: Jiewen Yao <jiewen@intel.com>
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---
  UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c | 382 


  UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h |  16 +
  2 files changed, 398 insertions(+)

diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c

index 867c5c01d6..52b3eb1463 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -14,6 +14,9 @@

  #include "CpuExceptionCommon.h"

+#include 
+#include 
+
  //
  // Error code flag indicating whether or not an error code will be
  // pushed on the stack if an exception occurs.
@@ -194,3 +197,382 @@ GetPdbFileName (
  }
    }
  }
+
+/**
+  Check if a linear address is valid by walking the page tables in 4-level
+  paging mode.
+
+  @param[in]  Cr3 CR3 control register.
+  @param[in]  MaxPhyAddrBits  MAXPHYADDRBITS bits.
+  @param[in]  LinearAddress   Linear address to be checked.
+**/
+STATIC
+BOOLEAN
+Do4LevelPagingModeCheck (
+  IN UINTN    Cr3,
+  IN UINT8    MaxPhyAddrBits,
+  IN UINTN    LinearAddress
+  )
+{
+  UINT64 PhysicalAddress;
+  UINT64 *Pml4TableEntry;
+  UINT64 *PageDirPtrTableEntry;
+  UINT64 *PageDirEntry;
+  UINT64 *PageTableEntry;
+
+  //
+  // In 4-level paging mode, linear addresses are 48 bits wide
+  //
+  if ((UINT64)LinearAddress > (1ULL << 48) - 1) {
+    return FALSE;
+  }
+
+  //
+  // Calculate physical address of PML4E
+  //
+  PhysicalAddress = (UINT64)Cr3 & (((1ULL << MaxPhyAddrBits) - 1) << 12);
+  PhysicalAddress |= (((UINT64)LinearAddress >> 39) & 0x1FF) << 3;
+
+  ASSERT ((PhysicalAddress & (sizeof (*Pml4TableEntry) - 1)) == 0);
+
+  Pml4TableEntry = (UINT64 *)(UINTN)PhysicalAddress;
+
+  //
+  // Check if a PDPTE is present
+  //
+  if ((*Pml4TableEntry & BIT0) == 0) {
+    return FALSE;
+  }
+
+  //
+  // Calculate physical address of PDPTE
+  //
+  PhysicalAddress = *Pml4TableEntry & (((1ULL << MaxPhyAddrBits) - 1) 
<< 12);

+  PhysicalAddress |= (((UINT64)LinearAddress >> 30) & 0x1FF) << 3;
+
+  ASSERT ((PhysicalAddress & (sizeof (*PageDirPtrTableEntry) - 1)) == 0);
+
+  PageDirPtrTableEntry = (UINT64 *)(UINTN)PhysicalAddress;
+
+  //
+  // Check whether a PDPTE or 1GiB page entry is present
+  //
+  if ((*PageDirPtrTableEntry & BIT0) == 0) {
+    return FALSE;
+  }
+
+  //
+  // Check if PDPTE maps an 1GiB page
+  //
+  if ((*PageDirPtrTableEntry & BIT7) != 0) {
+    return TRUE;
+  }
+
+  //
+  // Calculate physical address of PDE
+  //
+  PhysicalAddress = *PageDirPtrTableEntry & (((1ULL << MaxPhyAddrBits) 
- 1) <<

+ 12);
+  PhysicalAddress |= (((UINT64)LinearAddress >> 21) & 0x1FF) << 3;
+
+  ASSERT ((PhysicalAddress & (sizeof (*PageDirEntry) - 1)) == 0);
+
+  PageDirEntry = (UINT64 *)(UINTN)PhysicalAddress;
+
+  //
+  // Check whether a PDE or a 2MiB page entry is present
+  //
+  if ((*PageDirEntry & BIT0) == 0) {
+    return FALSE;
+  }
+
+  //
+  // Check if PDE maps a 2MiB page
+  //
+  if ((*PageDirEntry & BIT7) != 0) {
+    return TRUE;
+  }
+
+  //
+  // Calculate physical address of PTE
+  //
+  PhysicalAddress = *PageDirEntry & (((1ULL << MaxPhyAddrBits) - 1) << 12);
+  PhysicalAddress

[edk2] [RFC v4 2/6] UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName()

2017-12-28 Thread Paulo Alcantara
This function will be used by both IA32 and X64 exception handling in
order to print out image module names during stack unwinding.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c   | 60 
+++-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h   | 14 +
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 59 
---
 3 files changed, 73 insertions(+), 60 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index dbfaae1d30..f62ab8c48c 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -54,6 +54,11 @@ CONST CHAR8 *mExceptionNameStr[] = {
 
 #define EXCEPTION_KNOWN_NAME_NUM  (sizeof (mExceptionNameStr) / sizeof (CHAR8 
*))
 
+//
+// Unknown PDB file name
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mUnknownPdbFileName = "";
+
 /**
   Get ASCII format string exception name by exception type.
 
@@ -177,4 +182,57 @@ ReadAndVerifyVectorInfo (
 VectorInfo ++;
   }
   return EFI_SUCCESS;
-}
\ No newline at end of file
+}
+
+/**
+  Get absolute path and file name of PDB file in PE/COFF image.
+
+  @param[in]  ImageBaseBase address of PE/COFF image.
+  @param[out] PdbAbsoluteFilePath  Absolute path of PDB file.
+  @param[out] PdbFileName  File name of PDB file.
+**/
+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;
+}
+  }
+}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index e10d9379d5..64c7094513 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -327,5 +327,19 @@ AsmGetTssTemplateMap (
   OUT EXCEPTION_HANDLER_TEMPLATE_MAP  *AddressMap
   );
 
+/**
+  Get absolute path and file name of PDB file in PE/COFF image.
+
+  @param[in]  ImageBaseBase address of PE/COFF image.
+  @param[out] PdbAbsoluteFilePath  Absolute path of PDB file.
+  @param[out] PdbFileName  File name of PDB file.
+**/
+VOID
+GetPdbFileName (
+  IN  UINTNImageBase,
+  OUT CHAR8**PdbAbsoluteFilePath,
+  OUT CHAR8**PdbFileName
+  );
+
 #endif
 
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index 19bfaa329a..d3a3878b3d 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
@@ -14,11 +14,6 @@
 
 #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.
@@ -403,60 +398,6 @@ DumpCpuContext (
 );
 }
 
-/**
-  Get absolute path and file name of PDB file in PE/COFF image.
-
-  @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 = (C

[edk2] [RFC v4 4/6] UefiCpuPkg/CpuExceptionHandlerLib: Add helper to valid memory addresses

2017-12-28 Thread Paulo Alcantara
Introduce IsLinearAddressValid() function that will be used for
validating memory addresses that would get dereferenced during stack
traces in IA32 and X64 CPU exceptions.

Contributed-under: TianoCore Contribution Agreement 1.1
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Requested-by: Brian Johnson <brian.john...@hpe.com>
Requested-by: Jiewen Yao <jiewen@intel.com>
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c | 382 

 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h |  16 +
 2 files changed, 398 insertions(+)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index 867c5c01d6..52b3eb1463 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -14,6 +14,9 @@
 
 #include "CpuExceptionCommon.h"
 
+#include 
+#include 
+
 //
 // Error code flag indicating whether or not an error code will be
 // pushed on the stack if an exception occurs.
@@ -194,3 +197,382 @@ GetPdbFileName (
 }
   }
 }
+
+/**
+  Check if a linear address is valid by walking the page tables in 4-level
+  paging mode.
+
+  @param[in]  Cr3 CR3 control register.
+  @param[in]  MaxPhyAddrBits  MAXPHYADDRBITS bits.
+  @param[in]  LinearAddress   Linear address to be checked.
+**/
+STATIC
+BOOLEAN
+Do4LevelPagingModeCheck (
+  IN UINTNCr3,
+  IN UINT8MaxPhyAddrBits,
+  IN UINTNLinearAddress
+  )
+{
+  UINT64 PhysicalAddress;
+  UINT64 *Pml4TableEntry;
+  UINT64 *PageDirPtrTableEntry;
+  UINT64 *PageDirEntry;
+  UINT64 *PageTableEntry;
+
+  //
+  // In 4-level paging mode, linear addresses are 48 bits wide
+  //
+  if ((UINT64)LinearAddress > (1ULL << 48) - 1) {
+return FALSE;
+  }
+
+  //
+  // Calculate physical address of PML4E
+  //
+  PhysicalAddress = (UINT64)Cr3 & (((1ULL << MaxPhyAddrBits) - 1) << 12);
+  PhysicalAddress |= (((UINT64)LinearAddress >> 39) & 0x1FF) << 3;
+
+  ASSERT ((PhysicalAddress & (sizeof (*Pml4TableEntry) - 1)) == 0);
+
+  Pml4TableEntry = (UINT64 *)(UINTN)PhysicalAddress;
+
+  //
+  // Check if a PDPTE is present
+  //
+  if ((*Pml4TableEntry & BIT0) == 0) {
+return FALSE;
+  }
+
+  //
+  // Calculate physical address of PDPTE
+  //
+  PhysicalAddress = *Pml4TableEntry & (((1ULL << MaxPhyAddrBits) - 1) << 12);
+  PhysicalAddress |= (((UINT64)LinearAddress >> 30) & 0x1FF) << 3;
+
+  ASSERT ((PhysicalAddress & (sizeof (*PageDirPtrTableEntry) - 1)) == 0);
+
+  PageDirPtrTableEntry = (UINT64 *)(UINTN)PhysicalAddress;
+
+  //
+  // Check whether a PDPTE or 1GiB page entry is present
+  //
+  if ((*PageDirPtrTableEntry & BIT0) == 0) {
+return FALSE;
+  }
+
+  //
+  // Check if PDPTE maps an 1GiB page
+  //
+  if ((*PageDirPtrTableEntry & BIT7) != 0) {
+return TRUE;
+  }
+
+  //
+  // Calculate physical address of PDE
+  //
+  PhysicalAddress = *PageDirPtrTableEntry & (((1ULL << MaxPhyAddrBits) - 1) <<
+ 12);
+  PhysicalAddress |= (((UINT64)LinearAddress >> 21) & 0x1FF) << 3;
+
+  ASSERT ((PhysicalAddress & (sizeof (*PageDirEntry) - 1)) == 0);
+
+  PageDirEntry = (UINT64 *)(UINTN)PhysicalAddress;
+
+  //
+  // Check whether a PDE or a 2MiB page entry is present
+  //
+  if ((*PageDirEntry & BIT0) == 0) {
+return FALSE;
+  }
+
+  //
+  // Check if PDE maps a 2MiB page
+  //
+  if ((*PageDirEntry & BIT7) != 0) {
+return TRUE;
+  }
+
+  //
+  // Calculate physical address of PTE
+  //
+  PhysicalAddress = *PageDirEntry & (((1ULL << MaxPhyAddrBits) - 1) << 12);
+  PhysicalAddress |= (((UINT64)LinearAddress >> 12) & 0x1FF) << 3;
+
+  ASSERT ((PhysicalAddress & (sizeof (*PageTableEntry) - 1)) == 0);
+
+  PageTableEntry = (UINT64 *)(UINTN)PhysicalAddress;
+
+  //
+  // Check if PTE maps a 4KiB page
+  //
+  if ((*PageTableEntry & BIT0) == 0) {
+return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  Check if a linear address is valid by walking the page tables in 32-bit 
paging
+  mode.
+
+  @param[in]  Cr3 CR3 control register.
+  @param[in]  Cr4 CR4 control register.
+  @param[in]  LinearAddress   Linear address to be checked.
+**/
+STATIC
+BOOLEAN
+Do32BitPagingModeCheck (
+  IN UINTNCr3,
+  IN UINTNCr4,
+  IN UINTNLinearAddress
+  )
+{
+  UINT64 PhysicalAddress;
+  UINT32 *PageDirEntry;
+  UINT32 *PageTableEntry;
+
+  if (LinearAddress > MAX_UINT32) {
+return FALSE;
+  }
+
+  //
+  // Calculate physical address of PDE
+  //
+  PhysicalAddress = (UINT32)Cr3 & (((1ULL << 20) - 1) << 12);
+  PhysicalAdd

[edk2] [RFC v4 5/6] UefiCpuPkg/CpuExceptionHandlerLib: Ensure valid frame/stack pointers

2017-12-28 Thread Paulo Alcantara
Validate all possible memory dereferences during stack traces in IA32
and X64 CPU exceptions.

Contributed-under: TianoCore Contribution Agreement 1.1
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Requested-by: Brian Johnson <brian.john...@hpe.com>
Requested-by: Jiewen Yao <jiewen@intel.com>
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 143 
+++-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c  |  75 
+-
 2 files changed, 210 insertions(+), 8 deletions(-)

diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
index 25e02fbbc1..9b52d4f6d2 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -398,6 +398,96 @@ DumpCpuContext (
 );
 }
 
+/**
+  Check if a logical address is valid.
+
+  @param[in]  SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
+  @param[in]  SegmentSelectorSegment selector.
+  @param[in]  Offset Offset or logical address.
+**/
+STATIC
+BOOLEAN
+IsLogicalAddressValid (
+  IN  EFI_SYSTEM_CONTEXT   SystemContext,
+  IN  UINT16   SegmentSelector,
+  IN  UINTNOffset
+  )
+{
+  IA32_SEGMENT_DESCRIPTOR  *SegmentDescriptor;
+  UINT32   SegDescBase;
+  UINT32   SegDescLimit;
+  UINTNSegDescLimitInBytes;
+
+  //
+  // Check for valid input parameters
+  //
+  if (SegmentSelector == 0 || Offset == 0) {
+return FALSE;
+  }
+
+  //
+  // Check whether to look for a segment descriptor in GDT or LDT table
+  //
+  if ((SegmentSelector & BIT2) == 0) {
+//
+// Get segment descriptor from GDT table
+//
+SegmentDescriptor =
+  (IA32_SEGMENT_DESCRIPTOR *)(
+(UINTN)SystemContext.SystemContextIa32->Gdtr[0] +
+((SegmentSelector >> 3) * 8)
+);
+  } else {
+//
+// Get segment descriptor from LDT table
+//
+SegmentDescriptor =
+  (IA32_SEGMENT_DESCRIPTOR *)(
+(UINTN)SystemContext.SystemContextIa32->Ldtr +
+((SegmentSelector >> 3) * 8)
+);
+  }
+
+  //
+  // Get segment descriptor's base address
+  //
+  SegDescBase = SegmentDescriptor->Bits.BaseLow |
+(SegmentDescriptor->Bits.BaseMid << 16) |
+(SegmentDescriptor->Bits.BaseHigh << 24);
+
+  //
+  // Get segment descriptor's limit
+  //
+  SegDescLimit = SegmentDescriptor->Bits.LimitLow |
+(SegmentDescriptor->Bits.LimitHigh << 16);
+
+  //
+  // Calculate segment descriptor's limit in bytes
+  //
+  if (SegmentDescriptor->Bits.G == 1) {
+SegDescLimitInBytes = (UINTN)SegDescLimit * SIZE_4KB;
+  } else {
+SegDescLimitInBytes = SegDescLimit;
+  }
+
+  //
+  // Make sure to not access beyond a segment limit boundary
+  //
+  if (Offset + SegDescBase > SegDescLimitInBytes) {
+return FALSE;
+  }
+
+  //
+  // Check if the translated logical address (or linear address) is valid
+  //
+  return IsLinearAddressValid (
+SystemContext.SystemContextIa32->Cr0,
+SystemContext.SystemContextIa32->Cr3,
+SystemContext.SystemContextIa32->Cr4,
+Offset + SegDescBase
+);
+}
+
 /**
   Dump stack trace.
 
@@ -459,6 +549,20 @@ DumpStackTrace (
   InternalPrintMessage ("\nCall trace:\n");
 
   for (;;) {
+//
+// Check for valid frame pointer
+//
+if (!IsLogicalAddressValid (SystemContext,
+SystemContext.SystemContextIa32->Ss,
+(UINTN)Ebp + 4) ||
+!IsLogicalAddressValid (SystemContext,
+SystemContext.SystemContextIa32->Ss,
+(UINTN)Ebp)) {
+  InternalPrintMessage ("%a: attempted to dereference an invalid frame "
+"pointer at 0x%08x\n", __FUNCTION__, Ebp);
+  break;
+}
+
 //
 // Print stack frame in the following format:
 //
@@ -588,6 +692,16 @@ DumpImageModuleNames (
   // Walk through call stack and find next module names
   //
   for (;;) {
+if (!IsLogicalAddressValid (SystemContext,
+SystemContext.SystemContextIa32->Ss,
+(UINTN)Ebp) ||
+!IsLogicalAddressValid (SystemContext,
+SystemContext.SystemContextIa32->Ss,
+(UINTN)Ebp + 4)) {
+  InternalPrintMessage ("%a: attempted to dereference an invalid frame "
+"pointer at 0x%08x\n", __FUNCTION__, Ebp);
+}
+
 //
 // Set EIP with return address from current stack frame
 //
@@ -651,16 +765,23 @@

[edk2] [RFC v4 6/6] UefiCpuPkg/CpuExceptionHandlerLib: Correctly print IP addresses

2017-12-28 Thread Paulo Alcantara
Remove the supurious '- 1' when calculating the IP addresses during the
stack traces.

Contributed-under: TianoCore Contribution Agreement 1.1
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Requested-by: Jeff Fan <vanjeff_...@hotmail.com>
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 2 +-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
index 9b52d4f6d2..e2a3341286 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -573,7 +573,7 @@ DumpStackTrace (
   *UnwoundStacksCount - 1,
   Eip,
   ImageBase,
-  Eip - ImageBase - 1,
+  Eip - ImageBase,
   Ebp,
   PdbFileName
   );
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index 8067c34122..5ae3aa4e73 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
@@ -717,7 +717,7 @@ DumpStackTrace (
   *UnwoundStacksCount - 1,
   Rip,
   ImageBase,
-  Rip - ImageBase - 1,
+  Rip - ImageBase,
   Rbp,
   PdbFileName
   );
-- 
2.14.3

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


[edk2] [RFC v4 1/6] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

2017-12-28 Thread Paulo Alcantara
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 <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 376 
+++-
 1 file changed, 374 insertions(+), 2 deletions(-)

diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index 1dcf4277de..19bfaa329a 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.
@@ -398,6 +403,357 @@ DumpCpuContext (
 );
 }
 
+/**
+  Get absolute path and file name of PDB file in PE/COFF image.
+
+  @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]  UnwoundStacksCount  Count of unwound stack frames.
+**/
+STATIC
+VOID
+DumpStackContents (
+  IN UINT64  CurrentRsp,
+  IN INTNUnwoundStacksCount
+  )
+{
+  //
+  // 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 (UnwoundStacksCount-- > 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;
+  UINTN   LastImageBase;
+
+  //
+  // 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;
+  }
+
+  //
+  // Set last PE/COFF image base address
+  //
+  LastImageBase = ImageBase;
+
+  //
+  // 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)
+  //

[edk2] [RFC v4 3/6] UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support

2017-12-28 Thread Paulo Alcantara
This patch adds stack trace support during a IA32 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 <pa...@paulo.ac>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c|  42 ---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h|  11 -
 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 310 
+++-
 3 files changed, 308 insertions(+), 55 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index f62ab8c48c..867c5c01d6 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -109,48 +109,6 @@ InternalPrintMessage (
   SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
 }
 
-/**
-  Find and display image base address and return image base and its entry 
point.
-
-  @param CurrentEip  Current instruction pointer.
-
-**/
-VOID
-DumpModuleImageInfo (
-  IN  UINTN  CurrentEip
-  )
-{
-  EFI_STATUS   Status;
-  UINTNPe32Data;
-  VOID *PdbPointer;
-  VOID *EntryPoint;
-
-  Pe32Data = PeCoffSearchImageBase (CurrentEip);
-  if (Pe32Data == 0) {
-InternalPrintMessage (" Can't find image information. \n");
-  } else {
-//
-// Find Image Base entry point
-//
-Status = PeCoffLoaderGetEntryPoint ((VOID *) Pe32Data, );
-if (EFI_ERROR (Status)) {
-  EntryPoint = NULL;
-}
-InternalPrintMessage (" Find image ");
-PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);
-if (PdbPointer != NULL) {
-  InternalPrintMessage ("%a", PdbPointer);
-} else {
-  InternalPrintMessage ("(No PDB) " );
-}
-InternalPrintMessage (
-  " (ImageBase=%016lp, EntryPoint=%016p) \n",
-  (VOID *) Pe32Data,
-  EntryPoint
-  );
-  }
-}
-
 /**
   Read and save reserved vector information
 
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 64c7094513..ec46c2d9d3 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -130,17 +130,6 @@ InternalPrintMessage (
   ...
   );
 
-/**
-  Find and display image base address and return image base and its entry 
point.
-
-  @param CurrentEip  Current instruction pointer.
-
-**/
-VOID
-DumpModuleImageInfo (
-  IN  UINTN  CurrentEip
-  );
-
 /**
   Display CPU information.
 
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
index 6ac8549839..25e02fbbc1 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -398,6 +398,296 @@ DumpCpuContext (
 );
 }
 
+/**
+  Dump stack trace.
+
+  @param[in]  SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
+  @param[out] UnwoundStacksCount  Count of unwound stack frames.
+**/
+STATIC
+VOID
+DumpStackTrace (
+  IN  EFI_SYSTEM_CONTEXT   SystemContext,
+  OUT INTN *UnwoundStacksCount
+  )
+{
+  UINT32  Eip;
+  UINT32  Ebp;
+  UINTN   ImageBase;
+  CHAR8   *PdbFileName;
+
+  //
+  // Set current EIP address
+  //
+  Eip = SystemContext.SystemContextIa32->Eip;
+
+  //
+  // Set current frame pointer address
+  //
+  Ebp = SystemContext.SystemContextIa32->Ebp;
+
+  //
+  // Check for proper frame pointer alignment
+  //
+  if (((UINTN)Ebp & (CPU_STACK_ALIGNMENT - 1)) != 0) {
+InternalPrintMessage (" Unaligned frame pointer. \n");
+return;
+  }
+
+  //
+  // Get initial PE/COFF image base address from current EIP
+  //
+  ImageBase = PeCoffSearchImageBase (Eip);
+  if (ImageBase == 0) {
+InternalPrintMessage (" Could not find backtrace information. ");
+return;
+  }
+
+  //
+  // Get PDB file name from initial PE/COFF image
+  //
+  GetPdbFileName (ImageBase, NULL, );
+
+  //
+  // Initialize count of unwound stacks
+  //
+  *UnwoundStacksCount = 1;
+
+  //
+  // Print out back trace
+  //
+  InternalPrintMessage ("\nCall trace:\n");
+
+  for (;;) {
+//
+// Print stack frame in the following format:
+//
+// #  @ + (EBP) in [ | ]
+//
+InternalPrintMessage (
+  "%d 0x%08x @ 0x%08x+0x%x (0x%08x) in %a\n",
+  *UnwoundStacksCount - 1,
+ 

[edk2] [RFC v4 0/6] Stack trace support in X64 exception handling

2017-12-28 Thread Paulo Alcantara
Hi,

This series adds stack trace support during IA32 and X64 CPU exceptions.

Informations like back trace, stack contents and image module names
(that were part of the call stack) will be dumped out.

The current limitation is that it relies on available frame pointers
(GCC only) in order to successfully unwind the stack.

(Sorry for the very long delay - I was very busy working on something
 else and then went to vacations)

Jiewen,

I have tested it with VS2015x86 and the stack trace just hanged when
printing out the first EIP (that is, no frame pointer at all).

Thanks!
Paulo

Repo:   https://github.com/pcacjr/edk2.git
Branch: stacktrace_v4

Cc: Rick Bramley <richard.bram...@hp.com>
Cc: Andrew Fish <af...@apple.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Brian Johnson <brian.john...@hpe.com>
Cc: Jeff Fan <vanjeff_...@hotmail.com>
Cc: Jiewen Yao <jiewen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pa...@paulo.ac>
---

v1 -> v2:
  * Add IA32 arch support (GCC toolchain only)
  * Replace hard-coded stack alignment value (16) with
CPU_STACK_ALIGNMENT.
  * Check for proper stack and frame pointer alignments.
  * Fix initialization of UnwoundStacksCount to 1.
  * Move GetPdbFileName() to common code since it will be used by both
IA32 and X64 implementations.

v2 -> v3:
  * Fixed wrong assumption about "RIP < ImageBase" to start searching
for another PE/COFF image. That is, RIP may point to lower and
higher addresses for any other PE/COFF images. Both IA32 & X64.
(Thanks Andrew & Jiewen)
  * Fixed typo: unwond -> unwound. Both IA32 & X64. (Thanks Brian)

v3 -> v4:
  * Validate all frame/stack pointer addresses before dereferencing them
as requested by Brian & Jiewen.
  * Correctly print out IP addresses during the stack traces (by Jeff)

Paulo Alcantara (6):
  UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
  UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName()
  UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support
  UefiCpuPkg/CpuExceptionHandlerLib: Add helper to valid memory
addresses
  UefiCpuPkg/CpuExceptionHandlerLib: Ensure valid frame/stack pointers
  UefiCpuPkg/CpuExceptionHandlerLib: Correctly print IP addresses

 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c| 484 
++--
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h|  41 +-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 445 
+-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c  | 384 
+++-
 4 files changed, 1296 insertions(+), 58 deletions(-)

-- 
2.14.3

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


Re: [edk2] 答复: [RFC v3 1/3] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

2017-11-20 Thread Paulo Alcantara

Hi Jeff,

(sorry for the late response)

On 11/17/2017 5:24 AM, Fan Jeff wrote:

Paulo,


I don't understand why you - 1 when calculating EIP offset in image, it 
confused me.


That's an offset relative to the PE/COFF image base: 0 - (ImageBase + 
ImageBaseSize - 1)


Doesn't that look right to you?

Thanks
Paulo




+  for (;;) {
+    //
+    // Print stack frame in the following format:
+    //
+    // #  @ + (RBP) in [ | ]
+    //
+    InternalPrintMessage (
+  "%d 0x%016lx @ 0x%016lx+0x%x (0x%016lx) in %a\n",
+  *UnwoundStacksCount - 1,
+  Rip,
+  ImageBase,
+  Rip - ImageBase - 1,   // 
+  Rbp,
+  PdbFileName
+  );
+

Jeff





*发件人:* edk2-devel <edk2-devel-boun...@lists.01.org> 代表 Paulo 
Alcantara <pca...@zytor.com>

*发送时间:* 2017年11月17日 5:56
*收件人:* edk2-devel@lists.01.org
*抄送:* Laszlo Ersek; Eric Dong
*主题:* [edk2] [RFC v3 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.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
  UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 
376 +++-

  1 file changed, 374 insertions(+), 2 deletions(-)

diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c

index 65f0cff680..fe776ccc2d 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,357 @@ 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]  UnwoundStacksCount  Count of unwound stack frames.
+**/
+STATIC
+VOID
+DumpStackContents (
+  IN UINT64  CurrentRsp,
+  IN INTN    UnwoundStacksCount
+  )
+{
+  //
+  // 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 (UnwoundStacksCount-- > 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;
+  UINTN   LastImageBase;
+
+  //
+  // Set current RIP ad

Re: [edk2] [RFC v2 1/3] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

2017-11-20 Thread Paulo Alcantara

Hi Jiewen,

(sorry for the late response)

On 11/17/2017 1:43 AM, Yao, Jiewen wrote:

Thanks for your reply. Comments below:


-Original Message-
From: Paulo Alcantara [mailto:pca...@zytor.com]
Sent: Friday, November 17, 2017 6:13 AM
To: Yao, Jiewen <jiewen@intel.com>
Cc: Paulo Alcantara <pca...@zytor.com>; edk2-devel@lists.01.org; Laszlo Ersek
<ler...@redhat.com>; Dong, Eric <eric.d...@intel.com>
Subject: RE: [edk2] [RFC v2 1/3] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add
stack trace support

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.


[Jiewen] Not work is OK.
But my question is more about: Have you tested? Or have you tried?
Do you see basic exception information can be dumped without any problem for 
MSVC?
Or do you see system crash immediately for MSVC?


No, I haven't tried it. I built it with VS2015 and just run 'objdump -x 
-D' in an arbitrary .efi to check whether RBP was being used in 
function's prologues. They weren't and then I didn't even give it try. 
I'll test it though and then let you know its behavior.







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.



[Jiewen] Ummm.
Based upon the fact that the code you update may be used in all those phases.
I recommend to validate them in the final patch.


Sure.





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.


[Jiewen] OK. I look forward to seeing your patch to validate more.
Same as #2. I suggest you validate all those corner cases in the final patch.


I will for sure.




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.



[Jiewen] One possible solution is to scan page table, before access this 
address, to make sure you are accessing present page.
You can also filer invalid address directly by checking CPUID physical address 
bit before that. The invalid address will cause #GP instead of #PF.


Oh, looks like a great solution. I'll try them out and let you know if 
it worked. Thank you!!




All I all, I would like to clarify the goal for exception lib: whatever 
exception condition the BIOS meets, the exception handler can always dump the 
*basic* exception information and halt.
The missing of advanced symbol info is acceptable. But system crash, when we 
want to dump the advanced info, is not the best choice.


You're right. I'll make sure to validate it as much as possible and 
avoid such issues. Please, give me some more time because currently I've 
got pretty busy with something else.


I really appreciate your help. Thanks!

Paulo






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.



[Jiewen] Great. Thanks.



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-boun...@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 <ler...@redhat.com>; Dong, Eric <eric.d...@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.d...@intel.com>
Cc: Laszlo 

Re: [edk2] [PATCH v2 1/2] MdeModulePkg/PartitionDxe: Merge the discovery of ElTorito into UDF

2017-11-16 Thread Paulo Alcantara

On Thu, November 16, 2017 5:47 am, Hao Wu wrote:
> In order to create all of the children (El Torito standard and UDF) for
> a CD/DVD media in an entry of the PartitionDriverBindingStart(), this
> commit merges the discovery of the El Torito feature
> (PartitionInstallElToritoChildHandles) into function
> PartitionInstallUdfChildHandles.
>
> Cc: Paulo Alcantara <pca...@zytor.com>
> Cc: Ruiyu Ni <ruiyu...@intel.com>
> Cc: Star Zeng <star.z...@intel.com>
> Cc: Eric Dong <eric.d...@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Hao Wu <hao.a...@intel.com>
> ---
>  MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c |  7 +++--
>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c   | 27
> ++++++--
>  2 files changed, 28 insertions(+), 6 deletions(-)

Reviewed-by: Paulo Alcantara <pca...@zytor.com>

Thanks!
Paulo

>
> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c
> b/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c
> index f6030e0897..603abfe55a 100644
> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c
> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c
> @@ -43,7 +43,6 @@ EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding = {
>  //
>  PARTITION_DETECT_ROUTINE mPartitionDetectRoutineTable[] = {
>PartitionInstallGptChildHandles,
> -  PartitionInstallElToritoChildHandles,
>PartitionInstallMbrChildHandles,
>PartitionInstallUdfChildHandles,
>NULL
> @@ -306,9 +305,9 @@ PartitionDriverBindingStart (
>if (BlockIo->Media->MediaPresent ||
>(BlockIo->Media->RemovableMedia &&
> !BlockIo->Media->LogicalPartition)) {
>  //
> -// Try for GPT, then El Torito, then UDF, and then legacy MBR
> partition
> -// types. If the media supports a given partition type install child
> handles
> -// to represent the partitions described by the media.
> +// Try for GPT, then legacy MBR partition types, and then UDF and El
> Torito.
> +// If the media supports a given partition type install child handles
> to
> +// represent the partitions described by the media.
>  //
>  Routine = [0];
>  while (*Routine != NULL) {
> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> index 7eee748958..5aac5640f6 100644
> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
> @@ -688,8 +688,10 @@ PartitionInstallUdfChildHandles (
>EFI_PARTITION_INFO_PROTOCOL  PartitionInfo;
>EFI_LBA  StartingLBA;
>EFI_LBA  EndingLBA;
> +  BOOLEAN  ChildCreated;
>
>Media = BlockIo->Media;
> +  ChildCreated = FALSE;
>
>//
>// Check if UDF logical block size is multiple of underlying device
> block size
> @@ -704,11 +706,29 @@ PartitionInstallUdfChildHandles (
>}
>
>//
> +  // Detect El Torito feature first.
> +  // And always continue to search for UDF.
> +  //
> +  Status = PartitionInstallElToritoChildHandles (
> + This,
> + Handle,
> + DiskIo,
> + DiskIo2,
> + BlockIo,
> + BlockIo2,
> + DevicePath
> + );
> +  if (!EFI_ERROR (Status)) {
> +DEBUG ((DEBUG_INFO, "PartitionDxe: El Torito standard found on handle
> 0x%p.\n", Handle));
> +ChildCreated = TRUE;
> +  }
> +
> +  //
>// Search for an UDF file system on block device
>//
>Status = FindUdfFileSystem (BlockIo, DiskIo, , );
>if (EFI_ERROR (Status)) {
> -return EFI_NOT_FOUND;
> +return (ChildCreated ? EFI_SUCCESS : EFI_NOT_FOUND);
>}
>
>//
> @@ -735,6 +755,9 @@ PartitionInstallUdfChildHandles (
>  EndingLBA,
>  Media->BlockSize
>  );
> +  if (EFI_ERROR (Status)) {
> +return (ChildCreated ? EFI_SUCCESS : Status);
> +  }
>
> -  return Status;
> +  return EFI_SUCCESS;
>  }
> --
> 2.12.0.windows.1
>
>


-- 
Paulo Alcantara, HP Inc.
Speaking for myself only.
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] [RFC v2 1/3] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

2017-11-16 Thread Paulo Alcantara
tack 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, );
>> +
>> +  //
>> +  // Initialize count of unwond stacks
>> +  //
>> +  *UnwondStacksCount = 1;
>> +
>> +  //
>> +  // Print out back trace
>> +  //
>> +  InternalPrintMessage ("\nCall trace:\n");
>> +
>> +  for (;;) {
>> +//
>> +// Print stack frame in the following format:
>> +//
>> +// #  @ + (RBP) in [ | ]
>> +//
>> +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, );
>> +}
>> +
>> +//
>> +// 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, );
>> +
>> +  //
>> +  // 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);
>>   }
>>
>
>
> --
> Brian J. Johnson
> Enterprise X86 Lab
>
> Hewlett Packard Enterprise
>
> brian.john...@hpe.com
>
> ___
> 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.
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] [RFC v2 1/3] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

2017-11-16 Thread Paulo Alcantara
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-boun...@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 <ler...@redhat.com>; Dong, Eric <eric.d...@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.d...@intel.com>
>> Cc: Laszlo Ersek <ler...@redhat.com>
>> Signed-off-by: Paulo Alcantara <pca...@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]  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);
>&

Re: [edk2] [RFC v2 0/3] Stack trace support in X64 exception handling

2017-11-16 Thread Paulo Alcantara
Hi Andrew,

On Thu, November 16, 2017 3:01 am, Andrew Fish wrote:
> Paulo,
>
> Those attached stack traces don't look right.

What about the new ones?

Thanks!
Paulo

>
> Thanks,
>
> Andrew Fish
>
>> On Nov 15, 2017, at 5:46 PM, Paulo Alcantara <pca...@zytor.com> wrote:
>>
>> Hi,
>>
>> On 11/15/2017 11:18 PM, Paulo Alcantara wrote:
>>> Hi,
>>> This series adds stack trace support during a X64 CPU exception.
>>> Informations like back trace, stack contents and image module names
>>> (that were part of the call stack) will be dumped out.
>>> We already have such support in ARM/AArch64 (IIRC) exception handling
>>> (thanks to Ard), and then I thought we'd also deserve it in X64 and
>>> IA-32 platforms.
>>> What do you think guys?
>>> BTW, I've tested this only with OVMF (X64 only), using:
>>>   - gcc-6.3.0, GCC5, NOOPT
>>> Any other tests  would be really appreciable.
>>> Thanks!
>>> Paulo
>>> Repo:   https://github.com/pcacjr/edk2.git
>>> Branch: stacktrace_v2
>>> Cc: Rick Bramley <richard.bram...@hp.com>
>>> Cc: Andrew Fish <af...@apple.com>
>>> Cc: Eric Dong <eric.d...@intel.com>
>>> Cc: Laszlo Ersek <ler...@redhat.com>
>>> Cc: "Brian J. Johnson" <brian.john...@hpe.com>
>>> Cc: Jeff Fan <jeff@intel.com>
>>> Contributed-under: TianoCore Contribution Agreement 1.1
>>> Signed-off-by: Paulo Alcantara <pca...@zytor.com>
>>> ---
>>> v1 -> v2:
>>>   * Add IA32 arch support (GCC toolchain only)
>>>   * Replace hard-coded stack alignment value (16) with
>>> CPU_STACK_ALIGNMENT.
>>>   * Check for proper stack and frame pointer alignments.
>>>   * Fix initialization of UnwoundStacksCount to 1.
>>>   * Move GetPdbFileName() to common code since it will be used by both
>>> IA32 and X64 implementations.
>>
>> Sorry for the delay in sending v2. It's holiday here :-)
>>
>> FWIW, I've attached two files which contain stack trace dumps of IA32
>> and X64 exceptions.
>>
>> The new IA32 arch support is still limited to GCC only (that is, relying
>> on frame pointers), but I'll start investing in a new solution that
>> would work on both MSVC and GCC toolchains -- probably this weekend. If
>> I come up with something, I'll let you know.
>>
>> On IA32, I performed the same test as in X64 to trigger an NMI interrupt
>> manually with: asm ("int $0x2") in PartitionDxe driver and watched out
>> the call stack. The difference between the two dumps, regardless the CPU
>> context, etc. is that we don't see the calls from PeiCore.dll. Then I
>> figured out that the EIP gets a value of 0 before jumping to
>> PartitionDxe's entry point.
>>
>> I guess that's related to the "push $0" that Andrew mentioned earlier so
>> the debugger knows when to stop unwinding. Although I can't see a "push
>> 0" equivalent neither in SwitchStack.nasm nor in SwitchStack.asm for X64
>> -- so we're able to see the calls within PeiCore.dll.
>>
>> Thanks!
>> Paulo
>> ___
>> edk2-devel mailing list
>> edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org>
>> https://lists.01.org/mailman/listinfo/edk2-devel
>> <https://lists.01.org/mailman/listinfo/edk2-devel>
>


-- 
Paulo Alcantara, HP Inc.
Speaking for myself only. IA32 Exception Type - 03(#BP - Breakpoint)  CPU Apic ID -  
EIP  - 7DBCD580, CS  - 0010, EFLAGS - 0206
EAX  - , ECX - 7EEC8CFF, EDX - 7ED9C220, EBX - 
ESP  - 7EEC8DDC, EBP - 7EEC8DDC, ESI - 0004, EDI - 
DS   - 0008, ES  - 0008, FS  - 0008, GS  - 0008, SS - 0008
CR0  - 0033, CR2 - , CR3 - , CR4 - 0640
DR0  - , DR1 - , DR2 - , DR3 - 
DR6  - 0FF0, DR7 - 0400
GDTR - 7EE97A90 0047, IDTR - 7E65B010 07FF
LDTR - , TR - 
FXSAVE_STATE - 7EEC8B20

Call trace:
0 0x7DBCD580 @ 0x7DBCD000+0x57F (0x7EEC8DDC) in PartitionDxe.dll
1 0x7DBD41BE @ 0x7DBCD000+0x71BD (0x7EEC8DFC) in PartitionDxe.dll
2 0x7DBD456C @ 0x7DBCD000+0x756B (0x7EEC8E1C) in PartitionDxe.dll
3 0x7DBCF7F4 @ 0x7DBCD000+0x27F3 (0x7EEC8E4C) in PartitionDxe.dll
4 0x7EED9EA4 @ 0x7EEC9000+0x10EA3 (0x7EEC8E9C) in DxeCore.dll
5 0x7EEF1A8C @ 0x7EEC9000+0x28A8B (0x7EEC8EDC) in DxeCore.dll
6 0x7EEF3DD0 @ 0x7EEC9000+0x2ADCF (0x7EEC8FAC) in DxeCore.dll
7 0x7EEF44A5 @ 0x7EEC9000+0x2B4A4 (0x7EEC8FCC) in DxeCore.dll
8 0x7EECD272 @ 0x7EEC9000+0x4271 (0x7EEC8FEC) in DxeCore.dll

Partitio

[edk2] [RFC v3 0/3] Stack trace support in X64 exception handling

2017-11-16 Thread Paulo Alcantara
Hi,

This series adds stack trace support during a X64 CPU exception.

Informations like back trace, stack contents and image module names
(that were part of the call stack) will be dumped out.

We already have such support in ARM/AArch64 (IIRC) exception handling
(thanks to Ard), and then I thought we'd also deserve it in X64 and
IA-32 platforms.

What do you think guys?

BTW, I've tested this only with OVMF (X64 only), using:
  - gcc-6.3.0, GCC5, NOOPT

Any other tests  would be really appreciable.

Thanks!
Paulo

Repo:   https://github.com/pcacjr/edk2.git
Branch: stacktrace_v2

Cc: Rick Bramley <richard.bram...@hp.com>
Cc: Andrew Fish <af...@apple.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: brian.john...@hpe.com
Cc: jiewen@intel.com
Cc: Jeff Fan <jeff@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---

v1 -> v2:
  * Add IA32 arch support (GCC toolchain only)
  * Replace hard-coded stack alignment value (16) with
CPU_STACK_ALIGNMENT.
  * Check for proper stack and frame pointer alignments.
  * Fix initialization of UnwoundStacksCount to 1.
  * Move GetPdbFileName() to common code since it will be used by both
IA32 and X64 implementations.

v2 -> v3:
  * Fixed wrong assumption about "RIP < ImageBase" to start searching
for another PE/COFF image. That is, RIP may point to lower and
higher addresses for any other PE/COFF images. Both IA32 & X64.
(Thanks Andrew & Jiewen)
  * Fixed typo: unwond -> unwound. Both IA32 & X64. (Thanks Brian)

Brian: I didn't have a chance to investigate on how to validate the RIP
and RSP values yet as you've suggested, sorry. But I will any time soon.

NOTE: This RFC for stack trace in IA32 & X64 supports *only* GCC at the
moment.

Paulo Alcantara (3):
  UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
  UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName()
  UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support

 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c| 102 
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h|  25 +-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 310 
++-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c  | 317 
+++-
 4 files changed, 696 insertions(+), 58 deletions(-)

-- 
2.14.3

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


[edk2] [RFC v3 3/3] UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support

2017-11-16 Thread Paulo Alcantara
This patch adds stack trace support during a IA32 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/CpuExceptionCommon.c|  42 ---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h|  11 -
 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 310 
+++-
 3 files changed, 308 insertions(+), 55 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index f62ab8c48c..867c5c01d6 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -109,48 +109,6 @@ InternalPrintMessage (
   SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
 }
 
-/**
-  Find and display image base address and return image base and its entry 
point.
-
-  @param CurrentEip  Current instruction pointer.
-
-**/
-VOID
-DumpModuleImageInfo (
-  IN  UINTN  CurrentEip
-  )
-{
-  EFI_STATUS   Status;
-  UINTNPe32Data;
-  VOID *PdbPointer;
-  VOID *EntryPoint;
-
-  Pe32Data = PeCoffSearchImageBase (CurrentEip);
-  if (Pe32Data == 0) {
-InternalPrintMessage (" Can't find image information. \n");
-  } else {
-//
-// Find Image Base entry point
-//
-Status = PeCoffLoaderGetEntryPoint ((VOID *) Pe32Data, );
-if (EFI_ERROR (Status)) {
-  EntryPoint = NULL;
-}
-InternalPrintMessage (" Find image ");
-PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);
-if (PdbPointer != NULL) {
-  InternalPrintMessage ("%a", PdbPointer);
-} else {
-  InternalPrintMessage ("(No PDB) " );
-}
-InternalPrintMessage (
-  " (ImageBase=%016lp, EntryPoint=%016p) \n",
-  (VOID *) Pe32Data,
-  EntryPoint
-  );
-  }
-}
-
 /**
   Read and save reserved vector information
 
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 042207025e..478374d003 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -119,17 +119,6 @@ InternalPrintMessage (
   ...
   );
 
-/**
-  Find and display image base address and return image base and its entry 
point.
-
-  @param CurrentEip  Current instruction pointer.
-
-**/
-VOID
-DumpModuleImageInfo (
-  IN  UINTN  CurrentEip
-  );
-
 /**
   Display CPU information.
 
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
index f2c39eb193..db8013a5af 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -210,6 +210,296 @@ DumpCpuContext (
 );
 }
 
+/**
+  Dump stack trace.
+
+  @param[in]  SystemContext  Pointer to EFI_SYSTEM_CONTEXT.
+  @param[out] UnwoundStacksCount  Count of unwound stack frames.
+**/
+STATIC
+VOID
+DumpStackTrace (
+  IN  EFI_SYSTEM_CONTEXT   SystemContext,
+  OUT INTN *UnwoundStacksCount
+  )
+{
+  UINT32  Eip;
+  UINT32  Ebp;
+  UINTN   ImageBase;
+  CHAR8   *PdbFileName;
+
+  //
+  // Set current EIP address
+  //
+  Eip = SystemContext.SystemContextIa32->Eip;
+
+  //
+  // Set current frame pointer address
+  //
+  Ebp = SystemContext.SystemContextIa32->Ebp;
+
+  //
+  // Check for proper frame pointer alignment
+  //
+  if (((UINTN)Ebp & (CPU_STACK_ALIGNMENT - 1)) != 0) {
+InternalPrintMessage (" Unaligned frame pointer. \n");
+return;
+  }
+
+  //
+  // Get initial PE/COFF image base address from current EIP
+  //
+  ImageBase = PeCoffSearchImageBase (Eip);
+  if (ImageBase == 0) {
+InternalPrintMessage (" Could not find backtrace information. ");
+return;
+  }
+
+  //
+  // Get PDB file name from initial PE/COFF image
+  //
+  GetPdbFileName (ImageBase, NULL, );
+
+  //
+  // Initialize count of unwound stacks
+  //
+  *UnwoundStacksCount = 1;
+
+  //
+  // Print out back trace
+  //
+  InternalPrintMessage ("\nCall trace:\n");
+
+  for (;;) {
+//
+// Print stack frame in the following format:
+//
+// #  @ + (EBP) in [ | ]
+//
+InternalPrintMessage (
+  "%d 0x%08x @ 0x%08x+0x%x (0x%08x) in %a\n",
+  *UnwoundStacksCount - 1,
+ 

[edk2] [RFC v3 2/3] UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName()

2017-11-16 Thread Paulo Alcantara
This function will be used by both IA32 and X64 exception handling in
order to print out image module names during stack unwinding.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c   | 60 
+++-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h   | 14 +
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 59 
---
 3 files changed, 73 insertions(+), 60 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index dbfaae1d30..f62ab8c48c 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -54,6 +54,11 @@ CONST CHAR8 *mExceptionNameStr[] = {
 
 #define EXCEPTION_KNOWN_NAME_NUM  (sizeof (mExceptionNameStr) / sizeof (CHAR8 
*))
 
+//
+// Unknown PDB file name
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mUnknownPdbFileName = "";
+
 /**
   Get ASCII format string exception name by exception type.
 
@@ -177,4 +182,57 @@ ReadAndVerifyVectorInfo (
 VectorInfo ++;
   }
   return EFI_SUCCESS;
-}
\ No newline at end of file
+}
+
+/**
+  Get absolute path and file name of PDB file in PE/COFF image.
+
+  @param[in]  ImageBaseBase address of PE/COFF image.
+  @param[out] PdbAbsoluteFilePath  Absolute path of PDB file.
+  @param[out] PdbFileName  File name of PDB file.
+**/
+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;
+}
+  }
+}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 740a58828b..042207025e 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -288,5 +288,19 @@ CommonExceptionHandlerWorker (
   IN EXCEPTION_HANDLER_DATA  *ExceptionHandlerData
   );
 
+/**
+  Get absolute path and file name of PDB file in PE/COFF image.
+
+  @param[in]  ImageBaseBase address of PE/COFF image.
+  @param[out] PdbAbsoluteFilePath  Absolute path of PDB file.
+  @param[out] PdbFileName  File name of PDB file.
+**/
+VOID
+GetPdbFileName (
+  IN  UINTNImageBase,
+  OUT CHAR8**PdbAbsoluteFilePath,
+  OUT CHAR8**PdbFileName
+  );
+
 #endif
 
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index fe776ccc2d..7f8ec65e1d 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
@@ -14,11 +14,6 @@
 
 #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.
@@ -247,60 +242,6 @@ DumpCpuContext (
 );
 }
 
-/**
-  Get absolute path and file name of PDB file in PE/COFF image.
-
-  @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.

[edk2] [RFC v3 1/3] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

2017-11-16 Thread Paulo Alcantara
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 | 376 
+++-
 1 file changed, 374 insertions(+), 2 deletions(-)

diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index 65f0cff680..fe776ccc2d 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,357 @@ DumpCpuContext (
 );
 }
 
+/**
+  Get absolute path and file name of PDB file in PE/COFF image.
+
+  @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]  UnwoundStacksCount  Count of unwound stack frames.
+**/
+STATIC
+VOID
+DumpStackContents (
+  IN UINT64  CurrentRsp,
+  IN INTNUnwoundStacksCount
+  )
+{
+  //
+  // 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 (UnwoundStacksCount-- > 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;
+  UINTN   LastImageBase;
+
+  //
+  // 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;
+  }
+
+  //
+  // Set last PE/COFF image base address
+  //
+  LastImageBase = ImageBase;
+
+  //
+  // 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)
+  

Re: [edk2] [RFC v2 0/3] Stack trace support in X64 exception handling

2017-11-15 Thread Paulo Alcantara

Hi,

On 11/15/2017 11:18 PM, Paulo Alcantara wrote:

Hi,

This series adds stack trace support during a X64 CPU exception.

Informations like back trace, stack contents and image module names
(that were part of the call stack) will be dumped out.

We already have such support in ARM/AArch64 (IIRC) exception handling
(thanks to Ard), and then I thought we'd also deserve it in X64 and
IA-32 platforms.

What do you think guys?

BTW, I've tested this only with OVMF (X64 only), using:
   - gcc-6.3.0, GCC5, NOOPT

Any other tests  would be really appreciable.

Thanks!
Paulo

Repo:   https://github.com/pcacjr/edk2.git
Branch: stacktrace_v2

Cc: Rick Bramley <richard.bram...@hp.com>
Cc: Andrew Fish <af...@apple.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: "Brian J. Johnson" <brian.john...@hpe.com>
Cc: Jeff Fan <jeff@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---

v1 -> v2:
   * Add IA32 arch support (GCC toolchain only)
   * Replace hard-coded stack alignment value (16) with
 CPU_STACK_ALIGNMENT.
   * Check for proper stack and frame pointer alignments.
   * Fix initialization of UnwoundStacksCount to 1.
   * Move GetPdbFileName() to common code since it will be used by both
 IA32 and X64 implementations.


Sorry for the delay in sending v2. It's holiday here :-)

FWIW, I've attached two files which contain stack trace dumps of IA32 
and X64 exceptions.


The new IA32 arch support is still limited to GCC only (that is, relying 
on frame pointers), but I'll start investing in a new solution that 
would work on both MSVC and GCC toolchains -- probably this weekend. If 
I come up with something, I'll let you know.


On IA32, I performed the same test as in X64 to trigger an NMI interrupt 
manually with: asm ("int $0x2") in PartitionDxe driver and watched out 
the call stack. The difference between the two dumps, regardless the CPU 
context, etc. is that we don't see the calls from PeiCore.dll. Then I 
figured out that the EIP gets a value of 0 before jumping to 
PartitionDxe's entry point.


I guess that's related to the "push $0" that Andrew mentioned earlier so 
the debugger knows when to stop unwinding. Although I can't see a "push 
0" equivalent neither in SwitchStack.nasm nor in SwitchStack.asm for X64

-- so we're able to see the calls within PeiCore.dll.

Thanks!
Paulo
 X64 Exception Type - 02(NMI Interrupt)  CPU Apic ID -  
RIP  - 7EC30266, CS  - 0038, RFLAGS - 0202
RAX  - 7FE71018, RCX - 7F34F498, RDX - 7FE71018
RBX  - 00810248, RSP - 7FEE4C70, RBP - 7FEE4CB0
RSI  - 0007, RDI - 7F34E018
R8   - 7EC32DC8, R9  - 7F34E298, R10 - 0036
R11  - 00D7, R12 - , R13 - 
R14  - , R15 - 
DS   - 0030, ES  - 0030, FS  - 0030
GS   - 0030, SS  - 0030
CR0  - 80010033, CR2 - , CR3 - 7FE83000
CR4  - 0668, CR8 - 
DR0  - , DR1 - , DR2 - 
DR3  - , DR6 - 0FF0, DR7 - 0400
GDTR - 7FE71A98 0047, LDTR - 
IDTR - 7F7AB018 0FFF,   TR - 
FXSAVE_STATE - 7FEE48D0

Call trace:
0 0x7EC30266 @ 0x7EC28000+0x8265 (0x7FEE4CB0) in 
PartitionDxe.dll
1 0x7EC3063D @ 0x7EC28000+0x863C (0x7FEE4CE0) in 
PartitionDxe.dll
2 0x7EC2B116 @ 0x7EC28000+0x3115 (0x7FEE4D20) in 
PartitionDxe.dll
3 0x7FEF8A15 @ 0x7EC28000+0x12D0A14 (0x7FEE4DB0) in 
PartitionDxe.dll
4 0x7FF10F0A @ 0x7EC28000+0x12E8F09 (0x7FEE4E30) in 
PartitionDxe.dll
5 0x7FF13445 @ 0x7EC28000+0x12EB444 (0x7FEE4F60) in 
PartitionDxe.dll
6 0x7FF13BC9 @ 0x7EC28000+0x12EBBC8 (0x7FEE4F90) in 
PartitionDxe.dll
7 0x7FEE9DDE @ 0x7EC28000+0x12C1DDD (0x7FEE4FC0) in 
PartitionDxe.dll
8 0x7FF5B75F @ 0x7EC28000+0x133375E (0x7BFDC840) in 
PartitionDxe.dll
9 0x7FF61551 @ 0x7EC28000+0x1339550 (0x7BFDC8C0) in 
PartitionDxe.dll
10 0x7FF6031D @ 0x7EC28000+0x133831C (0x7BFDCA30) in 
PartitionDxe.dll
11 0x7FF6CDCB @ 0x7EC28000+0x1344DCA (0x7BFDCF80) in 
PartitionDxe.dll
12 0x008286F4 @ 0x00820140+0x85B3 (0x7BFDD4D0) in 
PeiCore.dll
13 0x00830940 @ 0x00820140+0x107FF (0x00817600) in 
PeiCore.dll
14 0x00831585 @ 0x00820140+0x11444 (0x008176D0) in 
PeiCore.dll
15 0

[edk2] [RFC v2 0/3] Stack trace support in X64 exception handling

2017-11-15 Thread Paulo Alcantara
Hi,

This series adds stack trace support during a X64 CPU exception.

Informations like back trace, stack contents and image module names
(that were part of the call stack) will be dumped out.

We already have such support in ARM/AArch64 (IIRC) exception handling
(thanks to Ard), and then I thought we'd also deserve it in X64 and
IA-32 platforms.

What do you think guys?

BTW, I've tested this only with OVMF (X64 only), using:
  - gcc-6.3.0, GCC5, NOOPT

Any other tests  would be really appreciable.

Thanks!
Paulo

Repo:   https://github.com/pcacjr/edk2.git
Branch: stacktrace_v2

Cc: Rick Bramley <richard.bram...@hp.com>
Cc: Andrew Fish <af...@apple.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: "Brian J. Johnson" <brian.john...@hpe.com>
Cc: Jeff Fan <jeff@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---

v1 -> v2:
  * Add IA32 arch support (GCC toolchain only)
  * Replace hard-coded stack alignment value (16) with
CPU_STACK_ALIGNMENT.
  * Check for proper stack and frame pointer alignments.
  * Fix initialization of UnwoundStacksCount to 1.
  * Move GetPdbFileName() to common code since it will be used by both
IA32 and X64 implementations.

Paulo Alcantara (3):
  UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support
  UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName()
  UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support

 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c| 102 
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h|  25 +-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 303 
++-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c  | 310 
+++-
 4 files changed, 682 insertions(+), 58 deletions(-)

-- 
2.14.3

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


[edk2] [RFC v2 3/3] UefiCpuPkg/CpuExceptionHandlerLib/Ia32: Add stack trace support

2017-11-15 Thread Paulo Alcantara
This patch adds stack trace support during a IA32 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/CpuExceptionCommon.c|  42 ---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h|  11 -
 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 303 
+++-
 3 files changed, 301 insertions(+), 55 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index f62ab8c48c..867c5c01d6 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -109,48 +109,6 @@ InternalPrintMessage (
   SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
 }
 
-/**
-  Find and display image base address and return image base and its entry 
point.
-
-  @param CurrentEip  Current instruction pointer.
-
-**/
-VOID
-DumpModuleImageInfo (
-  IN  UINTN  CurrentEip
-  )
-{
-  EFI_STATUS   Status;
-  UINTNPe32Data;
-  VOID *PdbPointer;
-  VOID *EntryPoint;
-
-  Pe32Data = PeCoffSearchImageBase (CurrentEip);
-  if (Pe32Data == 0) {
-InternalPrintMessage (" Can't find image information. \n");
-  } else {
-//
-// Find Image Base entry point
-//
-Status = PeCoffLoaderGetEntryPoint ((VOID *) Pe32Data, );
-if (EFI_ERROR (Status)) {
-  EntryPoint = NULL;
-}
-InternalPrintMessage (" Find image ");
-PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);
-if (PdbPointer != NULL) {
-  InternalPrintMessage ("%a", PdbPointer);
-} else {
-  InternalPrintMessage ("(No PDB) " );
-}
-InternalPrintMessage (
-  " (ImageBase=%016lp, EntryPoint=%016p) \n",
-  (VOID *) Pe32Data,
-  EntryPoint
-  );
-  }
-}
-
 /**
   Read and save reserved vector information
 
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 042207025e..478374d003 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -119,17 +119,6 @@ InternalPrintMessage (
   ...
   );
 
-/**
-  Find and display image base address and return image base and its entry 
point.
-
-  @param CurrentEip  Current instruction pointer.
-
-**/
-VOID
-DumpModuleImageInfo (
-  IN  UINTN  CurrentEip
-  );
-
 /**
   Display CPU information.
 
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
index f2c39eb193..169a0b660e 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
@@ -210,6 +210,289 @@ DumpCpuContext (
 );
 }
 
+/**
+  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
+  )
+{
+  UINT32  Eip;
+  UINT32  Ebp;
+  UINTN   ImageBase;
+  CHAR8   *PdbFileName;
+
+  //
+  // Set current EIP address
+  //
+  Eip = SystemContext.SystemContextIa32->Eip;
+
+  //
+  // Set current frame pointer address
+  //
+  Ebp = SystemContext.SystemContextIa32->Ebp;
+
+  //
+  // Check for proper frame pointer alignment
+  //
+  if (((UINTN)Ebp & (CPU_STACK_ALIGNMENT - 1)) != 0) {
+InternalPrintMessage (" Unaligned frame pointer. \n");
+return;
+  }
+
+  //
+  // Get initial PE/COFF image base address from current EIP
+  //
+  ImageBase = PeCoffSearchImageBase (Eip);
+  if (ImageBase == 0) {
+InternalPrintMessage (" Could not find backtrace information. ");
+return;
+  }
+
+  //
+  // Get PDB file name from initial PE/COFF image
+  //
+  GetPdbFileName (ImageBase, NULL, );
+
+  //
+  // Initialize count of unwond stacks
+  //
+  *UnwondStacksCount = 1;
+
+  //
+  // Print out back trace
+  //
+  InternalPrintMessage ("\nCall trace:\n");
+
+  for (;;) {
+//
+// Print stack frame in the following format:
+//
+// #  @ + (EBP) in [ | ]
+//
+InternalPrintMessage (
+  "%d 0x%08x @ 0x%08x+0x%x (0x%08x) in %a\n",
+  *UnwondStacksCount - 1,
+ 

[edk2] [RFC v2 1/3] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

2017-11-15 Thread Paulo Alcantara
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 | 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]  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
+  )
+{
+  //
+  // 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, );
+  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

[edk2] [RFC v2 2/3] UefiCpuPkg/CpuExceptionHandlerLib: Export GetPdbFileName()

2017-11-15 Thread Paulo Alcantara
This function will be used by both IA32 and X64 exception handling in
order to print out image module names during stack unwinding.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c   | 60 
+++-
 UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h   | 14 +
 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 59 
---
 3 files changed, 73 insertions(+), 60 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index dbfaae1d30..f62ab8c48c 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -54,6 +54,11 @@ CONST CHAR8 *mExceptionNameStr[] = {
 
 #define EXCEPTION_KNOWN_NAME_NUM  (sizeof (mExceptionNameStr) / sizeof (CHAR8 
*))
 
+//
+// Unknown PDB file name
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mUnknownPdbFileName = "";
+
 /**
   Get ASCII format string exception name by exception type.
 
@@ -177,4 +182,57 @@ ReadAndVerifyVectorInfo (
 VectorInfo ++;
   }
   return EFI_SUCCESS;
-}
\ No newline at end of file
+}
+
+/**
+  Get absolute path and file name of PDB file in PE/COFF image.
+
+  @param[in]  ImageBaseBase address of PE/COFF image.
+  @param[out] PdbAbsoluteFilePath  Absolute path of PDB file.
+  @param[out] PdbFileName  File name of PDB file.
+**/
+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;
+}
+  }
+}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 740a58828b..042207025e 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -288,5 +288,19 @@ CommonExceptionHandlerWorker (
   IN EXCEPTION_HANDLER_DATA  *ExceptionHandlerData
   );
 
+/**
+  Get absolute path and file name of PDB file in PE/COFF image.
+
+  @param[in]  ImageBaseBase address of PE/COFF image.
+  @param[out] PdbAbsoluteFilePath  Absolute path of PDB file.
+  @param[out] PdbFileName  File name of PDB file.
+**/
+VOID
+GetPdbFileName (
+  IN  UINTNImageBase,
+  OUT CHAR8**PdbAbsoluteFilePath,
+  OUT CHAR8**PdbFileName
+  );
+
 #endif
 
diff --git 
a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c 
b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index 11cd7c9e1c..ace835c02c 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
@@ -14,11 +14,6 @@
 
 #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.
@@ -247,60 +242,6 @@ DumpCpuContext (
 );
 }
 
-/**
-  Get absolute path and file name of PDB file in PE/COFF image.
-
-  @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.

Re: [edk2] 答复: 答复: [RFC 0/1] Stack trace support in X64 exception handling

2017-11-15 Thread Paulo Alcantara

Hi Fan,

On 15/11/2017 11:21, Fan Jeff wrote:

Paulo,

I will try to validate my code firstly and try to integrate into your 
patch.


OK. Thank you very much for the effort!



Before my part ready, it’s also welcome if you or others provide yours 
own solution on X64 MSFT toolchain.
Yes - that would be great. If I get this working on IA32 with GCC 
toolchain shortly, then I'll try to come up with a solution for MSVC.


In my mind, IA32 arch should use the same solution with yours, have you 
tested your solution on IA32 arch with GCC toolchain?


In theory, yes. :-) I haven't tested it yet, but I'll starting working 
it on now.


BTW, do you think it's appropriate to just let you know that I pushed 
out another commit with IA32 support, or do you think it's better to 
send a v2 with it?


Besides we shouldn't forget the suggestions from Andrew and Brian to 
validate the RIP and RSP values, as well as to have a kind of PCD to 
limit the number of stack frames printed out -- which I think that are 
really important even if unlikely.


Thanks!
Paulo



Thanks!

Jeff


*From:* Paulo Alcantara <pca...@zytor.com>
*Sent:* Tuesday, November 14, 2017 11:37:35 PM
*To:* Fan Jeff; edk2-devel@lists.01.org
*Cc:* Rick Bramley; Laszlo Ersek; Andrew Fish; Eric Dong
*Subject:* Re: 答复: [edk2] [RFC 0/1] Stack trace support in X64 
exception handling

Hi Fan,

On 14/11/2017 12:03, Fan Jeff wrote:

Paul,

I like this feature very much. Actually, I did some POC one year ago but 
I did finalize it.


In my POC, I could use EBP to tack the stack frame on IAS32 arch.

But for x64, I tried to use –keepexceptiontable flag to explain stack 
frame from the debug section of image.


I may workson MSFT toolchain, but it did now work well for GCC toolchain.

I think Eric could help to verify MSFT for your patch. If it works well, 
that’s will be great!


Say again, I like this feature!!!:-)


Cool! Your help would be really appreciable! If we get this working for
X64 in both toolchains, that should be easy to port it to IA-32 as well.

Thank you very much for willing to help on that.

Paulo



Thanks!

Jeff

*发件人: *Paulo Alcantara <mailto:pca...@zytor.com>
*发送时间: *2017年11月14日21:23
*收件人: *edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org>
*抄送: *Rick Bramley <mailto:richard.bram...@hp.com>; Laszlo Ersek
<mailto:ler...@redhat.com>; Andrew Fish <mailto:af...@apple.com>; Eric
Dong <mailto:eric.d...@intel.com>
*主题: *Re: [edk2] [RFC 0/1] Stack trace support in X64 exception handling

Hi,

On 14/11/2017 10:47, Paulo Alcantara wrote:

Hi,

This series adds stack trace support during a X64 CPU exception.

Informations like back trace, stack contents and image module names
(that were part of the call stack) will be dumped out.

We already have such support in ARM/AArch64 (IIRC) exception handling
(thanks to Ard), and then I thought we'd also deserve it in X64 and
IA-32 platforms.

What do you think guys?

BTW, I've tested this only with OVMF (X64 only), using:
    - gcc-6.3.0, GCC5, NOOPT

Any other tests  would be really appreciable.


I've attached a file to show you how the trace would look like.

Thanks!
Paulo



Thanks!
Paulo

Repo:   https://github.com/pcacjr/edk2.git
Branch: stacktrace_x64

Cc: Rick Bramley <richard.bram...@hp.com>
Cc: Andrew Fish <af...@apple.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---

Paulo Alcantara (1):
    UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

   UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 344 
+++-
   1 file changed, 342 insertions(+), 2 deletions(-)




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


Re: [edk2] [RFC 0/1] Stack trace support in X64 exception handling

2017-11-14 Thread Paulo Alcantara

Hi,

On 14/11/2017 15:41, Brian J. Johnson wrote:

On 11/14/2017 11:23 AM, Andrew Fish wrote:


On Nov 14, 2017, at 8:33 AM, Brian J. Johnson <brian.john...@hpe.com 
<mailto:brian.john...@hpe.com>> wrote:


On 11/14/2017 09:37 AM, Paulo Alcantara wrote:

Hi Fan,
On 14/11/2017 12:03, Fan Jeff wrote:

Paul,

I like this feature very much. Actually, I did some POC one year 
ago but I did finalize it.


In my POC, I could use EBP to tack the stack frame on IAS32 arch.

But for x64, I tried to use –keepexceptiontable flag to explain 
stack frame from the debug section of image.


I may workson MSFT toolchain, but it did now work well for GCC 
toolchain.


I think Eric could help to verify MSFT for your patch. If it works 
well, that’s will be great!


Say again, I like this feature!!!:-)
Cool! Your help would be really appreciable! If we get this working 
for X64 in both toolchains, that should be easy to port it to IA-3 2 
as well.

Thank you very much for willing to help on that.
Paulo


Great feature!  You do need some sort of sanity check on the RIP and 
RBP values, though, so if the stack gets corrupted or the RIP is 
nonsense from following a bad pointer, you don't start dereferencing 
garbage addresses and trigger an exception loop.




Brian,

This was a long time ago and my memory might be fuzzy I think we 
talked to some debugger folks about unwinding the stack and they 
mentioned it was common for the C runtime to have a return address or 
frame pointer have a zero value so the unwind logic knows when to 
stop. This is in addition to generic sanity checking.


We got an extra push $0 added to the stack switch to help with stack 
unwind.
https://github.com/tianocore/edk2/blob/master/MdePkg/Library/BaseLib/X64/SwitchStack.S 



If might be a good idea to have a PCD for the max number of stack 
frames to display as a fallback for the error check. For X64 you may 
also have to add a check for a non-cononical address as that will GP 
fault.




Good idea.

Regarding sanity checks:  I've had good luck validating code locations 
(EIP values) by using a modified PeCoffExtraActionLib to track the top 
and bottom of the range where images have been loaded.  (I've actually 
used two ranges:  one for code executed from firmware space, and one for 
code executed from RAM.)


I'm not sure offhand if there's a platform-independent way to validate 
stack pointer values.  For most PC-like systems, just ensuring that it's 
larger than 1 or 2M (to avoid NULL pointers and the legacy spaces) and 
less than about 3G (or the low memory size, if that's known) may be 
enough to avoid an exception loop.


Yeah, I agree with you guys. We certainly should be validating the RIP 
and RSP values and then avoiding the exception loop.


For the RIP value, I think we should validate it in 
PeCoffSearchImageBase(), so if it's outside PE/COFF image's address 
space, then we should return an address of zero and no trace would be 
printed out.


Since we already have a "SizeOfImage" field in PE/COFF Optional Header 
and it's available in the process' image, we might end up with checking 
whether RIP is between ImageBase through ImageBase + SizeOfImage - 1.


For the RSP value, I have no idea :-)

Thanks!
Paulo



Brian


Thanks,

Andrew Fish


For at least some versions of Microsoft's IA32 compiler, it's 
possible to compile using EBP as a stack frame base pointer (like 
gcc) by using the "/Oy-" switch.  The proposed unwind code should 
work in that case. The X64 compiler doesn't support this switch, though.


AFAIK the only way to unwind the stack with Microsoft's X64 compilers 
is to parse the unwind info in the .pdata and .xdata sections. 
 Genfw.exe usually strips those sections, but the 
"--keepexceptiontable" flag will preserve them, as Jeff pointed out. 
 I've looked hard for open source code to decode them, but haven't 
found any, even though the format is well documented.  And I haven't 
gotten around to writing it myself.  I'd love it if someone could 
contribute the code!


Another possibility is to use the branch history MSRs available on 
some x86-family processors.  Recent Intel processors can use them as 
a stack, as opposed to a circular list, so they can record a 
backtrace directly. (I'm not familiar with AMD processors' 
capabilities.)  You can enable call stack recording like this:


 #define LBR_ON_FLAG   0x0001
 #define IA32_DEBUGCTL 0x1D9
 #define CALL_STACK_SET_FLAG 0x3C4
 #define CALL_STACK_CLR_FLAG 0xFC7
 #define MSR_LBR_SELECT 0x1C8

 //
 // Enable branch recording
 //
 LbControl = AsmReadMsr64 ((UINT32)IA32_DEBUGCTL);
 LbControl |= LBR_ON_FLAG;
 AsmWriteMsr64 ((UINT32)IA32_DEBUGCTL, LbControl);

 //
 // Configure for call stack
 //
 LbSelect = AsmReadMsr64 ((UINT32)MSR_LBR_SELECT);
 LbSelect &= CALL_STACK_CLR_FLAG;
 LbSelect |= CALL_STACK_SET_FLAG;
 AsmWriteMsr64((UINT32)MSR_LBR_SELECT, LbSelect);

The EIP/RIP values are lo

Re: [edk2] [PATCH 0/2] Refine UDF related codes

2017-11-14 Thread Paulo Alcantara

Hi Hao,

On 14/11/2017 05:51, Hao Wu wrote:

The series will do the following refinements:
a. Merge the discovery of the El Torito feature on CD/DVD media into the
detect of UDF;
b. Avoid possible loss track of the allocated buffer pointer in UdfDxe.

Cc: Paulo Alcantara <pca...@zytor.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Eric Dong <eric.d...@intel.com>

Hao Wu (2):
   MdeModulePkg/PartitionDxe: Merge the discovery of ElTorito into UDF
   MdeModulePkg/UdfDxe: Avoid possible loss track of allocated buffer

  MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c  |  7 +++
  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c| 17 
+
  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 12 +++-
  3 files changed, 27 insertions(+), 9 deletions(-)



Looks good to me. Thanks for fixing and testing it!

Reviewed-by: Paulo Alcantara <pca...@zytor.com>

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


Re: [edk2] 答复: [RFC 0/1] Stack trace support in X64 exception handling

2017-11-14 Thread Paulo Alcantara

Hi Fan,

On 14/11/2017 12:03, Fan Jeff wrote:

Paul,

I like this feature very much. Actually, I did some POC one year ago but 
I did finalize it.


In my POC, I could use EBP to tack the stack frame on IAS32 arch.

But for x64, I tried to use –keepexceptiontable flag to explain stack 
frame from the debug section of image.


I may workson MSFT toolchain, but it did now work well for GCC toolchain.

I think Eric could help to verify MSFT for your patch. If it works well, 
that’s will be great!


Say again, I like this feature!!!:-)


Cool! Your help would be really appreciable! If we get this working for 
X64 in both toolchains, that should be easy to port it to IA-32 as well.


Thank you very much for willing to help on that.

Paulo



Thanks!

Jeff

*发件人: *Paulo Alcantara <mailto:pca...@zytor.com>
*发送时间: *2017年11月14日21:23
*收件人: *edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org>
*抄送: *Rick Bramley <mailto:richard.bram...@hp.com>; Laszlo Ersek 
<mailto:ler...@redhat.com>; Andrew Fish <mailto:af...@apple.com>; Eric 
Dong <mailto:eric.d...@intel.com>

*主题: *Re: [edk2] [RFC 0/1] Stack trace support in X64 exception handling

Hi,

On 14/11/2017 10:47, Paulo Alcantara wrote:

Hi,

This series adds stack trace support during a X64 CPU exception.

Informations like back trace, stack contents and image module names
(that were part of the call stack) will be dumped out.

We already have such support in ARM/AArch64 (IIRC) exception handling
(thanks to Ard), and then I thought we'd also deserve it in X64 and
IA-32 platforms.

What do you think guys?

BTW, I've tested this only with OVMF (X64 only), using:
    - gcc-6.3.0, GCC5, NOOPT

Any other tests  would be really appreciable.


I've attached a file to show you how the trace would look like.

Thanks!
Paulo



Thanks!
Paulo

Repo:   https://github.com/pcacjr/edk2.git
Branch: stacktrace_x64

Cc: Rick Bramley <richard.bram...@hp.com>
Cc: Andrew Fish <af...@apple.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---

Paulo Alcantara (1):
    UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

   UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 344 
+++-
   1 file changed, 342 insertions(+), 2 deletions(-)




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


Re: [edk2] [RFC 1/1] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

2017-11-14 Thread Paulo Alcantara

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 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.
+
+  @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:

Re: [edk2] [RFC 0/1] Stack trace support in X64 exception handling

2017-11-14 Thread Paulo Alcantara

Hi,

On 14/11/2017 10:47, Paulo Alcantara wrote:

Hi,

This series adds stack trace support during a X64 CPU exception.

Informations like back trace, stack contents and image module names
(that were part of the call stack) will be dumped out.

We already have such support in ARM/AArch64 (IIRC) exception handling
(thanks to Ard), and then I thought we'd also deserve it in X64 and
IA-32 platforms.

What do you think guys?

BTW, I've tested this only with OVMF (X64 only), using:
   - gcc-6.3.0, GCC5, NOOPT

Any other tests  would be really appreciable.


I've attached a file to show you how the trace would look like.

Thanks!
Paulo



Thanks!
Paulo

Repo:   https://github.com/pcacjr/edk2.git
Branch: stacktrace_x64

Cc: Rick Bramley <richard.bram...@hp.com>
Cc: Andrew Fish <af...@apple.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---

Paulo Alcantara (1):
   UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

  UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 344 
+++-
  1 file changed, 342 insertions(+), 2 deletions(-)



 X64 Exception Type - 0E(#PF - Page-Fault)  CPU Apic ID -  
ExceptionData - 0002  I:0 R:0 U:0 W:1 P:0 PK:0 S:0
RIP  - 7E510F7F, CS  - 0038, RFLAGS - 00010202
RAX  - , RCX - 7EA01318, RDX - 7F6EE018
RBX  - 00810248, RSP - 7F762C70, RBP - 7F762CB0
RSI  - 0007, RDI - 7EA01418
R8   - 7E513A88, R9  - 7EA01798, R10 - 0036
R11  - 00D7, R12 - , R13 - 
R14  - , R15 - 
DS   - 0030, ES  - 0030, FS  - 0030
GS   - 0030, SS  - 0030
CR0  - 80010033, CR2 - , CR3 - 7F701000
CR4  - 0668, CR8 - 
DR0  - , DR1 - , DR2 - 
DR3  - , DR6 - 0FF0, DR7 - 0400
GDTR - 7F6EEA98 0047, LDTR - 
IDTR - 7EEF2018 0FFF,   TR - 
FXSAVE_STATE - 7F7628D0

Back trace:
0 0x7E510F7F @ 0x7E509000+0x7F7E (0x7F762CB0) in 
PartitionDxe.dll
1 0x7E51135D @ 0x7E509000+0x835C (0x7F762CE0) in 
PartitionDxe.dll
2 0x7E50C116 @ 0x7E509000+0x3115 (0x7F762D20) in 
PartitionDxe.dll
3 0x7F776972 @ 0x7E509000+0x126D971 (0x7F762DB0) in 
PartitionDxe.dll
4 0x7F78EE08 @ 0x7E509000+0x1285E07 (0x7F762E30) in 
PartitionDxe.dll
5 0x7F791343 @ 0x7E509000+0x1288342 (0x7F762F60) in 
PartitionDxe.dll
6 0x7F791AC7 @ 0x7E509000+0x1288AC6 (0x7F762F90) in 
PartitionDxe.dll
7 0x7F767DDB @ 0x7E509000+0x125EDDA (0x7F762FC0) in 
PartitionDxe.dll
8 0x7F7DF75F @ 0x7E509000+0x12D675E (0x7B7DC840) in 
PartitionDxe.dll
9 0x7F7E5546 @ 0x7E509000+0x12DC545 (0x7B7DC8C0) in 
PartitionDxe.dll
10 0x7F7E4312 @ 0x7E509000+0x12DB311 (0x7B7DCA30) in 
PartitionDxe.dll
11 0x7F7F0DB9 @ 0x7E509000+0x12E7DB8 (0x7B7DCF80) in 
PartitionDxe.dll
12 0x008286E9 @ 0x00820140+0x85A8 (0x7B7DD4D0) in 
PeiCore.dll
13 0x0083092F @ 0x00820140+0x107EE (0x00817600) in 
PeiCore.dll
14 0x00831574 @ 0x00820140+0x11433 (0x008176D0) in 
PeiCore.dll
15 0x00828D9B @ 0x00820140+0x8C5A (0x00817C20) in 
PeiCore.dll
16 0x0083238A @ 0x00820140+0x12249 (0x00817C50) in 
PeiCore.dll
17 0x00824312 @ 0x00820140+0x41D1 (0x00817C80) in 
PeiCore.dll
18 0xFFFD4291 @ 0x00820140+0xFF7B4150 (0x00817CE0) in 
PeiCore.dll
19 0xFFFCF578 @ 0x00820140+0xFF7AF437 (0x00817D10) in 
PeiCore.dll
20 0xFFFD422C @ 0x00820140+0xFF7B40EB (0x00817FD0) in 
PeiCore.dll
21 0xFFFD4489 @ 0x00820140+0xFF7B4348 (0xFFFCC000) in 
PeiCore.dll

PartitionDxe.dll (ImageBase=0x7E509000, EntryPoint=0x7E50C01F):
/home/pcacjr/src/edk2.git/Build/OvmfX64/NOOPT_GCC5/X64/MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe/DEBUG/PartitionDxe.dll
PeiCore.dll (ImageBase=0x00820140, EntryPoint=0x008242EC):
/home/pcacjr/src/edk2.git/Build/OvmfX64/NOOPT_GCC5/X64/MdeModulePkg/Core/Pei/PeiMain/DEBUG/PeiCore.dll

Stack dump:
0x7F762C70: 7E5137E0 
0x7F762C80: 7E513A88 0100
0x7F762C90: 7F762CB0 
0x

[edk2] [RFC 0/1] Stack trace support in X64 exception handling

2017-11-14 Thread Paulo Alcantara
Hi,

This series adds stack trace support during a X64 CPU exception.

Informations like back trace, stack contents and image module names
(that were part of the call stack) will be dumped out.

We already have such support in ARM/AArch64 (IIRC) exception handling
(thanks to Ard), and then I thought we'd also deserve it in X64 and
IA-32 platforms.

What do you think guys?

BTW, I've tested this only with OVMF (X64 only), using:
  - gcc-6.3.0, GCC5, NOOPT

Any other tests  would be really appreciable.

Thanks!
Paulo

Repo:   https://github.com/pcacjr/edk2.git
Branch: stacktrace_x64

Cc: Rick Bramley <richard.bram...@hp.com>
Cc: Andrew Fish <af...@apple.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---

Paulo Alcantara (1):
  UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 344 
+++-
 1 file changed, 342 insertions(+), 2 deletions(-)

-- 
2.11.0

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


[edk2] [RFC 1/1] UefiCpuPkg/CpuExceptionHandlerLib/X64: Add stack trace support

2017-11-14 Thread Paulo Alcantara
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.
+
+  @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);
+
+

[edk2] [PATCH] ShellPkg: Fix type mismatch with GCC

2017-10-27 Thread Paulo Alcantara
This patch fixes the following warning reported by GCC 6.3:

/home/pcacjr/src/edk2.git/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c:271:1:
warning: type of ‘InternalCharToUpper’ does not match original decl
aration [-Wlto-type-mismatch]
 InternalCharToUpper (
 ^
/home/pcacjr/src/edk2.git/MdePkg/Library/BaseLib/String.c:555:1: note:
‘InternalCharToUpper’ was previously declared here
 InternalCharToUpper (
 ^

Cc: Jaben Carsey <jaben.car...@intel.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pa...@hp.com>
---
 ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c | 1 +
 1 file changed, 1 insertion(+)

diff --git 
a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c 
b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c
index 7948e53cfc..bab6631e15 100644
--- a/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c
+++ b/ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.c
@@ -268,6 +268,7 @@ VerifyIntermediateDirectories (
   @return Char as an upper case character.
 **/
 CHAR16
+EFIAPI
 InternalCharToUpper (
   IN CONST CHAR16Char
   );
-- 
2.11.0

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


Re: [edk2] [PATCH] MdeModulePkg/PartitionDxe: Fix UDF fs access on certain CD/DVD medias

2017-10-13 Thread Paulo Alcantara

Hi Laszlo,

On 13/10/2017 10:37, Laszlo Ersek wrote:

Hi Paulo,

On 10/13/17 15:24, Paulo Alcantara wrote:

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=725


Thank you for the patch. Some meta comments:

When you post a patch for a TianoCore BZ, can you please

(1) flip the TianoCore BZ in question to status IN_PROGRESS,

(2) add a comment to the BZ, with a link to the patch in the mailing
list archive <https://lists.01.org/pipermail/edk2-devel/> -- in this
case, the link would be:

https://lists.01.org/pipermail/edk2-devel/2017-October/016031.html

(3) optionally, assign the BZ to yourself?


In particular step (2) is very helpful when a BZ takes several
iterations of a patch set, and later someone would like to review the
evolution of the patches.

(It's not necessary to comment at length in the BZ about the patch set
versions -- that's what the patch set cover letters are for --,
capturing the archive links is enough and helpful.)

Finally, when the patch is applied and the BZ is fixed, it's best to:

(4) kick the BZ to RESOLVED|FIXED, and

(5) add a comment about the git commit hash of the patch.


Sure. I'll make sure to follow those steps carefully next time. Thanks!

I've just did (1), (2) and (3).

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


[edk2] [PATCH] MdeModulePkg/PartitionDxe: Fix UDF fs access on certain CD/DVD medias

2017-10-13 Thread Paulo Alcantara
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=725

Historically many drives or medias do not correctly return their value
for block N - which is also referred as last addressable/recorded block.
When they do so, there is still a problem when relying on last recorded
block number returned by SCSI commands READ CAPACITY and READ TRACK
INFORMATION - that is, between block 0 and block N there may be
unwritten blocks which are located outside any track.

That said, the Partition driver was unable to find AVDP at block N on
certain medias that do not either return or report their last recorded
block number correctly.

Apparently there is no official or correct way to find the correct block
number, however tools like the Philips UDF Conformance Tool (udf_test)
apply a correction by searching for an AVDP or VAT in blocks N through
N-456 -- this can be observed by looking at the log reported by udf_test
on those CD/DVD medias. So, if the AVDP or VAT is found, then it sets
the last recorded block number to where AVDP or VAT was located.

With the below setence in UDF 2.60, 6.13.2.2 Background Physical
Formatting:

"... the second AVDP must be recorded after the Background physical
Formatting has been finished..."

Implies that the last recorded block is the one where second AVDP was
recorded.

This patch implements a similar way to correct the last recorded block
number by searching for last AVDP in blocks N-1 through N-512 on those
certain medias, as well as ensure a minimum number of 2 AVDPs found as
specified by ECMA 167 and UDF 2.60 specifications.

Cc: Hao Wu <hao.a...@intel.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Eric Dong <eric.d...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Reported-by: Hao Wu <hao.a...@intel.com>
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
 MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c | 254 
 1 file changed, 201 insertions(+), 53 deletions(-)

diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c 
b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
index 8aee30c759..7eee748958 100644
--- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
+++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
@@ -14,6 +14,8 @@
 
 #include "Partition.h"
 
+#define MAX_CORRECTION_BLOCKS_NUM 512u
+
 //
 // C5BD4D42-1A76-4996-8956-73CDA326CD0A
 //
@@ -48,61 +50,199 @@ UDF_DEVICE_PATH gUdfDevicePath = {
 /**
   Find the anchor volume descriptor pointer.
 
-  @param[in]  BlockIo BlockIo interface.
-  @param[in]  DiskIo  DiskIo interface.
-  @param[out] AnchorPoint Anchor volume descriptor pointer.
+  @param[in]  BlockIo   BlockIo interface.
+  @param[in]  DiskIoDiskIo interface.
+  @param[out] AnchorPoint   Anchor volume descriptor pointer.
+  @param[out] LastRecordedBlock Last recorded block.
 
-  @retval EFI_SUCCESS Anchor volume descriptor pointer found.
-  @retval EFI_VOLUME_CORRUPTEDThe file system structures are corrupted.
-  @retval other   Anchor volume descriptor pointer not found.
+  @retval EFI_SUCCESS   Anchor volume descriptor pointer found.
+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
+  @retval other Anchor volume descriptor pointer not found.
 
 **/
 EFI_STATUS
 FindAnchorVolumeDescriptorPointer (
   IN   EFI_BLOCK_IO_PROTOCOL *BlockIo,
   IN   EFI_DISK_IO_PROTOCOL  *DiskIo,
-  OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
+  OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
+  OUT  EFI_LBA   *LastRecordedBlock
   )
 {
-  EFI_STATUS  Status;
-  UINT32  BlockSize;
-  EFI_LBA EndLBA;
-  EFI_LBA DescriptorLBAs[4];
-  UINTN   Index;
-  UDF_DESCRIPTOR_TAG  *DescriptorTag;
+  EFI_STATUSStatus;
+  UINT32BlockSize;
+  EFI_LBA   EndLBA;
+  UDF_DESCRIPTOR_TAG*DescriptorTag;
+  UINTN AvdpsCount;
+  UINTN Size;
+  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoints;
+  INTN  Index;
+  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPointPtr;
+  EFI_LBA   LastAvdpBlockNum;
 
+  //
+  // UDF 2.60, 2.2.3 Anchor Volume Descriptor Pointer
+  //
+  // An Anchor Volume Descriptor Pointer structure shall be recorded in at
+  // least 2 of the following 3 locations on the media: Logical Sector 256,
+  // N - 256 or N, where N is the last *addressable* sector of a volume.
+  //
+  // To figure out what logical sector N is, the SCSI commands READ CAPACITY 
and
+  // READ TRACK INFORMATION are used, however many drives or medias report 
t

Re: [edk2] [PATCH] MdeModulePkg/UdfDxe: Resolve potential NULL pointer dereference

2017-09-25 Thread Paulo Alcantara


On September 25, 2017 10:36:48 PM GMT-03:00, Hao Wu <hao.a...@intel.com> wrote:
>Within function GetAllocationDescriptorLsn():
>
>The call to GetPdFromLongAd() may return NULL and it will be later
>dereferenced in GetShortAdLsn().
>
>This commit adds ASSERT to resolve the potential NULL pointer
>dereference.
>
>Cc: Paulo Alcantara <pca...@zytor.com>
>Cc: Ruiyu Ni <ruiyu...@intel.com>
>Cc: Star Zeng <star.z...@intel.com>
>Cc: Eric Dong <eric.d...@intel.com>
>Contributed-under: TianoCore Contribution Agreement 1.1
>Signed-off-by: Hao Wu <hao.a...@intel.com>
>---
> MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 7 ++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
>diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>index b336ffc553..e048d95d31 100644
>--- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>+++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>@@ -748,12 +748,17 @@ GetAllocationDescriptorLsn (
>   IN VOID*Ad
>   )
> {
>+  UDF_PARTITION_DESCRIPTOR *PartitionDesc;
>+
>   if (RecordingFlags == LongAdsSequence) {
>return GetLongAdLsn (Volume, (UDF_LONG_ALLOCATION_DESCRIPTOR *)Ad);
>   } else if (RecordingFlags == ShortAdsSequence) {
>+PartitionDesc = GetPdFromLongAd (Volume, ParentIcb);
>+ASSERT (PartitionDesc != NULL);
>+
> return GetShortAdLsn (
>   Volume,
>-  GetPdFromLongAd (Volume, ParentIcb),
>+  PartitionDesc,
>   (UDF_SHORT_ALLOCATION_DESCRIPTOR *)Ad
>   );
>   }

Reviewed-by: Paulo Alcantara <pca...@zytor.com>

Thanks!
Paulo

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


[edk2] [PATCH v4 2/2] MdeModulePkg/UDF: Fix creation of UDF logical partition

2017-09-22 Thread Paulo Alcantara
Do not reserve entire block device size for an UDF file system -
instead, reserve the appropriate space (UDF logical volume space) for
it.

Additionally, only create a logical partition for UDF logical volumes
that are currently supported by EDK2 UDF file system implementation. For
instance, an UDF volume with a single LVD and a single Physical (Type 1)
Partition will be supported.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Reported-by: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
Tested-by: Hao Wu <hao.a...@intel.com>
Build-tested-by: Laszlo Ersek <ler...@redhat.com>
Reviewed-by: Star Zeng <star.z...@intel.com>
Build-tested-by: Star Zeng <star.z...@intel.com>
Build-tested-by: Paulo Alcantara <pa...@hp.com>
---
 MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c| 366 ++--
 MdeModulePkg/Universal/Disk/UdfDxe/File.c |  16 +-
 MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627 

 MdeModulePkg/Universal/Disk/UdfDxe/Udf.c  |   7 -
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  | 158 ++---
 5 files changed, 606 insertions(+), 568 deletions(-)

diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c 
b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
index 609f56cef6..8aee30c759 100644
--- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
+++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
@@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
   OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
   )
 {
-  EFI_STATUS  Status;
-  UINT32  BlockSize;
-  EFI_LBA EndLBA;
-  EFI_LBA DescriptorLBAs[4];
-  UINTN   Index;
+  EFI_STATUS  Status;
+  UINT32  BlockSize;
+  EFI_LBA EndLBA;
+  EFI_LBA DescriptorLBAs[4];
+  UINTN   Index;
+  UDF_DESCRIPTOR_TAG  *DescriptorTag;
 
   BlockSize = BlockIo->Media->BlockSize;
   EndLBA = BlockIo->Media->LastBlock;
@@ -88,10 +89,13 @@ FindAnchorVolumeDescriptorPointer (
 if (EFI_ERROR (Status)) {
   return Status;
 }
+
+DescriptorTag = >DescriptorTag;
+
 //
 // Check if read LBA has a valid AVDP descriptor.
 //
-if (IS_AVDP (AnchorPoint)) {
+if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
   return EFI_SUCCESS;
 }
   }
@@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (
 }
 
 /**
-  Check if block device supports a valid UDF file system as specified by OSTA
-  Universal Disk Format Specification 2.60.
+  Find UDF volume identifiers in a Volume Recognition Sequence.
 
-  @param[in]   BlockIo  BlockIo interface.
-  @param[in]   DiskIo   DiskIo interface.
+  @param[in]  BlockIo BlockIo interface.
+  @param[in]  DiskIo  DiskIo interface.
 
-  @retval EFI_SUCCESS  UDF file system found.
-  @retval EFI_UNSUPPORTED  UDF file system not found.
-  @retval EFI_NO_MEDIA The device has no media.
-  @retval EFI_DEVICE_ERROR The device reported an error.
-  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
-  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to lack of
-   resources.
+  @retval EFI_SUCCESS UDF volume identifiers were found.
+  @retval EFI_NOT_FOUND   UDF volume identifiers were not found.
+  @retval other   Failed to perform disk I/O.
 
 **/
 EFI_STATUS
-SupportUdfFileSystem (
+FindUdfVolumeIdentifiers (
   IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
   IN EFI_DISK_IO_PROTOCOL   *DiskIo
   )
@@ -128,7 +127,6 @@ SupportUdfFileSystem (
   UINT64EndDiskOffset;
   CDROM_VOLUME_DESCRIPTOR   VolDescriptor;
   CDROM_VOLUME_DESCRIPTOR   TerminatingVolDescriptor;
-  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
 
   ZeroMem ((VOID *), sizeof 
(CDROM_VOLUME_DESCRIPTOR));
 
@@ -167,7 +165,7 @@ SupportUdfFileSystem (
 (CompareMem ((VOID *),
  (VOID *),
  sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
-  return EFI_UNSUPPORTED;
+  return EFI_NOT_FOUND;
 }
   }
 
@@ -176,7 +174,7 @@ SupportUdfFileSystem (
   //
   Offset += UDF_LOGICAL_SECTOR_SIZE;
   if (Offset >= EndDiskOffset) {
-return EFI_UNSUPPORTED;
+return EFI_NOT_FOUND;
   }
 
   Status = DiskIo->ReadDisk (
@@ -196,7 +194,7 @@ SupportUdfFileSystem (
   (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
(VOID *)UDF_NSR3_IDENTIFIER,
sizeof (VolDescriptor.Unknown.Id)) != 0)) {
-return EFI_UNSUPPORTED;
+return EFI_NOT_FOUND;
   }
 
   //
@@ -204,7 +202,7 @@ SupportUdfFileSystem (
   //
   Offset += UDF_LOGIC

[edk2] [PATCH v4 1/2] MdePkg: Add UDF volume structure definitions

2017-09-22 Thread Paulo Alcantara
This patch adds a few more UDF volume structures in order to detect an
UDF file system which is supported by current EDK2 UDF file system
implementation in Partition driver.

Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Liming Gao <liming@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
Build-tested-by: Laszlo Ersek <ler...@redhat.com>
Reviewed-by: Star Zeng <star.z...@intel.com>
Tested-by: Hao Wu <hao.a...@intel.com>
Build-tested-by: Star Zeng <star.z...@intel.com>
Build-tested-by: Paulo Alcantara <pa...@hp.com>
---
 MdePkg/Include/IndustryStandard/Udf.h | 97 +++-
 1 file changed, 92 insertions(+), 5 deletions(-)

diff --git a/MdePkg/Include/IndustryStandard/Udf.h 
b/MdePkg/Include/IndustryStandard/Udf.h
index 0febb4bcda..5806560aee 100644
--- a/MdePkg/Include/IndustryStandard/Udf.h
+++ b/MdePkg/Include/IndustryStandard/Udf.h
@@ -24,11 +24,22 @@
 #define UDF_LOGICAL_SECTOR_SIZE   ((UINT64)(1ULL << UDF_LOGICAL_SECTOR_SHIFT))
 #define UDF_VRS_START_OFFSET  ((UINT64)(16ULL << UDF_LOGICAL_SECTOR_SHIFT))
 
-#define _GET_TAG_ID(_Pointer) \
-  (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier)
-
-#define IS_AVDP(_Pointer) \
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 2))
+typedef enum {
+  UdfPrimaryVolumeDescriptor = 1,
+  UdfAnchorVolumeDescriptorPointer = 2,
+  UdfVolumeDescriptorPointer = 3,
+  UdfImplemenationUseVolumeDescriptor = 4,
+  UdfPartitionDescriptor = 5,
+  UdfLogicalVolumeDescriptor = 6,
+  UdfUnallocatedSpaceDescriptor = 7,
+  UdfTerminatingDescriptor = 8,
+  UdfLogicalVolumeIntegrityDescriptor = 9,
+  UdfFileSetDescriptor = 256,
+  UdfFileIdentifierDescriptor = 257,
+  UdfAllocationExtentDescriptor = 258,
+  UdfFileEntry = 261,
+  UdfExtendedFileEntry = 266,
+} UDF_VOLUME_DESCRIPTOR_ID;
 
 #pragma pack(1)
 
@@ -49,12 +60,88 @@ typedef struct {
 } UDF_EXTENT_AD;
 
 typedef struct {
+  UINT8   CharacterSetType;
+  UINT8   CharacterSetInfo[63];
+} UDF_CHAR_SPEC;
+
+typedef struct {
+  UINT8   Flags;
+  UINT8   Identifier[23];
+  union {
+//
+// Domain Entity Identifier
+//
+struct {
+  UINT16  UdfRevision;
+  UINT8   DomainFlags;
+  UINT8   Reserved[5];
+} Domain;
+//
+// UDF Entity Identifier
+//
+struct {
+  UINT16  UdfRevision;
+  UINT8   OSClass;
+  UINT8   OSIdentifier;
+  UINT8   Reserved[4];
+} Entity;
+//
+// Implementation Entity Identifier
+//
+struct {
+  UINT8   OSClass;
+  UINT8   OSIdentifier;
+  UINT8   ImplementationUseArea[6];
+} ImplementationEntity;
+//
+// Application Entity Identifier
+//
+struct {
+  UINT8   ApplicationUseArea[8];
+} ApplicationEntity;
+//
+// Raw Identifier Suffix
+//
+struct {
+  UINT8   Data[8];
+} Raw;
+  } Suffix;
+} UDF_ENTITY_ID;
+
+typedef struct {
+  UINT32LogicalBlockNumber;
+  UINT16PartitionReferenceNumber;
+} UDF_LB_ADDR;
+
+typedef struct {
+  UINT32   ExtentLength;
+  UDF_LB_ADDR  ExtentLocation;
+  UINT8ImplementationUse[6];
+} UDF_LONG_ALLOCATION_DESCRIPTOR;
+
+typedef struct {
   UDF_DESCRIPTOR_TAG  DescriptorTag;
   UDF_EXTENT_AD   MainVolumeDescriptorSequenceExtent;
   UDF_EXTENT_AD   ReserveVolumeDescriptorSequenceExtent;
   UINT8   Reserved[480];
 } UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER;
 
+typedef struct {
+  UDF_DESCRIPTOR_TAG  DescriptorTag;
+  UINT32  VolumeDescriptorSequenceNumber;
+  UDF_CHAR_SPEC   DescriptorCharacterSet;
+  UINT8   LogicalVolumeIdentifier[128];
+  UINT32  LogicalBlockSize;
+  UDF_ENTITY_ID   DomainIdentifier;
+  UDF_LONG_ALLOCATION_DESCRIPTOR  LogicalVolumeContentsUse;
+  UINT32  MapTableLength;
+  UINT32  NumberOfPartitionMaps;
+  UDF_ENTITY_ID   ImplementationIdentifier;
+  UINT8   ImplementationUse[128];
+  UDF_EXTENT_AD   IntegritySequenceExtent;
+  UINT8   PartitionMaps[6];
+} UDF_LOGICAL_VOLUME_DESCRIPTOR;
+
 #pragma pack()
 
 #endif
-- 
2.13.3.windows.1

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


[edk2] [PATCH v4 0/2] UDF partition driver fix

2017-09-22 Thread Paulo Alcantara
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=707

Hi,

This patchset fixes a bug in Partition driver that created UDF logical
partitions by using entire block device space and thus polluting
protocol database with broken handles.

v1->v2:
 - Followed Laszlo's suggestions to submit a proper patchset. Thanks!
 - As I'm still waiting for Ruiyu and Star to test this fix, I took
   advantage of it and did some code cleanups :-)

v2->v3:
 - Followed Ruiyu's suggestions to improve code and add additional
   checks for ensuring a valid UDF file system and supported by current
   EDK2 UDF file system implementation. Also run Ecc.py to make sure the
   files I touched did not break EDK2 C Coding Style, as well as
   PatchCheck.py for mal-formed patches.

v3->v4:
 - Change 2/2's title as suggested by Star.
 - Remove UDF_TAG_ID() and refactor out UDF_ENTITY_ID structure as
   suggested by Ruiyu.
 - Tested build with VS2015 toolchain.

I've had a chance to test these changes with my 32GiB USB stick
and formatted it on Windows 10 with `format` command. The UDF revisions
I tested (by specifying it with "/R:revision") were 1.02, 1.50, 2.00,
2.01 (default) and 2.50. They all worked except the 2.50 revision which
adds a Type 2 (Metadata) Partition and it's not supported by current
EDK2 UDF implementation -- which handles only Type 1 (Physical)
Partitions. The UDF 2.60 revision I tested with the usual
`sudo mkudffs -b 512 --media-type=hd /dev/sdX` command in Linux.

Remember, the *officially* supported revision is 2.60, however all
revisions use the same volume structures as defined by ECMA 167
specification, and they usually differ from each other by means of
new optional features, so that's why all those revisions worked with
this implementation.

Well, at least this what I understood when looking at the
specifications. Please correct me if I'm wrong.

Please, test building these changes in toolchains other than GCC and
make sure they don't break the world :-)

Thanks!
Paulo

Repo:   https://github.com/pcacjr/edk2.git
Branch: udf-partition-fix-v4

Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Liming Gao <liming@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Jiewen Yao <jiewen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Reported-by: Ruiyu Ni <ruiyu...@intel.com>
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---

Paulo Alcantara (2):
  MdePkg: Add UDF volume structure definitions
  MdeModulePkg/UDF: Fix creation of UDF logical partition

 MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c| 366 ++--
 MdeModulePkg/Universal/Disk/UdfDxe/File.c |  16 +-
 MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627 

 MdeModulePkg/Universal/Disk/UdfDxe/Udf.c  |   7 -
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  | 158 ++---
 MdePkg/Include/IndustryStandard/Udf.h |  97 ++-
 6 files changed, 698 insertions(+), 573 deletions(-)

-- 
2.13.3.windows.1

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


Re: [edk2] [PATCH v3 1/2] MdePkg: Add UDF volume structure definitions

2017-09-22 Thread Paulo Alcantara

Ruiyu,

On 9/21/2017 11:50 PM, Ni, Ruiyu wrote:

Paulo,
Comments below:

#define UDF_TAG_ID(_Tag) \
   (UDF_VOLUME_DESCRIPTOR_ID)((_Tag)->TagIdentifier)
1. I prefer to remove the UDF_TAG_ID macro. Adding type-cast to get TAG_ID is 
very straightforward.


Right. I'll remove it.

  
#define UDF_LVD_REVISION(_Lv) \

   *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix
typedef struct {
   UINT8   Flags;
   UINT8   Identifier[23];
   UINT8   IdentifierSuffix[8];
} UDF_ENTITY_ID;
2. Entity structure is defined by ECMA-167 spec and re-used by UDF spec.
  I think since we are creating UDF structure in udf.h, how about using the 
below
  structure layout and removing the UDF_LVD_REVISION macro:
  Typedef struct {
UINT8   Flags;
UINT8   Identifier[23];
UINT16 UdfRevision;
UINT8   DomainFlags;
UINT8   Reserved[5];
 } UDF_ENTITY_ID;


Much better! Thanks for looking into that.

The UDF 2.60 specification says:

> UDF classifies Entity Identifiers into 4 separate types. Each type 
has > its own Suffix Type for the Identifier Suffix field. The 4 types are:

>
>  Domain Entity Identifiers with a Domain Identifier Suffix
>  UDF Entity Identifierswith a UDF Identifier Suffix
>  Implementation Entity Identifiers with an Implementation Identifier 
Suffix

>  Application Entity Identifierswith an Application Identifier Suffix

Given that, I think an union would be more appropriate.

E.g.,

typedef struct {
  UINT8   Flags;
  UINT8   Identifier[23];
  union {
struct {
  UINT16  UdfRevision;
  UINT8   DomainFlags;
  UINT8   Reversed[5];
} DomainIdentifier;
struct {
  UINT16  UdfRevision;
  UINT8   OSClass;
  UINT8   OSIdentifier;
  UINT8   Reserved[4];
} EntityIdentifier;
struct {
  UINT8   OSClass;
  UINT8   OSIdentifier;
  UINT8   ImplementationUseArea[6];
} ImplementationEntityIdentifier;
struct {
  UINT8   ApplicationUseArea[8];
} ApplicationEntityIdentifier;
UINT8 IdentifierSuffix[8];
  };
} UDF_ENTITY_ID;

Do you agree with me? Or that wouldn't be necessary?

Thanks!
Paulo



I am not sure if there are other structures that are defined in ECMA spec and
re-used by UDF spec. I think we can apply the similar rules to those structures
as well.

Thanks/Ray


-Original Message-
From: Paulo Alcantara [mailto:pca...@zytor.com]
Sent: Thursday, September 21, 2017 2:16 AM
To: edk2-devel@lists.01.org
Cc: Paulo Alcantara <pca...@zytor.com>; Kinney, Michael D
<michael.d.kin...@intel.com>; Gao, Liming <liming@intel.com>; Laszlo
Ersek <ler...@redhat.com>; Ni, Ruiyu <ruiyu...@intel.com>
Subject: [PATCH v3 1/2] MdePkg: Add UDF volume structure definitions

This patch adds a few more UDF volume structures in order to detect an UDF
file system which is supported by current EDK2 UDF file system
implementation in Partition driver.

Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Liming Gao <liming@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
  MdePkg/Include/IndustryStandard/Udf.h | 63 ++--
  1 file changed, 59 insertions(+), 4 deletions(-)

diff --git a/MdePkg/Include/IndustryStandard/Udf.h
b/MdePkg/Include/IndustryStandard/Udf.h
index 0febb4bcda..002e87e150 100644
--- a/MdePkg/Include/IndustryStandard/Udf.h
+++ b/MdePkg/Include/IndustryStandard/Udf.h
@@ -24,11 +24,28 @@
  #define UDF_LOGICAL_SECTOR_SIZE   ((UINT64)(1ULL <<
UDF_LOGICAL_SECTOR_SHIFT))
  #define UDF_VRS_START_OFFSET  ((UINT64)(16ULL <<
UDF_LOGICAL_SECTOR_SHIFT))

-#define _GET_TAG_ID(_Pointer) \
-  (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier)
+typedef enum {
+  UdfPrimaryVolumeDescriptor = 1,
+  UdfAnchorVolumeDescriptorPointer = 2,
+  UdfVolumeDescriptorPointer = 3,
+  UdfImplemenationUseVolumeDescriptor = 4,
+  UdfPartitionDescriptor = 5,
+  UdfLogicalVolumeDescriptor = 6,
+  UdfUnallocatedSpaceDescriptor = 7,
+  UdfTerminatingDescriptor = 8,
+  UdfLogicalVolumeIntegrityDescriptor = 9,
+  UdfFileSetDescriptor = 256,
+  UdfFileIdentifierDescriptor = 257,
+  UdfAllocationExtentDescriptor = 258,
+  UdfFileEntry = 261,
+  UdfExtendedFileEntry = 266,
+} UDF_VOLUME_DESCRIPTOR_ID;

-#define IS_AVDP(_Pointer) \
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 2))
+#define UDF_TAG_ID(_Tag) \
+  (UDF_VOLUME_DESCRIPTOR_ID)((_Tag)->TagIdentifier)
+
+#define UDF_LVD_REVISION(_Lv) \
+  *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix

  #pragma pack(1)

@@ -49,12 +66,50 @@ typedef struct {
  } UDF_EXTENT_AD;

  typedef struct {
+  UINT8   CharacterSetType;
+  UINT8   Charact

Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition

2017-09-21 Thread Paulo Alcantara
On Thu, Sep 21, 2017 at 10:52 AM, Paulo Alcantara <pca...@zytor.com> wrote:
>
>
> On September 21, 2017 10:47:07 AM GMT-03:00, "Zeng, Star" 
> <star.z...@intel.com> wrote:
>>Does it have functional impact?
>
> Nope. When Partition driver walks the partition detect routine table, it 
> executes each routine and then checks for EFI_NO_MEDIA and EFI_MEDIA_CHANGED 
> only. So, the child handle is installed and the EFI_NOT_FOUND is a no-op in 
> that case.

BTW, I performed a quick test with UdfDxe enabled and disabled in OVMF
and the removal did not seem to break or change any behavior.

Thanks!
Paulo

>
> Thanks!
> Paulo
>
>>
>>Thanks,
>>Star
>>-Original Message-
>>From: Paulo Alcantara [mailto:pca...@zytor.com]
>>Sent: Thursday, September 21, 2017 9:29 PM
>>To: Wu, Hao A <hao.a...@intel.com>; edk2-devel@lists.01.org
>>Cc: Ni, Ruiyu <ruiyu...@intel.com>; Laszlo Ersek <ler...@redhat.com>;
>>Dong, Eric <eric.d...@intel.com>; Zeng, Star <star.z...@intel.com>
>>Subject: RE: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>>creation of UDF logical partition
>>
>>
>>
>>On September 21, 2017 9:44:10 AM GMT-03:00, "Wu, Hao A"
>><hao.a...@intel.com> wrote:
>>>One small comment, within function PartitionInstallUdfChildHandles():
>>>
>>>  ...
>>>  //
>>>  // Install partition child handle for UDF file system
>>>  //
>>>  Status = PartitionInstallChildHandle (
>>>...
>>>);
>>>if (!EFI_ERROR (Status)) {  <- Is this a typo? "if (EFI_ERROR
>>>(Status)) {"
>>>Status = EFI_NOT_FOUND;
>>>  }
>>
>>Yes, it is. Good catch! Could you please fix that for me by removing
>>the if condition? Otherwise I can send a v4 later with that.
>>
>>Thanks!
>>Paulo
>>
>>>
>>>
>>>Best Regards,
>>>Hao Wu
>>>
>>>
>>>> -Original Message-
>>>> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf
>>>Of Paulo
>>>> Alcantara
>>>> Sent: Thursday, September 21, 2017 2:16 AM
>>>> To: edk2-devel@lists.01.org
>>>> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
>>>> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>>>creation of
>>>> UDF logical partition
>>>>
>>>> Do not reserve entire block device size for an UDF file system -
>>>> instead, reserve the appropriate space (UDF logical volume space)
>>for
>>>> it.
>>>>
>>>> Additionally, only create a logical partition for UDF logical
>>volumes
>>>> that are currently supported by EDK2 UDF file system implementation.
>>>For
>>>> instance, an UDF volume with a single LVD and a single Physical
>>(Type
>>>1)
>>>> Partition will be supported.
>>>>
>>>> Cc: Eric Dong <eric.d...@intel.com>
>>>> Cc: Ruiyu Ni <ruiyu...@intel.com>
>>>> Cc: Star Zeng <star.z...@intel.com>
>>>> Cc: Laszlo Ersek <ler...@redhat.com>
>>>> Reported-by: Ruiyu Ni <ruiyu...@intel.com>
>>>> Contributed-under: TianoCore Contribution Agreement 1.1
>>>> Signed-off-by: Paulo Alcantara <pca...@zytor.com>
>>>> ---
>>>>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c| 363
>>>++--
>>>>  MdeModulePkg/Universal/Disk/UdfDxe/File.c |  16 +-
>>>>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
>>>> 
>>>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c  |   7 -
>>>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  | 158
>>>++---
>>>>  5 files changed, 606 insertions(+), 565 deletions(-)
>>>>
>>>> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>>> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>>> index 609f56cef6..572ba7a81a 100644
>>>> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>>> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>>> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
>>>>OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>>>)
>>>>  {
>>>> -  EFI_STATUS  Status;
>>>> -  UINT32  BlockSize;
>>>> -  EFI_LBA EndLBA;
>>>> -  EFI_LBA Descr

Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition

2017-09-21 Thread Paulo Alcantara


On September 21, 2017 10:47:07 AM GMT-03:00, "Zeng, Star" <star.z...@intel.com> 
wrote:
>Does it have functional impact?

Nope. When Partition driver walks the partition detect routine table, it 
executes each routine and then checks for EFI_NO_MEDIA and EFI_MEDIA_CHANGED 
only. So, the child handle is installed and the EFI_NOT_FOUND is a no-op in 
that case.

Thanks!
Paulo

>
>Thanks,
>Star
>-----Original Message-
>From: Paulo Alcantara [mailto:pca...@zytor.com] 
>Sent: Thursday, September 21, 2017 9:29 PM
>To: Wu, Hao A <hao.a...@intel.com>; edk2-devel@lists.01.org
>Cc: Ni, Ruiyu <ruiyu...@intel.com>; Laszlo Ersek <ler...@redhat.com>;
>Dong, Eric <eric.d...@intel.com>; Zeng, Star <star.z...@intel.com>
>Subject: RE: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>creation of UDF logical partition
>
>
>
>On September 21, 2017 9:44:10 AM GMT-03:00, "Wu, Hao A"
><hao.a...@intel.com> wrote:
>>One small comment, within function PartitionInstallUdfChildHandles():
>>
>>  ...
>>  //
>>  // Install partition child handle for UDF file system
>>  //
>>  Status = PartitionInstallChildHandle (
>>...
>>);
>>if (!EFI_ERROR (Status)) {  <- Is this a typo? "if (EFI_ERROR
>>(Status)) {"  
>>Status = EFI_NOT_FOUND;
>>  }
>
>Yes, it is. Good catch! Could you please fix that for me by removing
>the if condition? Otherwise I can send a v4 later with that.
>
>Thanks!
>Paulo
>
>>  
>>
>>Best Regards,
>>Hao Wu
>>
>>
>>> -Original Message-
>>> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf
>>Of Paulo
>>> Alcantara
>>> Sent: Thursday, September 21, 2017 2:16 AM
>>> To: edk2-devel@lists.01.org
>>> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
>>> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>>creation of
>>> UDF logical partition
>>> 
>>> Do not reserve entire block device size for an UDF file system - 
>>> instead, reserve the appropriate space (UDF logical volume space)
>for 
>>> it.
>>> 
>>> Additionally, only create a logical partition for UDF logical
>volumes 
>>> that are currently supported by EDK2 UDF file system implementation.
>>For
>>> instance, an UDF volume with a single LVD and a single Physical
>(Type
>>1)
>>> Partition will be supported.
>>> 
>>> Cc: Eric Dong <eric.d...@intel.com>
>>> Cc: Ruiyu Ni <ruiyu...@intel.com>
>>> Cc: Star Zeng <star.z...@intel.com>
>>> Cc: Laszlo Ersek <ler...@redhat.com>
>>> Reported-by: Ruiyu Ni <ruiyu...@intel.com>
>>> Contributed-under: TianoCore Contribution Agreement 1.1
>>> Signed-off-by: Paulo Alcantara <pca...@zytor.com>
>>> ---
>>>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c| 363
>>++--
>>>  MdeModulePkg/Universal/Disk/UdfDxe/File.c |  16 +-
>>>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
>>> 
>>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c  |   7 -
>>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  | 158
>>++---
>>>  5 files changed, 606 insertions(+), 565 deletions(-)
>>> 
>>> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>> index 609f56cef6..572ba7a81a 100644
>>> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>>> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
>>>OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>>)
>>>  {
>>> -  EFI_STATUS  Status;
>>> -  UINT32  BlockSize;
>>> -  EFI_LBA EndLBA;
>>> -  EFI_LBA DescriptorLBAs[4];
>>> -  UINTN   Index;
>>> +  EFI_STATUS  Status;
>>> +  UINT32  BlockSize;
>>> +  EFI_LBA EndLBA;
>>> +  EFI_LBA DescriptorLBAs[4];
>>> +  UINTN   Index;
>>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>>> 
>>>BlockSize = BlockIo->Media->BlockSize;
>>>EndLBA = BlockIo->Media->LastBlock; @@ -88,10 +89,13 @@ 
>>> FindAnchorVolumeDescriptorPointer (
>>>  if (EFI_ERROR (Status)) {
>>>return Status;
>>>  }
>>> +
>>>

Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition

2017-09-21 Thread Paulo Alcantara


On September 21, 2017 9:44:10 AM GMT-03:00, "Wu, Hao A" <hao.a...@intel.com> 
wrote:
>One small comment, within function PartitionInstallUdfChildHandles():
>
>  ...
>  //
>  // Install partition child handle for UDF file system
>  //
>  Status = PartitionInstallChildHandle (
>...
>);
>if (!EFI_ERROR (Status)) {  <- Is this a typo? "if (EFI_ERROR
>(Status)) {"  
>Status = EFI_NOT_FOUND;
>  }

Yes, it is. Good catch! Could you please fix that for me by removing the if 
condition? Otherwise I can send a v4 later with that.

Thanks!
Paulo

>  
>
>Best Regards,
>Hao Wu
>
>
>> -Original Message-
>> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf
>Of Paulo
>> Alcantara
>> Sent: Thursday, September 21, 2017 2:16 AM
>> To: edk2-devel@lists.01.org
>> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
>> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>creation of
>> UDF logical partition
>> 
>> Do not reserve entire block device size for an UDF file system -
>> instead, reserve the appropriate space (UDF logical volume space) for
>> it.
>> 
>> Additionally, only create a logical partition for UDF logical volumes
>> that are currently supported by EDK2 UDF file system implementation.
>For
>> instance, an UDF volume with a single LVD and a single Physical (Type
>1)
>> Partition will be supported.
>> 
>> Cc: Eric Dong <eric.d...@intel.com>
>> Cc: Ruiyu Ni <ruiyu...@intel.com>
>> Cc: Star Zeng <star.z...@intel.com>
>> Cc: Laszlo Ersek <ler...@redhat.com>
>> Reported-by: Ruiyu Ni <ruiyu...@intel.com>
>> Contributed-under: TianoCore Contribution Agreement 1.1
>> Signed-off-by: Paulo Alcantara <pca...@zytor.com>
>> ---
>>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c| 363
>++--
>>  MdeModulePkg/Universal/Disk/UdfDxe/File.c |  16 +-
>>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
>> 
>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c  |   7 -
>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  | 158
>++---
>>  5 files changed, 606 insertions(+), 565 deletions(-)
>> 
>> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> index 609f56cef6..572ba7a81a 100644
>> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
>>OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
>>)
>>  {
>> -  EFI_STATUS  Status;
>> -  UINT32  BlockSize;
>> -  EFI_LBA EndLBA;
>> -  EFI_LBA DescriptorLBAs[4];
>> -  UINTN   Index;
>> +  EFI_STATUS  Status;
>> +  UINT32  BlockSize;
>> +  EFI_LBA EndLBA;
>> +  EFI_LBA DescriptorLBAs[4];
>> +  UINTN   Index;
>> +  UDF_DESCRIPTOR_TAG  *DescriptorTag;
>> 
>>BlockSize = BlockIo->Media->BlockSize;
>>EndLBA = BlockIo->Media->LastBlock;
>> @@ -88,10 +89,13 @@ FindAnchorVolumeDescriptorPointer (
>>  if (EFI_ERROR (Status)) {
>>return Status;
>>  }
>> +
>> +DescriptorTag = >DescriptorTag;
>> +
>>  //
>>  // Check if read LBA has a valid AVDP descriptor.
>>  //
>> -if (IS_AVDP (AnchorPoint)) {
>> +if (DescriptorTag->TagIdentifier ==
>UdfAnchorVolumeDescriptorPointer) {
>>return EFI_SUCCESS;
>>  }
>>}
>> @@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (
>>  }
>> 
>>  /**
>> -  Check if block device supports a valid UDF file system as
>specified by OSTA
>> -  Universal Disk Format Specification 2.60.
>> +  Find UDF volume identifiers in a Volume Recognition Sequence.
>> 
>> -  @param[in]   BlockIo  BlockIo interface.
>> -  @param[in]   DiskIo   DiskIo interface.
>> +  @param[in]  BlockIo BlockIo interface.
>> +  @param[in]  DiskIo  DiskIo interface.
>> 
>> -  @retval EFI_SUCCESS  UDF file system found.
>> -  @retval EFI_UNSUPPORTED  UDF file system not found.
>> -  @retval EFI_NO_MEDIA The device has no media.
>> -  @retval EFI_DEVICE_ERROR The device reported an error.
>> -  @retval EFI_VOLUME_CORRUPTED The file system structures are
>corrupted.
>> -  @retval EFI_OUT_OF_RESOURCES T

Re: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition

2017-09-21 Thread Paulo Alcantara


On September 21, 2017 5:49:19 AM GMT-03:00, "Zeng, Star" <star.z...@intel.com> 
wrote:
>VS2015 Build-tested-by: Star Zeng <star.z...@intel.com>
>
>I have a minor comment to this patch title, how about to use
>"MdeModulePkg/UDF: Fix creation of UDF logical partition" as this patch
>is touching both PartitionDxe and UdfDxe? Otherwise, you'd better to
>split this patch to two, one for PartitionDxe and one for UdfDxe.
>
>Since the patch could fix the issue we found, and if you agree my minor
>comment above, Reviewed-by: Star Zeng <star.z...@intel.com>

Thank you all for the tests! Star, I agree with you. Could you please fix the 
title for me? Also, please add Laszlo's Build-tested-by in the series.

Thanks!
Paulo

>
>
>Thanks,
>Star
>-Original Message-
>From: Wu, Hao A 
>Sent: Thursday, September 21, 2017 4:09 PM
>To: Paulo Alcantara <pca...@zytor.com>; edk2-devel@lists.01.org
>Cc: Ni, Ruiyu <ruiyu...@intel.com>; Laszlo Ersek <ler...@redhat.com>;
>Dong, Eric <eric.d...@intel.com>; Zeng, Star <star.z...@intel.com>
>Subject: RE: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>creation of UDF logical partition
>
>I did a simple test on a Windows8.1 installation DVD, and here's the
>result
>of a map command under shell:
>
>Before the patch:
>Mapping table
>  FS0: Alias(s):CD0f65535a1:;BLK2:
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0x,0x0)/CDROM(0x1)
> BLK0: Alias(s):
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0x,0x0)
> BLK1: Alias(s):
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0x,0x0)/CDROM(0x0)
>  FS1: Alias(s):CD0f65535ab:;BLK5:
>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0x,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)/CDROM(0x1)
> BLK3: Alias(s):
>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0x,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)
> BLK4: Alias(s):
>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0x,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)/CDROM(0x0)
>
>After the patch:
>Mapping table
>  FS0: Alias(s):CD0f65535a1:;BLK2:
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0x,0x0)/CDROM(0x1)
> BLK0: Alias(s):
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0x,0x0)
> BLK1: Alias(s):
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0x,0x0)/CDROM(0x0)
> BLK3: Alias(s):
>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x5,0x,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)
>
>
>Since the additional file system is gone:
>Tested-by: Hao Wu <hao.a...@intel.com>
>
>
>Best Regards,
>Hao Wu
>
>> -Original Message-
>> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf
>Of Paulo
>> Alcantara
>> Sent: Thursday, September 21, 2017 2:16 AM
>> To: edk2-devel@lists.01.org
>> Cc: Ni, Ruiyu; Laszlo Ersek; Dong, Eric; Zeng, Star
>> Subject: [edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix
>creation of
>> UDF logical partition
>> 
>> Do not reserve entire block device size for an UDF file system -
>> instead, reserve the appropriate space (UDF logical volume space) for
>> it.
>> 
>> Additionally, only create a logical partition for UDF logical volumes
>> that are currently supported by EDK2 UDF file system implementation.
>For
>> instance, an UDF volume with a single LVD and a single Physical (Type
>1)
>> Partition will be supported.
>> 
>> Cc: Eric Dong <eric.d...@intel.com>
>> Cc: Ruiyu Ni <ruiyu...@intel.com>
>> Cc: Star Zeng <star.z...@intel.com>
>> Cc: Laszlo Ersek <ler...@redhat.com>
>> Reported-by: Ruiyu Ni <ruiyu...@intel.com>
>> Contributed-under: TianoCore Contribution Agreement 1.1
>> Signed-off-by: Paulo Alcantara <pca...@zytor.com>
>> ---
>>  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c| 363
>++--
>>  MdeModulePkg/Universal/Disk/UdfDxe/File.c |  16 +-
>>  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627
>> 
>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c  |   7 -
>>  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  | 158
>++---
>>  5 files changed, 606 insertions(+), 565 deletions(-)
>> 
>> diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> index 609f56cef6..572ba7a81a 100644
>> --- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> +++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
>> @@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
>>OUT  UDF_ANCHOR_VOLUME_DESCRIPT

Re: [edk2] [PATCH v3 0/2] UDF partition driver fix

2017-09-20 Thread Paulo Alcantara


On September 20, 2017 4:25:10 PM GMT-03:00, Laszlo Ersek <ler...@redhat.com> 
wrote:
>On 09/20/17 20:16, Paulo Alcantara wrote:
>
>> Please, test building these changes in toolchains other than GCC and
>> make sure they don't break the world :-)
>
>> Repo:   https://github.com/pcacjr/edk2.git
>> Branch: udf-partition-fix-v3
>
>I build-tested your branch with OVMF (both IA32 and X64), using:
>
>- gcc-4.8.5, GCC48, DEBUG
>- clang-3.8.1, CLANG38, NOOPT
>- gcc-7.1.1, GCC5, DEBUG
>
>and also cross-built your branch as part of ArmVirtQemu (both ARM and
>AARCH64), using:
>
>- gcc-6.1.1, GCC5, DEBUG
>
>If it matters, you can add:
>
>Build-tested-by: Laszlo Ersek <ler...@redhat.com>

Of course it does! :-) Thank you very much. You might be wondering why I didn't 
build-test it with MSVC - well, my wife's laptop got no Visual Studio 
installed, bul only the necessary 'format' command for formatting my USB stick 
with UDF :-)

Thanks!
Paulo

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


[edk2] [PATCH v3 1/2] MdePkg: Add UDF volume structure definitions

2017-09-20 Thread Paulo Alcantara
This patch adds a few more UDF volume structures in order to detect an
UDF file system which is supported by current EDK2 UDF file system
implementation in Partition driver.

Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Liming Gao <liming@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
 MdePkg/Include/IndustryStandard/Udf.h | 63 ++--
 1 file changed, 59 insertions(+), 4 deletions(-)

diff --git a/MdePkg/Include/IndustryStandard/Udf.h 
b/MdePkg/Include/IndustryStandard/Udf.h
index 0febb4bcda..002e87e150 100644
--- a/MdePkg/Include/IndustryStandard/Udf.h
+++ b/MdePkg/Include/IndustryStandard/Udf.h
@@ -24,11 +24,28 @@
 #define UDF_LOGICAL_SECTOR_SIZE   ((UINT64)(1ULL << UDF_LOGICAL_SECTOR_SHIFT))
 #define UDF_VRS_START_OFFSET  ((UINT64)(16ULL << UDF_LOGICAL_SECTOR_SHIFT))
 
-#define _GET_TAG_ID(_Pointer) \
-  (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier)
+typedef enum {
+  UdfPrimaryVolumeDescriptor = 1,
+  UdfAnchorVolumeDescriptorPointer = 2,
+  UdfVolumeDescriptorPointer = 3,
+  UdfImplemenationUseVolumeDescriptor = 4,
+  UdfPartitionDescriptor = 5,
+  UdfLogicalVolumeDescriptor = 6,
+  UdfUnallocatedSpaceDescriptor = 7,
+  UdfTerminatingDescriptor = 8,
+  UdfLogicalVolumeIntegrityDescriptor = 9,
+  UdfFileSetDescriptor = 256,
+  UdfFileIdentifierDescriptor = 257,
+  UdfAllocationExtentDescriptor = 258,
+  UdfFileEntry = 261,
+  UdfExtendedFileEntry = 266,
+} UDF_VOLUME_DESCRIPTOR_ID;
 
-#define IS_AVDP(_Pointer) \
-  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 2))
+#define UDF_TAG_ID(_Tag) \
+  (UDF_VOLUME_DESCRIPTOR_ID)((_Tag)->TagIdentifier)
+
+#define UDF_LVD_REVISION(_Lv) \
+  *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix
 
 #pragma pack(1)
 
@@ -49,12 +66,50 @@ typedef struct {
 } UDF_EXTENT_AD;
 
 typedef struct {
+  UINT8   CharacterSetType;
+  UINT8   CharacterSetInfo[63];
+} UDF_CHAR_SPEC;
+
+typedef struct {
+  UINT8   Flags;
+  UINT8   Identifier[23];
+  UINT8   IdentifierSuffix[8];
+} UDF_ENTITY_ID;
+
+typedef struct {
+  UINT32LogicalBlockNumber;
+  UINT16PartitionReferenceNumber;
+} UDF_LB_ADDR;
+
+typedef struct {
+  UINT32   ExtentLength;
+  UDF_LB_ADDR  ExtentLocation;
+  UINT8ImplementationUse[6];
+} UDF_LONG_ALLOCATION_DESCRIPTOR;
+
+typedef struct {
   UDF_DESCRIPTOR_TAG  DescriptorTag;
   UDF_EXTENT_AD   MainVolumeDescriptorSequenceExtent;
   UDF_EXTENT_AD   ReserveVolumeDescriptorSequenceExtent;
   UINT8   Reserved[480];
 } UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER;
 
+typedef struct {
+  UDF_DESCRIPTOR_TAG  DescriptorTag;
+  UINT32  VolumeDescriptorSequenceNumber;
+  UDF_CHAR_SPEC   DescriptorCharacterSet;
+  UINT8   LogicalVolumeIdentifier[128];
+  UINT32  LogicalBlockSize;
+  UDF_ENTITY_ID   DomainIdentifier;
+  UDF_LONG_ALLOCATION_DESCRIPTOR  LogicalVolumeContentsUse;
+  UINT32  MapTableLength;
+  UINT32  NumberOfPartitionMaps;
+  UDF_ENTITY_ID   ImplementationIdentifier;
+  UINT8   ImplementationUse[128];
+  UDF_EXTENT_AD   IntegritySequenceExtent;
+  UINT8   PartitionMaps[6];
+} UDF_LOGICAL_VOLUME_DESCRIPTOR;
+
 #pragma pack()
 
 #endif
-- 
2.11.0

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


[edk2] [PATCH v3 2/2] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition

2017-09-20 Thread Paulo Alcantara
Do not reserve entire block device size for an UDF file system -
instead, reserve the appropriate space (UDF logical volume space) for
it.

Additionally, only create a logical partition for UDF logical volumes
that are currently supported by EDK2 UDF file system implementation. For
instance, an UDF volume with a single LVD and a single Physical (Type 1)
Partition will be supported.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Reported-by: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
 MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c| 363 ++--
 MdeModulePkg/Universal/Disk/UdfDxe/File.c |  16 +-
 MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627 

 MdeModulePkg/Universal/Disk/UdfDxe/Udf.c  |   7 -
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  | 158 ++---
 5 files changed, 606 insertions(+), 565 deletions(-)

diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c 
b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
index 609f56cef6..572ba7a81a 100644
--- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
+++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
@@ -64,11 +64,12 @@ FindAnchorVolumeDescriptorPointer (
   OUT  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint
   )
 {
-  EFI_STATUS  Status;
-  UINT32  BlockSize;
-  EFI_LBA EndLBA;
-  EFI_LBA DescriptorLBAs[4];
-  UINTN   Index;
+  EFI_STATUS  Status;
+  UINT32  BlockSize;
+  EFI_LBA EndLBA;
+  EFI_LBA DescriptorLBAs[4];
+  UINTN   Index;
+  UDF_DESCRIPTOR_TAG  *DescriptorTag;
 
   BlockSize = BlockIo->Media->BlockSize;
   EndLBA = BlockIo->Media->LastBlock;
@@ -88,10 +89,13 @@ FindAnchorVolumeDescriptorPointer (
 if (EFI_ERROR (Status)) {
   return Status;
 }
+
+DescriptorTag = >DescriptorTag;
+
 //
 // Check if read LBA has a valid AVDP descriptor.
 //
-if (IS_AVDP (AnchorPoint)) {
+if (DescriptorTag->TagIdentifier == UdfAnchorVolumeDescriptorPointer) {
   return EFI_SUCCESS;
 }
   }
@@ -102,23 +106,18 @@ FindAnchorVolumeDescriptorPointer (
 }
 
 /**
-  Check if block device supports a valid UDF file system as specified by OSTA
-  Universal Disk Format Specification 2.60.
+  Find UDF volume identifiers in a Volume Recognition Sequence.
 
-  @param[in]   BlockIo  BlockIo interface.
-  @param[in]   DiskIo   DiskIo interface.
+  @param[in]  BlockIo BlockIo interface.
+  @param[in]  DiskIo  DiskIo interface.
 
-  @retval EFI_SUCCESS  UDF file system found.
-  @retval EFI_UNSUPPORTED  UDF file system not found.
-  @retval EFI_NO_MEDIA The device has no media.
-  @retval EFI_DEVICE_ERROR The device reported an error.
-  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
-  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to lack of
-   resources.
+  @retval EFI_SUCCESS UDF volume identifiers were found.
+  @retval EFI_NOT_FOUND   UDF volume identifiers were not found.
+  @retval other   Failed to perform disk I/O.
 
 **/
 EFI_STATUS
-SupportUdfFileSystem (
+FindUdfVolumeIdentifiers (
   IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
   IN EFI_DISK_IO_PROTOCOL   *DiskIo
   )
@@ -128,7 +127,6 @@ SupportUdfFileSystem (
   UINT64EndDiskOffset;
   CDROM_VOLUME_DESCRIPTOR   VolDescriptor;
   CDROM_VOLUME_DESCRIPTOR   TerminatingVolDescriptor;
-  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
 
   ZeroMem ((VOID *), sizeof 
(CDROM_VOLUME_DESCRIPTOR));
 
@@ -167,7 +165,7 @@ SupportUdfFileSystem (
 (CompareMem ((VOID *),
  (VOID *),
  sizeof (CDROM_VOLUME_DESCRIPTOR)) == 0)) {
-  return EFI_UNSUPPORTED;
+  return EFI_NOT_FOUND;
 }
   }
 
@@ -176,7 +174,7 @@ SupportUdfFileSystem (
   //
   Offset += UDF_LOGICAL_SECTOR_SIZE;
   if (Offset >= EndDiskOffset) {
-return EFI_UNSUPPORTED;
+return EFI_NOT_FOUND;
   }
 
   Status = DiskIo->ReadDisk (
@@ -196,7 +194,7 @@ SupportUdfFileSystem (
   (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
(VOID *)UDF_NSR3_IDENTIFIER,
sizeof (VolDescriptor.Unknown.Id)) != 0)) {
-return EFI_UNSUPPORTED;
+return EFI_NOT_FOUND;
   }
 
   //
@@ -204,7 +202,7 @@ SupportUdfFileSystem (
   //
   Offset += UDF_LOGICAL_SECTOR_SIZE;
   if (Offset >= EndDiskOffset) {
-return EFI_UNSUPPORTED;
+return EFI_NOT_FOUND;
   }
 
   Status = DiskIo->ReadDisk (
@@ -221,15 +219,291 @@ SupportUdfFileSystem (
   if (CompareMem ((VOID *)VolDescriptor.Unknown.Id,
  

[edk2] [PATCH v3 0/2] UDF partition driver fix

2017-09-20 Thread Paulo Alcantara
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=707

Hi,

This patchset fixes a bug in Partition driver that created UDF logical
partitions by using entire block device space and thus polluting
protocol database with broken handles.

v1->v2:
 - Followed Laszlo's suggestions to submit a proper patchset. Thanks!
 - As I'm still waiting for Ruiyu and Star to test this fix, I took
   advantage of it and did some code cleanups :-)

v2->v3:
 - Followed Ruiyu's suggestions to improve code and add additional
   checks for ensuring a valid UDF file system and supported by current
   EDK2 UDF file system implementation. Also run Ecc.py to make sure the
   files I touched did not break EDK2 C Coding Style, as well as
   PatchCheck.py for mal-formed patches.

I've had a chance to test these changes with my 32GiB USB stick
and formatted it on Windows 10 with `format` command. The UDF revisions
I tested (by specifying it with "/R:revision") were 1.02, 1.50, 2.00,
2.01 (default) and 2.50. They all worked except the 2.50 revision which
adds a Type 2 (Metadata) Partition and it's not supported by current
EDK2 UDF implementation -- which handles only Type 1 (Physical)
Partitions. The UDF 2.60 revision I tested with the usual
`sudo mkudffs -b 512 --media-type=hd /dev/sdX` command in Linux.

Remember, the *officially* supported revision is 2.60, however all
revisions use the same volume structures as defined by ECMA 167
specification, and they usually differ from each other by means of
new optional features, so that's why all those revisions worked with
this implementation.

Well, at least this what I understood when looking at the
specifications. Please correct me if I'm wrong.

Please, test building these changes in toolchains other than GCC and
make sure they don't break the world :-)

Thanks!
Paulo

Repo:   https://github.com/pcacjr/edk2.git
Branch: udf-partition-fix-v3

Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Liming Gao <liming@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Jiewen Yao <jiewen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Reported-by: Ruiyu Ni <ruiyu...@intel.com>
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---

Paulo Alcantara (2):
  MdePkg: Add UDF volume structure definitions
  MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition

 MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c| 363 ++--
 MdeModulePkg/Universal/Disk/UdfDxe/File.c |  16 +-
 MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 627 

 MdeModulePkg/Universal/Disk/UdfDxe/Udf.c  |   7 -
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  | 158 ++---
 MdePkg/Include/IndustryStandard/Udf.h |  63 +-
 6 files changed, 665 insertions(+), 569 deletions(-)

-- 
2.11.0

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


Re: [edk2] [PATCH v2 0/3] UDF partition driver fix

2017-09-18 Thread Paulo Alcantara

Hi Ruiyu,

On 9/18/2017 1:52 AM, Ni, Ruiyu wrote:

Paulo,
Could you please paste a "map -r" output on a CDROM which
contains Eltorito volume?
I want to confirm that the result is expected.


With UdfDxe driver disabled in OVMF:

>Mapping table
>  FS0: Alias(s):CD0c65535a1:;BLK2:
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0x,0x0)/CDROM(0x1)
> BLK0: Alias(s):
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0x,0x0)
> BLK1: Alias(s):
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0x,0x0)/CDROM(0x0)
> BLK3: Alias(s):
> 
PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0x,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)


With UdfDxe driver enabled in OVMF:

> Mapping table
>  FS0: Alias(s):CD0c65535a1:;BLK2:
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0x,0x0)/CDROM(0x1)
>  FS1: Alias(s):F0c65535a:;BLK3:
> 
PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0x,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)

> BLK0: Alias(s):
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0x,0x0)
> BLK1: Alias(s):
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0x,0x0)/CDROM(0x0)

Thanks!
Paulo



Thanks/Ray


-Original Message-
From: Paulo Alcantara [mailto:pca...@zytor.com]
Sent: Sunday, September 17, 2017 9:13 PM
To: edk2-devel@lists.01.org
Cc: Paulo Alcantara <pca...@zytor.com>; Kinney, Michael D
<michael.d.kin...@intel.com>; Gao, Liming <liming@intel.com>; Laszlo
Ersek <ler...@redhat.com>; Ni, Ruiyu <ruiyu...@intel.com>; Zeng, Star
<star.z...@intel.com>; Yao, Jiewen <jiewen@intel.com>
Subject: [PATCH v2 0/3] UDF partition driver fix

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=707

Hi,

This patchset fixes a bug in Partition driver that UDF partitions occupied the
entire disk space instead of using LVD space only.

BTW, I've only tested it under OVMF and built it with GCC only. That would
be appreciable if someone could build with other toolchains and see if this
doesn't break.

I used a Windows 10 ISO image with UdfDxe disabled and enabled. The `map
-r` output seemed OK. No breakage when booting an OS off an ElTorito
partition from an UDF bridge disk.

v1->v2:
  - Followed Laszlo's suggestions to submit a proper patchset. Thanks!
  - As I'm still waiting for Ruiyu and Star to test this fix, I took
advantage of it and did some code cleanups :-)

Repo:   https://github.com/pcacjr/edk2.git
Branch: udf-partition-fix-v2

Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Liming Gao <liming@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Jiewen Yao <jiewen....@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Reported-by: Ruiyu Ni <ruiyu...@intel.com>
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---

Paulo Alcantara (3):
   MdePkg: Add UDF volume structure definitions
   MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
   MdeModulePkg/UdfDxe: Rework driver to support PartitionDxe changes

  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c| 323
+++-
  MdeModulePkg/Universal/Disk/UdfDxe/File.c |  13 +-
  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 515

  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c  |   7 -
  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  |  88 +---
  MdePkg/Include/IndustryStandard/Udf.h |  63 +++
  6 files changed, 566 insertions(+), 443 deletions(-)

--
2.11.0




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


Re: [edk2] [PATCH v2 3/3] MdeModulePkg/UdfDxe: Rework driver to support PartitionDxe changes

2017-09-18 Thread Paulo Alcantara



On 9/17/2017 10:00 PM, Ni, Ruiyu wrote:

Paulo,
With the change in partition driver, I suppose UdfDxe driver
only needs to take care of area covered by the partition descriptor.
But why StartMainVolumeDescriptorSequence() still reads
LVD, TD, and PD?


We still need the LVD again for a few reasons:

1. GetVolumeSize() needs to read LVID (Logical Volume Integrity 
Descriptor), which is located in LVD, in order to calculate free and 
used volume space.

2. To find FSD (File Set Descriptor), where the root directory is located.
3. To know which Partition Descriptor to use based on partition number 
from LVD->PartitionMaps field. I know UDF 2.60 spec says that there 
should be only one Partition Descriptor that covers the entire space of 
a single LVD, but it's good to make sure we're reading it correctly.


TD descriptor is used to know when stopping the Volume Descriptor 
Sequence and then we don't need to read all ExtentAd->ExtentLength 
blocks unnecessarily.


Thanks,
Paulo



I thought the UdfDxe driver's logic can be simplified a lot.
There should be no duplicated logic in Partition driver and udf driver.

Can you explain more?

Thanks/Ray


-Original Message-
From: Paulo Alcantara [mailto:pca...@zytor.com]
Sent: Sunday, September 17, 2017 9:13 PM
To: edk2-devel@lists.01.org
Cc: Paulo Alcantara <pca...@zytor.com>; Dong, Eric <eric.d...@intel.com>;
Ni, Ruiyu <ruiyu...@intel.com>; Zeng, Star <star.z...@intel.com>; Laszlo
Ersek <ler...@redhat.com>
Subject: [PATCH v2 3/3] MdeModulePkg/UdfDxe: Rework driver to support
PartitionDxe changes

This patch reworks the driver to support Partition driver changes.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Paulo Alcantara <pca...@zytor.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
  MdeModulePkg/Universal/Disk/UdfDxe/File.c |  13 +-
  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 515

  MdeModulePkg/Universal/Disk/UdfDxe/Udf.c  |   7 -
  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  |  88 +---
  4 files changed, 204 insertions(+), 419 deletions(-)

diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
index 01361141bb..f2c62967e8 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
@@ -100,6 +100,7 @@ UdfOpenVolume (
  >Volume,
  >Root
  );
+  ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
  goto Error_Find_Root_Dir;
}
@@ -131,7 +132,6 @@ Error_Alloc_Priv_File_Data:
CleanupFileInformation (>Root);

  Error_Find_Root_Dir:
-  CleanupVolumeInformation (>Volume);

  Error_Read_Udf_Volume:
  Error_Invalid_Params:
@@ -528,7 +528,6 @@ UdfClose (
EFI_TPL OldTpl;
EFI_STATUS  Status;
PRIVATE_UDF_FILE_DATA   *PrivFileData;
-  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;

OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

@@ -541,8 +540,6 @@ UdfClose (

PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);

-  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData-

SimpleFs);

-
if (!PrivFileData->IsRootDirectory) {
  CleanupFileInformation (>File);

@@ -551,10 +548,6 @@ UdfClose (
  }
}

-  if (--PrivFsData->OpenFiles == 0) {
-CleanupVolumeInformation (>Volume);
-  }
-
FreePool ((VOID *)PrivFileData);

  Exit:
@@ -787,7 +780,7 @@ UdfGetInfo (
} else if (CompareGuid (InformationType, )) {
  String = VolumeLabel;

-FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
+FileSetDesc = >Volume.FileSetDesc;

  OstaCompressed = >LogicalVolumeIdentifier[0];

@@ -846,7 +839,7 @@ UdfGetInfo (
  FileSystemInfo->Size= FileSystemInfoLength;
  FileSystemInfo->ReadOnly= TRUE;
  FileSystemInfo->BlockSize   =
-  LV_BLOCK_SIZE (>Volume, UDF_DEFAULT_LV_NUM);
+  PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
  FileSystemInfo->VolumeSize  = VolumeSize;
  FileSystemInfo->FreeSpace   = FreeSpaceSize;

diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
index 4609580b30..63b643e60a 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
@@ -60,154 +60,111 @@ FindAnchorVolumeDescriptorPointer (

  EFI_STATUS
  StartMainVolumeDescriptorSequence (
-  IN   EFI_BLOCK_IO_PROTOCOL *BlockIo,
-  IN   EFI_DISK_IO_PROTOCOL  *DiskIo,
-  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
-  OUT  UDF_VOLUME_INFO   *Volume
+  IN   EFI_BLOCK_IO

Re: [edk2] [PATCH v2 2/3] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition

2017-09-18 Thread Paulo Alcantara

Hi,

On 9/17/2017 9:54 PM, Ni, Ruiyu wrote:

Paulo,
Several comments:
1. Can below logic be removed in PartitionDxe/Udf.c?
while (!IsDevicePathEnd (DevicePathNode)) {
 //
 // Do not allow checking for UDF file systems in CDROM "El Torito"
 // partitions, and skip duplicate installation of UDF file system child
 // nodes.
 //
 if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH) {
   if (DevicePathSubType (DevicePathNode) == MEDIA_CDROM_DP) {
 return EFI_NOT_FOUND;
   }
   if (DevicePathSubType (DevicePathNode) == MEDIA_VENDOR_DP) {
 VendorDefinedGuid = (EFI_GUID *)((UINTN)DevicePathNode +
  OFFSET_OF (VENDOR_DEVICE_PATH, Guid));
 if (CompareGuid (VendorDefinedGuid, )) {
   return EFI_NOT_FOUND;
 }
   }
 }
 //
 // Try next device path node
 //
 DevicePathNode = NextDevicePathNode (DevicePathNode);
   }


I think it's no longer necessary, so I'll remove it.



2. Can you add function header comments for the newly added functions?


Sure.



3. Change the consuming code of IS_UDF_XXX macro after patch #1 is changed.


ACK.



4. Perhaps to add more checks for these numbers read from the UDF CDROM.
As Jiewen mentioned in another mail, secure code needs to validate all external 
inputs.
We shouldn't assume the UDF CDROM is a well-formatted CDROM.
A hacker may create a UDF CDROM to hack the system by using mechanism like
buffer overflow, integer overflow, etc.


OK, when we start the Main Volume Descriptor Sequence (MVDS), we rely on 
"ExtentAd->ExtentLocation" to know the LBA
where to start the sequence, and on "ExtentAd->ExtentLength" to know 
many LBAs the sequence has. We only care about
LVD, PD and TD descriptors. We currently check whether a TD descriptor 
exists, or the search exceed ExtentAd->ExtentLength blocks
to determine when stopping the sequence. That doesn't seem to be safe 
enough, but here are some thoughts:


a. "ExtentAd->ExtentLength" may point to a bad value. If it's greater 
than or equal to BlockIo->Media->LastBlock, and there is no
TD descriptor, we'll have to walk the entire disk and there will too 
much I/O overhead and then impacting bootup. Obviously,
when it's greater than LastBlock, DiksIo->ReadDisk() should not allow to 
read a non-existent LBA and then return

EFI_INVALID_PARAMETER, as per UEFI spec.

b. "ExtentAd->ExtentLocation" might point to a invalid LBA, although 
DiskIo->ReadDisk() would not allow it.


So, it's time to look at UDF 2.60 spec again:

> Volume Descriptor Sequence Extent
>
> Both the main and reserve volume descriptor sequence extents
> shall each have a minimum length of 16 logical sectors. The VDS
> Extent may be terminated by the extent length.

It doesn't tell us either a limit of logical blocks, or a maximum number.

Next:

> 6.9.2.3 Step 3. Volume Descriptor Sequence
> Read logical sectors:
> MVDS_Location through MVDS_Location + (MVDS_Length - 1) / SectorSize
> ...

MVDS_Length == ExtentAd->ExtentLength, so still insufficient.

Next:

> The data located in bytes 0-3 and 5 of the Anchor Volume Descriptor 
Pointer may be
> used for format verification if desired. Verifying the Tag Checksum 
in byte 4 and
> Descriptor CRC in bytes 8-11 are good additional verifications to 
perform.

> MVDS_Location and MVDS_Length are read from this structure.

Seems like a great check prior to reading ExtentAd->ExtentLocation and 
ExtentAd->ExtentLength contents. Would that be sufficient to you?


I haven't found a way to limit the number of blocks a Volume Descriptor 
Sequence might have.


Thanks,
Paulo




Thanks/Ray


-Original Message-----
From: Paulo Alcantara [mailto:pca...@zytor.com]
Sent: Sunday, September 17, 2017 9:13 PM
To: edk2-devel@lists.01.org
Cc: Paulo Alcantara <pca...@zytor.com>; Dong, Eric <eric.d...@intel.com>;
Ni, Ruiyu <ruiyu...@intel.com>; Zeng, Star <star.z...@intel.com>; Laszlo
Ersek <ler...@redhat.com>
Subject: [PATCH v2 2/3] MdeModulePkg/PartitionDxe: Fix creation of UDF
logical partition

Do not use entire block device size for the UDF logical partition, instead
reserve the appropriate space (LVD space) for it.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Reported-by: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c | 323
++--
  1 file changed, 299 insertions(+), 24 deletions(-)

diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
index 7856b5dfc1..3e84882922 100644
--- a/MdeModulePkg/Universal/D

Re: [edk2] [PATCH v2 1/3] MdePkg: Add UDF volume structure definitions

2017-09-18 Thread Paulo Alcantara

Hi,

On 9/17/2017 9:42 PM, Ni, Ruiyu wrote:

Continue reading the patch #2, I think we can change IS_PD to:
#define IS_UDF_PD(Tag) ((Tag)->TagIdentifier == 5)

Using the above way, we can avoid caller to supply an invalid buffer.


Good point. I'll fix it.

Thanks!
Paulo



Thanks/Ray


-Original Message-
From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Ni,
Ruiyu
Sent: Monday, September 18, 2017 8:29 AM
To: Paulo Alcantara <pca...@zytor.com>; edk2-devel@lists.01.org
Cc: Kinney, Michael D <michael.d.kin...@intel.com>; Laszlo Ersek
<ler...@redhat.com>; Gao, Liming <liming@intel.com>
Subject: Re: [edk2] [PATCH v2 1/3] MdePkg: Add UDF volume structure
definitions

#define _GET_TAG_ID(_Pointer) \
   (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier)

#define IS_PD(_Pointer) \
   ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 5))
#define IS_LVD(_Pointer) \
   ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 6))
#define IS_TD(_Pointer) \
   ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 8))

#define IS_AVDP(_Pointer) \
   ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 2))

Paulo,
If you take a look at Pci22.h in the same directory, all macros are started
as "IS_PCI_".
How about changing the above IS_xxx to IS_UDF_xxx?
Shall we change AVDP to AVD, following the same naming style as PD, LVD
and TD?
How about changing _Pointer to _Tag or DescriptorTag?


Thanks/Ray


-Original Message-
From: Paulo Alcantara [mailto:pca...@zytor.com]
Sent: Sunday, September 17, 2017 9:13 PM
To: edk2-devel@lists.01.org
Cc: Paulo Alcantara <pca...@zytor.com>; Kinney, Michael D
<michael.d.kin...@intel.com>; Gao, Liming <liming@intel.com>;

Laszlo

Ersek <ler...@redhat.com>; Ni, Ruiyu <ruiyu...@intel.com>
Subject: [PATCH v2 1/3] MdePkg: Add UDF volume structure definitions

This patch adds a fewe more UDF structures in order to detect Logical
Volume and Partition descriptors during Main Volume Descriptor Sequence
in Partition driver.

Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Liming Gao <liming@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
  MdePkg/Include/IndustryStandard/Udf.h | 63 
  1 file changed, 63 insertions(+)

diff --git a/MdePkg/Include/IndustryStandard/Udf.h
b/MdePkg/Include/IndustryStandard/Udf.h
index 0febb4bcda..6cc42f8543 100644
--- a/MdePkg/Include/IndustryStandard/Udf.h
+++ b/MdePkg/Include/IndustryStandard/Udf.h
@@ -27,9 +27,19 @@
  #define _GET_TAG_ID(_Pointer) \
(((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier)

+#define IS_PD(_Pointer) \
+  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 5)) #define IS_LVD(_Pointer) \
+  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 6)) #define IS_TD(_Pointer) \
+  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 8))
+
  #define IS_AVDP(_Pointer) \
((BOOLEAN)(_GET_TAG_ID (_Pointer) == 2))

+#define LV_UDF_REVISION(_Lv) \
+  *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix
+
  #pragma pack(1)

  typedef struct {
@@ -55,6 +65,59 @@ typedef struct {
UINT8   Reserved[480];
  } UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER;

+typedef struct {
+  UINT8   CharacterSetType;
+  UINT8   CharacterSetInfo[63];
+} UDF_CHAR_SPEC;
+
+typedef struct {
+  UINT8   Flags;
+  UINT8   Identifier[23];
+  UINT8   IdentifierSuffix[8];
+} UDF_ENTITY_ID;
+
+typedef struct {
+  UINT32LogicalBlockNumber;
+  UINT16PartitionReferenceNumber;
+} UDF_LB_ADDR;
+
+typedef struct {
+  UINT32   ExtentLength;
+  UDF_LB_ADDR  ExtentLocation;
+  UINT8ImplementationUse[6];
+} UDF_LONG_ALLOCATION_DESCRIPTOR;
+
+typedef struct {
+  UDF_DESCRIPTOR_TAG  DescriptorTag;
+  UINT32  VolumeDescriptorSequenceNumber;
+  UDF_CHAR_SPEC   DescriptorCharacterSet;
+  UINT8   LogicalVolumeIdentifier[128];
+  UINT32  LogicalBlockSize;
+  UDF_ENTITY_ID   DomainIdentifier;
+  UDF_LONG_ALLOCATION_DESCRIPTOR  LogicalVolumeContentsUse;
+  UINT32  MapTableLength;
+  UINT32  NumberOfPartitionMaps;
+  UDF_ENTITY_ID   ImplementationIdentifier;
+  UINT8   ImplementationUse[128];
+  UDF_EXTENT_AD   IntegritySequenceExtent;
+  UINT8   PartitionMaps[6];
+} UDF_LOGICAL_VOLUME_DESCRIPTOR;
+
+typedef struct {
+  UDF_DESCRIPTOR_TAG DescriptorTag;
+  UINT32 VolumeDescriptorSequenceNumber;
+  UINT16 PartitionFlags;
+  UINT16 PartitionNumber;
+  UDF_ENTITY_ID  PartitionContents;
+  UINT8  PartitionContentsU

Re: [edk2] [PATCH v2 1/3] MdePkg: Add UDF volume structure definitions

2017-09-18 Thread Paulo Alcantara

Hi Ruiyu,

On 9/17/2017 9:28 PM, Ni, Ruiyu wrote:

#define _GET_TAG_ID(_Pointer) \
   (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier)

#define IS_PD(_Pointer) \
   ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 5))
#define IS_LVD(_Pointer) \
   ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 6))
#define IS_TD(_Pointer) \
   ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 8))

#define IS_AVDP(_Pointer) \
   ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 2))

Paulo,
If you take a look at Pci22.h in the same directory, all macros are started
as "IS_PCI_".
How about changing the above IS_xxx to IS_UDF_xxx?


Looks good to me. I'll change them.


Shall we change AVDP to AVD, following the same naming style as PD, LVD and TD?


There is no "Anchor Volume Descriptor" but "Anchor Volume Descriptor 
Pointer", so we still need to keep 'P'.



How about changing _Pointer to _Tag or DescriptorTag?


I will change it to _Tag. _Pointer is really a bad name. Thanks! :-)

Paulo




Thanks/Ray


-Original Message-
From: Paulo Alcantara [mailto:pca...@zytor.com]
Sent: Sunday, September 17, 2017 9:13 PM
To: edk2-devel@lists.01.org
Cc: Paulo Alcantara <pca...@zytor.com>; Kinney, Michael D
<michael.d.kin...@intel.com>; Gao, Liming <liming@intel.com>; Laszlo
Ersek <ler...@redhat.com>; Ni, Ruiyu <ruiyu...@intel.com>
Subject: [PATCH v2 1/3] MdePkg: Add UDF volume structure definitions

This patch adds a fewe more UDF structures in order to detect Logical
Volume and Partition descriptors during Main Volume Descriptor Sequence
in Partition driver.

Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Liming Gao <liming@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
  MdePkg/Include/IndustryStandard/Udf.h | 63 
  1 file changed, 63 insertions(+)

diff --git a/MdePkg/Include/IndustryStandard/Udf.h
b/MdePkg/Include/IndustryStandard/Udf.h
index 0febb4bcda..6cc42f8543 100644
--- a/MdePkg/Include/IndustryStandard/Udf.h
+++ b/MdePkg/Include/IndustryStandard/Udf.h
@@ -27,9 +27,19 @@
  #define _GET_TAG_ID(_Pointer) \
(((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier)

+#define IS_PD(_Pointer) \
+  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 5)) #define IS_LVD(_Pointer) \
+  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 6)) #define IS_TD(_Pointer) \
+  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 8))
+
  #define IS_AVDP(_Pointer) \
((BOOLEAN)(_GET_TAG_ID (_Pointer) == 2))

+#define LV_UDF_REVISION(_Lv) \
+  *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix
+
  #pragma pack(1)

  typedef struct {
@@ -55,6 +65,59 @@ typedef struct {
UINT8   Reserved[480];
  } UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER;

+typedef struct {
+  UINT8   CharacterSetType;
+  UINT8   CharacterSetInfo[63];
+} UDF_CHAR_SPEC;
+
+typedef struct {
+  UINT8   Flags;
+  UINT8   Identifier[23];
+  UINT8   IdentifierSuffix[8];
+} UDF_ENTITY_ID;
+
+typedef struct {
+  UINT32LogicalBlockNumber;
+  UINT16PartitionReferenceNumber;
+} UDF_LB_ADDR;
+
+typedef struct {
+  UINT32   ExtentLength;
+  UDF_LB_ADDR  ExtentLocation;
+  UINT8ImplementationUse[6];
+} UDF_LONG_ALLOCATION_DESCRIPTOR;
+
+typedef struct {
+  UDF_DESCRIPTOR_TAG  DescriptorTag;
+  UINT32  VolumeDescriptorSequenceNumber;
+  UDF_CHAR_SPEC   DescriptorCharacterSet;
+  UINT8   LogicalVolumeIdentifier[128];
+  UINT32  LogicalBlockSize;
+  UDF_ENTITY_ID   DomainIdentifier;
+  UDF_LONG_ALLOCATION_DESCRIPTOR  LogicalVolumeContentsUse;
+  UINT32  MapTableLength;
+  UINT32  NumberOfPartitionMaps;
+  UDF_ENTITY_ID   ImplementationIdentifier;
+  UINT8   ImplementationUse[128];
+  UDF_EXTENT_AD   IntegritySequenceExtent;
+  UINT8   PartitionMaps[6];
+} UDF_LOGICAL_VOLUME_DESCRIPTOR;
+
+typedef struct {
+  UDF_DESCRIPTOR_TAG DescriptorTag;
+  UINT32 VolumeDescriptorSequenceNumber;
+  UINT16 PartitionFlags;
+  UINT16 PartitionNumber;
+  UDF_ENTITY_ID  PartitionContents;
+  UINT8  PartitionContentsUse[128];
+  UINT32 AccessType;
+  UINT32 PartitionStartingLocation;
+  UINT32 PartitionLength;
+  UDF_ENTITY_ID  ImplementationIdentifier;
+  UINT8  ImplementationUse[128];
+  UINT8  Reserved[156];
+} UDF_PARTITION_DESCRIPTOR;
+
  #pragma pack()

  #endif
--
2.11.0




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


Re: [edk2] [PATCH 0/3] UDF partition driver fix

2017-09-17 Thread Paulo Alcantara
 and check 
the remaining unsupported features.




I ask this, because we want to understand how we declare the support 
level of this UEFI UDF driver. If we just say we support UDF, then naive 
people may believe we support everything. J

Yes :-)



3)Which compatibility test has been done?

I am sorry that I cannot find the first version patch. I fund you 
mentioned Win10 ISO is tried in V2. Any more?


We would like to know how many existing OS installation CDROM (or any 
other CDROM) has been tried. Such as Linux (RedHat, Ubuntu, Suse, etc), 
or Windows (Win7, Win8, Win10)?


Currently, I'm only using a Windows 10 Enterprise ISO image. But I also 
tested it with Windows 8 ISO images as well (in 3 years ago :-) )


Like I said, the Fedora ISO image I have didn't serve because it has no 
UDF file system. Wondering if any other Linux ISO image contains an UDF 
file system.




The more detail, the better. May a list.

4)The last but not least important, which negative test (security test) 
has been done?


None.



Have you run some fuzzing test?


No.



Have you tried a mal-format UDF disc? For example, with bad offset or 
length?


No.



Have you test the integer overflow / buffer over flow handing in the code?


No.



NOTE: we should not use ASSERT to handle such error.

When I review the code, I found below:

     Status = ReadFileData (

   BlockIo,

   DiskIo,

   Volume,

   Parent,

   PrivFileData->FileSize,

   >FilePosition,

   Buffer,

   

   );

     ASSERT (BufferSizeUint64 <= MAX_UINTN);

     *BufferSize = (UINTN)BufferSizeUint64;

I am not sure if we can use ASSERT (BufferSizeUint64 <= MAX_UINTN);

Can a malicious user construct a bad UDF and make BufferSizeUint64 > 
MAX_UINTN?


Does it might happen? Or never happen?


Laszlo already answered :-)



We documented Appendix B - EDKII code review top 5 in 
https://github.com/tianocore-docs/Docs/raw/master/White_Papers/A_Tour_Beyond_BIOS_Security_Design_Guide_in_EDK_II.pdf


3 of them are matched in these partition and file system drivers. I 
quote below:


===

*If the code consumes input from an untrusted source or region,*

Ensure that the input is rigorously and adequately validated.

*Verify buffer overflow is handled. Avoid integer overflow.*

Try to use subtraction instead of addition and division instead of 
multiplication.


*Verify that ASSERT is used properly.*

ASSERT is used to catch conditions that should /never /happen. If 
something /might /happen, use error handling instead. We can use both 
ASSERT and error handling to facilitate debugging – ASSERT allows for 
earlier detection and isolation of several classes of issues. [McConnell]


===

It is just a reminder. If you are already following that, it will be 
great. Please let us now.


No, I wasn't. But I will make sure to follow that rigorously next time. 
Very good info. Thanks!




I take a glance of UDF 2.6 specification, but I do not have chance to 
read all content at this moment.


If I asked some stupid question , please feel free to correct me.


Not that I know of. I'm also not an UDF expert. I do enjoy writing 
read-only fs drivers in my free time, that is. :-)




All in all, we hope to understand the current quality level of the UDF 
partition support and UDF file system.


Sure. You're completely right by asking such questions. If we really 
want to make proper use of it, the more understanding, testing, 
documentation, the better. Thank you very much for all the questions and 
suggestions. Really appreciate it.


I hope you guys (+ community) to test this implementation, report bugs, 
etc. as much as possible. I wish I could work on it full time and give 
better support for you guys. Unfortunately I can't. But I'll do my best 
in giving you some support.


Thanks!
Paulo



If you can help to provide the detail, it may help us to evaluate.

Thank you

Yao Jiewen

*From:*edk2-devel [mailto:edk2-devel-boun...@lists.01.org] *On Behalf Of 
*Laszlo Ersek

*Sent:* Sunday, September 17, 2017 6:17 AM
*To:* Paulo Alcantara <pca...@zytor.com>
*Cc:* Ni, Ruiyu <ruiyu...@intel.com>; Dong, Eric <eric.d...@intel.com>; 
edk2-devel@lists.01.org; Gao, Liming <liming@intel.com>; Kinney, 
Michael D <michael.d.kin...@intel.com>; Zeng, Star <star.z...@intel.com>

*Subject:* Re: [edk2] [PATCH 0/3] UDF partition driver fix

Hi Paulo,

On 09/16/17 23:36, Paulo Alcantara wrote:

 This series fixes an UDF issue with Partition driver as discussed in ML:

https://lists.01.org/pipermail/edk2-devel/2017-September/014694.html

 Thanks!
 Paulo

 Repo:   https://github.com/pcacjr/edk2.git
 Branch: udf-partition-fix

 Paulo Alcantara (3):
   MdePkg: Add UDF volume structure definitions
   MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
   MdeModulePkg/UdfDxe: Rework driver to support PartitionDxe changes

  MdeModulePkg/Univers

[edk2] [PATCH v2 2/3] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition

2017-09-17 Thread Paulo Alcantara
Do not use entire block device size for the UDF logical partition,
instead reserve the appropriate space (LVD space) for it.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Reported-by: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
 MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c | 323 ++--
 1 file changed, 299 insertions(+), 24 deletions(-)

diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c 
b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
index 7856b5dfc1..3e84882922 100644
--- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
+++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
@@ -84,24 +84,8 @@ FindAnchorVolumeDescriptorPointer (
   return EFI_VOLUME_CORRUPTED;
 }
 
-/**
-  Check if block device supports a valid UDF file system as specified by OSTA
-  Universal Disk Format Specification 2.60.
-
-  @param[in]   BlockIo  BlockIo interface.
-  @param[in]   DiskIo   DiskIo interface.
-
-  @retval EFI_SUCCESS  UDF file system found.
-  @retval EFI_UNSUPPORTED  UDF file system not found.
-  @retval EFI_NO_MEDIA The device has no media.
-  @retval EFI_DEVICE_ERROR The device reported an error.
-  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
-  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to lack of
-   resources.
-
-**/
 EFI_STATUS
-SupportUdfFileSystem (
+FindUdfVolumeIdentifiers (
   IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
   IN EFI_DISK_IO_PROTOCOL   *DiskIo
   )
@@ -111,7 +95,6 @@ SupportUdfFileSystem (
   UINT64EndDiskOffset;
   CDROM_VOLUME_DESCRIPTOR   VolDescriptor;
   CDROM_VOLUME_DESCRIPTOR   TerminatingVolDescriptor;
-  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
 
   ZeroMem ((VOID *), sizeof 
(CDROM_VOLUME_DESCRIPTOR));
 
@@ -207,12 +190,302 @@ SupportUdfFileSystem (
 return EFI_UNSUPPORTED;
   }
 
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetPartitionNumber (
+  IN   UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc,
+  OUT  UINT16 *PartitionNum
+  )
+{
+  EFI_STATUS  Status;
+  UDF_LONG_ALLOCATION_DESCRIPTOR  *LongAd;
+
+  Status = EFI_SUCCESS;
+
+  switch (LV_UDF_REVISION (LogicalVolDesc)) {
+  case 0x0102:
+//
+// UDF 1.20 only supports Type 1 Partition
+//
+*PartitionNum = *(UINT16 *)((UINTN)>PartitionMaps[4]);
+break;
+  case 0x0150:
+//
+// Ensure Type 1 Partition map
+//
+ASSERT (LogicalVolDesc->PartitionMaps[0] == 1 &&
+LogicalVolDesc->PartitionMaps[1] == 6);
+*PartitionNum = *(UINT16 *)((UINTN)>PartitionMaps[4]);
+break;
+  case 0x0260:
+LongAd = >LogicalVolumeContentsUse;
+*PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
+break;
+  default:
+//
+// Unhandled UDF revision
+//
+Status = EFI_VOLUME_CORRUPTED;
+break;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+FindLogicalVolumeLocation (
+  IN   EFI_BLOCK_IO_PROTOCOL *BlockIo,
+  IN   EFI_DISK_IO_PROTOCOL  *DiskIo,
+  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
+  OUT  UINT64*MainVdsStartLsn,
+  OUT  UINT64*LogicalVolEndLsn
+  )
+{
+  EFI_STATUS Status;
+  UINT32 BlockSize;
+  EFI_LBALastBlock;
+  UDF_EXTENT_AD  *ExtentAd;
+  UINT64 StartingLsn;
+  UINT64 EndingLsn;
+  VOID   *Buffer;
+  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
+  UDF_PARTITION_DESCRIPTOR   *PartitionDesc;
+  UINT64 GuardMainVdsStartLsn;
+  UINT16 PartitionNum;
+
+  BlockSize = BlockIo->Media->BlockSize;
+  LastBlock = BlockIo->Media->LastBlock;
+  ExtentAd  = >MainVolumeDescriptorSequenceExtent;
+  StartingLsn   = (UINT64)ExtentAd->ExtentLocation;
+  EndingLsn =
+StartingLsn + DivU64x32 ((UINT64)ExtentAd->ExtentLength, BlockSize);
+
+  LogicalVolDesc= NULL;
+  PartitionDesc = NULL;
+  GuardMainVdsStartLsn  = StartingLsn;
+
+  //
+  // Allocate buffer for reading disk blocks
+  //
+  Buffer = AllocateZeroPool (BlockSize);
+  if (Buffer == NULL) {
+return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = EFI_VOLUME_CORRUPTED;
+
+  //
+  // As per UDF 2.60 specification:
+  //
+  // There shall be exactly one prevailing Logical Volume Descriptor
+  // recorded per Volume Set.
+  //
+  // Start Main Volume Descriptor Sequence and find Logical Volume Descriptor
+  //
+  while (StartingLsn <

[edk2] [PATCH v2 0/3] UDF partition driver fix

2017-09-17 Thread Paulo Alcantara
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=707

Hi,

This patchset fixes a bug in Partition driver that UDF partitions
occupied the entire disk space instead of using LVD space only.

BTW, I've only tested it under OVMF and built it with GCC only. That
would be appreciable if someone could build with other toolchains and
see if this doesn't break.

I used a Windows 10 ISO image with UdfDxe disabled and enabled. The
`map -r` output seemed OK. No breakage when booting an OS off an
ElTorito partition from an UDF bridge disk.

v1->v2:
 - Followed Laszlo's suggestions to submit a proper patchset. Thanks!
 - As I'm still waiting for Ruiyu and Star to test this fix, I took
   advantage of it and did some code cleanups :-)

Repo:   https://github.com/pcacjr/edk2.git
Branch: udf-partition-fix-v2

Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Liming Gao <liming@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Jiewen Yao <jiewen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Reported-by: Ruiyu Ni <ruiyu...@intel.com>
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---

Paulo Alcantara (3):
  MdePkg: Add UDF volume structure definitions
  MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
  MdeModulePkg/UdfDxe: Rework driver to support PartitionDxe changes

 MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c| 323 +++-
 MdeModulePkg/Universal/Disk/UdfDxe/File.c |  13 +-
 MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 515 

 MdeModulePkg/Universal/Disk/UdfDxe/Udf.c  |   7 -
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  |  88 +---
 MdePkg/Include/IndustryStandard/Udf.h |  63 +++
 6 files changed, 566 insertions(+), 443 deletions(-)

-- 
2.11.0

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


[edk2] [PATCH v2 3/3] MdeModulePkg/UdfDxe: Rework driver to support PartitionDxe changes

2017-09-17 Thread Paulo Alcantara
This patch reworks the driver to support Partition driver changes.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Paulo Alcantara <pca...@zytor.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
 MdeModulePkg/Universal/Disk/UdfDxe/File.c |  13 +-
 MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 515 

 MdeModulePkg/Universal/Disk/UdfDxe/Udf.c  |   7 -
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  |  88 +---
 4 files changed, 204 insertions(+), 419 deletions(-)

diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c 
b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
index 01361141bb..f2c62967e8 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
@@ -100,6 +100,7 @@ UdfOpenVolume (
 >Volume,
 >Root
 );
+  ASSERT_EFI_ERROR (Status);
   if (EFI_ERROR (Status)) {
 goto Error_Find_Root_Dir;
   }
@@ -131,7 +132,6 @@ Error_Alloc_Priv_File_Data:
   CleanupFileInformation (>Root);
 
 Error_Find_Root_Dir:
-  CleanupVolumeInformation (>Volume);
 
 Error_Read_Udf_Volume:
 Error_Invalid_Params:
@@ -528,7 +528,6 @@ UdfClose (
   EFI_TPL OldTpl;
   EFI_STATUS  Status;
   PRIVATE_UDF_FILE_DATA   *PrivFileData;
-  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;
 
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
 
@@ -541,8 +540,6 @@ UdfClose (
 
   PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
 
-  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData->SimpleFs);
-
   if (!PrivFileData->IsRootDirectory) {
 CleanupFileInformation (>File);
 
@@ -551,10 +548,6 @@ UdfClose (
 }
   }
 
-  if (--PrivFsData->OpenFiles == 0) {
-CleanupVolumeInformation (>Volume);
-  }
-
   FreePool ((VOID *)PrivFileData);
 
 Exit:
@@ -787,7 +780,7 @@ UdfGetInfo (
   } else if (CompareGuid (InformationType, )) {
 String = VolumeLabel;
 
-FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
+FileSetDesc = >Volume.FileSetDesc;
 
 OstaCompressed = >LogicalVolumeIdentifier[0];
 
@@ -846,7 +839,7 @@ UdfGetInfo (
 FileSystemInfo->Size= FileSystemInfoLength;
 FileSystemInfo->ReadOnly= TRUE;
 FileSystemInfo->BlockSize   =
-  LV_BLOCK_SIZE (>Volume, UDF_DEFAULT_LV_NUM);
+  PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
 FileSystemInfo->VolumeSize  = VolumeSize;
 FileSystemInfo->FreeSpace   = FreeSpaceSize;
 
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c 
b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
index 4609580b30..63b643e60a 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
@@ -60,154 +60,111 @@ FindAnchorVolumeDescriptorPointer (
 
 EFI_STATUS
 StartMainVolumeDescriptorSequence (
-  IN   EFI_BLOCK_IO_PROTOCOL *BlockIo,
-  IN   EFI_DISK_IO_PROTOCOL  *DiskIo,
-  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
-  OUT  UDF_VOLUME_INFO   *Volume
+  IN   EFI_BLOCK_IO_PROTOCOL*BlockIo,
+  IN   EFI_DISK_IO_PROTOCOL *DiskIo,
+  OUT  UDF_VOLUME_INFO  *Volume
   )
 {
-  EFI_STATUS Status;
-  UINT32 BlockSize;
-  UDF_EXTENT_AD  *ExtentAd;
-  UINT64 StartingLsn;
-  UINT64 EndingLsn;
-  VOID   *Buffer;
-  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
-  UDF_PARTITION_DESCRIPTOR   *PartitionDesc;
-  UINTN  Index;
-  UINT32 LogicalBlockSize;
+  EFI_STATUS  Status;
+  UINT32  BlockSize;
+  UINT64  BlockOffset;
+  VOID*Buffer;
+  UINT32  LogicalBlockSize;
+
+  BlockSize = BlockIo->Media->BlockSize;
 
   //
-  // We've already found an ADVP on the volume. It contains the extent
-  // (MainVolumeDescriptorSequenceExtent) where the Main Volume Descriptor
-  // Sequence starts. Therefore, we'll look for Logical Volume Descriptors and
-  // Partitions Descriptors and save them in memory, accordingly.
-  //
-  // Note also that each descriptor will be aligned on a block size (BlockSize)
-  // boundary, so we need to read one block at a time.
+  // Allocate buffer for reading disk blocks
   //
-  BlockSize= BlockIo->Media->BlockSize;
-  ExtentAd = >MainVolumeDescriptorSequenceExtent;
-  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;
-  EndingLsn= StartingLsn + DivU64x32 (
- (UINT64)ExtentAd->ExtentLength,
- BlockSize
- );
-
-  Volum

[edk2] [PATCH v2 1/3] MdePkg: Add UDF volume structure definitions

2017-09-17 Thread Paulo Alcantara
This patch adds a fewe more UDF structures in order to detect Logical
Volume and Partition descriptors during Main Volume Descriptor Sequence
in Partition driver.

Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Liming Gao <liming@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
 MdePkg/Include/IndustryStandard/Udf.h | 63 
 1 file changed, 63 insertions(+)

diff --git a/MdePkg/Include/IndustryStandard/Udf.h 
b/MdePkg/Include/IndustryStandard/Udf.h
index 0febb4bcda..6cc42f8543 100644
--- a/MdePkg/Include/IndustryStandard/Udf.h
+++ b/MdePkg/Include/IndustryStandard/Udf.h
@@ -27,9 +27,19 @@
 #define _GET_TAG_ID(_Pointer) \
   (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier)
 
+#define IS_PD(_Pointer) \
+  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 5))
+#define IS_LVD(_Pointer) \
+  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 6))
+#define IS_TD(_Pointer) \
+  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 8))
+
 #define IS_AVDP(_Pointer) \
   ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 2))
 
+#define LV_UDF_REVISION(_Lv) \
+  *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix
+
 #pragma pack(1)
 
 typedef struct {
@@ -55,6 +65,59 @@ typedef struct {
   UINT8   Reserved[480];
 } UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER;
 
+typedef struct {
+  UINT8   CharacterSetType;
+  UINT8   CharacterSetInfo[63];
+} UDF_CHAR_SPEC;
+
+typedef struct {
+  UINT8   Flags;
+  UINT8   Identifier[23];
+  UINT8   IdentifierSuffix[8];
+} UDF_ENTITY_ID;
+
+typedef struct {
+  UINT32LogicalBlockNumber;
+  UINT16PartitionReferenceNumber;
+} UDF_LB_ADDR;
+
+typedef struct {
+  UINT32   ExtentLength;
+  UDF_LB_ADDR  ExtentLocation;
+  UINT8ImplementationUse[6];
+} UDF_LONG_ALLOCATION_DESCRIPTOR;
+
+typedef struct {
+  UDF_DESCRIPTOR_TAG  DescriptorTag;
+  UINT32  VolumeDescriptorSequenceNumber;
+  UDF_CHAR_SPEC   DescriptorCharacterSet;
+  UINT8   LogicalVolumeIdentifier[128];
+  UINT32  LogicalBlockSize;
+  UDF_ENTITY_ID   DomainIdentifier;
+  UDF_LONG_ALLOCATION_DESCRIPTOR  LogicalVolumeContentsUse;
+  UINT32  MapTableLength;
+  UINT32  NumberOfPartitionMaps;
+  UDF_ENTITY_ID   ImplementationIdentifier;
+  UINT8   ImplementationUse[128];
+  UDF_EXTENT_AD   IntegritySequenceExtent;
+  UINT8   PartitionMaps[6];
+} UDF_LOGICAL_VOLUME_DESCRIPTOR;
+
+typedef struct {
+  UDF_DESCRIPTOR_TAG DescriptorTag;
+  UINT32 VolumeDescriptorSequenceNumber;
+  UINT16 PartitionFlags;
+  UINT16 PartitionNumber;
+  UDF_ENTITY_ID  PartitionContents;
+  UINT8  PartitionContentsUse[128];
+  UINT32 AccessType;
+  UINT32 PartitionStartingLocation;
+  UINT32 PartitionLength;
+  UDF_ENTITY_ID  ImplementationIdentifier;
+  UINT8  ImplementationUse[128];
+  UINT8  Reserved[156];
+} UDF_PARTITION_DESCRIPTOR;
+
 #pragma pack()
 
 #endif
-- 
2.11.0

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


[edk2] [PATCH 0/3] UDF partition driver fix

2017-09-16 Thread Paulo Alcantara
This series fixes an UDF issue with Partition driver as discussed in ML:

https://lists.01.org/pipermail/edk2-devel/2017-September/014694.html

Thanks!
Paulo

Repo:   https://github.com/pcacjr/edk2.git
Branch: udf-partition-fix

Paulo Alcantara (3):
  MdePkg: Add UDF volume structure definitions
  MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition
  MdeModulePkg/UdfDxe: Rework driver to support PartitionDxe changes

 MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c | 307 +++-
 MdeModulePkg/Universal/Disk/UdfDxe/File.c  |  13 +-
 .../Universal/Disk/UdfDxe/FileSystemOperations.c   | 525 -
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.c   |   7 -
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.h   |  88 +---
 MdePkg/Include/IndustryStandard/Udf.h  |  63 +++
 6 files changed, 560 insertions(+), 443 deletions(-)

-- 
2.11.0

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


[edk2] [PATCH 1/3] MdePkg: Add UDF volume structure definitions

2017-09-16 Thread Paulo Alcantara
This patch adds a fewe more UDF structures in order to detect Logical
Volume and Partition descriptors during Main Volume Descriptor Sequence
in Partition driver.

Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Liming Gao <liming@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
 MdePkg/Include/IndustryStandard/Udf.h | 63 +++
 1 file changed, 63 insertions(+)

diff --git a/MdePkg/Include/IndustryStandard/Udf.h 
b/MdePkg/Include/IndustryStandard/Udf.h
index 0febb4bcda..6cc42f8543 100644
--- a/MdePkg/Include/IndustryStandard/Udf.h
+++ b/MdePkg/Include/IndustryStandard/Udf.h
@@ -27,9 +27,19 @@
 #define _GET_TAG_ID(_Pointer) \
   (((UDF_DESCRIPTOR_TAG *)(_Pointer))->TagIdentifier)
 
+#define IS_PD(_Pointer) \
+  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 5))
+#define IS_LVD(_Pointer) \
+  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 6))
+#define IS_TD(_Pointer) \
+  ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 8))
+
 #define IS_AVDP(_Pointer) \
   ((BOOLEAN)(_GET_TAG_ID (_Pointer) == 2))
 
+#define LV_UDF_REVISION(_Lv) \
+  *(UINT16 *)(UINTN)(_Lv)->DomainIdentifier.IdentifierSuffix
+
 #pragma pack(1)
 
 typedef struct {
@@ -55,6 +65,59 @@ typedef struct {
   UINT8   Reserved[480];
 } UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER;
 
+typedef struct {
+  UINT8   CharacterSetType;
+  UINT8   CharacterSetInfo[63];
+} UDF_CHAR_SPEC;
+
+typedef struct {
+  UINT8   Flags;
+  UINT8   Identifier[23];
+  UINT8   IdentifierSuffix[8];
+} UDF_ENTITY_ID;
+
+typedef struct {
+  UINT32LogicalBlockNumber;
+  UINT16PartitionReferenceNumber;
+} UDF_LB_ADDR;
+
+typedef struct {
+  UINT32   ExtentLength;
+  UDF_LB_ADDR  ExtentLocation;
+  UINT8ImplementationUse[6];
+} UDF_LONG_ALLOCATION_DESCRIPTOR;
+
+typedef struct {
+  UDF_DESCRIPTOR_TAG  DescriptorTag;
+  UINT32  VolumeDescriptorSequenceNumber;
+  UDF_CHAR_SPEC   DescriptorCharacterSet;
+  UINT8   LogicalVolumeIdentifier[128];
+  UINT32  LogicalBlockSize;
+  UDF_ENTITY_ID   DomainIdentifier;
+  UDF_LONG_ALLOCATION_DESCRIPTOR  LogicalVolumeContentsUse;
+  UINT32  MapTableLength;
+  UINT32  NumberOfPartitionMaps;
+  UDF_ENTITY_ID   ImplementationIdentifier;
+  UINT8   ImplementationUse[128];
+  UDF_EXTENT_AD   IntegritySequenceExtent;
+  UINT8   PartitionMaps[6];
+} UDF_LOGICAL_VOLUME_DESCRIPTOR;
+
+typedef struct {
+  UDF_DESCRIPTOR_TAG DescriptorTag;
+  UINT32 VolumeDescriptorSequenceNumber;
+  UINT16 PartitionFlags;
+  UINT16 PartitionNumber;
+  UDF_ENTITY_ID  PartitionContents;
+  UINT8  PartitionContentsUse[128];
+  UINT32 AccessType;
+  UINT32 PartitionStartingLocation;
+  UINT32 PartitionLength;
+  UDF_ENTITY_ID  ImplementationIdentifier;
+  UINT8  ImplementationUse[128];
+  UINT8  Reserved[156];
+} UDF_PARTITION_DESCRIPTOR;
+
 #pragma pack()
 
 #endif
-- 
2.11.0

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


[edk2] [PATCH 2/3] MdeModulePkg/PartitionDxe: Fix creation of UDF logical partition

2017-09-16 Thread Paulo Alcantara
Do not use entire block device size for the UDF logical partition,
instead reserve the appropriate space (LVD space) for it.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Reported-by: Ruiyu Ni <ruiyu...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
 MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c | 307 +++--
 1 file changed, 283 insertions(+), 24 deletions(-)

diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c 
b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
index 7856b5dfc1..b00369ba6d 100644
--- a/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
+++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c
@@ -84,24 +84,8 @@ FindAnchorVolumeDescriptorPointer (
   return EFI_VOLUME_CORRUPTED;
 }
 
-/**
-  Check if block device supports a valid UDF file system as specified by OSTA
-  Universal Disk Format Specification 2.60.
-
-  @param[in]   BlockIo  BlockIo interface.
-  @param[in]   DiskIo   DiskIo interface.
-
-  @retval EFI_SUCCESS  UDF file system found.
-  @retval EFI_UNSUPPORTED  UDF file system not found.
-  @retval EFI_NO_MEDIA The device has no media.
-  @retval EFI_DEVICE_ERROR The device reported an error.
-  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
-  @retval EFI_OUT_OF_RESOURCES The scan was not successful due to lack of
-   resources.
-
-**/
 EFI_STATUS
-SupportUdfFileSystem (
+FindUdfVolumeIdentifiers (
   IN EFI_BLOCK_IO_PROTOCOL  *BlockIo,
   IN EFI_DISK_IO_PROTOCOL   *DiskIo
   )
@@ -111,7 +95,6 @@ SupportUdfFileSystem (
   UINT64EndDiskOffset;
   CDROM_VOLUME_DESCRIPTOR   VolDescriptor;
   CDROM_VOLUME_DESCRIPTOR   TerminatingVolDescriptor;
-  UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  AnchorPoint;
 
   ZeroMem ((VOID *), sizeof 
(CDROM_VOLUME_DESCRIPTOR));
 
@@ -207,12 +190,286 @@ SupportUdfFileSystem (
 return EFI_UNSUPPORTED;
   }
 
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetPartitionNumber (
+  IN   UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc,
+  OUT  UINT16 *PartitionNum
+  )
+{
+  EFI_STATUS  Status;
+  UDF_LONG_ALLOCATION_DESCRIPTOR  *LongAd;
+
+  Status = EFI_SUCCESS;
+
+  switch (LV_UDF_REVISION (LogicalVolDesc)) {
+  case 0x0102:
+//
+// UDF 1.20 only supports Type 1 Partition
+//
+*PartitionNum = *(UINT16 *)((UINTN)>PartitionMaps[4]);
+break;
+  case 0x0150:
+//
+// Ensure Type 1 Partition map
+//
+ASSERT (LogicalVolDesc->PartitionMaps[0] == 1 &&
+LogicalVolDesc->PartitionMaps[1] == 6);
+*PartitionNum = *(UINT16 *)((UINTN)>PartitionMaps[4]);
+break;
+  case 0x0260:
+LongAd = >LogicalVolumeContentsUse;
+*PartitionNum = LongAd->ExtentLocation.PartitionReferenceNumber;
+break;
+  default:
+//
+// Unhandled UDF revision
+//
+Status = EFI_VOLUME_CORRUPTED;
+break;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+FindLogicalVolumeLocation (
+  IN   EFI_BLOCK_IO_PROTOCOL *BlockIo,
+  IN   EFI_DISK_IO_PROTOCOL  *DiskIo,
+  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
+  OUT  UINT64*MainVdsStartLsn,
+  OUT  UINT64*LogicalVolEndLsn
+  )
+{
+  EFI_STATUS Status;
+  UINT32 BlockSize;
+  EFI_LBALastBlock;
+  UDF_EXTENT_AD  *ExtentAd;
+  UINT64 StartingLsn;
+  UINT64 EndingLsn;
+  VOID   *Buffer;
+  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
+  UDF_PARTITION_DESCRIPTOR   *PartitionDesc;
+  UINT64 GuardMainVdsStartLsn;
+  UINT16 PartitionNum;
+
+  BlockSize = BlockIo->Media->BlockSize;
+  LastBlock = BlockIo->Media->LastBlock;
+  ExtentAd  = >MainVolumeDescriptorSequenceExtent;
+  StartingLsn   = (UINT64)ExtentAd->ExtentLocation;
+  EndingLsn =
+StartingLsn + DivU64x32 ((UINT64)ExtentAd->ExtentLength, BlockSize);
+
+  LogicalVolDesc= NULL;
+  PartitionDesc = NULL;
+  GuardMainVdsStartLsn  = StartingLsn;
+
+  //
+  // Allocate buffer for reading disk blocks
+  //
+  Buffer = AllocateZeroPool (BlockSize);
+  if (Buffer == NULL) {
+return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = EFI_VOLUME_CORRUPTED;
+
+  //
+  // As per UDF 2.60 specification:
+  //
+  // There shall be exactly one prevailing Logical Volume Descriptor
+  // recorded per Volume Set.
+  //
+  // Start Main Volume Descriptor Sequence and find Logical Volume Descriptor
+  //
+  while (StartingLsn <

[edk2] [PATCH 3/3] MdeModulePkg/UdfDxe: Rework driver to support PartitionDxe changes

2017-09-16 Thread Paulo Alcantara
This patch reworks the driver to support Partition driver changes.

Cc: Eric Dong <eric.d...@intel.com>
Cc: Paulo Alcantara <pca...@zytor.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
 MdeModulePkg/Universal/Disk/UdfDxe/File.c  |  13 +-
 .../Universal/Disk/UdfDxe/FileSystemOperations.c   | 525 -
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.c   |   7 -
 MdeModulePkg/Universal/Disk/UdfDxe/Udf.h   |  88 +---
 4 files changed, 214 insertions(+), 419 deletions(-)

diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c 
b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
index 01361141bb..f2c62967e8 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
@@ -100,6 +100,7 @@ UdfOpenVolume (
 >Volume,
 >Root
 );
+  ASSERT_EFI_ERROR (Status);
   if (EFI_ERROR (Status)) {
 goto Error_Find_Root_Dir;
   }
@@ -131,7 +132,6 @@ Error_Alloc_Priv_File_Data:
   CleanupFileInformation (>Root);
 
 Error_Find_Root_Dir:
-  CleanupVolumeInformation (>Volume);
 
 Error_Read_Udf_Volume:
 Error_Invalid_Params:
@@ -528,7 +528,6 @@ UdfClose (
   EFI_TPL OldTpl;
   EFI_STATUS  Status;
   PRIVATE_UDF_FILE_DATA   *PrivFileData;
-  PRIVATE_UDF_SIMPLE_FS_DATA  *PrivFsData;
 
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
 
@@ -541,8 +540,6 @@ UdfClose (
 
   PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
 
-  PrivFsData = PRIVATE_UDF_SIMPLE_FS_DATA_FROM_THIS (PrivFileData->SimpleFs);
-
   if (!PrivFileData->IsRootDirectory) {
 CleanupFileInformation (>File);
 
@@ -551,10 +548,6 @@ UdfClose (
 }
   }
 
-  if (--PrivFsData->OpenFiles == 0) {
-CleanupVolumeInformation (>Volume);
-  }
-
   FreePool ((VOID *)PrivFileData);
 
 Exit:
@@ -787,7 +780,7 @@ UdfGetInfo (
   } else if (CompareGuid (InformationType, )) {
 String = VolumeLabel;
 
-FileSetDesc = PrivFsData->Volume.FileSetDescs[0];
+FileSetDesc = >Volume.FileSetDesc;
 
 OstaCompressed = >LogicalVolumeIdentifier[0];
 
@@ -846,7 +839,7 @@ UdfGetInfo (
 FileSystemInfo->Size= FileSystemInfoLength;
 FileSystemInfo->ReadOnly= TRUE;
 FileSystemInfo->BlockSize   =
-  LV_BLOCK_SIZE (>Volume, UDF_DEFAULT_LV_NUM);
+  PrivFsData->Volume.LogicalVolDesc.LogicalBlockSize;
 FileSystemInfo->VolumeSize  = VolumeSize;
 FileSystemInfo->FreeSpace   = FreeSpaceSize;
 
diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c 
b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
index 4609580b30..0f4bc02861 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
@@ -60,154 +60,111 @@ FindAnchorVolumeDescriptorPointer (
 
 EFI_STATUS
 StartMainVolumeDescriptorSequence (
-  IN   EFI_BLOCK_IO_PROTOCOL *BlockIo,
-  IN   EFI_DISK_IO_PROTOCOL  *DiskIo,
-  IN   UDF_ANCHOR_VOLUME_DESCRIPTOR_POINTER  *AnchorPoint,
-  OUT  UDF_VOLUME_INFO   *Volume
+  IN   EFI_BLOCK_IO_PROTOCOL*BlockIo,
+  IN   EFI_DISK_IO_PROTOCOL *DiskIo,
+  OUT  UDF_VOLUME_INFO  *Volume
   )
 {
-  EFI_STATUS Status;
-  UINT32 BlockSize;
-  UDF_EXTENT_AD  *ExtentAd;
-  UINT64 StartingLsn;
-  UINT64 EndingLsn;
-  VOID   *Buffer;
-  UDF_LOGICAL_VOLUME_DESCRIPTOR  *LogicalVolDesc;
-  UDF_PARTITION_DESCRIPTOR   *PartitionDesc;
-  UINTN  Index;
-  UINT32 LogicalBlockSize;
+  EFI_STATUS  Status;
+  UINT32  BlockSize;
+  UINT64  BlockOffset;
+  VOID*Buffer;
+  UINT32  LogicalBlockSize;
+
+  BlockSize = BlockIo->Media->BlockSize;
 
   //
-  // We've already found an ADVP on the volume. It contains the extent
-  // (MainVolumeDescriptorSequenceExtent) where the Main Volume Descriptor
-  // Sequence starts. Therefore, we'll look for Logical Volume Descriptors and
-  // Partitions Descriptors and save them in memory, accordingly.
-  //
-  // Note also that each descriptor will be aligned on a block size (BlockSize)
-  // boundary, so we need to read one block at a time.
+  // Allocate buffer for reading disk blocks
   //
-  BlockSize= BlockIo->Media->BlockSize;
-  ExtentAd = >MainVolumeDescriptorSequenceExtent;
-  StartingLsn  = (UINT64)ExtentAd->ExtentLocation;
-  EndingLsn= StartingLsn + DivU64x32 (
- (UINT64)ExtentAd->ExtentLength,
- BlockSize
- );
-
-  Volume->LogicalVolDescs =
-

Re: [edk2] [PATCH 0/7] MdeModulePkg/Udf: Code refinements

2017-09-15 Thread Paulo Alcantara

Hi Hao,

On 15/09/2017 01:57, Hao Wu wrote:

The series introduces the following code refinements for UdfDxe &
PartitionDxe:

a. Add checks to ensure no possible NULL pointer dereference
b. Reslove operands of different size in bitwise operations
c. Use compare operator for non-boolean comparisons
d. Refine function description comments
e. Refine local variable initialization
f. Refine enum members naming style

Cc: Paulo Alcantara <pca...@zytor.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Star Zeng <star.z...@intel.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Dandan Bi <dandan...@intel.com>

Hao Wu (7):
   MdeModulePkg/UdfDxe: Add checks to ensure no possible NULL ptr deref
   MdeModulePkg/UdfDxe: Fix operands of different size in bitwise OP
   MdeModulePkg/UdfDxe: Use compare operator for non-boolean comparisons
   MdeModulePkg/Udf: Refine function description comments
   MdeModulePkg/UdfDxe: Avoid short (single character) variable name
   MdeModulePkg/Udf: Avoid declaring and initializing local GUID variable
   MdeModulePkg/UdfDxe: Refine enum member naming style

  MdeModulePkg/Universal/Disk/PartitionDxe/Udf.c|  20 +-
  MdeModulePkg/Universal/Disk/UdfDxe/File.c |   5 +-
  MdeModulePkg/Universal/Disk/UdfDxe/FileName.c |  27 +-
  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 483 
+++-
  MdeModulePkg/Universal/Disk/UdfDxe/Udf.h  |  49 +-
  5 files changed, 432 insertions(+), 152 deletions(-)

Looks good to me. Also tested it with OVMF X64. Thanks!

Reviewed-by: Paulo Alcantara <pca...@zytor.com>

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


Re: [edk2] Functionality issues in UDF support

2017-09-15 Thread Paulo Alcantara

Laszlo,

On 15/09/2017 12:51, Laszlo Ersek wrote:

On 09/15/17 09:38, Ni, Ruiyu wrote:

Paulo,
Supporting multiple LVDs can be considered as a long-term task, or can be added
per request.
But I think a urgent fix in PartitionDxe driver is to:
1. create child BLK only for the portion covered by the LVD
2. Do not create child BLK for LVD that's actually an Eltorito LVD

I submitted a Bugzilla to record this:
https://bugzilla.tianocore.org/show_bug.cgi?id=707


Ray,

I've just assigned this bug to myself, for investigation.

I think I understand the problem, and the algorithm that's needed for
solving the problem is not complex:

- iterate over the logical volume descriptors
- if the current one is ElTorito, continue iterating
- if the current one is not ElTorito, stop, and then install a child for
   only the portion of the parent BlkIo (using *inclusive* start and stop
   block numbers) that are covered by the current logical volume
   descriptor
- if no LVD is found that is *not* ElTorito, then install no children,
   and report failure
- future extension: produce children for all non-ElTorito LVDs.

The problem is that I have absolutely no knowledge of UDF specifics, and
it would take me quite a bit of time to learn enough to actually
implement the details for the above algorithm. I don't think this
breakage should be allowed to stay in the tree until either I learn
enough to fix it, or Paulo finds enough time to write the code (he
doesn't have to start learning from zero, but apparently can't find the
time to fix the breakage).

If I understand correctly, this is exactly the kind of regression that
is *not* localized, it messes up the system. Booting from UDF *Bridge*
disks is *already* required by the UEFI spec, and it used to work before
the UDF-related changes. I will not quote section "13.3.2.1 ISO-9660 and
El Torito" of the UEFI-2.7 spec here, because it is confusing; instead I
will quote the improved / proposed wording froam Mantis#1835 (I'm at
liberty to quote it because I wrote it):


I can still boot my Windows 10 ISO image which is an UDF bridge disk 
image with the UDF changes. With or without UdfDxe driver. The problem 
is creating UDF child handles that occupy the entire medium instead of a 
single LVD, hence you can observe the wrong new partition handles & 
device paths from Ray's mapping out.




  > A DVD-ROM image formatted as required by the UDF 2.0 specification

(OSTA Universal Disk Format Specification, Revision 2.0) shall be
booted by UEFI if:

- the DVD-ROM image conforms to the "UDF Bridge" format defined in the
UDF 2.0 specification, and

- the DVD-ROM image contains exactly one ISO-9660 file system, and

- the ISO-9660 file system conforms to the "El Torito" Bootable CD-ROM
Format Specification.

Booting from a DVD-ROM satisfying these requirements is accomplished
using the same methods as booting from a CD-ROM: the ISO-9660 file
system shall be booted.


Again, such disks / disk images could *already* be booted on edk2,
before changing PartitionDxe and adding UdfDxe. By introducing the
PartitionDxe changes, previous functionality is disturbed.

Namely, according to your description at the start of this thread,
PartitionInstallUdfChildHandles() creates handles (with BlockIo
protocols and device paths) for such volumes -- ElTorito ones -- that
are already *owned* by other components in the firmware. In other words,
PartitionInstallUdfChildHandles() infringes on the ownership &
responsibilities of other components, when there is a UDF *Bridge*
volume in the system, which was handled correctly before.

>


This is the textbook definition of regression. My suggestion is that we
disable PartitionInstallUdfChildHandles() entirely, at least
temporarily. This should give Paulo enough time to fix the bug *well*. I
strongly suggest that we don't try to rush the fix; it could only lead
to even more problems.

I'm going to submit a patch series that introduces a feature PCD and
short-circuits PartitionInstallUdfChildHandles() if the PCD is clear.


Since I can't fix it in a pleasant time, as well as it's not a simple 
fix, that might help us a lot.


Thanks!
Paulo
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] Functionality issues in UDF support

2017-09-15 Thread Paulo Alcantara


On September 15, 2017 4:10:10 AM GMT-03:00, "Ni, Ruiyu" <ruiyu...@intel.com> 
wrote:
>Paulo,
>Can current code support multiple volumes in CDROM?

No. It can handle only a single UDF logical volume. I think I never found an 
UDF disk or image with more than a LVD (Logical Volume Descriptior). Although I 
think I also added some comment in the code that it currently handles only one 
logical volume per disk (no access to the code right now, sorry). Other than 
that, there should be also a DEBUG() or perhaps an ASSERT() in case more than 
one is found.

For supporting multiple logical volumes, we would have to follow your 
suggestion and change Partition driver to install a child handle for each LVD 
found in an UDF fs.

Thanks!
Paulo

>
>Thanks/Ray
>
>> -Original Message-
>> From: Paulo Alcantara [mailto:pca...@zytor.com]
>> Sent: Friday, September 15, 2017 2:26 PM
>> To: Ni, Ruiyu <ruiyu...@intel.com>; Laszlo Ersek <ler...@redhat.com>
>> Cc: edk2-devel@lists.01.org; Wu, Hao A <hao.a...@intel.com>; Zeng,
>Star
>> <star.z...@intel.com>
>> Subject: RE: Functionality issues in UDF support
>> 
>> 
>> 
>> Ray,
>> 
>> On September 15, 2017 3:02:11 AM GMT-03:00, "Ni, Ruiyu"
>> <ruiyu...@intel.com> wrote:
>> >Paulo,
>> >When will you change the implementation to this way?
>> 
>> Unfortunately I can't promise you when I'd be doing this because, you
>know,
>> I can only work on this in my free time (very short, ATM). Perhaps
>this
>> weekend - but real life also happens and I may get preempted by
>something
>> else.
>> 
>> Paulo
>> 
>> >
>> >
>> >Thanks/Ray
>> >
>> >> -Original Message-
>> >> From: Paulo Alcantara [mailto:pca...@zytor.com]
>> >> Sent: Friday, September 15, 2017 1:38 PM
>> >> To: Ni, Ruiyu <ruiyu...@intel.com>; Laszlo Ersek
><ler...@redhat.com>
>> >> Cc: edk2-devel@lists.01.org; Wu, Hao A <hao.a...@intel.com>; Zeng,
>> >Star
>> >> <star.z...@intel.com>
>> >> Subject: RE: Functionality issues in UDF support
>> >>
>> >>
>> >>
>> >> Hi,
>> >>
>> >> On September 15, 2017 2:08:28 AM GMT-03:00, "Ni, Ruiyu"
>> >> <ruiyu...@intel.com> wrote:
>> >> >Hi Paulo,
>> >> >The responsibility of PartitionDxe driver is to partition the
>> >physical
>> >> >BLK (the entire CDROM) into logical BLKs (one BLK for each
>volume).
>> >> >It doesn't make sense to create a child BLK handle which still
>> >covers
>> >> >the entire CDROM.
>> >> >So as I suggested in below, PartitionInstallUdfChildHandles()
>should
>> >> >contain a for-loop to iterate all the volumes in the CDROM, and
>> >create
>> >> >child BLK handle for each volumes, but skipping Eltorito volume.
>> >>
>> >> Ah, makes sense to me now. Thanks for clarifying it. So I agree
>with
>> >you.
>> >>
>> >> In whatever you guys decide to do with it, count on me to give
>some
>> >help.
>> >>
>> >> Thanks!
>> >> Paulo
>> >>
>> >> >
>> >> >Thanks/Ray
>> >> >
>> >> >> -Original Message-
>> >> >> From: Paulo Alcantara [mailto:pca...@zytor.com]
>> >> >> Sent: Friday, September 15, 2017 12:58 PM
>> >> >> To: Ni, Ruiyu <ruiyu...@intel.com>; Laszlo Ersek
>> ><ler...@redhat.com>
>> >> >> Cc: edk2-devel@lists.01.org; Wu, Hao A <hao.a...@intel.com>;
>Zeng,
>> >> >Star
>> >> >> <star.z...@intel.com>
>> >> >> Subject: Re: Functionality issues in UDF support
>> >> >>
>> >> >>
>> >> >>
>> >> >> Hi Ray,
>> >> >>
>> >> >> On September 15, 2017 12:33:04 AM GMT-03:00, "Ni, Ruiyu"
>> >> >> <ruiyu...@intel.com> wrote:
>> >> >> >Paulo,
>> >> >> >Before raising my questions, I'd like to confirm that for a
>> >single
>> >> >> >CD/DVD in UDF format, there might be multiple volumes.
>> >> >> >One of the volume could be Eltorito type.
>> >> >> >If my understanding is correct, please continue reading below.
>> >> >>
>> >> &g

Re: [edk2] [PATCH] MdeModulePkg/UdfDxe: Remove negative comparison of unsigned number

2017-09-15 Thread Paulo Alcantara


Star,

On September 15, 2017 3:14:38 AM GMT-03:00, "Zeng, Star" <star.z...@intel.com> 
wrote:
>Hi,
>
>Based on recent issues about UDF since the code was pushed for
>https://lists.01.org/pipermail/edk2-devel/2017-September/014360.html, I
>want to raise some questions kindly.
>
>https://lists.01.org/pipermail/edk2-devel/2017-September/014409.html
>https://lists.01.org/pipermail/edk2-devel/2017-September/014518.html
>https://lists.01.org/pipermail/edk2-devel/2017-September/014542.html
>https://lists.01.org/pipermail/edk2-devel/2017-September/014489.html
>https://lists.01.org/pipermail/edk2-devel/2017-September/014551.html
>https://lists.01.org/pipermail/edk2-devel/2017-September/014560.html
>https://lists.01.org/pipermail/edk2-devel/2017-September/014649.html
>https://lists.01.org/pipermail/edk2-devel/2017-September/014694.html
>https://lists.01.org/pipermail/edk2-devel/2017-September/014695.html
>
>Is the code expected to be got upstream originally? (I may be a stupid
>question since the code has been gotten upstream, I just want to double
>confirm that as Paulo's reply below "I believed that it would never get
>upstream".)
>Is the code ready to be in master? Should it be in Staging branch
>first?

Sorry if I wasn't clear enough, but when I sent UDF support to ML in ~3 years 
ago, nobody seemed to care and had no feedback since then, so I thought it 
would never get accepted and then I gave up on trying to improve, cleanup, etc. 
-- I even started working write support for it but also gave up. It would not 
make sense to work on it anymore. Right?

I would not know to tell you in which branch it should go, but as the driver 
gives you the ability to access an UDF fs as it's supposed to, then, IMHO, it'd 
be ready to go either way. 

>
>
>Paulo,
>Could you help do more evaluation to the code as you said "I *do* know
>that the code really needs refactoring, documentation, etc"? I believe
>you are most familiar with the code and know its quality. :)
>
>
>BTW: More test seems need to be done before the code check in, for
>example, build with various tool chains, ECC scan for coding style,
>static tool scan, etc. That is what we(especially me) need to improve
>in future when developing and reviewing.
>Anyway, let's help keep improving UDF codes.

Yep. We should refactor the code, fix coding style issues, improve 
documetation. Since I was the only one who tested it, it definitely needs a 
little more testing.

With you help, we definitely can resolve all those TODO items.

Thanks!
Paulo

>
>
>
>Thanks,
>Star
>-Original Message-
>From: Paulo Alcantara [mailto:pca...@zytor.com] 
>Sent: Wednesday, September 13, 2017 1:47 PM
>To: Zeng, Star <star.z...@intel.com>; edk2-devel@lists.01.org
>Cc: Dong, Eric <eric.d...@intel.com>; Ni, Ruiyu <ruiyu...@intel.com>;
>Bi, Dandan <dandan...@intel.com>
>Subject: RE: [PATCH] MdeModulePkg/UdfDxe: Remove negative comparison of
>unsigned number
>
>
>
>On September 13, 2017 2:08:54 AM GMT-03:00, "Zeng, Star"
><star.z...@intel.com> wrote:
>>I do not understand the context of the code.
>>The change is good to fix the build failure, but I want to ask a 
>>question before I gave Rb. :)
>>
>>Is it possible ReadFileInfo->FilePosition less than FilePosition?
>
>Nope. When doing my tests, I briefly looked at code how it's used and
>also added an ASSERT() to make sure it is never lesser than
>FilePosition.
>
>BTW, I *do* know that the code really needs refactoring, documentation,
>etc. --  I didnt do that before because I believed that it would never
>get upstream -- since its now -- I will look forward to that in my free
>time.
>
>Its 2:46am here so I should get some sleep :-) Thanks!
>
>Paulo
>
>>
>>
>>Thanks,
>>Star
>>-Original Message-
>>From: Paulo Alcantara [mailto:pca...@zytor.com]
>>Sent: Wednesday, September 13, 2017 12:45 PM
>>To: edk2-devel@lists.01.org
>>Cc: Paulo Alcantara <pca...@zytor.com>; Zeng, Star 
>><star.z...@intel.com>; Dong, Eric <eric.d...@intel.com>; Ni, Ruiyu 
>><ruiyu...@intel.com>; Bi, Dandan <dandan...@intel.com>
>>Subject: [PATCH] MdeModulePkg/UdfDxe: Remove negative comparison of 
>>unsigned number
>>
>>This patch gets rid of a negative comparison of an UINT64 type
>(Offset) 
>>as it'll never evaluate to true.
>>
>>Cc: Star Zeng <star.z...@intel.com>
>>Cc: Eric Dong <eric.d...@intel.com>
>>Cc: Ruiyu Ni <ruiyu...@intel.com>
>>Cc: Dandan Bi <dandan...@intel.com>
>>Contributed-under: TianoCore Contribution Agreement 1.1
>>Reported-by: Star Zeng <st

Re: [edk2] Functionality issues in UDF support

2017-09-15 Thread Paulo Alcantara


Ray,

On September 15, 2017 3:02:11 AM GMT-03:00, "Ni, Ruiyu" <ruiyu...@intel.com> 
wrote:
>Paulo,
>When will you change the implementation to this way?

Unfortunately I can't promise you when I'd be doing this because, you know, I 
can only work on this in my free time (very short, ATM). Perhaps this weekend - 
but real life also happens and I may get preempted by something else.

Paulo

>
>
>Thanks/Ray
>
>> -----Original Message-
>> From: Paulo Alcantara [mailto:pca...@zytor.com]
>> Sent: Friday, September 15, 2017 1:38 PM
>> To: Ni, Ruiyu <ruiyu...@intel.com>; Laszlo Ersek <ler...@redhat.com>
>> Cc: edk2-devel@lists.01.org; Wu, Hao A <hao.a...@intel.com>; Zeng,
>Star
>> <star.z...@intel.com>
>> Subject: RE: Functionality issues in UDF support
>> 
>> 
>> 
>> Hi,
>> 
>> On September 15, 2017 2:08:28 AM GMT-03:00, "Ni, Ruiyu"
>> <ruiyu...@intel.com> wrote:
>> >Hi Paulo,
>> >The responsibility of PartitionDxe driver is to partition the
>physical
>> >BLK (the entire CDROM) into logical BLKs (one BLK for each volume).
>> >It doesn't make sense to create a child BLK handle which still
>covers
>> >the entire CDROM.
>> >So as I suggested in below, PartitionInstallUdfChildHandles() should
>> >contain a for-loop to iterate all the volumes in the CDROM, and
>create
>> >child BLK handle for each volumes, but skipping Eltorito volume.
>> 
>> Ah, makes sense to me now. Thanks for clarifying it. So I agree with
>you.
>> 
>> In whatever you guys decide to do with it, count on me to give some
>help.
>> 
>> Thanks!
>> Paulo
>> 
>> >
>> >Thanks/Ray
>> >
>> >> -Original Message-
>> >> From: Paulo Alcantara [mailto:pca...@zytor.com]
>> >> Sent: Friday, September 15, 2017 12:58 PM
>> >> To: Ni, Ruiyu <ruiyu...@intel.com>; Laszlo Ersek
><ler...@redhat.com>
>> >> Cc: edk2-devel@lists.01.org; Wu, Hao A <hao.a...@intel.com>; Zeng,
>> >Star
>> >> <star.z...@intel.com>
>> >> Subject: Re: Functionality issues in UDF support
>> >>
>> >>
>> >>
>> >> Hi Ray,
>> >>
>> >> On September 15, 2017 12:33:04 AM GMT-03:00, "Ni, Ruiyu"
>> >> <ruiyu...@intel.com> wrote:
>> >> >Paulo,
>> >> >Before raising my questions, I'd like to confirm that for a
>single
>> >> >CD/DVD in UDF format, there might be multiple volumes.
>> >> >One of the volume could be Eltorito type.
>> >> >If my understanding is correct, please continue reading below.
>> >>
>> >> Right.
>> >>
>> >> >
>> >> >We found below mapping table using "map -r" shell command in a
>> >platform
>> >> >with only PartitionDxe change and without UdfDxe driver.
>> >> >It's a bug that  and  are created. Actually they
>are
>> >> >identical to  and .
>> >> >
>> >> >--- Mapping table---
>> >> > BLK2: Alias(s):
>> >> >  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)
>> >> >
>> >> > BLK3: Alias(s):
>> >> > 
>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/CDROM(0x0)
>> >> >  FS1: Alias(s):CD1a65535a1:;BLK4:
>> >> > 
>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/CDROM(0x1)
>> >> >
>> >> > BLK5: Alias(s):
>> >>
>>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/VenMedia(C5BD4D42-
>> >> 1A76-4996-8956-73CDA326CD0A)
>> >> > BLK6: Alias(s):
>> >>
>>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/VenMedia(C5BD4D42-
>> >> 1A76-4996-8956-73CDA326CD0A)/CDROM(0x0)
>> >> >  FS2: Alias(s):CD1a65535ab:;BLK7:
>> >>
>>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/VenMedia(C5BD4D42-
>> >> 1A76-
>> >> >4996-8956-73CDA326CD0A)/CDROM(0x1)
>> >> >--- End of mapping table ---
>> >> >
>> >> >After investigation, I found the UDF logic in Partition driver
>> >doesn't
>> >> >truly skip the Eltorito volume.
>> >> >The code flow is like below:
>> >> >
>> >> >  1.   is created by ScsiDiskDxe driver.
>> >> >  2.  By passing  to PartitionDxe Start()
>> >> >*and  are created

Re: [edk2] Functionality issues in UDF support

2017-09-14 Thread Paulo Alcantara


Hi,

On September 15, 2017 2:08:28 AM GMT-03:00, "Ni, Ruiyu" <ruiyu...@intel.com> 
wrote:
>Hi Paulo,
>The responsibility of PartitionDxe driver is to partition the physical
>BLK (the entire CDROM)
>into logical BLKs (one BLK for each volume).
>It doesn't make sense to create a child BLK handle which still covers
>the entire CDROM.
>So as I suggested in below, PartitionInstallUdfChildHandles() should
>contain a for-loop to iterate
>all the volumes in the CDROM, and create child BLK handle for each
>volumes, but skipping Eltorito volume.

Ah, makes sense to me now. Thanks for clarifying it. So I agree with you.

In whatever you guys decide to do with it, count on me to give some help.

Thanks!
Paulo

>
>Thanks/Ray
>
>> -Original Message-
>> From: Paulo Alcantara [mailto:pca...@zytor.com]
>> Sent: Friday, September 15, 2017 12:58 PM
>> To: Ni, Ruiyu <ruiyu...@intel.com>; Laszlo Ersek <ler...@redhat.com>
>> Cc: edk2-devel@lists.01.org; Wu, Hao A <hao.a...@intel.com>; Zeng,
>Star
>> <star.z...@intel.com>
>> Subject: Re: Functionality issues in UDF support
>> 
>> 
>> 
>> Hi Ray,
>> 
>> On September 15, 2017 12:33:04 AM GMT-03:00, "Ni, Ruiyu"
>> <ruiyu...@intel.com> wrote:
>> >Paulo,
>> >Before raising my questions, I'd like to confirm that for a single
>> >CD/DVD in UDF format, there might be multiple volumes.
>> >One of the volume could be Eltorito type.
>> >If my understanding is correct, please continue reading below.
>> 
>> Right.
>> 
>> >
>> >We found below mapping table using "map -r" shell command in a
>platform
>> >with only PartitionDxe change and without UdfDxe driver.
>> >It's a bug that  and  are created. Actually they are
>> >identical to  and .
>> >
>> >--- Mapping table---
>> > BLK2: Alias(s):
>> >  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)
>> >
>> > BLK3: Alias(s):
>> >  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/CDROM(0x0)
>> >  FS1: Alias(s):CD1a65535a1:;BLK4:
>> >  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/CDROM(0x1)
>> >
>> > BLK5: Alias(s):
>> >PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/VenMedia(C5BD4D42-
>> 1A76-4996-8956-73CDA326CD0A)
>> > BLK6: Alias(s):
>> >PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/VenMedia(C5BD4D42-
>> 1A76-4996-8956-73CDA326CD0A)/CDROM(0x0)
>> >  FS2: Alias(s):CD1a65535ab:;BLK7:
>> >PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/VenMedia(C5BD4D42-
>> 1A76-
>> >4996-8956-73CDA326CD0A)/CDROM(0x1)
>> >--- End of mapping table ---
>> >
>> >After investigation, I found the UDF logic in Partition driver
>doesn't
>> >truly skip the Eltorito volume.
>> >The code flow is like below:
>> >
>> >  1.   is created by ScsiDiskDxe driver.
>> >  2.  By passing  to PartitionDxe Start()
>> >*and  are created by PartitionDxe driver, by
>> >PartitionInstallElToritoChildHandles().
>> >*is created by PartitionDxe driver, by
>> >PartitionInstallUdfChildHandles().
>> >  3.  By passing  to PartitionDxe Start()
>> >*and  are created by PartitionDxe driver, by
>> >PartitionInstallElToritoChildHandles().
>> >
>> >I think step 2.a is not correct if my understanding to UDF is
>correct.
>> >The PartitionInstallUdfChildHandles() should iterate all volumes in
>the
>> >media and creates the child BLK handle for each volume, but skipping
>> >Eltorito volume.
>> >
>> >Instead, the current implementation just creates one child BLK
>handle
>> >for the entire media.
>> >To avoid reclusively creating  child BLK handle, the
>> >PartitionInstallUdfChildHandles() contains a logic to do nothing
>when
>> >the handle is created by ParititonDxe driver. The logic is not
>needed
>> >when the implementation follows my suggestion above.
>> >Due to this, step 3.a creates the additional but shouldn't-exist BLK
>> >handles  and .
>> >
>> >UdfDxe driver is supposed to Start() on each volume and produce
>> >SimpleFileSystem protocol.
>> 
>> It seems that PartitionInstallUdfChildHandles() indeed skips the
>ElTorito
>> partitions otherwise you'd see the ".../CDROM(0x1)/VenMedia()" and
>> ".../CDROM(0x0)/VenMedia()" device paths *also* in the mapping
>output.
>> 
>> If I understand correctly, the prob

Re: [edk2] Functionality issues in UDF support

2017-09-14 Thread Paulo Alcantara


Hi Ray,

On September 15, 2017 12:33:04 AM GMT-03:00, "Ni, Ruiyu"  
wrote:
>Paulo,
>Before raising my questions, I'd like to confirm that for a single
>CD/DVD in UDF format, there might be multiple volumes.
>One of the volume could be Eltorito type.
>If my understanding is correct, please continue reading below.

Right.

>
>We found below mapping table using "map -r" shell command in a platform
>with only PartitionDxe change and without UdfDxe driver.
>It's a bug that  and  are created. Actually they are
>identical to  and .
>
>--- Mapping table---
> BLK2: Alias(s):
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)
>
> BLK3: Alias(s):
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/CDROM(0x0)
>  FS1: Alias(s):CD1a65535a1:;BLK4:
>  PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/CDROM(0x1)
>
> BLK5: Alias(s):
>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)
> BLK6: Alias(s):
>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)/CDROM(0x0)
>  FS2: Alias(s):CD1a65535ab:;BLK7:
>PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0x,0x0)/VenMedia(C5BD4D42-1A76-4996-8956-73CDA326CD0A)/CDROM(0x1)
>--- End of mapping table ---
>
>After investigation, I found the UDF logic in Partition driver doesn't
>truly skip the Eltorito volume.
>The code flow is like below:
>
>  1.   is created by ScsiDiskDxe driver.
>  2.  By passing  to PartitionDxe Start()
>*and  are created by PartitionDxe driver, by
>PartitionInstallElToritoChildHandles().
>*is created by PartitionDxe driver, by
>PartitionInstallUdfChildHandles().
>  3.  By passing  to PartitionDxe Start()
>*and  are created by PartitionDxe driver, by
>PartitionInstallElToritoChildHandles().
>
>I think step 2.a is not correct if my understanding to UDF is correct.
>The PartitionInstallUdfChildHandles() should iterate
>all volumes in the media and creates the child BLK handle for each
>volume, but skipping Eltorito volume.
>
>Instead, the current implementation just creates one child BLK handle
>for the entire media.
>To avoid reclusively creating  child BLK handle, the
>PartitionInstallUdfChildHandles() contains a logic to do nothing when
>the handle is created by ParititonDxe driver. The logic is not needed
>when the implementation follows my suggestion above.
>Due to this, step 3.a creates the additional but shouldn't-exist BLK
>handles  and .
>
>UdfDxe driver is supposed to Start() on each volume and produce
>SimpleFileSystem protocol.

It seems that PartitionInstallUdfChildHandles() indeed skips the ElTorito 
partitions otherwise you'd see the ".../CDROM(0x1)/VenMedia()" and 
".../CDROM(0x0)/VenMedia()" device paths *also* in the mapping output.

If I understand correctly, the problem is that when we create a child handle 
for an UDF volume, Partition driver will execute again, parse the newly created 
UDF handle, find again an ElTorito partition and then install a new child 
handle (VenMedia()/CDROM())

So, the logic of skipping of ElTorito partitions in 
PartitionInstallUdfChildHandles() is not enough. Unfortunately we can't handle 
UDF bridge disks (ElTorito + UDF) entirely in PartitionInstallUdfChildHandles() 
-- we should probably also skip UDF device paths in 
PartitionInstallElToritoChildHandles().

Does it make sense to you, Ray? Thanks for raising this up.

Paulo

>
>Do you agree with my above suggestions?
>
>Laszlo,
>I understood your needs of this UDF support. But as you can see there
>are many build failures and even functionality issues due to this
>support.
>I am not sure how the other open source project handles such cases.
>But I am thinking maybe we could move the whole UDF support to
>edk2-staging firstly and move it back after all the issues are
>resolved.
>What's your suggestion?
>
>Thanks/Ray

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] [PATCH] MdeModulePkg UdfDxe: Fix VS2010/VS2012 build failure

2017-09-14 Thread Paulo Alcantara

Hi,

On 9/14/2017 7:53 AM, Star Zeng wrote:

VS2010/VS2012 build failure with below info:
warning C4701:
   potentially uninitialized local variable 'DataOffset' used
   potentially uninitialized local variable 'FilePosition' used
   potentially uninitialized local variable 'FinishedSeeking' used
   potentially uninitialized local variable 'Data' used
warning C4703:
   potentially uninitialized local pointer variable 'Data' used

In fact, DataOffset, FilePosition and FinishedSeeking are initialized
and then used if (ReadFileInfo->Flags == READ_FILE_SEEK_AND_READ).
DoFreeAed will be set to TRUE when Data is allocated and returned from
GetAedAdsData(), and Data will be freed if (DoFreeAed) when exiting.

Use same method at 5afa5b815936e2b45a375b6521764195bed68680 to fix
the build failure.

There is related discussion at
https://lists.01.org/pipermail/edk2-devel/2017-September/014641.html

Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Paulo Alcantara <pca...@zytor.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Liming Gao <liming@intel.com>
Cc: Dandan Bi <dandan...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Star Zeng <star.z...@intel.com>
---
  MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 4 
  1 file changed, 4 insertions(+)


With your patch, NT32 X64 build passes with VS2012. Thanks!

Reviewed-by: Paulo Alcantara <pa...@hp.com>

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


Re: [edk2] [PATCH] MdeModulePkg/UdfDxe: Fix NULL pointer dereference

2017-09-14 Thread Paulo Alcantara



On 9/12/2017 8:27 AM, Laszlo Ersek wrote:

On 09/12/17 03:30, Paulo Alcantara wrote:

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=704

For root directory, the FID (File Identifier Descriptor) pointer is
accessible through PRIVATE_UDF_FILE_DATA.Root, whereas non-root
directory and regular files, their FIDs are accessible through
PRIVATE_UDF_FILE_DATA.File.

In UdfSetPosition(), the FID was retrieved through
PRIVATE_UDF_FILE_DATA.File, hence when calling it with a root directory,
PRIVATE_UDF_FILE_DATA.File.FileIdentifierDescriptor would be NULL and
then dereferenced.

This patch fixes the NULL pointer dereference by calling _FILE() to
transparently return the correct UDF_FILE_INFO * which points to a valid
FID descriptor of a specific file.

Cc: Star Zeng <star.z...@intel.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Ruiyu Ni <ruiyu...@intel.com>
Cc: Laszlo Ersek <ler...@redhat.com>
Cc: Steven Shi <steven@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Reported-by: Steven Shi <steven....@intel.com>
Signed-off-by: Paulo Alcantara <pca...@zytor.com>
---
  MdeModulePkg/Universal/Disk/UdfDxe/File.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/File.c 
b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
index 8b9339567f..a1eb2196df 100644
--- a/MdeModulePkg/Universal/Disk/UdfDxe/File.c
+++ b/MdeModulePkg/Universal/Disk/UdfDxe/File.c
@@ -690,7 +690,8 @@ UdfSetPosition (
  
PrivFileData = PRIVATE_UDF_FILE_DATA_FROM_THIS (This);
  
-  FileIdentifierDesc = PrivFileData->File.FileIdentifierDesc;

+  FileIdentifierDesc = _FILE (PrivFileData)->FileIdentifierDesc;
+  ASSERT (FileIdentifierDesc != NULL);
if (IS_FID_DIRECTORY_FILE (FileIdentifierDesc)) {
  //
  // If the file handle is a directory, the _only_ position that may be set 
is



Reviewed-by: Laszlo Ersek <ler...@redhat.com>


Ping? :-)

Thanks!
Paulo
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] [PATCH 0/2] MdeModulePkg: UDF fixes and cleanups, round 2

2017-09-13 Thread Paulo Alcantara


On September 12, 2017 7:26:10 PM GMT-03:00, Laszlo Ersek <ler...@redhat.com> 
wrote:
>Repo:   https://github.com/lersek/edk2.git
>Branch: udf_fixes_cleanups_round2
>
>Once these patches are sufficiently reviewed, please don't wait for me
>to commit them.
>
>Further UdfDxe issues should be please reported in the TianoCore
>Bugzilla.
>
>Cc: Ard Biesheuvel <ard.biesheu...@linaro.org>
>Cc: Eric Dong <eric.d...@intel.com>
>Cc: Paulo Alcantara <pca...@zytor.com>
>Cc: Ruiyu Ni <ruiyu...@intel.com>
>Cc: Star Zeng <star.z...@intel.com>
>
>Thanks
>Laszlo
>
>Laszlo Ersek (2):
>  MdeModulePkg/UdfDxe: reject reserved values in ICB.Flags[2:0]
> MdeModulePkg/UdfDxe: suppress incorrect compiler warning in ReadFile()
>
>MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 13
>+
> 1 file changed, 13 insertions(+)

Reviewed-by: Paulo Alcantara <pca...@zytor.com>

Thanks,
Paulo

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


Re: [edk2] [PATCH] MdeModulePkg/UdfDxe: Remove negative comparison of unsigned number

2017-09-12 Thread Paulo Alcantara


On September 13, 2017 2:08:54 AM GMT-03:00, "Zeng, Star" <star.z...@intel.com> 
wrote:
>I do not understand the context of the code.
>The change is good to fix the build failure, but I want to ask a
>question before I gave Rb. :)
>
>Is it possible ReadFileInfo->FilePosition less than FilePosition?

Nope. When doing my tests, I briefly looked at code how it's used and also 
added an ASSERT() to make sure it is never lesser than FilePosition.

BTW, I *do* know that the code really needs refactoring, documentation, etc. -- 
 I didnt do that before because I believed that it would never get upstream -- 
since its now -- I will look forward to that in my free time.

Its 2:46am here so I should get some sleep :-) Thanks!

Paulo

>
>
>Thanks,
>Star
>-Original Message-
>From: Paulo Alcantara [mailto:pca...@zytor.com] 
>Sent: Wednesday, September 13, 2017 12:45 PM
>To: edk2-devel@lists.01.org
>Cc: Paulo Alcantara <pca...@zytor.com>; Zeng, Star
><star.z...@intel.com>; Dong, Eric <eric.d...@intel.com>; Ni, Ruiyu
><ruiyu...@intel.com>; Bi, Dandan <dandan...@intel.com>
>Subject: [PATCH] MdeModulePkg/UdfDxe: Remove negative comparison of
>unsigned number
>
>This patch gets rid of a negative comparison of an UINT64 type (Offset)
>as it'll never evaluate to true.
>
>Cc: Star Zeng <star.z...@intel.com>
>Cc: Eric Dong <eric.d...@intel.com>
>Cc: Ruiyu Ni <ruiyu...@intel.com>
>Cc: Dandan Bi <dandan...@intel.com>
>Contributed-under: TianoCore Contribution Agreement 1.1
>Reported-by: Star Zeng <star.z...@intel.com>
>Signed-off-by: Paulo Alcantara <pca...@zytor.com>
>---
> MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c | 3 ---
> 1 file changed, 3 deletions(-)
>
>diff --git a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>index 7286265373..2039f80289 100644
>--- a/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>+++ b/MdeModulePkg/Universal/Disk/UdfDxe/FileSystemOperations.c
>@@ -1082,9 +1082,6 @@ ReadFile (
> 
>if (FilePosition + ExtentLength > ReadFileInfo->FilePosition) {
>   Offset = ReadFileInfo->FilePosition - FilePosition;
>-  if (Offset < 0) {
>-Offset = -(Offset);
>-  }
> } else {
>   Offset = 0;
> }
>--
>2.11.0

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
___
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel


  1   2   >