]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ShellPkg/UefiShellLib: clarify workaround for unfixable EdkShell bug
authorLaszlo Ersek <lersek@redhat.com>
Fri, 6 Sep 2019 22:19:29 +0000 (00:19 +0200)
committerLaszlo Ersek <lersek@redhat.com>
Wed, 9 Oct 2019 07:40:10 +0000 (09:40 +0200)
The EDK 1 Shell (available at <https://github.com/tianocore/edk-Shell>)
has a bug in its EFI_SHELL_ENVIRONMENT2.Execute() implementation that
edk2's UefiShellLib has no choice but to work around.

Improve the explanation in the code. Also, document the implicit
EFI_HANDLE -> (EFI_HANDLE*) conversion, which happens implicitly after
dereferencing ParentHandle, with an explicit cast.

In practice, this patch is a no-op.

Cc: Jaben Carsey <jaben.carsey@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Zhichao Gao <zhichao.gao@intel.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Zhichao Gao <zhichao.gao@intel.com>
Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
ShellPkg/Library/UefiShellLib/UefiShellLib.c

index 835d0f88ca74ea923175ccabe03c53d15881b787..9f07a58eb23d38a8aa4da36f3abb6f40888f5330 100644 (file)
@@ -1291,9 +1291,27 @@ ShellExecute (
   if (mEfiShellEnvironment2 != NULL) {\r
     //\r
     // Call EFI Shell version.\r
   if (mEfiShellEnvironment2 != NULL) {\r
     //\r
     // Call EFI Shell version.\r
-    // Due to oddity in the EFI shell we want to dereference the ParentHandle here\r
     //\r
     //\r
-    CmdStatus = (mEfiShellEnvironment2->Execute(*ParentHandle,\r
+    // Due to an unfixable bug in the EdkShell implementation, we must\r
+    // dereference "ParentHandle" here:\r
+    //\r
+    // 1. The EFI shell installs the EFI_SHELL_ENVIRONMENT2 protocol,\r
+    //    identified by gEfiShellEnvironment2Guid.\r
+    // 2. The Execute() member function takes "ParentImageHandle" as first\r
+    //    parameter, with type (EFI_HANDLE*).\r
+    // 3. In the EdkShell implementation, SEnvExecute() implements the\r
+    //    Execute() member function. It passes "ParentImageHandle" correctly to\r
+    //    SEnvDoExecute().\r
+    // 4. SEnvDoExecute() takes the (EFI_HANDLE*), and passes it directly --\r
+    //    without de-referencing -- to the HandleProtocol() boot service.\r
+    // 5. But HandleProtocol() takes an EFI_HANDLE.\r
+    //\r
+    // Therefore we must\r
+    // - de-reference "ParentHandle" here, to mask the bug in\r
+    //   SEnvDoExecute(), and\r
+    // - pass the resultant EFI_HANDLE as an (EFI_HANDLE*).\r
+    //\r
+    CmdStatus = (mEfiShellEnvironment2->Execute((EFI_HANDLE *)*ParentHandle,\r
                                           CommandLine,\r
                                           Output));\r
     //\r
                                           CommandLine,\r
                                           Output));\r
     //\r