From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=pass header.i=@linaro.org header.s=google header.b=lROrvMra; spf=pass (domain: linaro.org, ip: 209.85.210.194, mailfrom: ard.biesheuvel@linaro.org) Received: from mail-pf1-f194.google.com (mail-pf1-f194.google.com [209.85.210.194]) by groups.io with SMTP; Sun, 14 Apr 2019 12:52:59 -0700 Received: by mail-pf1-f194.google.com with SMTP id 8so7526326pfr.4 for ; Sun, 14 Apr 2019 12:52:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=JFDd2KIMJ/nOCxkaNFN9MpCNFYY3lUWhzGC37seeqMg=; b=lROrvMra+N1rTNZzJ8ig9I7NVjaYnIB9iT4zk4SLaxBLy83GLnX/U1r+qQC/Cn6aGf Myitb6w3/qemtqKBb1OhhmkPCKg3RAup9ZIvYgdgRFFQB9DC2PzIY9ETrMap8bC3T+Iu cC1cLB+DXx8MEo2xc6dAeDSump8dUk2FTWjieyRE4o5vOpo+f7ZueAcOAXiUec4xUcHU FNBRUXz+dUWc3EBEJuxw9XNynk3eFFHxW0QrZGjxD4DzbexhntcY6M4h0lIuvpibrfSO 4WHTWKjyba4KOEwml6gqTsMRcUksbZaSsFquKzIHfDyw1PGzMcEJo1TjXbRtWQYHU5et bE+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=JFDd2KIMJ/nOCxkaNFN9MpCNFYY3lUWhzGC37seeqMg=; b=lSlh5EWxjFFe7tKWg8wV66iLjD3XGUXzHbXor3HcBce/1Nv4Rf5VKc6H/88Bm5yoqe rQawS+XTlcFmFDJB7Kkc3gifV5OiiNNu/xSmo2e+0xDNkahisPT8fU668MFlnhiDA0P4 k0IkiR+eYFslhkgVq+j16PdRWo42VbjAxwjmEmKlspl0bsNB0ws3QE0PdB9eVjGICXSR WC2k/p+u8IhXhCTh687781Lh9NIKHi2oyBf8GlYzGJO9aetEtN066f+OH90aUY1mb/yK bnu6tNLW4TKIC+lRMhNT2hQdLzwqM9YUBbvo78xq6xPmh7nb334L9R48SAVfZ++z0Ama eBIw== X-Gm-Message-State: APjAAAUbdeEL3dXs8CymP/LzyEQrqL7mqfpMiI5RZfMDu468bidQgUue LO3IgeFzSQ0ndqMW7QMJImPljAZ4rc8CSJEv X-Google-Smtp-Source: APXvYqzzfCcx8x8Ody+G0rXW4nXT8j0pqEGGjj60lXjA4Mwnogo0i7bmJTt8ql1Z/TwXqOdB+kSpmQ== X-Received: by 2002:a62:5fc7:: with SMTP id t190mr23323766pfb.191.1555271578515; Sun, 14 Apr 2019 12:52:58 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([50.236.184.206]) by smtp.gmail.com with ESMTPSA id j16sm62388977pfi.58.2019.04.14.12.52.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 14 Apr 2019 12:52:57 -0700 (PDT) From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Michael D Kinney , Andrew Fish , Leif Lindholm , Star Zeng , Eric Dong , Ruiyu Ni , Liming Gao , Jaben Carsey , Steven Shi , Jian J Wang , Hao Wu Subject: [PATCH v6 5/7] MdeModulePkg/EbcDxe: implement the PE/COFF emulator protocol Date: Sun, 14 Apr 2019 12:52:31 -0700 Message-Id: <20190414195233.30045-6-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190414195233.30045-1-ard.biesheuvel@linaro.org> References: <20190414195233.30045-1-ard.biesheuvel@linaro.org> Implement the new EDK2 PE/COFF image emulator protocol so that we can remove the EBC specific handling in the DXE core and other places in the core code. Signed-off-by: Ard Biesheuvel Reviewed-by: Michael D Kinney --- MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf | 3 + MdeModulePkg/Universal/EbcDxe/EbcDxe.inf | 3 + MdeModulePkg/Universal/EbcDxe/EbcInt.c | 121 +++++++++++++++++++- MdeModulePkg/Universal/EbcDxe/EbcInt.h | 3 + 4 files changed, 126 insertions(+), 4 deletions(-) diff --git a/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf b/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf index 8f293f5c7c29..c7a9d519b080 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf +++ b/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf @@ -89,6 +89,8 @@ BaseMemoryLib DebugLib BaseLib + CacheMaintenanceLib + PeCoffLib [Protocols] gEfiDebugSupportProtocolGuid ## PRODUCES @@ -98,6 +100,7 @@ gEfiEbcSimpleDebuggerProtocolGuid ## SOMETIMES_CONSUMES gEfiPciRootBridgeIoProtocolGuid ## SOMETIMES_CONSUMES gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES + gEdkiiPeCoffImageEmulatorProtocolGuid ## PRODUCES [Guids] gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## GUID diff --git a/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf b/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf index d6ee6194a0c8..ecccf2c57ffe 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf +++ b/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf @@ -57,7 +57,9 @@ MdeModulePkg/MdeModulePkg.dec [LibraryClasses] + CacheMaintenanceLib MemoryAllocationLib + PeCoffLib UefiBootServicesTableLib BaseMemoryLib UefiDriverEntryPoint @@ -68,6 +70,7 @@ [Protocols] gEfiDebugSupportProtocolGuid ## PRODUCES gEfiEbcProtocolGuid ## PRODUCES + gEdkiiPeCoffImageEmulatorProtocolGuid ## PRODUCES gEfiEbcVmTestProtocolGuid ## SOMETIMES_PRODUCES gEfiEbcSimpleDebuggerProtocolGuid ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Universal/EbcDxe/EbcInt.c b/MdeModulePkg/Universal/EbcDxe/EbcInt.c index 727ba8bcae44..3376b5e45184 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcInt.c +++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.c @@ -349,6 +349,119 @@ UINTN mStackNum = 0; EFI_EVENT mEbcPeriodicEvent; VM_CONTEXT *mVmPtr = NULL; +/** + Check whether the emulator supports executing a certain PE/COFF image + + @param[in] This This pointer for EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL + structure + @param[in] ImageType Whether the image is an application, a boot time + driver or a runtime driver. + @param[in] DevicePath Path to device where the image originated + (e.g., a PCI option ROM) + + @retval TRUE The image is supported by the emulator + @retval FALSE The image is not supported by the emulator. +**/ +BOOLEAN +EFIAPI +EbcIsImageSupported ( + IN EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *This, + IN UINT16 ImageType, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL + ) +{ + if (ImageType != EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION && + ImageType != EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) { + return FALSE; + } + return TRUE; +} + +/** + Register a supported PE/COFF image with the emulator. After this call + completes successfully, the PE/COFF image may be started as usual, and + it is the responsibility of the emulator implementation that any branch + into the code section of the image (including returns from functions called + from the foreign code) is executed as if it were running on the machine + type it was built for. + + @param[in] This This pointer for + EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL structure + @param[in] ImageBase The base address in memory of the PE/COFF image + @param[in] ImageSize The size in memory of the PE/COFF image + @param[in,out] EntryPoint The entry point of the PE/COFF image. Passed by + reference so that the emulator may modify it. + + @retval EFI_SUCCESS The image was registered with the emulator and + can be started as usual. + @retval other The image could not be registered. + + If the PE/COFF machine type or image type are not supported by the emulator, + then ASSERT(). +**/ +EFI_STATUS +EFIAPI +EbcRegisterImage ( + IN EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS ImageBase, + IN UINT64 ImageSize, + IN OUT EFI_IMAGE_ENTRY_POINT *EntryPoint + ) +{ + DEBUG_CODE_BEGIN (); + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + EFI_STATUS Status; + + ZeroMem (&ImageContext, sizeof (ImageContext)); + + ImageContext.Handle = (VOID *)(UINTN)ImageBase; + ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; + + Status = PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (ImageContext.Machine == EFI_IMAGE_MACHINE_EBC); + ASSERT (ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION || + ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER); + DEBUG_CODE_END (); + + EbcRegisterICacheFlush (NULL, + (EBC_ICACHE_FLUSH)InvalidateInstructionCacheRange); + + return EbcCreateThunk (NULL, (VOID *)(UINTN)ImageBase, + (VOID *)(UINTN)*EntryPoint, (VOID **)EntryPoint); +} + +/** + Unregister a PE/COFF image that has been registered with the emulator. + This should be done before the image is unloaded from memory. + + @param[in] This This pointer for EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL + structure + @param[in] ImageBase The base address in memory of the PE/COFF image + + @retval EFI_SUCCESS The image was unregistered with the emulator. + @retval other Image could not be unloaded. +**/ +EFI_STATUS +EFIAPI +EbcUnregisterImage ( + IN EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS ImageBase + ) +{ + return EbcUnloadImage (NULL, (VOID *)(UINTN)ImageBase); +} + +STATIC EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL mPeCoffEmuProtocol = { + EbcIsImageSupported, + EbcRegisterImage, + EbcUnregisterImage, + EDKII_PECOFF_IMAGE_EMULATOR_VERSION, + EFI_IMAGE_MACHINE_EBC +}; /** Initializes the VM EFI interface. Allocates memory for the VM interface @@ -437,11 +550,11 @@ InitializeEbcDriver ( // Add the protocol so someone can locate us if we haven't already. // if (!Installed) { - Status = gBS->InstallProtocolInterface ( + Status = gBS->InstallMultipleProtocolInterfaces ( &ImageHandle, - &gEfiEbcProtocolGuid, - EFI_NATIVE_INTERFACE, - EbcProtocol + &gEfiEbcProtocolGuid, EbcProtocol, + &gEdkiiPeCoffImageEmulatorProtocolGuid, &mPeCoffEmuProtocol, + NULL ); if (EFI_ERROR (Status)) { FreePool (EbcProtocol); diff --git a/MdeModulePkg/Universal/EbcDxe/EbcInt.h b/MdeModulePkg/Universal/EbcDxe/EbcInt.h index 8aa7a4abbd63..9b25e91f951c 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcInt.h +++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.h @@ -23,9 +23,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #include +#include #include +#include #include #include #include -- 2.17.1