[efi] Allow wrapping the global boot services table in situ

When DEBUG=efi_wrap is enabled, we construct a patched copy of the
boot services table and patch the global system table to point to this
copy.  This ensures that any subsequently loaded EFI binaries will
call our wrappers.

Previously loaded EFI binaries will typically have cached the boot
services table pointer (in the gBS variable used by EDK2 code), and
therefore will not pick up the updated pointer and so will not call
our wrappers.  In most cases, this is what we want to happen: we are
interested in tracing the calls issued by the newly loaded binary and
we do not want to be distracted by the high volume of boot services
calls issued by existing UEFI drivers.

In some circumstances (such as when a badly behaved OEM driver is
causing the system to lock up during the ExitBootServices() call), it
can be very useful to be able to patch the global boot services table
in situ, so that we can trace calls issued by existing drivers.

Restructure the wrapping code to allow wrapping to be enabled or
disabled at any time, and to allow for patching the global boot
services table in situ.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-03-20 12:25:26 +00:00
parent f68c8b09e3
commit 1a602c92ac
3 changed files with 144 additions and 80 deletions

View File

@@ -268,7 +268,7 @@ static int efi_image_exec ( struct image *image ) {
efi_snp_release();
/* Wrap calls made by the loaded image (for debugging) */
efi_wrap ( handle );
efi_wrap_image ( handle );
/* Reset console since image will probably use it */
console_reset();
@@ -291,6 +291,7 @@ static int efi_image_exec ( struct image *image ) {
rc = 0;
err_start_image:
efi_unwrap();
efi_snp_claim();
err_open_protocol:
/* If there was no error, then the image must have been