From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 618EBD80254 for ; Wed, 27 Sep 2023 03:45:45 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=BAetpWuWSReWVnqPI4z9Ir+m4PlAwnHEOnZcS2c5Y68=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:From:To:CC:Subject:Thread-Topic:Thread-Index:Date:Message-ID:References:In-Reply-To:Accept-Language:msip_labels:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Language:Content-Type; s=20140610; t=1695786344; v=1; b=qWe0aFZE+NHQKJ+vhjnToib6GXJCyzuzlUVs4GS4h38NrMj+cHa39/CgcmkNcxdY7q92XFHO qa2kbpUIZwQkRM+b7MroZevdqgcUZC8qnRcW04zvxC97e0aPw/vsoRahN+t32TttBqv/ZVkNJGQ w4Seb3g90iCy9TVd3YQLo+/I= X-Received: by 127.0.0.2 with SMTP id blxeYY7687511xnIAYH8bFNX; Tue, 26 Sep 2023 20:45:44 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.100]) by mx.groups.io with SMTP id smtpd.web10.10031.1695786342670463183 for ; Tue, 26 Sep 2023 20:45:43 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10845"; a="448218107" X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208,217";a="448218107" X-Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Sep 2023 20:45:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.03,179,1694761200"; d="scan'208,217";a="374283" X-Received: from orsmsx602.amr.corp.intel.com ([10.22.229.15]) by fmviesa001.fm.intel.com with ESMTP/TLS/AES256-GCM-SHA384; 26 Sep 2023 20:45:39 -0700 X-Received: from orsmsx612.amr.corp.intel.com (10.22.229.25) by ORSMSX602.amr.corp.intel.com (10.22.229.15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.32; Tue, 26 Sep 2023 20:45:37 -0700 X-Received: from orsmsx610.amr.corp.intel.com (10.22.229.23) by ORSMSX612.amr.corp.intel.com (10.22.229.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.32; Tue, 26 Sep 2023 20:45:36 -0700 X-Received: from ORSEDG602.ED.cps.intel.com (10.7.248.7) by orsmsx610.amr.corp.intel.com (10.22.229.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.32 via Frontend Transport; Tue, 26 Sep 2023 20:45:36 -0700 X-Received: from NAM11-DM6-obe.outbound.protection.outlook.com (104.47.57.175) by edgegateway.intel.com (134.134.137.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.32; Tue, 26 Sep 2023 20:45:36 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=MkJScKomi8dIGJafAY9On41D15ubhDHe8Q6OXsQW/n4nOJpD9ydAbsRcI2kjbB76zFwkwO/r+las16mjlocNdVNiEtToNheb59Oq/yOgpWotUIUSirJs2shhGdl6w8CQoE1DMOh9RegbsHHVA/gqtvcl6/jkOT4g7+ZBLsLzJ8jHLXGb6k2TJiBU71JVkHcFyr2qmi2CikNRORQliihyunHQQshuF1tYUJ+ye1rKfP+VS9oC3otjftHo0+P/vtmni1Fqm0ivbuVe6V1ae4XhvM8LNVfADRM8bG2bxypFL46CrNUkm+5JW0kWp4dEbJaaxN7NJGPneeK+FvqhlyZjww== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=QaMLhOjraGMUyHDMUasL6n5KLMSrpJ92W8Qas1WqrFw=; b=bGye71OCyZesqWl2pmZYwiY8Kls3yVwMmbabHBOJAq7LkRqEW/GEQ6uIH/71hAvi426M5bB6JXgVAPiZK4pHqcgWYX9Qc7VT6hJt5h4pMjZrDWVOcPw8L4T3E3q5r1ZruPUcTv/D8Hs2s4YcLPEF6iMynVBNXeRxXRQ5FFiEBlmquISlkGzqLGaPCEz16IZ0bDVWN0q+AK9q4S3b67V3RLGwtQErKqcZkJ32NRhb5UCe3xJ6rJySsPDBjC+v14f322+bFxh82kbVX2w8NSnM9JstNxM+mglmh1GiWYOnZSObrxgMTRbYnwgXZGFRMZDCtMIMOneC/6xn7wbqh3yOEw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none X-Received: from MN6PR11MB8244.namprd11.prod.outlook.com (2603:10b6:208:470::14) by MW4PR11MB6787.namprd11.prod.outlook.com (2603:10b6:303:209::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.20; Wed, 27 Sep 2023 03:45:33 +0000 X-Received: from MN6PR11MB8244.namprd11.prod.outlook.com ([fe80::a08f:5d:118c:aee1]) by MN6PR11MB8244.namprd11.prod.outlook.com ([fe80::a08f:5d:118c:aee1%4]) with mapi id 15.20.6838.016; Wed, 27 Sep 2023 03:45:32 +0000 From: "Ni, Ray" To: "Desimone, Nathaniel L" , "devel@edk2.groups.io" CC: Andrew Fish , "Kinney, Michael D" , "Chiu, Chasel" Subject: Re: [edk2-devel] [PATCH v1] EmulatorPkg: Fix Source Level Debug on Windows Thread-Topic: [PATCH v1] EmulatorPkg: Fix Source Level Debug on Windows Thread-Index: AQHZ7acX30BF4lZZE0651giOcaH+QrAuB8YX Date: Wed, 27 Sep 2023 03:45:32 +0000 Message-ID: References: <20230922224923.1978-1-nathaniel.l.desimone@intel.com> In-Reply-To: <20230922224923.1978-1-nathaniel.l.desimone@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MN6PR11MB8244:EE_|MW4PR11MB6787:EE_ x-ms-office365-filtering-correlation-id: 65ffdbbc-85ef-481d-d230-08dbbf0c3352 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam-message-info: M/diwtmVg+997sVcRBSOw4hLu+1Ir7bORtjxBhUd9SIQ6WsWucLljSsksUsRijpJXS2mSPVZTNUINT5O5cOR8wm/AiXoEnQ2FQVBddAcXdIf0BaSHCfcK68RujB4MpEk8+KyieG3wf4gGOzJwQSUETCxOmrhDOSOrVrwL8DeDhGKb3BnV2KWer8bvP+ndkrQunj/CgF7M7NYmMlPODOBTkPxpBSWd5iI5E7whu6Pkkf1aoHUkJf8p4jhQBwh4LWXmhXfresDPL9jlKHKL8Vq26fhCyWk5EygQDWU7LcRQfVT3tOcTc/Sx/O6RvdlYRHxL5hVrDVVf2tV2Qz1P6KG0JZTRVak7bvuwcxxT9jmCFAVEc2ZN0NvuIdKvUg/7TaEG13bQ7EoSiQiyE7yGwiMPwqMAbkQHKhp1XGOdpjmeqnhuv2EC6PFvAi92nDxjyzRF5avmGdNoNSZZjrsJJ3vGFIS2uf8hSLy+SoBsYcroZIHGLq1J7UzjOob6txO5vCsyDMz2038cjVTyYsWBhk8EtcUn6d7I9/hifcDRmyu8oYSL14RVM++z8JOE+br8CWgZDfJulMz0/wQOlwu8FOVsVlCL5CT7oix+pTXMze33RkVm+ILkjuD2giGM7Wp/v+Kdie1toYXmbP+5PIQYlAPUA== x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?HPJMGE9jz0XBhOoXCFIq8pLvQJzNScWrcTzdWKXR4jEh5lGZb/x4KkGb0wnw?= =?us-ascii?Q?90Y2GrcYVXVy6XfVLuhFvOSM9/3SFJ8UMQf1Y/rChqzUwsk6BbMr/4oUEPzi?= =?us-ascii?Q?5lt18YQg/YbNNrz5xADKqPF1RioCG6D4JqaiVwi2VtNUvCwPcdypxCM7qY34?= =?us-ascii?Q?PmzcLlXiXXiDs6ecLTycMoMCp51SF2eeqNoMQzNOlAN8kzlCbf6gZyJvUSKe?= =?us-ascii?Q?tsoSsBF/qibWGVW9O/8GKm3wzREFdiWQDQgIjHj2q/L85tfJIcb6kcC9Z2c5?= =?us-ascii?Q?7hqc2i7YpGL8fxq1d9wqjL4BJsnRXCJ7hGSDscKToSXkVNLNEppyUpcaOsqi?= =?us-ascii?Q?KF03V88YWCHogWOaqS+Nm0mpOO4v6a1CnI/h9Lnf/O79XDwLwEEFZHSMEnqG?= =?us-ascii?Q?TYHlmzuU7mG8vyBMXCPexEz9k8z2E8jCHFXY7ZY/tfWxqpar+F60cF1U42k3?= =?us-ascii?Q?XXpMpy8zKzTaGrTXIW+u19ugDo8FhuTv70PYREF6kfTHR43+cqoidBRwVczY?= =?us-ascii?Q?rExLGiscKqXpZJxgIQYpMME31sBdUM/sfxFA3bpchap7w1+oE0GCCatGR8Jx?= =?us-ascii?Q?I3VGZjRbzSFOWQwZLYUwmCFGvFl5YgfYLYCpGLe9ChDOEbZfZ4umdMIlZPqo?= =?us-ascii?Q?kg9G09i3gXnDU37wpz8E+kmb0FC4H+ERJHJ3vX1SIwTeHEERdrpZJZmD706y?= =?us-ascii?Q?z9GxoFtET8kIshviXT3aDb4tNj06VGxIfwgoBXYysfSIxgu91CoPIxQwroU8?= =?us-ascii?Q?d4nYnzy56pIh27RGJqRcas5AT/tKviOaAjpVrcgM/RR86vq+g71uJ2s2BSYO?= =?us-ascii?Q?PbWiftiPpqaw7+gA3Xp4/UDkx19aeesPepc3qN+2y9BOloJRl4rYUvRXmhGY?= =?us-ascii?Q?MgjT4fLyJxPnT902EBDC0h9u4DeIIMBtZvlmoYfXDDmC949I/GFccEmIKFmO?= =?us-ascii?Q?qkeigaHxmNGQKbAKETjfjTwMLreW1PRqNyunR4vSR5913jIerSQsL2Q/2eKn?= =?us-ascii?Q?j/Qo9oKiZaOI23i3PokXTYwJLQeI4L+QHYgfGm9guUIffpBolcGirCG/YBm1?= =?us-ascii?Q?OjZe9Z0HMWORAsmFVUABV+5N4xuCst3bsTCFzPG3zCXSTrwK8vUFN+YRwARu?= =?us-ascii?Q?w2wala+gKI62emx5ZzsUndXpoovEJCTOw0BD8dutWW+HBE0xEvjP25CI3+M0?= =?us-ascii?Q?oR8BvOGPx4RIjnGL6HMsyrARuzsIUgzy4/MGyQokjj5WT2gfh1HCwvURK8lW?= =?us-ascii?Q?oJ/dEw7r2wA2FWMJaC42kchLM2K9bzSfZuSs+jgsllNRNoEV00LIO8ANH8e7?= =?us-ascii?Q?Brv+BIfJYkNlxprI7MVH4OFDdTdNt9zneaBgHPbHUhABN9tiMV1PrugFOEFq?= =?us-ascii?Q?93vrX3ZI6jYlCZoaf5qdUgf+YJsaMi+s/q0wRoulxJJUwm6MgvlDffzoDfTW?= =?us-ascii?Q?IAMWFMym9TaskY9TozoC9jCRdsSiAM+vlqdbT4LsJ2eYriJHq2lIioN50VE/?= =?us-ascii?Q?VwtlU2oG8b4Grqp376qVFyEb+l67334ga5TujveHQ9OeCEPB1Geet1aVQOOi?= =?us-ascii?Q?1jUQc62WMRMz+zWuu34=3D?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MN6PR11MB8244.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 65ffdbbc-85ef-481d-d230-08dbbf0c3352 X-MS-Exchange-CrossTenant-originalarrivaltime: 27 Sep 2023 03:45:32.4232 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: Ta38kBBQDsdN8JtFdAnalNAnMuL09EtjBfPQ+vCRvuVsYop4qCb2vJTSRHg54U6MuwAEu//BtU5bTZixVy4L1g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW4PR11MB6787 X-OriginatorOrg: intel.com Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,ray.ni@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: r2TNhvJHMEfpE6ZsFN23jRtCx7686176AA= Content-Language: en-US Content-Type: multipart/alternative; boundary="_000_MN6PR11MB82445F99611572BC1D9FA1588CC2AMN6PR11MB8244namp_" X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=qWe0aFZE; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none); arc=reject ("signature check failed: fail, {[1] = sig:microsoft.com:reject}") --_000_MN6PR11MB82445F99611572BC1D9FA1588CC2AMN6PR11MB8244namp_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Nate, Thanks for the great patch! Minor comments: 1. Regarding the DllEntryPoint, what's the difference between below line= in your patch and the original code that calls GetProcAddress()? * DllEntryPoint =3D (VOID *) ((UINTN)Library + (UINTN)Hdr.Pe32Plus->= OptionalHeader.AddressOfEntryPoint); 2. Does it avoid relying on each driver exporting its entrypoint with a = fixed symbol name "InitializeDriver"? Does the new DllEntryPoint equal to the original one retrieved from GetProc= Address()? What else benifits? (Just curious) Can it be in a separate patch so that future readers can easily understand = the purpose of the change? 3. It seems the patch assumes the handle returned from LoadLibrary() is = the address of the loaded DLL in memory. I tried to find in MSDN if any doc= supports this assumption but failed. Can you provide any? I am ok if the assumption is based on the current LoadLibrary() implementat= ion. But can you please explicitly mention that assumption in comments? Thanks, Ray ________________________________ From: Desimone, Nathaniel L Sent: Saturday, September 23, 2023 6:49 AM To: devel@edk2.groups.io Cc: Andrew Fish ; Ni, Ray ; Kinney, Mich= ael D ; Chiu, Chasel Subject: [PATCH v1] EmulatorPkg: Fix Source Level Debug on Windows The Visual Studio Windows debugger will only load symbols for PE/COFF image= s that Windows is aware of. Therefore, to enable source level debugging, all PEI/DXE modules must be loaded via LoadLibrary() or LoadLibraryEx() and the the instance in memory created by LoadLibrary() must be the one that is actually executed. The current source level debug implementation in EmulatorPkg for Windows is inherited from the old Nt32Pkg. This implementation makes the assumption th= at all PEI/DXE modules have a DLL export tables with a symbol named InitializeDriver. Therefore, this source level debug implementation require= s all modules to be linked in a non-PI spec defined manner. Support for addin= g the InitializeDriver symbol was removed in EmulatorPkg, which broke source level debugging. To fix this, the source level debugging implementation has been modified to use the PE/COFF entry point directly. This brings the implementation into compliance with the PI spec and should work with any PEIM/DXE driver. Implementing this requires parsing the in-memory instance of the PE/COFF im= age created by Windows to find the entrypoint and since PEIMs/DXE drivers are n= ot garunteed to have 4KB aligned sections, it also requires explicit configura= tion of the page table using VirtualProtect(). With this fix, the debugging experience is now so good it is unprecedented! In Visual Studio Code, add the following to launch.json: { "version": "0.2.0", "configurations": [ { "name": "EmulatorPkg Launch", "type": "cppvsdbg", "request": "launch", "program": "${workspaceFolder}//Build/EmulatorX64/DEBU= G_/X64/WinHost", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}//Build/EmulatorX64/DEBUG_/X64/", "environment": [], "console": false, } ] } Make modifications to the above template as nessesary and build EmulatorPkg= . Now, just add breakpoints directly in Visual Studio Code the way you would = with any other software project. When you start the debugger, it will halt at th= e breakpoint automatically without any extra configuration required. Cc: Andrew Fish Cc: Ray Ni Cc: Michael D Kinney Cc: Chasel Chiu Signed-off-by: Nate DeSimone --- EmulatorPkg/Win/Host/WinHost.c | 206 +++++++++++++++++++++++++++++---- 1 file changed, 182 insertions(+), 24 deletions(-) diff --git a/EmulatorPkg/Win/Host/WinHost.c b/EmulatorPkg/Win/Host/WinHost.= c index 193a947fbd..e414da6c55 100644 --- a/EmulatorPkg/Win/Host/WinHost.c +++ b/EmulatorPkg/Win/Host/WinHost.c @@ -8,7 +8,7 @@ This code produces 128 K of temporary memory for the SEC stack by direct= ly allocate memory space with ReadWrite and Execute attribute. -Copyright (c) 2006 - 2022, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.
(C) Copyright 2016-2020 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -977,7 +977,7 @@ AddModHandle ( for (Index =3D 0; Index < mPdbNameModHandleArraySize; Index++, Array++) = { if (Array->PdbPointer =3D=3D NULL) { // - // Make a copy of the stirng and store the ModHandle + // Make a copy of the string and store the ModHandle // Handle =3D GetProcessHeap (); Size =3D AsciiStrLen (ImageContext->PdbPointer) + 1; @@ -1056,26 +1056,45 @@ RemoveModHandle ( return NULL; } +typedef struct { + UINTN Base; + UINT32 Size; + UINT32 Flags; +} IMAGE_SECTION_DATA; + VOID EFIAPI PeCoffLoaderRelocateImageExtraAction ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext ) { - EFI_STATUS Status; - VOID *DllEntryPoint; - CHAR16 *DllFileName; - HMODULE Library; - UINTN Index; + EFI_STATUS Status; + VOID *DllEntryPoint; + CHAR16 *DllFileName; + HMODULE Library; + UINTN Index; + PE_COFF_LOADER_IMAGE_CONTEXT PeCoffImageContext; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + EFI_IMAGE_SECTION_HEADER *FirstSection; + EFI_IMAGE_SECTION_HEADER *Section; + IMAGE_SECTION_DATA *SectionData; + UINTN NumberOfSections; + UINTN Base; + UINTN End; + UINTN RegionBase; + UINTN RegionSize; + UINT32 Flags; + DWORD NewProtection; + DWORD OldProtection; ASSERT (ImageContext !=3D NULL); // - // If we load our own PE COFF images the Windows debugger can not source - // level debug our code. If a valid PDB pointer exists use it to load - // the *.dll file as a library using Windows* APIs. This allows - // source level debug. The image is still loaded and relocated - // in the Framework memory space like on a real system (by the code abo= ve), - // but the entry point points into the DLL loaded by the code below. + // If we load our own PE/COFF images the Windows debugger can not source + // level debug our code. If a valid PDB pointer exists use it to load + // the *.dll file as a library using Windows* APIs. This allows + // source level debug. The image is still loaded and relocated + // in the Framework memory space like on a real system (by the code abov= e), + // but the entry point points into the DLL loaded by the code below. // DllEntryPoint =3D NULL; @@ -1106,27 +1125,166 @@ PeCoffLoaderRelocateImageExtraAction ( } // - // Replace .PDB with .DLL on the filename + // Replace .PDB with .DLL in the filename // DllFileName[Index - 3] =3D 'D'; DllFileName[Index - 2] =3D 'L'; DllFileName[Index - 1] =3D 'L'; // - // Load the .DLL file into the user process's address space for source - // level debug + // Load the .DLL file into the process's address space for source leve= l + // debug. + // + // EFI modules use the PE32 entry point for a different purpose than + // Windows. For Windows DLLs, the PE entry point is used for the DllMa= in() + // function. DllMain() has a very specific purpose; it initializes run= time + // libraries, instance data, and thread local storage. LoadLibrary()/ + // LoadLibraryEx() will run the PE32 entry point and assume it to be a + // DllMain() implementation by default. By passing the + // DONT_RESOLVE_DLL_REFERENCES argument to LoadLibraryEx(), the execut= ion + // of the entry point as a DllMain() function will be suppressed. This + // also prevents other modules that are referenced by the DLL from bei= ng + // loaded. We use LoadLibraryEx() to create a copy of the PE32 + // image that the OS (and therefore the debugger) is aware of. + // Source level debugging is the only reason to do this. // Library =3D LoadLibraryEx (DllFileName, NULL, DONT_RESOLVE_DLL_REFEREN= CES); if (Library !=3D NULL) { // - // InitializeDriver is the entry point we put in all our EFI DLL's. = The - // DONT_RESOLVE_DLL_REFERENCES argument to LoadLIbraryEx() suppresse= s the - // normal DLL entry point of DllMain, and prevents other modules tha= t are - // referenced in side the DllFileName from being loaded. There is no= error - // checking as the we can point to the PE32 image loaded by Tiano. T= his - // step is only needed for source level debugging + // Parse the PE32 image loaded by the OS and find the entry point // - DllEntryPoint =3D (VOID *)(UINTN)GetProcAddress (Library, "Initializ= eDriver"); + ZeroMem (&PeCoffImageContext, sizeof (PeCoffImageContext)); + PeCoffImageContext.Handle =3D Library; + PeCoffImageContext.ImageRead =3D PeCoffLoaderImageReadFromMemory; + Status =3D PeCoffLoaderGetImageInfo (&PeCoffImageContext); + if (EFI_ERROR (Status) || (PeCoffImageContext.ImageError !=3D IMAGE_= ERROR_SUCCESS)) { + SecPrint ("DLL is not a valid PE/COFF image.\n\r"); + FreeLibrary (Library); + Library =3D NULL; + } else { + Hdr.Pe32 =3D (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Library + (UINTN)Pe= CoffImageContext.PeCoffHeaderOffset); + if (Hdr.Pe32->OptionalHeader.Magic =3D=3D EFI_IMAGE_NT_OPTIONAL_HD= R32_MAGIC) { + // + // Use PE32 offset + // + DllEntryPoint =3D (VOID *) ((UINTN)Library + (UINTN)Hdr.Pe32->Op= tionalHeader.AddressOfEntryPoint); + } else { + // + // Use PE32+ offset + // + DllEntryPoint =3D (VOID *) ((UINTN)Library + (UINTN)Hdr.Pe32Plus= ->OptionalHeader.AddressOfEntryPoint); + } + // + // Now we need to configure memory access for the copy of the PE32= image + // loaded by the OS. + // + // Most Windows DLLs are linked with sections 4KB aligned but EFI + // modules are not to reduce size. Because of this we need to comp= ute + // the union of memory access attributes and explicitly configure + // each page. + // + FirstSection =3D (EFI_IMAGE_SECTION_HEADER *)( + (UINTN)Library + + PeCoffImageContext.PeCoffHeade= rOffset + + sizeof (UINT32) + + sizeof (EFI_IMAGE_FILE_HEADER)= + + Hdr.Pe32->FileHeader.SizeOfOpt= ionalHeader + ); + NumberOfSections =3D (UINTN)(Hdr.Pe32->FileHeader.NumberOfSections= ); + Section =3D FirstSection; + SectionData =3D malloc (NumberOfSections * sizeof (IMAGE_SECTION_D= ATA)); + if (SectionData =3D=3D NULL) { + FreeLibrary (Library); + Library =3D NULL; + DllEntryPoint =3D NULL; + } + ZeroMem (SectionData, NumberOfSections * sizeof (IMAGE_SECTION_DAT= A)); + // + // Extract the section data from the PE32 image + // + for (Index =3D 0; Index < NumberOfSections; Index++) { + SectionData[Index].Base =3D (UINTN)Library + Section->VirtualAdd= ress; + SectionData[Index].Size =3D Section->Misc.VirtualSize; + if (SectionData[Index].Size =3D=3D 0) { + SectionData[Index].Size =3D Section->SizeOfRawData; + } + SectionData[Index].Flags =3D (Section->Characteristics & + (EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMA= GE_SCN_MEM_WRITE)); + Section +=3D 1; + } + // + // Loop over every DWORD in memory and compute the union of the me= mory + // access bits. + // + End =3D (UINTN)Library + (UINTN)PeCoffImageContext.ImageSize; + RegionBase =3D (UINTN)Library; + RegionSize =3D 0; + Flags =3D 0; + for (Base =3D (UINTN)Library + sizeof (UINT32); Base < End; Base += =3D sizeof (UINT32)) { + for (Index =3D 0; Index < NumberOfSections; Index++) { + if (SectionData[Index].Base <=3D Base && + (SectionData[Index].Base + SectionData[Index].Size) > Base= ) { + Flags |=3D SectionData[Index].Flags; + } + } + // + // When a new page is reached configure the memory access for th= e + // previous page. + // + if (Base % SIZE_4KB =3D=3D 0) { + RegionSize +=3D SIZE_4KB; + if ((Flags & EFI_IMAGE_SCN_MEM_WRITE) =3D=3D EFI_IMAGE_SCN_MEM= _WRITE) { + if ((Flags & EFI_IMAGE_SCN_MEM_EXECUTE) =3D=3D EFI_IMAGE_SCN= _MEM_EXECUTE) { + NewProtection =3D PAGE_EXECUTE_READWRITE; + } else { + NewProtection =3D PAGE_READWRITE; + } + } else { + if ((Flags & EFI_IMAGE_SCN_MEM_EXECUTE) =3D=3D EFI_IMAGE_SCN= _MEM_EXECUTE) { + NewProtection =3D PAGE_EXECUTE_READ; + } else { + NewProtection =3D PAGE_READONLY; + } + } + if (!VirtualProtect ((LPVOID)RegionBase, (SIZE_T) RegionSize, = NewProtection, &OldProtection)) { + SecPrint ("Setting PE32 Section Access Failed\n\r"); + FreeLibrary (Library); + free (SectionData); + Library =3D NULL; + DllEntryPoint =3D NULL; + break; + } + Flags =3D 0; + RegionBase =3D Base; + RegionSize =3D 0; + } + } + free (SectionData); + // + // Configure the last partial page + // + if (Library !=3D NULL && (End - RegionBase) > 0) { + if ((Flags & EFI_IMAGE_SCN_MEM_WRITE) =3D=3D EFI_IMAGE_SCN_MEM_W= RITE) { + if ((Flags & EFI_IMAGE_SCN_MEM_EXECUTE) =3D=3D EFI_IMAGE_SCN_M= EM_EXECUTE) { + NewProtection =3D PAGE_EXECUTE_READWRITE; + } else { + NewProtection =3D PAGE_READWRITE; + } + } else { + if ((Flags & EFI_IMAGE_SCN_MEM_EXECUTE) =3D=3D EFI_IMAGE_SCN_M= EM_EXECUTE) { + NewProtection =3D PAGE_EXECUTE_READ; + } else { + NewProtection =3D PAGE_READONLY; + } + } + if (!VirtualProtect ((LPVOID)RegionBase, (SIZE_T) (End - RegionB= ase), NewProtection, &OldProtection)) { + SecPrint ("Setting PE32 Section Access Failed\n\r"); + FreeLibrary (Library); + Library =3D NULL; + DllEntryPoint =3D NULL; + } + } + } } if ((Library !=3D NULL) && (DllEntryPoint !=3D NULL)) { @@ -1142,7 +1300,7 @@ PeCoffLoaderRelocateImageExtraAction ( // This DLL is not already loaded, so source level debugging is su= pported. // ImageContext->EntryPoint =3D (EFI_PHYSICAL_ADDRESS)(UINTN)DllEntry= Point; - SecPrint ("LoadLibraryEx (\n\r %S,\n\r NULL, DONT_RESOLVE_DLL_RE= FERENCES)\n\r", DllFileName); + SecPrint ("LoadLibraryEx (\n\r %S,\n\r NULL, DONT_RESOLVE_DLL_RE= FERENCES) @ 0x%X\n\r", DllFileName, (int) (UINTN) Library); } } else { SecPrint ("WARNING: No source level debug %S. \n\r", DllFileName); -- 2.39.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#109100): https://edk2.groups.io/g/devel/message/109100 Mute This Topic: https://groups.io/mt/101531560/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/19134562= 12/xyzzy [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- --_000_MN6PR11MB82445F99611572BC1D9FA1588CC2AMN6PR11MB8244namp_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable
Nate,

Thanks for the great patch! Minor comments:
  1. Regarding the DllEntr= yPoint, what's the difference between below line in your patch and the orig= inal code that calls GetProcAddress()?
    1. DllEntryPoint =3D (VOID *) ((UINTN)Library + = (UINTN)Hdr.Pe32Plus->OptionalHeader.AddressOfEntryPoint);
  2. Does it avoid relying on each driver exporting its entrypoint with a fixed = symbol name "InitializeDriver"?
    Does the new DllEntryPoint equal to the original one retrieved from GetProcAddr= ess()?
    What else benifits? (Just curious)
    Can it be in a separate patch so that future readers can easily understand = the purpose of the change?
  3. It seems the patch ass= umes the handle returned from LoadLibrary() is the address of the loaded DL= L in memory. I tried to find in MSDN if any doc supports this assumption bu= t failed. Can you provide any?
    I am ok if the assumption = is based on the current LoadLibrary() implementation. But can you please ex= plicitly mention that assumption in comments?

Tha= nks,
Ray

From: Desimone, Nathaniel L= <nathaniel.l.desimone@intel.com>
Sent: Saturday, September 23, 2023 6:49 AM
To: devel@edk2.groups.io <devel@edk2.groups.io>
Cc: Andrew Fish <afish@apple.com>; Ni, Ray <ray.ni@intel.co= m>; Kinney, Michael D <michael.d.kinney@intel.com>; Chiu, Chasel &= lt;chasel.chiu@intel.com>
Subject: [PATCH v1] EmulatorPkg: Fix Source Level Debug on Windows
 
The Visual Studio Windows debugger will only load = symbols for PE/COFF images
that Windows is aware of. Therefore, to enable source level debugging, all<= br> PEI/DXE modules must be loaded via LoadLibrary() or LoadLibraryEx() and the=
the instance in memory created by LoadLibrary() must be the one that is
actually executed.

The current source level debug implementation in EmulatorPkg for Windows is=
inherited from the old Nt32Pkg. This implementation makes the assumption th= at
all PEI/DXE modules have a DLL export tables with a symbol named
InitializeDriver. Therefore, this source level debug implementation require= s
all modules to be linked in a non-PI spec defined manner. Support for addin= g
the InitializeDriver symbol was removed in EmulatorPkg, which broke source<= br> level debugging.

To fix this, the source level debugging implementation has been modified to=
use the PE/COFF entry point directly. This brings the implementation into compliance with the PI spec and should work with any PEIM/DXE driver.
Implementing this requires parsing the in-memory instance of the PE/COFF im= age
created by Windows to find the entrypoint and since PEIMs/DXE drivers are n= ot
garunteed to have 4KB aligned sections, it also requires explicit configura= tion
of the page table using VirtualProtect().

With this fix, the debugging experience is now so good it is unprecedented!=
In Visual Studio Code, add the following to launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "EmulatorPkg Launch&q= uot;,
      "type": "cppvsdbg",
      "request": "launch",
      "program": "${workspaceFolder= }/<path_to_build>/Build/EmulatorX64/DEBUG_<tool_chain>/X64/WinH= ost",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${workspaceFolder}/&l= t;path_to_build>/Build/EmulatorX64/DEBUG_<tool_chain>/X64/",<= br>       "environment": [],
      "console": false,
    }
  ]
}

Make modifications to the above template as nessesary and build EmulatorPkg= .
Now, just add breakpoints directly in Visual Studio Code the way you would = with
any other software project. When you start the debugger, it will halt at th= e
breakpoint automatically without any extra configuration required.

Cc: Andrew Fish <afish@apple.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Signed-off-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
---
 EmulatorPkg/Win/Host/WinHost.c | 206 +++++++++++++++++++++++++++++---= -
 1 file changed, 182 insertions(+), 24 deletions(-)

diff --git a/EmulatorPkg/Win/Host/WinHost.c b/EmulatorPkg/Win/Host/WinHost.= c
index 193a947fbd..e414da6c55 100644
--- a/EmulatorPkg/Win/Host/WinHost.c
+++ b/EmulatorPkg/Win/Host/WinHost.c
@@ -8,7 +8,7 @@
   This code produces 128 K of temporary memory for the SEC stack= by directly
   allocate memory space with ReadWrite and Execute attribute.  
-Copyright (c) 2006 - 2022, Intel Corporation. All rights reserved.<BR&g= t;
+Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.<BR&g= t;
 (C) Copyright 2016-2020 Hewlett Packard Enterprise Development LP<= BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
@@ -977,7 +977,7 @@ AddModHandle (
   for (Index =3D 0; Index < mPdbNameModHandleArraySize; Index= ++, Array++) {
     if (Array->PdbPointer =3D=3D NULL) {
       //
-      // Make a copy of the stirng and store the = ModHandle
+      // Make a copy of the string and store the = ModHandle
       //
       Handle     &n= bsp;      =3D GetProcessHeap ();
       Size     &nbs= p;        =3D AsciiStrLen (ImageContext-= >PdbPointer) + 1;
@@ -1056,26 +1056,45 @@ RemoveModHandle (
   return NULL;
 }
 
+typedef struct {
+  UINTN   Base;
+  UINT32  Size;
+  UINT32  Flags;
+} IMAGE_SECTION_DATA;
+
 VOID
 EFIAPI
 PeCoffLoaderRelocateImageExtraAction (
   IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
   )
 {
-  EFI_STATUS  Status;
-  VOID        *DllEntryPoint;
-  CHAR16      *DllFileName;
-  HMODULE     Library;
-  UINTN       Index;
+  EFI_STATUS         &nb= sp;            =     Status;
+  VOID          &nb= sp;            =          *DllEntryPoint;
+  CHAR16          &= nbsp;           &nbs= p;       *DllFileName;
+  HMODULE          =             &nb= sp;      Library;
+  UINTN          &n= bsp;            = ;        Index;
+  PE_COFF_LOADER_IMAGE_CONTEXT      &nb= sp; PeCoffImageContext;
+  EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
+  EFI_IMAGE_SECTION_HEADER       &= nbsp;    *FirstSection;
+  EFI_IMAGE_SECTION_HEADER       &= nbsp;    *Section;
+  IMAGE_SECTION_DATA        &= nbsp;         *SectionData;
+  UINTN          &n= bsp;            = ;        NumberOfSections;
+  UINTN          &n= bsp;            = ;        Base;
+  UINTN          &n= bsp;            = ;        End;
+  UINTN          &n= bsp;            = ;        RegionBase;
+  UINTN          &n= bsp;            = ;        RegionSize;
+  UINT32          &= nbsp;           &nbs= p;       Flags;
+  DWORD          &n= bsp;            = ;        NewProtection;
+  DWORD          &n= bsp;            = ;        OldProtection;
 
   ASSERT (ImageContext !=3D NULL);
   //
-  // If we load our own PE COFF images the Windows debugger can not s= ource
-  //  level debug our code. If a valid PDB pointer exists use it= to load
-  //  the *.dll file as a library using Windows* APIs. This allo= ws
-  //  source level debug. The image is still loaded and relocate= d
-  //  in the Framework memory space like on a real system (by th= e code above),
-  //  but the entry point points into the DLL loaded by the code= below.
+  // If we load our own PE/COFF images the Windows debugger can not s= ource
+  // level debug our code. If a valid PDB pointer exists use it to lo= ad
+  // the *.dll file as a library using Windows* APIs. This allows
+  // source level debug. The image is still loaded and relocated
+  // in the Framework memory space like on a real system (by the code= above),
+  // but the entry point points into the DLL loaded by the code below= .
   //
 
   DllEntryPoint =3D NULL;
@@ -1106,27 +1125,166 @@ PeCoffLoaderRelocateImageExtraAction (
     }
 
     //
-    // Replace .PDB with .DLL on the filename
+    // Replace .PDB with .DLL in the filename
     //
     DllFileName[Index - 3] =3D 'D';
     DllFileName[Index - 2] =3D 'L';
     DllFileName[Index - 1] =3D 'L';
 
     //
-    // Load the .DLL file into the user process's address s= pace for source
-    // level debug
+    // Load the .DLL file into the process's address space = for source level
+    // debug.
+    //
+    // EFI modules use the PE32 entry point for a different= purpose than
+    // Windows. For Windows DLLs, the PE entry point is use= d for the DllMain()
+    // function. DllMain() has a very specific purpose; it = initializes runtime
+    // libraries, instance data, and thread local storage. = LoadLibrary()/
+    // LoadLibraryEx() will run the PE32 entry point and as= sume it to be a
+    // DllMain() implementation by default. By passing the<= br> +    // DONT_RESOLVE_DLL_REFERENCES argument to LoadLibraryE= x(), the execution
+    // of the entry point as a DllMain() function will be s= uppressed. This
+    // also prevents other modules that are referenced by t= he DLL from being
+    // loaded. We use LoadLibraryEx() to create a copy of t= he PE32
+    // image that the OS (and therefore the debugger) is aw= are of.
+    // Source level debugging is the only reason to do this= .
     //
     Library =3D LoadLibraryEx (DllFileName, NULL, DONT= _RESOLVE_DLL_REFERENCES);
     if (Library !=3D NULL) {
       //
-      // InitializeDriver is the entry point we p= ut in all our EFI DLL's. The
-      // DONT_RESOLVE_DLL_REFERENCES argument to = LoadLIbraryEx() suppresses the
-      // normal DLL entry point of DllMain, and p= revents other modules that are
-      // referenced in side the DllFileName from = being loaded. There is no error
-      // checking as the we can point to the PE32= image loaded by Tiano. This
-      // step is only needed for source level deb= ugging
+      // Parse the PE32 image loaded by the OS an= d find the entry point
       //
-      DllEntryPoint =3D (VOID *)(UINTN)GetProcAdd= ress (Library, "InitializeDriver");
+      ZeroMem (&PeCoffImageContext, sizeof (P= eCoffImageContext));
+      PeCoffImageContext.Handle =3D Library;
+      PeCoffImageContext.ImageRead =3D PeCoffLoad= erImageReadFromMemory;
+      Status =3D PeCoffLoaderGetImageInfo (&P= eCoffImageContext);
+      if (EFI_ERROR (Status) || (PeCoffImageConte= xt.ImageError !=3D IMAGE_ERROR_SUCCESS)) {
+        SecPrint ("DLL is not a va= lid PE/COFF image.\n\r");
+        FreeLibrary (Library);
+        Library =3D NULL;
+      } else {
+        Hdr.Pe32 =3D (EFI_IMAGE_NT_HEAD= ERS32 *)((UINTN)Library + (UINTN)PeCoffImageContext.PeCoffHeaderOffset); +        if (Hdr.Pe32->OptionalHeader= .Magic =3D=3D EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+          //
+          // Use PE32 offset<= br> +          //
+          DllEntryPoint =3D (= VOID *) ((UINTN)Library + (UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntry= Point);
+        } else {
+          //
+          // Use PE32+ offset=
+          //
+          DllEntryPoint =3D (= VOID *) ((UINTN)Library + (UINTN)Hdr.Pe32Plus->OptionalHeader.AddressOfE= ntryPoint);
+        }
+        //
+        // Now we need to configure mem= ory access for the copy of the PE32 image
+        // loaded by the OS.
+        //
+        // Most Windows DLLs are linked= with sections 4KB aligned but EFI
+        // modules are not to reduce si= ze. Because of this we need to compute
+        // the union of memory access a= ttributes and explicitly configure
+        // each page.
+        //
+        FirstSection =3D (EFI_IMAGE_SEC= TION_HEADER *)(
+            &n= bsp;            = ;            &n= bsp;      (UINTN)Library +
+            &n= bsp;            = ;            &n= bsp;      PeCoffImageContext.PeCoffHeaderOffset +<= br> +            &n= bsp;            = ;            &n= bsp;      sizeof (UINT32) +
+            &n= bsp;            = ;            &n= bsp;      sizeof (EFI_IMAGE_FILE_HEADER) +
+            &n= bsp;            = ;            &n= bsp;      Hdr.Pe32->FileHeader.SizeOfOptionalHe= ader
+            &n= bsp;            = ;            &n= bsp;      );
+        NumberOfSections =3D (UINTN)(Hd= r.Pe32->FileHeader.NumberOfSections);
+        Section =3D FirstSection;
+        SectionData =3D malloc (NumberO= fSections * sizeof (IMAGE_SECTION_DATA));
+        if (SectionData =3D=3D NULL) {<= br> +          FreeLibrary (Librar= y);
+          Library =3D NULL; +          DllEntryPoint =3D N= ULL;
+        }
+        ZeroMem (SectionData, NumberOfS= ections * sizeof (IMAGE_SECTION_DATA));
+        //
+        // Extract the section data fro= m the PE32 image
+        //
+        for (Index =3D 0; Index < Nu= mberOfSections; Index++) {
+          SectionData[Index].= Base =3D (UINTN)Library + Section->VirtualAddress;
+          SectionData[Index].= Size =3D Section->Misc.VirtualSize;
+          if (SectionData[Ind= ex].Size =3D=3D 0) {
+            Section= Data[Index].Size =3D Section->SizeOfRawData;
+          }
+          SectionData[Index].= Flags =3D (Section->Characteristics &
+            &n= bsp;            = ;             (= EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_MEM_WRITE));
+          Section +=3D 1;
+        }
+        //
+        // Loop over every DWORD in mem= ory and compute the union of the memory
+        // access bits.
+        //
+        End =3D (UINTN)Library + (UINTN= )PeCoffImageContext.ImageSize;
+        RegionBase =3D (UINTN)Library;<= br> +        RegionSize =3D 0;
+        Flags =3D 0;
+        for (Base =3D (UINTN)Library + = sizeof (UINT32); Base < End; Base +=3D sizeof (UINT32)) {
+          for (Index =3D 0; I= ndex < NumberOfSections; Index++) {
+            if (Sec= tionData[Index].Base <=3D Base &&
+            &n= bsp;   (SectionData[Index].Base + SectionData[Index].Size) > B= ase) {
+            &n= bsp; Flags |=3D SectionData[Index].Flags;
+            }
+          }
+          //
+          // When a new page = is reached configure the memory access for the
+          // previous page. +          //
+          if (Base % SIZE_4KB= =3D=3D 0) {
+            RegionS= ize +=3D SIZE_4KB;
+            if ((Fl= ags & EFI_IMAGE_SCN_MEM_WRITE) =3D=3D EFI_IMAGE_SCN_MEM_WRITE) {
+            &n= bsp; if ((Flags & EFI_IMAGE_SCN_MEM_EXECUTE) =3D=3D EFI_IMAGE_SCN_MEM_E= XECUTE) {
+            &n= bsp;   NewProtection =3D PAGE_EXECUTE_READWRITE;
+            &n= bsp; } else {
+            &n= bsp;   NewProtection =3D PAGE_READWRITE;
+            &n= bsp; }
+            } else = {
+            &n= bsp; if ((Flags & EFI_IMAGE_SCN_MEM_EXECUTE) =3D=3D EFI_IMAGE_SCN_MEM_E= XECUTE) {
+            &n= bsp;   NewProtection =3D PAGE_EXECUTE_READ;
+            &n= bsp; } else {
+            &n= bsp;   NewProtection =3D PAGE_READONLY;
+            &n= bsp; }
+            }
+            if (!Vi= rtualProtect ((LPVOID)RegionBase, (SIZE_T) RegionSize, NewProtection, &= OldProtection)) {
+            &n= bsp; SecPrint ("Setting PE32 Section Access Failed\n\r");
+            &n= bsp; FreeLibrary (Library);
+            &n= bsp; free (SectionData);
+            &n= bsp; Library =3D NULL;
+            &n= bsp; DllEntryPoint =3D NULL;
+            &n= bsp; break;
+            }
+            Flags = =3D 0;
+            RegionB= ase =3D Base;
+            RegionS= ize =3D 0;
+          }
+        }
+        free (SectionData);
+        //
+        // Configure the last partial p= age
+        //
+        if (Library !=3D NULL &&= ; (End - RegionBase) > 0) {
+          if ((Flags & EF= I_IMAGE_SCN_MEM_WRITE) =3D=3D EFI_IMAGE_SCN_MEM_WRITE) {
+            if ((Fl= ags & EFI_IMAGE_SCN_MEM_EXECUTE) =3D=3D EFI_IMAGE_SCN_MEM_EXECUTE) { +            &n= bsp; NewProtection =3D PAGE_EXECUTE_READWRITE;
+            } else = {
+            &n= bsp; NewProtection =3D PAGE_READWRITE;
+            }
+          } else {
+            if ((Fl= ags & EFI_IMAGE_SCN_MEM_EXECUTE) =3D=3D EFI_IMAGE_SCN_MEM_EXECUTE) { +            &n= bsp; NewProtection =3D PAGE_EXECUTE_READ;
+            } else = {
+            &n= bsp; NewProtection =3D PAGE_READONLY;
+            }
+          }
+          if (!VirtualProtect= ((LPVOID)RegionBase, (SIZE_T) (End - RegionBase), NewProtection, &OldP= rotection)) {
+            SecPrin= t ("Setting PE32 Section Access Failed\n\r");
+            FreeLib= rary (Library);
+            Library= =3D NULL;
+            DllEntr= yPoint =3D NULL;
+          }
+        }
+      }
     }
 
     if ((Library !=3D NULL) && (DllEntryPoint = !=3D NULL)) {
@@ -1142,7 +1300,7 @@ PeCoffLoaderRelocateImageExtraAction (
         // This DLL is not already= loaded, so source level debugging is supported.
         //
         ImageContext->EntryPoin= t =3D (EFI_PHYSICAL_ADDRESS)(UINTN)DllEntryPoint;
-        SecPrint ("LoadLibraryEx (= \n\r  %S,\n\r  NULL, DONT_RESOLVE_DLL_REFERENCES)\n\r", DllF= ileName);
+        SecPrint ("LoadLibraryEx (= \n\r  %S,\n\r  NULL, DONT_RESOLVE_DLL_REFERENCES) @ 0x%X\n\r"= ;, DllFileName, (int) (UINTN) Library);
       }
     } else {
       SecPrint ("WARNING: No source lev= el debug %S. \n\r", DllFileName);
--
2.39.2.windows.1

_._,_._,_

Groups.io Links:

=20 You receive all messages sent to this group. =20 =20

View/Reply Online (#109100) | =20 | Mute= This Topic | New Topic
Your Subscriptio= n | Contact Group Owner | Unsubscribe [rebecca@openfw.io]

_._,_._,_
--_000_MN6PR11MB82445F99611572BC1D9FA1588CC2AMN6PR11MB8244namp_--