From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.126, mailfrom: michael.d.kinney@intel.com) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by groups.io with SMTP; Wed, 10 Apr 2019 23:20:40 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 10 Apr 2019 23:20:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,336,1549958400"; d="scan'208";a="160662092" Received: from orsmsx103.amr.corp.intel.com ([10.22.225.130]) by fmsmga004.fm.intel.com with ESMTP; 10 Apr 2019 23:20:39 -0700 Received: from orsmsx121.amr.corp.intel.com (10.22.225.226) by ORSMSX103.amr.corp.intel.com (10.22.225.130) with Microsoft SMTP Server (TLS) id 14.3.408.0; Wed, 10 Apr 2019 23:20:38 -0700 Received: from orsmsx113.amr.corp.intel.com ([169.254.9.24]) by ORSMSX121.amr.corp.intel.com ([169.254.10.219]) with mapi id 14.03.0415.000; Wed, 10 Apr 2019 23:20:39 -0700 From: "Michael D Kinney" To: Ard Biesheuvel , "devel@edk2.groups.io" CC: "Zimmer, Vincent" , "Richardson, Brian" , Andrew Fish , Leif Lindholm , "Zeng, Star" , "Dong, Eric" , "Ni, Ray" , "Gao, Liming" , "Carsey, Jaben" , "Shi, Steven" Subject: Re: [PATCH v4 2/7] MdeModulePkg/DxeCore: invoke the emulator protocol for foreign images Thread-Topic: [PATCH v4 2/7] MdeModulePkg/DxeCore: invoke the emulator protocol for foreign images Thread-Index: AQHU6DrVwloA5TO11UCiPaRRbalqcKY2jHOA Date: Thu, 11 Apr 2019 06:20:38 +0000 Message-ID: References: <20190401032709.14787-1-ard.biesheuvel@linaro.org> <20190401032709.14787-3-ard.biesheuvel@linaro.org> In-Reply-To: <20190401032709.14787-3-ard.biesheuvel@linaro.org> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.0.600.7 dlp-reaction: no-action x-originating-ip: [10.22.254.139] MIME-Version: 1.0 Return-Path: michael.d.kinney@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Ard, Resend to devel@edk2.groups.io One comment below on a logic issue that would be exposed=20 if multiple emulators are present. Mike > -----Original Message----- > From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org] > Sent: Sunday, March 31, 2019 8:27 PM > To: edk2-devel@lists.01.org > Cc: Ard Biesheuvel ; Zimmer, > Vincent ; Richardson, Brian > ; Kinney, Michael D > ; Andrew Fish > ; Leif Lindholm > ; Zeng, Star > ; Dong, Eric > ; Ni, Ray ; Gao, > Liming ; Carsey, Jaben > ; Shi, Steven > > Subject: [PATCH v4 2/7] MdeModulePkg/DxeCore: invoke > the emulator protocol for foreign images >=20 > When encountering PE/COFF images that cannot be > supported natively, > attempt to locate an instance of the PE/COFF image > emulator protocol, > and if it supports the image, proceed with loading it > and register it > with the emulator. >=20 > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ard Biesheuvel > > --- > MdeModulePkg/Core/Dxe/DxeMain.h | 3 + > MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + > MdeModulePkg/Core/Dxe/Image/Image.c | 144 > ++++++++++++++++++-- > 3 files changed, 137 insertions(+), 11 deletions(-) >=20 > diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h > b/MdeModulePkg/Core/Dxe/DxeMain.h > index 2dec9da5e35b..48ec30a48aa2 100644 > --- a/MdeModulePkg/Core/Dxe/DxeMain.h > +++ b/MdeModulePkg/Core/Dxe/DxeMain.h > @@ -53,6 +53,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS > OF ANY KIND, EITHER EXPRESS OR IMPLIED. > #include > #include > #include > +#include > #include > #include > #include > @@ -228,6 +229,8 @@ typedef struct { > UINT16 Machine; > /// EBC Protocol pointer > EFI_EBC_PROTOCOL *Ebc; > + /// PE/COFF Image Emulator Protocol pointer > + EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *PeCoffEmu; > /// Runtime image list > EFI_RUNTIME_IMAGE_ENTRY *RuntimeData; > /// Pointer to Loaded Image Device Path Protocol > diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf > b/MdeModulePkg/Core/Dxe/DxeMain.inf > index 10375443c0f4..ce6fc19be5e4 100644 > --- a/MdeModulePkg/Core/Dxe/DxeMain.inf > +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf > @@ -162,6 +162,7 @@ > gEfiHiiPackageListProtocolGuid ## > SOMETIMES_PRODUCES > gEfiEbcProtocolGuid ## > SOMETIMES_CONSUMES > gEfiSmmBase2ProtocolGuid ## > SOMETIMES_CONSUMES > + gEdkiiPeCoffImageEmulatorProtocolGuid ## > SOMETIMES_CONSUMES >=20 > # Arch Protocols > gEfiBdsArchProtocolGuid ## > CONSUMES > diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c > b/MdeModulePkg/Core/Dxe/Image/Image.c > index eddca140ee1a..cda447d23ec5 100644 > --- a/MdeModulePkg/Core/Dxe/Image/Image.c > +++ b/MdeModulePkg/Core/Dxe/Image/Image.c > @@ -29,6 +29,15 @@ LOAD_PE32_IMAGE_PRIVATE_DATA > mLoadPe32PrivateData =3D { > } > }; >=20 > +typedef struct { > + LIST_ENTRY Link; > + EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL *Emulator; > + UINT16 MachineType; > +} EMULATOR_ENTRY; > + > +STATIC LIST_ENTRY > mAvailableEmulators; > +STATIC EFI_EVENT > mPeCoffEmuProtocolRegistrationEvent; > +STATIC VOID > *mPeCoffEmuProtocolNotifyRegistration; >=20 > // > // This code is needed to build the Image handle for > the DXE Core > @@ -67,6 +76,7 @@ LOADED_IMAGE_PRIVATE_DATA > mCorePrivateImage =3D { > NULL, // JumpContext > 0, // Machine > NULL, // Ebc > + NULL, // PeCoffEmu > NULL, // RuntimeData > NULL // LoadedImageDevicePath > }; > @@ -118,6 +128,39 @@ GetMachineTypeName ( > return L""; > } >=20 > +/** > + Notification event handler registered by > CoreInitializeImageServices () to > + keep track of which PE/COFF image emulators are > available. > + > + @param Event The Event that is being > processed, not used. > + @param Context Event Context, not used. > + > +**/ > +STATIC > +VOID > +EFIAPI > +PeCoffEmuProtocolNotify ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + EFI_STATUS Status; > + EMULATOR_ENTRY *Entry; > + > + Entry =3D AllocateZeroPool (sizeof *Entry); > + ASSERT (Entry !=3D NULL); > + > + Status =3D CoreLocateProtocol > (&gEdkiiPeCoffImageEmulatorProtocolGuid, > + > mPeCoffEmuProtocolNotifyRegistration, > + (VOID **)&Entry- > >Emulator > + ); A protocol notification function that only expects a single instance of the protocol can use LocateProtocol(). However, this use case needs to support one or more Emu Protocol=20 instances and add each of them to the linked list. So the function LocateHandle() should be used with ByRegisterNotify to make sure the handle with the installation of the specific protocol instance is located. Then HandleProtocol() can be used on that handle to get the protocol instance. There is another example of this in the DXE Core in the file Dispatcher.c, function CoreFwVolEventProtocolNotify(). It call CoreLocateHandle() to get the handle. Status =3D CoreLocateHandle ( ByRegisterNotify, NULL, mFwVolEventRegistration, &BufferSize, &FvHandle ); Then calls CoreHandleProtocol() to get the protocol instance. Status =3D CoreHandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGu= id, (VOID **)&Fv); > + ASSERT_EFI_ERROR (Status); > + > + Entry->MachineType =3D Entry->Emulator->MachineType; > + > + InsertTailList (&mAvailableEmulators, &Entry->Link); > +} > + > /** > Add the Image Services to EFI Boot Services Table > and install the protocol > interfaces for this image. > @@ -192,6 +235,30 @@ CoreInitializeImageServices ( > gDxeCoreImageHandle =3D Image->Handle; > gDxeCoreLoadedImage =3D &Image->Info; >=20 > + // > + // Create the PE/COFF emulator protocol registration > event > + // > + Status =3D CoreCreateEvent ( > + EVT_NOTIFY_SIGNAL, > + TPL_CALLBACK, > + PeCoffEmuProtocolNotify, > + NULL, > + &mPeCoffEmuProtocolRegistrationEvent > + ); > + ASSERT_EFI_ERROR(Status); > + > + // > + // Register for protocol notifications on this event > + // > + Status =3D CoreRegisterProtocolNotify ( > + &gEdkiiPeCoffImageEmulatorProtocolGuid, > + mPeCoffEmuProtocolRegistrationEvent, > + &mPeCoffEmuProtocolNotifyRegistration > + ); > + ASSERT_EFI_ERROR(Status); > + > + InitializeListHead (&mAvailableEmulators); > + > if (FeaturePcdGet > (PcdFrameworkCompatibilitySupport)) { > // > // Export DXE Core PE Loader functionality for > backward compatibility. > @@ -425,6 +492,45 @@ > GetPeCoffImageFixLoadingAssignedAddress( > DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE > FIXED INFO: Loading module at fixed address 0x%11p. > Status =3D %r \n", (VOID *)(UINTN)(ImageContext- > >ImageAddress), Status)); > return Status; > } > + > +/** > + Decides whether a PE/COFF image can execute on this > system, either natively > + or via emulation/interpretation. In that latter > case, the PeCoffEmu member > + of the LOADED_IMAGE_PRIVATE_DATA struct pointer is > populated with a pointer > + to the emulator protocol that supports this image. > + > + @param[in] Image LOADED_IMAGE_PRIVATE_DATA > struct pointer > +**/ > +STATIC > +BOOLEAN > +CoreIsImageTypeSupported ( > + IN OUT LOADED_IMAGE_PRIVATE_DATA *Image > + ) > +{ > + LIST_ENTRY *Link; > + EMULATOR_ENTRY *Entry; > + > + for (Link =3D GetFirstNode (&mAvailableEmulators); > + !IsNull (&mAvailableEmulators, Link); > + Link =3D GetNextNode (&mAvailableEmulators, > Link)) { > + > + Entry =3D BASE_CR (Link, EMULATOR_ENTRY, Link); > + if (Entry->MachineType !=3D Image- > >ImageContext.Machine) { > + continue; > + } > + > + if (Entry->Emulator->IsImageSupported (Entry- > >Emulator, > + Image- > >ImageContext.ImageType, > + Image->Info.FilePath)) { > + Image->PeCoffEmu =3D Entry->Emulator; > + return TRUE; > + } > + } > + > + return EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image- > >ImageContext.Machine) || > + EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED > (Image->ImageContext.Machine); > +} > + > /** > Loads, relocates, and invokes a PE/COFF image >=20 > @@ -473,16 +579,14 @@ CoreLoadPeImage ( > return Status; > } >=20 > - if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image- > >ImageContext.Machine)) { > - if (!EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED > (Image->ImageContext.Machine)) { > - // > - // The PE/COFF loader can support loading image > types that can be executed. > - // If we loaded an image type that we can not > execute return EFI_UNSUPORTED. > - // > - DEBUG ((EFI_D_ERROR, "Image type %s can't be > loaded ", GetMachineTypeName(Image- > >ImageContext.Machine))); > - DEBUG ((EFI_D_ERROR, "on %s UEFI system.\n", > GetMachineTypeName(mDxeCoreImageMachineType))); > - return EFI_UNSUPPORTED; > - } > + if (!CoreIsImageTypeSupported (Image)) { > + // > + // The PE/COFF loader can support loading image > types that can be executed. > + // If we loaded an image type that we can not > execute return EFI_UNSUPORTED. > + // > + DEBUG ((EFI_D_ERROR, "Image type %s can't be > loaded ", GetMachineTypeName(Image- > >ImageContext.Machine))); > + DEBUG ((EFI_D_ERROR, "on %s UEFI system.\n", > GetMachineTypeName(mDxeCoreImageMachineType))); > + return EFI_UNSUPPORTED; > } >=20 > // > @@ -687,6 +791,16 @@ CoreLoadPeImage ( > if (EFI_ERROR(Status)) { > goto Done; > } > + } else if (Image->PeCoffEmu !=3D NULL) { > + Status =3D Image->PeCoffEmu->RegisterImage (Image- > >PeCoffEmu, > + Image->ImageBasePage, > + EFI_PAGES_TO_SIZE > (Image->NumberOfPages), > + &Image->EntryPoint); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_LOAD | DEBUG_ERROR, > + "CoreLoadPeImage: Failed to register foreign > image with emulator.\n")); > + goto Done; > + } > } >=20 > // > @@ -874,6 +988,13 @@ CoreUnloadAndCloseImage ( > Image->Ebc->UnloadImage (Image->Ebc, Image- > >Handle); > } >=20 > + if (Image->PeCoffEmu !=3D NULL) { > + // > + // If the PE/COFF Emulator protocol exists we must > unregister the image. > + // > + Image->PeCoffEmu->UnregisterImage (Image- > >PeCoffEmu, Image->ImageBasePage); > + } > + > // > // Unload image, free Image->ImageContext->ModHandle > // > @@ -1599,7 +1720,8 @@ CoreStartImage ( > // > // The image to be started must have the machine > type supported by DxeCore. > // > - if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image- > >Machine)) { > + if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image- > >Machine) && > + Image->PeCoffEmu =3D=3D NULL) { > // > // Do not ASSERT here, because image might be > loaded via EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED > // But it can not be started. > -- > 2.17.1