From 0f4eb39d08a19b58886134c0f26e12af79dede6a Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 22 Jul 2024 11:46:22 +0300 Subject: [PATCH 001/341] Ext4Pkg: Add EDK II Ext4 package Adds a Pedro Falcato's UEFI EXT4 filesystem driver that implements the EFI_FILE_PROTOCOL and EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. Signed-off-by: Savva Mitrofanov --- Ext4Pkg/Ext4.dsc.inc | 16 + Ext4Pkg/Ext4.fdf.inc | 11 + Ext4Pkg/Ext4Components.dsc.inc | 14 + Ext4Pkg/Ext4Defines.dsc.inc | 14 + Ext4Pkg/Ext4Dxe/BlockGroup.c | 229 ++++++ Ext4Pkg/Ext4Dxe/BlockMap.c | 285 ++++++++ Ext4Pkg/Ext4Dxe/Collation.c | 195 +++++ Ext4Pkg/Ext4Dxe/Directory.c | 708 ++++++++++++++++++ Ext4Pkg/Ext4Dxe/DiskUtil.c | 123 ++++ Ext4Pkg/Ext4Dxe/Ext4Disk.h | 501 +++++++++++++ Ext4Pkg/Ext4Dxe/Ext4Dxe.c | 847 +++++++++++++++++++++ Ext4Pkg/Ext4Dxe/Ext4Dxe.h | 1255 ++++++++++++++++++++++++++++++++ Ext4Pkg/Ext4Dxe/Ext4Dxe.inf | 149 ++++ Ext4Pkg/Ext4Dxe/Ext4Dxe.uni | 15 + Ext4Pkg/Ext4Dxe/Extents.c | 658 +++++++++++++++++ Ext4Pkg/Ext4Dxe/File.c | 1012 +++++++++++++++++++++++++ Ext4Pkg/Ext4Dxe/Inode.c | 490 +++++++++++++ Ext4Pkg/Ext4Dxe/Partition.c | 132 ++++ Ext4Pkg/Ext4Dxe/Superblock.c | 363 +++++++++ Ext4Pkg/Ext4Dxe/Symlink.c | 261 +++++++ Ext4Pkg/Ext4Libs.dsc.inc | 11 + Ext4Pkg/Ext4Pkg.dec | 17 + Ext4Pkg/Ext4Pkg.dsc | 75 ++ Ext4Pkg/Ext4Pkg.uni | 14 + 24 files changed, 7395 insertions(+) create mode 100644 Ext4Pkg/Ext4.dsc.inc create mode 100644 Ext4Pkg/Ext4.fdf.inc create mode 100644 Ext4Pkg/Ext4Components.dsc.inc create mode 100644 Ext4Pkg/Ext4Defines.dsc.inc create mode 100644 Ext4Pkg/Ext4Dxe/BlockGroup.c create mode 100644 Ext4Pkg/Ext4Dxe/BlockMap.c create mode 100644 Ext4Pkg/Ext4Dxe/Collation.c create mode 100644 Ext4Pkg/Ext4Dxe/Directory.c create mode 100644 Ext4Pkg/Ext4Dxe/DiskUtil.c create mode 100644 Ext4Pkg/Ext4Dxe/Ext4Disk.h create mode 100644 Ext4Pkg/Ext4Dxe/Ext4Dxe.c create mode 100644 Ext4Pkg/Ext4Dxe/Ext4Dxe.h create mode 100644 Ext4Pkg/Ext4Dxe/Ext4Dxe.inf create mode 100644 Ext4Pkg/Ext4Dxe/Ext4Dxe.uni create mode 100644 Ext4Pkg/Ext4Dxe/Extents.c create mode 100644 Ext4Pkg/Ext4Dxe/File.c create mode 100644 Ext4Pkg/Ext4Dxe/Inode.c create mode 100644 Ext4Pkg/Ext4Dxe/Partition.c create mode 100644 Ext4Pkg/Ext4Dxe/Superblock.c create mode 100644 Ext4Pkg/Ext4Dxe/Symlink.c create mode 100644 Ext4Pkg/Ext4Libs.dsc.inc create mode 100644 Ext4Pkg/Ext4Pkg.dec create mode 100644 Ext4Pkg/Ext4Pkg.dsc create mode 100644 Ext4Pkg/Ext4Pkg.uni diff --git a/Ext4Pkg/Ext4.dsc.inc b/Ext4Pkg/Ext4.dsc.inc new file mode 100644 index 0000000000..c060cb6687 --- /dev/null +++ b/Ext4Pkg/Ext4.dsc.inc @@ -0,0 +1,16 @@ +## @file +# Ext4 DSC include file for Platform DSC +# +# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] +!include Ext4Pkg/Ext4Defines.dsc.inc + +[LibraryClasses] +!include Ext4Pkg/Ext4Libs.dsc.inc + +[Components.common] +!include Ext4Pkg/Ext4Components.dsc.inc diff --git a/Ext4Pkg/Ext4.fdf.inc b/Ext4Pkg/Ext4.fdf.inc new file mode 100644 index 0000000000..ae3ee60938 --- /dev/null +++ b/Ext4Pkg/Ext4.fdf.inc @@ -0,0 +1,11 @@ +## @file +# Ext4 FDF include file for All Architectures. +# +# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +!if $(EXT4_ENABLE) == TRUE + INF Ext4Pkg/Ext4Dxe/Ext4Dxe.inf +!endif diff --git a/Ext4Pkg/Ext4Components.dsc.inc b/Ext4Pkg/Ext4Components.dsc.inc new file mode 100644 index 0000000000..853b35312b --- /dev/null +++ b/Ext4Pkg/Ext4Components.dsc.inc @@ -0,0 +1,14 @@ +## @file +# Ext4 DSC include file for [Components] section of all Architectures. +# +# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +!if $(EXT4_ENABLE) == TRUE + Ext4Pkg/Ext4Dxe/Ext4Dxe.inf { + + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000007 + } +!endif diff --git a/Ext4Pkg/Ext4Defines.dsc.inc b/Ext4Pkg/Ext4Defines.dsc.inc new file mode 100644 index 0000000000..b02eac59cf --- /dev/null +++ b/Ext4Pkg/Ext4Defines.dsc.inc @@ -0,0 +1,14 @@ +## @file +# Ext4 DSC include file for [Defines] section of all Architectures. +# +# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +!ifndef EXT4_ENABLE + # + # This flag is to enable or disable the ext4 feature. + # + DEFINE EXT4_ENABLE = TRUE +!endif diff --git a/Ext4Pkg/Ext4Dxe/BlockGroup.c b/Ext4Pkg/Ext4Dxe/BlockGroup.c new file mode 100644 index 0000000000..d5642a5f15 --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/BlockGroup.c @@ -0,0 +1,229 @@ +/** @file + Block group related routines + + Copyright (c) 2021 Pedro Falcato All rights reserved. + Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Ext4Dxe.h" + +/** + Retrieves a block group descriptor of the ext4 filesystem. + + @param[in] Partition Pointer to the opened ext4 partition. + @param[in] BlockGroup Block group number. + + @return A pointer to the block group descriptor. +**/ +EXT4_BLOCK_GROUP_DESC * +Ext4GetBlockGroupDesc ( + IN EXT4_PARTITION *Partition, + IN UINT32 BlockGroup + ) +{ + // Maybe assert that the block group nr isn't a nonsense number? + return (EXT4_BLOCK_GROUP_DESC *)((CHAR8 *)Partition->BlockGroups + BlockGroup * Partition->DescSize); +} + +/** + Reads an inode from disk. + + @param[in] Partition Pointer to the opened partition. + @param[in] InodeNum Number of the desired Inode + @param[out] OutIno Pointer to where it will be stored a pointer to the read inode. + + @return Status of the inode read. +**/ +EFI_STATUS +Ext4ReadInode ( + IN EXT4_PARTITION *Partition, + IN EXT4_INO_NR InodeNum, + OUT EXT4_INODE **OutIno + ) +{ + UINT64 InodeOffset; + UINT32 BlockGroupNumber; + EXT4_INODE *Inode; + EXT4_BLOCK_GROUP_DESC *BlockGroup; + EXT4_BLOCK_NR InodeTableStart; + EFI_STATUS Status; + + if (!EXT4_IS_VALID_INODE_NR (Partition, InodeNum)) { + DEBUG ((DEBUG_ERROR, "[ext4] Error reading inode: inode number %lu isn't valid\n", InodeNum)); + return EFI_VOLUME_CORRUPTED; + } + + BlockGroupNumber = (UINT32)DivU64x64Remainder ( + InodeNum - 1, + Partition->SuperBlock.s_inodes_per_group, + &InodeOffset + ); + + // Check for the block group number's correctness + if (BlockGroupNumber >= Partition->NumberBlockGroups) { + return EFI_VOLUME_CORRUPTED; + } + + Inode = Ext4AllocateInode (Partition); + + if (Inode == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + BlockGroup = Ext4GetBlockGroupDesc (Partition, BlockGroupNumber); + + // Note: We'll need to check INODE_UNINIT and friends when/if we add write support + + InodeTableStart = EXT4_BLOCK_NR_FROM_HALFS ( + Partition, + BlockGroup->bg_inode_table_lo, + BlockGroup->bg_inode_table_hi + ); + + Status = Ext4ReadDiskIo ( + Partition, + Inode, + Partition->InodeSize, + EXT4_BLOCK_TO_BYTES (Partition, InodeTableStart) + MultU64x32 (InodeOffset, Partition->InodeSize) + ); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "[ext4] Error reading inode: status %x; inode offset %lx" + " inode table start %lu block group %lu\n", + Status, + InodeOffset, + InodeTableStart, + BlockGroupNumber + )); + FreePool (Inode); + return Status; + } + + if (!Ext4CheckInodeChecksum (Partition, Inode, InodeNum)) { + DEBUG (( + DEBUG_ERROR, + "[ext4] Inode %llu has invalid checksum (calculated %x)\n", + InodeNum, + Ext4CalculateInodeChecksum (Partition, Inode, InodeNum) + )); + FreePool (Inode); + return EFI_VOLUME_CORRUPTED; + } + + *OutIno = Inode; + return EFI_SUCCESS; +} + +/** + Calculates the checksum of the block group descriptor for METADATA_CSUM enabled filesystems. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] BlockGroupDesc Pointer to the block group descriptor. + @param[in] BlockGroupNum Number of the block group. + + @return The checksum. +**/ +STATIC +UINT16 +Ext4CalculateBlockGroupDescChecksumMetadataCsum ( + IN CONST EXT4_PARTITION *Partition, + IN CONST EXT4_BLOCK_GROUP_DESC *BlockGroupDesc, + IN UINT32 BlockGroupNum + ) +{ + UINT32 Csum; + UINT16 Dummy; + + Dummy = 0; + + Csum = Ext4CalculateChecksum (Partition, &BlockGroupNum, sizeof (BlockGroupNum), Partition->InitialSeed); + Csum = Ext4CalculateChecksum (Partition, BlockGroupDesc, OFFSET_OF (EXT4_BLOCK_GROUP_DESC, bg_checksum), Csum); + Csum = Ext4CalculateChecksum (Partition, &Dummy, sizeof (Dummy), Csum); + Csum = + Ext4CalculateChecksum ( + Partition, + &BlockGroupDesc->bg_block_bitmap_hi, + Partition->DescSize - OFFSET_OF (EXT4_BLOCK_GROUP_DESC, bg_block_bitmap_hi), + Csum + ); + return (UINT16)Csum; +} + +/** + Calculates the checksum of the block group descriptor for GDT_CSUM enabled filesystems. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] BlockGroupDesc Pointer to the block group descriptor. + @param[in] BlockGroupNum Number of the block group. + + @return The checksum. +**/ +STATIC +UINT16 +Ext4CalculateBlockGroupDescChecksumGdtCsum ( + IN CONST EXT4_PARTITION *Partition, + IN CONST EXT4_BLOCK_GROUP_DESC *BlockGroupDesc, + IN UINT32 BlockGroupNum + ) +{ + UINT16 Csum; + + Csum = CalculateCrc16Ansi (Partition->SuperBlock.s_uuid, 16, CRC16ANSI_INIT); + Csum = CalculateCrc16Ansi (&BlockGroupNum, sizeof (BlockGroupNum), Csum); + Csum = CalculateCrc16Ansi (BlockGroupDesc, OFFSET_OF (EXT4_BLOCK_GROUP_DESC, bg_checksum), Csum); + Csum = + CalculateCrc16Ansi ( + &BlockGroupDesc->bg_block_bitmap_hi, + Partition->DescSize - OFFSET_OF (EXT4_BLOCK_GROUP_DESC, bg_block_bitmap_hi), + Csum + ); + return Csum; +} + +/** + Checks if the checksum of the block group descriptor is correct. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] BlockGroupDesc Pointer to the block group descriptor. + @param[in] BlockGroupNum Number of the block group. + + @return TRUE if checksum is correct, FALSE if there is corruption. +**/ +BOOLEAN +Ext4VerifyBlockGroupDescChecksum ( + IN CONST EXT4_PARTITION *Partition, + IN CONST EXT4_BLOCK_GROUP_DESC *BlockGroupDesc, + IN UINT32 BlockGroupNum + ) +{ + if (!EXT4_HAS_METADATA_CSUM (Partition) && !EXT4_HAS_GDT_CSUM (Partition)) { + return TRUE; + } + + return Ext4CalculateBlockGroupDescChecksum (Partition, BlockGroupDesc, BlockGroupNum) == BlockGroupDesc->bg_checksum; +} + +/** + Calculates the checksum of the block group descriptor. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] BlockGroupDesc Pointer to the block group descriptor. + @param[in] BlockGroupNum Number of the block group. + + @return The checksum. +**/ +UINT16 +Ext4CalculateBlockGroupDescChecksum ( + IN CONST EXT4_PARTITION *Partition, + IN CONST EXT4_BLOCK_GROUP_DESC *BlockGroupDesc, + IN UINT32 BlockGroupNum + ) +{ + if (EXT4_HAS_METADATA_CSUM (Partition)) { + return Ext4CalculateBlockGroupDescChecksumMetadataCsum (Partition, BlockGroupDesc, BlockGroupNum); + } else if (EXT4_HAS_GDT_CSUM (Partition)) { + return Ext4CalculateBlockGroupDescChecksumGdtCsum (Partition, BlockGroupDesc, BlockGroupNum); + } + + return 0; +} diff --git a/Ext4Pkg/Ext4Dxe/BlockMap.c b/Ext4Pkg/Ext4Dxe/BlockMap.c new file mode 100644 index 0000000000..8fee4476a5 --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/BlockMap.c @@ -0,0 +1,285 @@ +/** @file + Implementation of routines that deal with ext2/3 block maps. + + Copyright (c) 2022 Pedro Falcato All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +// Note: The largest path we can take uses up 4 indices +#define EXT4_MAX_BLOCK_PATH 4 + +typedef enum ext4_logical_block_type { + EXT4_TYPE_DIRECT_BLOCK = 0, + EXT4_TYPE_SINGLY_BLOCK, + EXT4_TYPE_DOUBLY_BLOCK, + EXT4_TYPE_TREBLY_BLOCK, + EXT4_TYPE_BAD_BLOCK +} EXT4_LOGICAL_BLOCK_TYPE; + +/** + @brief Detect the type of path the logical block will follow + + @param[in] LogicalBlock The logical block + @param[in] Partition Pointer to an EXT4_PARTITION + @return The type of path the logical block will need to follow + */ +STATIC +EXT4_LOGICAL_BLOCK_TYPE +Ext4DetectBlockType ( + IN UINT32 LogicalBlock, + IN CONST EXT4_PARTITION *Partition + ) +{ + UINT32 Entries; + UINT32 MinSinglyBlock; + UINT32 MinDoublyBlock; + UINT32 MinTreblyBlock; + UINT32 MinQuadBlock; + + Entries = (Partition->BlockSize / sizeof (UINT32)); + MinSinglyBlock = EXT4_DBLOCKS; + MinDoublyBlock = Entries + MinSinglyBlock; + MinTreblyBlock = Entries * Entries + MinDoublyBlock; + MinQuadBlock = Entries * Entries * Entries + MinTreblyBlock; // Doesn't actually exist + + if (LogicalBlock < MinSinglyBlock) { + return EXT4_TYPE_DIRECT_BLOCK; + } else if ((LogicalBlock >= MinSinglyBlock) && (LogicalBlock < MinDoublyBlock)) { + return EXT4_TYPE_SINGLY_BLOCK; + } else if ((LogicalBlock >= MinDoublyBlock) && (LogicalBlock < MinTreblyBlock)) { + return EXT4_TYPE_DOUBLY_BLOCK; + } else if (((LogicalBlock >= MinTreblyBlock) && (LogicalBlock < MinQuadBlock))) { + return EXT4_TYPE_TREBLY_BLOCK; + } else { + return EXT4_TYPE_BAD_BLOCK; + } +} + +/** + @brief Get a block's path in indices + + @param[in] Partition Pointer to an EXT4_PARTITION + @param[in] LogicalBlock Logical block + @param[out] BlockPath Pointer to an array of EXT4_MAX_BLOCK_PATH elements, where the + indices we'll need to read are inserted. + @return The number of path elements that are required (and were inserted in BlockPath) + */ +UINTN +Ext4GetBlockPath ( + IN CONST EXT4_PARTITION *Partition, + IN UINT32 LogicalBlock, + OUT EXT2_BLOCK_NR BlockPath[EXT4_MAX_BLOCK_PATH] + ) +{ + // The logic behind the block map is very much like a page table + // Let's think of blocks with 512 entries (exactly like a page table on x64). + // On doubly indirect block paths, we subtract the min doubly blocks from the logical block. + // The top 9 bits of the result are the index inside the dind block, the bottom 9 bits are the + // index inside the ind block. Since Entries is always a power of 2, entries - 1 will give us + // a mask of the BlockMapBits. + // Note that all this math could be done with ands and shifts (similar implementations exist + // in a bunch of other places), but I'm doing it a simplified way with divs and modulus, + // since it's not going to be a bottleneck anyway. + + UINT32 Entries; + UINT32 EntriesEntries; + UINT32 MinSinglyBlock; + UINT32 MinDoublyBlock; + UINT32 MinTreblyBlock; + + EXT4_LOGICAL_BLOCK_TYPE Type; + + Entries = (Partition->BlockSize / sizeof (UINT32)); + EntriesEntries = Entries * Entries; + + MinSinglyBlock = EXT4_DBLOCKS; + MinDoublyBlock = Entries + MinSinglyBlock; + MinTreblyBlock = EntriesEntries + MinDoublyBlock; + + Type = Ext4DetectBlockType (LogicalBlock, Partition); + + switch (Type) { + case EXT4_TYPE_DIRECT_BLOCK: + BlockPath[0] = LogicalBlock; + break; + case EXT4_TYPE_SINGLY_BLOCK: + BlockPath[0] = EXT4_IND_BLOCK; + BlockPath[1] = LogicalBlock - EXT4_DBLOCKS; + break; + case EXT4_TYPE_DOUBLY_BLOCK: + BlockPath[0] = EXT4_DIND_BLOCK; + LogicalBlock -= MinDoublyBlock; + BlockPath[1] = LogicalBlock / Entries; + BlockPath[2] = LogicalBlock % Entries; + break; + case EXT4_TYPE_TREBLY_BLOCK: + BlockPath[0] = EXT4_DIND_BLOCK; + LogicalBlock -= MinTreblyBlock; + BlockPath[1] = LogicalBlock / EntriesEntries; + BlockPath[2] = (LogicalBlock % EntriesEntries) / Entries; + BlockPath[3] = (LogicalBlock % EntriesEntries) % Entries; + break; + default: + // EXT4_TYPE_BAD_BLOCK + break; + } + + return Type + 1; +} + +/** + @brief Get an extent from a block map + Note: Also parses file holes and creates uninitialized extents from them. + + @param[in] Buffer Buffer of block pointers + @param[in] IndEntries Number of entries in this block pointer table + @param[in] StartIndex The start index from which we want to find a contiguous extent + @param[out] Extent Pointer to the resulting EXT4_EXTENT + */ +VOID +Ext4GetExtentInBlockMap ( + IN CONST UINT32 *Buffer, + IN CONST UINT32 IndEntries, + IN UINT32 StartIndex, + OUT EXT4_EXTENT *Extent + ) +{ + UINT32 Index; + UINT32 FirstBlock; + UINT32 LastBlock; + UINT16 Count; + + Count = 1; + LastBlock = Buffer[StartIndex]; + FirstBlock = LastBlock; + + if (FirstBlock == EXT4_BLOCK_FILE_HOLE) { + // File hole, let's see how many blocks this hole spans + Extent->ee_start_hi = 0; + Extent->ee_start_lo = 0; + + for (Index = StartIndex + 1; Index < IndEntries; Index++) { + if (Count == EXT4_EXTENT_MAX_INITIALIZED - 1) { + // We've reached the max size of an uninit extent, break + break; + } + + if (Buffer[Index] == EXT4_BLOCK_FILE_HOLE) { + Count++; + } else { + break; + } + } + + // We mark the extent as uninitialized, although there's a difference between uninit + // extents and file holes. + Extent->ee_len = EXT4_EXTENT_MAX_INITIALIZED + Count; + return; + } + + for (Index = StartIndex + 1; Index < IndEntries; Index++) { + if (Count == EXT4_EXTENT_MAX_INITIALIZED) { + // We've reached the max size of an extent, break + break; + } + + if ((Buffer[Index] == LastBlock + 1) && (Buffer[Index] != EXT4_BLOCK_FILE_HOLE)) { + Count++; + } else { + break; + } + + LastBlock = Buffer[Index]; + } + + Extent->ee_start_lo = FirstBlock; + Extent->ee_start_hi = 0; + Extent->ee_len = Count; +} + +/** + Retrieves an extent from an EXT2/3 inode (with a blockmap). + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] File Pointer to the opened file. + @param[in] LogicalBlock Block number which the returned extent must cover. + @param[out] Extent Pointer to the output buffer, where the extent will be copied to. + + @retval EFI_SUCCESS Retrieval was successful. + @retval EFI_NO_MAPPING Block has no mapping. +**/ +EFI_STATUS +Ext4GetBlocks ( + IN EXT4_PARTITION *Partition, + IN EXT4_FILE *File, + IN EXT2_BLOCK_NR LogicalBlock, + OUT EXT4_EXTENT *Extent + ) +{ + EXT4_INODE *Inode; + EXT2_BLOCK_NR BlockPath[EXT4_MAX_BLOCK_PATH]; + UINTN BlockPathLength; + UINTN Index; + UINT32 *Buffer; + EFI_STATUS Status; + UINT32 Block; + UINT32 BlockIndex; + + Inode = File->Inode; + + BlockPathLength = Ext4GetBlockPath (Partition, LogicalBlock, BlockPath); + + if (BlockPathLength - 1 == EXT4_TYPE_BAD_BLOCK) { + // Bad logical block (out of range) + return EFI_NO_MAPPING; + } + + Extent->ee_block = LogicalBlock; + + if (BlockPathLength == 1) { + // Fast path for blocks 0 - 12 that skips allocations + Ext4GetExtentInBlockMap (Inode->i_data, EXT4_DBLOCKS, BlockPath[0], Extent); + + return EFI_SUCCESS; + } + + Buffer = AllocatePool (Partition->BlockSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // Note the BlockPathLength - 1 so we don't end up reading the final block + for (Index = 0; Index < BlockPathLength - 1; Index++) { + BlockIndex = BlockPath[Index]; + + if (Index == 0) { + Block = Inode->i_data[BlockIndex]; + } else { + Block = Buffer[BlockIndex]; + } + + if (Block == EXT4_BLOCK_FILE_HOLE) { + FreePool (Buffer); + return EFI_NO_MAPPING; + } + + Status = Ext4ReadBlocks (Partition, Buffer, 1, Block); + + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + } + + Ext4GetExtentInBlockMap ( + Buffer, + Partition->BlockSize / sizeof (UINT32), + BlockPath[BlockPathLength - 1], + Extent + ); + + FreePool (Buffer); + + return EFI_SUCCESS; +} diff --git a/Ext4Pkg/Ext4Dxe/Collation.c b/Ext4Pkg/Ext4Dxe/Collation.c new file mode 100644 index 0000000000..82390ae8a9 --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/Collation.c @@ -0,0 +1,195 @@ +/** @file + Unicode collation routines + + Copyright (c) 2021 - 2023 Pedro Falcato All rights reserved. + Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include +#include +#include +#include + +#include + +STATIC EFI_UNICODE_COLLATION_PROTOCOL *gUnicodeCollationInterface = NULL; + +/* + * Note: This code is heavily based on FatPkg's Unicode collation, since they seem to know what + * they're doing. + * PS: Maybe all this code could be put in a library? It looks heavily shareable. +**/ + +/** + Check if unicode collation is initialized + + @retval TRUE if Ext4InitialiseUnicodeCollation() was already called successfully + @retval FALSE if Ext4InitialiseUnicodeCollation() was not yet called successfully +**/ +STATIC +BOOLEAN +Ext4IsCollationInitialized ( + VOID + ) +{ + return gUnicodeCollationInterface != NULL; +} + +/** + Worker function to initialize Unicode Collation support. + + It tries to locate Unicode Collation (2) protocol and matches it with current + platform language code. + + @param[in] DriverHandle The handle used to open Unicode Collation (2) protocol. + @param[in] ProtocolGuid The pointer to Unicode Collation (2) protocol GUID. + @param[in] VariableName The name of the RFC 4646 or ISO 639-2 language variable. + @param[in] DefaultLanguage The default language in case the RFC 4646 or ISO 639-2 language is absent. + + @retval EFI_SUCCESS The Unicode Collation (2) protocol has been successfully located. + @retval Others The Unicode Collation (2) protocol has not been located. + +**/ +STATIC +EFI_STATUS +Ext4InitialiseUnicodeCollationInternal ( + IN EFI_HANDLE DriverHandle, + IN EFI_GUID *ProtocolGuid, + IN CONST CHAR16 *VariableName, + IN CONST CHAR8 *DefaultLanguage + ) +{ + UINTN NumHandles; + EFI_HANDLE *Handles; + EFI_UNICODE_COLLATION_PROTOCOL *Uci; + BOOLEAN Iso639Language; + CHAR8 *Language; + EFI_STATUS RetStatus; + EFI_STATUS Status; + UINTN Idx; + CHAR8 *BestLanguage; + + Iso639Language = (BOOLEAN)(ProtocolGuid == &gEfiUnicodeCollationProtocolGuid); + RetStatus = EFI_UNSUPPORTED; + GetEfiGlobalVariable2 (VariableName, (VOID **)&Language, NULL); + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + ProtocolGuid, + NULL, + &NumHandles, + &Handles + ); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Idx = 0; Idx < NumHandles; Idx++) { + Status = gBS->OpenProtocol ( + Handles[Idx], + ProtocolGuid, + (VOID **)&Uci, + DriverHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + continue; + } + + BestLanguage = GetBestLanguage ( + Uci->SupportedLanguages, + Iso639Language, + (Language == NULL) ? "" : Language, + DefaultLanguage, + NULL + ); + if (BestLanguage != NULL) { + FreePool (BestLanguage); + gUnicodeCollationInterface = Uci; + RetStatus = EFI_SUCCESS; + break; + } + } + + if (Language != NULL) { + FreePool (Language); + } + + FreePool (Handles); + return RetStatus; +} + +/** + Initialises Unicode collation, which is needed for case-insensitive string comparisons + within the driver (a good example of an application of this is filename comparison). + + @param[in] DriverHandle Handle to the driver image. + + @retval EFI_SUCCESS Unicode collation was successfully initialised. + @retval !EFI_SUCCESS Failure. +**/ +EFI_STATUS +Ext4InitialiseUnicodeCollation ( + EFI_HANDLE DriverHandle + ) +{ + EFI_STATUS Status; + + Status = EFI_UNSUPPORTED; + + // If already done, just return success. + if (Ext4IsCollationInitialized ()) { + return EFI_SUCCESS; + } + + // + // First try to use RFC 4646 Unicode Collation 2 Protocol. + // + Status = Ext4InitialiseUnicodeCollationInternal ( + DriverHandle, + &gEfiUnicodeCollation2ProtocolGuid, + L"PlatformLang", + (CONST CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang) + ); + // + // If the attempt to use Unicode Collation 2 Protocol fails, then we fall back + // on the ISO 639-2 Unicode Collation Protocol. + // + if (EFI_ERROR (Status)) { + Status = Ext4InitialiseUnicodeCollationInternal ( + DriverHandle, + &gEfiUnicodeCollationProtocolGuid, + L"Lang", + (CONST CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultLang) + ); + } + + return Status; +} + +/** + Does a case-insensitive string comparison. Refer to EFI_UNICODE_COLLATION_PROTOCOL's StriColl + for more details. + + @param[in] Str1 Pointer to a null terminated string. + @param[in] Str2 Pointer to a null terminated string. + + @retval 0 Str1 is equivalent to Str2. + @retval >0 Str1 is lexically greater than Str2. + @retval <0 Str1 is lexically less than Str2. +**/ +INTN +Ext4StrCmpInsensitive ( + IN CHAR16 *Str1, + IN CHAR16 *Str2 + ) +{ + ASSERT (gUnicodeCollationInterface != NULL); + return gUnicodeCollationInterface->StriColl (gUnicodeCollationInterface, Str1, Str2); +} diff --git a/Ext4Pkg/Ext4Dxe/Directory.c b/Ext4Pkg/Ext4Dxe/Directory.c new file mode 100644 index 0000000000..88f89a4053 --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/Directory.c @@ -0,0 +1,708 @@ +/** @file + Directory related routines + + Copyright (c) 2021 - 2023 Pedro Falcato All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Ext4Dxe.h" + +#include + +/** + Retrieves the filename of the directory entry and converts it to UTF-16/UCS-2 + + @param[in] Entry Pointer to a EXT4_DIR_ENTRY. + @param[out] Ucs2FileName Pointer to an array of CHAR16's, of size EXT4_NAME_MAX + 1. + + @retval EFI_SUCCESS The filename was successfully retrieved and converted to UCS2. + @retval EFI_INVALID_PARAMETER The filename is not valid UTF-8. + @retval !EFI_SUCCESS Failure. +**/ +EFI_STATUS +Ext4GetUcs2DirentName ( + IN EXT4_DIR_ENTRY *Entry, + OUT CHAR16 Ucs2FileName[EXT4_NAME_MAX + 1] + ) +{ + CHAR8 Utf8NameBuf[EXT4_NAME_MAX + 1]; + UINT16 *Str; + UINT8 Index; + EFI_STATUS Status; + + for (Index = 0; Index < Entry->name_len; ++Index) { + if (Entry->name[Index] == '\0') { + return EFI_INVALID_PARAMETER; + } + + Utf8NameBuf[Index] = Entry->name[Index]; + } + + Utf8NameBuf[Entry->name_len] = '\0'; + + // Unfortunately, BaseUcs2Utf8Lib doesn't have a convert-buffer-to-buffer-like + // function. Therefore, we need to allocate from the pool (inside UTF8StrToUCS2), + // copy it to our out buffer (Ucs2FileName) and free. + + Status = UTF8StrToUCS2 (Utf8NameBuf, &Str); + + if (EFI_ERROR (Status)) { + return Status; + } + + Status = StrCpyS (Ucs2FileName, EXT4_NAME_MAX + 1, Str); + + FreePool (Str); + + return Status; +} + +/** + Validates a directory entry. + + @param[in] Dirent Pointer to the directory entry. + + @retval TRUE Valid directory entry. + FALSE Invalid directory entry. +**/ +STATIC +BOOLEAN +Ext4ValidDirent ( + IN CONST EXT4_DIR_ENTRY *Dirent + ) +{ + UINTN RequiredSize; + + RequiredSize = Dirent->name_len + EXT4_MIN_DIR_ENTRY_LEN; + + if (Dirent->rec_len < RequiredSize) { + DEBUG ((DEBUG_ERROR, "[ext4] dirent size %lu too small (compared to %lu)\n", Dirent->rec_len, RequiredSize)); + return FALSE; + } + + // Dirent sizes need to be 4 byte aligned + if ((Dirent->rec_len % 4) != 0) { + return FALSE; + } + + return TRUE; +} + +/** + Retrieves a directory entry. + + @param[in] Directory Pointer to the opened directory. + @param[in] NameUnicode Pointer to the UCS-2 formatted filename. + @param[in] Partition Pointer to the ext4 partition. + @param[out] Result Pointer to the destination directory entry. + + @return The result of the operation. +**/ +EFI_STATUS +Ext4RetrieveDirent ( + IN EXT4_FILE *Directory, + IN CONST CHAR16 *Name, + IN EXT4_PARTITION *Partition, + OUT EXT4_DIR_ENTRY *Result + ) +{ + EFI_STATUS Status; + CHAR8 *Buf; + UINT64 Off; + EXT4_INODE *Inode; + UINT64 DirInoSize; + UINT32 BlockRemainder; + UINTN Length; + EXT4_DIR_ENTRY *Entry; + UINTN RemainingBlock; + CHAR16 DirentUcs2Name[EXT4_NAME_MAX + 1]; + UINTN ToCopy; + UINTN BlockOffset; + + Buf = AllocatePool (Partition->BlockSize); + + if (Buf == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Off = 0; + + Inode = Directory->Inode; + DirInoSize = EXT4_INODE_SIZE (Inode); + + DivU64x32Remainder (DirInoSize, Partition->BlockSize, &BlockRemainder); + if (BlockRemainder != 0) { + // Directory inodes need to have block aligned sizes + Status = EFI_VOLUME_CORRUPTED; + goto Out; + } + + while (Off < DirInoSize) { + Length = Partition->BlockSize; + + Status = Ext4Read (Partition, Directory, Buf, Off, &Length); + + if (Status != EFI_SUCCESS) { + goto Out; + } + + for (BlockOffset = 0; BlockOffset < Partition->BlockSize; ) { + Entry = (EXT4_DIR_ENTRY *)(Buf + BlockOffset); + RemainingBlock = Partition->BlockSize - BlockOffset; + // Check if the minimum directory entry fits inside [BlockOffset, EndOfBlock] + if (RemainingBlock < EXT4_MIN_DIR_ENTRY_LEN) { + Status = EFI_VOLUME_CORRUPTED; + goto Out; + } + + if (!Ext4ValidDirent (Entry)) { + Status = EFI_VOLUME_CORRUPTED; + goto Out; + } + + if ((Entry->name_len > RemainingBlock) || (Entry->rec_len > RemainingBlock)) { + // Corrupted filesystem + Status = EFI_VOLUME_CORRUPTED; + goto Out; + } + + // Unused entry + if (Entry->inode == 0) { + BlockOffset += Entry->rec_len; + continue; + } + + Status = Ext4GetUcs2DirentName (Entry, DirentUcs2Name); + + /* In theory, this should never fail. + * In reality, it's quite possible that it can fail, considering filenames in + * Linux (and probably other nixes) are just null-terminated bags of bytes, and don't + * need to form valid ASCII/UTF-8 sequences. + */ + if (EFI_ERROR (Status)) { + if (Status == EFI_INVALID_PARAMETER) { + // If we error out due to a bad UTF-8 sequence (see Ext4GetUcs2DirentName), skip this entry. + // I'm not sure if this is correct behaviour, but I don't think there's a precedent here. + BlockOffset += Entry->rec_len; + continue; + } + + // Other sorts of errors should just error out. + FreePool (Buf); + return Status; + } + + if ((Entry->name_len == StrLen (Name)) && + !Ext4StrCmpInsensitive (DirentUcs2Name, (CHAR16 *)Name)) + { + ToCopy = MIN (Entry->rec_len, sizeof (EXT4_DIR_ENTRY)); + + CopyMem (Result, Entry, ToCopy); + Status = EFI_SUCCESS; + goto Out; + } + + BlockOffset += Entry->rec_len; + } + + Off += Partition->BlockSize; + } + + Status = EFI_NOT_FOUND; + +Out: + FreePool (Buf); + return Status; +} + +/** + Opens a file using a directory entry. + + @param[in] Partition Pointer to the ext4 partition. + @param[in] OpenMode Mode in which the file is supposed to be open. + @param[out] OutFile Pointer to the newly opened file. + @param[in] Entry Directory entry to be used. + @param[in] Directory Pointer to the opened directory. + + @retval EFI_STATUS Result of the operation +**/ +EFI_STATUS +Ext4OpenDirent ( + IN EXT4_PARTITION *Partition, + IN UINT64 OpenMode, + OUT EXT4_FILE **OutFile, + IN EXT4_DIR_ENTRY *Entry, + IN EXT4_FILE *Directory + ) +{ + EFI_STATUS Status; + CHAR16 FileName[EXT4_NAME_MAX + 1]; + EXT4_FILE *File; + + File = AllocateZeroPool (sizeof (EXT4_FILE)); + + if (File == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + Status = Ext4GetUcs2DirentName (Entry, FileName); + + if (EFI_ERROR (Status)) { + goto Error; + } + + if (StrCmp (FileName, L".") == 0) { + // We're using the parent directory's dentry + File->Dentry = Directory->Dentry; + + ASSERT (File->Dentry != NULL); + + Ext4RefDentry (File->Dentry); + } else if (StrCmp (FileName, L"..") == 0) { + // Using the parent's parent's dentry + File->Dentry = Directory->Dentry->Parent; + + if (!File->Dentry) { + // Someone tried .. on root, so direct them to / + // This is an illegal EFI Open() but is possible to hit from a variety of internal code + File->Dentry = Directory->Dentry; + } + + Ext4RefDentry (File->Dentry); + } else { + File->Dentry = Ext4CreateDentry (FileName, Directory->Dentry); + + if (File->Dentry == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + } + + Status = Ext4InitExtentsMap (File); + + if (EFI_ERROR (Status)) { + goto Error; + } + + File->InodeNum = Entry->inode; + + Ext4SetupFile (File, Partition); + + Status = Ext4ReadInode (Partition, Entry->inode, &File->Inode); + + if (EFI_ERROR (Status)) { + goto Error; + } + + *OutFile = File; + + InsertTailList (&Partition->OpenFiles, &File->OpenFilesListNode); + + return EFI_SUCCESS; + +Error: + if (File != NULL) { + if (File->Dentry != NULL) { + Ext4UnrefDentry (File->Dentry); + } + + if (File->ExtentsMap != NULL) { + OrderedCollectionUninit (File->ExtentsMap); + } + + FreePool (File); + } + + return Status; +} + +/** + Opens a file. + + @param[in] Directory Pointer to the opened directory. + @param[in] Name Pointer to the UCS-2 formatted filename. + @param[in] Partition Pointer to the ext4 partition. + @param[in] OpenMode Mode in which the file is supposed to be open. + @param[out] OutFile Pointer to the newly opened file. + + @return Result of the operation. +**/ +EFI_STATUS +Ext4OpenFile ( + IN EXT4_FILE *Directory, + IN CONST CHAR16 *Name, + IN EXT4_PARTITION *Partition, + IN UINT64 OpenMode, + OUT EXT4_FILE **OutFile + ) +{ + EXT4_DIR_ENTRY Entry; + EFI_STATUS Status; + + Status = Ext4RetrieveDirent (Directory, Name, Partition, &Entry); + + if (EFI_ERROR (Status)) { + return Status; + } + + // EFI requires us to error out on ".." opens for the root directory + if (Entry.inode == Directory->InodeNum) { + return EFI_NOT_FOUND; + } + + return Ext4OpenDirent (Partition, OpenMode, OutFile, &Entry, Directory); +} + +/** + Open the root directory on a volume. + + @param[in] This A pointer to the volume to open the root directory. + @param[out] Root A pointer to the location to return the opened file handle for the + root directory. + + @retval EFI_SUCCESS The device was opened. + @retval EFI_UNSUPPORTED This volume does not support the requested file system type. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no + longer supported. Any existing file handles for this volume are + no longer valid. To access the files on the new medium, the + volume must be reopened with OpenVolume(). + +**/ +EFI_STATUS +EFIAPI +Ext4OpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ) +{ + EXT4_INODE *RootInode; + EFI_STATUS Status; + EXT4_FILE *RootDir; + EXT4_PARTITION *Partition; + + Partition = (EXT4_PARTITION *)This; + + Status = Ext4ReadInode (Partition, EXT4_ROOT_INODE_NR, &RootInode); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[ext4] Could not open root inode - error %r\n", Status)); + return Status; + } + + RootDir = AllocateZeroPool (sizeof (EXT4_FILE)); + + if (RootDir == NULL) { + FreePool (RootInode); + return EFI_OUT_OF_RESOURCES; + } + + RootDir->Inode = RootInode; + RootDir->InodeNum = EXT4_ROOT_INODE_NR; + + Status = Ext4InitExtentsMap (RootDir); + + if (EFI_ERROR (Status)) { + FreePool (RootInode); + FreePool (RootDir); + return EFI_OUT_OF_RESOURCES; + } + + Ext4SetupFile (RootDir, Partition); + *Root = &RootDir->Protocol; + + InsertTailList (&Partition->OpenFiles, &RootDir->OpenFilesListNode); + + ASSERT (Partition->RootDentry != NULL); + RootDir->Dentry = Partition->RootDentry; + + Ext4RefDentry (RootDir->Dentry); + + return EFI_SUCCESS; +} + +/** + Reads a directory entry. + + @param[in] Partition Pointer to the ext4 partition. + @param[in] File Pointer to the open directory. + @param[out] Buffer Pointer to the output buffer. + @param[in] Offset Initial directory position. + @param[in out] OutLength Pointer to a UINTN that contains the length of the buffer, + and the length of the actual EFI_FILE_INFO after the call. + + @return Result of the operation. +**/ +EFI_STATUS +Ext4ReadDir ( + IN EXT4_PARTITION *Partition, + IN EXT4_FILE *File, + OUT VOID *Buffer, + IN UINT64 Offset, + IN OUT UINTN *OutLength + ) +{ + EXT4_INODE *DirIno; + EFI_STATUS Status; + UINT64 DirInoSize; + UINTN Len; + UINT32 BlockRemainder; + EXT4_DIR_ENTRY Entry; + EXT4_FILE *TempFile; + BOOLEAN ShouldSkip; + BOOLEAN IsDotOrDotDot; + CHAR16 DirentUcs2Name[EXT4_NAME_MAX + 1]; + + DirIno = File->Inode; + Status = EFI_SUCCESS; + DirInoSize = EXT4_INODE_SIZE (DirIno); + + DivU64x32Remainder (DirInoSize, Partition->BlockSize, &BlockRemainder); + if (BlockRemainder != 0) { + // Directory inodes need to have block aligned sizes + return EFI_VOLUME_CORRUPTED; + } + + while (TRUE) { + TempFile = NULL; + + // We (try to) read the maximum size of a directory entry at a time + // Note that we don't need to read any padding that may exist after it. + Len = sizeof (Entry); + Status = Ext4Read (Partition, File, &Entry, Offset, &Len); + + if (EFI_ERROR (Status)) { + goto Out; + } + + if (Len == 0) { + *OutLength = 0; + Status = EFI_SUCCESS; + goto Out; + } + + if (Len < EXT4_MIN_DIR_ENTRY_LEN) { + Status = EFI_VOLUME_CORRUPTED; + goto Out; + } + + // Invalid directory entry length + if (!Ext4ValidDirent (&Entry)) { + DEBUG ((DEBUG_ERROR, "[ext4] Invalid dirent at offset %lu\n", Offset)); + Status = EFI_VOLUME_CORRUPTED; + goto Out; + } + + // Check if the entire dir entry length fits in Len + if (Len < (UINTN)(EXT4_MIN_DIR_ENTRY_LEN + Entry.name_len)) { + Status = EFI_VOLUME_CORRUPTED; + goto Out; + } + + // We don't care about passing . or .. entries to the caller of ReadDir(), + // since they're generally useless entries *and* may break things if too + // many callers assume FAT32. + + // Entry.name_len may be 0 if it's a nameless entry, like an unused entry + // or a checksum at the end of the directory block. + // memcmp (and CompareMem) return 0 when the passed length is 0. + + // We must bound name_len as > 0 and <= 2 to avoid any out-of-bounds accesses or bad detection of + // "." and "..". + IsDotOrDotDot = Entry.name_len > 0 && Entry.name_len <= 2 && + CompareMem (Entry.name, "..", Entry.name_len) == 0; + + // When inode = 0, it's unused. When name_len == 0, it's a nameless entry + // (which we should not expose to ReadDir). + ShouldSkip = Entry.inode == 0 || Entry.name_len == 0 || IsDotOrDotDot; + + if (ShouldSkip) { + Offset += Entry.rec_len; + continue; + } + + // Test if the dirent is valid utf-8. This is already done inside Ext4OpenDirent but EFI_INVALID_PARAMETER + // has the danger of its meaning being overloaded in many places, so we can't skip according to that. + // So test outside of it, explicitly. + Status = Ext4GetUcs2DirentName (&Entry, DirentUcs2Name); + + if (EFI_ERROR (Status)) { + if (Status == EFI_INVALID_PARAMETER) { + // Bad UTF-8, skip. + Offset += Entry.rec_len; + continue; + } + + goto Out; + } + + Status = Ext4OpenDirent (Partition, EFI_FILE_MODE_READ, &TempFile, &Entry, File); + + if (EFI_ERROR (Status)) { + goto Out; + } + + Status = Ext4GetFileInfo (TempFile, Buffer, OutLength); + if (!EFI_ERROR (Status)) { + File->Position = Offset + Entry.rec_len; + } + + Ext4CloseInternal (TempFile); + + goto Out; + } + + Status = EFI_SUCCESS; +Out: + return Status; +} + +/** + Removes a dentry from the other's list. + + @param[in out] Parent Pointer to the parent EXT4_DENTRY. + @param[in out] ToBeRemoved Pointer to the child EXT4_DENTRY. +**/ +STATIC +VOID +Ext4RemoveDentry ( + IN OUT EXT4_DENTRY *Parent, + IN OUT EXT4_DENTRY *ToBeRemoved + ) +{ + ASSERT (IsNodeInList (&ToBeRemoved->ListNode, &Parent->Children)); + RemoveEntryList (&ToBeRemoved->ListNode); +} + +/** + Adds a dentry to the other's list. + + The dentry that is added to the other one's list gets ->Parent set to Parent, + and the parent gets its reference count incremented. + + @param[in out] Parent Pointer to the parent EXT4_DENTRY. + @param[in out] ToBeAdded Pointer to the child EXT4_DENTRY. +**/ +STATIC +VOID +Ext4AddDentry ( + IN OUT EXT4_DENTRY *Parent, + IN OUT EXT4_DENTRY *ToBeAdded + ) +{ + ToBeAdded->Parent = Parent; + InsertTailList (&Parent->Children, &ToBeAdded->ListNode); + Ext4RefDentry (Parent); +} + +/** + Creates a new dentry object. + + @param[in] Name Name of the dentry. + @param[in out opt] Parent Parent dentry, if it's not NULL. + + @return The new allocated and initialised dentry. + The ref count will be set to 1. +**/ +EXT4_DENTRY * +Ext4CreateDentry ( + IN CONST CHAR16 *Name, + IN OUT EXT4_DENTRY *Parent OPTIONAL + ) +{ + EXT4_DENTRY *Dentry; + EFI_STATUS Status; + + Dentry = AllocateZeroPool (sizeof (EXT4_DENTRY)); + + if (Dentry == NULL) { + return NULL; + } + + Dentry->RefCount = 1; + + // This StrCpyS should not fail. + Status = StrCpyS (Dentry->Name, ARRAY_SIZE (Dentry->Name), Name); + + ASSERT_EFI_ERROR (Status); + + InitializeListHead (&Dentry->Children); + + if (Parent != NULL) { + Ext4AddDentry (Parent, Dentry); + } + + DEBUG ((DEBUG_FS, "[ext4] Created dentry %s\n", Name)); + + return Dentry; +} + +/** + Increments the ref count of the dentry. + + @param[in out] Dentry Pointer to a valid EXT4_DENTRY. +**/ +VOID +Ext4RefDentry ( + IN OUT EXT4_DENTRY *Dentry + ) +{ + UINTN OldRef; + + OldRef = Dentry->RefCount; + + Dentry->RefCount++; + + // I'm not sure if this (Refcount overflow) is a valid concern, + // but it's better to be safe than sorry. + ASSERT (OldRef < Dentry->RefCount); +} + +/** + Deletes the dentry. + + @param[in out] Dentry Pointer to a valid EXT4_DENTRY. +**/ +STATIC +VOID +Ext4DeleteDentry ( + IN OUT EXT4_DENTRY *Dentry + ) +{ + if (Dentry->Parent) { + Ext4RemoveDentry (Dentry->Parent, Dentry); + Ext4UnrefDentry (Dentry->Parent); + } + + DEBUG ((DEBUG_FS, "[ext4] Deleted dentry %s\n", Dentry->Name)); + FreePool (Dentry); +} + +/** + Decrements the ref count of the dentry. + If the ref count is 0, it's destroyed. + + @param[in out] Dentry Pointer to a valid EXT4_DENTRY. + + @retval True if it was destroyed, false if it's alive. +**/ +BOOLEAN +Ext4UnrefDentry ( + IN OUT EXT4_DENTRY *Dentry + ) +{ + Dentry->RefCount--; + + if (Dentry->RefCount == 0) { + Ext4DeleteDentry (Dentry); + return TRUE; + } + + return FALSE; +} diff --git a/Ext4Pkg/Ext4Dxe/DiskUtil.c b/Ext4Pkg/Ext4Dxe/DiskUtil.c new file mode 100644 index 0000000000..5df9ce5baf --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/DiskUtil.c @@ -0,0 +1,123 @@ +/** @file + Disk utilities + + Copyright (c) 2021 Pedro Falcato All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include "Ext4Dxe.h" + +/** + Reads from the partition's disk using the DISK_IO protocol. + + @param[in] Partition Pointer to the opened ext4 partition. + @param[out] Buffer Pointer to a destination buffer. + @param[in] Length Length of the destination buffer. + @param[in] Offset Offset, in bytes, of the location to read. + + @return Success status of the disk read. +**/ +EFI_STATUS +Ext4ReadDiskIo ( + IN EXT4_PARTITION *Partition, + OUT VOID *Buffer, + IN UINTN Length, + IN UINT64 Offset + ) +{ + return EXT4_DISK_IO (Partition)->ReadDisk ( + EXT4_DISK_IO (Partition), + EXT4_MEDIA_ID (Partition), + Offset, + Length, + Buffer + ); +} + +/** + Reads blocks from the partition's disk using the DISK_IO protocol. + + @param[in] Partition Pointer to the opened ext4 partition. + @param[out] Buffer Pointer to a destination buffer. + @param[in] NumberBlocks Length of the read, in filesystem blocks. + @param[in] BlockNumber Starting block number. + + @return Success status of the read. +**/ +EFI_STATUS +Ext4ReadBlocks ( + IN EXT4_PARTITION *Partition, + OUT VOID *Buffer, + IN UINTN NumberBlocks, + IN EXT4_BLOCK_NR BlockNumber + ) +{ + UINT64 Offset; + UINTN Length; + + ASSERT (NumberBlocks != 0); + ASSERT (BlockNumber != EXT4_BLOCK_FILE_HOLE); + + Offset = MultU64x32 (BlockNumber, Partition->BlockSize); + Length = NumberBlocks * Partition->BlockSize; + + // Check for overflow on the block -> byte conversions. + // Partition->BlockSize is never 0, so we don't need to check for that. + + if (DivU64x64Remainder (Offset, BlockNumber, NULL) != Partition->BlockSize) { + return EFI_INVALID_PARAMETER; + } + + if (Length / NumberBlocks != Partition->BlockSize) { + return EFI_INVALID_PARAMETER; + } + + return Ext4ReadDiskIo (Partition, Buffer, Length, Offset); +} + +/** + Allocates a buffer and reads blocks from the partition's disk using the DISK_IO protocol. + This function is deprecated and will be removed in the future. + + @param[in] Partition Pointer to the opened ext4 partition. + @param[in] NumberBlocks Length of the read, in filesystem blocks. + @param[in] BlockNumber Starting block number. + + @return Buffer allocated by AllocatePool, or NULL if some part of the process + failed. +**/ +VOID * +Ext4AllocAndReadBlocks ( + IN EXT4_PARTITION *Partition, + IN UINTN NumberBlocks, + IN EXT4_BLOCK_NR BlockNumber + ) +{ + VOID *Buf; + UINTN Length; + + // Check that number of blocks isn't empty, because + // this is incorrect condition for opened partition, + // so we just early-exit + if ((NumberBlocks == 0) || (BlockNumber == EXT4_BLOCK_FILE_HOLE)) { + return NULL; + } + + Length = NumberBlocks * Partition->BlockSize; + + // Check for integer overflow + if (Length / NumberBlocks != Partition->BlockSize) { + return NULL; + } + + Buf = AllocatePool (Length); + if (Buf == NULL) { + return NULL; + } + + if (Ext4ReadBlocks (Partition, Buf, NumberBlocks, BlockNumber) != EFI_SUCCESS) { + FreePool (Buf); + return NULL; + } + + return Buf; +} diff --git a/Ext4Pkg/Ext4Dxe/Ext4Disk.h b/Ext4Pkg/Ext4Dxe/Ext4Disk.h new file mode 100644 index 0000000000..70cb6c3209 --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/Ext4Disk.h @@ -0,0 +1,501 @@ +/** @file + Raw filesystem data structures + + Copyright (c) 2021 - 2023 Pedro Falcato All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + Layout of an EXT2/3/4 filesystem: + (note: this driver has been developed using + https://www.kernel.org/doc/html/latest/filesystems/ext4/index.html as + documentation). + + An ext2/3/4 filesystem (here on out referred to as simply an ext4 filesystem, + due to the similarities) is composed of various concepts: + + 1) Superblock + The superblock is the structure near (1024 bytes offset from the start) + the start of the partition, and describes the filesystem in general. + Here, we get to know the size of the filesystem's blocks, which features + it supports or not, whether it's been cleanly unmounted, how many blocks + we have, etc. + + 2) Block groups + EXT4 filesystems are divided into block groups, and each block group covers + s_blocks_per_group(8 * Block Size) blocks. Each block group has an + associated block group descriptor; these are present directly after the + superblock. Each block group descriptor contains the location of the + inode table, and the inode and block bitmaps (note these bitmaps are only + a block long, which gets us the 8 * Block Size formula covered previously). + + 3) Blocks + The ext4 filesystem is divided in blocks, of size s_log_block_size ^ 1024. + Blocks can be allocated using individual block groups's bitmaps. Note + that block 0 is invalid and its presence on extents/block tables means + it's part of a file hole, and that particular location must be read as + a block full of zeros. + + 4) Inodes + The ext4 filesystem divides files/directories into inodes (originally + index nodes). Each file/socket/symlink/directory/etc (here on out referred + to as a file, since there is no distinction under the ext4 filesystem) is + stored as a /nameless/ inode, that is stored in some block group's inode + table. Each inode has s_inode_size size (or GOOD_OLD_INODE_SIZE if it's + an old filesystem), and holds various metadata about the file. Since the + largest inode structure right now is ~160 bytes, the rest of the inode + contains inline extended attributes. Inodes' data is stored using either + data blocks (under ext2/3) or extents (under ext4). + + 5) Extents + Ext4 inodes store data in extents. These let N contiguous logical blocks + that are represented by N contiguous physical blocks be represented by a + single extent structure, which minimizes filesystem metadata bloat and + speeds up block mapping (particularly due to the fact that high-quality + ext4 implementations like linux's try /really/ hard to make the file + contiguous, so it's common to have files with almost 0 fragmentation). + Inodes that use extents store them in a tree, and the top of the tree + is stored on i_data. The tree's leaves always start with an + EXT4_EXTENT_HEADER and contain EXT4_EXTENT_INDEX on eh_depth != 0 and + EXT4_EXTENT on eh_depth = 0; these entries are always sorted by logical + block. + + 6) Directories + Ext4 directories are files that store name -> inode mappings for the + logical directory; this is where files get their names, which means ext4 + inodes do not themselves have names, since they can be linked (present) + multiple times with different names. Directories can store entries in two + different ways: + 1) Classical linear directories: They store entries as a mostly-linked + mostly-list of EXT4_DIR_ENTRY. + 2) Hash tree directories: These are used for larger directories, with + hundreds of entries, and are designed in a backwards compatible way. + These are not yet implemented in the Ext4Dxe driver. + + 7) Journal + Ext3/4 filesystems have a journal to help protect the filesystem against + system crashes. This is not yet implemented in Ext4Dxe but is described + in detail in the Linux kernel's documentation. +**/ + +#ifndef EXT4_DISK_H_ +#define EXT4_DISK_H_ + +#include + +#define EXT4_SUPERBLOCK_OFFSET 1024U + +#define EXT4_SIGNATURE 0xEF53U + +#define EXT4_FS_STATE_UNMOUNTED 0x1 +#define EXT4_FS_STATE_ERRORS_DETECTED 0x2 +#define EXT4_FS_STATE_RECOVERING_ORPHANS 0x4 + +#define EXT4_ERRORS_CONTINUE 1 +#define EXT4_ERRORS_RO 2 +#define EXT4_ERRORS_PANIC 3 + +#define EXT4_LINUX_ID 0 +#define EXT4_GNU_HURD_ID 1 +#define EXT4_MASIX_ID 2 +#define EXT4_FREEBSD_ID 3 +#define EXT4_LITES_ID 4 + +#define EXT4_GOOD_OLD_REV 0 +#define EXT4_DYNAMIC_REV 1 + +#define EXT4_CHECKSUM_CRC32C 0x1 + +#define EXT4_FEATURE_COMPAT_DIR_PREALLOC 0x01 +#define EXT4_FEATURE_COMPAT_IMAGIC_INODES 0x02 +#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x04 +#define EXT4_FEATURE_COMPAT_EXT_ATTR 0x08 +#define EXT4_FEATURE_COMPAT_RESIZE_INO 0x10 +#define EXT4_FEATURE_COMPAT_DIR_INDEX 0x20 + +#define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x00001 +#define EXT4_FEATURE_INCOMPAT_FILETYPE 0x00002 +#define EXT4_FEATURE_INCOMPAT_RECOVER 0x00004 +#define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV 0x00008 +#define EXT4_FEATURE_INCOMPAT_META_BG 0x00010 +#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x00040 +#define EXT4_FEATURE_INCOMPAT_64BIT 0x00080 +#define EXT4_FEATURE_INCOMPAT_MMP 0x00100 +#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x00200 +#define EXT4_FEATURE_INCOMPAT_EA_INODE 0x00400 +// It's not clear whether or not this feature (below) is used right now +#define EXT4_FEATURE_INCOMPAT_DIRDATA 0x01000 +#define EXT4_FEATURE_INCOMPAT_CSUM_SEED 0x02000 +#define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x04000 +#define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x08000 +#define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 + +#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 +#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 +#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004// Unused +#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 +#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 +#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 +#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 +#define EXT4_FEATURE_RO_COMPAT_HAS_SNAPSHOT 0x0080// Not implemented in ext4 +#define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100 +#define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200 +#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400 +#define EXT4_FEATURE_RO_COMPAT_REPLICA 0x0800// Not used + +// We explicitly don't recognise this, so we get read only. +#define EXT4_FEATURE_RO_COMPAT_READONLY 0x1000 +#define EXT4_FEATURE_RO_COMPAT_PROJECT 0x2000 + +/* Important notes about the features + * Absolutely needed features: + * 1) Every incompat, because we might want to mount root filesystems + * 2) Relevant RO_COMPATs(I'm not sure of what to do wrt quota, project) + **/ + +#define EXT4_INO_TYPE_FIFO 0x1000 +#define EXT4_INO_TYPE_CHARDEV 0x2000 +#define EXT4_INO_TYPE_DIR 0x4000 +#define EXT4_INO_TYPE_BLOCKDEV 0x6000 +#define EXT4_INO_TYPE_REGFILE 0x8000 +#define EXT4_INO_TYPE_SYMLINK 0xA000 +#define EXT4_INO_TYPE_UNIX_SOCK 0xC000 + +/* Inode flags */ +#define EXT4_SECRM_FL 0x00000001 +#define EXT4_UNRM_FL 0x00000002 +#define EXT4_COMPR_FL 0x00000004 +#define EXT4_SYNC_FL 0x00000008 +#define EXT4_IMMUTABLE_FL 0x00000010 +#define EXT4_APPEND_FL 0x00000020 +#define EXT4_NODUMP_FL 0x00000040 +#define EXT4_NOATIME_FL 0x00000080 +#define EXT4_DIRTY_FL 0x00000100 +#define EXT4_COMPRBLK_FL 0x00000200 +#define EXT4_NOCOMPR_FL 0x00000400 +#define EXT4_ENCRYPT_FL 0x00000800 +#define EXT4_BTREE_FL 0x00001000 +#define EXT4_INDEX_FL 0x00002000 +#define EXT4_JOURNAL_DATA_FL 0x00004000 +#define EXT4_NOTAIL_FL 0x00008000 +#define EXT4_DIRSYNC_FL 0x00010000 +#define EXT4_TOPDIR_FL 0x00020000 +#define EXT4_HUGE_FILE_FL 0x00040000 +#define EXT4_EXTENTS_FL 0x00080000 +#define EXT4_VERITY_FL 0x00100000 +#define EXT4_EA_INODE_FL 0x00200000 +#define EXT4_RESERVED_FL 0x80000000 + +/* File type flags that are stored in the directory entries */ +#define EXT4_FT_UNKNOWN 0 +#define EXT4_FT_REG_FILE 1 +#define EXT4_FT_DIR 2 +#define EXT4_FT_CHRDEV 3 +#define EXT4_FT_BLKDEV 4 +#define EXT4_FT_FIFO 5 +#define EXT4_FT_SOCK 6 +#define EXT4_FT_SYMLINK 7 + +typedef struct { + UINT32 s_inodes_count; + UINT32 s_blocks_count; + UINT32 s_r_blocks_count; + UINT32 s_free_blocks_count; + UINT32 s_free_inodes_count; + UINT32 s_first_data_block; + UINT32 s_log_block_size; + UINT32 s_log_frag_size; + UINT32 s_blocks_per_group; + UINT32 s_frags_per_group; + UINT32 s_inodes_per_group; + UINT32 s_mtime; + UINT32 s_wtime; + UINT16 s_mnt_count; + UINT16 s_max_mnt_count; + UINT16 s_magic; + UINT16 s_state; + UINT16 s_errors; + UINT16 s_minor_rev_level; + UINT32 s_lastcheck; + UINT32 s_check_interval; + UINT32 s_creator_os; + UINT32 s_rev_level; + UINT16 s_def_resuid; + UINT16 s_def_resgid; + + /* Every field after this comment is revision >= 1 */ + + UINT32 s_first_ino; + UINT16 s_inode_size; + UINT16 s_block_group_nr; + UINT32 s_feature_compat; + UINT32 s_feature_incompat; + UINT32 s_feature_ro_compat; + UINT8 s_uuid[16]; + UINT8 s_volume_name[16]; + UINT8 s_last_mounted[64]; + UINT32 s_algo_bitmap; + UINT8 s_prealloc_blocks; + UINT8 s_prealloc_dir_blocks; + UINT16 unused; + UINT8 s_journal_uuid[16]; + UINT32 s_journal_inum; + UINT32 s_journal_dev; + UINT32 s_last_orphan; + UINT32 s_hash_seed[4]; + UINT8 s_def_hash_version; + UINT8 s_jnl_backup_type; + UINT16 s_desc_size; + UINT32 s_default_mount_options; + UINT32 s_first_meta_bg; + UINT32 s_mkfs_time; + UINT32 s_jnl_blocks[17]; + UINT32 s_blocks_count_hi; + UINT32 s_r_blocks_count_hi; + UINT32 s_free_blocks_count_hi; + UINT16 s_min_extra_isize; + UINT16 s_want_extra_isize; + UINT32 s_flags; + UINT16 s_raid_stride; + UINT16 s_mmp_interval; + UINT64 s_mmp_block; + UINT32 s_raid_stride_width; + UINT8 s_log_groups_per_flex; + UINT8 s_checksum_type; // Only valid value is 1 - CRC32C + UINT16 s_reserved_pad; + UINT64 s_kbytes_written; + + // Snapshot stuff isn't used in Linux and isn't implemented here + UINT32 s_snapshot_inum; + UINT32 s_snapshot_id; + UINT64 s_snapshot_r_blocks_count; + UINT32 s_snapshot_list; + UINT32 s_error_count; + UINT32 s_first_error_time; + UINT32 s_first_error_ino; + UINT64 s_first_error_block; + UINT8 s_first_error_func[32]; + UINT32 s_first_error_line; + UINT32 s_last_error_time; + UINT32 s_last_error_ino; + UINT32 s_last_error_line; + UINT64 s_last_error_block; + UINT8 s_last_error_func[32]; + UINT8 s_mount_opts[64]; + UINT32 s_usr_quota_inum; + UINT32 s_grp_quota_inum; + UINT32 s_overhead_blocks; + UINT32 s_backup_bgs[2]; // sparse_super2 + UINT8 s_encrypt_algos[4]; + UINT8 s_encrypt_pw_salt[16]; + UINT32 s_lpf_ino; + UINT32 s_prj_quota_inum; + UINT32 s_checksum_seed; + UINT32 s_reserved[98]; + UINT32 s_checksum; +} EXT4_SUPERBLOCK; + +STATIC_ASSERT ( + sizeof (EXT4_SUPERBLOCK) == 1024, + "ext4 superblock struct has incorrect size" + ); + +typedef struct { + UINT32 bg_block_bitmap_lo; + UINT32 bg_inode_bitmap_lo; + UINT32 bg_inode_table_lo; + UINT16 bg_free_blocks_count_lo; + UINT16 bg_free_inodes_count_lo; + UINT16 bg_used_dirs_count_lo; + UINT16 bg_flags; + UINT32 bg_exclude_bitmap_lo; + UINT16 bg_block_bitmap_csum_lo; + UINT16 bg_inode_bitmap_csum_lo; + UINT16 bg_itable_unused_lo; + UINT16 bg_checksum; + UINT32 bg_block_bitmap_hi; + UINT32 bg_inode_bitmap_hi; + UINT32 bg_inode_table_hi; + UINT16 bg_free_blocks_count_hi; + UINT16 bg_free_inodes_count_hi; + UINT16 bg_used_dirs_count_hi; + UINT16 bg_itable_unused_hi; + UINT32 bg_exclude_bitmap_hi; + UINT16 bg_block_bitmap_csum_hi; + UINT16 bg_inode_bitmap_csum_hi; + UINT32 bg_reserved; +} EXT4_BLOCK_GROUP_DESC; + +#define EXT4_OLD_BLOCK_DESC_SIZE 32 +#define EXT4_64BIT_BLOCK_DESC_SIZE 64 + +STATIC_ASSERT ( + sizeof (EXT4_BLOCK_GROUP_DESC) == EXT4_64BIT_BLOCK_DESC_SIZE, + "ext4 block group descriptor struct has incorrect size" + ); + +#define EXT4_DBLOCKS 12 +#define EXT4_IND_BLOCK 12 +#define EXT4_DIND_BLOCK 13 +#define EXT4_TIND_BLOCK 14 +#define EXT4_NR_BLOCKS 15 +#define EXT4_FAST_SYMLINK_MAX_SIZE EXT4_NR_BLOCKS * sizeof(UINT32) + +#define EXT4_GOOD_OLD_INODE_SIZE 128U + +typedef struct _Ext4_I_OSD2_Linux { + UINT16 l_i_blocks_high; + UINT16 l_i_file_acl_high; + UINT16 l_i_uid_high; + UINT16 l_i_gid_high; + UINT16 l_i_checksum_lo; + UINT16 l_i_reserved; +} EXT4_OSD2_LINUX; + +typedef struct _Ext4_I_OSD2_Hurd { + UINT16 h_i_reserved1; + UINT16 h_i_mode_high; + UINT16 h_i_uid_high; + UINT16 h_i_gid_high; + UINT32 h_i_author; +} EXT4_OSD2_HURD; + +typedef union { + // Note: Toolchain-specific defines (such as "linux") stops us from using + // simpler names down here. + EXT4_OSD2_LINUX data_linux; + EXT4_OSD2_HURD data_hurd; +} EXT4_OSD2; + +typedef struct _Ext4Inode { + UINT16 i_mode; + UINT16 i_uid; + UINT32 i_size_lo; + UINT32 i_atime; + UINT32 i_ctime; + UINT32 i_mtime; + UINT32 i_dtime; + UINT16 i_gid; + UINT16 i_links; + UINT32 i_blocks; + UINT32 i_flags; + UINT32 i_os_spec; + UINT32 i_data[EXT4_NR_BLOCKS]; + UINT32 i_generation; + UINT32 i_file_acl; + UINT32 i_size_hi; + UINT32 i_faddr; + + EXT4_OSD2 i_osd2; + + UINT16 i_extra_isize; + UINT16 i_checksum_hi; + UINT32 i_ctime_extra; + UINT32 i_mtime_extra; + UINT32 i_atime_extra; + UINT32 i_crtime; + UINT32 i_crtime_extra; + UINT32 i_version_hi; + UINT32 i_projid; +} EXT4_INODE; + +#define EXT4_NAME_MAX 255 + +typedef struct { + // offset 0x0: inode number (if 0, unused entry, should skip.) + UINT32 inode; + // offset 0x4: Directory entry's length. + // Note: rec_len >= name_len + EXT4_MIN_DIR_ENTRY_LEN and rec_len % 4 == 0. + UINT16 rec_len; + // offset 0x6: Directory entry's name's length + UINT8 name_len; + // offset 0x7: Directory entry's file type indicator + UINT8 file_type; + // offset 0x8: name[name_len]: Variable length character array; not null-terminated. + CHAR8 name[EXT4_NAME_MAX]; + // Further notes on names: + // 1) We use EXT4_NAME_MAX here instead of flexible arrays for ease of use around the driver. + // + // 2) ext4 directories are defined, as the documentation puts it, as: + // "a directory is more or less a flat file that maps an arbitrary byte string + // (usually ASCII) to an inode number on the filesystem". So, they are not + // necessarily encoded with ASCII, UTF-8, or any of the sort. We must treat it + // as a bag of bytes. When interacting with EFI interfaces themselves (which expect UCS-2) + // we skip any directory entry that is not valid UTF-8. +} EXT4_DIR_ENTRY; + +#define EXT4_MIN_DIR_ENTRY_LEN 8 + +// This on-disk structure is present at the bottom of the extent tree +typedef struct { + // First logical block + UINT32 ee_block; + // Length of the extent, in blocks + UINT16 ee_len; + // The physical (filesystem-relative) block is split between the high 16 bits + // and the low 32 bits - this forms a 48-bit block number + UINT16 ee_start_hi; + UINT32 ee_start_lo; +} EXT4_EXTENT; + +// This on-disk structure is present at all levels except the bottom +typedef struct { + // This index covers logical blocks from 'ei_block' + UINT32 ei_block; + // Block of the next level of the extent tree, similarly split in a high and + // low portion. + UINT32 ei_leaf_lo; + UINT16 ei_leaf_hi; + + UINT16 ei_unused; +} EXT4_EXTENT_INDEX; + +typedef struct { + // Needs to be EXT4_EXTENT_HEADER_MAGIC + UINT16 eh_magic; + // Number of entries + UINT16 eh_entries; + // Maximum number of entries that could follow this header + UINT16 eh_max; + // Depth of this node in the tree - the tree can be at most 5 levels deep + UINT16 eh_depth; + // Unused by standard ext4 + UINT32 eh_generation; +} EXT4_EXTENT_HEADER; + +#define EXT4_EXTENT_HEADER_MAGIC 0xF30A + +// Specified by ext4 docs and backed by a bunch of math +#define EXT4_EXTENT_TREE_MAX_DEPTH 5 + +typedef struct { + // CRC32C of UUID + inode number + igeneration + extent block + UINT32 eb_checksum; +} EXT4_EXTENT_TAIL; + +/** + * EXT4 has this feature called uninitialized extents: + * An extent has a maximum of 32768 blocks (2^15 or 1 << 15). + * When we find an extent with > 32768 blocks, this extent is called + * uninitialized. Long story short, it's an extent that behaves as a file hole + * but has blocks already allocated. + */ +#define EXT4_EXTENT_MAX_INITIALIZED (1 << 15) + +typedef UINT64 EXT4_BLOCK_NR; +typedef UINT32 EXT2_BLOCK_NR; +typedef UINT32 EXT4_INO_NR; + +/* Special inode numbers */ +#define EXT4_ROOT_INODE_NR 2 +#define EXT4_USR_QUOTA_INODE_NR 3 +#define EXT4_GRP_QUOTA_INODE_NR 4 +#define EXT4_BOOT_LOADER_INODE_NR 5 +#define EXT4_UNDEL_DIR_INODE_NR 6 +#define EXT4_RESIZE_INODE_NR 7 +#define EXT4_JOURNAL_INODE_NR 8 + +/* First non-reserved inode for old ext4 filesystems */ +#define EXT4_GOOD_OLD_FIRST_INODE_NR 11 + +#define EXT4_BLOCK_FILE_HOLE 0 + +#endif diff --git a/Ext4Pkg/Ext4Dxe/Ext4Dxe.c b/Ext4Pkg/Ext4Dxe/Ext4Dxe.c new file mode 100644 index 0000000000..064286791d --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/Ext4Dxe.c @@ -0,0 +1,847 @@ +/** @file + Driver entry point + + Copyright (c) 2021 - 2023 Pedro Falcato All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Ext4Dxe.h" + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mExt4DriverNameTable[] = { + { + "eng;en", + L"Ext4 File System Driver" + }, + { + NULL, + NULL + } +}; + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mExt4ControllerNameTable[] = { + { + "eng;en", + L"Ext4 File System" + }, + { + NULL, + NULL + } +}; + +// Needed by gExt4ComponentName* + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] Language A pointer to a three-character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param[out] DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +Ext4ComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param[in] ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param[in] Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param[out] ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language, from the point of view of the driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +Ext4ComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +extern EFI_COMPONENT_NAME_PROTOCOL gExt4ComponentName; + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gExt4ComponentName = { + Ext4ComponentNameGetDriverName, + Ext4ComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gExt4ComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)Ext4ComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)Ext4ComponentNameGetControllerName, + "en" +}; + +// Needed by gExt4BindingProtocol + +/** + Tests to see if this driver supports a given controller. If a child device is provided, + it further tests to see if this driver supports creating a handle for the specified child device. + + This function checks to see if the driver specified by This supports the device specified by + ControllerHandle. Drivers will typically use the device path attached to + ControllerHandle and/or the services from the bus I/O abstraction attached to + ControllerHandle to determine if the driver supports ControllerHandle. This function + may be called many times during platform initialization. In order to reduce boot times, the tests + performed by this function must be very small, and take as little time as possible to execute. This + function must not change the state of any hardware devices, and this function must be aware that the + device specified by ControllerHandle may already be managed by the same driver or a + different driver. This function must match its calls to AllocatePages() with FreePages(), + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). + Because ControllerHandle may have been previously started by the same driver, if a protocol is + already in the opened state, then it must not be closed with CloseProtocol(). This is required + to guarantee the state of ControllerHandle is not modified by this function. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to test. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For bus drivers, if this parameter is not NULL, then + the bus driver must determine if the bus controller specified + by ControllerHandle and the child controller specified + by RemainingDevicePath are both supported by this + bus driver. + + @retval EFI_SUCCESS The device specified by ControllerHandle and + RemainingDevicePath is supported by the driver specified by This. + @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by the driver + specified by This. + @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by a different + driver or an application that requires exclusive access. + Currently not implemented. + @retval EFI_UNSUPPORTED The device specified by ControllerHandle and + RemainingDevicePath is not supported by the driver specified by This. +**/ +EFI_STATUS +EFIAPI +Ext4IsBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *BindingProtocol, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL + ); + +/** + Starts a device controller or a bus controller. + + The Start() function is designed to be invoked from the EFI boot service ConnectController(). + As a result, much of the error checking on the parameters to Start() has been moved into this + common boot service. It is legal to call Start() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE. + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned + EFI_DEVICE_PATH_PROTOCOL. + 3. Prior to calling Start(), the Supported() function for the driver specified by This must + have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to start. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For a bus driver, if this parameter is NULL, then handles + for all the children of Controller are created by this driver. + If this parameter is not NULL and the first Device Path Node is + not the End of Device Path Node, then only the handle for the + child device specified by the first Device Path Node of + RemainingDevicePath is created by this driver. + If the first Device Path Node of RemainingDevicePath is + the End of Device Path Node, no child handle is created by this + driver. + + @retval EFI_SUCCESS The device was started. + @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others The driver failded to start the device. + +**/ +EFI_STATUS +EFIAPI +Ext4Bind ( + IN EFI_DRIVER_BINDING_PROTOCOL *BindingProtocol, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL + ); + +/** + Stops a device controller or a bus controller. + + The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). + As a result, much of the error checking on the parameters to Stop() has been moved + into this common boot service. It is legal to call Stop() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this + same driver's Start() function. + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid + EFI_HANDLE. In addition, all of these handles must have been created in this driver's + Start() function, and the Start() function must have called OpenProtocol() on + ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle A handle to the device being stopped. The handle must + support a bus specific I/O protocol for the driver + to use to stop the device. + @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval EFI_SUCCESS The device was stopped. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. + +**/ +EFI_STATUS +EFIAPI +Ext4Stop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ); + +EFI_DRIVER_BINDING_PROTOCOL gExt4BindingProtocol = +{ + .Supported = Ext4IsBindingSupported, + .Start = Ext4Bind, + .Stop = Ext4Stop, + .Version = EXT4_DRIVER_VERSION, + .ImageHandle = NULL, + .DriverBindingHandle = NULL +}; + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param[in] ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param[in] Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param[out] ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language, from the point of view of the driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +Ext4ComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // Test if the driver manages ControllHandle + Status = EfiTestManagedDevice ( + ControllerHandle, + gExt4BindingProtocol.DriverBindingHandle, + &gEfiDiskIoProtocolGuid + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mExt4ControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gExt4ComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] Language A pointer to a three-character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param[out] DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +Ext4ComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mExt4DriverNameTable, + DriverName, + (BOOLEAN)(This == &gExt4ComponentName) + ); +} + +/** + Stops a device controller or a bus controller. + + The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). + As a result, much of the error checking on the parameters to Stop() has been moved + into this common boot service. It is legal to call Stop() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this + same driver's Start() function. + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid + EFI_HANDLE. In addition, all of these handles must have been created in this driver's + Start() function, and the Start() function must have called OpenProtocol() on + ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle A handle to the device being stopped. The handle must + support a bus specific I/O protocol for the driver + to use to stop the device. + @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval EFI_SUCCESS The device was stopped. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. + +**/ +EFI_STATUS +EFIAPI +Ext4Stop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Sfs; + EXT4_PARTITION *Partition; + BOOLEAN HasDiskIo2; + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, + (VOID **)&Sfs, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + Partition = (EXT4_PARTITION *)Sfs; + + HasDiskIo2 = EXT4_DISK_IO2 (Partition) != NULL; + + Status = Ext4UnmountAndFreePartition (Partition); + + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->UninstallMultipleProtocolInterfaces ( + ControllerHandle, + &gEfiSimpleFileSystemProtocolGuid, + &Partition->Interface, + NULL + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // Close all open protocols (DiskIo, DiskIo2, BlockIo) + + Status = gBS->CloseProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->CloseProtocol ( + ControllerHandle, + &gEfiBlockIoProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + if (HasDiskIo2) { + Status = gBS->CloseProtocol ( + ControllerHandle, + &gEfiDiskIo2ProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + + if (EFI_ERROR (Status)) { + return Status; + } + } + + return Status; +} + +/** + Ext4Dxe Driver's entry point. + + Called at load time. + + @param[in] ImageHandle Handle to the image. + @param[in] SystemTable Pointer to the EFI_SYSTEM_TABLE. + @return Result of the load. +**/ +EFI_STATUS +EFIAPI +Ext4EntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return EfiLibInstallAllDriverProtocols2 ( + ImageHandle, + SystemTable, + &gExt4BindingProtocol, + ImageHandle, + &gExt4ComponentName, + &gExt4ComponentName2, + NULL, + NULL, + NULL, + NULL + ); +} + +/** + Ext4Dxe Driver's unload callback. + + Called at unload time. + + @param[in] ImageHandle Handle to the image. + @return Result of the unload. +**/ +EFI_STATUS +EFIAPI +Ext4Unload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + EFI_HANDLE *DeviceHandleBuffer; + UINTN DeviceHandleCount; + UINTN Index; + EFI_HANDLE Handle; + + Status = gBS->LocateHandleBuffer ( + AllHandles, + NULL, + NULL, + &DeviceHandleCount, + &DeviceHandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index = 0; Index < DeviceHandleCount; Index++) { + Handle = DeviceHandleBuffer[Index]; + + Status = EfiTestManagedDevice (Handle, ImageHandle, &gEfiDiskIoProtocolGuid); + + if (Status == EFI_SUCCESS) { + Status = gBS->DisconnectController (Handle, ImageHandle, NULL); + + if (EFI_ERROR (Status)) { + break; + } + } + } + + FreePool (DeviceHandleBuffer); + + Status = EfiLibUninstallAllDriverProtocols2 ( + &gExt4BindingProtocol, + &gExt4ComponentName, + &gExt4ComponentName2, + NULL, + NULL, + NULL, + NULL + ); + + return Status; +} + +/** + Tests to see if this driver supports a given controller. If a child device is provided, + it further tests to see if this driver supports creating a handle for the specified child device. + + This function checks to see if the driver specified by This supports the device specified by + ControllerHandle. Drivers will typically use the device path attached to + ControllerHandle and/or the services from the bus I/O abstraction attached to + ControllerHandle to determine if the driver supports ControllerHandle. This function + may be called many times during platform initialization. In order to reduce boot times, the tests + performed by this function must be very small, and take as little time as possible to execute. This + function must not change the state of any hardware devices, and this function must be aware that the + device specified by ControllerHandle may already be managed by the same driver or a + different driver. This function must match its calls to AllocatePages() with FreePages(), + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). + Because ControllerHandle may have been previously started by the same driver, if a protocol is + already in the opened state, then it must not be closed with CloseProtocol(). This is required + to guarantee the state of ControllerHandle is not modified by this function. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to test. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For bus drivers, if this parameter is not NULL, then + the bus driver must determine if the bus controller specified + by ControllerHandle and the child controller specified + by RemainingDevicePath are both supported by this + bus driver. + + @retval EFI_SUCCESS The device specified by ControllerHandle and + RemainingDevicePath is supported by the driver specified by This. + @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by the driver + specified by This. + @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by a different + driver or an application that requires exclusive access. + @retval EFI_UNSUPPORTED The device specified by ControllerHandle and + RemainingDevicePath is not supported by the driver specified by This. +**/ +EFI_STATUS +EFIAPI +Ext4IsBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *BindingProtocol, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + + DiskIo = NULL; + BlockIo = NULL; + + // + // Open the IO Abstraction(s) needed to perform the supported test + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + (VOID **)&DiskIo, + BindingProtocol->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Open the IO Abstraction(s) needed to perform the supported test + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiBlockIoProtocolGuid, + (VOID **)&BlockIo, + BindingProtocol->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (!EFI_ERROR (Status)) { + if (!Ext4SuperblockCheckMagic (DiskIo, BlockIo)) { + Status = EFI_UNSUPPORTED; + } + } + + // + // Close the I/O Abstraction(s) used to perform the supported test + // + if (DiskIo != NULL) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + BindingProtocol->DriverBindingHandle, + ControllerHandle + ); + } + + if (BlockIo != NULL) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiBlockIoProtocolGuid, + BindingProtocol->DriverBindingHandle, + ControllerHandle + ); + } + + return Status; +} + +/** + Starts a device controller or a bus controller. + + The Start() function is designed to be invoked from the EFI boot service ConnectController(). + As a result, much of the error checking on the parameters to Start() has been moved into this + common boot service. It is legal to call Start() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE. + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned + EFI_DEVICE_PATH_PROTOCOL. + 3. Prior to calling Start(), the Supported() function for the driver specified by This must + have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to start. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For a bus driver, if this parameter is NULL, then handles + for all the children of Controller are created by this driver. + If this parameter is not NULL and the first Device Path Node is + not the End of Device Path Node, then only the handle for the + child device specified by the first Device Path Node of + RemainingDevicePath is created by this driver. + If the first Device Path Node of RemainingDevicePath is + the End of Device Path Node, no child handle is created by this + driver. + + @retval EFI_SUCCESS The device was started. + @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others The driver failded to start the device. + +**/ +EFI_STATUS +EFIAPI +Ext4Bind ( + IN EFI_DRIVER_BINDING_PROTOCOL *BindingProtocol, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL + ) +{ + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_DISK_IO2_PROTOCOL *DiskIo2; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_STATUS Status; + + DiskIo2 = NULL; + BlockIo = NULL; + DiskIo = NULL; + + // Note: We initialize collation here since this is called in BDS, when we are likely + // to have the Unicode Collation protocols available. + Status = Ext4InitialiseUnicodeCollation (BindingProtocol->ImageHandle); + if (EFI_ERROR (Status)) { + // Lets throw a loud error into the log + // It is very unlikely something like this may fire out of the blue. Chances are either + // the platform configuration is wrong, or we are. + DEBUG ((DEBUG_ERROR, "[ext4] Error: Unicode Collation not available - failure to Start() - error %r\n", Status)); + goto Error; + } + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + (VOID **)&DiskIo, + BindingProtocol->ImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (EFI_ERROR (Status)) { + goto Error; + } + + DEBUG ((DEBUG_INFO, "[ext4] Controller supports DISK_IO\n")); + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiDiskIo2ProtocolGuid, + (VOID **)&DiskIo2, + BindingProtocol->ImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + // It's okay to not support DISK_IO2 + + if (DiskIo2 != NULL) { + DEBUG ((DEBUG_INFO, "[ext4] Controller supports DISK_IO2\n")); + } + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiBlockIoProtocolGuid, + (VOID **)&BlockIo, + BindingProtocol->ImageHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + goto Error; + } + + Status = Ext4OpenPartition (ControllerHandle, DiskIo, DiskIo2, BlockIo); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[ext4] Error mounting: %r\n", Status)); + // Falls through to Error + } else { + return Status; + } + +Error: + if (DiskIo) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiDiskIoProtocolGuid, + BindingProtocol->ImageHandle, + ControllerHandle + ); + } + + if (DiskIo2) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiDiskIo2ProtocolGuid, + BindingProtocol->ImageHandle, + ControllerHandle + ); + } + + if (BlockIo) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiBlockIoProtocolGuid, + BindingProtocol->ImageHandle, + ControllerHandle + ); + } + + return Status; +} diff --git a/Ext4Pkg/Ext4Dxe/Ext4Dxe.h b/Ext4Pkg/Ext4Dxe/Ext4Dxe.h new file mode 100644 index 0000000000..786e20f49f --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/Ext4Dxe.h @@ -0,0 +1,1255 @@ +/** @file + Common header for the driver + + Copyright (c) 2021 - 2023 Pedro Falcato All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef EXT4_H_ +#define EXT4_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Ext4Disk.h" + +#define SYMLOOP_MAX 8 +// +// We need to specify path length limit for security purposes, to prevent possible +// overflows and dead-loop conditions. Originally this limit is absent in FS design, +// but present in UNIX distros and shell environments, which may varies from 1024 to 4096. +// +#define EXT4_EFI_PATH_MAX 4096 +#define EXT4_DRIVER_VERSION 0x0000 + +// +// The EXT4 Specification doesn't strictly limit block size and this value could be up to 2^31, +// but in practice it is limited by PAGE_SIZE due to performance significant impact. +// Many EXT4 implementations have size of block limited to PAGE_SIZE. In many cases it's limited +// to 4096, which is a commonly supported page size on most MMU-capable hardware, and up to 65536. +// So, to take a balance between compatibility and security measures, it is decided to use the +// value of 2MiB as the limit, which is equal to large page size on new hardware. +// As for supporting big block sizes, EXT4 has a RO_COMPAT_FEATURE called BIGALLOC, which changes +// EXT4 to use clustered allocation, so that each bit in the ext4 block allocation bitmap addresses +// a power of two number of blocks. So it would be wiser to implement and use this feature +// if there is such a need instead of big block size. +// +#define EXT4_LOG_BLOCK_SIZE_MAX 11 + +/** + Opens an ext4 partition and installs the Simple File System protocol. + + @param[in] DeviceHandle Handle to the block device. + @param[in] DiskIo Pointer to an EFI_DISK_IO_PROTOCOL. + @param[in opt] DiskIo2 Pointer to an EFI_DISK_IO2_PROTOCOL, +if supported. + @param[in] BlockIo Pointer to an EFI_BLOCK_IO_PROTOCOL. + + @retval EFI_SUCCESS The opening was successful. + !EFI_SUCCESS Opening failed. +**/ +EFI_STATUS +Ext4OpenPartition ( + IN EFI_HANDLE DeviceHandle, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN OPTIONAL EFI_DISK_IO2_PROTOCOL *DiskIo2, + IN EFI_BLOCK_IO_PROTOCOL *BlockIo + ); + +typedef struct _Ext4File EXT4_FILE; +typedef struct _Ext4_Dentry EXT4_DENTRY; + +typedef struct _Ext4_PARTITION { + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL Interface; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_DISK_IO2_PROTOCOL *DiskIo2; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + + EXT4_SUPERBLOCK SuperBlock; + BOOLEAN Unmounting; + + UINT32 FeaturesIncompat; + UINT32 FeaturesCompat; + UINT32 FeaturesRoCompat; + UINT32 InodeSize; + UINT32 BlockSize; + BOOLEAN ReadOnly; + UINT64 NumberBlockGroups; + EXT4_BLOCK_NR NumberBlocks; + + EXT4_BLOCK_GROUP_DESC *BlockGroups; + UINT32 DescSize; + EXT4_FILE *Root; + + UINT32 InitialSeed; + + LIST_ENTRY OpenFiles; + + EXT4_DENTRY *RootDentry; +} EXT4_PARTITION; + +/** + This structure represents a directory entry inside our directory entry tree. + For now, it will be used as a way to track file names inside our opening + code, but it may very well be used as a directory cache in the future. + Because it's not being used as a directory cache right now, + an EXT4_DENTRY structure is not necessarily unique name-wise in the list of + children. Therefore, the dentry tree does not accurately reflect the + filesystem structure. + */ +struct _Ext4_Dentry { + UINTN RefCount; + CHAR16 Name[EXT4_NAME_MAX + 1]; + EXT4_INO_NR Inode; + struct _Ext4_Dentry *Parent; + LIST_ENTRY Children; + LIST_ENTRY ListNode; +}; + +#define EXT4_DENTRY_FROM_DENTRY_LIST(Node) BASE_CR(Node, EXT4_DENTRY, ListNode) + +/** + Creates a new dentry object. + + @param[in] Name Name of the dentry. + @param[in out opt] Parent Parent dentry, if it's not NULL. + + @return The new allocated and initialised dentry. + The ref count will be set to 1. +**/ +EXT4_DENTRY * +Ext4CreateDentry ( + IN CONST CHAR16 *Name, + IN OUT EXT4_DENTRY *Parent OPTIONAL + ); + +/** + Increments the ref count of the dentry. + + @param[in out] Dentry Pointer to a valid EXT4_DENTRY. +**/ +VOID +Ext4RefDentry ( + IN OUT EXT4_DENTRY *Dentry + ); + +/** + Decrements the ref count of the dentry. + If the ref count is 0, it's destroyed. + + @param[in out] Dentry Pointer to a valid EXT4_DENTRY. + + @retval True if it was destroyed, false if it's alive. +**/ +BOOLEAN +Ext4UnrefDentry ( + IN OUT EXT4_DENTRY *Dentry + ); + +/** + Opens and parses the superblock. + + @param[out] Partition Partition structure to fill with filesystem +details. + @retval EFI_SUCCESS Parsing was successful and the partition is a + valid ext4 partition. +**/ +EFI_STATUS +Ext4OpenSuperblock ( + OUT EXT4_PARTITION *Partition + ); + +/** + Retrieves the EFI_BLOCK_IO_PROTOCOL of the partition. + + @param[in] Partition Pointer to the opened ext4 partition. + @return The Block IO protocol associated with the partition. +**/ +#define EXT4_BLOCK_IO(Partition) Partition->BlockIo + +/** + Retrieves the EFI_DISK_IO_PROTOCOL of the partition. + + @param[in] Partition Pointer to the opened ext4 partition. + @return The Disk IO protocol associated with the partition. +**/ +#define EXT4_DISK_IO(Partition) Partition->DiskIo + +/** + Retrieves the EFI_DISK_IO2_PROTOCOL of the partition. + + @param[in] Partition Pointer to the opened ext4 partition. + @return The Disk IO 2 protocol associated with the partition, or NULL if + not supported. +**/ +#define EXT4_DISK_IO2(Partition) Partition->DiskIo2 + +/** + Retrieves the media ID of the partition. + + @param[in] Partition Pointer to the opened ext4 partition. + @return The media ID associated with the partition. +**/ +#define EXT4_MEDIA_ID(Partition) Partition->BlockIo->Media->MediaId + +/** + Reads from the partition's disk using the DISK_IO protocol. + + @param[in] Partition Pointer to the opened ext4 partition. + @param[out] Buffer Pointer to a destination buffer. + @param[in] Length Length of the destination buffer. + @param[in] Offset Offset, in bytes, of the location to read. + + @return Success status of the disk read. +**/ +EFI_STATUS +Ext4ReadDiskIo ( + IN EXT4_PARTITION *Partition, + OUT VOID *Buffer, + IN UINTN Length, + IN UINT64 Offset + ); + +/** + Reads blocks from the partition's disk using the DISK_IO protocol. + + @param[in] Partition Pointer to the opened ext4 partition. + @param[out] Buffer Pointer to a destination buffer. + @param[in] NumberBlocks Length of the read, in filesystem blocks. + @param[in] BlockNumber Starting block number. + + @return Success status of the read. +**/ +EFI_STATUS +Ext4ReadBlocks ( + IN EXT4_PARTITION *Partition, + OUT VOID *Buffer, + IN UINTN NumberBlocks, + IN EXT4_BLOCK_NR BlockNumber + ); + +/** + Allocates a buffer and reads blocks from the partition's disk using the +DISK_IO protocol. This function is deprecated and will be removed in the future. + + @param[in] Partition Pointer to the opened ext4 partition. + @param[in] NumberBlocks Length of the read, in filesystem blocks. + @param[in] BlockNumber Starting block number. + + @return Buffer allocated by AllocatePool, or NULL if some part of the process + failed. +**/ +VOID * +Ext4AllocAndReadBlocks ( + IN EXT4_PARTITION *Partition, + IN UINTN NumberBlocks, + IN EXT4_BLOCK_NR BlockNumber + ); + +/** + Checks if the opened partition has the 64-bit feature (see +EXT4_FEATURE_INCOMPAT_64BIT). + + @param[in] Partition Pointer to the opened ext4 partition. + + @return TRUE if EXT4_FEATURE_INCOMPAT_64BIT is enabled, else FALSE. +**/ +#define EXT4_IS_64_BIT(Partition) \ + ((Partition->FeaturesIncompat & EXT4_FEATURE_INCOMPAT_64BIT) != 0) + +/** + Composes an EXT4_BLOCK_NR safely, from two halfs. + + @param[in] Partition Pointer to the opened ext4 partition. + @param[in] Low Low half of the block number. + @param[in] High High half of the block number. + + @return The block number formed by Low, and if 64 bit is enabled, High. +**/ +#define EXT4_BLOCK_NR_FROM_HALFS(Partition, Low, High) \ + EXT4_IS_64_BIT(Partition) ? (Low | LShiftU64(High, 32)) : Low + +/** + Retrieves a block group descriptor of the ext4 filesystem. + + @param[in] Partition Pointer to the opened ext4 partition. + @param[in] BlockGroup Block group number. + + @return A pointer to the block group descriptor. +**/ +EXT4_BLOCK_GROUP_DESC * +Ext4GetBlockGroupDesc ( + IN EXT4_PARTITION *Partition, + IN UINT32 BlockGroup + ); + +/** + Checks inode number validity across superblock of the opened partition. + + @param[in] Partition Pointer to the opened ext4 partition. + + @return TRUE if inode number is valid. +**/ +#define EXT4_IS_VALID_INODE_NR(Partition, InodeNum) \ + (((InodeNum) > 0) && (InodeNum) <= (Partition->SuperBlock.s_inodes_count)) + +/** + Reads an inode from disk. + + @param[in] Partition Pointer to the opened partition. + @param[in] InodeNum Number of the desired Inode + @param[out] OutIno Pointer to where it will be stored a pointer to the +read inode. + + @return Status of the inode read. +**/ +EFI_STATUS +Ext4ReadInode ( + IN EXT4_PARTITION *Partition, + IN EXT4_INO_NR InodeNum, + OUT EXT4_INODE **OutIno + ); + +/** + Converts blocks to bytes. + + @param[in] Partition Pointer to the opened partition. + @param[in] Block Block number/number of blocks. + + @return The number of bytes. +**/ +#define EXT4_BLOCK_TO_BYTES(Partition, Block) \ + MultU64x32(Block, Partition->BlockSize) + +/** + Reads from an EXT4 inode. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] File Pointer to the opened file. + @param[out] Buffer Pointer to the buffer. + @param[in] Offset Offset of the read. + @param[in out] Length Pointer to the length of the buffer, in bytes. + After a successful read, it's updated to the +number of read bytes. + + @return Status of the read operation. +**/ +EFI_STATUS +Ext4Read ( + IN EXT4_PARTITION *Partition, + IN EXT4_FILE *File, + OUT VOID *Buffer, + IN UINT64 Offset, + IN OUT UINTN *Length + ); + +/** + Retrieves the size of the inode. + + @param[in] Inode Pointer to the ext4 inode. + + @return The size of the inode, in bytes. +**/ +#define EXT4_INODE_SIZE(Inode) \ + (LShiftU64(Inode->i_size_hi, 32) | Inode->i_size_lo) + +/** + Retrieves an extent from an EXT4 inode. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] File Pointer to the opened file. + @param[in] LogicalBlock Block number which the returned extent must +cover. + @param[out] Extent Pointer to the output buffer, where the extent +will be copied to. + + @retval EFI_SUCCESS Retrieval was successful. + @retval EFI_NO_MAPPING Block has no mapping. +**/ +EFI_STATUS +Ext4GetExtent ( + IN EXT4_PARTITION *Partition, + IN EXT4_FILE *File, + IN EXT4_BLOCK_NR LogicalBlock, + OUT EXT4_EXTENT *Extent + ); + +struct _Ext4File { + EFI_FILE_PROTOCOL Protocol; + EXT4_INODE *Inode; + EXT4_INO_NR InodeNum; + + UINT64 OpenMode; + UINT64 Position; + UINT32 SymLoops; + + EXT4_PARTITION *Partition; + + ORDERED_COLLECTION *ExtentsMap; + + LIST_ENTRY OpenFilesListNode; + + // Owning reference to this file's directory entry. + EXT4_DENTRY *Dentry; +}; + +#define EXT4_FILE_FROM_THIS(This) BASE_CR ((This), EXT4_FILE, Protocol) + +#define EXT4_FILE_FROM_OPEN_FILES_NODE(Node) \ + BASE_CR(Node, EXT4_FILE, OpenFilesListNode) + +/** + Retrieves a directory entry. + + @param[in] Directory Pointer to the opened directory. + @param[in] NameUnicode Pointer to the UCS-2 formatted filename. + @param[in] Partition Pointer to the ext4 partition. + @param[out] Result Pointer to the destination directory entry. + + @return The result of the operation. +**/ +EFI_STATUS +Ext4RetrieveDirent ( + IN EXT4_FILE *Directory, + IN CONST CHAR16 *NameUnicode, + IN EXT4_PARTITION *Partition, + OUT EXT4_DIR_ENTRY *Result + ); + +/** + Opens a file. + + @param[in] Directory Pointer to the opened directory. + @param[in] Name Pointer to the UCS-2 formatted filename. + @param[in] Partition Pointer to the ext4 partition. + @param[in] OpenMode Mode in which the file is supposed to be open. + @param[out] OutFile Pointer to the newly opened file. + + @return Result of the operation. +**/ +EFI_STATUS +Ext4OpenFile ( + IN EXT4_FILE *Directory, + IN CONST CHAR16 *Name, + IN EXT4_PARTITION *Partition, + IN UINT64 OpenMode, + OUT EXT4_FILE **OutFile + ); + +/** + Opens a file using a directory entry. + + @param[in] Partition Pointer to the ext4 partition. + @param[in] OpenMode Mode in which the file is supposed to be open. + @param[out] OutFile Pointer to the newly opened file. + @param[in] Entry Directory entry to be used. + @param[in] Directory Pointer to the opened directory. + + @retval EFI_STATUS Result of the operation +**/ +EFI_STATUS +Ext4OpenDirent ( + IN EXT4_PARTITION *Partition, + IN UINT64 OpenMode, + OUT EXT4_FILE **OutFile, + IN EXT4_DIR_ENTRY *Entry, + IN EXT4_FILE *Directory + ); + +/** + Allocates a zeroed inode structure. + @param[in] Partition Pointer to the opened EXT4 partition. + + @return Pointer to the allocated structure, from the pool, + with size Partition->InodeSize. +**/ +EXT4_INODE * +Ext4AllocateInode ( + IN EXT4_PARTITION *Partition + ); + +// Part of the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL + +/** + Open the root directory on a volume. + + @param[in] This A pointer to the volume to open the root directory. + @param[out] Root A pointer to the location to return the opened file handle +for the root directory. + + @retval EFI_SUCCESS The device was opened. + @retval EFI_UNSUPPORTED This volume does not support the requested file +system type. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of +resources. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the +medium is no longer supported. Any existing file handles for this volume are no +longer valid. To access the files on the new medium, the volume must be reopened +with OpenVolume(). + +**/ +EFI_STATUS +EFIAPI +Ext4OpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + IN EFI_FILE_PROTOCOL **Root + ); + +// End of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL + +/** + Sets up the protocol and metadata of a file that is being opened. + + @param[in out] File Pointer to the file. + @param[in] Partition Pointer to the opened partition. +**/ +VOID +Ext4SetupFile ( + IN OUT EXT4_FILE *File, + IN EXT4_PARTITION *Partition + ); + +/** + Opens a new file relative to the source file's location. + + @param[out] FoundFile A pointer to the location to return the opened handle for the new + file. + @param[in] Source A pointer to the EXT4_FILE instance that is the file + handle to the source location. This would typically be an open + handle to a directory. + @param[in] FileName The Null-terminated string of the name of the file to be opened. + The file name may contain the following path modifiers: "\", ".", + and "..". + @param[in] OpenMode The mode to open the file. The only valid combinations that the + file may be opened with are: Read, Read/Write, or Create/Read/Write. + @param[in] Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the + attribute bits for the newly created file. + + @retval EFI_SUCCESS The file was opened. + @retval EFI_NOT_FOUND The specified file could not be found on the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no + longer supported. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write + when the media is write-protected. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +Ext4OpenInternal ( + OUT EXT4_FILE **FoundFile, + IN EXT4_FILE *Source, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +/** + Closes a file. + + @param[in] File Pointer to the file. + + @return Status of the closing of the file. +**/ +EFI_STATUS +Ext4CloseInternal ( + IN EXT4_FILE *File + ); + +// Part of the EFI_FILE_PROTOCOL + +/** + Opens a new file relative to the source file's location. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the +file handle to the source location. This would typically be an open handle to a +directory. + @param[out] NewHandle A pointer to the location to return the opened handle +for the new file. + @param[in] FileName The Null-terminated string of the name of the file to +be opened. The file name may contain the following path modifiers: "\", ".", and +"..". + @param[in] OpenMode The mode to open the file. The only valid combinations +that the file may be opened with are: Read, Read/Write, or Create/Read/Write. + @param[in] Attributes Only valid for EFI_FILE_MODE_CREATE, in which case +these are the attribute bits for the newly created file. + + @retval EFI_SUCCESS The file was opened. + @retval EFI_NOT_FOUND The specified file could not be found on the +device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the +medium is no longer supported. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a +file for write when the media is write-protected. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the +file. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +EFIAPI +Ext4Open ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +/** + Closes a specified file handle. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is +the file handle to close. + + @retval EFI_SUCCESS The file was closed. + +**/ +EFI_STATUS +EFIAPI +Ext4Close ( + IN EFI_FILE_PROTOCOL *This + ); + +/** + Close and delete the file handle. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL +instance that is the handle to the file to delete. + + @retval EFI_SUCCESS The file was closed and deleted, and the +handle was closed. + @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not +deleted. + +**/ +EFI_STATUS +EFIAPI +Ext4Delete ( + IN EFI_FILE_PROTOCOL *This + ); + +/** + Reads data from a file. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance +that is the file handle to read data from. + @param[in out] BufferSize On input, the size of the Buffer. On output, +the amount of data returned in Buffer. In both cases, the size is measured in +bytes. + @param[out] Buffer The buffer into which the data is read. + + @retval EFI_SUCCESS Data was read. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file. + @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the +end of the file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current +directory entry. BufferSize has been updated with the size needed to complete +the request. + +**/ +EFI_STATUS +EFIAPI +Ext4ReadFile ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +/** + Writes data to a file. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that +is the file handle to write data to. + @param[in out] BufferSize On input, the size of the Buffer. On output, the +amount of data actually written. In both cases, the size is measured in bytes. + @param[in] Buffer The buffer of data to write. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Writes to open directory files are not supported. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The file or medium is write-protected. + @retval EFI_ACCESS_DENIED The file was opened read only. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +EFIAPI +Ext4WriteFile ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +/** + Returns a file's current position. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that +is the file handle to get the current position on. + @param[out] Position The address to return the file's current position +value. + + @retval EFI_SUCCESS The position was returned. + @retval EFI_UNSUPPORTED The request is not valid on open directories. + @retval EFI_DEVICE_ERROR An attempt was made to get the position from a +deleted file. + +**/ +EFI_STATUS +EFIAPI +Ext4GetPosition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ); + +/** + Sets a file's current position. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that +is the file handle to set the requested position on. + @param[in] Position The byte position from the start of the file to +set. + + @retval EFI_SUCCESS The position was set. + @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open + directories. + @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted +file. + +**/ +EFI_STATUS +EFIAPI +Ext4SetPosition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ); + +/** + Returns information about a file. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance +that is the file handle the requested information is for. + @param[in] InformationType The type identifier for the information being +requested. + @param[in out] BufferSize On input, the size of Buffer. On output, the +amount of data returned in Buffer. In both cases, the size is measured in bytes. + @param[out] Buffer A pointer to the data buffer to return. The +buffer's type is indicated by InformationType. + + @retval EFI_SUCCESS The information was returned. + @retval EFI_UNSUPPORTED The InformationType is not known. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current +directory entry. BufferSize has been updated with the size needed to complete + the request. +**/ +EFI_STATUS +EFIAPI +Ext4GetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +/** + Sets information about a file. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that +is the file handle the information is for. + @param[in] InformationType The type identifier for the information being set. + @param[in] BufferSize The size, in bytes, of Buffer. + @param[in] Buffer A pointer to the data buffer to write. The +buffer's type is indicated by InformationType. + + @retval EFI_SUCCESS The information was set. + @retval EFI_UNSUPPORTED The InformationType is not known. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_INFO_ID and the media +is read-only. + @retval EFI_WRITE_PROTECTED InformationType is +EFI_FILE_PROTOCOL_SYSTEM_INFO_ID and the media is read only. + @retval EFI_WRITE_PROTECTED InformationType is +EFI_FILE_SYSTEM_VOLUME_LABEL_ID and the media is read-only. + @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file +to a file that is already present. + @retval EFI_ACCESS_DENIED An attempt is being made to change the +EFI_FILE_DIRECTORY Attribute. + @retval EFI_ACCESS_DENIED An attempt is being made to change the size of a +directory. + @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the file +was opened read-only and an attempt is being made to modify a field other than +Attribute. + @retval EFI_VOLUME_FULL The volume is full. + @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of the type +indicated by InformationType. + +**/ +EFI_STATUS +EFIAPI +Ext4SetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +// EFI_FILE_PROTOCOL implementation ends here. + +/** + Checks if a file is a directory. + @param[in] File Pointer to the opened file. + + @return TRUE if file is a directory. +**/ +BOOLEAN +Ext4FileIsDir ( + IN CONST EXT4_FILE *File + ); + +/** + Checks if a file is a symlink. + + @param[in] File Pointer to the opened file. + + @return BOOLEAN Whether file is a symlink +**/ +BOOLEAN +Ext4FileIsSymlink ( + IN CONST EXT4_FILE *File + ); + +/** + Checks if a file is a regular file. + @param[in] File Pointer to the opened file. + + @return BOOLEAN TRUE if file is a regular file. +**/ +BOOLEAN +Ext4FileIsReg ( + IN CONST EXT4_FILE *File + ); + +// In EFI we can't open FIFO pipes, UNIX sockets, character/block devices since +// these concepts are at the kernel level and are OS dependent. + +/** + Checks if a file is openable. + @param[in] File Pointer to the file trying to be opened. + + + @return TRUE if file is openable. A file is considered openable if + it's a regular file or a directory, since most other file types + don't make sense under UEFI. +**/ +#define Ext4FileIsOpenable(File) (Ext4FileIsReg (File) || Ext4FileIsDir (File) || Ext4FileIsSymlink (File)) + +#define EXT4_INODE_HAS_FIELD(Inode, Field) \ + (Inode->i_extra_isize + EXT4_GOOD_OLD_INODE_SIZE >= \ + OFFSET_OF(EXT4_INODE, Field) + sizeof(((EXT4_INODE *)NULL)->Field)) + +/** + Calculates the physical space used by a file. + @param[in] File Pointer to the opened file. + + @return Physical space used by a file, in bytes. +**/ +UINT64 +Ext4FilePhysicalSpace ( + IN EXT4_FILE *File + ); + +/** + Gets the file's last access time. + @param[in] File Pointer to the opened file. + @param[out] Time Pointer to an EFI_TIME structure. +**/ +VOID +Ext4FileATime ( + IN EXT4_FILE *File, + OUT EFI_TIME *Time + ); + +/** + Gets the file's last (data) modification time. + @param[in] File Pointer to the opened file. + @param[out] Time Pointer to an EFI_TIME structure. +**/ +VOID +Ext4FileMTime ( + IN EXT4_FILE *File, + OUT EFI_TIME *Time + ); + +/** + Gets the file's creation time, if possible. + @param[in] File Pointer to the opened file. + @param[out] Time Pointer to an EFI_TIME structure. + In the case where the the creation time isn't +recorded, Time is zeroed. +**/ +VOID +Ext4FileCreateTime ( + IN EXT4_FILE *File, + OUT EFI_TIME *Time + ); + +/** + Initialises Unicode collation, which is needed for case-insensitive string +comparisons within the driver (a good example of an application of this is +filename comparison). + + @param[in] DriverHandle Handle to the driver image. + + @retval EFI_SUCCESS Unicode collation was successfully initialised. + @retval !EFI_SUCCESS Failure. +**/ +EFI_STATUS +Ext4InitialiseUnicodeCollation ( + EFI_HANDLE DriverHandle + ); + +/** + Does a case-insensitive string comparison. Refer to +EFI_UNICODE_COLLATION_PROTOCOL's StriColl for more details. + + @param[in] Str1 Pointer to a null terminated string. + @param[in] Str2 Pointer to a null terminated string. + + @retval 0 Str1 is equivalent to Str2. + @retval >0 Str1 is lexically greater than Str2. + @retval <0 Str1 is lexically less than Str2. +**/ +INTN +Ext4StrCmpInsensitive ( + IN CHAR16 *Str1, + IN CHAR16 *Str2 + ); + +/** + Retrieves the filename of the directory entry and converts it to UTF-16/UCS-2 + + @param[in] Entry Pointer to a EXT4_DIR_ENTRY. + @param[out] Ucs2FileName Pointer to an array of CHAR16's, of size EXT4_NAME_MAX + 1. + + @retval EFI_SUCCESS The filename was successfully retrieved and converted to UCS2. + @retval EFI_INVALID_PARAMETER The filename is not valid UTF-8. + @retval !EFI_SUCCESS Failure. +**/ +EFI_STATUS +Ext4GetUcs2DirentName ( + IN EXT4_DIR_ENTRY *Entry, + OUT CHAR16 Ucs2FileName[EXT4_NAME_MAX + 1] + ); + +/** + Retrieves information about the file and stores it in the EFI_FILE_INFO +format. + + @param[in] File Pointer to an opened file. + @param[out] Info Pointer to a EFI_FILE_INFO. + @param[in out] BufferSize Pointer to the buffer size + + @return Status of the file information request. +**/ +EFI_STATUS +Ext4GetFileInfo ( + IN EXT4_FILE *File, + OUT EFI_FILE_INFO *Info, + IN OUT UINTN *BufferSize + ); + +/** + Reads a directory entry. + + @param[in] Partition Pointer to the ext4 partition. + @param[in] File Pointer to the open directory. + @param[out] Buffer Pointer to the output buffer. + @param[in] Offset Initial directory position. + @param[in out] OutLength Pointer to a UINTN that contains the length of +the buffer, and the length of the actual EFI_FILE_INFO after the call. + + @return Result of the operation. +**/ +EFI_STATUS +Ext4ReadDir ( + IN EXT4_PARTITION *Partition, + IN EXT4_FILE *File, + OUT VOID *Buffer, + IN UINT64 Offset, + IN OUT UINTN *OutLength + ); + +/** + Initialises the (empty) extents map, that will work as a cache of extents. + + @param[in] File Pointer to the open file. + + @return Result of the operation. +**/ +EFI_STATUS +Ext4InitExtentsMap ( + IN EXT4_FILE *File + ); + +/** + Frees the extents map, deleting every extent stored. + + @param[in] File Pointer to the open file. +**/ +VOID +Ext4FreeExtentsMap ( + IN EXT4_FILE *File + ); + +/** + Calculates the checksum of the given buffer. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] Buffer Pointer to the buffer. + @param[in] Length Length of the buffer, in bytes. + @param[in] InitialValue Initial value of the CRC. + + @return The checksum. +**/ +UINT32 +Ext4CalculateChecksum ( + IN CONST EXT4_PARTITION *Partition, + IN CONST VOID *Buffer, + IN UINTN Length, + IN UINT32 InitialValue + ); + +/** + Calculates the checksum of the given inode. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] Inode Pointer to the inode. + @param[in] InodeNum Inode number. + + @return The checksum. +**/ +UINT32 +Ext4CalculateInodeChecksum ( + IN CONST EXT4_PARTITION *Partition, + IN CONST EXT4_INODE *Inode, + IN EXT4_INO_NR InodeNum + ); + +/** + Checks if the checksum of the inode is correct. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] Inode Pointer to the inode. + @param[in] InodeNum Inode number. + + @return TRUE if checksum is correct, FALSE if there is corruption. +**/ +BOOLEAN +Ext4CheckInodeChecksum ( + IN CONST EXT4_PARTITION *Partition, + IN CONST EXT4_INODE *Inode, + IN EXT4_INO_NR InodeNum + ); + +/** + Unmounts and frees an ext4 partition. + + @param[in] Partition Pointer to the opened partition. + + @return Status of the unmount. +**/ +EFI_STATUS +Ext4UnmountAndFreePartition ( + IN EXT4_PARTITION *Partition + ); + +/** + Checks if the checksum of the block group descriptor is correct. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] BlockGroupDesc Pointer to the block group descriptor. + @param[in] BlockGroupNum Number of the block group. + + @return TRUE if checksum is correct, FALSE if there is corruption. +**/ +BOOLEAN +Ext4VerifyBlockGroupDescChecksum ( + IN CONST EXT4_PARTITION *Partition, + IN CONST EXT4_BLOCK_GROUP_DESC *BlockGroupDesc, + IN UINT32 BlockGroupNum + ); + +/** + Calculates the checksum of the block group descriptor. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] BlockGroupDesc Pointer to the block group descriptor. + @param[in] BlockGroupNum Number of the block group. + + @return The checksum. +**/ +UINT16 +Ext4CalculateBlockGroupDescChecksum ( + IN CONST EXT4_PARTITION *Partition, + IN CONST EXT4_BLOCK_GROUP_DESC *BlockGroupDesc, + IN UINT32 BlockGroupNum + ); + +/** + Verifies the existence of a particular RO compat feature set. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] RoCompatFeatureSet Feature set to test. + + @return TRUE if all features are supported, else FALSE. +**/ +#define EXT4_HAS_RO_COMPAT(Partition, RoCompatFeatureSet) \ + ((Partition->FeaturesRoCompat & RoCompatFeatureSet) == RoCompatFeatureSet) + +/** + Verifies the existence of a particular compat feature set. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] CompatFeatureSet Feature set to test. + + @return TRUE if all features are supported, else FALSE. +**/ +#define EXT4_HAS_COMPAT(Partition, CompatFeatureSet) \ + ((Partition->FeaturesCompat & CompatFeatureSet) == CompatFeatureSet) + +/** + Verifies the existence of a particular compat feature set. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] IncompatFeatureSet Feature set to test. + + @return TRUE if all features are supported, else FALSE. +**/ +#define EXT4_HAS_INCOMPAT(Partition, IncompatFeatureSet) \ + ((Partition->FeaturesIncompat & IncompatFeatureSet) == IncompatFeatureSet) + +// Note: Might be a good idea to provide generic Ext4Has$feature() through +// macros. + +/** + Checks if metadata_csum is enabled on the partition. + @param[in] Partition Pointer to the opened EXT4 partition. + + @return TRUE if the metadata_csum is supported, else FALSE. +**/ +#define EXT4_HAS_METADATA_CSUM(Partition) \ + EXT4_HAS_RO_COMPAT(Partition, EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) + +/** + Checks if gdt_csum is enabled on the partition. + @param[in] Partition Pointer to the opened EXT4 partition. + + @return TRUE if the gdt_csum is supported, else FALSE. +**/ +#define EXT4_HAS_GDT_CSUM(Partition) \ + EXT4_HAS_RO_COMPAT(Partition, EXT4_FEATURE_RO_COMPAT_GDT_CSUM) + +/** + Retrieves the volume name. + + @param[in] Part Pointer to the opened partition. + @param[out] Info Pointer to a CHAR16*. + @param[out] BufferSize Pointer to a UINTN, where the string length + of the name will be put. + + @return Status of the volume name request. +**/ +EFI_STATUS +Ext4GetVolumeName ( + IN EXT4_PARTITION *Partition, + OUT CHAR16 **OutVolName, + OUT UINTN *VolNameLen + ); + +/** + Checks the superblock's magic value. + + @param[in] DiskIo Pointer to the DiskIo. + @param[in] BlockIo Pointer to the BlockIo. + + @returns Whether the partition has a valid EXT4 superblock magic value. +**/ +BOOLEAN +Ext4SuperblockCheckMagic ( + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN EFI_BLOCK_IO_PROTOCOL *BlockIo + ); + +/** + Check if the extent is uninitialized + + @param[in] Extent Pointer to the EXT4_EXTENT + + @returns True if uninitialized, else false. +**/ +#define EXT4_EXTENT_IS_UNINITIALIZED(Extent) \ + ((Extent)->ee_len > EXT4_EXTENT_MAX_INITIALIZED) + +/** + Retrieves the extent's length, dealing with uninitialized extents in the +process. + + @param[in] Extent Pointer to the EXT4_EXTENT + + @returns Extent's length, in filesystem blocks. +**/ +EXT4_BLOCK_NR +Ext4GetExtentLength ( + IN CONST EXT4_EXTENT *Extent + ); + +/** + Retrieves an extent from an EXT2/3 inode (with a blockmap). + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] File Pointer to the opened file. + @param[in] LogicalBlock Block number which the returned extent must cover. + @param[out] Extent Pointer to the output buffer, where the extent will be copied to. + + @retval EFI_SUCCESS Retrieval was successful. + @retval EFI_NO_MAPPING Block has no mapping. +**/ +EFI_STATUS +Ext4GetBlocks ( + IN EXT4_PARTITION *Partition, + IN EXT4_FILE *File, + IN EXT2_BLOCK_NR LogicalBlock, + OUT EXT4_EXTENT *Extent + ); + +#endif diff --git a/Ext4Pkg/Ext4Dxe/Ext4Dxe.inf b/Ext4Pkg/Ext4Dxe/Ext4Dxe.inf new file mode 100644 index 0000000000..a153fc41cc --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/Ext4Dxe.inf @@ -0,0 +1,149 @@ +## @file +# Ext4 Package +# +# UEFI Driver that produces the Simple File System Protocol for a partition that is formatted +# with the EXT4 file system. +# More details are available at: https://www.kernel.org/doc/html/v5.4/filesystems/ext4/index.html +# +# Copyright (c) 2021 Pedro Falcato +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# Layout of an EXT2/3/4 filesystem: +# (note: this driver has been developed using +# https://www.kernel.org/doc/html/latest/filesystems/ext4/index.html as +# documentation). +# +# An ext2/3/4 filesystem (here on out referred to as simply an ext4 filesystem, +# due to the similarities) is composed of various concepts: +# +# 1) Superblock +# The superblock is the structure near (1024 bytes offset from the start) +# the start of the partition, and describes the filesystem in general. +# Here, we get to know the size of the filesystem's blocks, which features +# it supports or not, whether it's been cleanly unmounted, how many blocks +# we have, etc. +# +# 2) Block groups +# EXT4 filesystems are divided into block groups, and each block group covers +# s_blocks_per_group(8 * Block Size) blocks. Each block group has an +# associated block group descriptor; these are present directly after the +# superblock. Each block group descriptor contains the location of the +# inode table, and the inode and block bitmaps (note these bitmaps are only +# a block long, which gets us the 8 * Block Size formula covered previously). +# +# 3) Blocks +# The ext4 filesystem is divided in blocks, of size s_log_block_size ^ 1024. +# Blocks can be allocated using individual block groups's bitmaps. Note +# that block 0 is invalid and its presence on extents/block tables means +# it's part of a file hole, and that particular location must be read as +# a block full of zeros. +# +# 4) Inodes +# The ext4 filesystem divides files/directories into inodes (originally +# index nodes). Each file/socket/symlink/directory/etc (here on out referred +# to as a file, since there is no distinction under the ext4 filesystem) is +# stored as a /nameless/ inode, that is stored in some block group's inode +# table. Each inode has s_inode_size size (or GOOD_OLD_INODE_SIZE if it's +# an old filesystem), and holds various metadata about the file. Since the +# largest inode structure right now is ~160 bytes, the rest of the inode +# contains inline extended attributes. Inodes' data is stored using either +# data blocks (under ext2/3) or extents (under ext4). +# +# 5) Extents +# Ext4 inodes store data in extents. These let N contiguous logical blocks +# that are represented by N contiguous physical blocks be represented by a +# single extent structure, which minimizes filesystem metadata bloat and +# speeds up block mapping (particularly due to the fact that high-quality +# ext4 implementations like linux's try /really/ hard to make the file +# contiguous, so it's common to have files with almost 0 fragmentation). +# Inodes that use extents store them in a tree, and the top of the tree +# is stored on i_data. The tree's leaves always start with an +# EXT4_EXTENT_HEADER and contain EXT4_EXTENT_INDEX on eh_depth != 0 and +# EXT4_EXTENT on eh_depth = 0; these entries are always sorted by logical +# block. +# +# 6) Directories +# Ext4 directories are files that store name -> inode mappings for the +# logical directory; this is where files get their names, which means ext4 +# inodes do not themselves have names, since they can be linked (present) +# multiple times with different names. Directories can store entries in two +# different ways: +# 1) Classical linear directories: They store entries as a mostly-linked +# mostly-list of EXT4_DIR_ENTRY. +# 2) Hash tree directories: These are used for larger directories, with +# hundreds of entries, and are designed in a backwards compatible way. +# These are not yet implemented in the Ext4Dxe driver. +# +# 7) Journal +# Ext3/4 filesystems have a journal to help protect the filesystem against +# system crashes. This is not yet implemented in Ext4Dxe but is described +# in detail in the Linux kernel's documentation. +## + + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Ext4Dxe + MODULE_UNI_FILE = Ext4Dxe.uni + FILE_GUID = 75F2B676-D73B-45CB-B7C1-303C7F4E6FD6 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = Ext4EntryPoint + UNLOAD_IMAGE = Ext4Unload + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + Ext4Dxe.c + Partition.c + DiskUtil.c + Superblock.c + BlockGroup.c + Inode.c + Directory.c + Extents.c + File.c + Symlink.c + Collation.c + Ext4Disk.h + Ext4Dxe.h + BlockMap.c + +[Packages] + MdePkg/MdePkg.dec + RedfishPkg/RedfishPkg.dec + +[LibraryClasses] + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + MemoryAllocationLib + BaseMemoryLib + BaseLib + UefiLib + UefiDriverEntryPoint + DebugLib + PcdLib + OrderedCollectionLib + BaseUcs2Utf8Lib + +[Guids] + gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## UNDEFINED + gEfiFileSystemInfoGuid ## SOMETIMES_CONSUMES ## UNDEFINED + gEfiFileSystemVolumeLabelInfoIdGuid ## SOMETIMES_CONSUMES ## UNDEFINED + +[Protocols] + gEfiDiskIoProtocolGuid ## TO_START + gEfiDiskIo2ProtocolGuid ## TO_START + gEfiBlockIoProtocolGuid ## TO_START + gEfiSimpleFileSystemProtocolGuid ## BY_START + gEfiUnicodeCollationProtocolGuid ## TO_START + gEfiUnicodeCollation2ProtocolGuid ## TO_START + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLang ## SOMETIMES_CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang ## SOMETIMES_CONSUMES diff --git a/Ext4Pkg/Ext4Dxe/Ext4Dxe.uni b/Ext4Pkg/Ext4Dxe/Ext4Dxe.uni new file mode 100644 index 0000000000..7476fbf9bd --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/Ext4Dxe.uni @@ -0,0 +1,15 @@ +## @file +# Ext4 Package +# +# UEFI Driver that produces the Simple File System Protocol for a partition that is formatted +# with the EXT4 file system. +# More details are available at: https://www.kernel.org/doc/html/v5.4/filesystems/ext4/index.html +# +# Copyright (c) 2021 Pedro Falcato +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +#string STR_MODULE_ABSTRACT #language en-US "UEFI driver for the EXT4 file system." + +#string STR_MODULE_DESCRIPTION #language en-US "Produces the EFI Simple File System protocol." diff --git a/Ext4Pkg/Ext4Dxe/Extents.c b/Ext4Pkg/Ext4Dxe/Extents.c new file mode 100644 index 0000000000..2b82417c9e --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/Extents.c @@ -0,0 +1,658 @@ +/** @file + Extent related routines + + Copyright (c) 2021 - 2023 Pedro Falcato All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Ext4Dxe.h" + +/** + Checks if the checksum of the extent data block is correct. + @param[in] ExtHeader Pointer to the EXT4_EXTENT_HEADER. + @param[in] File Pointer to the file. + + @return TRUE if the checksum is correct, FALSE if there is corruption. +**/ +BOOLEAN +Ext4CheckExtentChecksum ( + IN CONST EXT4_EXTENT_HEADER *ExtHeader, + IN CONST EXT4_FILE *File + ); + +/** + Calculates the checksum of the extent data block. + @param[in] ExtHeader Pointer to the EXT4_EXTENT_HEADER. + @param[in] File Pointer to the file. + + @return The checksum. +**/ +UINT32 +Ext4CalculateExtentChecksum ( + IN CONST EXT4_EXTENT_HEADER *ExtHeader, + IN CONST EXT4_FILE *File + ); + +/** + Caches a range of extents, by allocating pool memory for each extent and adding it to the tree. + + @param[in] File Pointer to the open file. + @param[in] Extents Pointer to an array of extents. + @param[in] NumberExtents Length of the array. +**/ +VOID +Ext4CacheExtents ( + IN EXT4_FILE *File, + IN CONST EXT4_EXTENT *Extents, + IN UINT16 NumberExtents + ); + +/** + Gets an extent from the extents cache of the file. + + @param[in] File Pointer to the open file. + @param[in] Block Block we want to grab. + + @return Pointer to the extent, or NULL if it was not found. +**/ +EXT4_EXTENT * +Ext4GetExtentFromMap ( + IN EXT4_FILE *File, + IN UINT32 Block + ); + +/** + Retrieves the pointer to the top of the extent tree. + @param[in] Inode Pointer to the inode structure. + + @return Pointer to an EXT4_EXTENT_HEADER. This pointer is inside + the inode and must not be freed. +**/ +STATIC +EXT4_EXTENT_HEADER * +Ext4GetInoExtentHeader ( + IN EXT4_INODE *Inode + ) +{ + return (EXT4_EXTENT_HEADER *)Inode->i_data; +} + +/** + Checks if an extent header is valid. + @param[in] Header Pointer to the EXT4_EXTENT_HEADER structure. + @param[in] MaxEntries Maximum number of entries possible for this tree node. + + @return TRUE if valid, FALSE if not. +**/ +STATIC +BOOLEAN +Ext4ExtentHeaderValid ( + IN CONST EXT4_EXTENT_HEADER *Header, + IN UINT16 MaxEntries + ) +{ + if (Header->eh_depth > EXT4_EXTENT_TREE_MAX_DEPTH) { + DEBUG ((DEBUG_ERROR, "[ext4] Invalid extent header depth %u\n", Header->eh_depth)); + return FALSE; + } + + if (Header->eh_magic != EXT4_EXTENT_HEADER_MAGIC) { + DEBUG ((DEBUG_ERROR, "[ext4] Invalid extent header magic %x\n", Header->eh_magic)); + return FALSE; + } + + // Note: We do not need to check eh_entries here, as the next branch makes sure max >= entries + if (Header->eh_max > MaxEntries) { + DEBUG (( + DEBUG_ERROR, + "[ext4] Invalid extent header max entries (%u eh_max, " + "theoretical max is %u) (larger than permitted)\n", + Header->eh_max, + MaxEntries + )); + return FALSE; + } + + if (Header->eh_max < Header->eh_entries) { + DEBUG (( + DEBUG_ERROR, + "[ext4] Invalid extent header num entries %u max entries %u\n", + Header->eh_entries, + Header->eh_max + )); + return FALSE; + } + + return TRUE; +} + +/** + Performs a binary search for a EXT4_EXTENT_INDEX that corresponds to a + logical block in a given extent tree node. + + @param[in] Header Pointer to the EXT4_EXTENT_HEADER structure. + @param[in] LogicalBlock Block that will be searched + + @return Pointer to the found EXT4_EXTENT_INDEX. +**/ +STATIC +EXT4_EXTENT_INDEX * +Ext4BinsearchExtentIndex ( + IN EXT4_EXTENT_HEADER *Header, + IN EXT4_BLOCK_NR LogicalBlock + ) +{ + EXT4_EXTENT_INDEX *l; + EXT4_EXTENT_INDEX *r; + EXT4_EXTENT_INDEX *m; + + l = ((EXT4_EXTENT_INDEX *)(Header + 1)) + 1; + r = ((EXT4_EXTENT_INDEX *)(Header + 1)) + Header->eh_entries - 1; + + // Perform a mostly-standard binary search on the array + // This works very nicely because the extents arrays are always sorted. + + while (l <= r) { + m = l + (r - l) / 2; + + if (LogicalBlock < m->ei_block) { + r = m - 1; + } else { + l = m + 1; + } + } + + return l - 1; +} + +/** + Performs a binary search for a EXT4_EXTENT that corresponds to a + logical block in a given extent tree node. + + @param[in] Header Pointer to the EXT4_EXTENT_HEADER structure. + @param[in] LogicalBlock Block that will be searched + + @return Pointer to the found EXT4_EXTENT_INDEX, else NULL if the array is empty. + Note: The caller must check if the logical block + is actually mapped under the given extent. +**/ +STATIC +EXT4_EXTENT * +Ext4BinsearchExtentExt ( + IN EXT4_EXTENT_HEADER *Header, + IN EXT4_BLOCK_NR LogicalBlock + ) +{ + EXT4_EXTENT *l; + EXT4_EXTENT *r; + EXT4_EXTENT *m; + + l = ((EXT4_EXTENT *)(Header + 1)) + 1; + r = ((EXT4_EXTENT *)(Header + 1)) + Header->eh_entries - 1; + // Perform a mostly-standard binary search on the array + // This works very nicely because the extents arrays are always sorted. + + // Empty array + if (Header->eh_entries == 0) { + return NULL; + } + + while (l <= r) { + m = l + (r - l) / 2; + + if (LogicalBlock < m->ee_block) { + r = m - 1; + } else { + l = m + 1; + } + } + + return l - 1; +} + +/** + Retrieves the leaf block from an EXT4_EXTENT_INDEX. + + @param[in] Index Pointer to the EXT4_EXTENT_INDEX structure. + + @return Block number of the leaf node. +**/ +STATIC +EXT4_BLOCK_NR +Ext4ExtentIdxLeafBlock ( + IN EXT4_EXTENT_INDEX *Index + ) +{ + return LShiftU64 (Index->ei_leaf_hi, 32) | Index->ei_leaf_lo; +} + +// Results of sizeof(i_data) / sizeof(extent) - 1 = 4 +#define EXT4_NR_INLINE_EXTENTS 4 + +/** + Retrieves an extent from an EXT4 inode. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] File Pointer to the opened file. + @param[in] LogicalBlock Block number which the returned extent must cover. + @param[out] Extent Pointer to the output buffer, where the extent will be copied to. + + @retval EFI_SUCCESS Retrieval was successful. + @retval EFI_NO_MAPPING Block has no mapping. +**/ +EFI_STATUS +Ext4GetExtent ( + IN EXT4_PARTITION *Partition, + IN EXT4_FILE *File, + IN EXT4_BLOCK_NR LogicalBlock, + OUT EXT4_EXTENT *Extent + ) +{ + EXT4_INODE *Inode; + VOID *Buffer; + EXT4_EXTENT *Ext; + UINT32 CurrentDepth; + EXT4_EXTENT_HEADER *ExtHeader; + EXT4_EXTENT_INDEX *Index; + EFI_STATUS Status; + UINT32 MaxExtentsPerNode; + EXT4_BLOCK_NR BlockNumber; + + Inode = File->Inode; + Ext = NULL; + Buffer = NULL; + + DEBUG ((DEBUG_FS, "[ext4] Looking up extent for block %lu\n", LogicalBlock)); + + // ext4 does not have support for logical block numbers bigger than UINT32_MAX + if (LogicalBlock > (UINT32)-1) { + return EFI_NO_MAPPING; + } + + // Note: Right now, holes are the single biggest reason for cache misses + // We should find a way to get (or cache) holes + if ((Ext = Ext4GetExtentFromMap (File, (UINT32)LogicalBlock)) != NULL) { + *Extent = *Ext; + + return EFI_SUCCESS; + } + + if ((Inode->i_flags & EXT4_EXTENTS_FL) == 0) { + // If this is an older ext2/ext3 filesystem, emulate Ext4GetExtent using the block map + // By specification files using block maps are limited to 2^32 blocks, + // so we can safely cast LogicalBlock to uint32 + Status = Ext4GetBlocks (Partition, File, (UINT32)LogicalBlock, Extent); + + if (!EFI_ERROR (Status)) { + Ext4CacheExtents (File, Extent, 1); + } + + return Status; + } + + // Slow path, we'll need to read from disk and (try to) cache those extents. + + ExtHeader = Ext4GetInoExtentHeader (Inode); + + if (!Ext4ExtentHeaderValid (ExtHeader, EXT4_NR_INLINE_EXTENTS)) { + return EFI_VOLUME_CORRUPTED; + } + + CurrentDepth = ExtHeader->eh_depth; + + // A single node fits into a single block, so we can only have (BlockSize / sizeof(EXT4_EXTENT)) - 1 + // extents in a single node. Note the -1, because both leaf and internal node headers are 12 bytes, + // and so are individual entries. + MaxExtentsPerNode = (Partition->BlockSize / sizeof (EXT4_EXTENT)) - 1; + + while (ExtHeader->eh_depth != 0) { + CurrentDepth--; + // While depth != 0, we're traversing the tree itself and not any leaves + // As such, every entry is an EXT4_EXTENT_INDEX entry + // Note: Entries after the extent header, either index or actual extent, are always sorted. + // Therefore, we can use binary search, and it's actually the standard for doing so + // (see FreeBSD). + + Index = Ext4BinsearchExtentIndex (ExtHeader, LogicalBlock); + BlockNumber = Ext4ExtentIdxLeafBlock (Index); + + // Check that block isn't file hole + if (BlockNumber == EXT4_BLOCK_FILE_HOLE) { + if (Buffer != NULL) { + FreePool (Buffer); + } + + return EFI_VOLUME_CORRUPTED; + } + + if (Buffer == NULL) { + Buffer = AllocatePool (Partition->BlockSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + // Read the leaf block onto the previously-allocated buffer. + + Status = Ext4ReadBlocks (Partition, Buffer, 1, BlockNumber); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + return Status; + } + + ExtHeader = Buffer; + + if (!Ext4ExtentHeaderValid (ExtHeader, MaxExtentsPerNode)) { + FreePool (Buffer); + return EFI_VOLUME_CORRUPTED; + } + + if (!Ext4CheckExtentChecksum (ExtHeader, File)) { + DEBUG ((DEBUG_ERROR, "[ext4] Invalid extent checksum\n")); + FreePool (Buffer); + return EFI_VOLUME_CORRUPTED; + } + + if (ExtHeader->eh_depth != CurrentDepth) { + FreePool (Buffer); + return EFI_VOLUME_CORRUPTED; + } + } + + /* We try to cache every extent under a single leaf, since it's quite likely that we + * may need to access things sequentially. Furthermore, ext4 block allocation as done + * by linux (and possibly other systems) is quite fancy and usually it results in a small number of extents. + * Therefore, we shouldn't have any memory issues. + **/ + Ext4CacheExtents (File, (EXT4_EXTENT *)(ExtHeader + 1), ExtHeader->eh_entries); + + Ext = Ext4BinsearchExtentExt (ExtHeader, LogicalBlock); + + if (!Ext) { + if (Buffer != NULL) { + FreePool (Buffer); + } + + return EFI_NO_MAPPING; + } + + if (!((LogicalBlock >= Ext->ee_block) && (Ext->ee_block + Ext4GetExtentLength (Ext) > LogicalBlock))) { + // This extent does not cover the block + if (Buffer != NULL) { + FreePool (Buffer); + } + + return EFI_NO_MAPPING; + } + + *Extent = *Ext; + + if (Buffer != NULL) { + FreePool (Buffer); + } + + return EFI_SUCCESS; +} + +/** + Compare two EXT4_EXTENT structs. + Used in the extent map's ORDERED_COLLECTION. + + @param[in] UserStruct1 Pointer to the first user structure. + + @param[in] UserStruct2 Pointer to the second user structure. + + @retval <0 If UserStruct1 compares less than UserStruct2. + + @retval 0 If UserStruct1 compares equal to UserStruct2. + + @retval >0 If UserStruct1 compares greater than UserStruct2. +**/ +STATIC +INTN +EFIAPI +Ext4ExtentsMapStructCompare ( + IN CONST VOID *UserStruct1, + IN CONST VOID *UserStruct2 + ) +{ + CONST EXT4_EXTENT *Extent1; + CONST EXT4_EXTENT *Extent2; + + Extent1 = UserStruct1; + Extent2 = UserStruct2; + + return Extent1->ee_block < Extent2->ee_block ? -1 : + Extent1->ee_block > Extent2->ee_block ? 1 : 0; +} + +/** + Compare a standalone key against a EXT4_EXTENT containing an embedded key. + Used in the extent map's ORDERED_COLLECTION. + + @param[in] StandaloneKey Pointer to the bare key. + + @param[in] UserStruct Pointer to the user structure with the embedded + key. + + @retval <0 If StandaloneKey compares less than UserStruct's key. + + @retval 0 If StandaloneKey compares equal to UserStruct's key. + + @retval >0 If StandaloneKey compares greater than UserStruct's key. +**/ +STATIC +INTN +EFIAPI +Ext4ExtentsMapKeyCompare ( + IN CONST VOID *StandaloneKey, + IN CONST VOID *UserStruct + ) +{ + CONST EXT4_EXTENT *Extent; + UINT32 Block; + + // Note that logical blocks are 32-bits in size so no truncation can happen here + // with regards to 32-bit architectures. + Extent = UserStruct; + Block = (UINT32)(UINTN)StandaloneKey; + + if ((Block >= Extent->ee_block) && (Block - Extent->ee_block < Ext4GetExtentLength (Extent))) { + return 0; + } + + return Block < Extent->ee_block ? -1 : + Block > Extent->ee_block ? 1 : 0; +} + +/** + Initialises the (empty) extents map, that will work as a cache of extents. + + @param[in] File Pointer to the open file. + + @return Result of the operation. +**/ +EFI_STATUS +Ext4InitExtentsMap ( + IN EXT4_FILE *File + ) +{ + File->ExtentsMap = OrderedCollectionInit (Ext4ExtentsMapStructCompare, Ext4ExtentsMapKeyCompare); + if (!File->ExtentsMap) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Frees the extents map, deleting every extent stored. + + @param[in] File Pointer to the open file. +**/ +VOID +Ext4FreeExtentsMap ( + IN EXT4_FILE *File + ) +{ + // Keep calling Min(), so we get an arbitrary node we can delete. + // If Min() returns NULL, it's empty. + + ORDERED_COLLECTION_ENTRY *MinEntry; + EXT4_EXTENT *Ext; + + MinEntry = NULL; + + while ((MinEntry = OrderedCollectionMin (File->ExtentsMap)) != NULL) { + OrderedCollectionDelete (File->ExtentsMap, MinEntry, (VOID **)&Ext); + FreePool (Ext); + } + + ASSERT (OrderedCollectionIsEmpty (File->ExtentsMap)); + + OrderedCollectionUninit (File->ExtentsMap); + File->ExtentsMap = NULL; +} + +/** + Caches a range of extents, by allocating pool memory for each extent and adding it to the tree. + + @param[in] File Pointer to the open file. + @param[in] Extents Pointer to an array of extents. + @param[in] NumberExtents Length of the array. +**/ +VOID +Ext4CacheExtents ( + IN EXT4_FILE *File, + IN CONST EXT4_EXTENT *Extents, + IN UINT16 NumberExtents + ) +{ + UINT16 Idx; + EXT4_EXTENT *Extent; + EFI_STATUS Status; + + /* Note that any out of memory condition might mean we don't get to cache a whole leaf of extents + * in which case, future insertions might fail. + */ + + for (Idx = 0; Idx < NumberExtents; Idx++, Extents++) { + Extent = AllocatePool (sizeof (EXT4_EXTENT)); + + if (Extent == NULL) { + return; + } + + CopyMem (Extent, Extents, sizeof (EXT4_EXTENT)); + Status = OrderedCollectionInsert (File->ExtentsMap, NULL, Extent); + + // EFI_ALREADY_STARTED = already exists in the tree. + if (EFI_ERROR (Status)) { + FreePool (Extent); + + if (Status == EFI_ALREADY_STARTED) { + continue; + } + + return; + } + } +} + +/** + Gets an extent from the extents cache of the file. + + @param[in] File Pointer to the open file. + @param[in] Block Block we want to grab. + + @return Pointer to the extent, or NULL if it was not found. +**/ +EXT4_EXTENT * +Ext4GetExtentFromMap ( + IN EXT4_FILE *File, + IN UINT32 Block + ) +{ + ORDERED_COLLECTION_ENTRY *Entry; + + Entry = OrderedCollectionFind (File->ExtentsMap, (CONST VOID *)(UINTN)Block); + + if (Entry == NULL) { + return NULL; + } + + return OrderedCollectionUserStruct (Entry); +} + +/** + Calculates the checksum of the extent data block. + @param[in] ExtHeader Pointer to the EXT4_EXTENT_HEADER. + @param[in] File Pointer to the file. + + @return The checksum. +**/ +UINT32 +Ext4CalculateExtentChecksum ( + IN CONST EXT4_EXTENT_HEADER *ExtHeader, + IN CONST EXT4_FILE *File + ) +{ + UINT32 Csum; + EXT4_PARTITION *Partition; + EXT4_INODE *Inode; + + Partition = File->Partition; + Inode = File->Inode; + + Csum = Ext4CalculateChecksum (Partition, &File->InodeNum, sizeof (EXT4_INO_NR), Partition->InitialSeed); + Csum = Ext4CalculateChecksum (Partition, &Inode->i_generation, sizeof (Inode->i_generation), Csum); + Csum = Ext4CalculateChecksum (Partition, ExtHeader, Partition->BlockSize - sizeof (EXT4_EXTENT_TAIL), Csum); + + return Csum; +} + +/** + Checks if the checksum of the extent data block is correct. + @param[in] ExtHeader Pointer to the EXT4_EXTENT_HEADER. + @param[in] File Pointer to the file. + + @return TRUE if the checksum is correct, FALSE if there is corruption. +**/ +BOOLEAN +Ext4CheckExtentChecksum ( + IN CONST EXT4_EXTENT_HEADER *ExtHeader, + IN CONST EXT4_FILE *File + ) +{ + EXT4_PARTITION *Partition; + EXT4_EXTENT_TAIL *Tail; + + Partition = File->Partition; + + if (!EXT4_HAS_METADATA_CSUM (Partition)) { + return TRUE; + } + + Tail = (EXT4_EXTENT_TAIL *)((CONST CHAR8 *)ExtHeader + (Partition->BlockSize - 4)); + + return Tail->eb_checksum == Ext4CalculateExtentChecksum (ExtHeader, File); +} + +/** + Retrieves the extent's length, dealing with uninitialized extents in the process. + + @param[in] Extent Pointer to the EXT4_EXTENT + + @returns Extent's length, in filesystem blocks. +**/ +EXT4_BLOCK_NR +Ext4GetExtentLength ( + IN CONST EXT4_EXTENT *Extent + ) +{ + // If it's an uninitialized extent, the true length is ee_len - 2^15 + if (EXT4_EXTENT_IS_UNINITIALIZED (Extent)) { + return Extent->ee_len - EXT4_EXTENT_MAX_INITIALIZED; + } + + return Extent->ee_len; +} diff --git a/Ext4Pkg/Ext4Dxe/File.c b/Ext4Pkg/Ext4Dxe/File.c new file mode 100644 index 0000000000..677caf88fb --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/File.c @@ -0,0 +1,1012 @@ +/** @file + EFI_FILE_PROTOCOL implementation for EXT4 + + Copyright (c) 2021 Pedro Falcato All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Ext4Dxe.h" + +#include + +/** + Reads a symlink file. + + @param[in] Partition Pointer to the ext4 partition. + @param[in] File Pointer to the open symlink file. + @param[out] Symlink Pointer to the output unicode symlink string. + + @retval EFI_SUCCESS Symlink was read. + @retval EFI_ACCESS_DENIED Symlink is encrypted. + @retval EFI_OUT_OF_RESOURCES Memory allocation error. + @retval EFI_INVALID_PARAMETER Symlink path has incorrect length + @retval EFI_VOLUME_CORRUPTED Symlink read block size differ from inode value +**/ +EFI_STATUS +Ext4ReadSymlink ( + IN EXT4_PARTITION *Partition, + IN EXT4_FILE *File, + OUT CHAR16 **Symlink + ); + +/** + Duplicates a file structure. + + @param[in] Original Pointer to the original file. + + @return Pointer to the new file structure. +**/ +STATIC +EXT4_FILE * +Ext4DuplicateFile ( + IN CONST EXT4_FILE *Original + ); + +/** + Gets the next path segment. + + @param[in] Path Pointer to the rest of the path. + @param[out] PathSegment Pointer to the buffer that will hold the path segment. + Note: It's necessarily EXT4_NAME_MAX +1 long. + @param[out] Length Pointer to the UINTN that will hold the length of the path segment. + + @retval !EFI_SUCCESS The path segment is too large(> EXT4_NAME_MAX). +**/ +STATIC +EFI_STATUS +GetPathSegment ( + IN CONST CHAR16 *Path, + OUT CHAR16 *PathSegment, + OUT UINTN *Length + ) +{ + CONST CHAR16 *Start; + CONST CHAR16 *End; + + Start = Path; + End = Path; + + // The path segment ends on a backslash or a null terminator + for ( ; *End != L'\0' && *End != L'\\'; End++) { + } + + *Length = End - Start; + + return StrnCpyS (PathSegment, EXT4_NAME_MAX, Start, End - Start); +} + +/** + Detects if we have more path segments on the path. + + @param[in] Path Pointer to the rest of the path. + @return True if we're on the last segment, false if there are more + segments. +**/ +STATIC +BOOLEAN +Ext4IsLastPathSegment ( + IN CONST CHAR16 *Path + ) +{ + while (Path[0] == L'\\') { + Path++; + } + + return Path[0] == '\0'; +} + +#define EXT4_INO_PERM_READ_OWNER 0400 +#define EXT4_INO_PERM_WRITE_OWNER 0200 +#define EXT4_INO_PERM_EXEC_OWNER 0100 + +/** + Detects if we have permissions to open the file on the desired mode. + + @param[in out] File Pointer to the file we're opening. + @param[in] OpenMode Mode in which to open the file. + + @return True if the open was successful, false if we don't have + enough permissions. +**/ +STATIC +BOOLEAN +Ext4ApplyPermissions ( + IN OUT EXT4_FILE *File, + IN UINT64 OpenMode + ) +{ + UINT16 NeededPerms; + + NeededPerms = 0; + + if ((OpenMode & EFI_FILE_MODE_READ) != 0) { + NeededPerms |= EXT4_INO_PERM_READ_OWNER; + } + + if ((OpenMode & EFI_FILE_MODE_WRITE) != 0) { + NeededPerms |= EXT4_INO_PERM_WRITE_OWNER; + } + + if ((File->Inode->i_mode & NeededPerms) != NeededPerms) { + return FALSE; + } + + File->OpenMode = OpenMode; + + return TRUE; +} + +/** + Detects if we have permissions to search on the directory. + + @param[in out] File Pointer to the open directory. + + @return True if we have permission to search, else false. +**/ +STATIC +BOOLEAN +Ext4DirCanLookup ( + IN CONST EXT4_FILE *File + ) +{ + // In UNIX, executable permission on directories means that we have permission to look up + // files in a directory. + return (File->Inode->i_mode & EXT4_INO_PERM_EXEC_OWNER) == EXT4_INO_PERM_EXEC_OWNER; +} + +/** + Opens a new file relative to the source file's location. + + @param[out] FoundFile A pointer to the location to return the opened handle for the new + file. + @param[in] Source A pointer to the EXT4_FILE instance that is the file + handle to the source location. This would typically be an open + handle to a directory. + @param[in] FileName The Null-terminated string of the name of the file to be opened. + The file name may contain the following path modifiers: "\", ".", + and "..". + @param[in] OpenMode The mode to open the file. The only valid combinations that the + file may be opened with are: Read, Read/Write, or Create/Read/Write. + @param[in] Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the + attribute bits for the newly created file. + + @retval EFI_SUCCESS The file was opened. + @retval EFI_NOT_FOUND The specified file could not be found on the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no + longer supported. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write + when the media is write-protected. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +Ext4OpenInternal ( + OUT EXT4_FILE **FoundFile, + IN EXT4_FILE *Source, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + EXT4_FILE *Current; + EXT4_PARTITION *Partition; + UINTN Level; + CHAR16 PathSegment[EXT4_NAME_MAX + 1]; + UINTN Length; + EXT4_FILE *File; + CHAR16 *Symlink; + EFI_STATUS Status; + + Current = Source; + Partition = Current->Partition; + Level = 0; + + DEBUG ((DEBUG_FS, "[ext4] Ext4OpenInternal %s\n", FileName)); + + if (!Ext4FileIsDir (Current)) { + return EFI_INVALID_PARAMETER; + } + + // If the path starts with a backslash, we treat the root directory as the base directory + if (FileName[0] == L'\\') { + FileName++; + Current = Partition->Root; + } + + while (FileName[0] != L'\0') { + if (Partition->Root->SymLoops > SYMLOOP_MAX) { + DEBUG ((DEBUG_FS, "[ext4] Symloop limit is hit !\n")); + return EFI_ACCESS_DENIED; + } + + if (!Ext4FileIsDir (Current)) { + return EFI_INVALID_PARAMETER; + } + + // Discard leading path separators + while (FileName[0] == L'\\') { + FileName++; + } + + if (GetPathSegment (FileName, PathSegment, &Length) != EFI_SUCCESS) { + return EFI_BUFFER_TOO_SMALL; + } + + // Reached the end of the path + if (Length == 0) { + break; + } + + FileName += Length; + + if (StrCmp (PathSegment, L".") == 0) { + // Opens of "." are a no-op + continue; + } + + DEBUG ((DEBUG_FS, "[ext4] Opening %s\n", PathSegment)); + + if (!Ext4IsLastPathSegment (FileName)) { + if (!Ext4DirCanLookup (Current)) { + return EFI_ACCESS_DENIED; + } + } + + Status = Ext4OpenFile (Current, PathSegment, Partition, EFI_FILE_MODE_READ, &File); + + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + return Status; + } else if (Status == EFI_NOT_FOUND) { + // We explicitly ignore the EFI_FILE_MODE_CREATE flag, since we don't have write support + /// If/ we add write support, this should be changed. + return Status; + } + + // Check if this is a valid file to open in EFI + if (!Ext4FileIsOpenable (File)) { + Ext4CloseInternal (File); + // This looks like an /okay/ status to return. + return EFI_ACCESS_DENIED; + } + + // + // Reading symlink and then trying to follow it + // + if (Ext4FileIsSymlink (File)) { + Partition->Root->SymLoops++; + DEBUG ((DEBUG_FS, "[ext4] File %s is symlink, trying to read it\n", PathSegment)); + Status = Ext4ReadSymlink (Partition, File, &Symlink); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_FS, "[ext4] Error reading %s symlink!\n", PathSegment)); + return Status; + } + + DEBUG ((DEBUG_FS, "[ext4] File %s is linked to %s\n", PathSegment, Symlink)); + // + // Close symlink file + // + Ext4CloseInternal (File); + // + // Open linked file by recursive call of Ext4OpenFile + // + Status = Ext4OpenInternal (FoundFile, Current, Symlink, OpenMode, Attributes); + FreePool (Symlink); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_FS, "[ext4] Error opening linked file %s\n", Symlink)); + return Status; + } + + // + // Set File to newly opened + // + File = *FoundFile; + } + + if (Level != 0) { + // Careful not to close the base directory + Ext4CloseInternal (Current); + } + + Level++; + + Current = File; + } + + if (Level == 0) { + // We opened the base directory again, so we need to duplicate the file structure + Current = Ext4DuplicateFile (Current); + if (Current == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + if (!Ext4ApplyPermissions (Current, OpenMode)) { + Ext4CloseInternal (Current); + return EFI_ACCESS_DENIED; + } + + *FoundFile = Current; + + DEBUG ((DEBUG_FS, "[ext4] Opened filename %s\n", Current->Dentry->Name)); + return EFI_SUCCESS; +} + +/** + Opens a new file relative to the source file's location. + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to the source location. This would typically be an open + handle to a directory. + @param[out] NewHandle A pointer to the location to return the opened handle for the new + file. + @param[in] FileName The Null-terminated string of the name of the file to be opened. + The file name may contain the following path modifiers: "\", ".", + and "..". + @param[in] OpenMode The mode to open the file. The only valid combinations that the + file may be opened with are: Read, Read/Write, or Create/Read/Write. + @param[in] Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the + attribute bits for the newly created file. + @retval EFI_SUCCESS The file was opened. + @retval EFI_NOT_FOUND The specified file could not be found on the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no + longer supported. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write + when the media is write-protected. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. + @retval EFI_VOLUME_FULL The volume is full. +**/ +EFI_STATUS +EFIAPI +Ext4Open ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + EFI_STATUS Status; + EXT4_FILE *FoundFile; + EXT4_FILE *Source; + + Source = EXT4_FILE_FROM_THIS (This); + + // + // Reset SymLoops counter + // + Source->Partition->Root->SymLoops = 0; + + Status = Ext4OpenInternal ( + &FoundFile, + Source, + FileName, + OpenMode, + Attributes + ); + + if (!EFI_ERROR (Status)) { + *NewHandle = &FoundFile->Protocol; + } + + return Status; +} + +/** + Closes a specified file handle. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to close. + + @retval EFI_SUCCESS The file was closed. + +**/ +EFI_STATUS +EFIAPI +Ext4Close ( + IN EFI_FILE_PROTOCOL *This + ) +{ + return Ext4CloseInternal (EXT4_FILE_FROM_THIS (This)); +} + +/** + Closes a file. + + @param[in] File Pointer to the file. + + @return Status of the closing of the file. +**/ +EFI_STATUS +Ext4CloseInternal ( + IN EXT4_FILE *File + ) +{ + if ((File == File->Partition->Root) && !File->Partition->Unmounting) { + return EFI_SUCCESS; + } + + DEBUG ((DEBUG_FS, "[ext4] Closed file %p (inode %lu)\n", File, File->InodeNum)); + RemoveEntryList (&File->OpenFilesListNode); + FreePool (File->Inode); + Ext4FreeExtentsMap (File); + Ext4UnrefDentry (File->Dentry); + FreePool (File); + return EFI_SUCCESS; +} + +/** + Close and delete the file handle. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the + handle to the file to delete. + + @retval EFI_SUCCESS The file was closed and deleted, and the handle was closed. + @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted. + +**/ +EFI_STATUS +EFIAPI +Ext4Delete ( + IN EFI_FILE_PROTOCOL *This + ) +{ + // We do a regular close here since we don't have write support. + Ext4Close (This); + return EFI_WARN_DELETE_FAILURE; +} + +/** + Reads data from a file. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to read data from. + @param[in out] BufferSize On input, the size of the Buffer. On output, the amount of data + returned in Buffer. In both cases, the size is measured in bytes. + @param[out] Buffer The buffer into which the data is read. + + @retval EFI_SUCCESS Data was read. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file. + @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory + entry. BufferSize has been updated with the size + needed to complete the request. + +**/ +EFI_STATUS +EFIAPI +Ext4ReadFile ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EXT4_FILE *File; + EXT4_PARTITION *Partition; + EFI_STATUS Status; + + File = EXT4_FILE_FROM_THIS (This); + Partition = File->Partition; + + ASSERT (Ext4FileIsOpenable (File)); + + if (Ext4FileIsReg (File)) { + Status = Ext4Read (Partition, File, Buffer, File->Position, BufferSize); + if (Status == EFI_SUCCESS) { + File->Position += *BufferSize; + } + + return Status; + } else if (Ext4FileIsDir (File)) { + Status = Ext4ReadDir (Partition, File, Buffer, File->Position, BufferSize); + + return Status; + } + + return EFI_SUCCESS; +} + +/** + Writes data to a file. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to write data to. + @param[in out] BufferSize On input, the size of the Buffer. On output, the amount of data + actually written. In both cases, the size is measured in bytes. + @param[in] Buffer The buffer of data to write. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Writes to open directory files are not supported. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The file or medium is write-protected. + @retval EFI_ACCESS_DENIED The file was opened read only. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +EFIAPI +Ext4WriteFile ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +{ + EXT4_FILE *File; + + File = EXT4_FILE_FROM_THIS (This); + + if (!(File->OpenMode & EFI_FILE_MODE_WRITE)) { + return EFI_ACCESS_DENIED; + } + + return EFI_WRITE_PROTECTED; +} + +/** + Returns a file's current position. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to get the current position on. + @param[out] Position The address to return the file's current position value. + + @retval EFI_SUCCESS The position was returned. + @retval EFI_UNSUPPORTED The request is not valid on open directories. + @retval EFI_DEVICE_ERROR An attempt was made to get the position from a deleted file. + +**/ +EFI_STATUS +EFIAPI +Ext4GetPosition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ) +{ + EXT4_FILE *File; + + File = EXT4_FILE_FROM_THIS (This); + + if (Ext4FileIsDir (File)) { + return EFI_UNSUPPORTED; + } + + *Position = File->Position; + + return EFI_SUCCESS; +} + +/** + Sets a file's current position. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the + file handle to set the requested position on. + @param[in] Position The byte position from the start of the file to set. + + @retval EFI_SUCCESS The position was set. + @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open + directories. + @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file. + +**/ +EFI_STATUS +EFIAPI +Ext4SetPosition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ) +{ + EXT4_FILE *File; + + File = EXT4_FILE_FROM_THIS (This); + + // Only seeks to 0 (so it resets the ReadDir operation) are allowed + if (Ext4FileIsDir (File) && (Position != 0)) { + return EFI_UNSUPPORTED; + } + + // -1 (0xffffff.......) seeks to the end of the file + if (Position == (UINT64)-1) { + Position = EXT4_INODE_SIZE (File->Inode); + } + + File->Position = Position; + + return EFI_SUCCESS; +} + +/** + Retrieves information about the file and stores it in the EFI_FILE_INFO format. + + @param[in] File Pointer to an opened file. + @param[out] Info Pointer to a EFI_FILE_INFO. + @param[in out] BufferSize Pointer to the buffer size + + @return Status of the file information request. +**/ +EFI_STATUS +Ext4GetFileInfo ( + IN EXT4_FILE *File, + OUT EFI_FILE_INFO *Info, + IN OUT UINTN *BufferSize + ) +{ + UINTN FileNameLen; + UINTN FileNameSize; + UINTN NeededLength; + CONST CHAR16 *FileName; + + if (File->InodeNum == EXT4_ROOT_INODE_NR) { + // Root inode gets a filename of "", regardless of how it was opened. + FileName = L""; + } else { + FileName = File->Dentry->Name; + } + + FileNameLen = StrLen (FileName); + FileNameSize = StrSize (FileName); + + NeededLength = SIZE_OF_EFI_FILE_INFO + FileNameSize; + + if (*BufferSize < NeededLength) { + *BufferSize = NeededLength; + return EFI_BUFFER_TOO_SMALL; + } + + Info->FileSize = EXT4_INODE_SIZE (File->Inode); + Info->PhysicalSize = Ext4FilePhysicalSpace (File); + Ext4FileATime (File, &Info->LastAccessTime); + Ext4FileMTime (File, &Info->ModificationTime); + Ext4FileCreateTime (File, &Info->LastAccessTime); + Info->Attribute = 0; + Info->Size = NeededLength; + + if (Ext4FileIsDir (File)) { + Info->Attribute |= EFI_FILE_DIRECTORY; + } + + *BufferSize = NeededLength; + + return StrCpyS (Info->FileName, FileNameLen + 1, FileName); +} + +/** + Retrieves the volume name. + + @param[in] Part Pointer to the opened partition. + @param[out] Info Pointer to a CHAR16*. + @param[out] BufferSize Pointer to a UINTN, where the string length + of the name will be put. + + @return Status of the volume name request. +**/ +EFI_STATUS +Ext4GetVolumeName ( + IN EXT4_PARTITION *Partition, + OUT CHAR16 **OutVolName, + OUT UINTN *VolNameLen + ) +{ + CHAR8 TempVolName[16 + 1]; + CHAR16 *VolumeName; + UINTN VolNameLength; + EFI_STATUS Status; + + VolNameLength = 0; + VolumeName = NULL; + + // s_volume_name is only valid on dynamic revision; old filesystems don't support this + if (Partition->SuperBlock.s_rev_level == EXT4_DYNAMIC_REV) { + CopyMem (TempVolName, Partition->SuperBlock.s_volume_name, 16); + TempVolName[16] = '\0'; + + Status = UTF8StrToUCS2 (TempVolName, &VolumeName); + + if (EFI_ERROR (Status)) { + return Status; + } + + VolNameLength = StrLen (VolumeName); + } else { + VolumeName = AllocateZeroPool (sizeof (CHAR16)); + if (VolumeName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + VolNameLength = 0; + } + + *OutVolName = VolumeName; + *VolNameLen = VolNameLength; + + return EFI_SUCCESS; +} + +/** + Retrieves information about the filesystem and stores it in the EFI_FILE_SYSTEM_INFO format. + + @param[in] Part Pointer to the opened partition. + @param[out] Info Pointer to a EFI_FILE_SYSTEM_INFO. + @param[in out] BufferSize Pointer to the buffer size + + @return Status of the file information request. +**/ +STATIC +EFI_STATUS +Ext4GetFilesystemInfo ( + IN EXT4_PARTITION *Part, + OUT EFI_FILE_SYSTEM_INFO *Info, + IN OUT UINTN *BufferSize + ) +{ + // Length of s_volume_name + null terminator + EFI_STATUS Status; + UINTN NeededLength; + EXT4_BLOCK_NR TotalBlocks; + EXT4_BLOCK_NR FreeBlocks; + CHAR16 *VolumeName; + UINTN VolNameLength; + + Status = Ext4GetVolumeName (Part, &VolumeName, &VolNameLength); + + if (EFI_ERROR (Status)) { + return Status; + } + + NeededLength = SIZE_OF_EFI_FILE_SYSTEM_INFO; + + NeededLength += StrSize (VolumeName); + + if (*BufferSize < NeededLength) { + *BufferSize = NeededLength; + + FreePool (VolumeName); + + return EFI_BUFFER_TOO_SMALL; + } + + TotalBlocks = Part->NumberBlocks; + + FreeBlocks = EXT4_BLOCK_NR_FROM_HALFS ( + Part, + Part->SuperBlock.s_free_blocks_count, + Part->SuperBlock.s_free_blocks_count_hi + ); + + Info->BlockSize = Part->BlockSize; + Info->Size = NeededLength; + Info->ReadOnly = Part->ReadOnly; + Info->VolumeSize = MultU64x32 (TotalBlocks, Part->BlockSize); + Info->FreeSpace = MultU64x32 (FreeBlocks, Part->BlockSize); + + Status = StrCpyS (Info->VolumeLabel, VolNameLength + 1, VolumeName); + + ASSERT_EFI_ERROR (Status); + + FreePool (VolumeName); + + *BufferSize = NeededLength; + + return EFI_SUCCESS; +} + +/** + Retrieves the volume label and stores it in the EFI_FILE_SYSTEM_VOLUME_LABEL format. + + @param[in] Part Pointer to the opened partition. + @param[out] Info Pointer to a EFI_FILE_SYSTEM_VOLUME_LABEL. + @param[in out] BufferSize Pointer to the buffer size + + @return Status of the file information request. +**/ +STATIC +EFI_STATUS +Ext4GetVolumeLabelInfo ( + IN EXT4_PARTITION *Part, + OUT EFI_FILE_SYSTEM_VOLUME_LABEL *Info, + IN OUT UINTN *BufferSize + ) +{ + // Length of s_volume_name + null terminator + CHAR16 *VolumeName; + UINTN VolNameLength; + EFI_STATUS Status; + UINTN NeededLength; + + Status = Ext4GetVolumeName (Part, &VolumeName, &VolNameLength); + + if (EFI_ERROR (Status)) { + return Status; + } + + NeededLength = (VolNameLength + 1) * sizeof (CHAR16); + + if (NeededLength > *BufferSize) { + *BufferSize = NeededLength; + + FreePool (VolumeName); + + return EFI_BUFFER_TOO_SMALL; + } + + Status = StrCpyS (Info->VolumeLabel, VolNameLength + 1, VolumeName); + + ASSERT_EFI_ERROR (Status); + + FreePool (VolumeName); + + *BufferSize = NeededLength; + + return EFI_SUCCESS; +} + +/** + Returns information about a file. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle the requested information is for. + @param[in] InformationType The type identifier for the information being requested. + @param[in out] BufferSize On input, the size of Buffer. On output, the amount of data + returned in Buffer. In both cases, the size is measured in bytes. + @param[out] Buffer A pointer to the data buffer to return. The buffer's type is + indicated by InformationType. + + @retval EFI_SUCCESS The information was returned. + @retval EFI_UNSUPPORTED The InformationType is not known. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry. + BufferSize has been updated with the size needed to complete + the request. +**/ +EFI_STATUS +EFIAPI +Ext4GetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EXT4_FILE *File; + EXT4_PARTITION *Partition; + + File = EXT4_FILE_FROM_THIS (This); + Partition = File->Partition; + + if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { + return Ext4GetFileInfo (File, Buffer, BufferSize); + } + + if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { + return Ext4GetFilesystemInfo (Partition, Buffer, BufferSize); + } + + if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { + return Ext4GetVolumeLabelInfo (Partition, Buffer, BufferSize); + } + + return EFI_UNSUPPORTED; +} + +/** + Duplicates a file structure. + + @param[in] Original Pointer to the original file. + + @return Pointer to the new file structure. +**/ +STATIC +EXT4_FILE * +Ext4DuplicateFile ( + IN CONST EXT4_FILE *Original + ) +{ + EXT4_PARTITION *Partition; + EXT4_FILE *File; + EFI_STATUS Status; + + Partition = Original->Partition; + File = AllocateZeroPool (sizeof (EXT4_FILE)); + + if (File == NULL) { + return NULL; + } + + File->Inode = Ext4AllocateInode (Partition); + if (File->Inode == NULL) { + FreePool (File); + return NULL; + } + + CopyMem (File->Inode, Original->Inode, Partition->InodeSize); + + File->Position = 0; + Ext4SetupFile (File, Partition); + File->InodeNum = Original->InodeNum; + File->OpenMode = 0; // Will be filled by other code + + Status = Ext4InitExtentsMap (File); + if (EFI_ERROR (Status)) { + FreePool (File->Inode); + FreePool (File); + return NULL; + } + + File->Dentry = Original->Dentry; + + Ext4RefDentry (File->Dentry); + + InsertTailList (&Partition->OpenFiles, &File->OpenFilesListNode); + + return File; +} + +/** + Sets information about a file. + + @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle the information is for. + @param[in] InformationType The type identifier for the information being set. + @param[in] BufferSize The size, in bytes, of Buffer. + @param[in] Buffer A pointer to the data buffer to write. The buffer's type is + indicated by InformationType. + + @retval EFI_SUCCESS The information was set. + @retval EFI_UNSUPPORTED The InformationType is not known. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_INFO_ID and the media is + read-only. + @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_PROTOCOL_SYSTEM_INFO_ID + and the media is read only. + @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_SYSTEM_VOLUME_LABEL_ID + and the media is read-only. + @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file to a + file that is already present. + @retval EFI_ACCESS_DENIED An attempt is being made to change the EFI_FILE_DIRECTORY + Attribute. + @retval EFI_ACCESS_DENIED An attempt is being made to change the size of a directory. + @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the file was opened + read-only and an attempt is being made to modify a field + other than Attribute. + @retval EFI_VOLUME_FULL The volume is full. + @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of the type indicated + by InformationType. + +**/ +EFI_STATUS +EFIAPI +Ext4SetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + EXT4_FILE *File; + EXT4_PARTITION *Partition; + + File = EXT4_FILE_FROM_THIS (This); + Partition = File->Partition; + + if (Partition->ReadOnly) { + return EFI_WRITE_PROTECTED; + } + + // There's no write support just yet. + return EFI_UNSUPPORTED; +} diff --git a/Ext4Pkg/Ext4Dxe/Inode.c b/Ext4Pkg/Ext4Dxe/Inode.c new file mode 100644 index 0000000000..8db051d3c4 --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/Inode.c @@ -0,0 +1,490 @@ +/** @file + Inode related routines + + Copyright (c) 2021 - 2022 Pedro Falcato All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + EpochToEfiTime copied from EmbeddedPkg/Library/TimeBaseLib.c + Copyright (c) 2016, Hisilicon Limited. All rights reserved. + Copyright (c) 2016-2019, Linaro Limited. All rights reserved. + Copyright (c) 2021, Ampere Computing LLC. All rights reserved. +**/ + +#include "Ext4Dxe.h" + +/** + Calculates the checksum of the given inode. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] Inode Pointer to the inode. + @param[in] InodeNum Inode number. + + @return The checksum. +**/ +UINT32 +Ext4CalculateInodeChecksum ( + IN CONST EXT4_PARTITION *Partition, + IN CONST EXT4_INODE *Inode, + IN EXT4_INO_NR InodeNum + ) +{ + UINT32 Crc; + UINT16 Dummy; + BOOLEAN HasSecondChecksumField; + CONST VOID *RestOfInode; + UINTN RestOfInodeLength; + UINTN Length; + + HasSecondChecksumField = EXT4_INODE_HAS_FIELD (Inode, i_checksum_hi); + + Dummy = 0; + + Crc = Ext4CalculateChecksum (Partition, &InodeNum, sizeof (InodeNum), Partition->InitialSeed); + Crc = Ext4CalculateChecksum (Partition, &Inode->i_generation, sizeof (Inode->i_generation), Crc); + + Crc = Ext4CalculateChecksum ( + Partition, + Inode, + OFFSET_OF (EXT4_INODE, i_osd2.data_linux.l_i_checksum_lo), + Crc + ); + + Crc = Ext4CalculateChecksum (Partition, &Dummy, sizeof (Dummy), Crc); + + RestOfInode = &Inode->i_osd2.data_linux.l_i_reserved; + RestOfInodeLength = Partition->InodeSize - OFFSET_OF (EXT4_INODE, i_osd2.data_linux.l_i_reserved); + + if (HasSecondChecksumField) { + Length = OFFSET_OF (EXT4_INODE, i_checksum_hi) - OFFSET_OF (EXT4_INODE, i_osd2.data_linux.l_i_reserved); + + Crc = Ext4CalculateChecksum (Partition, &Inode->i_osd2.data_linux.l_i_reserved, Length, Crc); + Crc = Ext4CalculateChecksum (Partition, &Dummy, sizeof (Dummy), Crc); + + // 4 is the size of the i_extra_size field + the size of i_checksum_hi + RestOfInodeLength = Partition->InodeSize - EXT4_GOOD_OLD_INODE_SIZE - 4; + RestOfInode = &Inode->i_ctime_extra; + } + + Crc = Ext4CalculateChecksum (Partition, RestOfInode, RestOfInodeLength, Crc); + + return Crc; +} + +/** + Reads from an EXT4 inode. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] File Pointer to the opened file. + @param[out] Buffer Pointer to the buffer. + @param[in] Offset Offset of the read. + @param[in out] Length Pointer to the length of the buffer, in bytes. + After a successful read, it's updated to the number of read bytes. + + @return Status of the read operation. +**/ +EFI_STATUS +Ext4Read ( + IN EXT4_PARTITION *Partition, + IN EXT4_FILE *File, + OUT VOID *Buffer, + IN UINT64 Offset, + IN OUT UINTN *Length + ) +{ + EXT4_INODE *Inode; + UINT64 InodeSize; + UINT64 CurrentSeek; + UINTN RemainingRead; + UINTN BeenRead; + UINTN WasRead; + EXT4_EXTENT Extent; + UINT32 BlockOff; + EFI_STATUS Status; + BOOLEAN HasBackingExtent; + UINT32 HoleOff; + UINT64 HoleLen; + UINT64 ExtentStartBytes; + UINT64 ExtentLengthBytes; + UINT64 ExtentLogicalBytes; + + // Our extent offset is the difference between CurrentSeek and ExtentLogicalBytes + UINT64 ExtentOffset; + UINTN ExtentMayRead; + + Inode = File->Inode; + InodeSize = EXT4_INODE_SIZE (Inode); + CurrentSeek = Offset; + RemainingRead = *Length; + BeenRead = 0; + + DEBUG ((DEBUG_FS, "[ext4] Ext4Read(%s, Offset %lu, Length %lu)\n", File->Dentry->Name, Offset, *Length)); + + if (Offset > InodeSize) { + return EFI_DEVICE_ERROR; + } + + if (RemainingRead > InodeSize - Offset) { + RemainingRead = (UINTN)(InodeSize - Offset); + } + + while (RemainingRead != 0) { + WasRead = 0; + + // The algorithm here is to get the extent corresponding to the current block + // and then read as much as we can from the current extent. + + Status = Ext4GetExtent ( + Partition, + File, + DivU64x32Remainder (CurrentSeek, Partition->BlockSize, &BlockOff), + &Extent + ); + + if ((Status != EFI_SUCCESS) && (Status != EFI_NO_MAPPING)) { + return Status; + } + + HasBackingExtent = Status != EFI_NO_MAPPING; + + if (!HasBackingExtent || EXT4_EXTENT_IS_UNINITIALIZED (&Extent)) { + HoleOff = BlockOff; + + if (!HasBackingExtent) { + HoleLen = Partition->BlockSize - HoleOff; + } else { + // Uninitialized extents behave exactly the same as file holes, except they have + // blocks already allocated to them. + HoleLen = MultU64x32 (Ext4GetExtentLength (&Extent), Partition->BlockSize) - HoleOff; + } + + WasRead = HoleLen > RemainingRead ? RemainingRead : (UINTN)HoleLen; + // Potential improvement: In the future, we could get the file hole's total + // size and memset all that + ZeroMem (Buffer, WasRead); + } else { + ExtentStartBytes = MultU64x32 ( + LShiftU64 (Extent.ee_start_hi, 32) | + Extent.ee_start_lo, + Partition->BlockSize + ); + ExtentLengthBytes = Extent.ee_len * Partition->BlockSize; + ExtentLogicalBytes = MultU64x32 ((UINT64)Extent.ee_block, Partition->BlockSize); + ExtentOffset = CurrentSeek - ExtentLogicalBytes; + ExtentMayRead = (UINTN)(ExtentLengthBytes - ExtentOffset); + + WasRead = ExtentMayRead > RemainingRead ? RemainingRead : ExtentMayRead; + + Status = Ext4ReadDiskIo (Partition, Buffer, WasRead, ExtentStartBytes + ExtentOffset); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "[ext4] Error %r reading [%lu, %lu]\n", + Status, + ExtentStartBytes + ExtentOffset, + ExtentStartBytes + ExtentOffset + WasRead - 1 + )); + return Status; + } + } + + RemainingRead -= WasRead; + Buffer = (VOID *)((CHAR8 *)Buffer + WasRead); + BeenRead += WasRead; + CurrentSeek += WasRead; + } + + *Length = BeenRead; + + return EFI_SUCCESS; +} + +/** + Allocates a zeroed inode structure. + @param[in] Partition Pointer to the opened EXT4 partition. + + @return Pointer to the allocated structure, from the pool, + with size Partition->InodeSize. +**/ +EXT4_INODE * +Ext4AllocateInode ( + IN EXT4_PARTITION *Partition + ) +{ + BOOLEAN NeedsToZeroRest; + UINT32 InodeSize; + EXT4_INODE *Inode; + + NeedsToZeroRest = FALSE; + InodeSize = Partition->InodeSize; + + // We allocate a structure of at least sizeof(EXT4_INODE), but in the future, when + // write support is added and we need to flush inodes to disk, we could have a bit better + // distinction between the on-disk inode and a separate, nicer to work with inode struct. + // It's important to note that EXT4_INODE includes fields that may not exist in an actual + // filesystem (the minimum inode size is 128 byte and at the moment the size of EXT4_INODE + // is 160 bytes). + + if (InodeSize < sizeof (EXT4_INODE)) { + InodeSize = sizeof (EXT4_INODE); + NeedsToZeroRest = TRUE; + } + + Inode = AllocateZeroPool (InodeSize); + + if (Inode == NULL) { + return NULL; + } + + if (NeedsToZeroRest) { + Inode->i_extra_isize = 0; + } + + return Inode; +} + +/** + Checks if a file is a directory. + @param[in] File Pointer to the opened file. + + @return TRUE if file is a directory. +**/ +BOOLEAN +Ext4FileIsDir ( + IN CONST EXT4_FILE *File + ) +{ + return (File->Inode->i_mode & EXT4_INO_TYPE_DIR) == EXT4_INO_TYPE_DIR; +} + +/** + Checks if a file is a symlink. + + @param[in] File Pointer to the opened file. + + @return BOOLEAN Whether file is a symlink +**/ +BOOLEAN +Ext4FileIsSymlink ( + IN CONST EXT4_FILE *File + ) +{ + return (File->Inode->i_mode & EXT4_INO_TYPE_SYMLINK) == EXT4_INO_TYPE_SYMLINK; +} + +/** + Checks if a file is a regular file. + @param[in] File Pointer to the opened file. + + @return BOOLEAN TRUE if file is a regular file. +**/ +BOOLEAN +Ext4FileIsReg ( + IN CONST EXT4_FILE *File + ) +{ + return (File->Inode->i_mode & EXT4_INO_TYPE_REGFILE) == EXT4_INO_TYPE_REGFILE; +} + +/** + Calculates the physical space used by a file. + @param[in] File Pointer to the opened file. + + @return Physical space used by a file, in bytes. +**/ +UINT64 +Ext4FilePhysicalSpace ( + IN EXT4_FILE *File + ) +{ + BOOLEAN HugeFile; + UINT64 Blocks; + + HugeFile = EXT4_HAS_RO_COMPAT (File->Partition, EXT4_FEATURE_RO_COMPAT_HUGE_FILE); + Blocks = File->Inode->i_blocks; + + if (HugeFile) { + Blocks |= LShiftU64 (File->Inode->i_osd2.data_linux.l_i_blocks_high, 32); + + // If HUGE_FILE is enabled and EXT4_HUGE_FILE_FL is set in the inode's flags, each unit + // in i_blocks corresponds to an actual filesystem block + if ((File->Inode->i_flags & EXT4_HUGE_FILE_FL) != 0) { + return MultU64x32 (Blocks, File->Partition->BlockSize); + } + } + + // Else, each i_blocks unit corresponds to 512 bytes + return MultU64x32 (Blocks, 512); +} + +// Copied from EmbeddedPkg at my mentor's request. +// The lack of comments and good variable names is frightening... + +/** + Converts Epoch seconds (elapsed since 1970 JANUARY 01, 00:00:00 UTC) to EFI_TIME. + + @param[in] EpochSeconds Epoch seconds. + @param[out] Time The time converted to UEFI format. + +**/ +STATIC +VOID +EFIAPI +EpochToEfiTime ( + IN UINTN EpochSeconds, + OUT EFI_TIME *Time + ) +{ + UINTN a; + UINTN b; + UINTN c; + UINTN d; + UINTN g; + UINTN j; + UINTN m; + UINTN y; + UINTN da; + UINTN db; + UINTN dc; + UINTN dg; + UINTN hh; + UINTN mm; + UINTN ss; + UINTN J; + + J = (EpochSeconds / 86400) + 2440588; + j = J + 32044; + g = j / 146097; + dg = j % 146097; + c = (((dg / 36524) + 1) * 3) / 4; + dc = dg - (c * 36524); + b = dc / 1461; + db = dc % 1461; + a = (((db / 365) + 1) * 3) / 4; + da = db - (a * 365); + y = (g * 400) + (c * 100) + (b * 4) + a; + m = (((da * 5) + 308) / 153) - 2; + d = da - (((m + 4) * 153) / 5) + 122; + + Time->Year = (UINT16)(y - 4800 + ((m + 2) / 12)); + Time->Month = ((m + 2) % 12) + 1; + Time->Day = (UINT8)(d + 1); + + ss = EpochSeconds % 60; + a = (EpochSeconds - ss) / 60; + mm = a % 60; + b = (a - mm) / 60; + hh = b % 24; + + Time->Hour = (UINT8)hh; + Time->Minute = (UINT8)mm; + Time->Second = (UINT8)ss; + Time->Nanosecond = 0; +} + +// The time format used to (de/en)code timestamp and timestamp_extra is documented on +// the ext4 docs page in kernel.org +#define EXT4_EXTRA_TIMESTAMP_MASK ((1 << 2) - 1) + +#define EXT4_FILE_GET_TIME_GENERIC(Name, Field) \ + VOID \ + Ext4File ## Name (IN EXT4_FILE *File, OUT EFI_TIME *Time) \ + { \ + EXT4_INODE *Inode = File->Inode; \ + UINT64 SecondsEpoch = Inode->Field; \ + UINT32 Nanoseconds = 0; \ + \ + if (EXT4_INODE_HAS_FIELD (Inode, Field ## _extra)) { \ + SecondsEpoch |= LShiftU64 ((UINT64)(Inode->Field ## _extra & EXT4_EXTRA_TIMESTAMP_MASK), 32); \ + Nanoseconds = Inode->Field ## _extra >> 2; \ + } \ + EpochToEfiTime ((UINTN)SecondsEpoch, Time); \ + Time->Nanosecond = Nanoseconds; \ + } + +// Note: EpochToEfiTime should be adjusted to take in a UINT64 instead of a UINTN, in order to avoid Y2038 +// on 32-bit systems. + +/** + Gets the file's last access time. + @param[in] File Pointer to the opened file. + @param[out] Time Pointer to an EFI_TIME structure. +**/ +EXT4_FILE_GET_TIME_GENERIC (ATime, i_atime); + +/** + Gets the file's last (data) modification time. + @param[in] File Pointer to the opened file. + @param[out] Time Pointer to an EFI_TIME structure. +**/ +EXT4_FILE_GET_TIME_GENERIC (MTime, i_mtime); + +/** + Gets the file's creation time. + @param[in] File Pointer to the opened file. + @param[out] Time Pointer to an EFI_TIME structure. +**/ +STATIC +EXT4_FILE_GET_TIME_GENERIC ( + CrTime, + i_crtime + ); + +/** + Gets the file's creation time, if possible. + @param[in] File Pointer to the opened file. + @param[out] Time Pointer to an EFI_TIME structure. + In the case where the the creation time isn't recorded, + Time is zeroed. +**/ +VOID +Ext4FileCreateTime ( + IN EXT4_FILE *File, + OUT EFI_TIME *Time + ) +{ + EXT4_INODE *Inode; + + Inode = File->Inode; + + if (!EXT4_INODE_HAS_FIELD (Inode, i_crtime)) { + ZeroMem (Time, sizeof (EFI_TIME)); + return; + } + + Ext4FileCrTime (File, Time); +} + +/** + Checks if the checksum of the inode is correct. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] Inode Pointer to the inode. + @param[in] InodeNum Inode number. + + @return TRUE if checksum is correct, FALSE if there is corruption. +**/ +BOOLEAN +Ext4CheckInodeChecksum ( + IN CONST EXT4_PARTITION *Partition, + IN CONST EXT4_INODE *Inode, + IN EXT4_INO_NR InodeNum + ) +{ + UINT32 Csum; + UINT32 DiskCsum; + + if (!EXT4_HAS_METADATA_CSUM (Partition)) { + return TRUE; + } + + Csum = Ext4CalculateInodeChecksum (Partition, Inode, InodeNum); + + DiskCsum = Inode->i_osd2.data_linux.l_i_checksum_lo; + + if (EXT4_INODE_HAS_FIELD (Inode, i_checksum_hi)) { + DiskCsum |= ((UINT32)Inode->i_checksum_hi) << 16; + } else { + // Only keep the lower bits for the comparison if the checksum is 16 bits. + Csum &= 0xffff; + } + + return Csum == DiskCsum; +} diff --git a/Ext4Pkg/Ext4Dxe/Partition.c b/Ext4Pkg/Ext4Dxe/Partition.c new file mode 100644 index 0000000000..316807497d --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/Partition.c @@ -0,0 +1,132 @@ +/** @file + Driver entry point + + Copyright (c) 2021 Pedro Falcato All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Ext4Dxe.h" + +/** + Opens an ext4 partition and installs the Simple File System protocol. + + @param[in] DeviceHandle Handle to the block device. + @param[in] DiskIo Pointer to an EFI_DISK_IO_PROTOCOL. + @param[in opt] DiskIo2 Pointer to an EFI_DISK_IO2_PROTOCOL, if supported. + @param[in] BlockIo Pointer to an EFI_BLOCK_IO_PROTOCOL. + + @retval EFI_SUCCESS The opening was successful. + !EFI_SUCCESS Opening failed. +**/ +EFI_STATUS +Ext4OpenPartition ( + IN EFI_HANDLE DeviceHandle, + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN OPTIONAL EFI_DISK_IO2_PROTOCOL *DiskIo2, + IN EFI_BLOCK_IO_PROTOCOL *BlockIo + ) +{ + EXT4_PARTITION *Part; + EFI_STATUS Status; + + Part = AllocateZeroPool (sizeof (*Part)); + + if (Part == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + InitializeListHead (&Part->OpenFiles); + + Part->BlockIo = BlockIo; + Part->DiskIo = DiskIo; + Part->DiskIo2 = DiskIo2; + + Status = Ext4OpenSuperblock (Part); + + if (EFI_ERROR (Status)) { + FreePool (Part); + return Status; + } + + Part->Interface.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; + Part->Interface.OpenVolume = Ext4OpenVolume; + Status = gBS->InstallMultipleProtocolInterfaces ( + &DeviceHandle, + &gEfiSimpleFileSystemProtocolGuid, + &Part->Interface, + NULL + ); + + if (EFI_ERROR (Status)) { + FreePool (Part); + return Status; + } + + return EFI_SUCCESS; +} + +/** + Sets up the protocol and metadata of a file that is being opened. + + @param[in out] File Pointer to the file. + @param[in] Partition Pointer to the opened partition. +**/ +VOID +Ext4SetupFile ( + IN OUT EXT4_FILE *File, + IN EXT4_PARTITION *Partition + ) +{ + // Note: We don't yet support revision 2 of the file protocol + // (needs DISK_IO2 + asynchronous IO) + File->Protocol.Revision = EFI_FILE_PROTOCOL_REVISION; + File->Protocol.Open = Ext4Open; + File->Protocol.Close = Ext4Close; + File->Protocol.Delete = Ext4Delete; + File->Protocol.Read = Ext4ReadFile; + File->Protocol.Write = Ext4WriteFile; + File->Protocol.SetPosition = Ext4SetPosition; + File->Protocol.GetPosition = Ext4GetPosition; + File->Protocol.GetInfo = Ext4GetInfo; + File->Protocol.SetInfo = Ext4SetInfo; + + File->Partition = Partition; +} + +/** + Unmounts and frees an ext4 partition. + + @param[in] Partition Pointer to the opened partition. + + @retval Status of the unmount. +**/ +EFI_STATUS +Ext4UnmountAndFreePartition ( + IN EXT4_PARTITION *Partition + ) +{ + LIST_ENTRY *Entry; + LIST_ENTRY *NextEntry; + EXT4_FILE *File; + BOOLEAN DeletedRootDentry; + + Partition->Unmounting = TRUE; + Ext4CloseInternal (Partition->Root); + + BASE_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Partition->OpenFiles) { + File = EXT4_FILE_FROM_OPEN_FILES_NODE (Entry); + + Ext4CloseInternal (File); + } + + DeletedRootDentry = Ext4UnrefDentry (Partition->RootDentry); + + if (!DeletedRootDentry) { + DEBUG ((DEBUG_ERROR, "[ext4] Failed to delete root dentry - resource leak present.\n")); + } + + FreePool (Partition->BlockGroups); + FreePool (Partition); + + return EFI_SUCCESS; +} diff --git a/Ext4Pkg/Ext4Dxe/Superblock.c b/Ext4Pkg/Ext4Dxe/Superblock.c new file mode 100644 index 0000000000..604925b582 --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/Superblock.c @@ -0,0 +1,363 @@ +/** @file + Superblock managing routines + + Copyright (c) 2021 - 2023 Pedro Falcato All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Ext4Dxe.h" + +STATIC CONST UINT32 gSupportedCompatFeat = EXT4_FEATURE_COMPAT_EXT_ATTR; + +STATIC CONST UINT32 gSupportedRoCompatFeat = + EXT4_FEATURE_RO_COMPAT_DIR_NLINK | EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | + EXT4_FEATURE_RO_COMPAT_HUGE_FILE | EXT4_FEATURE_RO_COMPAT_LARGE_FILE | + EXT4_FEATURE_RO_COMPAT_GDT_CSUM | EXT4_FEATURE_RO_COMPAT_METADATA_CSUM | EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER; + +STATIC CONST UINT32 gSupportedIncompatFeat = + EXT4_FEATURE_INCOMPAT_64BIT | EXT4_FEATURE_INCOMPAT_DIRDATA | + EXT4_FEATURE_INCOMPAT_FLEX_BG | EXT4_FEATURE_INCOMPAT_FILETYPE | + EXT4_FEATURE_INCOMPAT_EXTENTS | EXT4_FEATURE_INCOMPAT_LARGEDIR | + EXT4_FEATURE_INCOMPAT_MMP | EXT4_FEATURE_INCOMPAT_RECOVER | EXT4_FEATURE_INCOMPAT_CSUM_SEED; + +// Future features that may be nice additions in the future: +// 1) Btree support: Required for write support and would speed up lookups in large directories. +// 2) meta_bg: Required to mount meta_bg-enabled partitions. + +// Note: We ignore MMP because it's impossible that it's mapped elsewhere, +// I think (unless there's some sort of network setup where we're accessing a remote partition). + +// Note on corruption signaling: +// We (Ext4Dxe) could signal corruption by setting s_state to |= EXT4_FS_STATE_ERRORS_DETECTED. +// I've decided against that, because right now the driver is read-only, and +// that would mean we would need to writeback the superblock. If something like +// this is desired, it's fairly trivial to look for EFI_VOLUME_CORRUPTED +// references and add some Ext4SignalCorruption function + function call. + +/** + Checks the superblock's magic value. + + @param[in] DiskIo Pointer to the DiskIo. + @param[in] BlockIo Pointer to the BlockIo. + + @returns Whether the partition has a valid EXT4 superblock magic value. +**/ +BOOLEAN +Ext4SuperblockCheckMagic ( + IN EFI_DISK_IO_PROTOCOL *DiskIo, + IN EFI_BLOCK_IO_PROTOCOL *BlockIo + ) +{ + UINT16 Magic; + EFI_STATUS Status; + + Status = DiskIo->ReadDisk ( + DiskIo, + BlockIo->Media->MediaId, + EXT4_SUPERBLOCK_OFFSET + OFFSET_OF (EXT4_SUPERBLOCK, s_magic), + sizeof (Magic), + &Magic + ); + if (EFI_ERROR (Status)) { + return FALSE; + } + + if (Magic != EXT4_SIGNATURE) { + return FALSE; + } + + return TRUE; +} + +/** + Does brief validation of the ext4 superblock. + + @param[in] Sb Pointer to the read superblock. + + @return TRUE if a valid ext4 superblock, else FALSE. +**/ +BOOLEAN +Ext4SuperblockValidate ( + CONST EXT4_SUPERBLOCK *Sb + ) +{ + if (Sb->s_magic != EXT4_SIGNATURE) { + return FALSE; + } + + if ((Sb->s_rev_level != EXT4_DYNAMIC_REV) && (Sb->s_rev_level != EXT4_GOOD_OLD_REV)) { + return FALSE; + } + + if ((Sb->s_state & EXT4_FS_STATE_UNMOUNTED) == 0) { + DEBUG ((DEBUG_WARN, "[ext4] Filesystem was not unmounted cleanly\n")); + } + + return TRUE; +} + +/** + Calculates the superblock's checksum. + + @param[in] Partition Pointer to the opened partition. + @param[in] Sb Pointer to the superblock. + + @return The superblock's checksum. +**/ +STATIC +UINT32 +Ext4CalculateSuperblockChecksum ( + EXT4_PARTITION *Partition, + CONST EXT4_SUPERBLOCK *Sb + ) +{ + // Most checksums require us to go through a dummy 0 as part of the requirement + // that the checksum is done over a structure with its checksum field = 0. + UINT32 Checksum; + + Checksum = Ext4CalculateChecksum ( + Partition, + Sb, + OFFSET_OF (EXT4_SUPERBLOCK, s_checksum), + ~0U + ); + + return Checksum; +} + +/** + Verifies that the superblock's checksum is valid. + + @param[in] Partition Pointer to the opened partition. + @param[in] Sb Pointer to the superblock. + + @return The superblock's checksum. +**/ +STATIC +BOOLEAN +Ext4VerifySuperblockChecksum ( + EXT4_PARTITION *Partition, + CONST EXT4_SUPERBLOCK *Sb + ) +{ + if (!EXT4_HAS_METADATA_CSUM (Partition)) { + return TRUE; + } + + return Sb->s_checksum == Ext4CalculateSuperblockChecksum (Partition, Sb); +} + +/** + Opens and parses the superblock. + + @param[out] Partition Partition structure to fill with filesystem details. + @retval EFI_SUCCESS Parsing was successful and the partition is a + valid ext4 partition. +**/ +EFI_STATUS +Ext4OpenSuperblock ( + OUT EXT4_PARTITION *Partition + ) +{ + UINT32 Index; + EFI_STATUS Status; + EXT4_SUPERBLOCK *Sb; + UINT32 NrBlocksRem; + UINTN NrBlocks; + UINT32 UnsupportedRoCompat; + EXT4_BLOCK_GROUP_DESC *Desc; + + Status = Ext4ReadDiskIo ( + Partition, + &Partition->SuperBlock, + sizeof (EXT4_SUPERBLOCK), + EXT4_SUPERBLOCK_OFFSET + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + Sb = &Partition->SuperBlock; + + if (!Ext4SuperblockValidate (Sb)) { + return EFI_VOLUME_CORRUPTED; + } + + if (Sb->s_rev_level == EXT4_DYNAMIC_REV) { + Partition->FeaturesCompat = Sb->s_feature_compat; + Partition->FeaturesIncompat = Sb->s_feature_incompat; + Partition->FeaturesRoCompat = Sb->s_feature_ro_compat; + Partition->InodeSize = Sb->s_inode_size; + + // Check for proper alignment of InodeSize and that InodeSize is indeed larger than + // the minimum size, 128 bytes. + if (((Partition->InodeSize % 4) != 0) || (Partition->InodeSize < EXT4_GOOD_OLD_INODE_SIZE)) { + return EFI_VOLUME_CORRUPTED; + } + } else { + // GOOD_OLD_REV + Partition->FeaturesCompat = Partition->FeaturesIncompat = Partition->FeaturesRoCompat = 0; + Partition->InodeSize = EXT4_GOOD_OLD_INODE_SIZE; + } + + // Now, check for the feature set of the filesystem + // It's essential to check for this to avoid filesystem corruption and to avoid + // accidentally opening an ext2/3/4 filesystem we don't understand, which would be disastrous. + + if (Partition->FeaturesIncompat & ~gSupportedIncompatFeat) { + DEBUG (( + DEBUG_ERROR, + "[ext4] Unsupported features %lx\n", + Partition->FeaturesIncompat & ~gSupportedIncompatFeat + )); + return EFI_UNSUPPORTED; + } + + if (EXT4_HAS_INCOMPAT (Partition, EXT4_FEATURE_INCOMPAT_RECOVER)) { + DEBUG ((DEBUG_WARN, "[ext4] Needs journal recovery, mounting read-only\n")); + Partition->ReadOnly = TRUE; + } + + // At the time of writing, it's the only supported checksum. + if (EXT4_HAS_METADATA_CSUM (Partition) && (Sb->s_checksum_type != EXT4_CHECKSUM_CRC32C)) { + return EFI_UNSUPPORTED; + } + + if (EXT4_HAS_INCOMPAT (Partition, EXT4_FEATURE_INCOMPAT_CSUM_SEED)) { + Partition->InitialSeed = Sb->s_checksum_seed; + } else { + Partition->InitialSeed = Ext4CalculateChecksum (Partition, Sb->s_uuid, 16, ~0U); + } + + UnsupportedRoCompat = Partition->FeaturesRoCompat & ~gSupportedRoCompatFeat; + + if (UnsupportedRoCompat != 0) { + DEBUG ((DEBUG_WARN, "[ext4] Unsupported ro compat %x\n", UnsupportedRoCompat)); + Partition->ReadOnly = TRUE; + } + + // gSupportedCompatFeat is documentation-only since we never need to access it. + // The line below avoids unused variable warnings. + (VOID)gSupportedCompatFeat; + + DEBUG ((DEBUG_FS, "Read only = %u\n", Partition->ReadOnly)); + + if (Sb->s_inodes_per_group == 0) { + DEBUG ((DEBUG_ERROR, "[ext4] Inodes per group can not be zero\n")); + return EFI_VOLUME_CORRUPTED; + } + + if (Sb->s_log_block_size > EXT4_LOG_BLOCK_SIZE_MAX) { + DEBUG ((DEBUG_ERROR, "[ext4] SuperBlock s_log_block_size %lu is too big\n", Sb->s_log_block_size)); + return EFI_UNSUPPORTED; + } + + Partition->BlockSize = (UINT32)LShiftU64 (1024, Sb->s_log_block_size); + + // The size of a block group can also be calculated as 8 * Partition->BlockSize + if (Sb->s_blocks_per_group != 8 * Partition->BlockSize) { + return EFI_UNSUPPORTED; + } + + Partition->NumberBlocks = EXT4_BLOCK_NR_FROM_HALFS (Partition, Sb->s_blocks_count, Sb->s_blocks_count_hi); + Partition->NumberBlockGroups = DivU64x32 (Partition->NumberBlocks, Sb->s_blocks_per_group); + + DEBUG (( + DEBUG_FS, + "[ext4] Number of blocks = %lu\n[ext4] Number of block groups: %lu\n", + Partition->NumberBlocks, + Partition->NumberBlockGroups + )); + + if (EXT4_IS_64_BIT (Partition)) { + // s_desc_size should be 4 byte aligned and + // 64 bit filesystems need DescSize to be 64 bytes + if (((Sb->s_desc_size % 4) != 0) || (Sb->s_desc_size < EXT4_64BIT_BLOCK_DESC_SIZE)) { + return EFI_VOLUME_CORRUPTED; + } + + Partition->DescSize = Sb->s_desc_size; + } else { + Partition->DescSize = EXT4_OLD_BLOCK_DESC_SIZE; + } + + if (!Ext4VerifySuperblockChecksum (Partition, Sb)) { + DEBUG ((DEBUG_ERROR, "[ext4] Bad superblock checksum %lx\n", Ext4CalculateSuperblockChecksum (Partition, Sb))); + return EFI_VOLUME_CORRUPTED; + } + + NrBlocks = (UINTN)DivU64x32Remainder ( + MultU64x32 (Partition->NumberBlockGroups, Partition->DescSize), + Partition->BlockSize, + &NrBlocksRem + ); + + if (NrBlocksRem != 0) { + NrBlocks++; + } + + Partition->BlockGroups = Ext4AllocAndReadBlocks (Partition, NrBlocks, Partition->BlockSize == 1024 ? 2 : 1); + + if (Partition->BlockGroups == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Index = 0; Index < Partition->NumberBlockGroups; Index++) { + Desc = Ext4GetBlockGroupDesc (Partition, Index); + if (!Ext4VerifyBlockGroupDescChecksum (Partition, Desc, Index)) { + DEBUG ((DEBUG_ERROR, "[ext4] Block group descriptor %u has an invalid checksum\n", Index)); + FreePool (Partition->BlockGroups); + return EFI_VOLUME_CORRUPTED; + } + } + + // RootDentry will serve as the basis of our directory entry tree. + Partition->RootDentry = Ext4CreateDentry (L"\\", NULL); + + if (Partition->RootDentry == NULL) { + FreePool (Partition->BlockGroups); + return EFI_OUT_OF_RESOURCES; + } + + // Note that the cast below is completely safe, because EXT4_FILE is a specialization of EFI_FILE_PROTOCOL + Status = Ext4OpenVolume (&Partition->Interface, (EFI_FILE_PROTOCOL **)&Partition->Root); + + if (EFI_ERROR (Status)) { + Ext4UnrefDentry (Partition->RootDentry); + FreePool (Partition->BlockGroups); + } + + return Status; +} + +/** + Calculates the checksum of the given buffer. + @param[in] Partition Pointer to the opened EXT4 partition. + @param[in] Buffer Pointer to the buffer. + @param[in] Length Length of the buffer, in bytes. + @param[in] InitialValue Initial value of the CRC. + + @return The checksum. +**/ +UINT32 +Ext4CalculateChecksum ( + IN CONST EXT4_PARTITION *Partition, + IN CONST VOID *Buffer, + IN UINTN Length, + IN UINT32 InitialValue + ) +{ + if (!EXT4_HAS_METADATA_CSUM (Partition)) { + return 0; + } + + switch (Partition->SuperBlock.s_checksum_type) { + case EXT4_CHECKSUM_CRC32C: + // For some reason, EXT4 really likes non-inverted CRC32C checksums, so we stick to that here. + return ~CalculateCrc32c(Buffer, Length, ~InitialValue); + default: + ASSERT (FALSE); + return 0; + } +} diff --git a/Ext4Pkg/Ext4Dxe/Symlink.c b/Ext4Pkg/Ext4Dxe/Symlink.c new file mode 100644 index 0000000000..d80cb9fff9 --- /dev/null +++ b/Ext4Pkg/Ext4Dxe/Symlink.c @@ -0,0 +1,261 @@ +/** @file + Symbolic links routines + + Copyright (c) 2022-2023 Savva Mitrofanov All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Ext4Dxe.h" + +/** + Detects if a symlink is a fast symlink. + + @param[in] File Pointer to the opened file. + + @return BOOLEAN Whether symlink is a fast symlink +**/ +STATIC +BOOLEAN +Ext4SymlinkIsFastSymlink ( + IN CONST EXT4_FILE *File + ) +{ + // + // Detection logic of the fast-symlink splits into two behaviors - old and new. + // The old behavior is based on comparing the extended attribute blocks + // with the inode's i_blocks, and if it's zero we know the inode isn't storing + // the link in filesystem blocks, so we look to the inode->i_data. + // The new behavior is apparently needed only with the large EA inode feature. + // In this case we check that inode size less than maximum fast symlink size. + // So, we revert to the old behavior if the large EA inode feature is not set. + // + UINT32 FileAcl; + UINT32 ExtAttrBlocks; + + if ((File->Inode->i_flags & EXT4_EA_INODE_FL) == 0) { + FileAcl = File->Inode->i_file_acl; + if (EXT4_IS_64_BIT (File->Partition)) { + // + // We don't care about final value, we are just checking for any bit is set + // so, thats why we neglect LShiftU64(.., 32) + // + FileAcl |= File->Inode->i_osd2.data_linux.l_i_file_acl_high; + } + + ExtAttrBlocks = FileAcl != 0 ? (File->Partition->BlockSize >> 9) : 0; + + return File->Inode->i_blocks == ExtAttrBlocks; + } + + return EXT4_INODE_SIZE (File->Inode) <= EXT4_FAST_SYMLINK_MAX_SIZE; +} + +/** + Reads a fast symlink file. + + @param[in] Partition Pointer to the ext4 partition. + @param[in] File Pointer to the open symlink file. + @param[out] AsciiSymlink Pointer to the output ascii symlink string. + @param[out] AsciiSymlinkSize Pointer to the output ascii symlink string length. + + @retval EFI_SUCCESS Fast symlink was read. + @retval EFI_OUT_OF_RESOURCES Memory allocation error. +**/ +STATIC +EFI_STATUS +Ext4ReadFastSymlink ( + IN EXT4_PARTITION *Partition, + IN EXT4_FILE *File, + OUT CHAR8 **AsciiSymlink, + OUT UINT32 *AsciiSymlinkSize + ) +{ + UINT32 SymlinkSize; + CHAR8 *AsciiSymlinkTmp; + + // + // Fast-symlink's EXT4_INODE_SIZE is not necessarily validated when we checked it in + // Ext4SymlinkIsFastSymlink(), so truncate if necessary. + // + SymlinkSize = (UINT32)MIN (EXT4_INODE_SIZE (File->Inode), EXT4_FAST_SYMLINK_MAX_SIZE); + + AsciiSymlinkTmp = AllocatePool (SymlinkSize + 1); + if (AsciiSymlinkTmp == NULL) { + DEBUG ((DEBUG_ERROR, "[ext4] Failed to allocate symlink ascii string buffer\n")); + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (AsciiSymlinkTmp, File->Inode->i_data, SymlinkSize); + + // + // Add null-terminator + // + AsciiSymlinkTmp[SymlinkSize] = '\0'; + + *AsciiSymlink = AsciiSymlinkTmp; + *AsciiSymlinkSize = SymlinkSize + 1; + + return EFI_SUCCESS; +} + +/** + Reads a slow symlink file. + + @param[in] Partition Pointer to the ext4 partition. + @param[in] File Pointer to the open symlink file. + @param[out] AsciiSymlink Pointer to the output ascii symlink string. + @param[out] AsciiSymlinkSize Pointer to the output ascii symlink string length. + + @retval EFI_SUCCESS Slow symlink was read. + @retval EFI_OUT_OF_RESOURCES Memory allocation error. + @retval EFI_INVALID_PARAMETER Slow symlink path has incorrect length + @retval EFI_VOLUME_CORRUPTED Symlink read block size differ from inode value +**/ +STATIC +EFI_STATUS +Ext4ReadSlowSymlink ( + IN EXT4_PARTITION *Partition, + IN EXT4_FILE *File, + OUT CHAR8 **AsciiSymlink, + OUT UINT32 *AsciiSymlinkSize + ) +{ + EFI_STATUS Status; + CHAR8 *SymlinkTmp; + UINT64 SymlinkSizeTmp; + UINT32 SymlinkAllocateSize; + UINTN ReadSize; + + SymlinkSizeTmp = EXT4_INODE_SIZE (File->Inode); + + // + // Allocate EXT4_INODE_SIZE + 1 + // + if (SymlinkSizeTmp >= EXT4_EFI_PATH_MAX) { + DEBUG (( + DEBUG_WARN, + "[ext4] Warn: symlink path maximum length was hit!\n" + )); + return EFI_INVALID_PARAMETER; + } + + SymlinkAllocateSize = (UINT32)SymlinkSizeTmp + 1; + + SymlinkTmp = AllocatePool (SymlinkAllocateSize); + if (SymlinkTmp == NULL) { + DEBUG ((DEBUG_FS, "[ext4] Failed to allocate symlink ascii string buffer\n")); + return EFI_OUT_OF_RESOURCES; + } + + ReadSize = (UINTN)SymlinkSizeTmp; + Status = Ext4Read (Partition, File, SymlinkTmp, File->Position, &ReadSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_FS, "[ext4] Failed to read symlink from blocks with status %r\n", Status)); + FreePool (SymlinkTmp); + return Status; + } + + if (SymlinkSizeTmp != ReadSize) { + DEBUG (( + DEBUG_FS, + "[ext4] Error! The size of the read block doesn't match the value from the inode!\n" + )); + FreePool (SymlinkTmp); + return EFI_VOLUME_CORRUPTED; + } + + // + // Add null-terminator + // + SymlinkTmp[ReadSize] = '\0'; + + *AsciiSymlinkSize = SymlinkAllocateSize; + *AsciiSymlink = SymlinkTmp; + + return EFI_SUCCESS; +} + +/** + Reads a symlink file. + + @param[in] Partition Pointer to the ext4 partition. + @param[in] File Pointer to the open symlink file. + @param[out] Symlink Pointer to the output unicode symlink string. + + @retval EFI_SUCCESS Symlink was read. + @retval EFI_ACCESS_DENIED Symlink is encrypted. + @retval EFI_OUT_OF_RESOURCES Memory allocation error. + @retval EFI_INVALID_PARAMETER Symlink path has incorrect length + @retval EFI_VOLUME_CORRUPTED Symlink read block size differ from inode value +**/ +EFI_STATUS +Ext4ReadSymlink ( + IN EXT4_PARTITION *Partition, + IN EXT4_FILE *File, + OUT CHAR16 **Symlink + ) +{ + EFI_STATUS Status; + CHAR8 *SymlinkTmp; + UINT32 SymlinkSize; + CHAR16 *Symlink16Tmp; + CHAR16 *Needle; + + // + // Assume that we already read Inode via Ext4ReadInode + // Skip reading, just check encryption flag + // + if ((File->Inode->i_flags & EXT4_ENCRYPT_FL) != 0) { + DEBUG ((DEBUG_WARN, "[ext4] Warn: symlink is encrypted\n")); + return EFI_ACCESS_DENIED; + } + + if (Ext4SymlinkIsFastSymlink (File)) { + Status = Ext4ReadFastSymlink (Partition, File, &SymlinkTmp, &SymlinkSize); + } else { + Status = Ext4ReadSlowSymlink (Partition, File, &SymlinkTmp, &SymlinkSize); + } + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_FS, "[ext4] Symlink read error with Status %r\n", Status)); + return Status; + } + + Symlink16Tmp = AllocatePool (SymlinkSize * sizeof (CHAR16)); + if (Symlink16Tmp == NULL) { + DEBUG ((DEBUG_FS, "[ext4] Failed to allocate symlink unicode string buffer\n")); + FreePool (SymlinkTmp); + return EFI_OUT_OF_RESOURCES; + } + + Status = AsciiStrToUnicodeStrS ( + SymlinkTmp, + Symlink16Tmp, + SymlinkSize + ); + + FreePool (SymlinkTmp); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_FS, + "[ext4] Failed to convert ascii symlink to unicode with Status %r\n", + Status + )); + FreePool (Symlink16Tmp); + return Status; + } + + // + // Convert to UEFI slashes + // + for (Needle = Symlink16Tmp; *Needle != L'\0'; Needle++) { + if (*Needle == L'/') { + *Needle = L'\\'; + } + } + + *Symlink = Symlink16Tmp; + + return Status; +} diff --git a/Ext4Pkg/Ext4Libs.dsc.inc b/Ext4Pkg/Ext4Libs.dsc.inc new file mode 100644 index 0000000000..078183e0cc --- /dev/null +++ b/Ext4Pkg/Ext4Libs.dsc.inc @@ -0,0 +1,11 @@ +## @file +# Ext4 DSC include file for [LibraryClasses] section of all Architectures. +# +# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +!if $(EXT4_ENABLE) == TRUE + BaseUcs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf +!endif diff --git a/Ext4Pkg/Ext4Pkg.dec b/Ext4Pkg/Ext4Pkg.dec new file mode 100644 index 0000000000..f1f8b39c3c --- /dev/null +++ b/Ext4Pkg/Ext4Pkg.dec @@ -0,0 +1,17 @@ +## @file +# Ext4 Package +# +# This package provides libraries and drivers related to the ext4 filesystem implementation. +# More details are available at: https://www.kernel.org/doc/html/v5.4/filesystems/ext4/index.html +# +# Copyright (c) 2021 Pedro Falcato +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = Ext4Pkg + PACKAGE_UNI_FILE = Ext4Pkg.uni + PACKAGE_GUID = 6B4BF998-668B-46D3-BCFA-971F99F8708C + PACKAGE_VERSION = 0.1 diff --git a/Ext4Pkg/Ext4Pkg.dsc b/Ext4Pkg/Ext4Pkg.dsc new file mode 100644 index 0000000000..18cfc102b8 --- /dev/null +++ b/Ext4Pkg/Ext4Pkg.dsc @@ -0,0 +1,75 @@ +## @file +# Ext4 Package +# +# This package provides libraries and drivers related to the ext4 filesystem implementation. +# More details are available at: https://www.kernel.org/doc/html/v5.4/filesystems/ext4/index.html +# +# Copyright (c) 2021 Pedro Falcato +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + + +[Defines] + PLATFORM_NAME = Ext4 + PLATFORM_GUID = 6B4BF998-668B-46D3-BCFA-971F99F8708C + PLATFORM_VERSION = 0.1 + DSC_SPECIFICATION = 0x00010005 + SUPPORTED_ARCHITECTURES = IA32|X64|EBC|ARM|AARCH64|RISCV64 + OUTPUT_DIRECTORY = Build/Ext4Pkg + BUILD_TARGETS = DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER = DEFAULT + +!include MdePkg/MdeLibs.dsc.inc + +[BuildOptions] + *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES + +[LibraryClasses] + # + # Entry Point Libraries + # + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + # + # Common Libraries + # + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf + BaseUcs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf + + # + # Required for stack protector support + # + NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf + +################################################################################################### +# +# Components Section - list of the modules and components that will be processed by compilation +# tools and the EDK II tools to generate PE32/PE32+/Coff image files. +# +# Note: The EDK II DSC file is not used to specify how compiled binary images get placed +# into firmware volume images. This section is just a list of modules to compile from +# source into UEFI-compliant binaries. +# It is the FDF file that contains information on combining binary files into firmware +# volume images, whose concept is beyond UEFI and is described in PI specification. +# Binary modules do not need to be listed in this section, as they should be +# specified in the FDF file. For example: Shell binary (Shell_Full.efi), FAT binary (Fat.efi), +# Logo (Logo.bmp), and etc. +# There may also be modules listed in this section that are not required in the FDF file, +# When a module listed here is excluded from FDF file, then UEFI-compliant binary will be +# generated for it, but the binary will not be put into any firmware volume. +# +################################################################################################### + +[Components] + Ext4Pkg/Ext4Dxe/Ext4Dxe.inf diff --git a/Ext4Pkg/Ext4Pkg.uni b/Ext4Pkg/Ext4Pkg.uni new file mode 100644 index 0000000000..abeadd8fd9 --- /dev/null +++ b/Ext4Pkg/Ext4Pkg.uni @@ -0,0 +1,14 @@ +## @file +# Ext4 Package +# +# This package provides libraries and drivers related to the ext4 filesystem implementation. +# More details are available at: https://www.kernel.org/doc/html/v5.4/filesystems/ext4/index.html +# +# Copyright (c) 2021 Pedro Falcato +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +#string STR_PACKAGE_ABSTRACT #language en-US "Module implementations for the EXT4 file system" + +#string STR_PACKAGE_DESCRIPTION #language en-US "This package contains UEFI drivers and libraries for the EXT4 file system." From 4928d441c24189dfbfac3d01de4cc889dd960020 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 22 Jul 2024 12:30:43 +0300 Subject: [PATCH 002/341] Ext4Pkg: Various improvements based on Sydr fuzzing results. Signed-off-by: Savva Mitrofanov --- Ext4Pkg/Ext4Dxe/Extents.c | 43 +++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/Ext4Pkg/Ext4Dxe/Extents.c b/Ext4Pkg/Ext4Dxe/Extents.c index 2b82417c9e..b2ab19fc3a 100644 --- a/Ext4Pkg/Ext4Dxe/Extents.c +++ b/Ext4Pkg/Ext4Dxe/Extents.c @@ -39,8 +39,11 @@ Ext4CalculateExtentChecksum ( @param[in] File Pointer to the open file. @param[in] Extents Pointer to an array of extents. @param[in] NumberExtents Length of the array. + + @return Result of the caching **/ -VOID +STATIC +EFI_STATUS Ext4CacheExtents ( IN EXT4_FILE *File, IN CONST EXT4_EXTENT *Extents, @@ -254,7 +257,7 @@ Ext4GetExtent ( EXT4_EXTENT_HEADER *ExtHeader; EXT4_EXTENT_INDEX *Index; EFI_STATUS Status; - UINT32 MaxExtentsPerNode; + UINT16 MaxExtentsPerNode; EXT4_BLOCK_NR BlockNumber; Inode = File->Inode; @@ -283,7 +286,13 @@ Ext4GetExtent ( Status = Ext4GetBlocks (Partition, File, (UINT32)LogicalBlock, Extent); if (!EFI_ERROR (Status)) { - Ext4CacheExtents (File, Extent, 1); + Status = Ext4CacheExtents (File, Extent, 1); + + if (EFI_ERROR (Status) && (Status != EFI_OUT_OF_RESOURCES)) { + return Status; + } + + Status = EFI_SUCCESS; } return Status; @@ -302,7 +311,7 @@ Ext4GetExtent ( // A single node fits into a single block, so we can only have (BlockSize / sizeof(EXT4_EXTENT)) - 1 // extents in a single node. Note the -1, because both leaf and internal node headers are 12 bytes, // and so are individual entries. - MaxExtentsPerNode = (Partition->BlockSize / sizeof (EXT4_EXTENT)) - 1; + MaxExtentsPerNode = (UINT16)((Partition->BlockSize / sizeof (EXT4_EXTENT)) - 1); while (ExtHeader->eh_depth != 0) { CurrentDepth--; @@ -363,7 +372,15 @@ Ext4GetExtent ( * by linux (and possibly other systems) is quite fancy and usually it results in a small number of extents. * Therefore, we shouldn't have any memory issues. **/ - Ext4CacheExtents (File, (EXT4_EXTENT *)(ExtHeader + 1), ExtHeader->eh_entries); + Status = Ext4CacheExtents (File, (EXT4_EXTENT *)(ExtHeader + 1), ExtHeader->eh_entries); + + if (EFI_ERROR (Status) && (Status != EFI_OUT_OF_RESOURCES)) { + if (Buffer != NULL) { + FreePool (Buffer); + } + + return Status; + } Ext = Ext4BinsearchExtentExt (ExtHeader, LogicalBlock); @@ -519,8 +536,11 @@ Ext4FreeExtentsMap ( @param[in] File Pointer to the open file. @param[in] Extents Pointer to an array of extents. @param[in] NumberExtents Length of the array. + + @return Result of the caching **/ -VOID +STATIC +EFI_STATUS Ext4CacheExtents ( IN EXT4_FILE *File, IN CONST EXT4_EXTENT *Extents, @@ -536,10 +556,15 @@ Ext4CacheExtents ( */ for (Idx = 0; Idx < NumberExtents; Idx++, Extents++) { + if (Extents->ee_len == 0) { + // 0-sized extent, must be corruption + return EFI_VOLUME_CORRUPTED; + } + Extent = AllocatePool (sizeof (EXT4_EXTENT)); if (Extent == NULL) { - return; + return EFI_OUT_OF_RESOURCES; } CopyMem (Extent, Extents, sizeof (EXT4_EXTENT)); @@ -553,9 +578,11 @@ Ext4CacheExtents ( continue; } - return; + return EFI_SUCCESS; } } + + return EFI_SUCCESS; } /** From 28045e5b498c3751dac052d2edc0362bf7811eb1 Mon Sep 17 00:00:00 2001 From: Vitaly Cheptsov Date: Mon, 10 Feb 2020 13:10:40 +0300 Subject: [PATCH 003/341] ShellPkg: Add support for input with separately reported modifiers REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2510 Some firmwares: - Report Shift modifier even when they report upper-case unicode letter. - Report Ctrl modifier with "shifted" UniChar (i.e. X - 'A' + 1). This change provides support for these firmwares preserving the compatibility with the previous input handling. Signed-off-by: Michael Belyaev Reviewed-by: Vitaly Cheptsov --- .../Library/BrotliCustomDecompressLib/brotli | 2 +- .../Edit/MainTextEditor.c | 39 +++++++++----- .../UefiShellDebug1CommandsLib/EditInputBar.c | 51 +++++++++++-------- .../UefiShellDebug1CommandsLib/EditMenuBar.c | 6 +++ .../HexEdit/MainHexEditor.c | 12 +++-- 5 files changed, 70 insertions(+), 40 deletions(-) diff --git a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli index f4153a09f8..666c3280cc 160000 --- a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli +++ b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli @@ -1 +1 @@ -Subproject commit f4153a09f87cbb9c826d8fc12c74642bb2d879ea +Subproject commit 666c3280cc11dc433c303d79a83d4ffbdd12cc8d diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.c index f3ea38438d..a9edd368c9 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.c @@ -1397,9 +1397,8 @@ MainCommandDisplayHelp ( continue; } - if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || - (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID)) - { + if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) + || (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID)) { // // For consoles that don't support/report shift state, // CTRL+W is translated to L'W' - L'A' + 1. @@ -1407,15 +1406,17 @@ MainCommandDisplayHelp ( if (KeyData.Key.UnicodeChar == L'W' - L'A' + 1) { break; } - } else if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) && - ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) && - ((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0)) - { + } else if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) + && ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) + && ((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0)) { // // For consoles that supports/reports shift state, // make sure that only CONTROL shift key is pressed. + // For some consoles that report shift state, + // CTRL+W is still translated to L'W' - L'A' + 1. // - if ((KeyData.Key.UnicodeChar == 'w') || (KeyData.Key.UnicodeChar == 'W')) { + if ((KeyData.Key.UnicodeChar == L'w') || (KeyData.Key.UnicodeChar == L'W') + || (KeyData.Key.UnicodeChar == L'w' - L'a' + 1) || (KeyData.Key.UnicodeChar == L'W' - L'A' + 1)) { break; } } @@ -1854,7 +1855,8 @@ MainEditorKeyInput ( EFI_KEY_DATA KeyData; EFI_STATUS Status; EFI_SIMPLE_POINTER_STATE MouseState; - BOOLEAN NoShiftState; + BOOLEAN NoModifierState; + BOOLEAN ShiftOnlyState; do { Status = EFI_SUCCESS; @@ -1904,17 +1906,28 @@ MainEditorKeyInput ( // StatusBarSetRefresh (); // - // NoShiftState: TRUE when no shift key is pressed. + // NoModifierState: TRUE when no modifier key is pressed. // - NoShiftState = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID); + NoModifierState = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) + || (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID); + // + // ShiftOnlyState: TRUE when no modifier key except Shift is pressed. + // + ShiftOnlyState = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) + || ((KeyData.KeyState.KeyShiftState + & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED)) == 0); // // dispatch to different components' key handling function // if (EFI_NOT_FOUND != MenuBarDispatchControlHotKey (&KeyData)) { Status = EFI_SUCCESS; - } else if (NoShiftState && ((KeyData.Key.ScanCode == SCAN_NULL) || ((KeyData.Key.ScanCode >= SCAN_UP) && (KeyData.Key.ScanCode <= SCAN_PAGE_DOWN)))) { + } else if ((ShiftOnlyState && (KeyData.Key.ScanCode == SCAN_NULL)) + || (NoModifierState && (KeyData.Key.ScanCode >= SCAN_UP) && (KeyData.Key.ScanCode <= SCAN_PAGE_DOWN))) { + // + // alphanumeric keys with or without shift, or arrow keys without shift + // Status = FileBufferHandleInput (&KeyData.Key); - } else if (NoShiftState && (KeyData.Key.ScanCode >= SCAN_F1) && (KeyData.Key.ScanCode <= SCAN_F12)) { + } else if (NoModifierState && (KeyData.Key.ScanCode >= SCAN_F1) && (KeyData.Key.ScanCode <= SCAN_F12)) { Status = MenuBarDispatchFunctionKey (&KeyData.Key); } else { StatusBarSetStatusString (L"Unknown Command"); diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c index 0b25965427..2f9ec8a8a2 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c @@ -120,15 +120,17 @@ InputBarRefresh ( UINTN LastColumn ) { - INPUT_BAR_COLOR_UNION Orig; - INPUT_BAR_COLOR_UNION New; - EFI_KEY_DATA KeyData; - UINTN Size; - EFI_STATUS Status; - BOOLEAN NoDisplay; - UINTN EventIndex; - UINTN CursorRow; - UINTN CursorCol; + INPUT_BAR_COLOR_UNION Orig; + INPUT_BAR_COLOR_UNION New; + EFI_KEY_DATA KeyData; + UINTN Size; + EFI_STATUS Status; + BOOLEAN NoDisplay; + UINTN EventIndex; + UINTN CursorRow; + UINTN CursorCol; + BOOLEAN ShiftPressed; + BOOLEAN ModifiersPressed; // // variable initialization @@ -182,30 +184,36 @@ InputBarRefresh ( continue; } - if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) && - (KeyData.KeyState.KeyShiftState != EFI_SHIFT_STATE_VALID)) - { - // - // Shift key pressed. - // + ModifiersPressed = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) + && (KeyData.KeyState.KeyShiftState != EFI_SHIFT_STATE_VALID); + + // + // TRUE if Shift is pressed and no other modifiers are pressed + // + ShiftPressed = ModifiersPressed && + ((KeyData.KeyState.KeyShiftState & + ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED)) == 0); + + if (ModifiersPressed && !ShiftPressed) { continue; } // // pressed ESC // - if (KeyData.Key.ScanCode == SCAN_ESC) { - Size = 0; - Status = EFI_NOT_READY; + if (!ModifiersPressed && KeyData.Key.ScanCode == SCAN_ESC) { + Size = 0; + Status = EFI_NOT_READY; break; } // // return pressed // - if ((KeyData.Key.UnicodeChar == CHAR_LINEFEED) || (KeyData.Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) { + if (!ModifiersPressed + && (KeyData.Key.UnicodeChar == CHAR_LINEFEED || KeyData.Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) { break; - } else if (KeyData.Key.UnicodeChar == CHAR_BACKSPACE) { + } else if (!ModifiersPressed && KeyData.Key.UnicodeChar == CHAR_BACKSPACE) { // // backspace // @@ -216,7 +224,8 @@ InputBarRefresh ( InputBarPrintInput (LastColumn, LastRow); } } - } else if ((KeyData.Key.UnicodeChar <= 127) && (KeyData.Key.UnicodeChar >= 32)) { + } else if ((!ModifiersPressed || ShiftPressed) + && KeyData.Key.UnicodeChar <= 127 && KeyData.Key.UnicodeChar >= 32) { // // VALID ASCII char pressed // diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.c index c9eace1ac9..404dd26ebe 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.c @@ -198,11 +198,17 @@ MenuBarDispatchControlHotKey ( // // For consoles that supports/reports shift state, // make sure only CONTROL is pressed. + // For some consoles that report shift state, + // Ctrl+A is still translated to 1 (UnicodeChar). // if ((KeyData->Key.UnicodeChar >= L'A') && (KeyData->Key.UnicodeChar <= L'Z')) { ControlIndex = KeyData->Key.UnicodeChar - L'A' + 1; } else if ((KeyData->Key.UnicodeChar >= L'a') && (KeyData->Key.UnicodeChar <= L'z')) { ControlIndex = KeyData->Key.UnicodeChar - L'a' + 1; + } else if ((KeyData->Key.UnicodeChar >= L'A' - L'A' + 1) && (KeyData->Key.UnicodeChar <= L'Z' - L'A' + 1)) { + ControlIndex = KeyData->Key.UnicodeChar; + } else if ((KeyData->Key.UnicodeChar >= L'a' - L'a' + 1) && (KeyData->Key.UnicodeChar <= L'z' - L'z' + 1)) { + ControlIndex = KeyData->Key.UnicodeChar; } } diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c index 51e4ae2f81..5943d57a59 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c @@ -146,15 +146,17 @@ HMainCommandDisplayHelp ( if (KeyData.Key.UnicodeChar == L'W' - L'A' + 1) { break; } - } else if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) && - ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) && - ((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0)) - { + } else if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) + && ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) + && ((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0)) { // // For consoles that supports/reports shift state, // make sure that only CONTROL shift key is pressed. + // For some consoles that report shift state, + // CTRL+W is still translated to L'W' - L'A' + 1. // - if ((KeyData.Key.UnicodeChar == 'w') || (KeyData.Key.UnicodeChar == 'W')) { + if ((KeyData.Key.UnicodeChar == 'w') || (KeyData.Key.UnicodeChar == 'W') + || (KeyData.Key.UnicodeChar == L'w' - L'a' + 1) || (KeyData.Key.UnicodeChar == L'W' - L'A' + 1)) { break; } } From e3d661a53323a3090c4197ea8d29afdf641889bd Mon Sep 17 00:00:00 2001 From: Goldfish64 Date: Thu, 16 Dec 2021 17:30:58 +0300 Subject: [PATCH 004/341] OvmfPkg/SioBusDxe: Add PS/2 mouse support SioBusDxe by default does not create a device for PS/2 mice, this patch adds that device. --- OvmfPkg/SioBusDxe/SioService.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/SioBusDxe/SioService.c b/OvmfPkg/SioBusDxe/SioService.c index 66c5a08cf9..b22bf4f14e 100644 --- a/OvmfPkg/SioBusDxe/SioService.c +++ b/OvmfPkg/SioBusDxe/SioService.c @@ -72,8 +72,13 @@ SIO_DEVICE_INFO mDevicesInfo[] = { { EISA_PNP_ID (0x303), 0, - { (ACPI_SMALL_RESOURCE_HEADER *)&mPs2KeyboardDeviceResources } - } // PS/2 Keyboard Controller + { (ACPI_SMALL_RESOURCE_HEADER *) &mPs2KeyboardDeviceResources } + }, // PS/2 Keyboard Controller + { + EISA_PNP_ID(0xF13), + 0, + { (ACPI_SMALL_RESOURCE_HEADER *) &mPs2KeyboardDeviceResources } + } // PS/2 Mouse Controller }; // From c46ec15ff39ba3f1ca772c954bbc473ee301601c Mon Sep 17 00:00:00 2001 From: Vitaly Cheptsov Date: Sun, 13 Feb 2022 07:59:46 +0300 Subject: [PATCH 005/341] BaseTools: Allow .text relocations in CLANGDWARF toolchain UefiCpuPkg modules like ExceptionHandlerAsm.nasm require relocations to .text or PIC as they use instructions like mov or bt against external symbols: 1. mov rax, ASM_PFX(CommonInterruptEntry) 2. mov rax, HookAfterStubHeaderEnd 3. bt [ASM_PFX(mErrorCodeFlag)], ecx 4. mov [rcx + (@VectorNum - HookAfterStubHeaderBegin)], al It is not easily possible to rewrite 3/4 cases without involving more registers or more commands, and EDK II has never targeted read-only .text at load time, only at runtime. Change the defaults to let OVMF compile by CLANGDWARF as per: https://lists.llvm.org/pipermail/llvm-dev/2017-March/111441.html Signed-off-by: Vitaly Cheptsov --- BaseTools/Conf/tools_def.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index ffeb227421..95bb797863 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -2030,7 +2030,7 @@ DEFINE CLANGDWARF_X64_PREFIX = ENV(CLANG_BIN) # LLVM/CLANG doesn't support -n link option. So, it can't share the same IA32_X64_DLINK_COMMON flag. # LLVM/CLANG doesn't support common page size. So, it can't share the same GccBase.lds script. -DEFINE CLANGDWARF_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-q,--gc-sections -z common-page-size=0x40 +DEFINE CLANGDWARF_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-q,--gc-sections -z common-page-size=0x40 -Wl,-z,notext DEFINE CLANGDWARF_DLINK2_FLAGS_COMMON = -Wl,--script=$(EDK_TOOLS_PATH)/Scripts/GccBase.lds DEFINE CLANGDWARF_IA32_X64_ASLDLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0 DEF(CLANGDWARF_DLINK2_FLAGS_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable DEFINE CLANGDWARF_IA32_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive -Wl,-z,notext From 0c8a45ff10d85d551e36cccb73000f453dc3d562 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Thu, 24 Feb 2022 18:01:11 +0600 Subject: [PATCH 006/341] UefiPayloadPkg/PchSmiDispatchSmm: Add missing EFIAPI modifiers Added missing EFIAPI modifier to SmmSwDispatcher function which passed into gSmst->SmiHandlerRegister routine. Signed-off-by: Savva Mitrofanov Reviewed-by: Vitaly Cheptsov --- UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c b/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c index 8a076e16e6..4b52daa885 100644 --- a/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c +++ b/UefiPayloadPkg/PchSmiDispatchSmm/PchSmiDispatchSmm.c @@ -87,6 +87,7 @@ FindContextByDispatchHandle ( **/ EFI_STATUS +EFIAPI SmmSwDispatcher ( IN EFI_HANDLE DispatchHandle, IN CONST VOID *RegisterContext, @@ -436,7 +437,7 @@ PchSmiDispatchEntryPoint ( // // Register a SMM handler to handle subsequent SW SMIs. // - Status = gSmst->SmiHandlerRegister ((EFI_MM_HANDLER_ENTRY_POINT)SmmSwDispatcher, NULL, &DispatchHandle); + Status = gSmst->SmiHandlerRegister (SmmSwDispatcher, NULL, &DispatchHandle); ASSERT_EFI_ERROR (Status); // From 94327aacda6585fbf2c747bfc861cd297d7a0eb5 Mon Sep 17 00:00:00 2001 From: Vitaly Cheptsov Date: Sat, 5 Mar 2022 19:28:53 +0300 Subject: [PATCH 007/341] OvmfPkg/DxePciLibI440FxQ34: Add UefiBootServicesTableLib dependency In case PlatformBootManagerLib does not have PciLib dependency, we need to explicitly depend on UefiBootServicesTableLib. Otherwise UefiBootServicesTableLib may not be constructed before DxePciLibI440FxQ35, which uses a constructor-less PcdLib that directly accesses gBS. This can be viewed as a bug in the current implementation of BaseTools, namely GetModuleLibInstances. This function drops all constructor-less dependencies from the dependency resolution list to avoid dependency cycles, which at the same time causes issues like above. To properly fix the issue one should go over each library with constructors and for each its dependency without constructors add all the secondary dependencies that do have constructors. While doable, it may cause considerable performance issues and is thus not done in this patch. Signed-off-by: Vitaly Cheptsov --- OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf | 1 + 1 file changed, 1 insertion(+) diff --git a/OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf b/OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf index 4a8c0bac23..a9b712afb8 100644 --- a/OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf +++ b/OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf @@ -35,6 +35,7 @@ PcdLib PciCf8Lib PciExpressLib + UefiBootServicesTableLib [Pcd] gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId From 99b9591ef8ee905a4ca9da99111f46b6291c8d31 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Wed, 24 Aug 2022 21:39:00 +0600 Subject: [PATCH 008/341] MdePkg/BasePcdLibNull: Remove ASSERT from LibPcdGetSize, LibPcdGetExSize GetSize routines should return zero size when checking Token existence Signed-off-by: Savva Mitrofanov Reviewed-by: Vitaly Cheptsov --- MdePkg/Library/BasePcdLibNull/PcdLib.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/MdePkg/Library/BasePcdLibNull/PcdLib.c b/MdePkg/Library/BasePcdLibNull/PcdLib.c index a214371c3f..04170a73a3 100644 --- a/MdePkg/Library/BasePcdLibNull/PcdLib.c +++ b/MdePkg/Library/BasePcdLibNull/PcdLib.c @@ -174,8 +174,6 @@ LibPcdGetSize ( IN UINTN TokenNumber ) { - ASSERT (FALSE); - return 0; } @@ -353,8 +351,6 @@ LibPcdGetExSize ( IN UINTN TokenNumber ) { - ASSERT (FALSE); - return 0; } From 1f14fe27a543d3d2bf6e22017d0dbc93b6117c47 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Wed, 26 Oct 2022 00:00:46 +0600 Subject: [PATCH 009/341] RedfishPkg/BaseUcs2Utf8Lib: Fix out of bounds shift in UTF8ToUCS2Char MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Missing masks leads to shift out of bounds. Also there is no need to construct CHAR16 using cast to CHAR8 buffer, better to use native endian by assigning data directly into Ucs2Char variable Signed-off-by: Savva Mitrofanov Reviewed-by: Marvin Häuser --- .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c b/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c index 42839f5139..03356e2446 100644 --- a/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c +++ b/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c @@ -173,14 +173,12 @@ UTF8ToUCS2Char ( ) { UINT8 Utf8Size; - CHAR8 *Ucs2Buffer; CHAR8 TempChar1; CHAR8 TempChar2; CHAR8 TempChar3; ASSERT (Utf8Buffer != NULL && Ucs2Char != NULL); - ZeroMem (Ucs2Char, sizeof (CHAR16)); - Ucs2Buffer = (CHAR8 *)Ucs2Char; + *Ucs2Char = 0; Utf8Size = GetUTF8SizeForUCS2 (Utf8Buffer); switch (Utf8Size) { @@ -194,8 +192,7 @@ UTF8ToUCS2Char ( return EFI_INVALID_PARAMETER; } - *Ucs2Buffer = TempChar1; - *(Ucs2Buffer + 1) = 0; + *Ucs2Char = (CHAR16)TempChar1; break; case 2: @@ -213,8 +210,7 @@ UTF8ToUCS2Char ( return EFI_INVALID_PARAMETER; } - *Ucs2Buffer = (TempChar1 << 6) + (TempChar2 & 0x3F); - *(Ucs2Buffer + 1) = (TempChar1 >> 2) & 0x07; + *Ucs2Char = (TempChar1 & 0x1F) << 6 | (TempChar2 & 0x3F); break; case 3: @@ -237,9 +233,7 @@ UTF8ToUCS2Char ( return EFI_INVALID_PARAMETER; } - *Ucs2Buffer = (TempChar2 << 6) + (TempChar3 & 0x3F); - *(Ucs2Buffer + 1) = (TempChar1 << 4) + ((TempChar2 >> 2) & 0x0F); - + *Ucs2Char = (TempChar1 & 0x0F) << 12 | (TempChar2 & 0x3F) << 6 | (TempChar3 & 0x3F); break; default: From 26f032adb2933b10eb58a748ba677cb17946b4d1 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Fri, 9 Dec 2022 16:46:50 +0600 Subject: [PATCH 010/341] UefiCpuPkg/CpuExceptionHandlerLib: Increase mBuffer size Add missing GDT alignment into mBuffer to prevent possible memory corruption on ALIGN_POINTER operation on NewGdtTable in ArchExceptionHandler Signed-off-by: Savva Mitrofanov --- UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c index ee989bf079..d4e9979c92 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c @@ -24,7 +24,7 @@ EXCEPTION_HANDLER_DATA mExceptionHandlerData = { }; UINT8 mBuffer[CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_STACK_SIZE - + CPU_TSS_GDT_SIZE]; + + sizeof (IA32_TSS_DESCRIPTOR) + CPU_TSS_GDT_SIZE]; /** Common exception handler. From faeb23843b28d30245382b592bfe214aa7afe4ed Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 22 Jul 2024 12:54:00 +0300 Subject: [PATCH 011/341] MdePkg/X64/ProcessorBind.h: Fixes CLANGDWARF X64 compilation Corrects typedef redefinition, in particular for openssl e_os2.h Signed-off-by: Savva Mitrofanov --- MdePkg/Include/Ia32/ProcessorBind.h | 33 ++-------------------------- MdePkg/Include/X64/ProcessorBind.h | 34 ++++++++++------------------- 2 files changed, 13 insertions(+), 54 deletions(-) diff --git a/MdePkg/Include/Ia32/ProcessorBind.h b/MdePkg/Include/Ia32/ProcessorBind.h index 62ca7f8607..c7d58e3803 100644 --- a/MdePkg/Include/Ia32/ProcessorBind.h +++ b/MdePkg/Include/Ia32/ProcessorBind.h @@ -126,36 +126,6 @@ typedef unsigned __int32 UINT32; /// 4-byte signed value. /// typedef __int32 INT32; -/// -/// 2-byte unsigned value. -/// -typedef unsigned short UINT16; -/// -/// 2-byte Character. Unless otherwise specified all strings are stored in the -/// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards. -/// -typedef unsigned short CHAR16; -/// -/// 2-byte signed value. -/// -typedef short INT16; -/// -/// Logical Boolean. 1-byte value containing 0 for FALSE or a 1 for TRUE. Other -/// values are undefined. -/// -typedef unsigned char BOOLEAN; -/// -/// 1-byte unsigned value. -/// -typedef unsigned char UINT8; -/// -/// 1-byte Character. -/// -typedef char CHAR8; -/// -/// 1-byte signed value. -/// -typedef signed char INT8; #else /// /// 8-byte unsigned value. @@ -173,6 +143,8 @@ typedef unsigned int UINT32; /// 4-byte signed value. /// typedef int INT32; +#endif + /// /// 2-byte unsigned value. /// @@ -203,7 +175,6 @@ typedef char CHAR8; /// 1-byte signed value /// typedef signed char INT8; -#endif /// /// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions; diff --git a/MdePkg/Include/X64/ProcessorBind.h b/MdePkg/Include/X64/ProcessorBind.h index bc152ea761..c2bac12103 100644 --- a/MdePkg/Include/X64/ProcessorBind.h +++ b/MdePkg/Include/X64/ProcessorBind.h @@ -125,36 +125,23 @@ typedef unsigned __int32 UINT32; /// 4-byte signed value /// typedef __int32 INT32; +#elif defined (__clang__) /// -/// 2-byte unsigned value -/// -typedef unsigned short UINT16; -/// -/// 2-byte Character. Unless otherwise specified all strings are stored in the -/// UTF-16 encoding format as defined by Unicode 2.1 and ISO/IEC 10646 standards. -/// -typedef unsigned short CHAR16; -/// -/// 2-byte signed value -/// -typedef short INT16; -/// -/// Logical Boolean. 1-byte value containing 0 for FALSE or a 1 for TRUE. Other -/// values are undefined. +/// 8-byte unsigned value /// -typedef unsigned char BOOLEAN; +typedef __UINT64_TYPE__ UINT64; /// -/// 1-byte unsigned value +/// 8-byte signed value /// -typedef unsigned char UINT8; +typedef __INT64_TYPE__ INT64; /// -/// 1-byte Character +/// 4-byte unsigned value /// -typedef char CHAR8; +typedef unsigned int UINT32; /// -/// 1-byte signed value +/// 4-byte signed value /// -typedef signed char INT8; +typedef signed int INT32; #else /// /// 8-byte unsigned value @@ -172,6 +159,8 @@ typedef unsigned int UINT32; /// 4-byte signed value /// typedef int INT32; +#endif + /// /// 2-byte unsigned value /// @@ -202,7 +191,6 @@ typedef char CHAR8; /// 1-byte signed value /// typedef signed char INT8; -#endif /// /// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions, From 7a0cf5389b9f4aa69d6a1861540db54a5e584e90 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 20 Apr 2023 10:32:49 +0300 Subject: [PATCH 012/341] Build: Fixed missing HII for X64, IA32 CLANGDWARF DEBUG, NOOPT. --- BaseTools/Conf/build_rule.template | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template index 0f32cc398e..116cd29da7 100755 --- a/BaseTools/Conf/build_rule.template +++ b/BaseTools/Conf/build_rule.template @@ -663,7 +663,7 @@ *.hpk - + $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.lib @@ -673,8 +673,9 @@ "$(GENFW)" -o $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc -g $(MODULE_GUID) --hiipackage $(HII_BINARY_PACKAGES) $(GENFW_FLAGS) "$(RC)" /Fo${dst} $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc - + "$(GENFW)" -o $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc -g $(MODULE_GUID) --hiibinpackage $(HII_BINARY_PACKAGES) $(GENFW_FLAGS) "$(RC)" $(RC_FLAGS) $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc ${dst} + "$(GENFW)" -o $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc -g $(MODULE_GUID) --hiibinpackage $(HII_BINARY_PACKAGES) $(GENFW_FLAGS) From 7c5ce259d965362d7a6b884ba97a475e93203a11 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Fri, 23 Dec 2022 16:49:15 +0600 Subject: [PATCH 013/341] .gitignore: Add compile_flags.txt Signed-off-by: Savva Mitrofanov --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 274a66ce80..35c3d03f25 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ __pycache__/ tags/ .vscode/ .venv/ +compile_flags.txt From bef4387f56cf26b03bff202dd469443499fe016f Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Fri, 23 Dec 2022 19:09:27 +0600 Subject: [PATCH 014/341] MdeModulePkg/BrotliCustomDecompressLib: Correct BrotliDecompress We need to pass DestSize as pointer, because we assign this output var to TotalOut value inside BrotliDecompress routine Signed-off-by: Savva Mitrofanov --- .../Library/BrotliCustomDecompressLib/BrotliDecompress.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliDecompress.c b/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliDecompress.c index 3cb31ab984..73c8c1f23d 100644 --- a/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliDecompress.c +++ b/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliDecompress.c @@ -82,7 +82,7 @@ BrotliDecompress ( IN CONST VOID *Source, IN UINTN SourceSize, IN OUT VOID *Destination, - IN OUT UINTN DestSize, + IN OUT UINTN *DestSize, IN VOID *BuffInfo ) { @@ -157,7 +157,7 @@ BrotliDecompress ( CopyMem (Temp, Output, (size_t)(NextOut - Output)); } - DestSize = TotalOut; + *DestSize = TotalOut; BrFree (BuffInfo, Input); BrFree (BuffInfo, Output); @@ -292,7 +292,7 @@ BrotliUefiDecompress ( (VOID *)((UINT8 *)Source + BROTLI_SCRATCH_MAX), SourceSize - BROTLI_SCRATCH_MAX, Destination, - DestSize, + &DestSize, (VOID *)(&BroBuff) ); From 6ae449abe44abfc68d7eededfd5bb7d02fca559f Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Fri, 23 Dec 2022 21:10:16 +0600 Subject: [PATCH 015/341] MdeModulePkg/SmbiosMeasurementDxe: Removes unused local variable Removes unused local variable Size in GetSmbiosStringById Signed-off-by: Savva Mitrofanov --- .../Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c b/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c index 9c7d3906be..5388fe4c28 100644 --- a/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c +++ b/MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.c @@ -218,14 +218,12 @@ GetSmbiosStringById ( OUT UINTN *StringLen ) { - UINTN Size; UINTN StrLen; CHAR8 *CharInStr; UINTN StringsNumber; CHAR8 *String; CharInStr = (CHAR8 *)Head + Head->Length; - Size = Head->Length; StringsNumber = 0; StrLen = 0; // @@ -234,7 +232,6 @@ GetSmbiosStringById ( String = NULL; while (*CharInStr != 0 || *(CharInStr+1) != 0) { if (*CharInStr == 0) { - Size += 1; CharInStr++; } @@ -256,7 +253,6 @@ GetSmbiosStringById ( // forward the pointer // CharInStr += StrLen; - Size += StrLen; StringsNumber += 1; if (StringsNumber == StringId) { break; From e8d34602f0afb9727c0338d4af64666549758622 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Mon, 26 Dec 2022 16:34:27 +0600 Subject: [PATCH 016/341] MdeModulePkg/VarCheckHiiLib: Remove unused variable FfsIndex Corrects compiler warning due to unused variable in VarCheckHiiGenFromFv Signed-off-by: Savva Mitrofanov --- MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c index 562f5a02f6..4363eda115 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiGenFromFv.c @@ -260,7 +260,6 @@ ParseFv ( EFI_GUID NameGuid; EFI_FV_FILE_ATTRIBUTES FileAttributes; UINTN Size; - UINTN FfsIndex; VAR_CHECK_VFR_DRIVER_INFO *VfrDriverInfo; LIST_ENTRY *VfrDriverLink; @@ -315,7 +314,7 @@ ParseFv ( Key = InternalVarCheckAllocateZeroPool (Fv2->KeySize); ASSERT (Key != NULL); - for (FfsIndex = 0; ; FfsIndex++) { + while (TRUE) { FileType = EFI_FV_FILETYPE_ALL; Status = Fv2->GetNextFile ( Fv2, From c8ac8c004a97999be0f5723c2787c7240848ca55 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 28 Apr 2023 14:54:59 +0300 Subject: [PATCH 017/341] MdeModulePkg/RegularExpressionDxe: Corrects onigurama build with LLVM 15 Signed-off-by: Savva Mitrofanov --- .../Universal/RegularExpressionDxe/RegularExpressionDxe.inf | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Universal/RegularExpressionDxe/RegularExpressionDxe.inf b/MdeModulePkg/Universal/RegularExpressionDxe/RegularExpressionDxe.inf index 0092531a67..04149b19c6 100644 --- a/MdeModulePkg/Universal/RegularExpressionDxe/RegularExpressionDxe.inf +++ b/MdeModulePkg/Universal/RegularExpressionDxe/RegularExpressionDxe.inf @@ -125,6 +125,10 @@ # Oniguruma: implicit conversion from 'UINTN' (aka 'unsigned long long') to 'long' GCC:*_CLANGPDB_*_CC_FLAGS = -Wno-error=constant-conversion + # Onigurama: corrects build for llvm-15 + CLANGPDB:*_*_*_CC_FLAGS = -Wno-deprecated-non-prototype + CLANGGCC:*_*_*_CC_FLAGS = -Wno-deprecated-non-prototype + # Not add -Wno-error=maybe-uninitialized option for XCODE # XCODE doesn't know this option - XCODE:*_*_*_CC_FLAGS = + XCODE:*_*_*_CC_FLAGS = -Wno-deprecated-non-prototype From 483518897535a951e0bcd4d2922d473f8c6506fa Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Mon, 26 Dec 2022 17:44:06 +0600 Subject: [PATCH 018/341] NetworkPkg/WifiConnectionManagerDxe: Removes unused variable Removes unused variable in WifiMgrRefreshNetworkList routine to correct build Signed-off-by: Savva Mitrofanov --- .../WifiConnectionMgrHiiConfigAccess.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c index f11270642a..4ce1a044c0 100644 --- a/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c +++ b/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c @@ -390,7 +390,6 @@ WifiMgrRefreshNetworkList ( { EFI_STATUS Status; EFI_TPL OldTpl; - UINT32 AvailableCount; EFI_STRING_ID PortPromptToken; EFI_STRING_ID PortTextToken; EFI_STRING_ID PortHelpToken; @@ -418,7 +417,6 @@ WifiMgrRefreshNetworkList ( } OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - AvailableCount = 0; PortStringSize = sizeof (PortString); ConnectedProfile = NULL; AKMListDisplay = NULL; @@ -433,7 +431,6 @@ WifiMgrRefreshNetworkList ( Private->CurrentNic->CurrentOperateNetwork->IsAvailable) { Profile = Private->CurrentNic->CurrentOperateNetwork; - AvailableCount++; AKMListDisplay = WifiMgrGetStrAKMList (Profile); if (AKMListDisplay == NULL) { @@ -509,7 +506,6 @@ WifiMgrRefreshNetworkList ( } if (Profile->IsAvailable && Profile->CipherSuiteSupported) { - AvailableCount++; AKMListDisplay = WifiMgrGetStrAKMList (Profile); if (AKMListDisplay == NULL) { @@ -598,7 +594,6 @@ WifiMgrRefreshNetworkList ( } if (Profile->IsAvailable && !Profile->CipherSuiteSupported) { - AvailableCount++; AKMListDisplay = WifiMgrGetStrAKMList (Profile); if (AKMListDisplay == NULL) { From 4778567e82ff3d678716778e47dece537f4761ce Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Tue, 27 Dec 2022 17:58:15 +0600 Subject: [PATCH 019/341] MdeModulePkg/CapsuleOnDiskLoadPei: Removes unused Index variable Removes unused Index local variable in RetrieveRelocatedCapsule to suppress compiler warning in LLVM 15 Signed-off-by: Savva Mitrofanov --- .../Universal/CapsuleOnDiskLoadPei/CapsuleOnDiskLoadPei.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/MdeModulePkg/Universal/CapsuleOnDiskLoadPei/CapsuleOnDiskLoadPei.c b/MdeModulePkg/Universal/CapsuleOnDiskLoadPei/CapsuleOnDiskLoadPei.c index 0ea4fb38f9..1bbf38afc4 100644 --- a/MdeModulePkg/Universal/CapsuleOnDiskLoadPei/CapsuleOnDiskLoadPei.c +++ b/MdeModulePkg/Universal/CapsuleOnDiskLoadPei/CapsuleOnDiskLoadPei.c @@ -173,7 +173,6 @@ RetrieveRelocatedCapsule ( IN UINTN RelocCapsuleTotalSize ) { - UINTN Index; UINT8 *CapsuleDataBufEnd; UINT8 *CapsulePtr; UINT32 CapsuleSize; @@ -244,7 +243,6 @@ RetrieveRelocatedCapsule ( // Re-iterate the capsule buffer to create Capsule hob & Capsule Name Str Hob for each Capsule saved in relocated capsule file // CapsulePtr = RelocCapsuleBuf; - Index = 0; while (CapsulePtr < CapsuleDataBufEnd) { CapsuleSize = ((EFI_CAPSULE_HEADER *)CapsulePtr)->CapsuleImageSize; BuildCvHob ((EFI_PHYSICAL_ADDRESS)(UINTN)CapsulePtr, CapsuleSize); @@ -252,7 +250,6 @@ RetrieveRelocatedCapsule ( DEBUG ((DEBUG_INFO, "Capsule saved in address %x size %x\n", CapsulePtr, CapsuleSize)); CapsulePtr += CapsuleSize; - Index++; } return EFI_SUCCESS; From 37c4db9e29e6ff93d8abaf811d163377605df1b1 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 20 Dec 2023 13:37:39 +0300 Subject: [PATCH 020/341] MdeModulePkg/DebugSupportDxe: Adds callback function prototypes in caller Adds EFI_EXCEPTION_CALLBACK and EFI_PERIODIC_CALLBACK casts to RegisteredCallback call in InterruptDistributionHub to suppress deprecated non-prototype LLVM 15 warning Signed-off-by: Savva Mitrofanov --- MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c index 40fe74d8c2..129eee6b2c 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c @@ -268,10 +268,10 @@ InterruptDistrubutionHub ( { if (IdtEntryTable[ExceptionType].RegisteredCallback != NULL) { if (ExceptionType != SYSTEM_TIMER_VECTOR) { - IdtEntryTable[ExceptionType].RegisteredCallback (ExceptionType, ContextRecord); + ((EFI_EXCEPTION_CALLBACK)(IdtEntryTable[ExceptionType].RegisteredCallback))(ExceptionType, *(EFI_SYSTEM_CONTEXT *) &ContextRecord); } else { OrigVector = IdtEntryTable[ExceptionType].OrigVector; - IdtEntryTable[ExceptionType].RegisteredCallback (ContextRecord); + ((EFI_PERIODIC_CALLBACK)(IdtEntryTable[ExceptionType].RegisteredCallback))(*(EFI_SYSTEM_CONTEXT *) &ContextRecord); } } } From 09a0c067d09c1cb6be396eaa0107f2b793feb437 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 7 Apr 2025 12:12:35 +0300 Subject: [PATCH 021/341] SecurePE: Replaced old PE loader with Secure one. --- ArmPkg/ArmPkg.dsc | 8 +- .../ArmCrashDumpDxe/ArmCrashDumpDxe.dsc | 1 - ArmPkg/Drivers/CpuDxe/CpuDxe.h | 1 - ArmPkg/Drivers/CpuDxe/CpuDxe.inf | 1 - .../Library/ArmStandaloneMmCoreEntryPoint.h | 56 +- .../ArmStandaloneMmCoreEntryPoint.c | 75 +- .../ArmStandaloneMmCoreEntryPoint.inf | 8 +- .../SetPermissions.c | 323 +----- .../DebugAgentSymbolsBaseLib.c | 91 +- .../DebugAgentSymbolsBaseLib.inf | 4 +- .../DebugUefiImageExtraActionLib.c | 141 +++ .../DebugUefiImageExtraActionLib.inf | 33 + .../AArch64/DefaultExceptionHandler.c | 27 +- .../Arm/DefaultExceptionHandler.c | 22 +- .../DefaultExceptionHandlerLib.inf | 1 - .../DefaultExceptionHandlerUefi.c | 10 +- ArmPlatformPkg/ArmPlatformPkg.dsc | 5 +- ArmVirtPkg/ArmVirt.dsc.inc | 10 +- ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S | 3 +- ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S | 3 +- .../PrePi/ArmVirtPrePiUniCoreRelocatable.inf | 2 +- ArmVirtPkg/PrePi/PrePi.c | 33 +- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 217 +++- BaseTools/Source/C/GenFv/GenFvInternalLib.h | 3 +- BaseTools/Source/Python/build/build.py | 23 +- EmbeddedPkg/EmbeddedPkg.dec | 1 - EmbeddedPkg/EmbeddedPkg.dsc | 6 +- EmbeddedPkg/GdbStub/GdbStub.c | 170 +--- EmbeddedPkg/GdbStub/GdbStubInternal.h | 2 +- EmbeddedPkg/Include/Library/PrePiLib.h | 17 +- EmbeddedPkg/Library/PrePiHobLib/Hob.c | 24 +- EmbeddedPkg/Library/PrePiLib/FwVol.c | 32 +- EmbeddedPkg/Library/PrePiLib/PrePi.h | 2 +- EmbeddedPkg/Library/PrePiLib/PrePiLib.c | 71 +- EmbeddedPkg/Library/PrePiLib/PrePiLib.inf | 5 +- EmulatorPkg/EmulatorPkg.dsc | 18 +- EmulatorPkg/Include/Library/EmuMagicPageLib.h | 2 +- EmulatorPkg/Include/Protocol/EmuThunk.h | 17 +- .../DxeEmuPeCoffExtraActionLib.c | 11 +- .../DxeEmuUefiImageExtraActionLib.c | 94 ++ .../DxeEmuUefiImageExtraActionLib.inf | 42 + .../PeiEmuPeCoffExtraActionLib.c | 34 +- .../PeiEmuPeCoffGetEntryPointLib.c | 9 +- .../PeiEmuUefiImageExtraActionLib.c | 101 ++ .../PeiEmuUefiImageExtraActionLib.inf | 43 + EmulatorPkg/Library/SecPeiServicesLib/FwVol.c | 49 + .../SecPeiServicesLib/PeiServicesLib.c | 40 + EmulatorPkg/Sec/Sec.c | 56 +- EmulatorPkg/Sec/Sec.h | 1 - EmulatorPkg/Sec/Sec.inf | 1 - EmulatorPkg/Unix/GdbRun.sh | 2 +- EmulatorPkg/Unix/Host/EmuThunk.c | 6 +- EmulatorPkg/Unix/Host/Gasket.h | 11 +- EmulatorPkg/Unix/Host/Host.c | 337 ++----- EmulatorPkg/Unix/Host/Host.h | 37 +- EmulatorPkg/Unix/Host/Host.inf | 3 +- EmulatorPkg/Unix/Host/Ia32/Gasket.S | 22 +- EmulatorPkg/Unix/Host/X64/Gasket.S | 19 +- EmulatorPkg/Unix/lldbefi.py | 4 +- EmulatorPkg/Win/Host/WinHost.c | 74 +- EmulatorPkg/Win/Host/WinHost.h | 12 +- EmulatorPkg/Win/Host/WinHost.inf | 2 +- EmulatorPkg/Win/Host/WinThunk.c | 6 +- IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc | 6 +- .../FspWrapperNotifyDxe.inf | 3 +- .../FspWrapperNotifyDxe/LoadBelow4G.c | 68 +- .../FspmWrapperPeim/FspmWrapperPeim.inf | 4 +- .../FspsWrapperPeim/FspsWrapperPeim.inf | 4 +- IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc | 6 +- LoaderFlow.png | Bin 0 -> 218450 bytes MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h | 2 +- MdeModulePkg/Core/Dxe/DxeMain.h | 34 +- MdeModulePkg/Core/Dxe/DxeMain.inf | 5 +- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 40 +- MdeModulePkg/Core/Dxe/Image/Image.c | 635 ++++++------ MdeModulePkg/Core/Dxe/Mem/HeapGuard.c | 2 +- .../Core/Dxe/Mem/MemoryProfileRecord.c | 252 +---- MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c | 72 +- .../Core/Dxe/Misc/MemoryAttributesTable.c | 210 ++-- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 269 +++-- MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 120 ++- MdeModulePkg/Core/Pei/FwVol/FwVol.c | 104 +- MdeModulePkg/Core/Pei/FwVol/FwVol.h | 37 + MdeModulePkg/Core/Pei/Image/Image.c | 487 +++------ MdeModulePkg/Core/Pei/PeiMain.h | 45 +- MdeModulePkg/Core/Pei/PeiMain.inf | 3 +- MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 1 + MdeModulePkg/Core/Pei/Ppi/Ppi.c | 25 +- MdeModulePkg/Core/PiSmmCore/DebugImageInfo.c | 153 +++ MdeModulePkg/Core/PiSmmCore/Dispatcher.c | 329 +++--- .../PiSmmCore/MemoryAllocation.c} | 3 +- .../Core/PiSmmCore/MemoryAttributesTable.c | 255 ++--- MdeModulePkg/Core/PiSmmCore/PiSmmCore.c | 23 +- MdeModulePkg/Core/PiSmmCore/PiSmmCore.h | 62 +- MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf | 7 +- .../Core/PiSmmCore/PiSmmCorePrivateData.h | 4 +- MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c | 189 ++-- MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf | 2 +- .../Core/PiSmmCore/SmiHandlerProfile.c | 20 +- .../Core/PiSmmCore/SmramProfileRecord.c | 273 ++--- MdeModulePkg/Core/RuntimeDxe/Runtime.c | 8 +- MdeModulePkg/Core/RuntimeDxe/Runtime.h | 2 +- MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf | 2 +- MdeModulePkg/Include/Guid/MemoryProfile.h | 5 +- .../Library/ImagePropertiesRecordLib.h | 158 +-- .../DxeCorePerformanceLib.c | 9 +- .../DxeCorePerformanceLib.inf | 1 - .../DxeCorePerformanceLibInternal.h | 1 - .../ImagePropertiesRecordLib.c | 810 ++------------- .../ImagePropertiesRecordLib.inf | 2 +- .../PiSmmCoreMemoryAllocationLib.inf | 5 +- .../PiSmmCoreMemoryAllocationProfileLib.inf | 6 +- .../PiSmmCoreMemoryAllocationServices.h | 185 ---- .../SmmCorePerformanceLib.c | 11 +- .../SmmCorePerformanceLib.inf | 1 - .../SmmCorePerformanceLibInternal.h | 1 - .../Library/UefiBootManagerLib/BmLoadOption.c | 103 +- .../Library/UefiBootManagerLib/InternalBm.h | 3 +- .../UefiBootManagerLib/UefiBootManagerLib.inf | 1 - MdeModulePkg/MdeModulePkg.dec | 4 +- MdeModulePkg/MdeModulePkg.dsc | 6 +- .../BootScriptExecutorDxe.inf | 3 +- .../BootScriptExecutorDxe/ScriptExecute.c | 72 +- .../BootScriptExecutorDxe/ScriptExecute.h | 3 +- MdeModulePkg/Universal/CapsulePei/Capsule.h | 5 +- .../Universal/CapsulePei/CapsulePei.inf | 1 - .../Universal/CapsulePei/UefiCapsule.c | 4 +- MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf | 1 - .../Universal/EbcDxe/EbcDebugger/EdbSymbol.c | 117 +-- MdeModulePkg/Universal/EbcDxe/EbcDxe.inf | 1 - MdeModulePkg/Universal/EbcDxe/EbcInt.c | 21 - MdeModulePkg/Universal/EbcDxe/EbcInt.h | 3 +- MdePkg/Include/Guid/DebugImageInfoTable.h | 1 + MdePkg/Include/Guid/WinCertificate.h | 13 +- MdePkg/Include/IndustryStandard/PeImage.h | 72 +- MdePkg/Include/IndustryStandard/PeImage2.h | 761 ++++++++++++++ MdePkg/Include/Library/PeCoffExtraActionLib.h | 4 + MdePkg/Include/Library/PeCoffLib.h | 75 +- MdePkg/Include/Library/PeCoffLib2.h | 597 +++++++++++ MdePkg/Include/Library/PeiServicesLib.h | 26 + .../Include/Library/UefiImageExtraActionLib.h | 47 + MdePkg/Include/Library/UefiImageLib.h | 642 ++++++++++++ MdePkg/Include/Pi/PiPeiCis.h | 35 + MdePkg/Include/Ppi/FirmwareVolume.h | 38 +- MdePkg/Include/Protocol/DebugSupport.h | 14 +- MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 2 +- .../BasePeCoffLib/BasePeCoffLibInternals.h | 31 +- MdePkg/Library/BasePeCoffLib/PeCoffLoad.h | 50 + .../Library/BasePeCoffLib2/BasePeCoffLib2.inf | 47 + .../BasePeCoffLib2/BasePeCoffLib2Internals.h | 55 + .../Library/BasePeCoffLib2/Documentation.md | 40 + MdePkg/Library/BasePeCoffLib2/PeCoffDebug.c | 264 +++++ MdePkg/Library/BasePeCoffLib2/PeCoffHash.c | 487 +++++++++ MdePkg/Library/BasePeCoffLib2/PeCoffHii.c | 286 ++++++ MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c | 152 +++ MdePkg/Library/BasePeCoffLib2/PeCoffInit.c | 896 +++++++++++++++++ MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c | 259 +++++ .../Library/BasePeCoffLib2/PeCoffRelocate.c | 938 ++++++++++++++++++ .../BaseUefiImageExtraActionLibNull.inf | 33 + .../UefiImageExtraActionLib.c | 48 + .../UefiImageExtraActionLibNull.uni | 16 + .../BaseUefiImageLibPeCoff.inf | 40 + .../Library/BaseUefiImageLib/CommonSupport.c | 152 +++ .../BaseUefiImageLib/ExecutionSupport.c | 113 +++ .../Library/BaseUefiImageLib/PeCoffSupport.c | 511 ++++++++++ .../Library/BaseUefiImageLib/PeCoffSupport.h | 37 + .../BaseUefiImageLib/UefiImageLibPeCoff.c | 299 ++++++ .../Library/PeiServicesLib/PeiServicesLib.c | 32 + MdePkg/MdeLibs.dsc.inc | 1 + MdePkg/MdePkg.dec | 67 +- MdePkg/MdePkg.dsc | 6 +- NetworkPkg/NetworkPkg.dsc | 7 +- OvmfPkg/AmdSev/AmdSevX64.dsc | 16 +- OvmfPkg/Bhyve/BhyveX64.dsc | 16 +- .../CompatImageLoaderDxe.c | 1 - .../CompatImageLoaderDxe.inf | 1 - OvmfPkg/IntelTdx/IntelTdxX64.dsc | 35 +- OvmfPkg/IntelTdx/Sec/SecMain.c | 2 - OvmfPkg/IntelTdx/Sec/SecMain.inf | 3 - OvmfPkg/Library/PeilessStartupLib/DxeLoad.c | 12 +- .../PlatformBootManagerLib/BdsPlatform.h | 2 +- .../PlatformBootManagerLibBhyve/BdsPlatform.h | 2 +- OvmfPkg/OvmfPkgIa32.dsc | 35 +- OvmfPkg/OvmfPkgIa32X64.dsc | 53 +- OvmfPkg/OvmfPkgIa32X64.fdf | 2 +- OvmfPkg/OvmfPkgX64.dsc | 33 +- OvmfPkg/OvmfXen.dsc | 16 +- OvmfPkg/Sec/SecMain.c | 60 +- OvmfPkg/Sec/SecMain.inf | 5 +- OvmfPkg/Tcg/TdTcg2Dxe/MeasureBootPeCoff.c | 82 +- OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf | 2 +- README.md | 71 ++ .../DeviceSecurity/SpdmLib/SpdmCryptLib.inf | 5 + .../SpdmSecurityLib/SpdmAuthentication.c | 12 +- .../SpdmSecurityLib/SpdmConnectionInit.c | 20 +- .../SpdmSecurityLib/SpdmMeasurement.c | 8 +- .../DxeImageVerificationLib.c | 671 +++---------- .../DxeImageVerificationLib.h | 18 +- .../DxeImageVerificationLib.inf | 6 +- .../DxeTpm2MeasureBootLib.c | 93 +- .../DxeTpm2MeasureBootLib.inf | 2 +- .../DxeTpmMeasureBootLib.c | 353 +------ .../DxeTpmMeasureBootLib.inf | 2 +- .../HashInstanceLibSha1/HashInstanceLibSha1.c | 17 +- .../HashInstanceLibSha256.c | 15 +- .../HashInstanceLibSha384.c | 10 +- .../HashInstanceLibSha512.c | 17 +- .../HashInstanceLibSm3/HashInstanceLibSm3.c | 13 +- .../HashLibBaseCryptoRouterDxe.c | 4 +- SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c | 12 +- SecurityPkg/SecurityPkg.dsc | 8 +- SecurityPkg/Tcg/Tcg2Dxe/MeasureBootPeCoff.c | 408 -------- .../Tcg/Tcg2Dxe/MeasureBootUefiImage.c | 111 +++ SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c | 10 +- SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf | 4 +- SecurityPkg/Tcg/TcgDxe/TcgDxe.c | 2 +- .../SecureBootConfigDxe.inf | 2 +- .../SecureBootConfigImpl.c | 566 +++-------- .../SecureBootConfigImpl.h | 13 +- .../DynamicCommand/DpDynamicCommand/DpApp.inf | 1 - .../DpDynamicCommand/DpDynamicCommand.inf | 2 +- .../DpDynamicCommand/DpInternal.h | 4 +- .../DynamicCommand/DpDynamicCommand/DpTrace.c | 2 +- .../DpDynamicCommand/DpUtilities.c | 46 +- .../UefiHandleParsingLib.c | 4 +- .../UefiHandleParsingLib.h | 2 +- .../UefiHandleParsingLib.inf | 1 - .../UefiShellDebug1CommandsLib/LoadPciRom.c | 2 +- .../UefiShellDriver1CommandsLib.h | 2 +- .../UefiShellDriver1CommandsLib.inf | 1 - ShellPkg/ShellPkg.dsc | 1 - SignedCapsulePkg/SignedCapsulePkg.dsc | 6 +- .../DebugAgent/DebugAgentCommon/DebugAgent.c | 27 +- .../DebugAgent/DebugAgentCommon/DebugAgent.h | 14 +- .../DxeDebugAgent/DxeDebugAgentLib.c | 2 - .../Library/DebugAgent/DxeDebugAgentLib.inf | 3 +- .../SecPeiDebugAgent/SecPeiDebugAgentLib.c | 8 +- .../DebugAgent/SecPeiDebugAgentLib.inf | 3 +- .../SmmDebugAgent/SmmDebugAgentLib.c | 8 - .../Library/DebugAgent/SmmDebugAgentLib.inf | 3 +- .../Ia32/IntHandler.nasm | 4 + .../PeCoffExtraActionLib.c | 55 +- .../X64/IntHandler.nasm | 4 + .../Ia32/IntHandler.nasm | 22 + .../Ia32/IntHandlerFuncs.c | 93 ++ .../UefiImageExtraActionLib.c | 241 +++++ .../UefiImageExtraActionLib.h | 72 ++ .../UefiImageExtraActionLib.uni | 15 + .../UefiImageExtraActionLibDebug.inf | 50 + .../X64/IntHandler.nasm | 23 + .../X64/IntHandlerFuncs.c | 95 ++ SourceLevelDebugPkg/SourceLevelDebugPkg.dec | 2 +- SourceLevelDebugPkg/SourceLevelDebugPkg.dsc | 6 +- SourceLevelDebugPkg/SourceLevelDebugPkg.uni | 4 +- StandaloneMmPkg/Core/Dispatcher.c | 194 ++-- StandaloneMmPkg/Core/FwVol.c | 8 +- StandaloneMmPkg/Core/StandaloneMmCore.h | 5 +- StandaloneMmPkg/Core/StandaloneMmCore.inf | 12 +- StandaloneMmPkg/Include/Library/FvLib.h | 2 +- .../Library/StandaloneMmProtectionLib.h | 30 + StandaloneMmPkg/Library/FvLib/FvLib.c | 2 +- .../ProtectionAarch64.c | 41 + .../ProtectionNull.c | 49 + .../StandaloneMmProtectionLib.inf | 29 + StandaloneMmPkg/StandaloneMmPkg.dec | 3 + StandaloneMmPkg/StandaloneMmPkg.dsc | 8 +- UefiCpuPkg/CpuDxe/CpuPageTable.c | 2 +- UefiCpuPkg/CpuDxe/CpuPageTable.h | 2 +- .../CpuExceptionCommon.c | 26 +- .../CpuExceptionCommon.h | 12 +- .../DxeCpuExceptionHandlerLib.inf | 4 +- .../CpuExceptionHandlerLib/DxeException.c | 52 + .../CpuExceptionHandlerLib/PeiCpuException.c | 24 + .../PeiCpuExceptionHandlerLib.inf | 2 +- .../SecPeiCpuException.c | 10 + .../SecPeiCpuExceptionHandlerLib.inf | 2 +- .../SmmCpuExceptionHandlerLib.inf | 4 +- .../CpuExceptionHandlerLib/SmmException.c | 76 ++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c | 14 - UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 2 +- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 58 ++ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf | 2 +- .../PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf | 1 - UefiCpuPkg/SecCore/FindPeiCore.c | 64 +- UefiCpuPkg/SecCore/SecCore.inf | 4 +- UefiCpuPkg/SecCore/SecMain.h | 5 +- UefiCpuPkg/UefiCpuPkg.dec | 2 +- UefiCpuPkg/UefiCpuPkg.dsc | 5 +- .../MemoryAllocation.c | 0 .../UefiPayloadEntryMemoryAllocationLib.inf | 27 + UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c | 97 +- .../UefiPayloadEntry/UefiPayloadEntry.h | 7 +- .../UefiPayloadEntry/UefiPayloadEntry.inf | 4 +- .../UefiPayloadEntry/UniversalPayloadEntry.c | 3 +- .../UniversalPayloadEntry.inf | 2 +- UefiPayloadPkg/UefiPayloadPkg.dsc | 9 +- 296 files changed, 12462 insertions(+), 7109 deletions(-) create mode 100644 ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.c create mode 100644 ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.inf mode change 100755 => 100644 ArmVirtPkg/PrePi/PrePi.c create mode 100644 EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.c create mode 100644 EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.inf create mode 100644 EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.c create mode 100644 EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.inf mode change 100755 => 100644 EmulatorPkg/Unix/lldbefi.py create mode 100644 LoaderFlow.png create mode 100644 MdeModulePkg/Core/PiSmmCore/DebugImageInfo.c rename MdeModulePkg/{Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c => Core/PiSmmCore/MemoryAllocation.c} (96%) delete mode 100644 MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationServices.h create mode 100644 MdePkg/Include/IndustryStandard/PeImage2.h create mode 100644 MdePkg/Include/Library/PeCoffLib2.h create mode 100644 MdePkg/Include/Library/UefiImageExtraActionLib.h create mode 100644 MdePkg/Include/Library/UefiImageLib.h create mode 100644 MdePkg/Library/BasePeCoffLib/PeCoffLoad.h create mode 100644 MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf create mode 100644 MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2Internals.h create mode 100644 MdePkg/Library/BasePeCoffLib2/Documentation.md create mode 100644 MdePkg/Library/BasePeCoffLib2/PeCoffDebug.c create mode 100644 MdePkg/Library/BasePeCoffLib2/PeCoffHash.c create mode 100644 MdePkg/Library/BasePeCoffLib2/PeCoffHii.c create mode 100644 MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c create mode 100644 MdePkg/Library/BasePeCoffLib2/PeCoffInit.c create mode 100644 MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c create mode 100644 MdePkg/Library/BasePeCoffLib2/PeCoffRelocate.c create mode 100644 MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf create mode 100644 MdePkg/Library/BaseUefiImageExtraActionLibNull/UefiImageExtraActionLib.c create mode 100644 MdePkg/Library/BaseUefiImageExtraActionLibNull/UefiImageExtraActionLibNull.uni create mode 100644 MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf create mode 100644 MdePkg/Library/BaseUefiImageLib/CommonSupport.c create mode 100644 MdePkg/Library/BaseUefiImageLib/ExecutionSupport.c create mode 100644 MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c create mode 100644 MdePkg/Library/BaseUefiImageLib/PeCoffSupport.h create mode 100644 MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.c create mode 100644 README.md delete mode 100644 SecurityPkg/Tcg/Tcg2Dxe/MeasureBootPeCoff.c create mode 100644 SecurityPkg/Tcg/Tcg2Dxe/MeasureBootUefiImage.c create mode 100644 SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/Ia32/IntHandler.nasm create mode 100644 SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/Ia32/IntHandlerFuncs.c create mode 100644 SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.c create mode 100644 SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.h create mode 100644 SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.uni create mode 100644 SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf create mode 100644 SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/X64/IntHandler.nasm create mode 100644 SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/X64/IntHandlerFuncs.c create mode 100644 StandaloneMmPkg/Include/Library/StandaloneMmProtectionLib.h create mode 100644 StandaloneMmPkg/Library/StandaloneMmProtectionLib/ProtectionAarch64.c create mode 100644 StandaloneMmPkg/Library/StandaloneMmProtectionLib/ProtectionNull.c create mode 100644 StandaloneMmPkg/Library/StandaloneMmProtectionLib/StandaloneMmProtectionLib.inf rename UefiPayloadPkg/{UefiPayloadEntry => Library/UefiPayloadEntryMemoryAllocationLib}/MemoryAllocation.c (100%) create mode 100644 UefiPayloadPkg/Library/UefiPayloadEntryMemoryAllocationLib/UefiPayloadEntryMemoryAllocationLib.inf diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 90906796aa..8fb18bd32d 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -54,9 +54,9 @@ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf @@ -112,7 +112,7 @@ ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf - ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf + ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.inf ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf ArmPkg/Library/SemiHostingDebugLib/SemiHostingDebugLib.inf ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf diff --git a/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc b/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc index f93d31776f..e4488b3b3b 100644 --- a/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc +++ b/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc @@ -34,7 +34,6 @@ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/ArmPkg/Drivers/CpuDxe/CpuDxe.h index 80d53e3577..a86de6800f 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuDxe.h +++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.h @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf index deb4bad8d7..9e6b8805af 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf +++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.inf @@ -49,7 +49,6 @@ DxeServicesTableLib HobLib MemoryAllocationLib - PeCoffGetEntryPointLib UefiDriverEntryPoint UefiLib diff --git a/ArmPkg/Include/Library/ArmStandaloneMmCoreEntryPoint.h b/ArmPkg/Include/Library/ArmStandaloneMmCoreEntryPoint.h index 1549211613..29bd1a1356 100644 --- a/ArmPkg/Include/Library/ArmStandaloneMmCoreEntryPoint.h +++ b/ArmPkg/Include/Library/ArmStandaloneMmCoreEntryPoint.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include #define CPU_INFO_FLAG_PRIMARY_CPU 0x00000001 @@ -157,56 +157,6 @@ typedef RETURN_STATUS (*REGION_PERMISSION_UPDATE_FUNC) ( IN UINT64 Length ); -/** - Privileged firmware assigns RO & Executable attributes to all memory occupied - by the Boot Firmware Volume. This function sets the correct permissions of - sections in the Standalone MM Core module to be able to access RO and RW data - and make further progress in the boot process. - - @param [in] ImageContext Pointer to PE/COFF image context - @param [in] ImageBase Base of image in memory - @param [in] SectionHeaderOffset Offset of PE/COFF image section header - @param [in] NumberOfSections Number of Sections - @param [in] TextUpdater Function to change code permissions - @param [in] ReadOnlyUpdater Function to change RO permissions - @param [in] ReadWriteUpdater Function to change RW permissions - -**/ -EFI_STATUS -EFIAPI -UpdateMmFoundationPeCoffPermissions ( - IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN EFI_PHYSICAL_ADDRESS ImageBase, - IN UINT32 SectionHeaderOffset, - IN CONST UINT16 NumberOfSections, - IN REGION_PERMISSION_UPDATE_FUNC TextUpdater, - IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater, - IN REGION_PERMISSION_UPDATE_FUNC ReadWriteUpdater - ); - -/** - Privileged firmware assigns RO & Executable attributes to all memory occupied - by the Boot Firmware Volume. This function locates the section information of - the Standalone MM Core module to be able to change permissions of the - individual sections later in the boot process. - - @param [in] TeData Pointer to PE/COFF image data - @param [in, out] ImageContext Pointer to PE/COFF image context - @param [out] ImageBase Pointer to ImageBase variable - @param [in, out] SectionHeaderOffset Offset of PE/COFF image section header - @param [in, out] NumberOfSections Number of Sections - -**/ -EFI_STATUS -EFIAPI -GetStandaloneMmCorePeCoffSections ( - IN VOID *TeData, - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - OUT EFI_PHYSICAL_ADDRESS *ImageBase, - IN OUT UINT32 *SectionHeaderOffset, - IN OUT UINT16 *NumberOfSections - ); - /** Privileged firmware assigns RO & Executable attributes to all memory occupied by the Boot Firmware Volume. This function locates the Standalone MM Core @@ -220,10 +170,10 @@ GetStandaloneMmCorePeCoffSections ( **/ EFI_STATUS EFIAPI -LocateStandaloneMmCorePeCoffData ( +LocateStandaloneMmCoreUefiImage ( IN EFI_FIRMWARE_VOLUME_HEADER *BfvAddress, IN OUT VOID **TeData, - IN OUT UINTN *TeDataSize + IN OUT UINT32 *TeDataSize ); /** diff --git a/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.c b/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.c index 0d60a491ee..5fd320c3ad 100644 --- a/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.c +++ b/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -1010,13 +1011,12 @@ CEntryPoint ( PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; ARM_SVC_ARGS EventCompleteSvcArgs; EFI_STATUS Status; - UINT32 SectionHeaderOffset; - UINT16 NumberOfSections; COMM_PROTOCOL CommProtocol; VOID *HobStart; VOID *TeData; - UINTN TeDataSize; - EFI_PHYSICAL_ADDRESS ImageBase; + UINT32 TeDataSize; + UINT32 SectionIndex; + UEFI_IMAGE_RECORD *ImageRecord; EDKII_PI_MM_CPU_DRIVER_EP_PROTOCOL *PiMmCpuDriverEpProtocol; EDKII_PI_MM_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint; EFI_HOB_FIRMWARE_VOLUME *FvHob; @@ -1051,7 +1051,7 @@ CEntryPoint ( } // Locate PE/COFF File information for the Standalone MM core module - Status = LocateStandaloneMmCorePeCoffData ( + Status = LocateStandaloneMmCoreUefiImage ( (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHob->BaseAddress, &TeData, &TeDataSize @@ -1061,53 +1061,46 @@ CEntryPoint ( goto finish; } - // Obtain the PE/COFF Section information for the Standalone MM core module - Status = GetStandaloneMmCorePeCoffSections ( - TeData, - &ImageContext, - &ImageBase, - &SectionHeaderOffset, - &NumberOfSections - ); + DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", TeData)); + // Obtain the PE/COFF Section information for the Standalone MM core module + Status = UefiImageInitializeContext (&ImageContext, TeData, TeDataSize); if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Section information - %r\n", Status)); goto finish; } - // - // ImageBase may deviate from ImageContext.ImageAddress if we are dealing - // with a TE image, in which case the latter points to the actual offset - // of the image, whereas ImageBase refers to the address where the image - // would start if the stripped PE headers were still in place. In either - // case, we need to fix up ImageBase so it refers to the actual current - // load address. - // - ImageBase += (UINTN)TeData - ImageContext.ImageAddress; - - // Update the memory access permissions of individual sections in the - // Standalone MM core module - Status = UpdateMmFoundationPeCoffPermissions ( - &ImageContext, - ImageBase, - SectionHeaderOffset, - NumberOfSections, - ArmSetMemoryRegionNoExec, - ArmSetMemoryRegionReadOnly, - ArmClearMemoryRegionReadOnly - ); - if (EFI_ERROR (Status)) { + ImageRecord = UefiImageLoaderGetImageRecord (&ImageContext); + + if (ImageRecord == NULL) { goto finish; } - if (ImageContext.ImageAddress != (UINTN)TeData) { - ImageContext.ImageAddress = (UINTN)TeData; - ArmSetMemoryRegionNoExec (ImageBase, SIZE_4KB); - ArmClearMemoryRegionReadOnly (ImageBase, SIZE_4KB); + UINT32 Address = 0; + for (SectionIndex = 0; SectionIndex < ImageRecord->NumSegments; ++ SectionIndex) { + if ((ImageRecord->Segments[SectionIndex].Attributes & EFI_MEMORY_XP) != 0) { + ArmSetMemoryRegionNoExec ( + Address, + ImageRecord->Segments[SectionIndex].Size + ); + } + + if ((ImageRecord->Segments[SectionIndex].Attributes & EFI_MEMORY_RO) == 0) { + ArmClearMemoryRegionReadOnly ( + Address, + ImageRecord->Segments[SectionIndex].Size + ); + } - Status = PeCoffLoaderRelocateImage (&ImageContext); - ASSERT_EFI_ERROR (Status); + Address += ImageRecord->Segments[SectionIndex].Size; } + FreePool (ImageRecord); + + // FIXME: Should relocation not be performed with all of the Image writable? + Status = UefiImageRelocateImageInplaceForExecution (&ImageContext); + ASSERT_EFI_ERROR (Status); + // Set the gHobList to point to the HOB list passed by TF-A. // This will be used by StandaloneMmCoreHobLib in early stage. gHobList = HobStart; diff --git a/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.inf b/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.inf index e5bfb810f1..df86752525 100644 --- a/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.inf +++ b/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.inf @@ -63,11 +63,9 @@ gArmTokenSpaceGuid.PcdStMmStackSize # -# This configuration fails for CLANGPDB, which does not support PIE in the GCC -# sense. Such however is required for ARM family StandaloneMmCore -# self-relocation, and thus the CLANGPDB toolchain is unsupported for ARM and -# AARCH64 for this module. +# This configuration fails for CLANGDPB, which does not support PIE in the GCC +# sense. Such however is required for AArch64 StandaloneMmCore self-relocation, +# and thus the CLANGPDB toolchain is unsupported for AArch64 for this module. # [BuildOptions] - GCC:*_*_ARM_CC_FLAGS = -fpie GCC:*_*_AARCH64_CC_FLAGS = -fpie diff --git a/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/SetPermissions.c b/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/SetPermissions.c index fd3fdae4f0..728e26c814 100644 --- a/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/SetPermissions.c +++ b/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/SetPermissions.c @@ -24,162 +24,23 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include -/** - Privileged firmware assigns RO & Executable attributes to all memory occupied - by the Boot Firmware Volume. This function sets the correct permissions of - sections in the Standalone MM Core module to be able to access RO and RW data - and make further progress in the boot process. - - @param [in] ImageContext Pointer to PE/COFF image context - @param [in] ImageBase Base of image in memory - @param [in] SectionHeaderOffset Offset of PE/COFF image section header - @param [in] NumberOfSections Number of Sections - @param [in] TextUpdater Function to change code permissions - @param [in] ReadOnlyUpdater Function to change RO permissions - @param [in] ReadWriteUpdater Function to change RW permissions - -**/ -EFI_STATUS -EFIAPI -UpdateMmFoundationPeCoffPermissions ( - IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN EFI_PHYSICAL_ADDRESS ImageBase, - IN UINT32 SectionHeaderOffset, - IN CONST UINT16 NumberOfSections, - IN REGION_PERMISSION_UPDATE_FUNC TextUpdater, - IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater, - IN REGION_PERMISSION_UPDATE_FUNC ReadWriteUpdater - ) -{ - EFI_IMAGE_SECTION_HEADER SectionHeader; - RETURN_STATUS Status; - EFI_PHYSICAL_ADDRESS Base; - UINTN Size; - UINTN ReadSize; - UINTN Index; - - ASSERT (ImageContext != NULL); - - // - // Iterate over the sections - // - for (Index = 0; Index < NumberOfSections; Index++) { - // - // Read section header from file - // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - ReadSize = Size; - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - - if (RETURN_ERROR (Status) || (Size != ReadSize)) { - DEBUG (( - DEBUG_ERROR, - "%a: ImageContext->ImageRead () failed (Status = %r)\n", - __func__, - Status - )); - return Status; - } - - DEBUG (( - DEBUG_INFO, - "%a: Section %d of image at 0x%lx has 0x%x permissions\n", - __func__, - Index, - ImageContext->ImageAddress, - SectionHeader.Characteristics - )); - DEBUG (( - DEBUG_INFO, - "%a: Section %d of image at 0x%lx has %a name\n", - __func__, - Index, - ImageContext->ImageAddress, - SectionHeader.Name - )); - DEBUG (( - DEBUG_INFO, - "%a: Section %d of image at 0x%lx has 0x%x address\n", - __func__, - Index, - ImageContext->ImageAddress, - ImageContext->ImageAddress + SectionHeader.VirtualAddress - )); - DEBUG (( - DEBUG_INFO, - "%a: Section %d of image at 0x%lx has 0x%x data\n", - __func__, - Index, - ImageContext->ImageAddress, - SectionHeader.PointerToRawData - )); - - // - // If the section is marked as XN then remove the X attribute. Furthermore, - // if it is a writeable section then mark it appropriately as well. - // - if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) == 0) { - Base = ImageBase + SectionHeader.VirtualAddress; - - TextUpdater (Base, SectionHeader.Misc.VirtualSize); - - if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_WRITE) != 0) { - ReadWriteUpdater (Base, SectionHeader.Misc.VirtualSize); - DEBUG (( - DEBUG_INFO, - "%a: Mapping section %d of image at 0x%lx with RW-XN permissions\n", - __func__, - Index, - ImageContext->ImageAddress - )); - } else { - DEBUG (( - DEBUG_INFO, - "%a: Mapping section %d of image at 0x%lx with RO-XN permissions\n", - __func__, - Index, - ImageContext->ImageAddress - )); - } - } else { - DEBUG (( - DEBUG_INFO, - "%a: Ignoring section %d of image at 0x%lx with 0x%x permissions\n", - __func__, - Index, - ImageContext->ImageAddress, - SectionHeader.Characteristics - )); - } - - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); - } - - return RETURN_SUCCESS; -} - /** Privileged firmware assigns RO & Executable attributes to all memory occupied by the Boot Firmware Volume. This function locates the Standalone MM Core module PE/COFF image in the BFV and returns this information. - @param [in] BfvAddress Base Address of Boot Firmware Volume - @param [in, out] TeData Pointer to address for allocating memory - for PE/COFF image data - @param [in, out] TeDataSize Pointer to size of PE/COFF image data + @param [in] BfvAddress Base Address of Boot Firmware Volume + @param [in, out] UefiImage Pointer to address for allocating memory + for PE/COFF image data + @param [in, out] UefiImageSize Pointer to size of PE/COFF image data **/ EFI_STATUS EFIAPI -LocateStandaloneMmCorePeCoffData ( +LocateStandaloneMmCoreUefiImage ( IN EFI_FIRMWARE_VOLUME_HEADER *BfvAddress, - IN OUT VOID **TeData, - IN OUT UINTN *TeDataSize + IN OUT VOID **UefiImage, + IN OUT UINT32 *UefiImageSize ) { EFI_FFS_FILE_HEADER *FileHeader; @@ -201,9 +62,9 @@ LocateStandaloneMmCorePeCoffData ( return Status; } - Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, TeData, TeDataSize); + Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, UefiImage, UefiImageSize); if (EFI_ERROR (Status)) { - Status = FfsFindSectionData (EFI_SECTION_TE, FileHeader, TeData, TeDataSize); + Status = FfsFindSectionData (EFI_SECTION_TE, FileHeader, UefiImage, UefiImageSize); if (EFI_ERROR (Status)) { DEBUG (( DEBUG_ERROR, @@ -214,170 +75,6 @@ LocateStandaloneMmCorePeCoffData ( } } - DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", *TeData)); - return Status; -} - -/** - Returns the PC COFF section information. - - @param [in, out] ImageContext Pointer to PE/COFF image context - @param [out] ImageBase Base of image in memory - @param [out] SectionHeaderOffset Offset of PE/COFF image section header - @param [out] NumberOfSections Number of Sections - -**/ -STATIC -EFI_STATUS -GetPeCoffSectionInformation ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - OUT EFI_PHYSICAL_ADDRESS *ImageBase, - OUT UINT32 *SectionHeaderOffset, - OUT UINT16 *NumberOfSections - ) -{ - RETURN_STATUS Status; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData; - UINTN Size; - UINTN ReadSize; - - ASSERT (ImageContext != NULL); - ASSERT (SectionHeaderOffset != NULL); - ASSERT (NumberOfSections != NULL); - - Status = PeCoffLoaderGetImageInfo (ImageContext); - if (RETURN_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "%a: PeCoffLoaderGetImageInfo () failed (Status == %r)\n", - __func__, - Status - )); - return Status; - } - - if (ImageContext->SectionAlignment < EFI_PAGE_SIZE) { - // - // The sections need to be at least 4 KB aligned, since that is the - // granularity at which we can tighten permissions. - // - if (!ImageContext->IsTeImage) { - DEBUG (( - DEBUG_WARN, - "%a: non-TE Image at 0x%lx has SectionAlignment < 4 KB (%lu)\n", - __func__, - ImageContext->ImageAddress, - ImageContext->SectionAlignment - )); - return RETURN_UNSUPPORTED; - } - - ImageContext->SectionAlignment = EFI_PAGE_SIZE; - } - - // - // Read the PE/COFF Header. For PE32 (32-bit) this will read in too much - // data, but that should not hurt anything. Hdr.Pe32->OptionalHeader.Magic - // determines if this is a PE32 or PE32+ image. The magic is in the same - // location in both images. - // - Hdr.Union = &HdrData; - Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION); - ReadSize = Size; - Status = ImageContext->ImageRead ( - ImageContext->Handle, - ImageContext->PeCoffHeaderOffset, - &Size, - Hdr.Pe32 - ); - - if (RETURN_ERROR (Status) || (Size != ReadSize)) { - DEBUG (( - DEBUG_ERROR, - "%a: TmpContext->ImageRead () failed (Status = %r)\n", - __func__, - Status - )); - return Status; - } - - *ImageBase = ImageContext->ImageAddress; - if (!ImageContext->IsTeImage) { - ASSERT (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE); - - *SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER); - *NumberOfSections = Hdr.Pe32->FileHeader.NumberOfSections; - - switch (Hdr.Pe32->OptionalHeader.Magic) { - case EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC: - *SectionHeaderOffset += Hdr.Pe32->FileHeader.SizeOfOptionalHeader; - break; - case EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC: - *SectionHeaderOffset += Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader; - break; - default: - ASSERT (FALSE); - } - } else { - *SectionHeaderOffset = (UINTN)(sizeof (EFI_TE_IMAGE_HEADER)); - *NumberOfSections = Hdr.Te->NumberOfSections; - *ImageBase -= (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER); - } - - return RETURN_SUCCESS; -} - -/** - Privileged firmware assigns RO & Executable attributes to all memory occupied - by the Boot Firmware Volume. This function locates the section information of - the Standalone MM Core module to be able to change permissions of the - individual sections later in the boot process. - - @param [in] TeData Pointer to PE/COFF image data - @param [in, out] ImageContext Pointer to PE/COFF image context - @param [out] ImageBase Pointer to ImageBase variable - @param [in, out] SectionHeaderOffset Offset of PE/COFF image section header - @param [in, out] NumberOfSections Number of Sections - -**/ -EFI_STATUS -EFIAPI -GetStandaloneMmCorePeCoffSections ( - IN VOID *TeData, - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - OUT EFI_PHYSICAL_ADDRESS *ImageBase, - IN OUT UINT32 *SectionHeaderOffset, - IN OUT UINT16 *NumberOfSections - ) -{ - EFI_STATUS Status; - - // Initialize the Image Context - ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); - ImageContext->Handle = TeData; - ImageContext->ImageRead = PeCoffLoaderImageReadFromMemory; - - DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", TeData)); - - Status = GetPeCoffSectionInformation ( - ImageContext, - ImageBase, - SectionHeaderOffset, - NumberOfSections - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Section information - %r\n", Status)); - return Status; - } - - DEBUG (( - DEBUG_INFO, - "Standalone MM Core PE-COFF SectionHeaderOffset - 0x%x, NumberOfSections - %d\n", - *SectionHeaderOffset, - *NumberOfSections - )); - + DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", *UefiImage)); return Status; } diff --git a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c index 77c92f9ecc..a985f525d3 100644 --- a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c +++ b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c @@ -13,8 +13,8 @@ #include #include #include -#include -#include +#include +#include #include #include @@ -165,34 +165,39 @@ GetFfsFile ( EFI_STATUS GetImageContext ( - IN EFI_FFS_FILE_HEADER *FfsHeader, - OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + IN EFI_FFS_FILE_HEADER *FfsHeader, + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { - EFI_STATUS Status; - UINTN ParsedLength; - UINTN SectionSize; - UINTN SectionLength; - EFI_COMMON_SECTION_HEADER *Section; - VOID *EfiImage; - UINTN ImageAddress; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; - VOID *CodeViewEntryPointer; - - Section = (EFI_COMMON_SECTION_HEADER *)(FfsHeader + 1); - SectionSize = *(UINT32 *)(FfsHeader->Size) & 0x00FFFFFF; - SectionSize -= sizeof (EFI_FFS_FILE_HEADER); - ParsedLength = 0; - EfiImage = NULL; + EFI_STATUS Status; + UINTN ParsedLength; + UINT32 SectionSize; + UINT32 SectionLength; + EFI_COMMON_SECTION_HEADER *Section; + VOID *EfiImage; + + Section = (EFI_COMMON_SECTION_HEADER *)(FfsHeader + 1); + SectionLength = 0; + SectionSize = *(UINT32 *)(FfsHeader->Size) & 0x00FFFFFF; + SectionSize -= sizeof (EFI_FFS_FILE_HEADER); + ParsedLength = 0; + EfiImage = NULL; while (ParsedLength < SectionSize) { + // + // Size is 24 bits wide so mask upper 8 bits. + // + SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF; + if (SectionLength < sizeof (*Section)) { + return EFI_VOLUME_CORRUPTED; + } + if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) { - EfiImage = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(Section + 1); + EfiImage = (Section + 1); break; } // - // Size is 24 bits wide so mask upper 8 bits. // SectionLength is adjusted it is 4 byte aligned. // Go to the next section // @@ -208,34 +213,10 @@ GetImageContext ( } // Initialize the Image Context - ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); - ImageContext->Handle = EfiImage; - ImageContext->ImageRead = PeCoffLoaderImageReadFromMemory; - - Status = PeCoffLoaderGetImageInfo (ImageContext); - if (!EFI_ERROR (Status) && ((VOID *)(UINTN)ImageContext->DebugDirectoryEntryRva != NULL)) { - ImageAddress = ImageContext->ImageAddress; - if (ImageContext->IsTeImage) { - ImageAddress += sizeof (EFI_TE_IMAGE_HEADER) - ((EFI_TE_IMAGE_HEADER *)EfiImage)->StrippedSize; - } - - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(ImageAddress + ImageContext->DebugDirectoryEntryRva); - if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { - CodeViewEntryPointer = (VOID *)(ImageAddress + (UINTN)DebugEntry->RVA); - switch (*(UINT32 *)CodeViewEntryPointer) { - case CODEVIEW_SIGNATURE_NB10: - ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY); - break; - case CODEVIEW_SIGNATURE_RSDS: - ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY); - break; - case CODEVIEW_SIGNATURE_MTOC: - ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY); - break; - default: - break; - } - } + // FIXME: Common FFS API with size checks + Status = UefiImageInitializeContext (ImageContext, EfiImage, SectionLength - sizeof (*Section)); + if (!EFI_ERROR(Status)) { + Status = UefiImageLoadImageInplace( ImageContext); } return Status; @@ -271,9 +252,9 @@ InitializeDebugAgent ( IN DEBUG_AGENT_CONTINUE Function OPTIONAL ) { - EFI_STATUS Status; - EFI_FFS_FILE_HEADER *FfsHeader; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + EFI_STATUS Status; + EFI_FFS_FILE_HEADER *FfsHeader; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; // We use InitFlag to know if DebugAgent has been initialized from // Sec (DEBUG_AGENT_INIT_PREMEM_SEC) or PrePi (DEBUG_AGENT_INIT_POSTMEM_SEC) @@ -286,7 +267,7 @@ InitializeDebugAgent ( if (!EFI_ERROR (Status)) { Status = GetImageContext (FfsHeader, &ImageContext); if (!EFI_ERROR (Status)) { - PeCoffLoaderRelocateImageExtraAction (&ImageContext); + UefiImageLoaderRelocateImageExtraAction (&ImageContext); } } } else if (InitFlag == DEBUG_AGENT_INIT_POSTMEM_SEC) { @@ -297,7 +278,7 @@ InitializeDebugAgent ( if (!EFI_ERROR (Status)) { Status = GetImageContext (FfsHeader, &ImageContext); if (!EFI_ERROR (Status)) { - PeCoffLoaderRelocateImageExtraAction (&ImageContext); + UefiImageLoaderRelocateImageExtraAction (&ImageContext); } } @@ -308,7 +289,7 @@ InitializeDebugAgent ( if (!EFI_ERROR (Status)) { Status = GetImageContext (FfsHeader, &ImageContext); if (!EFI_ERROR (Status)) { - PeCoffLoaderRelocateImageExtraAction (&ImageContext); + UefiImageLoaderRelocateImageExtraAction (&ImageContext); } } } diff --git a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf index 2ceeebbdee..03a637346e 100644 --- a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf +++ b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf @@ -24,8 +24,8 @@ [LibraryClasses] DebugLib PcdLib - PeCoffExtraActionLib - PeCoffLib + UefiImageExtraActionLib + UefiImageLib [Pcd] gArmTokenSpaceGuid.PcdSecureFvBaseAddress diff --git a/ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.c b/ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.c new file mode 100644 index 0000000000..db74ff779b --- /dev/null +++ b/ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.c @@ -0,0 +1,141 @@ +/**@file + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+Portions copyright (c) 2011 - 2012, ARM Ltd. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +#include +#include +#include +#include +#include + +/** + If the build is done on cygwin the paths are cygpaths. + /cygdrive/c/tmp.txt vs c:\tmp.txt so we need to convert + them to work with RVD commands + + @param Name Path to convert if needed + +**/ +CONST CHAR8 * +DeCygwinPathIfNeeded ( + IN CONST CHAR8 *Name, + IN CHAR8 *Temp, + IN UINTN Size + ) +{ + CHAR8 *Ptr; + UINTN Index; + UINTN Index2; + + Ptr = AsciiStrStr (Name, "/cygdrive/"); + if (Ptr == NULL) { + return Name; + } + + for (Index = 9, Index2 = 0; (Index < (Size + 9)) && (Ptr[Index] != '\0'); Index++, Index2++) { + Temp[Index2] = Ptr[Index]; + if (Temp[Index2] == '/') { + Temp[Index2] = '\\'; + } + + if (Index2 == 1) { + Temp[Index2 - 1] = Ptr[Index]; + Temp[Index2] = ':'; + } + } + + return Temp; +} + +/** + Performs additional actions after a PE/COFF image has been loaded and relocated. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that has already been loaded and relocated. + +**/ +VOID +EFIAPI +UefiImageLoaderRelocateImageExtraAction ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + RETURN_STATUS Status; + CONST CHAR8 *PdbPath; + UINT32 PdbPathSize; +#if defined (__CC_ARM) || defined (__GNUC__) + CHAR8 Temp[512]; +#endif + + Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize); + + if (!RETURN_ERROR (Status)) { + #ifdef __CC_ARM + #if (__ARMCC_VERSION < 500000) + // Print out the command for the RVD debugger to load symbols for this image + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "load /a /ni /np %a &0x%p\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), UefiImageLoaderGetImageAddress (ImageContext))); + #else + // Print out the command for the DS-5 to load symbols for this image + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a -o 0x%p\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), UefiImageLoaderGetImageAddress (ImageContext))); + #endif + #elif __GNUC__ + // This may not work correctly if you generate PE/COFF directly as then the Offset would not be required + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a -o 0x%p\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), UefiImageLoaderGetImageAddress (ImageContext))); + #else + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Loading driver at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)UefiImageLoaderGetImageAddress (ImageContext), FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext)))); + #endif + } else { + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Loading driver at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)UefiImageLoaderGetImageAddress (ImageContext), FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext)))); + } +} + +/** + Performs additional actions just before a PE/COFF image is unloaded. Any resources + that were allocated by UefiImageLoaderRelocateImageExtraAction() must be freed. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that is being unloaded. + +**/ +VOID +EFIAPI +UefiImageLoaderUnloadImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + RETURN_STATUS Status; + CONST CHAR8 *PdbPath; + UINT32 PdbPathSize; +#if defined (__CC_ARM) || defined (__GNUC__) + CHAR8 Temp[512]; +#endif + + Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize); + + if (!RETURN_ERROR (Status)) { + #ifdef __CC_ARM + // Print out the command for the RVD debugger to load symbols for this image + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "unload symbols_only %a\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)))); + #elif __GNUC__ + // This may not work correctly if you generate PE/COFF directly as then the Offset would not be required + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "remove-symbol-file %a 0x%08x\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), (UINTN)UefiImageLoaderGetImageAddress (ImageContext))); + #else + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Unloading %a\n", PdbPath)); + #endif + } else { + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Unloading driver at 0x%11p\n", (VOID *)(UINTN)UefiImageLoaderGetImageAddress (ImageContext))); + } +} diff --git a/ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.inf b/ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.inf new file mode 100644 index 0000000000..31728d04d1 --- /dev/null +++ b/ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.inf @@ -0,0 +1,33 @@ +#/** @file +# UEFI Image extra action library for DXE phase that run Unix emulator. +# +# Lib to provide memory journal status code reporting Routines +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2010, Apple Inc. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DebugUnixUefiImageExtraActionLib + FILE_GUID = C3E9448E-1726-42fb-9368-41F75B038C0C + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiImageExtraActionLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = ARM +# + +[Sources.common] + DebugUefiImageExtraActionLib.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + DebugLib diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index 5f9bcf7966..93814bb266 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -36,11 +35,10 @@ STATIC CHAR8 *gExceptionTypeString[] = { STATIC BOOLEAN mRecursiveException; -CHAR8 * +CONST CHAR8 * GetImageName ( IN UINTN FaultAddress, - OUT UINTN *ImageBase, - OUT UINTN *PeCoffSizeOfHeaders + OUT UINTN *ImageBase ); STATIC @@ -211,14 +209,13 @@ DefaultExceptionHandler ( UnicodeSPrintAsciiFormat (UnicodeBuffer, MAX_PRINT_CHARS, Buffer); DEBUG_CODE_BEGIN (); - CHAR8 *Pdb, *PrevPdb; - UINTN ImageBase; - UINTN PeCoffSizeOfHeader; - UINT64 *Fp; - UINT64 RootFp[2]; - UINTN Idx; - - PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase, &PeCoffSizeOfHeader); + CONST CHAR8 *Pdb, *PrevPdb; + UINTN ImageBase; + UINT64 *Fp; + UINT64 RootFp[2]; + UINTN Idx; + + PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase); if (Pdb != NULL) { DEBUG (( DEBUG_ERROR, @@ -243,7 +240,7 @@ DefaultExceptionHandler ( } for (Fp = RootFp; Fp[0] != 0; Fp = (UINT64 *)Fp[0]) { - Pdb = GetImageName (Fp[1], &ImageBase, &PeCoffSizeOfHeader); + Pdb = GetImageName (Fp[1], &ImageBase); if (Pdb != NULL) { if (Pdb != PrevPdb) { Idx++; @@ -264,14 +261,14 @@ DefaultExceptionHandler ( } } - PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase, &PeCoffSizeOfHeader); + PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase); if (Pdb != NULL) { DEBUG ((DEBUG_ERROR, "\n[ 0] %a\n", Pdb)); } Idx = 0; for (Fp = RootFp; Fp[0] != 0; Fp = (UINT64 *)Fp[0]) { - Pdb = GetImageName (Fp[1], &ImageBase, &PeCoffSizeOfHeader); + Pdb = GetImageName (Fp[1], &ImageBase); if ((Pdb != NULL) && (Pdb != PrevPdb)) { DEBUG ((DEBUG_ERROR, "[% 2d] %a\n", ++Idx, Pdb)); PrevPdb = Pdb; diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c index 50e4205c23..d05b2f7d80 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -53,11 +52,10 @@ STATIC CONST CPSR_CHAR mCpsrChar[] = { { 0, '?' } }; -CHAR8 * +CONST CHAR8 * GetImageName ( IN UINTN FaultAddress, - OUT UINTN *ImageBase, - OUT UINTN *PeCoffSizeOfHeaders + OUT UINTN *ImageBase ); /** @@ -225,16 +223,16 @@ DefaultExceptionHandler ( UnicodeSPrintAsciiFormat (UnicodeBuffer, MAX_PRINT_CHARS, Buffer); DEBUG_CODE_BEGIN (); - CHAR8 *Pdb; - UINT32 ImageBase; - UINT32 PeCoffSizeOfHeader; - UINT32 Offset; - CHAR8 CpsrStr[CPSR_STRING_SIZE]; + CONST CHAR8 *Pdb; + UINT32 ImageBase; + UINT32 Offset; + CHAR8 CpsrStr[CPSR_STRING_SIZE]; // char per bit. Lower 5-bits are mode + // that is a 3 char string CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr); DEBUG ((DEBUG_ERROR, "%a\n", CpsrStr)); - Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase, &PeCoffSizeOfHeader); + Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase); Offset = SystemContext.SystemContextArm->PC - ImageBase; if (Pdb != NULL) { DEBUG ((DEBUG_ERROR, "%a\n", Pdb)); @@ -247,7 +245,9 @@ DefaultExceptionHandler ( // you need to subtract out the size of the PE/COFF header to get // get the offset that matches the link map. // - DEBUG ((DEBUG_ERROR, "loaded at 0x%08x (PE/COFF offset) 0x%x (ELF or Mach-O offset) 0x%x", ImageBase, Offset, Offset - PeCoffSizeOfHeader)); + // FIXME: Used to have (ELF or Mach-O offset) 0x%x + // Substitute with .text address (better + may be needed for GDB symbols?) + DEBUG ((EFI_D_ERROR, "loaded at 0x%08x (PE/COFF offset) 0x%x", ImageBase, Offset)); } DEBUG_CODE_END (); diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf index 30291a4663..40fa5d552e 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf @@ -34,7 +34,6 @@ BaseLib PrintLib DebugLib - PeCoffGetEntryPointLib SerialPortLib UefiBootServicesTableLib diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c index 752a763f04..290827a99b 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c @@ -7,7 +7,6 @@ **/ #include -#include #include #include @@ -20,17 +19,15 @@ @param FaultAddress Address to find PE/COFF image for. @param ImageBase Return load address of found image - @param PeCoffSizeOfHeaders Return the size of the PE/COFF header for the image that was found @retval NULL FaultAddress not in a loaded PE/COFF image. @retval Path and file name of PE/COFF image. **/ -CHAR8 * +CONST CHAR8 * GetImageName ( IN UINTN FaultAddress, - OUT UINTN *ImageBase, - OUT UINTN *PeCoffSizeOfHeaders + OUT UINTN *ImageBase ) { EFI_STATUS Status; @@ -59,8 +56,7 @@ GetImageName ( (Address <= ((CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase + DebugTable->NormalImage->LoadedImageProtocolInstance->ImageSize))) { *ImageBase = (UINTN)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase; - *PeCoffSizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)*ImageBase); - return PeCoffLoaderGetPdbPointer (DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase); + return DebugTable->NormalImage->PdbPath; } } } diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index d805778cee..f6655a4911 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -52,8 +52,9 @@ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index f053f5088e..bac77af65d 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -61,8 +61,8 @@ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf @@ -125,8 +125,8 @@ SerialPortLib|ArmVirtPkg/Library/FdtPL011SerialPortLib/FdtPL011SerialPortLib.inf FdtSerialPortAddressLib|OvmfPkg/Library/FdtSerialPortAddressLib/FdtSerialPortAddressLib.inf - PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf - #PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + UefiImageExtraActionLib|ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.inf + #UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf @@ -205,7 +205,6 @@ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf @@ -223,7 +222,6 @@ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf diff --git a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S index 06a0020f25..0f8ec68035 100644 --- a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S +++ b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S @@ -149,9 +149,8 @@ ASM_PFX(DiscoverDramFromDt): // window at the beginning of the FD image as a temp stack. // mov x0, x7 - adr x1, PeCoffLoaderImageReadFromMemory mov sp, x7 - bl RelocatePeCoffImage + bl RelocateUefiImage // // Discover the memory size and offset from the DTB, and record in the diff --git a/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S index cfb5de864f..7fefd4cd06 100644 --- a/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S +++ b/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S @@ -146,9 +146,8 @@ ASM_PFX(ArmPlatformPeiBootAction): // window at the beginning of the FD image as a temp stack. // mov r0, r5 - ADRL (r1, PeCoffLoaderImageReadFromMemory) mov sp, r5 - bl RelocatePeCoffImage + bl RelocateUefiImage // // Discover the memory size and offset from the DTB, and record in the diff --git a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf index 1f6538a4e5..9db6dd4dbe 100755 --- a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf +++ b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf @@ -46,7 +46,7 @@ TimerLib SerialPortLib ExtractGuidedSectionLib - PeCoffLib + UefiImageLib PrePiLib MemoryAllocationLib HobLib diff --git a/ArmVirtPkg/PrePi/PrePi.c b/ArmVirtPkg/PrePi/PrePi.c old mode 100755 new mode 100644 index 9dbb5af942..0ed4db2903 --- a/ArmVirtPkg/PrePi/PrePi.c +++ b/ArmVirtPkg/PrePi/PrePi.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -129,15 +129,15 @@ CEntryPoint ( } VOID -RelocatePeCoffImage ( - IN EFI_PEI_FV_HANDLE FwVolHeader, - IN PE_COFF_LOADER_READ_FILE ImageRead +RelocateUefiImage ( + IN EFI_PEI_FV_HANDLE FwVolHeader ) { - EFI_PEI_FILE_HANDLE FileHandle; - VOID *SectionData; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - EFI_STATUS Status; + EFI_PEI_FILE_HANDLE FileHandle; + VOID *SectionData; + UINT32 SectionSize; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + EFI_STATUS Status; FileHandle = NULL; Status = FfsFindNextFile ( @@ -147,21 +147,16 @@ RelocatePeCoffImage ( ); ASSERT_EFI_ERROR (Status); - Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SectionData); + Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SectionData, &SectionSize); if (EFI_ERROR (Status)) { - Status = FfsFindSectionData (EFI_SECTION_TE, FileHandle, &SectionData); + Status = FfsFindSectionData (EFI_SECTION_TE, FileHandle, &SectionData, &SectionSize); } ASSERT_EFI_ERROR (Status); - ZeroMem (&ImageContext, sizeof ImageContext); + Status = UefiImageInitializeContext (&ImageContext, SectionData, SectionSize); + ASSERT_RETURN_ERROR (Status); - ImageContext.Handle = (EFI_HANDLE)SectionData; - ImageContext.ImageRead = ImageRead; - PeCoffLoaderGetImageInfo (&ImageContext); - - if (ImageContext.ImageAddress != (UINTN)SectionData) { - ImageContext.ImageAddress = (UINTN)SectionData; - PeCoffLoaderRelocateImage (&ImageContext); - } + Status = UefiImageRelocateImageInplaceForExecution (&ImageContext); + ASSERT_RETURN_ERROR (Status); } diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 3f982c529b..4fc2abf0a8 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -54,6 +54,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent (((Imm32) >> 2) & 0x7fffff)) #define ARM_JUMP_TO_THUMB(Offset) _ARM_JUMP_TO_THUMB((Offset) - 8) +#define ALIGN_VALUE_ADDEND(Value, Alignment) (((Alignment) - (Value)) & ((Alignment) - 1U)) +#define ALIGN_VALUE(Value, Alignment) ((Value) + ALIGN_VALUE_ADDEND (Value, Alignment)) +#define IS_ALIGNED(Value, Alignment) (((Value) & ((Alignment) - 1U)) == 0U) + /* * Arm instruction to return from exception (MOVS PC, LR) */ @@ -1308,11 +1312,17 @@ Routine Description: // Rebase the PE or TE image in FileBuffer of FFS file for XIP // Rebase for the debug genfvmap tool // - Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER *) FileBuffer, (UINTN) *VtfFileImage - (UINTN) FvImage->FileImage, FvMapFile); + Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER **)&FileBuffer, &FileSize, (UINTN) *VtfFileImage - (UINTN) FvImage->FileImage, FvMapFile); if (EFI_ERROR (Status)) { Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]); return Status; } + + if (FileSize > (UINTN) ((UINTN) *VtfFileImage - (UINTN) FvImage->CurrentFilePointer)) { + free (FileBuffer); + Error (NULL, 0, 4002, "Resource", "FV space is full, not enough room to add file %s after ImageBase aligning.", FvInfo->FvFiles[Index]); + return EFI_OUT_OF_RESOURCES; + } // // copy VTF File // @@ -1354,11 +1364,17 @@ Routine Description: // Rebase the PE or TE image in FileBuffer of FFS file for XIP. // Rebase Bs and Rt drivers for the debug genfvmap tool. // - Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER *) FileBuffer, (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage, FvMapFile); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]); - return Status; - } + Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER **)&FileBuffer, &FileSize, (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage, FvMapFile); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 3000, "Invalid", "Could not rebase %s.", FvInfo->FvFiles[Index]); + return Status; + } + + if (FileSize > (UINTN) ((UINTN) *VtfFileImage - (UINTN) FvImage->CurrentFilePointer)) { + free (FileBuffer); + Error (NULL, 0, 4002, "Resource", "FV space is full, not enough room to add file %s after ImageBase aligning.", FvInfo->FvFiles[Index]); + return EFI_OUT_OF_RESOURCES; + } // // Copy the file // @@ -3456,11 +3472,109 @@ Routine Description: return EFI_SUCCESS; } +EFI_PHYSICAL_ADDRESS +AddPadSection ( + IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, + IN UINT32 Alignment, + IN OUT EFI_FFS_FILE_HEADER **FfsFile, + IN OUT UINTN *FileSize, + IN OUT EFI_FILE_SECTION_POINTER *Section + ) +{ + EFI_COMMON_SECTION_HEADER *NewSection; + UINT32 FfsHeaderLength; + UINT32 FfsFileLength; + UINT32 PadSize; + UINTN PadAddress; + UINT8 *FfsPart; + UINT32 PartSize; + UINT32 Offset; + EFI_FFS_INTEGRITY_CHECK *IntegrityCheck; + + PadAddress = ALIGN_VALUE (*BaseAddress + sizeof (EFI_COMMON_SECTION_HEADER), Alignment); + PadSize = PadAddress - *BaseAddress; + + Offset = (UINT32)((UINTN)((*Section).Pe32Section) - (UINTN)(*FfsFile)); + PartSize = GetFfsFileLength (*FfsFile) - Offset; + FfsPart = calloc (1, PartSize); + if (FfsPart == NULL) { + fprintf (stderr, "GenFv: Could not allocate memory for FfsPart\n"); + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (FfsPart, (UINT8 *)(UINTN)((*Section).Pe32Section), PartSize); + + FfsFileLength = GetFfsFileLength (*FfsFile) + PadSize; + *FfsFile = realloc (*FfsFile, FfsFileLength); + if (*FfsFile == NULL) { + fprintf (stderr, "GenFv: Could not reallocate memory for FfsFile\n"); + free (FfsPart); + return EFI_OUT_OF_RESOURCES; + } + *FileSize += PadSize; + + NewSection = (EFI_COMMON_SECTION_HEADER *)((UINTN)(*FfsFile) + Offset); + + NewSection->Size[0] = (UINT8)(PadSize & 0xff); + NewSection->Size[1] = (UINT8)((PadSize & 0xff00) >> 8); + NewSection->Size[2] = (UINT8)((PadSize & 0xff0000) >> 16); + NewSection->Type = EFI_SECTION_RAW; + ++NewSection; + ZeroMem ((VOID *)NewSection, PadSize - sizeof (EFI_COMMON_SECTION_HEADER)); + + *Section = (EFI_FILE_SECTION_POINTER)(EFI_PE32_SECTION *)((UINT8 *)NewSection + PadSize - sizeof (EFI_COMMON_SECTION_HEADER)); + + CopyMem ( + (UINT8 *)((*Section).Pe32Section), + FfsPart, + PartSize + ); + + FfsHeaderLength = GetFfsHeaderLength(*FfsFile); + if (FfsHeaderLength > sizeof(EFI_FFS_FILE_HEADER)) { + ((EFI_FFS_FILE_HEADER2 *)(*FfsFile))->ExtendedSize = FfsFileLength; + } else { + (*FfsFile)->Size[0] = (UINT8)(FfsFileLength & 0x000000FF); + (*FfsFile)->Size[1] = (UINT8)((FfsFileLength & 0x0000FF00) >> 8); + (*FfsFile)->Size[2] = (UINT8)((FfsFileLength & 0x00FF0000) >> 16); + } + + // + // Recalculate the FFS header checksum. Instead of setting Header and State + // both to zero, set Header to (UINT8)(-State) so State preserves its original + // value + // + IntegrityCheck = &(*FfsFile)->IntegrityCheck; + IntegrityCheck->Checksum.Header = (UINT8) (0x100 - (*FfsFile)->State); + IntegrityCheck->Checksum.File = 0; + + IntegrityCheck->Checksum.Header = CalculateChecksum8 ( + (UINT8 *)(*FfsFile), FfsHeaderLength); + + if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) { + // + // Ffs header checksum = zero, so only need to calculate ffs body. + // + IntegrityCheck->Checksum.File = CalculateChecksum8 ( + (UINT8 *)(*FfsFile) + FfsHeaderLength, + FfsFileLength - FfsHeaderLength); + } else { + IntegrityCheck->Checksum.File = FFS_FIXED_CHECKSUM; + } + + *BaseAddress = PadAddress; + + free (FfsPart); + + return EFI_SUCCESS; +} + EFI_STATUS FfsRebase ( IN OUT FV_INFO *FvInfo, IN CHAR8 *FileName, - IN OUT EFI_FFS_FILE_HEADER *FfsFile, + IN OUT EFI_FFS_FILE_HEADER **FfsFile, + IN OUT UINTN *FileSize, IN UINTN XipOffset, IN FILE *FvMapFile ) @@ -3533,13 +3647,12 @@ Routine Description: return EFI_SUCCESS; } - XipBase = FvInfo->BaseAddress + XipOffset; // // We only process files potentially containing PE32 sections. // - switch (FfsFile->Type) { + switch ((*FfsFile)->Type) { case EFI_FV_FILETYPE_SECURITY_CORE: case EFI_FV_FILETYPE_PEI_CORE: case EFI_FV_FILETYPE_PEIM: @@ -3551,7 +3664,7 @@ Routine Description: // // Rebase the inside FvImage. // - GetChildFvFromFfs (FvInfo, FfsFile, XipOffset); + GetChildFvFromFfs (FvInfo, *FfsFile, XipOffset); // // Search PE/TE section in FV sectin. @@ -3561,7 +3674,7 @@ Routine Description: return EFI_SUCCESS; } - FfsHeaderSize = GetFfsHeaderLength(FfsFile); + FfsHeaderSize = GetFfsHeaderLength(*FfsFile); // // Rebase each PE32 section // @@ -3575,7 +3688,7 @@ Routine Description: // // Find Pe Image // - Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section); + Status = GetSectionByType (*FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section); if (EFI_ERROR (Status)) { break; } @@ -3624,7 +3737,7 @@ Routine Description: // // Calculate the PE32 base address, based on file type // - switch (FfsFile->Type) { + switch ((*FfsFile)->Type) { case EFI_FV_FILETYPE_SECURITY_CORE: case EFI_FV_FILETYPE_PEI_CORE: case EFI_FV_FILETYPE_PEIM: @@ -3702,7 +3815,7 @@ Routine Description: ImageContext.RelocationsStripped = FALSE; } - NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)FfsFile; + NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile); break; case EFI_FV_FILETYPE_DRIVER: @@ -3717,7 +3830,7 @@ Routine Description: Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName); return EFI_ABORTED; } - NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)FfsFile; + NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile); break; default: @@ -3741,15 +3854,28 @@ Routine Description: // // Load and Relocate Image Data // - MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); + MemoryImagePointer = (UINT8 *) calloc (1, (UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment); if (MemoryImagePointer == NULL) { Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); return EFI_OUT_OF_RESOURCES; } - memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); - ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((UINTN) ImageContext.SectionAlignment - 1)); + ImageContext.ImageAddress = ALIGN_VALUE ((UINTN)MemoryImagePointer, ImageContext.SectionAlignment); - Status = PeCoffLoaderLoadImage (&ImageContext); + if (!(IS_ALIGNED (NewPe32BaseAddress, ImageContext.SectionAlignment))) { + Status = AddPadSection (&NewPe32BaseAddress, ImageContext.SectionAlignment, FfsFile, FileSize, &CurrentPe32Section); + if (EFI_ERROR (Status)) { + free ((VOID *) MemoryImagePointer); + return Status; + } + + CurSecHdrSize = GetSectionHeaderLength (CurrentPe32Section.CommonHeader); + ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize); + PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle); + + ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize + ImageContext.PeCoffHeaderOffset); + } + + Status = PeCoffLoaderLoadImage (&ImageContext); if (EFI_ERROR (Status)) { Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName); free ((VOID *) MemoryImagePointer); @@ -3757,7 +3883,8 @@ Routine Description: } ImageContext.DestinationAddress = NewPe32BaseAddress; - Status = PeCoffLoaderRelocateImage (&ImageContext); + + Status = PeCoffLoaderRelocateImage (&ImageContext); if (EFI_ERROR (Status)) { Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s Status=%d", FileName, Status); free ((VOID *) MemoryImagePointer); @@ -3807,15 +3934,15 @@ Routine Description: // // Now update file checksum // - if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) { - SavedState = FfsFile->State; - FfsFile->IntegrityCheck.Checksum.File = 0; - FfsFile->State = 0; - FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ( - (UINT8 *) ((UINT8 *)FfsFile + FfsHeaderSize), - GetFfsFileLength (FfsFile) - FfsHeaderSize + if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) { + SavedState = (*FfsFile)->State; + (*FfsFile)->IntegrityCheck.Checksum.File = 0; + (*FfsFile)->State = 0; + (*FfsFile)->IntegrityCheck.Checksum.File = CalculateChecksum8 ( + (UINT8 *) ((UINT8 *)(*FfsFile) + FfsHeaderSize), + GetFfsFileLength (*FfsFile) - FfsHeaderSize ); - FfsFile->State = SavedState; + (*FfsFile)->State = SavedState; } // @@ -3829,14 +3956,14 @@ Routine Description: PdbPointer = FileName; } - WriteMapFile (FvMapFile, PdbPointer, FfsFile, NewPe32BaseAddress, &OrigImageContext); + WriteMapFile (FvMapFile, PdbPointer, *FfsFile, NewPe32BaseAddress, &OrigImageContext); } - if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE && - FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE && - FfsFile->Type != EFI_FV_FILETYPE_PEIM && - FfsFile->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER && - FfsFile->Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE + if ((*FfsFile)->Type != EFI_FV_FILETYPE_SECURITY_CORE && + (*FfsFile)->Type != EFI_FV_FILETYPE_PEI_CORE && + (*FfsFile)->Type != EFI_FV_FILETYPE_PEIM && + (*FfsFile)->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER && + (*FfsFile)->Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE ) { // // Only Peim code may have a TE section @@ -3853,7 +3980,7 @@ Routine Description: // // Find Te Image // - Status = GetSectionByType (FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section); + Status = GetSectionByType (*FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section); if (EFI_ERROR (Status)) { break; } @@ -3901,7 +4028,7 @@ Routine Description: // Set new rebased address. // NewPe32BaseAddress = XipBase + (UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) \ - - TEImageHeader->StrippedSize - (UINTN) FfsFile; + - TEImageHeader->StrippedSize - (UINTN) (*FfsFile); // // if reloc is stripped, try to get the original efi image to get reloc info. @@ -4044,15 +4171,15 @@ Routine Description: // // Now update file checksum // - if (FfsFile->Attributes & FFS_ATTRIB_CHECKSUM) { - SavedState = FfsFile->State; - FfsFile->IntegrityCheck.Checksum.File = 0; - FfsFile->State = 0; - FfsFile->IntegrityCheck.Checksum.File = CalculateChecksum8 ( - (UINT8 *)((UINT8 *)FfsFile + FfsHeaderSize), - GetFfsFileLength (FfsFile) - FfsHeaderSize + if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) { + SavedState = (*FfsFile)->State; + (*FfsFile)->IntegrityCheck.Checksum.File = 0; + (*FfsFile)->State = 0; + (*FfsFile)->IntegrityCheck.Checksum.File = CalculateChecksum8 ( + (UINT8 *)((UINT8 *)(*FfsFile) + FfsHeaderSize), + GetFfsFileLength (*FfsFile) - FfsHeaderSize ); - FfsFile->State = SavedState; + (*FfsFile)->State = SavedState; } // // Get this module function address from ModulePeMapFile and add them into FvMap file @@ -4068,7 +4195,7 @@ Routine Description: WriteMapFile ( FvMapFile, PdbPointer, - FfsFile, + *FfsFile, NewPe32BaseAddress, &OrigImageContext ); diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.h b/BaseTools/Source/C/GenFv/GenFvInternalLib.h index 58dadc3fa9..bf476f2c08 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.h +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.h @@ -331,7 +331,8 @@ EFI_STATUS FfsRebase ( IN OUT FV_INFO *FvInfo, IN CHAR8 *FileName, - IN OUT EFI_FFS_FILE_HEADER *FfsFile, + IN OUT EFI_FFS_FILE_HEADER **FfsFile, + IN OUT UINTN *FileSize, IN UINTN XipOffset, IN FILE *FvMapFile ); diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py index 74b4242a16..9fb5ae758e 100755 --- a/BaseTools/Source/Python/build/build.py +++ b/BaseTools/Source/Python/build/build.py @@ -72,6 +72,24 @@ TemporaryTablePattern = re.compile(r'^_\d+_\d+_[a-fA-F0-9]+$') TmpTableDict = {} +## Return the biggest multiple of alignment that is smaller than or equal to +# value. +# +# @param value The value to align down. +# @param alignment The boundary to align down to. +# +def AlignDown(value, alignment): + return value - (value % alignment) + +## Return the smallest multiple of alignment that is bigger than or equal to +# value. +# +# @param value The value to align up. +# @param alignment The boundary to align up to. +# +def AlignUp(value, alignment): + return AlignDown(value + alignment - 1, alignment) + ## Check environment PATH variable to make sure the specified tool is found # # If the tool is found in the PATH, then True is returned @@ -706,7 +724,7 @@ def __init__(self, BaseName, Guid, Arch, OutputDir, DebugDir, ImageClass): self.OutputDir = OutputDir self.DebugDir = DebugDir self.Image = ImageClass - self.Image.Size = (self.Image.Size // 0x1000 + 1) * 0x1000 + self.Image.Size = AlignUp(self.Image.Size, 0x1000) ## The class implementing the EDK2 build process # @@ -1520,12 +1538,15 @@ def _RebaseModule (self, MapBuffer, BaseAddress, ModuleList, AddrIsOffset = True ## for SMM module in SMRAM, the SMRAM will be allocated from base to top. if not ModeIsSmm: BaseAddress = BaseAddress - ModuleInfo.Image.Size + BaseAddress = AlignDown(BaseAddress, ModuleInfo.Image.SectionAlignment) # # Update Image to new BaseAddress by GenFw tool # LaunchCommand(["GenFw", "--rebase", str(BaseAddress), "-r", ModuleOutputImage], ModuleInfo.OutputDir) LaunchCommand(["GenFw", "--rebase", str(BaseAddress), "-r", ModuleDebugImage], ModuleInfo.DebugDir) + ## for SMM module in SMRAM, the SMRAM will be allocated from base to top. else: + BaseAddress = AlignUp(BaseAddress, ModuleInfo.Image.SectionAlignment) # # Set new address to the section header only for SMM driver. # diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec index bb0b677bdc..7536e8d4ab 100644 --- a/EmbeddedPkg/EmbeddedPkg.dec +++ b/EmbeddedPkg/EmbeddedPkg.dec @@ -81,7 +81,6 @@ gEmbeddedDeviceGuid = { 0xbf4b9d10, 0x13ec, 0x43dd, { 0x88, 0x80, 0xe9, 0xb, 0x71, 0x8f, 0x27, 0xde } } gEmbeddedExternalDeviceProtocolGuid = { 0x735F8C64, 0xD696, 0x44D0, { 0xBD, 0xF2, 0x44, 0x7F, 0xD0, 0x5A, 0x54, 0x06 }} gEmbeddedGpioProtocolGuid = { 0x17a0a3d7, 0xc0a5, 0x4635, { 0xbb, 0xd5, 0x07, 0x21, 0x87, 0xdf, 0xe2, 0xee }} - gPeCoffLoaderProtocolGuid = { 0xB323179B, 0x97FB, 0x477E, { 0xB0, 0xFE, 0xD8, 0x85, 0x91, 0xFA, 0x11, 0xAB } } gEmbeddedMmcHostProtocolGuid = { 0x3e591c00, 0x9e4a, 0x11df, {0x92, 0x44, 0x00, 0x02, 0xA5, 0xD5, 0xC5, 0x1B }} gAndroidFastbootTransportProtocolGuid = { 0x74bd9fe0, 0x8902, 0x11e3, {0xb9, 0xd3, 0xf7, 0x22, 0x38, 0xfc, 0x9a, 0x31}} gAndroidFastbootPlatformProtocolGuid = { 0x524685a0, 0x89a0, 0x11e3, {0x9d, 0x4d, 0xbf, 0xa9, 0xf6, 0xa4, 0x03, 0x08}} diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc index 5cc0bb7ad6..44f220eb7e 100644 --- a/EmbeddedPkg/EmbeddedPkg.dsc +++ b/EmbeddedPkg/EmbeddedPkg.dsc @@ -58,9 +58,9 @@ ReportStatusCodeLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf diff --git a/EmbeddedPkg/GdbStub/GdbStub.c b/EmbeddedPkg/GdbStub/GdbStub.c index e6e07b87b6..3d317cb05a 100644 --- a/EmbeddedPkg/GdbStub/GdbStub.c +++ b/EmbeddedPkg/GdbStub/GdbStub.c @@ -807,166 +807,6 @@ gXferObjectReadResponse ( return Count; } -/** - Note: This should be a library function. In the Apple case you have to add - the size of the PE/COFF header into the starting address to make things work - right as there is no way to pad the Mach-O for the size of the PE/COFF header. - - - Returns a pointer to the PDB file name for a PE/COFF image that has been - loaded into system memory with the PE/COFF Loader Library functions. - - Returns the PDB file name for the PE/COFF image specified by Pe32Data. If - the PE/COFF image specified by Pe32Data is not a valid, then NULL is - returned. If the PE/COFF image specified by Pe32Data does not contain a - debug directory entry, then NULL is returned. If the debug directory entry - in the PE/COFF image specified by Pe32Data does not contain a PDB file name, - then NULL is returned. - If Pe32Data is NULL, then ASSERT(). - - @param Pe32Data Pointer to the PE/COFF image that is loaded in system - memory. - @param DebugBase Address that the debugger would use as the base of the image - - @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL - if it cannot be retrieved. DebugBase is only valid if PDB file name is - valid. - -**/ -VOID * -EFIAPI -PeCoffLoaderGetDebuggerInfo ( - IN VOID *Pe32Data, - OUT VOID **DebugBase - ) -{ - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; - UINTN DirCount; - VOID *CodeViewEntryPointer; - INTN TEImageAdjust; - UINT32 NumberOfRvaAndSizes; - UINT16 Magic; - UINTN SizeOfHeaders; - - ASSERT (Pe32Data != NULL); - - TEImageAdjust = 0; - DirectoryEntry = NULL; - DebugEntry = NULL; - NumberOfRvaAndSizes = 0; - SizeOfHeaders = 0; - - DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; - } - - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) { - DirectoryEntry = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG]; - TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize; - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN)Hdr.Te + - Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress + - TEImageAdjust); - } - - SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize; - - // __APPLE__ check this math... - *DebugBase = ((CHAR8 *)Pe32Data) - TEImageAdjust; - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - *DebugBase = Pe32Data; - - // - // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic. - // It is due to backward-compatibility, for some system might - // generate PE32+ image with PE32 Magic. - // - switch (Hdr.Pe32->FileHeader.Machine) { - case EFI_IMAGE_MACHINE_IA32: - // - // Assume PE32 image with IA32 Machine field. - // - Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; - break; - case EFI_IMAGE_MACHINE_X64: - case EFI_IMAGE_MACHINE_IA64: - // - // Assume PE32+ image with X64 or IPF Machine field - // - Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - break; - default: - // - // For unknown Machine field, use Magic in optional Header - // - Magic = Hdr.Pe32->OptionalHeader.Magic; - } - - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset get Debug Directory Entry - // - SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders; - NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes; - DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN)Pe32Data + DirectoryEntry->VirtualAddress); - } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - // - // Use PE32+ offset get Debug Directory Entry - // - SizeOfHeaders = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders; - NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes; - DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN)Pe32Data + DirectoryEntry->VirtualAddress); - } - - if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { - DirectoryEntry = NULL; - DebugEntry = NULL; - } - } else { - return NULL; - } - - if ((DebugEntry == NULL) || (DirectoryEntry == NULL)) { - return NULL; - } - - for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) { - if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { - if (DebugEntry->SizeOfData > 0) { - CodeViewEntryPointer = (VOID *)((UINTN)DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust); - switch (*(UINT32 *)CodeViewEntryPointer) { - case CODEVIEW_SIGNATURE_NB10: - return (VOID *)((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)); - case CODEVIEW_SIGNATURE_RSDS: - return (VOID *)((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY)); - case CODEVIEW_SIGNATURE_MTOC: - *DebugBase = (VOID *)(UINTN)((UINTN)DebugBase - SizeOfHeaders); - return (VOID *)((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY)); - default: - break; - } - } - } - } - - (void)SizeOfHeaders; - return NULL; -} - /** Process "qXfer:object:read:annex:offset,length" request. @@ -1007,7 +847,7 @@ QxferLibrary ( ) { VOID *LoadAddress; - CHAR8 *Pdb; + CONST CHAR8 *Pdb; UINTN Size; if (Offset != gPacketqXferLibraryOffset) { @@ -1035,12 +875,8 @@ QxferLibrary ( for ( ; gEfiDebugImageTableEntry < gDebugImageTableHeader->TableSize; gEfiDebugImageTableEntry++, gDebugTable++) { if (gDebugTable->NormalImage != NULL) { if ((gDebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && - (gDebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) - { - Pdb = PeCoffLoaderGetDebuggerInfo ( - gDebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase, - &LoadAddress - ); + (gDebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) { + Pdb = gDebugTable->NormalImage->PdbPath; if (Pdb != NULL) { Size = AsciiSPrint ( gXferLibraryBuffer, diff --git a/EmbeddedPkg/GdbStub/GdbStubInternal.h b/EmbeddedPkg/GdbStub/GdbStubInternal.h index 9c3929c812..cc954c0666 100644 --- a/EmbeddedPkg/GdbStub/GdbStubInternal.h +++ b/EmbeddedPkg/GdbStub/GdbStubInternal.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include extern CONST CHAR8 mHexToStr[]; diff --git a/EmbeddedPkg/Include/Library/PrePiLib.h b/EmbeddedPkg/Include/Library/PrePiLib.h index 93a9115eac..a76d4c5686 100644 --- a/EmbeddedPkg/Include/Library/PrePiLib.h +++ b/EmbeddedPkg/Include/Library/PrePiLib.h @@ -71,6 +71,7 @@ EFI_STATUS @param FileHeader A pointer to the file header that contains the set of sections to be searched. @param SectionData A pointer to the discovered section, if successful. + @param SectionSize A pointer to the size of the discovered section, if successful. @retval EFI_SUCCESS The section was found. @retval EFI_NOT_FOUND The section was not found. @@ -82,7 +83,8 @@ FfsFindSectionDataWithHook ( IN EFI_SECTION_TYPE SectionType, IN FFS_CHECK_SECTION_HOOK SectionCheckHook, IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **SectionData + OUT VOID **SectionData, + OUT UINT32 *SectionSize ); /** @@ -92,6 +94,7 @@ FfsFindSectionDataWithHook ( @param FileHandle A pointer to the file header that contains the set of sections to be searched. @param SectionData A pointer to the discovered section, if successful. + @param SectionSize A pointer to the size of the discovered section, if successful. @retval EFI_SUCCESS The section was found. @retval EFI_NOT_FOUND The section was not found. @@ -102,7 +105,8 @@ EFIAPI FfsFindSectionData ( IN EFI_SECTION_TYPE SectionType, IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **SectionData + OUT VOID **SectionData, + OUT UINT32 *SectionSize ); /** @@ -675,7 +679,7 @@ BuildExtractSectionHob ( VOID EFIAPI -BuildPeCoffLoaderHob ( +BuildUefiLoaderHob ( VOID ); @@ -760,10 +764,11 @@ AllocateAlignedPages ( EFI_STATUS EFIAPI -LoadPeCoffImage ( - IN VOID *PeCoffImage, +LoadUefiImage ( + IN VOID *UefiImage, + IN UINT32 UefiImageSize, OUT EFI_PHYSICAL_ADDRESS *ImageAddress, - OUT UINT64 *ImageSize, + OUT UINT32 *ImageSize, OUT EFI_PHYSICAL_ADDRESS *EntryPoint ); diff --git a/EmbeddedPkg/Library/PrePiHobLib/Hob.c b/EmbeddedPkg/Library/PrePiHobLib/Hob.c index a394ca00b4..3cdcfbaf8d 100644 --- a/EmbeddedPkg/Library/PrePiHobLib/Hob.c +++ b/EmbeddedPkg/Library/PrePiHobLib/Hob.c @@ -12,12 +12,11 @@ #include #include #include -#include +#include #include #include #include -#include #include #include #include @@ -821,27 +820,6 @@ BuildExtractSectionHob ( BuildGuidDataHob (Guid, &Data, sizeof (Data)); } -PE_COFF_LOADER_PROTOCOL gPeCoffProtocol = { - PeCoffLoaderGetImageInfo, - PeCoffLoaderLoadImage, - PeCoffLoaderRelocateImage, - PeCoffLoaderImageReadFromMemory, - PeCoffLoaderRelocateImageForRuntime, - PeCoffLoaderUnloadImage -}; - -VOID -EFIAPI -BuildPeCoffLoaderHob ( - VOID - ) -{ - VOID *Ptr; - - Ptr = &gPeCoffProtocol; - BuildGuidDataHob (&gPeCoffLoaderProtocolGuid, &Ptr, sizeof (VOID *)); -} - // May want to put this into a library so you only need the PCD settings if you are using the feature? VOID BuildMemoryTypeInformationHob ( diff --git a/EmbeddedPkg/Library/PrePiLib/FwVol.c b/EmbeddedPkg/Library/PrePiLib/FwVol.c index cfb1ff46b7..8ce5cab236 100644 --- a/EmbeddedPkg/Library/PrePiLib/FwVol.c +++ b/EmbeddedPkg/Library/PrePiLib/FwVol.c @@ -278,7 +278,8 @@ FfsProcessSection ( IN FFS_CHECK_SECTION_HOOK SectionCheckHook, IN EFI_COMMON_SECTION_HEADER *Section, IN UINTN SectionSize, - OUT VOID **OutputBuffer + OUT VOID **OutputBuffer, + OUT UINT32 *OutputSize ) { EFI_STATUS Status; @@ -298,6 +299,7 @@ FfsProcessSection ( Found = FALSE; *OutputBuffer = NULL; + *OutputSize = 0; ParsedLength = 0; Status = EFI_NOT_FOUND; while (ParsedLength < SectionSize) { @@ -313,10 +315,13 @@ FfsProcessSection ( } if (Found) { + // FIXME: Use common API with size checks if (IS_SECTION2 (Section)) { *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2)); + *OutputSize = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2); } else { *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER)); + *OutputSize = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER); } return EFI_SUCCESS; @@ -432,7 +437,8 @@ FfsProcessSection ( SectionCheckHook, DstBuffer, DstBufferSize, - OutputBuffer + OutputBuffer, + OutputSize ); } } @@ -466,6 +472,7 @@ FfsProcessSection ( @param FileHandle A pointer to the file header that contains the set of sections to be searched. @param SectionData A pointer to the discovered section, if successful. + @param SectionSize A pointer to the size of the discovered section, if successful. @retval EFI_SUCCESS The section was found. @retval EFI_NOT_FOUND The section was not found. @@ -477,7 +484,8 @@ FfsFindSectionDataWithHook ( IN EFI_SECTION_TYPE SectionType, IN FFS_CHECK_SECTION_HOOK SectionCheckHook, IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **SectionData + OUT VOID **SectionData, + OUT UINT32 *SectionSize ) { EFI_FFS_FILE_HEADER *FfsFileHeader; @@ -500,7 +508,8 @@ FfsFindSectionDataWithHook ( SectionCheckHook, Section, FileSize, - SectionData + SectionData, + SectionSize ); } @@ -511,6 +520,7 @@ FfsFindSectionDataWithHook ( @param FileHandle A pointer to the file header that contains the set of sections to be searched. @param SectionData A pointer to the discovered section, if successful. + @param SectionSize A pointer to the size of the discovered section, if successful. @retval EFI_SUCCESS The section was found. @retval EFI_NOT_FOUND The section was not found. @@ -521,10 +531,11 @@ EFIAPI FfsFindSectionData ( IN EFI_SECTION_TYPE SectionType, IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **SectionData + OUT VOID **SectionData, + OUT UINT32 *SectionSize ) { - return FfsFindSectionDataWithHook (SectionType, NULL, FileHandle, SectionData); + return FfsFindSectionDataWithHook (SectionType, NULL, FileHandle, SectionData, SectionSize); } /** @@ -816,6 +827,7 @@ FfsProcessFvFile ( { EFI_STATUS Status; EFI_PEI_FV_HANDLE FvImageHandle; + UINT32 FvImageHandleSize; EFI_FV_INFO FvImageInfo; UINT32 FvAlignment; VOID *FvBuffer; @@ -842,7 +854,13 @@ FfsProcessFvFile ( // // Find FvImage in FvFile // - Status = FfsFindSectionDataWithHook (EFI_SECTION_FIRMWARE_VOLUME_IMAGE, NULL, FvFileHandle, (VOID **)&FvImageHandle); + Status = FfsFindSectionDataWithHook ( + EFI_SECTION_FIRMWARE_VOLUME_IMAGE, + NULL, + FvFileHandle, + (VOID **)&FvImageHandle, + &FvImageHandleSize + ); if (EFI_ERROR (Status)) { return Status; } diff --git a/EmbeddedPkg/Library/PrePiLib/PrePi.h b/EmbeddedPkg/Library/PrePiLib/PrePi.h index a00c946512..c327081dc1 100644 --- a/EmbeddedPkg/Library/PrePiLib/PrePi.h +++ b/EmbeddedPkg/Library/PrePiLib/PrePi.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c index 3cf866dab2..650d864264 100644 --- a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c +++ b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c @@ -6,6 +6,7 @@ **/ +#include "ProcessorBind.h" #include // @@ -56,54 +57,45 @@ AllocateCodePages ( EFI_STATUS EFIAPI -LoadPeCoffImage ( - IN VOID *PeCoffImage, +LoadUefiImage ( + IN VOID *UefiImage, + IN UINT32 UefiImageSize, OUT EFI_PHYSICAL_ADDRESS *ImageAddress, - OUT UINT64 *ImageSize, + OUT UINT32 *DestinationSize, OUT EFI_PHYSICAL_ADDRESS *EntryPoint ) { - RETURN_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - VOID *Buffer; - - ZeroMem (&ImageContext, sizeof (ImageContext)); - - ImageContext.Handle = PeCoffImage; - ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; - - Status = PeCoffLoaderGetImageInfo (&ImageContext); + RETURN_STATUS Status; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UINT32 ImageSize; + VOID *Buffer; + UINT32 BufferSize; + UINT32 BufferPages; + UINT32 BufferAlignment; + + Status = UefiImageInitializeContext (&ImageContext, UefiImage, UefiImageSize); ASSERT_EFI_ERROR (Status); + ImageSize = UefiImageGetImageSize (&ImageContext); + BufferPages = EFI_SIZE_TO_PAGES (ImageSize); + BufferSize = EFI_PAGES_TO_SIZE (BufferPages); + BufferAlignment = UefiImageGetSegmentAlignment (&ImageContext); + // // Allocate Memory for the image // - Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES ((UINT32)ImageContext.ImageSize)); + Buffer = AllocateAlignedCodePages (BufferPages, BufferAlignment); ASSERT (Buffer != 0); - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer; - - // - // Load the image to our new buffer - // - Status = PeCoffLoaderLoadImage (&ImageContext); - ASSERT_EFI_ERROR (Status); - // - // Relocate the image in our new buffer + // Load and relocate the image to our new buffer // - Status = PeCoffLoaderRelocateImage (&ImageContext); + Status = UefiImageLoadImageForExecution (&ImageContext, Buffer, BufferSize, NULL, 0); ASSERT_EFI_ERROR (Status); - *ImageAddress = ImageContext.ImageAddress; - *ImageSize = ImageContext.ImageSize; - *EntryPoint = ImageContext.EntryPoint; - - // - // Flush not needed for all architectures. We could have a processor specific - // function in this library that does the no-op if needed. - // - InvalidateInstructionCacheRange ((VOID *)(UINTN)*ImageAddress, (UINTN)*ImageSize); + *ImageAddress = (UINTN) Buffer; + *DestinationSize = BufferSize; + *EntryPoint = (UINTN) UefiImageLoaderGetImageEntryPoint (&ImageContext); return Status; } @@ -122,22 +114,23 @@ LoadDxeCoreFromFfsFile ( ) { EFI_STATUS Status; - VOID *PeCoffImage; + VOID *UefiImage; + UINT32 UefiImageSize; EFI_PHYSICAL_ADDRESS ImageAddress; - UINT64 ImageSize; + UINT32 DestinationSize; EFI_PHYSICAL_ADDRESS EntryPoint; VOID *BaseOfStack; VOID *TopOfStack; VOID *Hob; EFI_FV_FILE_INFO FvFileInfo; - Status = FfsFindSectionDataWithHook (EFI_SECTION_PE32, NULL, FileHandle, &PeCoffImage); + Status = FfsFindSectionDataWithHook (EFI_SECTION_PE32, NULL, FileHandle, &UefiImage, &UefiImageSize); if (EFI_ERROR (Status)) { return Status; } - Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint); - // For NT32 Debug Status = SecWinNtPeiLoadFile (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint); + Status = LoadUefiImage (UefiImage, UefiImageSize, &ImageAddress, &DestinationSize, &EntryPoint); + // For NT32 Debug Status = SecWinNtPeiLoadFile (UefiImage, &ImageAddress, &ImageSize, &EntryPoint); ASSERT_EFI_ERROR (Status); // @@ -146,7 +139,7 @@ LoadDxeCoreFromFfsFile ( Status = FfsGetFileInfo (FileHandle, &FvFileInfo); ASSERT_EFI_ERROR (Status); - BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, EFI_SIZE_TO_PAGES ((UINT32)ImageSize) * EFI_PAGE_SIZE, EntryPoint); + BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, DestinationSize, EntryPoint); DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)EntryPoint)); diff --git a/EmbeddedPkg/Library/PrePiLib/PrePiLib.inf b/EmbeddedPkg/Library/PrePiLib/PrePiLib.inf index 090bfe888f..9b8e6f4c07 100644 --- a/EmbeddedPkg/Library/PrePiLib/PrePiLib.inf +++ b/EmbeddedPkg/Library/PrePiLib/PrePiLib.inf @@ -41,7 +41,7 @@ DebugLib BaseMemoryLib UefiDecompressLib - PeCoffLib + UefiImageLib CacheMaintenanceLib PrintLib SerialPortLib @@ -53,9 +53,6 @@ [Guids] gEfiMemoryTypeInformationGuid -[Protocols] - gPeCoffLoaderProtocolGuid - [FixedPcd.common] gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc index 5bba746a02..1a9b985c03 100644 --- a/EmulatorPkg/EmulatorPkg.dsc +++ b/EmulatorPkg/EmulatorPkg.dsc @@ -62,8 +62,8 @@ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf @@ -145,8 +145,7 @@ [LibraryClasses.common.SEC] PeiServicesLib|EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf - PeCoffGetEntryPointLib|EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf - PeCoffExtraActionLib|EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf + UefiImageExtraActionLib|EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.inf SerialPortLib|EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf @@ -154,13 +153,13 @@ [LibraryClasses.common.USER_DEFINED, LibraryClasses.common.BASE] DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf ThunkPpiList|EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf ThunkProtocolList|EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf PeiServicesLib|EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf @@ -169,8 +168,7 @@ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf - PeCoffGetEntryPointLib|EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf - PeCoffExtraActionLib|EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf + UefiImageExtraActionLib|EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf SerialPortLib|EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf @@ -186,7 +184,7 @@ HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf - PeCoffExtraActionLib|EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf + UefiImageExtraActionLib|EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.inf ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf TimerLib|EmulatorPkg/Library/DxeCoreTimerLib/DxeCoreTimerLib.inf @@ -208,7 +206,7 @@ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf EmuThunkLib|EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.inf - PeCoffExtraActionLib|EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf + UefiImageExtraActionLib|EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf TimerLib|EmulatorPkg/Library/DxeTimerLib/DxeTimerLib.inf diff --git a/EmulatorPkg/Include/Library/EmuMagicPageLib.h b/EmulatorPkg/Include/Library/EmuMagicPageLib.h index d102f1666a..9652a1186e 100644 --- a/EmulatorPkg/Include/Library/EmuMagicPageLib.h +++ b/EmulatorPkg/Include/Library/EmuMagicPageLib.h @@ -23,7 +23,7 @@ typedef struct { // Used by SecPeiServicesLib EFI_PEI_PPI_DESCRIPTOR *PpiList; - // Needed by PEI PEI PeCoffLoaderExtraActionLib + // Needed by PEI PEI UefiImageLoaderExtraActionLib EMU_THUNK_PROTOCOL *Thunk; } EMU_MAGIC_PAGE_LAYOUT; diff --git a/EmulatorPkg/Include/Protocol/EmuThunk.h b/EmulatorPkg/Include/Protocol/EmuThunk.h index bdd57f410b..ae0dbc95c9 100644 --- a/EmulatorPkg/Include/Protocol/EmuThunk.h +++ b/EmulatorPkg/Include/Protocol/EmuThunk.h @@ -17,7 +17,7 @@ // neded for things like EFI_TIME_CAPABILITIES #include -#include +#include #include #include @@ -88,20 +88,21 @@ BOOLEAN typedef EFI_STATUS (EFIAPI *EMU_PE_COFF_GET_ENTRY_POINT)( - IN VOID *Pe32Data, - IN OUT VOID **EntryPoint + IN VOID *Pe32Data, + IN UINT32 Pe32Size, + IN OUT VOID **EntryPoint ); typedef VOID (EFIAPI *EMU_PE_COFF_RELOCATE_EXTRA_ACTION)( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); typedef VOID (EFIAPI *EMU_PE_COFF_UNLOAD_EXTRA_ACTION)( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); typedef @@ -217,9 +218,9 @@ struct _EMU_THUNK_PROTOCOL { /// /// PE/COFF loader hooks to get symbols loaded /// - EMU_PE_COFF_GET_ENTRY_POINT PeCoffGetEntryPoint; - EMU_PE_COFF_RELOCATE_EXTRA_ACTION PeCoffRelocateImageExtraAction; - EMU_PE_COFF_UNLOAD_EXTRA_ACTION PeCoffUnloadImageExtraAction; + EMU_PE_COFF_GET_ENTRY_POINT UefiImageGetEntryPoint; + EMU_PE_COFF_RELOCATE_EXTRA_ACTION UefiImageRelocateImageExtraAction; + EMU_PE_COFF_UNLOAD_EXTRA_ACTION UefiImageUnloadImageExtraAction; /// /// DXE Architecture Protocol Services diff --git a/EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.c b/EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.c index c3c5ae4246..eba37b8755 100644 --- a/EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.c +++ b/EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.c @@ -1,3 +1,5 @@ +#ifndef DISABLE_NEW_DEPRECATED_INTERFACES + /** @file Provides services to perform additional actions to relocate and unload PE/Coff image for Emu environment specific purpose such as souce level debug. @@ -23,7 +25,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // // Cache of UnixThunk protocol // -EMU_THUNK_PROTOCOL *mThunk = NULL; +EMU_THUNK_PROTOCOL *mThunk = NULL; + /** The constructor function gets the pointer of the WinNT thunk functions @@ -39,7 +42,7 @@ DxeEmuPeCoffLibExtraActionConstructor ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_HOB_GUID_TYPE *GuidHob; + EFI_HOB_GUID_TYPE *GuidHob; // // Retrieve EmuThunkProtocol from GUID'ed HOB @@ -72,6 +75,8 @@ PeCoffLoaderRelocateImageExtraAction ( } } + + /** Performs additional actions just before a PE/COFF image is unloaded. Any resources that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed. @@ -92,3 +97,5 @@ PeCoffLoaderUnloadImageExtraAction ( mThunk->PeCoffUnloadImageExtraAction (ImageContext); } } + +#endif // DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.c b/EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.c new file mode 100644 index 0000000000..246c4d0068 --- /dev/null +++ b/EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.c @@ -0,0 +1,94 @@ +/** @file + Provides services to perform additional actions to relocate and unload + PE/Coff image for Emu environment specific purpose such as souce level debug. + This version only works for DXE phase + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +// +// Cache of UnixThunk protocol +// +EMU_THUNK_PROTOCOL *mThunk = NULL; + +/** + The constructor function gets the pointer of the WinNT thunk functions + It will ASSERT() if Unix thunk protocol is not installed. + + @retval EFI_SUCCESS Unix thunk protocol is found and cached. + +**/ +EFI_STATUS +EFIAPI +DxeEmuUefiImageLibExtraActionConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + // + // Retrieve EmuThunkProtocol from GUID'ed HOB + // + GuidHob = GetFirstGuidHob (&gEmuThunkProtocolGuid); + ASSERT (GuidHob != NULL); + mThunk = (EMU_THUNK_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob))); + ASSERT (mThunk != NULL); + + return EFI_SUCCESS; +} + +/** + Performs additional actions after a PE/COFF image has been loaded and relocated. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that has already been loaded and relocated. + +**/ +VOID +EFIAPI +UefiImageLoaderRelocateImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (mThunk != NULL) { + mThunk->UefiImageRelocateImageExtraAction (ImageContext); + } +} + +/** + Performs additional actions just before a PE/COFF image is unloaded. Any resources + that were allocated by UefiImageLoaderRelocateImageExtraAction() must be freed. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that is being unloaded. + +**/ +VOID +EFIAPI +UefiImageLoaderUnloadImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (mThunk != NULL) { + mThunk->UefiImageUnloadImageExtraAction (ImageContext); + } +} diff --git a/EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.inf b/EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.inf new file mode 100644 index 0000000000..8c7161b573 --- /dev/null +++ b/EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.inf @@ -0,0 +1,42 @@ +## @file +# PeCoff extra action libary for DXE phase that run Emu emulator. +# +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent + +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeEmuUefiImageExtraActionLib + FILE_GUID = 68FCD487-D230-6846-95B1-5E1F2EF942C4 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiImageExtraActionLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION + + CONSTRUCTOR = DxeEmuUefiImageLibExtraActionConstructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + DxeEmuUefiImageExtraActionLib.c + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + DebugLib + HobLib + BaseMemoryLib + +[Protocols] + gEmuThunkProtocolGuid # PROTOCOL ALWAYS_CONSUMED + diff --git a/EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c b/EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c index 9e1a8be607..f941158b88 100644 --- a/EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c +++ b/EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c @@ -1,3 +1,5 @@ +#ifndef DISABLE_NEW_DEPRECATED_INTERFACES + /** @file Provides services to perform additional actions to relocate and unload PE/Coff image for Emu environment specific purpose such as souce level debug. @@ -22,7 +24,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // // Cache of UnixThunk protocol // -EMU_THUNK_PROTOCOL *mThunk = NULL; +EMU_THUNK_PROTOCOL *mThunk = NULL; /** The function caches the pointer of the Unix thunk functions @@ -36,21 +38,22 @@ EFIAPI EmuPeCoffGetThunkStucture ( ) { - EMU_THUNK_PPI *ThunkPpi; - EFI_STATUS Status; + EMU_THUNK_PPI *ThunkPpi; + EFI_STATUS Status; + // // Locate Unix ThunkPpi for retrieving standard output handle // Status = PeiServicesLocatePpi ( - &gEmuThunkPpiGuid, - 0, - NULL, - (VOID **)&ThunkPpi - ); + &gEmuThunkPpiGuid, + 0, + NULL, + (VOID **) &ThunkPpi + ); ASSERT_EFI_ERROR (Status); - EMU_MAGIC_PAGE ()->Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk (); + EMU_MAGIC_PAGE()->Thunk = (EMU_THUNK_PROTOCOL *) ThunkPpi->Thunk (); return EFI_SUCCESS; } @@ -70,12 +73,12 @@ PeCoffLoaderRelocateImageExtraAction ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext ) { - if (EMU_MAGIC_PAGE ()->Thunk == NULL) { + if (EMU_MAGIC_PAGE()->Thunk == NULL) { EmuPeCoffGetThunkStucture (); } + EMU_MAGIC_PAGE()->Thunk->PeCoffRelocateImageExtraAction (ImageContext); + } - EMU_MAGIC_PAGE ()->Thunk->PeCoffRelocateImageExtraAction (ImageContext); -} /** Performs additional actions just before a PE/COFF image is unloaded. Any resources @@ -93,9 +96,10 @@ PeCoffLoaderUnloadImageExtraAction ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext ) { - if (EMU_MAGIC_PAGE ()->Thunk == NULL) { + if (EMU_MAGIC_PAGE()->Thunk == NULL) { EmuPeCoffGetThunkStucture (); } - - EMU_MAGIC_PAGE ()->Thunk->PeCoffUnloadImageExtraAction (ImageContext); + EMU_MAGIC_PAGE()->Thunk->PeCoffUnloadImageExtraAction (ImageContext); } + +#endif // DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.c b/EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.c index a9d28f48cf..e0a6b0f00f 100644 --- a/EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.c +++ b/EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.c @@ -7,7 +7,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "PiPei.h" -#include +//#include #include #include #include @@ -35,8 +35,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent RETURN_STATUS EFIAPI PeCoffLoaderGetEntryPoint ( - IN VOID *Pe32Data, - IN OUT VOID **EntryPoint + IN VOID *Pe32Data, + IN UINT32 Pe32Size, + IN OUT VOID **EntryPoint ) { EMU_THUNK_PPI *ThunkPpi; @@ -56,7 +57,7 @@ PeCoffLoaderGetEntryPoint ( Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk (); - return Thunk->PeCoffGetEntryPoint (Pe32Data, EntryPoint); + return Thunk->PeCoffGetEntryPoint (Pe32Data, Pe32Size, EntryPoint); } /** diff --git a/EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.c b/EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.c new file mode 100644 index 0000000000..ce19922aec --- /dev/null +++ b/EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.c @@ -0,0 +1,101 @@ +/** @file + Provides services to perform additional actions to relocate and unload + PE/Coff image for Emu environment specific purpose such as souce level debug. + This version only works for PEI phase + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// +// Cache of UnixThunk protocol +// +EMU_THUNK_PROTOCOL *mThunk = NULL; + +/** + The function caches the pointer of the Unix thunk functions + It will ASSERT() if Unix thunk ppi is not installed. + + @retval EFI_SUCCESS WinNT thunk protocol is found and cached. + +**/ +EFI_STATUS +EFIAPI +EmuUefiImageGetThunkStucture ( + ) +{ + EMU_THUNK_PPI *ThunkPpi; + EFI_STATUS Status; + + // + // Locate Unix ThunkPpi for retrieving standard output handle + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, + 0, + NULL, + (VOID **)&ThunkPpi + ); + ASSERT_EFI_ERROR (Status); + + EMU_MAGIC_PAGE ()->Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk (); + + return EFI_SUCCESS; +} + +/** + Performs additional actions after a PE/COFF image has been loaded and relocated. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that has already been loaded and relocated. + +**/ +VOID +EFIAPI +UefiImageLoaderRelocateImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (EMU_MAGIC_PAGE ()->Thunk == NULL) { + EmuUefiImageGetThunkStucture (); + } + + EMU_MAGIC_PAGE ()->Thunk->UefiImageRelocateImageExtraAction (ImageContext); +} + +/** + Performs additional actions just before a PE/COFF image is unloaded. Any resources + that were allocated by UefiImageLoaderRelocateImageExtraAction() must be freed. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that is being unloaded. + +**/ +VOID +EFIAPI +UefiImageLoaderUnloadImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (EMU_MAGIC_PAGE ()->Thunk == NULL) { + EmuUefiImageGetThunkStucture (); + } + + EMU_MAGIC_PAGE ()->Thunk->UefiImageUnloadImageExtraAction (ImageContext); +} diff --git a/EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.inf b/EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.inf new file mode 100644 index 0000000000..d2b109da86 --- /dev/null +++ b/EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.inf @@ -0,0 +1,43 @@ +## @file +# PeCoff extra action libary for Pei phase that run Emu emulator. +# +# Lib to provide memory journal status code reporting Routines +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent + +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiEmuUefiImageExtraActionLib + FILE_GUID = 79C4E72A-730B-F040-8129-95877B3A97A8 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiImageExtraActionLib|PEI_CORE PEIM + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + PeiEmuUefiImageExtraActionLib.c + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + BaseLib + PeiServicesLib + DebugLib + +[Ppis] + gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED + +[Pcd] + gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage diff --git a/EmulatorPkg/Library/SecPeiServicesLib/FwVol.c b/EmulatorPkg/Library/SecPeiServicesLib/FwVol.c index e1cc6c6a51..7bb6cd0fe9 100644 --- a/EmulatorPkg/Library/SecPeiServicesLib/FwVol.c +++ b/EmulatorPkg/Library/SecPeiServicesLib/FwVol.c @@ -276,3 +276,52 @@ Routine Description: return EFI_NOT_FOUND; } + +// FIXME: Docs +EFI_STATUS +SecFfsFindSectionData2 ( + IN EFI_SECTION_TYPE SectionType, + IN EFI_FFS_FILE_HEADER *FfsFileHeader, + IN OUT VOID **SectionData, + OUT UINT32 *SectionDataSize + ) +{ + UINT32 FileSize; + EFI_COMMON_SECTION_HEADER *Section; + UINT32 SectionLength; + UINT32 ParsedLength; + + // + // Size is 24 bits wide so mask upper 8 bits. + // Does not include FfsFileHeader header size + // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned. + // + Section = (EFI_COMMON_SECTION_HEADER *) (FfsFileHeader + 1); + FileSize = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF; + FileSize -= sizeof (EFI_FFS_FILE_HEADER); + + *SectionData = NULL; + ParsedLength = 0; + while (ParsedLength < FileSize) { + // FIXME: Common API with size checks + // + // Size is 24 bits wide so mask upper 8 bits. + // + SectionLength = *(UINT32 *) Section->Size & 0x00FFFFFF; + if (Section->Type == SectionType) { + *SectionData = (VOID *) (Section + 1); + *SectionDataSize = SectionLength - sizeof (*Section); + return EFI_SUCCESS; + } + // + // SectionLength is adjusted it is 4 byte aligned. + // Go to the next section + // + SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4); + + ParsedLength += SectionLength; + Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength); + } + + return EFI_NOT_FOUND; +} diff --git a/EmulatorPkg/Library/SecPeiServicesLib/PeiServicesLib.c b/EmulatorPkg/Library/SecPeiServicesLib/PeiServicesLib.c index 9409cbdb66..51bd3f9e1a 100644 --- a/EmulatorPkg/Library/SecPeiServicesLib/PeiServicesLib.c +++ b/EmulatorPkg/Library/SecPeiServicesLib/PeiServicesLib.c @@ -26,6 +26,14 @@ SecFfsFindSectionData ( OUT VOID **SectionData ); +EFI_STATUS +SecFfsFindSectionData2 ( + IN EFI_SECTION_TYPE SectionType, + IN EFI_FFS_FILE_HEADER *FfsFileHeader, + IN OUT VOID **SectionData, + OUT UINT32 *SectionDataSize + ); + /** This service enables a given PEIM to register an interface into the PEI Foundation. @@ -304,6 +312,38 @@ PeiServicesFfsFindSectionData ( return SecFfsFindSectionData (SectionType, FileHandle, SectionData); } +/** + This service enables PEIMs to discover sections of a given instance and type within a valid FFS file. + + @param SectionType The value of the section type to find. + @param SectionInstance Section instance to find. + @param FileHandle A pointer to the file header that contains the set + of sections to be searched. + @param SectionData A pointer to the discovered section, if successful. + @param SectionDataSize The size of the discovered section, if successful. + @param AuthenticationStatus A pointer to the authentication status for this section. + + @retval EFI_SUCCESS The section was found. + @retval EFI_NOT_FOUND The section was not found. + +**/ +EFI_STATUS +EFIAPI +PeiServicesFfsFindSectionData4 ( + IN EFI_SECTION_TYPE SectionType, + IN UINTN SectionInstance, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData, + OUT UINT32 *SectionDataSize, + OUT UINT32 *AuthenticationStatus + ) +{ + ASSERT (SectionInstance == 0); + + *AuthenticationStatus = 0; + return SecFfsFindSectionData2 (SectionType, FileHandle, SectionData, SectionDataSize); +} + /** This service enables PEIMs to register the permanent memory configuration that has been initialized with the PEI Foundation. diff --git a/EmulatorPkg/Sec/Sec.c b/EmulatorPkg/Sec/Sec.c index 3d792adc94..e1d9373b90 100644 --- a/EmulatorPkg/Sec/Sec.c +++ b/EmulatorPkg/Sec/Sec.c @@ -9,6 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "Sec.h" +#include EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPpi = { SecTemporaryRamSupport @@ -22,6 +23,53 @@ EFI_PEI_PPI_DESCRIPTOR gPrivateDispatchTable[] = { } }; +//FIXME: +/** + Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded + into system memory with the PE/COFF Loader Library functions. + + Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry + point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then + return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS. + If Pe32Data is NULL, then ASSERT(). + If EntryPoint is NULL, then ASSERT(). + + @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory. + @param EntryPoint The pointer to entry point to the PE/COFF image to return. + + @retval RETURN_SUCCESS EntryPoint was returned. + @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image. + +**/ +RETURN_STATUS +EFIAPI +UefiImageLoaderGetEntryPoint ( + IN VOID *Pe32Data, + IN UINT32 Pe32Size, + IN OUT VOID **EntryPoint + ) +{ + EMU_THUNK_PPI *ThunkPpi; + EFI_STATUS Status; + EMU_THUNK_PROTOCOL *Thunk; + + // + // Locate EmuThunkPpi for retrieving standard output handle + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, + 0, + NULL, + (VOID **) &ThunkPpi + ); + ASSERT_EFI_ERROR (Status); + + Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk (); + + return Thunk->UefiImageGetEntryPoint (Pe32Data, Pe32Size, EntryPoint); +} + + /** The entry point of PE/COFF Image for the PEI Core, that has been hijacked by this SEC that sits on top of an OS application. So the entry and exit of this module @@ -64,13 +112,15 @@ _ModuleEntryPoint ( EFI_STATUS Status; EFI_PEI_FV_HANDLE VolumeHandle; EFI_PEI_FILE_HANDLE FileHandle; - VOID *PeCoffImage; + VOID *UefiImage; + UINT32 UefiImageSize; EFI_PEI_CORE_ENTRY_POINT EntryPoint; EFI_PEI_PPI_DESCRIPTOR *Ppi; EFI_PEI_PPI_DESCRIPTOR *SecPpiList; UINTN SecReseveredMemorySize; UINTN Index; EFI_PEI_PPI_DESCRIPTOR PpiArray[10]; + UINT32 AuthenticationStatus; EMU_MAGIC_PAGE ()->PpiList = PpiList; ProcessLibraryConstructorList (); @@ -118,10 +168,10 @@ _ModuleEntryPoint ( Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_PEI_CORE, VolumeHandle, &FileHandle); ASSERT_EFI_ERROR (Status); - Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage); + Status = PeiServicesFfsFindSectionData4 (EFI_SECTION_PE32, 0, FileHandle, &UefiImage, &UefiImageSize, &AuthenticationStatus); ASSERT_EFI_ERROR (Status); - Status = PeCoffLoaderGetEntryPoint (PeCoffImage, (VOID **)&EntryPoint); + Status = UefiImageLoaderGetEntryPoint (UefiImage, UefiImageSize, (VOID **)&EntryPoint); ASSERT_EFI_ERROR (Status); // Transfer control to PEI Core diff --git a/EmulatorPkg/Sec/Sec.h b/EmulatorPkg/Sec/Sec.h index 94689eb41d..e357add14c 100644 --- a/EmulatorPkg/Sec/Sec.h +++ b/EmulatorPkg/Sec/Sec.h @@ -15,7 +15,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include #include #include diff --git a/EmulatorPkg/Sec/Sec.inf b/EmulatorPkg/Sec/Sec.inf index 5d47eed7ae..0de84f565a 100644 --- a/EmulatorPkg/Sec/Sec.inf +++ b/EmulatorPkg/Sec/Sec.inf @@ -36,7 +36,6 @@ [LibraryClasses] DebugLib - PeCoffGetEntryPointLib PeiServicesLib PpiListLib BaseMemoryLib diff --git a/EmulatorPkg/Unix/GdbRun.sh b/EmulatorPkg/Unix/GdbRun.sh index b050ad5e2c..6fea1c9d5b 100644 --- a/EmulatorPkg/Unix/GdbRun.sh +++ b/EmulatorPkg/Unix/GdbRun.sh @@ -41,7 +41,7 @@ set $SymbolFileChangesCount = 0 # define AddFirmwareSymbolFile if $SymbolFileChangesCount < $arg0 - add-symbol-file $arg1 $arg2 + add-symbol-file $arg1 -o $arg2 set $SymbolFileChangesCount = $arg0 end end diff --git a/EmulatorPkg/Unix/Host/EmuThunk.c b/EmulatorPkg/Unix/Host/EmuThunk.c index c57c105a53..bdc6d62035 100644 --- a/EmulatorPkg/Unix/Host/EmuThunk.c +++ b/EmulatorPkg/Unix/Host/EmuThunk.c @@ -415,9 +415,9 @@ EMU_THUNK_PROTOCOL gEmuThunkProtocol = { GasketSecMalloc, GasketSecValloc, GasketSecFree, - GasketSecPeCoffGetEntryPoint, - GasketSecPeCoffRelocateImageExtraAction, - GasketSecPeCoffUnloadImageExtraAction, + GasketSecUefiImageGetEntryPoint, + GasketSecUefiImageRelocateImageExtraAction, + GasketSecUefiImageUnloadImageExtraAction, GasketSecEnableInterrupt, GasketSecDisableInterrupt, GasketQueryPerformanceFrequency, diff --git a/EmulatorPkg/Unix/Host/Gasket.h b/EmulatorPkg/Unix/Host/Gasket.h index 71b459ddd8..6fe28b202b 100644 --- a/EmulatorPkg/Unix/Host/Gasket.h +++ b/EmulatorPkg/Unix/Host/Gasket.h @@ -67,21 +67,22 @@ GasketSecFree ( RETURN_STATUS EFIAPI -GasketSecPeCoffGetEntryPoint ( +GasketSecUefiImageGetEntryPoint ( IN VOID *Pe32Data, + IN UINT32 Pe32Size, IN OUT VOID **EntryPoint ); VOID EFIAPI -GasketSecPeCoffRelocateImageExtraAction ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext +GasketSecUefiImageRelocateImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); VOID EFIAPI -GasketSecPeCoffUnloadImageExtraAction ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext +GasketSecUefiImageUnloadImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); VOID diff --git a/EmulatorPkg/Unix/Host/Host.c b/EmulatorPkg/Unix/Host/Host.c index 1f29dd00a3..134481b617 100644 --- a/EmulatorPkg/Unix/Host/Host.c +++ b/EmulatorPkg/Unix/Host/Host.c @@ -44,9 +44,6 @@ EMU_FD_INFO *gFdInfo; UINTN gSystemMemoryCount = 0; EMU_SYSTEM_MEMORY *gSystemMemory; -UINTN mImageContextModHandleArraySize = 0; -IMAGE_CONTEXT_TO_MOD_HANDLE *mImageContextModHandleArray = NULL; - EFI_PEI_PPI_DESCRIPTOR *gPpiList; int gInXcode = 0; @@ -98,11 +95,13 @@ main ( BOOLEAN Done; EFI_PEI_FILE_HANDLE FileHandle; VOID *SecFile; + UINT32 SecFileSize; CHAR16 *MemorySizeStr; CHAR16 *FirmwareVolumesStr; UINTN *StackPointer; FILE *GdbTempFile; EMU_THUNK_PPI *SecEmuThunkPpi; + UINT32 AuthenticationStatus; // // Xcode does not support sourcing gdb scripts directly, so the Xcode XML @@ -111,8 +110,7 @@ main ( SecGdbConfigBreak (); // - // If dlopen doesn't work, then we build a gdb script to allow the - // symbols to be loaded. + // We build a gdb script to allow the symbols to be loaded. // Index = strlen (*Argv); gGdbWorkingFileName = AllocatePool (Index + strlen (".gdb") + 1); @@ -284,7 +282,14 @@ main ( &FileHandle ); if (!EFI_ERROR (Status)) { - Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SecFile); + Status = PeiServicesFfsFindSectionData4 ( + EFI_SECTION_PE32, + 0, + FileHandle, + &SecFile, + &SecFileSize, + &AuthenticationStatus + ); if (!EFI_ERROR (Status)) { PeiIndex = Index; printf (" contains SEC Core"); @@ -330,7 +335,7 @@ main ( // // Hand off to SEC // - SecLoadFromCore ((UINTN)InitialStackMemory, (UINTN)InitialStackMemorySize, (UINTN)gFdInfo[0].Address, SecFile); + SecLoadFromCore ((UINTN)InitialStackMemory, (UINTN)InitialStackMemorySize, (UINTN)gFdInfo[0].Address, SecFile, SecFileSize); // // If we get here, then the SEC Core returned. This is an error as SEC should @@ -546,7 +551,8 @@ SecLoadFromCore ( IN UINTN LargestRegion, IN UINTN LargestRegionSize, IN UINTN BootFirmwareVolumeBase, - IN VOID *PeiCorePe32File + IN VOID *PeiCorePe32File, + IN UINT32 PeiCorePe32Size ) { EFI_STATUS Status; @@ -597,7 +603,7 @@ SecLoadFromCore ( // // Find the SEC Core Entry Point // - Status = SecPeCoffGetEntryPoint (PeiCorePe32File, (VOID **)&PeiCoreEntryPoint); + Status = SecUefiImageGetEntryPoint (PeiCorePe32File, PeiCorePe32Size, (VOID **)&PeiCoreEntryPoint); if (EFI_ERROR (Status)) { return; } @@ -731,53 +737,28 @@ SecEmuThunkAddress ( RETURN_STATUS EFIAPI -SecPeCoffGetEntryPoint ( - IN VOID *Pe32Data, - IN OUT VOID **EntryPoint +SecUefiImageGetEntryPoint ( + IN VOID *Pe32Data, + IN UINT32 Pe32Size, + IN OUT VOID **EntryPoint ) { - EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - - ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.Handle = Pe32Data; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)SecImageRead; + EFI_STATUS Status; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; - Status = PeCoffLoaderGetImageInfo (&ImageContext); + Status = UefiImageInitializeContext (&ImageContext, Pe32Data, Pe32Size); if (EFI_ERROR (Status)) { return Status; } - if (ImageContext.ImageAddress != (UINTN)Pe32Data) { - // - // Relocate image to match the address where it resides - // - ImageContext.ImageAddress = (UINTN)Pe32Data; - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - return Status; - } - } else { - // - // Or just return image entry point - // - ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer (Pe32Data); - Status = PeCoffLoaderGetEntryPoint (Pe32Data, EntryPoint); - if (EFI_ERROR (Status)) { - return Status; - } - - ImageContext.EntryPoint = (UINTN)*EntryPoint; + // FIXME: Why cannot the Image be in-place already? + Status = UefiImageRelocateImageInplaceForExecution (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; } - // On Unix a dlopen is done that will change the entry point - SecPeCoffRelocateImageExtraAction (&ImageContext); - *EntryPoint = (VOID *)(UINTN)ImageContext.EntryPoint; + SecUefiImageRelocateImageExtraAction (&ImageContext); + *EntryPoint = (VOID *) (UefiImageLoaderGetImageEntryPoint (&ImageContext)); return Status; } @@ -900,114 +881,9 @@ Routine Description: return EFI_SUCCESS; } -/*++ - -Routine Description: - Store the ModHandle in an array indexed by the Pdb File name. - The ModHandle is needed to unload the image. - -Arguments: - ImageContext - Input data returned from PE Loader Library. Used to find the - .PDB file name of the PE Image. - ModHandle - Returned from LoadLibraryEx() and stored for call to - FreeLibrary(). - -Returns: - EFI_SUCCESS - ModHandle was stored. - -**/ -EFI_STATUS -AddHandle ( - IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN VOID *ModHandle - ) -{ - UINTN Index; - IMAGE_CONTEXT_TO_MOD_HANDLE *Array; - UINTN PreviousSize; - - Array = mImageContextModHandleArray; - for (Index = 0; Index < mImageContextModHandleArraySize; Index++, Array++) { - if (Array->ImageContext == NULL) { - // - // Make a copy of the string and store the ModHandle - // - Array->ImageContext = ImageContext; - Array->ModHandle = ModHandle; - return EFI_SUCCESS; - } - } - - // - // No free space in mImageContextModHandleArray so grow it by - // IMAGE_CONTEXT_TO_MOD_HANDLE entires. realloc will - // copy the old values to the new location. But it does - // not zero the new memory area. - // - PreviousSize = mImageContextModHandleArraySize * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE); - mImageContextModHandleArraySize += MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE; - - mImageContextModHandleArray = ReallocatePool ( - (mImageContextModHandleArraySize - 1) * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE), - mImageContextModHandleArraySize * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE), - mImageContextModHandleArray - ); - if (mImageContextModHandleArray == NULL) { - ASSERT (FALSE); - return EFI_OUT_OF_RESOURCES; - } - - memset (mImageContextModHandleArray + PreviousSize, 0, MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE)); - - return AddHandle (ImageContext, ModHandle); -} - -/*++ - -Routine Description: - Return the ModHandle and delete the entry in the array. - -Arguments: - ImageContext - Input data returned from PE Loader Library. Used to find the - .PDB file name of the PE Image. - -Returns: - ModHandle - ModHandle associated with ImageContext is returned - NULL - No ModHandle associated with ImageContext - -**/ -VOID * -RemoveHandle ( - IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -{ - UINTN Index; - IMAGE_CONTEXT_TO_MOD_HANDLE *Array; - - if (ImageContext->PdbPointer == NULL) { - // - // If no PDB pointer there is no ModHandle so return NULL - // - return NULL; - } - - Array = mImageContextModHandleArray; - for (Index = 0; Index < mImageContextModHandleArraySize; Index++, Array++) { - if (Array->ImageContext == ImageContext) { - // - // If you find a match return it and delete the entry - // - Array->ImageContext = NULL; - return Array->ModHandle; - } - } - - return NULL; -} - BOOLEAN IsPdbFile ( - IN CHAR8 *PdbFileName + IN CONST CHAR8 *PdbFileName ) { UINTN Len; @@ -1035,23 +911,29 @@ IsPdbFile ( void PrintLoadAddress ( - IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { - if (ImageContext->PdbPointer == NULL) { + EFI_STATUS Status; + CONST CHAR8 *PdbPath; + UINT32 PdbPathSize; + + Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize); + + if (EFI_ERROR (Status)) { fprintf ( stderr, "0x%08lx Loading NO DEBUG with entry point 0x%08lx\n", - (unsigned long)(ImageContext->ImageAddress), - (unsigned long)ImageContext->EntryPoint + (unsigned long) UefiImageLoaderGetImageAddress (ImageContext), + (unsigned long) UefiImageLoaderGetImageEntryPoint (ImageContext) ); } else { fprintf ( stderr, "0x%08lx Loading %s with entry point 0x%08lx\n", - (unsigned long)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders), - ImageContext->PdbPointer, - (unsigned long)ImageContext->EntryPoint + (unsigned long) UefiImageLoaderGetImageAddress (ImageContext), + PdbPath, + (unsigned long) UefiImageLoaderGetImageEntryPoint (ImageContext) ); } @@ -1059,71 +941,12 @@ PrintLoadAddress ( fflush (stderr); } -/** - Loads the image using dlopen so symbols will be automatically - loaded by gdb. - - @param ImageContext The PE/COFF image context - - @retval TRUE - The image was successfully loaded - @retval FALSE - The image was successfully loaded - -**/ -BOOLEAN -DlLoadImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -{ - #ifdef __APPLE__ - - return FALSE; - - #else - - void *Handle = NULL; - void *Entry = NULL; - - if (ImageContext->PdbPointer == NULL) { - return FALSE; - } - - if (!IsPdbFile (ImageContext->PdbPointer)) { - return FALSE; - } - - fprintf ( - stderr, - "Loading %s 0x%08lx - entry point 0x%08lx\n", - ImageContext->PdbPointer, - (unsigned long)ImageContext->ImageAddress, - (unsigned long)ImageContext->EntryPoint - ); - - Handle = dlopen (ImageContext->PdbPointer, RTLD_NOW); - if (Handle != NULL) { - Entry = dlsym (Handle, "_ModuleEntryPoint"); - AddHandle (ImageContext, Handle); - } else { - printf ("%s\n", dlerror ()); - } - - if (Entry != NULL) { - ImageContext->EntryPoint = (UINTN)Entry; - printf ("Change %s Entrypoint to :0x%08lx\n", ImageContext->PdbPointer, (unsigned long)Entry); - return TRUE; - } else { - return FALSE; - } - - #endif -} - #ifdef __APPLE__ __attribute__ ((noinline)) #endif VOID SecGdbScriptBreak ( - char *FileName, + const char *FileName, int FileNameLength, long unsigned int LoadAddress, int AddSymbolFlag @@ -1141,28 +964,37 @@ SecGdbScriptBreak ( **/ VOID GdbScriptAddImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { + EFI_STATUS Status; + CONST CHAR8 *PdbPath; + UINT32 PdbPathSize; + PrintLoadAddress (ImageContext); - if ((ImageContext->PdbPointer != NULL) && !IsPdbFile (ImageContext->PdbPointer)) { + Status = UefiImageGetSymbolsPath ((ImageContext, &PdbPath,) &PdbPathSize); + if (EFI_ERROR (Status)) { + return; + } + + if (!IsPdbFile (PdbPath)) { FILE *GdbTempFile; if (FeaturePcdGet (PcdEmulatorLazyLoadSymbols)) { GdbTempFile = fopen (gGdbWorkingFileName, "a"); if (GdbTempFile != NULL) { - long unsigned int SymbolsAddr = (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders); + long unsigned int SymbolsAddr = (long unsigned int)UefiImageLoaderGetImageAddress (ImageContext); mScriptSymbolChangesCount++; fprintf ( GdbTempFile, "AddFirmwareSymbolFile 0x%x %s 0x%08lx\n", mScriptSymbolChangesCount, - ImageContext->PdbPointer, + PdbPath, SymbolsAddr ); fclose (GdbTempFile); // This is for the lldb breakpoint only - SecGdbScriptBreak (ImageContext->PdbPointer, strlen (ImageContext->PdbPointer) + 1, (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders), 1); + SecGdbScriptBreak (PdbPath, PdbPathSize, (long unsigned int)UefiImageLoaderGetImageAddress (ImageContext), 1); } else { ASSERT (FALSE); } @@ -1171,9 +1003,9 @@ GdbScriptAddImage ( if (GdbTempFile != NULL) { fprintf ( GdbTempFile, - "add-symbol-file %s 0x%08lx\n", - ImageContext->PdbPointer, - (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders) + "add-symbol-file %s -o 0x%08lx\n", + PdbPath, + (long unsigned int)UefiImageLoaderGetImageAddress (ImageContext) ); fclose (GdbTempFile); @@ -1183,7 +1015,7 @@ GdbScriptAddImage ( // Also used for the lldb breakpoint script. The lldb breakpoint script does // not use the file, it uses the arguments. // - SecGdbScriptBreak (ImageContext->PdbPointer, strlen (ImageContext->PdbPointer) + 1, (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders), 1); + SecGdbScriptBreak (PdbPath, PdbPathSize, (long unsigned int)UefiImageLoaderGetImageAddress (ImageContext), 1); } else { ASSERT (FALSE); } @@ -1193,13 +1025,11 @@ GdbScriptAddImage ( VOID EFIAPI -SecPeCoffRelocateImageExtraAction ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext +SecUefiImageRelocateImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { - if (!DlLoadImage (ImageContext)) { - GdbScriptAddImage (ImageContext); - } + GdbScriptAddImage (ImageContext); } /** @@ -1211,15 +1041,23 @@ SecPeCoffRelocateImageExtraAction ( **/ VOID GdbScriptRemoveImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { - FILE *GdbTempFile; + FILE *GdbTempFile; + EFI_STATUS Status; + CONST CHAR8 *PdbPath; + UINT32 PdbPathSize; + + Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize); + if (EFI_ERROR (Status)) { + return; + } // // Need to skip .PDB files created from VC++ // - if (IsPdbFile (ImageContext->PdbPointer)) { + if (IsPdbFile (PdbPath)) { return; } @@ -1234,24 +1072,24 @@ GdbScriptRemoveImage ( GdbTempFile, "RemoveFirmwareSymbolFile 0x%x %s\n", mScriptSymbolChangesCount, - ImageContext->PdbPointer + PdbPath ); fclose (GdbTempFile); - SecGdbScriptBreak (ImageContext->PdbPointer, strlen (ImageContext->PdbPointer) + 1, 0, 0); + SecGdbScriptBreak (PdbPath, PdbPathSize, 0, 0); } else { ASSERT (FALSE); } } else { GdbTempFile = fopen (gGdbWorkingFileName, "w"); if (GdbTempFile != NULL) { - fprintf (GdbTempFile, "remove-symbol-file %s\n", ImageContext->PdbPointer); + fprintf (GdbTempFile, "remove-symbol-file %s\n", PdbPath); fclose (GdbTempFile); // // Target for gdb breakpoint in a script that uses gGdbWorkingFileName to set a breakpoint. // Hey what can you say scripting in gdb is not that great.... // - SecGdbScriptBreak (ImageContext->PdbPointer, strlen (ImageContext->PdbPointer) + 1, 0, 0); + SecGdbScriptBreak (PdbPath, PdbPathSize, 0, 0); } else { ASSERT (FALSE); } @@ -1260,22 +1098,9 @@ GdbScriptRemoveImage ( VOID EFIAPI -SecPeCoffUnloadImageExtraAction ( - IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext +SecUefiImageUnloadImageExtraAction ( + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { - VOID *Handle; - - // - // Check to see if the image symbols were loaded with gdb script, or dlopen - // - Handle = RemoveHandle (ImageContext); - if (Handle != NULL) { - #ifndef __APPLE__ - dlclose (Handle); - #endif - return; - } - GdbScriptRemoveImage (ImageContext); } diff --git a/EmulatorPkg/Unix/Host/Host.h b/EmulatorPkg/Unix/Host/Host.h index 0c81cdfc01..c3b4214f84 100644 --- a/EmulatorPkg/Unix/Host/Host.h +++ b/EmulatorPkg/Unix/Host/Host.h @@ -85,7 +85,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include +#include #include #include #include @@ -97,7 +97,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include #include #include @@ -137,7 +136,7 @@ typedef struct { #define MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE 0x100 typedef struct { - PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext; VOID *ModHandle; } IMAGE_CONTEXT_TO_MOD_HANDLE; @@ -162,7 +161,8 @@ SecLoadFromCore ( IN UINTN LargestRegion, IN UINTN LargestRegionSize, IN UINTN BootFirmwareVolumeBase, - IN VOID *PeiCoreFile + IN VOID *PeiCoreFile, + IN UINT32 PeiCorePe32Size ); EFI_STATUS @@ -194,17 +194,11 @@ SecFfsFindSectionData ( ); EFI_STATUS -EFIAPI -SecUnixPeCoffLoaderLoadAsDll ( - IN CHAR8 *PdbFileName, - IN VOID **ImageEntryPoint, - OUT VOID **ModHandle - ); - -EFI_STATUS -EFIAPI -SecUnixPeCoffLoaderFreeLibrary ( - OUT VOID *ModHandle +SecFfsFindSectionData2 ( + IN EFI_SECTION_TYPE SectionType, + IN EFI_FFS_FILE_HEADER *FfsFileHeader, + IN OUT VOID **SectionData, + OUT UINT32 *SectionDataSize ); EFI_STATUS @@ -228,7 +222,7 @@ GasketSecUnixFdAddress ( EFI_STATUS GetImageReadFunction ( - IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, IN EFI_PHYSICAL_ADDRESS *TopOfMemory ); @@ -273,21 +267,22 @@ GasketSecTemporaryRamSupport ( RETURN_STATUS EFIAPI -SecPeCoffGetEntryPoint ( +SecUefiImageGetEntryPoint ( IN VOID *Pe32Data, + IN UINT32 Pe32Size, IN OUT VOID **EntryPoint ); VOID EFIAPI -SecPeCoffRelocateImageExtraAction ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext +SecUefiImageRelocateImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); VOID EFIAPI -SecPeCoffLoaderUnloadImageExtraAction ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext +SecUefiImageLoaderUnloadImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); VOID diff --git a/EmulatorPkg/Unix/Host/Host.inf b/EmulatorPkg/Unix/Host/Host.inf index 550cb9f6e8..cae6ea0979 100644 --- a/EmulatorPkg/Unix/Host/Host.inf +++ b/EmulatorPkg/Unix/Host/Host.inf @@ -55,12 +55,11 @@ PrintLib BaseMemoryLib BaseLib - PeCoffLib + UefiImageLib ThunkPpiList ThunkProtocolList PpiListLib PeiServicesLib - PeCoffGetEntryPointLib StackCheckLib [Ppis] diff --git a/EmulatorPkg/Unix/Host/Ia32/Gasket.S b/EmulatorPkg/Unix/Host/Ia32/Gasket.S index 36197ff260..81c9fd2cc1 100644 --- a/EmulatorPkg/Unix/Host/Ia32/Gasket.S +++ b/EmulatorPkg/Unix/Host/Ia32/Gasket.S @@ -313,24 +313,26 @@ ASM_PFX(GasketSecGetNextProtocol): // PPIs produced by SEC -ASM_GLOBAL ASM_PFX(GasketSecPeCoffGetEntryPoint) -ASM_PFX(GasketSecPeCoffGetEntryPoint): +ASM_GLOBAL ASM_PFX(GasketSecUefiImageGetEntryPoint) +ASM_PFX(GasketSecUefiImageGetEntryPoint): pushl %ebp movl %esp, %ebp - subl $24, %esp // sub extra 16 from the stack for alignment + subl $40, %esp // sub extra 16 from the stack for alignment and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 16(%ebp), %eax + movl %eax, 8(%esp) movl 12(%ebp), %eax movl %eax, 4(%esp) movl 8(%ebp), %eax movl %eax, (%esp) - call ASM_PFX(SecPeCoffGetEntryPoint) + call ASM_PFX(SecUefiImageGetEntryPoint) leave ret -ASM_GLOBAL ASM_PFX(GasketSecPeCoffRelocateImageExtraAction) -ASM_PFX(GasketSecPeCoffRelocateImageExtraAction): +ASM_GLOBAL ASM_PFX(GasketSecUefiImageRelocateImageExtraAction) +ASM_PFX(GasketSecUefiImageRelocateImageExtraAction): pushl %ebp movl %esp, %ebp subl $24, %esp // sub extra 16 from the stack for alignment @@ -338,13 +340,13 @@ ASM_PFX(GasketSecPeCoffRelocateImageExtraAction): movl 8(%ebp), %eax movl %eax, (%esp) - call ASM_PFX(SecPeCoffRelocateImageExtraAction) + call ASM_PFX(SecUefiImageRelocateImageExtraAction) leave ret -ASM_GLOBAL ASM_PFX(GasketSecPeCoffUnloadImageExtraAction) -ASM_PFX(GasketSecPeCoffUnloadImageExtraAction): +ASM_GLOBAL ASM_PFX(GasketSecUefiImageUnloadImageExtraAction) +ASM_PFX(GasketSecUefiImageUnloadImageExtraAction): pushl %ebp movl %esp, %ebp subl $24, %esp // sub extra 16 from the stack for alignment @@ -352,7 +354,7 @@ ASM_PFX(GasketSecPeCoffUnloadImageExtraAction): movl 8(%ebp), %eax movl %eax, (%esp) - call ASM_PFX(SecPeCoffUnloadImageExtraAction) + call ASM_PFX(SecUefiImageUnloadImageExtraAction) leave ret diff --git a/EmulatorPkg/Unix/Host/X64/Gasket.S b/EmulatorPkg/Unix/Host/X64/Gasket.S index 030faa8e4c..006faa95d0 100644 --- a/EmulatorPkg/Unix/Host/X64/Gasket.S +++ b/EmulatorPkg/Unix/Host/X64/Gasket.S @@ -358,8 +358,8 @@ ASM_PFX(GasketSecGetNextProtocol): // PPIs produced by SEC -ASM_GLOBAL ASM_PFX(GasketSecPeCoffGetEntryPoint) -ASM_PFX(GasketSecPeCoffGetEntryPoint): +ASM_GLOBAL ASM_PFX(GasketSecUefiImageGetEntryPoint) +ASM_PFX(GasketSecUefiImageGetEntryPoint): pushq %rbp // stack frame is for the debugger movq %rsp, %rbp @@ -368,16 +368,17 @@ ASM_PFX(GasketSecPeCoffGetEntryPoint): movq %rcx, %rdi // Swizzle args movq %rdx, %rsi + movq %r8, %rdx - call ASM_PFX(SecPeCoffGetEntryPoint) + call ASM_PFX(SecUefiImageGetEntryPoint) popq %rdi // restore state popq %rsi popq %rbp ret -ASM_GLOBAL ASM_PFX(GasketSecPeCoffRelocateImageExtraAction) -ASM_PFX(GasketSecPeCoffRelocateImageExtraAction): +ASM_GLOBAL ASM_PFX(GasketSecUefiImageRelocateImageExtraAction) +ASM_PFX(GasketSecUefiImageRelocateImageExtraAction): pushq %rbp // stack frame is for the debugger movq %rsp, %rbp @@ -386,15 +387,15 @@ ASM_PFX(GasketSecPeCoffRelocateImageExtraAction): movq %rcx, %rdi // Swizzle args - call ASM_PFX(SecPeCoffRelocateImageExtraAction) + call ASM_PFX(SecUefiImageRelocateImageExtraAction) popq %rdi // restore state popq %rsi popq %rbp ret -ASM_GLOBAL ASM_PFX(GasketSecPeCoffUnloadImageExtraAction) -ASM_PFX(GasketSecPeCoffUnloadImageExtraAction): +ASM_GLOBAL ASM_PFX(GasketSecUefiImageUnloadImageExtraAction) +ASM_PFX(GasketSecUefiImageUnloadImageExtraAction): pushq %rbp // stack frame is for the debugger movq %rsp, %rbp @@ -403,7 +404,7 @@ ASM_PFX(GasketSecPeCoffUnloadImageExtraAction): movq %rcx, %rdi // Swizzle args - call ASM_PFX(SecPeCoffUnloadImageExtraAction) + call ASM_PFX(SecUefiImageUnloadImageExtraAction) popq %rdi // restore state popq %rsi diff --git a/EmulatorPkg/Unix/lldbefi.py b/EmulatorPkg/Unix/lldbefi.py old mode 100755 new mode 100644 index 952f8bf982..85be276d10 --- a/EmulatorPkg/Unix/lldbefi.py +++ b/EmulatorPkg/Unix/lldbefi.py @@ -361,7 +361,7 @@ def LoadEmulatorEfiSymbols(frame, bp_loc , internal_dict): # # VOID # SecGdbScriptBreak ( - # char *FileName, + # const char *FileName, # int FileNameLength, # long unsigned int LoadAddress, # int AddSymbolFlag @@ -394,7 +394,7 @@ def LoadEmulatorEfiSymbols(frame, bp_loc , internal_dict): debugger = frame.thread.process.target.debugger if frame.FindVariable ("AddSymbolFlag").GetValueAsUnsigned() == 1: - LoadAddress = frame.FindVariable ("LoadAddress").GetValueAsUnsigned() - 0x240 + LoadAddress = frame.FindVariable ("LoadAddress").GetValueAsUnsigned() debugger.HandleCommand ("target modules add %s" % FileName) print("target modules load --slid 0x%x %s" % (LoadAddress, FileName)) diff --git a/EmulatorPkg/Win/Host/WinHost.c b/EmulatorPkg/Win/Host/WinHost.c index 9a5201f4d1..9cfeeef693 100644 --- a/EmulatorPkg/Win/Host/WinHost.c +++ b/EmulatorPkg/Win/Host/WinHost.c @@ -444,6 +444,7 @@ Routine Description: BOOLEAN Done; EFI_PEI_FILE_HANDLE FileHandle; VOID *SecFile; + UINT32 SecFileSize; CHAR16 *MemorySizeStr; CHAR16 *FirmwareVolumesStr; UINTN ProcessAffinityMask; @@ -451,6 +452,7 @@ Routine Description: INT32 LowBit; UINTN ResetJumpCode; EMU_THUNK_PPI *SecEmuThunkPpi; + UINT32 AuthenticationStatus; // // If enabled use the magic page to communicate between modules @@ -648,7 +650,14 @@ Routine Description: &FileHandle ); if (!EFI_ERROR (Status)) { - Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SecFile); + Status = PeiServicesFfsFindSectionData4 ( + EFI_SECTION_PE32, + 0, + FileHandle, + &SecFile, + &SecFileSize, + &AuthenticationStatus + ); if (!EFI_ERROR (Status)) { SecPrint (" contains SEC Core"); } @@ -679,7 +688,7 @@ Routine Description: // // Hand off to SEC Core // - SecLoadSecCore ((UINTN)TemporaryRam, TemporaryRamSize, gFdInfo[0].Address, gFdInfo[0].Size, SecFile); + SecLoadSecCore ((UINTN)TemporaryRam, TemporaryRamSize, gFdInfo[0].Address, gFdInfo[0].Size, SecFile, SecFileSize); // // If we get here, then the SEC Core returned. This is an error as SEC should @@ -695,7 +704,8 @@ SecLoadSecCore ( IN UINTN TemporaryRamSize, IN VOID *BootFirmwareVolumeBase, IN UINTN BootFirmwareVolumeSize, - IN VOID *SecCorePe32File + IN VOID *SecCorePe32File, + IN UINT32 SecCorePe32Size ) /*++ @@ -759,8 +769,9 @@ Routine Description: // // Load the PEI Core from a Firmware Volume // - Status = SecPeCoffGetEntryPoint ( + Status = SecUefiImageGetEntryPoint ( SecCorePe32File, + SecCorePe32Size, &SecCoreEntryPoint ); if (EFI_ERROR (Status)) { @@ -784,40 +795,47 @@ Routine Description: RETURN_STATUS EFIAPI -SecPeCoffGetEntryPoint ( - IN VOID *Pe32Data, - IN OUT VOID **EntryPoint +SecUefiImageGetEntryPoint ( + IN VOID *Pe32Data, + IN UINT32 Pe32Size, + IN OUT VOID **EntryPoint ) { - EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + EFI_STATUS Status; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + VOID *Dest; + UINT32 DestSize; - ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.Handle = Pe32Data; - - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)SecImageRead; - - Status = PeCoffLoaderGetImageInfo (&ImageContext); + Status = UefiImageInitializeContext (&ImageContext, Pe32Data, Pe32Size); if (EFI_ERROR (Status)) { return Status; } // - // XIP for SEC and PEI_CORE + // Allocate space in NT (not emulator) memory with ReadWrite and Execute attribute. + // Extra space is for alignment // - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data; + Status = UefiImageLoaderGetDestinationSize(&ImageContext, &DestSize); + if (EFI_ERROR (Status)) { + return Status; + } + + Dest = VirtualAlloc (NULL, (SIZE_T) DestSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (Dest == NULL) { + return EFI_OUT_OF_RESOURCES; + } - Status = PeCoffLoaderLoadImage (&ImageContext); + Status = UefiImageLoadImage (&ImageContext, Dest, DestSize); if (EFI_ERROR (Status)) { return Status; } - Status = PeCoffLoaderRelocateImage (&ImageContext); + Status = UefiImageRelocateImage (&ImageContext, (UINTN) Dest, NULL, 0); if (EFI_ERROR (Status)) { return Status; } - *EntryPoint = (VOID *)(UINTN)ImageContext.EntryPoint; + *EntryPoint = (VOID *) (UefiImageLoaderGetImageEntryPoint (&ImageContext)); return EFI_SUCCESS; } @@ -951,7 +969,7 @@ Routine Description: --*/ EFI_STATUS AddModHandle ( - IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, IN VOID *ModHandle ) @@ -1028,7 +1046,7 @@ AddModHandle ( **/ VOID * RemoveModHandle ( - IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { UINTN Index; @@ -1064,8 +1082,8 @@ typedef struct { VOID EFIAPI -PeCoffLoaderRelocateImageExtraAction ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext +UefiImageLoaderRelocateImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { EFI_STATUS Status; @@ -1103,7 +1121,7 @@ PeCoffLoaderRelocateImageExtraAction ( // Load the DLL if it's not an EBC image. // if ((ImageContext->PdbPointer != NULL) && - (ImageContext->Machine != EFI_IMAGE_MACHINE_EBC)) + (UefiImageGetMachine (ImageContext) != EFI_IMAGE_MACHINE_EBC)) { // // Convert filename from ASCII to Unicode @@ -1117,7 +1135,7 @@ PeCoffLoaderRelocateImageExtraAction ( free (DllFileName); // - // Never return an error if PeCoffLoaderRelocateImage() succeeded. + // Never return an error if UefiImageRelocateImage() succeeded. // The image will run, but we just can't source level debug. If we // return an error the image will not run. // @@ -1316,8 +1334,8 @@ PeCoffLoaderRelocateImageExtraAction ( VOID EFIAPI -PeCoffLoaderUnloadImageExtraAction ( - IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext +UefiImageLoaderUnloadImageExtraAction ( + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { VOID *ModHandle; diff --git a/EmulatorPkg/Win/Host/WinHost.h b/EmulatorPkg/Win/Host/WinHost.h index a9a21007e3..bad2fca5ce 100644 --- a/EmulatorPkg/Win/Host/WinHost.h +++ b/EmulatorPkg/Win/Host/WinHost.h @@ -21,7 +21,7 @@ Module Name: #include "WinInclude.h" #include -#include +#include #include #include #include @@ -35,7 +35,7 @@ Module Name: #include #include -#include +#include #include #include #include @@ -44,7 +44,7 @@ Module Name: #include #include #include -#include +#include #include #define TEMPORARY_RAM_SIZE 0x20000 @@ -61,8 +61,9 @@ typedef struct { RETURN_STATUS EFIAPI -SecPeCoffGetEntryPoint ( +SecUefiImageGetEntryPoint ( IN VOID *Pe32Data, + IN UINT32 Pe32Size, IN OUT VOID **EntryPoint ); @@ -72,7 +73,8 @@ SecLoadSecCore ( IN UINTN TemporaryRamSize, IN VOID *BootFirmwareVolumeBase, IN UINTN BootFirmwareVolumeSize, - IN VOID *SecCorePe32File + IN VOID *SecCorePe32File, + IN UINT32 SecCorePe32Size ) /*++ diff --git a/EmulatorPkg/Win/Host/WinHost.inf b/EmulatorPkg/Win/Host/WinHost.inf index b123ea9dcf..3a4adcb711 100644 --- a/EmulatorPkg/Win/Host/WinHost.inf +++ b/EmulatorPkg/Win/Host/WinHost.inf @@ -49,7 +49,7 @@ PrintLib BaseMemoryLib BaseLib - PeCoffLib + UefiImageLib ThunkPpiList ThunkProtocolList PpiListLib diff --git a/EmulatorPkg/Win/Host/WinThunk.c b/EmulatorPkg/Win/Host/WinThunk.c index e1b158c2da..257046d0aa 100644 --- a/EmulatorPkg/Win/Host/WinThunk.c +++ b/EmulatorPkg/Win/Host/WinThunk.c @@ -592,9 +592,9 @@ EMU_THUNK_PROTOCOL gEmuThunkProtocol = { SecAlloc, NULL, SecFree, - SecPeCoffGetEntryPoint, - PeCoffLoaderRelocateImageExtraAction, - PeCoffLoaderUnloadImageExtraAction, + SecUefiImageGetEntryPoint, + UefiImageLoaderRelocateImageExtraAction, + UefiImageLoaderUnloadImageExtraAction, SecEnableInterrupt, SecDisableInterrupt, SecQueryPerformanceFrequency, diff --git a/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc b/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc index 3155812118..4fbaf8efd0 100644 --- a/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc +++ b/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc @@ -90,11 +90,11 @@ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf index 4e8b618513..37db0a5a21 100644 --- a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf +++ b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf @@ -39,12 +39,13 @@ BaseMemoryLib UefiLib FspWrapperApiLib - PeCoffLib + UefiImageLib CacheMaintenanceLib DxeServicesLib PerformanceLib HobLib FspWrapperPlatformLib + MemoryAllocationLib [Protocols] gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c index 97723aad65..1a1d052b4d 100644 --- a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c +++ b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c @@ -11,11 +11,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +#include #include #include #include #include +#include +#include /** Relocate this image under 4G memory. @@ -37,9 +39,11 @@ RelocateImageUnder4GIfNeeded ( UINT8 *Buffer; UINTN BufferSize; EFI_HANDLE NewImageHandle; + UINT32 ImageSize; + UINT32 ImageAlignment; UINTN Pages; EFI_PHYSICAL_ADDRESS FfsBuffer; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; VOID *Interface; // @@ -83,43 +87,34 @@ RelocateImageUnder4GIfNeeded ( &BufferSize ); ASSERT_EFI_ERROR (Status); - ImageContext.Handle = Buffer; - ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; // // Get information about the image being loaded // - Status = PeCoffLoaderGetImageInfo (&ImageContext); + Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize); ASSERT_EFI_ERROR (Status); - if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) { - Pages = EFI_SIZE_TO_PAGES ((UINTN)(ImageContext.ImageSize + ImageContext.SectionAlignment)); - } else { - Pages = EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize); - } + ImageSize = UefiImageGetImageSize (&ImageContext); + ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext); + Pages = EFI_SIZE_TO_PAGES (ImageSize); FfsBuffer = 0xFFFFFFFF; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiBootServicesCode, - Pages, - &FfsBuffer - ); + Status = AllocateAlignedPagesEx ( + AllocateMaxAddress, + EfiBootServicesCode, + Pages, + ImageAlignment, + &FfsBuffer + ); ASSERT_EFI_ERROR (Status); - ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer; - // - // Align buffer on section boundary - // - ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; - ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1); // - // Load the image to our new buffer - // - Status = PeCoffLoaderLoadImage (&ImageContext); - ASSERT_EFI_ERROR (Status); - + // Load and relocate the image to our new buffer // - // Relocate the image in our new buffer - // - Status = PeCoffLoaderRelocateImage (&ImageContext); + Status = UefiImageLoadImageForExecution ( + &ImageContext, + (VOID *) (UINTN) FfsBuffer, + ImageSize, + NULL, + 0 + ); ASSERT_EFI_ERROR (Status); // @@ -127,16 +122,11 @@ RelocateImageUnder4GIfNeeded ( // gBS->FreePool (Buffer); - // - // Flush the instruction cache so the image data is written before we execute it - // - InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); - - DEBUG ((DEBUG_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", (UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.EntryPoint)); - Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint))(NewImageHandle, gST); + DEBUG ((DEBUG_INFO, "Loading driver at 0x%08llx EntryPoint=0x%08x\n", FfsBuffer, UefiImageLoaderGetImageEntryPoint (&ImageContext))); + Status = ((EFI_IMAGE_ENTRY_POINT)(UefiImageLoaderGetImageEntryPoint (&ImageContext)))(NewImageHandle, gST); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status)); - gBS->FreePages (FfsBuffer, Pages); + DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08llx start failed: %r\n", FfsBuffer, Status)); + FreeAlignedPages ((VOID *)(UINTN)FfsBuffer, Pages); } // diff --git a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf index a0f384f992..6b0b422773 100644 --- a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf +++ b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf @@ -38,8 +38,8 @@ FspWrapperPlatformLib FspWrapperHobProcessLib CpuLib - PeCoffGetEntryPointLib - PeCoffExtraActionLib + UefiCpuLib + UefiImageExtraActionLib PerformanceLib TimerLib FspWrapperApiLib diff --git a/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf index a7b28e56b5..bc5be2f4cc 100644 --- a/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf +++ b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf @@ -39,8 +39,8 @@ FspWrapperPlatformLib FspWrapperHobProcessLib CpuLib - PeCoffGetEntryPointLib - PeCoffExtraActionLib + UefiCpuLib + UefiImageExtraActionLib PerformanceLib FspWrapperApiLib FspWrapperApiTestLib diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc index f51e1c89f6..4276859e72 100644 --- a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc +++ b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc @@ -27,9 +27,9 @@ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf diff --git a/LoaderFlow.png b/LoaderFlow.png new file mode 100644 index 0000000000000000000000000000000000000000..323e1b9aa36ef596509a07b2665d0d7d0c9ba110 GIT binary patch literal 218450 zcmeFZcT`j9`Ua{9hzckwAX3#)RC<>VA~1@8O0Q8m(g_esARwbCRYas03%!Z-mVihP zgx(=Y3%!RxD7jzeoS8E-XZ)S}&t2>OF>C2^6LVNiPF_5DZe3HZ{8=Y>|0UP;o0;crA5oq^e?E)i1zpQ#C?_uLatUJ)vB0lRF39Mw&HT8JW8|Nt~Y0hvd_#Zj? zgNx2ODy#X4fz^!@|L1KA{tB14{8tqJuSfm*7KTgyD?!wNZzh3z|V1?y>4&9wXxKsAT|5#N81?o!cA20g9=hAzk zS%L7=|5*1UM_K+^EMUC8nKhWVH=)n8UJehHf0nh!^?4!KQP1C%K_4>)kRi&d1d2Lm2T^pIx!dR z-(0zsa$g`_m^S2Z*E}|osxgd}`CyNb5-Ctuaqi!nk)Gp!X*7ce75Li+|3;O6wQdC; z2H;Twu&-W!@ZZ1V>uTK?&nTqi@6&7iaE||a^|G?Uk(!#(6S#kcz#qI9czKUbYMYyE zb6 zp5Z;>?z4RMm?<3jA!P7e!Riw^no;!0fDs;rz3ISg#e-37d)s=o2J4l@>rk(g%)n{Y3qt%-0F!Jl(4?i)TqO!T?6G^A1B9-uSQVm8ea8A zqZB?KAP&2Z3%Pv#C4OYnvxqP!seE)_KyHPZQx<=Rw|pa8$S8tCY%fXB(HOqIt}0e$ zIm4S&^=(PkN2RO+XIrf9ctOa`dAjYmS6Gx?!g5pi&P{66t_rQ!V%W94lE@?>ZCU@3daOu8>wj~qsr1bLHMNSttx1=0B-=d|(S0R{)7{_vP6<_gOq~DSrq=8SB z%{UiRwX{)K_ps@ku#po4Ra5MIfUIhIc_~mWM+}8CaLpQAcw6*gbvOz$%&|6!m|8u) z!k#1r3s)Z4Q?VyTMVTRIbTj890&#lwWnRiAdC|Li`Zr4DabM?ZwuDQ>n?A#^S#6`M zy*HTjU1szb{gp1O9?9fS@m(_=^__Hy#Jv-^c%71_7!lA2VSY-&t|6F8K zHb!u;V<5iDGJ80+oYFfMy1NOmF}a}$uifw~LG-Uk`}mFK?`>^uP(5QNO^EkH<+WM;vD(gYA*O#Fx&3M5}a`4H*@|k9(_!>?3dc^|NMG212 z*0h{!ck$`1_`6YN6FCA+N!)B&79>5#P|v0PqK_m5>58W*oq3XiG!uyAO%hF64F9!p zWW0Bek^`~7o{49XN6z#1+>m@xN=bvhMbQWS1s7+nP?>i1Se??iUy&c7Y^5^KuOjO? zx|(CBRZU&Y)^+5ULi4FoP7VeL-NiwRs)ew6`Q2M8bgYIZV@vo*rJzQWCX%38_b036 zsDQ174KLK`oSfWqT%8?Ml$|5Hbgth2S+?I|IrzjTzxMSdrOC7y)2C~;D~H1jT!PRO zp{$bGbyVu{=+Db^9+}zKPoLGiD=3FkPKke`^iAG*p+#%70k}qnXUYbwmbRf5=D;)8y?2;Dz0rCXv(Rg-e>3|S?jze}oBz8D;=dJ1P z2w{vd5DWLc2TNGk)--lAorbTTJW9c?1k!`~sI}hRAEt-crvY6MxapRV+x$ zW#Ij`>(dRmCcR_Fi!BID%bPP9$ACkxICLRBE`zt9n-iW&`XX}e?{e+GB1tRzFS! zDnKLU_qg`Qi>m?n0SKyiE&+TfQmv5EH;~9b@OhA$wV{mUY9ix1ue?4;g}WaEb$&oW znV#Z*gt%1%v-sN)7H8K|oZ{`wK9~;$59`r-oYh{M$R7kTi{eXfb76mbBw+i}V;aJ? z3uhwL54Y35mPGk(#IY&XIxB5t^ds(>uUWM0w&UiM6c@|;nJ({t}G~y=zR**hQ=VV zg!`=>RqryewX@`lW}r=*~cecLN1a!9_dH ztpk1gz_5if11^PB^OLd1YRt!BdVgE4{W@wJJ&Gxn@R#J!MUtCgUhn1f8@PrOx1IcU z0YCJ4XQC@;k~3(D*=Y=FoxnDr2%-RrTu%|kZ;AY^agb4|LeP27h3*iutu=w+?O|^9 z;Gm8j_lD{v2Oo-X6@LXEa!q&|Rwwy?AlTkh_b*6`kNZv_iTF~(osFKOAUl(Kbc3L5 z6qLj7{f~G{SKrWh^+yZ;Q_Sk@q9V#3OuJp0BW#`PnJKqbJ*xei7J&Yqzrr4Q44i~I zga2a;Z%@ECQmm(*+ZBX@<$0tlz07>ProXf)VOwvShLYy~D}|UFwz+&i+p8%a_mfnrhH>`L4I4&bti`+L1nPfM4j^a{xNxFJYW=AzTMmr=VoUmn|jKkGWt zfkb}ia5w*wDsXLJFLKAQG8sRH@;3J$cYk{EaAnAQ%O=;WXrT(fpi|5$@9kDJteKGyRlqj{w+0N-HL~EI>e8&A*qS9mIoRPkR#?`TR+K45FQ*|!h;620Dd5?l`$MR{~mBkl-KLJCXiL{uf*1zPJ zPX>3TT@A?Am6c8cDN&ZvbZ4Zmu-Thco6UR59C4OYc2^%5bLj_UR0)nt|3~XPv^Ed0+6@4FUEC}vf8-k_1W`AjCh{hYh>P}TY1J?0 z%X@*qQ>+Gb3d>sBey4uHZ9@1`tt`@~uPzd;e?2p5pWP(C%t`K=Q+o;_za z@6S1#5yr|yw~^)}}L7xJR$=W2tVwj`;BdsT30 zVt$Qjpa*uR?zDNnGLyptZ0ZNCjJcxWi-jYWddh_H8Xob8-7o93TkiC-GFHp|H6MI& z2G(Kh7?KjY!WkP(%ra@I_#QK6wMRW>@BLN4tfjrwX1#ioPD)$RzgCplX2j)Y`tHoF z-*z7a)7+Zv;q|2=jJVf2DE^_N9wQFwrG=5d-SO{S6}wBR;(KT?x;9p0RwdFAc2#`r z!y$#pF*ugh@fAj%$VH9ZaD|I`KKS$$#5 zJYY3yuHEa;NIC~aOGCCyz2oLUyoguFnZjFcO|Jx*uNgUgi%Fq>x&Be5;oFI+#SxEW zhwTp$wBwlmkE*`DySKfliO+I!ne6-s6U|=ZID@BgvC#L=+Ye$vWnR*PmZ9UZ_-<6=U;#21#HF)= zb_3Mj7o zgVSGZHZ|}>=tXf+N4ce1{U^9Fv$0inhE4t=;~IqmW#)+e-kap~#GGGsGr4m5!v*Qd z97FYsz3y=}cJ1~{)O1&Z(Mz<`n)A*pX~;(SuBEMzH(#axG~0YTU)(`*3izID@Ub~^ zMlUK5!f->5%vE&|pBEkRhOWN$piGY-;~W>5_P@uZkaMyc-)~gdZ)m3+!*61?*)9>$ z#$UzDWMp5cEBm73xB2}$)da9WCh$g1;rm-AK4bcB2XyA|#Rgtg5c$uV_~3(wW@E23 zhF@TS_)38-C%VFSrl;0BYG8~?WtuI~5f_ASb(kPol!`R(X0+SvHL{lhwD@7mXSQYD zHO#@qAzU%_BRPU@ao6I>oDe8dJ*UDX%qnJ(eo35RJ&*5E>FPgu-W&lSRY1!L`2MI!BD~mOpGP+L z*CHf9_gwkjN|kx{r@IZWhr`^5Q3%q`7yH<(4UZ%#_h84d%7)vg_|Cr==Z`5IWeea= zfeXtK=RWGYb(JDUsw8n40LuTKhkH~W4_U?}iL)<8|Jy}66)7n@rJKV%;>b63Zc{X| zLGQbC%J~w%MXGYJ#0icO@UcRoTlZa;cCmrt%(5r-FB%wB*%+)7T~tE0 zQ<$WEfrTo2_*xC(tm~+l6Pbd#xc@Nz-zNetY_tH@6QA)ABu{UynF1pt;tsucu#c0E z@L8$IxN@%2<3AJs;}^LE)xr8^+$iYyHMiCdP+U#xh4ynI1=oQ=>B5JzfU?~7MPp__MY0WPwwQW9QWH>-svmw>*McexcdXF6cBe8 z6mM3Q3HiU;la*9}*K8d33tE=5ppRm`R6Z3hGKP=l&(te0E$mWZRmLKH%~vXL;qR4# zR7i&hQ()^~eXkFSiC4$N2J%hJ7xT)(E#DbjliQt+DxZ00WVSWe#kTw6QUvFSuANN^p(9)Fc%Vy$} zyZiTm`|&kUho`)9%2&HWPE9P3#|QX<2#q8uvBlf;GHbOUzw=xh@pyIh-OJN*JE_RA zPj{mhV(j>~mWGOG=z+T}m54LDAETzttZ*P55F+gIE7E66bB!GJG{eAfB%k8t z9Y@Q_t~CXmGgJ@aTcRl6CV+xh9}*Yo7StG3IlL^4U0bdSwec2xi$Ls8-8$Tv3aNFo z-LosGVPbVGe*y=#>H|7_ zE`zt)e$FclreZe!e5-8Lk5I*k(;JuLb1eV<;@0u z3E|@C+P4--sI6`_7vRsz)IN66=+eVwCxj7YNLv}idp@nJ0D{`cHj@l2M(osc8YaFU zORdiiHjj`MHwC*e2re!M*5i_W9G5=V(-*c}OZavvi0v#!o&-lrE#?;XXh<_I(@QUX z&gQtR63)irH5O(W30oPJ6b>OB?yW`?bx7qXI(s)T>V>B4Pjf4yBt;LKI1!^07Yrf~ zEDX%U#3r9Jo4&jfe(QtPn#_oW!r}KI&T!gbiHxN$ZT#zvtWI~lr`u>HWe^vq3qjH@ z^IWSt9^%+NDUIFLhJh?S zxwI#>TD=)ORSlMrak<~fsmAQ!QiT1#YuWuF&m#VSPks{&hRHi>V-{W*{EyV z&ItBU7q#~xgx|3G`a{T*fWM8;l!k!jsp-4!eg`;OBb9KQ7|z`>d)m0^WWf1mWtP7(~Z&RbUOg2E5+_Mt3ZglIAK+dNps8GLb3THRMiUvs`W}@|i zHS^y0ZtABk&tN4HF!$ZUO zNW^#FMxK8ya9SJ1_PVKM!kfA?LVBfql1-%C#1zmj`ba}smK4RMjW?S~xCa}c3v9<* zG5x0D6m=Qa&xhd_3fR@+s@|>~3oT}e(0GrYCx!6o?O5{iQ_FX_-I)hlUJ$jJ1nj<* zkfyion8fcP_D>hZ;h>UTytP0Moa!e>;hXJ3_Jf}<+;V;_^pi({X-&MnlX(-vEnFh> zCIv>)$%8t8(`!2NGEa5dSr)gBCH#qV*Lq=v8?8J|7{Bcz@{~X%oLtB$;HRhn!Ny5u zZ>cCvJ?}8-=nR&0NWdS=y1J*L{LJsbw}-6p26F}}al=6z-ZoxQ#2JPwD&L?OSv^$p zDX#+~hY}qjw2!S4JuAfYspTT>%+kzNh)lC&H&lbLFP+c7`$dsn2*MGX;!rvi{CzZM z9u0X2z!v{xT|n% zP&5Op{bxn{FD=)?O543)dSr<9-Z|lBg=~=kY}hs*Q8ewegh3o`dQJo!pVUJUb+U#; zcRLo*%s=0|TGVDocN{WoN?ZX*!nSb7)V)vV3QpWfBg--tnz{-ALIdL520S}(ri92Y z>+QyHr=TRSI^Ww5pKdzb3T=yFx_1@gd5g5asg^^B++=H2)2gqJDJ%N#9-rVcr4&ZW z&i-%{(sVl6?*@GZp-X?=s7k#ma6axxfH;GV)a2l`j0rAw^~d#e5}~S`zQq?hq>2u$ zQhc|mDJ8X6=p;rT(3OhpW^xt16AKn^!znk&5a2&<3I>VRxgh=}5$Vz$dEilY{uX!rweL{YIxou=0= z(IC^ric_$%9Zcy%Nr4|0jcYy(df$NG8#q5ZVz6ravk@=LLSGMcx0`$Nxrh~eG^xEG9aDOwPUer6>vWb-8~?qk{D``veq;FCEuPf@JTD)EoPsy9x>!+H0RT9DQ_?T{1KZmrA9z z`wgxrJbrODlNIIuLdud`y68kM>X1msZwnHw(}RK0VDv=W`(d*Gn#It5;~_8LLn=ow zx^&!qB!wYor39jEVwVqJ z8?1NfdB0a?6+?{Iph&X&>7F{9w4+o~Sp8Y9&WmJTU+E#I*45XWiFz?vbfMF0-_nG| z>UJJ+A_3GAtfAxpc~)1_jh+fod-V9XweR&jM58Cq8E^Jy%-o}X-qr>xw}(O>?(7<` zMH%@4klb1of8!kp{~fp1YLA6HJTA;b(nJuorV;i0m2)2kEuz#Xr=v9U%RAVTA%CT~ z)5B{0V@zLyR@S9!;hfmHqm8tj9QEUfvM$V;rd;^Cd8240icTb`7PL`xye>suYe;}$ z9|Dd9fZ%%y)I?hMsziGz)jJc9p%3%G?AXVuU`{KJpzouQI(A}O<~xgm?{djNI&svM zz8aT;K+2txl^z9P&x{O%a|)2&*?TF*$NN}%Wqr02NBP;!_MV;M*S~M=I`||=c|Pq6 zv#IALzs&^f`TC`pQQ>nn)uHUtrSLxCKcz@eCk9g#jJhdJTlYJTnO7{sg4M%G20#l1 zYhW0!UMwwNjp5eq)hTdGcJJ4>jPNxpI)`AX$VI~`PA7TYb4#%v*LUq{Hy_Q6Twfc? zX!2)HN!jJ^Wn`FB0N{>&&I!Ye_rTxG?|JwW4U&l>>c;xm`&!dsW z`djA1kHPN;Ssk`ebn^S(Plrr+QCkBLk0;JDL*OpJ{;x#V5p4}#(6Q=v`Kkpu70g*s zLxw=@G(`?A-H9tKyrdRQzq4SK`~oFAa#XD&fsP6b&(Qo+gG1yO1?oE@ujK&yKDZqU z&Dcrg4rOH)Fox;C*ISwj+c^0n45UuA-4~h^9e;Ajs2hAh+I4603cu;x;E^D)mnnI+ zPX4sKpw(j6mBz4(j8WO?-|ak9F9OqaB=uET+0CdpgP&UT2Sb*}Y-kA)+?@f1pM;t6dLcaGd@?_NAcK7!K^+-hb zDb1b<=VfG@j-E+Lv!DPKX7d*)4FSN2GQ~BSvYEv78Ra82#`S;P(yIXgtl#Q4uuh^* z>Gr^aV0V9_CkA3O6iymhJP6`^$?YdGb95(5Dl=(B`!Q%WpGYptDi36c^`J0ykM}6` zP7bF4LK7pGEdwjt8rYr22u@B-S-dub8*ws3;PNpIo`Pyu`{FK@he?dL*ac*Tjqo6; zg`fqO`}2$}Jf;AFp}qMQNnFUeAmwI5%Od=#{6(LxQJz&*f98D@36%5=UY1Nx$3HeO z8S#=avpxuOmyapN-K_%a(*Vk^zKcQjx}2QwHANRwPQ<=TD2vFoSr9(;K>=qTNGEP{ zCikgskY$)_CK$c17?H3F*@`Ay3XBEC-F*X|5K2S-H3W%(XaK!{L$9bL3;%6Uql6wk zMty!W6<2gPw(2M0%CY|Ffd`mp2>JnP;@PSACA+8Ma+_!oIu8uC6O5`v(N{IInfW3) zSrXN1K>aWkZyI9rcHL;4^ThWJ&xra!4KqUibcWznF zg&r}+u6Gmti1X_$+$p{GUqBJX6fi^P=t_sI5`vF-SB?YY6C<>>`fd+p>}X5entrV` zxzQ$2ke?4hE#_AR`}-p8Ukk8n$B^roSY{#_J)r@e+n2y(3Y!d8{p3&MJCjp zr)9S~FG#vtv@hR0A*#xSV5Yw{;s3!_>*yBX2O5CU>r{V!Q?~$$q1-_nShHX<@bm+I zGQi1?8|^@a?N=ptcPBEx+Gt3I2c*j^!pp`y5+;w3EtLbPTtbaEB+|X7{ehn$Thy|} z`P;+Br!~a?+SOQA;R@RJTR4phNfIDxRY`Jl{|c(0rzwp3vpj$ggI>6#DNq5x@*EA*_;EKo6g>0Z;Np%>a30L5Hh8@~ zjw$k`ZWGQCRilO-r@N?a@&4U$4Adx(%hgJS%or$(d!)$u2FqoWFyCIC%gI?7*c=s3 z*l)fP!TSss=j+?0%-p~Z8)X1*l%I?>55FP2E21TRtiwQ<$ItMcXft{QjYe#BsfMIZ z0>9T8MO6pIF~kqVf25tR?j-XdGJxi5mr7d_7$GfL%kwHpUp=C`e(B4IA^H* z!Mvt&d&2Fi#B(?ihv2nLQFTV#3%03rx=6Ov^Py?+O18DJW5+<-FMWbiLss^=OqVHP9fHBPsbkf zzDFcVE^vU1+D6@a)Em}T7{i|CPCL)Wy*~h`QMJRQ8icn#n?6q+>J`_)IbIfC1c>ib znIFS%J{$1L_mYj9kKYuEx#xaFwrI1>q+j1W>`~98bdhyiSkw*`J^;gzl8(!R;iv<=6>C9mwY zbe-C`B`LE_KoV*uSz4vi%un`uKj9XM%qX6wVVt>QGkuD)yOu`vEx}8$-}94 z4?Wo3Iu#pMm2Ay5a$Y0OsYiE*NY6O9%5BfS-Dht_H9TsWXWLkEZJu|`bmS2EHrmdovTTggXFt9VO#uvb#0SV0ac9ByuL5FMG=Uqq@C0mPWwKgXJ8p^Hn+F28>GgLleB!Dzx7oixhLQ_hdw1r&7l<~ z^12L!SSDzuwQo3+Gbo$-i|++~jF7AJjJ#BYhz`H{T1!qlhV6;jy?cjzxR-P@7{@%? zt;9`!$m15?8Mxo()p*0Jh$;T+wXe6f2hA5HNDF$Xn}@m^S6>@m-D8vSbVkbq=~TjL z`Te!aRn`3=ckp4CFC%!0NQvVgv^ONgM0z%Bt(h6VVVP%m74plV z`+y0LxH|ttau`%QVB?V-+|R29WVJu-^5bC|H~~Vq16oKSrv~)>hS^dXy_3?^V)Q-p z+ymZ~$Ni=SFwcL!*T}Zn!ECM?`jSEEIDm)A5d!k;f;y^XWr{h{GA4rK)b^_mlge++ zPwLG&7Yn|n4nW$TJmelBSLd#Mn~*R~SdtTY8rV_P&UC7v!eeWx z$QdoPS}pWsY4C!Og)^=9LEnY#@v5HbFJz1cT9}ULn!&SOX?A5~wZ$Ci>!#3jop1q5?l*D7Ax*9N(imbj01b<> zA`?37+BX672!F*Dq=w-dCi7&-tiE?pPdsgK%suMWc&QAu6y~uteOJoWAY_OC7&WW? zgM|+}9Y+QMX~GT)?d$?f?oLaM%~}X#{{zi4dH|~YumS z{6PxxOS4b%l@FjkKxBHp*s#om7v4}knWfWxDJnB=`V{8RO<)E;!s=#q0Q(_?mB-;1(I=7A5wb zzNZ9no?n&K_91o+;SxoVF4IDVlVu(}6uo_WvqT`F2$6=c9np?Ui}7(1kB^Z6mg>h zKUrpP{y}ae=|PW{^P%NP`()8+RyrtbwX7SbpgSy3bLcY`z5Z1U z5q4s#F*=(SzUn!?O0M{xK1g8%63s9*@m$vLVvwH)*XE|o(o6_1`Aw?CZAdMfn1(TV zS#deiTp;y`_L(^va%K0OzpAn2q=l|CwNLA@IZ3pKdEMrc;4x{I$2T~2WpOh}{b^Ej z35vLl2`>$pC2i6ss?u6K*PW?A)xO2;Au?V z=mHm%IwI#-^Df~by8?z;lMGugXC_^-d;8_{CRG49rBk)@HeBm4NnqF_9q!KLslgnn z)Qk%e=wrd{R&9W$3$xb4=~J4!A8sG=4cy#)qeO3;@{s~Q#fr7*{OQ=xuIuf?F;H(C zG-R?2U57LqfKEsVGiz(n26W_d2=62GP_p78o5M#q{Z93^j0W<;gPZbuLzrNnSk!aC zzwqaC2d;WKNGdBMKWnvK#$Y28ORp60AT~D-ak6cj=q{ZNm>9`O$8;kZ0a`T;71Ofq z^W1;^{VE{H^A@&PMb=Hvz7>MdN03aR%Di93sg*lxyi>@mhurQe!fY)enq|;w+}#JL z0x_|OhSqsJsEt`x<@X=c`Vy8G@`LdW;)B;qr5B&Ynj?2Zj%>5S_IbvUt1B0TY#zI% zzz+4FWH>bl8#(AvzJk?k1z)y7U<5Q?-UZbAQh|0{9D0Pb{Z-#Nx-U2zs5=Br%eM=J z)=Kou`&Y)y$J1iMO6X-oXALd728qQ*=7n_P;nESLC-)N{NO+s!hO8r2HqoqOU`gB! zNG6Ne^ri@QR+go92Pod;(~9>3A=7A1R4pSrJ`2LWy)qIhAZw9|(w!Go!x{F`Er{P* zP%Rw)PGXiksqpSlV4vHxW_NWR$a&4TIb=U#p4xqTy0--Jbl3(`>oDKbFA?ncnhX20 zi*&@+V2m6bMYDzrq3TQ1!c|%er9_(uR9yDv{ruQHiik)5f?bS9HHlR@KrHG8oIWe0 z29g`muUVIcGmN>8F-P(AK{H~W=|_zeh?U_!f9<;(c$3UIy1OUj#~dd@kyEtJmV$*@ zZ|XkTGCb%Yo5r>Xjp-u7UMIzf8rj;`qbUK85(@O4xr&p0y`X0w=JHP->WPa?y29V< zJ$syNZ99V!=)oghsyolhle;f zM)hd>sG&ucSY`#Md#&PsMl7AK0q8{2)z2T}$LeCg*G~oX_!$&q=VGTqQlIX2tjc*J zWZYYx&*(I4oEk7;+#Ooqm;dHEvaH`*<9Q&qzO(9QMB6m>IOyf&dY>39ghSF|hb)_d zsB&E7lv}q^?kQWX5$TuP`P>}3#v7NFsFaD_3psalIJyAniiQTK3J^Rm0x-nW9KP2b z4^Z{N=5L2zp`)BmKk;ZM@e!i85TUNn7hnT&M zF>2LOS%>;PY_BI;`2n(89q)?##d$`@8XtP^D)-i;#CtA>ucl1Emvl z4lLRE{(4R4MZ1P=Yf?Uqb4*#ns4G&xuzenPK3{p{Zq#HQcK>EFs&WI{y^;1JcVtRn zK$$)$MSx?;cTC--Eiy<2mBAXW|C%5xAJ+h>Y?{G+SuA(hz_XNtbXhZw?>xc_JgHADgyDlD7Cgxp$1rC)gryL1Sd znhI-?+9j~O&m2m=m=rm5yiZK&=Lc+sp6|BTcGA($vu_vfcY}_5xmg+divUIr69%M0 z%F3)f>_(~HJ4?2Ckw+(Q+#oY&SLFHl;=GdTuug#TjAU6f5FR`PEPzT!ifPgf)5Tko z$9+1MlN4t`&qI*O)bqQUBYt1Dop*`c%KUOgYg&{c@1bjPxZxF#`}wQ1o@K?;PCp-B z%Lip^!`dbwSb1NJk=qp^%+woHpElkIu*^8=BNHP(UZiCe&)s2fWrpADu@l8nz2A`I z`|BCAJW#E6@FBds(PjI=d<#234)&^o$$=5@Vvn2|CkFPO`+cU~oIuG(_icZ^`gD5CjEvYUsZ|EnDp!vuw8GuX(TiCUSG; zIk$kEytvdhHy$6?h1{FbYmz36v7b(IH=GWkNPBaItr|*_EnMW>r1~Z7USHupJr;+dP zY5i!zpb$=8Kmc$L2Kzuv!Bdc3VJuhRC4Sw~|J}tH>yns-YzW)+zP)RLMJFwopjPpk z4!fYU8!TCuQJTWyPNMZ6xH$8nA3rTf8h{{t^VApqR04qxyZCv1k1F=Xz&5WzjU;K+ z0ZE@eHb3}1%|$Hg(2J~DBR(mGCNH4hAlLnCSlvq23+2NSRrliB_-%zflcgP@!;<(- zdmP&s%Uh@HYFB^}2g*bfB**N)wOX9?bV>Cxha0`qhNxpugpGnDK9AB_SnmYDvv?rPw5fG8CD*HIu0$zjZ#+s;Hk_m0=@Am(vUNm z{BbA7KM31C3h_vYPr4S$IfR8jn>xofn z%%2Cp#7-OSg&Z*TQKok%x76N>mn^{OZvYL8XG&9Yx29F|yO=ss!fJXoIPLK(XZ)w` z1-UV|OXZrm1&x6eA3_gX)f&@S3)ss@bItKed74>2(?=(7Cd9;$1<$`;?hM(Gj1MAD`(K8XW6Hg@}*cdd7R)-`U?1! ztOig^%>mlwV@ATzsPuBN7HGyvhLzgRzv!@Z+O*_^`0ZM%Rb>wf99sieMloMbch{rs z&uqlMRta5A5ho;TwwCI-nLjc`Jn)F1_0(|inqKOeDmp!$vw97O8YgZ+gZ=S9^UE$f z3*lP1wUSAu4SW;gPXW65EUS}lq3sU$!A-C(;M~=RI+~I6*rpzY#+)RBQu5&r>Az76d?6^_E zD(zuEy@m&;wElaI*!8%M&0|c~GX|%dxHTBRk|9jTx$sxMhaOOLcLo2aBJz2q6-1>l z6V|iHbMnLHQ5>-0)CkDBW9LpxfJ*M@?kd!ju+ZxLNI{Yc3E zMzCQz&^H~__ciAitidxbnM7=E-z%Ude#QdO1vqIg=>Q+YZnSGg@G-$kQ_L|h;> zU2sl*<;{L$Xgjs4%*Ldt~j+`j=?+&+Cvnb)wp9 zz#-4ID+RfA8=T8(VDzrbl8a9a>6iezuz^+hBZT@!p<>rZCeraF~Q^U0NX&x8Kx5{h)Vp0o<* zCfBk%>k$ZJ?9zNj3jdcLqeZHh;ARQO%K3ESA;f37X8h z=uqhvbp9X`_+9GSSxET;vEf2K5#pBMvyz2e%Q$p?!do%VR9M@Z(@%(ozK6{Z^SQ?2 zTcY!8E+*Gg#Y%;3&FXEnte53f&D%4w zks&wuS@DbAC3Z8VHJgP@DVGx>nK)-APVjK9CAx5Vty|ys2EK)t)qn!9I`5@79v)6)?+@~z=N7$&lRCB6OCm$mQM?1$;EBC6Sp)nFRouR>9^(dRp zr`r{?PakA_(0IIsOVN3NmU`aP+3!97q}MvySC_38L?phm;7}MtLXx4;1Q3(jbj|<@ z@B-k4Y{`dmCh7tggD9{rP3-1FN$cwDm0y@f@;sQWe$=Dt)wU7xqY6aL{G%p^zKP$oLaM38MgIHkdWG|2Z>jIL) zDteHj$Zh2;E9YL6z9pgNnsg|UjJ!2)q)W()GJ=jWk5@g{o%HmK_xm#vSpfHtpP6II za)|m=v_TwKVh#Uk*e9zM;p6zQNn~CF&~JI=Uv9Ab)hs5`K{PVO1iTv* zf!ar~0dQ?v_pO3#FMV#}@cH)6$kCw7y~8{iY7t>K%f@@`I6W_M4vRtvmEp+^$>76y z!xpZ!!9sJMcng*7>3i<}h;J`jFk&J=QKsj%2b8;w%Vk*8hXcL$@Inda67&18WbFx0 zUh$)bbh19xtOh;rN({kn2+4?|aQO4REeY{g1D5iJD3CIDiHPf0Nu&kyK_fEy* zeFAy{+It6^DWuS9Toeyk6=@GZ4`aKA)chy1jE!d@TQ3>D(bBxM16Kh8Gt@U@9Vbox z@`-2bK-5|a3Oh#>XhYrvxA9jkeeneB0Z%s8doeHA{lDz@*X2*7XmhOcMGIl~g*>KT z#)`iGzP2!NqBA?@NmsYCPSO| zDuk?YXF$$N(DYh+Y&1t+$w}xhuvWlBNJPB@Z+;7E0%#W*KGduE0v@WT*Ffg{SPyY$^56Xykv&&ZuPcg?jh)nUX;A8khcNOE2!M?O!-JX?Q)T) z&ri~r_=43@-*XH>I#{0wJl&`+F?JsG#&oq&oz8tadOD%^UK0c(N`Pvu37i99UqzAp zLOEomHY`Kk4pv|&)&$2&TcK)S>K3SWpyAb`rPF{EC922WO;#jSXGpRudU=t%dZj_^ z9{TIK@0`>~z@BrfTmPtC`Q6<_-q%V6^@p`eS?#P{D{x#6JRM?LI?T@@yPA6e{HBAD z(kYd&P#-@(_?@BA0W}14QQsw|F+(&-)WvMeCw&7u6!IRM;Y_~*4hubUK~6P=z6vO) z)_z#F#bnfwYf`1ttL|v|j^E^>XxxM7t$y2gr6+9rq++PK2fhZM=JfewhGCO@+#z>L zuUD)@c-56h+kOR{b7fovX~l*;pmevyHVN9-cAvkq3buNArve}}J!9LBj|X8+@GGwR ztF)q|IaT>!&}7c1adbrP&PKAdNQQ1(r}#4Y61QG~K#eT~J!74%hjx}Avnj8M9;*kY zuNHVs5(Xn5-vGGpCdEh^HPD!*gxp_Z)H4=Z0h!~G`+8D94-n%0s>W!REV7Fh>(`$m z4N0F8bq`SQeqA?XAe7)pp-9ogW zF2!-Dk9C0@PuefR>y?Z|+E1CBs|F(Kn>4Ja>(~i_>Zi_xCWt%SoZFnJJ9gvIrMma zS3ucTo5S{1@{YSbWvr;}8>5Gu(D$cT)J0@Yd205gtLF?(7*KJ`G;PkdYti1+&P;XJ zQ?(!TkBzWCbx?Te7Zr-16n^mMjNFNxJ7E_ypDQkDMDAhdQZ-klPtDDT#Ju?;OAIE3 z=Y6s3E=adC8LUv>=Y2ogM&P`@{wQ4-FTzBRPO{}a`EAX(?`izPD5D^(?P|`a1=wt6 zau8F87@bn`$}{!&1n@tu1DRL&nDSnK8bV*1Ns)y=zQ`ovN5RmB%}{55mUZTeWA)?s z7Wa6lkwl1Cs83_}YPm;oR>0?!LJJnH5WK9I*cUMPGd2|GJCB8hA5(g!urb|2^;PVb zHu&yF9RE=P>*)#dkqwLK=E&@bf`WpRH5>w_GV^0qWo*(O_g@vJ2hdZ|%+X-!A{^~@ zJRE55czJ5FDmh>hCAD6qsYY=0RmO#%(YQom9;P8~-bmY$B9C$qp?vzX_VE!H&KJ%T zXKa?grhQ}|7%empS~&J_*hopvC71D8O&748^k2N!ei^_g%lc?v@YoXaerIRyd;qdm z^X?|Db~IyxfUBF4=EX@-$6HnqwUq#vyAc z%M+_7V()x}RVL@~@UV4{&6ri(-lpyB)aw-XgGkM!A8h;4Oa7>+x>t3?lg(^PY7{?B z+^b#C|ApgTr~C3kDfQ(!X<6btIK7D~NMY6F(jB;fFOu=u`dN2t7d`Eej~}@Oe>qwO zf5>wWO?l!|s|0q@a4>Q zD7Uv?3arx-kwV!LnuDxiww4^|BNi)@;$m$vM*Z1`w*>(#VOj(~@zU|Qz!3psSs`t5Q zTJ65r?|vd^**3bub>@**o-Dqo^vZqD2Yg!T_bD*mo^q>WReEFR4sq82oNJY4fA;17 z;p?lTqVBr30Y?}>U=R`M4naVrVdw?{m2L$Eap)YnOX&~^Nu|4E00~J+rCYkY>pR@f zbHD3-;{Dc|KZeCDbbjZYy|2CZbzNs*wj@+jPK&YjWzgSTfG7s}7%_quB(J*(O@wvI z-*xSyp2a`)sUYhii<%rYfwyDc?wOqnCxJLla@l^Orx0#6M=p@Cs&%}0HoWwhicPcd z(T-qy89JxCxtEuwARINsIzrjr#1RlaZ&BdnVW z&-OoDtahLiyb!fp`q`C7v5yFNzR!J^2K~RhpvoA-LBKhIZ<)@!;~7nZ(&x>EnxAv! z^>eD}^UN3nT3kW|2cyAv73*g*p|*)dSGg(j3?prGCl>>f+Q)}zIl@N{Z~C9T?UJ9% zEO@hhAR3}SBw$-Wf8aV#x-X3zNF}QNKIeSmp7vlx{bc>@_ESva7a6i~UA~QRcNi7B zztz{hU6v|CySV5y*1l})`?mDi=IrG2?tGr>=i?V#HBP%e23BzSPxNuWFC9u-gUB`S zJDD+uTQ*!JK0OnzaniI*hI7c5E%pZzn+?clc#dgulB+z8*e#hB>(RKmB|=6U{|FB7_&o@*+b% z7+?R;5fzt*IcnE0DE;xZfocf9%@F(=#clPV{|wQd{lw^f*4hJMnPy?OB8ncT1J;`-44`t?6Pbo03ddbB5&;^&_t zx7#FV!{(V(XnER0;<)_{vs!+0lsPXvAA9mTpQgQ9=wmER+P!xNX)&wQvLr+k?{a6S={Y0-hQv zZAgspLuK7d$abVho@T*4g&|$jKR@;QPkez>AyGF!Nu4H)gkV%SqRN!^KL8Z{c ziLw;bP-RBW>h=@*Hxr{zDhcuWpJ+5o4Z4iEh+8`LY#BB%{30KY2^=XhQ-@>vpz*fZ zk5_WS=mi)aL7$5e;I5&VZq`uB2xOlbz)S_UoqLzZGkH)tIqxUdvtqGfe|msNinbK3 z7`kveN>z{f-|3-Q^QZb z)!LKzS&hIa3pU&KqU)UAyuD7gwcTVju2`j@-4;!%*Lu0clO-ihWdr>KbBlh{OV^ho zLO5fE)paGn^|iZK(&!Ma9TN*#ww(-rf!~{AQHzPQ?KZ4AZ8_8VZCYoJ&%HFCl3T34 zXeB)KcKi%G=YVmIiMDDNGG!({uM@3m^H z6sm)k-+953vNZIacNa>u#llm>aQG0LM^Uin^WWs&vZYdM*FNvH7-N8;>`;dKM$F1a zLL{hO!cxlgGG^Na{GtH@Yx(Y&O`8^4YHcd^mKqmf|V=>#&zjphyyY1003wSrDEbj(WF&8f68YmjIhN_@X;j^w!^J5%{dCpJ2oQB;zUq37G zBf-qJ%5x1TU^62hN#}3&0nkt7YaQLcq;&r7z`*vqi|&#dc=w$_z(1GmAB!hPqeqyE zAreUIQ6>h!qG-!yy8Y%4hF(pJ{myc!daUk1pST6k`=VG5TMObxi zt%zzg>*Kz6{IA3(@?~%1lGG8|N?5RJ+6K`YS4}E|M%K8Cqihz4>GgDWV8OA8@)5Qn zWW}4RVVXcCFAb}fS;Cz8A350j6;rWE4_VIhGzl+L_k)#4ki{hdbY$}I@aQU=7#Y#L zxV*dt*Oa>xM9P)fUEY^0Y?otv`@ikQn;ddN>!tUH0dbocb2HU;D1>!aXyZs!jAA_^JXbj&!_zx6hP%M68Wq?0WX2-`c{y) z7XSSCc(x7%4jA5ok^y&K=4(AMo2V=R_(j@Z&amQr?C%^^*>suEHOJlvOTFS(-m7N*~ zAXjU@dZ77o!QlguEDkX%186V|-$qhXQ|GAVM2VrM%S^*#Sk=268~U>^KyANJ)Od9l zx=cU?j{s!)&Pt03iTObk=Kt~3{!YOVTy&h3CZEXYo3wrNG{0jf3E0UvN2LflbmcWc z0~@SnL{0&LiP35rHCU)GRO7s#DN-rsje)U!^ddt>zWiNU%D2VdFG72OS1y+>75p0k zmh)^JDe-^QSAW-Cgx+Yk4}x|$Y(oE0idj8EM;l zhHN;7@DcEgeOY28Jy!bmqgfcMdTvL)b{WJ+F!W!~*WXd{pT`aS_+1F(z54l9gMZeK zFiY(3^K}OGF1G8#?7zqmBZcgMJit9v^7q&LKkLldXI>b!T;!F1KX^Y{>%}hO)ybN& zZWo{#U;sB_Ip&!DU%UQ)zM>Z!Sir((T9W^K+=NkR5|!ttr}4v7K#lGlr2LOv_P=-F zzrEjiMw772u_6BVdcj^mFTfLj`nnnN%NEp6EI>ODkq4}D*6P`5!d>E@zWoYL?%v6+ zv38|-yk4z+=fvDxrs2)fyMI-TQ@+cr{D{wLTJ5;RW?n}8!NqL(&DQRWVq^rK4S&|x z*?`{ENyxo7N#GlR?NM~nIKg)rKj;BWf3z`1k3~SGHa}iz!3HFzvB1)z_DkSDH^~3> zB*p0g(s*~lpYYGMYbN$4;n!vkdS8cLbL>!2G*Ws&EQ9ZbazUIm!>DOCR#CcLI?FyO7h??>wu?>NLMs z_04k(o>v#O$b1Lw@^_KHbJZ2uYAH5&qx0MHm5`onq+k#OiLNmuYc{m*WzeYe`K0;bR`$NVk=Y~ zq_Ul$bB_0U-m7_!oB{#f8?Yiq_xc8?rzgOX(2xwL5J-pDY%YmYE2 z^0{4!@D*!#Kg8-yW5I)rG`7qGN+8ox5Eab&Q@zDlsGk`5sTCRMcYR`K1IpaUy}dTf zTjuw~8Uc%ERM4L_h2KVkL$CVPMCOz+=*tWRU}PY}(BHK?H1)g#4jZb+w{|J0mJQu@ z{cl1l_9efl`&s!{l@x=sgVl^BuM=u^vSSf4(!Her-yvo`v$4`|tJA7k%IrIL2}1BlpGut_Z6e5UO5pNQ44Hz^b`Zcd zBx*`tUtOHqUR^k^PS@AXQWy#Ny@j?Wh=+s`F^BDakkQY1`R&cx@0=*mhAQ|dNEdPn zLhUn$2cY9SBM*dtN{2gcfmk(Jo(T)xaVi>xdJoM8zrGl;8p@4*mLf96O@afuAu&Li z@^VNLt)0mSs1p*-ywUxfp(6=AR?~W!N{N}oO0vihPQB{qf7-)~M(FRk)j4jynMOI6 zI&B-EUzeNxT1&iB9tPHx2zvP#xkG7fI-7v-3dGP% zk4H$R+12qlt3elk5AIU7`Hj#@6`zc!Ez&M)Q#1Ug zK+HHU@e^pp8qCMbJKsLSya3XhGyb6OP@?Tn5Lo1ZD-97N4f#2}c^#hw^VT-d@V;k3 zEo`>hD*K<`s&zBL&Qp8XE5TeV66171FJ9EKq!K=!Z?jx_ul;FN-5F zZ2SwI7h9{R12J0sS^+Mb0)ld|I$TzGcsNZGtEmm62jujuFMD!-$GQI+p{3$&xurYAvm!0{tM&87vz8#)3NRU|_1hl69*B>nv%w-73Q^XJIOh+63O zLu6|UmoAqdAKy3_hpwjwvAFJsjA|2{G_rGy|c%50x3^(4kF zlS)*%xX@Z5p5uA;2Og(oA<`(PgUVBhZW^m^dXuz+pYKpfap*2E1;ovPw4`P*7e*~=J+9ywx_w9`?6R`SFP`87B4&2dO0`NpX(Re$#OHGW8RFY?aA7m1y-7K_ zU#2D3AAIV8TwGkd0lj3_R*_z_|B^yrq|mPq)zlI=^*Hn$siG1@uUKuO5;BNnFfmcG zH&70G$NQZ(Y3mbl<_Ng6?J1a)Ks;OPt>=6uuy6X>FvnP0w&G9Z?psU5_RAgVR@bEjc>tDZs-gY2gsbH+t*L^3!`gPS zT>YA)kygwt)Z;vTTv;N?Yb2Zo8>6?=1>iWG`n3#s8U<0g>Un}kZ+%TMcHEK#9dg&8 z1oq|zV7gX!lM|%TQdMf!Cn@7qm$ z!D&xe^U3qN*c>(groB4&?JfAg%PeKe;JZJrQcOA|!%%82u|)lcK>mxh7p_!(dNQWCZ&N6Jw0#^EGoa;@4XiZ5>eirV~3e{8a*2 z(})q+V?9pO)(4POyUOwl*!Z%}pTtjs$ar!)jVWHg2l#_x`fG6YgC0xZ_Ri0fgV;!hlg*dHqHAa^Z^u zbD`3xn;1s-1l^S{OYROszNIjz#s34s z+mgo*>p13Vs~}T(mvMU-Pw-;U^e!lT>h!2i8+FUy(Vib|s-EWS3kE^k$nYB7HHvWS zY)ju13VcW5Ia{HUtCj(riT+5!S!>_khz?_=e%-cP7rqbly>$o1{!Wlgm6XE4#nD3< zGPIx-0M`B!mqQI9$)e7WvWANyK_OnNKl)|gba6OdwX$epxwj)Dk#920Gn!nb$dHYb zJx8L?T#vKwN|FAIX+~)Kue!xY!3)FXIX31z((mig9SrZGS%0bri6DlPX_T2LOTRa+(|9KCE*)EsbH<9ey$S z!(lEKU&YmrEHF^Sv*^~b<+IO^#fzUb^%j>vRuM34@BbXdz&xO03;MrHLPI#uKRqkd z)>h8fF{!K8rXG%#SDz_!zcl!k6vD1A#iZ`4!m%;_TIfotuoctiZM{e&^YK>h1jIKs z<=7?KD*pJdzuhDQoU#97FJ&53v{{z< z1eh4GtPqo*tB8Cj!N9mQlLN64xgCHMU=J{cX9#}2CeFUaWhEDOdb*sV^h+~OqlfV} zrj&!9sO&fnGuP66S?Vn7BjtI?GAeQ`Sk6}fF>U{}Vz(fQfjiB+SA*u$`n@5-B(O_&qon2%3MTBvG z+>PZ*s1ozNn-rD3+YiG%#bBSkUlXTq9Lvu3cFrn-+=TSb$)C|kZ=nX~SDY`0Tu#sU zPAr`fe^uJn2OQe_MZ8wiljVX7)*#UM=k%(+1`*D7z73C2LM>OVQ`M;w%iD{meQS5V z{T4TQGckSs;}EJ9bcyy}urn|*N{rh-4SrK3e}8qU91mi14hM>O=iG5`LEc?^r*f-5 z&DX#KjQkVLeYbIofp{`eqInfHxy{x-26jiI4o z5obVu^H83q=H;sQ77wo@2*$-Qv0D5E9KLao2wH19+efLWdgm^MJT8#GUIJG*`d~u( zfZX-*ioDsnU7+iHa#(U70BqA-1<5Xy~U?_$N60KK}vGXjmW-B*H95Cr9ksd@J3l&zeg9fmtH`#LDGt zQwaBXZ|WCfR<*~@QcW2bN1GEqq8P5Fp!i`8cYxNx`h6!N8V>% zl|kIjK6(xBUXY}e7Zz1>p;0erFR}DV{`A$$1eJOWFbqW|9X0u4`CL@(U^W5<6VBqt z$ps)mivtz?ha@OIhqJa zh{43?KUbIMPXV=3toMFx%g!YrsL=!yvwf<4EW(UO#vP%Q$cxR3`7@DEW%l7luj7Vw zkC{g1Gg9r+H^FtU)5a^U=Omhr0RWyLZSVyZWP!nn6PiR7BHj7t=O;tQGGg?Dqx#HG zhv%wl6=GS#9^!?8GC8^NE~A2!3>;+yJ3|<7+u#oV5fJ#J=)--pF4?X4}z>i-#dB z1r6d6C+?4IAAS#eL)+W;`HAGyw_R^693M(bf#ySH_qqSh7Rc%Lt3~QJ-I1MAG8A9Q z-1p9{$(oF5W;mPjbPg=)2_J+XX)8De+7gh{;4d5CAB+-mvTWjUJzQg~W=b~g*_l>O z5z%K$2%|mxId_Ikz9~DsQ>h=U4`c);w3t2GQzigqHi$ariH0PJY!QWXfTxFZKW*BK zGC!OG0*WMNpr$WeHJPiyE8(Sk&|CzXy}CM;<~f{IcFVo*ZxQqE&6cfo7L#J`KiJnF zDbVHnjv?4kRb8`Q_Tr}R+imzJwo1!Y^o;X|c7+useO!_P|-$apFJSK2++T2A?fofLR zUIH(NDsH!Bewk1T+_^N@67+)g?Y!1!n?f)0U`Rg8$?U5WQN-}0ChCM20VAnPv`$Mu zNf~QBPQN+P+Q@`c6+kS4mUr;U;mG3ek_1$~{DE18jg5_WC9D>Gx z^!w!>0SIGI2ds;*?LoST-~QX~Ppblpb2(IMzFAKpMtK&XVsc(2py2P%cz&19QqN&# zI!J1G9a4Vhg&@erH?uglT{sxaf7k{r(;WEzbAm|p=_}F8gXp!7J><%tSk+m*okUSp zn|G*UVU;)}9Qo4(pe1uP`sURX11zd<5)d`Mf!5g`pwF`G!U5h=_$>>8zysaSkJQO| zHnx5w3QE2Gj`<+y%}(;riNu|jn}T~yyIt7Fs!*@y4S-40&w4~6{pvaTyi`A% zWlg9=GliZ_b5(|ua>U>Lh2MXCbc$r@OjV|=&5OHW3Yf;L*twu`Z-IYzT-zi!Jm z1zlXZ)y(t+E&5vEwy0kw;2l(H&M)<)Sgi$y$~gx7=G^(yZUsecne{?;zI-(8?%bIG z6NML9Cd1MHQ?2~{M(P#Da;13`yJ%?Cxh6}h>}*w};!WoDhB1l}9Ke2%A9NDlr^G0J z!97!Bm-QWljAVEiiC7A#-f^UQfLZPLl9VdE1m-#>gIR)om`>;sU~RLM6x**3vVIjB zr^#)}BePJ(d|d|&b-RQ}=JGXx!vZXdM^ei!=nm|8$f*sj3;mtCfmy>yL}E%Mi&d3+z^ zK9T1N+IJk`ae4LL-KI4F!_PS&8_%~I64~=Wfx=*0%M`#I_0cza)XUHsFeXr$w_l@x z?@Hino0oszH|1XN3w+>@5c|!hQ=UDm{e%qi#&6i)e}M~Yfb4Z-3DX0Ka{Aw%5{G9@kVGZK}Xgl9A(cO}H*bEy`d+>JCTkGFt{67%0b%D_G zTLw}<9Ud8n*3c;I&o;91o!%K_VIMilgiuN$4fm?|i$S(hP)Bp4CMQ3W6QvV?s4CLi z=^=02+Rf5tX*K3u?-6R3ZwqJ1M>Jq;z;as8gqOIPQV&nUyymK`KxOSSW9}57gq|?x z)O&JSG&Fyl1vH^LFBV@~jTC$aO6v^5TAF?_0!YLyV= z?r+x^eq)oHQ9iuEU6JE-Gm^aB*K^+OLM?~UVxa2x{w&cC*{vi|=F#Ha-#bv&S( z#JYp`9x}Zm6LzGiXuz#=>L^gXzSensISsKu{z8ABz>%^S@R232l@GAFj%)l9bQ9*(76hdP%N?Vy>TpdwI#xX) zc>kO`rpou(yZtuxz{wmNzP5R1BmtBgF0^khfS>Rq01lpF=Q+;jCr8WB-oKo4PT({Y zsY~N<=;#bvZ^oq#=z(?IvRdB68NfDJhW$9+7z3#XWw^uL-i9e8S&oL%)Yz6a*Ar9L z_A?DA4u>CWa23)rqzL#a4TJ6=I{EF8KQ)yc`J@tLaKhI+Au!k!RRH6MDJZ%3;nE{11RWpjCAPV*@av{Ua$m@z346Xn7fc)usQ;#OnCvIl-Pm*!%v-bKBj1KNFN+T8BzeJc%*a7l=-+HHU>dO-{qEaq(MkX7bI>+=ioD<4fgo z3RC2V_lRTV%q?V33$LBWgp5m1l+Gmq8OL%&ddRtMcr-X#ZdJuaZdwqJK__2}V_$!= zOi|X~l{;clMEG+)lOH{O$mYZa6j1E;kK!X%?9uWWPzk*F*zVIC%zw85a=fiIZ+WG~|E~L_ON>KI%I^7az zbslUbqfoGMzAMjbv0@^~{YP4}hk8)PFjVQ|x|)Mv45Uy0F7$fyUYA}X{`4?tP`#ka z7`?N5QgTYIs?#_Nm(cPhsbSiC6$;A@X|6bQ*=gnuh-o*$T3~K7!DN5XnHvu?I*z;PLB9Nt!6avp1&8(OU z3Z-i6kTczR*7Q2DaTx?_~=B2^CJHvw+)A zZVaK!?ilxICK@404rYi(rMWiaBeHdrKsysD;tkCF`3)_XujNoAXw++)tp}#mDt|D1 zrWFqGsb->Y$YBs#spqvvMH3n!(~c{KH+6Ey&a8<2N`zp$Rq#OK1V2_UVmRL{*C+1j z)-RC!%T2)3Ixcx7K63p~hFXfm3x1=LR-{y9C~3O zA?0+On02`LpK~%$5_X(f{y<~LN$ywKnyR2AVq9yqRY=xx_%?RY$N;!397Z{0EAtsr z6XV97PG+9=>zM$@PZo%|U5*k8l)SImBy&_rrWwJfwlzCnUc?nR8@XGvQ6+1cB1F$J z5g+{^2NC8D@4jjMDMn9PNnqu#S({bl5uNJfEtIGWV}y02i?aHS^$B+Qk>D%dgE|Bauoa zglVVEZ}%L}m5rE_jVX9dxs#vFluXr9#e4)@H}?BQF%;XHah?Y7IQ?i3b#f*XzPzH= ztGqx0g_w5(4C}7M-xmMGzD#|gT4$yv<+$J4G+JO~YhU22!cwj9zAVK6_8O&ddo_vfHMw<<*aOaKK5U3xh4 z4)pQVt8GF`_R08qm(4hS4t!H2VYHv*1PL*Gp6%T?@Qz>YEOFwDnaT)gC^C- z40uKY62%D2xlw&qv;t~~%>r`dP9I5gu@LEl2Q5t*)PANJV3@EBJKsr?;BR*8&@a*k zCFjo5@+AV^fcoLWBFfO?P(h?;Etem1M1&kL(IY_T8Av{3^tS0o@KCwRX45zXb%9s1d`|_~v1qQ9#KEVtdAyOtor}Su@b7Affk@h24l5)M#nyKH^w|{bd(;#MiT*v*PV>m^o^LMTKTeB*Bx*~%dj_R#) z7wQf};o6QlM%;yC*2S3P+M)R|OOXQnW85NxpmA7PLBR79^}w)~uYbh34T=wY?#Jff zHb*db$9JnO6ES{3iN5iR*%;IhuGHde>oM1pJ?e|6U9P%fXVxf+2yF@M`1*eFFk%rl zNK28$X?f)u%Ue@9e7dQV4cpPFca(x2%BU_W{Pe?q+xJ_(v{(`mKV6*pfy(-AW6H1+ zB_Ojs+&kEIaI)8tVj|$<@xNf#`^MYG7pxaz-tz#%f8_4e(|Su&XVy1*_GyG zPg)tDxuj*X-%fmP9dwy7B<5Rr#zK$w+($bkfU5-rQCh%B)5MlXX_I{A>Lf zWJf!&cw>`^Ij96mi)Up6U4wFkZ7U*4=uP?d+{rVXk&;D@o8vy*)MI6)RhwZQ_eOvF zh-`VN%r@ce)`f(0dss}~zgh81bwwMe-P+;aF{=O*b?DKM$A z6hO{@H6U&`3rOtrz1L9zd{1)$zp)h%#oV+G;Nx3ft0VHsAF0GK+zDtE_I8%j0*9up4`gm+-MGbtSl!S( zY`W61kMWGduwjy+5UC)as!yG~CbK{6JIWuhO!yIv?y+BmcxyXbcEIvbVkjMYJ${3s z55fTXd7h7u+&MypqS5$dQk*5w=>qT_hX$s|XpQEHDNK|cUKSY$6Dv?9eux-EU-vVG zqk1BTn|`%D&Bso31>^p&pRg>0?)miKRf{G#L5iQi=mf9a-?ryUC@}nO>@Y*N9MGY9kMaTyvfeAHr$)q_sq{++ zy2f#K4X1cM4lTLgZ`xkeC>Os~uTCVjncE`su*ec&Sg_G(m*|)q22}~W*w1S?al%*4 z2*UZ&c$U|&H_#P|LE!wL)y&T>Fk-X!qRJvN$QSKK|T#SDUQ~6 zejYq7#^mRaBMRD@IsIjZit>53&RqWyJjJGWtjn*v2U^=xDYl|*nf?H#08z5JJ@!8Jbf(bO+% z?OuLI75gv!<2>bbn&3ULGM^U! zbLd%Ynn~e3ZTd&Td)@RXAyj3HZ%4@E%blopt6|^>mPc1lBN6x|Vm%nGA&Vw?-ig$% zAI0pYqyg*ray8`xg^kMyZ=1eV`Olti1YHD!orZh@d*GEq1h0N^(6UyM`s@MFV1k~; z*7m}9tjjwG_2v1DW^2Ue@cdN`my$tON8pz_84CnoobA=wwV?DyGJN1$j~2Q(Z)&D< zC1QToyMC^2Smz!BtSf<__tgnJ%Zl%$4iTjuPdpq55tfe0AMJttK z4eX}w&irjcUaI`-B~Rrk^-KNheWNL~2!7T3RmS}%gHc-qv?pI$?JP=vH58^_tZ|-K z!*z8$DI({m6Yyz*6Ay{aCx0%8d%T;2&)Zin#~p1x88R(;*`vmLKR-nBkKHR2Ri8W! z>W1KIFpbSQ>|I z21H0;|3wRdC<~|A!rk^7=3R0DuT6LrEgg*$Pc@CX5HG#f59Rd)$=r}oyqz<@Z10FB zM>^hN+}F(fc+U2r0kD&u%%kC1Vly5jJfQOSVZ3CanV%+aLS54QFgF@BcJob#q6Igy z(y-oTXdc)3bLi5&lBUtX<(oF#tQ45mpy!(H{`p}G7_VUb>O|wEq_Tzj2`GqnQ+wR; z<6iUpC-{5}d!U(_9nuji?iu$k`2;SgnjY0A88=XtR%BaS!cQHz?@`V0W({z0 zuVy*E{$0=)I6Y=D!G?bbJOa`6wH#4 zbHh(6{NZvJst9I6Em0n5MWMwT9r1{AN+Cz+RRpf&XH8@`-EUsVazr^en0csDz-LvP zvj#LEW``ai*HHJ5tO#hS#JO&(_@?|t2fNcBhxn;RV(%R79V>fe6alr!k98}>;=~)(z94Jo&G%BoX~tfoS(yKdU3LQwk%h4j}W;D7&~f363};umACaT zS{aWY?@7$ZLsxJOO8-*ZLGPeTrQXn`)XsvZ>o;3sZ<|ba@M2z1Ta!G*G(!ioKRWXJ z)13cnp~WDyUOnYpCO@s6ZCX4a&bMlQ(hwrAR?_r@Y~_YMF8$5V-`Ynk;cUEGaOBmA zdAGH%x&7rTu%zxQ5YW6Nd1MaY_}=e)<^kg$pM-xg#W#!K0 zXyZ_(r87gP9P_;Kn3vqA&Ka~dY6Ql$sn(a zYA$CYPm`1Q&(xIY87!VB=8;xHT6WG@Y8&ki`H_(Pw^k!}BRpt#f6mn>@L46h0lWCMxkqaPni zUo~NPkMP_6Rsp1p_alV`Rv)}(!>&*5O#$zRhX=Sz%&3`o-}D_NqR@EXnmLaHN;J!G z2R*IxCZEj~;MwJ{@GBn&;8{17VE37M{Ohbm>^YQ1Ddvzk=9K>vgpSVJV&21k7n30T z*aj3&iXQ6{N$GFv|I_;DwejxzOa-qbVd!e zWOs}u6|PKVlB;|Y&a%I74R6<++Fep2|IDD_1Te7~z@Y6eGMyZcwj*?@_m=*8pvZ~u zHK0AjYB~bKSL}nL3i5E6Ixyn4Gmh;RK-ESfDCQ8f)-CgsYvQ5eudvd%SzcT6L{hEe zgwTrCelfMPUTT(s+{(DkUBr=$zJ89gEBf`(*AxM`6|9p`hT1&hX)2(jV)VJil#oI$ zA`M<`jF$Ku50hy(xoi*jG4X!>tItcr4RyQNZD;jY0KZn(Ax3(^>YMB+)cH#IsX znFAW5?a_wze;sc5(V`=FlXa>D?`Y0memhp?%X%*zvNN_&|2jpJMTW^I8<{eceudH1gvqxb-q!{q{;W_R5abLhB==?^n z>et8D^tZ^dXkJR1@3w91^-U~FADeJko%ywKIqm+Dz9H@0J|0dLzvbS7DPlV7{|2V_hs<5nb%NO{arx65E-wS@E@UThxB{UWs{m+!={Vnch4%)sZanp zlvYmuzw@?$%rF*Ju^w0?J(j;TTFUscu#cqn9TmW%Kw|5?k#LZg!?)+%2pBA5LWfSO z?nu_wQs^}_j~eEBv=gc5B-AwWO_d=(D0URpi7~fr%9}%kEx+?gp5_D_Fep#rFWtde)@gvY z+{W+;FzVGR&BxLSF2TJRF)IzGeN^?mE>TQMWUIfj!uM?3Wgr<%A0HKGVy`?Puv+}C zHJrcnm>Z}cq5%&P%Y=2}iS&niHaP@A05IOtDgfio;oMgb0~ffm*muAu)|}&c5TEW2 zEdPwBzZo;Tgi;8+j9{(@W&{Qwmp_yE)D7TMi{v*qk*_0_Z))ErCA7pMnk~9PoFDtM zndjSXHxvMxsgN(Ug57`-Fl6$m&T;rZl|6ox-XH6nKFl0+g5g?Iv92G9rpN99-tw~VDXue< z8%w1y!U!>X!R3xZ(#YI z_X~n7l3ka#ifVXV25p`OVfn5Ak9L+>IcY_`a2trUpnggjq;`HSA1RviD&xP8_POBi zdIAo)(Y=CDJMD8n{1m1)D6sDGnm+6u@5|F$LHxO6oi1 zk{+WG#Sv~x<%i9R`_2BitXM9fEXmG)fgbjV8Qfn^E0QbPOr`}{Z2fC>T0RZ3mjfcCg=cV za(!RPD6^C0I-*V9o|8WHy>EKEO=$7?Nu{%Lfz=yPks8-_KN{shhN95fzqtUjb{$+w zKQXYSByQl(Kw{zItc>OR%}F!ooYiUX z?k5Y_wW(Re5l#JWdhWHd)@khtMu9vIzU@g>m2RiDsv|(cksR zA3j7g1S66k>p{qAcI=|&^$=>AuU;w^SJTRrd7ckS$n7HW!bFK|w)sTWa*EK~7vCm+kWLBm) z1-`aZcrPp*C6bxbM$Q6XEf6}HcCc+0m?cl#Bt|P#8ZEd-@;q>)-eg=479EK@P0rPe zwaZm(aN7fin_CIi{oW=E#azcW3l2hii2KGFKWO+>+u%|z%I7B$+4ige~*GOgBD%ihZn)sXC@gYm@milY_uYk6?s$ zUFjpe!qz9HHZa16Ir&KU=^^WAKv#Cr`P847W3WDn&q`;+D+p)~! zVE;pmc<iKHDui@iBWpJ@Q6LE+?x3e(0 z6q>2t#735ghN^fYV3$~XW;J8PTDFt${g6Jem8?zJ^{w5#@sav3eRsdQ7nJcI<4oQE z%9a`_rggXYy4z5zkR?i=+-M9aJcp=_B1KipfFP5FfEoEjV6iG-Ha|XVXS2E&aKV{A z-e(^SSZN2!2potMGmx#8M4E)IZ>vdx)0J+&i{ zjfJ$_vbVgq9eRs4J&s*hW5;8hbUF?QY7{`5UA@C8s2uQiqCrhO<}k9Z5W|v|GQR-Q z!OL2EvkEh`0bE$J8&IYxQ1FRpu6zu=-S&8%UM3_0C^iz7xb7F17z5DgLfkx!*!DFr z6S&bG;yR%W9s9iAX0rx>WUUWwYtp_8jDQNVsdwEb>URWMxuAtejbef3POz2fZsXkR zPuvypB~9K2qavKvSfEkq0QA_QW$Ki-sAVX-sN0FP>U(teyUG7x^!t%xfDdY1JKE{M z(!&AowI?V3CKLVJt4WIHIbC9Sc+AE@PJ_=5L+W2Jh|jgQfj0>lVd#L$jSg$M@6&QP zb^Lg<@!aHaj}hK{a>)S#7_TDQ&f{-vkK%6GnI?2SLNV>^o!SYMzq?w;A?#GI|HL3S ze;MF!PMp^v%f_eR9gs{gOj?ni%s1A9Q5$p}n&u}y)< z)V_w_?+{Q|4QE%?fJ&{zIiF@}H$(~AA& zzPw#fi^qWO=V$ob0Et02kPPzT`HtcdlB~D$BfA~fhn29`VGjzXCjos?9nlfTnX<<{ z!t~3}RPR=@-e;2K>MCHYC+RQlKMRcnjKO>i{oUMujZfDUwjvPcUy>u9-!<4F#V*%P45$eW1;pYH*);j_}0U z{sRyOb~B0`&tMeXzM7ZJH8vVx2i@ASlrdNYGg$3J{Vv!bpe(8A5?CYS0H5=Dut%GB zmF3jk5Z@|xDT{n82^z>YU`>3I)N~9=%RFxEaG0fFBG&-WCnCLTF>oCKo{n$%AWdSX}XDA^q6b#?p2rat8~}InJ6hTew4z*!r>R&l9AiPsBiOw%k&a zC<}UfuJeIQ_>|~WQwSW86YqtO5w~vR!>;RtI&t|O$Gi*T6%+)xFKR~8De{=HDZ{4y z^)GRAaXTq<@0a&Ab+3WsV3qbdsO0rV8CnabFB=O}Q+pTO0~?BcF(mWUx%A3QGe&>K zrLn3HimqU%!*t2J?8nFM{;$H5PcoH%5=T($RW7@_OJAXMmfS3tYmvs@S>Kz_NSFm) zPWQYq<)-xU9d4hk9M0`u)3vK0>t3YREG8@BxXscI;9=E-+XRc+FB&n`6D+Z)+Cop} zw?Z$K%m>5{FJRM$M&l9Bo;U0ExloCU$^_6U%E9KcLtM7j({kxLGzE|ePy6ZElyrqd zp!x>Tp366aqyw0mihZM^jB@<~6zm76a}7Gqnr|BR*>;XN8?a3ugCKZp`cJj=cr`{* zxnT)6+lY)%SE_WmVZ&yl*_A0&*XT&PNXaV)KGrP}XIQInjWviTml}aOm5)mGvr!51 zc9{acG=bOftwyV}s^P2$_aD9fK~mToTdZA`1h~Z?AU!jZMo7GLeAn{VSl(7|FsQXu zXZ^wYQ_^`A0#e#jtA9+aF#&{_7uWyL*?Z!(BK}Y;sA%E`%;AP>aIzyPteysEh|cTn`*(PokorG+ChTYZ(AmMFqJDMy zxP!kuE&a1qmwJkR;IX?~vE)y=_$z?&GU3t*j+-NbD^Z~2!-CjvQ__hdpYgcQ=B5R@ zA^k3Z*1z+9|Gup_e1O1J>#J>RZyeMVn~QmG1os%36NMdC>uCd7dL2btZnQMTmUZr8 zIElUo8`s9PphL{lT}G@tR2JE2RZzyS2%*>S7q*V8-C55Km4@2u+*)+#iztyE3vcZH z#agPopC7>vMG}9tbTglSSHl;S{;RvHV6OiG8DD%3yhb7mgS^77X?}P!DHcEeZEpBqfY(0m%xHpZmQZ43)8v0G=n>w2L zRn%Jd35nD^&l|3D*K$wUdGr-Vd$no5H|<%(3?e&-^E%&#h6npYwzU0^4*S1oX zZ-101k<5k7kIdA7veRn?u72tL=PL&(xaxJ{ZWz2_@vD95A9~$o-7xRRCmK+x?S>lw z1$V@&D9EF8b5C=DYl6+4WbGpDnl^c2y0rH>_`kC!U&TSBE_FG!%a$hF zkTfZ)TT>6CuJ2E-8AOm1DH}KsaJ0wh(Aee0dvQH^Ov7QXUcf~w52q%Y2oQW(=BSRs zMx;@PZr?G;g5FZfR3#p1o$?4N+M9B3!i^NZX59MXo1-~hvZ5_gZRn#rT%(%f=w`7s zONR|gk<8vLgFSa~J+4I_X&dxmxJkrAZ7($2qdK$one}VJ<@dM!kGJ!RTzamnCjrf; zX3g@CSKAXFc3pI>F&*Dx3By(cf`k#&L=b%us)=HK>B|{|;$@L5_&v0@Whc`V(uP)` zh->DAp8Oz>vwOdR3ZZ}*UD(r30|_ZbZe7;eov_W9c^G~@^63|2yU3@dRtl?1A)eva zEk$MZt0QH_`#HP->rQFZZm}NKaEzkH%(zrkTZdp1P;Pl1=f#q=BazHbVbdb^vU}xn z{sU4R(iJej^f8HfOw-t>MQ?ywm0i-$8V3Iu zh2yyzdf|;O?LRcUWZptuCDsOGEen3e6Pj#t?bcW5Og7rx}8}v{Kjj0kh>5R zm!&(>#S~ezAB6)kEvSMgY~#)Fnk46q$wn&Y?1urD6iIzQS6g+! zC+iGy9O!BoLQAiRei>A(HCr-%+vd#9%l4xFD_LI8W$UD~Z1NU#Cbc$|wR%pR#j$low^Xdd!T+$GI0Ls@+q_Y+N(?dUnN@^j)_0!za$bNkwBYOK!_ zwYB5+?H@UPx@z2eVYBqIa_FV;@mH00&TH;p1TS_5;<t%*T$7hLm@gsWNa>Q`4A9V%U)B@K((bBhZgr-s1Ble(BMdQg?esmmAe9;+SY z6Uyp+up#4{VFDo)nG{}QFaU+J%pF_QdlLllt@O%V~S|TZVGe*^f`V|w!E5(5_2Gjsx`E}6Zyam+FpS4n z1-L+UpvD!^Bw`-MXlz;jfBqXa!~=ycp?s3TY6Z74m7uuks}{-XcdYKK=s<{UdE z&F1s@Dmgo^K$|(XrUqg{`6H4mV%`o^8{LSi;kvw$(9m#kw5P;hIT;&Udfq@N;<)qy z%Ryvo7Vv{YI|@Ht8T2F&v5*52CTY(b-rTerzEkPEmZA`MOYx@R5AxJFP!W_48Y?M) z`VKa1w(wUSkYjVzb#spUr#)6E2!LsBMVvjBN!+1mJ{^wL%w?c>9tvbdJUxUj%&c!a zfT#@%RPZLLjQ=*MX8hq#!FHwF^5LGF^fWF|vY{YaJuEcq&3@D#fb(C&|MMwJHCCBW zZ;UqoJwOx##65XBnka#Oj>PNFU$toFL`g8RekKDr-Qhhb0tN1itWB!4E*{p$nG_Pg zKjA>Ofx*B*)A2_j#(_T(O<^XY7%QYwYNn3O?wJN$5G9|skm*oK7UeJ~e5GeMI~$2t z-8KOwTQSrGJ#cD?&CKuX#OL?&L5{{-bzVcT+>ka!G^lFp?5c9I&Xbe08Y+{`a@UAgPA33vC0%!F*@LRMT$BsWFlAuys7-SaGl?^CrOT7b!1E0 z4P|{$t=A9ge^Wv2VmRAFGOowT-gIYImYO3t<-sl=cBKcxI(ni`=v;ksAf%)h&<%Ky zFc3|QkwPcCCNI9}RZYMAK;j90Z5BP_7 zBHzYJ_#C>`Qv=}dM}g~1F(v(87oS7n0}F6U`>p9jz6ZT38y%m(pE#gsb6**)nVg#X zzCb7RD2)N)Y4p^_CE47(^XoTrBZk6{SOsx% zAw2&(J}`11TUbT~lG>F5<^VZVVrk6&-@eBmR|GOg0or1B82sY-D;nc>16PUyqGbE& zOAb=$&aG`*(T8&=5O?nGIRI9Jr21#V`FXs+^ni&*(Toj1TM^yDF}XAhwnQ~nmjz!E zSL&wEZA3(#Zly|S*MEsB+++W2F?h4kt;TunN~Ws4_@B3uA_1HQ+jr#8xW5EQaD0Fs zRTutO?niNSHM|h-+jP}m!KpXRy_t|97uBLBb9u-6G8p-vC;Oepoqq684+iSA-U8#? z40y1m*#AOJdQ{Fw2bJ++PHiaE7XH#H;iWJvqyFd!XLb8TCZ>oyQ>!?=#n`%9-(THl z>u&$dAYk8yYdv&$vJH@Bme}g=bkV$LqyeL!pFg;#=V-kQ^49Etk?T!hnj2LykfbD% z#0Od|ynv4^gLZ&J4#0xV%Kw0cKgxGLpIPe}ejjqI%8wBq@Q`7ZSMWEJ>F$rSZUR|^ zpsg&x#<87<2snv~VxvqeZ>jueL1%7XpuyFswvrEOKULteV~xQ z^ZW+T{IbKKq2J9~qxtN%7J6BrcRdewUabyd1+}YLmB3A?3eFQhNUR`tHpc%>PMi$H zC9xF~Sp83yBHUXdOT(3dKg@6E^8m>@l@gODvT*){Z-KO`;MU8}KO=Lm=IoS%ySsbO zA*gPC1Z+$0eMu0VXdd_u!>YYwE9F^Y?|=0pMuD5cZfW4gV68{hdU{(lU)-KJuYRp= zZw%qXulFObJ;A@S2O{>mx5jYJCMvpT07W|<%B~5%|1F^XdmBRrsK7# ziqDd)k@@%wiW|rU+GL$m_>PrC!xNp!1f}MA-eh0OOuN&8kf+s%_IS(@=x;c=}uMprH zi}^m5w3~iJ3zC}vCEt_(-T(@0rXffw>&kq>CL4dJP+l_E1AwQSFMnQ!mwBtH4*VyTxJOr0iR&J8v(U@?NX!ei2vtRApVkr z`EutTpx%r+lJ8*?6uwmUey+riQ)9VoAbyJPoB$x4c;| zgX`bne2moy+8ZM7?W1o3kvzcnoRg(RbczdPm(V8f8!k z>QP#JYaYBMlM}}PI0Lp0&ljrE?||+N14IyayTvekWCo|H`PjVP6$A}Z#OudgW*MXE z$Twbqezc(4UPEuM;w@Io5OlYq=BaWyJUFnZNdR2(89^xpZ_Sb?;t$0>07E+@#3#PI z#^AUz3JsVA#5#?519=O`VEs5MPc++`t*+{DIS>=S9g9@-wnV&B{Z&8xckVH{96n1XYoxu2c7a}vAt+K$mrn$0gssIv%RfZ{<mL?SXNGxs6st+fx5vXIpWruydAt z(qa+1EVa1#81xexP#W=+++Qk|@gCN==i7$J_U0c!e-L_x6+ogFAh5wi zY~M=5MV>cI@bKE|)s)xMOPmj%n=`>C&q%{%`%^uzE$RZJA;@Q4~Tu zH6WRU?Q(w8-iC<7f?Bs6F+!@kEw+zFS!f`?T@G&9?~e0)-v zRk|r2L8~FPmAi;^!Dlk>z>hc=LY_*c4wnsYIepg~MsbV?FLDVe#`=9>!~OxGTRsB= zPvNXu1l3S(^_vYNKpG0u%i*A93*8=pnt^=hLZKb>NEIs1x_0f3d@q!KG`8SNKQKkZ zOyd2XdZ7Dp^cQ=+ZrX}|sMDn6KHcgO=o-pvj4}7%s{;sdxuJis7u=T!Be(~qh-OkWyY z&kVnPOA6T)g`XSF-=8n=b3jk;86hGn-2X@-EHv~P^xBo?=H_UD$%-0pJbZEp4ledT z9}apiE55I$lSX%hx=fh;}~N=EGt8u@&W=A45p zXYvdZnHCe9=t_DHKT5D4qTUelI5=jbo$lIBN*QbyWSCdiDERh>`VL3ef`%|8K=yne zG>#hL4+Ct#<^6P|AOjh|TF_VHK>5)o({|DZ#52>4etk+wQSdpW684f@077r3lJ*I` zx%*x^5^l)Sz2b?>9pxyuy*|_sqwnP2*Vh?tCgeKCp~!H$xg{GX(}}OI)31WGlPx7nW!ck)r`H3&}4r5mOs*jcL=BY+WG&#J}Y!Yuc9)~4FZuSZuqHXpFDiHRWx z=(UaSF^kxJg9^LVw&flHHD?|WdykvzTCM%?_3PK^k8hc7I*hnjTdIC+Xr{NWp0MF) zR2c`+JR#J409p(kFXV3-C4`f||4A$zaP*>yvBAtP(-hr;hu{k05f*%EoVBR39;Jwg ztZwV+hs||-l(TdhuTJsd&q4ExoSmYgqB3d>q)lHy2vpytPdLn<>Y-gIOBJ9T2%n-7a_)GNP#AG`w(7`&B-DdWlDcxu}y4yGV)27YEw$LL;p$GcL zOqw&s4gi^_=g%EYMJZ|sM9kT(A@p~-GU8t>DX&zZd<<}ofZ|Iuh&Z@at7~h=uG!bx zq2xlgu3a>6AV>&8^Ut@EAuJ?`Pxk!({I{UwjpI5p*mVVP&quU!;84afmCcA@D$@Nsh&Wt&YCoITqLyiIPv$kZZ5N1rC|KNsVe)#?s5YHOmK zh633>E;rykq}xk$($E4eh388=d2Y>PcCCC-BoHK>T{-9YYZ|?4ZAOWB8)e(sdwH0` zUw8Y>d9<&L^wrh|j(-6D)U>m9PLn9lNOVcT-bQwDuf)g(&=`pXY6`=Sv|~*8FiF@5 z%?S6r{8hx(0}YL6^&2k#wQc|Y^zk`xp3QN?I8M%YwNAZRW4d~M72;C|OA5a-I-ZP4 zd@dffrfW=RZnN}`CqEPj!nFWUJB)T)T3Hcb_T2gC=jZ2a(XB($`v|k`r~t~5oW%21 zodFzA7Zu$fgm%?$fGd84n%*q|+l;v}P`^nItwCusTn=3{$LY4!C^MiJ7IC~4d(-IM zjj5+zZzMdJJa?XVTe4lbqA*+PvJONPVl~cm(40df7Wvr*3MA{W22)B#rf-HXPFDv6 zp)W$W>bX%fGjv|ccM1}psl&zpv10$RqL~OB+|BGbTY{6-3?Y8X7nENdVa{W!6I}ep zaydOceTXdQAa6gVZnI0it3Y3}ay~td7xT2Awl0E0G20GFYU@L&mH>aKtgKw1q6uWE z4YCW+xVX6K;>w&Ld*mXi5J=msIV$6P}YL+^)NW^94>B9`5t_Ke5) zIwkV0G^b@7At=4kVd(fC72{)bZz$aIcyG>HRqUw+LmIlBCVetu0jj4!b6!3~=tK6s?4d^hjoF&YU;;*gm&B#NqS;%Y-sX>$ zUJFDGIm~3)+v!~zsT|g61KO<1UDP=>>TDt-=AL_1ha=veS zcHAU+^qhAi-v>5gu8q-fQuzM;dvM0K!7L4bQE~CIQK`$gcp}*ML(U=(nzW;oE%QG= z6RyQJ?Od-vbHQJ%prhllLHiC63u^_bU(=}(N=0UG#4q4YOiVOJlWFAW%o**4v_WgS^NQez&N1i=@nT76ylB{f4axzOd-^jAW%CM%#y%hd%wC(Z-(5h&{c|pAi zK!EDZ4H|uS)c%>Qe12(7M$l6D6@_z;+oJqAY}6eT z;m0kA6%dVE$&~VEt$cu)ZXq7EO?9G>H6rue=MX^<7_3AgK~x>qSlRoYY;S3^-LH>L zT@ix0-_L@mN^O4z$Sm}`=7)b_h5tBZ06K7!kV6WtT<)d7VhMNEanOm@W`2hqt~(j7 z*?T@A#(m;7O)P)+AR4r<$l_8~w!qy41?zH;9{J0=NYjdn?E-oA+v-40uVQ{!M+w%x zs;TE9onJXa_euWk1!l+j*o~q&e(Ly};3$pOdDY!%9{_qtaj0g_q!NMlg1fWv_QA-s z`~>6Vs&mOe3aY;+4)Bs6+RPWfxmY_uUyjnK0Gn71+Vk0sy3EP~P8bE662M#rKLPj2 z4x||Ff3>O34=F4xWHMe|yhH%fIPo@2A3&_V% z=%3Fu%t`wW+`c=V;}$@MR-ts%b&(G%JbE%@*vRZ2u&6d%1qzM8sw(ux8>hyR(63Hg zd+o)Ec@Gyj3VlV$guK=reh;)IJAFAk8Q)|!~%d+< zRSxAu-6yxN-oCAQw3#6pFeT5d4s}TW8YfgpVry&LSi6CKljp?&YQ$0bAKd?SwaGL6 zz`*5Lo)DZ2+?EKd)qK-!+oJm!wiBaS`+do&K*4FyNcLu_aVe}c@0BGXB5{#&Hbi{g zKQFUuEV#JL;le6Vw?=gJYhq^?z-&Elv3E-O;+RlrEiWP> z!e1N*r1Xq%89y-x-_~e>eqfogrG-iLAMmuPN3{&jS-@* z5b0!JQdLor^15p-Ht6}rx?+N`v!;?q4zXVEH0EJkkS<>nVa9PCP$z38C3Ur#cH{Lv zu_JytCx`a87w~)0O}+x05VzW3JO^wtMD=1veG)psQXWW(hhs6LqxSp?FmXS?V!g;N z_+l}FK|+fNm@QEkBoAz&UfwYO+;3awP;(5DEiHfb?&uh+i)Dc1c`;)b@w%m=)^E1f zE=@QH!nautn ziQY8!Rl`>rHxftp>^p#(Ta#J30rbjI z4QA9n<{r8_scK4ERP`7%8BH>XJ~&+Qg4Z3O1k%N4sS;vx1#C^~^=jhvuYc~nKulc7 zNH?ZF*gA3v(tpmubXN>r(a;m!+pJ}rVAS46!~Cd}?K0MlviaQ`LP@@Jrwwjg5PdGD&?c4*r_rcLfbXMLyb*KF= z=ASjsv@E1@NlNPH*KBLI4wkwe15y}?>^qYn?Dbe`^x9?%QbbwNde3+82=%!Ndk8QKs`CoKlB zjK%t&?ybS~TxC6hoi;eOJrq%k0J^NLm9vQ_9Wi*dOCDXhawQOckpZq)e*4M`{Pl!# z#*W3QsVT;sN(o0#VyWYwCN^U(T<$t&_FjGK`1l~G8(}&t%mbyuIRF9u@$M zwSiAZ%+A4~9UT_%58&viAlN+4)kq2t4{wyPk$L<38$IFP`ju6`?wZdN3i+OV(fgA( z;Yz%5zi4#-Y$2iC@m7IXGl_;D!$y3ft6t%A|JOhP81Pn3Pj%V?{$ z({YC~5?x!^A!gPc6VCvBx=lL-QkAJl!$GL1L+^oaE*(p+(V+01e8CZi=qmnJ%X8tT zby%a!gYvtVJ%^Rs;X+x4RdDLQm|~&Yr;|C)uj(T zFTvua^gDr+U6>orp-WfH(4Ov=5pGlJ)~42?3KDD>C*GUE4(%9a$-@$r)^Cdhd#~OQ z?&Q66(Rb)oZ0Y(VGtt{!K`M4=fk^g{6mP)fCC7eM_Sl=ko( z3K}{{oO1ALIg^j?D#***&sSJ|Ov^D0iw%Y>OcJdB`qeL-fGem1tXTbfg0EMupvq93 z95c?gn)9*#6Ev5sM^Me>ZAD)}mfXP9AEecZcw0H;xxgeq z83t;^^zQDApJ7YR^)VtHT2QcqTIoQCmv86e>XOzkj1IK9`D? zNKh}Kh0huQgk#RcUw3I_MbC)y^S7;|h&&wW$omF&>5^eebh@6)rTu|!rmK2DWU`eI z9d3X#RvCPkld+1w(@I_W%o+k##c#gSHv3+n_B!5Bo25>|%0OYma?vIhUaW=t=945( z_0!JmP5Ki4%M8$l;MfR>-hxm zfa|yIbsY)_X8o)b1|WD@VsZ#3uSpSSq&$(PMjDHO_3G)*%-vEWjb5;L4z<%Z?ps(N zMkth_Idgq96BvOMn>)CjtaYPF%1fV&SSNhRD;@^zj|33$h_>*)i3v*7(C3rx&?wOA11PVY!f=cVSn*cyqx6b zLiilwycfWrf$%G^=+d@t`3jFhH6$V347}~P0Q_jnu;GlS2H9B z2t8Wp|N3Id4m^P0z5(59Fhw$Jm(7jH0oU+4Oa^?*N1KAhTaPDjtB(jw-=`UwlUsv( z{1+}PksPqGNch$-XLXo#4e z2Vf;L3_Oc&t#|+X(U#{!EC1hC4!c&R{2d^jJs>2+37Ma-@pv$bdid6T+<(3CgLGLw zhlPYpobp6F4Dn%Hhp%4YfsVLAs1FYGBqNjcBeh%6G+_Y{Y62$rtqpFydk$EH;Dfm6 zyqz!WFeq;6_R%{7&Rz4l3YJAoy!n&I^!_KKOd^(XQoMc8iA%D+ogQ(Y*)h*CteWw%|7* zZ0?=op^^+phP#8-q9a21qSWM4)^y6TPp*tJ;?Y4kSsydvM%xqw)AgUatjE9O5fc+r z($kv{Hgt8Vbh5Yt-^fTL=JYlGk3TMCgo`()xH~WC_zybvk>SCj0kCNb8T75J@+qYH zQKPc|`r9lv_q}oUh|dN8*&F00LU^DB^G&m!YXO0QB@EqwD`LNKqq8Vb;h!h`#-P{@ z6`Kv#H+^rK_Vz#P2KhuobncwstGPYPsIIOqq70T^124+!`o$7Stu)WuV8{Li$rbX>#-@BTXD=jA`|PEH;M zN{i&&-K%xp1JOk}Ik|U8yHm&R^dv6<^iID|_0s*+y4)cGOh= zd;;feG?Q7t_rdQI4ek$hi1Eio3z!oZ7ndx!-N*m0ant32am(zR&|dy$+&Fk>g1-sM zsOac-gq_7jMY->qPyO{j&q?kCBeE_DiS{{l6vwrmftKZzR8$69T)>wDAEYHG*B8bA z`<9`@TIj|dHCn1uZxBVk3c{9vp^-H-Of^~#3_Q=~Z>9B!QM$pK<(h4^;FY?7$+|(z$7IlTi-jP zhq*vfP!TU1)#;u7d-;4CuaXaZAZ&R0`wQ3~N_NFV&>#pq0d-+MSPu$!t_lgMwTW*i zwA$VLvqP#MJOja_XvTTa*aV+&eesz*!=LY-#Xb5y?fr%I)QA|YproWU1ksY{ z^I%WPkb3~HFdAie<)3#Ks`k!jN=2^T;UrCt`14NOm!1)0-UVg){4rsW2#OB<+{UJ+ zD#jI%?ZD2?{@qf9;M6qynUI|#99)>br|afPAmOj&_Yo!cfB&B9utFY41YjHORq}8! z|Jw}VCQ*Znpg1Hr_|LV>^4JMa^xR1I%_Lb_S*&M^Sj6Ew_3eL#!_t9+T_BtUoj*fl z89#@IU`C+dTSdvq%S-#tX=!O`e4jqG1ONQ`cm$r$-9dBF|6umEu3$}KjD%ZRYDPxY zu)trN)CeR9P}0#Ys3;NsGwG1Sb93DH6E!HakC|*A{x*5_<>0vQ_idzSVhJt@zCCOZ_3tHvoFN8&2HibaLYP(5?+wg-<-)%&55?!B zWq3O*DfrYBdqX^kzkU1Wj}G|%+svHNN@7w199-GN{F!pD=lCR$P0oJnxB%uv&TY&Z^z%BYe*{*7JmJS^;nYvTI z4ykt|AS9)`N)!?4 z#?>?z;WN{Zj?xvw#|oT9e&+(L%p7+xS<8U!-ID_>yDMtu9n?%D37Y_O_!w?4u)o$nzJ%kz^$W-`|oAD)H4laN7#c7pT4VYif$Gl~K?>BEo3V zk9d-X{Mk?PmCfl0%D#dm18O$sTHCqDs)@a_JI$Q(OZ3){Op@+ud{_DGu(%?KIXt*} z5UHAa*prpQgL5b26{DCT2I?dm+!igsW6wXsfQw)KxV~ZWzTSWi;y(hndYsp>Knp;% zB~6gI0iYU-*r}azab4a+j`YUDNlp{kiR&TRc=uBT#mB zO+v#_^+Wk{UyI636|SN3cEupcqSjV+>t*e!H2j3amH4hiPi;Gm{HxCB^9>?+db|*v zk@w7G&{NlHJq@-`pOo)h7+Enn!+t_o*mL~O*49?WViB1?paJ_)rUCA(#MdoHy3l;9 zE{Kh%+`B_N(r=pFQBks^vBFW=X6mwV=$Ok?kc#`bw|XJ6I;F-fZF=rWIf|M(l0oDJ zeq&nraZ)b?Vb48W+A8wi9-n;G4uD_1Bkwt;f9xO*UM&mxrAsgIJGYSBX=!Nz=m4er z|Meo0xFfT}BI+d;RrVgU_Dw9d>aW%i0>g~$jg;qp z?kLq`_g%@S2?ulxDLV+Tf1IxT137W-x7AEn@^E)n8so;v>J8~8|9tdIqx-VhC#h4f?W27O zz*^9RX}+u%G{$Krc`q?BtOxloU&&jOIP&F7xa49Jll<(7| zrO9f%041Cu^x!ECB>1XbfjL;Hw52}%7-w>9Tepjs zF0~XHwep&qdYYJI#>2W~|9;5mmCx%_UXKd+JDIBN`_D1AJRCb*DpZ1A9Chivw!5E4 zHF688r^gQ!sFg3WH!mB@MA8E=_}2pzRqD$kU0k%Z5<(;=Q{JaGZO#|1tTmy=7Yq7# z55-4VoVLt5FM#t!SBE2C@rMQdYne>QaTA_1(a_9pkN(Ctd>Pm^SS9q~tLnbG=$zP; zk57p2%v+H2_3-UY!&Wqm%VDF{9Dv4?zZx4|4rvk*egdJSMA<3?G>+PLhG*a)yCARY<7!_t8v78 zy%Bf9TqPzY%ig(f20{d%EUS!Z!RahS-~Ml)uC5n?K?Fi`H}eCZYRw zs$jTe;8cySG0dGr<^P`AAPorSK|hPDnOS!0WqEmd;1WIou>(#D3JQJ{_)Cyw;$cjN z{PYBUlVr`>BWEo+-wKAbx)on) zseM4Zjw*I?QODS=lT0_PT#{e(pIP@(<=@Dz?WFw;z>*PoVN;E=CM%=8HPu7?1Wt1- zmiaYhL;d#P+S#cE%ej9fXo!F6-f^y}2hEbNa&R;jCAqk`$dE&Qm#%_6DdzJl%e2U( zcSdgct;g1DU9yhA?p} zk9ejDojX@(A(pRvTZF63H#HT(k89!LBRwN+Oj`8gP+}2Dz=JyS^5787LDHx$96g{M zK}7XC96pM+c6DXE%J{bh^l_z{ldw+*FkonfhMbB2-ZJt%VdoK)UeXe-RhojGug{ zIKyvi-ryMD39Xy)#eTVvaCWP9TRDV@@*>rP)#{m$h)Y;<;wQvfC?wqHkE_Bmeux(q z21qOqkpBT_{+X@`kk;3dBK>~4dZW#riw%_8n`u7VPEl{9T#yhgg{PtxQ6-)uMv(Tl z?Ks^VH}#mj7R|XzcZ$slre~f_`a7>-FcFGk7+F)T%B&Fsk=^i^gvA-TqLYJa#@$h9 z@bKikldlr^IB+KMVu3`}!dPyMAHctH%@JwKNyirL1;2b>EhCMlIzDp7Zerl|{zSyg zLXU>V9OFvFF~d|wC$oDIJG<^n=jl$(?i(zFaboJv0OhD~Y95V>6FX$4{0!vwZ8zRk zhCOXmks5kf8h)-#d{9p>>I`zpAz?l-A;K6@k~_SGqE#hOI+VFq?FeMnd?cGCQsLns9Bs=yP?fW} z(kV+q@_xEC6}7!B^2alRBy;1<3)JzZX=$lfrp`FDwi=Cn3W?n|DscH!0&G()2Y7ma z;^jjuVf*)1Ne(001e%sWUT)G+2&CvoL`Ggb;bfipB?)w6pW5lJ zh4ID3taFQ2&U_uiC?!>zL^0UMdgyhQMxOFKpHW>C;119ICWSPu@xWe_=$5E0M@cKN zsYf}%8|)_%OPqob$<0LPL21e4kXDk+$Tx`-5xzo*1dZWC^vTX z>7xFs+hIuUeq~qx6N-PvfP>59GgWu+A__X|(gf$t+HkWu15AY;?ycIjQR4^ge@+Ft z3FUuW2rHmB`!x_f2?GhfC&WVXHooW6BAFuljWna;>u#SSWRlod+^gz6(euwXJA5d6 ziz+RU_K@iOk%cU?(pH3n36HO;=i6hn7Y4GFv+^ z%YFA!kW!CqWwRLW#Il>0Ek!f#lZk5NbQRVHlJ{o6mMS&l;QQKO`2EeYik{~S0&i|% zjix9a;R|rqjLk?g%THHRq$>;=T5p{9)T&Ypo}KAm8!=`2J^VYYp~Wv=Gk6|*H0#tI zNxhU{K!JL_3r-W401KN3T>qM_<_>}1>kU>uHq;yaHviscPmdb>2|P0L(ciZs2+irX z07u(ri0axk?&z3vo)MBzyWpD6FPsh$5ujO8B-C_U-05r?3Msi)>u8*Gc4xnJ%b+ca z3!Y%T`F-K&^>_C5?suf?J^O-2Q^6h@>f$r63C}iLY6gZb@{4F98cPaub8uk^TFjT| zEVR%cMAlvjqS|s~Xaz2sbcl-!eJgxA$suty%k-_HOOB+M%nPv+VU$SX@J4%x;a>dr zV69Tu;T-uAarY_b%GKO^DY#yis$^t7!JiS-ySx%d}jK$1BHI-8!!{$BT3qDLDvkfWRrJ!no?y@MhuG7Y8tL z4S4y-^y?E}I!^fR-*deR^#Lu`TYwrKJIGQnBCo8h+-7kFfJQ(0*s|L*e1>a2nI1M%rUv1oQFXEw^!T&VqWPE5``iw}y=E z)CpmpTXV%%Jt4}Kb4&M9ipP&P#;&?7<JwaoNH>J)K7yR<;yA`nTc%W0w9hWOR=M51(i;1%4%K6nFnPot}oLU3nYV?B)EYO z*Qfx?sgHnP2tl)s3*xo*Tf?EIZ-eSf^13wx8LlW-9|lE6M-3L~))p`bOW~b4FzWlN z-dME2Pn{k1v3RV`^@z!IB)igfD?MRj=_!mD(`f*lO%k^20jyxNG zuAmu_%?=?otn6v%{oEj3ccu91;{mn(Ky#?)QTE#-OYMA*=2*Uz;)M)7$69f>{;T^n z5{z@6>w6-V#>TsI%{tQis!tFT0p&~TOx2#b;ybg2+ZzaR=eakw>-7!>fjV=%`|=qz zyl!L+g=2Pu2+MV&uA95#Ygu;9BEHg^_|7gvh6c?C0uj;3Mcd!ldzABWc-TZ&)_7Y2 zbUizq0(i|&plA9?qYn;JM-*?ii%mTQ zIIS*E1>^ue>W|>cpCY(x(zd0j+Tw321bQYt-bjBexqX~hAH92g+yb<_K1KB2dx*y%Y`%f zhmPcv4xY7U_h8;EyGg_K3d~#`_bdk8R!!6ea_kOmi8H|8-6fE=`+lY%_SI||p~LRB zSYjMM0?(VT#-?33r9I%cGe64nxWqaM0IOKhfu$bRG(>B~qC?&rQo*5CovOYbE008} zKqkJAHLkSfyb_L+sFuB@Gno50K8@IP?X|l)GJmB|o`7v{WfCcA>1I#~{cS|$JE$`Y z{r=vZ6EYhCfzkQ6lJDHKjcJAE*RJxy#dR99JPc5&17tGe4injmWlMA($NNW%((u>i zX?1n`c?>^S4_Z4p$Btx#h^*wDbVXF!0>qjf&G!1VdYHv;so#H~v}AnrbH6xn5R?8+ ziBrJ+Ab~+5dMa{p7q;9dk;qfQr8r_e$~K}{YG(Yf%!1>%dRBXXYsFn`Y#oKGLr{8% zo;5^fl~`Qj@Ivh9?u(rLebzki(nLhUi+>(ii;aj?qnPilW^doI8@@yQF5m`#>jAnd zTMw-=Ch(c=9Q*#R?9Up^5R#kK+p2sV7<{vbfZbod(?#+dYGe0UPYUEM8Dk*Gb>skD zJFj7-nW|o_Q$Uj6;E7?FDMt*3Z$O>6kms&hsW3pcHQ9O~Xx%K4 z>mjJ=X5**3c0S@hD69qx->b_1x7ZO&S(pBByhGs{`oIw38uxFsiC zF8-y5`nGn$mL7cmO(AhQ?Q{~mMzzynOOTi%l+JDRS+@x1pCP}^P2z@?&W-4T+tdjX znIZ8#dA=a~5gj8m6p3jNFi*{__!im!K^d?*(~WDKN5Q>=D6TA1YBHDO=Nosk58Yt5 zeoYp9#^wGSfJ17|8MY9+o;*q4`@$&t2$Dm^!x%$i?woSB zjVo7~d6u`00#e_K&B)z7lj3&DWC$5yDdUrX+pE(7x8yy%v7g84BnfyeWid0sc?)_| zqJoD_DEh0*Ht7aWN`r+ziygo=JQv%FCnSU|)G^gxJQU%u#g0Cqecf|3oYuE`O_w;q zP{YYA*_In}mpm7Nw~8$2^sUG7GNl>pifkhOdv7`?K^7vp!t0FQXBmVUG_}YE1f;m7 zRLSG=>Bu4JtwN9L4zAF_uv~0UoOSf%nX|*t$=H=y&b)$Z6>R`wRW1oy#`?jQ7s6M< zCuTW+5nhN+O!DIQu^jsFPGZ?-^e9;Do8)lyyYRN^m7_K>%Hhi5tc2LaxuTsg16@tY zg`J(LF5tkMt%&J&d)i9i5vf6w>Eh(o4mosB1%AN!QPX7M=T{;jAu$AHvC)dW|HY0& zw(wyxc9UJDH@B;)>K-$?tK2rY<u6PL5?XF)c+Rb6N7c1OXY9aGQu$6V!{h!}L1GwWYuwi_9jdM|Z?cLv%iG+WBaIzW z+?vEPG=4S27vK2}djzODw5D`G3bfVnQF#es9M5g#tMXkfrMwWoAlfGxu zs&ju5sVpii13tw{e*xO+sOwcTov&?FH#*`&I9gSEP=sG<&iS#%?LE56D(b%5X6R8X zT>fb0mrAu)9YwN$fJh;CsQx4W&NqZBBYYV2Wr+198qVc(g&Qvu7Cn5$9EuQmB?^y1 zadR|eC(t8}Dx3RBp4uewde=W!cd!bU7%R`Oc08c$Ne{wzTIOCbih}jIw<}9Vbxk#~ zTOYbMk5xR`zI*UlU40$IV&y@!$gSBonf}yfWf|9d_9K*4<>}LFakq8a$ra_~!V3+W zX2CxI=108Y+Ykihk$C@{$D}fY8-x+5MRiQ zhw!fmJj8(Fnux1fnZ8G<6x6d)YRm!dmjDa*Fkvk$OkvJZi;m*~lIjq$>do-TndztM zw#^$CNK4~`mQ|j7`w)}oS$(5>e+rYhS<6W)8c9kbt9R_%zbAV6KbPXK3 z;DMX`z2hS#9lbnGP0HB^B6y^LIj-?x#wq{3=vXA>(?UGwIVVabAuQaBdId5a3JE&d zuKe`532(s?N@)Z$c~1o%76r@4`BN2F7BElb- z@%kdO=+zw1XsU(1ROR**(pp+_D=heUUEVja@NQ$H1i8rqaAM;2lyRm`jkf+RzDzI! z7Z6v72H8t+y;)Ekb8qv8LF1#Rms^ReaKd~b!uapxebuB%uZ;%CjS|Gi8RNqs# zP%od!BRUceZ*3YAD1`TKvhZI0kw!d1Q^TE=n>(xq-JkmqkL(`zGSynH#u;~Jw!Z7g zWc_}X+#1dA@c`uh6ETRrtTB5C=%%aJL-o&U`h;f_3Ay^jqgtgU0mK3hc`?rMi<@pX zr$7ks{dvbhvNsmuzD$<~EQ|y<(7*fyl66HOGb%CX0h16}Ph$^{0V(30y)^j-H<$zEz}daQTt}cqa<14my^ueER>my6!+K+x~Ax2^ErEN`S6o8FuKM}A?xDbmd%_|{KT3bZ4)fkCvvhub-VOO6!os-k#LMZ%)zn&lmo}j){D; zv+pqQJ%6|G!6~oIw3*5f{q2pPyFTs)HK7STIr-6Xr`E%-%O#6prg(nK*y)^iB&4nT z?|N_Dlu)k4yOrnUXL2rAtn$V9yVzt|t1&g}gg1-Fqpj7TI*D{l74aBk;i#4PV5ApT z;@gbS+y}jQ9asRpObSw!^-tsTcZn{mL-X~-7RV`|qW`rkITEpmJKcY~uqIyXFs*c! zKKoZ)C94n@=+8*?_+Grn&OX0omFPN8A^pPET6xXNLAR+`s+?1^;5YmH>73?iX{`7) z)e;H)LpSH(=^UG(V$Cqod(+bFC$u_=Ba+4ZTY}4V!t1Mr1-qlT;BEdj(@vI^Le%IH zZ+EnJRfFx#|EI8l-#Vk2SkJ-a{s;RI_~!n%_JKzwB-{lK5ND_cA(1*P1*WU&cfG>T zt*N3^b>z32VTpN&V}<9=aVM`^dBkSFLwKv0Ue;q>mnS1d2BY=I-($d8n1;6b6+LmFhbsF+BBU4)anpc36 z-NZ=L{Nl`%t7s6(L)9Hmh{LIv*Ua@_M8}g)UusdeZM#mwYg`6o)gv z7xg2yc~voSM7d?77eCsGWm))K$SC$x_o(TETc+b^3uuXv=(i6>bBa%KW!8|2WDoII zNm6#Bs^h&v5__zIbj`bqR^l$w-AG1_MDdAN(%`21U z9v7PfMincfkSFd1e52luOJ2?FVW8&rB?Xg7ctL2un*+gDmESXD9AF#d+cW!N^}RYZj<=6^Xl@UiU|xIyM9j+v2Gw?)?5T=OLjV zY=>2;J()L2N9gh#;OK)&p8ud~e*X7;37}@<)laUkuRpiOP-%akP)6o_^?}{_c+b*z zaJR&F#^R42@K&ikP=d2JoWFU?b;0e5lM$LEiT??ahPWXS3U}pH1J+mvE8AC82r_XM zh^S9Fw=6C4Ha1$IY7Kw;^6zHE8g%w*0~rn+z1lL)|tG`CiZdy79?C%j|-kwH9LTyIzTBjo3rG zIxzG3#(+%WfrS!A5#tA*9x1RVbJ^W!0$y*_Lr>%b)?GcR^H)AF9nQ5 zc~MO)6NKe;h*#EHQzFP-q!YKXJ}G|sglHlPh(O8=;* z#JOZ$D*#|2g?zSVM_+qqnjC(dA)D=n33oMXw?kL?YyVp0XuTA)v5IhhL`rXN#J5^r?E9_->V-ml1u*WT+`r-Lcg--!O(cJAZX2O9$E znuFKQmw(P#as5H8Tw(@@0{(;UL6*`NLzc%gqx7fTsGo;rNNK+4#h`Pa0u#qIpN}ZC zwn&M`zHP@ux3#vuXj>B;M&W%VH}?ih98Yh|b2n*EX->FhsMXkft6533r~kFhhN*yT z77`wG%agV8;53BI6|5TpG5TW6#DtbbS@BVk_Z%i~Cgwcn+LuAvtH@trHDurvGf0Ih zKg5Ntrhm*RYXXkf&Xn;AnMF9w?T7OS|3VabTD5gYi;fvJt^h~j<49$mA^^uioQBY2}R?h6`E<2)o>i4PVqVWCo*EIZ$3TG3+}!equ>JCvT+c+t#-Ao~OE}4jd+qx=VYps?mHrFCawp<3 z@_*<6_;KaZLm2jVPy_-8_h->J?;B>BW@gwu|BD6O)7W@U~gs z<)&X70-9H0a`oKzVAXm_?%pv+;QapMj)!w=c}YT5bcC;|mJPblw^3|m+;^zhkB;iY z6;!ePed_dI0UTQS&^Piwp!Zpoh&H?qft<}lzsbNb&?XN8@w&-VJ+`lTmfN?>;`%w~ zkB-m|sKZ?VZ8-uB(VJPM_Dz;NvGFt8#* zTkFZ)YHH?~#ulg=zRn<%Mbp{I5dTgG|ET%RUaLB%3>i)k3f;anP|KS;<5(BC+zLA^I3ojZ$_Y{^luUuLv7YRkB_7 z!c`b<2wA-k`Fl%KNwGPFb7AWYh{WF%R(jFhdnovJe)o<187T%B9 zq5u>pc}!%gadLylUCZLp zHrTt3b$9cZN4uo|ULVfvp!d{xVhJP{|J!5HivJPTj=kXoI+uY$*z&)fwTzLnErimcu%sbOrYE-=)X*6I`sKTW&HHfV z_e2Svd}UJ5YB2#B!C)v)!9VqyKFITbs;WJ!e^ga}5P9?hF-jU%NtcZ(S6!>`|Nm{lQ|~EAlLAVCLEb@=wKJ{zz4zlF<-~-A{rDepwR*+t3o~+8y1Y~N zm0j+)wzjo37R9`M)5wDy7|wr#^c9pOM#Sx_PEhnYT!a z01n9)r@fl0-L(jPq^@|;Zu+C1O?&Ui>&-|{=O9mS@AHd2jr(VeKw^^XgD}sd;`F+m zPi3)^hT_s&@69lA91>Y-IXg88Jm-`YTVzEbY!ZXck`ut${K+8bMJr2@WpFb}0e`}o zOe^E8ZiD)GLz!VQ7>rWkRy#!=vx^h^NvkJt&U?&HfLFkz)_>aMR z>mo$`!xZ!?XUfvq*+;Sp@80dMLn7!+?w+BW9~h>QCcHq2`0IE4$=2B6mp&SYP*~B<&TUe!Z^y5bcwlAmY_&EOfBp-Nu za$l<=Q7`=cKh-?-6_i*NJpZ!$d&Zbp+N(}h)2m*O^kW<^&$E*3G?Ec5u=?D2kV1Io z&L9x4{KuO|;2S`9W-&M;M9&6c-2CAj-jt>st^(-fmzT~YEPpl>pQ7{3qOW8JR#hXr znCyyr3y~S?$kd-=&hFs>R+9PlCW{A)Sy#q#B5NoDWsbD=qz<#A=xB$wcT!d+<+!9> zwa$bTI|lHGwe?z_j;X1iGPe{`*Q=DjlTpVcdY_a=vC7z?FujkE^zg4_okI6(oR3_4 zZQj5NrR+NxryX4nofbD6$eK#F7~3l|;?~j%RD11v>51OH{V+Q%aXfJv#0!##oHFsX z&8z}Mc+86ggS%SUd1=we(hnYux_z=K<0MDRs~ThfIuS2zu={Roykhv`K^_nY-LnD_ z&p={c^6{S*4Ybx%kP^cW;^+?cM(sIPpS(%j`+9f&8!aYr*JH9sV_o+&)OrIA!Y?u> z4^Fa@K1t!Q^H(HY)?nS^H6<_FubF0kD^NrFtP6NloM~}OB)yiUmr)`W5v^?;yL0hC zn>rstQDGZdK*Nb5`D!grjD5qFD3!eXgSrGezzOxOmDGB2r+N+5HakwGCz>ytf-ci- zbvE<@Su3ugz>rYnM(YHC(*Nz_OVI0Q9@Nz3|AH&7#d??B{yfRE4a{E_Shn)vHAd10 zGc>Uvo&aD_Ni;&qBq=pM~+8(=f$r5Z>fQg1ciJ-7RI%gwh*Y*ZWC@}=&ndJ>ckOViE%QaIbKRyCwWQYUnzfeL?%rs| z#L>ZCid)|0o9V{|m8}hfCN87!eILRrK$2C1e$`BccTgm2_BwpzWWN`4{=AZ2o%p^$ zQ5!1chnjn$l=@jC!x-w?(8OqF$#rXQ6y__1g`Pk==tYkC!&d8S^d50w90RowT^kQ%N#cRqqx7AU+FWQCrmq>Kjn z)KC7U&_63?Vq!)t;w{X~bQgtREaEfFj;*+c(c@dFt@evt*d%sBDb13*F70=*=mzrd z5_3YC)1N_}0Hv}8lnpFL9k`w*6>uz;F$%SM#jdH2pHz&Rt^c4N-Dai+&I3ou=q^?% zwRyTk=6D&CU~0CQlnPsa0(V8Dzw}E3pbo5jbA$e$mmZfQYiyhV1WLbFf6aF$L#kaw zFd5ufs<{8zG=0y}{Az8zf{1Vg{^k<1mMb|b8~SO0978j z8ODMH5UQZi=&K-~pmp0-8_wJ8b<~~xfB>6D>kn?b4-}L$)fr#Fy7}L$9GCi!O5=y- zzblP;1CqCXM6)eW&erIgQye@Xa})ox!ZV_*-2kO2b9(99Ycn)@cSGGysDdeq?TnSDsQt?D z;-7aUywrjj9X5=~uzQEgu%<%7ow&@cPgle$p86`l+;eKUPQTu_lyXRA_S{zYNLo$V zpOhQ@a$LPFb8-U;AeWvM8;_(cKVZG+nOn*Ot*%H6Es*eZU_|BLj#Sc1=~I-q!m4^c zJD5Z|SjBgAf-g(BTs{4Gsrz`jeDx@bwq*icbz7ZjaLMtd*BKpA5KmHJc@tG42WY8J zmF~`=__d)bAN_(4c#`Iy*HllDX67oJzQmtOZ45(ANF31NjOEP2Y7bB@$f+Htmc!p< zTs(K3@{fGtYH5hq3VdN7y^bL*!lk zEMbiQ*|%=&ub7UR&^qjO4=UE^4C~6n)=LXn@6F8TTTkQ}u3&FJAUcB4Gw$GUG(f$R z52VUL=gS<8h)_Y46Ip?Ia@%LZb&wjHD;Ng$tRdq0iaK1lehw*?0uf45eLjVr6BDsD z9ZfN=zgYo)ES2KsXz73v<3)(oI_0Rso%vrI6z~JBQYa`V%PywO-{!0yW6$^YUfgY@ zFL7MbnvSM zoWx-Hn0#2Fc-P4QGy_mT@8i88bZf&mEj6V$7$&@yzi=$4rYyV+iWOE*Z3-vQc zzxKkbQ`KyTITJ^>Qv%nGxa5Ayg6q*+KUg6*D63ZvwqKlrm2d#9_!bqox5RPmebC4; z5mP*Wf}h>kS!6#sxq=wA?E$>*t^3@q`gcj86%SiEkPks!yC+F?X~P+ajcQLw7G?fh zj)1MSFX&9mYzD@_0p}bca?jDx5j1x#;M}VPA{o!elW`QC!p>0dVQJ~#fDFZ) z8P&oMHPI#y{QPE8OUYW6sZR_a$Qye*EFItc5(va!P$HBzRZAtw>({S8q*R^j+}_&C z?K`l;q8NO)f%#N_Q9Q3zi2$+S#{TSg=5ugHqUxqn3KrSfBrJtpzqZ-fCW^s7#~Jb5 z>?TNayl^_5#5m@pb`UT8s9~Vs%1CvkX~kKgwpeEt#O%5%BzAOy*M8l1%yZ?1n_I~= z3ZyaNM}oXd&9C4OmzzS)DNVGsez;!2t65Z<>pb9^N5Oj^uGTd_IGq-*V8T2k_9D3L z(*eem8n}{BHG6TFUk&ivZZ8;^Jo>%2I#mSGxyZu3YF`HABh*Erp#%(!||~;~HFgaQ0l5~2m z9(0=k1y&rn_MaPE!r8dW?|5w_1> znU#h@Z0ZS+we+jQHyIU*LZj;Xo&DKh=b(Nw2TUTUvFB&)4t3(@a+K2|jtYn6cDYB*L2DEf+ohc#_)SQ4w6B6Cat-QjGcLKfeT>`lDZ$(tB&dneixQVU z%)YEu(cc@pnNvA#br);b)>}b^*zk37J8?4=^M-oq)k=(c*ZmyxC~|o885ix36y@v`il6ymdtk~-5itElK6ZD_0LZsy~K50 zT0frnosdnq%7=NKR5=tv=!ZVl{*--?!gu~#;cEY9rRINmf(d*X$^Qe&DAX1707NGA zI!cehja-z1xurEG*&yrJ=9uR^JKha0_a&XJrOf+`y?C3-ekKFlS!BHVqjLd5Js}GB za^3YB7M&(_b85{vlT+e%^~64x4xuGqy17-g8*f1M;!+CfFSHw>TPc8$?XNSHnG{5M zo98@N>AE~zb;sNzCFQSAtb<&|{lyl#&b7u!!h9pV+J z9R+Im#j&My5bX2$?L6vM-JXd>paf^fC<2F#zR)UR!X#$?LCUpI;8!IKQO@ORmsiBY zyn>o%HC000)AXA`(N{b6a16O<#?O_|dIW;X%KRt`wAFZ4kMvxf4=Yv9gmz#8g&|!;pwFYH_;Ek}xg>9ua0l;*mhf6$ zvM|)z<^2~uuNNhLOXIUTGkVj1WRGSH?$`Yi3O`aVLx0`J#cHjxLt6pi7BkbC6my2E zKKr5vt-#wCA-ICt27=CE9JeW6jI<@UwyI00Bj$eMNch96PF@e-l;pwz?&jOXsRgV* zz~#LK;?`P0iukR93m!TyU`YF!b^s(^e)1(IQvv@bk#JFZJ|kY_;o>+}TW~#4ygIy6 z$c9d>?1HO)<%D=-4LbYR>{iN~RpTui1`jrbE*1JPw|K1bUgr|j;^Yl}u+FSLPUs4v znPqBy8md-aH+$6*IF$Cjm}3&SKubT;SwOYpPn_6otBM*!v`gWJG}I?hW+>AhM60t9 zL0*)YMHtuUliIP4Q;PD`+V|a{A=Wh3f!mR!7bMjbd^)jN@i=lAwaln>7Te{eYHL~k zbOM?^81TMb5h~$;eXs2}Ep=hj(lds#)r+VHUssH~b3KLqsU~}jLIa$=`&vgxP$qq^ zhrn$&ljrUp5UI@1=5eqLh+xgFzt!ZbG)!lu1Vop72uQ9I5R#vL_%&1(#2@ZwWaM;%I0aen>`WTLe)`=@qB>CJgyZ8G ziTOKLTlI3aN%i6^UvjqQ|;GN{7qxVLvU+UelO zX~x$@7ww@kiG?3}bKZQGi;NQ1`0rvgIcD4VfFgtS_z6RQmIjSKe|7;V#}cGt($djoU~@>VmiN|E1(ppe>wm4fJmd^z$a0OdhF*n7 z8o|f4VV73u07cy5+c-27pz{V81(#0!yBN0)|&qg9Hr)8ihGq-h9> z3JQf3>!z-=Pu+E<(uP8hifWA_pK4F|#ocP@rU4yok#7`s24#>cuxB@Ni0icD4q^lsQOdh@$(OdR<#b@7a3qP2210IR=b-teks&Xu&q~&#xOtBqi-&R z_3L$v3^ImiwN>N_3cj~7!R$M)Pb43K*#QmDbQ+9V1vWC{v)6Vk#ZRU}^b=F1oVJqg z%Q-O2=H^=}rdb90q4mh9J~r1oLL#?xHtUD4%{N)OfK6(Dp#GBxd6-69e zsG}?1Z-Gt9jUu#m?GZO``D$NUK;%>6KO2dktb;=_d7R@0x}su0%f3Ttq86bznSi|b zz*53@@b7a`O)0JN^GWs2ojVUpS)wm}&8T;5)9;OX z@$ruSA1%ORzdOPu$Y(#=uz7qbuz54jrl7iMlp~(&C%L;wnn%FVI z^APX{)|~3tMxH(BGFK{!$B(XZ{0yI*$m_5 zFW18TGUY1ARg~Ah$v>W8b#b+Ia8^RBwnU+T>jrnX2|F|Fv5~_hXaGUpc4Wi<#0)giz^6Bclj{#n2->9At9$AElXxU zDF#vn<6Ajer0;>6*r$A0p$T?h`E%fONfKJd?Rkdgzi_;X$K#oZ=BeIP2$xskm&k3S zJ@&3)1IU%O`NfRnbkoM?c*YKQ_?GGkH*!B*d{N`~qspf!NVZ_hr_^JXiz`annOm{Q zNYO5LHr>_A!Q+kwqjiXNL5=Mie2GW56e1>iDLgN!)>t~Ad9q68f^lfRf_)GW=Nzt#O)>g5wP5>gl3 zZK|ibx&vLsZ*|J>laE_F1}n`AlD3UTkwxJaw3D$U;IPjAn*L#rwKWsrJ+GA(W|A2% zZbDCQ!N^LlSR5gh12u5r=E_UQGALVGxL*|#6pRyZe_m6WMHb537YIO)U(IcP8i~AF zG>RN$&Yd^7^X|i;15-Y?#Ww_)_`Xt8F3~9ISzx*Xq7Y80Uw&pLKUKkq2K8xGq z4&5#3NaSE=e?Wryp&Oev7bXW?zM#7@qDa}_A8a|mf*n(k-Br`jD1|8T_`r)DIUO#+ z;6zvNrhKJ0NvA2Q)2IS)g?-64n9CCFi*eVRjW%O<-fr{|COqnFz@k#wb8=x`C6$l6 z@u@)rZB)0t-fYG4`@dbU3Pe${aBH-6vY%pI7H6v0xl5Y+m*e6uq(m+mG3j;=ER4rJ z`GU!G+1jz0dMJ94=+b>oP(zEcl*#?OP`ZC}a$(^ivw}&DyU^wca!FfP*Ni+hZ}clQ zSpToOwzrcjdVUPv;tEKVct#?%b%+c|S;)j)?ftm$N|EgV^DRF4DxsBIqPxe68{f`) zJVZc@iY%q>V3ry+Z4#MNSSxo~*5%FX^zSpcK6%DHkrOu`b1d$H!{iYvodjh)PTQzT zsNKAp6S&yoV$f3|m79Mr$FC_1N>7ivZFv`aUm)V}T^t;K81-iR1z82d7W_R9H;4gh0WJ~o;KqeQl1~|5NkI#+25f$#-!`iiWd%J1)X;; zy>{k1(bKVoNgdncz1+8IqN9?cv&3|pa79`v_97h>>%wa(*2$g*W$FwJ#e0%!Ee4RfZ+CXO3i-BO)Us$>W+E8zYL8%nST~ zbdR+XQR?aGqAY0~wDjPTfz(+#!sIE|1&tlU9ZT$_umka(b6swC;cPW#9gKXGRh~AS z_UmsLz%)ek|owO>oc689mIj#8-`Nq(8UAT>Zv#cVY=D|c1LKe=N^_3MXAG-2+M9UoQ}3CF>CTi1DZK z5v^zK!v=nX!$c#o6U`yg9*4pa&y4jD0iqkslhcYxtn($GL_OSBy;)O4>P}*>)*Xj7 zKIJEa${-Gfm*}smNzNVz<_UL)*R5twD{|0I_J*2=N|=xob(#y~GMw$D)wbC@bj*bF zii$b*(%ebAdm2T0zMfbNVrD$N)OXd#k zjxKOH8hUBdzJLp7EsZ+eq>r1C5##KvArAM&iPhfTUVd_{u~9L%DT{@i_AWG&Ja>!3 z(FfPp8r@OtPDZA!nT8o&%hJ!k&uGy4&}DfPDH(9_ODncI^zcdU9mBfuJ3ixDaJ$8? z1NJUX>0K7dbaED$Z-cEL4KzdS7TFVPYUp4XW*NJ(6SsZqBCaGyJu7aO1U^4TZXUYk zEvh0&A#bR&^AdNlNt?I9QDg^(j<+Gxd#;DMzEx%S1Nrj+!lX?2G${#Bpn?dwtSnH4 zI8oB-{=e;~>*nPAJm=d5FpBWYxll`DYBp&#ke-oQY#Lgsy_-OWxbakDvXj`5Jtdb) z&Eyi3C3(sOdIrI#aO88x-KCq7{kpZCn%n5R-^2^UqY!%Ec2MJ9jh%|_7Yg8&3_bF$ zeWDB*6Viby;>HfQkD@e(g*=(pUbK_p@m(XQ(hp~&`vteh4PN$| zkX@XnUZGK;h6(ub*1r6lJ?*o!iqyPfip8~B1b8iletqhF_*;fr+ouTma?09xs{t2m z=b2Q)Fub!>V-Vzy0U_1h%a%iEWy(QbmW>wbx*n9RM+OY#w&#j6Z@TtFy7Cw=HEmMn zI0?_&2`B%eS2U(9=Vjsj8{f8fEa<%n{RyFd=%00`v$X?^Y((kl!o=5zBJQ1RSy*TA zn#+*woX;pqs*XfUjxF?-*9FrPZ(RuH%B~i{IxUK-h(ZQlN!Dd=EFrcnmsmQPmegz| zUt>9Ty7~nawtt&)S`HwJwD*D@$m1q(tf@u9M;f34E_JnICZ8`pz|ZATas_yy8yIFJ zVaJrEO+o7diZ?IctJ<~M@Z6oNTUe#5d%s>>MWcKTMY%}N3vc}hAGk00SIz80<-4?G z6=939PS}oGbyoq?zZ51x$goQ1vxU(x5|zlv98meZ4wu5Mr-Dge&y8HDTt&)X1qhLe z&1P&&hv!tJ$ig`)n5;3!HgvB#gq(KP{#vS97LOh44R}OtEfZqwaMe3Kr3|B#l)B!B zWv;!S1QxJ(oJfLEQnzikVCnDN!)=3NM0Kjm;Ikj^J9!|=YgNhut{6mLZ>3{m&c&UQ zDB7)v0!7Snj)a?AM8V*L`Pp-Q{uZKl3@bHYp$Kx>6b2%oJs_qId~kM5`gr-Wc^^GK zl@lcbpUDc4fM~#h4`~i}Nb>2)&!4|6x8r=<%b}s}{cL#`$dxW&qm{amBJbn(i5dN2 zg&|v%o4ZdG?@v5Acsk*+Q|EG(>o9Kgpw1r|G%1EVbCD}v(#0lcE!ED?YAPyi24T(Opuzx!9Mx~rx#wsk$J)UX+vW` z<}&0_ip<`zy2)w&#a}8cq7p_Ik{n^K)U%MU8D4DpBMOeUn|j~-A{6yp>^0*=oCRx+ zJ36)LHw~Ro3Hz$tXz40+l)f(GfG={;+IIVJn#bhZ=q1T{t`YjXUeL>u$S@t5L4U{F z?-w@@GDuWstC4G83Ox81P6nm3OgW>i(Whn3)HT&$)&NqR*y z+4d7elF_a|CDyO;_Ovtyg8nq?C_|Of*tz^IZNPMV40Dd5b|JP43Y*=Sp^;6Bo=Q)M^!V zhlV<4cv_NUKm9T>n4s>8lbpJ^-xJI&pIFu~ytj4bi+h9Y_}+15-9Xg3K_|JyuwZd*F382;W$ovBmVn*x`#aN=NlQs4=YF+!81z}M+KhUSS z8pp)MwCFn+)B7PLAjrlm=f{HFu^K3AEPaq`((whI$4D=vT7s`#?gnm_x^6AqTb-2y zwGl#0kr{qNhhe8~RXm$KWn1-{fy}0G!N?BsH!YrezH9%tL%?yUH)|JKMxM;(tS{@j z^sBv{wztf}!os>Nu5bzXy+EzshG2v@AoZ1&!h6_XI&D`eE@gV*|8#XkQ?|P&SKfUlNo3Pw%?J#H&^R)^M&SWmF39QgetuDr!AhIU2}b{f zU*c|dHF`L6^w=Y?Yqo^zmslQRwWvwwwF>7d!vc>jqcqmI`dUSY?bvZombqWs5qqP( zN0c{2agRUoksD0=Eqk8#!J+M(24v(-x;gjZtxzeEZJ$)%_k9z{)6t|{@+8O8`Iv%C z7yY9LWc=aXhZDFSEaW$`&PsU&G-V@1&d$zdKq~-LG7w9U)SAxe%F4{F2AmXWAd|NX zj8qJttP(E94zkuP^X5jA>H~;LYr(N|u@=IqsTu6Le6P`=QRYbYV7)dkJ91qxL9Fr} z#h^zhtGX1Mo5FbGlrWic#&?DRe_-)lt@xE?I#`HmTJ6cB_Xk-#zpovPU_rm%wP@nS zSGIYM>`MU`7E)*2U9iyx$*C>VecY@{(4tCDu^d&svv6bG&LQ67{zs&pX_HpvPX)K= zy^1B20;h8C@9HDm1m}SbDHRN*wciGb6oLqRBO%cm3V{SKF6Q<2logSc1B^BHgod2? z|2^$XFF(}-v8^RAs@@J)*U-oW0=YOFWnz*zZY{^mfdwrKPR=y(8oDK)xwOF!T{9l* z&}M6sZTJ4@l5%wUp-=|z?grlv)LPHxmh-O+@e@z4VXNGeX8*xsubt4MnT}xFoMhd_ zUiAscyNv1l1GMd$!jGu^G4JCFDRUFnU#&WYk*&jf17^wFLyZ~pnF%7!w#wnj(CP&I ztC(;4zfB}fWCR+zeh$yhWx6B9=dRw#3JVXpz+r7dke$sBcZtag_1@owSoW1`_RLbB zBKL<=!OLtxs$XEF2nL#q05^bx1uw|GEpuMhKLoSAep)yb?|R#VNFgN18+{1~c3Kt| zY%GIBV~wLMZk?3kr{Hi8CB8FW*;i!j`l`{9lapiGxP6V{)&~oCb)4V!+yx8zJXL_7 zKkifvd0+N6KNkZ}Q;JxZS$?(sL>V;MWlg#)=DWOPR*A$>5Pj4>o`=7#gR+SMd)dDB z(N;<|*dfBD_GTi3g<6OUYvYXHzHO&eWsX{xwom%f8H<)|?R8!JBCd1rzy!JRD$Q~t zLr!#CYH2z=1NI{;BsK-VNXhh}Wc+~R!XWvq+Jk_G6GMv{oOKZcX&qK~cx%hlDvUK_ z8c>@>S9}l0?a^{!=H`u0o25+n?hCGCO*zPTiPxS(j?;O zvvcL-^7OesSnuB;a>XS80^ZtPpO~1*5u09o7nH-K&id{g`IAc@2R_HR@D$}otP5M> zCnF?36_rapf66wpzh>&Rsrchp_v6@>n~9USn!uM0)Al-t5t2ErnaSvY3NS5v`vzf? z;m8<-d(n>3z44~t!dBo*3)C!^Y=%Q(qS4ym?MP)V;eO1Gb|)@N<*S zgX@R`o!mmc6OL-9Rd<;@YcN9hv->7HZ!Yq?*nIlI;!(!3R*?&)!nYQiZte*xGU2PD zh(p1gIvdXm)eO9xoXTc#-e9Hy`}Wuf{dr>;EXX7n4JLS6g7M3JU}Q^mm4)%kZBkI_ zPkvzd>H8$-o%Hrae`)+(hfBl8zb%{71`9b31UJyq&Q0yHx+ePOYg&=LKOHYgfe6~I zYl08)t^lg7-q8*|+|glIR<_D7$jJAn$gzo^HGE!1CRjM@+~#o)t`?R%$(;;Y$w0QB zt2%hnx$hc$I773=ET+x(4Xh8QTmk-t1q6=aP}F%@sm8<`n=TNH#uJ|p6meoc8hEd7IIVZf99@s0)Y9zjoaaLlb`oyr@aW$u?6BXn3C5yhU55!P z7hX;oUK;8&ttVJISV*JAEf+nnHd{4ng_S5c#*s4dGnEy0d>wr!L^ty&3xr zbo;gRqxt=y<3U(nCYc1g*aG9UvM=4P9j^`?)UoCg&Ktlk_WICucj%xoW2Z>@gr{V{ z4ZBsropx?lFClK7V;XNj>ue;U!PxuJ-NVYF%9MaZ@wHo@>7>692jha7gvk1Xe?Q-*Rm z+XVo%YP;hcg1W{xEjTT(PBacp9*z_i!MKx7@Ap~7E?}}4iD`M$P9mS*eqQ0%k4q{l z81tIb?d{;m%F17^`efl54&Ulf2}V`gW@91kE4;95=mVnN<1N)z!?K4Y%bAW{am35$HN>7Db?{R` zveJyH_$WX-gk=bDYG}=l*Er2ojHch-Y+=|Xv*<{bX7jdjHLP!GRz{Q5PpI|>Qd6*b z!B^aGa|ZTgseM@xvZk%|gb}-}T!%vwLFM;Z3hI#5bm-oSI)0Pe(MiAjMYXqbdt|Ey z2I%ROs~{KYm7@T3uE3sDJ;RY$WLs zLNYW=D&1&sG}|wlj`|cw5zKZ;QR*n#aJ=C}y6hE3VH4#SFQ_$!HKtf+9nm@XdmUQLvWjQ`RK3Z1R!uk6< ztCK|NtL}5ogAs#@^pA_0**L=+{DO#+pQ|`0>0=dsU)<1{@KUYnluUb~iB)isFE1+; zvZw`ew29}5*0`Z3TXkD1Q}y>W8#-bek1}|fHvl0Ub)jzmyLoSgqrOP;;K)>aZxx=$ zTmP$*O-;}&t!OpsusZe@%7`|b#$a_E+S_`_0r6;YBYW?Xl12m#;p5i?07=N>UL+}zHtkL^qZTzwwp?@ z)3+%dl5PtOZD*(j^<+wgXdzTY{*6eT%}3nP_H%A$ukN?RQ%m0=ET0pceI!H#-*c@W z`1`TqCNx3IBw#j`*UWu-?BXD;Q+j1Xm2|G8eK>f~DT~ka=iwrGN}hl5ME4n$^HP%* zNBl2bvW$mNSy>s(qyI#nYF$un_!o*@nMcvwIFu+0dg=?5{8a5D+&o7L-Ij6g%@lwW zt?a3nwh&0@dzcV;%l+r{9N0Gim>*g>4lhm`q+Rba~mfdA6&Ua%`|b{JR!A_ zN{{KZ`1HPd?dtGV3AS@*bmh}fg1YQqzT03PF;BNff6cp=eO|&jOM?NXNfThXb>lhr zaR}rp;}p_e<{k~z7=fVrDMpCmXJ%-Bz1-;!1Cx6LG4n`D6ex+|W|P)3k@2c@-X~nrdVyST za7~R|d&R`Q7+zoovN)xx2hOrT-0azAevfzZ_iymB8|X1u#Lmsl1(%D7L0L!vQu;o0 zfh!Xi!)9XiSW!Zox-BoR9C542rwMx`c<-~%*W&IQjXMqNKWzLw{0L>;k|FoldQj0p+PpY?0j-Qm~p{ zT%K8p+uZsXH@a)#VCg?~NaR^VhaUphIRc;jq{?fF4|&O&CSi$6=_$9 z=19!L4ZJ4K7~9IagT}EN9d^@;zYjtNmDvRHWzLACOcOy}zO{Qu^%SHu%$hb|-^uEG zSY4CgLi1L%PR3T*9uFK1jo>;x!)p^EUiofH@J=XvX=!PuT6mQAjxf~@j+**Qhj+&C z3iCZ7EzF|~zB_BFUYtZ(wwD+N~`@wjg8dYPjyZzBN0qkHX-l?Sq!t-{vkQYPCW`S3ef!o92 zR#wX|N5|#2xKWEe4#AUd-HWf?H)PuA5Hk`>1n#OYQr1r;0{2PD+{9#fwQEQ1Do<4e zl7uhAK6U=l0_aQaBC2a#jjw^N3;7QLj{oOE?8szQRu(5En{>k2MA^+!`nU6M4)z_o z|30RHZUq=P)rTCk|JAFe2vEGb+6VluYFBJVD?-l(50!FCqxp^@Rll7m>tVYf(~zAn@;VTyp~4JJHPYv+t+$<6J&v&75b zQTyC`wWvD#P^}(-vCTtu(+zk zl22X6NyW8R4u{VggNCo;P@o<7pf|CE>3PBcYEnuAD;hbAjGVoG% zgF&i`AgB1Ii;GKMxT5lZf600PBTwW1wOs)KnTh-&i+B`>zkR;d4wNZQJK6m8<|P7* z;vWdee(c7O&6%hXBrqiWcl~5)LHChbJ`Yn4bo?(p_n9h-Z~o{PUsV=|CO8?kgr%u_Vo% z7Ih-Kgan#CF9!$%Op@jTEj>L=-NSD-!~7#CXP(X4@(lZl+MmmHoe5%*scC5iQWwt% z#J_KaPXy>hm2PGK50d(8U37_`dFs=Fs5V}5_;7c5@n;at?a}V8O_H}qXlHC+Xz7*3 zh-F?rX2-2Q%Q)u=o*jTx$|v3vPS0P3&TFJUJNAGwZ+);?eMR+PUCInL_w9 zTb|4hSC{Qn>AxGUL*HboRtIR3kFyF0X;ivFN~J^uq!p#4UAntNMM7AXr9lLwy9Ja^=@yod?mo|Ae!p|h zf8TX|xbOSU^UTaWGxyA}aj>e<9#0SQWI5jRN>Mh?G>W;viylUFDNbNc|2=R8BNWrb@k8OQfWr>rHl54HlV`mfh6Mxd9KZbLG;@) zO26$`T-~aA1%aeKYYOO9*VL0GVOE5{CY;}*->Mz{OIrGd{p2huyyRLk!+#lHs91~S z_Y@V=CTmJAz1`j2Eq>N?nT?gTSBwka^c)R@+zsQQ0ed&`Z)vlM-Z(EjPoD462Y>R7Rs6xeePc^foslRjTxXmOa!%A<$tQp5Ks$!}0IcVwF2lXu&y_MYx zgyB)`@`+U*SIBMW*0KJkEM>h0DI4ca8%XpzTWREXvK|OSuEsz(1HC+WRaggID~#Qs zGVnl_2zGlq@-&d_`8|>4b%p%A(W%%+p2&>A9=i?bsVFEt1ep2eFp6UpICSuh72R_3{ys$wUIX2tFmIo4DJov9{f*;w=0GtZ+s08IT@; zlwwffHmQpJ`JR9T`|^?B<=$@uNpQ^k+PIV^*P!)F_zxfp=WoXr`daqsuXUx>tq*oD zwN5#(N6aTG5Wicgg-q0JXTI;m2fflx9v=-q`fWdFDa?F@?dFV$@8wx?RaRg2M66;p z_2yC+dqz<9{NXXw0DJnzW%4P(&`07P4=nOW3Zu@fm&!t(r_*`de?E&fkArpM-aVDi z0!(BpAqzWu>grfosM#pku%igdJsML_K=nf@Nj#AYurEVGL$B>BUeh4(`{z`{yriG2 zk?-8$VT}J}dKS=QIJE8pC(1j7VTn9`3${5$yYsLF~Q*MlS>T*-*gfr&qJ2UWTND8`#M?{yiU4VkC&R%Y4E5TX>}Li zXI(qjc+(8ZC$e&T7voPZf$ zZ>bp7&Scrwo&AES@AETq&jXu#@QR3Kyk z^esb5h5Igvb^iyYw%wVExh4=3`QjKq;d6JlHN%+LJCO(Y;XH`2l8e=QmdQ25tLEF+ zLl1$|_soipbfQd^qMxP>mubiqQ!)2Rrec@phUYy!e`Io2^(`fm)nz3#@19L@LQH3% zSBx+1Y+X8h&*iesKD*A~JhP4gyZZEVz4+|0+GNYv3Bo%+AxS{ucqryPZOz9W&pW{+ zG83_0eK!?DozT?Xd#*K-!~_Z&Hy4E~ii&ueTUtW64W^2?A1+bDNgTUI3*Xe%EG;`+ z>&YyPa8XZkWzC<^rQ||KBV7E1=IK=RC_3tuR%U6XmLr2fC7+RsP9i;GkQEM1Qb05; z{*P%uK`SNN*w}#Ik75pHbWvB2?uCOUd_&8JT^jNQDyaH2t{Sr#8U~{I7=W>o@PPfp z;$t(6&Ek>l_pLIL!ba;?+d4YSTsX3?nOvH39JDjj-0sg$xTz;@hQ2BReU9a!pjJM0 zFz{&0W`(H`kr_s<7<(Ohv-bNXb&a7OB!#7jA(vRn&N(4{Rf6C}AB}+}Ts}XEwQyBv z`-vW4;q_LrpWmzO4>H6_Nr(sg2 zG~(lrW`Pc3sTaF;%j4PAh4JDBWzqU42bifP{X%MqJmZ~YwNt?JrcCYA5qq1ixz44} zb#PJDt7WTH*LhQP3pz=`%>8t zHib?blL3dJ-&6dcyUF=B(JVWAKA?^G(>pNs)M5xe?ed1;!&g{oIU<9DiM$~c6!RZB zTw0_I{=hD{CJNP}OLGsyMcfd7!wYxEcys0{fGt8;4 zZ$5_~!~8XJkel+CD}@px23r~qLIZX)dn6^6m)GP(6J6x?Y-d?Jo!za?LxeAZt=A;v z;@8k7ZWD=_-LotIBIx+a4o)JQ$;!zdE4W?DdV}e@7uShN_+eoio3Q>9ro!=1)2JQ8=OYo~Z@sAj9(3y`~+Y`WA+S6Gt)<=T{sQNgGMIA%AI+;TFCN|*qtGb4c&FC4lR;?X`vo^E zR}R3B0_EK7J*TB|V}PCH(5hiV=N}slTta!3TqPyFCZ&6Sp5aAd{4ux$39k%q{W<5K z@UoL4C@2UH7JiNvn?)@=1;(CKYNx>$^CBSp?edE=BmqYmD<1Lv`=W4eY;5eacn5&i z0a2Of58yIoMMdw?c|bmQ!TR_cQ=0~$TUqlDT=96xGMonIx^3VqDEkwN#W{>J0d@bop2I8w4aVlMkKVS3nAxzYN z_}(rb4eDT^LdGH}_ykG!{{0s9cTbcVc7*gl62sWMEF3if$&%~qQ4`Qs0jEqzjVPoupVT|ilv2f*^!1E0m zL@plKQ;HTI9v)yeii3@9rx#XNC(#V{rA}AmUFxO!6Xh2dfX7*$pxC(l&ryHF`jh63 zWDr=^zsT}JVkofDe@NB$_Ikf)WYt`NxkP;K1zdOBS3m*sd`#0U8M}@4#brWPt^ko7~S)EiA% zG3iS@j|Upcv-Gg*ip%OY!xBhCrh5E}iY!s}V@1KhtE%3+oD8ii2@Jw^U+$_H@n9}o zFkHrmD2jqv>_1`t4ykHDcErkB1$PK!96%cE_v_hdqY@Ah%>F1)&(Tl?e(H_1l@-@! z{Ngw!2HL7>eQ$&JTD4(Fv%>cBvhrMDYjA$I=LsIFU8vzAQk&q;XjD{GOg4FZ{oxgF zoDV7W$Do-n%lNA%#+^+6T7*?8kcQveAhp5!{n%e`@R4--BNuB>*UH-u3dY9FmXp=* zTO#OktQy79M|I(Owcc(mlRXPV-Z;N*CoCRJ4pv9+0^8>7-)!vspcRY^3mdSf75;Ms zsIJH)7d?zPkLb@gUOdc85iTD|4>~-oCWN(CE0ka^(L;B^&6Cg!=KLcNNg03~!PSn5 z$r$s^G(*%oKYa>cdv5zzxj%u?3q7mz_h*EE=VgBB#TWFSNf>X?=zcv%tgHfpP$rUL z5Ovz9cwq6HzX&)Ng@uKSfQ0idDk`tU zgI^Mu<+ug&-~;_U{m%h219Yj-(dCXrJoxU8d;DN@1i{9&&?Gi~Q#?Q~Rd+?8aS(gA4JkWcanwtKxUy`lF(?+@g zQ#X$;RJS<0yVvB=`~Vx?u%Ll{ev88RiGO4xi5v=AlPY?D9P>Yx1_%P#-{`XldXnQW zuMFj9f|Z!q`1lu{NxzH+owQe`2?8#pGL)BT)00@#c?gbOp*wl;?+q4)0?nsedovsG zUqjQy0u0SPK0dzqx?6~jqTgml#pHW~*srT1TwD)2D`lpuKYe;Q=MQ9o!nO$^^ZsSKE^r{WVPualL!GTzl8AAc&{B3QK znkw0j%y7LWl|huK45nvgeIb<5EPM9H(;X8|Q_Ks_iC()VJ%k}5B0`g4w!gbOXwM-m z4Q%zH9mBZJ!Jn3i9KxSsi?A71piTvL_KgMU1xM& z#~`Qu&x3^1B*DmP8AA7oO8fZz*190X1;6s&dpmZ8l$4Yb4dIgS1FjQ0SU4c{}y=|GqTviugC`R}wWeHPyiK@CA3v{|8=>Y{wq>_6=-E zp$5H+kM7?O&WqX%z>)>Ft z%l_KGw!?z^p{}k)+)vPO@IPB z!qXXd+t|pLxVT6;P3BWX>|h}D|(lZ z(?5WOv1bdUR?Dhycm2BWztsyqfu#r)d;>^8(yag@RAy{#y^N zfd{=SCnv|Aj+Tmw6%7GyW@Uu5$zMTuFCeQAq7t-t|9$uRJai}&dJj8gdo*XcQOg!E zAK<{$*^})3wvnG6A?H@2cM;GDznCX7sj4V1r~IqIe{at)m{w;uCTK|d_n{Y$0`Y2z zxh5!LURa|KA3lWTiGW?#=)DyL*uQVuHym0~r`LeRz-!`iTL2rg-8sbJ?3F`HzD1{2 zGTxsPC@x0vpf)#q7WR)yTpR!$_QByHmCs@|S576ZxLaJQ#mHT-lT20MuN8WaQWxd` zvTB>n?a7O*&z?O4Q3DZCGU8T|dzsb5hY^rhi=3{`z-9aW-Ckagzz3yc?){^}$o~Wz zZ@{pgcv0s&xjJRa+b}S`Jb36XgScC{vB>X#oT$YpAz=Vq=bWx}aA;_1TpT4f7FLgI zR`XdkEso07d@fo^`G3k>pE!U&HM+L*``CX;wdWaz;2h`Gt4N=n<{asHx*Lm?LI5_s z{lUB5UCi}G#WpR6U~PllMCH#wz(We}-&^aB4NhJ>2`3Nxk039UMl$D$&1GGCd%pCv zG*ehqrVn5mrh_eRe}TGirKF{0E@%jQ`<7U*Y%EotU^Z+UtT$Qy*M$PB2u^;d)V5XY zkLZ5dy<+x%9CbcBaMUkS0s{m81~NTF7|MylMp)3Hp`n#ZS&z*ygGX~H!hfy>;HsYj zvappzH@4>g>YVI94jM7?>DeVfp;LYM@b%wApp%_m>`nb_o?v2Rv{ZQm*t;g)RbT@u zBV_+ojJ>O%5PR%|Uw+Y$@<-WG&{ppvNkK1PzT~}h8HnaOMsH0`%~b2QaJIMaDhOoh^J#49;vCxPFJU-+#Mc&h{pgCVE{?AYB$v`_i zJY+IO!tNDeT3T9}9#MY&7%-y7jxMz8pLgBk1ZwOqA)zbw+pzuopWfsY(_w&@`!l4k zI6GS52GE<=^q+dj$;f^lU^brSN`l4h zUj&iLToM@M!NtV|G8FD^ZvSLpY4_4LGc|39aJf*#NDn}ecG6;49-U3ObezHck{ zy`1Im?}#H2blQMpA@#XYS0I%ipl4uQySferGl>X)8x`cQa$rwq-V2qvh{pe71)#JU z=zFp%l;L38xJTrTIc<85z0wPUw?A} zB;gR8?+8Sw#ddKquO1;jK0c7x>FKHce-)hY)(xQHtW*}tRTMK`oS0tRyLZ7^hgsq$i~835rBNdJF9xa9w*n1_O%#Q1zk+C^2?o^Dn6QQF8Par6vP)7R$a)EfaUaY(s`p}#a|Uo!pXkm~Xn zN+JkZ2#d=Axru0HF#b8OA%qjQ>35#H1Y%;c8WHPQ_v1aYNjF7B+-G`DO4N@_-%2L6 z2`{Vb4LvYvGD8ZQ@N{PNfx0q2+{?=fNZUSY2IZIKMUYJIT2gT7vJ{F6io96rOaDB= zWT|RZv#UWZ;Zgln4UA^!2YZhdOH&(!y}|6tD1cJGb|F0;7$Wl?$>V42amIK+Gj3|o zLPSkM@-g_9qm1kU)NZ{*e7dZ*MOMzGy$5 zT8HK}2umTr+G;QrnWs_>AO3Gp@Pr(=-a;amU#>*B1SOySp#BoU!#a;sze^^rqI<*7 z?ON#^AA*J4Ib&deO|T*v=tAv;hzJRpeM^0mBq=9%d3S9hp}M-7m%z@>Zr~#rP6A{? zeqg4;Wp58j-e#&a_t6y+ejCGV^3Xxm|2G1G&tcJuxjaVi0+Se0Rx(6IMREI!U0qz3 zg~|UWAizED0Sond5>f-7|FY_dl5mr5Sip3JT~+nMv={0n7LZQ)@Uo;kzxF8PAk;HB z=G{9Pu(ipm1mc)MB6j#aYSsbdKbA(#^V31fz#(I-wFZCye!?f4twdXkvx>LH!VR2W zfqr#%?l5AhoyI$>OOu>>cRxj9+Cv~2VI=7>l__)=Le|!TCnrk*^Yk-R>7u8kWGU=? z!;e_tU$M8mpP3ZX|Xkp1Ln{)|1Xufg*7hKTAr(EK!Xon&j zPs4dIt17B`s#S@0&N8GQYo)GFz561`9WNmK*1?$Us#hMu8_o^h!ke7@r(w<8KfkN0 zs>)A$kSiNXKcsGCrbo*C$&uF8)kS`^uCdG(>^$+U*F#N zEOpP71Gw&;*--92FzD>2KK?W-_5BMGvRx*KXPAOpU(w16QTXG4f`Zo0b2j*9RzX2;-^10y#G;<{$`!7H zH9?ic-;TWJn$4CS8Rt~YeSzzHH{`>q^e+b-^>u7FEgnl0Dd8s&(kMn@?()7|C;2Yx zX+%afnEKPLYRh?@=Ywcsn}Yj!dL|g67g{e==M~oX3az?>?4OWDvLAys!Gk5j@288h zb3@j3S1P}P9cwP@7{)EztGH40?%5UYtAQs@MoQELtI~jg) zjMzI4Ll&BvdsmhNP%5c0j*&kZ&-f5Y*M8*7XqLd3 zy3owd4g7o&TMR`bvw@)@$MJ-g#9w)NJFJu9o3WLZ6>(4)pe70>z0I_pa+)rWC`$cl z%D!M6U`$`a#P0!<o1lK{2X!F^B!Poy3Abu#_LS3quRxrS>@1olp8^5lhCm^LTD)+RRL0*R0MN!4t7WHJEnA<<4%m$?4FmGRv{Q@6HsP-T2PHP}K1Q$2orL*a7? z4Ig1}{W*}7Y(LmD_IVSaEWYJ7snzwmbC}2Bd@M5<(RS(R__&`;Q&);Y-|4DZ&A=!3 zV+WTN&;s}IqoPM#^XlFfv{;{i+C&1(%%m1^;ILo$rnIepa3c&PpZablx!ncz#(4LK z$jU9e1U<&OJ&lI=_)&SCNzvJ4B=%NXv99~dPU$zXSYgROZB z$l>|b9oop+i@S%6f&fMbH91g1nqi%xzR=D3HS_}th2=(61vUSo6eQB~fsNmkkVyKL zZ=ixiw1FE=JjNZ21_lQ4!uB7quppnb*}dBOx%QU&0|i&K^=Rqnf-h}@DRy{zZkx@> zAt3fcdh#lwo9LUo5zvBF5VsCQw)V0?Yr5+ER=}!DRi32S$f}tD8dET_i3#4dzqGKB zfwi+GWL+^&PA%rbD|UXeO>Q83OSo5pj6&B2b;22u_#Lq3Ki~kyuI~7pG=bRlys;Op zp46jb5SQ<7G>h4ApK|k1ZB12{(TemlA{#k4C(F`Mt2@KK$z0@IkV?Rno z{62x`2Fg6xbTRQ6p$29yp{3E9BL9}mvKq2Gs2Mu#{NMrhDfpp_;WmoV!g8{*!P9#+ z`;+V~Gm`w6`z1cJeYg8=nv_9aL)Vic5w20#m_3IsLMtcX0+Vn9&(r8(|Inl)1|(4p z6x%;<>I&FQOA>uS9Dhgo1bYjr4rNmwRbMy^Dqf`@$Uc*m_5bqjy_hTi?qYA#E!`(i z;=UZ6gU)31f1oT zO|sR-rgj~5@nW|wgOg!=iaQ6oBi1LXGeRL0@NKzq1-ov4(lvyF_&^pz|K>%$OHv0*k#4-7 zxdBqUS8ruCFwyVy?Oka(HTQa#(%qSn$#nfE>9~L0^~w`YrVXQQD1|SOA}b zmYC-47fKK5opJS>^w=SZJfK%}L%Nwzl+36bmQlnob_@Z)1`bFl>}$a$Y&~pl=gSoA zPD(BpK}Ig;EmtSO@ZjFFst?&iJ{&t4Z8L(vhNfcq9lG`zZPqNkQMlZDfGYMSxT}`Z zeCh1KUlEq#-USsh9AT(_YIYxY^&guF`uNn!9lvLeDX)k7N^c{&hwSaEHP(A(pxyD6R6}>dGsOS2^{!WYMMc0!k+$CfP1K!VWvHwFX_DilGjda6 zX*&C?#T1y+@+O8;NA8ha*#NWq7I#)!2ckbyC5q2`8FX1SJA~5*N zEcH+F{i5;;Zr1RnlEAT{-t_wAFNsuCN5K39t6bP;;}t zpxSAl0=N2$elxuQ(w!L&J6Pd97}iX#W~AWm{P8Bt$;Ybp&{(!5V<18Wt2kN`WPkwH zWj`^7X`U70V;UZ=7lEo`TUQtPip92q7!<=Y+veeuHgQBP$a=@%6RkqCxwx0JtL82D zDm&kAZJ|{1reDu*waQ7+H-VXu_OJnrQhT^SgNz=U>k^h@If~a5^jo=qat%z)ycw+> zD-9o`Z<;8O;WOLXoZXXhR!BsqhqEB=-$M}#+K>P@%Rc=7YBPOouivq;c&)E1k9C1TpT8Nk2~6R zy(X5NQ~UaA=^?^AzlJ$at&$M`N8NUpNFSFtCzg$*<=_YP0DS|uP5-NNeGkoU(&$y% z6-2Q&8-2jAs@{}K;J|38D}Ngc!f5K;BrfaNQs-QI=a~_J zi*ig1%gp@cmPiH_wG2ho@!Iq-cUhB*X_}y27PCZX8_Lt8Q)xpk4A>31VVhS`yh{m# zmX?&7Qqi(JgUa&yw-psmcsNakjzELu?v0?Nl{ zwSsm7{Ef|mQ|*dxPlt~ovr8j~Q`-9CH@LWzJ6sr(WWDhSCCe5>P~DN?KDJH9_pDm) zTw+m#`45tTaE}oaXXdz!NrDI@f2t=Q4f?F>{Q|8Z!CtR`ue`DR~GqRA(ERO0R{pTb`572r9J2&MPen zL%u*wKr`f3xW1#yd|R|3YetXKpXlbj7&W^1%pU;~JfK*Z;w>U&b#AnQe3_d-=y zR}t(3zjg||Ez>2l$!h1zjYmf=P5eLS5NS`#+`oYg`}M1IO`ljxP>)u*hAPj|uT4dZ z>Lz9vW^{ck^VvjdUvWH2z8P1pbyvIEBJ1(15VPYc|DFA>k1CxVRKx;PtTBm(!D5ny zLPOC6>VE=%FC%bAIcbsu>9BV|+q-T_em?i+W21`-*J!GjFixB=j0J%{AijJG5z}!{ zaG%^efeI=l#a05U&f91Fz8^nw9DyZQtT%4>r@783+5t2u{rdizHwc3P^`Py;OEbvm z{mo{rS?Oyhrcc(_IA7hN_q5*2Ca0qDMdnFN?|Wx4a=)<@XX(%!G6M~AX2&ykM?K2D zu-jk$Z`SBfbz3;d3uI%;Nj|O)O3|}eT|%RKjBM@p@$tcR9MVvGN5chAw9L9R81rr4 zD!aWb7Qt&Ve5>+!tqM=;n3e+>03q$4oLX^C<|zQj>9wx6xPak$;8nzQxDuEs#B?q3 z(vsMz#r~}MJ$NWcEpUY z30>A}6u7ZjWLcR`$kA0B&>TKpb!g5T#$gExVM!rHMI}pP0e?eBjP=^@`t`K)ZpUXa z??*;DtqPYAqTQc(%DP1o@J7~QkUeOKeR@SP5!zizEG*QkjOcz|goJ2!>+#T-;8my! z@#OSqXJ=aq#&8W(f?l@<6Pbog5XEQd z*9ZfQu(^<6odVju%2!LrL~o}nJV$1=b5}qb>YlQ)9M~Cb)C{w{3m)*P2 znNVOp#1-urmO`E+4OoDxbsp|&3KblA=wM&~eCx6Kes>avT-S8Bv29sfG<#0mjm^h2JZfV z|1dgOFb$#`d4r1Zk&pT3XuhC}6hY-BgBt(%be+xq~5QQffUVZYqSJD>(+) z*ju352a2n0g;$#J)tS^#*9h*INkWQu5r==CArHJ8_UgFa0dAg=sCa(}4_IXd& z&KTk<)h7jXPXuV(*wr^avv<8xcxw{(*Qcym;e9lbus%@l-~rP)Rtej|{M*|gAb$9I zbucHk$w4UFbnpWiFg!#gB+mtKhwh^~jhEYk?L7pm%Oi+_R{AEu*_N^u00SiH76LSw zUV*;8O1q_$mP|@O+%j9cY?6XA#1AZN2TV+7H}#$exPI&e>wu9p&nf{haF1F7CTE$f zKvtxDrr(K#k8k{9>X5-ECRJZ#TU}%EtyZtH>%^$UjKAHA1&9mlH3myiplZ32+ zAWAKF@xI%7&3+0fFTojAK*xOTA(GpwNka$4y`kRhR}Xmm^+~zl701@%l7!eb^X!g_ zjLhAPNbUoU)J6-9b=H1dZQiXU9%28<14x{Kb0y9ZnJ9t z>B>mc^;#2MS@xz6W=$V!N?A4?wq{dN5nWSLsB=JlTkg$=`7g0P#B>X@p$JIPMwEN0 zA&6}@AAK+(XH3QNzWV^~mlV0hZxXlnDjjVcto2jfd@0>q`n=a_H>%~XU_3i4%^18FTUx5Ki(HE=N`aBeddwq2( zGL1dOS?&=r7l&R5Jce^dGy84RW>h4tlyT+m<=foW)=sfpt1(_lZa*kzHS;z0*VRT{ z`n8Q8V84xIa4cu$HZV9q$7~Yd9e75gkp>gPu@avaGaigt?I$6AUF<6G)(+oB`R3~f zz}9Sqdtoge2Iw<)S)-9=J3XYV06DF9LFoo07>@&pGh63Ca%Vv5P3X*+Nk?3=pL(uX zQ>5CvbV})H9(62pe)cUib!tnl-tziad{1i=oUZ51?e+C4GUK~P-7+T zu22q{-!V-Rf@I{vQf~R*>^j|SWq7_eUO_4DCdgta!V|!g8OR^LJ!RLgbO0i(MElzV zH5-jM{F^7>4_h%A+)%)jdmWm*So&>X#x!O&wVsjpICF1qYKm!4W;nISaF*WIcb+F3 zf7Q-eYQB1XU{*qawEM7wFLF=H_wr0DgC}~80AK2`5)str`Zbh?ewBdZ(qQvt+-Bwr za0h`PU!dpjZ9-FOB!l8!zPFNBrR)sb7TORBCeueVF1T~k@s8)2+Xh0KN6vS;`!mSE zejpQa19ba}2mSR)MDj%Rv<_XFA+P4!W_FhPl}$`4FUe)}gzdK`Wu6rKoIrPya;UH6 zbW7$&@ndM&(cSn6|XAZ zQud^Ct*wpEIC%c%0*sNKd9-Aqe9c~RGCIf@LF$)*u1p4a5=_WhbJZld@Rl*ywQ z{8nLYDq{YG6Z_vsQFP5;zS|DZzp*?d-?={}pB+J0Vuf$OZ8aHoDjiVY-YV}Lr0Ke= zj?QmpXsWX5rithZxRVnKH|~6R9LoK$v0=Y4c5l7zN5%TQKb)NN;iflcJr;^_mE9s? zgxC=a@gir^n`e13=HUKfGop6i2;%Y*xT!#lmPhzB%dTel*gDar=qwZuUeHGs5$)j26@bKL?8nLJn;nN&_CnMK|o{TSYw>7Ov zeOd1yf#b_WQjhoj;}-GL^2z=_+aR53W;MGLzpdjR?>G>QHUb<={s)CvuH3sLI>Dl0 z=l}wZp2lO?E!-c1^oCB*LhmNj>Wh@M9e0Iaj(1X?d6T@}IcKYw7yJytHy6JswEo3m zZ9H3a^}Tdr%csLo3hvU0s9FXpQBXEiZaP{SYj-{)xpm(0O4cpXsg1HiGPE8Z{&fKT z(q-HpE>44r`@UvWrsKMEEH}JH`s1!n6+J(}?V)Mi6*%2Y&v&#FfA#%dlN>cfC%mOOG@?$FH$U~o*S8DLIP*LAAE(G%X?Nh@_|hG`B-_y|8CTl$W^+Gb zq-lywYNF%4D*xvTfOjb6^=u^8Ld0KS!MZi_oW5l;2q&g}V|UYGL}%g^3TyFoLgzE4 z436Q5_1M+YoTR!1#u!UMw%H0gDpnR{^p`Q6pYRW9NOFzv%TwOIY&F}Xew9_`@{Rqep!X6I3Y)r9ZzjK))SeIr z2GFP-f8uzx^}^RFZ@m@bqRT)pHkv(DRuOr2)aQL^Si+8Fw&5<-@GbQwwRdII^F z7)NxLumpcp>@twjC(suDBHK7VOggn&>UQ|*)F=bOLtV(r}7VV)6K!wfgK z+?h<&*3!t|sTYWx%jyQO*HY*kEB~_Ca;JNFu-8nVnTs_9QU%pjJLwCZ?NC~`P#Vvw zKiP{1B@=v5flYESb2W-{ae=MW94?U=0Pw0qlM@9>JCnKN%Noz`X|0hw#r9>+p!)!g z?#21YZ}7rVHtYf1{|rG%`liBc4kV3RONR7AvB}u7lz0J)MSW$4Ic!MZ6^}IJaJw7p zibhM4W`=SP&3Y@;K-XY>u^JR@0@(82(2nzAR{{1<$#KWLVAynnDg7vdq#2Uo+#{cO ztGm^HgGbkTT(Vy%RPS>%yJl(omEjs!$IK)gj9npH2v}jLvx_xw%Htn!28pOE0=&^I z7>xkeQn-%`7zVm48vwE5x>bjHz)^Jckq4KF;wKnp{4^(nYy43-$dO|0^OVT72GItW zoSXWKF0}MwQ_qPW9ep1`kLm)JPcwn>vc zq&uu=o}i@W(0<1?eU#7Up`=D0rPvmqi0!Q37QKB-k>mO#+Yh0!g#cBHfmbJw!hQhy zV@&_Uch4hSJ1HNHakSlbX#jJIi<#Ltwk{EfKCN=FySo`pLw9y|Y%Q;pCYpqG%g?jM zW%pfqn<<(`i`y$w2hhwB0*Ku=^k4SkeH=AWC#RsmJR85$CX=I)YthMSDoo7xUc)=# zuExhF&&=}^?N&$CYwCt$?-ooRXtla6DXP{dl?4T1MSqi;k`qB7K=+r}LxARPz4RR^ zclJwgVVS)12ve)vP%*mRlt|IN-hKn(Kg;FG1&A$q0dSTRkZv366Nzh`=P@11qod|~ zi5^fRKyyv`meOYsqdfj_*@_=@ENKu49#HiFq+a!oX8cKgw}Kq{bO2RGU5}2GyRz=J zsYuE^FhDc(DoXzaf4QnXzoyLXbtS_= z{xa=)qT^%(NUf9ch^ySbFex5HLCW`93`DLCNX>*C_9bW%sM0UG&Tg5j%eqdI<`AxO zd1OB+{`zHt%mmH$tG=M!B#wQ%(J6+A0E$0@XrQmjcj*s;btc~@FTw|BDKF=)&KUJ! z2Z-x7pX_YCT=?Sx5kt}K6vSsrrn3XTD_J7$l{!t|?I!)~S8S}laroiU#LQPyX{NlR zrfxfr!V~;{7mM^VK=2d+nb*xbD9}3k6QX;s=~x#O6dbjS3JrZGIDJ8Cf~*<1tHP32 z{5=-vO~maMBpr=O2_VuBLBVmzz;h%c18WWJ998<#FPv9~RVTf9&wA$zpFB^`P`h)( zP02{h?V>VmK7UirT@;K~DApovQZEI|QwOjgFF1x&I(IS?8cIZD+!>$#SvjYqmnUv= zJ0fiE)v9Qm)iZ$4Vw6~+kkr>a&;5eIk$u1u$-`Rg7TbqD2$qt9O)eNeXE_4VVKyla z=|?&$0qQt4?YOa5r=sK>Pf)NIN#7JFd$4K86u;ix*}KV1ZtkR zy{e0Y-FTP6-U5v0nYABIj(-m7eriji#Z%YZ3^ttQBU~2;pmziGJ!mBgeS^2hgL?#9?EV8M+F>2+zjwb1}k$7&I*$NY3pBRx}GOp0m}3QN`414(_Kz|8QJ zHw*4v1*};WhNOu*4t?)d0`&J>)*+?oCb>^$nCru756#Sn@-PTo>eQwe*fEr?WRmZ- zC0$cOu`gD(()jwaDI~S_=oR*esHoXVMKY!xs8MdkEg0Xh5>9@ieA}}dCU#Fjq5V}G z0HM^P;{|{h!J2R9cqI5z=QS*1Zj_GU3{RNQf@@;~epvj=EIPaGxv=sW9{F z_D#SQyevRxmh}GcbQ=z6gV?A*KMJM24*fLOgu>%X%q45*+VG{8t^r9pU_nE+8#lKp zR8w{D>+JUz1P|LBh&B?yWVPkKO)iy2ykbKCnf`%$5#OsL_P=#H+w7(_^EFogZuZ{l z8)~ZeCfk`ZGK>yOkNkGllT09OGC-Q&8BmFOwj*mgIM73Qy+I(6LpV(OkyoeM>9*4? zyF1bn+qYad%`L?a+fEQJ37}}d)i@BVmAJAUUo=VkOmclNZ&$#Ywx?}g9jjcyYjPYA zJk}i8c~`+Ycuac#3G7*ju+21zQ@P;@RHw)|oLwnB{I^#?+5)dobe4B&k|w-ic!Ax| zy0fbzH4w9p(%=938*dAup6V{1+{S1VbD4eN=3Lz?^v;$h;)m$>MI0Ac0^RiUwH8Rw z?lQUpl+aBtuyg}RiX44WRrq-eZgl_fkKJ-WlGp%*>y)iwV@d?*jn5I?(ZWs0T?XTq zD35ww1=tDnr32Y1jPswk!yI$nLH?^m&6y1C!f#!?A@WriG11xl(390`u(L?1(;kgM zMQI{;tFFCy{atWN^NOcI@kdR1d$w4qr(WEKv)s>C8j1voov)6uUtuT7YWb*}cm3ql z&4%>`9l|imMv#dd6T%Xvk^hjo^JU;w-f}-`ku^i?6hp2Lw%585lzdPl{dHdgiJ8r{1#S)$%U z!gT8r3k4>FDyKX`qqytBc#=F}E89W|)3Y(0(^r{+jCyY}qPg^Xw!8|w%Q%H~%W(~q z^&*I_$z>5XF8JS)xdnl3XQ^f4i=Q1l9|w`(g0WDoxaV2*Gu(xzFpz;x<`AL44YlB3 zctQ@O|KH>zO!7d}v2kpyy%w$Bhc9qrIjrPEp4DKX(}|~LPr-dMr}yzUZ)DD__>0_n z{*|jqkhEQXVu1F%Di8I+DXteB)4W*-uT{zc9)XeSM}GVq%vpX*3#reYF|W?5^a7j^&e{GE}BV6L*nB_1|(m zq_-G$r4EjLq*`NWHa?nqm3k0MeSfILS-pDqxuA#6lJ*fr8O1faKc5NwgEX3vRr%Gx zYcKL$H+F|i@>6$+LC}4VkPx-zo@h&oBMIo87OG_B94L()(Yq?2`T+5Rm_;)WO56fU z)b`Pr+!s3DKPk7l+9A}!dJk|S`oXO8_t>YfiNlW5yVBCh1Z5r|@d}Bu&4AAD(c?w}0(=YaX9B$Z8fcW`x%4oaULtv>=eIpOulBSH^Kt53 z`L;hf+%c`COyty>3}NFvM$F}DqMfLCuFD?4`UM$c{n+LoJd;UcHhq)>wS-ZVJ(%jJFgb^!IdxHWr&45Br_e1cx6(x6Q-zB^__I3?!B|;KAvgbC|zVo zYZJpsc+mEhQV-p!*%JAUg-a7XsrL5Gs}(bJHmpK;p+i(^1|z~>ga0wKTfvfF;8HBT za4A^#nn5~tV*o+-wzJV)VBxUwQP+KnNVV?U-gtWB73k!e#|m7Sr=_HfOSMfaGPwfU zC7<=crQ!fnCnY6iW5RJN84#fyqNSZ^V2Oo3VB$^k{YpohG2RaYc9D5ysn zI0RBxG*nbn2i)>xImO>;4?>n&^hJ!*h961~EWW8N4iw*E4qNn6@fhY@42RW zcPpX^@wj{sbMlyk)l9B8?%8A=rKgw!omgN431Y4$i64;4sv@ARNi>nqcE;MDk{4q- zWaGGaixf(MeVU&krOAO6(W_$g;UN0ue~he@FQ)s?wOvD?u0=T4ZHeNx<;{BdT~+K$e>xd@o?08C{WK&L$) ze3E6YKyDC+^(2^8KC&`aqRXvrtjtL$BHCVJ{SLqTDH#^uLk4Gmz%1Qh2 z`yQ=Gq;1lfZ=BQd_yXxT>xY%_nUNJuoL&m5E}a2R>vApw<}V9IR#_+;`x$cqOd;cw z$|>-PzM9(P)1wJZv2Hvv6p(E&W~r>vyw+55$W)#t0sB8}y>(bs+ZrznNQa1^bb}Jo zARsA-7&Ou?0@AUlMI$LvD&0tfbhBtAq!x&D=c2pw8%y^-=iGb0=keM9xYfy=W4z;i ze>G|k)@Q}aH8!!t2B@`k-{PuU2^$qWh)skIm+STXAL}$k(hqtt@b1WBa?oSwL4~*n zS*7?D2}uQ{4b9@WBIAFxqMD+mj!wX%U>xWJ#pa21ij(i)&@J# z9EOHhZdiP_72;MR7;p5=9;WhNaOl;&;jsi9ldoA$Kq7o2AVEx;kC#`p3O(>Gf)50R zbpQ)!a(E9mIuK!Zf)RSJjZh-DYSVjrN>~%>nurAnFaTFN;ZL8^Xq6bEB2{S8wdHuv zW#)A8v5K_-@TuJB0ZkHfS7%qDU%xonv4zDD(<@D30~iwPQnwf!r|YAFUN7bDPYtxf zR{(gr05}xQS_kIi?S^$DwJF!1SAP#Auw073CMm4$yU5^nZx{FcJbjk1^^j-NEhF;s z+-2i)f+^MOS^L?&_erow{}Nt}CXYhpQhsMzv0__Ok%$oaisS?TjYHlj-3G%Nrv@HT zv4G7n|976HTlHGh#<;nBgB`V21gKQu!7|UEXLAUOHVlw|nEA{iemH@NNw^mWcBs5NyzgrIHM;p}xxl?C}d7F~C{T_f2zbR)t z$0j7K9#*+*0tAQksOTA(a*1en#)jGkG&%hxiI|$JECOE|t;eF;XY0k~DhueT<~ zhRPrIE2O4a9vD1v9eA9Y08?SMviyyWWz$4$U!cA`QO{cf9zP(+$2E;K#Y`5?g;OG ze`-_|dQlb_=x)bK+iTLY`VbU8JGsmJYOKR`w*?Ey&c-e!hyuQ|GlKZyX5q3}A zbfvRY58M;vh6}z)P9f_-TGP>p4zkNG>>d2MzudF;^I@vb8Yav6+SYs!ZATETS1`a- zy?=HL?Aq4vVa|9Q$b0hjK*~p(&L+yflHmHHDKtl?=An7vm5KhR=>~HQH$u|IDLyZI zYVBIVAx*ZOX<-GilJTncOK^xhnvA1M?`Y?QLGsKJ=~oqH-rem}Hb^iLEmiuI}l&c4;Ovjv?`^s#fVR_gi!6`qg zWxsEvu)sh1L(`6$t({v2ZCJ(qAKJr$*I_^HV;dxXyBX@S?zCBDeYix~SUq0JcHjWR z4C(`LFY=AgY(#w6EIb$o71`7f`*!{Os%-R|<+O&Z@HgX0O#H{MT=hO+D#GSUEx4gQ z=o;enVr3YNR4Knu57p9;`H(r7LhkiBx-HXddnak0tAyrANkL)Tqe zcK6NEEl#a6^t?O}rhcfPAm^C$HT=Um5J()gu@G(p<2+?|FDbQ%Ge7A(5a?jF>xRI3 zv3f73QoYVuT_xNyPEHouKOMZ%&(LV0UMLHVeZp!bkL2$w(IZ!7R^x; zzW~r4NX<`Q{bMi||IS7g`^j2&5YJ2PJ9C>>{QHFXZu716hWuj28v)Ca)lW=CxBgRw>T9RSmvxd&3gw? z1%4@}Q12cX8SSJ@Z(%MI?T#rU6ofbaw_gD}iUpllRpk!M(L9CgAu|ISsi0NYfBV)w zNiHGyx3OaX`BGM|8DK`k{2T|Z5OG@1++X62bpm3r`K_(OA7j8tHU|!ga%e>PHW<_V zwBA*Ia0kcwJqvemr8y?trH}*S0_br9!6`dGZB=0Rd@~Gq`&(|Whxni%XGR-x^lJXF zZlg$b=I~I`3v5?{qx$#Lb(M9r$D^SsKreJ%2bh9oOf=l?sXLN{b|D3ar-07-#Y$%Y z=@YQHg(e*;anQ?m{@^y8)@_x3Il94o=)rK{hkdXYbELlTaq+Z${;FtbNGE=C30Z#G zue9QpfhC4`w|WA0_tZ+30+-_qX(|TBHEy_;t(4~AZ-cMPJE}r#oA)q8VSQ|7beJkSu z?l(Ww{t=Y4Ppt`#Ze6e5K~I!VxEQbLfZqeS1z+gWgF~*yGeF zo@KpRuhmD}p6okK?;jVx{;MAO+uY9KpzYmUe{!gvUip|lMZxIRM-f$K7YMPuWBv$K zh;(KEccgnd%0T9UuNW&}gVyWxDfG_HRPB&+1_=#RQ!7s;iyK(7MFF>T8)BAtp)8py z3N5Q0v!f;^zU2mTyYwg%e8eqB9$j9Y%mzB2iR8eKf;9#!-a z2k#BBp2{OTuNkCBq>_R8t|}7(6DwRk;`(S~v_N;klqh8oZS|*u?e6#1BR+qTR2&&Q zap`j9&75kHGv$iMls#njhCpz>egUF4lBxpHTREtjyn|=cZ+9pcpPGy%$o;o&{@WBGB^f8^Mb>K688#My4=Oot>$_$H)N(z(>s=|b%NeF(s)g5!YdFO_vH7m-oBHw^! z(H4fe+>M@Z6rTFAt?g?pqxfK)gPcT=u$70>#{%fc(boS_O#(hkww@meiC9zIT4BaTpwz&&u3p)v2+skqpBPi{`Ks6gxrP3Jr{{l8(+|>g z&2TJR@qxa`0uL|;h+Yg^0A*CQPOfl74IiOn;lbv;ixP{;m-SbMF8qahw<8FwGj12A z6vwLk+TG~Bb?R{an7L+SqZdKS`G7KntWocO|A~I=C86r-7|N+uo}c6O<9V;e9nd>d zJx9t4Y+qpKH=Z&qs24r!t%t@~m+8bk!^#ncL}o(vd$u)yDT1!4RaO%Hu=S)jWH^Mp zKS5TRKQKLKtUH5_tlg}yN3?oGHRCw}KIP+H#x~X9Y*KH9FrynR0*a_1qs?k}U3N4Hn`nU(JRSng6iWQu^reelb9TWYjpo}-U&EBZW0dK7DjeLDB$ z+TxLPfG$!XWQ9FY>SKQR1pU-=aT zRZ{;mNcsC<_?lL>4dgWNpp9f7HY*G_8s75<@{h-q`kOnSn>Q1!RGUvu8%=J)B9*$+o?+bRwBRh z6^kw+5eiLjT^+PIKdh5Q#VW~R1Goo??*OSMGbmV}fSWx( z>OM%ueDUIik~wbNy5Ye}AChdYQqdrJ5GCe*T%ltFbb`+$t1}od{{1}uKJmaX^_!oB z=iSA227niJsAc9d)u%^J4m^r1~<2pfF_&!|tcEi$ItwJ%R&#fwNzRE{G zOPBRolHx#M zksO2poPrrrP4l2PsqRVq!$)+ZQ%Z(az_$hYjHJ2f(Epal=5WcdkPfA6Gh^bdiB-Js zq66jU66z5n0#?#dT$Jxc;6GnlXk*?l5(_mN6)Yo=Ry;4hZza71HFk9Yqx4VE0WB6{ z)y*f<3eHulVaZiGu>SKG0|3JmZ4C$Kg(mEN7R}e6rNO{W;bZVSFeu3QXnj}+sChVbYfwOt#hY9uR1$bRaXl!C>*pW{pamHFf>~9w z=Ric@xQ-<1b|pw0t*{*JFKP9@xf-?O_@f*EM}-9X#3+IEDgA}g&{;V}ynrCKD|Fob z9il@NDqyNPPM4#q*7a>B9|B6gL7OOVW+g6R(~%*`w?&5-i9^J)JI~?7xuKU+LTa%f zfMQW2JnPZ4pzT4JvCaM>lWm=oI?D#t+SO5iT6?f+8RkYyDStfducxg*PYiXqRMZ$EMsddu_FKCyz^Ml-phLLrhRkCn2?$m z{b^s~ zEzGfrj*gB6B(n|3SSyo>pCDAN*%-tlyy7=AaLeZVeF2)n@Sk5F8iVSteZa7H4knZ| z?MjPokyOD7pjf#C&I6f+nWYDRmQ+A;^PIE5V5O1F_i>l!{)esC+^GIqu8O0DDkIAx z8O;UNb7?47Shg)Bz>kpU3d~>MW z&)ShMtu@6@rckg*OfcHkdUxR+Iqf&rHt6Xy#nq*mE<97wFenU0h1J50y2$9jz9Y15lxd?M@tb4bhZ4<#s6!>wmcz6KjX4I(rRma}aOTlL-01Zsgo>OGGd?d* zYo^KIY(Mv=hikXs4URbvk5Kjj3cTzf8uMDMU_yYvYKH3N{aMR#fqIo@r#IkYLFr09 z)a19dw(oP(8@!|0c3D+1Yl+U2J$mntmC)aHd5cU`D&6B|^y8FOeeanYHsOjQLBTBi4^w zYuIO{fnJ$Hosj3v$(9nO$*Xa^&Q6Q$kuw zhwKBz31@%ds!KJEtY#QIp11S&3|Hu1US%O)4SGz#Hdi^Q7d5u^{#NrzkF)V!9U~Hz zvJKKcUCX+zDNrQ-ou`7islzrvNRS_7xH+dDceRe<)aY?w?{PeNU)rGdpI(DOp?Q|} z@L5je_Gmi$+>XHyTTPptF3*#3oMHM~Sl@ud%uvBmc7>QKbpK@LQ})eu!LyUlOeU(@ z8?Ve1@vYoXp0%;0-P6vLuUyvOX=p$%UD1DkH`lPym|G6`Vm*;I^IdC~0Cs-ER|R?C zuiZ?P-~+V{m-gYK?5;%tw2wTx3+#@JKpQ$1!mvL`;iF=AvvjD6u|#i9bN12 z3!G!fP@k%7l2`-R`G7|kg7--oX~V*n8x0 zwlV8W+z5qT#X6WRaxT}&y7f(L%_Gb%TYGKnRU(;vU!FM0yjVkdgU|Yr;+~%ok>}83 zOo#)m5P61Z>1<*p(coTe+gBvhN1dqtyx{zvQpN|K*_sh(=R9Q0fex1zUVC{Xo8+EW~-s0es^`?F&piZ(Y261{YFCC-WmUj zLwt>d*NKm?GqWEojD6mHq`jnM) zetzq~*YZ!-SL`yaab!&$w*8%pW8(rXVt;LpFk(Puedxz5J@;|Cb-f#=Gk?m4)7eix z&P);Z>kY+cRvA)-y@5HW&B+;0r^9wS+T{~B&lB-j>PM4A$-VBer9Jb*G@NmgjfqbQ z&lGcybXzB388FM%^GtQcK+ok_1>@(`MO7d{w1#LW*La-(+muV{{u4y~^>Ds$f_n5r zT9It2!Bn?J0$qnT;*{jqzYBuch#xd_J;J{hu>4S;qy;3lcU?9me--Ho@z{SW&sIUu zqiyt{)BWtMydiae|0<{rJ%*rV%xRKphXYm0Wl_kRVylBG;aKtG5?-vZr{ z`s>LBVJsvH^u&2H_%`*E+&!{ip1=S=CgCLt5`pj`T><~ru&D=W(9GBGPo^FuAM63j zdwHJ@A3l?*F6`vNW1A>1*;M4@bZCQ^g5^S!xtTpC(GTbDb}vqjFF6&&fNT98(^TWE zlC;E6PJYI~IQ_7ZE_-ZSaCNXJ^LV_*CI5SF^K| z*DeJYo8#Gm*7&%`%&$-L!ceMO*&j~1Dm7_q{doAm_~&`XtJTNVKiBIZNn=tILE=d&V7idC8hLieqIq3+6Hgb* zyEA7N3~bjjWs=I)V=Si(^`~~W7`5Gb;>f}VgvMx;0%aT=Y0lQWC1s(XNQneIpD1|m zqW;pmyzYWM!+C9MRj}9K;c@5pck*UN%I8MfX`XwZzEsNYT#Zz`)|+g~HqL&kIL2LytT0*c>Z0>~iW`SXg+Y z580ZS9uF*d}*gO2RsCFlaD&l4; zYItrwd`p7JZ?kvW{gTQhyRna8n^IdYW}$|wE(7TO`NH^l&GIV} z1zCgN3FG=}PZeyP0&QtsCIv8yJp+5H?+#S>v(}6j;NzdT%w`j7SI6t$iwqY4hzXd2b zAKUS=T~0Mza?quI41Ghh2G|ICXJ8*8-|oN4c`k!wFt#1{UQDjmLRuKP9s$JaV43D% zVdmX!z=h!i`{+;2qB`9CeQQc-IG~%nT`3Rq1|tM6kZTrE1I7>Lvhy62Z!77;&2i$U z%YD4JZ{J#({72tJSBw)JnKJsrL|hh~lZnZA9Mhf9R(8vUT9}X~{JZSNy6Z*DHru7h zq|&9={DyaOpgg>*>)Arq8|D&PaVOL!c?xU;T3Z1Ov28t`z13azGoo~NRVu;bNVBlLGm@v(PD4*d1HS5bJ`$>M@j4{kj3K6t_5>0 z)Qg8!hSDxUPGDq&2zfsQacc6G*gN84tNTg|-vulcpigjx!RcyHmevTo0t?1wkhRY-S+Wb;X>0?iKlR84`>U8odD~|oQ%`2R zY$RQIadENKw2$K6e#*Bx#*LvI!tJITFWF(&&C*UgK*+RjW+&RTf|Q>}2vL`9s>aLx z*B}g}eO^=L&njVAM}PK$YhAJC{j9;yyIz5m@5GNbH7jwmtfwDuidl=q690V%chI0O zC5eAsO*l$U#Mou>R$OFlUfF=lBzkoJ{rFS#z_Tb)ky-ffI~8S;~+ke7T|@C>V$?-2nyS0|j`yfjxk|MTCX|GpB1NA(Qaq2fD(#;Fge^z*2ACyx!Rs^vQiyXl zVNx{k1CfZJB}C2?Dl>ndai^FM>c1y~>ChGsfznpIQ3y`G-KJOZ@#iWC#NpdwHC9c5 zSFhpCQ)*aAE|J>*zOGvN=26ndttV|cPT;u7`52ip`NPEH@9%a=15GJ{ezTQZ4G6dG zRtM;VUMGW;R(+s83OW+bivz+(ibR?amuV-`2l5F^zZrQRLSFt^jgm%mN-$?@n2Ac{ zQIs;-W4u*-ouYBDMOrez80`wOTa*A`Uihkk*USy1?gOcvF49SrHm86GveXv#sa>Xw zh%-QjON53#6oaer^xNIcqg%+RMz&{9dRW+y8&DS$ShN`B%b1+4u~5P_)dgeTxyo!zvc>(^Wj znIky{0L{S$5d_7pKZ=3Vq1T!gTtM4eeX=@u3)nd;1#--8;&_aAffo_+>eO}e+27jB z!i3)X3d_(AmXH?NXgW*&UBb00^1E(~78MSa2zAi3EZmPls8Aug%+=8FHBw{tS_r5n z=PQ-+1o%7_hBXW@#B$9qb!i1{ zs8YPn%`>yJC(gM;YfV?~>^?$dqpqmJyII7M**T{`c<@_St8#Q5e991Dh8tL6ZZw0_ zc%04$bye8mE$*~{nZKY9eacFb2H!x@)@voYnztxrP_lGrDoqMaV zn{KY)>iq=xQ&c5@4bq8Es(CKiIt%MymC#v}(AkGj^H!T-qq{%Ma9@0tLjLHJGE3&H zhdjZ1;a@T@;AnAg5R|^LImPXQ@Wbb8bl#PLKvR}s(y)KJ2N%<9y5Lv&^=oTHy;k?- z;f4}r+XeqqyGRMZ#q14VZpAg8I@D3aZmTHKVWXciz{PLr)z0(I{9M0@DXNHmjNEQw zXoHAv^P^Q6(_zpc{cDlwA_gpsgvkDZ?L3{uz#Rv~tvlUZq z1PKn7?>nO=!vjv9M#$i@oAoCtpS<)9X(g6M0UvNHM%Z@C=Y=n_)`y^AII_bW*S@IP zS9O2+vI&V2?!M@oWuG$4A{`?a{_!YfgR~Vc>h@JtXygY^;8VoTHv_LTnc3gQh$Ud| z(C4Otv1da+TW(~$@Ap^)`jE%^AhoXX`rI;+uD>xtbRU}raC9JZ$}-2B`C-UTW245+ zhD-`q{qBdhsol$~K|rN0w-kl7&r&m_S@P?8X9YFIfd_-i(*3|%9WAq%k;j(wKNM}} z_-f+UJRht%bvE%m1!C;Xx^X?0H*N;6u`(XJO&n>i{pxwGu%F=xq1;oOp z-|Vh|{?+4r^8Tg-(bur?tk?Q?S>{38?AyP?^-|`E!_0FFq@JuB{j%=31SWP(y|KBY z54*iha(ddllc2C`IjxVg*8BN3(XVNG7VE#AK^n>(I}XfT)TUw53ldH;huF8AVuVNs$uk0of|}cKUy?8%++UCV zY1iz{e!s_t2-j)W6iM@L58#Y{Y>t-?XQPLxO^w-sw9QAFC6WP)h3bVADXt4R&tzp6 zfd^g%zF0MB!+t8r!VZ9ZIt?66Xevai0N%67`NQIo?195=2+5bz)6+*e*>?3HbzT~l zXj6w%dq!S-Vk0PLWj_ddipoK`f`teC4YKv>HeS=!wyEcO1<`!5X8@?o)thM8|Ad3P zgDkTN(m+=^X4V!+aL&1Y(vU96`KM2iYL*0NX6Nj0eCqXR!QVdv?sVCr5h3pGj&-tg zF9l%4iMkWV*oqgS@16c2d4t2ACHgCIl$FpeMYhwRb-_t?7YICg=EiGX!C=ggf;hPq zb@ulSH;bWZ_#ZYagU0N@NzyRV{VMC9AqU&ngUN1~fQ^=vUezoD1!G&5*7FTc@dP%| z2>bxFJ6I3D} zH*}LL^Z>PI*^&;x{V@m7Dvj#4shVDDkl?MP^a#-r04UphH*sRzb^I+6pn^|Cd>cL( zDE|xrCtU~^s^az?&<%GHM}~&C&c05F=G4>HgS2UQQMgP2)B0=)`pP4h;m5W!-@QgH zwl0ph3Pd;bJf9a?Ng8UpHAFwsQt@U*{OvF1d_YSlSg3wKF@yJWg0wk#!2xT&8 zR|0rQfQ?5*k@SQ!zlth(1XoBO)|3;QH=hK-EqbT>;1JIXW=%=yN#3&<&NtZ=2l#Fb z%wnYq9|nKHh3~S%%GX4ANIxeg5EKf08enUNpx;gkZ%gnrE0N&6Enrz4lxm<{|GM_! zzl{j8yn3LKmkzSgx=n<0u*9>#DDbX{zux=H8KL03z&?>W6(Yi*$mQCcymUe3{$Vo#a>OR1h1o#UUs14ts6+m7@IwIW2rgnsgQmH{`!>s-=#4r9 z-~W&#X|BXw^>_T1mS5YMcW9)!a{kk*OQmrW-61?|J*+^vw|)WK-j#(3Grd52gq5#e zXu%F~ZY`-Lfr4;No30F%r6%Hj{9SJd+|UB!W$p4t^E^NNc_Y(>>o3W}u-mpEpjl-TG)+A_o)xYapM!fy zgGixJ?f9dBd>177mW}&hwt(oSj4$xv#o_iCRh#YR`cHb3?^2RJd3oO-oA9Y+fSY~j zYi?info8G3SSYOo4VaC~j)+@E0vRSBhN7hrA~wQZOn_)*02Iha zI#qIgsnJ+&Riv!cU~RL!L65U&qY}sjaU(P^tb)?RH8Ii0L_R-$JZrPddKImr%&*%= zYO}hTj%UL*lqj+we4%WII437~##bPZ11t+Gw7yTA926^hnqXhz10-9RBjZYGL=<)9 z6{8Z_@6C$}u62)r#Q5tb;V=a(rW%wPcIp{sam6?4RU zqwvf+J6i#O%oQNH)*u>W%rxj*DICND5?~-z&>P=5X}mA(6MZ--DayVvgXj;}JBHhK z=5Q)+r5dy>uyzT^HXOfDe|qpV)YQ?(FYl zeG+FW*3`aodg|JCg#q$vi^}WLPp~z27?`-TuB*y9l2pA(x2QivJQ?{*pFC zX?7|5a9$?Qi-2H6ErwRdU+0sr2O}K~$fKBP_=xPDVYh+MuaX^-GZ!wh-5g5J_lA^c zV4B`+dL&7D9dLuEz!7aX?KG<8!X5qVU=KOpR+tab!Q0SfIRhkln2{|3m5?0@5VKSh zW^ zXK5QGFkLWFP2UkhS^LkAaDo%uS$ol&DSJ)4I$d;sre+qpy_P%nZ0hv4?OBti7P4FX zb5@b!yweSCpvw20d_d~{qWqF+Zh0rdf~&!QAYJ;i*E|}-tS2eL`;1v4mI?BwgyCW! zl_o95Z*8`aL}$q_%c5FLpncIZoo5h(V2h>C*6>L~s@?1X9{`Ib3#iy{J@Z zL;x+HKM1pn6p_{iw}p%LT!&NGwY38Eda3o~W2N7Vrhy;{!?(6YyW;))=ac=x4B1jJ zY$S<7RkGf)7&O+qNr2!3;mOZTRMQbrq#S5~-ERZwuqHKm0FyQZzSBTn7cKx%zh7;I zC!ZZ4D7!_W$_;K#ZFZN?9^3Nn69u@(byD41_0)^nduX%KM=vOm>kaT?bgfWjkNkE- z%3IQY)rE8e3HGKjWhK_SWFNnEs)(#gIhm(>cF?Hy;Ec zApv@e9m=~Ov{Su8mcBmxT;g2VWBfw;&tGqk6fV%au9GPCjuh#MKt4~7dU<)RjucWN zi5@GQRq$V0r0>1{d*4^pG}DwLaDDZ7K=ts1IC8Qk1QWZLCnDKp^H~O1yZT|~HU)aB z=-G5oF#3xEf01U1q3?7fl1la0B4iuoc9__~vzWj?6N72J}9g z>wOp`pFu#5>6-%eKBe~EZ4g8u5VgidChrq8{ydB#0Pu+ux>hjLIH<#%`y7B;svNFx z1gS+22c%uW=aAy-G(+k>~Ba%j_~sdJo0u>}AoD6_MJ;cVB4$!fyCrs?MS zrS}bLd_2a9sc1T-ZCx+3$Qn*9BNxb@` zLdr{7(Hg;h39eg}qfxtt!!h%=vu+z4+);&$sIe*QB>q%5_tcI2S-CCr57ZA-u)zzr z-R)wGU?DVFAwfJxbrUWRf9|^o{8Q~xWZ7=9;Th%?Wsk5}?KaG1;VPK@Vmh zrg|R7Yg6tFb+4B8PxX>47y7>yS9F6C(uk5Bc08sOB%cD<+v-qGL}AE$v{pyh9sZC& zl0;#`1N;LsKlqmolUz$1hBT!c&}~d~*f~nsx`$VTdtZnBcVul&=is*vB$46FugKsw zLY{72K!hyGnD3OhN}>`6kwp>`hOCo2Ff+%uvc+*5g&Jm8YKki<0*Y> z=1un&+Rw8&Q)itgtplr&iW{K0#y3f+=WZ%K6aG1HSVWN_zZ7V{H~`37Yl+w-zb1ot zueN)ZKy8~&E=d26Oi{8QJJ>FT&r5jiU%s^vRUCy)kQV*PlR|zIjXopA!0G$DNy2iipr3&+gIO z05AKCsYdG3*Rc#nS8j75H0hN++m?1G+qt4%^=`A;Ve^0|m!u(}WB^*8H{J*GKY9~` zRBh{hNi;GZg;NHx!Nn~F>h;F=%u?IO&4)I-r&;G#VmdgzBC2xC6q)qTZqFtQ13Ao|oht~q`WGcO; zaW?GkK)GuV;`Nz5ezi^9Gk)QSJBPHO%@_B1u4c*EnuiRN__HXeuw;$B;)ye=6)+~- zr4e&81R6+f{{UeuE06G8<~20QrH zINP-dnj?JH6h7TEF!E-m&|??`&gOK1Vr5&}>?J{l7GqjzrF;0?&}Lz}ga`L6JHn_B-+&Z` z6=-ULYkwHI2O%M?I28c}Kk|aps8OMV!Huw!TtpA#xe7OBJ23voidh3M}2w|s(Ht6@7D4H|Wg{o}%ddAnjo;IEUTW8@>o8=<;O^{1af9-92Vy{AH%m*w~`ha|Z87ldWnOf5&h?Gr2N-iPz? z5y4z}ZbwiAP+L#FechKZrd`eHY~aqJAQ$J8ISm`;!_HNf4&b+~w<3R)@c1X`YS2>0 z!dp@f-m3oIXTA5#n2lxj8bd%_-bWEvp^-jp^yReAX1}@OWclxT-?3)DIn7Biq@=v5^w`syD^q zTYZU(&0E!rQzx^2iH!9go@)IU+2GOFA@G(SIDDKxpY!9)Mu7&S80SV)d+Ss%%EtSJ zU(Wc8Wt*A8HAyVRY5>h5eypNujrhE`@x9}9Q zD*D*!?dmGDYW|)4K#y-pP#Wsq$|5QOK#AKy3!-2U#=@{$prT6~T0Lwk^c0*WL%nj9j1Hj?DdowUbq zx!HmWI!+h`2i|vd-AVPnu6^a69$kCz1Q24A2)_(3U>QP}uCeTZ+dL1kdq)B%SCg`x z^2oUH7#P(`=GzaRNy^%oGxLpSm*^?yoq-ka3`>e%PLoknZ~&1r8%qt%t!a5V`EA48}@P6<&tq{*~3-y z%;0YgZmxwKPo{&p5@@G!Ifq^fhLG_`b7bvC5vP=T>(g(j}O-a3JECYmR@sd6*ApJx;1e0P0+O=o=@4N6ZAI+k6XOCY6VvA88Do86R0)H(l2d85nQj$MUB23LZuUV1 z>MhbY+IS-edi$zpIKlH!rgXuoVcYy)qkA6fzw_8ALev!oQxgfO$W?h(5i>RR z864Vy8RAnySpjpS6H2)*$7jt5$bdu&%qmyjaEaN=_x34efYl5?IrKU|kz45=$nO%_N^Gl3OU7~)~>iglMh>5FV zj}yInReCT}Y-?a6uo_Fdr`2R?%3#q=ve~qJ|DA4K=7f^fcVL-lEjyhVa%-OAuy)#| zn|LlWep@0rLrR@5$Dqc?4=5N5kJj`27{13DqfNcDTlvIg#Za*r6Ki>To$lJ;4LVx* zREjcDYapQ@sYpY%>x|)y=&445silj>FD5GQb=Jv?VRa+0K8bLzrbNGyOE(MZmY_7! z(`$cj({L+E1y(aE&m|%qO1Fl@!YOK(xKFx`KrADj$8N5$^~A(9U!LYm+jMv+$sA8)YbY+K;A^37S2V)hHqtZK^`hq*r{l7ehEHHjv`XzZl%W=E$Cm)=7@d1*gyVaxaj*7yA&C+UCi;nFeGa?)!x zsT8HTbf|-c$C&`c3j7OEvhbt7$vuwtUiei3|E%8S50T>Z2G+aM#FUz#omyFF672j= zT+aDejlD*qyL(25j%|9BIp4)FX23}(%_-3E2b^H;yDt9>B7_MVn?6uzyevz8_yjBO zc;V9=CV@t1%7RmlqG0g!AY^6kP?om#mtJK$w%6f&kaZreCfQg;-YX3h)n^8>ejSf= zbER_2uUkR*)-oNqbeu$ATs*u^go8`gOvu*u9#L!3WD=$LsutG+bX+vwf>K$$R*QE8 z&giQgmL}>3zjZ1P9OD_eq_0E)jL?xZq)lcA(eu((y>q=)J!_@Pcf((Nl=7vj+bU(C zJg#;^m=hxzKs`d#AI~OO1C>J4yD~rWDTvf6|D2i#rAZS!FvaprzD|#Ufj{_USrNjksopxsQ3IjFU*_X@Sjxa%z!L@t+^6KxpXYXA$G^e^>&zNZAZ$W~M zR-gu#@h*oV@l7WzH6naokN0bng&~*#uveE~fm=s7MJU_2(mG?wlLgd)~<%mcq(8$dgKG(l{nyyt0O$Q@?8px=o3}JjA zk9Hsgvm|*){y+zBw*PXlGDof@B}Gi83qop2WRV&lvvNKC&Xg@3Ri|c}LQ$R8$5s?R1~=Q|<>2ew!g?sDW4DwZH1O`s;r%yZNSOu|AEuf3&D2vaWBb-@ z`Kroi@RTrM39}*~!=SG*gZHeVT4fa_N5Q^GC#P(i$j>GUpNIEVe$I*p!T?aj#CnDn zGqiC0l7O$LgY&Yo^C5i2C!r>7CnYA?Kk`IfG2ZNoy-td)XgZi^uSi5oGEI?%dI? z`YJ`A_OSWn!4MI*14f1*w>H`=rs<|P7b+~APNJ`A8 ziC+P<3T}r`%fs91Uu5ccWCjmCNKPMiLhPT80+kyxwznR;4xLF~7pVsaH zVSFw&Lui#$OY$Ih&Ch@)uG8_pFchGIQwlmeXc3hdD&f|sgB=410X8W!@gI;Cj@NGd zMdn|#6d?C~B-djeNhOiK!_?Q$J(~~O{go9VC*nqU@iVko8A_?p$tcu>{F3um%kII)?P7J%6eFL494LmWP6Ly6&Z%qW?^~A95>2DY~ zEj;7ytWnc+E(|+PprI~IW;h=;P(ErWZ6SD&pp4xVDN~_dSa{ss$K@-ZkgIfvK=hUp z4^%pX!jCK=JI5bND75^jQOi#XMto*mNXXjDWF>n(zgE`abMr!EgZd!%aj{oJ&M4T( zopnNoyzO8H1R*Pk-6=d5X6FmiH5)T=`C+?4H$vHP4ASE_Vz7&McDjYdp7$NBUkt*I z{@xU@eB7bP_L43c9nGJ{E%rg0V~HO_uwLn>BevrL?_xdWoywEIdymG5o;^`P&yvQ* zx%1)$8ct-S{x$rf#mdywOz`WwTdX_K6sU9Kb)PNi^yWn}gic$!nJ(|N44}qsj2CanZ>PVX z8A_SDb^B9t2%@#c2Pvu0OYxxTmqBBa{C|EaiJ=*pC7bN}w_DwT6SX$v$H43}mO#7B zFMQ?LNg~hH@J7X~Kk8crzbv)wi!=tbQ>y!BrXdDzqS6a&pZTX-sRh@b=t~Rim(pGy zs!Hpb;F;StS>G9GxV+39FRXsG-$tk*6fM5wt^7QYO0Qm1sx#C+6pvCuKOmu4uFHwT z<%vTDqpnC8x&&mZu*)$NW8i;d8{Nx>(!z#lg9?=?l{P+`J zF-bBnfToGnB?Ao<`O2q{A9Q79JeQ67-)alVE@T0%;ynhWJsM{k(lsK*-C}IO*GG&1) zzB&9-`wZ_2XGXqjWjIue-<9Ozx!b% zQP`liv5@U#muxgqO~Jtvb~cmWq$X~EAfy;gWw<0^?nk-=VGtWB8#Y*Ou7c4AWf+I;0r#x|ai10y3<6FVQD*J^su z67bzHem8G3!~$^i$E+Hl4g3#d#)6x{3ijW;VdWriZGndt0i=-oE%@<#?Q(ivqs~!Ts`f<`D%+|Apg7eSrFDs z4~LlVGj98Y${N-Ps=v!$i57={dsOj*+cCc=h3JoiDr>&qYFR!?qlI#;!*d+4o1YJ} zUY(W5{3wP(aKx`1@7<-5df$>F_9g7jY+c1SwegKSvRixQKLIwSHK(Vit;y29w)O=E z{r|W+%djZBuw6?DNQ-obA|RlMbcY})A>AS+B3(m+G)Sj3A|Wl^-3UWBLw66|dyVh= zetUoWI5_;FKjfKb&06=m@9R3RvX%W=O$P0+_;cswBa9`kPKTJ7k;6M*V%LRDPqtW^ zm|m4C&HaRVdoNKCXXo>IBvly(D5o^iZzY-^OF7^nHPre;_adc27{!_F4Z|a&ndGLm ztyDi>GBn+?JeCg6I}@iMb?$i_b=ZQgHMDCEYPMcOArU$;DL3nx@1cx}SQv_;#b{RI zQre_~kdkPxBB+$^5TsI@&}*`g$4+xzZAb`p5~wPq5E@tK(g)5XrTPp&Be~&WMx-67|Ln;DZ5P^* zPT7wi^t);eKhjuzs&4_zBL8d$q3meA0_D>R(CWnki@cnen77;2ZWSlEJW9jPvDm9c z5#$7Qif@m4OcpK9e{Hhbbg6 zzO1`GC@?nF&1y;uf6M<;{z>=_V_}lthSs;LJI0@Va{7hJAFF<6ExoU*jI_OR7Fs>t zV{3;_@J;F)C2VqxnSNhdV|l?e?M*Khhm2X#$zp@Y)hU^6eG>R`DX10Z`6~$ zLMzT$D;g2Ku$!Bzi~&`;bP4pJntfrhYRmm}+CEEO(t8B2Zf?%zsBr^pFF%{zv|`2C zrQ7zE7(~&~6vMwr&qFe~l7#1&AMsxj?aeT`?lq`~-5v(?)yS(#91LdA^AhBh4PU$Q z)fxpAbwajBeg>gx|0L-!z*3m}?XZoF%)f>$aJ3_gwSl3KcG8B2jOW--ezwbslp-MK zfrgGcsE;)-zi$^xt#2-X^kAdnhU#JD(SU#gLO|UnPjGn!gxSMD;3*-5b&8qL(Vv@} zE9)G-tuC(NNZJnTeXv0qaJ_NxHj%9xm!cbgI`x;zYf%5pW7rpbAAbYve@zbRcUTh=G5miO*Gi znR-v{yh2cwF;gMdU6@Lg4#)dX3y_eIOQgEtDDBPj|7~k=sQza`vC_rV&obVH-RZ`< zY$W{Aq~r)<4v6h?4u~_5y|yHnlFa_L^=uu-j6Z#0T=5~&_EAbVTKRn^Uy8I3cAzjff6?3kvA{cn z4)!U#g&Z#?a>sO=?wX(Dq}xA$45M&M%W$=) zr}w&jCbz}UvE^{N(Q>oW?XCRB&_`yfNu^JPbgdPUe$m;_D6sOs>tJg+op})C_QK6*#^#P4929S1rAq)0>S zZ(fJ3XqK5U<7w6%Rc}>+*{o*8=U5#eJ^z8(Qgk_<;{t(f_p@|WHO|d7bXow79t#%) zs7K};s=l;ceIXw7@$q51Qp@7x=hp&45lV^0IX$wGkp1cEt>+_a)+fQxOg%x6OcV@n0EiVv+4<001 z9EqMkwP0_I61AZH5Vqsx!^ic1H`-iW?;unAn1CWuMtni)bira0?U z_uPqCx8hUw)0?=Qb{|V+cmhA47q@ad3wJx{GikHNxW$^-kLB41cFazKC8{%Z;gkI4 zE8VgVPbRFQIHh+hS%A14KzK|{LG=tzpHC)Ou6MVMN!x2bgRFf0G;kig@UvBd9<5n-HYO``gS zEFfKBja1H|wqj$AUXiAbJa(FYbu4_{$B|bwlFavT@K>}}&XIyhPf>o6EhYaT9`E&b z@mDPBOB;Ppwot9Aah?$UGLzxkIj1olO_3YM0ME-eeht#+j=m2j;HHN7sO#Ju4UF3N z@#0FO;QRdkm#QV+{gnq9iL}# zYiPU!5tt&ThxoUD3~EyNr*ad3jWY2LIC08`>Tc~{tW(kmIDUzxktZB{(E@-Dnpw{L z3o9uD2k4W#R98E9)!ZrSLnF2P(iy9i`ry@_CQ2ae#%4!a$cuXV5kvOd8>DNTK->%-g-R4|NB z{vrQ1nO6xv%lq~Jy$z|-4HhfEbl&K-J*1=?y}N-u02vwmSo?zh*W&6;K>R_!m_#UJnHj2 zp153e@O&L6c(eK0J+}4^>L8&?eIj?eFa7vZJL{IkAq;z;3y&4-&+ zge#N2h3b~XU4czk6x6AjR^w)L*y6M5N9be{Nix=5gR5ZP7Q{z@NzMJ%5scVc%gmSf zF5}l$-*k4-^qtx)tDM_d5X=W+n4Rs_$uCaRt*l$j7qPSM8&HxDPM;KaD-`nhMk~~A zK5>sNboKq^6u3^`g@>BZZfEi1$EeCGrk*Xm3v+8^mFJy%3lfsLT8V2FRg0as{v&9BZ98 zR>S@P*#?`pcc-AW>*>y~_tn-nEC<2?6E6i#3B>C&NZSp|(7DA|)yI&L!(6#OT!XZA z`UA=00=hge*uuq^fnSAI6Z1)3TQlWXK*?!VwM9gI?s~TOYP5zGNE(L*1xvr)F_ZJF zmp<=07BTSs;_xAkFa#7tMT|H_CY$_(4@aTJ<=2j!2b(|_1t~b6In4S}?A*&m|mtki; zn^RHhAFj0>#?<_+CSEQJ{ZkD0&@HUf#~S^TD)-CVlOgmzS$0>DEEt_wq&Db{4AHi7 zrGbcIHeT}I2njk7T2+flI+3%L$dQ?9&K_FmyY?$p)_Om;B#wIl4GSXFb&)cp!Jj|zm%z$tudk2k609$- z`;(N@dTM^L*W$Jg0BQ$cQ=m+^0SWyByho(!#=bs0Wv}&pRf~hEIBy)o`MA7iKMT8M zBMUgiwXPWP)!P43B^i$tEo2l$YEWxr8%X-f#EFVsh6t)J1%e*Cib7j(yV3EyIRQ7@ zyfsT1y5v8wQ~dmXSX(7+>c-DA(SQWkKDMf-MX}%8b_n#oqu^W~+!l>fzBKv9AXzhR z+VT}`x^PAv0^!i99vnnZOGzvRv^etYqVBe_UKFau}{nWkh(nnP9TEuQSOU&)0H9dXG9&|i@?F3&J(P!}MSoLh89AJ*9 z)7NJ7v`~mXUwK9}PQ?c^`?mzQF2#hP$9h@~7Vo~v7?Ks0K6g-8)B13IR|?yn9V5l) z!Z0kV+Muw+w@UGeYwRaH%ktYB8Qz%ig6yp>FXw(;ua7<7+OS?)TgXWx7Y{?nBcrd@ z(bD{$A#(XxTa_iPHY0oOfe^TyHP$)h=j+P`AA_Fjbi<*) zD6KzT{axj6L*pw=)1IM@5DTmJuB9^Fr4}E$$-q_9nUA^xNv|zW4QsiwNeLatHJ1oY z-s1f1&kEW`2bqS}5J~fOa7L;jKN>XO7BKwH;Tz+RkymvMOy8CX9qR5h`L2Qf2&y3h zTgM3m2(fpwdHTBfKGHT)_kR;*)V}f={Jg69t767^3~OVf33B+c4+U>;P27W}f5B!~ zKAn4g1@@6a9h07PHeWy}uma{l;37Q}aLNySj6)&Efd8bj*k9qO(3IGQnw{J|zxm=-gwkvLfX!QmOsNcZ@S0v@4PmGaU>9L1PzF zfRDd{U$J;|Gpt^Om)2INZABMKu^Hlj73pr6|qQqM#4j7Aj% z(D5TEbgYCkGA=)c!j_+-;o2??({K(Fv+>)@*z$ZC3?6fJAdLMbOXzxD=Dv|%j6HJz zKZ_5<;@}$1NZ(?TS8?9L`~JR?-@yb8bCeVDuBRxLECpaN7#s{)WVgo)aps1Hhm9sn z3~Br>Jw1O&9%o33rYzcP=LeEqr?A;4Vq`>O4q-?po= zVvoK83Dv4`$S3SItN>z=I;)!J10qvLUW~ihO&Q1cOqr%xF!LR0cwtOT7Wl1%avBnVb3GOFs8{UFmXi%ig+14hHS_cvK^JXWci0scbk$KPPqC zl1+v9XQvIJ&-t*x4s#NA&qJS6|74HuLKG+X9z0O{yTWp(+L&tIQDs8kSgoqoLVNm7 zENe=Atxo`M;Xn*E83pp8juQ(3-`LUevIR87FgTaYt&`0E;)}vcwxOAa^G_=KBlwZs z$V}Ng3fJQZhoPaZ(q6XtkDb_FPcUF{V%|4_Jl)3mNLN1+=|fyI zRESM~3X*9b3%MLe08g?w$aqFg?O3ZR|Bc_*Z%_vYljh#ig#uTA?wp)RS6xdOMHiPO z^#&sRglXnXy!i(}IK-6=@XM`MI!^lrBJ8nnF!~foWUpCy=nT-pl&g8L4ZHO1b+15N z8|s?1LhQE(dOFrEXe=uNl3J8e2)?7Llk^-g7f_v5w`5>QKJ+rZ0T%rtTxB<4$w#(Q zyjetpWMm36GPb|a>qFbieLlC~)pCEXrv?CiwEk=-`FGblAGK4e-FV(zr6u6KN$4_L z1(4#;p!lL2%z68r9{>7Pn;qR5XKQvF18nE_4bWBB>h6O{Rt(sHK8^6{{f-;+^Famd zyWn|5{N^G?7wt$tqO=1Zaof=)_uGl4+bl^JN*%Fw49W23#dv_A>{V6Q&4SroCnbTq zNwPYYd@?^bl;Xeh@$UfO;JNn*|0}yhf||ii?rLXHT0I*g^Yo zujz|d##G7(R8-mH*w>wihKuK|W!d1w@!N1+*V;dxhf5ENZ&O0ue0=0#czxV7p>v>W z|D4baobyHi1}m>FAv>?p7RYzQOsg1UNfp!~OIomXTF`#JguUF-kT+0BgWkd=@}2o)`tG7D`*)RSKuGtnTt2fv$EeF#V|B(wc4A=-gTtl# zj+&K;oyX`>lk6ng>L?5s3b7*3KrpUyTM12|KmJ6;?C`W3#BUH&$pOGxIKka;bNU2A z%@df1Z@LamD{hy(Noa6AdmtG3!UVq3BWpBTRabilbR47CXR~(U{3`b%AMsTzj)e#{ zFG%4SkS^8K=}Z-kKcCnZ8ng*Sa-9$_W#HnKgjvqj_JDnsolUD;vCW3}UIvWrvJEf~ zIPe|Nv7g^s8|q;hOX5R-tzT+CE8MxHatcIK^P3e22w`TBQSalM5nNIl>=U#s0GDcn z-2h+L3&B^fRH?X|Gf?^$8t~{QdvU1+pW;t|gv<;{H@mc{GShtMeP0iVm!bZe+u}6o z^XByx&Q*7lq#m%7jg#iO7b!VV`Lj6%=Vz>5(Um5iM@K^Il3kYLX7hnfG zw;o&p5y8Jdn^66C^8P*jMk$aB-!4Lr9t1z;Y3e>bqUyFkJ+&m?;urbl{LxdNhOa>y zi%g^>6nmeLHT2r;=O|-I9sj+s-)j}`*-j1h%1Vtft}@U9Zm;t6`D<;O`^Td$ zj%#M4m4zAFN?M5-I!YOX^!?eORS^sSSo|q;dbIJZ1wHGq+4~2yE$m7yT!h_qzYcn; zHYSFqY?TlF@hfEa$0g5?kZ0*QTmfwpTf2=W1F39_Pozt_<=7){?k>U;TM<(lYGIuN zK7RPszGIHD$iv)Ms87=;603gLQg}bd^*#WSd?k8rNy7$^Kdxl`9cLMl2jN{^K%#nb z0|Qr8n|Ni4)N1@500W^y=0|mM*R#2Cn-;oU{+d${+MM$*#jWc&APhC(06Du;kGQaA{ZC zGO5I?*QCO7(ICYj@7o}?SE*B&<$*FTo+ah17tl_3XL*G=Qr0%x(R)_w%?|we^GFB3 znQn6V#+R;10N3_Y#(@%gxTPQ#u3G|5S|MN@vqDe6Oh(|;cyGPv8wz80nx%Zc*NcTP z6bjxIWcI+44<`(i!U7m`VQrKj6d3;BA*lDIJnd+VJ|(h?G4_pIUvIninZ$>LH($7+ z0TDYsbyX3EC}AOMp(rx{>OF;-ChOKd1wqFC`{F$UWTDMYimbkRXMaVw(u58}H)q*~1^l1rw(;6G6wIv8V(Mjm*Q;D27_dkl;8t$n{g%{o`~6e!B&OGy zn$I}6mk3YcrgW*-eZER7+<_5XLqPL)s$Hm_TF~D{tob$d7f6-(xo-}yZFZXk@e;M5 zbyp}wPJP&`-xFhMv@B}lmcV7yqN*t;Ba^#>Uv)!QEne=Q!v)upNS5BS@O>5@8mg*y zw3y9-Y{^tUHCbt)&1CZ^_41&k%Wu8iH6}H+=+wst8$W+B5*KeXj})c=Nnv<@5BCY} zIxox$lEBbjs|vBb;Ro-Ogp$`Q@D_~Qm=(-0Hu1+>WR4P~A2Df#1fC)^L_cow4(BBM&{Dsra9BZM zPvlk-uV=B?qe6O}OT4r-k;GQ6Kt< zGF#*R2OGp6-NM+jeli)ve{VET=u6e<+tYy|A$1njwgq?I-+uo+cGC3$9;(Lva9Kr7 z68D>}Ki`MNNyvy;%WvlIjJCg<%G#)@`C(CCU0I1)Ith8sUR8Zz_KSUMV_uOE>*etU z@SZ5w)C}jwVu^?_#iyk8JsUD9>IWoVf5Q*lW?^#C{7!kj^HN#>h$Pq%1zS9fjmK3g z&|0T_8I@LMt1U9^Gkf>TeU=F~htvB6#K=w#*y1&@RUQs&$155TTL$$8T?$_7^aWev zz{Z1NIS#%=n`R_}d$VNi&c4Q7bOe;0Uh7RJj(ExK?d=%05krXK%>VqPXApP=y0d^ksM*^sRE83`v&`@^5q}~gdUn@f__N%CdP!qHUiA%p zcHNw^wPt)_*)SOj?8s`4joj^rC?V&69h@ zFw$rSIYNrf=evrB;h{uL38WJ0foXi6w`RFVDlIv02-{Q+R)k_<>yy~26VmG&%2PTp zHRrkz1>Wam)Rn13xS;3d8%Dtt>TroIK2hayDD@_pyRbEft-miiGlWELGDs$W+Up4l zx@hTkw`)11gdU$u2`OA&`JOL(9Zj6lttXAj4NCxCZVb>{6=E<@gemU!Bn8}>T zZ+#tl2ki_V(t1a~`vA}q_Yd7xx+95#*VlwvGbv$*iDs}3t?$MEYmtfqSePl!7uJc? z5sAxAsx!DhdNu4T`9+@K$|b+k8C__Kop;jF55ocVJ#u4w=sLSxg!H`rB4er{n|>O6 z|NJRQJg=))W@CD;rp%+VAe{)HAIWs(2t3WtfK7}Rk03J0sl!?=@ zu$y{uGU3nP*BUh6++g42mvpsydlbI1KWUJQD{%G2%#mKprn5lPpBof_>;%tm{WRho z2O1EQZPCY=*FXv8PoNs~eqn!~qx(g%CWxmg*Zyzr{m+89hnaxUtbCnUR-3Q&4gzaj zhp;?$pCEo0s;687?FMC#q1 zw?{P2XLC-gh}#V)FZ)14fDyD>>SaTo0~1I~%OmptiapUAM(f)MTwIO=hOV#xP5rtX zub4RUvN$Jm3Ns2(oqTJFc^_%G(HYXR)6Gy$#fxLjYp2pj#5Dt|dxj4%tzc;$rDHR= z8zI9r4%L$WaWti`xYROBOtkY1?AON$-hcPGPx`HXf6ese+g|ZdeA3aybAy15!Fzng z`UQfv23CAkR;)oENpHy)``>_BF*z}kZ|XpJIFF$HF%A!gWL=)ta-;iW$mH|31D`Yx z7JM)BR@&Ul*W^uCl$s^Yr|%O>%v`oT1el znRivNRV(HeWEDTDa$m+dgde^b)h5D!pl5ZkVdb(KdzmLY&(n0{*p^V*D$aLsx$V!d zj>g8=WL14wS5?ylH{oyygV}>FO_6B0GeWp%i$u9$B0{yN=L}t3nZ|w2csgqXM9&XW%*pSxw$fMI2<)V z>~wFAb$g;X9@OgE4;~~R`KuWt(a_L1lo&0w2Q6(y$O4S_!q#Ah&o?RoHCsEoRp4We z+i$!YI2FF#zq?g%Io&Zc4*^r-ct-V?rlSCp#WA5{_s(y7QM0IEjfRJay%qPLovIR} z+-zFovNAM=EugRc>DV;+fIKlO3v2s*wDTS|LRSHkVL&*y!!qtzd&HNiE+;*cZutU! zlok|LT9-s8^i3%pKXL90$ki>+q8WJQ^dhF8dc)XKn5(HsHfn}_ixqC=9%D7fm?s4pDZknxxv$~L%SfK?~J_L z+K1X&1G{!_FxFT%*_uvv(-`0BjY!Fspt-!QXZl-AT1%vtt2oZv1lZpmN*}_Hl&K=E z__y-%QISnl|0Jt7Jm=GVpXyq~qC7=zc$xs!tmtLtYN!ix``VYeQ@yP|Rk`z6?&tY} zm`|5&_rap=K^c@K`N6)_0huZ3 zq}rm8TDG@uB6o;b&u^1jN_5sSWA2F5)@l6k2JtaPa|dS{??)(0-PP9@Q+kK6*LLH3 z+yK92G=MSmpE3fvUL?3J=$r&}?EpHp3{-RGcycHj6_^ShBg~xQ)%ngZU%mt?#10!{ zBcrD_(@>~_xVShYz{R`{r)GO;@+YDS<|0Rn?^@Smw(^Iw@NagbQvCPS!?vFgaMy?Q>sS4`8dXS)P2mvvj!X2G zbX@7u;dA!>8vOS1$VGO7n;^=WD{ZMpPBztQgM4@G*e~!n5GUGi6Av#!O_%{!xSBu{6Za~@^INz=8OvWy>VR*{<)`K-GN zC_ngGkmeC}Ts6<_RKf1*{AMsH5E+SzKhU!e?o+IWg4>^JkvpJS*2&CMo6#2Zb?PMz z0h<}4qBcU-$F`4preuZ;2w#ryr@q!GNXdy@q~H04Z2y#yUI%3ol}^EkK*CjsIb;4Kg^sqrhKj6xD9AfW=|T$i&oT_D)g` z0Vkj$5pDzb<(h|o5F`TTk()z5C|7;{3sVqGl)P4|`~u(&oIz5yRLHU7`}aS5F96j_ ze+@KnZe2qq6b|eI&aObF+$s=Tk2p>wDfjFI6=k*j8PDv^Kg!Mn)8SsS9(=X4i zz~)*zM}J%R`EGB{(S8Wy$zJ`ODM(buMV|#|1bChlJ2%NlY2x1!x7i1kpBpc-$7i~? ziDT#SdfK>_mK2v-8Pi}}S#L~I+K1e+t~?q`*Fdox;%BO#1isfe0K*fMlSEh zK4+D3G7H;xmpqm9EIatL@qq=B)H-wJ>zm*bL-G>lsSkJDu~vD?u{M-RWt>mp8`D*0 zet*al3i_r*h58Nklmw{dxWXAko)cUFTU}RrgeH$k)mMTFcNun1CUCHo!q4*Cq-ij1 zqw30*3ZA{G-eQRr(b=9jF70Eyyxgw%=vNHxVk}?W7|D3X@s-b#d)2On(6Zi;&h)kFVfBnQC3gRygRd_F5VA0LLXho53R20_}RiBi6 zXhB}>2psHC(+fs0WBHt1k2mPl_1!Dn;5|&LdLby=Oh}OCB|Bdz1~&aXSfw0b0Qz39 z29Qk&A^EK@fkxr>AvrlqPKsmVL)fB&$H+S#Okq=yCt955b*|zNd=Ja+JE|~kS4rU5?I({pK>s72uU!n`9l{aLD|(*5&UH&`yKKk84RAN z3v7u@)5Sqc*-uZB%m7}=eH)bNUXt(>*0n)6 z#@+40DoV%v1V6`<`ni2)_umFokgcZM;vx9TNgL{tNP?kYs*TaShVvEdx9#03%45(# zx;>fx_@0u^`FrElk*aH*|n?W6c&;^WNOO z7w~2@A>-bK%3^)Wiu^B6gP&3W64E=Lkz(9pe1}9VfeM6#x6y0lPa_}DY@x(I98JO zv(x3Nc2KgQ=GOpRB45q$1g3yWp1!@FVY|bUhSHPC__> z^G#bR4{j&cMHHOD2(QvIW$ZYtc2FrZ8TEM0X_gM?!o!5+dGz#<6`UH-9Jf?5o)+#~ zty3F}`Y4FZ{W3qAv9$ZR367WE;9#SDp)+17T(1C+oc+dV;dc$r6uKE@D)cQeSw{1z|*0cNt3B{OL^;93A_ruV%9jI@|sjA9K) zx44Sc@Xw&$A&~vT>YWP#rwNv%(27O2YWO{0RmjPRp!7ZG_C;WH@RjK@olSWMB$9$Y^l;r+gSiGnw?r8ee6^9@~1P+J- zdGy0CbzFBVzPjxs-hjILs|1Sbiv!ZT!R*(M&P#PT!`XA9he!Ej&_`7ixrU+Z zsW81xyf3VUKN4lOO^O<#4mA9v9@`##N?jp&BxloO6N#Vt=b!}FZuyDZYJr z);WA>AB+H_R`d+GwNUw;#&=Lh^{rik$#*xs9_AEw^)#Nm`==ijHs5==_)T_SgQt z*l(b{u{C{!*a4Ksc89P;Q6;6Koi|zxV8&qdAt0NxL?VU@$C1jo`E%UQ<1dr^I-Z<~cy7g37MyqW#>6DbDJyvyD z(XKFgUAiaYlOjOY^N@HE6PsfxLMc;4AM&Z~NXIW@f@;AoaYIt7yE{@g!D*~$tj*4C zo6HoW)k)%8XKjXImsarbfxR#o%Nn_zXRH+H=D%Bn_$f{wmOE0NT`Sh{u*VJ5Vm9%PQ~%n;(5 zEfxzPc1+Z>@iP{vuZRq$b-l2C#jbL5E!NqhXHzKIOEs(Rh90=eDN(mJO=(?6opkV%84T;uPVOTOS&>r_C!^ zPJ(?XZS2-$I;ClTL4z}tByZ{@Xav<2t1Or1&LN}E?L<`B*<$O@AwBao%BLb1KOZqZ z)^sdWuHi3_T)7wx8$9qfShU^F%af`uIV#v$)=UfJZ_0oaP5=Q1HX2DNs-W0C zx*VG!ne-yUl4$hVEiyX!Zpv0bmNO*lf1k38MD=4#?7rp?L zXT%gW%$UHI+KkU}Lp*?w{2fpC1upam;5S){?J0-7HVVn;WfwktQ>}I_3?F0tp-9V# zhF$*$nIB50rS#893rQ7~jD9^_Z1MBhjDjxG5>@M__gHvhB=@}0wN7TWU&ls)AaI0@ zo^}0k$h?1<1Kn(e18uH?=Y>-Zkj>eSY0f>)jVzvZ+Pqh@+baC^`A$}rF+%o_nu5XR z!J8urJKv-EUiYkJ;YCq@PJ?)0+AUn%`5;(~v(l5oheuGbQckuHm3rqcrA+=b8RO(G zE&MhHsGjr3N7jNKV8wKLdqiz7b$LJr6+Dj7#TpNTOxyY3)rOSp8t=CVoNtd_A>1*; z8Bz({6^lf43$B$`EK*FkIHcrKMxY;DvvTJV)z@hsi)m_a4>y{)^jWWxbLtIfvW%R) zrZ1d6e1J5U0(22ewC#b7zd!#0R;@>aRL3k%%8DxVeU&-C@=d=~WA99=@T*z#N@-{4 z+LtVlPvrYO9G+mLjF}aOV#!atxIG3peD7NMdl&JDCT%+y+tSwa`PLj@5{|C!O+9ej zSEF|XSMb_xlRAqti>f!#bP|m4rI5!ao!AbW=xr}AHfTJ%Z*$U!S1_tT7$_ZmW%a(W z+)&L^1_{pfKQ_MQ(t)RIPIIe{E`db{Tmy6UQ}0EkZ-5{Rt(8-7ZjoU2@Cb@#PP8}0 z00Vx|gPHD4+`gGc-6$G2#ZvVG>zX1fqo43=rztT>x7OCtE431*VhPcJk`U`F_Wl`d zpoUhYcU48Rr{uyYkJP4KvR4FE-q*k#dC~d1cEX2_1AJe7P)vN#`El(&2&*IW+h#Dy zCuOHLi~;?f;y!E(U#2gBhPY+5^??3Xr+J-$rW|O+cKQcHS%wZ z6%vRr2BN;_!5PM#HR+Wy>O!GXUbxx#A>a_o@2e_p2@l5pcvh3m@dxw_6bYzU$j!&X z@DBj%F8e`EQH6wtGz20b{z~xAB0;!mR|fKql-0r8i2#?0s+wA$&^c1|06b?%tlivB zPdy+ZA_mnuIHvAwbRRtCKlfBt<2=l*LKWQf#vQ`Un5rw!<)!&Sw&7%c_H;3bdc%aX zqKXpeatzVSl?;{^>8OD956us3Z@~Ju(-)ORaoQ7wbG4$8TK0Tr@0XSoTAx`;(i?KPuC^%Sn zzvDHxn%?Hk3{S;pN6i3~r{<2vxp&!FMw$UDPOlQEH;TGTQc=n8d;2eW7kTo~r84~C z5lkjft5^C`@X&S98>`qHQYwBfSo*=+h~can2haNE`qH%w{c_-!a;#`r#OAyE*!U}d zUQb&3mb1?`=@+8oZRe2-X3{a5FOD7xI%`+T>~)5Iz21Fgj1fxn!r&`BJs<-2umQj} znPue&ed9$qtx^%@*ac06d_H6`Ay?TAP19dc;`(zNTBM9YIa|A|r;nwmdcC9t;E^OW zoUiHfYIMhLzi)c$UCn1s*GgpeX`k*EwmIKpep zw+~|f-ow*fP!s*`%g$F4^ezkX9#l)qshYf%VTI0U#2!-G!7+_Y*7Kils$~r4mnFHA zO?~YPYgu;h$iCSs9nqghZ#~&6{IxYaG0`q0d69^}X8y4_xhz=}o?-aa{I)Y@d2vqQ z^_#%Zy8&nCAnYyDtRkvk(lHT@4*Fwg32>^zFvPF0MT6w4AWeO=1(b{IM1g&mitA%3 z3KV!Pmnwqlw_#LK@avNz^UW+_Zbk5ChmuW>zEU# zrc8e>fC>lO8Tx|QxijA!1Ielq(ZSPEH6WwjV0~-Q#&5qt`}=oSTcjGVcVN0FAeAw4 za6rx21(v4*{`o{~QSpD=)JEFaPE5@iK_=GTQymK4$TS*hK}ggsrFY&T?jWxuXa$;N zh%Mj5nl{cqwNu-V6G9K4(#y4bo2$cD;B#rU8X-TlwB43=`lZcK`hN+KO5S);Z*YtK zruet#KPrt3@@VD5W0RA2RC0<%2adsbb~}Ic27HB=!T2K>z=C^vd*4&o@pO3U`^k9=v8GT;`_;pgxMl7 zE@%2+g>Y9;6lpG6kdFjZtNnyBZ=u9GM?Bp8)UXDLm_i?^+eR2?f!#|73;BWfi*pzA z&552(pRXS9{tQ8>`F|`}wBC7$LGdfgf33-)$PTH^Kq6UKpK^lt5X7(oD8ryS-<;F- zc>ga;U>uWoP%ZRA7lfy77XonU<&RxgNQOcR|JV>s&CJ#DCIgs4IE`w~VUs==T~(NG zaIJb+UU;dJJuow)jS#(%aT*1Z-;Z<~`XLn+7x(1$_I4Ox{Z_~Dp!PZ?US3|k&srK0 z{a?jxOwnfnpKuTBvn6m}-Z>ZE@ml+Ue_+R;y=kw0E3jZ=!Is)#X* zas^WZ1z3XXTuo0{1YW5qA|c&G$*~h~aBxT~_?i^Uh|&Pi`qmxj<_L7EuCIX^xkKQ( z$jxyyBIF#|%C#RrvmS%Ak(61$yc`AuPStlvx|wb2f9n$3(l-n>_A;(w)u+)081s5M z?_D_KmdO7;uOX^zU$2p>xPNVJIYz8E)sLU%eTv%K6~UjL72fBLvuV(h{jJcrva*uf zmQi`XjPUQb(aQoE=G}=Rf6JydN!=Ir&l6W9c{%OEsGY#n?;q5{f*JAw?Hy3OS{zuv zh8zb_yT|~3GOG?dKmYVEXof^U@>ZS}65aflPzoMmo!D1`P{3KnZsXdwmB=becm72} zOx!!1CFj7VS_k6Hq7nXSoPoYRWxACU5Qo9qx*&4cPROz&xb-yM+~^#9YZNCiDSMeC zpz2S0Z~quFttvglHA;(dsK!A2(#g+|XOzRbnfe~CG&Nbq#tOXr*}X=W@dT;y;aUnu znMr??9~KFJqiJe^yB!r`C(4DQA_gS4Y}(}1zb`=5CaRO15r+1U7_1htJ2@P=FBkpi z6@8ByQATMnDE*BzLonl2_zu`cz6&@N(L$Zxya_7glaNRe(uW@%S%g-MVA7YxiUkTg z7QmOV>IY8@)^Dz_5wd7bz(&qDHab68{2H;%s$Ntu?6UUe>I{sYf8qMb=&7g}?JYfB zUt8-1W-``r;mcfFX`#@+X9E_JFQbRmkbKRTPp(1c)bBIHW1FwnU-iaE166o3KeCxL ze5K35)%dpahDG7h>-61YmUg{qnxCIri3kZZ8!60{!sX{itd0LZw=1f+KVJOcZ^Osw zhSI<>^=A`_yuylOPQ4(a9&9d7ZTAsZD$upx9StY?_uZ!f57P7}55oE#n=F3~*p1fX)7jBc+l-~bvZXJ)qAI;-XUIt?2M!Qq)cWj(0{@R=F_jZ!JH zv7l|Ou6sB*bpJ@@{1hmE&H7|Pdl3z)q^P)%`*NNZT}XUM`t|F?B#kGC&6ocjZBwqK zutvRdb}CHXr79>l(v&Yzo$;#7*4)Ta{_lob;U_8vOz<^ZD``Pb8T;a{rc5Q z=nm{7vNBy_%K7_e6|0&x;dulg-q3CAzU?E-2rq5qcmCLs8x&UdGw7k-DFXR@OpLzB zE`H^c-iS~BGZVt)edNAa^xwB!3w6PGcVI9~a6v7jeJ)gh%pw&=C^!w+q^y8X?(n4v z_%Me-|L4WJc6dmL@(F%Pf5tqO536(L885oiiUgRDJNXN40?&f|gr5cC<5V=obh|K( zS|KLx+q4;A7R$R*?DmvLNYuRjB|nV7p0yBBOle?lqVRK7oSaWhO_c)hvV)jp7ZDMW zvH3HBF%M+HM@m=o40|P(4`rO!$o|#_h!uW^nt;-9+tlSI{?DquFSD>3uO9~})W6Ix zk2gP_;v+1$$v_RNN^iI-wA(}TNvGeqqG%3XqaN~Gc>=sRzA-b{I)>Rk^Guynu|eJu zR79WJAcUcA!0Y=}A~`51sIu!f!@t!4LW%<<5P-foxVAdH8a=OE}qlIc;u8EvIm6r#;N=0-`qji!V8g1O}GLbJ)Q~8c^9^b=v zb7bV@i78hQniAt>P!jKV{J-ZR(!)=IK)lJ*?vw(3`*#N&T)+^;*8?q^#Tq)&c`!(l zzZk+vdG-K*rJwlW!;eLIwo{+keGQ;JziQR#;Po8Zm48ZdK!DaJz$a%~0)XsrwT+>e zaCfG(5D7A=h#&$B{r>&?B@MYcAgK-2@wixpcT!k&-vJF+50H+d@@@Zh9t}zx9CQAs z1yIB&_@)p)l^-PtuV&V)vE_m`c4bKuuQL8!m?4Ll0kaTh{reV0eV!ZuPK}IlruyR{WGlFcOaybK7U!UBn zU=!$j{bg^A$O{zK%GnD3T_R-2p8EqaG~;9=x+=y;m}XO|WSuYm{`UKr3s)xyUPmx% zQ3S}^lLeE$FG4SIzqS%mQEvjqJRv0a|9=8}@C5iUW8weSVIW3*^&+OOnwrVN3qaA^ zoUX{v7|=E7i(`}T2TE+~y!_98V>;mB^0(~6Y(Pa?3WB(#$#_uiV@Ci1zl@}$FD-{4 zF6n}FYvOa?$fo5m0V6OAiAvekS}_A~bHVckA5Mc--^9uL>x_tRyp}X=!S5#Q-PwZa ztB>cWpBYwA!NZ&+ivpzuHnpGzLTf9=p9wlZ(;gq);$MdygM096!Na-P)7BlC|BmLr z2Xu}X*tC`JrO5rq@%TmWMFR@SMf5iKfrozy1u5yLTqo7ZM)x{p-jm$ir;o+!$d$ie z0-8UsgS3W&Lc$almB9|kG-P1_N@VGnnpWW;7Z8Nk>o1J1M|Jtzhr@#L9&Ka%1qj)M_oe8) z`B%WF!5+<|5C`@lX#fp0z4~pv@Mtqb_;Q0G_A-~>Eba?O@4rO|;>Cg=>nMa~wWqm; z^56X;`7<(*Yx?cXnPbONP*JggkyJxrAzl30S2V2TOBebb$d@k#A2?hj&QHNT!aa7i zq3Z0g_|>`CU@RS;AUtCmCu7DY<2GF6c93UmQiya(u{ngJF;~zFpR9R{>@f4mKj-jE z@4f(si2uXab%0a-e}9Ci6fI?sBxF=1*XR~yQz$YkDVw<07FS!@AzLDwGP7xz*(+OF zmuqEa|If!LeSgpMf1VzXihJ+-^FHtMKIe5_=XJi9mo`6;vWo~INm6rEQd<8=R5(QK zxj!kr2I9ILshERPzkYp~{r=1xnO2WIckt;IRaI3p4}H#cPYg?6{{wyz2;GlupF1L( zkNnxU{{%O;ihUOA&k-u!?-av^Wz>Z<)A;Ifjg=$Q1uKo|u0RDJm-3 z40Pi7pePz{RRssI?qi$gz_rzn%3# zz?64*2vq~2qqCiPed6tReGcAA>zaDv-tI~2k{`{g zKCHsxp9r7jb++4L5 zhjt_6ifX3poxD5IT`&MKwm%>Tlx$LMnK0a=#C8OnjT)oU*9%ww@X$7Hp-adu^fRwi ze6t15btlC)7=|@B(PQyC9xhWW5CKYb>U~1~g2c+6S!teSH7=}Wak=`ah{klh}wL+a(Dgu z8A0K$c7;^c)l_Rslm_w~Fc`x1EqohV%~U^ZCf=LIPnYI-NT!{p&!x3%@68R5<;qLK zh{AXyk~H9cj;+s8Bo9kVPdAtyY35c&vGE$*`7XN0z>(Ny%i`AU4o7z!I)R@MTRUu+ z;r=)ylItQxnU;g&El)n0a9o)mX_kMd5cJbL&iLW`CAj10t=!p3mtcM#4}-}#Q7zUk z2R{Zh>@-G_{jA@Al741X72$k}asZWM`kt|A;qkzTwYGb4 zjkFN>6JBf*ub`6&k2k!K8=II~s7bz;;lw$NNg4GmBWOr;d!+zTK>9Hbj<%zv5}Uqb z(}PqZ9%R6RSa{>_Xp(03x(p-LSju1_>#?@jiF_Dca_H_=y{C>8c(`~{a@ylz?30Z> zAvt@G?oVoWQS3;6Q|mRdx%1FbT0g`Wao(kH8A9NcC+C{k^P}%hqO&VwQZoClF_$u) zA8n)TF+WrYcU~(SbxXZi-F@bxN4bFhl&C@ZYq0=3-0=14GVn$i=JQ#>3jo#}sZOvA zsw>K@D%1EVa_xF)tX39(Pxx_wSU#A_%ZQFAo40KoQWhvQQ0&^Ja@9X2e@gBsq>(_P z{vPfKCXVDA3!C9c)OkT;$Nm4=bU!Iql0{jPYJ;ud_BgQc8ZX04&Iv)G2X$`hS&WjN z7yAW;JK&%D3zxh}#d=lyPIeOXHC z#4jx#lT;XHvfpwS1w~!Lp46C_81mXVR>>#j&^c^DaV?b@(iZ8m60&}mHJA}NTfJ@r zIFx*(emXUh0tYVX<($!Z&=dMIjggArx3?1V!RU|CO?4LPbmDbXXbr^4;{4E&(CvE~ zF7zOQTW(*zer?k|#ls_iJxSxur@X#H2LCz#XGsb(%_KYbZQeEBu8t%W5$Av}gbU2! z@nN`iSkHdokbfV;tzwvda}vqg2fm1ih)lsJtOCvF;U)>gI+mkQn%$NC+SiwDZK-E% zPxoLu(IY7&d*&7HwtLIcBb;AhkvDc0!DxzK(1nkb2kyNfA||G7AIIM0*i-17$<+^o zf~HD#GM{^_Zi}hwx|vEH!kVvTkCFT$En}w*O<8^bdhNCr+-jb9Ezj@>wT?wSfpxEbI^(6Oj?OK~3*ZCCrtXY|k zIc6W*wP%4SHk*y>aq}yV4(Krjm)KEHu!Po67n8?JP6L5V$ zYi9w~wQ$PX-*uAv;y+W+>R^1P8bpRdtw{sB;r4~}>VXgQgWn|__ncieE*vvX>Xz?% z&xdfUEl<6Fs(MwbyIkkv9PgGa^L&Aq6fIB52yORtU0Tog$S<%QJ0@lM`|w4S6z175 zbbV%pGd`8R|D%`t5k~vpeBzuxX?|s|8-fFG7_}6UZYIEF=VcS`2dQ2niW2>lE{Sgy z`x+u>#6~?kJvDWVmsfE`ChOK`@&!oM=|W?L#A+ZIPat)8Us+RgooRIP_R~O#>U7e= zg+cmSrSdj#3!VGzdj0wPlPwOrM|fp-3MBY_xqLQjw1|KDb$+&C?7@RKn7^elL?`Z< zn)knZ3+MZ4T;h>qh|P|#wYA-Ec)Dit*K23oG$*(#{l#Tlb_ym6-V)l`C1{i(W?L51 z92#T%*=L^NHmb1idMT7an{5p!hGp8M62*w27wR;F)#PlgK=J>*h|E z_az8fPzYZnp>i!Ask`hu)OU?1Tu|VowmC>OUmtxO68D;@=+w1u&&2;^DcrI|Y?DY{ zm?F2=jJk`a=0RJU0oBhN3*KPURDs0N?hF$t$rNM`|Ng_C_lr@6h;2KIye4${Wp7~_eZ)uP`Ph?YBPBFv>2QgAw)tlcT% zRYlrCCq(x#h{qEdtMdKyTkO?-xsI@$!T~V4I|cAGj%Z1RY<&PY*7 zxxIKw%t({0WlVH*IRw$9Zn=zAm6g6g_fIf9p=oFPY=o*l7`Ba?Ib;)WST{o^c0l*_ zPl(X`kCB`tfmyt-V7OYI6W(R+PNf&YS0^idJr0E@t4(8AAN9DG4!XG5l^q^DC`=sp zT>Sa-b{mW$$c3CO_ER1*47|SP-!AjGXOM!rQ+x>f?^Bd1eokc7bWx1|#0g7d$xBWn zR~JTVk5!$$zL~4K>X4L_l$?fp6U&;h1Ow+tcYYkzP*L&iy_hnaqLascs;jE1s^-cZ z5-x51F)T(9mR{iqFQtDHVK_+FSg)w5MSsd-7P0zb^?Nl*d%?*d%7C6{3*Aj1&8QnK zx8KXk`12!URe3qJHju`zvY`fX0{<}#9!Lg~4ae!o3!nCfFOTU+v9oZ*oMle^~;S zv{`i)%+e}B5aCaGw&R^`E$3`DakULcw1y<3YxA#_|HTpD@iDO?Lu{XWdD)7ze!Sn; zKRXeS_tzAgNQw3I^o9XS%-w(B0NF*)N4O5IyN`AEIyQ!WUM2bR=eCj<*{vcx~Y06Ij2}S&@ z2apbdN48I8%*%R9Ja^l-IK@ZsYyJy`uV>eJVM zAgK{y;sxd?>h$|P47$2_JykbZ3S$@Z^yyQiV!3h6Y<$JSZ0MQX`SAN?+y52${z@My%wjwS zgM~t>u%I-D)HC=x+SZ*4{C}oD8p!vgtx%+V<-Ip`W_fveSGJb6_DOnSb2ZwjB-^p} zYns{SIzP_+6WYaTAtskR{~`|w6Sn`s(Q$f*g(ZKPc5@@C%Je>9^X>Ji0JEgcq!pKY zk>%Vujpuk68uZGnBa7>lI6M32mbn99ezaD}pV=9KcJ=2d$^1Y2Wd~CtulgXP!aW&8 zZj0z)Fc~lDg=^A0Hm~1fS7<5i?CnLQCPBo3n^l~PtD@yC+7iJlS@T67*>6u3KpY6- z)bT>wPLcn*SG!OmtMJ&Em>b|A_p^a%A98VVsj}H}cW50>SMSk}0Ov5kMUh*;CQ0!d zpy@;~K$>pGTR;B^CH|jHVkbS!r+s2FKmGKxLF!u8s4ZK9W=skoNeHLxOU$XD;=`tKS*e(Mm=^*H7w9bTee3_m)yJ`@o7e=jV^rs@_n zJq{fz_a7g59~2~SY@E=mnSR$}N=7<-rnnewE$kI2Y}S59gfsuAv-5)Wdk%)J)q_`X z^@Lb$_~vB5wq4t}ZrN}^?5HU9px2RD1Ta_aoK_&?_bs!daz#VlLqTlq z8UYna%4+lpN+ECWM;U7b(V>(xd1uC$5w zF@A3Dw1T%Ve^XAu3tY6y?x0a!1L5nlp@p&y)%`6Uv%UIti;n&Q1aiE_!a}k zeh047tiYrT)>PqTWn~=!e$O{|l#0_E+WElY3B9wkRi1b-*<0eO^xl5@ZoOjbjaH-f zoqLW@UlHYI-Le1*Qa&`1xFwJA<_Fz;8D5o}FtgJ)B!pl$Mkl7Mq-1k4cI#u%>9Vk~ zU3{|V=xx*7!5s3&FkPEzi6w}Sq_P1Jp~uZYXNo*L#e&59FE?L~g5}CiumLRkE#-#c zZ9exp6;cE%g^ICfU`SAqkpd?{14puHYlawHcY)&zbMQFR3KLA_vM*k|F!<_zsPr9s z12zn!>%Lpc^N%gNrV|lk?$OKrH3aw$cbGTQBypr%FjnxvvR!?qn(Ws5ijn&I`buRZ zgQMWZ)E42J9l7Up)OE4}nr8Rz&bH`rZNEynbt2Hk+-Rb%krJAJKRq{TmU$QVjT<*S z=TBSp%Yfv)<=@Ao6pBft_kNi&SnaWpcD?|G4&kl>qX(n=SSlAgle03p$EHshhK=a0K`h{csD zK{u&Kb_cITXKXSX{?1b*1k=DMAiZZRLklJ)10lalU zNvj_N;IZ@>hU%TVn%eIIuCUCz1C{=z@2c{Vf+Tdm3~qnUEwG;jLg#hHss0!%yxPT! zH$f4!wERq7h{wy9f^I`Exzih2_pSd3u7v~f5l}PtQ&kfAs==ufYug&>z+wbd)+j9y z0DXyefJk?T(PhT14KaG6CX_L&7dR~E(ihg+7Iu?w6;^3PLN2exk- zwL1wy!T`=*nO5z$Z?C{=%B*&68d~J+ZUjQXKnrxlJ%{<=V7ekEKo70 zGfAFS3D-Nzy=et#9%>fX?p;i5*;~fF{#I`|z5V?3moIh<*OYlN^Fv5r&3&AC^NC(m zVBzADRXV?dISO*CaH_5jg9rna%!O99R$l10KH}dUs~oZ2Ul=|oA+6K;soEF(*PTsF}3v)OQ^I(gBT5dn!yq8>w9OUg)v^oFy73BG{++J>Q=+3wIJUl!+eA>9_#J0D? z?oQIqQ5hxqi9qAE9t2aN+_ARwGKy#*M=dsesDctHL=geyX$Dm<>pxqFZfzM6N%aj_lJx_WHvK#Ra3(^sii-ZAU*8en zvvn0xkg`$J)AJzO$!B$@wOeKRPoCTp9dFuG*!3OqX7RTTI(+JAv-n3_<|oJr=2tyz zWXZeT{9Ii<&=BB!gF!!-T(vwO&+n?pf`4xkt?xk!*a2GcN=@D6zSIuib ze}99ZZgB|-iO4LqKgTBcArbM+;N-!NGM{>VNPCM4ae--=x700jKUCmi5K6Rk*{C$90@TH3nxH?bkj zu5BOmpPG5V5R4!cHbEevD&VQY#z(oR5()CuQCgC*ka?DW|Dey?m&)`N(~&xE*{*RNl@wyXTPgblgjtrR(`?YHij z4R6NsCxqaIf`G@c8Y9n@KWAGo4Go34OTs$y+OamR$?x8kPTcqtMi7!rSj53+Z8tSV zR&b|WuS9nKV`(%Ns;H1#Y2Rzt*P>66S3R4hOK+;jIk&Gmi8Ta2so0FKe zXZS#7bTlNzJ_Yv+(it*L5L9xaLQ*ovnf#f6mA3u(Q*prpScQgnZ#u7yhZXnKb+y3` z$bz2Y(Xp{raaZ3mRKX8!{!H)-G|1$?JZg=pwhn7|h9V)cPCFo22Ez?8rKV!2%sg{O zQJXz+y#8B{9`^)sqtxy*xPL8772Ucwnb$6*=ux=9t&8Hd7p=F%k=6 ze#9q5zWG%^z+%C(gaqyzc{UIOk2F_NM9+`5HE!RHSqLI@^)9q;dX3HZnmq`KLx4T> zpx(FILrMI-5isY_;)$aNM6wL2XuC7mz^>E_td{(qh?~_gPUqS z7JfDZ=0u8Ff)9VFD}Z0m{G|-DprJPu(n+^HGgt8Xxi=pEXHO{q9QS*b{|yF+a4mdw ziR%22>xkQW$)(1}|8ndAMU*rEQ}r9`@pLj1ojK{-bJI@PmahFy|2i*4mPqz^%$--N zbmt%B&p>h(|JrHGFj%5V;qDkfq|;A<)C(jJ$un?&liqoMzwh#Tjy2qcEx`Oa@V&~g zi1V!5(mL1?9QppbS&?)&?vC^#R?(*n;`Pb40vaM5^`U2;o&j+D=sO0hLp-hyLs@vQ z3_FrJoKc?m_q?O=5SZ-)H37!$N2HjNx=ydX2Ed44-~Q*e2g_LHj7*=!X90Dto@N-5 zlwHr>fdo+ipN=u))l!R4G>L%>k~lMFYZ;F`;nu3NZ|UUPzTu%P#5#HDS-m-{BzADU zbK*zN@oxQp-RX@Be)G7O%)kpS6a*p19T4Xa!zebBt4( z&Cl1gYV>p>G!|SlGTI*$dQ!3_IX$uAragVFgqB=dI`0ZLzn5fqrPDef|B1wRtLAGe zf)?RlJm@)BdR)%q$9d*PeS|n87%-xAkasjvX4JTx5(;C!_a_usKbj01E+(guKh4kA z_YRDc@f`c>nB5Njo`8WaHYN|DL*1jqrkRaEXd2BO>&$7Scn4!$g(8>ES@ya*%{HqC z40nO-=ni9f4$@%1;$MuS(ROX8pC3i3eTsT(QjjqMo%k9`o(wvZ zp+V}?CkBEnHuKfspxp5M1!#Fv;R+U2zpW&3gDnqp-&7qCmnOAqZ2@_oJ{>#B#}`NR zz+N|;VP%A;Z}oHEPt&Djkq6q9wxjQP8x_>09z7~6lYbP!!Nff`cEEW7JyEZxGnSq3 zQ9}+kqJfH@p;i$xSHXQqoYf~{d1%`{v()V(!}Qw&g=sA8>({SGOQwM#*2Z7a& z@I|IC<86LV-m0A$hbVo%%l771bLz2r(}6iF!u|P`e8HF44*c_AFm!+rMAT zEF)FiOZ@nfuKgwMeM~d`>Wt#tTA=%L&RoDEAR#n`w8BW+t+f$Im*6krPw%3U} zs>>VrC;D1HCK=R7fl5wSH+-!5GU&cTCieKMVwTtz_C!QNbsRFvoe0$hP<=_D8}T!) zygVTkVFwO=s$QD80(5dX!4I6K{osX8r;X#|@%u!p>s_FHe#|=g((c3MZ}y#^p%)Vt zZmMq~Tl@Xgv|xnWI?E?}sDhKX#9E$=M*quf7QJ~Kwkg||e)@jfV70H~udh~^U$?Do zl9x~kD>ByuIG^d67(D%?58(2<-F)7C3k!RN3Tsp1ee@I6>G?VEc$bNcCD8D-`?||* zs9S)6z3wI4$-;e4Kgaxu9l>1CRRh40b3g|81E{+JcSw* z;Us{)_lh}Njy|3lC`X7X2+cyoW>lltEdE*X^TU(6?Aoc)I~uTxbQFADAL|>ncl;ub z88H^gGQNhsHpV@iLFh;+(&e5T&*ZWBCR%76tHyM$S7SUi(rWDiy8xe%&}stR0G-Ud z(m;>%P}tW~VAC2<~ zNq&VevP=XpF!X%k#ziRI%Hjm&^c}|19Hg2LT~mgkV{`IWyoDu7W1miT0cOP^0$crX zjPv`VBa^)pO2_K?M>h6{W^!=d8v+Dar`0Rj=L=CXF5skq)9=Xurv+`%jeEh9B=_=N z;AZGAl>4xI7)kyU@4FU9%lgqp2G)(R!6>vRRP=XEVM=uX75&+AC}WdctaHfCwCK?# zr=q)K3Tf8*9mjhua-@#6uOU%RPN|%?zsK6^izgHBA;&qvwgs<=Zr-OuHU5vRYt7QE zt=LGZ&mqaKa;W&de}OGF?}!Ng>7iQNe0m)VYZw~kIdJgrEe0+xj8`Tb!Zo_L4N#Uj zSoav>cBE`+0F;>0XEOj*$i*s!ks$tCGuYL!$=;(2GoWaBM!IlW1!FRzCSd*URf?8+ zs!)H(Vz3A^2}P44gnC__hL8V=z>gr%eX0;d;I7T_9b0%O+@`$JkG4D?f9mx%(E$@wDT z#RX&03l)|AQS^|aXcnP02t}91skg$<^^C%hVf&38&H~+&keHcOm2bja@WY0yBxCKF zXYTILoohES0ByqtC^oqAFG3@hA2LJzZf!U(@JSC)rTBr7p2K}VAn2#QY!qAZ?9;_z zo1w509f3?5bmTP(0g{4iVwcTHwts+N&B(O028wV3Cd>wsFj=6{-d30T8+ii;cy2h_ z58~>=djRyLLA}d$92tr;1TwRWmn)eV; zFCZY`t^#DJjC z4zs-nS*ePus`P?(Na@+_QZD?BJzdd+Lv>gCfk~L~l1W_itm*fg5Z`6kZydH$ll{ks4~h=vN>2cZkq4uj zc3{$`+8(0`TH_FS2%01qQdOkG2{V7{MR0!WsF6}AOoY{M#MWY^avQ4xy4kix{;fB2 zQ}UE9vZ#?Rx=i9A*047h7CU~KP1N=w2w|u1_s@XA|R{bFbTv+!OMpQ&$+PGbo2{XB3n@d?@LgSmfXq- z5M!X=AYK_50)ULc!hZSpuZDkJCjhe2k*cvu(0W1&!ONmW1(Gw6{>d3=hI4ftRNqbN zI>)?=)<~E?BsgFsqW)}G5=08_pDxyRJ!0!5KTy#?icP?Y75}?J!3Pv zPv^;FS*fRc_n*PUVG0KhKR-W~!Cd)Wk_hL0kYaa5-r&1`u?7}WjB{mD(#f*J|ARZi zLN2PZAbt~iP~g&uQ3w~i0f6&i0V$v$L2*;B8-$XO$&{}G19x_2NgQHtcq-S_G%XeN zme5FLMib|U#>zft(8^Y_SuR@RbYybLS8^upip$l6IO-MXqgM`s+`c5U3j>B$5NxA` z1HcNbxbisp_5)0(QM~d(KGs~wQUY+w*xOUv79c>1Ikqq}+&J)QH~+z~cj9$wYHG*8 zvH7pxk&7cd`VPO*9pqZI&8Mz@TAB-duOz!)9IN@hI^GNYaM!5)lx#f8>Enf^nT{KZ z9{r$oXP{$KWEKYwGFb^sJJB(^llmXiepS4>vgC2~ywb|>t1%Q-^baxvA0JJIF`IsV zfU{DlRa-y**-@ZFTxr})alVC%YXNPW9Y6;i^q5=x!Jt#$RK@dcgQXNhe~R4QiFwP77ivHpE|w(`*ErT9Qs=^30dY2=jIAJ+b-S|-T8-LL9i``=86#ntsZ4g^7; z^O0f3GF$10u~bPrg9Q<%K=sb#iq1pAtdh^wsK)FN)i2&O`$e2yio9?p4OZ*L|NN@x zATeLz$*0-hJ#YZb;0g;H=|qs$_B)Q4)c6omJaHRB>Acecmai|D>Jbn9dy?B+>m&&( zCeIvFF<%&~+Xn4|=rD$Jmc_4IoM9r=X>d13AfZ`N!PZ5>m9@mcTE|{1! ze=~Qm&AQJ(OUnsI&HumY19e;?8nE+A!p=U{;Py*xmVe(b>O$a@glma_LTa|&ba-Fk zIFpm(3>F=|Tz)H_uhXRFZqegiz$hfx4vfzU3C$8XU0Vh^va38r$KNL(_3>uunkdxr zbXtgESnS==fx=dw?0SD;Z{f5ja#^?X89s%ZR|9r)_X9g^)IWxmUkuEC4iJIJ(x(bG znbdxW|65`vCZ&@{OZ!APjKm|_oBC3V5XneMhwSvtGHqka#Ts^8XCtTbshnMvZg>() z<^BGVl4n;Q8{0AC5kW4OC82mO9&D2Ig);}=Q(8T3onAXb!zfB8tU30+^O`Exu~3)7 zV{o|DM!R^P(*2Geu(wZJ3DBbZsGbW>BY+K#WQ-VB3RuAw+6Ny;=Oz#d(u^99mrdg{ z#!$|pl(=?M%$yrEe(4O>gz+p^jl+yMSp|icAOcEXL~$N;L=B+lb^on1myFF;RN(Fa zFO6m)0kZa+(e8qd*bx|vQr;sj!Cifx{p3l7EhzZvuoAzcLr?XO29@W*%k0k?9COuD zbh!Kp*JTxDKiCTOonzB~ZB{69CP|<3xr9mZE9c1ok&u~c_0 zkgsN~o}h@0(uG9ox_DI>C)6Vk_w>MAheaTeHs!$|g6Am*hR@5uGrA8J43JI>57e1^ zHG-8jB0~)KbF`;M(`&PK?KEez#9exE_-L(egvEDv zy4kzfghWT0;b@@sNUe2QLLz`PavEBSd-ogD^7zCmcxMSOf1-$ciXApLI@}Ty@@O7! zR$+~zAhbzG)reKazh1t3!cy$Ko^e9LN%a=?X^pnJS@p`rHF7>4pWR;e7|z|XZJQgi;isG4Jrjl$%kRW8oALXmh@`Q zU5|ny7N#jjDSZ*91=3yk2DN^A;_8Px_sKzxWV9=<6|mhBYehPZwE=z?h`zW^->YF@ zSKcueUAG?(;M<3jQch0!eIB;>x(nocj`X&Hjj(GLB_zo0WtK3_|2+-xX(h1w`84Oi z!=IbGv|i~(6R2e%-GHie`OBkc`d_Ik(S(hQ*F~%5X6KC3JujTxMLDrngl+h|GlId; z`fa%9buR{cxhrOIPCrQ#++W1l4Xad<;oE=w>e*SsOGeCqL|HyMd2~YioTp@oc#Tt| zs&slF@h5_kW+CssdrM6=j$Gfx|sC5{FDrv!SrQuN)_YQ?RMYA(P*#S+qIum=|-fc)H7juf_4It;(FCs81t{>*D`a={e&v-df>)geW zNX3w|r4&|SB`kH(CG$I(o$6kfpku9tV?o(IB1)e0(M9l&u_qgQdO&gUjb%qCJNTGh zc5e_QffB~Lz=aZO_*jHh>>hQeow0013%N|WN^45St0Ye)7G*r`3Ivk~ujf~ndcF?K zTByY4Jy($PU0t;J&ZiSSRmWO!#)HV#xG#*^VA@w&OO>TFudwTbuJp*tyq3H1?nsmO zVp00i@+)!XUB|?p1<{}MSYe3svNaaH>1ulz!E3%D_{H?jF9X~C47!hEw5O=&wMs|4 zEtS$R!mKhr@IA*m7H03A3Fk(1XQ4mJ-ZRVw>247&TJVT@O@lw|=`D8T)NQG{d1sJW zt^|SZkw&G5g#1@OK3^m!VP*FY4L#YdRo?0JtS7GUn=mw5YAokYul(iE zaXKm6uNfx!)^*koDNT!hUFPb_sA$mplwoAm(3ulu5+xcl`P)u*u|oOIGKA<0;%097_Kj|hF^G?@Xh6V-(vS|H+gSqK?kFoYD_d)O^bpfse0q&4zaDej>&i#Q|pG|&OlzR(iiBv2j^%gXmHTX|Fk^J zDkPIK!=zQI!S{ecb%gl=op~`f{kTV1N+O-)8BtE(ri&n{J8K}&-y zr%T~Xu!w4V$ZF~Vzi>Xz>L7L`4*1ZV7!wtVHcm+NV9E4s@?;dMJky*PU>0^t5-{SG z?l*?}K>Lgm*_Zy|U&j9~v(MP*cp=hwYZ)}w80D&c|m6fPAJ05tnXAluRL zsEBXvj zRJs+INCW>V;wiF6zI6fs!GxkC28eR{$;Nr7r>G|n*Ac~tFc&{kulak0EGo91e z)Fe~EG2@0dE2omsI#TlswmSB`uBJIZcMaS9`r0rMSoA9E-SFyL$N9ruqbiV199$*n zrOiL*j7~WB{sz^j_KXjV9%ijYJYw2{-u$`EtVTE6!=fB#Pmk9+k4~sc7ZI{1zS2J2 z8!2rw&M+xHg2nG9y02d*7t&oo8M)*r@QU5i4Gv~R@6O`ke|(h@nV_BSl`A(LRl*z` z0f*neS&Zu@K~=VfLMglY>4SM}|9er_8VXF2wwfh1MXMgF?28QO(ZoC%1fT-R11)!} zO?>m43bX&IITa)2DXz%2xX+5VdFc$BbDSD8mv7}E`H?PKM!~}365DQ?uG`8Ymws|8 zc-!cg%3!>h_Se68_~>h?9QOVPhMx2?xJyl9nOA32_3zjTs9(RTaiXoFqD0WhJ9lS~ ziyp?r9fSGx^MI9?;(d$I9k?sBz_=ReAsXM}tssw|dOso~fPbct7rjLmJmmM(HQCkH z)oO0EZR&TQ*Un{eI*7_4sgj1ymb*c_y65iPVe4hNqNBqLG{b4GvF5};WvG^{AJC?Q zjQc+*X*RH&xT>#AE8-x~H55%-K zwW?qnM17$DfWXBlf2*h8%&=qa%~q+1gp=OdV(Sz%ir<(r5j}_82x~Cb!cBL_3c_kL ztY@pJtqp|ONfwZ@Xsv8>t9GMUGKS*pJU*%~#znw%^M+ziy^tC(26+(FF@ouV#h>2*66}Y`*@ss|_8oJEmVMu_FthIgfq^gh#v=Jq z$dC;-cJ>{^QL+U5x1HUM*@TFDKquL|h{7Co`}%^m3P_JHhgzYPvVJ0`+Yyw*9*)=M z;dEo$MD;wzgXRpwO&Xyoi-X zg3VA!dfNu4Ao3Ezwz>*(HrtaNTrP#-`@2vl_f+JBR&%855+NIM5>s7)8*DA>;2J@1 zZ9f%>#B7u5<;gY`Lu*Tz0`rXA6#9%zRYyW%aAkSpx$;Q(QQwgez`^!`zJEPrj2&0jjSiKig2_+22U1;D5|z=*Fbr0ZBn6N~VYdakgV@-_lw3Jo z$1$P#H@_C32fGS@GqZ{_%!b7_kYNp;)L&zUD#7yTz4Ox*w)c`iC;|G!4M`_m=JR@v z4hhl6XUB3I6BX6v&$&$=4i{0I zJAor3S&LBH5%GHbZ!Ux!t9R5}KzX=v=g0dEMJ_G~QXZ$+3o3AD-3Gd`s|&R*?nM(5bYcN|iOZE;7FDgY##Rp~i`{w|4Ko?p}|8%C2WV$g3vVLpOthj}g@G%{-tCcn&==Pzi&&qFle3oYA6*k4tz z7}7IRrV?W&dJ}b6G#|cQOc#dq@i~x+Yz;;Uulj9drPKEv5kL#RHVK^ROuU}#3&fJ= z5<9FXwFyNqcK$RFKqKCP=uD}21gL{V%_p%BHs3**gzpGVCRd7}N*w-R(MSZ~(>s7$ zORR)G+e4*5nEw=7bAHV!XSPMF`iAGyV%irnTJ4)BZ~cNmo{oPnB8^jO-CDo2_z72N z7dhxq+n&v5`zD=?TajCx%PtbhY8Wm8S(m%|ja)5+U`$iGCv|IdqYlBg!_kA_ z?!GH$G_C4oZ}yTHYEerX*TJ#k@2a~7k`x|40c2o*jm)-QQfn<TjtD44vDbw8Dy0IaeFeig)?@T4t)*V54|{MX7uzCq9XqqE zDBN`?U)!>b(YE{<4f{)UL7v`96CrPDJWu=vomgw+d(rnPE5?!H$B&o7RP`B$;|i~P zkA7tUnj6Hx9yE2?YDs0d8mYQGTMPMpi?<(p=4Z>()wTA{!;t46TrD(x-V{gy5%!u49A@W{;4?Fq$X8bL^pfgm z22)|uTCLh|fUt!NdB8z?)@$#WTm1P6bg9h8YwTn{FL%{VjDu>`M7%Z3@}^6tusdDY z^W4+(>;v=s>2(LFnO;1X#NS^4^rg<*U%Y?p7rLLok@{h8!r3JMDf|9(ITNK_jydO&}`J&alR)@(yenUbNZWI_pFG-2a=cQ^B-128UFz*WYG`r zBecWDM#^wuU*|Y%qN-ekRV9~aHt?||5c&6)SF=%Mx#Y%Smo-GOQ5P=RPHOMSLydHb z+NGFbgRzXy&6%2$*?q9Q)_F5vk`8V|nkgn9I>>5;e&>KHg)(ifO{VP?(5%R^nkbm3 zyKqNdtU_6{gS<9#6vl`Olk|))fdhK04W+}8&l>SS-4^iww&Xjh~*5)!gWzz%0&{GCG@|-OK!% z6+j1pdmlD9gy8}(HXS8I- zR94FA-}&hIyLq+-OE-r;{#ev*GIDu&==?k;c`1`@2UhK)r<@HZV@%Rp*8;y3+7!Z_ zJU?`azU!_D~lT)dL%>%1M2HY?`_hHLMszj zrXkF4ufA~K`RGMyZqb-;-xQE8z}Vl=bRPh92|G`Eed*XAt@Yn?A3uFcZ<0#bO^;&7 zJrG8+(4&M}W2~%($~}|2?97)u zkMh&(I77E^60`X@KLg*#LPObMdvgcwz{yCHQzin9j$``s1`vE}kf6t%BxvHi(14jZ ztu73eE>@#1w&*puW~A_>R8ioAyD~W#jm(%Xq!3?nsc@89h5{O)Q7ZPd@LH(0%gU^0 zNi~pC7c*M9I>vm-FFaJF)22FWL_gv4E%!l|2vJJyMQH)$&~x=if>Kn+2*K0i(d<24 z{HO4_qc(3Ry0BdlxbL}yvtMGB4yBqr$rD~V^KC`N)pHba4yO56-Vjg12%h3I?Ri<& zgmg#zo2MtQVYt`OP=>ZpLh0m_R~7h?S5-Gone;k?ep+|4ljrPL3LU=UFii4ndw`5( zYu`G^SX_j*JK!lHtf$!Y%9SmwpEM9+ETS}PeyWLiOw{I5u;AZ z+t!sBAd<`bL(ldzk>0StK+f(9Se>1nT*JAY-Rw_=e)n|xl83+oYH9hj4fEq78*}qi z&COE`NVCYzcTn~_cAz}I*ha(_M&v%pPw^PX;yW|57hqdu$fw|iQ(m0$HXe)*M2Fy%!X4Bd@jVs z*cRcb4VjzPt>gW!M;yoHr6LYwhh9REY3{;;*{IFXIx=V%>6)h9nF1QVb;4()0R`S6 z3?gB}qqJ4m*j&+x)RRnHt=#7BA(jWhrKD7w24WNqslo}Uykn$vs^}tRpsFSf+jW6fs40=0nUZ}JjfI1r%qE!Ob<5{#(+Kx)u+cGdh#N6WI)a;90i zm5$#^LSoA4LQzy$o+G0@RfclN*=mjR+Og5uj$G)7A`yG91mQsY34;7C)I}#Km4-)w zyvnnMrS|~PR^hFaj~Ke@5=N@_3`U<3NP>bBCWv^Qt%mL*Wjj6cVb1>R{dkcSt(<4S z7CslMF|0|{>Rjgwj>RUMRdOWdCz#VJ^K9VT!3aEm;Gs2Y8{AE8$Uw|^E8(s2n6J`w zlF8DDV8=1iU^(=Tz{P?_Md_u&#gRnNhpw%HlBW~jh1TaS@om|rZMTEmv|I6KW1;p@ zUmRa_XRl`-fl0#YdjSt3mUd6iRuDbTUkwx-OruY+&4n8-Vbl z&}Uh*ZFD62KD%1oz58n`^HsnLkdijeYh?El1Npg(Z=o{__C1d8P3q=>m$)CTmtp9$ zaBvFZEKSc@mey5)@jrZBsm8+MQlgW@&JFS zA!Zu0gzC!6@w`3`a)7alETZBL8m%9?pyT7zTb!fue6m)yW^TPu2lnn0w4d!-yHae@ z2H(6%G4fr$c4ha1Z5LhRuJsTBM}6=n)eN;0zVr09^(D))KqD(A*d$iasNvX$-KFQ6 zIhm32UX$JX5>*{(L}*I5rN1RI%62MTQ%m|#h@X;KGW#<^TF}Edx=F#pZ#H28_*W5&F`Wq?ekY>3|td4p<%+VeBmmyn1A@JByK(pze z{PZq+q$=q>0|OCVFY*&l_Z*;IXICpFXA?)w`20!wQB+Lbq3TjkTkq@T`jniee7#Y zpe{EJ%`)noz$N2NL>7Hww*bk1o8i#A4}H%x3H%l!T>EPTLPE>9gb$vDws2aGJj z9xX{`k93)N%Y1|Ht0VU;pa7bc0Ovcmq-Lp6Od?uW0l^@+{hs0JCtS9fiGXGBn_>nT z;22EV=Xa|vE~!mcPCob%1tf^uO!X0=p{7P}h;1jX4hQVg-Pyfja!UTb9qavPuFSZo zD7IhS%Ytu?{0VP+9f4uy^ry`Z`FDT|@a?(qrr7*J7zv9=Z0U=TQ3$?r6?IMNseov) zHNFF`Ld|wyx>Q?cZB`(?Mru9>*P64tY&)7i;TAW ztmkRqMR?U&evKq@^mSMm$S8S6!vqgtcWI4RTMhs){u98V?BCMmRO^7!#usW73CdmN z;gHf>XH^vyq>Axo$EUFHD>&$Wva131(R?M0n-?#`jYHe4WFG}#WI%lZVNCbxZ_}sb?q0NJI1gg|RVCgoDju-;^gMtX#y>RVYFLQ5NT%L!rg+s(919byta%vFz(esq^JPdaSmqTD}Qh; znH2}vq!q$k8TYaNye(JFP#~sqM`-ixnew?3Syh{2FcUwn(sn%uHx^C!{ z*K#v9nm-rMCeMu0{2gqP@}VEPXXRmh>`D7fMyJV=od_0T53!fT|#_(0}kXKUj#;3SxKwKodzfG~sEZ)*>FU+rEU37C35r?5$5+)WQRR#0Fmo{gA zpXan-H4%0Ee2Y*gqB0jTz1q)t{#QjFRGLoOFN$}9o-jx4FdAYReVpjm($Y$UK%GGe zK?y7`^1dCu!XTGXb>D0!5&|6TvHVOG(AU0qCWd^ASe|hb_l0@w`;gm#n)5xJUV9L8 zjwgk>iND~`KUFseN__AT9ZQ;gu6YJ|tY6!H(IpATLJ`ls=qesEucB(jXlNU<>eSd-wA3|mQip)TBY+Yt`{s{N zk57Yde`{ClO03lER+*hQfxdV4BRskO~03bYm(Uq_XXiB*A`gM?qN+ATOncbE?YX*8nJBvi|TPb?B6GPx6IjkZG)n z4HuP^9$)KYUbAGTi$Hy9>nX=lopsz9_>j>#iTy)?v>YLB5w5KUEAj4~K>rcCySvWB z4vMX&JIcGwNJQqsjrBU9gMXnj)>dyM_6)^qRUoDG1Lc4k1dhGL=U&GsEY(dYm>B`W zUAmG>z^5JECpPK2R5ulW=HP4TB4$w=g&ENaesK^C4p?fQkOsLWh7b-;POZwB33p|Q zg)hEk#3XNy3jqAsH>B)BUaci1B^7tovWOxBh5HGaC-Ay8ClaAH#636q%hdnr-se2r zm9Lq^@8Yk>=8td>&we{|8C}rRVIlw2x`syG&Mw*ctj&*GAw_xnoF^~nM+B@Qm6W7_fN}L)vDjnDIt}P3 za-%MGOdj-Jp*~*(h5e<8uB(it1j+CQ{Gxx@fOLd1BhXV#Lr;1n$p|TlwwA69~72R_0r$@ndvA|3BZ{4)lZ|G&dS#B3iiJ%>pl|BR`)VoW!3WS;lDzki@Vov22ru@ zm2Y_we=O0b^xm9kSsRJE`{VvWN>TF&D{rMR?5$PHE>VZnHcidzNfCW|1i9&`({t85e2bR}aRYNmtb4)INz9>mF!7{c7dt z?UJnv-sT^d!7;N;3|a~W8fh_8#cMWYD>tx1LF`rTFD+b(ysSaC=mm+8TvmLu;;cZi z@)p=Q-<*1FVL*jRBf&G}3a`xc;9Uni0 zc-RNtDGQf;$~6I4*sc-ii~*4?=+mj_=@G5C9#P?_#l^X)hihEfrRt8x-b`|axF&S= zq1dT#KBnyCoE0x39Y1})c9GM1h8LQ;$d*$`99j}q;k286y$M?PTRir?c&0*;q61@8 z?8?VIDVPCGZHQ7ax;zv2g{V#$WCsm2Zi|H zSy8>b*YrIWzEry;7tCdC^@>dSekc9GTLyEElXjjVFr_L*CvGL6)FpgQoq>IFw>1Q8 zFm*L*gKzk;*Jr2sPg)4}qYsorJ4jhCOJfQz zI1x;E`g)c^3k_eJvSE3XNwTlak)!y#!epL0a%s!>Q<8i|z}SJ_Bt-_EmEh|qPx>R- zGM{=YyegKj`N}e2tCk!Ruecf{8_ZobWU{UJD-?WVzRD-$3YqFK$yMaK88{E{m(k?g z?PW|V974EvKtYDYbeFwvEPgM-->j8ea8l4`*K_7!2tBJ+2e;W+{;S3?-ty4%+J@&d zu2>t5Bm^MfRN}F$Q~Cmg%lGEV3sK0&M8L-cwzQ67C`=h3(Tk~ZAYMJkcQe`ddfKa2 z$|=njz!Kj2gphX-vcl;_;r3Ca$MIk`E- znH$JXn(q}06nS;(k#&Ux`*Bp%vbz>YPDGLn zWtXNNGt%hW`ch5U3j*^?2!N1V!rm~R0D-e`zh>>NX;B$yc;3i~Vcu^#WdiflL zg7;R0h>A}h=|%?jgg8N+_N2Kagc>Y!ewRuFgv>tun-!>)BMEO+jqP*(0(S6}C#zeZB!g`7$lZewnhOkE505Z3+p$^~%3K=LgUlZdhAckb{*Nh1gib{Xeu8 ze4##BQ9$(+^>CZ=8jGXsOAb_#K-%O$rUzAKK-yRFePweK5z6t+EkNEh@y>E-e|1#upeFM#Z4 zU6ENf?(N`=a>;2@bDu)_KWj0`{th@1DP!R(x*~EfBn%ekiey2dm;3XuL({#F1VQw| z>Xo-|{{$AWda;-1g>Ny}47813RfU{7tCpT#9kJH_<;w%PI>CY3g}xHn<s5r{iczU z`lkK`kJkWK_VxO*HTf|;>xBsH+|L1*_!szFb4x7>&unLl5WE?}TiS8xsIp3Kq)9$+ zJIwIzXY{ePV z7VHsB`3O^OZTNIW_Vb~A(ZAf^uvlz?*4eXX?;@NLMn;=`0&e8J!EV?&_@<%$XJ`F$ z3HmSbb`MyyEqesU)bN9YGJS~p^uSo-2UKJJM`{KhPME+v2uf^F`NwW;lxJ;J$(FB6 z)fZS^G|^do`{>cn+R6a+moXM~c)w>O4I@9?=j62P-mBB+wJS2+aWzc37Csi~Zs6@}HCD`+$N2Q{J1F+(~hk8(RXevjfBfMKlJ+w4t-M z--TPYCel*41@XjubKAp==Vv~57d$TjvC|+K@5!AE`iqss9(w1x=#V_8?v$YNqSuZ^ zy0BNT`mn24IU;}f23%0tip_fU)WfV?+V!h3Hjzkn)qE{jY(zxeV2kgmBffI|a$`iE zV1H=s_qdeeJWT;ZxAf-SCRxUy)AXA^sk+?yoDcyMu3W^xt7zGE`eNgI_q4>)-kk+# zW+|P87+@AFOt$}Exsn*0m^6T)YpK1rP%NL>v*q#T;lRIE|3KmZqEkw69F~bMcgid5 zTOK+6n&*XZtGc8ZkFuNOTI_N7zBxvdnrE9b2p!@z4QA>@KtpI*w(FKIX8SRGtWZPa z?ACzmRcG<#&=h%N2;;Av6;i)l8TsUgBX9>1Y5jM}?JJJDScev;?_1@|&kD;8rMTw= zE5gn~`k6JBO+~|8yN7c{nIAK2Yr@IlU~Bo{m>EBo|NQZ8a;?o6ghCM>V zXcbl2lb_oVX`Y?l=JaG?+kN(Z+j-r0Xy;zLKsvpAd3l)EQefa+HtsgnpPpLUE84Jd zGfiti(jqcN3@|DyJd>a{A~NFh!4w<$nXnWWi8;4%1jStV6z=pR^MlxyvM6g;SL7K3 zQE@Se{%2znrq_94wg>c9hKZ&5ls_y#`XjKdlm0__)tmQJ1`7A%)BN@Sx+48^YN{!0 zNpDZpE~3>zlH9oYvs+pA@l;2s*+9iEYn)BFPSwbz;wO{+2Edi%4wT&MUEn(n({=+I z#ZC0sC)g$5|BOj9`EdNj(U7_ByCRgyd(Kw_>%(+0r(Fb1<$2eHH-Oju5p~j+;RRLx z{ym$3BRYJPE)=o$TSW%85ic-QV*`Eah=QD47`XQc#*>Z8|MR@QC(g~o2*WPSMg*q@ z%bAaAuL|fx;lO5Mn0lFgFh$mx0K9dn2v@H>6ICB8S{c&227OqH(15m_lQcx1n3bgs?E-QXFQSSimpQ!v5$2KTAk zWw(?1r29fqrWzWL*fzf_%Lk8;=4RFZDlYtmpYlCH_xK+0RMvbJcV1m%IDCNn5-?JI zT;X8(3+&8mTr4it|v!Px#|>m->5~__Qo+4G3N$J!78To~Y4}N3^$nL>a#Q z#qqo@|3JBLgMB2SMp%SDyA@i9Y3 z-QdP(k@OLNmsp8DhYZm=ynzWFP5JzN)&YA}t-Hc)e)G;V9*eb5JT(EgfZ=pwbjiO8 zQFKDx!4td~ZcwG$i)DxGvmhka@{NH5qR*q9*#py$sNab73jSxk`0k@Y@J}h~mX|X2 z@)4=<`f5*P>8P_Rc082MV@|x`?u6sa>~RJfc6#12%|}tZQJ_69$@P@rI>xwK7yNqo z_^bqd7?5GlBT}$ncVqnv`(DI1L!?IpW0;0r69ENj0jIXV#nB+37>6pv5x{lg1W{qY zr$wm4emgIr&NuDCX8dYVm49&rYh={q$?tSv&gokZ_%8sRzWT0X@wPq5(QT#MR>oVbMrW;plb&kC6*$(W)O=A;Ny<4-tUAVU-N14-CFG6fu&nS zaJETr|+H zVQi)PT^PMi7&iwv?uWc#keU;N8O%ekwG-SoVQlXEm5KWIRtb^{v+2p8s zRs)mg{3lvdlm^Ok=0>7Yst2aU+uIStg5WC%8fRC;jom$(6m9m6kzxcUZ$RmBe(0iI z*uF%U&-=G8BQM`RU&c?w`T(3EKHwEfh}#`>Fwbn>QpE2%7!077+#^(EZK< zE6D0Y9~%($LUsTG_>(qG#jDw`m^6pmBRAPz7 z&7K0}K7KX2Zr8Oo`F3_%S8}alw>U-LZ;+n1@Z&S>o-2@vTpDlSO~JRS;BP#+1Tle- z=+ll|H<9&2g?$GUNRTv$`3M-J;TNjR%*+sRD{>-;Z`=ZAaSqJkLfq;>LR!=@%3HB* zpE4qKCL&{ExB#`PUIn4eqeE+batFp##1{M)&eQ?U*W2}vj}MxP6bSc+ zJqjQmzuJS5co7qKMd&ljmag`;bG@ylQ{~lATV~gRp%nY@lw*T z-rnK-7ev%YbkQjwP+=}DULe(nx2LqL z0+ge1#-VqC#~5eR<6gd;?83*v#Iu`68N^KM$VPtvvhJAS1prqAbO+9g#PO5(Rv&K) z`|;#CSWkM^O@JKc$og>+(w$LAdZ(u?7j~mtOQ*6*cz%@Y+J8X?#N?Fvy$t<30)smm z{lavd2*x$hC342D5<6Cxu(zw-y*y_Vf%unTKMe4QdhNM~O`7)z^hX!xl)1O>_J^*u=UrTGTFWcLyXb%y&%zP6}DM;@!P*ZDJ zvhfZtB%yi*W*wZaqo=ZQdoG=!m;!btz@APk`s@t~o@Axp*JdDhBYOV)d3D~5aiv$^XbNyXP}jrsx}N=u7&ij zG!;f9CYq)bohHUhe(;m)D|QNxzHG9|hXwG$7(tyjeziG}X!n^oFJ4S%s5)e2B4er1 ziw$752EiXw_Hvr$Z&)yP0e`Kp-ToG`c^1%=V4Lnp{u3Q=~h7 z{jcDVNYGv6{XA%&@M+QctgP;v$zX!fu!TseK)*$+o}c4M*KjSvqAvB#DGJb-oQ?nn z=JdMvo=Vm6hfkq$@ip{d=3MLNnt|!B2!xcOL~9lv$tH)#aQWrtylMr7Usp$F&P?$X z9bV6dBO5*I2X?lqlD-c&`P2CK-8{tpIX+ofM4O;Mj)+@R6~n6O_|4pJU%IOPqfJ9) zrT0S!F=EF7Advf_<7os`9m5TyT^yH-SCd;c4Lw)d7vJD{sZU`UUbC#|K0-eZp(DEl z>MA8lO3KG6e|=SQT73Wxlny5#9sdB)^gzzX_=^zJaOcl`{A;DyU7E` zt}i;_c!gK+P~+r$R&E(hw=w7a#H{n! zSDY0-K&8K28*@?SzQw0c$0XjNDm~AM8k;g|v9h)dCkC=W0+)OPU?fELeka%BMyX@^ zukwm-hf#Wp|5a2Uwhk1n)ribRC~JS7j($sX^W81qpCcn({b?b@9Y3%h^r?NhGogy8 zZDN@7QKxaW!W&T1BC(z2R$M7;Lm7K}dt-1#!<9l|F_qQ`B%U*8)_EP7?zNGK6UGr? z4vc^gaAb_jrf8*l(1HJ?MZ`Cm2Je$SM!O~);TwOOT*-9|=E|3f3FG2dS}@iu)4xC zXQUfKGId8>mc6dJwXaAZLh4W8yM3(x@rix6uzw!f*|`Ae$2T)wzO3Q4JU)m#w-WP( zNw8RFxTUVyH6X!p|Cxj8eG~;MjQi0Ga`Ln19tkIMjPhq&d>1ykm_hi(=fyz^Y6?PX z5>ldP$@1zf*PG@x`fT3rX|-#Ki(hSQ5?{iNnZ2D%Endr<#2I+4#kRgr&NpqYOx>td zD~I{BU`XPkTbzXJwt<%1QK26M7TtNAL~d$gLbGAHs2j5W_xgl+@+`k+Jqx-@Kt%3C zfMQamB-zfz<}P)ASQu6qTGY9Wl4l`AEmLlE>hPhM2ndPMfBzt<44U~}P1?GwpXX{< zjWftX?;la-B{qKHV;^bg@Qpu64g7k|fp30!lqZN0{ zqZ-xD(l;Z$ip)aohM97DKb8+uZs*q_wktd?C6(Xdue(kQT3Z5BlxM#1c3Kh7&37MR zjL_I+kpw9>@TDf%n|I+e<2XRfY1xPcyVOK z=3f>*fYtnWy)G#b5Q^uDojUUOGXMP-Um~Fz$$hrivq{qfK3Gu)@P^gGr~)?Ma21Iz zWWehdC|{^rRZp%tq8vvQrx<&^5OgzB({LN}2L%{u99;vQNhf65 zA$bl33O{bRZUVQyIjD8;qEn_F5Z)|Y20TBsgLm&6IrXmTuG|?=fP4U^%1i&6cUo^W z>z-^NMJ=@=ME> zE|JV!!oF`fAfUmPsL9Z1Q@ZegDv!5h`qI`9zhk|l5hn4T9U!(C^H&dgXimdg6)<+j zP7hafxv|~7~U^1YCej9w!Trz6s z2FM5d6d3AZTfEh)&>oenZ@7us04+d1ur&`=IpouVoGw`T$J}rnP4(s0PB6tRfLcey zPCrb%pz9v(2c2OMOyz^pr;;Uu(WTeU`l`Qc+7gee1JC3zoCL9R*oA-p^Ngws#N{k{4PSCQm3AQVb zJ1nQtTy8zJH6})^N_PqG@NwTcVIuH-CYR7AskZkt-#F)1``gli@f6RHbe?PMUxn*u_ZG1&DW^yaQdOyh_4qu|Hu}8lk19B>V;`&o)?R* z?JjlRdD;b$e9VB2euO$pbrS5$Y%$|Fnwhb9Zyb4YnetPy#fM7|Rycp^TaI)G5y0<)O|(Tvc1-rKcqtwcm@z;SbtDywKlbT~%Lg%@zqvz$*? z8N}UKc3tcONU39iV?lpqE-s15U(jn@JnToTS*xh9O@C?CyY3hBttyhNSv%}*1&iYq zKmwxt(tVt1K{Afxu$v$v1MGi5ZAE|uiq;HFK9_$y7H4`kYPVy2qhZ-I>Vnrt!o#jg zXP$OnNOWo23aS09UqSY$_J`m#S;VYr8n{4?UtR_$@pBOQ4J->b&wa`o@PS1aX_hvc zq82}6*-a<)DEtC-7BhiwCEEp)HWPtYdu9QiF?lsM#m?dFdKH{At9uc)94Vf6H&imnj&Jh(OyOD3$GpS2&c5YoN|zQ^5yN}rrC;F2S=U+Qs5F!;K!UAIm`oOH80p%E;1naR+b990;8@s{Z!JbFq1Ej;z zW*!0Tc(wz3sp1%RV;Hv`xF;P*MjweJgsu+(Z*9uoHOurMWh(1>+F6{% zEJ*P5q{QHJlVyX(-n2d-OF1xKP75wl1rnZ{D4_?~+VH(thwpM8vd8(asGY1FD%yO` zsZnj$A!4liR&0R!NTp4;YSO^Lxn%tnuebU|_DSC@lFtqm#Z!*`I$Qr)(OPSwPkSye z`W)^$@Bd>TGzDd6o>@3m<8wiQdY03*ew2P_0jf|_k2W>ggQ@HA_Js&9sE(JoLV)gT zhYMte>->6pmFtMrs^VCBRUTN_92(t*s9*AK7~?(1LFf$JwEh%PL_TLbV*p|C%TbYW zrnwgS&$zx_`G9Y$-16gVla3LB6;fFZEauhG?26Uxvd;xU9j87WVm|fUjEC~-4jZpI zc8V*lOfl?oeH8DU4duExSB6O{?KxD@K(by8S>>GRt=soHfD$&<{#LuN@OswB`D`Wf zP1A5+)DTROEB;2ixE%E`bHxM1wa#GHkh)WPya0pQ!|}tYIZh%U?J@dx848qGt3!); zvZ7RlSbbUO-pdLBV}C*U^(}Cu?f$7Y8!f#I%!BjqqpP^ah<~R>NHjZcLqt6OWosix zB@~D*Ab&{NIaJz2y=#!zz7oQ<=g6jrEA~2O zPhyXaUX0k90bpg(u-E}x`Jlp&l3-ZzOwPczQSr_Q>D^4*F5Jc!Og6ViL{uqv{eeD< z7;^}#uao^7w_kJzia&mi?~ZT4O#jr$m>*bF^oFpK320kT&+(4S8V|A8PR{p$L)37^ zWAQZs&ME34;lk9e z$#KDIQ0v~^b&I?n;4a9k;fAVE!ifooO6of;W+6l^s&B{bF@qh$mLO(5rdj7M zSkI!oc~CyUJ8C|r{wH&$?FJV6Htlrsg{keqsj{u>VtAXrsvs(Zn=aX<7vj5M(r|n& zP4-sZXUs-tZr4jbv!Pvvahv;VVXwK5*#u~63%OYpgZYJjuuQ^SH)JccH%(kU7tQy; zfQINxy+M3PJEW;WU3Z>}pBR5*GOltyq294ZyXW19it+=esr=Ac!5!_oe7L7}v zpP?+@G3prk5)%?oafebI^sP~^vhW5jalywEZD%)U-I(jcPs<#yBH0KCU57x11VK_1iZYuGkNCgqGIav@_B^cneh;MiaKV=Vy!tmAW^kQ7A%WG@b_ z+Q;v6L9ZpKiLxtMaj3{J^u|rsJyDwW8p9K-)p!}=J=btHB~sV;x7h+OURew-P+yT6 zoV-Z}WRNd!xi|~PAsE$vKF9KN($<-IP>DeZ7ir z=9_D&N0XX^E^pDj2&N5`fT~ytljo)IoJ@BxZ->ps3Ht$`sfSkvuqK?m6ud&c!*4ra zZZ=v19X8cu@B^gTecsWzV~ev#z2kp|W!du{F7mb;44qoEUz4ib>iH5km(#%Gd(LWc zKJ7H|)9mVc_xP-U8tn?eNYi@a{!3U5p?ati5;;tEXY(|6R8 zr1ahEnM0LO#|6qDk6VR3$)3teaWnBX^$mkn0HsUrq?Q8f7;4_$7yaHWBC^5> ziPYxBOpKn#G@>i-Hjn`$_LwunEHeKPQv@T(6QRnew+3@v^x8~850C9kMW{=$z{zDG z{u$BjxdDleWyDkhB-V@eNfBSVj> zQM3k$$$R>AAM^=I)!GG|xO+EvC567|gHaU*{SGSE8;#eU`(Ekhn+Lg1yh<4CIpDX> zg9z`(F3yd}My7cF~Sb1^bTJy z3f%kp!so>)>!=xgz{*$iw%1{K$jok*=Ogx4o}be?lP2lCyNx~`4r^JmOoADP=}>NI zX7tbHnJm4^PY>8^&>Iq!3Orcp*OL*7tjysL62N3##9{we}RGpkrT?Zzt`4 z%eCBuB;-f}&*|tC(VlHMQ0y|tpmpsODksFp-ot%Va;?7fj?m+hdW4=D^+6}GcCE{V zG22WgWRMO|>Rx{P%cIAS#X-y~3bti&W2J%#0z|d6;@r5mm<{|+WR}nDidk>rdjs$j z5&#BOjF4RtCtqo4+l~MXfQpE*-?qwKDSd~F_R{!#gHCL9$Kp}&JMw;xgm2tl!K5~G z*~j9u^@}d)8}F8m3@)s!@k~F*@%dykWiNOt2?wBWP`)-ODY)iYsdh8Reo>M1_lq=! zxed$QuEfCJ-uG>#hcl0!0 zZGd27-dfQtK3yY?#TtxBl+STp{{&8$X7$6fU4X3I1BQH#OSGe+Ho5}Dn3mv0nGa6L zEKdfh;r3xj?d_m!1>=ti>XKoos81Ar&ku&EG^Ckt-cAq#Mt#h-aZ@z%B$Ri-b%gAA z;MKCm=*#S?@%S%b!bYSt*_M7s=_Q|B1VrBesk$_{d)l*si$CFlLq8wXAHW2HTC@}H zs0sUc_q%pA;2PDH$52t@9xG_KF376&%BOIP`Wn_q{PIPS`Hu$Mk9 z@doJ6i`MGNy8pOVqtUm_GFTv}M zXcZfY(0Dcpv;wPuuwfzj7urV`3g>RMRDHD^Z%Tyz^JRA+d{ed8%QAd#E``LHbuwAG zl3_eW{`n*G$WAc_Fpm&w+^&@=m-=P}X}3y*zxa09qxrc6J7Z1}rh6a4j;5sKSlDf7Ib?p&8@u`elBD~vS z_mxR%4h0tvC&U4e$n*2?;d57Mytfx*U;8WUf4^uZJTX(kSU1(3@_n0|ypsq?vEG9b zS4~J$u1O<{+S!7O)a12ihyb4Qye$9&fv?BP#yQS(w?_a_GvRM@jI3iaK7=OUKA>T# z?{a{Q7rRp0ABg8%?c`;ETE9*LMXhT zPmev{+?5M+&)w5}ll`45IN9^1KBnaW5tiNVk*@oji=^t>CmR))LT%|r9on_DQ&t!P z2J+{fu5_GgXa6dw#o_I}2TqrLmAIZqBDP?yx*1cnMDN`Bi3b{*=naraQx%4kG(DiK zxSsiq)~L~Ir3_RB2d;9cS3aWVBD$+avxzfJ27=60*I_^Hv}6I?#`$cQ?tw^$KUYkY zgek#f%)#i!{uQeg@&)6=PVhCqUGw~%22ASdbUVisnu%huL|it5Cgf@xxYBYYwOx~C zp6J((RS{fd2RQ4Fy3(5?oR~X7E67wYmx&NS7af>~@fkW)9BYQ$IyqHGCDw06Szoz5 z-0waY_qyZ7Ao(=qiQ(zg80#Eh5R0nPvlqG(6`xkvrjzvYNHAQNx;+X^9DO^81~Z`N zJSJ#|uivBp9+f3FX_u-=1&#Q7>MLN25?;T3kkaRKQnsP(%7-VSya*7iF!#p$v#;1M zyfa&5@%8*LQrjo+oKta0xI)O2mwsiiZ70=~L~?ICw}NBB1H2xrHLe#9`2uAVu;{?x zz7@bF$z2)qjLuGP(9gbp!h)3SNjC=wy^SA82ShtfcV3*|MGVam^vgTEb_vo8@%i0e zx2enmfWBo4w2V5#F{NN|w9~l?(@FP-+%6S>jkn?{F8`Y*lly!;K@}<+TNNbK1HsWU z%D_43Z7Lm+jsp7jq+Ja?4LKI%Vl!guh)%{Q?Tt6ZuE!Yo%H|f@j$#-|`~?R*a$TZ@ zj?xJ=A@)q86IZwidwIJpe6IK%61H2wxzF0+I$wUUk3sww5JLqaJGC*e!O4?rTZ)m= zvpBOnzCMW6NQQrRUNt9VjszTxaEAgiPHTfMd3lh{ExtV0F@BM(^$S z0iW9yJa!?^xjja$6*d8H?CO0ayJv76o2}UM5*>YUhnxEm*Vi&!SrVH+{?!pR%Ga0g z7DtI?mYGaE;ZkuayV{*F=&k$)zox>lTz@5N7gxunH*n;d%EQap#0ub#`;PU1GEuM4 z)<~bG1oZOAWg6=;I zf4v3Ix!~OAgfBWmi0J9dz!fL8$X|T$Gj z{l|eANpG(O112s%0>~WDZ@fzzi|bCb_(yQ*^k><1KyP3yokm*)DxW9FkX1!yeEvo0 zv2;Z#TtAY-w?qVY*??!I9j(H0g;FI$>SE<{pJGr*vYU^N_;SrnLT^O)z0UpH5poaP z#Ezd3=a!bq*N!fAWX*c;S^BN=&%q#a0blm}P~6h2z_mloBLVUo%fOIiM^7uCZp6<46C%E7T83q@sw;EJxVI-Q zsQmh`iPykzjjxjaqIkFC*REtJ3y(y++SEMg*2wy@@g;wQXZ+8>xcX&%=Wa9hsAuSj zgNVTu+TojF(h@x0On*H3?$-c;pw~~MZYMxJZSChP?cTV|V6IVzSO!r?SJ_&g?fFT$(nmI+(ac;9an{zZC0`)P zRR1s71ZXvi7ndh5)3)s8B^4Xs*35o^pYfYEN;tnJlZDnm_ij$ zEQR@2JpzUr48$; zAO@N$ja-k!&Sk(zgSbeR>u=wSeHt;#CU2umyc_SenNAN~HMyh`lwLq%q)VRI-RB4N z6W>#Z7#L-<>OZ(<`GlQWPb#e=eD-pf5AP`A!W0v}Cy68A@^yez-bss;Y>sAUXQpgy z6E1EYm=nLP#o1^G&7xNi3DQN37o#`klD{49wq>51eK*cqusD6A*4`?@73>@p``7G7 z-#>i&^c?TF`|J~~M5%)xE?${?B5)I_=D;QJhgO=WW*ebhlf%Nc7*zQ)0u~&X`~+lN zD+_k5gT6p<7r(lG`|aAz%3Y{rCpIUx66XqqEIj&TZzRhcsnKty)Qk$55N5Eeq6pGF zv@7A3wnEn^H2fFMU33ijF9hovcnXxgzV5&XXq6sv9ZrSU?P8e|O!h9{et^7|N7Rrs z-(C^Y`3q%#A1!yHX~cxF5@*=d~mA)9^=cO>5VBxba&}EB{_I|P`0MWKlX(M;!AWybENfq!~76iFg z#~z)#2>dS^{%hRJS)9dwrE@D~q1XF>FsL!RbpJ)U$!WvH?v>rTV9fmjAucJuYJ3{t za2pJmX3_}CD>3Jn#oJt@2d;iAc_m)s@j3Ybw2MuVeR<^k0q7qKgAtCnEQ96=Whz2( zGDcDjr0!LXg{7hyOKa$63XMa_zwzM-lO^(%WY63qk&D%+{dF|{Esr^H@NvOo4tKTS zJZ!@Mx0+mQVDeqQt#)wB_TV1~tMNrbEUy=wz4t>!rPmh38ix+ow*8Ul{{HcT)9_+4 zAK+;JX>udTM1n0b;$|12B2XW(q&0*E*SO?2oDhHir_VqKv8fhIXXC#7@d+;|PQsA1 zhD6$Y?h)-9v!J8klGV~U^!xYz`lN&=VoRR80yc+Pf}{?7{rKzrhF&Dv&aXcye`r54 z@UesS0(j!ZNO-zUv#{XsfE^a#NdHK~2#5l%-8wpiHA=jz|LZSmFAz!fQyt1Gi9neGzkBEu7Cf*i$UM-dVhd5bnF+P*rXM-)}KBH zvk`BDkUuyxjp*NBk+4qwLJVvF^R{!3l^~bFOYfs0{#TiQFWo%F5ATZ`w`@uG{Yqc` zvlrY~Ew{ji@OD}s$jdF@(JaNOe?K+>(U;(lfMZ#LpNm}ZGoO%s-|4545BV(ia?-)y zzXHB&&a;mIVOn;+GkWh}(Up?|o1F8%uh{R;XSxpCv(}Gm|BC)Z`2qmi116q##(?Lk zfkeSOQ|bS#dQ2*PI|9dmP;0eD?Cx=QM49ZR)dAocnS|j$M>)o~hC1t$h!4@GRg|7p#}}Z$@+& z6|%SCnRpk=0eLC_@J1I<-~aMyr%<3oxpC=4{kh-Z5Sp2S$={vX_wLR8k8b?zBh2Ww z1W)z%SLMaB0r~p#)$e;8IQjn*0&b~AM8&4~4*L0Dz9)jkYDdBqKcw8)zj60(w`HjD z(rSYKC|Ekrp%AV-RA0emF33FT3vusVVZ_G%UG@6|(d9^$NJjJI_g90TQ*}fEBjGM& zdDo_oz-VV1AQOlDaWwwiGqqs7vAn&I#J~SnJo5jwabW=a`!)0bkBz$rfpDquF$1zl zi%JPFU-ZTs&Gd+PXzGu;>x=x_7U%_*cODyy5kpv@u~-3~avm3K0#WpT{BE6(;1fTb z@vuHZNE|^&gmkU7GIjY!?!y46h#Z{!uQ$hW3WadWtCj$LmE|df*)$!X+N>2J-M=3D zSKs$MY^3tL+vD)5Xr}W-S0DWK9uVP9pxE99c4?tjx;ks77vHaK=KJj0Ex;OJ^3Mf5 zK<0l|TC}}30_WI=|HrxMw1=!m?|UeP{7J%{&rX=c!pmBS|4QVA;xFDs01f339yrtq z`Jw(cO~c<$$uxjs!CB;LMQFWN{S-6?eTOG+Qju)ze_WPY0^gQXC;gaV3tWDynf^>G z8`F30M#eY_9I-%2dS0)9`(qkROt_J%cuIQ}h%#VYZD9pOBANABg4EmIcHkkQ3sKDq zCQ^Ly%H;k#0<@gH0OQAC))&Tj7!3RLz=$o=exx4hZvDAe{(Y!uW}m}u_k=FVld!$( zbMEN^F3U)z1N_4tHl>%wpcHqE2iqLBFf5=bR4eA9VD+H~tU-F)kA!kooE-hAmjYJ0 zr8KpZzcw@U*8TxD3Zh)IIN0_zoBmt})k4@8WKq1yQ3OPY>BI`?unOP-h_VZS*0c)M zxDHsel8VX5O?1NSPc-ok*qNUgh|r4U(*FKkbgoqDRLqrs&Rypw3P#i7)Wv|+ zmkt)yPE#ror}o_qKUsWX5Qtuz2}A+My}uycUF+CksHVy zEJOeb+6`@hFH`uWrfN1ud?BMkO{!K zaGH7;+@~qJcr*f9(^NiytxI=y#jZI3DIdtR2C@u9HD2g;fx&j4M^^FV8^yj$jdm~+ z#sZ>a+Bcx7d|)@eDQpWF_i& zC34zazCaAghsrp*yhLs9B;{-aMD|bv6!=tG0*sXl7uz-E44EgVI{@|mzhY$)^1AtA zi^xy~57E%5oCZiZh;A6jd$|Dql@ue+Q7jVRJ$Syk0IGmhur?_XdsE+&5Yg1%n_jNxNFAdn|Oz5qL&~d4M;85qy}G zEgw#%iOgk{ww z&m({rAZgVwJBq4Hsn{rW;~y>n(I!Fx0J;B@j5Km0FCxeq)(nf6AXY)Pq?SlP)TM$R z!uAdWK7bQ#sc)|9G5OAC6?Oz2^xKP~NIAwY`7 zRcQ0EwZCnI9b*amGGDIu`Pv5wqhQLgm8a_n3Nozl7Y6uog)vJkD(9A|#g?0{T3h34 zHei&A4FvH#P^fgUso*RT)9r5%R1sVbuP~*i%!93>c@T631Uxff%4Yu=D%kG=w>}a~ zH6{9$MAq^W>RWh%s(%I{$sq=#tGy15VrfeN_KGxn_LpL_GOI!nSIVPe^XPCUNeIjC zu;;D72G{!P72JUqrYU06&oa=EBDKN*fib2Gn>+XiCo_-GP)Vys-V^ zPKe#@4TKH}9?9}aaneRXEeO|5e0%=$DzrL#>e%BgA?PXO1&OE$IRyAcP3#6TxV`p- z+Dc97Yy+RoH|?QPd!b`cEdkdi-qamhp*=`52WhdIeaCT%<+H25@c{4@^E?hZx2gIV zT%TjBk~1uodsNUJ%@DVsF-RShUGo^RKf?r|YYb46eo}muH5TUraJtv-hRImEchi-_ zMX}4kU9?CtSeIsAgPg&Y<`Blo{Ov=6UE3LGs8lS8;T@V%4{@&%Bc7m2-R_dfHxjn1 zH_NM{{V%0xKcuWq-Zb@->jcNU3>`Hkq@2r%Kr&B73cVr4AuPnYp*Ng?f8Kik2Bb%! z1VnBWm7_PvJ1L3k6Fp(pk&w+e#aS7a2kJsMu`URyq~n8)p|)3#)d$wevT&<{uIjkR zb6WKz-{Jfg_1QO^$2j3+`wVXvEc&HcP}YbyuDZ__u`}V^@0j*N)2jswhNd7e>*P&9 z_>dNpAzttG4%Tzcj;J2vdtBHgb70{aXIh@rfNVg$R_!)B&b1OcinHD35(tlRY3S+6 z4&VkJrn!$1Zo5kwvo{#XD3e3E7tB*!3!J1$san}5vO24j2(Ltuu`JMS4l)!Iw^Xli z)zoh^>A=!Bqrg#t#iTB<6i$^e8DW}PhNRGA{3li*>u#p{T{c$#&t;?UHf1LOLyC<1 zQmBMmNX}6G1Vi3wj{5m!nx=_$wj8(>9ce1@Rk5o;yYyGhkRthn^O@y;HXmgOiC!43 z?0ruR8=)N-69nBOeU7VV@ZPr5z}RDBw#2_{tkkK*RlZd?zBUav-{a$rWp3Cwg{FD2 z5a6j;P+l65n-dIZi5x2$h%v-0V6FHH;jI|pmLV{21P+VI5_5Q$wVdNn^nO!|vTJB| zPp&23m?*!Z9?T+PLK^mgHDFC!qk|DvUF z^!Jqs)CD4n`Ia{7*O%k=&R(F?it2sZfLyA3ci zVO>#sy$yi!MYXJ^1!yQK4~fi5GkonH_ZboJg>dH-d?LXSMMlG;Xz>_nnf4Fni8KMq z-1!C-VLk{ZM-St!0@*tgvXS>I|D~I-?`GBuBw!fV3lwz;Kvxsj9uTmkG(j#0Te~n! zU;qNQ_hY*sTz$92o>Dpu)Q+crt<2g)4J?5nII47Y zfl6HEV$Pa-{M#A0wZ`Wvg;9$v^U#R}Dr0K~Y!qxk3L(VX9aJ6#_jA{N_*1D3y{H}I z7yn`yNH(t8Lc(WIQuoGYdvEW?%@&<^UVs~!5-Vn@Rs&4?#?-pnU?1q06NrZEcLpv} z=Z&s19Zs5zdXW0d0$*b|!)BlyJL47v&$!WABnAv@oOXYW(T`B z9Gcy!Nn@T~VX8nOha3t=sbq0fPUuG{vJsf00F3);yMWKwh_DQFWdD3vAWoxi1%3mA zpu0ITe`n%$kXsAy5=2X&a-u(8Jtl69aL593R(e2DWAG3g5FM4a36xE%v^eLNPyn_M zaNijNLqw9ttiD&{w{?Z|pR$n>O$PLR!kqs1s-_D}qs85E2QT}g-=9?lrU@;-dBiXFhTTwA?MfZj4oq2z>H{xE zq?ghKH}L6G{o*+eF9S%^rao9?6;)e<^w(R>_dAlRzVbrYM(2_Vh$hHi@R_NLe7n>k z!+By7pKSxli!-f!UUQW~QRqMn2kTXk;AKK5;RY~XT4j6;y*9oim7m>x4>jJi1$^W3rp=?bp)g{rS5jVR0F>9KCVCn z*LDGTi1t9HitN{SpdFOS(!eGl5)4ErgQN+{j*l#F`bY&ScYPsTusTI?-AaaftbQKMeBQ0wUFccFJTGp+SFi^qy3V z4wB(=X}yU6+FZ3~0d(=Cse($tj=X@X0s%E3AC+$lP{FuOux>%R-FGhvI-Mo&ojZ*J zZ7;L4h0qCK;@t7A8Yx@tZU`D1RHhuDE*gRhid0)TaSdkR$(=h!qZlvI=QzL--juCL znS<~MIi()dk8mRFLK!EOh%%5To!C8Z2Dd>_V2fr|wAU0Yz6o?$9rURhe&#+d4ywj4 z^+8YZtaol+v=K~MvBo_L@flG<&-H+h&l%cD8^5Zh|F9JHh3h~5*OmiU0 zgrI-`CrW$amJbv$pP@ZtAqq7{Ce%M+3NR(zWm&LCK*%%UbcJ&bVEOE0EyRHE47%TmF}3(51-oDc}hGO1)kUv z51)TK=kjK5ou_2_Sz+d$n40Nm>AQ-(-L303cH%VG$mS(M0aSkz1~E<}Ot+yT|2D+$ z5$VPv#d44I&mDp5(ppESHEEAu+Th-qYT1DD$Ovc`vHVc^TJ<;SBE3ezMwn#%_1Y0t zX~Li>^E5u%o90B_^NC8pEnN`Hp7YQ*tpBIf{1=k=`|9vbVh3cR`SMr@IY%>!rFSBE zdwj9eeS4uM&UQF3NhD}Ida*+Tvj|&Bz>bW>Hu^$9#nG6>5(U>vCURMHe;*}>Mi*?9 z$v4!P5&-ecJZV^5k%UN@1u~Vl0bh);pBSK@{JlgsDP63Tb#t@A1Xr6T;^}x^tq|ZX z-wAmS?ILNH{P0^DTU?GC(3rJ`yi*}BsxYgx@nsJb&L&WOd;r9<*z`C?XbGTiAtOBF zCnKnU1OlELmN;A8<_>U1x+8rubWbKKo}PvRy>~^k4Q z6qLnJ{jJ3>N0;U}9rJ#O6>oqj+IH=@Ds6xy(xNHTD@?9$(+)da%5VM^h&_d?zSZ|a z?xx~Wyr)CxMRkGIs2{fISOL`>A+Osv4cfS>8~w{eDJE=J3`cHW`Wq;ruH)aUkRC8B z8~9&=nNU%b`W~6rY=&PnfJQnpXsKp688o6?LDv^6HEWR+6(udk>+fJW=5fPcT>QC< zIF(TltNMePKt?ZO8oMKevS_1RR+)2EF2!t#I=HVJ7d^ep!8e!YQQv?{WjbmW{5A{8 zCpM4z2Q1j?5(NZB-J%m9S)kNLW;8A80{UA(#wiIyc-ZS7d=6JIjS|e2_RN$WaQD<^ z>6}as9j#}a5hU3~ghv$|c3J%97?I6y6{kKL&c<=&6`yovYqYa^CwCXa;DQ~o2=Q9b z-^pV})6$Ct$M{u81E~%Fm44(1t{!%6zRpLgM%IT7Q(|=YF%Drg6}WWoxXsMq;7g(A zyI;zby%m;ct91ap1?Aj5yY`6xwK~#~hwDax@vqkVXd^1s7seHGe08rl@rxisoT?-o z2VqT>%{d9eB}ejhjfdcF5RiuqdU>Z>J_l087Qu@J^N1XA8h&&}Lhl=rrm}$x%JE{5;c5H0muurNvM!l10)|%?OT3oB} zW4USpJZD5zrsoMTW!hOvB)F&|?NR#AOV1CN37mPAqbR1Z)4wISZMr1Yo7<{ibtC4C zSgVX55KI3bU)LQ^_5S}O6=@(+*(5s|N#?1PWM%IoJDbd7Mk!LH%*@P?y|-jVGPC!V zz31Wg`rPmB-tPC;{r>TNe0y~7<($uWyBglQ*9qcF3{jHId zwFtb~9)|B!R7p?p;%gzBJifIf5sp3=2(&?WD+_1@b&(u8(&LUMsVOeW{q=n(8rQCi zC<`Al{U?%JSmh5hOPjX`he_=6u8W1EFOrC>ZS8|P==k`d)0=YmYgW{cybfuD6r<31 zSe?FjXk~{A-*=g$|8w}0(q&SUGDxTxG#F(*y;dk!_@D@@F8ESz_9lLOHJ<9y-6*4X;`6V%V4>W5WL04e+XQ4nQ8 zf-DE17#19jNrXlXlD29FEW>GJUz{Dz4r&wG+9U;f7dLZdt z3Z(nkv*Ur!hy0i9Vz|h!-$KQ%!4|H7EoAfN2266rF1@{q*?H_g3dB8&Z@!-`;gAy= zaJXMVj!|=DkPtwxjfm_Id41UBK$mv!*|b_dXL5Yr*Vv~~AxW}~9qc0M#9~^p*xcQW(dgU3+c(0|)qenlT4TXC%)qx_Zk7{S+w>paGtGu~e$B3+K? z5VOw7{V;vEq8R&HTTyNdDieRcKi(4nOn8z-OkSCc``jdXDI>hD2+B`2d2RPkuyZu1 zP|?EHM@vo_aA#E3BNj=q#zq;il_IX5m>#<>ttq^Hl+N@h3@m(@I@7pH2>CUFmhM#U z{jEtbMP9pqX>kKQu16cH$VrqwkGM~~_azg>B~h5b?17fPgy@GHy~(mh9;11_gwZP< zKI``_Wm#)wYtJvJVBoPV{ZT2m-DR*+e#*V8v>0`aXZ2=P9VR-p?CB(|b+3WbMIUH@ zQezt#H}-ED!lHWdCTt@mH@%MgT(YLXAvwA4Fgg?(LvPN@JcDT=Gk<_^m96A!4wCK_ z|B8Uo768dOwXv$Vp>_{NUm%o$sPp5`Lo=4J0ghcJp|fu<#52DxB>k4fVOa-9RN^$5 zwjIP(TKDyc$R!!F z)y5E(ueC|?!3t%jm-T&$nv8pkpv;rm3%u(FP2!P-d94V*JwR=fgbDfPs{)dd9VsY^k{;_)s}w0f$9~RHg1Dal+4!Ls3h$w8=-F>uuZZJH!jnmbqj?G)~QYq zPQw7Dhtl6Loblo~{rtt|kFq$S&57^SQ!5Q3^(mD^xCRKE!OHbvMBj$MGhJK2>*M03| zF*(|>HH(1LuKBPQ=E2o+G22K4Ig@!A@__*ss3Pi_`6`CS5>4s}1Z#aJD-dPdCSeb` zwnxNXf&{DAiyR%=kq?Zt$I=fHeo{Xzy}S6!Qkr8=P1A0zz8wy17{{mW>)I04b*>P(Xb5GnA7q=qCHvUB8`C6;Mp98g29 z>^yj-R~Diia@&OJ&vZx2YUvD+okCX_kra^?=>Z2eNggucmClS4W&FgKUh0FEBadI# zrHr_p*#bqHri{#*l@HrbuL+y`Fky6@8^xPMA;J6_Lj?I?c(~9WW7Jg8qe|0e;$O)+ zFKJqfF{AC335h1f?xpiTeL^0(H$a-BDs<;;z)8IEEXs{jvR64VInuB$!S$kg5=jf$ zDb4FI#-w!T!FVtrUgXkF*22h(dEbM*nf}z=^HvTjI}>$WUP z<)NOBY(f7cUqWpp=;ob>Tl;~>Tk?XZ%U0g@?t+o2`!H8I&^s!sI{GMzQ`rR~t_+#n zQ=1{Lu?Sp$o%!D5o4MjX>MOZ{Rev!RoYvSLb8|I! zhKWX2MavBPIwu~-Ns|@8yujKF3thu!PI*$!L&BZK!4$KY5i1S~apspL+NhAn9IMU; zjf4Z7F{W|8+NiEg^w4Z+Y4c~c4{AAy5-+QA8#)m(p{u> zI>?nHkc@uJhu$7ya+k$Y1vyd=ei*j={11Ze#k)%2;i$tFWc-MK=}G_Q<>POosB3me zpOH;=AD?3LKv%ut!(onanrTarrh5erhiI`=4=lAtUXPUaPrF+!kx+tr}2s9l-bUEf@d-h>%;Ex;j}k7k9K<!qZ*< z+C|tygVnq+^?8o=zCPYX5oh$Imz{za{~`!P?mP==ajhm6H(OR+K`E(jONCeSx?aH- zBfii249>4RcSOBSWYtV?NovXFKQ*?dJv@!xvh$hgB_;jloc`)suQ$W{e$cO)j`_mt zbc4b)P@OKwcn;>vV|)}W0?%Td#k`~gGZ(L!e_)m(Ogi(W*)X9hLgn&HVaUP?F}!Gz z{uAN-C)oLq>3N(PXS8l|`iWleAK&nG2_8bmfes$NRSQEPc|okmmULB-6fvW|9J+dh z+si4Wa^A}_`l@O0Z1@jR0PNjSLLtXWVx7c%rgRoue42mpvcI$xfBX@(jL1~>qFC7e)TspWG;AE5}K zBp`W<_$xr+NHTHnAZCq>q@|r;2n}`YDQfX#EH4@SuC>dD>(c0AOy_l0r`%3=S(_(1 zNU%tcegxjJ6aK?OlYbw7DVb3Co0RU4rGAzkoE&)ij#d@28HfSsDjjRr-QGXOxM(?X z6HbPKGJ2+$3t;s(_Ojf3?%s81Mc@F8BP4oWvaxt;R(>m1(Hv#U{1|sf=T}K5agS?9 z)1<0q#d?+XthS4)^s-Vtu3D@^8268`P3XTy9a=X0hc;J;-)4`>T_O0%?>-6y{=!d$ zKk+B!TX{gdR8@ElmW;|VbLz-mlqG#8b1@xW2+lRBQ5 z$DJU5h*ggp(o@%&uK?I7_lPxSb#uD)GsMYALcWK|Gow)9&n$axtjn5o`*2y`37;{% z^y>@YP1gdNn9vI^emP^?=-{&1GPeQ@gEZW)FL|WVy-B>Dr#r;X?!*?o4S0?jFp*iN zA$40IqC32fm@90zhHgWtk9%>(0P~&cg5j1v&;|J*eyRT8B)-{aDH^gUEO*W(Hev=Q zm5kMK?JV8fQmOr%os-W&!CO<#2EafLybx3SH`M^_{hQ_a^^dQapj#CpZvB&2Ba)5* zhr9$CbeFQMeQlnZ%-V@kVM5RQLFabZylv*p^l%Bje;#z~yC!k6pIre_Dw%#(-ewgI zTyzrSiqkDeo&GXYs~^B+Z|j+cix8>|X{MLHGL) zBJi*49}|jnMr}Ga~u0E<*{b;Y6Ylc#v08 z`m;b;fA(xW_9XW@JL6-BtNJXO%M!Q?eX9|$23e37P;8W9#PrD#*x6jr`42|=)OV36qHX)t8)&o+ z$fg#}fHNoz)BT^iK@tH#7jLE)ZzxP#4d{Wpc>_*cr6t zXl`?-Y0}Fm+jz9yVi)D-GXkU3#G@}s?IId|C(d1=ePjY|`$5dc4pYNU+xbhW1#SwRU!VKHlUEa6S=eA;K9E0y6;#z}@2W7@1{vCC^lKV;^4>nrsgs)sa|#|5w(W@e0ue6!vTLWP1VUp8 ztIcuMV6zS3Zn~cJ)vUW@quQ-_M9sdl?M7OEy?g(BBSGYO%t?sCK`L=OyON=!2%A2lQLa)lM zqer}WnoZ+w%6;QGvw7S(hV9*rl+3k;(-|jOe`(GTAj3oR68zT7qQa9vVCs7U!xt8# z%3W7^xJ+NfLHXyQfI3RR9Ph@@V*NE@ZuUVcjzIdmNB>%)Ab<_UiE}!P@h|zC z#~Yakt+BWHAbCmk1W@$Z0G-zU55aQa3E;ID$FAr6N2rLr_xE)P*tN@r5)dv=VHQYl zpNY>^zkbGF%fH6~v=aO7?EJr|y_uik0gYqWpg@CoN|AFzTuJVy_U!+GM1d&e6D++? zQqLC31P+31w+KjR1-qfxVniZyfzRwAa70;%H3#y=3U80Kp8so(@vdB~IG`qoMMOei zGyGp7AxJ{9{i4a2>c>EfgN6Az2i$WE*_p1!dlcL}Ov{yuh>=~)ptCO^XQq8#e! zI%*j4^KiI7imwP3R?t1d$!TqB^yy!o)yF6y9HEx6o^iz{MCS#4P#$dlYyoYEXdl4L zX~2npiz|Wn0eiqcd*HWPAbPH%%LF|uZO}UegWphxrOz;X1q3#-7c3x*P{N={Ic91F zwBG7N<*rBwmohjuHW4c`6%4W)5Eup#ZmEyV)xMJd*%P$?LC?&>e&oK7A?<`ZEC2do zYZ3DWrE%*iU<4i^hOIQvW7$I)z3z)n$2@uQw1umV@~v&OCRsqu76ftTA*!Tc zb~RmSYzm++A2K(*kMAPPCj1srjvxs-cdj*f%>%+pwXtu#GYYuwKtX00v#0;x>WW^POAAc3wJxZX~3}IWQ zm8W^Mh-<{=Hqd=zLa}9ctc#i$_s@DsSVcjE+?jV*3wXZqf5sS)*Oc+N{;{_Up(3w+ z6lxLOo#P?DH&o(Zy0b2{7I18*Rh-5gbdHi{p7%=%r$%0V`Ux0#tP#vX9!Ea(Y9$qU zh^lCZ${6GxKVObR9+VfCKwu)4Xf3ommy>2|ynmhl7!8ZU&)mKkZ-QYDbaf?eVEFL!k8AHki@@KE!L+i88mEV?w3sqH`3MOT zP!=-azg==dawd?V0K&0_4Br>{!x=CI7Eow!E-j2@Oi}(>9Xx1p64H!eG|PPb51+zc zANr5aPY1<^j<&}w`Th`R>C#QzcPoa7e9sJM{Cj~30?9B#NQ?)O2M=Z6Ky|tBW`Npw zJ1JOUszH1)Oz0~at0-rCPWv;Q3WLVgrDmUhI(`3niv9TvkUGF`yuS973C2G+4`l^p zGDrg<^tQU!BXeyCfAkQ+&&Q!WQhcBEG5DvMb|#s`%z&mu6ahZv7)%V)g+~yu{m*al zoA+D)CCo3i_s=e%8VKD0JM4jS6jUe&dVT5bd_vt2w3BfqA=RgRTGA)3&{L5!t3uB| zERf+VdAaCf>(i4b2}u7ce!o1J|Mkb1dJy)LpZ~#8(h9GFXo{rar)Oj`kxh>2gt$&_^|!${3}Xfv;xu*zz%U<} z-(wA9m*IRdKm>Wh0Mpg3ddGb(z&9 zhwB;qzxEb!asBmAUK4`+z-E|*rCcD z=<&vVP-&`yapdif*yE=}_pF#=$n%aB%O9SmI+KJ5F&ct7Op&7!Btxq3yW$dyYYd8; z>jM}DoO9}^omDp%239F;08F%qa+>PQ(6)r1#ba#=GsrwhjxZbkrZFc8VN%M4GX|;o z{mz zcdaiQn#aw^yQKg7X$2QA{(aO83miM>bzOw~~cQSj$5fBANf*$)j{P;3lf@wr_ z4|&I;-x>v6ED1UqauC&E4_}{{(eXmyn32y<=pe0$00s6nWGWZa?H&P)T+DUYtDMlM zlH{Th7)^j>NI>kw5~iu@c`1qldsAb!*s33_)p86gX4MBo@2;WL{qLLh&cyBilGK~lT{VULa>9%Gg9T3;6YMl-a5j(ezl}M7hpJA=D0i=x!qV0=XKKD2%o07oz*vAY zFAItFtOY$Ik`j+-kk_JwKr3lsp>7oTMb8!7vR8dpM!jSHdyC2bIy_n5eHIs6XZ&`=qU+h5OWFM|knQ`-sWkgKY zCAJvH=Q6#!1fymzY`PwKy6pL^J>(kd)PAxwn1i>)C!!us6$kzuX#x=wk7yhe7OG&F0rOF^RpvW(|T)JJI0Vn)*}@N)j>h@1}#taiR#`ZXuHHx>E@)(<`~< zkUOC1xYqsb{c$h$&5FY$@5p+Gc+4Mq7h6I(Gy^5g+Pk7SK9YJKEKn>~UB^ofK#5a) z{m6xPMX!#nyx8PBf^^*DCy~(1r{R~<*QEkY8_y(`9nT7g`FQfAQ+k6JrQ7p7KSW?@ z7eM>LY8SoZi6kgvVw}e?b%=4s`XaScVkY)QI*}2{B%?l?Y?;)eM>RImzL%xtHhM*O zJ}ma|!!hrn4wdj@dx=FK(#Wr(gmQ17=%%pwfH+-~wWJ2~UnWR!I?aie3fL^BdYNNR zo>1k+xlP`B>Fn(WZys#a_JJ)(D0;C+XG(-92c}HuRD1vdDIty=Ktl5{eJQ*dD=u zob2Iyi-{U~6M~A#CR48>bFW%72@|3q2Mia*)^HhQKc*=D^@Yd=-yTzibK+hz!T1bZ zJFvL=_*0{hW2nM7;>LRzv;7&Yh7qJ`B(_X9zBA(cox19P*MZjvR~DV*egrffWm z%D~CbN%o@Su5{Fx(`AS><|Ei8X|9?)y?Fp`07eMeeft~}2mw>y0#6Nto>y9t?J9~D zM@t9R4ys4yzNdq1Crz8q-Be~=ZgcAUy|~T3{bYCc#Hn|q9Mc_?O#PfHE|!|Qa2}MD zdXXKeEYYrRAtkfHMa(xdajz75^-0KfG%G^(hg9iW9mHduktv2o_HoFy5|Lj1_*aa8 zp!sXuPQXxqa9)K40u*PReGo(nV~FOcR&ktIc&SuWfsW;P=?-(CqpGSh^IWFm0*&}+dbQL+|3oAPs@8V6 zd23PCqsGqy4HO-sO90%>f!5X5Gi0TVZS9dxACmmF<+>XoX*0^Go2KFb-i}2#e(g>H&?tag0iTzX`url?YwZ z6|DD#F6J(EG^C=*i}~~8It?+tVS7_$no%~%N3vbP2{V$z%$YU8*#oREMaGqeb&J!G zl@e%pD_LT+JkHD7vi4s=M+7B_N0Pp^-EX~8S#neqQ+Olcp4ULvgW6f=& z?&+T>SWo}#TKak(?b;!STT*4ZI}cL+Z=sJlMl?sJU@u3M@xwJV zbZuD7^NAoD!*g~AIo|{tNiX&C_-OA`hn-_qEE&2ew7ZyKv<{s|k@ulq$M;4tdt*^v z!c|wJM0+21$%y-`y1h**ExZ#})yj6#V`w~&!e}I75#|vIO$C*7qQyZW)9)z;&@tTW zK?jXU(;#tWQLYc~bK}QT1Tje6THFS?vdIp1J$%sU_HmyEi3Lj))u|nt!|reU zdk6ypq3imWJxlaT@GEZF7~d4OuiO}}Ndo}0@0r9#wD;(fJjGsWZUOgI{ zGe;-STB!5P43( z+hy}&H6oHr@7b$!T=cEzs4dKG`uk&kNNtp#qf=^?7&;}@}viqA=2RNTAp!EKY82@LT%n3ys^P24XuRf z715Ay0F-g0w&hL|G~9R%h5x@C{5qsnp1=`q9P-TEOuaT>g>RA(q347*-r5h!JJc8$ z?F6hMXM7PQRkiiRitEN}z$g%j)@>I!OwlBQ9E4>HM``{Xc zmEZ5SA5dv#Yal(Pj`+}p#{|cm4}f1Kf}eDmjjO>(a#R=8yQW!rrz(~J68^Q+1vtNfY=|Y zO@*Nb#!W)bh~kRKsxb1rFSD*+L%HmiYskY_;vtuABofT{_>(mxZ z2v})p%-EROw}|T=teE`SvWD4J01NPTYB0^mE?DDuxDd4ry|miFowxz(Sbj-8_~n!T z{Ns{4JYom_x0R#5tn#s*Sc7_+^QgRtm&NPKW_Z;oIq$`y9f`HCmIu)7yb~I7fEn>X zu^+>)jgf!ia<*Qt-%{@S7wr1T>W2-T8<+c;-gY5oNG-^TO_XK?>^BR7o;uX?&5UJ5 zvAGiUr;`L9<;W?xN6eN> zmjoR++)P1*YN9Nkoq@hKCFWO8RejU|ie06Y33v#G02T5_6#zjl^hX~T(@UoOA4i(U zS0d)fFr9M=R|squ`g_3fNl{pXP)J>x>Wx!OC5%edijaV&+Ao=k~xJ|YjcQdvQgRyKCyA_Ef+bejl!UmSw z?+`v#i+SDX+fVae2fzxCC=+rck}f#1r8mDq=X@Q;t}-gymKz%|i6aI`t@3FocZfJJ zpqrHLlPmB$*0+jRmIQObr4Tru{1hce5(?3l#_fIw!rwR5jY+_+7!le4FAz0b3fr3+ z2&~Z3FkfgJVj`%DV(BVwW1ZeK1&MRM@J9FN)O!LZt1S>@d}d;20sJ}q)>IC$iUcD~ zhk%&1r!XDenciH4_VsRxve;{IJPXPRloHgL?!gRPG!zYY0(09#59V$L2A>ZB2j!!= zAQxAKqk#mwF8FaBc|Cl%7sckQuPscIn)+Ab2Tpeo#`r9{-==faW_9;8Ug%Jb;15>i;C7Xfg!c;-z z*G11xkZ~+mWJ*=F!z5{p*a^L-RRQ^hu_D_N+eYzJZyiu+r1y``-2{L*Mk` z`|9zfI~QIp1EO^7sgtE9LC3u$x&ZAV^YyOD$1ra8A?yOc{r1x91tYI-oyt0Vil27H z@@cKVMpD5YbNLp_QZNn-r*z#pylClt?V34$%aGfEM#c9R0;@3IgwwyB)-bv#R%1&C^_iA)qSY=?S4-!^sL(ZkX5+-T* zeCd-4ZU&wqCY>$F6HmAK;!er|ymS5H6?zEwKe6u21$i~?;yNAQ2Nzj5J=BS5t0)Xg zoque)fQ(TFe-T&(!n$+;ObU>I0>l!~>lIOg+iih*$C*{f3BYr7o}h{A%EBNtf&F=t z>j%9hr>)phY^?hUZ_C{{LRLfK*_}z@yvSjnaTPsFM%ZcE5#6eq&Ui^qZ&5hETd#xp z0z+ptiQcEdOtFvMY@U13miu9mJ@cge&&!%ew3>6Gg+b;0?&>1tsfKGq>H%DCP`Ap(DPHfD({zvfP<;L$!;UdyG$}KY&`XM{!}9L^kl8#sYOS8~2WH z#hC7$clCV!L((-9qNBy@XcuOROe$PFd?H%Z<3l+A_`^dv)KMp2p(g7qo~PkLS$=;& zzoc@V!$B#IPZ5bVRyzo=yT%xV-$5!V^;s~B@pMexc0igC7h`81M=*Yh7;Q@2y^pgR z>~O}iF60+uL4F#NcmB!)RQ??+HG^aG)g(vUw?5M}IQg0_tAAR3sCeS?1e4Oytd*TT zLG&f>nE+s*d)d8_O>#!FDRsR+z@23B!mbT~kolAcs%~y+i};1)l6x;*!9h~P+J|?6 z6(W#AQ)cTHGa7oxbnh+U`>7laV$cxAopj%B)Xrv~2ZFxfM}Hy8+Q++I%>U~`{=O?2 zC;e?yvFd2E+wvyJsjLNq^}NaTVyjOOEw@Qqv&+%AC*651e7Z#(Rk|XwDx&vdyRfdb z+G#B4{O)$vbljs0>yGD{_AM|#or8jMAh67qsG^Te()#7HGYcnIlWW?L<+2N66(Cjk zF_n-vguw_7{q}Oxwq(P4&PEYwo3)rHr&844@^$K&FFN%FT_f$W3RtHM%gIY5$}k(! z+F)?h4D--3P1(yIwB*{d1@tc-|4?3m*jfE7#dIZ2A>|@1jK#!qxBp|gEU{WcsptKj z@|q0Szxm9(6in?0hn#^HU~PLGhU;C$2SWVHopL%xfSi2wG~~iAAM7}>!7fM=Hdd2W8{LkNE=c$aO9Iq#8fabI7GUL_niJP0x6`#9^Bh49LsJ1k=#24C zyL*oMqjgfG#0P9ip+B_%_|4L++PdB`?)#gq(8EO-#7#}9T)z6IYicMfLX!FcIjUL7 z<;>rYEs^AjT6T0$wEBVDP2Zo7a*R4`!S0P`F{MAV4aeul3w;n15*P&#WXevyqL`H~ zWY4m2_rxx$t67`RB(dcuf6e!QU}vyl<-Cv@dj9+Y4>$C^U-N`r6%C&jOnE)SFV0u) z1RTDNbOO^?Pj4>ibEpZ7hh5o;%Q@|83EVMcv#$#jR}RT%N#phZ2vXH>gBsE^f^U+? z1Pp!i2W`VJgKU;)U-QxChh@e|zVj>dz&i?rR~4g|I4!5bE35HIpS0Di&K}WbbGO%v zT+!{cStD*dTTRGEe9n)&gr28ZIe9KsIlT0;o4@kWbiLx0;C;=yqO5)isRU}hd>MQaPdL9wa$yNvbsi^~RvN6tJ zNQ61-kebi16?IVlaq~o~jQowi>p>+c9kQ}Gp`n@7dd%X@pBJ|U2N!pm>M?&&u{TQs z1HL-@vi}rdgVrf0%Fp(7^!mk&z=RbbeT~92t=6f1;C;vOP{lzNJYL;*3#DSHNuV$4 z9hiQUoJ0Aa(!DpV&MB1Jfhnbm2&pf$U_oh}XU4$xn-zswH#keyX5i3c5k$1;LGxXG zfW~UbbKON0zG8tL0N;dX6R^l6+_p__4RT+;R)UCo@Te;w6~h2b)(B0 zW=KS+K@-DnZW_;RF~dcOod}AoXt_xkw66CYC62Fn)NxgWL7|udc<&XhHTx4Q z0PW%%M77Ol3Y5d^Z*m3$`4SINr(~%q`K#>f4d;1Qo@J#wXOSiuadwgym<}`p*oZch zcMvQcW6WzH*+kYhCBkCgBHjtu9OELgtgB+mSx~cbAq(xCW~6}8+WnVeP>kx^uPI%3 z%MCq&OFUfoBPF#B9G;EoXV06ZrWc#A#O2RDcoi8+vQcrcThR{ubC@)lGr;IwO+QjK zbNIL&G}!XEDJuYi?UZ2)Prr7dP9uAsqhjZKM)udw!QXZV7Tr`fs&15qX2QQxV0$mM zj`i@gbybEtcGeb}^}xh=^W?Yn-7iu10;kzJchf^g&Y815xfUQdr2hK)H|X}T+3UVJ zgb9JVY0CiP^9-eJQ+>*^YLb+C9)K3Q_Lg5i(|(@FOx>}1I9?xM zV7D!!{~3YQw=HH$82#&MwX8lJku*QpD5yvX^`cFb^?RU{CR>_Iw7|uKlB(0pfPU}P zOp++pxMw8JPkrtWexKnY^f%g8+ue(`?{H~B;y8g4vk~4>MdP$Gg7?F zL##Hves7QJJkHvdGh1^*x|zoIrje;aeBHLrTO;o&?CmQRJPnYnAiv>oNB?WxVgx7_ z3KoXimr4F0+eS6LepZsd-v;DwE@`0-xwf5TGCd9X@#4V)l;<02NIq57%RnEC&0(?i zty`JL*M+ReZ5HmO{iWxk@#hUg>24cZ8)##8@q<-l`l!y^1jzNtC+AJt;Ayhuyzq4u z%Pi$)K0nJ_WBX~I1$Kko>4j2lDlkw3{FtILq?4XPbv^6Pa^+2n~ z{b2NISY5#a2O=``wVZ*?23V;k-2H8j!VJWU6V4~hJ<7(D4$rwqlU%S2`KLrWEEyjk7emn4vpFtnW8u&BY*Y zaLFMz+#pyjn>_HvR5c+d!riAvJ6eBGRd@Q7+?`(5w@f+e^i(!8 zZX~gy79eJA!03e=5ZrOaQ)1w!Fs)Qh=b;FD9^gYcWtP*#r}jFl+o)__)&E*H5roGK z&n0-`zq!MwtG`}*E>`TyMcmKCLYC&z15RBmo#Z?%V~o$vIg2pvf;}hj2!_GtQ9_XN zJy@)$VsBDPNu*FF-XhunJ24dS>_RjwigdfK7U&)Ifbf@mc1h74A5)d!(5MPnPn_@r zpI5xr8P8bn$7<+?h~X7}V3FJJP?#&4kgL5~&c0D<`#Pk4&>v-$wgOs;1pM^6cU8pI z8SGqTHhX4bF{0d+dYY0Pd5Q)(W}+uXr^aE|6bqIA`fCO&nj4vpiCi1_Z))W6z(0)^ z*dBkYfY-G82pGzE)iL2tStP9|C%So0)#YHENmK$_7MB-uOXoD44|^{^64U=k1Hz#i zi=26Q<~eF?=awVrd3ZUObBLnV8PQeV!Avv~~ zsoUZLM@gE~2y5+G&gV5lPl9f2y7bqGtQ4zLZ)XLU_X$k6O1gFko~>Y@UoG8o7VNEc z+rv^sBb~GM@@{_TN6z&fW!b-LLS-Ps{k?(|mZ|gsmOs1b7(G0^7QtHU>`fAnWqhJq zrySyHzZmPR>Ya?d&d0A-VR2Oqd!gpG|LXQOL>Nm1e+pStaTCvE#C@N&U_y=Zf9!0n zwcKE%E81Jf#67WUXQEd&73x`n_NlCd*DuN-Lp<2RbYipO!1XMpANvCSmAWKV`dx1B z4!wITj-O)U?(K^*5}y-+HEZ&Cw?2!qk6pigMZlA4IhkF@8VII%&g)p|p_Lz>7@z0|m-|Y`N`rztKk;^a%?nSamES#E1MJ zy9zZkXO%mb)(6OX(bxsFQf-nzz)A2{&kK}B>HW-4M=1hpm3q<>uv^>y>+NhwUVb)J z!su@A5X~w^L)8yg32*JqRd>uUbBlMg;Rz_vqEX50L7bdQ)RyCJdtp8=R~)yQIUzex z!e4kpRV^5!Z(P?XvFx0>wM#F`RBj48oxnNSp&3`|I5<8C*71y-A#v!`(Y47+qi$mc z@s2&r`}?oRTTQTT$#&@izYIjh6_uc&8pK+*QIY)FbqdHqcX`H|NxTb|j6`o8TT?wI z$lXQ%m?&&CfR6lpHgUi2iGE;qMH>aaJt8XD}hxLT(R9<@O6i3_|RSRIMgJOgxSq6?cH??BMX4ZbMH z06Nd_aIa3x_^>PsG0X}X9tZP^Zqu^kATg1j)VzB8Tk?!E=lzzeZs4_MKoMkD5Wt-w zRy`djq$iRX;%}-XqoX;;me26vdjL+v*0wOLJ;;$-tAFV4{ED1bx1X3dMUzRmlf!@J zJ45E#O`;pQp~iICvtv`Ss-p(}_-^8~BKN*NBH|SI2y{YE8F^o=eJL-=r!D+v;xQu8 zXGJ}ibR2*)Q;w4F^Bs^Vw0&e(lmQEtjV1Febgxjc+A;&j*D`Gs8;EH?IU{M9E8aRlM_-@f#)l$oR*B|hnn?%k>S0>v(@6elWm+u|u|k5W7) zPnCZ70_QNVjn5&6(x;@HGvkc7liP(1-jtlDYTht#HQp|hXS*-*`2-KI!6D%Vx+rP= zp*kjXp*pljIpoJoqy=d>32PS1R8wx#{r>w&oC!5)lX2jK5>)JmlCse}5e3CYJ?&^S z+v4TyFTS%hQ$5o`^K)k&@_B@^FmR{)G8(e`uzU_LQ!M{Lf-~Xbw2B{9=lWeeKi*M0 zE8>>H%**oB1v8@Do5qtz<`$6II=acl^(C_jfJ)qhpeK_xR9G z{Py+mLmrneB3*RgD|=l-7Vkq!T!(o(wUqH~k9gcB*UB{ug^tNJ|07Dx;O&B#A%@*U zj(t0Kewm6hyW==3d7nGvh_Ngbsj~8{_|{#>DuYP!LG#pg(5`A*GZW!FW=gO%k%Zht#D4_u&_gLx8 zuOb1UuE1RxtgqWc5Xmc2g(C9C7i{UFy}B1TFN+NerEddjeYRvebH1>S8FYI3??CRL zF@Mc6`r00d7FVSI1xvXS0B`ykf~nkELLsPZGjL#Drl^P6UyBp>E()pQ5 zL2X*@D7Hq30nt`dvT-lpo@~rcfK{j=RQ_}0js)Wn!*iD_5~FeNW2zSW@@Rc^a6>s@ z^WPWJS(B{&PqF4SX#C(^a0X<+V3UTEyn4|iIMLAm;}U*UGc?gN;8T>81t)t`qvD_* zUSA)NUL_C^*=}PIpx|Q4<70HTKL28CcL~C3KVH8a^e;Ej-XqG~GKJBjmT+%^(_O+H zmT}}HKL@;KFa@WEv;s8RR_eB`x7)cJ+20+ zu0o}KGkWGz11P+%G(oU{+G{MxoFtcdf-)kh)lxtq=PUqHtlmH>feF@&Eq@|Mvpe7FY!m<3%bw;<*mBf{)JB!0`cl8E&3$JcyrNxz;a1YM`p(*Q zfZgK}P1wisyh!{~@+W1jB8f8oqEF_}E9`~2K&zPT{89wcM|@N4nlvaRUkan?nadCH zK-_2o1nONPtQEiGtjXlrL#*jPL>>U^jL7L%g$&a^Y-USOa1#^XN1otzMA6)vnLSqX zaz(YzwUMJh3ZOxU3p|EW-?zC+P$E~|ODUIIZk<-jlluh+`E?eYCnrK#R)q0fU?%E$ zYZPI9CzZjQy=F^{NbFFVQaVfe4gEK@7g~s|UOebV;uv%}M({t@G)v=U(OaGURDb)d z+C@Uu^xU?4YFF5Pkm5!%X7-w-8ichF3z@Sp>@bOLOT3W9lc@mQmA&zLc95RdQfc)G z!e!jMc*&+m9<1624F!zs$I)P!34_I33RUT8DQ_UopDPF!s)pKzR7Q3_mOiwu4`Umg z(C^mCafWn#MD-vG_124oYxEBXI-PHBv2!;vdiCM}v5RpR87D4m6qNiiT`yk!b z?NmNwM)AT9wKaHQ5;DqnST&x}r;}BL(|;DO<$*a;CS19^lm9#M-@x79M_G&@;og*X zZ^^1wae)PcRTTkK{1!8wz|99hvq>+@;q&^U@G>;Q^GoExW`VoPp-Mo4lExC%o=wLeRr9(G+_VMshi&`{Vox!M~sxptiQkd$8q^E2gUxG zs3-Thhas_d2rj*|kS8`v@z$L9eF5(IzPDvV=b`nH5UX|7pA)aed=*%N`zf_XND|3a zo8B^&sq?wG>dLEtUmr&*)+;|eh-W5+9cEfYm=bcfE2u*zx9$7mZAUcW7|N9#ZVhuz zuuNQNO}7z9U0!qDO>m{g6z3FoSso*-M=d_MKk(-*(UPPcWcb= z{*{Vvr?}H^{@20(|Bl{w8bBl1h|GmZ8)u?D-!$^!wu$ z9yHVxft0BJ-3yPVB3V59<#racC7pJ?8QPAKYiq8?DoBgEsyl8i@ebT1G^jJe_B6Li znWl%K526odUT<6#l#_tY(VZ}~YQP`&_stISol!{yU)O!L13jmNsOn2z@8m|sy zFZS5?XORjupI+tk9CMq2_+h6TdVGKVJ{q2vo+WC#eGA zCdD&txi(EoN;G77z2aEg)ut}Gc~kpX1dTm7ON82t`};lm`<7Iaa#%qSM-r_1mI{^y z+eG3+(`&MiD+5`UnsS9hHWU2Sh06NlO0Aj?ZvxwE?FY4c8-1 zKJp~oAgM37i+ev*de&y!zwyY{UeTHBUhDjHEQw&O_PhRhoB6!tpVe8;Vjg2{={W0<|a>-YV{O(35lvdtjOAAZ~+96bf{XD}U8)T00}tbP*QIz8nj!tg zb+^~l?);^fG|}iD`@Rkb?0ODt;@g=LZ4ZGh>pJtZ_T$JaD1Q%k+U>+|?i~^BeWFl+ z0Nbe?`U7@0<~2T;4;e}kRKVJ<#Cp{s$e-zRSRw7)foM-z*i3hSCVdn99=0H*4%sj# zqHPhzt94(#eZgkH&b%Uw#_ewODVjmdeBWSBFkD9++)h+<6?I`B<8SVJOgRb+6m2vI zTXho0qsX0yAYr@>%Ek+&zf06RRk)HqG=A@YSBkG-j+}ycx!i7DU%TnsATzG!g*|!p z52FSCdW)wip-cQ`{hjT1w?a!Q24qGv-VA=zOLBFJOXAcR{pXvhw|>5&9)56qE;=d* z|L)OmIdbILDXLx_g#wkqeS||Wd}o~4VDdLoE`6yb=S!^~|8Jkn(2uyFtCRuE9n%ZR zp91s62;E=^90wQ3V1n_*u14<>7mfgUb4Ca-qefDA#@E?Rw1M#p1 zg6<^HdtB0(74Cek4e)mxc*DYhH(AO{a-OMPA5%~p6^Z5id0w=HL0yhaPPP1b&wpO^ zKaQ;qqI19mt3Q12)rRa`;5j7hwzstg3iSkzf`0BYz?zhV#fFh~PX;tGjh=Iercf#T z!w0f{G)x)_ng?)GzNTwqMxpDuucnkwbAAfJhE=6yd)EN@PwVv`WR-d|7l&wuboS$80XcYvb}qH#kF6zc+~f*85e z;L2cmf!eU03^PiEB&xz}2`6|0a%i3OpNMA)b2s+MuN>Nxc#sDNb>W$nD}Z`|AkkY9>DhY~!8Tr*&@kc5ZTP_pS>9VBK|uR#N% zzl#(p^#>kD?$y1ZKze?@2^YMMIMTz@#E$;5=$*~QXiLK(c*$&1*5z-gG5j1aJ!D9> zn%#Bm+K$*t{(Ut4+P$nFQAT4Xc;|E5gRgqe3;?;b!R|MW zwFoa@>$+<>Q;jfcwvM2DN|;xt00W-v3uoUIFbj2<#QOdDgIjFj`IFwfd&2wI-}L9( z*7X#@R=cm&m$M}D~wE?(^R+jPQroRx=f7j=jXDB#=Q%o2fsiW@% z;kVQoLAZMl(Knd3a^b!thCVAt_dIxVvJK(2)EkvE9Lk;kyt|d-XJ31W6xC??|K{5O zkZ_;2QxjR)D9JzrLyS67USM)Y=htGAZ`|u4U4!{nuh%f#{KfabP5@~(+Q);r{J1Sbm|=<(+F+Q0~*87FAD*6vI4;EwLvXX|1NXn=QZqs$`_6$>~Ws>sRbZ7PxFuJ z@w3T%Cq|oS?a#gn`xnv|ypf>RHy$FZYj68RJWUKvPt99da{>Q5wMqdVy}ARAwbr-|3NcqWmpq!XcR^F>(%F^~5l z65q~5@_`%R`chD(9cSLS?rw0H7vwI(btQiz{s9x2|X#WjnNW}k2C0`MP;Ir%mE zC2jVs;NqY2(8EAb^Tds7h5Y7y^|;Km1PGqutL^B6J)>~$>{OXOhue4`*}BN0yV>Wy zD{G|9al^UpmO?)44g!L4{|U=TO_ z4oJLdFPwdB;rhE!(wx<>P$t7HpqOS0{Pm`OVWfR5QWUTC{I{Qr10GS%cu*I{{Gdj| zd%Bhrjb)cMn_L6UXsTyFf^+OZY;H>Wcl8?h|0q~+EoXultP;V-Pv;6EsDxrf+kN|i zFn1MvgZRe7f^x(ctPIJ^}8^6ZXoiq9cYkpQsDI9 zL13cok?ciKxMrD&+9L_mwjdNXm`y|2^*_oFtgf|pg3~vpH|4JrF&@?IHz%e2``7U@ zE+Aj%vse5Vk+ufu;Os2tf&P(Q4ub=^Oxx;>}Pb`eNb72U6FX}R({uyz-1LV}F|d?W$u!hpLW$(|)vJ{$h$4Q&~L zbB{_U<*#1**UDM^1f_4@)tH&?;0|Bmu_GYM8Yg4Kmx>cs;Jr))E|}3YyXrVwF3V%; zR}2pZU=4#U_$mXr`+#E7o^?UG-U{rzWzI}r92UAYEt_-8Z7BWBDNz3*Zq;Voxz;)u zHiD@E?wxyE;JcWd_>R@tXBf^6Nn%>dG@uKw8UvrrCcTX|qdC9+f9+lQKb2|!FB#*R zr5IY6&@d&tNQ=E0QP~=@h7^Z{NT_V3d1^+s$CF)_89B0+gEICSTNHA}X^@zT99!AT z`h8zGjb_aA{RiqNuN?Qe@9Vy<&+>l1Kc5dgtuYDHn^5Oyp=`V4Ayl?huqiFD3(-1k z1iqxBo1{WacDEc}@jeG=@HhNvB6Y&p2r;(q0qO3ZtI%pAFpS&SA%!<6(9La_uLj@1 z#HbZL)YaZ+n?Nb@0oY-;UZB85*&~Q0uOoEcssa+42_sT7ISBys8YOkj2H7M_Ux#Z= zH$K+99yjqM#bImroR>xH%eGUx@`9_rQcs%tR9W%#&C!Ry&6zQ-hn-RO?eKF*)Jiz{ zg3F>vfK9Hk%|C_32)}PT3$K*p+&q2u8&lwv(6+tEHE+iIZpkmJF((c(x8eGDmk-PN zSA3$QkRz(NyzgJK;oU`Hrw2#3w|~0yrT@7~?_7&c9_Sej`tJ8Iq$L+(eX#H1qQ^)$?76|Qpe`a3W_x?lv?W@~~ms3*FonYC?zg~#-7d%q1Q;*#BzW%3g zT=<~>Ac;KU6R6(HQ)2Jd!9M^XN#b!uQI@}DebHZ@TKx?C`YSzsdI{^%{^5h=8YFq# z9?!F!KUwlrNlO2M-$_knTK&U?Sccdd11cLuW9tL{a!0J+vsSh-o)B4dy1UH(^Fi51 zumn81FEy5p0seeEI6t=Pmm+n*>r)3}FxUfHb*KUGlGtsF; zA1!K5_F}jIPjLM^q0Uw5#?wtjjjP_h;-x>Nf8;gZA5#@7bi_9)A~ssM7~q!!DmEOT z`_M(KeXnfE zf0D2g!o!7=YOOTY$C(>EZ+yi?&$)@fl}U{|nSLtI)5!KG!X`0M7O_ul@=<6l|K4`Y*f2J>Pt9T5 zcJ%`5g!f33?bWrvaLqCcs4L0k|C%%CPAX9eGeK3PD|P{v&_nW@nQrnY_hM~84u?_W z+vT=P-hS)Le0IkTi;g8@B)BB-$D5`R&T~xt^Xch^?_I-7@5IOTqDwa^YtyLP|Eq%c zH3=YZhjgvyDe=X;LH7d}v z$rr1SeB#rQe6HHgcK*{zTdhBt`1vv`Mt|?E#-e+xOz91NI-=$D-a~&L&getfd{@PL zSia!Bzfv^ngip)vJ%3eqM_RgL)-$wM(gPsk>V;`@bWE;lBFbs9ukx_}Qg?SpC+E{M zLPEdXDZMxGk%>>F>9K(AbRBu4{J4#4F|SO|3+)Bz5O>BCs1(d{b{@mrF$KY!_kU&P z8qUwkW1pXP0RK%g=lhdZP%}5NeJUw?-&gD7p^FuS!5&55CMto!poVvMKxb)PfJ)Zp zC=$zc^sKow+kPLLHjbn#qlkfRRS!Gm?Dc#YQhd2|(V}OQywoExK8$5#me|dnaW)LC zu=T>ms~wbQO9+&@ZE9wztwi+wO*j39_E<^><8WXBiZPJ>(#q^o=lgDK42CBlZZHIp2xBd((3VV#c(m)<4*7Za$ z(d@KtK=~AI*kZ)= z5CYI&NVvlU)U+@4n%e=Qm7}B9?$C)c*jL+zvALPDIg|8^JE!pa?0tDd%YdIbfYFsQ zj&QDaTQx+xw0IcZKVNBBa3=VrZTNEgcb`AB=!N~IBygXHp_`lA-lA-S4g@fU0np2R zZf3%MWj9fOT0+UmM8&W!f>n>!qdy4H)JO2wvBI)K&T6>7SWC?nJLImDP77=v)9C+GcT-KUBlLnTy-BhZX7i~dTA}~vq8?MTH|NE z4+QmL`oR9MNN zaBIx{Dm42ajDV_kBBC5EE|rT+2yksY<7zSQLLaw= zt~hO5ss`aMQN=hXgebRaa!exAKa$brUd3l`+tNkGEQnrn{iYB{x{2Th6u?}gmBYA( z!VF5`WsIBKL!4ei?jYm6e-pn{UgI}nRM*hHy`Fy2gXpGc)~MXOg*yFgec3*UdMqNj z1!dL}S*!z2q#k&5i}8TWaZaihmzvCwg|K(AG2bp%YcJ%5xoK~o#~4Qv1l-%|51y8O zV&Q8yG^Cb?I=pt&^%mmzV}p$Kyb>@<@z~__t^3-=ySV8UT3gCkdshI#ZT3iJQ22W` zaDLI%@2vgt!a3VBT030XMMRR{oGF{K^ehW25m?!Y+*0OnZn46@dnBlup-CQA*{IDd zpXvI9>DArSrM86nfulg1VM(-9&(i;Aw~yPw-N5+!9o4SPC!A8_Vi4f z&I&*)-0fj?%zW5%XNgrn(3nr`keBm`X8i}dxjSVdqg7|oR4%JX`mF82L{!yO8p{28 zcF#{%0qUOY=S2=H$q;!Ezw%kv(!(Q47+X)3zS*)XMe;{WKKAnvU7gqwDn<{a|6aYl zzcNbrL_DvILPg$q(C@(0;Hy`ZGef9Z{-;?r$loC zTlwxo>=#7ji%c+4{-o<38snI4dOTay2>m;gSR=X8<<>5X>|9aEWj zmM<)!M&-F_BAh%6Cn+J2FfRow(O&DZS7jMEbSjVsPLQh9Q$go8#V8vUQMx%%U%YH@bUYW?6Z(Ll^^+dl} z3|q^k5M&W8X7#hKpjz+XDH)C_5y#p8YD=f}rkZlMyyUhe1f@Zi_gzzXzmEiZm({(F#BiyT11I@?D4f3R9v)&6Vz` zREtRXp*l`dsSClv$)T=bG(FtvEoO}xOev)X!s5dMHRh9?j4>i-zD$g37_M&1hIVCL zl!=Xfaaz7z=B?WTIQnjmR~ z@6x)G-xIi*?e*0RXpDB1O!quWrUN=L9vL2zD^HvqP37eqC)vlt9pVc)sekrYvTtV{ zlO4})AbkFkIBH?j=x(_M4;D_HssF(fkCOubBGU1&)Mj#`R;(1$BkO59vIaf_lb^Yt zT@&p75#z`0p2Dk2XceuaSBr>nh-p$bX>`Toew3wW3olo|6}P<zWEsL?ipMsdd!%QX-)OQ>3Zm7#{^-S0*rYyUOiS$TD*nD` z?9^TUoVSc4amYkS7?{!vpGM7#ci~;tf6h|7BcIBdc+IRqDmW`Q#E8E#uM26HhrOkA z-vs2s2LNGtTuFPf212Y+^f9%g4_Ai|z!mCfZ9JvHFK4?ive|ND4VdA>PXm3^7Q zh;2m_=iyhN+kyQ^F)M=N5c)rgN4vBA?G`(Uq7<}PPC;FFWV6SMdO{IIf<6VLyptl& zS#kPHRiCqksJ&}~MAOtWZG(1>&fsUG1!T0l<;HIck#iajQG!p`?-s2r0E2JNsAnAy z1!QkU-KXVGEVBy@!^_d{^Scp0Qmkg+i zmf0KMB{vafCo4kGkt(t9X4M}PA;M%sqrjgj*E@@fY=b04552FUFYke|Z6!qeX51PY z%;|bNm895|hbCr}2-?hGK`sa#qjuv{C#KWC=P~2XUAYkeD8*g~WU2$o;iNMp2Dg8^ zLd8yvjAsx0^}vv@dU$lbiWSF=2L>{ZPK#)Kj{!05y{Gsj|9)Kk#SA;~Ms5}k)o6xz z&;lu_i@+g7&>`F;8FdD_9DONRU`4ZGR0*#=&*_N*~VvO(&=FokLXXMUc+E9w*1|KMjQc3B%U0d-m!irkz^ZE%J z=P`f563t;AhTdF5%oy-Wynbs^>>z?5q@nYiB4b+r|t}TcAWz@ zZPb37BM|$kC`wMjz^xDff%R57nr6Kc?eDN z4==t~+^)f$$5l)5sH&D8%|>bH+nSMv@0{5X74+Rgg)?6NIgf zVbTE)a-jOyb0WxuQdy^Y=4J4`6gQP&PSXxd4?A}?wquRT=s{Sf(Ap3@7t7FW;GFsb_A(`7n^-EV?pN#;}-T@KpuC9lgEIo#0}Y*I77_P*f%zK^xt zs2ct#bi3e`sWuCMFcmH#zlLj1A5N%J+!sn0<3aNtHJdWE@dE0!KWwdvZOwmZHe;T` zoJ0u~b+L+YI*QMO3>Iy{U?{OMusjGgz^! zRZpS$keR0s`;^G9stnE0SxmW#<)uFog7Uz~ay(;SO6-aiJiqPN*mLMrhZ+DKA0~S2 zd3#DSe27LmSKYlta*VU~=B<05h|z|;0sYR*jleO38171hoBF@T|2L0J7Xd&Wbhs+qa?t zlSRv98+T_z9a7@RkCHLI^O{LMQ|V$mM4ac1s?J>7xbnq(&WmXAAzL5zs0Et(zJecclp4@#Cb|&lpPy>$sO_~8 zz4&NbDV&pZ<)MkN6w=7dB)?8VGiXB?DJ}HbIYWYc;=*4FVRmip){VnekwpgA8qR29ZhS9f5n8 zu?trIc120pWVSBRejWsG^@&f<$r$zTv6^2_udqm1gclmWW+U!$-HYIISKHmy{B7Jx zp%wAl-=rt_0>*`B<%6T z@~Fmz(%P$kX@$JNeOxq-Kw%Wp&@a&2^!aph^A*BHX0OxoX z3zpP(uI*{jeO2eY3{*j)7XKap(ny*HE-c|VRl%cwJ$UESUBvAX^}&5Mri$0-R!19F z)aVDExu`?lLu(;``0L{~uJ%XUUn&ZF(t3k%Nu|$`o?&pYGGVQZs*M)kO}jpX`V-#N zK_Zybm63JrET;-3ul#FLVHjBsl=~{CSB6t!%K#J-^wt4D{62#95JEkwV#BQp1539j z95`WkW&C1|WKIna|Lzr!7t{N{rK0cd{NW~$Bz9*%sakfC7xu{fuRbRQIB!H`|5^6G zunxyLh<5421(z({yT$&nhVP^EOSa{QZL?%CmgZ47RUfv^hi&txL;rA6KAe;#&gFw~ w_+T797>5r5=R)-TA#(U&5C4Zf^q*U^e?)vZejEL>75KM*ubxKsH`W*b59DnxO8@`> literal 0 HcmV?d00001 diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h index ca5c06204d..e37d34c16d 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h @@ -40,7 +40,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include +#include #include typedef struct _PCI_IO_DEVICE PCI_IO_DEVICE; diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index cd3940d34b..9ebbd2b853 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -73,11 +73,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include -#include -#include +#include +#include #include #include +#include #include #include #include @@ -220,10 +220,10 @@ typedef struct { EFI_RUNTIME_IMAGE_ENTRY *RuntimeData; /// Pointer to Loaded Image Device Path Protocol EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; - /// PeCoffLoader ImageContext - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; /// Status returned by LoadImage() service. EFI_STATUS LoadImageStatus; + + VOID *HiiData; } LOADED_IMAGE_PRIVATE_DATA; #define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \ @@ -390,7 +390,8 @@ CoreInitializeEventServices ( **/ EFI_STATUS CoreInitializeImageServices ( - IN VOID *HobStart + IN VOID *HobStart, + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); /** @@ -2385,7 +2386,8 @@ VOID CoreNewDebugImageInfoEntry ( IN UINT32 ImageInfoType, IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_HANDLE ImageHandle + IN EFI_HANDLE ImageHandle, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); /** @@ -2574,7 +2576,8 @@ VerifyFvHeaderChecksum ( **/ VOID MemoryProfileInit ( - IN VOID *HobStart + IN VOID *HobStart, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); /** @@ -2600,8 +2603,9 @@ MemoryProfileInstallProtocol ( **/ EFI_STATUS RegisterMemoryProfileImage ( - IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry, - IN EFI_FV_FILETYPE FileType + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN EFI_FV_FILETYPE FileType, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); /** @@ -2617,7 +2621,8 @@ RegisterMemoryProfileImage ( **/ EFI_STATUS UnregisterMemoryProfileImage ( - IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry + EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN EFI_PHYSICAL_ADDRESS ImageAddress ); /** @@ -2704,7 +2709,8 @@ InstallMemoryAttributesTableOnMemoryAllocation ( **/ VOID InsertImageRecord ( - IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage + IN LOADED_IMAGE_PRIVATE_DATA *Image, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); /** @@ -2725,8 +2731,8 @@ RemoveImageRecord ( **/ VOID ProtectUefiImage ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath + IN LOADED_IMAGE_PRIVATE_DATA *Image, + UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); /** diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index cc315ac92a..4f20d6420f 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -82,9 +82,8 @@ UefiLib DebugLib DxeCoreEntryPoint - PeCoffLib - PeCoffGetEntryPointLib - PeCoffExtraActionLib + UefiImageLib + UefiImageExtraActionLib ExtractGuidedSectionLib MemoryAllocationLib UefiBootServicesTableLib diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 50ab5fb844..da8d411d9b 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -236,15 +236,14 @@ DxeMain ( IN VOID *HobStart ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS MemoryBaseAddress; - UINT64 MemoryLength; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - UINTN Index; - EFI_HOB_GUID_TYPE *GuidHob; - EFI_VECTOR_HANDOFF_INFO *VectorInfoList; - EFI_VECTOR_HANDOFF_INFO *VectorInfo; - VOID *EntryPoint; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS MemoryBaseAddress; + UINT64 MemoryLength; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UINTN Index; + EFI_HOB_GUID_TYPE *GuidHob; + EFI_VECTOR_HANDOFF_INFO *VectorInfoList; + EFI_VECTOR_HANDOFF_INFO *VectorInfo; // // Setup the default exception handlers @@ -276,8 +275,6 @@ DxeMain ( // CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength); - MemoryProfileInit (HobStart); - // // Start the Handle Services. // @@ -287,9 +284,11 @@ DxeMain ( // // Start the Image Services. // - Status = CoreInitializeImageServices (HobStart); + Status = CoreInitializeImageServices (HobStart, &ImageContext); ASSERT_EFI_ERROR (Status); + MemoryProfileInit (HobStart, &ImageContext); + // // Initialize the Global Coherency Domain Services // @@ -335,19 +334,9 @@ DxeMain ( // // Report DXE Core image information to the PE/COFF Extra Action Library + // FIXME: This is done by DxeIpl, why is this needed here? Difference PEI/DXE? // - ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)gDxeCoreLoadedImage->ImageBase; - ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress); - ImageContext.SizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID *)(UINTN)ImageContext.ImageAddress); - Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)ImageContext.ImageAddress, &EntryPoint); - if (Status == EFI_SUCCESS) { - ImageContext.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)EntryPoint; - } - - ImageContext.Handle = (VOID *)(UINTN)gDxeCoreLoadedImage->ImageBase; - ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; - PeCoffLoaderRelocateImageExtraAction (&ImageContext); + UefiImageLoaderRelocateImageExtraAction (&ImageContext); // // Install the DXE Services Table into the EFI System Tables's Configuration Table @@ -394,7 +383,8 @@ DxeMain ( CoreNewDebugImageInfoEntry ( EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, gDxeCoreLoadedImage, - gDxeCoreImageHandle + gDxeCoreImageHandle, + &ImageContext ); DEBUG ((DEBUG_INFO | DEBUG_LOAD, "HOBLIST address in DXE = 0x%p\n", HobStart)); diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 8d12f93d7f..818b7fb513 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -86,7 +86,20 @@ GLOBAL_REMOVE_IF_UNREFERENCED MACHINE_TYPE_INFO mMachineTypeInfo[] = { { EFI_IMAGE_MACHINE_LOONGARCH64, L"LOONGARCH64" }, }; -UINT16 mDxeCoreImageMachineType = 0; +// FIXME: RISC-V, IA64 +#if defined (MDE_CPU_IA32) + CONST CHAR16 *mDxeCoreImageMachineTypeName = L"IA32"; +#elif defined (MDE_CPU_IPF) + CONST CHAR16 *mDxeCoreImageMachineTypeName = L"IA64"; +#elif defined (MDE_CPU_X64) + CONST CHAR16 *mDxeCoreImageMachineTypeName = L"X64"; +#elif defined (MDE_CPU_ARM) + CONST CHAR16 *mDxeCoreImageMachineTypeName = L"ARM"; +#elif defined (MDE_CPU_AARCH64) + CONST CHAR16 *mDxeCoreImageMachineTypeName = L"AARCH64"; +#else + #error Unkown CPU architecture +#endif /** Return machine type name. @@ -102,7 +115,7 @@ GetMachineTypeName ( { UINTN Index; - for (Index = 0; Index < sizeof (mMachineTypeInfo)/sizeof (mMachineTypeInfo[0]); Index++) { + for (Index = 0; Index < sizeof (mMachineTypeInfo)/sizeof (mMachineTypeInfo[0]); ++Index) { if (mMachineTypeInfo[Index].MachineType == MachineType) { return mMachineTypeInfo[Index].MachineTypeName; } @@ -182,7 +195,8 @@ PeCoffEmuProtocolNotify ( **/ EFI_STATUS CoreInitializeImageServices ( - IN VOID *HobStart + IN VOID *HobStart, + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { EFI_STATUS Status; @@ -219,6 +233,18 @@ CoreInitializeImageServices ( // Image = &mCorePrivateImage; + Status = UefiImageInitializeContext ( + ImageContext, + (VOID *) (UINTN) DxeCoreImageBaseAddress, + (UINT32) DxeCoreImageLength + ); + ASSERT_EFI_ERROR (Status); + + // FIXME: DxeCore is dynamically loaded by DxeIpl, can't it pass the context? + ImageContext->ImageBuffer = (VOID *) ImageContext->FileBuffer; + + ASSERT ((UINTN) DxeCoreEntryPoint == UefiImageLoaderGetImageEntryPoint (ImageContext)); + Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)DxeCoreEntryPoint; Image->ImageBasePage = DxeCoreImageBaseAddress; Image->NumberOfPages = (UINTN)(EFI_SIZE_TO_PAGES ((UINTN)(DxeCoreImageLength))); @@ -242,9 +268,8 @@ CoreInitializeImageServices ( // // Fill in DXE globals // - mDxeCoreImageMachineType = PeCoffLoaderGetMachineType (Image->Info.ImageBase); - gDxeCoreImageHandle = Image->Handle; - gDxeCoreLoadedImage = &Image->Info; + gDxeCoreImageHandle = Image->Handle; + gDxeCoreLoadedImage = &Image->Info; // // Create the PE/COFF emulator protocol registration event @@ -270,64 +295,11 @@ CoreInitializeImageServices ( InitializeListHead (&mAvailableEmulators); - ProtectUefiImage (&Image->Info, Image->LoadedImageDevicePath); + ProtectUefiImage (Image, ImageContext); return Status; } -/** - Read image file (specified by UserHandle) into user specified buffer with specified offset - and length. - - @param UserHandle Image file handle - @param Offset Offset to the source file - @param ReadSize For input, pointer of size to read; For output, - pointer of size actually read. - @param Buffer Buffer to write into - - @retval EFI_SUCCESS Successfully read the specified part of file - into buffer. - -**/ -EFI_STATUS -EFIAPI -CoreReadImageFile ( - IN VOID *UserHandle, - IN UINTN Offset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer - ) -{ - UINTN EndPosition; - IMAGE_FILE_HANDLE *FHand; - - if ((UserHandle == NULL) || (ReadSize == NULL) || (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (MAX_ADDRESS - Offset < *ReadSize) { - return EFI_INVALID_PARAMETER; - } - - FHand = (IMAGE_FILE_HANDLE *)UserHandle; - ASSERT (FHand->Signature == IMAGE_FILE_HANDLE_SIGNATURE); - - // - // Move data from our local copy of the file - // - EndPosition = Offset + *ReadSize; - if (EndPosition > FHand->SourceSize) { - *ReadSize = (UINT32)(FHand->SourceSize - Offset); - } - - if (Offset >= FHand->SourceSize) { - *ReadSize = 0; - } - - CopyMem (Buffer, (CHAR8 *)FHand->Source + Offset, *ReadSize); - return EFI_SUCCESS; -} - /** To check memory usage bit map array to figure out if the memory range the image will be loaded in is available or not. If memory range is available, the function will mark the corresponding bits to 1 which indicates the memory range is used. @@ -378,8 +350,8 @@ CheckAndMarkFixLoadingMemoryUsageBitMap ( // // Test the memory range for loading the image in the DXE code range. // - if ((gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress < ImageBase + ImageSize) || - (DxeCodeBase > ImageBase)) + if ((gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress < ImageBase + ImageSize) || + (DxeCodeBase > ImageBase)) { return EFI_NOT_FOUND; } @@ -389,7 +361,7 @@ CheckAndMarkFixLoadingMemoryUsageBitMap ( // BaseOffsetPageNumber = EFI_SIZE_TO_PAGES ((UINT32)(ImageBase - DxeCodeBase)); TopOffsetPageNumber = EFI_SIZE_TO_PAGES ((UINT32)(ImageBase + ImageSize - DxeCodeBase)); - for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index++) { + for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; ++Index) { if ((mDxeCodeMemoryRangeUsageBitMap[Index / 64] & LShiftU64 (1, (Index % 64))) != 0) { // // This page is already used. @@ -401,7 +373,7 @@ CheckAndMarkFixLoadingMemoryUsageBitMap ( // // Being here means the memory range is available. So mark the bits for the memory range // - for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index++) { + for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; ++Index) { mDxeCodeMemoryRangeUsageBitMap[Index / 64] |= LShiftU64 (1, (Index % 64)); } @@ -420,88 +392,35 @@ CheckAndMarkFixLoadingMemoryUsageBitMap ( **/ EFI_STATUS -GetPeCoffImageFixLoadingAssignedAddress ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext +GetUefiImageFixLoadingAssignedAddress ( + OUT EFI_PHYSICAL_ADDRESS *LoadAddress, + IN UINT64 ValueInSectionHeader, + IN UINT32 ImageDestSize ) { - UINTN SectionHeaderOffset; - EFI_STATUS Status; - EFI_IMAGE_SECTION_HEADER SectionHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - UINT16 Index; - UINTN Size; - UINT16 NumberOfSections; - IMAGE_FILE_HANDLE *Handle; - UINT64 ValueInSectionHeader; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS FixLoadingAddress; - Status = EFI_NOT_FOUND; - - // - // Get PeHeader pointer - // - Handle = (IMAGE_FILE_HANDLE *)ImageContext->Handle; - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)Handle->Source + ImageContext->PeCoffHeaderOffset); - SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader; - NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections; - - // - // Get base address from the first section header that doesn't point to code section. - // - for (Index = 0; Index < NumberOfSections; Index++) { + if ((INT64)PcdGet64(PcdLoadModuleAtFixAddressEnable) > 0) { // - // Read section header from file + // When LMFA feature is configured as Load Module at Fixed Absolute Address mode, PointerToRelocations & PointerToLineNumbers field + // hold the absolute address of image base running in memory // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (EFI_ERROR (Status)) { - return Status; - } - - if (Size != sizeof (EFI_IMAGE_SECTION_HEADER)) { - return EFI_NOT_FOUND; - } - - Status = EFI_NOT_FOUND; - - if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) { - // - // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header - // that doesn't point to code section in image header, as well as ImageBase field of image header. And there is an - // assumption that when the feature is enabled, if a module is assigned a loading address by tools, PointerToRelocations - // & PointerToLineNumbers fields should NOT be Zero, or else, these 2 fields should be set to Zero - // - ValueInSectionHeader = ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations); - if (ValueInSectionHeader != 0) { - // - // When the feature is configured as load module at fixed absolute address, the ImageAddress field of ImageContext - // hold the specified address. If the feature is configured as load module at fixed offset, ImageAddress hold an offset - // relative to top address - // - if ((INT64)PcdGet64 (PcdLoadModuleAtFixAddressEnable) < 0) { - ImageContext->ImageAddress = gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress + (INT64)(INTN)ImageContext->ImageAddress; - } - - // - // Check if the memory range is available. - // - Status = CheckAndMarkFixLoadingMemoryUsageBitMap (ImageContext->ImageAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment)); - } - - break; - } - - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); + FixLoadingAddress = ValueInSectionHeader; + } else { + // + // When LMFA feature is configured as Load Module at Fixed offset mode, PointerToRelocations & PointerToLineNumbers field + // hold the offset relative to a platform-specific top address. + // + FixLoadingAddress = gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress + ValueInSectionHeader; } + // + // Check if the memory range is available. + // + Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoadingAddress, ImageDestSize); + *LoadAddress = FixLoadingAddress; - DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status = %r \n", (VOID *)(UINTN)(ImageContext->ImageAddress), Status)); + DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status = %r \n", (VOID *)(UINTN)FixLoadingAddress, Status)); return Status; } @@ -520,7 +439,8 @@ GetPeCoffImageFixLoadingAssignedAddress ( STATIC BOOLEAN CoreIsImageTypeSupported ( - IN OUT LOADED_IMAGE_PRIVATE_DATA *Image + IN OUT LOADED_IMAGE_PRIVATE_DATA *Image, + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { LIST_ENTRY *Link; @@ -531,13 +451,13 @@ CoreIsImageTypeSupported ( Link = GetNextNode (&mAvailableEmulators, Link)) { Entry = BASE_CR (Link, EMULATOR_ENTRY, Link); - if (Entry->MachineType != Image->ImageContext.Machine) { + if (Entry->MachineType != UefiImageGetMachine (ImageContext)) { continue; } if (Entry->Emulator->IsImageSupported ( Entry->Emulator, - Image->ImageContext.ImageType, + UefiImageGetSubsystem (ImageContext), Image->Info.FilePath )) { @@ -546,8 +466,8 @@ CoreIsImageTypeSupported ( } } - return EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image->ImageContext.Machine) || - EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (Image->ImageContext.Machine); + return EFI_IMAGE_MACHINE_TYPE_SUPPORTED (UefiImageGetMachine (ImageContext)) || + EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (UefiImageGetMachine (ImageContext)); } /** @@ -557,7 +477,6 @@ CoreIsImageTypeSupported ( from the boot manager, and that the boot manager is attempting to load FilePath as a boot selection. - @param Pe32Handle The handle of PE32 image @param Image PE image to be loaded @param DstBuffer The buffer to store the image @param EntryPoint A pointer to the entry point @@ -573,32 +492,30 @@ CoreIsImageTypeSupported ( **/ EFI_STATUS CoreLoadPeImage ( - IN BOOLEAN BootPolicy, - IN VOID *Pe32Handle, - IN LOADED_IMAGE_PRIVATE_DATA *Image, - IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL, - OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL, - IN UINT32 Attribute + IN BOOLEAN BootPolicy, + IN LOADED_IMAGE_PRIVATE_DATA *Image, + IN EFI_PHYSICAL_ADDRESS *DstBuffer OPTIONAL, + OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL, + IN UINT32 Attribute, + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { - EFI_STATUS Status; - BOOLEAN DstBufAlocated; - UINTN Size; - - ZeroMem (&Image->ImageContext, sizeof (Image->ImageContext)); - - Image->ImageContext.Handle = Pe32Handle; - Image->ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)CoreReadImageFile; - - // - // Get information about the image being loaded - // - Status = PeCoffLoaderGetImageInfo (&Image->ImageContext); - if (EFI_ERROR (Status)) { - return Status; - } - - if (!CoreIsImageTypeSupported (Image)) { + EFI_STATUS Status; + BOOLEAN DstBufAlocated; + UINT32 ImageSize; + UINT32 ImageAlignment; + UINT64 ValueInSectionHeader; + UINT32 DstBufPages; + UINT32 DstBufSize; + EFI_MEMORY_TYPE ImageCodeMemoryType; + EFI_MEMORY_TYPE ImageDataMemoryType; + UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RelocationData; + EFI_PHYSICAL_ADDRESS BufferAddress; + UINT32 RelocDataSize; + + RelocationData = NULL; + + if (!CoreIsImageTypeSupported (Image, ImageContext)) { // // 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_UNSUPPORTED. @@ -606,50 +523,50 @@ CoreLoadPeImage ( DEBUG (( DEBUG_ERROR, "Image type %s can't be loaded on %s UEFI system.\n", - GetMachineTypeName (Image->ImageContext.Machine), - GetMachineTypeName (mDxeCoreImageMachineType) + GetMachineTypeName (UefiImageGetMachine (ImageContext)), + mDxeCoreImageMachineTypeName )); + return EFI_UNSUPPORTED; } // // Set EFI memory type based on ImageType // - switch (Image->ImageContext.ImageType) { + switch (UefiImageGetSubsystem (ImageContext)) { case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION: - Image->ImageContext.ImageCodeMemoryType = EfiLoaderCode; - Image->ImageContext.ImageDataMemoryType = EfiLoaderData; + ImageCodeMemoryType = EfiLoaderCode; + ImageDataMemoryType = EfiLoaderData; break; case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER: - Image->ImageContext.ImageCodeMemoryType = EfiBootServicesCode; - Image->ImageContext.ImageDataMemoryType = EfiBootServicesData; + ImageCodeMemoryType = EfiBootServicesCode; + ImageDataMemoryType = EfiBootServicesData; break; case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER: - Image->ImageContext.ImageCodeMemoryType = EfiRuntimeServicesCode; - Image->ImageContext.ImageDataMemoryType = EfiRuntimeServicesData; + ImageCodeMemoryType = EfiRuntimeServicesCode; + ImageDataMemoryType = EfiRuntimeServicesData; break; - default: - Image->ImageContext.ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM; - return EFI_UNSUPPORTED; + default: + DEBUG ((DEBUG_INFO, "Unsupported type %d\n", UefiImageGetSubsystem (ImageContext))); + return EFI_UNSUPPORTED; } + ImageSize = UefiImageGetImageSize (ImageContext); + DstBufPages = EFI_SIZE_TO_PAGES (ImageSize); + DstBufSize = EFI_PAGES_TO_SIZE (DstBufPages); + ImageAlignment = UefiImageGetSegmentAlignment (ImageContext); + + BufferAddress = 0; // // Allocate memory of the correct memory type aligned on the required image boundary // DstBufAlocated = FALSE; - if (DstBuffer == 0) { + if (*DstBuffer == 0) { // // Allocate Destination Buffer as caller did not pass it in // - - if (Image->ImageContext.SectionAlignment > EFI_PAGE_SIZE) { - Size = (UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment; - } else { - Size = (UINTN)Image->ImageContext.ImageSize; - } - - Image->NumberOfPages = EFI_SIZE_TO_PAGES (Size); + Image->NumberOfPages = DstBufPages; // // If the image relocations have not been stripped, then load at any address. @@ -664,98 +581,105 @@ CoreLoadPeImage ( // a specified address. // if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0 ) { - Status = GetPeCoffImageFixLoadingAssignedAddress (&(Image->ImageContext)); + Status = UefiImageGetFixedAddress (ImageContext, &ValueInSectionHeader); + if (RETURN_ERROR (Status)) { + return Status; + } - if (EFI_ERROR (Status)) { + Status = GetUefiImageFixLoadingAssignedAddress (&BufferAddress, ValueInSectionHeader, DstBufSize); + + if (!EFI_ERROR (Status)) { + if (BufferAddress != UefiImageGetPreferredAddress (ImageContext) && UefiImageGetRelocsStripped (ImageContext)) { + Status = EFI_UNSUPPORTED; + DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since relocs have been stripped.\n")); + } + } else { // // If the code memory is not ready, invoke CoreAllocatePage with AllocateAnyPages to load the driver. // DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since specified memory is not available.\n")); - - Status = CoreAllocatePages ( - AllocateAnyPages, - (EFI_MEMORY_TYPE)(Image->ImageContext.ImageCodeMemoryType), - Image->NumberOfPages, - &Image->ImageContext.ImageAddress - ); } - } else { - if ((PcdGetBool (PcdImageLargeAddressLoad) && ((Image->ImageContext.ImageAddress) >= 0x100000)) || - Image->ImageContext.RelocationsStripped) - { - Status = CoreAllocatePages ( + } + if (EFI_ERROR (Status)) { + BufferAddress = UefiImageGetPreferredAddress (ImageContext); + if ((BufferAddress >= 0x100000) || UefiImageGetRelocsStripped (ImageContext)) { + Status = AllocatePagesEx ( AllocateAddress, - (EFI_MEMORY_TYPE)(Image->ImageContext.ImageCodeMemoryType), - Image->NumberOfPages, - &Image->ImageContext.ImageAddress + ImageCodeMemoryType, + DstBufPages, + &BufferAddress ); } - if (EFI_ERROR (Status) && !Image->ImageContext.RelocationsStripped) { - Status = CoreAllocatePages ( + if (EFI_ERROR (Status) && !UefiImageGetRelocsStripped (ImageContext)) { + Status = AllocateAlignedPagesEx ( AllocateAnyPages, - (EFI_MEMORY_TYPE)(Image->ImageContext.ImageCodeMemoryType), - Image->NumberOfPages, - &Image->ImageContext.ImageAddress + ImageCodeMemoryType, + DstBufPages, + ImageAlignment, + &BufferAddress ); } } if (EFI_ERROR (Status)) { + ASSERT (FALSE); return Status; } DstBufAlocated = TRUE; + *DstBuffer = BufferAddress; } else { // // Caller provided the destination buffer // - if (Image->ImageContext.RelocationsStripped && (Image->ImageContext.ImageAddress != DstBuffer)) { + if (UefiImageGetRelocsStripped (ImageContext) && (BufferAddress != *DstBuffer)) { // // If the image relocations were stripped, and the caller provided a // destination buffer address that does not match the address that the // image is linked at, then the image cannot be loaded. // + ASSERT (FALSE); return EFI_INVALID_PARAMETER; } if ((Image->NumberOfPages != 0) && (Image->NumberOfPages < - (EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment)))) + DstBufPages)) { - Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment); + Image->NumberOfPages = DstBufPages; + ASSERT (FALSE); return EFI_BUFFER_TOO_SMALL; } - Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment); - Image->ImageContext.ImageAddress = DstBuffer; + Image->NumberOfPages = DstBufPages; + BufferAddress = *DstBuffer; } - Image->ImageBasePage = Image->ImageContext.ImageAddress; - if (!Image->ImageContext.IsTeImage) { - Image->ImageContext.ImageAddress = - (Image->ImageContext.ImageAddress + Image->ImageContext.SectionAlignment - 1) & - ~((UINTN)Image->ImageContext.SectionAlignment - 1); - } - - // - // Load the image from the file into the allocated memory - // - Status = PeCoffLoaderLoadImage (&Image->ImageContext); - if (EFI_ERROR (Status)) { - goto Done; - } + Image->ImageBasePage = BufferAddress; // // If this is a Runtime Driver, then allocate memory for the FixupData that // is used to relocate the image when SetVirtualAddressMap() is called. The // relocation is done by the Runtime AP. // + RelocDataSize = 0; if ((Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION) != 0) { - if (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) { - Image->ImageContext.FixupData = AllocateRuntimePool ((UINTN)(Image->ImageContext.FixupDataSize)); - if (Image->ImageContext.FixupData == NULL) { + if (UefiImageGetSubsystem (ImageContext) == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) { + if (UefiImageGetRelocsStripped (ImageContext)) { + ASSERT (FALSE); + Status = RETURN_UNSUPPORTED; + goto Done; + } + Status = UefiImageLoaderGetRuntimeContextSize (ImageContext, &RelocDataSize); + if (EFI_ERROR (Status)) { + ASSERT (FALSE); + goto Done; + } + RelocationData = AllocateRuntimeZeroPool (RelocDataSize); + if (RelocationData == NULL) { + ASSERT (FALSE); Status = EFI_OUT_OF_RESOURCES; goto Done; } @@ -763,38 +687,40 @@ CoreLoadPeImage ( } // - // Relocate the image in memory + // Load the image from the file into the allocated memory // - Status = PeCoffLoaderRelocateImage (&Image->ImageContext); + Status = UefiImageLoadImageForExecution ( + ImageContext, + (VOID *)(UINTN)BufferAddress, + DstBufSize, + RelocationData, + RelocDataSize + ); if (EFI_ERROR (Status)) { + ASSERT (FALSE); goto Done; } - // - // Flush the Instruction Cache - // - InvalidateInstructionCacheRange ((VOID *)(UINTN)Image->ImageContext.ImageAddress, (UINTN)Image->ImageContext.ImageSize); - // // Copy the machine type from the context to the image private data. // - Image->Machine = Image->ImageContext.Machine; + Image->Machine = UefiImageGetMachine (ImageContext); // // Get the image entry point. // - Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)Image->ImageContext.EntryPoint; + Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UefiImageLoaderGetImageEntryPoint (ImageContext)); // // Fill in the image information for the Loaded Image Protocol // - Image->Type = Image->ImageContext.ImageType; - Image->Info.ImageBase = (VOID *)(UINTN)Image->ImageContext.ImageAddress; - Image->Info.ImageSize = Image->ImageContext.ImageSize; - Image->Info.ImageCodeType = (EFI_MEMORY_TYPE)(Image->ImageContext.ImageCodeMemoryType); - Image->Info.ImageDataType = (EFI_MEMORY_TYPE)(Image->ImageContext.ImageDataMemoryType); + Image->Type = UefiImageGetSubsystem (ImageContext); + Image->Info.ImageBase = (VOID *)(UINTN)BufferAddress; + Image->Info.ImageSize = ImageSize; + Image->Info.ImageCodeType = ImageCodeMemoryType; + Image->Info.ImageDataType = ImageDataMemoryType; if ((Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION) != 0) { - if (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) { + if (UefiImageGetSubsystem (ImageContext) == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) { // // Make a list off all the RT images so we can let the RT AP know about them. // @@ -805,10 +731,10 @@ CoreLoadPeImage ( Image->RuntimeData->ImageBase = Image->Info.ImageBase; Image->RuntimeData->ImageSize = (UINT64)(Image->Info.ImageSize); - Image->RuntimeData->RelocationData = Image->ImageContext.FixupData; + Image->RuntimeData->RelocationData = RelocationData; Image->RuntimeData->Handle = Image->Handle; InsertTailList (&gRuntime->ImageHead, &Image->RuntimeData->Link); - InsertImageRecord (Image->RuntimeData); + InsertImageRecord (Image, ImageContext); } } @@ -816,7 +742,17 @@ CoreLoadPeImage ( // Fill in the entry point of the image if it is available // if (EntryPoint != NULL) { - *EntryPoint = Image->ImageContext.EntryPoint; + *EntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext); + } + + UINT32 Hiioff; + UINT32 Hiisize; + Status = UefiImageGetHiiDataRva (ImageContext, &Hiioff, &Hiisize); + if (Status != RETURN_NOT_FOUND) { + ASSERT_EFI_ERROR (Status); + } + if (!EFI_ERROR (Status)) { + Image->HiiData = (VOID *)((UINTN)BufferAddress + Hiioff); } // @@ -825,56 +761,25 @@ CoreLoadPeImage ( DEBUG_CODE_BEGIN (); - UINTN Index; - UINTN StartIndex; - CHAR8 EfiFileName[256]; + CHAR8 EfiFileName[256]; - DEBUG (( - DEBUG_INFO | DEBUG_LOAD, - "Loading driver at 0x%11p EntryPoint=0x%11p ", - (VOID *)(UINTN)Image->ImageContext.ImageAddress, - FUNCTION_ENTRY_POINT (Image->ImageContext.EntryPoint) - )); + DEBUG ((DEBUG_INFO | DEBUG_LOAD, + "Loading driver at 0x%11p EntryPoint=0x%11p \n", + (VOID *)(UINTN)BufferAddress, + FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext)))); + + Status = UefiImageGetModuleNameFromSymbolsPath ( + ImageContext, + EfiFileName, + sizeof (EfiFileName) + ); // // Print Module Name by Pdb file path. - // Windows and Unix style file path are all trimmed correctly. // - if (Image->ImageContext.PdbPointer != NULL) { - StartIndex = 0; - for (Index = 0; Image->ImageContext.PdbPointer[Index] != 0; Index++) { - if ((Image->ImageContext.PdbPointer[Index] == '\\') || (Image->ImageContext.PdbPointer[Index] == '/')) { - StartIndex = Index + 1; - } - } - - // - // Copy the PDB file name to our temporary string, and replace .pdb with .efi - // The PDB file name is limited in the range of 0~255. - // If the length is bigger than 255, trim the redudant characters to avoid overflow in array boundary. - // - for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) { - EfiFileName[Index] = Image->ImageContext.PdbPointer[Index + StartIndex]; - if (EfiFileName[Index] == 0) { - EfiFileName[Index] = '.'; - } - - if (EfiFileName[Index] == '.') { - EfiFileName[Index + 1] = 'e'; - EfiFileName[Index + 2] = 'f'; - EfiFileName[Index + 3] = 'i'; - EfiFileName[Index + 4] = 0; - break; - } - } - - if (Index == sizeof (EfiFileName) - 4) { - EfiFileName[Index] = 0; - } - - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex])); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); } - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n")); DEBUG_CODE_END (); @@ -888,13 +793,13 @@ CoreLoadPeImage ( // if (DstBufAlocated) { - CoreFreePages (Image->ImageContext.ImageAddress, Image->NumberOfPages); - Image->ImageContext.ImageAddress = 0; + ZeroMem ((VOID *)(UINTN)BufferAddress, EFI_PAGES_TO_SIZE (Image->NumberOfPages)); + FreeAlignedPages ((VOID *)(UINTN)BufferAddress, Image->NumberOfPages); Image->ImageBasePage = 0; } - if (Image->ImageContext.FixupData != NULL) { - CoreFreePool (Image->ImageContext.FixupData); + if (RelocationData != NULL) { + CoreFreePool (RelocationData); } return Status; @@ -959,23 +864,20 @@ CoreUnloadAndCloseImage ( HandleBuffer = NULL; ProtocolGuidArray = NULL; - if (Image->Started) { - UnregisterMemoryProfileImage (Image); - } - - UnprotectUefiImage (&Image->Info, Image->LoadedImageDevicePath); + UnregisterMemoryProfileImage (Image->Info.FilePath, Image->ImageBasePage); if (Image->PeCoffEmu != NULL) { // // If the PE/COFF Emulator protocol exists we must unregister the image. // - Image->PeCoffEmu->UnregisterImage (Image->PeCoffEmu, Image->ImageBasePage); + Image->PeCoffEmu->UnregisterImage (Image->PeCoffEmu, (UINTN) Image->Info.ImageBase); } // // Unload image, free Image->ImageContext->ModHandle // - PeCoffLoaderUnloadImage (&Image->ImageContext); + // FIXME: + //PeCoffUnloadImage (&Image->ImageContext); // // Free our references to the image handle @@ -989,14 +891,14 @@ CoreUnloadAndCloseImage ( &HandleBuffer ); if (!EFI_ERROR (Status)) { - for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) { + for (HandleIndex = 0; HandleIndex < HandleCount; ++HandleIndex) { Status = CoreProtocolsPerHandle ( HandleBuffer[HandleIndex], &ProtocolGuidArray, &ArrayCount ); if (!EFI_ERROR (Status)) { - for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) { + for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ++ProtocolIndex) { Status = CoreOpenProtocolInformation ( HandleBuffer[HandleIndex], ProtocolGuidArray[ProtocolIndex], @@ -1004,7 +906,7 @@ CoreUnloadAndCloseImage ( &OpenInfoCount ); if (!EFI_ERROR (Status)) { - for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) { + for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; ++OpenInfoIndex) { if (OpenInfo[OpenInfoIndex].AgentHandle == Image->Handle) { Status = CoreCloseProtocol ( HandleBuffer[HandleIndex], @@ -1046,11 +948,11 @@ CoreUnloadAndCloseImage ( &Image->Info ); - if (Image->ImageContext.HiiResourceData != 0) { + if (Image->HiiData != NULL) { Status = CoreUninstallProtocolInterface ( Image->Handle, &gEfiHiiPackageListProtocolGuid, - (VOID *)(UINTN)Image->ImageContext.HiiResourceData + Image->HiiData ); } } @@ -1067,16 +969,23 @@ CoreUnloadAndCloseImage ( CoreFreePool (Image->RuntimeData); } + // + // Done with the Image structure + // + if (Image->FixupData != NULL) { + CoreFreePool (Image->FixupData); + } + // // Free the Image from memory // if ((Image->ImageBasePage != 0) && FreePage) { + UnprotectUefiImage (&Image->Info, Image->LoadedImageDevicePath); + // FIXME: SecureZeroMem; instruction pattern to trap? + ZeroMem ((VOID *)(UINTN)Image->ImageBasePage, EFI_PAGES_TO_SIZE (Image->NumberOfPages)); CoreFreePages (Image->ImageBasePage, Image->NumberOfPages); } - // - // Done with the Image structure - // if (Image->Info.FilePath != NULL) { CoreFreePool (Image->Info.FilePath); } @@ -1085,10 +994,6 @@ CoreUnloadAndCloseImage ( CoreFreePool (Image->LoadedImageDevicePath); } - if (Image->FixupData != NULL) { - CoreFreePool (Image->FixupData); - } - CoreFreePool (Image); } @@ -1150,20 +1055,21 @@ CoreLoadImageCommon ( IN UINT32 Attribute ) { - LOADED_IMAGE_PRIVATE_DATA *Image; - LOADED_IMAGE_PRIVATE_DATA *ParentImage; - IMAGE_FILE_HANDLE FHand; - EFI_STATUS Status; - EFI_STATUS SecurityStatus; - EFI_HANDLE DeviceHandle; - UINT32 AuthenticationStatus; - EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath; - EFI_DEVICE_PATH_PROTOCOL *HandleFilePath; - EFI_DEVICE_PATH_PROTOCOL *InputFilePath; - EFI_DEVICE_PATH_PROTOCOL *Node; - UINTN FilePathSize; - BOOLEAN ImageIsFromFv; - BOOLEAN ImageIsFromLoadFile; + LOADED_IMAGE_PRIVATE_DATA *Image; + LOADED_IMAGE_PRIVATE_DATA *ParentImage; + IMAGE_FILE_HANDLE FHand; + EFI_STATUS Status; + EFI_STATUS SecurityStatus; + EFI_HANDLE DeviceHandle; + UINT32 AuthenticationStatus; + EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath; + EFI_DEVICE_PATH_PROTOCOL *HandleFilePath; + EFI_DEVICE_PATH_PROTOCOL *InputFilePath; + EFI_DEVICE_PATH_PROTOCOL *Node; + UINTN FilePathSize; + BOOLEAN ImageIsFromFv; + BOOLEAN ImageIsFromLoadFile; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; SecurityStatus = EFI_SUCCESS; @@ -1206,6 +1112,18 @@ CoreLoadImageCommon ( } if (SourceSize > 0) { + if (DeviceHandle != NULL) { + Status = CoreOpenProtocol ( + DeviceHandle, + &gEfiFirmwareVolume2ProtocolGuid, + NULL, + NULL, + NULL, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + ImageIsFromFv = !EFI_ERROR (Status); + } + Status = EFI_SUCCESS; } else { Status = EFI_LOAD_ERROR; @@ -1269,6 +1187,16 @@ CoreLoadImageCommon ( goto Done; } + // + // Get information about the image being loaded + // + Status = UefiImageInitializeContextPreHash (&ImageContext, FHand.Source, (UINT32) FHand.SourceSize); + if (EFI_ERROR (Status)) { + ASSERT (FALSE); + return Status; + } + + // FIXME: Context if (gSecurity2 != NULL) { // // Verify File Authentication through the Security2 Architectural Protocol @@ -1276,8 +1204,8 @@ CoreLoadImageCommon ( SecurityStatus = gSecurity2->FileAuthentication ( gSecurity2, OriginalFilePath, - FHand.Source, - FHand.SourceSize, + &ImageContext, + sizeof (ImageContext), BootPolicy ); if (!EFI_ERROR (SecurityStatus) && ImageIsFromFv) { @@ -1324,6 +1252,11 @@ CoreLoadImageCommon ( goto Done; } + Status = UefiImageInitializeContextPostHash (&ImageContext); + if (RETURN_ERROR (Status)) { + goto Done; + } + // // Allocate a new image structure // @@ -1379,7 +1312,8 @@ CoreLoadImageCommon ( // // Load the image. If EntryPoint is Null, it will not be set. // - Status = CoreLoadPeImage (BootPolicy, &FHand, Image, DstBuffer, EntryPoint, Attribute); + EFI_PHYSICAL_ADDRESS LoadAddress = DstBuffer; + Status = CoreLoadPeImage (BootPolicy, Image, &LoadAddress, EntryPoint, Attribute, &ImageContext); if (EFI_ERROR (Status)) { if ((Status == EFI_BUFFER_TOO_SMALL) || (Status == EFI_OUT_OF_RESOURCES)) { if (NumberOfPages != NULL) { @@ -1398,7 +1332,7 @@ CoreLoadImageCommon ( // Register the image in the Debug Image Info Table if the attribute is set // if ((Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION) != 0) { - CoreNewDebugImageInfoEntry (EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, &Image->Info, Image->Handle); + CoreNewDebugImageInfoEntry (EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, &Image->Info, Image->Handle, &ImageContext); } // @@ -1445,22 +1379,26 @@ CoreLoadImageCommon ( goto Done; } - // - // Install HII Package List Protocol onto the image handle - // - if (Image->ImageContext.HiiResourceData != 0) { + if (Image->HiiData != NULL) { Status = CoreInstallProtocolInterface ( &Image->Handle, &gEfiHiiPackageListProtocolGuid, EFI_NATIVE_INTERFACE, - (VOID *)(UINTN)Image->ImageContext.HiiResourceData + Image->HiiData ); if (EFI_ERROR (Status)) { goto Done; } } - ProtectUefiImage (&Image->Info, Image->LoadedImageDevicePath); + Status = EFI_SUCCESS; + ProtectUefiImage (Image, &ImageContext); + + RegisterMemoryProfileImage ( + Image->LoadedImageDevicePath, + (UefiImageGetSubsystem (&ImageContext) == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ? EFI_FV_FILETYPE_APPLICATION : EFI_FV_FILETYPE_DRIVER), + &ImageContext + ); // // Success. Return the image handle @@ -1623,6 +1561,8 @@ CoreStartImage ( return Image->LoadImageStatus; } + DEBUG ((DEBUG_WARN, "Starting driver at %lu\n", Image->Info.ImageBase)); + // // The image to be started must have the machine type supported by DxeCore. // @@ -1633,16 +1573,16 @@ CoreStartImage ( // Do not ASSERT here, because image might be loaded via EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED // But it can not be started. // - DEBUG ((DEBUG_ERROR, "Image type %s can't be started ", GetMachineTypeName (Image->Machine))); - DEBUG ((DEBUG_ERROR, "on %s UEFI system.\n", GetMachineTypeName (mDxeCoreImageMachineType))); + DEBUG ((EFI_D_ERROR, "Image type %s can't be started ", GetMachineTypeName(Image->Machine))); + DEBUG ((EFI_D_ERROR, "on %s UEFI system.\n", mDxeCoreImageMachineTypeName)); return EFI_UNSUPPORTED; } if (Image->PeCoffEmu != NULL) { Status = Image->PeCoffEmu->RegisterImage ( Image->PeCoffEmu, - Image->ImageBasePage, - EFI_PAGES_TO_SIZE (Image->NumberOfPages), + (UINTN) Image->Info.ImageBase, + Image->Info.ImageSize, &Image->EntryPoint ); if (EFI_ERROR (Status)) { @@ -1696,7 +1636,6 @@ CoreStartImage ( // Subsequent calls to LongJump() cause a non-zero value to be returned by SetJump(). // if (SetJumpFlag == 0) { - RegisterMemoryProfileImage (Image, (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ? EFI_FV_FILETYPE_APPLICATION : EFI_FV_FILETYPE_DRIVER)); // // Call the image's entry point // diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c index 4071053036..3baeef0dfc 100644 --- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c +++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c @@ -1533,7 +1533,7 @@ PromoteGuardedFreePages ( OUT EFI_PHYSICAL_ADDRESS *EndAddress ) { - EFI_STATUS Status; + EFI_STATUS Status; UINTN AvailablePages; UINT64 Bitmap; EFI_PHYSICAL_ADDRESS Start; diff --git a/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c b/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c index 00e33b707d..b67596f48e 100644 --- a/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c +++ b/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c @@ -8,6 +8,10 @@ #include "DxeMain.h" #include "Imem.h" +#include "Library/UefiImageLib.h" +#include "ProcessorBind.h" +#include "Protocol/LoadedImage.h" +#include "Uefi/UefiBaseType.h" #define IS_UEFI_MEMORY_PROFILE_ENABLED ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT0) != 0) @@ -104,8 +108,7 @@ EFIAPI ProfileProtocolRegisterImage ( IN EDKII_MEMORY_PROFILE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, IN EFI_FV_FILETYPE FileType ); @@ -247,110 +250,6 @@ GetMemoryProfileContext ( return mMemoryProfileContextPtr; } -/** - Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory. - If Pe32Data is NULL, then ASSERT(). - - @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory. - - @return The Subsystem of the PE/COFF image. - -**/ -UINT16 -InternalPeCoffGetSubsystem ( - IN VOID *Pe32Data - ) -{ - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - EFI_IMAGE_DOS_HEADER *DosHdr; - UINT16 Magic; - - ASSERT (Pe32Data != NULL); - - DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; - } - - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - return Hdr.Te->Subsystem; - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - Magic = Hdr.Pe32->OptionalHeader.Magic; - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - return Hdr.Pe32->OptionalHeader.Subsystem; - } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - return Hdr.Pe32Plus->OptionalHeader.Subsystem; - } - } - - return 0x0000; -} - -/** - Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded - into system memory with the PE/COFF Loader Library functions. - - Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry - point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then - return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS. - If Pe32Data is NULL, then ASSERT(). - If EntryPoint is NULL, then ASSERT(). - - @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory. - @param EntryPoint The pointer to entry point to the PE/COFF image to return. - - @retval RETURN_SUCCESS EntryPoint was returned. - @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image. - -**/ -RETURN_STATUS -InternalPeCoffGetEntryPoint ( - IN VOID *Pe32Data, - OUT VOID **EntryPoint - ) -{ - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - - ASSERT (Pe32Data != NULL); - ASSERT (EntryPoint != NULL); - - DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; - } - - // - // Calculate the entry point relative to the start of the image. - // AddressOfEntryPoint is common for PE32 & PE32+ - // - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - *EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize); - return RETURN_SUCCESS; - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - *EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff)); - return RETURN_SUCCESS; - } - - return RETURN_UNSUPPORTED; -} - /** Build driver info. @@ -367,32 +266,27 @@ InternalPeCoffGetEntryPoint ( **/ MEMORY_PROFILE_DRIVER_INFO_DATA * BuildDriverInfo ( - IN MEMORY_PROFILE_CONTEXT_DATA *ContextData, - IN EFI_GUID *FileName, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, - IN PHYSICAL_ADDRESS EntryPoint, - IN UINT16 ImageSubsystem, - IN EFI_FV_FILETYPE FileType + IN MEMORY_PROFILE_CONTEXT_DATA *ContextData, + IN EFI_GUID *FileName, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + IN EFI_FV_FILETYPE FileType ) { + RETURN_STATUS PdbStatus; EFI_STATUS Status; MEMORY_PROFILE_DRIVER_INFO *DriverInfo; MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - VOID *EntryPointInImage; - CHAR8 *PdbString; - UINTN PdbSize; + CONST CHAR8 *PdbString; + UINT32 PdbSize; UINTN PdbOccupiedSize; - PdbSize = 0; PdbOccupiedSize = 0; - PdbString = NULL; - if (ImageBase != 0) { - PdbString = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageBase); - if (PdbString != NULL) { - PdbSize = AsciiStrSize (PdbString); - PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64)); - } + + ASSERT (UefiImageLoaderGetImageAddress (ImageContext) != 0); + + PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbString, &PdbSize); + if (!EFI_ERROR (PdbStatus)) { + PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64)); } // @@ -420,19 +314,10 @@ BuildDriverInfo ( CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID)); } - DriverInfo->ImageBase = ImageBase; - DriverInfo->ImageSize = ImageSize; - DriverInfo->EntryPoint = EntryPoint; - DriverInfo->ImageSubsystem = ImageSubsystem; - if ((EntryPoint != 0) && ((EntryPoint < ImageBase) || (EntryPoint >= (ImageBase + ImageSize)))) { - // - // If the EntryPoint is not in the range of image buffer, it should come from emulation environment. - // So patch ImageBuffer here to align the EntryPoint. - // - Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)ImageBase, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverInfo->ImageBase = ImageBase + EntryPoint - (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage; - } + DriverInfo->ImageBase = UefiImageLoaderGetImageAddress (ImageContext); + DriverInfo->ImageSize = UefiImageGetImageSize (ImageContext); + DriverInfo->EntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext); + DriverInfo->ImageSubsystem = UefiImageGetSubsystem (ImageContext); DriverInfo->FileType = FileType; DriverInfoData->AllocInfoList = (LIST_ENTRY *)(DriverInfoData + 1); @@ -440,7 +325,7 @@ BuildDriverInfo ( DriverInfo->CurrentUsage = 0; DriverInfo->PeakUsage = 0; DriverInfo->AllocRecordCount = 0; - if (PdbSize != 0) { + if (!RETURN_ERROR (PdbStatus)) { DriverInfo->PdbStringOffset = (UINT16)sizeof (MEMORY_PROFILE_DRIVER_INFO); DriverInfoData->PdbString = (CHAR8 *)(DriverInfoData->AllocInfoList + 1); CopyMem (DriverInfoData->PdbString, PdbString, PdbSize); @@ -528,13 +413,13 @@ NeedRecordThisDriver ( **/ BOOLEAN RegisterDxeCore ( - IN VOID *HobStart, - IN MEMORY_PROFILE_CONTEXT_DATA *ContextData + IN VOID *HobStart, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + IN MEMORY_PROFILE_CONTEXT_DATA *ContextData ) { EFI_PEI_HOB_POINTERS DxeCoreHob; MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - PHYSICAL_ADDRESS ImageBase; UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)]; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath; @@ -565,14 +450,10 @@ RegisterDxeCore ( return FALSE; } - ImageBase = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress; DriverInfoData = BuildDriverInfo ( ContextData, &DxeCoreHob.MemoryAllocationModule->ModuleName, - ImageBase, - DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength, - DxeCoreHob.MemoryAllocationModule->EntryPoint, - InternalPeCoffGetSubsystem ((VOID *)(UINTN)ImageBase), + ImageContext, EFI_FV_FILETYPE_DXE_CORE ); if (DriverInfoData == NULL) { @@ -590,7 +471,8 @@ RegisterDxeCore ( **/ VOID MemoryProfileInit ( - IN VOID *HobStart + IN VOID *HobStart, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { MEMORY_PROFILE_CONTEXT_DATA *ContextData; @@ -615,7 +497,7 @@ MemoryProfileInit ( mMemoryProfileDriverPath = AllocateCopyPool (mMemoryProfileDriverPathSize, PcdGetPtr (PcdMemoryProfileDriverPath)); mMemoryProfileContextPtr = &mMemoryProfileContext; - RegisterDxeCore (HobStart, &mMemoryProfileContext); + RegisterDxeCore (HobStart, ImageContext, &mMemoryProfileContext); DEBUG ((DEBUG_INFO, "MemoryProfileInit MemoryProfileContext - 0x%x\n", &mMemoryProfileContext)); } @@ -692,8 +574,9 @@ GetFileNameFromFilePath ( **/ EFI_STATUS RegisterMemoryProfileImage ( - IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry, - IN EFI_FV_FILETYPE FileType + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN EFI_FV_FILETYPE FileType, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { MEMORY_PROFILE_CONTEXT_DATA *ContextData; @@ -703,7 +586,7 @@ RegisterMemoryProfileImage ( return EFI_UNSUPPORTED; } - if (!NeedRecordThisDriver (DriverEntry->Info.FilePath)) { + if (!NeedRecordThisDriver (FilePath)) { return EFI_UNSUPPORTED; } @@ -714,11 +597,8 @@ RegisterMemoryProfileImage ( DriverInfoData = BuildDriverInfo ( ContextData, - GetFileNameFromFilePath (DriverEntry->Info.FilePath), - DriverEntry->ImageContext.ImageAddress, - DriverEntry->ImageContext.ImageSize, - DriverEntry->ImageContext.EntryPoint, - DriverEntry->ImageContext.ImageType, + GetFileNameFromFilePath (FilePath), + ImageContext, FileType ); if (DriverInfoData == NULL) { @@ -831,21 +711,21 @@ GetMemoryProfileDriverInfoFromAddress ( **/ EFI_STATUS UnregisterMemoryProfileImage ( - IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry + EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN EFI_PHYSICAL_ADDRESS ImageAddress ) { - EFI_STATUS Status; + //EFI_STATUS Status; MEMORY_PROFILE_CONTEXT_DATA *ContextData; MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; EFI_GUID *FileName; - PHYSICAL_ADDRESS ImageAddress; - VOID *EntryPointInImage; + //VOID *EntryPointInImage; if (!IS_UEFI_MEMORY_PROFILE_ENABLED) { return EFI_UNSUPPORTED; } - if (!NeedRecordThisDriver (DriverEntry->Info.FilePath)) { + if (!NeedRecordThisDriver (FilePath)) { return EFI_UNSUPPORTED; } @@ -855,17 +735,7 @@ UnregisterMemoryProfileImage ( } DriverInfoData = NULL; - FileName = GetFileNameFromFilePath (DriverEntry->Info.FilePath); - ImageAddress = DriverEntry->ImageContext.ImageAddress; - if ((DriverEntry->ImageContext.EntryPoint < ImageAddress) || (DriverEntry->ImageContext.EntryPoint >= (ImageAddress + DriverEntry->ImageContext.ImageSize))) { - // - // If the EntryPoint is not in the range of image buffer, it should come from emulation environment. - // So patch ImageAddress here to align the EntryPoint. - // - Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)ImageAddress, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - ImageAddress = ImageAddress + (UINTN)DriverEntry->ImageContext.EntryPoint - (UINTN)EntryPointInImage; - } + FileName = GetFileNameFromFilePath (FilePath); if (FileName != NULL) { DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageAddress); @@ -1629,27 +1499,13 @@ ProfileProtocolGetData ( EFI_STATUS EFIAPI ProfileProtocolRegisterImage ( - IN EDKII_MEMORY_PROFILE_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, - IN EFI_FV_FILETYPE FileType + IN EDKII_MEMORY_PROFILE_PROTOCOL *This, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + IN EFI_FV_FILETYPE FileType ) { - EFI_STATUS Status; - LOADED_IMAGE_PRIVATE_DATA DriverEntry; - VOID *EntryPointInImage; - - ZeroMem (&DriverEntry, sizeof (DriverEntry)); - DriverEntry.Info.FilePath = FilePath; - DriverEntry.ImageContext.ImageAddress = ImageBase; - DriverEntry.ImageContext.ImageSize = ImageSize; - Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)ImageBase, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverEntry.ImageContext.EntryPoint = (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage; - DriverEntry.ImageContext.ImageType = InternalPeCoffGetSubsystem ((VOID *)(UINTN)ImageBase); - - return RegisterMemoryProfileImage (&DriverEntry, FileType); + return RegisterMemoryProfileImage (FilePath, FileType, ImageContext); } /** @@ -1675,19 +1531,7 @@ ProfileProtocolUnregisterImage ( IN UINT64 ImageSize ) { - EFI_STATUS Status; - LOADED_IMAGE_PRIVATE_DATA DriverEntry; - VOID *EntryPointInImage; - - ZeroMem (&DriverEntry, sizeof (DriverEntry)); - DriverEntry.Info.FilePath = FilePath; - DriverEntry.ImageContext.ImageAddress = ImageBase; - DriverEntry.ImageContext.ImageSize = ImageSize; - Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)ImageBase, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverEntry.ImageContext.EntryPoint = (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage; - - return UnregisterMemoryProfileImage (&DriverEntry); + return UnregisterMemoryProfileImage (FilePath, ImageBase); } /** diff --git a/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c b/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c index eeb18f6e47..d6e732e021 100644 --- a/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c +++ b/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c @@ -160,15 +160,20 @@ CoreUpdateDebugTableCrc32 ( **/ VOID CoreNewDebugImageInfoEntry ( - IN UINT32 ImageInfoType, - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_HANDLE ImageHandle + IN UINT32 ImageInfoType, + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN EFI_HANDLE ImageHandle, + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { - EFI_DEBUG_IMAGE_INFO *Table; - EFI_DEBUG_IMAGE_INFO *NewTable; - UINTN Index; - UINTN TableSize; + EFI_DEBUG_IMAGE_INFO *Table; + EFI_DEBUG_IMAGE_INFO *NewTable; + UINTN Index; + UINTN TableSize; + EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; + RETURN_STATUS Status; + CONST CHAR8 *PdbPath; + UINT32 PdbPathSize; // // Set the flag indicating that we're in the process of updating the table. @@ -205,6 +210,15 @@ CoreNewDebugImageInfoEntry ( // Copy the old table into the new one // CopyMem (NewTable, Table, TableSize); + mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable; + // + // Set the first empty entry index to be the original max table entries. + // + Index = mMaxTableEntries; + // + // Enlarge the max table entries. + // + mMaxTableEntries += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE; // // Free the old table // @@ -212,32 +226,31 @@ CoreNewDebugImageInfoEntry ( // // Update the table header // - Table = NewTable; - mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable; - // - // Enlarge the max table entries and set the first empty entry index to - // be the original max table entries. - // - Index = mMaxTableEntries; - mMaxTableEntries += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE; + Table = NewTable; } // // Allocate data for new entry // - Table[Index].NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL)); - if (Table[Index].NormalImage != NULL) { + NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL)); + if (NormalImage != NULL) { // // Update the entry // - Table[Index].NormalImage->ImageInfoType = (UINT32)ImageInfoType; - Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage; - Table[Index].NormalImage->ImageHandle = ImageHandle; + NormalImage->ImageInfoType = (UINT32)ImageInfoType; + NormalImage->LoadedImageProtocolInstance = LoadedImage; + NormalImage->ImageHandle = ImageHandle; + + Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize); + if (!RETURN_ERROR (Status)) { + NormalImage->PdbPath = AllocateCopyPool (PdbPathSize, PdbPath); + } // // Increase the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status. // - mDebugInfoTableHeader.TableSize++; mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED; + Table[Index].NormalImage = NormalImage; + mDebugInfoTableHeader.TableSize++; } mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; @@ -254,8 +267,9 @@ CoreRemoveDebugImageInfoEntry ( EFI_HANDLE ImageHandle ) { - EFI_DEBUG_IMAGE_INFO *Table; - UINTN Index; + EFI_DEBUG_IMAGE_INFO *Table; + UINTN Index; + EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; @@ -267,13 +281,19 @@ CoreRemoveDebugImageInfoEntry ( // Found a match. Free up the record, then NULL the pointer to indicate the slot // is free. // - CoreFreePool (Table[Index].NormalImage); - Table[Index].NormalImage = NULL; + NormalImage = Table[Index].NormalImage; // // Decrease the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status. // - mDebugInfoTableHeader.TableSize--; mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED; + mDebugInfoTableHeader.TableSize--; + Table[Index].NormalImage = NULL; + + if (NormalImage->PdbPath != NULL) { + FreePool (NormalImage->PdbPath); + } + + CoreFreePool (NormalImage); break; } } diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c index a11c455ab5..670297a339 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c @@ -22,6 +22,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "DxeMain.h" #include "HeapGuard.h" +#include "IndustryStandard/PeImage2.h" +#include "ProcessorBind.h" /** This function for GetMemoryMap() with properties table capability. @@ -73,7 +75,7 @@ CoreGetMemoryMapWithSeparatedImageSection ( typedef struct { UINT32 Signature; UINTN ImageRecordCount; - UINTN CodeSegmentCountMax; + UINTN SectionCountMax; LIST_ENTRY ImageRecordList; } IMAGE_PROPERTIES_PRIVATE_DATA; @@ -201,7 +203,7 @@ InstallMemoryAttributesTable ( case EfiRuntimeServicesCode: case EfiRuntimeServicesData: CopyMem (MemoryAttributesEntry, MemoryMap, DescriptorSize); - MemoryAttributesEntry->Attribute &= (EFI_MEMORY_RO|EFI_MEMORY_XP|EFI_MEMORY_RUNTIME); + MemoryAttributesEntry->Attribute &= EFI_MEMORY_ACCESS_MASK | EFI_MEMORY_RUNTIME; DEBUG ((DEBUG_VERBOSE, "Entry (0x%x)\n", MemoryAttributesEntry)); DEBUG ((DEBUG_VERBOSE, " Type - 0x%x\n", MemoryAttributesEntry->Type)); DEBUG ((DEBUG_VERBOSE, " PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart)); @@ -284,15 +286,6 @@ InstallMemoryAttributesTableOnEndOfDxe ( { mMemoryAttributesTableEndOfDxe = TRUE; InstallMemoryAttributesTable (); - - DEBUG_CODE_BEGIN (); - if ( mImagePropertiesPrivateData.ImageRecordCount > 0) { - DEBUG ((DEBUG_INFO, "DXE - Total Runtime Image Count: 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount)); - DEBUG ((DEBUG_INFO, "DXE - Dump Runtime Image Records:\n")); - DumpImageRecords (&mImagePropertiesPrivateData.ImageRecordList); - } - - DEBUG_CODE_END (); } /** @@ -534,7 +527,11 @@ CoreGetMemoryMapWithSeparatedImageSection ( CoreAcquiremMemoryAttributesTableLock (); - AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount; + // + // Per image, there may be one additional trailer. There may be prefixed data + // (counted as the original entry). + // + AdditionalRecordCount = (mImagePropertiesPrivateData.SectionCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount; OldMemoryMapSize = *MemoryMapSize; Status = CoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion); @@ -574,6 +571,68 @@ CoreGetMemoryMapWithSeparatedImageSection ( // Below functions are for ImageRecord // +/** + Set MemoryAttributesTable according to PE/COFF image section alignment. + + @param SectionAlignment PE/COFF section alignment +**/ +STATIC +VOID +SetMemoryAttributesTableSectionAlignment ( + IN UINT32 SectionAlignment + ) +{ + if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) && + mMemoryAttributesTableEnable) + { + DEBUG ((DEBUG_VERBOSE, "SetMemoryAttributesTableSectionAlignment - Clear\n")); + mMemoryAttributesTableEnable = FALSE; + } +} + +/** + Sort image record based upon the ImageBase from low to high. +**/ +STATIC +VOID +InsertSortImageRecord ( + IN UEFI_IMAGE_RECORD *NewImageRecord + ) +{ + UEFI_IMAGE_RECORD *ImageRecord; + LIST_ENTRY *PrevImageRecordLink; + LIST_ENTRY *ImageRecordLink; + LIST_ENTRY *ImageRecordList; + + ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList; + + PrevImageRecordLink = ImageRecordList; + for ( + ImageRecordLink = GetFirstNode (ImageRecordList); + !IsNull (ImageRecordLink, ImageRecordList); + ImageRecordLink = GetNextNode (ImageRecordList, PrevImageRecordLink) + ) { + ImageRecord = CR ( + ImageRecordLink, + UEFI_IMAGE_RECORD, + Link, + UEFI_IMAGE_RECORD_SIGNATURE + ); + if (NewImageRecord->StartAddress < ImageRecord->StartAddress) { + break; + } + + PrevImageRecordLink = ImageRecordLink; + } + + InsertHeadList (PrevImageRecordLink, &NewImageRecord->Link); + mImagePropertiesPrivateData.ImageRecordCount++; + + if (mImagePropertiesPrivateData.SectionCountMax < NewImageRecord->NumSegments) { + mImagePropertiesPrivateData.SectionCountMax = NewImageRecord->NumSegments; + } +} + /** Insert image record. @@ -581,13 +640,18 @@ CoreGetMemoryMapWithSeparatedImageSection ( **/ VOID InsertImageRecord ( - IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage + IN LOADED_IMAGE_PRIVATE_DATA *Image, + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { - EFI_STATUS Status; - IMAGE_PROPERTIES_RECORD *ImageRecord; - CHAR8 *PdbPointer; - UINT32 RequiredAlignment; + RETURN_STATUS PdbStatus; + EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage; + UINT32 SectionAlignment; + UEFI_IMAGE_RECORD *ImageRecord; + CONST CHAR8 *PdbPointer; + UINT32 PdbSize; + + RuntimeImage = Image->RuntimeData; DEBUG ((DEBUG_VERBOSE, "InsertImageRecord - 0x%x\n", RuntimeImage)); @@ -596,71 +660,85 @@ InsertImageRecord ( return; } - ImageRecord = AllocatePool (sizeof (*ImageRecord)); - if (ImageRecord == NULL) { - return; - } - - InitializeListHead (&ImageRecord->Link); - InitializeListHead (&ImageRecord->CodeSegmentList); + DEBUG ((DEBUG_VERBOSE, "ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount)); - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)RuntimeImage->ImageBase); - if (PdbPointer != NULL) { + PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize); + if (!EFI_ERROR (PdbStatus)) { DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer)); } - RequiredAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; - Status = CreateImagePropertiesRecord ( - RuntimeImage->ImageBase, - RuntimeImage->ImageSize, - &RequiredAlignment, - ImageRecord - ); - - if (EFI_ERROR (Status)) { - if (Status == EFI_ABORTED) { - mMemoryAttributesTableEnable = FALSE; + // + // Get SectionAlignment + // + SectionAlignment = UefiImageGetSegmentAlignment (ImageContext); + + SetMemoryAttributesTableSectionAlignment (SectionAlignment); + if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) { + DEBUG (( + DEBUG_WARN, + "!!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n", + SectionAlignment, RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10)); + if (!EFI_ERROR (PdbStatus)) { + DEBUG ((DEBUG_WARN, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); } - Status = EFI_ABORTED; - goto Finish; + return; } - if (ImageRecord->CodeSegmentCount == 0) { - mMemoryAttributesTableEnable = FALSE; - DEBUG ((DEBUG_ERROR, "!!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n")); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_ERROR, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); - } - - Status = EFI_ABORTED; - goto Finish; + ImageRecord = UefiImageLoaderGetImageRecord (ImageContext); + if (ImageRecord == NULL) { + return ; } + UefiImageDebugPrintSegments (ImageContext); + UefiImageDebugPrintImageRecord (ImageRecord); + // - // Check overlap all section in ImageBase/Size + // Section order is guaranteed by the PE specification. + // Section validity (e.g. no overlap) is guaranteed by the PE specification. // - if (!IsImageRecordCodeSectionValid (ImageRecord)) { - DEBUG ((DEBUG_ERROR, "IsImageRecordCodeSectionValid - FAIL\n")); - Status = EFI_ABORTED; - goto Finish; - } - InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link); - mImagePropertiesPrivateData.ImageRecordCount++; + InsertSortImageRecord (ImageRecord); +} - if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) { - mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount; - } +/** + Find image record according to image base and size. - SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList); + @param ImageBase Base of PE image + @param ImageSize Size of PE image -Finish: - if (EFI_ERROR (Status) && (ImageRecord != NULL)) { - DeleteImagePropertiesRecord (ImageRecord); + @return image record +**/ +STATIC +UEFI_IMAGE_RECORD * +FindImageRecord ( + IN EFI_PHYSICAL_ADDRESS ImageBase + ) +{ + UEFI_IMAGE_RECORD *ImageRecord; + LIST_ENTRY *ImageRecordLink; + LIST_ENTRY *ImageRecordList; + + ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList; + + for (ImageRecordLink = ImageRecordList->ForwardLink; + ImageRecordLink != ImageRecordList; + ImageRecordLink = ImageRecordLink->ForwardLink) + { + ImageRecord = CR ( + ImageRecordLink, + UEFI_IMAGE_RECORD, + Link, + UEFI_IMAGE_RECORD_SIGNATURE + ); + + if (ImageBase == ImageRecord->StartAddress) + { + return ImageRecord; + } } - return; + return NULL; } /** @@ -673,7 +751,7 @@ RemoveImageRecord ( IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage ) { - IMAGE_PROPERTIES_RECORD *ImageRecord; + UEFI_IMAGE_RECORD *ImageRecord; DEBUG ((DEBUG_VERBOSE, "RemoveImageRecord - 0x%x\n", RuntimeImage)); DEBUG ((DEBUG_VERBOSE, "RemoveImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize)); @@ -683,7 +761,7 @@ RemoveImageRecord ( return; } - ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize, &mImagePropertiesPrivateData.ImageRecordList); + ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase); if (ImageRecord == NULL) { DEBUG ((DEBUG_ERROR, "!!!!!!!! ImageRecord not found !!!!!!!!\n")); return; diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 2c069cc12c..2d568b2463 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -40,8 +40,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include +#include "Base.h" #include "DxeMain.h" +#include "Library/UefiImageLib.h" #include "Mem/HeapGuard.h" +#include "ProcessorBind.h" +#include "Uefi/UefiMultiPhase.h" // // Image type definitions @@ -213,113 +217,73 @@ SetUefiImageMemoryAttributes ( **/ VOID SetUefiImageProtectionAttributes ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord + IN UEFI_IMAGE_RECORD *ImageRecord ) { - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - UINT64 CurrentBase; - UINT64 ImageEnd; - - ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; - - CurrentBase = ImageRecord->ImageBase; - ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize; - - ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink; - ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList; - while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection = CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - - ASSERT (CurrentBase <= ImageRecordCodeSection->CodeSegmentBase); - if (CurrentBase < ImageRecordCodeSection->CodeSegmentBase) { - // - // DATA - // - SetUefiImageMemoryAttributes ( - CurrentBase, - ImageRecordCodeSection->CodeSegmentBase - CurrentBase, - EFI_MEMORY_XP - ); - } + UEFI_IMAGE_RECORD_SEGMENT *ImageRecordSegment; + UINTN SectionAddress; + UINT32 Index; - // - // CODE - // + SectionAddress = ImageRecord->StartAddress; + for (Index = 0; Index < ImageRecord->NumSegments; Index++) { + ImageRecordSegment = &ImageRecord->Segments[Index]; SetUefiImageMemoryAttributes ( - ImageRecordCodeSection->CodeSegmentBase, - ImageRecordCodeSection->CodeSegmentSize, - EFI_MEMORY_RO + SectionAddress, + ImageRecordSegment->Size, + ImageRecordSegment->Attributes ); - CurrentBase = ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize; - } - // - // Last DATA - // - ASSERT (CurrentBase <= ImageEnd); - if (CurrentBase < ImageEnd) { - // - // DATA - // - SetUefiImageMemoryAttributes ( - CurrentBase, - ImageEnd - CurrentBase, - EFI_MEMORY_XP - ); + SectionAddress += ImageRecordSegment->Size; } - - return; } /** - Return the section alignment requirement for the PE image section type. - - @param[in] MemoryType PE/COFF image memory type + Return if the PE image section is aligned. - @retval The required section alignment for this memory type + @param[in] SectionAlignment PE/COFF section alignment + @param[in] MemoryType PE/COFF image memory type + @retval TRUE The PE image section is aligned. + @retval FALSE The PE image section is not aligned. **/ STATIC -UINT32 -GetMemoryProtectionSectionAlignment ( +BOOLEAN +IsMemoryProtectionSectionAligned ( + IN UINT32 SectionAlignment, IN EFI_MEMORY_TYPE MemoryType ) { - UINT32 SectionAlignment; + UINT32 PageAlignment; switch (MemoryType) { case EfiRuntimeServicesCode: case EfiACPIMemoryNVS: case EfiReservedMemoryType: - SectionAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; + PageAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; break; case EfiRuntimeServicesData: ASSERT (FALSE); - SectionAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; + PageAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; break; case EfiBootServicesCode: case EfiLoaderCode: - SectionAlignment = EFI_PAGE_SIZE; + PageAlignment = EFI_PAGE_SIZE; break; case EfiACPIReclaimMemory: default: ASSERT (FALSE); - SectionAlignment = EFI_PAGE_SIZE; + PageAlignment = EFI_PAGE_SIZE; break; } - return SectionAlignment; + if ((SectionAlignment & (PageAlignment - 1)) != 0) { + return FALSE; + } else { + return TRUE; + } } +// FIXME: Deduplicate /** Protect UEFI PE/COFF image. @@ -328,22 +292,26 @@ GetMemoryProtectionSectionAlignment ( **/ VOID ProtectUefiImage ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath + IN LOADED_IMAGE_PRIVATE_DATA *Image, + UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { - IMAGE_PROPERTIES_RECORD *ImageRecord; - UINT32 ProtectionPolicy; - EFI_STATUS Status; - UINT32 RequiredAlignment; + RETURN_STATUS PdbStatus; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; + UINT32 SectionAlignment; + UEFI_IMAGE_RECORD *ImageRecord; + CONST CHAR8 *PdbPointer; + UINT32 PdbSize; + BOOLEAN IsAligned; + UINT32 ProtectionPolicy; + + LoadedImage = &Image->Info; + LoadedImageDevicePath = Image->LoadedImageDevicePath; DEBUG ((DEBUG_INFO, "ProtectUefiImageCommon - 0x%x\n", LoadedImage)); DEBUG ((DEBUG_INFO, " - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase, LoadedImage->ImageSize)); - if (gCpu == NULL) { - return; - } - ProtectionPolicy = GetUefiImageProtectionPolicy (LoadedImage, LoadedImageDevicePath); switch (ProtectionPolicy) { case DO_NOT_PROTECT: @@ -355,36 +323,49 @@ ProtectUefiImage ( return; } - ImageRecord = AllocateZeroPool (sizeof (*ImageRecord)); - if (ImageRecord == NULL) { - return; + PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize); + if (!RETURN_ERROR (PdbStatus)) { + DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer)); } - RequiredAlignment = GetMemoryProtectionSectionAlignment (LoadedImage->ImageCodeType); + // + // Get SectionAlignment + // + SectionAlignment = UefiImageGetSegmentAlignment (ImageContext); - Status = CreateImagePropertiesRecord ( - LoadedImage->ImageBase, - LoadedImage->ImageSize, - &RequiredAlignment, - ImageRecord - ); + IsAligned = IsMemoryProtectionSectionAligned (SectionAlignment, LoadedImage->ImageCodeType); + if (!IsAligned) { + DEBUG (( + DEBUG_VERBOSE, + "!!!!!!!! ProtectUefiImageCommon - Section Alignment(0x%x) is incorrect !!!!!!!!\n", + SectionAlignment)); + if (!RETURN_ERROR (PdbStatus)) { + DEBUG ((DEBUG_VERBOSE, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); + } - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a failed to create image properties record\n", __func__)); - FreePool (ImageRecord); goto Finish; } - // - // CPU ARCH present. Update memory attribute directly. - // - SetUefiImageProtectionAttributes (ImageRecord); + ImageRecord = UefiImageLoaderGetImageRecord (ImageContext); + if (ImageRecord == NULL) { + return ; + } + + UefiImageDebugPrintSegments (ImageContext); + UefiImageDebugPrintImageRecord (ImageRecord); // // Record the image record in the list so we can undo the protections later // InsertTailList (&mProtectedImageRecordList, &ImageRecord->Link); + if (gCpu != NULL) { + // + // CPU ARCH present. Update memory attribute directly. + // + SetUefiImageProtectionAttributes (ImageRecord); + } + Finish: return; } @@ -401,30 +382,31 @@ UnprotectUefiImage ( IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath ) { - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; - - if (PcdGet32 (PcdImageProtectionPolicy) != 0) { - for (ImageRecordLink = mProtectedImageRecordList.ForwardLink; - ImageRecordLink != &mProtectedImageRecordList; - ImageRecordLink = ImageRecordLink->ForwardLink) - { - ImageRecord = CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - - if (ImageRecord->ImageBase == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) { + UEFI_IMAGE_RECORD *ImageRecord; + LIST_ENTRY *ImageRecordLink; + + for (ImageRecordLink = mProtectedImageRecordList.ForwardLink; + ImageRecordLink != &mProtectedImageRecordList; + ImageRecordLink = ImageRecordLink->ForwardLink) { + ImageRecord = CR ( + ImageRecordLink, + UEFI_IMAGE_RECORD, + Link, + UEFI_IMAGE_RECORD_SIGNATURE + ); + + if (ImageRecord->StartAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) { + // TODO: Revise for removal (e.g. CpuDxe integration) + if (gCpu != NULL) { SetUefiImageMemoryAttributes ( - ImageRecord->ImageBase, - ImageRecord->ImageSize, + ImageRecord->StartAddress, + ImageRecord->EndAddress - ImageRecord->StartAddress, 0 ); - DeleteImagePropertiesRecord (ImageRecord); - return; } + RemoveEntryList (&ImageRecord->Link); + FreePool (ImageRecord); + return; } } } @@ -567,7 +549,6 @@ MergeMemoryMapForProtectionPolicy ( Remove exec permissions from all regions whose type is identified by PcdDxeNxMemoryProtectionPolicy. **/ -STATIC VOID InitializeDxeNxMemoryProtectionPolicy ( VOID @@ -775,12 +756,9 @@ MemoryProtectionCpuArchProtocolNotify ( IN VOID *Context ) { - EFI_STATUS Status; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; - UINTN NoHandles; - EFI_HANDLE *HandleBuffer; - UINTN Index; + EFI_STATUS Status; + LIST_ENTRY *ImageRecordLink; + UEFI_IMAGE_RECORD *ImageRecord; DEBUG ((DEBUG_INFO, "MemoryProtectionCpuArchProtocolNotify:\n")); Status = CoreLocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu); @@ -804,41 +782,22 @@ MemoryProtectionCpuArchProtocolNotify ( goto Done; } - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiLoadedImageProtocolGuid, - NULL, - &NoHandles, - &HandleBuffer - ); - if (EFI_ERROR (Status) && (NoHandles == 0)) { - goto Done; - } - - for (Index = 0; Index < NoHandles; Index++) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiLoadedImageProtocolGuid, - (VOID **)&LoadedImage - ); - if (EFI_ERROR (Status)) { - continue; - } - - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiLoadedImageDevicePathProtocolGuid, - (VOID **)&LoadedImageDevicePath + for (ImageRecordLink = mProtectedImageRecordList.ForwardLink; + ImageRecordLink != &mProtectedImageRecordList; + ImageRecordLink = ImageRecordLink->ForwardLink) { + ImageRecord = CR ( + ImageRecordLink, + UEFI_IMAGE_RECORD, + Link, + UEFI_IMAGE_RECORD_SIGNATURE ); - if (EFI_ERROR (Status)) { - LoadedImageDevicePath = NULL; - } - ProtectUefiImage (LoadedImage, LoadedImageDevicePath); + // + // CPU ARCH present. Update memory attribute directly. + // + SetUefiImageProtectionAttributes (ImageRecord); } - FreePool (HandleBuffer); - Done: CoreCloseEvent (Event); } diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c index 4073bad82c..da2dcd796f 100644 --- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c +++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c @@ -9,6 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "PeiMain.h" +#include "ProcessorBind.h" // // Utility global variables @@ -1377,8 +1378,7 @@ MigratePeim ( EFI_FFS_FILE_HEADER *FileHeader; VOID *Pe32Data; VOID *ImageAddress; - CHAR8 *AsciiString; - UINTN Index; + UINT32 ImageSize; Status = EFI_SUCCESS; @@ -1386,24 +1386,10 @@ MigratePeim ( ASSERT (!IS_FFS_FILE2 (FileHeader)); ImageAddress = NULL; - PeiGetPe32Data (MigratedFileHandle, &ImageAddress); + PeiGetPe32Data (MigratedFileHandle, &ImageAddress, &ImageSize); if (ImageAddress != NULL) { - DEBUG_CODE_BEGIN (); - AsciiString = PeCoffLoaderGetPdbPointer (ImageAddress); - for (Index = 0; AsciiString[Index] != 0; Index++) { - if ((AsciiString[Index] == '\\') || (AsciiString[Index] == '/')) { - AsciiString = AsciiString + Index + 1; - Index = 0; - } else if (AsciiString[Index] == '.') { - AsciiString[Index] = 0; - } - } - - DEBUG ((DEBUG_VERBOSE, "%a", AsciiString)); - DEBUG_CODE_END (); - Pe32Data = (VOID *)((UINTN)ImageAddress - (UINTN)MigratedFileHandle + (UINTN)FileHandle); - Status = LoadAndRelocatePeCoffImageInPlace (Pe32Data, ImageAddress); + Status = LoadAndRelocateUefiImageInPlace (Pe32Data, ImageAddress, ImageSize); ASSERT_EFI_ERROR (Status); } @@ -1465,6 +1451,104 @@ ConvertStatusCodeCallbacks ( } } +/** + Migrates SEC modules in the given firmware volume. + + Migrating SECURITY_CORE files requires special treatment since they are not tracked for PEI dispatch. + + This functioun should be called after the FV has been copied to its post-memory location and the PEI Core FV list has + been updated. + + @param Private Pointer to the PeiCore's private data structure. + @param FvIndex The firmware volume index to migrate. + @param OrgFvHandle The handle to the firmware volume in temporary memory. + + @retval EFI_SUCCESS SEC modules were migrated successfully + @retval EFI_INVALID_PARAMETER The Private pointer is NULL or FvCount is invalid. + @retval EFI_NOT_FOUND Can't find valid FFS header. + +**/ +EFI_STATUS +EFIAPI +MigrateSecModulesInFv ( + IN PEI_CORE_INSTANCE *Private, + IN UINTN FvIndex, + IN UINTN OrgFvHandle + ) +{ + EFI_STATUS Status; + EFI_STATUS FindFileStatus; + EFI_PEI_FILE_HANDLE MigratedFileHandle; + EFI_PEI_FILE_HANDLE FileHandle; + UINT32 SectionAuthenticationStatus; + UINT32 FileSize; + VOID *OrgPe32SectionData; + VOID *Pe32SectionData; + UINT32 Pe32SectionDataSize; + EFI_FFS_FILE_HEADER *FfsFileHeader; + EFI_COMMON_SECTION_HEADER *Section; + BOOLEAN IsFfs3Fv; + UINTN SectionInstance; + + if (Private == NULL || FvIndex >= Private->FvCount) { + return EFI_INVALID_PARAMETER; + } + + do { + FindFileStatus = PeiFfsFindNextFile ( + GetPeiServicesTablePointer (), + EFI_FV_FILETYPE_SECURITY_CORE, + Private->Fv[FvIndex].FvHandle, + &MigratedFileHandle + ); + if (!EFI_ERROR (FindFileStatus ) && MigratedFileHandle != NULL) { + FileHandle = (EFI_PEI_FILE_HANDLE) ((UINTN) MigratedFileHandle - (UINTN) Private->Fv[FvIndex].FvHandle + OrgFvHandle); + FfsFileHeader = (EFI_FFS_FILE_HEADER *) MigratedFileHandle; + + DEBUG ((DEBUG_VERBOSE, " Migrating SEC_CORE MigratedFileHandle at 0x%x.\n", (UINTN) MigratedFileHandle)); + DEBUG ((DEBUG_VERBOSE, " FileHandle at 0x%x.\n", (UINTN) FileHandle)); + + IsFfs3Fv = CompareGuid (&Private->Fv[FvIndex].FvHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid); + if (IS_FFS_FILE2 (FfsFileHeader)) { + ASSERT (FFS_FILE2_SIZE (FfsFileHeader) > 0x00FFFFFF); + if (!IsFfs3Fv) { + DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name)); + return EFI_NOT_FOUND; + } + Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2)); + FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2); + } else { + Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER)); + FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER); + } + + SectionInstance = 1; + SectionAuthenticationStatus = 0; + Status = ProcessSection ( + GetPeiServicesTablePointer (), + EFI_SECTION_PE32, + &SectionInstance, + Section, + FileSize, + &Pe32SectionData, + &Pe32SectionDataSize, + &SectionAuthenticationStatus, + IsFfs3Fv + ); + + if (!EFI_ERROR (Status)) { + OrgPe32SectionData = (VOID *) ((UINTN) Pe32SectionData - (UINTN) MigratedFileHandle + (UINTN) FileHandle); + DEBUG ((DEBUG_VERBOSE, " PE32 section in migrated file at 0x%x.\n", (UINTN) Pe32SectionData)); + DEBUG ((DEBUG_VERBOSE, " PE32 section in original file at 0x%x.\n", (UINTN) OrgPe32SectionData)); + Status = LoadAndRelocateUefiImageInPlace (OrgPe32SectionData, Pe32SectionData, Pe32SectionDataSize); + ASSERT_EFI_ERROR (Status); + } + } + } while (!EFI_ERROR (FindFileStatus)); + + return EFI_SUCCESS; +} + /** Migrates PEIMs in the given firmware volume. diff --git a/MdeModulePkg/Core/Pei/FwVol/FwVol.c b/MdeModulePkg/Core/Pei/FwVol/FwVol.c index 04bec986e4..f63565ff13 100644 --- a/MdeModulePkg/Core/Pei/FwVol/FwVol.c +++ b/MdeModulePkg/Core/Pei/FwVol/FwVol.c @@ -35,7 +35,8 @@ PEI_FW_VOL_INSTANCE mPeiFfs2FwVol = { PeiFfsFvPpiGetFileInfo2, PeiFfsFvPpiFindSectionByType2, EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE, - EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION + EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION, + PeiFfsFvPpiFindSectionByType3 } }; @@ -52,7 +53,8 @@ PEI_FW_VOL_INSTANCE mPeiFfs3FwVol = { PeiFfsFvPpiGetFileInfo2, PeiFfsFvPpiFindSectionByType2, EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE, - EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION + EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION, + PeiFfsFvPpiFindSectionByType3 } }; @@ -771,6 +773,8 @@ VerifyGuidedSectionGuid ( @param SectionSize The file size to search. @param OutputBuffer A pointer to the discovered section, if successful. NULL if section not found + @param OutputSize The size of the discovered section, if successful. + 0 if section not found @param AuthenticationStatus Updated upon return to point to the authentication status for this section. @param IsFfs3Fv Indicates the FV format. @@ -786,6 +790,7 @@ ProcessSection ( IN EFI_COMMON_SECTION_HEADER *Section, IN UINTN SectionSize, OUT VOID **OutputBuffer, + OUT UINT32 *OutputSize, OUT UINT32 *AuthenticationStatus, IN BOOLEAN IsFfs3Fv ) @@ -803,11 +808,13 @@ ProcessSection ( EFI_GUID *SectionDefinitionGuid; BOOLEAN SectionCached; VOID *TempOutputBuffer; + UINT32 TempOutputSize; UINT32 TempAuthenticationStatus; UINT16 GuidedSectionAttributes; PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); *OutputBuffer = NULL; + *OutputSize = 0; ParsedLength = 0; Index = 0; Status = EFI_NOT_FOUND; @@ -844,10 +851,13 @@ ProcessSection ( // // Got it! // + // FIXME: Size checks if (IS_SECTION2 (Section)) { *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2)); + *OutputSize = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2); } else { *OutputBuffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER)); + *OutputSize = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER); } return EFI_SUCCESS; @@ -894,11 +904,13 @@ ProcessSection ( PpiOutput, PpiOutputSize, &TempOutputBuffer, + &TempOutputSize, &TempAuthenticationStatus, IsFfs3Fv ); if (!EFI_ERROR (Status)) { *OutputBuffer = TempOutputBuffer; + *OutputSize = TempOutputSize; *AuthenticationStatus = TempAuthenticationStatus | Authentication; return EFI_SUCCESS; } @@ -981,11 +993,13 @@ ProcessSection ( PpiOutput, PpiOutputSize, &TempOutputBuffer, + &TempOutputSize, &TempAuthenticationStatus, IsFfs3Fv ); if (!EFI_ERROR (Status)) { *OutputBuffer = TempOutputBuffer; + *OutputSize = TempOutputSize; *AuthenticationStatus = TempAuthenticationStatus | Authentication; return EFI_SUCCESS; } @@ -1072,6 +1086,38 @@ PeiFfsFindSectionData3 ( OUT VOID **SectionData, OUT UINT32 *AuthenticationStatus ) +{ + UINT32 SectionDataSize; + + return PeiFfsFindSectionData4 (PeiServices, SectionType, SectionInstance, FileHandle, SectionData, &SectionDataSize, AuthenticationStatus); +} + +/** + Searches for the next matching section within the specified file. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param SectionType The value of the section type to find. + @param SectionInstance Section instance to find. + @param FileHandle Handle of the firmware file to search. + @param SectionData A pointer to the discovered section, if successful. + @param SectionDataSize The size of the discovered section, if successful. + @param AuthenticationStatus A pointer to the authentication status for this section. + + @retval EFI_SUCCESS The section was found. + @retval EFI_NOT_FOUND The section was not found. + +**/ +EFI_STATUS +EFIAPI +PeiFfsFindSectionData4 ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_SECTION_TYPE SectionType, + IN UINTN SectionInstance, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData, + OUT UINT32 *SectionDataSize, + OUT UINT32 *AuthenticationStatus + ) { PEI_CORE_FV_HANDLE *CoreFvHandle; @@ -1083,7 +1129,7 @@ PeiFfsFindSectionData3 ( if ((CoreFvHandle->FvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) && (CoreFvHandle->FvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION)) { - return CoreFvHandle->FvPpi->FindSectionByType2 (CoreFvHandle->FvPpi, SectionType, SectionInstance, FileHandle, SectionData, AuthenticationStatus); + return CoreFvHandle->FvPpi->FindSectionByType3 (CoreFvHandle->FvPpi, SectionType, SectionInstance, FileHandle, SectionData, SectionDataSize, AuthenticationStatus); } // @@ -2040,6 +2086,57 @@ PeiFfsFvPpiFindSectionByType2 ( OUT VOID **SectionData, OUT UINT32 *AuthenticationStatus ) +{ + UINT32 SectionDataSize; + + // FIXME: Deprecate + return PeiFfsFvPpiFindSectionByType3 ( + This, + SearchType, + SearchInstance, + FileHandle, + SectionData, + &SectionDataSize, + AuthenticationStatus + ); +} + +/** + Find the next matching section in the firmware file. + + This service enables PEI modules to discover sections + of a given instance and type within a valid file. + + @param This Points to this instance of the + EFI_PEI_FIRMWARE_VOLUME_PPI. + @param SearchType A filter to find only sections of this + type. + @param SearchInstance A filter to find the specific instance + of sections. + @param FileHandle Handle of firmware file in which to + search. + @param SectionData Updated upon return to point to the + section found. + @param SectionDataSize Updated upon return to point to the + section size found. + @param AuthenticationStatus Updated upon return to point to the + authentication status for this section. + + @retval EFI_SUCCESS Section was found. + @retval EFI_NOT_FOUND Section of the specified type was not + found. SectionData contains NULL. +**/ +EFI_STATUS +EFIAPI +PeiFfsFvPpiFindSectionByType3 ( + IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, + IN EFI_SECTION_TYPE SearchType, + IN UINTN SearchInstance, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData, + OUT UINT32 *SectionDataSize, + OUT UINT32 *AuthenticationStatus + ) { EFI_STATUS Status; EFI_FFS_FILE_HEADER *FfsFileHeader; @@ -2089,6 +2186,7 @@ PeiFfsFvPpiFindSectionByType2 ( Section, FileSize, SectionData, + SectionDataSize, &ExtractedAuthenticationStatus, FwVolInstance->IsFfs3Fv ); diff --git a/MdeModulePkg/Core/Pei/FwVol/FwVol.h b/MdeModulePkg/Core/Pei/FwVol/FwVol.h index 7d1dc9cba1..02a732845e 100644 --- a/MdeModulePkg/Core/Pei/FwVol/FwVol.h +++ b/MdeModulePkg/Core/Pei/FwVol/FwVol.h @@ -185,6 +185,43 @@ PeiFfsFvPpiFindSectionByType2 ( OUT UINT32 *AuthenticationStatus ); +/** + Find the next matching section in the firmware file. + + This service enables PEI modules to discover sections + of a given instance and type within a valid file. + + @param This Points to this instance of the + EFI_PEI_FIRMWARE_VOLUME_PPI. + @param SearchType A filter to find only sections of this + type. + @param SearchInstance A filter to find the specific instance + of sections. + @param FileHandle Handle of firmware file in which to + search. + @param SectionData Updated upon return to point to the + section found. + @param SectionDataSize Updated upon return to point to the + section size found. + @param AuthenticationStatus Updated upon return to point to the + authentication status for this section. + + @retval EFI_SUCCESS Section was found. + @retval EFI_NOT_FOUND Section of the specified type was not + found. SectionData contains NULL. +**/ +EFI_STATUS +EFIAPI +PeiFfsFvPpiFindSectionByType3 ( + IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, + IN EFI_SECTION_TYPE SearchType, + IN UINTN SearchInstance, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData, + OUT UINT32 *SectionDataSize, + OUT UINT32 *AuthenticationStatus + ); + /** Returns information about a specific file. diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c index cee9f09c6e..ca57bfaefc 100644 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ b/MdeModulePkg/Core/Pei/Image/Image.c @@ -18,40 +18,6 @@ EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = { &mPeiLoadImagePpi }; -/** - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file. - The function is used for XIP code to have optimized memory copy. - - @param FileHandle - The handle to the PE/COFF file - @param FileOffset - The offset, in bytes, into the file to read - @param ReadSize - The number of bytes to read from the file starting at FileOffset - @param Buffer - A pointer to the buffer to read the data into. - - @return EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - -**/ -EFI_STATUS -EFIAPI -PeiImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN UINTN *ReadSize, - OUT VOID *Buffer - ) -{ - CHAR8 *Destination8; - CHAR8 *Source8; - - Destination8 = Buffer; - Source8 = (CHAR8 *)((UINTN)FileHandle + FileOffset); - if (Destination8 != Source8) { - CopyMem (Destination8, Source8, *ReadSize); - } - - return EFI_SUCCESS; -} - /** To check memory usage bit map array to figure out if the memory range the image will be loaded in is available or not. If memory range is available, the function will mark the corresponding bits to 1 which indicates the memory range is used. @@ -135,111 +101,36 @@ CheckAndMarkFixLoadingMemoryUsageBitMap ( **/ EFI_STATUS -GetPeCoffImageFixLoadingAssignedAddress ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN PEI_CORE_INSTANCE *Private +GetUefiImageFixLoadingAssignedAddress ( + OUT EFI_PHYSICAL_ADDRESS *LoadAddress, + IN UINT64 ValueInSectionHeader, + IN UINT32 ImageDestSize, + IN PEI_CORE_INSTANCE *Private ) { - UINTN SectionHeaderOffset; - EFI_STATUS Status; - EFI_IMAGE_SECTION_HEADER SectionHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - EFI_PHYSICAL_ADDRESS FixLoadingAddress; - UINT16 Index; - UINTN Size; - UINT16 NumberOfSections; - UINT64 ValueInSectionHeader; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS FixLoadingAddress; - FixLoadingAddress = 0; - Status = EFI_NOT_FOUND; - - // - // Get PeHeader pointer - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset); - if (ImageContext->IsTeImage) { + if ((INT64)PcdGet64(PcdLoadModuleAtFixAddressEnable) > 0) { // - // for TE image, the fix loading address is saved in first section header that doesn't point - // to code section. + // When LMFA feature is configured as Load Module at Fixed Absolute Address mode, PointerToRelocations & PointerToLineNumbers field + // hold the absolute address of image base running in memory // - SectionHeaderOffset = sizeof (EFI_TE_IMAGE_HEADER); - NumberOfSections = ImgHdr->Te.NumberOfSections; + FixLoadingAddress = ValueInSectionHeader; } else { - SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader; - NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections; - } - - // - // Get base address from the first section header that doesn't point to code section. - // - for (Index = 0; Index < NumberOfSections; Index++) { // - // Read section header from file + // When LMFA feature is configured as Load Module at Fixed offset mode, PointerToRelocations & PointerToLineNumbers field + // hold the offset relative to a platform-specific top address. // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EFI_NOT_FOUND; - - if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) { - // - // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header - // that doesn't point to code section in image header, as well as ImageBase field of image header. A notable thing is - // that for PEIM, the value in ImageBase field may not be equal to the value in PointerToRelocations & PointerToLineNumbers because - // for XIP PEIM, ImageBase field holds the image base address running on the Flash. And PointerToRelocations & PointerToLineNumbers - // hold the image base address when it is shadow to the memory. And there is an assumption that when the feature is enabled, if a - // module is assigned a loading address by tools, PointerToRelocations & PointerToLineNumbers fields should NOT be Zero, or - // else, these 2 fields should be set to Zero - // - ValueInSectionHeader = ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations); - if (ValueInSectionHeader != 0) { - // - // Found first section header that doesn't point to code section. - // - if ((INT64)PcdGet64 (PcdLoadModuleAtFixAddressEnable) > 0) { - // - // When LMFA feature is configured as Load Module at Fixed Absolute Address mode, PointerToRelocations & PointerToLineNumbers field - // hold the absolute address of image base running in memory - // - FixLoadingAddress = ValueInSectionHeader; - } else { - // - // When LMFA feature is configured as Load Module at Fixed offset mode, PointerToRelocations & PointerToLineNumbers field - // hold the offset relative to a platform-specific top address. - // - FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(Private->LoadModuleAtFixAddressTopAddress + (INT64)ValueInSectionHeader); - } - - // - // Check if the memory range is available. - // - Status = CheckAndMarkFixLoadingMemoryUsageBitMap (Private, FixLoadingAddress, (UINT32)ImageContext->ImageSize); - if (!EFI_ERROR (Status)) { - // - // The assigned address is valid. Return the specified loading address - // - ImageContext->ImageAddress = FixLoadingAddress; - } - } - - break; - } - - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); + FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(Private->LoadModuleAtFixAddressTopAddress + ValueInSectionHeader); } + // + // Check if the memory range is available. + // + Status = CheckAndMarkFixLoadingMemoryUsageBitMap (Private, FixLoadingAddress, ImageDestSize); + *LoadAddress = FixLoadingAddress; - DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status= %r \n", (VOID *)(UINTN)FixLoadingAddress, Status)); + DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status= %r \n", (VOID *)(UINTN)FixLoadingAddress, Status)); return Status; } @@ -262,38 +153,49 @@ GetPeCoffImageFixLoadingAssignedAddress ( **/ EFI_STATUS -LoadAndRelocatePeCoffImage ( +LoadAndRelocateUefiImage ( IN EFI_PEI_FILE_HANDLE FileHandle, IN VOID *Pe32Data, - OUT EFI_PHYSICAL_ADDRESS *ImageAddress, - OUT UINT64 *ImageSize, - OUT EFI_PHYSICAL_ADDRESS *EntryPoint + IN UINT32 Pe32DataSize, + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + OUT EFI_PHYSICAL_ADDRESS *ImageAddress ) { EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + BOOLEAN Success; PEI_CORE_INSTANCE *Private; - UINT64 AlignImageSize; + UINT32 ImageSize; + UINT32 ImageAlignment; + UINT64 ValueInSectionHeader; BOOLEAN IsXipImage; EFI_STATUS ReturnStatus; BOOLEAN IsS3Boot; BOOLEAN IsPeiModule; BOOLEAN IsRegisterForShadow; EFI_FV_FILE_INFO FileInfo; + UINT32 DestinationPages; + UINT32 DestinationSize; + EFI_PHYSICAL_ADDRESS Destination; + UINT16 Machine; + BOOLEAN LoadDynamically; Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ()); ReturnStatus = EFI_SUCCESS; - IsXipImage = FALSE; - ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.Handle = Pe32Data; - ImageContext.ImageRead = PeiImageRead; - Status = PeCoffLoaderGetImageInfo (&ImageContext); + Status = UefiImageInitializeContext (ImageContext, Pe32Data, Pe32DataSize); if (EFI_ERROR (Status)) { return Status; } + Machine = UefiImageGetMachine (ImageContext); + + if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) { + if (!EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (Machine)) { + return EFI_UNSUPPORTED; + } + } + // // Initialize local IsS3Boot and IsRegisterForShadow variable // @@ -312,9 +214,7 @@ LoadAndRelocatePeCoffImage ( // // XIP image that ImageAddress is same to Image handle. // - if (ImageContext.ImageAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data) { - IsXipImage = TRUE; - } + IsXipImage = UefiImageImageIsInplace (ImageContext); // // Get file type first @@ -336,7 +236,7 @@ LoadAndRelocatePeCoffImage ( // // When Image has no reloc section, it can't be relocated into memory. // - if (ImageContext.RelocationsStripped && (Private->PeiMemoryInstalled) && + if (UefiImageGetRelocsStripped (ImageContext) && (Private->PeiMemoryInstalled) && ((!IsPeiModule) || PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) || (!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) || (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot))) @@ -345,125 +245,95 @@ LoadAndRelocatePeCoffImage ( DEBUG ((DEBUG_INFO|DEBUG_LOAD, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN)Pe32Data)); } - // - // Set default base address to current image address. - // - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data; + LoadDynamically = FALSE; + ImageSize = UefiImageGetImageSize (ImageContext); + DestinationPages = EFI_SIZE_TO_PAGES (ImageSize); + DestinationSize = EFI_PAGES_TO_SIZE (DestinationPages); // // Allocate Memory for the image when memory is ready, and image is relocatable. // On normal boot, PcdShadowPeimOnBoot decides whether load PEIM or PeiCore into memory. // On S3 boot, PcdShadowPeimOnS3Boot decides whether load PEIM or PeiCore into memory. // - if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) && + if ((!UefiImageGetRelocsStripped (ImageContext)) && (Private->PeiMemoryInstalled) && ((!IsPeiModule) || PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) || (!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) || (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot))) ) { - // - // Allocate more buffer to avoid buffer overflow. - // - if (ImageContext.IsTeImage) { - AlignImageSize = ImageContext.ImageSize + ((EFI_TE_IMAGE_HEADER *)Pe32Data)->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER); - } else { - AlignImageSize = ImageContext.ImageSize; - } + Success = FALSE; - if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) { - AlignImageSize += ImageContext.SectionAlignment; - } + if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) { + Status = UefiImageGetFixedAddress (ImageContext, &ValueInSectionHeader); + if (!RETURN_ERROR (Status)) { + Status = GetUefiImageFixLoadingAssignedAddress(&Destination, ValueInSectionHeader, DestinationSize, Private); + } - if ((PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) { - Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext, Private); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n")); - // - // The PEIM is not assigned valid address, try to allocate page to load it. - // - Status = PeiServicesAllocatePages ( - EfiBootServicesCode, - EFI_SIZE_TO_PAGES ((UINT32)AlignImageSize), - &ImageContext.ImageAddress - ); + if (!EFI_ERROR (Status)){ + Success = Destination == UefiImageGetPreferredAddress (ImageContext); + + if (!Success) { + DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since relocs have been stripped.\n")); + } + } else { + DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n")); } - } else { - Status = PeiServicesAllocatePages ( - EfiBootServicesCode, - EFI_SIZE_TO_PAGES ((UINT32)AlignImageSize), - &ImageContext.ImageAddress - ); } - if (!EFI_ERROR (Status)) { + if (!Success) { // - // Adjust the Image Address to make sure it is section alignment. + // Allocate more buffer to avoid buffer overflow. // - if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) { - ImageContext.ImageAddress = - (ImageContext.ImageAddress + ImageContext.SectionAlignment - 1) & - ~((UINTN)ImageContext.SectionAlignment - 1); - } + ImageAlignment = UefiImageGetSegmentAlignment (ImageContext); + + Destination = (UINTN)AllocateAlignedCodePages ( + DestinationPages, + ImageAlignment + ); + Success = Destination != 0; + } + if (Success) { + LoadDynamically = TRUE; // - // Fix alignment requirement when Load IPF TeImage into memory. - // Skip the reserved space for the stripped PeHeader when load TeImage into memory. + // Load the image to our new buffer // - if (ImageContext.IsTeImage) { - ImageContext.ImageAddress = ImageContext.ImageAddress + - ((EFI_TE_IMAGE_HEADER *)Pe32Data)->StrippedSize - - sizeof (EFI_TE_IMAGE_HEADER); + Status = UefiImageLoadImageForExecution ( + ImageContext, + (VOID *) (UINTN)Destination, + DestinationSize, + NULL, + 0 + ); + if (EFI_ERROR (Status)) { + return Status; } } else { // // No enough memory resource. // - if (IsXipImage) { - // - // XIP image can still be invoked. - // - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data; - ReturnStatus = EFI_WARN_BUFFER_TOO_SMALL; - } else { + if (!IsXipImage) { // // Non XIP image can't be loaded because no enough memory is allocated. // ASSERT (FALSE); return EFI_OUT_OF_RESOURCES; } + // + // XIP image can still be invoked. + // + ReturnStatus = EFI_WARN_BUFFER_TOO_SMALL; } } - // - // Load the image to our new buffer - // - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - if (ImageContext.ImageError == IMAGE_ERROR_INVALID_SECTION_ALIGNMENT) { - DEBUG ((DEBUG_ERROR, "PEIM Image Address 0x%11p doesn't meet with section alignment 0x%x.\n", (VOID *)(UINTN)ImageContext.ImageAddress, ImageContext.SectionAlignment)); + if (!LoadDynamically) { + Status = UefiImageLoadImageInplace (ImageContext); + if (EFI_ERROR (Status)) { + return Status; } - - return Status; } - // - // Relocate the image in our new buffer - // - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Flush the instruction cache so the image data is written before we execute it - // - if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data) { - InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); - } - - *ImageAddress = ImageContext.ImageAddress; - *ImageSize = ImageContext.ImageSize; - *EntryPoint = ImageContext.EntryPoint; + *ImageAddress = UefiImageLoaderGetImageAddress (ImageContext); return ReturnStatus; } @@ -479,50 +349,30 @@ LoadAndRelocatePeCoffImage ( **/ EFI_STATUS -LoadAndRelocatePeCoffImageInPlace ( +LoadAndRelocateUefiImageInPlace ( IN VOID *Pe32Data, - IN VOID *ImageAddress + IN VOID *ImageAddress, + IN UINT32 ImageSize ) { EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; - ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.Handle = Pe32Data; - ImageContext.ImageRead = PeiImageRead; + ASSERT (Pe32Data != ImageAddress); - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - - ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)ImageAddress; - - // - // Load the image in place - // - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } + CopyMem (ImageAddress, Pe32Data, ImageSize); - // - // Relocate the image in place - // - Status = PeCoffLoaderRelocateImage (&ImageContext); + Status = UefiImageInitializeContext (&ImageContext, ImageAddress, ImageSize); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } // - // Flush the instruction cache so the image data is written before we execute it + // Load the image in place // - if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data) { - InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); - } + Status = UefiImageRelocateImageInplaceForExecution (&ImageContext); + ASSERT_EFI_ERROR (Status); return Status; } @@ -540,7 +390,8 @@ LoadAndRelocatePeCoffImageInPlace ( EFI_STATUS PeiGetPe32Data ( IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **Pe32Data + OUT VOID **Pe32Data, + OUT UINT32 *Pe32DataSize ) { EFI_STATUS Status; @@ -562,22 +413,24 @@ PeiGetPe32Data ( // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst // is true, TE will be searched first). // - Status = PeiServicesFfsFindSectionData3 ( + Status = PeiServicesFfsFindSectionData4 ( SearchType1, 0, FileHandle, Pe32Data, + Pe32DataSize, &AuthenticationState ); // // If we didn't find a first exe section, try to find the second exe section. // if (EFI_ERROR (Status)) { - Status = PeiServicesFfsFindSectionData3 ( + Status = PeiServicesFfsFindSectionData4 ( SearchType2, 0, FileHandle, Pe32Data, + Pe32DataSize, &AuthenticationState ); } @@ -617,15 +470,13 @@ PeiLoadImageLoadImage ( { EFI_STATUS Status; VOID *Pe32Data; + UINT32 Pe32DataSize; EFI_PHYSICAL_ADDRESS ImageAddress; - UINT64 ImageSize; - EFI_PHYSICAL_ADDRESS ImageEntryPoint; - UINT16 Machine; EFI_SECTION_TYPE SearchType1; EFI_SECTION_TYPE SearchType2; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; *EntryPoint = 0; - ImageSize = 0; *AuthenticationState = 0; if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) { @@ -640,22 +491,24 @@ PeiLoadImageLoadImage ( // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst // is true, TE will be searched first). // - Status = PeiServicesFfsFindSectionData3 ( + Status = PeiServicesFfsFindSectionData4 ( SearchType1, 0, FileHandle, &Pe32Data, + &Pe32DataSize, AuthenticationState ); // // If we didn't find a first exe section, try to find the second exe section. // if (EFI_ERROR (Status)) { - Status = PeiServicesFfsFindSectionData3 ( + Status = PeiServicesFfsFindSectionData4 ( SearchType2, 0, FileHandle, &Pe32Data, + &Pe32DataSize, AuthenticationState ); if (EFI_ERROR (Status)) { @@ -672,12 +525,12 @@ PeiLoadImageLoadImage ( // // If memory is installed, perform the shadow operations // - Status = LoadAndRelocatePeCoffImage ( + Status = LoadAndRelocateUefiImage ( FileHandle, Pe32Data, - &ImageAddress, - &ImageSize, - &ImageEntryPoint + Pe32DataSize, + &ImageContext, + &ImageAddress ); if (EFI_ERROR (Status)) { @@ -687,83 +540,47 @@ PeiLoadImageLoadImage ( // // Got the entry point from the loaded Pe32Data // - Pe32Data = (VOID *)((UINTN)ImageAddress); - *EntryPoint = ImageEntryPoint; - - Machine = PeCoffLoaderGetMachineType (Pe32Data); - - if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) { - if (!EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (Machine)) { - return EFI_UNSUPPORTED; - } - } + *EntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext); if (ImageAddressArg != NULL) { *ImageAddressArg = ImageAddress; } if (ImageSizeArg != NULL) { - *ImageSizeArg = ImageSize; + *ImageSizeArg =UefiImageGetImageSize (&ImageContext); } DEBUG_CODE_BEGIN (); - CHAR8 *AsciiString; - CHAR8 EfiFileName[512]; - INT32 Index; - INT32 StartIndex; + CHAR8 EfiFileName[512]; + UINT16 Machine; + + Machine = UefiImageGetMachine (&ImageContext); - // - // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi - // - if (Machine != EFI_IMAGE_MACHINE_IA64) { - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)*EntryPoint)); - } else { // - // For IPF Image, the real entry point should be print. + // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi // - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint))); - } - - // - // Print Module Name by PeImage PDB file name. - // - AsciiString = PeCoffLoaderGetPdbPointer (Pe32Data); - - if (AsciiString != NULL) { - StartIndex = 0; - for (Index = 0; AsciiString[Index] != 0; Index++) { - if ((AsciiString[Index] == '\\') || (AsciiString[Index] == '/')) { - StartIndex = Index + 1; - } + if (Machine != EFI_IMAGE_MACHINE_IA64) { + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)*EntryPoint)); + } else { + // + // For IPF Image, the real entry point should be print. + // + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint))); } // - // Copy the PDB file name to our temporary string, and replace .pdb with .efi - // The PDB file name is limited in the range of 0~511. - // If the length is bigger than 511, trim the redundant characters to avoid overflow in array boundary. + // Print Module Name by PeImage PDB file name. // - for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) { - EfiFileName[Index] = AsciiString[Index + StartIndex]; - if (EfiFileName[Index] == 0) { - EfiFileName[Index] = '.'; - } - - if (EfiFileName[Index] == '.') { - EfiFileName[Index + 1] = 'e'; - EfiFileName[Index + 2] = 'f'; - EfiFileName[Index + 3] = 'i'; - EfiFileName[Index + 4] = 0; - break; - } - } + Status = UefiImageGetModuleNameFromSymbolsPath ( + &ImageContext, + EfiFileName, + sizeof (EfiFileName) + ); - if (Index == sizeof (EfiFileName) - 4) { - EfiFileName[Index] = 0; + if (!RETURN_ERROR (Status)) { + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); } - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); - } - DEBUG_CODE_END (); DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n")); @@ -814,7 +631,7 @@ PeiLoadImageLoadImageWrapper ( @retval FALSE Relocation is not stripped. **/ -BOOLEAN +/*BOOLEAN RelocationIsStrip ( IN VOID *Pe32Data ) @@ -863,7 +680,7 @@ RelocationIsStrip ( } return FALSE; -} +}*/ /** Routine to load image file for subsequent execution by LoadFile Ppi. @@ -896,9 +713,9 @@ PeiLoadImage ( EFI_PEI_LOAD_FILE_PPI *LoadFile; EFI_PHYSICAL_ADDRESS ImageAddress; UINT64 ImageSize; - BOOLEAN IsStrip; + //BOOLEAN IsStrip; - IsStrip = FALSE; + //IsStrip = FALSE; // // If any instances of PEI_LOAD_FILE_PPI are installed, they are called. // one at a time, until one reports EFI_SUCCESS. @@ -924,7 +741,9 @@ PeiLoadImage ( // // The shadowed PEIM must be relocatable. // - if (PeimState == PEIM_STATE_REGISTER_FOR_SHADOW) { + // FIXME: + /*if (PeimState == PEIM_STATE_REGISTER_FOR_SHADOW) { + // FIXME: Assumes headers were loaded into the image memory IsStrip = RelocationIsStrip ((VOID *)(UINTN)ImageAddress); ASSERT (!IsStrip); if (IsStrip) { @@ -935,10 +754,10 @@ PeiLoadImage ( // // The image to be started must have the machine type supported by PeiCore. // - ASSERT (EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *)(UINTN)ImageAddress))); - if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *)(UINTN)ImageAddress))) { + ASSERT (EFI_IMAGE_MACHINE_TYPE_SUPPORTED (UefiImageLoaderGetMachineType ((VOID *)(UINTN)ImageAddress))); + if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (UefiImageLoaderGetMachineType ((VOID *)(UINTN)ImageAddress))) { return EFI_UNSUPPORTED; - } + }*/ return EFI_SUCCESS; } diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h index 278e5a1087..278b6692da 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.h +++ b/MdeModulePkg/Core/Pei/PeiMain.h @@ -36,12 +36,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include -#include +#include #include #include #include -#include +#include #include #include #include @@ -312,7 +311,7 @@ struct _PEI_CORE_INSTANCE { // // This field points to the shadowed image read function // - PE_COFF_LOADER_READ_FILE ShadowedImageRead; + VOID *ShadowedImageRead; UINTN TempPeimCount; @@ -929,6 +928,8 @@ PeiFfsFindNextFile ( @param SectionSize The file size to search. @param OutputBuffer A pointer to the discovered section, if successful. NULL if section not found. + @param OutputSize The size of the discovered section, if successful. + 0 if section not found @param AuthenticationStatus Updated upon return to point to the authentication status for this section. @param IsFfs3Fv Indicates the FV format. @@ -944,6 +945,7 @@ ProcessSection ( IN EFI_COMMON_SECTION_HEADER *Section, IN UINTN SectionSize, OUT VOID **OutputBuffer, + OUT UINT32 *OutputSize, OUT UINT32 *AuthenticationStatus, IN BOOLEAN IsFfs3Fv ); @@ -995,6 +997,33 @@ PeiFfsFindSectionData3 ( OUT UINT32 *AuthenticationStatus ); +/** + Searches for the next matching section within the specified file. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param SectionType The value of the section type to find. + @param SectionInstance Section instance to find. + @param FileHandle Handle of the firmware file to search. + @param SectionData A pointer to the discovered section, if successful. + @param SectionDataSize The size of the discovered section, if successful. + @param AuthenticationStatus A pointer to the authentication status for this section. + + @retval EFI_SUCCESS The section was found. + @retval EFI_NOT_FOUND The section was not found. + +**/ +EFI_STATUS +EFIAPI +PeiFfsFindSectionData4 ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_SECTION_TYPE SectionType, + IN UINTN SectionInstance, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData, + OUT UINT32 *SectionDataSize, + OUT UINT32 *AuthenticationStatus + ); + /** Search the firmware volumes by index @@ -1417,9 +1446,10 @@ InitializeImageServices ( **/ EFI_STATUS -LoadAndRelocatePeCoffImageInPlace ( +LoadAndRelocateUefiImageInPlace ( IN VOID *Pe32Data, - IN VOID *ImageAddress + IN VOID *ImageAddress, + IN UINT32 ImageSize ); /** @@ -1435,7 +1465,8 @@ LoadAndRelocatePeCoffImageInPlace ( EFI_STATUS PeiGetPe32Data ( IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **Pe32Data + OUT VOID **Pe32Data, + OUT UINT32 *Pe32DataSize ); /** diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf index 4cd58ee3aa..46d7e1c453 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.inf +++ b/MdeModulePkg/Core/Pei/PeiMain.inf @@ -53,7 +53,6 @@ [LibraryClasses] BaseMemoryLib - PeCoffGetEntryPointLib ReportStatusCodeLib PeiServicesLib PerformanceLib @@ -63,7 +62,7 @@ DebugLib MemoryAllocationLib CacheMaintenanceLib - PeCoffLib + UefiImageLib PeiServicesTablePointerLib PcdLib TimerLib diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c index ff65e69f52..fb1b989038 100644 --- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c +++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c @@ -65,6 +65,7 @@ EFI_PEI_SERVICES gPs = { PeiFfsGetFileInfo2, PeiResetSystem2, PeiFreePages, + PeiFfsFindSectionData4 }; /** diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c b/MdeModulePkg/Core/Pei/Ppi/Ppi.c index 0e85264ddb..0184f206b9 100644 --- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c +++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c @@ -1082,14 +1082,16 @@ ConvertPeiCorePpiPointers ( IN PEI_CORE_FV_HANDLE *CoreFvHandle ) { - EFI_FV_FILE_INFO FileInfo; - EFI_PHYSICAL_ADDRESS OrgImageBase; - EFI_PHYSICAL_ADDRESS MigratedImageBase; - UINTN PeiCoreModuleSize; - EFI_PEI_FILE_HANDLE PeiCoreFileHandle; - VOID *PeiCoreImageBase; - VOID *PeiCoreEntryPoint; - EFI_STATUS Status; + EFI_FV_FILE_INFO FileInfo; + EFI_PHYSICAL_ADDRESS OrgImageBase; + EFI_PHYSICAL_ADDRESS MigratedImageBase; + UINTN PeiCoreModuleSize; + EFI_PEI_FILE_HANDLE PeiCoreFileHandle; + VOID *PeiCoreImageBase; + UINT32 PeiCoreImageSize; + //VOID *PeiCoreEntryPoint; + EFI_STATUS Status; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; PeiCoreFileHandle = NULL; @@ -1108,17 +1110,18 @@ ConvertPeiCorePpiPointers ( Status = CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, PeiCoreFileHandle, &FileInfo); ASSERT_EFI_ERROR (Status); - Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase); + Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase, &PeiCoreImageSize); ASSERT_EFI_ERROR (Status); // // Find PEI Core EntryPoint in the BFV in temporary memory. // - Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, &PeiCoreEntryPoint); + // FIXME: "Assume" sanity and skip full initialisation? + Status = UefiImageInitializeContext (&ImageContext, (VOID *) (UINTN) PeiCoreImageBase, PeiCoreImageSize); ASSERT_EFI_ERROR (Status); OrgImageBase = (UINTN)PeiCoreImageBase; - MigratedImageBase = (UINTN)_ModuleEntryPoint - ((UINTN)PeiCoreEntryPoint - (UINTN)PeiCoreImageBase); + MigratedImageBase = (UINTN)_ModuleEntryPoint - UefiImageGetEntryPointAddress (&ImageContext); // // Size of loaded PEI_CORE in permanent memory. diff --git a/MdeModulePkg/Core/PiSmmCore/DebugImageInfo.c b/MdeModulePkg/Core/PiSmmCore/DebugImageInfo.c new file mode 100644 index 0000000000..1812eacc2d --- /dev/null +++ b/MdeModulePkg/Core/PiSmmCore/DebugImageInfo.c @@ -0,0 +1,153 @@ +/** @file + Support functions for managing debug image info table when loading and unloading + images. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiSmmCore.h" + +// FIXME: Unify with DXE + +EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugInfoTableHeader = { + 0, // volatile UINT32 UpdateStatus; + 0, // UINT32 TableSize; + NULL // EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable; +}; + +UINTN mMaxTableEntries = 0; + +#define EFI_DEBUG_TABLE_ENTRY_SIZE (sizeof (VOID *)) + +/** + Creates and initializes the DebugImageInfo Table. Also creates the configuration + table and registers it into the system table. + +**/ +VOID +SmmInitializeDebugImageInfoTable ( + VOID + ) +{ + EFI_STATUS Status; + + // + // Install the EFI_SYSTEM_TABLE_POINTER structure in the EFI System + // Configuration Table + // + Status = SmmInstallConfigurationTable ( + gSmst, + &gEfiDebugImageInfoTableGuid, + &mDebugInfoTableHeader, + sizeof (mDebugInfoTableHeader) + ); + ASSERT_EFI_ERROR (Status); +} + + +/** + Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates + the table if it's not large enough to accomidate another entry. + + @param ImageInfoType type of debug image information + @param LoadedImage pointer to the loaded image protocol for the image being + loaded + @param ImageHandle image handle for the image being loaded + +**/ +VOID +SmmNewDebugImageInfoEntry ( + IN UINT32 ImageInfoType, + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN EFI_HANDLE ImageHandle, + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + EFI_DEBUG_IMAGE_INFO *Table; + EFI_DEBUG_IMAGE_INFO *NewTable; + UINTN Index; + UINTN TableSize; + EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; + RETURN_STATUS Status; + CONST CHAR8 *PdbPath; + UINT32 PdbPathSize; + + // + // Set the flag indicating that we're in the process of updating the table. + // + mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; + + Table = mDebugInfoTableHeader.EfiDebugImageInfoTable; + + if (mDebugInfoTableHeader.TableSize < mMaxTableEntries) { + // + // We still have empty entires in the Table, find the first empty entry. + // + Index = 0; + while (Table[Index].NormalImage != NULL) { + Index++; + } + // + // There must be an empty entry in the in the table. + // + ASSERT (Index < mMaxTableEntries); + } else { + // + // Table is full, so re-allocate another page for a larger table... + // + TableSize = mMaxTableEntries * EFI_DEBUG_TABLE_ENTRY_SIZE; + NewTable = AllocateZeroPool (TableSize + EFI_PAGE_SIZE); + if (NewTable == NULL) { + mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; + return; + } + // + // Copy the old table into the new one + // + CopyMem (NewTable, Table, TableSize); + mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable; + // + // Enlarge the max table entries. + // + mMaxTableEntries += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE; + // + // Free the old table + // + SmmFreePool (Table); + // + // Update the table header + // + Table = NewTable; + // + // Set the first empty entry index to be the original max table entries. + // + Index = mMaxTableEntries; + } + + // + // Allocate data for new entry + // + NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL)); + if (NormalImage != NULL) { + // + // Update the entry + // + NormalImage->ImageInfoType = (UINT32) ImageInfoType; + NormalImage->LoadedImageProtocolInstance = LoadedImage; + NormalImage->ImageHandle = ImageHandle; + + Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize); + if (!RETURN_ERROR (Status)) { + NormalImage->PdbPath = AllocateCopyPool (PdbPathSize, PdbPath); + } + // + // Increase the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status. + // + mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED; + Table[Index].NormalImage = NormalImage; + mDebugInfoTableHeader.TableSize++; + } + mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; +} diff --git a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c index bb789e5890..dc22b9a7a5 100644 --- a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c +++ b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c @@ -33,7 +33,9 @@ **/ +#include "Library/UefiImageLib.h" #include "PiSmmCore.h" +#include "Uefi/UefiBaseType.h" // // SMM Dispatcher Data structures @@ -213,84 +215,18 @@ CheckAndMarkFixLoadingMemoryUsageBitMap ( **/ EFI_STATUS -GetPeCoffImageFixLoadingAssignedAddress ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext +GetUefiImageFixLoadingAssignedAddress ( + OUT EFI_PHYSICAL_ADDRESS *LoadAddress, + IN UINT64 ValueInSectionHeader, + IN UINT32 ImageDestSize ) { - UINTN SectionHeaderOffset; - EFI_STATUS Status; - EFI_IMAGE_SECTION_HEADER SectionHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - EFI_PHYSICAL_ADDRESS FixLoadingAddress; - UINT16 Index; - UINTN Size; - UINT16 NumberOfSections; - UINT64 ValueInSectionHeader; + RETURN_STATUS Status; + EFI_PHYSICAL_ADDRESS FixLoadingAddress; - FixLoadingAddress = 0; - Status = EFI_NOT_FOUND; - - // - // Get PeHeader pointer - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset); - SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader; - NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections; - - // - // Get base address from the first section header that doesn't point to code section. - // - for (Index = 0; Index < NumberOfSections; Index++) { - // - // Read section header from file - // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EFI_NOT_FOUND; - - if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) { - // - // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header - // that doesn't point to code section in image header.So there is an assumption that when the feature is enabled, - // if a module with a loading address assigned by tools, the PointerToRelocations & PointerToLineNumbers fields - // should not be Zero, or else, these 2 fields should be set to Zero - // - ValueInSectionHeader = ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations); - if (ValueInSectionHeader != 0) { - // - // Found first section header that doesn't point to code section in which build tool saves the - // offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields - // - FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + (INT64)ValueInSectionHeader); - // - // Check if the memory range is available. - // - Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoadingAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment)); - if (!EFI_ERROR (Status)) { - // - // The assigned address is valid. Return the specified loading address - // - ImageContext->ImageAddress = FixLoadingAddress; - } - } - - break; - } - - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); - } + FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + ValueInSectionHeader); + Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoadingAddress, ImageDestSize); + *LoadAddress = FixLoadingAddress; DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r\n", FixLoadingAddress, Status)); return Status; @@ -307,24 +243,29 @@ GetPeCoffImageFixLoadingAssignedAddress ( EFI_STATUS EFIAPI SmmLoadImage ( - IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry + IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry, + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { UINT32 AuthenticationStatus; UINTN FilePathSize; VOID *Buffer; UINTN Size; - UINTN PageCount; + UINT32 DstBufferPages; EFI_GUID *NameGuid; EFI_STATUS Status; EFI_STATUS SecurityStatus; EFI_HANDLE DeviceHandle; - EFI_PHYSICAL_ADDRESS DstBuffer; + UINT32 ImageSize; + UINT32 ImageAlignment; + UINT64 ValueInSectionHeader; + VOID *DstBuffer; + UINT32 DstBufferSize; EFI_DEVICE_PATH_PROTOCOL *FilePath; EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath; EFI_DEVICE_PATH_PROTOCOL *HandleFilePath; EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + EFI_PHYSICAL_ADDRESS LoadAddress; PERF_LOAD_IMAGE_BEGIN (DriverEntry->ImageHandle); @@ -413,6 +354,18 @@ SmmLoadImage ( return Status; } + // + // Get information about the image being loaded + // + Status = UefiImageInitializeContextPreHash (ImageContext, Buffer, (UINT32) Size); + if (EFI_ERROR (Status)) { + if (Buffer != NULL) { + gBS->FreePool (Buffer); + } + return Status; + } + + // FIXME: Context? // // Verify File Authentication through the Security2 Architectural Protocol // @@ -420,8 +373,8 @@ SmmLoadImage ( SecurityStatus = mSecurity2->FileAuthentication ( mSecurity2, OriginalFilePath, - Buffer, - Size, + ImageContext, + sizeof (*ImageContext), FALSE ); } @@ -444,24 +397,23 @@ SmmLoadImage ( return Status; } - // - // Initialize ImageContext - // - ImageContext.Handle = Buffer; - ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; + Status = UefiImageInitializeContextPostHash (ImageContext); + if (RETURN_ERROR (Status)) { + return Status; + } // - // Get information about the image being loaded + // Stripped relocations are not supported for both fixed-address and dynamic + // loading. // - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - if (Buffer != NULL) { - gBS->FreePool (Buffer); - } - - return Status; + if (UefiImageGetRelocsStripped (ImageContext)) { + return EFI_UNSUPPORTED; } + ImageSize = UefiImageGetImageSize (ImageContext); + DstBufferPages = EFI_SIZE_TO_PAGES (ImageSize); + DstBufferSize = EFI_PAGES_TO_SIZE (DstBufferPages); + ImageAlignment = UefiImageGetSegmentAlignment (ImageContext); // // if Loading module at Fixed Address feature is enabled, then cut out a memory range started from TESG BASE // to hold the Smm driver code @@ -470,102 +422,68 @@ SmmLoadImage ( // // Get the fixed loading address assigned by Build tool // - Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext); + Status = UefiImageGetFixedAddress (ImageContext, &ValueInSectionHeader); + if (!RETURN_ERROR (Status)) { + Status = GetUefiImageFixLoadingAssignedAddress (&LoadAddress, ValueInSectionHeader, DstBufferSize); + } + if (!EFI_ERROR (Status)) { // // Since the memory range to load Smm core already been cut out, so no need to allocate and free this range // following statements is to bypass SmmFreePages // - PageCount = 0; - DstBuffer = (UINTN)gLoadModuleAtFixAddressSmramBase; + DstBufferPages = 0; + DstBuffer = (VOID *)(UINTN)LoadAddress; } else { DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n")); // // allocate the memory to load the SMM driver // - PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment); - DstBuffer = (UINTN)(-1); - - Status = SmmAllocatePages ( - AllocateMaxAddress, - EfiRuntimeServicesCode, - PageCount, - &DstBuffer - ); - if (EFI_ERROR (Status)) { + DstBuffer = AllocateAlignedCodePages (DstBufferPages, ImageAlignment); + if (DstBuffer == NULL) { if (Buffer != NULL) { gBS->FreePool (Buffer); } - return Status; - } - - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer; + return EFI_OUT_OF_RESOURCES; + } } } else { - PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment); - DstBuffer = (UINTN)(-1); - - Status = SmmAllocatePages ( - AllocateMaxAddress, - EfiRuntimeServicesCode, - PageCount, - &DstBuffer - ); - if (EFI_ERROR (Status)) { + DstBuffer = AllocateAlignedCodePages (DstBufferPages, ImageAlignment); + if (DstBuffer == NULL) { if (Buffer != NULL) { gBS->FreePool (Buffer); } - return Status; + return EFI_OUT_OF_RESOURCES; } - - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer; } - // - // Align buffer on section boundary - // - ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; - ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1); - // // Load the image to our new buffer // - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - if (Buffer != NULL) { - gBS->FreePool (Buffer); - } - - SmmFreePages (DstBuffer, PageCount); - return Status; - } - - // - // Relocate the image in our new buffer - // - Status = PeCoffLoaderRelocateImage (&ImageContext); + Status = UefiImageLoadImageForExecution ( + ImageContext, + DstBuffer, + DstBufferSize, + NULL, + 0 + ); if (EFI_ERROR (Status)) { if (Buffer != NULL) { gBS->FreePool (Buffer); } - SmmFreePages (DstBuffer, PageCount); + FreeAlignedPages (DstBuffer, DstBufferPages); return Status; } - // - // Flush the instruction cache so the image data are written before we execute it - // - InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); - // // Save Image EntryPoint in DriverEntry // - DriverEntry->ImageEntryPoint = ImageContext.EntryPoint; - DriverEntry->ImageBuffer = DstBuffer; - DriverEntry->NumberOfPage = PageCount; + DriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext); + DriverEntry->ImageBuffer = (UINTN)DstBuffer; + DriverEntry->NumberOfPage = DstBufferPages; // // Allocate a Loaded Image Protocol in EfiBootServicesData @@ -576,7 +494,7 @@ SmmLoadImage ( gBS->FreePool (Buffer); } - SmmFreePages (DstBuffer, PageCount); + FreeAlignedPages (DstBuffer, DstBufferPages); return Status; } @@ -604,14 +522,14 @@ SmmLoadImage ( gBS->FreePool (Buffer); } - SmmFreePages (DstBuffer, PageCount); + FreeAlignedPages (DstBuffer, DstBufferPages); return Status; } CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath)); - DriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN)ImageContext.ImageAddress; - DriverEntry->LoadedImage->ImageSize = ImageContext.ImageSize; + DriverEntry->LoadedImage->ImageBase = DstBuffer; + DriverEntry->LoadedImage->ImageSize = ImageSize; DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode; DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData; @@ -625,14 +543,14 @@ SmmLoadImage ( } gBS->FreePool (DriverEntry->LoadedImage->FilePath); - SmmFreePages (DstBuffer, PageCount); + FreeAlignedPages (DstBuffer, DstBufferPages); return Status; } - CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize (FilePath)); + CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize(FilePath)); - DriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN)ImageContext.ImageAddress; - DriverEntry->SmmLoadedImage.ImageSize = ImageContext.ImageSize; + DriverEntry->SmmLoadedImage.ImageBase = DstBuffer; + DriverEntry->SmmLoadedImage.ImageSize = ImageSize; DriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode; DriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData; @@ -660,60 +578,42 @@ SmmLoadImage ( PERF_LOAD_IMAGE_END (DriverEntry->ImageHandle); + SmmInsertImageRecord (&DriverEntry->SmmLoadedImage, ImageContext); + + // + // Register the image in the Debug Image Info Table if the attribute is set + // + SmmNewDebugImageInfoEntry ( + EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, + &DriverEntry->SmmLoadedImage, + DriverEntry->SmmImageHandle, + ImageContext + ); + // // Print the load address and the PDB file name if it is available // DEBUG_CODE_BEGIN (); - UINTN Index; - UINTN StartIndex; - CHAR8 EfiFileName[256]; + CHAR8 EfiFileName[256]; - DEBUG (( - DEBUG_INFO | DEBUG_LOAD, - "Loading SMM driver at 0x%11p EntryPoint=0x%11p ", - (VOID *)(UINTN)ImageContext.ImageAddress, - FUNCTION_ENTRY_POINT (ImageContext.EntryPoint) - )); + DEBUG ((DEBUG_INFO | DEBUG_LOAD, + "Loading SMM driver at 0x%11p EntryPoint=0x%11p ", + DstBuffer, + FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext)))); // // Print Module Name by Pdb file path. // Windows and Unix style file path are all trimmed correctly. // - if (ImageContext.PdbPointer != NULL) { - StartIndex = 0; - for (Index = 0; ImageContext.PdbPointer[Index] != 0; Index++) { - if ((ImageContext.PdbPointer[Index] == '\\') || (ImageContext.PdbPointer[Index] == '/')) { - StartIndex = Index + 1; - } - } - - // - // Copy the PDB file name to our temporary string, and replace .pdb with .efi - // The PDB file name is limited in the range of 0~255. - // If the length is bigger than 255, trim the redundant characters to avoid overflow in array boundary. - // - for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) { - EfiFileName[Index] = ImageContext.PdbPointer[Index + StartIndex]; - if (EfiFileName[Index] == 0) { - EfiFileName[Index] = '.'; - } - - if (EfiFileName[Index] == '.') { - EfiFileName[Index + 1] = 'e'; - EfiFileName[Index + 2] = 'f'; - EfiFileName[Index + 3] = 'i'; - EfiFileName[Index + 4] = 0; - break; - } - } - - if (Index == sizeof (EfiFileName) - 4) { - EfiFileName[Index] = 0; - } - - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex])); + Status = UefiImageGetModuleNameFromSymbolsPath ( + ImageContext, + EfiFileName, + sizeof (EfiFileName) + ); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); } DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n")); @@ -852,11 +752,12 @@ SmmDispatcher ( VOID ) { - EFI_STATUS Status; - LIST_ENTRY *Link; - EFI_SMM_DRIVER_ENTRY *DriverEntry; - BOOLEAN ReadyToRun; - BOOLEAN PreviousSmmEntryPointRegistered; + EFI_STATUS Status; + LIST_ENTRY *Link; + EFI_SMM_DRIVER_ENTRY *DriverEntry; + BOOLEAN ReadyToRun; + BOOLEAN PreviousSmmEntryPointRegistered; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; if (!gRequestDispatch) { return EFI_NOT_FOUND; @@ -889,8 +790,7 @@ SmmDispatcher ( // skip the LoadImage // if (DriverEntry->ImageHandle == NULL) { - Status = SmmLoadImage (DriverEntry); - + Status = SmmLoadImage (DriverEntry, &ImageContext); // // Update the driver state to reflect that it's been loaded // @@ -929,7 +829,7 @@ SmmDispatcher ( // // For each SMM driver, pass NULL as ImageHandle // - RegisterSmramProfileImage (DriverEntry, TRUE); + RegisterSmramProfileImage (&DriverEntry->FileName, TRUE, &ImageContext); PERF_START_IMAGE_BEGIN (DriverEntry->ImageHandle); Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, gST); PERF_START_IMAGE_END (DriverEntry->ImageHandle); @@ -940,7 +840,12 @@ SmmDispatcher ( DriverEntry->SmmLoadedImage.ImageBase, Status )); - UnregisterSmramProfileImage (DriverEntry, TRUE); + UnregisterSmramProfileImage ( + &DriverEntry->FileName, + (UINTN) DriverEntry->LoadedImage->ImageBase, + DriverEntry->LoadedImage->ImageSize, + TRUE + ); SmmFreePages (DriverEntry->ImageBuffer, DriverEntry->NumberOfPage); // // Uninstall LoadedImage diff --git a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c b/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c similarity index 96% rename from MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c rename to MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c index 9a4d5b8cac..b81d637aef 100644 --- a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c @@ -22,7 +22,8 @@ #include #include #include -#include "PiSmmCoreMemoryAllocationServices.h" +#include "PiSmmCore.h" +#include "PiSmmCorePrivateData.h" #include diff --git a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c b/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c index 28fe74ecc4..c06bb409d4 100644 --- a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c +++ b/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c @@ -16,12 +16,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include -#include +#include #include #include "PiSmmCore.h" +#include "ProcessorBind.h" #define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) @@ -31,7 +31,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent typedef struct { UINT32 Signature; UINTN ImageRecordCount; - UINTN CodeSegmentCountMax; + UINT32 NumberOfSectionsMax; LIST_ENTRY ImageRecordList; } IMAGE_PROPERTIES_PRIVATE_DATA; @@ -212,7 +212,10 @@ SmmCoreGetMemoryMapMemoryAttributesTable ( return EFI_INVALID_PARAMETER; } - AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount; + // + // Per image, they may be one trailer. There may be prefixed data. + // + AdditionalRecordCount = (mImagePropertiesPrivateData.NumberOfSectionsMax + 1) * mImagePropertiesPrivateData.ImageRecordCount + 1; OldMemoryMapSize = *MemoryMapSize; Status = SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion); @@ -252,88 +255,158 @@ SmmCoreGetMemoryMapMemoryAttributesTable ( // /** - Insert image record. + Set MemoryProtectionAttribute according to PE/COFF image section alignment. - @param[in] DriverEntry Driver information + @param[in] SectionAlignment PE/COFF section alignment **/ +STATIC VOID -SmmInsertImageRecord ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry +SetMemoryAttributesTableSectionAlignment ( + IN UINT32 SectionAlignment ) { - EFI_STATUS Status; - IMAGE_PROPERTIES_RECORD *ImageRecord; - CHAR8 *PdbPointer; - UINT32 RequiredAlignment; + if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) && + ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) != 0)) + { + DEBUG ((DEBUG_VERBOSE, "SMM SetMemoryAttributesTableSectionAlignment - Clear\n")); + mMemoryProtectionAttribute &= ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); + } +} - DEBUG ((DEBUG_VERBOSE, "SMM InsertImageRecord - 0x%x\n", DriverEntry)); +/** + Sort image record based upon the ImageBase from low to high. +**/ +STATIC +VOID +InsertSortImageRecord ( + IN UEFI_IMAGE_RECORD *NewImageRecord + ) +{ + UEFI_IMAGE_RECORD *ImageRecord; + LIST_ENTRY *PrevImageRecordLink; + LIST_ENTRY *ImageRecordLink; + LIST_ENTRY *ImageRecordList; + + ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList; + + PrevImageRecordLink = ImageRecordList; + for ( + ImageRecordLink = GetFirstNode (ImageRecordList); + !IsNull (ImageRecordLink, ImageRecordList); + ImageRecordLink = GetNextNode (ImageRecordList, PrevImageRecordLink) + ) { + ImageRecord = CR ( + ImageRecordLink, + UEFI_IMAGE_RECORD, + Link, + UEFI_IMAGE_RECORD_SIGNATURE + ); + if (NewImageRecord->StartAddress < ImageRecord->StartAddress) { + break; + } - ImageRecord = AllocatePool (sizeof (*ImageRecord)); - if (ImageRecord == NULL) { - return; + PrevImageRecordLink = ImageRecordLink; } - InitializeListHead (&ImageRecord->Link); - InitializeListHead (&ImageRecord->CodeSegmentList); + InsertHeadList (PrevImageRecordLink, &NewImageRecord->Link); + mImagePropertiesPrivateData.ImageRecordCount++; - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)DriverEntry->ImageBuffer); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_VERBOSE, "SMM Image - %a\n", PdbPointer)); + if (mImagePropertiesPrivateData.NumberOfSectionsMax < NewImageRecord->NumSegments) { + mImagePropertiesPrivateData.NumberOfSectionsMax = NewImageRecord->NumSegments; } +} - RequiredAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; - Status = CreateImagePropertiesRecord ( - (VOID *)(UINTN)DriverEntry->ImageBuffer, - LShiftU64 (DriverEntry->NumberOfPage, EFI_PAGE_SHIFT), - &RequiredAlignment, - ImageRecord - ); - - if (EFI_ERROR (Status)) { - if (Status == EFI_ABORTED) { - mMemoryProtectionAttribute &= - ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); - } - - goto Finish; +/** + Dump image record. +**/ +STATIC +VOID +DumpImageRecord ( + VOID + ) +{ + UEFI_IMAGE_RECORD *ImageRecord; + LIST_ENTRY *ImageRecordLink; + LIST_ENTRY *ImageRecordList; + UINTN Index; + + ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList; + + for (ImageRecordLink = ImageRecordList->ForwardLink, Index = 0; + ImageRecordLink != ImageRecordList; + ImageRecordLink = ImageRecordLink->ForwardLink, Index++) + { + ImageRecord = CR ( + ImageRecordLink, + UEFI_IMAGE_RECORD, + Link, + UEFI_IMAGE_RECORD_SIGNATURE + ); + DEBUG ((DEBUG_VERBOSE, "SMM Image[%d]: 0x%016lx - 0x%016lx\n", Index, ImageRecord->StartAddress, ImageRecord->EndAddress - ImageRecord->StartAddress)); } +} - if (ImageRecord->CodeSegmentCount == 0) { - mMemoryProtectionAttribute &= - ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); - DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n")); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); - } +/** + Insert image record. - Status = EFI_ABORTED; - goto Finish; + @param[in] DriverEntry Driver information +**/ +VOID +SmmInsertImageRecord ( + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + RETURN_STATUS PdbStatus; + PHYSICAL_ADDRESS ImageBuffer; + UINTN NumberOfPage; + UINT32 SectionAlignment; + UEFI_IMAGE_RECORD *ImageRecord; + CONST CHAR8 *PdbPointer; + UINT32 PdbSize; + + ImageBuffer = (UINTN)LoadedImage->ImageBase; + NumberOfPage = EFI_SIZE_TO_PAGES((UINTN)LoadedImage->ImageSize); + + DEBUG ((DEBUG_VERBOSE, "SMM InsertImageRecord - 0x%016lx - 0x%08x\n", ImageBuffer, NumberOfPage)); + + DEBUG ((DEBUG_VERBOSE, "SMM ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount)); + + PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize); + if (!RETURN_ERROR (PdbStatus)) { + DEBUG ((DEBUG_VERBOSE, "SMM Image - %a\n", PdbPointer)); } // - // Check overlap all section in ImageBase/Size + // Get SectionAlignment // - if (!IsImageRecordCodeSectionValid (ImageRecord)) { - DEBUG ((DEBUG_ERROR, "SMM IsImageRecordCodeSectionValid - FAIL\n")); - Status = EFI_ABORTED; - goto Finish; - } - - InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link); - mImagePropertiesPrivateData.ImageRecordCount++; + SectionAlignment = UefiImageGetSegmentAlignment (ImageContext); + + SetMemoryAttributesTableSectionAlignment (SectionAlignment); + if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) { + DEBUG (( + DEBUG_WARN, + "SMM !!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n", + SectionAlignment, RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10)); + if (!RETURN_ERROR (PdbStatus)) { + DEBUG ((DEBUG_WARN, "SMM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); + } - if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) { - mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount; + return; } - SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList); - -Finish: - if (EFI_ERROR (Status) && (ImageRecord != NULL)) { - DeleteImagePropertiesRecord (ImageRecord); + // + // The image headers are not recorded among the sections, allocate one more. + // + ImageRecord = UefiImageLoaderGetImageRecord (ImageContext); + if (ImageRecord == NULL) { + return; } - return; + UefiImageDebugPrintSegments (ImageContext); + UefiImageDebugPrintImageRecord (ImageRecord); + + InsertSortImageRecord (ImageRecord); } /** @@ -418,60 +491,6 @@ PublishMemoryAttributesTable ( ASSERT_EFI_ERROR (Status); } -/** - This function installs all SMM image record information. -**/ -VOID -SmmInstallImageRecord ( - VOID - ) -{ - EFI_STATUS Status; - UINTN NoHandles; - EFI_HANDLE *HandleBuffer; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - UINTN Index; - EFI_SMM_DRIVER_ENTRY DriverEntry; - - Status = SmmLocateHandleBuffer ( - ByProtocol, - &gEfiLoadedImageProtocolGuid, - NULL, - &NoHandles, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return; - } - - for (Index = 0; Index < NoHandles; Index++) { - Status = gSmst->SmmHandleProtocol ( - HandleBuffer[Index], - &gEfiLoadedImageProtocolGuid, - (VOID **)&LoadedImage - ); - if (EFI_ERROR (Status)) { - continue; - } - - DEBUG ((DEBUG_VERBOSE, "LoadedImage - 0x%x 0x%x ", LoadedImage->ImageBase, LoadedImage->ImageSize)); - { - VOID *PdbPointer; - PdbPointer = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_VERBOSE, "(%a) ", PdbPointer)); - } - } - DEBUG ((DEBUG_VERBOSE, "\n")); - ZeroMem (&DriverEntry, sizeof (DriverEntry)); - DriverEntry.ImageBuffer = (UINTN)LoadedImage->ImageBase; - DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)LoadedImage->ImageSize); - SmmInsertImageRecord (&DriverEntry); - } - - FreePool (HandleBuffer); -} - /** Install MemoryAttributesTable. @@ -489,8 +508,6 @@ SmmInstallMemoryAttributesTable ( IN EFI_HANDLE Handle ) { - SmmInstallImageRecord (); - DEBUG ((DEBUG_VERBOSE, "SMM MemoryProtectionAttribute - 0x%016lx\n", mMemoryProtectionAttribute)); if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) { return EFI_SUCCESS; @@ -500,7 +517,7 @@ SmmInstallMemoryAttributesTable ( if ( mImagePropertiesPrivateData.ImageRecordCount > 0) { DEBUG ((DEBUG_INFO, "SMM - Total Runtime Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount)); DEBUG ((DEBUG_INFO, "SMM - Dump Runtime Image Records:\n")); - DumpImageRecords (&mImagePropertiesPrivateData.ImageRecordList); + DumpImageRecord (); } DEBUG_CODE_END (); diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c index e957cb67f8..9f3e9392e8 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c @@ -815,7 +815,7 @@ SmmCoreInstallLoadedImage ( mSmmCoreLoadedImage->SystemTable = gST; mSmmCoreLoadedImage->ImageBase = (VOID *)(UINTN)gSmmCorePrivate->PiSmmCoreImageBase; - mSmmCoreLoadedImage->ImageSize = gSmmCorePrivate->PiSmmCoreImageSize; + mSmmCoreLoadedImage->ImageSize = UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext); mSmmCoreLoadedImage->ImageCodeType = EfiRuntimeServicesCode; mSmmCoreLoadedImage->ImageDataType = EfiRuntimeServicesData; @@ -847,13 +847,13 @@ SmmCoreInstallLoadedImage ( mSmmCoreDriverEntry->SmmLoadedImage.SystemTable = gST; mSmmCoreDriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN)gSmmCorePrivate->PiSmmCoreImageBase; - mSmmCoreDriverEntry->SmmLoadedImage.ImageSize = gSmmCorePrivate->PiSmmCoreImageSize; + mSmmCoreDriverEntry->SmmLoadedImage.ImageSize = UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext); mSmmCoreDriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode; mSmmCoreDriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData; - mSmmCoreDriverEntry->ImageEntryPoint = gSmmCorePrivate->PiSmmCoreEntryPoint; + mSmmCoreDriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (&gSmmCorePrivate->PiSmmCoreImageContext); mSmmCoreDriverEntry->ImageBuffer = gSmmCorePrivate->PiSmmCoreImageBase; - mSmmCoreDriverEntry->NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)gSmmCorePrivate->PiSmmCoreImageSize); + mSmmCoreDriverEntry->NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext)); // // Create a new image handle in the SMM handle database for the SMM Driver @@ -867,6 +867,21 @@ SmmCoreInstallLoadedImage ( ); ASSERT_EFI_ERROR (Status); + SmmInsertImageRecord (&mSmmCoreDriverEntry->SmmLoadedImage, &gSmmCorePrivate->PiSmmCoreImageContext); + + // + // Create the aligned system table pointer structure that is used by external + // debuggers to locate the system table... Also, install debug image info + // configuration table. + // + SmmInitializeDebugImageInfoTable (); + SmmNewDebugImageInfoEntry ( + EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, + &mSmmCoreDriverEntry->SmmLoadedImage, + mSmmCoreDriverEntry->SmmImageHandle, + &gSmmCorePrivate->PiSmmCoreImageContext + ); + return; } diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h index 60073c78b4..6b33a9d34a 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h @@ -37,11 +37,11 @@ #include #include #include +#include #include #include -#include -#include +#include #include #include #include @@ -55,6 +55,7 @@ #include #include #include +#include #include "PiSmmCorePrivateData.h" #include "HeapGuard.h" @@ -1020,8 +1021,9 @@ SmramProfileInstallProtocol ( **/ EFI_STATUS RegisterSmramProfileImage ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry, - IN BOOLEAN RegisterToDxe + IN EFI_GUID *FileName, + IN BOOLEAN RegisterToDxe, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); /** @@ -1038,8 +1040,10 @@ RegisterSmramProfileImage ( **/ EFI_STATUS UnregisterSmramProfileImage ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry, - IN BOOLEAN UnregisterToDxe + IN EFI_GUID *FileName, + IN PHYSICAL_ADDRESS ImageBase, + IN UINT64 ImageSize, + IN BOOLEAN UnregisterFromDxe ); /** @@ -1352,4 +1356,50 @@ SmmEntryPointMemoryManagementHook ( VOID ); +/** + Creates and initializes the DebugImageInfo Table. Also creates the configuration + table and registers it into the system table. + + Note: + This function allocates memory, frees it, and then allocates memory at an + address within the initial allocation. Since this function is called early + in DXE core initialization (before drivers are dispatched), this should not + be a problem. + +**/ +VOID +SmmInitializeDebugImageInfoTable ( + VOID + ); + + +/** + Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates + the table if it's not large enough to accomidate another entry. + + @param ImageInfoType type of debug image information + @param LoadedImage pointer to the loaded image protocol for the image being + loaded + @param ImageHandle image handle for the image being loaded + +**/ +VOID +SmmNewDebugImageInfoEntry ( + IN UINT32 ImageInfoType, + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN EFI_HANDLE ImageHandle, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ); + +/** + Insert image record. + + @param[in] DriverEntry Driver information +**/ +VOID +SmmInsertImageRecord ( + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ); + #endif diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf index 75a5934f0c..d14f76b65f 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf @@ -37,6 +37,8 @@ SmiHandlerProfile.c HeapGuard.c HeapGuard.h + MemoryAllocation.c + DebugImageInfo.c [Packages] MdePkg/MdePkg.dec @@ -46,8 +48,7 @@ UefiDriverEntryPoint BaseLib BaseMemoryLib - PeCoffLib - PeCoffGetEntryPointLib + UefiImageLib CacheMaintenanceLib DebugLib ReportStatusCodeLib @@ -99,6 +100,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxEfiSystemTablePointerAddress ## CONSUMES [Guids] gAprioriGuid ## SOMETIMES_CONSUMES ## File @@ -120,6 +122,7 @@ gSmiHandlerProfileGuid gEdkiiEndOfS3ResumeGuid ## SOMETIMES_PRODUCES ## GUID # Install protocol gEdkiiS3SmmInitDoneGuid ## SOMETIMES_PRODUCES ## GUID # Install protocol + gEfiDebugImageInfoTableGuid ## PRODUCES ## SystemTable [UserExtensions.TianoCore."ExtraFiles"] PiSmmCoreExtra.uni diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h index d8fe2dd9b9..301b9b4656 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h @@ -22,6 +22,7 @@ /// the SMM Entry Point enabling the use of SMM Mode. In this case, the SMM Core /// should be notified again to dispatch more SMM Drivers using SMM Mode. /// +#include "Library/UefiImageLib.h" #define COMM_BUFFER_SMM_DISPATCH_ERROR 0x00 #define COMM_BUFFER_SMM_DISPATCH_SUCCESS 0x01 #define COMM_BUFFER_SMM_DISPATCH_RESTART 0x02 @@ -112,8 +113,7 @@ typedef struct { EFI_STATUS ReturnStatus; EFI_PHYSICAL_ADDRESS PiSmmCoreImageBase; - UINT64 PiSmmCoreImageSize; - EFI_PHYSICAL_ADDRESS PiSmmCoreEntryPoint; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT PiSmmCoreImageContext; } SMM_CORE_PRIVATE_DATA; #endif diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c index fbba868fd0..524a74bdc4 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include @@ -36,6 +36,8 @@ #include #include "PiSmmCorePrivateData.h" #include +#include "ProcessorBind.h" +#include "Uefi/UefiBaseType.h" #define SMRAM_CAPABILITIES (EFI_MEMORY_WB | EFI_MEMORY_UC) @@ -913,91 +915,41 @@ SmmIplSetVirtualAddressNotify ( @retval EFI_NOT_FOUND The image has no assigned fixed loading address. **/ EFI_STATUS -GetPeCoffImageFixLoadingAssignedAddress ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext +GetUefiImageFixLoadingAssignedAddress ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + OUT EFI_PHYSICAL_ADDRESS *LoadAddress ) { - UINTN SectionHeaderOffset; - EFI_STATUS Status; - EFI_IMAGE_SECTION_HEADER SectionHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - EFI_PHYSICAL_ADDRESS FixLoadingAddress; - UINT16 Index; - UINTN Size; - UINT16 NumberOfSections; - EFI_PHYSICAL_ADDRESS SmramBase; - UINT64 SmmCodeSize; - UINT64 ValueInSectionHeader; - + EFI_STATUS Status; + UINT64 ValueInSectionHeader; + EFI_PHYSICAL_ADDRESS FixLoadingAddress; + UINT32 SizeOfImage; + EFI_PHYSICAL_ADDRESS SmramBase; + UINT64 SmmCodeSize; + + Status = UefiImageGetFixedAddress (ImageContext, &ValueInSectionHeader); + if (RETURN_ERROR (Status)) { + return Status; + } // // Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber // - SmmCodeSize = EFI_PAGES_TO_SIZE (PcdGet32 (PcdLoadFixAddressSmmCodePageNumber)); + SmmCodeSize = EFI_PAGES_TO_SIZE (PcdGet32(PcdLoadFixAddressSmmCodePageNumber)); + SmramBase = mLMFAConfigurationTable->SmramBase; - FixLoadingAddress = 0; - Status = EFI_NOT_FOUND; - SmramBase = mLMFAConfigurationTable->SmramBase; - // - // Get PeHeader pointer - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset); - SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader; - NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections; + FixLoadingAddress = SmramBase + ValueInSectionHeader; + SizeOfImage = UefiImageGetImageSize (ImageContext); - // - // Get base address from the first section header that doesn't point to code section. - // - for (Index = 0; Index < NumberOfSections; Index++) { + if (SmramBase + SmmCodeSize >= FixLoadingAddress + SizeOfImage + && SmramBase <= FixLoadingAddress) { // - // Read section header from file + // The assigned address is valid. Return the specified loading address // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EFI_NOT_FOUND; - - if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) { - // - // Build tool saves the offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields in the - // first section header that doesn't point to code section in image header. And there is an assumption that when the - // feature is enabled, if a module is assigned a loading address by tools, PointerToRelocations & PointerToLineNumbers - // fields should NOT be Zero, or else, these 2 fields should be set to Zero - // - ValueInSectionHeader = ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations); - if (ValueInSectionHeader != 0) { - // - // Found first section header that doesn't point to code section in which build tool saves the - // offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields - // - FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(SmramBase + (INT64)ValueInSectionHeader); - - if ((SmramBase + SmmCodeSize > FixLoadingAddress) && (SmramBase <= FixLoadingAddress)) { - // - // The assigned address is valid. Return the specified loading address - // - ImageContext->ImageAddress = FixLoadingAddress; - Status = EFI_SUCCESS; - } - } - - break; - } - - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); + *LoadAddress = FixLoadingAddress; + Status = EFI_SUCCESS; } - DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r \n", FixLoadingAddress, Status)); + DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r \n", FixLoadingAddress, Status)); return Status; } @@ -1024,9 +976,14 @@ ExecuteSmmCoreFromSmram ( EFI_STATUS Status; VOID *SourceBuffer; UINTN SourceSize; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UINT32 ImageSize; + UINT32 ImageAlignment; + UINT32 DestinationPages; + UINT32 DestinationSize; + UINT32 AlignSubtrahend; UINTN PageCount; EFI_IMAGE_ENTRY_POINT EntryPoint; + EFI_PHYSICAL_ADDRESS LoadAddress; // // Search all Firmware Volumes for a PE/COFF image in a file of type SMM_CORE @@ -1043,20 +1000,26 @@ ExecuteSmmCoreFromSmram ( return Status; } - // - // Initialize ImageContext - // - ImageContext.Handle = SourceBuffer; - ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; - // // Get information about the image being loaded // - Status = PeCoffLoaderGetImageInfo (&ImageContext); + Status = UefiImageInitializeContext (&gSmmCorePrivate->PiSmmCoreImageContext, SourceBuffer, (UINT32) SourceSize); if (EFI_ERROR (Status)) { return Status; } + // + // Stripped relocations are not supported for both fixed-address and dynamic + // loading. + // + if (UefiImageGetRelocsStripped (&gSmmCorePrivate->PiSmmCoreImageContext)) { + return EFI_UNSUPPORTED; + } + + ImageSize = UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext); + DestinationPages = EFI_SIZE_TO_PAGES (ImageSize); + DestinationSize = EFI_PAGES_TO_SIZE (DestinationPages); + ImageAlignment = UefiImageGetSegmentAlignment (&gSmmCorePrivate->PiSmmCoreImageContext); // // if Loading module at Fixed Address feature is enabled, the SMM core driver will be loaded to // the address assigned by build tool. @@ -1065,7 +1028,7 @@ ExecuteSmmCoreFromSmram ( // // Get the fixed loading address assigned by Build tool // - Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext); + Status = GetUefiImageFixLoadingAssignedAddress (&gSmmCorePrivate->PiSmmCoreImageContext, &LoadAddress); if (!EFI_ERROR (Status)) { // // Since the memory range to load SMM CORE will be cut out in SMM core, so no need to allocate and free this range @@ -1081,7 +1044,11 @@ ExecuteSmmCoreFromSmram ( // Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR // specified by SmramRange // - PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment); + AlignSubtrahend = ALIGN_VALUE_SUBTRAHEND ( + SmramRange->CpuStart + SmramRange->PhysicalSize, + ImageAlignment + ); + PageCount = (UINTN)DestinationPages + (UINTN)EFI_SIZE_TO_PAGES ((UINTN)AlignSubtrahend); ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0); ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount)); @@ -1095,14 +1062,18 @@ ExecuteSmmCoreFromSmram ( // // Align buffer on section boundary // - ImageContext.ImageAddress = SmramRangeSmmCore->CpuStart; + LoadAddress = SmramRangeSmmCore->CpuStart; } } else { // // Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR // specified by SmramRange // - PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment); + AlignSubtrahend = ALIGN_VALUE_SUBTRAHEND ( + SmramRange->CpuStart + SmramRange->PhysicalSize, + ImageAlignment + ); + PageCount = (UINTN)DestinationPages + (UINTN)EFI_SIZE_TO_PAGES ((UINTN)AlignSubtrahend); ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0); ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount)); @@ -1116,50 +1087,34 @@ ExecuteSmmCoreFromSmram ( // // Align buffer on section boundary // - ImageContext.ImageAddress = SmramRangeSmmCore->CpuStart; + LoadAddress = SmramRangeSmmCore->CpuStart; } - ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; - ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1); - // // Print debug message showing SMM Core load address. // - DEBUG ((DEBUG_INFO, "SMM IPL loading SMM Core at SMRAM address %p\n", (VOID *)(UINTN)ImageContext.ImageAddress)); + DEBUG ((DEBUG_INFO, "SMM IPL loading SMM Core at SMRAM destination %p\n", (VOID *)(UINTN)LoadAddress)); // // Load the image to our new buffer // - Status = PeCoffLoaderLoadImage (&ImageContext); + Status = UefiImageLoadImageForExecution (&gSmmCorePrivate->PiSmmCoreImageContext, (VOID *)(UINTN)LoadAddress, DestinationSize, NULL, 0); if (!EFI_ERROR (Status)) { + LoadAddress = UefiImageLoaderGetImageAddress (&gSmmCorePrivate->PiSmmCoreImageContext); // - // Relocate the image in our new buffer + // Print debug message showing SMM Core entry point address. // - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (!EFI_ERROR (Status)) { - // - // Flush the instruction cache so the image data are written before we execute it - // - InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); - - // - // Print debug message showing SMM Core entry point address. - // - DEBUG ((DEBUG_INFO, "SMM IPL calling SMM Core at SMRAM address %p\n", (VOID *)(UINTN)ImageContext.EntryPoint)); - - gSmmCorePrivate->PiSmmCoreImageBase = ImageContext.ImageAddress; - gSmmCorePrivate->PiSmmCoreImageSize = ImageContext.ImageSize; - DEBUG ((DEBUG_INFO, "PiSmmCoreImageBase - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageBase)); - DEBUG ((DEBUG_INFO, "PiSmmCoreImageSize - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageSize)); + DEBUG ((DEBUG_INFO, "SMM IPL calling SMM Core at SMRAM address %p\n", (VOID *)(UINTN)(UefiImageLoaderGetImageEntryPoint (&gSmmCorePrivate->PiSmmCoreImageContext)))); - gSmmCorePrivate->PiSmmCoreEntryPoint = ImageContext.EntryPoint; + gSmmCorePrivate->PiSmmCoreImageBase = LoadAddress; + DEBUG ((DEBUG_INFO, "PiSmmCoreImageBase - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageBase)); + DEBUG ((DEBUG_INFO, "PiSmmCoreImageSize - 0x%016lx\n", UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext))); - // - // Execute image - // - EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)ImageContext.EntryPoint; - Status = EntryPoint ((EFI_HANDLE)Context, gST); - } + // + // Execute image + // + EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)(UefiImageLoaderGetImageEntryPoint (&gSmmCorePrivate->PiSmmCoreImageContext)); + Status = EntryPoint ((EFI_HANDLE)Context, gST); } // diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf index ddeb39cee2..60d14cd59c 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf @@ -35,7 +35,7 @@ UefiDriverEntryPoint BaseLib BaseMemoryLib - PeCoffLib + UefiImageLib CacheMaintenanceLib MemoryAllocationLib DebugLib diff --git a/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c b/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c index e48532c0fb..2944522ca7 100644 --- a/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c +++ b/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c @@ -17,7 +17,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include #include #include #include @@ -74,7 +73,7 @@ BuildSmiHandlerProfileDatabase ( **/ RETURN_STATUS -InternalPeCoffGetEntryPoint ( +InternalUefiImageGetEntryPoint ( IN VOID *Pe32Data, OUT VOID **EntryPoint ); @@ -264,7 +263,6 @@ GetSmmLoadedImage ( CHAR16 *PathStr; EFI_SMM_DRIVER_ENTRY *LoadedImagePrivate; PHYSICAL_ADDRESS EntryPoint; - VOID *EntryPointInImage; EFI_GUID Guid; CHAR8 *PdbString; PHYSICAL_ADDRESS RealImageBase; @@ -324,15 +322,6 @@ GetSmmLoadedImage ( RealImageBase = (UINTN)LoadedImage->ImageBase; if (LoadedImagePrivate->Signature == EFI_SMM_DRIVER_ENTRY_SIGNATURE) { EntryPoint = LoadedImagePrivate->ImageEntryPoint; - if ((EntryPoint != 0) && ((EntryPoint < (UINTN)LoadedImage->ImageBase) || (EntryPoint >= ((UINTN)LoadedImage->ImageBase + LoadedImage->ImageSize)))) { - // - // If the EntryPoint is not in the range of image buffer, it should come from emulation environment. - // So patch ImageBuffer here to align the EntryPoint. - // - Status = InternalPeCoffGetEntryPoint (LoadedImage->ImageBase, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - RealImageBase = (UINTN)LoadedImage->ImageBase + EntryPoint - (UINTN)EntryPointInImage; - } } DEBUG ((DEBUG_INFO, "(0x%lx - 0x%lx", RealImageBase, LoadedImage->ImageSize)); @@ -342,10 +331,11 @@ GetSmmLoadedImage ( DEBUG ((DEBUG_INFO, ")\n")); - if (RealImageBase != 0) { - PdbString = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)RealImageBase); + // FIXME: + /*if (RealImageBase != 0) { + PdbString = UefiImageLoaderGetPdbPointer ((VOID *)(UINTN)RealImageBase); DEBUG ((DEBUG_INFO, " pdb - %a\n", PdbString)); - } else { + } else*/ { PdbString = NULL; } diff --git a/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c b/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c index b437e4c433..1fa33efbbe 100644 --- a/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c +++ b/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c @@ -128,8 +128,7 @@ EFIAPI SmramProfileProtocolRegisterImage ( IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, IN EFI_FV_FILETYPE FileType ); @@ -249,110 +248,6 @@ GetSmramProfileContext ( return mSmramProfileContextPtr; } -/** - Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory. - If Pe32Data is NULL, then ASSERT(). - - @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory. - - @return The Subsystem of the PE/COFF image. - -**/ -UINT16 -InternalPeCoffGetSubsystem ( - IN VOID *Pe32Data - ) -{ - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - EFI_IMAGE_DOS_HEADER *DosHdr; - UINT16 Magic; - - ASSERT (Pe32Data != NULL); - - DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; - } - - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - return Hdr.Te->Subsystem; - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - Magic = Hdr.Pe32->OptionalHeader.Magic; - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - return Hdr.Pe32->OptionalHeader.Subsystem; - } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - return Hdr.Pe32Plus->OptionalHeader.Subsystem; - } - } - - return 0x0000; -} - -/** - Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded - into system memory with the PE/COFF Loader Library functions. - - Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry - point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then - return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS. - If Pe32Data is NULL, then ASSERT(). - If EntryPoint is NULL, then ASSERT(). - - @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory. - @param EntryPoint The pointer to entry point to the PE/COFF image to return. - - @retval RETURN_SUCCESS EntryPoint was returned. - @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image. - -**/ -RETURN_STATUS -InternalPeCoffGetEntryPoint ( - IN VOID *Pe32Data, - OUT VOID **EntryPoint - ) -{ - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - - ASSERT (Pe32Data != NULL); - ASSERT (EntryPoint != NULL); - - DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)Pe32Data + (UINTN)((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; - } - - // - // Calculate the entry point relative to the start of the image. - // AddressOfEntryPoint is common for PE32 & PE32+ - // - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - *EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize); - return RETURN_SUCCESS; - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - *EntryPoint = (VOID *)((UINTN)Pe32Data + (UINTN)(Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff)); - return RETURN_SUCCESS; - } - - return RETURN_UNSUPPORTED; -} - /** Build driver info. @@ -371,30 +266,26 @@ MEMORY_PROFILE_DRIVER_INFO_DATA * BuildDriverInfo ( IN MEMORY_PROFILE_CONTEXT_DATA *ContextData, IN EFI_GUID *FileName, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, - IN PHYSICAL_ADDRESS EntryPoint, - IN UINT16 ImageSubsystem, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + IN EFI_PHYSICAL_ADDRESS LoadAddress, IN EFI_FV_FILETYPE FileType ) { + RETURN_STATUS PdbStatus; EFI_STATUS Status; MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - VOID *EntryPointInImage; - CHAR8 *PdbString; - UINTN PdbSize; - UINTN PdbOccupiedSize; + MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; + CONST CHAR8 *PdbString; + UINT32 PdbSize; + UINTN PdbOccupiedSize; - PdbSize = 0; PdbOccupiedSize = 0; - PdbString = NULL; - if (ImageBase != 0) { - PdbString = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageBase); - if (PdbString != NULL) { - PdbSize = AsciiStrSize (PdbString); - PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64)); - } + + ASSERT (UefiImageLoaderGetImageAddress (ImageContext) != 0); + + PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbString, &PdbSize); + if (!EFI_ERROR (PdbStatus)) { + PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64)); } // @@ -422,19 +313,10 @@ BuildDriverInfo ( CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID)); } - DriverInfo->ImageBase = ImageBase; - DriverInfo->ImageSize = ImageSize; - DriverInfo->EntryPoint = EntryPoint; - DriverInfo->ImageSubsystem = ImageSubsystem; - if ((EntryPoint != 0) && ((EntryPoint < ImageBase) || (EntryPoint >= (ImageBase + ImageSize)))) { - // - // If the EntryPoint is not in the range of image buffer, it should come from emulation environment. - // So patch ImageBuffer here to align the EntryPoint. - // - Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)ImageBase, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverInfo->ImageBase = ImageBase + EntryPoint - (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage; - } + DriverInfo->ImageBase = LoadAddress; + DriverInfo->ImageSize = UefiImageGetImageSize (ImageContext); + DriverInfo->EntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext); + DriverInfo->ImageSubsystem = UefiImageGetSubsystem (ImageContext); DriverInfo->FileType = FileType; DriverInfoData->AllocInfoList = (LIST_ENTRY *)(DriverInfoData + 1); @@ -442,7 +324,7 @@ BuildDriverInfo ( DriverInfo->CurrentUsage = 0; DriverInfo->PeakUsage = 0; DriverInfo->AllocRecordCount = 0; - if (PdbSize != 0) { + if (!RETURN_ERROR (PdbStatus)) { DriverInfo->PdbStringOffset = (UINT16)sizeof (MEMORY_PROFILE_DRIVER_INFO); DriverInfoData->PdbString = (CHAR8 *)(DriverInfoData->AllocInfoList + 1); CopyMem (DriverInfoData->PdbString, PdbString, PdbSize); @@ -470,8 +352,7 @@ BuildDriverInfo ( VOID RegisterImageToDxe ( IN EFI_GUID *FileName, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, IN EFI_FV_FILETYPE FileType ) { @@ -490,8 +371,7 @@ RegisterImageToDxe ( Status = ProfileProtocol->RegisterImage ( ProfileProtocol, (EFI_DEVICE_PATH_PROTOCOL *)FilePath, - ImageBase, - ImageSize, + ImageContext, FileType ); } @@ -610,7 +490,6 @@ RegisterSmmCore ( ) { MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - PHYSICAL_ADDRESS ImageBase; UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)]; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath; @@ -622,14 +501,11 @@ RegisterSmmCore ( return FALSE; } - ImageBase = gSmmCorePrivate->PiSmmCoreImageBase; DriverInfoData = BuildDriverInfo ( ContextData, &gEfiCallerIdGuid, - ImageBase, - gSmmCorePrivate->PiSmmCoreImageSize, - gSmmCorePrivate->PiSmmCoreEntryPoint, - InternalPeCoffGetSubsystem ((VOID *)(UINTN)ImageBase), + &gSmmCorePrivate->PiSmmCoreImageContext, + gSmmCorePrivate->PiSmmCoreImageBase, EFI_FV_FILETYPE_SMM_CORE ); if (DriverInfoData == NULL) { @@ -652,8 +528,7 @@ SmramProfileInit ( RegisterImageToDxe ( &gEfiCallerIdGuid, - gSmmCorePrivate->PiSmmCoreImageBase, - gSmmCorePrivate->PiSmmCoreImageSize, + &gSmmCorePrivate->PiSmmCoreImageContext, EFI_FV_FILETYPE_SMM_CORE ); @@ -754,8 +629,9 @@ GetFileNameFromFilePath ( **/ EFI_STATUS RegisterSmramProfileImage ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry, - IN BOOLEAN RegisterToDxe + IN EFI_GUID *FileName, + IN BOOLEAN RegisterToDxe, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { MEMORY_PROFILE_CONTEXT_DATA *ContextData; @@ -765,9 +641,8 @@ RegisterSmramProfileImage ( if (RegisterToDxe) { RegisterImageToDxe ( - &DriverEntry->FileName, - DriverEntry->ImageBuffer, - EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage), + FileName, + ImageContext, EFI_FV_FILETYPE_SMM ); } @@ -777,7 +652,7 @@ RegisterSmramProfileImage ( } FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer; - EfiInitializeFwVolDevicepathNode (FilePath, &DriverEntry->FileName); + EfiInitializeFwVolDevicepathNode (FilePath, FileName); SetDevicePathEndNode (FilePath + 1); if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *)FilePath)) { @@ -791,11 +666,9 @@ RegisterSmramProfileImage ( DriverInfoData = BuildDriverInfo ( ContextData, - &DriverEntry->FileName, - DriverEntry->ImageBuffer, - EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage), - DriverEntry->ImageEntryPoint, - InternalPeCoffGetSubsystem ((VOID *)(UINTN)DriverEntry->ImageBuffer), + FileName, + ImageContext, + UefiImageLoaderGetImageAddress (ImageContext), EFI_FV_FILETYPE_SMM ); if (DriverInfoData == NULL) { @@ -909,24 +782,22 @@ GetMemoryProfileDriverInfoFromAddress ( **/ EFI_STATUS UnregisterSmramProfileImage ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry, - IN BOOLEAN UnregisterFromDxe + IN EFI_GUID *FileName, + IN PHYSICAL_ADDRESS ImageBase, + IN UINT64 ImageSize, + IN BOOLEAN UnregisterFromDxe ) { - EFI_STATUS Status; MEMORY_PROFILE_CONTEXT_DATA *ContextData; MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - EFI_GUID *FileName; - PHYSICAL_ADDRESS ImageAddress; - VOID *EntryPointInImage; UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)]; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath; if (UnregisterFromDxe) { UnregisterImageFromDxe ( - &DriverEntry->FileName, - DriverEntry->ImageBuffer, - EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage) + FileName, + ImageBase, + ImageSize ); } @@ -935,7 +806,7 @@ UnregisterSmramProfileImage ( } FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer; - EfiInitializeFwVolDevicepathNode (FilePath, &DriverEntry->FileName); + EfiInitializeFwVolDevicepathNode (FilePath, FileName); SetDevicePathEndNode (FilePath + 1); if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *)FilePath)) { @@ -948,24 +819,13 @@ UnregisterSmramProfileImage ( } DriverInfoData = NULL; - FileName = &DriverEntry->FileName; - ImageAddress = DriverEntry->ImageBuffer; - if ((DriverEntry->ImageEntryPoint < ImageAddress) || (DriverEntry->ImageEntryPoint >= (ImageAddress + EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage)))) { - // - // If the EntryPoint is not in the range of image buffer, it should come from emulation environment. - // So patch ImageAddress here to align the EntryPoint. - // - Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)ImageAddress, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - ImageAddress = ImageAddress + (UINTN)DriverEntry->ImageEntryPoint - (UINTN)EntryPointInImage; - } if (FileName != NULL) { - DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageAddress); + DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageBase); } if (DriverInfoData == NULL) { - DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, ImageAddress); + DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, ImageBase); } if (DriverInfoData == NULL) { @@ -1989,29 +1849,20 @@ EFIAPI SmramProfileProtocolRegisterImage ( IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, IN EFI_FV_FILETYPE FileType ) { - EFI_STATUS Status; - EFI_SMM_DRIVER_ENTRY DriverEntry; - VOID *EntryPointInImage; - EFI_GUID *Name; + EFI_GUID *FileName; + EFI_GUID ZeroGuid; - ZeroMem (&DriverEntry, sizeof (DriverEntry)); - Name = GetFileNameFromFilePath (FilePath); - if (Name != NULL) { - CopyMem (&DriverEntry.FileName, Name, sizeof (EFI_GUID)); + FileName = GetFileNameFromFilePath (FilePath); + if (FileName == NULL) { + ZeroMem (&ZeroGuid, sizeof (ZeroGuid)); + FileName = &ZeroGuid; } - DriverEntry.ImageBuffer = ImageBase; - DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)ImageSize); - Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)DriverEntry.ImageBuffer, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage; - - return RegisterSmramProfileImage (&DriverEntry, FALSE); + return RegisterSmramProfileImage (FileName, FALSE, ImageContext); } /** @@ -2037,24 +1888,16 @@ SmramProfileProtocolUnregisterImage ( IN UINT64 ImageSize ) { - EFI_STATUS Status; - EFI_SMM_DRIVER_ENTRY DriverEntry; - VOID *EntryPointInImage; - EFI_GUID *Name; + EFI_GUID *FileName; + EFI_GUID ZeroGuid; - ZeroMem (&DriverEntry, sizeof (DriverEntry)); - Name = GetFileNameFromFilePath (FilePath); - if (Name != NULL) { - CopyMem (&DriverEntry.FileName, Name, sizeof (EFI_GUID)); + FileName = GetFileNameFromFilePath (FilePath); + if (FileName == NULL) { + ZeroMem (&ZeroGuid, sizeof (ZeroGuid)); + FileName = &ZeroGuid; } - DriverEntry.ImageBuffer = ImageBase; - DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)ImageSize); - Status = InternalPeCoffGetEntryPoint ((VOID *)(UINTN)DriverEntry.ImageBuffer, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS)(UINTN)EntryPointInImage; - - return UnregisterSmramProfileImage (&DriverEntry, FALSE); + return UnregisterSmramProfileImage (FileName, ImageBase, ImageSize, FALSE); } /** diff --git a/MdeModulePkg/Core/RuntimeDxe/Runtime.c b/MdeModulePkg/Core/RuntimeDxe/Runtime.c index c66ed71e35..314a424e14 100644 --- a/MdeModulePkg/Core/RuntimeDxe/Runtime.c +++ b/MdeModulePkg/Core/RuntimeDxe/Runtime.c @@ -325,14 +325,12 @@ RuntimeDriverSetVirtualAddressMap ( Status = RuntimeDriverConvertPointer (0, (VOID **)&VirtImageBase); ASSERT_EFI_ERROR (Status); - PeCoffLoaderRelocateImageForRuntime ( - (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, + UefiImageRuntimeRelocateImageForExecution ( + (VOID *)(UINTN)RuntimeImage->ImageBase, + (UINT32)RuntimeImage->ImageSize, VirtImageBase, - (UINTN)RuntimeImage->ImageSize, RuntimeImage->RelocationData ); - - InvalidateInstructionCacheRange (RuntimeImage->ImageBase, (UINTN)RuntimeImage->ImageSize); } } diff --git a/MdeModulePkg/Core/RuntimeDxe/Runtime.h b/MdeModulePkg/Core/RuntimeDxe/Runtime.h index 1e28b98d78..00ac1fe08d 100644 --- a/MdeModulePkg/Core/RuntimeDxe/Runtime.h +++ b/MdeModulePkg/Core/RuntimeDxe/Runtime.h @@ -22,7 +22,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +#include // // Function Prototypes diff --git a/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf b/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf index 694c7690fa..36d282d69a 100644 --- a/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf +++ b/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf @@ -39,7 +39,7 @@ MdePkg/MdePkg.dec [LibraryClasses] - PeCoffLib + UefiImageLib CacheMaintenanceLib UefiBootServicesTableLib UefiLib diff --git a/MdeModulePkg/Include/Guid/MemoryProfile.h b/MdeModulePkg/Include/Guid/MemoryProfile.h index 8194b06330..33a033bb00 100644 --- a/MdeModulePkg/Include/Guid/MemoryProfile.h +++ b/MdeModulePkg/Include/Guid/MemoryProfile.h @@ -11,6 +11,8 @@ #include +#include + // // For BIOS MemoryType (0 ~ EfiMaxMemoryType - 1), it is recorded in UsageByType[MemoryType]. (Each valid entry has one entry) // For OS MemoryType (0x80000000 ~ 0xFFFFFFFF), it is recorded in UsageByType[EfiMaxMemoryType]. (All types are combined into one entry) @@ -242,8 +244,7 @@ EFI_STATUS (EFIAPI *EDKII_MEMORY_PROFILE_REGISTER_IMAGE)( IN EDKII_MEMORY_PROFILE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, IN EFI_FV_FILETYPE FileType ); diff --git a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h index 87c94c7237..7207e9f763 100644 --- a/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h +++ b/MdeModulePkg/Include/Library/ImagePropertiesRecordLib.h @@ -11,25 +11,7 @@ #ifndef IMAGE_PROPERTIES_RECORD_SUPPORT_LIB_H_ #define IMAGE_PROPERTIES_RECORD_SUPPORT_LIB_H_ -#define IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE SIGNATURE_32 ('I','P','R','C') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - EFI_PHYSICAL_ADDRESS CodeSegmentBase; - UINT64 CodeSegmentSize; -} IMAGE_PROPERTIES_RECORD_CODE_SECTION; - -#define IMAGE_PROPERTIES_RECORD_SIGNATURE SIGNATURE_32 ('I','P','R','D') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - EFI_PHYSICAL_ADDRESS ImageBase; - UINT64 ImageSize; - UINTN CodeSegmentCount; - LIST_ENTRY CodeSegmentList; -} IMAGE_PROPERTIES_RECORD; +#include /** Split the original memory map and add more entries to describe PE code @@ -82,142 +64,6 @@ SplitTable ( IN UINTN NumberOfAdditionalDescriptors ); -/** - Sort the code sections in the input ImageRecord based upon CodeSegmentBase from low to high. - - @param[in] ImageRecord IMAGE_PROPERTIES_RECORD to be sorted - - @retval EFI_SUCCESS The code sections in the input ImageRecord were sorted successfully - @retval EFI_ABORTED An error occurred while sorting the code sections in the input ImageRecord - @retval EFI_INVALID_PARAMETER ImageRecord is NULL -**/ -EFI_STATUS -EFIAPI -SortImageRecordCodeSection ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ); - -/** - Check if the code sections in the input ImageRecord are valid. - The code sections are valid if they don't overlap, are contained - within the the ImageRecord's ImageBase and ImageSize, and are - contained within the MAX_ADDRESS. - - @param[in] ImageRecord IMAGE_PROPERTIES_RECORD to be checked - - @retval TRUE The code sections in the input ImageRecord are valid - @retval FALSE The code sections in the input ImageRecord are invalid -**/ -BOOLEAN -EFIAPI -IsImageRecordCodeSectionValid ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ); - -/** - Sort the input ImageRecordList based upon the ImageBase from low to high. - - @param[in] ImageRecordList Image record list to be sorted - - @retval EFI_SUCCESS The image record list was sorted successfully - @retval EFI_ABORTED An error occurred while sorting the image record list - @retval EFI_INVALID_PARAMETER ImageRecordList is NULL -**/ -EFI_STATUS -EFIAPI -SortImageRecord ( - IN LIST_ENTRY *ImageRecordList - ); - -/** - Swap two image records. - - @param[in] FirstImageRecord The first image record. - @param[in] SecondImageRecord The second image record. - - @retval EFI_SUCCESS The image records were swapped successfully - @retval EFI_INVALID_PARAMETER FirstImageRecord or SecondImageRecord is NULL -**/ -EFI_STATUS -EFIAPI -SwapImageRecord ( - IN IMAGE_PROPERTIES_RECORD *FirstImageRecord, - IN IMAGE_PROPERTIES_RECORD *SecondImageRecord - ); - -/** - Swap two code sections in a single IMAGE_PROPERTIES_RECORD. - - @param[in] FirstImageRecordCodeSection The first code section - @param[in] SecondImageRecordCodeSection The second code section - - @retval EFI_SUCCESS The code sections were swapped successfully - @retval EFI_INVALID_PARAMETER FirstImageRecordCodeSection or SecondImageRecordCodeSection is NULL -**/ -EFI_STATUS -EFIAPI -SwapImageRecordCodeSection ( - IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *FirstImageRecordCodeSection, - IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *SecondImageRecordCodeSection - ); - -/** - Find image properties record according to image base and size in the - input ImageRecordList. - - @param[in] ImageBase Base of PE image - @param[in] ImageSize Size of PE image - @param[in] ImageRecordList Image record list to be searched - - @retval NULL No IMAGE_PROPERTIES_RECORD matches ImageBase - and ImageSize in the input ImageRecordList - @retval Other The found IMAGE_PROPERTIES_RECORD -**/ -IMAGE_PROPERTIES_RECORD * -EFIAPI -FindImageRecord ( - IN EFI_PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, - IN LIST_ENTRY *ImageRecordList - ); - -/** - Debug dumps the input list of IMAGE_PROPERTIES_RECORD structs. - - @param[in] ImageRecordList Head of the IMAGE_PROPERTIES_RECORD list -**/ -VOID -EFIAPI -DumpImageRecords ( - IN LIST_ENTRY *ImageRecordList - ); - -/** - Creates an IMAGE_PROPERTIES_RECORD from a loaded PE image. The PE/COFF header will be found - and parsed to determine the number of code segments and their base addresses and sizes. - - @param[in] ImageBase Base of the PE image - @param[in] ImageSize Size of the PE image - @param[in] RequiredAlignment If non-NULL, the alignment specified in the PE/COFF header - will be compared against this value. - @param[out] ImageRecord On out, a populated image properties record - - @retval EFI_INVALID_PARAMETER This function ImageBase or ImageRecord was NULL, or the - image located at ImageBase was not a valid PE/COFF image - @retval EFI_OUT_OF_RESOURCES Failure to Allocate() - @retval EFI_ABORTED The input Alignment was non-NULL and did not match the - alignment specified in the PE/COFF header - @retval EFI_SUCCESS The image properties record was successfully created -**/ -EFI_STATUS -EFIAPI -CreateImagePropertiesRecord ( - IN CONST VOID *ImageBase, - IN CONST UINT64 ImageSize, - IN CONST UINT32 *Alignment OPTIONAL, - OUT IMAGE_PROPERTIES_RECORD *ImageRecord - ); - /** Deleted an image properties record. The function will also call RemoveEntryList() on each code segment and the input ImageRecord before @@ -228,7 +74,7 @@ CreateImagePropertiesRecord ( VOID EFIAPI DeleteImagePropertiesRecord ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord + IN UEFI_IMAGE_RECORD *ImageRecord ); #endif diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c index ef32771561..9825fdaeab 100644 --- a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c +++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c @@ -462,9 +462,9 @@ GetModuleInfoFromHandle ( EFI_STATUS Status; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; - CHAR8 *PdbFileName; + //CHAR8 *PdbFileName; EFI_GUID *TempGuid; - UINTN StartIndex; + //UINTN StartIndex; UINTN Index; INTN Count; BOOLEAN ModuleGuidIsGet; @@ -558,7 +558,8 @@ GetModuleInfoFromHandle ( // // Method 1 Get Module Name from PDB string. // - PdbFileName = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase); + // FIXME: + /*PdbFileName = UefiImageLoaderGetPdbPointer (LoadedImage->ImageBase); if ((PdbFileName != NULL) && (BufferSize > 0)) { StartIndex = 0; for (Index = 0; PdbFileName[Index] != 0; Index++) { @@ -587,7 +588,7 @@ GetModuleInfoFromHandle ( // Module Name is got. // goto Done; - } + }*/ } // diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf index 599d4dea66..0a36591c63 100644 --- a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf +++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf @@ -54,7 +54,6 @@ UefiLib ReportStatusCodeLib DxeServicesLib - PeCoffGetEntryPointLib DevicePathLib [Protocols] diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLibInternal.h b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLibInternal.h index 8f32018c06..155e71555a 100644 --- a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLibInternal.h +++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLibInternal.h @@ -42,7 +42,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include /** Create performance record with event description and a timestamp. diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c index 08e3311d15..22a1a7cc5a 100644 --- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c +++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ @@ -60,39 +59,6 @@ EfiSizeToPages ( return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MASK) ? 1 : 0); } -/** - Frees the memory for each ImageRecordCodeSection within an ImageRecord - and removes the entries from the list. It does not free the ImageRecord - itself. - - @param[in] ImageRecord The ImageRecord in which to free code sections -**/ -STATIC -VOID -FreeImageRecordCodeSections ( - IMAGE_PROPERTIES_RECORD *ImageRecord - ) -{ - LIST_ENTRY *CodeSegmentListHead; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - - if (ImageRecord == NULL) { - return; - } - - CodeSegmentListHead = &ImageRecord->CodeSegmentList; - while (!IsListEmpty (CodeSegmentListHead)) { - ImageRecordCodeSection = CR ( - CodeSegmentListHead->ForwardLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - RemoveEntryList (&ImageRecordCodeSection->Link); - FreePool (ImageRecordCodeSection); - } -} - /** Sort memory map entries based upon PhysicalStart from low to high. @@ -146,15 +112,15 @@ SortMemoryMap ( @retval The first image record covered by [Buffer, Length] **/ STATIC -IMAGE_PROPERTIES_RECORD * +UEFI_IMAGE_RECORD * GetImageRecordByAddress ( IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length, IN LIST_ENTRY *ImageRecordList ) { - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; + UEFI_IMAGE_RECORD *ImageRecord; + LIST_ENTRY *ImageRecordLink; for (ImageRecordLink = ImageRecordList->ForwardLink; ImageRecordLink != ImageRecordList; @@ -162,13 +128,13 @@ GetImageRecordByAddress ( { ImageRecord = CR ( ImageRecordLink, - IMAGE_PROPERTIES_RECORD, + UEFI_IMAGE_RECORD, Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE + UEFI_IMAGE_RECORD_SIGNATURE ); - if ((Buffer <= ImageRecord->ImageBase) && - (Buffer + Length >= ImageRecord->ImageBase + ImageRecord->ImageSize)) + if ((Buffer <= ImageRecord->StartAddress) && + (Buffer + Length >= ImageRecord->EndAddress)) { return ImageRecord; } @@ -195,88 +161,48 @@ GetImageRecordByAddress ( STATIC UINTN SetNewRecord ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord, + IN UEFI_IMAGE_RECORD *ImageRecord, IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord, IN EFI_MEMORY_DESCRIPTOR *OldRecord, IN UINTN DescriptorSize ) { - EFI_MEMORY_DESCRIPTOR TempRecord; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - UINTN NewRecordCount; - UINT64 PhysicalEnd; - UINT64 ImageEnd; + EFI_MEMORY_DESCRIPTOR TempRecord; + UEFI_IMAGE_RECORD_SEGMENT *ImageRecordSegment; + UINTN SectionAddress; + UINT32 Index; + UINT32 NewRecordCount; CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR)); - PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages); + // + // Always create a new entry for non-PE image record + // NewRecordCount = 0; - - ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; - - ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink; - ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList; - while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection = CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - - if (TempRecord.PhysicalStart <= ImageRecordCodeSection->CodeSegmentBase) { - // - // DATA - // - NewRecord->Type = TempRecord.Type; - NewRecord->PhysicalStart = TempRecord.PhysicalStart; - NewRecord->VirtualStart = 0; - NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart); - NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP; - if (NewRecord->NumberOfPages != 0) { - NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); - NewRecordCount++; - } - - // - // CODE - // - NewRecord->Type = TempRecord.Type; - NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase; - NewRecord->VirtualStart = 0; - NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize); - NewRecord->Attribute = (TempRecord.Attribute & (~EFI_MEMORY_XP)) | EFI_MEMORY_RO; - if (NewRecord->NumberOfPages != 0) { - NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); - NewRecordCount++; - } - - TempRecord.PhysicalStart = ImageRecordCodeSection->CodeSegmentBase + EfiPagesToSize (EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize)); - TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - TempRecord.PhysicalStart); - if (TempRecord.NumberOfPages == 0) { - break; - } - } + if (ImageRecord->StartAddress > TempRecord.PhysicalStart) { + NewRecord->Type = TempRecord.Type; + NewRecord->PhysicalStart = TempRecord.PhysicalStart; + NewRecord->VirtualStart = 0; + NewRecord->NumberOfPages = EfiSizeToPages (ImageRecord->StartAddress - TempRecord.PhysicalStart); + NewRecord->Attribute = TempRecord.Attribute; + NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); + ++NewRecordCount; } - ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize; + SectionAddress = ImageRecord->StartAddress; + for (Index = 0; Index < ImageRecord->NumSegments; ++Index) { + ImageRecordSegment = &ImageRecord->Segments[Index]; - // - // Final DATA - // - if (TempRecord.PhysicalStart < ImageEnd) { NewRecord->Type = TempRecord.Type; - NewRecord->PhysicalStart = TempRecord.PhysicalStart; + NewRecord->PhysicalStart = SectionAddress; NewRecord->VirtualStart = 0; - NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart); - NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP; - NewRecordCount++; + NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordSegment->Size); + NewRecord->Attribute = (TempRecord.Attribute & ~(UINT64) EFI_MEMORY_ACCESS_MASK) | ImageRecordSegment->Attributes; + NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); + + SectionAddress += ImageRecordSegment->Size; } - return NewRecordCount; + return NewRecordCount + ImageRecord->NumSegments; } /** @@ -298,29 +224,32 @@ GetMaxSplitRecordCount ( IN LIST_ENTRY *ImageRecordList ) { - IMAGE_PROPERTIES_RECORD *ImageRecord; - UINTN SplitRecordCount; - UINT64 PhysicalStart; - UINT64 PhysicalEnd; - + UEFI_IMAGE_RECORD *ImageRecord; + UINTN SplitRecordCount; + UINT64 PhysicalStart; + UINT64 PhysicalEnd; + // + // Per region, there may be one prefix, but the return value is the amount of + // new records in addition to the original one. + // SplitRecordCount = 0; PhysicalStart = OldRecord->PhysicalStart; PhysicalEnd = OldRecord->PhysicalStart + EfiPagesToSize (OldRecord->NumberOfPages); do { + // FIXME: Inline iteration to not always start anew? ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart, ImageRecordList); if (ImageRecord == NULL) { break; } - SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 3); - PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize; + // + // Per image, they may be one trailer. + // + SplitRecordCount += ImageRecord->NumSegments + 1; + PhysicalStart = ImageRecord->EndAddress; } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd)); - if (SplitRecordCount != 0) { - SplitRecordCount--; - } - return SplitRecordCount; } @@ -350,13 +279,13 @@ SplitRecord ( IN LIST_ENTRY *ImageRecordList ) { - EFI_MEMORY_DESCRIPTOR TempRecord; - IMAGE_PROPERTIES_RECORD *ImageRecord; - IMAGE_PROPERTIES_RECORD *NewImageRecord; - UINT64 PhysicalStart; - UINT64 PhysicalEnd; - UINTN NewRecordCount; - UINTN TotalNewRecordCount; + EFI_MEMORY_DESCRIPTOR TempRecord; + UEFI_IMAGE_RECORD *ImageRecord; + UEFI_IMAGE_RECORD *NewImageRecord; + UINT64 PhysicalStart; + UINT64 PhysicalEnd; + UINTN NewRecordCount; + UINTN TotalNewRecordCount; if (MaxSplitRecordCount == 0) { CopyMem (NewRecord, OldRecord, DescriptorSize); @@ -397,15 +326,15 @@ SplitRecord ( // // Update PhysicalStart to exclude the portion before the image buffer // - if (TempRecord.PhysicalStart < ImageRecord->ImageBase) { + if (TempRecord.PhysicalStart < ImageRecord->StartAddress) { NewRecord->Type = TempRecord.Type; NewRecord->PhysicalStart = TempRecord.PhysicalStart; NewRecord->VirtualStart = 0; - NewRecord->NumberOfPages = EfiSizeToPages (ImageRecord->ImageBase - TempRecord.PhysicalStart); + NewRecord->NumberOfPages = EfiSizeToPages (ImageRecord->StartAddress - TempRecord.PhysicalStart); NewRecord->Attribute = TempRecord.Attribute; TotalNewRecordCount++; - PhysicalStart = ImageRecord->ImageBase; + PhysicalStart = ImageRecord->StartAddress; TempRecord.PhysicalStart = PhysicalStart; TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart); @@ -422,7 +351,7 @@ SplitRecord ( // // Update PhysicalStart, in order to exclude the image buffer already splitted. // - PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize; + PhysicalStart = ImageRecord->EndAddress; TempRecord.PhysicalStart = PhysicalStart; TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart); } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd)); @@ -550,623 +479,6 @@ SplitTable ( return EFI_SUCCESS; } -/** - Swap two code sections in a single IMAGE_PROPERTIES_RECORD. - - @param[in] FirstImageRecordCodeSection The first code section - @param[in] SecondImageRecordCodeSection The second code section - - @retval EFI_SUCCESS The code sections were swapped successfully - @retval EFI_INVALID_PARAMETER FirstImageRecordCodeSection or SecondImageRecordCodeSection is NULL -**/ -EFI_STATUS -EFIAPI -SwapImageRecordCodeSection ( - IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *FirstImageRecordCodeSection, - IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *SecondImageRecordCodeSection - ) -{ - IMAGE_PROPERTIES_RECORD_CODE_SECTION TempImageRecordCodeSection; - - if ((FirstImageRecordCodeSection == NULL) || (SecondImageRecordCodeSection == NULL)) { - return EFI_INVALID_PARAMETER; - } - - TempImageRecordCodeSection.CodeSegmentBase = FirstImageRecordCodeSection->CodeSegmentBase; - TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize; - - FirstImageRecordCodeSection->CodeSegmentBase = SecondImageRecordCodeSection->CodeSegmentBase; - FirstImageRecordCodeSection->CodeSegmentSize = SecondImageRecordCodeSection->CodeSegmentSize; - - SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase; - SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize; - - return EFI_SUCCESS; -} - -/** - Sort the code sections in the input ImageRecord based upon CodeSegmentBase from low to high. - - @param[in] ImageRecord IMAGE_PROPERTIES_RECORD to be sorted - - @retval EFI_SUCCESS The code sections in the input ImageRecord were sorted successfully - @retval EFI_ABORTED An error occurred while sorting the code sections in the input ImageRecord - @retval EFI_INVALID_PARAMETER ImageRecord is NULL -**/ -EFI_STATUS -EFIAPI -SortImageRecordCodeSection ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ) -{ - EFI_STATUS Status; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *NextImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *NextImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - - if (ImageRecord == NULL) { - return EFI_INVALID_PARAMETER; - } - - ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; - - ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink; - NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList; - while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection = CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - while (NextImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - NextImageRecordCodeSection = CR ( - NextImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) { - Status = SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return EFI_ABORTED; - } - } - - NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink; - } - - ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - } - - return EFI_SUCCESS; -} - -/** - Check if the code sections in the input ImageRecord are valid. - The code sections are valid if they don't overlap, are contained - within the the ImageRecord's ImageBase and ImageSize, and are - contained within the MAX_ADDRESS. - - @param[in] ImageRecord IMAGE_PROPERTIES_RECORD to be checked - - @retval TRUE The code sections in the input ImageRecord are valid - @retval FALSE The code sections in the input ImageRecord are invalid -**/ -BOOLEAN -EFIAPI -IsImageRecordCodeSectionValid ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ) -{ - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *LastImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - - if (ImageRecord == NULL) { - return FALSE; - } - - DEBUG ((DEBUG_VERBOSE, "ImageCode SegmentCount - 0x%x\n", ImageRecord->CodeSegmentCount)); - - ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; - - ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink; - ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList; - LastImageRecordCodeSection = NULL; - while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection = CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - if (ImageRecordCodeSection->CodeSegmentSize == 0) { - return FALSE; - } - - if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) { - return FALSE; - } - - if (ImageRecordCodeSection->CodeSegmentBase >= MAX_ADDRESS - ImageRecordCodeSection->CodeSegmentSize) { - return FALSE; - } - - if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) { - return FALSE; - } - - if (LastImageRecordCodeSection != NULL) { - if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCodeSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) { - return FALSE; - } - } - - LastImageRecordCodeSection = ImageRecordCodeSection; - ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - } - - return TRUE; -} - -/** - Swap two image records. - - @param[in] FirstImageRecord The first image record. - @param[in] SecondImageRecord The second image record. - - @retval EFI_SUCCESS The image records were swapped successfully - @retval EFI_INVALID_PARAMETER FirstImageRecord or SecondImageRecord is NULL -**/ -EFI_STATUS -EFIAPI -SwapImageRecord ( - IN IMAGE_PROPERTIES_RECORD *FirstImageRecord, - IN IMAGE_PROPERTIES_RECORD *SecondImageRecord - ) -{ - IMAGE_PROPERTIES_RECORD TempImageRecord; - - if ((FirstImageRecord == NULL) || (SecondImageRecord == NULL)) { - return EFI_INVALID_PARAMETER; - } - - TempImageRecord.ImageBase = FirstImageRecord->ImageBase; - TempImageRecord.ImageSize = FirstImageRecord->ImageSize; - TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount; - - FirstImageRecord->ImageBase = SecondImageRecord->ImageBase; - FirstImageRecord->ImageSize = SecondImageRecord->ImageSize; - FirstImageRecord->CodeSegmentCount = SecondImageRecord->CodeSegmentCount; - - SecondImageRecord->ImageBase = TempImageRecord.ImageBase; - SecondImageRecord->ImageSize = TempImageRecord.ImageSize; - SecondImageRecord->CodeSegmentCount = TempImageRecord.CodeSegmentCount; - - SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord->CodeSegmentList); - return EFI_SUCCESS; -} - -/** - Sort the input ImageRecordList based upon the ImageBase from low to high. - - @param[in] ImageRecordList Image record list to be sorted - - @retval EFI_SUCCESS The image record list was sorted successfully - @retval EFI_ABORTED An error occurred while sorting the image record list - @retval EFI_INVALID_PARAMETER ImageRecordList is NULL -**/ -EFI_STATUS -EFIAPI -SortImageRecord ( - IN LIST_ENTRY *ImageRecordList - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - IMAGE_PROPERTIES_RECORD *NextImageRecord; - LIST_ENTRY *ImageRecordLink; - LIST_ENTRY *NextImageRecordLink; - LIST_ENTRY *ImageRecordEndLink; - EFI_STATUS Status; - - if (ImageRecordList == NULL) { - return EFI_INVALID_PARAMETER; - } - - ImageRecordLink = ImageRecordList->ForwardLink; - NextImageRecordLink = ImageRecordLink->ForwardLink; - ImageRecordEndLink = ImageRecordList; - while (ImageRecordLink != ImageRecordEndLink) { - ImageRecord = CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - while (NextImageRecordLink != ImageRecordEndLink) { - NextImageRecord = CR ( - NextImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - - ); - if (ImageRecord->ImageBase > NextImageRecord->ImageBase) { - Status = SwapImageRecord (ImageRecord, NextImageRecord); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return EFI_ABORTED; - } - } - - NextImageRecordLink = NextImageRecordLink->ForwardLink; - } - - ImageRecordLink = ImageRecordLink->ForwardLink; - NextImageRecordLink = ImageRecordLink->ForwardLink; - } - - return EFI_SUCCESS; -} - -/** - Extract the .efi filename out of the input PDB. - - @param[in] PdbPointer Pointer to the PDB file path. - @param[out] EfiFileName Pointer to the .efi filename. - @param[in] EfiFileNameSize Size of the .efi filename buffer. -**/ -STATIC -VOID -GetFilename ( - IN CHAR8 *PdbPointer, - OUT CHAR8 *EfiFileName, - IN UINTN EfiFileNameSize - ) -{ - UINTN Index; - UINTN StartIndex; - - if ((PdbPointer == NULL) || (EfiFileNameSize < 5)) { - return; - } - - // Print Module Name by Pdb file path. - StartIndex = 0; - for (Index = 0; PdbPointer[Index] != 0; Index++) { - if ((PdbPointer[Index] == '\\') || (PdbPointer[Index] == '/')) { - StartIndex = Index + 1; - } - } - - // Copy the PDB file name to EfiFileName and replace .pdb with .efi - for (Index = 0; Index < EfiFileNameSize - 4; Index++) { - EfiFileName[Index] = PdbPointer[Index + StartIndex]; - if (EfiFileName[Index] == 0) { - EfiFileName[Index] = '.'; - } - - if (EfiFileName[Index] == '.') { - EfiFileName[Index + 1] = 'e'; - EfiFileName[Index + 2] = 'f'; - EfiFileName[Index + 3] = 'i'; - EfiFileName[Index + 4] = 0; - break; - } - } - - if (Index == sizeof (EfiFileName) - 4) { - EfiFileName[Index] = 0; - } -} - -/** - Debug dumps the input list of IMAGE_PROPERTIES_RECORD structs. - - @param[in] ImageRecordList Head of the IMAGE_PROPERTIES_RECORD list -**/ -VOID -EFIAPI -DumpImageRecords ( - IN LIST_ENTRY *ImageRecordList - ) -{ - LIST_ENTRY *ImageRecordLink; - IMAGE_PROPERTIES_RECORD *CurrentImageRecord; - LIST_ENTRY *CodeSectionLink; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *CurrentCodeSection; - CHAR8 *PdbPointer; - CHAR8 EfiFileName[256]; - - if (ImageRecordList == NULL) { - return; - } - - ImageRecordLink = ImageRecordList->ForwardLink; - - while (ImageRecordLink != ImageRecordList) { - CurrentImageRecord = CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)CurrentImageRecord->ImageBase); - if (PdbPointer != NULL) { - GetFilename (PdbPointer, EfiFileName, sizeof (EfiFileName)); - DEBUG (( - DEBUG_INFO, - "%a: 0x%llx - 0x%llx\n", - EfiFileName, - CurrentImageRecord->ImageBase, - CurrentImageRecord->ImageBase + CurrentImageRecord->ImageSize - )); - } else { - DEBUG (( - DEBUG_INFO, - "Unknown Image: 0x%llx - 0x%llx\n", - CurrentImageRecord->ImageBase, - CurrentImageRecord->ImageBase + CurrentImageRecord->ImageSize - )); - } - - CodeSectionLink = CurrentImageRecord->CodeSegmentList.ForwardLink; - - while (CodeSectionLink != &CurrentImageRecord->CodeSegmentList) { - CurrentCodeSection = CR ( - CodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - - DEBUG (( - DEBUG_INFO, - " Code Section: 0x%llx - 0x%llx\n", - CurrentCodeSection->CodeSegmentBase, - CurrentCodeSection->CodeSegmentBase + CurrentCodeSection->CodeSegmentSize - )); - - CodeSectionLink = CodeSectionLink->ForwardLink; - } - - ImageRecordLink = ImageRecordLink->ForwardLink; - } -} - -/** - Find image record according to image base and size. - - @param[in] ImageBase Base of PE image - @param[in] ImageSize Size of PE image - @param[in] ImageRecordList Image record list to be searched - - @retval NULL No IMAGE_PROPERTIES_RECORD matches ImageBase - and ImageSize in the input ImageRecordList - @retval Other The found IMAGE_PROPERTIES_RECORD -**/ -IMAGE_PROPERTIES_RECORD * -EFIAPI -FindImageRecord ( - IN EFI_PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, - IN LIST_ENTRY *ImageRecordList - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; - - if (ImageRecordList == NULL) { - return NULL; - } - - for (ImageRecordLink = ImageRecordList->ForwardLink; - ImageRecordLink != ImageRecordList; - ImageRecordLink = ImageRecordLink->ForwardLink) - { - ImageRecord = CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - - if ((ImageBase == ImageRecord->ImageBase) && - (ImageSize == ImageRecord->ImageSize)) - { - return ImageRecord; - } - } - - return NULL; -} - -/** - Creates an IMAGE_PROPERTIES_RECORD from a loaded PE image. The PE/COFF header will be found - and parsed to determine the number of code segments and their base addresses and sizes. - - @param[in] ImageBase Base of the PE image - @param[in] ImageSize Size of the PE image - @param[in] RequiredAlignment If non-NULL, the alignment specified in the PE/COFF header - will be compared against this value. - @param[out] ImageRecord On out, a populated image properties record - - @retval EFI_INVALID_PARAMETER This function ImageBase or ImageRecord was NULL, or the - image located at ImageBase was not a valid PE/COFF image - @retval EFI_OUT_OF_RESOURCES Failure to Allocate() - @retval EFI_ABORTED The input Alignment was non-NULL and did not match the - alignment specified in the PE/COFF header - @retval EFI_SUCCESS The image properties record was successfully created -**/ -EFI_STATUS -EFIAPI -CreateImagePropertiesRecord ( - IN CONST VOID *ImageBase, - IN CONST UINT64 ImageSize, - IN CONST UINT32 *RequiredAlignment OPTIONAL, - OUT IMAGE_PROPERTIES_RECORD *ImageRecord - ) -{ - EFI_STATUS Status; - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - EFI_IMAGE_SECTION_HEADER *Section; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - UINTN Index; - UINT8 *Name; - UINT32 SectionAlignment; - UINT32 PeCoffHeaderOffset; - CHAR8 *PdbPointer; - - if ((ImageRecord == NULL) || (ImageBase == NULL)) { - return EFI_INVALID_PARAMETER; - } - - DEBUG (( - DEBUG_VERBOSE, - "Creating Image Properties Record: 0x%016lx - 0x%016lx\n", - (EFI_PHYSICAL_ADDRESS)(UINTN)ImageBase, - ImageSize - )); - - // - // Step 1: record whole region - // - Status = EFI_SUCCESS; - ImageRecord->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE; - ImageRecord->ImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)ImageBase; - ImageRecord->ImageSize = ImageSize; - ImageRecord->CodeSegmentCount = 0; - InitializeListHead (&ImageRecord->Link); - InitializeListHead (&ImageRecord->CodeSegmentList); - - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageBase); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer)); - } - - // Check PE/COFF image - DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageBase; - PeCoffHeaderOffset = 0; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - PeCoffHeaderOffset = DosHdr->e_lfanew; - } - - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *)(UINTN)ImageBase + PeCoffHeaderOffset); - if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { - DEBUG ((DEBUG_VERBOSE, "Hdr.Pe32->Signature invalid - 0x%x\n", Hdr.Pe32->Signature)); - return EFI_INVALID_PARAMETER; - } - - // Get SectionAlignment - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment; - } else { - SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment; - } - - // Check RequiredAlignment - if ((RequiredAlignment != NULL) && ((SectionAlignment & (*RequiredAlignment - 1)) != 0)) { - DEBUG (( - DEBUG_WARN, - "!!!!!!!! Image Section Alignment(0x%x) does not match Required Alignment (0x%x) !!!!!!!!\n", - SectionAlignment, - *RequiredAlignment - )); - - return EFI_ABORTED; - } - - Section = (EFI_IMAGE_SECTION_HEADER *)( - (UINT8 *)(UINTN)ImageBase + - PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - Hdr.Pe32->FileHeader.SizeOfOptionalHeader - ); - for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) { - Name = Section[Index].Name; - DEBUG (( - DEBUG_VERBOSE, - " Section - '%c%c%c%c%c%c%c%c'\n", - Name[0], - Name[1], - Name[2], - Name[3], - Name[4], - Name[5], - Name[6], - Name[7] - )); - - if ((Section[Index].Characteristics & EFI_IMAGE_SCN_CNT_CODE) != 0) { - DEBUG ((DEBUG_VERBOSE, " VirtualSize - 0x%08x\n", Section[Index].Misc.VirtualSize)); - DEBUG ((DEBUG_VERBOSE, " VirtualAddress - 0x%08x\n", Section[Index].VirtualAddress)); - DEBUG ((DEBUG_VERBOSE, " SizeOfRawData - 0x%08x\n", Section[Index].SizeOfRawData)); - DEBUG ((DEBUG_VERBOSE, " PointerToRawData - 0x%08x\n", Section[Index].PointerToRawData)); - DEBUG ((DEBUG_VERBOSE, " PointerToRelocations - 0x%08x\n", Section[Index].PointerToRelocations)); - DEBUG ((DEBUG_VERBOSE, " PointerToLinenumbers - 0x%08x\n", Section[Index].PointerToLinenumbers)); - DEBUG ((DEBUG_VERBOSE, " NumberOfRelocations - 0x%08x\n", Section[Index].NumberOfRelocations)); - DEBUG ((DEBUG_VERBOSE, " NumberOfLinenumbers - 0x%08x\n", Section[Index].NumberOfLinenumbers)); - DEBUG ((DEBUG_VERBOSE, " Characteristics - 0x%08x\n", Section[Index].Characteristics)); - - // Record code section(s) - ImageRecordCodeSection = AllocatePool (sizeof (*ImageRecordCodeSection)); - if (ImageRecordCodeSection == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto CreateImagePropertiesRecordEnd; - } - - ImageRecordCodeSection->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE; - - ImageRecordCodeSection->CodeSegmentBase = (UINTN)ImageBase + Section[Index].VirtualAddress; - // We still need to align the VirtualSize to the SectionAlignment because MSVC does not do - // this when creating a PE image. It expects the loader to do this. - ImageRecordCodeSection->CodeSegmentSize = ALIGN_VALUE (Section[Index].Misc.VirtualSize, SectionAlignment); - - InsertTailList (&ImageRecord->CodeSegmentList, &ImageRecordCodeSection->Link); - ImageRecord->CodeSegmentCount++; - } - } - - if (ImageRecord->CodeSegmentCount > 0) { - SortImageRecordCodeSection (ImageRecord); - } - - // - // Check overlap all section in ImageBase/Size - // - if (!IsImageRecordCodeSectionValid (ImageRecord)) { - DEBUG ((DEBUG_ERROR, "IsImageRecordCodeSectionValid - FAIL\n")); - Status = EFI_INVALID_PARAMETER; - goto CreateImagePropertiesRecordEnd; - } - - // - // Round up the ImageSize, some CPU arch may return EFI_UNSUPPORTED if ImageSize is not aligned. - // Given that the loader always allocates full pages, we know the space after the image is not used. - // - ImageRecord->ImageSize = ALIGN_VALUE (ImageRecord->ImageSize, EFI_PAGE_SIZE); - -CreateImagePropertiesRecordEnd: - if (EFI_ERROR (Status)) { - // we failed to create a valid record, free the section memory that was allocated - FreeImageRecordCodeSections (ImageRecord); - } - - return Status; -} - /** Deleted an image properties record. The function will also call RemoveEntryList() on each code segment and the input ImageRecord before @@ -1177,11 +489,9 @@ CreateImagePropertiesRecord ( VOID EFIAPI DeleteImagePropertiesRecord ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord + IN UEFI_IMAGE_RECORD *ImageRecord ) { - FreeImageRecordCodeSections (ImageRecord); - if (!IsListEmpty (&ImageRecord->Link)) { RemoveEntryList (&ImageRecord->Link); } diff --git a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf index 1f82cc3e46..43310f5553 100644 --- a/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf +++ b/MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf @@ -24,7 +24,7 @@ BaseMemoryLib DebugLib MemoryAllocationLib - PeCoffGetEntryPointLib + UefiImageLib [Packages] MdePkg/MdePkg.dec diff --git a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf index 5c51c48b0b..8812c96041 100644 --- a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf +++ b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf @@ -19,6 +19,9 @@ VERSION_STRING = 1.0 PI_SPECIFICATION_VERSION = 0x0001000A LIBRARY_CLASS = MemoryAllocationLib|SMM_CORE + # + # This function is defined in PiSmmCore. + # CONSTRUCTOR = PiSmmCoreMemoryAllocationLibConstructor # @@ -28,8 +31,6 @@ # [Sources] - MemoryAllocationLib.c - PiSmmCoreMemoryAllocationServices.h PiSmmCoreMemoryProfileLibNull.c [Packages] diff --git a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationProfileLib.inf b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationProfileLib.inf index 89658c0f6c..c3b8a4fdce 100644 --- a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationProfileLib.inf +++ b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationProfileLib.inf @@ -19,6 +19,9 @@ VERSION_STRING = 1.0 PI_SPECIFICATION_VERSION = 0x0001000A LIBRARY_CLASS = MemoryAllocationLib|SMM_CORE + # + # This function is defined in PiSmmCore. + # CONSTRUCTOR = PiSmmCoreMemoryAllocationLibConstructor LIBRARY_CLASS = MemoryProfileLib|SMM_CORE CONSTRUCTOR = PiSmmCoreMemoryProfileLibConstructor @@ -30,8 +33,6 @@ # [Sources] - MemoryAllocationLib.c - PiSmmCoreMemoryAllocationServices.h PiSmmCoreMemoryProfileLib.c PiSmmCoreMemoryProfileServices.h @@ -43,6 +44,7 @@ DebugLib BaseMemoryLib UefiBootServicesTableLib + MemoryAllocationLib [Guids] gEdkiiMemoryProfileGuid ## SOMETIMES_CONSUMES ## GUID # Locate protocol diff --git a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationServices.h b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationServices.h deleted file mode 100644 index 64429e028a..0000000000 --- a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationServices.h +++ /dev/null @@ -1,185 +0,0 @@ -/** @file - Contains function prototypes for Memory Services in the SMM Core. - - This header file borrows the PiSmmCore Memory Allocation services as the primitive - for memory allocation. - - Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _PI_SMM_CORE_MEMORY_ALLOCATION_SERVICES_H_ -#define _PI_SMM_CORE_MEMORY_ALLOCATION_SERVICES_H_ - -// -// It should be aligned with the definition in PiSmmCore. -// -typedef struct { - UINTN Signature; - - /// - /// The ImageHandle passed into the entry point of the SMM IPL. This ImageHandle - /// is used by the SMM Core to fill in the ParentImageHandle field of the Loaded - /// Image Protocol for each SMM Driver that is dispatched by the SMM Core. - /// - EFI_HANDLE SmmIplImageHandle; - - /// - /// The number of SMRAM ranges passed from the SMM IPL to the SMM Core. The SMM - /// Core uses these ranges of SMRAM to initialize the SMM Core memory manager. - /// - UINTN SmramRangeCount; - - /// - /// A table of SMRAM ranges passed from the SMM IPL to the SMM Core. The SMM - /// Core uses these ranges of SMRAM to initialize the SMM Core memory manager. - /// - EFI_SMRAM_DESCRIPTOR *SmramRanges; - - /// - /// The SMM Foundation Entry Point. The SMM Core fills in this field when the - /// SMM Core is initialized. The SMM IPL is responsbile for registering this entry - /// point with the SMM Configuration Protocol. The SMM Configuration Protocol may - /// not be available at the time the SMM IPL and SMM Core are started, so the SMM IPL - /// sets up a protocol notification on the SMM Configuration Protocol and registers - /// the SMM Foundation Entry Point as soon as the SMM Configuration Protocol is - /// available. - /// - EFI_SMM_ENTRY_POINT SmmEntryPoint; - - /// - /// Boolean flag set to TRUE while an SMI is being processed by the SMM Core. - /// - BOOLEAN SmmEntryPointRegistered; - - /// - /// Boolean flag set to TRUE while an SMI is being processed by the SMM Core. - /// - BOOLEAN InSmm; - - /// - /// This field is set by the SMM Core then the SMM Core is initialized. This field is - /// used by the SMM Base 2 Protocol and SMM Communication Protocol implementations in - /// the SMM IPL. - /// - EFI_SMM_SYSTEM_TABLE2 *Smst; - - /// - /// This field is used by the SMM Communicatioon Protocol to pass a buffer into - /// a software SMI handler and for the software SMI handler to pass a buffer back to - /// the caller of the SMM Communication Protocol. - /// - VOID *CommunicationBuffer; - - /// - /// This field is used by the SMM Communicatioon Protocol to pass the size of a buffer, - /// in bytes, into a software SMI handler and for the software SMI handler to pass the - /// size, in bytes, of a buffer back to the caller of the SMM Communication Protocol. - /// - UINTN BufferSize; - - /// - /// This field is used by the SMM Communication Protocol to pass the return status from - /// a software SMI handler back to the caller of the SMM Communication Protocol. - /// - EFI_STATUS ReturnStatus; - - EFI_PHYSICAL_ADDRESS PiSmmCoreImageBase; - UINT64 PiSmmCoreImageSize; - EFI_PHYSICAL_ADDRESS PiSmmCoreEntryPoint; -} SMM_CORE_PRIVATE_DATA; - -/** - Called to initialize the memory service. - - @param SmramRangeCount Number of SMRAM Regions - @param SmramRanges Pointer to SMRAM Descriptors - -**/ -VOID -SmmInitializeMemoryServices ( - IN UINTN SmramRangeCount, - IN EFI_SMRAM_DESCRIPTOR *SmramRanges - ); - -/** - Allocates pages from the memory map. - - @param Type The type of allocation to perform - @param MemoryType The type of memory to turn the allocated pages - into - @param NumberOfPages The number of pages to allocate - @param Memory A pointer to receive the base allocated memory - address - - @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. - @retval EFI_NOT_FOUND Could not allocate pages match the requirement. - @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. - @retval EFI_SUCCESS Pages successfully allocated. - -**/ -EFI_STATUS -EFIAPI -SmmAllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - OUT EFI_PHYSICAL_ADDRESS *Memory - ); - -/** - Frees previous allocated pages. - - @param Memory Base address of memory being freed - @param NumberOfPages The number of pages to free - - @retval EFI_NOT_FOUND Could not find the entry that covers the range - @retval EFI_INVALID_PARAMETER Address not aligned - @return EFI_SUCCESS Pages successfully freed. - -**/ -EFI_STATUS -EFIAPI -SmmFreePages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ); - -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER PoolType not valid - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -SmmAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ); - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -SmmFreePool ( - IN VOID *Buffer - ); - -#endif diff --git a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c index 2700f5adbc..2b6cd76d7f 100644 --- a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c +++ b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c @@ -272,9 +272,9 @@ GetModuleInfoFromHandle ( EFI_STATUS Status; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; - CHAR8 *PdbFileName; + //CHAR8 *PdbFileName; EFI_GUID *TempGuid; - UINTN StartIndex; + //UINTN StartIndex; UINTN Index; INTN Count; BOOLEAN ModuleGuidIsGet; @@ -367,7 +367,8 @@ GetModuleInfoFromHandle ( // // Method 1 Get Module Name from PDB string. // - PdbFileName = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase); + // FIXME: + /*PdbFileName = UefiImageLoaderGetPdbPointer (LoadedImage->ImageBase); if ((PdbFileName != NULL) && (BufferSize > 0)) { StartIndex = 0; for (Index = 0; PdbFileName[Index] != 0; Index++) { @@ -396,7 +397,7 @@ GetModuleInfoFromHandle ( // Module Name is got. // goto Done; - } + }*/ } if (ModuleGuidIsGet) { @@ -426,7 +427,7 @@ GetModuleInfoFromHandle ( } } -Done: +//Done: // // Copy Module Guid // diff --git a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf index 9a7e14e80c..cb8ab4897e 100644 --- a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf +++ b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf @@ -53,7 +53,6 @@ SmmMemLib UefiLib ReportStatusCodeLib - PeCoffGetEntryPointLib DxeServicesLib [Protocols] diff --git a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLibInternal.h b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLibInternal.h index 62b496484c..2f24117069 100644 --- a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLibInternal.h +++ b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLibInternal.h @@ -33,7 +33,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include #include #include diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c b/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c index 83a2f893e4..0e8154ae07 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c @@ -1213,82 +1213,6 @@ EfiBootManagerFreeLoadOptions ( return EFI_SUCCESS; } -/** - Return whether the PE header of the load option is valid or not. - - @param[in] Type The load option type. - It's used to check whether the load option is valid. - When it's LoadOptionTypeMax, the routine only guarantees - the load option is a valid PE image but doesn't guarantee - the PE's subsystem type is valid. - @param[in] FileBuffer The PE file buffer of the load option. - @param[in] FileSize The size of the load option file. - - @retval TRUE The PE header of the load option is valid. - @retval FALSE The PE header of the load option is not valid. -**/ -BOOLEAN -BmIsLoadOptionPeHeaderValid ( - IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE Type, - IN VOID *FileBuffer, - IN UINTN FileSize - ) -{ - EFI_IMAGE_DOS_HEADER *DosHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHeader; - EFI_IMAGE_OPTIONAL_HEADER32 *OptionalHeader; - UINT16 Subsystem; - - if ((FileBuffer == NULL) || (FileSize == 0)) { - return FALSE; - } - - // - // Read dos header - // - DosHeader = (EFI_IMAGE_DOS_HEADER *)FileBuffer; - if ((FileSize >= sizeof (EFI_IMAGE_DOS_HEADER)) && - (FileSize > DosHeader->e_lfanew) && (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) - ) - { - // - // Read and check PE signature - // - PeHeader = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINT8 *)FileBuffer + DosHeader->e_lfanew); - if ((FileSize >= DosHeader->e_lfanew + sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION)) && - (PeHeader->Pe32.Signature == EFI_IMAGE_NT_SIGNATURE) - ) - { - // - // Check PE32 or PE32+ magic, and machine type - // - OptionalHeader = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHeader->Pe32.OptionalHeader; - if ((OptionalHeader->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) || - (OptionalHeader->Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC)) - { - // - // Check the Subsystem: - // Driver#### must be of type BootServiceDriver or RuntimeDriver - // SysPrep####, Boot####, OsRecovery####, PlatformRecovery#### must be of type Application - // - Subsystem = OptionalHeader->Subsystem; - if ((Type == LoadOptionTypeMax) || - ((Type == LoadOptionTypeDriver) && (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)) || - ((Type == LoadOptionTypeDriver) && (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)) || - ((Type == LoadOptionTypeSysPrep) && (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)) || - ((Type == LoadOptionTypeBoot) && (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)) || - ((Type == LoadOptionTypePlatformRecovery) && (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)) - ) - { - return TRUE; - } - } - } - } - - return FALSE; -} - /** Return the next matched load option buffer. The routine keeps calling BmGetNextLoadOptionDevicePath() until a valid @@ -1322,7 +1246,6 @@ BmGetNextLoadOptionBuffer ( EFI_DEVICE_PATH_PROTOCOL *CurFullPath; UINTN LocalFileSize; UINT32 AuthenticationStatus; - EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath; LocalFileSize = 0; FileBuffer = NULL; @@ -1342,22 +1265,6 @@ BmGetNextLoadOptionBuffer ( } FileBuffer = GetFileBufferByFilePath (TRUE, CurFullPath, &LocalFileSize, &AuthenticationStatus); - if ((FileBuffer != NULL) && !BmIsLoadOptionPeHeaderValid (Type, FileBuffer, LocalFileSize)) { - // - // Free the RAM disk file system if the load option is invalid. - // - RamDiskDevicePath = BmGetRamDiskDevicePath (FilePath); - if (RamDiskDevicePath != NULL) { - BmDestroyRamDisk (RamDiskDevicePath); - FreePool (RamDiskDevicePath); - } - - // - // Free the invalid load option buffer. - // - FreePool (FileBuffer); - FileBuffer = NULL; - } } while (FileBuffer == NULL); if (FileBuffer == NULL) { @@ -1399,6 +1306,7 @@ EfiBootManagerProcessLoadOption ( EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; VOID *FileBuffer; UINTN FileSize; + EFI_DEVICE_PATH_PROTOCOL *RamDiskDevicePath; if ((UINT32)LoadOption->OptionType >= LoadOptionTypeMax) { return EFI_INVALID_PARAMETER; @@ -1476,6 +1384,15 @@ EfiBootManagerProcessLoadOption ( if (Status == EFI_SECURITY_VIOLATION) { gBS->UnloadImage (ImageHandle); } + + // + // Free the RAM disk file system if the load option is invalid. + // + RamDiskDevicePath = BmGetRamDiskDevicePath (LoadOption->FilePath); + if (RamDiskDevicePath != NULL) { + BmDestroyRamDisk (RamDiskDevicePath); + FreePool (RamDiskDevicePath); + } } else { Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&ImageInfo); ASSERT_EFI_ERROR (Status); diff --git a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h index 76ee0a83bf..a2782f0cbc 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h +++ b/MdeModulePkg/Library/UefiBootManagerLib/InternalBm.h @@ -14,7 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include +#include #include #include #include @@ -64,7 +64,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include #include #include #include diff --git a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf index 2fc0a80a4e..6a32f5128d 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf +++ b/MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf @@ -52,7 +52,6 @@ BaseMemoryLib DevicePathLib PerformanceLib - PeCoffGetEntryPointLib UefiBootServicesTableLib UefiRuntimeServicesTableLib DxeServicesTableLib diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index b9bc7041f2..263435caf2 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -587,7 +587,7 @@ ## Load File protocol provides capability to load and unload EFI image into memory and execute it. # Include/Protocol/LoadPe32Image.h # This protocol is deprecated. Native EDKII module should NOT use this protocol to load/unload image. - # If developer need implement such functionality, they should use BasePeCoffLib. + # If developer need implement such functionality, they should use BasePeCoffLib2. gEfiLoadPeImageProtocolGuid = { 0x5CB5C776, 0x60D5, 0x45EE, { 0x88, 0x3C, 0x45, 0x27, 0x08, 0xCD, 0x74, 0x3F }} ## Print protocols define basic print functions to print the format unicode and ascii string. @@ -1516,7 +1516,7 @@ # e.g. 0x7BD4 can be used for all memory except Code and ACPINVS/Reserved.
# # @Prompt Set DXE memory protection policy. - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x0000000|UINT64|0x00001048 + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFFD5|UINT64|0x00001048 ## PCI Serial Device Info. It is an array of Device, Function, and Power Management # information that describes the path that contains zero or more PCI to PCI bridges diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index ebceafcdd0..08c2530d11 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -43,8 +43,8 @@ PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf # # UEFI & PI @@ -81,7 +81,7 @@ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf index fb149c2f02..22a28df8e6 100644 --- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf +++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf @@ -49,7 +49,7 @@ UefiDriverEntryPoint BaseLib S3BootScriptLib - PeCoffLib + UefiImageLib DxeServicesLib UefiBootServicesTableLib CacheMaintenanceLib @@ -59,6 +59,7 @@ CpuExceptionHandlerLib DevicePathLib DxeServicesTableLib + MemoryAllocationLib [Guids] gEfiBootScriptExecutorVariableGuid ## PRODUCES ## UNDEFINED # SaveLockBox diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c index 98c5abecf8..4599425859 100644 --- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c +++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c @@ -227,8 +227,7 @@ S3BootScriptExecutorEntryFunction ( VOID RegisterMemoryProfileImage ( IN EFI_GUID *FileName, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, IN EFI_FV_FILETYPE FileType ) { @@ -247,8 +246,7 @@ RegisterMemoryProfileImage ( Status = ProfileProtocol->RegisterImage ( ProfileProtocol, (EFI_DEVICE_PATH_PROTOCOL *)FilePath, - ImageBase, - ImageSize, + ImageContext, FileType ); } @@ -275,9 +273,11 @@ ReadyToLockEventNotify ( UINTN BufferSize; EFI_HANDLE NewImageHandle; UINTN Pages; - EFI_PHYSICAL_ADDRESS FfsBuffer; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UINT32 ImageSize; + UINT32 ImageAlignment; EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc; + EFI_PHYSICAL_ADDRESS LoadAddress; Status = gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface); if (EFI_ERROR (Status)) { @@ -307,56 +307,40 @@ ReadyToLockEventNotify ( &BufferSize ); ASSERT_EFI_ERROR (Status); - ImageContext.Handle = Buffer; - ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; // // Get information about the image being loaded // - Status = PeCoffLoaderGetImageInfo (&ImageContext); + Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize); ASSERT_EFI_ERROR (Status); - if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) { - Pages = EFI_SIZE_TO_PAGES ((UINTN)(ImageContext.ImageSize + ImageContext.SectionAlignment)); - } else { - Pages = EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize); - } - - FfsBuffer = 0xFFFFFFFF; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiReservedMemoryType, - Pages, - &FfsBuffer - ); + ImageSize = UefiImageGetImageSize (&ImageContext); + ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext); + Pages = EFI_SIZE_TO_PAGES (ImageSize); + LoadAddress = 0xFFFFFFFF; + Status = AllocateAlignedPagesEx ( + AllocateMaxAddress, + EfiReservedMemoryType, + Pages, + ImageAlignment, + &LoadAddress + ); ASSERT_EFI_ERROR (Status); // // Make sure that the buffer can be used to store code. // - Status = gDS->GetMemorySpaceDescriptor (FfsBuffer, &MemDesc); + Status = gDS->GetMemorySpaceDescriptor (LoadAddress, &MemDesc); if (!EFI_ERROR (Status) && ((MemDesc.Attributes & EFI_MEMORY_XP) != 0)) { gDS->SetMemorySpaceAttributes ( - FfsBuffer, + LoadAddress, EFI_PAGES_TO_SIZE (Pages), MemDesc.Attributes & (~EFI_MEMORY_XP) ); } - ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer; - // - // Align buffer on section boundary - // - ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; - ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1); // // Load the image to our new buffer // - Status = PeCoffLoaderLoadImage (&ImageContext); - ASSERT_EFI_ERROR (Status); - - // - // Relocate the image in our new buffer - // - Status = PeCoffLoaderRelocateImage (&ImageContext); + Status = UefiImageLoadImageForExecution (&ImageContext, (VOID *)(UINTN)LoadAddress, ImageSize, NULL, 0); ASSERT_EFI_ERROR (Status); // @@ -364,19 +348,13 @@ ReadyToLockEventNotify ( // gBS->FreePool (Buffer); - // - // Flush the instruction cache so the image data is written before we execute it - // - InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); - RegisterMemoryProfileImage ( &gEfiCallerIdGuid, - ImageContext.ImageAddress, - ImageContext.ImageSize, + &ImageContext, EFI_FV_FILETYPE_DRIVER ); - Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint))(NewImageHandle, gST); + Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(UefiImageLoaderGetImageEntryPoint (&ImageContext)))(NewImageHandle, gST); ASSERT_EFI_ERROR (Status); // @@ -385,8 +363,8 @@ ReadyToLockEventNotify ( // Status = SaveLockBox ( &mBootScriptExecutorImageGuid, - (VOID *)(UINTN)ImageContext.ImageAddress, - (UINTN)ImageContext.ImageSize + (VOID *)(UINTN)LoadAddress, + (UINTN)UefiImageGetImageSize (&ImageContext) ); ASSERT_EFI_ERROR (Status); diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h index 0ea38223d7..c18e6ed551 100644 --- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h +++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.h @@ -21,7 +21,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +#include #include #include #include @@ -34,6 +34,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include #include #include diff --git a/MdeModulePkg/Universal/CapsulePei/Capsule.h b/MdeModulePkg/Universal/CapsulePei/Capsule.h index c16f83a07a..7e3ee64d5f 100644 --- a/MdeModulePkg/Universal/CapsulePei/Capsule.h +++ b/MdeModulePkg/Universal/CapsulePei/Capsule.h @@ -25,13 +25,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include -#include +#include #include #include #include #include -#include +#include #include "Common/CommonHeader.h" #ifdef MDE_CPU_IA32 diff --git a/MdeModulePkg/Universal/CapsulePei/CapsulePei.inf b/MdeModulePkg/Universal/CapsulePei/CapsulePei.inf index e5078c7986..832f97683a 100644 --- a/MdeModulePkg/Universal/CapsulePei/CapsulePei.inf +++ b/MdeModulePkg/Universal/CapsulePei/CapsulePei.inf @@ -53,7 +53,6 @@ ReportStatusCodeLib [LibraryClasses.IA32] - PeCoffGetEntryPointLib PcdLib DebugAgentLib diff --git a/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c b/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c index 8e26a7d795..a155078ed8 100644 --- a/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c +++ b/MdeModulePkg/Universal/CapsulePei/UefiCapsule.c @@ -542,7 +542,9 @@ FindCapsuleCoalesceImage ( return Status; } - *CoalesceImageMachineType = PeCoffLoaderGetMachineType ((VOID *)(UINTN)CoalesceImageAddress); + *CoalesceImageMachineType = EFI_IMAGE_MACHINE_X64; + // FIXME: Get machine type from context once PPI is adapted + //*CoalesceImageMachineType = UefiImageLoaderGetMachineType ((VOID *)(UINTN)CoalesceImageAddress); break; } else { continue; diff --git a/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf b/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf index e942317603..ef0ed4936c 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf +++ b/MdeModulePkg/Universal/EbcDxe/EbcDebugger.inf @@ -85,7 +85,6 @@ DebugLib BaseLib CacheMaintenanceLib - PeCoffLib [Protocols] gEfiDebugSupportProtocolGuid ## PRODUCES diff --git a/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSymbol.c b/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSymbol.c index 834c90e32a..cf8ff3d371 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSymbol.c +++ b/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSymbol.c @@ -759,107 +759,6 @@ EdbLoadSymbol ( return EFI_SUCCESS; } -/** - - Located PDB path name in PE image. - - @param ImageBase - base of PE to search - - @return Pointer into image at offset of PDB file name if PDB file name is found, - Otherwise a pointer to an empty string. - -**/ -CHAR8 * -GetPdbPath ( - VOID *ImageBase - ) -{ - CHAR8 *PdbPath; - UINT32 DirCount; - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - EFI_IMAGE_OPTIONAL_HEADER32 *OptionalHdr32; - EFI_IMAGE_OPTIONAL_HEADER64 *OptionalHdr64; - EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; - VOID *CodeViewEntryPointer; - - // - // Init value - // - CodeViewEntryPointer = NULL; - PdbPath = NULL; - DosHdr = ImageBase; - - // - // Check magic - // - if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - return NULL; - } - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINT8 *)DosHdr + DosHdr->e_lfanew); - // - // Check Machine, filter for EBC - // - if (NtHdr->Pe32.FileHeader.Machine != EFI_IMAGE_MACHINE_EBC) { - // - // If not EBC, return NULL - // - return NULL; - } - - // - // Get DirectoryEntry - // EBC spec says PE32+, but implementation uses PE32. So check dynamically here. - // - if (NtHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - OptionalHdr32 = (VOID *)&NtHdr->Pe32.OptionalHeader; - DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(OptionalHdr32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - } else if (NtHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - OptionalHdr64 = (VOID *)&NtHdr->Pe32Plus.OptionalHeader; - DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(OptionalHdr64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - } else { - return NULL; - } - - if (DirectoryEntry->VirtualAddress == 0) { - return NULL; - } - - // - // Go through DirectoryEntry - // - for (DirCount = 0; - (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && CodeViewEntryPointer == NULL; - DirCount++ - ) - { - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(DirectoryEntry->VirtualAddress + (UINTN)ImageBase + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)); - if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { - // - // Match DebugEntry, only CODEVIEW_SIGNATURE_NB10 and CODEVIEW_SIGNATURE_RSDS are supported. - // - CodeViewEntryPointer = (VOID *)((UINTN)DebugEntry->RVA + (UINTN)ImageBase); - switch (*(UINT32 *)CodeViewEntryPointer) { - case CODEVIEW_SIGNATURE_NB10: - PdbPath = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY); - break; - case CODEVIEW_SIGNATURE_RSDS: - PdbPath = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY); - break; - default: - break; - } - } - } - - // - // Done successfully - // - return PdbPath; -} - /** Check whether PDB file and MAP file have same name. @@ -873,14 +772,14 @@ GetPdbPath ( **/ BOOLEAN MatchPdbAndMap ( - IN CHAR8 *PdbFileName, - IN CHAR16 *MapFileName + IN CONST CHAR8 *PdbFileName, + IN CONST CHAR16 *MapFileName ) { - UINTN PdbNameSize; - UINTN MapNameSize; - CHAR8 *PurePdbFileName; - UINTN Index; + UINTN PdbNameSize; + UINTN MapNameSize; + CONST CHAR8 *PurePdbFileName; + UINTN Index; // // remove dir name @@ -1003,7 +902,7 @@ EdbPatchSymbolRVA ( EFI_STATUS Status; UINTN ImageNumber; EFI_DEBUG_IMAGE_INFO *ImageTable; - CHAR8 *PdbPath; + CONST CHAR8 *PdbPath; VOID *ImageBase; VOID *CandidateImageBase; EFI_DEBUGGER_SYMBOL_OBJECT *Object; @@ -1058,7 +957,7 @@ EdbPatchSymbolRVA ( // // Get PDB path // - PdbPath = GetPdbPath (ImageBase); + PdbPath = ImageTable[ImageNumber].NormalImage->PdbPath; if (PdbPath == NULL) { continue; } diff --git a/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf b/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf index 8f5fcbeb82..9ca18d8ec6 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf +++ b/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf @@ -53,7 +53,6 @@ [LibraryClasses] CacheMaintenanceLib MemoryAllocationLib - PeCoffLib UefiBootServicesTableLib BaseMemoryLib UefiDriverEntryPoint diff --git a/MdeModulePkg/Universal/EbcDxe/EbcInt.c b/MdeModulePkg/Universal/EbcDxe/EbcInt.c index d2254c2765..46c4020102 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcInt.c +++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.c @@ -405,27 +405,6 @@ EbcRegisterImage ( 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 diff --git a/MdeModulePkg/Universal/EbcDxe/EbcInt.h b/MdeModulePkg/Universal/EbcDxe/EbcInt.h index 646e3a613b..df3f11b1d4 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcInt.h +++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.h @@ -12,6 +12,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include +#include + #include #include #include @@ -21,7 +23,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include #include #include #include diff --git a/MdePkg/Include/Guid/DebugImageInfoTable.h b/MdePkg/Include/Guid/DebugImageInfoTable.h index 6661c4dd6a..82f337f67e 100644 --- a/MdePkg/Include/Guid/DebugImageInfoTable.h +++ b/MdePkg/Include/Guid/DebugImageInfoTable.h @@ -47,6 +47,7 @@ typedef struct { /// Indicates the image handle of the associated image. /// EFI_HANDLE ImageHandle; + CHAR8 *PdbPath; } EFI_DEBUG_IMAGE_INFO_NORMAL; typedef union { diff --git a/MdePkg/Include/Guid/WinCertificate.h b/MdePkg/Include/Guid/WinCertificate.h index 3b81a8a769..d29dc0ed17 100644 --- a/MdePkg/Include/Guid/WinCertificate.h +++ b/MdePkg/Include/Guid/WinCertificate.h @@ -56,7 +56,7 @@ typedef struct { /// WIN_CERTIFICATE_UEFI_GUID.CertData /// typedef struct { - EFI_GUID HashType; + GUID HashType; UINT8 PublicKey[256]; UINT8 Signature[256]; } EFI_CERT_BLOCK_RSA_2048_SHA256; @@ -74,14 +74,14 @@ typedef struct { /// This is the unique id which determines the /// format of the CertData. . /// - EFI_GUID CertType; + GUID CertType; /// /// The following is the certificate data. The format of /// the data is determined by the CertType. /// If CertType is EFI_CERT_TYPE_RSA2048_SHA256_GUID, /// the CertData will be EFI_CERT_BLOCK_RSA_2048_SHA256 structure. /// - UINT8 CertData[1]; + UINT8 CertData[]; } WIN_CERTIFICATE_UEFI_GUID; /// @@ -102,7 +102,7 @@ typedef struct { /// This is the hashing algorithm which was performed on the /// UEFI executable when creating the digital signature. /// - EFI_GUID HashAlgorithm; + GUID HashAlgorithm; /// /// The following is the actual digital signature. The /// size of the signature is the same size as the key @@ -111,10 +111,9 @@ typedef struct { /// from the total length of the certificate as found in /// Hdr.dwLength. /// - /// UINT8 Signature[]; - /// + UINT8 Signature[]; } WIN_CERTIFICATE_EFI_PKCS1_15; -extern EFI_GUID gEfiCertTypeRsa2048Sha256Guid; +extern GUID gEfiCertTypeRsa2048Sha256Guid; #endif diff --git a/MdePkg/Include/IndustryStandard/PeImage.h b/MdePkg/Include/IndustryStandard/PeImage.h index 596c2fc3cd..cfcabad63f 100644 --- a/MdePkg/Include/IndustryStandard/PeImage.h +++ b/MdePkg/Include/IndustryStandard/PeImage.h @@ -1,3 +1,5 @@ +#ifndef DISABLE_NEW_DEPRECATED_INTERFACES + /** @file EFI image format for PE32, PE32+ and TE. Please note some data structures are different for PE32 and PE32+. EFI_IMAGE_NT_HEADERS32 is for PE32 and @@ -25,7 +27,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10 #define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 #define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 -#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13///< defined PI Specification, 1.0 +#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 ///< defined PI Specification, 1.0 // // PE32+ Machine type for EFI images @@ -191,7 +193,7 @@ typedef struct { /// EFI_IMAGE_OPTIONAL_HEADER64 must be used. The data structures only vary /// after NT additional fields. /// -#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b +#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b /// /// Optional Header Standard Fields for PE32+. @@ -232,32 +234,33 @@ typedef struct { UINT64 SizeOfHeapCommit; UINT32 LoaderFlags; UINT32 NumberOfRvaAndSizes; - EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; + EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; } EFI_IMAGE_OPTIONAL_HEADER64; + /// /// @attention /// EFI_IMAGE_NT_HEADERS32 is for use ONLY by tools. /// typedef struct { - UINT32 Signature; - EFI_IMAGE_FILE_HEADER FileHeader; - EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader; + UINT32 Signature; + EFI_IMAGE_FILE_HEADER FileHeader; + EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader; } EFI_IMAGE_NT_HEADERS32; -#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32) +#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32) /// /// @attention /// EFI_IMAGE_HEADERS64 is for use ONLY by tools. /// typedef struct { - UINT32 Signature; - EFI_IMAGE_FILE_HEADER FileHeader; - EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader; + UINT32 Signature; + EFI_IMAGE_FILE_HEADER FileHeader; + EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader; } EFI_IMAGE_NT_HEADERS64; -#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64) +#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64) // // Other Windows Subsystem Values @@ -293,10 +296,10 @@ typedef struct { /// Section Table. This table immediately follows the optional header. /// typedef struct { - UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME]; + UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME]; union { - UINT32 PhysicalAddress; - UINT32 VirtualSize; + UINT32 PhysicalAddress; + UINT32 VirtualSize; } Misc; UINT32 VirtualAddress; UINT32 SizeOfRawData; @@ -311,7 +314,7 @@ typedef struct { /// /// Size of EFI_IMAGE_SECTION_HEADER. /// -#define EFI_IMAGE_SIZEOF_SECTION_HEADER 40 +#define EFI_IMAGE_SIZEOF_SECTION_HEADER 40 // // Section Flags Values @@ -518,9 +521,9 @@ typedef struct { /// /// Relocation types of RISC-V processor. /// -#define EFI_IMAGE_REL_BASED_RISCV_HI20 5 -#define EFI_IMAGE_REL_BASED_RISCV_LOW12I 7 -#define EFI_IMAGE_REL_BASED_RISCV_LOW12S 8 +#define EFI_IMAGE_REL_BASED_RISCV_HI20 5 +#define EFI_IMAGE_REL_BASED_RISCV_LOW12I 7 +#define EFI_IMAGE_REL_BASED_RISCV_LOW12S 8 // // Relocation types of LoongArch processor. @@ -572,6 +575,7 @@ typedef struct { /// #define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + // // DLL Support // @@ -634,6 +638,7 @@ typedef struct { EFI_IMAGE_THUNK_DATA *FirstThunk; } EFI_IMAGE_IMPORT_DESCRIPTOR; + /// /// Debug Directory Format. /// @@ -681,6 +686,7 @@ typedef struct { // } EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY; + /// /// Debug Data Structure defined by Apple Mach-O to Coff utility. /// @@ -725,12 +731,12 @@ typedef struct { /// Resource format. /// typedef struct { - UINT32 Characteristics; - UINT32 TimeDateStamp; - UINT16 MajorVersion; - UINT16 MinorVersion; - UINT16 NumberOfNamedEntries; - UINT16 NumberOfIdEntries; + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT16 NumberOfNamedEntries; + UINT16 NumberOfIdEntries; // // Array of EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY entries goes here. // @@ -789,6 +795,7 @@ typedef struct { EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; ///< Only base relocation and debug directory. } EFI_TE_IMAGE_HEADER; + #define EFI_TE_IMAGE_HEADER_SIGNATURE SIGNATURE_16('V', 'Z') // @@ -797,20 +804,23 @@ typedef struct { #define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0 #define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1 + /// /// Union of PE32, PE32+, and TE headers. /// typedef union { - EFI_IMAGE_NT_HEADERS32 Pe32; - EFI_IMAGE_NT_HEADERS64 Pe32Plus; - EFI_TE_IMAGE_HEADER Te; + EFI_IMAGE_NT_HEADERS32 Pe32; + EFI_IMAGE_NT_HEADERS64 Pe32Plus; + EFI_TE_IMAGE_HEADER Te; } EFI_IMAGE_OPTIONAL_HEADER_UNION; typedef union { - EFI_IMAGE_NT_HEADERS32 *Pe32; - EFI_IMAGE_NT_HEADERS64 *Pe32Plus; - EFI_TE_IMAGE_HEADER *Te; - EFI_IMAGE_OPTIONAL_HEADER_UNION *Union; + EFI_IMAGE_NT_HEADERS32 *Pe32; + EFI_IMAGE_NT_HEADERS64 *Pe32Plus; + EFI_TE_IMAGE_HEADER *Te; + EFI_IMAGE_OPTIONAL_HEADER_UNION *Union; } EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION; #endif + +#endif // DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/MdePkg/Include/IndustryStandard/PeImage2.h b/MdePkg/Include/IndustryStandard/PeImage2.h new file mode 100644 index 0000000000..d5a69f7886 --- /dev/null +++ b/MdePkg/Include/IndustryStandard/PeImage2.h @@ -0,0 +1,761 @@ +/** @file + EFI image format for PE32, PE32+ and TE. Please note some data structures are + different for PE32 and PE32+. EFI_IMAGE_NT_HEADERS32 is for PE32 and + EFI_IMAGE_NT_HEADERS64 is for PE32+. + This file is coded to the Visual Studio, Microsoft Portable Executable and + Common Object File Format Specification, Revision 8.3 - February 6, 2013. + This file also includes some definitions in PI Specification, Revision 1.0. + + Copyright (c) 2020, Marvin Häuser. All rights reserved.
+ Copyright (c) 2020, Vitaly Cheptsov. All rights reserved.
+ Copyright (c) 2020, ISP RAS. All rights reserved.
+ Portions copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+ Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef PE_COFF_IMAGE2_H_ +#define PE_COFF_IMAGE2_H_ + +// +// PE32+ Subsystem type for EFI images +// +#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 ///< defined PI Specification, 1.0 + + +// +// PE32+ Machine type for EFI images +// +#define IMAGE_FILE_MACHINE_I386 0x014c +#define IMAGE_FILE_MACHINE_IA64 0x0200 +#define IMAGE_FILE_MACHINE_EBC 0x0EBC +#define IMAGE_FILE_MACHINE_X64 0x8664 +#define IMAGE_FILE_MACHINE_ARMTHUMB_MIXED 0x01c2 +#define IMAGE_FILE_MACHINE_ARM64 0xAA64 +#define IMAGE_FILE_MACHINE_RISCV32 0x5032 +#define IMAGE_FILE_MACHINE_RISCV64 0x5064 +#define IMAGE_FILE_MACHINE_RISCV128 0x5128 + +// +// EXE file formats +// +#define EFI_IMAGE_DOS_SIGNATURE SIGNATURE_16('M', 'Z') +#define EFI_IMAGE_OS2_SIGNATURE SIGNATURE_16('N', 'E') +#define EFI_IMAGE_OS2_SIGNATURE_LE SIGNATURE_16('L', 'E') +#define EFI_IMAGE_NT_SIGNATURE SIGNATURE_32('P', 'E', '\0', '\0') + +/// +/// PE images can start with an optional DOS header, so if an image is run +/// under DOS it can print an error message. +/// +typedef struct { + UINT16 e_magic; ///< Magic number. + UINT16 e_cblp; ///< Bytes on last page of file. + UINT16 e_cp; ///< Pages in file. + UINT16 e_crlc; ///< Relocations. + UINT16 e_cparhdr; ///< Size of header in paragraphs. + UINT16 e_minalloc; ///< Minimum extra paragraphs needed. + UINT16 e_maxalloc; ///< Maximum extra paragraphs needed. + UINT16 e_ss; ///< Initial (relative) SS value. + UINT16 e_sp; ///< Initial SP value. + UINT16 e_csum; ///< Checksum. + UINT16 e_ip; ///< Initial IP value. + UINT16 e_cs; ///< Initial (relative) CS value. + UINT16 e_lfarlc; ///< File address of relocation table. + UINT16 e_ovno; ///< Overlay number. + UINT16 e_res[4]; ///< Reserved words. + UINT16 e_oemid; ///< OEM identifier (for e_oeminfo). + UINT16 e_oeminfo; ///< OEM information; e_oemid specific. + UINT16 e_res2[10]; ///< Reserved words. + UINT32 e_lfanew; ///< File address of new exe header. +} EFI_IMAGE_DOS_HEADER; + +/// +/// COFF File Header (Object and Image). +/// +typedef struct { + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} EFI_IMAGE_FILE_HEADER; + +/// +/// Size of EFI_IMAGE_FILE_HEADER. +/// +#define EFI_IMAGE_SIZEOF_FILE_HEADER 20 + +// +// Characteristics +// +#define EFI_IMAGE_FILE_RELOCS_STRIPPED BIT0 ///< 0x0001 Relocation info stripped from file. +#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE BIT1 ///< 0x0002 File is executable (i.e. no unresolved externel references). +#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED BIT2 ///< 0x0004 Line numbers stripped from file. +#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED BIT3 ///< 0x0008 Local symbols stripped from file. +#define EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE BIT5 ///< 0x0020 Supports addresses > 2-GB +#define EFI_IMAGE_FILE_BYTES_REVERSED_LO BIT7 ///< 0x0080 Bytes of machine word are reversed. +#define EFI_IMAGE_FILE_32BIT_MACHINE BIT8 ///< 0x0100 32 bit word machine. +#define EFI_IMAGE_FILE_DEBUG_STRIPPED BIT9 ///< 0x0200 Debugging info stripped from file in .DBG file. +#define EFI_IMAGE_FILE_SYSTEM BIT12 ///< 0x1000 System File. +#define EFI_IMAGE_FILE_DLL BIT13 ///< 0x2000 File is a DLL. +#define EFI_IMAGE_FILE_BYTES_REVERSED_HI BIT15 ///< 0x8000 Bytes of machine word are reversed. + +/// +/// Header Data Directories. +/// +typedef struct { + UINT32 VirtualAddress; + UINT32 Size; +} EFI_IMAGE_DATA_DIRECTORY; + +// +// Directory Entries +// +#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0 +#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1 +#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2 +#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 +#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4 +#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5 +#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6 +#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 +#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 +#define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9 +#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 + +#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16 + +/// +/// @attention +/// EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC means PE32 and +/// EFI_IMAGE_OPTIONAL_HEADER32 must be used. The data structures only vary +/// after NT additional fields. +/// +#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b + +/// +/// @attention +/// EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC means PE32+ and +/// EFI_IMAGE_OPTIONAL_HEADER64 must be used. The data structures only vary +/// after NT additional fields. +/// +#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b + + +/// +/// @attention +/// EFI_IMAGE_NT_HEADERS32 is for use ONLY by tools. +/// +typedef struct { + UINT32 Signature; + EFI_IMAGE_FILE_HEADER FileHeader; +} EFI_IMAGE_NT_HEADERS_COMMON_HDR; + +STATIC_ASSERT ( + sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR) == sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER), + "Unsupported padding." + ); + +/// +/// @attention +/// EFI_IMAGE_NT_HEADERS32 is for use ONLY by tools. +/// +typedef struct { + EFI_IMAGE_NT_HEADERS_COMMON_HDR CommonHeader; + /// + /// Standard fields. + /// + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; ///< PE32 contains this additional field, which is absent in PE32+. + /// + /// Optional Header Windows-Specific Fields. + /// + UINT32 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Win32VersionValue; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT32 SizeOfStackReserve; + UINT32 SizeOfStackCommit; + UINT32 SizeOfHeapReserve; + UINT32 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + EFI_IMAGE_DATA_DIRECTORY DataDirectory[]; +} EFI_IMAGE_NT_HEADERS32; + +/// +/// @attention +/// EFI_IMAGE_HEADERS64 is for use ONLY by tools. +/// +typedef struct { + EFI_IMAGE_NT_HEADERS_COMMON_HDR CommonHeader; + /// + /// Standard fields. + /// + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + /// + /// Optional Header Windows-Specific Fields. + /// + UINT64 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Win32VersionValue; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT64 SizeOfStackReserve; + UINT64 SizeOfStackCommit; + UINT64 SizeOfHeapReserve; + UINT64 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + EFI_IMAGE_DATA_DIRECTORY DataDirectory[]; +} EFI_IMAGE_NT_HEADERS64; + +// +// Other Windows Subsystem Values +// +#define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0 +#define EFI_IMAGE_SUBSYSTEM_NATIVE 1 +#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2 +#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3 +#define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5 +#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7 + +/// +/// Length of ShortName. +/// +#define EFI_IMAGE_SIZEOF_SHORT_NAME 8 + +/// +/// Section Table. This table immediately follows the optional header. +/// +typedef struct { + UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME]; + UINT32 VirtualSize; + UINT32 VirtualAddress; + UINT32 SizeOfRawData; + UINT32 PointerToRawData; + UINT32 PointerToRelocations; + UINT32 PointerToLinenumbers; + UINT16 NumberOfRelocations; + UINT16 NumberOfLinenumbers; + UINT32 Characteristics; +} EFI_IMAGE_SECTION_HEADER; + +// +// Section Flags Values +// +#define EFI_IMAGE_SCN_TYPE_NO_PAD BIT3 ///< 0x00000008 ///< Reserved. +#define EFI_IMAGE_SCN_CNT_CODE BIT5 ///< 0x00000020 +#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA BIT6 ///< 0x00000040 +#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA BIT7 ///< 0x00000080 + +#define EFI_IMAGE_SCN_LNK_OTHER BIT8 ///< 0x00000100 ///< Reserved. +#define EFI_IMAGE_SCN_LNK_INFO BIT9 ///< 0x00000200 ///< Section contains comments or some other type of information. +#define EFI_IMAGE_SCN_LNK_REMOVE BIT11 ///< 0x00000800 ///< Section contents will not become part of image. +#define EFI_IMAGE_SCN_LNK_COMDAT BIT12 ///< 0x00001000 + +#define EFI_IMAGE_SCN_ALIGN_1BYTES BIT20 ///< 0x00100000 +#define EFI_IMAGE_SCN_ALIGN_2BYTES BIT21 ///< 0x00200000 +#define EFI_IMAGE_SCN_ALIGN_4BYTES (BIT20|BIT21) ///< 0x00300000 +#define EFI_IMAGE_SCN_ALIGN_8BYTES BIT22 ///< 0x00400000 +#define EFI_IMAGE_SCN_ALIGN_16BYTES (BIT20|BIT22) ///< 0x00500000 +#define EFI_IMAGE_SCN_ALIGN_32BYTES (BIT21|BIT22) ///< 0x00600000 +#define EFI_IMAGE_SCN_ALIGN_64BYTES (BIT20|BIT21|BIT22) ///< 0x00700000 + +#define EFI_IMAGE_SCN_MEM_DISCARDABLE BIT25 ///< 0x02000000 +#define EFI_IMAGE_SCN_MEM_NOT_CACHED BIT26 ///< 0x04000000 +#define EFI_IMAGE_SCN_MEM_NOT_PAGED BIT27 ///< 0x08000000 +#define EFI_IMAGE_SCN_MEM_SHARED BIT28 ///< 0x10000000 +#define EFI_IMAGE_SCN_MEM_EXECUTE BIT29 ///< 0x20000000 +#define EFI_IMAGE_SCN_MEM_READ BIT30 ///< 0x40000000 +#define EFI_IMAGE_SCN_MEM_WRITE BIT31 ///< 0x80000000 + +/// +/// Size of a Symbol Table Record. +/// +#define EFI_IMAGE_SIZEOF_SYMBOL 18 + +// +// Symbols have a section number of the section in which they are +// defined. Otherwise, section numbers have the following meanings: +// +#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 ///< Symbol is undefined or is common. +#define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 ///< Symbol is an absolute value. +#define EFI_IMAGE_SYM_DEBUG (UINT16) -2 ///< Symbol is a special debug item. + +// +// Symbol Type (fundamental) values. +// +#define EFI_IMAGE_SYM_TYPE_NULL 0 ///< no type. +#define EFI_IMAGE_SYM_TYPE_VOID 1 ///< no valid type. +#define EFI_IMAGE_SYM_TYPE_CHAR 2 ///< type character. +#define EFI_IMAGE_SYM_TYPE_SHORT 3 ///< type short integer. +#define EFI_IMAGE_SYM_TYPE_INT 4 +#define EFI_IMAGE_SYM_TYPE_LONG 5 +#define EFI_IMAGE_SYM_TYPE_FLOAT 6 +#define EFI_IMAGE_SYM_TYPE_DOUBLE 7 +#define EFI_IMAGE_SYM_TYPE_STRUCT 8 +#define EFI_IMAGE_SYM_TYPE_UNION 9 +#define EFI_IMAGE_SYM_TYPE_ENUM 10 ///< enumeration. +#define EFI_IMAGE_SYM_TYPE_MOE 11 ///< member of enumeration. +#define EFI_IMAGE_SYM_TYPE_BYTE 12 +#define EFI_IMAGE_SYM_TYPE_WORD 13 +#define EFI_IMAGE_SYM_TYPE_UINT 14 +#define EFI_IMAGE_SYM_TYPE_DWORD 15 + +// +// Symbol Type (derived) values. +// +#define EFI_IMAGE_SYM_DTYPE_NULL 0 ///< no derived type. +#define EFI_IMAGE_SYM_DTYPE_POINTER 1 +#define EFI_IMAGE_SYM_DTYPE_FUNCTION 2 +#define EFI_IMAGE_SYM_DTYPE_ARRAY 3 + +// +// Storage classes. +// +#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION ((UINT8) -1) +#define EFI_IMAGE_SYM_CLASS_NULL 0 +#define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1 +#define EFI_IMAGE_SYM_CLASS_EXTERNAL 2 +#define EFI_IMAGE_SYM_CLASS_STATIC 3 +#define EFI_IMAGE_SYM_CLASS_REGISTER 4 +#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5 +#define EFI_IMAGE_SYM_CLASS_LABEL 6 +#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7 +#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8 +#define EFI_IMAGE_SYM_CLASS_ARGUMENT 9 +#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10 +#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11 +#define EFI_IMAGE_SYM_CLASS_UNION_TAG 12 +#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13 +#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14 +#define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15 +#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16 +#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17 +#define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18 +#define EFI_IMAGE_SYM_CLASS_BLOCK 100 +#define EFI_IMAGE_SYM_CLASS_FUNCTION 101 +#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102 +#define EFI_IMAGE_SYM_CLASS_FILE 103 +#define EFI_IMAGE_SYM_CLASS_SECTION 104 +#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105 + +// +// type packing constants +// +#define EFI_IMAGE_N_BTMASK 017 +#define EFI_IMAGE_N_TMASK 060 +#define EFI_IMAGE_N_TMASK1 0300 +#define EFI_IMAGE_N_TMASK2 0360 +#define EFI_IMAGE_N_BTSHFT 4 +#define EFI_IMAGE_N_TSHIFT 2 + +// +// Communal selection types. +// +#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define EFI_IMAGE_COMDAT_SELECT_ANY 2 +#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 + +// +// the following values only be referred in PeCoff, not defined in PECOFF. +// +#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + +/// +/// Relocation format. +/// +typedef struct { + UINT32 VirtualAddress; + UINT32 SymbolTableIndex; + UINT16 Type; +} EFI_IMAGE_RELOCATION; + +/// +/// Size of EFI_IMAGE_RELOCATION +/// +#define EFI_IMAGE_SIZEOF_RELOCATION 10 + +// +// I386 relocation types. +// +#define EFI_IMAGE_REL_I386_ABSOLUTE 0x0000 ///< Reference is absolute, no relocation is necessary. +#define EFI_IMAGE_REL_I386_DIR16 0x0001 ///< Direct 16-bit reference to the symbols virtual address. +#define EFI_IMAGE_REL_I386_REL16 0x0002 ///< PC-relative 16-bit reference to the symbols virtual address. +#define EFI_IMAGE_REL_I386_DIR32 0x0006 ///< Direct 32-bit reference to the symbols virtual address. +#define EFI_IMAGE_REL_I386_DIR32NB 0x0007 ///< Direct 32-bit reference to the symbols virtual address, base not included. +#define EFI_IMAGE_REL_I386_SEG12 0x0009 ///< Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address. +#define EFI_IMAGE_REL_I386_SECTION 0x000A +#define EFI_IMAGE_REL_I386_SECREL 0x000B +#define EFI_IMAGE_REL_I386_REL32 0x0014 ///< PC-relative 32-bit reference to the symbols virtual address. + +// +// x64 processor relocation types. +// +#define IMAGE_REL_AMD64_ABSOLUTE 0x0000 +#define IMAGE_REL_AMD64_ADDR64 0x0001 +#define IMAGE_REL_AMD64_ADDR32 0x0002 +#define IMAGE_REL_AMD64_ADDR32NB 0x0003 +#define IMAGE_REL_AMD64_REL32 0x0004 +#define IMAGE_REL_AMD64_REL32_1 0x0005 +#define IMAGE_REL_AMD64_REL32_2 0x0006 +#define IMAGE_REL_AMD64_REL32_3 0x0007 +#define IMAGE_REL_AMD64_REL32_4 0x0008 +#define IMAGE_REL_AMD64_REL32_5 0x0009 +#define IMAGE_REL_AMD64_SECTION 0x000A +#define IMAGE_REL_AMD64_SECREL 0x000B +#define IMAGE_REL_AMD64_SECREL7 0x000C +#define IMAGE_REL_AMD64_TOKEN 0x000D +#define IMAGE_REL_AMD64_SREL32 0x000E +#define IMAGE_REL_AMD64_PAIR 0x000F +#define IMAGE_REL_AMD64_SSPAN32 0x0010 + +/** + Returns the type of a Base Relocation. + + @param[in] Relocation The composite Base Relocation value. +**/ +#define IMAGE_RELOC_TYPE(Relocation) ((Relocation) >> 12U) + +/** + Returns the target offset of a Base Relocation. + + @param[in] Relocation The composite Base Relocation value. +**/ +#define IMAGE_RELOC_OFFSET(Relocation) ((Relocation) & 0x0FFFU) + +/// +/// Based relocation format. +/// +typedef struct { + UINT32 VirtualAddress; + UINT32 SizeOfBlock; + UINT16 Relocations[]; +} EFI_IMAGE_BASE_RELOCATION_BLOCK; + +// +// Based relocation types. +// +#define EFI_IMAGE_REL_BASED_ABSOLUTE 0 +#define EFI_IMAGE_REL_BASED_HIGH 1 +#define EFI_IMAGE_REL_BASED_LOW 2 +#define EFI_IMAGE_REL_BASED_HIGHLOW 3 +#define EFI_IMAGE_REL_BASED_HIGHADJ 4 +#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5 +#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7 +#define EFI_IMAGE_REL_BASED_IA64_IMM64 9 +#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR16 9 +#define EFI_IMAGE_REL_BASED_DIR64 10 + +/// +/// Relocation types of RISC-V processor. +/// +#define EFI_IMAGE_REL_BASED_RISCV_HI20 5 +#define EFI_IMAGE_REL_BASED_RISCV_LOW12I 7 +#define EFI_IMAGE_REL_BASED_RISCV_LOW12S 8 + +/// +/// Line number format. +/// +typedef struct { + union { + UINT32 SymbolTableIndex; ///< Symbol table index of function name if Linenumber is 0. + UINT32 VirtualAddress; ///< Virtual address of line number. + } Type; + UINT16 Linenumber; ///< Line number. +} EFI_IMAGE_LINENUMBER; + +/// +/// Size of EFI_IMAGE_LINENUMBER. +/// +#define EFI_IMAGE_SIZEOF_LINENUMBER 6 + +// +// Archive format. +// +#define EFI_IMAGE_ARCHIVE_START_SIZE 8 +#define EFI_IMAGE_ARCHIVE_START "!\n" +#define EFI_IMAGE_ARCHIVE_END "`\n" +#define EFI_IMAGE_ARCHIVE_PAD "\n" +#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +/// +/// Archive Member Headers +/// +typedef struct { + UINT8 Name[16]; ///< File member name - `/' terminated. + UINT8 Date[12]; ///< File member date - decimal. + UINT8 UserID[6]; ///< File member user id - decimal. + UINT8 GroupID[6]; ///< File member group id - decimal. + UINT8 Mode[8]; ///< File member mode - octal. + UINT8 Size[10]; ///< File member size - decimal. + UINT8 EndHeader[2]; ///< String to end header. (0x60 0x0A). +} EFI_IMAGE_ARCHIVE_MEMBER_HEADER; + +/// +/// Size of EFI_IMAGE_ARCHIVE_MEMBER_HEADER. +/// +#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + + +// +// DLL Support +// + +/// +/// Export Directory Table. +/// +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Name; + UINT32 Base; + UINT32 NumberOfFunctions; + UINT32 NumberOfNames; + UINT32 AddressOfFunctions; + UINT32 AddressOfNames; + UINT32 AddressOfNameOrdinals; +} EFI_IMAGE_EXPORT_DIRECTORY; + +/// +/// Hint/Name Table. +/// +typedef struct { + UINT16 Hint; + UINT8 Name[1]; +} EFI_IMAGE_IMPORT_BY_NAME; + +/// +/// Import Address Table RVA (Thunk Table). +/// +typedef struct { + union { + UINT32 Function; + UINT32 Ordinal; + EFI_IMAGE_IMPORT_BY_NAME *AddressOfData; + } u1; +} EFI_IMAGE_THUNK_DATA; + +#define EFI_IMAGE_ORDINAL_FLAG BIT31 ///< Flag for PE32. +#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0) +#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +/// +/// Import Directory Table +/// +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT32 ForwarderChain; + UINT32 Name; + EFI_IMAGE_THUNK_DATA *FirstThunk; +} EFI_IMAGE_IMPORT_DESCRIPTOR; + + +/// +/// Debug Directory Format. +/// +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Type; + UINT32 SizeOfData; + UINT32 RVA; ///< The address of the debug data when loaded, relative to the image base. + UINT32 FileOffset; ///< The file pointer to the debug data. +} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY; + +#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2 ///< The Visual C++ debug information. + +/// +/// Debug Data Structure defined in Microsoft C++. +/// +#define CODEVIEW_SIGNATURE_NB10 SIGNATURE_32('N', 'B', '1', '0') +typedef struct { + UINT32 Signature; ///< "NB10" + UINT32 Unknown; + UINT32 Unknown2; + UINT32 Unknown3; + // + // Filename of .PDB goes here + // +} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY; + +/// +/// Debug Data Structure defined in Microsoft C++. +/// FIXME: +/// Documentation available at: https://github.com/dotnet/runtime/blob/main/docs/design/specs/PE-COFF.md +/// +#define CODEVIEW_SIGNATURE_RSDS SIGNATURE_32('R', 'S', 'D', 'S') +typedef struct { + // + // 0x52 0x53 0x44 0x53 (ASCII string: "RSDS") + // + UINT32 Signature; ///< "RSDS". + // + // GUID (Globally Unique Identifier) of the associated PDB. + // + UINT8 Guid[16]; + // + // Iteration of the PDB. The first iteration is 1. The iteration is + // incremented each time the PDB content is augmented. + // + UINT32 Age; + // + // UTF-8 NUL-terminated path to the associated .pdb file + // +} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY; + + +/// +/// Debug Data Structure defined by Apple Mach-O to Coff utility. +/// +#define CODEVIEW_SIGNATURE_MTOC SIGNATURE_32('M', 'T', 'O', 'C') +typedef struct { + UINT32 Signature; ///< "MTOC". + UINT8 Uuid[16]; + // + // Filename of .DLL (Mach-O with debug info) goes here + // +} EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY; + +/// +/// Resource directory entry format. +/// +typedef struct { + union { + struct { + UINT32 NameOffset:31; + UINT32 NameIsString:1; + } s; + UINT32 Id; + } u1; + union { + UINT32 OffsetToData; + struct { + UINT32 OffsetToDirectory:31; + UINT32 DataIsDirectory:1; + } s; + } u2; +} EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY; + +/// +/// Resource format. +/// +typedef struct { + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT16 NumberOfNamedEntries; + UINT16 NumberOfIdEntries; + EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY Entries[]; +} EFI_IMAGE_RESOURCE_DIRECTORY; + +/// +/// Resource directory entry for string. +/// +typedef struct { + UINT16 Length; + CHAR16 String[]; +} EFI_IMAGE_RESOURCE_DIRECTORY_STRING; + +/// +/// Resource directory entry for data array. +/// +typedef struct { + UINT32 OffsetToData; + UINT32 Size; + UINT32 CodePage; + UINT32 Reserved; +} EFI_IMAGE_RESOURCE_DATA_ENTRY; + +/// +/// Header format for TE images, defined in the PI Specification, 1.0. +/// +typedef struct { + UINT16 Signature; ///< The signature for TE format = "VZ". + UINT16 Machine; ///< From the original file header. + UINT8 NumberOfSections; ///< From the original file header. + UINT8 Subsystem; ///< From original optional header. + UINT16 StrippedSize; ///< Number of bytes we removed from the header. + UINT32 AddressOfEntryPoint; ///< Offset to entry point -- from original optional header. + UINT32 BaseOfCode; ///< From original image -- required for ITP debug. + UINT64 ImageBase; ///< From original file header. + EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; ///< Only base relocation and debug directory. +} EFI_TE_IMAGE_HEADER; + + +#define EFI_TE_IMAGE_HEADER_SIGNATURE SIGNATURE_16('V', 'Z') + +// +// Data directory indexes in our TE image header +// +#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0 +#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1 + + +/// +/// Union of PE32, PE32+, and TE headers. +/// +typedef union { + EFI_IMAGE_NT_HEADERS_COMMON_HDR PeCommon; + EFI_IMAGE_NT_HEADERS32 Pe32; + EFI_IMAGE_NT_HEADERS64 Pe32Plus; + EFI_TE_IMAGE_HEADER Te; +} EFI_IMAGE_OPTIONAL_HEADER_UNION; + +#endif // PE_COFF_IMAGE2_H_ diff --git a/MdePkg/Include/Library/PeCoffExtraActionLib.h b/MdePkg/Include/Library/PeCoffExtraActionLib.h index efe5133922..8950f1a604 100644 --- a/MdePkg/Include/Library/PeCoffExtraActionLib.h +++ b/MdePkg/Include/Library/PeCoffExtraActionLib.h @@ -1,3 +1,5 @@ +#ifndef DISABLE_NEW_DEPRECATED_INTERFACES + /** @file Provides services to perform additional actions when a PE/COFF image is loaded or unloaded. This is useful for environment where symbols need to be loaded @@ -45,3 +47,5 @@ PeCoffLoaderUnloadImageExtraAction ( ); #endif + +#endif // DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/MdePkg/Include/Library/PeCoffLib.h b/MdePkg/Include/Library/PeCoffLib.h index 74cceb37bf..f644fdeddc 100644 --- a/MdePkg/Include/Library/PeCoffLib.h +++ b/MdePkg/Include/Library/PeCoffLib.h @@ -1,3 +1,5 @@ +#ifndef DISABLE_NEW_DEPRECATED_INTERFACES + /** @file Provides services to load and relocate a PE/COFF image. @@ -76,127 +78,127 @@ typedef struct { /// /// Set by PeCoffLoaderGetImageInfo() to the ImageBase in the PE/COFF header. /// - PHYSICAL_ADDRESS ImageAddress; + PHYSICAL_ADDRESS ImageAddress; /// /// Set by PeCoffLoaderGetImageInfo() to the SizeOfImage in the PE/COFF header. /// Image size includes the size of Debug Entry if it is present. /// - UINT64 ImageSize; + UINT64 ImageSize; /// /// Is set to zero by PeCoffLoaderGetImageInfo(). If DestinationAddress is non-zero, /// PeCoffLoaderRelocateImage() will relocate the image using this base address. /// If the DestinationAddress is zero, the ImageAddress will be used as the base /// address of relocation. /// - PHYSICAL_ADDRESS DestinationAddress; + PHYSICAL_ADDRESS DestinationAddress; /// /// PeCoffLoaderLoadImage() sets EntryPoint to to the entry point of the PE/COFF image. /// - PHYSICAL_ADDRESS EntryPoint; + PHYSICAL_ADDRESS EntryPoint; /// /// Passed in by the caller to PeCoffLoaderGetImageInfo() and PeCoffLoaderLoadImage() /// to abstract accessing the image from the library. /// - PE_COFF_LOADER_READ_FILE ImageRead; + PE_COFF_LOADER_READ_FILE ImageRead; /// /// Used as the FileHandle passed into the ImageRead function when it's called. /// - VOID *Handle; + VOID *Handle; /// /// Caller allocated buffer of size FixupDataSize that can be optionally allocated /// prior to calling PeCoffLoaderRelocateImage(). /// This buffer is filled with the information used to fix up the image. /// The fixups have been applied to the image and this entry is just for information. /// - VOID *FixupData; + VOID *FixupData; /// /// Set by PeCoffLoaderGetImageInfo() to the Section Alignment in the PE/COFF header. /// If the image is a TE image, then this field is set to 0. /// - UINT32 SectionAlignment; + UINT32 SectionAlignment; /// /// Set by PeCoffLoaderGetImageInfo() to offset to the PE/COFF header. /// If the PE/COFF image does not start with a DOS header, this value is zero. /// Otherwise, it's the offset to the PE/COFF header. /// - UINT32 PeCoffHeaderOffset; + UINT32 PeCoffHeaderOffset; /// /// Set by PeCoffLoaderGetImageInfo() to the Relative Virtual Address of the debug directory, /// if it exists in the image /// - UINT32 DebugDirectoryEntryRva; + UINT32 DebugDirectoryEntryRva; /// /// Set by PeCoffLoaderLoadImage() to CodeView area of the PE/COFF Debug directory. /// - VOID *CodeView; + VOID *CodeView; /// /// Set by PeCoffLoaderLoadImage() to point to the PDB entry contained in the CodeView area. /// The PdbPointer points to the filename of the PDB file used for source-level debug of /// the image by a debugger. /// - CHAR8 *PdbPointer; + CHAR8 *PdbPointer; /// /// Is set by PeCoffLoaderGetImageInfo() to the Section Alignment in the PE/COFF header. /// - UINTN SizeOfHeaders; + UINTN SizeOfHeaders; /// /// Not used by this library class. Other library classes that layer on top of this library /// class fill in this value as part of their GetImageInfo call. /// This allows the caller of the library to know what type of memory needs to be allocated /// to load and relocate the image. /// - UINT32 ImageCodeMemoryType; + UINT32 ImageCodeMemoryType; /// /// Not used by this library class. Other library classes that layer on top of this library /// class fill in this value as part of their GetImageInfo call. /// This allows the caller of the library to know what type of memory needs to be allocated /// to load and relocate the image. /// - UINT32 ImageDataMemoryType; + UINT32 ImageDataMemoryType; /// /// Set by any of the library functions if they encounter an error. /// - UINT32 ImageError; + UINT32 ImageError; /// /// Set by PeCoffLoaderLoadImage() to indicate the size of FixupData that the caller must /// allocate before calling PeCoffLoaderRelocateImage(). /// - UINTN FixupDataSize; + UINTN FixupDataSize; /// /// Set by PeCoffLoaderGetImageInfo() to the machine type stored in the PE/COFF header. /// - UINT16 Machine; + UINT16 Machine; /// /// Set by PeCoffLoaderGetImageInfo() to the subsystem type stored in the PE/COFF header. /// - UINT16 ImageType; + UINT16 ImageType; /// /// Set by PeCoffLoaderGetImageInfo() to the DLL flags stored in the PE/COFF header and /// in the DllCharacteristicsEx debug table. /// - UINT16 DllCharacteristics; - UINT32 DllCharacteristicsEx; + UINT16 DllCharacteristics; + UINT32 DllCharacteristicsEx; /// /// Set by PeCoffLoaderGetImageInfo() to TRUE if the PE/COFF image does not contain /// relocation information. /// - BOOLEAN RelocationsStripped; + BOOLEAN RelocationsStripped; /// /// Set by PeCoffLoaderGetImageInfo() to TRUE if the image is a TE image. /// For a definition of the TE Image format, see the Platform Initialization Pre-EFI /// Initialization Core Interface Specification. /// - BOOLEAN IsTeImage; + BOOLEAN IsTeImage; /// /// Set by PeCoffLoaderLoadImage() to the HII resource offset /// if the image contains a custom PE/COFF resource with the type 'HII'. /// Otherwise, the entry remains to be 0. /// - PHYSICAL_ADDRESS HiiResourceData; + PHYSICAL_ADDRESS HiiResourceData; /// /// Private storage for implementation specific data. /// - UINT64 Context; + UINT64 Context; } PE_COFF_LOADER_IMAGE_CONTEXT; /** @@ -302,6 +304,7 @@ PeCoffLoaderLoadImage ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext ); + /** Reads contents of a PE/COFF image from a buffer in system memory. @@ -328,12 +331,13 @@ PeCoffLoaderLoadImage ( RETURN_STATUS EFIAPI PeCoffLoaderImageReadFromMemory ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer ); + /** Reapply fixups on a fixed up PE32/PE32+ image to allow virtual calling at EFI runtime. @@ -359,11 +363,11 @@ PeCoffLoaderImageReadFromMemory ( **/ VOID EFIAPI -PeCoffLoaderRelocateImageForRuntime ( - IN PHYSICAL_ADDRESS ImageBase, - IN PHYSICAL_ADDRESS VirtImageBase, - IN UINTN ImageSize, - IN VOID *RelocationData +PeCoffLoaderRuntimeRelocateImage ( + IN PHYSICAL_ADDRESS ImageBase, + IN PHYSICAL_ADDRESS VirtImageBase, + IN UINTN ImageSize, + IN VOID *RelocationData ); /** @@ -387,5 +391,6 @@ EFIAPI PeCoffLoaderUnloadImage ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext ); - #endif + +#endif // DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/MdePkg/Include/Library/PeCoffLib2.h b/MdePkg/Include/Library/PeCoffLib2.h new file mode 100644 index 0000000000..0985a0bc1e --- /dev/null +++ b/MdePkg/Include/Library/PeCoffLib2.h @@ -0,0 +1,597 @@ +/** @file + Provides APIs to inspect, load, and relocate PE/COFF Images. + + No implementation of this library may use global variable pointers, as this + may cause the emission of Image relocations for this address. This is + incompatible with the concept of Image self-relocation, where the Image is + loaded in a similar fashion to XIP Images into the memory at an address + unknown at compile-time. As such, Image relocation must be safe to perform + without any Image relocations applied earlier. + + Copyright (c) 2020 - 2021, Marvin Häuser. All rights reserved.
+ Copyright (c) 2020, Vitaly Cheptsov. All rights reserved.
+ Copyright (c) 2020, ISP RAS. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef PE_COFF_LIB2_H_ +#define PE_COFF_LIB2_H_ + +#include + +#include + +// FIXME: Where to put this? +// +// PcdImageLoaderAlignmentPolicy bits. +// + +/// +/// If set, unaligned Image sections are permitted. +/// +#define PCD_ALIGNMENT_POLICY_CONTIGUOUS_SECTIONS BIT0 +/// +/// If set, unaligned Image Relocation Block sizes are permitted. +/// +#define PCD_ALIGNMENT_POLICY_RELOCATION_BLOCK_SIZES BIT1 +/// +/// If set, unaligned Image certificate sizes are permitted. +/// +#define PCD_ALIGNMENT_POLICY_CERTIFICATE_SIZES BIT2 + +// FIXME: Rework docs to consider Inplace dependencies + +/** + Returns whether the Image targets the UEFI Subsystem. + + @param[in] Subsystem The Subsystem value from the Image Headers. +**/ +#define IMAGE_IS_EFI_SUBYSYSTEM(Subsystem) \ + ((Subsystem) >= EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION && \ + (Subsystem) <= EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) + +/// +/// Image type enumeration for Image format identification from the context. +/// +typedef enum { + PeCoffLoaderTypeTe, + PeCoffLoaderTypePe32, + PeCoffLoaderTypePe32Plus, + PeCoffLoaderTypeMax +} PE_COFF_LOADER_IMAGE_TYPE; + +/// +/// Image context structure used for abstraction and bookkeeping. +/// This structure is publicly exposed for memory allocation reasons and must +/// not be accessed directly outside of the library implementation. +/// +typedef struct { + /// + /// The preferred load address of the Image. + /// + UINT64 ImageBase; + /// + /// A pointer to the Image raw file buffer. + /// + CONST VOID *FileBuffer; + /// + /// The size, in Bytes, of FileBuffer. + /// + UINT32 FileSize; + /// + /// A pointer to the loaded Image destination. + /// + VOID *ImageBuffer; + /// + /// The offset of the Section Headers from the beginning of the raw file. + /// + UINT32 SectionsOffset; + /// + /// The number of Sections in the Image. + /// + UINT16 NumberOfSections; + /// + /// The size, in Bytes, required to load the Image. + /// + UINT32 SizeOfImage; + /// + /// The alignment, in Bytes, of Image Sections virtual addresses. + /// + UINT32 SectionAlignment; + /// + /// The offset of the Image Header from the beginning of the raw file. + /// + UINT32 ExeHdrOffset; + /// + /// The combined size, in Bytes, of all Image Headers. + /// + UINT32 SizeOfHeaders; + /// + /// The RVA of the Image entry point. + /// + UINT32 AddressOfEntryPoint; + /// + /// Indicates whether relocation information has been stripped from the Image. + /// + BOOLEAN RelocsStripped; + /// + /// The file format of the Image raw file, refer to PE_COFF_LOADER_IMAGE_TYPE. + /// + UINT8 ImageType; + /// + /// The Subsystem value from the Image Header. + /// + UINT16 Subsystem; + /// + /// The Machine value from the Image Header. + /// + UINT16 Machine; + /// + /// The size, in Bytes, stripped from the beginning of the Image raw file + /// during TE file generation. Always 0 for PE Images. + /// + UINT16 TeStrippedOffset; + /// + /// The RVA of the Relocation Directory. + /// + UINT32 RelocDirRva; + /// + /// The size, in Bytes, of the Relocation Directory. + /// + UINT32 RelocDirSize; + /// + /// The RVA of the Security Directory. + /// + UINT32 SecDirOffset; + /// + /// The size, in Bytes, of the Security Directory. + /// + UINT32 SecDirSize; +} PE_COFF_LOADER_IMAGE_CONTEXT; + +/// +/// Image runtime context used to relocate the Image during runtime. +/// +typedef struct PE_COFF_LOADER_RUNTIME_CONTEXT_ PE_COFF_LOADER_RUNTIME_CONTEXT; + +/** + Adds the digest of Data to HashContext. This function can be called multiple + times to compute the digest of discontinuous data. + + @param[in,out] HashContext The context of the current hash. + @param[in] Data The data to be hashed. + @param[in] DataSize The size, in Bytes, of Data. + + @returns Whether hashing has been successful. +**/ +typedef +BOOLEAN +(EFIAPI *PE_COFF_LOADER_HASH_UPDATE)( + IN OUT VOID *HashContext, + IN CONST VOID *Data, + IN UINTN DataSize + ); + +/** + Verify the TE, PE32, or PE32+ Image and initialise Context. + + Used offsets and ranges must be aligned and in the bounds of the raw file. + Image Section Headers and basic Relocation information must be well-formed. + + FileBuffer must remain valid for the entire lifetime of Context. + + @param[out] Context The context describing the Image. + @param[in] FileBuffer The file data to parse as TE or PE Image. + @param[in] FileSize The size, in Bytes, of FileBuffer. + + @retval RETURN_SUCCESS The Image context has been initialised successfully. + @retval other The file data is malformed. +**/ +RETURN_STATUS +PeCoffInitializeContext ( + OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN CONST VOID *FileBuffer, + IN UINT32 FileSize + ); + +/** + Hashes the Image using the Authenticode (PE/COFF Specification 8.1 Appendix A) + algorithm. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + @param[in,out] HashContext The context of the current hash. Must have been + initialised for usage with the HashUpdate + function. + @param[in] HashUpdate The data hashing function. + + @returns Whether hashing has been successful. +**/ +BOOLEAN +PeCoffHashImageAuthenticode ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN OUT VOID *HashContext, + IN PE_COFF_LOADER_HASH_UPDATE HashUpdate + ); + +/** + Load the Image into the destination memory space. + + @param[in,out] Context The context describing the Image. Must have + been initialised by PeCoffInitializeContext(). + @param[out] Destination The Image destination memory. Must be + allocated from page memory. + @param[in] DestinationSize The size, in Bytes, of Destination. Must be + sufficent to load the Image with regards to + its Image section alignment. + + @retval RETURN_SUCCESS The Image was loaded successfully. + @retval other The Image could not be loaded successfully. +**/ +RETURN_STATUS +PeCoffLoadImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT VOID *Destination, + IN UINT32 DestinationSize + ); + +// FIXME: Docs +BOOLEAN +PeCoffImageIsInplace ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Equivalent to the PeCoffLoadImage() function for inplace-loading. Ensures that + all important raw file offsets match the respective RVAs. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + + @retval RETURN_SUCCESS The Image has been inplace-loaded successfully. + @retval other The Image is not suitable for inplace-loading. +**/ +RETURN_STATUS +PeCoffLoadImageInplace ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +// FIXME: Docs +RETURN_STATUS +PeCoffRelocateImageInplace ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the size required to bookkeep Image runtime relocation information. + + May only be called when PeCoffGetRelocsStripped() returns FALSE. + + @param[in,out] Context The context describing the Image. Must have been + loaded by PeCoffLoadImage(). + @param[out] Size On output, the size, in Bytes, required for the + bookkeeping buffer. + + @retval RETURN_SUCCESS The Image runtime context size for the Image was + retrieved successfully. + @retval other The Image runtime context size for the Image could not + be retrieved successfully. +**/ +RETURN_STATUS +PeCoffLoaderGetRuntimeContextSize ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *Size + ); + +/** + Relocate the Image for boot-time usage. + + May only be called when PeCoffGetRelocsStripped() returns FALSE, or with + BaseAddress == PeCoffGetImageBase(). + + @param[in,out] Context The context describing the Image. Must have + been loaded by PeCoffLoadImage(). + @param[in] BaseAddress The address to relocate the Image to. + @param[out] RuntimeContext If not NULL, on output, a bookkeeping data + required for Image runtime relocation. + @param[in] RuntimeContextSize The size, in Bytes, of RuntimeContext. Must + be at least as big as the size returned by + PeCoffLoaderGetRuntimeContextSize(). + + @retval RETURN_SUCCESS The Image has been relocated successfully. + @retval other The Image Relocation Directory is malformed. +**/ +RETURN_STATUS +PeCoffRelocateImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN UINT64 BaseAddress, + OUT PE_COFF_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize + ); + +/** + Relocate Image for Runtime usage. + + May only be called when PeCoffGetRelocsStripped() returns FALSE, or with + BaseAddress == PeCoffGetImageBase(). + + @param[in,out] Image The Image destination memory. Must have been + relocated by PeCoffRelocateImage(). + @param[in] ImageSize The size, in Bytes, of Image. + @param[in] BaseAddress The address to relocate the Image to. + @param[in] RuntimeContext The Relocation context obtained by + PeCoffRelocateImage(). + + @retval RETURN_SUCCESS The Image has been relocated successfully. + @retval other The Image could not be relocated successfully. +**/ +RETURN_STATUS +PeCoffRuntimeRelocateImage ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN UINT64 BaseAddress, + IN CONST PE_COFF_LOADER_RUNTIME_CONTEXT *RuntimeContext + ); + +/** + Discards optional Image Sections to disguise sensitive data. + + This may destruct the Image Relocation Directory and as such, no function that + performs Image relocation may be called after this function has been invoked. + + @param[in,out] Context The context describing the Image. Must have been + loaded by PeCoffLoadImage(). +**/ +VOID +PeCoffDiscardSections ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the Image PDB path. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + @param[out] PdbPath On output, a pointer to the Image PDB path. + @param[out] PdbPathSize On output, the size, in Bytes, of *PdbPath. + + @retval RETURN_SUCCESS The Image PDB path was retrieved successfully. + @retval other The Image PDB path could not be retrieved + successfully. +**/ +RETURN_STATUS +PeCoffGetPdbPath ( + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT CONST CHAR8 **PdbPath, + OUT UINT32 *PdbPathSize + ); + +/** + Retrieves the first certificate from the Image Certificate Directory. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + @param[out] Certificate On output, the first certificate of the Image. + + @retval RETURN_SUCCESS The certificate has been retrieved successfully. + @retval RETURN_NOT_FOUND There is no such certificate. + @retval other The Image Certificate Directory is malformed. +**/ +RETURN_STATUS +PeCoffGetFirstCertificate ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT CONST WIN_CERTIFICATE **Certificate + ); + +/** + Retrieves the next certificate from the Image Certificate Directory. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + @param[out] Certificate On input, the current certificate of the Image. + Must have been retrieved by + PeCoffGetFirstCertificate(). + On output, the next certificate of the Image. + + @retval RETURN_SUCCESS The certificate has been retrieved successfully. + @retval RETURN_NOT_FOUND There is no such certificate. + @retval other The Image Certificate Directory is malformed. +**/ +RETURN_STATUS +PeCoffGetNextCertificate ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN OUT CONST WIN_CERTIFICATE **Certificate + ); + +/** + Retrieves the Image Section Table. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + @param[out] Sections On output, points to the Image Section Table. + + @returns The number of sections in the Image Section Table. +**/ +UINT16 +PeCoffGetSectionTable ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT CONST EFI_IMAGE_SECTION_HEADER **Sections + ); + +/** + Retrieves the Image HII data RVA. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + @param[out] HiiRva On output, the RVA of the HII resource data. + @param[out] HiiSize On output, the size, in Bytes, of HiiRva. + + @retval RETURN_SUCCESS The Image HII data has been retrieved successfully. + @retval RETURN_NOT_FOUND The Image HII data could not be found. + @retval other The Image Resource Directory is malformed. +**/ +RETURN_STATUS +PeCoffGetHiiDataRva ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *HiiRva, + OUT UINT32 *HiiSize + ); + +/** + Retrieve the Image entry point RVA. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + + @returns The Image entry point RVA. +**/ +UINT32 +PeCoffGetAddressOfEntryPoint ( + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the Image machine type. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + + @returns The Image machine type. +**/ +UINT16 +PeCoffGetMachine ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the Image subsystem type. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + + @returns The Image subsystem type. +**/ +UINT16 +PeCoffGetSubsystem ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the Image section alignment. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + + @returns The Image section alignment. +**/ +UINT32 +PeCoffGetSectionAlignment ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the size, in Bytes, of the Image memory space. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + + @returns The size of the Image memory space. +**/ +UINT32 +PeCoffGetSizeOfImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the size, in Bytes, of the Image memory space for in-place loading. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + + @returns The size of the Image memory space for in-place loading. +**/ +UINT32 +PeCoffGetSizeOfImageInplace ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the Image preferred load address. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + + @returns The Image preferred load address. +**/ +UINT64 +PeCoffGetImageBase ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the size, in Bytes, of the Image Headers. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + + @returns The size of the Image Headers. +**/ +UINT32 +PeCoffGetSizeOfHeaders ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Returns whether the Image relocations have been stripped. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + + @returns Whether the Image relocations have been stripped. +**/ +BOOLEAN +PeCoffGetRelocsStripped ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the Image load address PeCoffLoadImage() has loaded the Image to. + + May be called only after PeCoffLoadImage() has succeeded. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + + @returns The Image load address. +**/ +UINTN +PeCoffLoaderGetImageAddress ( + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieve the immediate data encoded in an ARM MOVW/MOVT instruciton pair. + + @param[in] Instructions Pointer to an ARM MOVW/MOVT insturction pair. + + @returns The Immediate address encoded in the instructions. +**/ +UINT32 +PeCoffThumbMovwMovtImmediateAddress ( + IN CONST VOID *Instructions + ); + +/** + Relocate an ARM MOVW/MOVT immediate instruction instruction pair. + + @param[in,out] Instructions Pointer to ARM MOVW/MOVT instruction pair. + @param[in] Adjust The delta to add to the addresses. +**/ +VOID +PeCoffThumbMovwMovtImmediateFixup ( + IN OUT VOID *Instructions, + IN UINT64 Adjust + ); + +#endif // PE_COFF_LIB2_H_ diff --git a/MdePkg/Include/Library/PeiServicesLib.h b/MdePkg/Include/Library/PeiServicesLib.h index 0ca032e411..3ed1fd72f7 100644 --- a/MdePkg/Include/Library/PeiServicesLib.h +++ b/MdePkg/Include/Library/PeiServicesLib.h @@ -238,6 +238,32 @@ PeiServicesFfsFindSectionData3 ( OUT UINT32 *AuthenticationStatus ); +/** + This service enables PEIMs to discover sections of a given instance and type within a valid FFS file. + + @param SectionType The value of the section type to find. + @param SectionInstance Section instance to find. + @param FileHandle A pointer to the file header that contains the set + of sections to be searched. + @param SectionData A pointer to the discovered section, if successful. + @param SectionDataSize The size of the discovered section, if successful. + @param AuthenticationStatus A pointer to the authentication status for this section. + + @retval EFI_SUCCESS The section was found. + @retval EFI_NOT_FOUND The section was not found. + +**/ +EFI_STATUS +EFIAPI +PeiServicesFfsFindSectionData4 ( + IN EFI_SECTION_TYPE SectionType, + IN UINTN SectionInstance, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData, + OUT UINT32 *SectionDataSize, + OUT UINT32 *AuthenticationStatus + ); + /** This service enables PEIMs to register the permanent memory configuration that has been initialized with the PEI Foundation. diff --git a/MdePkg/Include/Library/UefiImageExtraActionLib.h b/MdePkg/Include/Library/UefiImageExtraActionLib.h new file mode 100644 index 0000000000..4aa7193527 --- /dev/null +++ b/MdePkg/Include/Library/UefiImageExtraActionLib.h @@ -0,0 +1,47 @@ +/** @file + Provides services to perform additional actions when an UEFI image is loaded + or unloaded. This is useful for environment where symbols need to be loaded + and unloaded to support source level debugging. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __UEFI_IMAGE_EXTRA_ACTION_LIB_H__ +#define __UEFI_IMAGE_EXTRA_ACTION_LIB_H__ + +#include + +/** + Performs additional actions after a UEFI image has been loaded and relocated. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + UEFI image that has already been loaded and relocated. + +**/ +VOID +EFIAPI +UefiImageLoaderRelocateImageExtraAction ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ); + +/** + Performs additional actions just before a UEFI image is unloaded. Any resources + that were allocated by UefiImageLoaderRelocateImageExtraAction() must be freed. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + UEFI image that is being unloaded. + +**/ +VOID +EFIAPI +UefiImageLoaderUnloadImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ); + +#endif diff --git a/MdePkg/Include/Library/UefiImageLib.h b/MdePkg/Include/Library/UefiImageLib.h new file mode 100644 index 0000000000..b0de4b317c --- /dev/null +++ b/MdePkg/Include/Library/UefiImageLib.h @@ -0,0 +1,642 @@ +// FIXME: Docs +#ifndef UEFI_IMAGE_LIB_H_ +#define UEFI_IMAGE_LIB_H_ + +// FIXME: Work on reasonable abstraction +#ifndef UEFI_IMAGE_LOADER_IMAGE_CONTEXT + #include + + #define UEFI_IMAGE_LOADER_IMAGE_CONTEXT PE_COFF_LOADER_IMAGE_CONTEXT + #define UEFI_IMAGE_LOADER_RUNTIME_CONTEXT PE_COFF_LOADER_RUNTIME_CONTEXT +#endif + +/// +/// Image record segment that desribes the UEFI memory permission configuration +/// for one segment of the Image. +/// +typedef struct { + /// + /// The size, in Bytes, of the Image record segment. + /// + UINT32 Size; + /// + /// The UEFI memory permission attributes corresponding to this Image record + /// segment. + /// + UINT32 Attributes; +} UEFI_IMAGE_RECORD_SEGMENT; + +/// +/// The 32-bit signature that identifies a UEFI_IMAGE_RECORD structure. +/// +#define UEFI_IMAGE_RECORD_SIGNATURE SIGNATURE_32 ('U','I','I','R') + +/// +/// Image record that describes the UEFI memory permission configuration for +/// every segment of the Image. +/// +typedef struct { + /// + /// The signature of the Image record structure. Must be set to + /// UEFI_IMAGE_RECORD_SIGNATURE. + /// + UINT32 Signature; + /// + /// The number of Image records. Must be at least 1. + /// + UINT32 NumSegments; + /// + /// A link to allow insertion of the Image record into a doubly-linked list. + /// + LIST_ENTRY Link; + /// + /// The start address of the Image memory space. + /// + UINTN StartAddress; + /// + /// The end address of the Image memory space. Must be equal to StartAddress + /// plus the sum of Segments[i].Size for 0 <= i < NumSegments. + /// + UINTN EndAddress; + /// + /// The Image record segments with their corresponding memory permission + /// attributes. All Image record segments are contiguous and cover the entire + /// Image memory space. The address of an Image record segment can be + /// determined by adding the sum of all previous sizes to StartAddress. + /// + UEFI_IMAGE_RECORD_SEGMENT Segments[]; +} UEFI_IMAGE_RECORD; + +/** + Adds the digest of Data to HashContext. This function can be called multiple + times to compute the digest of discontinuous data. + + @param[in,out] HashContext The context of the current hash. + @param[in] Data The data to be hashed. + @param[in] DataSize The size, in Bytes, of Data. + + @returns Whether hashing has been successful. +**/ +typedef +BOOLEAN +(EFIAPI *UEFI_IMAGE_LOADER_HASH_UPDATE)( + IN OUT VOID *HashContext, + IN CONST VOID *Data, + IN UINTN DataSize + ); + +// FIXME: Docs +RETURN_STATUS +UefiImageInitializeContextPreHash ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN CONST VOID *FileBuffer, + IN UINT32 FileSize + ); + +RETURN_STATUS +UefiImageInitializeContextPostHash ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Verify the UEFI Image and initialise Context. + + Used offsets and ranges must be aligned and in the bounds of the raw file. + Image headers and basic Relocation information must be well-formed. + + FileBuffer must remain valid for the entire lifetime of Context. + + @param[out] Context The context describing the Image. + @param[in] FileBuffer The file data to parse as UEFI Image. + @param[in] FileSize The size, in Bytes, of FileBuffer. + + @retval RETURN_SUCCESS The Image context has been initialised successfully. + @retval other The file data is malformed. +**/ +RETURN_STATUS +UefiImageInitializeContext ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN CONST VOID *FileBuffer, + IN UINT32 FileSize + ); + +/** + Retrieves the UefiImageLib Image format identifier. + + @param[out] Context The context describing the Image. + + @returns The UefiImageLib format identifier. +**/ +UINT8 +UefiImageGetFormat ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Hashes the Image using the format's default hashing algorithm. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + @param[in,out] HashContext The context of the current hash. Must have been + initialised for usage with the HashUpdate + function. + @param[in] HashUpdate The data hashing function. + + @returns Whether hashing has been successful. +**/ +BOOLEAN +UefiImageHashImageDefault ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN OUT VOID *HashContext, + IN UEFI_IMAGE_LOADER_HASH_UPDATE HashUpdate + ); + +/** + Load the Image into the destination memory space. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + @param[out] Destination The Image destination memory. Must be allocated + from page memory. + @param[in] DestinationSize The size, in Bytes, of Destination. Must be at + least as large as the size returned by + UefiImageGetImageSize(). + + @retval RETURN_SUCCESS The Image was loaded successfully. + @retval other The Image could not be loaded successfully. +**/ +RETURN_STATUS +UefiImageLoadImage ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT VOID *Destination, + IN UINT32 DestinationSize + ); + +// FIXME: Docs +BOOLEAN +UefiImageImageIsInplace ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Equivalent to the UefiImageLoadImage() function for inplace-loading. Ensures that + all important raw file offsets match the respective RVAs. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + + @retval RETURN_SUCCESS The Image has been inplace-loaded successfully. + @retval other The Image is not suitable for inplace-loading. +**/ +RETURN_STATUS +UefiImageLoadImageInplace ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +// FIXME: Docs +RETURN_STATUS +UefiImageRelocateImageInplace ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +// FIXME: +RETURN_STATUS +UefiImageRelocateImageInplaceForExecution ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the size required to bookkeep Image runtime relocation information. + + May only be called when UefiImageGetRelocsStripped() returns FALSE. + + @param[in,out] Context The context describing the Image. Must have been + loaded by UefiImageLoadImage(). + @param[out] Size On output, the size, in Bytes, required for the + bookkeeping buffer. + + @retval RETURN_SUCCESS The Image runtime context size for the Image was + retrieved successfully. + @retval other The Image runtime context size for the Image could not + be retrieved successfully. +**/ +RETURN_STATUS +UefiImageLoaderGetRuntimeContextSize ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *Size + ); + +/** + Relocate the Image for boot-time usage. + + May only be called when UefiImageGetRelocsStripped() returns FALSE, or with + BaseAddress == UefiImageGetPreferredAddress(). + + @param[in,out] Context The context describing the Image. Must have + been loaded by UefiImageLoadImage(). + @param[in] BaseAddress The address to relocate the Image to. + @param[out] RuntimeContext If not NULL, on output, a bookkeeping data + required for Image runtime relocation. + @param[in] RuntimeContextSize The size, in Bytes, of RuntimeContext. Must + be at least as big as the size returned by + UefiImageLoaderGetRuntimeContextSize(). + + @retval RETURN_SUCCESS The Image has been relocated successfully. + @retval other The Image Relocation Directory is malformed. +**/ +RETURN_STATUS +UefiImageRelocateImage ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINT64 BaseAddress, + OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize + ); + +/** + Load the Image into the destination memory space, relocate Image for boot-time + usage, and perform environment-specific actions required to execute code from + the Image. + + May only be called when UefiImageGetRelocsStripped() returns FALSE, or with + BaseAddress == UefiImageGetPreferredAddress(). + + @param[in,out] Context The context describing the Image. Must have + been initialised by + UefiImageInitializeContext(). + @param[out] Destination The Image destination memory. Must be + allocated from page memory. + @param[in] DestinationSize The size, in Bytes, of Destination. Must be + at least as large as the size returned by + UefiImageGetImageSize(). + @param[out] RuntimeContext If not NULL, on output, a buffer + bookkeeping data required for Image runtime + relocation. + @param[in] RuntimeContextSize The size, in Bytes, of RuntimeContext. Must + be at least as big as the size returned by + UefiImageLoaderGetRuntimeContextSize(). + + @retval RETURN_SUCCESS The Image was loaded successfully. + @retval other The Image could not be loaded successfully. +**/ +RETURN_STATUS +UefiImageLoadImageForExecution ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT VOID *Destination, + IN UINT32 DestinationSize, + OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize + ); + +/** + Relocate Image for Runtime usage. + + May only be called when UefiImageGetRelocsStripped() returns FALSE, or with + BaseAddress == UefiImageGetPreferredAddress(). + + @param[in,out] Image The Image destination memory. Must have been + relocated by UefiImageRelocateImage(). + @param[in] ImageSize The size, in Bytes, of Image. + @param[in] BaseAddress The address to relocate the Image to. + @param[in] RuntimeContext The Relocation context obtained by + UefiImageRelocateImage(). + + @retval RETURN_SUCCESS The Image has been relocated successfully. + @retval other The Image could not be relocated successfully. +**/ +RETURN_STATUS +UefiImageRuntimeRelocateImage ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN UINT64 BaseAddress, + IN CONST UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext + ); + +/** + Relocate Image for Runtime usage, and perform environment-specific actions + required to execute code from the Image. + + May only be called when UefiImageGetRelocsStripped() returns FALSE, or with + BaseAddress == UefiImageGetPreferredAddress(). + + @param[in,out] Image The Image destination memory. Must have been + relocated by UefiImageRelocateImage(). + @param[in] ImageSize The size, in Bytes, of Image. + @param[in] BaseAddress The address to relocate the Image to. + @param[in] RuntimeContext The Relocation context obtained by + UefiImageRelocateImage(). + + @retval RETURN_SUCCESS The Image has been relocated successfully. + @retval other The Image could not be relocated successfully. +**/ +RETURN_STATUS +UefiImageRuntimeRelocateImageForExecution ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN UINT64 BaseAddress, + IN CONST UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext + ); + +/** + Discards optional Image segments to disguise sensitive data. + + This may destruct the Image Relocation Directory and as such, no function that + performs Image relocation may be called after this function has been invoked. + + @param[in,out] Context The context describing the Image. Must have been + loaded by UefiImageLoadImage(). +**/ +VOID +UefiImageDiscardSegments ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the Image symbols path. + + @param[in,out] Context The context describing the Image. Must have + been initialised by + UefiImageInitializeContext(). + @param[out] SymbolsPath On output, a pointer to the Image symbols + path. + @param[out] SymbolsPathSize On output, the size, in Bytes, of * + SymbolsPath. + + @retval RETURN_SUCCESS The Image symbols path was retrieved successfully. + @retval other The Image symbols path could not be retrieved + successfully. +**/ +RETURN_STATUS +UefiImageGetSymbolsPath ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST CHAR8 **SymbolsPath, + OUT UINT32 *SymbolsPathSize + ); + +/** + Retrieves the Image module name from the Image symbols path. + + @param[in,out] Context The context describing the Image. Must have + been initialised by + UefiImageInitializeContext(). + @param[out] ModuleName Buffer the Image module name is written into. + If the name exceeds ModuleNameSize, it will be + truncated. + @param[out] ModuleNameSize The size, in Bytes, of ModuleName. + + @retval RETURN_SUCCESS The Image module name was retrieved successfully. + @retval other The Image module name could not be retrieved + successfully. +**/ +RETURN_STATUS +UefiImageGetModuleNameFromSymbolsPath ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CHAR8 *ModuleName, + IN UINT32 ModuleNameSize + ); + +// FIXME: Abstract certificates somehow? +/** + Retrieves the first certificate from the Image Certificate Directory. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + @param[out] Certificate On output, the first certificate of the Image. + + @retval RETURN_SUCCESS The certificate has been retrieved successfully. + @retval RETURN_NOT_FOUND There is no such certificate. + @retval other The Image Certificate Directory is malformed. +**/ +RETURN_STATUS +UefiImageGetFirstCertificate ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST WIN_CERTIFICATE **Certificate + ); + +/** + Retrieves the next certificate from the Image Certificate Directory. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + @param[out] Certificate On input, the current certificate of the Image. + Must have been retrieved by + UefiImageGetFirstCertificate(). + On output, the next certificate of the Image. + + @retval RETURN_SUCCESS The certificate has been retrieved successfully. + @retval RETURN_NOT_FOUND There is no such certificate. + @retval other The Image Certificate Directory is malformed. +**/ +RETURN_STATUS +UefiImageGetNextCertificate ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN OUT CONST WIN_CERTIFICATE **Certificate + ); + +/** + Retrieves the Image HII data RVA. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + @param[out] HiiRva On output, the RVA of the HII resource data. + @param[out] HiiSize On output, the size, in Bytes, of HiiRva. + + @retval RETURN_SUCCESS The Image HII data has been retrieved successfully. + @retval RETURN_NOT_FOUND The Image HII data could not be found. + @retval other The Image Resource Directory is malformed. +**/ +RETURN_STATUS +UefiImageGetHiiDataRva ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *HiiRva, + OUT UINT32 *HiiSize + ); + +/** + Retrieve the Image entry point RVA. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + + @returns The Image entry point RVA. +**/ +UINT32 +UefiImageGetEntryPointAddress ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the Image machine type. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + + @returns The Image machine type. +**/ +UINT16 +UefiImageGetMachine ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the Image subsystem type. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + + @returns The Image subsystem type. +**/ +UINT16 +UefiImageGetSubsystem ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the Image segment alignment. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + + @returns The Image segment alignment. +**/ +UINT32 +UefiImageGetSegmentAlignment ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the size, in Bytes, of the Image memory space. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + + @returns The size of the Image memory space. +**/ +UINT32 +UefiImageGetImageSize ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +// FIXME: Docs +UINT32 +UefiImageGetImageSizeInplace ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the Image preferred load address. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + + @returns The Image preferred load address. +**/ +UINT64 +UefiImageGetPreferredAddress ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Returns whether the Image relocations have been stripped. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + + @returns Whether the Image relocations have been stripped. +**/ +BOOLEAN +UefiImageGetRelocsStripped ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieves the Image load address UefiImageLoadImage() has loaded the Image to. + + May be called only after UefiImageLoadImage() has succeeded. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + + @returns The Image load address. +**/ +UINTN +UefiImageLoaderGetImageAddress ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Retrieve the Image entry point address. + + May be called only after UefiImageLoadImage() has succeeded. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + + @returns The Image entry point addres. +**/ +UINTN +UefiImageLoaderGetImageEntryPoint ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +/** + Constructs an Image record from the Image. Any headers, gaps, or trailers are + described as read-only data. + + May be called only after UefiImageLoadImage() has succeeded. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + + @retval NULL The Image record could not constructed successfully. + @retval other The Image record was constructed successfully and is returned. + It is allocated using the AllocatePool() API and is + caller-owned as soon as this function returns. +**/ +UEFI_IMAGE_RECORD * +UefiImageLoaderGetImageRecord ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +// FIXME: Docs +RETURN_STATUS +UefiImageDebugLocateImage ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINTN Address + ); + +/** + Retrieve the Image fixed loading address. + + This function is only guaranteed to function correctly if the Image was built + by a tool with this feature enabled. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + @param[out] Address On output, the fixed loading address of the Image. + *Address is guaranteed to by aligned by the Image + segment alignment, and thus the size returned by + UefiImageGetImageSize is sufficient to hold the + Image. + + @retval RETURN_SUCCESS The Image has a fixed loading address. + @retval RETURN_NOT_FOUND The Image does not have a fixed loading address. + @retval RETURN_UNSUPPORTED The Image fixed loading address is unaligned. +**/ +RETURN_STATUS +UefiImageGetFixedAddress ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT64 *Address + ); + +// FIXME: Docs +VOID +UefiImageDebugPrintSegments ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +VOID +UefiImageDebugPrintImageRecord ( + IN CONST UEFI_IMAGE_RECORD *ImageRecord + ); + +#endif // UEFI_IMAGE_LIB_H_ diff --git a/MdePkg/Include/Pi/PiPeiCis.h b/MdePkg/Include/Pi/PiPeiCis.h index ad4be384bc..d8c13bd928 100644 --- a/MdePkg/Include/Pi/PiPeiCis.h +++ b/MdePkg/Include/Pi/PiPeiCis.h @@ -419,6 +419,40 @@ EFI_STATUS OUT UINT32 *AuthenticationStatus ); +/** + Searches for the next matching section within the specified file. + + This service enables PEI modules to discover the section of a given type within a valid file. + This service will search within encapsulation sections (compression and GUIDed) as well. It will + search inside of a GUIDed section or a compressed section, but may not, for example, search a + GUIDed section inside a GUIDes section. + This service will not search within compression sections or GUIDed sections that require + extraction if memory is not present. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param SectionType The value of the section type to find. + @param SectionInstance Section instance to find. + @param FileHandle Handle of the firmware file to search. + @param SectionData A pointer to the discovered section, if successful. + @param SectionDataSize The size of the discovered section, if successful. + @param AuthenticationStatus A pointer to the authentication status for this section. + + @retval EFI_SUCCESS The section was found. + @retval EFI_NOT_FOUND The section was not found. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PEI_FFS_FIND_SECTION_DATA4)( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_SECTION_TYPE SectionType, + IN UINTN SectionInstance, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData, + OUT UINT32 *SectionDataSize, + OUT UINT32 *AuthenticationStatus + ); + /** This function registers the found memory configuration with the PEI Foundation. @@ -944,6 +978,7 @@ struct _EFI_PEI_SERVICES { EFI_PEI_FFS_GET_FILE_INFO2 FfsGetFileInfo2; EFI_PEI_RESET2_SYSTEM ResetSystem2; EFI_PEI_FREE_PAGES FreePages; + EFI_PEI_FFS_FIND_SECTION_DATA4 FindSectionData4; }; /// diff --git a/MdePkg/Include/Ppi/FirmwareVolume.h b/MdePkg/Include/Ppi/FirmwareVolume.h index e789970edb..0b7a2727c6 100644 --- a/MdePkg/Include/Ppi/FirmwareVolume.h +++ b/MdePkg/Include/Ppi/FirmwareVolume.h @@ -255,8 +255,43 @@ EFI_STATUS OUT UINT32 *AuthenticationStatus ); +/** + Find the next matching section in the firmware file. + + This service enables PEI modules to discover sections + of a given instance and type within a valid file. + + @param This Points to this instance of the + EFI_PEI_FIRMWARE_VOLUME_PPI. + @param SearchType A filter to find only sections of this + type. + @param SearchInstance A filter to find the specific instance + of sections. + @param FileHandle Handle of firmware file in which to + search. + @param SectionData Updated upon return to point to the + section found. + @param AuthenticationStatus Updated upon return to point to the + authentication status for this section. + + @retval EFI_SUCCESS Section was found. + @retval EFI_NOT_FOUND Section of the specified type was not + found. SectionData contains NULL. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_PEI_FV_FIND_SECTION3)( + IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, + IN EFI_SECTION_TYPE SearchType, + IN UINTN SearchInstance, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData, + OUT UINT32 *SectionDataSize, + OUT UINT32 *AuthenticationStatus +); + #define EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE SIGNATURE_32 ('P', 'F', 'V', 'P') -#define EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION 0x00010030 +#define EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION 0x00010031 /// /// This PPI provides functions for accessing a memory-mapped firmware volume of a specific format. @@ -278,6 +313,7 @@ struct _EFI_PEI_FIRMWARE_VOLUME_PPI { /// Revision for further extension. /// UINT32 Revision; + EFI_PEI_FV_FIND_SECTION3 FindSectionByType3; }; extern EFI_GUID gEfiPeiFirmwareVolumePpiGuid; diff --git a/MdePkg/Include/Protocol/DebugSupport.h b/MdePkg/Include/Protocol/DebugSupport.h index fced5c759f..5b7e331780 100644 --- a/MdePkg/Include/Protocol/DebugSupport.h +++ b/MdePkg/Include/Protocol/DebugSupport.h @@ -16,8 +16,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #ifndef __DEBUG_SUPPORT_H__ #define __DEBUG_SUPPORT_H__ -#include - typedef struct _EFI_DEBUG_SUPPORT_PROTOCOL EFI_DEBUG_SUPPORT_PROTOCOL; /// @@ -845,12 +843,12 @@ VOID /// Machine type definition /// typedef enum { - IsaIa32 = IMAGE_FILE_MACHINE_I386, ///< 0x014C - IsaX64 = IMAGE_FILE_MACHINE_X64, ///< 0x8664 - IsaIpf = IMAGE_FILE_MACHINE_IA64, ///< 0x0200 - IsaEbc = IMAGE_FILE_MACHINE_EBC, ///< 0x0EBC - IsaArm = IMAGE_FILE_MACHINE_ARMTHUMB_MIXED, ///< 0x01c2 - IsaAArch64 = IMAGE_FILE_MACHINE_ARM64 ///< 0xAA64 + IsaIa32 = EFI_IMAGE_MACHINE_IA32, ///< 0x014C + IsaX64 = EFI_IMAGE_MACHINE_X64, ///< 0x8664 + IsaIpf = EFI_IMAGE_MACHINE_IA64, ///< 0x0200 + IsaEbc = EFI_IMAGE_MACHINE_EBC, ///< 0x0EBC + IsaArm = EFI_IMAGE_MACHINE_ARMTHUMB_MIXED, ///< 0x01c2 + IsaAArch64 = EFI_IMAGE_MACHINE_AARCH64 ///< 0xAA64 } EFI_INSTRUCTION_SET_ARCHITECTURE; // diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c index f853c84827..022020b4c6 100644 --- a/MdePkg/Library/BasePeCoffLib/BasePeCoff.c +++ b/MdePkg/Library/BasePeCoffLib/BasePeCoff.c @@ -1743,7 +1743,7 @@ PeCoffLoaderLoadImage ( **/ VOID EFIAPI -PeCoffLoaderRelocateImageForRuntime ( +PeCoffLoaderRuntimeRelocateImage ( IN PHYSICAL_ADDRESS ImageBase, IN PHYSICAL_ADDRESS VirtImageBase, IN UINTN ImageSize, diff --git a/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h b/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h index aa86a54850..3ee56e0e5f 100644 --- a/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h +++ b/MdePkg/Library/BasePeCoffLib/BasePeCoffLibInternals.h @@ -20,12 +20,13 @@ // // Macro definitions for RISC-V architecture. // -#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1)) -#define RISCV_IMM_BITS 12 -#define RISCV_IMM_REACH (1LL<> (s)) & ((1<<(n))-1)) +#define RISCV_IMM_BITS 12 +#define RISCV_IMM_REACH (1LL< + Copyright (c) 2020, Vitaly Cheptsov. All rights reserved.
+ Copyright (c) 2020, ISP RAS. All rights reserved.
+ SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef PE_COFF_LOAD_H_ +#define PE_COFF_LOAD_H_ + +/** + Load the Image into the destination memory space. + + @param[in] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + @param[out] Destination The Image destination memory. Must be allocated + from page memory. + @param[in] DestinationSize The size, in bytes, of Destination. + Must be at least + Context->SizeOfImage + + Context->SizeOfImageDebugAdd. If the Section + Alignment exceeds 4 KB, must be at least + Context->SizeOfImage + + Context->SizeOfImageDebugAdd + Context->SectionAlignment. + + @retval RETURN_SUCCESS The Image was loaded successfully. + @retval other The Image could not be loaded successfully. +**/ +RETURN_STATUS +PeCoffLoadImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT VOID *Destination, + IN UINT32 DestinationSize + ); + +/** + Discards optional Image Sections to disguise sensitive data. + + @param[in] Context The context describing the Image. Must have been loaded by + PeCoffLoadImage(). +**/ +VOID +PeCoffDiscardSections ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +#endif // PE_COFF_LOAD_H_ diff --git a/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf new file mode 100644 index 0000000000..4d375e2506 --- /dev/null +++ b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf @@ -0,0 +1,47 @@ +## @file +# PE/COFF Loader Library implementation. +# +# Copyright (c) 2020 - 2021, Marvin Häuser. All rights reserved.
+# Copyright (c) 2020, Vitaly Cheptsov. All rights reserved.
+# Copyright (c) 2020, ISP RAS. All rights reserved.
+# +# SPDX-License-Identifier: BSD-3-Clause +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BasePeCoffLib2 + FILE_GUID = 454A346E-3064-464E-8285-99DF1E220E0F + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeCoffLib2 + +[Sources] + PeCoffDebug.c + PeCoffHash.c + PeCoffHii.c + PeCoffInfo.c + PeCoffInit.c + PeCoffLoad.c + PeCoffRelocate.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + BaseOverflowLib + DebugLib + MemoryAllocationLib + +[FixedPcd] + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRtRelocAllowTargetMismatch + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderHashProhibitOverlap + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderLoadHeader + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRelocTypePolicy + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAlignmentPolicy + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderWXorX + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderDebugSupport + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderProhibitTe + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset diff --git a/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2Internals.h b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2Internals.h new file mode 100644 index 0000000000..97f2d4b5c8 --- /dev/null +++ b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2Internals.h @@ -0,0 +1,55 @@ +/** @file + Provides shared private definitions across this library. + + Copyright (c) 2020 - 2021, Marvin Häuser. All rights reserved.
+ Copyright (c) 2020, Vitaly Cheptsov. All rights reserved.
+ Copyright (c) 2020, ISP RAS. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef BASE_PE_COFF_LIB2_INTERNALS_H_ +#define BASE_PE_COFF_LIB2_INTERNALS_H_ + +// +// PcdImageLoaderRelocTypePolicy bits. +// + +/// +/// If set, ARM Thumb Image relocations are supported. +/// +#define PCD_RELOC_TYPE_POLICY_ARM BIT0 + +/// +/// Denotes the alignment requirement for Image certificate sizes. +/// +#define IMAGE_CERTIFICATE_ALIGN 8U + +// +// The PE/COFF specification guarantees an 8 Byte alignment for certificate +// sizes. This is larger than the alignment requirement for WIN_CERTIFICATE +// implied by the UEFI ABI. ASSERT this holds. +// +STATIC_ASSERT ( + ALIGNOF (WIN_CERTIFICATE) <= IMAGE_CERTIFICATE_ALIGN, + "The PE/COFF specification guarantee does not suffice." + ); + +// +// The 4 Byte alignment guaranteed by the PE/COFF specification has been +// replaced with ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK) for proof simplicity. +// This obviously was the original intention of the specification. ASSERT in +// case the equality is not given. +// +STATIC_ASSERT ( + sizeof (UINT32) == ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK), + "The current model violates the PE/COFF specification" + ); + +// FIXME: +RETURN_STATUS +PeCoffLoadImageInplaceNoBase ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +#endif // BASE_PE_COFF_LIB_INTERNALS_H_ diff --git a/MdePkg/Library/BasePeCoffLib2/Documentation.md b/MdePkg/Library/BasePeCoffLib2/Documentation.md new file mode 100644 index 0000000000..0c8ef63e07 --- /dev/null +++ b/MdePkg/Library/BasePeCoffLib2/Documentation.md @@ -0,0 +1,40 @@ +# EDK II Image Loader documentation + +**Please note that this is an early work-in-progress. Correctness and completeness are not guaranteed.** + +## 1. Image Section Table well-formedness +An Image Section Table is considered well-formed if and only if: +1. The Image Section Table is sorted by Image section RVA in ascending order. +2. All Image sections are disjoint in the Image memory space. +3. For PE/COFF Images, all Image sections are in bounds of the Image memory space defined by the Image headers. + * For TE Images, the Image memory space is implicitly defined by the Image Section Table. +4. All Image sections are in bounds of the raw file. + +Additionally, based on PCD policy values, the following constraints may be added: + +5. All Image sections are aligned by the Image section alignment. +6. The first Image section is adjacent to the aligned Image headers, or it is the start of the Image memory space. +7. All Image sections are pairwise adjacent (considering aligned size) in the Image memory space. +8. All Image sections are not executable and writable at the same time. + +### 1.2. Rationales + +|| Origin | Rationale | Known violations | +|---|---|---|---| +|1 | PE | Allows for efficient verification of constraint 2. | None | +|2 | PE | Mitigates accidental Image corruption and ensures the same deterministic Image memory space contents invariant of Image section load order. | None | +|3 | PE | Provides hardening against (otherwise potentially incorrect) assumptions regarding the Image header information. | None | +|4 | PE | Mitigates out-of-bounds accesses. | None | +|5 | PE | Ensures data is aligned at their optimal boundary and provides hardening against (otherwise potentially incorrect) assumptions regarding the Image header information. | Old Apple Mac OS X bootloaders, old iPXE OPROMs | +|6 | EDK II | Allows both the Image Headers to be or to not be loaded. Loading the Image Headers is the default behaviour for all common PE/COFF Image loaders, however it is not required, and the data may be used to more easily identify locations within the Image memory space. | See 5 | +|7 | PE | Provides hardening against unintentional gaps in the Image memory space that may be handled incorrectly. | See 5 | +|8 | EDK II | Provides hardening against accidental and malicious code modifications. The concept is well-known as W^X. | None | + +## 2. Image memory permissions +The Image memory space is protected as follows: +1. Image Headers are protected as read-only data. +2. Image sections are protected according to their defined permissions. +3. Any gaps between Image sections are protected as read-only data. +4. The Image trailer is protected as read-only data. + +Due to the explicit handling of Image Headers, gaps, and Image trailer, the full Image memory space has well-defined permissions. To embrace the W^X pattern, and to mitigate attacks (e.g. format string exploits), the tightest permissions are chosen for all Image memory permission segments. diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffDebug.c b/MdePkg/Library/BasePeCoffLib2/PeCoffDebug.c new file mode 100644 index 0000000000..8109b65f57 --- /dev/null +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffDebug.c @@ -0,0 +1,264 @@ +/** @file + Implements APIs to load PE/COFF debug information. + + Copyright (c) 2020 - 2021, Marvin Häuser. All rights reserved.
+ Copyright (c) 2020, Vitaly Cheptsov. All rights reserved.
+ Copyright (c) 2020, ISP RAS. All rights reserved.
+ Portions copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+ Portions copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "BasePeCoffLib2Internals.h" + +RETURN_STATUS +PeCoffGetPdbPath ( + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT CONST CHAR8 **PdbPath, + OUT UINT32 *PdbPathSize + ) +{ + BOOLEAN Overflow; + + CONST EFI_IMAGE_DATA_DIRECTORY *DebugDir; + CONST EFI_TE_IMAGE_HEADER *TeHdr; + CONST EFI_IMAGE_NT_HEADERS32 *Pe32Hdr; + CONST EFI_IMAGE_NT_HEADERS64 *Pe32PlusHdr; + + CONST EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntries; + UINT32 NumDebugEntries; + UINT32 DebugIndex; + CONST EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *CodeViewEntry; + + UINT32 DebugDirTop; + UINT32 DebugEntryFileOffset; + UINT32 DebugEntryFileOffsetTop; + + CONST CHAR8 *CodeView; + UINT32 PdbOffset; + CONST CHAR8 *PdbName; + UINT32 PdbNameSize; + + ASSERT (Context != NULL); + ASSERT (PdbPath != NULL); + ASSERT (PdbPathSize != NULL); + + if (!PcdGetBool (PcdImageLoaderDebugSupport)) { + return RETURN_NOT_FOUND; + } + // + // Retrieve the Debug Directory of the Image. + // + switch (Context->ImageType) { + case PeCoffLoaderTypeTe: + if (PcdGetBool (PcdImageLoaderProhibitTe)) { + ASSERT (FALSE); + return RETURN_UNSUPPORTED; + } + + TeHdr = (CONST EFI_TE_IMAGE_HEADER *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + ); + + DebugDir = &TeHdr->DataDirectory[1]; + break; + + case PeCoffLoaderTypePe32: + Pe32Hdr = (CONST EFI_IMAGE_NT_HEADERS32 *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->ExeHdrOffset + ); + + if (Pe32Hdr->NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { + return RETURN_NOT_FOUND; + } + + DebugDir = Pe32Hdr->DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_DEBUG; + break; + + case PeCoffLoaderTypePe32Plus: + Pe32PlusHdr = (CONST EFI_IMAGE_NT_HEADERS64 *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->ExeHdrOffset + ); + + if (Pe32PlusHdr->NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { + return RETURN_NOT_FOUND; + } + + DebugDir = Pe32PlusHdr->DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_DEBUG; + break; + + default: + ASSERT (FALSE); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Debug Directory is not empty. + // + if (DebugDir->Size == 0) { + return RETURN_NOT_FOUND; + } + // + // Verify the Debug Directory has a well-formed size. + // + if (DebugDir->Size % sizeof (*DebugEntries) != 0) { + // + // Some Apple-made images contain a sum of EFI_IMAGE_DEBUG_DIRECTORY_ENTRY + // and EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY sizes in DebugDir size. + // Since this violates the spec and nobody but Apple has access + // to the DEBUG symbols, just ignore this debug information. + // + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Debug Directory is in bounds of the Image buffer. + // + Overflow = BaseOverflowAddU32 ( + DebugDir->VirtualAddress, + DebugDir->Size, + &DebugDirTop + ); + if (Overflow || DebugDirTop > Context->SizeOfImage) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Debug Directory Image address is sufficiently aligned. + // + if (!IS_ALIGNED (DebugDir->VirtualAddress, ALIGNOF (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY))) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + DebugEntries = (CONST EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (CONST VOID *) ( + (CONST CHAR8 *) Context->ImageBuffer + DebugDir->VirtualAddress + ); + + NumDebugEntries = DebugDir->Size / sizeof (*DebugEntries); + + for (DebugIndex = 0; DebugIndex < NumDebugEntries; ++DebugIndex) { + if (DebugEntries[DebugIndex].Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { + break; + } + } + // + // Verify the CodeView entry has been found in the Debug Directory. + // + if (DebugIndex == NumDebugEntries) { + return RETURN_NOT_FOUND; + } + // + // Verify the CodeView entry has sufficient space for the signature. + // + CodeViewEntry = &DebugEntries[DebugIndex]; + + if (CodeViewEntry->SizeOfData < sizeof (UINT32)) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + DebugEntryFileOffset = CodeViewEntry->FileOffset; + + if (!PcdGetBool (PcdImageLoaderProhibitTe)) { + Overflow = BaseOverflowSubU32 ( + DebugEntryFileOffset, + Context->TeStrippedOffset, + &DebugEntryFileOffset + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } else { + ASSERT (Context->TeStrippedOffset == 0); + } + // + // Verify the CodeView entry is in bounds of the raw file, and the + // CodeView entry raw file offset is sufficiently aligned. + // + Overflow = BaseOverflowAddU32 ( + DebugEntryFileOffset, + CodeViewEntry->SizeOfData, + &DebugEntryFileOffsetTop + ); + if (Overflow || DebugEntryFileOffsetTop > Context->FileSize + || !IS_ALIGNED (DebugEntryFileOffset, ALIGNOF (UINT32))) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + CodeView = (CONST CHAR8 *) Context->FileBuffer + DebugEntryFileOffset; + // + // This memory access is safe because we know that + // 1) IS_ALIGNED (DebugEntryFileOffset, ALIGNOF (UINT32)) + // 2) sizeof (UINT32) <= CodeViewEntry->SizeOfData. + // + switch (*(CONST UINT32 *) (CONST VOID *) CodeView) { + case CODEVIEW_SIGNATURE_NB10: + PdbOffset = sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY); + + STATIC_ASSERT ( + ALIGNOF (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) <= ALIGNOF (UINT32), + "The structure may be misalignedd." + ); + break; + + case CODEVIEW_SIGNATURE_RSDS: + PdbOffset = sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY); + + STATIC_ASSERT ( + ALIGNOF (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY) <= ALIGNOF (UINT32), + "The structure may be misalignedd." + ); + break; + + case CODEVIEW_SIGNATURE_MTOC: + PdbOffset = sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY); + + STATIC_ASSERT ( + ALIGNOF (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY) <= ALIGNOF (UINT32), + "The structure may be misalignedd." + ); + break; + + default: + return RETURN_UNSUPPORTED; + } + // + // Verify the PDB path exists and is in bounds of the Image buffer. + // + Overflow = BaseOverflowSubU32 ( + CodeViewEntry->SizeOfData, + PdbOffset, + &PdbNameSize + ); + if (Overflow || PdbNameSize == 0) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the PDB path is correctly terminated. + // + PdbName = CodeView + PdbOffset; + if (PdbName[PdbNameSize - 1] != 0) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + *PdbPath = PdbName; + *PdbPathSize = PdbNameSize; + + return RETURN_SUCCESS; +} diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffHash.c b/MdePkg/Library/BasePeCoffLib2/PeCoffHash.c new file mode 100644 index 0000000000..12a9495d05 --- /dev/null +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffHash.c @@ -0,0 +1,487 @@ +/** @file + Implements APIs to verify the Authenticode Signature of PE/COFF Images. + + Copyright (c) 2020 - 2021, Marvin Häuser. All rights reserved.
+ Copyright (c) 2020, Vitaly Cheptsov. All rights reserved.
+ Copyright (c) 2020, ISP RAS. All rights reserved.
+ Portions copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ Portions copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include "BasePeCoffLib2Internals.h" + +/** + Hashes the Image section data in ascending order of raw file appearance. + + @param[in] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + @param[in] HashUpdate The data hashing function. + @param[in,out] HashContext The context of the current hash. + + @returns Whether hashing has been successful. +**/ +STATIC +BOOLEAN +InternalHashSections ( + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN OUT VOID *HashContext, + IN PE_COFF_LOADER_HASH_UPDATE HashUpdate, + IN OUT UINT32 *SumBytesHashed + ) +{ + BOOLEAN Result; + BOOLEAN Overflow; + + CONST EFI_IMAGE_SECTION_HEADER *Sections; + CONST EFI_IMAGE_SECTION_HEADER **SortedSections; + UINT16 SectionIndex; + UINT16 SectionPos; + UINT32 SectionTop; + UINT32 CurHashSize; + // + // 9. Build a temporary table of pointers to all of the section headers in the + // image. The NumberOfSections field of COFF File Header indicates how big + // the table should be. Do not include any section headers in the table + // whose SizeOfRawData field is zero. + // + SortedSections = AllocatePool ( + (UINT32) Context->NumberOfSections * sizeof (*SortedSections) + ); + if (SortedSections == NULL) { + return FALSE; + } + + Sections = (CONST EFI_IMAGE_SECTION_HEADER *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->SectionsOffset + ); + // + // 10. Using the PointerToRawData field (offset 20) in the referenced + // SectionHeader structure as a key, arrange the table's elements in + // ascending order. In other words, sort the section headers in ascending + // order according to the disk-file offset of the sections. + // + SortedSections[0] = Sections; + // + // Perform Insertion Sort to order the Sections by their raw file offset. + // + for (SectionIndex = 1; SectionIndex < Context->NumberOfSections; ++SectionIndex) { + for (SectionPos = SectionIndex; + 0 < SectionPos + && SortedSections[SectionPos - 1]->PointerToRawData > Sections[SectionIndex].PointerToRawData; + --SectionPos) { + SortedSections[SectionPos] = SortedSections[SectionPos - 1]; + } + + SortedSections[SectionPos] = Sections + SectionIndex; + } + + Result = TRUE; + SectionTop = 0; + CurHashSize = 0; + // + // 13. Repeat steps 11 and 12 for all of the sections in the sorted table. + // + ASSERT (Context->TeStrippedOffset == 0); + for (SectionIndex = 0; SectionIndex < Context->NumberOfSections; ++SectionIndex) { + // + // Verify the Image section does not overlap with the previous one if the + // policy demands it. Overlapping Sections could dramatically increase the + // hashing time. + // FIXME: Move to init, along with a trailing data policy. + // + if (PcdGetBool (PcdImageLoaderHashProhibitOverlap)) { + if (SectionTop > SortedSections[SectionIndex]->PointerToRawData) { + Result = FALSE; + break; + } + + SectionTop = SortedSections[SectionIndex]->PointerToRawData + SortedSections[SectionIndex]->SizeOfRawData; + } + // + // Skip Sections that contain no data. + // + if (SortedSections[SectionIndex]->SizeOfRawData > 0) { + // + // 11. Walk through the sorted table, load the corresponding section into + // memory, and hash the entire section. Use the SizeOfRawData field in the + // SectionHeader structure to determine the amount of data to hash. + // + Result = HashUpdate ( + HashContext, + (CONST CHAR8 *) Context->FileBuffer + SortedSections[SectionIndex]->PointerToRawData, + SortedSections[SectionIndex]->SizeOfRawData + ); + if (!Result) { + break; + } + // + // 12. Add the section’s SizeOfRawData value to SUM_OF_BYTES_HASHED. + // + // If and only if the Sections do not overlap, we know their sizes are at + // most MAX_UINT32 in sum because the file size is at most MAX_UINT32. + // + if (PcdGetBool (PcdImageLoaderHashProhibitOverlap)) { + CurHashSize += SortedSections[SectionIndex]->SizeOfRawData; + } else { + // + // Verify the hash size does not overflow. + // + Overflow = BaseOverflowAddU32 ( + CurHashSize, + SortedSections[SectionIndex]->SizeOfRawData, + &CurHashSize + ); + if (Overflow) { + Result = FALSE; + break; + } + } + } + } + + *SumBytesHashed = CurHashSize; + FreePool ((VOID *) SortedSections); + + return Result; +} + +BOOLEAN +PeCoffHashImageAuthenticode ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN OUT VOID *HashContext, + IN PE_COFF_LOADER_HASH_UPDATE HashUpdate + ) +{ + BOOLEAN Result; + BOOLEAN Overflow; + UINT32 NumberOfRvaAndSizes; + UINT32 ChecksumOffset; + UINT32 SecurityDirOffset; + UINT32 SecurityDirSize; + UINT32 CurrentOffset; + UINT32 HashSize; + CONST EFI_IMAGE_NT_HEADERS32 *Pe32; + CONST EFI_IMAGE_NT_HEADERS64 *Pe32Plus; + UINT32 SumBytesHashed; + UINT32 FileSize; + + // + // These conditions must be met by the caller prior to calling this function. + // + // 1. Load the image header into memory. + // 2. Initialize a hash algorithm context. + // + + // + // This step can be moved here because steps 1 to 5 do not modify the Image. + // + // 6. Get the Attribute Certificate Table address and size from the + // Certificate Table entry. For details, see section 5.7 of the PE/COFF + // specification. + // + // Additionally, retrieve important offsets for later steps. + // + switch (Context->ImageType) { + case PeCoffLoaderTypeTe: + if (PcdGetBool (PcdImageLoaderProhibitTe)) { + ASSERT (FALSE); + return FALSE; + } + // + // Authenticode does not define a hashing algorithm for TE Images. + // + DEBUG_RAISE (); + return FALSE; + + case PeCoffLoaderTypePe32: + Pe32 = (CONST EFI_IMAGE_NT_HEADERS32 *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->ExeHdrOffset + ); + ChecksumOffset = Context->ExeHdrOffset + (UINT32) OFFSET_OF (EFI_IMAGE_NT_HEADERS32, CheckSum); + SecurityDirOffset = Context->ExeHdrOffset + (UINT32) OFFSET_OF (EFI_IMAGE_NT_HEADERS32, DataDirectory) + (UINT32) (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY * sizeof (EFI_IMAGE_DATA_DIRECTORY)); + NumberOfRvaAndSizes = Pe32->NumberOfRvaAndSizes; + // + // Retrieve the Security Directory size depending on existence. + // + if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY < NumberOfRvaAndSizes) { + SecurityDirSize = Pe32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size; + } else { + SecurityDirSize = 0; + } + + break; + + case PeCoffLoaderTypePe32Plus: + Pe32Plus = (CONST EFI_IMAGE_NT_HEADERS64 *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->ExeHdrOffset + ); + ChecksumOffset = Context->ExeHdrOffset + (UINT32) OFFSET_OF (EFI_IMAGE_NT_HEADERS64, CheckSum); + SecurityDirOffset = Context->ExeHdrOffset + (UINT32) OFFSET_OF (EFI_IMAGE_NT_HEADERS64, DataDirectory) + (UINT32) (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY * sizeof (EFI_IMAGE_DATA_DIRECTORY)); + NumberOfRvaAndSizes = Pe32Plus->NumberOfRvaAndSizes; + // + // Retrieve the Security Directory size depending on existence. + // + if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY < NumberOfRvaAndSizes) { + SecurityDirSize = Pe32Plus->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size; + } else { + SecurityDirSize = 0; + } + + break; + + default: + ASSERT (FALSE); + return FALSE; + } + // + // 3. Hash the image header from its base to immediately before the start of + // the checksum address, as specified in Optional Header Windows-Specific + // Fields. + // + Result = HashUpdate (HashContext, Context->FileBuffer, ChecksumOffset); + if (!Result) { + DEBUG_RAISE (); + return FALSE; + } + // + // 4. Skip over the checksum, which is a 4-byte field. + // + CurrentOffset = ChecksumOffset + sizeof (UINT32); + // + // 5. Hash everything from the end of the checksum field to immediately before + // the start of the Certificate Table entry, as specified in Optional + // Header Data Directories. + // + if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY < NumberOfRvaAndSizes) { + HashSize = SecurityDirOffset - CurrentOffset; + Result = HashUpdate ( + HashContext, + (CONST CHAR8 *) Context->FileBuffer + CurrentOffset, + HashSize + ); + if (!Result) { + DEBUG_RAISE (); + return FALSE; + } + // + // Skip over the Security Directory. + // + CurrentOffset = SecurityDirOffset + sizeof (EFI_IMAGE_DATA_DIRECTORY); + } + // + // 7. Exclude the Certificate Table entry from the calculation and hash + // everything from the end of the Certificate Table entry to the end of + // image header, including Section Table (headers).The Certificate Table + // entry is 8 Bytes long, as specified in Optional Header Data Directories. + // + HashSize = Context->SizeOfHeaders - CurrentOffset; + Result = HashUpdate ( + HashContext, + (CONST CHAR8 *) Context->FileBuffer + CurrentOffset, + HashSize + ); + if (!Result) { + DEBUG_RAISE (); + return FALSE; + } + // + // Perform the Section-related steps of the algorithm. + // + Result = InternalHashSections ( + Context, + HashContext, + HashUpdate, + &SumBytesHashed + ); + if (!Result) { + DEBUG_RAISE (); + return FALSE; + } + // + // 8. Create a counter called SUM_OF_BYTES_HASHED, which is not part of the + // signature. Set this counter to the SizeOfHeaders field, as specified in + // Optional Header Windows-Specific Field. + // + Overflow = BaseOverflowAddU32 ( + SumBytesHashed, + Context->SizeOfHeaders, + &SumBytesHashed + ); + if (Overflow) { + DEBUG_RAISE (); + return FALSE; + } + // + // 14. Create a value called FILE_SIZE, which is not part of the signature. + // Set this value to the image’s file size, acquired from the underlying + // file system. If FILE_SIZE is greater than SUM_OF_BYTES_HASHED, the file + // contains extra data that must be added to the hash. This data begins at + // the SUM_OF_BYTES_HASHED file offset, and its length is: + // (File Size) - ((Size of AttributeCertificateTable) + SUM_OF_BYTES_HASHED) + // + // Note: The size of Attribute Certificate Table is specified in the + // second ULONG value in the Certificate Table entry (32 bit: offset 132, + // 64 bit: offset 148) in Optional Header Data Directories. + // + FileSize = Context->FileSize - SecurityDirSize; + if (SumBytesHashed < FileSize) { + Result = HashUpdate ( + HashContext, + (CONST CHAR8 *) Context->FileBuffer + SumBytesHashed, + FileSize - SumBytesHashed + ); + } + // + // This step must be performed by the caller after this function succeeded. + // + // 15. Finalize the hash algorithm context. + // + return Result; +} + +RETURN_STATUS +PeCoffGetFirstCertificate ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT CONST WIN_CERTIFICATE **Certificate + ) +{ + CONST WIN_CERTIFICATE *WinCertificate; + // + // These conditions are verified by PeCoffInitializeContext(). + // + ASSERT (Context->SecDirOffset % ALIGNOF (WIN_CERTIFICATE)); + ASSERT (Context->SecDirSize == 0 || sizeof (WIN_CERTIFICATE) <= Context->SecDirSize); + // + // Verify the Security Directory is not empty. + // + if (Context->SecDirSize == 0) { + return RETURN_NOT_FOUND; + } + // + // Verify the certificate size is well-formed and that it is in bounds of the + // Security Directory. + // + WinCertificate = (CONST WIN_CERTIFICATE *) (CONST VOID *) ( + (CONST UINT8 *) Context->FileBuffer + Context->SecDirOffset + ); + if (WinCertificate->dwLength < sizeof (WIN_CERTIFICATE) + || WinCertificate->dwLength > Context->SecDirSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the certificate size is sufficiently aligned, if the policy demands + // it. This has been observed to not be the case with images signed with + // pesign, such as GRUB. + // + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_CERTIFICATE_SIZES) == 0) { + if (!IS_ALIGNED (WinCertificate->dwLength, IMAGE_CERTIFICATE_ALIGN)) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } + + *Certificate = WinCertificate; + + return RETURN_SUCCESS; +} + +RETURN_STATUS +PeCoffGetNextCertificate ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN OUT CONST WIN_CERTIFICATE **Certificate + ) +{ + BOOLEAN Overflow; + UINT32 CertOffset; + UINT32 CertSize; + UINT32 CertEnd; + CONST WIN_CERTIFICATE *WinCertificate; + // + // This condition is verified by PeCoffInitializeContext(). + // + ASSERT (IS_ALIGNED (Context->SecDirSize, IMAGE_CERTIFICATE_ALIGN)); + // + // Retrieve the current certificate. + // + WinCertificate = *Certificate; + CertOffset = (UINT32) ((UINTN) WinCertificate - ((UINTN) Context->FileBuffer + Context->SecDirOffset)); + // + // Retrieve the offset of the next certificate. + // + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_CERTIFICATE_SIZES) == 0) { + CertSize = WinCertificate->dwLength; + } else { + CertSize = ALIGN_VALUE (WinCertificate->dwLength, IMAGE_CERTIFICATE_ALIGN); + } + + CertOffset += CertSize; + // + // This invariant is ensured by the certificate iteration functions. + // + ASSERT (CertOffset <= Context->SecDirSize); + // + // If the next offset is the end of the Directory, signal it's the end of + // the certificate list. + // + if (CertOffset == Context->SecDirSize) { + return RETURN_NOT_FOUND; + } + // + // Verify the Directory fits another certificate. + // + if (Context->SecDirSize - CertOffset < sizeof (WIN_CERTIFICATE)) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the certificate has a well-formed size. + // + WinCertificate = (CONST WIN_CERTIFICATE *) (CONST VOID *) ( + (CONST UINT8 *) Context->FileBuffer + Context->SecDirOffset + CertOffset + ); + if (WinCertificate->dwLength < sizeof (WIN_CERTIFICATE)) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the certificate size is sufficiently aligned, if the policy demands + // it. + // + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_CERTIFICATE_SIZES) == 0) { + if (!IS_ALIGNED (WinCertificate->dwLength, IMAGE_CERTIFICATE_ALIGN)) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } + // + // Verify the certificate is in bounds of the Security Directory. + // + Overflow = BaseOverflowAddU32 ( + CertOffset, + WinCertificate->dwLength, + &CertEnd + ); + if (Overflow || CertEnd > Context->SecDirSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + *Certificate = WinCertificate; + + return RETURN_SUCCESS; +} diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffHii.c b/MdePkg/Library/BasePeCoffLib2/PeCoffHii.c new file mode 100644 index 0000000000..a877031ca9 --- /dev/null +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffHii.c @@ -0,0 +1,286 @@ +/** @file + Implements APIs to retrieve UEFI HII data from PE/COFF Images. + + Copyright (c) 2020 - 2021, Marvin Häuser. All rights reserved.
+ Copyright (c) 2020, Vitaly Cheptsov. All rights reserved.
+ Copyright (c) 2020, ISP RAS. All rights reserved.
+ Portions copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+ Portions copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include + +#include + +#include +#include +#include +#include + +#include "BasePeCoffLib2Internals.h" + +RETURN_STATUS +PeCoffGetHiiDataRva ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *HiiRva, + OUT UINT32 *HiiSize + ) +{ + UINT16 Index; + CONST EFI_IMAGE_NT_HEADERS32 *Pe32Hdr; + CONST EFI_IMAGE_NT_HEADERS64 *Pe32PlusHdr; + CONST EFI_IMAGE_DATA_DIRECTORY *ResDirTable; + CONST EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDir; + CONST EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *ResourceDirEntry; + CONST EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirString; + CONST EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry; + BOOLEAN Overflow; + UINT32 Offset; + UINT32 TopOffset; + UINT8 ResourceLevel; + UINT32 HiiRvaEnd; + + ASSERT (Context != NULL); + ASSERT (HiiRva != NULL); + ASSERT (HiiSize != NULL); + // + // Retrieve the Image's Resource Directory Table. + // + switch (Context->ImageType) { + case PeCoffLoaderTypeTe: + if (PcdGetBool (PcdImageLoaderProhibitTe)) { + ASSERT (FALSE); + return RETURN_UNSUPPORTED; + } + // + // TE Images do not contain a Resource Directory Table. + // + return RETURN_NOT_FOUND; + + case PeCoffLoaderTypePe32: + Pe32Hdr = (CONST EFI_IMAGE_NT_HEADERS32 *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->ExeHdrOffset + ); + if (Pe32Hdr->NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE) { + return RETURN_NOT_FOUND; + } + + ResDirTable = &Pe32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE]; + break; + + case PeCoffLoaderTypePe32Plus: + Pe32PlusHdr = (CONST EFI_IMAGE_NT_HEADERS64 *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->ExeHdrOffset + ); + if (Pe32PlusHdr->NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE) { + return RETURN_NOT_FOUND; + } + + ResDirTable = &Pe32PlusHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE]; + break; + + default: + ASSERT (FALSE); + return RETURN_UNSUPPORTED; + } + // + // Verify the Resource Directory Table contains at least one entry. + // + if (ResDirTable->Size < sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (*ResourceDir->Entries)) { + return RETURN_NOT_FOUND; + } + // + // Verify the start of the Resource Directory Table is sufficiently aligned. + // + if (!IS_ALIGNED (ResDirTable->VirtualAddress, ALIGNOF (EFI_IMAGE_RESOURCE_DIRECTORY))) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // FIXME: Verify against first Image section / Headers due to XIP TE. + // + // Verify the Resource Directory Table is in bounds of the Image buffer. + // + Overflow = BaseOverflowAddU32 ( + ResDirTable->VirtualAddress, + ResDirTable->Size, + &TopOffset + ); + if (Overflow || TopOffset > Context->SizeOfImage) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + ResourceDir = (CONST EFI_IMAGE_RESOURCE_DIRECTORY *) (CONST VOID *) ( + (CONST CHAR8 *) Context->ImageBuffer + ResDirTable->VirtualAddress + ); + // + // Verify the Resource Directory Table can hold all of its entries. + // + STATIC_ASSERT ( + sizeof (*ResourceDirEntry) * MAX_UINT16 <= ((UINT64) MAX_UINT32 + 1U) / 2 - sizeof (EFI_IMAGE_RESOURCE_DIRECTORY), + "The following arithmetic may overflow." + ); + TopOffset = sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (*ResourceDirEntry) * + ((UINT32) ResourceDir->NumberOfNamedEntries + ResourceDir->NumberOfIdEntries); + if (TopOffset > ResDirTable->Size) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Try to locate the "HII" Resource entry. + // + for (Index = 0; Index < ResourceDir->NumberOfNamedEntries; ++Index) { + ResourceDirEntry = &ResourceDir->Entries[Index]; + // + // Filter entries with a non-Unicode name entry. + // + if (ResourceDirEntry->u1.s.NameIsString == 0) { + continue; + } + // + // Verify the Resource Directory String header is in bounds of the Resource + // Directory Table. + // + Overflow = BaseOverflowAddU32 ( + ResourceDirEntry->u1.s.NameOffset, + sizeof (*ResourceDirString), + &TopOffset + ); + if (Overflow || TopOffset > ResDirTable->Size) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Resource Directory String offset is sufficiently aligned. + // + Offset = ResDirTable->VirtualAddress + ResourceDirEntry->u1.s.NameOffset; + if (!IS_ALIGNED (Offset, ALIGNOF (EFI_IMAGE_RESOURCE_DIRECTORY_STRING))) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + ResourceDirString = (CONST EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (CONST VOID *) ( + (CONST CHAR8 *) Context->ImageBuffer + Offset + ); + // + // Verify the Resource Directory String is in bounds of the Resource + // Directory Table. + // + Overflow = BaseOverflowAddU32 ( + TopOffset, + (UINT32) ResourceDirString->Length * sizeof (CHAR16), + &TopOffset + ); + if (Overflow || TopOffset > ResDirTable->Size) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the type name matches "HII". + // + if (ResourceDirString->Length == 3 + && ResourceDirString->String[0] == L'H' + && ResourceDirString->String[1] == L'I' + && ResourceDirString->String[2] == L'I') { + break; + } + } + // + // Verify the "HII" Type Resource Directory Entry exists. + // + if (Index == ResourceDir->NumberOfNamedEntries) { + return RETURN_NOT_FOUND; + } + // + // Walk down the conventional "Name" and "Language" levels to reach the + // data directory. + // + for (ResourceLevel = 0; ResourceLevel < 2; ++ResourceLevel) { + // + // Succeed early if one of the levels is omitted. + // + if (ResourceDirEntry->u2.s.DataIsDirectory == 0) { + break; + } + // + // Verify the Resource Directory Table fits at least the Resource Directory + // with and one Relocation Directory Entry. + // + if (ResourceDirEntry->u2.s.OffsetToDirectory > ResDirTable->Size - sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (*ResourceDir->Entries)) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the next Relocation Directory offset is sufficiently aligned. + // + Offset = ResDirTable->VirtualAddress + ResourceDirEntry->u2.s.OffsetToDirectory; + if (!IS_ALIGNED (Offset, ALIGNOF (EFI_IMAGE_RESOURCE_DIRECTORY))) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Resource Directory has at least one entry. + // + ResourceDir = (CONST EFI_IMAGE_RESOURCE_DIRECTORY *) (CONST VOID *) ( + (CONST CHAR8 *) Context->ImageBuffer + Offset + ); + if ((UINT32) ResourceDir->NumberOfIdEntries + ResourceDir->NumberOfNamedEntries == 0) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Always take the first entry for simplicity. + // + ResourceDirEntry = &ResourceDir->Entries[0]; + } + // + // Verify the final Resource Directory Entry is of a data type. + // + if (ResourceDirEntry->u2.s.DataIsDirectory != 0) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Resource Directory Table fits at least the Resource Directory. + // + STATIC_ASSERT ( + sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY) <= sizeof (EFI_IMAGE_RESOURCE_DIRECTORY), + "The following arithmetic may overflow." + ); + if (ResourceDirEntry->u2.OffsetToData > ResDirTable->Size - sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY)) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Relocation Directory Entry offset is sufficiently aligned. + // + Offset = ResDirTable->VirtualAddress + ResourceDirEntry->u2.OffsetToData; + if (!IS_ALIGNED (Offset, ALIGNOF (EFI_IMAGE_RESOURCE_DATA_ENTRY))) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + ResourceDataEntry = (CONST EFI_IMAGE_RESOURCE_DATA_ENTRY *) (CONST VOID *) ( + (CONST CHAR8 *) Context->ImageBuffer + Offset + ); + // + // Verify the "HII" data is in bounds of the Image buffer. + // + Overflow = BaseOverflowAddU32 ( + ResourceDataEntry->OffsetToData, + ResourceDataEntry->Size, + &HiiRvaEnd + ); + if (Overflow || HiiRvaEnd > Context->SizeOfImage) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + *HiiRva = ResourceDataEntry->OffsetToData; + *HiiSize = ResourceDataEntry->Size; + + return RETURN_SUCCESS; +} diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c b/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c new file mode 100644 index 0000000000..38211f1c89 --- /dev/null +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c @@ -0,0 +1,152 @@ +/** @file + Implements APIs to retrieve general information about PE/COFF Images. + + Copyright (c) 2020 - 2021, Marvin Häuser. All rights reserved.
+ Copyright (c) 2020, Vitaly Cheptsov. All rights reserved.
+ Copyright (c) 2020, ISP RAS. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "BasePeCoffLib2Internals.h" + +UINT32 +PeCoffGetAddressOfEntryPoint ( + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->AddressOfEntryPoint; +} + +UINT16 +PeCoffGetMachine ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->Machine; +} + +UINT16 +PeCoffGetSubsystem ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->Subsystem; +} + +UINT32 +PeCoffGetSectionAlignment ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->SectionAlignment; +} + +UINT32 +PeCoffGetSizeOfImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->SizeOfImage; +} + +UINT32 +PeCoffGetSizeOfImageInplace ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINT32 SizeOfImage; + + ASSERT (Context != NULL); + + SizeOfImage = Context->SizeOfImage; + // + // SizeOfImage is defined with the full Image header size pre-stripping. As + // XIP TE Images always have a stripped Image header, subtract the difference. + // + if (!PcdGetBool (PcdImageLoaderProhibitTe)) { + ASSERT (Context->TeStrippedOffset < SizeOfImage); + SizeOfImage -= Context->TeStrippedOffset; + } else { + ASSERT (Context->TeStrippedOffset == 0); + } + + return SizeOfImage; +} + +UINT64 +PeCoffGetImageBase ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->ImageBase; +} + +UINT32 +PeCoffGetSizeOfHeaders ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->SizeOfHeaders; +} + +UINT16 +PeCoffGetSectionTable ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT CONST EFI_IMAGE_SECTION_HEADER **Sections + ) +{ + ASSERT (Context != NULL); + ASSERT (Sections != NULL); + + *Sections = (CONST EFI_IMAGE_SECTION_HEADER *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->SectionsOffset + ); + return Context->NumberOfSections; +} + +BOOLEAN +PeCoffGetRelocsStripped ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->RelocsStripped; +} + +// FIXME: Distinguish between base and buffer (XIP TE) +UINTN +PeCoffLoaderGetImageAddress ( + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + ASSERT (Context->ImageBuffer != NULL); + + return (UINTN) Context->ImageBuffer; +} diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c new file mode 100644 index 0000000000..11b8237599 --- /dev/null +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c @@ -0,0 +1,896 @@ +/** @file + Implements APIs to verify PE/COFF Images for further processing. + + Copyright (c) 2020 - 2021, Marvin Häuser. All rights reserved.
+ Copyright (c) 2020, Vitaly Cheptsov. All rights reserved.
+ Copyright (c) 2020, ISP RAS. All rights reserved.
+ Portions copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+ Portions copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include "BasePeCoffLib2Internals.h" + +// +// FIXME: Provide an API to destruct the context? +// + +/** + Verify the Image section Headers and initialise the Image memory space size. + + The first Image section must be the beginning of the memory space, or be + contiguous to the aligned Image Headers. + Sections must be disjoint and, depending on the policy, contiguous in the + memory space space. + The section data must be in bounds bounds of the file buffer. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + @param[in] FileSize The size, in Bytes, of Context->FileBuffer. + @param[out] StartAddress On output, the RVA of the first Image section. + + @retval RETURN_SUCCESS The Image section Headers are well-formed. + @retval other The Image section Headers are malformed. +**/ +STATIC +RETURN_STATUS +InternalVerifySections ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN UINT32 FileSize, + OUT UINT32 *StartAddress + ) +{ + BOOLEAN Overflow; + UINT32 NextSectRva; + UINT32 SectRawEnd; + UINT32 EffectiveSectRawEnd; + UINT16 SectionIndex; + CONST EFI_IMAGE_SECTION_HEADER *Sections; + + ASSERT (Context != NULL); + ASSERT (Context->TeStrippedOffset <= Context->SizeOfHeaders); + ASSERT (IS_POW2 (Context->SectionAlignment)); + ASSERT (StartAddress != NULL); + // + // Images without Sections have no usable data, disallow them. + // + if (Context->NumberOfSections == 0) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + Sections = (CONST EFI_IMAGE_SECTION_HEADER *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->SectionsOffset + ); + // + // The first Image section must begin the Image memory space, or it must be + // adjacent to the Image Headers. + // + if (Sections[0].VirtualAddress == 0) { + // FIXME: Add PCD to disallow. + // + // TE Images cannot support loading the Image Headers as part of the first + // Image section due to its StrippedSize sematics. + // + if (!PcdGetBool (PcdImageLoaderProhibitTe)) { + if (Context->ImageType == PeCoffLoaderTypeTe) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } else { + ASSERT (Context->ImageType != PeCoffLoaderTypeTe); + } + + NextSectRva = 0; + } else { + // + // Choose the raw or aligned Image Headers size depending on whether loading + // unaligned Sections is allowed. + // + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_CONTIGUOUS_SECTIONS) == 0) { + Overflow = BaseOverflowAlignUpU32 ( + Context->SizeOfHeaders, + Context->SectionAlignment, + &NextSectRva + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } else { + NextSectRva = Context->SizeOfHeaders; + } + } + + *StartAddress = NextSectRva; + // + // Verify all Image sections are valid. + // + for (SectionIndex = 0; SectionIndex < Context->NumberOfSections; ++SectionIndex) { + // + // Verify the Image section adheres to the W^X principle, if the policy + // demands it. + // + if (PcdGetBool (PcdImageLoaderWXorX)) { + if ((Sections[SectionIndex].Characteristics & (EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_MEM_WRITE)) == (EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_MEM_WRITE)) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } + // + // Verify the Image sections are disjoint (relaxed) or adjacent (strict) + // depending on whether unaligned Image sections may be loaded or not. + // Unaligned Image sections have been observed with iPXE Option ROMs and old + // Apple Mac OS X bootloaders. + // + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_CONTIGUOUS_SECTIONS) == 0) { + if (Sections[SectionIndex].VirtualAddress != NextSectRva) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } else { + if (Sections[SectionIndex].VirtualAddress < NextSectRva) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // If the Image section address is not aligned by the Image section + // alignment, fall back to important architecture-specific page sizes if + // possible, to ensure the Image can have memory protection applied. + // Otherwise, report no alignment for the Image. + // + if (!IS_ALIGNED (Sections[SectionIndex].VirtualAddress, Context->SectionAlignment)) { + STATIC_ASSERT ( + DEFAULT_PAGE_ALLOCATION_GRANULARITY <= RUNTIME_PAGE_ALLOCATION_GRANULARITY, + "This code must be adapted to consider the reversed order." + ); + + if (IS_ALIGNED (Sections[SectionIndex].VirtualAddress, RUNTIME_PAGE_ALLOCATION_GRANULARITY)) { + Context->SectionAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; + } else if (DEFAULT_PAGE_ALLOCATION_GRANULARITY < RUNTIME_PAGE_ALLOCATION_GRANULARITY + && IS_ALIGNED (Sections[SectionIndex].VirtualAddress, DEFAULT_PAGE_ALLOCATION_GRANULARITY)) { + Context->SectionAlignment = DEFAULT_PAGE_ALLOCATION_GRANULARITY; + } else { + Context->SectionAlignment = 1; + } + } + } + // + // Verify the Image sections with data are in bounds of the file buffer. + // + if (Sections[SectionIndex].SizeOfRawData > 0) { + if (!PcdGetBool (PcdImageLoaderProhibitTe)) { + if (Context->TeStrippedOffset > Sections[SectionIndex].PointerToRawData) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } else { + ASSERT (Context->TeStrippedOffset == 0); + } + + Overflow = BaseOverflowAddU32 ( + Sections[SectionIndex].PointerToRawData, + Sections[SectionIndex].SizeOfRawData, + &SectRawEnd + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + if (!PcdGetBool (PcdImageLoaderProhibitTe)) { + EffectiveSectRawEnd = SectRawEnd - Context->TeStrippedOffset; + } else { + ASSERT (Context->TeStrippedOffset == 0); + EffectiveSectRawEnd = SectRawEnd; + } + + if (EffectiveSectRawEnd > FileSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } + // + // Determine the end of the current Image section. + // + Overflow = BaseOverflowAddU32 ( + Sections[SectionIndex].VirtualAddress, + Sections[SectionIndex].VirtualSize, + &NextSectRva + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // VirtualSize does not need to be aligned, so align the result if needed. + // + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_CONTIGUOUS_SECTIONS) == 0) { + Overflow = BaseOverflowAlignUpU32 ( + NextSectRva, + Context->SectionAlignment, + &NextSectRva + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } + } + // + // Set SizeOfImage to the aligned end address of the last ImageSection. + // + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_CONTIGUOUS_SECTIONS) == 0) { + Context->SizeOfImage = NextSectRva; + } else { + // + // Because VirtualAddress is aligned by SectionAlignment for all Image + // sections, and they are disjoint and ordered by VirtualAddress, + // VirtualAddress + VirtualSize must be safe to align by SectionAlignment for + // all but the last Image section. + // Determine the strictest common alignment that the last section's end is + // safe to align to. + // + Overflow = BaseOverflowAlignUpU32 ( + NextSectRva, + Context->SectionAlignment, + &Context->SizeOfImage + ); + if (Overflow) { + Context->SectionAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; + Overflow = BaseOverflowAlignUpU32 ( + NextSectRva, + Context->SectionAlignment, + &Context->SizeOfImage + ); + if (DEFAULT_PAGE_ALLOCATION_GRANULARITY < RUNTIME_PAGE_ALLOCATION_GRANULARITY + && Overflow) { + Context->SectionAlignment = DEFAULT_PAGE_ALLOCATION_GRANULARITY; + Overflow = BaseOverflowAlignUpU32 ( + NextSectRva, + Context->SectionAlignment, + &Context->SizeOfImage + ); + } + + if (Overflow) { + Context->SectionAlignment = 1; + } + } + } + + return RETURN_SUCCESS; +} + +/** + Verify the basic Image Relocation information. + + The preferred Image load address must be aligned by the section alignment. + The Relocation Directory must be contained within the Image section memory. + The Relocation Directory must be sufficiently aligned in memory. + + @param[in] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + @param[in] StartAddress The RVA of the first Image section. + + @retval RETURN_SUCCESS The basic Image Relocation information is well-formed. + @retval other The basic Image Relocation information is malformed. +**/ +STATIC +RETURN_STATUS +InternalValidateRelocInfo ( + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN UINT32 StartAddress + ) +{ + BOOLEAN Overflow; + UINT32 SectRvaEnd; + + ASSERT (Context != NULL); + ASSERT (!Context->RelocsStripped || Context->RelocDirSize == 0); + // + // If the Base Relocations have not been stripped, verify their Directory. + // + if (Context->RelocDirSize != 0) { + // + // Verify the Relocation Directory is not empty. + // + if (sizeof (EFI_IMAGE_BASE_RELOCATION_BLOCK) > Context->RelocDirSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Relocation Directory does not overlap with the Image Headers. + // + if (StartAddress > Context->RelocDirRva) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Relocation Directory is contained in the Image memory space. + // + Overflow = BaseOverflowAddU32 ( + Context->RelocDirRva, + Context->RelocDirSize, + &SectRvaEnd + ); + if (Overflow || SectRvaEnd > Context->SizeOfImage) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Relocation Directory start is sufficiently aligned. + // + if (!IS_ALIGNED (Context->RelocDirRva, ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK))) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } + // + // Verify the preferred Image load address is sufficiently aligned. + // + // FIXME: Only with force-aligned sections? What to do with XIP? + if (!IS_ALIGNED (Context->ImageBase, (UINT64) Context->SectionAlignment)) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + return RETURN_SUCCESS; +} + +/** + Verify the TE Image and initialise Context. + + Used offsets and ranges must be aligned and in the bounds of the raw file. + Image section Headers and basic Relocation information must be well-formed. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + @param[in] FileSize The size, in Bytes, of Context->FileBuffer. + + @retval RETURN_SUCCESS The TE Image is well-formed. + @retval other The TE Image is malformed. +**/ +STATIC +RETURN_STATUS +InternalInitializeTe ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN UINT32 FileSize + ) +{ + RETURN_STATUS Status; + BOOLEAN Overflow; + CONST EFI_TE_IMAGE_HEADER *TeHdr; + UINT32 StartAddress; + + ASSERT (Context != NULL); + ASSERT (Context->ExeHdrOffset == 0); + ASSERT (sizeof (EFI_TE_IMAGE_HEADER) <= FileSize); + + if (PcdGetBool (PcdImageLoaderProhibitTe)) { + ASSERT (FALSE); + return RETURN_UNSUPPORTED; + } + + TeHdr = (CONST EFI_TE_IMAGE_HEADER *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + ); + + Context->ImageType = PeCoffLoaderTypeTe; + // + // Calculate the size, in Bytes, stripped from the Image Headers. + // + Overflow = BaseOverflowSubU16 ( + TeHdr->StrippedSize, + sizeof (*TeHdr), + &Context->TeStrippedOffset + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + STATIC_ASSERT ( + MAX_UINT8 * sizeof (EFI_IMAGE_SECTION_HEADER) <= MAX_UINT32 - MAX_UINT16, + "The following arithmetic may overflow." + ); + // + // Calculate SizeOfHeaders in a way that is equivalent to what the size would + // be if this was the original (unstripped) PE32 binary. As the TE image + // creation doesn't fix fields up, values work the same way as for PE32. + // When referencing raw data however, the TE stripped size must be subracted. + // + Context->SizeOfHeaders = (UINT32) TeHdr->StrippedSize + (UINT32) TeHdr->NumberOfSections * sizeof (EFI_IMAGE_SECTION_HEADER); + // + // Verify that the Image Headers are in bounds of the file buffer. + // + if (Context->SizeOfHeaders - Context->TeStrippedOffset > FileSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + STATIC_ASSERT ( + IS_ALIGNED (sizeof (*TeHdr), ALIGNOF (EFI_IMAGE_SECTION_HEADER)), + "The Image section alignment requirements are violated." + ); + // + // TE Image sections start right after the Image Headers. + // + Context->SectionsOffset = sizeof (EFI_TE_IMAGE_HEADER); + // + // TE Images do not store their section alignment. Assume the UEFI Page size + // by default, as it is the minimum to guarantee memory permission support. + // + Context->SectionAlignment = EFI_PAGE_SIZE; + Context->NumberOfSections = TeHdr->NumberOfSections; + // + // Validate the sections. + // TE images do not have a field to explicitly describe the image size. + // Set it to the top of the Image's memory space. + // + Status = InternalVerifySections ( + Context, + FileSize, + &StartAddress + ); + if (Status != RETURN_SUCCESS) { + DEBUG_RAISE (); + return Status; + } + // + // Verify the Image entry point is in bounds of the Image buffer. + // + if (TeHdr->AddressOfEntryPoint >= Context->SizeOfImage) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + Context->Machine = TeHdr->Machine; + Context->Subsystem = TeHdr->Subsystem; + Context->ImageBase = TeHdr->ImageBase; + Context->AddressOfEntryPoint = TeHdr->AddressOfEntryPoint; + Context->RelocDirRva = TeHdr->DataDirectory[0].VirtualAddress; + Context->RelocDirSize = TeHdr->DataDirectory[0].Size; + // + // TE Images do not explicitly store whether their Relocations have been + // stripped. Relocations have been stripped if and only if both the RVA and + // size of the Relocation Directory are zero. + // + Context->RelocsStripped = TeHdr->DataDirectory[0].VirtualAddress == 0 && TeHdr->DataDirectory[0].Size == 0; + // + // Verify basic sanity of the Relocation Directory. + // + return InternalValidateRelocInfo (Context, StartAddress); +} + +/** + Verify the PE32 or PE32+ Image and initialise Context. + + Used offsets and ranges must be aligned and in the bounds of the raw file. + Image section Headers and basic Relocation information must be Well-formed. + + @param[in,out] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + @param[in] FileSize The size, in Bytes, of Context->FileBuffer. + + @retval RETURN_SUCCESS The PE Image is Well-formed. + @retval other The PE Image is malformed. +**/ +STATIC +RETURN_STATUS +InternalInitializePe ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN UINT32 FileSize + ) +{ + BOOLEAN Overflow; + CONST EFI_IMAGE_NT_HEADERS_COMMON_HDR *PeCommon; + CONST EFI_IMAGE_NT_HEADERS32 *Pe32; + CONST EFI_IMAGE_NT_HEADERS64 *Pe32Plus; + CONST CHAR8 *OptHdrPtr; + UINT32 HdrSizeWithoutDataDir; + UINT32 MinSizeOfOptionalHeader; + UINT32 MinSizeOfHeaders; + CONST EFI_IMAGE_DATA_DIRECTORY *RelocDir; + CONST EFI_IMAGE_DATA_DIRECTORY *SecDir; + UINT32 SecDirEnd; + UINT32 NumberOfRvaAndSizes; + RETURN_STATUS Status; + UINT32 StartAddress; + + ASSERT (Context != NULL); + ASSERT (sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR) + sizeof (UINT16) <= FileSize - Context->ExeHdrOffset); + if (!PcdGetBool (PcdImageLoaderAllowMisalignedOffset)) { + ASSERT (IS_ALIGNED (Context->ExeHdrOffset, ALIGNOF (EFI_IMAGE_NT_HEADERS_COMMON_HDR))); + } + // + // Locate the PE Optional Header. + // + OptHdrPtr = (CONST CHAR8 *) Context->FileBuffer + Context->ExeHdrOffset; + OptHdrPtr += sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR); + + STATIC_ASSERT ( + IS_ALIGNED (ALIGNOF (EFI_IMAGE_NT_HEADERS_COMMON_HDR), ALIGNOF (UINT16)) + && IS_ALIGNED (sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR), ALIGNOF (UINT16)), + "The following operation might be an unaligned access." + ); + // + // Determine the type of and retrieve data from the PE Optional Header. + // Do not retrieve SizeOfImage as the value usually does not follow the + // specification. Even if the value is large enough to hold the last Image + // section, it may not be aligned, or it may be too large. No data can + // possibly be loaded past the last Image section anyway. + // + switch (*(CONST UINT16 *) (CONST VOID *) OptHdrPtr) { + case EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC: + // + // Verify the PE32 header is in bounds of the file buffer. + // + if (sizeof (*Pe32) > FileSize - Context->ExeHdrOffset) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // The PE32 header offset is always sufficiently aligned. + // + STATIC_ASSERT ( + ALIGNOF (EFI_IMAGE_NT_HEADERS32) <= ALIGNOF (EFI_IMAGE_NT_HEADERS_COMMON_HDR), + "The following operations may be unaligned." + ); + // + // Populate the common data with information from the Optional Header. + // + Pe32 = (CONST EFI_IMAGE_NT_HEADERS32 *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->ExeHdrOffset + ); + + Context->ImageType = PeCoffLoaderTypePe32; + Context->Subsystem = Pe32->Subsystem; + Context->SizeOfHeaders = Pe32->SizeOfHeaders; + Context->ImageBase = Pe32->ImageBase; + Context->AddressOfEntryPoint = Pe32->AddressOfEntryPoint; + Context->SectionAlignment = Pe32->SectionAlignment; + + RelocDir = Pe32->DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC; + SecDir = Pe32->DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_SECURITY; + + PeCommon = &Pe32->CommonHeader; + NumberOfRvaAndSizes = Pe32->NumberOfRvaAndSizes; + HdrSizeWithoutDataDir = sizeof (EFI_IMAGE_NT_HEADERS32) - sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR); + + break; + + case EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC: + // + // Verify the PE32+ header is in bounds of the file buffer. + // + if (sizeof (*Pe32Plus) > FileSize - Context->ExeHdrOffset) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the PE32+ header offset is sufficiently aligned. + // + if (!PcdGetBool (PcdImageLoaderAllowMisalignedOffset) + && !IS_ALIGNED (Context->ExeHdrOffset, ALIGNOF (EFI_IMAGE_NT_HEADERS64))) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Populate the common data with information from the Optional Header. + // + Pe32Plus = (CONST EFI_IMAGE_NT_HEADERS64 *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->ExeHdrOffset + ); + + Context->ImageType = PeCoffLoaderTypePe32Plus; + Context->Subsystem = Pe32Plus->Subsystem; + Context->SizeOfHeaders = Pe32Plus->SizeOfHeaders; + Context->ImageBase = Pe32Plus->ImageBase; + Context->AddressOfEntryPoint = Pe32Plus->AddressOfEntryPoint; + Context->SectionAlignment = Pe32Plus->SectionAlignment; + + RelocDir = Pe32Plus->DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC; + SecDir = Pe32Plus->DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_SECURITY; + + PeCommon = &Pe32Plus->CommonHeader; + NumberOfRvaAndSizes = Pe32Plus->NumberOfRvaAndSizes; + HdrSizeWithoutDataDir = sizeof (EFI_IMAGE_NT_HEADERS64) - sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR); + + break; + + default: + // + // Disallow Images with unknown PE Optional Header signatures. + // + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + // + // Disallow Images with unknown directories. + // + if (NumberOfRvaAndSizes > EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Image alignment is a power of 2. + // + if (!IS_POW2 (Context->SectionAlignment)) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + STATIC_ASSERT ( + sizeof (EFI_IMAGE_DATA_DIRECTORY) <= MAX_UINT32 / EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES, + "The following arithmetic may overflow." + ); + // + // Calculate the offset of the Image sections. + // + // Context->ExeHdrOffset + sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR) cannot overflow because + // * ExeFileSize > sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR) and + // * Context->ExeHdrOffset + ExeFileSize = FileSize + // + Overflow = BaseOverflowAddU32 ( + Context->ExeHdrOffset + sizeof (*PeCommon), + PeCommon->FileHeader.SizeOfOptionalHeader, + &Context->SectionsOffset + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Section Headers offset is sufficiently aligned. + // + if (!PcdGetBool (PcdImageLoaderAllowMisalignedOffset) + && !IS_ALIGNED (Context->SectionsOffset, ALIGNOF (EFI_IMAGE_SECTION_HEADER))) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // This arithmetic cannot overflow because all values are sufficiently + // bounded. + // + MinSizeOfOptionalHeader = HdrSizeWithoutDataDir + + NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY); + + ASSERT (MinSizeOfOptionalHeader >= HdrSizeWithoutDataDir); + + STATIC_ASSERT ( + sizeof (EFI_IMAGE_SECTION_HEADER) <= (MAX_UINT32 + 1ULL) / (MAX_UINT16 + 1ULL), + "The following arithmetic may overflow." + ); + // + // Calculate the minimum size of the Image Headers. + // + Overflow = BaseOverflowAddU32 ( + Context->SectionsOffset, + (UINT32) PeCommon->FileHeader.NumberOfSections * sizeof (EFI_IMAGE_SECTION_HEADER), + &MinSizeOfHeaders + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Image Header sizes are sane. SizeOfHeaders contains all header + // components (DOS, PE Common and Optional Header). + // + if (MinSizeOfOptionalHeader > PeCommon->FileHeader.SizeOfOptionalHeader) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + if (MinSizeOfHeaders > Context->SizeOfHeaders) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Image Headers are in bounds of the file buffer. + // + if (Context->SizeOfHeaders > FileSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Populate the Image context with information from the Common Header. + // + Context->NumberOfSections = PeCommon->FileHeader.NumberOfSections; + Context->Machine = PeCommon->FileHeader.Machine; + Context->RelocsStripped = + ( + PeCommon->FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED + ) != 0; + + if (EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC < NumberOfRvaAndSizes) { + Context->RelocDirRva = RelocDir->VirtualAddress; + Context->RelocDirSize = RelocDir->Size; + + if (Context->RelocsStripped && Context->RelocDirSize != 0) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } else { + ASSERT (Context->RelocDirRva == 0); + ASSERT (Context->RelocDirSize == 0); + } + + if (EFI_IMAGE_DIRECTORY_ENTRY_SECURITY < NumberOfRvaAndSizes) { + Context->SecDirOffset = SecDir->VirtualAddress; + Context->SecDirSize = SecDir->Size; + // + // Verify the Security Directory is in bounds of the Image buffer. + // + Overflow = BaseOverflowAddU32 ( + Context->SecDirOffset, + Context->SecDirSize, + &SecDirEnd + ); + if (Overflow || SecDirEnd > FileSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Security Directory is sufficiently aligned. + // + if (!IS_ALIGNED (Context->SecDirOffset, IMAGE_CERTIFICATE_ALIGN)) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Security Directory size is sufficiently aligned, and that if + // it is not empty, it can fit at least one certificate. + // + if (Context->SecDirSize != 0 + && (!IS_ALIGNED (Context->SecDirSize, IMAGE_CERTIFICATE_ALIGN) + || Context->SecDirSize < sizeof (WIN_CERTIFICATE))) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } else { + // + // The Image context is zero'd on allocation. + // + ASSERT (Context->SecDirOffset == 0); + ASSERT (Context->SecDirSize == 0); + } + + ASSERT (Context->TeStrippedOffset == 0); + // + // Verify the Image sections are Well-formed. + // + Status = InternalVerifySections ( + Context, + FileSize, + &StartAddress + ); + if (Status != RETURN_SUCCESS) { + DEBUG_RAISE (); + return Status; + } + // + // Verify the entry point is in bounds of the Image buffer. + // + if (Context->AddressOfEntryPoint >= Context->SizeOfImage) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the basic Relocation information is well-formed. + // + Status = InternalValidateRelocInfo (Context, StartAddress); + if (Status != RETURN_SUCCESS) { + DEBUG_RAISE (); + } + + return Status; +} + +RETURN_STATUS +PeCoffInitializeContext ( + OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN CONST VOID *FileBuffer, + IN UINT32 FileSize + ) +{ + RETURN_STATUS Status; + CONST EFI_IMAGE_DOS_HEADER *DosHdr; + + ASSERT (Context != NULL); + ASSERT (FileBuffer != NULL || FileSize == 0); + // + // Initialise the Image context with 0-values. + // + ZeroMem (Context, sizeof (*Context)); + + Context->FileBuffer = FileBuffer; + Context->FileSize = FileSize; + // + // Check whether the DOS Image Header is present. + // + if (sizeof (*DosHdr) <= FileSize + && *(CONST UINT16 *) (CONST VOID *) FileBuffer == EFI_IMAGE_DOS_SIGNATURE) { + DosHdr = (CONST EFI_IMAGE_DOS_HEADER *) (CONST VOID *) ( + (CONST CHAR8 *) FileBuffer + ); + // + // Verify the DOS Image Header and the Executable Header are in bounds of + // the file buffer, and that they are disjoint. + // + if (sizeof (EFI_IMAGE_DOS_HEADER) > DosHdr->e_lfanew + || DosHdr->e_lfanew > FileSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + Context->ExeHdrOffset = DosHdr->e_lfanew; + // + // Verify the Execution Header offset is sufficiently aligned. + // + if (!PcdGetBool (PcdImageLoaderAllowMisalignedOffset) + && !IS_ALIGNED (Context->ExeHdrOffset, ALIGNOF (EFI_IMAGE_NT_HEADERS_COMMON_HDR))) { + return RETURN_UNSUPPORTED; + } + } else if (!PcdGetBool (PcdImageLoaderProhibitTe)) { + // + // Assume the Image starts with the Executable Header, determine whether it + // is a TE Image. + // + if (sizeof (EFI_TE_IMAGE_HEADER) <= FileSize + && *(CONST UINT16 *) (CONST VOID *) FileBuffer == EFI_TE_IMAGE_HEADER_SIGNATURE) { + // + // Verify the TE Image Header is well-formed. + // + Status = InternalInitializeTe (Context, FileSize); + if (Status != RETURN_SUCCESS) { + DEBUG_RAISE (); + return Status; + } + + return RETURN_SUCCESS; + } + } + // + // Verify the file buffer can hold a PE Common Header. + // + if (FileSize - Context->ExeHdrOffset < sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR) + sizeof (UINT16)) { + return RETURN_UNSUPPORTED; + } + + STATIC_ASSERT ( + ALIGNOF (UINT32) <= ALIGNOF (EFI_IMAGE_NT_HEADERS_COMMON_HDR), + "The following access may be performed unaligned" + ); + // + // Verify the Image Executable Header has a PE signature. + // + if (*(CONST UINT32 *) (CONST VOID *) ((CONST CHAR8 *) FileBuffer + Context->ExeHdrOffset) != EFI_IMAGE_NT_SIGNATURE) { + return RETURN_UNSUPPORTED; + } + // + // Verify the PE Image Header is well-formed. + // + Status = InternalInitializePe (Context, FileSize); + if (Status != RETURN_SUCCESS) { + return Status; + } + + return RETURN_SUCCESS; +} diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c b/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c new file mode 100644 index 0000000000..6aa1acb38f --- /dev/null +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c @@ -0,0 +1,259 @@ +/** @file + Implements APIs to load PE/COFF Images. + + Copyright (c) 2020 - 2021, Marvin Häuser. All rights reserved.
+ Copyright (c) 2020, Vitaly Cheptsov. All rights reserved.
+ Copyright (c) 2020, ISP RAS. All rights reserved.
+ Portions copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+ Portions copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include + +#include + +#include +#include +#include +#include + +#include "BasePeCoffLib2Internals.h" + +/** + Loads the Image sections into the memory space and initialises any padding + with zeros. + + @param[in] Context The context describing the Image. Must have been + initialised by PeCoffInitializeContext(). + @param[in] LoadedHeaderSize The size, in Bytes, of the loaded Image Headers. + @param[in] DestinationSize The size, in Bytes, of Destination. Must be + sufficent to load the Image with regards to its + Image section alignment. +**/ +STATIC +VOID +InternalLoadSections ( + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN UINT32 LoadedHeaderSize, + IN UINT32 DestinationSize + ) +{ + CONST EFI_IMAGE_SECTION_HEADER *Sections; + UINT16 SectionIndex; + UINT32 EffectivePointerToRawData; + UINT32 DataSize; + UINT32 PreviousTopRva; + + Sections = (CONST EFI_IMAGE_SECTION_HEADER *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->SectionsOffset + ); + // + // As the loop zero's the data from the end of the previous section, start + // with the size of the loaded Image Headers to zero their trailing data. + // + PreviousTopRva = LoadedHeaderSize; + + for (SectionIndex = 0; SectionIndex < Context->NumberOfSections; ++SectionIndex) { + // + // Zero from the end of the previous section to the start of this section. + // + ZeroMem ( + (CHAR8 *) Context->ImageBuffer + PreviousTopRva, + Sections[SectionIndex].VirtualAddress - PreviousTopRva + ); + // + // Copy the maximum amount of data that fits both sizes. + // + if (Sections[SectionIndex].SizeOfRawData <= Sections[SectionIndex].VirtualSize) { + DataSize = Sections[SectionIndex].SizeOfRawData; + } else { + DataSize = Sections[SectionIndex].VirtualSize; + } + // + // Load the current Image section into the memory space. + // + if (!PcdGetBool (PcdImageLoaderProhibitTe)) { + EffectivePointerToRawData = Sections[SectionIndex].PointerToRawData - Context->TeStrippedOffset; + } else { + ASSERT (Context->TeStrippedOffset == 0); + EffectivePointerToRawData = Sections[SectionIndex].PointerToRawData; + } + + CopyMem ( + (CHAR8 *) Context->ImageBuffer + Sections[SectionIndex].VirtualAddress, + (CONST CHAR8 *) Context->FileBuffer + EffectivePointerToRawData, + DataSize + ); + + PreviousTopRva = Sections[SectionIndex].VirtualAddress + DataSize; + } + // + // Zero the trailing data after the last Image section. + // + ZeroMem ( + (CHAR8 *) Context->ImageBuffer + PreviousTopRva, + DestinationSize - PreviousTopRva + ); +} + +RETURN_STATUS +PeCoffLoadImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT VOID *Destination, + IN UINT32 DestinationSize + ) +{ + UINT32 LoadedHeaderSize; + CONST EFI_IMAGE_SECTION_HEADER *Sections; + + ASSERT (Context != NULL); + ASSERT (Destination != NULL); + ASSERT (ADDRESS_IS_ALIGNED (Destination, Context->SectionAlignment)); + ASSERT (Context->SizeOfImage <= DestinationSize); + + Context->ImageBuffer = Destination; + // + // Load the Image Headers into the memory space, if the policy demands it. + // + Sections = (CONST EFI_IMAGE_SECTION_HEADER *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->SectionsOffset + ); + if (PcdGetBool (PcdImageLoaderLoadHeader) && Sections[0].VirtualAddress != 0) { + LoadedHeaderSize = Context->SizeOfHeaders - Context->TeStrippedOffset; + CopyMem (Context->ImageBuffer, Context->FileBuffer, LoadedHeaderSize); + } else { + LoadedHeaderSize = 0; + } + // + // Load all Image sections into the memory space. + // + InternalLoadSections (Context, LoadedHeaderSize, DestinationSize); + + return RETURN_SUCCESS; +} + +RETURN_STATUS +PeCoffLoadImageInplaceNoBase ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINT32 NumberOfSections; + CONST EFI_IMAGE_SECTION_HEADER *Sections; + UINT32 AlignedSize; + UINT16 SectionIndex; + CHAR8 *ImageBuffer; + + ASSERT (Context != NULL); + + NumberOfSections = PeCoffGetSectionTable (Context, &Sections); + // + // Verify all RVAs and raw file offsets are identical for XIP Images. + // + for (SectionIndex = 0; SectionIndex < NumberOfSections; ++SectionIndex) { + AlignedSize = ALIGN_VALUE ( + Sections[SectionIndex].VirtualSize, + Context->SectionAlignment + ); + if (Sections[SectionIndex].PointerToRawData != Sections[SectionIndex].VirtualAddress + || Sections[SectionIndex].SizeOfRawData != AlignedSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } + + ImageBuffer = (CHAR8 *) Context->FileBuffer; + if (!PcdGetBool (PcdImageLoaderProhibitTe)) { + // FIXME: Abstract all accesses to ImageBuffer for safety? + // + // TE XIP Images are padded to be aligned such that their Image sections + // are correctly aligned. ImageBuffer is used exclusively to accesses RVAs, + // which for TE XIP Images are always off by Context->TeStrippedOffset. + // There is no other way but to treat the data in front of the TE Image + // Header as a part of the TE Image Header. + // + ImageBuffer -= Context->TeStrippedOffset; + } else { + ASSERT (Context->ImageType != PeCoffLoaderTypeTe); + } + + Context->ImageBuffer = ImageBuffer; + + return RETURN_SUCCESS; +} + +BOOLEAN +PeCoffImageIsInplace ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINT64 ImageBase; + + ASSERT (Context != NULL); + + ImageBase = PeCoffGetImageBase (Context); + + if (!PcdGetBool (PcdImageLoaderProhibitTe)) { + ImageBase += Context->TeStrippedOffset; + } else { + ASSERT (Context->TeStrippedOffset == 0); + } + // + // Verify the Image is located at its preferred load address. + // + return ImageBase == (UINTN) Context->FileBuffer; +} + +RETURN_STATUS +PeCoffLoadImageInplace ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + BOOLEAN Result; + + ASSERT (Context != NULL); + + Result = PeCoffImageIsInplace (Context); + if (!Result) { + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + + return PeCoffLoadImageInplaceNoBase (Context); +} + +// +// FIXME: Provide a runtime version of this API as well. +// +VOID +PeCoffDiscardSections ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + CONST EFI_IMAGE_SECTION_HEADER *Sections; + UINT32 SectionIndex; + + ASSERT (Context != NULL); + // + // By the PE/COFF specification, the .reloc section is supposed to be + // discardable, so we must assume it is no longer valid. + // + Context->RelocDirRva = 0; + Context->RelocDirSize = 0; + // + // Zero all Image sections that are flagged as discardable. + // + Sections = (CONST EFI_IMAGE_SECTION_HEADER *) (CONST VOID *) ( + (CONST CHAR8 *) Context->FileBuffer + Context->SectionsOffset + ); + for (SectionIndex = 0; SectionIndex < Context->NumberOfSections; ++SectionIndex) { + if ((Sections[SectionIndex].Characteristics & EFI_IMAGE_SCN_MEM_DISCARDABLE) != 0) { + ZeroMem ( + (CHAR8 *) Context->ImageBuffer + Sections[SectionIndex].VirtualAddress, + Sections[SectionIndex].VirtualSize + ); + } + } +} diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffRelocate.c b/MdePkg/Library/BasePeCoffLib2/PeCoffRelocate.c new file mode 100644 index 0000000000..78527b0ac3 --- /dev/null +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffRelocate.c @@ -0,0 +1,938 @@ +/** @file + Implements APIs to relocate PE/COFF Images. + + Copyright (c) 2020 - 2021, Marvin Häuser. All rights reserved.
+ Copyright (c) 2020, Vitaly Cheptsov. All rights reserved.
+ Copyright (c) 2020, ISP RAS. All rights reserved.
+ Portions copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+ Portions copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "BasePeCoffLib2Internals.h" + +struct PE_COFF_LOADER_RUNTIME_CONTEXT_ { + /// + /// The RVA of the Relocation Directory. + /// + UINT32 RelocDirRva; + /// + /// The size, in Bytes, of the Relocation Directory. + /// + UINT32 RelocDirSize; + /// + /// Information bookkept during the initial Image relocation. + /// + UINT64 FixupData[]; +}; + +// FIXME: Add RISC-V support. +/** + Returns whether the Base Relocation type is supported by this loader. + + @param[in] Type The type of the Base Relocation. +**/ +#define IMAGE_RELOC_TYPE_SUPPORTED(Type) \ + (((Type) == EFI_IMAGE_REL_BASED_ABSOLUTE) || \ + ((Type) == EFI_IMAGE_REL_BASED_HIGHLOW) || \ + ((Type) == EFI_IMAGE_REL_BASED_DIR64) || \ + ((PcdGet32 (PcdImageLoaderRelocTypePolicy) & PCD_RELOC_TYPE_POLICY_ARM) != 0 && (Type) == EFI_IMAGE_REL_BASED_ARM_MOV32T)) + +/** + Returns whether the Base Relocation is supported by this loader. + + @param[in] Relocation The composite Base Relocation value. +**/ +#define IMAGE_RELOC_SUPPORTED(Relocation) \ + IMAGE_RELOC_TYPE_SUPPORTED (IMAGE_RELOC_TYPE (Reloc)) + +/** + Retrieve the immediate data encoded in an ARM MOVT or MOVW immediate + instruciton. + + @param[in] Instruction Pointer to an ARM MOVT or MOVW immediate instruction. + + @returns The Immediate address encoded in the instruction. +**/ +STATIC +UINT16 +ThumbMovtImmediateAddress ( + IN CONST VOID *Instruction + ) +{ + UINT32 Movt; + UINT16 Movt1; + UINT16 Movt2; + UINT16 Address; + // + // Thumb2 is two separate 16-bit instructions working together, e.g. + // MOVT R0, #0 is 0x0000f2c0 or 0xf2c0 0x0000 + // + Movt1 = *(CONST UINT16 *) (CONST VOID *) Instruction; + Movt2 = *(CONST UINT16 *) (CONST VOID *) ((CONST CHAR8 *) Instruction + sizeof (UINT16)); + Movt = ((UINT32) Movt1 << 16U) | (UINT32) Movt2; + // + // imm16 = imm4:i:imm3:imm8 + // imm4 -> Bit19:Bit16 + // i -> Bit26 + // imm3 -> Bit14:Bit12 + // imm8 -> Bit7:Bit0 + // + Address = (UINT16) (Movt & 0x000000FFU); // imm8 + Address |= (UINT16) ((Movt >> 4U) & 0x0000F700U); // imm4 imm3 + Address |= (UINT16) ((Movt & BIT26) >> 15U); // i, Bit26->11 + + return Address; +} + +/** + Update an ARM MOVT or MOVW immediate instruction immediate data. + + @param[in,out] Instruction Pointer to an ARM MOVT or MOVW immediate + instruction. + @param[in] Address New address to patch into the instruction. +**/ +STATIC +VOID +ThumbMovtImmediatePatch ( + IN OUT VOID *Instruction, + IN UINT16 Address + ) +{ + UINT16 Patch; + UINT16 PatchedInstruction; + // + // First 16-bit chunk of instruction. + // + Patch = (Address & 0xF000U) >> 12U; // imm4 + Patch |= (Address & BIT11) >> 1U; // i, Bit11->10 + // + // Mask out instruction bits and or in address. + // + PatchedInstruction = *(CONST UINT16 *) (CONST VOID *) Instruction; + *(UINT16 *) (VOID *) Instruction = (PatchedInstruction & ~(UINT16) 0x040FU) | Patch; + // + // Second 16-bit chunk of instruction. + // + Patch = Address & 0x000000FFU; // imm8 + Patch |= ((UINT32) Address << 4U) & 0x00007000U; // imm3 + // + // Mask out instruction bits and or in address. + // + PatchedInstruction = *(CONST UINT16 *) (CONST VOID *) ((CHAR8 *) Instruction + sizeof (UINT16)); + *(UINT16 *) (VOID *) ((CHAR8 *) Instruction + sizeof (UINT16)) = + (PatchedInstruction & ~(UINT16) 0x70FFU) | Patch; +} + +UINT32 +PeCoffThumbMovwMovtImmediateAddress ( + IN CONST VOID *Instructions + ) +{ + CONST CHAR8 *Word; + CONST CHAR8 *Top; + // + // Calculate the encoded address of the instruction pair. + // + Word = Instructions; // MOVW + Top = (CONST CHAR8 *) Instructions + 2 * sizeof (UINT16); // MOVT + + return (UINT32) (((UINT32) ThumbMovtImmediateAddress (Top) << 16U) | ThumbMovtImmediateAddress (Word)); +} + +/** + Update an ARM MOVW/MOVT immediate instruction instruction pair. + + @param[in,out] Instructions Pointer to ARM MOVW/MOVT instruction pair. + @param[in] Address New address to patch into the instructions. +**/ +STATIC +VOID +ThumbMovwMovtImmediatePatch ( + IN OUT VOID *Instructions, + IN UINT32 Address + ) +{ + CHAR8 *Word; + CHAR8 *Top; + // + // Patch the instruction pair's encoded address. + // + Word = Instructions; // MOVW + Top = (CHAR8 *) Instructions + 2 * sizeof (UINT16); // MOVT + + ThumbMovtImmediatePatch (Word, (UINT16) (Address & 0x0000FFFFU)); + ThumbMovtImmediatePatch (Top, (UINT16) ((Address & 0xFFFF0000U) >> 16U)); +} + +/** + Relocate an ARM MOVW/MOVT immediate instruction instruction pair. + + @param[in,out] Instructions Pointer to ARM MOVW/MOVT instruction pair. + @param[in] Adjust The delta to add to the addresses. +**/ +VOID +PeCoffThumbMovwMovtImmediateFixup ( + IN OUT VOID *Instructions, + IN UINT64 Adjust + ) +{ + UINT32 Fixup32; + // + // Relocate the instruction pair. + // + Fixup32 = PeCoffThumbMovwMovtImmediateAddress (Instructions) + (UINT32) Adjust; + ThumbMovwMovtImmediatePatch (Instructions, Fixup32); +} + +/** + Apply an Image Base Relocation. + + Only a subset of the PE/COFF Base Relocation types are permited. + The Base Relocation target must be in bounds, aligned, and must not overlap + with the Relocation Directory. + + @param[in] Context The context describing the Image. Must have been + loaded by PeCoffLoadImage(). + @param[in] RelocBlock The Base Relocation Block to apply from. + @param[in] RelocIndex The index of the Base Relocation to apply. + @param[in] Adjust The delta to add to the addresses. + @param[out] FixupData On input, a pointer to a bookkeeping value or NULL. + On output, a value to preserve for Image runtime + relocation. + + @retval RETURN_SUCCESS The Base Relocation has been applied successfully. + @retval other The Base Relocation could not be applied successfully. +**/ +STATIC +RETURN_STATUS +InternalApplyRelocation ( + IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN CONST EFI_IMAGE_BASE_RELOCATION_BLOCK *RelocBlock, + IN UINT32 RelocIndex, + IN UINT64 Adjust, + OUT UINT64 *FixupData OPTIONAL + ) +{ + BOOLEAN Overflow; + + UINT16 RelocType; + UINT16 RelocOffset; + UINT32 RelocTargetRva; + UINT32 RemRelocTargetSize; + + CHAR8 *Fixup; + UINT32 Fixup32; + UINT64 Fixup64; + + RelocType = IMAGE_RELOC_TYPE (RelocBlock->Relocations[RelocIndex]); + RelocOffset = IMAGE_RELOC_OFFSET (RelocBlock->Relocations[RelocIndex]); + // + // Absolute Base Relocations are used for padding any must be skipped. + // + if (RelocType == EFI_IMAGE_REL_BASED_ABSOLUTE) { + if (FixupData != NULL) { + FixupData[RelocIndex] = 0; + } + + return RETURN_SUCCESS; + } + // + // Verify the Base Relocation target address is in bounds of the Image buffer. + // + Overflow = BaseOverflowAddU32 ( + RelocBlock->VirtualAddress, + RelocOffset, + &RelocTargetRva + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + Overflow = BaseOverflowSubU32 ( + Context->SizeOfImage, + RelocTargetRva, + &RemRelocTargetSize + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + Fixup = (CHAR8 *) Context->ImageBuffer + RelocTargetRva; + // + // Apply the Base Relocation fixup per type. + // If RuntimeContext is not NULL, store the current value of the fixup + // target to determine whether it has been changed during runtime + // execution. + // + // It is not clear how EFI_IMAGE_REL_BASED_HIGH and + // EFI_IMAGE_REL_BASED_LOW are supposed to be handled. While the PE + // specification suggests to just add the high or low part of the + // displacement, there are concerns about how it's supposed to deal with + // wraparounds. As they are virtually non-existent, they are unsupported for + // the time being. + // + switch (RelocType) { + case EFI_IMAGE_REL_BASED_HIGHLOW: + // + // Verify the Base Relocation target is in bounds of the Image buffer. + // + if (sizeof (UINT32) > RemRelocTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Image Base Relocation does not target the Image Relocation + // Directory. + // + if (RelocTargetRva + sizeof (UINT32) > Context->RelocDirRva + && Context->RelocDirRva + Context->RelocDirSize > RelocTargetRva) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Relocate the target instruction. + // + Fixup32 = ReadUnaligned32 ((CONST VOID *) Fixup); + Fixup32 += (UINT32) Adjust; + WriteUnaligned32 ((VOID *) Fixup, Fixup32); + // + // Record the relocated value for Image runtime relocation. + // + if (FixupData != NULL) { + FixupData[RelocIndex] = Fixup32; + } + + break; + + case EFI_IMAGE_REL_BASED_DIR64: + // + // Verify the Image Base Relocation target is in bounds of the Image + // buffer. + // + if (sizeof (UINT64) > RemRelocTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Image Base Relocation does not target the Image Relocation + // Directory. + // + if (RelocTargetRva + sizeof (UINT64) > Context->RelocDirRva + && Context->RelocDirRva + Context->RelocDirSize > RelocTargetRva) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Relocate target the instruction. + // + Fixup64 = ReadUnaligned64 ((CONST VOID *) Fixup); + Fixup64 += Adjust; + WriteUnaligned64 ((VOID *) Fixup, Fixup64); + // + // Record the relocated value for Image runtime relocation. + // + if (FixupData != NULL) { + FixupData[RelocIndex] = Fixup64; + } + + break; + + case EFI_IMAGE_REL_BASED_ARM_MOV32T: + // + // Verify ARM Thumb mode Base Relocations are supported. + // + if ((PcdGet32 (PcdImageLoaderRelocTypePolicy) & PCD_RELOC_TYPE_POLICY_ARM) == 0) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Base Relocation target is in bounds of the Image buffer. + // + if (sizeof (UINT64) > RemRelocTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Base Relocation target is sufficiently aligned. + // The ARM Thumb instruction pair must start on a 16-bit boundary. + // + if (!IS_ALIGNED (RelocTargetRva, ALIGNOF (UINT16))) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Base Relocation does not target the Relocation Directory. + // + if (RelocTargetRva + sizeof (UINT64) > Context->RelocDirRva + && Context->RelocDirRva + Context->RelocDirSize > RelocTargetRva) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Relocate the target instruction. + // + PeCoffThumbMovwMovtImmediateFixup (Fixup, Adjust); + // + // Record the relocated value for Image runtime relocation. + // + if (FixupData != NULL) { + FixupData[RelocIndex] = ReadUnaligned64 ((CONST VOID *) Fixup); + } + + break; + + default: + // + // The Image Base Relocation type is unknown, disallow the Image. + // + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + + return RETURN_SUCCESS; +} + +RETURN_STATUS +PeCoffRelocateImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN UINT64 BaseAddress, + OUT PE_COFF_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize + ) +{ + RETURN_STATUS Status; + BOOLEAN Overflow; + + UINT64 Adjust; + + UINT32 RelocBlockOffsetMax; + UINT32 TopOfRelocDir; + + UINT32 RelocBlockOffset; + CONST EFI_IMAGE_BASE_RELOCATION_BLOCK *RelocBlock; + UINT32 RelocBlockSize; + UINT32 SizeOfRelocs; + UINT32 NumRelocs; + UINT32 RelocIndex; + UINT32 FixupDataIndex; + UINT64 *CurrentFixupData; + + ASSERT (Context != NULL); + ASSERT (!Context->RelocsStripped || BaseAddress == Context->ImageBase); + ASSERT (RuntimeContext != NULL || RuntimeContextSize == 0); + ASSERT (RuntimeContext == NULL || RuntimeContextSize >= sizeof (PE_COFF_LOADER_RUNTIME_CONTEXT) + Context->RelocDirSize * (sizeof (UINT64) / sizeof (UINT16))); + // + // Initialise the Image runtime context header. + // + if (RuntimeContext != NULL) { + RuntimeContext->RelocDirRva = Context->RelocDirRva; + RuntimeContext->RelocDirSize = Context->RelocDirSize; + } + // + // Verify the Relocation Directory is not empty. + // + if (Context->RelocDirSize == 0) { + return RETURN_SUCCESS; + } + // + // Calculate the Image displacement from its prefered load address. + // + Adjust = BaseAddress - Context->ImageBase; + // + // Runtime drivers should unconditionally go through the full Relocation + // procedure early to eliminate the possibility of errors later at runtime. + // Runtime drivers don't have their Base Relocations stripped, this is + // verified during context creation. + // Skip explicit Relocation when the Image is already loaded at its + // prefered location. + // + if (RuntimeContext == NULL && Adjust == 0) { + return RETURN_SUCCESS; + } + + RelocBlockOffset = Context->RelocDirRva; + TopOfRelocDir = Context->RelocDirRva + Context->RelocDirSize; + RelocBlockOffsetMax = TopOfRelocDir - sizeof (EFI_IMAGE_BASE_RELOCATION_BLOCK); + FixupDataIndex = 0; + // + // Align TopOfRelocDir because, if the policy does not demand Relocation Block + // sizes to be aligned, the code below will manually align them. Thus, the + // end offset of the last Relocation Block must be compared to a manually + // aligned Relocation Directoriy end offset. + // + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_RELOCATION_BLOCK_SIZES) != 0) { + Overflow = BaseOverflowAlignUpU32 ( + TopOfRelocDir, + ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK), + &TopOfRelocDir + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } + // + // Apply all Base Relocations of the Image. + // + while (RelocBlockOffset <= RelocBlockOffsetMax) { + RelocBlock = (CONST EFI_IMAGE_BASE_RELOCATION_BLOCK *) (CONST VOID *) ( + (CONST CHAR8 *) Context->ImageBuffer + RelocBlockOffset + ); + // + // Verify the Base Relocation Block size is well-formed. + // + Overflow = BaseOverflowSubU32 ( + RelocBlock->SizeOfBlock, + sizeof (EFI_IMAGE_BASE_RELOCATION_BLOCK), + &SizeOfRelocs + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the Base Relocation Block is in bounds of the Relocation + // Directory. + // + if (SizeOfRelocs > RelocBlockOffsetMax - RelocBlockOffset) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Advance to the next Base Relocation Block offset based on the alignment + // policy. + // + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_RELOCATION_BLOCK_SIZES) == 0) { + RelocBlockSize = RelocBlock->SizeOfBlock; + // + // Verify the next Base Relocation Block offset is sufficiently aligned. + // + if (!IS_ALIGNED (RelocBlockSize, ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK))) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } else { + // + // This arithmetic cannot overflow because we know + // 1) RelocBlock->SizeOfBlock <= RelocMax <= TopOfRelocDir + // 2) IS_ALIGNED (TopOfRelocDir, ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK)). + // + RelocBlockSize = ALIGN_VALUE ( + RelocBlock->SizeOfBlock, + ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK) + ); + } + // + // This division is safe due to the guarantee made above. + // + NumRelocs = SizeOfRelocs / sizeof (*RelocBlock->Relocations); + + if (RuntimeContext != NULL) { + CurrentFixupData = &RuntimeContext->FixupData[FixupDataIndex]; + // + // This arithmetic cannot overflow because The number of Image Base + // Relocations cannot exceed the size of their Image Relocation Block, and + // latter has been verified to be in bounds of the Image buffer. The Image + // buffer size and RelocDataIndex are both bound by MAX_UINT32. + // + FixupDataIndex += NumRelocs; + } else { + CurrentFixupData = NULL; + } + // + // Process all Base Relocations of the current Block. + // + for (RelocIndex = 0; RelocIndex < NumRelocs; ++RelocIndex) { + // + // Apply the Image Base Relocation fixup. + // If RuntimeContext is not NULL, store the current value of the fixup + // target to determine whether it has been changed during runtime + // execution. + // + // It is not clear how EFI_IMAGE_REL_BASED_HIGH and + // EFI_IMAGE_REL_BASED_LOW are supposed to be handled. While PE reference + // suggests to just add the high or low part of the displacement, there + // are concerns about how it's supposed to deal with wraparounds. + // As no known linker emits them, omit support. + // + Status = InternalApplyRelocation ( + Context, + RelocBlock, + RelocIndex, + Adjust, + CurrentFixupData + ); + if (Status != RETURN_SUCCESS) { + DEBUG_RAISE (); + return Status; + } + } + // + // This arithmetic cannot overflow because it has been checked that the + // Image Base Relocation Block is in bounds of the Image buffer. + // + RelocBlockOffset += RelocBlockSize; + } + // + // Verify the Relocation Directory size matches the contained data. + // + if (RelocBlockOffset != TopOfRelocDir) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Initialise the remaining uninitialised portion of the Image runtime + // context. + // + if (RuntimeContext != NULL) { + // + // This arithmetic cannot overflow due to the guarantee given by + // PeCoffLoaderGetRuntimeContextSize(). + // + ZeroMem ( + &RuntimeContext->FixupData[FixupDataIndex], + RuntimeContextSize - sizeof (PE_COFF_LOADER_RUNTIME_CONTEXT) - FixupDataIndex * sizeof (UINT64) + ); + } + + return RETURN_SUCCESS; +} + +/** + Apply an Image Base Relocation for Image runtime relocation. + + Well-formedness has been verified by PeCoffRelocateImage() previously. + Fails if the Relocation target value has changed since PeCoffRelocateImage(). + + @param[in] Image The Image destination memory. Must have been relocated + by PeCoffRelocateImage(). + @param[in] RelocBlock The Base Relocation Block to apply from. + @param[in] RelocIndex The index of the Base Relocation to apply. + @param[in] Adjust The delta to add to the addresses. + @param[out] FixupData The bookkeeping value. + + @retval RETURN_SUCCESS The Base Relocation has been applied successfully. + @retval other The Base Relocation could not be applied successfully. +**/ +STATIC +RETURN_STATUS +InternalApplyRelocationRuntime ( + IN OUT VOID *Fixup, + IN UINT16 RelocType, + IN UINT64 Adjust, + IN UINT64 FixupData + ) +{ + UINT32 Fixup32; + UINT64 Fixup64; + + ASSERT (Fixup != NULL); + ASSERT (IMAGE_RELOC_TYPE_SUPPORTED (RelocType) + && RelocType != EFI_IMAGE_REL_BASED_ABSOLUTE); + // + // Apply the Image Base Relocation fixup per type. + // + // If the Image relocation target value has changes since the initial + // Image relocation, skip or abort based on the policy. The fixup cannot + // be applies safely as the value might not reference an address within + // the Image memory space, e.g. when a global variable pointer to another + // variable is changed during runtime. + // + switch (RelocType) { + case EFI_IMAGE_REL_BASED_HIGHLOW: + Fixup32 = ReadUnaligned32 ((CONST VOID *) Fixup); + // + // If the Image relocation target value mismatches, skip or abort. + // + if (FixupData != Fixup32) { + if (PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) { + return RETURN_SUCCESS; + } + + return RETURN_VOLUME_CORRUPTED; + } + + Fixup32 += (UINT32) Adjust; + WriteUnaligned32 (Fixup, Fixup32); + + break; + + case EFI_IMAGE_REL_BASED_DIR64: + Fixup64 = ReadUnaligned64 (Fixup); + // + // If the Image relocation target value mismatches, skip or abort. + // + if (FixupData != Fixup64) { + if (PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) { + return RETURN_SUCCESS; + } + + return RETURN_VOLUME_CORRUPTED; + } + + Fixup64 += Adjust; + WriteUnaligned64 (Fixup, Fixup64); + + break; + + case EFI_IMAGE_REL_BASED_ARM_MOV32T: + ASSERT ((PcdGet32 (PcdImageLoaderRelocTypePolicy) & PCD_RELOC_TYPE_POLICY_ARM) != 0); + + Fixup64 = ReadUnaligned64 (Fixup); + // + // If the Image relocation target value mismatches, skip or abort. + // + if (FixupData != Fixup64) { + if (PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) { + return RETURN_SUCCESS; + } + + return RETURN_VOLUME_CORRUPTED; + } + + PeCoffThumbMovwMovtImmediateFixup (Fixup, Adjust); + + break; + + default: + // + // Invalid Base Relocation types would have caused the Image to not be + // loaded relocated successfully earlier. + // + ASSERT (FALSE); + } + + return RETURN_SUCCESS; +} + +RETURN_STATUS +PeCoffLoaderGetRuntimeContextSize ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *Size + ) +{ + BOOLEAN Overflow; + UINT32 FixupDataSize; + + ASSERT (Context != NULL); + ASSERT (!Context->RelocsStripped); + ASSERT (Size != NULL); + + // + // Because the ImageBase Relocations have not been stripped, + // PeCoffInitializeContext() has verified the Relocation Directory exists and + // is valid. + // + + // + // Request 64-bit of source value per 16-bit Base Relocation. + // This allocates too many Bytes because it assumes that every Base Relocation + // refers to a 64-bit target and does not account for Base Relocation Block + // headers. + // + Overflow = BaseOverflowMulU32 ( + Context->RelocDirSize, + sizeof (UINT64) / sizeof (UINT16), + &FixupDataSize + ); + if (Overflow) { + return RETURN_UNSUPPORTED; + } + + Overflow = BaseOverflowAddU32 ( + FixupDataSize, + sizeof (PE_COFF_LOADER_RUNTIME_CONTEXT), + Size + ); + if (Overflow) { + return RETURN_UNSUPPORTED; + } + + return RETURN_SUCCESS; +} + +RETURN_STATUS +PeCoffRuntimeRelocateImage ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN UINT64 BaseAddress, + IN CONST PE_COFF_LOADER_RUNTIME_CONTEXT *RuntimeContext + ) +{ + RETURN_STATUS Status; + + UINTN ImageAddress; + UINT32 FixupDataIndex; + CONST EFI_IMAGE_BASE_RELOCATION_BLOCK *RelocBlock; + UINT64 Adjust; + + UINT32 TopOfRelocDir; + UINT32 RelocBlockOffset; + UINT32 SizeOfRelocs; + UINT32 NumRelocs; + UINT32 RelocIndex; + UINT32 RelocTarget; + UINT32 RelocOffset; + UINT32 RelocBlockSize; + + (VOID) ImageSize; + + ASSERT (Image != NULL); + ASSERT (BaseAddress != 0); + ASSERT (RuntimeContext != NULL); + // + // If the relocation directory is empty, skip relocation. + // + if (RuntimeContext->RelocDirSize == 0) { + return RETURN_SUCCESS; + } + + // + // The arithmetics in this function generally cannot overflow due to the + // guarantees given by PeCoffRelocateImage(). + // + + ImageAddress = (UINTN) Image; + Adjust = BaseAddress - ImageAddress; + // + // If the Image remains at the current address, skip relocation. + // + if (Adjust == 0) { + return RETURN_SUCCESS; + } + // + // Apply all Base Relocations of the Image. + // + RelocBlockOffset = RuntimeContext->RelocDirRva; + TopOfRelocDir = RuntimeContext->RelocDirRva + RuntimeContext->RelocDirSize; + FixupDataIndex = 0; + while (RelocBlockOffset < TopOfRelocDir) { + ASSERT (IS_ALIGNED (RelocBlockOffset, ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK))); + + RelocBlock = (CONST EFI_IMAGE_BASE_RELOCATION_BLOCK *) (CONST VOID *) ( + (CONST CHAR8 *) Image + RelocBlockOffset + ); + + STATIC_ASSERT ( + (sizeof (UINT32) % ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK)) == 0, + "The following accesses must be performed unaligned." + ); + + ASSERT (sizeof (EFI_IMAGE_BASE_RELOCATION_BLOCK) <= RelocBlock->SizeOfBlock); + // + // Determine the number of Image Base Relocations in this Block. + // + SizeOfRelocs = RelocBlock->SizeOfBlock - sizeof (EFI_IMAGE_BASE_RELOCATION_BLOCK); + NumRelocs = SizeOfRelocs / sizeof (*RelocBlock->Relocations); + // + // Apply all Image Base Relocation fixups of the current Image Base + // Relocation Block. + // + for (RelocIndex = 0; RelocIndex < NumRelocs; ++RelocIndex) { + // + // Skip Absolute Image Base Relocations. + // + if (IMAGE_RELOC_TYPE (RelocBlock->Relocations[RelocIndex]) == EFI_IMAGE_REL_BASED_ABSOLUTE) { + ++FixupDataIndex; + continue; + } + // + // Determine the Image Base Relocation target address. + // + RelocOffset = IMAGE_RELOC_OFFSET (RelocBlock->Relocations[RelocIndex]); + ASSERT (RelocOffset <= RelocBlock->VirtualAddress + RelocOffset); + // + // Apply the Image Base Relocation fixup. + // + RelocTarget = RelocBlock->VirtualAddress + RelocOffset; + Status = InternalApplyRelocationRuntime ( + (CHAR8 *) Image + RelocTarget, + IMAGE_RELOC_TYPE (RelocBlock->Relocations[RelocIndex]), + Adjust, + RuntimeContext->FixupData[FixupDataIndex] + ); + // + // If the original Image Relocation target value mismatches the expected + // value, and the policy demands it, report an error. + // + if (!PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) { + if (Status != RETURN_SUCCESS) { + return Status; + } + } else { + ASSERT (Status == RETURN_SUCCESS); + } + + ++FixupDataIndex; + } + // + // Advance to the next Base Relocation Block based on the alignment policy. + // + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_RELOCATION_BLOCK_SIZES) == 0) { + RelocBlockSize = RelocBlock->SizeOfBlock; + ASSERT (IS_ALIGNED (RelocBlockSize, ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK))); + } else { + RelocBlockSize = ALIGN_VALUE ( + RelocBlock->SizeOfBlock, + ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK) + ); + } + + RelocBlockOffset += RelocBlockSize; + } + // + // Align TopOfRelocDir because, if the policy does not demand Relocation Block + // sizes to be aligned, the code below will manually align them. Thus, the + // end offset of the last Relocation Block must be compared to a manually + // aligned Relocation Directoriy end offset. + // + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_RELOCATION_BLOCK_SIZES) != 0) { + TopOfRelocDir = ALIGN_VALUE (TopOfRelocDir, ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK)); + } + // + // This condition is verified by PeCoffRelocateImage(). + // + ASSERT (RelocBlockOffset == TopOfRelocDir); + + return RETURN_SUCCESS; +} + +RETURN_STATUS +PeCoffRelocateImageInplace ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + RETURN_STATUS Status; + UINTN NewBase; + + Status = PeCoffLoadImageInplaceNoBase (Context); + if (RETURN_ERROR (Status)) { + DEBUG_RAISE (); + return Status; + } + + NewBase = PeCoffLoaderGetImageAddress (Context); + + Status = PeCoffRelocateImage (Context, NewBase, NULL, 0); + if (RETURN_ERROR (Status)) { + DEBUG_RAISE (); + } + + return Status; +} diff --git a/MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf b/MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf new file mode 100644 index 0000000000..125733a234 --- /dev/null +++ b/MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf @@ -0,0 +1,33 @@ +## @file +# Null PE/Coff Extra Action library instances with empty functions. +# +# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UefiImageExtraActionLibNull + MODULE_UNI_FILE = UefiImageExtraActionLibNull.uni + FILE_GUID = 0EB84DA1-267A-40b4-8347-1F48694C8B47 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiImageExtraActionLib + + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + UefiImageExtraActionLib.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + DebugLib + diff --git a/MdePkg/Library/BaseUefiImageExtraActionLibNull/UefiImageExtraActionLib.c b/MdePkg/Library/BaseUefiImageExtraActionLibNull/UefiImageExtraActionLib.c new file mode 100644 index 0000000000..d134a48810 --- /dev/null +++ b/MdePkg/Library/BaseUefiImageExtraActionLibNull/UefiImageExtraActionLib.c @@ -0,0 +1,48 @@ +/** @file + Null PE/Coff Extra Action library instances with empty functions. + + Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +/** + Performs additional actions after a PE/COFF image has been loaded and relocated. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext The pointer to the image context structure that describes the + PE/COFF image that has already been loaded and relocated. + +**/ +VOID +EFIAPI +UefiImageLoaderRelocateImageExtraAction ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + ASSERT (ImageContext != NULL); +} + +/** + Performs additional actions just before a PE/COFF image is unloaded. Any resources + that were allocated by UefiImageLoaderRelocateImageExtraAction() must be freed. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext The pointer to the image context structure that describes the + PE/COFF image that is being unloaded. + +**/ +VOID +EFIAPI +UefiImageLoaderUnloadImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + ASSERT (ImageContext != NULL); +} diff --git a/MdePkg/Library/BaseUefiImageExtraActionLibNull/UefiImageExtraActionLibNull.uni b/MdePkg/Library/BaseUefiImageExtraActionLibNull/UefiImageExtraActionLibNull.uni new file mode 100644 index 0000000000..2ed84d48b8 --- /dev/null +++ b/MdePkg/Library/BaseUefiImageExtraActionLibNull/UefiImageExtraActionLibNull.uni @@ -0,0 +1,16 @@ +// /** @file +// Null PE/Coff Extra Action library instances with empty functions. +// +// Null PE/Coff Extra Action library instances with empty functions. +// +// Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Null PE/Coff Extra Action library instances with empty functions" + +#string STR_MODULE_DESCRIPTION #language en-US "Null PE/Coff Extra Action library instances with empty functions." + diff --git a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf new file mode 100644 index 0000000000..bfe7296e0d --- /dev/null +++ b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf @@ -0,0 +1,40 @@ +## @file +# UEFI Image Loader library implementation for PE/COFF and TE Images. +# +# Copyright (c) 2021, Marvin Häuser. All rights reserved.
+# +# SPDX-License-Identifier: BSD-3-Clause +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseUefiImageLibPeCoff + FILE_GUID = 357AD87E-8D6B-468A-B3FA-0D9CC4C725CD + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiImageLib + +[Sources] + CommonSupport.c + ExecutionSupport.c + PeCoffSupport.h + PeCoffSupport.c + UefiImageLibPeCoff.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + BaseOverflowLib + BaseMemoryLib + CacheMaintenanceLib + DebugLib + MemoryAllocationLib + PeCoffLib2 + UefiImageExtraActionLib + +[FixedPcd] + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAlignmentPolicy + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderLoadHeader + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderProhibitTe diff --git a/MdePkg/Library/BaseUefiImageLib/CommonSupport.c b/MdePkg/Library/BaseUefiImageLib/CommonSupport.c new file mode 100644 index 0000000000..70a191c2af --- /dev/null +++ b/MdePkg/Library/BaseUefiImageLib/CommonSupport.c @@ -0,0 +1,152 @@ +/** @file + Support for functions common to all Image formats. + + Copyright (c) 2021, Marvin Häuser. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include +#include +#include + +#include +#include +#include + +RETURN_STATUS +UefiImageInitializeContext ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN CONST VOID *FileBuffer, + IN UINT32 FileSize + ) +{ + RETURN_STATUS Status; + + Status = UefiImageInitializeContextPreHash (Context, FileBuffer, FileSize); + if (RETURN_ERROR (Status)) { + return Status; + } + + return UefiImageInitializeContextPostHash (Context); +} + +UINTN +UefiImageLoaderGetImageEntryPoint ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINTN ImageAddress; + UINT32 EntryPointAddress; + + ASSERT (Context != NULL); + + ImageAddress = UefiImageLoaderGetImageAddress (Context); + EntryPointAddress = UefiImageGetEntryPointAddress (Context); + + return ImageAddress + EntryPointAddress; +} + +// FIXME: Some image prints use this and some don't. Is this really needed? +RETURN_STATUS +UefiImageGetModuleNameFromSymbolsPath ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CHAR8 *ModuleName, + IN UINT32 ModuleNameSize + ) +{ + RETURN_STATUS Status; + CONST CHAR8 *SymbolsPath; + UINT32 SymbolsPathSize; + UINTN Index; + UINTN StartIndex; + + ASSERT (Context != NULL); + ASSERT (ModuleName != NULL); + ASSERT (3 <= ModuleNameSize); + + Status = UefiImageGetSymbolsPath ( + Context, + &SymbolsPath, + &SymbolsPathSize + ); + if (RETURN_ERROR (Status)) { + return Status; + } + // + // Find the last component of the symbols path, which is the file containing + // the debug symbols for the Image. + // + StartIndex = 0; + for ( + Index = 0; + Index < SymbolsPathSize && SymbolsPath[Index] != '\0'; + ++Index + ) { + if (SymbolsPath[Index] == '\\' || SymbolsPath[Index] == '/') { + StartIndex = Index + 1; + } + } + // + // Extract the module name from the debug symbols file and ensure the correct + // file extensions. + // + for ( + Index = 0; + Index < MIN (ModuleNameSize, SymbolsPathSize); + ++Index + ) { + ModuleName[Index] = SymbolsPath[Index + StartIndex]; + if (ModuleName[Index] == '\0') { + ModuleName[Index] = '.'; + } + if (ModuleName[Index] == '.') { + if (Index > ModuleNameSize - 3) { + break; + } + + ModuleName[Index + 1] = 'e'; + ModuleName[Index + 2] = 'f'; + ModuleName[Index + 3] = 'i'; + Index += 4; + break; + } + } + // + // Terminate the newly created module name string. + // + ModuleName[Index] = '\0'; + + return RETURN_SUCCESS; +} + +VOID +UefiImageDebugPrintImageRecord ( + IN CONST UEFI_IMAGE_RECORD *ImageRecord + ) +{ + UINT16 SegmentIndex; + UINTN SegmentAddress; + + ASSERT (ImageRecord != NULL); + + SegmentAddress = ImageRecord->StartAddress; + for ( + SegmentIndex = 0; + SegmentIndex < ImageRecord->NumSegments; + ++SegmentIndex + ) { + DEBUG (( + DEBUG_VERBOSE, + " RecordSegment\n" + " Address - 0x%016llx\n" + " Size - 0x%08x\n" + " Attributes - 0x%08x\n", + (UINT64) SegmentAddress, + ImageRecord->Segments[SegmentIndex].Size, + ImageRecord->Segments[SegmentIndex].Attributes + )); + + SegmentAddress += ImageRecord->Segments[SegmentIndex].Size; + } +} diff --git a/MdePkg/Library/BaseUefiImageLib/ExecutionSupport.c b/MdePkg/Library/BaseUefiImageLib/ExecutionSupport.c new file mode 100644 index 0000000000..63f5b00466 --- /dev/null +++ b/MdePkg/Library/BaseUefiImageLib/ExecutionSupport.c @@ -0,0 +1,113 @@ +/** @file + Support for functions common to all Image formats. + + Copyright (c) 2021, Marvin Häuser. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include +#include +#include + +#include +#include +#include +#include + +RETURN_STATUS +UefiImageRelocateImageInplaceForExecution ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + RETURN_STATUS Status; + UINTN ImageAddress; + UINTN ImageSize; + + Status = UefiImageRelocateImageInplace (Context); + if (RETURN_ERROR (Status)) { + return Status; + } + + ImageAddress = UefiImageLoaderGetImageAddress (Context); + ImageSize = UefiImageGetImageSizeInplace (Context); + // + // Flush the instruction cache so the image data is written before + // execution. + // + InvalidateInstructionCacheRange ((VOID *) ImageAddress, ImageSize); + + return RETURN_SUCCESS; +} + +// FIXME: Check Subsystem here +RETURN_STATUS +UefiImageLoadImageForExecution ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT VOID *Destination, + IN UINT32 DestinationSize, + OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize + ) +{ + RETURN_STATUS Status; + UINTN BaseAddress; + UINTN SizeOfImage; + // + // Load the Image into the memory space. + // + Status = UefiImageLoadImage (Context, Destination, DestinationSize); + if (RETURN_ERROR (Status)) { + return Status; + } + // + // Relocate the Image to the address it has been loaded to. + // + BaseAddress = UefiImageLoaderGetImageAddress (Context); + Status = UefiImageRelocateImage ( + Context, + BaseAddress, + RuntimeContext, + RuntimeContextSize + ); + if (RETURN_ERROR (Status)) { + return Status; + } + + SizeOfImage = UefiImageGetImageSize (Context); + // + // Flush the instruction cache so the image data is written before execution. + // + InvalidateInstructionCacheRange ((VOID *) BaseAddress, SizeOfImage); + + return RETURN_SUCCESS; +} + +RETURN_STATUS +UefiImageRuntimeRelocateImageForExecution ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN UINT64 BaseAddress, + IN CONST UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext + ) +{ + RETURN_STATUS Status; + // + // Relocate the Image to the new address. + // + Status = UefiImageRuntimeRelocateImage ( + Image, + ImageSize, + BaseAddress, + RuntimeContext + ); + if (RETURN_ERROR (Status)) { + return Status; + } + // + // Flush the instruction cache so the image data is written before execution. + // + InvalidateInstructionCacheRange (Image, ImageSize); + + return RETURN_SUCCESS; +} diff --git a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c b/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c new file mode 100644 index 0000000000..678c6b2b5a --- /dev/null +++ b/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c @@ -0,0 +1,511 @@ +/** @file + UEFI Image Loader library implementation for PE/COFF and TE Images. + + Copyright (c) 2021, Marvin Häuser. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Retrieves the memory protection attributes corresponding to PE/COFF Image + section permissions. + + @param[in] Characteristics The PE/COFF Image section permissions + + @returns The memory protection attributes corresponding to the PE/COFF Image + section permissions. +**/ +STATIC +UINT32 +InternalCharacteristicsToAttributes ( + IN UINT32 Characteristics + ) +{ + UINT32 Attributes; + + Attributes = 0; + if ((Characteristics & EFI_IMAGE_SCN_MEM_READ) == 0) { + Attributes |= EFI_MEMORY_RP; + } + if ((Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) == 0) { + Attributes |= EFI_MEMORY_XP; + } + if ((Characteristics & EFI_IMAGE_SCN_MEM_WRITE) == 0) { + Attributes |= EFI_MEMORY_RO; + } + + return Attributes; +} + +/** + Index the read-only padding following an Image record section, if existent. + + @param[in,out] RecordSegment The Image record section for the current memory + protection range. May be extended if it is of + the same type as the adjacent padding. At least + one more record section must be reserved after + it in order to index the read-only padding. + @param[in] NextAddress The start address of the next memory permission + range. This may be the end address of the Image + in order to cover the Image trailer. + @param[in] EndAddress The end address of the current memory permission + range. This also denotes the start of the added + read-only padding. + @param[in] Attributes The memory protection attributes of the current + memory permission range. + + @returns The amount of Image record sections that have been appended. +**/ +STATIC +UINT8 +InternalInsertImageRecordSegmentPadding ( + IN OUT UEFI_IMAGE_RECORD_SEGMENT *RecordSegment, + IN UINT32 EndAddress, + IN UINT32 NextAddress, + IN UINT32 Attributes + ) +{ + ASSERT (RecordSegment != NULL); + ASSERT (EndAddress <= NextAddress); + + if (NextAddress == EndAddress) { + return 0; + } + // + // Add a new Image record section or expand the previous one depending on + // the the permissions of the previous Image record section. + // + if (Attributes == (EFI_MEMORY_XP | EFI_MEMORY_RO)) { + RecordSegment->Size += NextAddress - EndAddress; + + return 0; + } + + ++RecordSegment; + RecordSegment->Size = NextAddress - EndAddress; + RecordSegment->Attributes = EFI_MEMORY_XP | EFI_MEMORY_RO; + + return 1; +} + +UEFI_IMAGE_RECORD * +UefiImageLoaderGetImageRecordPeCoff ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + UEFI_IMAGE_RECORD *ImageRecord; + UINT32 MaxNumRecordSegments; + UINT32 NumRecordSegments; + UEFI_IMAGE_RECORD_SEGMENT *RecordSegment; + UINTN ImageAddress; + UINT32 SizeOfImage; + UINT32 SectionAlignment; + CONST EFI_IMAGE_SECTION_HEADER *Sections; + UINT16 NumberOfSections; + UINT16 SectionIndex; + CONST EFI_IMAGE_SECTION_HEADER *Section; + UINT32 SectionAddress; + UINT32 SectionSize; + UINT32 SectionCharacteristics; + UINT32 StartAddress; + UINT32 EndAddress; + UINT32 Characteristics; + UINT32 Attributes; + + ASSERT (Context != NULL); + // + // Determine the maximum amount of Image record sections and allocate the + // Image record. + // + NumberOfSections = PeCoffGetSectionTable (Context, &Sections); + + STATIC_ASSERT ( + MAX_UINT16 <= MAX_UINT32 / 2 - 1, + "The following arithmetic may overflow." + ); + + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_CONTIGUOUS_SECTIONS) == 0) { + // + // In case of contiguous Image sections, there can be two additional record + // sections (Image Headers and trailer, e.g. debug information). + // + MaxNumRecordSegments = (UINT32) NumberOfSections + 2; + } else { + // + // In case of possibly non-contiguous Image sections, there can be a trailer + // per Image section (the last Image section's trailer is the same as the + // Image trailer), as well as additionally the Image Headers. + // + MaxNumRecordSegments = (UINT32) NumberOfSections * 2 + 1; + } + + ImageRecord = AllocatePool ( + sizeof (*ImageRecord) + + MaxNumRecordSegments * sizeof (*ImageRecord->Segments) + ); + if (ImageRecord == NULL) { + DEBUG_RAISE (); + return NULL; + } + + ImageRecord->Signature = UEFI_IMAGE_RECORD_SIGNATURE; + InitializeListHead (&ImageRecord->Link); + + SectionAlignment = PeCoffGetSectionAlignment (Context); + // + // Map the Image Headers as read-only data. If the first Image section is + // loaded at the start of the Image memory space, the condition + // SectionAddress != StartAddress does not hold and these definitions will be + // ignored. + // + StartAddress = 0; + EndAddress = PeCoffGetSizeOfHeaders (Context); + Characteristics = EFI_IMAGE_SCN_MEM_READ; + Attributes = EFI_MEMORY_XP | EFI_MEMORY_RO; + ASSERT (Attributes == InternalCharacteristicsToAttributes (Characteristics)); + // + // Create an Image record section for every permission-distinct range of the + // Image. The current range [StartAddress, EndAddress) shares the memory + // permissions Charactersitics/Attributes and is extended till a new + // memory permission configuration is required. Headers and trailers treated + // as read-only data. + // + NumRecordSegments = 0; + for (SectionIndex = 0; SectionIndex < NumberOfSections; ++SectionIndex) { + Section = Sections + SectionIndex; + // + // Skip empty Image sections to avoid unnecessary splitting. + // + if (Section->VirtualSize == 0) { + continue; + } + // + // These arithmetics are safe as guaranteed by PeCoffInitializeContext(). + // + SectionAddress = Section->VirtualAddress; + SectionSize = ALIGN_VALUE (Section->VirtualSize, SectionAlignment); + SectionCharacteristics = Section->Characteristics & (EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_MEM_READ | EFI_IMAGE_SCN_MEM_WRITE); + // + // Skip Image sections with the same memory permissions as the current range + // as they can be merged. For this, the Image sections must be adjacent, or + // the range must have the same memory permissions as the padding inbetween + // (read-only). + // + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_CONTIGUOUS_SECTIONS) == 0 + || SectionAddress == EndAddress + || Characteristics == EFI_IMAGE_SCN_MEM_READ) { + if (SectionCharacteristics == Characteristics) { + EndAddress = SectionAddress + SectionSize; + continue; + } + } + // + // Only create an entry if the range is not empty, otherwise discard it and + // start a new one. Even with skipping empty Image sections, this can still + // happen for the Image Headers when the first Image section starts at 0. + // + if (SectionAddress != StartAddress) { + // + // Create an Image record section for the current memory permission range. + // + RecordSegment = &ImageRecord->Segments[NumRecordSegments]; + RecordSegment->Size = EndAddress - StartAddress; + RecordSegment->Attributes = Attributes; + ++NumRecordSegments; + // + // If the previous range is not adjacent to the current Image section, + // report the padding as read-only data. + // + if ((PcdGet32 (PcdImageLoaderAlignmentPolicy) & PCD_ALIGNMENT_POLICY_CONTIGUOUS_SECTIONS) != 0) { + NumRecordSegments += InternalInsertImageRecordSegmentPadding ( + RecordSegment, + EndAddress, + SectionAddress, + Attributes + ); + } + + StartAddress = SectionAddress; + } + // + // Start a Image record section with the current Image section. + // + EndAddress = SectionAddress + SectionSize; + Characteristics = SectionCharacteristics; + Attributes = InternalCharacteristicsToAttributes (Characteristics); + } + // + // Image Record sections are only created once a non-empty Image section is + // encountered that requests a different memory permission configuration. + // As such, the last memory permission range is never converted in the loop. + // If the loop never produced such, this is true for the Image Headers, which + // cannot be empty. + // + ASSERT (StartAddress < EndAddress); + // + // Create an Image record section for the last Image memory permission range. + // + RecordSegment = &ImageRecord->Segments[NumRecordSegments]; + RecordSegment->Size = EndAddress - StartAddress; + RecordSegment->Attributes = Attributes; + ++NumRecordSegments; + + ImageAddress = PeCoffLoaderGetImageAddress (Context); + SizeOfImage = PeCoffGetSizeOfImage (Context); + // + // The Image trailer, if existent, is treated as padding and as such is + // reported as read-only data, as intended. Because it is not part of the + // original Image memory space, this needs to happen whether Image sections + // are guaranteed to be contiguously form the entire Image memory space or + // not. + // + NumRecordSegments += InternalInsertImageRecordSegmentPadding ( + RecordSegment, + EndAddress, + SizeOfImage, + Attributes + ); + + ImageRecord->NumSegments = NumRecordSegments; + ImageRecord->StartAddress = ImageAddress; + ImageRecord->EndAddress = ImageAddress + SizeOfImage; + // + // Zero the remaining array entries to avoid uninitialised data. + // + ZeroMem ( + ImageRecord->Segments + NumRecordSegments, + (MaxNumRecordSegments - NumRecordSegments) * sizeof (*ImageRecord->Segments) + ); + + return ImageRecord; +} + +// FIXME: Docs +STATIC +RETURN_STATUS +InternalDebugLocateImage ( + OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN CHAR8 *Buffer, + IN UINTN Address, + IN BOOLEAN Recurse + ) +{ + RETURN_STATUS Status; + RETURN_STATUS DosStatus; + PE_COFF_LOADER_IMAGE_CONTEXT DosContext; + + ASSERT (((UINTN) Buffer & 3U) == 0); + // + // Align the search buffer to a 4 Byte boundary. + // + // Search for the Image Header in 4 Byte steps. All dynamically loaded + // Images start at a page boundary to allow for Image section protection, + // but XIP Images may not. As all Image Headers are at least 4 Byte aligned + // due to natural alignment, even XIP TE Image Headers should start at a + // 4 Byte boundary. + // + // Do not attempt to access memory of the first page as it may be protected as + // part of NULL dereference detection. + // + for (; EFI_PAGE_SIZE <= (UINTN) Buffer; Buffer -= 4) { + // + // Try to parse the current memory as PE/COFF or TE Image. Pass MAX_UINT32 + // as the file size as there isn't any more information available. Only the + // Image Header memory will be accessed as part of initialisation. + // + Status = PeCoffInitializeContext ( + Context, + Buffer, + MAX_UINT32 + ); + if (RETURN_ERROR (Status)) { + continue; + } + + if (!Recurse) { + // + // For PE/COFF Images, the PE/COFF Image Header may be discovered while + // there may still be a preceeding DOS Image Header. All RVAs are relatvie + // to the start of the Image memory space, of which the DOS Image Header + // is a part of, if existent. Allow one level of recursion to find a lower + // Image Base including the DOS Image Header. + // + if ((PcdGetBool (PcdImageLoaderProhibitTe) + || Context->ImageType != PeCoffLoaderTypeTe) + && Context->ExeHdrOffset == 0) { + ASSERT (Context->ImageType != PeCoffLoaderTypeTe); + + DosStatus = InternalDebugLocateImage ( + &DosContext, + Buffer - 4, + Address, + TRUE + ); + if (!RETURN_ERROR (DosStatus)) { + Buffer = DosContext.ImageBuffer; + CopyMem (Context, &DosContext, sizeof (*Context)); + } + } + } + // + // We know that (UINTN) Buffer <= Address from the initialisation. + // + // FIXME: Set to non-stripped base for XIP TE Images. + if (Address < (UINTN) Buffer + PeCoffGetSizeOfImage (Context)) { + Context->ImageBuffer = Buffer; + // + // Zero the raw file information as we are initialising from a potentially + // non-XIP in-memory Image. + // + Context->FileBuffer = NULL; + Context->FileSize = 0; + + return RETURN_SUCCESS; + } + // + // Continue for the unlikely case that a PE/COFF or TE Image embeds another + // one within its data, the outer Image may still follow. + // + } + + return RETURN_NOT_FOUND; +} + +RETURN_STATUS +UefiImageDebugLocateImagePeCoff ( + OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN UINTN Address + ) +{ + RETURN_STATUS Status; + + Status = RETURN_NOT_FOUND; + // + // As this function is intrinsically unsafe, do not allow its usage outside of + // DEBUG-enabled code. + // + DEBUG_CODE_BEGIN (); + + // + // If the Image Headers are not loaded explicitly, only XIP Images and Images + // that embed the Image Header in the first Image section can be located. As + // this is not the case for the majority of Images, don't attempt to locate + // the Image base to not access too much (potentially protected) memory. + // + if (!PcdGetBool (PcdImageLoaderLoadHeader)) { + DEBUG_RAISE (); + return RETURN_NOT_FOUND; + } + // + // Align the search buffer to a 4 Byte boundary. + // + Status = InternalDebugLocateImage ( + Context, + (CHAR8 *) (Address & ~(UINTN) 3U), + Address, + FALSE + ); + + DEBUG_CODE_END (); + + return Status; +} + +RETURN_STATUS +UefiImageGetFixedAddressPeCoff ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT UINT64 *Address + ) +{ + CONST EFI_IMAGE_SECTION_HEADER *Sections; + UINT16 NumberOfSections; + UINT16 SectionIndex; + UINT64 FixedAddress; + + ASSERT (Address != NULL); + // + // If this feature is enabled, the build tool will save the address in the + // PointerToRelocations and PointerToLineNumbers fields of the first Image + // section header that doesn't hold code. The 64-bit value across those fields + // will be non-zero if and only if the module has been assigned an address. + // + NumberOfSections = PeCoffGetSectionTable (Context, &Sections); + for (SectionIndex = 0; SectionIndex < NumberOfSections; ++SectionIndex) { + if ((Sections[SectionIndex].Characteristics & EFI_IMAGE_SCN_CNT_CODE) != 0) { + continue; + } + + FixedAddress = ReadUnaligned64 ( + (CONST VOID *) &Sections[SectionIndex].PointerToRelocations + ); + if (FixedAddress != 0) { + if (!IS_ALIGNED (FixedAddress, Context->SectionAlignment)) { + return RETURN_UNSUPPORTED; + } + + *Address = FixedAddress; + return RETURN_SUCCESS; + } + + break; + } + + return RETURN_NOT_FOUND; +} + +VOID +UefiImageDebugPrintSegmentsPeCoff ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + CONST EFI_IMAGE_SECTION_HEADER *Sections; + UINT16 NumberOfSections; + UINT16 SectionIndex; + CONST UINT8 *Name; + + NumberOfSections = PeCoffGetSectionTable (Context, &Sections); + + for (SectionIndex = 0; SectionIndex < NumberOfSections; ++SectionIndex) { + Name = Sections[SectionIndex].Name; + DEBUG (( + DEBUG_VERBOSE, + " Section - '%c%c%c%c%c%c%c%c'\n" + " VirtualSize - 0x%08x\n" + " VirtualAddress - 0x%08x\n" + " SizeOfRawData - 0x%08x\n" + " PointerToRawData - 0x%08x\n", + Name[0], Name[1], Name[2], Name[3], Name[4], Name[5], Name[6], Name[7], + Sections[SectionIndex].VirtualSize, + Sections[SectionIndex].VirtualAddress, + Sections[SectionIndex].SizeOfRawData, + Sections[SectionIndex].PointerToRawData + )); + DEBUG (( + DEBUG_VERBOSE, + " PointerToRelocations - 0x%08x\n" + " PointerToLinenumbers - 0x%08x\n" + " NumberOfRelocations - 0x%08x\n" + " NumberOfLinenumbers - 0x%08x\n" + " Characteristics - 0x%08x\n", + Sections[SectionIndex].PointerToRelocations, + Sections[SectionIndex].PointerToLinenumbers, + Sections[SectionIndex].NumberOfRelocations, + Sections[SectionIndex].NumberOfLinenumbers, + Sections[SectionIndex].Characteristics + )); + } +} diff --git a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.h b/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.h new file mode 100644 index 0000000000..102e09375f --- /dev/null +++ b/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.h @@ -0,0 +1,37 @@ +/** @file + UEFI Image Loader library implementation for PE/COFF and TE Images. + + Copyright (c) 2021, Marvin Häuser. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef PE_COFF_SUPPORT_H_ +#define PE_COFF_SUPPORT_H_ + +#include +#include + +UEFI_IMAGE_RECORD * +UefiImageLoaderGetImageRecordPeCoff ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +RETURN_STATUS +UefiImageDebugLocateImagePeCoff ( + OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + IN UINTN Address + ); + +RETURN_STATUS +UefiImageGetFixedAddressPeCoff ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, + OUT UINT64 *Address + ); + +VOID +UefiImageDebugPrintSegmentsPeCoff ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +#endif // PE_COFF_SUPPORT_H_ diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.c b/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.c new file mode 100644 index 0000000000..76b43f228a --- /dev/null +++ b/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.c @@ -0,0 +1,299 @@ +/** @file + UEFI Image Loader library implementation for PE/COFF and TE Images. + + Copyright (c) 2021, Marvin Häuser. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#define UEFI_IMAGE_LOADER_IMAGE_CONTEXT PE_COFF_LOADER_IMAGE_CONTEXT +#define UEFI_IMAGE_LOADER_RUNTIME_CONTEXT PE_COFF_LOADER_RUNTIME_CONTEXT + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PeCoffSupport.h" + +RETURN_STATUS +UefiImageInitializeContextPreHash ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN CONST VOID *FileBuffer, + IN UINT32 FileSize + ) +{ + return PeCoffInitializeContext (Context, FileBuffer, FileSize); +} + +RETURN_STATUS +UefiImageInitializeContextPostHash ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return RETURN_SUCCESS; +} + +UINT8 +UefiImageGetFormat ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return UefiImageFormatPe; +} + +BOOLEAN +UefiImageHashImageDefault ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN OUT VOID *HashContext, + IN UEFI_IMAGE_LOADER_HASH_UPDATE HashUpdate + ) +{ + return PeCoffHashImageAuthenticode (Context, HashContext, HashUpdate); +} + +RETURN_STATUS +UefiImageLoadImage ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT VOID *Destination, + IN UINT32 DestinationSize + ) +{ + return PeCoffLoadImage (Context, Destination, DestinationSize); +} + +BOOLEAN +UefiImageImageIsInplace ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffImageIsInplace (Context); +} + +RETURN_STATUS +UefiImageLoadImageInplace ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffLoadImageInplace (Context); +} + +RETURN_STATUS +UefiImageRelocateImageInplace ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffRelocateImageInplace (Context); +} + +RETURN_STATUS +UefiImageLoaderGetRuntimeContextSize ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *Size + ) +{ + return PeCoffLoaderGetRuntimeContextSize (Context, Size); +} + +RETURN_STATUS +UefiImageRelocateImage ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINT64 BaseAddress, + OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize + ) +{ + RETURN_STATUS Status; + + Status = PeCoffRelocateImage ( + Context, + BaseAddress, + RuntimeContext, + RuntimeContextSize + ); + if (!RETURN_ERROR (Status)) { + UefiImageLoaderRelocateImageExtraAction (Context); + } + + return Status; +} + +RETURN_STATUS +UefiImageRuntimeRelocateImage ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN UINT64 BaseAddress, + IN CONST UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext + ) +{ + return PeCoffRuntimeRelocateImage ( + Image, + ImageSize, + BaseAddress, + RuntimeContext + ); +} + +VOID +UefiImageDiscardSegments ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + PeCoffDiscardSections (Context); +} + +RETURN_STATUS +UefiImageGetSymbolsPath ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST CHAR8 **SymbolsPath, + OUT UINT32 *SymbolsPathSize + ) +{ + return PeCoffGetPdbPath (Context, SymbolsPath, SymbolsPathSize); +} + +RETURN_STATUS +UefiImageGetFirstCertificate ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST WIN_CERTIFICATE **Certificate + ) +{ + return PeCoffGetFirstCertificate (Context, Certificate); +} + +RETURN_STATUS +UefiImageGetNextCertificate ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN OUT CONST WIN_CERTIFICATE **Certificate + ) +{ + return PeCoffGetNextCertificate (Context, Certificate); +} + +RETURN_STATUS +UefiImageGetHiiDataRva ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *HiiRva, + OUT UINT32 *HiiSize + ) +{ + return PeCoffGetHiiDataRva (Context, HiiRva, HiiSize); +} + +UINT32 +UefiImageGetEntryPointAddress ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetAddressOfEntryPoint (Context); +} + +UINT16 +UefiImageGetMachine ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetMachine (Context); +} + +UINT16 +UefiImageGetSubsystem ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetSubsystem (Context); +} + +UINT32 +UefiImageGetSegmentAlignment ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetSectionAlignment (Context); +} + +UINT32 +UefiImageGetImageSize ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetSizeOfImage (Context); +} + +UINT32 +UefiImageGetImageSizeInplace ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetSizeOfImageInplace (Context); +} + +UINT64 +UefiImageGetPreferredAddress ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetImageBase (Context); +} + +BOOLEAN +UefiImageGetRelocsStripped ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetRelocsStripped (Context); +} + +UINTN +UefiImageLoaderGetImageAddress ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffLoaderGetImageAddress (Context); +} + +UEFI_IMAGE_RECORD * +UefiImageLoaderGetImageRecord ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return UefiImageLoaderGetImageRecordPeCoff (Context); +} + +RETURN_STATUS +UefiImageDebugLocateImage ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINTN Address + ) +{ + return UefiImageDebugLocateImagePeCoff (Context, Address); +} + +RETURN_STATUS +UefiImageGetFixedAddress ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT64 *Address + ) +{ + return UefiImageGetFixedAddressPeCoff (Context, Address); +} + +VOID +UefiImageDebugPrintSegments ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UefiImageDebugPrintSegmentsPeCoff (Context); +} diff --git a/MdePkg/Library/PeiServicesLib/PeiServicesLib.c b/MdePkg/Library/PeiServicesLib/PeiServicesLib.c index 16d5134981..5521e1690f 100644 --- a/MdePkg/Library/PeiServicesLib/PeiServicesLib.c +++ b/MdePkg/Library/PeiServicesLib/PeiServicesLib.c @@ -324,6 +324,38 @@ PeiServicesFfsFindSectionData3 ( return (*PeiServices)->FindSectionData3 (PeiServices, SectionType, SectionInstance, FileHandle, SectionData, AuthenticationStatus); } +/** + This service enables PEIMs to discover sections of a given instance and type within a valid FFS file. + + @param SectionType The value of the section type to find. + @param SectionInstance Section instance to find. + @param FileHandle A pointer to the file header that contains the set + of sections to be searched. + @param SectionData A pointer to the discovered section, if successful. + @param SectionDataSize The size of the discovered section, if successful. + @param AuthenticationStatus A pointer to the authentication status for this section. + + @retval EFI_SUCCESS The section was found. + @retval EFI_NOT_FOUND The section was not found. + +**/ +EFI_STATUS +EFIAPI +PeiServicesFfsFindSectionData4 ( + IN EFI_SECTION_TYPE SectionType, + IN UINTN SectionInstance, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData, + OUT UINT32 *SectionDataSize, + OUT UINT32 *AuthenticationStatus + ) +{ + CONST EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer (); + return (*PeiServices)->FindSectionData4 (PeiServices, SectionType, SectionInstance, FileHandle, SectionData, SectionDataSize, AuthenticationStatus); +} + /** This service enables PEIMs to register the permanent memory configuration that has been initialized with the PEI Foundation. diff --git a/MdePkg/MdeLibs.dsc.inc b/MdePkg/MdeLibs.dsc.inc index 57818e2499..ae645164c8 100644 --- a/MdePkg/MdeLibs.dsc.inc +++ b/MdePkg/MdeLibs.dsc.inc @@ -28,6 +28,7 @@ SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf + BaseOverflowLib|MdePkg/Library/BaseOverflowLib/BaseOverflowLib.inf StackCheckFailureHookLib|MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf !if $(CUSTOM_STACK_CHECK_LIB) == STATIC diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 37a2b461d4..f4df56d209 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -132,9 +132,15 @@ ## @libraryclass Provides extra action services for unloading and relocating a PE/COFF image on some specific platform such ## as NT32 emulator. PeCoffExtraActionLib|Include/Library/PeCoffExtraActionLib.h + # FIXME: Docs + ## @libraryclass Provides services to load and relocate a PE/COFF image. + PeCoffLib2|Include/Library/PeCoffLib2.h + ## @libraryclass Provides extra action services for unloading and relocating a PE/COFF image on some specific platform such + ## as NT32 emulator. + UefiImageExtraActionLib|Include/Library/UefiImageExtraActionLib.h ## @libraryclass Provides a service to retrieve the PE/COFF entry point from a PE/COFF image. - PeCoffGetEntryPointLib|Include/Library/PeCoffGetEntryPointLib.h + UefiImageGetEntryPointLib|Include/Library/UefiImageGetEntryPointLib.h ## @libraryclass Provides services to return the PCI segment information. PciSegmentInfoLib|Include/Library/PciSegmentInfoLib.h @@ -2275,7 +2281,7 @@ # BIT0 - SMM CET Shadow Stack is enabled.
# Other - reserved # @Prompt Enable control flow enforcement. - gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask|0x0|UINT32|0x30001017 + gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask|0|UINT32|0x30001017 ## Indicates the type of instruction sequence to use for a speculation # barrier. The default instruction sequence is LFENCE.

@@ -2294,6 +2300,63 @@ # FALSE - Do not enforce and depend on the default implementation of RNG algorithm from the provider. # @Prompt Enforce the use of Secure UEFI spec defined RNG algorithms. gEfiMdePkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms|TRUE|BOOLEAN|0x1000000D + + ## Indicates whether Image Relocation target values at Runtime may mismatch + # the values assigned during initial load.

+ # TRUE - Image relocation target values may mismatch the expected values.
+ # FALSE - Image relocation target values must match the expected values.
+ # @Prompt Allow Runtime Relocation Target Mismatch. + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRtRelocAllowTargetMismatch|FALSE|BOOLEAN|0x40001018 + + ## Indicates whether Image section may overlap with the previous one. + # Overlapping Sections could dramatically increase the hashing time.

+ # TRUE - Image section must not overlap with the previous one.
+ # FALSE - Image section may overlap with the previous one.
+ # @Prompt Prohibit Overlapping Sections. + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderHashProhibitOverlap|TRUE|BOOLEAN|0x40001019 + + ## Indicates whether Image Headers must be loaded into the memory space.

+ # TRUE - Image Headers will be loaded into the memory space.
+ # FALSE - Image Headers will not be loaded into the memory space.
+ # @Prompt Load Image Headers. + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderLoadHeader|TRUE|BOOLEAN|0x4000101A + + ## This flag is used to control the set of supported relocations' types.

+ # BIT0 - If set, ARM Thumb Image relocations are supported.
+ # @Prompt Image Relocations Policy. + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRelocTypePolicy|0xFFFFFFFF|UINT32|0x4000101B + + ## Indicates whether Image sections must adhere to the W^X principle.

+ # TRUE - Image sections must adhere to the W^X principle.
+ # FALSE - Image sections may not adhere to the W^X principle.
+ # @Prompt Enforce W^X principle. + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderWXorX|TRUE|BOOLEAN|0x4000101C + + ## Indicates whether Debug information can be retrieved + # from the Debug Directory of the Image.

+ # TRUE - Debug Directory will be scaned for Debug Information.
+ # FALSE - Debug Directory will not be scaned.
+ # @Prompt Support Debug Information. + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderDebugSupport|TRUE|BOOLEAN|0x4000101D + + ## This flag is used to control Image Loader alignment policy.

+ # BIT0 - If set, unaligned Image sections are permitted.
+ # BIT1 - If set, unaligned Image Relocation Block sizes are permitted.
+ # BIT2 - If set, unaligned Image certificate sizes are permitted.
+ # @Prompt Image Loader Alignment Policy. + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAlignmentPolicy|0xFFFFFFFF|UINT32|0x4000101E + + ## Indicates whether TE Images are allowed.

+ # TRUE - TE Images are forbidden.
+ # FALSE - TE Images are allowed.
+ # @Prompt Prohibit TE Images Loading. + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderProhibitTe|FALSE|BOOLEAN|0x4000101F + + ## Indicates whether PE32+ header offset is sufficiently aligned.

+ # TRUE - Execution Header offset may be not aligned.
+ # FALSE - Execution Header offset must be sufficiently aligned.
+ # @Prompt Allow Misaligned Offset. + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|FALSE|BOOLEAN|0x40001020 [PcdsFixedAtBuild,PcdsPatchableInModule] ## Indicates the maximum length of unicode string used in the following diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 84730b09d4..acf7be2aa7 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -58,9 +58,9 @@ MdePkg/Library/PciSegmentLibSegmentInfo/DxeRuntimePciSegmentLibSegmentInfo.inf MdePkg/Library/BaseS3PciSegmentLib/BaseS3PciSegmentLib.inf MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf - MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf - MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf - MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf + MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDebug.inf MdePkg/Library/BasePostCodeLibPort80/BasePostCodeLibPort80.inf diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc index b3710bf07a..f69df9d4c2 100644 --- a/NetworkPkg/NetworkPkg.dsc +++ b/NetworkPkg/NetworkPkg.dsc @@ -41,12 +41,15 @@ UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf + CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf @@ -118,7 +121,7 @@ NetworkPkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf NetworkPkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf - !include NetworkPkg/Network.dsc.inc +!include NetworkPkg/Network.dsc.inc [BuildOptions] *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc index e0eaa3c574..0c3ddaf445 100644 --- a/OvmfPkg/AmdSev/AmdSevX64.dsc +++ b/OvmfPkg/AmdSev/AmdSevX64.dsc @@ -122,7 +122,8 @@ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf @@ -134,7 +135,6 @@ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf @@ -175,10 +175,10 @@ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE - PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf + UefiImageExtraActionLib|SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf !else - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf !endif @@ -242,14 +242,14 @@ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf !ifdef $(DEBUG_ON_SERIAL_PORT) DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf !else DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf CcProbeLib|OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -259,13 +259,13 @@ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf !ifdef $(DEBUG_ON_SERIAL_PORT) DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf !else DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc index 5aab790316..d1e3616dc3 100644 --- a/OvmfPkg/Bhyve/BhyveX64.dsc +++ b/OvmfPkg/Bhyve/BhyveX64.dsc @@ -133,7 +133,8 @@ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf @@ -145,7 +146,6 @@ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf @@ -185,10 +185,10 @@ FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE - PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf + UefiImageExtraActionLib|SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf !else - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf !endif @@ -270,13 +270,13 @@ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf !ifdef $(DEBUG_ON_SERIAL_PORT) DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf !else DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -286,13 +286,13 @@ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf !ifdef $(DEBUG_ON_SERIAL_PORT) DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf !else DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE diff --git a/OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.c b/OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.c index c4416494a9..c4ae25fe2e 100644 --- a/OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.c +++ b/OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.c @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.inf b/OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.inf index 74f06c64bf..c9fbbe0591 100644 --- a/OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.inf +++ b/OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.inf @@ -26,7 +26,6 @@ [LibraryClasses] BaseMemoryLib DebugLib - PeCoffLib UefiBootServicesTableLib UefiDriverEntryPoint diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc index 6d3e0a5f1c..840159d118 100644 --- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc +++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc @@ -36,6 +36,9 @@ # DEFINE BUILD_SHELL = TRUE + DEFINE LEGACY_WINDOWS_LOADER = FALSE + DEFINE LINUX_LOADER = FALSE + # # Device drivers # @@ -90,12 +93,6 @@ INTEL:*_*_*_CC_FLAGS = /D TDX_PEI_LESS_BOOT GCC:*_*_*_CC_FLAGS = -D TDX_PEI_LESS_BOOT -[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] - GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 - XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000 - XCODE:*_*_*_MTOC_FLAGS = -align 0x1000 - CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096 - ################################################################################ # # SKU Identification section - list of all SKU IDs supported by this Platform. @@ -125,7 +122,8 @@ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf @@ -137,7 +135,6 @@ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf @@ -177,9 +174,14 @@ CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf +!if $(SOURCE_DEBUG_ENABLE) == TRUE + UefiImageExtraActionLib|SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf +!else + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf +!endif + LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf @@ -468,6 +470,21 @@ # gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi|FALSE + # + # Security measures for memory protection. + # + !if $(LEGACY_WINDOWS_LOADER) == TRUE + # Allow execution of EfiLoaderData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFFD1 + !elseif $(LINUX_LOADER) == TRUE + # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF40 + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE + !else + # Allow execution of EfiConventionalMemory and EfiBootServicesData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF45 + !endif + ################################################################################ # # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform diff --git a/OvmfPkg/IntelTdx/Sec/SecMain.c b/OvmfPkg/IntelTdx/Sec/SecMain.c index 7f2d28af95..d9c26535eb 100644 --- a/OvmfPkg/IntelTdx/Sec/SecMain.c +++ b/OvmfPkg/IntelTdx/Sec/SecMain.c @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/OvmfPkg/IntelTdx/Sec/SecMain.inf b/OvmfPkg/IntelTdx/Sec/SecMain.inf index a9ba5c8f78..5c281dbd6d 100644 --- a/OvmfPkg/IntelTdx/Sec/SecMain.inf +++ b/OvmfPkg/IntelTdx/Sec/SecMain.inf @@ -40,9 +40,6 @@ CpuLib DebugAgentLib IoLib - PeCoffLib - PeCoffGetEntryPointLib - PeCoffExtraActionLib ExtractGuidedSectionLib LocalApicLib MemEncryptSevLib diff --git a/OvmfPkg/Library/PeilessStartupLib/DxeLoad.c b/OvmfPkg/Library/PeilessStartupLib/DxeLoad.c index d34690eb8a..f2f0acff3a 100644 --- a/OvmfPkg/Library/PeilessStartupLib/DxeLoad.c +++ b/OvmfPkg/Library/PeilessStartupLib/DxeLoad.c @@ -194,6 +194,7 @@ FindDxeNonCc ( EFI_FV_INFO FvImageInfo; UINT32 FvAlignment; VOID *FvBuffer; + UINT32 FvImageSize; FileHandle = NULL; @@ -209,7 +210,7 @@ FindDxeNonCc ( // // Find FvImage in FvFile // - Status = FfsFindSectionDataWithHook (EFI_SECTION_FIRMWARE_VOLUME_IMAGE, CheckSectionHookForDxeNonCc, FileHandle, (VOID **)&FvImageHandle); + Status = FfsFindSectionDataWithHook (EFI_SECTION_FIRMWARE_VOLUME_IMAGE, CheckSectionHookForDxeNonCc, FileHandle, (VOID **)&FvImageHandle, &FvImageSize); if (EFI_ERROR (Status)) { return Status; } @@ -281,10 +282,11 @@ DxeLoadCore ( EFI_STATUS Status; EFI_FV_FILE_INFO DxeCoreFileInfo; EFI_PHYSICAL_ADDRESS DxeCoreAddress; - UINT64 DxeCoreSize; + UINT32 DxeCoreSize; EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint; EFI_PEI_FILE_HANDLE FileHandle; - VOID *PeCoffImage; + VOID *UefiImage; + UINT32 UefiImageSize; // // Look in all the FVs present and find the DXE Core FileHandle @@ -303,12 +305,12 @@ DxeLoadCore ( // // Load the DXE Core from a Firmware Volume. // - Status = FfsFindSectionDataWithHook (EFI_SECTION_PE32, NULL, FileHandle, &PeCoffImage); + Status = FfsFindSectionDataWithHook (EFI_SECTION_PE32, NULL, FileHandle, &UefiImage, &UefiImageSize); if (EFI_ERROR (Status)) { return Status; } - Status = LoadPeCoffImage (PeCoffImage, &DxeCoreAddress, &DxeCoreSize, &DxeCoreEntryPoint); + Status = LoadUefiImage (UefiImage, UefiImageSize, &DxeCoreAddress, &DxeCoreSize, &DxeCoreEntryPoint); ASSERT_EFI_ERROR (Status); // diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h index 18b3deb9db..9c172d56a7 100644 --- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h +++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.h @@ -22,7 +22,7 @@ Module Name: #include #include #include -#include +#include #include #include diff --git a/OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.h b/OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.h index 9be184cb64..af26b3bac7 100644 --- a/OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.h +++ b/OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.h @@ -23,7 +23,7 @@ Module Name: #include #include #include -#include +#include #include #include diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 09c196feb3..6d75ebdb24 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -53,6 +53,10 @@ !include NetworkPkg/NetworkDefines.dsc.inc + DEFINE LEGACY_WINDOWS_LOADER = FALSE + DEFINE LINUX_LOADER = FALSE + DEFINE WINDOWS_10_IA32 = FALSE + # # Device drivers # @@ -143,7 +147,8 @@ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf @@ -155,7 +160,6 @@ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf @@ -198,10 +202,10 @@ FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE - PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf + UefiImageExtraActionLib|SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf !else - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf !endif @@ -284,13 +288,13 @@ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf !ifdef $(DEBUG_ON_SERIAL_PORT) DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf !else DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -300,13 +304,13 @@ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf !ifdef $(DEBUG_ON_SERIAL_PORT) DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf !else DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE @@ -591,6 +595,21 @@ # gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi|FALSE + # + # Security measures for memory protection. + # + !if $(LEGACY_WINDOWS_LOADER) == TRUE + # Allow execution of EfiLoaderData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7FD1 + !elseif $(LINUX_LOADER) == TRUE + # Allow execution of EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7F41 + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE + !elseif $(WINDOWS_10_IA32) == TRUE + # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiRuntimeServicesData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7F04 + !endif + ################################################################################ # # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index a9383a6b9b..b11a4523f8 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -53,6 +53,10 @@ !include NetworkPkg/NetworkDefines.dsc.inc + DEFINE LEGACY_WINDOWS_LOADER = FALSE + DEFINE LINUX_LOADER = FALSE + DEFINE WINDOWS_10_IA32 = FALSE + # # Device drivers # @@ -106,19 +110,10 @@ !include NetworkPkg/NetworkBuildOptions.dsc.inc -[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] - GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 - XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000 - XCODE:*_*_*_MTOC_FLAGS = -align 0x1000 - CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096 - -# Force PE/COFF sections to be aligned at 4KB boundaries to support page level -# protection of DXE_SMM_DRIVER/SMM_CORE modules -[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE] GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000 XCODE:*_*_*_MTOC_FLAGS = -align 0x1000 - CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096 + CLANGPDB:*_*_*_DLINK_FLAGS = /FILEALIGN:4096 /ALIGN:4096 ################################################################################ # @@ -150,7 +145,8 @@ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf @@ -162,7 +158,6 @@ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf @@ -203,10 +198,10 @@ FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE - PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf + UefiImageExtraActionLib|SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf !else - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf !endif @@ -289,13 +284,13 @@ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf !ifdef $(DEBUG_ON_SERIAL_PORT) DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf !else DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -305,13 +300,13 @@ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf !ifdef $(DEBUG_ON_SERIAL_PORT) DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf !else DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE @@ -544,7 +539,7 @@ # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may # // significantly impact boot performance # DEBUG_ERROR 0x80000000 // Error - gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x800000CF !if $(SOURCE_DEBUG_ENABLE) == TRUE gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17 @@ -574,6 +569,9 @@ # gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi|FALSE + gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask|0x1 + gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 + [PcdsFixedAtBuild.IA32] # # The NumberOfPages values below are ad-hoc. They are updated sporadically at @@ -596,12 +594,27 @@ gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize|0x20000 !if $(SMM_REQUIRE) == TRUE - gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000 + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x8000 !endif # Point to the MdeModulePkg/Application/UiApp/UiApp.inf gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } + # + # Security measures for memory protection. + # + !if $(LEGACY_WINDOWS_LOADER) == TRUE + # Allow execution of EfiLoaderData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7FD1 + !elseif $(LINUX_LOADER) == TRUE + # Allow execution of EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7F41 + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE + !elseif $(WINDOWS_10_IA32) == TRUE + # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiRuntimeServicesData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7F04 + !endif + ################################################################################ # # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index 605d9cd47a..0a9a31df75 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -408,7 +408,7 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { [Rule.Common.SEC] FILE SEC = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING ="$(MODULE_NAME)" Optional VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index eb5df0d74c..d562e47dae 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -53,6 +53,9 @@ !include NetworkPkg/NetworkDefines.dsc.inc + DEFINE LEGACY_WINDOWS_LOADER = FALSE + DEFINE LINUX_LOADER = FALSE + # # Device drivers # @@ -161,7 +164,8 @@ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf @@ -173,7 +177,6 @@ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf @@ -219,10 +222,10 @@ FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE - PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf + UefiImageExtraActionLib|SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf !else - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf !endif @@ -307,13 +310,13 @@ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf !ifdef $(DEBUG_ON_SERIAL_PORT) DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf !else DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CcProbeLib|OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf [LibraryClasses.common.PEIM] @@ -324,13 +327,13 @@ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf !ifdef $(DEBUG_ON_SERIAL_PORT) DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf !else DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE @@ -567,7 +570,7 @@ # DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may # // significantly impact boot performance # DEBUG_ERROR 0x80000000 // Error - gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x800000CF !if $(SOURCE_DEBUG_ENABLE) == TRUE gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17 @@ -624,6 +627,18 @@ # gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi|FALSE + # + # Security measures for memory protection. + # + !if $(LEGACY_WINDOWS_LOADER) == TRUE + # Allow execution of EfiLoaderData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7FD1 + !elseif $(LINUX_LOADER) == TRUE + # Allow execution of EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7F41 + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE + !endif + ################################################################################ # # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc index a4fb92f7cf..10f2992ceb 100644 --- a/OvmfPkg/OvmfXen.dsc +++ b/OvmfPkg/OvmfXen.dsc @@ -134,7 +134,8 @@ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf @@ -146,7 +147,6 @@ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf @@ -185,10 +185,10 @@ ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE - PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf + UefiImageExtraActionLib|SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf !else - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf !endif @@ -270,9 +270,9 @@ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -282,8 +282,8 @@ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c index d13a948509..ccd1e8e060 100644 --- a/OvmfPkg/Sec/SecMain.c +++ b/OvmfPkg/Sec/SecMain.c @@ -9,6 +9,7 @@ **/ +#include "ProcessorBind.h" #include #include @@ -19,9 +20,9 @@ #include #include #include -#include -#include -#include +#include + +#include #include #include #include @@ -488,7 +489,8 @@ DecompressMemFvs ( EFI_STATUS FindPeiCoreImageBaseInFv ( IN EFI_FIRMWARE_VOLUME_HEADER *Fv, - OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase, + OUT UINT32 *PeiCoreImageSize ) { EFI_STATUS Status; @@ -514,6 +516,8 @@ FindPeiCoreImageBaseInFv ( } *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1); + // FIXME: Size check, common API? + *PeiCoreImageSize = SECTION_SIZE (Section) - sizeof (*Section); return EFI_SUCCESS; } @@ -571,7 +575,8 @@ GetS3ResumePeiFv ( VOID FindPeiCoreImageBase ( IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv, - OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase, + OUT UINT32 *PeiCoreImageSize ) { BOOLEAN S3Resume; @@ -601,7 +606,7 @@ FindPeiCoreImageBase ( DecompressMemFvs (BootFv); } - FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase); + FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase, PeiCoreImageSize); } /** @@ -611,7 +616,8 @@ FindPeiCoreImageBase ( EFI_STATUS FindImageBase ( IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, - OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase + OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase, + OUT UINT32 *SecCoreImageSize ) { EFI_PHYSICAL_ADDRESS CurrentAddress; @@ -623,6 +629,7 @@ FindImageBase ( EFI_PHYSICAL_ADDRESS EndOfSection; *SecCoreImageBase = 0; + *SecCoreImageSize = 0; CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)BootFirmwareVolumePtr; EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength; @@ -678,6 +685,7 @@ FindImageBase ( if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) { if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) { *SecCoreImageBase = (PHYSICAL_ADDRESS)(UINTN)(Section + 1); + *SecCoreImageSize = Size - sizeof (*Section); } break; @@ -708,39 +716,45 @@ FindAndReportEntryPoints ( { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS SecCoreImageBase; + UINT32 SecCoreImageSize; EFI_PHYSICAL_ADDRESS PeiCoreImageBase; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UINT32 PeiCoreImageSize; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; // // Find SEC Core and PEI Core image base // - Status = FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase); + Status = FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase, &SecCoreImageSize); ASSERT_EFI_ERROR (Status); - FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase); + FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase, &PeiCoreImageSize); - ZeroMem ((VOID *)&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); // // Report SEC Core debug information when remote debug is enabled // - ImageContext.ImageAddress = SecCoreImageBase; - ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress); - PeCoffLoaderRelocateImageExtraAction (&ImageContext); + Status = UefiImageInitializeContext (&ImageContext, (VOID *) (UINTN) SecCoreImageBase, SecCoreImageSize); + ASSERT_EFI_ERROR (Status); + + Status = UefiImageLoadImageInplace (&ImageContext); + ASSERT_EFI_ERROR (Status); + + UefiImageLoaderRelocateImageExtraAction (&ImageContext); // - // Report PEI Core debug information when remote debug is enabled + // Find PEI Core entry point // - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase; - ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress); - PeCoffLoaderRelocateImageExtraAction (&ImageContext); + Status = UefiImageInitializeContext (&ImageContext, (VOID *) (UINTN) PeiCoreImageBase, PeiCoreImageSize); + ASSERT_EFI_ERROR (Status); + + Status = UefiImageLoadImageInplace (&ImageContext); + ASSERT_EFI_ERROR (Status); // - // Find PEI Core entry point + // Report PEI Core debug information when remote debug is enabled // - Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, (VOID **)PeiCoreEntryPoint); - if (EFI_ERROR (Status)) { - *PeiCoreEntryPoint = 0; - } + UefiImageLoaderRelocateImageExtraAction (&ImageContext); + + *PeiCoreEntryPoint = (EFI_PEI_CORE_ENTRY_POINT)(UINTN)(UefiImageLoaderGetImageEntryPoint (&ImageContext)); return; } diff --git a/OvmfPkg/Sec/SecMain.inf b/OvmfPkg/Sec/SecMain.inf index 4a91fb2bbb..0383c4f999 100644 --- a/OvmfPkg/Sec/SecMain.inf +++ b/OvmfPkg/Sec/SecMain.inf @@ -47,9 +47,8 @@ CpuLib DebugAgentLib IoLib - PeCoffLib - PeCoffGetEntryPointLib - PeCoffExtraActionLib + UefiImageLib + UefiImageExtraActionLib ExtractGuidedSectionLib LocalApicLib MemEncryptSevLib diff --git a/OvmfPkg/Tcg/TdTcg2Dxe/MeasureBootPeCoff.c b/OvmfPkg/Tcg/TdTcg2Dxe/MeasureBootPeCoff.c index 4d542156ba..e6e372b6b6 100644 --- a/OvmfPkg/Tcg/TdTcg2Dxe/MeasureBootPeCoff.c +++ b/OvmfPkg/Tcg/TdTcg2Dxe/MeasureBootPeCoff.c @@ -19,11 +19,17 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +#include #include UINTN mTcg2DxeImageSize = 0; +typedef union { + EFI_IMAGE_NT_HEADERS32 *Pe32; + EFI_IMAGE_NT_HEADERS64 *Pe32Plus; + EFI_IMAGE_OPTIONAL_HEADER_UNION *Union; +} EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION; + /** Reads contents of a PE/COFF image in memory buffer. @@ -113,25 +119,19 @@ MeasurePeImageAndExtend ( UINT32 NumberOfRvaAndSizes; UINT32 CertSize; HASH_HANDLE HashHandle; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; HashHandle = 0xFFFFFFFF; // Know bad value Status = EFI_UNSUPPORTED; SectionHeader = NULL; - // - // Check PE/COFF image - // - ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.Handle = (VOID *)(UINTN)ImageAddress; - mTcg2DxeImageSize = ImageSize; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)Tcg2DxeImageRead; + mTcg2DxeImageSize = ImageSize; // // Get information about the image being loaded // - Status = PeCoffLoaderGetImageInfo (&ImageContext); + Status = UefiImageInitializeContext (&ImageContext, (VOID *) (UINTN) ImageAddress, ImageSize); if (EFI_ERROR (Status)) { // // The information can't be got from the invalid PeImage @@ -147,7 +147,7 @@ MeasurePeImageAndExtend ( } Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset); - if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { + if (Hdr.Pe32->CommonHeader.Signature != EFI_IMAGE_NT_SIGNATURE) { Status = EFI_UNSUPPORTED; goto Finish; } @@ -179,18 +179,18 @@ MeasurePeImageAndExtend ( // 4. Hash the image header from its base to beginning of the image checksum. // HashBase = (UINT8 *)(UINTN)ImageAddress; - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + if (Hdr.Pe32->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { // // Use PE32 offset // - NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes; - HashSize = (UINTN)(&Hdr.Pe32->OptionalHeader.CheckSum) - (UINTN)HashBase; + NumberOfRvaAndSizes = Hdr.Pe32->NumberOfRvaAndSizes; + HashSize = (UINTN)(&Hdr.Pe32->CheckSum) - (UINTN)HashBase; } else { // // Use PE32+ offset // - NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes; - HashSize = (UINTN)(&Hdr.Pe32Plus->OptionalHeader.CheckSum) - (UINTN)HashBase; + NumberOfRvaAndSizes = Hdr.Pe32Plus->NumberOfRvaAndSizes; + HashSize = (UINTN)(&Hdr.Pe32Plus->CheckSum) - (UINTN)HashBase; } Status = HashUpdate (HashHandle, HashBase, HashSize); @@ -206,18 +206,18 @@ MeasurePeImageAndExtend ( // 6. Since there is no Cert Directory in optional header, hash everything // from the end of the checksum to the end of image header. // - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + if (Hdr.Pe32->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { // // Use PE32 offset. // - HashBase = (UINT8 *)&Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); + HashBase = (UINT8 *)&Hdr.Pe32->CheckSum + sizeof (UINT32); + HashSize = Hdr.Pe32->SizeOfHeaders - (UINTN)(HashBase - ImageAddress); } else { // // Use PE32+ offset. // - HashBase = (UINT8 *)&Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); + HashBase = (UINT8 *)&Hdr.Pe32Plus->CheckSum + sizeof (UINT32); + HashSize = Hdr.Pe32Plus->SizeOfHeaders - (UINTN)(HashBase - ImageAddress); } if (HashSize != 0) { @@ -230,18 +230,18 @@ MeasurePeImageAndExtend ( // // 7. Hash everything from the end of the checksum to the start of the Cert Directory. // - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + if (Hdr.Pe32->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { // // Use PE32 offset // - HashBase = (UINT8 *)&Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; + HashBase = (UINT8 *)&Hdr.Pe32->CheckSum + sizeof (UINT32); + HashSize = (UINTN)(&Hdr.Pe32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; } else { // // Use PE32+ offset // - HashBase = (UINT8 *)&Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; + HashBase = (UINT8 *)&Hdr.Pe32Plus->CheckSum + sizeof (UINT32); + HashSize = (UINTN)(&Hdr.Pe32Plus->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; } if (HashSize != 0) { @@ -255,18 +255,18 @@ MeasurePeImageAndExtend ( // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.) // 9. Hash everything from the end of the Cert Directory to the end of image header. // - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + if (Hdr.Pe32->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { // // Use PE32 offset // - HashBase = (UINT8 *)&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); + HashBase = (UINT8 *)&Hdr.Pe32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; + HashSize = Hdr.Pe32->SizeOfHeaders - (UINTN)(HashBase - ImageAddress); } else { // // Use PE32+ offset // - HashBase = (UINT8 *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); + HashBase = (UINT8 *)&Hdr.Pe32Plus->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; + HashSize = Hdr.Pe32Plus->SizeOfHeaders - (UINTN)(HashBase - ImageAddress); } if (HashSize != 0) { @@ -280,16 +280,16 @@ MeasurePeImageAndExtend ( // // 10. Set the SUM_OF_BYTES_HASHED to the size of the header // - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + if (Hdr.Pe32->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { // // Use PE32 offset // - SumOfBytesHashed = Hdr.Pe32->OptionalHeader.SizeOfHeaders; + SumOfBytesHashed = Hdr.Pe32->SizeOfHeaders; } else { // // Use PE32+ offset // - SumOfBytesHashed = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders; + SumOfBytesHashed = Hdr.Pe32Plus->SizeOfHeaders; } // @@ -298,7 +298,7 @@ MeasurePeImageAndExtend ( // header indicates how big the table should be. Do not include any // IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero. // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *)AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * Hdr.Pe32->FileHeader.NumberOfSections); + SectionHeader = (EFI_IMAGE_SECTION_HEADER *)AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * Hdr.Pe32->CommonHeader.FileHeader.NumberOfSections); if (SectionHeader == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Finish; @@ -315,9 +315,9 @@ MeasurePeImageAndExtend ( PeCoffHeaderOffset + sizeof (UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + - Hdr.Pe32->FileHeader.SizeOfOptionalHeader + Hdr.Pe32->CommonHeader.FileHeader.SizeOfOptionalHeader ); - for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) { + for (Index = 0; Index < Hdr.Pe32->CommonHeader.FileHeader.NumberOfSections; Index++) { Pos = Index; while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) { CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof (EFI_IMAGE_SECTION_HEADER)); @@ -335,7 +335,7 @@ MeasurePeImageAndExtend ( // 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED . // 15. Repeat steps 13 and 14 for all the sections in the sorted table. // - for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) { + for (Index = 0; Index < Hdr.Pe32->CommonHeader.FileHeader.NumberOfSections; Index++) { Section = (EFI_IMAGE_SECTION_HEADER *)&SectionHeader[Index]; if (Section->SizeOfRawData == 0) { continue; @@ -364,16 +364,16 @@ MeasurePeImageAndExtend ( if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) { CertSize = 0; } else { - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + if (Hdr.Pe32->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { // // Use PE32 offset. // - CertSize = Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size; + CertSize = Hdr.Pe32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size; } else { // // Use PE32+ offset. // - CertSize = Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size; + CertSize = Hdr.Pe32Plus->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size; } } diff --git a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf index 0c2d116cc7..9c019fdb1d 100644 --- a/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf +++ b/OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf @@ -47,7 +47,7 @@ HashLib PerformanceLib ReportStatusCodeLib - PeCoffLib + UefiImageLib TpmMeasurementLib TdxLib TdxMeasurementLib diff --git a/README.md b/README.md new file mode 100644 index 0000000000..efa9528d4d --- /dev/null +++ b/README.md @@ -0,0 +1,71 @@ +# PE/COFF loader designed with formal methods + +This branch demonstrates the integration of a new PE/COFF loader designed with the help of formal methods into the EDK II infrastructure. + +## Introduction + +The PE/COFF loader is one of the central components of the firmware core and its trust base. Every Image which is part of a UEFI system, including platform drivers from the primary firmware storage, Option ROMs from external hardware, and OS loaders from arbitrary storage, is verified and loaded by this library. Clearly it is a key component to ensure platform reliability and software compatibility, and can only be modified with great care. It also is an essential component for security technologies such as Secure Boot and Measured Boot. + +![image](LoaderFlow.png) + +Unfortunately, over the years, the current solution has been subject to bug reports affecting platform reliability, some of which have been unresolved to date. Please refer to the TianoCore BugZilla and especially discussions on the edk2-devel mailing list for further reading. Due to the incremental changes to the existing solution over the years, the state of a sound solution has been lost, and it has become a maintenance burden that is hard to fix and further advance incrementally. At the same time, the demand on not only tested but proven security has become more important in the recent times. + +The usage of formal methods to design the new solution greatly helped restore the state of a truly sound solution, resolving many issues regarding inter-API guarantees and Image format validation. Many new abstractions have been introduced, external code has been centralized, and the overall flexibility has been improved, to hopefully aid developers to extend the codebase more easily in the future. Beyond that, the formal model ensures a high level of confidence that security-wise there have been no regressions, and there might even be potential improvements. + +Please also refer to the new work-in-progress documentation available at [MdePkg/Library/BasePeCoffLib2/Documentation.md](MdePkg/Library/BasePeCoffLib2/Documentation.md) + +## Further abstraction + +The new solution has been implemented as a new library class in MdePkg. ``PeCoffLib2`` features a new API that allows for a more resilient and a more flexible caller design. Most notably, all Image operations have been integrated into the API design rather than the callers accessing the library context and duplicating certain work. ``PeCoffLib`` remains intact as deprecated API to support legacy code during the transition period. + +To increase platform flexibility, a new layer of abstraction is introduced in the form of the library class ``UefiImageLib``, which can be found at [MdePkg/Include/Library/UefiImageLib.h](MdePkg/Include/Library/UefiImageLib.h). Currently, it is a subset of the APIs provided by ``PeCoffLib2`` that is expected to be compatible with most other common executable formats, plus a few convenience functions. As part of the proposal, the instance ``UefiImageLibPeCoff`` is provided, which is basically a shim for ``PeCoffLib2``. In the future, instances to support other file formats can be introduced without having to integrate them across the entire EDK II tree. + +## Issues of the current solution +* High level of maintenance cost due to convoluted function contracts +* Error-prone design promoting the introduction of code bugs +* Multiple real-world bugs affecting reliability, some unaddressed for years +* A lot of duplicate caller-side code that decreases the flexibility of porting and integration (e.g. Image permissions in PEI) +* Dependency on Image re-parsing for production code + +## Benefits of the new solution +* Fixes all known reported BugZilla tickets on PE/COFF loader reliability +* Formal methods increase confidence in a high level of reliability and security +* Improved design eases future maintenance and extension +* Architecture-independent Image processing (e.g. for emulation) +* Support for more granular Image section permissions (e.g. read-only) + +## Benefits of the formal methods involved +* Complete proof arithmetic cannot overflow (excluding intentional modulo arithmetic) +* Mostly complete proof memory accesses are safe (requires axioms) +* Complete proof of Image format compliance verification +* Complete proof of Image loading +* Mostly complete proof of Image relocation (final memory state cannot be easily described) + +## Further notes about the formal approach +* A snapshot of the new PE/COFF loader code will be provided with annotations and proving results +* The snapshot will not be current and updating the old code is out of the scope of this project, however the functional changes should be manageable to review +* We are currently investigating whether deploying the proving environment as a Docker container is feasible +* There may be aids to compare the updates over the last fully verified state (e.g. stripped versions of the code with diffs) +* If accepted, the new PE/COFF loader code should be developed further without updating the formal annotations, but with thorough review of important invariants and sufficient documentation + +## Current progress, future goals, and further notes +* OVMF boots to Shell with SMM and Secure Boot enabled +* Linux EmulatorPkg boots +* Extended support for Image protection has been implemented +* FFS and DebugTable enhancements have been implemented +* Not all features have been implemented, e.g. RISC-V support +* There are unrelated changes present to help testing and validation +* Specified interfaces need adjustments (e.g. security architectural protocol) +* Some validation is still absent + +## BZs fixed by integrating the new PE/COFF loader +* https://bugzilla.tianocore.org/show_bug.cgi?id=1860 +* https://bugzilla.tianocore.org/show_bug.cgi?id=1999 +* https://bugzilla.tianocore.org/show_bug.cgi?id=2120 +* https://bugzilla.tianocore.org/show_bug.cgi?id=3329 +* More to be added shortly... + +## BZs easier to address by integrating the new PE/COFF loader +* https://bugzilla.tianocore.org/show_bug.cgi?id=3326 +* https://bugzilla.tianocore.org/show_bug.cgi?id=3331 +* More to be added shortly... diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf index 5e91968576..11e65bc739 100644 --- a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf +++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf @@ -43,3 +43,8 @@ BaseCryptLib RngLib MemLibWrapper + +[BuildOptions] + CLANGPDB:*_*_*_CC_FLAGS = -Wno-non-literal-null-conversion + GCC:*_*_*_CC_FLAGS = -Wno-non-literal-null-conversion + XCODE:*_*_*_CC_FLAGS = -Wno-non-literal-null-conversion diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c index 86cf9b225c..3852025ec4 100644 --- a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c +++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c @@ -136,9 +136,9 @@ ExtendCertificate ( EventLog = NULL; ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationConnection; + Parameter.location = (libspdm_data_location_t)SpdmDataLocationConnection; DataSize = sizeof (BaseHashAlgo); - Status = SpdmGetData (SpdmContext, SpdmDataBaseHashAlgo, &Parameter, &BaseHashAlgo, &DataSize); + Status = SpdmGetData (SpdmContext, (libspdm_data_type_t)SpdmDataBaseHashAlgo, &Parameter, &BaseHashAlgo, &DataSize); ASSERT_EFI_ERROR (Status); DeviceContextSize = GetDeviceMeasurementContextSize (SpdmDeviceContext); @@ -520,9 +520,9 @@ DoDeviceCertificate ( SpdmContext = SpdmDeviceContext->SpdmContext; ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationConnection; + Parameter.location = (libspdm_data_location_t)SpdmDataLocationConnection; DataSize = sizeof (CapabilityFlags); - SpdmReturn = SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize); + SpdmReturn = SpdmGetData (SpdmContext, (libspdm_data_type_t)SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR; return EFI_DEVICE_ERROR; @@ -641,9 +641,9 @@ DoDeviceAuthentication ( SpdmContext = SpdmDeviceContext->SpdmContext; ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationConnection; + Parameter.location = (libspdm_data_location_t)SpdmDataLocationConnection; DataSize = sizeof (CapabilityFlags); - SpdmReturn = SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize); + SpdmReturn = SpdmGetData (SpdmContext, (libspdm_data_type_t)SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR; return EFI_DEVICE_ERROR; diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c index d61aa01698..962e906e4e 100644 --- a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c +++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c @@ -338,8 +338,8 @@ CreateSpdmDeviceContext ( DataSize = DbList->SignatureSize - sizeof (EFI_GUID); ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationLocal; - SpdmReturn = SpdmSetData (SpdmContext, SpdmDataPeerPublicRootCert, &Parameter, Data, DataSize); + Parameter.location = (libspdm_data_location_t)SpdmDataLocationLocal; + SpdmReturn = SpdmSetData (SpdmContext, (libspdm_data_type_t)SpdmDataPeerPublicRootCert, &Parameter, Data, DataSize); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { if (SpdmReturn == LIBSPDM_STATUS_BUFFER_FULL) { Status = RecordConnectionFailureStatus ( @@ -366,22 +366,22 @@ CreateSpdmDeviceContext ( Data8 = 0; ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationLocal; - SpdmReturn = SpdmSetData (SpdmContext, SpdmDataCapabilityCTExponent, &Parameter, &Data8, sizeof (Data8)); + Parameter.location = (libspdm_data_location_t)SpdmDataLocationLocal; + SpdmReturn = SpdmSetData (SpdmContext, (libspdm_data_type_t)SpdmDataCapabilityCTExponent, &Parameter, &Data8, sizeof (Data8)); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { ASSERT (FALSE); goto Error; } Data32 = 0; - SpdmReturn = SpdmSetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &Data32, sizeof (Data32)); + SpdmReturn = SpdmSetData (SpdmContext, (libspdm_data_type_t)SpdmDataCapabilityFlags, &Parameter, &Data32, sizeof (Data32)); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { ASSERT (FALSE); goto Error; } Data8 = SPDM_MEASUREMENT_SPECIFICATION_DMTF; - SpdmReturn = SpdmSetData (SpdmContext, SpdmDataMeasurementSpec, &Parameter, &Data8, sizeof (Data8)); + SpdmReturn = SpdmSetData (SpdmContext, (libspdm_data_type_t)SpdmDataMeasurementSpec, &Parameter, &Data8, sizeof (Data8)); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { ASSERT (FALSE); goto Error; @@ -398,7 +398,7 @@ CreateSpdmDeviceContext ( SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521; } - SpdmReturn = SpdmSetData (SpdmContext, SpdmDataBaseAsymAlgo, &Parameter, &Data32, sizeof (Data32)); + SpdmReturn = SpdmSetData (SpdmContext, (libspdm_data_type_t)SpdmDataBaseAsymAlgo, &Parameter, &Data32, sizeof (Data32)); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { ASSERT (FALSE); goto Error; @@ -412,7 +412,7 @@ CreateSpdmDeviceContext ( SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512; } - SpdmReturn = SpdmSetData (SpdmContext, SpdmDataBaseHashAlgo, &Parameter, &Data32, sizeof (Data32)); + SpdmReturn = SpdmSetData (SpdmContext, (libspdm_data_type_t)SpdmDataBaseHashAlgo, &Parameter, &Data32, sizeof (Data32)); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { ASSERT (FALSE); goto Error; @@ -433,9 +433,9 @@ CreateSpdmDeviceContext ( } ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationConnection; + Parameter.location = (libspdm_data_location_t)SpdmDataLocationConnection; DataSize = sizeof (Data16); - SpdmReturn = SpdmGetData (SpdmContext, SpdmDataSpdmVersion, &Parameter, &Data16, &DataSize); + SpdmReturn = SpdmGetData (SpdmContext, (libspdm_data_type_t)SpdmDataSpdmVersion, &Parameter, &Data16, &DataSize); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { DEBUG ((DEBUG_ERROR, "SpdmGetData - %p\n", SpdmReturn)); goto Error; diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c index f94ec1e7bf..3eb33292bd 100644 --- a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c +++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c @@ -209,9 +209,9 @@ ExtendMeasurement ( EventLog = NULL; ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationConnection; + Parameter.location = (libspdm_data_location_t)SpdmDataLocationConnection; DataSize = sizeof (MeasurementHashAlgo); - Status = SpdmGetData (SpdmContext, SpdmDataMeasurementHashAlgo, &Parameter, &MeasurementHashAlgo, &DataSize); + Status = SpdmGetData (SpdmContext, (libspdm_data_type_t)SpdmDataMeasurementHashAlgo, &Parameter, &MeasurementHashAlgo, &DataSize); ASSERT_EFI_ERROR (Status); if (MeasurementRecord != NULL) { @@ -531,9 +531,9 @@ DoDeviceMeasurement ( SpdmContext = SpdmDeviceContext->SpdmContext; ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationConnection; + Parameter.location = (libspdm_data_location_t)SpdmDataLocationConnection; DataSize = sizeof (CapabilityFlags); - SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize); + SpdmGetData (SpdmContext, (libspdm_data_type_t)SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize); if ((CapabilityFlags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) == 0) { AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG; diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c index b05da19c2b..3ac202a32b 100644 --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c @@ -19,22 +19,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "DxeImageVerificationLib.h" - -// -// Caution: This is used by a function which may receive untrusted input. -// These global variables hold PE/COFF image data, and they should be validated before use. -// -EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION mNtHeader; -UINT32 mPeCoffHeaderOffset; -EFI_GUID mCertType; - -// -// Information on current PE/COFF image -// -UINTN mImageSize; -UINT8 *mImageBase = NULL; -UINT8 mImageDigest[MAX_DIGEST_SIZE]; -UINTN mImageDigestSize; +#include "Library/BaseCryptLib.h" +#include "Library/UefiImageLib.h" // // Notify string for authorization UI. @@ -57,20 +43,24 @@ UINT8 mHashOidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, // OBJ_sha512 }; -HASH_TABLE mHash[] = { - #ifndef DISABLE_SHA1_DEPRECATED_INTERFACES - { L"SHA1", 20, &mHashOidValue[0], 5, Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final }, - #else - { L"SHA1", 20, &mHashOidValue[0], 5, NULL, NULL, NULL, NULL }, - #endif - { L"SHA224", 28, &mHashOidValue[5], 9, NULL, NULL, NULL, NULL }, - { L"SHA256", 32, &mHashOidValue[14], 9, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final }, - { L"SHA384", 48, &mHashOidValue[23], 9, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final }, - { L"SHA512", 64, &mHashOidValue[32], 9, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final } +// +// Support hash types +// +#define HASHALG_SHA256 0x00000000 +#define HASHALG_SHA384 0x00000001 +#define HASHALG_SHA512 0x00000002 +#define HASHALG_SHA1 0x00000003 +#define HASHALG_MAX 0x00000004 + +HASH_TABLE mHash[] = { + { L"SHA256", 32, &mHashOidValue[14], 9, &gEfiCertSha256Guid, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final }, + { L"SHA384", 48, &mHashOidValue[23], 9, &gEfiCertSha384Guid, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final }, + { L"SHA512", 64, &mHashOidValue[32], 9, &gEfiCertSha512Guid, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final }, +#ifndef DISABLE_SHA1_DEPRECATED_INTERFACES + { L"SHA1", 20, &mHashOidValue[0], 5, &gEfiCertSha1Guid, Sha1GetContextSize, Sha1Init, Sha1Update, Sha1Final }, +#endif }; -EFI_STRING mHashTypeStr; - /** SecureBoot Hook for processing image verification. @@ -90,54 +80,6 @@ SecureBootHook ( IN VOID *Data ); -/** - Reads contents of a PE/COFF image in memory buffer. - - Caution: This function may receive untrusted input. - PE/COFF image is external input, so this function will make sure the PE/COFF image content - read is within the image buffer. - - @param FileHandle Pointer to the file handle to read the PE/COFF image. - @param FileOffset Offset into the PE/COFF image to begin the read operation. - @param ReadSize On input, the size in bytes of the requested read operation. - On output, the number of bytes actually read. - @param Buffer Output buffer that contains the data read from the PE/COFF image. - - @retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size -**/ -EFI_STATUS -EFIAPI -DxeImageVerificationLibImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer - ) -{ - UINTN EndPosition; - - if ((FileHandle == NULL) || (ReadSize == NULL) || (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (MAX_ADDRESS - FileOffset < *ReadSize) { - return EFI_INVALID_PARAMETER; - } - - EndPosition = FileOffset + *ReadSize; - if (EndPosition > mImageSize) { - *ReadSize = (UINT32)(mImageSize - FileOffset); - } - - if (FileOffset >= mImageSize) { - *ReadSize = 0; - } - - CopyMem (Buffer, (UINT8 *)((UINTN)FileHandle + FileOffset), *ReadSize); - - return EFI_SUCCESS; -} - /** Get the image type. @@ -279,7 +221,7 @@ GetImageType ( PE/COFF image is external input, so this function will validate its data structure within this image buffer before use. - Notes: PE/COFF image has been checked by BasePeCoffLib PeCoffLoaderGetImageInfo() in + Notes: PE/COFF image has been checked by UefiImageLibLib UefiImageInitializeContext() in its caller function DxeImageVerificationHandler(). @param[in] HashAlg Hash algorithm type. @@ -290,318 +232,54 @@ GetImageType ( **/ BOOLEAN HashPeImage ( - IN UINT32 HashAlg + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + IN HASH_TABLE *HashAlg, + OUT UINT8 ImageDigest[MAX_DIGEST_SIZE], + OUT UINTN *ImageDigestSize ) { - BOOLEAN Status; - EFI_IMAGE_SECTION_HEADER *Section; - VOID *HashCtx; - UINTN CtxSize; - UINT8 *HashBase; - UINTN HashSize; - UINTN SumOfBytesHashed; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - UINTN Index; - UINTN Pos; - UINT32 CertSize; - UINT32 NumberOfRvaAndSizes; - - HashCtx = NULL; - SectionHeader = NULL; - Status = FALSE; + BOOLEAN Status; + VOID *HashCtx; + UINTN CtxSize; - if ((HashAlg >= HASHALG_MAX)) { - return FALSE; - } + HashCtx = NULL; + Status = FALSE; // // Initialize context of hash. // - ZeroMem (mImageDigest, MAX_DIGEST_SIZE); - - switch (HashAlg) { - #ifndef DISABLE_SHA1_DEPRECATED_INTERFACES - case HASHALG_SHA1: - mImageDigestSize = SHA1_DIGEST_SIZE; - mCertType = gEfiCertSha1Guid; - break; - #endif - - case HASHALG_SHA256: - mImageDigestSize = SHA256_DIGEST_SIZE; - mCertType = gEfiCertSha256Guid; - break; - - case HASHALG_SHA384: - mImageDigestSize = SHA384_DIGEST_SIZE; - mCertType = gEfiCertSha384Guid; - break; - - case HASHALG_SHA512: - mImageDigestSize = SHA512_DIGEST_SIZE; - mCertType = gEfiCertSha512Guid; - break; - - default: - return FALSE; - } + ZeroMem (ImageDigest, MAX_DIGEST_SIZE); - mHashTypeStr = mHash[HashAlg].Name; - CtxSize = mHash[HashAlg].GetContextSize (); + CtxSize = HashAlg->GetContextSize (); HashCtx = AllocatePool (CtxSize); if (HashCtx == NULL) { return FALSE; } - // 1. Load the image header into memory. - - // 2. Initialize a SHA hash context. - Status = mHash[HashAlg].HashInit (HashCtx); + Status = HashAlg->HashInit (HashCtx); if (!Status) { goto Done; } - // - // Measuring PE/COFF Image Header; - // But CheckSum field and SECURITY data directory (certificate) are excluded - // - - // - // 3. Calculate the distance from the base of the image header to the image checksum address. - // 4. Hash the image header from its base to beginning of the image checksum. - // - HashBase = mImageBase; - if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - HashSize = (UINTN)(&mNtHeader.Pe32->OptionalHeader.CheckSum) - (UINTN)HashBase; - NumberOfRvaAndSizes = mNtHeader.Pe32->OptionalHeader.NumberOfRvaAndSizes; - } else if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - // - // Use PE32+ offset. - // - HashSize = (UINTN)(&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - (UINTN)HashBase; - NumberOfRvaAndSizes = mNtHeader.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes; - } else { - // - // Invalid header magic number. - // - Status = FALSE; - goto Done; - } + Status = UefiImageHashImageDefault (ImageContext, HashCtx, HashAlg->HashUpdate); - Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize); if (!Status) { + DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash this image using %s.\n", HashAlg->Name)); goto Done; } - // - // 5. Skip over the image checksum (it occupies a single ULONG). - // - if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) { - // - // 6. Since there is no Cert Directory in optional header, hash everything - // from the end of the checksum to the end of image header. - // - if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - HashBase = (UINT8 *)&mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - ((UINTN)HashBase - (UINTN)mImageBase); - } else { - // - // Use PE32+ offset. - // - HashBase = (UINT8 *)&mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - ((UINTN)HashBase - (UINTN)mImageBase); - } - - if (HashSize != 0) { - Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize); - if (!Status) { - goto Done; - } - } - } else { - // - // 7. Hash everything from the end of the checksum to the start of the Cert Directory. - // - if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - HashBase = (UINT8 *)&mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN)(&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; - } else { - // - // Use PE32+ offset. - // - HashBase = (UINT8 *)&mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN)(&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; - } - - if (HashSize != 0) { - Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize); - if (!Status) { - goto Done; - } - } - - // - // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.) - // 9. Hash everything from the end of the Cert Directory to the end of image header. - // - if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset - // - HashBase = (UINT8 *)&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - ((UINTN)HashBase - (UINTN)mImageBase); - } else { - // - // Use PE32+ offset. - // - HashBase = (UINT8 *)&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - ((UINTN)HashBase - (UINTN)mImageBase); - } + ASSERT (HashAlg->DigestLength <= MAX_DIGEST_SIZE); + Status = HashAlg->HashFinal(HashCtx, ImageDigest); - if (HashSize != 0) { - Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize); - if (!Status) { - goto Done; - } - } - } - - // - // 10. Set the SUM_OF_BYTES_HASHED to the size of the header. - // - if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - SumOfBytesHashed = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders; - } else { - // - // Use PE32+ offset - // - SumOfBytesHashed = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders; - } - - Section = (EFI_IMAGE_SECTION_HEADER *)( - mImageBase + - mPeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - mNtHeader.Pe32->FileHeader.SizeOfOptionalHeader - ); - - // - // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER - // structures in the image. The 'NumberOfSections' field of the image - // header indicates how big the table should be. Do not include any - // IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero. - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *)AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * mNtHeader.Pe32->FileHeader.NumberOfSections); - if (SectionHeader == NULL) { - Status = FALSE; - goto Done; - } - - // - // 12. Using the 'PointerToRawData' in the referenced section headers as - // a key, arrange the elements in the table in ascending order. In other - // words, sort the section headers according to the disk-file offset of - // the section. - // - for (Index = 0; Index < mNtHeader.Pe32->FileHeader.NumberOfSections; Index++) { - Pos = Index; - while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) { - CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof (EFI_IMAGE_SECTION_HEADER)); - Pos--; - } - - CopyMem (&SectionHeader[Pos], Section, sizeof (EFI_IMAGE_SECTION_HEADER)); - Section += 1; - } - - // - // 13. Walk through the sorted table, bring the corresponding section - // into memory, and hash the entire section (using the 'SizeOfRawData' - // field in the section header to determine the amount of data to hash). - // 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED . - // 15. Repeat steps 13 and 14 for all the sections in the sorted table. - // - for (Index = 0; Index < mNtHeader.Pe32->FileHeader.NumberOfSections; Index++) { - Section = &SectionHeader[Index]; - if (Section->SizeOfRawData == 0) { - continue; - } - - HashBase = mImageBase + Section->PointerToRawData; - HashSize = (UINTN)Section->SizeOfRawData; - - Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize); - if (!Status) { - goto Done; - } - - SumOfBytesHashed += HashSize; - } - - // - // 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra - // data in the file that needs to be added to the hash. This data begins - // at file offset SUM_OF_BYTES_HASHED and its length is: - // FileSize - (CertDirectory->Size) - // - if (mImageSize > SumOfBytesHashed) { - HashBase = mImageBase + SumOfBytesHashed; - - if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) { - CertSize = 0; - } else { - if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - CertSize = mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size; - } else { - // - // Use PE32+ offset. - // - CertSize = mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size; - } - } - - if (mImageSize > CertSize + SumOfBytesHashed) { - HashSize = (UINTN)(mImageSize - CertSize - SumOfBytesHashed); - - Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize); - if (!Status) { - goto Done; - } - } else if (mImageSize < CertSize + SumOfBytesHashed) { - Status = FALSE; - goto Done; - } - } - - Status = mHash[HashAlg].HashFinal (HashCtx, mImageDigest); + *ImageDigestSize = HashAlg->DigestLength; Done: if (HashCtx != NULL) { FreePool (HashCtx); } - if (SectionHeader != NULL) { - FreePool (SectionHeader); - } - return Status; } @@ -623,34 +301,38 @@ HashPeImage ( **/ EFI_STATUS HashPeImageByType ( - IN UINT8 *AuthData, - IN UINTN AuthDataSize + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + IN CONST UINT8 *AuthData, + IN UINTN AuthDataSize, + OUT UINT8 ImageDigest[MAX_DIGEST_SIZE], + OUT UINTN *ImageDigestSize, + OUT CONST EFI_GUID **CertType ) { UINT8 Index; - for (Index = 0; Index < HASHALG_MAX; Index++) { + // + // Check the Hash algorithm in PE/COFF Authenticode. + // According to PKCS#7 Definition: + // SignedData ::= SEQUENCE { + // version Version, + // digestAlgorithms DigestAlgorithmIdentifiers, + // contentInfo ContentInfo, + // .... } + // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing + // This field has the fixed offset (+32) in final Authenticode ASN.1 data. + // Fixed offset (+32) is calculated based on two bytes of length encoding. + // + if ((*(AuthData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE) { // - // Check the Hash algorithm in PE/COFF Authenticode. - // According to PKCS#7 Definition: - // SignedData ::= SEQUENCE { - // version Version, - // digestAlgorithms DigestAlgorithmIdentifiers, - // contentInfo ContentInfo, - // .... } - // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing - // This field has the fixed offset (+32) in final Authenticode ASN.1 data. - // Fixed offset (+32) is calculated based on two bytes of length encoding. + // Only support two bytes of Long Form of Length Encoding. // - if ((*(AuthData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE) { - // - // Only support two bytes of Long Form of Length Encoding. - // - continue; - } + return EFI_UNSUPPORTED; + } + for (Index = 0; Index < HASHALG_MAX; Index++) { if (AuthDataSize < 32 + mHash[Index].OidLength) { - return EFI_UNSUPPORTED; + continue; } if (CompareMem (AuthData + 32, mHash[Index].OidValue, mHash[Index].OidLength) == 0) { @@ -665,10 +347,12 @@ HashPeImageByType ( // // HASH PE Image based on Hash algorithm in PE/COFF Authenticode. // - if (!HashPeImage (Index)) { + if (!HashPeImage (ImageContext, &mHash[Index], ImageDigest, ImageDigestSize)) { return EFI_UNSUPPORTED; } + *CertType = mHash[Index].CertType; + return EFI_SUCCESS; } @@ -911,15 +595,15 @@ IsCertHashFoundInDbx ( goto Done; } - if (!mHash[HashAlg].HashInit (HashCtx)) { + if (EFI_ERROR(mHash[HashAlg].HashInit (HashCtx))) { goto Done; } - if (!mHash[HashAlg].HashUpdate (HashCtx, TBSCert, TBSCertSize)) { + if (EFI_ERROR(mHash[HashAlg].HashUpdate (HashCtx, TBSCert, TBSCertSize))) { goto Done; } - if (!mHash[HashAlg].HashFinal (HashCtx, CertDigest)) { + if (EFI_ERROR(mHash[HashAlg].HashFinal (HashCtx, CertDigest))) { goto Done; } @@ -980,11 +664,11 @@ IsCertHashFoundInDbx ( **/ EFI_STATUS IsSignatureFoundInDatabase ( - IN CHAR16 *VariableName, - IN UINT8 *Signature, - IN EFI_GUID *CertType, - IN UINTN SignatureSize, - OUT BOOLEAN *IsFound + IN CHAR16 *VariableName, + IN UINT8 *Signature, + IN CONST EFI_GUID *CertType, + IN UINTN SignatureSize, + OUT BOOLEAN *IsFound ) { EFI_STATUS Status; @@ -1137,9 +821,9 @@ IsTimeZero ( **/ BOOLEAN PassTimestampCheck ( - IN UINT8 *AuthData, - IN UINTN AuthDataSize, - IN EFI_TIME *RevocationTime + IN CONST UINT8 *AuthData, + IN UINTN AuthDataSize, + IN EFI_TIME *RevocationTime ) { EFI_STATUS Status; @@ -1244,8 +928,10 @@ PassTimestampCheck ( **/ BOOLEAN IsForbiddenByDbx ( - IN UINT8 *AuthData, - IN UINTN AuthDataSize + IN CONST UINT8 *AuthData, + IN UINTN AuthDataSize, + UINT8 ImageDigest[MAX_DIGEST_SIZE], + UINTN ImageDigestSize ) { EFI_STATUS Status; @@ -1338,8 +1024,8 @@ IsForbiddenByDbx ( AuthDataSize, RootCert, RootCertSize, - mImageDigest, - mImageDigestSize + ImageDigest, + ImageDigestSize ); if (IsForbidden) { DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature is forbidden by DBX.\n")); @@ -1440,8 +1126,10 @@ IsForbiddenByDbx ( **/ BOOLEAN IsAllowedByDb ( - IN UINT8 *AuthData, - IN UINTN AuthDataSize + IN CONST UINT8 *AuthData, + IN UINTN AuthDataSize, + OUT UINT8 ImageDigest[MAX_DIGEST_SIZE], + OUT UINTN ImageDigestSize ) { EFI_STATUS Status; @@ -1543,8 +1231,8 @@ IsAllowedByDb ( AuthDataSize, RootCert, RootCertSize, - mImageDigest, - mImageDigestSize + ImageDigest, + ImageDigestSize ); if (VerifyStatus) { // @@ -1663,28 +1351,16 @@ DxeImageVerificationHandler ( IN BOOLEAN BootPolicy ) { - EFI_IMAGE_DOS_HEADER *DosHdr; BOOLEAN IsVerified; EFI_SIGNATURE_LIST *SignatureList; UINTN SignatureListSize; EFI_SIGNATURE_DATA *Signature; EFI_IMAGE_EXECUTION_ACTION Action; - WIN_CERTIFICATE *WinCertificate; UINT32 Policy; UINT8 SecureBoot; UINTN SecureBootSize; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - UINT32 NumberOfRvaAndSizes; - WIN_CERTIFICATE_EFI_PKCS *PkcsCertData; - WIN_CERTIFICATE_UEFI_GUID *WinCertUefiGuid; - UINT8 *AuthData; UINTN AuthDataSize; - EFI_IMAGE_DATA_DIRECTORY *SecDataDir; - UINT32 SecDataDirEnd; - UINT32 SecDataDirLeft; - UINT32 OffSet; CHAR16 *NameStr; - RETURN_STATUS PeCoffStatus; EFI_STATUS HashStatus; EFI_STATUS DbStatus; EFI_STATUS VarStatus; @@ -1693,16 +1369,29 @@ DxeImageVerificationHandler ( UINT8 HashAlg; BOOLEAN IsFoundInDatabase; + CONST WIN_CERTIFICATE *WinCertificate; + CONST WIN_CERTIFICATE_EFI_PKCS *PkcsCertData; + CONST WIN_CERTIFICATE_UEFI_GUID *WinCertUefiGuid; + CONST UINT8 *AuthData; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext; + + UINT8 ImageDigest[MAX_DIGEST_SIZE]; + UINTN ImageDigestSize; + CONST EFI_GUID *CertType; + SignatureList = NULL; SignatureListSize = 0; WinCertificate = NULL; - SecDataDir = NULL; PkcsCertData = NULL; Action = EFI_IMAGE_EXECUTION_AUTH_UNTESTED; IsVerified = FALSE; IsFound = FALSE; IsFoundInDatabase = FALSE; + // FIXME: + ASSERT (FileSize == sizeof (UEFI_IMAGE_LOADER_IMAGE_CONTEXT)); + ImageContext = FileBuffer; + // // Check the image type and get policy setting. // @@ -1775,70 +1464,12 @@ DxeImageVerificationHandler ( return EFI_ACCESS_DENIED; } - mImageBase = (UINT8 *)FileBuffer; - mImageSize = FileSize; - - ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.Handle = (VOID *)FileBuffer; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)DxeImageVerificationLibImageRead; - - // - // Get information about the image being loaded - // - PeCoffStatus = PeCoffLoaderGetImageInfo (&ImageContext); - if (RETURN_ERROR (PeCoffStatus)) { - // - // The information can't be got from the invalid PeImage - // - DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: PeImage invalid. Cannot retrieve image information.\n")); - goto Failed; - } - - DosHdr = (EFI_IMAGE_DOS_HEADER *)mImageBase; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, - // so read the PE header after the DOS image header. - // - mPeCoffHeaderOffset = DosHdr->e_lfanew; - } else { - mPeCoffHeaderOffset = 0; - } - - // - // Check PE/COFF image. - // - mNtHeader.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(mImageBase + mPeCoffHeaderOffset); - if (mNtHeader.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { - // - // It is not a valid Pe/Coff file. - // - DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Not a valid PE/COFF image.\n")); - goto Failed; - } - - if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - NumberOfRvaAndSizes = mNtHeader.Pe32->OptionalHeader.NumberOfRvaAndSizes; - if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) { - SecDataDir = (EFI_IMAGE_DATA_DIRECTORY *)&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]; - } - } else { - // - // Use PE32+ offset. - // - NumberOfRvaAndSizes = mNtHeader.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes; - if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) { - SecDataDir = (EFI_IMAGE_DATA_DIRECTORY *)&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]; - } - } + HashStatus = UefiImageGetFirstCertificate (ImageContext, &WinCertificate); // // Start Image Validation. // - if ((SecDataDir == NULL) || (SecDataDir->Size == 0)) { + if (HashStatus == RETURN_NOT_FOUND) { // // This image is not signed. The hash value of the image must match a record in the security database "db", // and not be reflected in the security data base "dbx". @@ -1850,30 +1481,32 @@ DxeImageVerificationHandler ( continue; } - if (!HashPeImage (HashAlg)) { + if (!HashPeImage (ImageContext, &mHash[HashAlg], ImageDigest, &ImageDigestSize)) { continue; } + CertType = mHash[HashAlg].CertType; + DbStatus = IsSignatureFoundInDatabase ( EFI_IMAGE_SECURITY_DATABASE1, - mImageDigest, - &mCertType, - mImageDigestSize, + ImageDigest, + CertType, + ImageDigestSize, &IsFound ); if (EFI_ERROR (DbStatus) || IsFound) { // // Image Hash is in forbidden database (DBX). // - DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is forbidden by DBX.\n", mHashTypeStr)); + DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and hash of image is forbidden by DBX.\n")); goto Failed; } DbStatus = IsSignatureFoundInDatabase ( EFI_IMAGE_SECURITY_DATABASE, - mImageDigest, - &mCertType, - mImageDigestSize, + ImageDigest, + CertType, + ImageDigestSize, &IsFound ); if (!EFI_ERROR (DbStatus) && IsFound) { @@ -1891,7 +1524,7 @@ DxeImageVerificationHandler ( // // Image Hash is not found in both forbidden and allowed database. // - DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and %s hash of image is not found in DB/DBX.\n", mHashTypeStr)); + DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is not signed and hash of image is not found in DB/DBX.\n")); goto Failed; } @@ -1900,24 +1533,12 @@ DxeImageVerificationHandler ( // "Attribute Certificate Table". // The first certificate starts at offset (SecDataDir->VirtualAddress) from the start of the file. // - SecDataDirEnd = SecDataDir->VirtualAddress + SecDataDir->Size; - for (OffSet = SecDataDir->VirtualAddress; - OffSet < SecDataDirEnd; - OffSet += (WinCertificate->dwLength + ALIGN_SIZE (WinCertificate->dwLength))) + for ( + ; + !RETURN_ERROR (HashStatus); + HashStatus = UefiImageGetNextCertificate (ImageContext, &WinCertificate) + ) { - SecDataDirLeft = SecDataDirEnd - OffSet; - if (SecDataDirLeft <= sizeof (WIN_CERTIFICATE)) { - break; - } - - WinCertificate = (WIN_CERTIFICATE *)(mImageBase + OffSet); - if ((SecDataDirLeft < WinCertificate->dwLength) || - (SecDataDirLeft - WinCertificate->dwLength < - ALIGN_SIZE (WinCertificate->dwLength))) - { - break; - } - // // Verify the image's Authenticode signature, only DER-encoded PKCS#7 signed data is supported. // @@ -1926,7 +1547,7 @@ DxeImageVerificationHandler ( // The certificate is formatted as WIN_CERTIFICATE_EFI_PKCS which is described in the // Authenticode specification. // - PkcsCertData = (WIN_CERTIFICATE_EFI_PKCS *)WinCertificate; + PkcsCertData = (CONST WIN_CERTIFICATE_EFI_PKCS *)WinCertificate; if (PkcsCertData->Hdr.dwLength <= sizeof (PkcsCertData->Hdr)) { break; } @@ -1937,26 +1558,23 @@ DxeImageVerificationHandler ( // // The certificate is formatted as WIN_CERTIFICATE_UEFI_GUID which is described in UEFI Spec. // - WinCertUefiGuid = (WIN_CERTIFICATE_UEFI_GUID *)WinCertificate; - if (WinCertUefiGuid->Hdr.dwLength <= OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)) { - break; - } + WinCertUefiGuid = (CONST WIN_CERTIFICATE_UEFI_GUID *)WinCertificate; if (!CompareGuid (&WinCertUefiGuid->CertType, &gEfiCertPkcs7Guid)) { continue; } + if (WinCertUefiGuid->Hdr.dwLength <= OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData)) { + break; + } AuthData = WinCertUefiGuid->CertData; AuthDataSize = WinCertUefiGuid->Hdr.dwLength - OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData); } else { - if (WinCertificate->dwLength < sizeof (WIN_CERTIFICATE)) { - break; - } continue; } - HashStatus = HashPeImageByType (AuthData, AuthDataSize); + HashStatus = HashPeImageByType (ImageContext, AuthData, AuthDataSize, ImageDigest, &ImageDigestSize, &CertType); if (EFI_ERROR (HashStatus)) { continue; } @@ -1964,17 +1582,16 @@ DxeImageVerificationHandler ( // // Check the digital signature against the revoked certificate in forbidden database (dbx). // - if (IsForbiddenByDbx (AuthData, AuthDataSize)) { + if (IsForbiddenByDbx (AuthData, AuthDataSize, ImageDigest, ImageDigestSize)) { Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED; IsVerified = FALSE; - break; } // // Check the digital signature against the valid certificate in allowed database (db). // if (!IsVerified) { - if (IsAllowedByDb (AuthData, AuthDataSize)) { + if (IsAllowedByDb (AuthData, AuthDataSize, ImageDigest, ImageDigestSize)) { IsVerified = TRUE; } } @@ -1984,14 +1601,14 @@ DxeImageVerificationHandler ( // DbStatus = IsSignatureFoundInDatabase ( EFI_IMAGE_SECURITY_DATABASE1, - mImageDigest, - &mCertType, - mImageDigestSize, + ImageDigest, + CertType, + ImageDigestSize, &IsFound ); if (EFI_ERROR (DbStatus) || IsFound) { Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND; - DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but %s hash of image is found in DBX.\n", mHashTypeStr)); + DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but hash of image is found in DBX.\n")); IsVerified = FALSE; break; } @@ -1999,36 +1616,28 @@ DxeImageVerificationHandler ( if (!IsVerified) { DbStatus = IsSignatureFoundInDatabase ( EFI_IMAGE_SECURITY_DATABASE, - mImageDigest, - &mCertType, - mImageDigestSize, + ImageDigest, + CertType, + ImageDigestSize, &IsFound ); if (!EFI_ERROR (DbStatus) && IsFound) { IsVerified = TRUE; } else { Action = EFI_IMAGE_EXECUTION_AUTH_SIG_NOT_FOUND; - DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature is not allowed by DB and %s hash of image is not found in DB/DBX.\n", mHashTypeStr)); + DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Image is signed but signature is not allowed by DB and hash of image is not found in DB/DBX.\n")); } } } - if (OffSet != SecDataDirEnd) { - // - // The Size in Certificate Table or the attribute certificate table is corrupted. - // - IsVerified = FALSE; - } - if (IsVerified) { return EFI_SUCCESS; } - if ((Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED) || (Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND)) { // // Get image hash value as signature of executable. // - SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize; + SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + ImageDigestSize; SignatureList = (EFI_SIGNATURE_LIST *)AllocateZeroPool (SignatureListSize); if (SignatureList == NULL) { SignatureListSize = 0; @@ -2037,10 +1646,10 @@ DxeImageVerificationHandler ( SignatureList->SignatureHeaderSize = 0; SignatureList->SignatureListSize = (UINT32)SignatureListSize; - SignatureList->SignatureSize = (UINT32)(sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize); - CopyMem (&SignatureList->SignatureType, &mCertType, sizeof (EFI_GUID)); + SignatureList->SignatureSize = (UINT32)(sizeof (EFI_SIGNATURE_DATA) - 1 + ImageDigestSize); + CopyMem (&SignatureList->SignatureType, CertType, sizeof (EFI_GUID)); Signature = (EFI_SIGNATURE_DATA *)((UINT8 *)SignatureList + sizeof (EFI_SIGNATURE_LIST)); - CopyMem (Signature->SignatureData, mImageDigest, mImageDigestSize); + CopyMem (Signature->SignatureData, ImageDigest, ImageDigestSize); } Failed: @@ -2078,8 +1687,8 @@ DxeImageVerificationHandler ( VOID EFIAPI OnReadyToBoot ( - IN EFI_EVENT Event, - IN VOID *Context + IN EFI_EVENT Event, + IN VOID *Context ) { EFI_IMAGE_EXECUTION_INFO_TABLE *ImageExeInfoTable; diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.h b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.h index 53fe34358c..903ffd3f29 100644 --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.h +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.h @@ -22,7 +22,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +#include #include #include #include @@ -30,7 +30,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +#include #define EFI_CERT_TYPE_RSA2048_SHA256_SIZE 256 #define EFI_CERT_TYPE_RSA2048_SIZE 256 @@ -59,16 +59,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define DENY_EXECUTE_ON_SECURITY_VIOLATION 0x00000004 #define QUERY_USER_ON_SECURITY_VIOLATION 0x00000005 -// -// Support hash types -// -#define HASHALG_SHA1 0x00000000 -#define HASHALG_SHA224 0x00000001 -#define HASHALG_SHA256 0x00000002 -#define HASHALG_SHA384 0x00000003 -#define HASHALG_SHA512 0x00000004 -#define HASHALG_MAX 0x00000005 - // // Set max digest size as SHA512 Output (64 bytes) by far // @@ -178,6 +168,10 @@ typedef struct { // UINTN OidLength; // + // GUID of the certificate type + // + CONST GUID *CertType; + // // Pointer to Hash GetContentSize function // HASH_GET_CONTEXT_SIZE GetContextSize; diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf index 1e1a639857..3b944cddf9 100644 --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf @@ -51,7 +51,7 @@ DevicePathLib BaseCryptLib SecurityManagementLib - PeCoffLib + UefiImageLib TpmMeasurementLib [Protocols] @@ -75,6 +75,10 @@ ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the signature. gEfiCertSha256Guid + ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature. + ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the signature. + gEfiCertSha224Guid + ## SOMETIMES_CONSUMES ## GUID # Unique ID for the type of the signature. ## SOMETIMES_PRODUCES ## GUID # Unique ID for the type of the signature. gEfiCertSha384Guid diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c index 73719f3b96..c963739c17 100644 --- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c +++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.c @@ -7,9 +7,6 @@ This external input must be validated carefully to avoid security issue like buffer overflow, integer overflow. - DxeTpm2MeasureBootLibImageRead() function will make sure the PE/COFF image content - read is within the image buffer. - Tcg2MeasurePeImage() function will accept untrusted PE/COFF image and validate its data structure within this image buffer before use. @@ -41,7 +38,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +#include #include #include #include @@ -58,62 +55,12 @@ typedef struct { // BOOLEAN mTcg2MeasureGptTableFlag = FALSE; UINTN mTcg2MeasureGptCount = 0; -VOID *mTcg2FileBuffer; -UINTN mTcg2ImageSize; // // Measured FV handle cache // EFI_HANDLE mTcg2CacheMeasuredHandle = NULL; MEASURED_HOB_DATA *mTcg2MeasuredHobData = NULL; -/** - Reads contents of a PE/COFF image in memory buffer. - - Caution: This function may receive untrusted input. - PE/COFF image is external input, so this function will make sure the PE/COFF image content - read is within the image buffer. - - @param FileHandle Pointer to the file handle to read the PE/COFF image. - @param FileOffset Offset into the PE/COFF image to begin the read operation. - @param ReadSize On input, the size in bytes of the requested read operation. - On output, the number of bytes actually read. - @param Buffer Output buffer that contains the data read from the PE/COFF image. - - @retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size -**/ -EFI_STATUS -EFIAPI -DxeTpm2MeasureBootLibImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer - ) -{ - UINTN EndPosition; - - if ((FileHandle == NULL) || (ReadSize == NULL) || (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (MAX_ADDRESS - FileOffset < *ReadSize) { - return EFI_INVALID_PARAMETER; - } - - EndPosition = FileOffset + *ReadSize; - if (EndPosition > mTcg2ImageSize) { - *ReadSize = (UINT32)(mTcg2ImageSize - FileOffset); - } - - if (FileOffset >= mTcg2ImageSize) { - *ReadSize = 0; - } - - CopyMem (Buffer, (UINT8 *)((UINTN)FileHandle + FileOffset), *ReadSize); - - return EFI_SUCCESS; -} - /** Measure GPT table data into TPM log. @@ -640,11 +587,15 @@ DxeTpm2MeasureBootHandler ( EFI_HANDLE Handle; EFI_HANDLE TempHandle; BOOLEAN ApplicationRequired; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext; EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol; EFI_PHYSICAL_ADDRESS FvAddress; UINT32 Index; + // FIXME: + ASSERT (FileSize == sizeof (UEFI_IMAGE_LOADER_IMAGE_CONTEXT)); + ImageContext = FileBuffer; + MeasureBootProtocols.Tcg2Protocol = NULL; MeasureBootProtocols.CcProtocol = NULL; @@ -806,42 +757,17 @@ DxeTpm2MeasureBootHandler ( goto Finish; } - mTcg2ImageSize = FileSize; - mTcg2FileBuffer = FileBuffer; - // // Measure PE Image // DevicePathNode = OrigDevicePathNode; - ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.Handle = (VOID *)FileBuffer; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)DxeTpm2MeasureBootLibImageRead; - - // - // Get information about the image being loaded - // - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - // - // Check for invalid parameters. - // - if (File == NULL) { - Status = EFI_ACCESS_DENIED; - } - - // - // The information can't be got from the invalid PeImage - // - goto Finish; - } // // Measure only application if Application flag is set // Measure drivers and applications if Application flag is not set // if ((!ApplicationRequired) || - (ApplicationRequired && (ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION))) - { + (ApplicationRequired && UefiImageGetSubsystem (ImageContext) == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)) { // // Print the image path to be measured. // @@ -862,12 +788,13 @@ DxeTpm2MeasureBootHandler ( // // Measure PE image into TPM log. // + // FIXME: Pass context? Status = Tcg2MeasurePeImage ( &MeasureBootProtocols, (EFI_PHYSICAL_ADDRESS)(UINTN)FileBuffer, FileSize, - (UINTN)ImageContext.ImageAddress, - ImageContext.ImageType, + UefiImageLoaderGetImageAddress (ImageContext), + UefiImageGetSubsystem (ImageContext), DevicePathNode ); } diff --git a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf index 28995f438d..713c56b1ab 100644 --- a/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf +++ b/SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf @@ -54,7 +54,7 @@ DevicePathLib UefiBootServicesTableLib BaseCryptLib - PeCoffLib + UefiImageLib BaseLib SecurityManagementLib HobLib diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c index ac855b8fbb..fb06a8112b 100644 --- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c +++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.c @@ -6,9 +6,6 @@ This external input must be validated carefully to avoid security issue like buffer overflow, integer overflow. - DxeTpmMeasureBootLibImageRead() function will make sure the PE/COFF image content - read is within the image buffer. - TcgMeasurePeImage() function will accept untrusted PE/COFF image and validate its data structure within this image buffer before use. @@ -39,7 +36,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +#include #include #include @@ -50,62 +47,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // BOOLEAN mMeasureGptTableFlag = FALSE; UINTN mMeasureGptCount = 0; -VOID *mFileBuffer; -UINTN mTpmImageSize; // // Measured FV handle cache // EFI_HANDLE mCacheMeasuredHandle = NULL; MEASURED_HOB_DATA *mMeasuredHobData = NULL; -/** - Reads contents of a PE/COFF image in memory buffer. - - Caution: This function may receive untrusted input. - PE/COFF image is external input, so this function will make sure the PE/COFF image content - read is within the image buffer. - - @param FileHandle Pointer to the file handle to read the PE/COFF image. - @param FileOffset Offset into the PE/COFF image to begin the read operation. - @param ReadSize On input, the size in bytes of the requested read operation. - On output, the number of bytes actually read. - @param Buffer Output buffer that contains the data read from the PE/COFF image. - - @retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size -**/ -EFI_STATUS -EFIAPI -DxeTpmMeasureBootLibImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer - ) -{ - UINTN EndPosition; - - if ((FileHandle == NULL) || (ReadSize == NULL) || (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (MAX_ADDRESS - FileOffset < *ReadSize) { - return EFI_INVALID_PARAMETER; - } - - EndPosition = FileOffset + *ReadSize; - if (EndPosition > mTpmImageSize) { - *ReadSize = (UINT32)(mTpmImageSize - FileOffset); - } - - if (FileOffset >= mTpmImageSize) { - *ReadSize = 0; - } - - CopyMem (Buffer, (UINT8 *)((UINTN)FileHandle + FileOffset), *ReadSize); - - return EFI_SUCCESS; -} - /** Measure GPT table data into TPM log. @@ -292,7 +239,7 @@ TcgMeasureGptTable ( PE/COFF image is external input, so this function will validate its data structure within this image buffer before use. - Notes: PE/COFF image has been checked by BasePeCoffLib PeCoffLoaderGetImageInfo() in + Notes: PE/COFF image has been checked by UefiImageLibLib UefiImageInitializeContext() in its caller function DxeTpmMeasureBootHandler(). @param[in] TcgProtocol Pointer to the located TCG protocol instance. @@ -311,12 +258,11 @@ TcgMeasureGptTable ( EFI_STATUS EFIAPI TcgMeasurePeImage ( - IN EFI_TCG_PROTOCOL *TcgProtocol, - IN EFI_PHYSICAL_ADDRESS ImageAddress, - IN UINTN ImageSize, - IN UINTN LinkTimeBase, - IN UINT16 ImageType, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath + IN EFI_TCG_PROTOCOL *TcgProtocol, + IN EFI_PHYSICAL_ADDRESS ImageAddress, + IN UINTN ImageSize, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath ) { EFI_STATUS Status; @@ -325,22 +271,12 @@ TcgMeasurePeImage ( UINT32 FilePathSize; VOID *Sha1Ctx; UINTN CtxSize; - EFI_IMAGE_DOS_HEADER *DosHdr; - UINT32 PeCoffHeaderOffset; - EFI_IMAGE_SECTION_HEADER *Section; - UINT8 *HashBase; - UINTN HashSize; - UINTN SumOfBytesHashed; EFI_IMAGE_SECTION_HEADER *SectionHeader; - UINTN Index; - UINTN Pos; UINT32 EventSize; UINT32 EventNumber; EFI_PHYSICAL_ADDRESS EventLogLastEntry; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - UINT32 NumberOfRvaAndSizes; BOOLEAN HashStatus; - UINT32 CertSize; + UINT16 ImageType; Status = EFI_UNSUPPORTED; ImageLoad = NULL; @@ -364,6 +300,8 @@ TcgMeasurePeImage ( TcgEvent->EventSize = EventSize - sizeof (TCG_PCR_EVENT_HDR); ImageLoad = (EFI_IMAGE_LOAD_EVENT *)TcgEvent->Event; + ImageType = UefiImageGetSubsystem (ImageContext); + switch (ImageType) { case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION: TcgEvent->EventType = EV_EFI_BOOT_SERVICES_APPLICATION; @@ -390,26 +328,12 @@ TcgMeasurePeImage ( ImageLoad->ImageLocationInMemory = ImageAddress; ImageLoad->ImageLengthInMemory = ImageSize; - ImageLoad->ImageLinkTimeAddress = LinkTimeBase; + ImageLoad->ImageLinkTimeAddress = UefiImageLoaderGetImageAddress (ImageContext); ImageLoad->LengthOfDevicePath = FilePathSize; if ((FilePath != NULL) && (FilePathSize != 0)) { CopyMem (ImageLoad->DevicePath, FilePath, FilePathSize); } - // - // Check PE/COFF image - // - DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageAddress; - PeCoffHeaderOffset = 0; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - PeCoffHeaderOffset = DosHdr->e_lfanew; - } - - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset); - if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { - goto Finish; - } - // // PE/COFF Image Measurement // @@ -418,9 +342,7 @@ TcgMeasurePeImage ( // // - // 1. Load the image header into memory. - - // 2. Initialize a SHA hash context. + // Initialize a SHA hash context. CtxSize = Sha1GetContextSize (); Sha1Ctx = AllocatePool (CtxSize); if (Sha1Ctx == NULL) { @@ -438,220 +360,7 @@ TcgMeasurePeImage ( // But CheckSum field and SECURITY data directory (certificate) are excluded // - // - // 3. Calculate the distance from the base of the image header to the image checksum address. - // 4. Hash the image header from its base to beginning of the image checksum. - // - HashBase = (UINT8 *)(UINTN)ImageAddress; - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset - // - NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes; - HashSize = (UINTN)(&Hdr.Pe32->OptionalHeader.CheckSum) - (UINTN)HashBase; - } else { - // - // Use PE32+ offset - // - NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes; - HashSize = (UINTN)(&Hdr.Pe32Plus->OptionalHeader.CheckSum) - (UINTN)HashBase; - } - - HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); - if (!HashStatus) { - goto Finish; - } - - // - // 5. Skip over the image checksum (it occupies a single ULONG). - // - if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) { - // - // 6. Since there is no Cert Directory in optional header, hash everything - // from the end of the checksum to the end of image header. - // - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - HashBase = (UINT8 *)&Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); - } else { - // - // Use PE32+ offset. - // - HashBase = (UINT8 *)&Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); - } - - if (HashSize != 0) { - HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); - if (!HashStatus) { - goto Finish; - } - } - } else { - // - // 7. Hash everything from the end of the checksum to the start of the Cert Directory. - // - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset - // - HashBase = (UINT8 *)&Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; - } else { - // - // Use PE32+ offset - // - HashBase = (UINT8 *)&Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; - } - - if (HashSize != 0) { - HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); - if (!HashStatus) { - goto Finish; - } - } - - // - // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.) - // 9. Hash everything from the end of the Cert Directory to the end of image header. - // - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset - // - HashBase = (UINT8 *)&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); - } else { - // - // Use PE32+ offset - // - HashBase = (UINT8 *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); - } - - if (HashSize != 0) { - HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); - if (!HashStatus) { - goto Finish; - } - } - } - - // - // 10. Set the SUM_OF_BYTES_HASHED to the size of the header - // - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset - // - SumOfBytesHashed = Hdr.Pe32->OptionalHeader.SizeOfHeaders; - } else { - // - // Use PE32+ offset - // - SumOfBytesHashed = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders; - } - - // - // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER - // structures in the image. The 'NumberOfSections' field of the image - // header indicates how big the table should be. Do not include any - // IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero. - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *)AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * Hdr.Pe32->FileHeader.NumberOfSections); - if (SectionHeader == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Finish; - } - - // - // 12. Using the 'PointerToRawData' in the referenced section headers as - // a key, arrange the elements in the table in ascending order. In other - // words, sort the section headers according to the disk-file offset of - // the section. - // - Section = (EFI_IMAGE_SECTION_HEADER *)( - (UINT8 *)(UINTN)ImageAddress + - PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - Hdr.Pe32->FileHeader.SizeOfOptionalHeader - ); - for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) { - Pos = Index; - while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) { - CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof (EFI_IMAGE_SECTION_HEADER)); - Pos--; - } - - CopyMem (&SectionHeader[Pos], Section, sizeof (EFI_IMAGE_SECTION_HEADER)); - Section += 1; - } - - // - // 13. Walk through the sorted table, bring the corresponding section - // into memory, and hash the entire section (using the 'SizeOfRawData' - // field in the section header to determine the amount of data to hash). - // 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED . - // 15. Repeat steps 13 and 14 for all the sections in the sorted table. - // - for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) { - Section = (EFI_IMAGE_SECTION_HEADER *)&SectionHeader[Index]; - if (Section->SizeOfRawData == 0) { - continue; - } - - HashBase = (UINT8 *)(UINTN)ImageAddress + Section->PointerToRawData; - HashSize = (UINTN)Section->SizeOfRawData; - - HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); - if (!HashStatus) { - goto Finish; - } - - SumOfBytesHashed += HashSize; - } - - // - // 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra - // data in the file that needs to be added to the hash. This data begins - // at file offset SUM_OF_BYTES_HASHED and its length is: - // FileSize - (CertDirectory->Size) - // - if (ImageSize > SumOfBytesHashed) { - HashBase = (UINT8 *)(UINTN)ImageAddress + SumOfBytesHashed; - - if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) { - CertSize = 0; - } else { - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - CertSize = Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size; - } else { - // - // Use PE32+ offset. - // - CertSize = Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size; - } - } - - if (ImageSize > CertSize + SumOfBytesHashed) { - HashSize = (UINTN)(ImageSize - CertSize - SumOfBytesHashed); - - HashStatus = Sha1Update (Sha1Ctx, HashBase, HashSize); - if (!HashStatus) { - goto Finish; - } - } else if (ImageSize < CertSize + SumOfBytesHashed) { - goto Finish; - } - } + UefiImageHashImageDefault (ImageContext, Sha1Ctx, Sha1Update); // // 17. Finalize the SHA hash. @@ -756,11 +465,15 @@ DxeTpmMeasureBootHandler ( EFI_HANDLE Handle; EFI_HANDLE TempHandle; BOOLEAN ApplicationRequired; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext; EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol; EFI_PHYSICAL_ADDRESS FvAddress; UINT32 Index; + // FIXME: + ASSERT (FileSize == sizeof (UEFI_IMAGE_LOADER_IMAGE_CONTEXT)); + ImageContext = FileBuffer; + Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **)&TcgProtocol); if (EFI_ERROR (Status)) { // @@ -922,42 +635,17 @@ DxeTpmMeasureBootHandler ( goto Finish; } - mTpmImageSize = FileSize; - mFileBuffer = FileBuffer; - // // Measure PE Image // DevicePathNode = OrigDevicePathNode; - ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.Handle = (VOID *)FileBuffer; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)DxeTpmMeasureBootLibImageRead; - - // - // Get information about the image being loaded - // - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - // - // Check for invalid parameters. - // - if (File == NULL) { - return EFI_ACCESS_DENIED; - } - - // - // The information can't be got from the invalid PeImage - // - goto Finish; - } // // Measure only application if Application flag is set // Measure drivers and applications if Application flag is not set // if ((!ApplicationRequired) || - (ApplicationRequired && (ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION))) - { + (ApplicationRequired && UefiImageGetSubsystem (ImageContext) == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)) { // // Print the image path to be measured. // @@ -982,8 +670,7 @@ DxeTpmMeasureBootHandler ( TcgProtocol, (EFI_PHYSICAL_ADDRESS)(UINTN)FileBuffer, FileSize, - (UINTN)ImageContext.ImageAddress, - ImageContext.ImageType, + ImageContext, DevicePathNode ); } diff --git a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf index 414c654d15..ffe925af25 100644 --- a/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf +++ b/SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf @@ -49,7 +49,7 @@ DevicePathLib UefiBootServicesTableLib BaseCryptLib - PeCoffLib + UefiImageLib BaseLib SecurityManagementLib HobLib diff --git a/SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.c b/SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.c index c786c2189c..5de9ac1762 100644 --- a/SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.c +++ b/SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.c @@ -56,7 +56,9 @@ Sha1HashInit ( CtxSize = Sha1GetContextSize (); Sha1Ctx = AllocatePool (CtxSize); - ASSERT (Sha1Ctx != NULL); + if (Sha1Ctx == NULL) { + return EFI_OUT_OF_RESOURCES; + } Sha1Init (Sha1Ctx); @@ -82,10 +84,7 @@ Sha1HashUpdate ( IN UINTN DataToHashLen ) { - VOID *Sha1Ctx; - - Sha1Ctx = (VOID *)HashHandle; - Sha1Update (Sha1Ctx, DataToHash, DataToHashLen); + Sha1Update ((VOID *)HashHandle, DataToHash, DataToHashLen); return EFI_SUCCESS; } @@ -101,17 +100,15 @@ Sha1HashUpdate ( EFI_STATUS EFIAPI Sha1HashFinal ( - IN HASH_HANDLE HashHandle, + IN HASH_HANDLE HashHandle, OUT TPML_DIGEST_VALUES *DigestList ) { UINT8 Digest[SHA1_DIGEST_SIZE]; - VOID *Sha1Ctx; - Sha1Ctx = (VOID *)HashHandle; - Sha1Final (Sha1Ctx, Digest); + Sha1Final ((VOID *)HashHandle, Digest); - FreePool (Sha1Ctx); + FreePool ((VOID *)HashHandle); Tpm2SetSha1ToDigestList (DigestList, Digest); diff --git a/SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.c b/SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.c index 4387740001..57c8c9590a 100644 --- a/SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.c +++ b/SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.c @@ -56,7 +56,9 @@ Sha256HashInit ( CtxSize = Sha256GetContextSize (); Sha256Ctx = AllocatePool (CtxSize); - ASSERT (Sha256Ctx != NULL); + if (Sha256Ctx == NULL) { + return EFI_OUT_OF_RESOURCES; + } Sha256Init (Sha256Ctx); @@ -82,10 +84,7 @@ Sha256HashUpdate ( IN UINTN DataToHashLen ) { - VOID *Sha256Ctx; - - Sha256Ctx = (VOID *)HashHandle; - Sha256Update (Sha256Ctx, DataToHash, DataToHashLen); + Sha256Update ((VOID *)HashHandle, DataToHash, DataToHashLen); return EFI_SUCCESS; } @@ -106,12 +105,10 @@ Sha256HashFinal ( ) { UINT8 Digest[SHA256_DIGEST_SIZE]; - VOID *Sha256Ctx; - Sha256Ctx = (VOID *)HashHandle; - Sha256Final (Sha256Ctx, Digest); + Sha256Final ((VOID *)HashHandle, Digest); - FreePool (Sha256Ctx); + FreePool ((VOID *)HashHandle); Tpm2SetSha256ToDigestList (DigestList, Digest); diff --git a/SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.c b/SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.c index 1f21483e16..4997874eb0 100644 --- a/SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.c +++ b/SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.c @@ -56,7 +56,9 @@ Sha384HashInit ( CtxSize = Sha384GetContextSize (); Sha384Ctx = AllocatePool (CtxSize); - ASSERT (Sha384Ctx != NULL); + if (Sha384Ctx == NULL) { + return EFI_OUT_OF_RESOURCES; + } Sha384Init (Sha384Ctx); @@ -106,12 +108,10 @@ Sha384HashFinal ( ) { UINT8 Digest[SHA384_DIGEST_SIZE]; - VOID *Sha384Ctx; - Sha384Ctx = (VOID *)HashHandle; - Sha384Final (Sha384Ctx, Digest); + Sha384Final ((VOID *)HashHandle, Digest); - FreePool (Sha384Ctx); + FreePool ((VOID *)HashHandle); Tpm2SetSha384ToDigestList (DigestList, Digest); diff --git a/SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.c b/SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.c index e25ecb9ed6..f426f31e28 100644 --- a/SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.c +++ b/SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.c @@ -55,7 +55,9 @@ Sha512HashInit ( CtxSize = Sha512GetContextSize (); Sha512Ctx = AllocatePool (CtxSize); - ASSERT (Sha512Ctx != NULL); + if (Sha512Ctx == NULL) { + return EFI_OUT_OF_RESOURCES; + } Sha512Init (Sha512Ctx); @@ -81,10 +83,7 @@ Sha512HashUpdate ( IN UINTN DataToHashLen ) { - VOID *Sha512Ctx; - - Sha512Ctx = (VOID *)HashHandle; - Sha512Update (Sha512Ctx, DataToHash, DataToHashLen); + Sha512Update ((VOID *)HashHandle, DataToHash, DataToHashLen); return EFI_SUCCESS; } @@ -100,17 +99,15 @@ Sha512HashUpdate ( EFI_STATUS EFIAPI Sha512HashFinal ( - IN HASH_HANDLE HashHandle, + IN HASH_HANDLE HashHandle, OUT TPML_DIGEST_VALUES *DigestList ) { UINT8 Digest[SHA512_DIGEST_SIZE]; - VOID *Sha512Ctx; - Sha512Ctx = (VOID *)HashHandle; - Sha512Final (Sha512Ctx, Digest); + Sha512Final ((VOID *)HashHandle, Digest); - FreePool (Sha512Ctx); + FreePool ((VOID *)HashHandle); Tpm2SetSha512ToDigestList (DigestList, Digest); diff --git a/SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.c b/SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.c index 635ca1ebfb..88eee675ca 100644 --- a/SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.c +++ b/SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.c @@ -83,10 +83,7 @@ Sm3HashUpdate ( IN UINTN DataToHashLen ) { - VOID *Sm3Ctx; - - Sm3Ctx = (VOID *)HashHandle; - Sm3Update (Sm3Ctx, DataToHash, DataToHashLen); + Sm3Update ((VOID *)HashHandle, DataToHash, DataToHashLen); return EFI_SUCCESS; } @@ -102,17 +99,15 @@ Sm3HashUpdate ( EFI_STATUS EFIAPI Sm3HashFinal ( - IN HASH_HANDLE HashHandle, + IN HASH_HANDLE HashHandle, OUT TPML_DIGEST_VALUES *DigestList ) { UINT8 Digest[SM3_256_DIGEST_SIZE]; - VOID *Sm3Ctx; - Sm3Ctx = (VOID *)HashHandle; - Sm3Final (Sm3Ctx, Digest); + Sm3Final ((VOID *)HashHandle, Digest); - FreePool (Sm3Ctx); + FreePool ((VOID *)HashHandle); Tpm2SetSm3ToDigestList (DigestList, Digest); diff --git a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c index 2169c5e185..ac6fb8f9f6 100644 --- a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c +++ b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c @@ -76,7 +76,9 @@ HashStart ( CheckSupportedHashMaskMismatch (); HashCtx = AllocatePool (sizeof (*HashCtx) * mHashInterfaceCount); - ASSERT (HashCtx != NULL); + if (HashCtx == NULL) { + return EFI_OUT_OF_RESOURCES; + } for (Index = 0; Index < mHashInterfaceCount; Index++) { HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid); diff --git a/SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c b/SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c index 00ba80b884..6c82dac66b 100644 --- a/SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c +++ b/SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c @@ -72,11 +72,13 @@ HashStart ( AlgoId = Tpm2GetAlgoFromHashMask (); Status = Tpm2HashSequenceStart (AlgoId, &SequenceHandle); - if (!EFI_ERROR (Status)) { - *HashHandle = (HASH_HANDLE)SequenceHandle; + if (EFI_ERROR (Status)) { + return Status; } - return Status; + *HashHandle = (HASH_HANDLE)SequenceHandle; + + return EFI_SUCCESS; } /** @@ -109,7 +111,7 @@ HashUpdate ( Status = Tpm2SequenceUpdate ((TPMI_DH_OBJECT)HashHandle, &HashBuffer); if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; + return Status; } } @@ -120,7 +122,7 @@ HashUpdate ( CopyMem (HashBuffer.buffer, Buffer, (UINTN)HashLen); Status = Tpm2SequenceUpdate ((TPMI_DH_OBJECT)HashHandle, &HashBuffer); if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; + return Status; } return EFI_SUCCESS; diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index ea6a14c328..5000e05b7c 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -32,8 +32,12 @@ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf + # FIXME: ARM? + CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf diff --git a/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootPeCoff.c b/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootPeCoff.c deleted file mode 100644 index b6c6faf2d2..0000000000 --- a/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootPeCoff.c +++ /dev/null @@ -1,408 +0,0 @@ -/** @file - This module implements measuring PeCoff image for Tcg2 Protocol. - - Caution: This file requires additional review when modified. - This driver will have external input - PE/COFF image. - This external input must be validated carefully to avoid security issue like - buffer overflow, integer overflow. - -Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -UINTN mTcg2DxeImageSize = 0; - -/** - Reads contents of a PE/COFF image in memory buffer. - - Caution: This function may receive untrusted input. - PE/COFF image is external input, so this function will make sure the PE/COFF image content - read is within the image buffer. - - @param FileHandle Pointer to the file handle to read the PE/COFF image. - @param FileOffset Offset into the PE/COFF image to begin the read operation. - @param ReadSize On input, the size in bytes of the requested read operation. - On output, the number of bytes actually read. - @param Buffer Output buffer that contains the data read from the PE/COFF image. - - @retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size -**/ -EFI_STATUS -EFIAPI -Tcg2DxeImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer - ) -{ - UINTN EndPosition; - - if ((FileHandle == NULL) || (ReadSize == NULL) || (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (MAX_ADDRESS - FileOffset < *ReadSize) { - return EFI_INVALID_PARAMETER; - } - - EndPosition = FileOffset + *ReadSize; - if (EndPosition > mTcg2DxeImageSize) { - *ReadSize = (UINT32)(mTcg2DxeImageSize - FileOffset); - } - - if (FileOffset >= mTcg2DxeImageSize) { - *ReadSize = 0; - } - - CopyMem (Buffer, (UINT8 *)((UINTN)FileHandle + FileOffset), *ReadSize); - - return EFI_SUCCESS; -} - -/** - Measure PE image into TPM log based on the authenticode image hashing in - PE/COFF Specification 8.0 Appendix A. - - Caution: This function may receive untrusted input. - PE/COFF image is external input, so this function will validate its data structure - within this image buffer before use. - - Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo(). - - @param[in] PCRIndex TPM PCR index - @param[in] ImageAddress Start address of image buffer. - @param[in] ImageSize Image size - @param[out] DigestList Digest list of this image. - - @retval EFI_SUCCESS Successfully measure image. - @retval EFI_OUT_OF_RESOURCES No enough resource to measure image. - @retval other error value -**/ -EFI_STATUS -MeasurePeImageAndExtend ( - IN UINT32 PCRIndex, - IN EFI_PHYSICAL_ADDRESS ImageAddress, - IN UINTN ImageSize, - OUT TPML_DIGEST_VALUES *DigestList - ) -{ - EFI_STATUS Status; - EFI_IMAGE_DOS_HEADER *DosHdr; - UINT32 PeCoffHeaderOffset; - EFI_IMAGE_SECTION_HEADER *Section; - UINT8 *HashBase; - UINTN HashSize; - UINTN SumOfBytesHashed; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - UINTN Index; - UINTN Pos; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - UINT32 NumberOfRvaAndSizes; - UINT32 CertSize; - HASH_HANDLE HashHandle; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - - HashHandle = 0xFFFFFFFF; // Know bad value - - Status = EFI_UNSUPPORTED; - SectionHeader = NULL; - - // - // Check PE/COFF image - // - ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.Handle = (VOID *)(UINTN)ImageAddress; - mTcg2DxeImageSize = ImageSize; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)Tcg2DxeImageRead; - - // - // Get information about the image being loaded - // - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - // - // The information can't be got from the invalid PeImage - // - DEBUG ((DEBUG_INFO, "Tcg2Dxe: PeImage invalid. Cannot retrieve image information.\n")); - goto Finish; - } - - DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageAddress; - PeCoffHeaderOffset = 0; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - PeCoffHeaderOffset = DosHdr->e_lfanew; - } - - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset); - if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { - Status = EFI_UNSUPPORTED; - goto Finish; - } - - // - // PE/COFF Image Measurement - // - // NOTE: The following codes/steps are based upon the authenticode image hashing in - // PE/COFF Specification 8.0 Appendix A. - // - // - - // 1. Load the image header into memory. - - // 2. Initialize a SHA hash context. - - Status = HashStart (&HashHandle); - if (EFI_ERROR (Status)) { - goto Finish; - } - - // - // Measuring PE/COFF Image Header; - // But CheckSum field and SECURITY data directory (certificate) are excluded - // - - // - // 3. Calculate the distance from the base of the image header to the image checksum address. - // 4. Hash the image header from its base to beginning of the image checksum. - // - HashBase = (UINT8 *)(UINTN)ImageAddress; - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset - // - NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes; - HashSize = (UINTN)(&Hdr.Pe32->OptionalHeader.CheckSum) - (UINTN)HashBase; - } else { - // - // Use PE32+ offset - // - NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes; - HashSize = (UINTN)(&Hdr.Pe32Plus->OptionalHeader.CheckSum) - (UINTN)HashBase; - } - - Status = HashUpdate (HashHandle, HashBase, HashSize); - if (EFI_ERROR (Status)) { - goto Finish; - } - - // - // 5. Skip over the image checksum (it occupies a single ULONG). - // - if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) { - // - // 6. Since there is no Cert Directory in optional header, hash everything - // from the end of the checksum to the end of image header. - // - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - HashBase = (UINT8 *)&Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); - } else { - // - // Use PE32+ offset. - // - HashBase = (UINT8 *)&Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); - } - - if (HashSize != 0) { - Status = HashUpdate (HashHandle, HashBase, HashSize); - if (EFI_ERROR (Status)) { - goto Finish; - } - } - } else { - // - // 7. Hash everything from the end of the checksum to the start of the Cert Directory. - // - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset - // - HashBase = (UINT8 *)&Hdr.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN)(&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; - } else { - // - // Use PE32+ offset - // - HashBase = (UINT8 *)&Hdr.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN)(&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; - } - - if (HashSize != 0) { - Status = HashUpdate (HashHandle, HashBase, HashSize); - if (EFI_ERROR (Status)) { - goto Finish; - } - } - - // - // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.) - // 9. Hash everything from the end of the Cert Directory to the end of image header. - // - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset - // - HashBase = (UINT8 *)&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = Hdr.Pe32->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); - } else { - // - // Use PE32+ offset - // - HashBase = (UINT8 *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN)(HashBase - ImageAddress); - } - - if (HashSize != 0) { - Status = HashUpdate (HashHandle, HashBase, HashSize); - if (EFI_ERROR (Status)) { - goto Finish; - } - } - } - - // - // 10. Set the SUM_OF_BYTES_HASHED to the size of the header - // - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset - // - SumOfBytesHashed = Hdr.Pe32->OptionalHeader.SizeOfHeaders; - } else { - // - // Use PE32+ offset - // - SumOfBytesHashed = Hdr.Pe32Plus->OptionalHeader.SizeOfHeaders; - } - - // - // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER - // structures in the image. The 'NumberOfSections' field of the image - // header indicates how big the table should be. Do not include any - // IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero. - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *)AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * Hdr.Pe32->FileHeader.NumberOfSections); - if (SectionHeader == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Finish; - } - - // - // 12. Using the 'PointerToRawData' in the referenced section headers as - // a key, arrange the elements in the table in ascending order. In other - // words, sort the section headers according to the disk-file offset of - // the section. - // - Section = (EFI_IMAGE_SECTION_HEADER *)( - (UINT8 *)(UINTN)ImageAddress + - PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - Hdr.Pe32->FileHeader.SizeOfOptionalHeader - ); - for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) { - Pos = Index; - while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) { - CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof (EFI_IMAGE_SECTION_HEADER)); - Pos--; - } - - CopyMem (&SectionHeader[Pos], Section, sizeof (EFI_IMAGE_SECTION_HEADER)); - Section += 1; - } - - // - // 13. Walk through the sorted table, bring the corresponding section - // into memory, and hash the entire section (using the 'SizeOfRawData' - // field in the section header to determine the amount of data to hash). - // 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED . - // 15. Repeat steps 13 and 14 for all the sections in the sorted table. - // - for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) { - Section = (EFI_IMAGE_SECTION_HEADER *)&SectionHeader[Index]; - if (Section->SizeOfRawData == 0) { - continue; - } - - HashBase = (UINT8 *)(UINTN)ImageAddress + Section->PointerToRawData; - HashSize = (UINTN)Section->SizeOfRawData; - - Status = HashUpdate (HashHandle, HashBase, HashSize); - if (EFI_ERROR (Status)) { - goto Finish; - } - - SumOfBytesHashed += HashSize; - } - - // - // 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra - // data in the file that needs to be added to the hash. This data begins - // at file offset SUM_OF_BYTES_HASHED and its length is: - // FileSize - (CertDirectory->Size) - // - if (ImageSize > SumOfBytesHashed) { - HashBase = (UINT8 *)(UINTN)ImageAddress + SumOfBytesHashed; - - if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) { - CertSize = 0; - } else { - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - CertSize = Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size; - } else { - // - // Use PE32+ offset. - // - CertSize = Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size; - } - } - - if (ImageSize > CertSize + SumOfBytesHashed) { - HashSize = (UINTN)(ImageSize - CertSize - SumOfBytesHashed); - - Status = HashUpdate (HashHandle, HashBase, HashSize); - if (EFI_ERROR (Status)) { - goto Finish; - } - } else if (ImageSize < CertSize + SumOfBytesHashed) { - Status = EFI_UNSUPPORTED; - goto Finish; - } - } - - // - // 17. Finalize the SHA hash. - // - Status = HashCompleteAndExtend (HashHandle, PCRIndex, NULL, 0, DigestList); - if (EFI_ERROR (Status)) { - goto Finish; - } - -Finish: - if (SectionHeader != NULL) { - FreePool (SectionHeader); - } - - return Status; -} diff --git a/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootUefiImage.c b/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootUefiImage.c new file mode 100644 index 0000000000..51956c5e6d --- /dev/null +++ b/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootUefiImage.c @@ -0,0 +1,111 @@ +/** @file + This module implements measuring UEFI Image for Tcg2 Protocol. + + Caution: This file requires additional review when modified. + This driver will have external input - PE/COFF image. + This external input must be validated carefully to avoid security issue like + buffer overflow, integer overflow. + +Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +STATIC +EFI_STATUS +EFIAPI +UifiImageHashUpdate ( + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + IN HASH_HANDLE HashHandle + ) +{ + return UefiImageHashImageDefault ( + ImageContext, + (VOID *)HashHandle, + (UEFI_IMAGE_LOADER_HASH_UPDATE)HashUpdate + ) ? EFI_SUCCESS : EFI_ABORTED; +} + +/** + Measure UEFI image into TPM log based on its default image hashing. + + Caution: This function may receive untrusted input. + UEFI image is external input, so this function will validate its data structure + within this image buffer before use. + + Notes: UEFI image is checked by UefiImageLibLib UefiImageInitializeContext(). + + @param[in] PCRIndex TPM PCR index + @param[in] ImageAddress Start address of image buffer. + @param[in] ImageSize Image size + @param[out] DigestList Digest list of this image. + + @retval EFI_SUCCESS Successfully measure image. + @retval EFI_OUT_OF_RESOURCES No enough resource to measure image. + @retval other error value +**/ +EFI_STATUS +MeasureUefiImageAndExtend ( + IN UINT32 PCRIndex, + IN EFI_PHYSICAL_ADDRESS ImageAddress, + IN UINTN ImageSize, + OUT TPML_DIGEST_VALUES *DigestList + ) +{ + EFI_STATUS Status; + HASH_HANDLE HashHandle; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + + Status = EFI_UNSUPPORTED; + + // FIXME: Can this somehow be abstracted away? + // + // Get information about the image being loaded + // + Status = UefiImageInitializeContextPreHash ( + &ImageContext, + (VOID *) (UINTN) ImageAddress, + (UINT32) ImageSize + ); + if (EFI_ERROR (Status)) { + // + // The information can't be got from the invalid PeImage + // + DEBUG ((DEBUG_INFO, "Tcg2Dxe: PeImage invalid. Cannot retrieve image information.\n")); + return Status; + } + + // + // UEFI Image Measurement + // + + // Initialize a SHA hash context. + + Status = HashStart (&HashHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + // FIXME: This is just an ugly wrapper, the types should match (UINTN <-> VOID *), fix the libs + Status = UifiImageHashUpdate (&ImageContext, HashHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // 17. Finalize the SHA hash. + // + return HashCompleteAndExtend (HashHandle, PCRIndex, NULL, 0, DigestList); +} diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c index 4d0c241f4d..2637df578d 100644 --- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c +++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c @@ -9,7 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include +#include #include #include @@ -124,7 +124,7 @@ EFI_HANDLE mImageHandle; PE/COFF image is external input, so this function will validate its data structure within this image buffer before use. - Notes: PE/COFF image is checked by BasePeCoffLib PeCoffLoaderGetImageInfo(). + Notes: PE/COFF image is checked by UefiImageLibLib UefiImageInitializeContext(). @param[in] PCRIndex TPM PCR index @param[in] ImageAddress Start address of image buffer. @@ -136,7 +136,7 @@ EFI_HANDLE mImageHandle; @retval other error value **/ EFI_STATUS -MeasurePeImageAndExtend ( +MeasureUefiImageAndExtend ( IN UINT32 PCRIndex, IN EFI_PHYSICAL_ADDRESS ImageAddress, IN UINTN ImageSize, @@ -1346,7 +1346,7 @@ Tcg2HashLogExtendEvent ( NewEventHdr.EventType = Event->Header.EventType; NewEventHdr.EventSize = Event->Size - sizeof (UINT32) - Event->Header.HeaderSize; if ((Flags & PE_COFF_IMAGE) != 0) { - Status = MeasurePeImageAndExtend ( + Status = MeasureUefiImageAndExtend ( NewEventHdr.PCRIndex, DataToHash, (UINTN)DataToHashLen, @@ -1359,7 +1359,7 @@ Tcg2HashLogExtendEvent ( } if (Status == EFI_DEVICE_ERROR) { - DEBUG ((DEBUG_ERROR, "MeasurePeImageAndExtend - %r. Disable TPM.\n", Status)); + DEBUG ((DEBUG_ERROR, "MeasureUefiImageAndExtend - %r. Disable TPM.\n", Status)); mTcgDxeData.BsCap.TPMPresentFlag = FALSE; REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MINOR, diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf index a645474bf3..3e86b6c999 100644 --- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf +++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf @@ -38,7 +38,7 @@ [Sources] Tcg2Dxe.c - MeasureBootPeCoff.c + MeasureBootUefiImage.c [Packages] MdePkg/MdePkg.dec @@ -63,7 +63,7 @@ PerformanceLib ReportStatusCodeLib Tcg2PhysicalPresenceLib - PeCoffLib + UefiImageLib [Guids] ## SOMETIMES_CONSUMES ## Variable:L"SecureBoot" diff --git a/SecurityPkg/Tcg/TcgDxe/TcgDxe.c b/SecurityPkg/Tcg/TcgDxe/TcgDxe.c index ee6c627303..95458a2c4c 100644 --- a/SecurityPkg/Tcg/TcgDxe/TcgDxe.c +++ b/SecurityPkg/Tcg/TcgDxe/TcgDxe.c @@ -17,7 +17,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +#include #include #include diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf index 0602acf702..ba5775198f 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf @@ -53,7 +53,7 @@ PlatformSecureLib DevicePathLib FileExplorerLib - PeCoffLib + UefiImageLib SecureBootVariableLib SecureBootVariableProvisionLib diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c index d4dc4e1402..dd953e63ac 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c @@ -12,6 +12,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include "Library/UefiImageLib.h" #include #include #include @@ -71,26 +72,25 @@ UINT8 mHashOidValue[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, // OBJ_sha512 }; +// +// Support hash types +// +#define HASHALG_SHA256 0x00000001 +#define HASHALG_SHA384 0x00000002 +#define HASHALG_SHA512 0x00000003 +#define HASHALG_RAW 0x00000004 +#define HASHALG_MAX 0x00000004 + HASH_TABLE mHash[] = { - { L"SHA224", 28, &mHashOidValue[13], 9, NULL, NULL, NULL, NULL }, - { L"SHA256", 32, &mHashOidValue[22], 9, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final }, - { L"SHA384", 48, &mHashOidValue[31], 9, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final }, - { L"SHA512", 64, &mHashOidValue[40], 9, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final } + { L"SHA256", 32, &mHashOidValue[14], 9, &gEfiCertSha256Guid, Sha256GetContextSize, Sha256Init, Sha256Update, Sha256Final }, + { L"SHA384", 48, &mHashOidValue[23], 9, &gEfiCertSha384Guid, Sha384GetContextSize, Sha384Init, Sha384Update, Sha384Final }, + { L"SHA512", 64, &mHashOidValue[32], 9, &gEfiCertSha512Guid, Sha512GetContextSize, Sha512Init, Sha512Update, Sha512Final } }; // // Variable Definitions // -UINT32 mPeCoffHeaderOffset = 0; -WIN_CERTIFICATE *mCertificate = NULL; -IMAGE_TYPE mImageType; -UINT8 *mImageBase = NULL; -UINTN mImageSize = 0; -UINT8 mImageDigest[MAX_DIGEST_SIZE]; -UINTN mImageDigestSize; -EFI_GUID mCertType; -EFI_IMAGE_SECURITY_DATA_DIRECTORY *mSecDataDir = NULL; -EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION mNtHeader; +EFI_IMAGE_SECURITY_DATA_DIRECTORY *mSecDataDir = NULL; // // Possible DER-encoded certificate file suffixes, end with NULL pointer. @@ -234,6 +234,8 @@ IsAuthentication2Format ( EFI_STATUS Status; EFI_VARIABLE_AUTHENTICATION_2 *Auth2; BOOLEAN IsAuth2Format; + UINT8 *ImageBase; + UINTN ImageSize; IsAuth2Format = FALSE; @@ -242,15 +244,15 @@ IsAuthentication2Format ( // Status = ReadFileContent ( FileHandle, - (VOID **)&mImageBase, - &mImageSize, + (VOID **)&ImageBase, + &ImageSize, 0 ); if (EFI_ERROR (Status)) { goto ON_EXIT; } - Auth2 = (EFI_VARIABLE_AUTHENTICATION_2 *)mImageBase; + Auth2 = (EFI_VARIABLE_AUTHENTICATION_2 *)ImageBase; if (Auth2->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) { goto ON_EXIT; } @@ -263,9 +265,8 @@ IsAuthentication2Format ( // // Do not close File. simply check file content // - if (mImageBase != NULL) { - FreePool (mImageBase); - mImageBase = NULL; + if (ImageBase != NULL) { + FreePool (ImageBase); } return IsAuth2Format; @@ -1683,151 +1684,11 @@ IsX509CertInDbx ( return IsFound; } -/** - Reads contents of a PE/COFF image in memory buffer. - - Caution: This function may receive untrusted input. - PE/COFF image is external input, so this function will make sure the PE/COFF image content - read is within the image buffer. - - @param FileHandle Pointer to the file handle to read the PE/COFF image. - @param FileOffset Offset into the PE/COFF image to begin the read operation. - @param ReadSize On input, the size in bytes of the requested read operation. - On output, the number of bytes actually read. - @param Buffer Output buffer that contains the data read from the PE/COFF image. - - @retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size -**/ -EFI_STATUS -EFIAPI -SecureBootConfigImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer - ) -{ - UINTN EndPosition; - - if ((FileHandle == NULL) || (ReadSize == NULL) || (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (MAX_ADDRESS - FileOffset < *ReadSize) { - return EFI_INVALID_PARAMETER; - } - - EndPosition = FileOffset + *ReadSize; - if (EndPosition > mImageSize) { - *ReadSize = (UINT32)(mImageSize - FileOffset); - } - - if (FileOffset >= mImageSize) { - *ReadSize = 0; - } - - CopyMem (Buffer, (UINT8 *)((UINTN)FileHandle + FileOffset), *ReadSize); - - return EFI_SUCCESS; -} - -/** - Load PE/COFF image information into internal buffer and check its validity. - - @retval EFI_SUCCESS Successful - @retval EFI_UNSUPPORTED Invalid PE/COFF file - @retval EFI_ABORTED Serious error occurs, like file I/O error etc. - -**/ -EFI_STATUS -LoadPeImage ( - VOID - ) -{ - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_NT_HEADERS32 *NtHeader32; - EFI_IMAGE_NT_HEADERS64 *NtHeader64; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - EFI_STATUS Status; - - NtHeader32 = NULL; - NtHeader64 = NULL; - - ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.Handle = (VOID *)mImageBase; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)SecureBootConfigImageRead; - - // - // Get information about the image being loaded - // - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - // - // The information can't be got from the invalid PeImage - // - DEBUG ((DEBUG_INFO, "SecureBootConfigDxe: PeImage invalid. \n")); - return Status; - } - - // - // Read the Dos header - // - DosHdr = (EFI_IMAGE_DOS_HEADER *)(mImageBase); - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, - // So read the PE header after the DOS image header - // - mPeCoffHeaderOffset = DosHdr->e_lfanew; - } else { - mPeCoffHeaderOffset = 0; - } - - // - // Read PE header and check the signature validity and machine compatibility - // - NtHeader32 = (EFI_IMAGE_NT_HEADERS32 *)(mImageBase + mPeCoffHeaderOffset); - if (NtHeader32->Signature != EFI_IMAGE_NT_SIGNATURE) { - return EFI_UNSUPPORTED; - } - - mNtHeader.Pe32 = NtHeader32; - - // - // Check the architecture field of PE header and get the Certificate Data Directory data - // Note the size of FileHeader field is constant for both IA32 and X64 arch - // - if ( (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) - || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_EBC) - || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_ARMTHUMB_MIXED)) - { - // - // 32-bits Architecture - // - mImageType = ImageType_IA32; - mSecDataDir = (EFI_IMAGE_SECURITY_DATA_DIRECTORY *)&(NtHeader32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]); - } else if ( (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) - || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) - || (NtHeader32->FileHeader.Machine == EFI_IMAGE_MACHINE_AARCH64)) - { - // - // 64-bits Architecture - // - mImageType = ImageType_X64; - NtHeader64 = (EFI_IMAGE_NT_HEADERS64 *)(mImageBase + mPeCoffHeaderOffset); - mSecDataDir = (EFI_IMAGE_SECURITY_DATA_DIRECTORY *)&(NtHeader64->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]); - } else { - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; -} - /** Calculate hash of Pe/Coff image based on the authenticode image hashing in PE/COFF Specification 8.0 Appendix A - Notes: PE/COFF image has been checked by BasePeCoffLib PeCoffLoaderGetImageInfo() in + Notes: PE/COFF image has been checked by UefiImageLibLib UefiImageInitializeContext() in the function LoadPeImage (). @param[in] HashAlg Hash algorithm type. @@ -1838,254 +1699,56 @@ LoadPeImage ( **/ BOOLEAN HashPeImage ( - IN UINT32 HashAlg + UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + IN UINT32 HashAlg, + UINT8 ImageDigest[MAX_DIGEST_SIZE], + UINTN *ImageDigestSize ) { - BOOLEAN Status; - EFI_IMAGE_SECTION_HEADER *Section; - VOID *HashCtx; - UINTN CtxSize; - UINT8 *HashBase; - UINTN HashSize; - UINTN SumOfBytesHashed; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - UINTN Index; - UINTN Pos; - - HashCtx = NULL; - SectionHeader = NULL; - Status = FALSE; - - if ((HashAlg >= HASHALG_MAX)) { - return FALSE; - } + BOOLEAN Status; + VOID *HashCtx; + UINTN CtxSize; + + ASSERT (HashAlg < HASHALG_MAX); + + HashCtx = NULL; + Status = FALSE; // // Initialize context of hash. // - ZeroMem (mImageDigest, MAX_DIGEST_SIZE); - - switch (HashAlg) { - case HASHALG_SHA256: - mImageDigestSize = SHA256_DIGEST_SIZE; - mCertType = gEfiCertSha256Guid; - break; - - case HASHALG_SHA384: - mImageDigestSize = SHA384_DIGEST_SIZE; - mCertType = gEfiCertSha384Guid; - break; - - case HASHALG_SHA512: - mImageDigestSize = SHA512_DIGEST_SIZE; - mCertType = gEfiCertSha512Guid; - break; - - default: - return FALSE; - } + ZeroMem (ImageDigest, MAX_DIGEST_SIZE); CtxSize = mHash[HashAlg].GetContextSize (); HashCtx = AllocatePool (CtxSize); - ASSERT (HashCtx != NULL); - - // 1. Load the image header into memory. - - // 2. Initialize a SHA hash context. - Status = mHash[HashAlg].HashInit (HashCtx); - if (!Status) { - goto Done; - } - - // - // Measuring PE/COFF Image Header; - // But CheckSum field and SECURITY data directory (certificate) are excluded - // - - // - // 3. Calculate the distance from the base of the image header to the image checksum address. - // 4. Hash the image header from its base to beginning of the image checksum. - // - HashBase = mImageBase; - if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - HashSize = (UINTN)(&mNtHeader.Pe32->OptionalHeader.CheckSum) - (UINTN)HashBase; - } else { - // - // Use PE32+ offset. - // - HashSize = (UINTN)(&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - (UINTN)HashBase; - } - - Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize); - if (!Status) { - goto Done; + if (HashCtx == NULL) { + return FALSE; } - // - // 5. Skip over the image checksum (it occupies a single ULONG). - // 6. Get the address of the beginning of the Cert Directory. - // 7. Hash everything from the end of the checksum to the start of the Cert Directory. - // - if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - HashBase = (UINT8 *)&mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN)(&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; - } else { - // - // Use PE32+ offset. - // - HashBase = (UINT8 *)&mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32); - HashSize = (UINTN)(&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - (UINTN)HashBase; - } + Status = mHash[HashAlg].HashInit (HashCtx); - Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize); if (!Status) { goto Done; } - // - // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.) - // 9. Hash everything from the end of the Cert Directory to the end of image header. - // - if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset - // - HashBase = (UINT8 *)&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - ((UINTN)(&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINTN)mImageBase); - } else { - // - // Use PE32+ offset. - // - HashBase = (UINT8 *)&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]; - HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - ((UINTN)(&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINTN)mImageBase); - } + Status = UefiImageHashImageDefault (ImageContext, HashCtx, mHash[HashAlg].HashUpdate); - Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize); if (!Status) { + DEBUG ((DEBUG_INFO, "DxeImageVerificationLib: Failed to hash this image using %s.\n", mHash[HashAlg].Name)); goto Done; } - // - // 10. Set the SUM_OF_BYTES_HASHED to the size of the header. - // - if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - SumOfBytesHashed = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders; - } else { - // - // Use PE32+ offset - // - SumOfBytesHashed = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders; - } - - // - // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER - // structures in the image. The 'NumberOfSections' field of the image - // header indicates how big the table should be. Do not include any - // IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero. - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *)AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * mNtHeader.Pe32->FileHeader.NumberOfSections); - ASSERT (SectionHeader != NULL); - // - // 12. Using the 'PointerToRawData' in the referenced section headers as - // a key, arrange the elements in the table in ascending order. In other - // words, sort the section headers according to the disk-file offset of - // the section. - // - Section = (EFI_IMAGE_SECTION_HEADER *)( - mImageBase + - mPeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - mNtHeader.Pe32->FileHeader.SizeOfOptionalHeader - ); - for (Index = 0; Index < mNtHeader.Pe32->FileHeader.NumberOfSections; Index++) { - Pos = Index; - while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) { - CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof (EFI_IMAGE_SECTION_HEADER)); - Pos--; - } - - CopyMem (&SectionHeader[Pos], Section, sizeof (EFI_IMAGE_SECTION_HEADER)); - Section += 1; - } - - // - // 13. Walk through the sorted table, bring the corresponding section - // into memory, and hash the entire section (using the 'SizeOfRawData' - // field in the section header to determine the amount of data to hash). - // 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED . - // 15. Repeat steps 13 and 14 for all the sections in the sorted table. - // - for (Index = 0; Index < mNtHeader.Pe32->FileHeader.NumberOfSections; Index++) { - Section = &SectionHeader[Index]; - if (Section->SizeOfRawData == 0) { - continue; - } - - HashBase = mImageBase + Section->PointerToRawData; - HashSize = (UINTN)Section->SizeOfRawData; - - Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize); - if (!Status) { - goto Done; - } - - SumOfBytesHashed += HashSize; - } - - // - // 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra - // data in the file that needs to be added to the hash. This data begins - // at file offset SUM_OF_BYTES_HASHED and its length is: - // FileSize - (CertDirectory->Size) - // - if (mImageSize > SumOfBytesHashed) { - HashBase = mImageBase + SumOfBytesHashed; - if (mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // Use PE32 offset. - // - HashSize = (UINTN)( - mImageSize - - mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size - - SumOfBytesHashed); - } else { - // - // Use PE32+ offset. - // - HashSize = (UINTN)( - mImageSize - - mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size - - SumOfBytesHashed); - } - - Status = mHash[HashAlg].HashUpdate (HashCtx, HashBase, HashSize); - if (!Status) { - goto Done; - } - } + ASSERT (mHash[HashAlg].DigestLength <= MAX_DIGEST_SIZE); + Status = mHash[HashAlg].HashFinal (HashCtx, ImageDigest); - Status = mHash[HashAlg].HashFinal (HashCtx, mImageDigest); + *ImageDigestSize = mHash[HashAlg].DigestLength; Done: if (HashCtx != NULL) { FreePool (HashCtx); } - if (SectionHeader != NULL) { - FreePool (SectionHeader); - } - return Status; } @@ -2100,36 +1763,41 @@ HashPeImage ( **/ EFI_STATUS HashPeImageByType ( - VOID + UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + IN CONST UINT8 *AuthData, + IN UINTN AuthDataSize, + UINT8 ImageDigest[MAX_DIGEST_SIZE], + UINTN *ImageDigestSize, + OUT CONST EFI_GUID **CertType ) { - UINT8 Index; - WIN_CERTIFICATE_EFI_PKCS *PkcsCertData; - - PkcsCertData = (WIN_CERTIFICATE_EFI_PKCS *)(mImageBase + mSecDataDir->Offset); + UINT8 Index; - for (Index = 0; Index < HASHALG_MAX; Index++) { + // + // Check the Hash algorithm in PE/COFF Authenticode. + // According to PKCS#7 Definition: + // SignedData ::= SEQUENCE { + // version Version, + // digestAlgorithms DigestAlgorithmIdentifiers, + // contentInfo ContentInfo, + // .... } + // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing + // This field has the fixed offset (+32) in final Authenticode ASN.1 data. + // Fixed offset (+32) is calculated based on two bytes of length encoding. + // + if ((*(AuthData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE) { // - // Check the Hash algorithm in PE/COFF Authenticode. - // According to PKCS#7 Definition: - // SignedData ::= SEQUENCE { - // version Version, - // digestAlgorithms DigestAlgorithmIdentifiers, - // contentInfo ContentInfo, - // .... } - // The DigestAlgorithmIdentifiers can be used to determine the hash algorithm in PE/COFF hashing - // This field has the fixed offset (+32) in final Authenticode ASN.1 data. - // Fixed offset (+32) is calculated based on two bytes of length encoding. + // Only support two bytes of Long Form of Length Encoding. // - if ((*(PkcsCertData->CertData + 1) & TWO_BYTE_ENCODE) != TWO_BYTE_ENCODE) { - // - // Only support two bytes of Long Form of Length Encoding. - // + return EFI_UNSUPPORTED; + } + + for (Index = 0; Index < HASHALG_MAX; Index++) { + if (AuthDataSize < 32 + mHash[Index].OidLength) { continue; } - // - if (CompareMem (PkcsCertData->CertData + 32, mHash[Index].OidValue, mHash[Index].OidLength) == 0) { + if (CompareMem (AuthData + 32, mHash[Index].OidValue, mHash[Index].OidLength) == 0) { break; } } @@ -2141,10 +1809,12 @@ HashPeImageByType ( // // HASH PE Image based on Hash algorithm in PE/COFF Authenticode. // - if (!HashPeImage (Index)) { + if (!HashPeImage (ImageContext, Index, ImageDigest, ImageDigestSize)) { return EFI_UNSUPPORTED; } + *CertType = mHash[Index].CertType; + return EFI_SUCCESS; } @@ -2172,6 +1842,8 @@ EnrollAuthentication2Descriptor ( VOID *Data; UINTN DataSize; UINT32 Attr; + UINT8 *ImageBase; + UINTN ImageSize; Data = NULL; @@ -2187,16 +1859,14 @@ EnrollAuthentication2Descriptor ( // Status = ReadFileContent ( Private->FileContext->FHandle, - (VOID **)&mImageBase, - &mImageSize, + (VOID **)&ImageBase, + &ImageSize, 0 ); if (EFI_ERROR (Status)) { goto ON_EXIT; } - ASSERT (mImageBase != NULL); - Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; @@ -2226,8 +1896,8 @@ EnrollAuthentication2Descriptor ( VariableName, &gEfiImageSecurityDatabaseGuid, Attr, - mImageSize, - mImageBase + ImageSize, + ImageBase ); DEBUG ((DEBUG_INFO, "Enroll AUTH_2 data to Var:%s Status: %x\n", VariableName, Status)); @@ -2240,9 +1910,8 @@ EnrollAuthentication2Descriptor ( FreePool (Data); } - if (mImageBase != NULL) { - FreePool (mImageBase); - mImageBase = NULL; + if (ImageBase != NULL) { + FreePool (ImageBase); } return Status; @@ -2268,16 +1937,24 @@ EnrollImageSignatureToSigDB ( IN CHAR16 *VariableName ) { - EFI_STATUS Status; - EFI_SIGNATURE_LIST *SigDBCert; - EFI_SIGNATURE_DATA *SigDBCertData; - VOID *Data; - UINTN DataSize; - UINTN SigDBSize; - UINT32 Attr; - WIN_CERTIFICATE_UEFI_GUID *GuidCertData; - EFI_TIME Time; - UINT32 HashAlg; + EFI_STATUS Status; + EFI_SIGNATURE_LIST *SigDBCert; + EFI_SIGNATURE_DATA *SigDBCertData; + VOID *Data; + UINTN DataSize; + UINTN SigDBSize; + UINT32 Attr; + EFI_TIME Time; + UINT32 HashAlg; + CONST WIN_CERTIFICATE_UEFI_GUID *GuidCertData; + CONST WIN_CERTIFICATE *Certificate; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UINT8 *ImageBase; + UINTN ImageSize; + UINT8 ImageDigest[MAX_DIGEST_SIZE]; + UINTN ImageDigestSize; + CONST EFI_GUID *CertType; + CONST WIN_CERTIFICATE_EFI_PKCS *PkcsCertData; Data = NULL; GuidCertData = NULL; @@ -2300,22 +1977,22 @@ EnrollImageSignatureToSigDB ( // Status = ReadFileContent ( Private->FileContext->FHandle, - (VOID **)&mImageBase, - &mImageSize, + (VOID **)&ImageBase, + &ImageSize, 0 ); if (EFI_ERROR (Status)) { goto ON_EXIT; } - ASSERT (mImageBase != NULL); - - Status = LoadPeImage (); + Status = UefiImageInitializeContextPreHash (&ImageContext, ImageBase, (UINT32)ImageSize); if (EFI_ERROR (Status)) { goto ON_EXIT; } - if (mSecDataDir->SizeOfCert == 0) { + Status = UefiImageGetFirstCertificate (&ImageContext, &Certificate); + + if (Status == RETURN_NOT_FOUND) { Status = EFI_SECURITY_VIOLATION; HashAlg = sizeof (mHash) / sizeof (HASH_TABLE); while (HashAlg > 0) { @@ -2324,7 +2001,7 @@ EnrollImageSignatureToSigDB ( continue; } - if (HashPeImage (HashAlg)) { + if (HashPeImage (&ImageContext, HashAlg, ImageDigest, &ImageDigestSize)) { Status = EFI_SUCCESS; break; } @@ -2335,24 +2012,21 @@ EnrollImageSignatureToSigDB ( goto ON_EXIT; } } else { - // - // Read the certificate data - // - mCertificate = (WIN_CERTIFICATE *)(mImageBase + mSecDataDir->Offset); - - if (mCertificate->wCertificateType == WIN_CERT_TYPE_EFI_GUID) { - GuidCertData = (WIN_CERTIFICATE_UEFI_GUID *)mCertificate; + if (Certificate->wCertificateType == WIN_CERT_TYPE_EFI_GUID) { + GuidCertData = (CONST WIN_CERTIFICATE_UEFI_GUID *)Certificate; if (CompareMem (&GuidCertData->CertType, &gEfiCertTypeRsa2048Sha256Guid, sizeof (EFI_GUID)) != 0) { Status = EFI_ABORTED; goto ON_EXIT; } - if (!HashPeImage (HASHALG_SHA256)) { + if (!HashPeImage (&ImageContext, HASHALG_SHA256, ImageDigest, &ImageDigestSize)) { Status = EFI_ABORTED; goto ON_EXIT; } - } else if (mCertificate->wCertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) { - Status = HashPeImageByType (); + } else if (Certificate->wCertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) { + PkcsCertData = (CONST WIN_CERTIFICATE_EFI_PKCS *)Certificate; + + Status = HashPeImageByType (&ImageContext, PkcsCertData->CertData, PkcsCertData->Hdr.dwLength - sizeof (PkcsCertData->Hdr), ImageDigest, &ImageDigestSize, &CertType); if (EFI_ERROR (Status)) { goto ON_EXIT; } @@ -2367,7 +2041,7 @@ EnrollImageSignatureToSigDB ( // SigDBSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 - + (UINT32)mImageDigestSize; + + (UINT32)ImageDigestSize; Data = (UINT8 *)AllocateZeroPool (SigDBSize); if (Data == NULL) { @@ -2381,12 +2055,12 @@ EnrollImageSignatureToSigDB ( SigDBCert = (EFI_SIGNATURE_LIST *)Data; SigDBCert->SignatureListSize = (UINT32)SigDBSize; SigDBCert->SignatureHeaderSize = 0; - SigDBCert->SignatureSize = sizeof (EFI_SIGNATURE_DATA) - 1 + (UINT32)mImageDigestSize; - CopyGuid (&SigDBCert->SignatureType, &mCertType); + SigDBCert->SignatureSize = sizeof (EFI_SIGNATURE_DATA) - 1 + (UINT32)ImageDigestSize; + CopyGuid (&SigDBCert->SignatureType, CertType); SigDBCertData = (EFI_SIGNATURE_DATA *)((UINT8 *)SigDBCert + sizeof (EFI_SIGNATURE_LIST)); CopyGuid (&SigDBCertData->SignatureOwner, Private->SignatureGUID); - CopyMem (SigDBCertData->SignatureData, mImageDigest, mImageDigestSize); + CopyMem (SigDBCertData->SignatureData, ImageDigest, ImageDigestSize); Attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS; @@ -2448,9 +2122,9 @@ EnrollImageSignatureToSigDB ( FreePool (Data); } - if (mImageBase != NULL) { - FreePool (mImageBase); - mImageBase = NULL; + if (ImageBase != NULL) { + FreePool (ImageBase); + ImageBase = NULL; } return Status; diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h index ff6e7301af..7ad3052a6a 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.h @@ -34,7 +34,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +#include #include #include @@ -85,16 +85,6 @@ extern EFI_IFR_GUID_LABEL *mEndLabel; #define WIN_CERT_UEFI_RSA3072_SIZE 384 #define WIN_CERT_UEFI_RSA4096_SIZE 512 -// -// Support hash types -// -#define HASHALG_SHA224 0x00000000 -#define HASHALG_SHA256 0x00000001 -#define HASHALG_SHA384 0x00000002 -#define HASHALG_SHA512 0x00000003 -#define HASHALG_RAW 0x00000004 -#define HASHALG_MAX 0x00000004 - // // Certificate public key minimum size (bytes) // @@ -306,6 +296,7 @@ typedef struct { UINTN DigestLength; ///< Digest Length UINT8 *OidValue; ///< Hash Algorithm OID ASN.1 Value UINTN OidLength; ///< Length of Hash OID Value + CONST GUID *CertType; ///< GUID of the certificate type HASH_GET_CONTEXT_SIZE GetContextSize; ///< Pointer to Hash GetContentSize function HASH_INIT HashInit; ///< Pointer to Hash Init function HASH_UPDATE HashUpdate; ///< Pointer to Hash Update function diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.inf b/ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.inf index d9e1c23a1e..abe15b3f42 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.inf +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpApp.inf @@ -50,7 +50,6 @@ DevicePathLib PerformanceLib DxeServicesLib - PeCoffGetEntryPointLib [Guids] gPerformanceProtocolGuid ## CONSUMES ## SystemTable diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf b/ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf index 2723fee706..290d1adebd 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf @@ -51,11 +51,11 @@ DevicePathLib PerformanceLib DxeServicesLib - PeCoffGetEntryPointLib [Guids] gPerformanceProtocolGuid ## CONSUMES ## SystemTable gEdkiiFpdtExtendedFirmwarePerformanceGuid ## CONSUMES ## SystemTable + gEfiDebugImageInfoTableGuid ## CONSUMES ## SystemTable [Protocols] gEfiLoadedImageProtocolGuid ## CONSUMES diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpInternal.h b/ShellPkg/DynamicCommand/DpDynamicCommand/DpInternal.h index 97f47f2960..3ce8d05d49 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpInternal.h +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpInternal.h @@ -109,8 +109,8 @@ IsCorePerf ( **/ VOID DpGetShortPdbFileName ( - IN CHAR8 *PdbFileName, - OUT CHAR16 *UnicodeBuffer + IN CONST CHAR8 *PdbFileName, + OUT CHAR16 *UnicodeBuffer ); /** diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c b/ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c index 9c0a9a06a1..5cd28ff919 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c @@ -11,7 +11,7 @@ #include #include #include -#include + #include #include #include diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c b/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c index 60c886c11d..240093dc26 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c @@ -11,7 +11,7 @@ #include #include #include -#include + #include #include #include @@ -28,6 +28,7 @@ #include #include +#include #include "Dp.h" #include "Literals.h" @@ -148,8 +149,8 @@ IsCorePerf ( **/ VOID DpGetShortPdbFileName ( - IN CHAR8 *PdbFileName, - OUT CHAR16 *UnicodeBuffer + IN CONST CHAR8 *PdbFileName, + OUT CHAR16 *UnicodeBuffer ) { UINTN IndexA; // Current work location within an ASCII string. @@ -188,6 +189,41 @@ DpGetShortPdbFileName ( } } +// FIXME: Duplicate (GetImageName), create API +CONST CHAR8 * +GetImagePdb ( + IN CONST VOID *ImageBase + ) +{ + EFI_STATUS Status; + EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *DebugTableHeader; + EFI_DEBUG_IMAGE_INFO *DebugTable; + UINTN Entry; + + Status = EfiGetSystemConfigurationTable (&gEfiDebugImageInfoTableGuid, (VOID **)&DebugTableHeader); + if (EFI_ERROR (Status)) { + return NULL; + } + + DebugTable = DebugTableHeader->EfiDebugImageInfoTable; + if (DebugTable == NULL) { + return NULL; + } + + for (Entry = 0; Entry < DebugTableHeader->TableSize; Entry++, DebugTable++) { + if (DebugTable->NormalImage != NULL) { + if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && + (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) { + if (ImageBase == DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase) { + return DebugTable->NormalImage->PdbPath; + } + } + } + } + + return NULL; +} + /** Get a human readable name for an image handle. The following methods will be tried orderly: @@ -211,7 +247,7 @@ DpGetNameFromHandle ( { EFI_STATUS Status; EFI_LOADED_IMAGE_PROTOCOL *Image; - CHAR8 *PdbFileName; + CONST CHAR8 *PdbFileName; EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; EFI_STRING StringPtr; EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; @@ -255,7 +291,7 @@ DpGetNameFromHandle ( } if (!EFI_ERROR (Status)) { - PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase); + PdbFileName = GetImagePdb (Image->ImageBase); if (PdbFileName != NULL) { DpGetShortPdbFileName (PdbFileName, mGaugeString); diff --git a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c index 1e3ba1b0a9..13168a9872 100644 --- a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c +++ b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.c @@ -309,7 +309,9 @@ LoadedImageProtocolDumpInformation ( return NULL; } - PdbFileName = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase); + // FIXME: + //PdbFileName = UefiImageLoaderGetPdbPointer (LoadedImage->ImageBase); + PdbFileName = NULL; DataType = ConvertMemoryType (LoadedImage->ImageDataType); CodeType = ConvertMemoryType (LoadedImage->ImageCodeType); if ((PdbFileName != NULL) && (DataType != NULL) && (CodeType != NULL) && (FilePath != NULL)) { diff --git a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h index 6be0d78c4c..74aa3c88f6 100644 --- a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h +++ b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.h @@ -148,7 +148,7 @@ #include #include #include -#include + #define EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V1 1 #define EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION_V2 2 diff --git a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf index 0d483805e7..f51b22516b 100644 --- a/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf +++ b/ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf @@ -45,7 +45,6 @@ UefiLib HiiLib SortLib - PeCoffGetEntryPointLib [Protocols] gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c b/ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c index 40260ea3dc..1244668bbe 100644 --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/LoadPciRom.c @@ -10,7 +10,7 @@ #include "UefiShellDebug1CommandsLib.h" #include #include -#include +#include #include /** diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h index 1c002361de..6273491aee 100644 --- a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h +++ b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.h @@ -54,7 +54,7 @@ #include #include #include -#include + #include extern EFI_HII_HANDLE gShellDriver1HiiHandle; diff --git a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf index e7661c3fce..518eb1a09e 100644 --- a/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf +++ b/ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf @@ -50,7 +50,6 @@ UefiBootServicesTableLib SortLib PrintLib - PeCoffGetEntryPointLib [Pcd] gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask ## CONSUMES diff --git a/ShellPkg/ShellPkg.dsc b/ShellPkg/ShellPkg.dsc index 7e985f8280..9f22cdb4a3 100644 --- a/ShellPkg/ShellPkg.dsc +++ b/ShellPkg/ShellPkg.dsc @@ -53,7 +53,6 @@ HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf AcpiViewCommandLib|ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf diff --git a/SignedCapsulePkg/SignedCapsulePkg.dsc b/SignedCapsulePkg/SignedCapsulePkg.dsc index b38fd2da15..c840a1acb2 100644 --- a/SignedCapsulePkg/SignedCapsulePkg.dsc +++ b/SignedCapsulePkg/SignedCapsulePkg.dsc @@ -40,8 +40,8 @@ PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf # # UEFI & PI @@ -75,7 +75,7 @@ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c index b553a2a9aa..8fc4c6d79b 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c +++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c @@ -183,30 +183,7 @@ IsDebugAgentInitialzed ( } } -/** - Find and report module image info to HOST. - - @param[in] AlignSize Image aligned size. - -**/ -VOID -FindAndReportModuleImageInfo ( - IN UINTN AlignSize - ) -{ - UINTN Pe32Data; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - - // - // Find Image Base - // - Pe32Data = PeCoffSearchImageBase ((UINTN)mErrorMsgVersionAlert); - if (Pe32Data != 0) { - ImageContext.ImageAddress = Pe32Data; - ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress); - PeCoffLoaderRelocateImageExtraAction (&ImageContext); - } -} +// FIXME: UefiImageRelocExtra functio removed, done by *Core? /** Trigger one software interrupt to debug agent to handle it. @@ -1315,7 +1292,7 @@ GetBreakCause ( // triggered by the single step execution mode. // The single-step mode is the highest priority debug exception. // This is single step, no need to check DR0, to ensure single step - // work in PeCoffExtraActionLib (right after triggering a breakpoint + // work in UefiImageExtraActionLib (right after triggering a breakpoint // to report image load/unload). // return Cause; diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h index 4c72f8f3a9..fdbef964bd 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h +++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h @@ -26,8 +26,7 @@ #include #include #include -#include -#include +#include #include #include @@ -313,17 +312,6 @@ MultiProcessorDebugSupport ( VOID ); -/** - Find and report module image info to HOST. - - @param[in] AlignSize Image aligned size. - -**/ -VOID -FindAndReportModuleImageInfo ( - IN UINTN AlignSize - ); - /** Read IDT entry to check if IDT entries are setup by Debug Agent. diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c index fcb1b631c1..c957e7558e 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c +++ b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c @@ -446,7 +446,6 @@ InitializeDebugAgent ( EnableInterrupts (); mDebugAgentInitialized = TRUE; - FindAndReportModuleImageInfo (SIZE_4KB); *(EFI_STATUS *)Context = EFI_SUCCESS; @@ -528,7 +527,6 @@ InitializeDebugAgent ( // Disable interrupt // DisableInterrupts (); - FindAndReportModuleImageInfo (SIZE_4KB); if (GetDebugFlag (DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT) == 1) { // // If Boot Script entry break is set, code will be break at here. diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf index aa50048780..ba670014c6 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf +++ b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf @@ -69,8 +69,7 @@ LocalApicLib TimerLib PrintLib - PeCoffGetEntryPointLib - PeCoffExtraActionLib + UefiImageExtraActionLib MemoryAllocationLib [Guids] diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c index b32754fc2a..64e66b3d29 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c +++ b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c @@ -575,10 +575,7 @@ InitializeDebugAgent ( Phase2Context.InitFlag = InitFlag; Phase2Context.Context = Context; Phase2Context.Function = Function; - DebugPortInitialize ((VOID *)&Phase2Context, InitializeDebugAgentPhase2); - - FindAndReportModuleImageInfo (4); - + DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2); break; case DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64: @@ -606,10 +603,7 @@ InitializeDebugAgent ( // Update IDT entry to save location pointer saved the mailbox pointer // SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer); - - FindAndReportModuleImageInfo (4); } - break; default: diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf index f91e2d01ad..da030e9bc7 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf +++ b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf @@ -66,8 +66,7 @@ PrintLib PeiServicesLib MemoryAllocationLib - PeCoffGetEntryPointLib - PeCoffExtraActionLib + UefiImageExtraActionLib [Ppis] gEfiPeiMemoryDiscoveredPpiGuid ## NOTIFY diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c index cc5bb957f7..633d009ceb 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c +++ b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c @@ -278,11 +278,6 @@ InitializeDebugAgent ( // TriggerSoftInterrupt (MEMORY_READY_SIGNATURE); } - - // - // Find and report PE/COFF image info to HOST - // - FindAndReportModuleImageInfo (SIZE_4KB); // // Restore saved IDT entries // @@ -396,10 +391,7 @@ InitializeDebugAgent ( // SaveAndSetDebugTimerInterrupt (TRUE); EnableInterrupts (); - - FindAndReportModuleImageInfo (SIZE_4KB); } - break; default: diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf index 2084b34a85..e4abdd50cd 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf +++ b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf @@ -63,8 +63,7 @@ LocalApicLib TimerLib PrintLib - PeCoffExtraActionLib - PeCoffGetEntryPointLib + UefiImageExtraActionLib SmmServicesTableLib [Guids] diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.nasm b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.nasm index 9442d3adc5..fc08898254 100644 --- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.nasm +++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.nasm @@ -1,3 +1,5 @@ +#ifndef DISABLE_NEW_DEPRECATED_INTERFACES + ;------------------------------------------------------------------------------ ; ; Copyright (c) 2016, Intel Corporation. All rights reserved.
@@ -20,3 +22,5 @@ ASM_PFX(AsmInterruptHandle): cli mov al, 1 iretd + +#endif // DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c index 2c80f7e22d..80ab235376 100644 --- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c +++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c @@ -1,3 +1,5 @@ +#ifndef DISABLE_NEW_DEPRECATED_INTERFACES + /** @file PE/Coff Extra Action library instances. @@ -27,7 +29,7 @@ IsDrxEnabled ( IN UINTN Dr7 ) { - return (BOOLEAN)(((Dr7 >> (RegisterIndex * 2)) & (BIT0 | BIT1)) == (BIT0 | BIT1)); + return (BOOLEAN) (((Dr7 >> (RegisterIndex * 2)) & (BIT0 | BIT1)) == (BIT0 | BIT1)); } /** @@ -46,25 +48,25 @@ PeCoffLoaderExtraActionCommon ( IN UINTN Signature ) { - BOOLEAN InterruptState; - UINTN Dr0; - UINTN Dr1; - UINTN Dr2; - UINTN Dr3; - UINTN Dr7; - UINTN Cr4; - UINTN NewDr7; - UINT8 LoadImageMethod; - UINT8 DebugAgentStatus; - IA32_DESCRIPTOR IdtDescriptor; - IA32_IDT_GATE_DESCRIPTOR OriginalIdtEntry; - BOOLEAN IdtEntryHooked; - UINT32 RegEdx; + BOOLEAN InterruptState; + UINTN Dr0; + UINTN Dr1; + UINTN Dr2; + UINTN Dr3; + UINTN Dr7; + UINTN Cr4; + UINTN NewDr7; + UINT8 LoadImageMethod; + UINT8 DebugAgentStatus; + IA32_DESCRIPTOR IdtDescriptor; + IA32_IDT_GATE_DESCRIPTOR OriginalIdtEntry; + BOOLEAN IdtEntryHooked; + UINT32 RegEdx; ASSERT (ImageContext != NULL); if (ImageContext->PdbPointer != NULL) { - DEBUG ((DEBUG_ERROR, " PDB = %a\n", ImageContext->PdbPointer)); + DEBUG((EFI_D_ERROR, " PDB = %a\n", ImageContext->PdbPointer)); } // @@ -84,7 +86,6 @@ PeCoffLoaderExtraActionCommon ( LoadImageMethod = DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3; } } - AsmReadIdtr (&IdtDescriptor); if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) { if (!CheckDebugAgentHandler (&IdtDescriptor, SOFT_INT_VECTOR_NUM)) { @@ -123,8 +124,8 @@ PeCoffLoaderExtraActionCommon ( // AsmWriteDr7 (BIT10); AsmWriteDr0 (Signature); - AsmWriteDr1 ((UINTN)ImageContext->PdbPointer); - AsmWriteDr2 ((UINTN)ImageContext); + AsmWriteDr1 ((UINTN) ImageContext->PdbPointer); + AsmWriteDr2 ((UINTN) ImageContext); AsmWriteDr3 (IO_PORT_BREAKPOINT_ADDRESS); if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) { @@ -137,6 +138,7 @@ PeCoffLoaderExtraActionCommon ( do { DebugAgentStatus = IoRead8 (IO_PORT_BREAKPOINT_ADDRESS); } while (DebugAgentStatus == DEBUG_AGENT_IMAGE_WAIT); + } else if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) { // // Generate a software break point. @@ -150,31 +152,26 @@ PeCoffLoaderExtraActionCommon ( // in the above exception handler // NewDr7 = AsmReadDr7 () | BIT10; // H/w sets bit 10, some simulators don't - if (!IsDrxEnabled (0, NewDr7) && ((AsmReadDr0 () == 0) || (AsmReadDr0 () == Signature))) { + if (!IsDrxEnabled (0, NewDr7) && (AsmReadDr0 () == 0 || AsmReadDr0 () == Signature)) { // // If user changed Dr3 (by setting HW bp in the above exception handler, // we will not set Dr0 to 0 in GO/STEP handler because the break cause is not IMAGE_LOAD/_UNLOAD. // AsmWriteDr0 (Dr0); } - - if (!IsDrxEnabled (1, NewDr7) && (AsmReadDr1 () == (UINTN)ImageContext->PdbPointer)) { + if (!IsDrxEnabled (1, NewDr7) && (AsmReadDr1 () == (UINTN) ImageContext->PdbPointer)) { AsmWriteDr1 (Dr1); } - - if (!IsDrxEnabled (2, NewDr7) && (AsmReadDr2 () == (UINTN)ImageContext)) { + if (!IsDrxEnabled (2, NewDr7) && (AsmReadDr2 () == (UINTN) ImageContext)) { AsmWriteDr2 (Dr2); } - if (!IsDrxEnabled (3, NewDr7) && (AsmReadDr3 () == IO_PORT_BREAKPOINT_ADDRESS)) { AsmWriteDr3 (Dr3); } - if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) { if (AsmReadCr4 () == (Cr4 | BIT3)) { AsmWriteCr4 (Cr4); } - if (NewDr7 == 0x20000480) { AsmWriteDr7 (Dr7); } @@ -183,14 +180,12 @@ PeCoffLoaderExtraActionCommon ( AsmWriteDr7 (Dr7); } } - // // Restore original IDT entry for INT1 if it was hooked. // if (IdtEntryHooked) { RestoreIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry); } - // // Restore the interrupt state // @@ -229,3 +224,5 @@ PeCoffLoaderUnloadImageExtraAction ( { PeCoffLoaderExtraActionCommon (ImageContext, IMAGE_UNLOAD_SIGNATURE); } + +#endif // DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.nasm b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.nasm index 6b3a7a526f..2aa9280797 100644 --- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.nasm +++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.nasm @@ -1,3 +1,5 @@ +#ifndef DISABLE_NEW_DEPRECATED_INTERFACES + ;------------------------------------------------------------------------------ ; ; Copyright (c) 2016, Intel Corporation. All rights reserved.
@@ -21,3 +23,5 @@ ASM_PFX(AsmInterruptHandle): cli mov al, 1 iretq + +#endif // DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/Ia32/IntHandler.nasm b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/Ia32/IntHandler.nasm new file mode 100644 index 0000000000..9442d3adc5 --- /dev/null +++ b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/Ia32/IntHandler.nasm @@ -0,0 +1,22 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2016, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; IntHandler.nasm +; +; Abstract: +; +; Assembly interrupt handler function. +; +;------------------------------------------------------------------------------ + +global ASM_PFX(AsmInterruptHandle) + +SECTION .text +ASM_PFX(AsmInterruptHandle): + cli + mov al, 1 + iretd diff --git a/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/Ia32/IntHandlerFuncs.c b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/Ia32/IntHandlerFuncs.c new file mode 100644 index 0000000000..9e2934fda5 --- /dev/null +++ b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/Ia32/IntHandlerFuncs.c @@ -0,0 +1,93 @@ +/** @file + Ia32 arch functions to access IDT vector. + + Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +/** + Read IDT entry to check if IDT entries are setup by Debug Agent. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[in] InterruptType Interrupt type. + + @retval TRUE IDT entries were setup by Debug Agent. + @retval FALSE IDT entries were not setuo by Debug Agent. + +**/ +BOOLEAN +CheckDebugAgentHandler ( + IN IA32_DESCRIPTOR *IdtDescriptor, + IN UINTN InterruptType + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + UINTN InterruptHandler; + + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base; + if (IdtEntry == NULL) { + return FALSE; + } + + InterruptHandler = IdtEntry[InterruptType].Bits.OffsetLow + + (IdtEntry[InterruptType].Bits.OffsetHigh << 16); + if ((InterruptHandler >= sizeof (UINT32)) && (*(UINT32 *)(InterruptHandler - sizeof (UINT32)) == AGENT_HANDLER_SIGNATURE)) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Save IDT entry for INT1 and update it. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[out] SavedIdtEntry Original IDT entry returned. + +**/ +VOID +SaveAndUpdateIdtEntry1 ( + IN IA32_DESCRIPTOR *IdtDescriptor, + OUT IA32_IDT_GATE_DESCRIPTOR *SavedIdtEntry + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + UINT16 CodeSegment; + UINTN InterruptHandler; + + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base; + CopyMem (SavedIdtEntry, &IdtEntry[1], sizeof (IA32_IDT_GATE_DESCRIPTOR)); + + // + // Use current CS as the segment selector of interrupt gate in IDT + // + CodeSegment = AsmReadCs (); + + InterruptHandler = (UINTN)&AsmInterruptHandle; + IdtEntry[1].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; + IdtEntry[1].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); + IdtEntry[1].Bits.Selector = CodeSegment; + IdtEntry[1].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; +} + +/** + Restore IDT entry for INT1. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[in] RestoredIdtEntry IDT entry to be restored. + +**/ +VOID +RestoreIdtEntry1 ( + IN IA32_DESCRIPTOR *IdtDescriptor, + IN IA32_IDT_GATE_DESCRIPTOR *RestoredIdtEntry + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base; + CopyMem (&IdtEntry[1], RestoredIdtEntry, sizeof (IA32_IDT_GATE_DESCRIPTOR)); +} diff --git a/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.c b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.c new file mode 100644 index 0000000000..35f7db1258 --- /dev/null +++ b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.c @@ -0,0 +1,241 @@ +/** @file + PE/Coff Extra Action library instances. + + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Library/UefiImageLib.h" +#include "ProcessorBind.h" +#include "Uefi/UefiBaseType.h" +#include + +/** + Check if the hardware breakpoint in Drx is enabled by checking the Lx and Gx bit in Dr7. + + It assumes that DebugAgent will set both Lx and Gx bit when setting up the hardware breakpoint. + + + @param RegisterIndex Index of Dr register. The value range is from 0 to 3. + @param Dr7 Value of Dr7 register. + + @return TRUE The hardware breakpoint specified in the Drx is enabled. + @return FALSE The hardware breakpoint specified in the Drx is disabled. + +**/ +BOOLEAN +IsDrxEnabled ( + IN UINT8 RegisterIndex, + IN UINTN Dr7 + ) +{ + return (BOOLEAN)(((Dr7 >> (RegisterIndex * 2)) & (BIT0 | BIT1)) == (BIT0 | BIT1)); +} + +/** + Common routine to report the PE/COFF image loading/relocating or unloading event. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image. + @param Signature IMAGE_LOAD_SIGNATURE or IMAGE_UNLOAD_SIGNATURE. + +**/ +VOID +UefiImageLoaderExtraActionCommon ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + IN UINTN Signature + ) +{ + BOOLEAN InterruptState; + UINTN Dr0; + UINTN Dr1; + UINTN Dr2; + UINTN Dr3; + UINTN Dr7; + UINTN Cr4; + UINTN NewDr7; + UINT8 LoadImageMethod; + UINT8 DebugAgentStatus; + IA32_DESCRIPTOR IdtDescriptor; + IA32_IDT_GATE_DESCRIPTOR OriginalIdtEntry; + BOOLEAN IdtEntryHooked; + UINT32 RegEdx; + RETURN_STATUS Status; + CONST CHAR8 *PdbPath; + UINT32 PdbPathSize; + EFI_PHYSICAL_ADDRESS ImageBase; + + ASSERT (ImageContext != NULL); + + Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize); + if (!RETURN_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, " PDB = %a\n", PdbPath)); + } + + // + // Disable interrupts and save the current interrupt state + // + InterruptState = SaveAndDisableInterrupts (); + + IdtEntryHooked = FALSE; + LoadImageMethod = PcdGet8 (PcdDebugLoadImageMethod); + if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) { + // + // If the CPU does not support Debug Extensions(CPUID:01 EDX:BIT2) + // then force use of DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3 + // + AsmCpuid (1, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT2) == 0) { + LoadImageMethod = DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3; + } + } + + AsmReadIdtr (&IdtDescriptor); + if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) { + if (!CheckDebugAgentHandler (&IdtDescriptor, SOFT_INT_VECTOR_NUM)) { + // + // Do not trigger INT3 if Debug Agent did not setup IDT entries. + // + return; + } + } else { + if (!CheckDebugAgentHandler (&IdtDescriptor, IO_HW_BREAKPOINT_VECTOR_NUM)) { + // + // Save and update IDT entry for INT1 + // + SaveAndUpdateIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry); + IdtEntryHooked = TRUE; + } + } + + ImageBase = UefiImageLoaderGetImageAddress (ImageContext); + + // + // Save Debug Register State + // + Dr0 = AsmReadDr0 (); + Dr1 = AsmReadDr1 (); + Dr2 = AsmReadDr2 (); + Dr3 = AsmReadDr3 (); + Dr7 = AsmReadDr7 () | BIT10; // H/w sets bit 10, some simulators don't + Cr4 = AsmReadCr4 (); + + // + // DR0 = Signature + // DR1 = The address of the Null-terminated ASCII string for the PE/COFF image's PDB file name + // DR2 = The pointer to the ImageBase address + // DR3 = IO_PORT_BREAKPOINT_ADDRESS + // DR7 = Disables all HW breakpoints except for DR3 I/O port access of length 1 byte + // CR4 = Make sure DE(BIT3) is set + // + AsmWriteDr7 (BIT10); + AsmWriteDr0 (Signature); + AsmWriteDr1 ((UINTN)PdbPath); + AsmWriteDr2 ((UINTN)&ImageBase); + AsmWriteDr3 (IO_PORT_BREAKPOINT_ADDRESS); + + if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) { + AsmWriteDr7 (0x20000480); + AsmWriteCr4 (Cr4 | BIT3); + // + // Do an IN from IO_PORT_BREAKPOINT_ADDRESS to generate a HW breakpoint until the port + // returns a read value other than DEBUG_AGENT_IMAGE_WAIT + // + do { + DebugAgentStatus = IoRead8 (IO_PORT_BREAKPOINT_ADDRESS); + } while (DebugAgentStatus == DEBUG_AGENT_IMAGE_WAIT); + } else if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) { + // + // Generate a software break point. + // + CpuBreakpoint (); + } + + // + // Restore Debug Register State only when Host didn't change it inside exception handler. + // E.g.: User halts the target and sets the HW breakpoint while target is + // in the above exception handler + // + NewDr7 = AsmReadDr7 () | BIT10; // H/w sets bit 10, some simulators don't + if (!IsDrxEnabled (0, NewDr7) && ((AsmReadDr0 () == 0) || (AsmReadDr0 () == Signature))) { + // + // If user changed Dr3 (by setting HW bp in the above exception handler, + // we will not set Dr0 to 0 in GO/STEP handler because the break cause is not IMAGE_LOAD/_UNLOAD. + // + AsmWriteDr0 (Dr0); + } + + if (!IsDrxEnabled (1, NewDr7) && (AsmReadDr1 () == (UINTN)PdbPath)) { + AsmWriteDr1 (Dr1); + } + + if (!IsDrxEnabled (2, NewDr7) && (AsmReadDr2 () == (UINTN)&ImageBase)) { + AsmWriteDr2 (Dr2); + } + + if (!IsDrxEnabled (3, NewDr7) && (AsmReadDr3 () == IO_PORT_BREAKPOINT_ADDRESS)) { + AsmWriteDr3 (Dr3); + } + + if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) { + if (AsmReadCr4 () == (Cr4 | BIT3)) { + AsmWriteCr4 (Cr4); + } + + if (NewDr7 == 0x20000480) { + AsmWriteDr7 (Dr7); + } + } else if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) { + if (NewDr7 == BIT10) { + AsmWriteDr7 (Dr7); + } + } + + // + // Restore original IDT entry for INT1 if it was hooked. + // + if (IdtEntryHooked) { + RestoreIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry); + } + + // + // Restore the interrupt state + // + SetInterruptState (InterruptState); +} + +/** + Performs additional actions after a PE/COFF image has been loaded and relocated. + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that has already been loaded and relocated. + +**/ +VOID +EFIAPI +UefiImageLoaderRelocateImageExtraAction ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + UefiImageLoaderExtraActionCommon (ImageContext, IMAGE_LOAD_SIGNATURE); +} + +/** + Performs additional actions just before a PE/COFF image is unloaded. Any resources + that were allocated by UefiImageLoaderRelocateImageExtraAction() must be freed. + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that is being unloaded. + +**/ +VOID +EFIAPI +UefiImageLoaderUnloadImageExtraAction ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + UefiImageLoaderExtraActionCommon (ImageContext, IMAGE_UNLOAD_SIGNATURE); +} diff --git a/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.h b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.h new file mode 100644 index 0000000000..594ad394aa --- /dev/null +++ b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.h @@ -0,0 +1,72 @@ +/** @file + PE/Coff Extra Action library instances, it will report image debug info. + + Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _UEFI_IMAGE_EXTRA_ACTION_LIB_H_ +#define _UEFI_IMAGE_EXTRA_ACTION_LIB_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT 1 +#define DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3 2 + +#define IO_HW_BREAKPOINT_VECTOR_NUM 1 +#define SOFT_INT_VECTOR_NUM 3 + +extern UINTN AsmInterruptHandle; + +/** + Read IDT entry to check if IDT entries are setup by Debug Agent. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[in] InterruptType Interrupt type. + + @retval TRUE IDT entries were setup by Debug Agent. + @retval FALSE IDT entries were not setuo by Debug Agent. + +**/ +BOOLEAN +CheckDebugAgentHandler ( + IN IA32_DESCRIPTOR *IdtDescriptor, + IN UINTN InterruptType + ); + +/** + Save IDT entry for INT1 and update it. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[out] SavedIdtEntry Original IDT entry returned. + +**/ +VOID +SaveAndUpdateIdtEntry1 ( + IN IA32_DESCRIPTOR *IdtDescriptor, + OUT IA32_IDT_GATE_DESCRIPTOR *SavedIdtEntry + ); + +/** + Restore IDT entry for INT1. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[in] RestoredIdtEntry IDT entry to be restored. + +**/ +VOID +RestoreIdtEntry1 ( + IN IA32_DESCRIPTOR *IdtDescriptor, + IN IA32_IDT_GATE_DESCRIPTOR *RestoredIdtEntry + ); + +#endif diff --git a/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.uni b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.uni new file mode 100644 index 0000000000..f2ba4aa32d --- /dev/null +++ b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.uni @@ -0,0 +1,15 @@ +// /** @file +// UefiImageExtraAction Library to support source level debug. +// +// UefiImageExtraAction Library to support source level debug. +// +// Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "UefiImageExtraAction Library to support source level debug" + +#string STR_MODULE_DESCRIPTION #language en-US "UefiImageExtraAction Library to support source level debug." diff --git a/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf new file mode 100644 index 0000000000..82a3dc7971 --- /dev/null +++ b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf @@ -0,0 +1,50 @@ +## @file +# UefiImageExtraAction Library to support source level debug. +# +# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UefiImageExtraActionLib + MODULE_UNI_FILE = UefiImageExtraActionLib.uni + FILE_GUID = 8F01CBD5-E069-44d7-90C9-35F0318603AD + MODULE_TYPE = BASE + VERSION_STRING = 0.8 + LIBRARY_CLASS = UefiImageExtraActionLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.common] + UefiImageExtraActionLib.h + UefiImageExtraActionLib.c + +[Sources.IA32] + Ia32/IntHandlerFuncs.c + Ia32/IntHandler.nasm + +[Sources.X64] + X64/IntHandlerFuncs.c + X64/IntHandler.nasm + +[Packages] + MdePkg/MdePkg.dec + SourceLevelDebugPkg/SourceLevelDebugPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + IoLib + PcdLib + +[Pcd] + gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod ## CONSUMES + diff --git a/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/X64/IntHandler.nasm b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/X64/IntHandler.nasm new file mode 100644 index 0000000000..6b3a7a526f --- /dev/null +++ b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/X64/IntHandler.nasm @@ -0,0 +1,23 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2016, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; IntHandler.nasm +; +; Abstract: +; +; Assembly interrupt handler function. +; +;------------------------------------------------------------------------------ + +global ASM_PFX(AsmInterruptHandle) + +DEFAULT REL +SECTION .text +ASM_PFX(AsmInterruptHandle): + cli + mov al, 1 + iretq diff --git a/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/X64/IntHandlerFuncs.c b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/X64/IntHandlerFuncs.c new file mode 100644 index 0000000000..a518892d2c --- /dev/null +++ b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/X64/IntHandlerFuncs.c @@ -0,0 +1,95 @@ +/** @file + X64 arch function to access IDT vector. + + Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +/** + Read IDT entry to check if IDT entries are setup by Debug Agent. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[in] InterruptType Interrupt type. + + @retval TRUE IDT entries were setup by Debug Agent. + @retval FALSE IDT entries were not setuo by Debug Agent. + +**/ +BOOLEAN +CheckDebugAgentHandler ( + IN IA32_DESCRIPTOR *IdtDescriptor, + IN UINTN InterruptType + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + UINTN InterruptHandler; + + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base; + if (IdtEntry == NULL) { + return FALSE; + } + + InterruptHandler = IdtEntry[InterruptType].Bits.OffsetLow + + (((UINTN)IdtEntry[InterruptType].Bits.OffsetHigh) << 16) + + (((UINTN)IdtEntry[InterruptType].Bits.OffsetUpper) << 32); + if ((InterruptHandler >= sizeof (UINT32)) && (*(UINT32 *)(InterruptHandler - sizeof (UINT32)) == AGENT_HANDLER_SIGNATURE)) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Save IDT entry for INT1 and update it. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[out] SavedIdtEntry Original IDT entry returned. + +**/ +VOID +SaveAndUpdateIdtEntry1 ( + IN IA32_DESCRIPTOR *IdtDescriptor, + OUT IA32_IDT_GATE_DESCRIPTOR *SavedIdtEntry + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + UINT16 CodeSegment; + UINTN InterruptHandler; + + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base; + CopyMem (SavedIdtEntry, &IdtEntry[1], sizeof (IA32_IDT_GATE_DESCRIPTOR)); + + // + // Use current CS as the segment selector of interrupt gate in IDT + // + CodeSegment = AsmReadCs (); + + InterruptHandler = (UINTN)&AsmInterruptHandle; + IdtEntry[1].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; + IdtEntry[1].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); + IdtEntry[1].Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32); + IdtEntry[1].Bits.Selector = CodeSegment; + IdtEntry[1].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; +} + +/** + Restore IDT entry for INT1. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[in] RestoredIdtEntry IDT entry to be restored. + +**/ +VOID +RestoreIdtEntry1 ( + IN IA32_DESCRIPTOR *IdtDescriptor, + IN IA32_IDT_GATE_DESCRIPTOR *RestoredIdtEntry + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base; + CopyMem (&IdtEntry[1], RestoredIdtEntry, sizeof (IA32_IDT_GATE_DESCRIPTOR)); +} diff --git a/SourceLevelDebugPkg/SourceLevelDebugPkg.dec b/SourceLevelDebugPkg/SourceLevelDebugPkg.dec index 564aca6e7c..a743a69bfe 100644 --- a/SourceLevelDebugPkg/SourceLevelDebugPkg.dec +++ b/SourceLevelDebugPkg/SourceLevelDebugPkg.dec @@ -3,7 +3,7 @@ # The target side components includes the Debug Agent Library instance # to communicate with host side modules, Debug Communication Library and # instances to provide the communication I/O functions between Debug Agent -# and host, PeCoffExtraActionLib instance to report symbol path information, +# and host, UefiImageExtraActionLib instance to report symbol path information, # etc. # # Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
diff --git a/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc b/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc index 986dd5a769..744b9527b4 100644 --- a/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc +++ b/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc @@ -35,9 +35,9 @@ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf - PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf + UefiImageExtraActionLib|SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf TimerLib|UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf @@ -100,7 +100,7 @@ SourceLevelDebugPkg/Library/DebugCommunicationLibUsb3/DebugCommunicationLibUsb3Pei.inf SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf SourceLevelDebugPkg/Library/DebugCommunicationLibUsb/DebugCommunicationLibUsb.inf - SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf + SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf diff --git a/SourceLevelDebugPkg/SourceLevelDebugPkg.uni b/SourceLevelDebugPkg/SourceLevelDebugPkg.uni index 8d2f06eb4e..2613c5fd2e 100644 --- a/SourceLevelDebugPkg/SourceLevelDebugPkg.uni +++ b/SourceLevelDebugPkg/SourceLevelDebugPkg.uni @@ -5,7 +5,7 @@ // The target side components includes the Debug Agent Library instance // to communicate with host side modules, Debug Communication Library and // instances to provide the communication I/O functions between Debug Agent -// and host, PeCoffExtraActionLib instance to report symbol path information, +// and host, UefiImageExtraActionLib instance to report symbol path information, // etc. // // Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
@@ -20,7 +20,7 @@ #string STR_PACKAGE_DESCRIPTION #language en-US "The target side components includes the Debug Agent Library instance\n" "to communicate with host side modules, Debug Communication Library and\n" "instances to provide the communication I/O functions between Debug Agent\n" - "and host, PeCoffExtraActionLib instance to report symbol path information,\n" + "and host, UefiImageExtraActionLib instance to report symbol path information,\n" "etc." diff --git a/StandaloneMmPkg/Core/Dispatcher.c b/StandaloneMmPkg/Core/Dispatcher.c index b686c31aaf..eeed408eb6 100644 --- a/StandaloneMmPkg/Core/Dispatcher.c +++ b/StandaloneMmPkg/Core/Dispatcher.c @@ -36,6 +36,7 @@ **/ +#include "ProcessorBind.h" #include "StandaloneMmCore.h" // @@ -97,6 +98,76 @@ BOOLEAN gDispatcherRunning = FALSE; // BOOLEAN gRequestDispatch = FALSE; +STATIC +RETURN_STATUS +InternalProtectMmImage ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + UEFI_IMAGE_RECORD *ImageRecord; + UINTN SectionAddress; + UINT32 SectionIndex; + + if (UefiImageGetSegmentAlignment (ImageContext) < EFI_PAGE_SIZE) { + // FIXME: PCD to abort loading? + // + // The sections need to be at least 4 KB aligned, since that is the + // granularity at which we can tighten permissions. So just clear the + // noexec permissions on the entire region. + // + DEBUG ((DEBUG_WARN, + "%a: Image at 0x%lx has SectionAlignment < 4 KB (%lu)\n", + __FUNCTION__, UefiImageLoaderGetImageAddress (ImageContext), UefiImageGetSegmentAlignment (ImageContext))); + + ASSERT ((UefiImageLoaderGetImageAddress (ImageContext) & (EFI_PAGE_SIZE - 1)) == 0); + + ClearMemoryRegionNoExec ( + UefiImageLoaderGetImageAddress (ImageContext), + ALIGN_VALUE (UefiImageGetImageSize (ImageContext), EFI_PAGE_SIZE) + ); + + return RETURN_SUCCESS; + } + + ImageRecord = UefiImageLoaderGetImageRecord (ImageContext); + if (ImageRecord == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + // + // Images are loaded into RW memory, thus only +X and -W need to be handled. + // + SectionAddress = ImageRecord->StartAddress; + for (SectionIndex = 0; SectionIndex < ImageRecord->NumSegments; ++ SectionIndex) { + DEBUG ((DEBUG_INFO, + "%a: Mapping segment of image at 0x%lx with %s-%s permissions and size 0x%x\n", + __FUNCTION__, SectionAddress, + (ImageRecord->Segments[SectionIndex].Attributes & EFI_MEMORY_RO) != 0 ? "RO" : "RW", + (ImageRecord->Segments[SectionIndex].Attributes & EFI_MEMORY_XP) != 0 ? "XN" : "X", + ImageRecord->Segments[SectionIndex].Size)); + + // FIXME: What about their return values? + if ((ImageRecord->Segments[SectionIndex].Attributes & EFI_MEMORY_RO) != 0) { + SetMemoryRegionReadOnly ( + SectionAddress, + ImageRecord->Segments[SectionIndex].Size + ); + } + + if ((ImageRecord->Segments[SectionIndex].Attributes & EFI_MEMORY_XP) == 0) { + ClearMemoryRegionNoExec ( + SectionAddress, + ImageRecord->Segments[SectionIndex].Size + ); + } + + SectionAddress += ImageRecord->Segments[SectionIndex].Size; + } + + FreePool (ImageRecord); + + return RETURN_SUCCESS; +} + /** Loads an EFI image into SMRAM. @@ -113,9 +184,12 @@ MmLoadImage ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext ) { - UINTN PageCount; - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS DstBuffer; + UINT32 ImageSize; + UINT32 ImageAlignment; + EFI_STATUS Status; + VOID *DstBuffer; + UINT32 DstBufferPages; + UINT32 DstBufferSize; DEBUG ((DEBUG_INFO, "MmLoadImage - %g\n", &DriverEntry->FileName)); @@ -125,73 +199,39 @@ MmLoadImage ( Status = EFI_SUCCESS; - // - // Initialize ImageContext - // - ImageContext->Handle = DriverEntry->Pe32Data; - ImageContext->ImageRead = PeCoffLoaderImageReadFromMemory; - // // Get information about the image being loaded // - Status = PeCoffLoaderGetImageInfo (ImageContext); + Status = UefiImageInitializeContext (ImageContext, DriverEntry->Pe32Data, DriverEntry->Pe32DataSize); if (EFI_ERROR (Status)) { return Status; } - PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext->ImageSize + ImageContext->SectionAlignment); - DstBuffer = (UINTN)(-1); + ImageSize = UefiImageGetImageSize (ImageContext); + DstBufferPages = EFI_SIZE_TO_PAGES (ImageSize); + DstBufferSize = EFI_PAGES_TO_SIZE (DstBufferPages); + ImageAlignment = UefiImageGetSegmentAlignment (ImageContext); - Status = MmAllocatePages ( - AllocateMaxAddress, - EfiRuntimeServicesCode, - PageCount, - &DstBuffer - ); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; + DstBuffer = AllocateAlignedCodePages (DstBufferPages, ImageAlignment); + if (DstBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; } - ImageContext->ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer; - - // - // Align buffer on section boundary - // - ImageContext->ImageAddress += ImageContext->SectionAlignment - 1; - ImageContext->ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)(ImageContext->SectionAlignment - 1)); - // // Load the image to our new buffer // - Status = PeCoffLoaderLoadImage (ImageContext); - if (EFI_ERROR (Status)) { - MmFreePages (DstBuffer, PageCount); - return Status; - } - - // - // Relocate the image in our new buffer - // - Status = PeCoffLoaderRelocateImage (ImageContext); + Status = UefiImageLoadImageForExecution (ImageContext, DstBuffer, DstBufferSize, NULL, 0); if (EFI_ERROR (Status)) { - // if relocate fails, we don't need to call unload image here, as the extra action that may change page attributes - // only is called on a successful return - MmFreePages (DstBuffer, PageCount); + FreeAlignedPages (DstBuffer, DstBufferPages); return Status; } - // - // Flush the instruction cache so the image data are written before we execute it - // - InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext->ImageAddress, (UINTN)ImageContext->ImageSize); - // // Save Image EntryPoint in DriverEntry // - DriverEntry->ImageEntryPoint = ImageContext->EntryPoint; - DriverEntry->ImageBuffer = DstBuffer; - DriverEntry->NumberOfPage = PageCount; + DriverEntry->ImageEntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext); + DriverEntry->ImageBuffer = (UINTN)DstBuffer; + DriverEntry->NumberOfPage = DstBufferPages; // // Fill in the remaining fields of the Loaded Image Protocol instance. @@ -203,8 +243,8 @@ MmLoadImage ( DriverEntry->LoadedImage.DeviceHandle = NULL; DriverEntry->LoadedImage.FilePath = NULL; - DriverEntry->LoadedImage.ImageBase = (VOID *)(UINTN)DriverEntry->ImageBuffer; - DriverEntry->LoadedImage.ImageSize = ImageContext->ImageSize; + DriverEntry->LoadedImage.ImageBase = DstBuffer; + DriverEntry->LoadedImage.ImageSize = ImageSize; DriverEntry->LoadedImage.ImageCodeType = EfiRuntimeServicesCode; DriverEntry->LoadedImage.ImageDataType = EfiRuntimeServicesData; @@ -218,58 +258,32 @@ MmLoadImage ( &DriverEntry->LoadedImage ); + InternalProtectMmImage (ImageContext); + // // Print the load address and the PDB file name if it is available // DEBUG_CODE_BEGIN (); - UINTN Index; - UINTN StartIndex; CHAR8 EfiFileName[256]; DEBUG (( DEBUG_INFO | DEBUG_LOAD, "Loading MM driver at 0x%11p EntryPoint=0x%11p ", - (VOID *)(UINTN)ImageContext->ImageAddress, - FUNCTION_ENTRY_POINT (ImageContext->EntryPoint) + DstBuffer, + FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext)) )); + Status = UefiImageGetModuleNameFromSymbolsPath ( + ImageContext, + EfiFileName, + sizeof (EfiFileName) + ); + // // Print Module Name by Pdb file path. - // Windows and Unix style file path are all trimmed correctly. // - if (ImageContext->PdbPointer != NULL) { - StartIndex = 0; - for (Index = 0; ImageContext->PdbPointer[Index] != 0; Index++) { - if ((ImageContext->PdbPointer[Index] == '\\') || (ImageContext->PdbPointer[Index] == '/')) { - StartIndex = Index + 1; - } - } - - // - // Copy the PDB file name to our temporary string, and replace .pdb with .efi - // The PDB file name is limited in the range of 0~255. - // If the length is bigger than 255, trim the redundant characters to avoid overflow in array boundary. - // - for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) { - EfiFileName[Index] = ImageContext->PdbPointer[Index + StartIndex]; - if (EfiFileName[Index] == 0) { - EfiFileName[Index] = '.'; - } - - if (EfiFileName[Index] == '.') { - EfiFileName[Index + 1] = 'e'; - EfiFileName[Index + 2] = 'f'; - EfiFileName[Index + 3] = 'i'; - EfiFileName[Index + 4] = 0; - break; - } - } - - if (Index == sizeof (EfiFileName) - 4) { - EfiFileName[Index] = 0; - } - + if (!EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); } @@ -699,7 +713,7 @@ EFI_STATUS MmAddToDriverList ( IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader, IN VOID *Pe32Data, - IN UINTN Pe32DataSize, + IN UINT32 Pe32DataSize, IN VOID *Depex, IN UINTN DepexSize, IN EFI_GUID *DriverName diff --git a/StandaloneMmPkg/Core/FwVol.c b/StandaloneMmPkg/Core/FwVol.c index d5dfdacbf0..d059329204 100644 --- a/StandaloneMmPkg/Core/FwVol.c +++ b/StandaloneMmPkg/Core/FwVol.c @@ -19,7 +19,7 @@ EFI_STATUS MmAddToDriverList ( IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader, IN VOID *Pe32Data, - IN UINTN Pe32DataSize, + IN UINT32 Pe32DataSize, IN VOID *Depex, IN UINTN DepexSize, IN EFI_GUID *DriverName @@ -65,12 +65,12 @@ MmCoreFfsFindMmDriver ( EFI_STATUS DepexStatus; EFI_FFS_FILE_HEADER *FileHeader; VOID *Pe32Data; - UINTN Pe32DataSize; + UINT32 Pe32DataSize; VOID *Depex; - UINTN DepexSize; + UINT32 DepexSize; EFI_COMMON_SECTION_HEADER *Section; VOID *SectionData; - UINTN SectionDataSize; + UINT32 SectionDataSize; UINT32 DstBufferSize; VOID *ScratchBuffer; UINT32 ScratchBufferSize; diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h index 24574b254c..de7cdf50ab 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.h +++ b/StandaloneMmPkg/Core/StandaloneMmCore.h @@ -34,9 +34,10 @@ #include #include +#include #include #include -#include +#include #include #include #include @@ -74,7 +75,7 @@ typedef struct { EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; EFI_GUID FileName; VOID *Pe32Data; - UINTN Pe32DataSize; + UINT32 Pe32DataSize; VOID *Depex; UINTN DepexSize; diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf index aca21a7e20..ec9283df7a 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.inf +++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf @@ -50,8 +50,9 @@ HobLib MemoryAllocationLib MemLib - PeCoffLib + UefiImageLib ReportStatusCodeLib + StandaloneMmProtectionLib StandaloneMmCoreEntryPoint HobPrintLib ImagePropertiesRecordLib @@ -88,13 +89,10 @@ gStandaloneMmPkgTokenSpaceGuid.PcdShadowBfv ##CONSUMES # -# This configuration fails for CLANGPDB, which does not support PIE in the GCC -# sense. Such however is required for ARM family StandaloneMmCore -# self-relocation, and thus the CLANGPDB toolchain is unsupported for ARM and -# AARCH64 for this module. +# This configuration fails for CLANGDPB, which does not support PIE in the GCC +# sense. Such however is required for AArch64 StandaloneMmCore self-relocation, +# and thus the CLANGPDB toolchain is unsupported for AArch64 for this module. # [BuildOptions] - GCC:*_*_ARM_CC_FLAGS = -fpie - GCC:*_*_ARM_DLINK_FLAGS = -Wl,-z,text,-Bsymbolic,-pie GCC:*_*_AARCH64_CC_FLAGS = -fpie GCC:*_*_AARCH64_DLINK_FLAGS = -Wl,-z,text,-Bsymbolic,-pie diff --git a/StandaloneMmPkg/Include/Library/FvLib.h b/StandaloneMmPkg/Include/Library/FvLib.h index 3b603e473d..2c951b4691 100644 --- a/StandaloneMmPkg/Include/Library/FvLib.h +++ b/StandaloneMmPkg/Include/Library/FvLib.h @@ -98,7 +98,7 @@ FfsFindSectionData ( IN EFI_SECTION_TYPE SectionType, IN EFI_FFS_FILE_HEADER *FfsFileHeader, OUT VOID **SectionData, - OUT UINTN *SectionDataSize + OUT UINT32 *SectionDataSize ); #endif diff --git a/StandaloneMmPkg/Include/Library/StandaloneMmProtectionLib.h b/StandaloneMmPkg/Include/Library/StandaloneMmProtectionLib.h new file mode 100644 index 0000000000..395aaff910 --- /dev/null +++ b/StandaloneMmPkg/Include/Library/StandaloneMmProtectionLib.h @@ -0,0 +1,30 @@ +// FIXME: docs + +#ifndef STANDALONE_MM_PROTECTION_LIB_H_ +#define STANDALONE_MM_PROTECTION_LIB_H_ + +EFI_STATUS +SetMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ); + +EFI_STATUS +ClearMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ); + +EFI_STATUS +SetMemoryRegionReadOnly ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ); + +EFI_STATUS +ClearMemoryRegionReadOnly ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ); + +#endif // STANDALONE_MM_PROTECTION_LIB_H_ diff --git a/StandaloneMmPkg/Library/FvLib/FvLib.c b/StandaloneMmPkg/Library/FvLib/FvLib.c index 2faa7cd054..5693031758 100644 --- a/StandaloneMmPkg/Library/FvLib/FvLib.c +++ b/StandaloneMmPkg/Library/FvLib/FvLib.c @@ -353,7 +353,7 @@ FfsFindSectionData ( IN EFI_SECTION_TYPE SectionType, IN EFI_FFS_FILE_HEADER *FfsFileHeader, IN OUT VOID **SectionData, - IN OUT UINTN *SectionDataSize + IN OUT UINT32 *SectionDataSize ) { UINT32 FileSize; diff --git a/StandaloneMmPkg/Library/StandaloneMmProtectionLib/ProtectionAarch64.c b/StandaloneMmPkg/Library/StandaloneMmProtectionLib/ProtectionAarch64.c new file mode 100644 index 0000000000..b1258fb373 --- /dev/null +++ b/StandaloneMmPkg/Library/StandaloneMmProtectionLib/ProtectionAarch64.c @@ -0,0 +1,41 @@ +// FIXME: Docs, more general libclass for DXE? + +#include + +#include + +EFI_STATUS +SetMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + return ArmSetMemoryRegionNoExec (BaseAddress, Length); +} + +EFI_STATUS +ClearMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + return ArmClearMemoryRegionNoExec (BaseAddress, Length); +} + +EFI_STATUS +SetMemoryRegionReadOnly ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + return ArmSetMemoryRegionReadOnly (BaseAddress, Length); +} + +EFI_STATUS +ClearMemoryRegionReadOnly ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + return ArmClearMemoryRegionReadOnly (BaseAddress, Length); +} diff --git a/StandaloneMmPkg/Library/StandaloneMmProtectionLib/ProtectionNull.c b/StandaloneMmPkg/Library/StandaloneMmProtectionLib/ProtectionNull.c new file mode 100644 index 0000000000..706762d8c8 --- /dev/null +++ b/StandaloneMmPkg/Library/StandaloneMmProtectionLib/ProtectionNull.c @@ -0,0 +1,49 @@ +#include + +EFI_STATUS +SetMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + (VOID) BaseAddress; + (VOID) Length; + + return RETURN_SUCCESS; +} + +EFI_STATUS +ClearMemoryRegionNoExec ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + (VOID) BaseAddress; + (VOID) Length; + + return RETURN_SUCCESS; +} + +EFI_STATUS +SetMemoryRegionReadOnly ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + (VOID) BaseAddress; + (VOID) Length; + + return RETURN_SUCCESS; +} + +EFI_STATUS +ClearMemoryRegionReadOnly ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +{ + (VOID) BaseAddress; + (VOID) Length; + + return RETURN_SUCCESS; +} diff --git a/StandaloneMmPkg/Library/StandaloneMmProtectionLib/StandaloneMmProtectionLib.inf b/StandaloneMmPkg/Library/StandaloneMmProtectionLib/StandaloneMmProtectionLib.inf new file mode 100644 index 0000000000..fe817c6f8e --- /dev/null +++ b/StandaloneMmPkg/Library/StandaloneMmProtectionLib/StandaloneMmProtectionLib.inf @@ -0,0 +1,29 @@ +# FIXME: Docs +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = StandaloneMmProtectionLib + FILE_GUID = 4FCCC091-D240-4FE3-A922-5153D1DB1649 + MODULE_TYPE = MM_CORE_STANDALONE + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x00010032 + LIBRARY_CLASS = StandaloneMmProtectionLib|MM_CORE_STANDALONE + +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only) +# + +[Sources.AARCH64] + ProtectionAarch64.c + +[Sources.X64, Sources.ARM] + ProtectionNull.c + +[Packages] + MdePkg/MdePkg.dec + StandaloneMmPkg/StandaloneMmPkg.dec + +[Packages.AARCH64] + ArmPkg/ArmPkg.dec + +[LibraryClasses.AARCH64] + StandaloneMmMmuLib diff --git a/StandaloneMmPkg/StandaloneMmPkg.dec b/StandaloneMmPkg/StandaloneMmPkg.dec index 00ec8c076e..903aac7022 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dec +++ b/StandaloneMmPkg/StandaloneMmPkg.dec @@ -30,6 +30,9 @@ [LibraryClasses.X64.PEIM] MmPlatformHobProducerLib|Include/Library/MmPlatformHobProducerLib.h + ## FIXME: docs + StandaloneMmProtectionLib|Include/Library/StandaloneMmProtectionLib.h + [Guids] gStandaloneMmPkgTokenSpaceGuid = { 0x18fe7632, 0xf5c8, 0x4e63, { 0x8d, 0xe8, 0x17, 0xa5, 0x5c, 0x59, 0x13, 0xbd }} gMpInformationHobGuid = { 0xba33f15d, 0x4000, 0x45c1, { 0x8e, 0x88, 0xf9, 0x16, 0x92, 0xd4, 0x57, 0xe3 }} diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index 08b80c9360..dfe51ad519 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -52,11 +52,13 @@ MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf + StandaloneMmProtectionLib|StandaloneMmPkg/Library/StandaloneMmProtectionLib/StandaloneMmProtectionLib.inf VariableMmDependency|StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf HobPrintLib|MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf MmPlatformHobProducerLib|StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf @@ -81,7 +83,6 @@ ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf ArmSvcLib|ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf - PeCoffExtraActionLib|StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf ArmTransferListLib|ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf [LibraryClasses.common.MM_CORE_STANDALONE] @@ -148,6 +149,7 @@ StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf StandaloneMmPkg/Drivers/MmCommunicationDxe/MmCommunicationDxe.inf StandaloneMmPkg/Library/StandaloneMmExtractGuidedSectionLib/StandaloneMmExtractGuidedSectionLib.inf + StandaloneMmPkg/Library/StandaloneMmProtectionLib/StandaloneMmProtectionLib.inf [Components.AARCH64, Components.ARM] StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf diff --git a/UefiCpuPkg/CpuDxe/CpuPageTable.c b/UefiCpuPkg/CpuDxe/CpuPageTable.c index 9a519bcb7e..6a3f1f34ed 100644 --- a/UefiCpuPkg/CpuDxe/CpuPageTable.c +++ b/UefiCpuPkg/CpuDxe/CpuPageTable.c @@ -10,7 +10,7 @@ #include #include -#include + #include #include #include diff --git a/UefiCpuPkg/CpuDxe/CpuPageTable.h b/UefiCpuPkg/CpuDxe/CpuPageTable.h index f2694452f5..3245e97bfb 100644 --- a/UefiCpuPkg/CpuDxe/CpuPageTable.h +++ b/UefiCpuPkg/CpuDxe/CpuPageTable.h @@ -9,7 +9,7 @@ #ifndef _PAGE_TABLE_LIB_H_ #define _PAGE_TABLE_LIB_H_ -#include +#include #include #define PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PSE BIT0 diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c index 903fac927e..76ea152955 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c @@ -118,35 +118,29 @@ DumpModuleImageInfo ( IN UINTN CurrentEip ) { - EFI_STATUS Status; - UINTN Pe32Data; - VOID *PdbPointer; - VOID *EntryPoint; + BOOLEAN Result; + UINTN ImageBase; + CONST CHAR8 *PdbPath; - Pe32Data = PeCoffSearchImageBase (CurrentEip); - if (Pe32Data == 0) { + Result = GetImageInfoByIp (&ImageBase, &PdbPath, CurrentEip); + + if (!Result) { InternalPrintMessage ("!!!! Can't find image information. !!!!\n"); } else { // // Find Image Base entry point // - Status = PeCoffLoaderGetEntryPoint ((VOID *)Pe32Data, &EntryPoint); - if (EFI_ERROR (Status)) { - EntryPoint = NULL; - } InternalPrintMessage ("!!!! Find image based on IP(0x%x) ", CurrentEip); - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)Pe32Data); - if (PdbPointer != NULL) { - InternalPrintMessage ("%a", PdbPointer); + if (PdbPath!= NULL) { + InternalPrintMessage ("%a", PdbPath); } else { InternalPrintMessage ("(No PDB) "); } InternalPrintMessage ( - " (ImageBase=%016lp, EntryPoint=%016p) !!!!\n", - (VOID *)Pe32Data, - EntryPoint + " (ImageBase=%016lp) !!!!\n", + (EFI_PHYSICAL_ADDRESS) ImageBase ); } } diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h index 4593c204a6..95877b8be0 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h @@ -15,7 +15,8 @@ #include #include #include -#include +#include + #include #include #include @@ -321,4 +322,13 @@ AsmGetTssTemplateMap ( OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap ); +// FIXME: +BOOLEAN +GetImageInfoByIp ( + OUT UINTN *ImageBase, + OUT CONST CHAR8 **SymbolsPath, + IN UINTN CurrentEip + ); + #endif + diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf index 9fcba009d6..e8b4deeddd 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf @@ -63,7 +63,6 @@ BaseLib DebugLib MemoryAllocationLib - PeCoffGetEntryPointLib PrintLib SerialPortLib SynchronizationLib @@ -77,3 +76,6 @@ [BuildOptions] XCODE:*_*_X64_NASM_FLAGS = -D NO_ABSOLUTE_RELOCS_IN_TEXT + +[Guids] + gEfiDebugImageInfoTableGuid ## CONSUMES ## SystemTable diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c index d4e9979c92..2a4fca621a 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include CONST UINTN mDoFarReturnFlag = 0; @@ -26,6 +28,8 @@ EXCEPTION_HANDLER_DATA mExceptionHandlerData = { UINT8 mBuffer[CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_STACK_SIZE + sizeof (IA32_TSS_DESCRIPTOR) + CPU_TSS_GDT_SIZE]; +STATIC CONST EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *mDebugImageInfoTable = NULL; + /** Common exception handler. @@ -135,3 +139,51 @@ InitializeSeparateExceptionStacks ( return ArchSetupExceptionStack (Buffer, BufferSize); } } + +BOOLEAN +GetImageInfoByIp ( + OUT UINTN *ImageBase, + OUT CONST CHAR8 **SymbolsPath, + IN UINTN CurrentEip + ) +{ + EFI_STATUS Status; + UINT32 Index; + CONST EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; + + if (mDebugImageInfoTable == NULL) { + Status = EfiGetSystemConfigurationTable ( + &gEfiDebugImageInfoTableGuid, + (VOID **) &mDebugImageInfoTable + ); + if (EFI_ERROR (Status)) { + mDebugImageInfoTable = NULL; + return FALSE; + } + } + + ASSERT (mDebugImageInfoTable != NULL); + + for (Index = 0; Index < mDebugImageInfoTable->TableSize; ++Index) { + if (mDebugImageInfoTable->EfiDebugImageInfoTable[Index].ImageInfoType == NULL) { + continue; + } + + if (*mDebugImageInfoTable->EfiDebugImageInfoTable[Index].ImageInfoType != EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) { + continue; + } + + NormalImage = mDebugImageInfoTable->EfiDebugImageInfoTable[Index].NormalImage; + + ASSERT (NormalImage->LoadedImageProtocolInstance != NULL); + + if (CurrentEip >= (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase && + CurrentEip < (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase + NormalImage->LoadedImageProtocolInstance->ImageSize) { + *ImageBase = (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase; + *SymbolsPath = NormalImage->PdbPath; + return TRUE; + } + } + + return FALSE; +} diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c index 994e3917fb..2e49bd88b6 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c @@ -12,6 +12,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include CONST UINTN mDoFarReturnFlag = 0; @@ -224,3 +225,26 @@ InitializeSeparateExceptionStacks ( return ArchSetupExceptionStack (Buffer, BufferSize); } + +// FIXME: Expose DebugImageInfoTable as PPI? +BOOLEAN +GetImageInfoByIp ( + OUT UINTN *ImageBase, + OUT CONST CHAR8 **SymbolsPath, + IN UINTN CurrentEip + ) +{ + RETURN_STATUS Status; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UINT32 PdbPathSize; + + Status = UefiImageDebugLocateImage (&ImageContext, CurrentEip); + if (RETURN_ERROR (Status)) { + return FALSE; + } + + *ImageBase = UefiImageLoaderGetImageAddress (&ImageContext); + + Status = UefiImageGetSymbolsPath (&ImageContext, SymbolsPath, &PdbPathSize); + return !RETURN_ERROR (Status); +} diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf index 3a11516e32..3db1ad47ab 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf @@ -49,7 +49,7 @@ HobLib LocalApicLib MemoryAllocationLib - PeCoffGetEntryPointLib + UefiImageLib PrintLib SerialPortLib SynchronizationLib diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c index 497cd16499..8351d29b96 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c @@ -222,3 +222,13 @@ InitializeSeparateExceptionStacks ( { return EFI_UNSUPPORTED; } + +BOOLEAN +GetImageInfoByIp ( + OUT UINTN *ImageBase, + OUT CONST CHAR8 **SymbolsPath, + IN UINTN CurrentEip + ) +{ + return FALSE; +} diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf index 64de252dcd..55acb46ebe 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf @@ -54,7 +54,7 @@ [LibraryClasses.common] BaseLib - PeCoffGetEntryPointLib + UefiImageLib PrintLib SerialPortLib diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf index cc280a6ee7..ef835ee9dc 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf @@ -48,7 +48,6 @@ CcExitLib DebugLib LocalApicLib - PeCoffGetEntryPointLib PrintLib SerialPortLib SynchronizationLib @@ -63,3 +62,6 @@ [BuildOptions] XCODE:*_*_X64_NASM_FLAGS = -D NO_ABSOLUTE_RELOCS_IN_TEXT + +[Guids] + gEfiDebugImageInfoTableGuid ## CONSUMES ## SystemTable diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c index 46a86ad2c6..d14d00aa7e 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c @@ -8,6 +8,8 @@ #include #include "CpuExceptionCommon.h" +#include +#include CONST UINTN mDoFarReturnFlag = 1; @@ -20,6 +22,7 @@ EXCEPTION_HANDLER_DATA mExceptionHandlerData = { mExternalInterruptHandlerTable }; +STATIC CONST EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *mDebugImageInfoTableHeader = NULL; /** Common exception handler. @@ -118,3 +121,76 @@ InitializeSeparateExceptionStacks ( { return EFI_UNSUPPORTED; } + +// FIXME: Lib? +STATIC +EFI_STATUS +EFIAPI +InternalGetSystemConfigurationTable ( + IN EFI_GUID *TableGuid, + OUT VOID **Table + ) +{ + UINTN Index; + + ASSERT (TableGuid != NULL); + ASSERT (Table != NULL); + + *Table = NULL; + for (Index = 0; Index < gSmst->NumberOfTableEntries; Index++) { + if (CompareGuid (TableGuid, &(gSmst->SmmConfigurationTable[Index].VendorGuid))) { + *Table = gSmst->SmmConfigurationTable[Index].VendorTable; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +BOOLEAN +GetImageInfoByIp ( + OUT UINTN *ImageBase, + OUT CONST CHAR8 **SymbolsPath, + IN UINTN CurrentEip + ) +{ + EFI_STATUS Status; + UINT32 Index; + CONST EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; + + if (mDebugImageInfoTableHeader == NULL) { + Status = InternalGetSystemConfigurationTable ( + &gEfiDebugImageInfoTableGuid, + (VOID **) &mDebugImageInfoTableHeader + ); + if (EFI_ERROR (Status)) { + mDebugImageInfoTableHeader = NULL; + return FALSE; + } + } + + ASSERT (mDebugImageInfoTableHeader != NULL); + + for (Index = 0; Index < mDebugImageInfoTableHeader->TableSize; ++Index) { + if (mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].ImageInfoType == NULL) { + continue; + } + + if (*mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].ImageInfoType != EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) { + continue; + } + + NormalImage = mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].NormalImage; + + ASSERT (NormalImage->LoadedImageProtocolInstance != NULL); + + if (CurrentEip >= (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase && + CurrentEip < (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase + NormalImage->LoadedImageProtocolInstance->ImageSize) { + *ImageBase = (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase; + *SymbolsPath = NormalImage->PdbPath; + return TRUE; + } + } + + return FALSE; +} diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c index c6df9358eb..5e24c12548 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c @@ -182,20 +182,6 @@ DumpModuleInfoByIp ( IN UINTN CallerIpAddress ) { - UINTN Pe32Data; - VOID *PdbPointer; - - // - // Find Image Base - // - Pe32Data = PeCoffSearchImageBase (CallerIpAddress); - if (Pe32Data != 0) { - DEBUG ((DEBUG_ERROR, "It is invoked from the instruction before IP(0x%p)", (VOID *)CallerIpAddress)); - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)Pe32Data); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_ERROR, " in module (%a)\n", PdbPointer)); - } - } } /** diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index bc08f03640..d0ad3be63a 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -51,7 +51,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include + #include #include #include diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 44972bbb76..38724cddd7 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -38,6 +38,64 @@ IsSmmProfileEnabled ( return FeaturePcdGet (PcdCpuSmmProfileEnable); } +#include +#include +#include + +EFI_STATUS +EFIAPI +SmmGetSystemConfigurationTable ( + IN EFI_GUID *TableGuid, + OUT VOID **Table + ); + +CONST EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *mDebugImageInfoTableHeader = NULL; + +// FIXME: +CONST EFI_DEBUG_IMAGE_INFO_NORMAL * +InternalLocateImage ( + IN UINTN CurrentEip + ) +{ + EFI_STATUS Status; + UINT32 Index; + CONST EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; + + if (mDebugImageInfoTableHeader == NULL) { + Status = SmmGetSystemConfigurationTable ( + &gEfiDebugImageInfoTableGuid, + (VOID **) &mDebugImageInfoTableHeader + ); + if (EFI_ERROR (Status)) { + mDebugImageInfoTableHeader = NULL; + return NULL; + } + } + + ASSERT (mDebugImageInfoTableHeader != NULL); + + for (Index = 0; Index < mDebugImageInfoTableHeader->TableSize; ++Index) { + if (mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].ImageInfoType == NULL) { + continue; + } + + if (*mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].ImageInfoType != EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) { + continue; + } + + NormalImage = mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].NormalImage; + + ASSERT (NormalImage->LoadedImageProtocolInstance != NULL); + + if (CurrentEip >= (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase && + CurrentEip < (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase + NormalImage->LoadedImageProtocolInstance->ImageSize) { + return NormalImage; + } + } + + return NULL; +} + /** Perform the remaining tasks. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf index 8c4be7e588..8b8d3b5c80 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf @@ -97,7 +97,6 @@ CpuLib ReportStatusCodeLib SmmCpuFeaturesLib - PeCoffGetEntryPointLib PerformanceLib CpuPageTableLib MmSaveStateLib @@ -121,6 +120,7 @@ gSmmBaseHobGuid ## CONSUMES gMpInformation2HobGuid ## CONSUMES # Assume the HOB must has been created gEfiSmmSmramMemoryGuid + gEfiDebugImageInfoTableGuid ## CONSUMES ## SystemTable [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug ## CONSUMES diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf index d0ae5e709d..bc13e266f9 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuStandaloneMm.inf @@ -79,7 +79,6 @@ CpuLib ReportStatusCodeLib SmmCpuFeaturesLib - PeCoffGetEntryPointLib PerformanceLib CpuPageTableLib MmSaveStateLib diff --git a/UefiCpuPkg/SecCore/FindPeiCore.c b/UefiCpuPkg/SecCore/FindPeiCore.c index 97adb68138..3187dcf60f 100644 --- a/UefiCpuPkg/SecCore/FindPeiCore.c +++ b/UefiCpuPkg/SecCore/FindPeiCore.c @@ -23,7 +23,8 @@ EFIAPI FindImageBase ( IN EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumePtr, IN EFI_FV_FILETYPE FileType, - OUT EFI_PHYSICAL_ADDRESS *CoreImageBase + OUT EFI_PHYSICAL_ADDRESS *CoreImageBase, + OUT UINT32 *CoreImageSize ) { EFI_PHYSICAL_ADDRESS CurrentAddress; @@ -110,8 +111,10 @@ FindImageBase ( if (File->Type == FileType) { if (IS_SECTION2 (Section)) { *CoreImageBase = (PHYSICAL_ADDRESS)(UINTN)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2)); + *CoreImageSize = Size - sizeof (EFI_COMMON_SECTION_HEADER2); } else { *CoreImageBase = (PHYSICAL_ADDRESS)(UINTN)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER)); + *CoreImageSize = Size - sizeof (EFI_COMMON_SECTION_HEADER); } } @@ -147,45 +150,70 @@ FindAndReportEntryPoints ( OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS SecCoreImageBase; - EFI_PHYSICAL_ADDRESS PeiCoreImageBase; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS SecCoreImageBase; + UINT32 SecCoreImageSize; + EFI_PHYSICAL_ADDRESS PeiCoreImageBase; + UINT32 PeiCoreImageSize; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; // // Find SEC Core image base // - Status = FindImageBase (SecCoreFirmwareVolumePtr, EFI_FV_FILETYPE_SECURITY_CORE, &SecCoreImageBase); + Status = FindImageBase ( + SecCoreFirmwareVolumePtr, + EFI_FV_FILETYPE_SECURITY_CORE, + &SecCoreImageBase, + &SecCoreImageSize + ); + ASSERT_EFI_ERROR (Status); + + // FIXME: DEBUG-only + Status = UefiImageInitializeContext ( + &ImageContext, + (VOID*) (UINTN) SecCoreImageBase, + SecCoreImageSize + ); + ASSERT_EFI_ERROR (Status); + + Status = UefiImageLoadImageInplace (&ImageContext); ASSERT_EFI_ERROR (Status); - ZeroMem ((VOID *)&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); // // Report SEC Core debug information when remote debug is enabled // - ImageContext.ImageAddress = SecCoreImageBase; - ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress); - PeCoffLoaderRelocateImageExtraAction (&ImageContext); + UefiImageLoaderRelocateImageExtraAction (&ImageContext); // // Find PEI Core image base // - Status = FindImageBase (PeiCoreFirmwareVolumePtr, EFI_FV_FILETYPE_PEI_CORE, &PeiCoreImageBase); + Status = FindImageBase ( + PeiCoreFirmwareVolumePtr, + EFI_FV_FILETYPE_PEI_CORE, + &PeiCoreImageBase, + &PeiCoreImageSize + ); + ASSERT_EFI_ERROR (Status); + + Status = UefiImageInitializeContext ( + &ImageContext, + (VOID*)(UINTN)PeiCoreImageBase, + PeiCoreImageSize + ); + ASSERT_EFI_ERROR (Status); + + Status = UefiImageLoadImageInplace (&ImageContext); ASSERT_EFI_ERROR (Status); // // Report PEI Core debug information when remote debug is enabled // - ImageContext.ImageAddress = PeiCoreImageBase; - ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress); - PeCoffLoaderRelocateImageExtraAction (&ImageContext); + UefiImageLoaderRelocateImageExtraAction (&ImageContext); // // Find PEI Core entry point // - Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, (VOID **)PeiCoreEntryPoint); - if (EFI_ERROR (Status)) { - *PeiCoreEntryPoint = 0; - } + *PeiCoreEntryPoint = (EFI_PEI_CORE_ENTRY_POINT) (UINTN) (UefiImageLoaderGetImageEntryPoint (&ImageContext)); return; } diff --git a/UefiCpuPkg/SecCore/SecCore.inf b/UefiCpuPkg/SecCore/SecCore.inf index 94966f4edf..7d3a80cf04 100644 --- a/UefiCpuPkg/SecCore/SecCore.inf +++ b/UefiCpuPkg/SecCore/SecCore.inf @@ -48,8 +48,8 @@ PcdLib DebugAgentLib CpuLib - PeCoffGetEntryPointLib - PeCoffExtraActionLib + UefiCpuLib + UefiImageExtraActionLib CpuExceptionHandlerLib ReportStatusCodeLib PeiServicesLib diff --git a/UefiCpuPkg/SecCore/SecMain.h b/UefiCpuPkg/SecCore/SecMain.h index 81c561424e..f26d337843 100644 --- a/UefiCpuPkg/SecCore/SecMain.h +++ b/UefiCpuPkg/SecCore/SecMain.h @@ -25,8 +25,9 @@ #include #include #include -#include -#include +#include + +#include #include #include #include diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 8ac7747eca..42919debdb 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -446,7 +446,7 @@ # TRUE - Access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock.
# FALSE - Access to any type of non-SMRAM memory after SmmReadyToLock is allowed.
# @Prompt Access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock. - gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmRestrictedMemoryAccess|TRUE|BOOLEAN|0x3213210F + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmRestrictedMemoryAccess|FALSE|BOOLEAN|0x3213210F [PcdsFixedAtBuild.RISCV64] ## Indicate the maximum SATP mode allowed. diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index ec2b6cc722..dc6150ce57 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -58,8 +58,9 @@ SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf SmmCpuSyncLib|UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf TdxMeasurementLib|UefiCpuPkg/Library/TdxMeasurementLibNull/TdxMeasurementLibNull.inf diff --git a/UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c b/UefiPayloadPkg/Library/UefiPayloadEntryMemoryAllocationLib/MemoryAllocation.c similarity index 100% rename from UefiPayloadPkg/UefiPayloadEntry/MemoryAllocation.c rename to UefiPayloadPkg/Library/UefiPayloadEntryMemoryAllocationLib/MemoryAllocation.c diff --git a/UefiPayloadPkg/Library/UefiPayloadEntryMemoryAllocationLib/UefiPayloadEntryMemoryAllocationLib.inf b/UefiPayloadPkg/Library/UefiPayloadEntryMemoryAllocationLib/UefiPayloadEntryMemoryAllocationLib.inf new file mode 100644 index 0000000000..03da9b5cff --- /dev/null +++ b/UefiPayloadPkg/Library/UefiPayloadEntryMemoryAllocationLib/UefiPayloadEntryMemoryAllocationLib.inf @@ -0,0 +1,27 @@ +# FIXME: Docs + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UefiPayloadEntryMemoryAllocationLib + FILE_GUID = D3C5B8A1-B946-4D46-8251-9020A527EE40 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiPayloadEntryMemoryAllocationLib|SEC + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + MemoryAllocation.c + +[Packages] + MdePkg/MdePkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + HobLib diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c index 3e13496147..5904d9cb51 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c @@ -48,7 +48,7 @@ AllocateCodePages ( /** Loads and relocates a PE/COFF image - @param[in] PeCoffImage Point to a Pe/Coff image. + @param[in] UefiImage Point to a Pe/Coff image. @param[out] ImageAddress The image memory address after relocation. @param[out] ImageSize The image size. @param[out] EntryPoint The image entry point. @@ -57,59 +57,59 @@ AllocateCodePages ( @return Others If the image failed to load or relocate. **/ EFI_STATUS -LoadPeCoffImage ( - IN VOID *PeCoffImage, +LoadUefiImage ( + IN VOID *UefiImage, + IN UINT32 UefiImageSize, OUT EFI_PHYSICAL_ADDRESS *ImageAddress, - OUT UINT64 *ImageSize, + OUT UINT64 *DestinationSize, OUT EFI_PHYSICAL_ADDRESS *EntryPoint ) { RETURN_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UINT32 ImageSize; + UINT32 ImageAlignment; + UINT32 BufferPages; + UINT32 BufferSize; VOID *Buffer; - ZeroMem (&ImageContext, sizeof (ImageContext)); - - ImageContext.Handle = PeCoffImage; - ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; - - Status = PeCoffLoaderGetImageInfo (&ImageContext); + Status = UefiImageInitializeContext (&ImageContext, UefiImage, UefiImageSize); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } + ImageSize = UefiImageGetImageSize (&ImageContext); + BufferPages = EFI_SIZE_TO_PAGES (ImageSize); + BufferSize = EFI_PAGES_TO_SIZE (BufferPages); + ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext); + // // Allocate Memory for the image // - Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES ((UINT32)ImageContext.ImageSize)); + Buffer = AllocateAlignedCodePages (BufferPages, ImageAlignment); if (Buffer == NULL) { return EFI_OUT_OF_RESOURCES; } - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer; - - // - // Load the image to our new buffer - // - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - // - // Relocate the image in our new buffer + // Load and relocate the image to our new buffer // - Status = PeCoffLoaderRelocateImage (&ImageContext); + Status = UefiImageLoadImageForExecution ( + &ImageContext, + Buffer, + BufferSize, + NULL, + 0 + ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } - *ImageAddress = ImageContext.ImageAddress; - *ImageSize = ImageContext.ImageSize; - *EntryPoint = ImageContext.EntryPoint; + *ImageAddress = (UINTN)Buffer; + *DestinationSize = BufferSize; + *EntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext); return EFI_SUCCESS; } @@ -201,12 +201,13 @@ EFI_STATUS FileFindSection ( IN EFI_FFS_FILE_HEADER *FileHeader, IN EFI_SECTION_TYPE SectionType, - OUT VOID **SectionData + OUT VOID **SectionData, + OUT UINT32 *SectionSize ) { UINT32 FileSize; EFI_COMMON_SECTION_HEADER *Section; - UINT32 SectionSize; + UINT32 CurSectionSize; UINT32 Index; if (IS_FFS_FILE2 (FileHeader)) { @@ -222,26 +223,29 @@ FileFindSection ( Index = 0; while (Index < FileSize) { if (Section->Type == SectionType) { + // FIXME: Use general API (MdePkg?) with proper size checks if (IS_SECTION2 (Section)) { *SectionData = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2)); + *SectionSize = CurSectionSize - sizeof (EFI_COMMON_SECTION_HEADER2); } else { *SectionData = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER)); + *SectionSize = CurSectionSize - sizeof (EFI_COMMON_SECTION_HEADER); } return EFI_SUCCESS; } if (IS_SECTION2 (Section)) { - SectionSize = SECTION2_SIZE (Section); + CurSectionSize = SECTION2_SIZE (Section); } else { - SectionSize = SECTION_SIZE (Section); + CurSectionSize = SECTION_SIZE (Section); } - SectionSize = GET_OCCUPIED_SIZE (SectionSize, 4); - ASSERT (SectionSize != 0); - Index += SectionSize; + CurSectionSize = GET_OCCUPIED_SIZE (CurSectionSize, 4); + ASSERT (CurSectionSize != 0); + Index += CurSectionSize; - Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionSize); + Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + CurSectionSize); } return EFI_NOT_FOUND; @@ -263,10 +267,12 @@ LoadDxeCore ( EFI_STATUS Status; EFI_FIRMWARE_VOLUME_HEADER *PayloadFv; EFI_FIRMWARE_VOLUME_HEADER *DxeCoreFv; + UINT32 DxeCoreFvSize; EFI_FFS_FILE_HEADER *FileHeader; - VOID *PeCoffImage; + VOID *UefiImage; + UINT32 UefiImageSize; EFI_PHYSICAL_ADDRESS ImageAddress; - UINT64 ImageSize; + UINT64 DestinationSize; PayloadFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdPayloadFdMemBase); @@ -278,7 +284,7 @@ LoadDxeCore ( return Status; } - Status = FileFindSection (FileHeader, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, (VOID **)&DxeCoreFv); + Status = FileFindSection (FileHeader, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, (VOID **)&DxeCoreFv, &DxeCoreFvSize); if (EFI_ERROR (Status)) { return Status; } @@ -296,7 +302,7 @@ LoadDxeCore ( return Status; } - Status = FileFindSection (FileHeader, EFI_SECTION_PE32, (VOID **)&PeCoffImage); + Status = FileFindSection (FileHeader, EFI_SECTION_PE32, (VOID **)&UefiImage, &UefiImageSize); if (EFI_ERROR (Status)) { return Status; } @@ -304,12 +310,12 @@ LoadDxeCore ( // // Get DXE core info // - Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, DxeCoreEntryPoint); + Status = LoadUefiImage (UefiImage, UefiImageSize, &ImageAddress, &DestinationSize, DxeCoreEntryPoint); if (EFI_ERROR (Status)) { return Status; } - BuildModuleHob (&FileHeader->Name, ImageAddress, EFI_SIZE_TO_PAGES ((UINT32)ImageSize) * EFI_PAGE_SIZE, *DxeCoreEntryPoint); + BuildModuleHob (&FileHeader->Name, ImageAddress, DestinationSize, *DxeCoreEntryPoint); return EFI_SUCCESS; } @@ -331,7 +337,8 @@ UniversalLoadDxeCore ( { EFI_STATUS Status; EFI_FFS_FILE_HEADER *FileHeader; - VOID *PeCoffImage; + VOID *UefiImage; + UINT32 UefiImageSize; EFI_PHYSICAL_ADDRESS ImageAddress; UINT64 ImageSize; @@ -343,7 +350,7 @@ UniversalLoadDxeCore ( return Status; } - Status = FileFindSection (FileHeader, EFI_SECTION_PE32, (VOID **)&PeCoffImage); + Status = FileFindSection (FileHeader, EFI_SECTION_PE32, (VOID **)&UefiImage, &UefiImageSize); if (EFI_ERROR (Status)) { return Status; } @@ -351,7 +358,7 @@ UniversalLoadDxeCore ( // // Get DXE core info // - Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, DxeCoreEntryPoint); + Status = LoadUefiImage (UefiImage, UefiImageSize, &ImageAddress, &ImageSize, DxeCoreEntryPoint); if (EFI_ERROR (Status)) { return Status; } diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h index 09fce8dbcf..91095769ee 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h @@ -15,12 +15,12 @@ #include #include #include -#include +#include #include #include #include #include -#include +#include #include #include #include @@ -196,7 +196,8 @@ EFI_STATUS FileFindSection ( IN EFI_FFS_FILE_HEADER *FileHeader, IN EFI_SECTION_TYPE SectionType, - OUT VOID **SectionData + OUT VOID **SectionData, + OUT UINT32 *SectionSize ); /** diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf index da5a58ab22..f012299f41 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf @@ -24,7 +24,6 @@ [Sources] UefiPayloadEntry.c LoadDxeCore.c - MemoryAllocation.c AcpiTable.c [Sources.Ia32] @@ -52,10 +51,11 @@ IoLib BlParseLib HobLib - PeCoffLib + UefiImageLib PlatformSupportLib CpuLib StackCheckLib + MemoryAllocationLib [Guids] gEfiMemoryTypeInformationGuid diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c index 5b864eeefe..b6329834c1 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c @@ -54,6 +54,7 @@ FixUpPcdDatabase ( EFI_STATUS Status; EFI_FFS_FILE_HEADER *FileHeader; VOID *PcdRawData; + UINT32 PcdRawSize; PEI_PCD_DATABASE *PeiDatabase; PEI_PCD_DATABASE *UplDatabase; EFI_HOB_GUID_TYPE *GuidHob; @@ -77,7 +78,7 @@ FixUpPcdDatabase ( return Status; } - Status = FileFindSection (FileHeader, EFI_SECTION_RAW, &PcdRawData); + Status = FileFindSection (FileHeader, EFI_SECTION_RAW, &PcdRawData, &PcdRawSize); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { return Status; diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf index 8804ef6b9c..a13afd8ef3 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf @@ -44,10 +44,10 @@ SerialPortLib IoLib HobLib - PeCoffLib CpuLib HobPrintLib StackCheckLib + UefiImageLib [Guids] gEfiMemoryTypeInformationGuid diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 9ff326a6cb..f0c713c8dd 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -216,8 +216,8 @@ !endif PciSegmentLib|MdePkg/Library/PciSegmentLibSegmentInfo/BasePciSegmentLibSegmentInfo.inf PciSegmentInfoLib|UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.inf - PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf - PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf DxeHobListLib|UefiPayloadPkg/Library/DxeHobListLib/DxeHobListLib.inf @@ -288,10 +288,10 @@ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE - PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf + UefiImageExtraActionLib|SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf !else - PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf !endif PlatformSupportLib|UefiPayloadPkg/Library/PlatformSupportLibNull/PlatformSupportLibNull.inf @@ -371,6 +371,7 @@ !if $(MULTIPLE_DEBUG_PORT_SUPPORT) == TRUE SerialPortLib|UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf !endif + MemoryAllocationLib|UefiPayloadPkg/Library/UefiPayloadEntryMemoryAllocationLib/UefiPayloadEntryMemoryAllocationLib.inf [LibraryClasses.common.DXE_CORE] DxeHobListLib|UefiPayloadPkg/Library/DxeHobListLibNull/DxeHobListLibNull.inf From 5d894921a36cc1eb57fbf466fc9a5d2f23982040 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 26 Jun 2023 13:23:02 +0300 Subject: [PATCH 022/341] BaseTools: Replaced GenFw with ImageTool and MicroTool. --- .gitmodules | 3 + .pytool/Plugin/SpellCheck/cspell.base.yaml | 1 - ArmVirtPkg/ArmVirt.dsc.inc | 7 +- BaseTools/.gitignore | 6 +- BaseTools/BinWrappers/PosixLike/ImageTool | 25 + BaseTools/BinWrappers/PosixLike/MicroTool | 25 + .../BinWrappers/WindowsLike/ImageTool.bat | 6 + .../BinWrappers/WindowsLike/MicroTool.bat | 6 + BaseTools/Conf/build_rule.template | 129 +- BaseTools/Conf/tools_def.template | 500 ++++--- BaseTools/GNUmakefile | 2 +- BaseTools/ImageTool/BinEmit.c | 200 +++ BaseTools/ImageTool/ElfScan.c | 731 +++++++++++ BaseTools/ImageTool/ElfScan32.c | 7 + BaseTools/ImageTool/ElfScan64.c | 7 + BaseTools/ImageTool/ElfScanCommon.c | 24 + BaseTools/ImageTool/ElfScanCommon.h | 29 + BaseTools/ImageTool/GNUmakefile | 25 + BaseTools/ImageTool/Image.c | 649 +++++++++ BaseTools/ImageTool/ImageTool.c | 530 ++++++++ BaseTools/ImageTool/ImageTool.h | 185 +++ BaseTools/ImageTool/ImageToolEmit.c | 184 +++ BaseTools/ImageTool/ImageToolEmit.h | 29 + BaseTools/ImageTool/Makefile | 108 ++ BaseTools/ImageTool/PeEmit.c | 1036 +++++++++++++++ BaseTools/ImageTool/PeEmit32.c | 7 + BaseTools/ImageTool/PeEmit64.c | 7 + BaseTools/ImageTool/PeEmitCommon.c | 39 + BaseTools/ImageTool/PeEmitCommon.h | 25 + BaseTools/ImageTool/PeScan.c | 295 +++++ BaseTools/ImageTool/PeScan.h | 23 + BaseTools/ImageTool/UefiImageScan.c | 279 ++++ BaseTools/Makefile | 7 +- BaseTools/MicroTool/GNUmakefile | 15 + BaseTools/MicroTool/Makefile | 84 ++ BaseTools/MicroTool/MicroTool.c | 298 +++++ BaseTools/Scripts/Base.lds | 67 + BaseTools/Scripts/Merge.lds | 64 + BaseTools/Source/C/GNUmakefile | 1 - BaseTools/Source/C/GenFv/GenFvInternalLib.c | 10 +- BaseTools/Source/C/GenFw/Elf32Convert.h | 19 - BaseTools/Source/C/GenFw/Elf64Convert.h | 19 - BaseTools/Source/C/GenFw/ElfConvert.h | 122 -- BaseTools/Source/C/GenFw/GenFw.h | 50 - BaseTools/Source/C/GenFw/Makefile | 18 - BaseTools/Source/C/GenFw/elf32.h | 252 ---- BaseTools/Source/C/GenFw/elf64.h | 254 ---- BaseTools/Source/C/GenFw/elf_common.h | 1159 ----------------- BaseTools/Source/C/Makefile | 1 - BaseTools/Source/C/Makefiles/ms.app | 5 +- .../Python/Common/ToolDefClassObject.py | 21 + BaseTools/Source/Python/GenFds/DataSection.py | 2 +- BaseTools/Source/Python/GenFds/EfiSection.py | 2 +- .../Source/Python/GenFds/FfsInfStatement.py | 4 +- .../Python/GenFds/GenFdsGlobalVariable.py | 31 +- BaseTools/Source/Python/build/BuildReport.py | 6 +- BaseTools/Source/Python/build/build.py | 10 +- .../UserManuals/GenFds_Utility_Man_Page.rtf | 2 +- .../UserManuals/GenFw_Utility_Man_Page.rtf | 179 --- BaseTools/toolsetup.bat | 1 - MdePkg/Include/Library/UefiImageLib.h | 5 + .../BaseCpuLib/Ia32/InitializeFpu.nasm | 3 +- .../Library/BaseCpuLib/X64/InitializeFpu.nasm | 3 +- OpenCorePkg | 1 + OvmfPkg/OvmfPkgIa32.dsc | 23 +- OvmfPkg/OvmfPkgIa32X64.dsc | 14 +- OvmfPkg/OvmfPkgIa32X64.fdf | 4 +- OvmfPkg/OvmfPkgX64.dsc | 23 +- OvmfPkg/OvmfPkgX64.fdf | 4 +- UefiCpuPkg/SecCore/SecCoreNative.inf | 4 +- .../MemoryAllocationLib.c} | 51 +- .../UefiPayloadMemoryAllocationLib.inf | 39 + .../UefiPayloadMemoryAllocationLib.uni | 16 + .../PayloadLoaderPeim/ElfLib/ElfCommon.h | 15 +- .../UniversalPayloadEntry.inf | 2 +- UefiPayloadPkg/UefiPayloadPkg.dsc | 9 +- UefiPayloadPkg/UefiPayloadPkg.fdf | 4 +- 77 files changed, 5533 insertions(+), 2519 deletions(-) create mode 100755 BaseTools/BinWrappers/PosixLike/ImageTool create mode 100644 BaseTools/BinWrappers/PosixLike/MicroTool create mode 100644 BaseTools/BinWrappers/WindowsLike/ImageTool.bat create mode 100644 BaseTools/BinWrappers/WindowsLike/MicroTool.bat create mode 100644 BaseTools/ImageTool/BinEmit.c create mode 100644 BaseTools/ImageTool/ElfScan.c create mode 100644 BaseTools/ImageTool/ElfScan32.c create mode 100644 BaseTools/ImageTool/ElfScan64.c create mode 100644 BaseTools/ImageTool/ElfScanCommon.c create mode 100644 BaseTools/ImageTool/ElfScanCommon.h create mode 100644 BaseTools/ImageTool/GNUmakefile create mode 100644 BaseTools/ImageTool/Image.c create mode 100644 BaseTools/ImageTool/ImageTool.c create mode 100644 BaseTools/ImageTool/ImageTool.h create mode 100644 BaseTools/ImageTool/ImageToolEmit.c create mode 100644 BaseTools/ImageTool/ImageToolEmit.h create mode 100644 BaseTools/ImageTool/Makefile create mode 100644 BaseTools/ImageTool/PeEmit.c create mode 100644 BaseTools/ImageTool/PeEmit32.c create mode 100644 BaseTools/ImageTool/PeEmit64.c create mode 100644 BaseTools/ImageTool/PeEmitCommon.c create mode 100644 BaseTools/ImageTool/PeEmitCommon.h create mode 100644 BaseTools/ImageTool/PeScan.c create mode 100644 BaseTools/ImageTool/PeScan.h create mode 100644 BaseTools/ImageTool/UefiImageScan.c create mode 100644 BaseTools/MicroTool/GNUmakefile create mode 100644 BaseTools/MicroTool/Makefile create mode 100644 BaseTools/MicroTool/MicroTool.c create mode 100644 BaseTools/Scripts/Base.lds create mode 100644 BaseTools/Scripts/Merge.lds delete mode 100644 BaseTools/Source/C/GenFw/Elf32Convert.h delete mode 100644 BaseTools/Source/C/GenFw/Elf64Convert.h delete mode 100644 BaseTools/Source/C/GenFw/ElfConvert.h delete mode 100644 BaseTools/Source/C/GenFw/GenFw.h delete mode 100644 BaseTools/Source/C/GenFw/Makefile delete mode 100644 BaseTools/Source/C/GenFw/elf32.h delete mode 100644 BaseTools/Source/C/GenFw/elf64.h delete mode 100644 BaseTools/Source/C/GenFw/elf_common.h delete mode 100644 BaseTools/UserManuals/GenFw_Utility_Man_Page.rtf create mode 160000 OpenCorePkg rename UefiPayloadPkg/Library/{UefiPayloadEntryMemoryAllocationLib/MemoryAllocation.c => UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c} (81%) mode change 100644 => 100755 create mode 100755 UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.inf create mode 100755 UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.uni diff --git a/.gitmodules b/.gitmodules index 60cb590af8..326d6bbb62 100644 --- a/.gitmodules +++ b/.gitmodules @@ -35,3 +35,6 @@ [submodule "SecurityPkg/DeviceSecurity/SpdmLib/libspdm"] path = SecurityPkg/DeviceSecurity/SpdmLib/libspdm url = https://github.com/DMTF/libspdm.git +[submodule "OpenCorePkg"] + path = OpenCorePkg + url = https://github.com/acidanthera/OpenCorePkg.git diff --git a/.pytool/Plugin/SpellCheck/cspell.base.yaml b/.pytool/Plugin/SpellCheck/cspell.base.yaml index d701c0650e..bd24c823ae 100644 --- a/.pytool/Plugin/SpellCheck/cspell.base.yaml +++ b/.pytool/Plugin/SpellCheck/cspell.base.yaml @@ -108,7 +108,6 @@ "fwvol", "FXRSTOR", "FXSAVE", - "genfw", "Goldmont", "grayoutif", "guidid", diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index bac77af65d..c8250dc264 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -40,12 +40,9 @@ DEFINE CUSTOM_STACK_CHECK_LIB = DYNAMIC !endif -[BuildOptions.common.EDKII.DXE_CORE,BuildOptions.common.EDKII.DXE_DRIVER,BuildOptions.common.EDKII.UEFI_DRIVER,BuildOptions.common.EDKII.UEFI_APPLICATION] - GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 - [BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] - GCC:*_*_ARM_DLINK_FLAGS = -z common-page-size=0x1000 - GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x10000 + GCC:*_*_ARM_DLINK_FLAGS = -z max-page-size=0x1000 + GCC:*_*_AARCH64_DLINK_FLAGS = -z max-page-size=0x10000 [LibraryClasses.common] !if $(TARGET) == RELEASE diff --git a/BaseTools/.gitignore b/BaseTools/.gitignore index 0186128250..08a53639bd 100644 --- a/BaseTools/.gitignore +++ b/BaseTools/.gitignore @@ -19,4 +19,8 @@ Source/C/libs/ Bin/Win32 Bin/Win64 Lib -BaseToolsBuild/ \ No newline at end of file +BaseToolsBuild/ +ImageTool/ImageTool +ImageTool/ImageTool32 +ImageTool/ImageTool64 +MicroTool/MicroTool diff --git a/BaseTools/BinWrappers/PosixLike/ImageTool b/BaseTools/BinWrappers/PosixLike/ImageTool new file mode 100755 index 0000000000..7c6a21ce99 --- /dev/null +++ b/BaseTools/BinWrappers/PosixLike/ImageTool @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2022, Mikhail Krichanov. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause +# +full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here +dir=$(dirname "$full_cmd") +cmd=${full_cmd##*/} + +if [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/ImageTool" ] +then + if [ ! -e "$EDK_TOOLS_PATH/ImageTool/ImageTool" ] + then + echo "BaseTools C Tool binary was not found (ImageTool)" + echo "You may need to run:" + echo " make -C $EDK_TOOLS_PATH/ImageTool" + else + exec "$EDK_TOOLS_PATH/ImageTool/ImageTool" "$@" + fi +else + echo "Unable to find the real '$cmd' to run" + echo "This message was printed by" + echo " $0" + exit 127 +fi diff --git a/BaseTools/BinWrappers/PosixLike/MicroTool b/BaseTools/BinWrappers/PosixLike/MicroTool new file mode 100644 index 0000000000..0e22e2775d --- /dev/null +++ b/BaseTools/BinWrappers/PosixLike/MicroTool @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2022, Mikhail Krichanov. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause +# +full_cmd=${BASH_SOURCE:-$0} # see http://mywiki.wooledge.org/BashFAQ/028 for a discussion of why $0 is not a good choice here +dir=$(dirname "$full_cmd") +cmd=${full_cmd##*/} + +if [ -n "$WORKSPACE" ] && [ -e "$EDK_TOOLS_PATH/MicroTool" ] +then + if [ ! -e "$EDK_TOOLS_PATH/MicroTool/MicroTool" ] + then + echo "BaseTools C Tool binary was not found (MicroTool)" + echo "You may need to run:" + echo " make -C $EDK_TOOLS_PATH/MicroTool" + else + exec "$EDK_TOOLS_PATH/MicroTool/MicroTool" "$@" + fi +else + echo "Unable to find the real '$cmd' to run" + echo "This message was printed by" + echo " $0" + exit 127 +fi diff --git a/BaseTools/BinWrappers/WindowsLike/ImageTool.bat b/BaseTools/BinWrappers/WindowsLike/ImageTool.bat new file mode 100644 index 0000000000..7e9d81741b --- /dev/null +++ b/BaseTools/BinWrappers/WindowsLike/ImageTool.bat @@ -0,0 +1,6 @@ +:: +:: Copyright (c) 2022, Mikhail Krichanov. All rights reserved. +:: SPDX-License-Identifier: BSD-3-Clause +:: +@echo off +call ImageTool.exe %* diff --git a/BaseTools/BinWrappers/WindowsLike/MicroTool.bat b/BaseTools/BinWrappers/WindowsLike/MicroTool.bat new file mode 100644 index 0000000000..ad8515c577 --- /dev/null +++ b/BaseTools/BinWrappers/WindowsLike/MicroTool.bat @@ -0,0 +1,6 @@ +:: +:: Copyright (c) 2022, Mikhail Krichanov. All rights reserved. +:: SPDX-License-Identifier: BSD-3-Clause +:: +@echo off +call MicroTool.exe %* diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template index 116cd29da7..f9b4b83d32 100755 --- a/BaseTools/Conf/build_rule.template +++ b/BaseTools/Conf/build_rule.template @@ -272,7 +272,14 @@ $(RM) ${dst} "$(SLINK)" cr ${dst} $(SLINK_FLAGS) @$(OBJECT_FILES_LIST) - + + + "$(SLINK)" $(SLINK_FLAGS) ${dst} --via $(OBJECT_FILES_LIST) + + + # $(OBJECT_FILES_LIST) has wrong paths for cygwin + "$(SLINK)" $(SLINK_FLAGS) ${dst} $(OBJECT_FILES) + "$(SLINK)" $(SLINK_FLAGS) ${dst} -filelist $(OBJECT_FILES_LIST) @@ -296,12 +303,11 @@ "$(DLINK)" -o ${dst} $(DLINK_FLAGS) -Wl,--start-group,@$(STATIC_LIBRARY_FILES_LIST),--end-group $(CC_FLAGS) $(DLINK2_FLAGS) - "$(OBJCOPY)" $(OBJCOPY_FLAGS) ${dst} "$(DLINK)" $(DLINK_FLAGS) -o ${dst} $(DLINK_SPATH) -filelist $(STATIC_LIBRARY_FILES_LIST) $(DLINK2_FLAGS) - - + + [Static-Library-File.SEC, Static-Library-File.PEI_CORE, Static-Library-File.PEIM] *.lib @@ -319,8 +325,6 @@ "$(DLINK)" -o ${dst} $(DLINK_FLAGS) $(DLINK_XIPFLAGS) -Wl,--start-group,@$(STATIC_LIBRARY_FILES_LIST),--end-group $(CC_FLAGS) $(CC_XIPFLAGS) $(DLINK2_FLAGS) - "$(OBJCOPY)" $(OBJCOPY_FLAGS) ${dst} - [Static-Library-File.USER_DEFINED] @@ -364,8 +368,8 @@ "$(DLINK)" -o ${dst} $(DLINK_FLAGS) $(DLINK_SPATH) -filelist $(STATIC_LIBRARY_FILES_LIST) $(DLINK2_FLAGS) - - + + [Dynamic-Library-File] ?.dll @@ -375,32 +379,67 @@ $(OUTPUT_DIR)(+)$(MODULE_NAME).map - "$(GENFW)" -e $(MODULE_TYPE) -o ${dst} ${src} $(GENFW_FLAGS) + ImageTool GenImage -c PE -t $(MODULE_TYPE) -o ${dst} ${src} $(CP) ${dst} $(DEBUG_DIR) $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) - -$(CP) $(DEBUG_DIR)(+)*.pdb $(OUTPUT_DIR) - - $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).debug - "$(OBJCOPY)" $(OBJCOPY_STRIPFLAG) ${src} + -$(CP) $(DEBUG_DIR)(+)*.pdb $(OUTPUT_DIR) + + + $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).strip + $(OBJCOPY) $(OBJCOPY_STRIPFLAG) $(DEBUG_DIR)(+)$(MODULE_NAME).strip + + ImageTool GenImage -c PE -t $(MODULE_TYPE) -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).strip + + $(CP) ${dst} $(DEBUG_DIR) + $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi + -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) + + + # tool to convert Mach-O to PE/COFF + "$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff + # create symbol file for GDB debug + -$(DSYMUTIL) ${src} + ImageTool GenImage -c PE -t $(MODULE_TYPE) -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff + $(CP) ${dst} $(DEBUG_DIR) + $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi + -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) + +[Dynamic-Library-File.UEFI_HII] + + ?.dll - # - #The below 2 lines are only needed for UNIXGCC tool chain, which generates PE image directly - # - -"$(OBJCOPY)" $(OBJCOPY_ADDDEBUGFLAG) ${src} - -$(CP) $(DEBUG_DIR)(+)$(MODULE_NAME).debug $(BIN_DIR)(+)$(MODULE_NAME_GUID).debug + + $(OUTPUT_DIR)(+)$(MODULE_NAME).efi + $(DEBUG_DIR)(+)$(MODULE_NAME).efi + $(OUTPUT_DIR)(+)$(MODULE_NAME).map + + + $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc + + + ImageTool GenImage -c PE -t $(MODULE_TYPE) -h $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc -o ${dst} ${src} + $(CP) ${dst} $(DEBUG_DIR) + $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi + -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) + -$(CP) $(DEBUG_DIR)(+)*.pdb $(OUTPUT_DIR) + + + $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).strip + $(OBJCOPY) $(OBJCOPY_STRIPFLAG) $(DEBUG_DIR)(+)$(MODULE_NAME).strip + + ImageTool GenImage -c PE -t $(MODULE_TYPE) -h $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).strip - "$(GENFW)" -e $(MODULE_TYPE) -o ${dst} ${src} $(GENFW_FLAGS) $(CP) ${dst} $(DEBUG_DIR) $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) - + # tool to convert Mach-O to PE/COFF "$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff # create symbol file for GDB debug -$(DSYMUTIL) ${src} - "$(GENFW)" -e $(MODULE_TYPE) -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff $(GENFW_FLAGS) + ImageTool GenImage -c PE -t $(MODULE_TYPE) -h $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff $(CP) ${dst} $(DEBUG_DIR) $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) @@ -434,14 +473,14 @@ Trim --asl-file --asl-deps -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i -i $(INC_LIST) ${src} "$(ASLPP)" $(DEPS_FLAGS) $(ASLPP_FLAGS) $(INC) /I${s_path} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i > $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii - Trim --source-code -l -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii + Trim --source-code -l -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii "$(ASL)" $(ASL_FLAGS) $(ASL_OUTFLAGS)${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii $(CP) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.aml $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.amli Trim --asl-file --asl-deps -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i -i $(INC_LIST) ${src} "$(ASLPP)" $(DEPS_FLAGS) $(ASLPP_FLAGS) $(INC) -I${s_path} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i > $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii - Trim --source-code -l -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii + Trim --source-code -l -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii "$(ASL)" $(ASL_FLAGS) $(ASL_OUTFLAGS)${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iiii $(CP) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.aml $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.amli @@ -468,12 +507,12 @@ "$(ASLCC)" $(DEPS_FLAGS) /Fo$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASLCC_FLAGS) $(DEPS_FLAGS) $(INC) ${src} "$(ASLDLINK)" /OUT:$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj - "$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS) + ImageTool GetAcpi -o ${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll "$(ASLCC)" $(DEPS_FLAGS) -c -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) $(ASLCC_FLAGS) $(DEPS_FLAGS) $(INC) ${src} "$(ASLDLINK)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj - "$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS) + ImageTool GetAcpi -o ${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll [Acpi-Table-Code-File] @@ -488,25 +527,24 @@ "$(ASLCC)" $(DEPS_FLAGS) /Fo$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASLCC_FLAGS) $(DEPS_FLAGS) $(INC) ${src} "$(ASLDLINK)" /OUT:$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj - "$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS) + ImageTool GetAcpi -o ${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll "$(ASLCC)" $(DEPS_FLAGS) -c -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) $(ASLCC_FLAGS) $(DEPS_FLAGS) $(INC) ${src} - "$(ASLDLINK)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj - "$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS) + "$(ASLDLINK)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) $(ASLCC_FLAGS) + ImageTool GetAcpi -o ${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll "$(ASLCC)" $(DEPS_FLAGS) -c -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(CC_FLAGS) $(ASLCC_FLAGS) $(DEPS_FLAGS) $(INC) ${src} "$(ASLDLINK)" /OUT:$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj - "$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(GENFW_FLAGS) + ImageTool GetAcpi -o ${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll - + "$(ASLCC)" $(DEPS_FLAGS) -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASLCC_FLAGS) $(DEPS_FLAGS) $(INC) ${src} "$(ASLDLINK)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(ASLDLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj "$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.pecoff - "$(GENFW)" -o ${dst} -c $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.pecoff $(GENFW_FLAGS) - - + ImageTool GetAcpi -o ${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.pecoff + [Masm16-Code-File] ?.asm16, ?.Asm16, ?.ASM16, ?.s16, ?.S16 @@ -531,7 +569,7 @@ Trim --source-code -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.ii "$(ASM)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASM_FLAGS) $(INC) ${d_path}(+)${s_base}.iii "$(DLINK)" -o ${dst} $(DLINK_FLAGS) --start-group $(DLINK_SPATH) $(LIBS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj --end-group - + Trim --asm-file -o ${d_path}(+)${s_base}.i -i $(INC_LIST) ${src} "$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii @@ -539,7 +577,7 @@ "$(ASM)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASM_FLAGS) $(INC) ${d_path}(+)${s_base}.iii "$(SLINK)" $(SLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.slib $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj otool -t $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.slib | hex2bin.py ${dst} - + [Nasm-to-Binary-Code-File] @@ -567,7 +605,7 @@ $(OUTPUT_DIR)(+)${s_base}.mcb - "$(GENFW)" -o ${dst} -m ${src} $(GENFW_FLAGS) + MicroTool TxtToBin ${src} ${dst} [Microcode-Binary-File] @@ -580,7 +618,7 @@ $(OUTPUT_DIR)(+)$(MODULE_NAME).bin - "$(GENFW)" -o ${dst} -j $(MICROCODE_BINARY_FILES) $(GENFW_FLAGS) + MicroTool Merge ${dst} $(MICROCODE_BINARY_FILES) -$(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).bin [EFI-Image-File] @@ -663,19 +701,8 @@ *.hpk - - $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.lib - - + $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc - - "$(GENFW)" -o $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc -g $(MODULE_GUID) --hiipackage $(HII_BINARY_PACKAGES) $(GENFW_FLAGS) - "$(RC)" /Fo${dst} $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc - - - "$(GENFW)" -o $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc -g $(MODULE_GUID) --hiibinpackage $(HII_BINARY_PACKAGES) $(GENFW_FLAGS) - "$(RC)" $(RC_FLAGS) $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc ${dst} - - - "$(GENFW)" -o $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc -g $(MODULE_GUID) --hiibinpackage $(HII_BINARY_PACKAGES) $(GENFW_FLAGS) + + ImageTool HiiBin $(MODULE_GUID) -o $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc $(HII_BINARY_PACKAGES) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index 95bb797863..45f7a18e1b 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -27,6 +27,28 @@ IDENTIFIER = Default TOOL_CHAIN_CONF +!ifdef $(EDK2_MERGE_RODATA_INTO_TEXT) +DEFINE DLINK_SCRIPT = -Wl,--script=$(EDK_TOOLS_PATH)/Scripts/Merge.lds +DEFINE MSFT_MERGE = /MERGE:.rdata=.text +DEFINE XCODE_MERGE = -rename_section __DATA_CONST __text_const __TEXT __const -rename_section __DATA_CONST __cstring __TEXT __cstring -rename_section __DATA_CONST __ustring __TEXT __ustring -rename_section __DATA_CONST __const __TEXT __data_const +!else +DEFINE DLINK_SCRIPT = -Wl,--script=$(EDK_TOOLS_PATH)/Scripts/Base.lds +DEFINE MSFT_MERGE = +DEFINE XCODE_MERGE = +!endif + +!ifdef $(EDK2_REDUCE_FW_SIZE) +DEFINE GCC_ALIGN = -z max-page-size=0x20 +DEFINE MSFT_ALIGN = /ALIGN:32 /FILEALIGN:32 +DEFINE XCODE_ALIGN = 0x20 +DEFINE XCODE_ADDR = 0x400 +!else +DEFINE GCC_ALIGN = -z max-page-size=0x1000 +DEFINE MSFT_ALIGN = /ALIGN:4096 /FILEALIGN:4096 +DEFINE XCODE_ALIGN = 0x1000 +DEFINE XCODE_ADDR = 0x1000 +!endif + # common path macros DEFINE VS2015_BIN = ENV(VS2015_PREFIX)Vc\bin DEFINE VS2015_DLL = ENV(VS2015_PREFIX)Common7\IDE;DEF(VS2015_BIN) @@ -116,6 +138,7 @@ DEFINE MSFT_DEPS_FLAGS = /showIncludes DEFINE MSFT_ASLPP_FLAGS = /nologo /E /C /FIAutoGen.h DEFINE MSFT_ASLCC_FLAGS = /nologo /c /FIAutoGen.h /TC /Dmain=ReferenceAcpiTable DEFINE MSFT_ASLDLINK_FLAGS = /NODEFAULTLIB /ENTRY:ReferenceAcpiTable /SUBSYSTEM:CONSOLE +DEFINE MSFT_DLINK_COMMON = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER DEF(MSFT_ALIGN) DEF(MSFT_MERGE) DEFINE DTCPP_BIN = ENV(DTCPP_PREFIX)cpp DEFINE DTC_BIN = ENV(DTC_PREFIX)dtc @@ -282,7 +305,7 @@ DEFINE DTC_BIN = ENV(DTC_PREFIX)dtc *_VS2015_*_PP_FLAGS = /nologo /E /TC /FIAutoGen.h *_VS2015_*_VFRPP_FLAGS = /nologo /E /TC /DVFRCOMPILE /FI$(MODULE_NAME)StrDefs.h *_VS2015_*_DLINK2_FLAGS = -*_VS2015_*_DEPS_FLAGS = DEF(MSFT_DEPS_FLAGS) +*_VS2015_*_DEPS_FLAGS = DEF(MSFT_DEPS_FLAGS) *_VS2015_*_ASM16_PATH = DEF(VS2015_BIN)\ml.exe ################## @@ -319,13 +342,13 @@ NOOPT_VS2015_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 RELEASE_VS2015_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd NOOPT_VS2015_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd /Zi - DEBUG_VS2015_IA32_NASM_FLAGS = -Ox -f win32 -g -RELEASE_VS2015_IA32_NASM_FLAGS = -Ox -f win32 -NOOPT_VS2015_IA32_NASM_FLAGS = -O0 -f win32 -g + DEBUG_VS2015_IA32_NASM_FLAGS = -Ox -f win32 -g -DRODATA_SECTION_NAME=.rdata +RELEASE_VS2015_IA32_NASM_FLAGS = -Ox -f win32 -DRODATA_SECTION_NAME=.rdata +NOOPT_VS2015_IA32_NASM_FLAGS = -O0 -f win32 -g -DRODATA_SECTION_NAME=.rdata - DEBUG_VS2015_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG -RELEASE_VS2015_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data -NOOPT_VS2015_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + DEBUG_VS2015_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X86 /DEBUG +RELEASE_VS2015_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /MACHINE:X86 +NOOPT_VS2015_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X86 /DEBUG ################## # X64 definitions @@ -349,15 +372,15 @@ NOOPT_VS2015_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /G DEBUG_VS2015_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi RELEASE_VS2015_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd -NOOPT_VS2015_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi +NOOPT_VS2015_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi - DEBUG_VS2015_X64_NASM_FLAGS = -Ox -f win64 -g -RELEASE_VS2015_X64_NASM_FLAGS = -Ox -f win64 -NOOPT_VS2015_X64_NASM_FLAGS = -O0 -f win64 -g + DEBUG_VS2015_X64_NASM_FLAGS = -Ox -f win64 -g -DRODATA_SECTION_NAME=.rdata +RELEASE_VS2015_X64_NASM_FLAGS = -Ox -f win64 -DRODATA_SECTION_NAME=.rdata +NOOPT_VS2015_X64_NASM_FLAGS = -O0 -f win64 -g -DRODATA_SECTION_NAME=.rdata - DEBUG_VS2015_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG -RELEASE_VS2015_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data -NOOPT_VS2015_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + DEBUG_VS2015_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X64 /DEBUG +RELEASE_VS2015_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /MACHINE:X64 +NOOPT_VS2015_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X64 /DEBUG #################################################################################### # VS2015x86 - Microsoft Visual Studio 2015 (x86) professional with Intel ASL @@ -412,13 +435,13 @@ NOOPT_VS2015x86_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 RELEASE_VS2015x86_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd NOOPT_VS2015x86_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd /Zi - DEBUG_VS2015x86_IA32_NASM_FLAGS = -Ox -f win32 -g -RELEASE_VS2015x86_IA32_NASM_FLAGS = -Ox -f win32 -NOOPT_VS2015x86_IA32_NASM_FLAGS = -O0 -f win32 -g + DEBUG_VS2015x86_IA32_NASM_FLAGS = -Ox -f win32 -g -DRODATA_SECTION_NAME=.rdata +RELEASE_VS2015x86_IA32_NASM_FLAGS = -Ox -f win32 -DRODATA_SECTION_NAME=.rdata +NOOPT_VS2015x86_IA32_NASM_FLAGS = -O0 -f win32 -g -DRODATA_SECTION_NAME=.rdata - DEBUG_VS2015x86_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG -RELEASE_VS2015x86_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data -NOOPT_VS2015x86_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + DEBUG_VS2015x86_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X86 /DEBUG +RELEASE_VS2015x86_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /MACHINE:X86 +NOOPT_VS2015x86_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X86 /DEBUG ################## # X64 definitions @@ -444,13 +467,13 @@ NOOPT_VS2015x86_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE RELEASE_VS2015x86_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd NOOPT_VS2015x86_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi - DEBUG_VS2015x86_X64_NASM_FLAGS = -Ox -f win64 -g -RELEASE_VS2015x86_X64_NASM_FLAGS = -Ox -f win64 -NOOPT_VS2015x86_X64_NASM_FLAGS = -O0 -f win64 -g + DEBUG_VS2015x86_X64_NASM_FLAGS = -Ox -f win64 -g -DRODATA_SECTION_NAME=.rdata +RELEASE_VS2015x86_X64_NASM_FLAGS = -Ox -f win64 -DRODATA_SECTION_NAME=.rdata +NOOPT_VS2015x86_X64_NASM_FLAGS = -O0 -f win64 -g -DRODATA_SECTION_NAME=.rdata - DEBUG_VS2015x86_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG -RELEASE_VS2015x86_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data -NOOPT_VS2015x86_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + DEBUG_VS2015x86_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X64 /DEBUG +RELEASE_VS2015x86_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /MACHINE:X64 +NOOPT_VS2015x86_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X64 /DEBUG #################################################################################### # VS2017 - Microsoft Visual Studio 2017 with Intel ASL @@ -503,13 +526,13 @@ NOOPT_VS2017_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D RELEASE_VS2017_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd NOOPT_VS2017_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd /Zi - DEBUG_VS2017_IA32_NASM_FLAGS = -Ox -f win32 -g -RELEASE_VS2017_IA32_NASM_FLAGS = -Ox -f win32 -NOOPT_VS2017_IA32_NASM_FLAGS = -O0 -f win32 -g + DEBUG_VS2017_IA32_NASM_FLAGS = -Ox -f win32 -g -DRODATA_SECTION_NAME=.rdata +RELEASE_VS2017_IA32_NASM_FLAGS = -Ox -f win32 -DRODATA_SECTION_NAME=.rdata +NOOPT_VS2017_IA32_NASM_FLAGS = -O0 -f win32 -g -DRODATA_SECTION_NAME=.rdata - DEBUG_VS2017_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG -RELEASE_VS2017_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data -NOOPT_VS2017_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + DEBUG_VS2017_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X86 /DEBUG +RELEASE_VS2017_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /MACHINE:X86 +NOOPT_VS2017_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X86 /DEBUG ################## # X64 definitions @@ -533,13 +556,13 @@ NOOPT_VS2017_X64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /G RELEASE_VS2017_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd NOOPT_VS2017_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi - DEBUG_VS2017_X64_NASM_FLAGS = -Ox -f win64 -g -RELEASE_VS2017_X64_NASM_FLAGS = -Ox -f win64 -NOOPT_VS2017_X64_NASM_FLAGS = -O0 -f win64 -g + DEBUG_VS2017_X64_NASM_FLAGS = -Ox -f win64 -g -DRODATA_SECTION_NAME=.rdata +RELEASE_VS2017_X64_NASM_FLAGS = -Ox -f win64 -DRODATA_SECTION_NAME=.rdata +NOOPT_VS2017_X64_NASM_FLAGS = -O0 -f win64 -g -DRODATA_SECTION_NAME=.rdata - DEBUG_VS2017_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG -RELEASE_VS2017_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data -NOOPT_VS2017_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + DEBUG_VS2017_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4281 /MACHINE:X64 /DEBUG +RELEASE_VS2017_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4281 /IGNORE:4254 /MACHINE:X64 +NOOPT_VS2017_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4281 /MACHINE:X64 /DEBUG ################# # ARM definitions @@ -563,9 +586,9 @@ NOOPT_VS2017_ARM_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE RELEASE_VS2017_ARM_ASM_FLAGS = /nologo NOOPT_VS2017_ARM_ASM_FLAGS = /nologo - DEBUG_VS2017_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG -RELEASE_VS2017_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data -NOOPT_VS2017_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + DEBUG_VS2017_ARM_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:ARM /DEBUG +RELEASE_VS2017_ARM_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /MACHINE:ARM +NOOPT_VS2017_ARM_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:ARM /DEBUG ##################### # AARCH64 definitions @@ -589,9 +612,9 @@ NOOPT_VS2017_AARCH64_CC_FLAGS = /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE RELEASE_VS2017_AARCH64_ASM_FLAGS = /nologo NOOPT_VS2017_AARCH64_ASM_FLAGS = /nologo - DEBUG_VS2017_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /DEBUG -RELEASE_VS2017_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /MERGE:.rdata=.data -NOOPT_VS2017_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /DEBUG + DEBUG_VS2017_AARCH64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:ARM64 /DEBUG +RELEASE_VS2017_AARCH64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /MACHINE:ARM64 +NOOPT_VS2017_AARCH64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:ARM64 /DEBUG #################################################################################### # VS2019 - Microsoft Visual Studio 2019 with Intel ASL @@ -644,13 +667,13 @@ NOOPT_VS2019_IA32_CC_FLAGS = /nologo /arch:IA32 /c /WX /GS /W4 /Gs32768 /D RELEASE_VS2019_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd NOOPT_VS2019_IA32_ASM_FLAGS = /nologo /c /WX /W3 /Cx /coff /Zd /Zi - DEBUG_VS2019_IA32_NASM_FLAGS = -Ox -f win32 -g -RELEASE_VS2019_IA32_NASM_FLAGS = -Ox -f win32 -NOOPT_VS2019_IA32_NASM_FLAGS = -O0 -f win32 -g + DEBUG_VS2019_IA32_NASM_FLAGS = -Ox -f win32 -g -DRODATA_SECTION_NAME=.rdata +RELEASE_VS2019_IA32_NASM_FLAGS = -Ox -f win32 -DRODATA_SECTION_NAME=.rdata +NOOPT_VS2019_IA32_NASM_FLAGS = -O0 -f win32 -g -DRODATA_SECTION_NAME=.rdata - DEBUG_VS2019_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG -RELEASE_VS2019_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data -NOOPT_VS2019_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + DEBUG_VS2019_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X86 /DEBUG +RELEASE_VS2019_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /MACHINE:X86 +NOOPT_VS2019_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X86 /DEBUG ################## # X64 definitions @@ -674,13 +697,13 @@ NOOPT_VS2019_X64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE /Gy RELEASE_VS2019_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd NOOPT_VS2019_X64_ASM_FLAGS = /nologo /c /WX /W3 /Cx /Zd /Zi - DEBUG_VS2019_X64_NASM_FLAGS = -Ox -f win64 -g -RELEASE_VS2019_X64_NASM_FLAGS = -Ox -f win64 -NOOPT_VS2019_X64_NASM_FLAGS = -O0 -f win64 -g + DEBUG_VS2019_X64_NASM_FLAGS = -Ox -f win64 -g -DRODATA_SECTION_NAME=.rdata +RELEASE_VS2019_X64_NASM_FLAGS = -Ox -f win64 -DRODATA_SECTION_NAME=.rdata +NOOPT_VS2019_X64_NASM_FLAGS = -O0 -f win64 -g -DRODATA_SECTION_NAME=.rdata - DEBUG_VS2019_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG -RELEASE_VS2019_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data -NOOPT_VS2019_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + DEBUG_VS2019_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4281 /MACHINE:X64 /DEBUG +RELEASE_VS2019_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4281 /IGNORE:4254 /MACHINE:X64 +NOOPT_VS2019_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4281 /MACHINE:X64 /DEBUG ################# # ARM definitions @@ -704,9 +727,9 @@ NOOPT_VS2019_ARM_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE / RELEASE_VS2019_ARM_ASM_FLAGS = /nologo NOOPT_VS2019_ARM_ASM_FLAGS = /nologo - DEBUG_VS2019_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG -RELEASE_VS2019_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data -NOOPT_VS2019_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG + DEBUG_VS2019_ARM_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:ARM /DEBUG +RELEASE_VS2019_ARM_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /MACHINE:ARM +NOOPT_VS2019_ARM_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:ARM /DEBUG ##################### # AARCH64 definitions @@ -730,9 +753,9 @@ NOOPT_VS2019_AARCH64_CC_FLAGS = /nologo /c /WX /GS /W4 /Gs32768 /D UNICODE RELEASE_VS2019_AARCH64_ASM_FLAGS = /nologo NOOPT_VS2019_AARCH64_ASM_FLAGS = /nologo - DEBUG_VS2019_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /DEBUG -RELEASE_VS2019_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /MERGE:.rdata=.data -NOOPT_VS2019_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /DEBUG + DEBUG_VS2019_AARCH64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:ARM64 /DEBUG +RELEASE_VS2019_AARCH64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /MACHINE:ARM64 +NOOPT_VS2019_AARCH64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:ARM64 /DEBUG #################################################################################### # VS2022 - Microsoft Visual Studio 2022 with Intel ASL @@ -908,12 +931,8 @@ NOOPT_VS2022_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF #################################################################################### *_*_*_OBJCOPY_PATH = echo -*_*_*_OBJCOPY_FLAGS = objcopy not needed for *_*_*_SYMRENAME_PATH = echo *_*_*_SYMRENAME_FLAGS = Symbol renaming not needed for -DEBUG_*_*_OBJCOPY_ADDDEBUGFLAG = --add-gnu-debuglink="$(DEBUG_DIR)/$(MODULE_NAME).debug" -RELEASE_*_*_OBJCOPY_ADDDEBUGFLAG = -NOOPT_*_*_OBJCOPY_ADDDEBUGFLAG = --add-gnu-debuglink="$(DEBUG_DIR)/$(MODULE_NAME).debug" *_*_*_OBJCOPY_STRIPFLAG = --strip-unneeded -R .eh_frame *_*_*_DTC_FLAGS = -H epapr *_*_*_DTCPP_PATH = DEF(DTCPP_BIN) @@ -922,20 +941,20 @@ NOOPT_*_*_OBJCOPY_ADDDEBUGFLAG = --add-gnu-debuglink="$(DEBUG_DIR)/$(MODULE_ # All supported GCC archs except LOONGARCH64 support -mstack-protector-guard=global, so set that on everything except LOONGARCH64 DEFINE GCC_ALL_CC_FLAGS = -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -fno-common -fstack-protector DEFINE GCC_IA32_X64_CC_FLAGS = -mstack-protector-guard=global -DEFINE GCC_ARM_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -mabi=aapcs -fno-short-enums -funsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -Wno-address -mthumb -fno-pic -fno-pie -mstack-protector-guard=global +DEFINE GCC_ARM_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -march=armv7-a -mthumb -mlittle-endian -mabi=aapcs -fno-short-enums -funsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -Wno-address -fno-pic -fno-pie -mstack-protector-guard=global DEFINE GCC_LOONGARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mabi=lp64d -fno-asynchronous-unwind-tables -Wno-address -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections DEFINE GCC_ARM_CC_XIPFLAGS = -mno-unaligned-access DEFINE GCC_AARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -fno-short-enums -fverbose-asm -funsigned-char -ffunction-sections -fdata-sections -Wno-address -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pic -fno-pie -ffixed-x18 -mstack-protector-guard=global DEFINE GCC_AARCH64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only DEFINE GCC_RISCV64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only -DEFINE GCC_DLINK2_FLAGS_COMMON = -Wl,--script=$(EDK_TOOLS_PATH)/Scripts/GccBase.lds +DEFINE GCC_DLINK2_FLAGS_COMMON = -Wl,--defsym=ALIGNED_PE_HEADER_SIZE=0x400 DEF(DLINK_SCRIPT) DEFINE GCC_IA32_X64_DLINK_COMMON = -nostdlib --pie --fatal-warnings -z,noexecstack --gc-sections -DEFINE GCC_ARM_AARCH64_DLINK_COMMON= -Wl,--emit-relocs -nostdlib -Wl,--gc-sections -u $(IMAGE_ENTRY_POINT) -Wl,-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map -Wl,--fatal-warnings -Wl,-z,noexecstack +DEFINE GCC_ARM_AARCH64_DLINK_COMMON= -Wl,--emit-relocs -nostdlib -Wl,--gc-sections -u $(IMAGE_ENTRY_POINT) -Wl,-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map -Wl,--fatal-warnings -Wl,-z,noexecstack -no-pie DEFINE GCC_LOONGARCH64_DLINK_COMMON= -Wl,--emit-relocs -nostdlib -Wl,--gc-sections -u $(IMAGE_ENTRY_POINT) -Wl,-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map -DEFINE GCC_ARM_DLINK_FLAGS = DEF(GCC_ARM_AARCH64_DLINK_COMMON) -z common-page-size=0x20 -Wl,--pic-veneer -DEFINE GCC_AARCH64_DLINK_FLAGS = DEF(GCC_ARM_AARCH64_DLINK_COMMON) -z common-page-size=0x20 -DEFINE GCC_LOONGARCH64_DLINK_FLAGS = DEF(GCC_LOONGARCH64_DLINK_COMMON) -z common-page-size=0x20 -DEFINE GCC_ARM_AARCH64_ASLDLINK_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0 DEF(GCC_DLINK2_FLAGS_COMMON) -z common-page-size=0x20 +DEFINE GCC_ARM_DLINK_FLAGS = DEF(GCC_ARM_AARCH64_DLINK_COMMON) DEF(GCC_ALIGN) -Wl,--pic-veneer +DEFINE GCC_AARCH64_DLINK_FLAGS = DEF(GCC_ARM_AARCH64_DLINK_COMMON) DEF(GCC_ALIGN) +DEFINE GCC_LOONGARCH64_DLINK_FLAGS = DEF(GCC_LOONGARCH64_DLINK_COMMON) DEF(GCC_ALIGN) +DEFINE GCC_ARM_AARCH64_ASLDLINK_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) DEF(GCC_ALIGN) DEFINE GCC_IA32_X64_ASLDLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_COMMON) --entry _ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT) DEFINE GCC_ARM_ASLDLINK_FLAGS = DEF(GCC_ARM_DLINK_FLAGS) -Wl,--entry,ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT) DEF(GCC_ARM_AARCH64_ASLDLINK_FLAGS) DEFINE GCC_AARCH64_ASLDLINK_FLAGS = DEF(GCC_AARCH64_DLINK_FLAGS) -Wl,--entry,ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT) DEF(GCC_ARM_AARCH64_ASLDLINK_FLAGS) @@ -948,45 +967,38 @@ DEFINE GCC_ASLPP_FLAGS = -x c -E -include AutoGen.h DEFINE GCC_ASLCC_FLAGS = -x c DEFINE GCC_WINDRES_FLAGS = -J rc -O coff DEFINE GCC_DTCPP_FLAGS = -E -x assembler-with-cpp -imacros AutoGen.h -nostdinc -undef -DEFINE GCC_IA32_RC_FLAGS = -I binary -O elf32-i386 -B i386 --rename-section .data=.hii -DEFINE GCC_X64_RC_FLAGS = -I binary -O elf64-x86-64 -B i386 --rename-section .data=.hii -DEFINE GCC_ARM_RC_FLAGS = -I binary -O elf32-littlearm -B arm --rename-section .data=.hii -DEFINE GCC_AARCH64_RC_FLAGS = -I binary -O elf64-littleaarch64 -B aarch64 --rename-section .data=.hii -DEFINE GCC_AARCH64_RC_BTI_FLAGS = --add-section .note.gnu.property=$(WORKSPACE)/BaseTools/Bin/GnuNoteBti.bin --set-section-flags .note.gnu.property=alloc,readonly -DEFINE GCC_RISCV64_RC_FLAGS = -I binary -O elf64-littleriscv -B riscv --rename-section .data=.hii -DEFINE GCC_LOONGARCH64_RC_FLAGS = -I binary -O elf64-loongarch -B loongarch64 --rename-section .data=.hii # GCC Build Flag for included header file list generation DEFINE GCC_DEPS_FLAGS = -MMD -MF $@.deps DEFINE GCC48_ALL_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -DEFINE GCC48_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x20 +DEFINE GCC48_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections DEF(GCC_ALIGN) DEFINE GCC48_IA32_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m32 -march=i586 -malign-double -D EFI32 -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer -DEFINE GCC48_X64_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer +DEFINE GCC48_X64_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer DEFINE GCC48_IA32_X64_ASLDLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable DEFINE GCC48_IA32_X64_DLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive -DEFINE GCC48_IA32_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x220 DEF(GCC_DLINK2_FLAGS_COMMON) +DEFINE GCC48_IA32_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) DEFINE GCC48_X64_DLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_FLAGS) -Wl,-melf_x86_64,--oformat=elf64-x86-64,-pie -DEFINE GCC48_X64_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x228 DEF(GCC_DLINK2_FLAGS_COMMON) +DEFINE GCC48_X64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) DEFINE GCC48_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -DEFINE GCC48_ARM_ASM_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_ASM_FLAGS) -mlittle-endian -DEFINE GCC48_AARCH64_ASM_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_ASM_FLAGS) -mlittle-endian -DEFINE GCC48_ARM_CC_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_ARM_CC_FLAGS) -mword-relocations +DEFINE GCC48_ARM_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian -march=armv7-a +DEFINE GCC48_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian +DEFINE GCC48_ARM_CC_FLAGS = DEF(GCC_ARM_CC_FLAGS) -mword-relocations DEFINE GCC48_ARM_CC_XIPFLAGS = DEF(GCC_ARM_CC_XIPFLAGS) -DEFINE GCC48_AARCH64_CC_FLAGS = $(PLATFORM_FLAGS) -mcmodel=large DEF(GCC_AARCH64_CC_FLAGS) +DEFINE GCC48_AARCH64_CC_FLAGS = -mcmodel=large DEF(GCC_AARCH64_CC_FLAGS) DEFINE GCC48_AARCH64_CC_XIPFLAGS = DEF(GCC_AARCH64_CC_XIPFLAGS) DEFINE GCC48_ARM_DLINK_FLAGS = DEF(GCC_ARM_DLINK_FLAGS) -Wl,--oformat=elf32-littlearm -DEFINE GCC48_ARM_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0x220 +DEFINE GCC48_ARM_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) DEFINE GCC48_AARCH64_DLINK_FLAGS = DEF(GCC_AARCH64_DLINK_FLAGS) -DEFINE GCC48_AARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0x228 +DEFINE GCC48_AARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) DEFINE GCC48_ARM_ASLDLINK_FLAGS = DEF(GCC_ARM_ASLDLINK_FLAGS) -Wl,--oformat=elf32-littlearm DEFINE GCC48_AARCH64_ASLDLINK_FLAGS = DEF(GCC_AARCH64_ASLDLINK_FLAGS) DEFINE GCC48_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) DEFINE GCC49_IA32_CC_FLAGS = DEF(GCC48_IA32_CC_FLAGS) -fno-pic -fno-pie DEFINE GCC49_X64_CC_FLAGS = DEF(GCC48_X64_CC_FLAGS) -DEFINE GCC49_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x40 -DEFINE GCC49_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_DLINK_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0 DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable +DEFINE GCC49_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections DEF(GCC_ALIGN) +DEFINE GCC49_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_DLINK_COMMON) DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable DEFINE GCC49_IA32_X64_DLINK_FLAGS = DEF(GCC49_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive DEFINE GCC49_IA32_DLINK2_FLAGS = DEF(GCC48_IA32_DLINK2_FLAGS) DEFINE GCC49_X64_DLINK_FLAGS = DEF(GCC49_IA32_X64_DLINK_FLAGS) -Wl,-melf_x86_64,--oformat=elf64-x86-64,-pie @@ -996,11 +1008,11 @@ DEFINE GCC49_ARM_ASM_FLAGS = DEF(GCC48_ARM_ASM_FLAGS) DEFINE GCC49_AARCH64_ASM_FLAGS = DEF(GCC48_AARCH64_ASM_FLAGS) DEFINE GCC49_ARM_CC_FLAGS = DEF(GCC48_ARM_CC_FLAGS) DEFINE GCC49_ARM_CC_XIPFLAGS = DEF(GCC48_ARM_CC_XIPFLAGS) -DEFINE GCC49_AARCH64_CC_FLAGS = $(PLATFORM_FLAGS) DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_AARCH64_CC_FLAGS) -mcmodel=small +DEFINE GCC49_AARCH64_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_AARCH64_CC_FLAGS) -mcmodel=small DEFINE GCC49_AARCH64_CC_XIPFLAGS = DEF(GCC48_AARCH64_CC_XIPFLAGS) DEFINE GCC49_ARM_DLINK_FLAGS = DEF(GCC48_ARM_DLINK_FLAGS) DEFINE GCC49_ARM_DLINK2_FLAGS = DEF(GCC48_ARM_DLINK2_FLAGS) -DEFINE GCC49_AARCH64_DLINK_FLAGS = DEF(GCC48_AARCH64_DLINK_FLAGS) -z common-page-size=0x1000 +DEFINE GCC49_AARCH64_DLINK_FLAGS = DEF(GCC48_AARCH64_DLINK_FLAGS) DEF(GCC_ALIGN) DEFINE GCC49_AARCH64_DLINK2_FLAGS = DEF(GCC48_AARCH64_DLINK2_FLAGS) DEFINE GCC49_ARM_ASLDLINK_FLAGS = DEF(GCC48_ARM_ASLDLINK_FLAGS) DEFINE GCC49_AARCH64_ASLDLINK_FLAGS = DEF(GCC48_AARCH64_ASLDLINK_FLAGS) @@ -1030,9 +1042,9 @@ DEFINE GCC5_AARCH64_ASLDLINK_FLAGS = DEF(GCC49_AARCH64_ASLDLINK_FLAGS) DEFINE GCC5_ASLCC_FLAGS = DEF(GCC49_ASLCC_FLAGS) -fno-lto DEFINE GCC5_RISCV_ALL_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -fno-common -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -msmall-data-limit=0 -DEFINE GCC5_RISCV_ALL_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x40 +DEFINE GCC5_RISCV_ALL_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections DEF(GCC_ALIGN) DEFINE GCC5_RISCV_ALL_DLINK_FLAGS = DEF(GCC5_RISCV_ALL_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map -DEFINE GCC5_RISCV_ALL_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x220,--script=$(EDK_TOOLS_PATH)/Scripts/GccBase.lds +DEFINE GCC5_RISCV_ALL_DLINK2_FLAGS = -Wl,--defsym=ALIGNED_PE_HEADER_SIZE=0x400 DEF(DLINK_SCRIPT) DEFINE GCC5_RISCV_ALL_ASM_FLAGS = -c -x assembler -imacros $(DEST_DIR_DEBUG)/AutoGen.h DEFINE GCC5_RISCV_ALL_CC_FLAGS_WARNING_DISABLE = -Wno-tautological-compare -Wno-pointer-compare @@ -1047,7 +1059,7 @@ DEFINE GCC5_RISCV64_ASM_FLAGS = DEF(GCC5_RISCV_ALL_ASM_FLAGS) -marc DEFINE GCC5_LOONGARCH64_CC_FLAGS = DEF(GCC_LOONGARCH64_CC_FLAGS) -march=loongarch64 -mno-memcpy -Werror -Wno-maybe-uninitialized -Wno-stringop-overflow -Wno-pointer-to-int-cast -no-pie -fno-stack-protector -mno-explicit-relocs DEFINE GCC5_LOONGARCH64_DLINK_FLAGS = DEF(GCC_LOONGARCH64_DLINK_FLAGS) -DEFINE GCC5_LOONGARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0x228 +DEFINE GCC5_LOONGARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) DEFINE GCC5_LOONGARCH64_ASLDLINK_FLAGS = DEF(GCC_LOONGARCH64_ASLDLINK_FLAGS) DEF(GCC5_LOONGARCH64_DLINK2_FLAGS) DEFINE GCC5_LOONGARCH64_ASM_FLAGS = -x assembler-with-cpp -mabi=lp64d -march=loongarch64 -fno-builtin -c -Wall -mno-explicit-relocs DEFINE GCC5_LOONGARCH64_PP_FLAGS = -mabi=lp64d -march=loongarch64 DEF(GCC_PP_FLAGS) @@ -1094,8 +1106,7 @@ DEFINE GCC5_LOONGARCH64_PP_FLAGS = -mabi=lp64d -march=loongarch64 DEF( *_GCC48_IA32_DLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_FLAGS) -Wl,-m,elf_i386,--oformat=elf32-i386 *_GCC48_IA32_DLINK2_FLAGS = DEF(GCC48_IA32_DLINK2_FLAGS) *_GCC48_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS) -*_GCC48_IA32_OBJCOPY_FLAGS = -*_GCC48_IA32_NASM_FLAGS = -f elf32 +*_GCC48_IA32_NASM_FLAGS = -f elf32 -DRODATA_SECTION_NAME=.rodata DEBUG_GCC48_IA32_CC_FLAGS = DEF(GCC48_IA32_CC_FLAGS) RELEASE_GCC48_IA32_CC_FLAGS = DEF(GCC48_IA32_CC_FLAGS) -Wno-unused-but-set-variable @@ -1122,8 +1133,7 @@ RELEASE_GCC48_IA32_CC_FLAGS = DEF(GCC48_IA32_CC_FLAGS) -Wno-unused-but-set *_GCC48_X64_DLINK_FLAGS = DEF(GCC48_X64_DLINK_FLAGS) *_GCC48_X64_DLINK2_FLAGS = DEF(GCC48_X64_DLINK2_FLAGS) *_GCC48_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) -*_GCC48_X64_OBJCOPY_FLAGS = -*_GCC48_X64_NASM_FLAGS = -f elf64 +*_GCC48_X64_NASM_FLAGS = -f elf64 -DRODATA_SECTION_NAME=.rodata DEBUG_GCC48_X64_CC_FLAGS = DEF(GCC48_X64_CC_FLAGS) RELEASE_GCC48_X64_CC_FLAGS = DEF(GCC48_X64_CC_FLAGS) -Wno-unused-but-set-variable @@ -1149,10 +1159,9 @@ RELEASE_GCC48_X64_CC_FLAGS = DEF(GCC48_X64_CC_FLAGS) -Wno-unused-but-set-v *_GCC48_ARM_DLINK_FLAGS = DEF(GCC48_ARM_DLINK_FLAGS) *_GCC48_ARM_DLINK2_FLAGS = DEF(GCC48_ARM_DLINK2_FLAGS) *_GCC48_ARM_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC48_ARM_PLATFORM_FLAGS = -march=armv7-a -*_GCC48_ARM_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) +*_GCC48_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS) -mthumb -march=armv7-a *_GCC48_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS) -*_GCC48_ARM_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) +*_GCC48_ARM_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -mthumb -march=armv7-a *_GCC48_ARM_CC_XIPFLAGS = DEF(GCC48_ARM_CC_XIPFLAGS) DEBUG_GCC48_ARM_CC_FLAGS = DEF(GCC48_ARM_CC_FLAGS) -O0 @@ -1179,10 +1188,9 @@ RELEASE_GCC48_ARM_CC_FLAGS = DEF(GCC48_ARM_CC_FLAGS) -Wno-unused-but-set-v *_GCC48_AARCH64_DLINK_FLAGS = DEF(GCC48_AARCH64_DLINK_FLAGS) *_GCC48_AARCH64_DLINK2_FLAGS = DEF(GCC48_AARCH64_DLINK2_FLAGS) *_GCC48_AARCH64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC48_AARCH64_PLATFORM_FLAGS = -*_GCC48_AARCH64_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) +*_GCC48_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) *_GCC48_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS) -*_GCC48_AARCH64_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) +*_GCC48_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) *_GCC48_AARCH64_CC_XIPFLAGS = DEF(GCC48_AARCH64_CC_XIPFLAGS) DEBUG_GCC48_AARCH64_CC_FLAGS = DEF(GCC48_AARCH64_CC_FLAGS) -O0 @@ -1231,8 +1239,7 @@ RELEASE_GCC48_AARCH64_CC_FLAGS = DEF(GCC48_AARCH64_CC_FLAGS) -Wno-unused-but-s *_GCC49_IA32_DLINK_FLAGS = DEF(GCC49_IA32_X64_DLINK_FLAGS) -Wl,-m,elf_i386,--oformat=elf32-i386 *_GCC49_IA32_DLINK2_FLAGS = DEF(GCC49_IA32_DLINK2_FLAGS) *_GCC49_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS) -*_GCC49_IA32_OBJCOPY_FLAGS = -*_GCC49_IA32_NASM_FLAGS = -f elf32 +*_GCC49_IA32_NASM_FLAGS = -f elf32 -DRODATA_SECTION_NAME=.rodata DEBUG_GCC49_IA32_CC_FLAGS = DEF(GCC49_IA32_CC_FLAGS) RELEASE_GCC49_IA32_CC_FLAGS = DEF(GCC49_IA32_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable @@ -1259,8 +1266,7 @@ RELEASE_GCC49_IA32_CC_FLAGS = DEF(GCC49_IA32_CC_FLAGS) -Wno-unused-but-set *_GCC49_X64_DLINK_FLAGS = DEF(GCC49_X64_DLINK_FLAGS) *_GCC49_X64_DLINK2_FLAGS = DEF(GCC49_X64_DLINK2_FLAGS) *_GCC49_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) -*_GCC49_X64_OBJCOPY_FLAGS = -*_GCC49_X64_NASM_FLAGS = -f elf64 +*_GCC49_X64_NASM_FLAGS = -f elf64 -DRODATA_SECTION_NAME=.rodata DEBUG_GCC49_X64_CC_FLAGS = DEF(GCC49_X64_CC_FLAGS) RELEASE_GCC49_X64_CC_FLAGS = DEF(GCC49_X64_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable @@ -1286,10 +1292,9 @@ RELEASE_GCC49_X64_CC_FLAGS = DEF(GCC49_X64_CC_FLAGS) -Wno-unused-but-set-v *_GCC49_ARM_DLINK_FLAGS = DEF(GCC49_ARM_DLINK_FLAGS) *_GCC49_ARM_DLINK2_FLAGS = DEF(GCC49_ARM_DLINK2_FLAGS) *_GCC49_ARM_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC49_ARM_PLATFORM_FLAGS = -march=armv7-a -*_GCC49_ARM_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) +*_GCC49_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS) -mthumb -march=armv7-a *_GCC49_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS) -*_GCC49_ARM_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) +*_GCC49_ARM_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -mthumb -march=armv7-a *_GCC49_ARM_CC_XIPFLAGS = DEF(GCC49_ARM_CC_XIPFLAGS) DEBUG_GCC49_ARM_CC_FLAGS = DEF(GCC49_ARM_CC_FLAGS) -O0 @@ -1315,23 +1320,22 @@ RELEASE_GCC49_ARM_CC_FLAGS = DEF(GCC49_ARM_CC_FLAGS) -Wno-unused-but-set-v *_GCC49_AARCH64_ASM_FLAGS = DEF(GCC49_AARCH64_ASM_FLAGS) *_GCC49_AARCH64_DLINK2_FLAGS = DEF(GCC49_AARCH64_DLINK2_FLAGS) *_GCC49_AARCH64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC49_AARCH64_PLATFORM_FLAGS = -*_GCC49_AARCH64_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) +*_GCC49_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) *_GCC49_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS) -*_GCC49_AARCH64_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) +*_GCC49_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) *_GCC49_AARCH64_CC_XIPFLAGS = DEF(GCC49_AARCH64_CC_XIPFLAGS) DEBUG_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -O0 DEBUG_GCC49_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) - DEBUG_GCC49_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 + DEBUG_GCC49_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) RELEASE_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable RELEASE_GCC49_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) -RELEASE_GCC49_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 +RELEASE_GCC49_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) NOOPT_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -O0 NOOPT_GCC49_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) -O0 - NOOPT_GCC49_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 -O0 + NOOPT_GCC49_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) -O0 #################################################################################### # @@ -1517,9 +1521,7 @@ RELEASE_GCCNOLTO_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 *_GCC5_IA32_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -no-pie *_GCC5_IA32_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m32 -march=i386 *_GCC5_IA32_DLINK2_FLAGS = DEF(GCC5_IA32_DLINK2_FLAGS) -no-pie -*_GCC5_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS) -*_GCC5_IA32_OBJCOPY_FLAGS = -*_GCC5_IA32_NASM_FLAGS = -f elf32 +*_GCC5_IA32_NASM_FLAGS = -f elf32 -DRODATA_SECTION_NAME=.rodata DEBUG_GCC5_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -flto DEBUG_GCC5_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-m,elf_i386,--oformat=elf32-i386 @@ -1549,9 +1551,7 @@ RELEASE_GCC5_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl, *_GCC5_X64_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 *_GCC5_X64_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m64 *_GCC5_X64_DLINK2_FLAGS = DEF(GCC5_X64_DLINK2_FLAGS) -*_GCC5_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) -*_GCC5_X64_OBJCOPY_FLAGS = -*_GCC5_X64_NASM_FLAGS = -f elf64 +*_GCC5_X64_NASM_FLAGS = -f elf64 -DRODATA_SECTION_NAME=.rodata DEBUG_GCC5_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -flto -DUSING_LTO DEBUG_GCC5_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os @@ -1565,6 +1565,7 @@ RELEASE_GCC5_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os ################## # GCC5 ARM definitions ################## +*_GCC5_ARM_OBJCOPY_PATH = ENV(GCC5_ARM_PREFIX)objcopy *_GCC5_ARM_CC_PATH = ENV(GCC5_ARM_PREFIX)gcc *_GCC5_ARM_SLINK_PATH = ENV(GCC5_ARM_PREFIX)gcc-ar *_GCC5_ARM_DLINK_PATH = ENV(GCC5_ARM_PREFIX)gcc @@ -1581,10 +1582,8 @@ RELEASE_GCC5_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os *_GCC5_ARM_ASM_FLAGS = DEF(GCC5_ARM_ASM_FLAGS) *_GCC5_ARM_DLINK2_FLAGS = DEF(GCC5_ARM_DLINK2_FLAGS) *_GCC5_ARM_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC5_ARM_PLATFORM_FLAGS = -march=armv7-a -mfloat-abi=soft -*_GCC5_ARM_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) -*_GCC5_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS) -*_GCC5_ARM_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) +*_GCC5_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS) -mthumb -march=armv7-a +*_GCC5_ARM_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -mthumb -march=armv7-a *_GCC5_ARM_CC_XIPFLAGS = DEF(GCC5_ARM_CC_XIPFLAGS) DEBUG_GCC5_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable @@ -1599,6 +1598,7 @@ RELEASE_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKS ################## # GCC5 AARCH64 definitions ################## +*_GCC5_AARCH64_OBJCOPY_PATH = ENV(GCC5_AARCH64_PREFIX)objcopy *_GCC5_AARCH64_CC_PATH = ENV(GCC5_AARCH64_PREFIX)gcc *_GCC5_AARCH64_SLINK_PATH = ENV(GCC5_AARCH64_PREFIX)gcc-ar *_GCC5_AARCH64_DLINK_PATH = ENV(GCC5_AARCH64_PREFIX)gcc @@ -1615,23 +1615,21 @@ RELEASE_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKS *_GCC5_AARCH64_ASM_FLAGS = DEF(GCC5_AARCH64_ASM_FLAGS) *_GCC5_AARCH64_DLINK2_FLAGS = DEF(GCC5_AARCH64_DLINK2_FLAGS) *_GCC5_AARCH64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC5_AARCH64_PLATFORM_FLAGS = -*_GCC5_AARCH64_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) -*_GCC5_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS) DEF(GCC_AARCH64_RC_BTI_FLAGS) -*_GCC5_AARCH64_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) +*_GCC5_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) +*_GCC5_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) *_GCC5_AARCH64_CC_XIPFLAGS = DEF(GCC5_AARCH64_CC_XIPFLAGS) DEBUG_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable DEBUG_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch - DEBUG_GCC5_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 + DEBUG_GCC5_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) RELEASE_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable RELEASE_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch -RELEASE_GCC5_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 +RELEASE_GCC5_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) NOOPT_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 NOOPT_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -O0 - NOOPT_GCC5_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 -O0 + NOOPT_GCC5_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) -O0 #################################################################################### # @@ -1661,8 +1659,6 @@ RELEASE_GCC5_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 *_GCC5_RISCV64_CC_FLAGS = DEF(GCC5_RISCV64_CC_FLAGS) -save-temps *_GCC5_RISCV64_DLINK_FLAGS = DEF(GCC5_RISCV64_DLINK_FLAGS) *_GCC5_RISCV64_DLINK2_FLAGS = DEF(GCC5_RISCV64_DLINK2_FLAGS) -*_GCC5_RISCV64_RC_FLAGS = DEF(GCC_RISCV64_RC_FLAGS) -*_GCC5_RISCV64_OBJCOPY_FLAGS = *_GCC5_RISCV64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) *_GCC5_RISCV64_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(GCC5_RISCV_OPENSBI_TYPES) @@ -1686,8 +1682,6 @@ RELEASE_GCC5_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 *_GCC5_LOONGARCH64_ASM_FLAGS = DEF(GCC5_LOONGARCH64_ASM_FLAGS) *_GCC5_LOONGARCH64_DLINK_FLAGS = DEF(GCC5_LOONGARCH64_DLINK_FLAGS) *_GCC5_LOONGARCH64_DLINK2_FLAGS = DEF(GCC5_LOONGARCH64_DLINK2_FLAGS) -*_GCC5_LOONGARCH64_RC_FLAGS = DEF(GCC_LOONGARCH64_RC_FLAGS) -*_GCC5_LOONGARCH64_OBJCOPY_FLAGS = *_GCC5_LOONGARCH64_NASM_FLAGS = -f elf32 *_GCC5_LOONGARCH64_PP_FLAGS = DEF(GCC5_LOONGARCH64_PP_FLAGS) @@ -1734,7 +1728,6 @@ RELEASE_GCC5_LOONGARCH64_CC_FLAGS = DEF(GCC5_LOONGARCH64_CC_FLAGS) -Wno-un *_GCC_IA32_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -no-pie *_GCC_IA32_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m32 -march=i386 *_GCC_IA32_DLINK2_FLAGS = DEF(GCC5_IA32_DLINK2_FLAGS) -no-pie -*_GCC_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS) *_GCC_IA32_OBJCOPY_FLAGS = *_GCC_IA32_NASM_FLAGS = -f elf32 @@ -1766,7 +1759,6 @@ RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,- *_GCC_X64_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 *_GCC_X64_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m64 *_GCC_X64_DLINK2_FLAGS = DEF(GCC5_X64_DLINK2_FLAGS) -*_GCC_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) *_GCC_X64_OBJCOPY_FLAGS = *_GCC_X64_NASM_FLAGS = -f elf64 @@ -1800,7 +1792,6 @@ RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os *_GCC_ARM_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) *_GCC_ARM_PLATFORM_FLAGS = -march=armv7-a -mfloat-abi=soft *_GCC_ARM_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) -*_GCC_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS) *_GCC_ARM_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) *_GCC_ARM_CC_XIPFLAGS = DEF(GCC5_ARM_CC_XIPFLAGS) @@ -1834,7 +1825,6 @@ RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSP *_GCC_AARCH64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) *_GCC_AARCH64_PLATFORM_FLAGS = *_GCC_AARCH64_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) -*_GCC_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS) DEF(GCC_AARCH64_RC_BTI_FLAGS) *_GCC_AARCH64_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) *_GCC_AARCH64_CC_XIPFLAGS = DEF(GCC5_AARCH64_CC_XIPFLAGS) @@ -1878,7 +1868,6 @@ RELEASE_GCC_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 *_GCC_RISCV64_CC_FLAGS = DEF(GCC5_RISCV64_CC_FLAGS) -save-temps *_GCC_RISCV64_DLINK_FLAGS = DEF(GCC5_RISCV64_DLINK_FLAGS) *_GCC_RISCV64_DLINK2_FLAGS = DEF(GCC5_RISCV64_DLINK2_FLAGS) -*_GCC_RISCV64_RC_FLAGS = DEF(GCC_RISCV64_RC_FLAGS) *_GCC_RISCV64_OBJCOPY_FLAGS = *_GCC_RISCV64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) *_GCC_RISCV64_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(GCC5_RISCV_OPENSBI_TYPES) @@ -1903,7 +1892,6 @@ RELEASE_GCC_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 *_GCC_LOONGARCH64_ASM_FLAGS = DEF(GCC5_LOONGARCH64_ASM_FLAGS) *_GCC_LOONGARCH64_DLINK_FLAGS = DEF(GCC5_LOONGARCH64_DLINK_FLAGS) *_GCC_LOONGARCH64_DLINK2_FLAGS = DEF(GCC5_LOONGARCH64_DLINK2_FLAGS) -*_GCC_LOONGARCH64_RC_FLAGS = DEF(GCC_LOONGARCH64_RC_FLAGS) *_GCC_LOONGARCH64_OBJCOPY_FLAGS = *_GCC_LOONGARCH64_NASM_FLAGS = -f elf32 *_GCC_LOONGARCH64_PP_FLAGS = DEF(GCC5_LOONGARCH64_PP_FLAGS) @@ -1954,22 +1942,21 @@ DEFINE CLANGPDB_ALL_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(CLANGPDB_WARN *_CLANGPDB_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32 -fno-lto DEF(CLANGPDB_IA32_TARGET) *_CLANGPDB_IA32_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -m32 -march=i386 DEF(CLANGPDB_IA32_TARGET) -*_CLANGPDB_IA32_OBJCOPY_FLAGS = -*_CLANGPDB_IA32_NASM_FLAGS = -f win32 +*_CLANGPDB_IA32_NASM_FLAGS = -f win32 -DRODATA_SECTION_NAME=.rdata *_CLANGPDB_IA32_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGPDB_IA32_TARGET) *_CLANGPDB_IA32_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGPDB_IA32_TARGET) *_CLANGPDB_IA32_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGPDB_IA32_TARGET) DEBUG_CLANGPDB_IA32_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m32 -Oz -flto -march=i586 DEF(CLANGPDB_IA32_TARGET) -gcodeview -malign-double -DEBUG_CLANGPDB_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /ALIGN:32 /DRIVER /FILEALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap +DEBUG_CLANGPDB_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /DRIVER /MACHINE:X86 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap DEBUG_CLANGPDB_IA32_DLINK2_FLAGS = RELEASE_CLANGPDB_IA32_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m32 -Oz -flto -march=i586 DEF(CLANGPDB_IA32_TARGET) -malign-double -RELEASE_CLANGPDB_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /ALIGN:32 /DRIVER /FILEALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /MERGE:.rdata=.data /MLLVM:-exception-model=wineh /lldmap +RELEASE_CLANGPDB_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /DRIVER /IGNORE:4254 /MACHINE:X86 /MLLVM:-exception-model=wineh /lldmap RELEASE_CLANGPDB_IA32_DLINK2_FLAGS = NOOPT_CLANGPDB_IA32_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m32 -O0 -march=i586 DEF(CLANGPDB_IA32_TARGET) -gcodeview -malign-double -NOOPT_CLANGPDB_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /ALIGN:32 /DRIVER /FILEALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap +NOOPT_CLANGPDB_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /DRIVER /MACHINE:X86 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap NOOPT_CLANGPDB_IA32_DLINK2_FLAGS = ########################## @@ -1988,26 +1975,22 @@ NOOPT_CLANGPDB_IA32_DLINK2_FLAGS = *_CLANGPDB_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64 -fno-lto DEF(CLANGPDB_X64_TARGET) *_CLANGPDB_X64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -m64 DEF(CLANGPDB_X64_TARGET) -*_CLANGPDB_X64_OBJCOPY_FLAGS = -*_CLANGPDB_X64_NASM_FLAGS = -f win64 +*_CLANGPDB_X64_NASM_FLAGS = -f win64 -DRODATA_SECTION_NAME=.rdata *_CLANGPDB_X64_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGPDB_X64_TARGET) *_CLANGPDB_X64_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGPDB_X64_TARGET) *_CLANGPDB_X64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGPDB_X64_TARGET) DEBUG_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -Oz -flto DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables -DEBUG_CLANGPDB_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /ALIGN:32 /DRIVER /FILEALIGN:32 /Machine:X64 /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap +DEBUG_CLANGPDB_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /DRIVER /MACHINE:X64 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap DEBUG_CLANGPDB_X64_DLINK2_FLAGS = -DEBUG_CLANGPDB_X64_GENFW_FLAGS = --keepexceptiontable RELEASE_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -Oz -flto DEF(CLANGPDB_X64_TARGET) -fno-unwind-tables -RELEASE_CLANGPDB_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /ALIGN:32 /DRIVER /FILEALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /MERGE:.rdata=.data /MLLVM:-exception-model=wineh /lldmap +RELEASE_CLANGPDB_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /DRIVER /IGNORE:4254 /MACHINE:X64 /MLLVM:-exception-model=wineh /lldmap RELEASE_CLANGPDB_X64_DLINK2_FLAGS = -RELEASE_CLANGPDB_X64_GENFW_FLAGS = NOOPT_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -O0 DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables -NOOPT_CLANGPDB_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /ALIGN:32 /DRIVER /FILEALIGN:32 /Machine:X64 /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap +NOOPT_CLANGPDB_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /DRIVER /MACHINE:X64 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap NOOPT_CLANGPDB_X64_DLINK2_FLAGS = -NOOPT_CLANGPDB_X64_GENFW_FLAGS = --keepexceptiontable #################################################################################### # @@ -2027,15 +2010,14 @@ NOOPT_CLANGPDB_X64_GENFW_FLAGS = --keepexceptiontable DEFINE CLANGDWARF_IA32_PREFIX = ENV(CLANG_BIN) DEFINE CLANGDWARF_X64_PREFIX = ENV(CLANG_BIN) +DEFINE CLANGDWARF_ARM_PREFIX = ENV(CLANG_BIN) +DEFINE CLANGDWARF_AARCH64_PREFIX = ENV(CLANG_BIN) # LLVM/CLANG doesn't support -n link option. So, it can't share the same IA32_X64_DLINK_COMMON flag. -# LLVM/CLANG doesn't support common page size. So, it can't share the same GccBase.lds script. -DEFINE CLANGDWARF_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-q,--gc-sections -z common-page-size=0x40 -Wl,-z,notext -DEFINE CLANGDWARF_DLINK2_FLAGS_COMMON = -Wl,--script=$(EDK_TOOLS_PATH)/Scripts/GccBase.lds -DEFINE CLANGDWARF_IA32_X64_ASLDLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0 DEF(CLANGDWARF_DLINK2_FLAGS_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable -DEFINE CLANGDWARF_IA32_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive -Wl,-z,notext -DEFINE CLANGDWARF_IA32_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x220 DEF(CLANGDWARF_DLINK2_FLAGS_COMMON) -DEFINE CLANGDWARF_X64_DLINK2_FLAGS = -Wl,--defsym=PECOFF_HEADER_SIZE=0x228 DEF(CLANGDWARF_DLINK2_FLAGS_COMMON) +DEFINE CLANGDWARF_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-q,--gc-sections DEF(GCC_ALIGN) -Wl,-z,notext,--defsym=ALIGNED_PE_HEADER_SIZE=0x400 DEF(DLINK_SCRIPT) +DEFINE CLANGDWARF_IA32_X64_ASLDLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable +DEFINE CLANGDWARF_IA32_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive +DEFINE CLANGDWARF_IA32_DLINK2_FLAGS = -no-pie DEFINE CLANGDWARF_IA32_TARGET = -target i686-pc-linux-gnu DEFINE CLANGDWARF_X64_TARGET = -target x86_64-pc-linux-gnu @@ -2046,6 +2028,7 @@ DEFINE CLANGDWARF_ALL_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(CLANGDWARF_ ########################### # CLANGDWARF IA32 definitions ########################### +*_CLANGDWARF_IA32_OBJCOPY_PATH = DEF(CLANGDWARF_IA32_PREFIX)llvm-objcopy *_CLANGDWARF_IA32_CC_PATH = DEF(CLANGDWARF_IA32_PREFIX)clang *_CLANGDWARF_IA32_SLINK_PATH = DEF(CLANGDWARF_IA32_PREFIX)llvm-ar *_CLANGDWARF_IA32_DLINK_PATH = DEF(CLANGDWARF_IA32_PREFIX)clang @@ -2060,28 +2043,27 @@ DEFINE CLANGDWARF_ALL_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(CLANGDWARF_ *_CLANGDWARF_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32 -fno-lto DEF(CLANGDWARF_IA32_TARGET) *_CLANGDWARF_IA32_ASLDLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -fuse-ld=lld -no-pie *_CLANGDWARF_IA32_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m32 -march=i386 DEF(CLANGDWARF_IA32_TARGET) -*_CLANGDWARF_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS) -*_CLANGDWARF_IA32_OBJCOPY_FLAGS = -*_CLANGDWARF_IA32_NASM_FLAGS = -f elf32 +*_CLANGDWARF_IA32_NASM_FLAGS = -f elf32 -DRODATA_SECTION_NAME=.rodata *_CLANGDWARF_IA32_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGDWARF_IA32_TARGET) *_CLANGDWARF_IA32_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGDWARF_IA32_TARGET) *_CLANGDWARF_IA32_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_IA32_TARGET) -DEBUG_CLANGDWARF_IA32_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -fno-pic -fno-pie -m32 -Oz -flto -march=i586 DEF(CLANGDWARF_IA32_TARGET) -g -malign-double +DEBUG_CLANGDWARF_IA32_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m32 -malign-double -Oz -flto -march=i586 DEF(CLANGDWARF_IA32_TARGET) -g -fno-pic -fno-pie DEBUG_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-O3 -Wl,-melf_i386 -Wl,--oformat,elf32-i386 DEBUG_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O3 -fuse-ld=lld -no-pie -RELEASE_CLANGDWARF_IA32_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -fno-pic -fno-pie -m32 -Oz -flto -march=i586 DEF(CLANGDWARF_IA32_TARGET) -malign-double +RELEASE_CLANGDWARF_IA32_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m32 -malign-double -Oz -flto -march=i586 DEF(CLANGDWARF_IA32_TARGET) -fno-pic -fno-pie RELEASE_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-O3 -Wl,-melf_i386 -Wl,--oformat,elf32-i386 RELEASE_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O3 -fuse-ld=lld -no-pie -NOOPT_CLANGDWARF_IA32_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -fno-pic -fno-pie -m32 -O0 -march=i586 DEF(CLANGDWARF_IA32_TARGET) -g -malign-double +NOOPT_CLANGDWARF_IA32_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m32 -malign-double -O0 -march=i586 DEF(CLANGDWARF_IA32_TARGET) -g -fno-pic -fno-pie NOOPT_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-O0 -Wl,-melf_i386 -Wl,--oformat,elf32-i386 NOOPT_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O0 -fuse-ld=lld -no-pie ########################## # CLANGDWARF X64 definitions ########################## +*_CLANGDWARF_X64_OBJCOPY_PATH = DEF(CLANGDWARF_X64_PREFIX)llvm-objcopy *_CLANGDWARF_X64_CC_PATH = DEF(CLANGDWARF_X64_PREFIX)clang *_CLANGDWARF_X64_SLINK_PATH = DEF(CLANGDWARF_X64_PREFIX)llvm-ar *_CLANGDWARF_X64_DLINK_PATH = DEF(CLANGDWARF_X64_PREFIX)clang @@ -2096,31 +2078,29 @@ NOOPT_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O0 - *_CLANGDWARF_X64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m64 -fno-lto DEF(CLANGDWARF_X64_TARGET) *_CLANGDWARF_X64_ASLDLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 -fuse-ld=lld *_CLANGDWARF_X64_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m64 DEF(CLANGDWARF_X64_TARGET) -*_CLANGDWARF_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) -*_CLANGDWARF_X64_OBJCOPY_FLAGS = -*_CLANGDWARF_X64_NASM_FLAGS = -f elf64 +*_CLANGDWARF_X64_NASM_FLAGS = -f elf64 -DRODATA_SECTION_NAME=.rodata *_CLANGDWARF_X64_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGDWARF_X64_TARGET) *_CLANGDWARF_X64_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGDWARF_X64_TARGET) *_CLANGDWARF_X64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_X64_TARGET) DEBUG_CLANGDWARF_X64_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -fpie -fdirect-access-external-data -Oz -flto DEF(CLANGDWARF_X64_TARGET) -g DEBUG_CLANGDWARF_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-O3 -Wl,-melf_x86_64 -Wl,--oformat,elf64-x86-64 -Wl,-pie -mcmodel=small -Wl,--apply-dynamic-relocs -DEBUG_CLANGDWARF_X64_DLINK2_FLAGS = DEF(CLANGDWARF_X64_DLINK2_FLAGS) -O3 -fuse-ld=lld +DEBUG_CLANGDWARF_X64_DLINK2_FLAGS = -O3 -fuse-ld=lld RELEASE_CLANGDWARF_X64_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -fpie -fdirect-access-external-data -Oz -flto DEF(CLANGDWARF_X64_TARGET) RELEASE_CLANGDWARF_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-O3 -Wl,-melf_x86_64 -Wl,--oformat,elf64-x86-64 -Wl,-pie -mcmodel=small -Wl,--apply-dynamic-relocs -RELEASE_CLANGDWARF_X64_DLINK2_FLAGS = DEF(CLANGDWARF_X64_DLINK2_FLAGS) -O3 -fuse-ld=lld +RELEASE_CLANGDWARF_X64_DLINK2_FLAGS = -O3 -fuse-ld=lld NOOPT_CLANGDWARF_X64_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -fpie -fdirect-access-external-data -O0 DEF(CLANGDWARF_X64_TARGET) -g NOOPT_CLANGDWARF_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-O0 -Wl,-melf_x86_64 -Wl,--oformat,elf64-x86-64 -Wl,-pie -mcmodel=small -Wl,--apply-dynamic-relocs -NOOPT_CLANGDWARF_X64_DLINK2_FLAGS = DEF(CLANGDWARF_X64_DLINK2_FLAGS) -O0 -fuse-ld=lld +NOOPT_CLANGDWARF_X64_DLINK2_FLAGS = -O0 -fuse-ld=lld ################## # CLANGDWARF ARM definitions ################## DEFINE CLANGDWARF_ARM_TARGET = -target arm-linux-gnueabi DEFINE CLANGDWARF_ARM_CC_FLAGS = DEF(GCC_ARM_CC_FLAGS) DEF(CLANGDWARF_ARM_TARGET) DEF(CLANGDWARF_WARNING_OVERRIDES) -mno-movt -fno-stack-protector -DEFINE CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_DLINK_FLAGS) +DEFINE CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_DLINK_FLAGS) -fuse-ld=lld -Wl,--apply-dynamic-relocs,--no-pie,--no-relax *_CLANGDWARF_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS) *_CLANGDWARF_ARM_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) @@ -2129,42 +2109,40 @@ DEFINE CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_DLI *_CLANGDWARF_ARM_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS) *_CLANGDWARF_ARM_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_CLANGDWARF_ARM_CC_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_ARM_ASM_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_ARM_PP_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_ARM_VFRPP_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_ARM_ASLCC_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_ARM_ASLPP_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_ARM_DLINK_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_ARM_ASLDLINK_PATH = ENV(CLANGDWARF_BIN)clang - -*_CLANGDWARF_ARM_SLINK_PATH = ENV(CLANGDWARF_BIN)llvm-ar -*_CLANGDWARF_ARM_RC_PATH = ENV(CLANGDWARF_BIN)llvm-objcopy +*_CLANGDWARF_ARM_OBJCOPY_PATH = DEF(CLANGDWARF_ARM_PREFIX)llvm-objcopy +*_CLANGDWARF_ARM_CC_PATH = DEF(CLANGDWARF_ARM_PREFIX)clang +*_CLANGDWARF_ARM_ASM_PATH = DEF(CLANGDWARF_ARM_PREFIX)clang +*_CLANGDWARF_ARM_PP_PATH = DEF(CLANGDWARF_ARM_PREFIX)clang +*_CLANGDWARF_ARM_VFRPP_PATH = DEF(CLANGDWARF_ARM_PREFIX)clang +*_CLANGDWARF_ARM_ASLCC_PATH = DEF(CLANGDWARF_ARM_PREFIX)clang +*_CLANGDWARF_ARM_ASLPP_PATH = DEF(CLANGDWARF_ARM_PREFIX)clang +*_CLANGDWARF_ARM_DLINK_PATH = DEF(CLANGDWARF_ARM_PREFIX)clang +*_CLANGDWARF_ARM_ASLDLINK_PATH = DEF(CLANGDWARF_ARM_PREFIX)clang +*_CLANGDWARF_ARM_SLINK_PATH = DEF(CLANGDWARF_ARM_PREFIX)llvm-ar +*_CLANGDWARF_ARM_RC_PATH = DEF(CLANGDWARF_ARM_PREFIX)llvm-objcopy *_CLANGDWARF_ARM_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -fno-lto -*_CLANGDWARF_ARM_ASLDLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_ASLDLINK_FLAGS) -*_CLANGDWARF_ARM_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_ARM_TARGET) $(PLATFORM_FLAGS) -Qunused-arguments -*_CLANGDWARF_ARM_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0x220 -*_CLANGDWARF_ARM_PLATFORM_FLAGS = -march=armv7-a -*_CLANGDWARF_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGDWARF_ARM_TARGET) $(PLATFORM_FLAGS) -*_CLANGDWARF_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS) -*_CLANGDWARF_ARM_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_ARM_TARGET) $(PLATFORM_FLAGS) +*_CLANGDWARF_ARM_ASLDLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_ASLDLINK_FLAGS) -fuse-ld=lld +*_CLANGDWARF_ARM_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_ARM_TARGET) -march=armv7-a -Qunused-arguments +*_CLANGDWARF_ARM_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) +*_CLANGDWARF_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGDWARF_ARM_TARGET) -march=armv7-a +*_CLANGDWARF_ARM_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_ARM_TARGET) -march=armv7-a *_CLANGDWARF_ARM_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGDWARF_ARM_TARGET) *_CLANGDWARF_ARM_CC_XIPFLAGS = DEF(GCC_ARM_CC_XIPFLAGS) - DEBUG_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O1 - DEBUG_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm -Wl,--no-pie,--no-relax - NOOPT_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) $(PLATFORM_FLAGS) -O0 - NOOPT_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -fuse-ld=lld -Wl,--no-pie,--no-relax -RELEASE_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) $(PLATFORM_FLAGS) -flto -Oz -RELEASE_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm -Wl,--no-pie,--no-relax + DEBUG_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) -flto -O1 + DEBUG_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O1 -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm + NOOPT_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) -O0 + NOOPT_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) +RELEASE_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) -flto -Oz +RELEASE_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O3 -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm ################## # CLANGDWARF AARCH64 definitions ################## DEFINE CLANGDWARF_AARCH64_TARGET = -target aarch64-linux-gnu DEFINE CLANGDWARF_AARCH64_CC_FLAGS = DEF(GCC_AARCH64_CC_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) -mcmodel=small DEF(CLANGDWARF_WARNING_OVERRIDES) -DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_DLINK_FLAGS) -z common-page-size=0x1000 +DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_DLINK_FLAGS) DEF(GCC_ALIGN) -fuse-ld=lld -Wl,--apply-dynamic-relocs,--no-pie,--no-relax *_CLANGDWARF_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) *_CLANGDWARF_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) @@ -2173,37 +2151,35 @@ DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_ *_CLANGDWARF_AARCH64_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS) *_CLANGDWARF_AARCH64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_CLANGDWARF_AARCH64_CC_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_AARCH64_ASM_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_AARCH64_PP_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_AARCH64_VFRPP_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_AARCH64_ASLCC_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_AARCH64_ASLPP_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_AARCH64_DLINK_PATH = ENV(CLANGDWARF_BIN)clang -*_CLANGDWARF_AARCH64_ASLDLINK_PATH = ENV(CLANGDWARF_BIN)clang - -*_CLANGDWARF_AARCH64_SLINK_PATH = ENV(CLANGDWARF_BIN)llvm-ar -*_CLANGDWARF_AARCH64_RC_PATH = ENV(CLANGDWARF_BIN)llvm-objcopy +*_CLANGDWARF_AARCH64_OBJCOPY_PATH = DEF(CLANGDWARF_AARCH64_PREFIX)llvm-objcopy +*_CLANGDWARF_AARCH64_CC_PATH = DEF(CLANGDWARF_AARCH64_PREFIX)clang +*_CLANGDWARF_AARCH64_ASM_PATH = DEF(CLANGDWARF_AARCH64_PREFIX)clang +*_CLANGDWARF_AARCH64_PP_PATH = DEF(CLANGDWARF_AARCH64_PREFIX)clang +*_CLANGDWARF_AARCH64_VFRPP_PATH = DEF(CLANGDWARF_AARCH64_PREFIX)clang +*_CLANGDWARF_AARCH64_ASLCC_PATH = DEF(CLANGDWARF_AARCH64_PREFIX)clang +*_CLANGDWARF_AARCH64_ASLPP_PATH = DEF(CLANGDWARF_AARCH64_PREFIX)clang +*_CLANGDWARF_AARCH64_DLINK_PATH = DEF(CLANGDWARF_AARCH64_PREFIX)clang +*_CLANGDWARF_AARCH64_ASLDLINK_PATH = DEF(CLANGDWARF_AARCH64_PREFIX)clang +*_CLANGDWARF_AARCH64_SLINK_PATH = DEF(CLANGDWARF_AARCH64_PREFIX)llvm-ar +*_CLANGDWARF_AARCH64_RC_PATH = DEF(CLANGDWARF_AARCH64_PREFIX)llvm-objcopy *_CLANGDWARF_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -fno-lto -*_CLANGDWARF_AARCH64_ASLDLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_ASLDLINK_FLAGS) -*_CLANGDWARF_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) $(PLATFORM_FLAGS) -Qunused-arguments -*_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_DLINK_FLAGS) -z common-page-size=0x1000 -*_CLANGDWARF_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 -*_CLANGDWARF_AARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0x228 -*_CLANGDWARF_AARCH64_PLATFORM_FLAGS = -*_CLANGDWARF_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) $(PLATFORM_FLAGS) -*_CLANGDWARF_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS) DEF(GCC_AARCH64_RC_BTI_FLAGS) -*_CLANGDWARF_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) $(PLATFORM_FLAGS) +*_CLANGDWARF_AARCH64_ASLDLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_ASLDLINK_FLAGS) -fuse-ld=lld +*_CLANGDWARF_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) -Qunused-arguments +*_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_DLINK_FLAGS) DEF(GCC_ALIGN) +*_CLANGDWARF_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) +*_CLANGDWARF_AARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) +*_CLANGDWARF_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) +*_CLANGDWARF_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) *_CLANGDWARF_AARCH64_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) *_CLANGDWARF_AARCH64_CC_XIPFLAGS = -mstrict-align - DEBUG_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O1 - DEBUG_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wl,--no-pie,--no-relax - NOOPT_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) $(PLATFORM_FLAGS) -O0 - NOOPT_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -fuse-ld=lld -Wl,--no-pie,--no-relax -RELEASE_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -Oz -RELEASE_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O3 -fuse-ld=lld -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wl,--no-pie,--no-relax + DEBUG_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) -flto -O1 + DEBUG_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O1 -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 + NOOPT_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) -O0 + NOOPT_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) +RELEASE_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) -flto -Oz +RELEASE_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O3 -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 ################## # CLANGDWARF RISCV64 definitions @@ -2280,14 +2256,28 @@ RELEASE_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_DLINK_FLAGS) -fl *_XCODE5_*_ASLPP_PATH = clang *_XCODE5_*_ASLDLINK_PATH = ld *_XCODE5_*_DSYMUTIL_PATH = /usr/bin/dsymutil -*_XCODE5_*_MTOC_PATH = /usr/local/bin/mtoc +*_XCODE5_*_MTOC_PATH = ENV(MTOC_PREFIX)mtoc *_XCODE5_*_DEPS_FLAGS = DEF(GCC_DEPS_FLAGS) +# +# x86_64 Preload Mach-O files index relocations relative to the first writable +# section, usually in __DATA. Merging __DATA,__const, which may have relocations +# targeting it, into __TEXT moves it in front of __DATA, yielding negative +# offsets to the relocation base address. These cannot be represented by the +# Mach-O relocation offsets, resulting in a broken binary. +# To work around this, introduce a new 0-sized segment __RO_RELOCS segment with +# RW permissions, which will make all relocations relative to the beginning of +# image. This also makes the usage of "-read_only_relocs suppress" safe, as +# relocations can now target __TEXT without triggering the same issue. +# +DEFINE XCODE5_RORELOCS_ARGS = -segprot __RO_RELOCS rw- rw- -segment_order __RO_RELOCS:__TEXT:__DATA_CONST:__DATA -rename_section __TEXT __text __RO_RELOCS __text -rename_section __RO_RELOCS __text __TEXT __text +DEFINE XCODE5_RODATA_ARGS = DEF(XCODE5_RORELOCS_ARGS) -segprot __DATA_CONST r-- r-- -rename_section __DATA __const __DATA_CONST __const -rename_section __TEXT __const __DATA_CONST __text_const -rename_section __TEXT __cstring __DATA_CONST __cstring -rename_section __TEXT __ustring __DATA_CONST __ustring + ################## # ASL definitions ################## *_XCODE5_*_ASLCC_FLAGS = -x c -save-temps -g -O0 -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-missing-braces -c -include AutoGen.h -*_XCODE5_*_ASLDLINK_FLAGS = -e _ReferenceAcpiTable -preload -segalign 0x20 -pie -seg1addr 0x240 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map +*_XCODE5_*_ASLDLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -e _ReferenceAcpiTable -preload -segalign DEF(XCODE_ALIGN) -pie -seg1addr DEF(XCODE_ADDR) -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map *_XCODE5_*_ASLPP_FLAGS = -x c -E -include AutoGen.h *_XCODE5_*_ASL_FLAGS = *_XCODE5_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS) @@ -2296,46 +2286,46 @@ RELEASE_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_DLINK_FLAGS) -fl # MTOC definitions ################## - DEBUG_XCODE5_*_MTOC_FLAGS = -align 0x20 -d $(DEBUG_DIR)/$(MODULE_NAME).dll - NOOPT_XCODE5_*_MTOC_FLAGS = -align 0x20 -d $(DEBUG_DIR)/$(MODULE_NAME).dll -RELEASE_XCODE5_*_MTOC_FLAGS = -align 0x20 + DEBUG_XCODE5_*_MTOC_FLAGS = -align DEF(XCODE_ALIGN) -d $(DEBUG_DIR)/$(MODULE_NAME).dll -require_read_only_relocs + NOOPT_XCODE5_*_MTOC_FLAGS = -align DEF(XCODE_ALIGN) -d $(DEBUG_DIR)/$(MODULE_NAME).dll -require_read_only_relocs +RELEASE_XCODE5_*_MTOC_FLAGS = -align DEF(XCODE_ALIGN) -require_read_only_relocs #################### # IA-32 definitions #################### - DEBUG_XCODE5_IA32_DLINK_FLAGS = -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x240 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map - NOOPT_XCODE5_IA32_DLINK_FLAGS = -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x240 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map -RELEASE_XCODE5_IA32_DLINK_FLAGS = -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x240 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map + DEBUG_XCODE5_IA32_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_MERGE) + NOOPT_XCODE5_IA32_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_MERGE) +RELEASE_XCODE5_IA32_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_MERGE) *_XCODE5_IA32_SLINK_FLAGS = -static -o DEBUG_XCODE5_IA32_ASM_FLAGS = -arch i386 -g NOOPT_XCODE5_IA32_ASM_FLAGS = -arch i386 -g RELEASE_XCODE5_IA32_ASM_FLAGS = -arch i386 - *_XCODE5_IA32_NASM_FLAGS = -f macho32 + *_XCODE5_IA32_NASM_FLAGS = -f macho32 -DRODATA_SECTION_NAME=.rodata - DEBUG_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang $(PLATFORM_FLAGS) -RELEASE_XCODE5_IA32_CC_FLAGS = -arch i386 -c -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unused-const-variable -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang $(PLATFORM_FLAGS) - NOOPT_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -O0 -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang $(PLATFORM_FLAGS) + DEBUG_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang +RELEASE_XCODE5_IA32_CC_FLAGS = -arch i386 -c -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -Wno-unused-const-variable -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang + NOOPT_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -O0 -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang ################## # X64 definitions ################## - DEBUG_XCODE5_X64_DLINK_FLAGS = -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x240 -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map - NOOPT_XCODE5_X64_DLINK_FLAGS = -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x240 -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map -RELEASE_XCODE5_X64_DLINK_FLAGS = -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign 0x20 -pie -all_load -dead_strip -seg1addr 0x240 -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map + DEBUG_XCODE5_X64_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_MERGE) + NOOPT_XCODE5_X64_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_MERGE) +RELEASE_XCODE5_X64_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_MERGE) *_XCODE5_X64_SLINK_FLAGS = -static -o DEBUG_XCODE5_X64_ASM_FLAGS = -arch x86_64 -g NOOPT_XCODE5_X64_ASM_FLAGS = -arch x86_64 -g RELEASE_XCODE5_X64_ASM_FLAGS = -arch x86_64 - *_XCODE5_X64_NASM_FLAGS = -f macho64 -*_XCODE5_*_PP_FLAGS = -E -x assembler-with-cpp -include AutoGen.h -*_XCODE5_*_VFRPP_FLAGS = -x c -E -P -DVFRCOMPILE -include $(MODULE_NAME)StrDefs.h + *_XCODE5_X64_NASM_FLAGS = -f macho64 -DRODATA_SECTION_NAME=.rodata +*_XCODE5_*_PP_FLAGS = -E -x assembler-with-cpp -include AutoGen.h +*_XCODE5_*_VFRPP_FLAGS = -x c -E -P -DVFRCOMPILE -include $(MODULE_NAME)StrDefs.h - DEBUG_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -gdwarf -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS $(PLATFORM_FLAGS) - NOOPT_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -gdwarf -O0 -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS $(PLATFORM_FLAGS) -RELEASE_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unused-const-variable -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS $(PLATFORM_FLAGS) + DEBUG_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -gdwarf -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS + NOOPT_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -gdwarf -O0 -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS +RELEASE_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unused-const-variable -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS ################# # ASM 16 linker definitions @@ -2355,12 +2345,6 @@ RELEASE_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -Os -W *_*_*_OPTROM_PATH = EfiRom *_*_*_OPTROM_FLAGS = -e -################## -# GenFw tool definitions -################## -*_*_*_GENFW_PATH = GenFw -*_*_*_GENFW_FLAGS = - ################## # Asl Compiler definitions ################## diff --git a/BaseTools/GNUmakefile b/BaseTools/GNUmakefile index d29f6d9c9b..fdaa7fa9ec 100644 --- a/BaseTools/GNUmakefile +++ b/BaseTools/GNUmakefile @@ -10,7 +10,7 @@ all: subdirs LANGUAGES = C Python SOURCE_SUBDIRS := $(patsubst %,Source/%,$(sort $(LANGUAGES))) -SUBDIRS := $(SOURCE_SUBDIRS) Tests +SUBDIRS := $(SOURCE_SUBDIRS) Tests ImageTool MicroTool CLEAN_SUBDIRS := $(patsubst %,%-clean,$(sort $(SUBDIRS))) .PHONY: subdirs $(SUBDIRS) diff --git a/BaseTools/ImageTool/BinEmit.c b/BaseTools/ImageTool/BinEmit.c new file mode 100644 index 0000000000..51fbb6f5a7 --- /dev/null +++ b/BaseTools/ImageTool/BinEmit.c @@ -0,0 +1,200 @@ +/** @file + Copyright (c) 2022, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include "ImageTool.h" + +static +EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY * +CreateEntry ( + IN UINT8 *HiiSectionHeader, + IN OUT UINT32 *HiiSectionOffset, + IN BOOLEAN DataIsDirectory + ) +{ + EFI_IMAGE_RESOURCE_DIRECTORY *RDir; + EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *Entry; + + assert (HiiSectionHeader != NULL); + assert (HiiSectionOffset != NULL); + + RDir = (EFI_IMAGE_RESOURCE_DIRECTORY *)(HiiSectionHeader + *HiiSectionOffset); + *HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY); + RDir->NumberOfNamedEntries = 1; + + Entry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *)(HiiSectionHeader + *HiiSectionOffset); + *HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY); + Entry->u1.s.NameIsString = 1; + + if (DataIsDirectory) { + Entry->u2.s.DataIsDirectory = 1; + Entry->u2.s.OffsetToDirectory = *HiiSectionOffset; + } + + return Entry; +} + +static +void +CreateStringEntry ( + IN OUT EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *Entry, + IN UINT8 *HiiSectionHeader, + IN OUT UINT32 *HiiSectionOffset, + IN CHAR16 *String + ) +{ + EFI_IMAGE_RESOURCE_DIRECTORY_STRING *RDStr; + + assert (Entry != NULL); + assert (HiiSectionHeader != NULL); + assert (HiiSectionOffset != NULL); + assert (String != NULL); + + Entry->u1.s.NameOffset = *HiiSectionOffset; + RDStr = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *)(HiiSectionHeader + *HiiSectionOffset); + RDStr->Length = (UINT16)StrLen (String); + memcpy (RDStr->String, String, RDStr->Length * sizeof (RDStr->String[0])); + *HiiSectionOffset += sizeof (*RDStr) + RDStr->Length * sizeof (RDStr->String[0]); +} + +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 mHiiResourceSectionHeaderSize = + 3 * (sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) + + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_STRING) + 3 * sizeof (CHAR16)) + sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY); + +VOID +InitializeHiiResouceSectionHeader ( + OUT UINT8 *HiiSectionHeader, + IN UINT32 HiiDataAddress, + IN UINT32 HiiDataSize + ) +{ + UINT32 HiiSectionOffset; + EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *TypeRDirEntry; + EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *NameRDirEntry; + EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *LangRDirEntry; + EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry; + + assert (HiiSectionHeader != NULL); + + HiiSectionOffset = 0; + // + // Create Type, Name, Language entries + // + TypeRDirEntry = CreateEntry (HiiSectionHeader, &HiiSectionOffset, TRUE); + NameRDirEntry = CreateEntry (HiiSectionHeader, &HiiSectionOffset, TRUE); + LangRDirEntry = CreateEntry (HiiSectionHeader, &HiiSectionOffset, FALSE); + // + // Create string entry for Type, Name, Language + // + CreateStringEntry (TypeRDirEntry, HiiSectionHeader, &HiiSectionOffset, L"HII"); + CreateStringEntry (NameRDirEntry, HiiSectionHeader, &HiiSectionOffset, L"EFI"); + CreateStringEntry (LangRDirEntry, HiiSectionHeader, &HiiSectionOffset, L"BIN"); + // + // Create Leaf data + // + LangRDirEntry->u2.OffsetToData = HiiSectionOffset; + ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *)(HiiSectionHeader + HiiSectionOffset); + HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY); + ResourceDataEntry->OffsetToData = HiiDataAddress + HiiSectionOffset; + ResourceDataEntry->Size = HiiDataSize; +} + +RETURN_STATUS +ConstructHii ( + IN const char *FileNames[], + IN UINT32 NumOfFiles, + IN GUID *HiiGuid, + OUT void **Hii, + OUT UINT32 *HiiSize + ) +{ + UINT8 *HiiPackageData; + UINT8 *HiiPackageDataPointer; + EFI_HII_PACKAGE_LIST_HEADER HiiPackageListHeader; + EFI_HII_PACKAGE_HEADER *HiiPackageHeader; + EFI_IFR_FORM_SET *IfrFormSet; + EFI_HII_PACKAGE_HEADER EndPackage; + UINT32 Index; + void *File; + UINT32 FileSize; + UINT8 NumberOfFormPackages; + + assert (Hii != NULL); + assert (HiiGuid != NULL); + assert (FileNames != NULL); + + NumberOfFormPackages = 0; + + EndPackage.Length = sizeof (EFI_HII_PACKAGE_HEADER); + EndPackage.Type = EFI_HII_PACKAGE_END; + + HiiPackageListHeader.PackageLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER) + sizeof (EndPackage); + + for (Index = 0; Index < NumOfFiles; ++Index) { + File = UserReadFile (FileNames[Index], &FileSize); + if (File == NULL) { + fprintf (stderr, "ImageTool: Could not open %s: %s\n", FileNames[Index], strerror (errno)); + return RETURN_ABORTED; + } + + HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)File; + if (HiiPackageHeader->Type == EFI_HII_PACKAGE_FORMS) { + if (HiiPackageHeader->Length != FileSize) { + fprintf (stderr, "ImageTool: Wrong package size in HII package file %s\n", FileNames[Index]); + free (File); + return RETURN_ABORTED; + } + + if (IsZeroGuid (HiiGuid)) { + IfrFormSet = (EFI_IFR_FORM_SET *)(HiiPackageHeader + 1); + CopyGuid (HiiGuid, &IfrFormSet->Guid); + } + + ++NumberOfFormPackages; + } + + HiiPackageListHeader.PackageLength += FileSize; + free (File); + } + + if (NumberOfFormPackages > 1) { + fprintf (stderr, "ImageTool: The input HII packages contain more than one HII Form package\n"); + return RETURN_INVALID_PARAMETER; + } + + if (IsZeroGuid (HiiGuid)) { + fprintf (stderr, "ImageTool: HII package list guid is not specified\n"); + return RETURN_ABORTED; + } + + CopyGuid (&HiiPackageListHeader.PackageListGuid, HiiGuid); + + HiiPackageData = calloc (1, HiiPackageListHeader.PackageLength); + if (HiiPackageData == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + + memmove (HiiPackageData, &HiiPackageListHeader, sizeof (HiiPackageListHeader)); + + HiiPackageDataPointer = HiiPackageData + sizeof (HiiPackageListHeader); + for (Index = 0; Index < NumOfFiles; ++Index) { + File = UserReadFile (FileNames[Index], &FileSize); + if (File == NULL) { + fprintf (stderr, "ImageTool: Could not open %s: %s\n", FileNames[Index], strerror (errno)); + return RETURN_ABORTED; + } + + memmove (HiiPackageDataPointer, File, FileSize); + HiiPackageDataPointer += FileSize; + + free (File); + } + + memmove (HiiPackageDataPointer, &EndPackage, sizeof (EndPackage)); + + *Hii = HiiPackageData; + *HiiSize = HiiPackageListHeader.PackageLength; + + return RETURN_SUCCESS; +} diff --git a/BaseTools/ImageTool/ElfScan.c b/BaseTools/ImageTool/ElfScan.c new file mode 100644 index 0000000000..ca2a1010b2 --- /dev/null +++ b/BaseTools/ImageTool/ElfScan.c @@ -0,0 +1,731 @@ +/** @file + Copyright (c) 2022, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include "ImageTool.h" + +#include "ElfScanCommon.h" + +#include "../../UefiPayloadPkg/PayloadLoaderPeim/ElfLib/ElfCommon.h" + +#if ELF_ARCH == 32 + +#include "../../UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf32.h" + +#define ELFCLASS ELFCLASS32 +#define Elf_Ehdr Elf32_Ehdr +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Rel Elf32_Rel +#define Elf_Rela Elf32_Rela +#define Elf_Size Elf32_Size +#define Elf_Addr Elf32_Addr +#define ELF_R_TYPE ELF32_R_TYPE +#define ELF_R_SYM ELF32_R_SYM + +#elif ELF_ARCH == 64 + +#include "../../UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf64.h" + +#define ELFCLASS ELFCLASS64 +#define Elf_Ehdr Elf64_Ehdr +#define Elf_Shdr Elf64_Shdr +#define Elf_Sym Elf64_Sym +#define Elf_Rel Elf64_Rel +#define Elf_Rela Elf64_Rela +#define Elf_Size Elf64_Size +#define Elf_Addr Elf64_Addr +#define ELF_R_TYPE ELF64_R_TYPE +#define ELF_R_SYM ELF64_R_SYM + +#endif + +#define ELF_SUFFIX__(Name, Arch) Name##Arch +#define ELF_SUFFIX_(Name, Arch) ELF_SUFFIX__ (Name, Arch) +#define ELF_SUFFIX(Name) ELF_SUFFIX_ (Name, ELF_ARCH) + +typedef struct { + const Elf_Ehdr *Ehdr; + uint32_t Alignment; + Elf_Addr BaseAddress; + bool HasPieRelocs; +} tool_elf_scan_context; + +#if defined (_MSC_EXTENSIONS) +#define EFI_IMAGE_MACHINE_IA32 0x014C +#define EFI_IMAGE_MACHINE_X64 0x8664 +#define EFI_IMAGE_MACHINE_ARMTHUMB_MIXED 0x01C2 +#define EFI_IMAGE_MACHINE_AARCH64 0xAA64 +#endif + + +#define GetShrbyIndex ELF_SUFFIX(GetShrbyIndex) +static +Elf_Shdr * +GetShdrByIndex ( + IN const Elf_Ehdr *Ehdr, + IN UINT32 Index + ) +{ + UINTN Offset; + + assert (Index < Ehdr->e_shnum); + + Offset = (UINTN)Ehdr->e_shoff + Index * Ehdr->e_shentsize; + + return (Elf_Shdr *)((UINT8 *)Ehdr + Offset); +} + +#define GetString ELF_SUFFIX(GetString) +static +const char * +GetString ( + IN const Elf_Ehdr *Ehdr, + IN UINT32 Offset, + IN UINT32 Index + ) +{ + const Elf_Shdr *Shdr; + + if (Index == 0) { + Shdr = GetShdrByIndex (Ehdr, Ehdr->e_shstrndx); + } else { + Shdr = GetShdrByIndex (Ehdr, Index); + } + + if (Offset >= Shdr->sh_size) { + fprintf (stderr, "ImageTool: Invalid ELF string offset\n"); + return NULL; + } + + return (const char *)Ehdr + Shdr->sh_offset + Offset; +} + +#define IsShdrLoadable ELF_SUFFIX(IsShdrLoadable) +static +BOOLEAN +IsShdrLoadable ( + IN const Elf_Ehdr *Ehdr, + IN const Elf_Shdr *Shdr + ) +{ + assert (Shdr != NULL); + + return (Shdr->sh_flags & SHF_ALLOC) != 0; +} + +#define ParseElfFile ELF_SUFFIX(ParseElfFile) +static +RETURN_STATUS +ParseElfFile ( + OUT tool_elf_scan_context *Context, + IN const void *File, + IN uint32_t FileSize + ) +{ + static const unsigned char Ident[] = { + ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ELFCLASS, ELFDATA2LSB + }; + const Elf_Ehdr *Ehdr; + bool AlignmentSet; + Elf_Size Alignment; + bool BaseAddressSet; + Elf_Addr BaseAddress; + bool HasPieRelocs; + const Elf_Shdr *Shdr; + UINTN Offset; + UINT32 Index; + char *Last; + + assert (File != NULL || FileSize == 0); + + Ehdr = (const Elf_Ehdr *)File; + + // + // Check header + // + if ((FileSize < sizeof (*Ehdr)) + || (memcmp (Ident, Ehdr->e_ident, sizeof (Ident)) != 0)) { + return RETURN_UNSUPPORTED; + } + + if ((Ehdr->e_type != ET_EXEC) && (Ehdr->e_type != ET_DYN)) { + fprintf (stderr, "ImageTool: ELF e_type not ET_EXEC or ET_DYN\n"); + return RETURN_INCOMPATIBLE_VERSION; + } + + // + // Check section headers + // + BaseAddressSet = false; + BaseAddress = 0; + Alignment = 0; + AlignmentSet = false; + HasPieRelocs = false; + for (Index = 0; Index < Ehdr->e_shnum; ++Index) { + Offset = (UINTN)Ehdr->e_shoff + Index * Ehdr->e_shentsize; + + if (FileSize < (Offset + sizeof (*Shdr))) { + fprintf (stderr, "ImageTool: ELF section header is outside file\n"); + return RETURN_VOLUME_CORRUPTED; + } + + Shdr = (const Elf_Shdr *)((const char *)Ehdr + Offset); + + if ((Shdr->sh_type != SHT_NOBITS) + && ((FileSize < Shdr->sh_offset) || ((FileSize - Shdr->sh_offset) < Shdr->sh_size))) { + fprintf (stderr, "ImageTool: ELF section %d points outside file\n", Index); + return RETURN_VOLUME_CORRUPTED; + } + + if (Shdr->sh_link >= Ehdr->e_shnum) { + fprintf (stderr, "ImageTool: ELF %d-th section's sh_link is out of range\n", Index); + return RETURN_VOLUME_CORRUPTED; + } + + if ((Shdr->sh_type == SHT_RELA) || (Shdr->sh_type == SHT_REL)) { + if (Shdr->sh_info >= Ehdr->e_shnum) { + fprintf (stderr, "ImageTool: ELF %d-th section's sh_info is out of range\n", Index); + return RETURN_VOLUME_CORRUPTED; + } + + if (Shdr->sh_info == 0) { + HasPieRelocs = TRUE; + } + } + + if (!BaseAddressSet || Shdr->sh_addr < BaseAddress) { + BaseAddressSet = TRUE; + BaseAddress = Shdr->sh_addr; + } + + if (!IsShdrLoadable (Ehdr, Shdr)) { + continue; + } + + if (!AlignmentSet || Alignment < Shdr->sh_addralign) { + AlignmentSet = TRUE; + Alignment = Shdr->sh_addralign; + } + } + + if (Ehdr->e_shstrndx >= Ehdr->e_shnum) { + fprintf (stderr, "ImageTool: Invalid section name string table\n"); + return RETURN_VOLUME_CORRUPTED; + } + Shdr = GetShdrByIndex (Ehdr, Ehdr->e_shstrndx); + + if (Shdr->sh_type != SHT_STRTAB) { + fprintf (stderr, "ImageTool: ELF string table section has wrong type\n"); + return RETURN_VOLUME_CORRUPTED; + } + + Last = (char *)((UINT8 *)Ehdr + Shdr->sh_offset + Shdr->sh_size - 1); + if (*Last != '\0') { + fprintf (stderr, "ImageTool: ELF string table section is not NUL-terminated\n"); + return RETURN_VOLUME_CORRUPTED; + } + + if (!AlignmentSet || (!IS_POW2(Alignment)) || (Alignment > MAX_PE_ALIGNMENT)) { + fprintf (stderr, "ImageTool: Invalid section alignment\n"); + return RETURN_VOLUME_CORRUPTED; + } + + if (!BaseAddressSet || !IS_ALIGNED (BaseAddress, Alignment)) { + fprintf (stderr, "ImageTool: Invalid base address %llx\n", (unsigned long long)BaseAddress); + return RETURN_VOLUME_CORRUPTED; + } + + memset (Context, 0, sizeof (*Context)); + + Context->Ehdr = Ehdr; + Context->Alignment = (uint32_t)Alignment; + Context->BaseAddress = BaseAddress; + Context->HasPieRelocs = HasPieRelocs; + + return RETURN_SUCCESS; +} + +#define ProcessRelocSection ELF_SUFFIX(ProcessRelocSection) +static +bool +ProcessRelocSection ( + const tool_elf_scan_context *Context, + const Elf_Shdr *Shdr + ) +{ + const Elf_Ehdr *Ehdr; + bool HasPieRelocs; + const Elf_Shdr *SecShdr; + + Ehdr = Context->Ehdr; + HasPieRelocs = Context->HasPieRelocs; + // + // PIE relocations will target dummy section 0. + // + if (Shdr->sh_info != 0) { + // + // If PIE relocations exist, prefer them. + // + if (HasPieRelocs) { + return FALSE; + } + // + // Only translate relocations targetting sections that are translated. + // + SecShdr = GetShdrByIndex (Ehdr, Shdr->sh_info); + + if (!IsShdrLoadable (Ehdr, SecShdr)) { + return FALSE; + } + } else { + assert (HasPieRelocs); + } + + return TRUE; +} + +#define SetRelocs ELF_SUFFIX(SetRelocs) +static +RETURN_STATUS +SetRelocs ( + OUT image_tool_image_info_t *ImageInfo, + IN const tool_elf_scan_context *Context + ) +{ + const Elf_Ehdr *Ehdr; + Elf_Addr BaseAddress; + UINT32 Index; + const Elf_Shdr *RelShdr; + UINTN RelIdx; + const Elf_Rela *Rel; + UINT32 RelNum; + + Ehdr = Context->Ehdr; + BaseAddress = Context->BaseAddress; + + RelNum = 0; + + for (Index = 0; Index < Ehdr->e_shnum; Index++) { + RelShdr = GetShdrByIndex (Ehdr, Index); + + if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) { + continue; + } + + if (!ProcessRelocSection (Context, RelShdr)) { + continue; + } + + for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += (UINTN)RelShdr->sh_entsize) { + Rel = (const Elf_Rela *)((const char *)Ehdr + RelShdr->sh_offset + RelIdx); + // + // Assume ELF virtual addresses match corresponding PE virtual adresses one to one, + // so we don't need to recalculate relocations computed by the linker at all r_offset's. + // We only need to transform ELF relocations' format into PE one. + // +#if ELF_ARCH == 64 + if (Ehdr->e_machine == EM_X86_64) { + switch (ELF_R_TYPE(Rel->r_info)) { + case R_X86_64_NONE: + break; + case R_X86_64_RELATIVE: + case R_X86_64_64: + ImageInfo->RelocInfo.Relocs[RelNum].Type = EFI_IMAGE_REL_BASED_DIR64; + ImageInfo->RelocInfo.Relocs[RelNum].Target = (uint32_t)(Rel->r_offset - BaseAddress); + ++RelNum; + + break; + case R_X86_64_32: + + ImageInfo->RelocInfo.Relocs[RelNum].Type = EFI_IMAGE_REL_BASED_HIGHLOW; + ImageInfo->RelocInfo.Relocs[RelNum].Target = (uint32_t)(Rel->r_offset - BaseAddress); + ++RelNum; + + break; + case R_X86_64_32S: + case R_X86_64_PLT32: + case R_X86_64_PC32: + break; + case R_X86_64_GOTPCREL: + case R_X86_64_GOTPCRELX: + case R_X86_64_REX_GOTPCRELX: + // + // Relocations of these types point to instructions' arguments containing + // offsets relative to RIP leading to .got entries. As sections' virtual + // addresses do not change during ELF->PE transform, we don't need to + // add them to relocations' list. But .got entries contain virtual + // addresses which must be updated. + // + // At r_offset the following value is stored: G + GOT + A - P. + // To derive .got entry address (G + GOT) compute: value - A + P. + // + // Such a method of finding relocatable .got entries can not be used, + // due to a BUG in clang compiler, which sometimes generates + // R_X86_64_REX_GOTPCRELX relocations instead of R_X86_64_PC32. + // + break; + default: + fprintf (stderr, "ImageTool: Unsupported ELF EM_X86_64 relocation 0x%llx in %s\n", ELF_R_TYPE(Rel->r_info), ImageInfo->DebugInfo.SymbolsPath); + return RETURN_INCOMPATIBLE_VERSION; + } + } else if (Ehdr->e_machine == EM_AARCH64) { + switch (ELF_R_TYPE(Rel->r_info)) { + case R_AARCH64_NONE0: + case R_AARCH64_NONE: + case R_AARCH64_LD64_GOTOFF_LO15: + case R_AARCH64_LD64_GOTPAGE_LO15: + case R_AARCH64_LD64_GOT_LO12_NC: + case R_AARCH64_ADR_GOT_PAGE: + case R_AARCH64_ADR_PREL_PG_HI21: + case R_AARCH64_ADD_ABS_LO12_NC: + case R_AARCH64_LDST8_ABS_LO12_NC: + case R_AARCH64_LDST16_ABS_LO12_NC: + case R_AARCH64_LDST32_ABS_LO12_NC: + case R_AARCH64_LDST64_ABS_LO12_NC: + case R_AARCH64_LDST128_ABS_LO12_NC: + case R_AARCH64_ADR_PREL_LO21: + case R_AARCH64_CONDBR19: + case R_AARCH64_LD_PREL_LO19: + case R_AARCH64_CALL26: + case R_AARCH64_JUMP26: + case R_AARCH64_PREL64: + case R_AARCH64_PREL32: + case R_AARCH64_PREL16: + break; + case R_AARCH64_ABS64: + case R_AARCH64_RELATIVE: + ImageInfo->RelocInfo.Relocs[RelNum].Type = EFI_IMAGE_REL_BASED_DIR64; + ImageInfo->RelocInfo.Relocs[RelNum].Target = (uint32_t)(Rel->r_offset - BaseAddress); + ++RelNum; + + break; + case R_AARCH64_ABS32: + + ImageInfo->RelocInfo.Relocs[RelNum].Type = EFI_IMAGE_REL_BASED_HIGHLOW; + ImageInfo->RelocInfo.Relocs[RelNum].Target = (uint32_t)(Rel->r_offset - BaseAddress); + ++RelNum; + + break; + default: + fprintf (stderr, "ImageTool: Unsupported ELF EM_AARCH64 relocation 0x%llx in %s\n", ELF_R_TYPE(Rel->r_info), ImageInfo->DebugInfo.SymbolsPath); + return RETURN_INCOMPATIBLE_VERSION; + } + } +#elif ELF_ARCH == 32 + if (Ehdr->e_machine == EM_386) { + switch (ELF_R_TYPE(Rel->r_info)) { + case R_386_NONE: + break; + case R_386_32: + + ImageInfo->RelocInfo.Relocs[RelNum].Type = EFI_IMAGE_REL_BASED_HIGHLOW; + ImageInfo->RelocInfo.Relocs[RelNum].Target = (Rel->r_offset - BaseAddress); + ++RelNum; + + break; + case R_386_PLT32: + case R_386_PC32: + break; + default: + fprintf (stderr, "ImageTool: Unsupported ELF EM_386 relocation 0x%x in %s\n", ELF_R_TYPE(Rel->r_info), ImageInfo->DebugInfo.SymbolsPath); + return RETURN_INCOMPATIBLE_VERSION; + } + } else if (Ehdr->e_machine == EM_ARM) { + switch (ELF32_R_TYPE(Rel->r_info)) { + case R_ARM_NONE: + case R_ARM_PC24: + case R_ARM_REL32: + case R_ARM_XPC25: + case R_ARM_THM_PC22: + case R_ARM_THM_JUMP19: + case R_ARM_CALL: + case R_ARM_JMP24: + case R_ARM_THM_JUMP24: + case R_ARM_PREL31: + case R_ARM_MOVW_PREL_NC: + case R_ARM_MOVT_PREL: + case R_ARM_THM_MOVW_PREL_NC: + case R_ARM_THM_MOVT_PREL: + case R_ARM_THM_JMP6: + case R_ARM_THM_ALU_PREL_11_0: + case R_ARM_THM_PC12: + case R_ARM_REL32_NOI: + case R_ARM_ALU_PC_G0_NC: + case R_ARM_ALU_PC_G0: + case R_ARM_ALU_PC_G1_NC: + case R_ARM_ALU_PC_G1: + case R_ARM_ALU_PC_G2: + case R_ARM_LDR_PC_G1: + case R_ARM_LDR_PC_G2: + case R_ARM_LDRS_PC_G0: + case R_ARM_LDRS_PC_G1: + case R_ARM_LDRS_PC_G2: + case R_ARM_LDC_PC_G0: + case R_ARM_LDC_PC_G1: + case R_ARM_LDC_PC_G2: + case R_ARM_THM_JUMP11: + case R_ARM_THM_JUMP8: + case R_ARM_TLS_GD32: + case R_ARM_TLS_LDM32: + case R_ARM_TLS_IE32: + break; + case R_ARM_ABS32: + + ImageInfo->RelocInfo.Relocs[RelNum].Type = EFI_IMAGE_REL_BASED_HIGHLOW; + ImageInfo->RelocInfo.Relocs[RelNum].Target = (Rel->r_offset - BaseAddress); + ++RelNum; + + break; + default: + fprintf (stderr, "ImageTool: Unsupported ELF EM_ARM relocation 0x%x in %s\n", ELF_R_TYPE(Rel->r_info), ImageInfo->DebugInfo.SymbolsPath); + return RETURN_INCOMPATIBLE_VERSION; + } + } +#endif + } + } + + ImageInfo->RelocInfo.NumRelocs = RelNum; + + return RETURN_SUCCESS; +} + +#define CreateIntermediate ELF_SUFFIX(CreateIntermediate) +static +RETURN_STATUS +CreateIntermediate ( + OUT image_tool_image_info_t *ImageInfo, + IN const tool_elf_scan_context *Context + ) +{ + const Elf_Ehdr *Ehdr; + Elf_Addr BaseAddress; + const Elf_Shdr *Shdr; + UINT32 Index; + image_tool_segment_t *Segments; + image_tool_reloc_t *Relocs; + UINT32 SIndex; + const Elf_Rel *Rel; + UINTN RIndex; + const char *Name; + UINT32 NumRelocs; + + Ehdr = Context->Ehdr; + BaseAddress = Context->BaseAddress; + + Segments = NULL; + SIndex = 0; + Relocs = NULL; + NumRelocs = 0; + + for (Index = 0; Index < Ehdr->e_shnum; ++Index) { + Shdr = GetShdrByIndex (Ehdr, Index); + + if ((Shdr->sh_type == SHT_REL) || (Shdr->sh_type == SHT_RELA)) { + if ((Shdr->sh_flags & SHF_ALLOC) != 0) { + fprintf (stderr, "ImageTool: Loadable reloc sections are unsupported\n"); + return RETURN_VOLUME_CORRUPTED; + } + + if (!ProcessRelocSection (Context, Shdr)) { + continue; + } + + for (RIndex = 0; RIndex < Shdr->sh_size; RIndex += (UINTN)Shdr->sh_entsize) { + Rel = (Elf_Rel *)((UINT8 *)Ehdr + Shdr->sh_offset + RIndex); +#if ELF_ARCH == 64 + if (Ehdr->e_machine == EM_X86_64) { + if ((ELF_R_TYPE(Rel->r_info) == R_X86_64_RELATIVE) + || (ELF_R_TYPE(Rel->r_info) == R_X86_64_64) + || (ELF_R_TYPE(Rel->r_info) == R_X86_64_32) + || (ELF_R_TYPE(Rel->r_info) == R_X86_64_GOTPCREL) + || (ELF_R_TYPE(Rel->r_info) == R_X86_64_GOTPCRELX) + || (ELF_R_TYPE(Rel->r_info) == R_X86_64_REX_GOTPCRELX)) { + ++NumRelocs; + } + } else if (Ehdr->e_machine == EM_AARCH64) { + if ((ELF_R_TYPE(Rel->r_info) == R_AARCH64_ABS64) + || (ELF_R_TYPE(Rel->r_info) == R_AARCH64_RELATIVE) + || (ELF_R_TYPE(Rel->r_info) == R_AARCH64_ABS32)) { + ++NumRelocs; + } + } +#elif ELF_ARCH == 32 + if (Ehdr->e_machine == EM_386) { + if (ELF_R_TYPE(Rel->r_info) == R_386_32) { + ++NumRelocs; + } + } else if (Ehdr->e_machine == EM_ARM) { + if (ELF_R_TYPE(Rel->r_info) == R_ARM_ABS32) { + ++NumRelocs; + } + } +#endif + } + } + + if (!IsShdrLoadable (Ehdr, Shdr)) { + continue; + } + + ++ImageInfo->SegmentInfo.NumSegments; + } + + if (ImageInfo->SegmentInfo.NumSegments == 0) { + fprintf (stderr, "ImageTool: No loadable sections\n"); + return RETURN_VOLUME_CORRUPTED; + } + + Segments = calloc (1, sizeof (*Segments) * ImageInfo->SegmentInfo.NumSegments); + if (Segments == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for Segments\n"); + return RETURN_OUT_OF_RESOURCES; + }; + + ImageInfo->SegmentInfo.Segments = Segments; + + if (NumRelocs != 0) { + Relocs = calloc (1, sizeof (*Relocs) * NumRelocs); + if (Relocs == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for Relocs\n"); + return RETURN_OUT_OF_RESOURCES; + }; + + ImageInfo->RelocInfo.Relocs = Relocs; + } + + for (Index = 0; Index < Ehdr->e_shnum; ++Index) { + Shdr = GetShdrByIndex (Ehdr, Index); + + if ((Shdr->sh_flags & SHF_ALLOC) == 0) { + continue; + } + + if (Shdr->sh_type != SHT_PROGBITS && Shdr->sh_type != SHT_NOBITS) { + fprintf (stderr, "ImageTool: Segment #%d type %x unsupported\n", Index, Shdr->sh_type); + return RETURN_VOLUME_CORRUPTED; + } + + Name = GetString (Ehdr, Shdr->sh_name, 0); + if (Name == NULL) { + return RETURN_VOLUME_CORRUPTED; + } + + Segments[SIndex].Name = calloc (1, strlen (Name) + 1); + if (Segments[SIndex].Name == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Name\n", Index); + return RETURN_OUT_OF_RESOURCES; + }; + + memcpy (Segments[SIndex].Name, Name, strlen (Name)); + + Segments[SIndex].ImageAddress = (uint32_t)(Shdr->sh_addr - BaseAddress); + Segments[SIndex].ImageSize = ALIGN_VALUE ((uint32_t)Shdr->sh_size, Context->Alignment); + Segments[SIndex].Read = true; + Segments[SIndex].Write = (Shdr->sh_flags & SHF_WRITE) != 0; + Segments[SIndex].Execute = (Shdr->sh_flags & SHF_EXECINSTR) != 0; + + Segments[SIndex].Data = calloc (1, Segments[SIndex].ImageSize); + if (Segments[SIndex].Data == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Data\n", Index); + return RETURN_OUT_OF_RESOURCES; + }; + + if (Shdr->sh_type == SHT_PROGBITS) { + memcpy (Segments[SIndex].Data, (const char *)Ehdr + Shdr->sh_offset, (size_t)Shdr->sh_size); + } + + ++SIndex; + } + + assert (SIndex == ImageInfo->SegmentInfo.NumSegments); + + return SetRelocs (ImageInfo, Context); +} + +#define ScanElf ELF_SUFFIX(ScanElf) +RETURN_STATUS +ScanElf ( + OUT image_tool_image_info_t *ImageInfo, + IN const void *File, + IN uint32_t FileSize, + IN const char *SymbolsPath OPTIONAL + ) +{ + RETURN_STATUS Status; + tool_elf_scan_context Context; + const Elf_Ehdr *Ehdr; + Elf_Addr BaseAddress; + + assert (ImageInfo != NULL); + assert (File != NULL || FileSize == 0); + + Status = ParseElfFile (&Context, File, FileSize); + if (RETURN_ERROR (Status)) { + return Status; + } + + Ehdr = Context.Ehdr; + BaseAddress = Context.BaseAddress; + + memset (ImageInfo, 0, sizeof (*ImageInfo)); + + ImageInfo->HeaderInfo.BaseAddress = BaseAddress; + ImageInfo->HeaderInfo.EntryPointAddress = (uint32_t)(Ehdr->e_entry - BaseAddress); + ImageInfo->HeaderInfo.IsXip = true; + ImageInfo->SegmentInfo.SegmentAlignment = (uint32_t)Context.Alignment; + ImageInfo->RelocInfo.RelocsStripped = false; + + if (SymbolsPath != NULL) { + ImageInfo->DebugInfo.SymbolsPathLen = strlen (SymbolsPath); + } else { + assert (ImageInfo->DebugInfo.SymbolsPathLen == 0); + } + + switch (Ehdr->e_machine) { +#if ELF_ARCH == 64 + case EM_X86_64: + ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_X64; + break; + case EM_AARCH64: + ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_AARCH64; + break; +#elif ELF_ARCH == 32 + case EM_386: + ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_IA32; + break; + case EM_ARM: + ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_ARMTHUMB_MIXED; + break; +#endif + default: + fprintf (stderr, "ImageTool: Unknown ELF architecture %d\n", Ehdr->e_machine); + return RETURN_INCOMPATIBLE_VERSION; + } + + ImageInfo->DebugInfo.SymbolsPath = malloc (ImageInfo->DebugInfo.SymbolsPathLen + 1); + if (ImageInfo->DebugInfo.SymbolsPath == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for Debug Data\n"); + return RETURN_OUT_OF_RESOURCES; + }; + + if (SymbolsPath != NULL) { + memmove (ImageInfo->DebugInfo.SymbolsPath, SymbolsPath, ImageInfo->DebugInfo.SymbolsPathLen + 1); + } else { + *ImageInfo->DebugInfo.SymbolsPath = '\0'; + } + + // + // There is no corresponding ELF property. + // + ImageInfo->HeaderInfo.Subsystem = 0; + + Status = CreateIntermediate (ImageInfo, &Context); + if (RETURN_ERROR (Status)) { + ToolImageDestruct (ImageInfo); + } + + return Status; +} diff --git a/BaseTools/ImageTool/ElfScan32.c b/BaseTools/ImageTool/ElfScan32.c new file mode 100644 index 0000000000..de954058b7 --- /dev/null +++ b/BaseTools/ImageTool/ElfScan32.c @@ -0,0 +1,7 @@ +/** @file + Copyright (c) 2023, Marvin Häuser. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#define ELF_ARCH 32 +#include "ElfScan.c" diff --git a/BaseTools/ImageTool/ElfScan64.c b/BaseTools/ImageTool/ElfScan64.c new file mode 100644 index 0000000000..c229cc8740 --- /dev/null +++ b/BaseTools/ImageTool/ElfScan64.c @@ -0,0 +1,7 @@ +/** @file + Copyright (c) 2023, Marvin Häuser. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#define ELF_ARCH 64 +#include "ElfScan.c" diff --git a/BaseTools/ImageTool/ElfScanCommon.c b/BaseTools/ImageTool/ElfScanCommon.c new file mode 100644 index 0000000000..167e9df36c --- /dev/null +++ b/BaseTools/ImageTool/ElfScanCommon.c @@ -0,0 +1,24 @@ +/** @file + Copyright (c) 2023, Marvin Häuser. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include "ElfScanCommon.h" + +RETURN_STATUS +ScanElf ( + OUT image_tool_image_info_t *ImageInfo, + IN const void *File, + IN uint32_t FileSize, + IN const char *SymbolsPath OPTIONAL + ) +{ + RETURN_STATUS Status; + + Status = ScanElf64 (ImageInfo, File, FileSize, SymbolsPath); + if (Status == RETURN_UNSUPPORTED) { + Status = ScanElf32 (ImageInfo, File, FileSize, SymbolsPath); + } + + return Status; +} diff --git a/BaseTools/ImageTool/ElfScanCommon.h b/BaseTools/ImageTool/ElfScanCommon.h new file mode 100644 index 0000000000..a8b79290f7 --- /dev/null +++ b/BaseTools/ImageTool/ElfScanCommon.h @@ -0,0 +1,29 @@ +/** @file + Copyright (c) 2023, Marvin Häuser. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef ELF_SCAN_COMMON_H +#define ELF_SCAN_COMMON_H + +#include + +#include "ImageTool.h" + +RETURN_STATUS +ScanElf32 ( + OUT image_tool_image_info_t *ImageInfo, + IN const void *File, + IN uint32_t FileSize, + IN const char *SymbolsPath OPTIONAL + ); + +RETURN_STATUS +ScanElf64 ( + OUT image_tool_image_info_t *ImageInfo, + IN const void *File, + IN uint32_t FileSize, + IN const char *SymbolsPath OPTIONAL + ); + +#endif // ELF_SCAN_COMMON_H diff --git a/BaseTools/ImageTool/GNUmakefile b/BaseTools/ImageTool/GNUmakefile new file mode 100644 index 0000000000..f4e13585ef --- /dev/null +++ b/BaseTools/ImageTool/GNUmakefile @@ -0,0 +1,25 @@ +## @file +# Copyright (c) 2021, Marvin Häuser. All rights reserved. +# Copyright (c) 2022, Mikhail Krichanov. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause +## + +PROJECT = ImageTool +PRODUCT = $(PROJECT)$(INFIX)$(SUFFIX) +OBJS = $(PROJECT).o +OBJS += Image.o UefiImageScan.o PeEmit32.o PeEmit64.o PeEmitCommon.o PeScan.o ElfScan32.o ElfScan64.o ElfScanCommon.o BinEmit.o ImageToolEmit.o +OBJS += UefiImageExtraActionLib.o +OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o PeCoffHash.o +OBJS += UefiImageLibPeCoff.o PeCoffSupport.o CommonSupport.o + +WERROR = 1 +DEBUG = 1 +SANITIZE = 0 +OC_USER = ../../OpenCorePkg +UDK_PATH = ../.. + +VPATH += ../../MdePkg/Library/BasePeCoffLib2:$\ + ../../MdePkg/Library/BaseUefiImageExtraActionLibNull:$\ + ../../MdePkg/Library/BaseUefiImageLib + +include $(OC_USER)/User/Makefile diff --git a/BaseTools/ImageTool/Image.c b/BaseTools/ImageTool/Image.c new file mode 100644 index 0000000000..699bd89242 --- /dev/null +++ b/BaseTools/ImageTool/Image.c @@ -0,0 +1,649 @@ +/** @file + Copyright (c) 2021, Marvin Häuser. All rights reserved. + Copyright (c) 2022, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include "ImageTool.h" + +static +bool +CheckToolImageSegment ( + const image_tool_segment_info_t *SegmentInfo, + const image_tool_segment_t *Segment, + uint32_t *PreviousEndAddress + ) +{ + bool Overflow; + + assert (Segment != NULL); + assert (PreviousEndAddress != NULL); + + if (!IS_ALIGNED (Segment->ImageSize, SegmentInfo->SegmentAlignment)) { + raise (); + return false; + } + + if (Segment->Write && Segment->Execute) { + raise (); + return false; + } + + // FIXME: Expand prior segment + if (Segment->ImageAddress != *PreviousEndAddress) { + raise (); + return false; + } + + Overflow = BaseOverflowAddU32 ( + Segment->ImageAddress, + Segment->ImageSize, + PreviousEndAddress + ); + if (Overflow) { + raise (); + return false; + } + + return true; +} + +static +bool +CheckToolImageSegmentInfo ( + const image_tool_segment_info_t *SegmentInfo, + uint32_t *ImageSize + ) +{ + uint32_t Index; + bool Result; + + assert (SegmentInfo != NULL); + assert (ImageSize != NULL); + + if (!IS_POW2 (SegmentInfo->SegmentAlignment)) { + raise (); + return false; + } + + if (SegmentInfo->NumSegments == 0) { + raise (); + return false; + } + + if (!IS_ALIGNED (SegmentInfo->Segments[0].ImageAddress, SegmentInfo->SegmentAlignment)) { + raise (); + return false; + } + + *ImageSize = SegmentInfo->Segments[0].ImageAddress; + for (Index = 0; Index < SegmentInfo->NumSegments; ++Index) { + Result = CheckToolImageSegment ( + SegmentInfo, + &SegmentInfo->Segments[Index], + ImageSize + ); + if (!Result) { + raise (); + return false; + } + } + + return true; +} + +static +const image_tool_segment_t * +ImageGetSegmentByAddress ( + uint32_t *Address, + uint32_t *RemainingSize, + const image_tool_segment_info_t *SegmentInfo + ) +{ + uint32_t Index; + + assert (Address != NULL); + assert (SegmentInfo != NULL); + + for (Index = 0; Index < SegmentInfo->NumSegments; ++Index) { + if ((SegmentInfo->Segments[Index].ImageAddress <= *Address) + && (*Address < SegmentInfo->Segments[Index].ImageAddress + SegmentInfo->Segments[Index].ImageSize)) { + *Address -= SegmentInfo->Segments[Index].ImageAddress; + *RemainingSize = SegmentInfo->Segments[Index].ImageSize - *Address; + return &SegmentInfo->Segments[Index]; + } + } + + return NULL; +} + +static +bool +CheckToolImageReloc ( + const image_tool_image_info_t *Image, + uint32_t ImageSize, + const image_tool_reloc_t *Reloc + ) +{ + uint32_t RelocOffset; + uint32_t RemainingSize; + const image_tool_segment_t *Segment; + uint16_t MovHigh; + uint16_t MovLow; + + assert (Image != NULL); + assert (Reloc != NULL); + + RelocOffset = Reloc->Target; + Segment = ImageGetSegmentByAddress ( + &RelocOffset, + &RemainingSize, + &Image->SegmentInfo + ); + if (Segment == NULL) { + raise (); + return false; + } + + switch (Reloc->Type) { + case EFI_IMAGE_REL_BASED_HIGHLOW: + { + if (RemainingSize < sizeof (UINT32)) { + raise (); + return false; + } + + break; + } + + case EFI_IMAGE_REL_BASED_DIR64: + { + if (RemainingSize < sizeof (UINT64)) { + raise (); + return false; + } + + break; + } + + case EFI_IMAGE_REL_BASED_ARM_MOV32T: + { + if (RemainingSize < sizeof (UINT32)) { + raise (); + return false; + } + + if (!IS_ALIGNED (Reloc->Target, ALIGNOF (UINT16))) { + raise (); + return false; + } + + MovHigh = *(const uint16_t *)&Segment->Data[RelocOffset]; + MovLow = *(const uint16_t *)&Segment->Data[RelocOffset + 2]; + if (((MovHigh & 0xFBF0U) != 0xF200U && (MovHigh & 0xFBF0U) != 0xF2C0U) || + (MovLow & 0x8000U) != 0) { + raise (); + return false; + } + + break; + } + + default: + { + raise (); + return false; + } + } + + /*if (Segment->Write) { + printf("!!! writable reloc at %x !!!\n", Reloc->Target); + }*/ + + return true; +} + +static +bool +CheckToolImageRelocInfo ( + const image_tool_image_info_t *Image, + uint32_t ImageSize + ) +{ + const image_tool_reloc_info_t *RelocInfo; + uint32_t Index; + bool Result; + + assert (Image != NULL); + + RelocInfo = &Image->RelocInfo; + + if (RelocInfo->NumRelocs == 0) { + return true; + } + + if (RelocInfo->RelocsStripped && (RelocInfo->NumRelocs > 0)) { + raise (); + return false; + } + + if (RelocInfo->NumRelocs > (MAX_UINT32 / sizeof (UINT16))) { + raise (); + return false; + } + + Result = CheckToolImageReloc (Image, ImageSize, &RelocInfo->Relocs[0]); + if (!Result) { + raise (); + return false; + } + + for (Index = 1; Index < RelocInfo->NumRelocs; ++Index) { + if (RelocInfo->Relocs[Index].Target < RelocInfo->Relocs[Index - 1].Target) { + assert (false); + return false; + } + + Result = CheckToolImageReloc (Image, ImageSize, &RelocInfo->Relocs[Index]); + if (!Result) { + raise (); + return false; + } + } + + return true; +} + +static +bool +CheckToolImageDebugInfo ( + const image_tool_debug_info_t *DebugInfo + ) +{ + assert (DebugInfo != NULL); + + if (DebugInfo->SymbolsPath != NULL) { + // FIXME: UE-only? + if (DebugInfo->SymbolsPathLen > MAX_UINT8) { + raise (); + return false; + } + } + + return true; +} + +bool +CheckToolImage ( + const image_tool_image_info_t *Image + ) +{ + bool Result; + uint32_t ImageSize; + + assert (Image != NULL); + + Result = CheckToolImageSegmentInfo (&Image->SegmentInfo, &ImageSize); + if (!Result) { + raise (); + return false; + } + + Result = CheckToolImageRelocInfo (Image, ImageSize); + if (!Result) { + raise (); + return false; + } + + Result = CheckToolImageDebugInfo (&Image->DebugInfo); + if (!Result) { + raise (); + return false; + } + + return true; +} + +void +ImageInitUnpaddedSize ( + const image_tool_image_info_t *Image + ) +{ + uint32_t Index; + image_tool_segment_t *Segment; + + for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { + Segment = &Image->SegmentInfo.Segments[Index]; + Segment->UnpaddedSize = Segment->ImageSize; + + if (Image->HeaderInfo.IsXip) { + continue; + } + + for (; Segment->UnpaddedSize > 0; --Segment->UnpaddedSize) { + if (Segment->Data[Segment->UnpaddedSize - 1] != 0) { + break; + } + } + } +} + +void +ToolImageDestruct ( + image_tool_image_info_t *Image + ) +{ + uint8_t Index; + + assert (Image != NULL); + + if (Image->SegmentInfo.Segments != NULL) { + for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { + free (Image->SegmentInfo.Segments[Index].Name); + free (Image->SegmentInfo.Segments[Index].Data); + } + + free (Image->SegmentInfo.Segments); + } + + free (Image->HiiInfo.Data); + free (Image->RelocInfo.Relocs); + free (Image->DebugInfo.SymbolsPath); + + memset (Image, 0, sizeof (*Image)); +} + +bool +ToolImageRelocate ( + image_tool_image_info_t *Image, + uint64_t BaseAddress + ) +{ + uint64_t Adjust; + const image_tool_reloc_t *Reloc; + uint32_t RelocOffset; + uint32_t RemainingSize; + const image_tool_segment_t *Segment; + uint32_t Index; + uint32_t RelocTarget32; + uint64_t RelocTarget64; + + Adjust = BaseAddress - Image->HeaderInfo.BaseAddress; + + if (Adjust == 0) { + return TRUE; + } + + for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) { + Reloc = &Image->RelocInfo.Relocs[Index]; + + RelocOffset = Reloc->Target; + Segment = ImageGetSegmentByAddress ( + &RelocOffset, + &RemainingSize, + &Image->SegmentInfo + ); + if (Segment == NULL) { + raise (); + return false; + } + + switch (Reloc->Type) { + case EFI_IMAGE_REL_BASED_HIGHLOW: + { + assert (RemainingSize >= sizeof (UINT32)); + + RelocTarget32 = ReadUnaligned32 ((CONST VOID *)&Segment->Data[RelocOffset]); + RelocTarget32 += (uint32_t)Adjust; + WriteUnaligned32 ((VOID *)&Segment->Data[RelocOffset], RelocTarget32); + break; + } + + case EFI_IMAGE_REL_BASED_DIR64: + { + assert (RemainingSize >= sizeof (UINT64)); + + RelocTarget64 = ReadUnaligned64 ((CONST VOID *)&Segment->Data[RelocOffset]); + RelocTarget64 += Adjust; + WriteUnaligned64 ((VOID *)&Segment->Data[RelocOffset], RelocTarget64); + break; + } + + case EFI_IMAGE_REL_BASED_ARM_MOV32T: + { + assert (RemainingSize >= sizeof (UINT32)); + assert (IS_ALIGNED (Reloc->Target, ALIGNOF (UINT16))); + + PeCoffThumbMovwMovtImmediateFixup (&Segment->Data[RelocOffset], Adjust); + break; + } + + default: + { + raise (); + return false; + } + } + } + + Image->HeaderInfo.BaseAddress = BaseAddress; + + return true; +} + +static +int +ToolImageRelocCompare ( + IN const void *Buffer1, + IN const void *Buffer2 + ) +{ + const image_tool_reloc_t *Reloc1; + const image_tool_reloc_t *Reloc2; + + Reloc1 = (const image_tool_reloc_t *)Buffer1; + Reloc2 = (const image_tool_reloc_t *)Buffer2; + + if (Reloc1->Target < Reloc2->Target) { + return -1; + } + + if (Reloc1->Target > Reloc2->Target) { + return 1; + } + + return 0; +} + +void +ToolImageSortRelocs ( + image_tool_image_info_t *Image + ) +{ + if (Image->RelocInfo.Relocs == NULL) { + return; + } + + qsort ( + Image->RelocInfo.Relocs, + Image->RelocInfo.NumRelocs, + sizeof (*Image->RelocInfo.Relocs), + ToolImageRelocCompare + ); +} + +bool +ToolImageCompare ( + const image_tool_image_info_t *Image1, + const image_tool_image_info_t *Image2 + ) +{ + int CmpResult; + uint32_t SegIndex; + const char *Name1; + const char *Name2; + uint32_t NameIndex; + + // + // Compare HeaderInfo. + // + + CmpResult = memcmp ( + &Image1->HeaderInfo, + &Image2->HeaderInfo, + sizeof (Image1->HeaderInfo) + ); + if (CmpResult != 0) { + raise (); + return false; + } + + // + // Compare SegmentInfo. + // UnpaddedSize is deliberately omitted, as it's implicit by the equality of + // ImageSize and Data. + // + + CmpResult = memcmp ( + &Image1->SegmentInfo, + &Image2->SegmentInfo, + OFFSET_OF (image_tool_segment_info_t, Segments) + ); + if (CmpResult != 0) { + raise (); + return false; + } + + for (SegIndex = 0; SegIndex < Image1->SegmentInfo.NumSegments; ++SegIndex) { + CmpResult = memcmp ( + &Image1->SegmentInfo.Segments[SegIndex], + &Image2->SegmentInfo.Segments[SegIndex], + OFFSET_OF (image_tool_segment_t, Name) + ); + if (CmpResult != 0) { + raise (); + return false; + } + + // + // Don't assume images generally support arbitrarily long names or names in + // general. Check prefix equiality as a best effort. + // + Name1 = Image1->SegmentInfo.Segments[SegIndex].Name; + Name2 = Image2->SegmentInfo.Segments[SegIndex].Name; + if (Name1 != NULL && Name2 != NULL) { + for ( + NameIndex = 0; + Name1[NameIndex] != '\0' && Name2[NameIndex] != '\0'; + ++NameIndex + ) { + if (Name1[NameIndex] != Name2[NameIndex]) { + raise (); + return false; + } + } + } + + CmpResult = memcmp ( + Image1->SegmentInfo.Segments[SegIndex].Data, + Image2->SegmentInfo.Segments[SegIndex].Data, + Image1->SegmentInfo.Segments[SegIndex].ImageSize + ); + if (CmpResult != 0) { + raise (); + return false; + } + } + + // + // Compare RelocInfo. + // + + CmpResult = memcmp ( + &Image1->RelocInfo, + &Image2->RelocInfo, + OFFSET_OF (image_tool_reloc_info_t, Relocs) + ); + if (CmpResult != 0) { + raise (); + return false; + } + + CmpResult = memcmp ( + Image1->RelocInfo.Relocs, + Image2->RelocInfo.Relocs, + Image1->RelocInfo.NumRelocs * sizeof (*Image1->RelocInfo.Relocs) + ); + if (CmpResult != 0) { + raise (); + return false; + } + + // + // Compare HiiInfo. + // + + CmpResult = memcmp ( + &Image1->HiiInfo, + &Image2->HiiInfo, + OFFSET_OF (image_tool_hii_info_t, Data) + ); + if (CmpResult != 0) { + raise (); + return false; + } + + CmpResult = memcmp ( + Image1->HiiInfo.Data, + Image2->HiiInfo.Data, + Image1->HiiInfo.DataSize + ); + if (CmpResult != 0) { + raise (); + return false; + } + + // + // Compare DebugInfo. + // + + CmpResult = memcmp ( + &Image1->DebugInfo, + &Image2->DebugInfo, + OFFSET_OF (image_tool_debug_info_t, SymbolsPath) + ); + if (CmpResult != 0) { + raise (); + return false; + } + + if ((Image1->DebugInfo.SymbolsPath != NULL) != (Image2->DebugInfo.SymbolsPath != NULL)) { + raise (); + return false; + } + + if (Image1->DebugInfo.SymbolsPath != NULL) { + CmpResult = strcmp ( + Image1->DebugInfo.SymbolsPath, + Image2->DebugInfo.SymbolsPath + ); + if (CmpResult != 0) { + raise (); + return false; + } + } + + return true; +} + +void +ToolImageStripRelocs ( + image_tool_image_info_t *Image + ) +{ + Image->RelocInfo.NumRelocs = 0; + free (Image->RelocInfo.Relocs); + Image->RelocInfo.Relocs = NULL; + + Image->RelocInfo.RelocsStripped = TRUE; +} diff --git a/BaseTools/ImageTool/ImageTool.c b/BaseTools/ImageTool/ImageTool.c new file mode 100644 index 0000000000..866a369a9a --- /dev/null +++ b/BaseTools/ImageTool/ImageTool.c @@ -0,0 +1,530 @@ +/** @file + Copyright (c) 2021, Marvin Häuser. All rights reserved. + Copyright (c) 2022, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include "ImageTool.h" +#include +#include +#include + +#include + +#include "ImageToolEmit.h" + +#define EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x0 + + +static +RETURN_STATUS +HiiBin ( + IN const char *HiiName, + IN const char *Guid, + IN const char *FileNames[], + IN UINT32 NumOfFiles + ) +{ + RETURN_STATUS Status; + void *Hii; + UINT32 HiiSize; + GUID HiiGuid; + + assert (FileNames != NULL); + assert (HiiName != NULL); + assert (Guid != NULL); + + Status = AsciiStrToGuid (Guid, &HiiGuid); + if (RETURN_ERROR (Status)) { + fprintf (stderr, "ImageTool: Invalid GUID - %s\n", Guid); + return Status; + } + + Status = ConstructHii (FileNames, NumOfFiles, &HiiGuid, &Hii, &HiiSize); + if (RETURN_ERROR (Status)) { + fprintf (stderr, "ImageTool: Could not construct HiiBin\n"); + return Status; + } + + UserWriteFile (HiiName, Hii, HiiSize); + + free (Hii); + + return RETURN_SUCCESS; +} + +static +RETURN_STATUS +CheckAcpiTable ( + IN const void *AcpiTable, + IN UINT32 Length + ) +{ + const EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader; + const EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs; + UINT32 ExpectedLength; + + AcpiHeader = (const EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable; + + if (AcpiHeader->Length > Length) { + fprintf (stderr, "ImageTool: AcpiTable length section size\n"); + return RETURN_VOLUME_CORRUPTED; + } + + switch (AcpiHeader->Signature) { + case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE: + switch (AcpiHeader->Revision) { + case EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION: + ExpectedLength = sizeof(EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE); + break; + case EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION: + ExpectedLength = sizeof(EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE); + break; + case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION: + ExpectedLength = sizeof(EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE); + break; + default: + if (AcpiHeader->Revision > EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) { + ExpectedLength = AcpiHeader->Length; + break; + } + fprintf (stderr, "ImageTool: FACP revision check failed\n"); + return RETURN_VOLUME_CORRUPTED; + } + + if (ExpectedLength != AcpiHeader->Length) { + fprintf (stderr, "ImageTool: FACP length check failed\n"); + return RETURN_VOLUME_CORRUPTED; + } + break; + case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE: + Facs = (const EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)AcpiTable; + if (Facs->Version > EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) { + break; + } + + if ((Facs->Version != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) + && (Facs->Version != EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) + && (Facs->Version != EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION)) { + fprintf (stderr, "ImageTool: FACS version check failed\n"); + return RETURN_VOLUME_CORRUPTED; + } + + if ((Facs->Length != sizeof(EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE)) + && (Facs->Length != sizeof(EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE)) + && (Facs->Length != sizeof(EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE))) { + fprintf (stderr, "ImageTool: FACS length check failed\n"); + return RETURN_VOLUME_CORRUPTED; + } + break; + case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: + if (AcpiHeader->Revision > EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION) { + break; + } + + if (AcpiHeader->Length <= sizeof(EFI_ACPI_DESCRIPTION_HEADER)) { + fprintf (stderr, "ImageTool: DSDT length check failed\n"); + return RETURN_VOLUME_CORRUPTED; + } + break; + case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE: + if (AcpiHeader->Revision > EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) { + break; + } + + if ((AcpiHeader->Revision != EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) + && (AcpiHeader->Revision != EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) + && (AcpiHeader->Revision != EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION)) { + fprintf (stderr, "ImageTool: APIC revision check failed\n"); + return RETURN_VOLUME_CORRUPTED; + } + + if (AcpiHeader->Length <= (sizeof(EFI_ACPI_DESCRIPTION_HEADER) + sizeof(UINT32) + sizeof(UINT32))) { + fprintf (stderr, "ImageTool: APIC length check failed\n"); + return RETURN_VOLUME_CORRUPTED; + } + break; + case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE: + if (AcpiHeader->Revision > EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION) { + break; + } + + if (AcpiHeader->Revision != EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION) { + fprintf (stderr, "ImageTool: MCFG revision check failed\n"); + return RETURN_VOLUME_CORRUPTED; + } + + if (AcpiHeader->Length <= (sizeof(EFI_ACPI_DESCRIPTION_HEADER) + sizeof(UINT64))) { + fprintf (stderr, "ImageTool: MCFG length check failed\n"); + return RETURN_VOLUME_CORRUPTED; + } + break; + default: + break; + } + + return RETURN_SUCCESS; +} + +static +RETURN_STATUS +GetAcpi ( + IN const char *PeName, + IN const char *AcpiName + ) +{ + RETURN_STATUS Status; + void *Pe; + uint32_t PeSize; + PE_COFF_LOADER_IMAGE_CONTEXT Context; + UINT16 NumberOfSections; + const EFI_IMAGE_SECTION_HEADER *Sections; + UINT16 Index; + UINT32 FileLength; + + assert (PeName != NULL); + assert (AcpiName != NULL); + + Pe = UserReadFile (PeName, &PeSize); + if (Pe == NULL) { + fprintf (stderr, "ImageTool: Could not open %s: %s\n", PeName, strerror (errno)); + return RETURN_ABORTED; + } + + Status = PeCoffInitializeContext (&Context, Pe, (UINT32)PeSize); + if (RETURN_ERROR (Status)) { + fprintf (stderr, "ImageTool: Could not initialise Context\n"); + free (Pe); + return Status; + } + + NumberOfSections = PeCoffGetSectionTable (&Context, &Sections); + for (Index = 0; Index < NumberOfSections; ++Index) { + if ((strcmp ((char *)Sections[Index].Name, ".data") == 0) + || (strcmp ((char *)Sections[Index].Name, ".sdata") == 0) + || (strcmp ((char *)Sections[Index].Name, ".rdata") == 0)) { + + if (Sections[Index].VirtualSize < Sections[Index].SizeOfRawData) { + FileLength = Sections[Index].VirtualSize; + } else { + FileLength = Sections[Index].SizeOfRawData; + } + + Status = CheckAcpiTable ((char *)Context.FileBuffer + Sections[Index].PointerToRawData, FileLength); + if (RETURN_ERROR (Status)) { + free (Pe); + return Status; + } + + UserWriteFile (AcpiName, (char *)Context.FileBuffer + Sections[Index].PointerToRawData, FileLength); + + free (Pe); + + return RETURN_SUCCESS; + } + } + + return RETURN_NOT_FOUND; +} + +static +int32_t +NameToType ( + IN const char *TypeName + ) +{ + if ((strcmp (TypeName, "BASE") == 0) + || (strcmp (TypeName, "SEC") == 0) + || (strcmp (TypeName, "SECURITY_CORE") == 0) + || (strcmp (TypeName, "PEI_CORE") == 0) + || (strcmp (TypeName, "PEIM") == 0) + || (strcmp (TypeName, "COMBINED_PEIM_DRIVER") == 0) + || (strcmp (TypeName, "PIC_PEIM") == 0) + || (strcmp (TypeName, "RELOCATABLE_PEIM") == 0) + || (strcmp (TypeName, "DXE_CORE") == 0) + || (strcmp (TypeName, "BS_DRIVER") == 0) + || (strcmp (TypeName, "DXE_DRIVER") == 0) + || (strcmp (TypeName, "DXE_SMM_DRIVER") == 0) + || (strcmp (TypeName, "UEFI_DRIVER") == 0) + || (strcmp (TypeName, "SMM_CORE") == 0) + || (strcmp (TypeName, "MM_STANDALONE") == 0) + || (strcmp (TypeName, "MM_CORE_STANDALONE") == 0)) { + return EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER; + } + + if ((strcmp (TypeName, "UEFI_APPLICATION") == 0) + || (strcmp (TypeName, "APPLICATION") == 0)) { + return EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION; + } + + if ((strcmp (TypeName, "DXE_RUNTIME_DRIVER") == 0) + || (strcmp (TypeName, "RT_DRIVER") == 0)) { + return EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER; + } + + if ((strcmp (TypeName, "DXE_SAL_DRIVER") == 0) + || (strcmp (TypeName, "SAL_RT_DRIVER") == 0)) { + return EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER; + } + + return -1; +} + +static +int8_t +NameToFormat ( + IN const char *FormatName + ) +{ + if (strcmp (FormatName, "PE") == 0) { + return UefiImageFormatPe; + } + + return -1; +} + +static +RETURN_STATUS +GenExecutable ( + IN const char *OutputFileName, + IN const char *InputFileName, + IN const char *FormatName, + IN const char *TypeName, + IN const char *HiiFileName, + IN const char *BaseAddress, + IN bool Strip, + IN bool FixedAddress + ) +{ + UINT32 InputFileSize; + VOID *InputFile; + int8_t Format; + int32_t Type; + UINT32 HiiFileSize; + VOID *HiiFile; + RETURN_STATUS Status; + UINT64 NewBaseAddress; + void *OutputFile; + uint32_t OutputFileSize; + + Format = -1; + if (FormatName != NULL) { + Format = NameToFormat (FormatName); + if (Format == -1) { + fprintf (stderr, "ImageTool: Unknown output format %s\n", FormatName); + return RETURN_UNSUPPORTED; + } + } + + Type = -1; + if (TypeName != NULL) { + Type = NameToType (TypeName); + if (Type == -1) { + fprintf (stderr, "ImageTool: Unknown EFI_FILETYPE = %s\n", TypeName); + return RETURN_UNSUPPORTED; + } + } + + NewBaseAddress = 0; + if (BaseAddress != NULL) { + Status = AsciiStrHexToUint64S (BaseAddress, NULL, &NewBaseAddress); + if (RETURN_ERROR (Status)) { + fprintf (stderr, "ImageTool: Could not convert ASCII string to UINT64\n"); + return Status; + } + } + + InputFile = UserReadFile (InputFileName, &InputFileSize); + if (InputFile == NULL) { + fprintf (stderr, "ImageTool: Could not open %s: %s\n", InputFileName, strerror (errno)); + return RETURN_ABORTED; + } + + HiiFile = NULL; + HiiFileSize = 0; + if (HiiFileName != NULL) { + HiiFile = UserReadFile (HiiFileName, &HiiFileSize); + if (HiiFile == NULL) { + fprintf (stderr, "ImageTool: Could not open %s: %s\n", HiiFileName, strerror (errno)); + return RETURN_ABORTED; + } + } + + OutputFile = ToolImageEmit ( + &OutputFileSize, + InputFile, + InputFileSize, + Format, + Type, + HiiFile, + HiiFileSize, + BaseAddress != NULL, + NewBaseAddress, + InputFileName, + Strip, + FixedAddress + ); + + if (OutputFile == NULL) { + free (HiiFile); + return RETURN_ABORTED; + } + + UserWriteFile (OutputFileName, OutputFile, OutputFileSize); + + free (OutputFile); + + return RETURN_SUCCESS; +} + +int main (int argc, const char *argv[]) +{ + RETURN_STATUS Status; + UINT32 NumOfFiles; + const char *OutputName; + const char *InputName; + const char *FormatName; + const char *TypeName; + const char *HiiFileName; + const char *BaseAddress; + bool Strip; + bool FixedAddress; + int ArgIndex; + + if (argc < 2) { + fprintf (stderr, "ImageTool: No command is specified\n"); + raise (); + return -1; + } + // + // The command structure must prefix all output files with "-o" and all + // following dash-less parameters must be input files due to scanning for + // these arguments by BaseTools/GenMake. + // + if (strcmp (argv[1], "GenImage") == 0) { + if (argc < 5) { + fprintf (stderr, "ImageTool: Command arguments are missing\n"); + fprintf (stderr, " Usage: ImageTool GenImage [-c Format] [-t ModuleType] [-h HiiRc] [-b BaseAddress] [-s] [-f] -o OutputFile InputFile\n"); + raise (); + return -1; + } + + OutputName = NULL; + InputName = NULL; + FormatName = NULL; + TypeName = NULL; + HiiFileName = NULL; + BaseAddress = NULL; + Strip = false; + FixedAddress = false; + for (ArgIndex = 2; ArgIndex < argc; ++ArgIndex) { + if (strcmp (argv[ArgIndex], "-o") == 0) { + ++ArgIndex; + if (ArgIndex == argc) { + fprintf (stderr, "Must specify an argument to -o\n"); + return -1; + } + + OutputName = argv[ArgIndex]; + } else if (strcmp (argv[ArgIndex], "-c") == 0) { + ++ArgIndex; + if (ArgIndex == argc) { + fprintf (stderr, "Must specify an argument to -c\n"); + return -1; + } + + FormatName = argv[ArgIndex]; + } else if (strcmp (argv[ArgIndex], "-t") == 0) { + ++ArgIndex; + if (ArgIndex == argc) { + fprintf (stderr, "Must specify an argument to -t\n"); + return -1; + } + + TypeName = argv[ArgIndex]; + } else if (strcmp (argv[ArgIndex], "-h") == 0) { + ++ArgIndex; + if (ArgIndex == argc) { + fprintf (stderr, "Must specify an argument to -h\n"); + return -1; + } + + HiiFileName = argv[ArgIndex]; + } else if (strcmp (argv[ArgIndex], "-b") == 0) { + ++ArgIndex; + if (ArgIndex == argc) { + fprintf (stderr, "Must specify an argument to -b\n"); + return -1; + } + + BaseAddress = argv[ArgIndex]; + } else if (strcmp (argv[ArgIndex], "-s") == 0) { + Strip = true; + } else if (strcmp (argv[ArgIndex], "-f") == 0) { + FixedAddress = true; + } else if (argv[ArgIndex][0] == '-') { + fprintf (stderr, "Unknown parameter %s\n", argv[ArgIndex]); + } else if (InputName == NULL) { + InputName = argv[ArgIndex]; + } else { + fprintf (stderr, "GenImage only supports one input file.\n"); + return -1; + } + } + + if (OutputName == NULL) { + fprintf (stderr, "Must provide an output file.\n"); + return -1; + } + + if (InputName == NULL) { + fprintf (stderr, "Must provide an input file.\n"); + return -1; + } + + Status = GenExecutable ( + OutputName, + InputName, + FormatName, + TypeName, + HiiFileName, + BaseAddress, + Strip, + FixedAddress + ); + if (RETURN_ERROR (Status)) { + raise (); + return -1; + } + } else if (strcmp (argv[1], "HiiBin") == 0) { + if (argc < 5 || strcmp (argv[3], "-o") != 0) { + fprintf (stderr, "ImageTool: Command arguments are missing\n"); + fprintf (stderr, " Usage: ImageTool HiiBin GUID -o OutputFile InputFile1 InputFile2 ...\n"); + raise (); + return -1; + } + + NumOfFiles = (UINT32)argc - 5U; + + Status = HiiBin (argv[4], argv[2], &argv[5], NumOfFiles); + if (RETURN_ERROR (Status)) { + raise (); + return -1; + } + } else if (strcmp (argv[1], "GetAcpi") == 0) { + if (argc != 5 || strcmp (argv[2], "-o") != 0) { + fprintf (stderr, "ImageTool: Command arguments are missing\n"); + fprintf (stderr, " Usage: ImageTool GetAcpi -o OutputFile InputFile\n"); + raise (); + return -1; + } + + Status = GetAcpi (argv[4], argv[3]); + if (RETURN_ERROR (Status)) { + raise (); + return -1; + } + } + + return 0; +} diff --git a/BaseTools/ImageTool/ImageTool.h b/BaseTools/ImageTool/ImageTool.h new file mode 100644 index 0000000000..048579a315 --- /dev/null +++ b/BaseTools/ImageTool/ImageTool.h @@ -0,0 +1,185 @@ +/** @file + Copyright (c) 2021, Marvin Häuser. All rights reserved. + Copyright (c) 2022, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef IMAGE_TOOL_H +#define IMAGE_TOOL_H + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MAX_PE_ALIGNMENT 0x10000 + +#define raise() assert(false) + +typedef struct { + EFI_IMAGE_DEBUG_DIRECTORY_ENTRY Dir; + EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY Nb10; + char Name[]; +} DebugData; + +#define PAGE(x) ((x) & ~4095U) +#define PAGE_OFF(x) ((x) & 4095U) + +typedef struct { + uint64_t BaseAddress; + uint32_t EntryPointAddress; + uint16_t Machine; + uint16_t Subsystem; + uint8_t IsXip; + uint8_t FixedAddress; + uint8_t Reserved[6]; +} image_tool_header_info_t; + +typedef struct { + uint32_t ImageAddress; + uint32_t ImageSize; + uint8_t Read; + uint8_t Write; + uint8_t Execute; + uint8_t Reserved[1]; + + char *Name; + uint8_t *Data; + + uint32_t UnpaddedSize; +} image_tool_segment_t; + +typedef struct { + uint32_t SegmentAlignment; + uint32_t NumSegments; + + image_tool_segment_t *Segments; +} image_tool_segment_info_t; + +typedef struct { + uint8_t Type; + uint8_t Reserved[3]; + uint32_t Target; +} image_tool_reloc_t; + +typedef struct { + uint32_t NumRelocs; + uint8_t RelocsStripped; + uint8_t Reserved[3]; + + image_tool_reloc_t *Relocs; +} image_tool_reloc_info_t; + +typedef struct { + uint32_t SymbolsPathLen; + + char *SymbolsPath; +} image_tool_debug_info_t; + +typedef struct { + uint32_t DebugDirAddress; + uint32_t DebugDirSize; +} image_tool_pe_datadir_info_t; + +typedef struct { + uint32_t DataSize; + + void *Data; +} image_tool_hii_info_t; + +typedef struct { + image_tool_header_info_t HeaderInfo; + image_tool_segment_info_t SegmentInfo; + image_tool_reloc_info_t RelocInfo; + image_tool_hii_info_t HiiInfo; + image_tool_debug_info_t DebugInfo; +} image_tool_image_info_t; + +void +ToolImageDestruct ( + image_tool_image_info_t *Image + ); + +void +ImageInitUnpaddedSize ( + const image_tool_image_info_t *Image + ); + +bool +ToolImageRelocate ( + image_tool_image_info_t *Image, + uint64_t BaseAddress + ); + +void +ToolImageSortRelocs ( + image_tool_image_info_t *Image + ); + +bool +ToolImageCompare ( + const image_tool_image_info_t *Image1, + const image_tool_image_info_t *Image2 + ); + +void +ToolImageStripRelocs ( + image_tool_image_info_t *Image + ); + +RETURN_STATUS +ToolContextConstructUefiImage ( + OUT image_tool_image_info_t *Image, + OUT INT8 *Format, + IN const void *File, + IN size_t FileSize + ); + +bool +CheckToolImage ( + const image_tool_image_info_t *Image + ); + +void * +ToolImageEmitPe ( + image_tool_image_info_t *Image, + uint32_t *FileSize, + bool Strip + ); + +RETURN_STATUS +ScanElf ( + OUT image_tool_image_info_t *ImageInfo, + IN const void *File, + IN uint32_t FileSize, + IN const char *SymbolsPath OPTIONAL + ); + +extern CONST UINT8 mHiiResourceSectionHeaderSize; + +VOID +InitializeHiiResouceSectionHeader ( + OUT UINT8 *HiiSectionHeader, + IN UINT32 HiiDataAddress, + IN UINT32 HiiDataSize + ); + +RETURN_STATUS +ConstructHii ( + IN const char *FileNames[], + IN UINT32 NumOfFiles, + IN GUID *HiiGuid, + OUT void **Hii, + OUT UINT32 *HiiSize + ); + +#endif // IMAGE_TOOL_H diff --git a/BaseTools/ImageTool/ImageToolEmit.c b/BaseTools/ImageTool/ImageToolEmit.c new file mode 100644 index 0000000000..338ac0fce2 --- /dev/null +++ b/BaseTools/ImageTool/ImageToolEmit.c @@ -0,0 +1,184 @@ +/** @file + Copyright (c) 2023, Marvin Häuser. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include "ImageTool.h" + +#include + +#include + +#include + +#include "ImageToolEmit.h" + +static +RETURN_STATUS +ToolContextConstruct ( + OUT image_tool_image_info_t *ImageInfo, + OUT int8_t *Format, + IN const void *File, + IN uint32_t FileSize, + IN const char *SymbolsPath OPTIONAL + ) +{ + RETURN_STATUS Status; + + *Format = -1; + + Status = ToolContextConstructUefiImage ( + ImageInfo, + Format, + File, + FileSize + ); + if (Status == RETURN_UNSUPPORTED) { + Status = ScanElf (ImageInfo, File, FileSize, SymbolsPath); + } + + return Status; +} + +static +RETURN_STATUS +ValidateOutputFile ( + void *OutputFile, + uint32_t OutputFileSize, + const image_tool_image_info_t *ImageInfo + ) +{ + RETURN_STATUS Status; + bool Result; + image_tool_image_info_t OutputImageInfo; + int8_t Format; + + Status = ToolContextConstruct ( + &OutputImageInfo, + &Format, + OutputFile, + OutputFileSize, + NULL + ); + if (EFI_ERROR (Status)) { + assert (false); + return Status; + } + + Result = CheckToolImage (&OutputImageInfo); + if (!Result) { + raise (); + ToolImageDestruct (&OutputImageInfo); + return RETURN_UNSUPPORTED; + } + + Result = ToolImageCompare (&OutputImageInfo, ImageInfo); + + ToolImageDestruct (&OutputImageInfo); + + if (!Result) { + assert (false); + return RETURN_VOLUME_CORRUPTED; + } + + return RETURN_SUCCESS; +} + +void * +ToolImageEmit ( + OUT uint32_t *OutputFileSize, + IN const void *Buffer, + IN uint32_t BufferSize, + IN int8_t Format, + IN int32_t Type, + IN void *HiiFile, + IN uint32_t HiiFileSize, + IN bool Relocate, + IN uint64_t BaseAddress, + IN const char *SymbolsPath OPTIONAL, + IN bool Strip, + IN bool FixedAddress + ) +{ + RETURN_STATUS Status; + bool Success; + image_tool_image_info_t ImageInfo; + int8_t SourceFormat; + void *OutputFile; + + Status = ToolContextConstruct ( + &ImageInfo, + &SourceFormat, + Buffer, + BufferSize, + SymbolsPath + ); + + if (SymbolsPath == NULL) { + SymbolsPath = ""; + } + + if (RETURN_ERROR (Status)) { + fprintf (stderr, "ImageTool: Could not parse input file %s - %llx\n", SymbolsPath, (unsigned long long)Status); + return NULL; + } + + if (Format == -1) { + Format = SourceFormat; + if (Format == -1) { + fprintf (stderr, "ImageTool: Unknown output format of file %s\n", SymbolsPath); + ToolImageDestruct (&ImageInfo); + return NULL; + } + } + + if (Type != -1) { + ImageInfo.HeaderInfo.Subsystem = (uint16_t)Type; + } + + if (HiiFile != NULL) { + free (ImageInfo.HiiInfo.Data); + + ImageInfo.HiiInfo.Data = HiiFile; + ImageInfo.HiiInfo.DataSize = HiiFileSize; + } + + ToolImageSortRelocs (&ImageInfo); + + Success = CheckToolImage (&ImageInfo); + if (!Success) { + ToolImageDestruct (&ImageInfo); + return NULL; + } + + if (Relocate) { + Success = ToolImageRelocate (&ImageInfo, BaseAddress); + if (!Success) { + fprintf (stderr, "ImageTool: Failed to relocate input file %s\n", SymbolsPath); + ToolImageDestruct (&ImageInfo); + return NULL; + } + } + + if (FixedAddress) { + ImageInfo.HeaderInfo.FixedAddress = true; + } + + OutputFile = NULL; + if (Format == UefiImageFormatPe) { + OutputFile = ToolImageEmitPe (&ImageInfo, OutputFileSize, Strip); + } else { + assert (false); + } + + Status = ValidateOutputFile (OutputFile, *OutputFileSize, &ImageInfo); + + ToolImageDestruct (&ImageInfo); + + if (EFI_ERROR (Status)) { + assert (false); + return NULL; + } + + return OutputFile; +} diff --git a/BaseTools/ImageTool/ImageToolEmit.h b/BaseTools/ImageTool/ImageToolEmit.h new file mode 100644 index 0000000000..6bf7493f3f --- /dev/null +++ b/BaseTools/ImageTool/ImageToolEmit.h @@ -0,0 +1,29 @@ +/** @file + Copyright (c) 2023, Marvin Häuser. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef IMAGE_TOOL_EMIT_H +#define IMAGE_TOOL_EMIT_H + +#include + +#include + +void * +ToolImageEmit ( + OUT uint32_t *OutputFileSize, + IN const void *Buffer, + IN uint32_t BufferSize, + IN int8_t Format, + IN int32_t Type, + IN void *HiiFile, + IN uint32_t HiiFileSize, + IN bool Relocate, + IN uint64_t BaseAddress, + IN const char *SymbolsPath OPTIONAL, + IN bool Strip, + IN bool FixedAddress + ); + +#endif // IMAGE_TOOL_EMIT_H diff --git a/BaseTools/ImageTool/Makefile b/BaseTools/ImageTool/Makefile new file mode 100644 index 0000000000..76e9479d96 --- /dev/null +++ b/BaseTools/ImageTool/Makefile @@ -0,0 +1,108 @@ +## @file +# Windows makefile for 'ImageTool' module build. +# +# Copyright (c) 2022, Mikhail Krichanov. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause +# +!INCLUDE ..\Source\C\Makefiles\ms.common + +APP = ImageTool + +OC_USER = ..\..\OpenCorePkg +UDK_PATH = ..\.. +UDK_ARCH = $(HOST_ARCH) +OUT_DIR = .\Windows + +OV = $(UDK_PATH)\MdePkg\Library\BaseOverflowLib +PE = $(UDK_PATH)\MdePkg\Library\BasePeCoffLib2 +UA = $(UDK_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull + +OBJECTS = ImageTool.obj Image.obj PeEmit32.obj PeEmit64.obj PeEmitCommon.obj UefiImageScan.obj PeScan.obj ElfScan32.obj ElfScan64.obj ElfScanCommon.obj BinEmit.obj ImageToolEmit.obj +OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UA)}UefiImageExtraActionLib.obj +OBJECTS = $(OBJECTS) {$(PE)}PeCoffInit.obj PeCoffInfo.obj PeCoffRelocate.obj PeCoffLoad.obj PeCoffHii.obj PeCoffDebug.obj PeCoffHash.obj + +BASE = $(UDK_PATH)\MdePkg\Library\BaseLib +OUT = $(UDK_PATH)\MdePkg\Library\UefiDebugLibConOut +PRIN = $(UDK_PATH)\MdePkg\Library\BasePrintLib +ERRO = $(UDK_PATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib +UIMG = $(UDK_PATH)\MdePkg\Library\BaseUefiImageLib +BMPN = $(UDK_PATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull +CMEM = $(UDK_PATH)\MdeModulePkg\Library\CommonMemoryAllocationLib +USER = $(OC_USER)\User\Library +OBJECTS = $(OBJECTS) {$(BASE)}SafeString.obj String.obj SwapBytes16.obj SwapBytes32.obj CpuDeadLoop.obj CheckSum.obj QuickSort.obj LinkedList.obj +OBJECTS = $(OBJECTS) {$(OUT)}DebugLib.obj {$(PRIN)}PrintLib.obj PrintLibInternal.obj {$(ERRO)}BaseDebugPrintErrorLevelLib.obj +OBJECTS = $(OBJECTS) {$(UIMG)}UefiImageLibPeCoff.obj PeCoffSupport.obj CommonSupport.obj +OBJECTS = $(OBJECTS) {$(USER)}UserFile.obj UserBaseMemoryLib.obj UserMath.obj UserPcd.obj UserMisc.obj UserGlobalVar.obj UserBootServices.obj +OBJECTS = $(OBJECTS) {$(BMPN)}BaseMemoryProfileLibNull.obj {$(CMEM)}CommonMemoryAllocationLib.obj {$(CMEM)}CommonMemoryAllocationLibEx.obj + +INC = -I . -I $(OC_USER)\User\Include -I $(OC_USER)\Include\Acidanthera +INC = $(INC) -I $(UDK_PATH)\MdePkg\Include -I $(UDK_PATH)\MdePkg\Include\Library -I $(UDK_PATH)\MdePkg\Include\$(UDK_ARCH) +INC = $(INC) -I $(UDK_PATH)\MdePkg\Library\BaseLib -I $(UDK_PATH)\MdeModulePkg\Include -I $(UDK_PATH)\UefiCpuPkg\Include +INC = $(INC) /FI $(OC_USER)\User\Include\UserPcd.h /FI $(UDK_PATH)\MdePkg\Include\Base.h /FI $(OC_USER)\User\Include\UserGlobalVar.h + +all: + -if not exist $(OUT_DIR) mkdir $(OUT_DIR) + $(MAKE) $(APP) + +$(APP) : $(OBJECTS) + -@if not exist $(BIN_PATH) mkdir $(BIN_PATH) + @cd $(OUT_DIR) + $(LD) /nologo /debug /OPT:REF /OPT:ICF=10 /incremental:no /nodefaultlib:libc.lib /out:..\$@ $(LIBS) $** + @copy /y ..\$@ $(BIN_PATH)\$@.exe + +.PHONY:clean +.PHONY:cleanall + +clean: + del /f /q $(OUT_DIR) $(APP) *.pdb > nul + +cleanall: + del /f /q $(OUT_DIR) *.pdb $(BIN_PATH)\$(APP).exe > nul + +.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(OV)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(PE)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(UA)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(BASE)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) /wd 4005 $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(BMPN)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(CMEM)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(OUT)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(PRIN)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) /wd 4005 $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(ERRO)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(UIMG)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(USER)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) /D WIN32 /wd 4754 $< -Fo$@ + @move $@ $(OUT_DIR)\ diff --git a/BaseTools/ImageTool/PeEmit.c b/BaseTools/ImageTool/PeEmit.c new file mode 100644 index 0000000000..ef4ffb30df --- /dev/null +++ b/BaseTools/ImageTool/PeEmit.c @@ -0,0 +1,1036 @@ +/** @file + Copyright (c) 2021, Marvin Häuser. All rights reserved. + Copyright (c) 2022, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include "ImageTool.h" + +#if PE_ARCH == 32 + +#define EFI_IMAGE_NT_HEADERS EFI_IMAGE_NT_HEADERS32 +#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC + +#elif PE_ARCH == 64 + +#define EFI_IMAGE_NT_HEADERS EFI_IMAGE_NT_HEADERS64 +#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC + +#endif + +#define PE_SUFFIX__(Name, Arch) Name##Arch +#define PE_SUFFIX_(Name, Arch) PE_SUFFIX__ (Name, Arch) +#define PE_SUFFIX(Name) PE_SUFFIX_ (Name, PE_ARCH) + +typedef struct { + uint8_t NumExtraSections; + uint32_t SizeOfHeaders; + uint8_t NumberOfRvaAndSizes; + uint16_t SizeOfOptionalHeader; + uint32_t SectionHeadersSize; + uint32_t ExtraSectionHeadersSize; +} image_tool_emit_pe_hdr_info_t; + +typedef struct { + const image_tool_image_info_t *Image; + EFI_IMAGE_NT_HEADERS *PeHdr; + image_tool_emit_pe_hdr_info_t HdrInfo; + uint32_t SectionsSize; + uint32_t HiiSectionAddress; + uint32_t ExtraSectionsSize; + uint32_t UnsignedFileSize; + uint32_t RelocTableSize; + uint32_t DebugTableSize; + uint32_t FileAlignment; +} image_tool_pe_emit_context_t; + +#define EmitPeGetHeaderSizes PE_SUFFIX (EmitPeGetHeaderSizes) +static +bool +EmitPeGetHeaderSizes ( + const image_tool_image_info_t *Image, + image_tool_emit_pe_hdr_info_t *HdrInfo + ) +{ + assert (Image != NULL); + assert (HdrInfo != NULL); + + if (Image->RelocInfo.NumRelocs > 0) { + HdrInfo->ExtraSectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER); + } + + if (Image->HiiInfo.DataSize > 0) { + HdrInfo->ExtraSectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER); + } + + if (Image->DebugInfo.SymbolsPath != NULL) { + HdrInfo->ExtraSectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER); + } + + HdrInfo->SectionHeadersSize = (uint32_t)Image->SegmentInfo.NumSegments * sizeof (EFI_IMAGE_SECTION_HEADER); + HdrInfo->NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES; + HdrInfo->SizeOfOptionalHeader = sizeof (EFI_IMAGE_NT_HEADERS) - sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR) + + HdrInfo->NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY); + HdrInfo->SizeOfHeaders = sizeof (EFI_IMAGE_DOS_HEADER) + sizeof (EFI_IMAGE_NT_HEADERS) + + HdrInfo->NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY) + + HdrInfo->SectionHeadersSize + HdrInfo->ExtraSectionHeadersSize; + + return true; +} + +#define EmitPeGetSectionsSize PE_SUFFIX (EmitPeGetSectionsSize) +static +bool +EmitPeGetSectionsSize ( + const image_tool_pe_emit_context_t *Context, + uint32_t *SectionsSize + ) +{ + const image_tool_image_info_t *Image; + uint8_t Index; + uint32_t DataSize; + bool Overflow; + + assert (Context != NULL); + assert (SectionsSize != NULL); + + Image = Context->Image; + *SectionsSize = 0; + + for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { + Overflow = BaseOverflowAlignUpU32 ( + Image->SegmentInfo.Segments[Index].UnpaddedSize, + Context->FileAlignment, + &DataSize + ); + if (Overflow) { + raise (); + return false; + } + + Overflow = BaseOverflowAddU32 (*SectionsSize, DataSize, SectionsSize); + if (Overflow) { + raise (); + return false; + } + } + + return true; +} + +#define EmitPeGetRelocSectionSize PE_SUFFIX (EmitPeGetRelocSectionSize) +static +bool +EmitPeGetRelocSectionSize ( + const image_tool_image_info_t *Image, + uint32_t *RelocsSize + ) +{ + uint32_t RelocTableSize; + uint32_t BlockAddress; + uint32_t BlockSize; + uint32_t Index; + uint32_t RelocAddress; + + assert (Image != NULL); + assert (RelocsSize != NULL); + + if (Image->RelocInfo.NumRelocs == 0) { + *RelocsSize = 0; + return true; + } + + assert (Image->RelocInfo.NumRelocs <= MAX_UINT32); + + RelocTableSize = 0; + BlockAddress = PAGE(Image->RelocInfo.Relocs[0].Target); + BlockSize = sizeof (EFI_IMAGE_BASE_RELOCATION_BLOCK); + + for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) { + RelocAddress = PAGE(Image->RelocInfo.Relocs[Index].Target); + if (RelocAddress != BlockAddress) { + BlockSize = ALIGN_VALUE (BlockSize, 4); + + RelocTableSize += BlockSize; + + BlockAddress = RelocAddress; + BlockSize = sizeof (EFI_IMAGE_BASE_RELOCATION_BLOCK); + } + + BlockSize += sizeof (UINT16); + } + + BlockSize = ALIGN_VALUE (BlockSize, 4); + RelocTableSize += BlockSize; + + *RelocsSize = RelocTableSize; + + return true; +} + +#define EmitPeGetDebugSectionSize PE_SUFFIX (EmitPeGetDebugSectionSize) +static +void +EmitPeGetDebugSectionSize ( + const image_tool_image_info_t *Image, + uint32_t *DebugSize + ) +{ + uint32_t Size; + + assert (Image != NULL); + assert (DebugSize != NULL); + + Size = 0; + if (Image->DebugInfo.SymbolsPath != NULL) { + Size = sizeof (DebugData) + Image->DebugInfo.SymbolsPathLen + 1; + } + + *DebugSize = Size; +} + +#define EmitPeGetExtraSectionsSize PE_SUFFIX (EmitPeGetExtraSectionsSize) +static +bool +EmitPeGetExtraSectionsSize ( + image_tool_pe_emit_context_t *Context, + uint32_t *SectionsSize + ) +{ + const image_tool_image_info_t *Image; + bool Result; + uint32_t AlignedRelocTableSize; + bool Overflow; + uint32_t AlignedDebugTableSize; + uint32_t AlignedHiiTableSize; + + assert (Context != NULL); + assert (SectionsSize != NULL); + + Image = Context->Image; + + Result = EmitPeGetRelocSectionSize (Image, &Context->RelocTableSize); + if (!Result) { + raise (); + return false; + } + + EmitPeGetDebugSectionSize (Image, &Context->DebugTableSize); + + Overflow = BaseOverflowAlignUpU32 ( + Context->RelocTableSize, + Context->FileAlignment, + &AlignedRelocTableSize + ); + if (Overflow) { + raise (); + return false; + } + + Overflow = BaseOverflowAlignUpU32 ( + Context->DebugTableSize, + Context->FileAlignment, + &AlignedDebugTableSize + ); + if (Overflow) { + raise (); + return false; + } + + AlignedHiiTableSize = 0; + if (Context->Image->HiiInfo.DataSize > 0) { + Overflow = BaseOverflowAddU32 ( + mHiiResourceSectionHeaderSize, + Context->Image->HiiInfo.DataSize, + &AlignedHiiTableSize + ); + + Overflow |= BaseOverflowAlignUpU32 ( + AlignedHiiTableSize, + Context->FileAlignment, + &AlignedHiiTableSize + ); + if (Overflow) { + raise (); + return false; + } + } + + Overflow = BaseOverflowAddU32 ( + AlignedRelocTableSize, + AlignedDebugTableSize, + SectionsSize + ); + if (Overflow) { + raise (); + return false; + } + + Overflow = BaseOverflowAddU32 ( + *SectionsSize, + AlignedHiiTableSize, + SectionsSize + ); + if (Overflow) { + raise (); + return false; + } + + return true; +} + +#define ToolImageEmitPeSectionHeaders PE_SUFFIX (ToolImageEmitPeSectionHeaders) +static +bool +ToolImageEmitPeSectionHeaders ( + const image_tool_pe_emit_context_t *Context, + uint8_t **Buffer, + uint32_t *BufferSize, + uint32_t AlignedHeaderSize + ) +{ + const image_tool_image_info_t *Image; + uint16_t SectionHeadersSize; + uint32_t SectionOffset; + EFI_IMAGE_SECTION_HEADER *Sections; + uint8_t Index; + + assert (Context != NULL); + assert (Buffer != NULL); + assert (BufferSize != NULL); + + Image = Context->Image; + SectionHeadersSize = (uint16_t) (Image->SegmentInfo.NumSegments * sizeof (EFI_IMAGE_SECTION_HEADER)); + SectionOffset = AlignedHeaderSize; + Sections = (void *) *Buffer; + + assert (SectionHeadersSize <= *BufferSize); + + for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { + assert (Sections[Index].Characteristics == 0); + + if (Image->SegmentInfo.Segments[Index].Read) { + Sections[Index].Characteristics |= EFI_IMAGE_SCN_MEM_READ; + } + + if (Image->SegmentInfo.Segments[Index].Write) { + Sections[Index].Characteristics |= EFI_IMAGE_SCN_MEM_WRITE; + } + + if (Image->SegmentInfo.Segments[Index].Execute) { + Sections[Index].Characteristics |= EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_CNT_CODE; + } else { + Sections[Index].Characteristics |= EFI_IMAGE_SCN_CNT_INITIALIZED_DATA; + } + + Sections[Index].PointerToRawData = SectionOffset; + Sections[Index].VirtualAddress = SectionOffset; + Sections[Index].SizeOfRawData = ALIGN_VALUE (Image->SegmentInfo.Segments[Index].UnpaddedSize, Context->FileAlignment); + Sections[Index].VirtualSize = Image->SegmentInfo.Segments[Index].ImageSize; + + strncpy ( + (char *) Sections[Index].Name, + Image->SegmentInfo.Segments[Index].Name, + sizeof (Sections[Index].Name) + ); + + SectionOffset += Sections[Index].SizeOfRawData; + } + + if (Image->HeaderInfo.FixedAddress) { + for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { + if ((Sections[Index].Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) == 0) { + WriteUnaligned64 ( + (VOID *)&Sections[Index].PointerToRelocations, + Image->HeaderInfo.BaseAddress + ); + break; + } + } + + if (Index == Image->SegmentInfo.NumSegments) { + raise (); + return false; + } + } + + *BufferSize -= SectionHeadersSize; + *Buffer += SectionHeadersSize; + + assert (SectionHeadersSize == Context->HdrInfo.SectionHeadersSize); + + return true; +} + +#define ToolImageEmitPeExtraSectionHeaders PE_SUFFIX (ToolImageEmitPeExtraSectionHeaders) +static +bool +ToolImageEmitPeExtraSectionHeaders ( + image_tool_pe_emit_context_t *Context, + uint8_t **Buffer, + uint32_t *BufferSize, + uint32_t AlignedHeaderSize + ) +{ + uint32_t SectionHeadersSize; + EFI_IMAGE_SECTION_HEADER *Section; + uint32_t SectionOffset; + uint32_t HiiSectionSize; + + assert (Context != NULL); + assert (Buffer != NULL); + assert (BufferSize != NULL); + + SectionHeadersSize = 0; + SectionOffset = AlignedHeaderSize + Context->SectionsSize; + + if (Context->Image->HiiInfo.DataSize > 0) { + ++Context->PeHdr->CommonHeader.FileHeader.NumberOfSections; + + assert (sizeof (EFI_IMAGE_SECTION_HEADER) <= *BufferSize); + + HiiSectionSize = mHiiResourceSectionHeaderSize + Context->Image->HiiInfo.DataSize; + + Section = (void *) *Buffer; + + strncpy ((char *)Section->Name, ".rsrc", sizeof (Section->Name)); + Section->SizeOfRawData = ALIGN_VALUE (HiiSectionSize, Context->FileAlignment); + Section->VirtualSize = ALIGN_VALUE (HiiSectionSize, Context->Image->SegmentInfo.SegmentAlignment); + Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_READ; + Section->PointerToRawData = SectionOffset; + Section->VirtualAddress = Section->PointerToRawData; + + Context->HiiSectionAddress = SectionOffset; + + SectionOffset += Section->SizeOfRawData; + + Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = HiiSectionSize; + Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = Section->PointerToRawData; + + *BufferSize -= sizeof (EFI_IMAGE_SECTION_HEADER); + *Buffer += sizeof (EFI_IMAGE_SECTION_HEADER); + SectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER); + } + + if (Context->RelocTableSize > 0) { + ++Context->PeHdr->CommonHeader.FileHeader.NumberOfSections; + + assert (sizeof (EFI_IMAGE_SECTION_HEADER) <= *BufferSize); + + Section = (void *) *Buffer; + + strncpy ((char *)Section->Name, ".reloc", sizeof (Section->Name)); + Section->SizeOfRawData = ALIGN_VALUE (Context->RelocTableSize, Context->FileAlignment); + Section->VirtualSize = Section->SizeOfRawData; + Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA + | EFI_IMAGE_SCN_MEM_DISCARDABLE | EFI_IMAGE_SCN_MEM_READ; + Section->PointerToRawData = SectionOffset; + Section->VirtualAddress = Section->PointerToRawData; + + SectionOffset += Section->SizeOfRawData; + + Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = Context->RelocTableSize; + Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Section->PointerToRawData; + + *BufferSize -= sizeof (EFI_IMAGE_SECTION_HEADER); + *Buffer += sizeof (EFI_IMAGE_SECTION_HEADER); + SectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER); + } + + if (Context->DebugTableSize > 0) { + ++Context->PeHdr->CommonHeader.FileHeader.NumberOfSections; + + assert (sizeof (EFI_IMAGE_SECTION_HEADER) <= *BufferSize); + + Section = (void *) *Buffer; + + strncpy ((char *)Section->Name, ".debug", sizeof (Section->Name)); + Section->SizeOfRawData = ALIGN_VALUE (Context->DebugTableSize, Context->FileAlignment); + Section->VirtualSize = Section->SizeOfRawData; + Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_READ; + Section->PointerToRawData = SectionOffset; + Section->VirtualAddress = Section->PointerToRawData; + + SectionOffset += Section->SizeOfRawData; + + Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); + Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = Section->VirtualAddress; + + *BufferSize -= sizeof (EFI_IMAGE_SECTION_HEADER); + *Buffer += sizeof (EFI_IMAGE_SECTION_HEADER); + SectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER); + } + + assert (SectionHeadersSize == Context->HdrInfo.ExtraSectionHeadersSize); + assert (SectionOffset == Context->UnsignedFileSize); + + return true; +} + +#define ToolImageEmitPeHeaders PE_SUFFIX (ToolImageEmitPeHeaders) +static +bool +ToolImageEmitPeHeaders ( + image_tool_pe_emit_context_t *Context, + uint8_t **Buffer, + uint32_t *BufferSize, + uint32_t AlignedHeaderSize + ) +{ + const image_tool_image_info_t *Image; + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_NT_HEADERS *PePlusHdr; + bool Result; + uint32_t HeaderPadding; + + assert (Context != NULL); + assert (Buffer != NULL); + assert (BufferSize != NULL); + + assert (sizeof (EFI_IMAGE_DOS_HEADER) <= *BufferSize); + + Image = Context->Image; + DosHdr = (void *) *Buffer; + + DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE; + DosHdr->e_lfanew = sizeof (EFI_IMAGE_DOS_HEADER); + + *BufferSize -= sizeof (EFI_IMAGE_DOS_HEADER); + *Buffer += sizeof (EFI_IMAGE_DOS_HEADER); + + assert (sizeof (EFI_IMAGE_NT_HEADERS) <= *BufferSize); + + PePlusHdr = (EFI_IMAGE_NT_HEADERS *)(VOID *) *Buffer; + + PePlusHdr->CommonHeader.Signature = EFI_IMAGE_NT_SIGNATURE; + PePlusHdr->CommonHeader.FileHeader.Machine = Image->HeaderInfo.Machine; + PePlusHdr->CommonHeader.FileHeader.NumberOfSections = (UINT16)Image->SegmentInfo.NumSegments; + PePlusHdr->CommonHeader.FileHeader.SizeOfOptionalHeader = Context->HdrInfo.SizeOfOptionalHeader; + PePlusHdr->CommonHeader.FileHeader.Characteristics = + EFI_IMAGE_FILE_EXECUTABLE_IMAGE | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED | + EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; + + if (Image->RelocInfo.RelocsStripped) { + PePlusHdr->CommonHeader.FileHeader.Characteristics |= EFI_IMAGE_FILE_RELOCS_STRIPPED; + } + + PePlusHdr->Magic = EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC; + PePlusHdr->AddressOfEntryPoint = Image->HeaderInfo.EntryPointAddress; + PePlusHdr->SectionAlignment = Image->SegmentInfo.SegmentAlignment; + PePlusHdr->FileAlignment = Context->FileAlignment; + PePlusHdr->SizeOfHeaders = AlignedHeaderSize; + PePlusHdr->SizeOfImage = AlignedHeaderSize; + PePlusHdr->ImageBase = (UINTN)Image->HeaderInfo.BaseAddress; + PePlusHdr->Subsystem = Image->HeaderInfo.Subsystem; + PePlusHdr->NumberOfRvaAndSizes = Context->HdrInfo.NumberOfRvaAndSizes; + + STATIC_ASSERT( + OFFSET_OF(EFI_IMAGE_NT_HEADERS, DataDirectory) == sizeof (EFI_IMAGE_NT_HEADERS), + "The following code needs to be updated to consider padding." + ); + + Context->PeHdr = PePlusHdr; + + *BufferSize -= sizeof (EFI_IMAGE_NT_HEADERS) + PePlusHdr->NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY); + *Buffer += sizeof (EFI_IMAGE_NT_HEADERS) + PePlusHdr->NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY); + + Result = ToolImageEmitPeSectionHeaders (Context, Buffer, BufferSize, AlignedHeaderSize); + if (!Result) { + return false; + } + + Result = ToolImageEmitPeExtraSectionHeaders (Context, Buffer, BufferSize, AlignedHeaderSize); + if (!Result) { + return false; + } + + HeaderPadding = AlignedHeaderSize - Context->HdrInfo.SizeOfHeaders; + + assert (HeaderPadding <= *BufferSize); + + *BufferSize -= HeaderPadding; + *Buffer += HeaderPadding; + + return true; +} + +#define ToolImageEmitPeSections PE_SUFFIX (ToolImageEmitPeSections) +static +bool +ToolImageEmitPeSections ( + const image_tool_pe_emit_context_t *Context, + uint8_t **Buffer, + uint32_t *BufferSize + ) +{ + const image_tool_image_info_t *Image; + uint32_t SectionsSize; + uint8_t Index; + const image_tool_segment_t *Segment; + uint32_t SectionPadding; + bool FirstCode; + +#if PE_ARCH == 32 + bool FirstData; +#endif + + assert (Context != NULL); + assert (Buffer != NULL); + assert (BufferSize != NULL); + + assert (Context->SectionsSize <= *BufferSize); + + Image = Context->Image; + SectionsSize = 0; + FirstCode = true; + +#if PE_ARCH == 32 + FirstData = true; +#endif + + for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { + Segment = &Image->SegmentInfo.Segments[Index]; + + Context->PeHdr->SizeOfImage += Segment->ImageSize; + + if (Segment->Execute) { + if (FirstCode) { + Context->PeHdr->BaseOfCode = Segment->ImageAddress; + FirstCode = false; + } + } +#if PE_ARCH == 32 + else { + if (FirstData) { + Context->PeHdr->BaseOfData = Segment->ImageAddress; + FirstData = false; + } + } +#endif + + assert (Segment->UnpaddedSize <= *BufferSize); + + memmove (*Buffer, Segment->Data, Segment->UnpaddedSize); + + *BufferSize -= Segment->UnpaddedSize; + *Buffer += Segment->UnpaddedSize; + SectionsSize += Segment->UnpaddedSize; + + SectionPadding = ALIGN_VALUE_ADDEND ( + Segment->UnpaddedSize, + Context->FileAlignment + ); + + assert (SectionPadding <= *BufferSize); + + *BufferSize -= SectionPadding; + *Buffer += SectionPadding; + SectionsSize += SectionPadding; + + if (Segment->Execute) { + Context->PeHdr->BaseOfCode = MIN(Context->PeHdr->BaseOfCode, Segment->ImageAddress); + Context->PeHdr->SizeOfCode += Segment->ImageSize; + } else { +#if PE_ARCH == 32 + Context->PeHdr->BaseOfData = MIN(Context->PeHdr->BaseOfData, Segment->ImageAddress); +#endif + Context->PeHdr->SizeOfInitializedData += Segment->ImageSize; + } + } + + assert (SectionsSize == Context->SectionsSize); + + return true; +} + +#define ToolImageEmitPeRelocTable PE_SUFFIX (ToolImageEmitPeRelocTable) +static +bool +ToolImageEmitPeRelocTable ( + const image_tool_pe_emit_context_t *Context, + uint8_t **Buffer, + uint32_t *BufferSize + ) +{ + const image_tool_image_info_t *Image; + uint32_t RelocTableSize; + EFI_IMAGE_BASE_RELOCATION_BLOCK *RelocBlock; + uint32_t BlockAddress; + uint32_t BlockNumRelocs; + uint32_t Index; + uint32_t RelocAddress; + uint32_t RelocTablePadding; + + assert (Context != NULL); + assert (Buffer != NULL); + assert (BufferSize != NULL); + + if (Context->RelocTableSize == 0) { + return true; + } + + Image = Context->Image; + + Context->PeHdr->SizeOfImage += ALIGN_VALUE (Context->RelocTableSize, Image->SegmentInfo.SegmentAlignment); + + assert (Image->RelocInfo.NumRelocs > 0); + assert (Image->RelocInfo.NumRelocs <= MAX_UINT32); + + assert (sizeof (EFI_IMAGE_BASE_RELOCATION_BLOCK) <= *BufferSize); + + RelocTableSize = 0; + RelocBlock = (void *) *Buffer; + BlockAddress = PAGE(Image->RelocInfo.Relocs[0].Target); + BlockNumRelocs = 0; + + RelocBlock->VirtualAddress = BlockAddress; + RelocBlock->SizeOfBlock = sizeof (*RelocBlock); + + for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) { + RelocAddress = PAGE(Image->RelocInfo.Relocs[Index].Target); + if (RelocAddress != BlockAddress) { + RelocBlock->SizeOfBlock = ALIGN_VALUE (RelocBlock->SizeOfBlock, 4); + + assert (RelocBlock->SizeOfBlock <= *BufferSize); + + *BufferSize -= RelocBlock->SizeOfBlock; + *Buffer += RelocBlock->SizeOfBlock; + RelocTableSize += RelocBlock->SizeOfBlock; + + RelocBlock = (void *) *Buffer; + + BlockAddress = RelocAddress; + BlockNumRelocs = 0; + + RelocBlock->VirtualAddress = BlockAddress; + RelocBlock->SizeOfBlock = sizeof (*RelocBlock); + } + + RelocBlock->SizeOfBlock += sizeof (*RelocBlock->Relocations); + + assert (RelocBlock->SizeOfBlock <= *BufferSize); + + RelocBlock->Relocations[BlockNumRelocs] = PAGE_OFF(Image->RelocInfo.Relocs[Index].Target); + RelocBlock->Relocations[BlockNumRelocs] |= ((uint16_t)Image->RelocInfo.Relocs[Index].Type) << 12U; + + ++BlockNumRelocs; + } + + RelocBlock->SizeOfBlock = ALIGN_VALUE (RelocBlock->SizeOfBlock, 4); + + assert (RelocBlock->SizeOfBlock <= *BufferSize); + + *BufferSize -= RelocBlock->SizeOfBlock; + *Buffer += RelocBlock->SizeOfBlock; + RelocTableSize += RelocBlock->SizeOfBlock; + + assert (RelocTableSize == Context->RelocTableSize); + + RelocTablePadding = ALIGN_VALUE_ADDEND ( + RelocTableSize, + Context->FileAlignment + ); + + assert (RelocTablePadding <= *BufferSize); + + *BufferSize -= RelocTablePadding; + *Buffer += RelocTablePadding; + + return true; +} + +typedef struct { + EFI_IMAGE_DEBUG_DIRECTORY_ENTRY CodeViewDirEntry; + EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY CodeViewEntry; + uint8_t PdbPath[]; +} image_tool_debug_dir_t; + +STATIC_ASSERT( + OFFSET_OF(image_tool_debug_dir_t, PdbPath) == sizeof (image_tool_debug_dir_t), + "Flexible array aliases padding." + ); + +#define ToolImageEmitPeDebugTable PE_SUFFIX (ToolImageEmitPeDebugTable) +static +bool +ToolImageEmitPeDebugTable ( + const image_tool_pe_emit_context_t *Context, + uint8_t **Buffer, + uint32_t *BufferSize + ) +{ + const image_tool_image_info_t *Image; + uint32_t DebugTablePadding; + DebugData *Data; + + assert (Context != NULL); + assert (Buffer != NULL); + assert (BufferSize != NULL); + + Image = Context->Image; + + if (Context->DebugTableSize == 0) { + return true; + } + + Context->PeHdr->SizeOfImage += ALIGN_VALUE (Context->DebugTableSize, Image->SegmentInfo.SegmentAlignment); + + assert (Image->DebugInfo.SymbolsPathLen + 1 <= Context->DebugTableSize); + assert (Context->DebugTableSize <= *BufferSize); + + Data = (DebugData *) *Buffer; + + Data->Dir.Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW; + Data->Dir.SizeOfData = sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Image->DebugInfo.SymbolsPathLen + 1; + Data->Dir.RVA = (Context->UnsignedFileSize - ALIGN_VALUE (Context->DebugTableSize, Context->FileAlignment)) + sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); + Data->Dir.FileOffset = Data->Dir.RVA; + + Data->Nb10.Signature = CODEVIEW_SIGNATURE_NB10; + memmove (Data->Name, Image->DebugInfo.SymbolsPath, Image->DebugInfo.SymbolsPathLen + 1); + + assert (sizeof (*Data) + Image->DebugInfo.SymbolsPathLen + 1 == Context->DebugTableSize); + + *BufferSize -= Context->DebugTableSize; + *Buffer += Context->DebugTableSize; + + DebugTablePadding = ALIGN_VALUE_ADDEND( + Context->DebugTableSize, + Context->FileAlignment + ); + + assert (DebugTablePadding <= *BufferSize); + + *BufferSize -= DebugTablePadding; + *Buffer += DebugTablePadding; + + return true; +} + +#define ToolImageEmitPeHiiTable PE_SUFFIX (ToolImageEmitPeHiiTable) +static +bool +ToolImageEmitPeHiiTable ( + const image_tool_pe_emit_context_t *Context, + uint8_t **Buffer, + uint32_t *BufferSize + ) +{ + const image_tool_image_info_t *Image; + uint32_t HiiTablePadding; + + assert (Context != NULL); + assert (Buffer != NULL); + assert (BufferSize != NULL); + + Image = Context->Image; + + if (Image->HiiInfo.DataSize == 0) { + return true; + } + + Context->PeHdr->SizeOfImage += ALIGN_VALUE (mHiiResourceSectionHeaderSize + Image->HiiInfo.DataSize, Image->SegmentInfo.SegmentAlignment); + + assert (mHiiResourceSectionHeaderSize <= *BufferSize); + + InitializeHiiResouceSectionHeader ( + *Buffer, + Context->HiiSectionAddress, + Context->Image->HiiInfo.DataSize + ); + + *BufferSize -= mHiiResourceSectionHeaderSize; + *Buffer += mHiiResourceSectionHeaderSize; + + assert (Image->HiiInfo.DataSize <= *BufferSize); + + memmove (*Buffer, Image->HiiInfo.Data, Image->HiiInfo.DataSize); + + *BufferSize -= Image->HiiInfo.DataSize; + *Buffer += Image->HiiInfo.DataSize; + + HiiTablePadding = ALIGN_VALUE_ADDEND( + mHiiResourceSectionHeaderSize + Image->HiiInfo.DataSize, + Context->FileAlignment + ); + + assert (HiiTablePadding <= *BufferSize); + + *BufferSize -= HiiTablePadding; + *Buffer += HiiTablePadding; + + return true; +} + +#define ToolImageEmitPeExtraSections PE_SUFFIX (ToolImageEmitPeExtraSections) +static +bool +ToolImageEmitPeExtraSections ( + const image_tool_pe_emit_context_t *Context, + uint8_t **Buffer, + uint32_t *BufferSize + ) +{ + uint32_t OldBufferSize; + bool Result; + + assert (Context != NULL); + assert (Buffer != NULL); + assert (BufferSize != NULL); + + OldBufferSize = *BufferSize; + + Result = ToolImageEmitPeHiiTable (Context, Buffer, BufferSize); + if (!Result) { + return false; + } + + Result = ToolImageEmitPeRelocTable (Context, Buffer, BufferSize); + if (!Result) { + return false; + } + + Result = ToolImageEmitPeDebugTable (Context, Buffer, BufferSize); + if (!Result) { + return false; + } + + assert ((OldBufferSize - *BufferSize) == Context->ExtraSectionsSize); + + return true; +} + +#define ToolImageEmitPe PE_SUFFIX (ToolImageEmitPe) +void * +ToolImageEmitPe ( + image_tool_image_info_t *Image, + uint32_t *FileSize + ) +{ + image_tool_pe_emit_context_t Context; + bool Result; + uint32_t AlignedHeaderSize; + bool Overflow; + uint32_t SectionsOffset; + void *FileBuffer; + uint8_t *Buffer; + uint32_t RemainingSize; + uint32_t ExpectedSize; + + assert (Image != NULL); + assert (FileSize != NULL); + + memset (&Context, 0, sizeof (Context)); + + // FIXME: Non-XIP is not well-supported right now. + Context.FileAlignment = Image->SegmentInfo.SegmentAlignment; + Image->HeaderInfo.IsXip = true; + + ImageInitUnpaddedSize (Image); + + Context.Image = Image; + + Result = EmitPeGetHeaderSizes (Image, &Context.HdrInfo); + if (!Result) { + raise (); + return NULL; + } + + Overflow = BaseOverflowAlignUpU32 ( + Context.HdrInfo.SizeOfHeaders, + Context.FileAlignment, + &AlignedHeaderSize + ); + if (Overflow) { + raise (); + return NULL; + } + + if (AlignedHeaderSize > Image->SegmentInfo.Segments[0].ImageAddress) { + raise (); + return NULL; + } + + AlignedHeaderSize = (uint32_t)Image->SegmentInfo.Segments[0].ImageAddress; + + Result = EmitPeGetSectionsSize (&Context, &Context.SectionsSize); + if (!Result) { + raise (); + return NULL; + } + + Overflow = BaseOverflowAddU32 ( + AlignedHeaderSize, + Context.SectionsSize, + &SectionsOffset + ); + if (Overflow) { + raise (); + return NULL; + } + + Result = EmitPeGetExtraSectionsSize (&Context, &Context.ExtraSectionsSize); + if (!Result) { + raise (); + return NULL; + } + + Overflow = BaseOverflowAddU32 ( + SectionsOffset, + Context.ExtraSectionsSize, + &Context.UnsignedFileSize + ); + if (Overflow) { + raise (); + return NULL; + } + + FileBuffer = calloc (1, Context.UnsignedFileSize); + if (FileBuffer == NULL) { + raise (); + return NULL; + } + + Buffer = FileBuffer; + RemainingSize = Context.UnsignedFileSize; + ExpectedSize = Context.UnsignedFileSize; + + Result = ToolImageEmitPeHeaders (&Context, &Buffer, &RemainingSize, AlignedHeaderSize); + if (!Result) { + raise (); + free (FileBuffer); + return NULL; + } + + ExpectedSize -= AlignedHeaderSize; + + assert (RemainingSize == ExpectedSize); + + Result = ToolImageEmitPeSections (&Context, &Buffer, &RemainingSize); + if (!Result) { + raise (); + free (FileBuffer); + return NULL; + } + + ExpectedSize -= Context.SectionsSize; + + assert (RemainingSize == ExpectedSize); + + Result = ToolImageEmitPeExtraSections (&Context, &Buffer, &RemainingSize); + if (!Result) { + raise (); + free (FileBuffer); + return NULL; + } + + ExpectedSize -= Context.ExtraSectionsSize; + + assert (RemainingSize == ExpectedSize); + assert (RemainingSize == 0); + + Context.PeHdr->SizeOfInitializedData += Context.ExtraSectionsSize; + + *FileSize = Context.UnsignedFileSize; + + return FileBuffer; +} diff --git a/BaseTools/ImageTool/PeEmit32.c b/BaseTools/ImageTool/PeEmit32.c new file mode 100644 index 0000000000..65da7c8f93 --- /dev/null +++ b/BaseTools/ImageTool/PeEmit32.c @@ -0,0 +1,7 @@ +/** @file + Copyright (c) 2023, Marvin Häuser. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#define PE_ARCH 32 +#include "PeEmit.c" diff --git a/BaseTools/ImageTool/PeEmit64.c b/BaseTools/ImageTool/PeEmit64.c new file mode 100644 index 0000000000..83448fc8e5 --- /dev/null +++ b/BaseTools/ImageTool/PeEmit64.c @@ -0,0 +1,7 @@ +/** @file + Copyright (c) 2023, Marvin Häuser. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#define PE_ARCH 64 +#include "PeEmit.c" diff --git a/BaseTools/ImageTool/PeEmitCommon.c b/BaseTools/ImageTool/PeEmitCommon.c new file mode 100644 index 0000000000..c136721a19 --- /dev/null +++ b/BaseTools/ImageTool/PeEmitCommon.c @@ -0,0 +1,39 @@ +/** @file + Copyright (c) 2023, Marvin Häuser. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include "PeEmitCommon.h" + +void * +ToolImageEmitPe ( + image_tool_image_info_t *Image, + uint32_t *FileSize, + bool Strip + ) +{ + if (Strip) { + ToolImageStripRelocs (Image); + } + + switch (Image->HeaderInfo.Machine) { + case IMAGE_FILE_MACHINE_I386: + case IMAGE_FILE_MACHINE_ARMTHUMB_MIXED: + { + return ToolImageEmitPe32 (Image, FileSize); + } + + case IMAGE_FILE_MACHINE_X64: + case IMAGE_FILE_MACHINE_ARM64: + { + return ToolImageEmitPe64 (Image, FileSize); + } + + default: + { + assert (false); + } + } + + return NULL; +} diff --git a/BaseTools/ImageTool/PeEmitCommon.h b/BaseTools/ImageTool/PeEmitCommon.h new file mode 100644 index 0000000000..a65761f06f --- /dev/null +++ b/BaseTools/ImageTool/PeEmitCommon.h @@ -0,0 +1,25 @@ +/** @file + Copyright (c) 2023, Marvin Häuser. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef PE_EMIT_COMMON_H +#define PE_EMIT_COMMON_H + +#include + +#include "ImageTool.h" + +void * +ToolImageEmitPe32 ( + const image_tool_image_info_t *Image, + uint32_t *FileSize + ); + +void * +ToolImageEmitPe64 ( + const image_tool_image_info_t *Image, + uint32_t *FileSize + ); + +#endif // PE_EMIT_COMMON_H diff --git a/BaseTools/ImageTool/PeScan.c b/BaseTools/ImageTool/PeScan.c new file mode 100644 index 0000000000..8c7585a2a1 --- /dev/null +++ b/BaseTools/ImageTool/PeScan.c @@ -0,0 +1,295 @@ +/** @file + Copyright (c) 2021, Marvin Häuser. All rights reserved. + Copyright (c) 2022, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include "ImageTool.h" + +#define PE_COFF_SECT_NAME_RELOC ".reloc\0" +#define PE_COFF_SECT_NAME_RESRC ".rsrc\0\0" +#define PE_COFF_SECT_NAME_DEBUG ".debug\0" + +bool +ScanPeGetRelocInfo ( + OUT image_tool_reloc_info_t *RelocInfo, + IN PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + BOOLEAN Overflow; + UINT32 RelocBlockRvaMax; + UINT32 TopOfRelocDir; + UINT32 RelocBlockRva; + const EFI_IMAGE_BASE_RELOCATION_BLOCK *RelocBlock; + UINT32 RelocBlockSize; + UINT32 SizeOfRelocs; + UINT32 NumRelocs; + UINT32 RelocIndex; + uint32_t RelocDirSize; + const char *ImageBuffer; + UINT16 RelocType; + UINT16 RelocOffset; + + assert (RelocInfo != NULL); + assert (Context != NULL); + + // FIXME: PE/COFF context access + RelocBlockRva = Context->RelocDirRva; + RelocDirSize = Context->RelocDirSize; + // + // Verify the Relocation Directory is not empty. + // + if (RelocDirSize == 0) { + return true; + } + + RelocInfo->Relocs = calloc (RelocDirSize / sizeof (UINT16), sizeof (*RelocInfo->Relocs)); + if (RelocInfo->Relocs == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for Relocs[]\n"); + return false; + } + + TopOfRelocDir = RelocBlockRva + RelocDirSize; + + RelocBlockRvaMax = TopOfRelocDir - sizeof (EFI_IMAGE_BASE_RELOCATION_BLOCK); + // + // Align TopOfRelocDir because, if the policy does not demand Relocation Block + // sizes to be aligned, the code below will manually align them. Thus, the + // end offset of the last Relocation Block must be compared to a manually + // aligned Relocation Directoriy end offset. + // + Overflow = BaseOverflowAlignUpU32 ( + TopOfRelocDir, + ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK), + &TopOfRelocDir + ); + if (Overflow) { + fprintf (stderr, "ImageTool: Overflow during TopOfRelocDir calculation\n"); + return false; + } + // + // Apply all Base Relocations of the Image. + // + ImageBuffer = (char *)PeCoffLoaderGetImageAddress (Context); + while (RelocBlockRva <= RelocBlockRvaMax) { + RelocBlock = (const EFI_IMAGE_BASE_RELOCATION_BLOCK *)(const void *)(ImageBuffer + RelocBlockRva); + // + // Verify the Base Relocation Block size is well-formed. + // + Overflow = BaseOverflowSubU32 ( + RelocBlock->SizeOfBlock, + sizeof (EFI_IMAGE_BASE_RELOCATION_BLOCK), + &SizeOfRelocs + ); + if (Overflow) { + fprintf (stderr, "ImageTool: Overflow during SizeOfRelocs calculation\n"); + return false; + } + // + // Verify the Base Relocation Block is in bounds of the Relocation + // Directory. + // + if (SizeOfRelocs > RelocBlockRvaMax - RelocBlockRva) { + fprintf (stderr, "ImageTool: Base Relocation Block is out of bounds of the Relocation Directory\n"); + return false; + } + // + // This arithmetic cannot overflow because we know + // 1) RelocBlock->SizeOfBlock <= RelocMax <= TopOfRelocDir + // 2) IS_ALIGNED (TopOfRelocDir, ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK)). + // + RelocBlockSize = ALIGN_VALUE ( + RelocBlock->SizeOfBlock, + ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK) + ); + // + // This division is safe due to the guarantee made above. + // + NumRelocs = SizeOfRelocs / sizeof (*RelocBlock->Relocations); + // + // Process all Base Relocations of the current Block. + // + for (RelocIndex = 0; RelocIndex < NumRelocs; ++RelocIndex) { + RelocType = IMAGE_RELOC_TYPE (RelocBlock->Relocations[RelocIndex]); + RelocOffset = IMAGE_RELOC_OFFSET (RelocBlock->Relocations[RelocIndex]); + + // FIXME: Make separate functions for UE + switch (RelocType) { + case EFI_IMAGE_REL_BASED_ABSOLUTE: + continue; + case EFI_IMAGE_REL_BASED_HIGHLOW: + case EFI_IMAGE_REL_BASED_DIR64: + RelocInfo->Relocs[RelocInfo->NumRelocs].Type = (uint8_t)RelocType; + break; + default: + fprintf (stderr, "ImageTool: Unknown RelocType = 0x%x\n", RelocType); + return false; + } + + RelocInfo->Relocs[RelocInfo->NumRelocs].Target = RelocBlock->VirtualAddress + RelocOffset; + ++RelocInfo->NumRelocs; + } + // + // This arithmetic cannot overflow because it has been checked that the + // Image Base Relocation Block is in bounds of the Image buffer. + // + RelocBlockRva += RelocBlockSize; + } + // + // Verify the Relocation Directory size matches the contained data. + // + if (RelocBlockRva != TopOfRelocDir) { + fprintf (stderr, "ImageTool: Relocation Directory size does not match the contained data\n"); + return false; + } + + return true; +} + +bool +ScanPeGetSegmentInfo ( + OUT image_tool_segment_info_t *SegmentInfo, + IN PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + const EFI_IMAGE_SECTION_HEADER *Section; + uint32_t NumSections; + image_tool_segment_t *ImageSegment; + const char *ImageBuffer; + uint32_t Index; + + assert (SegmentInfo != NULL); + assert (Context != NULL); + + NumSections = PeCoffGetSectionTable (Context, &Section); + + SegmentInfo->Segments = calloc (NumSections, sizeof (*SegmentInfo->Segments)); + if (SegmentInfo->Segments == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for Segments[]\n"); + return false; + } + + ImageBuffer = (char *)PeCoffLoaderGetImageAddress (Context); + + ImageSegment = SegmentInfo->Segments; + for (Index = 0; Index < NumSections; ++Index, ++Section) { + STATIC_ASSERT ( + sizeof(PE_COFF_SECT_NAME_RELOC) == sizeof(Section->Name) && + sizeof(PE_COFF_SECT_NAME_RESRC) == sizeof(Section->Name) && + sizeof(PE_COFF_SECT_NAME_DEBUG) == sizeof(Section->Name), + "Section names exceed section name bounds." + ); + + if ((Section->Characteristics & EFI_IMAGE_SCN_MEM_DISCARDABLE) == 0 + && memcmp (Section->Name, PE_COFF_SECT_NAME_RELOC, sizeof (Section->Name)) != 0 + && memcmp (Section->Name, PE_COFF_SECT_NAME_RESRC, sizeof (Section->Name)) != 0 + && memcmp (Section->Name, PE_COFF_SECT_NAME_DEBUG, sizeof (Section->Name)) != 0) { + ImageSegment->Name = calloc (1, sizeof (Section->Name)); + if (ImageSegment->Name == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for Segment Name\n"); + return false; + } + + memmove (ImageSegment->Name, Section->Name, sizeof (Section->Name)); + + ImageSegment->ImageAddress = Section->VirtualAddress; + ImageSegment->ImageSize = ALIGN_VALUE (Section->VirtualSize, SegmentInfo->SegmentAlignment); + ImageSegment->Read = (Section->Characteristics & EFI_IMAGE_SCN_MEM_READ) != 0; + ImageSegment->Write = (Section->Characteristics & EFI_IMAGE_SCN_MEM_WRITE) != 0; + ImageSegment->Execute = (Section->Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) != 0; + + ImageSegment->Data = malloc (ImageSegment->ImageSize); + if (ImageSegment->Data == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for Segment Data\n"); + free (ImageSegment->Name); + return false; + } + + memmove ( + ImageSegment->Data, + ImageBuffer + Section->VirtualAddress, + ImageSegment->ImageSize + ); + + ++SegmentInfo->NumSegments; + ++ImageSegment; + } + } + + return true; +} + +bool +ScanPeGetDebugInfo ( + OUT image_tool_debug_info_t *DebugInfo, + IN PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + const CHAR8 *PdbPath; + UINT32 PdbPathSize; + RETURN_STATUS Status; + + assert (DebugInfo != NULL); + assert (Context != NULL); + + Status = PeCoffGetPdbPath (Context, &PdbPath, &PdbPathSize); + if (Status == RETURN_NOT_FOUND) { + return true; + } + if (RETURN_ERROR (Status)) { + fprintf (stderr, "ImageTool: Could not get PdbPath\n"); + return false; + } + + DebugInfo->SymbolsPath = malloc (PdbPathSize); + if (DebugInfo->SymbolsPath == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for SymbolsPath\n"); + return false; + } + + memmove (DebugInfo->SymbolsPath, PdbPath, PdbPathSize); + + assert (PdbPathSize >= 1); + assert (DebugInfo->SymbolsPath[PdbPathSize - 1] == '\0'); + + DebugInfo->SymbolsPathLen = PdbPathSize - 1; + + return true; +} + +bool +ScanPeGetHiiInfo ( + OUT image_tool_hii_info_t *HiiInfo, + IN PE_COFF_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINT32 HiiRva; + UINT32 HiiSize; + RETURN_STATUS Status; + const char *ImageBuffer; + + assert (HiiInfo != NULL); + assert (Context != NULL); + + Status = PeCoffGetHiiDataRva (Context, &HiiRva, &HiiSize); + if (Status == RETURN_NOT_FOUND) { + return true; + } + if (RETURN_ERROR (Status)) { + fprintf (stderr, "ImageTool: Could not get HiiRva\n"); + return false; + } + + HiiInfo->Data = calloc (1, HiiSize); + if (HiiInfo->Data == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for HiiInfo Data\n"); + return false; + } + + ImageBuffer = (char *)PeCoffLoaderGetImageAddress (Context); + + memmove (HiiInfo->Data, ImageBuffer + HiiRva, HiiSize); + HiiInfo->DataSize = HiiSize; + + return true; +} diff --git a/BaseTools/ImageTool/PeScan.h b/BaseTools/ImageTool/PeScan.h new file mode 100644 index 0000000000..bdcf2078f8 --- /dev/null +++ b/BaseTools/ImageTool/PeScan.h @@ -0,0 +1,23 @@ +/** @file + Copyright (c) 2023, Marvin Häuser. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef PE_SCAN_H +#define PE_SCAN_H + +#include "ImageTool.h" + +bool +ScanPeGetRelocInfo ( + OUT image_tool_reloc_info_t *RelocInfo, + IN PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +bool +ScanPeGetSegmentInfo ( + OUT image_tool_segment_info_t *SegmentInfo, + IN PE_COFF_LOADER_IMAGE_CONTEXT *Context + ); + +#endif // PE_SCAN_H diff --git a/BaseTools/ImageTool/UefiImageScan.c b/BaseTools/ImageTool/UefiImageScan.c new file mode 100644 index 0000000000..c02a62b7e9 --- /dev/null +++ b/BaseTools/ImageTool/UefiImageScan.c @@ -0,0 +1,279 @@ +/** @file + Copyright (c) 2023, Marvin Häuser. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include "ImageTool.h" + +#include + +#include + +#include "PeScan.h" + +static +bool +ScanUefiImageGetHeaderInfo ( + OUT image_tool_header_info_t *HeaderInfo, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + RETURN_STATUS Status; + UINT64 Address; + + assert (HeaderInfo != NULL); + assert (Context != NULL); + + HeaderInfo->BaseAddress = UefiImageGetPreferredAddress (Context); + HeaderInfo->EntryPointAddress = UefiImageGetEntryPointAddress (Context); + HeaderInfo->Machine = UefiImageGetMachine (Context); + HeaderInfo->Subsystem = UefiImageGetSubsystem (Context); + // FIXME: + HeaderInfo->IsXip = true; + + Status = UefiImageGetFixedAddress (Context, &Address); + if (!RETURN_ERROR (Status)) { + if (Address != HeaderInfo->BaseAddress) { + fprintf ( + stderr, + "ImageTool: Images with a fixed address different from their base address are not supported.\n" + ); + return false; + } + + HeaderInfo->FixedAddress = true; + } else if (Status != RETURN_NOT_FOUND) { + return false; + } + + return true; +} + +static +bool +ScanUefiImageGetRelocInfo ( + OUT image_tool_reloc_info_t *RelocInfo, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINT8 FormatIndex; + + assert (RelocInfo != NULL); + assert (Context != NULL); + + FormatIndex = UefiImageGetFormat (Context); + + RelocInfo->RelocsStripped = UefiImageGetRelocsStripped (Context); + + if (FormatIndex == UefiImageFormatPe) { + return ScanPeGetRelocInfo ( + RelocInfo, + (PE_COFF_LOADER_IMAGE_CONTEXT *)Context + ); + } + + fprintf ( + stderr, + "ImageTool: Unsupported UefiImage format %u\n", + FormatIndex + ); + return false; +} + +static +bool +ScanUefiImageGetSegmentInfo ( + OUT image_tool_segment_info_t *SegmentInfo, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINT8 FormatIndex; + + assert (SegmentInfo != NULL); + assert (Context != NULL); + + FormatIndex = UefiImageGetFormat (Context); + + SegmentInfo->SegmentAlignment = UefiImageGetSegmentAlignment (Context); + + if (FormatIndex == UefiImageFormatPe) { + return ScanPeGetSegmentInfo ( + SegmentInfo, + (PE_COFF_LOADER_IMAGE_CONTEXT *)Context + ); + } + + fprintf ( + stderr, + "ImageTool: Unsupported UefiImage format %u\n", + FormatIndex + ); + return false; +} + +bool +ScanUefiImageGetDebugInfo ( + OUT image_tool_debug_info_t *DebugInfo, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + RETURN_STATUS Status; + const CHAR8 *SymbolsPath; + UINT32 SymbolsPathSize; + + assert (DebugInfo != NULL); + assert (Context != NULL); + + Status = UefiImageGetSymbolsPath (Context, &SymbolsPath, &SymbolsPathSize); + if (Status == RETURN_NOT_FOUND) { + return true; + } + if (RETURN_ERROR (Status)) { + fprintf (stderr, "ImageTool: Could not get SymbolsPath\n"); + return false; + } + + assert (SymbolsPathSize >= 1); + + DebugInfo->SymbolsPath = malloc (SymbolsPathSize + 1); + if (DebugInfo->SymbolsPath == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for SymbolsPath\n"); + return false; + } + + memmove (DebugInfo->SymbolsPath, SymbolsPath, SymbolsPathSize); + assert (DebugInfo->SymbolsPath[SymbolsPathSize - 1] == '\0'); + + DebugInfo->SymbolsPathLen = SymbolsPathSize - 1; + + return true; +} + +bool +ScanUefiImageGetHiiInfo ( + OUT image_tool_hii_info_t *HiiInfo, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + RETURN_STATUS Status; + UINT32 HiiRva; + UINT32 HiiSize; + const char *ImageBuffer; + + assert (HiiInfo != NULL); + assert (Context != NULL); + + Status = UefiImageGetHiiDataRva (Context, &HiiRva, &HiiSize); + if (Status == RETURN_NOT_FOUND) { + return true; + } + if (RETURN_ERROR (Status)) { + fprintf (stderr, "ImageTool: Malformed HII data\n"); + return false; + } + + HiiInfo->Data = malloc (HiiSize); + if (HiiInfo->Data == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for HiiInfo Data\n"); + return false; + } + + ImageBuffer = (char *)UefiImageLoaderGetImageAddress (Context); + + memmove (HiiInfo->Data, ImageBuffer + HiiRva, HiiSize); + HiiInfo->DataSize = HiiSize; + + return true; +} + +RETURN_STATUS +ToolContextConstructUefiImage ( + OUT image_tool_image_info_t *Image, + OUT int8_t *Format, + IN const void *File, + IN size_t FileSize + ) +{ + RETURN_STATUS Status; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT Context; + UINT32 ImageSize; + UINT32 ImageAlignment; + UINT32 DestinationPages; + UINT32 DestinationSize; + void *Destination; + bool Success; + + assert (Image != NULL); + assert (File != NULL || FileSize == 0); + + if (FileSize > MAX_UINT32) { + fprintf (stderr, "ImageTool: FileSize is too huge\n"); + return RETURN_UNSUPPORTED; + } + + Status = UefiImageInitializeContext (&Context, File, (UINT32)FileSize); + if (RETURN_ERROR (Status)) { + return Status; + } + + *Format = (int8_t)UefiImageGetFormat (&Context); + + ImageSize = UefiImageGetImageSize (&Context); + DestinationPages = EFI_SIZE_TO_PAGES (ImageSize); + DestinationSize = EFI_PAGES_TO_SIZE (DestinationPages); + ImageAlignment = UefiImageGetSegmentAlignment (&Context); + + Destination = AllocateAlignedCodePages (DestinationPages, ImageAlignment); + if (Destination == NULL) { + fprintf (stderr, "ImageTool: Could not allocate Destination buffer\n"); + return RETURN_OUT_OF_RESOURCES; + } + + Status = UefiImageLoadImage (&Context, Destination, DestinationSize); + if (RETURN_ERROR (Status)) { + fprintf (stderr, "ImageTool: Could not Load Image\n"); + FreeAlignedPages (Destination, DestinationPages); + return RETURN_VOLUME_CORRUPTED; + } + + memset (Image, 0, sizeof (*Image)); + + Success = ScanUefiImageGetHeaderInfo (&Image->HeaderInfo, &Context); + if (!Success) { + fprintf (stderr, "ImageTool: Could not retrieve header info\n"); + FreeAlignedPages (Destination, DestinationPages); + return RETURN_VOLUME_CORRUPTED; + } + + Success = ScanUefiImageGetSegmentInfo (&Image->SegmentInfo, &Context); + if (!Success) { + fprintf (stderr, "ImageTool: Could not retrieve segment info\n"); + FreeAlignedPages (Destination, DestinationPages); + return RETURN_VOLUME_CORRUPTED; + } + + Success = ScanUefiImageGetRelocInfo (&Image->RelocInfo, &Context); + if (!Success) { + fprintf (stderr, "ImageTool: Could not retrieve reloc info\n"); + FreeAlignedPages (Destination, DestinationPages); + return RETURN_VOLUME_CORRUPTED; + } + + Success = ScanUefiImageGetHiiInfo (&Image->HiiInfo, &Context); + if (!Success) { + fprintf (stderr, "ImageTool: Could not retrieve HII info\n"); + FreeAlignedPages (Destination, DestinationPages); + return RETURN_VOLUME_CORRUPTED; + } + + Success = ScanUefiImageGetDebugInfo (&Image->DebugInfo, &Context); + if (!Success) { + fprintf (stderr, "ImageTool: Could not retrieve debug info\n"); + FreeAlignedPages (Destination, DestinationPages); + return RETURN_VOLUME_CORRUPTED; + } + + FreeAlignedPages (Destination, DestinationPages); + + return RETURN_SUCCESS; +} diff --git a/BaseTools/Makefile b/BaseTools/Makefile index 10963009e9..28fa83e4dc 100644 --- a/BaseTools/Makefile +++ b/BaseTools/Makefile @@ -9,13 +9,13 @@ !ERROR "BASE_TOOLS_PATH is not set! Please run toolsetup.bat first!" !ENDIF -SUBDIRS = $(BASE_TOOLS_PATH)\Source\C $(BASE_TOOLS_PATH)\Source\Python +SUBDIRS = $(BASE_TOOLS_PATH)\Source\C $(BASE_TOOLS_PATH)\Source\Python $(BASE_TOOLS_PATH)\ImageTool $(BASE_TOOLS_PATH)\MicroTool all: c c : - @if defined PYTHON_COMMAND $(PYTHON_COMMAND) $(BASE_TOOLS_PATH)\Source\C\Makefiles\NmakeSubdirs.py all $(BASE_TOOLS_PATH)\Source\C - @if not defined PYTHON_COMMAND $(PYTHON_HOME)\python.exe $(BASE_TOOLS_PATH)\Source\C\Makefiles\NmakeSubdirs.py all $(BASE_TOOLS_PATH)\Source\C + @if defined PYTHON_COMMAND $(PYTHON_COMMAND) $(BASE_TOOLS_PATH)\Source\C\Makefiles\NmakeSubdirs.py all $(BASE_TOOLS_PATH)\Source\C $(BASE_TOOLS_PATH)\ImageTool $(BASE_TOOLS_PATH)\MicroTool + @if not defined PYTHON_COMMAND $(PYTHON_HOME)\python.exe $(BASE_TOOLS_PATH)\Source\C\Makefiles\NmakeSubdirs.py all $(BASE_TOOLS_PATH)\Source\C $(BASE_TOOLS_PATH)\ImageTool $(BASE_TOOLS_PATH)\MicroTool subdirs: $(SUBDIRS) @@ -31,4 +31,3 @@ clean: cleanall: @if defined PYTHON_COMMAND $(PYTHON_COMMAND) $(BASE_TOOLS_PATH)\Source\C\Makefiles\NmakeSubdirs.py cleanall $(SUBDIRS) @if not defined PYTHON_COMMAND $(PYTHON_HOME)\python.exe $(BASE_TOOLS_PATH)\Source\C\Makefiles\NmakeSubdirs.py cleanall $(SUBDIRS) - diff --git a/BaseTools/MicroTool/GNUmakefile b/BaseTools/MicroTool/GNUmakefile new file mode 100644 index 0000000000..cce15c2c39 --- /dev/null +++ b/BaseTools/MicroTool/GNUmakefile @@ -0,0 +1,15 @@ +## @file +# Copyright (c) 2022, Mikhail Krichanov. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause +## + +PROJECT = MicroTool +PRODUCT = $(PROJECT)$(INFIX)$(SUFFIX) +OBJS = $(PROJECT).o + +DEBUG = 1 +SANITIZE = 0 +OC_USER = ../../OpenCorePkg +UDK_PATH = ../.. + +include $(OC_USER)/User/Makefile diff --git a/BaseTools/MicroTool/Makefile b/BaseTools/MicroTool/Makefile new file mode 100644 index 0000000000..8df029aff8 --- /dev/null +++ b/BaseTools/MicroTool/Makefile @@ -0,0 +1,84 @@ +## @file +# Windows makefile for 'MicroTool' module build. +# +# Copyright (c) 2022, Mikhail Krichanov. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause +# +!INCLUDE ..\Source\C\Makefiles\ms.common + +APP = MicroTool + +OC_USER = ..\..\OpenCorePkg +UDK_PATH = ..\.. +UDK_ARCH = $(HOST_ARCH) +OUT_DIR = .\Windows + +OBJECTS = MicroTool.obj + +BASE = $(UDK_PATH)\MdePkg\Library\BaseLib +OUT = $(UDK_PATH)\MdePkg\Library\UefiDebugLibConOut +PRIN = $(UDK_PATH)\MdePkg\Library\BasePrintLib +ERRO = $(UDK_PATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib +BMPN = $(UDK_PATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull +CMEM = $(UDK_PATH)\MdeModulePkg\Library\CommonMemoryAllocationLib +USER = $(OC_USER)\User\Library +OBJECTS = $(OBJECTS) {$(BASE)}SafeString.obj String.obj SwapBytes16.obj SwapBytes32.obj CpuDeadLoop.obj CheckSum.obj +OBJECTS = $(OBJECTS) {$(OUT)}DebugLib.obj {$(PRIN)}PrintLib.obj PrintLibInternal.obj {$(ERRO)}BaseDebugPrintErrorLevelLib.obj +OBJECTS = $(OBJECTS) {$(USER)}UserFile.obj UserBaseMemoryLib.obj UserMath.obj UserPcd.obj UserMisc.obj UserGlobalVar.obj UserBootServices.obj +OBJECTS = $(OBJECTS) {$(BMPN)}BaseMemoryProfileLibNull.obj {$(CMEM)}CommonMemoryAllocationLib.obj {$(CMEM)}CommonMemoryAllocationLibEx.obj + +INC = -I . -I $(OC_USER)\User\Include -I $(OC_USER)\Include\Acidanthera +INC = $(INC) -I $(UDK_PATH)\MdePkg\Include -I $(UDK_PATH)\MdePkg\Include\Library -I $(UDK_PATH)\MdePkg\Include\$(UDK_ARCH) +INC = $(INC) -I $(UDK_PATH)\MdePkg\Library\BaseLib -I $(UDK_PATH)\MdeModulePkg\Include -I $(UDK_PATH)\UefiCpuPkg\Include +INC = $(INC) /FI $(OC_USER)\User\Include\UserPcd.h /FI $(UDK_PATH)\MdePkg\Include\Base.h /FI $(OC_USER)\User\Include\UserGlobalVar.h + +all: + -@if not exist $(OUT_DIR) mkdir $(OUT_DIR) + $(MAKE) $(APP) + +$(APP) : $(OBJECTS) + -@if not exist $(BIN_PATH) mkdir $(BIN_PATH) + @cd $(OUT_DIR) + $(LD) /nologo /debug /OPT:REF /OPT:ICF=10 /incremental:no /nodefaultlib:libc.lib /out:..\$@ $(LIBS) $** + @copy /y ..\$@ $(BIN_PATH)\$@.exe + +.PHONY:clean +.PHONY:cleanall + +clean: + del /f /q $(OUT_DIR) $(APP) *.pdb > nul + +cleanall: + del /f /q $(OUT_DIR) *.pdb $(BIN_PATH)\$(APP).exe $(BIN_PATH)\$(APP).exe > nul + +.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(BASE)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) /wd 4005 $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(BMPN)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(CMEM)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(OUT)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(PRIN)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) /wd 4005 $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(ERRO)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + +{$(USER)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) /D WIN32 /wd 4754 $< -Fo$@ + @move $@ $(OUT_DIR)\ diff --git a/BaseTools/MicroTool/MicroTool.c b/BaseTools/MicroTool/MicroTool.c new file mode 100644 index 0000000000..d7431317bc --- /dev/null +++ b/BaseTools/MicroTool/MicroTool.c @@ -0,0 +1,298 @@ +/** @file + Copyright (c) 2022, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include +#include +#include +#include + +#include + +#define DEFAULT_MC_ALIGNMENT 16 +#define DEFAULT_MC_PAD_BYTE_VALUE 0xFF + +typedef struct { + UINT32 HeaderVersion; + UINT32 PatchId; + UINT32 Date; + UINT32 CpuId; + UINT32 Checksum; + UINT32 LoaderVersion; + UINT32 PlatformId; + UINT32 DataSize; // if 0, then TotalSize = 2048, and TotalSize field is invalid + UINT32 TotalSize; // number of bytes + UINT32 Reserved[3]; +} MICROCODE_HEADER; + +static +RETURN_STATUS +TxtToBin ( + IN const char *TxtName, + IN const char *BinName + ) +{ + char *Txt; + char *TxtStart; + uint32_t TxtSize; + UINT32 *Buffer; + UINT32 *BufferStart; + UINT32 FileLength; + UINT32 Index; + MICROCODE_HEADER *Micro; + UINT32 CheckSum; + + assert (TxtName != NULL); + assert (BinName != NULL); + + Txt = (char *)UserReadFile (TxtName, &TxtSize); + if (Txt == NULL) { + fprintf (stderr, "MicroTool: Could not open %s: %s\n", TxtName, strerror (errno)); + return RETURN_ABORTED; + } + + Buffer = calloc (1, TxtSize); + if (Buffer == NULL) { + fprintf (stderr, "MicroTool: Could not allocate memory for Buffer\n"); + free (Txt); + return RETURN_OUT_OF_RESOURCES; + } + + BufferStart = Buffer; + TxtStart = Txt; + FileLength = 0; + for (Index = 0; Index < TxtSize; ++Index, ++Txt) { + // + // Skip Blank Lines and Comment Lines + // + if (isspace ((int)*Txt)) { + continue; + } + + if (*Txt == ';') { + while ((Index < TxtSize) && (*Txt != '\n')) { + ++Index; + ++Txt; + } + + if (Index == TxtSize) { + break; + } + + ++Index; + ++Txt; + } + // + // Look for + // dd 000000001h ; comment + // dd XXXXXXXX + // DD XXXXXXXXX + // DD XXXXXXXXX + // + if (((Index + 2) < TxtSize) && (tolower ((int)Txt[0]) == 'd') && (tolower ((int)Txt[1]) == 'd') && isspace ((int)Txt[2])) { + // + // Skip blanks and look for a hex digit + // + Txt += 3; + Index += 3; + while ((Index < TxtSize) && isspace ((int)*Txt)) { + ++Index; + ++Txt; + } + + if (Index == TxtSize) { + break; + } + + if (isxdigit ((int)*Txt)) { + if (sscanf (Txt, "%X", Buffer) != 1) { + fprintf (stderr, "MicroTool: Could not write into Buffer\n"); + free (TxtStart); + free (BufferStart); + return RETURN_ABORTED; + } + + while ((Index < TxtSize) && (*Txt != '\n')) { + ++Index; + ++Txt; + } + } + + ++Buffer; + FileLength += sizeof (*Buffer); + continue; + } + + fprintf (stderr, "MicroTool: Corrupted input file\n"); + break; + } + + free (TxtStart); + + if (FileLength == 0) { + fprintf (stderr, "MicroTool: No parseable data found in file %s\n", TxtName); + free (BufferStart); + return RETURN_INVALID_PARAMETER; + } + + if (FileLength < sizeof (MICROCODE_HEADER)) { + fprintf (stderr, "MicroTool: Amount of parsable data in %s is insufficient to contain a microcode header\n", TxtName); + free (BufferStart); + return RETURN_VOLUME_CORRUPTED; + } + + // + // Can't do much checking on the header because, per the spec, the + // DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K, + // and the TotalSize field is invalid (actually missing). Thus we can't + // even verify the Reserved fields are 0. + // + Micro = (MICROCODE_HEADER *)BufferStart; + if (Micro->DataSize == 0) { + Index = 2048; + } else { + Index = Micro->TotalSize; + } + + if (Index != FileLength) { + fprintf (stderr, "MicroTool: File length of %s (0x%x) does not equal expected TotalSize: 0x%04X\n", TxtName, FileLength, Index); + free (BufferStart); + return RETURN_VOLUME_CORRUPTED; + } + + // + // Checksum the contents + // + Buffer = BufferStart; + CheckSum = 0; + Index = 0; + while (Index < FileLength) { + CheckSum += *Buffer; + + ++Buffer; + Index += sizeof (*Buffer); + } + + if (CheckSum != 0) { + fprintf (stderr, "MicroTool: Checksum (0x%x) failed on file %s\n", CheckSum, TxtName); + free (BufferStart); + return RETURN_VOLUME_CORRUPTED; + } + + UserWriteFile (BinName, BufferStart, FileLength); + + free (BufferStart); + + return RETURN_SUCCESS; +} + +static +RETURN_STATUS +Merge ( + IN const char *Output, + IN const char *FileNames[], + IN UINT32 NumOfFiles + ) +{ + void *File; + uint32_t FileSize; + UINT32 Index; + UINT32 Total; + char *Buffer; + char *BufferStart; + UINT32 Addend; + + assert (Output != NULL); + assert (FileNames != NULL); + + Total = 0; + + for (Index = 0; Index < NumOfFiles; ++Index) { + File = UserReadFile (FileNames[Index], &FileSize); + if (File == NULL) { + fprintf (stderr, "MicroTool: Could not open %s: %s\n", FileNames[Index], strerror (errno)); + return RETURN_ABORTED; + } + + Total += ALIGN_VALUE (FileSize, DEFAULT_MC_ALIGNMENT); + + free (File); + } + + Buffer = calloc (1, Total); + if (Buffer == NULL) { + fprintf (stderr, "MicroTool: Could not allocate memory for Buffer\n"); + return RETURN_OUT_OF_RESOURCES; + } + + BufferStart = Buffer; + + for (Index = 0; Index < NumOfFiles; ++Index) { + File = UserReadFile (FileNames[Index], &FileSize); + if (File == NULL) { + fprintf (stderr, "MicroTool: Could not reopen %s: %s\n", FileNames[Index], strerror (errno)); + free (BufferStart); + return RETURN_ABORTED; + } + + memcpy (Buffer, File, FileSize); + Buffer += FileSize; + + Addend = ALIGN_VALUE_ADDEND (FileSize, DEFAULT_MC_ALIGNMENT); + memset (Buffer, DEFAULT_MC_PAD_BYTE_VALUE, Addend); + Buffer += Addend; + + free (File); + } + + UserWriteFile (Output, BufferStart, Total); + + free (BufferStart); + + return RETURN_SUCCESS; +} + +int main (int argc, const char *argv[]) +{ + RETURN_STATUS Status; + UINT32 NumOfFiles; + + if (argc < 2) { + fprintf (stderr, "MicroTool: No command is specified\n"); + assert (false); + return -1; + } + + if (strcmp (argv[1], "TxtToBin") == 0) { + if (argc < 4) { + fprintf (stderr, "MicroTool: Command arguments are missing\n"); + fprintf (stderr, " Usage: MicroTool TxtToBin InputFile OutputFile\n"); + assert (false); + return -1; + } + + Status = TxtToBin (argv[2], argv [3]); + if (RETURN_ERROR (Status)) { + assert (false); + return -1; + } + } else if (strcmp (argv[1], "Merge") == 0) { + if (argc < 4) { + fprintf (stderr, "MicroTool: Command arguments are missing\n"); + fprintf (stderr, " Usage: MicroTool Merge OutputFile InputFile1 InputFile2 ...\n"); + assert (false); + return -1; + } + + NumOfFiles = (UINT32)argc - 3U; + + Status = Merge (argv[2], &argv[3], NumOfFiles); + if (RETURN_ERROR (Status)) { + assert (false); + return -1; + } + } + + return 0; +} diff --git a/BaseTools/Scripts/Base.lds b/BaseTools/Scripts/Base.lds new file mode 100644 index 0000000000..8823db55c2 --- /dev/null +++ b/BaseTools/Scripts/Base.lds @@ -0,0 +1,67 @@ +/** @file + + Unified linker script for GCC, CLANG based builds + + Copyright (c) 2023, Mikhail Krichanov. All rights reserved.
+ Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.
+ Copyright (c) 2015, Linaro Ltd. All rights reserved.
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +SECTIONS { + + . = ALIGNED_PE_HEADER_SIZE; + + .text : ALIGN(CONSTANT(MAXPAGESIZE)) { + *(.text .text.* .stub .gnu.linkonce.t.*) + } + + .rodata : ALIGN(CONSTANT(MAXPAGESIZE)) { + *(.rodata .rodata.* .data.rel.ro .data.rel.ro.* .gnu.linkonce.r.*) + *(.got .got.*) + + /* + * The contents of AutoGen.c files are mostly constant from the POV of the + * program, but most of it ends up in .data or .bss by default since few of + * the variable definitions that get emitted are declared as CONST. + * Unfortunately, we cannot pull it into the .text section entirely, since + * patchable PCDs are also emitted here, but we can at least move all of the + * emitted GUIDs here. + */ + *:AutoGen.obj(.data.g*Guid) + } + + .data : ALIGN(CONSTANT(MAXPAGESIZE)) { + *(.data .data.* .gnu.linkonce.d.*) + *(.bss .bss.*) + } + + .hii : ALIGN(CONSTANT(MAXPAGESIZE)) { + KEEP (*(.hii)) + } + + .eh_frame : ALIGN(CONSTANT(MAXPAGESIZE)) { + KEEP (*(.eh_frame)) + } + + .rela (INFO) : { + *(.rela .rela.*) + } + + .build-id (INFO) : { *(.note.gnu.build-id) } + + /DISCARD/ : { + *(.note.GNU-stack) + *(.interp) + *(.dynsym) + *(.dynstr) + *(.hash .gnu.hash) + *(.comment) + *(COMMON) + *(.dynamic) + *(.ARM.exidx .ARM.exidx.*) + } +} diff --git a/BaseTools/Scripts/Merge.lds b/BaseTools/Scripts/Merge.lds new file mode 100644 index 0000000000..d9514283a9 --- /dev/null +++ b/BaseTools/Scripts/Merge.lds @@ -0,0 +1,64 @@ +/** @file + + Unified linker script for GCC, CLANG based builds + + Copyright (c) 2023, Mikhail Krichanov. All rights reserved.
+ Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.
+ Copyright (c) 2015, Linaro Ltd. All rights reserved.
+ (C) Copyright 2016 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +SECTIONS { + + . = ALIGNED_PE_HEADER_SIZE; + + .text : ALIGN(CONSTANT(MAXPAGESIZE)) { + *(.text .text.* .stub .gnu.linkonce.t.*) + *(.rodata .rodata.* .data.rel.ro .data.rel.ro.* .gnu.linkonce.r.*) + *(.got .got.*) + + /* + * The contents of AutoGen.c files are mostly constant from the POV of the + * program, but most of it ends up in .data or .bss by default since few of + * the variable definitions that get emitted are declared as CONST. + * Unfortunately, we cannot pull it into the .text section entirely, since + * patchable PCDs are also emitted here, but we can at least move all of the + * emitted GUIDs here. + */ + *:AutoGen.obj(.data.g*Guid) + } + + .data : ALIGN(CONSTANT(MAXPAGESIZE)) { + *(.data .data.* .gnu.linkonce.d.*) + *(.bss .bss.*) + } + + .hii : ALIGN(CONSTANT(MAXPAGESIZE)) { + KEEP (*(.hii)) + } + + .eh_frame : ALIGN(CONSTANT(MAXPAGESIZE)) { + KEEP (*(.eh_frame)) + } + + .rela (INFO) : { + *(.rela .rela.*) + } + + .build-id (INFO) : { *(.note.gnu.build-id) } + + /DISCARD/ : { + *(.note.GNU-stack) + *(.interp) + *(.dynsym) + *(.dynstr) + *(.hash .gnu.hash) + *(.comment) + *(COMMON) + *(.dynamic) + *(.ARM.exidx .ARM.exidx.*) + } +} diff --git a/BaseTools/Source/C/GNUmakefile b/BaseTools/Source/C/GNUmakefile index 5275f657ef..362fdf202f 100644 --- a/BaseTools/Source/C/GNUmakefile +++ b/BaseTools/Source/C/GNUmakefile @@ -56,7 +56,6 @@ APPLICATIONS = \ EfiRom \ GenFfs \ GenFv \ - GenFw \ GenSec \ GenCrc32 \ LzmaCompress \ diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 4fc2abf0a8..4c9eaa7dae 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -3472,7 +3472,7 @@ Routine Description: return EFI_SUCCESS; } -EFI_PHYSICAL_ADDRESS +EFI_STATUS AddPadSection ( IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, IN UINT32 Alignment, @@ -3485,14 +3485,14 @@ AddPadSection ( UINT32 FfsHeaderLength; UINT32 FfsFileLength; UINT32 PadSize; - UINTN PadAddress; + EFI_PHYSICAL_ADDRESS PadAddress; UINT8 *FfsPart; UINT32 PartSize; UINT32 Offset; EFI_FFS_INTEGRITY_CHECK *IntegrityCheck; PadAddress = ALIGN_VALUE (*BaseAddress + sizeof (EFI_COMMON_SECTION_HEADER), Alignment); - PadSize = PadAddress - *BaseAddress; + PadSize = (UINT32)(PadAddress - *BaseAddress); Offset = (UINT32)((UINTN)((*Section).Pe32Section) - (UINTN)(*FfsFile)); PartSize = GetFfsFileLength (*FfsFile) - Offset; @@ -3522,7 +3522,7 @@ AddPadSection ( ++NewSection; ZeroMem ((VOID *)NewSection, PadSize - sizeof (EFI_COMMON_SECTION_HEADER)); - *Section = (EFI_FILE_SECTION_POINTER)(EFI_PE32_SECTION *)((UINT8 *)NewSection + PadSize - sizeof (EFI_COMMON_SECTION_HEADER)); + (*Section).Pe32Section = (EFI_PE32_SECTION *)((UINT8 *)NewSection + PadSize - sizeof (EFI_COMMON_SECTION_HEADER)); CopyMem ( (UINT8 *)((*Section).Pe32Section), @@ -3956,7 +3956,7 @@ Routine Description: PdbPointer = FileName; } - WriteMapFile (FvMapFile, PdbPointer, *FfsFile, NewPe32BaseAddress, &OrigImageContext); + WriteMapFile (FvMapFile, PdbPointer, *FfsFile, NewPe32BaseAddress, &ImageContext); } if ((*FfsFile)->Type != EFI_FV_FILETYPE_SECURITY_CORE && diff --git a/BaseTools/Source/C/GenFw/Elf32Convert.h b/BaseTools/Source/C/GenFw/Elf32Convert.h deleted file mode 100644 index 906a4de3cc..0000000000 --- a/BaseTools/Source/C/GenFw/Elf32Convert.h +++ /dev/null @@ -1,19 +0,0 @@ -/** @file -Header file for Elf32 Convert solution - -Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _ELF_32_CONVERT_ -#define _ELF_32_CONVERT_ - -BOOLEAN -InitializeElf32 ( - UINT8 *FileBuffer, - ELF_FUNCTION_TABLE *ElfFunctions - ); - -#endif diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.h b/BaseTools/Source/C/GenFw/Elf64Convert.h deleted file mode 100644 index 330b2a76a7..0000000000 --- a/BaseTools/Source/C/GenFw/Elf64Convert.h +++ /dev/null @@ -1,19 +0,0 @@ -/** @file -Header file for Elf64 convert solution - -Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _ELF_64_CONVERT_ -#define _ELF_64_CONVERT_ - -BOOLEAN -InitializeElf64 ( - UINT8 *FileBuffer, - ELF_FUNCTION_TABLE *ElfFunctions - ); - -#endif diff --git a/BaseTools/Source/C/GenFw/ElfConvert.h b/BaseTools/Source/C/GenFw/ElfConvert.h deleted file mode 100644 index 6ab4605227..0000000000 --- a/BaseTools/Source/C/GenFw/ElfConvert.h +++ /dev/null @@ -1,122 +0,0 @@ -/** @file -Header file for Elf convert solution - -Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _ELF_CONVERT_H_ -#define _ELF_CONVERT_H_ - -#include "elf_common.h" -#include "elf32.h" -#include "elf64.h" - -// -// Externally defined variables -// -extern UINT32 mCoffOffset; -extern CHAR8 *mInImageName; -extern UINT32 mImageTimeStamp; -extern UINT8 *mCoffFile; -extern UINT32 mTableOffset; -extern UINT32 mOutImageType; -extern UINT32 mFileBufferSize; -extern BOOLEAN mExportFlag; - -// -// Common EFI specific data. -// -#define ELF_HII_SECTION_NAME ".hii" -#define ELF_STRTAB_SECTION_NAME ".strtab" -#define MAX_COFF_ALIGNMENT 0x10000 -#define ELF_SYMBOL_SECTION_NAME ".symtab" - -// -// Platform Runtime Mechanism (PRM) specific data. -// -#define PRM_MODULE_EXPORT_SYMBOL_NUM 256 - -// to include PRM header directly once PrmPkg is in main repo -#define PRM_HANDLER_NAME_MAXIMUM_LENGTH 128 - -#define PRM_MODULE_EXPORT_DESCRIPTOR_NAME "PrmModuleExportDescriptor" -#define PRM_MODULE_EXPORT_DESCRIPTOR_SIGNATURE SIGNATURE_64 ('P', 'R', 'M', '_', 'M', 'E', 'D', 'T') -#define PRM_MODULE_EXPORT_REVISION 0x0 - -// -// Platform Runtime Mechanism (PRM) Export Descriptor Structures -// -#pragma pack(push, 1) - -typedef struct { - EFI_GUID PrmHandlerGuid; - CHAR8 PrmHandlerName[PRM_HANDLER_NAME_MAXIMUM_LENGTH]; -} PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT; - -typedef struct { - UINT64 Signature; - UINT16 Revision; - UINT16 NumberPrmHandlers; - EFI_GUID PlatformGuid; - EFI_GUID ModuleGuid; -} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER; - -typedef struct { - PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER Header; - PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT PrmHandlerExportDescriptors[1]; -} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT; - -#pragma pack(pop) - -// -// Filter Types -// -typedef enum { - SECTION_TEXT, - SECTION_HII, - SECTION_DATA, - SECTION_SYMBOL - -} SECTION_FILTER_TYPES; - -// -// FunctionTable -// -typedef struct { - VOID (*ScanSections) (); - BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType); - VOID (*WriteRelocations) (); - VOID (*WriteDebug) (); - VOID (*WriteExport) (); - VOID (*SetImageSize) (); - VOID (*CleanUp) (); - -} ELF_FUNCTION_TABLE; - -// -// Common functions -// -VOID -CoffAddFixup ( - UINT32 Offset, - UINT8 Type - ); - -VOID -CoffAddFixupEntry ( - UINT16 Val - ); - - -VOID -CreateSectionHeader ( - const CHAR8 *Name, - UINT32 Offset, - UINT32 Size, - UINT32 Flags - ); - -#endif diff --git a/BaseTools/Source/C/GenFw/GenFw.h b/BaseTools/Source/C/GenFw/GenFw.h deleted file mode 100644 index 469017602d..0000000000 --- a/BaseTools/Source/C/GenFw/GenFw.h +++ /dev/null @@ -1,50 +0,0 @@ -/** @file -Header file for GenFw - -Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _GEN_FW_H_ -#define _GEN_FW_H_ - -// -// Action for this tool. -// -#define FW_DUMMY_IMAGE 0 -#define FW_EFI_IMAGE 1 -#define FW_TE_IMAGE 2 -#define FW_ACPI_IMAGE 3 -#define FW_BIN_IMAGE 4 -#define FW_ZERO_DEBUG_IMAGE 5 -#define FW_SET_STAMP_IMAGE 6 -#define FW_MCI_IMAGE 7 -#define FW_MERGE_IMAGE 8 -#define FW_RELOC_STRIPEED_IMAGE 9 -#define FW_HII_PACKAGE_LIST_RCIMAGE 10 -#define FW_HII_PACKAGE_LIST_BINIMAGE 11 -#define FW_REBASE_IMAGE 12 -#define FW_SET_ADDRESS_IMAGE 13 - -#define DUMP_TE_HEADER 0x11 - -VOID -SetHiiResourceHeader ( - UINT8 *HiiBinData, - UINT32 OffsetToFile - ); - -INTN -IsElfHeader ( - UINT8 *FileBuffer - ); - -BOOLEAN -ConvertElf ( - UINT8 **FileBuffer, - UINT32 *FileLength - ); - -#endif diff --git a/BaseTools/Source/C/GenFw/Makefile b/BaseTools/Source/C/GenFw/Makefile deleted file mode 100644 index 08626c8f3a..0000000000 --- a/BaseTools/Source/C/GenFw/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -## @file -# Windows makefile for 'GenFw' module build. -# -# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
-# SPDX-License-Identifier: BSD-2-Clause-Patent -# -!INCLUDE ..\Makefiles\ms.common - -APPNAME = GenFw - -LIBS = $(LIB_PATH)\Common.lib - -OBJECTS = GenFw.obj ElfConvert.obj Elf32Convert.obj Elf64Convert.obj - -#CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib - -!INCLUDE ..\Makefiles\ms.app - diff --git a/BaseTools/Source/C/GenFw/elf32.h b/BaseTools/Source/C/GenFw/elf32.h deleted file mode 100644 index e8a56ff345..0000000000 --- a/BaseTools/Source/C/GenFw/elf32.h +++ /dev/null @@ -1,252 +0,0 @@ -/** @file -Ported ELF include files from FreeBSD - -Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - - -**/ -/*- - * Copyright (c) 1996-1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.2 2007/12/03 21:30:36 marius Exp $ - */ - -#ifndef _SYS_ELF32_H_ -#define _SYS_ELF32_H_ 1 - - -/* - * ELF definitions common to all 32-bit architectures. - */ - -typedef UINT32 Elf32_Addr; -typedef UINT16 Elf32_Half; -typedef UINT32 Elf32_Off; -typedef INT32 Elf32_Sword; -typedef UINT32 Elf32_Word; -typedef UINT64 Elf32_Lword; - -typedef Elf32_Word Elf32_Hashelt; - -/* Non-standard class-dependent datatype used for abstraction. */ -typedef Elf32_Word Elf32_Size; -typedef Elf32_Sword Elf32_Ssize; - -/* - * ELF header. - */ - -typedef struct { - unsigned char e_ident[EI_NIDENT]; /* File identification. */ - Elf32_Half e_type; /* File type. */ - Elf32_Half e_machine; /* Machine architecture. */ - Elf32_Word e_version; /* ELF format version. */ - Elf32_Addr e_entry; /* Entry point. */ - Elf32_Off e_phoff; /* Program header file offset. */ - Elf32_Off e_shoff; /* Section header file offset. */ - Elf32_Word e_flags; /* Architecture-specific flags. */ - Elf32_Half e_ehsize; /* Size of ELF header in bytes. */ - Elf32_Half e_phentsize; /* Size of program header entry. */ - Elf32_Half e_phnum; /* Number of program header entries. */ - Elf32_Half e_shentsize; /* Size of section header entry. */ - Elf32_Half e_shnum; /* Number of section header entries. */ - Elf32_Half e_shstrndx; /* Section name strings section. */ -} Elf32_Ehdr; - -/* - * Section header. - */ - -typedef struct { - Elf32_Word sh_name; /* Section name (index into the - section header string table). */ - Elf32_Word sh_type; /* Section type. */ - Elf32_Word sh_flags; /* Section flags. */ - Elf32_Addr sh_addr; /* Address in memory image. */ - Elf32_Off sh_offset; /* Offset in file. */ - Elf32_Word sh_size; /* Size in bytes. */ - Elf32_Word sh_link; /* Index of a related section. */ - Elf32_Word sh_info; /* Depends on section type. */ - Elf32_Word sh_addralign; /* Alignment in bytes. */ - Elf32_Word sh_entsize; /* Size of each entry in section. */ -} Elf32_Shdr; - -/* - * Program header. - */ - -typedef struct { - Elf32_Word p_type; /* Entry type. */ - Elf32_Off p_offset; /* File offset of contents. */ - Elf32_Addr p_vaddr; /* Virtual address in memory image. */ - Elf32_Addr p_paddr; /* Physical address (not used). */ - Elf32_Word p_filesz; /* Size of contents in file. */ - Elf32_Word p_memsz; /* Size of contents in memory. */ - Elf32_Word p_flags; /* Access permission flags. */ - Elf32_Word p_align; /* Alignment in memory and file. */ -} Elf32_Phdr; - -/* - * Dynamic structure. The ".dynamic" section contains an array of them. - */ - -typedef struct { - Elf32_Sword d_tag; /* Entry type. */ - union { - Elf32_Word d_val; /* Integer value. */ - Elf32_Addr d_ptr; /* Address value. */ - } d_un; -} Elf32_Dyn; - -/* - * Relocation entries. - */ - -/* Relocations that don't need an addend field. */ -typedef struct { - Elf32_Addr r_offset; /* Location to be relocated. */ - Elf32_Word r_info; /* Relocation type and symbol index. */ -} Elf32_Rel; - -/* Relocations that need an addend field. */ -typedef struct { - Elf32_Addr r_offset; /* Location to be relocated. */ - Elf32_Word r_info; /* Relocation type and symbol index. */ - Elf32_Sword r_addend; /* Addend. */ -} Elf32_Rela; - -/* Macros for accessing the fields of r_info. */ -#define ELF32_R_SYM(info) ((info) >> 8) -#define ELF32_R_TYPE(info) ((unsigned char)(info)) - -/* Macro for constructing r_info from field values. */ -#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type)) - -/* - * Note entry header - */ -typedef Elf_Note Elf32_Nhdr; - -/* - * Move entry - */ -typedef struct { - Elf32_Lword m_value; /* symbol value */ - Elf32_Word m_info; /* size + index */ - Elf32_Word m_poffset; /* symbol offset */ - Elf32_Half m_repeat; /* repeat count */ - Elf32_Half m_stride; /* stride info */ -} Elf32_Move; - -/* - * The macros compose and decompose values for Move.r_info - * - * sym = ELF32_M_SYM(M.m_info) - * size = ELF32_M_SIZE(M.m_info) - * M.m_info = ELF32_M_INFO(sym, size) - */ -#define ELF32_M_SYM(info) ((info)>>8) -#define ELF32_M_SIZE(info) ((unsigned char)(info)) -#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size)) - -/* - * Hardware/Software capabilities entry - */ -typedef struct { - Elf32_Word c_tag; /* how to interpret value */ - union { - Elf32_Word c_val; - Elf32_Addr c_ptr; - } c_un; -} Elf32_Cap; - -/* - * Symbol table entries. - */ - -typedef struct { - Elf32_Word st_name; /* String table index of name. */ - Elf32_Addr st_value; /* Symbol value. */ - Elf32_Word st_size; /* Size of associated object. */ - unsigned char st_info; /* Type and binding information. */ - unsigned char st_other; /* Reserved (not used). */ - Elf32_Half st_shndx; /* Section index of symbol. */ -} Elf32_Sym; - -/* Macros for accessing the fields of st_info. */ -#define ELF32_ST_BIND(info) ((info) >> 4) -#define ELF32_ST_TYPE(info) ((info) & 0xf) - -/* Macro for constructing st_info from field values. */ -#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) - -/* Macro for accessing the fields of st_other. */ -#define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3) - -/* Structures used by Sun & GNU symbol versioning. */ -typedef struct -{ - Elf32_Half vd_version; - Elf32_Half vd_flags; - Elf32_Half vd_ndx; - Elf32_Half vd_cnt; - Elf32_Word vd_hash; - Elf32_Word vd_aux; - Elf32_Word vd_next; -} Elf32_Verdef; - -typedef struct -{ - Elf32_Word vda_name; - Elf32_Word vda_next; -} Elf32_Verdaux; - -typedef struct -{ - Elf32_Half vn_version; - Elf32_Half vn_cnt; - Elf32_Word vn_file; - Elf32_Word vn_aux; - Elf32_Word vn_next; -} Elf32_Verneed; - -typedef struct -{ - Elf32_Word vna_hash; - Elf32_Half vna_flags; - Elf32_Half vna_other; - Elf32_Word vna_name; - Elf32_Word vna_next; -} Elf32_Vernaux; - -typedef Elf32_Half Elf32_Versym; - -typedef struct { - Elf32_Half si_boundto; /* direct bindings - symbol bound to */ - Elf32_Half si_flags; /* per symbol flags */ -} Elf32_Syminfo; - -#endif /* !_SYS_ELF32_H_ */ diff --git a/BaseTools/Source/C/GenFw/elf64.h b/BaseTools/Source/C/GenFw/elf64.h deleted file mode 100644 index 1ec0c2b29b..0000000000 --- a/BaseTools/Source/C/GenFw/elf64.h +++ /dev/null @@ -1,254 +0,0 @@ -/** @file -Ported ELF include files from FreeBSD - -Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ -/*- - * Copyright (c) 1996-1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.2 2007/12/03 21:30:36 marius Exp $ - */ - -#ifndef _SYS_ELF64_H_ -#define _SYS_ELF64_H_ 1 - - -/* - * ELF definitions common to all 64-bit architectures. - */ - -typedef UINT64 Elf64_Addr; -typedef UINT16 Elf64_Half; -typedef UINT64 Elf64_Off; -typedef INT32 Elf64_Sword; -typedef INT64 Elf64_Sxword; -typedef UINT32 Elf64_Word; -typedef UINT64 Elf64_Lword; -typedef UINT64 Elf64_Xword; - -/* - * Types of dynamic symbol hash table bucket and chain elements. - * - * This is inconsistent among 64 bit architectures, so a machine dependent - * typedef is required. - */ - -typedef Elf64_Word Elf64_Hashelt; - -/* Non-standard class-dependent datatype used for abstraction. */ -typedef Elf64_Xword Elf64_Size; -typedef Elf64_Sxword Elf64_Ssize; - -/* - * ELF header. - */ - -typedef struct { - unsigned char e_ident[EI_NIDENT]; /* File identification. */ - Elf64_Half e_type; /* File type. */ - Elf64_Half e_machine; /* Machine architecture. */ - Elf64_Word e_version; /* ELF format version. */ - Elf64_Addr e_entry; /* Entry point. */ - Elf64_Off e_phoff; /* Program header file offset. */ - Elf64_Off e_shoff; /* Section header file offset. */ - Elf64_Word e_flags; /* Architecture-specific flags. */ - Elf64_Half e_ehsize; /* Size of ELF header in bytes. */ - Elf64_Half e_phentsize; /* Size of program header entry. */ - Elf64_Half e_phnum; /* Number of program header entries. */ - Elf64_Half e_shentsize; /* Size of section header entry. */ - Elf64_Half e_shnum; /* Number of section header entries. */ - Elf64_Half e_shstrndx; /* Section name strings section. */ -} Elf64_Ehdr; - -/* - * Section header. - */ - -typedef struct { - Elf64_Word sh_name; /* Section name (index into the - section header string table). */ - Elf64_Word sh_type; /* Section type. */ - Elf64_Xword sh_flags; /* Section flags. */ - Elf64_Addr sh_addr; /* Address in memory image. */ - Elf64_Off sh_offset; /* Offset in file. */ - Elf64_Xword sh_size; /* Size in bytes. */ - Elf64_Word sh_link; /* Index of a related section. */ - Elf64_Word sh_info; /* Depends on section type. */ - Elf64_Xword sh_addralign; /* Alignment in bytes. */ - Elf64_Xword sh_entsize; /* Size of each entry in section. */ -} Elf64_Shdr; - -/* - * Program header. - */ - -typedef struct { - Elf64_Word p_type; /* Entry type. */ - Elf64_Word p_flags; /* Access permission flags. */ - Elf64_Off p_offset; /* File offset of contents. */ - Elf64_Addr p_vaddr; /* Virtual address in memory image. */ - Elf64_Addr p_paddr; /* Physical address (not used). */ - Elf64_Xword p_filesz; /* Size of contents in file. */ - Elf64_Xword p_memsz; /* Size of contents in memory. */ - Elf64_Xword p_align; /* Alignment in memory and file. */ -} Elf64_Phdr; - -/* - * Dynamic structure. The ".dynamic" section contains an array of them. - */ - -typedef struct { - Elf64_Sxword d_tag; /* Entry type. */ - union { - Elf64_Xword d_val; /* Integer value. */ - Elf64_Addr d_ptr; /* Address value. */ - } d_un; -} Elf64_Dyn; - -/* - * Relocation entries. - */ - -/* Relocations that don't need an addend field. */ -typedef struct { - Elf64_Addr r_offset; /* Location to be relocated. */ - Elf64_Xword r_info; /* Relocation type and symbol index. */ -} Elf64_Rel; - -/* Relocations that need an addend field. */ -typedef struct { - Elf64_Addr r_offset; /* Location to be relocated. */ - Elf64_Xword r_info; /* Relocation type and symbol index. */ - Elf64_Sxword r_addend; /* Addend. */ -} Elf64_Rela; - -/* Macros for accessing the fields of r_info. */ -#define ELF64_R_SYM(info) ((info) >> 32) -#define ELF64_R_TYPE(info) ((info) & 0xffffffffL) - -/* Macro for constructing r_info from field values. */ -#define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL)) - -#define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40) -#define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56) -#define ELF64_R_TYPE_INFO(data, type) \ - (((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type)) - -/* - * Note entry header - */ -typedef Elf_Note Elf64_Nhdr; - -/* - * Move entry - */ -typedef struct { - Elf64_Lword m_value; /* symbol value */ - Elf64_Xword m_info; /* size + index */ - Elf64_Xword m_poffset; /* symbol offset */ - Elf64_Half m_repeat; /* repeat count */ - Elf64_Half m_stride; /* stride info */ -} Elf64_Move; - -#define ELF64_M_SYM(info) ((info)>>8) -#define ELF64_M_SIZE(info) ((unsigned char)(info)) -#define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size)) - -/* - * Hardware/Software capabilities entry - */ -typedef struct { - Elf64_Xword c_tag; /* how to interpret value */ - union { - Elf64_Xword c_val; - Elf64_Addr c_ptr; - } c_un; -} Elf64_Cap; - -/* - * Symbol table entries. - */ - -typedef struct { - Elf64_Word st_name; /* String table index of name. */ - unsigned char st_info; /* Type and binding information. */ - unsigned char st_other; /* Reserved (not used). */ - Elf64_Half st_shndx; /* Section index of symbol. */ - Elf64_Addr st_value; /* Symbol value. */ - Elf64_Xword st_size; /* Size of associated object. */ -} Elf64_Sym; - -/* Macros for accessing the fields of st_info. */ -#define ELF64_ST_BIND(info) ((info) >> 4) -#define ELF64_ST_TYPE(info) ((info) & 0xf) - -/* Macro for constructing st_info from field values. */ -#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) - -/* Macro for accessing the fields of st_other. */ -#define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3) - -/* Structures used by Sun & GNU-style symbol versioning. */ -typedef struct { - Elf64_Half vd_version; - Elf64_Half vd_flags; - Elf64_Half vd_ndx; - Elf64_Half vd_cnt; - Elf64_Word vd_hash; - Elf64_Word vd_aux; - Elf64_Word vd_next; -} Elf64_Verdef; - -typedef struct { - Elf64_Word vda_name; - Elf64_Word vda_next; -} Elf64_Verdaux; - -typedef struct { - Elf64_Half vn_version; - Elf64_Half vn_cnt; - Elf64_Word vn_file; - Elf64_Word vn_aux; - Elf64_Word vn_next; -} Elf64_Verneed; - -typedef struct { - Elf64_Word vna_hash; - Elf64_Half vna_flags; - Elf64_Half vna_other; - Elf64_Word vna_name; - Elf64_Word vna_next; -} Elf64_Vernaux; - -typedef Elf64_Half Elf64_Versym; - -typedef struct { - Elf64_Half si_boundto; /* direct bindings - symbol bound to */ - Elf64_Half si_flags; /* per symbol flags */ -} Elf64_Syminfo; - -#endif /* !_SYS_ELF64_H_ */ diff --git a/BaseTools/Source/C/GenFw/elf_common.h b/BaseTools/Source/C/GenFw/elf_common.h deleted file mode 100644 index e4d0cdac4f..0000000000 --- a/BaseTools/Source/C/GenFw/elf_common.h +++ /dev/null @@ -1,1159 +0,0 @@ -/** @file -Ported ELF include files from FreeBSD - -Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.
-Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
-Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
-Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - - -**/ -/*- - * Copyright (c) 1998 John D. Polstra. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.2 2007/12/03 21:30:36 marius Exp $ - */ - -#ifndef _SYS_ELF_COMMON_H_ -#define _SYS_ELF_COMMON_H_ 1 - -/* - * ELF definitions that are independent of architecture or word size. - */ - -/* - * Note header. The ".note" section contains an array of notes. Each - * begins with this header, aligned to a word boundary. Immediately - * following the note header is n_namesz bytes of name, padded to the - * next word boundary. Then comes n_descsz bytes of descriptor, again - * padded to a word boundary. The values of n_namesz and n_descsz do - * not include the padding. - */ - -typedef struct { - UINT32 n_namesz; /* Length of name. */ - UINT32 n_descsz; /* Length of descriptor. */ - UINT32 n_type; /* Type of this note. */ -} Elf_Note; - -#define NT_GNU_PROPERTY_TYPE_0 5 - -#define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002 -#define GNU_PROPERTY_X86_FEATURE_1_IBT 0x1 - -#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 -#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI 0x1 -#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC 0x2 - -/* Indexes into the e_ident array. Keep synced with - http://www.sco.com/developers/gabi/latest/ch4.eheader.html */ -#define EI_MAG0 0 /* Magic number, byte 0. */ -#define EI_MAG1 1 /* Magic number, byte 1. */ -#define EI_MAG2 2 /* Magic number, byte 2. */ -#define EI_MAG3 3 /* Magic number, byte 3. */ -#define EI_CLASS 4 /* Class of machine. */ -#define EI_DATA 5 /* Data format. */ -#define EI_VERSION 6 /* ELF format version. */ -#define EI_OSABI 7 /* Operating system / ABI identification */ -#define EI_ABIVERSION 8 /* ABI version */ -#define OLD_EI_BRAND 8 /* Start of architecture identification. */ -#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */ -#define EI_NIDENT 16 /* Size of e_ident array. */ - -/* Values for the magic number bytes. */ -#define ELFMAG0 0x7f -#define ELFMAG1 'E' -#define ELFMAG2 'L' -#define ELFMAG3 'F' -#define ELFMAG "\177ELF" /* magic string */ -#define SELFMAG 4 /* magic string size */ - -/* Values for e_ident[EI_VERSION] and e_version. */ -#define EV_NONE 0 -#define EV_CURRENT 1 - -/* Values for e_ident[EI_CLASS]. */ -#define ELFCLASSNONE 0 /* Unknown class. */ -#define ELFCLASS32 1 /* 32-bit architecture. */ -#define ELFCLASS64 2 /* 64-bit architecture. */ - -/* Values for e_ident[EI_DATA]. */ -#define ELFDATANONE 0 /* Unknown data format. */ -#define ELFDATA2LSB 1 /* 2's complement little-endian. */ -#define ELFDATA2MSB 2 /* 2's complement big-endian. */ - -/* Values for e_ident[EI_OSABI]. */ -#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -#define ELFOSABI_HPUX 1 /* HP-UX operating system */ -#define ELFOSABI_NETBSD 2 /* NetBSD */ -#define ELFOSABI_LINUX 3 /* GNU/Linux */ -#define ELFOSABI_HURD 4 /* GNU/Hurd */ -#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ -#define ELFOSABI_SOLARIS 6 /* Solaris */ -#define ELFOSABI_AIX 7 /* AIX */ -#define ELFOSABI_IRIX 8 /* IRIX */ -#define ELFOSABI_FREEBSD 9 /* FreeBSD */ -#define ELFOSABI_TRU64 10 /* TRU64 UNIX */ -#define ELFOSABI_MODESTO 11 /* Novell Modesto */ -#define ELFOSABI_OPENBSD 12 /* OpenBSD */ -#define ELFOSABI_OPENVMS 13 /* Open VMS */ -#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */ -#define ELFOSABI_ARM 97 /* ARM */ -#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ - -#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */ -#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */ - -/* e_ident */ -#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ - (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ - (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ - (ehdr).e_ident[EI_MAG3] == ELFMAG3) - -/* Values for e_type. */ -#define ET_NONE 0 /* Unknown type. */ -#define ET_REL 1 /* Relocatable. */ -#define ET_EXEC 2 /* Executable. */ -#define ET_DYN 3 /* Shared object. */ -#define ET_CORE 4 /* Core file. */ -#define ET_LOOS 0xfe00 /* First operating system specific. */ -#define ET_HIOS 0xfeff /* Last operating system-specific. */ -#define ET_LOPROC 0xff00 /* First processor-specific. */ -#define ET_HIPROC 0xffff /* Last processor-specific. */ - -/* Values for e_machine. */ -#define EM_NONE 0 /* Unknown machine. */ -#define EM_M32 1 /* AT&T WE32100. */ -#define EM_SPARC 2 /* Sun SPARC. */ -#define EM_386 3 /* Intel i386. */ -#define EM_68K 4 /* Motorola 68000. */ -#define EM_88K 5 /* Motorola 88000. */ -#define EM_860 7 /* Intel i860. */ -#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */ -#define EM_S370 9 /* IBM System/370. */ -#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */ -#define EM_PARISC 15 /* HP PA-RISC. */ -#define EM_VPP500 17 /* Fujitsu VPP500. */ -#define EM_SPARC32PLUS 18 /* SPARC v8plus. */ -#define EM_960 19 /* Intel 80960. */ -#define EM_PPC 20 /* PowerPC 32-bit. */ -#define EM_PPC64 21 /* PowerPC 64-bit. */ -#define EM_S390 22 /* IBM System/390. */ -#define EM_V800 36 /* NEC V800. */ -#define EM_FR20 37 /* Fujitsu FR20. */ -#define EM_RH32 38 /* TRW RH-32. */ -#define EM_RCE 39 /* Motorola RCE. */ -#define EM_ARM 40 /* ARM. */ -#define EM_SH 42 /* Hitachi SH. */ -#define EM_SPARCV9 43 /* SPARC v9 64-bit. */ -#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */ -#define EM_ARC 45 /* Argonaut RISC Core. */ -#define EM_H8_300 46 /* Hitachi H8/300. */ -#define EM_H8_300H 47 /* Hitachi H8/300H. */ -#define EM_H8S 48 /* Hitachi H8S. */ -#define EM_H8_500 49 /* Hitachi H8/500. */ -#define EM_MIPS_X 51 /* Stanford MIPS-X. */ -#define EM_COLDFIRE 52 /* Motorola ColdFire. */ -#define EM_68HC12 53 /* Motorola M68HC12. */ -#define EM_MMA 54 /* Fujitsu MMA. */ -#define EM_PCP 55 /* Siemens PCP. */ -#define EM_NCPU 56 /* Sony nCPU. */ -#define EM_NDR1 57 /* Denso NDR1 microprocessor. */ -#define EM_STARCORE 58 /* Motorola Star*Core processor. */ -#define EM_ME16 59 /* Toyota ME16 processor. */ -#define EM_ST100 60 /* STMicroelectronics ST100 processor. */ -#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */ -#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ -#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */ -#define EM_AARCH64 183 /* ARM 64bit Architecture */ -#define EM_RISCV64 243 /* 64bit RISC-V Architecture */ -#define EM_RISCV 244 /* 32bit RISC-V Architecture */ -#define EM_LOONGARCH 258 /* LoongArch Architecture */ - -/* Non-standard or deprecated. */ -#define EM_486 6 /* Intel i486. */ -#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ -#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */ -#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */ - -/* Special section indexes. */ -#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */ -#define SHN_LORESERVE 0xff00 /* First of reserved range. */ -#define SHN_LOPROC 0xff00 /* First processor-specific. */ -#define SHN_HIPROC 0xff1f /* Last processor-specific. */ -#define SHN_LOOS 0xff20 /* First operating system-specific. */ -#define SHN_HIOS 0xff3f /* Last operating system-specific. */ -#define SHN_ABS 0xfff1 /* Absolute values. */ -#define SHN_COMMON 0xfff2 /* Common data. */ -#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */ -#define SHN_HIRESERVE 0xffff /* Last of reserved range. */ - -/* sh_type */ -#define SHT_NULL 0 /* inactive */ -#define SHT_PROGBITS 1 /* program defined information */ -#define SHT_SYMTAB 2 /* symbol table section */ -#define SHT_STRTAB 3 /* string table section */ -#define SHT_RELA 4 /* relocation section with addends */ -#define SHT_HASH 5 /* symbol hash table section */ -#define SHT_DYNAMIC 6 /* dynamic section */ -#define SHT_NOTE 7 /* note section */ -#define SHT_NOBITS 8 /* no space section */ -#define SHT_REL 9 /* relocation section - no addends */ -#define SHT_SHLIB 10 /* reserved - purpose unknown */ -#define SHT_DYNSYM 11 /* dynamic symbol table section */ -#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */ -#define SHT_FINI_ARRAY 15 /* Termination function pointers. */ -#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */ -#define SHT_GROUP 17 /* Section group. */ -#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */ -#define SHT_LOOS 0x60000000 /* First of OS specific semantics */ -#define SHT_LOSUNW 0x6ffffff4 -#define SHT_SUNW_dof 0x6ffffff4 -#define SHT_SUNW_cap 0x6ffffff5 -#define SHT_SUNW_SIGNATURE 0x6ffffff6 -#define SHT_SUNW_ANNOTATE 0x6ffffff7 -#define SHT_SUNW_DEBUGSTR 0x6ffffff8 -#define SHT_SUNW_DEBUG 0x6ffffff9 -#define SHT_SUNW_move 0x6ffffffa -#define SHT_SUNW_COMDAT 0x6ffffffb -#define SHT_SUNW_syminfo 0x6ffffffc -#define SHT_SUNW_verdef 0x6ffffffd -#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */ -#define SHT_SUNW_verneed 0x6ffffffe -#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */ -#define SHT_SUNW_versym 0x6fffffff -#define SHT_GNU_versym 0x6fffffff /* Symbol version table */ -#define SHT_HISUNW 0x6fffffff -#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ -#define SHT_LOPROC 0x70000000 /* reserved range for processor */ -#define SHT_AMD64_UNWIND 0x70000001 /* unwind information */ -#define SHT_HIPROC 0x7fffffff /* specific section header types */ -#define SHT_LOUSER 0x80000000 /* reserved range for application */ -#define SHT_HIUSER 0xffffffff /* specific indexes */ - -/* Flags for sh_flags. */ -#define SHF_WRITE 0x1 /* Section contains writable data. */ -#define SHF_ALLOC 0x2 /* Section occupies memory. */ -#define SHF_EXECINSTR 0x4 /* Section contains instructions. */ -#define SHF_MERGE 0x10 /* Section may be merged. */ -#define SHF_STRINGS 0x20 /* Section contains strings. */ -#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */ -#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */ -#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */ -#define SHF_GROUP 0x200 /* Member of section group. */ -#define SHF_TLS 0x400 /* Section contains TLS data. */ -#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */ -#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */ - -/* Values for p_type. */ -#define PT_NULL 0 /* Unused entry. */ -#define PT_LOAD 1 /* Loadable segment. */ -#define PT_DYNAMIC 2 /* Dynamic linking information segment. */ -#define PT_INTERP 3 /* Pathname of interpreter. */ -#define PT_NOTE 4 /* Auxiliary information. */ -#define PT_SHLIB 5 /* Reserved (not used). */ -#define PT_PHDR 6 /* Location of program header itself. */ -#define PT_TLS 7 /* Thread local storage segment */ -#define PT_LOOS 0x60000000 /* First OS-specific. */ -#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */ -#define PT_GNU_EH_FRAME 0x6474e550 -#define PT_LOSUNW 0x6ffffffa -#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ -#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */ -#define PT_SUNWDTRACE 0x6ffffffc /* private */ -#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */ -#define PT_HISUNW 0x6fffffff -#define PT_HIOS 0x6fffffff /* Last OS-specific. */ -#define PT_LOPROC 0x70000000 /* First processor-specific type. */ -#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ - -/* Values for p_flags. */ -#define PF_X 0x1 /* Executable. */ -#define PF_W 0x2 /* Writable. */ -#define PF_R 0x4 /* Readable. */ -#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */ -#define PF_MASKPROC 0xf0000000 /* Processor-specific. */ - -/* Extended program header index. */ -#define PN_XNUM 0xffff - -/* Values for d_tag. */ -#define DT_NULL 0 /* Terminating entry. */ -#define DT_NEEDED 1 /* String table offset of a needed shared - library. */ -#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ -#define DT_PLTGOT 3 /* Processor-dependent address. */ -#define DT_HASH 4 /* Address of symbol hash table. */ -#define DT_STRTAB 5 /* Address of string table. */ -#define DT_SYMTAB 6 /* Address of symbol table. */ -#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ -#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ -#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ -#define DT_STRSZ 10 /* Size of string table. */ -#define DT_SYMENT 11 /* Size of each symbol table entry. */ -#define DT_INIT 12 /* Address of initialization function. */ -#define DT_FINI 13 /* Address of finalization function. */ -#define DT_SONAME 14 /* String table offset of shared object - name. */ -#define DT_RPATH 15 /* String table offset of library path. [sup] */ -#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */ -#define DT_REL 17 /* Address of ElfNN_Rel relocations. */ -#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ -#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ -#define DT_PLTREL 20 /* Type of relocation used for PLT. */ -#define DT_DEBUG 21 /* Reserved (not used). */ -#define DT_TEXTREL 22 /* Indicates there may be relocations in - non-writable segments. [sup] */ -#define DT_JMPREL 23 /* Address of PLT relocations. */ -#define DT_BIND_NOW 24 /* [sup] */ -#define DT_INIT_ARRAY 25 /* Address of the array of pointers to - initialization functions */ -#define DT_FINI_ARRAY 26 /* Address of the array of pointers to - termination functions */ -#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of - initialization functions. */ -#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of - terminationfunctions. */ -#define DT_RUNPATH 29 /* String table offset of a null-terminated - library search path string. */ -#define DT_FLAGS 30 /* Object specific flag values. */ -#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING - and less than DT_LOOS follow the rules for - the interpretation of the d_un union - as follows: even == 'd_ptr', even == 'd_val' - or none */ -#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to - pre-initialization functions. */ -#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of - pre-initialization functions. */ -#define DT_MAXPOSTAGS 34 /* number of positive tags */ -#define DT_LOOS 0x6000000d /* First OS-specific */ -#define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */ -#define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */ -#define DT_SUNW_FILTER 0x6000000f /* symbol filter name */ -#define DT_SUNW_CAP 0x60000010 /* hardware/software */ -#define DT_HIOS 0x6ffff000 /* Last OS-specific */ - -/* - * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the - * Dyn.d_un.d_val field of the Elf*_Dyn structure. - */ -#define DT_VALRNGLO 0x6ffffd00 -#define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */ -#define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */ -#define DT_MOVEENT 0x6ffffdfa /* move table entry size */ -#define DT_MOVESZ 0x6ffffdfb /* move table size */ -#define DT_FEATURE_1 0x6ffffdfc /* feature holder */ -#define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */ - /* the following DT_* entry. */ - /* See DF_P1_* definitions */ -#define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */ -#define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */ -#define DT_VALRNGHI 0x6ffffdff - -/* - * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the - * Dyn.d_un.d_ptr field of the Elf*_Dyn structure. - * - * If any adjustment is made to the ELF object after it has been - * built, these entries will need to be adjusted. - */ -#define DT_ADDRRNGLO 0x6ffffe00 -#define DT_CONFIG 0x6ffffefa /* configuration information */ -#define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */ -#define DT_AUDIT 0x6ffffefc /* object auditing */ -#define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */ -#define DT_MOVETAB 0x6ffffefe /* move table */ -#define DT_SYMINFO 0x6ffffeff /* syminfo table */ -#define DT_ADDRRNGHI 0x6ffffeff - -#define DT_VERSYM 0x6ffffff0 /* Address of versym section. */ -#define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */ -#define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */ -#define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */ -#define DT_VERDEF 0x6ffffffc /* Address of verdef section. */ -#define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */ -#define DT_VERNEED 0x6ffffffe /* Address of verneed section. */ -#define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */ - -#define DT_LOPROC 0x70000000 /* First processor-specific type. */ -#define DT_DEPRECATED_SPARC_REGISTER 0x7000001 -#define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */ -#define DT_USED 0x7ffffffe /* ignored - same as needed */ -#define DT_FILTER 0x7fffffff /* shared library filter name */ -#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */ - -/* Values for DT_FLAGS */ -#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may - make reference to the $ORIGIN substitution - string */ -#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ -#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in - non-writable segments. */ -#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should - process all relocations for the object - containing this entry before transferring - control to the program. */ -#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or - executable contains code using a static - thread-local storage scheme. */ - -/* Values for n_type. Used in core files. */ -#define NT_PRSTATUS 1 /* Process status. */ -#define NT_FPREGSET 2 /* Floating point registers. */ -#define NT_PRPSINFO 3 /* Process state info. */ - -/* Symbol Binding - ELFNN_ST_BIND - st_info */ -#define STB_LOCAL 0 /* Local symbol */ -#define STB_GLOBAL 1 /* Global symbol */ -#define STB_WEAK 2 /* like global - lower precedence */ -#define STB_LOOS 10 /* Reserved range for operating system */ -#define STB_HIOS 12 /* specific semantics. */ -#define STB_LOPROC 13 /* reserved range for processor */ -#define STB_HIPROC 15 /* specific semantics. */ - -/* Symbol type - ELFNN_ST_TYPE - st_info */ -#define STT_NOTYPE 0 /* Unspecified type. */ -#define STT_OBJECT 1 /* Data object. */ -#define STT_FUNC 2 /* Function. */ -#define STT_SECTION 3 /* Section. */ -#define STT_FILE 4 /* Source file. */ -#define STT_COMMON 5 /* Uninitialized common block. */ -#define STT_TLS 6 /* TLS object. */ -#define STT_NUM 7 -#define STT_LOOS 10 /* Reserved range for operating system */ -#define STT_HIOS 12 /* specific semantics. */ -#define STT_LOPROC 13 /* reserved range for processor */ -#define STT_HIPROC 15 /* specific semantics. */ - -/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */ -#define STV_DEFAULT 0x0 /* Default visibility (see binding). */ -#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */ -#define STV_HIDDEN 0x2 /* Not visible. */ -#define STV_PROTECTED 0x3 /* Visible but not preemptible. */ - -/* Special symbol table indexes. */ -#define STN_UNDEF 0 /* Undefined symbol index. */ - -/* Symbol versioning flags. */ -#define VER_DEF_CURRENT 1 -#define VER_DEF_IDX(x) VER_NDX(x) - -#define VER_FLG_BASE 0x01 -#define VER_FLG_WEAK 0x02 - -#define VER_NEED_CURRENT 1 -#define VER_NEED_WEAK (1u << 15) -#define VER_NEED_HIDDEN VER_NDX_HIDDEN -#define VER_NEED_IDX(x) VER_NDX(x) - -#define VER_NDX_LOCAL 0 -#define VER_NDX_GLOBAL 1 -#define VER_NDX_GIVEN 2 - -#define VER_NDX_HIDDEN (1u << 15) -#define VER_NDX(x) ((x) & ~(1u << 15)) - -#define CA_SUNW_NULL 0 -#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */ -#define CA_SUNW_SF_1 2 /* first software capabilities entry */ - -/* - * Syminfo flag values - */ -#define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */ - /* to object containing defn. */ -#define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */ -#define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */ -#define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */ - /* lazily-loaded */ -#define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */ - /* object containing defn. */ -#define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */ - /* directly bind to this symbol */ -#define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */ -#define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */ - -/* - * Syminfo.si_boundto values. - */ -#define SYMINFO_BT_SELF 0xffff /* symbol bound to self */ -#define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */ -#define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */ -#define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */ -#define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */ - -/* - * Syminfo version values. - */ -#define SYMINFO_NONE 0 /* Syminfo version */ -#define SYMINFO_CURRENT 1 -#define SYMINFO_NUM 2 - -/* - * Relocation types. - * - * All machine architectures are defined here to allow tools on one to - * handle others. - */ - -#define R_386_NONE 0 /* No relocation. */ -#define R_386_32 1 /* Add symbol value. */ -#define R_386_PC32 2 /* Add PC-relative symbol value. */ -#define R_386_GOT32 3 /* Add PC-relative GOT offset. */ -#define R_386_PLT32 4 /* Add PC-relative PLT offset. */ -#define R_386_COPY 5 /* Copy data from shared object. */ -#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */ -#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */ -#define R_386_RELATIVE 8 /* Add load address of shared object. */ -#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */ -#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */ -#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */ -#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */ -#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */ -#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */ -#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */ -#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */ -#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */ -#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */ -#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */ -#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */ -#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */ -#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */ -#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */ -#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */ -#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */ -#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */ -#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */ -#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */ -#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */ -#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ - -/* Null relocation */ -#define R_AARCH64_NONE 256 /* No relocation */ -/* Static AArch64 relocations */ - /* Static data relocations */ -#define R_AARCH64_ABS64 257 /* S + A */ -#define R_AARCH64_ABS32 258 /* S + A */ -#define R_AARCH64_ABS16 259 /* S + A */ -#define R_AARCH64_PREL64 260 /* S + A - P */ -#define R_AARCH64_PREL32 261 /* S + A - P */ -#define R_AARCH64_PREL16 262 /* S + A - P */ - /* Group relocations to create a 16, 32, 48, or 64 bit unsigned data value or address inline */ -#define R_AARCH64_MOVW_UABS_G0 263 /* S + A */ -#define R_AARCH64_MOVW_UABS_G0_NC 264 /* S + A */ -#define R_AARCH64_MOVW_UABS_G1 265 /* S + A */ -#define R_AARCH64_MOVW_UABS_G1_NC 266 /* S + A */ -#define R_AARCH64_MOVW_UABS_G2 267 /* S + A */ -#define R_AARCH64_MOVW_UABS_G2_NC 268 /* S + A */ -#define R_AARCH64_MOVW_UABS_G3 269 /* S + A */ - /* Group relocations to create a 16, 32, 48, or 64 bit signed data or offset value inline */ -#define R_AARCH64_MOVW_SABS_G0 270 /* S + A */ -#define R_AARCH64_MOVW_SABS_G1 271 /* S + A */ -#define R_AARCH64_MOVW_SABS_G2 272 /* S + A */ - /* Relocations to generate 19, 21 and 33 bit PC-relative addresses */ -#define R_AARCH64_LD_PREL_LO19 273 /* S + A - P */ -#define R_AARCH64_ADR_PREL_LO21 274 /* S + A - P */ -#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page(S+A) - Page(P) */ -#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Page(S+A) - Page(P) */ -#define R_AARCH64_ADD_ABS_LO12_NC 277 /* S + A */ -#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* S + A */ -#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* S + A */ -#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* S + A */ -#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* S + A */ -#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* S + A */ - /* Relocations for control-flow instructions - all offsets are a multiple of 4 */ -#define R_AARCH64_TSTBR14 279 /* S+A-P */ -#define R_AARCH64_CONDBR19 280 /* S+A-P */ -#define R_AARCH64_JUMP26 282 /* S+A-P */ -#define R_AARCH64_CALL26 283 /* S+A-P */ - /* Group relocations to create a 16, 32, 48, or 64 bit PC-relative offset inline */ -#define R_AARCH64_MOVW_PREL_G0 287 /* S+A-P */ -#define R_AARCH64_MOVW_PREL_G0_NC 288 /* S+A-P */ -#define R_AARCH64_MOVW_PREL_G1 289 /* S+A-P */ -#define R_AARCH64_MOVW_PREL_G1_NC 290 /* S+A-P */ -#define R_AARCH64_MOVW_PREL_G2 291 /* S+A-P */ -#define R_AARCH64_MOVW_PREL_G2_NC 292 /* S+A-P */ -#define R_AARCH64_MOVW_PREL_G3 293 /* S+A-P */ - /* Group relocations to create a 16, 32, 48, or 64 bit GOT-relative offsets inline */ -#define R_AARCH64_MOVW_GOTOFF_G0 300 /* G(S)-GOT */ -#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* G(S)-GOT */ -#define R_AARCH64_MOVW_GOTOFF_G1 302 /* G(S)-GOT */ -#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* G(S)-GOT */ -#define R_AARCH64_MOVW_GOTOFF_G2 304 /* G(S)-GOT */ -#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* G(S)-GOT */ -#define R_AARCH64_MOVW_GOTOFF_G3 306 /* G(S)-GOT */ - /* GOT-relative data relocations */ -#define R_AARCH64_GOTREL64 307 /* S+A-GOT */ -#define R_AARCH64_GOTREL32 308 /* S+A-GOT */ - /* GOT-relative instruction relocations */ -#define R_AARCH64_GOT_LD_PREL19 309 /* G(S)-P */ -#define R_AARCH64_LD64_GOTOFF_LO15 310 /* G(S)-GOT */ -#define R_AARCH64_ADR_GOT_PAGE 311 /* Page(G(S))-Page(P) */ -#define R_AARCH64_LD64_GOT_LO12_NC 312 /* G(S) */ -#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* G(S)-Page(GOT) */ -/* Relocations for thread-local storage */ - /* General Dynamic TLS relocations */ -#define R_AARCH64_TLSGD_ADR_PREL21 512 /* G(TLSIDX(S+A)) - P */ -#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* Page(G(TLSIDX(S+A))) - Page(P) */ -#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* G(TLSIDX(S+A)) */ -#define R_AARCH64_TLSGD_MOVW_G1 515 /* G(TLSIDX(S+A)) - GOT */ -#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* G(TLSIDX(S+A)) - GOT */ - /* Local Dynamic TLS relocations */ -#define R_AARCH64_TLSLD_ADR_PREL21 517 /* G(LDM(S))) - P */ -#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Page(G(LDM(S)))-Page(P) */ -#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* G(LDM(S)) */ -#define R_AARCH64_TLSLD_MOVW_G1 520 /* G(LDM(S)) - GOT */ -#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* G(LDM(S)) - GOT */ -#define R_AARCH64_TLSLD_LD_PREL19 522 /* G(LDM(S)) - P */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTPREL(S+A) */ -#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* DTPREL(S+A) */ - /* Initial Exec TLS relocations */ -#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* G(TPREL(S+A)) - GOT */ -#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* G(TPREL(S+A)) - GOT */ -#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page(G(TPREL(S+A))) - Page(P) */ -#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* G(TPREL(S+A)) */ -#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* G(TPREL(S+A)) - P */ - /* Local Exec TLS relocations */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TPREL(S+A) */ -#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* TPREL(S+A) */ -/* Dynamic relocations */ - /* Dynamic relocations */ -#define R_AARCH64_COPY 1024 -#define R_AARCH64_GLOB_DAT 1025 /* S + A */ -#define R_AARCH64_JUMP_SLOT 1026 /* S + A */ -#define R_AARCH64_RELATIVE 1027 /* Delta(S) + A , Delta(P) + A */ -#define R_AARCH64_TLS_DTPREL64 1028 /* DTPREL(S+A) */ -#define R_AARCH64_TLS_DTPMOD64 1029 /* LDM(S) */ -#define R_AARCH64_TLS_TPREL64 1030 /* TPREL(S+A) */ -#define R_AARCH64_TLS_DTPREL32 1031 /* DTPREL(S+A) */ -#define R_AARCH64_TLS_DTPMOD32 1032 /* LDM(S) */ -#define R_AARCH64_TLS_TPREL32 1033 /* DTPREL(S+A) */ - -#define R_ALPHA_NONE 0 /* No reloc */ -#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ -#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ -#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ -#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ -#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ -#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ -#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ -#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ -#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ -#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ -#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ -#define R_ALPHA_OP_PUSH 12 /* OP stack push */ -#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */ -#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */ -#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */ -#define R_ALPHA_GPVALUE 16 -#define R_ALPHA_GPRELHIGH 17 -#define R_ALPHA_GPRELLOW 18 -#define R_ALPHA_IMMED_GP_16 19 -#define R_ALPHA_IMMED_GP_HI32 20 -#define R_ALPHA_IMMED_SCN_HI32 21 -#define R_ALPHA_IMMED_BR_HI32 22 -#define R_ALPHA_IMMED_LO32 23 -#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ -#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ -#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ -#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ - -#define R_ARM_NONE 0 /* No relocation. */ -#define R_ARM_PC24 1 -#define R_ARM_ABS32 2 -#define R_ARM_REL32 3 -#define R_ARM_PC13 4 -#define R_ARM_ABS16 5 -#define R_ARM_ABS12 6 -#define R_ARM_THM_ABS5 7 -#define R_ARM_ABS8 8 -#define R_ARM_SBREL32 9 -#define R_ARM_THM_PC22 10 -#define R_ARM_THM_PC8 11 -#define R_ARM_AMP_VCALL9 12 -#define R_ARM_SWI24 13 -#define R_ARM_THM_SWI8 14 -#define R_ARM_XPC25 15 -#define R_ARM_THM_XPC22 16 -#define R_ARM_COPY 20 /* Copy data from shared object. */ -#define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */ -#define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */ -#define R_ARM_RELATIVE 23 /* Add load address of shared object. */ -#define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */ -#define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */ -#define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */ -#define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */ -#define R_ARM_CALL 28 -#define R_ARM_JMP24 29 -#define R_ARM_THM_MOVW_ABS_NC 47 -#define R_ARM_THM_MOVT_ABS 48 - -// Block of PC-relative relocations added to work around gcc putting -// object relocations in static executables. -#define R_ARM_THM_JUMP24 30 -#define R_ARM_PREL31 42 -#define R_ARM_MOVW_PREL_NC 45 -#define R_ARM_MOVT_PREL 46 -#define R_ARM_THM_MOVW_PREL_NC 49 -#define R_ARM_THM_MOVT_PREL 50 -#define R_ARM_THM_JMP6 52 -#define R_ARM_THM_ALU_PREL_11_0 53 -#define R_ARM_THM_PC12 54 -#define R_ARM_REL32_NOI 56 -#define R_ARM_ALU_PC_G0_NC 57 -#define R_ARM_ALU_PC_G0 58 -#define R_ARM_ALU_PC_G1_NC 59 -#define R_ARM_ALU_PC_G1 60 -#define R_ARM_ALU_PC_G2 61 -#define R_ARM_LDR_PC_G1 62 -#define R_ARM_LDR_PC_G2 63 -#define R_ARM_LDRS_PC_G0 64 -#define R_ARM_LDRS_PC_G1 65 -#define R_ARM_LDRS_PC_G2 66 -#define R_ARM_LDC_PC_G0 67 -#define R_ARM_LDC_PC_G1 68 -#define R_ARM_LDC_PC_G2 69 -#define R_ARM_GOT_PREL 96 -#define R_ARM_THM_JUMP11 102 -#define R_ARM_THM_JUMP8 103 -#define R_ARM_TLS_GD32 104 -#define R_ARM_TLS_LDM32 105 -#define R_ARM_TLS_IE32 107 - -#define R_ARM_THM_JUMP19 51 -#define R_ARM_GNU_VTENTRY 100 -#define R_ARM_GNU_VTINHERIT 101 -#define R_ARM_RSBREL32 250 -#define R_ARM_THM_RPC22 251 -#define R_ARM_RREL32 252 -#define R_ARM_RABS32 253 -#define R_ARM_RPC24 254 -#define R_ARM_RBASE 255 - -#define R_PPC_NONE 0 /* No relocation. */ -#define R_PPC_ADDR32 1 -#define R_PPC_ADDR24 2 -#define R_PPC_ADDR16 3 -#define R_PPC_ADDR16_LO 4 -#define R_PPC_ADDR16_HI 5 -#define R_PPC_ADDR16_HA 6 -#define R_PPC_ADDR14 7 -#define R_PPC_ADDR14_BRTAKEN 8 -#define R_PPC_ADDR14_BRNTAKEN 9 -#define R_PPC_REL24 10 -#define R_PPC_REL14 11 -#define R_PPC_REL14_BRTAKEN 12 -#define R_PPC_REL14_BRNTAKEN 13 -#define R_PPC_GOT16 14 -#define R_PPC_GOT16_LO 15 -#define R_PPC_GOT16_HI 16 -#define R_PPC_GOT16_HA 17 -#define R_PPC_PLTREL24 18 -#define R_PPC_COPY 19 -#define R_PPC_GLOB_DAT 20 -#define R_PPC_JMP_SLOT 21 -#define R_PPC_RELATIVE 22 -#define R_PPC_LOCAL24PC 23 -#define R_PPC_UADDR32 24 -#define R_PPC_UADDR16 25 -#define R_PPC_REL32 26 -#define R_PPC_PLT32 27 -#define R_PPC_PLTREL32 28 -#define R_PPC_PLT16_LO 29 -#define R_PPC_PLT16_HI 30 -#define R_PPC_PLT16_HA 31 -#define R_PPC_SDAREL16 32 -#define R_PPC_SECTOFF 33 -#define R_PPC_SECTOFF_LO 34 -#define R_PPC_SECTOFF_HI 35 -#define R_PPC_SECTOFF_HA 36 - -/* - * TLS relocations - */ -#define R_PPC_TLS 67 -#define R_PPC_DTPMOD32 68 -#define R_PPC_TPREL16 69 -#define R_PPC_TPREL16_LO 70 -#define R_PPC_TPREL16_HI 71 -#define R_PPC_TPREL16_HA 72 -#define R_PPC_TPREL32 73 -#define R_PPC_DTPREL16 74 -#define R_PPC_DTPREL16_LO 75 -#define R_PPC_DTPREL16_HI 76 -#define R_PPC_DTPREL16_HA 77 -#define R_PPC_DTPREL32 78 -#define R_PPC_GOT_TLSGD16 79 -#define R_PPC_GOT_TLSGD16_LO 80 -#define R_PPC_GOT_TLSGD16_HI 81 -#define R_PPC_GOT_TLSGD16_HA 82 -#define R_PPC_GOT_TLSLD16 83 -#define R_PPC_GOT_TLSLD16_LO 84 -#define R_PPC_GOT_TLSLD16_HI 85 -#define R_PPC_GOT_TLSLD16_HA 86 -#define R_PPC_GOT_TPREL16 87 -#define R_PPC_GOT_TPREL16_LO 88 -#define R_PPC_GOT_TPREL16_HI 89 -#define R_PPC_GOT_TPREL16_HA 90 - -/* - * The remaining relocs are from the Embedded ELF ABI, and are not in the - * SVR4 ELF ABI. - */ - -#define R_PPC_EMB_NADDR32 101 -#define R_PPC_EMB_NADDR16 102 -#define R_PPC_EMB_NADDR16_LO 103 -#define R_PPC_EMB_NADDR16_HI 104 -#define R_PPC_EMB_NADDR16_HA 105 -#define R_PPC_EMB_SDAI16 106 -#define R_PPC_EMB_SDA2I16 107 -#define R_PPC_EMB_SDA2REL 108 -#define R_PPC_EMB_SDA21 109 -#define R_PPC_EMB_MRKREF 110 -#define R_PPC_EMB_RELSEC16 111 -#define R_PPC_EMB_RELST_LO 112 -#define R_PPC_EMB_RELST_HI 113 -#define R_PPC_EMB_RELST_HA 114 -#define R_PPC_EMB_BIT_FLD 115 -#define R_PPC_EMB_RELSDA 116 - -#define R_SPARC_NONE 0 -#define R_SPARC_8 1 -#define R_SPARC_16 2 -#define R_SPARC_32 3 -#define R_SPARC_DISP8 4 -#define R_SPARC_DISP16 5 -#define R_SPARC_DISP32 6 -#define R_SPARC_WDISP30 7 -#define R_SPARC_WDISP22 8 -#define R_SPARC_HI22 9 -#define R_SPARC_22 10 -#define R_SPARC_13 11 -#define R_SPARC_LO10 12 -#define R_SPARC_GOT10 13 -#define R_SPARC_GOT13 14 -#define R_SPARC_GOT22 15 -#define R_SPARC_PC10 16 -#define R_SPARC_PC22 17 -#define R_SPARC_WPLT30 18 -#define R_SPARC_COPY 19 -#define R_SPARC_GLOB_DAT 20 -#define R_SPARC_JMP_SLOT 21 -#define R_SPARC_RELATIVE 22 -#define R_SPARC_UA32 23 -#define R_SPARC_PLT32 24 -#define R_SPARC_HIPLT22 25 -#define R_SPARC_LOPLT10 26 -#define R_SPARC_PCPLT32 27 -#define R_SPARC_PCPLT22 28 -#define R_SPARC_PCPLT10 29 -#define R_SPARC_10 30 -#define R_SPARC_11 31 -#define R_SPARC_64 32 -#define R_SPARC_OLO10 33 -#define R_SPARC_HH22 34 -#define R_SPARC_HM10 35 -#define R_SPARC_LM22 36 -#define R_SPARC_PC_HH22 37 -#define R_SPARC_PC_HM10 38 -#define R_SPARC_PC_LM22 39 -#define R_SPARC_WDISP16 40 -#define R_SPARC_WDISP19 41 -#define R_SPARC_GLOB_JMP 42 -#define R_SPARC_7 43 -#define R_SPARC_5 44 -#define R_SPARC_6 45 -#define R_SPARC_DISP64 46 -#define R_SPARC_PLT64 47 -#define R_SPARC_HIX22 48 -#define R_SPARC_LOX10 49 -#define R_SPARC_H44 50 -#define R_SPARC_M44 51 -#define R_SPARC_L44 52 -#define R_SPARC_REGISTER 53 -#define R_SPARC_UA64 54 -#define R_SPARC_UA16 55 -#define R_SPARC_TLS_GD_HI22 56 -#define R_SPARC_TLS_GD_LO10 57 -#define R_SPARC_TLS_GD_ADD 58 -#define R_SPARC_TLS_GD_CALL 59 -#define R_SPARC_TLS_LDM_HI22 60 -#define R_SPARC_TLS_LDM_LO10 61 -#define R_SPARC_TLS_LDM_ADD 62 -#define R_SPARC_TLS_LDM_CALL 63 -#define R_SPARC_TLS_LDO_HIX22 64 -#define R_SPARC_TLS_LDO_LOX10 65 -#define R_SPARC_TLS_LDO_ADD 66 -#define R_SPARC_TLS_IE_HI22 67 -#define R_SPARC_TLS_IE_LO10 68 -#define R_SPARC_TLS_IE_LD 69 -#define R_SPARC_TLS_IE_LDX 70 -#define R_SPARC_TLS_IE_ADD 71 -#define R_SPARC_TLS_LE_HIX22 72 -#define R_SPARC_TLS_LE_LOX10 73 -#define R_SPARC_TLS_DTPMOD32 74 -#define R_SPARC_TLS_DTPMOD64 75 -#define R_SPARC_TLS_DTPOFF32 76 -#define R_SPARC_TLS_DTPOFF64 77 -#define R_SPARC_TLS_TPOFF32 78 -#define R_SPARC_TLS_TPOFF64 79 - -#define R_X86_64_NONE 0 /* No relocation. */ -#define R_X86_64_64 1 /* Add 64 bit symbol value. */ -#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */ -#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */ -#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */ -#define R_X86_64_COPY 5 /* Copy data from shared object. */ -#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */ -#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */ -#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */ -#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */ -#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */ -#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */ -#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */ -#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */ -#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */ -#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */ -#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ -#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */ -#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */ -#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */ -#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */ -#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ -#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */ -#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */ -#define R_X86_64_PC64 24 /* PC relative 64 bit */ -#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ -#define R_X86_64_GOTPC3 26 /* 32 bit signed pc relative offset to GOT */ -#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ -#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset to GOT entry */ -#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ -#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ -#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset to PLT entry */ -#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ -#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ -#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ -#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS descriptor. */ -#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ -#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ -#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */ -#define R_X86_64_GOTPCRELX 41 /* Load from 32 bit signed pc relative offset to GOT entry without REX prefix, relaxable. */ -#define R_X86_64_REX_GOTPCRELX 42 /* Load from 32 bit signed pc relative offset to GOT entry with REX prefix, relaxable. */ - -/* - * RISC-V relocation types - */ - -/* Relocation types used by the dynamic linker */ -#define R_RISCV_NONE 0 -#define R_RISCV_32 1 -#define R_RISCV_64 2 -#define R_RISCV_RELATIVE 3 -#define R_RISCV_COPY 4 -#define R_RISCV_JUMP_SLOT 5 -#define R_RISCV_TLS_DTPMOD32 6 -#define R_RISCV_TLS_DTPMOD64 7 -#define R_RISCV_TLS_DTPREL32 8 -#define R_RISCV_TLS_DTPREL64 9 -#define R_RISCV_TLS_TPREL32 10 -#define R_RISCV_TLS_TPREL64 11 - -/* Relocation types not used by the dynamic linker */ -#define R_RISCV_BRANCH 16 -#define R_RISCV_JAL 17 -#define R_RISCV_CALL 18 -#define R_RISCV_CALL_PLT 19 -#define R_RISCV_GOT_HI20 20 -#define R_RISCV_TLS_GOT_HI20 21 -#define R_RISCV_TLS_GD_HI20 22 -#define R_RISCV_PCREL_HI20 23 -#define R_RISCV_PCREL_LO12_I 24 -#define R_RISCV_PCREL_LO12_S 25 -#define R_RISCV_HI20 26 -#define R_RISCV_LO12_I 27 -#define R_RISCV_LO12_S 28 -#define R_RISCV_TPREL_HI20 29 -#define R_RISCV_TPREL_LO12_I 30 -#define R_RISCV_TPREL_LO12_S 31 -#define R_RISCV_TPREL_ADD 32 -#define R_RISCV_ADD8 33 -#define R_RISCV_ADD16 34 -#define R_RISCV_ADD32 35 -#define R_RISCV_ADD64 36 -#define R_RISCV_SUB8 37 -#define R_RISCV_SUB16 38 -#define R_RISCV_SUB32 39 -#define R_RISCV_SUB64 40 -#define R_RISCV_GNU_VTINHERIT 41 -#define R_RISCV_GNU_VTENTRY 42 -#define R_RISCV_ALIGN 43 -#define R_RISCV_RVC_BRANCH 44 -#define R_RISCV_RVC_JUMP 45 -#define R_RISCV_RVC_LUI 46 -#define R_RISCV_GPREL_I 47 -#define R_RISCV_GPREL_S 48 -#define R_RISCV_TPREL_I 49 -#define R_RISCV_TPREL_S 50 -#define R_RISCV_RELAX 51 -#define R_RISCV_SUB6 52 -#define R_RISCV_SET6 53 -#define R_RISCV_SET8 54 -#define R_RISCV_SET16 55 -#define R_RISCV_SET32 56 - -/* - * LoongArch relocation types - */ -#define R_LARCH_NONE 0 -#define R_LARCH_32 1 -#define R_LARCH_64 2 -#define R_LARCH_RELATIVE 3 -#define R_LARCH_COPY 4 -#define R_LARCH_JUMP_SLOT 5 -#define R_LARCH_TLS_DTPMOD32 6 -#define R_LARCH_TLS_DTPMOD64 7 -#define R_LARCH_TLS_DTPREL32 8 -#define R_LARCH_TLS_DTPREL64 9 -#define R_LARCH_TLS_TPREL32 10 -#define R_LARCH_TLS_TPREL64 11 -#define R_LARCH_IRELATIVE 12 -#define R_LARCH_MARK_LA 20 -#define R_LARCH_MARK_PCREL 21 -#define R_LARCH_SOP_PUSH_PCREL 22 -#define R_LARCH_SOP_PUSH_ABSOLUTE 23 -#define R_LARCH_SOP_PUSH_DUP 24 -#define R_LARCH_SOP_PUSH_GPREL 25 -#define R_LARCH_SOP_PUSH_TLS_TPREL 26 -#define R_LARCH_SOP_PUSH_TLS_GOT 27 -#define R_LARCH_SOP_PUSH_TLS_GD 28 -#define R_LARCH_SOP_PUSH_PLT_PCREL 29 -#define R_LARCH_SOP_ASSERT 30 -#define R_LARCH_SOP_NOT 31 -#define R_LARCH_SOP_SUB 32 -#define R_LARCH_SOP_SL 33 -#define R_LARCH_SOP_SR 34 -#define R_LARCH_SOP_ADD 35 -#define R_LARCH_SOP_AND 36 -#define R_LARCH_SOP_IF_ELSE 37 -#define R_LARCH_SOP_POP_32_S_10_5 38 -#define R_LARCH_SOP_POP_32_U_10_12 39 -#define R_LARCH_SOP_POP_32_S_10_12 40 -#define R_LARCH_SOP_POP_32_S_10_16 41 -#define R_LARCH_SOP_POP_32_S_10_16_S2 42 -#define R_LARCH_SOP_POP_32_S_5_20 43 -#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44 -#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45 -#define R_LARCH_SOP_POP_32_U 46 -#define R_LARCH_ADD8 47 -#define R_LARCH_ADD16 48 -#define R_LARCH_ADD24 49 -#define R_LARCH_ADD32 50 -#define R_LARCH_ADD64 51 -#define R_LARCH_SUB8 52 -#define R_LARCH_SUB16 53 -#define R_LARCH_SUB24 54 -#define R_LARCH_SUB32 55 -#define R_LARCH_SUB64 56 -#define R_LARCH_GNU_VTINHERIT 57 -#define R_LARCH_GNU_VTENTRY 58 -#define R_LARCH_B16 64 -#define R_LARCH_B21 65 -#define R_LARCH_B26 66 -#define R_LARCH_ABS_HI20 67 -#define R_LARCH_ABS_LO12 68 -#define R_LARCH_ABS64_LO20 69 -#define R_LARCH_ABS64_HI12 70 -#define R_LARCH_PCALA_HI20 71 -#define R_LARCH_PCALA_LO12 72 -#define R_LARCH_PCALA64_LO20 73 -#define R_LARCH_PCALA64_HI12 74 -#define R_LARCH_GOT_PC_HI20 75 -#define R_LARCH_GOT_PC_LO12 76 -#define R_LARCH_GOT64_PC_LO20 77 -#define R_LARCH_GOT64_PC_HI12 78 -#define R_LARCH_GOT64_HI20 79 -#define R_LARCH_GOT64_LO12 80 -#define R_LARCH_GOT64_LO20 81 -#define R_LARCH_GOT64_HI12 82 -#define R_LARCH_TLS_LE_HI20 83 -#define R_LARCH_TLS_LE_LO12 84 -#define R_LARCH_TLS_LE64_LO20 85 -#define R_LARCH_TLS_LE64_HI12 86 -#define R_LARCH_TLS_IE_PC_HI20 87 -#define R_LARCH_TLS_IE_PC_LO12 88 -#define R_LARCH_TLS_IE64_PC_LO20 89 -#define R_LARCH_TLS_IE64_PC_HI12 90 -#define R_LARCH_TLS_IE64_HI20 91 -#define R_LARCH_TLS_IE64_LO12 92 -#define R_LARCH_TLS_IE64_LO20 93 -#define R_LARCH_TLS_IE64_HI12 94 -#define R_LARCH_TLS_LD_PC_HI20 95 -#define R_LARCH_TLS_LD64_HI20 96 -#define R_LARCH_TLS_GD_PC_HI20 97 -#define R_LARCH_TLS_GD64_HI20 98 -#define R_LARCH_32_PCREL 99 -#define R_LARCH_RELAX 100 -#define R_LARCH_DELETE 101 -#define R_LARCH_ALIGN 102 -#define R_LARCH_PCREL20_S2 103 -#define R_LARCH_CFA 104 -#define R_LARCH_ADD6 105 -#define R_LARCH_SUB6 106 -#define R_LARCH_ADD_ULEB128 107 -#define R_LARCH_SUB_ULEB128 108 -#define R_LARCH_64_PCREL 109 - -#endif /* !_SYS_ELF_COMMON_H_ */ diff --git a/BaseTools/Source/C/Makefile b/BaseTools/Source/C/Makefile index 0f26de0aa1..7895b930fc 100644 --- a/BaseTools/Source/C/Makefile +++ b/BaseTools/Source/C/Makefile @@ -18,7 +18,6 @@ APPLICATIONS = \ GenCrc32 \ GenFfs \ GenFv \ - GenFw \ GenSec \ LzmaCompress \ TianoCompress \ diff --git a/BaseTools/Source/C/Makefiles/ms.app b/BaseTools/Source/C/Makefiles/ms.app index aecae37396..0e6e16474c 100644 --- a/BaseTools/Source/C/Makefiles/ms.app +++ b/BaseTools/Source/C/Makefiles/ms.app @@ -19,10 +19,9 @@ $(OBJECTS) : $(SOURCE_PATH)\Include\Common\BuildVersion.h .PHONY:cleanall clean: - del /f /q $(OBJECTS) *.pdb > nul + del /f /q *.obj *.pdb > nul cleanall: - del /f /q $(OBJECTS) $(APPLICATION) *.pdb $(BIN_PATH)\$(APPNAME).pdb > nul + del /f /q *.obj $(APPLICATION) *.pdb $(BIN_PATH)\$(APPNAME).pdb > nul !INCLUDE $(SOURCE_PATH)\Makefiles\ms.rule - diff --git a/BaseTools/Source/Python/Common/ToolDefClassObject.py b/BaseTools/Source/Python/Common/ToolDefClassObject.py index afc20a3c17..aa4d971d62 100644 --- a/BaseTools/Source/Python/Common/ToolDefClassObject.py +++ b/BaseTools/Source/Python/Common/ToolDefClassObject.py @@ -103,11 +103,32 @@ def IncludeToolDefFile(self, FileName): else: EdkLogger.error("tools_def.txt parser", FILE_NOT_FOUND, ExtraData=FileName) + Branch = 0 for Index in range(len(FileContent)): Line = FileContent[Index].strip() if Line == "" or Line[0] == '#': continue + if Line.startswith("!ifdef"): + Condition = Line[6:].strip() + Reference = GlobalData.gMacroRefPattern.findall(Condition) + if Reference[0] in GlobalData.gCommandLineDefines: + Branch = 1 + else: + Branch = -1 + continue + + if Line.startswith("!else"): + Branch *= -1 + continue + + if Line.startswith("!endif"): + Branch = 0 + continue + + if Branch == -1: + continue + if Line.startswith("!include"): IncFile = Line[8:].strip() Done, IncFile = self.ExpandMacros(IncFile) diff --git a/BaseTools/Source/Python/GenFds/DataSection.py b/BaseTools/Source/Python/GenFds/DataSection.py index 5af3ee7b7f..abf75abcc7 100644 --- a/BaseTools/Source/Python/GenFds/DataSection.py +++ b/BaseTools/Source/Python/GenFds/DataSection.py @@ -94,7 +94,7 @@ def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = No StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped') GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, - [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)], + GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict), Strip=True, IsMakefile = IsMakefile ) diff --git a/BaseTools/Source/Python/GenFds/EfiSection.py b/BaseTools/Source/Python/GenFds/EfiSection.py index ca7a447008..bbbf3eca6b 100644 --- a/BaseTools/Source/Python/GenFds/EfiSection.py +++ b/BaseTools/Source/Python/GenFds/EfiSection.py @@ -289,7 +289,7 @@ def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = Non StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped') GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, - [File], + File, Strip=True, IsMakefile = IsMakefile ) diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py index 4e26a5af9d..f59cd596f9 100644 --- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -792,7 +792,7 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, - [File], + File, Strip=True, IsMakefile=IsMakefile ) @@ -835,7 +835,7 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, - [GenSecInputFile], + GenSecInputFile, Strip=True, IsMakefile=IsMakefile ) diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py index d7668ba681..68faace90f 100644 --- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py +++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py @@ -607,36 +607,17 @@ def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Ca GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV") @staticmethod - def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False, - Strip=False, Replace=False, TimeStamp=None, Join=False, - Align=None, Padding=None, Convert=False, IsMakefile=False): + def GenerateFirmwareImage(Output, Input, Format="Auto", Strip=False, IsMakefile=False): if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile: return GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) - Cmd = ["GenFw"] - if Type.lower() == "te": - Cmd.append("-t") - if SubType: - Cmd += ("-e", SubType) - if TimeStamp: - Cmd += ("-s", TimeStamp) - if Align: - Cmd += ("-a", Align) - if Padding: - Cmd += ("-p", Padding) - if Zero: - Cmd.append("-z") + Cmd = ["ImageTool GenImage"] + if Format != "Auto": + Cmd += ("-c", Format) if Strip: - Cmd.append("-l") - if Replace: - Cmd.append("-r") - if Join: - Cmd.append("-j") - if Convert: - Cmd.append("-m") - Cmd += ("-o", Output) - Cmd += Input + Cmd.append("-s") + Cmd += ("-o", Output, Input) if IsMakefile: if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip()) diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py index 497bbbd646..b9a720d605 100644 --- a/BaseTools/Source/Python/build/BuildReport.py +++ b/BaseTools/Source/Python/build/BuildReport.py @@ -644,11 +644,11 @@ def GenerateReport(self, File, GlobalPcdReport, GlobalPredictionReport, GlobalDe if os.path.isfile(DefaultEFIfile): Tempfile = os.path.join(OutputDir, self.ModuleName + "_hash.tmp") # rebase the efi image since its base address may not zero - cmd = ["GenFw", "--rebase", str(0), "-o", Tempfile, DefaultEFIfile] + cmd = ["ImageTool GenImage -b 0 -o", Tempfile, DefaultEFIfile] try: PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) except Exception as X: - EdkLogger.error("GenFw", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0])) + EdkLogger.error("ImageTool", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0])) EndOfProcedure = threading.Event() EndOfProcedure.clear() if PopenObject.stderr: @@ -661,7 +661,7 @@ def GenerateReport(self, File, GlobalPcdReport, GlobalPredictionReport, GlobalDe if PopenObject.stderr: StdErrThread.join() if PopenObject.returncode != 0: - EdkLogger.error("GenFw", COMMAND_FAILURE, "Failed to generate firmware hash image for %s" % (DefaultEFIfile)) + EdkLogger.error("ImageTool", COMMAND_FAILURE, "Failed to generate firmware hash image for %s" % (DefaultEFIfile)) if os.path.isfile(Tempfile): self.Hash = hashlib.sha1() buf = open(Tempfile, 'rb').read() diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py index 9fb5ae758e..ac2c8d6bc4 100755 --- a/BaseTools/Source/Python/build/build.py +++ b/BaseTools/Source/Python/build/build.py @@ -1540,18 +1540,18 @@ def _RebaseModule (self, MapBuffer, BaseAddress, ModuleList, AddrIsOffset = True BaseAddress = BaseAddress - ModuleInfo.Image.Size BaseAddress = AlignDown(BaseAddress, ModuleInfo.Image.SectionAlignment) # - # Update Image to new BaseAddress by GenFw tool + # Update Image to new BaseAddress by ImageTool tool # - LaunchCommand(["GenFw", "--rebase", str(BaseAddress), "-r", ModuleOutputImage], ModuleInfo.OutputDir) - LaunchCommand(["GenFw", "--rebase", str(BaseAddress), "-r", ModuleDebugImage], ModuleInfo.DebugDir) + LaunchCommand(["ImageTool", "GenImage", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir) + LaunchCommand(["ImageTool", "GenImage", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir) ## for SMM module in SMRAM, the SMRAM will be allocated from base to top. else: BaseAddress = AlignUp(BaseAddress, ModuleInfo.Image.SectionAlignment) # # Set new address to the section header only for SMM driver. # - LaunchCommand(["GenFw", "--address", str(BaseAddress), "-r", ModuleOutputImage], ModuleInfo.OutputDir) - LaunchCommand(["GenFw", "--address", str(BaseAddress), "-r", ModuleDebugImage], ModuleInfo.DebugDir) + LaunchCommand(["ImageTool", "GenImage", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir) + LaunchCommand(["ImageTool", "GenImage", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir) # # Collect function address from Map file # diff --git a/BaseTools/UserManuals/GenFds_Utility_Man_Page.rtf b/BaseTools/UserManuals/GenFds_Utility_Man_Page.rtf index 9192bb699e..eed8ba70e2 100644 --- a/BaseTools/UserManuals/GenFds_Utility_Man_Page.rtf +++ b/BaseTools/UserManuals/GenFds_Utility_Man_Page.rtf @@ -289,7 +289,7 @@ Build\\Nt32\\Debug_MyTools. ActivePlatform is C:\\work\\EdkII\\Nt32Pkg\\Nt32Pkg \par }\pard\plain \ltrpar\s2\ql \li-1440\ri0\sb400\sa60\sl-340\slmult0\keep\keepn\nowidctlpar\tx1440\wrapdefault\faauto\outlinelevel1\rin0\lin-1440\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\loch\af41\hich\af41\dbch\af13\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af41\afs28 \ltrch\fcs0 \b\fs28\cf17\insrsid5513321 \hich\af41\dbch\af13\loch\f41 See also \par }\pard\plain \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\loch\af41\hich\af41\dbch\af13\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af41\afs18 \ltrch\fcs0 -\fs18\cf1\insrsid5513321 \hich\af41\dbch\af13\loch\f41 GenFv, GenFfs, GenSection, GenFw. +\fs18\cf1\insrsid5513321 \hich\af41\dbch\af13\loch\f41 GenFv, GenFfs, GenSection. \par }\pard\plain \ltrpar\s2\ql \li-1440\ri0\sb400\sa60\sl-340\slmult0\keep\keepn\nowidctlpar\tx1440\wrapdefault\faauto\outlinelevel1\rin0\lin-1440\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\loch\af41\hich\af41\dbch\af13\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af41\afs28 \ltrch\fcs0 \b\fs28\cf17\insrsid5513321 \hich\af41\dbch\af13\loch\f41 License \par }\pard\plain \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\loch\af41\hich\af41\dbch\af13\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af41\afs18 \ltrch\fcs0 diff --git a/BaseTools/UserManuals/GenFw_Utility_Man_Page.rtf b/BaseTools/UserManuals/GenFw_Utility_Man_Page.rtf deleted file mode 100644 index ab7ba045e3..0000000000 --- a/BaseTools/UserManuals/GenFw_Utility_Man_Page.rtf +++ /dev/null @@ -1,179 +0,0 @@ -{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033\deflangfe1033\deftab360{\fonttbl{\f0\fswiss\fprq2\fcharset0 Verdana;}{\f1\froman\fprq2\fcharset0 Times New Roman;}{\f2\fmodern\fprq1\fcharset0 Courier New;}{\f3\fmodern\fprq1\fcharset0 Consolas;}} -{\colortbl ;\red8\green96\blue168;\red0\green0\blue0;\red0\green127\blue127;\red128\green0\blue0;\red0\green0\blue255;} -{\stylesheet{ Normal;}{\s1 heading 1;}{\s2 heading 2;}} -{\*\generator Riched20 10.0.22621}{\*\mmathPr\mnaryLim0\mdispDef1\mwrapIndent1440 }\viewkind4\uc1 -\pard\keep\keepn\nowidctlpar\s2\li-1440\sb400\sa60\sl-340\slmult0\cf1\b\f0\fs28 Name\par - -\pard\nowidctlpar\sb200\cf2\b0\fs18 GenFw.exe \endash build a UEFI image or other image.\par - -\pard\keep\keepn\nowidctlpar\s2\li-1440\sb400\sa60\sl-340\slmult0\tx1440\cf1\b\fs28 Synopsis\par - -\pard\nowidctlpar\sb200\cf2\fs18 GenFw.exe -r | -o [-e ] [-c | -t | -l | -u | -b | -z | -s | -m | -j | --hiipackage | --hiibinpackage | --nonxcompat] [-a] [-p] \par - -\pard\nowidctlpar GenFw.exe \endash h\par -GenFw.exe --version\cf0\b0\fs24\par - -\pard\nowidctlpar\sb200\cf2\f1\fs18\par - -\pard\keep\keepn\nowidctlpar\s2\li-1440\sb400\sa60\sl-340\slmult0\cf1\b\f0\fs28 Description\par - -\pard\nowidctlpar\sb200\cf2\b0\fs18 Genfw is mainly used to process PE32 image to get the expected image data or image file. PE32 is a general-purpose image format that contains, among other information, data identifying the target environment for execution of the image. This utility can modify the standard PE32 image to create UEFI image with EFI subsystem type, PI Terse Executable image with the compact TE image header, zero its debug data or reset its time stamp. It can also extract PE32 image data to create bin file, extract PE32 image data section to create Acpi table image, or dump PI TE image header information. It can also parse the text MicroCode definition file to create the MicroCode binary image, merge (concatenate) several MicroCode binary images into a single file by pad value and alignment requirement. This tool also supports the override the input file with the output contents.\par - -\pard\keep\keepn\nowidctlpar\s2\li-1440\sb400\sa60\sl-340\slmult0\cf1\b\fs28 Options\par - -\pard\nowidctlpar\sb200\cf2\b0\fs18 If no options are specified, tool prints usage.\b\par -Filename1 [FilenameN]\par - -\pard\nowidctlpar\li360\sb200\b0 Input PE/PE32+ image, or TE image, or MicroCode Txt file, or MicroCode bin file, or hii binary packages.\par - -\pard\nowidctlpar\sb200\b -o FileName, --outputfile FileName\par - -\pard\nowidctlpar\li360\sb200\b0 The EFI image, TeImage, AcpiImage, MicroBin, hii package lists file or other modified PE image will be created.\par - -\pard\nowidctlpar\sb200\b -e EFI_FILETYPE, --efiImage EFI_FILETYPE\par - -\pard\nowidctlpar\li360\sb200\b0 Create Efi Image. EFI_FILETYPE is one of BASE, SEC, PEI_CORE, PEIM, DXE_CORE, SMM_CORE, DXE_DRIVER, UEFI_APPLICATION, DXE_SAL_DRIVER, UEFI_DRIVER, DXE_RUNTIME_DRIVER, DXE_SMM_DRIVER, SECURITY_CORE, COMBINED_PEIM_DRIVER, PIC_PEIM, RELOCATABLE_PEIM, BS_DRIVER, RT_DRIVER, APPLICATION, SAL_RT_DRIVER to support all module types.\f1\par - -\pard\nowidctlpar\sb200\b\f0 -c, --acpi\par - -\pard\nowidctlpar\fi360\sb200\b0 Create Acpi table.\par - -\pard\nowidctlpar\sb200\b -t, --terse\par - -\pard\nowidctlpar\fi360\sb200\b0 Create Te Image.\par - -\pard\nowidctlpar\sb200\b -u, --dump\par - -\pard\nowidctlpar\fi360\sb200\b0 Dump TeImage Header.\par - -\pard\nowidctlpar\sb200\b -z, --zero\par - -\pard\nowidctlpar\fi360\sb200\b0 Zero the Debug Data Fields in the PE input image file. It also zeros the time stamp fields.\f1\par - -\pard\nowidctlpar\sb200\b\f0 -b, --exe2bin\par - -\pard\nowidctlpar\fi360\sb200\b0 Convert the input EXE to the output BIN file.\par - -\pard\nowidctlpar\sb200\b -l, --stripped\par - -\pard\nowidctlpar\fi360\sb200\b0 Strip off the relocation information data from PE or TE image.\f1\par - -\pard\nowidctlpar\sb200\b\f0 -s timedate, --stamp timedate\par - -\pard\nowidctlpar\li360\sb200\b0 timedate format is \ldblquote yyyy-mm-dd 00:00:00\rdblquote . If timedata is set to \ldblquote NOW\rdblquote , current system time is used. The support date scope is 1970-1-1 8:0:0 ~ 2038-1-19 3:14:07.\f1\par - -\pard\nowidctlpar\sb200\b\f0 -m, --mcifile\par - -\pard\nowidctlpar\fi360\sb200\b0 Convert input microcode txt definition file to microcode bin file.\par - -\pard\nowidctlpar\sb200\b -j, --join\par - -\pard\nowidctlpar\fi360\sb200\b0 Merge multiple microcode bin files to one file.\par - -\pard\nowidctlpar\sb200\b -a NUM, --align NUM\par - -\pard\nowidctlpar\li360\sb200\b0 NUM is one HEX or DEC format alignment value, which is used to combine multiple microcode bin files.\par - -\pard\nowidctlpar\sb200\b -p NUM, --pad NUM\par - -\pard\nowidctlpar\li360\sb200\b0 NUM is one HEX or DEC format padding value, which is used to combine multiple microcode bin files.\par - -\pard\nowidctlpar\sb200\b --keepexceptiontable\par - -\pard\nowidctlpar\fi360\sb200\b0 Don\rquote t clear exception table.\par - -\pard\nowidctlpar\sb200\b --keepzeropending\par - -\pard\nowidctlpar\fi360\sb200\b0 Don\rquote t strip zero pending of .reloc.\par - -\pard\nowidctlpar\sb200\b -r, --replace\par - -\pard\nowidctlpar\fi360\sb200\b0 Overwrite the input file with the output content.\par - -\pard\nowidctlpar\sb200\b -g HiiPackageListGuid, --hiiguid HiiPackageListGuid\par - -\pard\nowidctlpar\fi360\sb200\b0 Guid is used to specify hii package list guid.\f1\par -\f0 Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\par - -\pard\nowidctlpar\sb200\b --hiipackage \f1\par - -\pard\nowidctlpar\fi360\sb200\b0\f0 Combine all input binary hii packages into a single package list as the text resource data file (RC file format).\par - -\pard\nowidctlpar\sb200\b --hiibinpackage \f1\par - -\pard\nowidctlpar\fi360\sb200\b0\f0 Combine all input binary hii packages into a single package list as the binary resource section.\par - -\pard\nowidctlpar\sb200\b --nonxcompat \f1\par -\b0\f0 Do not set the IMAGE_DLLCHARACTERISTICS_NX_COMPAT bit of the optional header in the PE header even if the requirements are met.\par -\b -v, --verbose\b0\par - -\pard\nowidctlpar\fi360\sb200 Turn on verbose output with informational messages.\par - -\pard\nowidctlpar\sb200\b -d, --debug level\par -\b0\f1\tab\f0 Enable debug message with specified level.\par -\b --version\par - -\pard\nowidctlpar\fi360\sb200\b0 Show program's version number and exit\par - -\pard\nowidctlpar\sb200\b -h, --help\par - -\pard\nowidctlpar\fi360\sb200\b0 Show this help message and exit\par - -\pard\keep\keepn\nowidctlpar\s2\fi-1440\sb400\sa60\sl-340\slmult0\tx1440\cf3\b\fs28 Status codes returned\par -\trowd\trgaph10\trleft-118\trbrdrl\brdrs\brdrw10 \trbrdrt\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trpaddl10\trpaddr10\trpaddfl3\trpaddfr3 -\clbrdrl\brdrw10\brdrs\clbrdrt\brdrw10\brdrs\clbrdrr\brdrw10\brdrs\clbrdrb\brdrw10\brdrs \cellx2852\clbrdrl\brdrw10\brdrs\clbrdrt\brdrw10\brdrs\clbrdrr\brdrw10\brdrs\clbrdrb\brdrw10\brdrs \cellx8702 -\pard\intbl\widctlpar\ri20\sb60\sa60\sl-200\slmult0\cf4\kerning2\f2\fs18 STATUS_SUCCESS\cf2\kerning0\b0\f0\fs16 \cf4\kerning2\b\f2\fs18\tab 0\cf2\cell\kerning0\b0\f0\fs16 The action was completed as requested.\kerning2\cell\row\trowd\trgaph10\trleft-118\trbrdrl\brdrs\brdrw10 \trbrdrt\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trpaddl10\trpaddr10\trpaddfl3\trpaddfr3 -\clbrdrl\brdrw10\brdrs\clbrdrt\brdrw10\brdrs\clbrdrr\brdrw10\brdrs\clbrdrb\brdrw10\brdrs \cellx2852\clbrdrl\brdrw10\brdrs\clbrdrt\brdrw10\brdrs\clbrdrr\brdrw10\brdrs\clbrdrb\brdrw10\brdrs \cellx8702 -\pard\intbl\widctlpar\ri20\sb60\sa60\sl-200\slmult0\cf4\b\f2\fs18 STATUS_ERROR\cf2\kerning0\b0\f0\fs16 \cf4\kerning2\b\f2\fs18\tab\tab 2\cf0\kerning0\b0\f3\fs19\cell\cf2\kerning2\f0\fs16 The action failed.\cell\row -\pard\keep\keepn\nowidctlpar\s2\li-1440\sb400\sa60\sl-340\slmult0\cf1\kerning0\b\fs28 Example\par - -\pard\nowidctlpar\sb200\cf2\b0\fs18 1. Generate Efi image with the input PE image, module type and the output file name.\par -\b GenFw \endash e PEI_CORE PeiMain.dll \endash o PeiMain.efi\par -\b0 2. Generate Te image with the input PE image and the output file name.\par -\b GenFw \endash t PeiMain.dll \endash o PeiMain.te\par -\b0 3. Generate acpi table image with the input PE image and the output file name.\par -\b GenFw \endash c Facs.dll \endash o Facs.acpi\par -\b0 4. Dump TeImage Header with the input Te Image and the output file name.\par -\b GenFw \endash u PeiMain.te \endash o PeiMain.teheader\par -\b0 5. Modify PeImage by zero its debug data.\par -\b GenFw \endash z PeiMain.dll \endash o Peimain.zero\par -\b0 6. Modify PeImage by set new timestamp and override the input image without the output file name.\par -\b GenFw \endash s \ldblquote 2007-8-16 16:06:32\rdblquote PeiMain.dll \endash r\par -\b0 7. Extract bin image from PeImage.\par -\b GenFw \endash b PeiMain.dll \endash o PeiMain.bin\par -\b0 8. Generate the microcode binary file from the micro code txt file.\par -\b GenFw \endash m Mci.txt \endash o Mci.bin\par -\b0 9. Merge the multiple mci binary files to one file.\par -\b GenFw \endash j Mci.bin1 Mci.bin2 Mci.bin3 \endash a 32 \endash p 0xFF \endash o Mci.bin\par -\b0 10. Generate the text resource file (RC format) based on all input binary HII packages and their package list guid.\par -\b GenFw \endash o SampleHii.rc \endash g D49D2EB0-44D5-4621-9FD6-1A92C9109B99 \endash hiipackage SampleStr.hpk SampleVfr.hpk\f1\par -\b0\f0 11. Generate the binary resource section based on all input binary HII packages and their package list guid.\f1\par -\b\f0 GenFw \endash o SampleHii.bin \endash g D49D2EB0-44D5-4621-9FD6-1A92C9109B99 \endash hiibinpackage SampleStr.hpk SampleVfr.hpk\f1\par - -\pard\keep\keepn\nowidctlpar\s2\li-1440\sb400\sa60\sl-340\slmult0\cf1\f0\fs28 Bugs\par - -\pard\nowidctlpar\sb200\cf2\b0\fs18 No known bugs.\par -Report bugs to \cf5\revised edk2-devel@lists.01.org\cf2\revised0\deleted edk2-buildtools-devel@lists.sourceforge.net\deleted0\f1\par - -\pard\keep\keepn\nowidctlpar\s2\li-1440\sb400\sa60\sl-340\slmult0\cf1\b\f0\fs28 Files\par - -\pard\nowidctlpar\sb200\cf2\b0\fs18 None\par - -\pard\keep\keepn\nowidctlpar\s2\li-1440\sb400\sa60\sl-340\slmult0\cf1\b\fs28 See also\par - -\pard\nowidctlpar\sb200\cf2\b0\fs18 None\par - -\pard\keep\keepn\nowidctlpar\s2\li-1440\sb400\sa60\sl-340\slmult0\cf1\b\fs28 License\par - -\pard\nowidctlpar\cf2\b0\fs18 Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.\par -This program and the accompanying materials are licensed and made available \par -under the terms and conditions of the BSD License which accompanies this \par -distribution. The full text of the license may be found at\par -{{\field{\*\fldinst{HYPERLINK http://opensource.org/licenses/bsd-license.php }}{\fldrslt{http://opensource.org/licenses/bsd-license.php\ul0\cf0}}}}\f0\fs18\par -\par -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\par - -\pard\nowidctlpar\sb200 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\par -\cf0\f1\par -} - \ No newline at end of file diff --git a/BaseTools/toolsetup.bat b/BaseTools/toolsetup.bat index 8cfca3dc5c..04112383ae 100755 --- a/BaseTools/toolsetup.bat +++ b/BaseTools/toolsetup.bat @@ -271,7 +271,6 @@ if not exist "%EDK_TOOLS_BIN%" goto check_build_environment IF NOT EXIST "%EDK_TOOLS_BIN%\EfiRom.exe" goto check_c_tools IF NOT EXIST "%EDK_TOOLS_BIN%\GenFfs.exe" goto check_c_tools IF NOT EXIST "%EDK_TOOLS_BIN%\GenFv.exe" goto check_c_tools -IF NOT EXIST "%EDK_TOOLS_BIN%\GenFw.exe" goto check_c_tools IF NOT EXIST "%EDK_TOOLS_BIN%\GenSec.exe" goto check_c_tools IF NOT EXIST "%EDK_TOOLS_BIN%\TianoCompress.exe" goto check_c_tools IF NOT EXIST "%EDK_TOOLS_BIN%\VfrCompile.exe" goto check_c_tools diff --git a/MdePkg/Include/Library/UefiImageLib.h b/MdePkg/Include/Library/UefiImageLib.h index b0de4b317c..ecdb706fd9 100644 --- a/MdePkg/Include/Library/UefiImageLib.h +++ b/MdePkg/Include/Library/UefiImageLib.h @@ -2,6 +2,11 @@ #ifndef UEFI_IMAGE_LIB_H_ #define UEFI_IMAGE_LIB_H_ +typedef enum { + UefiImageFormatPe = 0, + UefiImageFormatMax +} UEFI_IMAGE_FORMAT; + // FIXME: Work on reasonable abstraction #ifndef UEFI_IMAGE_LOADER_IMAGE_CONTEXT #include diff --git a/MdePkg/Library/BaseCpuLib/Ia32/InitializeFpu.nasm b/MdePkg/Library/BaseCpuLib/Ia32/InitializeFpu.nasm index 5e27cc3250..3b0197a284 100644 --- a/MdePkg/Library/BaseCpuLib/Ia32/InitializeFpu.nasm +++ b/MdePkg/Library/BaseCpuLib/Ia32/InitializeFpu.nasm @@ -6,7 +6,7 @@ ;* ;------------------------------------------------------------------------------ - SECTION .rodata + SECTION RODATA_SECTION_NAME ; ; Float control word initial value: @@ -65,4 +65,3 @@ Done: pop ebx ret - diff --git a/MdePkg/Library/BaseCpuLib/X64/InitializeFpu.nasm b/MdePkg/Library/BaseCpuLib/X64/InitializeFpu.nasm index 8485b47135..22a5645abc 100644 --- a/MdePkg/Library/BaseCpuLib/X64/InitializeFpu.nasm +++ b/MdePkg/Library/BaseCpuLib/X64/InitializeFpu.nasm @@ -6,7 +6,7 @@ ;* ;------------------------------------------------------------------------------ - SECTION .rodata + SECTION RODATA_SECTION_NAME ; ; Float control word initial value: ; all exceptions masked, double-extended-precision, round-to-nearest @@ -48,4 +48,3 @@ ASM_PFX(InitializeFloatingPointUnits): ldmxcsr [mMmxControlWord] ret - diff --git a/OpenCorePkg b/OpenCorePkg new file mode 160000 index 0000000000..ca9a501490 --- /dev/null +++ b/OpenCorePkg @@ -0,0 +1 @@ +Subproject commit ca9a501490ccce20431f095182b4fb0d359d80e3 diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 6d75ebdb24..735f828797 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -103,20 +103,6 @@ !include NetworkPkg/NetworkBuildOptions.dsc.inc -[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] - GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 - XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000 - XCODE:*_*_*_MTOC_FLAGS = -align 0x1000 - CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096 - -# Force PE/COFF sections to be aligned at 4KB boundaries to support page level -# protection of DXE_SMM_DRIVER/SMM_CORE modules -[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE] - GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 - XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000 - XCODE:*_*_*_MTOC_FLAGS = -align 0x1000 - CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096 - ################################################################################ # # SKU Identification section - list of all SKU IDs supported by this Platform. @@ -600,14 +586,15 @@ # !if $(LEGACY_WINDOWS_LOADER) == TRUE # Allow execution of EfiLoaderData memory regions. - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7FD1 + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFFD1 !elseif $(LINUX_LOADER) == TRUE - # Allow execution of EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7F41 + # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF40 gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE !elseif $(WINDOWS_10_IA32) == TRUE # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiRuntimeServicesData memory regions. - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7F04 + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF04 + gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x0 !endif ################################################################################ diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index b11a4523f8..4aa7f236a7 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -110,11 +110,6 @@ !include NetworkPkg/NetworkBuildOptions.dsc.inc - GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 - XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000 - XCODE:*_*_*_MTOC_FLAGS = -align 0x1000 - CLANGPDB:*_*_*_DLINK_FLAGS = /FILEALIGN:4096 /ALIGN:4096 - ################################################################################ # # SKU Identification section - list of all SKU IDs supported by this Platform. @@ -605,14 +600,15 @@ # !if $(LEGACY_WINDOWS_LOADER) == TRUE # Allow execution of EfiLoaderData memory regions. - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7FD1 + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFFD1 !elseif $(LINUX_LOADER) == TRUE - # Allow execution of EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7F41 + # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF40 gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE !elseif $(WINDOWS_10_IA32) == TRUE # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiRuntimeServicesData memory regions. - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7F04 + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF04 + gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x0 !endif ################################################################################ diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index 0a9a31df75..7f971dd9c2 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -82,11 +82,11 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvm 0x010000|0x010000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize -0x020000|0x0E0000 +0x020000|0x100000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize FV = PEIFV -0x100000|0xE80000 +0x120000|0xE60000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize FV = DXEFV diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index d562e47dae..a167addb60 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -120,20 +120,6 @@ !include NetworkPkg/NetworkBuildOptions.dsc.inc -[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] - GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 - XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000 - XCODE:*_*_*_MTOC_FLAGS = -align 0x1000 - CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096 - -# Force PE/COFF sections to be aligned at 4KB boundaries to support page level -# protection of DXE_SMM_DRIVER/SMM_CORE modules -[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE] - GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 - XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000 - XCODE:*_*_*_MTOC_FLAGS = -align 0x1000 - CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096 - ################################################################################ # # SKU Identification section - list of all SKU IDs supported by this Platform. @@ -603,7 +589,8 @@ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|0x100 # - # TDX need 1G PageTable support + # TDX needs 1G PageTable support + # gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable|TRUE # @@ -632,10 +619,10 @@ # !if $(LEGACY_WINDOWS_LOADER) == TRUE # Allow execution of EfiLoaderData memory regions. - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7FD1 + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFFD1 !elseif $(LINUX_LOADER) == TRUE - # Allow execution of EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0x7F41 + # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF40 gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE !endif diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 2602c3d2fe..547c6ee3b7 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -103,11 +103,11 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableBase|gUefiOvmfPkgTokenSpaceGui 0x011000|0x00F000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize -0x020000|0x0E0000 +0x020000|0x110000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize FV = PEIFV -0x100000|0xE80000 +0x130000|0xE50000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize FV = DXEFV diff --git a/UefiCpuPkg/SecCore/SecCoreNative.inf b/UefiCpuPkg/SecCore/SecCoreNative.inf index facb79c2c4..5edff00946 100644 --- a/UefiCpuPkg/SecCore/SecCoreNative.inf +++ b/UefiCpuPkg/SecCore/SecCoreNative.inf @@ -45,8 +45,8 @@ PcdLib DebugAgentLib CpuLib - PeCoffGetEntryPointLib - PeCoffExtraActionLib + UefiImageLib + UefiImageExtraActionLib CpuExceptionHandlerLib ReportStatusCodeLib PeiServicesLib diff --git a/UefiPayloadPkg/Library/UefiPayloadEntryMemoryAllocationLib/MemoryAllocation.c b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c old mode 100644 new mode 100755 similarity index 81% rename from UefiPayloadPkg/Library/UefiPayloadEntryMemoryAllocationLib/MemoryAllocation.c rename to UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c index 23bbf196cc..daf5fbd174 --- a/UefiPayloadPkg/Library/UefiPayloadEntryMemoryAllocationLib/MemoryAllocation.c +++ b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c @@ -8,7 +8,31 @@ **/ -#include "UefiPayloadEntry.h" +#include + +#include +#include +#include +#include +#include +#include + +/** + Add a new HOB to the HOB List. + + @param HobType Type of the new HOB. + @param HobLength Length of the new HOB to allocate. + + @return NULL if there is no space to create a hob. + @return The address point to the new created hob. + +**/ +VOID * +EFIAPI +CreateHob ( + IN UINT16 HobType, + IN UINT16 HobLength + ); /** Allocates one or more pages of type EfiBootServicesData. @@ -246,3 +270,28 @@ AllocateZeroPool ( return Buffer; } + +/** + Frees a buffer that was previously allocated with one of the pool allocation functions in the + Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + pool allocation services of the Memory Allocation Library. If it is not possible to free pool + resources, then this function will perform no actions. + + If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, + then ASSERT(). + + @param Buffer The pointer to the buffer to free. + +**/ +VOID +EFIAPI +FreePool ( + IN VOID *Buffer + ) +{ + // + // PEI phase does not support to free pool, so leave it as NOP. + // +} diff --git a/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.inf b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.inf new file mode 100755 index 0000000000..46ca835552 --- /dev/null +++ b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.inf @@ -0,0 +1,39 @@ +## @file +# Instance of Memory Allocation Library using PEI Services. +# +# Memory Allocation Library that uses PEI Services to allocate memory. +# Free operations are ignored. +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UefiPayloadMemoryAllocationLib + MODULE_UNI_FILE = UefiPayloadMemoryAllocationLib.uni + FILE_GUID = b694e0dc-cd4e-4b30-885b-9c164ed3e74a + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = MemoryAllocationLib|PEIM PEI_CORE SEC + + +# +# VALID_ARCHITECTURES = IA32 X64 EBC (EBC is for build only) +# + +[Sources] + MemoryAllocationLib.c + +[Packages] + MdePkg/MdePkg.dec + + +[LibraryClasses] + DebugLib + BaseMemoryLib + BaseLib + HobLib diff --git a/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.uni b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.uni new file mode 100755 index 0000000000..0194972ecf --- /dev/null +++ b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.uni @@ -0,0 +1,16 @@ +// /** @file +// Instance of Memory Allocation Library using PEI Services. +// +// Memory Allocation Library that uses PEI Services to allocate memory. +// Free operations are ignored. +// +// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Instance of Memory Allocation Library for Uefi payloads" + +#string STR_MODULE_DESCRIPTION #language en-US "Memory Allocation Library that allocates memory in uefi payload implementations. Free operations are ignored." diff --git a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/ElfCommon.h b/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/ElfCommon.h index 7559f229ef..aee9fd96b8 100644 --- a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/ElfCommon.h +++ b/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/ElfCommon.h @@ -539,7 +539,8 @@ typedef struct { #define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ /* Null relocation */ -#define R_AARCH64_NONE 256 /* No relocation */ +#define R_AARCH64_NONE0 0 +#define R_AARCH64_NONE 256 /* No relocation */ /* Static AArch64 relocations */ /* Static data relocations */ #define R_AARCH64_ABS64 257 /* S + A */ @@ -735,6 +736,7 @@ typedef struct { #define R_ARM_THM_MOVW_PREL_NC 49 #define R_ARM_THM_MOVT_PREL 50 #define R_ARM_THM_JMP6 52 +#define R_ARM_THM_JUMP19 51 #define R_ARM_THM_ALU_PREL_11_0 53 #define R_ARM_THM_PC12 54 #define R_ARM_REL32_NOI 56 @@ -752,21 +754,14 @@ typedef struct { #define R_ARM_LDC_PC_G1 68 #define R_ARM_LDC_PC_G2 69 #define R_ARM_GOT_PREL 96 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 #define R_ARM_THM_JUMP11 102 #define R_ARM_THM_JUMP8 103 #define R_ARM_TLS_GD32 104 #define R_ARM_TLS_LDM32 105 #define R_ARM_TLS_IE32 107 -#define R_ARM_THM_JUMP19 51 -#define R_ARM_GNU_VTENTRY 100 -#define R_ARM_GNU_VTINHERIT 101 -#define R_ARM_RSBREL32 250 -#define R_ARM_THM_RPC22 251 -#define R_ARM_RREL32 252 -#define R_ARM_RABS32 253 -#define R_ARM_RPC24 254 -#define R_ARM_RBASE 255 #define R_PPC_NONE 0/* No relocation. */ #define R_PPC_ADDR32 1 diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf index a13afd8ef3..2e8dec529f 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf @@ -20,7 +20,6 @@ [Sources] UniversalPayloadEntry.c LoadDxeCore.c - MemoryAllocation.c PrintHob.c AcpiTable.c [Sources.Ia32] @@ -48,6 +47,7 @@ HobPrintLib StackCheckLib UefiImageLib + MemoryAllocationLib [Guids] gEfiMemoryTypeInformationGuid diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index f0c713c8dd..931e5461c2 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -167,13 +167,6 @@ MSFT:RELEASE_*_*_CC_FLAGS = /D MDEPKG_NDEBUG !endif -[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] - GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 - XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000 - XCODE:*_*_*_MTOC_FLAGS = -align 0x1000 - CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096 - MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096 - ################################################################################ # # SKU Identification section - list of all SKU IDs supported by this Platform. @@ -371,7 +364,7 @@ !if $(MULTIPLE_DEBUG_PORT_SUPPORT) == TRUE SerialPortLib|UefiPayloadPkg/Library/BaseSerialPortLibHob/BaseSerialPortLibHob.inf !endif - MemoryAllocationLib|UefiPayloadPkg/Library/UefiPayloadEntryMemoryAllocationLib/UefiPayloadEntryMemoryAllocationLib.inf + MemoryAllocationLib|UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.inf [LibraryClasses.common.DXE_CORE] DxeHobListLib|UefiPayloadPkg/Library/DxeHobListLibNull/DxeHobListLibNull.inf diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index e788f27cc1..283df03ac4 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -13,8 +13,8 @@ DEFINE FD_BASE = 0x00800000 DEFINE FD_BLOCK_SIZE = 0x00001000 !if $(TARGET) == "NOOPT" -DEFINE FD_SIZE = 0x00850000 -DEFINE NUM_BLOCKS = 0x850 +DEFINE FD_SIZE = 0x00A00000 +DEFINE NUM_BLOCKS = 0xA00 !else DEFINE FD_SIZE = 0x00700000 From 84c6f4ae1ad2c9318090fdec01c2d44bd253992f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 27 Feb 2025 14:01:48 +0300 Subject: [PATCH 023/341] MdePkg: Added BaseOverflowLib library. --- MdePkg/Include/Library/BaseOverflowLib.h | 447 ++++++++++++++++++ .../Library/BaseOverflowLib/BaseAlignment.c | 36 ++ .../Library/BaseOverflowLib/BaseBitOverflow.c | 442 +++++++++++++++++ MdePkg/Library/BaseOverflowLib/BaseMath.c | 64 +++ .../BaseOverflowLib/BaseNativeOverflow.c | 156 ++++++ .../BaseOverflowLib/BaseOverflowInternals.h | 50 ++ .../BaseOverflowLib/BaseOverflowLib.inf | 48 ++ .../BaseOverflowLib/BaseTripleOverflow.c | 429 +++++++++++++++++ MdePkg/MdePkg.dec | 5 + MdePkg/MdePkg.dsc | 1 + 10 files changed, 1678 insertions(+) create mode 100644 MdePkg/Include/Library/BaseOverflowLib.h create mode 100644 MdePkg/Library/BaseOverflowLib/BaseAlignment.c create mode 100644 MdePkg/Library/BaseOverflowLib/BaseBitOverflow.c create mode 100644 MdePkg/Library/BaseOverflowLib/BaseMath.c create mode 100644 MdePkg/Library/BaseOverflowLib/BaseNativeOverflow.c create mode 100644 MdePkg/Library/BaseOverflowLib/BaseOverflowInternals.h create mode 100644 MdePkg/Library/BaseOverflowLib/BaseOverflowLib.inf create mode 100644 MdePkg/Library/BaseOverflowLib/BaseTripleOverflow.c diff --git a/MdePkg/Include/Library/BaseOverflowLib.h b/MdePkg/Include/Library/BaseOverflowLib.h new file mode 100644 index 0000000000..0714cdb917 --- /dev/null +++ b/MdePkg/Include/Library/BaseOverflowLib.h @@ -0,0 +1,447 @@ +/** @file + +BaseOverflowLib + +Copyright (c) 2018, vit9696 + +All rights reserved. + +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __BASE_OVERFLOW_LIB__ +#define __BASE_OVERFLOW_LIB__ + +// +// The macros below provide pointer alignment checking interfaces. +// TypedPtr - pointer of a dedicated type, which alignment is to be checked. +// Align - valid alignment for the target platform (power of two so far). +// Type - valid complete typename. +// Ptr - raw pointer value, must fit into UINTN, meant to be uintptr_t equivalent. +// + +#define BASE_ALIGNOF(Type) (_Alignof (Type)) +#define BASE_POT_ALIGNED(Align, Ptr) (0ULL == (((UINTN) (Ptr)) & (Align-1U))) +#define BASE_TYPE_ALIGNED(Type, Ptr) (BASE_POT_ALIGNED (BASE_ALIGNOF (Type), Ptr)) + +// +// Force alignment for structure member or variable definition. +// +#if defined (_MSC_VER) +#define BASE_ALIGNAS(Alignment) __declspec(align(Alignment)) +#elif (defined (__STDC__) && __STDC_VERSION__ >= 201112L) || defined (__GNUC__) || defined (__clang__) +#define BASE_ALIGNAS(Alignment) _Alignas(Alignment) +#else +#define BASE_ALIGNAS(Alignment) +#endif + +/** + Return the result of (Multiplicand * Multiplier / Divisor). + + @param Multiplicand A 64-bit unsigned value. + @param Multiplier A 64-bit unsigned value. + @param Divisor A 32-bit unsigned value. + @param Remainder A pointer to a 32-bit unsigned value. This parameter is + optional and may be NULL. + + @return Multiplicand * Multiplier / Divisor. + **/ +UINT64 +BaseMultThenDivU64x64x32 ( + IN UINT64 Multiplicand, + IN UINT64 Multiplier, + IN UINT32 Divisor, + OUT UINT32 *Remainder OPTIONAL + ); + +// +// The interfaces below provide base safe arithmetics, reporting +// signed integer overflow and unsigned integer wraparound similarly to +// os/overflow.h in macOS SDK. +// +// Each interface may be implemented not only as an actual function, but +// a macro as well. Macro implementations are allowed to evaluate the +// expressions no more than once, and are supposed to provide faster +// compiler builtins if available. +// +// Each interface returns FALSE when the the stored result is equal to +// the infinite precision result, otherwise TRUE. The operands should +// be read left to right with the last argument representing a non-NULL +// pointer to the resulting value of the same type. +// +// More information could be found in Clang Extensions documentation: +// http://releases.llvm.org/7.0.0/tools/clang/docs/LanguageExtensions.html#checked-arithmetic-builtins +// + +// +// 32-bit integer addition, subtraction, multiplication, triple addition (A+B+C), +// triple multiplication (A*B*C), addition with multiplication ((A+B)*C), +// and multiplication with addition (A*B+C) support. +// + +BOOLEAN +BaseOverflowAddU16 ( + UINT16 A, + UINT16 B, + UINT16 *Result + ); + +BOOLEAN +BaseOverflowSubU16 ( + UINT16 A, + UINT16 B, + UINT16 *Result + ); + +BOOLEAN +BaseOverflowMulU16 ( + UINT16 A, + UINT16 B, + UINT16 *Result + ); + +BOOLEAN +BaseOverflowAddU32 ( + UINT32 A, + UINT32 B, + UINT32 *Result + ); + +BOOLEAN +BaseOverflowSubU32 ( + UINT32 A, + UINT32 B, + UINT32 *Result + ); + +BOOLEAN +BaseOverflowMulU32 ( + UINT32 A, + UINT32 B, + UINT32 *Result + ); + +BOOLEAN +BaseOverflowTriAddU32 ( + UINT32 A, + UINT32 B, + UINT32 C, + UINT32 *Result + ); + +BOOLEAN +BaseOverflowTriMulU32 ( + UINT32 A, + UINT32 B, + UINT32 C, + UINT32 *Result + ); + +BOOLEAN +BaseOverflowAddMulU32 ( + UINT32 A, + UINT32 B, + UINT32 C, + UINT32 *Result + ); + +BOOLEAN +BaseOverflowMulAddU32 ( + UINT32 A, + UINT32 B, + UINT32 C, + UINT32 *Result + ); + +BOOLEAN +BaseOverflowAlignUpU32 ( + UINT32 Value, + UINT32 Alignment, + UINT32 *Result + ); + +BOOLEAN +BaseOverflowAddS32 ( + INT32 A, + INT32 B, + INT32 *Result + ); + +BOOLEAN +BaseOverflowSubS32 ( + INT32 A, + INT32 B, + INT32 *Result + ); + +BOOLEAN +BaseOverflowMulS32 ( + INT32 A, + INT32 B, + INT32 *Result + ); + +BOOLEAN +BaseOverflowTriAddS32 ( + INT32 A, + INT32 B, + INT32 C, + INT32 *Result + ); + +BOOLEAN +BaseOverflowTriMulS32 ( + INT32 A, + INT32 B, + INT32 C, + INT32 *Result + ); + +BOOLEAN +BaseOverflowAddMulS32 ( + INT32 A, + INT32 B, + INT32 C, + INT32 *Result + ); + +BOOLEAN +BaseOverflowMulAddS32 ( + INT32 A, + INT32 B, + INT32 C, + INT32 *Result + ); + +// +// 64-bit integer addition, subtraction, multiplication, triple addition (A+B+C), +// triple multiplication (A*B*C), addition with multiplication ((A+B)*C), +// and multiplication with addition (A*B+C) support. +// + +BOOLEAN +BaseOverflowAddU64 ( + UINT64 A, + UINT64 B, + UINT64 *Result + ); + +BOOLEAN +BaseOverflowSubU64 ( + UINT64 A, + UINT64 B, + UINT64 *Result + ); + +BOOLEAN +BaseOverflowMulU64 ( + UINT64 A, + UINT64 B, + UINT64 *Result + ); + +BOOLEAN +BaseOverflowTriAddU64 ( + UINT64 A, + UINT64 B, + UINT64 C, + UINT64 *Result + ); + +BOOLEAN +BaseOverflowTriMulU64 ( + UINT64 A, + UINT64 B, + UINT64 C, + UINT64 *Result + ); + +BOOLEAN +BaseOverflowAddMulU64 ( + UINT64 A, + UINT64 B, + UINT64 C, + UINT64 *Result + ); + +BOOLEAN +BaseOverflowMulAddU64 ( + UINT64 A, + UINT64 B, + UINT64 C, + UINT64 *Result + ); + +BOOLEAN +BaseOverflowAddS64 ( + INT64 A, + INT64 B, + INT64 *Result + ); + +BOOLEAN +BaseOverflowSubS64 ( + INT64 A, + INT64 B, + INT64 *Result + ); + +BOOLEAN +BaseOverflowMulS64 ( + INT64 A, + INT64 B, + INT64 *Result + ); + +BOOLEAN +BaseOverflowTriAddS64 ( + INT64 A, + INT64 B, + INT64 C, + INT64 *Result + ); + +BOOLEAN +BaseOverflowTriMulS64 ( + INT64 A, + INT64 B, + INT64 C, + INT64 *Result + ); + +BOOLEAN +BaseOverflowAddMulS64 ( + INT64 A, + INT64 B, + INT64 C, + INT64 *Result + ); + +BOOLEAN +BaseOverflowMulAddS64 ( + INT64 A, + INT64 B, + INT64 C, + INT64 *Result + ); + +// +// Native integer addition, subtraction, multiplication, triple addition (A+B+C), +// triple multiplication (A*B*C), addition with multiplication ((A+B)*C), +// and multiplication with addition (A*B+C) support. +// + +BOOLEAN +BaseOverflowAddUN ( + UINTN A, + UINTN B, + UINTN *Result + ); + +BOOLEAN +BaseOverflowSubUN ( + UINTN A, + UINTN B, + UINTN *Result + ); + +BOOLEAN +BaseOverflowMulUN ( + UINTN A, + UINTN B, + UINTN *Result + ); + +BOOLEAN +BaseOverflowTriAddUN ( + UINTN A, + UINTN B, + UINTN C, + UINTN *Result + ); + +BOOLEAN +BaseOverflowTriMulUN ( + UINTN A, + UINTN B, + UINTN C, + UINTN *Result + ); + +BOOLEAN +BaseOverflowAddMulUN ( + UINTN A, + UINTN B, + UINTN C, + UINTN *Result + ); + +BOOLEAN +BaseOverflowMulAddUN ( + UINTN A, + UINTN B, + UINTN C, + UINTN *Result + ); + +BOOLEAN +BaseOverflowAddSN ( + INTN A, + INTN B, + INTN *Result + ); + +BOOLEAN +BaseOverflowSubSN ( + INTN A, + INTN B, + INTN *Result + ); + +BOOLEAN +BaseOverflowMulSN ( + INTN A, + INTN B, + INTN *Result + ); + +BOOLEAN +BaseOverflowTriAddSN ( + INTN A, + INTN B, + INTN C, + INTN *Result + ); + +BOOLEAN +BaseOverflowTriMulSN ( + INTN A, + INTN B, + INTN C, + INTN *Result + ); + +BOOLEAN +BaseOverflowAddMulSN ( + INTN A, + INTN B, + INTN C, + INTN *Result + ); + +BOOLEAN +BaseOverflowMulAddSN ( + INTN A, + INTN B, + INTN C, + INTN *Result + ); + +#endif // __BASE_OVERFLOW_LIB__ diff --git a/MdePkg/Library/BaseOverflowLib/BaseAlignment.c b/MdePkg/Library/BaseOverflowLib/BaseAlignment.c new file mode 100644 index 0000000000..141f124f61 --- /dev/null +++ b/MdePkg/Library/BaseOverflowLib/BaseAlignment.c @@ -0,0 +1,36 @@ +/** @file + +BaseOverflowLib + +Copyright (c) 2020, Download-Fritz + +All rights reserved. + +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +#include + +#include +#include + +BOOLEAN +BaseOverflowAlignUpU32 ( + UINT32 Value, + UINT32 Alignment, + UINT32 *Result + ) +{ + BOOLEAN Status; + + Status = BaseOverflowAddU32 (Value, Alignment - 1U, Result); + *Result &= ~(Alignment - 1U); + + return Status; +} diff --git a/MdePkg/Library/BaseOverflowLib/BaseBitOverflow.c b/MdePkg/Library/BaseOverflowLib/BaseBitOverflow.c new file mode 100644 index 0000000000..1ea658cd93 --- /dev/null +++ b/MdePkg/Library/BaseOverflowLib/BaseBitOverflow.c @@ -0,0 +1,442 @@ +/** @file + +BaseOverflowLib + +Copyright (c) 2018, vit9696 + +All rights reserved. + +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include + +#include "BaseOverflowInternals.h" + +// +// Software implementations provided try not to be obviously slow, but primarily +// target C99 compliance rather than performance. +// + +BOOLEAN +BaseOverflowAddU16 ( + UINT16 A, + UINT16 B, + UINT16 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_add_overflow (A, B, Result); + #else + UINT32 Temp; + + // + // I believe casting will be faster on X86 at least. + // + Temp = A + B; + *Result = (UINT16)Temp; + if (Temp <= MAX_UINT16) { + return FALSE; + } + + return TRUE; + #endif +} + +BOOLEAN +BaseOverflowSubU16 ( + UINT16 A, + UINT16 B, + UINT16 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_sub_overflow (A, B, Result); + #else + *Result = (UINT16)(A - B); + + if (A >= B) { + return FALSE; + } + + return TRUE; + #endif +} + +BOOLEAN +BaseOverflowMulU16 ( + UINT16 A, + UINT16 B, + UINT16 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_mul_overflow (A, B, Result); + #else + UINT32 Temp; + + Temp = (UINT32)A * B; + *Result = (UINT16)Temp; + if (Temp <= MAX_UINT32) { + return FALSE; + } + + return TRUE; + #endif +} + +BOOLEAN +BaseOverflowAddU32 ( + UINT32 A, + UINT32 B, + UINT32 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_add_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64) + return __builtin_uadd_overflow (A, B, Result); + #else + UINT32 Temp; + + // + // I believe casting will be faster on X86 at least. + // + Temp = A + B; + *Result = Temp; + if (Temp >= A) { + return FALSE; + } + + return TRUE; + #endif +} + +BOOLEAN +BaseOverflowSubU32 ( + UINT32 A, + UINT32 B, + UINT32 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_sub_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS) + return __builtin_usub_overflow (A, B, Result); + #else + *Result = A - B; + if (B <= A) { + return FALSE; + } + + return TRUE; + #endif +} + +BOOLEAN +BaseOverflowMulU32 ( + UINT32 A, + UINT32 B, + UINT32 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_mul_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS) + return __builtin_umul_overflow (A, B, Result); + #else + UINT64 Temp; + + Temp = (UINT64)A * B; + *Result = (UINT32)Temp; + if (Temp <= MAX_UINT32) { + return FALSE; + } + + return TRUE; + #endif +} + +BOOLEAN +BaseOverflowAddS32 ( + INT32 A, + INT32 B, + INT32 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_add_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS) + return __builtin_sadd_overflow (A, B, Result); + #else + INT64 Temp; + + Temp = (INT64)A + B; + *Result = (INT32)Temp; + if ((Temp >= MIN_INT32) && (Temp <= MAX_INT32)) { + return FALSE; + } + + return TRUE; + #endif +} + +BOOLEAN +BaseOverflowSubS32 ( + INT32 A, + INT32 B, + INT32 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_sub_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS) + return __builtin_ssub_overflow (A, B, Result); + #else + INT64 Temp; + + Temp = (INT64)A - B; + *Result = (INT32)Temp; + if ((Temp >= MIN_INT32) && (Temp <= MAX_INT32)) { + return FALSE; + } + + return TRUE; + #endif +} + +BOOLEAN +BaseOverflowMulS32 ( + INT32 A, + INT32 B, + INT32 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_mul_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS) + return __builtin_smul_overflow (A, B, Result); + #else + INT64 Temp; + + Temp = MultS64x64 (A, B); + *Result = (INT32)Temp; + if ((Temp >= MIN_INT32) && (Temp <= MAX_INT32)) { + return FALSE; + } + + return TRUE; + #endif +} + +BOOLEAN +BaseOverflowAddU64 ( + UINT64 A, + UINT64 B, + UINT64 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_add_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS) + return __builtin_uaddll_overflow (A, B, Result); + #else + UINT64 Temp; + + Temp = A + B; + *Result = Temp; + if (Temp >= A) { + return FALSE; + } + + return TRUE; + #endif +} + +BOOLEAN +BaseOverflowSubU64 ( + UINT64 A, + UINT64 B, + UINT64 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_sub_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS) + return __builtin_usubll_overflow (A, B, Result); + #else + *Result = A - B; + if (B <= A) { + return FALSE; + } + + return TRUE; + #endif +} + +BOOLEAN +BaseOverflowMulU64 ( + UINT64 A, + UINT64 B, + UINT64 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_mul_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS) + return __builtin_umulll_overflow (A, B, Result); + #else + UINT64 AHi; + UINT64 ALo; + UINT64 BHi; + UINT64 BLo; + UINT64 LoBits; + UINT64 HiBits1; + UINT64 HiBits2; + BOOLEAN Overflow; + + // + // Based on the 2nd option written by Charphacy, believed to be the fastest portable on x86. + // See: https://stackoverflow.com/a/26320664 + // Implements overflow checking by a series of up to 3 multiplications. + // + + AHi = RShiftU64 (A, 32); + ALo = A & MAX_UINT32; + BHi = RShiftU64 (B, 32); + BLo = B & MAX_UINT32; + + LoBits = MultU64x64 (ALo, BLo); + if ((AHi == 0) && (BHi == 0)) { + *Result = LoBits; + return FALSE; + } + + Overflow = AHi > 0 && BHi > 0; + HiBits1 = MultU64x64 (ALo, BHi); + HiBits2 = MultU64x64 (AHi, BLo); + + *Result = LoBits + LShiftU64 (HiBits1 + HiBits2, 32); + return Overflow || *Result < LoBits || RShiftU64 (HiBits1, 32) != 0 || RShiftU64 (HiBits2, 32) != 0; + #endif +} + +BOOLEAN +BaseOverflowAddS64 ( + INT64 A, + INT64 B, + INT64 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_add_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS) + return __builtin_saddll_overflow (A, B, Result); + #else + if (((B <= 0) || (A <= MAX_INT64 - B)) && ((B >= 0) || (A >= MIN_INT64 - B))) { + *Result = A + B; + return FALSE; + } + + // + // Assign some defined value to *Result. + // + *Result = 0; + return TRUE; + #endif +} + +BOOLEAN +BaseOverflowSubS64 ( + INT64 A, + INT64 B, + INT64 *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_sub_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS) + return __builtin_ssubll_overflow (A, B, Result); + #else + if (((B >= 0) || (A <= MAX_INT64 + B)) && ((B <= 0) || (A >= MIN_INT64 + B))) { + *Result = A - B; + return FALSE; + } + + // + // Assign some defined value to *Result. + // + *Result = 0; + return TRUE; + #endif +} + +BOOLEAN +BaseOverflowMulS64 ( + INT64 A, + INT64 B, + INT64 *Result + ) +{ + // + // Intel 32-bit architectures do not have hardware signed 64-bit + // multiplication with overflow. + // + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) && !defined (MDE_CPU_IA32) + return __builtin_mul_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS) && !defined (MDE_CPU_IA32) + return __builtin_smulll_overflow (A, B, Result); + #else + UINT64 AU; + UINT64 BU; + UINT64 ResultU; + + // + // It hurts to implement it without unsigned multiplication, maybe rewrite it one day. + // The idea taken from BaseSafeIntLib. + // + + #define OC_ABS_64(X) (((X) < 0) ? (((UINT64) (-((X) + 1))) + 1) : (UINT64) (X)) + + AU = OC_ABS_64 (A); + BU = OC_ABS_64 (B); + + if (BaseOverflowMulU64 (AU, BU, &ResultU)) { + *Result = 0; + return TRUE; + } + + // + // Split into positive and negative results and check just one range. + // + if ((A < 0) == (B < 0)) { + if (ResultU <= MAX_INT64) { + *Result = (INT64)ResultU; + return FALSE; + } + } else { + if (ResultU < OC_ABS_64 (MIN_INT64)) { + *Result = -((INT64)ResultU); + return FALSE; + } else if (ResultU == OC_ABS_64 (MIN_INT64)) { + *Result = MIN_INT64; + return FALSE; + } + } + + #undef OC_ABS_64 + + *Result = 0; + return TRUE; + #endif +} diff --git a/MdePkg/Library/BaseOverflowLib/BaseMath.c b/MdePkg/Library/BaseOverflowLib/BaseMath.c new file mode 100644 index 0000000000..9547c08935 --- /dev/null +++ b/MdePkg/Library/BaseOverflowLib/BaseMath.c @@ -0,0 +1,64 @@ +/** @file + Copyright (C) 2019, vit9696. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + **/ + +#include + +#include + +/** + BaseMultThenDivU64x64x32 is from MdeModulePkg's PciRootBridgeIo.c + + Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + **/ +UINT64 +BaseMultThenDivU64x64x32 ( + IN UINT64 Multiplicand, + IN UINT64 Multiplier, + IN UINT32 Divisor, + OUT UINT32 *Remainder OPTIONAL + ) +{ + UINT64 Uint64; + UINT32 LocalRemainder; + UINT32 Uint32; + + if (Multiplicand > DivU64x64Remainder (MAX_UINT64, Multiplier, NULL)) { + // + // Make sure Multiplicand is the bigger one. + // + if (Multiplicand < Multiplier) { + Uint64 = Multiplicand; + Multiplicand = Multiplier; + Multiplier = Uint64; + } + + // + // Because Multiplicand * Multiplier overflows, + // Multiplicand * Multiplier / Divisor + // = (2 * Multiplicand' + 1) * Multiplier / Divisor + // = 2 * (Multiplicand' * Multiplier / Divisor) + Multiplier / Divisor + // + Uint64 = BaseMultThenDivU64x64x32 (RShiftU64 (Multiplicand, 1), Multiplier, Divisor, &LocalRemainder); + Uint64 = LShiftU64 (Uint64, 1); + Uint32 = 0; + if ((Multiplicand & 0x1) == 1) { + Uint64 += DivU64x32Remainder (Multiplier, Divisor, &Uint32); + } + + return Uint64 + DivU64x32Remainder (Uint32 + LShiftU64 (LocalRemainder, 1), Divisor, Remainder); + } else { + return DivU64x32Remainder (MultU64x64 (Multiplicand, Multiplier), Divisor, Remainder); + } +} diff --git a/MdePkg/Library/BaseOverflowLib/BaseNativeOverflow.c b/MdePkg/Library/BaseOverflowLib/BaseNativeOverflow.c new file mode 100644 index 0000000000..204b552beb --- /dev/null +++ b/MdePkg/Library/BaseOverflowLib/BaseNativeOverflow.c @@ -0,0 +1,156 @@ +/** @file + +BaseOverflowLib + +Copyright (c) 2018, vit9696 + +All rights reserved. + +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include +#include + +#include "BaseOverflowInternals.h" + +BOOLEAN +BaseOverflowAddUN ( + UINTN A, + UINTN B, + UINTN *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_add_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64) + return __builtin_uaddll_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_32) + return __builtin_uadd_overflow (A, B, Result); + #else + if (sizeof (UINTN) == sizeof (UINT64)) { + return BaseOverflowAddU64 (A, B, (UINT64 *)Result); + } + + return BaseOverflowAddU32 ((UINT32)A, (UINT32)B, (UINT32 *)Result); + #endif +} + +BOOLEAN +BaseOverflowSubUN ( + UINTN A, + UINTN B, + UINTN *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_sub_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64) + return __builtin_usubll_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_32) + return __builtin_usub_overflow (A, B, Result); + #else + if (sizeof (UINTN) == sizeof (UINT64)) { + return BaseOverflowSubU64 (A, B, (UINT64 *)Result); + } + + return BaseOverflowSubU32 ((UINT32)A, (UINT32)B, (UINT32 *)Result); + #endif +} + +BOOLEAN +BaseOverflowMulUN ( + UINTN A, + UINTN B, + UINTN *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_mul_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64) + return __builtin_umulll_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_32) + return __builtin_umul_overflow (A, B, Result); + #else + if (sizeof (UINTN) == sizeof (UINT64)) { + return BaseOverflowMulU64 (A, B, (UINT64 *)Result); + } + + return BaseOverflowMulU32 ((UINT32)A, (UINT32)B, (UINT32 *)Result); + #endif +} + +BOOLEAN +BaseOverflowAddSN ( + INTN A, + INTN B, + INTN *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_add_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64) + return __builtin_saddll_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_32) + return __builtin_sadd_overflow (A, B, Result); + #else + if (sizeof (INTN) == sizeof (INT64)) { + return BaseOverflowAddS64 (A, B, (INT64 *)Result); + } + + return BaseOverflowAddS32 ((INT32)A, (INT32)B, (INT32 *)Result); + #endif +} + +BOOLEAN +BaseOverflowSubSN ( + INTN A, + INTN B, + INTN *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_sub_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64) + return __builtin_ssubll_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_32) + return __builtin_ssub_overflow (A, B, Result); + #else + if (sizeof (INTN) == sizeof (INT64)) { + return BaseOverflowSubS64 (A, B, (INT64 *)Result); + } + + return BaseOverflowSubS32 ((INT32)A, (INT32)B, (INT32 *)Result); + #endif +} + +BOOLEAN +BaseOverflowMulSN ( + INTN A, + INTN B, + INTN *Result + ) +{ + #if defined (BASE_HAS_TYPE_GENERIC_BUILTINS) + return __builtin_mul_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_64) + return __builtin_smulll_overflow (A, B, Result); + #elif defined (BASE_HAS_TYPE_SPECIFIC_BUILTINS_32) + return __builtin_smul_overflow (A, B, Result); + #else + if (sizeof (INTN) == sizeof (INT64)) { + return BaseOverflowMulS64 (A, B, (INT64 *)Result); + } + + return BaseOverflowMulS32 ((INT32)A, (INT32)B, (INT32 *)Result); + #endif +} diff --git a/MdePkg/Library/BaseOverflowLib/BaseOverflowInternals.h b/MdePkg/Library/BaseOverflowLib/BaseOverflowInternals.h new file mode 100644 index 0000000000..e4377a6e59 --- /dev/null +++ b/MdePkg/Library/BaseOverflowLib/BaseOverflowInternals.h @@ -0,0 +1,50 @@ +/** @file + This header provides internal BaseOverflowLib definitions. + + Copyright (c) 2020, vit9696. All rights reserved.
+ SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef __OVERFLOW_INTERNALS__ +#define __OVERFLOW_INTERNALS__ + +#if defined (__has_builtin) + #if __has_builtin (__builtin_add_overflow) && __has_builtin (__builtin_sub_overflow) && __has_builtin (__builtin_mul_overflow) +#define BASE_HAS_TYPE_GENERIC_BUILTINS 1 + #endif +#endif + +#if defined (__GNUC__) || defined (__clang__) + #if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_X64) +STATIC_ASSERT (sizeof (INTN) == 8, "INTN is expected to be 8 bytes"); +STATIC_ASSERT (sizeof (UINTN) == 8, "UINTN is expected to be 8 bytes"); +#define BASE_HAS_TYPE_SPECIFIC_BUILTINS_64 1 + #elif defined (MDE_CPU_ARM) || defined (MDE_CPU_IA32) +STATIC_ASSERT (sizeof (INTN) == 4, "INTN is expected to be 4 bytes"); +STATIC_ASSERT (sizeof (UINTN) == 4, "UINTN is expected to be 4 bytes"); +#define BASE_HAS_TYPE_SPECIFIC_BUILTINS_32 1 + #endif + +STATIC_ASSERT (sizeof (int) == 4, "int is expected to be 4 bytes"); +STATIC_ASSERT (sizeof (unsigned) == 4, "unsigned is expected to be 4 bytes"); +STATIC_ASSERT (sizeof (long long) == 8, "long long is expected to be 8 bytes"); +STATIC_ASSERT (sizeof (unsigned long long) == 8, "unsigned long long is expected to be 8 bytes"); +#define BASE_HAS_TYPE_SPECIFIC_BUILTINS 1 +#endif + +// +// Currently no architectures provide UINTN and INTN different from 32-bit or 64-bit +// integers. For this reason they are the only variants supported and are enforced here. +// + +STATIC_ASSERT ( + sizeof (INTN) == sizeof (INT64) || sizeof (INTN) == sizeof (INT32), + "INTN must be 32 or 64 Bits wide." + ); + +STATIC_ASSERT ( + sizeof (UINTN) == sizeof (UINT64) || sizeof (UINTN) == sizeof (UINT32), + "UINTN must be 32 or 64 Bits wide." + ); + +#endif // __OVERFLOW_INTERNALS__ diff --git a/MdePkg/Library/BaseOverflowLib/BaseOverflowLib.inf b/MdePkg/Library/BaseOverflowLib/BaseOverflowLib.inf new file mode 100644 index 0000000000..a14bd80e56 --- /dev/null +++ b/MdePkg/Library/BaseOverflowLib/BaseOverflowLib.inf @@ -0,0 +1,48 @@ +## @file +# BaseOverflowLib +# +# Copyright (c) 2018, vit9696 +# +# All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseOverflowLib + FILE_GUID = 57D4B14C-CC2C-4779-8A80-0BA5AAC1B8F3 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = BaseOverflowLib + + +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + BaseAlignment.c + BaseBitOverflow.c + BaseOverflowInternals.h + BaseMath.c + BaseNativeOverflow.c + BaseTripleOverflow.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + +[BuildOptions] + XCODE:DEBUG_*_*_CC_FLAGS = -fno-stack-protector + XCODE:NOOPT_*_*_CC_FLAGS = -fno-stack-protector + XCODE:RELEASE_*_*_CC_FLAGS = -fno-stack-protector diff --git a/MdePkg/Library/BaseOverflowLib/BaseTripleOverflow.c b/MdePkg/Library/BaseOverflowLib/BaseTripleOverflow.c new file mode 100644 index 0000000000..ebcadc9ed4 --- /dev/null +++ b/MdePkg/Library/BaseOverflowLib/BaseTripleOverflow.c @@ -0,0 +1,429 @@ +/** @file + +BaseOverflowLib + +Copyright (c) 2018, vit9696 + +All rights reserved. + +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + +#include + +BOOLEAN +BaseOverflowTriAddU32 ( + UINT32 A, + UINT32 B, + UINT32 C, + UINT32 *Result + ) +{ + UINT32 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowAddU32 (A, B, &BaseTmp); + BaseSecond = BaseOverflowAddU32 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowTriMulU32 ( + UINT32 A, + UINT32 B, + UINT32 C, + UINT32 *Result + ) +{ + UINT32 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowMulU32 (A, B, &BaseTmp); + BaseSecond = BaseOverflowMulU32 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowAddMulU32 ( + UINT32 A, + UINT32 B, + UINT32 C, + UINT32 *Result + ) +{ + UINT32 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowAddU32 (A, B, &BaseTmp); + BaseSecond = BaseOverflowMulU32 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowMulAddU32 ( + UINT32 A, + UINT32 B, + UINT32 C, + UINT32 *Result + ) +{ + UINT32 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowMulU32 (A, B, &BaseTmp); + BaseSecond = BaseOverflowAddU32 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowTriAddS32 ( + INT32 A, + INT32 B, + INT32 C, + INT32 *Result + ) +{ + INT32 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowAddS32 (A, B, &BaseTmp); + BaseSecond = BaseOverflowAddS32 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowTriMulS32 ( + INT32 A, + INT32 B, + INT32 C, + INT32 *Result + ) +{ + INT32 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowMulS32 (A, B, &BaseTmp); + BaseSecond = BaseOverflowMulS32 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowAddMulS32 ( + INT32 A, + INT32 B, + INT32 C, + INT32 *Result + ) +{ + INT32 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowAddS32 (A, B, &BaseTmp); + BaseSecond = BaseOverflowMulS32 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowMulAddS32 ( + INT32 A, + INT32 B, + INT32 C, + INT32 *Result + ) +{ + INT32 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowMulS32 (A, B, &BaseTmp); + BaseSecond = BaseOverflowAddS32 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowTriAddU64 ( + UINT64 A, + UINT64 B, + UINT64 C, + UINT64 *Result + ) +{ + UINT64 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowAddU64 (A, B, &BaseTmp); + BaseSecond = BaseOverflowAddU64 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowTriMulU64 ( + UINT64 A, + UINT64 B, + UINT64 C, + UINT64 *Result + ) +{ + UINT64 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowMulU64 (A, B, &BaseTmp); + BaseSecond = BaseOverflowMulU64 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowAddMulU64 ( + UINT64 A, + UINT64 B, + UINT64 C, + UINT64 *Result + ) +{ + UINT64 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowAddU64 (A, B, &BaseTmp); + BaseSecond = BaseOverflowMulU64 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowMulAddU64 ( + UINT64 A, + UINT64 B, + UINT64 C, + UINT64 *Result + ) +{ + UINT64 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowMulU64 (A, B, &BaseTmp); + BaseSecond = BaseOverflowAddU64 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowTriAddS64 ( + INT64 A, + INT64 B, + INT64 C, + INT64 *Result + ) +{ + INT64 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowAddS64 (A, B, &BaseTmp); + BaseSecond = BaseOverflowAddS64 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowTriMulS64 ( + INT64 A, + INT64 B, + INT64 C, + INT64 *Result + ) +{ + INT64 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowMulS64 (A, B, &BaseTmp); + BaseSecond = BaseOverflowMulS64 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowAddMulS64 ( + INT64 A, + INT64 B, + INT64 C, + INT64 *Result + ) +{ + INT64 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowAddS64 (A, B, &BaseTmp); + BaseSecond = BaseOverflowMulS64 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowMulAddS64 ( + INT64 A, + INT64 B, + INT64 C, + INT64 *Result + ) +{ + INT64 BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowMulS64 (A, B, &BaseTmp); + BaseSecond = BaseOverflowAddS64 (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowTriAddUN ( + UINTN A, + UINTN B, + UINTN C, + UINTN *Result + ) +{ + UINTN BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowAddUN (A, B, &BaseTmp); + BaseSecond = BaseOverflowAddUN (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowTriMulUN ( + UINTN A, + UINTN B, + UINTN C, + UINTN *Result + ) +{ + UINTN BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowMulUN (A, B, &BaseTmp); + BaseSecond = BaseOverflowMulUN (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowAddMulUN ( + UINTN A, + UINTN B, + UINTN C, + UINTN *Result + ) +{ + UINTN BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowAddUN (A, B, &BaseTmp); + BaseSecond = BaseOverflowMulUN (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowMulAddUN ( + UINTN A, + UINTN B, + UINTN C, + UINTN *Result + ) +{ + UINTN BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowMulUN (A, B, &BaseTmp); + BaseSecond = BaseOverflowAddUN (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowTriAddSN ( + INTN A, + INTN B, + INTN C, + INTN *Result + ) +{ + INTN BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowAddSN (A, B, &BaseTmp); + BaseSecond = BaseOverflowAddSN (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowTriMulSN ( + INTN A, + INTN B, + INTN C, + INTN *Result + ) +{ + INTN BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowMulSN (A, B, &BaseTmp); + BaseSecond = BaseOverflowMulSN (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowAddMulSN ( + INTN A, + INTN B, + INTN C, + INTN *Result + ) +{ + INTN BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowAddSN (A, B, &BaseTmp); + BaseSecond = BaseOverflowMulSN (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} + +BOOLEAN +BaseOverflowMulAddSN ( + INTN A, + INTN B, + INTN C, + INTN *Result + ) +{ + INTN BaseTmp; + BOOLEAN BaseFirst; + BOOLEAN BaseSecond; + + BaseFirst = BaseOverflowMulSN (A, B, &BaseTmp); + BaseSecond = BaseOverflowAddSN (BaseTmp, C, Result); + return BaseFirst | BaseSecond; +} diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index f4df56d209..53c619c8f9 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -350,6 +350,11 @@ ## @libraryclass Provides function to support TDX processing. TdxLib|Include/Library/TdxLib.h + ## @libraryclass Provides base safe arithmetics, reporting signed integer overflow + # and unsigned integer wraparound similarly to os/overflow.h in macOS SDK. + ## + BaseOverflowLib|Include/Library/BaseOverflowLib.h + [LibraryClasses.X64] ## @libraryclass Defines a set of interfaces for the MM core entrypoint. The ARM/AARCH64 version lives in ArmPkg # diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index acf7be2aa7..cb549d6f42 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -195,6 +195,7 @@ MdePkg/Library/TdxLib/TdxLib.inf MdePkg/Library/MipiSysTLib/MipiSysTLib.inf MdePkg/Library/TraceHubDebugSysTLibNull/TraceHubDebugSysTLibNull.inf + MdePkg/Library/BaseOverflowLib/BaseOverflowLib.inf [Components.X64] MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf From d172035eded2beec78014f18a7d21e3ae94290c2 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 15 Dec 2023 17:09:27 +0300 Subject: [PATCH 024/341] MdePkg: Defined DEBUG_RAISE() to facilitate fuzzing. --- MdePkg/Include/Library/DebugLib.h | 18 ++++++++++++++++++ .../Library/BasePeCoffLib2/BasePeCoffLib2.inf | 1 + .../BaseUefiImageLibPeCoff.inf | 1 + MdePkg/MdePkg.dec | 7 +++++++ 4 files changed, 27 insertions(+) diff --git a/MdePkg/Include/Library/DebugLib.h b/MdePkg/Include/Library/DebugLib.h index b48e08a7e4..541dfeec31 100644 --- a/MdePkg/Include/Library/DebugLib.h +++ b/MdePkg/Include/Library/DebugLib.h @@ -23,6 +23,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #ifndef __DEBUG_LIB_H__ #define __DEBUG_LIB_H__ +#include +#include + // // Declare bits for PcdDebugPropertyMask // @@ -609,6 +612,21 @@ UnitTestDebugAssert ( } \ } while (FALSE) +#define DEBUG_RAISE() \ + do { \ + if ((PcdGet8 (PcdDebugRaisePropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0) { \ + DEBUG ((DEBUG_WARN, "DEBUG RAISE: Constraint violation in %a:%a:%u\n", __FILE__, __func__, __LINE__));\ + } \ + \ + if ((PcdGet8 (PcdDebugRaisePropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0) { \ + ASSERT (FALSE); \ + } \ + \ + if ((PcdGet8 (PcdDebugRaisePropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) { \ + CpuBreakpoint (); \ + } \ + } while (FALSE) + /** Macro that calls DebugAssert() if the containing record does not have a matching signature. If the signatures matches, then a pointer to the data diff --git a/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf index 4d375e2506..f3c3951ac5 100644 --- a/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf +++ b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf @@ -45,3 +45,4 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderDebugSupport gEfiMdePkgTokenSpaceGuid.PcdImageLoaderProhibitTe gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset + gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask diff --git a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf index bfe7296e0d..e3684fe922 100644 --- a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf +++ b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf @@ -38,3 +38,4 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAlignmentPolicy gEfiMdePkgTokenSpaceGuid.PcdImageLoaderLoadHeader gEfiMdePkgTokenSpaceGuid.PcdImageLoaderProhibitTe + gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 53c619c8f9..98391bfefe 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -2411,6 +2411,13 @@ # @Expression 0x80000002 | (gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask & 0xC0) == 0 gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0|UINT8|0x00000005 + ## The mask is used to control DEBUG_RAISE() behavior.

+ # BIT0 - Enable Debug Assert.
+ # BIT1 - Enable Debug Print.
+ # BIT4 - Enable BreakPoint as ASSERT.
+ # @Prompt DEBUG_RAISE() Property. + gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask|0|UINT8|0x0000001b + ## This flag is used to filter the output of the DEBUG_PRINT macro and DebugPrint functions.

# The default value is 0x80000000, meaning that DebugPrint returns immediately for anything # except errors. You might set this to a value like 0x80000002 to also enable warnings.

From 011411a38ebf7a333e60f540dd1855d87580bd9b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 4 May 2023 16:32:53 +0300 Subject: [PATCH 025/341] BaseTools, MdeModulePkg: Update brotli submodule Update the brotli submodule to the latest commit (ed1995b6bda1) so that the build isn't broken in GCC 12 compilers. Signed-off-by: Savva Mitrofanov --- BaseTools/Source/C/BrotliCompress/brotli | 2 +- MdeModulePkg/Library/BrotliCustomDecompressLib/brotli | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BaseTools/Source/C/BrotliCompress/brotli b/BaseTools/Source/C/BrotliCompress/brotli index f4153a09f8..ed1995b6bd 160000 --- a/BaseTools/Source/C/BrotliCompress/brotli +++ b/BaseTools/Source/C/BrotliCompress/brotli @@ -1 +1 @@ -Subproject commit f4153a09f87cbb9c826d8fc12c74642bb2d879ea +Subproject commit ed1995b6bda19244070ab5d331111f16f67c8054 diff --git a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli index 666c3280cc..ed1995b6bd 160000 --- a/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli +++ b/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli @@ -1 +1 @@ -Subproject commit 666c3280cc11dc433c303d79a83d4ffbdd12cc8d +Subproject commit ed1995b6bda19244070ab5d331111f16f67c8054 From 09b751e80afdb88b5a9ef394c7e40fc5c7185386 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Fri, 3 Feb 2023 17:44:30 +0600 Subject: [PATCH 026/341] MdeModulePkg/BrotliCustomDecompressLib: Disable C4559 MSVC warning Disables redefinition warning due to win 10 sdk to fix build using MSVC toolchain Signed-off-by: Savva Mitrofanov --- .../BrotliCustomDecompressLib.inf | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliCustomDecompressLib.inf b/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliCustomDecompressLib.inf index a96d553ccd..5ded352e2c 100644 --- a/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliCustomDecompressLib.inf +++ b/MdeModulePkg/Library/BrotliCustomDecompressLib/BrotliCustomDecompressLib.inf @@ -76,3 +76,12 @@ DebugLib BaseMemoryLib ExtractGuidedSectionLib + +[BuildOptions] + # + # Disables the following Visual Studio compiler warnings brought by brotli source, + # so we do not break the build with /WX option: + # C4559: 'function' : redefinition; the function gains __declspec(restrict) + # + MSFT:*_*_IA32_CC_FLAGS = /wd4559 + MSFT:*_*_X64_CC_FLAGS = /wd4559 From f8ef5b77e156cf8171922e86de790b95cc595f68 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Fri, 3 Feb 2023 14:25:18 +0600 Subject: [PATCH 027/341] IntelFsp2WrapperPkg/FspWrapperMultiPhaseProcessLib: Fix CLANGPDB build Silences "sometimes-uninitialized" warning by initializing the variable FspMultiPhaseApiOffset and corrects build using LLVM 15 toolchain Signed-off-by: Savva Mitrofanov --- .../PeiFspWrapperMultiPhaseProcessLib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c b/IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c index 68331c701d..63c9ad6ee3 100644 --- a/IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c +++ b/IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c @@ -82,7 +82,8 @@ CallFspMultiPhaseEntry ( BOOLEAN IsVariableServiceRequest; FSP_MULTI_PHASE_PARAMS *FspMultiPhaseParamsPtr; - FspMultiPhaseApiOffset = 0; + FspMultiPhaseApiOffset = 0; + FspMultiPhaseParamsPtr = (FSP_MULTI_PHASE_PARAMS *)FspMultiPhaseParams; IsVariableServiceRequest = FALSE; if ((FspMultiPhaseParamsPtr->MultiPhaseAction == EnumMultiPhaseGetVariableRequestInfo) || From 66470c302a84834d61c949709d971ffee7dcfec7 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Tue, 14 Feb 2023 15:28:58 +0600 Subject: [PATCH 028/341] MdePkg/UnitTest: Fixes CLANGPDB build Signed-off-by: Savva Mitrofanov --- MdePkg/Test/UnitTest/Library/BaseLib/BaseLibUnitTestsUefi.inf | 3 +++ .../UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibDxe.inf | 3 +++ .../UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibPei.inf | 3 +++ .../UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibSmm.inf | 3 +++ .../Library/BaseSafeIntLib/TestBaseSafeIntLibUefiShell.inf | 3 +++ 5 files changed, 15 insertions(+) diff --git a/MdePkg/Test/UnitTest/Library/BaseLib/BaseLibUnitTestsUefi.inf b/MdePkg/Test/UnitTest/Library/BaseLib/BaseLibUnitTestsUefi.inf index 907503898a..72f8b6292f 100644 --- a/MdePkg/Test/UnitTest/Library/BaseLib/BaseLibUnitTestsUefi.inf +++ b/MdePkg/Test/UnitTest/Library/BaseLib/BaseLibUnitTestsUefi.inf @@ -31,3 +31,6 @@ UefiApplicationEntryPoint DebugLib UnitTestLib + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibDxe.inf b/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibDxe.inf index de67b04bd5..8a106d6ce7 100644 --- a/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibDxe.inf +++ b/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibDxe.inf @@ -43,3 +43,6 @@ [Depex] TRUE + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibPei.inf b/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibPei.inf index c8ba4f44ef..9787c0ffbc 100644 --- a/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibPei.inf +++ b/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibPei.inf @@ -43,3 +43,6 @@ [Depex] TRUE + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibSmm.inf b/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibSmm.inf index df7288501d..753719de27 100644 --- a/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibSmm.inf +++ b/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibSmm.inf @@ -43,3 +43,6 @@ [Depex] TRUE + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibUefiShell.inf b/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibUefiShell.inf index 5a13c1c845..dccbc66855 100644 --- a/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibUefiShell.inf +++ b/MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibUefiShell.inf @@ -40,3 +40,6 @@ DebugLib SafeIntLib UnitTestLib + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved From 292e5ed7628985e46c261fb7a78ab4198457b696 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Tue, 14 Feb 2023 15:42:21 +0600 Subject: [PATCH 029/341] UefiCpuPkg/UnitTest: Fixes CLANGDWARF build Adds missing EFIAPI modifiers. Fixes calling conventions by defining as ms_abi Signed-off-by: Savva Mitrofanov --- .../EdkiiPeiMpServices2PpiUnitTest.c | 2 ++ .../EfiMpServicesUnitTestCommom.c | 10 ++++++++++ .../EfiMpServicesUnitTestCommom.h | 2 ++ 3 files changed, 14 insertions(+) diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiUnitTest.c b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiUnitTest.c index 5c42a81d29..328e99cbda 100644 --- a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiUnitTest.c +++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2PpiUnitTest.c @@ -215,6 +215,7 @@ MpServicesUnitTestStartupAllCPUs ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI ApInfiniteLoopProcedure ( IN OUT VOID *Buffer ) @@ -245,6 +246,7 @@ ApInfiniteLoopProcedure ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI RunMpServiceStartupAllCPUsOnAp ( IN OUT VOID *Buffer ) diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.c b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.c index 7cd3f48d76..d7fa06c992 100644 --- a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.c +++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.c @@ -231,6 +231,7 @@ FreeUTContext ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI StoreCpuNumbers ( IN OUT VOID *Buffer ) @@ -260,6 +261,7 @@ StoreCpuNumbers ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI StoreAPsExecutionOrder ( IN OUT VOID *Buffer ) @@ -290,6 +292,7 @@ StoreAPsExecutionOrder ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI InfiniteLoopProcedure ( IN OUT VOID *Buffer ) @@ -308,6 +311,7 @@ InfiniteLoopProcedure ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI EmptyProcedure ( IN OUT VOID *Buffer ) @@ -320,6 +324,7 @@ EmptyProcedure ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI RunMpServiceGetNumberOfProcessorsOnAp ( IN OUT VOID *Buffer ) @@ -343,6 +348,7 @@ RunMpServiceGetNumberOfProcessorsOnAp ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI RunMpServiceGetProcessorInfoOnAp ( IN OUT VOID *Buffer ) @@ -365,6 +371,7 @@ RunMpServiceGetProcessorInfoOnAp ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI RunMpServiceEnableDisableAPOnAp ( IN OUT VOID *Buffer ) @@ -387,6 +394,7 @@ RunMpServiceEnableDisableAPOnAp ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI RunMpServiceStartupThisAPOnAp ( IN OUT VOID *Buffer ) @@ -410,6 +418,7 @@ RunMpServiceStartupThisAPOnAp ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI RunMpServiceStartupAllAPsOnAp ( IN OUT VOID *Buffer ) @@ -433,6 +442,7 @@ RunMpServiceStartupAllAPsOnAp ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI RunMpServiceSwitchBSPOnAp ( IN OUT VOID *Buffer ) diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.h b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.h index d2b1633b4d..2df400009c 100644 --- a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.h +++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestCommom.h @@ -191,6 +191,7 @@ MpServicesUnitTestWhoAmI ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI EmptyProcedure ( IN OUT VOID *Buffer ); @@ -201,6 +202,7 @@ EmptyProcedure ( @param[in,out] Buffer The pointer to private data buffer. **/ VOID +EFIAPI StoreCpuNumbers ( IN OUT VOID *Buffer ); From 9429976185ceb5575396dc83d28e3cd445997ee4 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Tue, 14 Feb 2023 15:29:37 +0600 Subject: [PATCH 030/341] UnitTestFrameworkPkg/UnitTest: Fixes CLANGPDB build Signed-off-by: Savva Mitrofanov --- .../Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestDxe.inf | 3 +++ .../Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestPei.inf | 3 +++ .../Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestSmm.inf | 3 +++ .../UnitTest/Sample/SampleUnitTest/SampleUnitTestUefiShell.inf | 3 +++ 4 files changed, 12 insertions(+) diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestDxe.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestDxe.inf index a1b1e53789..5af0c07e24 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestDxe.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestDxe.inf @@ -37,3 +37,6 @@ [Depex] TRUE + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestPei.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestPei.inf index 2565f764a0..bcbbf4d82f 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestPei.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestPei.inf @@ -37,3 +37,6 @@ [Depex] gEfiPeiMemoryDiscoveredPpiGuid + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestSmm.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestSmm.inf index f47bc87df3..3a3749585c 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestSmm.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestSmm.inf @@ -38,3 +38,6 @@ [Depex] gEfiSmmCpuProtocolGuid + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestUefiShell.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestUefiShell.inf index 19534e7b1f..b93ad7c59e 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestUefiShell.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnitTestUefiShell.inf @@ -34,3 +34,6 @@ [Pcd] gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved From 4d4dcbe71f6536aca80b59cc287caef6fc3edd74 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 26 Jun 2023 13:24:46 +0300 Subject: [PATCH 031/341] BaseTools: Removed GCC48/49 toolchains, refactored tools_def.template. --- BaseTools/Conf/tools_def.template | 517 +++--------------- EmulatorPkg/Unix/Host/Host.inf | 2 - EmulatorPkg/build.sh | 13 +- IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc | 3 - .../X86QemuLoadImageLib/X86QemuLoadImageLib.c | 5 - OvmfPkg/README | 4 +- OvmfPkg/build.sh | 10 +- 7 files changed, 92 insertions(+), 462 deletions(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index 45f7a18e1b..a245a49645 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -17,9 +17,9 @@ # - Change RC path to use plugin # 3.00 - Update toolchains # - Add support for ARM and AARCH64 to CLANGDWARF -# - Remove VS2008, VS2010, VS2012, VS2013, CLANG35, CLANG38, EBC +# - Remove VS2008, VS2010, VS2012, VS2013, CLANG35, CLANG38, EBC, GCC48, GCC49 # - Add GCC and GCCNOLTO -# - Deprecate GCC48, GCC49 and GCC5. +# - Deprecate GCC5. # 3.01 - Add toolchain for VS2022 # 3.02 - Enable stack cookies for IA32, X64, ARM, and AARCH64 builds for GCC and MSVC # @@ -86,9 +86,6 @@ DEFINE VS2022_BIN_AARCH64 = DEF(VS2022_BIN)\HostDEF(VS_HOST)\arm64 # DEFINE RC_PATH = ENV(WINSDK_PATH_FOR_RC_EXE)\rc.exe -DEFINE WINSDK_BIN = ENV(WINSDK_PREFIX) -DEFINE WINSDKx86_BIN = ENV(WINSDKx86_PREFIX) - # Microsoft Visual Studio 2015 Professional Edition DEFINE WINSDK81_BIN = ENV(WINSDK81_PREFIX)x64 DEFINE WINSDK81x86_BIN = ENV(WINSDK81x86_PREFIX)x86 @@ -107,12 +104,6 @@ DEFINE CYGWIN_BIN = c:/cygwin/bin DEFINE CYGWIN_BINIA32 = c:/cygwin/opt/tiano/i386-tiano-pe/i386-tiano-pe/bin/ DEFINE CYGWIN_BINX64 = c:/cygwin/opt/tiano/x86_64-pc-mingw64/x86_64-pc-mingw64/bin/ -DEFINE GCC48_IA32_PREFIX = ENV(GCC48_BIN) -DEFINE GCC48_X64_PREFIX = ENV(GCC48_BIN) - -DEFINE GCC49_IA32_PREFIX = ENV(GCC49_BIN) -DEFINE GCC49_X64_PREFIX = ENV(GCC49_BIN) - DEFINE GCCNOLTO_IA32_PREFIX = ENV(GCCNOLTO_BIN) DEFINE GCCNOLTO_X64_PREFIX = ENV(GCCNOLTO_BIN) @@ -229,18 +220,6 @@ DEFINE DTC_BIN = ENV(DTC_PREFIX)dtc # # Deprecated Tool Chains # ====================== -# GCC48 -Linux,Windows- Requires: -# GCC 4.8 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi -# Optional: -# Required to build platforms or ACPI tables: -# Intel(r) ACPI Compiler from -# https://acpica.org/downloads -# GCC49 -Linux,Windows- Requires: -# GCC 4.9 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi -# Optional: -# Required to build platforms or ACPI tables: -# Intel(r) ACPI Compiler from -# https://acpica.org/downloads # GCC5 -Linux,Windows- Requires: # GCC 5 with LTO support, targeting x86_64-linux-gnu, aarch64-linux-gnu, arm-linux-gnueabi, riscv64-linux-gnu or loongarch64-linux-gnu # Optional: @@ -948,18 +927,15 @@ DEFINE GCC_AARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -fno- DEFINE GCC_AARCH64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only DEFINE GCC_RISCV64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only DEFINE GCC_DLINK2_FLAGS_COMMON = -Wl,--defsym=ALIGNED_PE_HEADER_SIZE=0x400 DEF(DLINK_SCRIPT) -DEFINE GCC_IA32_X64_DLINK_COMMON = -nostdlib --pie --fatal-warnings -z,noexecstack --gc-sections DEFINE GCC_ARM_AARCH64_DLINK_COMMON= -Wl,--emit-relocs -nostdlib -Wl,--gc-sections -u $(IMAGE_ENTRY_POINT) -Wl,-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map -Wl,--fatal-warnings -Wl,-z,noexecstack -no-pie DEFINE GCC_LOONGARCH64_DLINK_COMMON= -Wl,--emit-relocs -nostdlib -Wl,--gc-sections -u $(IMAGE_ENTRY_POINT) -Wl,-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map DEFINE GCC_ARM_DLINK_FLAGS = DEF(GCC_ARM_AARCH64_DLINK_COMMON) DEF(GCC_ALIGN) -Wl,--pic-veneer DEFINE GCC_AARCH64_DLINK_FLAGS = DEF(GCC_ARM_AARCH64_DLINK_COMMON) DEF(GCC_ALIGN) DEFINE GCC_LOONGARCH64_DLINK_FLAGS = DEF(GCC_LOONGARCH64_DLINK_COMMON) DEF(GCC_ALIGN) DEFINE GCC_ARM_AARCH64_ASLDLINK_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) DEF(GCC_ALIGN) -DEFINE GCC_IA32_X64_ASLDLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_COMMON) --entry _ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT) DEFINE GCC_ARM_ASLDLINK_FLAGS = DEF(GCC_ARM_DLINK_FLAGS) -Wl,--entry,ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT) DEF(GCC_ARM_AARCH64_ASLDLINK_FLAGS) DEFINE GCC_AARCH64_ASLDLINK_FLAGS = DEF(GCC_AARCH64_DLINK_FLAGS) -Wl,--entry,ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT) DEF(GCC_ARM_AARCH64_ASLDLINK_FLAGS) DEFINE GCC_LOONGARCH64_ASLDLINK_FLAGS = DEF(GCC_LOONGARCH64_DLINK_FLAGS) -Wl,--entry,ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT) -DEFINE GCC_IA32_X64_DLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_COMMON) --entry _$(IMAGE_ENTRY_POINT) --file-alignment 0x20 --section-alignment 0x20 -Map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEFINE GCC_ASM_FLAGS = -c -x assembler -imacros AutoGen.h DEFINE GCC_PP_FLAGS = -E -x assembler-with-cpp -include AutoGen.h DEFINE GCC_VFRPP_FLAGS = -x c -E -P -DVFRCOMPILE --include $(MODULE_NAME)StrDefs.h @@ -971,75 +947,27 @@ DEFINE GCC_DTCPP_FLAGS = -E -x assembler-with-cpp -imacros AutoGen.h # GCC Build Flag for included header file list generation DEFINE GCC_DEPS_FLAGS = -MMD -MF $@.deps -DEFINE GCC48_ALL_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -DEFINE GCC48_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections DEF(GCC_ALIGN) -DEFINE GCC48_IA32_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m32 -march=i586 -malign-double -D EFI32 -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer -DEFINE GCC48_X64_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer -DEFINE GCC48_IA32_X64_ASLDLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable -DEFINE GCC48_IA32_X64_DLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive -DEFINE GCC48_IA32_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -DEFINE GCC48_X64_DLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_FLAGS) -Wl,-melf_x86_64,--oformat=elf64-x86-64,-pie -DEFINE GCC48_X64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -DEFINE GCC48_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -DEFINE GCC48_ARM_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian -march=armv7-a -DEFINE GCC48_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian -DEFINE GCC48_ARM_CC_FLAGS = DEF(GCC_ARM_CC_FLAGS) -mword-relocations -DEFINE GCC48_ARM_CC_XIPFLAGS = DEF(GCC_ARM_CC_XIPFLAGS) -DEFINE GCC48_AARCH64_CC_FLAGS = -mcmodel=large DEF(GCC_AARCH64_CC_FLAGS) -DEFINE GCC48_AARCH64_CC_XIPFLAGS = DEF(GCC_AARCH64_CC_XIPFLAGS) -DEFINE GCC48_ARM_DLINK_FLAGS = DEF(GCC_ARM_DLINK_FLAGS) -Wl,--oformat=elf32-littlearm -DEFINE GCC48_ARM_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -DEFINE GCC48_AARCH64_DLINK_FLAGS = DEF(GCC_AARCH64_DLINK_FLAGS) -DEFINE GCC48_AARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -DEFINE GCC48_ARM_ASLDLINK_FLAGS = DEF(GCC_ARM_ASLDLINK_FLAGS) -Wl,--oformat=elf32-littlearm -DEFINE GCC48_AARCH64_ASLDLINK_FLAGS = DEF(GCC_AARCH64_ASLDLINK_FLAGS) -DEFINE GCC48_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) - -DEFINE GCC49_IA32_CC_FLAGS = DEF(GCC48_IA32_CC_FLAGS) -fno-pic -fno-pie -DEFINE GCC49_X64_CC_FLAGS = DEF(GCC48_X64_CC_FLAGS) -DEFINE GCC49_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections DEF(GCC_ALIGN) -DEFINE GCC49_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_DLINK_COMMON) DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable -DEFINE GCC49_IA32_X64_DLINK_FLAGS = DEF(GCC49_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive -DEFINE GCC49_IA32_DLINK2_FLAGS = DEF(GCC48_IA32_DLINK2_FLAGS) -DEFINE GCC49_X64_DLINK_FLAGS = DEF(GCC49_IA32_X64_DLINK_FLAGS) -Wl,-melf_x86_64,--oformat=elf64-x86-64,-pie -DEFINE GCC49_X64_DLINK2_FLAGS = DEF(GCC48_X64_DLINK2_FLAGS) -DEFINE GCC49_ASM_FLAGS = DEF(GCC48_ASM_FLAGS) -DEFINE GCC49_ARM_ASM_FLAGS = DEF(GCC48_ARM_ASM_FLAGS) -DEFINE GCC49_AARCH64_ASM_FLAGS = DEF(GCC48_AARCH64_ASM_FLAGS) -DEFINE GCC49_ARM_CC_FLAGS = DEF(GCC48_ARM_CC_FLAGS) -DEFINE GCC49_ARM_CC_XIPFLAGS = DEF(GCC48_ARM_CC_XIPFLAGS) -DEFINE GCC49_AARCH64_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(GCC_AARCH64_CC_FLAGS) -mcmodel=small -DEFINE GCC49_AARCH64_CC_XIPFLAGS = DEF(GCC48_AARCH64_CC_XIPFLAGS) -DEFINE GCC49_ARM_DLINK_FLAGS = DEF(GCC48_ARM_DLINK_FLAGS) -DEFINE GCC49_ARM_DLINK2_FLAGS = DEF(GCC48_ARM_DLINK2_FLAGS) -DEFINE GCC49_AARCH64_DLINK_FLAGS = DEF(GCC48_AARCH64_DLINK_FLAGS) DEF(GCC_ALIGN) -DEFINE GCC49_AARCH64_DLINK2_FLAGS = DEF(GCC48_AARCH64_DLINK2_FLAGS) -DEFINE GCC49_ARM_ASLDLINK_FLAGS = DEF(GCC48_ARM_ASLDLINK_FLAGS) -DEFINE GCC49_AARCH64_ASLDLINK_FLAGS = DEF(GCC48_AARCH64_ASLDLINK_FLAGS) -DEFINE GCC49_ASLCC_FLAGS = DEF(GCC48_ASLCC_FLAGS) - -DEFINE GCC5_IA32_CC_FLAGS = DEF(GCC49_IA32_CC_FLAGS) -DEFINE GCC5_X64_CC_FLAGS = DEF(GCC49_X64_CC_FLAGS) -DEFINE GCC5_IA32_X64_DLINK_COMMON = DEF(GCC49_IA32_X64_DLINK_COMMON) -DEFINE GCC5_IA32_X64_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_ASLDLINK_FLAGS) -DEFINE GCC5_IA32_X64_DLINK_FLAGS = DEF(GCC49_IA32_X64_DLINK_FLAGS) -DEFINE GCC5_IA32_DLINK2_FLAGS = DEF(GCC49_IA32_DLINK2_FLAGS) -Wno-error -DEFINE GCC5_X64_DLINK_FLAGS = DEF(GCC49_X64_DLINK_FLAGS) -DEFINE GCC5_X64_DLINK2_FLAGS = DEF(GCC49_X64_DLINK2_FLAGS) -Wno-error -DEFINE GCC5_ASM_FLAGS = DEF(GCC49_ASM_FLAGS) -DEFINE GCC5_ARM_ASM_FLAGS = DEF(GCC49_ARM_ASM_FLAGS) -DEFINE GCC5_AARCH64_ASM_FLAGS = DEF(GCC49_AARCH64_ASM_FLAGS) -DEFINE GCC5_ARM_CC_FLAGS = DEF(GCC49_ARM_CC_FLAGS) -DEFINE GCC5_ARM_CC_XIPFLAGS = DEF(GCC49_ARM_CC_XIPFLAGS) -DEFINE GCC5_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -DEFINE GCC5_AARCH64_CC_XIPFLAGS = DEF(GCC49_AARCH64_CC_XIPFLAGS) -DEFINE GCC5_ARM_DLINK_FLAGS = DEF(GCC49_ARM_DLINK_FLAGS) -DEFINE GCC5_ARM_DLINK2_FLAGS = DEF(GCC49_ARM_DLINK2_FLAGS) -Wno-error -DEFINE GCC5_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) -DEFINE GCC5_AARCH64_DLINK2_FLAGS = DEF(GCC49_AARCH64_DLINK2_FLAGS) -Wno-error -DEFINE GCC5_ARM_ASLDLINK_FLAGS = DEF(GCC49_ARM_ASLDLINK_FLAGS) -DEFINE GCC5_AARCH64_ASLDLINK_FLAGS = DEF(GCC49_AARCH64_ASLDLINK_FLAGS) -DEFINE GCC5_ASLCC_FLAGS = DEF(GCC49_ASLCC_FLAGS) -fno-lto +DEFINE GCC5_ALL_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings +DEFINE GCC5_IA32_CC_FLAGS = DEF(GCC5_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m32 -march=i586 -malign-double -D EFI32 -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer -fno-pic -fno-pie +DEFINE GCC5_X64_CC_FLAGS = DEF(GCC5_ALL_CC_FLAGS) DEF(GCC_IA32_X64_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer +DEFINE GCC5_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,--gc-sections DEF(GCC_ALIGN) +DEFINE GCC5_IA32_X64_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_COMMON) DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable +DEFINE GCC5_IA32_X64_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive +DEFINE GCC5_IA32_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wno-error +DEFINE GCC5_X64_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-melf_x86_64,--oformat=elf64-x86-64,-pie +DEFINE GCC5_X64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wno-error +DEFINE GCC5_ASM_FLAGS = DEF(GCC_ASM_FLAGS) +DEFINE GCC5_ARM_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian -march=armv7-a +DEFINE GCC5_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian +DEFINE GCC5_ARM_CC_FLAGS = DEF(GCC_ARM_CC_FLAGS) -mword-relocations +DEFINE GCC5_AARCH64_CC_FLAGS = DEF(GCC5_ALL_CC_FLAGS) DEF(GCC_AARCH64_CC_FLAGS) -mcmodel=small +DEFINE GCC5_ARM_DLINK_FLAGS = DEF(GCC_ARM_DLINK_FLAGS) -Wl,--oformat=elf32-littlearm +DEFINE GCC5_ARM_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wno-error +DEFINE GCC5_AARCH64_DLINK_FLAGS = DEF(GCC_AARCH64_DLINK_FLAGS) DEF(GCC_ALIGN) +DEFINE GCC5_AARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wno-error +DEFINE GCC5_ARM_ASLDLINK_FLAGS = DEF(GCC_ARM_ASLDLINK_FLAGS) -Wl,--oformat=elf32-littlearm +DEFINE GCC5_AARCH64_ASLDLINK_FLAGS = DEF(GCC_AARCH64_ASLDLINK_FLAGS) +DEFINE GCC5_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -fno-lto DEFINE GCC5_RISCV_ALL_CC_FLAGS = -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -fno-common -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings -msmall-data-limit=0 DEFINE GCC5_RISCV_ALL_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections DEF(GCC_ALIGN) @@ -1064,279 +992,6 @@ DEFINE GCC5_LOONGARCH64_ASLDLINK_FLAGS = DEF(GCC_LOONGARCH64_ASLDLINK_FLAGS) DEFINE GCC5_LOONGARCH64_ASM_FLAGS = -x assembler-with-cpp -mabi=lp64d -march=loongarch64 -fno-builtin -c -Wall -mno-explicit-relocs DEFINE GCC5_LOONGARCH64_PP_FLAGS = -mabi=lp64d -march=loongarch64 DEF(GCC_PP_FLAGS) -#################################################################################### -# -# GCC 4.8 - This configuration is used to compile under Linux to produce -# PE/COFF binaries using GCC 4.8. -# -#################################################################################### -*_GCC48_*_*_FAMILY = GCC - -*_GCC48_*_MAKE_PATH = DEF(GCC_HOST_PREFIX)make -*_GCC48_*_*_DLL = ENV(GCC48_DLL) -*_GCC48_*_ASL_PATH = DEF(UNIX_IASL_BIN) - -*_GCC48_*_PP_FLAGS = DEF(GCC_PP_FLAGS) -*_GCC48_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) -*_GCC48_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -*_GCC48_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -*_GCC48_*_APP_FLAGS = -*_GCC48_*_ASL_FLAGS = DEF(IASL_FLAGS) -*_GCC48_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS) -*_GCC48_*_DEPS_FLAGS = DEF(GCC_DEPS_FLAGS) - -################## -# GCC48 IA32 definitions -################## -*_GCC48_IA32_OBJCOPY_PATH = DEF(GCC48_IA32_PREFIX)objcopy -*_GCC48_IA32_CC_PATH = DEF(GCC48_IA32_PREFIX)gcc -*_GCC48_IA32_SLINK_PATH = DEF(GCC48_IA32_PREFIX)ar -*_GCC48_IA32_DLINK_PATH = DEF(GCC48_IA32_PREFIX)gcc -*_GCC48_IA32_ASLDLINK_PATH = DEF(GCC48_IA32_PREFIX)gcc -*_GCC48_IA32_ASM_PATH = DEF(GCC48_IA32_PREFIX)gcc -*_GCC48_IA32_PP_PATH = DEF(GCC48_IA32_PREFIX)gcc -*_GCC48_IA32_VFRPP_PATH = DEF(GCC48_IA32_PREFIX)gcc -*_GCC48_IA32_ASLCC_PATH = DEF(GCC48_IA32_PREFIX)gcc -*_GCC48_IA32_ASLPP_PATH = DEF(GCC48_IA32_PREFIX)gcc -*_GCC48_IA32_RC_PATH = DEF(GCC48_IA32_PREFIX)objcopy - -*_GCC48_IA32_ASLCC_FLAGS = DEF(GCC48_ASLCC_FLAGS) -m32 -*_GCC48_IA32_ASLDLINK_FLAGS = DEF(GCC48_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -*_GCC48_IA32_ASM_FLAGS = DEF(GCC48_ASM_FLAGS) -m32 -march=i386 -*_GCC48_IA32_DLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_FLAGS) -Wl,-m,elf_i386,--oformat=elf32-i386 -*_GCC48_IA32_DLINK2_FLAGS = DEF(GCC48_IA32_DLINK2_FLAGS) -*_GCC48_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS) -*_GCC48_IA32_NASM_FLAGS = -f elf32 -DRODATA_SECTION_NAME=.rodata - - DEBUG_GCC48_IA32_CC_FLAGS = DEF(GCC48_IA32_CC_FLAGS) -RELEASE_GCC48_IA32_CC_FLAGS = DEF(GCC48_IA32_CC_FLAGS) -Wno-unused-but-set-variable - NOOPT_GCC48_IA32_CC_FLAGS = DEF(GCC48_IA32_CC_FLAGS) -O0 - -################## -# GCC48 X64 definitions -################## -*_GCC48_X64_OBJCOPY_PATH = DEF(GCC48_X64_PREFIX)objcopy -*_GCC48_X64_CC_PATH = DEF(GCC48_X64_PREFIX)gcc -*_GCC48_X64_SLINK_PATH = DEF(GCC48_X64_PREFIX)ar -*_GCC48_X64_DLINK_PATH = DEF(GCC48_X64_PREFIX)gcc -*_GCC48_X64_ASLDLINK_PATH = DEF(GCC48_X64_PREFIX)gcc -*_GCC48_X64_ASM_PATH = DEF(GCC48_X64_PREFIX)gcc -*_GCC48_X64_PP_PATH = DEF(GCC48_X64_PREFIX)gcc -*_GCC48_X64_VFRPP_PATH = DEF(GCC48_X64_PREFIX)gcc -*_GCC48_X64_ASLCC_PATH = DEF(GCC48_X64_PREFIX)gcc -*_GCC48_X64_ASLPP_PATH = DEF(GCC48_X64_PREFIX)gcc -*_GCC48_X64_RC_PATH = DEF(GCC48_X64_PREFIX)objcopy - -*_GCC48_X64_ASLCC_FLAGS = DEF(GCC48_ASLCC_FLAGS) -m64 -*_GCC48_X64_ASLDLINK_FLAGS = DEF(GCC48_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 -*_GCC48_X64_ASM_FLAGS = DEF(GCC48_ASM_FLAGS) -m64 -*_GCC48_X64_DLINK_FLAGS = DEF(GCC48_X64_DLINK_FLAGS) -*_GCC48_X64_DLINK2_FLAGS = DEF(GCC48_X64_DLINK2_FLAGS) -*_GCC48_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) -*_GCC48_X64_NASM_FLAGS = -f elf64 -DRODATA_SECTION_NAME=.rodata - - DEBUG_GCC48_X64_CC_FLAGS = DEF(GCC48_X64_CC_FLAGS) -RELEASE_GCC48_X64_CC_FLAGS = DEF(GCC48_X64_CC_FLAGS) -Wno-unused-but-set-variable - NOOPT_GCC48_X64_CC_FLAGS = DEF(GCC48_X64_CC_FLAGS) -O0 - -################## -# GCC48 ARM definitions -################## -*_GCC48_ARM_CC_PATH = ENV(GCC48_ARM_PREFIX)gcc -*_GCC48_ARM_SLINK_PATH = ENV(GCC48_ARM_PREFIX)ar -*_GCC48_ARM_DLINK_PATH = ENV(GCC48_ARM_PREFIX)gcc -*_GCC48_ARM_ASLDLINK_PATH = ENV(GCC48_ARM_PREFIX)gcc -*_GCC48_ARM_ASM_PATH = ENV(GCC48_ARM_PREFIX)gcc -*_GCC48_ARM_PP_PATH = ENV(GCC48_ARM_PREFIX)gcc -*_GCC48_ARM_VFRPP_PATH = ENV(GCC48_ARM_PREFIX)gcc -*_GCC48_ARM_ASLCC_PATH = ENV(GCC48_ARM_PREFIX)gcc -*_GCC48_ARM_ASLPP_PATH = ENV(GCC48_ARM_PREFIX)gcc -*_GCC48_ARM_RC_PATH = ENV(GCC48_ARM_PREFIX)objcopy - -*_GCC48_ARM_ASLCC_FLAGS = DEF(GCC48_ASLCC_FLAGS) -*_GCC48_ARM_ASLDLINK_FLAGS = DEF(GCC48_ARM_ASLDLINK_FLAGS) -*_GCC48_ARM_ASM_FLAGS = DEF(GCC48_ARM_ASM_FLAGS) -*_GCC48_ARM_DLINK_FLAGS = DEF(GCC48_ARM_DLINK_FLAGS) -*_GCC48_ARM_DLINK2_FLAGS = DEF(GCC48_ARM_DLINK2_FLAGS) -*_GCC48_ARM_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC48_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS) -mthumb -march=armv7-a -*_GCC48_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS) -*_GCC48_ARM_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -mthumb -march=armv7-a -*_GCC48_ARM_CC_XIPFLAGS = DEF(GCC48_ARM_CC_XIPFLAGS) - - DEBUG_GCC48_ARM_CC_FLAGS = DEF(GCC48_ARM_CC_FLAGS) -O0 -RELEASE_GCC48_ARM_CC_FLAGS = DEF(GCC48_ARM_CC_FLAGS) -Wno-unused-but-set-variable - NOOPT_GCC48_ARM_CC_FLAGS = DEF(GCC48_ARM_CC_FLAGS) -O0 - -################## -# GCC48 AARCH64 definitions -################## -*_GCC48_AARCH64_CC_PATH = ENV(GCC48_AARCH64_PREFIX)gcc -*_GCC48_AARCH64_SLINK_PATH = ENV(GCC48_AARCH64_PREFIX)ar -*_GCC48_AARCH64_DLINK_PATH = ENV(GCC48_AARCH64_PREFIX)gcc -*_GCC48_AARCH64_ASLDLINK_PATH = ENV(GCC48_AARCH64_PREFIX)gcc -*_GCC48_AARCH64_ASM_PATH = ENV(GCC48_AARCH64_PREFIX)gcc -*_GCC48_AARCH64_PP_PATH = ENV(GCC48_AARCH64_PREFIX)gcc -*_GCC48_AARCH64_VFRPP_PATH = ENV(GCC48_AARCH64_PREFIX)gcc -*_GCC48_AARCH64_ASLCC_PATH = ENV(GCC48_AARCH64_PREFIX)gcc -*_GCC48_AARCH64_ASLPP_PATH = ENV(GCC48_AARCH64_PREFIX)gcc -*_GCC48_AARCH64_RC_PATH = ENV(GCC48_AARCH64_PREFIX)objcopy - -*_GCC48_AARCH64_ASLCC_FLAGS = DEF(GCC48_ASLCC_FLAGS) -*_GCC48_AARCH64_ASLDLINK_FLAGS = DEF(GCC48_AARCH64_ASLDLINK_FLAGS) -*_GCC48_AARCH64_ASM_FLAGS = DEF(GCC48_AARCH64_ASM_FLAGS) -*_GCC48_AARCH64_DLINK_FLAGS = DEF(GCC48_AARCH64_DLINK_FLAGS) -*_GCC48_AARCH64_DLINK2_FLAGS = DEF(GCC48_AARCH64_DLINK2_FLAGS) -*_GCC48_AARCH64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC48_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) -*_GCC48_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS) -*_GCC48_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -*_GCC48_AARCH64_CC_XIPFLAGS = DEF(GCC48_AARCH64_CC_XIPFLAGS) - - DEBUG_GCC48_AARCH64_CC_FLAGS = DEF(GCC48_AARCH64_CC_FLAGS) -O0 -RELEASE_GCC48_AARCH64_CC_FLAGS = DEF(GCC48_AARCH64_CC_FLAGS) -Wno-unused-but-set-variable - NOOPT_GCC48_AARCH64_CC_FLAGS = DEF(GCC48_AARCH64_CC_FLAGS) -O0 - -#################################################################################### -# -# GCC 4.9 - This configuration is used to compile under Linux to produce -# PE/COFF binaries using GCC 4.9. -# -#################################################################################### -*_GCC49_*_*_FAMILY = GCC - -*_GCC49_*_MAKE_PATH = DEF(GCC_HOST_PREFIX)make -*_GCC49_*_*_DLL = ENV(GCC49_DLL) -*_GCC49_*_ASL_PATH = DEF(UNIX_IASL_BIN) - -*_GCC49_*_PP_FLAGS = DEF(GCC_PP_FLAGS) -*_GCC49_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) -*_GCC49_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -*_GCC49_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -*_GCC49_*_APP_FLAGS = -*_GCC49_*_ASL_FLAGS = DEF(IASL_FLAGS) -*_GCC49_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS) -*_GCC49_*_DEPS_FLAGS = DEF(GCC_DEPS_FLAGS) - -################## -# GCC49 IA32 definitions -################## -*_GCC49_IA32_OBJCOPY_PATH = DEF(GCC49_IA32_PREFIX)objcopy -*_GCC49_IA32_CC_PATH = DEF(GCC49_IA32_PREFIX)gcc -*_GCC49_IA32_SLINK_PATH = DEF(GCC49_IA32_PREFIX)ar -*_GCC49_IA32_DLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc -*_GCC49_IA32_ASLDLINK_PATH = DEF(GCC49_IA32_PREFIX)gcc -*_GCC49_IA32_ASM_PATH = DEF(GCC49_IA32_PREFIX)gcc -*_GCC49_IA32_PP_PATH = DEF(GCC49_IA32_PREFIX)gcc -*_GCC49_IA32_VFRPP_PATH = DEF(GCC49_IA32_PREFIX)gcc -*_GCC49_IA32_ASLCC_PATH = DEF(GCC49_IA32_PREFIX)gcc -*_GCC49_IA32_ASLPP_PATH = DEF(GCC49_IA32_PREFIX)gcc -*_GCC49_IA32_RC_PATH = DEF(GCC49_IA32_PREFIX)objcopy - -*_GCC49_IA32_ASLCC_FLAGS = DEF(GCC49_ASLCC_FLAGS) -m32 -*_GCC49_IA32_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -*_GCC49_IA32_ASM_FLAGS = DEF(GCC49_ASM_FLAGS) -m32 -march=i386 -*_GCC49_IA32_DLINK_FLAGS = DEF(GCC49_IA32_X64_DLINK_FLAGS) -Wl,-m,elf_i386,--oformat=elf32-i386 -*_GCC49_IA32_DLINK2_FLAGS = DEF(GCC49_IA32_DLINK2_FLAGS) -*_GCC49_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS) -*_GCC49_IA32_NASM_FLAGS = -f elf32 -DRODATA_SECTION_NAME=.rodata - - DEBUG_GCC49_IA32_CC_FLAGS = DEF(GCC49_IA32_CC_FLAGS) -RELEASE_GCC49_IA32_CC_FLAGS = DEF(GCC49_IA32_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable - NOOPT_GCC49_IA32_CC_FLAGS = DEF(GCC49_IA32_CC_FLAGS) -O0 - -################## -# GCC49 X64 definitions -################## -*_GCC49_X64_OBJCOPY_PATH = DEF(GCC49_X64_PREFIX)objcopy -*_GCC49_X64_CC_PATH = DEF(GCC49_X64_PREFIX)gcc -*_GCC49_X64_SLINK_PATH = DEF(GCC49_X64_PREFIX)ar -*_GCC49_X64_DLINK_PATH = DEF(GCC49_X64_PREFIX)gcc -*_GCC49_X64_ASLDLINK_PATH = DEF(GCC49_X64_PREFIX)gcc -*_GCC49_X64_ASM_PATH = DEF(GCC49_X64_PREFIX)gcc -*_GCC49_X64_PP_PATH = DEF(GCC49_X64_PREFIX)gcc -*_GCC49_X64_VFRPP_PATH = DEF(GCC49_X64_PREFIX)gcc -*_GCC49_X64_ASLCC_PATH = DEF(GCC49_X64_PREFIX)gcc -*_GCC49_X64_ASLPP_PATH = DEF(GCC49_X64_PREFIX)gcc -*_GCC49_X64_RC_PATH = DEF(GCC49_X64_PREFIX)objcopy - -*_GCC49_X64_ASLCC_FLAGS = DEF(GCC49_ASLCC_FLAGS) -m64 -*_GCC49_X64_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 -*_GCC49_X64_ASM_FLAGS = DEF(GCC49_ASM_FLAGS) -m64 -*_GCC49_X64_DLINK_FLAGS = DEF(GCC49_X64_DLINK_FLAGS) -*_GCC49_X64_DLINK2_FLAGS = DEF(GCC49_X64_DLINK2_FLAGS) -*_GCC49_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) -*_GCC49_X64_NASM_FLAGS = -f elf64 -DRODATA_SECTION_NAME=.rodata - - DEBUG_GCC49_X64_CC_FLAGS = DEF(GCC49_X64_CC_FLAGS) -RELEASE_GCC49_X64_CC_FLAGS = DEF(GCC49_X64_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable - NOOPT_GCC49_X64_CC_FLAGS = DEF(GCC49_X64_CC_FLAGS) -O0 - -################## -# GCC49 ARM definitions -################## -*_GCC49_ARM_CC_PATH = ENV(GCC49_ARM_PREFIX)gcc -*_GCC49_ARM_SLINK_PATH = ENV(GCC49_ARM_PREFIX)ar -*_GCC49_ARM_DLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc -*_GCC49_ARM_ASLDLINK_PATH = ENV(GCC49_ARM_PREFIX)gcc -*_GCC49_ARM_ASM_PATH = ENV(GCC49_ARM_PREFIX)gcc -*_GCC49_ARM_PP_PATH = ENV(GCC49_ARM_PREFIX)gcc -*_GCC49_ARM_VFRPP_PATH = ENV(GCC49_ARM_PREFIX)gcc -*_GCC49_ARM_ASLCC_PATH = ENV(GCC49_ARM_PREFIX)gcc -*_GCC49_ARM_ASLPP_PATH = ENV(GCC49_ARM_PREFIX)gcc -*_GCC49_ARM_RC_PATH = ENV(GCC49_ARM_PREFIX)objcopy - -*_GCC49_ARM_ASLCC_FLAGS = DEF(GCC49_ASLCC_FLAGS) -*_GCC49_ARM_ASLDLINK_FLAGS = DEF(GCC49_ARM_ASLDLINK_FLAGS) -*_GCC49_ARM_ASM_FLAGS = DEF(GCC49_ARM_ASM_FLAGS) -*_GCC49_ARM_DLINK_FLAGS = DEF(GCC49_ARM_DLINK_FLAGS) -*_GCC49_ARM_DLINK2_FLAGS = DEF(GCC49_ARM_DLINK2_FLAGS) -*_GCC49_ARM_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC49_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS) -mthumb -march=armv7-a -*_GCC49_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS) -*_GCC49_ARM_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -mthumb -march=armv7-a -*_GCC49_ARM_CC_XIPFLAGS = DEF(GCC49_ARM_CC_XIPFLAGS) - - DEBUG_GCC49_ARM_CC_FLAGS = DEF(GCC49_ARM_CC_FLAGS) -O0 -RELEASE_GCC49_ARM_CC_FLAGS = DEF(GCC49_ARM_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable - NOOPT_GCC49_ARM_CC_FLAGS = DEF(GCC49_ARM_CC_FLAGS) -O0 - -################## -# GCC49 AARCH64 definitions -################## -*_GCC49_AARCH64_CC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc -*_GCC49_AARCH64_SLINK_PATH = ENV(GCC49_AARCH64_PREFIX)ar -*_GCC49_AARCH64_DLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc -*_GCC49_AARCH64_ASLDLINK_PATH = ENV(GCC49_AARCH64_PREFIX)gcc -*_GCC49_AARCH64_ASM_PATH = ENV(GCC49_AARCH64_PREFIX)gcc -*_GCC49_AARCH64_PP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc -*_GCC49_AARCH64_VFRPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc -*_GCC49_AARCH64_ASLCC_PATH = ENV(GCC49_AARCH64_PREFIX)gcc -*_GCC49_AARCH64_ASLPP_PATH = ENV(GCC49_AARCH64_PREFIX)gcc -*_GCC49_AARCH64_RC_PATH = ENV(GCC49_AARCH64_PREFIX)objcopy - -*_GCC49_AARCH64_ASLCC_FLAGS = DEF(GCC49_ASLCC_FLAGS) -*_GCC49_AARCH64_ASLDLINK_FLAGS = DEF(GCC49_AARCH64_ASLDLINK_FLAGS) -*_GCC49_AARCH64_ASM_FLAGS = DEF(GCC49_AARCH64_ASM_FLAGS) -*_GCC49_AARCH64_DLINK2_FLAGS = DEF(GCC49_AARCH64_DLINK2_FLAGS) -*_GCC49_AARCH64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC49_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) -*_GCC49_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS) -*_GCC49_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -*_GCC49_AARCH64_CC_XIPFLAGS = DEF(GCC49_AARCH64_CC_XIPFLAGS) - - DEBUG_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -O0 - DEBUG_GCC49_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) - DEBUG_GCC49_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) - -RELEASE_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC49_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) -RELEASE_GCC49_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) - - NOOPT_GCC49_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -O0 - NOOPT_GCC49_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) -O0 - NOOPT_GCC49_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) -O0 - #################################################################################### # # GCC NOLTO - This configuration is used to compile under Linux to produce @@ -1373,18 +1028,17 @@ RELEASE_GCC49_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) *_GCCNOLTO_IA32_ASLPP_PATH = DEF(GCCNOLTO_IA32_PREFIX)gcc *_GCCNOLTO_IA32_RC_PATH = DEF(GCCNOLTO_IA32_PREFIX)objcopy -*_GCCNOLTO_IA32_ASLCC_FLAGS = DEF(GCC49_ASLCC_FLAGS) -m32 -*_GCCNOLTO_IA32_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -*_GCCNOLTO_IA32_ASM_FLAGS = DEF(GCC49_ASM_FLAGS) -m32 -march=i386 -*_GCCNOLTO_IA32_DLINK_FLAGS = DEF(GCC49_IA32_X64_DLINK_FLAGS) -Wl,-m,elf_i386,--oformat=elf32-i386 -*_GCCNOLTO_IA32_DLINK2_FLAGS = DEF(GCC49_IA32_DLINK2_FLAGS) -*_GCCNOLTO_IA32_RC_FLAGS = DEF(GCC_IA32_RC_FLAGS) +*_GCCNOLTO_IA32_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) -m32 +*_GCCNOLTO_IA32_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 +*_GCCNOLTO_IA32_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m32 -march=i386 +*_GCCNOLTO_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-m,elf_i386,--oformat=elf32-i386 +*_GCCNOLTO_IA32_DLINK2_FLAGS = DEF(GCC5_IA32_DLINK2_FLAGS) *_GCCNOLTO_IA32_OBJCOPY_FLAGS = *_GCCNOLTO_IA32_NASM_FLAGS = -f elf32 - DEBUG_GCCNOLTO_IA32_CC_FLAGS = DEF(GCC49_IA32_CC_FLAGS) -RELEASE_GCCNOLTO_IA32_CC_FLAGS = DEF(GCC49_IA32_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable - NOOPT_GCCNOLTO_IA32_CC_FLAGS = DEF(GCC49_IA32_CC_FLAGS) -O0 + DEBUG_GCCNOLTO_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) +RELEASE_GCCNOLTO_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable + NOOPT_GCCNOLTO_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -O0 ################## # GCCNOLTO X64 definitions @@ -1401,18 +1055,17 @@ RELEASE_GCCNOLTO_IA32_CC_FLAGS = DEF(GCC49_IA32_CC_FLAGS) -Wno-unused-but- *_GCCNOLTO_X64_ASLPP_PATH = DEF(GCCNOLTO_X64_PREFIX)gcc *_GCCNOLTO_X64_RC_PATH = DEF(GCCNOLTO_X64_PREFIX)objcopy -*_GCCNOLTO_X64_ASLCC_FLAGS = DEF(GCC49_ASLCC_FLAGS) -m64 -*_GCCNOLTO_X64_ASLDLINK_FLAGS = DEF(GCC49_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 -*_GCCNOLTO_X64_ASM_FLAGS = DEF(GCC49_ASM_FLAGS) -m64 -*_GCCNOLTO_X64_DLINK_FLAGS = DEF(GCC49_X64_DLINK_FLAGS) -*_GCCNOLTO_X64_DLINK2_FLAGS = DEF(GCC49_X64_DLINK2_FLAGS) -*_GCCNOLTO_X64_RC_FLAGS = DEF(GCC_X64_RC_FLAGS) +*_GCCNOLTO_X64_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) -m64 +*_GCCNOLTO_X64_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 +*_GCCNOLTO_X64_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m64 +*_GCCNOLTO_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) +*_GCCNOLTO_X64_DLINK2_FLAGS = DEF(GCC5_X64_DLINK2_FLAGS) *_GCCNOLTO_X64_OBJCOPY_FLAGS = *_GCCNOLTO_X64_NASM_FLAGS = -f elf64 - DEBUG_GCCNOLTO_X64_CC_FLAGS = DEF(GCC49_X64_CC_FLAGS) -RELEASE_GCCNOLTO_X64_CC_FLAGS = DEF(GCC49_X64_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable - NOOPT_GCCNOLTO_X64_CC_FLAGS = DEF(GCC49_X64_CC_FLAGS) -O0 + DEBUG_GCCNOLTO_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) +RELEASE_GCCNOLTO_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable + NOOPT_GCCNOLTO_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -O0 ################## # GCCNOLTO ARM definitions @@ -1428,21 +1081,20 @@ RELEASE_GCCNOLTO_X64_CC_FLAGS = DEF(GCC49_X64_CC_FLAGS) -Wno-unused-but-se *_GCCNOLTO_ARM_ASLPP_PATH = ENV(GCCNOLTO_ARM_PREFIX)gcc *_GCCNOLTO_ARM_RC_PATH = ENV(GCCNOLTO_ARM_PREFIX)objcopy -*_GCCNOLTO_ARM_ASLCC_FLAGS = DEF(GCC49_ASLCC_FLAGS) -*_GCCNOLTO_ARM_ASLDLINK_FLAGS = DEF(GCC49_ARM_ASLDLINK_FLAGS) -*_GCCNOLTO_ARM_ASM_FLAGS = DEF(GCC49_ARM_ASM_FLAGS) -*_GCCNOLTO_ARM_DLINK_FLAGS = DEF(GCC49_ARM_DLINK_FLAGS) -*_GCCNOLTO_ARM_DLINK2_FLAGS = DEF(GCC49_ARM_DLINK2_FLAGS) +*_GCCNOLTO_ARM_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) +*_GCCNOLTO_ARM_ASLDLINK_FLAGS = DEF(GCC5_ARM_ASLDLINK_FLAGS) +*_GCCNOLTO_ARM_ASM_FLAGS = DEF(GCC5_ARM_ASM_FLAGS) +*_GCCNOLTO_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) +*_GCCNOLTO_ARM_DLINK2_FLAGS = DEF(GCC5_ARM_DLINK2_FLAGS) *_GCCNOLTO_ARM_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) *_GCCNOLTO_ARM_PLATFORM_FLAGS = -march=armv7-a *_GCCNOLTO_ARM_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) -*_GCCNOLTO_ARM_RC_FLAGS = DEF(GCC_ARM_RC_FLAGS) *_GCCNOLTO_ARM_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) -*_GCCNOLTO_ARM_CC_XIPFLAGS = DEF(GCC49_ARM_CC_XIPFLAGS) +*_GCCNOLTO_ARM_CC_XIPFLAGS = DEF(GCC5_ARM_CC_XIPFLAGS) - DEBUG_GCCNOLTO_ARM_CC_FLAGS = DEF(GCC49_ARM_CC_FLAGS) -O0 -RELEASE_GCCNOLTO_ARM_CC_FLAGS = DEF(GCC49_ARM_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable - NOOPT_GCCNOLTO_ARM_CC_FLAGS = DEF(GCC49_ARM_CC_FLAGS) -O0 + DEBUG_GCCNOLTO_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -O0 +RELEASE_GCCNOLTO_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable + NOOPT_GCCNOLTO_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -O0 ################## # GCCNOLTO AARCH64 definitions @@ -1458,27 +1110,26 @@ RELEASE_GCCNOLTO_ARM_CC_FLAGS = DEF(GCC49_ARM_CC_FLAGS) -Wno-unused-but-se *_GCCNOLTO_AARCH64_ASLPP_PATH = ENV(GCCNOLTO_AARCH64_PREFIX)gcc *_GCCNOLTO_AARCH64_RC_PATH = ENV(GCCNOLTO_AARCH64_PREFIX)objcopy -*_GCCNOLTO_AARCH64_ASLCC_FLAGS = DEF(GCC49_ASLCC_FLAGS) -*_GCCNOLTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC49_AARCH64_ASLDLINK_FLAGS) -*_GCCNOLTO_AARCH64_ASM_FLAGS = DEF(GCC49_AARCH64_ASM_FLAGS) -*_GCCNOLTO_AARCH64_DLINK2_FLAGS = DEF(GCC49_AARCH64_DLINK2_FLAGS) +*_GCCNOLTO_AARCH64_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) +*_GCCNOLTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC5_AARCH64_ASLDLINK_FLAGS) +*_GCCNOLTO_AARCH64_ASM_FLAGS = DEF(GCC5_AARCH64_ASM_FLAGS) +*_GCCNOLTO_AARCH64_DLINK2_FLAGS = DEF(GCC5_AARCH64_DLINK2_FLAGS) *_GCCNOLTO_AARCH64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) *_GCCNOLTO_AARCH64_PLATFORM_FLAGS = *_GCCNOLTO_AARCH64_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) -*_GCCNOLTO_AARCH64_RC_FLAGS = DEF(GCC_AARCH64_RC_FLAGS) *_GCCNOLTO_AARCH64_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) -*_GCCNOLTO_AARCH64_CC_XIPFLAGS = DEF(GCC49_AARCH64_CC_XIPFLAGS) +*_GCCNOLTO_AARCH64_CC_XIPFLAGS = DEF(GCC5_AARCH64_CC_XIPFLAGS) - DEBUG_GCCNOLTO_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -O0 - DEBUG_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) + DEBUG_GCCNOLTO_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 + DEBUG_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) DEBUG_GCCNOLTO_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 -RELEASE_GCCNOLTO_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) +RELEASE_GCCNOLTO_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable +RELEASE_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) RELEASE_GCCNOLTO_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 - NOOPT_GCCNOLTO_AARCH64_CC_FLAGS = DEF(GCC49_AARCH64_CC_FLAGS) -O0 - NOOPT_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCC49_AARCH64_DLINK_FLAGS) -O0 + NOOPT_GCCNOLTO_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 + NOOPT_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -O0 NOOPT_GCCNOLTO_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 -O0 #################################################################################### @@ -1518,19 +1169,19 @@ RELEASE_GCCNOLTO_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 *_GCC5_IA32_RC_PATH = DEF(GCC5_IA32_PREFIX)objcopy *_GCC5_IA32_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) -m32 -*_GCC5_IA32_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -no-pie +*_GCC5_IA32_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-q,-m,elf_i386 -no-pie *_GCC5_IA32_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m32 -march=i386 *_GCC5_IA32_DLINK2_FLAGS = DEF(GCC5_IA32_DLINK2_FLAGS) -no-pie *_GCC5_IA32_NASM_FLAGS = -f elf32 -DRODATA_SECTION_NAME=.rodata - DEBUG_GCC5_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -flto - DEBUG_GCC5_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-m,elf_i386,--oformat=elf32-i386 + DEBUG_GCC5_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -flto -Os + DEBUG_GCC5_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-q,-m,elf_i386,--oformat=elf32-i386 -RELEASE_GCC5_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC5_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-m,elf_i386,--oformat=elf32-i386 +RELEASE_GCC5_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -flto -Os -Wno-unused-but-set-variable -Wno-unused-const-variable +RELEASE_GCC5_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-q,-m,elf_i386,--oformat=elf32-i386 NOOPT_GCC5_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -O0 - NOOPT_GCC5_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-m,elf_i386,--oformat=elf32-i386 -O0 + NOOPT_GCC5_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-q,-m,elf_i386,--oformat=elf32-i386 -O0 ################## # GCC5 X64 definitions @@ -1924,7 +1575,7 @@ DEFINE CLANGPDB_IA32_TARGET = -target i686-unknown-windows-gnu DEFINE CLANGPDB_X64_TARGET = -target x86_64-unknown-windows-gnu DEFINE CLANGPDB_WARNING_OVERRIDES = -Wno-parentheses-equality -Wno-tautological-compare -Wno-tautological-constant-out-of-range-compare -Wno-empty-body -Wno-unused-const-variable -Wno-varargs -Wno-unknown-warning-option -Wno-unused-but-set-variable -Wno-unused-const-variable -Wno-unaligned-access -Wno-microsoft-enum-forward-reference -DEFINE CLANGPDB_ALL_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(CLANGPDB_WARNING_OVERRIDES) -fno-stack-protector -funsigned-char -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -Wno-address -Wno-shift-negative-value -Wno-unknown-pragmas -Wno-incompatible-library-redeclaration -Wno-null-dereference -mno-implicit-float -mms-bitfields -mno-stack-arg-probe -nostdlib -nostdlibinc -fseh-exceptions +DEFINE CLANGPDB_ALL_CC_FLAGS = DEF(GCC5_ALL_CC_FLAGS) DEF(CLANGPDB_WARNING_OVERRIDES) -fno-stack-protector -funsigned-char -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -Wno-address -Wno-shift-negative-value -Wno-unknown-pragmas -Wno-incompatible-library-redeclaration -Wno-null-dereference -mno-implicit-float -mms-bitfields -mno-stack-arg-probe -nostdlib -nostdlibinc -fseh-exceptions ########################### # CLANGPDB IA32 definitions @@ -2007,23 +1658,27 @@ NOOPT_CLANGPDB_X64_DLINK2_FLAGS = *_CLANGDWARF_*_APP_FLAGS = *_CLANGDWARF_*_ASL_FLAGS = DEF(IASL_FLAGS) *_CLANGDWARF_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS) +*_CLANGDWARF_*_DEPS_FLAGS = DEF(GCC_DEPS_FLAGS) +*_CLANGDWARF_*_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) DEFINE CLANGDWARF_IA32_PREFIX = ENV(CLANG_BIN) DEFINE CLANGDWARF_X64_PREFIX = ENV(CLANG_BIN) DEFINE CLANGDWARF_ARM_PREFIX = ENV(CLANG_BIN) DEFINE CLANGDWARF_AARCH64_PREFIX = ENV(CLANG_BIN) +DEFINE CLANGDWARF_IA32_TARGET = -target i686-pc-linux-gnu +DEFINE CLANGDWARF_X64_TARGET = -target x86_64-pc-linux-gnu +DEFINE CLANGDWARF_ARM_TARGET = -target arm-linux-gnueabi +DEFINE CLANGDWARF_AARCH64_TARGET = -target aarch64-linux-gnu + # LLVM/CLANG doesn't support -n link option. So, it can't share the same IA32_X64_DLINK_COMMON flag. -DEFINE CLANGDWARF_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-q,--gc-sections DEF(GCC_ALIGN) -Wl,-z,notext,--defsym=ALIGNED_PE_HEADER_SIZE=0x400 DEF(DLINK_SCRIPT) +DEFINE CLANGDWARF_IA32_X64_DLINK_COMMON = -nostdlib -Wl,--gc-sections DEF(GCC_ALIGN) -Wl,-z,notext,--defsym=ALIGNED_PE_HEADER_SIZE=0x400 DEF(DLINK_SCRIPT) DEFINE CLANGDWARF_IA32_X64_ASLDLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable DEFINE CLANGDWARF_IA32_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive DEFINE CLANGDWARF_IA32_DLINK2_FLAGS = -no-pie -DEFINE CLANGDWARF_IA32_TARGET = -target i686-pc-linux-gnu -DEFINE CLANGDWARF_X64_TARGET = -target x86_64-pc-linux-gnu - -DEFINE CLANGDWARF_WARNING_OVERRIDES = -Wno-parentheses-equality -Wno-empty-body -Wno-unused-const-variable -Wno-varargs -Wno-unknown-warning-option -Wno-unused-but-set-variable -Wno-unused-const-variable -Wno-unaligned-access -DEFINE CLANGDWARF_ALL_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(CLANGDWARF_WARNING_OVERRIDES) -fno-stack-protector -mms-bitfields -Wno-address -Wno-shift-negative-value -Wno-unknown-pragmas -Wno-incompatible-library-redeclaration -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -msoft-float -mno-implicit-float -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -funsigned-char -fno-ms-extensions -Wno-null-dereference +DEFINE CLANGDWARF_WARNING_OVERRIDES = -Wno-parentheses-equality -Wno-empty-body -Wno-unused-const-variable -Wno-varargs -Wno-unknown-warning-option -Wno-unused-but-set-variable -Wno-unused-const-variable -Wno-unaligned-access +DEFINE CLANGDWARF_ALL_CC_FLAGS = DEF(GCC5_ALL_CC_FLAGS) DEF(CLANGDWARF_WARNING_OVERRIDES) -fno-stack-protector -mms-bitfields -Wno-address -Wno-shift-negative-value -Wno-unknown-pragmas -Wno-incompatible-library-redeclaration -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -msoft-float -mno-implicit-float -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -funsigned-char -fno-ms-extensions -Wno-null-dereference ########################### # CLANGDWARF IA32 definitions @@ -2041,7 +1696,7 @@ DEFINE CLANGDWARF_ALL_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(CLANGDWARF_ *_CLANGDWARF_IA32_RC_PATH = DEF(CLANGDWARF_IA32_PREFIX)llvm-objcopy *_CLANGDWARF_IA32_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -m32 -fno-lto DEF(CLANGDWARF_IA32_TARGET) -*_CLANGDWARF_IA32_ASLDLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -fuse-ld=lld -no-pie +*_CLANGDWARF_IA32_ASLDLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_ASLDLINK_FLAGS) -Wl,-q,-m,elf_i386 -fuse-ld=lld -no-pie *_CLANGDWARF_IA32_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m32 -march=i386 DEF(CLANGDWARF_IA32_TARGET) *_CLANGDWARF_IA32_NASM_FLAGS = -f elf32 -DRODATA_SECTION_NAME=.rodata *_CLANGDWARF_IA32_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGDWARF_IA32_TARGET) @@ -2049,20 +1704,20 @@ DEFINE CLANGDWARF_ALL_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) DEF(CLANGDWARF_ *_CLANGDWARF_IA32_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_IA32_TARGET) DEBUG_CLANGDWARF_IA32_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m32 -malign-double -Oz -flto -march=i586 DEF(CLANGDWARF_IA32_TARGET) -g -fno-pic -fno-pie -DEBUG_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-O3 -Wl,-melf_i386 -Wl,--oformat,elf32-i386 -DEBUG_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O3 -fuse-ld=lld -no-pie +DEBUG_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-q,-O3 -Wl,-melf_i386 -Wl,--oformat,elf32-i386 +DEBUG_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O3 -fuse-ld=lld RELEASE_CLANGDWARF_IA32_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m32 -malign-double -Oz -flto -march=i586 DEF(CLANGDWARF_IA32_TARGET) -fno-pic -fno-pie -RELEASE_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-O3 -Wl,-melf_i386 -Wl,--oformat,elf32-i386 -RELEASE_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O3 -fuse-ld=lld -no-pie +RELEASE_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-q,-O3 -Wl,-melf_i386 -Wl,--oformat,elf32-i386 +RELEASE_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O3 -fuse-ld=lld NOOPT_CLANGDWARF_IA32_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m32 -malign-double -O0 -march=i586 DEF(CLANGDWARF_IA32_TARGET) -g -fno-pic -fno-pie -NOOPT_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-O0 -Wl,-melf_i386 -Wl,--oformat,elf32-i386 -NOOPT_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O0 -fuse-ld=lld -no-pie +NOOPT_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-O0 -Wl,-q,-melf_i386 -Wl,--oformat,elf32-i386 +NOOPT_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O0 -fuse-ld=lld -########################## +########################### # CLANGDWARF X64 definitions -########################## +########################### *_CLANGDWARF_X64_OBJCOPY_PATH = DEF(CLANGDWARF_X64_PREFIX)llvm-objcopy *_CLANGDWARF_X64_CC_PATH = DEF(CLANGDWARF_X64_PREFIX)clang *_CLANGDWARF_X64_SLINK_PATH = DEF(CLANGDWARF_X64_PREFIX)llvm-ar @@ -2098,7 +1753,6 @@ NOOPT_CLANGDWARF_X64_DLINK2_FLAGS = -O0 -fuse-ld=lld ################## # CLANGDWARF ARM definitions ################## -DEFINE CLANGDWARF_ARM_TARGET = -target arm-linux-gnueabi DEFINE CLANGDWARF_ARM_CC_FLAGS = DEF(GCC_ARM_CC_FLAGS) DEF(CLANGDWARF_ARM_TARGET) DEF(CLANGDWARF_WARNING_OVERRIDES) -mno-movt -fno-stack-protector DEFINE CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_DLINK_FLAGS) -fuse-ld=lld -Wl,--apply-dynamic-relocs,--no-pie,--no-relax @@ -2140,7 +1794,6 @@ RELEASE_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl, ################## # CLANGDWARF AARCH64 definitions ################## -DEFINE CLANGDWARF_AARCH64_TARGET = -target aarch64-linux-gnu DEFINE CLANGDWARF_AARCH64_CC_FLAGS = DEF(GCC_AARCH64_CC_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) -mcmodel=small DEF(CLANGDWARF_WARNING_OVERRIDES) DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_DLINK_FLAGS) DEF(GCC_ALIGN) -fuse-ld=lld -Wl,--apply-dynamic-relocs,--no-pie,--no-relax diff --git a/EmulatorPkg/Unix/Host/Host.inf b/EmulatorPkg/Unix/Host/Host.inf index cae6ea0979..d8f9585e20 100644 --- a/EmulatorPkg/Unix/Host/Host.inf +++ b/EmulatorPkg/Unix/Host/Host.inf @@ -121,8 +121,6 @@ GCC:*_*_X64_DLINK_FLAGS == -o $(BIN_DIR)/Host -m64 -L/usr/X11R6/lib GCC:*_GCC5_X64_DLINK_FLAGS == -flto -o $(BIN_DIR)/Host -m64 -L/usr/X11R6/lib GCC:*_*_X64_CC_FLAGS == -m64 -g -fshort-wchar -fno-strict-aliasing -Wall -malign-double -idirafter/usr/include -c -include $(DEST_DIR_DEBUG)/AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings - GCC:*_GCC48_X64_CC_FLAGS = "-DEFIAPI=__attribute__((ms_abi))" - GCC:*_GCC49_X64_CC_FLAGS = "-DEFIAPI=__attribute__((ms_abi))" GCC:*_GCC5_X64_CC_FLAGS = "-DEFIAPI=__attribute__((ms_abi))" -flto -DUSING_LTO -Os GCC:*_GCC_X64_CC_FLAGS = "-DEFIAPI=__attribute__((ms_abi))" -flto -DUSING_LTO -Os GCC:*_*_X64_PP_FLAGS == -m64 -E -x assembler-with-cpp -include $(DEST_DIR_DEBUG)/AutoGen.h diff --git a/EmulatorPkg/build.sh b/EmulatorPkg/build.sh index 76c22dfaf8..5bf1a82d83 100755 --- a/EmulatorPkg/build.sh +++ b/EmulatorPkg/build.sh @@ -42,7 +42,7 @@ PLATFORMFILE= LAST_ARG= RUN_EMULATOR=no CLEAN_TYPE=none -TARGET_TOOLS=GCC48 +TARGET_TOOLS=GCC5 NETWORK_SUPPORT= BUILD_NEW_SHELL= BUILD_FAT= @@ -87,16 +87,10 @@ case `uname` in gcc_version=$(gcc -v 2>&1 | tail -1 | awk '{print $3}') case $gcc_version in - [1-3].*|4.[0-7].*) - echo EmulatorPkg requires GCC4.8 or later + [1-3].*|4.[0-9].*) + echo EmulatorPkg requires GCC5 or later exit 1 ;; - 4.8.*) - TARGET_TOOLS=GCC48 - ;; - 4.9.*|6.[0-2].*) - TARGET_TOOLS=GCC49 - ;; *) TARGET_TOOLS=GCC5 ;; @@ -249,4 +243,3 @@ else cp "$BUILD_OUTPUT_DIR/${BUILDTARGET}_$HOST_TOOLS/$PROCESSOR/Host" $BUILD_ROOT_ARCH fi exit $? - diff --git a/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc b/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc index 4fbaf8efd0..c9478d49c2 100644 --- a/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc +++ b/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc @@ -461,9 +461,6 @@ ################################################################################################### [BuildOptions] # Append build options for EDK and EDKII drivers (= is Append, == is Replace) - # Enable link-time optimization when building with GCC49 - *_GCC49_IA32_CC_FLAGS = -flto - *_GCC49_IA32_DLINK_FLAGS = -flto *_GCC5_IA32_CC_FLAGS = -fno-pic *_GCC5_IA32_DLINK_FLAGS = -no-pie *_GCC5_IA32_ASLCC_FLAGS = -fno-pic diff --git a/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.c b/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.c index 2d610f6bd3..9ab357ebb8 100644 --- a/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.c +++ b/OvmfPkg/Library/X86QemuLoadImageLib/X86QemuLoadImageLib.c @@ -362,11 +362,6 @@ QemuLoadKernelImage ( UINTN InitrdSize; BOOLEAN Shim; - // - // Redundant assignment to work around GCC48/GCC49 limitations. - // - CommandLine = NULL; - // // Load the image. This should call back into the QEMU EFI loader file system. // diff --git a/OvmfPkg/README b/OvmfPkg/README index 8c19b4c490..73c85099d2 100644 --- a/OvmfPkg/README +++ b/OvmfPkg/README @@ -119,8 +119,8 @@ $ OvmfPkg/build.sh -a X64 qemu And to run a 64-bit UEFI bootable ISO image: $ OvmfPkg/build.sh -a X64 qemu -cdrom /path/to/disk-image.iso -To build a 32-bit OVMF without debug messages using GCC 4.8: -$ OvmfPkg/build.sh -a IA32 -b RELEASE -t GCC48 +To build a 32-bit OVMF without debug messages using GCC 5: +$ OvmfPkg/build.sh -a IA32 -b RELEASE -t GCC5 === Secure Boot === diff --git a/OvmfPkg/build.sh b/OvmfPkg/build.sh index 279f0d099a..f14b7f72ff 100755 --- a/OvmfPkg/build.sh +++ b/OvmfPkg/build.sh @@ -77,16 +77,10 @@ case `uname` in Linux*) gcc_version=$(gcc -v 2>&1 | tail -1 | awk '{print $3}') case $gcc_version in - [1-3].*|4.[0-7].*) - echo OvmfPkg requires GCC4.8 or later + [1-3].*|4.[0-9].*) + echo OvmfPkg requires GCC5 or later exit 1 ;; - 4.8.*) - TARGET_TOOLS=GCC48 - ;; - 4.9.*|6.[0-2].*) - TARGET_TOOLS=GCC49 - ;; *) TARGET_TOOLS=GCC5 ;; From 7b30f784112c61c4747a1dde2caf1fb424f7b5e7 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 26 Jun 2023 13:28:22 +0300 Subject: [PATCH 032/341] Build: Renamed XIPFLAGS as SECPEIFLAGS, added comment in build_rule.template on its usage. --- .pytool/Plugin/SpellCheck/cspell.base.yaml | 2 +- ArmVirtPkg/ArmVirtKvmTool.dsc | 2 +- BaseTools/Conf/build_rule.template | 7 ++- BaseTools/Conf/tools_def.template | 56 +++++++++---------- CryptoPkg/Library/OpensslLib/OpensslLib.inf | 2 +- .../Library/OpensslLib/OpensslLibCrypto.inf | 2 +- .../Library/OpensslLib/OpensslLibFull.inf | 2 +- 7 files changed, 38 insertions(+), 35 deletions(-) diff --git a/.pytool/Plugin/SpellCheck/cspell.base.yaml b/.pytool/Plugin/SpellCheck/cspell.base.yaml index bd24c823ae..45ae19a81a 100644 --- a/.pytool/Plugin/SpellCheck/cspell.base.yaml +++ b/.pytool/Plugin/SpellCheck/cspell.base.yaml @@ -289,7 +289,7 @@ "XENSTORE", "xform", "xformed", - "XIPFLAGS", + "SECPEIFLAGS", "xmlef", "yesno" ] diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc index 2714593271..278ec1b629 100644 --- a/ArmVirtPkg/ArmVirtKvmTool.dsc +++ b/ArmVirtPkg/ArmVirtKvmTool.dsc @@ -111,7 +111,7 @@ # We need to avoid jump tables in SEC and BASE modules, so that the PE/COFF # self-relocation code itself is guaranteed to be position independent. # - GCC:*_*_*_CC_XIPFLAGS = -fno-jump-tables + GCC:*_*_*_CC_SECPEIFLAGS = -fno-jump-tables ################################################################################ # diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template index f9b4b83d32..7a85d73e09 100755 --- a/BaseTools/Conf/build_rule.template +++ b/BaseTools/Conf/build_rule.template @@ -134,6 +134,9 @@ "$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) -o ${dst} $(INC) ${src} +## Early stages on ARM/AArch64 execute with strict alignment enabled and will crash, +# when compiler generates misaligned access. +# [C-Code-File.BASE.AARCH64,C-Code-File.SEC.AARCH64,C-Code-File.PEI_CORE.AARCH64,C-Code-File.PEIM.AARCH64,C-Code-File.BASE.ARM,C-Code-File.SEC.ARM,C-Code-File.PEI_CORE.ARM,C-Code-File.PEIM.ARM] ?.c @@ -145,7 +148,7 @@ $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj - "$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) $(CC_XIPFLAGS) -c -o ${dst} $(INC) ${src} + "$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) $(CC_SECPEIFLAGS) -c -o ${dst} $(INC) ${src} [C-Header-File] @@ -324,7 +327,7 @@ "$(DLINK)" /OUT:${dst} $(DLINK_FLAGS) $(DLINK_XIPFLAGS) $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) - "$(DLINK)" -o ${dst} $(DLINK_FLAGS) $(DLINK_XIPFLAGS) -Wl,--start-group,@$(STATIC_LIBRARY_FILES_LIST),--end-group $(CC_FLAGS) $(CC_XIPFLAGS) $(DLINK2_FLAGS) + "$(DLINK)" -o ${dst} $(DLINK_FLAGS) $(DLINK_SECPEIFLAGS) -Wl,--start-group,@$(STATIC_LIBRARY_FILES_LIST),--end-group $(CC_FLAGS) $(CC_SECPEIFLAGS) $(DLINK2_FLAGS) [Static-Library-File.USER_DEFINED] diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index a245a49645..bee52d1cd7 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -801,7 +801,7 @@ RELEASE_VS2022_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:425 NOOPT_VS2022_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /WX /IGNORE:4210 # BaseTools cannot handle XIP modules with different section and file alignment -*_VS2022_IA32_DLINK_XIPFLAGS = /ALIGN:32 +*_VS2022_IA32_DLINK_SECPEIFLAGS = /ALIGN:32 ################## # X64 definitions @@ -837,7 +837,7 @@ RELEASE_VS2022_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:428 NOOPT_VS2022_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /ALIGN:4096 /DLL /WX /IGNORE:4210 # BaseTools cannot handle XIP modules with different section and file alignment -*_VS2022_X64_DLINK_XIPFLAGS = /ALIGN:32 +*_VS2022_X64_DLINK_SECPEIFLAGS = /ALIGN:32 ################# # ARM definitions @@ -870,7 +870,7 @@ RELEASE_VS2022_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4 NOOPT_VS2022_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /WX /IGNORE:4210 # BaseTools cannot handle XIP modules with different section and file alignment -*_VS2022_ARM_DLINK_XIPFLAGS = /ALIGN:32 +*_VS2022_ARM_DLINK_SECPEIFLAGS = /ALIGN:32 ##################### # AARCH64 definitions @@ -903,7 +903,7 @@ RELEASE_VS2022_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE: NOOPT_VS2022_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /DEBUG /WX /IGNORE:4210 # BaseTools cannot handle XIP modules with different section and file alignment -*_VS2022_AARCH64_DLINK_XIPFLAGS = /ALIGN:32 +*_VS2022_AARCH64_DLINK_SECPEIFLAGS = /ALIGN:32 #################################################################################### # GCC Common @@ -922,13 +922,13 @@ DEFINE GCC_ALL_CC_FLAGS = -g -Os -fshort-wchar -fno-builtin -fno-stri DEFINE GCC_IA32_X64_CC_FLAGS = -mstack-protector-guard=global DEFINE GCC_ARM_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -march=armv7-a -mthumb -mlittle-endian -mabi=aapcs -fno-short-enums -funsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -Wno-address -fno-pic -fno-pie -mstack-protector-guard=global DEFINE GCC_LOONGARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mabi=lp64d -fno-asynchronous-unwind-tables -Wno-address -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections -DEFINE GCC_ARM_CC_XIPFLAGS = -mno-unaligned-access DEFINE GCC_AARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mlittle-endian -fno-short-enums -fverbose-asm -funsigned-char -ffunction-sections -fdata-sections -Wno-address -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pic -fno-pie -ffixed-x18 -mstack-protector-guard=global -DEFINE GCC_AARCH64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only -DEFINE GCC_RISCV64_CC_XIPFLAGS = -mstrict-align -mgeneral-regs-only +DEFINE GCC_RISCV64_CC_SECPEIFLAGS = -mstrict-align -mgeneral-regs-only DEFINE GCC_DLINK2_FLAGS_COMMON = -Wl,--defsym=ALIGNED_PE_HEADER_SIZE=0x400 DEF(DLINK_SCRIPT) DEFINE GCC_ARM_AARCH64_DLINK_COMMON= -Wl,--emit-relocs -nostdlib -Wl,--gc-sections -u $(IMAGE_ENTRY_POINT) -Wl,-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map -Wl,--fatal-warnings -Wl,-z,noexecstack -no-pie DEFINE GCC_LOONGARCH64_DLINK_COMMON= -Wl,--emit-relocs -nostdlib -Wl,--gc-sections -u $(IMAGE_ENTRY_POINT) -Wl,-e,$(IMAGE_ENTRY_POINT),-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map +DEFINE GCC_ARM_CC_SECPEIFLAGS = -mno-unaligned-access +DEFINE GCC_AARCH64_CC_SECPEIFLAGS = -mstrict-align -mgeneral-regs-only DEFINE GCC_ARM_DLINK_FLAGS = DEF(GCC_ARM_AARCH64_DLINK_COMMON) DEF(GCC_ALIGN) -Wl,--pic-veneer DEFINE GCC_AARCH64_DLINK_FLAGS = DEF(GCC_ARM_AARCH64_DLINK_COMMON) DEF(GCC_ALIGN) DEFINE GCC_LOONGARCH64_DLINK_FLAGS = DEF(GCC_LOONGARCH64_DLINK_COMMON) DEF(GCC_ALIGN) @@ -1090,7 +1090,7 @@ RELEASE_GCCNOLTO_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -Wno-unused-but-set *_GCCNOLTO_ARM_PLATFORM_FLAGS = -march=armv7-a *_GCCNOLTO_ARM_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) *_GCCNOLTO_ARM_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) -*_GCCNOLTO_ARM_CC_XIPFLAGS = DEF(GCC5_ARM_CC_XIPFLAGS) +*_GCCNOLTO_ARM_CC_SECPEIFLAGS = DEF(GCC_ARM_CC_SECPEIFLAGS) DEBUG_GCCNOLTO_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -O0 RELEASE_GCCNOLTO_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable @@ -1118,19 +1118,19 @@ RELEASE_GCCNOLTO_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -Wno-unused-but-set *_GCCNOLTO_AARCH64_PLATFORM_FLAGS = *_GCCNOLTO_AARCH64_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) *_GCCNOLTO_AARCH64_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) -*_GCCNOLTO_AARCH64_CC_XIPFLAGS = DEF(GCC5_AARCH64_CC_XIPFLAGS) +*_GCCNOLTO_AARCH64_CC_SECPEIFLAGS = DEF(GCC_AARCH64_CC_SECPEIFLAGS) DEBUG_GCCNOLTO_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 DEBUG_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) - DEBUG_GCCNOLTO_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 + DEBUG_GCCNOLTO_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 RELEASE_GCCNOLTO_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable RELEASE_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -RELEASE_GCCNOLTO_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 +RELEASE_GCCNOLTO_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 NOOPT_GCCNOLTO_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 NOOPT_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -O0 - NOOPT_GCCNOLTO_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 -O0 + NOOPT_GCCNOLTO_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 -O0 #################################################################################### # @@ -1235,7 +1235,7 @@ RELEASE_GCC5_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os *_GCC5_ARM_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) *_GCC5_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS) -mthumb -march=armv7-a *_GCC5_ARM_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -mthumb -march=armv7-a -*_GCC5_ARM_CC_XIPFLAGS = DEF(GCC5_ARM_CC_XIPFLAGS) +*_GCC5_ARM_CC_SECPEIFLAGS = DEF(GCC_ARM_CC_SECPEIFLAGS) DEBUG_GCC5_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable DEBUG_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm @@ -1268,19 +1268,19 @@ RELEASE_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKS *_GCC5_AARCH64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) *_GCC5_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) *_GCC5_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -*_GCC5_AARCH64_CC_XIPFLAGS = DEF(GCC5_AARCH64_CC_XIPFLAGS) +*_GCC5_AARCH64_CC_SECPEIFLAGS = DEF(GCC_AARCH64_CC_SECPEIFLAGS) DEBUG_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable DEBUG_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch - DEBUG_GCC5_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) + DEBUG_GCC5_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) RELEASE_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable RELEASE_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch -RELEASE_GCC5_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) +RELEASE_GCC5_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) NOOPT_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 NOOPT_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -O0 - NOOPT_GCC5_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) -O0 + NOOPT_GCC5_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) -O0 #################################################################################### # @@ -1444,7 +1444,7 @@ RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os *_GCC_ARM_PLATFORM_FLAGS = -march=armv7-a -mfloat-abi=soft *_GCC_ARM_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) *_GCC_ARM_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) -*_GCC_ARM_CC_XIPFLAGS = DEF(GCC5_ARM_CC_XIPFLAGS) +*_GCC_ARM_CC_SECPEIFLAGS = DEF(GCC_ARM_CC_SECPEIFLAGS) DEBUG_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable DEBUG_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm @@ -1477,19 +1477,19 @@ RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSP *_GCC_AARCH64_PLATFORM_FLAGS = *_GCC_AARCH64_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) *_GCC_AARCH64_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) -*_GCC_AARCH64_CC_XIPFLAGS = DEF(GCC5_AARCH64_CC_XIPFLAGS) +*_GCC_AARCH64_CC_SECPEIFLAGS = DEF(GCC_AARCH64_CC_SECPEIFLAGS) DEBUG_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable DEBUG_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch - DEBUG_GCC_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 + DEBUG_GCC_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 RELEASE_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable RELEASE_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch -RELEASE_GCC_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 +RELEASE_GCC_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 NOOPT_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 NOOPT_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -O0 - NOOPT_GCC_AARCH64_DLINK_XIPFLAGS = -z common-page-size=0x20 -O0 + NOOPT_GCC_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 -O0 #################################################################################### # @@ -1782,7 +1782,7 @@ DEFINE CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_DLI *_CLANGDWARF_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGDWARF_ARM_TARGET) -march=armv7-a *_CLANGDWARF_ARM_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_ARM_TARGET) -march=armv7-a *_CLANGDWARF_ARM_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGDWARF_ARM_TARGET) -*_CLANGDWARF_ARM_CC_XIPFLAGS = DEF(GCC_ARM_CC_XIPFLAGS) +*_CLANGDWARF_ARM_CC_SECPEIFLAGS = DEF(GCC_ARM_CC_SECPEIFLAGS) DEBUG_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) -flto -O1 DEBUG_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O1 -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm @@ -1820,12 +1820,12 @@ DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_ *_CLANGDWARF_AARCH64_ASLDLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_ASLDLINK_FLAGS) -fuse-ld=lld *_CLANGDWARF_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) -Qunused-arguments *_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_DLINK_FLAGS) DEF(GCC_ALIGN) -*_CLANGDWARF_AARCH64_DLINK_XIPFLAGS = DEF(GCC_ALIGN) +*_CLANGDWARF_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) *_CLANGDWARF_AARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) *_CLANGDWARF_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) *_CLANGDWARF_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) *_CLANGDWARF_AARCH64_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) -*_CLANGDWARF_AARCH64_CC_XIPFLAGS = -mstrict-align +*_CLANGDWARF_AARCH64_CC_SECPEIFLAGS = DEF(GCC_AARCH64_CC_SECPEIFLAGS) DEBUG_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) -flto -O1 DEBUG_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O1 -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 @@ -1870,14 +1870,14 @@ DEFINE CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_TARGET) DEF *_CLANGDWARF_RISCV64_ASLDLINK_FLAGS = DEF(CLANGDWARF_RISCV64_TARGET) DEF(GCC5_RISCV32_RISCV64_ASLDLINK_FLAGS) *_CLANGDWARF_RISCV64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_RISCV64_TARGET) $(PLATFORM_FLAGS) -Qunused-arguments -mabi=lp64 -mno-relax *_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_TARGET) DEF(GCC5_RISCV64_DLINK_FLAGS) -*_CLANGDWARF_RISCV64_DLINK_XIPFLAGS = -z common-page-size=0x20 -*_CLANGDWARF_RISCV64_DLINK2_FLAGS = DEF(CLANGDWARF_DLINK2_FLAGS_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0x240 +*_CLANGDWARF_RISCV64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 +*_CLANGDWARF_RISCV64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0x240 *_CLANGDWARF_RISCV64_PLATFORM_FLAGS = *_CLANGDWARF_RISCV64_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGDWARF_RISCV64_TARGET) $(PLATFORM_FLAGS) *_CLANGDWARF_RISCV64_RC_FLAGS = DEF(GCC_RISCV64_RC_FLAGS) *_CLANGDWARF_RISCV64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_RISCV64_TARGET) $(PLATFORM_FLAGS) *_CLANGDWARF_RISCV64_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGDWARF_RISCV64_TARGET) -*_CLANGDWARF_RISCV64_CC_XIPFLAGS = DEF(GCC_RISCV64_CC_XIPFLAGS) +*_CLANGDWARF_RISCV64_CC_SECPEIFLAGS = DEF(GCC_RISCV64_CC_SECPEIFLAGS) DEBUG_CLANGDWARF_RISCV64_CC_FLAGS = DEF(CLANGDWARF_RISCV64_CC_FLAGS) $(PLATFORM_FLAGS) -flto -O1 DEBUG_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_DLINK_FLAGS) -flto -Wl,-O1 -fuse-ld=lld -Wl,--no-pie,--no-relax diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf index 9e7f59b548..21d63b15ea 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf @@ -790,4 +790,4 @@ # compiler from successfully building some of the OpenSSL source files that # use floating point types, so clear the flags here. # - GCC:*_*_AARCH64_CC_XIPFLAGS == + GCC:*_*_AARCH64_CC_SECPEIFLAGS == diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf index 5b7b160983..66aa304afb 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf @@ -741,4 +741,4 @@ # compiler from successfully building some of the OpenSSL source files that # use floating point types, so clear the flags here. # - GCC:*_*_AARCH64_CC_XIPFLAGS == + GCC:*_*_AARCH64_CC_SECPEIFLAGS == diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf b/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf index ad9a9c3260..d063e9abb0 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf @@ -847,4 +847,4 @@ # compiler from successfully building some of the OpenSSL source files that # use floating point types, so clear the flags here. # - GCC:*_*_AARCH64_CC_XIPFLAGS == + GCC:*_*_AARCH64_CC_SECPEIFLAGS == From f75d7e9fca6c32d74611498cb0495cb501c4ee19 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 20 Apr 2023 11:03:03 +0300 Subject: [PATCH 033/341] MdePkg: Add PCD to remove X perm from image sections with WX perms This feature is useful for images created by old Apple mtoc utility. Signed-off-by: Vitaly Cheptsov --- MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf | 1 + MdePkg/Library/BasePeCoffLib2/PeCoffInit.c | 2 +- .../Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf | 1 + MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c | 4 ++++ MdePkg/MdePkg.dec | 9 +++++++++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf index f3c3951ac5..42b49a82bb 100644 --- a/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf +++ b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf @@ -46,3 +46,4 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderProhibitTe gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c index 11b8237599..bde745ff38 100644 --- a/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c @@ -126,7 +126,7 @@ InternalVerifySections ( // Verify the Image section adheres to the W^X principle, if the policy // demands it. // - if (PcdGetBool (PcdImageLoaderWXorX)) { + if (PcdGetBool (PcdImageLoaderWXorX) && !PcdGetBool (PcdImageLoaderRemoveXForWX)) { if ((Sections[SectionIndex].Characteristics & (EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_MEM_WRITE)) == (EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_MEM_WRITE)) { DEBUG_RAISE (); return RETURN_VOLUME_CORRUPTED; diff --git a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf index e3684fe922..a533706604 100644 --- a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf +++ b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf @@ -39,3 +39,4 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderLoadHeader gEfiMdePkgTokenSpaceGuid.PcdImageLoaderProhibitTe gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX diff --git a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c b/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c index 678c6b2b5a..683ee0a9af 100644 --- a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c @@ -37,6 +37,10 @@ InternalCharacteristicsToAttributes ( { UINT32 Attributes; + if (PcdGetBool (PcdImageLoaderRemoveXForWX) && (Characteristics & (EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_MEM_WRITE)) == (EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_MEM_WRITE)) { + Characteristics &= ~EFI_IMAGE_SCN_MEM_EXECUTE; + } + Attributes = 0; if ((Characteristics & EFI_IMAGE_SCN_MEM_READ) == 0) { Attributes |= EFI_MEMORY_RP; diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 98391bfefe..257841d492 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -2363,6 +2363,15 @@ # @Prompt Allow Misaligned Offset. gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|FALSE|BOOLEAN|0x40001020 + ## Indicates whether Image sections that do not adhere to the W^X principle + # by mistake will have their X permission removed at load time.

+ # TRUE - Image sections with WX permissions will have X permission removed.
+ # FALSE - Image sections with WX permissions will be treated by PcdImageLoaderWXorX.
+ # This feature is only useful for images created by old Apple mtoc utility. Do not enable + # it unless such images need to be supported. + # @Prompt Remove X permission from WX sections. + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX|FALSE|BOOLEAN|0x40001021 + [PcdsFixedAtBuild,PcdsPatchableInModule] ## Indicates the maximum length of unicode string used in the following # BaseLib functions: StrLen(), StrSize(), StrCmp(), StrnCmp(), StrCpy(), StrnCpy()

From a5fc3d111f35a4738744031a7b2dce67a3ae0a78 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 27 Feb 2025 14:06:29 +0300 Subject: [PATCH 034/341] CI: Constructed separate workflows for common, arm, x86 packages and CodeQL. Signed-off-by: Savva Mitrofanov --- .devcontainer/devcontainer.json | 26 +- .github/workflows/build_arm.yaml | 312 +++++++++++++ .github/workflows/build_common.yml | 676 ++++++++++++++++++++++++++++ .github/workflows/build_nolto.yaml | 577 ++++++++++++++++++++++++ .github/workflows/build_x86.yaml | 680 +++++++++++++++++++++++++++++ .github/workflows/codeql.yml | 30 +- .pytool/CISettings.py | 3 + Ext4Pkg/Ext4Pkg.ci.yaml | 65 +++ docker-compose.yaml | 13 + 9 files changed, 2344 insertions(+), 38 deletions(-) create mode 100644 .github/workflows/build_arm.yaml create mode 100644 .github/workflows/build_common.yml create mode 100644 .github/workflows/build_nolto.yaml create mode 100644 .github/workflows/build_x86.yaml create mode 100644 Ext4Pkg/Ext4Pkg.ci.yaml create mode 100755 docker-compose.yaml diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 43694eb389..41b18091fe 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,16 +1,10 @@ -{ - "image": "ghcr.io/tianocore/containers/fedora-40-dev:latest", - "postCreateCommand": "git config --global --add safe.directory '*' && pip install --upgrade -r pip-requirements.txt", - "customizations": { - "vscode": { - "extensions": [ - "DavidAnson.vscode-markdownlint", - "ms-azuretools.vscode-docker", - "ms-vscode-remote.remote-containers", - "ms-vscode.cpptools", - "walonli.edk2-vscode", - "zachflower.uncrustify" - ] - } - } -} +{ + "name": "audk", + "build": { + "dockerfile": "../OpenCorePkg/Dockerfiles/oc-dev/Dockerfile", + "context": "../OpenCorePkg/Dockerfiles/oc-dev/", + "target": "oc-dev-edk2" + }, + "workspaceMount": "source=${localWorkspaceFolder},target=/com.docker.devenvironments.code,type=bind,consistency=cached", + "workspaceFolder": "/com.docker.devenvironments.code" +} diff --git a/.github/workflows/build_arm.yaml b/.github/workflows/build_arm.yaml new file mode 100644 index 0000000000..be83e78d4e --- /dev/null +++ b/.github/workflows/build_arm.yaml @@ -0,0 +1,312 @@ +name: Build ARM Firmwares + +on: + push: + pull_request: + workflow_dispatch: + release: + types: [published] + +env: + PROJECT_TYPE: UEFI + FORCE_INSTALL: 1 + WERROR: 1 + QEMU_VERSION_TAG: qemu-ci-8.1.5-r1 + WINPE_VERSION_TAG: images-winpe-1.0 + +jobs: + build-linux-gcc5: + name: Linux GCC5 + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y lsb-release wget software-properties-common gnupg build-essential nasm uuid-dev libssl-dev iasl curl git zip gcc-arm-linux-gnueabi gcc-aarch64-linux-gnu + + - name: CI Bootstrap + run: | + src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1 + touch UDK.ready + + - name: Prepare efibuild.sh + run: | + curl -o ./efibuild.sh https://raw.githubusercontent.com/acidanthera/ocbuild/master/efibuild.sh || exit 1 + chmod +x ./efibuild.sh + ln -s `pwd` UDK + + - name: Build BaseTools + run: ./efibuild.sh + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build ArmPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: ArmPkg + SELFPKG_DIR: ArmPkg + TOOLCHAINS: GCC5 + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + GCC5_ARM_PREFIX: arm-linux-gnueabi- + GCC5_AARCH64_PREFIX: aarch64-linux-gnu- + + - name: Build ArmPlatformPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: ArmPlatformPkg + SELFPKG_DIR: ArmPlatformPkg + TOOLCHAINS: GCC5 + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + GCC5_ARM_PREFIX: arm-linux-gnueabi- + GCC5_AARCH64_PREFIX: aarch64-linux-gnu- + + - name: Build ArmVirtQemu + if: always() + run: ./efibuild.sh + env: + SELFPKG: ArmVirtQemu + SELFPKG_DIR: ArmVirtPkg + TOOLCHAINS: GCC5 + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + GCC5_ARM_PREFIX: arm-linux-gnueabi- + GCC5_AARCH64_PREFIX: aarch64-linux-gnu- + + - name: Prepare artifacts with firmwares + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + mkdir -p ./firmware_artifacts/ArmVirtQemu/"$arch"/"$target"_"$TOOLCHAIN" + cp ./Build/ArmVirtQemu-"$arch"/"$target"_"$TOOLCHAIN"/FV/QEMU_EFI.fd ./firmware_artifacts/ArmVirtQemu/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done + env: + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG,NOOPT + TOOLCHAIN: GCC5 + + - name: Zip artifacts + run: zip GCC5_fw_arm_artifacts.zip ./firmware_artifacts/* -r + + - name: Upload to Artifacts + uses: actions/upload-artifact@v4 + with: + name: GCC5 Firmware ARM Artifacts + path: GCC5_fw_arm_artifacts.zip + + build-linux-clangdwarf: + name: Linux CLANGDWARF + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y lsb-release wget software-properties-common gnupg build-essential nasm uuid-dev libssl-dev iasl curl git zip + wget https://apt.llvm.org/llvm.sh + chmod +x llvm.sh + yes '' | sudo ./llvm.sh 15 + rm -f llvm.sh + echo "/usr/lib/llvm-15/bin" >> $GITHUB_PATH + + - name: CI Bootstrap + run: | + src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1 + touch UDK.ready + + - name: Prepare efibuild.sh + run: | + curl -o ./efibuild.sh https://raw.githubusercontent.com/acidanthera/ocbuild/master/efibuild.sh || exit 1 + chmod +x ./efibuild.sh + ln -s `pwd` UDK + + - name: Build BaseTools + run: ./efibuild.sh + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build ArmPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: ArmPkg + SELFPKG_DIR: ArmPkg + TOOLCHAINS: CLANGDWARF + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build ArmPlatformPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: ArmPlatformPkg + SELFPKG_DIR: ArmPlatformPkg + TOOLCHAINS: CLANGDWARF + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build ArmVirtQemu + if: always() + run: ./efibuild.sh + env: + SELFPKG: ArmVirtQemu + SELFPKG_DIR: ArmVirtPkg + TOOLCHAINS: CLANGDWARF + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Prepare artifacts with firmwares + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + mkdir -p ./firmware_artifacts/ArmVirtQemu/"$arch"/"$target"_"$TOOLCHAIN" + cp ./Build/ArmVirtQemu-"$arch"/"$target"_"$TOOLCHAIN"/FV/QEMU_EFI.fd ./firmware_artifacts/ArmVirtQemu/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done + env: + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG,NOOPT + TOOLCHAIN: CLANGDWARF + + - name: Zip artifacts + run: zip CLANGDWARF_fw_arm_artifacts.zip ./firmware_artifacts/* -r + + - name: Upload to Artifacts + uses: actions/upload-artifact@v4 + with: + name: CLANGDWARF Firmware ARM Artifacts + path: CLANGDWARF_fw_arm_artifacts.zip + + test-firmwares: + name: Test + runs-on: ubuntu-22.04 + needs: [build-linux-gcc5, build-linux-clangdwarf] + + strategy: + fail-fast: false + matrix: + package: [ + {name: "ArmVirtQemu", archs: "ARM,AARCH64", toolchain: "GCC5", targets: "RELEASE,DEBUG,NOOPT"}, + {name: "ArmVirtQemu", archs: "ARM,AARCH64", toolchain: "CLANGDWARF", targets: "RELEASE,DEBUG,NOOPT"}, + ] + steps: + - name: Checkout ocbuild repository + uses: actions/checkout@v4 + with: + repository: acidanthera/ocbuild + ref: master + path: ./ + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y python3 python3-pip libglib2.0-dev libfdt-dev libpixman-1-dev libepoxy-dev libcapstone-dev libsdl2-dev libnuma-dev libgtk-3-dev libvte-2.91-dev libbrlapi-dev libiscsi-dev libnfs-dev librbd-dev libxen-dev + python3 -m pip install -r requirements.txt + + - name: Downloading QEMU + uses: robinraju/release-downloader@v1.7 + with: + repository: "acidanthera/OcBinaryData" + tag: ${{ env.QEMU_VERSION_TAG }} + fileName: "qemu.tar.xz" + + - name: Installing QEMU and add to PATH + run: | + echo "${HOME}/qemu/bin" >> $GITHUB_PATH + tar -xJf ./qemu.tar.xz -C $HOME + + - name: Download a single artifact + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.package.toolchain }} Firmware ARM Artifacts + + - name: Unzip artifacts + run: unzip "$TOOLCHAIN"_fw_arm_artifacts.zip + env: + TOOLCHAIN: ${{ matrix.package.toolchain }} + + - name: Downloading Windows PE AARCH64 iso + uses: robinraju/release-downloader@v1.7 + with: + repository: "acidanthera/OcBinaryData" + tag: ${{ env.WINPE_VERSION_TAG }} + fileName: "winpe_AARCH64.iso" + + - name: Run TestConsole + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --fw-arch "$arch" + done + done + env: + PACKAGE: ${{ matrix.package.name }} + ARCHS: ${{ matrix.package.archs }} + TARGETS: ${{ matrix.package.targets }} + TOOLCHAIN: ${{ matrix.package.toolchain }} + + - name: Run TestLinux + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --test-linux --fw-arch "$arch" + done + done + env: + PACKAGE: ${{ matrix.package.name }} + ARCHS: ${{ matrix.package.archs }} + TARGETS: ${{ matrix.package.targets }} + TOOLCHAIN: ${{ matrix.package.toolchain }} + + - name: Run Windows PE aarch64 + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + echo Checking "$PACKAGE"AARCH64 "$target"_"$TOOLCHAIN" + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/AARCH64/"$target"_"$TOOLCHAIN"/FW.fd --fw-arch AARCH64 --test-winpe --test-winpe-path ./winpe_AARCH64.iso + done + env: + PACKAGE: ${{ matrix.package.name }} + TARGETS: ${{ matrix.package.targets }} + TOOLCHAIN: ${{ matrix.package.toolchain }} diff --git a/.github/workflows/build_common.yml b/.github/workflows/build_common.yml new file mode 100644 index 0000000000..6762225eda --- /dev/null +++ b/.github/workflows/build_common.yml @@ -0,0 +1,676 @@ +name: Build Common packages + +on: + push: + pull_request: + workflow_dispatch: + release: + types: [published] + +env: + PROJECT_TYPE: UEFI + FORCE_INSTALL: 1 + WERROR: 1 + +jobs: + build-macos: + name: macOS XCODE5 + runs-on: macos-latest + env: + JOB_TYPE: BUILD + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Add Linux Toolchain + run: brew tap FiloSottile/homebrew-musl-cross + + - name: Install Linux Toolchain + run: brew install musl-cross + env: + HOMEBREW_NO_INSTALL_CLEANUP: 1 + HOMEBREW_NO_AUTO_UPDATE: 1 + + - name: Install Dependencies + run: brew install openssl mingw-w64 + env: + HOMEBREW_NO_INSTALL_CLEANUP: 1 + HOMEBREW_NO_AUTO_UPDATE: 1 + + - name: CI Bootstrap + run: | + src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1 + touch UDK.ready + + - name: Prepare efibuild.sh + run: | + curl -o ./efibuild.sh https://raw.githubusercontent.com/acidanthera/ocbuild/master/efibuild.sh || exit 1 + chmod +x ./efibuild.sh + ln -s `pwd` UDK + + - name: Build BaseTools + run: ./efibuild.sh + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build Ext4Pkg + run: ./efibuild.sh + env: + SELFPKG: Ext4Pkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build FatPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: FatPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build IntelFsp2Pkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: IntelFsp2Pkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build IntelFsp2WrapperPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: IntelFsp2WrapperPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build MdeModulePkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: MdeModulePkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build MdePkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: MdePkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiCpuPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: UefiCpuPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UnitTestFrameworkPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: UnitTestFrameworkPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build NetworkPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: NetworkPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build SecurityPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: SecurityPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + build-windows: + name: Windows VS2019 + runs-on: windows-latest + env: + CC: gcc + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Dependencies + run: | + choco install make nasm zip iasl --no-progress + + - name: CI Bootstrap + run: | + src=$(curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1 + touch UDK.ready + + - name: Prepare efibuild.sh + run: | + curl -o ./efibuild.sh https://raw.githubusercontent.com/acidanthera/ocbuild/master/efibuild.sh || exit 1 + chmod +x ./efibuild.sh + cmd <<< "mklink /D .\\UDK .\\" > /dev/null + + - name: Build BaseTools + run: ./efibuild.sh + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build Ext4Pkg + run: ./efibuild.sh + env: + SELFPKG: Ext4Pkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build FatPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: FatPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build IntelFsp2Pkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: IntelFsp2Pkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build IntelFsp2WrapperPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: IntelFsp2WrapperPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build MdeModulePkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: MdeModulePkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build MdePkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: MdePkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiCpuPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: UefiCpuPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UnitTestFrameworkPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: UnitTestFrameworkPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build NetworkPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: NetworkPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build SecurityPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: SecurityPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + build-linux-clangpdb: + name: Linux CLANGPDB + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Use Docker in rootless mode. + uses: ScribeMD/rootless-docker@0.2.2 + + - name: Build BaseTools + run: docker compose run build-package + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build Ext4Pkg + run: docker compose run build-package + env: + SELFPKG: Ext4Pkg + SELFPKG_DIR: Ext4Pkg + TOOLCHAINS: CLANGPDB + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build FatPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: FatPkg + SELFPKG_DIR: FatPkg + TOOLCHAINS: CLANGPDB + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build IntelFsp2Pkg + if: always() + run: docker compose run build-package + env: + SELFPKG: IntelFsp2Pkg + SELFPKG_DIR: IntelFsp2Pkg + TOOLCHAINS: CLANGPDB + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build IntelFsp2WrapperPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: IntelFsp2WrapperPkg + SELFPKG_DIR: IntelFsp2WrapperPkg + TOOLCHAINS: CLANGPDB + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build MdeModulePkg + if: always() + run: docker compose run build-package + env: + SELFPKG: MdeModulePkg + SELFPKG_DIR: MdeModulePkg + TOOLCHAINS: CLANGPDB + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build MdePkg + if: always() + run: docker compose run build-package + env: + SELFPKG: MdePkg + SELFPKG_DIR: MdePkg + TOOLCHAINS: CLANGPDB + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiCpuPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: UefiCpuPkg + SELFPKG_DIR: UefiCpuPkg + TOOLCHAINS: CLANGPDB + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UnitTestFrameworkPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: UnitTestFrameworkPkg + SELFPKG_DIR: UnitTestFrameworkPkg + TOOLCHAINS: CLANGPDB + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build NetworkPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: NetworkPkg + SELFPKG_DIR: NetworkPkg + TOOLCHAINS: CLANGPDB + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build SecurityPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: SecurityPkg + SELFPKG_DIR: SecurityPkg + TOOLCHAINS: CLANGPDB + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + build-linux-clangdwarf: + name: Linux CLANGDWARF + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Use Docker in rootless mode. + uses: ScribeMD/rootless-docker@0.2.2 + + - name: Build BaseTools + run: docker compose run build-package + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build Ext4Pkg + run: docker compose run build-package + env: + SELFPKG: Ext4Pkg + SELFPKG_DIR: Ext4Pkg + TOOLCHAINS: CLANGDWARF + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build FatPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: FatPkg + SELFPKG_DIR: FatPkg + TOOLCHAINS: CLANGDWARF + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build IntelFsp2Pkg + if: always() + run: docker compose run build-package + env: + SELFPKG: IntelFsp2Pkg + SELFPKG_DIR: IntelFsp2Pkg + TOOLCHAINS: CLANGDWARF + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build IntelFsp2WrapperPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: IntelFsp2WrapperPkg + SELFPKG_DIR: IntelFsp2WrapperPkg + TOOLCHAINS: CLANGDWARF + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build MdeModulePkg + if: always() + run: docker compose run build-package + env: + SELFPKG: MdeModulePkg + SELFPKG_DIR: MdeModulePkg + TOOLCHAINS: CLANGDWARF + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build MdePkg + if: always() + run: docker compose run build-package + env: + SELFPKG: MdePkg + SELFPKG_DIR: MdePkg + TOOLCHAINS: CLANGDWARF + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiCpuPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: UefiCpuPkg + SELFPKG_DIR: UefiCpuPkg + TOOLCHAINS: CLANGDWARF + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UnitTestFrameworkPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: UnitTestFrameworkPkg + SELFPKG_DIR: UnitTestFrameworkPkg + TOOLCHAINS: CLANGDWARF + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build NetworkPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: NetworkPkg + SELFPKG_DIR: NetworkPkg + TOOLCHAINS: CLANGDWARF + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build SecurityPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: SecurityPkg + SELFPKG_DIR: SecurityPkg + TOOLCHAINS: CLANGDWARF + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + build-linux-gcc5: + name: Linux GCC5 + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Use Docker in rootless mode. + uses: ScribeMD/rootless-docker@0.2.2 + + - name: Build BaseTools + run: docker compose run build-package + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build Ext4Pkg + run: docker compose run build-package + env: + SELFPKG: Ext4Pkg + SELFPKG_DIR: Ext4Pkg + TOOLCHAINS: GCC5 + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build FatPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: FatPkg + SELFPKG_DIR: FatPkg + TOOLCHAINS: GCC5 + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build IntelFsp2Pkg + if: always() + run: docker compose run build-package + env: + SELFPKG: IntelFsp2Pkg + SELFPKG_DIR: IntelFsp2Pkg + TOOLCHAINS: GCC5 + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build IntelFsp2WrapperPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: IntelFsp2WrapperPkg + SELFPKG_DIR: IntelFsp2WrapperPkg + TOOLCHAINS: GCC5 + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build MdeModulePkg + if: always() + run: docker compose run build-package + env: + SELFPKG: MdeModulePkg + SELFPKG_DIR: MdeModulePkg + TOOLCHAINS: GCC5 + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build MdePkg + if: always() + run: docker compose run build-package + env: + SELFPKG: MdePkg + SELFPKG_DIR: MdePkg + TOOLCHAINS: GCC5 + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiCpuPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: UefiCpuPkg + SELFPKG_DIR: UefiCpuPkg + TOOLCHAINS: GCC5 + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UnitTestFrameworkPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: UnitTestFrameworkPkg + SELFPKG_DIR: UnitTestFrameworkPkg + TOOLCHAINS: GCC5 + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build NetworkPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: NetworkPkg + SELFPKG_DIR: NetworkPkg + TOOLCHAINS: GCC5 + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build SecurityPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: SecurityPkg + SELFPKG_DIR: SecurityPkg + TOOLCHAINS: GCC + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 diff --git a/.github/workflows/build_nolto.yaml b/.github/workflows/build_nolto.yaml new file mode 100644 index 0000000000..ad48934a31 --- /dev/null +++ b/.github/workflows/build_nolto.yaml @@ -0,0 +1,577 @@ +name: Build Firmwares using GCC without Link Time Optimization + +on: + push: + pull_request: + workflow_dispatch: + release: + types: [published] + +env: + PROJECT_TYPE: UEFI + FORCE_INSTALL: 1 + WERROR: 1 + QEMU_VERSION_TAG: qemu-ci-8.1.5-r1 + WINPE_VERSION_TAG: images-winpe-1.0 + +jobs: + build-linux-arm: + name: Linux GCC ARM + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get install -y lsb-release wget software-properties-common gnupg build-essential nasm uuid-dev libssl-dev iasl curl git zip gcc-arm-linux-gnueabi gcc-aarch64-linux-gnu + + - name: CI Bootstrap + run: | + src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1 + touch UDK.ready + + - name: Prepare efibuild.sh + run: | + curl -o ./efibuild.sh https://raw.githubusercontent.com/acidanthera/ocbuild/master/efibuild.sh || exit 1 + chmod +x ./efibuild.sh + ln -s `pwd` UDK + + - name: Build BaseTools + run: ./efibuild.sh + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build ArmPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: ArmPkg + SELFPKG_DIR: ArmPkg + TOOLCHAINS: GCC + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + GCC_ARM_PREFIX: arm-linux-gnueabi- + GCC_AARCH64_PREFIX: aarch64-linux-gnu- + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Build ArmPlatformPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: ArmPlatformPkg + SELFPKG_DIR: ArmPlatformPkg + TOOLCHAINS: GCC + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + GCC_ARM_PREFIX: arm-linux-gnueabi- + GCC_AARCH64_PREFIX: aarch64-linux-gnu- + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Build ArmVirtQemu + if: always() + run: ./efibuild.sh + env: + SELFPKG: ArmVirtQemu + SELFPKG_DIR: ArmVirtPkg + TOOLCHAINS: GCC + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + GCC_ARM_PREFIX: arm-linux-gnueabi- + GCC_AARCH64_PREFIX: aarch64-linux-gnu- + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Prepare artifacts with firmwares + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + mkdir -p ./firmware_artifacts/ArmVirtQemu/"$arch"/"$target"_"$TOOLCHAIN" + cp ./Build/ArmVirtQemu-"$arch"/"$target"_"$TOOLCHAIN"/FV/QEMU_EFI.fd ./firmware_artifacts/ArmVirtQemu/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done + env: + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG + TOOLCHAIN: GCC + + - name: Zip artifacts + run: zip GCC_no_lto_artifacts.zip ./firmware_artifacts/* -r + + - name: Upload to Artifacts + uses: actions/upload-artifact@v4 + with: + name: GCC Firmware NO_LTO Artifacts + path: GCC_no_lto_artifacts.zip + + build-linux-amd: + name: Linux GCC AMD + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Use Docker in rootless mode. + uses: ScribeMD/rootless-docker@0.2.2 + + - name: Build BaseTools + run: docker compose run build-package + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build OvmfPkgIa32 + if: always() + run: docker compose run build-package + env: + SELFPKG: OvmfPkgIa32 + SELFPKG_DIR: OvmfPkg + TOOLCHAINS: GCC + ARCHS: IA32 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D WINDOWS_10_IA32 -D EDK2_GCC_NOLTO + + - name: Build OvmfPkgX64 + if: always() + run: docker compose run build-package + env: + SELFPKG: OvmfPkgX64 + SELFPKG_DIR: OvmfPkg + TOOLCHAINS: GCC + ARCHS: X64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Build OvmfPkgIa32X64 + if: always() + run: docker compose run build-package + env: + SELFPKG: OvmfPkgIa32X64 + SELFPKG_DIR: OvmfPkg + TOOLCHAINS: GCC + ARCHS: X64 + ARCHS_EXT: IA32 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Build UefiPayloadPkg with X64 PEI/DXE + if: always() + run: docker compose run build-package + env: + SELFPKG: UefiPayloadPkg + SELFPKG_DIR: UefiPayloadPkg + TOOLCHAINS: GCC + ARCHS: X64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Build UefiPayloadPkg with Ia32 PEI and X64 DXE + if: always() + run: docker compose run build-package + env: + SELFPKG: UefiPayloadPkg + SELFPKG_DIR: UefiPayloadPkg + TOOLCHAINS: GCC + ARCHS: X64 + ARCHS_EXT: IA32 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Prepare artifacts with firmwares + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + mkdir -p ./firmware_artifacts/Ovmf/"$arch"/"$target"_"$TOOLCHAIN" + cp ./Build/Ovmf"$arch"/"$target"_"$TOOLCHAIN"/FV/OVMF.fd ./firmware_artifacts/Ovmf/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done + env: + ARCHS: Ia32,X64,3264 + TARGETS: RELEASE,DEBUG + TOOLCHAIN: GCC + + - name: Zip artifacts + run: zip GCC_fw_artifacts.zip ./firmware_artifacts/* -r + + - name: Upload to Artifacts + uses: actions/upload-artifact@v4 + with: + name: GCC Firmware Artifacts + path: GCC_fw_artifacts.zip + + build-linux-common: + name: Linux GCC Common + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Use Docker in rootless mode. + uses: ScribeMD/rootless-docker@0.2.2 + + - name: Build BaseTools + run: docker compose run build-package + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build Ext4Pkg + run: docker compose run build-package + env: + SELFPKG: Ext4Pkg + SELFPKG_DIR: Ext4Pkg + TOOLCHAINS: GCC + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Build FatPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: FatPkg + SELFPKG_DIR: FatPkg + TOOLCHAINS: GCC + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Build IntelFsp2Pkg + if: always() + run: docker compose run build-package + env: + SELFPKG: IntelFsp2Pkg + SELFPKG_DIR: IntelFsp2Pkg + TOOLCHAINS: GCC + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Build IntelFsp2WrapperPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: IntelFsp2WrapperPkg + SELFPKG_DIR: IntelFsp2WrapperPkg + TOOLCHAINS: GCC + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Build MdeModulePkg + if: always() + run: docker compose run build-package + env: + SELFPKG: MdeModulePkg + SELFPKG_DIR: MdeModulePkg + TOOLCHAINS: GCC + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Build MdePkg + if: always() + run: docker compose run build-package + env: + SELFPKG: MdePkg + SELFPKG_DIR: MdePkg + TOOLCHAINS: GCC + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Build UefiCpuPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: UefiCpuPkg + SELFPKG_DIR: UefiCpuPkg + TOOLCHAINS: GCC + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Build UnitTestFrameworkPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: UnitTestFrameworkPkg + SELFPKG_DIR: UnitTestFrameworkPkg + TOOLCHAINS: GCC + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + - name: Build NetworkPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: NetworkPkg + SELFPKG_DIR: NetworkPkg + TOOLCHAINS: GCC + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO + + test-arm: + name: Test ARM + runs-on: ubuntu-22.04 + needs: [build-linux-arm] + + strategy: + fail-fast: false + matrix: + package: [ + {name: "ArmVirtQemu", archs: "ARM,AARCH64", toolchain: "GCC", targets: "RELEASE,DEBUG"}, + ] + steps: + - name: Checkout ocbuild repository + uses: actions/checkout@v4 + with: + repository: acidanthera/ocbuild + ref: master + path: ./ + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y python3 python3-pip libglib2.0-dev libfdt-dev libpixman-1-dev libepoxy-dev libcapstone-dev libsdl2-dev libnuma-dev libgtk-3-dev libvte-2.91-dev libbrlapi-dev libiscsi-dev libnfs-dev librbd-dev libxen-dev + python3 -m pip install -r requirements.txt + + - name: Downloading QEMU + uses: robinraju/release-downloader@v1.7 + with: + repository: "acidanthera/OcBinaryData" + tag: ${{ env.QEMU_VERSION_TAG }} + fileName: "qemu.tar.xz" + + - name: Installing QEMU and add to PATH + run: | + echo "${HOME}/qemu/bin" >> $GITHUB_PATH + tar -xJf ./qemu.tar.xz -C $HOME + + - name: Download a single artifact + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.package.toolchain }} Firmware NO_LTO Artifacts + + - name: Unzip artifacts + run: unzip "$TOOLCHAIN"_no_lto_artifacts.zip + env: + TOOLCHAIN: ${{ matrix.package.toolchain }} + + - name: Downloading Windows PE AARCH64 iso + uses: robinraju/release-downloader@v1.7 + with: + repository: "acidanthera/OcBinaryData" + tag: ${{ env.WINPE_VERSION_TAG }} + fileName: "winpe_AARCH64.iso" + + - name: Run TestConsole + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --fw-arch "$arch" + done + done + env: + PACKAGE: ${{ matrix.package.name }} + ARCHS: ${{ matrix.package.archs }} + TARGETS: ${{ matrix.package.targets }} + TOOLCHAIN: ${{ matrix.package.toolchain }} + + - name: Run TestLinux + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --test-linux --fw-arch "$arch" + done + done + env: + PACKAGE: ${{ matrix.package.name }} + ARCHS: ${{ matrix.package.archs }} + TARGETS: ${{ matrix.package.targets }} + TOOLCHAIN: ${{ matrix.package.toolchain }} + + - name: Run Windows PE aarch64 + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + echo Checking "$PACKAGE"AARCH64 "$target"_"$TOOLCHAIN" + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/AARCH64/"$target"_"$TOOLCHAIN"/FW.fd --fw-arch AARCH64 --test-winpe --test-winpe-path ./winpe_AARCH64.iso + done + env: + PACKAGE: ${{ matrix.package.name }} + TARGETS: ${{ matrix.package.targets }} + TOOLCHAIN: ${{ matrix.package.toolchain }} + + test-amd: + name: Test AMD + runs-on: ubuntu-22.04 + needs: [build-linux-amd] + + strategy: + fail-fast: false + matrix: + package: [ + {name: "Ovmf", archs: "Ia32,X64,3264", toolchain: "GCC", targets: "RELEASE,DEBUG"}, + ] + steps: + - name: Checkout ocbuild repository + uses: actions/checkout@v4 + with: + repository: acidanthera/ocbuild + ref: master + path: ./ + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y python3 python3-pip libglib2.0-dev libfdt-dev libpixman-1-dev libepoxy-dev libcapstone-dev libsdl2-dev libnuma-dev libgtk-3-dev libvte-2.91-dev libbrlapi-dev libiscsi-dev libnfs-dev librbd-dev libxen-dev + python3 -m pip install -r requirements.txt + + - name: Downloading QEMU + uses: robinraju/release-downloader@v1.7 + with: + repository: "acidanthera/OcBinaryData" + tag: ${{ env.QEMU_VERSION_TAG }} + fileName: "qemu.tar.xz" + + - name: Installing QEMU and add to PATH + run: | + echo "${HOME}/qemu/bin" >> $GITHUB_PATH + tar -xJf ./qemu.tar.xz -C $HOME + + - name: Download a single artifact + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.package.toolchain }} Firmware Artifacts + + - name: Unzip artifacts + run: unzip "$TOOLCHAIN"_fw_artifacts.zip + env: + TOOLCHAIN: ${{ matrix.package.toolchain }} + + - name: Downloading Windows PE X64 iso + uses: robinraju/release-downloader@v1.7 + with: + repository: "acidanthera/OcBinaryData" + tag: ${{ env.WINPE_VERSION_TAG }} + fileName: "winpe_X64.iso" + + - name: Downloading Windows PE IA32 iso + uses: robinraju/release-downloader@v1.7 + with: + repository: "acidanthera/OcBinaryData" + tag: ${{ env.WINPE_VERSION_TAG }} + fileName: "winpe_IA32.iso" + + - name: Run TestConsole + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done + env: + PACKAGE: ${{ matrix.package.name }} + ARCHS: ${{ matrix.package.archs }} + TARGETS: ${{ matrix.package.targets }} + TOOLCHAIN: ${{ matrix.package.toolchain }} + + - name: Run TestLinux + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --test-linux + done + done + env: + PACKAGE: ${{ matrix.package.name }} + ARCHS: ${{ matrix.package.archs }} + TARGETS: ${{ matrix.package.targets }} + TOOLCHAIN: ${{ matrix.package.toolchain }} + + - name: Run Windows PE + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + if [ "$arch" = "Ia32" ]; then + WINPE_FILENAME=winpe_IA32.iso + elif [ "$arch" = "X64" ] || [ "$arch" = "3264" ]; then + WINPE_FILENAME=winpe_X64.iso + fi + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --test-winpe --test-winpe-path "$WINPE_FILENAME" + done + done + env: + PACKAGE: ${{ matrix.package.name }} + ARCHS: ${{ matrix.package.archs }} + TARGETS: ${{ matrix.package.targets }} + TOOLCHAIN: ${{ matrix.package.toolchain }} diff --git a/.github/workflows/build_x86.yaml b/.github/workflows/build_x86.yaml new file mode 100644 index 0000000000..c7d72fbf40 --- /dev/null +++ b/.github/workflows/build_x86.yaml @@ -0,0 +1,680 @@ +name: Build X86 Firmwares + +on: + push: + pull_request: + workflow_dispatch: + release: + types: [published] + +env: + PROJECT_TYPE: UEFI + FORCE_INSTALL: 1 + WERROR: 1 + QEMU_VERSION_TAG: qemu-ci-8.1.5-r1 + WINPE_VERSION_TAG: images-winpe-1.0 + +jobs: + build-macos: + name: macOS XCODE5 + runs-on: macos-latest + env: + JOB_TYPE: BUILD + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Add Linux Toolchain + run: brew tap FiloSottile/homebrew-musl-cross + + - name: Install Linux Toolchain + run: brew install musl-cross + env: + HOMEBREW_NO_INSTALL_CLEANUP: 1 + HOMEBREW_NO_AUTO_UPDATE: 1 + + - name: Install Dependencies + run: brew install openssl mingw-w64 + env: + HOMEBREW_NO_INSTALL_CLEANUP: 1 + HOMEBREW_NO_AUTO_UPDATE: 1 + + - name: CI Bootstrap + run: | + src=$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1 + touch UDK.ready + + - name: Prepare efibuild.sh + run: | + curl -o ./efibuild.sh https://raw.githubusercontent.com/acidanthera/ocbuild/master/efibuild.sh || exit 1 + chmod +x ./efibuild.sh + ln -s `pwd` UDK + + - name: Build BaseTools + run: ./efibuild.sh + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build OvmfPkgIa32 + if: always() + run: ./efibuild.sh + env: + SELFPKG: OvmfPkgIa32 + SELFPKG_DIR: OvmfPkg + ARCHS: IA32 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D WINDOWS_10_IA32 + + - name: Build OvmfPkgX64 + if: always() + run: ./efibuild.sh + env: + SELFPKG: OvmfPkgX64 + SELFPKG_DIR: OvmfPkg + ARCHS: X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build OvmfPkgIa32X64 + if: always() + run: ./efibuild.sh + env: + SELFPKG: OvmfPkgIa32X64 + SELFPKG_DIR: OvmfPkg + ARCHS: X64 + ARCHS_EXT: IA32 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiPayloadPkg with X64 PEI/DXE + if: always() + run: ./efibuild.sh + env: + SELFPKG: UefiPayloadPkg + ARCHS: X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiPayloadPkg with Ia32 PEI and X64 DXE + if: always() + run: ./efibuild.sh + env: + SELFPKG: UefiPayloadPkg + ARCHS: X64 + ARCHS_EXT: IA32 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Prepare artifacts with firmwares + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + mkdir -p ./firmware_artifacts/Ovmf/"$arch"/"$target"_"$TOOLCHAIN" + cp ./Build/Ovmf"$arch"/"$target"_"$TOOLCHAIN"/FV/OVMF.fd ./firmware_artifacts/Ovmf/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done + env: + ARCHS: Ia32,X64,3264 + TARGETS: RELEASE,DEBUG,NOOPT + TOOLCHAIN: XCODE5 + + - name: Zip artifacts + run: zip XCODE5_fw_artifacts.zip ./firmware_artifacts/* -r + + - name: Upload to Artifacts + uses: actions/upload-artifact@v4 + with: + name: XCODE5 Firmware Artifacts + path: XCODE5_fw_artifacts.zip + + build-windows: + name: Windows VS2019 + runs-on: windows-latest + env: + CC: gcc + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Dependencies + run: | + choco install make nasm zip iasl --no-progress + + - name: CI Bootstrap + run: | + src=$(curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh) && eval "$src" || exit 1 + touch UDK.ready + + - name: Prepare efibuild.sh + run: | + curl -o ./efibuild.sh https://raw.githubusercontent.com/acidanthera/ocbuild/master/efibuild.sh || exit 1 + chmod +x ./efibuild.sh + cmd <<< "mklink /D .\\UDK .\\" > /dev/null + + - name: Build BaseTools + run: ./efibuild.sh + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build OvmfPkgIa32 + if: always() + run: ./efibuild.sh + env: + SELFPKG: OvmfPkgIa32 + SELFPKG_DIR: OvmfPkg + ARCHS: IA32 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D WINDOWS_10_IA32 + + - name: Build OvmfPkgX64 + if: always() + run: ./efibuild.sh + env: + SELFPKG: OvmfPkgX64 + SELFPKG_DIR: OvmfPkg + ARCHS: X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build OvmfPkgIa32X64 + if: always() + run: ./efibuild.sh + env: + SELFPKG: OvmfPkgIa32X64 + SELFPKG_DIR: OvmfPkg + ARCHS: X64 + ARCHS_EXT: IA32 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiPayloadPkg with X64 PEI/DXE + if: always() + run: ./efibuild.sh + env: + SELFPKG: UefiPayloadPkg + ARCHS: X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiPayloadPkg with Ia32 PEI and X64 DXE + if: always() + run: ./efibuild.sh + env: + SELFPKG: UefiPayloadPkg + ARCHS: X64 + ARCHS_EXT: IA32 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Prepare artifacts with firmwares + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + mkdir -p ./firmware_artifacts/Ovmf/"$arch"/"$target"_"$TOOLCHAIN" + cp ./Build/Ovmf"$arch"/"$target"_"$TOOLCHAIN"/FV/OVMF.fd ./firmware_artifacts/Ovmf/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done + env: + ARCHS: Ia32,X64,3264 + TARGETS: RELEASE,DEBUG,NOOPT + TOOLCHAIN: VS2019 + + - name: Zip artifacts + run: zip VS2019_fw_artifacts.zip ./firmware_artifacts/* -r + + - name: Upload to Artifacts + uses: actions/upload-artifact@v4 + with: + name: VS2019 Firmware Artifacts + path: VS2019_fw_artifacts.zip + + build-linux-clangpdb: + name: Linux CLANGPDB + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Use Docker in rootless mode. + uses: ScribeMD/rootless-docker@0.2.2 + + - name: Build BaseTools + run: docker compose run build-package + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build OvmfPkgIa32 + if: always() + run: docker compose run build-package + env: + SELFPKG: OvmfPkgIa32 + SELFPKG_DIR: OvmfPkg + TOOLCHAINS: CLANGPDB + ARCHS: IA32 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D WINDOWS_10_IA32 + + - name: Build OvmfPkgX64 + if: always() + run: docker compose run build-package + env: + SELFPKG: OvmfPkgX64 + SELFPKG_DIR: OvmfPkg + TOOLCHAINS: CLANGPDB + ARCHS: X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build OvmfPkgIa32X64 + if: always() + run: docker compose run build-package + env: + SELFPKG: OvmfPkgIa32X64 + SELFPKG_DIR: OvmfPkg + TOOLCHAINS: CLANGPDB + ARCHS: X64 + ARCHS_EXT: IA32 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiPayloadPkg with X64 PEI/DXE + if: always() + run: docker compose run build-package + env: + SELFPKG: UefiPayloadPkg + SELFPKG_DIR: UefiPayloadPkg + TOOLCHAINS: CLANGPDB + ARCHS: X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiPayloadPkg with Ia32 PEI and X64 DXE + if: always() + run: docker compose run build-package + env: + SELFPKG: UefiPayloadPkg + SELFPKG_DIR: UefiPayloadPkg + TOOLCHAINS: CLANGPDB + ARCHS: X64 + ARCHS_EXT: IA32 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Prepare artifacts with firmwares + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + mkdir -p ./firmware_artifacts/Ovmf/"$arch"/"$target"_"$TOOLCHAIN" + cp ./Build/Ovmf"$arch"/"$target"_"$TOOLCHAIN"/FV/OVMF.fd ./firmware_artifacts/Ovmf/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done + env: + ARCHS: Ia32,X64,3264 + TARGETS: RELEASE,DEBUG,NOOPT + TOOLCHAIN: CLANGPDB + + - name: Zip artifacts + run: zip CLANGPDB_fw_artifacts.zip ./firmware_artifacts/* -r + + - name: Upload to Artifacts + uses: actions/upload-artifact@v4 + with: + name: CLANGPDB Firmware Artifacts + path: CLANGPDB_fw_artifacts.zip + + build-linux-clangdwarf: + name: Linux CLANGDWARF + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Use Docker in rootless mode. + uses: ScribeMD/rootless-docker@0.2.2 + + - name: Build BaseTools + run: docker compose run build-package + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build OvmfPkgIa32 + if: always() + run: docker compose run build-package + env: + SELFPKG: OvmfPkgIa32 + SELFPKG_DIR: OvmfPkg + TOOLCHAINS: CLANGDWARF + ARCHS: IA32 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D WINDOWS_10_IA32 + + - name: Build OvmfPkgX64 + if: always() + run: docker compose run build-package + env: + SELFPKG: OvmfPkgX64 + SELFPKG_DIR: OvmfPkg + TOOLCHAINS: CLANGDWARF + ARCHS: X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build OvmfPkgIa32X64 + if: always() + run: docker compose run build-package + env: + SELFPKG: OvmfPkgIa32X64 + SELFPKG_DIR: OvmfPkg + TOOLCHAINS: CLANGDWARF + ARCHS: X64 + ARCHS_EXT: IA32 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiPayloadPkg with X64 PEI/DXE + if: always() + run: docker compose run build-package + env: + SELFPKG: UefiPayloadPkg + SELFPKG_DIR: UefiPayloadPkg + TOOLCHAINS: CLANGDWARF + ARCHS: X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiPayloadPkg with Ia32 PEI and X64 DXE + if: always() + run: docker compose run build-package + env: + SELFPKG: UefiPayloadPkg + SELFPKG_DIR: UefiPayloadPkg + TOOLCHAINS: CLANGDWARF + ARCHS: X64 + ARCHS_EXT: IA32 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Prepare artifacts with firmwares + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + mkdir -p ./firmware_artifacts/Ovmf/"$arch"/"$target"_"$TOOLCHAIN" + cp ./Build/Ovmf"$arch"/"$target"_"$TOOLCHAIN"/FV/OVMF.fd ./firmware_artifacts/Ovmf/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done + env: + ARCHS: Ia32,X64,3264 + TARGETS: RELEASE,DEBUG,NOOPT + TOOLCHAIN: CLANGDWARF + + - name: Zip artifacts + run: zip CLANGDWARF_fw_artifacts.zip ./firmware_artifacts/* -r + + - name: Upload to Artifacts + uses: actions/upload-artifact@v4 + with: + name: CLANGDWARF Firmware Artifacts + path: CLANGDWARF_fw_artifacts.zip + + build-linux-gcc5: + name: Linux GCC5 + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Use Docker in rootless mode. + uses: ScribeMD/rootless-docker@0.2.2 + + - name: Build BaseTools + run: docker compose run build-package + env: + SELFPKG: MdePkg + SKIP_BUILD: 1 + + - name: Build OvmfPkgIa32 + if: always() + run: docker compose run build-package + env: + SELFPKG: OvmfPkgIa32 + SELFPKG_DIR: OvmfPkg + TOOLCHAINS: GCC5 + ARCHS: IA32 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D WINDOWS_10_IA32 + + - name: Build OvmfPkgX64 + if: always() + run: docker compose run build-package + env: + SELFPKG: OvmfPkgX64 + SELFPKG_DIR: OvmfPkg + TOOLCHAINS: GCC5 + ARCHS: X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build OvmfPkgIa32X64 + if: always() + run: docker compose run build-package + env: + SELFPKG: OvmfPkgIa32X64 + SELFPKG_DIR: OvmfPkg + TOOLCHAINS: GCC5 + ARCHS: X64 + ARCHS_EXT: IA32 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiPayloadPkg with X64 PEI/DXE + if: always() + run: docker compose run build-package + env: + SELFPKG: UefiPayloadPkg + SELFPKG_DIR: UefiPayloadPkg + TOOLCHAINS: GCC5 + ARCHS: X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Build UefiPayloadPkg with Ia32 PEI and X64 DXE + if: always() + run: docker compose run build-package + env: + SELFPKG: UefiPayloadPkg + SELFPKG_DIR: UefiPayloadPkg + TOOLCHAINS: GCC5 + ARCHS: X64 + ARCHS_EXT: IA32 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + + - name: Prepare artifacts with firmwares + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + mkdir -p ./firmware_artifacts/Ovmf/"$arch"/"$target"_"$TOOLCHAIN" + cp ./Build/Ovmf"$arch"/"$target"_"$TOOLCHAIN"/FV/OVMF.fd ./firmware_artifacts/Ovmf/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done + env: + ARCHS: Ia32,X64,3264 + TARGETS: RELEASE,DEBUG,NOOPT + TOOLCHAIN: GCC5 + + - name: Zip artifacts + run: zip GCC5_fw_artifacts.zip ./firmware_artifacts/* -r + + - name: Upload to Artifacts + uses: actions/upload-artifact@v4 + with: + name: GCC5 Firmware Artifacts + path: GCC5_fw_artifacts.zip + + test-firmwares: + name: Test + runs-on: ubuntu-22.04 + needs: [build-macos, build-windows, build-linux-clangpdb, build-linux-clangdwarf, build-linux-gcc5] + + strategy: + fail-fast: false + matrix: + package: [ + {name: "Ovmf", archs: "Ia32,X64,3264", toolchain: "XCODE5", targets: "RELEASE,DEBUG,NOOPT"}, + {name: "Ovmf", archs: "Ia32,X64,3264", toolchain: "VS2019", targets: "RELEASE,DEBUG,NOOPT"}, + {name: "Ovmf", archs: "Ia32,X64,3264", toolchain: "CLANGPDB", targets: "RELEASE,DEBUG,NOOPT"}, + {name: "Ovmf", archs: "Ia32,X64,3264", toolchain: "CLANGDWARF", targets: "RELEASE,DEBUG,NOOPT"}, + {name: "Ovmf", archs: "Ia32,X64,3264", toolchain: "GCC5", targets: "RELEASE,DEBUG,NOOPT"}, + ] + steps: + - name: Checkout ocbuild repository + uses: actions/checkout@v4 + with: + repository: acidanthera/ocbuild + ref: master + path: ./ + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y python3 python3-pip libglib2.0-dev libfdt-dev libpixman-1-dev libepoxy-dev libcapstone-dev libsdl2-dev libnuma-dev libgtk-3-dev libvte-2.91-dev libbrlapi-dev libiscsi-dev libnfs-dev librbd-dev libxen-dev + python3 -m pip install -r requirements.txt + + - name: Downloading QEMU + uses: robinraju/release-downloader@v1.7 + with: + repository: "acidanthera/OcBinaryData" + tag: ${{ env.QEMU_VERSION_TAG }} + fileName: "qemu.tar.xz" + + - name: Installing QEMU and add to PATH + run: | + echo "${HOME}/qemu/bin" >> $GITHUB_PATH + tar -xJf ./qemu.tar.xz -C $HOME + + - name: Download a single artifact + uses: actions/download-artifact@v4 + with: + name: ${{ matrix.package.toolchain }} Firmware Artifacts + + - name: Unzip artifacts + run: unzip "$TOOLCHAIN"_fw_artifacts.zip + env: + TOOLCHAIN: ${{ matrix.package.toolchain }} + + - name: Downloading Windows PE X64 iso + uses: robinraju/release-downloader@v1.7 + with: + repository: "acidanthera/OcBinaryData" + tag: ${{ env.WINPE_VERSION_TAG }} + fileName: "winpe_X64.iso" + + - name: Downloading Windows PE IA32 iso + uses: robinraju/release-downloader@v1.7 + with: + repository: "acidanthera/OcBinaryData" + tag: ${{ env.WINPE_VERSION_TAG }} + fileName: "winpe_IA32.iso" + + - name: Run TestConsole + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done + env: + PACKAGE: ${{ matrix.package.name }} + ARCHS: ${{ matrix.package.archs }} + TARGETS: ${{ matrix.package.targets }} + TOOLCHAIN: ${{ matrix.package.toolchain }} + + - name: Run TestLinux + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --test-linux + done + done + env: + PACKAGE: ${{ matrix.package.name }} + ARCHS: ${{ matrix.package.archs }} + TARGETS: ${{ matrix.package.targets }} + TOOLCHAIN: ${{ matrix.package.toolchain }} + + - name: Run Windows PE + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + if [ "$arch" = "Ia32" ]; then + WINPE_FILENAME=winpe_IA32.iso + elif [ "$arch" = "X64" ] || [ "$arch" = "3264" ]; then + WINPE_FILENAME=winpe_X64.iso + fi + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --test-winpe --test-winpe-path "$WINPE_FILENAME" + done + done + env: + PACKAGE: ${{ matrix.package.name }} + ARCHS: ${{ matrix.package.archs }} + TARGETS: ${{ matrix.package.targets }} + TOOLCHAIN: ${{ matrix.package.toolchain }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c22fa8dd61..017b827647 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -35,41 +35,27 @@ jobs: fail-fast: false matrix: include: - - Package: "CryptoPkg" - ArchList: "IA32" - - Package: "CryptoPkg" - ArchList: "X64" - - Package: "DynamicTablesPkg" + - Package: "Ext4Pkg" ArchList: "IA32,X64" - Package: "FatPkg" ArchList: "IA32,X64" - - Package: "FmpDevicePkg" - ArchList: "IA32,X64" - Package: "IntelFsp2Pkg" ArchList: "IA32,X64" - Package: "IntelFsp2WrapperPkg" ArchList: "IA32,X64" - Package: "MdeModulePkg" - ArchList: "IA32" - - Package: "MdeModulePkg" - ArchList: "X64" - - Package: "MdePkg" - ArchList: "IA32,X64" - - Package: "PcAtChipsetPkg" - ArchList: "IA32,X64" - - Package: "PrmPkg" ArchList: "IA32,X64" - - Package: "SecurityPkg" + - Package: "MdePkg" ArchList: "IA32,X64" - - Package: "ShellPkg" + - Package: "UefiCpuPkg" ArchList: "IA32,X64" - - Package: "SourceLevelDebugPkg" + - Package: "UnitTestFrameworkPkg" ArchList: "IA32,X64" - - Package: "StandaloneMmPkg" + - Package: "OvmfPkg" ArchList: "IA32,X64" - - Package: "UefiCpuPkg" + - Package: "UefiPayloadPkg" ArchList: "IA32,X64" - - Package: "UnitTestFrameworkPkg" + - Package: "NetworkPkg" ArchList: "IA32,X64" steps: @@ -267,7 +253,7 @@ jobs: - name: CI Build env: STUART_CODEQL_PATH: ${{ steps.cache_key_gen.outputs.codeql_cli_ext_dep_dir }} - run: stuart_ci_build -c .pytool/CISettings.py -t DEBUG -p ${{ matrix.Package }} -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2022 --codeql + run: stuart_ci_build -c .pytool/CISettings.py -t DEBUG -p ${{ matrix.Package }} -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2022 --codeql --npt - name: Build Cleanup id: build_cleanup diff --git a/.pytool/CISettings.py b/.pytool/CISettings.py index 46f61db284..e8fd8488b9 100644 --- a/.pytool/CISettings.py +++ b/.pytool/CISettings.py @@ -71,6 +71,7 @@ def GetPackagesSupported(self): "DynamicTablesPkg", "EmbeddedPkg", "EmulatorPkg", + "Ext4Pkg", "IntelFsp2Pkg", "IntelFsp2WrapperPkg", "MdePkg", @@ -210,6 +211,8 @@ def GetRequiredSubmodules(self): "CryptoPkg/Library/MbedTlsLib/mbedtls", False)) rs.append(RequiredSubmodule( "SecurityPkg/DeviceSecurity/SpdmLib/libspdm", False)) + rs.append(RequiredSubmodule( + "OpenCorePkg", False)) return rs def GetName(self): diff --git a/Ext4Pkg/Ext4Pkg.ci.yaml b/Ext4Pkg/Ext4Pkg.ci.yaml new file mode 100644 index 0000000000..81c7694c5f --- /dev/null +++ b/Ext4Pkg/Ext4Pkg.ci.yaml @@ -0,0 +1,65 @@ +## @file +# CI configuration for Ext4Pkg +# +# Copyright (c) Microsoft Corporation +# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## +{ + "LicenseCheck": { + "IgnoreFiles": [] + }, + "EccCheck": { + ## Exception sample looks like below: + ## "ExceptionList": [ + ## "", "" + ## ] + "ExceptionList": [ + ], + ## Both file path and directory path are accepted. + "IgnoreFiles": [ + ] + }, + "CompilerPlugin": { + "DscPath": "Ext4Pkg.dsc" + }, + "CharEncodingCheck": { + "IgnoreFiles": [] + }, + "DependencyCheck": { + "AcceptableDependencies": [ + "MdePkg/MdePkg.dec", + "MdeModulePkg/MdeModulePkg.dec", + ], + # For host based unit tests + "AcceptableDependencies-HOST_APPLICATION":[], + # For UEFI shell based apps + "AcceptableDependencies-UEFI_APPLICATION":[], + "IgnoreInf": [] + }, + "DscCompleteCheck": { + "IgnoreInf": [], + "DscPath": "Ext4Pkg.dsc" + }, + "GuidCheck": { + "IgnoreGuidName": [], + "IgnoreGuidValue": [], + "IgnoreFoldersAndFiles": [] + }, + "LibraryClassCheck": { + "IgnoreHeaderFile": [] + }, + "SpellCheck": { + "ExtendWords": [ + "ELTORITO", + "FHAND", + "IFILE", + "OFILE", + "FDISKed", + "Lfnbuffer", + "FFFFFFFFL", + "CDVOL", + "DMDEPKG" + ] + } +} diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100755 index 0000000000..1d2b6adde7 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,13 @@ +name: audk +services: + build-package: + extends: + service: dev-edk2 + file: OpenCorePkg/docker-compose.yaml + environment: + - SELFPKG + - SELFPKG_DIR + entrypoint: + - /bin/bash + - -c + - "{ . ~/.edk2_rc.sh && eval \"$(/usr/bin/curl -Lfs https://raw.githubusercontent.com/acidanthera/ocbuild/master/ci-bootstrap.sh)\" && curl -o ./efibuild.sh \"https://raw.githubusercontent.com/acidanthera/ocbuild/master/efibuild.sh\" && rm -f UDK && ln -s `pwd` UDK && touch UDK.ready && . ./efibuild.sh; } || exit 1" From 850cf3b6285f474add9eb849f0a39671a1955542 Mon Sep 17 00:00:00 2001 From: Mike Beaton Date: Sun, 29 Jan 2023 15:12:25 +0000 Subject: [PATCH 035/341] GenSec: Support TianoCompress Allows .fdf files to define a compressed .ffs section which can be read by legacy EFI firmware (such as found on Apple Mac). Use `COMPRESS TIANO`. --- BaseTools/Source/C/GenSec/GenSec.c | 14 ++++++++++---- BaseTools/Source/C/Include/Common/PiFirmwareFile.h | 1 + BaseTools/Source/Python/GenFds/CompressSection.py | 3 ++- BaseTools/Source/Python/GenFds/FdfParser.py | 4 ++-- BaseTools/UserManuals/GenSec_Utility_Man_Page.rtf | 2 +- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c index d9d2efeca7..62fd0c0a95 100644 --- a/BaseTools/Source/C/GenSec/GenSec.c +++ b/BaseTools/Source/C/GenSec/GenSec.c @@ -71,7 +71,7 @@ STATIC CHAR8 *mSectionTypeName[] = { "EFI_SECTION_SMM_DEPEX" // 0x1C }; -STATIC CHAR8 *mCompressionTypeName[] = { "PI_NONE", "PI_STD" }; +STATIC CHAR8 *mCompressionTypeName[] = { "PI_NONE", "PI_STD", "TIANO" }; #define EFI_GUIDED_SECTION_NONE 0x80 STATIC CHAR8 *mGUIDedSectionAttribue[] = { "NONE", "PROCESSING_REQUIRED", "AUTH_STATUS_VALID"}; @@ -171,7 +171,7 @@ Routine Description: if -s option is not given, \n\ EFI_SECTION_ALL is default section type.\n"); fprintf (stdout, " -c [Type], --compress [Type]\n\ - Compress method type can be PI_NONE or PI_STD.\n\ + Compress method type can be PI_NONE, PI_STD or TIANO.\n\ if -c option is not given, PI_STD is default type.\n"); fprintf (stdout, " -g GuidValue, --vendor GuidValue\n\ GuidValue is one specific vendor guid value.\n\ @@ -710,6 +710,10 @@ Routine Description: CompressFunction = (COMPRESS_FUNCTION) EfiCompress; break; + case TIANO_COMPRESS: + CompressFunction = (COMPRESS_FUNCTION) TianoCompress; + break; + default: Error (NULL, 0, 2000, "Invalid parameter", "unknown compression type"); free (FileBuffer); @@ -774,7 +778,7 @@ Routine Description: memset(CompressionSect2->CommonHeader.Size, 0xff, sizeof(UINT8) * 3); CompressionSect2->CommonHeader.Type = EFI_SECTION_COMPRESSION; CompressionSect2->CommonHeader.ExtendedSize = TotalLength; - CompressionSect2->CompressionType = SectCompSubType; + CompressionSect2->CompressionType = (SectCompSubType == EFI_NOT_COMPRESSED) ? SectCompSubType : EFI_STANDARD_COMPRESSION; CompressionSect2->UncompressedLength = InputLength; } else { CompressionSect = (EFI_COMPRESSION_SECTION *) FileBuffer; @@ -783,7 +787,7 @@ Routine Description: CompressionSect->CommonHeader.Size[0] = (UINT8) (TotalLength & 0xff); CompressionSect->CommonHeader.Size[1] = (UINT8) ((TotalLength & 0xff00) >> 8); CompressionSect->CommonHeader.Size[2] = (UINT8) ((TotalLength & 0xff0000) >> 16); - CompressionSect->CompressionType = SectCompSubType; + CompressionSect->CompressionType = (SectCompSubType == EFI_NOT_COMPRESSED) ? SectCompSubType : EFI_STANDARD_COMPRESSION; CompressionSect->UncompressedLength = InputLength; } @@ -1667,6 +1671,8 @@ Routine Description: SectCompSubType = EFI_NOT_COMPRESSED; } else if (stricmp (CompressionName, mCompressionTypeName[EFI_STANDARD_COMPRESSION]) == 0) { SectCompSubType = EFI_STANDARD_COMPRESSION; + } else if (stricmp (CompressionName, mCompressionTypeName[TIANO_COMPRESS]) == 0) { + SectCompSubType = TIANO_COMPRESS; } else { Error (NULL, 0, 1003, "Invalid option value", "--compress = %s", CompressionName); goto Finish; diff --git a/BaseTools/Source/C/Include/Common/PiFirmwareFile.h b/BaseTools/Source/C/Include/Common/PiFirmwareFile.h index 7d8acb669b..56874374ca 100644 --- a/BaseTools/Source/C/Include/Common/PiFirmwareFile.h +++ b/BaseTools/Source/C/Include/Common/PiFirmwareFile.h @@ -169,6 +169,7 @@ typedef EFI_COMMON_SECTION_HEADER2 EFI_COMPATIBILITY16_SECTION2; // #define EFI_NOT_COMPRESSED 0x00 #define EFI_STANDARD_COMPRESSION 0x01 +#define TIANO_COMPRESS 0x02 // // An encapsulation section type in which the // section data is compressed. diff --git a/BaseTools/Source/Python/GenFds/CompressSection.py b/BaseTools/Source/Python/GenFds/CompressSection.py index e62280fc16..38836324a6 100644 --- a/BaseTools/Source/Python/GenFds/CompressSection.py +++ b/BaseTools/Source/Python/GenFds/CompressSection.py @@ -26,7 +26,8 @@ class CompressSection (CompressSectionClassObject) : ## compress types: PI standard and non PI standard CompTypeDict = { 'PI_STD' : 'PI_STD', - 'PI_NONE' : 'PI_NONE' + 'PI_NONE' : 'PI_NONE', + 'TIANO' : 'TIANO', } ## The constructor diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py index feb4c72779..cab4fecce0 100644 --- a/BaseTools/Source/Python/GenFds/FdfParser.py +++ b/BaseTools/Source/Python/GenFds/FdfParser.py @@ -2985,7 +2985,7 @@ def _GetCglSection(self, Obj, AlignValue = None): if self._IsKeyword("COMPRESS"): type = "PI_STD" - if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"): + if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE") or self._IsKeyword("TIANO"): type = self._Token if not self._IsToken("{"): @@ -4054,7 +4054,7 @@ def _CheckRuleSectionFileType(self, SectionType, FileType): def _GetRuleEncapsulationSection(self, theRule): if self._IsKeyword("COMPRESS"): Type = "PI_STD" - if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"): + if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE") or self._IsKeyword("TIANO"): Type = self._Token if not self._IsToken("{"): diff --git a/BaseTools/UserManuals/GenSec_Utility_Man_Page.rtf b/BaseTools/UserManuals/GenSec_Utility_Man_Page.rtf index fea5009beb..2ccaf8f65c 100644 --- a/BaseTools/UserManuals/GenSec_Utility_Man_Page.rtf +++ b/BaseTools/UserManuals/GenSec_Utility_Man_Page.rtf @@ -184,7 +184,7 @@ COMPAT16\cell \hich\af4\dbch\af31505\loch\f4 EFI_SECTION_COMPATIBILITY16\cell }\ SSION, EFI_SECTION_GUID_DEFINED, EFI_SECTION_PE32, EFI_SECTION_PIC, EFI_SECTION_TE, EFI_SECTION_DXE_DEPEX, EFI_SECTION_COMPATIBILITY16, EFI_SECTION_USER_INTERFACE, EFI_SECTION_VERSION, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, EFI_SECTION_RAW, EFI_SECTION_FREEFO \hich\af43\dbch\af31505\loch\f43 R\hich\af43\dbch\af31505\loch\f43 M_SUBTYPE_GUID, EFI_SECTION_PEI_DEPEX. If sectiontype is not given, EFI_SECTION_ALL is default type to contain the input all sections to one section file. \par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af43\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 -c [Type], --compress [Type] -\par }\pard \ltrpar\ql \li360\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin360\itap0 {\rtlch\fcs1 \af43\afs18 \ltrch\fcs0 \fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 Compress method type can be PI_NONE or PI_STD. If Type is not given, PI_ +\par }\pard \ltrpar\ql \li360\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin360\itap0 {\rtlch\fcs1 \af43\afs18 \ltrch\fcs0 \fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 Compress method type can be PI_NONE, PI_STD or TIANO. If Type is not given, PI_ \hich\af43\dbch\af31505\loch\f43 STD is default type. \par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af43\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 -g GuidValue, --vendor GuidValue \par }\pard \ltrpar\ql \li360\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin360\itap0 {\rtlch\fcs1 \af43\afs18 \ltrch\fcs0 \fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 From bf04e15d555bb549e7ba063c03f947a4d86e645f Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Mon, 6 Feb 2023 23:06:26 +0600 Subject: [PATCH 036/341] CryptoPkg/IntrinsicLib: Corrects __ashrdi3 and adds __lshrdi3 The ashrdi3 function should do arithmetic shift instead of logic using sar instruction. Also adds __lshrdi3 implementation to correct build using LLVM Signed-off-by: Savva Mitrofanov --- .../IntrinsicLib/Ia32/MathRShiftU64.nasm | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathRShiftU64.nasm b/CryptoPkg/Library/IntrinsicLib/Ia32/MathRShiftU64.nasm index 1d51a4dfa3..25a7296648 100644 --- a/CryptoPkg/Library/IntrinsicLib/Ia32/MathRShiftU64.nasm +++ b/CryptoPkg/Library/IntrinsicLib/Ia32/MathRShiftU64.nasm @@ -23,6 +23,31 @@ ;------------------------------------------------------------------------------ global ASM_PFX(__ashrdi3) ASM_PFX(__ashrdi3): + cmp cl,0x40 + jnc ReturnZero + cmp cl,0x20 + jnc CounterMore32 + shrd eax,edx,cl + sar edx,cl + ret +CounterMore32: + mov eax,edx + xor edx,edx + and cl,0x1f + sar eax,cl + ret +ReturnZero: + xor eax,eax + xor edx,edx + ret + +;------------------------------------------------------------------------------ +; +; void __cdecl __lshrdi3 (void) +; +;------------------------------------------------------------------------------ +global ASM_PFX(__lshrdi3) +ASM_PFX(__lshrdi3): cmp cl,0x40 jnc _Exit cmp cl,0x20 @@ -40,4 +65,3 @@ _Exit: xor eax,eax xor edx,edx ret - From 85d905ee560f20f0c758c2d164df065061e245a2 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Fri, 10 Feb 2023 16:24:01 +0600 Subject: [PATCH 037/341] UefiCpuPkg/CpuPageTableLib: Add intrinsic lib to fix MSVC build For the bitfield access, MSVC apparently uses a right shift of the base type of the bitfield member. In our case, is is cased by IA32_PTE_4K and IA32_PAGE_LEAF_ENTRY_BIG_PAGESIZE and other structures which uses uint64 bitfields and 32-bit x86 doesn't have a 64-bit integer shift (except using MMX or SSE2). With -Od (NOOPT) even for constant counts it puts the data in EDX:EAX, the shift count in cl and calls __aullshr. Signed-off-by: Savva Mitrofanov --- .../IntrinsicLib/Ia32/MathDivU64xU64Rem.c | 91 +++++++++++++++++++ .../Library/IntrinsicLib/IntrinsicLib.inf | 2 + .../CpuPageTableLib/CpuPageTableLib.inf | 1 + UefiCpuPkg/UefiCpuPkg.dsc | 4 + 4 files changed, 98 insertions(+) create mode 100644 CryptoPkg/Library/IntrinsicLib/Ia32/MathDivU64xU64Rem.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathDivU64xU64Rem.c b/CryptoPkg/Library/IntrinsicLib/Ia32/MathDivU64xU64Rem.c new file mode 100644 index 0000000000..ca74d54d07 --- /dev/null +++ b/CryptoPkg/Library/IntrinsicLib/Ia32/MathDivU64xU64Rem.c @@ -0,0 +1,91 @@ +/** @file + 64-bit Math Worker Function. + The 32-bit versions of C compiler generate calls to library routines + to handle 64-bit math. These functions use non-standard calling conventions. + Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+ This program and the accompanying materials are licensed and made available + under the terms and conditions of the BSD License which accompanies this + distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + + +/* + * Divides a 64-bit unsigned value by another 64-bit unsigned value and returns + * the 64-bit unsigned remainder. + */ +__declspec(naked) void __cdecl +_aullrem(void) +{ + // + // Wrapper Implementation over EDKII DivU64x64Remainder() routine + // UINT64 + // EFIAPI + // DivU64x64Remainder ( + // IN UINT64 Dividend, + // IN UINT64 Divisor, + // OUT UINT64 *Remainder OPTIONAL + // ) + // + _asm { + ; Original local stack when calling _aullrem + ; ----------------- + ; | | + ; |---------------| + ; | | + ; |-- Divisor --| + ; | | + ; |---------------| + ; | | + ; |-- Dividend --| + ; | | + ; |---------------| + ; | ReturnAddr** | + ; ESP---->|---------------| + ; + + ; + ; Set up the local stack for Reminder pointer + ; + sub esp, 8 + push esp + + ; + ; Set up the local stack for Divisor parameter + ; + mov eax, [esp + 28] + push eax + mov eax, [esp + 28] + push eax + + ; + ; Set up the local stack for Dividend parameter + ; + mov eax, [esp + 28] + push eax + mov eax, [esp + 28] + push eax + + ; + ; Call native DivU64x64Remainder of BaseLib + ; + call DivU64x64Remainder + + ; + ; Put the Reminder in EDX:EAX as return value + ; + mov eax, [esp + 20] + mov edx, [esp + 24] + + ; + ; Adjust stack + ; + add esp, 28 + + ret 16 + } +} \ No newline at end of file diff --git a/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf b/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf index ae238ccc0b..8602a513b0 100644 --- a/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf +++ b/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf @@ -27,6 +27,7 @@ [Sources.IA32] CopyMem.c + Ia32/MathDivU64xU64Rem.c | MSFT Ia32/MathLShiftS64.c | MSFT Ia32/MathRShiftU64.c | MSFT Ia32/MathFtol.c | MSFT @@ -37,6 +38,7 @@ Ia32/MathLldiv.asm | MSFT Ia32/MathUllrem.asm | MSFT + Ia32/MathDivU64xU64Rem.c | INTEL Ia32/MathLShiftS64.c | INTEL Ia32/MathRShiftU64.c | INTEL Ia32/MathFtol.c | INTEL diff --git a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf index e4ead7441c..5d48feb81f 100644 --- a/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf +++ b/UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf @@ -33,3 +33,4 @@ BaseLib BaseMemoryLib DebugLib + IntrinsicLib diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index dc6150ce57..ff9768375d 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -74,6 +74,7 @@ LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf HobLib|MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf MemoryAllocationLib|MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf [LibraryClasses.common.SEC] PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf @@ -138,6 +139,9 @@ UefiCpuPkg/MicrocodeMeasurementDxe/MicrocodeMeasurementDxe.inf UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.inf +[Components.IA32] + CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + [Components.IA32, Components.X64] UefiCpuPkg/CpuDxe/CpuDxe.inf UefiCpuPkg/CpuFeatures/CpuFeaturesPei.inf { From f1cd03097231d167bfc888636fcb34c45ffe5181 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 20 Apr 2023 11:47:10 +0300 Subject: [PATCH 038/341] FatPkg: Adds support for read-only mode Implements gEfiFatPkgTokenSpaceGuid token space and adds token which disables write operations. By default driver still supports read-write mode Signed-off-by: Savva Mitrofanov --- FatPkg/EnhancedFatDxe/Delete.c | 2 +- FatPkg/EnhancedFatDxe/DirectoryManage.c | 23 ++++++++++++++++++++++ FatPkg/EnhancedFatDxe/Fat.inf | 2 ++ FatPkg/EnhancedFatDxe/FileSpace.c | 8 ++++++++ FatPkg/EnhancedFatDxe/Flush.c | 7 +++++++ FatPkg/EnhancedFatDxe/Init.c | 2 +- FatPkg/EnhancedFatDxe/Open.c | 4 ++++ FatPkg/EnhancedFatDxe/ReadWrite.c | 26 +++++++++++++++++++++++++ FatPkg/FatPkg.dec | 13 +++++++++++++ FatPkg/FatPkg.dsc | 3 +++ 10 files changed, 88 insertions(+), 2 deletions(-) diff --git a/FatPkg/EnhancedFatDxe/Delete.c b/FatPkg/EnhancedFatDxe/Delete.c index 448d669f9d..a341005afb 100644 --- a/FatPkg/EnhancedFatDxe/Delete.c +++ b/FatPkg/EnhancedFatDxe/Delete.c @@ -44,7 +44,7 @@ FatDelete ( // // If the file is read-only, then don't delete it // - if (IFile->ReadOnly) { + if (IFile->ReadOnly || FeaturePcdGet (PcdFatReadOnlyMode)) { Status = EFI_WRITE_PROTECTED; goto Done; } diff --git a/FatPkg/EnhancedFatDxe/DirectoryManage.c b/FatPkg/EnhancedFatDxe/DirectoryManage.c index 723fc35f38..d296033b13 100644 --- a/FatPkg/EnhancedFatDxe/DirectoryManage.c +++ b/FatPkg/EnhancedFatDxe/DirectoryManage.c @@ -73,6 +73,10 @@ FatStoreDirEnt ( UINT8 EntryCount; UINT8 LfnOrdinal; + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } + EntryPos = DirEnt->EntryPos; EntryCount = DirEnt->EntryCount; // @@ -709,6 +713,9 @@ FatExpandODir ( IN FAT_OFILE *OFile ) { + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } return FatExpandOFile (OFile, OFile->FileSize + OFile->Volume->ClusterSize); } @@ -954,6 +961,10 @@ FatSetVolumeEntry ( FAT_DIRENT LabelDirEnt; FAT_OFILE *Root; + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } + Root = Volume->Root; Status = FatSeekVolumeId (Volume->Root, &LabelDirEnt); if (EFI_ERROR (Status)) { @@ -1001,6 +1012,10 @@ FatCreateDotDirEnts ( EFI_STATUS Status; FAT_DIRENT *DirEnt; + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } + Status = FatExpandODir (OFile); if (EFI_ERROR (Status)) { return Status; @@ -1048,6 +1063,10 @@ FatCreateDirEnt ( FAT_ODIR *ODir; EFI_STATUS Status; + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } + ASSERT (OFile != NULL); ODir = OFile->ODir; ASSERT (ODir != NULL); @@ -1105,6 +1124,10 @@ FatRemoveDirEnt ( { FAT_ODIR *ODir; + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } + ODir = OFile->ODir; if (ODir->CurrentCursor == &DirEnt->Link) { // diff --git a/FatPkg/EnhancedFatDxe/Fat.inf b/FatPkg/EnhancedFatDxe/Fat.inf index 17b6348a25..92864278c4 100644 --- a/FatPkg/EnhancedFatDxe/Fat.inf +++ b/FatPkg/EnhancedFatDxe/Fat.inf @@ -56,6 +56,7 @@ [Packages] MdePkg/MdePkg.dec + FatPkg/FatPkg.dec [LibraryClasses] UefiRuntimeServicesTableLib @@ -82,6 +83,7 @@ gEfiUnicodeCollation2ProtocolGuid ## TO_START [Pcd] + gEfiFatPkgTokenSpaceGuid.PcdFatReadOnlyMode ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLang ## SOMETIMES_CONSUMES gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang ## SOMETIMES_CONSUMES [UserExtensions.TianoCore."ExtraFiles"] diff --git a/FatPkg/EnhancedFatDxe/FileSpace.c b/FatPkg/EnhancedFatDxe/FileSpace.c index 909d4980d2..d1573df5fb 100644 --- a/FatPkg/EnhancedFatDxe/FileSpace.c +++ b/FatPkg/EnhancedFatDxe/FileSpace.c @@ -362,6 +362,10 @@ FatShrinkEof ( UINTN Cluster; UINTN LastCluster; + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } + Volume = OFile->Volume; ASSERT_VOLUME_LOCKED (Volume); @@ -440,6 +444,10 @@ FatGrowEof ( UINTN NewCluster; UINTN ClusterCount; + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } + // // For FAT file system, the max file is 4GB. // diff --git a/FatPkg/EnhancedFatDxe/Flush.c b/FatPkg/EnhancedFatDxe/Flush.c index 8c6010328b..294641e798 100644 --- a/FatPkg/EnhancedFatDxe/Flush.c +++ b/FatPkg/EnhancedFatDxe/Flush.c @@ -35,6 +35,10 @@ FatFlushEx ( EFI_STATUS Status; FAT_TASK *Task; + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } + IFile = IFILE_FROM_FHAND (FHand); OFile = IFile->OFile; Volume = OFile->Volume; @@ -112,6 +116,9 @@ FatFlush ( IN EFI_FILE_PROTOCOL *FHand ) { + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } return FatFlushEx (FHand, NULL); } diff --git a/FatPkg/EnhancedFatDxe/Init.c b/FatPkg/EnhancedFatDxe/Init.c index 9c51ed5b7b..6dcfca3212 100644 --- a/FatPkg/EnhancedFatDxe/Init.c +++ b/FatPkg/EnhancedFatDxe/Init.c @@ -51,7 +51,7 @@ FatAllocateVolume ( Volume->DiskIo2 = DiskIo2; Volume->BlockIo = BlockIo; Volume->MediaId = BlockIo->Media->MediaId; - Volume->ReadOnly = BlockIo->Media->ReadOnly; + Volume->ReadOnly = BlockIo->Media->ReadOnly || FeaturePcdGet (PcdFatReadOnlyMode); Volume->VolumeInterface.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION; Volume->VolumeInterface.OpenVolume = FatOpenVolume; InitializeListHead (&Volume->CheckRef); diff --git a/FatPkg/EnhancedFatDxe/Open.c b/FatPkg/EnhancedFatDxe/Open.c index f3fd6566ea..32a8e59fa6 100644 --- a/FatPkg/EnhancedFatDxe/Open.c +++ b/FatPkg/EnhancedFatDxe/Open.c @@ -224,8 +224,12 @@ FatOpenEx ( // switch (OpenMode) { case EFI_FILE_MODE_READ: + break; case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE: case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE: + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } break; default: diff --git a/FatPkg/EnhancedFatDxe/ReadWrite.c b/FatPkg/EnhancedFatDxe/ReadWrite.c index 8f525044d1..cf0ed0f52b 100644 --- a/FatPkg/EnhancedFatDxe/ReadWrite.c +++ b/FatPkg/EnhancedFatDxe/ReadWrite.c @@ -211,6 +211,10 @@ FatIFileAccess ( UINT64 EndPosition; FAT_TASK *Task; + if (FeaturePcdGet (PcdFatReadOnlyMode) && IoMode == WriteData) { + return EFI_WRITE_PROTECTED; + } + IFile = IFILE_FROM_FHAND (FHand); OFile = IFile->OFile; Volume = OFile->Volume; @@ -414,6 +418,9 @@ FatWrite ( IN VOID *Buffer ) { + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } return FatIFileAccess (FHand, WriteData, BufferSize, Buffer, NULL); } @@ -437,6 +444,9 @@ FatWriteEx ( IN OUT EFI_FILE_IO_TOKEN *Token ) { + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } return FatIFileAccess (FHand, WriteData, &Token->BufferSize, Token->Buffer, Token); } @@ -471,6 +481,10 @@ FatAccessOFile ( EFI_STATUS Status; UINTN BufferSize; + if (FeaturePcdGet (PcdFatReadOnlyMode) && IoMode == WriteData) { + return EFI_WRITE_PROTECTED; + } + BufferSize = *DataBufferSize; Volume = OFile->Volume; ASSERT_VOLUME_LOCKED (Volume); @@ -542,6 +556,10 @@ FatExpandOFile ( EFI_STATUS Status; UINTN WritePos; + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } + WritePos = OFile->FileSize; Status = FatGrowEof (OFile, ExpandedSize); if (!EFI_ERROR (Status)) { @@ -575,6 +593,10 @@ FatWriteZeroPool ( UINTN BufferSize; UINTN WriteSize; + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } + AppendedSize = OFile->FileSize - WritePos; BufferSize = AppendedSize; if (AppendedSize > FAT_MAX_ALLOCATE_SIZE) { @@ -624,6 +646,10 @@ FatTruncateOFile ( IN UINTN TruncatedSize ) { + if (FeaturePcdGet (PcdFatReadOnlyMode)) { + return EFI_WRITE_PROTECTED; + } + OFile->FileSize = TruncatedSize; return FatShrinkEof (OFile); } diff --git a/FatPkg/FatPkg.dec b/FatPkg/FatPkg.dec index ecd086b41a..017402984a 100644 --- a/FatPkg/FatPkg.dec +++ b/FatPkg/FatPkg.dec @@ -17,3 +17,16 @@ [UserExtensions.TianoCore."ExtraFiles"] FatPkgExtra.uni + +[Guids] + # + # GUID defined in package + # + gEfiFatPkgTokenSpaceGuid = { 0xbe1f59ff, 0x65f5, 0x4b28, {0xb2, 0x8d, 0x56, 0x85, 0x36, 0x4a, 0xb1, 0xd2 } } + +[PcdsFeatureFlag.common] + ## Indicates if driver is in read-only mode.

+ # TRUE - Restricts write operations.
+ # FALSE - Write operations allowed. Default behavior
+ # @Prompt Disables write operations on fat filesystem. + gEfiFatPkgTokenSpaceGuid.PcdFatReadOnlyMode |FALSE|BOOLEAN|0x00000001 diff --git a/FatPkg/FatPkg.dsc b/FatPkg/FatPkg.dsc index 49b42213aa..ed81d2adf1 100644 --- a/FatPkg/FatPkg.dsc +++ b/FatPkg/FatPkg.dsc @@ -78,3 +78,6 @@ [Components] FatPkg/FatPei/FatPei.inf FatPkg/EnhancedFatDxe/Fat.inf + +[PcdsFeatureFlag] + gEfiFatPkgTokenSpaceGuid.PcdFatReadOnlyMode|FALSE From 70dd7f8309432058aa6c5e1ff8f212bda0eb809a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Wed, 8 Mar 2023 17:02:48 +0100 Subject: [PATCH 039/341] MdePkg/Base.h: Only use C++ static_assert when supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To support GoogleTest, 933b4c3 added support for C++ static_assert. However, this is not a mandatory or universally supported C++ feature. Guard its usage by the __cpp_static_assert support flag. Signed-off-by: Marvin Häuser --- MdePkg/Include/Base.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h index ee5940a2d1..900523df66 100644 --- a/MdePkg/Include/Base.h +++ b/MdePkg/Include/Base.h @@ -800,7 +800,7 @@ typedef UINTN *BASE_LIST; @param Message Raised compiler diagnostic message when expression is false. **/ -#if defined (__cplusplus) +#if defined (__cpp_static_assert) #define STATIC_ASSERT static_assert #elif defined (__GNUC__) || defined (__clang__) #define STATIC_ASSERT _Static_assert From c4ec3c100b6a3f9104eb1f47f3af0acaacff5770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Sun, 12 Mar 2023 22:08:46 +0100 Subject: [PATCH 040/341] MdePkg/Base.h: Add support for C++ alignof MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation of including Base.h in C++ BaseTools programs, support the C++ 11 alignof operator. The C _Alignof operator is not universally supported in C++ mode across compiler toolchains and thus the current definition may lead to compilation errors with said programs. Signed-off-by: Marvin Häuser --- MdePkg/Include/Base.h | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h index 900523df66..469161b4b9 100644 --- a/MdePkg/Include/Base.h +++ b/MdePkg/Include/Base.h @@ -765,23 +765,30 @@ typedef UINTN *BASE_LIST; @return Alignment requirement, in Bytes, of TYPE. **/ -#if defined (__cplusplus) -// -// Standard C++ operator. -// -#define ALIGNOF(TYPE) alignof (TYPE) -#elif defined (__GNUC__) || defined (__clang__) || (defined (_MSC_VER) && _MSC_VER >= 1900) -// -// All supported versions of GCC and Clang, as well as MSVC 2015 and later, -// support the standard operator _Alignof. -// -#define ALIGNOF(TYPE) _Alignof (TYPE) -#elif defined (_MSC_EXTENSIONS) -// -// Earlier versions of MSVC, at least MSVC 2008 and later, support the vendor -// extension __alignof. -// -#define ALIGNOF(TYPE) __alignof (TYPE) +#if defined(__cplusplus) && __cplusplus >= 201103L + // + // C++ 11 and later support the standard operator alignof. + // + #define ALIGNOF(TYPE) alignof (TYPE) +#elif ((defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1900)) && !defined (__cplusplus)) || defined(__clang__) + // + // All supported versions of GCC and Clang, as well as MSVC 2015 and later, + // support the standard operator _Alignof in C mode. GCC and MSVC do not + // support it in C++ mode though. + // + #define ALIGNOF(TYPE) _Alignof (TYPE) +#elif defined(__GNUC__) + // + // GCC does not support _Alignof in C++ mode, unlike Clang. The vendor- + // extenstion is supported in both C and C++ mode. + // + #define ALIGNOF(TYPE) __alignof__ (TYPE) +#elif defined(_MSC_EXTENSIONS) + // + // Earlier versions of MSVC, at least MSVC 2008 and later, as well as current + // versions in C++ mode support the vendor-extension __alignof. + // + #define ALIGNOF(TYPE) __alignof (TYPE) #else // // For compilers that do not support inbuilt alignof operators, use OFFSET_OF. From 72aa61ce91bc8152372939fa20a32643d8adbc9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Wed, 8 Mar 2023 15:58:47 +0100 Subject: [PATCH 041/341] UefiCpuPkg/MtrrLib: Add missing PcdLib.h include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MtrrLib does not include PcdLib.h despite explicitly using its definitions. Add the include to fix compilation for modules that do not utilize AutoGen. Signed-off-by: Marvin Häuser --- UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c index bfe02f3cb9..a5181ebd74 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -19,6 +19,7 @@ #include #include #include +#include #define OR_SEED 0x0101010101010101ull #define CLEAR_SEED 0xFFFFFFFFFFFFFFFFull From 2f61ab9f51dfa943bae7a9c609ff0a79919f1475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Wed, 8 Mar 2023 15:57:01 +0100 Subject: [PATCH 042/341] BaseTools/CommonLib: Consume MdePkg and MdeModulePkg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BaseTools has been duplicating and adapting code that is defined in MdePkg and MdeModulePkg. This leads to desync issues where the same symbols may be backed by different functions with slightly different semantics and also fixes that apply only to BaseTools or only to MdePkg and MdeModulePkg. To address these issues, update BaseTools/Source/C to utilize the code from MdePkg and MdeModulePkg. Signed-off-by: Marvin Häuser --- BaseTools/.gitignore | 1 + BaseTools/ImageTool/Makefile | 4 +- BaseTools/MicroTool/Makefile | 4 +- BaseTools/Source/C/Common/AutoGen.c | 19 + BaseTools/Source/C/Common/BasePeCoff.c | 2 +- BaseTools/Source/C/Common/BinderFuncs.c | 4 +- BaseTools/Source/C/Common/BinderFuncs.h | 2 +- BaseTools/Source/C/Common/CommonLib.c | 1624 ++-------------- BaseTools/Source/C/Common/CommonLib.h | 302 +-- BaseTools/Source/C/Common/Crc32.c | 306 +-- BaseTools/Source/C/Common/Crc32.h | 23 +- BaseTools/Source/C/Common/DebugLib.c | 356 ++++ .../Source/C/Common/FirmwareVolumeBuffer.c | 14 +- BaseTools/Source/C/Common/FvLib.c | 4 +- BaseTools/Source/C/Common/GNUmakefile | 62 + BaseTools/Source/C/Common/Makefile | 61 + .../Source/C/Common/ParseGuidedSectionTools.c | 2 +- BaseTools/Source/C/Common/PeCoffLoaderEx.c | 12 +- BaseTools/Source/C/DevicePath/Makefile | 9 +- .../Source/C/DevicePath/UefiDevicePathLib.h | 112 ++ BaseTools/Source/C/EfiRom/EfiRom.h | 2 +- BaseTools/Source/C/GenCrc32/GenCrc32.c | 4 +- BaseTools/Source/C/GenFfs/GenFfs.c | 7 +- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 27 +- BaseTools/Source/C/GenFv/GenFvInternalLib.h | 5 +- BaseTools/Source/C/GenSec/GenSec.c | 19 +- BaseTools/Source/C/Include/Common/AutoGen.h | 94 + BaseTools/Source/C/Include/Common/BaseTypes.h | 302 +-- .../Common/GuidedSectionExtractionEx.h | 36 + .../Source/C/Include/Common/MdeModuleHii.h | 223 +-- BaseTools/Source/C/Include/Common/PeImageEx.h | 59 + .../Source/C/Include/Common/PiFirmwareFile.h | 298 +-- .../C/Include/Common/PiFirmwareVolume.h | 145 +- .../Source/C/Include/Common/UefiBaseTypes.h | 158 +- .../Source/C/Include/Common/UefiCapsule.h | 18 +- .../Common/UefiInternalFormRepresentation.h | 1675 +---------------- .../Source/C/Include/Common/VariableFormat.h | 44 - .../C/Include/Common/WorkingBlockHeader.h | 35 - BaseTools/Source/C/Include/Guid/PcAnsi.h | 52 - .../C/Include/Guid/PiFirmwareFileSystem.h | 39 - .../Source/C/Include/Protocol/DevicePath.h | 1404 -------------- .../C/Include/Protocol/DevicePathUtilities.h | 288 --- .../C/Include/Protocol/GraphicsOutput.h | 187 -- .../Protocol/GuidedSectionExtraction.h | 145 -- .../Source/C/Include/Protocol/HiiFramework.h | 944 ---------- BaseTools/Source/C/Include/Protocol/UgaDraw.h | 161 -- .../Source/C/LzmaCompress/LzmaCompress.c | 2 + BaseTools/Source/C/Makefiles/footer.makefile | 5 + BaseTools/Source/C/Makefiles/header.makefile | 13 +- BaseTools/Source/C/Makefiles/ms.common | 7 + BaseTools/Source/C/Makefiles/ms.rule | 20 + BaseTools/Source/C/VolInfo/VolInfo.c | 15 +- 52 files changed, 1160 insertions(+), 8196 deletions(-) create mode 100644 BaseTools/Source/C/Common/AutoGen.c create mode 100644 BaseTools/Source/C/Common/DebugLib.c create mode 100644 BaseTools/Source/C/Include/Common/AutoGen.h create mode 100644 BaseTools/Source/C/Include/Common/GuidedSectionExtractionEx.h create mode 100644 BaseTools/Source/C/Include/Common/PeImageEx.h delete mode 100644 BaseTools/Source/C/Include/Common/VariableFormat.h delete mode 100644 BaseTools/Source/C/Include/Common/WorkingBlockHeader.h delete mode 100644 BaseTools/Source/C/Include/Guid/PcAnsi.h delete mode 100644 BaseTools/Source/C/Include/Guid/PiFirmwareFileSystem.h delete mode 100644 BaseTools/Source/C/Include/Protocol/DevicePath.h delete mode 100644 BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h delete mode 100644 BaseTools/Source/C/Include/Protocol/GraphicsOutput.h delete mode 100644 BaseTools/Source/C/Include/Protocol/GuidedSectionExtraction.h delete mode 100644 BaseTools/Source/C/Include/Protocol/HiiFramework.h delete mode 100644 BaseTools/Source/C/Include/Protocol/UgaDraw.h diff --git a/BaseTools/.gitignore b/BaseTools/.gitignore index 08a53639bd..3f28c9038d 100644 --- a/BaseTools/.gitignore +++ b/BaseTools/.gitignore @@ -16,6 +16,7 @@ Source/C/VfrCompile/VfrSyntax.cpp Source/C/VfrCompile/VfrTokens.h Source/C/bin/ Source/C/libs/ +Source/C/obj/ Bin/Win32 Bin/Win64 Lib diff --git a/BaseTools/ImageTool/Makefile b/BaseTools/ImageTool/Makefile index 76e9479d96..fe1e197b5a 100644 --- a/BaseTools/ImageTool/Makefile +++ b/BaseTools/ImageTool/Makefile @@ -4,12 +4,14 @@ # Copyright (c) 2022, Mikhail Krichanov. All rights reserved. # SPDX-License-Identifier: BSD-3-Clause # +EDK2_PATH = ..\.. + !INCLUDE ..\Source\C\Makefiles\ms.common APP = ImageTool OC_USER = ..\..\OpenCorePkg -UDK_PATH = ..\.. +UDK_PATH = $(EDK2_PATH) UDK_ARCH = $(HOST_ARCH) OUT_DIR = .\Windows diff --git a/BaseTools/MicroTool/Makefile b/BaseTools/MicroTool/Makefile index 8df029aff8..44d23ca0de 100644 --- a/BaseTools/MicroTool/Makefile +++ b/BaseTools/MicroTool/Makefile @@ -4,12 +4,14 @@ # Copyright (c) 2022, Mikhail Krichanov. All rights reserved. # SPDX-License-Identifier: BSD-3-Clause # +EDK2_PATH = ..\.. + !INCLUDE ..\Source\C\Makefiles\ms.common APP = MicroTool OC_USER = ..\..\OpenCorePkg -UDK_PATH = ..\.. +UDK_PATH = $(EDK2_PATH) UDK_ARCH = $(HOST_ARCH) OUT_DIR = .\Windows diff --git a/BaseTools/Source/C/Common/AutoGen.c b/BaseTools/Source/C/Common/AutoGen.c new file mode 100644 index 0000000000..8c88f6c177 --- /dev/null +++ b/BaseTools/Source/C/Common/AutoGen.c @@ -0,0 +1,19 @@ +/** @file + AutoGen definitions for edk2 package code consumption in BaseTools. + + Copyright (c) 2023, Marvin Häuser. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +GLOBAL_REMOVE_IF_UNREFERENCED GUID gEfiCallerIdGuid = EFI_CALLER_ID_GUID; + +GLOBAL_REMOVE_IF_UNREFERENCED GUID gEdkiiDscPlatformGuid = EDKII_DSC_PLATFORM_GUID; + +GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *gEfiCallerBaseName = "BaseTools"; + +// Definition of SkuId Array +GLOBAL_REMOVE_IF_UNREFERENCED UINT64 _gPcd_SkuId_Array[] = {0x0}; + diff --git a/BaseTools/Source/C/Common/BasePeCoff.c b/BaseTools/Source/C/Common/BasePeCoff.c index 038bb054e5..c38180af69 100644 --- a/BaseTools/Source/C/Common/BasePeCoff.c +++ b/BaseTools/Source/C/Common/BasePeCoff.c @@ -12,7 +12,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include +#include #include "PeCoffLib.h" typedef union { diff --git a/BaseTools/Source/C/Common/BinderFuncs.c b/BaseTools/Source/C/Common/BinderFuncs.c index de835287e9..6d81cb8d30 100644 --- a/BaseTools/Source/C/Common/BinderFuncs.c +++ b/BaseTools/Source/C/Common/BinderFuncs.c @@ -62,12 +62,12 @@ CommonLibBinderCompareMem ( } BOOLEAN -CommonLibBinderCompareGuid ( +CommonLibBinderBtCompareGuid ( IN EFI_GUID *Guid1, IN EFI_GUID *Guid2 ) { - return CompareGuid (Guid1, Guid2) ? FALSE : TRUE; + return BtCompareGuid (Guid1, Guid2) ? FALSE : TRUE; } diff --git a/BaseTools/Source/C/Common/BinderFuncs.h b/BaseTools/Source/C/Common/BinderFuncs.h index ceaa9cd318..1774ff08b1 100644 --- a/BaseTools/Source/C/Common/BinderFuncs.h +++ b/BaseTools/Source/C/Common/BinderFuncs.h @@ -52,7 +52,7 @@ CommonLibBinderCompareMem ( ); BOOLEAN -CommonLibBinderCompareGuid ( +CommonLibBinderBtCompareGuid ( IN EFI_GUID *Guid1, IN EFI_GUID *Guid2 ); diff --git a/BaseTools/Source/C/Common/CommonLib.c b/BaseTools/Source/C/Common/CommonLib.c index b2cde6d481..ded1cbb5c3 100644 --- a/BaseTools/Source/C/Common/CommonLib.c +++ b/BaseTools/Source/C/Common/CommonLib.c @@ -18,77 +18,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "CommonLib.h" #include "EfiUtilityMsgs.h" -#define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \ - do { \ - ASSERT (Expression); \ - if (!(Expression)) { \ - return Status; \ - } \ - } while (FALSE) - -/** - Set Buffer to zero for Size bytes. - - @param Buffer Memory to set. - @param Size Number of bytes to set -**/ -VOID -PeiZeroMem ( - IN VOID *Buffer, - IN UINTN Size - ) -{ - INT8 *Ptr; - - Ptr = Buffer; - while (Size--) { - *(Ptr++) = 0; - } -} - -/** - Copy Length bytes from Source to Destination. - - @param Destination Target of copy - @param Source Place to copy from - @param Length Number of bytes to copy -**/ -VOID -PeiCopyMem ( - IN VOID *Destination, - IN VOID *Source, - IN UINTN Length - ) -{ - CHAR8 *Destination8; - CHAR8 *Source8; - - Destination8 = Destination; - Source8 = Source; - while (Length--) { - *(Destination8++) = *(Source8++); - } -} - -VOID -ZeroMem ( - IN VOID *Buffer, - IN UINTN Size - ) -{ - PeiZeroMem (Buffer, Size); -} - -VOID -CopyMem ( - IN VOID *Destination, - IN VOID *Source, - IN UINTN Length - ) -{ - PeiCopyMem (Destination, Source, Length); -} - /** Compares to GUIDs @@ -99,27 +28,12 @@ CopyMem ( @retval != 0 if Guid1 != Guid2 **/ INTN -CompareGuid ( +BtCompareGuid ( IN EFI_GUID *Guid1, IN EFI_GUID *Guid2 ) { - INT32 *g1; - INT32 *g2; - INT32 r; - - // - // Compare 32 bits at a time - // - g1 = (INT32 *) Guid1; - g2 = (INT32 *) Guid2; - - r = g1[0] - g2[0]; - r |= g1[1] - g2[1]; - r |= g1[2] - g2[2]; - r |= g1[3] - g2[3]; - - return r; + return !CompareGuid (Guid1, Guid2); } /** @@ -273,67 +187,13 @@ PutFileImage ( return EFI_SUCCESS; } -/** - This function calculates the value needed for a valid UINT8 checksum - - @param Buffer Pointer to buffer containing byte data of component. - @param Size Size of the buffer - - @return The 8 bit checksum value needed. -**/ -UINT8 -CalculateChecksum8 ( - IN UINT8 *Buffer, - IN UINTN Size - ) -{ - return (UINT8) (0x100 - CalculateSum8 (Buffer, Size)); -} - -/** - This function calculates the UINT8 sum for the requested region. - - @param Buffer Pointer to buffer containing byte data of component. - @param Size Size of the buffer - - @return The 8 bit checksum value needed. -**/ -UINT8 -CalculateSum8 ( - IN UINT8 *Buffer, - IN UINTN Size - ) -{ - UINTN Index; - UINT8 Sum; - - Sum = 0; - - // - // Perform the byte sum for buffer - // - for (Index = 0; Index < Size; Index++) { - Sum = (UINT8) (Sum + Buffer[Index]); - } - - return Sum; -} - -/** - This function calculates the value needed for a valid UINT16 checksum - - @param Buffer Pointer to buffer containing byte data of component. - @param Size Size of the buffer - - @return The 16 bit checksum value needed. -**/ UINT16 -CalculateChecksum16 ( +BtCalculateChecksum16 ( IN UINT16 *Buffer, IN UINTN Size ) { - return (UINT16) (0x10000 - CalculateSum16 (Buffer, Size)); + return CalculateCheckSum16 (Buffer, Size * sizeof (UINT16)); } /** @@ -345,24 +205,12 @@ CalculateChecksum16 ( @return The 16 bit checksum **/ UINT16 -CalculateSum16 ( +BtCalculateSum16 ( IN UINT16 *Buffer, IN UINTN Size ) { - UINTN Index; - UINT16 Sum; - - Sum = 0; - - // - // Perform the word sum for buffer - // - for (Index = 0; Index < Size; Index++) { - Sum = (UINT16) (Sum + Buffer[Index]); - } - - return (UINT16) Sum; + return CalculateSum16 (Buffer, Size * sizeof (UINT16)); } /** @@ -634,45 +482,6 @@ LongFilePath ( #endif } -CHAR16 -InternalCharToUpper ( - CHAR16 Char - ) -{ - if (Char >= L'a' && Char <= L'z') { - return (CHAR16) (Char - (L'a' - L'A')); - } - - return Char; -} - -UINTN -StrnLenS ( - CONST CHAR16 *String, - UINTN MaxSize - ) -{ - UINTN Length; - - ASSERT (((UINTN) String & BIT0) == 0); - - // - // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero. - // - if ((String == NULL) || (MaxSize == 0)) { - return 0; - } - - Length = 0; - while (String[Length] != 0) { - if (Length >= MaxSize - 1) { - return MaxSize; - } - Length++; - } - return Length; -} - VOID * InternalAllocatePool ( @@ -705,6 +514,7 @@ InternalReallocatePool ( } VOID * +EFIAPI ReallocatePool ( UINTN OldSize, UINTN NewSize, @@ -714,1344 +524,174 @@ ReallocatePool ( return InternalReallocatePool (OldSize, NewSize, OldBuffer); } -/** - Returns the length of a Null-terminated Unicode string. - - This function returns the number of Unicode characters in the Null-terminated - Unicode string specified by String. - - If String is NULL, then ASSERT(). - If String is not aligned on a 16-bit boundary, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and String contains more than - PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - - @param String A pointer to a Null-terminated Unicode string. - - @return The length of String. - -**/ -UINTN -StrLen ( - CONST CHAR16 *String +VOID * +InternalAllocateCopyPool ( + UINTN AllocationSize, + CONST VOID *Buffer ) { - UINTN Length; + VOID *Memory; - ASSERT (String != NULL); - ASSERT (((UINTN) String & BIT0) == 0); + ASSERT (Buffer != NULL); - for (Length = 0; *String != L'\0'; String++, Length++) { - // - // If PcdMaximumUnicodeStringLength is not zero, - // length should not more than PcdMaximumUnicodeStringLength - // + Memory = malloc (AllocationSize); + if (Memory != NULL) { + Memory = memcpy (Memory, Buffer, AllocationSize); } - return Length; + return Memory; } -BOOLEAN -InternalSafeStringIsOverlap ( - IN VOID *Base1, - IN UINTN Size1, - IN VOID *Base2, - IN UINTN Size2 +VOID * +EFIAPI +AllocateCopyPool ( + UINTN AllocationSize, + CONST VOID *Buffer + ) +{ + return InternalAllocateCopyPool (AllocationSize, Buffer); +} + +VOID * +EFIAPI +AllocateZeroPool ( + UINTN AllocationSize ) { - if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) || - (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) { - return TRUE; + VOID * Memory; + Memory = malloc(AllocationSize); + ASSERT (Memory != NULL); + if (Memory == NULL) { + fprintf(stderr, "Not memory for malloc\n"); } - return FALSE; + memset(Memory, 0, AllocationSize); + return Memory; } -BOOLEAN -InternalSafeStringNoStrOverlap ( - IN CHAR16 *Str1, - IN UINTN Size1, - IN CHAR16 *Str2, - IN UINTN Size2 +VOID * +EFIAPI +AllocatePool ( + UINTN AllocationSize ) { - return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16)); + return InternalAllocatePool (AllocationSize); } /** - Convert a Null-terminated Unicode decimal string to a value of type UINT64. - - This function outputs a value of type UINT64 by interpreting the contents of - the Unicode string specified by String as a decimal number. The format of the - input Unicode string String is: - - [spaces] [decimal digits]. - - The valid decimal digit character is in the range [0-9]. The function will - ignore the pad space, which includes spaces or tab characters, before - [decimal digits]. The running zero in the beginning of [decimal digits] will - be ignored. Then, the function stops at the first character that is a not a - valid decimal character or a Null-terminator, whichever one comes first. - - If String is NULL, then ASSERT(). - If Data is NULL, then ASSERT(). - If String is not aligned in a 16-bit boundary, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and String contains more than - PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - - If String has no valid decimal digits in the above format, then 0 is stored - at the location pointed to by Data. - If the number represented by String exceeds the range defined by UINT64, then - MAX_UINT64 is stored at the location pointed to by Data. - - If EndPointer is not NULL, a pointer to the character that stopped the scan - is stored at the location pointed to by EndPointer. If String has no valid - decimal digits right after the optional pad spaces, the value of String is - stored at the location pointed to by EndPointer. - - @param String Pointer to a Null-terminated Unicode string. - @param EndPointer Pointer to character that stops scan. - @param Data Pointer to the converted value. - - @retval RETURN_SUCCESS Value is translated from String. - @retval RETURN_INVALID_PARAMETER If String is NULL. - If Data is NULL. - If PcdMaximumUnicodeStringLength is not - zero, and String contains more than - PcdMaximumUnicodeStringLength Unicode - characters, not including the - Null-terminator. - @retval RETURN_UNSUPPORTED If the number represented by String exceeds - the range defined by UINT64. + Return whether the integer string is a hex string. + + @param Str The integer string + + @retval TRUE Hex string + @retval FALSE Decimal string **/ -RETURN_STATUS -StrDecimalToUint64S ( - CONST CHAR16 *String, - CHAR16 **EndPointer, OPTIONAL - UINT64 *Data +BOOLEAN +IsHexStr ( + CHAR16 *Str ) { - ASSERT (((UINTN) String & BIT0) == 0); - // - // 1. Neither String nor Data shall be a null pointer. - // - SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); - SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER); - - // - // 2. The length of String shall not be greater than RSIZE_MAX. + // skip preceding white space // - if (RSIZE_MAX != 0) { - SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); - } - - if (EndPointer != NULL) { - *EndPointer = (CHAR16 *) String; + while ((*Str != 0) && *Str == L' ') { + Str ++; } - // - // Ignore the pad spaces (space or tab) + // skip preceding zeros // - while ((*String == L' ') || (*String == L'\t')) { - String++; + while ((*Str != 0) && *Str == L'0') { + Str ++; } - // - // Ignore leading Zeros after the spaces - // - while (*String == L'0') { - String++; - } + return (BOOLEAN) (*Str == L'x' || *Str == L'X'); +} - *Data = 0; +/** - while (InternalIsDecimalDigitCharacter (*String)) { - // - // If the number represented by String overflows according to the range - // defined by UINT64, then MAX_UINT64 is stored in *Data and - // RETURN_UNSUPPORTED is returned. - // - if (*Data > ((MAX_UINT64 - (*String - L'0'))/10)) { - *Data = MAX_UINT64; - if (EndPointer != NULL) { - *EndPointer = (CHAR16 *) String; - } - return RETURN_UNSUPPORTED; - } + Convert integer string to uint. - *Data = (*Data) * 10 + (*String - L'0'); - String++; - } + @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal. + + @return A UINTN value represented by Str - if (EndPointer != NULL) { - *EndPointer = (CHAR16 *) String; +**/ +UINTN +Strtoi ( + CHAR16 *Str + ) +{ + if (IsHexStr (Str)) { + return (UINTN)StrHexToUint64 (Str); + } else { + return (UINTN)StrDecimalToUint64 (Str); } - return RETURN_SUCCESS; } /** - Convert a Null-terminated Unicode hexadecimal string to a value of type - UINT64. - - This function outputs a value of type UINT64 by interpreting the contents of - the Unicode string specified by String as a hexadecimal number. The format of - the input Unicode string String is: - - [spaces][zeros][x][hexadecimal digits]. - - The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F]. - The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. - If "x" appears in the input string, it must be prefixed with at least one 0. - The function will ignore the pad space, which includes spaces or tab - characters, before [zeros], [x] or [hexadecimal digit]. The running zero - before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts - after [x] or the first valid hexadecimal digit. Then, the function stops at - the first character that is a not a valid hexadecimal character or NULL, - whichever one comes first. - - If String is NULL, then ASSERT(). - If Data is NULL, then ASSERT(). - If String is not aligned in a 16-bit boundary, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and String contains more than - PcdMaximumUnicodeStringLength Unicode characters, not including the - Null-terminator, then ASSERT(). - - If String has no valid hexadecimal digits in the above format, then 0 is - stored at the location pointed to by Data. - If the number represented by String exceeds the range defined by UINT64, then - MAX_UINT64 is stored at the location pointed to by Data. - - If EndPointer is not NULL, a pointer to the character that stopped the scan - is stored at the location pointed to by EndPointer. If String has no valid - hexadecimal digits right after the optional pad spaces, the value of String - is stored at the location pointed to by EndPointer. - - @param String Pointer to a Null-terminated Unicode string. - @param EndPointer Pointer to character that stops scan. - @param Data Pointer to the converted value. - - @retval RETURN_SUCCESS Value is translated from String. - @retval RETURN_INVALID_PARAMETER If String is NULL. - If Data is NULL. - If PcdMaximumUnicodeStringLength is not - zero, and String contains more than - PcdMaximumUnicodeStringLength Unicode - characters, not including the - Null-terminator. - @retval RETURN_UNSUPPORTED If the number represented by String exceeds - the range defined by UINT64. + + Convert integer string to 64 bit data. + + @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal. + @param Data A pointer to the UINT64 value represented by Str **/ -RETURN_STATUS -StrHexToUint64S ( - CONST CHAR16 *String, - CHAR16 **EndPointer, OPTIONAL - UINT64 *Data +VOID +Strtoi64 ( + CHAR16 *Str, + UINT64 *Data ) { - ASSERT (((UINTN) String & BIT0) == 0); + if (IsHexStr (Str)) { + *Data = StrHexToUint64 (Str); + } else { + *Data = StrDecimalToUint64 (Str); + } +} - // - // 1. Neither String nor Data shall be a null pointer. - // - SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); - SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER); +/** + Converts a Unicode string to ASCII string. - // - // 2. The length of String shall not be greater than RSIZE_MAX. - // - if (RSIZE_MAX != 0) { - SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER); - } + @param Str The equivalent Unicode string + @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points + to the next ASCII string next to it - if (EndPointer != NULL) { - *EndPointer = (CHAR16 *) String; - } +**/ +VOID +StrToAscii ( + CHAR16 *Str, + CHAR8 **AsciiStr + ) +{ + CHAR8 *Dest; - // - // Ignore the pad spaces (space or tab) - // - while ((*String == L' ') || (*String == L'\t')) { - String++; + Dest = *AsciiStr; + while (!IS_NULL (*Str)) { + *(Dest++) = (CHAR8) *(Str++); } + *Dest = 0; // - // Ignore leading Zeros after the spaces + // Return the string next to it // - while (*String == L'0') { - String++; - } - - if (InternalCharToUpper (*String) == L'X') { - if (*(String - 1) != L'0') { - *Data = 0; - return RETURN_SUCCESS; - } - // - // Skip the 'X' - // - String++; - } - - *Data = 0; + *AsciiStr = Dest + 1; +} - while (InternalIsHexaDecimalDigitCharacter (*String)) { - // - // If the number represented by String overflows according to the range - // defined by UINT64, then MAX_UINT64 is stored in *Data and - // RETURN_UNSUPPORTED is returned. - // - if (*Data > ((MAX_UINT64 - InternalHexCharToUintn (*String))>>4)) { - *Data = MAX_UINT64; - if (EndPointer != NULL) { - *EndPointer = (CHAR16 *) String; - } - return RETURN_UNSUPPORTED; - } +/** + Gets current sub-string from a string list, before return + the list header is moved to next sub-string. The sub-string is separated + by the specified character. For example, the separator is ',', the string + list is "2,0,3", it returns "2", the remain list move to "0,3" - *Data = ((*Data) << 4) + InternalHexCharToUintn (*String); - String++; - } + @param List A string list separated by the specified separator + @param Separator The separator character - if (EndPointer != NULL) { - *EndPointer = (CHAR16 *) String; - } - return RETURN_SUCCESS; -} + @return A pointer to the current sub-string -UINT64 -StrDecimalToUint64 ( - CONST CHAR16 *String - ) -{ - UINT64 Result; - - StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result); - return Result; -} - - -UINT64 -StrHexToUint64 ( - CONST CHAR16 *String - ) -{ - UINT64 Result; - - StrHexToUint64S (String, (CHAR16 **) NULL, &Result); - return Result; -} - -UINTN -StrSize ( - CONST CHAR16 *String - ) -{ - return (StrLen (String) + 1) * sizeof (*String); -} - - -UINT64 -ReadUnaligned64 ( - CONST UINT64 *Buffer - ) -{ - ASSERT (Buffer != NULL); - - return *Buffer; -} - -UINT64 -WriteUnaligned64 ( - UINT64 *Buffer, - UINT64 Value - ) -{ - ASSERT (Buffer != NULL); - - return *Buffer = Value; -} - - -EFI_GUID * -CopyGuid ( - EFI_GUID *DestinationGuid, - CONST EFI_GUID *SourceGuid - ) -{ - WriteUnaligned64 ( - (UINT64*)DestinationGuid, - ReadUnaligned64 ((CONST UINT64*)SourceGuid) - ); - WriteUnaligned64 ( - (UINT64*)DestinationGuid + 1, - ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1) - ); - return DestinationGuid; -} - -UINT16 -SwapBytes16 ( - UINT16 Value - ) -{ - return (UINT16) ((Value<< 8) | (Value>> 8)); -} - - -UINT32 -SwapBytes32 ( - UINT32 Value - ) -{ - UINT32 LowerBytes; - UINT32 HigherBytes; - - LowerBytes = (UINT32) SwapBytes16 ((UINT16) Value); - HigherBytes = (UINT32) SwapBytes16 ((UINT16) (Value >> 16)); - return (LowerBytes << 16 | HigherBytes); -} - -BOOLEAN -InternalIsDecimalDigitCharacter ( - CHAR16 Char - ) -{ - return (BOOLEAN) (Char >= L'0' && Char <= L'9'); -} - -VOID * -InternalAllocateCopyPool ( - UINTN AllocationSize, - CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - - Memory = malloc (AllocationSize); - if (Memory != NULL) { - Memory = memcpy (Memory, Buffer, AllocationSize); - } - return Memory; -} - -BOOLEAN -InternalIsHexaDecimalDigitCharacter ( - CHAR16 Char - ) -{ - - return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) || - (Char >= L'A' && Char <= L'F') || - (Char >= L'a' && Char <= L'f')); -} - -UINTN -InternalHexCharToUintn ( - CHAR16 Char - ) -{ - if (InternalIsDecimalDigitCharacter (Char)) { - return Char - L'0'; - } - - return (10 + InternalCharToUpper (Char) - L'A'); -} - - -/** - Convert a Null-terminated Unicode hexadecimal string to a byte array. - - This function outputs a byte array by interpreting the contents of - the Unicode string specified by String in hexadecimal format. The format of - the input Unicode string String is: - - [XX]* - - X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F]. - The function decodes every two hexadecimal digit characters as one byte. The - decoding stops after Length of characters and outputs Buffer containing - (Length / 2) bytes. - - If String is not aligned in a 16-bit boundary, then ASSERT(). - - If String is NULL, then ASSERT(). - - If Buffer is NULL, then ASSERT(). - - If Length is not multiple of 2, then ASSERT(). - - If PcdMaximumUnicodeStringLength is not zero and Length is greater than - PcdMaximumUnicodeStringLength, then ASSERT(). - - If MaxBufferSize is less than (Length / 2), then ASSERT(). - - @param String Pointer to a Null-terminated Unicode string. - @param Length The number of Unicode characters to decode. - @param Buffer Pointer to the converted bytes array. - @param MaxBufferSize The maximum size of Buffer. - - @retval RETURN_SUCCESS Buffer is translated from String. - @retval RETURN_INVALID_PARAMETER If String is NULL. - If Data is NULL. - If Length is not multiple of 2. - If PcdMaximumUnicodeStringLength is not zero, - and Length is greater than - PcdMaximumUnicodeStringLength. - @retval RETURN_UNSUPPORTED If Length of characters from String contain - a character that is not valid hexadecimal - digit characters, or a Null-terminator. - @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2). -**/ -RETURN_STATUS -StrHexToBytes ( - CONST CHAR16 *String, - UINTN Length, - UINT8 *Buffer, - UINTN MaxBufferSize - ) -{ - UINTN Index; - - ASSERT (((UINTN) String & BIT0) == 0); - - // - // 1. None of String or Buffer shall be a null pointer. - // - SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); - SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER); - - // - // 2. Length shall not be greater than RSIZE_MAX. - // - if (RSIZE_MAX != 0) { - SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER); - } - - // - // 3. Length shall not be odd. - // - SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER); - - // - // 4. MaxBufferSize shall equal to or greater than Length / 2. - // - SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL); - - // - // 5. String shall not contains invalid hexadecimal digits. - // - for (Index = 0; Index < Length; Index++) { - if (!InternalIsHexaDecimalDigitCharacter (String[Index])) { - break; - } - } - if (Index != Length) { - return RETURN_UNSUPPORTED; - } - - // - // Convert the hex string to bytes. - // - for(Index = 0; Index < Length; Index++) { - - // - // For even characters, write the upper nibble for each buffer byte, - // and for even characters, the lower nibble. - // - if ((Index & BIT0) == 0) { - Buffer[Index / 2] = (UINT8) InternalHexCharToUintn (String[Index]) << 4; - } else { - Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]); - } - } - return RETURN_SUCCESS; -} - -/** - Convert a Null-terminated Unicode GUID string to a value of type - EFI_GUID. - - This function outputs a GUID value by interpreting the contents of - the Unicode string specified by String. The format of the input - Unicode string String consists of 36 characters, as follows: - - aabbccdd-eeff-gghh-iijj-kkllmmnnoopp - - The pairs aa - pp are two characters in the range [0-9], [a-f] and - [A-F], with each pair representing a single byte hexadecimal value. - - The mapping between String and the EFI_GUID structure is as follows: - aa Data1[24:31] - bb Data1[16:23] - cc Data1[8:15] - dd Data1[0:7] - ee Data2[8:15] - ff Data2[0:7] - gg Data3[8:15] - hh Data3[0:7] - ii Data4[0:7] - jj Data4[8:15] - kk Data4[16:23] - ll Data4[24:31] - mm Data4[32:39] - nn Data4[40:47] - oo Data4[48:55] - pp Data4[56:63] - - If String is NULL, then ASSERT(). - If Guid is NULL, then ASSERT(). - If String is not aligned in a 16-bit boundary, then ASSERT(). - - @param String Pointer to a Null-terminated Unicode string. - @param Guid Pointer to the converted GUID. - - @retval RETURN_SUCCESS Guid is translated from String. - @retval RETURN_INVALID_PARAMETER If String is NULL. - If Data is NULL. - @retval RETURN_UNSUPPORTED If String is not as the above format. - -**/ -RETURN_STATUS -StrToGuid ( - CONST CHAR16 *String, - EFI_GUID *Guid - ) -{ - RETURN_STATUS Status; - EFI_GUID LocalGuid; - - ASSERT (((UINTN) String & BIT0) == 0); - - // - // 1. None of String or Guid shall be a null pointer. - // - SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); - SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER); - - // - // Get aabbccdd in big-endian. - // - Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1)); - if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') { - return RETURN_UNSUPPORTED; - } - // - // Convert big-endian to little-endian. - // - LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1); - String += 2 * sizeof (LocalGuid.Data1) + 1; - - // - // Get eeff in big-endian. - // - Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2)); - if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') { - return RETURN_UNSUPPORTED; - } - // - // Convert big-endian to little-endian. - // - LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2); - String += 2 * sizeof (LocalGuid.Data2) + 1; - - // - // Get gghh in big-endian. - // - Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3)); - if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') { - return RETURN_UNSUPPORTED; - } - // - // Convert big-endian to little-endian. - // - LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3); - String += 2 * sizeof (LocalGuid.Data3) + 1; - - // - // Get iijj. - // - Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2); - if (RETURN_ERROR (Status) || String[2 * 2] != L'-') { - return RETURN_UNSUPPORTED; - } - String += 2 * 2 + 1; - - // - // Get kkllmmnnoopp. - // - Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6); - if (RETURN_ERROR (Status)) { - return RETURN_UNSUPPORTED; - } - - CopyGuid (Guid, &LocalGuid); - return RETURN_SUCCESS; -} - -/** - Compares up to a specified length the contents of two Null-terminated Unicode strings, - and returns the difference between the first mismatched Unicode characters. - - This function compares the Null-terminated Unicode string FirstString to the - Null-terminated Unicode string SecondString. At most, Length Unicode - characters will be compared. If Length is 0, then 0 is returned. If - FirstString is identical to SecondString, then 0 is returned. Otherwise, the - value returned is the first mismatched Unicode character in SecondString - subtracted from the first mismatched Unicode character in FirstString. - - If Length > 0 and FirstString is NULL, then ASSERT(). - If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT(). - If Length > 0 and SecondString is NULL, then ASSERT(). - If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and Length is greater than - PcdMaximumUnicodeStringLength, then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than - PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator, - then ASSERT(). - If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than - PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator, - then ASSERT(). - - @param FirstString A pointer to a Null-terminated Unicode string. - @param SecondString A pointer to a Null-terminated Unicode string. - @param Length The maximum number of Unicode characters to compare. - - @retval 0 FirstString is identical to SecondString. - @return others FirstString is not identical to SecondString. - -**/ -INTN -StrnCmp ( - CONST CHAR16 *FirstString, - CONST CHAR16 *SecondString, - UINTN Length - ) -{ - if (Length == 0) { - return 0; - } - - // - // ASSERT both strings are less long than PcdMaximumUnicodeStringLength. - // Length tests are performed inside StrLen(). - // - ASSERT (StrSize (FirstString) != 0); - ASSERT (StrSize (SecondString) != 0); - - while ((*FirstString != L'\0') && - (*SecondString != L'\0') && - (*FirstString == *SecondString) && - (Length > 1)) { - FirstString++; - SecondString++; - Length--; - } - - return *FirstString - *SecondString; -} - -VOID * -AllocateCopyPool ( - UINTN AllocationSize, - CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (AllocationSize, Buffer); -} - -INTN -StrCmp ( - CONST CHAR16 *FirstString, - CONST CHAR16 *SecondString - ) -{ - // - // ASSERT both strings are less long than PcdMaximumUnicodeStringLength - // - ASSERT (StrSize (FirstString) != 0); - ASSERT (StrSize (SecondString) != 0); - - while ((*FirstString != L'\0') && (*FirstString == *SecondString)) { - FirstString++; - SecondString++; - } - return *FirstString - *SecondString; -} - -UINT64 -SwapBytes64 ( - UINT64 Value - ) -{ - return InternalMathSwapBytes64 (Value); -} - -UINT64 -InternalMathSwapBytes64 ( - UINT64 Operand - ) -{ - UINT64 LowerBytes; - UINT64 HigherBytes; - - LowerBytes = (UINT64) SwapBytes32 ((UINT32) Operand); - HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32)); - - return (LowerBytes << 32 | HigherBytes); -} - -RETURN_STATUS -StrToIpv4Address ( - CONST CHAR16 *String, - CHAR16 **EndPointer, - EFI_IPv4_ADDRESS *Address, - UINT8 *PrefixLength - ) -{ - RETURN_STATUS Status; - UINTN AddressIndex; - UINT64 Uint64; - EFI_IPv4_ADDRESS LocalAddress; - UINT8 LocalPrefixLength; - CHAR16 *Pointer; - - LocalPrefixLength = MAX_UINT8; - LocalAddress.Addr[0] = 0; - - ASSERT (((UINTN) String & BIT0) == 0); - - // - // 1. None of String or Guid shall be a null pointer. - // - SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); - SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER); - - for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) { - if (!InternalIsDecimalDigitCharacter (*Pointer)) { - // - // D or P contains invalid characters. - // - break; - } - - // - // Get D or P. - // - Status = StrDecimalToUint64S ((CONST CHAR16 *) Pointer, &Pointer, &Uint64); - if (RETURN_ERROR (Status)) { - return RETURN_UNSUPPORTED; - } - if (AddressIndex == ARRAY_SIZE (Address->Addr)) { - // - // It's P. - // - if (Uint64 > 32) { - return RETURN_UNSUPPORTED; - } - LocalPrefixLength = (UINT8) Uint64; - } else { - // - // It's D. - // - if (Uint64 > MAX_UINT8) { - return RETURN_UNSUPPORTED; - } - LocalAddress.Addr[AddressIndex] = (UINT8) Uint64; - AddressIndex++; - } - - // - // Check the '.' or '/', depending on the AddressIndex. - // - if (AddressIndex == ARRAY_SIZE (Address->Addr)) { - if (*Pointer == L'/') { - // - // '/P' is in the String. - // Skip "/" and get P in next loop. - // - Pointer++; - } else { - // - // '/P' is not in the String. - // - break; - } - } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) { - if (*Pointer == L'.') { - // - // D should be followed by '.' - // - Pointer++; - } else { - return RETURN_UNSUPPORTED; - } - } - } - - if (AddressIndex < ARRAY_SIZE (Address->Addr)) { - return RETURN_UNSUPPORTED; - } - - memcpy (Address, &LocalAddress, sizeof (*Address)); - if (PrefixLength != NULL) { - *PrefixLength = LocalPrefixLength; - } - if (EndPointer != NULL) { - *EndPointer = Pointer; - } - - return RETURN_SUCCESS; -} - -RETURN_STATUS -StrToIpv6Address ( - CONST CHAR16 *String, - CHAR16 **EndPointer, - EFI_IPv6_ADDRESS *Address, - UINT8 *PrefixLength - ) -{ - RETURN_STATUS Status; - UINTN AddressIndex; - UINT64 Uint64; - EFI_IPv6_ADDRESS LocalAddress; - UINT8 LocalPrefixLength; - CONST CHAR16 *Pointer; - CHAR16 *End; - UINTN CompressStart; - BOOLEAN ExpectPrefix; - - LocalPrefixLength = MAX_UINT8; - CompressStart = ARRAY_SIZE (Address->Addr); - ExpectPrefix = FALSE; - - ASSERT (((UINTN) String & BIT0) == 0); - - // - // 1. None of String or Guid shall be a null pointer. - // - SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER); - SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER); - - for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) { - if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) { - if (*Pointer != L':') { - // - // ":" or "/" should be followed by digit characters. - // - return RETURN_UNSUPPORTED; - } - - // - // Meet second ":" after previous ":" or "/" - // or meet first ":" in the beginning of String. - // - if (ExpectPrefix) { - // - // ":" shall not be after "/" - // - return RETURN_UNSUPPORTED; - } - - if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) { - // - // "::" can only appear once. - // "::" can only appear when address is not full length. - // - return RETURN_UNSUPPORTED; - } else { - // - // Remember the start of zero compressing. - // - CompressStart = AddressIndex; - Pointer++; - - if (CompressStart == 0) { - if (*Pointer != L':') { - // - // Single ":" shall not be in the beginning of String. - // - return RETURN_UNSUPPORTED; - } - Pointer++; - } - } - } - - if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) { - if (*Pointer == L'/') { - // - // Might be optional "/P" after "::". - // - if (CompressStart != AddressIndex) { - return RETURN_UNSUPPORTED; - } - } else { - break; - } - } else { - if (!ExpectPrefix) { - // - // Get X. - // - Status = StrHexToUint64S (Pointer, &End, &Uint64); - if (RETURN_ERROR (Status) || End - Pointer > 4) { - // - // Number of hexadecimal digit characters is no more than 4. - // - return RETURN_UNSUPPORTED; - } - Pointer = End; - // - // Uint64 won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4. - // - ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr)); - LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uint64 >> 8); - LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uint64; - AddressIndex += 2; - } else { - // - // Get P, then exit the loop. - // - Status = StrDecimalToUint64S (Pointer, &End, &Uint64); - if (RETURN_ERROR (Status) || End == Pointer || Uint64 > 128) { - // - // Prefix length should not exceed 128. - // - return RETURN_UNSUPPORTED; - } - LocalPrefixLength = (UINT8) Uint64; - Pointer = End; - break; - } - } - - // - // Skip ':' or "/" - // - if (*Pointer == L'/') { - ExpectPrefix = TRUE; - } else if (*Pointer == L':') { - if (AddressIndex == ARRAY_SIZE (Address->Addr)) { - // - // Meet additional ":" after all 8 16-bit address - // - break; - } - } else { - // - // Meet other character that is not "/" or ":" after all 8 16-bit address - // - break; - } - Pointer++; - } - - if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) || - (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr)) - ) { - // - // Full length of address shall not have compressing zeros. - // Non-full length of address shall have compressing zeros. - // - return RETURN_UNSUPPORTED; - } - memcpy (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart); - if (AddressIndex > CompressStart) { - memset (&Address->Addr[CompressStart], 0, ARRAY_SIZE (Address->Addr) - AddressIndex); - memcpy ( - &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex], - &LocalAddress.Addr[CompressStart], - AddressIndex - CompressStart - ); - } - - if (PrefixLength != NULL) { - *PrefixLength = LocalPrefixLength; - } - if (EndPointer != NULL) { - *EndPointer = (CHAR16 *) Pointer; - } - - return RETURN_SUCCESS; -} - - -RETURN_STATUS -UnicodeStrToAsciiStrS ( - CONST CHAR16 *Source, - CHAR8 *Destination, - UINTN DestMax - ) -{ - UINTN SourceLen; - - ASSERT (((UINTN) Source & BIT0) == 0); - - // - // 1. Neither Destination nor Source shall be a null pointer. - // - SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER); - SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER); - - // - // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX. - // - if (ASCII_RSIZE_MAX != 0) { - SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER); - } - if (RSIZE_MAX != 0) { - SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); - } - - // - // 3. DestMax shall not equal zero. - // - SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER); - - // - // 4. DestMax shall be greater than StrnLenS (Source, DestMax). - // - SourceLen = StrnLenS (Source, DestMax); - SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); - - // - // 5. Copying shall not take place between objects that overlap. - // - SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED); - - // - // convert string - // - while (*Source != '\0') { - // - // If any Unicode characters in Source contain - // non-zero value in the upper 8 bits, then ASSERT(). - // - ASSERT (*Source < 0x100); - *(Destination++) = (CHAR8) *(Source++); - } - *Destination = '\0'; - - return RETURN_SUCCESS; -} - -RETURN_STATUS -StrCpyS ( - CHAR16 *Destination, - UINTN DestMax, - CONST CHAR16 *Source - ) -{ - UINTN SourceLen; - - ASSERT (((UINTN) Destination & BIT0) == 0); - ASSERT (((UINTN) Source & BIT0) == 0); - - // - // 1. Neither Destination nor Source shall be a null pointer. - // - SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER); - SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER); - - // - // 2. DestMax shall not be greater than RSIZE_MAX. - // - if (RSIZE_MAX != 0) { - SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER); - } - - // - // 3. DestMax shall not equal zero. - // - SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER); - - // - // 4. DestMax shall be greater than StrnLenS(Source, DestMax). - // - SourceLen = StrnLenS (Source, DestMax); - SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL); - - // - // 5. Copying shall not take place between objects that overlap. - // - SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED); - - // - // The StrCpyS function copies the string pointed to by Source (including the terminating - // null character) into the array pointed to by Destination. - // - while (*Source != 0) { - *(Destination++) = *(Source++); - } - *Destination = 0; - - return RETURN_SUCCESS; -} - -VOID * -AllocateZeroPool ( - UINTN AllocationSize - ) -{ - VOID * Memory; - Memory = malloc(AllocationSize); - ASSERT (Memory != NULL); - if (Memory == NULL) { - fprintf(stderr, "Not memory for malloc\n"); - } - memset(Memory, 0, AllocationSize); - return Memory; -} - -VOID * -AllocatePool ( - UINTN AllocationSize - ) -{ - return InternalAllocatePool (AllocationSize); -} - -UINT16 -WriteUnaligned16 ( - UINT16 *Buffer, - UINT16 Value - ) -{ - ASSERT (Buffer != NULL); - - return *Buffer = Value; -} - -UINT16 -ReadUnaligned16 ( - CONST UINT16 *Buffer - ) -{ - ASSERT (Buffer != NULL); - - return *Buffer; -} -/** - Return whether the integer string is a hex string. - - @param Str The integer string - - @retval TRUE Hex string - @retval FALSE Decimal string - -**/ -BOOLEAN -IsHexStr ( - CHAR16 *Str - ) -{ - // - // skip preceding white space - // - while ((*Str != 0) && *Str == L' ') { - Str ++; - } - // - // skip preceding zeros - // - while ((*Str != 0) && *Str == L'0') { - Str ++; - } - - return (BOOLEAN) (*Str == L'x' || *Str == L'X'); -} - -/** - - Convert integer string to uint. - - @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal. - - @return A UINTN value represented by Str - -**/ -UINTN -Strtoi ( - CHAR16 *Str - ) -{ - if (IsHexStr (Str)) { - return (UINTN)StrHexToUint64 (Str); - } else { - return (UINTN)StrDecimalToUint64 (Str); - } -} - -/** - - Convert integer string to 64 bit data. - - @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal. - @param Data A pointer to the UINT64 value represented by Str - -**/ -VOID -Strtoi64 ( - CHAR16 *Str, - UINT64 *Data - ) -{ - if (IsHexStr (Str)) { - *Data = StrHexToUint64 (Str); - } else { - *Data = StrDecimalToUint64 (Str); - } -} - -/** - Converts a Unicode string to ASCII string. - - @param Str The equivalent Unicode string - @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points - to the next ASCII string next to it - -**/ -VOID -StrToAscii ( - CHAR16 *Str, - CHAR8 **AsciiStr - ) -{ - CHAR8 *Dest; - - Dest = *AsciiStr; - while (!IS_NULL (*Str)) { - *(Dest++) = (CHAR8) *(Str++); - } - *Dest = 0; - - // - // Return the string next to it - // - *AsciiStr = Dest + 1; -} - -/** - Gets current sub-string from a string list, before return - the list header is moved to next sub-string. The sub-string is separated - by the specified character. For example, the separator is ',', the string - list is "2,0,3", it returns "2", the remain list move to "0,3" - - @param List A string list separated by the specified separator - @param Separator The separator character - - @return A pointer to the current sub-string - -**/ -CHAR16 * -SplitStr ( - CHAR16 **List, - CHAR16 Separator +**/ +CHAR16 * +SplitStr ( + CHAR16 **List, + CHAR16 Separator ) { CHAR16 *Str; @@ -2088,3 +728,21 @@ SplitStr ( *List = Str; return ReturnStr; } + +VOID +EFIAPI +CpuBreakpoint ( + VOID + ) +{ + abort (); +} + +VOID +EFIAPI +CpuDeadLoop ( + VOID + ) +{ + abort (); +} diff --git a/BaseTools/Source/C/Common/CommonLib.h b/BaseTools/Source/C/Common/CommonLib.h index a841029c2a..923f936e4f 100644 --- a/BaseTools/Source/C/Common/CommonLib.h +++ b/BaseTools/Source/C/Common/CommonLib.h @@ -16,6 +16,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #endif +#include +#include +#include +#include + #define PRINTED_GUID_BUFFER_SIZE 37 // including null-termination #ifdef PATH_MAX @@ -41,8 +46,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define IS_SLASH(a) ((a) == L'/') #define IS_NULL(a) ((a) == L'\0') -#define ASSERT(x) assert(x) - #ifdef __cplusplus extern "C" { #endif @@ -50,38 +53,8 @@ extern "C" { // // Function declarations // -VOID -PeiZeroMem ( - IN VOID *Buffer, - IN UINTN Size - ) -; - -VOID -PeiCopyMem ( - IN VOID *Destination, - IN VOID *Source, - IN UINTN Length - ) -; - -VOID -ZeroMem ( - IN VOID *Buffer, - IN UINTN Size - ) -; - -VOID -CopyMem ( - IN VOID *Destination, - IN VOID *Source, - IN UINTN Length - ) -; - INTN -CompareGuid ( +BtCompareGuid ( IN EFI_GUID *Guid1, IN EFI_GUID *Guid2 ) @@ -95,26 +68,6 @@ GetFileImage ( ) ; -/*++ - -Routine Description: - - This function opens a file and writes OutputFileImage into the file. - -Arguments: - - OutputFileName The name of the file to write. - OutputFileImage A pointer to the memory buffer. - BytesToWrite The size of the memory buffer. - -Returns: - - EFI_SUCCESS The function completed successfully. - EFI_INVALID_PARAMETER One of the input parameters was invalid. - EFI_ABORTED An error occurred. - EFI_OUT_OF_RESOURCES No resource to complete operations. - -**/ EFI_STATUS PutFileImage ( IN CHAR8 *OutputFileName, @@ -123,29 +76,17 @@ PutFileImage ( ) ; -UINT8 -CalculateChecksum8 ( - IN UINT8 *Buffer, - IN UINTN Size - ) -; - -UINT8 -CalculateSum8 ( - IN UINT8 *Buffer, - IN UINTN Size - ) -; +#define CalculateChecksum8 CalculateCheckSum8 UINT16 -CalculateChecksum16 ( +BtCalculateChecksum16 ( IN UINT16 *Buffer, IN UINTN Size ) ; UINT16 -CalculateSum16 ( +BtCalculateSum16 ( IN UINT16 *Buffer, IN UINTN Size ) @@ -172,231 +113,6 @@ LongFilePath ( IN CHAR8 *FileName ); -UINTN -StrLen ( - CONST CHAR16 *String - ); - -VOID * -AllocateCopyPool ( - UINTN AllocationSize, - CONST VOID *Buffer - ); - -INTN -StrnCmp ( - CONST CHAR16 *FirstString, - CONST CHAR16 *SecondString, - UINTN Length - ); - -RETURN_STATUS -StrToGuid ( - CONST CHAR16 *String, - EFI_GUID *Guid - ); - -RETURN_STATUS -StrHexToBytes ( - CONST CHAR16 *String, - UINTN Length, - UINT8 *Buffer, - UINTN MaxBufferSize - ); - -UINTN -InternalHexCharToUintn ( - CHAR16 Char - ); - -VOID * -InternalAllocateCopyPool ( - UINTN AllocationSize, - CONST VOID *Buffer - ); - -BOOLEAN -InternalIsDecimalDigitCharacter ( - CHAR16 Char - ); - -UINT32 -SwapBytes32 ( - UINT32 Value - ); - -UINT16 -SwapBytes16 ( - UINT16 Value - ); - -EFI_GUID * -CopyGuid ( - EFI_GUID *DestinationGuid, - CONST EFI_GUID *SourceGuid - ); - -UINT64 -WriteUnaligned64 ( - UINT64 *Buffer, - UINT64 Value - ); - -UINT64 -ReadUnaligned64 ( - CONST UINT64 *Buffer - ); - -UINTN -StrSize ( - CONST CHAR16 *String - ); - -UINT64 -StrHexToUint64 ( - CONST CHAR16 *String - ); - -UINT64 -StrDecimalToUint64 ( - CONST CHAR16 *String - ); - -RETURN_STATUS -StrHexToUint64S ( - CONST CHAR16 *String, - CHAR16 **EndPointer, - UINT64 *Data - ); - -RETURN_STATUS -StrDecimalToUint64S ( - CONST CHAR16 *String, - CHAR16 **EndPointer, OPTIONAL - UINT64 *Data - ); - -VOID * -ReallocatePool ( - UINTN OldSize, - UINTN NewSize, - VOID *OldBuffer OPTIONAL - ); - -VOID * -InternalReallocatePool ( - UINTN OldSize, - UINTN NewSize, - VOID *OldBuffer OPTIONAL - ); - -VOID * -InternalAllocateZeroPool ( - UINTN AllocationSize - ) ; - -VOID * -InternalAllocatePool ( - UINTN AllocationSize - ); - -UINTN -StrnLenS ( - CONST CHAR16 *String, - UINTN MaxSize - ); - -CHAR16 -InternalCharToUpper ( - CHAR16 Char - ); - -INTN -StrCmp ( - CONST CHAR16 *FirstString, - CONST CHAR16 *SecondString - ); - -UINT64 -SwapBytes64 ( - UINT64 Value - ); - -UINT64 -InternalMathSwapBytes64 ( - UINT64 Operand - ); - -RETURN_STATUS -StrToIpv4Address ( - CONST CHAR16 *String, - CHAR16 **EndPointer, - EFI_IPv4_ADDRESS *Address, - UINT8 *PrefixLength - ); - -RETURN_STATUS -StrToIpv6Address ( - CONST CHAR16 *String, - CHAR16 **EndPointer, - EFI_IPv6_ADDRESS *Address, - UINT8 *PrefixLength - ); - -RETURN_STATUS -StrCpyS ( - CHAR16 *Destination, - UINTN DestMax, - CONST CHAR16 *Source - ); - -RETURN_STATUS -UnicodeStrToAsciiStrS ( - CONST CHAR16 *Source, - CHAR8 *Destination, - UINTN DestMax - ); -VOID * -AllocatePool ( - UINTN AllocationSize - ); - -UINT16 -WriteUnaligned16 ( - UINT16 *Buffer, - UINT16 Value - ); - -UINT16 -ReadUnaligned16 ( - CONST UINT16 *Buffer - ); - -VOID * -AllocateZeroPool ( - UINTN AllocationSize - ); - -BOOLEAN -InternalIsHexaDecimalDigitCharacter ( - CHAR16 Char - ); - -BOOLEAN -InternalSafeStringIsOverlap ( - IN VOID *Base1, - IN UINTN Size1, - IN VOID *Base2, - IN UINTN Size2 - ); - -BOOLEAN -InternalSafeStringNoStrOverlap ( - IN CHAR16 *Str1, - IN UINTN Size1, - IN CHAR16 *Str2, - IN UINTN Size2 - ); BOOLEAN IsHexStr ( diff --git a/BaseTools/Source/C/Common/Crc32.c b/BaseTools/Source/C/Common/Crc32.c index 00cae94898..7c79e4d7de 100644 --- a/BaseTools/Source/C/Common/Crc32.c +++ b/BaseTools/Source/C/Common/Crc32.c @@ -1,5 +1,5 @@ /** @file -CalculateCrc32 routine. +BtCalculateCrc32 routine. Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -7,299 +7,41 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include +#include +#include #include "Crc32.h" -UINT32 mCrcTable[256] = { - 0x00000000, - 0x77073096, - 0xEE0E612C, - 0x990951BA, - 0x076DC419, - 0x706AF48F, - 0xE963A535, - 0x9E6495A3, - 0x0EDB8832, - 0x79DCB8A4, - 0xE0D5E91E, - 0x97D2D988, - 0x09B64C2B, - 0x7EB17CBD, - 0xE7B82D07, - 0x90BF1D91, - 0x1DB71064, - 0x6AB020F2, - 0xF3B97148, - 0x84BE41DE, - 0x1ADAD47D, - 0x6DDDE4EB, - 0xF4D4B551, - 0x83D385C7, - 0x136C9856, - 0x646BA8C0, - 0xFD62F97A, - 0x8A65C9EC, - 0x14015C4F, - 0x63066CD9, - 0xFA0F3D63, - 0x8D080DF5, - 0x3B6E20C8, - 0x4C69105E, - 0xD56041E4, - 0xA2677172, - 0x3C03E4D1, - 0x4B04D447, - 0xD20D85FD, - 0xA50AB56B, - 0x35B5A8FA, - 0x42B2986C, - 0xDBBBC9D6, - 0xACBCF940, - 0x32D86CE3, - 0x45DF5C75, - 0xDCD60DCF, - 0xABD13D59, - 0x26D930AC, - 0x51DE003A, - 0xC8D75180, - 0xBFD06116, - 0x21B4F4B5, - 0x56B3C423, - 0xCFBA9599, - 0xB8BDA50F, - 0x2802B89E, - 0x5F058808, - 0xC60CD9B2, - 0xB10BE924, - 0x2F6F7C87, - 0x58684C11, - 0xC1611DAB, - 0xB6662D3D, - 0x76DC4190, - 0x01DB7106, - 0x98D220BC, - 0xEFD5102A, - 0x71B18589, - 0x06B6B51F, - 0x9FBFE4A5, - 0xE8B8D433, - 0x7807C9A2, - 0x0F00F934, - 0x9609A88E, - 0xE10E9818, - 0x7F6A0DBB, - 0x086D3D2D, - 0x91646C97, - 0xE6635C01, - 0x6B6B51F4, - 0x1C6C6162, - 0x856530D8, - 0xF262004E, - 0x6C0695ED, - 0x1B01A57B, - 0x8208F4C1, - 0xF50FC457, - 0x65B0D9C6, - 0x12B7E950, - 0x8BBEB8EA, - 0xFCB9887C, - 0x62DD1DDF, - 0x15DA2D49, - 0x8CD37CF3, - 0xFBD44C65, - 0x4DB26158, - 0x3AB551CE, - 0xA3BC0074, - 0xD4BB30E2, - 0x4ADFA541, - 0x3DD895D7, - 0xA4D1C46D, - 0xD3D6F4FB, - 0x4369E96A, - 0x346ED9FC, - 0xAD678846, - 0xDA60B8D0, - 0x44042D73, - 0x33031DE5, - 0xAA0A4C5F, - 0xDD0D7CC9, - 0x5005713C, - 0x270241AA, - 0xBE0B1010, - 0xC90C2086, - 0x5768B525, - 0x206F85B3, - 0xB966D409, - 0xCE61E49F, - 0x5EDEF90E, - 0x29D9C998, - 0xB0D09822, - 0xC7D7A8B4, - 0x59B33D17, - 0x2EB40D81, - 0xB7BD5C3B, - 0xC0BA6CAD, - 0xEDB88320, - 0x9ABFB3B6, - 0x03B6E20C, - 0x74B1D29A, - 0xEAD54739, - 0x9DD277AF, - 0x04DB2615, - 0x73DC1683, - 0xE3630B12, - 0x94643B84, - 0x0D6D6A3E, - 0x7A6A5AA8, - 0xE40ECF0B, - 0x9309FF9D, - 0x0A00AE27, - 0x7D079EB1, - 0xF00F9344, - 0x8708A3D2, - 0x1E01F268, - 0x6906C2FE, - 0xF762575D, - 0x806567CB, - 0x196C3671, - 0x6E6B06E7, - 0xFED41B76, - 0x89D32BE0, - 0x10DA7A5A, - 0x67DD4ACC, - 0xF9B9DF6F, - 0x8EBEEFF9, - 0x17B7BE43, - 0x60B08ED5, - 0xD6D6A3E8, - 0xA1D1937E, - 0x38D8C2C4, - 0x4FDFF252, - 0xD1BB67F1, - 0xA6BC5767, - 0x3FB506DD, - 0x48B2364B, - 0xD80D2BDA, - 0xAF0A1B4C, - 0x36034AF6, - 0x41047A60, - 0xDF60EFC3, - 0xA867DF55, - 0x316E8EEF, - 0x4669BE79, - 0xCB61B38C, - 0xBC66831A, - 0x256FD2A0, - 0x5268E236, - 0xCC0C7795, - 0xBB0B4703, - 0x220216B9, - 0x5505262F, - 0xC5BA3BBE, - 0xB2BD0B28, - 0x2BB45A92, - 0x5CB36A04, - 0xC2D7FFA7, - 0xB5D0CF31, - 0x2CD99E8B, - 0x5BDEAE1D, - 0x9B64C2B0, - 0xEC63F226, - 0x756AA39C, - 0x026D930A, - 0x9C0906A9, - 0xEB0E363F, - 0x72076785, - 0x05005713, - 0x95BF4A82, - 0xE2B87A14, - 0x7BB12BAE, - 0x0CB61B38, - 0x92D28E9B, - 0xE5D5BE0D, - 0x7CDCEFB7, - 0x0BDBDF21, - 0x86D3D2D4, - 0xF1D4E242, - 0x68DDB3F8, - 0x1FDA836E, - 0x81BE16CD, - 0xF6B9265B, - 0x6FB077E1, - 0x18B74777, - 0x88085AE6, - 0xFF0F6A70, - 0x66063BCA, - 0x11010B5C, - 0x8F659EFF, - 0xF862AE69, - 0x616BFFD3, - 0x166CCF45, - 0xA00AE278, - 0xD70DD2EE, - 0x4E048354, - 0x3903B3C2, - 0xA7672661, - 0xD06016F7, - 0x4969474D, - 0x3E6E77DB, - 0xAED16A4A, - 0xD9D65ADC, - 0x40DF0B66, - 0x37D83BF0, - 0xA9BCAE53, - 0xDEBB9EC5, - 0x47B2CF7F, - 0x30B5FFE9, - 0xBDBDF21C, - 0xCABAC28A, - 0x53B39330, - 0x24B4A3A6, - 0xBAD03605, - 0xCDD70693, - 0x54DE5729, - 0x23D967BF, - 0xB3667A2E, - 0xC4614AB8, - 0x5D681B02, - 0x2A6F2B94, - 0xB40BBE37, - 0xC30C8EA1, - 0x5A05DF1B, - 0x2D02EF8D -}; - -/** - The CalculateCrc32 routine. - - @param Data The buffer containing the data to be processed - @param DataSize The size of data to be processed - @param CrcOut A pointer to the caller allocated UINT32 that on - contains the CRC32 checksum of Data - - @retval EFI_SUCCESS Calculation is successful. - @retval EFI_INVALID_PARAMETER Data / CrcOut = NULL, or DataSize = 0 -**/ EFI_STATUS -CalculateCrc32 ( +BtCalculateCrc32 ( IN UINT8 *Data, IN UINTN DataSize, IN OUT UINT32 *CrcOut ) -{ - UINT32 Crc; - UINTN Index; - UINT8 *Ptr; +/*++ + +Routine Description: + + The BtCalculateCrc32 routine. +Arguments: + + Data - The buffer containing the data to be processed + DataSize - The size of data to be processed + CrcOut - A pointer to the caller allocated UINT32 that on + contains the CRC32 checksum of Data + +Returns: + + EFI_SUCCESS - Calculation is successful. + EFI_INVALID_PARAMETER - Data / CrcOut = NULL, or DataSize = 0 + +--*/ +{ if ((DataSize == 0) || (Data == NULL) || (CrcOut == NULL)) { return EFI_INVALID_PARAMETER; } - Crc = 0xffffffff; - for (Index = 0, Ptr = Data; Index < DataSize; Index++, Ptr++) { - Crc = (Crc >> 8) ^ mCrcTable[(UINT8) Crc ^ *Ptr]; - } - - *CrcOut = Crc ^ 0xffffffff; + *CrcOut = CalculateCrc32 (Data, DataSize); return EFI_SUCCESS; } diff --git a/BaseTools/Source/C/Common/Crc32.h b/BaseTools/Source/C/Common/Crc32.h index 3f6b5b35fc..b57717f397 100644 --- a/BaseTools/Source/C/Common/Crc32.h +++ b/BaseTools/Source/C/Common/Crc32.h @@ -1,5 +1,5 @@ /** @file -Header file for CalculateCrc32 routine +Header file for BtCalculateCrc32 routine Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -23,11 +23,30 @@ SPDX-License-Identifier: BSD-2-Clause-Patent @retval EFI_INVALID_PARAMETER - Data / CrcOut = NULL, or DataSize = 0 **/ EFI_STATUS -CalculateCrc32 ( +BtCalculateCrc32 ( IN UINT8 *Data, IN UINTN DataSize, IN OUT UINT32 *CrcOut ) +/*++ + +Routine Description: + + The BtCalculateCrc32 routine. + +Arguments: + + Data - The buffer containing the data to be processed + DataSize - The size of data to be processed + CrcOut - A pointer to the caller allocated UINT32 that on + contains the CRC32 checksum of Data + +Returns: + + EFI_SUCCESS - Calculation is successful. + EFI_INVALID_PARAMETER - Data / CrcOut = NULL, or DataSize = 0 + +--*/ ; #endif diff --git a/BaseTools/Source/C/Common/DebugLib.c b/BaseTools/Source/C/Common/DebugLib.c new file mode 100644 index 0000000000..e385dec19e --- /dev/null +++ b/BaseTools/Source/C/Common/DebugLib.c @@ -0,0 +1,356 @@ +/** @file + BaseTools Debug Library that sends messages to the standard output. + + Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2023, Marvin Häuser. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +// +// Define the maximum debug and assert message length that this library supports +// +#define MAX_DEBUG_MESSAGE_LENGTH 0x100 + +// +// VA_LIST can not initialize to NULL for all compiler, so we use this to +// indicate a null VA_LIST +// +VA_LIST mVaListNull; + +/** + Prints a debug message to the debug output device if the specified error level is enabled. + + If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function + GetDebugPrintErrorLevel (), then print the message specified by Format and the + associated variable argument list to the debug output device. + + If Format is NULL, then ASSERT(). + + @param ErrorLevel The error level of the debug message. + @param Format Format string for the debug message to print. + @param ... A variable argument list whose contents are accessed + based on the format string specified by Format. + +**/ +VOID +EFIAPI +DebugPrint ( + IN UINTN ErrorLevel, + IN CONST CHAR8 *Format, + ... + ) +{ + VA_LIST Marker; + + VA_START (Marker, Format); + DebugVPrint (ErrorLevel, Format, Marker); + VA_END (Marker); +} + +/** + Prints a debug message to the debug output device if the specified + error level is enabled base on Null-terminated format string and a + VA_LIST argument list or a BASE_LIST argument list. + + If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function + GetDebugPrintErrorLevel (), then print the message specified by Format and + the associated variable argument list to the debug output device. + + If Format is NULL, then ASSERT(). + + @param ErrorLevel The error level of the debug message. + @param Format Format string for the debug message to print. + @param VaListMarker VA_LIST marker for the variable argument list. + @param BaseListMarker BASE_LIST marker for the variable argument list. + +**/ +VOID +DebugPrintMarker ( + IN UINTN ErrorLevel, + IN CONST CHAR8 *Format, + IN VA_LIST VaListMarker, + IN BASE_LIST BaseListMarker + ) +{ + CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; + + // + // If Format is NULL, then ASSERT(). + // + ASSERT (Format != NULL); + + // + // Check driver debug mask value and global mask + // + if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) { + return; + } + + // + // Convert the DEBUG() message to a Unicode String + // + if (BaseListMarker == NULL) { + AsciiVSPrint (Buffer, sizeof (Buffer), Format, VaListMarker); + } else { + AsciiBSPrint (Buffer, sizeof (Buffer), Format, BaseListMarker); + } + + // + // Send the print string to the Console Output device + // + printf("%s", Buffer); +} + +/** + Prints a debug message to the debug output device if the specified + error level is enabled. + + If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function + GetDebugPrintErrorLevel (), then print the message specified by Format and + the associated variable argument list to the debug output device. + + If Format is NULL, then ASSERT(). + + @param ErrorLevel The error level of the debug message. + @param Format Format string for the debug message to print. + @param VaListMarker VA_LIST marker for the variable argument list. + +**/ +VOID +EFIAPI +DebugVPrint ( + IN UINTN ErrorLevel, + IN CONST CHAR8 *Format, + IN VA_LIST VaListMarker + ) +{ + DebugPrintMarker (ErrorLevel, Format, VaListMarker, NULL); +} + +/** + Prints a debug message to the debug output device if the specified + error level is enabled. + This function use BASE_LIST which would provide a more compatible + service than VA_LIST. + + If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function + GetDebugPrintErrorLevel (), then print the message specified by Format and + the associated variable argument list to the debug output device. + + If Format is NULL, then ASSERT(). + + @param ErrorLevel The error level of the debug message. + @param Format Format string for the debug message to print. + @param BaseListMarker BASE_LIST marker for the variable argument list. + +**/ +VOID +EFIAPI +DebugBPrint ( + IN UINTN ErrorLevel, + IN CONST CHAR8 *Format, + IN BASE_LIST BaseListMarker + ) +{ + DebugPrintMarker (ErrorLevel, Format, mVaListNull, BaseListMarker); +} + +/** + Prints an assert message containing a filename, line number, and description. + This may be followed by a breakpoint or a dead loop. + + Print a message of the form "ASSERT (): \n" + to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of + PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if + DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then + CpuDeadLoop() is called. If neither of these bits are set, then this function + returns immediately after the message is printed to the debug output device. + DebugAssert() must actively prevent recursion. If DebugAssert() is called while + processing another DebugAssert(), then DebugAssert() must return immediately. + + If FileName is NULL, then a string of "(NULL) Filename" is printed. + If Description is NULL, then a string of "(NULL) Description" is printed. + + @param FileName The pointer to the name of the source file that generated + the assert condition. + @param LineNumber The line number in the source file that generated the + assert condition + @param Description The pointer to the description of the assert condition. + +**/ +VOID +EFIAPI +DebugAssert ( + IN CONST CHAR8 *FileName, + IN UINTN LineNumber, + IN CONST CHAR8 *Description + ) +{ + CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; + + // + // Generate the ASSERT() message in Unicode format + // + AsciiSPrint ( + Buffer, + sizeof (Buffer), + "ASSERT [%a] %a(%d): %a\n", + gEfiCallerBaseName, + FileName, + LineNumber, + Description + ); + + // + // Send the print string to the Console Output device + // + printf ("%s", Buffer); + + // + // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings + // + if ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) { + CpuBreakpoint (); + } else if ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) { + CpuDeadLoop (); + } +} + +/** + Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer. + + This function fills Length bytes of Buffer with the value specified by + PcdDebugClearMemoryValue, and returns Buffer. + + If Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param Buffer The pointer to the target buffer to be filled with PcdDebugClearMemoryValue. + @param Length The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. + + @return Buffer The pointer to the target buffer filled with PcdDebugClearMemoryValue. + +**/ +VOID * +EFIAPI +DebugClearMemory ( + OUT VOID *Buffer, + IN UINTN Length + ) +{ + // + // If Buffer is NULL, then ASSERT(). + // + ASSERT (Buffer != NULL); + + // + // SetMem() checks for the the ASSERT() condition on Length and returns Buffer + // + return SetMem (Buffer, Length, PcdGet8 (PcdDebugClearMemoryValue)); +} + +/** + Returns TRUE if ASSERT() macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugAssertEnabled ( + VOID + ) +{ + return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0); +} + +/** + Returns TRUE if DEBUG() macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugPrintEnabled ( + VOID + ) +{ + return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0); +} + +/** + Returns TRUE if DEBUG_CODE() macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugCodeEnabled ( + VOID + ) +{ + return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0); +} + +/** + Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled. + + This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugClearMemoryEnabled ( + VOID + ) +{ + return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0); +} + +/** + Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel. + + This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel. + + @retval TRUE Current ErrorLevel is supported. + @retval FALSE Current ErrorLevel is not supported. + +**/ +BOOLEAN +EFIAPI +DebugPrintLevelEnabled ( + IN CONST UINTN ErrorLevel + ) +{ + return (BOOLEAN)((ErrorLevel & PcdGet32 (PcdFixedDebugPrintErrorLevel)) != 0); +} diff --git a/BaseTools/Source/C/Common/FirmwareVolumeBuffer.c b/BaseTools/Source/C/Common/FirmwareVolumeBuffer.c index 40e068c303..7e530200ac 100644 --- a/BaseTools/Source/C/Common/FirmwareVolumeBuffer.c +++ b/BaseTools/Source/C/Common/FirmwareVolumeBuffer.c @@ -62,7 +62,7 @@ FvBufGetSecFileLen ( STATIC UINT16 -FvBufCalculateChecksum16 ( +FvBufBtCalculateChecksum16 ( IN UINT16 *Buffer, IN UINTN Size ); @@ -181,7 +181,7 @@ FvBufRemoveFile ( return Status; } - if (CommonLibBinderCompareGuid (Name, &NextFile->Name)) { + if (CommonLibBinderBtCompareGuid (Name, &NextFile->Name)) { continue; } else { @@ -265,7 +265,7 @@ FvBufChecksumHeader ( FvHeader->Checksum = 0; FvHeader->Checksum = - FvBufCalculateChecksum16 ( + FvBufBtCalculateChecksum16 ( (UINT16*) FvHeader, FvHeader->HeaderLength / sizeof (UINT16) ); @@ -919,7 +919,7 @@ FvBufFindFileByName ( return Status; } - if (CommonLibBinderCompareGuid (Name, &NextFile->Name)) { + if (CommonLibBinderBtCompareGuid (Name, &NextFile->Name)) { if (File != NULL) { *File = NextFile; } @@ -1429,7 +1429,7 @@ FvBufUnifyBlockSizes ( **/ STATIC UINT16 -FvBufCalculateSum16 ( +FvBufBtCalculateSum16 ( IN UINT16 *Buffer, IN UINTN Size ) @@ -1459,12 +1459,12 @@ FvBufCalculateSum16 ( **/ STATIC UINT16 -FvBufCalculateChecksum16 ( +FvBufBtCalculateChecksum16 ( IN UINT16 *Buffer, IN UINTN Size ) { - return (UINT16)(0x10000 - FvBufCalculateSum16 (Buffer, Size)); + return (UINT16)(0x10000 - FvBufBtCalculateSum16 (Buffer, Size)); } /** diff --git a/BaseTools/Source/C/Common/FvLib.c b/BaseTools/Source/C/Common/FvLib.c index 37631f470f..9bd415b64b 100644 --- a/BaseTools/Source/C/Common/FvLib.c +++ b/BaseTools/Source/C/Common/FvLib.c @@ -246,7 +246,7 @@ GetFileByName ( // Loop as long as we have a valid file // while (CurrentFile) { - if (!CompareGuid (&CurrentFile->Name, FileName)) { + if (!BtCompareGuid (&CurrentFile->Name, FileName)) { *File = CurrentFile; return EFI_SUCCESS; } @@ -543,7 +543,7 @@ VerifyFv ( // // Verify header checksum // - Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); + Checksum = BtCalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); if (Checksum != 0) { Error (NULL, 0, 0006, "invalid FV header checksum", NULL); diff --git a/BaseTools/Source/C/Common/GNUmakefile b/BaseTools/Source/C/Common/GNUmakefile index b3eef7460f..17e166d62e 100644 --- a/BaseTools/Source/C/Common/GNUmakefile +++ b/BaseTools/Source/C/Common/GNUmakefile @@ -30,4 +30,66 @@ OBJECTS = \ StringFuncs.o \ TianoCompress.o +OBJECTS += AutoGen.o DebugLib.o + +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.o + +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/ARShiftU64.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/BitField.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/CheckSum.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/DivS64x64Remainder.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/DivU64x32.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/DivU64x32Remainder.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/DivU64x64Remainder.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/FilePaths.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/GetPowerOfTwo32.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/GetPowerOfTwo64.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/HighBitSet32.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/HighBitSet64.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/LinkedList.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/LowBitSet32.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/LRotU32.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/LRotU64.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/LShiftU64.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/Math64.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/ModU64x32.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/MultS64x64.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/MultU64x32.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/MultU64x64.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/QuickSort.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/RRotU32.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/RRotU64.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/RShiftU64.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/SafeString.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/SafeString.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/String.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/SwapBytes16.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/SwapBytes32.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/SwapBytes64.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseLib/Unaligned.o + +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/CompareMemWrapper.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/CopyMem.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/CopyMemWrapper.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/IsZeroBufferWrapper.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/MemLibGeneric.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/MemLibGuid.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/ScanMem8Wrapper.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/ScanMem16Wrapper.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/ScanMem32Wrapper.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/ScanMem64Wrapper.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/SetMem.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/SetMem16Wrapper.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/SetMem32Wrapper.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/SetMem64Wrapper.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/SetMemWrapper.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseMemoryLib/ZeroMemWrapper.o + +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePrintLib/PrintLib.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePrintLib/PrintLibInternal.o + include $(MAKEROOT)/Makefiles/lib.makefile diff --git a/BaseTools/Source/C/Common/Makefile b/BaseTools/Source/C/Common/Makefile index ec61e45c81..c2abbca39b 100644 --- a/BaseTools/Source/C/Common/Makefile +++ b/BaseTools/Source/C/Common/Makefile @@ -30,6 +30,67 @@ OBJECTS = \ StringFuncs.obj \ TianoCompress.obj +OBJECTS = $(OBJECTS) AutoGen.obj DebugLib.obj + +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib\BaseDebugPrintErrorLevelLib.obj + +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\ARShiftU64.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\BitField.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\CheckSum.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\DivS64x64Remainder.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\DivU64x32.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\DivU64x32Remainder.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\DivU64x64Remainder.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\FilePaths.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\GetPowerOfTwo32.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\GetPowerOfTwo64.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\HighBitSet32.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\HighBitSet64.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\LinkedList.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\LowBitSet32.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\LRotU32.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\LRotU64.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\LShiftU64.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\Math64.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\ModU64x32.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\MultS64x64.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\MultU64x32.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\MultU64x64.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\QuickSort.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\RRotU32.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\RRotU64.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\RShiftU64.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\SafeString.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\String.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\SwapBytes16.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\SwapBytes32.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\SwapBytes64.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseLib\Unaligned.obj + +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\CompareMemWrapper.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\CopyMem.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\CopyMemWrapper.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\IsZeroBufferWrapper.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\MemLibGeneric.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\MemLibGuid.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\ScanMem8Wrapper.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\ScanMem16Wrapper.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\ScanMem32Wrapper.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\ScanMem64Wrapper.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\SetMem.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\SetMem16Wrapper.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\SetMem32Wrapper.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\SetMem64Wrapper.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\SetMemWrapper.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\ZeroMemWrapper.obj + +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePrintLib\PrintLib.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePrintLib\PrintLibInternal.obj + !INCLUDE ..\Makefiles\ms.lib diff --git a/BaseTools/Source/C/Common/ParseGuidedSectionTools.c b/BaseTools/Source/C/Common/ParseGuidedSectionTools.c index e1e9a97e7b..e7709828f8 100644 --- a/BaseTools/Source/C/Common/ParseGuidedSectionTools.c +++ b/BaseTools/Source/C/Common/ParseGuidedSectionTools.c @@ -168,7 +168,7 @@ LookupGuidedSectionToolPath ( } for ( ; GuidTool != NULL; GuidTool = GuidTool->Next) { - if (CompareGuid (&(GuidTool->Guid), SectionGuid) == 0) { + if (BtCompareGuid (&(GuidTool->Guid), SectionGuid) == 0) { return CloneString (GuidTool->Path); } } diff --git a/BaseTools/Source/C/Common/PeCoffLoaderEx.c b/BaseTools/Source/C/Common/PeCoffLoaderEx.c index 181192035e..088e470d17 100644 --- a/BaseTools/Source/C/Common/PeCoffLoaderEx.c +++ b/BaseTools/Source/C/Common/PeCoffLoaderEx.c @@ -10,19 +10,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent --*/ #include -#include +#include #include "PeCoffLib.h" #include "CommonLib.h" #include "EfiUtilityMsgs.h" - -#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \ - Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos) - -#define INS_IMM64(Value, Address, Size, InstPos, ValPos) \ - *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \ - ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos) - #define IMM64_IMM7B_INST_WORD_X 3 #define IMM64_IMM7B_SIZE_X 7 #define IMM64_IMM7B_INST_WORD_POS_X 4 @@ -166,6 +158,7 @@ PeCoffLoaderRelocateRiscVImage ( **/ UINT16 +EFIAPI ThumbMovtImmediateAddress ( IN UINT16 *Instruction ) @@ -196,6 +189,7 @@ ThumbMovtImmediateAddress ( @param Address New address to patch into the instruction **/ VOID +EFIAPI ThumbMovtImmediatePatch ( IN OUT UINT16 *Instruction, IN UINT16 Address diff --git a/BaseTools/Source/C/DevicePath/Makefile b/BaseTools/Source/C/DevicePath/Makefile index 177a96dfb6..9ee776db07 100644 --- a/BaseTools/Source/C/DevicePath/Makefile +++ b/BaseTools/Source/C/DevicePath/Makefile @@ -10,7 +10,14 @@ APPNAME = DevicePath LIBS = $(LIB_PATH)\Common.lib -OBJECTS = DevicePath.obj UefiDevicePathLib.obj DevicePathFromText.obj DevicePathUtilities.obj +OBJECTS = DevicePath.obj + +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\UefiDevicePathLib\DevicePathFromText.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\UefiDevicePathLib\DevicePathToText.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\UefiDevicePathLib\DevicePathUtilities.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\UefiDevicePathLib\DevicePathUtilitiesBase.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\UefiDevicePathLib\UefiDevicePathLib.obj #CFLAGS = $(CFLAGS) /nodefaultlib:libc.lib diff --git a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h index 1c171c8085..30d8854c99 100644 --- a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h +++ b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h @@ -24,6 +24,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "CommonLib.h" #include "EfiUtilityMsgs.h" + +#include +#define EFI_UART_DEVICE_PATH_GUID DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL + + #define END_DEVICE_PATH_LENGTH (sizeof (EFI_DEVICE_PATH_PROTOCOL)) #define MAX_DEVICE_PATH_NODE_COUNT 1024 #define SIZE_64KB 0x00010000 @@ -436,4 +441,111 @@ ConvertTextToDevicePath ( CONST CHAR16 *TextDevicePath ); + + +VOID +SetDevicePathEndNode ( + VOID *Node + ); + +BOOLEAN +IsDevicePathValid ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + UINTN MaxSize + ); + +UINT8 +DevicePathType ( + CONST VOID *Node + ); + +UINT8 +DevicePathSubType ( + CONST VOID *Node + ); + +UINTN +DevicePathNodeLength ( + CONST VOID *Node + ); + +EFI_DEVICE_PATH_PROTOCOL * +NextDevicePathNode ( + CONST VOID *Node + ); + +BOOLEAN +IsDevicePathEndType ( + CONST VOID *Node + ); + +BOOLEAN +IsDevicePathEnd ( + CONST VOID *Node + ); +BOOLEAN +IsDevicePathEndInstance ( + CONST VOID *Node + ); + +UINT16 +SetDevicePathNodeLength ( + VOID *Node, + UINTN Length + ); + +VOID +SetDevicePathEndNode ( + VOID *Node + ); + +UINTN +UefiDevicePathLibGetDevicePathSize ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibDuplicateDevicePath ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibAppendDevicePath ( + CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, + CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath + ); + +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibAppendDevicePathNode ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode + ); + +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibAppendDevicePathInstance ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance + ); + +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibGetNextDevicePathInstance ( + EFI_DEVICE_PATH_PROTOCOL **DevicePath, + UINTN *Size + ); + +EFI_DEVICE_PATH_PROTOCOL * +UefiDevicePathLibCreateDeviceNode ( + UINT8 NodeType, + UINT8 NodeSubType, + UINT16 NodeLength + ); + +BOOLEAN +UefiDevicePathLibIsDevicePathMultiInstance ( + CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + + + + #endif diff --git a/BaseTools/Source/C/EfiRom/EfiRom.h b/BaseTools/Source/C/EfiRom/EfiRom.h index dfb4c32077..f05198713e 100644 --- a/BaseTools/Source/C/EfiRom/EfiRom.h +++ b/BaseTools/Source/C/EfiRom/EfiRom.h @@ -14,7 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include // for PE32 structure definitions +#include // for PE32 structure definitions #include // for option ROM header structures #include diff --git a/BaseTools/Source/C/GenCrc32/GenCrc32.c b/BaseTools/Source/C/GenCrc32/GenCrc32.c index 8c2056e369..877b83a53d 100644 --- a/BaseTools/Source/C/GenCrc32/GenCrc32.c +++ b/BaseTools/Source/C/GenCrc32/GenCrc32.c @@ -304,7 +304,7 @@ Routine Description: // Calculate Crc32 value // if (FileAction == CRC32_ENCODE) { - Status = CalculateCrc32 (FileBuffer, FileSize, &Crc32Value); + Status = BtCalculateCrc32 (FileBuffer, FileSize, &Crc32Value); if (Status != EFI_SUCCESS) { Error (NULL, 0, 3000, "Invalid", "Calculate CRC32 value failed!"); goto Finish; @@ -324,7 +324,7 @@ Routine Description: Error (NULL, 0, 3000, "Invalid", "Input file is invalid!"); goto Finish; } - Status = CalculateCrc32 (FileBuffer + sizeof (UINT32), FileSize - sizeof (UINT32), &Crc32Value); + Status = BtCalculateCrc32 (FileBuffer + sizeof (UINT32), FileSize - sizeof (UINT32), &Crc32Value); if (Status != EFI_SUCCESS) { Error (NULL, 0, 3000, "Invalid", "Calculate CRC32 value failed!"); goto Finish; diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c index 4c2e93e6f4..3776fb92ed 100644 --- a/BaseTools/Source/C/GenFfs/GenFfs.c +++ b/BaseTools/Source/C/GenFfs/GenFfs.c @@ -6,6 +6,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ +#include "WinNtInclude.h" + #ifndef __GNUC__ #define RUNTIME_FUNCTION _WINNT_DUP_RUNTIME_FUNCTION #include @@ -25,7 +27,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include +#include #include #include "CommonLib.h" @@ -471,6 +473,7 @@ Routine Description: } EFI_STATUS +EFIAPI FfsRebaseImageRead ( IN VOID *FileHandle, IN UINTN FileOffset, @@ -897,7 +900,7 @@ Routine Description: goto Finish; } - if (CompareGuid (&FileGuid, &mZeroGuid) == 0) { + if (BtCompareGuid (&FileGuid, &mZeroGuid) == 0) { Error (NULL, 0, 1001, "Missing option", "fileguid"); goto Finish; } diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 4c9eaa7dae..1f4651c819 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -1056,7 +1056,7 @@ Routine Description: Status = GetSectionByType (FfsFile, EFI_SECTION_FREEFORM_SUBTYPE_GUID, 1, &PadSection); if (EFI_ERROR (Status) || - CompareGuid (&PadSection.FreeformSubtypeSection->SubTypeGuid, + BtCompareGuid (&PadSection.FreeformSubtypeSection->SubTypeGuid, &mEfiFfsSectionAlignmentPaddingGuid) != 0) { return FALSE; } @@ -1263,7 +1263,7 @@ Routine Description: // Verify the input file is the duplicated file in this Fv image // for (Index1 = 0; Index1 < Index; Index1 ++) { - if (CompareGuid ((EFI_GUID *) FileBuffer, &mFileGuidArray [Index1]) == 0) { + if (BtCompareGuid ((EFI_GUID *) FileBuffer, &mFileGuidArray [Index1]) == 0) { Error (NULL, 0, 2000, "Invalid parameter", "the %dth file and %uth file have the same file GUID.", (unsigned) Index1 + 1, (unsigned) Index + 1); PrintGuid ((EFI_GUID *) FileBuffer); free (FileBuffer); @@ -2688,8 +2688,8 @@ Routine Description: mFvDataInfo.FvNameGuid.Data4[7]); } - if (CompareGuid (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem2Guid) == 0 || - CompareGuid (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem3Guid) == 0) { + if (BtCompareGuid (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem2Guid) == 0 || + BtCompareGuid (&mFvDataInfo.FvFileSystemGuid, &mEfiFirmwareFileSystem3Guid) == 0) { mFvDataInfo.IsPiFvImage = TRUE; } @@ -2830,7 +2830,7 @@ Routine Description: // FvHeader->HeaderLength = (UINT16) (((UINTN) &(FvHeader->BlockMap[Index + 1])) - (UINTN) FvImage); FvHeader->Checksum = 0; - FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); + FvHeader->Checksum = BtCalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); // // If there is no FFS file, generate one empty FV @@ -2910,7 +2910,7 @@ Routine Description: // Fv Extension header change update Fv Header Check sum // FvHeader->Checksum = 0; - FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); + FvHeader->Checksum = BtCalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); } // @@ -2976,7 +2976,7 @@ Routine Description: // Update Checksum for FvHeader // FvHeader->Checksum = 0; - FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); + FvHeader->Checksum = BtCalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); } if (mRiscV) { @@ -2992,7 +2992,7 @@ Routine Description: // Update Checksum for FvHeader // FvHeader->Checksum = 0; - FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); + FvHeader->Checksum = BtCalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); } if (mLoongArch) { @@ -3005,7 +3005,7 @@ Routine Description: // Update Checksum for FvHeader // FvHeader->Checksum = 0; - FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); + FvHeader->Checksum = BtCalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); } // @@ -3018,16 +3018,16 @@ Routine Description: // Update Checksum for FvHeader // FvHeader->Checksum = 0; - FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); + FvHeader->Checksum = BtCalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); } // // If there are large FFS in FV, the file system GUID should set to system 3 GUID. // - if (mIsLargeFfs && CompareGuid (&FvHeader->FileSystemGuid, &mEfiFirmwareFileSystem2Guid) == 0) { + if (mIsLargeFfs && BtCompareGuid (&FvHeader->FileSystemGuid, &mEfiFirmwareFileSystem2Guid) == 0) { memcpy (&FvHeader->FileSystemGuid, &mEfiFirmwareFileSystem3Guid, sizeof (EFI_GUID)); FvHeader->Checksum = 0; - FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); + FvHeader->Checksum = BtCalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16)); } WriteFile: @@ -3350,6 +3350,7 @@ Routine Description: } EFI_STATUS +EFIAPI FfsRebaseImageRead ( IN VOID *FileHandle, IN UINTN FileOffset, @@ -4423,7 +4424,7 @@ Routine Description: // // Set Default Capsule Guid value // - if (CompareGuid (&mCapDataInfo.CapGuid, &mZeroGuid) == 0) { + if (BtCompareGuid (&mCapDataInfo.CapGuid, &mZeroGuid) == 0) { memcpy (&mCapDataInfo.CapGuid, &mDefaultCapsuleGuid, sizeof (EFI_GUID)); } // diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.h b/BaseTools/Source/C/GenFv/GenFvInternalLib.h index bf476f2c08..7bace6ad36 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.h +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.h @@ -20,8 +20,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include -#include +#include +#include +#include #include "CommonLib.h" #include "ParseInf.h" diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c index 62fd0c0a95..9d7321515b 100644 --- a/BaseTools/Source/C/GenSec/GenSec.c +++ b/BaseTools/Source/C/GenSec/GenSec.c @@ -5,6 +5,8 @@ Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ +#include "WinNtInclude.h" + #ifndef __GNUC__ #define RUNTIME_FUNCTION _WINNT_DUP_RUNTIME_FUNCTION #include @@ -21,8 +23,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include -#include +#include +#include #include "CommonLib.h" #include "Compress.h" @@ -872,7 +874,7 @@ Routine Description: ); if (Status == EFI_BUFFER_TOO_SMALL) { - if (CompareGuid (VendorGuid, &mZeroGuid) == 0) { + if (BtCompareGuid (VendorGuid, &mZeroGuid) == 0) { Offset = sizeof (CRC32_SECTION_HEADER); if (InputLength + Offset >= MAX_SECTION_SIZE) { Offset = sizeof (CRC32_SECTION_HEADER2); @@ -929,12 +931,12 @@ Routine Description: // // Now data is in FileBuffer + Offset // - if (CompareGuid (VendorGuid, &mZeroGuid) == 0) { + if (BtCompareGuid (VendorGuid, &mZeroGuid) == 0) { // // Default Guid section is CRC32. // Crc32Checksum = 0; - CalculateCrc32 (FileBuffer + Offset, InputLength, &Crc32Checksum); + BtCalculateCrc32 (FileBuffer + Offset, InputLength, &Crc32Checksum); if (TotalLength >= MAX_SECTION_SIZE) { Crc32GuidSect2 = (CRC32_SECTION_HEADER2 *) FileBuffer; @@ -1144,6 +1146,7 @@ Routine Description: } EFI_STATUS +EFIAPI FfsRebaseImageRead ( IN VOID *FileHandle, IN UINTN FileOffset, @@ -1752,14 +1755,14 @@ Routine Description: // if ((SectType != EFI_SECTION_GUID_DEFINED) && (SectType != EFI_SECTION_FREEFORM_SUBTYPE_GUID) && (SectionName != NULL) && - (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) { + (BtCompareGuid (&VendorGuid, &mZeroGuid) != 0)) { fprintf (stdout, "Warning: the input guid value is not required for this section type %s\n", SectionName); } // // Check whether there is GUID for the SubtypeGuid section // - if ((SectType == EFI_SECTION_FREEFORM_SUBTYPE_GUID) && (CompareGuid (&VendorGuid, &mZeroGuid) == 0)) { + if ((SectType == EFI_SECTION_FREEFORM_SUBTYPE_GUID) && (BtCompareGuid (&VendorGuid, &mZeroGuid) == 0)) { Error (NULL, 0, 1001, "Missing options", "GUID"); goto Finish; } @@ -1813,7 +1816,7 @@ Routine Description: break; case EFI_SECTION_GUID_DEFINED: - if (InputFileAlign != NULL && (CompareGuid (&VendorGuid, &mZeroGuid) != 0)) { + if (InputFileAlign != NULL && (BtCompareGuid (&VendorGuid, &mZeroGuid) != 0)) { // // Only process alignment for the default known CRC32 guided section. // For the unknown guided section, the alignment is processed when the dummy all section (EFI_SECTION_ALL) is generated. diff --git a/BaseTools/Source/C/Include/Common/AutoGen.h b/BaseTools/Source/C/Include/Common/AutoGen.h new file mode 100644 index 0000000000..8136bd1e2a --- /dev/null +++ b/BaseTools/Source/C/Include/Common/AutoGen.h @@ -0,0 +1,94 @@ +/** @file + AutoGen definitions for edk2 package code consumption in BaseTools. + + Copyright (c) 2023, Marvin Häuser. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _BT_AUTOGENH +#define _BT_AUTOGENH + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +extern GUID gEfiCallerIdGuid; +extern GUID gEdkiiDscPlatformGuid; +extern CHAR8 *gEfiCallerBaseName; + +#define EFI_CALLER_ID_GUID \ + {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} +#define EDKII_DSC_PLATFORM_GUID \ + {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} + +// Definition of SkuId Array +extern UINT64 _gPcd_SkuId_Array[]; + +// Definition of PCDs used in this module + +#define _PCD_TOKEN_PcdMaximumAsciiStringLength 0U +#define _PCD_SIZE_PcdMaximumAsciiStringLength 4 +#define _PCD_GET_MODE_SIZE_PcdMaximumAsciiStringLength _PCD_SIZE_PcdMaximumAsciiStringLength +#define _PCD_VALUE_PcdMaximumAsciiStringLength 0U +#define _PCD_GET_MODE_32_PcdMaximumAsciiStringLength _PCD_VALUE_PcdMaximumAsciiStringLength +//#define _PCD_SET_MODE_32_PcdMaximumAsciiStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdMaximumUnicodeStringLength 0U +#define _PCD_SIZE_PcdMaximumUnicodeStringLength 4 +#define _PCD_GET_MODE_SIZE_PcdMaximumUnicodeStringLength _PCD_SIZE_PcdMaximumUnicodeStringLength +#define _PCD_VALUE_PcdMaximumUnicodeStringLength 0U +#define _PCD_GET_MODE_32_PcdMaximumUnicodeStringLength _PCD_VALUE_PcdMaximumUnicodeStringLength +//#define _PCD_SET_MODE_32_PcdMaximumUnicodeStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdMaximumLinkedListLength 0U +#define _PCD_SIZE_PcdMaximumLinkedListLength 4 +#define _PCD_GET_MODE_SIZE_PcdMaximumLinkedListLength _PCD_SIZE_PcdMaximumLinkedListLength +#define _PCD_VALUE_PcdMaximumLinkedListLength 0U +#define _PCD_GET_MODE_32_PcdMaximumLinkedListLength _PCD_VALUE_PcdMaximumLinkedListLength +//#define _PCD_SET_MODE_32_PcdMaximumLinkedListLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdVerifyNodeInList 0U +#define _PCD_SIZE_PcdVerifyNodeInList 1 +#define _PCD_GET_MODE_SIZE_PcdVerifyNodeInList _PCD_SIZE_PcdVerifyNodeInList +#define _PCD_VALUE_PcdVerifyNodeInList 1U +#define _PCD_GET_MODE_BOOL_PcdVerifyNodeInList _PCD_VALUE_PcdVerifyNodeInList +//#define _PCD_SET_MODE_BOOL_PcdVerifyNodeInList ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdFixedDebugPrintErrorLevel 0U +#define _PCD_SIZE_PcdFixedDebugPrintErrorLevel 4 +#define _PCD_GET_MODE_SIZE_PcdFixedDebugPrintErrorLevel _PCD_SIZE_PcdFixedDebugPrintErrorLevel +#define _PCD_VALUE_PcdFixedDebugPrintErrorLevel 0xFFFFFFFFU +#define _PCD_GET_MODE_32_PcdFixedDebugPrintErrorLevel _PCD_VALUE_PcdFixedDebugPrintErrorLevel +//#define _PCD_SET_MODE_32_PcdFixedDebugPrintErrorLevel ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdDebugPropertyMask 0U +#define _PCD_SIZE_PcdDebugPropertyMask 1 +#define _PCD_GET_MODE_SIZE_PcdDebugPropertyMask _PCD_SIZE_PcdDebugPropertyMask +#define _PCD_VALUE_PcdDebugPropertyMask 0xFFU +#define _PCD_GET_MODE_8_PcdDebugPropertyMask _PCD_VALUE_PcdDebugPropertyMask +//#define _PCD_SET_MODE_8_PcdDebugPropertyMask ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdDebugClearMemoryValue 0U +#define _PCD_SIZE_PcdDebugClearMemoryValue 1 +#define _PCD_GET_MODE_SIZE_PcdDebugClearMemoryValue _PCD_SIZE_PcdDebugClearMemoryValue +#define _PCD_VALUE_PcdDebugClearMemoryValue 0xAFU +#define _PCD_GET_MODE_8_PcdDebugClearMemoryValue _PCD_VALUE_PcdDebugClearMemoryValue +//#define _PCD_SET_MODE_8_PcdDebugClearMemoryValue ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdDebugPrintErrorLevel 0U +#define _PCD_SIZE_PcdDebugPrintErrorLevel 4 +#define _PCD_GET_MODE_SIZE_PcdDebugPrintErrorLevel _PCD_SIZE_PcdDebugPrintErrorLevel +#define _PCD_VALUE_PcdDebugPrintErrorLevel 0x8000004F +#define _PCD_GET_MODE_32_PcdDebugPrintErrorLevel _PCD_VALUE_PcdDebugPrintErrorLevel +//#define _PCD_SET_MODE_32_PcdDebugPrintErrorLevel ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BaseTools/Source/C/Include/Common/BaseTypes.h b/BaseTools/Source/C/Include/Common/BaseTypes.h index 5093a2f1f9..f81449c91b 100644 --- a/BaseTools/Source/C/Include/Common/BaseTypes.h +++ b/BaseTools/Source/C/Include/Common/BaseTypes.h @@ -10,303 +10,37 @@ **/ -#ifndef __BASE_TYPES_H__ -#define __BASE_TYPES_H__ +#ifndef __BT_BASE_TYPES_H__ +#define __BT_BASE_TYPES_H__ // -// Include processor specific binding +// To be able to safely include Windows headers, we need to include +// WinNtInclude.h first. // -#include -#include - -// -// Modifiers to abstract standard types to aid in debug of problems -// -#define CONST const -#define STATIC static -#define VOID void +#include "WinNtInclude.h" -// -// Modifiers for Data Types used to self document code. -// This concept is borrowed for UEFI specification. -// -#ifndef IN -// -// Some other environments use this construct, so #ifndef to prevent -// multiple definition. -// -#define IN -#define OUT -#define OPTIONAL -#endif +#include +#include // -// Constants. They may exist in other build structures, so #ifndef them. -// -#ifndef TRUE +// Base.h is a C header and must be linked against as such. +// Without this, MSVC may fail to link against _ReturnAddress. // -// BugBug: UEFI specification claims 1 and 0. We are concerned about the -// compiler portability so we did it this way. -// -#define TRUE ((BOOLEAN)(1==1)) -#endif - -#ifndef FALSE -#define FALSE ((BOOLEAN)(0==1)) +#ifdef __cplusplus +extern "C" { #endif -#ifndef NULL -#define NULL ((VOID *) 0) -#endif - -#define PACKED - -// -// Support for variable length argument lists using the ANSI standard. -// -// Since we are using the ANSI standard we used the standard naming and -// did not follow the coding convention -// -// VA_LIST - typedef for argument list. -// VA_START (VA_LIST Marker, argument before the ...) - Init Marker for use. -// VA_END (VA_LIST Marker) - Clear Marker -// VA_ARG (VA_LIST Marker, var arg size) - Use Marker to get an argument from -// the ... list. You must know the size and pass it in this macro. -// -// example: // -// UINTN -// ExampleVarArg ( -// IN UINTN NumberOfArgs, -// ... -// ) -// { -// VA_LIST Marker; -// UINTN Index; -// UINTN Result; -// -// // -// // Initialize the Marker -// // -// VA_START (Marker, NumberOfArgs); -// for (Index = 0, Result = 0; Index < NumberOfArgs; Index++) { -// // -// // The ... list is a series of UINTN values, so average them up. -// // -// Result += VA_ARG (Marker, UINTN); -// } -// -// VA_END (Marker); -// return Result -// } +// These macros may have been declared previously by C standard libraries. // +#undef NULL +#undef FALSE +#undef TRUE -#define _INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1)) - -// -// Also support coding convention rules for var arg macros -// -#ifndef VA_START - -// typedef CHAR8 *VA_LIST; -// #define VA_START(ap, v) (ap = (VA_LIST) & (v) + _INT_SIZE_OF (v)) -// #define VA_ARG(ap, t) (*(t *) ((ap += _INT_SIZE_OF (t)) - _INT_SIZE_OF (t))) -// #define VA_END(ap) (ap = (VA_LIST) 0) -// Use the native arguments for tools. -#define VA_START va_start -#define VA_ARG va_arg -#define VA_END va_end -#define VA_LIST va_list +#include +#ifdef __cplusplus +} #endif -#ifndef GUID_DEFINED -#define GUID_DEFINED -/// -/// 128 bit buffer containing a unique identifier value. -/// Unless otherwise specified, aligned on a 64 bit boundary. -/// -typedef struct { - UINT32 Data1; - UINT16 Data2; - UINT16 Data3; - UINT8 Data4[8]; -} GUID; -#endif - -/// -/// 4-byte buffer. An IPv4 internet protocol address. -/// -typedef struct { - UINT8 Addr[4]; -} IPv4_ADDRESS; - -/// -/// 16-byte buffer. An IPv6 internet protocol address. -/// -typedef struct { - UINT8 Addr[16]; -} IPv6_ADDRESS; - -// -// Macro that returns the byte offset of a field in a data structure. -// -#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field)) - -/// -/// _CR - returns a pointer to the structure -/// from one of its elements. -/// -#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field))) - -/// -/// ALIGN_POINTER - aligns a pointer to the lowest boundary -/// -#define ALIGN_POINTER(p, s) ((VOID *) ((UINTN)(p) + (((s) - ((UINTN) (p))) & ((s) - 1)))) - -/// -/// ALIGN_VARIABLE - aligns a variable up to the next natural boundary for int size of a processor -/// -#define ALIGN_VARIABLE(Value, Adjustment) \ - Adjustment = 0U; \ - if ((UINTN) (Value) % sizeof (UINTN)) { \ - (Adjustment) = (UINTN)(sizeof (UINTN) - ((UINTN) (Value) % sizeof (UINTN))); \ - } \ - (Value) = (UINTN)((UINTN) (Value) + (UINTN) (Adjustment)) - -// -// Return the maximum of two operands. -// This macro returns the maximum of two operand specified by a and b. -// Both a and b must be the same numerical types, signed or unsigned. -// -#define MAX(a, b) \ - (((a) > (b)) ? (a) : (b)) - - -// -// Return the minimum of two operands. -// This macro returns the minimal of two operand specified by a and b. -// Both a and b must be the same numerical types, signed or unsigned. -// -#define MIN(a, b) \ - (((a) < (b)) ? (a) : (b)) - - -// -// EFI Error Codes common to all execution phases -// - -typedef UINTN RETURN_STATUS; - -/// -/// Set the upper bit to indicate EFI Error. -/// -#define ENCODE_ERROR(a) ((RETURN_STATUS)(MAX_BIT | (a))) - -#define ENCODE_WARNING(a) ((RETURN_STATUS)(a)) -#define RETURN_ERROR(a) (((RETURN_STATUS)(a)) >= MAX_BIT) - -#define RETURN_SUCCESS 0 -#define RETURN_LOAD_ERROR ENCODE_ERROR (1) -#define RETURN_INVALID_PARAMETER ENCODE_ERROR (2) -#define RETURN_UNSUPPORTED ENCODE_ERROR (3) -#define RETURN_BAD_BUFFER_SIZE ENCODE_ERROR (4) -#define RETURN_BUFFER_TOO_SMALL ENCODE_ERROR (5) -#define RETURN_NOT_READY ENCODE_ERROR (6) -#define RETURN_DEVICE_ERROR ENCODE_ERROR (7) -#define RETURN_WRITE_PROTECTED ENCODE_ERROR (8) -#define RETURN_OUT_OF_RESOURCES ENCODE_ERROR (9) -#define RETURN_VOLUME_CORRUPTED ENCODE_ERROR (10) -#define RETURN_VOLUME_FULL ENCODE_ERROR (11) -#define RETURN_NO_MEDIA ENCODE_ERROR (12) -#define RETURN_MEDIA_CHANGED ENCODE_ERROR (13) -#define RETURN_NOT_FOUND ENCODE_ERROR (14) -#define RETURN_ACCESS_DENIED ENCODE_ERROR (15) -#define RETURN_NO_RESPONSE ENCODE_ERROR (16) -#define RETURN_NO_MAPPING ENCODE_ERROR (17) -#define RETURN_TIMEOUT ENCODE_ERROR (18) -#define RETURN_NOT_STARTED ENCODE_ERROR (19) -#define RETURN_ALREADY_STARTED ENCODE_ERROR (20) -#define RETURN_ABORTED ENCODE_ERROR (21) -#define RETURN_ICMP_ERROR ENCODE_ERROR (22) -#define RETURN_TFTP_ERROR ENCODE_ERROR (23) -#define RETURN_PROTOCOL_ERROR ENCODE_ERROR (24) -#define RETURN_INCOMPATIBLE_VERSION ENCODE_ERROR (25) -#define RETURN_SECURITY_VIOLATION ENCODE_ERROR (26) -#define RETURN_CRC_ERROR ENCODE_ERROR (27) -#define RETURN_END_OF_MEDIA ENCODE_ERROR (28) -#define RETURN_END_OF_FILE ENCODE_ERROR (31) - -#define RETURN_WARN_UNKNOWN_GLYPH ENCODE_WARNING (1) -#define RETURN_WARN_DELETE_FAILURE ENCODE_WARNING (2) -#define RETURN_WARN_WRITE_FAILURE ENCODE_WARNING (3) -#define RETURN_WARN_BUFFER_TOO_SMALL ENCODE_WARNING (4) - -typedef UINT64 PHYSICAL_ADDRESS; - -#define BIT0 0x00000001 -#define BIT1 0x00000002 -#define BIT2 0x00000004 -#define BIT3 0x00000008 -#define BIT4 0x00000010 -#define BIT5 0x00000020 -#define BIT6 0x00000040 -#define BIT7 0x00000080 -#define BIT8 0x00000100 -#define BIT9 0x00000200 -#define BIT10 0x00000400 -#define BIT11 0x00000800 -#define BIT12 0x00001000 -#define BIT13 0x00002000 -#define BIT14 0x00004000 -#define BIT15 0x00008000 -#define BIT16 0x00010000 -#define BIT17 0x00020000 -#define BIT18 0x00040000 -#define BIT19 0x00080000 -#define BIT20 0x00100000 -#define BIT21 0x00200000 -#define BIT22 0x00400000 -#define BIT23 0x00800000 -#define BIT24 0x01000000 -#define BIT25 0x02000000 -#define BIT26 0x04000000 -#define BIT27 0x08000000 -#define BIT28 0x10000000 -#define BIT29 0x20000000 -#define BIT30 0x40000000 -#define BIT31 0x80000000 -#define BIT32 0x0000000100000000ULL -#define BIT33 0x0000000200000000ULL -#define BIT34 0x0000000400000000ULL -#define BIT35 0x0000000800000000ULL -#define BIT36 0x0000001000000000ULL -#define BIT37 0x0000002000000000ULL -#define BIT38 0x0000004000000000ULL -#define BIT39 0x0000008000000000ULL -#define BIT40 0x0000010000000000ULL -#define BIT41 0x0000020000000000ULL -#define BIT42 0x0000040000000000ULL -#define BIT43 0x0000080000000000ULL -#define BIT44 0x0000100000000000ULL -#define BIT45 0x0000200000000000ULL -#define BIT46 0x0000400000000000ULL -#define BIT47 0x0000800000000000ULL -#define BIT48 0x0001000000000000ULL -#define BIT49 0x0002000000000000ULL -#define BIT50 0x0004000000000000ULL -#define BIT51 0x0008000000000000ULL -#define BIT52 0x0010000000000000ULL -#define BIT53 0x0020000000000000ULL -#define BIT54 0x0040000000000000ULL -#define BIT55 0x0080000000000000ULL -#define BIT56 0x0100000000000000ULL -#define BIT57 0x0200000000000000ULL -#define BIT58 0x0400000000000000ULL -#define BIT59 0x0800000000000000ULL -#define BIT60 0x1000000000000000ULL -#define BIT61 0x2000000000000000ULL -#define BIT62 0x4000000000000000ULL -#define BIT63 0x8000000000000000ULL - #endif diff --git a/BaseTools/Source/C/Include/Common/GuidedSectionExtractionEx.h b/BaseTools/Source/C/Include/Common/GuidedSectionExtractionEx.h new file mode 100644 index 0000000000..3a9f505190 --- /dev/null +++ b/BaseTools/Source/C/Include/Common/GuidedSectionExtractionEx.h @@ -0,0 +1,36 @@ +/** @file + This file declares GUIDed section extraction protocol. + + This interface provides a means of decoding a GUID defined encapsulation + section. There may be multiple different GUIDs associated with the GUIDed + section extraction protocol. That is, all instances of the GUIDed section + extraction protocol must have the same interface structure. + + @par Revision Reference: PI + Version 1.00. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __BT_EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL_H__ +#define __BT_EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL_H__ + +#include +#include + +// +// Protocol GUID definition. Each GUIDed section extraction protocol has the +// same interface but with different GUID. All the GUIDs is defined here. +// May add multiple GUIDs here. +// +#define EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID EFI_CRC32_GUIDED_SECTION_EXTRACTION_GUID + +// +// may add other GUID here +// +#define gEfiCrc32GuidedSectionExtractionProtocolGuid gEfiCrc32GuidedSectionExtractionGuid + +#endif \ No newline at end of file diff --git a/BaseTools/Source/C/Include/Common/MdeModuleHii.h b/BaseTools/Source/C/Include/Common/MdeModuleHii.h index d4944efe45..60697b9422 100644 --- a/BaseTools/Source/C/Include/Common/MdeModuleHii.h +++ b/BaseTools/Source/C/Include/Common/MdeModuleHii.h @@ -7,227 +7,10 @@ **/ -#ifndef _MDEMODULE_HII_H -#define _MDEMODULE_HII_H +#ifndef _BT_MDEMODULE_HII_H +#define _BT_MDEMODULE_HII_H -#define NARROW_CHAR 0xFFF0 -#define WIDE_CHAR 0xFFF1 -#define NON_BREAKING_CHAR 0xFFF2 - -/// -/// State defined for password statemachine . -/// -#define BROWSER_STATE_VALIDATE_PASSWORD 0 -#define BROWSER_STATE_SET_PASSWORD 1 - -/// -/// GUIDed opcodes defined for EDKII implementation. -/// -#define EFI_IFR_TIANO_GUID \ - { 0xf0b1735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38, 0xaf, 0x48, 0xce} } - -#pragma pack(1) - -/// -/// EDKII implementation extension opcodes, new extension can be added here later. -/// -#define EFI_IFR_EXTEND_OP_LABEL 0x0 -#define EFI_IFR_EXTEND_OP_BANNER 0x1 -#define EFI_IFR_EXTEND_OP_TIMEOUT 0x2 -#define EFI_IFR_EXTEND_OP_CLASS 0x3 -#define EFI_IFR_EXTEND_OP_SUBCLASS 0x4 - -/// -/// Label opcode. -/// -typedef struct _EFI_IFR_GUID_LABEL { - EFI_IFR_OP_HEADER Header; - /// - /// EFI_IFR_TIANO_GUID. - /// - EFI_GUID Guid; - /// - /// EFI_IFR_EXTEND_OP_LABEL. - /// - UINT8 ExtendOpCode; - /// - /// Label Number. - /// - UINT16 Number; -} EFI_IFR_GUID_LABEL; - -#define EFI_IFR_BANNER_ALIGN_LEFT 0 -#define EFI_IFR_BANNER_ALIGN_CENTER 1 -#define EFI_IFR_BANNER_ALIGN_RIGHT 2 - -/// -/// Banner opcode. -/// -typedef struct _EFI_IFR_GUID_BANNER { - EFI_IFR_OP_HEADER Header; - /// - /// EFI_IFR_TIANO_GUID. - /// - EFI_GUID Guid; - /// - /// EFI_IFR_EXTEND_OP_BANNER - /// - UINT8 ExtendOpCode; - EFI_STRING_ID Title; ///< The string token for the banner title. - UINT16 LineNumber; ///< 1-based line number. - UINT8 Alignment; ///< left, center, or right-aligned. -} EFI_IFR_GUID_BANNER; - -/// -/// Timeout opcode. -/// -typedef struct _EFI_IFR_GUID_TIMEOUT { - EFI_IFR_OP_HEADER Header; - /// - /// EFI_IFR_TIANO_GUID. - /// - EFI_GUID Guid; - /// - /// EFI_IFR_EXTEND_OP_TIMEOUT. - /// - UINT8 ExtendOpCode; - UINT16 TimeOut; ///< TimeOut Value. -} EFI_IFR_GUID_TIMEOUT; - -#define EFI_NON_DEVICE_CLASS 0x00 -#define EFI_DISK_DEVICE_CLASS 0x01 -#define EFI_VIDEO_DEVICE_CLASS 0x02 -#define EFI_NETWORK_DEVICE_CLASS 0x04 -#define EFI_INPUT_DEVICE_CLASS 0x08 -#define EFI_ON_BOARD_DEVICE_CLASS 0x10 -#define EFI_OTHER_DEVICE_CLASS 0x20 - -/// -/// Device Class opcode. -/// -typedef struct _EFI_IFR_GUID_CLASS { - EFI_IFR_OP_HEADER Header; - /// - /// EFI_IFR_TIANO_GUID. - /// - EFI_GUID Guid; - /// - /// EFI_IFR_EXTEND_OP_CLASS. - /// - UINT8 ExtendOpCode; - UINT16 Class; ///< Device Class from the above. -} EFI_IFR_GUID_CLASS; - -#define EFI_SETUP_APPLICATION_SUBCLASS 0x00 -#define EFI_GENERAL_APPLICATION_SUBCLASS 0x01 -#define EFI_FRONT_PAGE_SUBCLASS 0x02 -#define EFI_SINGLE_USE_SUBCLASS 0x03 - -/// -/// SubClass opcode -/// -typedef struct _EFI_IFR_GUID_SUBCLASS { - EFI_IFR_OP_HEADER Header; - /// - /// EFI_IFR_TIANO_GUID. - /// - EFI_GUID Guid; - /// - /// EFI_IFR_EXTEND_OP_SUBCLASS. - /// - UINT8 ExtendOpCode; - UINT16 SubClass; ///< Sub Class type from the above. -} EFI_IFR_GUID_SUBCLASS; - -/// -/// GUIDed opcodes support for framework vfr. -/// -#define EFI_IFR_FRAMEWORK_GUID \ - { 0x31ca5d1a, 0xd511, 0x4931, { 0xb7, 0x82, 0xae, 0x6b, 0x2b, 0x17, 0x8c, 0xd7 } } - -/// -/// Two extended opcodes are added, and new extensions can be added here later. -/// One is for framework OneOf question Option Key value; -/// another is for framework vareqval. -/// -#define EFI_IFR_EXTEND_OP_OPTIONKEY 0x0 -#define EFI_IFR_EXTEND_OP_VAREQNAME 0x1 - -/// -/// Store the framework vfr option key value. -/// -typedef struct _EFI_IFR_GUID_OPTIONKEY { - EFI_IFR_OP_HEADER Header; - /// - /// EFI_IFR_FRAMEWORK_GUID. - /// - EFI_GUID Guid; - /// - /// EFI_IFR_EXTEND_OP_OPTIONKEY. - /// - UINT8 ExtendOpCode; - /// - /// OneOf Questiond ID binded by OneOf Option. - /// - EFI_QUESTION_ID QuestionId; - /// - /// The OneOf Option Value. - /// - EFI_IFR_TYPE_VALUE OptionValue; - /// - /// The Framework OneOf Option Key Value. - /// - UINT16 KeyValue; -} EFI_IFR_GUID_OPTIONKEY; - -/// -/// Store the framework vfr vareqval name number. -/// -typedef struct _EFI_IFR_GUID_VAREQNAME { - EFI_IFR_OP_HEADER Header; - /// - /// EFI_IFR_FRAMEWORK_GUID. - /// - EFI_GUID Guid; - /// - /// EFI_IFR_EXTEND_OP_VAREQNAME. - /// - UINT8 ExtendOpCode; - /// - /// Question ID of the Numeric Opcode created. - /// - EFI_QUESTION_ID QuestionId; - /// - /// For vareqval (0x100), NameId is 0x100. - /// This value will convert to a Unicode String following this rule; - /// sprintf(StringBuffer, "%d", NameId) . - /// The Unicode String will be used as a EFI Variable Name. - /// - UINT16 NameId; -} EFI_IFR_GUID_VAREQNAME; - -/// -/// EDKII implementation extension GUID, used to indicate there are bit fields in the varstore. -/// -#define EDKII_IFR_BIT_VARSTORE_GUID \ - { 0x82DDD68B, 0x9163, 0x4187, {0x9B, 0x27, 0x20, 0xA8, 0xFD, 0x60 ,0xA7, 0x1D}} - -/// -/// EDKII implementation extension flags, used to indicate the display style and bit width for bit filed storage. -/// Two high bits for display style and the low six bits for bit width. -/// -#define EDKII_IFR_DISPLAY_BIT 0xC0 -#define EDKII_IFR_DISPLAY_INT_DEC_BIT 0x00 -#define EDKII_IFR_DISPLAY_UINT_DEC_BIT 0x40 -#define EDKII_IFR_DISPLAY_UINT_HEX_BIT 0x80 - -#define EDKII_IFR_NUMERIC_SIZE_BIT 0x3F - -#pragma pack() - -extern EFI_GUID gEfiIfrTianoGuid; -extern EFI_GUID gEfiIfrFrameworkGuid; -extern EFI_GUID gEdkiiIfrBitVarStoreGuid; +#include #endif diff --git a/BaseTools/Source/C/Include/Common/PeImageEx.h b/BaseTools/Source/C/Include/Common/PeImageEx.h new file mode 100644 index 0000000000..3e4e129778 --- /dev/null +++ b/BaseTools/Source/C/Include/Common/PeImageEx.h @@ -0,0 +1,59 @@ +/** @file + EFI image format for PE32+. Please note some data structures are different + for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64 + + @bug Fix text - doc as defined in MSFT EFI specification. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+ Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
+ Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __BT_PE_IMAGE_H__ +#define __BT_PE_IMAGE_H__ + +#include + +// +// PE32+ Machine type for EFI images +// +#define IMAGE_FILE_MACHINE_ARM 0x01c0 +#define IMAGE_FILE_MACHINE_ARMT IMAGE_FILE_MACHINE_ARMTHUMB_MIXED + +// +// Support old names for backward compatible +// +#define EFI_IMAGE_MACHINE_ARMT EFI_IMAGE_MACHINE_ARMTHUMB_MIXED + +#define EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // Supports addresses > 2-GB + +// +// Based export types. +// +#define EFI_IMAGE_EXPORT_ORDINAL_BASE 1 +#define EFI_IMAGE_EXPORT_ADDR_SIZE 4 +#define EFI_IMAGE_EXPORT_ORDINAL_SIZE 2 + +// +// .pdata entries for X64 +// +typedef struct { + UINT32 FunctionStartAddress; + UINT32 FunctionEndAddress; + UINT32 UnwindInfoAddress; +} RUNTIME_FUNCTION; + +typedef struct { + UINT8 Version:3; + UINT8 Flags:5; + UINT8 SizeOfProlog; + UINT8 CountOfUnwindCodes; + UINT8 FrameRegister:4; + UINT8 FrameRegisterOffset:4; +} UNWIND_INFO; + +#endif diff --git a/BaseTools/Source/C/Include/Common/PiFirmwareFile.h b/BaseTools/Source/C/Include/Common/PiFirmwareFile.h index 56874374ca..a3d1c76956 100644 --- a/BaseTools/Source/C/Include/Common/PiFirmwareFile.h +++ b/BaseTools/Source/C/Include/Common/PiFirmwareFile.h @@ -10,308 +10,24 @@ **/ -#ifndef __PI_FIRMWARE_FILE_H__ -#define __PI_FIRMWARE_FILE_H__ +#ifndef __BT_PI_FIRMWARE_FILE_H__ +#define __BT_PI_FIRMWARE_FILE_H__ -#pragma pack(1) -// -// Used to verify the integrity of the file. -// -typedef union { - struct { - UINT8 Header; - UINT8 File; - } Checksum; - UINT16 Checksum16; -} EFI_FFS_INTEGRITY_CHECK; - -typedef UINT8 EFI_FV_FILETYPE; -typedef UINT8 EFI_FFS_FILE_ATTRIBUTES; -typedef UINT8 EFI_FFS_FILE_STATE; - -// -// File Types Definitions -// -#define EFI_FV_FILETYPE_ALL 0x00 -#define EFI_FV_FILETYPE_RAW 0x01 -#define EFI_FV_FILETYPE_FREEFORM 0x02 -#define EFI_FV_FILETYPE_SECURITY_CORE 0x03 -#define EFI_FV_FILETYPE_PEI_CORE 0x04 -#define EFI_FV_FILETYPE_DXE_CORE 0x05 -#define EFI_FV_FILETYPE_PEIM 0x06 -#define EFI_FV_FILETYPE_DRIVER 0x07 -#define EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER 0x08 -#define EFI_FV_FILETYPE_APPLICATION 0x09 -#define EFI_FV_FILETYPE_SMM 0x0A -#define EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE 0x0B -#define EFI_FV_FILETYPE_COMBINED_SMM_DXE 0x0C -#define EFI_FV_FILETYPE_SMM_CORE 0x0D -#define EFI_FV_FILETYPE_MM_STANDALONE 0x0E -#define EFI_FV_FILETYPE_MM_CORE_STANDALONE 0x0F -#define EFI_FV_FILETYPE_OEM_MIN 0xc0 -#define EFI_FV_FILETYPE_OEM_MAX 0xdf -#define EFI_FV_FILETYPE_DEBUG_MIN 0xe0 -#define EFI_FV_FILETYPE_DEBUG_MAX 0xef -#define EFI_FV_FILETYPE_FFS_MIN 0xf0 -#define EFI_FV_FILETYPE_FFS_MAX 0xff -#define EFI_FV_FILETYPE_FFS_PAD 0xf0 -// -// FFS File Attributes. -// -#define FFS_ATTRIB_LARGE_FILE 0x01 -#define FFS_ATTRIB_DATA_ALIGNMENT2 0x02 -#define FFS_ATTRIB_FIXED 0x04 -#define FFS_ATTRIB_DATA_ALIGNMENT 0x38 -#define FFS_ATTRIB_CHECKSUM 0x40 -// -// FFS_FIXED_CHECKSUM is the checksum value used when the -// FFS_ATTRIB_CHECKSUM attribute bit is clear -// -#define FFS_FIXED_CHECKSUM 0xAA - -// -// FFS File State Bits. -// -#define EFI_FILE_HEADER_CONSTRUCTION 0x01 -#define EFI_FILE_HEADER_VALID 0x02 -#define EFI_FILE_DATA_VALID 0x04 -#define EFI_FILE_MARKED_FOR_UPDATE 0x08 -#define EFI_FILE_DELETED 0x10 -#define EFI_FILE_HEADER_INVALID 0x20 - -#define EFI_FILE_ALL_STATE_BITS (EFI_FILE_HEADER_CONSTRUCTION | \ - EFI_FILE_HEADER_VALID | \ - EFI_FILE_DATA_VALID | \ - EFI_FILE_MARKED_FOR_UPDATE | \ - EFI_FILE_DELETED | \ - EFI_FILE_HEADER_INVALID \ - ) - -// -// Each file begins with the header that describe the -// contents and state of the files. -// -typedef struct { - EFI_GUID Name; - EFI_FFS_INTEGRITY_CHECK IntegrityCheck; - EFI_FV_FILETYPE Type; - EFI_FFS_FILE_ATTRIBUTES Attributes; - UINT8 Size[3]; - EFI_FFS_FILE_STATE State; -} EFI_FFS_FILE_HEADER; - -typedef struct { - EFI_GUID Name; - EFI_FFS_INTEGRITY_CHECK IntegrityCheck; - EFI_FV_FILETYPE Type; - EFI_FFS_FILE_ATTRIBUTES Attributes; - UINT8 Size[3]; - EFI_FFS_FILE_STATE State; - UINT64 ExtendedSize; -} EFI_FFS_FILE_HEADER2; +#include +#include #define MAX_FFS_SIZE 0x1000000 - -typedef UINT8 EFI_SECTION_TYPE; - -// -// Pseudo type. It is -// used as a wild card when retrieving sections. The section -// type EFI_SECTION_ALL matches all section types. -// -#define EFI_SECTION_ALL 0x00 - -// -// Encapsulation section Type values -// -#define EFI_SECTION_COMPRESSION 0x01 - -#define EFI_SECTION_GUID_DEFINED 0x02 - -// -// Leaf section Type values -// -#define EFI_SECTION_PE32 0x10 -#define EFI_SECTION_PIC 0x11 -#define EFI_SECTION_TE 0x12 -#define EFI_SECTION_DXE_DEPEX 0x13 -#define EFI_SECTION_VERSION 0x14 -#define EFI_SECTION_USER_INTERFACE 0x15 -#define EFI_SECTION_COMPATIBILITY16 0x16 -#define EFI_SECTION_FIRMWARE_VOLUME_IMAGE 0x17 -#define EFI_SECTION_FREEFORM_SUBTYPE_GUID 0x18 -#define EFI_SECTION_RAW 0x19 -#define EFI_SECTION_PEI_DEPEX 0x1B -#define EFI_SECTION_SMM_DEPEX 0x1C - -typedef struct { - UINT8 Size[3]; - EFI_SECTION_TYPE Type; -} EFI_COMMON_SECTION_HEADER; - -typedef struct { - UINT8 Size[3]; - EFI_SECTION_TYPE Type; - UINT32 ExtendedSize; -} EFI_COMMON_SECTION_HEADER2; - -#define MAX_SECTION_SIZE 0x1000000 +#define MAX_SECTION_SIZE 0x1000000 // -// Leaf section type that contains an -// IA-32 16-bit executable image. +// FFS File Attributes. // -typedef EFI_COMMON_SECTION_HEADER EFI_COMPATIBILITY16_SECTION; -typedef EFI_COMMON_SECTION_HEADER2 EFI_COMPATIBILITY16_SECTION2; +#define FFS_ATTRIB_DATA_ALIGNMENT2 FFS_ATTRIB_DATA_ALIGNMENT_2 // // CompressionType of EFI_COMPRESSION_SECTION. // -#define EFI_NOT_COMPRESSED 0x00 -#define EFI_STANDARD_COMPRESSION 0x01 #define TIANO_COMPRESS 0x02 -// -// An encapsulation section type in which the -// section data is compressed. -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; - UINT32 UncompressedLength; - UINT8 CompressionType; -} EFI_COMPRESSION_SECTION; - -typedef struct { - EFI_COMMON_SECTION_HEADER2 CommonHeader; - UINT32 UncompressedLength; - UINT8 CompressionType; -} EFI_COMPRESSION_SECTION2; - -// -// Leaf section which could be used to determine the dispatch order of DXEs. -// -typedef EFI_COMMON_SECTION_HEADER EFI_DXE_DEPEX_SECTION; -typedef EFI_COMMON_SECTION_HEADER2 EFI_DXE_DEPEX_SECTION2; - -// -// Leaf section witch contains a PI FV. -// -typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION; -typedef EFI_COMMON_SECTION_HEADER2 EFI_FIRMWARE_VOLUME_IMAGE_SECTION2; - -// -// Leaf section which contains a single GUID. -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; - EFI_GUID SubTypeGuid; -} EFI_FREEFORM_SUBTYPE_GUID_SECTION; - -typedef struct { - EFI_COMMON_SECTION_HEADER2 CommonHeader; - EFI_GUID SubTypeGuid; -} EFI_FREEFORM_SUBTYPE_GUID_SECTION2; - -// -// Attributes of EFI_GUID_DEFINED_SECTION -// -#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01 -#define EFI_GUIDED_SECTION_AUTH_STATUS_VALID 0x02 -// -// Leaf section which is encapsulation defined by specific GUID -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; - EFI_GUID SectionDefinitionGuid; - UINT16 DataOffset; - UINT16 Attributes; -} EFI_GUID_DEFINED_SECTION; - -typedef struct { - EFI_COMMON_SECTION_HEADER2 CommonHeader; - EFI_GUID SectionDefinitionGuid; - UINT16 DataOffset; - UINT16 Attributes; -} EFI_GUID_DEFINED_SECTION2; - -// -// Leaf section which contains PE32+ image. -// -typedef EFI_COMMON_SECTION_HEADER EFI_PE32_SECTION; -typedef EFI_COMMON_SECTION_HEADER2 EFI_PE32_SECTION2; - -// -// Leaf section which contains PIC image. -// -typedef EFI_COMMON_SECTION_HEADER EFI_PIC_SECTION; -typedef EFI_COMMON_SECTION_HEADER2 EFI_PIC_SECTION2; - -// -// Leaf section which used to determine the dispatch order of PEIMs. -// -typedef EFI_COMMON_SECTION_HEADER EFI_PEI_DEPEX_SECTION; -typedef EFI_COMMON_SECTION_HEADER2 EFI_PEI_DEPEX_SECTION2; - -// -// Leaf section which constains the position-independent-code image. -// -typedef EFI_COMMON_SECTION_HEADER EFI_TE_SECTION; -typedef EFI_COMMON_SECTION_HEADER2 EFI_TE_SECTION2; - -// -// Leaf section which contains an array of zero or more bytes. -// -typedef EFI_COMMON_SECTION_HEADER EFI_RAW_SECTION; -typedef EFI_COMMON_SECTION_HEADER2 EFI_RAW_SECTION2; - -// -// Leaf section which contains a unicode string that -// is human readable file name. -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; - - // - // Array of unicode string. - // - CHAR16 FileNameString[1]; -} EFI_USER_INTERFACE_SECTION; - -typedef struct { - EFI_COMMON_SECTION_HEADER2 CommonHeader; - - // - // Array of unicode string. - // - CHAR16 FileNameString[1]; -} EFI_USER_INTERFACE_SECTION2; - -// -// Leaf section which contains a numeric build number and -// an optional unicode string that represent the file revision. -// -typedef struct { - EFI_COMMON_SECTION_HEADER CommonHeader; - UINT16 BuildNumber; - CHAR16 VersionString[1]; -} EFI_VERSION_SECTION; - -typedef struct { - EFI_COMMON_SECTION_HEADER2 CommonHeader; - UINT16 BuildNumber; - CHAR16 VersionString[1]; -} EFI_VERSION_SECTION2; - -// -// The argument passed as the SectionHeaderPtr parameter to the SECTION_SIZE() -// function-like macro below must not have side effects: SectionHeaderPtr is -// evaluated multiple times. -// -#define SECTION_SIZE(SectionHeaderPtr) ((UINT32) ( \ - (((EFI_COMMON_SECTION_HEADER *) (SectionHeaderPtr))->Size[0] ) | \ - (((EFI_COMMON_SECTION_HEADER *) (SectionHeaderPtr))->Size[1] << 8) | \ - (((EFI_COMMON_SECTION_HEADER *) (SectionHeaderPtr))->Size[2] << 16))) - -#pragma pack() typedef union { EFI_COMMON_SECTION_HEADER *CommonHeader; diff --git a/BaseTools/Source/C/Include/Common/PiFirmwareVolume.h b/BaseTools/Source/C/Include/Common/PiFirmwareVolume.h index 35afbdf00a..f0d28dae30 100644 --- a/BaseTools/Source/C/Include/Common/PiFirmwareVolume.h +++ b/BaseTools/Source/C/Include/Common/PiFirmwareVolume.h @@ -10,148 +10,9 @@ **/ -#ifndef __PI_FIRMWAREVOLUME_H__ -#define __PI_FIRMWAREVOLUME_H__ +#ifndef __BT_PI_FIRMWAREVOLUME_H__ +#define __BT_PI_FIRMWAREVOLUME_H__ -// -// EFI_FV_FILE_ATTRIBUTES -// -typedef UINT32 EFI_FV_FILE_ATTRIBUTES; - -// -// Value of EFI_FV_FILE_ATTRIBUTES. -// -#define EFI_FV_FILE_ATTRIB_ALIGNMENT 0x0000001F -#define EFI_FV_FILE_ATTRIB_FIXED 0x00000100 -#define EFI_FV_FILE_ATTRIB_MEMORY_MAPPED 0x00000200 - -typedef UINT32 EFI_FVB_ATTRIBUTES_2; - -// -// Attributes bit definitions -// -#define EFI_FVB2_READ_DISABLED_CAP 0x00000001 -#define EFI_FVB2_READ_ENABLED_CAP 0x00000002 -#define EFI_FVB2_READ_STATUS 0x00000004 -#define EFI_FVB2_WRITE_DISABLED_CAP 0x00000008 -#define EFI_FVB2_WRITE_ENABLED_CAP 0x00000010 -#define EFI_FVB2_WRITE_STATUS 0x00000020 -#define EFI_FVB2_LOCK_CAP 0x00000040 -#define EFI_FVB2_LOCK_STATUS 0x00000080 -#define EFI_FVB2_STICKY_WRITE 0x00000200 -#define EFI_FVB2_MEMORY_MAPPED 0x00000400 -#define EFI_FVB2_ERASE_POLARITY 0x00000800 -#define EFI_FVB2_READ_LOCK_CAP 0x00001000 -#define EFI_FVB2_READ_LOCK_STATUS 0x00002000 -#define EFI_FVB2_WRITE_LOCK_CAP 0x00004000 -#define EFI_FVB2_WRITE_LOCK_STATUS 0x00008000 -#define EFI_FVB2_ALIGNMENT 0x001F0000 -#define EFI_FVB2_WEAK_ALIGNMENT 0x80000000 -#define EFI_FVB2_ALIGNMENT_1 0x00000000 -#define EFI_FVB2_ALIGNMENT_2 0x00010000 -#define EFI_FVB2_ALIGNMENT_4 0x00020000 -#define EFI_FVB2_ALIGNMENT_8 0x00030000 -#define EFI_FVB2_ALIGNMENT_16 0x00040000 -#define EFI_FVB2_ALIGNMENT_32 0x00050000 -#define EFI_FVB2_ALIGNMENT_64 0x00060000 -#define EFI_FVB2_ALIGNMENT_128 0x00070000 -#define EFI_FVB2_ALIGNMENT_256 0x00080000 -#define EFI_FVB2_ALIGNMENT_512 0x00090000 -#define EFI_FVB2_ALIGNMENT_1K 0x000A0000 -#define EFI_FVB2_ALIGNMENT_2K 0x000B0000 -#define EFI_FVB2_ALIGNMENT_4K 0x000C0000 -#define EFI_FVB2_ALIGNMENT_8K 0x000D0000 -#define EFI_FVB2_ALIGNMENT_16K 0x000E0000 -#define EFI_FVB2_ALIGNMENT_32K 0x000F0000 -#define EFI_FVB2_ALIGNMENT_64K 0x00100000 -#define EFI_FVB2_ALIGNMENT_128K 0x00110000 -#define EFI_FVB2_ALIGNMENT_256K 0x00120000 -#define EFI_FVB2_ALIGNMENT_512K 0x00130000 -#define EFI_FVB2_ALIGNMENT_1M 0x00140000 -#define EFI_FVB2_ALIGNMENT_2M 0x00150000 -#define EFI_FVB2_ALIGNMENT_4M 0x00160000 -#define EFI_FVB2_ALIGNMENT_8M 0x00170000 -#define EFI_FVB2_ALIGNMENT_16M 0x00180000 -#define EFI_FVB2_ALIGNMENT_32M 0x00190000 -#define EFI_FVB2_ALIGNMENT_64M 0x001A0000 -#define EFI_FVB2_ALIGNMENT_128M 0x001B0000 -#define EFI_FVB2_ALIGNMENT_256M 0x001C0000 -#define EFI_FVB2_ALIGNMENT_512M 0x001D0000 -#define EFI_FVB2_ALIGNMENT_1G 0x001E0000 -#define EFI_FVB2_ALIGNMENT_2G 0x001F0000 - - -typedef struct { - UINT32 NumBlocks; - UINT32 Length; -} EFI_FV_BLOCK_MAP_ENTRY; - -// -// Describes the features and layout of the firmware volume. -// -typedef struct { - UINT8 ZeroVector[16]; - EFI_GUID FileSystemGuid; - UINT64 FvLength; - UINT32 Signature; - EFI_FVB_ATTRIBUTES_2 Attributes; - UINT16 HeaderLength; - UINT16 Checksum; - UINT16 ExtHeaderOffset; - UINT8 Reserved[1]; - UINT8 Revision; - EFI_FV_BLOCK_MAP_ENTRY BlockMap[1]; -} EFI_FIRMWARE_VOLUME_HEADER; - -#define EFI_FVH_SIGNATURE SIGNATURE_32 ('_', 'F', 'V', 'H') - -/// -/// Firmware Volume Header Revision definition -/// -#define EFI_FVH_REVISION 0x02 - -// -// Extension header pointed by ExtHeaderOffset of volume header. -// -typedef struct { - EFI_GUID FvName; - UINT32 ExtHeaderSize; -} EFI_FIRMWARE_VOLUME_EXT_HEADER; - -typedef struct { - UINT16 ExtEntrySize; - UINT16 ExtEntryType; -} EFI_FIRMWARE_VOLUME_EXT_ENTRY; - -#define EFI_FV_EXT_TYPE_OEM_TYPE 0x01 -typedef struct { - EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr; - UINT32 TypeMask; - - // - // Array of GUIDs. - // Each GUID represents an OEM file type. - // - // EFI_GUID Types[1]; - // -} EFI_FIRMWARE_VOLUME_EXT_ENTRY_OEM_TYPE; - -#define EFI_FV_EXT_TYPE_GUID_TYPE 0x0002 -typedef struct { - EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr; - EFI_GUID FormatType; - - // - // An array of bytes of length Length. - // - // UINT8 Data[1]; - // -} EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE; - -#define EFI_FV_EXT_TYPE_USED_SIZE_TYPE 0x03 -typedef struct { - EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr; - UINT32 UsedSize; -} EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE; +#include #endif diff --git a/BaseTools/Source/C/Include/Common/UefiBaseTypes.h b/BaseTools/Source/C/Include/Common/UefiBaseTypes.h index acf179af23..a47549cc9b 100644 --- a/BaseTools/Source/C/Include/Common/UefiBaseTypes.h +++ b/BaseTools/Source/C/Include/Common/UefiBaseTypes.h @@ -7,162 +7,10 @@ **/ -#ifndef __UEFI_BASETYPE_H__ -#define __UEFI_BASETYPE_H__ +#ifndef __BT_UEFI_BASETYPE_H__ +#define __BT_UEFI_BASETYPE_H__ #include - -// -// Basical data type definitions introduced in UEFI. -// -typedef struct { - UINT32 Data1; - UINT16 Data2; - UINT16 Data3; - UINT8 Data4[8]; -} EFI_GUID; - -typedef RETURN_STATUS EFI_STATUS; -typedef VOID *EFI_HANDLE; - -typedef VOID *EFI_EVENT; - -typedef UINTN EFI_TPL; - - -typedef UINT64 EFI_LBA; - - -typedef UINT16 STRING_REF; - -typedef UINT64 EFI_PHYSICAL_ADDRESS; -typedef UINT64 EFI_VIRTUAL_ADDRESS; - -// -// EFI Time Abstraction: -// Year: 2000 - 20XX -// Month: 1 - 12 -// Day: 1 - 31 -// Hour: 0 - 23 -// Minute: 0 - 59 -// Second: 0 - 59 -// Nanosecond: 0 - 999,999,999 -// TimeZone: -1440 to 1440 or 2047 -// -typedef struct { - UINT16 Year; - UINT8 Month; - UINT8 Day; - UINT8 Hour; - UINT8 Minute; - UINT8 Second; - UINT8 Pad1; - UINT32 Nanosecond; - INT16 TimeZone; - UINT8 Daylight; - UINT8 Pad2; -} EFI_TIME; - - -// -// Networking Definitions -// -typedef struct { - UINT8 Addr[4]; -} EFI_IPv4_ADDRESS; - -typedef struct { - UINT8 Addr[16]; -} EFI_IPv6_ADDRESS; - -typedef struct { - UINT8 Addr[32]; -} EFI_MAC_ADDRESS; - -typedef union { - UINT32 Addr[4]; - EFI_IPv4_ADDRESS v4; - EFI_IPv6_ADDRESS v6; -} EFI_IP_ADDRESS; - - -// -// Enumeration of EFI_STATUS. -// -#define EFI_SUCCESS RETURN_SUCCESS -#define EFI_LOAD_ERROR RETURN_LOAD_ERROR -#define EFI_INVALID_PARAMETER RETURN_INVALID_PARAMETER -#define EFI_UNSUPPORTED RETURN_UNSUPPORTED -#define EFI_BAD_BUFFER_SIZE RETURN_BAD_BUFFER_SIZE -#define EFI_BUFFER_TOO_SMALL RETURN_BUFFER_TOO_SMALL -#define EFI_NOT_READY RETURN_NOT_READY -#define EFI_DEVICE_ERROR RETURN_DEVICE_ERROR -#define EFI_WRITE_PROTECTED RETURN_WRITE_PROTECTED -#define EFI_OUT_OF_RESOURCES RETURN_OUT_OF_RESOURCES -#define EFI_VOLUME_CORRUPTED RETURN_VOLUME_CORRUPTED -#define EFI_VOLUME_FULL RETURN_VOLUME_FULL -#define EFI_NO_MEDIA RETURN_NO_MEDIA -#define EFI_MEDIA_CHANGED RETURN_MEDIA_CHANGED -#define EFI_NOT_FOUND RETURN_NOT_FOUND -#define EFI_ACCESS_DENIED RETURN_ACCESS_DENIED -#define EFI_NO_RESPONSE RETURN_NO_RESPONSE -#define EFI_NO_MAPPING RETURN_NO_MAPPING -#define EFI_TIMEOUT RETURN_TIMEOUT -#define EFI_NOT_STARTED RETURN_NOT_STARTED -#define EFI_ALREADY_STARTED RETURN_ALREADY_STARTED -#define EFI_ABORTED RETURN_ABORTED -#define EFI_ICMP_ERROR RETURN_ICMP_ERROR -#define EFI_TFTP_ERROR RETURN_TFTP_ERROR -#define EFI_PROTOCOL_ERROR RETURN_PROTOCOL_ERROR -#define EFI_INCOMPATIBLE_VERSION RETURN_INCOMPATIBLE_VERSION -#define EFI_SECURITY_VIOLATION RETURN_SECURITY_VIOLATION -#define EFI_CRC_ERROR RETURN_CRC_ERROR -#define EFI_END_OF_MEDIA RETURN_END_OF_MEDIA -#define EFI_END_OF_FILE RETURN_END_OF_FILE - -#define EFI_WARN_UNKNOWN_GLYPH RETURN_WARN_UNKNOWN_GLYPH -#define EFI_WARN_DELETE_FAILURE RETURN_WARN_DELETE_FAILURE -#define EFI_WARN_WRITE_FAILURE RETURN_WARN_WRITE_FAILURE -#define EFI_WARN_BUFFER_TOO_SMALL RETURN_WARN_BUFFER_TOO_SMALL - - -#define NULL_HANDLE ((VOID *) 0) - -// -// Define macro to encode the status code. -// -#define EFIERR(_a) ENCODE_ERROR(_a) - -#define EFI_ERROR(A) RETURN_ERROR(A) - -// -// Define macros to build data structure signatures from characters. -// -#define SIGNATURE_16(A, B) ((A) | (B << 8)) -#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16)) -#define SIGNATURE_64(A, B, C, D, E, F, G, H) \ - (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32)) - - -// -// Returns the byte offset to a field within a structure -// -#define EFI_FIELD_OFFSET(TYPE,Field) ((UINTN)(&(((TYPE *) 0)->Field))) - -// -// The EFI memory allocation functions work in units of EFI_PAGEs that are -// 4K. This should in no way be confused with the page size of the processor. -// An EFI_PAGE is just the quanta of memory in EFI. -// -#define EFI_PAGE_SIZE 0x1000 -#define EFI_PAGE_MASK 0xFFF -#define EFI_PAGE_SHIFT 12 - -#define EFI_SIZE_TO_PAGES(a) (((a) >> EFI_PAGE_SHIFT) + (((a) & EFI_PAGE_MASK) ? 1 : 0)) - -#define EFI_PAGES_TO_SIZE(a) ( (a) << EFI_PAGE_SHIFT) - - -#define EFI_MAX_BIT MAX_BIT +#include #endif diff --git a/BaseTools/Source/C/Include/Common/UefiCapsule.h b/BaseTools/Source/C/Include/Common/UefiCapsule.h index ecfe3a0a7a..01beb6b84f 100644 --- a/BaseTools/Source/C/Include/Common/UefiCapsule.h +++ b/BaseTools/Source/C/Include/Common/UefiCapsule.h @@ -9,18 +9,10 @@ **/ -#ifndef _EFI_CAPSULE_H_ -#define _EFI_CAPSULE_H_ +#ifndef _BT_EFI_CAPSULE_H_ +#define _BT_EFI_CAPSULE_H_ -typedef struct { - EFI_GUID CapsuleGuid; - UINT32 HeaderSize; - UINT32 Flags; - UINT32 CapsuleImageSize; -} EFI_CAPSULE_HEADER; +#include +#include -#define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000 -#define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000 -#define CAPSULE_FLAGS_INITIATE_RESET 0x00040000 - -#endif // #ifndef _EFI_CAPSULE_H_ +#endif // #ifndef _EFI_CAPSULE_H_ diff --git a/BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h b/BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h index cb009ed68e..76b8f8254a 100644 --- a/BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h +++ b/BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h @@ -13,1678 +13,13 @@ **/ -#ifndef __UEFI_INTERNAL_FORMREPRESENTATION_H__ -#define __UEFI_INTERNAL_FORMREPRESENTATION_H__ +#ifndef __BT_UEFI_INTERNAL_FORMREPRESENTATION_H__ +#define __BT_UEFI_INTERNAL_FORMREPRESENTATION_H__ -#define EFI_HII_PLATFORM_SETUP_FORMSET_GUID \ - { 0x93039971, 0x8545, 0x4b04, { 0xb4, 0x5e, 0x32, 0xeb, 0x83, 0x26, 0x4, 0xe } } +#include +#include -// -// The following types are currently defined: -// -typedef UINT32 RELOFST; - -typedef VOID* EFI_HII_HANDLE; -typedef CHAR16* EFI_STRING; -typedef UINT16 EFI_IMAGE_ID; -typedef UINT16 EFI_QUESTION_ID; -typedef UINT16 EFI_STRING_ID; -typedef UINT16 EFI_FORM_ID; -typedef UINT16 EFI_VARSTORE_ID; -typedef UINT16 EFI_DEFAULT_ID; -typedef UINT32 EFI_HII_FONT_STYLE; - - - -#pragma pack(1) - - -// -// HII package list -// -typedef struct { - EFI_GUID PackageListGuid; - UINT32 PackageLength; -} EFI_HII_PACKAGE_LIST_HEADER; - -/** - - Each package starts with a header, as defined above, which - indicates the size and type of the package. When added to a - pointer pointing to the start of the header, Length points at - the next package. The package lists form a package list when - concatenated together and terminated with an - EFI_HII_PACKAGE_HEADER with a Type of EFI_HII_PACKAGE_END. The - type EFI_HII_PACKAGE_TYPE_GUID is used for vendor-defined HII - packages, whose contents are determined by the Guid. The range - of package types starting with EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN - through EFI_HII_PACKAGE_TYPE_SYSTEM_END are reserved for system - firmware implementers. - - @param Length The size of the package in bytes. - - @param Type The package type. See EFI_HII_PACKAGE_TYPE_x, - below. - - @param Data The package data, the format of which is - determined by Type. - -**/ -typedef struct { - UINT32 Length:24; - UINT32 Type:8; - // UINT8 Data[...]; -} EFI_HII_PACKAGE_HEADER; - -// -// EFI_HII_PACKAGE_TYPE_x. -// -#define EFI_HII_PACKAGE_TYPE_ALL 0x00 -#define EFI_HII_PACKAGE_TYPE_GUID 0x01 -#define EFI_HII_PACKAGE_FORM 0x02 -#define EFI_HII_PACKAGE_KEYBOARD_LAYOUT 0x03 -#define EFI_HII_PACKAGE_STRINGS 0x04 -#define EFI_HII_PACKAGE_FONTS 0x05 -#define EFI_HII_PACKAGE_IMAGES 0x06 -#define EFI_HII_PACKAGE_SIMPLE_FONTS 0x07 -#define EFI_HII_PACKAGE_DEVICE_PATH 0x08 -#define EFI_HII_PACKAGE_END 0xDF -#define EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN 0xE0 -#define EFI_HII_PACKAGE_TYPE_SYSTEM_END 0xFF - -// -// Simplified Font Package -// - -#define EFI_GLYPH_HEIGHT 19 -#define EFI_GLYPH_WIDTH 8 -// -// Contents of EFI_NARROW_GLYPH.Attributes -// -#define EFI_GLYPH_NON_SPACING 0x01 -#define EFI_GLYPH_WIDE 0x02 - -typedef struct { - CHAR16 UnicodeWeight; - UINT8 Attributes; - UINT8 GlyphCol1[EFI_GLYPH_HEIGHT]; -} EFI_NARROW_GLYPH; - -typedef struct { - CHAR16 UnicodeWeight; - UINT8 Attributes; - UINT8 GlyphCol1[EFI_GLYPH_HEIGHT]; - UINT8 GlyphCol2[EFI_GLYPH_HEIGHT]; - UINT8 Pad[3]; -} EFI_WIDE_GLYPH; - - -typedef struct _EFI_HII_SIMPLE_FONT_PACKAGE_HDR { - EFI_HII_PACKAGE_HEADER Header; - UINT16 NumberOfNarrowGlyphs; - UINT16 NumberOfWideGlyphs; - // EFI_NARROW_GLYPH NarrowGlyphs[]; - // EFI_WIDE_GLYPH WideGlyphs[]; -} EFI_HII_SIMPLE_FONT_PACKAGE_HDR; - -// -// Font Package -// - -#define EFI_HII_FONT_STYLE_BOLD 0x00000001 -#define EFI_HII_FONT_STYLE_ITALIC 0x00000002 -#define EFI_HII_FONT_STYLE_EMBOSS 0x00010000 -#define EFI_HII_FONT_STYLE_OUTLINE 0x00020000 -#define EFI_HII_FONT_STYLE_SHADOW 0x00040000 -#define EFI_HII_FONT_STYLE_UNDERLINE 0x00080000 -#define EFI_HII_FONT_STYLE_DBL_UNDER 0x00100000 - -typedef struct _EFI_HII_GLYPH_INFO { - UINT16 Width; - UINT16 Height; - INT16 OffsetX; - INT16 OffsetY; - INT16 AdvanceX; -} EFI_HII_GLYPH_INFO; - -typedef struct _EFI_HII_FONT_PACKAGE_HDR { - EFI_HII_PACKAGE_HEADER Header; - UINT32 HdrSize; - UINT32 GlyphBlockOffset; - EFI_HII_GLYPH_INFO Cell; - EFI_HII_FONT_STYLE FontStyle; - CHAR16 FontFamily[1]; -} EFI_HII_FONT_PACKAGE_HDR; - -#define EFI_HII_GIBT_END 0x00 -#define EFI_HII_GIBT_GLYPH 0x10 -#define EFI_HII_GIBT_GLYPHS 0x11 -#define EFI_HII_GIBT_GLYPH_DEFAULT 0x12 -#define EFI_HII_GIBT_GLYPHS_DEFAULT 0x13 -#define EFI_HII_GIBT_GLYPH_VARIABILITY 0x14 -#define EFI_HII_GIBT_DUPLICATE 0x20 -#define EFI_HII_GIBT_SKIP2 0x21 -#define EFI_HII_GIBT_SKIP1 0x22 -#define EFI_HII_GIBT_DEFAULTS 0x23 -#define EFI_HII_GIBT_EXT1 0x30 -#define EFI_HII_GIBT_EXT2 0x31 -#define EFI_HII_GIBT_EXT4 0x32 - -typedef struct _EFI_HII_GLYPH_BLOCK { - UINT8 BlockType; -} EFI_HII_GLYPH_BLOCK; - -typedef struct _EFI_HII_GIBT_DEFAULTS_BLOCK { - EFI_HII_GLYPH_BLOCK Header; - EFI_HII_GLYPH_INFO Cell; -} EFI_HII_GIBT_DEFAULTS_BLOCK; - -typedef struct _EFI_HII_GIBT_DUPLICATE_BLOCK { - EFI_HII_GLYPH_BLOCK Header; - CHAR16 CharValue; -} EFI_HII_GIBT_DUPLICATE_BLOCK; - -typedef struct _EFI_GLYPH_GIBT_END_BLOCK { - EFI_HII_GLYPH_BLOCK Header; -} EFI_GLYPH_GIBT_END_BLOCK; - -typedef struct _EFI_HII_GIBT_EXT1_BLOCK { - EFI_HII_GLYPH_BLOCK Header; - UINT8 BlockType2; - UINT8 Length; -} EFI_HII_GIBT_EXT1_BLOCK; - -typedef struct _EFI_HII_GIBT_EXT2_BLOCK { - EFI_HII_GLYPH_BLOCK Header; - UINT8 BlockType2; - UINT16 Length; -} EFI_HII_GIBT_EXT2_BLOCK; - -typedef struct _EFI_HII_GIBT_EXT4_BLOCK { - EFI_HII_GLYPH_BLOCK Header; - UINT8 BlockType2; - UINT32 Length; -} EFI_HII_GIBT_EXT4_BLOCK; - -typedef struct _EFI_HII_GIBT_GLYPH_BLOCK { - EFI_HII_GLYPH_BLOCK Header; - EFI_HII_GLYPH_INFO Cell; - UINT8 BitmapData[1]; // the number of bytes per bitmap can be calculated by ((Cell.Width+7)/8)*Cell.Height -} EFI_HII_GIBT_GLYPH_BLOCK; - -typedef struct _EFI_HII_GIBT_GLYPHS_BLOCK { - EFI_HII_GLYPH_BLOCK Header; - EFI_HII_GLYPH_INFO Cell; - UINT16 Count; - UINT8 BitmapData[1]; // the number of bytes per bitmap can be calculated by ((Cell.Width+7)/8)*Cell.Height -} EFI_HII_GIBT_GLYPHS_BLOCK; - -typedef struct _EFI_HII_GIBT_GLYPH_DEFAULT_BLOCK { - EFI_HII_GLYPH_BLOCK Header; - UINT8 BitmapData[1]; // the number of bytes per bitmap can be calculated by ((Global.Cell.Width+7)/8)*Global.Cell.Height -} EFI_HII_GIBT_GLYPH_DEFAULT_BLOCK; - -typedef struct _EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK { - EFI_HII_GLYPH_BLOCK Header; - UINT16 Count; - UINT8 BitmapData[1]; // the number of bytes per bitmap can be calculated by ((Global.Cell.Width+7)/8)*Global.Cell.Height -} EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK; - -typedef struct _EFI_HII_GIBT_VARIABILITY_BLOCK { - EFI_HII_GLYPH_BLOCK Header; - EFI_HII_GLYPH_INFO Cell; - UINT8 GlyphPackInBits; - UINT8 BitmapData [1]; -} EFI_HII_GIBT_VARIABILITY_BLOCK; - -typedef struct _EFI_HII_GIBT_SKIP1_BLOCK { - EFI_HII_GLYPH_BLOCK Header; - UINT8 SkipCount; -} EFI_HII_GIBT_SKIP1_BLOCK; - -typedef struct _EFI_HII_GIBT_SKIP2_BLOCK { - EFI_HII_GLYPH_BLOCK Header; - UINT16 SkipCount; -} EFI_HII_GIBT_SKIP2_BLOCK; - -// -// Device Path Package -// -typedef struct _EFI_HII_DEVICE_PATH_PACKAGE { - EFI_HII_PACKAGE_HEADER Header; - // EFI_DEVICE_PATH_PROTOCOL DevicePath[]; -} EFI_HII_DEVICE_PATH_PACKAGE; - -// -// GUID Package -// -typedef struct _EFI_HII_GUID_PACKAGE_HDR { - EFI_HII_PACKAGE_HEADER Header; - EFI_GUID Guid; - // Data per GUID definition may follow -} EFI_HII_GUID_PACKAGE_HDR; - -// -// String Package -// - -#define UEFI_CONFIG_LANG "x-UEFI" -#define UEFI_CONFIG_LANG2 "x-i-UEFI" - -typedef struct _EFI_HII_STRING_PACKAGE_HDR { - EFI_HII_PACKAGE_HEADER Header; - UINT32 HdrSize; - UINT32 StringInfoOffset; - CHAR16 LanguageWindow[16]; - EFI_STRING_ID LanguageName; - CHAR8 Language[1]; -} EFI_HII_STRING_PACKAGE_HDR; - -typedef struct { - UINT8 BlockType; -} EFI_HII_STRING_BLOCK; - -#define EFI_HII_SIBT_END 0x00 -#define EFI_HII_SIBT_STRING_SCSU 0x10 -#define EFI_HII_SIBT_STRING_SCSU_FONT 0x11 -#define EFI_HII_SIBT_STRINGS_SCSU 0x12 -#define EFI_HII_SIBT_STRINGS_SCSU_FONT 0x13 -#define EFI_HII_SIBT_STRING_UCS2 0x14 -#define EFI_HII_SIBT_STRING_UCS2_FONT 0x15 -#define EFI_HII_SIBT_STRINGS_UCS2 0x16 -#define EFI_HII_SIBT_STRINGS_UCS2_FONT 0x17 -#define EFI_HII_SIBT_DUPLICATE 0x20 -#define EFI_HII_SIBT_SKIP2 0x21 -#define EFI_HII_SIBT_SKIP1 0x22 -#define EFI_HII_SIBT_EXT1 0x30 -#define EFI_HII_SIBT_EXT2 0x31 -#define EFI_HII_SIBT_EXT4 0x32 -#define EFI_HII_SIBT_FONT 0x40 - -typedef struct _EFI_HII_SIBT_DUPLICATE_BLOCK { - EFI_HII_STRING_BLOCK Header; - EFI_STRING_ID StringId; -} EFI_HII_SIBT_DUPLICATE_BLOCK; - -typedef struct _EFI_HII_SIBT_END_BLOCK { - EFI_HII_STRING_BLOCK Header; -} EFI_HII_SIBT_END_BLOCK; - -typedef struct _EFI_HII_SIBT_EXT1_BLOCK { - EFI_HII_STRING_BLOCK Header; - UINT8 BlockType2; - UINT8 Length; -} EFI_HII_SIBT_EXT1_BLOCK; - -typedef struct _EFI_HII_SIBT_EXT2_BLOCK { - EFI_HII_STRING_BLOCK Header; - UINT8 BlockType2; - UINT16 Length; -} EFI_HII_SIBT_EXT2_BLOCK; - -typedef struct _EFI_HII_SIBT_EXT4_BLOCK { - EFI_HII_STRING_BLOCK Header; - UINT8 BlockType2; - UINT32 Length; -} EFI_HII_SIBT_EXT4_BLOCK; - -typedef struct _EFI_HII_SIBT_FONT_BLOCK { - EFI_HII_SIBT_EXT2_BLOCK Header; - UINT8 FontId; - UINT16 FontSize; - EFI_HII_FONT_STYLE FontStyle; - CHAR16 FontName[1]; -} EFI_HII_SIBT_FONT_BLOCK; - -typedef struct _EFI_HII_SIBT_SKIP1_BLOCK { - EFI_HII_STRING_BLOCK Header; - UINT8 SkipCount; -} EFI_HII_SIBT_SKIP1_BLOCK; - -typedef struct _EFI_HII_SIBT_SKIP2_BLOCK { - EFI_HII_STRING_BLOCK Header; - UINT16 SkipCount; -} EFI_HII_SIBT_SKIP2_BLOCK; - -typedef struct _EFI_HII_SIBT_STRING_SCSU_BLOCK { - EFI_HII_STRING_BLOCK Header; - UINT8 StringText[1]; -} EFI_HII_SIBT_STRING_SCSU_BLOCK; - -typedef struct _EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK { - EFI_HII_STRING_BLOCK Header; - UINT8 FontIdentifier; - UINT8 StringText[1]; -} EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK; - -typedef struct _EFI_HII_SIBT_STRINGS_SCSU_BLOCK { - EFI_HII_STRING_BLOCK Header; - UINT16 StringCount; - UINT8 StringText[1]; -} EFI_HII_SIBT_STRINGS_SCSU_BLOCK; - -typedef struct _EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK { - EFI_HII_STRING_BLOCK Header; - UINT8 FontIdentifier; - UINT16 StringCount; - UINT8 StringText[1]; -} EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK; - -typedef struct _EFI_HII_SIBT_STRING_UCS2_BLOCK { - EFI_HII_STRING_BLOCK Header; - CHAR16 StringText[1]; -} EFI_HII_SIBT_STRING_UCS2_BLOCK; - -typedef struct _EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK { - EFI_HII_STRING_BLOCK Header; - UINT8 FontIdentifier; - CHAR16 StringText[1]; -} EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK; - -typedef struct _EFI_HII_SIBT_STRINGS_UCS2_BLOCK { - EFI_HII_STRING_BLOCK Header; - UINT16 StringCount; - CHAR16 StringText[1]; -} EFI_HII_SIBT_STRINGS_UCS2_BLOCK; - -typedef struct _EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK { - EFI_HII_STRING_BLOCK Header; - UINT8 FontIdentifier; - UINT16 StringCount; - CHAR16 StringText[1]; -} EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK; - -// -// Image Packages -// - -typedef struct _EFI_HII_IMAGE_PACKAGE_HDR { - EFI_HII_PACKAGE_HEADER Header; - UINT32 ImageInfoOffset; - UINT32 PaletteInfoOffset; -} EFI_HII_IMAGE_PACKAGE_HDR; - -typedef struct _EFI_HII_IMAGE_BLOCK { - UINT8 BlockType; -} EFI_HII_IMAGE_BLOCK; - -#define EFI_HII_IIBT_END 0x00 -#define EFI_HII_IIBT_IMAGE_1BIT 0x10 -#define EFI_HII_IIBT_IMAGE_1BIT_TRANS 0x11 -#define EFI_HII_IIBT_IMAGE_4BIT 0x12 -#define EFI_HII_IIBT_IMAGE_4BIT_TRANS 0x13 -#define EFI_HII_IIBT_IMAGE_8BIT 0x14 -#define EFI_HII_IIBT_IMAGE_8BIT_TRANS 0x15 -#define EFI_HII_IIBT_IMAGE_24BIT 0x16 -#define EFI_HII_IIBT_IMAGE_24BIT_TRANS 0x17 -#define EFI_HII_IIBT_IMAGE_JPEG 0x18 -#define EFI_HII_IIBT_IMAGE_PNG 0x19 -#define EFI_HII_IIBT_DUPLICATE 0x20 -#define EFI_HII_IIBT_SKIP2 0x21 -#define EFI_HII_IIBT_SKIP1 0x22 -#define EFI_HII_IIBT_EXT1 0x30 -#define EFI_HII_IIBT_EXT2 0x31 -#define EFI_HII_IIBT_EXT4 0x32 - -typedef struct _EFI_HII_IIBT_END_BLOCK { - EFI_HII_IMAGE_BLOCK Header; -} EFI_HII_IIBT_END_BLOCK; - -typedef struct _EFI_HII_IIBT_EXT1_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - UINT8 BlockType2; - UINT8 Length; -} EFI_HII_IIBT_EXT1_BLOCK; - -typedef struct _EFI_HII_IIBT_EXT2_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - UINT8 BlockType2; - UINT16 Length; -} EFI_HII_IIBT_EXT2_BLOCK; - -typedef struct _EFI_HII_IIBT_EXT4_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - UINT8 BlockType2; - UINT32 Length; -} EFI_HII_IIBT_EXT4_BLOCK; - -typedef struct _EFI_HII_IIBT_IMAGE_1BIT_BASE { - UINT16 Width; - UINT16 Height; - UINT8 Data[1]; -} EFI_HII_IIBT_IMAGE_1BIT_BASE; - -typedef struct _EFI_HII_IIBT_IMAGE_1BIT_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - UINT8 PaletteIndex; - EFI_HII_IIBT_IMAGE_1BIT_BASE Bitmap; -} EFI_HII_IIBT_IMAGE_1BIT_BLOCK; - -typedef struct _EFI_HII_IIBT_IMAGE_1BIT_TRANS_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - UINT8 PaletteIndex; - EFI_HII_IIBT_IMAGE_1BIT_BASE Bitmap; -} EFI_HII_IIBT_IMAGE_1BIT_TRANS_BLOCK; - -typedef struct _EFI_HII_RGB_PIXEL { - UINT8 b; - UINT8 g; - UINT8 r; -} EFI_HII_RGB_PIXEL; - -typedef struct _EFI_HII_IIBT_IMAGE_24BIT_BASE { - UINT16 Width; - UINT16 Height; - EFI_HII_RGB_PIXEL Bitmap[1]; -} EFI_HII_IIBT_IMAGE_24BIT_BASE; - -typedef struct _EFI_HII_IIBT_IMAGE_24BIT_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - EFI_HII_IIBT_IMAGE_24BIT_BASE Bitmap; -} EFI_HII_IIBT_IMAGE_24BIT_BLOCK; - -typedef struct _EFI_HII_IIBT_IMAGE_24BIT_TRANS_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - EFI_HII_IIBT_IMAGE_24BIT_BASE Bitmap; -} EFI_HII_IIBT_IMAGE_24BIT_TRANS_BLOCK; - -typedef struct _EFI_HII_IIBT_IMAGE_4BIT_BASE { - UINT16 Width; - UINT16 Height; - UINT8 Data[1]; -} EFI_HII_IIBT_IMAGE_4BIT_BASE; - -typedef struct _EFI_HII_IIBT_IMAGE_4BIT_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - UINT8 PaletteIndex; - EFI_HII_IIBT_IMAGE_4BIT_BASE Bitmap; -} EFI_HII_IIBT_IMAGE_4BIT_BLOCK; - -typedef struct _EFI_HII_IIBT_IMAGE_4BIT_TRANS_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - UINT8 PaletteIndex; - EFI_HII_IIBT_IMAGE_4BIT_BASE Bitmap; -} EFI_HII_IIBT_IMAGE_4BIT_TRANS_BLOCK; - -typedef struct _EFI_HII_IIBT_IMAGE_8BIT_BASE { - UINT16 Width; - UINT16 Height; - UINT8 Data[1]; -} EFI_HII_IIBT_IMAGE_8BIT_BASE; - -typedef struct _EFI_HII_IIBT_IMAGE_8BIT_PALETTE_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - UINT8 PaletteIndex; - EFI_HII_IIBT_IMAGE_8BIT_BASE Bitmap; -} EFI_HII_IIBT_IMAGE_8BIT_BLOCK; - -typedef struct _EFI_HII_IIBT_IMAGE_8BIT_TRANS_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - UINT8 PaletteIndex; - EFI_HII_IIBT_IMAGE_8BIT_BASE Bitmap; -} EFI_HII_IIBT_IMAGE_8BIT_TRAN_BLOCK; - -typedef struct _EFI_HII_IIBT_DUPLICATE_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - EFI_IMAGE_ID ImageId; -} EFI_HII_IIBT_DUPLICATE_BLOCK; - -typedef struct _EFI_HII_IIBT_JPEG_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - UINT32 Size; - UINT8 Data[1]; -} EFI_HII_IIBT_JPEG_BLOCK; - -typedef struct _EFI_HII_IIBT_PNG_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - UINT32 Size; - UINT8 Data[1]; -} EFI_HII_IIBT_PNG_BLOCK; - -typedef struct _EFI_HII_IIBT_SKIP1_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - UINT8 SkipCount; -} EFI_HII_IIBT_SKIP1_BLOCK; - -typedef struct _EFI_HII_IIBT_SKIP2_BLOCK { - EFI_HII_IMAGE_BLOCK Header; - UINT16 SkipCount; -} EFI_HII_IIBT_SKIP2_BLOCK; - -typedef struct _EFI_HII_IMAGE_PALETTE_INFO_HEADER { - UINT16 PaletteCount; -} EFI_HII_IMAGE_PALETTE_INFO_HEADER; - -typedef struct _EFI_HII_IMAGE_PALETTE_INFO { - UINT16 PaletteSize; - EFI_HII_RGB_PIXEL PaletteValue[1]; -} EFI_HII_IMAGE_PALETTE_INFO; - -// -// Forms Package -// - -typedef struct _EFI_HII_FORM_PACKAGE { - EFI_HII_PACKAGE_HEADER Header; - // EFI_IFR_OP_HEADER OpCodeHeader; - // More op-codes follow -} EFI_HII_FORM_PACKAGE; - -typedef struct { - UINT8 Hour; - UINT8 Minute; - UINT8 Second; -} EFI_HII_TIME; - -typedef struct { - UINT16 Year; - UINT8 Month; - UINT8 Day; -} EFI_HII_DATE; - -typedef struct { - EFI_QUESTION_ID QuestionId; - EFI_FORM_ID FormId; - EFI_GUID FormSetGuid; - EFI_STRING_ID DevicePath; -} EFI_HII_REF; - -typedef union { - UINT8 u8; - UINT16 u16; - UINT32 u32; - UINT64 u64; - BOOLEAN b; - EFI_HII_TIME time; - EFI_HII_DATE date; - EFI_STRING_ID string; - EFI_HII_REF ref; -} EFI_IFR_TYPE_VALUE; - -#define EFI_IFR_FORM_OP 0x01 -#define EFI_IFR_SUBTITLE_OP 0x02 -#define EFI_IFR_TEXT_OP 0x03 -#define EFI_IFR_IMAGE_OP 0x04 -#define EFI_IFR_ONE_OF_OP 0x05 -#define EFI_IFR_CHECKBOX_OP 0x06 -#define EFI_IFR_NUMERIC_OP 0x07 -#define EFI_IFR_PASSWORD_OP 0x08 -#define EFI_IFR_ONE_OF_OPTION_OP 0x09 -#define EFI_IFR_SUPPRESS_IF_OP 0x0A -#define EFI_IFR_LOCKED_OP 0x0B -#define EFI_IFR_ACTION_OP 0x0C -#define EFI_IFR_RESET_BUTTON_OP 0x0D -#define EFI_IFR_FORM_SET_OP 0x0E -#define EFI_IFR_REF_OP 0x0F -#define EFI_IFR_NO_SUBMIT_IF_OP 0x10 -#define EFI_IFR_INCONSISTENT_IF_OP 0x11 -#define EFI_IFR_EQ_ID_VAL_OP 0x12 -#define EFI_IFR_EQ_ID_ID_OP 0x13 -#define EFI_IFR_EQ_ID_VAL_LIST_OP 0x14 -#define EFI_IFR_AND_OP 0x15 -#define EFI_IFR_OR_OP 0x16 -#define EFI_IFR_NOT_OP 0x17 -#define EFI_IFR_RULE_OP 0x18 -#define EFI_IFR_GRAY_OUT_IF_OP 0x19 -#define EFI_IFR_DATE_OP 0x1A -#define EFI_IFR_TIME_OP 0x1B -#define EFI_IFR_STRING_OP 0x1C -#define EFI_IFR_REFRESH_OP 0x1D -#define EFI_IFR_DISABLE_IF_OP 0x1E -#define EFI_IFR_TO_LOWER_OP 0x20 -#define EFI_IFR_TO_UPPER_OP 0x21 -#define EFI_IFR_MAP_OP 0x22 -#define EFI_IFR_ORDERED_LIST_OP 0x23 -#define EFI_IFR_VARSTORE_OP 0x24 -#define EFI_IFR_VARSTORE_NAME_VALUE_OP 0x25 -#define EFI_IFR_VARSTORE_EFI_OP 0x26 -#define EFI_IFR_VARSTORE_DEVICE_OP 0x27 -#define EFI_IFR_VERSION_OP 0x28 -#define EFI_IFR_END_OP 0x29 -#define EFI_IFR_MATCH_OP 0x2A -#define EFI_IFR_GET_OP 0x2B -#define EFI_IFR_SET_OP 0x2C -#define EFI_IFR_READ_OP 0x2D -#define EFI_IFR_WRITE_OP 0x2E -#define EFI_IFR_EQUAL_OP 0x2F -#define EFI_IFR_NOT_EQUAL_OP 0x30 -#define EFI_IFR_GREATER_THAN_OP 0x31 -#define EFI_IFR_GREATER_EQUAL_OP 0x32 -#define EFI_IFR_LESS_THAN_OP 0x33 -#define EFI_IFR_LESS_EQUAL_OP 0x34 -#define EFI_IFR_BITWISE_AND_OP 0x35 -#define EFI_IFR_BITWISE_OR_OP 0x36 -#define EFI_IFR_BITWISE_NOT_OP 0x37 -#define EFI_IFR_SHIFT_LEFT_OP 0x38 -#define EFI_IFR_SHIFT_RIGHT_OP 0x39 -#define EFI_IFR_ADD_OP 0x3A -#define EFI_IFR_SUBTRACT_OP 0x3B -#define EFI_IFR_MULTIPLY_OP 0x3C -#define EFI_IFR_DIVIDE_OP 0x3D -#define EFI_IFR_MODULO_OP 0x3E -#define EFI_IFR_RULE_REF_OP 0x3F -#define EFI_IFR_QUESTION_REF1_OP 0x40 -#define EFI_IFR_QUESTION_REF2_OP 0x41 -#define EFI_IFR_UINT8_OP 0x42 -#define EFI_IFR_UINT16_OP 0x43 -#define EFI_IFR_UINT32_OP 0x44 -#define EFI_IFR_UINT64_OP 0x45 -#define EFI_IFR_TRUE_OP 0x46 -#define EFI_IFR_FALSE_OP 0x47 -#define EFI_IFR_TO_UINT_OP 0x48 -#define EFI_IFR_TO_STRING_OP 0x49 -#define EFI_IFR_TO_BOOLEAN_OP 0x4A -#define EFI_IFR_MID_OP 0x4B -#define EFI_IFR_FIND_OP 0x4C -#define EFI_IFR_TOKEN_OP 0x4D -#define EFI_IFR_STRING_REF1_OP 0x4E -#define EFI_IFR_STRING_REF2_OP 0x4F -#define EFI_IFR_CONDITIONAL_OP 0x50 -#define EFI_IFR_QUESTION_REF3_OP 0x51 -#define EFI_IFR_ZERO_OP 0x52 -#define EFI_IFR_ONE_OP 0x53 -#define EFI_IFR_ONES_OP 0x54 -#define EFI_IFR_UNDEFINED_OP 0x55 -#define EFI_IFR_LENGTH_OP 0x56 -#define EFI_IFR_DUP_OP 0x57 -#define EFI_IFR_THIS_OP 0x58 -#define EFI_IFR_SPAN_OP 0x59 -#define EFI_IFR_VALUE_OP 0x5A -#define EFI_IFR_DEFAULT_OP 0x5B -#define EFI_IFR_DEFAULTSTORE_OP 0x5C -#define EFI_IFR_FORM_MAP_OP 0x5D -#define EFI_IFR_CATENATE_OP 0x5E -#define EFI_IFR_GUID_OP 0x5F -#define EFI_IFR_SECURITY_OP 0x60 -#define EFI_IFR_MODAL_TAG_OP 0x61 -#define EFI_IFR_REFRESH_ID_OP 0x62 -#define EFI_IFR_WARNING_IF_OP 0x63 -#define EFI_IFR_MATCH2_OP 0x64 - - -typedef struct _EFI_IFR_OP_HEADER { - UINT8 OpCode; - UINT8 Length:7; - UINT8 Scope:1; -} EFI_IFR_OP_HEADER; - -typedef struct _EFI_IFR_STATEMENT_HEADER { - EFI_STRING_ID Prompt; - EFI_STRING_ID Help; -} EFI_IFR_STATEMENT_HEADER; - -typedef struct _EFI_IFR_QUESTION_HEADER { - EFI_IFR_STATEMENT_HEADER Header; - EFI_QUESTION_ID QuestionId; - EFI_VARSTORE_ID VarStoreId; - union { - EFI_STRING_ID VarName; - UINT16 VarOffset; - } VarStoreInfo; - UINT8 Flags; -} EFI_IFR_QUESTION_HEADER; - -#define EFI_IFR_FLAG_READ_ONLY 0x01 -#define EFI_IFR_FLAG_CALLBACK 0x04 -#define EFI_IFR_FLAG_RESET_REQUIRED 0x10 -#define EFI_IFR_FLAG_REST_STYLE 0x20 -#define EFI_IFR_FLAG_RECONNECT_REQUIRED 0x40 -#define EFI_IFR_FLAG_OPTIONS_ONLY 0x80 - -typedef struct _EFI_IFR_DEFAULTSTORE { - EFI_IFR_OP_HEADER Header; - EFI_STRING_ID DefaultName; - UINT16 DefaultId; -} EFI_IFR_DEFAULTSTORE; - -#define EFI_HII_DEFAULT_CLASS_STANDARD 0x0000 -#define EFI_HII_DEFAULT_CLASS_MANUFACTURING 0x0001 -#define EFI_HII_DEFAULT_CLASS_SAFE 0x0002 -#define EFI_HII_DEFAULT_CLASS_PLATFORM_BEGIN 0x4000 -#define EFI_HII_DEFAULT_CLASS_PLATFORM_END 0x7fff -#define EFI_HII_DEFAULT_CLASS_HARDWARE_BEGIN 0x8000 -#define EFI_HII_DEFAULT_CLASS_HARDWARE_END 0xbfff -#define EFI_HII_DEFAULT_CLASS_FIRMWARE_BEGIN 0xc000 -#define EFI_HII_DEFAULT_CLASS_FIRMWARE_END 0xffff - -typedef struct _EFI_IFR_VARSTORE { - EFI_IFR_OP_HEADER Header; - EFI_GUID Guid; - EFI_VARSTORE_ID VarStoreId; - UINT16 Size; - UINT8 Name[1]; -} EFI_IFR_VARSTORE; - -typedef struct _EFI_IFR_VARSTORE_EFI { - EFI_IFR_OP_HEADER Header; - EFI_VARSTORE_ID VarStoreId; - EFI_GUID Guid; - UINT32 Attributes; - UINT16 Size; - UINT8 Name[1]; -} EFI_IFR_VARSTORE_EFI; - -typedef struct _EFI_IFR_VARSTORE_NAME_VALUE { - EFI_IFR_OP_HEADER Header; - EFI_VARSTORE_ID VarStoreId; - EFI_GUID Guid; -} EFI_IFR_VARSTORE_NAME_VALUE; - -typedef struct _EFI_IFR_FORM_SET { - EFI_IFR_OP_HEADER Header; - EFI_GUID Guid; - EFI_STRING_ID FormSetTitle; - EFI_STRING_ID Help; - UINT8 Flags; - // EFI_GUID ClassGuid[]; -} EFI_IFR_FORM_SET; - -typedef struct _EFI_IFR_END { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_END; - -typedef struct _EFI_IFR_FORM { - EFI_IFR_OP_HEADER Header; - UINT16 FormId; - EFI_STRING_ID FormTitle; -} EFI_IFR_FORM; - -typedef struct _EFI_IFR_IMAGE { - EFI_IFR_OP_HEADER Header; - EFI_IMAGE_ID Id; -} EFI_IFR_IMAGE; - -typedef struct _EFI_IFR_MODAL_TAG { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_MODAL_TAG; - -typedef struct _EFI_IFR_LOCKED { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_LOCKED; - -typedef struct _EFI_IFR_RULE { - EFI_IFR_OP_HEADER Header; - UINT8 RuleId; -} EFI_IFR_RULE; - -typedef struct _EFI_IFR_DEFAULT { - EFI_IFR_OP_HEADER Header; - UINT16 DefaultId; - UINT8 Type; - EFI_IFR_TYPE_VALUE Value; -} EFI_IFR_DEFAULT; - -typedef struct _EFI_IFR_DEFAULT_2 { - EFI_IFR_OP_HEADER Header; - UINT16 DefaultId; - UINT8 Type; -} EFI_IFR_DEFAULT_2; - -typedef struct _EFI_IFR_VALUE { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_VALUE; - -typedef struct _EFI_IFR_SUBTITLE { - EFI_IFR_OP_HEADER Header; - EFI_IFR_STATEMENT_HEADER Statement; - UINT8 Flags; -} EFI_IFR_SUBTITLE; - -#define EFI_IFR_FLAGS_HORIZONTAL 0x01 - -typedef struct _EFI_IFR_CHECKBOX { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; - UINT8 Flags; -} EFI_IFR_CHECKBOX; - -#define EFI_IFR_CHECKBOX_DEFAULT 0x01 -#define EFI_IFR_CHECKBOX_DEFAULT_MFG 0x02 - -typedef struct _EFI_IFR_TEXT { - EFI_IFR_OP_HEADER Header; - EFI_IFR_STATEMENT_HEADER Statement; - EFI_STRING_ID TextTwo; -} EFI_IFR_TEXT; - -typedef struct _EFI_IFR_REF { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; - EFI_FORM_ID FormId; -} EFI_IFR_REF; - -typedef struct _EFI_IFR_REF2 { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; - EFI_FORM_ID FormId; - EFI_QUESTION_ID QuestionId; -} EFI_IFR_REF2; - -typedef struct _EFI_IFR_REF3 { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; - EFI_FORM_ID FormId; - EFI_QUESTION_ID QuestionId; - EFI_GUID FormSetId; -} EFI_IFR_REF3; - -typedef struct _EFI_IFR_REF4 { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; - EFI_FORM_ID FormId; - EFI_QUESTION_ID QuestionId; - EFI_GUID FormSetId; - EFI_STRING_ID DevicePath; -} EFI_IFR_REF4; - -typedef struct _EFI_IFR_REF5 { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; -} EFI_IFR_REF5; - -typedef struct _EFI_IFR_RESET_BUTTON { - EFI_IFR_OP_HEADER Header; - EFI_IFR_STATEMENT_HEADER Statement; - EFI_DEFAULT_ID DefaultId; -} EFI_IFR_RESET_BUTTON; - -typedef struct _EFI_IFR_ACTION { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; - EFI_STRING_ID QuestionConfig; -} EFI_IFR_ACTION; - -typedef struct _EFI_IFR_ACTION_1 { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; -} EFI_IFR_ACTION_1; - -typedef struct _EFI_IFR_DATE { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; - UINT8 Flags; -} EFI_IFR_DATE; - -#define EFI_QF_DATE_YEAR_SUPPRESS 0x01 -#define EFI_QF_DATE_MONTH_SUPPRESS 0x02 -#define EFI_QF_DATE_DAY_SUPPRESS 0x04 - -#define EFI_QF_DATE_STORAGE 0x30 -#define QF_DATE_STORAGE_NORMAL 0x00 -#define QF_DATE_STORAGE_TIME 0x10 -#define QF_DATE_STORAGE_WAKEUP 0x20 - -typedef union { - struct { - UINT8 MinValue; - UINT8 MaxValue; - UINT8 Step; - } u8; - struct { - UINT16 MinValue; - UINT16 MaxValue; - UINT16 Step; - } u16; - struct { - UINT32 MinValue; - UINT32 MaxValue; - UINT32 Step; - } u32; - struct { - UINT64 MinValue; - UINT64 MaxValue; - UINT64 Step; - } u64; -} MINMAXSTEP_DATA; - -typedef struct _EFI_IFR_NUMERIC { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; - UINT8 Flags; - MINMAXSTEP_DATA data; -} EFI_IFR_NUMERIC; - -#define EFI_IFR_NUMERIC_SIZE 0x03 -#define EFI_IFR_NUMERIC_SIZE_1 0x00 -#define EFI_IFR_NUMERIC_SIZE_2 0x01 -#define EFI_IFR_NUMERIC_SIZE_4 0x02 -#define EFI_IFR_NUMERIC_SIZE_8 0x03 - -#define EFI_IFR_DISPLAY 0x30 -#define EFI_IFR_DISPLAY_INT_DEC 0x00 -#define EFI_IFR_DISPLAY_UINT_DEC 0x10 -#define EFI_IFR_DISPLAY_UINT_HEX 0x20 - -typedef struct _EFI_IFR_ONE_OF { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; - UINT8 Flags; - MINMAXSTEP_DATA data; -} EFI_IFR_ONE_OF; - -typedef struct _EFI_IFR_STRING { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; - UINT8 MinSize; - UINT8 MaxSize; - UINT8 Flags; -} EFI_IFR_STRING; - -#define EFI_IFR_STRING_MULTI_LINE 0x01 - -typedef struct _EFI_IFR_PASSWORD { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; - UINT16 MinSize; - UINT16 MaxSize; -} EFI_IFR_PASSWORD; - -typedef struct _EFI_IFR_ORDERED_LIST { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; - UINT8 MaxContainers; - UINT8 Flags; -} EFI_IFR_ORDERED_LIST; - -#define EFI_IFR_UNIQUE_SET 0x01 -#define EFI_IFR_NO_EMPTY_SET 0x02 - -typedef struct _EFI_IFR_TIME { - EFI_IFR_OP_HEADER Header; - EFI_IFR_QUESTION_HEADER Question; - UINT8 Flags; -} EFI_IFR_TIME; - -#define QF_TIME_HOUR_SUPPRESS 0x01 -#define QF_TIME_MINUTE_SUPPRESS 0x02 -#define QF_TIME_SECOND_SUPPRESS 0x04 - -#define QF_TIME_STORAGE 0x30 -#define QF_TIME_STORAGE_NORMAL 0x00 -#define QF_TIME_STORAGE_TIME 0x10 -#define QF_TIME_STORAGE_WAKEUP 0x20 - -typedef struct _EFI_IFR_DISABLE_IF { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_DISABLE_IF; - -typedef struct _EFI_IFR_SUPPRESS_IF { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_SUPPRESS_IF; - -typedef struct _EFI_IFR_GRAY_OUT_IF { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_GRAY_OUT_IF; - -typedef struct _EFI_IFR_INCONSISTENT_IF { - EFI_IFR_OP_HEADER Header; - EFI_STRING_ID Error; -} EFI_IFR_INCONSISTENT_IF; - -typedef struct _EFI_IFR_NO_SUBMIT_IF { - EFI_IFR_OP_HEADER Header; - EFI_STRING_ID Error; -} EFI_IFR_NO_SUBMIT_IF; - -typedef struct _EFI_IFR_WARNING_IF { - EFI_IFR_OP_HEADER Header; - EFI_STRING_ID Warning; - UINT8 TimeOut; -} EFI_IFR_WARNING_IF; - -typedef struct _EFI_IFR_REFRESH { - EFI_IFR_OP_HEADER Header; - UINT8 RefreshInterval; -} EFI_IFR_REFRESH; - -typedef struct _EFI_IFR_REFRESH_ID { - EFI_IFR_OP_HEADER Header; - EFI_GUID RefreshEventGroupId; -} EFI_IFR_REFRESH_ID; - -typedef struct _EFI_IFR_VARSTORE_DEVICE { - EFI_IFR_OP_HEADER Header; - EFI_STRING_ID DevicePath; -} EFI_IFR_VARSTORE_DEVICE; - -typedef struct _EFI_IFR_ONE_OF_OPTION { - EFI_IFR_OP_HEADER Header; - EFI_STRING_ID Option; - UINT8 Flags; - UINT8 Type; - EFI_IFR_TYPE_VALUE Value; -} EFI_IFR_ONE_OF_OPTION; - -#define EFI_IFR_TYPE_NUM_SIZE_8 0x00 -#define EFI_IFR_TYPE_NUM_SIZE_16 0x01 -#define EFI_IFR_TYPE_NUM_SIZE_32 0x02 -#define EFI_IFR_TYPE_NUM_SIZE_64 0x03 -#define EFI_IFR_TYPE_BOOLEAN 0x04 -#define EFI_IFR_TYPE_TIME 0x05 -#define EFI_IFR_TYPE_DATE 0x06 -#define EFI_IFR_TYPE_STRING 0x07 -#define EFI_IFR_TYPE_OTHER 0x08 -#define EFI_IFR_TYPE_UNDEFINED 0x09 -#define EFI_IFR_TYPE_ACTION 0x0A -#define EFI_IFR_TYPE_BUFFER 0x0B -#define EFI_IFR_TYPE_REF 0x0C - -#define EFI_IFR_OPTION_DEFAULT 0x10 -#define EFI_IFR_OPTION_DEFAULT_MFG 0x20 - -typedef struct _EFI_IFR_GUID { - EFI_IFR_OP_HEADER Header; - EFI_GUID Guid; - //Optional Data Follows -} EFI_IFR_GUID; - -typedef struct _EFI_IFR_DUP { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_DUP; - -typedef struct _EFI_IFR_EQ_ID_ID { - EFI_IFR_OP_HEADER Header; - EFI_QUESTION_ID QuestionId1; - EFI_QUESTION_ID QuestionId2; -} EFI_IFR_EQ_ID_ID; - -typedef struct _EFI_IFR_EQ_ID_VAL { - EFI_IFR_OP_HEADER Header; - EFI_QUESTION_ID QuestionId; - UINT16 Value; -} EFI_IFR_EQ_ID_VAL; - -typedef struct _EFI_IFR_EQ_ID_VAL_LIST { - EFI_IFR_OP_HEADER Header; - EFI_QUESTION_ID QuestionId; - UINT16 ListLength; - UINT16 ValueList[1]; -} EFI_IFR_EQ_ID_VAL_LIST; - -typedef struct _EFI_IFR_QUESTION_REF1 { - EFI_IFR_OP_HEADER Header; - EFI_QUESTION_ID QuestionId; -} EFI_IFR_QUESTION_REF1; - -typedef struct _EFI_IFR_UINT8 { - EFI_IFR_OP_HEADER Header; - UINT8 Value; -} EFI_IFR_UINT8; - -typedef struct _EFI_IFR_UINT16 { - EFI_IFR_OP_HEADER Header; - UINT16 Value; -} EFI_IFR_UINT16; - -typedef struct _EFI_IFR_QUESTION_REF2 { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_QUESTION_REF2; - -typedef struct _EFI_IFR_UINT32 { - EFI_IFR_OP_HEADER Header; - UINT32 Value; -} EFI_IFR_UINT32; - -typedef struct _EFI_IFR_UINT64 { - EFI_IFR_OP_HEADER Header; - UINT64 Value; -} EFI_IFR_UINT64; - -typedef struct _EFI_IFR_QUESTION_REF3 { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_QUESTION_REF3; - -typedef struct _EFI_IFR_QUESTION_REF3_2 { - EFI_IFR_OP_HEADER Header; - EFI_STRING_ID DevicePath; -} EFI_IFR_QUESTION_REF3_2; - -typedef struct _EFI_IFR_QUESTION_REF3_3 { - EFI_IFR_OP_HEADER Header; - EFI_STRING_ID DevicePath; - EFI_GUID Guid; -} EFI_IFR_QUESTION_REF3_3; - -typedef struct _EFI_IFR_RULE_REF { - EFI_IFR_OP_HEADER Header; - UINT8 RuleId; -} EFI_IFR_RULE_REF; - -typedef struct _EFI_IFR_STRING_REF1 { - EFI_IFR_OP_HEADER Header; - EFI_STRING_ID StringId; -} EFI_IFR_STRING_REF1; - -typedef struct _EFI_IFR_STRING_REF2 { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_STRING_REF2; - -typedef struct _EFI_IFR_THIS { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_THIS; - -typedef struct _EFI_IFR_TRUE { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_TRUE; - -typedef struct _EFI_IFR_FALSE { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_FALSE; - -typedef struct _EFI_IFR_ONE { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_ONE; - -typedef struct _EFI_IFR_ONES { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_ONES; - -typedef struct _EFI_IFR_ZERO { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_ZERO; - -typedef struct _EFI_IFR_UNDEFINED { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_UNDEFINED; - -typedef struct _EFI_IFR_VERSION { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_VERSION; - -typedef struct _EFI_IFR_LENGTH { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_LENGTH; - -typedef struct _EFI_IFR_NOT { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_NOT; - -typedef struct _EFI_IFR_BITWISE_NOT { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_BITWISE_NOT; - -typedef struct _EFI_IFR_TO_BOOLEAN { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_TO_BOOLEAN; - -#define EFI_IFR_STRING_UNSIGNED_DEC 0 -#define EFI_IFR_STRING_SIGNED_DEC 1 -#define EFI_IFR_STRING_LOWERCASE_HEX 2 -#define EFI_IFR_STRING_UPPERCASE_HEX 3 - -#define EFI_IFR_STRING_ASCII 0 -#define EFI_IFR_STRING_UNICODE 8 - -typedef struct _EFI_IFR_TO_STRING { - EFI_IFR_OP_HEADER Header; - UINT8 Format; -} EFI_IFR_TO_STRING; - -typedef struct _EFI_IFR_TO_UINT { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_TO_UINT; - -typedef struct _EFI_IFR_TO_UPPER { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_TO_UPPER; - -typedef struct _EFI_IFR_TO_LOWER { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_TO_LOWER; - -typedef struct _EFI_IFR_ADD { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_ADD; - -typedef struct _EFI_IFR_AND { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_AND; - -typedef struct _EFI_IFR_BITWISE_AND { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_BITWISE_AND; - -typedef struct _EFI_IFR_BITWISE_OR { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_BITWISE_OR; - -typedef struct _EFI_IFR_CATENATE { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_CATENATE; - -typedef struct _EFI_IFR_DIVIDE { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_DIVIDE; - -typedef struct _EFI_IFR_EQUAL { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_EQUAL; - -typedef struct _EFI_IFR_GREATER_EQUAL { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_GREATER_EQUAL; - -typedef struct _EFI_IFR_GREATER_THAN { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_GREATER_THAN; - -typedef struct _EFI_IFR_LESS_EQUAL { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_LESS_EQUAL; - -typedef struct _EFI_IFR_LESS_THAN { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_LESS_THAN; - -typedef struct _EFI_IFR_MATCH { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_MATCH; - -typedef struct _EFI_IFR_MATCH2 { - EFI_IFR_OP_HEADER Header; - EFI_GUID SyntaxType; -} EFI_IFR_MATCH2; - -typedef struct _EFI_IFR_MULTIPLY { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_MULTIPLY; - -typedef struct _EFI_IFR_MODULO { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_MODULO; - -typedef struct _EFI_IFR_NOT_EQUAL { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_NOT_EQUAL; - -typedef struct _EFI_IFR_OR { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_OR; - -typedef struct _EFI_IFR_SHIFT_LEFT { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_SHIFT_LEFT; - -typedef struct _EFI_IFR_SHIFT_RIGHT { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_SHIFT_RIGHT; - -typedef struct _EFI_IFR_SUBTRACT { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_SUBTRACT; - -typedef struct _EFI_IFR_CONDITIONAL { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_CONDITIONAL; - -#define EFI_IFR_FF_CASE_SENSITIVE 0x00 -#define EFI_IFR_FF_CASE_INSENSITIVE 0x01 - -typedef struct _EFI_IFR_FIND { - EFI_IFR_OP_HEADER Header; - UINT8 Format; -} EFI_IFR_FIND; - -typedef struct _EFI_IFR_MID { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_MID; - -typedef struct _EFI_IFR_TOKEN { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_TOKEN; - -#define EFI_IFR_FLAGS_FIRST_MATCHING 0x00 -#define EFI_IFR_FLAGS_FIRST_NON_MATCHING 0x01 - -typedef struct _EFI_IFR_SPAN { - EFI_IFR_OP_HEADER Header; - UINT8 Flags; -} EFI_IFR_SPAN; - -typedef struct _EFI_IFR_SECURITY { - /// - /// Standard opcode header, where Header.Op = EFI_IFR_SECURITY_OP. - /// - EFI_IFR_OP_HEADER Header; - /// - /// Security permission level. - /// - EFI_GUID Permissions; -} EFI_IFR_SECURITY; - -typedef struct _EFI_IFR_FORM_MAP_METHOD { - /// - /// The string identifier which provides the human-readable name of - /// the configuration method for this standards map form. - /// - EFI_STRING_ID MethodTitle; - /// - /// Identifier which uniquely specifies the configuration methods - /// associated with this standards map form. - /// - EFI_GUID MethodIdentifier; -} EFI_IFR_FORM_MAP_METHOD; - -typedef struct _EFI_IFR_FORM_MAP { - /// - /// The sequence that defines the type of opcode as well as the length - /// of the opcode being defined. Header.OpCode = EFI_IFR_FORM_MAP_OP. - /// - EFI_IFR_OP_HEADER Header; - /// - /// The unique identifier for this particular form. - /// - EFI_FORM_ID FormId; - /// - /// One or more configuration method's name and unique identifier. - /// - // EFI_IFR_FORM_MAP_METHOD Methods[]; -} EFI_IFR_FORM_MAP; - -typedef struct _EFI_IFR_SET { - /// - /// The sequence that defines the type of opcode as well as the length - /// of the opcode being defined. Header.OpCode = EFI_IFR_SET_OP. - /// - EFI_IFR_OP_HEADER Header; - /// - /// Specifies the identifier of a previously declared variable store to - /// use when storing the question's value. - /// - EFI_VARSTORE_ID VarStoreId; - union { - /// - /// A 16-bit Buffer Storage offset. - /// - EFI_STRING_ID VarName; - /// - /// A Name Value or EFI Variable name (VarName). - /// - UINT16 VarOffset; - } VarStoreInfo; - /// - /// Specifies the type used for storage. - /// - UINT8 VarStoreType; -} EFI_IFR_SET; - -typedef struct _EFI_IFR_GET { - /// - /// The sequence that defines the type of opcode as well as the length - /// of the opcode being defined. Header.OpCode = EFI_IFR_GET_OP. - /// - EFI_IFR_OP_HEADER Header; - /// - /// Specifies the identifier of a previously declared variable store to - /// use when retrieving the value. - /// - EFI_VARSTORE_ID VarStoreId; - union { - /// - /// A 16-bit Buffer Storage offset. - /// - EFI_STRING_ID VarName; - /// - /// A Name Value or EFI Variable name (VarName). - /// - UINT16 VarOffset; - } VarStoreInfo; - /// - /// Specifies the type used for storage. - /// - UINT8 VarStoreType; -} EFI_IFR_GET; - -typedef struct _EFI_IFR_READ { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_READ; - -typedef struct _EFI_IFR_WRITE { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_WRITE; - -typedef struct _EFI_IFR_MAP { - EFI_IFR_OP_HEADER Header; -} EFI_IFR_MAP; -// -// Keyboard Package -// - -typedef enum { - EfiKeyLCtrl, - EfiKeyA0, - EfiKeyLAlt, - EfiKeySpaceBar, - EfiKeyA2, - EfiKeyA3, - EfiKeyA4, - EfiKeyRCtrl, - EfiKeyLeftArrow, - EfiKeyDownArrow, - EfiKeyRightArrow, - EfiKeyZero, - EfiKeyPeriod, - EfiKeyEnter, - EfiKeyLShift, - EfiKeyB0, - EfiKeyB1, - EfiKeyB2, - EfiKeyB3, - EfiKeyB4, - EfiKeyB5, - EfiKeyB6, - EfiKeyB7, - EfiKeyB8, - EfiKeyB9, - EfiKeyB10, - EfiKeyRshift, - EfiKeyUpArrow, - EfiKeyOne, - EfiKeyTwo, - EfiKeyThree, - EfiKeyCapsLock, - EfiKeyC1, - EfiKeyC2, - EfiKeyC3, - EfiKeyC4, - EfiKeyC5, - EfiKeyC6, - EfiKeyC7, - EfiKeyC8, - EfiKeyC9, - EfiKeyC10, - EfiKeyC11, - EfiKeyC12, - EfiKeyFour, - EfiKeyFive, - EfiKeySix, - EfiKeyPlus, - EfiKeyTab, - EfiKeyD1, - EfiKeyD2, - EfiKeyD3, - EfiKeyD4, - EfiKeyD5, - EfiKeyD6, - EfiKeyD7, - EfiKeyD8, - EfiKeyD9, - EfiKeyD10, - EfiKeyD11, - EfiKeyD12, - EfiKeyD13, - EfiKeyDel, - EfiKeyEnd, - EfiKeyPgDn, - EfiKeySeven, - EfiKeyEight, - EfiKeyNine, - EfiKeyE0, - EfiKeyE1, - EfiKeyE2, - EfiKeyE3, - EfiKeyE4, - EfiKeyE5, - EfiKeyE6, - EfiKeyE7, - EfiKeyE8, - EfiKeyE9, - EfiKeyE10, - EfiKeyE11, - EfiKeyE12, - EfiKeyBackSpace, - EfiKeyIns, - EfiKeyHome, - EfiKeyPgUp, - EfiKeyNLck, - EfiKeySlash, - EfiKeyAsterisk, - EfiKeyMinus, - EfiKeyEsc, - EfiKeyF1, - EfiKeyF2, - EfiKeyF3, - EfiKeyF4, - EfiKeyF5, - EfiKeyF6, - EfiKeyF7, - EfiKeyF8, - EfiKeyF9, - EfiKeyF10, - EfiKeyF11, - EfiKeyF12, - EfiKeyPrint, - EfiKeySLck, - EfiKeyPause, - EfiKeyIntl0, - EfiKeyIntl1, - EfiKeyIntl2, - EfiKeyIntl3, - EfiKeyIntl4, - EfiKeyIntl5, - EfiKeyIntl6, - EfiKeyIntl7, - EfiKeyIntl8, - EfiKeyIntl9 -} EFI_KEY; - -typedef struct { - EFI_KEY Key; - CHAR16 Unicode; - CHAR16 ShiftedUnicode; - CHAR16 AltGrUnicode; - CHAR16 ShiftedAltGrUnicode; - UINT16 Modifier; - UINT16 AffectedAttribute; -} EFI_KEY_DESCRIPTOR; - -// -// A key which is affected by all the standard shift modifiers. -// Most keys would be expected to have this bit active. -// -#define EFI_AFFECTED_BY_STANDARD_SHIFT 0x0001 -// -// This key is affected by the caps lock so that if a keyboard driver -// would need to disambiguate between a key which had a "1" defined -// versus a "a" character. Having this bit turned on would tell -// the keyboard driver to use the appropriate shifted state or not. -// -#define EFI_AFFECTED_BY_CAPS_LOCK 0x0002 -// -// Similar to the case of CAPS lock, if this bit is active, the key -// is affected by the num lock being turned on. -// -#define EFI_AFFECTED_BY_NUM_LOCK 0x0004 - -typedef struct { - UINT16 LayoutLength; - EFI_GUID Guid; - UINT32 LayoutDescriptorStringOffset; - UINT8 DescriptorCount; - // EFI_KEY_DESCRIPTOR Descriptors[]; -} EFI_HII_KEYBOARD_LAYOUT; - -typedef struct { - EFI_HII_PACKAGE_HEADER Header; - UINT16 LayoutCount; - // EFI_HII_KEYBOARD_LAYOUT Layout[]; -} EFI_HII_KEYBOARD_PACKAGE_HDR; - -typedef struct { - CHAR16 Language[3]; - CHAR16 Space; - CHAR16 DescriptionString[1]; -} EFI_DESCRIPTION_STRING; - -typedef struct { - UINT16 DescriptionCount; - EFI_DESCRIPTION_STRING DescriptionString[1]; -} EFI_DESCRIPTION_STRING_BUNDLE; - -// -// Modifier values -// -#define EFI_NULL_MODIFIER 0x0000 -#define EFI_LEFT_CONTROL_MODIFIER 0x0001 -#define EFI_RIGHT_CONTROL_MODIFIER 0x0002 -#define EFI_LEFT_ALT_MODIFIER 0x0003 -#define EFI_RIGHT_ALT_MODIFIER 0x0004 -#define EFI_ALT_GR_MODIFIER 0x0005 -#define EFI_INSERT_MODIFIER 0x0006 -#define EFI_DELETE_MODIFIER 0x0007 -#define EFI_PAGE_DOWN_MODIFIER 0x0008 -#define EFI_PAGE_UP_MODIFIER 0x0009 -#define EFI_HOME_MODIFIER 0x000A -#define EFI_END_MODIFIER 0x000B -#define EFI_LEFT_SHIFT_MODIFIER 0x000C -#define EFI_RIGHT_SHIFT_MODIFIER 0x000D -#define EFI_CAPS_LOCK_MODIFIER 0x000E -#define EFI_NUM_LOCK _MODIFIER 0x000F -#define EFI_LEFT_ARROW_MODIFIER 0x0010 -#define EFI_RIGHT_ARROW_MODIFIER 0x0011 -#define EFI_DOWN_ARROW_MODIFIER 0x0012 -#define EFI_UP_ARROW_MODIFIER 0x0013 -#define EFI_NS_KEY_MODIFIER 0x0014 -#define EFI_NS_KEY_DEPENDENCY_MODIFIER 0x0015 -#define EFI_FUNCTION_KEY_ONE_MODIFIER 0x0016 -#define EFI_FUNCTION_KEY_TWO_MODIFIER 0x0017 -#define EFI_FUNCTION_KEY_THREE_MODIFIER 0x0018 -#define EFI_FUNCTION_KEY_FOUR_MODIFIER 0x0019 -#define EFI_FUNCTION_KEY_FIVE_MODIFIER 0x001A -#define EFI_FUNCTION_KEY_SIX_MODIFIER 0x001B -#define EFI_FUNCTION_KEY_SEVEN_MODIFIER 0x001C -#define EFI_FUNCTION_KEY_EIGHT_MODIFIER 0x001D -#define EFI_FUNCTION_KEY_NINE_MODIFIER 0x001E -#define EFI_FUNCTION_KEY_TEN_MODIFIER 0x001F -#define EFI_FUNCTION_KEY_ELEVEN_MODIFIER 0x0020 -#define EFI_FUNCTION_KEY_TWELVE_MODIFIER 0x0021 - -// -// Keys that have multiple control functions based on modifier -// settings are handled in the keyboard driver implementation. -// For instance PRINT_KEY might have a modifier held down and -// is still a nonprinting character, but might have an alternate -// control function like SYSREQUEST -// -#define EFI_PRINT_MODIFIER 0x0022 -#define EFI_SYS_REQUEST_MODIFIER 0x0023 -#define EFI_SCROLL_LOCK_MODIFIER 0x0024 -#define EFI_PAUSE_MODIFIER 0x0025 -#define EFI_BREAK_MODIFIER 0x0026 - -#pragma pack() - - - -// -// References to string tokens must use this macro to enable scanning for -// token usages. -// -// -// STRING_TOKEN is not defined in UEFI specification. But it is placed -// here for the easy access by C files and VFR source files. -// -#define STRING_TOKEN(t) t +#define EFI_HII_PACKAGE_FORM EFI_HII_PACKAGE_FORMS #endif diff --git a/BaseTools/Source/C/Include/Common/VariableFormat.h b/BaseTools/Source/C/Include/Common/VariableFormat.h deleted file mode 100644 index 096db88bc7..0000000000 --- a/BaseTools/Source/C/Include/Common/VariableFormat.h +++ /dev/null @@ -1,44 +0,0 @@ -/**@file - Header file for EFI Variable Services. - - Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __VARIABLE_FORMAT_H__ -#define __VARIABLE_FORMAT_H__ - -#define VARIABLE_DATA 0x55AA - -// -// Variable Store Header flags -// -#define VARIABLE_STORE_FORMATTED 0x5a -#define VARIABLE_STORE_HEALTHY 0xfe - -#pragma pack(1) - -typedef struct { - EFI_GUID Signature; - UINT32 Size; - UINT8 Format; - UINT8 State; - UINT16 Reserved; - UINT32 Reserved1; -} VARIABLE_STORE_HEADER; - -typedef struct { - UINT16 StartId; - UINT8 State; - UINT8 Reserved; - UINT32 Attributes; - UINT32 NameSize; - UINT32 DataSize; - EFI_GUID VendorGuid; -} VARIABLE_HEADER; - -#pragma pack() - -#endif // _EFI_VARIABLE_H_ diff --git a/BaseTools/Source/C/Include/Common/WorkingBlockHeader.h b/BaseTools/Source/C/Include/Common/WorkingBlockHeader.h deleted file mode 100644 index a1b77dd3e8..0000000000 --- a/BaseTools/Source/C/Include/Common/WorkingBlockHeader.h +++ /dev/null @@ -1,35 +0,0 @@ -/** @file - Defines data structure that is the headers found at the runtime - updatable firmware volumes, such as the FileSystemGuid of the - working block, the header structure of the variable block, FTW - working block, or event log block. - - Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __EFI_WORKING_BLOCK_HEADER_H__ -#define __EFI_WORKING_BLOCK_HEADER_H__ - -// -// EFI Fault tolerant working block header -// The header is immediately followed by the write queue. -// -typedef struct { - EFI_GUID Signature; - UINT32 Crc; - UINT8 WorkingBlockValid : 1; - UINT8 WorkingBlockInvalid : 1; -#define WORKING_BLOCK_VALID 0x1 -#define WORKING_BLOCK_INVALID 0x2 - UINT8 Reserved : 6; - UINT8 Reserved3[3]; - UINT64 WriteQueueSize; - // - // UINT8 WriteQueue[WriteQueueSize]; - // -} EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER; - -#endif diff --git a/BaseTools/Source/C/Include/Guid/PcAnsi.h b/BaseTools/Source/C/Include/Guid/PcAnsi.h deleted file mode 100644 index 697cf418b9..0000000000 --- a/BaseTools/Source/C/Include/Guid/PcAnsi.h +++ /dev/null @@ -1,52 +0,0 @@ -/** @file - Terminal Device Path Vendor Guid. - @par Revision Reference: - GUIDs defined in UEFI 2.0 spec. - - Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __PC_ANSI_H__ -#define __PC_ANSI_H__ - -#define EFI_PC_ANSI_GUID \ - { \ - 0xe0c14753, 0xf9be, 0x11d2, {0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ - } - -#define EFI_VT_100_GUID \ - { \ - 0xdfa66065, 0xb419, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ - } - -#define EFI_VT_100_PLUS_GUID \ - { \ - 0x7baec70b, 0x57e0, 0x4c76, {0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43 } \ - } - -#define EFI_VT_UTF8_GUID \ - { \ - 0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88 } \ - } - -#define EFI_UART_DEVICE_PATH_GUID \ - { \ - 0x37499a9d, 0x542f, 0x4c89, {0xa0, 0x26, 0x35, 0xda, 0x14, 0x20, 0x94, 0xe4 } \ - } - -#define EFI_SAS_DEVICE_PATH_GUID \ - { \ - 0xd487ddb4, 0x008b, 0x11d9, {0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } \ - } - -extern EFI_GUID gEfiPcAnsiGuid; -extern EFI_GUID gEfiVT100Guid; -extern EFI_GUID gEfiVT100PlusGuid; -extern EFI_GUID gEfiVTUTF8Guid; -extern EFI_GUID gEfiUartDevicePathGuid; -extern EFI_GUID gEfiSasDevicePathGuid; - -#endif diff --git a/BaseTools/Source/C/Include/Guid/PiFirmwareFileSystem.h b/BaseTools/Source/C/Include/Guid/PiFirmwareFileSystem.h deleted file mode 100644 index 0483966beb..0000000000 --- a/BaseTools/Source/C/Include/Guid/PiFirmwareFileSystem.h +++ /dev/null @@ -1,39 +0,0 @@ -/** @file - Guid used to define the Firmware File System. See PI spec volume 3 for more - details. - - @par Revision Reference: - Guids defined in PI Spec Volume 3 - - Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __FIRMWARE_FILE_SYSTEM2_GUID_H__ -#define __FIRMWARE_FILE_SYSTEM2_GUID_H__ - -// -// GUIDs defined by the PI specification. -// -#define EFI_FIRMWARE_FILE_SYSTEM2_GUID \ - { \ - 0x8c8ce578, 0x8a3d, 0x4f1c, {0x99, 0x35, 0x89, 0x61, 0x85, 0xc3, 0x2d, 0xd3 } \ - } - -#define EFI_FIRMWARE_FILE_SYSTEM3_GUID \ - { \ - 0x5473c07a, 0x3dcb, 0x4dca, {0xbd, 0x6f, 0x1e, 0x96, 0x89, 0xe7, 0x34, 0x9a } \ - } - -#define EFI_FFS_VOLUME_TOP_FILE_GUID \ - { \ - 0x1BA0062E, 0xC779, 0x4582, {0x85, 0x66, 0x33, 0x6A, 0xE8, 0xF7, 0x8F, 0x09 } \ - } - -extern EFI_GUID gEfiFirmwareFileSystem2Guid; -extern EFI_GUID gEfiFirmwareFileSystem3Guid; -extern EFI_GUID gEfiFirmwareVolumeTopFileGuid; - -#endif diff --git a/BaseTools/Source/C/Include/Protocol/DevicePath.h b/BaseTools/Source/C/Include/Protocol/DevicePath.h deleted file mode 100644 index bcad2cfead..0000000000 --- a/BaseTools/Source/C/Include/Protocol/DevicePath.h +++ /dev/null @@ -1,1404 +0,0 @@ -/** @file - The device path protocol as defined in UEFI 2.0. - - The device path represents a programmatic path to a device, - from a software point of view. The path must persist from boot to boot, so - it can not contain things like PCI bus numbers that change from boot to boot. - -Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __EFI_DEVICE_PATH_H__ -#define __EFI_DEVICE_PATH_H__ - -#include -#include -#include - -/// -/// Device Path protocol. -/// -#define EFI_DEVICE_PATH_PROTOCOL_GUID \ - { \ - 0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ - } - -/// -/// Device Path guid definition for backward-compatible with EFI1.1. -/// -#define DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL_GUID - -#pragma pack(1) - -#if defined(_MSC_EXTENSIONS) -// -// Disable warning when last field of data structure is a zero sized array. -// -#pragma warning ( disable : 4200 ) -#endif - -/** - This protocol can be used on any device handle to obtain generic path/location - information concerning the physical device or logical device. If the handle does - not logically map to a physical device, the handle may not necessarily support - the device path protocol. The device path describes the location of the device - the handle is for. The size of the Device Path can be determined from the structures - that make up the Device Path. -**/ -typedef struct { - UINT8 Type; ///< 0x01 Hardware Device Path. - ///< 0x02 ACPI Device Path. - ///< 0x03 Messaging Device Path. - ///< 0x04 Media Device Path. - ///< 0x05 BIOS Boot Specification Device Path. - ///< 0x7F End of Hardware Device Path. - - UINT8 SubType; ///< Varies by Type - ///< 0xFF End Entire Device Path, or - ///< 0x01 End This Instance of a Device Path and start a new - ///< Device Path. - - UINT8 Length[2]; ///< Specific Device Path data. Type and Sub-Type define - ///< type of data. Size of data is included in Length. - -} EFI_DEVICE_PATH_PROTOCOL; - -/// -/// Device Path protocol definition for backward-compatible with EFI1.1. -/// -typedef EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH; - -/// -/// Hardware Device Paths. -/// -#define HARDWARE_DEVICE_PATH 0x01 - -/// -/// PCI Device Path SubType. -/// -#define HW_PCI_DP 0x01 - -/// -/// PCI Device Path. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// PCI Function Number. - /// - UINT8 Function; - /// - /// PCI Device Number. - /// - UINT8 Device; -} PCI_DEVICE_PATH; - -/// -/// PCCARD Device Path SubType. -/// -#define HW_PCCARD_DP 0x02 - -/// -/// PCCARD Device Path. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Function Number (0 = First Function). - /// - UINT8 FunctionNumber; -} PCCARD_DEVICE_PATH; - -/// -/// Memory Mapped Device Path SubType. -/// -#define HW_MEMMAP_DP 0x03 - -/// -/// Memory Mapped Device Path. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// EFI_MEMORY_TYPE - /// - UINT32 MemoryType; - /// - /// Starting Memory Address. - /// - EFI_PHYSICAL_ADDRESS StartingAddress; - /// - /// Ending Memory Address. - /// - EFI_PHYSICAL_ADDRESS EndingAddress; -} MEMMAP_DEVICE_PATH; - -/// -/// Hardware Vendor Device Path SubType. -/// -#define HW_VENDOR_DP 0x04 - -/// -/// The Vendor Device Path allows the creation of vendor-defined Device Paths. A vendor must -/// allocate a Vendor GUID for a Device Path. The Vendor GUID can then be used to define the -/// contents on the n bytes that follow in the Vendor Device Path node. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Vendor-assigned GUID that defines the data that follows. - /// - EFI_GUID Guid; - /// - /// Vendor-defined variable size data. - /// -} VENDOR_DEVICE_PATH; - -/// -/// Controller Device Path SubType. -/// -#define HW_CONTROLLER_DP 0x05 - -/// -/// Controller Device Path. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Controller number. - /// - UINT32 ControllerNumber; -} CONTROLLER_DEVICE_PATH; - -/// -/// BMC Device Path SubType. -/// -#define HW_BMC_DP 0x06 - -/// -/// BMC Device Path. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Interface Type. - /// - UINT8 InterfaceType; - /// - /// Base Address. - /// - UINT8 BaseAddress[8]; -} BMC_DEVICE_PATH; - -/// -/// ACPI Device Paths. -/// -#define ACPI_DEVICE_PATH 0x02 - -/// -/// ACPI Device Path SubType. -/// -#define ACPI_DP 0x01 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Device's PnP hardware ID stored in a numeric 32-bit - /// compressed EISA-type ID. This value must match the - /// corresponding _HID in the ACPI name space. - /// - UINT32 HID; - /// - /// Unique ID that is required by ACPI if two devices have the - /// same _HID. This value must also match the corresponding - /// _UID/_HID pair in the ACPI name space. Only the 32-bit - /// numeric value type of _UID is supported. Thus, strings must - /// not be used for the _UID in the ACPI name space. - /// - UINT32 UID; -} ACPI_HID_DEVICE_PATH; - -/// -/// Expanded ACPI Device Path SubType. -/// -#define ACPI_EXTENDED_DP 0x02 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Device's PnP hardware ID stored in a numeric 32-bit - /// compressed EISA-type ID. This value must match the - /// corresponding _HID in the ACPI name space. - /// - UINT32 HID; - /// - /// Unique ID that is required by ACPI if two devices have the - /// same _HID. This value must also match the corresponding - /// _UID/_HID pair in the ACPI name space. - /// - UINT32 UID; - /// - /// Device's compatible PnP hardware ID stored in a numeric - /// 32-bit compressed EISA-type ID. This value must match at - /// least one of the compatible device IDs returned by the - /// corresponding _CID in the ACPI name space. - /// - UINT32 CID; - /// - /// Optional variable length _HIDSTR. - /// Optional variable length _UIDSTR. - /// Optional variable length _CIDSTR. - /// -} ACPI_EXTENDED_HID_DEVICE_PATH; - -// -// EISA ID Macro -// EISA ID Definition 32-bits -// bits[15:0] - three character compressed ASCII EISA ID. -// bits[31:16] - binary number -// Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z' -// -#define PNP_EISA_ID_CONST 0x41d0 -#define EISA_ID(_Name, _Num) ((UINT32)((_Name) | (_Num) << 16)) -#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) -#define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) - -#define PNP_EISA_ID_MASK 0xffff -#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16) - -/// -/// ACPI _ADR Device Path SubType. -/// -#define ACPI_ADR_DP 0x03 - -/// -/// The _ADR device path is used to contain video output device attributes to support the Graphics -/// Output Protocol. The device path can contain multiple _ADR entries if multiple video output -/// devices are displaying the same output. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// _ADR value. For video output devices the value of this - /// field comes from Table B-2 of the ACPI 3.0 specification. At - /// least one _ADR value is required. - /// - UINT32 ADR; - // - // This device path may optionally contain more than one _ADR entry. - // -} ACPI_ADR_DEVICE_PATH; - -#define ACPI_ADR_DISPLAY_TYPE_OTHER 0 -#define ACPI_ADR_DISPLAY_TYPE_VGA 1 -#define ACPI_ADR_DISPLAY_TYPE_TV 2 -#define ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL 3 -#define ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL 4 - -#define ACPI_DISPLAY_ADR(_DeviceIdScheme, _HeadId, _NonVgaOutput, _BiosCanDetect, _VendorInfo, _Type, _Port, _Index) \ - ((UINT32)( ((UINT32)((_DeviceIdScheme) & 0x1) << 31) | \ - (((_HeadId) & 0x7) << 18) | \ - (((_NonVgaOutput) & 0x1) << 17) | \ - (((_BiosCanDetect) & 0x1) << 16) | \ - (((_VendorInfo) & 0xf) << 12) | \ - (((_Type) & 0xf) << 8) | \ - (((_Port) & 0xf) << 4) | \ - ((_Index) & 0xf) )) - -/// -/// Messaging Device Paths. -/// This Device Path is used to describe the connection of devices outside the resource domain of the -/// system. This Device Path can describe physical messaging information like SCSI ID, or abstract -/// information like networking protocol IP addresses. -/// -#define MESSAGING_DEVICE_PATH 0x03 - -/// -/// ATAPI Device Path SubType -/// -#define MSG_ATAPI_DP 0x01 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Set to zero for primary, or one for secondary. - /// - UINT8 PrimarySecondary; - /// - /// Set to zero for master, or one for slave mode. - /// - UINT8 SlaveMaster; - /// - /// Logical Unit Number. - /// - UINT16 Lun; -} ATAPI_DEVICE_PATH; - -/// -/// SCSI Device Path SubType. -/// -#define MSG_SCSI_DP 0x02 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Target ID on the SCSI bus (PUN). - /// - UINT16 Pun; - /// - /// Logical Unit Number (LUN). - /// - UINT16 Lun; -} SCSI_DEVICE_PATH; - -/// -/// Fibre Channel SubType. -/// -#define MSG_FIBRECHANNEL_DP 0x03 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Reserved for the future. - /// - UINT32 Reserved; - /// - /// Fibre Channel World Wide Number. - /// - UINT64 WWN; - /// - /// Fibre Channel Logical Unit Number. - /// - UINT64 Lun; -} FIBRECHANNEL_DEVICE_PATH; - -/// -/// Fibre Channel Ex SubType. -/// -#define MSG_FIBRECHANNELEX_DP 0x15 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Reserved for the future. - /// - UINT32 Reserved; - /// - /// 8 byte array containing Fibre Channel End Device Port Name. - /// - UINT8 WWN[8]; - /// - /// 8 byte array containing Fibre Channel Logical Unit Number. - /// - UINT8 Lun[8]; -} FIBRECHANNELEX_DEVICE_PATH; - -/// -/// 1394 Device Path SubType -/// -#define MSG_1394_DP 0x04 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Reserved for the future. - /// - UINT32 Reserved; - /// - /// 1394 Global Unique ID (GUID). - /// - UINT64 Guid; -} F1394_DEVICE_PATH; - -/// -/// USB Device Path SubType. -/// -#define MSG_USB_DP 0x05 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// USB Parent Port Number. - /// - UINT8 ParentPortNumber; - /// - /// USB Interface Number. - /// - UINT8 InterfaceNumber; -} USB_DEVICE_PATH; - -/// -/// USB Class Device Path SubType. -/// -#define MSG_USB_CLASS_DP 0x0f -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Vendor ID assigned by USB-IF. A value of 0xFFFF will - /// match any Vendor ID. - /// - UINT16 VendorId; - /// - /// Product ID assigned by USB-IF. A value of 0xFFFF will - /// match any Product ID. - /// - UINT16 ProductId; - /// - /// The class code assigned by the USB-IF. A value of 0xFF - /// will match any class code. - /// - UINT8 DeviceClass; - /// - /// The subclass code assigned by the USB-IF. A value of - /// 0xFF will match any subclass code. - /// - UINT8 DeviceSubClass; - /// - /// The protocol code assigned by the USB-IF. A value of - /// 0xFF will match any protocol code. - /// - UINT8 DeviceProtocol; -} USB_CLASS_DEVICE_PATH; - -/// -/// USB WWID Device Path SubType. -/// -#define MSG_USB_WWID_DP 0x10 - -/// -/// This device path describes a USB device using its serial number. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// USB interface number. - /// - UINT16 InterfaceNumber; - /// - /// USB vendor id of the device. - /// - UINT16 VendorId; - /// - /// USB product id of the device. - /// - UINT16 ProductId; - /// - /// Last 64-or-fewer UTF-16 characters of the USB - /// serial number. The length of the string is - /// determined by the Length field less the offset of the - /// Serial Number field (10) - /// - /// CHAR16 SerialNumber[...]; -} USB_WWID_DEVICE_PATH; - -/// -/// Device Logical Unit SubType. -/// -#define MSG_DEVICE_LOGICAL_UNIT_DP 0x11 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Logical Unit Number for the interface. - /// - UINT8 Lun; -} DEVICE_LOGICAL_UNIT_DEVICE_PATH; - -/// -/// SATA Device Path SubType. -/// -#define MSG_SATA_DP 0x12 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// The HBA port number that facilitates the connection to the - /// device or a port multiplier. The value 0xFFFF is reserved. - /// - UINT16 HBAPortNumber; - /// - /// The Port multiplier port number that facilitates the connection - /// to the device. Must be set to 0xFFFF if the device is directly - /// connected to the HBA. - /// - UINT16 PortMultiplierPortNumber; - /// - /// Logical Unit Number. - /// - UINT16 Lun; -} SATA_DEVICE_PATH; - -/// -/// Flag for if the device is directly connected to the HBA. -/// -#define SATA_HBA_DIRECT_CONNECT_FLAG 0x8000 - -/// -/// I2O Device Path SubType. -/// -#define MSG_I2O_DP 0x06 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Target ID (TID) for a device. - /// - UINT32 Tid; -} I2O_DEVICE_PATH; - -/// -/// MAC Address Device Path SubType. -/// -#define MSG_MAC_ADDR_DP 0x0b -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// The MAC address for a network interface padded with 0s. - /// - EFI_MAC_ADDRESS MacAddress; - /// - /// Network interface type(i.e. 802.3, FDDI). - /// - UINT8 IfType; -} MAC_ADDR_DEVICE_PATH; - -/// -/// IPv4 Device Path SubType -/// -#define MSG_IPv4_DP 0x0c -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// The local IPv4 address. - /// - EFI_IPv4_ADDRESS LocalIpAddress; - /// - /// The remote IPv4 address. - /// - EFI_IPv4_ADDRESS RemoteIpAddress; - /// - /// The local port number. - /// - UINT16 LocalPort; - /// - /// The remote port number. - /// - UINT16 RemotePort; - /// - /// The network protocol(i.e. UDP, TCP). - /// - UINT16 Protocol; - /// - /// 0x00 - The Source IP Address was assigned though DHCP. - /// 0x01 - The Source IP Address is statically bound. - /// - BOOLEAN StaticIpAddress; - /// - /// The gateway IP address - /// - EFI_IPv4_ADDRESS GatewayIpAddress; - /// - /// The subnet mask - /// - EFI_IPv4_ADDRESS SubnetMask; -} IPv4_DEVICE_PATH; - -/// -/// IPv6 Device Path SubType. -/// -#define MSG_IPv6_DP 0x0d -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// The local IPv6 address. - /// - EFI_IPv6_ADDRESS LocalIpAddress; - /// - /// The remote IPv6 address. - /// - EFI_IPv6_ADDRESS RemoteIpAddress; - /// - /// The local port number. - /// - UINT16 LocalPort; - /// - /// The remote port number. - /// - UINT16 RemotePort; - /// - /// The network protocol(i.e. UDP, TCP). - /// - UINT16 Protocol; - /// - /// 0x00 - The Local IP Address was manually configured. - /// 0x01 - The Local IP Address is assigned through IPv6 - /// stateless auto-configuration. - /// 0x02 - The Local IP Address is assigned through IPv6 - /// stateful configuration. - /// - UINT8 IpAddressOrigin; - /// - /// The prefix length - /// - UINT8 PrefixLength; - /// - /// The gateway IP address - /// - EFI_IPv6_ADDRESS GatewayIpAddress; -} IPv6_DEVICE_PATH; - -/// -/// InfiniBand Device Path SubType. -/// -#define MSG_INFINIBAND_DP 0x09 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Flags to help identify/manage InfiniBand device path elements: - /// Bit 0 - IOC/Service (0b = IOC, 1b = Service). - /// Bit 1 - Extend Boot Environment. - /// Bit 2 - Console Protocol. - /// Bit 3 - Storage Protocol. - /// Bit 4 - Network Protocol. - /// All other bits are reserved. - /// - UINT32 ResourceFlags; - /// - /// 128-bit Global Identifier for remote fabric port. - /// - UINT8 PortGid[16]; - /// - /// 64-bit unique identifier to remote IOC or server process. - /// Interpretation of field specified by Resource Flags (bit 0). - /// - UINT64 ServiceId; - /// - /// 64-bit persistent ID of remote IOC port. - /// - UINT64 TargetPortId; - /// - /// 64-bit persistent ID of remote device. - /// - UINT64 DeviceId; -} INFINIBAND_DEVICE_PATH; - -#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE 0x01 -#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT 0x02 -#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL 0x04 -#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL 0x08 -#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL 0x10 - -/// -/// UART Device Path SubType. -/// -#define MSG_UART_DP 0x0e -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Reserved. - /// - UINT32 Reserved; - /// - /// The baud rate setting for the UART style device. A value of 0 - /// means that the device's default baud rate will be used. - /// - UINT64 BaudRate; - /// - /// The number of data bits for the UART style device. A value - /// of 0 means that the device's default number of data bits will be used. - /// - UINT8 DataBits; - /// - /// The parity setting for the UART style device. - /// Parity 0x00 - Default Parity. - /// Parity 0x01 - No Parity. - /// Parity 0x02 - Even Parity. - /// Parity 0x03 - Odd Parity. - /// Parity 0x04 - Mark Parity. - /// Parity 0x05 - Space Parity. - /// - UINT8 Parity; - /// - /// The number of stop bits for the UART style device. - /// Stop Bits 0x00 - Default Stop Bits. - /// Stop Bits 0x01 - 1 Stop Bit. - /// Stop Bits 0x02 - 1.5 Stop Bits. - /// Stop Bits 0x03 - 2 Stop Bits. - /// - UINT8 StopBits; -} UART_DEVICE_PATH; - -/// -/// NVDIMM Namespace Device Path SubType. -/// -#define NVDIMM_NAMESPACE_DP 0x20 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Namespace unique label identifier UUID. - /// - EFI_GUID Uuid; -} NVDIMM_NAMESPACE_DEVICE_PATH; - -// -// Use VENDOR_DEVICE_PATH struct -// -#define MSG_VENDOR_DP 0x0a -typedef VENDOR_DEVICE_PATH VENDOR_DEFINED_DEVICE_PATH; - -#define DEVICE_PATH_MESSAGING_PC_ANSI EFI_PC_ANSI_GUID -#define DEVICE_PATH_MESSAGING_VT_100 EFI_VT_100_GUID -#define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID -#define DEVICE_PATH_MESSAGING_VT_UTF8 EFI_VT_UTF8_GUID - -/// -/// A new device path node is defined to declare flow control characteristics. -/// UART Flow Control Messaging Device Path -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL GUID. - /// - EFI_GUID Guid; - /// - /// Bitmap of supported flow control types. - /// Bit 0 set indicates hardware flow control. - /// Bit 1 set indicates Xon/Xoff flow control. - /// All other bits are reserved and are clear. - /// - UINT32 FlowControlMap; -} UART_FLOW_CONTROL_DEVICE_PATH; - -#define UART_FLOW_CONTROL_HARDWARE 0x00000001 -#define UART_FLOW_CONTROL_XON_XOFF 0x00000010 - -#define DEVICE_PATH_MESSAGING_SAS EFI_SAS_DEVICE_PATH_GUID -/// -/// Serial Attached SCSI (SAS) Device Path. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// DEVICE_PATH_MESSAGING_SAS GUID. - /// - EFI_GUID Guid; - /// - /// Reserved for future use. - /// - UINT32 Reserved; - /// - /// SAS Address for Serial Attached SCSI Target. - /// - UINT64 SasAddress; - /// - /// SAS Logical Unit Number. - /// - UINT64 Lun; - /// - /// More Information about the device and its interconnect. - /// - UINT16 DeviceTopology; - /// - /// Relative Target Port (RTP). - /// - UINT16 RelativeTargetPort; -} SAS_DEVICE_PATH; - -/// -/// Serial Attached SCSI (SAS) Ex Device Path SubType -/// -#define MSG_SASEX_DP 0x16 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// 8-byte array of the SAS Address for Serial Attached SCSI Target Port. - /// - UINT8 SasAddress[8]; - /// - /// 8-byte array of the SAS Logical Unit Number. - /// - UINT8 Lun[8]; - /// - /// More Information about the device and its interconnect. - /// - UINT16 DeviceTopology; - /// - /// Relative Target Port (RTP). - /// - UINT16 RelativeTargetPort; -} SASEX_DEVICE_PATH; - -/// -/// NvmExpress Namespace Device Path SubType. -/// -#define MSG_NVME_NAMESPACE_DP 0x17 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - UINT32 NamespaceId; - UINT64 NamespaceUuid; -} NVME_NAMESPACE_DEVICE_PATH; - -/// -/// DNS Device Path SubType -/// -#define MSG_DNS_DP 0x1F -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Indicates the DNS server address is IPv4 or IPv6 address. - /// - UINT8 IsIPv6; - /// - /// Instance of the DNS server address. - /// - EFI_IP_ADDRESS DnsServerIp[]; -} DNS_DEVICE_PATH; - -/// -/// Uniform Resource Identifiers (URI) Device Path SubType -/// -#define MSG_URI_DP 0x18 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Instance of the URI pursuant to RFC 3986. - /// - CHAR8 Uri[]; -} URI_DEVICE_PATH; - -/// -/// Universal Flash Storage (UFS) Device Path SubType. -/// -#define MSG_UFS_DP 0x19 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Target ID on the UFS bus (PUN). - /// - UINT8 Pun; - /// - /// Logical Unit Number (LUN). - /// - UINT8 Lun; -} UFS_DEVICE_PATH; - -/// -/// SD (Secure Digital) Device Path SubType. -/// -#define MSG_SD_DP 0x1A -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - UINT8 SlotNumber; -} SD_DEVICE_PATH; - -/// -/// EMMC (Embedded MMC) Device Path SubType. -/// -#define MSG_EMMC_DP 0x1D -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - UINT8 SlotNumber; -} EMMC_DEVICE_PATH; - -/// -/// iSCSI Device Path SubType -/// -#define MSG_ISCSI_DP 0x13 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Network Protocol (0 = TCP, 1+ = reserved). - /// - UINT16 NetworkProtocol; - /// - /// iSCSI Login Options. - /// - UINT16 LoginOption; - /// - /// iSCSI Logical Unit Number. - /// - UINT64 Lun; - /// - /// iSCSI Target Portal group tag the initiator intends - /// to establish a session with. - /// - UINT16 TargetPortalGroupTag; - /// - /// iSCSI NodeTarget Name. The length of the name - /// is determined by subtracting the offset of this field from Length. - /// - /// CHAR8 iSCSI Target Name. -} ISCSI_DEVICE_PATH; - -#define ISCSI_LOGIN_OPTION_NO_HEADER_DIGEST 0x0000 -#define ISCSI_LOGIN_OPTION_HEADER_DIGEST_USING_CRC32C 0x0002 -#define ISCSI_LOGIN_OPTION_NO_DATA_DIGEST 0x0000 -#define ISCSI_LOGIN_OPTION_DATA_DIGEST_USING_CRC32C 0x0008 -#define ISCSI_LOGIN_OPTION_AUTHMETHOD_CHAP 0x0000 -#define ISCSI_LOGIN_OPTION_AUTHMETHOD_NON 0x1000 -#define ISCSI_LOGIN_OPTION_CHAP_BI 0x0000 -#define ISCSI_LOGIN_OPTION_CHAP_UNI 0x2000 - -/// -/// VLAN Device Path SubType. -/// -#define MSG_VLAN_DP 0x14 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// VLAN identifier (0-4094). - /// - UINT16 VlanId; -} VLAN_DEVICE_PATH; - -/// -/// Bluetooth Device Path SubType. -/// -#define MSG_BLUETOOTH_DP 0x1b -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// 48bit Bluetooth device address. - /// - BLUETOOTH_ADDRESS BD_ADDR; -} BLUETOOTH_DEVICE_PATH; - -/// -/// Wi-Fi Device Path SubType. -/// -#define MSG_WIFI_DP 0x1C -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Service set identifier. A 32-byte octets string. - /// - UINT8 SSId[32]; -} WIFI_DEVICE_PATH; - -/// -/// Bluetooth LE Device Path SubType. -/// -#define MSG_BLUETOOTH_LE_DP 0x1E -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - BLUETOOTH_LE_ADDRESS Address; -} BLUETOOTH_LE_DEVICE_PATH; - -// -// Media Device Path -// -#define MEDIA_DEVICE_PATH 0x04 - -/// -/// Hard Drive Media Device Path SubType. -/// -#define MEDIA_HARDDRIVE_DP 0x01 - -/// -/// The Hard Drive Media Device Path is used to represent a partition on a hard drive. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Describes the entry in a partition table, starting with entry 1. - /// Partition number zero represents the entire device. Valid - /// partition numbers for a MBR partition are [1, 4]. Valid - /// partition numbers for a GPT partition are [1, NumberOfPartitionEntries]. - /// - UINT32 PartitionNumber; - /// - /// Starting LBA of the partition on the hard drive. - /// - UINT64 PartitionStart; - /// - /// Size of the partition in units of Logical Blocks. - /// - UINT64 PartitionSize; - /// - /// Signature unique to this partition: - /// If SignatureType is 0, this field has to be initialized with 16 zeros. - /// If SignatureType is 1, the MBR signature is stored in the first 4 bytes of this field. - /// The other 12 bytes are initialized with zeros. - /// If SignatureType is 2, this field contains a 16 byte signature. - /// - UINT8 Signature[16]; - /// - /// Partition Format: (Unused values reserved). - /// 0x01 - PC-AT compatible legacy MBR. - /// 0x02 - GUID Partition Table. - /// - UINT8 MBRType; - /// - /// Type of Disk Signature: (Unused values reserved). - /// 0x00 - No Disk Signature. - /// 0x01 - 32-bit signature from address 0x1b8 of the type 0x01 MBR. - /// 0x02 - GUID signature. - /// - UINT8 SignatureType; -} HARDDRIVE_DEVICE_PATH; - -#define MBR_TYPE_PCAT 0x01 -#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02 - -#define NO_DISK_SIGNATURE 0x00 -#define SIGNATURE_TYPE_MBR 0x01 -#define SIGNATURE_TYPE_GUID 0x02 - -/// -/// CD-ROM Media Device Path SubType. -/// -#define MEDIA_CDROM_DP 0x02 - -/// -/// The CD-ROM Media Device Path is used to define a system partition that exists on a CD-ROM. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Boot Entry number from the Boot Catalog. The Initial/Default entry is defined as zero. - /// - UINT32 BootEntry; - /// - /// Starting RBA of the partition on the medium. CD-ROMs use Relative logical Block Addressing. - /// - UINT64 PartitionStart; - /// - /// Size of the partition in units of Blocks, also called Sectors. - /// - UINT64 PartitionSize; -} CDROM_DEVICE_PATH; - -// -// Use VENDOR_DEVICE_PATH struct -// -#define MEDIA_VENDOR_DP 0x03 ///< Media vendor device path subtype. - -/// -/// File Path Media Device Path SubType -/// -#define MEDIA_FILEPATH_DP 0x04 -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// A NULL-terminated Path string including directory and file names. - /// - CHAR16 PathName[1]; -} FILEPATH_DEVICE_PATH; - -#define SIZE_OF_FILEPATH_DEVICE_PATH OFFSET_OF(FILEPATH_DEVICE_PATH,PathName) - -/// -/// Media Protocol Device Path SubType. -/// -#define MEDIA_PROTOCOL_DP 0x05 - -/// -/// The Media Protocol Device Path is used to denote the protocol that is being -/// used in a device path at the location of the path specified. -/// Many protocols are inherent to the style of device path. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// The ID of the protocol. - /// - EFI_GUID Protocol; -} MEDIA_PROTOCOL_DEVICE_PATH; - -/// -/// PIWG Firmware File SubType. -/// -#define MEDIA_PIWG_FW_FILE_DP 0x06 - -/// -/// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware file. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Firmware file name - /// - EFI_GUID FvFileName; -} MEDIA_FW_VOL_FILEPATH_DEVICE_PATH; - -/// -/// PIWG Firmware Volume Device Path SubType. -/// -#define MEDIA_PIWG_FW_VOL_DP 0x07 - -/// -/// This device path is used by systems implementing the UEFI PI Specification 1.0 to describe a firmware volume. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Firmware volume name. - /// - EFI_GUID FvName; -} MEDIA_FW_VOL_DEVICE_PATH; - -/// -/// Media relative offset range device path. -/// -#define MEDIA_RELATIVE_OFFSET_RANGE_DP 0x08 - -/// -/// Used to describe the offset range of media relative. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - UINT32 Reserved; - UINT64 StartingOffset; - UINT64 EndingOffset; -} MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH; - -/// -/// This GUID defines a RAM Disk supporting a raw disk format in volatile memory. -/// -#define EFI_VIRTUAL_DISK_GUID \ - { \ - 0x77AB535A, 0x45FC, 0x624B, {0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E } \ - } - -extern EFI_GUID gEfiVirtualDiskGuid; - -/// -/// This GUID defines a RAM Disk supporting an ISO image in volatile memory. -/// -#define EFI_VIRTUAL_CD_GUID \ - { \ - 0x3D5ABD30, 0x4175, 0x87CE, {0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB } \ - } -extern EFI_GUID gEfiVirtualCdGuid; - -/// -/// This GUID defines a RAM Disk supporting a raw disk format in persistent memory. -/// -#define EFI_PERSISTENT_VIRTUAL_DISK_GUID \ - { \ - 0x5CEA02C9, 0x4D07, 0x69D3, {0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 } \ - } - -extern EFI_GUID gEfiPersistentVirtualDiskGuid; - -/// -/// This GUID defines a RAM Disk supporting an ISO image in persistent memory. -/// -#define EFI_PERSISTENT_VIRTUAL_CD_GUID \ - { \ - 0x08018188, 0x42CD, 0xBB48, {0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D } \ - } - -extern EFI_GUID gEfiPersistentVirtualCdGuid; - -/// -/// Media ram disk device path. -/// -#define MEDIA_RAM_DISK_DP 0x09 - -/// -/// Used to describe the ram disk device path. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Starting Memory Address. - /// - UINT32 StartingAddr[2]; - /// - /// Ending Memory Address. - /// - UINT32 EndingAddr[2]; - /// - /// GUID that defines the type of the RAM Disk. - /// - EFI_GUID TypeGuid; - /// - /// RAM Diskinstance number, if supported. The default value is zero. - /// - UINT16 Instance; -} MEDIA_RAM_DISK_DEVICE_PATH; - -/// -/// BIOS Boot Specification Device Path. -/// -#define BBS_DEVICE_PATH 0x05 - -/// -/// BIOS Boot Specification Device Path SubType. -/// -#define BBS_BBS_DP 0x01 - -/// -/// This Device Path is used to describe the booting of non-EFI-aware operating systems. -/// -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - /// - /// Device Type as defined by the BIOS Boot Specification. - /// - UINT16 DeviceType; - /// - /// Status Flags as defined by the BIOS Boot Specification. - /// - UINT16 StatusFlag; - /// - /// Null-terminated ASCII string that describes the boot device to a user. - /// - CHAR8 String[1]; -} BBS_BBS_DEVICE_PATH; - -// -// DeviceType definitions - from BBS specification -// -#define BBS_TYPE_FLOPPY 0x01 -#define BBS_TYPE_HARDDRIVE 0x02 -#define BBS_TYPE_CDROM 0x03 -#define BBS_TYPE_PCMCIA 0x04 -#define BBS_TYPE_USB 0x05 -#define BBS_TYPE_EMBEDDED_NETWORK 0x06 -#define BBS_TYPE_BEV 0x80 -#define BBS_TYPE_UNKNOWN 0xFF - - -/// -/// Union of all possible Device Paths and pointers to Device Paths. -/// -typedef union { - EFI_DEVICE_PATH_PROTOCOL DevPath; - PCI_DEVICE_PATH Pci; - PCCARD_DEVICE_PATH PcCard; - MEMMAP_DEVICE_PATH MemMap; - VENDOR_DEVICE_PATH Vendor; - - CONTROLLER_DEVICE_PATH Controller; - BMC_DEVICE_PATH Bmc; - ACPI_HID_DEVICE_PATH Acpi; - ACPI_EXTENDED_HID_DEVICE_PATH ExtendedAcpi; - ACPI_ADR_DEVICE_PATH AcpiAdr; - - ATAPI_DEVICE_PATH Atapi; - SCSI_DEVICE_PATH Scsi; - ISCSI_DEVICE_PATH Iscsi; - FIBRECHANNEL_DEVICE_PATH FibreChannel; - FIBRECHANNELEX_DEVICE_PATH FibreChannelEx; - - F1394_DEVICE_PATH F1394; - USB_DEVICE_PATH Usb; - SATA_DEVICE_PATH Sata; - USB_CLASS_DEVICE_PATH UsbClass; - USB_WWID_DEVICE_PATH UsbWwid; - DEVICE_LOGICAL_UNIT_DEVICE_PATH LogicUnit; - I2O_DEVICE_PATH I2O; - MAC_ADDR_DEVICE_PATH MacAddr; - IPv4_DEVICE_PATH Ipv4; - IPv6_DEVICE_PATH Ipv6; - VLAN_DEVICE_PATH Vlan; - INFINIBAND_DEVICE_PATH InfiniBand; - UART_DEVICE_PATH Uart; - UART_FLOW_CONTROL_DEVICE_PATH UartFlowControl; - SAS_DEVICE_PATH Sas; - SASEX_DEVICE_PATH SasEx; - NVME_NAMESPACE_DEVICE_PATH NvmeNamespace; - DNS_DEVICE_PATH Dns; - URI_DEVICE_PATH Uri; - BLUETOOTH_DEVICE_PATH Bluetooth; - WIFI_DEVICE_PATH WiFi; - UFS_DEVICE_PATH Ufs; - SD_DEVICE_PATH Sd; - EMMC_DEVICE_PATH Emmc; - HARDDRIVE_DEVICE_PATH HardDrive; - CDROM_DEVICE_PATH CD; - - FILEPATH_DEVICE_PATH FilePath; - MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol; - - MEDIA_FW_VOL_DEVICE_PATH FirmwareVolume; - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FirmwareFile; - MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH Offset; - MEDIA_RAM_DISK_DEVICE_PATH RamDisk; - BBS_BBS_DEVICE_PATH Bbs; -} EFI_DEV_PATH; - - - -typedef union { - EFI_DEVICE_PATH_PROTOCOL *DevPath; - PCI_DEVICE_PATH *Pci; - PCCARD_DEVICE_PATH *PcCard; - MEMMAP_DEVICE_PATH *MemMap; - VENDOR_DEVICE_PATH *Vendor; - - CONTROLLER_DEVICE_PATH *Controller; - BMC_DEVICE_PATH *Bmc; - ACPI_HID_DEVICE_PATH *Acpi; - ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi; - ACPI_ADR_DEVICE_PATH *AcpiAdr; - - ATAPI_DEVICE_PATH *Atapi; - SCSI_DEVICE_PATH *Scsi; - ISCSI_DEVICE_PATH *Iscsi; - FIBRECHANNEL_DEVICE_PATH *FibreChannel; - FIBRECHANNELEX_DEVICE_PATH *FibreChannelEx; - - F1394_DEVICE_PATH *F1394; - USB_DEVICE_PATH *Usb; - SATA_DEVICE_PATH *Sata; - USB_CLASS_DEVICE_PATH *UsbClass; - USB_WWID_DEVICE_PATH *UsbWwid; - DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicUnit; - I2O_DEVICE_PATH *I2O; - MAC_ADDR_DEVICE_PATH *MacAddr; - IPv4_DEVICE_PATH *Ipv4; - IPv6_DEVICE_PATH *Ipv6; - VLAN_DEVICE_PATH *Vlan; - INFINIBAND_DEVICE_PATH *InfiniBand; - UART_DEVICE_PATH *Uart; - UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl; - SAS_DEVICE_PATH *Sas; - SASEX_DEVICE_PATH *SasEx; - NVME_NAMESPACE_DEVICE_PATH *NvmeNamespace; - DNS_DEVICE_PATH *Dns; - URI_DEVICE_PATH *Uri; - BLUETOOTH_DEVICE_PATH *Bluetooth; - WIFI_DEVICE_PATH *WiFi; - UFS_DEVICE_PATH *Ufs; - SD_DEVICE_PATH *Sd; - EMMC_DEVICE_PATH *Emmc; - HARDDRIVE_DEVICE_PATH *HardDrive; - CDROM_DEVICE_PATH *CD; - - FILEPATH_DEVICE_PATH *FilePath; - MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol; - - MEDIA_FW_VOL_DEVICE_PATH *FirmwareVolume; - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FirmwareFile; - MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset; - MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; - BBS_BBS_DEVICE_PATH *Bbs; - UINT8 *Raw; -} EFI_DEV_PATH_PTR; - -#define EFI_DEBUGPORT_PROTOCOL_GUID \ - { \ - 0xEBA4E8D2, 0x3858, 0x41EC, {0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \ - } -// -// DEBUGPORT variable definitions... -// -#define EFI_DEBUGPORT_VARIABLE_NAME L"DEBUGPORT" -#define EFI_DEBUGPORT_VARIABLE_GUID EFI_DEBUGPORT_PROTOCOL_GUID -extern EFI_GUID gEfiDebugPortVariableGuid; - -// -// DebugPort device path definitions... -// -#define DEVICE_PATH_MESSAGING_DEBUGPORT EFI_DEBUGPORT_PROTOCOL_GUID -extern EFI_GUID gEfiDebugPortProtocolGuid; - -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - EFI_GUID Guid; -} DEBUGPORT_DEVICE_PATH; - -#pragma pack() - -#define END_DEVICE_PATH_TYPE 0x7f -#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xFF -#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 - -extern EFI_GUID gEfiDevicePathProtocolGuid; - -#endif diff --git a/BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h b/BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h deleted file mode 100644 index b2fd6b2837..0000000000 --- a/BaseTools/Source/C/Include/Protocol/DevicePathUtilities.h +++ /dev/null @@ -1,288 +0,0 @@ -/** @file - EFI_DEVICE_PATH_UTILITIES_PROTOCOL as defined in UEFI 2.0. - Use to create and manipulate device paths and device nodes. - - Copyright (c) 2017, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __DEVICE_PATH_UTILITIES_H__ -#define __DEVICE_PATH_UTILITIES_H__ - -/// -/// Device Path Utilities protocol -/// -#define EFI_DEVICE_PATH_UTILITIES_GUID \ - { \ - 0x379be4e, 0xd706, 0x437d, {0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \ - } - -/** - Returns the size of the device path, in bytes. - - @param DevicePath Points to the start of the EFI device path. - - @return Size Size of the specified device path, in bytes, including the end-of-path tag. - @retval 0 DevicePath is NULL - -**/ -typedef -UINTN -( *EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE)( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - - -/** - Create a duplicate of the specified path. - - @param DevicePath Points to the source EFI device path. - - @retval Pointer A pointer to the duplicate device path. - @retval NULL insufficient memory or DevicePath is NULL - -**/ -typedef -EFI_DEVICE_PATH_PROTOCOL* -( *EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH)( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -/** - Create a new path by appending the second device path to the first. - If Src1 is NULL and Src2 is non-NULL, then a duplicate of Src2 is returned. - If Src1 is non-NULL and Src2 is NULL, then a duplicate of Src1 is returned. - If Src1 and Src2 are both NULL, then a copy of an end-of-device-path is returned. - - @param Src1 Points to the first device path. - @param Src2 Points to the second device path. - - @retval Pointer A pointer to the newly created device path. - @retval NULL Memory could not be allocated - -**/ -typedef -EFI_DEVICE_PATH_PROTOCOL* -( *EFI_DEVICE_PATH_UTILS_APPEND_PATH)( - CONST EFI_DEVICE_PATH_PROTOCOL *Src1, - CONST EFI_DEVICE_PATH_PROTOCOL *Src2 - ); - -/** - Creates a new path by appending the device node to the device path. - If DeviceNode is NULL then a copy of DevicePath is returned. - If DevicePath is NULL then a copy of DeviceNode, followed by an end-of-device path device node is returned. - If both DeviceNode and DevicePath are NULL then a copy of an end-of-device-path device node is returned. - - @param DevicePath Points to the device path. - @param DeviceNode Points to the device node. - - @retval Pointer A pointer to the allocated device node. - @retval NULL There was insufficient memory. - -**/ -typedef -EFI_DEVICE_PATH_PROTOCOL* -( *EFI_DEVICE_PATH_UTILS_APPEND_NODE)( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode - ); - -/** - Creates a new path by appending the specified device path instance to the specified device path. - - @param DevicePath Points to the device path. If NULL, then ignored. - @param DevicePathInstance Points to the device path instance. - - @retval Pointer A pointer to the newly created device path - @retval NULL Memory could not be allocated or DevicePathInstance is NULL. - -**/ -typedef -EFI_DEVICE_PATH_PROTOCOL* -( *EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE)( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance - ); - -/** - Creates a copy of the current device path instance and returns a pointer to the next device path - instance. - - @param DevicePathInstance On input, this holds the pointer to the current device path - instance. On output, this holds the pointer to the next - device path instance or NULL if there are no more device - path instances in the device path. - @param DevicePathInstanceSize On output, this holds the size of the device path instance, - in bytes or zero, if DevicePathInstance is NULL. - If NULL, then the instance size is not output. - - @retval Pointer A pointer to the copy of the current device path instance. - @retval NULL DevicePathInstance was NULL on entry or there was insufficient memory. - -**/ -typedef -EFI_DEVICE_PATH_PROTOCOL* -( *EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE)( - EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance, - UINTN *DevicePathInstanceSize - ); - -/** - Creates a device node - - @param NodeType NodeType is the device node type (EFI_DEVICE_PATH.Type) for - the new device node. - @param NodeSubType NodeSubType is the device node sub-type - EFI_DEVICE_PATH.SubType) for the new device node. - @param NodeLength NodeLength is the length of the device node - (EFI_DEVICE_PATH.Length) for the new device node. - - @retval Pointer A pointer to the newly created device node. - @retval NULL NodeLength is less than - the size of the header or there was insufficient memory. - -**/ -typedef -EFI_DEVICE_PATH_PROTOCOL* -( *EFI_DEVICE_PATH_UTILS_CREATE_NODE)( - UINT8 NodeType, - UINT8 NodeSubType, - UINT16 NodeLength -); - -/** - Returns whether a device path is multi-instance. - - @param DevicePath Points to the device path. If NULL, then ignored. - - @retval TRUE The device path has more than one instance - @retval FALSE The device path is empty or contains only a single instance. - -**/ -typedef -BOOLEAN -( *EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE)( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -/// -/// This protocol is used to creates and manipulates device paths and device nodes. -/// -typedef struct { - EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize; - EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH DuplicateDevicePath; - EFI_DEVICE_PATH_UTILS_APPEND_PATH AppendDevicePath; - EFI_DEVICE_PATH_UTILS_APPEND_NODE AppendDeviceNode; - EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE AppendDevicePathInstance; - EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE GetNextDevicePathInstance; - EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE IsDevicePathMultiInstance; - EFI_DEVICE_PATH_UTILS_CREATE_NODE CreateDeviceNode; -} EFI_DEVICE_PATH_UTILITIES_PROTOCOL; - -extern EFI_GUID gEfiDevicePathUtilitiesProtocolGuid; - -VOID -SetDevicePathEndNode ( - VOID *Node - ); - -BOOLEAN -IsDevicePathValid ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - UINTN MaxSize - ); - -UINT8 -DevicePathType ( - CONST VOID *Node - ); - -UINT8 -DevicePathSubType ( - CONST VOID *Node - ); - -UINTN -DevicePathNodeLength ( - CONST VOID *Node - ); - -EFI_DEVICE_PATH_PROTOCOL * -NextDevicePathNode ( - CONST VOID *Node - ); - -BOOLEAN -IsDevicePathEndType ( - CONST VOID *Node - ); - -BOOLEAN -IsDevicePathEnd ( - CONST VOID *Node - ); -BOOLEAN -IsDevicePathEndInstance ( - CONST VOID *Node - ); - -UINT16 -SetDevicePathNodeLength ( - VOID *Node, - UINTN Length - ); - -VOID -SetDevicePathEndNode ( - VOID *Node - ); - -UINTN -UefiDevicePathLibGetDevicePathSize ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibDuplicateDevicePath ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibAppendDevicePath ( - CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, - CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath - ); - -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibAppendDevicePathNode ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode - ); - -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibAppendDevicePathInstance ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance - ); - -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibGetNextDevicePathInstance ( - EFI_DEVICE_PATH_PROTOCOL **DevicePath, - UINTN *Size - ); - -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibCreateDeviceNode ( - UINT8 NodeType, - UINT8 NodeSubType, - UINT16 NodeLength - ); - -BOOLEAN -UefiDevicePathLibIsDevicePathMultiInstance ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -#endif diff --git a/BaseTools/Source/C/Include/Protocol/GraphicsOutput.h b/BaseTools/Source/C/Include/Protocol/GraphicsOutput.h deleted file mode 100644 index 5a10ac72a4..0000000000 --- a/BaseTools/Source/C/Include/Protocol/GraphicsOutput.h +++ /dev/null @@ -1,187 +0,0 @@ -/** @file - Graphics Output Protocol from the UEFI 2.0 specification. - - Abstraction of a very simple graphics device. - - Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __GRAPHICS_OUTPUT_H__ -#define __GRAPHICS_OUTPUT_H__ - -#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ - { \ - 0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } \ - } - -typedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL EFI_GRAPHICS_OUTPUT_PROTOCOL; - -typedef struct { - UINT32 RedMask; - UINT32 GreenMask; - UINT32 BlueMask; - UINT32 ReservedMask; -} EFI_PIXEL_BITMASK; - -typedef enum { - PixelRedGreenBlueReserved8BitPerColor, - PixelBlueGreenRedReserved8BitPerColor, - PixelBitMask, - PixelBltOnly, - PixelFormatMax -} EFI_GRAPHICS_PIXEL_FORMAT; - -typedef struct { - UINT32 Version; - UINT32 HorizontalResolution; - UINT32 VerticalResolution; - EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; - EFI_PIXEL_BITMASK PixelInformation; - UINT32 PixelsPerScanLine; -} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION; - -/** - Return the current video mode information. - - @param This Protocol instance pointer. - @param ModeNumber The mode number to return information on. - @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer. - @param Info A pointer to callee allocated buffer that returns information about ModeNumber. - - @retval EFI_SUCCESS Mode information returned. - @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small. - @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode. - @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () - @retval EFI_INVALID_PARAMETER One of the input args was NULL. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE) ( - IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, - IN UINT32 ModeNumber, - OUT UINTN *SizeOfInfo, - OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info - ) -; - -/** - Return the current video mode information. - - @param This Protocol instance pointer. - @param ModeNumber The mode number to be set. - - @retval EFI_SUCCESS Graphics mode was changed. - @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. - @retval EFI_UNSUPPORTED ModeNumber is not supported by this device. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE) ( - IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, - IN UINT32 ModeNumber - ) -; - -typedef struct { - UINT8 Blue; - UINT8 Green; - UINT8 Red; - UINT8 Reserved; -} EFI_GRAPHICS_OUTPUT_BLT_PIXEL; - -typedef union { - EFI_GRAPHICS_OUTPUT_BLT_PIXEL Pixel; - UINT32 Raw; -} EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION; - -typedef enum { - EfiBltVideoFill, - EfiBltVideoToBltBuffer, - EfiBltBufferToVideo, - EfiBltVideoToVideo, - EfiGraphicsOutputBltOperationMax -} EFI_GRAPHICS_OUTPUT_BLT_OPERATION; - -/** - The following table defines actions for BltOperations: - - EfiBltVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY) - directly to every pixel of the video display rectangle - (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). - Only one pixel will be used from the BltBuffer. Delta is NOT used. - - EfiBltVideoToBltBuffer - Read data from the video display rectangle - (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in - the BltBuffer rectangle (DestinationX, DestinationY ) - (DestinationX + Width, DestinationY + Height). If DestinationX or - DestinationY is not zero then Delta must be set to the length in bytes - of a row in the BltBuffer. - - EfiBltBufferToVideo - Write data from the BltBuffer rectangle - (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the - video display rectangle (DestinationX, DestinationY) - (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is - not zero then Delta must be set to the length in bytes of a row in the - BltBuffer. - - EfiBltVideoToVideo - Copy from the video display rectangle (SourceX, SourceY) - (SourceX + Width, SourceY + Height) .to the video display rectangle - (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). - The BltBuffer and Delta are not used in this mode. - - @param This Protocol instance pointer. - @param BltBuffer Buffer containing data to blit into video buffer. This - buffer has a size of Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) - @param BltOperation Operation to perform on BlitBuffer and video memory - @param SourceX X coordinate of source for the BltBuffer. - @param SourceY Y coordinate of source for the BltBuffer. - @param DestinationX X coordinate of destination for the BltBuffer. - @param DestinationY Y coordinate of destination for the BltBuffer. - @param Width Width of rectangle in BltBuffer in pixels. - @param Height Height of rectangle in BltBuffer in pixels. - @param Delta OPTIONAL - - @retval EFI_SUCCESS The Blt operation completed. - @retval EFI_INVALID_PARAMETER BltOperation is not valid. - @retval EFI_DEVICE_ERROR A hardware error occurred writing to the video buffer. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) ( - IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, - IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL - IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, - IN UINTN SourceX, - IN UINTN SourceY, - IN UINTN DestinationX, - IN UINTN DestinationY, - IN UINTN Width, - IN UINTN Height, - IN UINTN Delta OPTIONAL - ); - -typedef struct { - UINT32 MaxMode; - UINT32 Mode; - EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; - UINTN SizeOfInfo; - EFI_PHYSICAL_ADDRESS FrameBufferBase; - UINTN FrameBufferSize; -} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE; - -struct _EFI_GRAPHICS_OUTPUT_PROTOCOL { - EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode; - EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode; - EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt; - EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode; -}; - -extern EFI_GUID gEfiGraphicsOutputProtocolGuid; - -#endif diff --git a/BaseTools/Source/C/Include/Protocol/GuidedSectionExtraction.h b/BaseTools/Source/C/Include/Protocol/GuidedSectionExtraction.h deleted file mode 100644 index f629546252..0000000000 --- a/BaseTools/Source/C/Include/Protocol/GuidedSectionExtraction.h +++ /dev/null @@ -1,145 +0,0 @@ -/** @file - This file declares GUIDed section extraction protocol. - - This interface provides a means of decoding a GUID defined encapsulation - section. There may be multiple different GUIDs associated with the GUIDed - section extraction protocol. That is, all instances of the GUIDed section - extraction protocol must have the same interface structure. - - @par Revision Reference: PI - Version 1.00. - - Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL_H__ -#define __EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL_H__ - -// -// Forward reference for pure ANSI compatibility - -typedef struct _EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL; - - -/** - The ExtractSection() function processes the input section and - allocates a buffer from the pool in which it returns the section - contents. If the section being extracted contains - authentication information (the section's - GuidedSectionHeader.Attributes field has the - EFI_GUIDED_SECTION_AUTH_STATUS_VALID bit set), the values - returned in AuthenticationStatus must reflect the results of - the authentication operation. Depending on the algorithm and - size of the encapsulated data, the time that is required to do - a full authentication may be prohibitively long for some - classes of systems. To indicate this, use - EFI_SECURITY_POLICY_PROTOCOL_GUID, which may be published by - the security policy driver (see the Platform Initialization - Driver Execution Environment Core Interface Specification for - more details and the GUID definition). If the - EFI_SECURITY_POLICY_PROTOCOL_GUID exists in the handle - database, then, if possible, full authentication should be - skipped and the section contents simply returned in the - OutputBuffer. In this case, the - EFI_AUTH_STATUS_PLATFORM_OVERRIDE bit AuthenticationStatus - must be set on return. ExtractSection() is callable only from - TPL_NOTIFY and below. Behavior of ExtractSection() at any - EFI_TPL above TPL_NOTIFY is undefined. Type EFI_TPL is - defined in RaiseTPL() in the UEFI 2.0 specification. - - - @param This Indicates the - EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL instance. - - @param InputSection Buffer containing the input GUIDed section - to be processed. OutputBuffer OutputBuffer - is allocated from boot services pool - memory and contains the new section - stream. The caller is responsible for - freeing this buffer. - - @param OutputSize A pointer to a caller-allocated UINTN in - which the size of OutputBuffer allocation - is stored. If the function returns - anything other than EFI_SUCCESS, the value - of OutputSize is undefined. - - @param AuthenticationStatus A pointer to a caller-allocated - UINT32 that indicates the - authentication status of the - output buffer. If the input - section's - GuidedSectionHeader.Attributes - field has the - EFI_GUIDED_SECTION_AUTH_STATUS_VAL - bit as clear, AuthenticationStatus - must return zero. Both local bits - (19:16) and aggregate bits (3:0) - in AuthenticationStatus are - returned by ExtractSection(). - These bits reflect the status of - the extraction operation. The bit - pattern in both regions must be - the same, as the local and - aggregate authentication statuses - have equivalent meaning at this - level. If the function returns - anything other than EFI_SUCCESS, - the value of AuthenticationStatus - is undefined. - - - @retval EFI_SUCCESS The InputSection was successfully - processed and the section contents were - returned. - - @retval EFI_OUT_OF_RESOURCES The system has insufficient - resources to process the - request. - - @retval EFI_INVALID_PARAMETER The GUID in InputSection does - not match this instance of the - GUIDed Section Extraction - Protocol. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_EXTRACT_GUIDED_SECTION)( - IN CONST EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This, - IN CONST VOID *InputSection, - OUT VOID **OutputBuffer, - OUT UINTN *OutputSize, - OUT UINT32 *AuthenticationStatus -); - - -/** - - Takes the GUIDed section as input and produces the section - stream data. See the ExtractSection() function description. - -**/ -struct _EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL { - EFI_EXTRACT_GUIDED_SECTION ExtractSection; -}; - -// -// Protocol GUID definition. Each GUIDed section extraction protocol has the -// same interface but with different GUID. All the GUIDs is defined here. -// May add multiple GUIDs here. -// -#define EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID \ - { \ - 0xFC1BCDB0, 0x7D31, 0x49aa, {0x93, 0x6A, 0xA4, 0x60, 0x0D, 0x9D, 0xD0, 0x83 } \ - } - -// -// may add other GUID here -// -extern EFI_GUID gEfiCrc32GuidedSectionExtractionProtocolGuid; - -#endif diff --git a/BaseTools/Source/C/Include/Protocol/HiiFramework.h b/BaseTools/Source/C/Include/Protocol/HiiFramework.h deleted file mode 100644 index 448350967b..0000000000 --- a/BaseTools/Source/C/Include/Protocol/HiiFramework.h +++ /dev/null @@ -1,944 +0,0 @@ -/** @file - This file defines the Human Interface Infrastructure protocol which will - be used by resources which want to publish IFR/Font/String data and have it - collected by the Configuration engine. - - @par Revision Reference: - This protocol is defined in HII spec 0.92. - - Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _FRAMEWORK_HII_H_ -#define _FRAMEWORK_HII_H_ - -//#include - -// -// To get EFI_GRAPHICS_OUTPUT_BLT_PIXEL, -// is defined in MdePkg/Protocol/GraphicsOutput.h -// -#include - -#define EFI_HII_PROTOCOL_GUID \ - { \ - 0xd7ad636e, 0xb997, 0x459b, {0xbf, 0x3f, 0x88, 0x46, 0x89, 0x79, 0x80, 0xe1} \ - } - -// BugBug: -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// If UGA goes away we need to put this some place. I'm not sure where? -// -//typedef struct { -// UINT8 Blue; -// UINT8 Green; -// UINT8 Red; -// UINT8 Reserved; -//} EFI_UGA_PIXEL; - -//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// - -typedef struct _EFI_HII_PROTOCOL EFI_HII_PROTOCOL; - -// -// Global definition -// -#define NARROW_CHAR 0xFFF0 -#define WIDE_CHAR 0xFFF1 -#define NON_BREAKING_CHAR 0xFFF2 -#define GLYPH_WIDTH 8 -#define GLYPH_HEIGHT 19 - -#define EFI_HII_FONT 1 -#define EFI_HII_STRING 2 -#define EFI_HII_IFR 3 -#define EFI_HII_KEYBOARD 4 -#define EFI_HII_HANDLES 5 -#define EFI_HII_VARIABLE 6 -#define EFI_HII_DEVICE_PATH 7 - - -// References to string tokens must use this macro to enable scanning for -// token usages. -// -#define STRING_TOKEN(t) t - -// -// The following types are currently defined: -// EFI_FROM_ID has been defined in UEFI spec. -// -typedef UINT16 EFI_FORM_LABEL; - -#pragma pack(1) - -typedef struct { - UINT32 Length; - UINT16 Type; -} EFI_HII_PACK_HEADER; - -// -// A form list consists of a large variety of structure -// possibilities so to represent the binary blob of data -// associated with a package of forms, we will assume a -// pointer to a self-describing data buffer. -// -typedef struct { - EFI_HII_PACK_HEADER Header; -} EFI_HII_IFR_PACK; - -typedef struct { - EFI_HII_PACK_HEADER Header; // Must be filled in - EFI_HANDLE ImageHandle; // Must be filled in - EFI_HANDLE DeviceHandle; // Optional - EFI_HANDLE ControllerHandle; // Optional - EFI_HANDLE CallbackHandle; // Optional - EFI_HANDLE COBExportHandle; // Optional -} EFI_HII_HANDLE_PACK; - -// -// ******************************************************** -// EFI_VARIABLE_CONTENTS -// ******************************************************** -// -typedef struct { - EFI_HII_PACK_HEADER Header; - EFI_GUID VariableGuid; - UINT32 VariableNameLength; - UINT16 VariableId; - // - // CHAR16 VariableName[]; //Null-terminated - // -} EFI_HII_VARIABLE_PACK; - -// -// ******************************************************** -// EFI_DEVICE_PATH_PACK -// ******************************************************** -// -typedef struct { - EFI_HII_PACK_HEADER Header; - // - // EFI_DEVICE_PATH DevicePath[]; - // -} EFI_HII_DEVICE_PATH_PACK; - -// -// ******************************************************** -// EFI_HII_DATA_TABLE -// ******************************************************** -// -typedef struct { - EFI_HII_HANDLE HiiHandle; - EFI_GUID PackageGuid; - UINT32 DataTableSize; - UINT32 IfrDataOffset; - UINT32 StringDataOffset; - UINT32 VariableDataOffset; - UINT32 DevicePathOffset; - UINT32 NumberOfVariableData; - UINT32 NumberOfLanguages; - // - // EFI_HII_DEVICE_PATH_PACK DevicePath[]; - // EFI_HII_VARIABLE_PACK VariableData[]; - // EFI_HII_IFR_PACK IfrData; - // EFI_HII_STRING_PACK StringData[]; - // -} EFI_HII_DATA_TABLE; - -// -// ******************************************************** -// EFI_HII_EXPORT_TABLE -// ******************************************************** -// -typedef struct { - UINT32 NumberOfHiiDataTables; - EFI_GUID Revision; - // - // EFI_HII_DATA_TABLE HiiDataTable[]; - // -} EFI_HII_EXPORT_TABLE; - -typedef struct { - BOOLEAN FormSetUpdate; // If TRUE, next variable is significant - EFI_PHYSICAL_ADDRESS FormCallbackHandle; // If not 0, will update Formset with this info - BOOLEAN FormUpdate; // If TRUE, next variable is significant - UINT16 FormValue; // specify which form is to be updated if FormUpdate value is TRUE. - STRING_REF FormTitle; // If not 0, will update Form with this info - UINT16 DataCount; // The number of Data entries in this structure - UINT8 *Data; // An array of 1+ op-codes, specified by DataCount -} EFI_HII_UPDATE_DATA; - -// -// String attributes -// -#define LANG_RIGHT_TO_LEFT 0x00000001 - -// -// A string package is used to localize strings to a particular -// language. The package is associated with a particular driver -// or set of drivers. Tools are used to associate tokens with -// string references in forms and in programs. These tokens are -// language agnostic. When paired with a language pack (directly -// or indirectly), the string token resolves into an actual -// UNICODE string. The NumStringPointers determines how many -// StringPointers (offset values) there are as well as the total -// number of Strings that are defined. -// -typedef struct { - EFI_HII_PACK_HEADER Header; - RELOFST LanguageNameString; - RELOFST PrintableLanguageName; - UINT32 NumStringPointers; - UINT32 Attributes; - // - // RELOFST StringPointers[]; - // EFI_STRING Strings[]; - // -} EFI_HII_STRING_PACK; - -// -// Glyph Attributes -// -#define EFI_GLYPH_NON_SPACING 1 -#define EFI_GLYPH_WIDE 2 - -typedef struct { - CHAR16 UnicodeWeight; - UINT8 Attributes; - UINT8 GlyphCol1[GLYPH_HEIGHT]; -} EFI_NARROW_GLYPH; - -typedef struct { - CHAR16 UnicodeWeight; - UINT8 Attributes; - UINT8 GlyphCol1[GLYPH_HEIGHT]; - UINT8 GlyphCol2[GLYPH_HEIGHT]; - UINT8 Pad[3]; -} EFI_WIDE_GLYPH; - -// -// A font list consists of a font header followed by a series -// of glyph structures. Note that fonts are not language specific. -// -typedef struct { - EFI_HII_PACK_HEADER Header; - UINT16 NumberOfNarrowGlyphs; - UINT16 NumberOfWideGlyphs; -} EFI_HII_FONT_PACK; - -// -// The IfrData in the EFI_HII_IFR_PACK structure definition -// is variable length, and not really part of the header. To -// simplify from code the size of the header, define an -// identical structure that does not include the IfrData field. -// Then use sizeof() this new structure to determine the -// actual size of the header. -// -typedef struct { - EFI_HII_PACK_HEADER Header; -} EFI_HII_IFR_PACK_HEADER; - -// -// pedef EFI_HII_PACK_HEADER EFI_HII_IFR_PACK_HEADER; -// -typedef enum { - EfiKeyLCtrl, - EfiKeyA0, - EfiKeyLAlt, - EfiKeySpaceBar, - EfiKeyA2, - EfiKeyA3, - EfiKeyA4, - EfiKeyRCtrl, - EfiKeyLeftArrow, - EfiKeyDownArrow, - EfiKeyRightArrow, - EfiKeyZero, - EfiKeyPeriod, - EfiKeyEnter, - EfiKeyLShift, - EfiKeyB0, - EfiKeyB1, - EfiKeyB2, - EfiKeyB3, - EfiKeyB4, - EfiKeyB5, - EfiKeyB6, - EfiKeyB7, - EfiKeyB8, - EfiKeyB9, - EfiKeyB10, - EfiKeyRshift, - EfiKeyUpArrow, - EfiKeyOne, - EfiKeyTwo, - EfiKeyThree, - EfiKeyCapsLock, - EfiKeyC1, - EfiKeyC2, - EfiKeyC3, - EfiKeyC4, - EfiKeyC5, - EfiKeyC6, - EfiKeyC7, - EfiKeyC8, - EfiKeyC9, - EfiKeyC10, - EfiKeyC11, - EfiKeyC12, - EfiKeyFour, - EfiKeyFive, - EfiKeySix, - EfiKeyPlus, - EfiKeyTab, - EfiKeyD1, - EfiKeyD2, - EfiKeyD3, - EfiKeyD4, - EfiKeyD5, - EfiKeyD6, - EfiKeyD7, - EfiKeyD8, - EfiKeyD9, - EfiKeyD10, - EfiKeyD11, - EfiKeyD12, - EfiKeyD13, - EfiKeyDel, - EfiKeyEnd, - EfiKeyPgDn, - EfiKeySeven, - EfiKeyEight, - EfiKeyNine, - EfiKeyE0, - EfiKeyE1, - EfiKeyE2, - EfiKeyE3, - EfiKeyE4, - EfiKeyE5, - EfiKeyE6, - EfiKeyE7, - EfiKeyE8, - EfiKeyE9, - EfiKeyE10, - EfiKeyE11, - EfiKeyE12, - EfiKeyBackSpace, - EfiKeyIns, - EfiKeyHome, - EfiKeyPgUp, - EfiKeyNLck, - EfiKeySlash, - EfiKeyAsterisk, - EfiKeyMinus, - EfiKeyEsc, - EfiKeyF1, - EfiKeyF2, - EfiKeyF3, - EfiKeyF4, - EfiKeyF5, - EfiKeyF6, - EfiKeyF7, - EfiKeyF8, - EfiKeyF9, - EfiKeyF10, - EfiKeyF11, - EfiKeyF12, - EfiKeyPrint, - EfiKeySLck, - EfiKeyPause -} EFI_KEY; - -typedef struct { - EFI_KEY Key; - CHAR16 Unicode; - CHAR16 ShiftedUnicode; - CHAR16 AltGrUnicode; - CHAR16 ShiftedAltGrUnicode; - UINT16 Modifier; -} EFI_KEY_DESCRIPTOR; - -// -// This structure allows a sparse set of keys to be redefined -// or a complete redefinition of the keyboard layout. Most -// keyboards have a lot of commonality in their layouts, therefore -// only defining those keys that need to change from the default -// minimizes the passed in information. -// -// Additionally, when an update occurs, the active keyboard layout -// will be switched to the newly updated keyboard layout. This -// allows for situations that when a keyboard layout driver is -// loaded as part of system initialization, the system will default -// the keyboard behavior to the new layout. -// -// Each call to update the keyboard mapping should contain the -// complete set of key descriptors to be updated, since every -// call to the HII which contains an EFI_HII_KEYBOARD_PACK will -// wipe the previous set of overrides. A call to -// -typedef struct { - EFI_HII_PACK_HEADER Header; - EFI_KEY_DESCRIPTOR *Descriptor; - UINT8 DescriptorCount; -} EFI_HII_KEYBOARD_PACK; - -// -// The EFI_HII_PACKAGES can contain different types of packages just -// after the structure as inline data. -// -typedef struct { - UINTN NumberOfPackages; - EFI_GUID *GuidId; - // - // EFI_HII_HANDLE_PACK *HandlePack; // Only one pack. - // EFI_HII_IFR_PACK *IfrPack; // Only one pack. - // EFI_HII_FONT_PACK *FontPack[]; // Multiple packs ok - // EFI_HII_STRING_PACK *StringPack[]; // Multiple packs ok - // EFI_HII_KEYBOARD_PACK *KeyboardPack[]; // Multiple packs ok - // -} EFI_HII_PACKAGES; - -typedef struct _EFI_HII_VARIABLE_PACK_LIST { - struct _EFI_HII_VARIABLE_PACK_LIST *NextVariablePack; - EFI_HII_VARIABLE_PACK *VariablePack; -} EFI_HII_VARIABLE_PACK_LIST; - - -#pragma pack() - -/** - Registers the various packs that are passed in via the Packages parameter. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param Packages A pointer to an EFI_HII_PACKAGES package instance. - @param Handle A pointer to the EFI_HII_HANDLE instance. - - @retval EFI_SUCCESS Data was extracted from Packages, the database - was updated with the data, and Handle returned successfully. - @retval EFI_INVALID_PARAMETER The content of Packages was invalid. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_NEW_PACK) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_PACKAGES *Packages, - OUT EFI_HII_HANDLE *Handle - ); - -/** - Removes a package from the HII database. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param Handle The handle that was registered to the data that is requested - for removal. - - @retval EFI_SUCCESS The data associated with the Handle was removed - from the HII database. - @retval EFI_INVALID_PARAMETER The Handle was not valid. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_REMOVE_PACK) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle - ); - -/** - Determines the handles that are currently active in the database. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param HandleBufferLength On input, a pointer to the length of the handle - buffer. On output, the length of the handle buffer that is required - for the handles found. - @param Handle An array of EFI_HII_HANDLE instances returned. - - @retval EFI_SUCCESS Handle was updated successfully. - @retval EFI_BUFFER_TOO_SMALL The HandleBufferLength parameter indicates - that Handle is too small to support the number of handles. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_FIND_HANDLES) ( - IN EFI_HII_PROTOCOL *This, - IN OUT UINT16 *HandleBufferLength, - OUT EFI_HII_HANDLE *Handle - ); - -/** - Exports the contents of the database into a buffer. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param Handle An EFI_HII_HANDLE that corresponds to the desired - handle to export. If the value is 0, the entire database will be exported. - In either case, the data will be exported in a format described by the - structure definition of EFI_HII_EXPORT_TABLE. - @param BufferSize - On input, a pointer to the length of the buffer. On output, the length - of the buffer that is required for the export data. - @param Buffer A pointer to a buffer that will contain the results of the export function. - - @retval EFI_SUCCESS The buffer was successfully filled with BufferSize amount of data. - @retval EFI_BUFFER_TOO_SMALL The value in BufferSize was too small to contain the export data. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_EXPORT) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ); - -/** - Remove any new strings that were added after the initial string export - for this handle. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param Handle The handle on which the string resides. - - @retval EFI_SUCCESS Remove strings from the handle successfully. - @retval EFI_INVALID_PARAMETER The Handle was unknown. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_RESET_STRINGS) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle - ); - -/** - Tests if all of the characters in a string have corresponding font characters. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param StringToTest A pointer to a Unicode string. - @param FirstMissing A pointer to an index into the string. On input, - the index of the first character in the StringToTest to examine. On exit, - the index of the first character encountered for which a glyph is unavailable. - If all glyphs in the string are available, the index is the index of the - terminator of the string. - @param GlyphBufferSize A pointer to a value. On output, if the function - returns EFI_SUCCESS, it contains the amount of memory that is required to - store the string's glyph equivalent. - - @retval EFI_SUCCESS All glyphs are available. Note that an empty string - always returns this value. - @retval EFI_NOT_FOUND A glyph was not found for a character. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_TEST_STRING) ( - IN EFI_HII_PROTOCOL *This, - IN CHAR16 *StringToTest, - IN OUT UINT32 *FirstMissing, - OUT UINT32 *GlyphBufferSize - ); - -/** - Translates a Unicode character into the corresponding font glyph. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param Source A pointer to a Unicode string. - @param Index On input, the offset into the string from which to fetch - the character.On successful completion, the index is updated to the first - character past the character(s) making up the just extracted glyph. - @param GlyphBuffer Pointer to an array where the glyphs corresponding - to the characters in the source may be stored. GlyphBuffer is assumed - to be wide enough to accept a wide glyph character. - @param BitWidth If EFI_SUCCESS was returned, the UINT16 pointed to by - this value is filled with the length of the glyph in pixels. It is unchanged - if the call was unsuccessful. - @param InternalStatus The cell pointed to by this parameter must be - initialized to zero prior to invoking the call the first time for any string. - - @retval EFI_SUCCESS It worked. - @retval EFI_NOT_FOUND A glyph for a character was not found. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_GLYPH) ( - IN EFI_HII_PROTOCOL *This, - IN CHAR16 *Source, - IN OUT UINT16 *Index, - OUT UINT8 **GlyphBuffer, - OUT UINT16 *BitWidth, - IN OUT UINT32 *InternalStatus - ); - -/** - Translates a glyph into the format required for input to the Universal - Graphics Adapter (UGA) Block Transfer (BLT) routines. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param GlyphBuffer A pointer to the buffer that contains glyph data. - @param Foreground The foreground setting requested to be used for the - generated BltBuffer data. - @param Background The background setting requested to be used for the - generated BltBuffer data. - @param Count The entry in the BltBuffer upon which to act. - @param Width The width in bits of the glyph being converted. - @param Height The height in bits of the glyph being converted - @param BltBuffer A pointer to the buffer that contains the data that is - ready to be used by the UGA BLT routines. - - @retval EFI_SUCCESS It worked. - @retval EFI_NOT_FOUND A glyph for a character was not found. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GLYPH_TO_BLT) ( - IN EFI_HII_PROTOCOL *This, - IN UINT8 *GlyphBuffer, - IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground, - IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background, - IN UINTN Count, - IN UINTN Width, - IN UINTN Height, - IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer - ); - -/** - Allows a new string to be added to an already existing string package. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param Pointer to a NULL-terminated string containing a single ISO 639-2 - language identifier, indicating the language in which the string is translated. - @param Handle The handle of the language pack to which the string is to be added. - @param Reference The identifier of the string to be added. If the reference - value is zero, then the string will be assigned a new identifier on that - handle for the language specified. Otherwise, the string will be updated - with the NewString Value. - @param NewString The string to be added. - - @retval EFI_SUCCESS The string was effectively registered. - @retval EFI_INVALID_PARAMETER The Handle was unknown. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_NEW_STRING) ( - IN EFI_HII_PROTOCOL *This, - IN CHAR16 *Language, - IN EFI_HII_HANDLE Handle, - IN OUT STRING_REF *Reference, - IN CHAR16 *NewString - ); - -/** - Allows a program to determine the primary languages that are supported - on a given handle. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param Handle The handle on which the strings reside. - @param LanguageString A string allocated by GetPrimaryLanguages() that - contains a list of all primary languages registered on the handle. - - @retval EFI_SUCCESS LanguageString was correctly returned. - @retval EFI_INVALID_PARAMETER The Handle was unknown. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_PRI_LANGUAGES) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - OUT EFI_STRING *LanguageString - ); - -/** - Allows a program to determine which secondary languages are supported - on a given handle for a given primary language. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param Handle The handle on which the strings reside. - @param PrimaryLanguage Pointer to a NULL-terminated string containing a single - ISO 639-2 language identifier, indicating the primary language. - @param LanguageString A string allocated by GetSecondaryLanguages() - containing a list of all secondary languages registered on the handle. - - @retval EFI_SUCCESS LanguageString was correctly returned. - @retval EFI_INVALID_PARAMETER The Handle was unknown. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_SEC_LANGUAGES) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN CHAR16 *PrimaryLanguage, - OUT EFI_STRING *LanguageString - ); - -/** - Extracts a string from a package already registered with the EFI HII database. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param Handle The handle on which the string resides. - @param Token The string token assigned to the string. - @param Raw If TRUE, the string is returned unedited in the internal - storage format described above. If false, the string returned is edited - by replacing with and by removing special characters such - as the prefix. - @param LanguageString Pointer to a NULL-terminated string containing a - single ISO 639-2 language identifier, indicating the language to print. - If the LanguageString is empty (starts with a NULL), the default system - language will be used to determine the language. - @param BufferLength Length of the StringBuffer. - @param StringBuffer The buffer designed to receive the characters in the string. - - @retval EFI_SUCCESS StringBuffer is filled with a NULL-terminated string. - @retval EFI_INVALID_PARAMETER The handle or string token is unknown. - @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough to - allow the entire string to be stored. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_STRING) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN STRING_REF Token, - IN BOOLEAN Raw, - IN CHAR16 *LanguageString, - IN OUT UINTN *BufferLength, - OUT EFI_STRING StringBuffer - ); - -/** - Allows a program to extract a part of a string of not more than a given width. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param Handle The handle on which the string resides. - @param Token The string token assigned to the string. - @param Index On input, the offset into the string where the line is to start. - On output, the index is updated to point to beyond the last character returned - in the call. - @param LineWidth The maximum width of the line in units of narrow glyphs. - @param LanguageString Pointer to a NULL-terminated string containing a - single ISO 639-2 language identifier, indicating the language to print. - @param BufferLength Pointer to the length of the StringBuffer. - @param StringBuffer The buffer designed to receive the characters in the string. - - @retval EFI_SUCCESS StringBuffer filled with characters that will fit on the line. - @retval EFI_NOT_FOUND The font glyph for at least one of the characters in - the string is not in the font database. - @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough - to allow the entire string to be stored. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_LINE) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN STRING_REF Token, - IN OUT UINT16 *Index, - IN UINT16 LineWidth, - IN CHAR16 *LanguageString, - IN OUT UINT16 *BufferLength, - OUT EFI_STRING StringBuffer - ); - -/** - Allows a program to extract a form or form package that has previously - been registered with the HII database. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param Handle Handle on which the form resides. - @param FormId The ID of the form to return. If the ID is zero, - the entire form package is returned. - @param BufferLength On input, the length of the Buffer. On output, - the length of the returned buffer, - @param Buffer The buffer designed to receive the form(s). - - @retval EFI_SUCCESS Buffer filled with the requested forms. BufferLength - was updated. - @retval EFI_INVALID_PARAMETER The handle is unknown. - @retval EFI_NOT_FOUND A form on the requested handle cannot be found with - the requested FormId. - @retval EFI_BUFFER_TOO_SMALL The buffer provided was not large enough - to allow the form to be stored. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_FORMS) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN EFI_FORM_ID FormId, - IN OUT UINTN *BufferLength, - OUT UINT8 *Buffer - ); - -/** - Extracts the defaults that are associated with a given handle in the HII database. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param Handle The HII handle from which will have default data retrieved. - @param DefaultMask The mask used to specify some type of default override when extracting - the default image data. - @param VariablePackList A indirect pointer to the first entry of a link list with - type EFI_HII_VARIABLE_PACK_LIST. - - @retval EFI_SUCCESS The VariablePackList was populated with the appropriate - default setting data. - @retval EFI_NOT_FOUND The IFR does not have any explicit or default map(s). - @retval EFI_INVALID_PARAMETER The HII database entry associated with Handle - contain invalid data. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_DEFAULT_IMAGE) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN UINTN DefaultMask, - OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList - ); - -/** - Allows the caller to update a form or form package that has previously been - registered with the EFI HII database. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param Handle Handle of the package where the form to be updated resides. - @param Label The label inside the form package where the update is to take place. - @param AddData If TRUE, adding data at a given Label; otherwise, - if FALSE, removing data at a given Label. - @param Data The buffer containing the new tags to insert after the Label - - @retval EFI_SUCCESS The form was updated with the new tags. - @retval EFI_INVALID_PARAMETER The buffer for the buffer length does not - contain an integral number of tags. - @retval EFI_NOT_FOUND The Handle, Label, or FormId was not found. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_UPDATE_FORM) ( - IN EFI_HII_PROTOCOL *This, - IN EFI_HII_HANDLE Handle, - IN EFI_FORM_LABEL Label, - IN BOOLEAN AddData, - IN EFI_HII_UPDATE_DATA *Data - ); - -/** - Retrieves the current keyboard layout. - - @param This A pointer to the EFI_HII_PROTOCOL instance. - @param DescriptorCount A pointer to the number of Descriptor entries being - described in the keyboard layout being retrieved. - @param Descriptor A pointer to a buffer containing an array of EFI_KEY_DESCRIPTOR - entries. Each entry will reflect the definition of a specific physical key. - - @retval EFI_SUCCESS The keyboard layout was retrieved successfully. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_HII_GET_KEYBOARD_LAYOUT) ( - IN EFI_HII_PROTOCOL *This, - OUT UINT16 *DescriptorCount, - OUT EFI_KEY_DESCRIPTOR *Descriptor - ); - -/** - @par Protocol Description: - The HII Protocol manages the HII database, which is a repository for data - having to do with fonts, strings, forms, keyboards, and other future human - interface items. - - @param NewPack - Extracts the various packs from a package list. - - @param RemovePack - Removes a package from the HII database. - - @param FindHandles - Determines the handles that are currently active in the database. - - @param ExportDatabase - Export the entire contents of the database to a buffer. - - @param TestString - Tests if all of the characters in a string have corresponding font characters. - - @param GetGlyph - Translates a Unicode character into the corresponding font glyph. - - @param GlyphToBlt - Converts a glyph value into a format that is ready for a UGA BLT command. - - @param NewString - Allows a new string to be added to an already existing string package. - - @param GetPrimaryLanguages - Allows a program to determine the primary languages that are supported - on a given handle. - - @param GetSecondaryLanguages - Allows a program to determine which secondary languages are supported - on a given handle for a given primary language. - - @param GetString - Extracts a string from a package that is already registered with the - EFI HII database. - - @param ResetString - Remove any new strings that were added after the initial string export - for this handle. - - @param GetLine - Allows a program to extract a part of a string of not more than a given width. - - @param GetForms - Allows a program to extract a form or form package that has been previously registered. - - @param GetDefaultImage - Allows a program to extract the nonvolatile image that represents the default storage image. - - @param UpdateForm - Allows a program to update a previously registered form. - - @param GetKeyboardLayout - Allows a program to extract the current keyboard layout. - -**/ -struct _EFI_HII_PROTOCOL { - EFI_HII_NEW_PACK NewPack; - EFI_HII_REMOVE_PACK RemovePack; - EFI_HII_FIND_HANDLES FindHandles; - EFI_HII_EXPORT ExportDatabase; - - EFI_HII_TEST_STRING TestString; - EFI_HII_GET_GLYPH GetGlyph; - EFI_HII_GLYPH_TO_BLT GlyphToBlt; - - EFI_HII_NEW_STRING NewString; - EFI_HII_GET_PRI_LANGUAGES GetPrimaryLanguages; - EFI_HII_GET_SEC_LANGUAGES GetSecondaryLanguages; - EFI_HII_GET_STRING GetString; - EFI_HII_RESET_STRINGS ResetStrings; - EFI_HII_GET_LINE GetLine; - EFI_HII_GET_FORMS GetForms; - EFI_HII_GET_DEFAULT_IMAGE GetDefaultImage; - EFI_HII_UPDATE_FORM UpdateForm; - - EFI_HII_GET_KEYBOARD_LAYOUT GetKeyboardLayout; -}; - -extern EFI_GUID gEfiHiiProtocolGuid; - -#endif diff --git a/BaseTools/Source/C/Include/Protocol/UgaDraw.h b/BaseTools/Source/C/Include/Protocol/UgaDraw.h deleted file mode 100644 index 412b000aeb..0000000000 --- a/BaseTools/Source/C/Include/Protocol/UgaDraw.h +++ /dev/null @@ -1,161 +0,0 @@ -/** @file - UGA Draw protocol from the EFI 1.1 specification. - - Abstraction of a very simple graphics device. - - Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __UGA_DRAW_H__ -#define __UGA_DRAW_H__ - -#define EFI_UGA_DRAW_PROTOCOL_GUID \ - { \ - 0x982c298b, 0xf4fa, 0x41cb, {0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 } \ - } - -typedef struct _EFI_UGA_DRAW_PROTOCOL EFI_UGA_DRAW_PROTOCOL; - -/** - Return the current video mode information. - - @param This Protocol instance pointer. - @param HorizontalResolution Current video horizontal resolution in pixels - @param VerticalResolution Current video vertical resolution in pixels - @param ColorDepth Current video color depth in bits per pixel - @param RefreshRate Current video refresh rate in Hz. - - @retval EFI_SUCCESS Mode information returned. - @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () - @retval EFI_INVALID_PARAMETER One of the input args was NULL. - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_UGA_DRAW_PROTOCOL_GET_MODE) ( - IN EFI_UGA_DRAW_PROTOCOL *This, - OUT UINT32 *HorizontalResolution, - OUT UINT32 *VerticalResolution, - OUT UINT32 *ColorDepth, - OUT UINT32 *RefreshRate - ) -; - -/** - Return the current video mode information. - - @param This Protocol instance pointer. - @param HorizontalResolution Current video horizontal resolution in pixels - @param VerticalResolution Current video vertical resolution in pixels - @param ColorDepth Current video color depth in bits per pixel - @param RefreshRate Current video refresh rate in Hz. - - @retval EFI_SUCCESS Mode information returned. - @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode () - -**/ -typedef -EFI_STATUS -(EFIAPI *EFI_UGA_DRAW_PROTOCOL_SET_MODE) ( - IN EFI_UGA_DRAW_PROTOCOL *This, - IN UINT32 HorizontalResolution, - IN UINT32 VerticalResolution, - IN UINT32 ColorDepth, - IN UINT32 RefreshRate - ) -; - -typedef struct { - UINT8 Blue; - UINT8 Green; - UINT8 Red; - UINT8 Reserved; -} EFI_UGA_PIXEL; - -typedef union { - EFI_UGA_PIXEL Pixel; - UINT32 Raw; -} EFI_UGA_PIXEL_UNION; - -typedef enum { - EfiUgaVideoFill, - EfiUgaVideoToBltBuffer, - EfiUgaBltBufferToVideo, - EfiUgaVideoToVideo, - EfiUgaBltMax -} EFI_UGA_BLT_OPERATION; - -/** - Type specifying a pointer to a function to perform an UGA Blt operation. - - The following table defines actions for BltOperations: - - EfiUgaVideoFill - Write data from the BltBuffer pixel (SourceX, SourceY) - directly to every pixel of the video display rectangle - (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). - Only one pixel will be used from the BltBuffer. Delta is NOT used. - - EfiUgaVideoToBltBuffer - Read data from the video display rectangle - (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in - the BltBuffer rectangle (DestinationX, DestinationY ) - (DestinationX + Width, DestinationY + Height). If DestinationX or - DestinationY is not zero then Delta must be set to the length in bytes - of a row in the BltBuffer. - - EfiUgaBltBufferToVideo - Write data from the BltBuffer rectangle - (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the - video display rectangle (DestinationX, DestinationY) - (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is - not zero then Delta must be set to the length in bytes of a row in the - BltBuffer. - - EfiUgaVideoToVideo - Copy from the video display rectangle (SourceX, SourceY) - (SourceX + Width, SourceY + Height) .to the video display rectangle - (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height). - The BltBuffer and Delta are not used in this mode. - - - @param[in] This - Protocol instance pointer. - @param[in] BltBuffer - Buffer containing data to blit into video buffer. This - buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL) - @param[in] BltOperation - Operation to perform on BlitBuffer and video memory - @param[in] SourceX - X coordinate of source for the BltBuffer. - @param[in] SourceY - Y coordinate of source for the BltBuffer. - @param[in] DestinationX - X coordinate of destination for the BltBuffer. - @param[in] DestinationY - Y coordinate of destination for the BltBuffer. - @param[in] Width - Width of rectangle in BltBuffer in pixels. - @param[in] Height - Height of rectangle in BltBuffer in pixels. - @param[in] Delta - OPTIONAL - - @retval EFI_SUCCESS - The Blt operation completed. - @retval EFI_INVALID_PARAMETER - BltOperation is not valid. - @retval EFI_DEVICE_ERROR - A hardware error occurred writing to the video buffer. - ---*/ -typedef -EFI_STATUS -(EFIAPI *EFI_UGA_DRAW_PROTOCOL_BLT) ( - IN EFI_UGA_DRAW_PROTOCOL * This, - IN EFI_UGA_PIXEL * BltBuffer, OPTIONAL - IN EFI_UGA_BLT_OPERATION BltOperation, - IN UINTN SourceX, - IN UINTN SourceY, - IN UINTN DestinationX, - IN UINTN DestinationY, - IN UINTN Width, - IN UINTN Height, - IN UINTN Delta OPTIONAL - ); - -struct _EFI_UGA_DRAW_PROTOCOL { - EFI_UGA_DRAW_PROTOCOL_GET_MODE GetMode; - EFI_UGA_DRAW_PROTOCOL_SET_MODE SetMode; - EFI_UGA_DRAW_PROTOCOL_BLT Blt; -}; - -extern EFI_GUID gEfiUgaDrawProtocolGuid; - -#endif diff --git a/BaseTools/Source/C/LzmaCompress/LzmaCompress.c b/BaseTools/Source/C/LzmaCompress/LzmaCompress.c index bf4706ee23..f9613a7d6d 100644 --- a/BaseTools/Source/C/LzmaCompress/LzmaCompress.c +++ b/BaseTools/Source/C/LzmaCompress/LzmaCompress.c @@ -12,6 +12,8 @@ #define _CRT_SECURE_NO_WARNINGS +#include "WinNtInclude.h" + #include #include #include diff --git a/BaseTools/Source/C/Makefiles/footer.makefile b/BaseTools/Source/C/Makefiles/footer.makefile index 7546da8cf5..e914749169 100644 --- a/BaseTools/Source/C/Makefiles/footer.makefile +++ b/BaseTools/Source/C/Makefiles/footer.makefile @@ -17,6 +17,10 @@ install: $(MAKEROOT)/libs-$(HOST_ARCH) $(LIBRARY) $(LIBRARY): $(OBJECTS) $(AR) crs $@ $^ +$(EDK2_OBJPATH)/%.o : $(EDK2_PATH)/%.c + @mkdir -p $(@D) + $(CC) -c $(CPPFLAGS) $(CFLAGS) $(EDK2_INCLUDE) $< -o $@ + %.o : %.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ @@ -26,5 +30,6 @@ $(LIBRARY): $(OBJECTS) .PHONY: clean clean: @rm -f $(OBJECTS) $(LIBRARY) $(DEPFILES) + @rm -rf $(EDK2_OBJPATH) -include $(DEPFILES) diff --git a/BaseTools/Source/C/Makefiles/header.makefile b/BaseTools/Source/C/Makefiles/header.makefile index f16b3297fc..31f94e9be9 100644 --- a/BaseTools/Source/C/Makefiles/header.makefile +++ b/BaseTools/Source/C/Makefiles/header.makefile @@ -9,6 +9,7 @@ # SPDX-License-Identifier: BSD-2-Clause-Patent EDK2_PATH ?= $(MAKEROOT)/../../.. +EDK2_OBJPATH ?= $(MAKEROOT)/obj/edk2 ifndef HOST_ARCH # @@ -84,7 +85,11 @@ $(error Bad HOST_ARCH) endif INCLUDE = $(TOOL_INCLUDE) -I $(MAKEROOT) -I $(MAKEROOT)/Include/Common -I $(MAKEROOT)/Include/ -I $(MAKEROOT)/Include/IndustryStandard -I $(MAKEROOT)/Common/ -I .. -I . $(ARCH_INCLUDE) -INCLUDE += -I $(EDK2_PATH)/MdePkg/Include + +INCLUDE += -I $(EDK2_PATH)/MdePkg/Include/ -I $(EDK2_PATH)/MdeModulePkg/Include/ + +EDK2_INCLUDE = -include $(MAKEROOT)/Include/Common/AutoGen.h + CPPFLAGS = $(INCLUDE) # keep EXTRA_OPTFLAGS last @@ -114,6 +119,12 @@ else LDFLAGS = CXXFLAGS = -Wno-unused-result endif + +CPPFLAGS += -fshort-wchar -flto -DUSING_LTO +ifeq ($(HOST_ARCH), X64) + CPPFLAGS += "-DEFIAPI=__attribute__((ms_abi))" +endif + ifeq ($(HOST_ARCH), IA32) # # Snow Leopard is a 32-bit and 64-bit environment. uname -m returns i386, but gcc defaults diff --git a/BaseTools/Source/C/Makefiles/ms.common b/BaseTools/Source/C/Makefiles/ms.common index 66f0f5ba4c..291e8f180c 100644 --- a/BaseTools/Source/C/Makefiles/ms.common +++ b/BaseTools/Source/C/Makefiles/ms.common @@ -34,6 +34,7 @@ EDK_TOOLS_PATH = $(EDK_TOOLS_PATH::\\=:\) SOURCE_PATH = $(BASE_TOOLS_PATH)\Source\C BIN_PATH = $(BASE_TOOLS_PATH)\Bin LIB_PATH = $(BASE_TOOLS_PATH)\Lib +EDK2_OBJPATH = ..\obj\edk2 SYS_BIN_PATH=$(EDK_TOOLS_PATH)\Bin SYS_LIB_PATH=$(EDK_TOOLS_PATH)\Lib @@ -42,6 +43,7 @@ SYS_LIB_PATH=$(EDK_TOOLS_PATH)\Lib ARCH_INCLUDE = $(EDK2_PATH)\MdePkg\Include\Ia32 BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win32 LIB_PATH = $(BASE_TOOLS_PATH)\Lib\Win32 +EDK2_OBJPATH = ..\obj\Win32\edk2 SYS_BIN_PATH = $(EDK_TOOLS_PATH)\Bin\Win32 SYS_LIB_PATH = $(EDK_TOOLS_PATH)\Lib\Win32 @@ -49,6 +51,7 @@ SYS_LIB_PATH = $(EDK_TOOLS_PATH)\Lib\Win32 ARCH_INCLUDE = $(EDK2_PATH)\MdePkg\Include\X64 BIN_PATH = $(BASE_TOOLS_PATH)\Bin\Win64 LIB_PATH = $(BASE_TOOLS_PATH)\Lib\Win64 +EDK2_OBJPATH = ..\obj\Win64\edk2 SYS_BIN_PATH = $(EDK_TOOLS_PATH)\Bin\Win64 SYS_LIB_PATH = $(EDK_TOOLS_PATH)\Lib\Win64 CFLAGS = $(CFLAGS) /wd4267 /wd4244 /wd4334 @@ -83,5 +86,9 @@ LINKER = $(LD) INC = $(INC) -I . -I $(SOURCE_PATH)\Include -I $(ARCH_INCLUDE) -I $(SOURCE_PATH)\Common INC = $(INC) -I $(EDK2_PATH)\MdePkg\Include +INC = $(INC) -I $(EDK2_PATH)\MdePkg\Include -I $(EDK2_PATH)\MdeModulePkg\Include + +EDK2_INC = $(INC) /FI..\Include\Common\AutoGen.h + CFLAGS = $(CFLAGS) /nologo /Z7 /c /O2 /MT /W4 /WX /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE CPPFLAGS = $(CPPFLAGS) /EHsc /nologo /Z7 /c /O2 /MT /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE diff --git a/BaseTools/Source/C/Makefiles/ms.rule b/BaseTools/Source/C/Makefiles/ms.rule index 7d53316c43..a7ea626592 100644 --- a/BaseTools/Source/C/Makefiles/ms.rule +++ b/BaseTools/Source/C/Makefiles/ms.rule @@ -7,6 +7,26 @@ #DEPFILES = $(OBJECTS:%.o=%.d) +{$(EDK2_PATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + +{$(EDK2_PATH)\MdePkg\Library\BaseLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseLib\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + +{$(EDK2_PATH)\MdePkg\Library\BaseMemoryLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseMemoryLib\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + +{$(EDK2_PATH)\MdePkg\Library\BasePrintLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BasePrintLib\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + +{$(EDK2_PATH)\MdePkg\Library\UefiDevicePathLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\UefiDevicePathLib\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + .c.obj : $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ diff --git a/BaseTools/Source/C/VolInfo/VolInfo.c b/BaseTools/Source/C/VolInfo/VolInfo.c index 428011ca04..be8e30dbde 100644 --- a/BaseTools/Source/C/VolInfo/VolInfo.c +++ b/BaseTools/Source/C/VolInfo/VolInfo.c @@ -23,9 +23,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include -#include -#include +#include +#include +#include #include "Compress.h" #include "Decompress.h" @@ -1395,7 +1395,7 @@ Routine Description: break; } - if (!CompareGuid ( + if (!BtCompareGuid ( &FileHeader->Name, &gPeiAprioriFileNameGuid )) @@ -1404,7 +1404,7 @@ Routine Description: printf("PEI APRIORI FILE:\n"); return PrintAprioriFile (FileHeader); } - if (!CompareGuid ( + if (!BtCompareGuid ( &FileHeader->Name, &gAprioriGuid )) @@ -1418,6 +1418,7 @@ Routine Description: } EFI_STATUS +EFIAPI RebaseImageRead ( IN VOID *FileHandle, IN UINTN FileOffset, @@ -2082,7 +2083,7 @@ Routine Description: ); free (ExtractionTool); - if (!CompareGuid ( + if (!BtCompareGuid ( EfiGuid, &gEfiCrc32GuidedSectionExtractionProtocolGuid ) @@ -2128,7 +2129,7 @@ Routine Description: // // Check for CRC32 sections which we can handle internally if needed. // - } else if (!CompareGuid ( + } else if (!BtCompareGuid ( EfiGuid, &gEfiCrc32GuidedSectionExtractionProtocolGuid ) From 48e9d4282c0590f4699d4a764b6c71583ab1173c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Wed, 8 Mar 2023 17:25:27 +0100 Subject: [PATCH 043/341] BaseTools/DevicePath: Consume MdePkg/UefiDevicePathLib MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BaseTools has been duplicating and adapting code that is defined in MdePkg and MdeModulePkg. This leads to desync issues where the same symbols may be backed by different functions with slightly different semantics and also fixes that apply only to BaseTools or only to MdePkg and MdeModulePkg. To address these issues, update BaseTools/Source/C to utilize the code from MdePkg and MdeModulePkg. Signed-off-by: Marvin Häuser --- BaseTools/Source/C/Common/CommonLib.c | 153 +- BaseTools/Source/C/Common/CommonLib.h | 29 - .../Source/C/DevicePath/DevicePathFromText.c | 3520 ----------------- .../Source/C/DevicePath/DevicePathUtilities.c | 868 ---- BaseTools/Source/C/DevicePath/GNUmakefile | 9 +- .../Source/C/DevicePath/UefiDevicePathLib.c | 292 -- .../Source/C/DevicePath/UefiDevicePathLib.h | 524 +-- BaseTools/Source/C/Include/Common/AutoGen.h | 7 + 8 files changed, 24 insertions(+), 5378 deletions(-) delete mode 100644 BaseTools/Source/C/DevicePath/DevicePathFromText.c delete mode 100644 BaseTools/Source/C/DevicePath/DevicePathUtilities.c delete mode 100644 BaseTools/Source/C/DevicePath/UefiDevicePathLib.c diff --git a/BaseTools/Source/C/Common/CommonLib.c b/BaseTools/Source/C/Common/CommonLib.c index ded1cbb5c3..3f022fba46 100644 --- a/BaseTools/Source/C/Common/CommonLib.c +++ b/BaseTools/Source/C/Common/CommonLib.c @@ -576,157 +576,14 @@ AllocatePool ( return InternalAllocatePool (AllocationSize); } -/** - Return whether the integer string is a hex string. - - @param Str The integer string - - @retval TRUE Hex string - @retval FALSE Decimal string - -**/ -BOOLEAN -IsHexStr ( - CHAR16 *Str - ) -{ - // - // skip preceding white space - // - while ((*Str != 0) && *Str == L' ') { - Str ++; - } - // - // skip preceding zeros - // - while ((*Str != 0) && *Str == L'0') { - Str ++; - } - - return (BOOLEAN) (*Str == L'x' || *Str == L'X'); -} - -/** - - Convert integer string to uint. - - @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal. - - @return A UINTN value represented by Str - -**/ -UINTN -Strtoi ( - CHAR16 *Str - ) -{ - if (IsHexStr (Str)) { - return (UINTN)StrHexToUint64 (Str); - } else { - return (UINTN)StrDecimalToUint64 (Str); - } -} - -/** - - Convert integer string to 64 bit data. - - @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal. - @param Data A pointer to the UINT64 value represented by Str - -**/ VOID -Strtoi64 ( - CHAR16 *Str, - UINT64 *Data - ) -{ - if (IsHexStr (Str)) { - *Data = StrHexToUint64 (Str); - } else { - *Data = StrDecimalToUint64 (Str); - } -} - -/** - Converts a Unicode string to ASCII string. - - @param Str The equivalent Unicode string - @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points - to the next ASCII string next to it - -**/ -VOID -StrToAscii ( - CHAR16 *Str, - CHAR8 **AsciiStr - ) -{ - CHAR8 *Dest; - - Dest = *AsciiStr; - while (!IS_NULL (*Str)) { - *(Dest++) = (CHAR8) *(Str++); - } - *Dest = 0; - - // - // Return the string next to it - // - *AsciiStr = Dest + 1; -} - -/** - Gets current sub-string from a string list, before return - the list header is moved to next sub-string. The sub-string is separated - by the specified character. For example, the separator is ',', the string - list is "2,0,3", it returns "2", the remain list move to "0,3" - - @param List A string list separated by the specified separator - @param Separator The separator character - - @return A pointer to the current sub-string - -**/ -CHAR16 * -SplitStr ( - CHAR16 **List, - CHAR16 Separator +EFIAPI +FreePool ( + IN VOID *Buffer ) { - CHAR16 *Str; - CHAR16 *ReturnStr; - - Str = *List; - ReturnStr = Str; - - if (IS_NULL (*Str)) { - return ReturnStr; - } - - // - // Find first occurrence of the separator - // - while (!IS_NULL (*Str)) { - if (*Str == Separator) { - break; - } - Str++; - } - - if (*Str == Separator) { - // - // Find a sub-string, terminate it - // - *Str = L'\0'; - Str++; - } - - // - // Move to next sub-string - // - *List = Str; - return ReturnStr; + ASSERT (Buffer != NULL); + free (Buffer); } VOID diff --git a/BaseTools/Source/C/Common/CommonLib.h b/BaseTools/Source/C/Common/CommonLib.h index 923f936e4f..6ac64897f1 100644 --- a/BaseTools/Source/C/Common/CommonLib.h +++ b/BaseTools/Source/C/Common/CommonLib.h @@ -113,35 +113,6 @@ LongFilePath ( IN CHAR8 *FileName ); - -BOOLEAN -IsHexStr ( - CHAR16 *Str - ); - -UINTN -Strtoi ( - CHAR16 *Str - ); - -VOID -Strtoi64 ( - CHAR16 *Str, - UINT64 *Data - ); - -VOID -StrToAscii ( - CHAR16 *Str, - CHAR8 **AsciiStr - ); - -CHAR16 * -SplitStr ( - CHAR16 **List, - CHAR16 Separator - ); - /*++ Routine Description: diff --git a/BaseTools/Source/C/DevicePath/DevicePathFromText.c b/BaseTools/Source/C/DevicePath/DevicePathFromText.c deleted file mode 100644 index fc39881c9a..0000000000 --- a/BaseTools/Source/C/DevicePath/DevicePathFromText.c +++ /dev/null @@ -1,3520 +0,0 @@ -/** @file - DevicePathFromText protocol as defined in the UEFI 2.0 specification. - -Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "UefiDevicePathLib.h" - -/** - - Duplicates a string. - - @param Src Source string. - - @return The duplicated string. - -**/ -CHAR16 * -UefiDevicePathLibStrDuplicate ( - CONST CHAR16 *Src - ) -{ - return AllocateCopyPool (StrSize (Src), Src); -} - -/** - - Get parameter in a pair of parentheses follow the given node name. - For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1". - - @param Str Device Path Text. - @param NodeName Name of the node. - - @return Parameter text for the node. - -**/ -CHAR16 * -GetParamByNodeName ( - CHAR16 *Str, - CHAR16 *NodeName - ) -{ - CHAR16 *ParamStr; - CHAR16 *StrPointer; - UINTN NodeNameLength; - UINTN ParameterLength; - - // - // Check whether the node name matchs - // - NodeNameLength = StrLen (NodeName); - if (StrnCmp (Str, NodeName, NodeNameLength) != 0) { - return NULL; - } - - ParamStr = Str + NodeNameLength; - if (!IS_LEFT_PARENTH (*ParamStr)) { - return NULL; - } - - // - // Skip the found '(' and find first occurrence of ')' - // - ParamStr++; - ParameterLength = 0; - StrPointer = ParamStr; - while (!IS_NULL (*StrPointer)) { - if (IS_RIGHT_PARENTH (*StrPointer)) { - break; - } - StrPointer++; - ParameterLength++; - } - if (IS_NULL (*StrPointer)) { - // - // ')' not found - // - return NULL; - } - - ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), ParamStr); - if (ParamStr == NULL) { - return NULL; - } - // - // Terminate the parameter string - // - ParamStr[ParameterLength] = L'\0'; - - return ParamStr; -} - -/** - Gets the next parameter string from the list. - - @param List A string list separated by the specified separator - - @return A pointer to the current sub-string - -**/ -CHAR16 * -GetNextParamStr ( - CHAR16 **List - ) -{ - // - // The separator is comma - // - return SplitStr (List, L','); -} - -/** - Get one device node from entire device path text. - - @param DevicePath On input, the current Device Path node; on output, the next device path node - @param IsInstanceEnd This node is the end of a device path instance - - @return A device node text or NULL if no more device node available - -**/ -CHAR16 * -GetNextDeviceNodeStr ( - CHAR16 **DevicePath, - BOOLEAN *IsInstanceEnd - ) -{ - CHAR16 *Str; - CHAR16 *ReturnStr; - UINTN ParenthesesStack; - - Str = *DevicePath; - if (IS_NULL (*Str)) { - return NULL; - } - - // - // Skip the leading '/', '(', ')' and ',' - // - while (!IS_NULL (*Str)) { - if (!IS_SLASH (*Str) && - !IS_COMMA (*Str) && - !IS_LEFT_PARENTH (*Str) && - !IS_RIGHT_PARENTH (*Str)) { - break; - } - Str++; - } - - ReturnStr = Str; - - // - // Scan for the separator of this device node, '/' or ',' - // - ParenthesesStack = 0; - while (!IS_NULL (*Str)) { - if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) { - break; - } - - if (IS_LEFT_PARENTH (*Str)) { - ParenthesesStack++; - } else if (IS_RIGHT_PARENTH (*Str)) { - ParenthesesStack--; - } - - Str++; - } - - if (ParenthesesStack != 0) { - // - // The '(' doesn't pair with ')', invalid device path text - // - return NULL; - } - - if (IS_COMMA (*Str)) { - *IsInstanceEnd = TRUE; - *Str = L'\0'; - Str++; - } else { - *IsInstanceEnd = FALSE; - if (!IS_NULL (*Str)) { - *Str = L'\0'; - Str++; - } - } - - *DevicePath = Str; - - return ReturnStr; -} - -/** - Converts a generic text device path node to device path structure. - - @param Type The type of the device path node. - @param TextDeviceNode The input text device path node. - - @return A pointer to device path structure. -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextGenericPath ( - UINT8 Type, - CHAR16 *TextDeviceNode - ) -{ - EFI_DEVICE_PATH_PROTOCOL *Node; - CHAR16 *SubtypeStr; - CHAR16 *DataStr; - UINTN DataLength; - - SubtypeStr = GetNextParamStr (&TextDeviceNode); - DataStr = GetNextParamStr (&TextDeviceNode); - - if (DataStr == NULL) { - DataLength = 0; - } else { - DataLength = StrLen (DataStr) / 2; - } - Node = CreateDeviceNode ( - Type, - (UINT8) Strtoi (SubtypeStr), - (UINT16) (sizeof (EFI_DEVICE_PATH_PROTOCOL) + DataLength) - ); - - StrHexToBytes (DataStr, DataLength * 2, (UINT8 *) (Node + 1), DataLength); - return Node; -} - -/** - Converts a generic text device path node to device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextPath ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *TypeStr; - - TypeStr = GetNextParamStr (&TextDeviceNode); - - return DevPathFromTextGenericPath ((UINT8) Strtoi (TypeStr), TextDeviceNode); -} - -/** - Converts a generic hardware text device path node to Hardware device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to Hardware device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextHardwarePath ( - CHAR16 *TextDeviceNode - ) -{ - return DevPathFromTextGenericPath (HARDWARE_DEVICE_PATH, TextDeviceNode); -} - -/** - Converts a text device path node to Hardware PCI device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to Hardware PCI device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextPci ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *FunctionStr; - CHAR16 *DeviceStr; - PCI_DEVICE_PATH *Pci; - - DeviceStr = GetNextParamStr (&TextDeviceNode); - FunctionStr = GetNextParamStr (&TextDeviceNode); - Pci = (PCI_DEVICE_PATH *) CreateDeviceNode ( - HARDWARE_DEVICE_PATH, - HW_PCI_DP, - (UINT16) sizeof (PCI_DEVICE_PATH) - ); - - Pci->Function = (UINT8) Strtoi (FunctionStr); - Pci->Device = (UINT8) Strtoi (DeviceStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Pci; -} - -/** - Converts a text device path node to Hardware PC card device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to Hardware PC card device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextPcCard ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *FunctionNumberStr; - PCCARD_DEVICE_PATH *Pccard; - - FunctionNumberStr = GetNextParamStr (&TextDeviceNode); - Pccard = (PCCARD_DEVICE_PATH *) CreateDeviceNode ( - HARDWARE_DEVICE_PATH, - HW_PCCARD_DP, - (UINT16) sizeof (PCCARD_DEVICE_PATH) - ); - - Pccard->FunctionNumber = (UINT8) Strtoi (FunctionNumberStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Pccard; -} - -/** - Converts a text device path node to Hardware memory map device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to Hardware memory map device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextMemoryMapped ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *MemoryTypeStr; - CHAR16 *StartingAddressStr; - CHAR16 *EndingAddressStr; - MEMMAP_DEVICE_PATH *MemMap; - - MemoryTypeStr = GetNextParamStr (&TextDeviceNode); - StartingAddressStr = GetNextParamStr (&TextDeviceNode); - EndingAddressStr = GetNextParamStr (&TextDeviceNode); - MemMap = (MEMMAP_DEVICE_PATH *) CreateDeviceNode ( - HARDWARE_DEVICE_PATH, - HW_MEMMAP_DP, - (UINT16) sizeof (MEMMAP_DEVICE_PATH) - ); - - MemMap->MemoryType = (UINT32) Strtoi (MemoryTypeStr); - Strtoi64 (StartingAddressStr, &MemMap->StartingAddress); - Strtoi64 (EndingAddressStr, &MemMap->EndingAddress); - - return (EFI_DEVICE_PATH_PROTOCOL *) MemMap; -} - -/** - Converts a text device path node to Vendor device path structure based on the input Type - and SubType. - - @param TextDeviceNode The input Text device path node. - @param Type The type of device path node. - @param SubType The subtype of device path node. - - @return A pointer to the newly-created Vendor device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -ConvertFromTextVendor ( - CHAR16 *TextDeviceNode, - UINT8 Type, - UINT8 SubType - ) -{ - CHAR16 *GuidStr; - CHAR16 *DataStr; - UINTN Length; - VENDOR_DEVICE_PATH *Vendor; - - GuidStr = GetNextParamStr (&TextDeviceNode); - - DataStr = GetNextParamStr (&TextDeviceNode); - Length = StrLen (DataStr); - // - // Two hex characters make up 1 buffer byte - // - Length = (Length + 1) / 2; - - Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( - Type, - SubType, - (UINT16) (sizeof (VENDOR_DEVICE_PATH) + Length) - ); - - StrToGuid (GuidStr, &Vendor->Guid); - StrHexToBytes (DataStr, Length * 2, (UINT8 *) (Vendor + 1), Length); - - return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; -} - -/** - Converts a text device path node to Vendor Hardware device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Vendor Hardware device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextVenHw ( - CHAR16 *TextDeviceNode - ) -{ - return ConvertFromTextVendor ( - TextDeviceNode, - HARDWARE_DEVICE_PATH, - HW_VENDOR_DP - ); -} - -/** - Converts a text device path node to Hardware Controller device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Hardware Controller device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextCtrl ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *ControllerStr; - CONTROLLER_DEVICE_PATH *Controller; - - ControllerStr = GetNextParamStr (&TextDeviceNode); - Controller = (CONTROLLER_DEVICE_PATH *) CreateDeviceNode ( - HARDWARE_DEVICE_PATH, - HW_CONTROLLER_DP, - (UINT16) sizeof (CONTROLLER_DEVICE_PATH) - ); - Controller->ControllerNumber = (UINT32) Strtoi (ControllerStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Controller; -} - -/** - Converts a text device path node to BMC device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created BMC device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextBmc ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *InterfaceTypeStr; - CHAR16 *BaseAddressStr; - BMC_DEVICE_PATH *BmcDp; - - InterfaceTypeStr = GetNextParamStr (&TextDeviceNode); - BaseAddressStr = GetNextParamStr (&TextDeviceNode); - BmcDp = (BMC_DEVICE_PATH *) CreateDeviceNode ( - HARDWARE_DEVICE_PATH, - HW_BMC_DP, - (UINT16) sizeof (BMC_DEVICE_PATH) - ); - - BmcDp->InterfaceType = (UINT8) Strtoi (InterfaceTypeStr); - WriteUnaligned64 ( - (UINT64 *) (&BmcDp->BaseAddress), - StrHexToUint64 (BaseAddressStr) - ); - - return (EFI_DEVICE_PATH_PROTOCOL *) BmcDp; -} - -/** - Converts a generic ACPI text device path node to ACPI device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to ACPI device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextAcpiPath ( - CHAR16 *TextDeviceNode - ) -{ - return DevPathFromTextGenericPath (ACPI_DEVICE_PATH, TextDeviceNode); -} - -/** - Converts a string to EisaId. - - @param Text The input string. - - @return UINT32 EISA ID. -**/ -UINT32 -EisaIdFromText ( - CHAR16 *Text - ) -{ - return (((Text[0] - 'A' + 1) & 0x1f) << 10) - + (((Text[1] - 'A' + 1) & 0x1f) << 5) - + (((Text[2] - 'A' + 1) & 0x1f) << 0) - + (UINT32) (StrHexToUint64 (&Text[3]) << 16) - ; -} - -/** - Converts a text device path node to ACPI HID device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created ACPI HID device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextAcpi ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *HIDStr; - CHAR16 *UIDStr; - ACPI_HID_DEVICE_PATH *Acpi; - - HIDStr = GetNextParamStr (&TextDeviceNode); - UIDStr = GetNextParamStr (&TextDeviceNode); - Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode ( - ACPI_DEVICE_PATH, - ACPI_DP, - (UINT16) sizeof (ACPI_HID_DEVICE_PATH) - ); - - Acpi->HID = EisaIdFromText (HIDStr); - Acpi->UID = (UINT32) Strtoi (UIDStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Acpi; -} - -/** - Converts a text device path node to ACPI HID device path structure. - - @param TextDeviceNode The input Text device path node. - @param PnPId The input plug and play identification. - - @return A pointer to the newly-created ACPI HID device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -ConvertFromTextAcpi ( - CHAR16 *TextDeviceNode, - UINT32 PnPId - ) -{ - CHAR16 *UIDStr; - ACPI_HID_DEVICE_PATH *Acpi; - - UIDStr = GetNextParamStr (&TextDeviceNode); - Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode ( - ACPI_DEVICE_PATH, - ACPI_DP, - (UINT16) sizeof (ACPI_HID_DEVICE_PATH) - ); - - Acpi->HID = EFI_PNP_ID (PnPId); - Acpi->UID = (UINT32) Strtoi (UIDStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Acpi; -} - -/** - Converts a text device path node to PCI root device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created PCI root device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextPciRoot ( - CHAR16 *TextDeviceNode - ) -{ - return ConvertFromTextAcpi (TextDeviceNode, 0x0a03); -} - -/** - Converts a text device path node to PCIE root device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created PCIE root device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextPcieRoot ( - CHAR16 *TextDeviceNode - ) -{ - return ConvertFromTextAcpi (TextDeviceNode, 0x0a08); -} - -/** - Converts a text device path node to Floppy device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Floppy device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextFloppy ( - CHAR16 *TextDeviceNode - ) -{ - return ConvertFromTextAcpi (TextDeviceNode, 0x0604); -} - -/** - Converts a text device path node to Keyboard device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Keyboard device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextKeyboard ( - CHAR16 *TextDeviceNode - ) -{ - return ConvertFromTextAcpi (TextDeviceNode, 0x0301); -} - -/** - Converts a text device path node to Serial device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Serial device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextSerial ( - CHAR16 *TextDeviceNode - ) -{ - return ConvertFromTextAcpi (TextDeviceNode, 0x0501); -} - -/** - Converts a text device path node to Parallel Port device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Parallel Port device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextParallelPort ( - CHAR16 *TextDeviceNode - ) -{ - return ConvertFromTextAcpi (TextDeviceNode, 0x0401); -} - -/** - Converts a text device path node to ACPI extension device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created ACPI extension device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextAcpiEx ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *HIDStr; - CHAR16 *CIDStr; - CHAR16 *UIDStr; - CHAR16 *HIDSTRStr; - CHAR16 *CIDSTRStr; - CHAR16 *UIDSTRStr; - CHAR8 *AsciiStr; - UINT16 Length; - ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx; - - HIDStr = GetNextParamStr (&TextDeviceNode); - CIDStr = GetNextParamStr (&TextDeviceNode); - UIDStr = GetNextParamStr (&TextDeviceNode); - HIDSTRStr = GetNextParamStr (&TextDeviceNode); - CIDSTRStr = GetNextParamStr (&TextDeviceNode); - UIDSTRStr = GetNextParamStr (&TextDeviceNode); - - Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (HIDSTRStr) + 1); - Length = (UINT16) (Length + StrLen (UIDSTRStr) + 1); - Length = (UINT16) (Length + StrLen (CIDSTRStr) + 1); - AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode ( - ACPI_DEVICE_PATH, - ACPI_EXTENDED_DP, - Length - ); - - AcpiEx->HID = EisaIdFromText (HIDStr); - AcpiEx->CID = EisaIdFromText (CIDStr); - AcpiEx->UID = (UINT32) Strtoi (UIDStr); - - AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH)); - StrToAscii (HIDSTRStr, &AsciiStr); - StrToAscii (UIDSTRStr, &AsciiStr); - StrToAscii (CIDSTRStr, &AsciiStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx; -} - -/** - Converts a text device path node to ACPI extension device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created ACPI extension device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextAcpiExp ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *HIDStr; - CHAR16 *CIDStr; - CHAR16 *UIDSTRStr; - CHAR8 *AsciiStr; - UINT16 Length; - ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx; - - HIDStr = GetNextParamStr (&TextDeviceNode); - CIDStr = GetNextParamStr (&TextDeviceNode); - UIDSTRStr = GetNextParamStr (&TextDeviceNode); - Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (UIDSTRStr) + 3); - AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode ( - ACPI_DEVICE_PATH, - ACPI_EXTENDED_DP, - Length - ); - - AcpiEx->HID = EisaIdFromText (HIDStr); - // - // According to UEFI spec, the CID parametr is optional and has a default value of 0. - // So when the CID parametr is not specified or specified as 0 in the text device node. - // Set the CID to 0 in the ACPI extension device path structure. - // - if (*CIDStr == L'\0' || *CIDStr == L'0') { - AcpiEx->CID = 0; - } else { - AcpiEx->CID = EisaIdFromText (CIDStr); - } - AcpiEx->UID = 0; - - AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH)); - // - // HID string is NULL - // - *AsciiStr = '\0'; - // - // Convert UID string - // - AsciiStr++; - StrToAscii (UIDSTRStr, &AsciiStr); - // - // CID string is NULL - // - *AsciiStr = '\0'; - - return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx; -} - -/** - Converts a text device path node to ACPI _ADR device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created ACPI _ADR device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextAcpiAdr ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *DisplayDeviceStr; - ACPI_ADR_DEVICE_PATH *AcpiAdr; - UINTN Index; - UINTN Length; - - AcpiAdr = (ACPI_ADR_DEVICE_PATH *) CreateDeviceNode ( - ACPI_DEVICE_PATH, - ACPI_ADR_DP, - (UINT16) sizeof (ACPI_ADR_DEVICE_PATH) - ); - ASSERT (AcpiAdr != NULL); - - for (Index = 0; ; Index++) { - DisplayDeviceStr = GetNextParamStr (&TextDeviceNode); - if (IS_NULL (*DisplayDeviceStr)) { - break; - } - if (Index > 0) { - Length = DevicePathNodeLength (AcpiAdr); - AcpiAdr = ReallocatePool ( - Length, - Length + sizeof (UINT32), - AcpiAdr - ); - ASSERT (AcpiAdr != NULL); - SetDevicePathNodeLength (AcpiAdr, Length + sizeof (UINT32)); - } - - (&AcpiAdr->ADR)[Index] = (UINT32) Strtoi (DisplayDeviceStr); - } - - return (EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr; -} - -/** - Converts a generic messaging text device path node to messaging device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to messaging device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextMsg ( - CHAR16 *TextDeviceNode - ) -{ - return DevPathFromTextGenericPath (MESSAGING_DEVICE_PATH, TextDeviceNode); -} - -/** - Converts a text device path node to Parallel Port device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Parallel Port device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextAta ( - CHAR16 *TextDeviceNode -) -{ - CHAR16 *PrimarySecondaryStr; - CHAR16 *SlaveMasterStr; - CHAR16 *LunStr; - ATAPI_DEVICE_PATH *Atapi; - - Atapi = (ATAPI_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_ATAPI_DP, - (UINT16) sizeof (ATAPI_DEVICE_PATH) - ); - - PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode); - SlaveMasterStr = GetNextParamStr (&TextDeviceNode); - LunStr = GetNextParamStr (&TextDeviceNode); - - if (StrCmp (PrimarySecondaryStr, L"Primary") == 0) { - Atapi->PrimarySecondary = 0; - } else if (StrCmp (PrimarySecondaryStr, L"Secondary") == 0) { - Atapi->PrimarySecondary = 1; - } else { - Atapi->PrimarySecondary = (UINT8) Strtoi (PrimarySecondaryStr); - } - if (StrCmp (SlaveMasterStr, L"Master") == 0) { - Atapi->SlaveMaster = 0; - } else if (StrCmp (SlaveMasterStr, L"Slave") == 0) { - Atapi->SlaveMaster = 1; - } else { - Atapi->SlaveMaster = (UINT8) Strtoi (SlaveMasterStr); - } - - Atapi->Lun = (UINT16) Strtoi (LunStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Atapi; -} - -/** - Converts a text device path node to SCSI device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created SCSI device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextScsi ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *PunStr; - CHAR16 *LunStr; - SCSI_DEVICE_PATH *Scsi; - - PunStr = GetNextParamStr (&TextDeviceNode); - LunStr = GetNextParamStr (&TextDeviceNode); - Scsi = (SCSI_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_SCSI_DP, - (UINT16) sizeof (SCSI_DEVICE_PATH) - ); - - Scsi->Pun = (UINT16) Strtoi (PunStr); - Scsi->Lun = (UINT16) Strtoi (LunStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Scsi; -} - -/** - Converts a text device path node to Fibre device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Fibre device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextFibre ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *WWNStr; - CHAR16 *LunStr; - FIBRECHANNEL_DEVICE_PATH *Fibre; - - WWNStr = GetNextParamStr (&TextDeviceNode); - LunStr = GetNextParamStr (&TextDeviceNode); - Fibre = (FIBRECHANNEL_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_FIBRECHANNEL_DP, - (UINT16) sizeof (FIBRECHANNEL_DEVICE_PATH) - ); - - Fibre->Reserved = 0; - Strtoi64 (WWNStr, &Fibre->WWN); - Strtoi64 (LunStr, &Fibre->Lun); - - return (EFI_DEVICE_PATH_PROTOCOL *) Fibre; -} - -/** - Converts a text device path node to FibreEx device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created FibreEx device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextFibreEx ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *WWNStr; - CHAR16 *LunStr; - FIBRECHANNELEX_DEVICE_PATH *FibreEx; - - WWNStr = GetNextParamStr (&TextDeviceNode); - LunStr = GetNextParamStr (&TextDeviceNode); - FibreEx = (FIBRECHANNELEX_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_FIBRECHANNELEX_DP, - (UINT16) sizeof (FIBRECHANNELEX_DEVICE_PATH) - ); - - FibreEx->Reserved = 0; - Strtoi64 (WWNStr, (UINT64 *) (&FibreEx->WWN)); - Strtoi64 (LunStr, (UINT64 *) (&FibreEx->Lun)); - - *(UINT64 *) (&FibreEx->WWN) = SwapBytes64 (*(UINT64 *) (&FibreEx->WWN)); - *(UINT64 *) (&FibreEx->Lun) = SwapBytes64 (*(UINT64 *) (&FibreEx->Lun)); - - return (EFI_DEVICE_PATH_PROTOCOL *) FibreEx; -} - -/** - Converts a text device path node to 1394 device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created 1394 device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromText1394 ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *GuidStr; - F1394_DEVICE_PATH *F1394DevPath; - - GuidStr = GetNextParamStr (&TextDeviceNode); - F1394DevPath = (F1394_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_1394_DP, - (UINT16) sizeof (F1394_DEVICE_PATH) - ); - - F1394DevPath->Reserved = 0; - F1394DevPath->Guid = StrHexToUint64 (GuidStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) F1394DevPath; -} - -/** - Converts a text device path node to USB device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsb ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *PortStr; - CHAR16 *InterfaceStr; - USB_DEVICE_PATH *Usb; - - PortStr = GetNextParamStr (&TextDeviceNode); - InterfaceStr = GetNextParamStr (&TextDeviceNode); - Usb = (USB_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_USB_DP, - (UINT16) sizeof (USB_DEVICE_PATH) - ); - - Usb->ParentPortNumber = (UINT8) Strtoi (PortStr); - Usb->InterfaceNumber = (UINT8) Strtoi (InterfaceStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Usb; -} - -/** - Converts a text device path node to I20 device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created I20 device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextI2O ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *TIDStr; - I2O_DEVICE_PATH *I2ODevPath; - - TIDStr = GetNextParamStr (&TextDeviceNode); - I2ODevPath = (I2O_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_I2O_DP, - (UINT16) sizeof (I2O_DEVICE_PATH) - ); - - I2ODevPath->Tid = (UINT32) Strtoi (TIDStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) I2ODevPath; -} - -/** - Converts a text device path node to Infini Band device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Infini Band device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextInfiniband ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *FlagsStr; - CHAR16 *GuidStr; - CHAR16 *SidStr; - CHAR16 *TidStr; - CHAR16 *DidStr; - INFINIBAND_DEVICE_PATH *InfiniBand; - - FlagsStr = GetNextParamStr (&TextDeviceNode); - GuidStr = GetNextParamStr (&TextDeviceNode); - SidStr = GetNextParamStr (&TextDeviceNode); - TidStr = GetNextParamStr (&TextDeviceNode); - DidStr = GetNextParamStr (&TextDeviceNode); - InfiniBand = (INFINIBAND_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_INFINIBAND_DP, - (UINT16) sizeof (INFINIBAND_DEVICE_PATH) - ); - - InfiniBand->ResourceFlags = (UINT32) Strtoi (FlagsStr); - StrToGuid (GuidStr, (EFI_GUID *) InfiniBand->PortGid); - Strtoi64 (SidStr, &InfiniBand->ServiceId); - Strtoi64 (TidStr, &InfiniBand->TargetPortId); - Strtoi64 (DidStr, &InfiniBand->DeviceId); - - return (EFI_DEVICE_PATH_PROTOCOL *) InfiniBand; -} - -/** - Converts a text device path node to Vendor-Defined Messaging device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Vendor-Defined Messaging device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextVenMsg ( - CHAR16 *TextDeviceNode - ) -{ - return ConvertFromTextVendor ( - TextDeviceNode, - MESSAGING_DEVICE_PATH, - MSG_VENDOR_DP - ); -} - -/** - Converts a text device path node to Vendor defined PC-ANSI device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Vendor defined PC-ANSI device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextVenPcAnsi ( - CHAR16 *TextDeviceNode - ) -{ - VENDOR_DEVICE_PATH *Vendor; - - Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_VENDOR_DP, - (UINT16) sizeof (VENDOR_DEVICE_PATH)); - CopyGuid (&Vendor->Guid, &gEfiPcAnsiGuid); - - return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; -} - -/** - Converts a text device path node to Vendor defined VT100 device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Vendor defined VT100 device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextVenVt100 ( - CHAR16 *TextDeviceNode - ) -{ - VENDOR_DEVICE_PATH *Vendor; - - Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_VENDOR_DP, - (UINT16) sizeof (VENDOR_DEVICE_PATH)); - CopyGuid (&Vendor->Guid, &gEfiVT100Guid); - - return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; -} - -/** - Converts a text device path node to Vendor defined VT100 Plus device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Vendor defined VT100 Plus device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextVenVt100Plus ( - CHAR16 *TextDeviceNode - ) -{ - VENDOR_DEVICE_PATH *Vendor; - - Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_VENDOR_DP, - (UINT16) sizeof (VENDOR_DEVICE_PATH)); - CopyGuid (&Vendor->Guid, &gEfiVT100PlusGuid); - - return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; -} - -/** - Converts a text device path node to Vendor defined UTF8 device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Vendor defined UTF8 device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextVenUtf8 ( - CHAR16 *TextDeviceNode - ) -{ - VENDOR_DEVICE_PATH *Vendor; - - Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_VENDOR_DP, - (UINT16) sizeof (VENDOR_DEVICE_PATH)); - CopyGuid (&Vendor->Guid, &gEfiVTUTF8Guid); - - return (EFI_DEVICE_PATH_PROTOCOL *) Vendor; -} - -/** - Converts a text device path node to UART Flow Control device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created UART Flow Control device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUartFlowCtrl ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *ValueStr; - UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl; - - ValueStr = GetNextParamStr (&TextDeviceNode); - UartFlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_VENDOR_DP, - (UINT16) sizeof (UART_FLOW_CONTROL_DEVICE_PATH) - ); - - CopyGuid (&UartFlowControl->Guid, &gEfiUartDevicePathGuid); - if (StrCmp (ValueStr, L"XonXoff") == 0) { - UartFlowControl->FlowControlMap = 2; - } else if (StrCmp (ValueStr, L"Hardware") == 0) { - UartFlowControl->FlowControlMap = 1; - } else { - UartFlowControl->FlowControlMap = 0; - } - - return (EFI_DEVICE_PATH_PROTOCOL *) UartFlowControl; -} - -/** - Converts a text device path node to Serial Attached SCSI device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Serial Attached SCSI device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextSAS ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *AddressStr; - CHAR16 *LunStr; - CHAR16 *RTPStr; - CHAR16 *SASSATAStr; - CHAR16 *LocationStr; - CHAR16 *ConnectStr; - CHAR16 *DriveBayStr; - CHAR16 *ReservedStr; - UINT16 Info; - UINT16 Uint16; - SAS_DEVICE_PATH *Sas; - - AddressStr = GetNextParamStr (&TextDeviceNode); - LunStr = GetNextParamStr (&TextDeviceNode); - RTPStr = GetNextParamStr (&TextDeviceNode); - SASSATAStr = GetNextParamStr (&TextDeviceNode); - LocationStr = GetNextParamStr (&TextDeviceNode); - ConnectStr = GetNextParamStr (&TextDeviceNode); - DriveBayStr = GetNextParamStr (&TextDeviceNode); - ReservedStr = GetNextParamStr (&TextDeviceNode); - Sas = (SAS_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_VENDOR_DP, - (UINT16) sizeof (SAS_DEVICE_PATH) - ); - - CopyGuid (&Sas->Guid, &gEfiSasDevicePathGuid); - Strtoi64 (AddressStr, &Sas->SasAddress); - Strtoi64 (LunStr, &Sas->Lun); - Sas->RelativeTargetPort = (UINT16) Strtoi (RTPStr); - - if (StrCmp (SASSATAStr, L"NoTopology") == 0) { - Info = 0x0; - - } else if ((StrCmp (SASSATAStr, L"SATA") == 0) || (StrCmp (SASSATAStr, L"SAS") == 0)) { - - Uint16 = (UINT16) Strtoi (DriveBayStr); - if (Uint16 == 0) { - Info = 0x1; - } else { - Info = (UINT16) (0x2 | ((Uint16 - 1) << 8)); - } - - if (StrCmp (SASSATAStr, L"SATA") == 0) { - Info |= BIT4; - } - - // - // Location is an integer between 0 and 1 or else - // the keyword Internal (0) or External (1). - // - if (StrCmp (LocationStr, L"External") == 0) { - Uint16 = 1; - } else if (StrCmp (LocationStr, L"Internal") == 0) { - Uint16 = 0; - } else { - Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0); - } - Info |= (Uint16 << 5); - - // - // Connect is an integer between 0 and 3 or else - // the keyword Direct (0) or Expanded (1). - // - if (StrCmp (ConnectStr, L"Expanded") == 0) { - Uint16 = 1; - } else if (StrCmp (ConnectStr, L"Direct") == 0) { - Uint16 = 0; - } else { - Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1)); - } - Info |= (Uint16 << 6); - - } else { - Info = (UINT16) Strtoi (SASSATAStr); - } - - Sas->DeviceTopology = Info; - Sas->Reserved = (UINT32) Strtoi (ReservedStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Sas; -} - -/** - Converts a text device path node to Serial Attached SCSI Ex device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Serial Attached SCSI Ex device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextSasEx ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *AddressStr; - CHAR16 *LunStr; - CHAR16 *RTPStr; - CHAR16 *SASSATAStr; - CHAR16 *LocationStr; - CHAR16 *ConnectStr; - CHAR16 *DriveBayStr; - UINT16 Info; - UINT16 Uint16; - UINT64 SasAddress; - UINT64 Lun; - SASEX_DEVICE_PATH *SasEx; - - AddressStr = GetNextParamStr (&TextDeviceNode); - LunStr = GetNextParamStr (&TextDeviceNode); - RTPStr = GetNextParamStr (&TextDeviceNode); - SASSATAStr = GetNextParamStr (&TextDeviceNode); - LocationStr = GetNextParamStr (&TextDeviceNode); - ConnectStr = GetNextParamStr (&TextDeviceNode); - DriveBayStr = GetNextParamStr (&TextDeviceNode); - SasEx = (SASEX_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_SASEX_DP, - (UINT16) sizeof (SASEX_DEVICE_PATH) - ); - - Strtoi64 (AddressStr, &SasAddress); - Strtoi64 (LunStr, &Lun); - WriteUnaligned64 ((UINT64 *) &SasEx->SasAddress, SwapBytes64 (SasAddress)); - WriteUnaligned64 ((UINT64 *) &SasEx->Lun, SwapBytes64 (Lun)); - SasEx->RelativeTargetPort = (UINT16) Strtoi (RTPStr); - - if (StrCmp (SASSATAStr, L"NoTopology") == 0) { - Info = 0x0; - - } else if ((StrCmp (SASSATAStr, L"SATA") == 0) || (StrCmp (SASSATAStr, L"SAS") == 0)) { - - Uint16 = (UINT16) Strtoi (DriveBayStr); - if (Uint16 == 0) { - Info = 0x1; - } else { - Info = (UINT16) (0x2 | ((Uint16 - 1) << 8)); - } - - if (StrCmp (SASSATAStr, L"SATA") == 0) { - Info |= BIT4; - } - - // - // Location is an integer between 0 and 1 or else - // the keyword Internal (0) or External (1). - // - if (StrCmp (LocationStr, L"External") == 0) { - Uint16 = 1; - } else if (StrCmp (LocationStr, L"Internal") == 0) { - Uint16 = 0; - } else { - Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0); - } - Info |= (Uint16 << 5); - - // - // Connect is an integer between 0 and 3 or else - // the keyword Direct (0) or Expanded (1). - // - if (StrCmp (ConnectStr, L"Expanded") == 0) { - Uint16 = 1; - } else if (StrCmp (ConnectStr, L"Direct") == 0) { - Uint16 = 0; - } else { - Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1)); - } - Info |= (Uint16 << 6); - - } else { - Info = (UINT16) Strtoi (SASSATAStr); - } - - SasEx->DeviceTopology = Info; - - return (EFI_DEVICE_PATH_PROTOCOL *) SasEx; -} - -/** - Converts a text device path node to NVM Express Namespace device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created NVM Express Namespace device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextNVMe ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *NamespaceIdStr; - CHAR16 *NamespaceUuidStr; - NVME_NAMESPACE_DEVICE_PATH *Nvme; - UINT8 *Uuid; - UINTN Index; - - NamespaceIdStr = GetNextParamStr (&TextDeviceNode); - NamespaceUuidStr = GetNextParamStr (&TextDeviceNode); - Nvme = (NVME_NAMESPACE_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_NVME_NAMESPACE_DP, - (UINT16) sizeof (NVME_NAMESPACE_DEVICE_PATH) - ); - - Nvme->NamespaceId = (UINT32) Strtoi (NamespaceIdStr); - Uuid = (UINT8 *) &Nvme->NamespaceUuid; - - Index = sizeof (Nvme->NamespaceUuid) / sizeof (UINT8); - while (Index-- != 0) { - Uuid[Index] = (UINT8) StrHexToUint64 (SplitStr (&NamespaceUuidStr, L'-')); - } - - return (EFI_DEVICE_PATH_PROTOCOL *) Nvme; -} - -/** - Converts a text device path node to UFS device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created UFS device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUfs ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *PunStr; - CHAR16 *LunStr; - UFS_DEVICE_PATH *Ufs; - - PunStr = GetNextParamStr (&TextDeviceNode); - LunStr = GetNextParamStr (&TextDeviceNode); - Ufs = (UFS_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_UFS_DP, - (UINT16) sizeof (UFS_DEVICE_PATH) - ); - - Ufs->Pun = (UINT8) Strtoi (PunStr); - Ufs->Lun = (UINT8) Strtoi (LunStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Ufs; -} - -/** - Converts a text device path node to SD (Secure Digital) device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created SD device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextSd ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *SlotNumberStr; - SD_DEVICE_PATH *Sd; - - SlotNumberStr = GetNextParamStr (&TextDeviceNode); - Sd = (SD_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_SD_DP, - (UINT16) sizeof (SD_DEVICE_PATH) - ); - - Sd->SlotNumber = (UINT8) Strtoi (SlotNumberStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Sd; -} - -/** - Converts a text device path node to EMMC (Embedded MMC) device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created EMMC device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextEmmc ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *SlotNumberStr; - EMMC_DEVICE_PATH *Emmc; - - SlotNumberStr = GetNextParamStr (&TextDeviceNode); - Emmc = (EMMC_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_EMMC_DP, - (UINT16) sizeof (EMMC_DEVICE_PATH) - ); - - Emmc->SlotNumber = (UINT8) Strtoi (SlotNumberStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Emmc; -} - -/** - Converts a text device path node to Debug Port device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Debug Port device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextDebugPort ( - CHAR16 *TextDeviceNode - ) -{ - VENDOR_DEVICE_PATH *Vend; - - Vend = (VENDOR_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_VENDOR_DP, - (UINT16) sizeof (VENDOR_DEVICE_PATH) - ); - - CopyGuid (&Vend->Guid, &gEfiDebugPortProtocolGuid); - - return (EFI_DEVICE_PATH_PROTOCOL *) Vend; -} - -/** - Converts a text device path node to MAC device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created MAC device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextMAC ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *AddressStr; - CHAR16 *IfTypeStr; - UINTN Length; - MAC_ADDR_DEVICE_PATH *MACDevPath; - - AddressStr = GetNextParamStr (&TextDeviceNode); - IfTypeStr = GetNextParamStr (&TextDeviceNode); - MACDevPath = (MAC_ADDR_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_MAC_ADDR_DP, - (UINT16) sizeof (MAC_ADDR_DEVICE_PATH) - ); - - MACDevPath->IfType = (UINT8) Strtoi (IfTypeStr); - - Length = sizeof (EFI_MAC_ADDRESS); - if (MACDevPath->IfType == 0x01 || MACDevPath->IfType == 0x00) { - Length = 6; - } - - StrHexToBytes (AddressStr, Length * 2, MACDevPath->MacAddress.Addr, Length); - - return (EFI_DEVICE_PATH_PROTOCOL *) MACDevPath; -} - - -/** - Converts a text format to the network protocol ID. - - @param Text String of protocol field. - - @return Network protocol ID . - -**/ -UINTN -NetworkProtocolFromText ( - CHAR16 *Text - ) -{ - if (StrCmp (Text, L"UDP") == 0) { - return RFC_1700_UDP_PROTOCOL; - } - - if (StrCmp (Text, L"TCP") == 0) { - return RFC_1700_TCP_PROTOCOL; - } - - return Strtoi (Text); -} - - -/** - Converts a text device path node to IPV4 device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created IPV4 device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextIPv4 ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *RemoteIPStr; - CHAR16 *ProtocolStr; - CHAR16 *TypeStr; - CHAR16 *LocalIPStr; - CHAR16 *GatewayIPStr; - CHAR16 *SubnetMaskStr; - IPv4_DEVICE_PATH *IPv4; - - RemoteIPStr = GetNextParamStr (&TextDeviceNode); - ProtocolStr = GetNextParamStr (&TextDeviceNode); - TypeStr = GetNextParamStr (&TextDeviceNode); - LocalIPStr = GetNextParamStr (&TextDeviceNode); - GatewayIPStr = GetNextParamStr (&TextDeviceNode); - SubnetMaskStr = GetNextParamStr (&TextDeviceNode); - IPv4 = (IPv4_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_IPv4_DP, - (UINT16) sizeof (IPv4_DEVICE_PATH) - ); - - StrToIpv4Address (RemoteIPStr, NULL, &IPv4->RemoteIpAddress, NULL); - IPv4->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr); - if (StrCmp (TypeStr, L"Static") == 0) { - IPv4->StaticIpAddress = TRUE; - } else { - IPv4->StaticIpAddress = FALSE; - } - - StrToIpv4Address (LocalIPStr, NULL, &IPv4->LocalIpAddress, NULL); - if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) { - StrToIpv4Address (GatewayIPStr, NULL, &IPv4->GatewayIpAddress, NULL); - StrToIpv4Address (SubnetMaskStr, NULL, &IPv4->SubnetMask, NULL); - } else { - ZeroMem (&IPv4->GatewayIpAddress, sizeof (IPv4->GatewayIpAddress)); - ZeroMem (&IPv4->SubnetMask, sizeof (IPv4->SubnetMask)); - } - - IPv4->LocalPort = 0; - IPv4->RemotePort = 0; - - return (EFI_DEVICE_PATH_PROTOCOL *) IPv4; -} - -/** - Converts a text device path node to IPV6 device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created IPV6 device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextIPv6 ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *RemoteIPStr; - CHAR16 *ProtocolStr; - CHAR16 *TypeStr; - CHAR16 *LocalIPStr; - CHAR16 *GatewayIPStr; - CHAR16 *PrefixLengthStr; - IPv6_DEVICE_PATH *IPv6; - - RemoteIPStr = GetNextParamStr (&TextDeviceNode); - ProtocolStr = GetNextParamStr (&TextDeviceNode); - TypeStr = GetNextParamStr (&TextDeviceNode); - LocalIPStr = GetNextParamStr (&TextDeviceNode); - PrefixLengthStr = GetNextParamStr (&TextDeviceNode); - GatewayIPStr = GetNextParamStr (&TextDeviceNode); - IPv6 = (IPv6_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_IPv6_DP, - (UINT16) sizeof (IPv6_DEVICE_PATH) - ); - - StrToIpv6Address (RemoteIPStr, NULL, &IPv6->RemoteIpAddress, NULL); - IPv6->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr); - if (StrCmp (TypeStr, L"Static") == 0) { - IPv6->IpAddressOrigin = 0; - } else if (StrCmp (TypeStr, L"StatelessAutoConfigure") == 0) { - IPv6->IpAddressOrigin = 1; - } else { - IPv6->IpAddressOrigin = 2; - } - - StrToIpv6Address (LocalIPStr, NULL, &IPv6->LocalIpAddress, NULL); - if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) { - StrToIpv6Address (GatewayIPStr, NULL, &IPv6->GatewayIpAddress, NULL); - IPv6->PrefixLength = (UINT8) Strtoi (PrefixLengthStr); - } else { - ZeroMem (&IPv6->GatewayIpAddress, sizeof (IPv6->GatewayIpAddress)); - IPv6->PrefixLength = 0; - } - - IPv6->LocalPort = 0; - IPv6->RemotePort = 0; - - return (EFI_DEVICE_PATH_PROTOCOL *) IPv6; -} - -/** - Converts a text device path node to UART device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created UART device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUart ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *BaudStr; - CHAR16 *DataBitsStr; - CHAR16 *ParityStr; - CHAR16 *StopBitsStr; - UART_DEVICE_PATH *Uart; - - BaudStr = GetNextParamStr (&TextDeviceNode); - DataBitsStr = GetNextParamStr (&TextDeviceNode); - ParityStr = GetNextParamStr (&TextDeviceNode); - StopBitsStr = GetNextParamStr (&TextDeviceNode); - Uart = (UART_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_UART_DP, - (UINT16) sizeof (UART_DEVICE_PATH) - ); - - if (StrCmp (BaudStr, L"DEFAULT") == 0) { - Uart->BaudRate = 115200; - } else { - Strtoi64 (BaudStr, &Uart->BaudRate); - } - Uart->DataBits = (UINT8) ((StrCmp (DataBitsStr, L"DEFAULT") == 0) ? 8 : Strtoi (DataBitsStr)); - switch (*ParityStr) { - case L'D': - Uart->Parity = 0; - break; - - case L'N': - Uart->Parity = 1; - break; - - case L'E': - Uart->Parity = 2; - break; - - case L'O': - Uart->Parity = 3; - break; - - case L'M': - Uart->Parity = 4; - break; - - case L'S': - Uart->Parity = 5; - break; - - default: - Uart->Parity = (UINT8) Strtoi (ParityStr); - break; - } - - if (StrCmp (StopBitsStr, L"D") == 0) { - Uart->StopBits = (UINT8) 0; - } else if (StrCmp (StopBitsStr, L"1") == 0) { - Uart->StopBits = (UINT8) 1; - } else if (StrCmp (StopBitsStr, L"1.5") == 0) { - Uart->StopBits = (UINT8) 2; - } else if (StrCmp (StopBitsStr, L"2") == 0) { - Uart->StopBits = (UINT8) 3; - } else { - Uart->StopBits = (UINT8) Strtoi (StopBitsStr); - } - - return (EFI_DEVICE_PATH_PROTOCOL *) Uart; -} - -/** - Converts a text device path node to USB class device path structure. - - @param TextDeviceNode The input Text device path node. - @param UsbClassText A pointer to USB_CLASS_TEXT structure to be integrated to USB Class Text. - - @return A pointer to the newly-created USB class device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -ConvertFromTextUsbClass ( - CHAR16 *TextDeviceNode, - USB_CLASS_TEXT *UsbClassText - ) -{ - CHAR16 *VIDStr; - CHAR16 *PIDStr; - CHAR16 *ClassStr; - CHAR16 *SubClassStr; - CHAR16 *ProtocolStr; - USB_CLASS_DEVICE_PATH *UsbClass; - - UsbClass = (USB_CLASS_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_USB_CLASS_DP, - (UINT16) sizeof (USB_CLASS_DEVICE_PATH) - ); - - VIDStr = GetNextParamStr (&TextDeviceNode); - PIDStr = GetNextParamStr (&TextDeviceNode); - if (UsbClassText->ClassExist) { - ClassStr = GetNextParamStr (&TextDeviceNode); - if (*ClassStr == L'\0') { - UsbClass->DeviceClass = 0xFF; - } else { - UsbClass->DeviceClass = (UINT8) Strtoi (ClassStr); - } - } else { - UsbClass->DeviceClass = UsbClassText->Class; - } - if (UsbClassText->SubClassExist) { - SubClassStr = GetNextParamStr (&TextDeviceNode); - if (*SubClassStr == L'\0') { - UsbClass->DeviceSubClass = 0xFF; - } else { - UsbClass->DeviceSubClass = (UINT8) Strtoi (SubClassStr); - } - } else { - UsbClass->DeviceSubClass = UsbClassText->SubClass; - } - - ProtocolStr = GetNextParamStr (&TextDeviceNode); - - if (*VIDStr == L'\0') { - UsbClass->VendorId = 0xFFFF; - } else { - UsbClass->VendorId = (UINT16) Strtoi (VIDStr); - } - if (*PIDStr == L'\0') { - UsbClass->ProductId = 0xFFFF; - } else { - UsbClass->ProductId = (UINT16) Strtoi (PIDStr); - } - if (*ProtocolStr == L'\0') { - UsbClass->DeviceProtocol = 0xFF; - } else { - UsbClass->DeviceProtocol = (UINT8) Strtoi (ProtocolStr); - } - - return (EFI_DEVICE_PATH_PROTOCOL *) UsbClass; -} - - -/** - Converts a text device path node to USB class device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB class device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbClass ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = TRUE; - UsbClassText.SubClassExist = TRUE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB audio device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB audio device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbAudio ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_AUDIO; - UsbClassText.SubClassExist = TRUE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB CDC Control device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB CDC Control device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbCDCControl ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_CDCCONTROL; - UsbClassText.SubClassExist = TRUE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB HID device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB HID device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbHID ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_HID; - UsbClassText.SubClassExist = TRUE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB Image device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB Image device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbImage ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_IMAGE; - UsbClassText.SubClassExist = TRUE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB Print device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB Print device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbPrinter ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_PRINTER; - UsbClassText.SubClassExist = TRUE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB mass storage device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB mass storage device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbMassStorage ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_MASS_STORAGE; - UsbClassText.SubClassExist = TRUE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB HUB device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB HUB device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbHub ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_HUB; - UsbClassText.SubClassExist = TRUE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB CDC data device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB CDC data device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbCDCData ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_CDCDATA; - UsbClassText.SubClassExist = TRUE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB smart card device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB smart card device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbSmartCard ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_SMART_CARD; - UsbClassText.SubClassExist = TRUE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB video device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB video device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbVideo ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_VIDEO; - UsbClassText.SubClassExist = TRUE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB diagnostic device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB diagnostic device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbDiagnostic ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_DIAGNOSTIC; - UsbClassText.SubClassExist = TRUE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB wireless device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB wireless device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbWireless ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_WIRELESS; - UsbClassText.SubClassExist = TRUE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB device firmware update device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB device firmware update device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbDeviceFirmwareUpdate ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_RESERVE; - UsbClassText.SubClassExist = FALSE; - UsbClassText.SubClass = USB_SUBCLASS_FW_UPDATE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB IRDA bridge device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB IRDA bridge device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbIrdaBridge ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_RESERVE; - UsbClassText.SubClassExist = FALSE; - UsbClassText.SubClass = USB_SUBCLASS_IRDA_BRIDGE; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB text and measurement device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB text and measurement device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbTestAndMeasurement ( - CHAR16 *TextDeviceNode - ) -{ - USB_CLASS_TEXT UsbClassText; - - UsbClassText.ClassExist = FALSE; - UsbClassText.Class = USB_CLASS_RESERVE; - UsbClassText.SubClassExist = FALSE; - UsbClassText.SubClass = USB_SUBCLASS_TEST; - - return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText); -} - -/** - Converts a text device path node to USB WWID device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created USB WWID device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUsbWwid ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *VIDStr; - CHAR16 *PIDStr; - CHAR16 *InterfaceNumStr; - CHAR16 *SerialNumberStr; - USB_WWID_DEVICE_PATH *UsbWwid; - UINTN SerialNumberStrLen; - - VIDStr = GetNextParamStr (&TextDeviceNode); - PIDStr = GetNextParamStr (&TextDeviceNode); - InterfaceNumStr = GetNextParamStr (&TextDeviceNode); - SerialNumberStr = GetNextParamStr (&TextDeviceNode); - SerialNumberStrLen = StrLen (SerialNumberStr); - if (SerialNumberStrLen >= 2 && - SerialNumberStr[0] == L'\"' && - SerialNumberStr[SerialNumberStrLen - 1] == L'\"' - ) { - SerialNumberStr[SerialNumberStrLen - 1] = L'\0'; - SerialNumberStr++; - SerialNumberStrLen -= 2; - } - UsbWwid = (USB_WWID_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_USB_WWID_DP, - (UINT16) (sizeof (USB_WWID_DEVICE_PATH) + SerialNumberStrLen * sizeof (CHAR16)) - ); - UsbWwid->VendorId = (UINT16) Strtoi (VIDStr); - UsbWwid->ProductId = (UINT16) Strtoi (PIDStr); - UsbWwid->InterfaceNumber = (UINT16) Strtoi (InterfaceNumStr); - - // - // There is no memory allocated in UsbWwid for the '\0' in SerialNumberStr. - // Therefore, the '\0' will not be copied. - // - memcpy ( - (UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH), - SerialNumberStr, - SerialNumberStrLen * sizeof (CHAR16) - ); - - return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid; -} - -/** - Converts a text device path node to Logic Unit device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Logic Unit device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUnit ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *LunStr; - DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit; - - LunStr = GetNextParamStr (&TextDeviceNode); - LogicalUnit = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_DEVICE_LOGICAL_UNIT_DP, - (UINT16) sizeof (DEVICE_LOGICAL_UNIT_DEVICE_PATH) - ); - - LogicalUnit->Lun = (UINT8) Strtoi (LunStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) LogicalUnit; -} - -/** - Converts a text device path node to iSCSI device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created iSCSI device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextiSCSI ( - CHAR16 *TextDeviceNode - ) -{ - UINT16 Options; - CHAR16 *NameStr; - CHAR16 *PortalGroupStr; - CHAR16 *LunStr; - CHAR16 *HeaderDigestStr; - CHAR16 *DataDigestStr; - CHAR16 *AuthenticationStr; - CHAR16 *ProtocolStr; - CHAR8 *AsciiStr; - ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath; - UINT64 Lun; - - NameStr = GetNextParamStr (&TextDeviceNode); - PortalGroupStr = GetNextParamStr (&TextDeviceNode); - LunStr = GetNextParamStr (&TextDeviceNode); - HeaderDigestStr = GetNextParamStr (&TextDeviceNode); - DataDigestStr = GetNextParamStr (&TextDeviceNode); - AuthenticationStr = GetNextParamStr (&TextDeviceNode); - ProtocolStr = GetNextParamStr (&TextDeviceNode); - ISCSIDevPath = (ISCSI_DEVICE_PATH_WITH_NAME *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_ISCSI_DP, - (UINT16) (sizeof (ISCSI_DEVICE_PATH_WITH_NAME) + StrLen (NameStr)) - ); - - AsciiStr = ISCSIDevPath->TargetName; - StrToAscii (NameStr, &AsciiStr); - - ISCSIDevPath->TargetPortalGroupTag = (UINT16) Strtoi (PortalGroupStr); - Strtoi64 (LunStr, &Lun); - WriteUnaligned64 ((UINT64 *) &ISCSIDevPath->Lun, SwapBytes64 (Lun)); - - Options = 0x0000; - if (StrCmp (HeaderDigestStr, L"CRC32C") == 0) { - Options |= 0x0002; - } - - if (StrCmp (DataDigestStr, L"CRC32C") == 0) { - Options |= 0x0008; - } - - if (StrCmp (AuthenticationStr, L"None") == 0) { - Options |= 0x0800; - } - - if (StrCmp (AuthenticationStr, L"CHAP_UNI") == 0) { - Options |= 0x1000; - } - - ISCSIDevPath->LoginOption = (UINT16) Options; - - if (IS_NULL (*ProtocolStr) || (StrCmp (ProtocolStr, L"TCP") == 0)) { - ISCSIDevPath->NetworkProtocol = 0; - } else { - // - // Undefined and reserved. - // - ISCSIDevPath->NetworkProtocol = 1; - } - - return (EFI_DEVICE_PATH_PROTOCOL *) ISCSIDevPath; -} - -/** - Converts a text device path node to VLAN device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created VLAN device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextVlan ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *VlanStr; - VLAN_DEVICE_PATH *Vlan; - - VlanStr = GetNextParamStr (&TextDeviceNode); - Vlan = (VLAN_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_VLAN_DP, - (UINT16) sizeof (VLAN_DEVICE_PATH) - ); - - Vlan->VlanId = (UINT16) Strtoi (VlanStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Vlan; -} - -/** - Converts a text device path node to Bluetooth device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Bluetooth device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextBluetooth ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *BluetoothStr; - BLUETOOTH_DEVICE_PATH *BluetoothDp; - - BluetoothStr = GetNextParamStr (&TextDeviceNode); - BluetoothDp = (BLUETOOTH_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_BLUETOOTH_DP, - (UINT16) sizeof (BLUETOOTH_DEVICE_PATH) - ); - StrHexToBytes ( - BluetoothStr, - sizeof (BLUETOOTH_ADDRESS) * 2, - BluetoothDp->BD_ADDR.Address, - sizeof (BLUETOOTH_ADDRESS) - ); - return (EFI_DEVICE_PATH_PROTOCOL *) BluetoothDp; -} - -/** - Converts a text device path node to Wi-Fi device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Wi-Fi device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextWiFi ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *SSIdStr; - CHAR8 AsciiStr[33]; - UINTN DataLen; - WIFI_DEVICE_PATH *WiFiDp; - - SSIdStr = GetNextParamStr (&TextDeviceNode); - WiFiDp = (WIFI_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_WIFI_DP, - (UINT16) sizeof (WIFI_DEVICE_PATH) - ); - - if (NULL != SSIdStr) { - DataLen = StrLen (SSIdStr); - if (StrLen (SSIdStr) > 32) { - SSIdStr[32] = L'\0'; - DataLen = 32; - } - - UnicodeStrToAsciiStrS (SSIdStr, AsciiStr, sizeof (AsciiStr)); - memcpy (WiFiDp->SSId, AsciiStr, DataLen); - } - - return (EFI_DEVICE_PATH_PROTOCOL *) WiFiDp; -} - -/** - Converts a text device path node to Bluetooth LE device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Bluetooth LE device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextBluetoothLE ( - IN CHAR16 *TextDeviceNode - ) -{ - CHAR16 *BluetoothLeAddrStr; - CHAR16 *BluetoothLeAddrTypeStr; - BLUETOOTH_LE_DEVICE_PATH *BluetoothLeDp; - - BluetoothLeAddrStr = GetNextParamStr (&TextDeviceNode); - BluetoothLeAddrTypeStr = GetNextParamStr (&TextDeviceNode); - BluetoothLeDp = (BLUETOOTH_LE_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_BLUETOOTH_LE_DP, - (UINT16) sizeof (BLUETOOTH_LE_DEVICE_PATH) - ); - - BluetoothLeDp->Address.Type = (UINT8) Strtoi (BluetoothLeAddrTypeStr); - StrHexToBytes ( - BluetoothLeAddrStr, sizeof (BluetoothLeDp->Address.Address) * 2, - BluetoothLeDp->Address.Address, sizeof (BluetoothLeDp->Address.Address) - ); - return (EFI_DEVICE_PATH_PROTOCOL *) BluetoothLeDp; -} - -/** - Converts a text device path node to DNS device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created DNS device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextDns ( - IN CHAR16 *TextDeviceNode - ) -{ - CHAR16 *DeviceNodeStr; - CHAR16 *DeviceNodeStrPtr; - UINT32 DnsServerIpCount; - UINT16 DnsDeviceNodeLength; - DNS_DEVICE_PATH *DnsDeviceNode; - UINT32 DnsServerIpIndex; - CHAR16 *DnsServerIp; - - - // - // Count the DNS server address number. - // - DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode); - if (DeviceNodeStr == NULL) { - return NULL; - } - - DeviceNodeStrPtr = DeviceNodeStr; - - DnsServerIpCount = 0; - while (DeviceNodeStrPtr != NULL && *DeviceNodeStrPtr != L'\0') { - GetNextParamStr (&DeviceNodeStrPtr); - DnsServerIpCount ++; - } - - free (DeviceNodeStr); - DeviceNodeStr = NULL; - - // - // One or more instances of the DNS server address in EFI_IP_ADDRESS, - // otherwise, NULL will be returned. - // - if (DnsServerIpCount == 0) { - return NULL; - } - - // - // Create the DNS DeviceNode. - // - DnsDeviceNodeLength = (UINT16) (sizeof (EFI_DEVICE_PATH_PROTOCOL) + sizeof (UINT8) + DnsServerIpCount * sizeof (EFI_IP_ADDRESS)); - DnsDeviceNode = (DNS_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_DNS_DP, - DnsDeviceNodeLength - ); - if (DnsDeviceNode == NULL) { - return NULL; - } - - // - // Confirm the DNS server address is IPv4 or IPv6 type. - // - DeviceNodeStrPtr = TextDeviceNode; - while (!IS_NULL (*DeviceNodeStrPtr)) { - if (*DeviceNodeStrPtr == L'.') { - DnsDeviceNode->IsIPv6 = 0x00; - break; - } - - if (*DeviceNodeStrPtr == L':') { - DnsDeviceNode->IsIPv6 = 0x01; - break; - } - - DeviceNodeStrPtr++; - } - - for (DnsServerIpIndex = 0; DnsServerIpIndex < DnsServerIpCount; DnsServerIpIndex++) { - DnsServerIp = GetNextParamStr (&TextDeviceNode); - if (DnsDeviceNode->IsIPv6 == 0x00) { - StrToIpv4Address (DnsServerIp, NULL, &(DnsDeviceNode->DnsServerIp[DnsServerIpIndex].v4), NULL); - } else { - StrToIpv6Address (DnsServerIp, NULL, &(DnsDeviceNode->DnsServerIp[DnsServerIpIndex].v6), NULL); - } - } - - return (EFI_DEVICE_PATH_PROTOCOL *) DnsDeviceNode; -} - -/** - Converts a text device path node to URI device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created URI device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextUri ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *UriStr; - UINTN UriLength; - URI_DEVICE_PATH *Uri; - - UriStr = GetNextParamStr (&TextDeviceNode); - UriLength = StrnLenS (UriStr, MAX_UINT16 - sizeof (URI_DEVICE_PATH)); - Uri = (URI_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_URI_DP, - (UINT16) (sizeof (URI_DEVICE_PATH) + UriLength) - ); - - while (UriLength-- != 0) { - Uri->Uri[UriLength] = (CHAR8) UriStr[UriLength]; - } - - return (EFI_DEVICE_PATH_PROTOCOL *) Uri; -} - -/** - Converts a media text device path node to media device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to media device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextMediaPath ( - CHAR16 *TextDeviceNode - ) -{ - return DevPathFromTextGenericPath (MEDIA_DEVICE_PATH, TextDeviceNode); -} - -/** - Converts a text device path node to HD device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created HD device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextHD ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *PartitionStr; - CHAR16 *TypeStr; - CHAR16 *SignatureStr; - CHAR16 *StartStr; - CHAR16 *SizeStr; - UINT32 Signature32; - HARDDRIVE_DEVICE_PATH *Hd; - - PartitionStr = GetNextParamStr (&TextDeviceNode); - TypeStr = GetNextParamStr (&TextDeviceNode); - SignatureStr = GetNextParamStr (&TextDeviceNode); - StartStr = GetNextParamStr (&TextDeviceNode); - SizeStr = GetNextParamStr (&TextDeviceNode); - Hd = (HARDDRIVE_DEVICE_PATH *) CreateDeviceNode ( - MEDIA_DEVICE_PATH, - MEDIA_HARDDRIVE_DP, - (UINT16) sizeof (HARDDRIVE_DEVICE_PATH) - ); - - Hd->PartitionNumber = (UINT32) Strtoi (PartitionStr); - - ZeroMem (Hd->Signature, 16); - Hd->MBRType = (UINT8) 0; - - if (StrCmp (TypeStr, L"MBR") == 0) { - Hd->SignatureType = SIGNATURE_TYPE_MBR; - Hd->MBRType = 0x01; - - Signature32 = (UINT32) Strtoi (SignatureStr); - memcpy (Hd->Signature, &Signature32, sizeof (UINT32)); - } else if (StrCmp (TypeStr, L"GPT") == 0) { - Hd->SignatureType = SIGNATURE_TYPE_GUID; - Hd->MBRType = 0x02; - - StrToGuid (SignatureStr, (EFI_GUID *) Hd->Signature); - } else { - Hd->SignatureType = (UINT8) Strtoi (TypeStr); - } - - Strtoi64 (StartStr, &Hd->PartitionStart); - Strtoi64 (SizeStr, &Hd->PartitionSize); - - return (EFI_DEVICE_PATH_PROTOCOL *) Hd; -} - -/** - Converts a text device path node to CDROM device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created CDROM device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextCDROM ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *EntryStr; - CHAR16 *StartStr; - CHAR16 *SizeStr; - CDROM_DEVICE_PATH *CDROMDevPath; - - EntryStr = GetNextParamStr (&TextDeviceNode); - StartStr = GetNextParamStr (&TextDeviceNode); - SizeStr = GetNextParamStr (&TextDeviceNode); - CDROMDevPath = (CDROM_DEVICE_PATH *) CreateDeviceNode ( - MEDIA_DEVICE_PATH, - MEDIA_CDROM_DP, - (UINT16) sizeof (CDROM_DEVICE_PATH) - ); - - CDROMDevPath->BootEntry = (UINT32) Strtoi (EntryStr); - Strtoi64 (StartStr, &CDROMDevPath->PartitionStart); - Strtoi64 (SizeStr, &CDROMDevPath->PartitionSize); - - return (EFI_DEVICE_PATH_PROTOCOL *) CDROMDevPath; -} - -/** - Converts a text device path node to Vendor-defined media device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Vendor-defined media device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextVenMedia ( - CHAR16 *TextDeviceNode - ) -{ - return ConvertFromTextVendor ( - TextDeviceNode, - MEDIA_DEVICE_PATH, - MEDIA_VENDOR_DP - ); -} - -/** - Converts a text device path node to File device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created File device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextFilePath ( - CHAR16 *TextDeviceNode - ) -{ - FILEPATH_DEVICE_PATH *File; - - File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode ( - MEDIA_DEVICE_PATH, - MEDIA_FILEPATH_DP, - (UINT16) (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2) - ); - - StrCpyS (File->PathName, StrLen (TextDeviceNode) + 1, TextDeviceNode); - - return (EFI_DEVICE_PATH_PROTOCOL *) File; -} - -/** - Converts a text device path node to Media protocol device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Media protocol device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextMedia ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *GuidStr; - MEDIA_PROTOCOL_DEVICE_PATH *Media; - - GuidStr = GetNextParamStr (&TextDeviceNode); - Media = (MEDIA_PROTOCOL_DEVICE_PATH *) CreateDeviceNode ( - MEDIA_DEVICE_PATH, - MEDIA_PROTOCOL_DP, - (UINT16) sizeof (MEDIA_PROTOCOL_DEVICE_PATH) - ); - - StrToGuid (GuidStr, &Media->Protocol); - - return (EFI_DEVICE_PATH_PROTOCOL *) Media; -} - -/** - Converts a text device path node to firmware volume device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created firmware volume device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextFv ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *GuidStr; - MEDIA_FW_VOL_DEVICE_PATH *Fv; - - GuidStr = GetNextParamStr (&TextDeviceNode); - Fv = (MEDIA_FW_VOL_DEVICE_PATH *) CreateDeviceNode ( - MEDIA_DEVICE_PATH, - MEDIA_PIWG_FW_VOL_DP, - (UINT16) sizeof (MEDIA_FW_VOL_DEVICE_PATH) - ); - - StrToGuid (GuidStr, &Fv->FvName); - - return (EFI_DEVICE_PATH_PROTOCOL *) Fv; -} - -/** - Converts a text device path node to firmware file device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created firmware file device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextFvFile ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *GuidStr; - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFile; - - GuidStr = GetNextParamStr (&TextDeviceNode); - FvFile = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) CreateDeviceNode ( - MEDIA_DEVICE_PATH, - MEDIA_PIWG_FW_FILE_DP, - (UINT16) sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) - ); - - StrToGuid (GuidStr, &FvFile->FvFileName); - - return (EFI_DEVICE_PATH_PROTOCOL *) FvFile; -} - -/** - Converts a text device path node to text relative offset device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Text device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextRelativeOffsetRange ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *StartingOffsetStr; - CHAR16 *EndingOffsetStr; - MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset; - - StartingOffsetStr = GetNextParamStr (&TextDeviceNode); - EndingOffsetStr = GetNextParamStr (&TextDeviceNode); - Offset = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) CreateDeviceNode ( - MEDIA_DEVICE_PATH, - MEDIA_RELATIVE_OFFSET_RANGE_DP, - (UINT16) sizeof (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH) - ); - - Strtoi64 (StartingOffsetStr, &Offset->StartingOffset); - Strtoi64 (EndingOffsetStr, &Offset->EndingOffset); - - return (EFI_DEVICE_PATH_PROTOCOL *) Offset; -} - -/** - Converts a text device path node to text ram disk device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Text device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextRamDisk ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *StartingAddrStr; - CHAR16 *EndingAddrStr; - CHAR16 *TypeGuidStr; - CHAR16 *InstanceStr; - MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; - UINT64 StartingAddr; - UINT64 EndingAddr; - - StartingAddrStr = GetNextParamStr (&TextDeviceNode); - EndingAddrStr = GetNextParamStr (&TextDeviceNode); - InstanceStr = GetNextParamStr (&TextDeviceNode); - TypeGuidStr = GetNextParamStr (&TextDeviceNode); - RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( - MEDIA_DEVICE_PATH, - MEDIA_RAM_DISK_DP, - (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH) - ); - - Strtoi64 (StartingAddrStr, &StartingAddr); - WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); - Strtoi64 (EndingAddrStr, &EndingAddr); - WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); - RamDisk->Instance = (UINT16) Strtoi (InstanceStr); - StrToGuid (TypeGuidStr, &RamDisk->TypeGuid); - - return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; -} - -/** - Converts a text device path node to text virtual disk device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Text device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextVirtualDisk ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *StartingAddrStr; - CHAR16 *EndingAddrStr; - CHAR16 *InstanceStr; - MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; - UINT64 StartingAddr; - UINT64 EndingAddr; - - StartingAddrStr = GetNextParamStr (&TextDeviceNode); - EndingAddrStr = GetNextParamStr (&TextDeviceNode); - InstanceStr = GetNextParamStr (&TextDeviceNode); - - RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( - MEDIA_DEVICE_PATH, - MEDIA_RAM_DISK_DP, - (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH) - ); - - Strtoi64 (StartingAddrStr, &StartingAddr); - WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); - Strtoi64 (EndingAddrStr, &EndingAddr); - WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); - RamDisk->Instance = (UINT16) Strtoi (InstanceStr); - CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid); - - return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; -} - -/** - Converts a text device path node to text virtual cd device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Text device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextVirtualCd ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *StartingAddrStr; - CHAR16 *EndingAddrStr; - CHAR16 *InstanceStr; - MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; - UINT64 StartingAddr; - UINT64 EndingAddr; - - StartingAddrStr = GetNextParamStr (&TextDeviceNode); - EndingAddrStr = GetNextParamStr (&TextDeviceNode); - InstanceStr = GetNextParamStr (&TextDeviceNode); - - RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( - MEDIA_DEVICE_PATH, - MEDIA_RAM_DISK_DP, - (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH) - ); - - Strtoi64 (StartingAddrStr, &StartingAddr); - WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); - Strtoi64 (EndingAddrStr, &EndingAddr); - WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); - RamDisk->Instance = (UINT16) Strtoi (InstanceStr); - CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid); - - return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; -} - -/** - Converts a text device path node to text persistent virtual disk device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Text device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextPersistentVirtualDisk ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *StartingAddrStr; - CHAR16 *EndingAddrStr; - CHAR16 *InstanceStr; - MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; - UINT64 StartingAddr; - UINT64 EndingAddr; - - StartingAddrStr = GetNextParamStr (&TextDeviceNode); - EndingAddrStr = GetNextParamStr (&TextDeviceNode); - InstanceStr = GetNextParamStr (&TextDeviceNode); - - RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( - MEDIA_DEVICE_PATH, - MEDIA_RAM_DISK_DP, - (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH) - ); - - Strtoi64 (StartingAddrStr, &StartingAddr); - WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); - Strtoi64 (EndingAddrStr, &EndingAddr); - WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); - RamDisk->Instance = (UINT16) Strtoi (InstanceStr); - CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid); - - return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; -} - -/** - Converts a text device path node to text persistent virtual cd device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created Text device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextPersistentVirtualCd ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *StartingAddrStr; - CHAR16 *EndingAddrStr; - CHAR16 *InstanceStr; - MEDIA_RAM_DISK_DEVICE_PATH *RamDisk; - UINT64 StartingAddr; - UINT64 EndingAddr; - - StartingAddrStr = GetNextParamStr (&TextDeviceNode); - EndingAddrStr = GetNextParamStr (&TextDeviceNode); - InstanceStr = GetNextParamStr (&TextDeviceNode); - - RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode ( - MEDIA_DEVICE_PATH, - MEDIA_RAM_DISK_DP, - (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH) - ); - - Strtoi64 (StartingAddrStr, &StartingAddr); - WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr); - Strtoi64 (EndingAddrStr, &EndingAddr); - WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr); - RamDisk->Instance = (UINT16) Strtoi (InstanceStr); - CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid); - - return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk; -} - -/** - Converts a BBS text device path node to BBS device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to BBS device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextBbsPath ( - CHAR16 *TextDeviceNode - ) -{ - return DevPathFromTextGenericPath (BBS_DEVICE_PATH, TextDeviceNode); -} - -/** - Converts a text device path node to BIOS Boot Specification device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created BIOS Boot Specification device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextBBS ( - CHAR16 *TextDeviceNode - ) -{ - CHAR16 *TypeStr; - CHAR16 *IdStr; - CHAR16 *FlagsStr; - CHAR8 *AsciiStr; - BBS_BBS_DEVICE_PATH *Bbs; - - TypeStr = GetNextParamStr (&TextDeviceNode); - IdStr = GetNextParamStr (&TextDeviceNode); - FlagsStr = GetNextParamStr (&TextDeviceNode); - Bbs = (BBS_BBS_DEVICE_PATH *) CreateDeviceNode ( - BBS_DEVICE_PATH, - BBS_BBS_DP, - (UINT16) (sizeof (BBS_BBS_DEVICE_PATH) + StrLen (IdStr)) - ); - - if (StrCmp (TypeStr, L"Floppy") == 0) { - Bbs->DeviceType = BBS_TYPE_FLOPPY; - } else if (StrCmp (TypeStr, L"HD") == 0) { - Bbs->DeviceType = BBS_TYPE_HARDDRIVE; - } else if (StrCmp (TypeStr, L"CDROM") == 0) { - Bbs->DeviceType = BBS_TYPE_CDROM; - } else if (StrCmp (TypeStr, L"PCMCIA") == 0) { - Bbs->DeviceType = BBS_TYPE_PCMCIA; - } else if (StrCmp (TypeStr, L"USB") == 0) { - Bbs->DeviceType = BBS_TYPE_USB; - } else if (StrCmp (TypeStr, L"Network") == 0) { - Bbs->DeviceType = BBS_TYPE_EMBEDDED_NETWORK; - } else { - Bbs->DeviceType = (UINT16) Strtoi (TypeStr); - } - - AsciiStr = Bbs->String; - StrToAscii (IdStr, &AsciiStr); - - Bbs->StatusFlag = (UINT16) Strtoi (FlagsStr); - - return (EFI_DEVICE_PATH_PROTOCOL *) Bbs; -} - -/** - Converts a text device path node to SATA device path structure. - - @param TextDeviceNode The input Text device path node. - - @return A pointer to the newly-created SATA device path structure. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DevPathFromTextSata ( - CHAR16 *TextDeviceNode - ) -{ - SATA_DEVICE_PATH *Sata; - CHAR16 *Param1; - CHAR16 *Param2; - CHAR16 *Param3; - - Param1 = GetNextParamStr (&TextDeviceNode); - Param2 = GetNextParamStr (&TextDeviceNode); - Param3 = GetNextParamStr (&TextDeviceNode); - - Sata = (SATA_DEVICE_PATH *) CreateDeviceNode ( - MESSAGING_DEVICE_PATH, - MSG_SATA_DP, - (UINT16) sizeof (SATA_DEVICE_PATH) - ); - Sata->HBAPortNumber = (UINT16) Strtoi (Param1); - - // - // According to UEFI spec, if PMPN is not provided, the default is 0xFFFF - // - if (*Param2 == L'\0' ) { - Sata->PortMultiplierPortNumber = 0xFFFF; - } else { - Sata->PortMultiplierPortNumber = (UINT16) Strtoi (Param2); - } - Sata->Lun = (UINT16) Strtoi (Param3); - - return (EFI_DEVICE_PATH_PROTOCOL *) Sata; -} - -DEVICE_PATH_FROM_TEXT_TABLE mUefiDevicePathLibDevPathFromTextTable[] = { - {L"Path", DevPathFromTextPath }, - - {L"HardwarePath", DevPathFromTextHardwarePath }, - {L"Pci", DevPathFromTextPci }, - {L"PcCard", DevPathFromTextPcCard }, - {L"MemoryMapped", DevPathFromTextMemoryMapped }, - {L"VenHw", DevPathFromTextVenHw }, - {L"Ctrl", DevPathFromTextCtrl }, - {L"BMC", DevPathFromTextBmc }, - - {L"AcpiPath", DevPathFromTextAcpiPath }, - {L"Acpi", DevPathFromTextAcpi }, - {L"PciRoot", DevPathFromTextPciRoot }, - {L"PcieRoot", DevPathFromTextPcieRoot }, - {L"Floppy", DevPathFromTextFloppy }, - {L"Keyboard", DevPathFromTextKeyboard }, - {L"Serial", DevPathFromTextSerial }, - {L"ParallelPort", DevPathFromTextParallelPort }, - {L"AcpiEx", DevPathFromTextAcpiEx }, - {L"AcpiExp", DevPathFromTextAcpiExp }, - {L"AcpiAdr", DevPathFromTextAcpiAdr }, - - {L"Msg", DevPathFromTextMsg }, - {L"Ata", DevPathFromTextAta }, - {L"Scsi", DevPathFromTextScsi }, - {L"Fibre", DevPathFromTextFibre }, - {L"FibreEx", DevPathFromTextFibreEx }, - {L"I1394", DevPathFromText1394 }, - {L"USB", DevPathFromTextUsb }, - {L"I2O", DevPathFromTextI2O }, - {L"Infiniband", DevPathFromTextInfiniband }, - {L"VenMsg", DevPathFromTextVenMsg }, - {L"VenPcAnsi", DevPathFromTextVenPcAnsi }, - {L"VenVt100", DevPathFromTextVenVt100 }, - {L"VenVt100Plus", DevPathFromTextVenVt100Plus }, - {L"VenUtf8", DevPathFromTextVenUtf8 }, - {L"UartFlowCtrl", DevPathFromTextUartFlowCtrl }, - {L"SAS", DevPathFromTextSAS }, - {L"SasEx", DevPathFromTextSasEx }, - {L"NVMe", DevPathFromTextNVMe }, - {L"UFS", DevPathFromTextUfs }, - {L"SD", DevPathFromTextSd }, - {L"eMMC", DevPathFromTextEmmc }, - {L"DebugPort", DevPathFromTextDebugPort }, - {L"MAC", DevPathFromTextMAC }, - {L"IPv4", DevPathFromTextIPv4 }, - {L"IPv6", DevPathFromTextIPv6 }, - {L"Uart", DevPathFromTextUart }, - {L"UsbClass", DevPathFromTextUsbClass }, - {L"UsbAudio", DevPathFromTextUsbAudio }, - {L"UsbCDCControl", DevPathFromTextUsbCDCControl }, - {L"UsbHID", DevPathFromTextUsbHID }, - {L"UsbImage", DevPathFromTextUsbImage }, - {L"UsbPrinter", DevPathFromTextUsbPrinter }, - {L"UsbMassStorage", DevPathFromTextUsbMassStorage }, - {L"UsbHub", DevPathFromTextUsbHub }, - {L"UsbCDCData", DevPathFromTextUsbCDCData }, - {L"UsbSmartCard", DevPathFromTextUsbSmartCard }, - {L"UsbVideo", DevPathFromTextUsbVideo }, - {L"UsbDiagnostic", DevPathFromTextUsbDiagnostic }, - {L"UsbWireless", DevPathFromTextUsbWireless }, - {L"UsbDeviceFirmwareUpdate", DevPathFromTextUsbDeviceFirmwareUpdate }, - {L"UsbIrdaBridge", DevPathFromTextUsbIrdaBridge }, - {L"UsbTestAndMeasurement", DevPathFromTextUsbTestAndMeasurement }, - {L"UsbWwid", DevPathFromTextUsbWwid }, - {L"Unit", DevPathFromTextUnit }, - {L"iSCSI", DevPathFromTextiSCSI }, - {L"Vlan", DevPathFromTextVlan }, - {L"Dns", DevPathFromTextDns }, - {L"Uri", DevPathFromTextUri }, - {L"Bluetooth", DevPathFromTextBluetooth }, - {L"Wi-Fi", DevPathFromTextWiFi }, - {L"BluetoothLE", DevPathFromTextBluetoothLE }, - {L"MediaPath", DevPathFromTextMediaPath }, - {L"HD", DevPathFromTextHD }, - {L"CDROM", DevPathFromTextCDROM }, - {L"VenMedia", DevPathFromTextVenMedia }, - {L"Media", DevPathFromTextMedia }, - {L"Fv", DevPathFromTextFv }, - {L"FvFile", DevPathFromTextFvFile }, - {L"Offset", DevPathFromTextRelativeOffsetRange }, - {L"RamDisk", DevPathFromTextRamDisk }, - {L"VirtualDisk", DevPathFromTextVirtualDisk }, - {L"VirtualCD", DevPathFromTextVirtualCd }, - {L"PersistentVirtualDisk", DevPathFromTextPersistentVirtualDisk }, - {L"PersistentVirtualCD", DevPathFromTextPersistentVirtualCd }, - - {L"BbsPath", DevPathFromTextBbsPath }, - {L"BBS", DevPathFromTextBBS }, - {L"Sata", DevPathFromTextSata }, - {NULL, NULL} -}; - -/** - Convert text to the binary representation of a device node. - - @param TextDeviceNode TextDeviceNode points to the text representation of a device - node. Conversion starts with the first character and continues - until the first non-device node character. - - @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was - insufficient memory or text unsupported. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibConvertTextToDeviceNode ( - CONST CHAR16 *TextDeviceNode - ) -{ - DEVICE_PATH_FROM_TEXT FromText; - CHAR16 *ParamStr; - EFI_DEVICE_PATH_PROTOCOL *DeviceNode; - CHAR16 *DeviceNodeStr; - UINTN Index; - - if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) { - return NULL; - } - - ParamStr = NULL; - FromText = NULL; - DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode); - ASSERT (DeviceNodeStr != NULL); - - for (Index = 0; mUefiDevicePathLibDevPathFromTextTable[Index].Function != NULL; Index++) { - ParamStr = GetParamByNodeName (DeviceNodeStr, mUefiDevicePathLibDevPathFromTextTable[Index].DevicePathNodeText); - if (ParamStr != NULL) { - FromText = mUefiDevicePathLibDevPathFromTextTable[Index].Function; - break; - } - } - - if (FromText == NULL) { - // - // A file path - // - FromText = DevPathFromTextFilePath; - DeviceNode = FromText (DeviceNodeStr); - // - // According to above logic, if 'FromText' is NULL in the 'if' statement, - // then 'ParamStr' must be NULL as well. No memory allocation has been made - // in this case. - // - // The below check is for addressing a false positive potential memory leak - // issue raised from static analysis. - // - if (ParamStr != NULL) { - free (ParamStr); - } - } else { - DeviceNode = FromText (ParamStr); - free (ParamStr); - } - - free (DeviceNodeStr); - - return DeviceNode; -} - -/** - Convert text to the binary representation of a device path. - - - @param TextDevicePath TextDevicePath points to the text representation of a device - path. Conversion starts with the first character and continues - until the first non-device node character. - - @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or - there was insufficient memory. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibConvertTextToDevicePath ( - CONST CHAR16 *TextDevicePath - ) -{ - EFI_DEVICE_PATH_PROTOCOL *DeviceNode; - EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; - CHAR16 *DevicePathStr; - CHAR16 *Str; - CHAR16 *DeviceNodeStr; - BOOLEAN IsInstanceEnd; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - - if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) { - return NULL; - } - - DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH); - ASSERT (DevicePath != NULL); - SetDevicePathEndNode (DevicePath); - - DevicePathStr = UefiDevicePathLibStrDuplicate (TextDevicePath); - - Str = DevicePathStr; - while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) { - DeviceNode = UefiDevicePathLibConvertTextToDeviceNode (DeviceNodeStr); - - NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode); - free (DevicePath); - free (DeviceNode); - DevicePath = NewDevicePath; - - if (IsInstanceEnd) { - DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH); - ASSERT (DeviceNode != NULL); - SetDevicePathEndNode (DeviceNode); - DeviceNode->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; - - NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode); - free (DevicePath); - free (DeviceNode); - DevicePath = NewDevicePath; - } - } - - free (DevicePathStr); - return DevicePath; -} diff --git a/BaseTools/Source/C/DevicePath/DevicePathUtilities.c b/BaseTools/Source/C/DevicePath/DevicePathUtilities.c deleted file mode 100644 index 49078aac8c..0000000000 --- a/BaseTools/Source/C/DevicePath/DevicePathUtilities.c +++ /dev/null @@ -1,868 +0,0 @@ -/** @file - Device Path services. The thing to remember is device paths are built out of - nodes. The device path is terminated by an end node that is length - sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL) - all over this file. - - The only place where multi-instance device paths are supported is in - environment variables. Multi-instance device paths should never be placed - on a Handle. - - Copyright (c) 2017, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "UefiDevicePathLib.h" -#include - -// -// Template for an end-of-device path node. -// -CONST EFI_DEVICE_PATH_PROTOCOL mUefiDevicePathLibEndDevicePath = { - END_DEVICE_PATH_TYPE, - END_ENTIRE_DEVICE_PATH_SUBTYPE, - { - END_DEVICE_PATH_LENGTH, - 0 - } -}; - -/** - Determine whether a given device path is valid. - - @param DevicePath A pointer to a device path data structure. - @param MaxSize The maximum size of the device path data structure. - - @retval TRUE DevicePath is valid. - @retval FALSE DevicePath is NULL. - @retval FALSE Maxsize is less than sizeof(EFI_DEVICE_PATH_PROTOCOL). - @retval FALSE The length of any node in the DevicePath is less - than sizeof (EFI_DEVICE_PATH_PROTOCOL). - @retval FALSE If MaxSize is not zero, the size of the DevicePath - exceeds MaxSize. - @retval FALSE If PcdMaximumDevicePathNodeCount is not zero, the node - count of the DevicePath exceeds PcdMaximumDevicePathNodeCount. -**/ -BOOLEAN -IsDevicePathValid ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - UINTN MaxSize - ) -{ - UINTN Count; - UINTN Size; - UINTN NodeLength; - - // - // Validate the input whether exists and its size big enough to touch the first node - // - if (DevicePath == NULL || (MaxSize > 0 && MaxSize < END_DEVICE_PATH_LENGTH)) { - return FALSE; - } - - if (MaxSize == 0) { - MaxSize = MAX_UINT32; - } - - for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) { - NodeLength = DevicePathNodeLength (DevicePath); - if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { - return FALSE; - } - - if (NodeLength > MAX_UINT32 - Size) { - return FALSE; - } - Size += NodeLength; - - // - // Validate next node before touch it. - // - if (Size > MaxSize - END_DEVICE_PATH_LENGTH ) { - return FALSE; - } - - Count++; - if (Count >= MAX_DEVICE_PATH_NODE_COUNT) { - return FALSE; - } - - } - - // - // Only return TRUE when the End Device Path node is valid. - // - return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH); -} - - -/** - Returns the Type field of a device path node. - - Returns the Type field of the device path node specified by Node. - - If Node is NULL, then ASSERT(). - - @param Node A pointer to a device path node data structure. - - @return The Type field of the device path node specified by Node. - -**/ -UINT8 -DevicePathType ( - CONST VOID *Node - ) -{ - ASSERT (Node != NULL); - return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Type; -} - -/** - Returns the SubType field of a device path node. - - Returns the SubType field of the device path node specified by Node. - - If Node is NULL, then ASSERT(). - - @param Node A pointer to a device path node data structure. - - @return The SubType field of the device path node specified by Node. - -**/ -UINT8 -DevicePathSubType ( - CONST VOID *Node - ) -{ - ASSERT (Node != NULL); - return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->SubType; -} - -/** - Returns the 16-bit Length field of a device path node. - - Returns the 16-bit Length field of the device path node specified by Node. - Node is not required to be aligned on a 16-bit boundary, so it is recommended - that a function such as ReadUnaligned16() be used to extract the contents of - the Length field. - - If Node is NULL, then ASSERT(). - - @param Node A pointer to a device path node data structure. - - @return The 16-bit Length field of the device path node specified by Node. - -**/ -UINTN -DevicePathNodeLength ( - CONST VOID *Node - ) -{ - ASSERT (Node != NULL); - return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]); -} - -/** - Returns a pointer to the next node in a device path. - - Returns a pointer to the device path node that follows the device path node - specified by Node. - - If Node is NULL, then ASSERT(). - - @param Node A pointer to a device path node data structure. - - @return a pointer to the device path node that follows the device path node - specified by Node. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -NextDevicePathNode ( - CONST VOID *Node - ) -{ - ASSERT (Node != NULL); - return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + DevicePathNodeLength(Node)); -} - -/** - Determines if a device path node is an end node of a device path. - This includes nodes that are the end of a device path instance and nodes that - are the end of an entire device path. - - Determines if the device path node specified by Node is an end node of a device path. - This includes nodes that are the end of a device path instance and nodes that are the - end of an entire device path. If Node represents an end node of a device path, - then TRUE is returned. Otherwise, FALSE is returned. - - If Node is NULL, then ASSERT(). - - @param Node A pointer to a device path node data structure. - - @retval TRUE The device path node specified by Node is an end node of a - device path. - @retval FALSE The device path node specified by Node is not an end node of - a device path. - -**/ -BOOLEAN -IsDevicePathEndType ( - CONST VOID *Node - ) -{ - ASSERT (Node != NULL); - return (BOOLEAN) (DevicePathType (Node) == END_DEVICE_PATH_TYPE); -} - -/** - Determines if a device path node is an end node of an entire device path. - - Determines if a device path node specified by Node is an end node of an entire - device path. If Node represents the end of an entire device path, then TRUE is - returned. Otherwise, FALSE is returned. - - If Node is NULL, then ASSERT(). - - @param Node A pointer to a device path node data structure. - - @retval TRUE The device path node specified by Node is the end of an entire - device path. - @retval FALSE The device path node specified by Node is not the end of an - entire device path. - -**/ -BOOLEAN -IsDevicePathEnd ( - CONST VOID *Node - ) -{ - ASSERT (Node != NULL); - return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE); -} - -/** - Determines if a device path node is an end node of a device path instance. - - Determines if a device path node specified by Node is an end node of a device - path instance. If Node represents the end of a device path instance, then TRUE - is returned. Otherwise, FALSE is returned. - - If Node is NULL, then ASSERT(). - - @param Node A pointer to a device path node data structure. - - @retval TRUE The device path node specified by Node is the end of a device - path instance. - @retval FALSE The device path node specified by Node is not the end of a - device path instance. - -**/ -BOOLEAN -IsDevicePathEndInstance ( - CONST VOID *Node - ) -{ - ASSERT (Node != NULL); - return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_INSTANCE_DEVICE_PATH_SUBTYPE); -} - -/** - Sets the length, in bytes, of a device path node. - - Sets the length of the device path node specified by Node to the value specified - by NodeLength. NodeLength is returned. Node is not required to be aligned on - a 16-bit boundary, so it is recommended that a function such as WriteUnaligned16() - be used to set the contents of the Length field. - - If Node is NULL, then ASSERT(). - If NodeLength >= SIZE_64KB, then ASSERT(). - If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT(). - - @param Node A pointer to a device path node data structure. - @param Length The length, in bytes, of the device path node. - - @return Length - -**/ -UINT16 -SetDevicePathNodeLength ( - VOID *Node, - UINTN Length - ) -{ - ASSERT (Node != NULL); - ASSERT ((Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) && (Length < SIZE_64KB)); - return WriteUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length)); -} - -/** - Fills in all the fields of a device path node that is the end of an entire device path. - - Fills in all the fields of a device path node specified by Node so Node represents - the end of an entire device path. The Type field of Node is set to - END_DEVICE_PATH_TYPE, the SubType field of Node is set to - END_ENTIRE_DEVICE_PATH_SUBTYPE, and the Length field of Node is set to - END_DEVICE_PATH_LENGTH. Node is not required to be aligned on a 16-bit boundary, - so it is recommended that a function such as WriteUnaligned16() be used to set - the contents of the Length field. - - If Node is NULL, then ASSERT(). - - @param Node A pointer to a device path node data structure. - -**/ -VOID -SetDevicePathEndNode ( - VOID *Node - ) -{ - ASSERT (Node != NULL); - memcpy (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath)); -} - -/** - Returns the size of a device path in bytes. - - This function returns the size, in bytes, of the device path data structure - specified by DevicePath including the end of device path node. - If DevicePath is NULL or invalid, then 0 is returned. - - @param DevicePath A pointer to a device path data structure. - - @retval 0 If DevicePath is NULL or invalid. - @retval Others The size of a device path in bytes. - -**/ -UINTN -UefiDevicePathLibGetDevicePathSize ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - CONST EFI_DEVICE_PATH_PROTOCOL *Start; - - if (DevicePath == NULL) { - return 0; - } - - if (!IsDevicePathValid (DevicePath, 0)) { - return 0; - } - - // - // Search for the end of the device path structure - // - Start = DevicePath; - while (!IsDevicePathEnd (DevicePath)) { - DevicePath = NextDevicePathNode (DevicePath); - } - - // - // Compute the size and add back in the size of the end device path structure - // - return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength (DevicePath); -} - -/** - Creates a new copy of an existing device path. - - This function allocates space for a new copy of the device path specified by DevicePath. - If DevicePath is NULL, then NULL is returned. If the memory is successfully - allocated, then the contents of DevicePath are copied to the newly allocated - buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned. - The memory for the new device path is allocated from EFI boot services memory. - It is the responsibility of the caller to free the memory allocated. - - @param DevicePath A pointer to a device path data structure. - - @retval NULL DevicePath is NULL or invalid. - @retval Others A pointer to the duplicated device path. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibDuplicateDevicePath ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - UINTN Size; - - // - // Compute the size - // - Size = GetDevicePathSize (DevicePath); - if (Size == 0) { - return NULL; - } - - // - // Allocate space for duplicate device path - // - - return AllocateCopyPool (Size, DevicePath); -} - -/** - Creates a new device path by appending a second device path to a first device path. - - This function creates a new device path by appending a copy of SecondDevicePath - to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path - device node from SecondDevicePath is retained. The newly created device path is - returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of - SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored, - and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and - SecondDevicePath are NULL, then a copy of an end-of-device-path is returned. - - If there is not enough memory for the newly allocated buffer, then NULL is returned. - The memory for the new device path is allocated from EFI boot services memory. - It is the responsibility of the caller to free the memory allocated. - - @param FirstDevicePath A pointer to a device path data structure. - @param SecondDevicePath A pointer to a device path data structure. - - @retval NULL If there is not enough memory for the newly allocated buffer. - @retval NULL If FirstDevicePath or SecondDevicePath is invalid. - @retval Others A pointer to the new device path if success. - Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibAppendDevicePath ( - CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, - CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath - ) -{ - UINTN Size; - UINTN Size1; - UINTN Size2; - EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePath2; - - // - // If there's only 1 path, just duplicate it. - // - if (FirstDevicePath == NULL) { - return DuplicateDevicePath ((SecondDevicePath != NULL) ? SecondDevicePath : &mUefiDevicePathLibEndDevicePath); - } - - if (SecondDevicePath == NULL) { - return DuplicateDevicePath (FirstDevicePath); - } - - if (!IsDevicePathValid (FirstDevicePath, 0) || !IsDevicePathValid (SecondDevicePath, 0)) { - return NULL; - } - - // - // Allocate space for the combined device path. It only has one end node of - // length EFI_DEVICE_PATH_PROTOCOL. - // - Size1 = GetDevicePathSize (FirstDevicePath); - Size2 = GetDevicePathSize (SecondDevicePath); - Size = Size1 + Size2 - END_DEVICE_PATH_LENGTH; - - NewDevicePath = AllocatePool (Size); - - if (NewDevicePath != NULL) { - NewDevicePath = memcpy (NewDevicePath, FirstDevicePath, Size1); - // - // Over write FirstDevicePath EndNode and do the copy - // - DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + - (Size1 - END_DEVICE_PATH_LENGTH)); - memcpy (DevicePath2, SecondDevicePath, Size2); - } - - return NewDevicePath; -} - -/** - Creates a new path by appending the device node to the device path. - - This function creates a new device path by appending a copy of the device node - specified by DevicePathNode to a copy of the device path specified by DevicePath - in an allocated buffer. The end-of-device-path device node is moved after the - end of the appended device node. - If DevicePathNode is NULL then a copy of DevicePath is returned. - If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device - path device node is returned. - If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path - device node is returned. - If there is not enough memory to allocate space for the new device path, then - NULL is returned. - The memory is allocated from EFI boot services memory. It is the responsibility - of the caller to free the memory allocated. - - @param DevicePath A pointer to a device path data structure. - @param DevicePathNode A pointer to a single device path node. - - @retval NULL If there is not enough memory for the new device path. - @retval Others A pointer to the new device path if success. - A copy of DevicePathNode followed by an end-of-device-path node - if both FirstDevicePath and SecondDevicePath are NULL. - A copy of an end-of-device-path node if both FirstDevicePath - and SecondDevicePath are NULL. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibAppendDevicePathNode ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode - ) -{ - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - EFI_DEVICE_PATH_PROTOCOL *NextNode; - EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; - UINTN NodeLength; - - if (DevicePathNode == NULL) { - return DuplicateDevicePath ((DevicePath != NULL) ? DevicePath : &mUefiDevicePathLibEndDevicePath); - } - // - // Build a Node that has a terminator on it - // - NodeLength = DevicePathNodeLength (DevicePathNode); - - TempDevicePath = AllocatePool (NodeLength + END_DEVICE_PATH_LENGTH); - if (TempDevicePath == NULL) { - return NULL; - } - TempDevicePath = memcpy (TempDevicePath, DevicePathNode, NodeLength); - // - // Add and end device path node to convert Node to device path - // - NextNode = NextDevicePathNode (TempDevicePath); - SetDevicePathEndNode (NextNode); - // - // Append device paths - // - NewDevicePath = AppendDevicePath (DevicePath, TempDevicePath); - - free (TempDevicePath); - - return NewDevicePath; -} - -/** - Creates a new device path by appending the specified device path instance to the specified device - path. - - This function creates a new device path by appending a copy of the device path - instance specified by DevicePathInstance to a copy of the device path specified - by DevicePath in a allocated buffer. - The end-of-device-path device node is moved after the end of the appended device - path instance and a new end-of-device-path-instance node is inserted between. - If DevicePath is NULL, then a copy if DevicePathInstance is returned. - If DevicePathInstance is NULL, then NULL is returned. - If DevicePath or DevicePathInstance is invalid, then NULL is returned. - If there is not enough memory to allocate space for the new device path, then - NULL is returned. - The memory is allocated from EFI boot services memory. It is the responsibility - of the caller to free the memory allocated. - - @param DevicePath A pointer to a device path data structure. - @param DevicePathInstance A pointer to a device path instance. - - @return A pointer to the new device path. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibAppendDevicePathInstance ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance - ) -{ - EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - UINTN SrcSize; - UINTN InstanceSize; - - if (DevicePath == NULL) { - return DuplicateDevicePath (DevicePathInstance); - } - - if (DevicePathInstance == NULL) { - return NULL; - } - - if (!IsDevicePathValid (DevicePath, 0) || !IsDevicePathValid (DevicePathInstance, 0)) { - return NULL; - } - - SrcSize = GetDevicePathSize (DevicePath); - InstanceSize = GetDevicePathSize (DevicePathInstance); - - NewDevicePath = AllocatePool (SrcSize + InstanceSize); - if (NewDevicePath != NULL) { - - TempDevicePath = memcpy (NewDevicePath, DevicePath, SrcSize);; - - while (!IsDevicePathEnd (TempDevicePath)) { - TempDevicePath = NextDevicePathNode (TempDevicePath); - } - - TempDevicePath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; - TempDevicePath = NextDevicePathNode (TempDevicePath); - memcpy (TempDevicePath, DevicePathInstance, InstanceSize); - } - - return NewDevicePath; -} - -/** - Creates a copy of the current device path instance and returns a pointer to the next device path - instance. - - This function creates a copy of the current device path instance. It also updates - DevicePath to point to the next device path instance in the device path (or NULL - if no more) and updates Size to hold the size of the device path instance copy. - If DevicePath is NULL, then NULL is returned. - If DevicePath points to a invalid device path, then NULL is returned. - If there is not enough memory to allocate space for the new device path, then - NULL is returned. - The memory is allocated from EFI boot services memory. It is the responsibility - of the caller to free the memory allocated. - If Size is NULL, then ASSERT(). - - @param DevicePath On input, this holds the pointer to the current - device path instance. On output, this holds - the pointer to the next device path instance - or NULL if there are no more device path - instances in the device path pointer to a - device path data structure. - @param Size On output, this holds the size of the device - path instance, in bytes or zero, if DevicePath - is NULL. - - @return A pointer to the current device path instance. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibGetNextDevicePathInstance ( - EFI_DEVICE_PATH_PROTOCOL **DevicePath, - UINTN *Size - ) -{ - EFI_DEVICE_PATH_PROTOCOL *DevPath; - EFI_DEVICE_PATH_PROTOCOL *ReturnValue; - UINT8 Temp; - - ASSERT (Size != NULL); - - if (DevicePath == NULL || *DevicePath == NULL) { - *Size = 0; - return NULL; - } - - if (!IsDevicePathValid (*DevicePath, 0)) { - return NULL; - } - - // - // Find the end of the device path instance - // - DevPath = *DevicePath; - while (!IsDevicePathEndType (DevPath)) { - DevPath = NextDevicePathNode (DevPath); - } - - // - // Compute the size of the device path instance - // - *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL); - - // - // Make a copy and return the device path instance - // - Temp = DevPath->SubType; - DevPath->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; - ReturnValue = DuplicateDevicePath (*DevicePath); - DevPath->SubType = Temp; - - // - // If DevPath is the end of an entire device path, then another instance - // does not follow, so *DevicePath is set to NULL. - // - if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) { - *DevicePath = NULL; - } else { - *DevicePath = NextDevicePathNode (DevPath); - } - - return ReturnValue; -} - -/** - Creates a device node. - - This function creates a new device node in a newly allocated buffer of size - NodeLength and initializes the device path node header with NodeType and NodeSubType. - The new device path node is returned. - If NodeLength is smaller than a device path header, then NULL is returned. - If there is not enough memory to allocate space for the new device path, then - NULL is returned. - The memory is allocated from EFI boot services memory. It is the responsibility - of the caller to free the memory allocated. - - @param NodeType The device node type for the new device node. - @param NodeSubType The device node sub-type for the new device node. - @param NodeLength The length of the new device node. - - @return The new device path. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibCreateDeviceNode ( - UINT8 NodeType, - UINT8 NodeSubType, - UINT16 NodeLength - ) -{ - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - - if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { - // - // NodeLength is less than the size of the header. - // - return NULL; - } - - DevicePath = AllocateZeroPool (NodeLength); - if (DevicePath != NULL) { - DevicePath->Type = NodeType; - DevicePath->SubType = NodeSubType; - SetDevicePathNodeLength (DevicePath, NodeLength); - } - - return DevicePath; -} - -/** - Determines if a device path is single or multi-instance. - - This function returns TRUE if the device path specified by DevicePath is - multi-instance. - Otherwise, FALSE is returned. - If DevicePath is NULL or invalid, then FALSE is returned. - - @param DevicePath A pointer to a device path data structure. - - @retval TRUE DevicePath is multi-instance. - @retval FALSE DevicePath is not multi-instance, or DevicePath - is NULL or invalid. - -**/ -BOOLEAN -UefiDevicePathLibIsDevicePathMultiInstance ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - CONST EFI_DEVICE_PATH_PROTOCOL *Node; - - if (DevicePath == NULL) { - return FALSE; - } - - if (!IsDevicePathValid (DevicePath, 0)) { - return FALSE; - } - - Node = DevicePath; - while (!IsDevicePathEnd (Node)) { - if (IsDevicePathEndInstance (Node)) { - return TRUE; - } - - Node = NextDevicePathNode (Node); - } - - return FALSE; -} - - -/** - Retrieves the device path protocol from a handle. - - This function returns the device path protocol from the handle specified by Handle. - If Handle is NULL or Handle does not contain a device path protocol, then NULL - is returned. - - @param Handle The handle from which to retrieve the device - path protocol. - - @return The device path protocol from the handle specified by Handle. - -**/ -/* -EFI_DEVICE_PATH_PROTOCOL * -DevicePathFromHandle ( - EFI_HANDLE Handle - ) -{ - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_STATUS Status; - - Status = gBS->HandleProtocol ( - Handle, - &gEfiDevicePathProtocolGuid, - (VOID *) &DevicePath - ); - if (EFI_ERROR (Status)) { - DevicePath = NULL; - } - return DevicePath; -} -*/ -/** - Allocates a device path for a file and appends it to an existing device path. - - If Device is a valid device handle that contains a device path protocol, then a device path for - the file specified by FileName is allocated and appended to the device path associated with the - handle Device. The allocated device path is returned. If Device is NULL or Device is a handle - that does not support the device path protocol, then a device path containing a single device - path node for the file specified by FileName is allocated and returned. - The memory for the new device path is allocated from EFI boot services memory. It is the responsibility - of the caller to free the memory allocated. - - If FileName is NULL, then ASSERT(). - If FileName is not aligned on a 16-bit boundary, then ASSERT(). - - @param Device A pointer to a device handle. This parameter - is optional and may be NULL. - @param FileName A pointer to a Null-terminated Unicode string. - - @return The allocated device path. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -FileDevicePath ( - EFI_HANDLE Device, OPTIONAL - CONST CHAR16 *FileName - ) -{ - UINTN Size; - FILEPATH_DEVICE_PATH *FilePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *FileDevicePath; - - DevicePath = NULL; - - Size = StrSize (FileName); - FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH); - if (FileDevicePath != NULL) { - FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath; - FilePath->Header.Type = MEDIA_DEVICE_PATH; - FilePath->Header.SubType = MEDIA_FILEPATH_DP; - memcpy (&FilePath->PathName, FileName, Size); - SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); - SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header)); - - //if (Device != NULL) { - // DevicePath = DevicePathFromHandle (Device); - //} - - DevicePath = AppendDevicePath (DevicePath, FileDevicePath); - free (FileDevicePath); - } - - return DevicePath; -} diff --git a/BaseTools/Source/C/DevicePath/GNUmakefile b/BaseTools/Source/C/DevicePath/GNUmakefile index 26ae14c468..3688c5f121 100644 --- a/BaseTools/Source/C/DevicePath/GNUmakefile +++ b/BaseTools/Source/C/DevicePath/GNUmakefile @@ -9,7 +9,14 @@ MAKEROOT ?= .. APPNAME = DevicePath -OBJECTS = DevicePath.o UefiDevicePathLib.o DevicePathFromText.o DevicePathUtilities.o +OBJECTS = DevicePath.o + +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.o \ + $(EDK2_OBJPATH)/MdePkg/Library/UefiDevicePathLib/DevicePathToText.o \ + $(EDK2_OBJPATH)/MdePkg/Library/UefiDevicePathLib/DevicePathUtilities.o \ + $(EDK2_OBJPATH)/MdePkg/Library/UefiDevicePathLib/DevicePathUtilitiesBase.o \ + $(EDK2_OBJPATH)/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.o include $(MAKEROOT)/Makefiles/app.makefile diff --git a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c deleted file mode 100644 index ad3593f963..0000000000 --- a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.c +++ /dev/null @@ -1,292 +0,0 @@ -/** @file - Device Path services. The thing to remember is device paths are built out of - nodes. The device path is terminated by an end node that is length - sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL) - all over this file. - - The only place where multi-instance device paths are supported is in - environment variables. Multi-instance device paths should never be placed - on a Handle. - - Copyright (c) 2017, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - - -#include "UefiDevicePathLib.h" - -/** - Returns the size of a device path in bytes. - - This function returns the size, in bytes, of the device path data structure - specified by DevicePath including the end of device path node. - If DevicePath is NULL or invalid, then 0 is returned. - - @param DevicePath A pointer to a device path data structure. - - @retval 0 If DevicePath is NULL or invalid. - @retval Others The size of a device path in bytes. - -**/ -UINTN -GetDevicePathSize ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - return UefiDevicePathLibGetDevicePathSize (DevicePath); -} - -/** - Creates a new copy of an existing device path. - - This function allocates space for a new copy of the device path specified by DevicePath. - If DevicePath is NULL, then NULL is returned. If the memory is successfully - allocated, then the contents of DevicePath are copied to the newly allocated - buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned. - The memory for the new device path is allocated from EFI boot services memory. - It is the responsibility of the caller to free the memory allocated. - - @param DevicePath A pointer to a device path data structure. - - @retval NULL DevicePath is NULL or invalid. - @retval Others A pointer to the duplicated device path. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -DuplicateDevicePath ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - return UefiDevicePathLibDuplicateDevicePath (DevicePath); -} - -/** - Creates a new device path by appending a second device path to a first device path. - - This function creates a new device path by appending a copy of SecondDevicePath - to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path - device node from SecondDevicePath is retained. The newly created device path is - returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of - SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored, - and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and - SecondDevicePath are NULL, then a copy of an end-of-device-path is returned. - - If there is not enough memory for the newly allocated buffer, then NULL is returned. - The memory for the new device path is allocated from EFI boot services memory. - It is the responsibility of the caller to free the memory allocated. - - @param FirstDevicePath A pointer to a device path data structure. - @param SecondDevicePath A pointer to a device path data structure. - - @retval NULL If there is not enough memory for the newly allocated buffer. - @retval NULL If FirstDevicePath or SecondDevicePath is invalid. - @retval Others A pointer to the new device path if success. - Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -AppendDevicePath ( - CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL - CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL - ) -{ - return UefiDevicePathLibAppendDevicePath (FirstDevicePath, SecondDevicePath); -} - -/** - Creates a new path by appending the device node to the device path. - - This function creates a new device path by appending a copy of the device node - specified by DevicePathNode to a copy of the device path specified by DevicePath - in an allocated buffer. The end-of-device-path device node is moved after the - end of the appended device node. - If DevicePathNode is NULL then a copy of DevicePath is returned. - If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device - path device node is returned. - If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path - device node is returned. - If there is not enough memory to allocate space for the new device path, then - NULL is returned. - The memory is allocated from EFI boot services memory. It is the responsibility - of the caller to free the memory allocated. - - @param DevicePath A pointer to a device path data structure. - @param DevicePathNode A pointer to a single device path node. - - @retval NULL If there is not enough memory for the new device path. - @retval Others A pointer to the new device path if success. - A copy of DevicePathNode followed by an end-of-device-path node - if both FirstDevicePath and SecondDevicePath are NULL. - A copy of an end-of-device-path node if both FirstDevicePath - and SecondDevicePath are NULL. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -AppendDevicePathNode ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL - ) -{ - return UefiDevicePathLibAppendDevicePathNode (DevicePath, DevicePathNode); -} - -/** - Creates a new device path by appending the specified device path instance to the specified device - path. - - This function creates a new device path by appending a copy of the device path - instance specified by DevicePathInstance to a copy of the device path specified - by DevicePath in a allocated buffer. - The end-of-device-path device node is moved after the end of the appended device - path instance and a new end-of-device-path-instance node is inserted between. - If DevicePath is NULL, then a copy if DevicePathInstance is returned. - If DevicePathInstance is NULL, then NULL is returned. - If DevicePath or DevicePathInstance is invalid, then NULL is returned. - If there is not enough memory to allocate space for the new device path, then - NULL is returned. - The memory is allocated from EFI boot services memory. It is the responsibility - of the caller to free the memory allocated. - - @param DevicePath A pointer to a device path data structure. - @param DevicePathInstance A pointer to a device path instance. - - @return A pointer to the new device path. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -AppendDevicePathInstance ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL - ) -{ - return UefiDevicePathLibAppendDevicePathInstance (DevicePath, DevicePathInstance); -} - -/** - Creates a copy of the current device path instance and returns a pointer to the next device path - instance. - - This function creates a copy of the current device path instance. It also updates - DevicePath to point to the next device path instance in the device path (or NULL - if no more) and updates Size to hold the size of the device path instance copy. - If DevicePath is NULL, then NULL is returned. - If DevicePath points to a invalid device path, then NULL is returned. - If there is not enough memory to allocate space for the new device path, then - NULL is returned. - The memory is allocated from EFI boot services memory. It is the responsibility - of the caller to free the memory allocated. - If Size is NULL, then ASSERT(). - - @param DevicePath On input, this holds the pointer to the current - device path instance. On output, this holds - the pointer to the next device path instance - or NULL if there are no more device path - instances in the device path pointer to a - device path data structure. - @param Size On output, this holds the size of the device - path instance, in bytes or zero, if DevicePath - is NULL. - - @return A pointer to the current device path instance. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -GetNextDevicePathInstance ( - EFI_DEVICE_PATH_PROTOCOL **DevicePath, - UINTN *Size - ) -{ - return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, Size); -} - -/** - Creates a device node. - - This function creates a new device node in a newly allocated buffer of size - NodeLength and initializes the device path node header with NodeType and NodeSubType. - The new device path node is returned. - If NodeLength is smaller than a device path header, then NULL is returned. - If there is not enough memory to allocate space for the new device path, then - NULL is returned. - The memory is allocated from EFI boot services memory. It is the responsibility - of the caller to free the memory allocated. - - @param NodeType The device node type for the new device node. - @param NodeSubType The device node sub-type for the new device node. - @param NodeLength The length of the new device node. - - @return The new device path. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -CreateDeviceNode ( - UINT8 NodeType, - UINT8 NodeSubType, - UINT16 NodeLength - ) -{ - return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType, NodeLength); -} - -/** - Determines if a device path is single or multi-instance. - - This function returns TRUE if the device path specified by DevicePath is - multi-instance. - Otherwise, FALSE is returned. - If DevicePath is NULL or invalid, then FALSE is returned. - - @param DevicePath A pointer to a device path data structure. - - @retval TRUE DevicePath is multi-instance. - @retval FALSE DevicePath is not multi-instance, or DevicePath - is NULL or invalid. - -**/ -BOOLEAN -IsDevicePathMultiInstance ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath); -} - -/** - Convert text to the binary representation of a device node. - - @param TextDeviceNode TextDeviceNode points to the text representation of a device - node. Conversion starts with the first character and continues - until the first non-device node character. - - @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was - insufficient memory or text unsupported. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -ConvertTextToDeviceNode ( - CONST CHAR16 *TextDeviceNode - ) -{ - return UefiDevicePathLibConvertTextToDeviceNode (TextDeviceNode); -} - -/** - Convert text to the binary representation of a device path. - - - @param TextDevicePath TextDevicePath points to the text representation of a device - path. Conversion starts with the first character and continues - until the first non-device node character. - - @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or - there was insufficient memory. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -ConvertTextToDevicePath ( - CONST CHAR16 *TextDevicePath - ) -{ - return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath); -} diff --git a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h index 30d8854c99..7097c08659 100644 --- a/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h +++ b/BaseTools/Source/C/DevicePath/UefiDevicePathLib.h @@ -25,527 +25,11 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "EfiUtilityMsgs.h" -#include -#define EFI_UART_DEVICE_PATH_GUID DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL - - -#define END_DEVICE_PATH_LENGTH (sizeof (EFI_DEVICE_PATH_PROTOCOL)) -#define MAX_DEVICE_PATH_NODE_COUNT 1024 -#define SIZE_64KB 0x00010000 - -// -// Private Data structure -// -typedef -EFI_DEVICE_PATH_PROTOCOL * -(*DEVICE_PATH_FROM_TEXT) ( - IN CHAR16 *Str - ); - -typedef struct { - CHAR16 *Str; - UINTN Count; - UINTN Capacity; -} POOL_PRINT; - - -typedef struct { - CHAR16 *DevicePathNodeText; - DEVICE_PATH_FROM_TEXT Function; -} DEVICE_PATH_FROM_TEXT_TABLE; - -typedef struct { - BOOLEAN ClassExist; - UINT8 Class; - BOOLEAN SubClassExist; - UINT8 SubClass; -} USB_CLASS_TEXT; - -#define USB_CLASS_AUDIO 1 -#define USB_CLASS_CDCCONTROL 2 -#define USB_CLASS_HID 3 -#define USB_CLASS_IMAGE 6 -#define USB_CLASS_PRINTER 7 -#define USB_CLASS_MASS_STORAGE 8 -#define USB_CLASS_HUB 9 -#define USB_CLASS_CDCDATA 10 -#define USB_CLASS_SMART_CARD 11 -#define USB_CLASS_VIDEO 14 -#define USB_CLASS_DIAGNOSTIC 220 -#define USB_CLASS_WIRELESS 224 - -#define USB_CLASS_RESERVE 254 -#define USB_SUBCLASS_FW_UPDATE 1 -#define USB_SUBCLASS_IRDA_BRIDGE 2 -#define USB_SUBCLASS_TEST 3 - -#define RFC_1700_UDP_PROTOCOL 17 -#define RFC_1700_TCP_PROTOCOL 6 - -#pragma pack(1) - -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - EFI_GUID Guid; - UINT8 VendorDefinedData[1]; -} VENDOR_DEFINED_HARDWARE_DEVICE_PATH; - -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - EFI_GUID Guid; - UINT8 VendorDefinedData[1]; -} VENDOR_DEFINED_MESSAGING_DEVICE_PATH; - -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - EFI_GUID Guid; - UINT8 VendorDefinedData[1]; -} VENDOR_DEFINED_MEDIA_DEVICE_PATH; - -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - UINT32 Hid; - UINT32 Uid; - UINT32 Cid; - CHAR8 HidUidCidStr[3]; -} ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR; - -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - UINT16 NetworkProtocol; - UINT16 LoginOption; - UINT64 Lun; - UINT16 TargetPortalGroupTag; - CHAR8 TargetName[1]; -} ISCSI_DEVICE_PATH_WITH_NAME; - -typedef struct { - EFI_DEVICE_PATH_PROTOCOL Header; - EFI_GUID Guid; - UINT8 VendorDefinedData[1]; -} VENDOR_DEVICE_PATH_WITH_DATA; - -#pragma pack() - -/** - Returns the size of a device path in bytes. - - This function returns the size, in bytes, of the device path data structure - specified by DevicePath including the end of device path node. - If DevicePath is NULL or invalid, then 0 is returned. - - @param DevicePath A pointer to a device path data structure. - - @retval 0 If DevicePath is NULL or invalid. - @retval Others The size of a device path in bytes. - -**/ -UINTN -UefiDevicePathLibGetDevicePathSize ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -/** - Creates a new copy of an existing device path. - - This function allocates space for a new copy of the device path specified by DevicePath. - If DevicePath is NULL, then NULL is returned. If the memory is successfully - allocated, then the contents of DevicePath are copied to the newly allocated - buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned. - The memory for the new device path is allocated from EFI boot services memory. - It is the responsibility of the caller to free the memory allocated. - - @param DevicePath A pointer to a device path data structure. - - @retval NULL DevicePath is NULL or invalid. - @retval Others A pointer to the duplicated device path. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibDuplicateDevicePath ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -/** - Creates a new device path by appending a second device path to a first device path. - - This function creates a new device path by appending a copy of SecondDevicePath - to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path - device node from SecondDevicePath is retained. The newly created device path is - returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of - SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored, - and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and - SecondDevicePath are NULL, then a copy of an end-of-device-path is returned. - - If there is not enough memory for the newly allocated buffer, then NULL is returned. - The memory for the new device path is allocated from EFI boot services memory. - It is the responsibility of the caller to free the memory allocated. - - @param FirstDevicePath A pointer to a device path data structure. - @param SecondDevicePath A pointer to a device path data structure. - - @retval NULL If there is not enough memory for the newly allocated buffer. - @retval NULL If FirstDevicePath or SecondDevicePath is invalid. - @retval Others A pointer to the new device path if success. - Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibAppendDevicePath ( - CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL - CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL - ); - -/** - Creates a new path by appending the device node to the device path. - - This function creates a new device path by appending a copy of the device node - specified by DevicePathNode to a copy of the device path specified by DevicePath - in an allocated buffer. The end-of-device-path device node is moved after the - end of the appended device node. - If DevicePathNode is NULL then a copy of DevicePath is returned. - If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device - path device node is returned. - If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path - device node is returned. - If there is not enough memory to allocate space for the new device path, then - NULL is returned. - The memory is allocated from EFI boot services memory. It is the responsibility - of the caller to free the memory allocated. - - @param DevicePath A pointer to a device path data structure. - @param DevicePathNode A pointer to a single device path node. - - @retval NULL If there is not enough memory for the new device path. - @retval Others A pointer to the new device path if success. - A copy of DevicePathNode followed by an end-of-device-path node - if both FirstDevicePath and SecondDevicePath are NULL. - A copy of an end-of-device-path node if both FirstDevicePath - and SecondDevicePath are NULL. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibAppendDevicePathNode ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL - ); - -/** - Creates a new device path by appending the specified device path instance to the specified device - path. - - This function creates a new device path by appending a copy of the device path - instance specified by DevicePathInstance to a copy of the device path specified - by DevicePath in a allocated buffer. - The end-of-device-path device node is moved after the end of the appended device - path instance and a new end-of-device-path-instance node is inserted between. - If DevicePath is NULL, then a copy if DevicePathInstance is returned. - If DevicePathInstance is NULL, then NULL is returned. - If DevicePath or DevicePathInstance is invalid, then NULL is returned. - If there is not enough memory to allocate space for the new device path, then - NULL is returned. - The memory is allocated from EFI boot services memory. It is the responsibility - of the caller to free the memory allocated. - - @param DevicePath A pointer to a device path data structure. - @param DevicePathInstance A pointer to a device path instance. - - @return A pointer to the new device path. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibAppendDevicePathInstance ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL - ); - -/** - Creates a copy of the current device path instance and returns a pointer to the next device path - instance. - - This function creates a copy of the current device path instance. It also updates - DevicePath to point to the next device path instance in the device path (or NULL - if no more) and updates Size to hold the size of the device path instance copy. - If DevicePath is NULL, then NULL is returned. - If DevicePath points to a invalid device path, then NULL is returned. - If there is not enough memory to allocate space for the new device path, then - NULL is returned. - The memory is allocated from EFI boot services memory. It is the responsibility - of the caller to free the memory allocated. - If Size is NULL, then ASSERT(). - - @param DevicePath On input, this holds the pointer to the current - device path instance. On output, this holds - the pointer to the next device path instance - or NULL if there are no more device path - instances in the device path pointer to a - device path data structure. - @param Size On output, this holds the size of the device - path instance, in bytes or zero, if DevicePath - is NULL. - - @return A pointer to the current device path instance. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibGetNextDevicePathInstance ( - EFI_DEVICE_PATH_PROTOCOL **DevicePath, - UINTN *Size - ); - -/** - Creates a device node. - - This function creates a new device node in a newly allocated buffer of size - NodeLength and initializes the device path node header with NodeType and NodeSubType. - The new device path node is returned. - If NodeLength is smaller than a device path header, then NULL is returned. - If there is not enough memory to allocate space for the new device path, then - NULL is returned. - The memory is allocated from EFI boot services memory. It is the responsibility - of the caller to free the memory allocated. - - @param NodeType The device node type for the new device node. - @param NodeSubType The device node sub-type for the new device node. - @param NodeLength The length of the new device node. - - @return The new device path. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibCreateDeviceNode ( - UINT8 NodeType, - UINT8 NodeSubType, - UINT16 NodeLength - ); - -/** - Determines if a device path is single or multi-instance. - - This function returns TRUE if the device path specified by DevicePath is - multi-instance. - Otherwise, FALSE is returned. - If DevicePath is NULL or invalid, then FALSE is returned. - - @param DevicePath A pointer to a device path data structure. - - @retval TRUE DevicePath is multi-instance. - @retval FALSE DevicePath is not multi-instance, or DevicePath - is NULL or invalid. - -**/ -BOOLEAN -UefiDevicePathLibIsDevicePathMultiInstance ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -/** - Convert text to the binary representation of a device node. - - @param TextDeviceNode TextDeviceNode points to the text representation of a device - node. Conversion starts with the first character and continues - until the first non-device node character. - - @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was - insufficient memory or text unsupported. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibConvertTextToDeviceNode ( - CONST CHAR16 *TextDeviceNode - ); - -/** - Convert text to the binary representation of a device path. - - - @param TextDevicePath TextDevicePath points to the text representation of a device - path. Conversion starts with the first character and continues - until the first non-device node character. - - @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or - there was insufficient memory. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibConvertTextToDevicePath ( - CONST CHAR16 *TextDevicePath - ); - -EFI_DEVICE_PATH_PROTOCOL * -CreateDeviceNode ( - UINT8 NodeType, - UINT8 NodeSubType, - UINT16 NodeLength - ); - -BOOLEAN -IsDevicePathMultiInstance ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -EFI_DEVICE_PATH_PROTOCOL * -GetNextDevicePathInstance ( - EFI_DEVICE_PATH_PROTOCOL **DevicePath, - UINTN *Size - ); - -EFI_DEVICE_PATH_PROTOCOL * -AppendDevicePathInstance ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL - ); - -EFI_DEVICE_PATH_PROTOCOL * -AppendDevicePathNode ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL - ); -EFI_DEVICE_PATH_PROTOCOL * -AppendDevicePath ( - CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL - CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL - ); - -EFI_DEVICE_PATH_PROTOCOL * -DuplicateDevicePath ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -UINTN -GetDevicePathSize ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -CHAR16 * -ConvertDeviceNodeToText ( - CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode, - BOOLEAN DisplayOnly, - BOOLEAN AllowShortcuts - ); - -CHAR16 * -ConvertDevicePathToText ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - BOOLEAN DisplayOnly, - BOOLEAN AllowShortcuts - ); - -EFI_DEVICE_PATH_PROTOCOL * -ConvertTextToDeviceNode ( - CONST CHAR16 *TextDeviceNode - ); - -EFI_DEVICE_PATH_PROTOCOL * -ConvertTextToDevicePath ( - CONST CHAR16 *TextDevicePath - ); - - - -VOID -SetDevicePathEndNode ( - VOID *Node - ); - -BOOLEAN -IsDevicePathValid ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - UINTN MaxSize - ); - -UINT8 -DevicePathType ( - CONST VOID *Node - ); - -UINT8 -DevicePathSubType ( - CONST VOID *Node - ); - -UINTN -DevicePathNodeLength ( - CONST VOID *Node - ); - -EFI_DEVICE_PATH_PROTOCOL * -NextDevicePathNode ( - CONST VOID *Node - ); - -BOOLEAN -IsDevicePathEndType ( - CONST VOID *Node - ); - -BOOLEAN -IsDevicePathEnd ( - CONST VOID *Node - ); -BOOLEAN -IsDevicePathEndInstance ( - CONST VOID *Node - ); - -UINT16 -SetDevicePathNodeLength ( - VOID *Node, - UINTN Length - ); - -VOID -SetDevicePathEndNode ( - VOID *Node - ); - -UINTN -UefiDevicePathLibGetDevicePathSize ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibDuplicateDevicePath ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibAppendDevicePath ( - CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, - CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath - ); - -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibAppendDevicePathNode ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode - ); - -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibAppendDevicePathInstance ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance - ); - -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibGetNextDevicePathInstance ( - EFI_DEVICE_PATH_PROTOCOL **DevicePath, - UINTN *Size - ); - -EFI_DEVICE_PATH_PROTOCOL * -UefiDevicePathLibCreateDeviceNode ( - UINT8 NodeType, - UINT8 NodeSubType, - UINT16 NodeLength - ); - -BOOLEAN -UefiDevicePathLibIsDevicePathMultiInstance ( - CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath - ); - +#include +#define UefiDevicePathLibConvertTextToDevicePath ConvertTextToDevicePath +#include +#define EFI_UART_DEVICE_PATH_GUID DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL #endif diff --git a/BaseTools/Source/C/Include/Common/AutoGen.h b/BaseTools/Source/C/Include/Common/AutoGen.h index 8136bd1e2a..150994a7e1 100644 --- a/BaseTools/Source/C/Include/Common/AutoGen.h +++ b/BaseTools/Source/C/Include/Common/AutoGen.h @@ -51,6 +51,13 @@ extern UINT64 _gPcd_SkuId_Array[]; #define _PCD_GET_MODE_32_PcdMaximumLinkedListLength _PCD_VALUE_PcdMaximumLinkedListLength //#define _PCD_SET_MODE_32_PcdMaximumLinkedListLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD +#define _PCD_TOKEN_PcdMaximumDevicePathNodeCount 0U +#define _PCD_SIZE_PcdMaximumDevicePathNodeCount 4 +#define _PCD_GET_MODE_SIZE_PcdMaximumDevicePathNodeCount _PCD_SIZE_PcdMaximumDevicePathNodeCount +#define _PCD_VALUE_PcdMaximumDevicePathNodeCount 0U +#define _PCD_GET_MODE_32_PcdMaximumDevicePathNodeCount _PCD_VALUE_PcdMaximumDevicePathNodeCount +//#define _PCD_SET_MODE_32_PcdMaximumDevicePathNodeCount ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + #define _PCD_TOKEN_PcdVerifyNodeInList 0U #define _PCD_SIZE_PcdVerifyNodeInList 1 #define _PCD_GET_MODE_SIZE_PcdVerifyNodeInList _PCD_SIZE_PcdVerifyNodeInList From 8acad7450a8668b58dadc645adabe5d7b88642ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Tue, 28 Mar 2023 00:29:29 +0200 Subject: [PATCH 044/341] EmulatorPkg/Host: Fix XCODE5 build --- EmulatorPkg/Unix/Host/Host.inf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/EmulatorPkg/Unix/Host/Host.inf b/EmulatorPkg/Unix/Host/Host.inf index d8f9585e20..806bb52c65 100644 --- a/EmulatorPkg/Unix/Host/Host.inf +++ b/EmulatorPkg/Unix/Host/Host.inf @@ -132,11 +132,11 @@ # Need to do this link via gcc and not ld as the pathing to libraries changes from OS version to OS version # XCODE:*_*_IA32_DLINK_PATH == gcc - XCODE:*_*_IA32_CC_FLAGS = -I$(WORKSPACE)/EmulatorPkg/Unix/Host/X11IncludeHack + XCODE:*_*_IA32_CC_FLAGS = -I$(WORKSPACE)/EmulatorPkg/Unix/Host/X11IncludeHack -Wno-error=unused-but-set-variable XCODE:*_*_IA32_DLINK_FLAGS == -arch i386 -o $(BIN_DIR)/Host -L/usr/X11R6/lib -lXext -lX11 -framework Carbon XCODE:*_*_IA32_ASM_FLAGS == -arch i386 -g XCODE:*_*_X64_DLINK_PATH == gcc - XCODE:*_*_X64_DLINK_FLAGS == -o $(BIN_DIR)/Host -L/usr/X11R6/lib -lXext -lX11 -framework Carbon -Wl,-no_pie - XCODE:*_*_X64_ASM_FLAGS == -g - XCODE:*_*_X64_CC_FLAGS = -O0 -target x86_64-apple-darwin -I$(WORKSPACE)/EmulatorPkg/Unix/Host/X11IncludeHack "-DEFIAPI=__attribute__((ms_abi))" + XCODE:*_*_X64_DLINK_FLAGS == -arch x86_64 -o $(BIN_DIR)/Host -L/usr/X11R6/lib -lXext -lX11 -framework Carbon -Wl,-no_pie + XCODE:*_*_X64_ASM_FLAGS == -arch x86_64 -g + XCODE:*_*_X64_CC_FLAGS = -O0 -target x86_64-apple-darwin -I$(WORKSPACE)/EmulatorPkg/Unix/Host/X11IncludeHack "-DEFIAPI=__attribute__((ms_abi))" -Wno-error=unused-but-set-variable From 607095f8f4c18ef28367cddd49323ed45b648daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Sun, 26 Mar 2023 19:18:40 +0200 Subject: [PATCH 045/341] BaseTools/GenFv: Remove duplicated alignment macros --- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 1f4651c819..f90b36469c 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -54,10 +54,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent (((Imm32) >> 2) & 0x7fffff)) #define ARM_JUMP_TO_THUMB(Offset) _ARM_JUMP_TO_THUMB((Offset) - 8) -#define ALIGN_VALUE_ADDEND(Value, Alignment) (((Alignment) - (Value)) & ((Alignment) - 1U)) -#define ALIGN_VALUE(Value, Alignment) ((Value) + ALIGN_VALUE_ADDEND (Value, Alignment)) -#define IS_ALIGNED(Value, Alignment) (((Value) & ((Alignment) - 1U)) == 0U) - /* * Arm instruction to return from exception (MOVS PC, LR) */ From a52b6a8d8e0419bee7ff6a7e076e4cf2cec4f940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Tue, 28 Mar 2023 00:18:57 +0200 Subject: [PATCH 046/341] EmulatorPkg/Host: Remove orphaned SecImageRead() --- EmulatorPkg/Unix/Host/Host.c | 39 ---------------------------------- EmulatorPkg/Unix/Host/Host.h | 9 -------- EmulatorPkg/Win/Host/WinHost.c | 39 ---------------------------------- EmulatorPkg/Win/Host/WinHost.h | 29 ------------------------- 4 files changed, 116 deletions(-) diff --git a/EmulatorPkg/Unix/Host/Host.c b/EmulatorPkg/Unix/Host/Host.c index 134481b617..aa1e792074 100644 --- a/EmulatorPkg/Unix/Host/Host.c +++ b/EmulatorPkg/Unix/Host/Host.c @@ -842,45 +842,6 @@ CountSeparatorsInString ( return Count; } -EFI_STATUS -EFIAPI -SecImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer - ) - -/*++ - -Routine Description: - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - -Arguments: - FileHandle - The handle to the PE/COFF file - FileOffset - The offset, in bytes, into the file to read - ReadSize - The number of bytes to read from the file starting at FileOffset - Buffer - A pointer to the buffer to read the data into. - -Returns: - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - -**/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINTN Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *)((UINTN)FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} - BOOLEAN IsPdbFile ( IN CONST CHAR8 *PdbFileName diff --git a/EmulatorPkg/Unix/Host/Host.h b/EmulatorPkg/Unix/Host/Host.h index c3b4214f84..a238f57259 100644 --- a/EmulatorPkg/Unix/Host/Host.h +++ b/EmulatorPkg/Unix/Host/Host.h @@ -226,15 +226,6 @@ GetImageReadFunction ( IN EFI_PHYSICAL_ADDRESS *TopOfMemory ); -EFI_STATUS -EFIAPI -SecImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer - ); - CHAR16 * AsciiToUnicode ( IN CHAR8 *Ascii, diff --git a/EmulatorPkg/Win/Host/WinHost.c b/EmulatorPkg/Win/Host/WinHost.c index 9cfeeef693..37aacd3d86 100644 --- a/EmulatorPkg/Win/Host/WinHost.c +++ b/EmulatorPkg/Win/Host/WinHost.c @@ -840,45 +840,6 @@ SecUefiImageGetEntryPoint ( return EFI_SUCCESS; } -EFI_STATUS -EFIAPI -SecImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer - ) - -/*++ - -Routine Description: - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - -Arguments: - FileHandle - The handle to the PE/COFF file - FileOffset - The offset, in bytes, into the file to read - ReadSize - The number of bytes to read from the file starting at FileOffset - Buffer - A pointer to the buffer to read the data into. - -Returns: - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - ---*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINTN Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *)((UINTN)FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} - CHAR16 * AsciiToUnicode ( IN CHAR8 *Ascii, diff --git a/EmulatorPkg/Win/Host/WinHost.h b/EmulatorPkg/Win/Host/WinHost.h index bad2fca5ce..99b04dc0e1 100644 --- a/EmulatorPkg/Win/Host/WinHost.h +++ b/EmulatorPkg/Win/Host/WinHost.h @@ -121,35 +121,6 @@ Routine Description: --*/ ; -EFI_STATUS -EFIAPI -SecImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer - ) - -/*++ - -Routine Description: - - TODO: Add function description - -Arguments: - - FileHandle - TODO: add argument description - FileOffset - TODO: add argument description - ReadSize - TODO: add argument description - Buffer - TODO: add argument description - -Returns: - - TODO: add return values - ---*/ -; - CHAR16 * AsciiToUnicode ( IN CHAR8 *Ascii, From 91526b5ef2414aa991fd23329f81ece486d7711f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Sun, 26 Mar 2023 01:03:31 +0100 Subject: [PATCH 047/341] EmulatorPkg: Fix Thunk PPI/Protocol library types --- EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf | 2 +- EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf b/EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf index 327aab6292..7a05a51109 100644 --- a/EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf +++ b/EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf @@ -15,7 +15,7 @@ FILE_GUID = 465FDE84-E8B0-B04B-A843-A03F68F617A9 MODULE_TYPE = BASE VERSION_STRING = 1.0 - LIBRARY_CLASS = MemoryAllocationLib|SEC BASE USER_DEFINED + LIBRARY_CLASS = ThunkPpiList|SEC BASE USER_DEFINED [Sources] ThunkPpiList.c diff --git a/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf b/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf index 795ee04638..0ae2ae3b7b 100644 --- a/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf +++ b/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf @@ -14,7 +14,7 @@ FILE_GUID = 7833616E-AE0D-594F-870C-80E68682D587 MODULE_TYPE = BASE VERSION_STRING = 1.0 - LIBRARY_CLASS = MemoryAllocationLib|BASE SEC USER_DEFINED + LIBRARY_CLASS = ThunkProtocolList|BASE SEC USER_DEFINED [Sources] ThunkProtocolList.c From f4778d6fdd8dc2fff71d264fd2e178cfcdc810da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Sun, 26 Mar 2023 19:14:01 +0200 Subject: [PATCH 048/341] EmulatorPkg: Fix some image loader related issues --- EmulatorPkg/Include/Protocol/EmuThunk.h | 2 +- .../DxeEmuUefiImageExtraActionLib.c | 2 +- .../PeiEmuUefiImageExtraActionLib.c | 2 +- EmulatorPkg/Unix/Host/Gasket.h | 2 +- EmulatorPkg/Unix/Host/Host.c | 17 ++-- EmulatorPkg/Unix/Host/Host.h | 2 +- EmulatorPkg/Win/Host/WinHost.c | 83 ++++++++++--------- MdeModulePkg/Core/Dxe/Image/Image.c | 3 + 8 files changed, 60 insertions(+), 53 deletions(-) diff --git a/EmulatorPkg/Include/Protocol/EmuThunk.h b/EmulatorPkg/Include/Protocol/EmuThunk.h index ae0dbc95c9..7902d93c6f 100644 --- a/EmulatorPkg/Include/Protocol/EmuThunk.h +++ b/EmulatorPkg/Include/Protocol/EmuThunk.h @@ -96,7 +96,7 @@ EFI_STATUS typedef VOID (EFIAPI *EMU_PE_COFF_RELOCATE_EXTRA_ACTION)( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); typedef diff --git a/EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.c b/EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.c index 246c4d0068..8f8e6f76e4 100644 --- a/EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.c +++ b/EmulatorPkg/Library/DxeEmuUefiImageExtraActionLib/DxeEmuUefiImageExtraActionLib.c @@ -64,7 +64,7 @@ DxeEmuUefiImageLibExtraActionConstructor ( VOID EFIAPI UefiImageLoaderRelocateImageExtraAction ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { if (mThunk != NULL) { diff --git a/EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.c b/EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.c index ce19922aec..9580688acd 100644 --- a/EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.c +++ b/EmulatorPkg/Library/PeiEmuUefiImageExtraActionLib/PeiEmuUefiImageExtraActionLib.c @@ -67,7 +67,7 @@ EmuUefiImageGetThunkStucture ( VOID EFIAPI UefiImageLoaderRelocateImageExtraAction ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { if (EMU_MAGIC_PAGE ()->Thunk == NULL) { diff --git a/EmulatorPkg/Unix/Host/Gasket.h b/EmulatorPkg/Unix/Host/Gasket.h index 6fe28b202b..2c43ad89a5 100644 --- a/EmulatorPkg/Unix/Host/Gasket.h +++ b/EmulatorPkg/Unix/Host/Gasket.h @@ -76,7 +76,7 @@ GasketSecUefiImageGetEntryPoint ( VOID EFIAPI GasketSecUefiImageRelocateImageExtraAction ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); VOID diff --git a/EmulatorPkg/Unix/Host/Host.c b/EmulatorPkg/Unix/Host/Host.c index aa1e792074..b8faa54fdf 100644 --- a/EmulatorPkg/Unix/Host/Host.c +++ b/EmulatorPkg/Unix/Host/Host.c @@ -746,12 +746,15 @@ SecUefiImageGetEntryPoint ( EFI_STATUS Status; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; - Status = UefiImageInitializeContext (&ImageContext, Pe32Data, Pe32Size); + Status = UefiImageInitializeContext (&ImageContext, Pe32Data, Pe32Size); if (EFI_ERROR (Status)) { return Status; } - - // FIXME: Why cannot the Image be in-place already? + // + // FIXME: This modifies the FD data (which is not possible on real platforms) + // and thus re-relocation (i.e., PEIM shadowing) fails badly due to + // not updating ImageBase. + // Status = UefiImageRelocateImageInplaceForExecution (&ImageContext); if (EFI_ERROR (Status)) { return Status; @@ -872,7 +875,7 @@ IsPdbFile ( void PrintLoadAddress ( - IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { EFI_STATUS Status; @@ -925,7 +928,7 @@ SecGdbScriptBreak ( **/ VOID GdbScriptAddImage ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { EFI_STATUS Status; @@ -934,7 +937,7 @@ GdbScriptAddImage ( PrintLoadAddress (ImageContext); - Status = UefiImageGetSymbolsPath ((ImageContext, &PdbPath,) &PdbPathSize); + Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize); if (EFI_ERROR (Status)) { return; } @@ -987,7 +990,7 @@ GdbScriptAddImage ( VOID EFIAPI SecUefiImageRelocateImageExtraAction ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { GdbScriptAddImage (ImageContext); diff --git a/EmulatorPkg/Unix/Host/Host.h b/EmulatorPkg/Unix/Host/Host.h index a238f57259..f564ff19e0 100644 --- a/EmulatorPkg/Unix/Host/Host.h +++ b/EmulatorPkg/Unix/Host/Host.h @@ -267,7 +267,7 @@ SecUefiImageGetEntryPoint ( VOID EFIAPI SecUefiImageRelocateImageExtraAction ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); VOID diff --git a/EmulatorPkg/Win/Host/WinHost.c b/EmulatorPkg/Win/Host/WinHost.c index 37aacd3d86..e7fa542a33 100644 --- a/EmulatorPkg/Win/Host/WinHost.c +++ b/EmulatorPkg/Win/Host/WinHost.c @@ -801,37 +801,21 @@ SecUefiImageGetEntryPoint ( IN OUT VOID **EntryPoint ) { - EFI_STATUS Status; - UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; - VOID *Dest; - UINT32 DestSize; + EFI_STATUS Status; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; - Status = UefiImageInitializeContext (&ImageContext, Pe32Data, Pe32Size); + Status = UefiImageInitializeContext (&ImageContext, Pe32Data, Pe32Size); if (EFI_ERROR (Status)) { return Status; } - // - // Allocate space in NT (not emulator) memory with ReadWrite and Execute attribute. - // Extra space is for alignment + // FIXME: This modifies the FD data (which is not possible on real platforms) + // and thus re-relocation (i.e., PEIM shadowing) fails badly due to + // not updating ImageBase. // - Status = UefiImageLoaderGetDestinationSize(&ImageContext, &DestSize); - if (EFI_ERROR (Status)) { - return Status; - } - - Dest = VirtualAlloc (NULL, (SIZE_T) DestSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - if (Dest == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = UefiImageLoadImage (&ImageContext, Dest, DestSize); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = UefiImageRelocateImage (&ImageContext, (UINTN) Dest, NULL, 0); - if (EFI_ERROR (Status)) { + Status = UefiImageRelocateImageInplaceForExecution (&ImageContext); + if (RETURN_ERROR (Status)) { + DEBUG_RAISE (); return Status; } @@ -842,8 +826,8 @@ SecUefiImageGetEntryPoint ( CHAR16 * AsciiToUnicode ( - IN CHAR8 *Ascii, - IN UINTN *StrLen OPTIONAL + IN CONST CHAR8 *Ascii, + IN UINTN *StrLen OPTIONAL ) /*++ @@ -930,8 +914,8 @@ Routine Description: --*/ EFI_STATUS AddModHandle ( - IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, - IN VOID *ModHandle + IN CONST CHAR8 *PdbPointer, + IN VOID *ModHandle ) { @@ -959,11 +943,11 @@ AddModHandle ( // Make a copy of the string and store the ModHandle // Handle = GetProcessHeap (); - Size = AsciiStrLen (ImageContext->PdbPointer) + 1; + Size = AsciiStrLen (PdbPointer) + 1; Array->PdbPointer = HeapAlloc (Handle, HEAP_ZERO_MEMORY, Size); ASSERT (Array->PdbPointer != NULL); - AsciiStrCpyS (Array->PdbPointer, Size, ImageContext->PdbPointer); + AsciiStrCpyS (Array->PdbPointer, Size, PdbPointer); Array->ModHandle = ModHandle; return EFI_SUCCESS; } @@ -994,7 +978,7 @@ AddModHandle ( return EFI_OUT_OF_RESOURCES; } - return AddModHandle (ImageContext, ModHandle); + return AddModHandle (PdbPointer, ModHandle); } /** @@ -1007,13 +991,13 @@ AddModHandle ( **/ VOID * RemoveModHandle ( - IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN CONST CHAR8 *PdbPointer ) { UINTN Index; PDB_NAME_TO_MOD_HANDLE *Array; - if (ImageContext->PdbPointer == NULL) { + if (PdbPointer == NULL) { // // If no PDB pointer there is no ModHandle so return NULL // @@ -1022,7 +1006,7 @@ RemoveModHandle ( Array = mPdbNameModHandleArray; for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) { - if ((Array->PdbPointer != NULL) && (AsciiStrCmp (Array->PdbPointer, ImageContext->PdbPointer) == 0)) { + if ((Array->PdbPointer != NULL) && (AsciiStrCmp (Array->PdbPointer, PdbPointer) == 0)) { // // If you find a match return it and delete the entry // @@ -1065,6 +1049,8 @@ UefiImageLoaderRelocateImageExtraAction ( UINT32 Flags; DWORD NewProtection; DWORD OldProtection; + CONST CHAR8 *PdbPointer; + UINT32 PdbPointerSize; ASSERT (ImageContext != NULL); // @@ -1078,16 +1064,22 @@ UefiImageLoaderRelocateImageExtraAction ( DllEntryPoint = NULL; + Status = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbPointerSize); + if (RETURN_ERROR (Status)) { + PdbPointer = NULL; + PdbPointerSize = 0; + } + // // Load the DLL if it's not an EBC image. // - if ((ImageContext->PdbPointer != NULL) && + if ((PdbPointer != NULL) && (UefiImageGetMachine (ImageContext) != EFI_IMAGE_MACHINE_EBC)) { // // Convert filename from ASCII to Unicode // - DllFileName = AsciiToUnicode (ImageContext->PdbPointer, &Index); + DllFileName = AsciiToUnicode (PdbPointer, &Index); // // Check that we have a valid filename @@ -1277,12 +1269,12 @@ UefiImageLoaderRelocateImageExtraAction ( } if ((Library != NULL) && (DllEntryPoint != NULL)) { - Status = AddModHandle (ImageContext, Library); + Status = AddModHandle (PdbPointer, Library); if ((Status == EFI_SUCCESS) || (Status == EFI_ALREADY_STARTED)) { // // This DLL is either not loaded or already started, so source level debugging is supported. // - ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)DllEntryPoint; + ImageContext->ImageBuffer = (VOID *)((UINTN)DllEntryPoint - UefiImageGetEntryPointAddress (ImageContext)); SecPrint ("LoadLibraryEx (\n\r %S,\n\r NULL, DONT_RESOLVE_DLL_REFERENCES) @ 0x%X\n\r", DllFileName, (int)(UINTN)Library); } } else { @@ -1300,13 +1292,22 @@ UefiImageLoaderUnloadImageExtraAction ( ) { VOID *ModHandle; + RETURN_STATUS Status; + CONST CHAR8 *PdbPointer; + UINT32 PdbPointerSize; ASSERT (ImageContext != NULL); - ModHandle = RemoveModHandle (ImageContext); + Status = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbPointerSize); + if (RETURN_ERROR (Status)) { + PdbPointer = NULL; + PdbPointerSize = 0; + } + + ModHandle = RemoveModHandle (PdbPointer); if (ModHandle != NULL) { FreeLibrary (ModHandle); - SecPrint ("FreeLibrary (\n\r %s)\n\r", ImageContext->PdbPointer); + SecPrint ("FreeLibrary (\n\r %s)\n\r", PdbPointer); } else { SecPrint ("WARNING: Unload image without source level debug\n\r"); } diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 818b7fb513..948d3478ee 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -233,6 +233,9 @@ CoreInitializeImageServices ( // Image = &mCorePrivateImage; + // + // FIXME: This is not a proper solution, because DxeCore may not be XIP + // Status = UefiImageInitializeContext ( ImageContext, (VOID *) (UINTN) DxeCoreImageBaseAddress, From 473ab073026ae3ecb798ab28cfc85d83251f8e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Fri, 17 Mar 2023 22:45:33 +0100 Subject: [PATCH 049/341] BaseTools/GenFvInternalLib: Remove unused BaseOfCode parameter --- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 11 ----------- BaseTools/Source/C/GenFv/GenFvInternalLib.h | 1 - 2 files changed, 12 deletions(-) diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index f90b36469c..53c601082b 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -1526,7 +1526,6 @@ Routine Description: EFI_STATUS Status; EFI_FILE_SECTION_POINTER Pe32Section; UINT32 EntryPoint; - UINT32 BaseOfCode; UINT16 MachineType; EFI_PHYSICAL_ADDRESS PeiCorePhysicalAddress; EFI_PHYSICAL_ADDRESS SecCorePhysicalAddress; @@ -1602,7 +1601,6 @@ Routine Description: Status = GetPe32Info ( (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize), &EntryPoint, - &BaseOfCode, &MachineType ); @@ -1655,7 +1653,6 @@ Routine Description: Status = GetPe32Info ( (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize), &EntryPoint, - &BaseOfCode, &MachineType ); @@ -1897,7 +1894,6 @@ Routine Description: { EFI_STATUS Status; UINT32 EntryPoint; - UINT32 BaseOfCode; if (CoreMachineType == NULL) { return EFI_INVALID_PARAMETER; @@ -1906,7 +1902,6 @@ Routine Description: Status = GetPe32Info( (VOID *)((UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)), &EntryPoint, - &BaseOfCode, CoreMachineType ); if (EFI_ERROR(Status)) { @@ -1947,7 +1942,6 @@ Routine Description: { EFI_STATUS Status; UINT32 EntryPoint; - UINT32 BaseOfCode; UINT16 MachineType; EFI_PHYSICAL_ADDRESS EntryPhysicalAddress; @@ -1958,7 +1952,6 @@ Routine Description: Status = GetPe32Info( (VOID *)((UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)), &EntryPoint, - &BaseOfCode, &MachineType ); if (EFI_ERROR(Status)) { @@ -2407,7 +2400,6 @@ EFI_STATUS GetPe32Info ( IN UINT8 *Pe32, OUT UINT32 *EntryPoint, - OUT UINT32 *BaseOfCode, OUT UINT16 *MachineType ) /*++ @@ -2422,7 +2414,6 @@ Routine Description: Pe32 Beginning of the PE32. EntryPoint Offset from the beginning of the PE32 to the image entry point. - BaseOfCode Base address of code. MachineType Magic number for the machine type. Returns: @@ -2454,7 +2445,6 @@ Routine Description: // By TeImage Header to get output // *EntryPoint = TeHeader->AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader->StrippedSize; - *BaseOfCode = TeHeader->BaseOfCode + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader->StrippedSize; *MachineType = TeHeader->Machine; } else { @@ -2487,7 +2477,6 @@ Routine Description: // Get output // *EntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint; - *BaseOfCode = ImgHdr->Pe32.OptionalHeader.BaseOfCode; *MachineType = ImgHdr->Pe32.FileHeader.Machine; } diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.h b/BaseTools/Source/C/GenFv/GenFvInternalLib.h index 7bace6ad36..dc6b2aca91 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.h +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.h @@ -307,7 +307,6 @@ EFI_STATUS GetPe32Info ( IN UINT8 *Pe32, OUT UINT32 *EntryPoint, - OUT UINT32 *BaseOfCode, OUT UINT16 *MachineType ); From d11ca287c5025872b232190196acf0b3ec7f942c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Wed, 29 Mar 2023 21:54:43 +0200 Subject: [PATCH 050/341] MdeModulePkg/CorePei: Remove unused ShadowedImageRead member --- MdeModulePkg/Core/Pei/PeiMain.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h index 278b6692da..9a89e71b03 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.h +++ b/MdeModulePkg/Core/Pei/PeiMain.h @@ -308,10 +308,6 @@ struct _PEI_CORE_INSTANCE { // available or not. // UINT64 *PeiCodeMemoryRangeUsageBitMap; - // - // This field points to the shadowed image read function - // - VOID *ShadowedImageRead; UINTN TempPeimCount; From 97a45f46339c20192500fe7869b1c1d72120f026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Wed, 29 Mar 2023 21:55:23 +0200 Subject: [PATCH 051/341] EmulatorPkg/Host: Remove orphaned GetImageReadFunction() --- EmulatorPkg/Unix/Host/Host.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/EmulatorPkg/Unix/Host/Host.h b/EmulatorPkg/Unix/Host/Host.h index f564ff19e0..eb7f340dba 100644 --- a/EmulatorPkg/Unix/Host/Host.h +++ b/EmulatorPkg/Unix/Host/Host.h @@ -220,12 +220,6 @@ GasketSecUnixFdAddress ( ) ; -EFI_STATUS -GetImageReadFunction ( - IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, - IN EFI_PHYSICAL_ADDRESS *TopOfMemory - ); - CHAR16 * AsciiToUnicode ( IN CHAR8 *Ascii, From 78c65024de230395d8af5f8e48f61f8ca2943a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Thu, 30 Mar 2023 16:12:39 +0200 Subject: [PATCH 052/341] MdePkg/Base.h: Introduce ALIGN_VALUE_SUBTRAHEND --- MdePkg/Include/Base.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h index 469161b4b9..2e0d68fa7e 100644 --- a/MdePkg/Include/Base.h +++ b/MdePkg/Include/Base.h @@ -907,6 +907,17 @@ STATIC_ASSERT (ALIGNOF (__VERIFY_INT32_ENUM_SIZE) == sizeof (__VERIFY_INT32_ENUM **/ #define IS_POW2(Value) ((Value) != 0U && ((Value) & ((Value) - 1U)) == 0U) +/** + Determines the subtrahend to subtract from a value to round it down to the + previous boundary of a specified alignment. + + @param Value The value to round down. + @param Alignment The alignment boundary used to return the subtrahend. + + @return Subtrahend to round Value down to alignment boundary Alignment. +**/ +#define ALIGN_VALUE_SUBTRAHEND(Value, Alignment) ((Value) & ((Alignment) - 1U)) + /** Checks whether a value is aligned by a specified alignment. @@ -916,7 +927,7 @@ STATIC_ASSERT (ALIGNOF (__VERIFY_INT32_ENUM_SIZE) == sizeof (__VERIFY_INT32_ENUM @retval TRUE Value is aligned by Alignment. @retval FALSE Value is not aligned by Alignment. **/ -#define IS_ALIGNED(Value, Alignment) (((Value) & ((Alignment) - 1U)) == 0U) +#define IS_ALIGNED(Value, Alignment) (ALIGN_VALUE_SUBTRAHEND (Value, Alignment) == 0U) /** Checks whether a pointer or address is aligned by a specified alignment. From 3cad7a6524d526b2399d8066ed18b38ed6af311f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Thu, 30 Mar 2023 16:13:58 +0200 Subject: [PATCH 053/341] MdeModulePkg: Manage MemoryProfileLib separately --- .../BaseMemoryProfileLibNull.c} | 4 +- .../BaseMemoryProfileLibNull.inf | 32 + .../BaseMemoryProfileLibNull.uni | 14 + .../DxeCoreMemoryAllocationLib.inf | 2 +- .../DxeCoreMemoryAllocationProfileLib.inf | 13 +- .../DxeCoreMemoryAllocationProfileLib.uni | 10 +- .../MemoryAllocationLib.c | 21 + .../PiSmmCoreMemoryAllocationLib.inf | 7 +- .../PiSmmCoreMemoryAllocationProfileLib.inf | 11 +- .../PiSmmCoreMemoryAllocationProfileLib.uni | 12 +- .../PiSmmCoreMemoryProfileLibNull.c | 47 - .../MemoryAllocationLib.c | 1160 ----------------- .../SmmMemoryAllocationProfileLib.inf | 15 +- .../SmmMemoryAllocationProfileLib.uni | 11 +- .../MemoryAllocationLib.c | 1076 --------------- .../UefiMemoryAllocationProfileLib.inf | 12 +- .../UefiMemoryAllocationProfileLib.uni | 10 +- MdePkg/MdeLibs.dsc.inc | 2 + 18 files changed, 102 insertions(+), 2357 deletions(-) rename MdeModulePkg/Library/{DxeCoreMemoryAllocationLib/DxeCoreMemoryProfileLibNull.c => BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.c} (93%) create mode 100644 MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.inf create mode 100644 MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.uni create mode 100644 MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c delete mode 100644 MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryProfileLibNull.c delete mode 100644 MdeModulePkg/Library/SmmMemoryAllocationProfileLib/MemoryAllocationLib.c delete mode 100644 MdeModulePkg/Library/UefiMemoryAllocationProfileLib/MemoryAllocationLib.c diff --git a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryProfileLibNull.c b/MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.c similarity index 93% rename from MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryProfileLibNull.c rename to MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.c index 01f9210777..b11b5db112 100644 --- a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryProfileLibNull.c +++ b/MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.c @@ -1,12 +1,12 @@ /** @file - Null routines for memory profile for DxeCore. + Null routines for memory profile. Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include +#include #include diff --git a/MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.inf b/MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.inf new file mode 100644 index 0000000000..caa82ac2d1 --- /dev/null +++ b/MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.inf @@ -0,0 +1,32 @@ +## @file +# Memory Profile Library Null instance. +# +# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseMemoryProfileLibNull + MODULE_UNI_FILE = BaseMemoryProfileLibNull.uni + FILE_GUID = 888809d7-e5c5-4848-b8b9-f920a7b89ce1 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = MemoryProfileLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + BaseMemoryProfileLibNull.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + diff --git a/MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.uni b/MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.uni new file mode 100644 index 0000000000..31339032e5 --- /dev/null +++ b/MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.uni @@ -0,0 +1,14 @@ +// /** @file +// Memory Profile Library Null instance. +// +// Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Memory Profile Library Null instance" + +#string STR_MODULE_DESCRIPTION #language en-US "Memory Profile Library Null instance." + diff --git a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf index 199da4ba65..cd5515ee52 100644 --- a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf +++ b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf @@ -29,7 +29,6 @@ [Sources] MemoryAllocationLib.c DxeCoreMemoryAllocationServices.h - DxeCoreMemoryProfileLibNull.c [Packages] MdePkg/MdePkg.dec @@ -38,3 +37,4 @@ [LibraryClasses] DebugLib BaseMemoryLib + MemoryProfileLib diff --git a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationProfileLib.inf b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationProfileLib.inf index 987e1cd9ce..5f3c5c3ef4 100644 --- a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationProfileLib.inf +++ b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationProfileLib.inf @@ -1,7 +1,7 @@ ## @file -# Memory Allocation/Profile Library instance dedicated to DXE Core. -# The implementation borrows the DxeCore Memory Allocation/profile services as the primitive -# for memory allocation/profile instead of using UEFI boot services or memory profile protocol in an indirect way. +# Memory Profile Library instance dedicated to DXE Core. +# The implementation borrows the DxeCore Memory profile services as the primitive +# for memory profile instead of using UEFI boot services or memory profile protocol in an indirect way. # It is assumed that this library instance must be linked with DxeCore in this package. # # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
@@ -18,7 +18,6 @@ FILE_GUID = 7ADD7147-74E8-4583-BE34-B6BC45353BB5 MODULE_TYPE = DXE_CORE VERSION_STRING = 1.0 - LIBRARY_CLASS = MemoryAllocationLib|DXE_CORE LIBRARY_CLASS = MemoryProfileLib|DXE_CORE # @@ -28,8 +27,6 @@ # [Sources] - MemoryAllocationLib.c - DxeCoreMemoryAllocationServices.h DxeCoreMemoryProfileLib.c DxeCoreMemoryProfileServices.h @@ -37,7 +34,3 @@ MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec -[LibraryClasses] - DebugLib - BaseMemoryLib - diff --git a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationProfileLib.uni b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationProfileLib.uni index 089cfb33c9..1c558bd577 100644 --- a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationProfileLib.uni +++ b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationProfileLib.uni @@ -1,8 +1,8 @@ // /** @file -// Memory Allocation/Profile Library instance dedicated to DXE Core. +// Memory Profile Library instance dedicated to DXE Core. // -// The implementation borrows the DxeCore Memory Allocation/Profile services as the primitive -// for memory allocation/profile instead of using UEFI boot services or memory profile protocol in an indirect way. +// The implementation borrows the DxeCore Memory Profile services as the primitive +// for memory profile instead of using UEFI boot services or memory profile protocol in an indirect way. // It is assumed that this library instance must be linked with DxeCore in this package. // // Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.
@@ -12,7 +12,7 @@ // **/ -#string STR_MODULE_ABSTRACT #language en-US "Memory Allocation/Profile Library instance dedicated to DXE Core" +#string STR_MODULE_ABSTRACT #language en-US "Memory Profile Library instance dedicated to DXE Core" -#string STR_MODULE_DESCRIPTION #language en-US "The implementation borrows the DxeCore Memory Allocation/Profile services as the primitive for memory allocation/profile instead of using UEFI boot services or memory profile protocol in an indirect way. It is assumed that this library instance must be linked with DxeCore in this package." +#string STR_MODULE_DESCRIPTION #language en-US "The implementation borrows the DxeCore Memory Profile services as the primitive for memory profile instead of using UEFI boot services or memory profile protocol in an indirect way. It is assumed that this library instance must be linked with DxeCore in this package." diff --git a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c new file mode 100644 index 0000000000..adad6b651e --- /dev/null +++ b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c @@ -0,0 +1,21 @@ +/** @file + Support routines for memory allocation routines based on SMM Core internal functions, + with memory profile support. + + The PI System Management Mode Core Interface Specification only allows the use + of EfiRuntimeServicesCode and EfiRuntimeServicesData memory types for memory + allocations as the SMRAM space should be reserved after BDS phase. The functions + in the Memory Allocation Library use EfiBootServicesData as the default memory + allocation type. For this SMM specific instance of the Memory Allocation Library, + EfiRuntimeServicesData is used as the default memory type for all allocations. + In addition, allocation for the Reserved memory types are not supported and will + always return NULL. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +// +// The required functions are defined by PiSmmCore itself. +// diff --git a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf index 8812c96041..9bb3aaef02 100644 --- a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf +++ b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf @@ -31,13 +31,10 @@ # [Sources] - PiSmmCoreMemoryProfileLibNull.c + MemoryAllocationLib.c [Packages] MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec [LibraryClasses] - DebugLib - BaseMemoryLib - UefiBootServicesTableLib + MemoryProfileLib diff --git a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationProfileLib.inf b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationProfileLib.inf index c3b8a4fdce..04306f82b8 100644 --- a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationProfileLib.inf +++ b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationProfileLib.inf @@ -1,8 +1,8 @@ ## @file -# Memory Allocation/Profile Library instance dedicated to SMM Core. -# The implementation borrows the SMM Core Memory Allocation/Profile services as the primitive -# for memory allocation/profile instead of using SMM System Table servces or SMM memory profile protocol in an indirect way. -# It is assumed that this library instance must be linked with SMM Cre in this package. +# Memory Profile Library instance dedicated to SMM Core. +# The implementation borrows the SMM Core Memory Profile services as the primitive +# for memory profile instead of using SMM System Table services or SMM memory profile protocol in an indirect way. +# It is assumed that this library instance must be linked with SMM Core in this package. # # Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
# @@ -18,7 +18,6 @@ MODULE_TYPE = SMM_CORE VERSION_STRING = 1.0 PI_SPECIFICATION_VERSION = 0x0001000A - LIBRARY_CLASS = MemoryAllocationLib|SMM_CORE # # This function is defined in PiSmmCore. # @@ -42,9 +41,7 @@ [LibraryClasses] DebugLib - BaseMemoryLib UefiBootServicesTableLib - MemoryAllocationLib [Guids] gEdkiiMemoryProfileGuid ## SOMETIMES_CONSUMES ## GUID # Locate protocol diff --git a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationProfileLib.uni b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationProfileLib.uni index 479c07941c..708fb8e83c 100644 --- a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationProfileLib.uni +++ b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationProfileLib.uni @@ -1,9 +1,9 @@ // /** @file -// Memory Allocation/Profile Library instance dedicated to SMM Core. +// Memory Profile Library instance dedicated to SMM Core. // -// The implementation borrows the SMM Core Memory Allocation/Profile services as the primitive -// for memory allocation/profile instead of using SMM System Table servces or SMM memory profile protocol in an indirect way. -// It is assumed that this library instance must be linked with SMM Cre in this package. +// The implementation borrows the SMM Core Memory Profile services as the primitive +// for memory profile instead of using SMM System Table services or SMM memory profile protocol in an indirect way. +// It is assumed that this library instance must be linked with SMM Core in this package. // // Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
// @@ -12,7 +12,7 @@ // **/ -#string STR_MODULE_ABSTRACT #language en-US "Memory Allocation/Profile Library instance dedicated to SMM Core" +#string STR_MODULE_ABSTRACT #language en-US "Memory Profile Library instance dedicated to SMM Core" -#string STR_MODULE_DESCRIPTION #language en-US "The implementation borrows the SMM Core Memory Allocation/Profile services as the primitive for memory allocation/profile instead of using SMM System Table services or SMM memory profile protocol in an indirect way. This library is only intended to be linked with the SMM Core that resides in this same package." +#string STR_MODULE_DESCRIPTION #language en-US "The implementation borrows the SMM Core Memory Profile services as the primitive for memory profile instead of using SMM System Table services or SMM memory profile protocol in an indirect way. This library is only intended to be linked with the SMM Core that resides in this same package." diff --git a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryProfileLibNull.c b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryProfileLibNull.c deleted file mode 100644 index 22b2cf883a..0000000000 --- a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryProfileLibNull.c +++ /dev/null @@ -1,47 +0,0 @@ -/** @file - Null routines for memory profile for PiSmmCore. - - Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include - -/** - Record memory profile of multilevel caller. - - @param[in] CallerAddress Address of caller. - @param[in] Action Memory profile action. - @param[in] MemoryType Memory type. - EfiMaxMemoryType means the MemoryType is unknown. - @param[in] Buffer Buffer address. - @param[in] Size Buffer size. - @param[in] ActionString String for memory profile action. - Only needed for user defined allocate action. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required, - or memory profile for the memory type is not required. - @return EFI_ACCESS_DENIED It is during memory profile data getting. - @return EFI_ABORTED Memory profile recording is not enabled. - @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. - @return EFI_NOT_FOUND No matched allocate info found for free action. - -**/ -EFI_STATUS -EFIAPI -MemoryProfileLibRecord ( - IN PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, - IN VOID *Buffer, - IN UINTN Size, - IN CHAR8 *ActionString OPTIONAL - ) -{ - return EFI_UNSUPPORTED; -} diff --git a/MdeModulePkg/Library/SmmMemoryAllocationProfileLib/MemoryAllocationLib.c b/MdeModulePkg/Library/SmmMemoryAllocationProfileLib/MemoryAllocationLib.c deleted file mode 100644 index 17c380a1d8..0000000000 --- a/MdeModulePkg/Library/SmmMemoryAllocationProfileLib/MemoryAllocationLib.c +++ /dev/null @@ -1,1160 +0,0 @@ -/** @file - Support routines for memory allocation routines based - on SMM Services Table services for SMM phase drivers, with memory profile support. - - The PI System Management Mode Core Interface Specification only allows the use - of EfiRuntimeServicesCode and EfiRuntimeServicesData memory types for memory - allocations through the SMM Services Table as the SMRAM space should be - reserved after BDS phase. The functions in the Memory Allocation Library use - EfiBootServicesData as the default memory allocation type. For this SMM - specific instance of the Memory Allocation Library, EfiRuntimeServicesData - is used as the default memory type for all allocations. In addition, - allocation for the Reserved memory types are not supported and will always - return NULL. - - Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include -#include -#include -#include -#include -#include - -#include - -EFI_SMRAM_DESCRIPTOR *mSmramRanges; -UINTN mSmramRangeCount; - -/** - The constructor function caches SMRAM ranges that are present in the system. - - It will ASSERT() if SMM Access2 Protocol doesn't exist. - It will ASSERT() if SMRAM ranges can't be got. - It will ASSERT() if Resource can't be allocated for cache SMRAM range. - It will always return EFI_SUCCESS. - - @param ImageHandle The firmware allocated handle for the EFI image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. - -**/ -EFI_STATUS -EFIAPI -SmmMemoryAllocationLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - EFI_SMM_ACCESS2_PROTOCOL *SmmAccess; - UINTN Size; - - // - // Locate SMM Access2 Protocol - // - Status = gBS->LocateProtocol ( - &gEfiSmmAccess2ProtocolGuid, - NULL, - (VOID **)&SmmAccess - ); - ASSERT_EFI_ERROR (Status); - - // - // Get SMRAM range information - // - Size = 0; - Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); - - mSmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocatePool (Size); - ASSERT (mSmramRanges != NULL); - - Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges); - ASSERT_EFI_ERROR (Status); - - mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR); - - return EFI_SUCCESS; -} - -/** - If SMM driver exits with an error, it must call this routine - to free the allocated resource before the exiting. - - @param[in] ImageHandle The firmware allocated handle for the EFI image. - @param[in] SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The deconstructor always returns EFI_SUCCESS. -**/ -EFI_STATUS -EFIAPI -SmmMemoryAllocationLibDestructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - FreePool (mSmramRanges); - - return EFI_SUCCESS; -} - -/** - Check whether the start address of buffer is within any of the SMRAM ranges. - - @param[in] Buffer The pointer to the buffer to be checked. - - @retval TRUE The buffer is in SMRAM ranges. - @retval FALSE The buffer is out of SMRAM ranges. -**/ -BOOLEAN -EFIAPI -BufferInSmram ( - IN VOID *Buffer - ) -{ - UINTN Index; - - for (Index = 0; Index < mSmramRangeCount; Index++) { - if (((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer >= mSmramRanges[Index].CpuStart) && - ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer < (mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize))) - { - return TRUE; - } - } - - return FALSE; -} - -/** - Allocates one or more 4KB pages of a certain memory type. - - Allocates the number of 4KB pages of a certain memory type and returns a pointer - to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If - Pages is 0, then NULL is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param MemoryType The type of memory to allocate. - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - - if (Pages == 0) { - return NULL; - } - - Status = gSmst->SmmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer - to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If - Pages is 0, then NULL is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a - pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary. - If Pages is 0, then NULL is returned. If there is not enough memory remaining - to satisfy the request, then NULL is returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a - pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary. - If Pages is 0, then NULL is returned. If there is not enough memory remaining - to satisfy the request, then NULL is returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return NULL; -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the page allocation - functions in the Memory Allocation Library. - - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. - Buffer must have been allocated on a previous call to the page allocation services - of the Memory Allocation Library. If it is not possible to free allocated pages, - then this function will perform no actions. - - If Buffer was not allocated with a page allocation function in the Memory Allocation - Library, then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - if (BufferInSmram (Buffer)) { - // - // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service. - // So, gSmst->SmmFreePages() service is used to free it. - // - Status = gSmst->SmmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - } else { - // - // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service. - // So, gBS->FreePages() service is used to free it. - // - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - } - - ASSERT_EFI_ERROR (Status); -} - -/** - Allocates one or more 4KB pages of a certain memory type at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of a certain memory type - with an alignment specified by Alignment. The allocated buffer is returned. - If Pages is 0, then NULL is returned. If there is not enough memory at the - specified alignment remaining to satisfy the request, then NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param MemoryType The type of memory to allocate. - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = gSmst->SmmAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = gSmst->SmmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = gSmst->SmmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = gSmst->SmmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData - with an alignment specified by Alignment. The allocated buffer is returned. - If Pages is 0, then NULL is returned. If there is not enough memory at the - specified alignment remaining to satisfy the request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData - with an alignment specified by Alignment. The allocated buffer is returned. - If Pages is 0, then NULL is returned. If there is not enough memory at the - specified alignment remaining to satisfy the request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType - with an alignment specified by Alignment. The allocated buffer is returned. - If Pages is 0, then NULL is returned. If there is not enough memory at the - specified alignment remaining to satisfy the request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return NULL; -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the aligned page - allocation functions in the Memory Allocation Library. - - Frees the number of 4KB pages specified by Pages from the buffer specified by - Buffer. Buffer must have been allocated on a previous call to the aligned page - allocation services of the Memory Allocation Library. If it is not possible to - free allocated pages, then this function will perform no actions. - - If Buffer was not allocated with an aligned page allocation function in the - Memory Allocation Library, then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - if (BufferInSmram (Buffer)) { - // - // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service. - // So, gSmst->SmmFreePages() service is used to free it. - // - Status = gSmst->SmmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - } else { - // - // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service. - // So, gBS->FreePages() service is used to free it. - // - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - } - - ASSERT_EFI_ERROR (Status); -} - -/** - Allocates a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type - and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param MemoryType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocatePool ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN AllocationSize - ) -{ - EFI_STATUS Status; - VOID *Memory; - - Status = gSmst->SmmAllocatePool (MemoryType, AllocationSize, &Memory); - if (EFI_ERROR (Status)) { - Memory = NULL; - } - - return Memory; -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData - and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData - and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType - and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, - clears the buffer with zeros, and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is - not enough memory remaining to satisfy the request, then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, - clears the buffer with zeros, and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is - not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, - clears the buffer with zeros, and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is - not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, - clears the buffer with zeros, and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is - not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, - copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer - of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, - copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer - of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL, - EfiRuntimeServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, - copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer - of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL, - EfiRuntimeServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, - copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer - of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return NULL; -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize - and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize - and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL, - EfiRuntimeServicesData, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize - and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize - and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL, - EfiRuntimeServicesData, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize - and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize - and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return NULL; -} - -/** - Frees a buffer that was previously allocated with one of the pool allocation - functions in the Memory Allocation Library. - - Frees the buffer specified by Buffer. Buffer must have been allocated on a - previous call to the pool allocation services of the Memory Allocation Library. - If it is not possible to free pool resources, then this function will perform - no actions. - - If Buffer was not allocated with a pool allocation function in the Memory - Allocation Library, then ASSERT(). - - @param Buffer The pointer to the buffer to free. - -**/ -VOID -EFIAPI -FreePool ( - IN VOID *Buffer - ) -{ - EFI_STATUS Status; - - if (BufferInSmram (Buffer)) { - // - // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePool() service. - // So, gSmst->SmmFreePool() service is used to free it. - // - Status = gSmst->SmmFreePool (Buffer); - } else { - // - // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service. - // So, gBS->FreePool() service is used to free it. - // - Status = gBS->FreePool (Buffer); - } - - ASSERT_EFI_ERROR (Status); -} diff --git a/MdeModulePkg/Library/SmmMemoryAllocationProfileLib/SmmMemoryAllocationProfileLib.inf b/MdeModulePkg/Library/SmmMemoryAllocationProfileLib/SmmMemoryAllocationProfileLib.inf index 3e29a8caf3..fb7c3c026d 100644 --- a/MdeModulePkg/Library/SmmMemoryAllocationProfileLib/SmmMemoryAllocationProfileLib.inf +++ b/MdeModulePkg/Library/SmmMemoryAllocationProfileLib/SmmMemoryAllocationProfileLib.inf @@ -1,12 +1,6 @@ ## @file -# Instance of Memory Allocation Library using SMM Services Table, -# with memory profile support. -# -# Memory Allocation Library that uses services from the SMM Services Table to -# allocate and free memory, with memory profile support. -# -# The implementation of this instance is copied from UefiMemoryAllocationLib -# in MdePkg and updated to support both MemoryAllocationLib and MemoryProfileLib. +# Instance of Memory Profile Library using the EDK II SMM Memory Profile +# Protocol. # # Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent @@ -21,9 +15,6 @@ MODULE_TYPE = DXE_SMM_DRIVER VERSION_STRING = 1.0 PI_SPECIFICATION_VERSION = 0x0001000A - LIBRARY_CLASS = MemoryAllocationLib|DXE_SMM_DRIVER - CONSTRUCTOR = SmmMemoryAllocationLibConstructor - DESTRUCTOR = SmmMemoryAllocationLibDestructor LIBRARY_CLASS = MemoryProfileLib|DXE_SMM_DRIVER CONSTRUCTOR = SmmMemoryProfileLibConstructor @@ -32,7 +23,6 @@ # [Sources] - MemoryAllocationLib.c SmmMemoryProfileLib.c [Packages] @@ -41,7 +31,6 @@ [LibraryClasses] DebugLib - BaseMemoryLib SmmServicesTableLib UefiBootServicesTableLib diff --git a/MdeModulePkg/Library/SmmMemoryAllocationProfileLib/SmmMemoryAllocationProfileLib.uni b/MdeModulePkg/Library/SmmMemoryAllocationProfileLib/SmmMemoryAllocationProfileLib.uni index 3fae263725..e70e66a43b 100644 --- a/MdeModulePkg/Library/SmmMemoryAllocationProfileLib/SmmMemoryAllocationProfileLib.uni +++ b/MdeModulePkg/Library/SmmMemoryAllocationProfileLib/SmmMemoryAllocationProfileLib.uni @@ -1,9 +1,6 @@ // /** @file -// Instance of Memory Allocation Library using SMM Services Table, -// with memory profile support. -// -// Memory Allocation Library that uses services from the SMM Services Table to -// allocate and free memory, with memory profile support. +// Instance of Memory Profile Library using the EDK II SMM Memory Profile +// Protocol. // // Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
// @@ -12,7 +9,7 @@ // **/ -#string STR_MODULE_ABSTRACT #language en-US "Instance of Memory Allocation Library using SMM Services Table, with memory profile support" +#string STR_MODULE_ABSTRACT #language en-US "Instance of Memory Profile Library using the EDK II SMM Memory Profile Protocol" -#string STR_MODULE_DESCRIPTION #language en-US "This Memory Allocation Library uses services from the SMM Services Table to allocate and free memory, with memory profile support." +#string STR_MODULE_DESCRIPTION #language en-US "Instance of Memory Profile Library using the EDK II SMM Memory Profile Protocol." diff --git a/MdeModulePkg/Library/UefiMemoryAllocationProfileLib/MemoryAllocationLib.c b/MdeModulePkg/Library/UefiMemoryAllocationProfileLib/MemoryAllocationLib.c deleted file mode 100644 index 38c95b9eb7..0000000000 --- a/MdeModulePkg/Library/UefiMemoryAllocationProfileLib/MemoryAllocationLib.c +++ /dev/null @@ -1,1076 +0,0 @@ -/** @file - Support routines for memory allocation routines based - on boot services for Dxe phase drivers, with memory profile support. - - Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include - -#include -#include -#include -#include - -#include - -/** - Allocates one or more 4KB pages of a certain memory type. - - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param MemoryType The type of memory to allocate. - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - - if (Pages == 0) { - return NULL; - } - - Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiBootServicesData, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES, - EfiBootServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiReservedMemoryType, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES, - EfiReservedMemoryType, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the page allocation - functions in the Memory Allocation Library. - - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with a page allocation function in the Memory Allocation Library, - then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); -} - -/** - Allocates one or more 4KB pages of a certain memory type at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment - specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned. - If there is not enough memory at the specified alignment remaining to satisfy the request, then - NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param MemoryType The type of memory to allocate. - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = gBS->FreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = gBS->FreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES, - EfiBootServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES, - EfiReservedMemoryType, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the aligned page - allocation functions in the Memory Allocation Library. - - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the aligned page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with an aligned page allocation function in the Memory Allocation - Library, then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); -} - -/** - Allocates a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param MemoryType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocatePool ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN AllocationSize - ) -{ - EFI_STATUS Status; - VOID *Memory; - - Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory); - if (EFI_ERROR (Status)) { - Memory = NULL; - } - - return Memory; -} - -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiBootServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL, - EfiBootServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiReservedMemoryType, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL, - EfiReservedMemoryType, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiBootServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL, - EfiBootServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL, - EfiReservedMemoryType, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL, - EfiBootServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL, - EfiRuntimeServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL, - EfiRuntimeServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL, - EfiBootServicesData, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL, - EfiRuntimeServicesData, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL, - EfiReservedMemoryType, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - -/** - Frees a buffer that was previously allocated with one of the pool allocation functions in the - Memory Allocation Library. - - Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the - pool allocation services of the Memory Allocation Library. If it is not possible to free pool - resources, then this function will perform no actions. - - If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, - then ASSERT(). - - @param Buffer The pointer to the buffer to free. - -**/ -VOID -EFIAPI -FreePool ( - IN VOID *Buffer - ) -{ - EFI_STATUS Status; - - Status = gBS->FreePool (Buffer); - ASSERT_EFI_ERROR (Status); -} diff --git a/MdeModulePkg/Library/UefiMemoryAllocationProfileLib/UefiMemoryAllocationProfileLib.inf b/MdeModulePkg/Library/UefiMemoryAllocationProfileLib/UefiMemoryAllocationProfileLib.inf index 553e876e44..8ac7bf6f4c 100644 --- a/MdeModulePkg/Library/UefiMemoryAllocationProfileLib/UefiMemoryAllocationProfileLib.inf +++ b/MdeModulePkg/Library/UefiMemoryAllocationProfileLib/UefiMemoryAllocationProfileLib.inf @@ -1,12 +1,5 @@ ## @file -# Instance of Memory Allocation Library using EFI Boot Services, -# with memory profile support. -# -# Memory Allocation Library that uses EFI Boot Services to allocate -# and free memory, with memory profile support. -# -# The implementation of this instance is copied from UefiMemoryAllocationLib -# in MdePkg and updated to support both MemoryAllocationLib and MemoryProfileLib. +# Instance of Memory Profile Library using the EDK II Memory Profile Protocol. # # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
# @@ -22,7 +15,6 @@ FILE_GUID = 9E8A380A-231E-41E4-AD40-5E706196B853 MODULE_TYPE = UEFI_DRIVER VERSION_STRING = 1.0 - LIBRARY_CLASS = MemoryAllocationLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER LIBRARY_CLASS = MemoryProfileLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER CONSTRUCTOR = MemoryProfileLibConstructor @@ -31,7 +23,6 @@ # [Sources] - MemoryAllocationLib.c DxeMemoryProfileLib.c [Packages] @@ -40,7 +31,6 @@ [LibraryClasses] DebugLib - BaseMemoryLib UefiBootServicesTableLib [Guids] diff --git a/MdeModulePkg/Library/UefiMemoryAllocationProfileLib/UefiMemoryAllocationProfileLib.uni b/MdeModulePkg/Library/UefiMemoryAllocationProfileLib/UefiMemoryAllocationProfileLib.uni index e0f369de34..185efeb23f 100644 --- a/MdeModulePkg/Library/UefiMemoryAllocationProfileLib/UefiMemoryAllocationProfileLib.uni +++ b/MdeModulePkg/Library/UefiMemoryAllocationProfileLib/UefiMemoryAllocationProfileLib.uni @@ -1,9 +1,5 @@ // /** @file -// Instance of Memory Allocation Library using EFI Boot Services, -// with memory profile support. -// -// Memory Allocation Library that uses EFI Boot Services to allocate -// and free memory, with memory profile support. +// Instance of Memory Profile Library using the EDK II Memory Profile Protocol. // // Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.
// @@ -12,7 +8,7 @@ // **/ -#string STR_MODULE_ABSTRACT #language en-US "Instance of Memory Allocation Library using EFI Boot Services, with memory profile support" +#string STR_MODULE_ABSTRACT #language en-US "Instance of Memory Profile Library using the EDK II Memory Profile Protocol" -#string STR_MODULE_DESCRIPTION #language en-US "This Memory Allocation Library uses EFI Boot Services to allocate and free memory, with memory profile support." +#string STR_MODULE_DESCRIPTION #language en-US "Instance of Memory Profile Library using the EDK II Memory Profile Protocol." diff --git a/MdePkg/MdeLibs.dsc.inc b/MdePkg/MdeLibs.dsc.inc index ae645164c8..8bdb95e607 100644 --- a/MdePkg/MdeLibs.dsc.inc +++ b/MdePkg/MdeLibs.dsc.inc @@ -29,6 +29,8 @@ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf BaseOverflowLib|MdePkg/Library/BaseOverflowLib/BaseOverflowLib.inf + + MemoryProfileLib|MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.inf StackCheckFailureHookLib|MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf !if $(CUSTOM_STACK_CHECK_LIB) == STATIC From a52efcc86abc3a833d80a89c2ebc6dfa386e66eb Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 4 May 2023 15:24:56 +0300 Subject: [PATCH 054/341] MdePkg: Introduce CommonMemoryAllocationLib --- .../MemoryAllocationLib.c | 182 +-- .../PrePiMemoryAllocationLib.inf | 1 + .../GuardUefiMemoryAllocationLib.inf | 1 + .../MemoryAllocationLib.c | 755 +----------- .../Core/PiSmmCore/MemoryAllocation.c | 952 +--------------- .../BaseMemoryAllocationLibNull.c | 528 +-------- .../BaseMemoryAllocationLibNull.inf | 1 + .../CommonMemoryAllocationLib.c | 978 ++++++++++++++++ .../CommonMemoryAllocationLib.inf | 37 + .../CommonMemoryAllocationLib.uni | 15 + .../CommonMemoryAllocationLibEx.c | 150 +++ .../DxeCoreMemoryAllocationLib.inf | 1 + .../MemoryAllocationLib.c | 1012 +---------------- .../PiSmmCoreMemoryAllocationLib.inf | 2 +- .../Include/Library/MemoryAllocationLibEx.h | 75 ++ .../Library/PhaseMemoryAllocationLib.h | 117 ++ .../MemoryAllocationLib.c | 811 +------------ .../PeiMemoryAllocationLib.inf | 1 + .../MemoryAllocationLib.c | 780 +------------ .../SmmMemoryAllocationLib.inf | 1 + .../MemoryAllocationLib.c | 768 +------------ .../UefiMemoryAllocationLib.inf | 1 + MdePkg/MdeLibs.dsc.inc | 1 + .../StandaloneMmCoreMemoryAllocationLib.c | 768 +------------ .../StandaloneMmCoreMemoryAllocationLib.inf | 1 + .../StandaloneMmMemoryAllocationLib.c | 768 +------------ .../StandaloneMmMemoryAllocationLib.inf | 1 + .../MemoryAllocationLib.c | 175 +-- .../UefiPayloadMemoryAllocationLib.inf | 1 + .../MemoryAllocationLibPosix.c | 568 ++------- .../MemoryAllocationLibPosix.inf | 1 + 31 files changed, 1963 insertions(+), 7490 deletions(-) create mode 100644 MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c create mode 100644 MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf create mode 100644 MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.uni create mode 100644 MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLibEx.c create mode 100644 MdePkg/Include/Library/MemoryAllocationLibEx.h create mode 100644 MdePkg/Include/Library/PhaseMemoryAllocationLib.h diff --git a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c index f4077c04a7..e056cdb9ed 100644 --- a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c +++ b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c @@ -8,23 +8,29 @@ **/ #include +#include #include #include #include #include -STATIC -VOID * +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; + +EFI_STATUS EFIAPI -InternalAllocatePages ( - IN UINTN Pages, - IN EFI_MEMORY_TYPE MemoryType +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { EFI_PEI_HOB_POINTERS Hob; EFI_PHYSICAL_ADDRESS NewTop; + ASSERT (Type == AllocateAnyPages); + Hob.Raw = GetHobList (); NewTop = Hob.HandoffInformationTable->EfiFreeMemoryTop & ~(EFI_PHYSICAL_ADDRESS)EFI_PAGE_MASK; @@ -34,7 +40,7 @@ InternalAllocatePages ( // Verify that there is sufficient memory to satisfy the allocation // if (NewTop < (Hob.HandoffInformationTable->EfiFreeMemoryBottom + sizeof (EFI_HOB_MEMORY_ALLOCATION))) { - return NULL; + return EFI_OUT_OF_RESOURCES; } // @@ -51,131 +57,41 @@ InternalAllocatePages ( MemoryType ); - return (VOID *)(UINTN)Hob.HandoffInformationTable->EfiFreeMemoryTop; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of MemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (Pages, EfiBootServicesData); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (Pages, EfiRuntimeServicesData); -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Memory; - UINTN AlignmentMask; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment))); - // - // We would rather waste some memory to save PEI code size. - // - Memory = (VOID *)(UINTN)AllocatePages (Pages + EFI_SIZE_TO_PAGES (Alignment)); - if (Alignment == 0) { - AlignmentMask = Alignment; - } else { - AlignmentMask = Alignment - 1; - } - - return (VOID *)(UINTN)(((UINTN)Memory + AlignmentMask) & ~AlignmentMask); + *Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop; + return EFI_SUCCESS; } /** Frees one or more 4KB pages that were previously allocated with one of the page allocation functions in the Memory Allocation Library. - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. - If Buffer was not allocated with a page allocation function in the Memory Allocation Library, - then ASSERT(). + If Buffer was not allocated with a page allocation function in the Memory Allocation + Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer Pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { // For now, we do not support the ability to free pages in the PrePei Memory Allocator. // The allocated memory is lost. + return EFI_SUCCESS; } /** @@ -192,8 +108,9 @@ FreePages ( **/ VOID * EFIAPI -AllocatePool ( - IN UINTN AllocationSize +PhaseAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize ) { EFI_HOB_MEMORY_POOL *Hob; @@ -216,37 +133,6 @@ AllocatePool ( } } -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = AllocatePool (AllocationSize); - if (Buffer == NULL) { - return NULL; - } - - ZeroMem (Buffer, AllocationSize); - - return Buffer; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -263,7 +149,7 @@ AllocateZeroPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf index 9491af9f24..4513a1d0fd 100644 --- a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf +++ b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf @@ -30,4 +30,5 @@ BaseMemoryLib PrePiLib #PeiServicesLib + CommonMemoryAllocationLib diff --git a/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/GuardUefiMemoryAllocationLib.inf b/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/GuardUefiMemoryAllocationLib.inf index 95038a64de..5ddc9299c6 100644 --- a/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/GuardUefiMemoryAllocationLib.inf +++ b/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/GuardUefiMemoryAllocationLib.inf @@ -35,3 +35,4 @@ BaseMemoryLib UefiBootServicesTableLib EmuThunkLib + CommonMemoryAllocationLib diff --git a/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c b/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c index 515ef1a59b..23aa0b1b7b 100644 --- a/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c +++ b/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c @@ -17,337 +17,95 @@ #include -#include +#include #include #include #include #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; + /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - - if (Pages == 0) { - return NULL; - } - - return gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE); -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * +EFI_STATUS EFIAPI -AllocatePages ( - IN UINTN Pages +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - return InternalAllocatePages (EfiBootServicesData, Pages); -} + VOID *Buffer; -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. + ASSERT (Type == AllocateAnyPages); - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. + if (Pages == 0) { + return EFI_INVALID_PARAMETER; + } - @return A pointer to the allocated buffer or NULL if allocation fails. + Buffer = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiReservedMemoryType, Pages); + *Memory = (UINTN)Buffer; + return EFI_SUCCESS; } /** Frees one or more 4KB pages that were previously allocated with one of the page allocation functions in the Memory Allocation Library. - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. - If Buffer was not allocated with a page allocation function in the Memory Allocation Library, - then ASSERT(). + If Buffer was not allocated with a page allocation function in the Memory Allocation + Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer The pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - EFI_STATUS Status; - ASSERT (Pages != 0); - if (!gEmuThunk->Free (Buffer)) { + if (!gEmuThunk->Free ((VOID *)(UINTN)Memory)) { // The Free thunk will not free memory allocated in emulated EFI memory. // The assmuption is this was allocated directly by EFI. We need this as some // times protocols or EFI BootServices can return dynamically allocated buffers. - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); - } -} - -/** - Allocates one or more 4KB pages of a certain memory type at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment - specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned. - If there is not enough memory at the specified alignment remaining to satisfy the request, then - NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - - @param MemoryType The type of memory to allocate. - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - VOID *Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Caculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE); - if (Memory != NULL) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - FreePages (Memory, UnalignedPages); - } - - Memory = (VOID *)(AlignedMemory + EFI_PAGES_TO_SIZE (Pages)); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - FreePages (Memory, UnalignedPages); - } - } else { - // - // Do not over-allocate pages in this case. - // - Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE); - if (Memory != NULL) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; + return gBS->FreePages (Memory, Pages); } - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment); -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the aligned page - allocation functions in the Memory Allocation Library. - - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the aligned page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with an aligned page allocation function in the Memory Allocation - Library, then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - FreePages (Buffer, Pages); + return EFI_SUCCESS; } /** @@ -364,7 +122,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -372,420 +131,6 @@ InternalAllocatePool ( return gEmuThunk->Malloc (AllocationSize); } -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiBootServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiReservedMemoryType, AllocationSize); -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize); -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer); -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer); -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -802,7 +147,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c b/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c index b81d637aef..66f075531e 100644 --- a/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c +++ b/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c @@ -18,7 +18,7 @@ #include -#include +#include #include #include #include @@ -27,6 +27,8 @@ #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiRuntimeServicesData; + EFI_SMRAM_DESCRIPTOR *mSmmCoreMemoryAllocLibSmramRanges = NULL; UINTN mSmmCoreMemoryAllocLibSmramRangeCount = 0; @@ -41,14 +43,14 @@ UINTN mSmmCoreMemoryAllocLibSmramRangeCount = 0; BOOLEAN EFIAPI BufferInSmram ( - IN VOID *Buffer + IN EFI_PHYSICAL_ADDRESS Buffer ) { UINTN Index; for (Index = 0; Index < mSmmCoreMemoryAllocLibSmramRangeCount; Index++) { - if (((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer >= mSmmCoreMemoryAllocLibSmramRanges[Index].CpuStart) && - ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer < (mSmmCoreMemoryAllocLibSmramRanges[Index].CpuStart + mSmmCoreMemoryAllocLibSmramRanges[Index].PhysicalSize))) + if ((Buffer >= mSmmCoreMemoryAllocLibSmramRanges[Index].CpuStart) && + (Buffer < (mSmmCoreMemoryAllocLibSmramRanges[Index].CpuStart + mSmmCoreMemoryAllocLibSmramRanges[Index].PhysicalSize))) { return TRUE; } @@ -60,420 +62,83 @@ BufferInSmram ( /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - - if (Pages == 0) { - return NULL; - } - - Status = SmmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * +EFI_STATUS EFIAPI -AllocateRuntimePages ( - IN UINTN Pages +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); + if (Pages == 0) { + return EFI_INVALID_PARAMETER; } - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return NULL; + return SmmAllocatePages (Type, MemoryType, Pages, Memory); } /** Frees one or more 4KB pages that were previously allocated with one of the page allocation functions in the Memory Allocation Library. - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with a page allocation function in the Memory Allocation Library, - then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer Pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - if (BufferInSmram (Buffer)) { - // - // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service. - // So, SmmFreePages() service is used to free it. - // - Status = SmmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - } else { - // - // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service. - // So, gBS->FreePages() service is used to free it. - // - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - } - - ASSERT_EFI_ERROR (Status); -} - -/** - Allocates one or more 4KB pages of a certain memory type at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment - specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned. - If there is not enough memory at the specified alignment remaining to satisfy the request, then - NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param MemoryType The type of memory to allocate. - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = SmmAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = SmmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = SmmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = SmmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return NULL; -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the aligned page - allocation functions in the Memory Allocation Library. - - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the aligned page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer Pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { EFI_STATUS Status; ASSERT (Pages != 0); - if (BufferInSmram (Buffer)) { + if (BufferInSmram (Memory)) { // // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service. // So, SmmFreePages() service is used to free it. // - Status = SmmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); + Status = SmmFreePages (Memory, Pages); } else { // // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service. // So, gBS->FreePages() service is used to free it. // - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); + Status = gBS->FreePages (Memory, Pages); } - ASSERT_EFI_ERROR (Status); + return Status; } /** @@ -490,7 +155,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -508,532 +174,6 @@ InternalAllocatePool ( return Memory; } -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL, - EfiRuntimeServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL, - EfiRuntimeServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return NULL; -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL, - EfiRuntimeServicesData, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL, - EfiRuntimeServicesData, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return NULL; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -1050,13 +190,13 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { EFI_STATUS Status; - if (BufferInSmram (Buffer)) { + if (BufferInSmram ((UINTN)Buffer)) { // // When Buffer is in SMRAM range, it should be allocated by SmmAllocatePool() service. // So, SmmFreePool() service is used to free it. diff --git a/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.c b/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.c index 3061ec6cd0..bd661ca428 100644 --- a/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.c +++ b/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.c @@ -7,275 +7,84 @@ **/ -#include +#include #include -#include +#include -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - ASSERT (FALSE); - return NULL; -} +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; /** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. + Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * +EFI_STATUS EFIAPI -AllocateRuntimePages ( - IN UINTN Pages +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { ASSERT (FALSE); - return NULL; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - ASSERT (FALSE); - return NULL; + return EFI_OUT_OF_RESOURCES; } /** Frees one or more 4KB pages that were previously allocated with one of the page allocation functions in the Memory Allocation Library. - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with a page allocation function in the Memory Allocation Library, - then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - ASSERT (FALSE); -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the aligned page - allocation functions in the Memory Allocation Library. - - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the aligned page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer The pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. -**/ -VOID -EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - ASSERT (FALSE); -} - -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). **/ -VOID * +EFI_STATUS EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { ASSERT (FALSE); - return NULL; + return EFI_NOT_FOUND; } /** - Allocates a buffer of type EfiReservedMemoryType. + Allocates a buffer of a certain pool type. - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + Allocates the number bytes specified by AllocationSize of a certain pool type and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + @param MemoryType The type of memory to allocate. @param AllocationSize The number of bytes to allocate. @return A pointer to the allocated buffer or NULL if allocation fails. @@ -283,260 +92,9 @@ AllocateRuntimePool ( **/ VOID * EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - ASSERT (FALSE); - return NULL; -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL +PhaseAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize ) { ASSERT (FALSE); @@ -559,7 +117,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf b/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf index 00a2b78093..3a89dfa0f9 100644 --- a/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf +++ b/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf @@ -31,3 +31,4 @@ [LibraryClasses] DebugLib + CommonMemoryAllocationLib diff --git a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c new file mode 100644 index 0000000000..6eed53cfc8 --- /dev/null +++ b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c @@ -0,0 +1,978 @@ +/** @file + Common code for the Memory Allocation Library based on + PhaseMemoryAllocationLib. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include + +#include + +/** + Allocates one or more 4KB pages of type EfiBootServicesData. + + Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocatePages ( + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + VOID *Buffer; + + Status = PhaseAllocatePages (AllocateAnyPages, gPhaseDefaultDataType, Pages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; + } + + Buffer = (VOID *)(UINTN)Memory; + + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES, + gPhaseDefaultDataType, + Buffer, + EFI_PAGES_TO_SIZE (Pages), + NULL + ); + + return Buffer; +} + +/** + Allocates one or more 4KB pages of type EfiRuntimeServicesData. + + Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimePages ( + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + VOID *Buffer; + + Status = PhaseAllocatePages (AllocateAnyPages, EfiRuntimeServicesData, Pages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; + } + + Buffer = (VOID *)(UINTN)Memory; + + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES, + EfiRuntimeServicesData, + Buffer, + EFI_PAGES_TO_SIZE (Pages), + NULL + ); + + return Buffer; +} + +/** + Allocates one or more 4KB pages of type EfiReservedMemoryType. + + Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedPages ( + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + VOID *Buffer; + + Status = PhaseAllocatePages (AllocateAnyPages, EfiReservedMemoryType, Pages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; + } + + Buffer = (VOID *)(UINTN)Memory; + + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES, + EfiReservedMemoryType, + Buffer, + EFI_PAGES_TO_SIZE (Pages), + NULL + ); + + return Buffer; +} + +/** + Frees one or more 4KB pages that were previously allocated with one of the page allocation + functions in the Memory Allocation Library. + + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer + must have been allocated on a previous call to the page allocation services of the Memory + Allocation Library. If it is not possible to free allocated pages, then this function will + perform no actions. + + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, + then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Buffer Pointer to the buffer of pages to free. + @param Pages The number of 4 KB pages to free. + +**/ +VOID +EFIAPI +FreePages ( + IN VOID *Buffer, + IN UINTN Pages + ) +{ + EFI_STATUS Status; + + Status = PhaseFreePages ((UINTN)Buffer, Pages); + ASSERT_EFI_ERROR (Status); +} + +/** + Allocates one or more 4KB pages of a certain memory type at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment + specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned. + If there is not enough memory at the specified alignment remaining to satisfy the request, then + NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +STATIC +VOID * +InternalAllocateAlignedPages ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN UINTN Alignment + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + + Status = AllocateAlignedPagesEx ( + AllocateAnyPages, + MemoryType, + Pages, + Alignment, + &Memory + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + return (VOID *)(UINTN)Memory; +} + +/** + Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateAlignedPages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + VOID *Buffer; + + Buffer = InternalAllocateAlignedPages (gPhaseDefaultDataType, Pages, Alignment); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES, + gPhaseDefaultDataType, + Buffer, + EFI_PAGES_TO_SIZE (Pages), + NULL + ); + } + + return Buffer; +} + +/** + Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateAlignedRuntimePages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + VOID *Buffer; + + Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES, + EfiRuntimeServicesData, + Buffer, + EFI_PAGES_TO_SIZE (Pages), + NULL + ); + } + + return Buffer; +} + +/** + Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateAlignedReservedPages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + VOID *Buffer; + + Buffer = InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES, + EfiReservedMemoryType, + Buffer, + EFI_PAGES_TO_SIZE (Pages), + NULL + ); + } + + return Buffer; +} + +/** + Frees one or more 4KB pages that were previously allocated with one of the aligned page + allocation functions in the Memory Allocation Library. + + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer + must have been allocated on a previous call to the aligned page allocation services of the Memory + Allocation Library. If it is not possible to free allocated pages, then this function will + perform no actions. + + If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + Library, then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Buffer Pointer to the buffer of pages to free. + @param Pages The number of 4 KB pages to free. + +**/ +VOID +EFIAPI +FreeAlignedPages ( + IN VOID *Buffer, + IN UINTN Pages + ) +{ + FreePages (Buffer, Pages); +} + +/** + Allocates a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocatePool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = PhaseAllocatePool (gPhaseDefaultDataType, AllocationSize); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL, + gPhaseDefaultDataType, + Buffer, + AllocationSize, + NULL + ); + } + + return Buffer; +} + +/** + Allocates a buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns + a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimePool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = PhaseAllocatePool (EfiRuntimeServicesData, AllocationSize); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL, + EfiRuntimeServicesData, + Buffer, + AllocationSize, + NULL + ); + } + + return Buffer; +} + +/** + Allocates a buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns + a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedPool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = PhaseAllocatePool (EfiReservedMemoryType, AllocationSize); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL, + EfiReservedMemoryType, + Buffer, + AllocationSize, + NULL + ); + } + + return Buffer; +} + +/** + Allocates and zeros a buffer of a certain pool type. + + Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer + with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid + buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, + then NULL is returned. + + @param PoolType The type of memory to allocate. + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +STATIC +VOID * +InternalAllocateZeroPool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN AllocationSize + ) +{ + VOID *Memory; + + Memory = PhaseAllocatePool (PoolType, AllocationSize); + if (Memory != NULL) { + Memory = ZeroMem (Memory, AllocationSize); + } + + return Memory; +} + +/** + Allocates and zeros a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateZeroPool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = InternalAllocateZeroPool (gPhaseDefaultDataType, AllocationSize); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL, + gPhaseDefaultDataType, + Buffer, + AllocationSize, + NULL + ); + } + + return Buffer; +} + +/** + Allocates and zeros a buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimeZeroPool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL, + EfiRuntimeServicesData, + Buffer, + AllocationSize, + NULL + ); + } + + return Buffer; +} + +/** + Allocates and zeros a buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedZeroPool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL, + EfiReservedMemoryType, + Buffer, + AllocationSize, + NULL + ); + } + + return Buffer; +} + +/** + Copies a buffer to an allocated buffer of a certain pool type. + + Allocates the number bytes specified by AllocationSize of a certain pool type, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param PoolType The type of pool to allocate. + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +STATIC +VOID * +InternalAllocateCopyPool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + VOID *Memory; + + ASSERT (Buffer != NULL); + ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); + + Memory = PhaseAllocatePool (PoolType, AllocationSize); + if (Memory != NULL) { + Memory = CopyMem (Memory, Buffer, AllocationSize); + } + + return Memory; +} + +/** + Copies a buffer to an allocated buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + VOID *NewBuffer; + + NewBuffer = InternalAllocateCopyPool (gPhaseDefaultDataType, AllocationSize, Buffer); + if (NewBuffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL, + gPhaseDefaultDataType, + NewBuffer, + AllocationSize, + NULL + ); + } + + return NewBuffer; +} + +/** + Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimeCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + VOID *NewBuffer; + + NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); + if (NewBuffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL, + EfiRuntimeServicesData, + NewBuffer, + AllocationSize, + NULL + ); + } + + return NewBuffer; +} + +/** + Copies a buffer to an allocated buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + VOID *NewBuffer; + + NewBuffer = InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer); + if (NewBuffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL, + EfiRuntimeServicesData, + NewBuffer, + AllocationSize, + NULL + ); + } + + return NewBuffer; +} + +/** + Reallocates a buffer of a specified memory type. + + Allocates and zeros the number bytes specified by NewSize from memory of the type + specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param PoolType The type of pool to allocate. + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +STATIC +VOID * +InternalReallocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + VOID *NewBuffer; + + NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); + if ((NewBuffer != NULL) && (OldBuffer != NULL)) { + CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); + FreePool (OldBuffer); + } + + return NewBuffer; +} + +/** + Reallocates a buffer of type EfiBootServicesData. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocatePool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + VOID *Buffer; + + Buffer = InternalReallocatePool (gPhaseDefaultDataType, OldSize, NewSize, OldBuffer); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL, + gPhaseDefaultDataType, + Buffer, + NewSize, + NULL + ); + } + + return Buffer; +} + +/** + Reallocates a buffer of type EfiRuntimeServicesData. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocateRuntimePool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + VOID *Buffer; + + Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL, + EfiRuntimeServicesData, + Buffer, + NewSize, + NULL + ); + } + + return Buffer; +} + +/** + Reallocates a buffer of type EfiReservedMemoryType. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocateReservedPool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + VOID *Buffer; + + Buffer = InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer); + if (Buffer != NULL) { + MemoryProfileLibRecord ( + (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), + MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL, + EfiReservedMemoryType, + Buffer, + NewSize, + NULL + ); + } + + return Buffer; +} + +/** + Frees a buffer that was previously allocated with one of the pool allocation functions in the + Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + pool allocation services of the Memory Allocation Library. If it is not possible to free pool + resources, then this function will perform no actions. + + If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, + then ASSERT(). + + @param Buffer Pointer to the buffer to free. + +**/ +VOID +EFIAPI +FreePool ( + IN VOID *Buffer + ) +{ + PhaseFreePool (Buffer); +} diff --git a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf new file mode 100644 index 0000000000..8c806dc642 --- /dev/null +++ b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf @@ -0,0 +1,37 @@ +## @file +# Common code for the Memory Allocation Library based on +# PhaseMemoryAllocationLib. +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CommonMemoryAllocationLib + MODULE_UNI_FILE = CommonMemoryAllocationLib.uni + FILE_GUID = 020172f8-f96d-479b-9f29-c4d2f204573d + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = CommonMemoryAllocationLib + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + CommonMemoryAllocationLib.c + CommonMemoryAllocationLibEx.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + DebugLib + BaseMemoryLib + MemoryProfileLib + diff --git a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.uni b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.uni new file mode 100644 index 0000000000..4ed987566c --- /dev/null +++ b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.uni @@ -0,0 +1,15 @@ +// /** @file +// Common code for the Memory Allocation Library based on +// PhaseMemoryAllocationLib. +// +// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Common code for the Memory Allocation Library based on PhaseMemoryAllocationLib" + +#string STR_MODULE_DESCRIPTION #language en-US "Common code for the Memory Allocation Library based on PhaseMemoryAllocationLib." + diff --git a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLibEx.c b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLibEx.c new file mode 100644 index 0000000000..b378193421 --- /dev/null +++ b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLibEx.c @@ -0,0 +1,150 @@ +/** @file + Implementation of MemoryAllocationLibEx based on PhaseMemoryAllocationLib. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2023, Marvin Häuser. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include + +/** + Allocates one or more 4KB pages of a certain memory type. + + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. + + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. + +**/ +EFI_STATUS +EFIAPI +AllocatePagesEx ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ) +{ + return PhaseAllocatePages (Type, MemoryType, Pages, Memory); +} + +/** + Allocates one or more 4KB pages of a certain memory type at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment + specified by Alignment. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. + + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. + +**/ +EFI_STATUS +EFIAPI +AllocateAlignedPagesEx ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN UINTN Alignment, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Address; + EFI_PHYSICAL_ADDRESS AlignedMemory; + UINTN AlignmentMask; + UINTN UnalignedPages; + UINTN RealPages; + + // + // Alignment must be a power of two or zero. + // + ASSERT ((Alignment & (Alignment - 1)) == 0); + + // + // Reserving a specific address does not require guaranteeing alignment + // constraints. + // + ASSERT (Type != AllocateAddress); + + if (Pages == 0) { + return EFI_INVALID_PARAMETER; + } + + if (Alignment > EFI_PAGE_SIZE) { + // + // Calculate the total number of pages since alignment is larger than page size. + // + AlignmentMask = Alignment - 1; + RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); + // + // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. + // + ASSERT (RealPages > Pages); + + Status = AllocatePagesEx (Type, MemoryType, RealPages, Memory); + if (EFI_ERROR (Status)) { + return Status; + } + + Address = *Memory; + + AlignedMemory = (Address + AlignmentMask) & ~(EFI_PHYSICAL_ADDRESS)AlignmentMask; + UnalignedPages = EFI_SIZE_TO_PAGES ((UINTN)(AlignedMemory - Address)); + if (UnalignedPages > 0) { + // + // Free first unaligned page(s). + // + Status = PhaseFreePages (Address, UnalignedPages); + ASSERT_EFI_ERROR (Status); + } + + Address = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); + UnalignedPages = RealPages - Pages - UnalignedPages; + if (UnalignedPages > 0) { + // + // Free last unaligned page(s). + // + Status = PhaseFreePages (Address, UnalignedPages); + ASSERT_EFI_ERROR (Status); + } + + *Memory = AlignedMemory; + } else { + // + // Do not over-allocate pages in this case. + // + Status = AllocatePagesEx (Type, MemoryType, Pages, Memory); + if (EFI_ERROR (Status)) { + return Status; + } + } + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf index cd5515ee52..de8c565352 100644 --- a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf +++ b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf @@ -38,3 +38,4 @@ DebugLib BaseMemoryLib MemoryProfileLib + CommonMemoryAllocationLib diff --git a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c index e813e87f24..1d8a263947 100644 --- a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c @@ -10,432 +10,77 @@ #include -#include +#include #include #include #include "DxeCoreMemoryAllocationServices.h" -#include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - - if (Pages == 0) { - return NULL; - } - - Status = CoreAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * +EFI_STATUS EFIAPI -AllocatePages ( - IN UINTN Pages +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiBootServicesData, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES, - EfiBootServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePages (EfiReservedMemoryType, Pages); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES, - EfiReservedMemoryType, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); + if (Pages == 0) { + return EFI_INVALID_PARAMETER; } - return Buffer; + return CoreAllocatePages (Type, MemoryType, Pages, Memory); } /** Frees one or more 4KB pages that were previously allocated with one of the page allocation functions in the Memory Allocation Library. - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with a page allocation function in the Memory Allocation Library, - then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer Pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - Status = CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); -} - -/** - Allocates one or more 4KB pages of a certain memory type at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment - specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned. - If there is not enough memory at the specified alignment remaining to satisfy the request, then - NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param MemoryType The type of memory to allocate. - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = CoreAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = CoreFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = CoreFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = CoreAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES, - EfiBootServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES, - EfiRuntimeServicesData, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES, - EfiReservedMemoryType, - Buffer, - EFI_PAGES_TO_SIZE (Pages), - NULL - ); - } - - return Buffer; -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the aligned page - allocation functions in the Memory Allocation Library. - - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the aligned page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer Pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - EFI_STATUS Status; - ASSERT (Pages != 0); - Status = CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); + return CoreFreePages (Memory, Pages); } /** @@ -452,7 +97,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -470,588 +116,6 @@ InternalAllocatePool ( return Memory; } -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiBootServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL, - EfiBootServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocatePool (EfiReservedMemoryType, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL, - EfiReservedMemoryType, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiBootServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL, - EfiBootServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL, - EfiRuntimeServicesData, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL, - EfiReservedMemoryType, - Buffer, - AllocationSize, - NULL - ); - } - - return Buffer; -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL, - EfiBootServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL, - EfiRuntimeServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer); - if (NewBuffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL, - EfiRuntimeServicesData, - NewBuffer, - AllocationSize, - NULL - ); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL, - EfiBootServicesData, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL, - EfiRuntimeServicesData, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *Buffer; - - Buffer = InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer); - if (Buffer != NULL) { - MemoryProfileLibRecord ( - (PHYSICAL_ADDRESS)(UINTN)RETURN_ADDRESS (0), - MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL, - EfiReservedMemoryType, - Buffer, - NewSize, - NULL - ); - } - - return Buffer; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -1068,7 +132,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf index 9bb3aaef02..c56c4aef42 100644 --- a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf +++ b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf @@ -37,4 +37,4 @@ MdePkg/MdePkg.dec [LibraryClasses] - MemoryProfileLib + CommonMemoryAllocationLib diff --git a/MdePkg/Include/Library/MemoryAllocationLibEx.h b/MdePkg/Include/Library/MemoryAllocationLibEx.h new file mode 100644 index 0000000000..079d823a78 --- /dev/null +++ b/MdePkg/Include/Library/MemoryAllocationLibEx.h @@ -0,0 +1,75 @@ +/** @file + Provides extended services to allocate and free memory buffers of various memory types and alignments. + This header is part of the MemoryAllocationLib library class. Every instance + of MemoryAllocationLib must also implement the functions declared by this + header. The separation is due to the newly-introduced dependency on + MdePkg/Uefi/UefiSpec.h. + +Copyright (c) 2023, Marvin Häuser. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __MEMORY_ALLOCATION_LIB_EX_H__ +#define __MEMORY_ALLOCATION_LIB_EX_H__ + +/** + Allocates one or more 4KB pages of a certain memory type. + + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. + + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. + +**/ +EFI_STATUS +EFIAPI +AllocatePagesEx ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +/** + Allocates one or more 4KB pages of a certain memory type at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment + specified by Alignment. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. + + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. + +**/ +EFI_STATUS +EFIAPI +AllocateAlignedPagesEx ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN UINTN Alignment, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +#endif diff --git a/MdePkg/Include/Library/PhaseMemoryAllocationLib.h b/MdePkg/Include/Library/PhaseMemoryAllocationLib.h new file mode 100644 index 0000000000..fbe1ad6e1f --- /dev/null +++ b/MdePkg/Include/Library/PhaseMemoryAllocationLib.h @@ -0,0 +1,117 @@ +/** @file + Provides primitives to allocate and free memory buffers of various memory types and alignments. + + The Phase Memory Allocation Library abstracts primitive memory allocation operations. This library + allows code to be written in a phase-independent manner because the allocation of memory in PEI, DXE, + and SMM (for example) is done via a different mechanism. Using a common library interface makes it + much easier to port algorithms from phase to phase. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __PHASE_MEMORY_ALLOCATION_LIB_H__ +#define __PHASE_MEMORY_ALLOCATION_LIB_H__ + +/** + Allocates one or more 4KB pages of a certain memory type. + + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. + + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. + +**/ +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +/** + Frees one or more 4KB pages that were previously allocated with one of the page allocation + functions in the Memory Allocation Library. + + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. + + If Buffer was not allocated with a page allocation function in the Memory Allocation + Library, then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Memory The base physical address of the pages to be freed. + @param Pages The number of 4 KB pages to free. + + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + +**/ +EFI_STATUS +EFIAPI +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages + ); + +/** + Allocates a buffer of a certain pool type. + + Allocates the number bytes specified by AllocationSize of a certain pool type and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param MemoryType The type of memory to allocate. + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +PhaseAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize + ); + +/** + Frees a buffer that was previously allocated with one of the pool allocation functions in the + Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + pool allocation services of the Memory Allocation Library. If it is not possible to free pool + resources, then this function will perform no actions. + + If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, + then ASSERT(). + + @param Buffer The pointer to the buffer to free. + +**/ +VOID +EFIAPI +PhaseFreePool ( + IN VOID *Buffer + ); + +/// +/// The memory type to allocate for calls to AllocatePages(). +/// +extern CONST EFI_MEMORY_TYPE gPhaseDefaultDataType; + +#endif diff --git a/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c b/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c index e540e06e00..619a3664f7 100644 --- a/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c @@ -8,820 +8,135 @@ **/ #include +#include -#include +#include #include #include #include #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; + /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; + ASSERT (Type == AllocateAnyPages); if (Pages == 0) { - return NULL; - } - - Status = PeiServicesAllocatePages (MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; + return EFI_INVALID_PARAMETER; } - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiBootServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiReservedMemoryType, Pages); + return PeiServicesAllocatePages (MemoryType, Pages, Memory); } /** Frees one or more 4KB pages that were previously allocated with one of the page allocation functions in the Memory Allocation Library. - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. - If Buffer was not allocated with a page allocation function in the Memory Allocation Library, - then ASSERT(). + If Buffer was not allocated with a page allocation function in the Memory Allocation + Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer The pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - EFI_STATUS Status; - ASSERT (Pages != 0); - Status = PeiServicesFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); + return PeiServicesFreePages (Memory, Pages); } /** - Allocates one or more 4KB pages of a certain memory type at a specified alignment. + Allocates a buffer of a certain pool type. - Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment - specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned. - If there is not enough memory at the specified alignment remaining to satisfy the request, then - NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + Allocates the number bytes specified by AllocationSize of a certain pool type and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. @param MemoryType The type of memory to allocate. - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. + @param AllocationSize The number of bytes to allocate. @return A pointer to the allocated buffer or NULL if allocation fails. **/ VOID * -InternalAllocateAlignedPages ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment + IN UINTN AllocationSize ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + VOID *Buffer; - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); + if (MemoryType != EfiBootServicesData) { // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. + // If we need lots of small runtime/reserved memory type from PEI in the future, + // we can consider providing a more complex algorithm that allocates runtime pages and + // provide pool allocations from those pages. // - ASSERT (RealPages > Pages); - - Status = PeiServicesAllocatePages (MemoryType, RealPages, &Memory); + Status = PhaseAllocatePages ( + AllocateAnyPages, + MemoryType, + EFI_SIZE_TO_PAGES (AllocationSize), + &Memory + ); if (EFI_ERROR (Status)) { return NULL; } - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = PeiServicesFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = PeiServicesFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } + Buffer = (VOID *)(UINTN)Memory; } else { - // - // Do not over-allocate pages in this case. - // - Status = PeiServicesAllocatePages (MemoryType, Pages, &Memory); + Status = PeiServicesAllocatePool (AllocationSize, &Buffer); if (EFI_ERROR (Status)) { return NULL; } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment); -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the aligned page - allocation functions in the Memory Allocation Library. - - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the aligned page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with an aligned page allocation function in the Memory Allocation - Library, then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - Status = PeiServicesFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); -} - -/** - Allocates a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param MemoryType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocatePool ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN AllocationSize - ) -{ - // - // If we need lots of small runtime/reserved memory type from PEI in the future, - // we can consider providing a more complex algorithm that allocates runtime pages and - // provide pool allocations from those pages. - // - return InternalAllocatePages (MemoryType, EFI_SIZE_TO_PAGES (AllocationSize)); -} - -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - EFI_STATUS Status; - VOID *Buffer; - - Status = PeiServicesAllocatePool (AllocationSize, &Buffer); - if (EFI_ERROR (Status)) { - Buffer = NULL; } return Buffer; } -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiReservedMemoryType, AllocationSize); -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = AllocatePool (AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize); -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = AllocatePool (AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer); -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer); -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -838,7 +153,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf b/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf index f6a670871e..8f6d8cf37b 100644 --- a/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf +++ b/MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf @@ -37,4 +37,5 @@ BaseMemoryLib PeiServicesLib HobLib + CommonMemoryAllocationLib diff --git a/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c b/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c index 99a8259325..0dfd86bedd 100644 --- a/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c @@ -21,11 +21,14 @@ #include #include +#include #include #include #include #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiRuntimeServicesData; + EFI_SMRAM_DESCRIPTOR *mSmramRanges; UINTN mSmramRangeCount; @@ -114,14 +117,14 @@ SmmMemoryAllocationLibDestructor ( BOOLEAN EFIAPI BufferInSmram ( - IN VOID *Buffer + IN EFI_PHYSICAL_ADDRESS Buffer ) { UINTN Index; for (Index = 0; Index < mSmramRangeCount; Index++) { - if (((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer >= mSmramRanges[Index].CpuStart) && - ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer < (mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize))) + if ((Buffer >= mSmramRanges[Index].CpuStart) && + (Buffer < (mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize))) { return TRUE; } @@ -134,101 +137,34 @@ BufferInSmram ( Allocates one or more 4KB pages of a certain memory type. Allocates the number of 4KB pages of a certain memory type and returns a pointer - to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If - Pages is 0, then NULL is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - if (Pages == 0) { - return NULL; - } - - Status = gSmst->SmmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; + return EFI_INVALID_PARAMETER; } - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer - to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If - Pages is 0, then NULL is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a - pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary. - If Pages is 0, then NULL is returned. If there is not enough memory remaining - to satisfy the request, then NULL is returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a - pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary. - If Pages is 0, then NULL is returned. If there is not enough memory remaining - to satisfy the request, then NULL is returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return NULL; + return gSmst->SmmAllocatePages (Type, MemoryType, Pages, Memory); } /** @@ -244,258 +180,39 @@ AllocateReservedPages ( Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer The pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - if (BufferInSmram (Buffer)) { - // - // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service. - // So, gSmst->SmmFreePages() service is used to free it. - // - Status = gSmst->SmmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - } else { - // - // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service. - // So, gBS->FreePages() service is used to free it. - // - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - } - - ASSERT_EFI_ERROR (Status); -} - -/** - Allocates one or more 4KB pages of a certain memory type at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of a certain memory type - with an alignment specified by Alignment. The allocated buffer is returned. - If Pages is 0, then NULL is returned. If there is not enough memory at the - specified alignment remaining to satisfy the request, then NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param MemoryType The type of memory to allocate. - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment) - 1; - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = gSmst->SmmAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = gSmst->SmmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = gSmst->SmmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = gSmst->SmmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData - with an alignment specified by Alignment. The allocated buffer is returned. - If Pages is 0, then NULL is returned. If there is not enough memory at the - specified alignment remaining to satisfy the request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData - with an alignment specified by Alignment. The allocated buffer is returned. - If Pages is 0, then NULL is returned. If there is not enough memory at the - specified alignment remaining to satisfy the request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). **/ -VOID * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType - with an alignment specified by Alignment. The allocated buffer is returned. - If Pages is 0, then NULL is returned. If there is not enough memory at the - specified alignment remaining to satisfy the request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return NULL; -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the aligned page - allocation functions in the Memory Allocation Library. - - Frees the number of 4KB pages specified by Pages from the buffer specified by - Buffer. Buffer must have been allocated on a previous call to the aligned page - allocation services of the Memory Allocation Library. If it is not possible to - free allocated pages, then this function will perform no actions. - - If Buffer was not allocated with an aligned page allocation function in the - Memory Allocation Library, then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { EFI_STATUS Status; ASSERT (Pages != 0); - if (BufferInSmram (Buffer)) { + if (BufferInSmram (Memory)) { // // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePages() service. // So, gSmst->SmmFreePages() service is used to free it. // - Status = gSmst->SmmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); + Status = gSmst->SmmFreePages (Memory, Pages); } else { // // When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service. // So, gBS->FreePages() service is used to free it. // - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); + Status = gBS->FreePages (Memory, Pages); } - ASSERT_EFI_ERROR (Status); + return Status; } /** @@ -513,7 +230,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -529,426 +247,6 @@ InternalAllocatePool ( return Memory; } -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData - and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData - and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType - and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to - satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, - clears the buffer with zeros, and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is - not enough memory remaining to satisfy the request, then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, - clears the buffer with zeros, and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is - not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, - clears the buffer with zeros, and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is - not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, - clears the buffer with zeros, and returns a pointer to the allocated buffer. - If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is - not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, - copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer - of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, - copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer - of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, - copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer - of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, - copies AllocationSize bytes from Buffer to the newly allocated buffer, and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer - of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return NULL; -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize - and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize - and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize - and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize - and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize - and NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize - and OldSize is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an - optional parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return NULL; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -966,13 +264,13 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { EFI_STATUS Status; - if (BufferInSmram (Buffer)) { + if (BufferInSmram ((UINTN)Buffer)) { // // When Buffer is in SMRAM range, it should be allocated by gSmst->SmmAllocatePool() service. // So, gSmst->SmmFreePool() service is used to free it. diff --git a/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf b/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf index 9f0ecbf663..bd652c5e9d 100644 --- a/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf +++ b/MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf @@ -36,6 +36,7 @@ BaseMemoryLib SmmServicesTableLib UefiBootServicesTableLib + CommonMemoryAllocationLib [Protocols] gEfiSmmAccess2ProtocolGuid ## CONSUMES diff --git a/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c b/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c index eb1226612f..4b7e18f2e0 100644 --- a/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c @@ -9,346 +9,85 @@ #include -#include +#include #include #include #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; + /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If + Pages is 0, then NULL is returned. If there is not enough memory remaining to + satisfy the request, then NULL is returned. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or + AllocateMaxAddress or AllocateAddress. + 2) MemoryType is in the range + EfiMaxMemoryType..0x6FFFFFFF. + 3) Memory is NULL. + 4) MemoryType is EfiPersistentMemory. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - if (Pages == 0) { - return NULL; + return EFI_INVALID_PARAMETER; } - Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiBootServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiReservedMemoryType, Pages); + return gBS->AllocatePages (Type, MemoryType, Pages, Memory); } /** Frees one or more 4KB pages that were previously allocated with one of the page allocation functions in the Memory Allocation Library. - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with a page allocation function in the Memory Allocation Library, - then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); -} - -/** - Allocates one or more 4KB pages of a certain memory type at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment - specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned. - If there is not enough memory at the specified alignment remaining to satisfy the request, then - NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param MemoryType The type of memory to allocate. - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = gBS->FreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = gBS->FreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment); -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the aligned page - allocation functions in the Memory Allocation Library. - - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the aligned page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer The pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - EFI_STATUS Status; - ASSERT (Pages != 0); - Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); + return gBS->FreePages (Memory, Pages); } /** @@ -365,7 +104,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -381,420 +121,6 @@ InternalAllocatePool ( return Memory; } -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiBootServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiReservedMemoryType, AllocationSize); -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize); -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer); -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer); -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -811,7 +137,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf b/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf index 4d14a157f2..57e0740e0d 100644 --- a/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf +++ b/MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf @@ -34,4 +34,5 @@ DebugLib BaseMemoryLib UefiBootServicesTableLib + CommonMemoryAllocationLib diff --git a/MdePkg/MdeLibs.dsc.inc b/MdePkg/MdeLibs.dsc.inc index 8bdb95e607..fc0c53538d 100644 --- a/MdePkg/MdeLibs.dsc.inc +++ b/MdePkg/MdeLibs.dsc.inc @@ -31,6 +31,7 @@ BaseOverflowLib|MdePkg/Library/BaseOverflowLib/BaseOverflowLib.inf MemoryProfileLib|MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.inf + CommonMemoryAllocationLib|MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf StackCheckFailureHookLib|MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf !if $(CUSTOM_STACK_CHECK_LIB) == STATIC diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c index af2182ee52..63ee134159 100644 --- a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c +++ b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c @@ -11,349 +11,88 @@ #include #include -#include +#include #include #include #include #include "StandaloneMmCoreMemoryAllocationServices.h" +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiRuntimeServicesData; + static EFI_MM_SYSTEM_TABLE *mMemoryAllocationMmst = NULL; /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If + Pages is 0, then NULL is returned. If there is not enough memory remaining to + satisfy the request, then NULL is returned. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or + AllocateMaxAddress or AllocateAddress. + 2) MemoryType is in the range + EfiMaxMemoryType..0x6FFFFFFF. + 3) Memory is NULL. + 4) MemoryType is EfiPersistentMemory. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - if (Pages == 0) { - return NULL; - } - - Status = mMemoryAllocationMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; + return EFI_INVALID_PARAMETER; } - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return NULL; + return mMemoryAllocationMmst->MmAllocatePages (Type, MemoryType, Pages, Memory); } /** Frees one or more 4KB pages that were previously allocated with one of the page allocation functions in the Memory Allocation Library. - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with a page allocation function in the Memory Allocation Library, - then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer Pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - Status = mMemoryAllocationMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); -} - -/** - Allocates one or more 4KB pages of a certain memory type at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment - specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned. - If there is not enough memory at the specified alignment remaining to satisfy the request, then - NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. - @param MemoryType The type of memory to allocate. - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = mMemoryAllocationMmst->MmAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = mMemoryAllocationMmst->MmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = (EFI_PHYSICAL_ADDRESS)(AlignedMemory + EFI_PAGES_TO_SIZE (Pages)); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = mMemoryAllocationMmst->MmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = mMemoryAllocationMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return NULL; -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the aligned page - allocation functions in the Memory Allocation Library. - - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the aligned page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer Pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - EFI_STATUS Status; - ASSERT (Pages != 0); - Status = mMemoryAllocationMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); + return mMemoryAllocationMmst->MmFreePages (Memory, Pages); } /** @@ -370,7 +109,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -388,420 +128,6 @@ InternalAllocatePool ( return Memory; } -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return NULL; -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return NULL; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -818,7 +144,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf index 2848c4b0c7..d5d1e89f1f 100644 --- a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf +++ b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.inf @@ -39,6 +39,7 @@ BaseMemoryLib DebugLib HobLib + CommonMemoryAllocationLib [Guids] gEfiMmPeiMmramMemoryReserveGuid diff --git a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c index b38b32b27f..b3b38a1568 100644 --- a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c +++ b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c @@ -12,344 +12,83 @@ #include #include -#include +#include #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiRuntimeServicesData; + /** Allocates one or more 4KB pages of a certain memory type. - Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated - buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. - If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. If + Pages is 0, then NULL is returned. If there is not enough memory remaining to + satisfy the request, then NULL is returned. + @param Type The type of allocation to perform. @param MemoryType The type of memory to allocate. @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or + AllocateMaxAddress or AllocateAddress. + 2) MemoryType is in the range + EfiMaxMemoryType..0x6FFFFFFF. + 3) Memory is NULL. + 4) MemoryType is EfiPersistentMemory. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * -InternalAllocatePages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages +EFI_STATUS +EFIAPI +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - if (Pages == 0) { - return NULL; + return EFI_INVALID_PARAMETER; } - Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return InternalAllocatePages (EfiRuntimeServicesData, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return NULL; + return gMmst->MmAllocatePages (Type, MemoryType, Pages, Memory); } /** Frees one or more 4KB pages that were previously allocated with one of the page allocation functions in the Memory Allocation Library. - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with a page allocation function in the Memory Allocation Library, - then ASSERT(). - If Pages is zero, then ASSERT(). - - @param Buffer Pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. - -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - EFI_STATUS Status; - - ASSERT (Pages != 0); - Status = gMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); -} - -/** - Allocates one or more 4KB pages of a certain memory type at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment - specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned. - If there is not enough memory at the specified alignment remaining to satisfy the request, then - NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param MemoryType The type of memory to allocate. - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. - // - ASSERT (RealPages > Pages); - - Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = gMmst->MmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = (EFI_PHYSICAL_ADDRESS)(AlignedMemory + EFI_PAGES_TO_SIZE (Pages)); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = gMmst->MmFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Status = gMmst->MmAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return NULL; -} - -/** - Frees one or more 4KB pages that were previously allocated with one of the aligned page - allocation functions in the Memory Allocation Library. - - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the aligned page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. - - If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer Pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). + **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - EFI_STATUS Status; - ASSERT (Pages != 0); - Status = gMmst->MmFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Pages); - ASSERT_EFI_ERROR (Status); + return gMmst->MmFreePages (Memory, Pages); } /** @@ -366,7 +105,8 @@ FreeAlignedPages ( **/ VOID * -InternalAllocatePool ( +EFIAPI +PhaseAllocatePool ( IN EFI_MEMORY_TYPE MemoryType, IN UINTN AllocationSize ) @@ -384,420 +124,6 @@ InternalAllocatePool ( return Memory; } -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Allocates and zeros a buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer - with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid - buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, - then NULL is returned. - - @param PoolType The type of memory to allocate. - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateZeroPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize - ) -{ - VOID *Memory; - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = ZeroMem (Memory, AllocationSize); - } - - return Memory; -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return NULL; -} - -/** - Copies a buffer to an allocated buffer of a certain pool type. - - Allocates the number bytes specified by AllocationSize of a certain pool type, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalAllocateCopyPool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - ASSERT (Buffer != NULL); - ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN)Buffer + 1)); - - Memory = InternalAllocatePool (PoolType, AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return NULL; -} - -/** - Reallocates a buffer of a specified memory type. - - Allocates and zeros the number bytes specified by NewSize from memory of the type - specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param PoolType The type of pool to allocate. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -InternalReallocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return NULL; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -814,7 +140,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf index f5aaff1a25..bcf7eb120d 100644 --- a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf +++ b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf @@ -35,3 +35,4 @@ BaseMemoryLib DebugLib MmServicesTableLib + CommonMemoryAllocationLib diff --git a/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c index daf5fbd174..c82a8c7c4e 100755 --- a/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c +++ b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c @@ -9,14 +9,17 @@ **/ #include +#include #include #include -#include +#include #include #include #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; + /** Add a new HOB to the HOB List. @@ -35,7 +38,7 @@ CreateHob ( ); /** - Allocates one or more pages of type EfiBootServicesData. + Allocates one or more pages . Allocates the number of pages of MemoryType and returns a pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary. @@ -85,32 +88,49 @@ PayloadAllocatePages ( } /** - Allocates one or more pages of type EfiBootServicesData. - - Allocates the number of pages of MemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. - If Pages is 0, then NULL is returned. - If there is not enough memory availble to satisfy the request, then NULL - is returned. + Allocates one or more 4KB pages of a certain memory type. + + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. + + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. + + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or + AllocateMaxAddress or AllocateAddress. + 2) MemoryType is in the range + EfiMaxMemoryType..0x6FFFFFFF. + 3) Memory is NULL. + 4) MemoryType is EfiPersistentMemory. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. - @param Pages The number of 4 KB pages to allocate. - @return A pointer to the allocated buffer or NULL if allocation fails. **/ -VOID * +EFI_STATUS EFIAPI -AllocatePages ( - IN UINTN Pages +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { EFI_PEI_HOB_POINTERS Hob; EFI_PHYSICAL_ADDRESS Offset; EFI_HOB_HANDOFF_INFO_TABLE *HobTable; + ASSERT (Type == AllocateAnyPages); + Hob.Raw = GetHobList (); HobTable = Hob.HandoffInformationTable; if (Pages == 0) { - return NULL; + return EFI_INVALID_PARAMETER; } // Make sure allocation address is page aligned. @@ -123,94 +143,48 @@ AllocatePages ( // Check available memory for the allocation // if (HobTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < HobTable->EfiFreeMemoryBottom) { - return NULL; + return EFI_OUT_OF_RESOURCES; } HobTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE; - BuildMemoryAllocationHob (HobTable->EfiFreeMemoryTop, Pages * EFI_PAGE_SIZE, EfiBootServicesData); + BuildMemoryAllocationHob (HobTable->EfiFreeMemoryTop, Pages * EFI_PAGE_SIZE, MemoryType); - return (VOID *)(UINTN)HobTable->EfiFreeMemoryTop; + *Memory = HobTable->EfiFreeMemoryTop; + return EFI_SUCCESS; } /** Frees one or more 4KB pages that were previously allocated with one of the page allocation functions in the Memory Allocation Library. - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. - If Buffer was not allocated with a page allocation function in the Memory Allocation Library, - then ASSERT(). + If Buffer was not allocated with a page allocation function in the Memory Allocation + Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer Pointer to the buffer of pages to free. + @param Memory The base physical address of the pages to be freed. @param Pages The number of 4 KB pages to free. -**/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ -} - -/** - Allocates one or more pages of type EfiBootServicesData at a specified alignment. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). - Allocates the number of pages specified by Pages of type EfiBootServicesData with an - alignment specified by Alignment. - If Pages is 0, then NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If there is no enough memory at the specified alignment available to satisfy the - request, then NULL is returned. - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. - - @return A pointer to the allocated buffer or NULL if allocation fails. **/ -VOID * +EFI_STATUS EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - VOID *Memory; - UINTN AlignmentMask; - - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { - return NULL; - } - - // - // Check overflow. - // - ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment))); - - Memory = (VOID *)(UINTN)AllocatePages (Pages + EFI_SIZE_TO_PAGES (Alignment)); - if (Memory == NULL) { - return NULL; - } - - if (Alignment == 0) { - AlignmentMask = Alignment; - } else { - AlignmentMask = Alignment - 1; - } - - return (VOID *)(UINTN)(((UINTN)Memory + AlignmentMask) & ~AlignmentMask); + return EFI_SUCCESS; } + /** Allocates a buffer of type EfiBootServicesData. @@ -218,6 +192,7 @@ AllocateAlignedPages ( pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + @param MemoryType The type of memory to allocate. @param AllocationSize The number of bytes to allocate. @return A pointer to the allocated buffer or NULL if allocation fails. @@ -225,8 +200,9 @@ AllocateAlignedPages ( **/ VOID * EFIAPI -AllocatePool ( - IN UINTN AllocationSize +PhaseAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize ) { EFI_HOB_MEMORY_POOL *Hob; @@ -240,37 +216,6 @@ AllocatePool ( return (VOID *)(Hob + 1); } -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = AllocatePool (AllocationSize); - if (Buffer == NULL) { - return NULL; - } - - ZeroMem (Buffer, AllocationSize); - - return Buffer; -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -287,7 +232,7 @@ AllocateZeroPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.inf b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.inf index 46ca835552..fa9982ab2f 100755 --- a/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.inf +++ b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/UefiPayloadMemoryAllocationLib.inf @@ -37,3 +37,4 @@ BaseMemoryLib BaseLib HobLib + CommonMemoryAllocationLib diff --git a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c index 4ebdef1863..a4e89b0af8 100644 --- a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c +++ b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include /// @@ -40,133 +40,49 @@ typedef struct { UINT32 TotalSize; } POOL_HEAD; -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ) -{ - return AllocateAlignedPages (Pages, SIZE_4KB); -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ) -{ - return AllocatePages (Pages); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType. - - Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPages ( - IN UINTN Pages - ) -{ - return AllocatePages (Pages); -} +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; /** - Frees one or more 4KB pages that were previously allocated with one of the page allocation - functions in the Memory Allocation Library. + Allocates one or more 4KB pages of a certain memory type. - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. - If Buffer was not allocated with a page allocation function in the Memory Allocation Library, - then ASSERT(). - If Pages is zero, then ASSERT(). + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_INVALID_PARAMETER 1) Type is not AllocateAnyPages or + AllocateMaxAddress or AllocateAddress. + 2) MemoryType is in the range + EfiMaxMemoryType..0x6FFFFFFF. + 3) Memory is NULL. + 4) MemoryType is EfiPersistentMemory. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID -EFIAPI -FreePages ( - IN VOID *Buffer, - IN UINTN Pages - ) -{ - FreeAlignedPages (Buffer, Pages); -} - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/VOID * +EFI_STATUS EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { PAGE_HEAD PageHead; PAGE_HEAD *PageHeadPtr; + UINTN Alignment; UINTN AlignmentMask; - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Alignment < SIZE_4KB) { - Alignment = SIZE_4KB; - } + ASSERT (Type == AllocateAnyPages); + Alignment = SIZE_4KB; AlignmentMask = Alignment - 1; // @@ -176,6 +92,9 @@ AllocateAlignedPages ( PageHead.TotalPages = Pages + EFI_SIZE_TO_PAGES (Alignment) * 2; PageHead.AlignedPages = Pages; PageHead.AllocatedBuffer = malloc (EFI_PAGES_TO_SIZE (PageHead.TotalPages)); + if (PageHead.AllocatedBuffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } ASSERT (PageHead.AllocatedBuffer != NULL); @@ -189,96 +108,45 @@ AllocateAlignedPages ( PageHeadPtr = (VOID *)((UINTN)PageHead.AlignedBuffer - sizeof (PAGE_HEAD)); memcpy (PageHeadPtr, &PageHead, sizeof (PAGE_HEAD)); - return PageHead.AlignedBuffer; -} - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedRuntimePages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return AllocateAlignedPages (Pages, Alignment); -} - -/** - Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedReservedPages ( - IN UINTN Pages, - IN UINTN Alignment - ) -{ - return AllocateAlignedPages (Pages, Alignment); + *Memory = (UINTN)PageHead.AlignedBuffer; + return EFI_SUCCESS; } /** - Frees one or more 4KB pages that were previously allocated with one of the aligned page - allocation functions in the Memory Allocation Library. + Frees one or more 4KB pages that were previously allocated with one of the page allocation + functions in the Memory Allocation Library. - Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer - must have been allocated on a previous call to the aligned page allocation services of the Memory - Allocation Library. If it is not possible to free allocated pages, then this function will - perform no actions. + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. - If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, then ASSERT(). If Pages is zero, then ASSERT(). - @param Buffer The pointer to the buffer of pages to free. - @param Pages The number of 4 KB pages to free. + @param Memory The base physical address of the pages to be freed. + @param Pages The number of 4 KB pages to free. + + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). **/ -VOID +EFI_STATUS EFIAPI -FreeAlignedPages ( - IN VOID *Buffer, - IN UINTN Pages +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { PAGE_HEAD *PageHeadPtr; VOID *AllocatedBuffer; UINTN Length; - ASSERT (Buffer != NULL); + ASSERT (Memory != NULL); - PageHeadPtr = ((PAGE_HEAD *)Buffer) - 1; + PageHeadPtr = ((PAGE_HEAD *)Memory) - 1; ASSERT (PageHeadPtr != NULL); ASSERT (PageHeadPtr->Signature == PAGE_HEAD_PRIVATE_SIGNATURE); @@ -291,24 +159,28 @@ FreeAlignedPages ( DEBUG_CLEAR_MEMORY (AllocatedBuffer, Length); free (AllocatedBuffer); + + return EFI_SUCCESS; } /** - Allocates a buffer of type EfiBootServicesData. + Allocates a buffer of a certain pool type. - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a + Allocates the number bytes specified by AllocationSize of a certain pool type and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - @param AllocationSize The number of bytes to allocate. + @param MemoryType The type of memory to allocate. + @param AllocationSize The number of bytes to allocate. - @return A pointer to the allocated buffer or NULL if allocation fails. + @return A pointer to the allocated buffer or NULL if allocation fails. **/ VOID * EFIAPI -AllocatePool ( - IN UINTN AllocationSize +PhaseAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize ) { POOL_HEAD *PoolHead; @@ -327,318 +199,6 @@ AllocatePool ( return (VOID *)(PoolHead + 1); } -/** - Allocates a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePool ( - IN UINTN AllocationSize - ) -{ - return AllocatePool (AllocationSize); -} - -/** - Allocates a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns - a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedPool ( - IN UINTN AllocationSize - ) -{ - return AllocatePool (AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize - ) -{ - VOID *Buffer; - - Buffer = AllocatePool (AllocationSize); - if (Buffer == NULL) { - return NULL; - } - - memset (Buffer, 0, AllocationSize); - return Buffer; -} - -/** - Allocates and zeros a buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeZeroPool ( - IN UINTN AllocationSize - ) -{ - return AllocateZeroPool (AllocationSize); -} - -/** - Allocates and zeros a buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate and zero. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedZeroPool ( - IN UINTN AllocationSize - ) -{ - return AllocateZeroPool (AllocationSize); -} - -/** - Copies a buffer to an allocated buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - VOID *Memory; - - Memory = AllocatePool (AllocationSize); - if (Memory == NULL) { - return NULL; - } - - memcpy (Memory, Buffer, AllocationSize); - return Memory; -} - -/** - Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimeCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return AllocateCopyPool (AllocationSize, Buffer); -} - -/** - Copies a buffer to an allocated buffer of type EfiReservedMemoryType. - - Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). - - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateReservedCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ) -{ - return AllocateCopyPool (AllocationSize, Buffer); -} - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - NewBuffer = AllocatePool (NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - memcpy (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - } - - if (OldBuffer != NULL) { - FreePool (OldBuffer); - } - - return NewBuffer; -} - -/** - Reallocates a buffer of type EfiRuntimeServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateRuntimePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return ReallocatePool (OldSize, NewSize, OldBuffer); -} - -/** - Reallocates a buffer of type EfiReservedMemoryType. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocateReservedPool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - return ReallocatePool (OldSize, NewSize, OldBuffer); -} - /** Frees a buffer that was previously allocated with one of the pool allocation functions in the Memory Allocation Library. @@ -655,7 +215,7 @@ ReallocateReservedPool ( **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf index 1443600013..f9233ff994 100644 --- a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf +++ b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf @@ -29,3 +29,4 @@ [LibraryClasses] DebugLib + CommonMemoryAllocationLib From cd0db29940bba98b3e079ce961fba9410f3ffbc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Sun, 26 Mar 2023 19:20:28 +0200 Subject: [PATCH 055/341] EmulatorPkg/Host: Consume MemoryAllocationLib --- EmulatorPkg/Unix/Host/Host.inf | 1 + EmulatorPkg/Unix/Host/MemoryAllocationLib.c | 147 +++++++++------- EmulatorPkg/Win/Host/WinHost.inf | 1 + EmulatorPkg/Win/Host/WinMemoryAllocationLib.c | 162 ++++++++---------- 4 files changed, 152 insertions(+), 159 deletions(-) diff --git a/EmulatorPkg/Unix/Host/Host.inf b/EmulatorPkg/Unix/Host/Host.inf index 806bb52c65..f44d060721 100644 --- a/EmulatorPkg/Unix/Host/Host.inf +++ b/EmulatorPkg/Unix/Host/Host.inf @@ -61,6 +61,7 @@ PpiListLib PeiServicesLib StackCheckLib + CommonMemoryAllocationLib [Ppis] gEfiPeiStatusCodePpiGuid # PPI ALWAYS_PRODUCED diff --git a/EmulatorPkg/Unix/Host/MemoryAllocationLib.c b/EmulatorPkg/Unix/Host/MemoryAllocationLib.c index 4e3c8faa3c..7eb6b0366b 100644 --- a/EmulatorPkg/Unix/Host/MemoryAllocationLib.c +++ b/EmulatorPkg/Unix/Host/MemoryAllocationLib.c @@ -6,109 +6,124 @@ **/ -#include "Base.h" -#include "Library/BaseMemoryLib.h" -#include "Library/MemoryAllocationLib.h" +#include "Uefi.h" +#include "Library/PhaseMemoryAllocationLib.h" +#include #include +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode; + /** - Allocates a buffer of type EfiBootServicesData. + Allocates one or more 4KB pages of a certain memory type. - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. - @param AllocationSize The number of bytes to allocate. + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * +EFI_STATUS EFIAPI -AllocatePool ( - IN UINTN AllocationSize +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - return (VOID *)malloc (AllocationSize); + UINTN DestSize; + VOID *Buffer; + + DestSize = EFI_PAGES_TO_SIZE (Pages); + Buffer = mmap ( + NULL, + DestSize, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, + -1, + 0 + ); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + *Memory = (UINTN)Buffer; + + return EFI_SUCCESS; } /** - Allocates and zeros a buffer of type EfiBootServicesData. + Frees one or more 4KB pages that were previously allocated with one of the page allocation + functions in the Memory Allocation Library. - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. - @param AllocationSize The number of bytes to allocate and zero. + If Buffer was not allocated with a page allocation function in the Memory Allocation + Library, then ASSERT(). + If Pages is zero, then ASSERT(). - @return A pointer to the allocated buffer or NULL if allocation fails. + @param Memory The base physical address of the pages to be freed. + @param Pages The number of 4 KB pages to free. + + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). **/ -VOID * +EFI_STATUS EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - VOID *Buffer; + UINTN DestSize; + INT32 Result; - Buffer = AllocatePool (AllocationSize); - if (Buffer == NULL) { - return NULL; + DestSize = EFI_PAGES_TO_SIZE (Pages); + Result = munmap ((VOID *)(UINTN)Memory, DestSize); + if (Result != 0) { + return EFI_NOT_FOUND; } - ZeroMem (Buffer, AllocationSize); - - return Buffer; + return EFI_SUCCESS; } /** - Reallocates a buffer of type EfiBootServicesData. + Allocates a buffer of a certain pool type. - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + Allocates the number bytes specified by AllocationSize of a certain pool type and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. + @param MemoryType The type of memory to allocate. + @param AllocationSize The number of bytes to allocate. @return A pointer to the allocated buffer or NULL if allocation fails. **/ VOID * EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL +PhaseAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize ) { - VOID *NewBuffer; - - NewBuffer = AllocatePool (NewSize); - if (NewBuffer == NULL) { - return NULL; - } - - if (OldBuffer != NULL) { - if (OldSize > 0) { - CopyMem (NewBuffer, OldBuffer, OldSize); - } - - FreePool (OldBuffer); - } - - return NewBuffer; + return (VOID *)malloc (AllocationSize); } /** @@ -122,12 +137,12 @@ ReallocatePool ( If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, then ASSERT(). - @param Buffer Pointer to the buffer to free. + @param Buffer The pointer to the buffer to free. **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { diff --git a/EmulatorPkg/Win/Host/WinHost.inf b/EmulatorPkg/Win/Host/WinHost.inf index 3a4adcb711..fd7a33ce71 100644 --- a/EmulatorPkg/Win/Host/WinHost.inf +++ b/EmulatorPkg/Win/Host/WinHost.inf @@ -56,6 +56,7 @@ PeiServicesLib FrameBufferBltLib StackCheckLib + CommonMemoryAllocationLib [Ppis] gEmuThunkPpiGuid diff --git a/EmulatorPkg/Win/Host/WinMemoryAllocationLib.c b/EmulatorPkg/Win/Host/WinMemoryAllocationLib.c index 4d972d2c2e..c56b3508de 100644 --- a/EmulatorPkg/Win/Host/WinMemoryAllocationLib.c +++ b/EmulatorPkg/Win/Host/WinMemoryAllocationLib.c @@ -6,143 +6,119 @@ **/ -#include -#include -#include +#include "WinHost.h" -#include - -/** - Allocates a buffer of type EfiBootServicesData. +#include - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. +#include -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ) -{ - return (VOID *)malloc (AllocationSize); -} +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode; /** - Allocates and zeros a buffer of type EfiBootServicesData. + Allocates one or more 4KB pages of a certain memory type. - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the - buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a - valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the - request, then NULL is returned. + Allocates the number of 4KB pages of a certain memory type and returns a pointer + to the allocated buffer. The buffer returned is aligned on a 4KB boundary. - @param AllocationSize The number of bytes to allocate and zero. + @param Type The type of allocation to perform. + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Memory The pointer to a physical address. On input, the + way in which the address is used depends on the + value of Type. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_NOT_FOUND The requested pages could not be found. **/ -VOID * +EFI_STATUS EFIAPI -AllocateZeroPool ( - IN UINTN AllocationSize +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - VOID *Buffer; + UINTN DestSize; + VOID *Buffer; - Buffer = AllocatePool (AllocationSize); + ASSERT (Type == AllocateAnyPages); + + DestSize = EFI_PAGES_TO_SIZE (Pages); + Buffer = VirtualAlloc (NULL, (SIZE_T) DestSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (Buffer == NULL) { - return NULL; + return EFI_OUT_OF_RESOURCES; } - ZeroMem (Buffer, AllocationSize); + *Memory = (UINTN)Buffer; - return Buffer; + return EFI_SUCCESS; } /** - Reallocates a buffer of type EfiBootServicesData. + Frees one or more 4KB pages that were previously allocated with one of the page allocation + functions in the Memory Allocation Library. - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. + Buffer must have been allocated on a previous call to the page allocation services + of the Memory Allocation Library. If it is not possible to free allocated pages, + then this function will perform no actions. - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + If Buffer was not allocated with a page allocation function in the Memory Allocation + Library, then ASSERT(). + If Pages is zero, then ASSERT(). - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. + @param Memory The base physical address of the pages to be freed. + @param Pages The number of 4 KB pages to free. - @return A pointer to the allocated buffer or NULL if allocation fails. + @retval EFI_SUCCESS The requested pages were freed. + @retval EFI_NOT_FOUND The requested memory pages were not allocated with + PhaseAllocatePages(). **/ -VOID * +EFI_STATUS EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - VOID *NewBuffer; - - NewBuffer = AllocatePool (NewSize); - if (NewBuffer == NULL) { - return NULL; - } - - if (OldBuffer != NULL) { - if (OldSize > 0) { - CopyMem (NewBuffer, OldBuffer, OldSize); - } + UINTN DestSize; + INT32 Success; - FreePool (OldBuffer); + DestSize = EFI_PAGES_TO_SIZE (Pages); + Success = VirtualFree ((VOID *)(UINTN)Memory, (SIZE_T) DestSize, MEM_DECOMMIT); + if (!Success) { + return EFI_NOT_FOUND; } - return NewBuffer; + return EFI_SUCCESS; } /** - Copies a buffer to an allocated buffer of type EfiBootServicesData. + Allocates a buffer of a certain pool type. - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies - AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the - allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there - is not enough memory remaining to satisfy the request, then NULL is returned. - - If Buffer is NULL, then ASSERT(). - If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + Allocates the number bytes specified by AllocationSize of a certain pool type and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - @param AllocationSize The number of bytes to allocate and zero. - @param Buffer The buffer to copy to the allocated buffer. + @param MemoryType The type of memory to allocate. + @param AllocationSize The number of bytes to allocate. @return A pointer to the allocated buffer or NULL if allocation fails. **/ VOID * EFIAPI -AllocateCopyPool ( - IN UINTN AllocationSize, - IN CONST VOID *Buffer +PhaseAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize ) { - VOID *Memory; - - Memory = AllocatePool (AllocationSize); - if (Memory != NULL) { - Memory = CopyMem (Memory, Buffer, AllocationSize); - } - - return Memory; + return (VOID *)malloc (AllocationSize); } /** @@ -156,12 +132,12 @@ AllocateCopyPool ( If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, then ASSERT(). - @param Buffer Pointer to the buffer to free. + @param Buffer The pointer to the buffer to free. **/ VOID EFIAPI -FreePool ( +PhaseFreePool ( IN VOID *Buffer ) { From 6b652ab025dd60e11247ec56ea823fb6c6fdac3a Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 7 Apr 2025 12:16:51 +0300 Subject: [PATCH 056/341] MdePkg/MemoryAllocationLib: Add Allocate(Aligned)CodePages --- EmbeddedPkg/Library/PrePiLib/PrePiLib.c | 33 -------------- .../MemoryAllocationLib.c | 1 + .../MemoryAllocationLib.c | 1 + .../Core/PiSmmCore/MemoryAllocation.c | 1 + .../BaseMemoryAllocationLibNull.c | 1 + .../CommonMemoryAllocationLib.c | 40 +++++++++++++++++ .../MemoryAllocationLib.c | 1 + MdePkg/Include/Library/MemoryAllocationLib.h | 44 +++++++++++++++++++ .../Library/PhaseMemoryAllocationLib.h | 5 +++ .../MemoryAllocationLib.c | 1 + .../MemoryAllocationLib.c | 1 + .../MemoryAllocationLib.c | 1 + .../StandaloneMmCoreMemoryAllocationLib.c | 1 + .../StandaloneMmMemoryAllocationLib.c | 1 + UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c | 27 ------------ UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h | 12 ----- .../MemoryAllocationLib.c | 1 + UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c | 37 ---------------- .../MemoryAllocationLibPosix.c | 1 + 19 files changed, 101 insertions(+), 109 deletions(-) diff --git a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c index 650d864264..98d5eee1cc 100644 --- a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c +++ b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c @@ -6,7 +6,6 @@ **/ -#include "ProcessorBind.h" #include // @@ -23,38 +22,6 @@ SecWinNtPeiLoadFile ( IN EFI_PHYSICAL_ADDRESS *EntryPoint ); -STATIC -VOID * -EFIAPI -AllocateCodePages ( - IN UINTN Pages - ) -{ - VOID *Alloc; - EFI_PEI_HOB_POINTERS Hob; - - Alloc = AllocatePages (Pages); - if (Alloc == NULL) { - return NULL; - } - - // find the HOB we just created, and change the type to EfiBootServicesCode - Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION); - while (Hob.Raw != NULL) { - if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == (UINTN)Alloc) { - Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiBootServicesCode; - return Alloc; - } - - Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (Hob)); - } - - ASSERT (FALSE); - - FreePages (Alloc, Pages); - return NULL; -} - EFI_STATUS EFIAPI LoadUefiImage ( diff --git a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c index e056cdb9ed..24bf5142d9 100644 --- a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c +++ b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c @@ -16,6 +16,7 @@ #include GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode; EFI_STATUS EFIAPI diff --git a/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c b/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c index 23aa0b1b7b..dea5363463 100644 --- a/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c +++ b/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c @@ -24,6 +24,7 @@ #include GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode; /** Allocates one or more 4KB pages of a certain memory type. diff --git a/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c b/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c index 66f075531e..e3779c6291 100644 --- a/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c +++ b/MdeModulePkg/Core/PiSmmCore/MemoryAllocation.c @@ -28,6 +28,7 @@ #include GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiRuntimeServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiRuntimeServicesCode; EFI_SMRAM_DESCRIPTOR *mSmmCoreMemoryAllocLibSmramRanges = NULL; UINTN mSmmCoreMemoryAllocLibSmramRangeCount = 0; diff --git a/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.c b/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.c index bd661ca428..2dbb465a7d 100644 --- a/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.c +++ b/MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.c @@ -13,6 +13,7 @@ #include GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode; /** Allocates one or more 4KB pages of a certain memory type. diff --git a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c index 6eed53cfc8..18365a70b9 100644 --- a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c +++ b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c @@ -143,6 +143,36 @@ AllocateReservedPages ( return Buffer; } +/** + Allocates one or more 4KB pages of type EfiBootServicesCode. + + Allocates the number of 4KB pages of type EfiBootServicesCode and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateCodePages ( + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + + Status = PhaseAllocatePages (AllocateAnyPages, gPhaseDefaultCodeType, Pages, &Memory); + if (EFI_ERROR (Status)) { + return NULL; + } + + return (VOID *)(UINTN)Memory; +} + /** Frees one or more 4KB pages that were previously allocated with one of the page allocation functions in the Memory Allocation Library. @@ -342,6 +372,16 @@ AllocateAlignedReservedPages ( return Buffer; } +VOID * +EFIAPI +AllocateAlignedCodePages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + return InternalAllocateAlignedPages (gPhaseDefaultCodeType, Pages, Alignment); +} + /** Frees one or more 4KB pages that were previously allocated with one of the aligned page allocation functions in the Memory Allocation Library. diff --git a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c index 1d8a263947..1b82e7672c 100644 --- a/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c @@ -16,6 +16,7 @@ #include "DxeCoreMemoryAllocationServices.h" GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode; /** Allocates one or more 4KB pages of a certain memory type. diff --git a/MdePkg/Include/Library/MemoryAllocationLib.h b/MdePkg/Include/Library/MemoryAllocationLib.h index 9dd841004d..59d4b29c44 100644 --- a/MdePkg/Include/Library/MemoryAllocationLib.h +++ b/MdePkg/Include/Library/MemoryAllocationLib.h @@ -71,6 +71,25 @@ AllocateReservedPages ( IN UINTN Pages ); +/** + Allocates one or more 4KB pages of type EfiBootServicesCode. + + Allocates the number of 4KB pages of type EfiBootServicesCode and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateCodePages ( + IN UINTN Pages + ); + /** Frees one or more 4KB pages that were previously allocated with one of the page allocation functions in the Memory Allocation Library. @@ -170,6 +189,31 @@ AllocateAlignedReservedPages ( IN UINTN Alignment ); +/** + Allocates one or more 4KB pages of type EfiBootServicesCode at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiBootServicesCode with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateAlignedCodePages ( + IN UINTN Pages, + IN UINTN Alignment + ); + /** Frees one or more 4KB pages that were previously allocated with one of the aligned page allocation functions in the Memory Allocation Library. diff --git a/MdePkg/Include/Library/PhaseMemoryAllocationLib.h b/MdePkg/Include/Library/PhaseMemoryAllocationLib.h index fbe1ad6e1f..a7c45dd9a4 100644 --- a/MdePkg/Include/Library/PhaseMemoryAllocationLib.h +++ b/MdePkg/Include/Library/PhaseMemoryAllocationLib.h @@ -114,4 +114,9 @@ PhaseFreePool ( /// extern CONST EFI_MEMORY_TYPE gPhaseDefaultDataType; +/// +/// The memory type to allocate for calls to AllocateCodePages(). +/// +extern CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType; + #endif diff --git a/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c b/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c index 619a3664f7..4e5ad5b1bb 100644 --- a/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c @@ -17,6 +17,7 @@ #include GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode; /** Allocates one or more 4KB pages of a certain memory type. diff --git a/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c b/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c index 0dfd86bedd..bf69b15330 100644 --- a/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdePkg/Library/SmmMemoryAllocationLib/MemoryAllocationLib.c @@ -28,6 +28,7 @@ #include GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiRuntimeServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiRuntimeServicesCode; EFI_SMRAM_DESCRIPTOR *mSmramRanges; UINTN mSmramRangeCount; diff --git a/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c b/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c index 4b7e18f2e0..9768a3c301 100644 --- a/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c @@ -15,6 +15,7 @@ #include GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode; /** Allocates one or more 4KB pages of a certain memory type. diff --git a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c index 63ee134159..33ce184e2b 100644 --- a/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c +++ b/StandaloneMmPkg/Library/StandaloneMmCoreMemoryAllocationLib/StandaloneMmCoreMemoryAllocationLib.c @@ -18,6 +18,7 @@ #include "StandaloneMmCoreMemoryAllocationServices.h" GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiRuntimeServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiRuntimeServicesCode; static EFI_MM_SYSTEM_TABLE *mMemoryAllocationMmst = NULL; diff --git a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c index b3b38a1568..996acdb6d3 100644 --- a/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c +++ b/StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.c @@ -16,6 +16,7 @@ #include GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiRuntimeServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiRuntimeServicesCode; /** Allocates one or more 4KB pages of a certain memory type. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c index 5e24c12548..291759f479 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.c @@ -1484,33 +1484,6 @@ ConfigSmmCodeAccessCheck ( PERF_FUNCTION_END (); } -/** - Allocate pages for code. - - @param[in] Pages Number of pages to be allocated. - - @return Allocated memory. -**/ -VOID * -AllocateCodePages ( - IN UINTN Pages - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - - if (Pages == 0) { - return NULL; - } - - Status = gMmst->MmAllocatePages (AllocateAnyPages, EfiRuntimeServicesCode, Pages, &Memory); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - /** Perform the pre tasks. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h index d0ad3be63a..2bde958e18 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuCommon.h @@ -1144,18 +1144,6 @@ AllocatePageTableMemory ( IN UINTN Pages ); -/** - Allocate pages for code. - - @param[in] Pages Number of pages to be allocated. - - @return Allocated memory. -**/ -VOID * -AllocateCodePages ( - IN UINTN Pages - ); - // // S3 related global variable and function prototype. // diff --git a/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c index c82a8c7c4e..42b5b776ce 100755 --- a/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c +++ b/UefiPayloadPkg/Library/UefiPayloadMemoryAllocationLib/MemoryAllocationLib.c @@ -19,6 +19,7 @@ #include GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode; /** Add a new HOB to the HOB List. diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c index 5904d9cb51..bdec06e974 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c @@ -8,43 +8,6 @@ #include "UefiPayloadEntry.h" -/** - Allocate pages for code. - - @param[in] Pages Number of pages to be allocated. - - @return Allocated memory. -**/ -VOID * -AllocateCodePages ( - IN UINTN Pages - ) -{ - VOID *Alloc; - EFI_PEI_HOB_POINTERS Hob; - - Alloc = AllocatePages (Pages); - if (Alloc == NULL) { - return NULL; - } - - // find the HOB we just created, and change the type to EfiBootServicesCode - Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION); - while (Hob.Raw != NULL) { - if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == (UINTN)Alloc) { - Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiBootServicesCode; - return Alloc; - } - - Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (Hob)); - } - - ASSERT (FALSE); - - FreePages (Alloc, Pages); - return NULL; -} - /** Loads and relocates a PE/COFF image diff --git a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c index a4e89b0af8..b44452d879 100644 --- a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c +++ b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c @@ -41,6 +41,7 @@ typedef struct { } POOL_HEAD; GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode; /** Allocates one or more 4KB pages of a certain memory type. From 7fb834ffacbe46680dc7cf508ad4c327d573272c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Sun, 26 Mar 2023 23:06:23 +0200 Subject: [PATCH 057/341] EmbeddedPkg/NonCoherentDmaLib: Utilize AllocateAlignedPagesEx --- .../NonCoherentDmaLib/NonCoherentDmaLib.c | 83 +++---------------- 1 file changed, 11 insertions(+), 72 deletions(-) diff --git a/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c b/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c index 403cc8e2fd..bff4c99a9f 100644 --- a/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c +++ b/EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -81,82 +82,20 @@ InternalAllocateAlignedPages ( { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - // - // Alignment must be a power of two or zero. - // - ASSERT ((Alignment & (Alignment - 1)) == 0); - - if (Pages == 0) { + Memory = mDmaHostAddressLimit; + Status = AllocateAlignedPagesEx ( + AllocateMaxAddress, + MemoryType, + Pages, + Alignment, + &Memory + ); + if (EFI_ERROR (Status)) { return NULL; } - if (Alignment > EFI_PAGE_SIZE) { - // - // Calculate the total number of pages since alignment is larger than page - // size. - // - AlignmentMask = Alignment - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); - // - // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not - // overflow. - // - ASSERT (RealPages > Pages); - - Memory = mDmaHostAddressLimit; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - MemoryType, - RealPages, - &Memory - ); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = gBS->FreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = gBS->FreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Do not over-allocate pages in this case. - // - Memory = mDmaHostAddressLimit; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - MemoryType, - Pages, - &Memory - ); - if (EFI_ERROR (Status)) { - return NULL; - } - - AlignedMemory = (UINTN)Memory; - } - - return (VOID *)AlignedMemory; + return (VOID *)(UINTN)Memory; } /** From 0a18e628cac1303af0c8613aa0f5f353ca96650e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Sun, 26 Mar 2023 23:08:15 +0200 Subject: [PATCH 058/341] EmbeddedPkg/PrePiLib: Deduplicate MemoryAllocationLib declarations --- EmbeddedPkg/Include/Library/PrePiLib.h | 81 +------------------------- 1 file changed, 2 insertions(+), 79 deletions(-) diff --git a/EmbeddedPkg/Include/Library/PrePiLib.h b/EmbeddedPkg/Include/Library/PrePiLib.h index a76d4c5686..cf64eaf661 100644 --- a/EmbeddedPkg/Include/Library/PrePiLib.h +++ b/EmbeddedPkg/Include/Library/PrePiLib.h @@ -12,6 +12,8 @@ #include +#include + /** This service enables discovery of additional firmware volumes. @@ -683,85 +685,6 @@ BuildUefiLoaderHob ( VOID ); -/** - Allocates one or more 4KB pages of type EfiBootServicesData. - - Allocates the number of 4KB pages of MemoryType and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePages ( - IN UINTN Pages - ); - -/** - Allocates one or more 4KB pages of type EfiRuntimeServicesData. - - Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the - allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL - is returned. If there is not enough memory remaining to satisfy the request, then NULL is - returned. - - @param Pages The number of 4 KB pages to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateRuntimePages ( - IN UINTN Pages - ); - -/** - Allocates a buffer of type EfiBootServicesData. - - Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a - pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is - returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. - - @param AllocationSize The number of bytes to allocate. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocatePool ( - IN UINTN AllocationSize - ); - -/** - Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an - alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is - returned. If there is not enough memory at the specified alignment remaining to satisfy the - request, then NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -AllocateAlignedPages ( - IN UINTN Pages, - IN UINTN Alignment - ); - EFI_STATUS EFIAPI LoadUefiImage ( From f60f34fabf2cae788cbb04284c088774faa992ca Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 4 May 2023 15:35:29 +0300 Subject: [PATCH 059/341] BaseTools/CommonLib: Consume MemoryAllocationLib --- BaseTools/Source/C/Common/CommonLib.c | 138 ++++++++++-------- BaseTools/Source/C/Common/GNUmakefile | 7 + BaseTools/Source/C/Common/Makefile | 7 + BaseTools/Source/C/Makefiles/ms.rule | 9 ++ .../CommonMemoryAllocationLib/AlignedPages.c | 84 +++++++++++ .../CommonMemoryAllocationLib/AlignedPages.h | 60 ++++++++ .../CommonMemoryAllocationLib.c | 51 +------ .../CommonMemoryAllocationLib.inf | 2 + 8 files changed, 250 insertions(+), 108 deletions(-) create mode 100644 MdeModulePkg/Library/CommonMemoryAllocationLib/AlignedPages.c create mode 100644 MdeModulePkg/Library/CommonMemoryAllocationLib/AlignedPages.h diff --git a/BaseTools/Source/C/Common/CommonLib.c b/BaseTools/Source/C/Common/CommonLib.c index 3f022fba46..80b62897ca 100644 --- a/BaseTools/Source/C/Common/CommonLib.c +++ b/BaseTools/Source/C/Common/CommonLib.c @@ -18,6 +18,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "CommonLib.h" #include "EfiUtilityMsgs.h" +#include +#include + +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; +GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode; + /** Compares to GUIDs @@ -483,107 +489,113 @@ LongFilePath ( } -VOID * -InternalAllocatePool ( - UINTN AllocationSize +static +void * +InternalAlignedAlloc ( + size_t Alignment, + size_t Size ) { - VOID * Memory; - - Memory = malloc(AllocationSize); - ASSERT(Memory != NULL); - return Memory; +#ifndef _WIN32 + return aligned_alloc (Alignment, Size); +#else + return _aligned_malloc (Size, Alignment); +#endif } - -VOID * -InternalReallocatePool ( - UINTN OldSize, - UINTN NewSize, - VOID *OldBuffer OPTIONAL +static +void +InternalAlignedFree ( + void *Ptr ) { - VOID *NewBuffer; - - NewBuffer = AllocateZeroPool (NewSize); - if (NewBuffer != NULL && OldBuffer != NULL) { - memcpy (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - free(OldBuffer); - } - return NewBuffer; +#ifndef _WIN32 + free (Ptr); +#else + _aligned_free (Ptr); +#endif } -VOID * +EFI_STATUS EFIAPI -ReallocatePool ( - UINTN OldSize, - UINTN NewSize, - VOID *OldBuffer OPTIONAL +PhaseAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - return InternalReallocatePool (OldSize, NewSize, OldBuffer); + VOID *Buffer; + UINTN BufferSize; + + ASSERT (Type == AllocateAnyPages); + + BufferSize = EFI_PAGES_TO_SIZE (Pages); + Buffer = InternalAlignedAlloc (EFI_PAGE_SIZE, BufferSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + *Memory = (UINTN)Buffer; + + return EFI_SUCCESS; } -VOID * -InternalAllocateCopyPool ( - UINTN AllocationSize, - CONST VOID *Buffer +EFI_STATUS +EFIAPI +PhaseFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages ) { - VOID *Memory; + VOID *Buffer; - ASSERT (Buffer != NULL); + Buffer = (VOID *)(UINTN)Memory; + InternalAlignedFree (Buffer); - Memory = malloc (AllocationSize); - if (Memory != NULL) { - Memory = memcpy (Memory, Buffer, AllocationSize); - } - return Memory; + return EFI_SUCCESS; } VOID * EFIAPI -AllocateCopyPool ( - UINTN AllocationSize, - CONST VOID *Buffer +PhaseAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize ) { - return InternalAllocateCopyPool (AllocationSize, Buffer); + return InternalAlignedAlloc (8, AllocationSize); } -VOID * +VOID EFIAPI -AllocateZeroPool ( - UINTN AllocationSize +PhaseFreePool ( + IN VOID *Buffer ) { - VOID * Memory; - Memory = malloc(AllocationSize); - ASSERT (Memory != NULL); - if (Memory == NULL) { - fprintf(stderr, "Not memory for malloc\n"); - } - memset(Memory, 0, AllocationSize); - return Memory; + ASSERT (Buffer != NULL); + InternalAlignedFree (Buffer); } VOID * -EFIAPI -AllocatePool ( - UINTN AllocationSize +InternalAllocateAlignedPages ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN UINTN Alignment ) { - return InternalAllocatePool (AllocationSize); + UINTN BufferSize; + + BufferSize = EFI_PAGES_TO_SIZE (Pages); + return InternalAlignedAlloc (MAX (Alignment, EFI_PAGE_SIZE), BufferSize); } VOID -EFIAPI -FreePool ( - IN VOID *Buffer +InternalFreeAlignedPages ( + IN VOID *Buffer, + IN UINTN Pages ) { - ASSERT (Buffer != NULL); - free (Buffer); + InternalAlignedFree (Buffer); } VOID diff --git a/BaseTools/Source/C/Common/GNUmakefile b/BaseTools/Source/C/Common/GNUmakefile index 17e166d62e..c5a49ffe2f 100644 --- a/BaseTools/Source/C/Common/GNUmakefile +++ b/BaseTools/Source/C/Common/GNUmakefile @@ -92,4 +92,11 @@ OBJECTS += \ $(EDK2_OBJPATH)/MdePkg/Library/BasePrintLib/PrintLib.o \ $(EDK2_OBJPATH)/MdePkg/Library/BasePrintLib/PrintLibInternal.o +OBJECTS += \ + $(EDK2_OBJPATH)/MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.o + +OBJECTS += \ + $(EDK2_OBJPATH)/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.o \ + $(EDK2_OBJPATH)/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLibEx.o + include $(MAKEROOT)/Makefiles/lib.makefile diff --git a/BaseTools/Source/C/Common/Makefile b/BaseTools/Source/C/Common/Makefile index c2abbca39b..e4982cbff4 100644 --- a/BaseTools/Source/C/Common/Makefile +++ b/BaseTools/Source/C/Common/Makefile @@ -91,6 +91,13 @@ OBJECTS = $(OBJECTS) \ $(EDK2_OBJPATH)\MdePkg\Library\BasePrintLib\PrintLib.obj \ $(EDK2_OBJPATH)\MdePkg\Library\BasePrintLib\PrintLibInternal.obj +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull\BaseMemoryProfileLibNull.obj + +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdeModulePkg\Library\CommonMemoryAllocationLib\CommonMemoryAllocationLib.obj \ + $(EDK2_OBJPATH)\MdeModulePkg\Library\CommonMemoryAllocationLib\CommonMemoryAllocationLibEx.obj + !INCLUDE ..\Makefiles\ms.lib diff --git a/BaseTools/Source/C/Makefiles/ms.rule b/BaseTools/Source/C/Makefiles/ms.rule index a7ea626592..97f43126ad 100644 --- a/BaseTools/Source/C/Makefiles/ms.rule +++ b/BaseTools/Source/C/Makefiles/ms.rule @@ -27,6 +27,15 @@ -@if not exist $(@D)\ mkdir $(@D) $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ +{$(EDK2_PATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull\}.c{$(EDK2_OBJPATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + +{$(EDK2_PATH)\MdeModulePkg\Library\CommonMemoryAllocationLib\}.c{$(EDK2_OBJPATH)\MdeModulePkg\Library\CommonMemoryAllocationLib\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + + .c.obj : $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ diff --git a/MdeModulePkg/Library/CommonMemoryAllocationLib/AlignedPages.c b/MdeModulePkg/Library/CommonMemoryAllocationLib/AlignedPages.c new file mode 100644 index 0000000000..47203089e3 --- /dev/null +++ b/MdeModulePkg/Library/CommonMemoryAllocationLib/AlignedPages.c @@ -0,0 +1,84 @@ +/** @file + Common code for the Memory Allocation Library aligned page allocation code. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +#include +#include + +#include "AlignedPages.h" + +/** + Allocates one or more 4KB pages of a certain memory type at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment + specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned. + If there is not enough memory at the specified alignment remaining to satisfy the request, then + NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +InternalAllocateAlignedPages ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN UINTN Alignment + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + + Status = AllocateAlignedPagesEx ( + AllocateAnyPages, + MemoryType, + Pages, + Alignment, + &Memory + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + return (VOID *)(UINTN)Memory; +} + +/** + Frees one or more 4KB pages that were previously allocated with one of the aligned page + allocation functions in the Memory Allocation Library. + + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer + must have been allocated on a previous call to the aligned page allocation services of the Memory + Allocation Library. If it is not possible to free allocated pages, then this function will + perform no actions. + + If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + Library, then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Buffer Pointer to the buffer of pages to free. + @param Pages The number of 4 KB pages to free. + +**/ +VOID +InternalFreeAlignedPages ( + IN VOID *Buffer, + IN UINTN Pages + ) +{ + FreePages (Buffer, Pages); +} diff --git a/MdeModulePkg/Library/CommonMemoryAllocationLib/AlignedPages.h b/MdeModulePkg/Library/CommonMemoryAllocationLib/AlignedPages.h new file mode 100644 index 0000000000..d5aa547b30 --- /dev/null +++ b/MdeModulePkg/Library/CommonMemoryAllocationLib/AlignedPages.h @@ -0,0 +1,60 @@ +/** @file + Common code for the Memory Allocation Library aligned page allocation code. + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef ALIGNED_PAGES_H_ +#define ALIGNED_PAGES_H_ + +/** + Allocates one or more 4KB pages of a certain memory type at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment + specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned. + If there is not enough memory at the specified alignment remaining to satisfy the request, then + NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +InternalAllocateAlignedPages ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN UINTN Alignment + ); + +/** + Frees one or more 4KB pages that were previously allocated with one of the aligned page + allocation functions in the Memory Allocation Library. + + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer + must have been allocated on a previous call to the aligned page allocation services of the Memory + Allocation Library. If it is not possible to free allocated pages, then this function will + perform no actions. + + If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + Library, then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Buffer Pointer to the buffer of pages to free. + @param Pages The number of 4 KB pages to free. + +**/ +VOID +InternalFreeAlignedPages ( + IN VOID *Buffer, + IN UINTN Pages + ); + +#endif // ALIGNED_PAGES_H_ diff --git a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c index 18365a70b9..7e02718a2b 100644 --- a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c +++ b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.c @@ -7,7 +7,9 @@ **/ -#include +#include +#include +#include #include #include @@ -17,6 +19,8 @@ #include +#include "AlignedPages.h" + /** Allocates one or more 4KB pages of type EfiBootServicesData. @@ -203,49 +207,6 @@ FreePages ( ASSERT_EFI_ERROR (Status); } -/** - Allocates one or more 4KB pages of a certain memory type at a specified alignment. - - Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment - specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned. - If there is not enough memory at the specified alignment remaining to satisfy the request, then - NULL is returned. - If Alignment is not a power of two and Alignment is not zero, then ASSERT(). - If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). - - @param MemoryType The type of memory to allocate. - @param Pages The number of 4 KB pages to allocate. - @param Alignment The requested alignment of the allocation. Must be a power of two. - If Alignment is zero, then byte alignment is used. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -STATIC -VOID * -InternalAllocateAlignedPages ( - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - IN UINTN Alignment - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Memory; - - Status = AllocateAlignedPagesEx ( - AllocateAnyPages, - MemoryType, - Pages, - Alignment, - &Memory - ); - if (EFI_ERROR (Status)) { - return NULL; - } - - return (VOID *)(UINTN)Memory; -} - /** Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. @@ -406,7 +367,7 @@ FreeAlignedPages ( IN UINTN Pages ) { - FreePages (Buffer, Pages); + InternalFreeAlignedPages (Buffer, Pages); } /** diff --git a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf index 8c806dc642..6bbecffbb0 100644 --- a/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf +++ b/MdeModulePkg/Library/CommonMemoryAllocationLib/CommonMemoryAllocationLib.inf @@ -23,6 +23,8 @@ # [Sources] + AlignedPages.h + AlignedPages.c CommonMemoryAllocationLib.c CommonMemoryAllocationLibEx.c From 27ffa568f54e05f3e5d4fa75aab855cb9b8075d9 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 26 Jun 2023 12:42:16 +0300 Subject: [PATCH 060/341] UefiCpuPkg/CpuExceptionHandlerLib: Creates unified ExceptionHandlerAsm This change removes Xcode5ExceptionHandlerAsm and merge it's functionality into ExceptionHandlerAsm. Also decreases number of vectors to 32 for: - 64-bit PeiCpuExceptionHandlerLib - 32-bit PeiCpuExceptionHandlerLib, SecPeiCpuExceptionHandlerLib Signed-off-by: Savva Mitrofanov --- .../CpuExceptionCommon.h | 1 + .../DxeCpuExceptionHandlerLib.inf | 3 - .../Ia32/ExceptionHandlerAsm.nasm | 11 +- .../Ia32/ExceptionTssEntryAsm.nasm | 1 + .../PeiCpuExceptionHandlerLib.inf | 4 +- .../PeiDxeSmmCpuException.c | 4 +- .../SecPeiCpuExceptionHandlerLib.inf | 4 +- .../SmmCpuExceptionHandlerLib.inf | 6 +- .../X64/ExceptionHandlerAsm.nasm | 44 +- .../X64/SecPeiExceptionHandlerAsm.nasm | 406 ------------------ 10 files changed, 36 insertions(+), 448 deletions(-) delete mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/SecPeiExceptionHandlerAsm.nasm diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h index 95877b8be0..6d3dc46b6e 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h @@ -57,6 +57,7 @@ typedef struct { UINTN ExceptionStart; UINTN ExceptionStubHeaderSize; UINTN HookAfterStubHeaderStart; + UINTN HookAfterStubHeaderSize; } EXCEPTION_HANDLER_TEMPLATE_MAP; typedef struct { diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf index e8b4deeddd..398c82d46f 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf @@ -74,8 +74,5 @@ [LibraryClasses.LoongArch64] CpuLib -[BuildOptions] - XCODE:*_*_X64_NASM_FLAGS = -D NO_ABSOLUTE_RELOCS_IN_TEXT - [Guids] gEfiDebugImageInfoTableGuid ## CONSUMES ## SystemTable diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm index 31a00449a2..9a92c931dd 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm @@ -14,6 +14,12 @@ ; ;------------------------------------------------------------------------------ +%ifdef CEHL_MINIMAL_INTERRUPTS +%define NUM_VECTORS 32 +%else +%define NUM_VECTORS 256 +%endif + ; ; CommonExceptionHandler() ; @@ -33,7 +39,7 @@ ALIGN 8 ; AsmIdtVectorBegin: %assign Vector 0 -%rep 256 +%rep NUM_VECTORS push strict dword %[Vector]; push eax mov eax, ASM_PFX(CommonInterruptEntry) @@ -438,8 +444,9 @@ ASM_PFX(AsmGetTemplateAddressMap): mov ebx, dword [ebp + 0x8] mov dword [ebx], AsmIdtVectorBegin - mov dword [ebx + 0x4], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 256 + mov dword [ebx + 0x4], (AsmIdtVectorEnd - AsmIdtVectorBegin) / NUM_VECTORS mov dword [ebx + 0x8], HookAfterStubBegin + mov dword [ebx + 0xC], HookAfterStubHeaderEnd - HookAfterStubBegin popad pop ebp diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.nasm index b63cfeac6d..8d91b04b53 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionTssEntryAsm.nasm @@ -382,6 +382,7 @@ ASM_PFX(AsmGetTssTemplateMap): mov dword [ebx], ASM_PFX(ExceptionTaskSwtichEntry0) mov dword [ebx + 0x4], (AsmExceptionEntryEnd - AsmExceptionEntryBegin) / 32 mov dword [ebx + 0x8], 0 + mov dword [ebx + 0xC], 0 popad pop ebp diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf index 3db1ad47ab..3caff1beb6 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf @@ -30,7 +30,7 @@ [Sources.X64] X64/ArchExceptionHandler.c X64/ArchInterruptDefs.h - X64/SecPeiExceptionHandlerAsm.nasm + X64/ExceptionHandlerAsm.nasm [Sources.common] CpuExceptionCommon.h @@ -63,4 +63,4 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES [BuildOptions] - XCODE:*_*_X64_NASM_FLAGS = -D NO_ABSOLUTE_RELOCS_IN_TEXT + *_*_*_NASM_FLAGS = -DCEHL_MINIMAL_INTERRUPTS diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c index 748cf8d3bf..c92e405b2c 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiDxeSmmCpuException.c @@ -206,7 +206,7 @@ UpdateIdtTable ( CopyMem ( (VOID *)ReservedVectors[Index].HookAfterStubHeaderCode, (VOID *)TemplateMap->HookAfterStubHeaderStart, - TemplateMap->ExceptionStubHeaderSize + TemplateMap->HookAfterStubHeaderSize ); AsmVectorNumFixup ( (VOID *)ReservedVectors[Index].HookAfterStubHeaderCode, @@ -279,7 +279,7 @@ InitializeCpuExceptionHandlersWorker ( IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor.Base; AsmGetTemplateAddressMap (&TemplateMap); - ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE); + ASSERT (TemplateMap.HookAfterStubHeaderSize <= HOOKAFTER_STUB_SIZE); UpdateIdtTable (IdtTable, &TemplateMap, ExceptionHandlerData); diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf index 55acb46ebe..827bcd0e36 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf @@ -32,7 +32,7 @@ [Sources.X64] X64/ArchExceptionHandler.c X64/ArchInterruptDefs.h - X64/SecPeiExceptionHandlerAsm.nasm + X64/ExceptionHandlerAsm.nasm [Sources.Ia32, Sources.X64] CpuExceptionCommon.h @@ -74,4 +74,4 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES [BuildOptions] - XCODE:*_*_X64_NASM_FLAGS = -D NO_ABSOLUTE_RELOCS_IN_TEXT + *_*_*_NASM_FLAGS = -DCEHL_MINIMAL_INTERRUPTS diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf index ef835ee9dc..de88041442 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf @@ -60,8 +60,8 @@ [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES -[BuildOptions] - XCODE:*_*_X64_NASM_FLAGS = -D NO_ABSOLUTE_RELOCS_IN_TEXT - [Guids] gEfiDebugImageInfoTableGuid ## CONSUMES ## SystemTable + +[BuildOptions] + *_*_*_NASM_FLAGS = -DCEHL_SUPPORTS_CET diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm index 3d64ac9080..4863686f14 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm @@ -36,6 +36,12 @@ struc IA32_IDT_GATE_DESCRIPTOR .Reserved_1 CTYPE_UINT32 1 endstruc +%ifdef CEHL_MINIMAL_INTERRUPTS +%define NUM_VECTORS 32 +%else +%define NUM_VECTORS 256 +%endif + ; ; CommonExceptionHandler() ; @@ -53,17 +59,14 @@ SECTION .text ALIGN 8 -; Generate 256 IDT vectors. +; Generate NUM_VECTORS IDT vectors. AsmIdtVectorBegin: %assign Vector 0 -%rep 256 +%rep NUM_VECTORS push strict dword %[Vector] ; This instruction pushes sign-extended 8-byte value on stack push rax -%ifdef NO_ABSOLUTE_RELOCS_IN_TEXT - mov rax, strict qword 0 ; mov rax, ASM_PFX(CommonInterruptEntry) -%else - mov rax, ASM_PFX(CommonInterruptEntry) -%endif + ; This code is not copied, thus relative addressing is safe. + lea rax, [ASM_PFX(CommonInterruptEntry)] jmp rax %assign Vector Vector+1 %endrep @@ -73,12 +76,9 @@ HookAfterStubHeaderBegin: push strict dword 0 ; 0 will be fixed VectorNum: push rax -%ifdef NO_ABSOLUTE_RELOCS_IN_TEXT - mov rax, strict qword 0 ; mov rax, HookAfterStubHeaderEnd -JmpAbsoluteAddress: -%else + ; This code is copied, thus relative addressing would not be safe and we + ; need to utilize the absolute address. mov rax, HookAfterStubHeaderEnd -%endif jmp rax HookAfterStubHeaderEnd: mov rax, rsp @@ -308,6 +308,7 @@ DrFinish: call ASM_PFX(CommonExceptionHandler) add rsp, 4 * 8 + 8 +%ifdef CEHL_SUPPORTS_CET ; The follow algorithm is used for clear shadow stack token busy bit. ; The comment is based on the sample shadow stack. ; Shadow stack is 32 bytes aligned. @@ -354,6 +355,7 @@ DrFinish: mov rax, 0x01 ; Pop off the new save token created incsspq rax ; SSP should be 0xFC0 now CetDone: +%endif cli ;; UINT64 ExceptionData; @@ -461,23 +463,10 @@ global ASM_PFX(AsmGetTemplateAddressMap) ASM_PFX(AsmGetTemplateAddressMap): lea rax, [AsmIdtVectorBegin] mov qword [rcx], rax - mov qword [rcx + 0x8], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 256 + mov qword [rcx + 0x8], (AsmIdtVectorEnd - AsmIdtVectorBegin) / NUM_VECTORS lea rax, [HookAfterStubHeaderBegin] mov qword [rcx + 0x10], rax - -%ifdef NO_ABSOLUTE_RELOCS_IN_TEXT -; Fix up CommonInterruptEntry address - lea rax, [ASM_PFX(CommonInterruptEntry)] - lea rcx, [AsmIdtVectorBegin] -%rep 256 - mov qword [rcx + (JmpAbsoluteAddress - 8 - HookAfterStubHeaderBegin)], rax - add rcx, (AsmIdtVectorEnd - AsmIdtVectorBegin) / 256 -%endrep -; Fix up HookAfterStubHeaderEnd - lea rax, [HookAfterStubHeaderEnd] - lea rcx, [JmpAbsoluteAddress] - mov qword [rcx - 8], rax -%endif + mov qword [rcx + 0x18], HookAfterStubHeaderEnd - HookAfterStubHeaderBegin ret @@ -489,4 +478,3 @@ ASM_PFX(AsmVectorNumFixup): mov rax, rdx mov [rcx + (VectorNum - 4 - HookAfterStubHeaderBegin)], al ret - diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/SecPeiExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/SecPeiExceptionHandlerAsm.nasm deleted file mode 100644 index 5c7a59c99d..0000000000 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/SecPeiExceptionHandlerAsm.nasm +++ /dev/null @@ -1,406 +0,0 @@ -;------------------------------------------------------------------------------ ; -; Copyright (c) 2012 - 2022, Intel Corporation. All rights reserved.
-; SPDX-License-Identifier: BSD-2-Clause-Patent -; -; Module Name: -; -; ExceptionHandlerAsm.Asm -; -; Abstract: -; -; x64 CPU Exception Handler -; -; Notes: -; -;------------------------------------------------------------------------------ - -; -; CommonExceptionHandler() -; - -%define VC_EXCEPTION 29 - -extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions -extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag -extern ASM_PFX(CommonExceptionHandler) - -SECTION .data - -DEFAULT REL -%ifndef NO_ABSOLUTE_RELOCS_IN_TEXT -SECTION .text -%endif - -ALIGN 8 - -; Generate 32 IDT vectors. -; 32 IDT vectors are enough because interrupts (32+) are not enabled in SEC and PEI phase. -AsmIdtVectorBegin: -%assign Vector 0 -%rep 32 - push byte %[Vector] - push rax - mov rax, ASM_PFX(CommonInterruptEntry) - jmp rax -%assign Vector Vector+1 -%endrep -AsmIdtVectorEnd: - -HookAfterStubHeaderBegin: - db 0x6a ; push -@VectorNum: - db 0 ; 0 will be fixed - push rax - mov rax, HookAfterStubHeaderEnd - jmp rax - -SECTION .text - -HookAfterStubHeaderEnd: - mov rax, rsp - and sp, 0xfff0 ; make sure 16-byte aligned for exception context - sub rsp, 0x18 ; reserve room for filling exception data later - push rcx - mov rcx, [rax + 8] - bt [ASM_PFX(mErrorCodeFlag)], ecx - jnc .0 - push qword [rsp] ; push additional rcx to make stack alignment -.0: - xchg rcx, [rsp] ; restore rcx, save Exception Number in stack - push qword [rax] ; push rax into stack to keep code consistence - -;---------------------------------------; -; CommonInterruptEntry ; -;---------------------------------------; -; The follow algorithm is used for the common interrupt routine. -; Entry from each interrupt with a push eax and eax=interrupt number -; Stack frame would be as follows as specified in IA32 manuals: -; -; +---------------------+ <-- 16-byte aligned ensured by processor -; + Old SS + -; +---------------------+ -; + Old RSP + -; +---------------------+ -; + RFlags + -; +---------------------+ -; + CS + -; +---------------------+ -; + RIP + -; +---------------------+ -; + Error Code + -; +---------------------+ -; + Vector Number + -; +---------------------+ -; + RBP + -; +---------------------+ <-- RBP, 16-byte aligned -; The follow algorithm is used for the common interrupt routine. -global ASM_PFX(CommonInterruptEntry) -ASM_PFX(CommonInterruptEntry): - cli - pop rax - ; - ; All interrupt handlers are invoked through interrupt gates, so - ; IF flag automatically cleared at the entry point - ; - xchg rcx, [rsp] ; Save rcx into stack and save vector number into rcx - and rcx, 0xFF - cmp ecx, 32 ; Intel reserved vector for exceptions? - jae NoErrorCode - bt [ASM_PFX(mErrorCodeFlag)], ecx - jc HasErrorCode - -NoErrorCode: - - ; - ; Push a dummy error code on the stack - ; to maintain coherent stack map - ; - push qword [rsp] - mov qword [rsp + 8], 0 -HasErrorCode: - push rbp - mov rbp, rsp - push 0 ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler - push 0 ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag - - ; - ; Stack: - ; +---------------------+ <-- 16-byte aligned ensured by processor - ; + Old SS + - ; +---------------------+ - ; + Old RSP + - ; +---------------------+ - ; + RFlags + - ; +---------------------+ - ; + CS + - ; +---------------------+ - ; + RIP + - ; +---------------------+ - ; + Error Code + - ; +---------------------+ - ; + RCX / Vector Number + - ; +---------------------+ - ; + RBP + - ; +---------------------+ <-- RBP, 16-byte aligned - ; - - ; - ; Since here the stack pointer is 16-byte aligned, so - ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64 - ; is 16-byte aligned - ; - -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - push r15 - push r14 - push r13 - push r12 - push r11 - push r10 - push r9 - push r8 - push rax - push qword [rbp + 8] ; RCX - push rdx - push rbx - push qword [rbp + 48] ; RSP - push qword [rbp] ; RBP - push rsi - push rdi - -;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero - movzx rax, word [rbp + 56] - push rax ; for ss - movzx rax, word [rbp + 32] - push rax ; for cs - mov rax, ds - push rax - mov rax, es - push rax - mov rax, fs - push rax - mov rax, gs - push rax - - mov [rbp + 8], rcx ; save vector number - -;; UINT64 Rip; - push qword [rbp + 24] - -;; UINT64 Gdtr[2], Idtr[2]; - xor rax, rax - push rax - push rax - sidt [rsp] - mov bx, word [rsp] - mov rax, qword [rsp + 2] - mov qword [rsp], rax - mov word [rsp + 8], bx - - xor rax, rax - push rax - push rax - sgdt [rsp] - mov bx, word [rsp] - mov rax, qword [rsp + 2] - mov qword [rsp], rax - mov word [rsp + 8], bx - -;; UINT64 Ldtr, Tr; - xor rax, rax - str ax - push rax - sldt ax - push rax - -;; UINT64 RFlags; - push qword [rbp + 40] - -;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; - mov rax, cr8 - push rax - mov rax, cr4 - or rax, 0x208 - mov cr4, rax - push rax - mov rax, cr3 - push rax - mov rax, cr2 - push rax - xor rax, rax - push rax - mov rax, cr0 - push rax - -;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - cmp qword [rbp + 8], VC_EXCEPTION - je VcDebugRegs ; For SEV-ES (#VC) Debug registers ignored - - mov rax, dr7 - push rax - mov rax, dr6 - push rax - mov rax, dr3 - push rax - mov rax, dr2 - push rax - mov rax, dr1 - push rax - mov rax, dr0 - push rax - jmp DrFinish - -VcDebugRegs: -;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7 are skipped for #VC to avoid exception recursion - xor rax, rax - push rax - push rax - push rax - push rax - push rax - push rax - -DrFinish: -;; FX_SAVE_STATE_X64 FxSaveState; - sub rsp, 512 - mov rdi, rsp - fxsave [rdi] - -;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear - cld - -;; UINT32 ExceptionData; - push qword [rbp + 16] - -;; Prepare parameter and call - mov rcx, [rbp + 8] - mov rdx, rsp - ; - ; Per X64 calling convention, allocate maximum parameter stack space - ; and make sure RSP is 16-byte aligned - ; - sub rsp, 4 * 8 + 8 - call ASM_PFX(CommonExceptionHandler) - add rsp, 4 * 8 + 8 - - cli -;; UINT64 ExceptionData; - add rsp, 8 - -;; FX_SAVE_STATE_X64 FxSaveState; - - mov rsi, rsp - fxrstor [rsi] - add rsp, 512 - -;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -;; Skip restoration of DRx registers to support in-circuit emualators -;; or debuggers set breakpoint in interrupt/exception context - add rsp, 8 * 6 - -;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; - pop rax - mov cr0, rax - add rsp, 8 ; not for Cr1 - pop rax - mov cr2, rax - pop rax - mov cr3, rax - pop rax - mov cr4, rax - pop rax - mov cr8, rax - -;; UINT64 RFlags; - pop qword [rbp + 40] - -;; UINT64 Ldtr, Tr; -;; UINT64 Gdtr[2], Idtr[2]; -;; Best not let anyone mess with these particular registers... - add rsp, 48 - -;; UINT64 Rip; - pop qword [rbp + 24] - -;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; - pop rax - ; mov gs, rax ; not for gs - pop rax - ; mov fs, rax ; not for fs - ; (X64 will not use fs and gs, so we do not restore it) - pop rax - mov es, rax - pop rax - mov ds, rax - pop qword [rbp + 32] ; for cs - pop qword [rbp + 56] ; for ss - -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - pop rdi - pop rsi - add rsp, 8 ; not for rbp - pop qword [rbp + 48] ; for rsp - pop rbx - pop rdx - pop rcx - pop rax - pop r8 - pop r9 - pop r10 - pop r11 - pop r12 - pop r13 - pop r14 - pop r15 - - mov rsp, rbp - pop rbp - add rsp, 16 - cmp qword [rsp - 32], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler - jz DoReturn - cmp qword [rsp - 40], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag - jz ErrorCode - jmp qword [rsp - 32] -ErrorCode: - sub rsp, 8 - jmp qword [rsp - 24] - -DoReturn: - cmp qword [ASM_PFX(mDoFarReturnFlag)], 0 ; Check if need to do far return instead of IRET - jz DoIret - push rax - mov rax, rsp ; save old RSP to rax - mov rsp, [rsp + 0x20] - push qword [rax + 0x10] ; save CS in new location - push qword [rax + 0x8] ; save EIP in new location - push qword [rax + 0x18] ; save EFLAGS in new location - mov rax, [rax] ; restore rax - popfq ; restore EFLAGS - retfq -DoIret: - iretq - -;------------------------------------------------------------------------------------- -; GetTemplateAddressMap (&AddressMap); -;------------------------------------------------------------------------------------- -; comments here for definition of address map -global ASM_PFX(AsmGetTemplateAddressMap) -ASM_PFX(AsmGetTemplateAddressMap): - lea rax, [AsmIdtVectorBegin] - mov qword [rcx], rax - mov qword [rcx + 0x8], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32 - lea rax, [HookAfterStubHeaderBegin] - mov qword [rcx + 0x10], rax - ret - -;------------------------------------------------------------------------------------- -; AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr); -;------------------------------------------------------------------------------------- -global ASM_PFX(AsmVectorNumFixup) -ASM_PFX(AsmVectorNumFixup): - mov rax, rdx - mov [rcx + (@VectorNum - HookAfterStubHeaderBegin)], al - ret - From c4c7783b5ca66c8c754986128a66cc03a5f72bdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Sun, 2 Apr 2023 17:19:14 +0200 Subject: [PATCH 061/341] UefiPayloadPkg/UefiPayloadEntry: Return image destination size as UINT32 --- UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c index bdec06e974..6763416060 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c @@ -24,7 +24,7 @@ LoadUefiImage ( IN VOID *UefiImage, IN UINT32 UefiImageSize, OUT EFI_PHYSICAL_ADDRESS *ImageAddress, - OUT UINT64 *DestinationSize, + OUT UINT32 *DestinationSize, OUT EFI_PHYSICAL_ADDRESS *EntryPoint ) { @@ -235,7 +235,7 @@ LoadDxeCore ( VOID *UefiImage; UINT32 UefiImageSize; EFI_PHYSICAL_ADDRESS ImageAddress; - UINT64 DestinationSize; + UINT32 DestinationSize; PayloadFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdPayloadFdMemBase); @@ -300,10 +300,10 @@ UniversalLoadDxeCore ( { EFI_STATUS Status; EFI_FFS_FILE_HEADER *FileHeader; - VOID *UefiImage; - UINT32 UefiImageSize; + VOID *UefiImage; + UINT32 UefiImageSize; EFI_PHYSICAL_ADDRESS ImageAddress; - UINT64 ImageSize; + UINT32 DestinationSize; // // Find DXE core file from DXE FV @@ -321,12 +321,12 @@ UniversalLoadDxeCore ( // // Get DXE core info // - Status = LoadUefiImage (UefiImage, UefiImageSize, &ImageAddress, &ImageSize, DxeCoreEntryPoint); + Status = LoadUefiImage (UefiImage, UefiImageSize, &ImageAddress, &DestinationSize, DxeCoreEntryPoint); if (EFI_ERROR (Status)) { return Status; } - BuildModuleHob (&FileHeader->Name, ImageAddress, EFI_SIZE_TO_PAGES ((UINT32)ImageSize) * EFI_PAGE_SIZE, *DxeCoreEntryPoint); + BuildModuleHob (&FileHeader->Name, ImageAddress, DestinationSize, *DxeCoreEntryPoint); return EFI_SUCCESS; } From c24587e6bf4c46573b6f53de5c212e06fe8bf5bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Mon, 10 Apr 2023 10:49:29 +0200 Subject: [PATCH 062/341] MdeModulePkg/ExtendedFirmwarePerformance: Fix FPDT struct alignment --- .../Guid/ExtendedFirmwarePerformance.h | 20 +++++++++++++++++++ .../DxeCorePerformanceLib.c | 8 ++++++++ .../PeiPerformanceLib/PeiPerformanceLib.c | 6 ++++++ .../SmmCorePerformanceLib.c | 6 ++++++ 4 files changed, 40 insertions(+) diff --git a/MdeModulePkg/Include/Guid/ExtendedFirmwarePerformance.h b/MdeModulePkg/Include/Guid/ExtendedFirmwarePerformance.h index 20be7654c8..869412da4d 100644 --- a/MdeModulePkg/Include/Guid/ExtendedFirmwarePerformance.h +++ b/MdeModulePkg/Include/Guid/ExtendedFirmwarePerformance.h @@ -64,6 +64,10 @@ typedef struct { /// UINT16 ProgressID; /// + /// Reserved for future usage. Must be 0. + /// + UINT16 Reserved; + /// /// APIC ID for the processor in the system used as a timestamp clock source. /// If only one timestamp clock source is used, this field is Reserved and populated as 0. /// @@ -91,6 +95,10 @@ typedef struct { /// UINT16 ProgressID; /// + /// Reserved for future usage. Must be 0. + /// + UINT16 Reserved; + /// /// APIC ID for the processor in the system used as a timestamp clock source. /// If only one timestamp clock source is used, this field is Reserved and populated as 0. /// @@ -123,6 +131,10 @@ typedef struct { /// UINT16 ProgressID; /// + /// Reserved for future usage. Must be 0. + /// + UINT16 Reserved; + /// /// APIC ID for the processor in the system used as a timestamp clock source. /// If only one timestamp clock source is used, this field is Reserved and populated as 0. /// @@ -159,6 +171,10 @@ typedef struct { /// UINT16 ProgressID; /// + /// Reserved for future usage. Must be 0. + /// + UINT16 Reserved; + /// /// APIC ID for the processor in the system used as a timestamp clock source. /// If only one timestamp clock source is used, this field is Reserved and populated as 0. /// @@ -190,6 +206,10 @@ typedef struct { /// UINT16 ProgressID; /// + /// Reserved for future usage. Must be 0. + /// + UINT16 Reserved; + /// /// APIC ID for the processor in the system used as a timestamp clock source. /// If only one timestamp clock source is used, this field is Reserved and populated as 0. /// diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c index 9825fdaeab..f831801441 100644 --- a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c +++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c @@ -1072,6 +1072,7 @@ InsertFpdtRecord ( FpdtRecordPtr.GuidEvent->Header.Length = sizeof (FPDT_GUID_EVENT_RECORD); FpdtRecordPtr.GuidEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.GuidEvent->ProgressID = PerfId; + FpdtRecordPtr.GuidEvent->Reserved = 0; FpdtRecordPtr.GuidEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.GuidEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidEvent->Guid)); if ((CallerIdentifier == NULL) && (PerfId == MODULE_END_ID) && (mCachedLength != 0)) { @@ -1111,6 +1112,7 @@ InsertFpdtRecord ( FpdtRecordPtr.GuidQwordEvent->Header.Length = sizeof (FPDT_GUID_QWORD_EVENT_RECORD); FpdtRecordPtr.GuidQwordEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.GuidQwordEvent->ProgressID = PerfId; + FpdtRecordPtr.GuidQwordEvent->Reserved = 0; FpdtRecordPtr.GuidQwordEvent->Timestamp = TimeStamp; FpdtRecordPtr.GuidQwordEvent->Qword = mLoadImageCount; CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidQwordEvent->Guid)); @@ -1140,6 +1142,7 @@ InsertFpdtRecord ( FpdtRecordPtr.GuidQwordEvent->Header.Length = sizeof (FPDT_GUID_QWORD_EVENT_RECORD); FpdtRecordPtr.GuidQwordEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.GuidQwordEvent->ProgressID = PerfId; + FpdtRecordPtr.GuidQwordEvent->Reserved = 0; FpdtRecordPtr.GuidQwordEvent->Timestamp = TimeStamp; FpdtRecordPtr.GuidQwordEvent->Qword = Address; CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidQwordEvent->Guid)); @@ -1155,6 +1158,7 @@ InsertFpdtRecord ( FpdtRecordPtr.GuidQwordStringEvent->Header.Length = sizeof (FPDT_GUID_QWORD_STRING_EVENT_RECORD); FpdtRecordPtr.GuidQwordStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.GuidQwordStringEvent->ProgressID = PerfId; + FpdtRecordPtr.GuidQwordStringEvent->Reserved = 0; FpdtRecordPtr.GuidQwordStringEvent->Timestamp = TimeStamp; FpdtRecordPtr.GuidQwordStringEvent->Qword = Address; CopyMem (&FpdtRecordPtr.GuidQwordStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidQwordStringEvent->Guid)); @@ -1183,6 +1187,7 @@ InsertFpdtRecord ( FpdtRecordPtr.DualGuidStringEvent->Header.Length = sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD); FpdtRecordPtr.DualGuidStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.DualGuidStringEvent->ProgressID = PerfId; + FpdtRecordPtr.DualGuidStringEvent->Reserved = 0; FpdtRecordPtr.DualGuidStringEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid1, CallerIdentifier, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid1)); CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid2, Guid, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid2)); @@ -1214,6 +1219,7 @@ InsertFpdtRecord ( FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD); FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId; + FpdtRecordPtr.DynamicStringEvent->Reserved = 0; FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid)); CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length); @@ -1239,6 +1245,7 @@ InsertFpdtRecord ( FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD); FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId; + FpdtRecordPtr.DynamicStringEvent->Reserved = 0; FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid)); CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length); @@ -1262,6 +1269,7 @@ InsertFpdtRecord ( FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD); FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId; + FpdtRecordPtr.DynamicStringEvent->Reserved = 0; FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp; if (Guid != NULL) { // diff --git a/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.c b/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.c index 93edc01014..a1becabd77 100644 --- a/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.c +++ b/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.c @@ -398,6 +398,7 @@ InsertFpdtRecord ( FpdtRecordPtr.GuidEvent->Header.Length = sizeof (FPDT_GUID_EVENT_RECORD); FpdtRecordPtr.GuidEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.GuidEvent->ProgressID = PerfId; + FpdtRecordPtr.GuidEvent->Reserved = 0; FpdtRecordPtr.GuidEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.GuidEvent->Guid, ModuleGuid, sizeof (EFI_GUID)); } @@ -412,6 +413,7 @@ InsertFpdtRecord ( FpdtRecordPtr.GuidQwordEvent->Header.Length = sizeof (FPDT_GUID_QWORD_EVENT_RECORD); FpdtRecordPtr.GuidQwordEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.GuidQwordEvent->ProgressID = PerfId; + FpdtRecordPtr.GuidQwordEvent->Reserved = 0; FpdtRecordPtr.GuidQwordEvent->Timestamp = TimeStamp; if (PerfId == MODULE_LOADIMAGE_START_ID) { PeiPerformanceLogHeader->LoadImageCount++; @@ -441,6 +443,7 @@ InsertFpdtRecord ( FpdtRecordPtr.DualGuidStringEvent->Header.Length = sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD); FpdtRecordPtr.DualGuidStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.DualGuidStringEvent->ProgressID = PerfId; + FpdtRecordPtr.DualGuidStringEvent->Reserved = 0; FpdtRecordPtr.DualGuidStringEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid1, ModuleGuid, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid1)); CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid2, Guid, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid2)); @@ -467,6 +470,7 @@ InsertFpdtRecord ( FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD); FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId; + FpdtRecordPtr.DynamicStringEvent->Reserved = 0; FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, ModuleGuid, sizeof (EFI_GUID)); CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length); @@ -487,6 +491,7 @@ InsertFpdtRecord ( FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD); FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId; + FpdtRecordPtr.DynamicStringEvent->Reserved = 0; FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid)); CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length); @@ -506,6 +511,7 @@ InsertFpdtRecord ( FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD); FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId; + FpdtRecordPtr.DynamicStringEvent->Reserved = 0; FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp; if (Guid != NULL) { // diff --git a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c index 2b6cd76d7f..7d484df8d8 100644 --- a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c +++ b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c @@ -620,6 +620,7 @@ InsertFpdtRecord ( FpdtRecordPtr.GuidEvent->Header.Length = sizeof (FPDT_GUID_EVENT_RECORD); FpdtRecordPtr.GuidEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.GuidEvent->ProgressID = PerfId; + FpdtRecordPtr.GuidEvent->Reserved = 0; FpdtRecordPtr.GuidEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.GuidEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidEvent->Guid)); if ((CallerIdentifier == NULL) && (PerfId == MODULE_END_ID) && (mCachedLength != 0)) { @@ -650,6 +651,7 @@ InsertFpdtRecord ( FpdtRecordPtr.GuidQwordEvent->Header.Length = sizeof (FPDT_GUID_QWORD_EVENT_RECORD); FpdtRecordPtr.GuidQwordEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.GuidQwordEvent->ProgressID = PerfId; + FpdtRecordPtr.GuidQwordEvent->Reserved = 0; FpdtRecordPtr.GuidQwordEvent->Timestamp = TimeStamp; FpdtRecordPtr.GuidQwordEvent->Qword = mLoadImageCount; CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidQwordEvent->Guid)); @@ -680,6 +682,7 @@ InsertFpdtRecord ( FpdtRecordPtr.DualGuidStringEvent->Header.Length = sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD); FpdtRecordPtr.DualGuidStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.DualGuidStringEvent->ProgressID = PerfId; + FpdtRecordPtr.DualGuidStringEvent->Reserved = 0; FpdtRecordPtr.DualGuidStringEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid1, CallerIdentifier, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid1)); CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid2, Guid, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid2)); @@ -711,6 +714,7 @@ InsertFpdtRecord ( FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD); FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId; + FpdtRecordPtr.DynamicStringEvent->Reserved = 0; FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid)); CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length); @@ -736,6 +740,7 @@ InsertFpdtRecord ( FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD); FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId; + FpdtRecordPtr.DynamicStringEvent->Reserved = 0; FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid)); CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length); @@ -759,6 +764,7 @@ InsertFpdtRecord ( FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD); FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId; + FpdtRecordPtr.DynamicStringEvent->Reserved = 0; FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp; if (Guid != NULL) { // From 9e2b1a158fc845eb2c5fd84e7237d0bba958db31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Tue, 11 Apr 2023 09:47:52 +0200 Subject: [PATCH 063/341] ArmPkg/ArmMmuLib: ASSERT ArmReplaceLiveTranslationEntry alignment --- ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 10 ++++++++++ .../ArmMmuLib/AArch64/ArmMmuPeiLibConstructor.c | 14 ++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index 45b7c81341..cb45102bcc 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -755,12 +755,22 @@ ArmMmuBaseLibConstructor ( ) { extern UINT32 ArmReplaceLiveTranslationEntrySize; + UINTN ArmReplaceLiveTranslationEntryEnd; VOID *Hob; Hob = GetFirstGuidHob (&gArmMmuReplaceLiveTranslationEntryFuncGuid); if (Hob != NULL) { mReplaceLiveEntryFunc = *(ARM_REPLACE_LIVE_TRANSLATION_ENTRY *)GET_GUID_HOB_DATA (Hob); } else { + ArmReplaceLiveTranslationEntryEnd = (UINTN)ArmReplaceLiveTranslationEntry + ArmReplaceLiveTranslationEntrySize; + // + // Align this routine to a log2 upper bound of its size, so that it is + // guaranteed not to cross a page or block boundary + // (see ArmMmuLibReplaceEntry.S). + // + ASSERT (IS_ALIGNED ((UINTN)ArmReplaceLiveTranslationEntry, 0x200)); + ASSERT (((UINTN)ArmReplaceLiveTranslationEntry >> EFI_PAGE_SHIFT) == ((ArmReplaceLiveTranslationEntryEnd - 1) >> EFI_PAGE_SHIFT)); + // // The ArmReplaceLiveTranslationEntry () helper function may be invoked // with the MMU off so we have to ensure that it gets cleaned to the PoC diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuPeiLibConstructor.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuPeiLibConstructor.c index a0c9facdea..eb7011b3c5 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuPeiLibConstructor.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuPeiLibConstructor.c @@ -24,6 +24,7 @@ ArmMmuPeiLibConstructor ( { extern UINT32 ArmReplaceLiveTranslationEntrySize; ARM_REPLACE_LIVE_TRANSLATION_ENTRY ArmReplaceLiveTranslationEntryFunc; + UINTN ArmReplaceLiveTranslationEntryEnd; VOID *Hob; EFI_FV_FILE_INFO FileInfo; @@ -31,6 +32,16 @@ ArmMmuPeiLibConstructor ( ASSERT (FileHandle != NULL); + ArmReplaceLiveTranslationEntryEnd = (UINTN)ArmReplaceLiveTranslationEntry + ArmReplaceLiveTranslationEntrySize; + + // + // Align this routine to a log2 upper bound of its size, so that it is + // guaranteed not to cross a page or block boundary + // (see ArmMmuLibReplaceEntry.S). + // + ASSERT (IS_ALIGNED ((UINTN)ArmReplaceLiveTranslationEntry, 0x200)); + ASSERT (((UINTN)ArmReplaceLiveTranslationEntry >> EFI_PAGE_SHIFT) == ((ArmReplaceLiveTranslationEntryEnd - 1) >> EFI_PAGE_SHIFT)); + Status = (*PeiServices)->FfsGetFileInfo (FileHandle, &FileInfo); ASSERT_EFI_ERROR (Status); @@ -42,8 +53,7 @@ ArmMmuPeiLibConstructor ( // when not executing in place. // if (((UINTN)FileInfo.Buffer <= (UINTN)ArmReplaceLiveTranslationEntry) && - ((UINTN)FileInfo.Buffer + FileInfo.BufferSize >= - (UINTN)ArmReplaceLiveTranslationEntry + ArmReplaceLiveTranslationEntrySize)) + ((UINTN)FileInfo.Buffer + FileInfo.BufferSize >= ArmReplaceLiveTranslationEntryEnd)) { DEBUG ((DEBUG_INFO, "ArmMmuLib: skipping cache maintenance on XIP PEIM\n")); From bc87d7b4305d5f34c88bd5955c73770ce7c97946 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 20 Apr 2023 16:10:12 +0300 Subject: [PATCH 064/341] Drop support for the TE format --- .../SetPermissions.c | 15 +- .../DebugAgentSymbolsBaseLib.c | 2 +- ArmPlatformPkg/Scripts/Ds5/firmware_volume.py | 59 +-- ArmVirtPkg/ArmVirtRules.fdf.inc | 8 +- ArmVirtPkg/PrePi/PrePi.c | 4 - .../plugins/EdkPlugins/basemodel/efibinary.py | 1 - BaseTools/Scripts/efi_debugging.py | 128 ++---- BaseTools/Scripts/efi_gdb.py | 16 +- BaseTools/Scripts/efi_lldb.py | 12 +- BaseTools/Source/C/GenFfs/GenFfs.c | 37 +- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 367 ++---------------- BaseTools/Source/C/GenSec/GenSec.c | 34 +- BaseTools/Source/C/VolInfo/VolInfo.c | 3 +- BaseTools/Source/Python/Common/DataType.py | 1 - .../Source/Python/FMMT/core/BiosTreeNode.py | 1 - BaseTools/Source/Python/GenFds/DataSection.py | 14 +- BaseTools/Source/Python/GenFds/EfiSection.py | 16 +- BaseTools/Source/Python/GenFds/FdfParser.py | 37 +- BaseTools/Source/Python/GenFds/Ffs.py | 1 - .../Source/Python/GenFds/FfsInfStatement.py | 22 +- BaseTools/Source/Python/GenFds/GenFds.py | 7 +- BaseTools/Source/Python/GenFds/Section.py | 6 +- .../Source/Python/UPT/Library/DataType.py | 1 - .../UserManuals/GenSec_Utility_Man_Page.rtf | 4 +- .../Scripts/LauterbachT32/EfiLoadFv.cmm | 9 +- .../LauterbachT32/EfiProcessTeImage.cmm | 64 --- EmulatorPkg/EmulatorPkg.dsc | 1 - .../Tools/ConfigEditor/ConfigEditor.py | 1 - IntelFsp2Pkg/Tools/SplitFspBin.py | 63 +-- MdeModulePkg/Core/Pei/Image/Image.c | 81 +--- MdeModulePkg/Core/Pei/PeiMain.inf | 1 - MdeModulePkg/Core/PiSmmCore/Dispatcher.c | 18 - MdeModulePkg/MdeModulePkg.dec | 8 - MdeModulePkg/MdeModulePkg.uni | 6 - .../FvSimpleFileSystem.c | 2 +- MdePkg/Include/IndustryStandard/PeImage2.h | 28 +- MdePkg/Include/Library/DxeServicesLib.h | 13 - MdePkg/Include/Library/PeCoffLib2.h | 8 +- MdePkg/Include/Pi/PiFirmwareFile.h | 1 - .../Library/BasePeCoffLib2/BasePeCoffLib2.inf | 1 - .../Library/BasePeCoffLib2/Documentation.md | 1 - MdePkg/Library/BasePeCoffLib2/PeCoffDebug.c | 28 -- MdePkg/Library/BasePeCoffLib2/PeCoffHash.c | 12 - MdePkg/Library/BasePeCoffLib2/PeCoffHii.c | 10 - MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c | 16 +- MdePkg/Library/BasePeCoffLib2/PeCoffInit.c | 178 +-------- MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c | 33 +- .../BaseUefiImageLibPeCoff.inf | 3 +- .../Library/BaseUefiImageLib/PeCoffSupport.c | 17 +- .../Library/BaseUefiImageLib/PeCoffSupport.h | 2 +- .../BaseUefiImageLib/UefiImageLibPeCoff.c | 2 +- .../Library/DxeServicesLib/DxeServicesLib.c | 34 -- MdePkg/MdePkg.dec | 6 - OvmfPkg/Sec/SecMain.c | 14 +- .../Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c | 4 +- .../Vtf0/Ia32/SearchForSecEntry.asm | 20 - UefiCpuPkg/SecCore/FindPeiCore.c | 2 +- 57 files changed, 208 insertions(+), 1275 deletions(-) delete mode 100644 EmbeddedPkg/Scripts/LauterbachT32/EfiProcessTeImage.cmm diff --git a/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/SetPermissions.c b/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/SetPermissions.c index 728e26c814..0fbd39156b 100644 --- a/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/SetPermissions.c +++ b/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/SetPermissions.c @@ -64,15 +64,12 @@ LocateStandaloneMmCoreUefiImage ( Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, UefiImage, UefiImageSize); if (EFI_ERROR (Status)) { - Status = FfsFindSectionData (EFI_SECTION_TE, FileHeader, UefiImage, UefiImageSize); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "Unable to locate Standalone MM Section data - %r\n", - Status - )); - return Status; - } + DEBUG (( + DEBUG_ERROR, + "Unable to locate Standalone MM Section data - %r\n", + Status + )); + return Status; } DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", *UefiImage)); diff --git a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c index a985f525d3..dad2dd9d29 100644 --- a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c +++ b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c @@ -192,7 +192,7 @@ GetImageContext ( return EFI_VOLUME_CORRUPTED; } - if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) { + if (Section->Type == EFI_SECTION_PE32) { EfiImage = (Section + 1); break; } diff --git a/ArmPlatformPkg/Scripts/Ds5/firmware_volume.py b/ArmPlatformPkg/Scripts/Ds5/firmware_volume.py index c6d1ca830a..e44dcf6ea0 100644 --- a/ArmPlatformPkg/Scripts/Ds5/firmware_volume.py +++ b/ArmPlatformPkg/Scripts/Ds5/firmware_volume.py @@ -14,7 +14,6 @@ class EfiFileSection(object): EFI_SECTION_PE32 = 0x10 EFI_SECTION_PIC = 0x11 - EFI_SECTION_TE = 0x12 EFI_IMAGE_DEBUG_TYPE_CODEVIEW = 0x2 @@ -38,58 +37,12 @@ def get_size(self): def get_debug_filepath(self): type = self.get_type() - if type == EfiFileSection.EFI_SECTION_TE: - section = EfiSectionTE(self, ec, self.base + 0x4) - elif type == EfiFileSection.EFI_SECTION_PE32: + if type == EfiFileSection.EFI_SECTION_PE32: section = EfiSectionPE32(self, ec, self.base + 0x4) else: raise Exception("EfiFileSection", "No debug section") return section.get_debug_filepath() -class EfiSectionTE: - SIZEOF_EFI_TE_IMAGE_HEADER = 0x28 - EFI_TE_IMAGE_SIGNATURE = ('V','Z') - - def __init__(self, ec, base_te): - self.ec = ec - self.base_te = int(base_te) - te_sig = struct.unpack("cc", self.ec.getMemoryService().read(self.base_te, 2, 32)) - if te_sig != EfiSectionTE.EFI_TE_IMAGE_SIGNATURE: - raise Exception("EfiFileSectionTE","TE Signature incorrect") - - def get_debug_filepath(self): - stripped_size = struct.unpack("= debug_info[0]) and (addr < debug_info[0] + debug_info[1]): - if debug_info[2] == EfiFileSection.EFI_SECTION_TE: - section = EfiSectionTE(self.ec, debug_info[0] + 0x4) - elif debug_info[2] == EfiFileSection.EFI_SECTION_PE32: + if debug_info[2] == EfiFileSection.EFI_SECTION_PE32: section = EfiSectionPE32(self.ec, debug_info[0] + 0x4) else: raise Exception('FirmwareVolume','Section Type not supported') @@ -313,9 +264,7 @@ def load_all_symbols(self, verbose = False): self.get_debug_info() for debug_info in self.DebugInfos: - if debug_info[2] == EfiFileSection.EFI_SECTION_TE: - section = EfiSectionTE(self.ec, debug_info[0] + 0x4) - elif debug_info[2] == EfiFileSection.EFI_SECTION_PE32: + if debug_info[2] == EfiFileSection.EFI_SECTION_PE32: section = EfiSectionPE32(self.ec, debug_info[0] + 0x4) else: continue diff --git a/ArmVirtPkg/ArmVirtRules.fdf.inc b/ArmVirtPkg/ArmVirtRules.fdf.inc index b8ec040d23..5865c2ef31 100644 --- a/ArmVirtPkg/ArmVirtRules.fdf.inc +++ b/ArmVirtPkg/ArmVirtRules.fdf.inc @@ -36,24 +36,24 @@ [Rule.Common.SEC] FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED FIXED { - TE TE Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi } [Rule.Common.SEC.SELF_RELOC] FILE SEC = $(NAMED_GUID) { - TE TE Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi } [Rule.Common.PEI_CORE] FILE PEI_CORE = $(NAMED_GUID) FIXED { - TE TE Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING ="$(MODULE_NAME)" Optional } [Rule.Common.PEIM] FILE PEIM = $(NAMED_GUID) FIXED { PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - TE TE Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING="$(MODULE_NAME)" Optional } diff --git a/ArmVirtPkg/PrePi/PrePi.c b/ArmVirtPkg/PrePi/PrePi.c index 0ed4db2903..4dabd6e467 100644 --- a/ArmVirtPkg/PrePi/PrePi.c +++ b/ArmVirtPkg/PrePi/PrePi.c @@ -148,10 +148,6 @@ RelocateUefiImage ( ASSERT_EFI_ERROR (Status); Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SectionData, &SectionSize); - if (EFI_ERROR (Status)) { - Status = FfsFindSectionData (EFI_SECTION_TE, FileHandle, &SectionData, &SectionSize); - } - ASSERT_EFI_ERROR (Status); Status = UefiImageInitializeContext (&ImageContext, SectionData, SectionSize); diff --git a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/efibinary.py b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/efibinary.py index 1bc4938bfc..d9e1a68d6d 100644 --- a/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/efibinary.py +++ b/BaseTools/Scripts/PackageDocumentTools/plugins/EdkPlugins/basemodel/efibinary.py @@ -496,7 +496,6 @@ class EfiSectionHeader(BinaryItem): 0x02: 'EFI_SECTION_GUID_DEFINED', 0x10: 'EFI_SECTION_PE32', 0x11: 'EFI_SECTION_PIC', - 0x12: 'EFI_SECTION_TE', 0x13: 'EFI_SECTION_DXE_DEPEX', 0x14: 'EFI_SECTION_VERSION', 0x15: 'EFI_SECTION_USER_INTERFACE', diff --git a/BaseTools/Scripts/efi_debugging.py b/BaseTools/Scripts/efi_debugging.py index 9848cd5968..66e598faf7 100755 --- a/BaseTools/Scripts/efi_debugging.py +++ b/BaseTools/Scripts/efi_debugging.py @@ -167,21 +167,6 @@ class EFI_IMAGE_DATA_DIRECTORY(LittleEndianStructure): ] -class EFI_TE_IMAGE_HEADER(LittleEndianStructure): - _fields_ = [ - ('Signature', ARRAY(c_char, 2)), - ('Machine', c_uint16), - ('NumberOfSections', c_uint8), - ('Subsystem', c_uint8), - ('StrippedSize', c_uint16), - ('AddressOfEntryPoint', c_uint32), - ('BaseOfCode', c_uint32), - ('ImageBase', c_uint64), - ('DataDirectoryBaseReloc', EFI_IMAGE_DATA_DIRECTORY), - ('DataDirectoryDebug', EFI_IMAGE_DATA_DIRECTORY) - ] - - class EFI_IMAGE_DOS_HEADER(LittleEndianStructure): _fields_ = [ ('e_magic', c_uint16), @@ -1837,9 +1822,9 @@ def DebugImageInfo(self, table=None): return ImageLoad -class PeTeImage: +class PeImage: ''' - A class to abstract PE/COFF or TE image processing via passing in a + A class to abstract PE/COFF image processing via passing in a Python file like object. If you pass in an address the PE/COFF is parsed, if you pass in NULL for an address then you get a class instance you can use to search memory for a PE/COFF hader given a pc value. @@ -1872,7 +1857,6 @@ def __init__(self, file, address=0): # book keeping, but public self.PeHdr = None - self.TeHdr = None self.Machine = None self.Subsystem = None self.CodeViewSig = None @@ -1888,7 +1872,6 @@ def __init__(self, file, address=0): self.DataAddress = 0 self.CodeViewPdb = None self.CodeViewUuid = None - self.TeAdjust = 0 self.dir_name = { 0: 'Export Table', @@ -1914,9 +1897,9 @@ def __init__(self, file, address=0): self.parse() def __str__(self): - if self.PeHdr is None and self.TeHdr is None: + if self.PeHdr is None: # no PE/COFF header found - return "" + return "" if self.CodeViewPdb: pdb = f'{self.Machine}`{self.CodeViewPdb}' @@ -1928,8 +1911,7 @@ def __str__(self): else: guid = '' - slide = f'slide = {self.TeAdjust:d} ' if self.TeAdjust != 0 else ' ' - res = guid + f'{pdb} load = 0x{self.LoadAddress:08x} ' + slide + res = guid + f'{pdb} load = 0x{self.LoadAddress:08x} ' return res def _seek(self, offset): @@ -1989,60 +1971,46 @@ def pcToPeCoff(self, return False def maybe(self, offset=None): - """Probe to see if this offset is likely a PE/COFF or TE file """ + """Probe to see if this offset is likely a PE/COFF file """ self.LoadAddress = 0 e_magic = self._read_offset(2, offset) - header_ok = e_magic == b'MZ' or e_magic == b'VZ' + header_ok = e_magic == b'MZ' if offset is not None and header_ok: self.LoadAddress = offset return header_ok def parse(self): - """Parse PE/COFF (TE) debug directory entry """ + """Parse PE/COFF debug directory entry """ DosHdr = self._read_ctype(EFI_IMAGE_DOS_HEADER, 0) - if DosHdr.e_magic == self._unsigned(b'VZ'): - # TE image - self.TeHdr = self._read_ctype(EFI_TE_IMAGE_HEADER, 0) - - self.TeAdjust = sizeof(self.TeHdr) - self.TeHdr.StrippedSize - self.Machine = image_machine_dict.get(self.TeHdr.Machine, None) - self.Subsystem = self.TeHdr.Subsystem - self.AddressOfEntryPoint = self.TeHdr.AddressOfEntryPoint - - debug_dir_size = self.TeHdr.DataDirectoryDebug.Size - debug_dir_offset = (self.TeAdjust + - self.TeHdr.DataDirectoryDebug.VirtualAddress) + if DosHdr.e_magic == self._unsigned(b'MZ'): + self.e_lfanew = DosHdr.e_lfanew else: - if DosHdr.e_magic == self._unsigned(b'MZ'): - self.e_lfanew = DosHdr.e_lfanew - else: - self.e_lfanew = 0 + self.e_lfanew = 0 + self.PeHdr = self._read_ctype( + EFI_IMAGE_NT_HEADERS64, self.e_lfanew) + if self.PeHdr.Signature != self._unsigned(b'PE\0\0'): + return False + + if self.PeHdr.OptionalHeader.Magic == \ + EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC: self.PeHdr = self._read_ctype( - EFI_IMAGE_NT_HEADERS64, self.e_lfanew) - if self.PeHdr.Signature != self._unsigned(b'PE\0\0'): - return False - - if self.PeHdr.OptionalHeader.Magic == \ - EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC: - self.PeHdr = self._read_ctype( - EFI_IMAGE_NT_HEADERS32, self.e_lfanew) - - if self.PeHdr.OptionalHeader.NumberOfRvaAndSizes <= \ - DIRECTORY_DEBUG: - return False - - self.Machine = image_machine_dict.get( - self.PeHdr.FileHeader.Machine, None) - self.Subsystem = self.PeHdr.OptionalHeader.Subsystem - self.AddressOfEntryPoint = \ - self.PeHdr.OptionalHeader.AddressOfEntryPoint - self.TeAdjust = 0 - - debug_dir_size = self.PeHdr.OptionalHeader.DataDirectory[ - DIRECTORY_DEBUG].Size - debug_dir_offset = self.PeHdr.OptionalHeader.DataDirectory[ - DIRECTORY_DEBUG].VirtualAddress + EFI_IMAGE_NT_HEADERS32, self.e_lfanew) + + if self.PeHdr.OptionalHeader.NumberOfRvaAndSizes <= \ + DIRECTORY_DEBUG: + return False + + self.Machine = image_machine_dict.get( + self.PeHdr.FileHeader.Machine, None) + self.Subsystem = self.PeHdr.OptionalHeader.Subsystem + self.AddressOfEntryPoint = \ + self.PeHdr.OptionalHeader.AddressOfEntryPoint + + debug_dir_size = self.PeHdr.OptionalHeader.DataDirectory[ + DIRECTORY_DEBUG].Size + debug_dir_offset = self.PeHdr.OptionalHeader.DataDirectory[ + DIRECTORY_DEBUG].VirtualAddress if self.Machine is None or self.Subsystem not in [0, 10, 11, 12]: return False @@ -2056,10 +2024,7 @@ def sections(self): '''Parse the PE/COFF (TE) section table''' if self.Sections is not None: return - elif self.TeHdr is not None: - self.NumberOfSections = self.TeHdr.NumberOfSections - offset = sizeof(EFI_TE_IMAGE_HEADER) - elif self.PeHdr is not None: + if self.PeHdr is not None: self.NumberOfSections = self.PeHdr.FileHeader.NumberOfSections offset = sizeof(c_uint32) + \ sizeof(EFI_IMAGE_FILE_HEADER) @@ -2074,7 +2039,7 @@ def sections(self): for i in range(self.NumberOfSections): name = str(self.Sections[i].Name, 'ascii', 'ignore') addr = self.Sections[i].VirtualAddress - addr += self.LoadAddress + self.TeAdjust + addr += self.LoadAddress if name == '.text': self.TextAddress = addr elif name == '.data': @@ -2099,22 +2064,7 @@ def sections_to_str(self): def directory_to_str(self): result = '' - if self.TeHdr: - debug_size = self.TeHdr.DataDirectoryDebug.Size - if debug_size > 0: - debug_offset = (self.TeAdjust - + self.TeHdr.DataDirectoryDebug.VirtualAddress) - result += f"Debug 0x{debug_offset:08X} 0x{debug_size}\n" - - relocation_size = self.TeHdr.DataDirectoryBaseReloc.Size - if relocation_size > 0: - relocation_offset = ( - self.TeAdjust - + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress) - result += f'Relocation 0x{relocation_offset:08X} ' - result += f' 0x{relocation_size}\n' - - elif self.PeHdr: + if self.PeHdr: for i in range(self.PeHdr.OptionalHeader.NumberOfRvaAndSizes): size = self.PeHdr.OptionalHeader.DataDirectory[i].Size if size == 0: @@ -2143,7 +2093,7 @@ def processDebugDirEntry(self, virt_address, virt_size): continue entry = self._read_offset( - DirectoryEntry.SizeOfData, DirectoryEntry.RVA + self.TeAdjust) + DirectoryEntry.SizeOfData, DirectoryEntry.RVA) self.CodeViewSig = entry[:4] if self.CodeViewSig == b'MTOC': self.CodeViewUuid = uuid.UUID(bytes_le=entry[4:4+16]) @@ -2170,7 +2120,7 @@ def main(): '''Process arguments as PE/COFF files''' for fname in sys.argv[1:]: with open(fname, 'rb') as f: - image = PeTeImage(f) + image = PeImage(f) print(image) res = f'EntryPoint = 0x{image.AddressOfEntryPoint:08x} ' res += f'TextAddress = 0x{image.TextAddress:08x} ' diff --git a/BaseTools/Scripts/efi_gdb.py b/BaseTools/Scripts/efi_gdb.py index f3e7fd9d0c..11240ad10e 100755 --- a/BaseTools/Scripts/efi_gdb.py +++ b/BaseTools/Scripts/efi_gdb.py @@ -41,7 +41,7 @@ # so lets fix that for gdb... sys.path.append(os.path.dirname(os.path.abspath(__file__))) -from efi_debugging import PeTeImage, patch_ctypes # noqa: E402 +from efi_debugging import PeImage, patch_ctypes # noqa: E402 from efi_debugging import EfiHob, GuidNames, EfiStatusClass # noqa: E402 from efi_debugging import EfiBootMode, EfiDevicePath # noqa: E402 from efi_debugging import EfiConfigurationTable, EfiTpl # noqa: E402 @@ -155,7 +155,7 @@ def add_symbols_for_pecoff(cls, pecoff): @ classmethod def address_to_symbols(cls, address, reprobe=False): ''' - Given an address search backwards for a PE/COFF (or TE) header + Given an address search backwards for a PE/COFF header and load symbols. Return a status string. ''' if not isinstance(address, int): @@ -166,12 +166,12 @@ def address_to_symbols(cls, address, reprobe=False): # skip the probe of the remote return f'{pecoff} is already loaded' - pecoff = PeTeImage(cls.file, None) + pecoff = PeImage(cls.file, None) if pecoff.pcToPeCoff(address, cls.stride, cls.range): res = cls.add_symbols_for_pecoff(pecoff) return f'{res}{pecoff}' else: - return f'0x{address:08x} not in a PE/COFF (or TE) image' + return f'0x{address:08x} not in a PE/COFF image' @ classmethod def address_in_loaded_pecoff(cls, address): @@ -289,7 +289,7 @@ def __init__(self): def create_options(self, arg, from_tty): usage = "usage: %prog [options] [arg]" description = ( - "Command that can load EFI PE/COFF and TE image symbols. ") + "Command that can load EFI PE/COFF image symbols. ") self.parser = optparse.OptionParser( description=description, @@ -461,7 +461,7 @@ def __init__(self): def create_options(self, arg, from_tty): usage = "usage: %prog [options] [arg]" description = ( - "Command that can load EFI PE/COFF and TE image symbols. ") + "Command that can load EFI PE/COFF image symbols. ") self.parser = optparse.OptionParser( description=description, @@ -595,9 +595,9 @@ def __init__(self): def create_options(self, arg, from_tty): usage = "usage: %prog [options]" description = ( - "Command that can load EFI PE/COFF and TE image symbols. " + "Command that can load EFI PE/COFF image symbols. " "If you are having trouble in PEI try adding --pei. " - "Given any address search backward for the PE/COFF (or TE header) " + "Given any address search backward for the PE/COFF " "and then parse the PE/COFF image to get debug info. " "The address can come from the current pc, pc values in the " "frame, or an address provided to the command" diff --git a/BaseTools/Scripts/efi_lldb.py b/BaseTools/Scripts/efi_lldb.py index 6487e41bf5..562583cf91 100755 --- a/BaseTools/Scripts/efi_lldb.py +++ b/BaseTools/Scripts/efi_lldb.py @@ -17,7 +17,7 @@ from pathlib import Path from efi_debugging import EfiDevicePath, EfiConfigurationTable, EfiTpl from efi_debugging import EfiHob, GuidNames, EfiStatusClass, EfiBootMode -from efi_debugging import PeTeImage, patch_ctypes +from efi_debugging import PeImage, patch_ctypes try: # Just try for LLDB in case PYTHONPATH is already correctly setup @@ -144,7 +144,7 @@ def add_symbols_for_pecoff(cls, pecoff): str(pecoff.CodeViewUuid)) if module.IsValid(): SBError = cls.target.SetModuleLoadAddress( - module, pecoff.LoadAddress + pecoff.TeAdjust) + module, pecoff.LoadAddress) if SBError.success: cls.loaded[pecoff.LoadAddress] = (pecoff, module) return '' @@ -154,7 +154,7 @@ def add_symbols_for_pecoff(cls, pecoff): @ classmethod def address_to_symbols(cls, address, reprobe=False): ''' - Given an address search backwards for a PE/COFF (or TE) header + Given an address search backwards for a PE/COFF header and load symbols. Return a status string. ''' if not isinstance(address, int): @@ -165,12 +165,12 @@ def address_to_symbols(cls, address, reprobe=False): # skip the probe of the remote return f'{pecoff} is already loaded' - pecoff = PeTeImage(cls._file, None) + pecoff = PeImage(cls._file, None) if pecoff.pcToPeCoff(address, cls.stride, cls.range): res = cls.add_symbols_for_pecoff(pecoff) return f'{res}{pecoff}' else: - return f'0x{address:08x} not in a PE/COFF (or TE) image' + return f'0x{address:08x} not in a PE/COFF image' @ classmethod def address_in_loaded_pecoff(cls, address): @@ -596,7 +596,7 @@ class EfiSymbolicateCommand(object): def create_options(self): ''' standard lldb command help/options parser''' usage = "usage: %prog [options]" - description = '''Command that can load EFI PE/COFF and TE image + description = '''Command that can load EFI PE/COFF image symbols. If you are having trouble in PEI try adding --pei. ''' diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c index 3776fb92ed..857c5c294f 100644 --- a/BaseTools/Source/C/GenFfs/GenFfs.c +++ b/BaseTools/Source/C/GenFfs/GenFfs.c @@ -287,7 +287,7 @@ Routine Description: MaxAlignment - The max alignment required by all the input file datas. - PeSectionNum - Calculate the number of Pe/Te Section in this FFS file. + PeSectionNum - Calculate the number of Pe Section in this FFS file. Returns: @@ -304,8 +304,6 @@ Routine Description: FILE *InFile; EFI_FREEFORM_SUBTYPE_GUID_SECTION *SectHeader; EFI_COMMON_SECTION_HEADER2 TempSectHeader; - EFI_TE_IMAGE_HEADER TeHeader; - UINT32 TeOffset; EFI_GUID_DEFINED_SECTION GuidSectHeader; EFI_GUID_DEFINED_SECTION2 GuidSectHeader2; UINT32 HeaderSize; @@ -313,7 +311,6 @@ Routine Description: Size = 0; Offset = 0; - TeOffset = 0; MaxEncounteredAlignment = 1; // @@ -344,22 +341,15 @@ Routine Description: "the input section name is %s and the size is %u bytes", InputFileName[Index], (unsigned) FileSize); // - // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section. + // Check this section is Pe section, and Calculate the numbers of Pe section. // - TeOffset = 0; if (FileSize >= MAX_FFS_SIZE) { HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2); } else { HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER); } fread (&TempSectHeader, 1, HeaderSize, InFile); - if (TempSectHeader.Type == EFI_SECTION_TE) { - (*PESectionNum) ++; - fread (&TeHeader, 1, sizeof (TeHeader), InFile); - if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - TeOffset = TeHeader.StrippedSize - sizeof (TeHeader); - } - } else if (TempSectHeader.Type == EFI_SECTION_PE32) { + if (TempSectHeader.Type == EFI_SECTION_PE32) { (*PESectionNum) ++; } else if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) { fseek (InFile, 0, SEEK_SET); @@ -378,30 +368,21 @@ Routine Description: } else if (TempSectHeader.Type == EFI_SECTION_COMPRESSION || TempSectHeader.Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) { // - // for the encapsulated section, assume it contains Pe/Te section + // for the encapsulated section, assume it contains Pe section // (*PESectionNum) ++; } fseek (InFile, 0, SEEK_SET); - // - // Revert TeOffset to the converse value relative to Alignment - // This is to assure the original PeImage Header at Alignment. - // - if ((TeOffset != 0) && (InputFileAlign [Index] != 0)) { - TeOffset = InputFileAlign [Index] - (TeOffset % InputFileAlign [Index]); - TeOffset = TeOffset % InputFileAlign [Index]; - } - // // make sure section data meet its alignment requirement by adding one pad section. // But the different sections have the different section header. Necessary or not? // Based on section type to adjust offset? Todo // - if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize + TeOffset) % InputFileAlign [Index]) != 0)) { - Offset = (Size + sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1); - Offset = Offset - Size - HeaderSize - TeOffset; + if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize) % InputFileAlign [Index]) != 0)) { + Offset = (Size + sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1); + Offset = Offset - Size - HeaderSize; if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) { // @@ -961,7 +942,7 @@ Routine Description: if ((FfsFiletype == EFI_FV_FILETYPE_SECURITY_CORE || FfsFiletype == EFI_FV_FILETYPE_PEI_CORE || FfsFiletype == EFI_FV_FILETYPE_DXE_CORE) && (PeSectionNum != 1)) { - Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have one and only one Pe or Te section, but %u Pe/Te section are input", mFfsFileType [FfsFiletype], PeSectionNum); + Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have one and only one Pe section, but %u Pe section are input", mFfsFileType [FfsFiletype], PeSectionNum); goto Finish; } @@ -969,7 +950,7 @@ Routine Description: FfsFiletype == EFI_FV_FILETYPE_DRIVER || FfsFiletype == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER || FfsFiletype == EFI_FV_FILETYPE_APPLICATION) && (PeSectionNum < 1)) { - Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have at least one Pe or Te section, but no Pe/Te section is input", mFfsFileType [FfsFiletype]); + Error (NULL, 0, 2000, "Invalid parameter", "Fv File type %s must have at least one Pe section, but no Pe section is input", mFfsFileType [FfsFiletype]); goto Finish; } diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 53c601082b..6e162fccd6 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -768,7 +768,6 @@ Routine Description: UINT32 AddressOfEntryPoint; UINT32 Offset; EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - EFI_TE_IMAGE_HEADER *TEImageHeader; EFI_IMAGE_SECTION_HEADER *SectionHeader; long long TempLongAddress; UINT32 TextVirtualAddress; @@ -839,24 +838,18 @@ Routine Description: // // AddressOfEntryPoint and Offset in Image // - if (!pImageContext->IsTeImage) { - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINT8 *) pImageContext->Handle + pImageContext->PeCoffHeaderOffset); - AddressOfEntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint; - Offset = 0; - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( - (UINT8 *) ImgHdr + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - Index = ImgHdr->Pe32.FileHeader.NumberOfSections; - } else { - TEImageHeader = (EFI_TE_IMAGE_HEADER *) pImageContext->Handle; - AddressOfEntryPoint = TEImageHeader->AddressOfEntryPoint; - Offset = TEImageHeader->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER); - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1); - Index = TEImageHeader->NumberOfSections; - } + assert (!pImageContext->IsTeImage); + + ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINT8 *) pImageContext->Handle + pImageContext->PeCoffHeaderOffset); + AddressOfEntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint; + Offset = 0; + SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( + (UINT8 *) ImgHdr + + sizeof (UINT32) + + sizeof (EFI_IMAGE_FILE_HEADER) + + ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader + ); + Index = ImgHdr->Pe32.FileHeader.NumberOfSections; // // module information output @@ -870,11 +863,7 @@ Routine Description: } fprintf (FvMapFile, "EntryPoint=0x%010llx, ", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint)); - if (!pImageContext->IsTeImage) { - fprintf (FvMapFile, "Type=PE"); - } else { - fprintf (FvMapFile, "Type=TE"); - } + fprintf (FvMapFile, "Type=PE"); fprintf (FvMapFile, ")\n"); fprintf (FvMapFile, "(GUID=%s", FileGuidName); @@ -1305,7 +1294,7 @@ Routine Description: return EFI_ABORTED; } // - // Rebase the PE or TE image in FileBuffer of FFS file for XIP + // Rebase the PE image in FileBuffer of FFS file for XIP // Rebase for the debug genfvmap tool // Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER **)&FileBuffer, &FileSize, (UINTN) *VtfFileImage - (UINTN) FvImage->FileImage, FvMapFile); @@ -1357,7 +1346,7 @@ Routine Description: // if ((UINTN) (FvImage->CurrentFilePointer + FileSize) <= (UINTN) (*VtfFileImage)) { // - // Rebase the PE or TE image in FileBuffer of FFS file for XIP. + // Rebase the PE image in FileBuffer of FFS file for XIP. // Rebase Bs and Rt drivers for the debug genfvmap tool. // Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER **)&FileBuffer, &FileSize, (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage, FvMapFile); @@ -1588,10 +1577,6 @@ Routine Description: // Sec Core found, now find PE32 section // Status = GetSectionByType (SecCoreFile, EFI_SECTION_PE32, 1, &Pe32Section); - if (Status == EFI_NOT_FOUND) { - Status = GetSectionByType (SecCoreFile, EFI_SECTION_TE, 1, &Pe32Section); - } - if (EFI_ERROR (Status)) { Error (NULL, 0, 3000, "Invalid", "could not find a PE32 section in the SEC core file."); return EFI_ABORTED; @@ -1637,15 +1622,11 @@ Routine Description: Status = GetFileByType (EFI_FV_FILETYPE_PEI_CORE, 1, &PeiCoreFile); if (!EFI_ERROR (Status) && (PeiCoreFile != NULL)) { // - // PEI Core found, now find PE32 or TE section + // PEI Core found, now find PE32 section // Status = GetSectionByType (PeiCoreFile, EFI_SECTION_PE32, 1, &Pe32Section); - if (Status == EFI_NOT_FOUND) { - Status = GetSectionByType (PeiCoreFile, EFI_SECTION_TE, 1, &Pe32Section); - } - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "could not find either a PE32 or a TE section in PEI core file."); + Error (NULL, 0, 3000, "Invalid", "could not find either a PE32 section in PEI core file."); return EFI_ABORTED; } @@ -1794,13 +1775,9 @@ Routine Description: if (!EFI_ERROR(Status) && (CoreFfsFile != NULL) ) { // - // Core found, now find PE32 or TE section + // Core found, now find PE32 section // Status = GetSectionByType(CoreFfsFile, EFI_SECTION_PE32, 1, Pe32Section); - if (EFI_ERROR(Status)) { - Status = GetSectionByType(CoreFfsFile, EFI_SECTION_TE, 1, Pe32Section); - } - if (EFI_ERROR(Status)) { Error(NULL, 0, 3000, "Invalid", "could not find a PE32 section in the core file."); return EFI_ABORTED; @@ -2427,7 +2404,6 @@ Routine Description: { EFI_IMAGE_DOS_HEADER *DosHeader; EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - EFI_TE_IMAGE_HEADER *TeHeader; // // Verify input parameters @@ -2437,48 +2413,35 @@ Routine Description: } // - // First check whether it is one TE Image. + // Check whether + // First is the DOS header // - TeHeader = (EFI_TE_IMAGE_HEADER *) Pe32; - if (TeHeader->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - // - // By TeImage Header to get output - // - *EntryPoint = TeHeader->AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader->StrippedSize; - *MachineType = TeHeader->Machine; - } else { - - // - // Then check whether - // First is the DOS header - // - DosHeader = (EFI_IMAGE_DOS_HEADER *) Pe32; + DosHeader = (EFI_IMAGE_DOS_HEADER *) Pe32; - // - // Verify DOS header is expected - // - if (DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - Error (NULL, 0, 3000, "Invalid", "Unknown magic number in the DOS header, 0x%04X.", DosHeader->e_magic); - return EFI_UNSUPPORTED; - } - // - // Immediately following is the NT header. - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINTN) Pe32 + DosHeader->e_lfanew); + // + // Verify DOS header is expected + // + if (DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { + Error (NULL, 0, 3000, "Invalid", "Unknown magic number in the DOS header, 0x%04X.", DosHeader->e_magic); + return EFI_UNSUPPORTED; + } + // + // Immediately following is the NT header. + // + ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINTN) Pe32 + DosHeader->e_lfanew); - // - // Verify NT header is expected - // - if (ImgHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { - Error (NULL, 0, 3000, "Invalid", "Unrecognized image signature 0x%08X.", (unsigned) ImgHdr->Pe32.Signature); - return EFI_UNSUPPORTED; - } - // - // Get output - // - *EntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint; - *MachineType = ImgHdr->Pe32.FileHeader.Machine; + // + // Verify NT header is expected + // + if (ImgHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { + Error (NULL, 0, 3000, "Invalid", "Unrecognized image signature 0x%08X.", (unsigned) ImgHdr->Pe32.Signature); + return EFI_UNSUPPORTED; } + // + // Get output + // + *EntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint; + *MachineType = ImgHdr->Pe32.FileHeader.Machine; // // Verify machine type is supported @@ -3598,7 +3561,6 @@ Routine Description: EFI_FILE_SECTION_POINTER CurrentPe32Section; EFI_FFS_FILE_STATE SavedState; EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - EFI_TE_IMAGE_HEADER *TEImageHeader; UINT8 *MemoryImagePointer; EFI_IMAGE_SECTION_HEADER *SectionHeader; CHAR8 PeFileName [MAX_LONG_FILE_PATH]; @@ -3612,7 +3574,6 @@ Routine Description: Index = 0; MemoryImagePointer = NULL; - TEImageHeader = NULL; ImgHdr = NULL; SectionHeader = NULL; Cptr = NULL; @@ -3945,248 +3906,6 @@ Routine Description: WriteMapFile (FvMapFile, PdbPointer, *FfsFile, NewPe32BaseAddress, &ImageContext); } - if ((*FfsFile)->Type != EFI_FV_FILETYPE_SECURITY_CORE && - (*FfsFile)->Type != EFI_FV_FILETYPE_PEI_CORE && - (*FfsFile)->Type != EFI_FV_FILETYPE_PEIM && - (*FfsFile)->Type != EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER && - (*FfsFile)->Type != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE - ) { - // - // Only Peim code may have a TE section - // - return EFI_SUCCESS; - } - - // - // Now process TE sections - // - for (Index = 1;; Index++) { - NewPe32BaseAddress = 0; - - // - // Find Te Image - // - Status = GetSectionByType (*FfsFile, EFI_SECTION_TE, Index, &CurrentPe32Section); - if (EFI_ERROR (Status)) { - break; - } - - CurSecHdrSize = GetSectionHeaderLength(CurrentPe32Section.CommonHeader); - - // - // Calculate the TE base address, the FFS file base plus the offset of the TE section less the size stripped off - // by GenTEImage - // - TEImageHeader = (EFI_TE_IMAGE_HEADER *) ((UINT8 *) CurrentPe32Section.Pe32Section + CurSecHdrSize); - - // - // Initialize context, load image info. - // - memset (&ImageContext, 0, sizeof (ImageContext)); - ImageContext.Handle = (VOID *) TEImageHeader; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead; - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid TeImage", "The input file is %s and the return status is %x", FileName, (int) Status); - return Status; - } - - if ( (ImageContext.Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) || - (ImageContext.Machine == IMAGE_FILE_MACHINE_ARM64) ) { - mArm = TRUE; - } - - if (ImageContext.Machine == IMAGE_FILE_MACHINE_LOONGARCH64) { - mLoongArch = TRUE; - } - - // - // Keep Image Context for TE image in FV - // - memcpy (&OrigImageContext, &ImageContext, sizeof (ImageContext)); - - // - // Get File PdbPointer - // - PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle); - - // - // Set new rebased address. - // - NewPe32BaseAddress = XipBase + (UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) \ - - TEImageHeader->StrippedSize - (UINTN) (*FfsFile); - - // - // if reloc is stripped, try to get the original efi image to get reloc info. - // - if (ImageContext.RelocationsStripped) { - // - // Construct the original efi file name - // - if (strlen (FileName) >= MAX_LONG_FILE_PATH) { - Error (NULL, 0, 2000, "Invalid", "The file name %s is too long.", FileName); - return EFI_ABORTED; - } - strncpy (PeFileName, FileName, MAX_LONG_FILE_PATH - 1); - PeFileName[MAX_LONG_FILE_PATH - 1] = 0; - Cptr = PeFileName + strlen (PeFileName); - while (*Cptr != '.') { - Cptr --; - } - - if (*Cptr != '.') { - Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName); - return EFI_ABORTED; - } else { - *(Cptr + 1) = 'e'; - *(Cptr + 2) = 'f'; - *(Cptr + 3) = 'i'; - *(Cptr + 4) = '\0'; - } - - PeFile = fopen (LongFilePath (PeFileName), "rb"); - if (PeFile == NULL) { - Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName); - //Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName); - //return EFI_ABORTED; - } else { - // - // Get the file size - // - PeFileSize = _filelength (fileno (PeFile)); - PeFileBuffer = (UINT8 *) malloc (PeFileSize); - if (PeFileBuffer == NULL) { - fclose (PeFile); - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); - return EFI_OUT_OF_RESOURCES; - } - // - // Read Pe File - // - fread (PeFileBuffer, sizeof (UINT8), PeFileSize, PeFile); - // - // close file - // - fclose (PeFile); - // - // Append reloc section into TeImage - // - ImageContext.Handle = PeFileBuffer; - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid TeImage", "The input file is %s and the return status is %x", FileName, (int) Status); - return Status; - } - ImageContext.RelocationsStripped = FALSE; - } - } - // - // Relocation doesn't exist - // - if (ImageContext.RelocationsStripped) { - Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName); - continue; - } - - // - // Relocation exist and rebase - // - // - // Load and Relocate Image Data - // - MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); - if (MemoryImagePointer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); - return EFI_OUT_OF_RESOURCES; - } - memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); - ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((UINTN) ImageContext.SectionAlignment - 1)); - - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName); - free ((VOID *) MemoryImagePointer); - return Status; - } - // - // Reloacate TeImage - // - ImageContext.DestinationAddress = NewPe32BaseAddress; - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of TE image %s", FileName); - free ((VOID *) MemoryImagePointer); - return Status; - } - - // - // Copy the relocated image into raw image file. - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TEImageHeader + 1); - for (Index = 0; Index < TEImageHeader->NumberOfSections; Index ++, SectionHeader ++) { - if (!ImageContext.IsTeImage) { - CopyMem ( - (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, - (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), - SectionHeader->SizeOfRawData - ); - } else { - CopyMem ( - (UINT8 *) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->PointerToRawData, - (VOID*) (UINTN) (ImageContext.ImageAddress + sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize + SectionHeader->VirtualAddress), - SectionHeader->SizeOfRawData - ); - } - } - - // - // Free the allocated memory resource - // - free ((VOID *) MemoryImagePointer); - MemoryImagePointer = NULL; - if (PeFileBuffer != NULL) { - free (PeFileBuffer); - PeFileBuffer = NULL; - } - - // - // Update Image Base Address - // - TEImageHeader->ImageBase = NewPe32BaseAddress; - - // - // Now update file checksum - // - if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) { - SavedState = (*FfsFile)->State; - (*FfsFile)->IntegrityCheck.Checksum.File = 0; - (*FfsFile)->State = 0; - (*FfsFile)->IntegrityCheck.Checksum.File = CalculateChecksum8 ( - (UINT8 *)((UINT8 *)(*FfsFile) + FfsHeaderSize), - GetFfsFileLength (*FfsFile) - FfsHeaderSize - ); - (*FfsFile)->State = SavedState; - } - // - // Get this module function address from ModulePeMapFile and add them into FvMap file - // - - // - // Default use FileName as map file path - // - if (PdbPointer == NULL) { - PdbPointer = FileName; - } - - WriteMapFile ( - FvMapFile, - PdbPointer, - *FfsFile, - NewPe32BaseAddress, - &OrigImageContext - ); - } - return EFI_SUCCESS; } diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c index 9d7321515b..d585d10cd5 100644 --- a/BaseTools/Source/C/GenSec/GenSec.c +++ b/BaseTools/Source/C/GenSec/GenSec.c @@ -60,7 +60,7 @@ STATIC CHAR8 *mSectionTypeName[] = { NULL, // 0x0F - reserved "EFI_SECTION_PE32", // 0x10 "EFI_SECTION_PIC", // 0x11 - "EFI_SECTION_TE", // 0x12 + NULL, // 0x12 - formerly TE "EFI_SECTION_DXE_DEPEX", // 0x13 "EFI_SECTION_VERSION", // 0x14 "EFI_SECTION_USER_INTERFACE", // 0x15 @@ -164,7 +164,7 @@ Routine Description: fprintf (stdout, " -s [SectionType], --sectiontype [SectionType]\n\ SectionType defined in PI spec is one type of\n\ EFI_SECTION_COMPRESSION, EFI_SECTION_GUID_DEFINED,\n\ - EFI_SECTION_PE32, EFI_SECTION_PIC, EFI_SECTION_TE,\n\ + EFI_SECTION_PE32, EFI_SECTION_PIC,\n\ EFI_SECTION_DXE_DEPEX, EFI_SECTION_COMPATIBILITY16,\n\ EFI_SECTION_USER_INTERFACE, EFI_SECTION_VERSION,\n\ EFI_SECTION_FIRMWARE_VOLUME_IMAGE, EFI_SECTION_RAW,\n\ @@ -440,8 +440,6 @@ Routine Description: FILE *InFile; EFI_COMMON_SECTION_HEADER *SectHeader; EFI_COMMON_SECTION_HEADER2 TempSectHeader; - EFI_TE_IMAGE_HEADER TeHeader; - UINT32 TeOffset; EFI_GUID_DEFINED_SECTION GuidSectHeader; EFI_GUID_DEFINED_SECTION2 GuidSectHeader2; UINT32 HeaderSize; @@ -458,7 +456,6 @@ Routine Description: Size = 0; Offset = 0; - TeOffset = 0; // // Go through our array of file names and copy their contents // to the output buffer. @@ -492,9 +489,8 @@ Routine Description: // if (InputFileAlign != NULL) { // - // Check this section is Te/Pe section, and Calculate the numbers of Te/Pe section. + // Check this section is Pe section, and Calculate the numbers of Pe section. // - TeOffset = 0; // // The section might be EFI_COMMON_SECTION_HEADER2 // But only Type needs to be checked @@ -505,12 +501,7 @@ Routine Description: HeaderSize = sizeof (EFI_COMMON_SECTION_HEADER); } fread (&TempSectHeader, 1, HeaderSize, InFile); - if (TempSectHeader.Type == EFI_SECTION_TE) { - fread (&TeHeader, 1, sizeof (TeHeader), InFile); - if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - TeOffset = TeHeader.StrippedSize - sizeof (TeHeader); - } - } else if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) { + if (TempSectHeader.Type == EFI_SECTION_GUID_DEFINED) { fseek (InFile, 0, SEEK_SET); if (FileSize >= MAX_SECTION_SIZE) { fread (&GuidSectHeader2, 1, sizeof (GuidSectHeader2), InFile); @@ -527,21 +518,12 @@ Routine Description: fseek (InFile, 0, SEEK_SET); - // - // Revert TeOffset to the converse value relative to Alignment - // This is to assure the original PeImage Header at Alignment. - // - if (TeOffset != 0) { - TeOffset = InputFileAlign [Index] - (TeOffset % InputFileAlign [Index]); - TeOffset = TeOffset % InputFileAlign [Index]; - } - // // make sure section data meet its alignment requirement by adding one raw pad section. // - if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize + TeOffset) % InputFileAlign [Index]) != 0)) { - Offset = (Size + sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + TeOffset + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1); - Offset = Offset - Size - HeaderSize - TeOffset; + if ((InputFileAlign [Index] != 0) && (((Size + HeaderSize) % InputFileAlign [Index]) != 0)) { + Offset = (Size + sizeof (EFI_COMMON_SECTION_HEADER) + HeaderSize + InputFileAlign [Index] - 1) & ~(InputFileAlign [Index] - 1); + Offset = Offset - Size - HeaderSize; if (FileBuffer != NULL && ((Size + Offset) < *BufferLength)) { // @@ -1715,8 +1697,6 @@ Routine Description: SectType = EFI_SECTION_PE32; } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_PIC]) == 0) { SectType = EFI_SECTION_PIC; - } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_TE]) == 0) { - SectType = EFI_SECTION_TE; } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_DXE_DEPEX]) == 0) { SectType = EFI_SECTION_DXE_DEPEX; } else if (stricmp (SectionName, mSectionTypeName[EFI_SECTION_SMM_DEPEX]) == 0) { diff --git a/BaseTools/Source/C/VolInfo/VolInfo.c b/BaseTools/Source/C/VolInfo/VolInfo.c index be8e30dbde..5fe962729f 100644 --- a/BaseTools/Source/C/VolInfo/VolInfo.c +++ b/BaseTools/Source/C/VolInfo/VolInfo.c @@ -665,7 +665,7 @@ Routine Description: // // 0x12 // - "EFI_SECTION_TE", + "Unsupported section type - formerly TE", // // 0x13 // @@ -1788,7 +1788,6 @@ Routine Description: switch (Type) { case EFI_SECTION_RAW: case EFI_SECTION_PIC: - case EFI_SECTION_TE: // default is no more information break; diff --git a/BaseTools/Source/Python/Common/DataType.py b/BaseTools/Source/Python/Common/DataType.py index 48dbf16495..fdbcdbc308 100644 --- a/BaseTools/Source/Python/Common/DataType.py +++ b/BaseTools/Source/Python/Common/DataType.py @@ -122,7 +122,6 @@ BINARY_FILE_TYPE_PEI_DEPEX = 'PEI_DEPEX' BINARY_FILE_TYPE_DXE_DEPEX = 'DXE_DEPEX' BINARY_FILE_TYPE_SMM_DEPEX = 'SMM_DEPEX' -BINARY_FILE_TYPE_TE = 'TE' BINARY_FILE_TYPE_VER = 'VER' BINARY_FILE_TYPE_UI = 'UI' BINARY_FILE_TYPE_BIN = 'BIN' diff --git a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py index 5ca4c20dc6..936a9244cc 100644 --- a/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py +++ b/BaseTools/Source/Python/FMMT/core/BiosTreeNode.py @@ -18,7 +18,6 @@ 0x03:'EFI_SECTION_DISPOSABLE', 0x10:'EFI_SECTION_PE32', 0x11:'EFI_SECTION_PIC', - 0x12:'EFI_SECTION_TE', 0x13:'EFI_SECTION_DXE_DEPEX', 0x14:'EFI_SECTION_VERSION', 0x15:'EFI_SECTION_USER_INTERFACE', diff --git a/BaseTools/Source/Python/GenFds/DataSection.py b/BaseTools/Source/Python/GenFds/DataSection.py index abf75abcc7..61d162f31b 100644 --- a/BaseTools/Source/Python/GenFds/DataSection.py +++ b/BaseTools/Source/Python/GenFds/DataSection.py @@ -79,10 +79,10 @@ def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = No CopyLongFilePath(MapFile, CopyMapFile) #Get PE Section alignment when align is set to AUTO - if self.Alignment == 'Auto' and self.SecType in (BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32): + if self.Alignment == 'Auto' and self.SecType in (BINARY_FILE_TYPE_PE32): self.Alignment = "0" NoStrip = True - if self.SecType in (BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32): + if self.SecType in (BINARY_FILE_TYPE_PE32): if self.KeepReloc is not None: NoStrip = self.KeepReloc @@ -100,16 +100,6 @@ def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = No ) self.SectFileName = StrippedFile - if self.SecType == BINARY_FILE_TYPE_TE: - TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw') - GenFdsGlobalVariable.GenerateFirmwareImage( - TeFile, - [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)], - Type='te', - IsMakefile = IsMakefile - ) - self.SectFileName = TeFile - OutputFile = os.path.join (OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get(self.SecType)) OutputFile = os.path.normpath(OutputFile) GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType), IsMakefile = IsMakefile) diff --git a/BaseTools/Source/Python/GenFds/EfiSection.py b/BaseTools/Source/Python/GenFds/EfiSection.py index bbbf3eca6b..809260651f 100644 --- a/BaseTools/Source/Python/GenFds/EfiSection.py +++ b/BaseTools/Source/Python/GenFds/EfiSection.py @@ -62,7 +62,7 @@ def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = Non StringData = FfsInf.__ExtendMacro__(self.StringData) ModuleNameStr = FfsInf.__ExtendMacro__('$(MODULE_NAME)') NoStrip = True - if FfsInf.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE) and SectionType in (BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32): + if FfsInf.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE) and SectionType in (BINARY_FILE_TYPE_PE32): if FfsInf.KeepReloc is not None: NoStrip = FfsInf.KeepReloc elif FfsInf.KeepRelocFromRule is not None: @@ -259,7 +259,7 @@ def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = Non File = GenFdsGlobalVariable.MacroExtend(File, Dict) #Get PE Section alignment when align is set to AUTO - if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_TE): + if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32): Align = "0" if File[(len(File)-4):] == '.efi' and FfsInf.InfModule.BaseName == os.path.basename(File)[:-4]: MapFile = File.replace('.efi', '.map') @@ -295,18 +295,6 @@ def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = Non ) File = StrippedFile - """For TE Section call GenFw to generate TE image""" - - if SectionType == BINARY_FILE_TYPE_TE: - TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw') - GenFdsGlobalVariable.GenerateFirmwareImage( - TeFile, - [File], - Type='te', - IsMakefile = IsMakefile - ) - File = TeFile - """Call GenSection""" GenFdsGlobalVariable.GenerateSection(OutputFile, [File], diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py index cab4fecce0..cdc448adcc 100644 --- a/BaseTools/Source/Python/GenFds/FdfParser.py +++ b/BaseTools/Source/Python/GenFds/FdfParser.py @@ -2597,7 +2597,7 @@ def _FileCouldHaveRelocFlag (FileType): # @staticmethod def _SectionCouldHaveRelocFlag (SectionType): - if SectionType in {BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32}: + if SectionType in {BINARY_FILE_TYPE_PE32}: return True else: return False @@ -2806,7 +2806,7 @@ def _GetLeafSection(self, Obj): if self._IsKeyword("VERSION"): if AlignValue == 'Auto': - raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber) if not self._IsToken(TAB_EQUAL_SPLIT): raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) if not self._GetNextToken(): @@ -2822,7 +2822,7 @@ def _GetLeafSection(self, Obj): elif self._IsKeyword(BINARY_FILE_TYPE_UI): if AlignValue == 'Auto': - raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber) if not self._IsToken(TAB_EQUAL_SPLIT): raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) if not self._GetNextToken(): @@ -2837,7 +2837,7 @@ def _GetLeafSection(self, Obj): elif self._IsKeyword("FV_IMAGE"): if AlignValue == 'Auto': - raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber) if not self._IsToken(TAB_EQUAL_SPLIT): raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) if not self._GetNextToken(): @@ -2878,7 +2878,7 @@ def _GetLeafSection(self, Obj): elif self._IsKeyword("PEI_DEPEX_EXP") or self._IsKeyword("DXE_DEPEX_EXP") or self._IsKeyword("SMM_DEPEX_EXP"): if AlignValue == 'Auto': - raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber) DepexSectionObj = DepexSection() DepexSectionObj.Alignment = AlignValue DepexSectionObj.DepexType = self._Token @@ -2895,7 +2895,7 @@ def _GetLeafSection(self, Obj): elif self._IsKeyword("SUBTYPE_GUID"): if AlignValue == 'Auto': - raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber) SubTypeGuidValue = None if not self._GetNextGuid(): raise Warning.Expected("GUID", self.FileName, self.CurrentLineNumber) @@ -2923,11 +2923,11 @@ def _GetLeafSection(self, Obj): self.SetFileBufferPos(OldPos) return False - if self._Token not in {"COMPAT16", BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\ + if self._Token not in {"COMPAT16", BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_PIC, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\ BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX}: raise Warning("Unknown section type '%s'" % self._Token, self.FileName, self.CurrentLineNumber) - if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32) and (not self._Token == BINARY_FILE_TYPE_TE): - raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32): + raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber) # DataSection DataSectionObj = DataSection() @@ -3726,7 +3726,7 @@ def _GetRuleFileStatements(self): if SectionName not in { "COMPAT16", BINARY_FILE_TYPE_PE32, - BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE", + BINARY_FILE_TYPE_PIC, "FV_IMAGE", "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX}: @@ -3743,8 +3743,8 @@ def _GetRuleFileStatements(self): if self._GetAlignment(): if self._Token not in ALIGNMENTS: raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber) - if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE): - raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32): + raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber) SectAlignment = self._Token Ext = None @@ -3796,7 +3796,7 @@ def _GetEfiSection(self, Obj): if SectionName not in { "COMPAT16", BINARY_FILE_TYPE_PE32, - BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE", + BINARY_FILE_TYPE_PIC, "FV_IMAGE", "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX, BINARY_FILE_TYPE_GUID}: @@ -3843,7 +3843,7 @@ def _GetEfiSection(self, Obj): elif self._GetNextToken(): if self._Token not in { T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32, - BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, + BINARY_FILE_TYPE_PIC, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID, @@ -3907,8 +3907,8 @@ def _GetEfiSection(self, Obj): if self._GetAlignment(): if self._Token not in ALIGNMENTS: raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber) - if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE): - raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32): + raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber) EfiSectionObj.Alignment = self._Token if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'): @@ -3928,7 +3928,7 @@ def _GetEfiSection(self, Obj): elif self._GetNextToken(): if self._Token not in { T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32, - BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, + BINARY_FILE_TYPE_PIC, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID, @@ -4020,9 +4020,6 @@ def _CheckRuleSectionFileType(self, SectionType, FileType): elif SectionType == BINARY_FILE_TYPE_PIC: if FileType not in {BINARY_FILE_TYPE_PIC, "SEC_PIC"}: raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) - elif SectionType == BINARY_FILE_TYPE_TE: - if FileType not in {BINARY_FILE_TYPE_TE, "SEC_TE"}: - raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) elif SectionType == "RAW": if FileType not in {BINARY_FILE_TYPE_BIN, "SEC_BIN", "RAW", "ASL", "ACPI"}: raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) diff --git a/BaseTools/Source/Python/GenFds/Ffs.py b/BaseTools/Source/Python/GenFds/Ffs.py index 4e58df279b..64b031f33f 100644 --- a/BaseTools/Source/Python/GenFds/Ffs.py +++ b/BaseTools/Source/Python/GenFds/Ffs.py @@ -33,7 +33,6 @@ SectionSuffix = { BINARY_FILE_TYPE_PE32 : '.pe32', BINARY_FILE_TYPE_PIC : '.pic', - BINARY_FILE_TYPE_TE : '.te', BINARY_FILE_TYPE_DXE_DEPEX : '.dpx', 'VERSION' : '.ver', BINARY_FILE_TYPE_UI : '.ui', diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py index f59cd596f9..b68f363b39 100644 --- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -775,7 +775,7 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch) #Get PE Section alignment when align is set to AUTO - if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_TE): + if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32): ImageObj = PeImageClass (File) if ImageObj.SectionAlignment < 0x400: self.Alignment = str (ImageObj.SectionAlignment) @@ -798,15 +798,6 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): ) File = StrippedFile - if SectionType == BINARY_FILE_TYPE_TE: - TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') - GenFdsGlobalVariable.GenerateFirmwareImage( - TeFile, - [File], - Type='te', - IsMakefile=IsMakefile - ) - File = TeFile GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile) OutputFileList.append(OutputFile) else: @@ -817,7 +808,7 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch) #Get PE Section alignment when align is set to AUTO - if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_TE): + if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32): ImageObj = PeImageClass (GenSecInputFile) if ImageObj.SectionAlignment < 0x400: self.Alignment = str (ImageObj.SectionAlignment) @@ -841,15 +832,6 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): ) GenSecInputFile = StrippedFile - if SectionType == BINARY_FILE_TYPE_TE: - TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') - GenFdsGlobalVariable.GenerateFirmwareImage( - TeFile, - [GenSecInputFile], - Type='te', - IsMakefile=IsMakefile - ) - GenSecInputFile = TeFile GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile) OutputFileList.append(OutputFile) diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py index 885e01e9cc..14a2afc143 100644 --- a/BaseTools/Source/Python/GenFds/GenFds.py +++ b/BaseTools/Source/Python/GenFds/GenFds.py @@ -733,12 +733,12 @@ def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj): if not os.path.exists(FfsPath[0]): continue MatchDict = {} - ReFileEnds = compile(r'\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.te.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$') + ReFileEnds = compile(r'\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$') FileList = os.listdir(FfsPath[0]) for File in FileList: Match = ReFileEnds.search(File) if Match: - for Index in range(1, 8): + for Index in range(1, 7): if Match.group(Index) and Match.group(Index) in MatchDict: MatchDict[Match.group(Index)].append(File) elif Match.group(Index): @@ -759,8 +759,6 @@ def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj): FileList = MatchDict['fv.sec.txt'] elif '.pe32.txt' in MatchDict: FileList = MatchDict['.pe32.txt'] - elif '.te.txt' in MatchDict: - FileList = MatchDict['.te.txt'] elif '.pic.txt' in MatchDict: FileList = MatchDict['.pic.txt'] elif '.raw.txt' in MatchDict: @@ -797,4 +795,3 @@ def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj): if r < 0 or r > 127: r = 1 exit(r) - diff --git a/BaseTools/Source/Python/GenFds/Section.py b/BaseTools/Source/Python/GenFds/Section.py index 859db7230a..d05d656417 100644 --- a/BaseTools/Source/Python/GenFds/Section.py +++ b/BaseTools/Source/Python/GenFds/Section.py @@ -26,7 +26,6 @@ class Section (SectionClassObject): 'FREEFORM' : 'EFI_SECTION_FREEFORM_SUBTYPE_GUID', BINARY_FILE_TYPE_PE32 : 'EFI_SECTION_PE32', BINARY_FILE_TYPE_PIC : 'EFI_SECTION_PIC', - BINARY_FILE_TYPE_TE : 'EFI_SECTION_TE', 'FV_IMAGE' : 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', 'COMPAT16' : 'EFI_SECTION_COMPATIBILITY16', BINARY_FILE_TYPE_DXE_DEPEX : 'EFI_SECTION_DXE_DEPEX', @@ -47,7 +46,6 @@ class Section (SectionClassObject): BINARY_FILE_TYPE_PIC : '.pic', BINARY_FILE_TYPE_PEI_DEPEX : '.depex', 'SEC_PEI_DEPEX' : '.depex', - BINARY_FILE_TYPE_TE : '.te', BINARY_FILE_TYPE_UNI_VER : '.ver', BINARY_FILE_TYPE_VER : '.ver', BINARY_FILE_TYPE_UNI_UI : '.ui', @@ -62,7 +60,6 @@ class Section (SectionClassObject): 'SEC_GUID' : '.sec' , 'SEC_PE32' : '.sec' , 'SEC_PIC' : '.sec', - 'SEC_TE' : '.sec', 'SEC_VER' : '.sec', 'SEC_UI' : '.sec', 'SEC_COMPAT16' : '.sec', @@ -124,8 +121,7 @@ def GetFileList(FfsInf, FileType, FileExtension, Dict = None, IsMakefile=False, for File in FfsInf.BinFileList: if File.Arch == TAB_ARCH_COMMON or FfsInf.CurrentArch == File.Arch: if File.Type == FileType or (int(FfsInf.PiSpecVersion, 16) >= 0x0001000A \ - and FileType == 'DXE_DPEX' and File.Type == BINARY_FILE_TYPE_SMM_DEPEX) \ - or (FileType == BINARY_FILE_TYPE_TE and File.Type == BINARY_FILE_TYPE_PE32): + and FileType == 'DXE_DPEX' and File.Type == BINARY_FILE_TYPE_SMM_DEPEX): if TAB_STAR in FfsInf.TargetOverrideList or File.Target == TAB_STAR or File.Target in FfsInf.TargetOverrideList or FfsInf.TargetOverrideList == []: FileList.append(FfsInf.PatchEfiFile(File.Path, File.Type)) else: diff --git a/BaseTools/Source/Python/UPT/Library/DataType.py b/BaseTools/Source/Python/UPT/Library/DataType.py index 0e47f35670..b212786a6d 100644 --- a/BaseTools/Source/Python/UPT/Library/DataType.py +++ b/BaseTools/Source/Python/UPT/Library/DataType.py @@ -424,7 +424,6 @@ BINARY_FILE_TYPE_PEI_DEPEX = 'PEI_DEPEX' BINARY_FILE_TYPE_DXE_DEPEX = 'DXE_DEPEX' BINARY_FILE_TYPE_SMM_DEPEX = 'SMM_DEPEX' -BINARY_FILE_TYPE_TE = 'TE' BINARY_FILE_TYPE_VER = 'VER' BINARY_FILE_TYPE_UI = 'UI' BINARY_FILE_TYPE_BIN = 'BIN' diff --git a/BaseTools/UserManuals/GenSec_Utility_Man_Page.rtf b/BaseTools/UserManuals/GenSec_Utility_Man_Page.rtf index 2ccaf8f65c..9a98b760d5 100644 --- a/BaseTools/UserManuals/GenSec_Utility_Man_Page.rtf +++ b/BaseTools/UserManuals/GenSec_Utility_Man_Page.rtf @@ -175,13 +175,13 @@ COMPAT16\cell \hich\af4\dbch\af31505\loch\f4 EFI_SECTION_COMPATIBILITY16\cell }\ \ltrch\fcs0 \fs18\cf1\insrsid15798865\charrsid12198464 \hich\af43\dbch\af31505\loch\f43 If no options ar}{\rtlch\fcs1 \af43\afs18 \ltrch\fcs0 \fs18\cf1\insrsid15798865 \hich\af43\dbch\af31505\loch\f43 e specified, tool prints usage.}{\rtlch\fcs1 \ab\af43\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid13127309 \par }{\rtlch\fcs1 \ab\af43\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 Filename1 [FilenameN] -\par }\pard \ltrpar\ql \li360\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin360\itap0 {\rtlch\fcs1 \af43\afs18 \ltrch\fcs0 \fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 Input PE/PE32+ image, or TE image, or other binary files. +\par }\pard \ltrpar\ql \li360\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin360\itap0 {\rtlch\fcs1 \af43\afs18 \ltrch\fcs0 \fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 Input PE/PE32+ image or other binary files. \par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af43\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 -o FileName, --outputfile FileName \par }\pard \ltrpar\ql \li360\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin360\itap0 {\rtlch\fcs1 \af43\afs18 \ltrch\fcs0 \fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 The PI section file is created. This option is required. \par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af43\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 -s SectionType, --sectiontype SectionType \par }\pard \ltrpar\ql \li360\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin360\itap0 {\rtlch\fcs1 \af43\afs18 \ltrch\fcs0 \fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 SectionType defined in PI spec is one type of EFI_SECTION_COMPRE \hich\af43\dbch\af31505\loch\f43 -SSION, EFI_SECTION_GUID_DEFINED, EFI_SECTION_PE32, EFI_SECTION_PIC, EFI_SECTION_TE, EFI_SECTION_DXE_DEPEX, EFI_SECTION_COMPATIBILITY16, EFI_SECTION_USER_INTERFACE, EFI_SECTION_VERSION, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, EFI_SECTION_RAW, EFI_SECTION_FREEFO +SSION, EFI_SECTION_GUID_DEFINED, EFI_SECTION_PE32, EFI_SECTION_PIC, EFI_SECTION_DXE_DEPEX, EFI_SECTION_COMPATIBILITY16, EFI_SECTION_USER_INTERFACE, EFI_SECTION_VERSION, EFI_SECTION_FIRMWARE_VOLUME_IMAGE, EFI_SECTION_RAW, EFI_SECTION_FREEFO \hich\af43\dbch\af31505\loch\f43 R\hich\af43\dbch\af31505\loch\f43 M_SUBTYPE_GUID, EFI_SECTION_PEI_DEPEX. If sectiontype is not given, EFI_SECTION_ALL is default type to contain the input all sections to one section file. \par }\pard \ltrpar\ql \li0\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \ab\af43\afs18 \ltrch\fcs0 \b\fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 -c [Type], --compress [Type] \par }\pard \ltrpar\ql \li360\ri0\sb200\nowidctlpar\wrapdefault\faauto\rin0\lin360\itap0 {\rtlch\fcs1 \af43\afs18 \ltrch\fcs0 \fs18\cf1\insrsid11342878 \hich\af43\dbch\af31505\loch\f43 Compress method type can be PI_NONE, PI_STD or TIANO. If Type is not given, PI_ diff --git a/EmbeddedPkg/Scripts/LauterbachT32/EfiLoadFv.cmm b/EmbeddedPkg/Scripts/LauterbachT32/EfiLoadFv.cmm index c74ddaa6b8..7ba296c9fa 100644 --- a/EmbeddedPkg/Scripts/LauterbachT32/EfiLoadFv.cmm +++ b/EmbeddedPkg/Scripts/LauterbachT32/EfiLoadFv.cmm @@ -112,14 +112,7 @@ ProcessFvSection: ) else ( - if §iontype==0x12 ; TE - ( - do EfiProcessTeImage (&secstart+0x4) - ) - else - ( - print "unknown section type" - ) + print "unknown section type" ) return diff --git a/EmbeddedPkg/Scripts/LauterbachT32/EfiProcessTeImage.cmm b/EmbeddedPkg/Scripts/LauterbachT32/EfiProcessTeImage.cmm deleted file mode 100644 index 379e5de61e..0000000000 --- a/EmbeddedPkg/Scripts/LauterbachT32/EfiProcessTeImage.cmm +++ /dev/null @@ -1,64 +0,0 @@ -; -; Copyright (c) 2011, Hewlett-Packard Company. All rights reserved.
-; -; SPDX-License-Identifier: BSD-2-Clause-Patent -; - - LOCAL &imgstart &strippedsize &debugdirentryrva &debugtype &debugrva &dwarfsig &elfbase &elfpath &pathoffset - ENTRY &imgstart - - &imgstart=&imgstart - print "TE image found at &imgstart" - - ; determine pe header bytes removed to account for in rva references - &strippedsize=(Data.Long(a:&imgstart+0x4)&0xffff0000)>>16. - &strippedsize=&strippedsize-0x28 - - &debugdirentryrva=Data.Long(a:&imgstart+0x20) - if &debugdirentryrva==0 - ( - print "no debug dir for image at &imgstart" - enddo - ) - &debugdirentryrva=&debugdirentryrva-&strippedsize - - &debugtype=Data.Long(a:&imgstart+&debugdirentryrva+0xc) - if (&debugtype!=0xdf)&&(&debugtype!=0x02) - ( - print "debug type is not dwarf for image at &imgstart, it's &debugtype" - enddo - ) - - &debugrva=Data.Long(a:&imgstart+&debugdirentryrva+0x14) - &debugrva=&debugrva-&strippedsize; - &dwarfsig=Data.Long(a:&imgstart+&debugrva); - if &dwarfsig==0x66727764 - ( - &pathoffset=0xc - ) - else - ( - if &dwarfsig==0x3031424E - ( - &pathoffset=0x10 - ) - else - ( - print "debug signature not found for image at &imgstart, its &dwarfsig" - enddo - ) - ) - - &elfpath=Data.String(c:&imgstart+&debugrva+&pathoffset) - - ; elf base is baseofcode (we hope that for TE images it's not baseofdata) - &elfbase=&imgstart+Data.Long(a:&imgstart+0xc)-&strippedsize - - print "found path &elfpath" - ; $fprintf 50, "load /ni /np /a %s &0x%x\n",elfpath,elfbase$; - ON ERROR GOSUB - return - data.load.elf &elfpath &elfbase /NOCODE /NOCLEAR - ON error - -enddo diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc index 1a9b985c03..c6cf430605 100644 --- a/EmulatorPkg/EmulatorPkg.dsc +++ b/EmulatorPkg/EmulatorPkg.dsc @@ -212,7 +212,6 @@ [PcdsFeatureFlag] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE - gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst|FALSE gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables|FALSE [PcdsFixedAtBuild] diff --git a/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py b/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py index 6e67a3e073..d0c89fcd3a 100644 --- a/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py +++ b/IntelFsp2Pkg/Tools/ConfigEditor/ConfigEditor.py @@ -419,7 +419,6 @@ class EFI_SECTION_TYPE: DISPOSABLE = 0x03 PE32 = 0x10 PIC = 0x11 - TE = 0x12 DXE_DEPEX = 0x13 VERSION = 0x14 USER_INTERFACE = 0x15 diff --git a/IntelFsp2Pkg/Tools/SplitFspBin.py b/IntelFsp2Pkg/Tools/SplitFspBin.py index 558eaf401a..2e5cec7cf6 100644 --- a/IntelFsp2Pkg/Tools/SplitFspBin.py +++ b/IntelFsp2Pkg/Tools/SplitFspBin.py @@ -145,20 +145,6 @@ class EFI_IMAGE_DATA_DIRECTORY(Structure): ('Size', c_uint32) ] -class EFI_TE_IMAGE_HEADER(Structure): - _fields_ = [ - ('Signature', ARRAY(c_char, 2)), - ('Machine', c_uint16), - ('NumberOfSections', c_uint8), - ('Subsystem', c_uint8), - ('StrippedSize', c_uint16), - ('AddressOfEntryPoint', c_uint32), - ('BaseOfCode', c_uint32), - ('ImageBase', c_uint64), - ('DataDirectoryBaseReloc', EFI_IMAGE_DATA_DIRECTORY), - ('DataDirectoryDebug', EFI_IMAGE_DATA_DIRECTORY) - ] - class EFI_IMAGE_DOS_HEADER(Structure): _fields_ = [ ('e_magic', c_uint16), @@ -326,7 +312,6 @@ class EFI_SECTION_TYPE: DISPOSABLE = 0x03 PE32 = 0x10 PIC = 0x11 - TE = 0x12 DXE_DEPEX = 0x13 VERSION = 0x14 USER_INTERFACE = 0x15 @@ -633,11 +618,8 @@ def ParseFsp(self): class PeTeImage: def __init__(self, offset, data): self.Offset = offset - tehdr = EFI_TE_IMAGE_HEADER.from_buffer (data, 0) - if tehdr.Signature == b'VZ': # TE image - self.TeHdr = tehdr - elif tehdr.Signature == b'MZ': # PE image - self.TeHdr = None + doshdr = EFI_IMAGE_DOS_HEADER.from_buffer (data, 0) + elif doshdr.e_magic == b'MZ': # PE image self.DosHdr = EFI_IMAGE_DOS_HEADER.from_buffer (data, 0) self.PeHdr = EFI_IMAGE_NT_HEADERS32.from_buffer (data, self.DosHdr.e_lfanew) if self.PeHdr.Signature != 0x4550: @@ -658,20 +640,13 @@ def __init__(self, offset, data): self.Data = data self.RelocList = [] - def IsTeImage(self): - return self.TeHdr is not None - def ParseReloc(self): - if self.IsTeImage(): - rsize = self.TeHdr.DataDirectoryBaseReloc.Size - roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress - else: - # Assuming PE32 image type (self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x10b) - rsize = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size - roffset = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress - if self.PeHdr.OptionalHeader.PePlusOptHdr.Magic == 0x20b: # PE32+ image - rsize = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size - roffset = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress + # Assuming PE32 image type (self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x10b) + rsize = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size + roffset = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress + if self.PeHdr.OptionalHeader.PePlusOptHdr.Magic == 0x20b: # PE32+ image + rsize = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size + roffset = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress alignment = 4 offset = roffset @@ -692,8 +667,6 @@ def ParseReloc(self): raise Exception("ERROR: Unsupported relocation type %d!" % rtype) # Calculate the offset of the relocation aoff = blkhdr.PageRVA + roff - if self.IsTeImage(): - aoff += sizeof(self.TeHdr) - self.TeHdr.StrippedSize self.RelocList.append((rtype, aoff)) offset += sizeof(rdata) @@ -718,18 +691,14 @@ def Rebase(self, delta, fdbin): else: raise Exception('ERROR: Unknown relocation type %d !' % rtype) - if self.IsTeImage(): - offset = self.Offset + EFI_TE_IMAGE_HEADER.ImageBase.offset - size = EFI_TE_IMAGE_HEADER.ImageBase.size + offset = self.Offset + self.DosHdr.e_lfanew + offset += EFI_IMAGE_NT_HEADERS32.OptionalHeader.offset + if self.PeHdr.OptionalHeader.PePlusOptHdr.Magic == 0x20b: # PE32+ image + offset += EFI_IMAGE_OPTIONAL_HEADER32_PLUS.ImageBase.offset + size = EFI_IMAGE_OPTIONAL_HEADER32_PLUS.ImageBase.size else: - offset = self.Offset + self.DosHdr.e_lfanew - offset += EFI_IMAGE_NT_HEADERS32.OptionalHeader.offset - if self.PeHdr.OptionalHeader.PePlusOptHdr.Magic == 0x20b: # PE32+ image - offset += EFI_IMAGE_OPTIONAL_HEADER32_PLUS.ImageBase.offset - size = EFI_IMAGE_OPTIONAL_HEADER32_PLUS.ImageBase.size - else: - offset += EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.offset - size = EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.size + offset += EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.offset + size = EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.size value = Bytes2Val(fdbin[offset:offset+size]) + delta fdbin[offset:offset+size] = Val2Bytes(value, size) @@ -815,7 +784,7 @@ def SplitFspBin (fspfile, outdir, nametemplate): def GetImageFromFv (fd, parentfvoffset, fv, imglist): for ffs in fv.FfsList: for sec in ffs.SecList: - if sec.SecHdr.Type in [EFI_SECTION_TYPE.TE, EFI_SECTION_TYPE.PE32]: # TE or PE32 + if sec.SecHdr.Type in [EFI_SECTION_TYPE.PE32]: # PE32 offset = fd.Offset + parentfvoffset + fv.Offset + ffs.Offset + sec.Offset + sizeof(sec.SecHdr) imglist.append ((offset, len(sec.SecData) - sizeof(sec.SecHdr))) diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c index ca57bfaefc..094fc80fe6 100644 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ b/MdeModulePkg/Core/Pei/Image/Image.c @@ -394,47 +394,22 @@ PeiGetPe32Data ( OUT UINT32 *Pe32DataSize ) { - EFI_STATUS Status; - EFI_SECTION_TYPE SearchType1; - EFI_SECTION_TYPE SearchType2; - UINT32 AuthenticationState; + EFI_STATUS Status; + UINT32 AuthenticationState; *Pe32Data = NULL; - if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) { - SearchType1 = EFI_SECTION_TE; - SearchType2 = EFI_SECTION_PE32; - } else { - SearchType1 = EFI_SECTION_PE32; - SearchType2 = EFI_SECTION_TE; - } - // - // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst - // is true, TE will be searched first). + // Try to find the exe section. // Status = PeiServicesFfsFindSectionData4 ( - SearchType1, + EFI_SECTION_PE32, 0, FileHandle, Pe32Data, Pe32DataSize, &AuthenticationState ); - // - // If we didn't find a first exe section, try to find the second exe section. - // - if (EFI_ERROR (Status)) { - Status = PeiServicesFfsFindSectionData4 ( - SearchType2, - 0, - FileHandle, - Pe32Data, - Pe32DataSize, - &AuthenticationState - ); - } - return Status; } @@ -472,52 +447,28 @@ PeiLoadImageLoadImage ( VOID *Pe32Data; UINT32 Pe32DataSize; EFI_PHYSICAL_ADDRESS ImageAddress; - EFI_SECTION_TYPE SearchType1; - EFI_SECTION_TYPE SearchType2; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; *EntryPoint = 0; *AuthenticationState = 0; - if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) { - SearchType1 = EFI_SECTION_TE; - SearchType2 = EFI_SECTION_PE32; - } else { - SearchType1 = EFI_SECTION_PE32; - SearchType2 = EFI_SECTION_TE; - } - // - // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst - // is true, TE will be searched first). + // Try to find the exe section. // Status = PeiServicesFfsFindSectionData4 ( - SearchType1, + EFI_SECTION_PE32, 0, FileHandle, &Pe32Data, &Pe32DataSize, AuthenticationState ); - // - // If we didn't find a first exe section, try to find the second exe section. - // if (EFI_ERROR (Status)) { - Status = PeiServicesFfsFindSectionData4 ( - SearchType2, - 0, - FileHandle, - &Pe32Data, - &Pe32DataSize, - AuthenticationState - ); - if (EFI_ERROR (Status)) { - // - // PEI core only carry the loader function for TE and PE32 executables - // If this two section does not exist, just return. - // - return Status; - } + // + // PEI core only carry the loader function for PE32 executables + // If this two section does not exist, just return. + // + return Status; } DEBUG ((DEBUG_INFO, "Loading PEIM %g\n", FileHandle)); @@ -625,7 +576,7 @@ PeiLoadImageLoadImageWrapper ( /** Check whether the input image has the relocation. - @param Pe32Data Pointer to the PE/COFF or TE image. + @param Pe32Data Pointer to the PE/COFF image. @retval TRUE Relocation is stripped. @retval FALSE Relocation is not stripped. @@ -665,13 +616,7 @@ RelocationIsStrip ( // Look at the file header to determine if relocations have been stripped, and // save this info in the image context for later use. // - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - if ((Hdr.Te->DataDirectory[0].Size == 0) && (Hdr.Te->DataDirectory[0].VirtualAddress == 0)) { - return TRUE; - } else { - return FALSE; - } - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { if ((Hdr.Pe32->FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0) { return TRUE; } else { diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf index 46d7e1c453..e3e7f51d76 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.inf +++ b/MdeModulePkg/Core/Pei/PeiMain.inf @@ -109,7 +109,6 @@ [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressPeiCodePageNumber ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressBootTimeCodePageNumber ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressRuntimeCodePageNumber ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c index dc22b9a7a5..324140a0b0 100644 --- a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c +++ b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c @@ -328,24 +328,6 @@ SmmLoadImage ( &Size, &AuthenticationStatus ); - - if (EFI_ERROR (Status)) { - // - // Try reading TE section secondly - // - Buffer = NULL; - Size = 0; - Status = Fv->ReadSection ( - Fv, - NameGuid, - EFI_SECTION_TE, - 0, - &Buffer, - &Size, - &AuthenticationStatus - ); - } - if (EFI_ERROR (Status)) { if (Buffer != NULL) { gBS->FreePool (Buffer); diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 263435caf2..5446443296 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -825,14 +825,6 @@ # @Prompt Enable ConOut UGA support. gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|TRUE|BOOLEAN|0x00010043 - ## Indicates PeiCore will first search TE section from the PEIM to load the image, or PE32 section, when PeiCore dispatches a PEI module. - # This PCD is used to tune PEI phase performance to reduce the search image time. - # It can be set according to the generated image section type.

- # TRUE - PeiCore will first search TE section from PEIM to load the image, if TE section is not found, then PeiCore will search PE section.
- # FALSE - PeiCore will first search PE section from PEIM to load the image.
- # @Prompt PeiCore search TE section first. - gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst|TRUE|BOOLEAN|0x00010044 - ## Indicates if to turn off the support of legacy usb. So legacy usb device driver can not make use of SMI # interrupt to access usb device in the case of absence of usb stack. # DUET platform requires the token to be TRUE.

diff --git a/MdeModulePkg/MdeModulePkg.uni b/MdeModulePkg/MdeModulePkg.uni index 6079285e3f..7124f07a71 100644 --- a/MdeModulePkg/MdeModulePkg.uni +++ b/MdeModulePkg/MdeModulePkg.uni @@ -715,12 +715,6 @@ "TRUE - Installs UGA Draw Protocol on virtual handle created by ConsplitterDxe.
\n" "FALSE - Does not install UGA Draw Protocol on virtual handle created by ConsplitterDxe.
" -#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdPeiCoreImageLoaderSearchTeSectionFirst_PROMPT #language en-US "PeiCore search TE section first" - -#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdPeiCoreImageLoaderSearchTeSectionFirst_HELP #language en-US "Indicates PeiCore will first search TE section from the PEIM to load the image, or PE32 section, when PeiCore dispatches a PEI module. This PCD is used to tune PEI phase performance to reduce the search image time. It can be set according to the generated image section type.

\n" - "TRUE - PeiCore will first search TE section from PEIM to load the image, if TE section is not found, then PeiCore will search PE section.
\n" - "FALSE - PeiCore will first search PE section from PEIM to load the image.
" - #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdTurnOffUsbLegacySupport_PROMPT #language en-US "Turn off USB legacy support" #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdTurnOffUsbLegacySupport_HELP #language en-US "Disable legacy USB? If disabled, legacy USB device driver cannot make use of SMI interrupt to access USB device in the case of absence of a USB stack. TRUE - disable
\n" diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c index 0252db19ad..43ab654c8a 100644 --- a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c +++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c @@ -78,7 +78,7 @@ FvFsFindExecutableSection ( UINT32 AuthenticationStatus; EFI_STATUS Status; - for (SectionType = EFI_SECTION_PE32; SectionType <= EFI_SECTION_TE; SectionType++) { + for (SectionType = EFI_SECTION_PE32; SectionType <= EFI_SECTION_PIC; SectionType++) { Status = FvProtocol->ReadSection ( FvProtocol, &FvFileInfo->NameGuid, diff --git a/MdePkg/Include/IndustryStandard/PeImage2.h b/MdePkg/Include/IndustryStandard/PeImage2.h index d5a69f7886..29c4e706e5 100644 --- a/MdePkg/Include/IndustryStandard/PeImage2.h +++ b/MdePkg/Include/IndustryStandard/PeImage2.h @@ -724,38 +724,12 @@ typedef struct { } EFI_IMAGE_RESOURCE_DATA_ENTRY; /// -/// Header format for TE images, defined in the PI Specification, 1.0. -/// -typedef struct { - UINT16 Signature; ///< The signature for TE format = "VZ". - UINT16 Machine; ///< From the original file header. - UINT8 NumberOfSections; ///< From the original file header. - UINT8 Subsystem; ///< From original optional header. - UINT16 StrippedSize; ///< Number of bytes we removed from the header. - UINT32 AddressOfEntryPoint; ///< Offset to entry point -- from original optional header. - UINT32 BaseOfCode; ///< From original image -- required for ITP debug. - UINT64 ImageBase; ///< From original file header. - EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; ///< Only base relocation and debug directory. -} EFI_TE_IMAGE_HEADER; - - -#define EFI_TE_IMAGE_HEADER_SIGNATURE SIGNATURE_16('V', 'Z') - -// -// Data directory indexes in our TE image header -// -#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0 -#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1 - - -/// -/// Union of PE32, PE32+, and TE headers. +/// Union of PE32 and PE32+ headers. /// typedef union { EFI_IMAGE_NT_HEADERS_COMMON_HDR PeCommon; EFI_IMAGE_NT_HEADERS32 Pe32; EFI_IMAGE_NT_HEADERS64 Pe32Plus; - EFI_TE_IMAGE_HEADER Te; } EFI_IMAGE_OPTIONAL_HEADER_UNION; #endif // PE_COFF_IMAGE2_H_ diff --git a/MdePkg/Include/Library/DxeServicesLib.h b/MdePkg/Include/Library/DxeServicesLib.h index b5c5c4dbdf..9de8121b20 100644 --- a/MdePkg/Include/Library/DxeServicesLib.h +++ b/MdePkg/Include/Library/DxeServicesLib.h @@ -25,8 +25,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from an FFS file based on SectionType and SectionInstance. - If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, - the search will be retried with a section type of EFI_SECTION_PE32. This function must be called with a TPL <= TPL_NOTIFY. If Buffer is NULL, then ASSERT(). @@ -73,8 +71,6 @@ GetSectionFromAnyFvByFileType ( See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from an FFS file based on SectionType and SectionInstance. - If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, - the search will be retried with a section type of EFI_SECTION_PE32. This function must be called with a TPL <= TPL_NOTIFY. If NameGuid is NULL, then ASSERT(). @@ -126,10 +122,6 @@ GetSectionFromAnyFv ( See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from an FFS file based on SectionType and SectionInstance. - If the currently executing module was not loaded from a firmware volume, then EFI_NOT_FOUND is returned. - If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, - the search will be retried with a section type of EFI_SECTION_PE32. - This function must be called with a TPL <= TPL_NOTIFY. If NameGuid is NULL, then ASSERT(). If Buffer is NULL, then ASSERT(). @@ -179,9 +171,6 @@ GetSectionFromFv ( to use FreePool() to free the allocated buffer. See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from an FFS file based on SectionType and SectionInstance. - If the currently executing module was not loaded from an FFS file, then EFI_NOT_FOUND is returned. - If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, - the search will be retried with a section type of EFI_SECTION_PE32. This function must be called with a TPL <= TPL_NOTIFY. If Buffer is NULL, then ASSERT(). @@ -263,8 +252,6 @@ GetFileBufferByFilePath ( The order that the firmware volumes is searched is not deterministic. For each FFS file found a search is made for FFS sections of type SectionType. - If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, - the search will be retried with a section type of EFI_SECTION_PE32. This function must be called with a TPL <= TPL_NOTIFY. If NameGuid is NULL, then ASSERT(). diff --git a/MdePkg/Include/Library/PeCoffLib2.h b/MdePkg/Include/Library/PeCoffLib2.h index 0985a0bc1e..95222dfdef 100644 --- a/MdePkg/Include/Library/PeCoffLib2.h +++ b/MdePkg/Include/Library/PeCoffLib2.h @@ -55,7 +55,6 @@ /// Image type enumeration for Image format identification from the context. /// typedef enum { - PeCoffLoaderTypeTe, PeCoffLoaderTypePe32, PeCoffLoaderTypePe32Plus, PeCoffLoaderTypeMax @@ -128,11 +127,6 @@ typedef struct { /// UINT16 Machine; /// - /// The size, in Bytes, stripped from the beginning of the Image raw file - /// during TE file generation. Always 0 for PE Images. - /// - UINT16 TeStrippedOffset; - /// /// The RVA of the Relocation Directory. /// UINT32 RelocDirRva; @@ -182,7 +176,7 @@ BOOLEAN FileBuffer must remain valid for the entire lifetime of Context. @param[out] Context The context describing the Image. - @param[in] FileBuffer The file data to parse as TE or PE Image. + @param[in] FileBuffer The file data to parse as PE Image. @param[in] FileSize The size, in Bytes, of FileBuffer. @retval RETURN_SUCCESS The Image context has been initialised successfully. diff --git a/MdePkg/Include/Pi/PiFirmwareFile.h b/MdePkg/Include/Pi/PiFirmwareFile.h index f740f9cd50..f8c65762b2 100644 --- a/MdePkg/Include/Pi/PiFirmwareFile.h +++ b/MdePkg/Include/Pi/PiFirmwareFile.h @@ -212,7 +212,6 @@ typedef UINT8 EFI_SECTION_TYPE; /// #define EFI_SECTION_PE32 0x10 #define EFI_SECTION_PIC 0x11 -#define EFI_SECTION_TE 0x12 #define EFI_SECTION_DXE_DEPEX 0x13 #define EFI_SECTION_VERSION 0x14 #define EFI_SECTION_USER_INTERFACE 0x15 diff --git a/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf index 42b49a82bb..95cfb62beb 100644 --- a/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf +++ b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf @@ -43,7 +43,6 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAlignmentPolicy gEfiMdePkgTokenSpaceGuid.PcdImageLoaderWXorX gEfiMdePkgTokenSpaceGuid.PcdImageLoaderDebugSupport - gEfiMdePkgTokenSpaceGuid.PcdImageLoaderProhibitTe gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX diff --git a/MdePkg/Library/BasePeCoffLib2/Documentation.md b/MdePkg/Library/BasePeCoffLib2/Documentation.md index 0c8ef63e07..f294b3659b 100644 --- a/MdePkg/Library/BasePeCoffLib2/Documentation.md +++ b/MdePkg/Library/BasePeCoffLib2/Documentation.md @@ -7,7 +7,6 @@ An Image Section Table is considered well-formed if and only if: 1. The Image Section Table is sorted by Image section RVA in ascending order. 2. All Image sections are disjoint in the Image memory space. 3. For PE/COFF Images, all Image sections are in bounds of the Image memory space defined by the Image headers. - * For TE Images, the Image memory space is implicitly defined by the Image Section Table. 4. All Image sections are in bounds of the raw file. Additionally, based on PCD policy values, the following constraints may be added: diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffDebug.c b/MdePkg/Library/BasePeCoffLib2/PeCoffDebug.c index 8109b65f57..48cc1ab146 100644 --- a/MdePkg/Library/BasePeCoffLib2/PeCoffDebug.c +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffDebug.c @@ -34,7 +34,6 @@ PeCoffGetPdbPath ( BOOLEAN Overflow; CONST EFI_IMAGE_DATA_DIRECTORY *DebugDir; - CONST EFI_TE_IMAGE_HEADER *TeHdr; CONST EFI_IMAGE_NT_HEADERS32 *Pe32Hdr; CONST EFI_IMAGE_NT_HEADERS64 *Pe32PlusHdr; @@ -63,19 +62,6 @@ PeCoffGetPdbPath ( // Retrieve the Debug Directory of the Image. // switch (Context->ImageType) { - case PeCoffLoaderTypeTe: - if (PcdGetBool (PcdImageLoaderProhibitTe)) { - ASSERT (FALSE); - return RETURN_UNSUPPORTED; - } - - TeHdr = (CONST EFI_TE_IMAGE_HEADER *) (CONST VOID *) ( - (CONST CHAR8 *) Context->FileBuffer - ); - - DebugDir = &TeHdr->DataDirectory[1]; - break; - case PeCoffLoaderTypePe32: Pe32Hdr = (CONST EFI_IMAGE_NT_HEADERS32 *) (CONST VOID *) ( (CONST CHAR8 *) Context->FileBuffer + Context->ExeHdrOffset @@ -170,20 +156,6 @@ PeCoffGetPdbPath ( } DebugEntryFileOffset = CodeViewEntry->FileOffset; - - if (!PcdGetBool (PcdImageLoaderProhibitTe)) { - Overflow = BaseOverflowSubU32 ( - DebugEntryFileOffset, - Context->TeStrippedOffset, - &DebugEntryFileOffset - ); - if (Overflow) { - DEBUG_RAISE (); - return RETURN_VOLUME_CORRUPTED; - } - } else { - ASSERT (Context->TeStrippedOffset == 0); - } // // Verify the CodeView entry is in bounds of the raw file, and the // CodeView entry raw file offset is sufficiently aligned. diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffHash.c b/MdePkg/Library/BasePeCoffLib2/PeCoffHash.c index 12a9495d05..343647d810 100644 --- a/MdePkg/Library/BasePeCoffLib2/PeCoffHash.c +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffHash.c @@ -95,7 +95,6 @@ InternalHashSections ( // // 13. Repeat steps 11 and 12 for all of the sections in the sorted table. // - ASSERT (Context->TeStrippedOffset == 0); for (SectionIndex = 0; SectionIndex < Context->NumberOfSections; ++SectionIndex) { // // Verify the Image section does not overlap with the previous one if the @@ -196,17 +195,6 @@ PeCoffHashImageAuthenticode ( // Additionally, retrieve important offsets for later steps. // switch (Context->ImageType) { - case PeCoffLoaderTypeTe: - if (PcdGetBool (PcdImageLoaderProhibitTe)) { - ASSERT (FALSE); - return FALSE; - } - // - // Authenticode does not define a hashing algorithm for TE Images. - // - DEBUG_RAISE (); - return FALSE; - case PeCoffLoaderTypePe32: Pe32 = (CONST EFI_IMAGE_NT_HEADERS32 *) (CONST VOID *) ( (CONST CHAR8 *) Context->FileBuffer + Context->ExeHdrOffset diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffHii.c b/MdePkg/Library/BasePeCoffLib2/PeCoffHii.c index a877031ca9..fab2431100 100644 --- a/MdePkg/Library/BasePeCoffLib2/PeCoffHii.c +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffHii.c @@ -50,16 +50,6 @@ PeCoffGetHiiDataRva ( // Retrieve the Image's Resource Directory Table. // switch (Context->ImageType) { - case PeCoffLoaderTypeTe: - if (PcdGetBool (PcdImageLoaderProhibitTe)) { - ASSERT (FALSE); - return RETURN_UNSUPPORTED; - } - // - // TE Images do not contain a Resource Directory Table. - // - return RETURN_NOT_FOUND; - case PeCoffLoaderTypePe32: Pe32Hdr = (CONST EFI_IMAGE_NT_HEADERS32 *) (CONST VOID *) ( (CONST CHAR8 *) Context->FileBuffer + Context->ExeHdrOffset diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c b/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c index 38211f1c89..5b36cf2794 100644 --- a/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c @@ -75,23 +75,9 @@ PeCoffGetSizeOfImageInplace ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context ) { - UINT32 SizeOfImage; - ASSERT (Context != NULL); - SizeOfImage = Context->SizeOfImage; - // - // SizeOfImage is defined with the full Image header size pre-stripping. As - // XIP TE Images always have a stripped Image header, subtract the difference. - // - if (!PcdGetBool (PcdImageLoaderProhibitTe)) { - ASSERT (Context->TeStrippedOffset < SizeOfImage); - SizeOfImage -= Context->TeStrippedOffset; - } else { - ASSERT (Context->TeStrippedOffset == 0); - } - - return SizeOfImage; + return Context->SizeOfImage; } UINT64 diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c index bde745ff38..897b168fdd 100644 --- a/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c @@ -58,12 +58,10 @@ InternalVerifySections ( BOOLEAN Overflow; UINT32 NextSectRva; UINT32 SectRawEnd; - UINT32 EffectiveSectRawEnd; UINT16 SectionIndex; CONST EFI_IMAGE_SECTION_HEADER *Sections; ASSERT (Context != NULL); - ASSERT (Context->TeStrippedOffset <= Context->SizeOfHeaders); ASSERT (IS_POW2 (Context->SectionAlignment)); ASSERT (StartAddress != NULL); // @@ -83,19 +81,6 @@ InternalVerifySections ( // if (Sections[0].VirtualAddress == 0) { // FIXME: Add PCD to disallow. - // - // TE Images cannot support loading the Image Headers as part of the first - // Image section due to its StrippedSize sematics. - // - if (!PcdGetBool (PcdImageLoaderProhibitTe)) { - if (Context->ImageType == PeCoffLoaderTypeTe) { - DEBUG_RAISE (); - return RETURN_VOLUME_CORRUPTED; - } - } else { - ASSERT (Context->ImageType != PeCoffLoaderTypeTe); - } - NextSectRva = 0; } else { // @@ -174,15 +159,6 @@ InternalVerifySections ( // Verify the Image sections with data are in bounds of the file buffer. // if (Sections[SectionIndex].SizeOfRawData > 0) { - if (!PcdGetBool (PcdImageLoaderProhibitTe)) { - if (Context->TeStrippedOffset > Sections[SectionIndex].PointerToRawData) { - DEBUG_RAISE (); - return RETURN_VOLUME_CORRUPTED; - } - } else { - ASSERT (Context->TeStrippedOffset == 0); - } - Overflow = BaseOverflowAddU32 ( Sections[SectionIndex].PointerToRawData, Sections[SectionIndex].SizeOfRawData, @@ -193,14 +169,7 @@ InternalVerifySections ( return RETURN_VOLUME_CORRUPTED; } - if (!PcdGetBool (PcdImageLoaderProhibitTe)) { - EffectiveSectRawEnd = SectRawEnd - Context->TeStrippedOffset; - } else { - ASSERT (Context->TeStrippedOffset == 0); - EffectiveSectRawEnd = SectRawEnd; - } - - if (EffectiveSectRawEnd > FileSize) { + if (SectRawEnd > FileSize) { DEBUG_RAISE (); return RETURN_VOLUME_CORRUPTED; } @@ -353,131 +322,6 @@ InternalValidateRelocInfo ( return RETURN_SUCCESS; } -/** - Verify the TE Image and initialise Context. - - Used offsets and ranges must be aligned and in the bounds of the raw file. - Image section Headers and basic Relocation information must be well-formed. - - @param[in,out] Context The context describing the Image. Must have been - initialised by PeCoffInitializeContext(). - @param[in] FileSize The size, in Bytes, of Context->FileBuffer. - - @retval RETURN_SUCCESS The TE Image is well-formed. - @retval other The TE Image is malformed. -**/ -STATIC -RETURN_STATUS -InternalInitializeTe ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, - IN UINT32 FileSize - ) -{ - RETURN_STATUS Status; - BOOLEAN Overflow; - CONST EFI_TE_IMAGE_HEADER *TeHdr; - UINT32 StartAddress; - - ASSERT (Context != NULL); - ASSERT (Context->ExeHdrOffset == 0); - ASSERT (sizeof (EFI_TE_IMAGE_HEADER) <= FileSize); - - if (PcdGetBool (PcdImageLoaderProhibitTe)) { - ASSERT (FALSE); - return RETURN_UNSUPPORTED; - } - - TeHdr = (CONST EFI_TE_IMAGE_HEADER *) (CONST VOID *) ( - (CONST CHAR8 *) Context->FileBuffer - ); - - Context->ImageType = PeCoffLoaderTypeTe; - // - // Calculate the size, in Bytes, stripped from the Image Headers. - // - Overflow = BaseOverflowSubU16 ( - TeHdr->StrippedSize, - sizeof (*TeHdr), - &Context->TeStrippedOffset - ); - if (Overflow) { - DEBUG_RAISE (); - return RETURN_VOLUME_CORRUPTED; - } - - STATIC_ASSERT ( - MAX_UINT8 * sizeof (EFI_IMAGE_SECTION_HEADER) <= MAX_UINT32 - MAX_UINT16, - "The following arithmetic may overflow." - ); - // - // Calculate SizeOfHeaders in a way that is equivalent to what the size would - // be if this was the original (unstripped) PE32 binary. As the TE image - // creation doesn't fix fields up, values work the same way as for PE32. - // When referencing raw data however, the TE stripped size must be subracted. - // - Context->SizeOfHeaders = (UINT32) TeHdr->StrippedSize + (UINT32) TeHdr->NumberOfSections * sizeof (EFI_IMAGE_SECTION_HEADER); - // - // Verify that the Image Headers are in bounds of the file buffer. - // - if (Context->SizeOfHeaders - Context->TeStrippedOffset > FileSize) { - DEBUG_RAISE (); - return RETURN_VOLUME_CORRUPTED; - } - - STATIC_ASSERT ( - IS_ALIGNED (sizeof (*TeHdr), ALIGNOF (EFI_IMAGE_SECTION_HEADER)), - "The Image section alignment requirements are violated." - ); - // - // TE Image sections start right after the Image Headers. - // - Context->SectionsOffset = sizeof (EFI_TE_IMAGE_HEADER); - // - // TE Images do not store their section alignment. Assume the UEFI Page size - // by default, as it is the minimum to guarantee memory permission support. - // - Context->SectionAlignment = EFI_PAGE_SIZE; - Context->NumberOfSections = TeHdr->NumberOfSections; - // - // Validate the sections. - // TE images do not have a field to explicitly describe the image size. - // Set it to the top of the Image's memory space. - // - Status = InternalVerifySections ( - Context, - FileSize, - &StartAddress - ); - if (Status != RETURN_SUCCESS) { - DEBUG_RAISE (); - return Status; - } - // - // Verify the Image entry point is in bounds of the Image buffer. - // - if (TeHdr->AddressOfEntryPoint >= Context->SizeOfImage) { - DEBUG_RAISE (); - return RETURN_VOLUME_CORRUPTED; - } - - Context->Machine = TeHdr->Machine; - Context->Subsystem = TeHdr->Subsystem; - Context->ImageBase = TeHdr->ImageBase; - Context->AddressOfEntryPoint = TeHdr->AddressOfEntryPoint; - Context->RelocDirRva = TeHdr->DataDirectory[0].VirtualAddress; - Context->RelocDirSize = TeHdr->DataDirectory[0].Size; - // - // TE Images do not explicitly store whether their Relocations have been - // stripped. Relocations have been stripped if and only if both the RVA and - // size of the Relocation Directory are zero. - // - Context->RelocsStripped = TeHdr->DataDirectory[0].VirtualAddress == 0 && TeHdr->DataDirectory[0].Size == 0; - // - // Verify basic sanity of the Relocation Directory. - // - return InternalValidateRelocInfo (Context, StartAddress); -} - /** Verify the PE32 or PE32+ Image and initialise Context. @@ -771,8 +615,6 @@ InternalInitializePe ( ASSERT (Context->SecDirOffset == 0); ASSERT (Context->SecDirSize == 0); } - - ASSERT (Context->TeStrippedOffset == 0); // // Verify the Image sections are Well-formed. // @@ -848,24 +690,6 @@ PeCoffInitializeContext ( && !IS_ALIGNED (Context->ExeHdrOffset, ALIGNOF (EFI_IMAGE_NT_HEADERS_COMMON_HDR))) { return RETURN_UNSUPPORTED; } - } else if (!PcdGetBool (PcdImageLoaderProhibitTe)) { - // - // Assume the Image starts with the Executable Header, determine whether it - // is a TE Image. - // - if (sizeof (EFI_TE_IMAGE_HEADER) <= FileSize - && *(CONST UINT16 *) (CONST VOID *) FileBuffer == EFI_TE_IMAGE_HEADER_SIGNATURE) { - // - // Verify the TE Image Header is well-formed. - // - Status = InternalInitializeTe (Context, FileSize); - if (Status != RETURN_SUCCESS) { - DEBUG_RAISE (); - return Status; - } - - return RETURN_SUCCESS; - } } // // Verify the file buffer can hold a PE Common Header. diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c b/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c index 6aa1acb38f..e6cdc80399 100644 --- a/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.c @@ -75,12 +75,7 @@ InternalLoadSections ( // // Load the current Image section into the memory space. // - if (!PcdGetBool (PcdImageLoaderProhibitTe)) { - EffectivePointerToRawData = Sections[SectionIndex].PointerToRawData - Context->TeStrippedOffset; - } else { - ASSERT (Context->TeStrippedOffset == 0); - EffectivePointerToRawData = Sections[SectionIndex].PointerToRawData; - } + EffectivePointerToRawData = Sections[SectionIndex].PointerToRawData; CopyMem ( (CHAR8 *) Context->ImageBuffer + Sections[SectionIndex].VirtualAddress, @@ -122,7 +117,7 @@ PeCoffLoadImage ( (CONST CHAR8 *) Context->FileBuffer + Context->SectionsOffset ); if (PcdGetBool (PcdImageLoaderLoadHeader) && Sections[0].VirtualAddress != 0) { - LoadedHeaderSize = Context->SizeOfHeaders - Context->TeStrippedOffset; + LoadedHeaderSize = Context->SizeOfHeaders; CopyMem (Context->ImageBuffer, Context->FileBuffer, LoadedHeaderSize); } else { LoadedHeaderSize = 0; @@ -144,7 +139,6 @@ PeCoffLoadImageInplaceNoBase ( CONST EFI_IMAGE_SECTION_HEADER *Sections; UINT32 AlignedSize; UINT16 SectionIndex; - CHAR8 *ImageBuffer; ASSERT (Context != NULL); @@ -164,22 +158,7 @@ PeCoffLoadImageInplaceNoBase ( } } - ImageBuffer = (CHAR8 *) Context->FileBuffer; - if (!PcdGetBool (PcdImageLoaderProhibitTe)) { - // FIXME: Abstract all accesses to ImageBuffer for safety? - // - // TE XIP Images are padded to be aligned such that their Image sections - // are correctly aligned. ImageBuffer is used exclusively to accesses RVAs, - // which for TE XIP Images are always off by Context->TeStrippedOffset. - // There is no other way but to treat the data in front of the TE Image - // Header as a part of the TE Image Header. - // - ImageBuffer -= Context->TeStrippedOffset; - } else { - ASSERT (Context->ImageType != PeCoffLoaderTypeTe); - } - - Context->ImageBuffer = ImageBuffer; + Context->ImageBuffer = (CHAR8 *) Context->FileBuffer; return RETURN_SUCCESS; } @@ -194,12 +173,6 @@ PeCoffImageIsInplace ( ASSERT (Context != NULL); ImageBase = PeCoffGetImageBase (Context); - - if (!PcdGetBool (PcdImageLoaderProhibitTe)) { - ImageBase += Context->TeStrippedOffset; - } else { - ASSERT (Context->TeStrippedOffset == 0); - } // // Verify the Image is located at its preferred load address. // diff --git a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf index a533706604..4e1cfe6058 100644 --- a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf +++ b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf @@ -1,5 +1,5 @@ ## @file -# UEFI Image Loader library implementation for PE/COFF and TE Images. +# UEFI Image Loader library implementation for PE/COFF Images. # # Copyright (c) 2021, Marvin Häuser. All rights reserved.
# @@ -37,6 +37,5 @@ [FixedPcd] gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAlignmentPolicy gEfiMdePkgTokenSpaceGuid.PcdImageLoaderLoadHeader - gEfiMdePkgTokenSpaceGuid.PcdImageLoaderProhibitTe gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX diff --git a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c b/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c index 683ee0a9af..926914e7c9 100644 --- a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c @@ -1,5 +1,5 @@ /** @file - UEFI Image Loader library implementation for PE/COFF and TE Images. + UEFI Image Loader library implementation for PE/COFF Images. Copyright (c) 2021, Marvin Häuser. All rights reserved.
@@ -318,16 +318,14 @@ InternalDebugLocateImage ( // // Search for the Image Header in 4 Byte steps. All dynamically loaded // Images start at a page boundary to allow for Image section protection, - // but XIP Images may not. As all Image Headers are at least 4 Byte aligned - // due to natural alignment, even XIP TE Image Headers should start at a - // 4 Byte boundary. + // but XIP Images may not. // // Do not attempt to access memory of the first page as it may be protected as // part of NULL dereference detection. // for (; EFI_PAGE_SIZE <= (UINTN) Buffer; Buffer -= 4) { // - // Try to parse the current memory as PE/COFF or TE Image. Pass MAX_UINT32 + // Try to parse the current memory as PE/COFF Image. Pass MAX_UINT32 // as the file size as there isn't any more information available. Only the // Image Header memory will be accessed as part of initialisation. // @@ -348,11 +346,7 @@ InternalDebugLocateImage ( // is a part of, if existent. Allow one level of recursion to find a lower // Image Base including the DOS Image Header. // - if ((PcdGetBool (PcdImageLoaderProhibitTe) - || Context->ImageType != PeCoffLoaderTypeTe) - && Context->ExeHdrOffset == 0) { - ASSERT (Context->ImageType != PeCoffLoaderTypeTe); - + if (Context->ExeHdrOffset == 0) { DosStatus = InternalDebugLocateImage ( &DosContext, Buffer - 4, @@ -368,7 +362,6 @@ InternalDebugLocateImage ( // // We know that (UINTN) Buffer <= Address from the initialisation. // - // FIXME: Set to non-stripped base for XIP TE Images. if (Address < (UINTN) Buffer + PeCoffGetSizeOfImage (Context)) { Context->ImageBuffer = Buffer; // @@ -381,7 +374,7 @@ InternalDebugLocateImage ( return RETURN_SUCCESS; } // - // Continue for the unlikely case that a PE/COFF or TE Image embeds another + // Continue for the unlikely case that a PE/COFF Image embeds another // one within its data, the outer Image may still follow. // } diff --git a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.h b/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.h index 102e09375f..6c5098362d 100644 --- a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.h +++ b/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.h @@ -1,5 +1,5 @@ /** @file - UEFI Image Loader library implementation for PE/COFF and TE Images. + UEFI Image Loader library implementation for PE/COFF Images. Copyright (c) 2021, Marvin Häuser. All rights reserved.
diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.c b/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.c index 76b43f228a..3350c92466 100644 --- a/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.c +++ b/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.c @@ -1,5 +1,5 @@ /** @file - UEFI Image Loader library implementation for PE/COFF and TE Images. + UEFI Image Loader library implementation for PE/COFF Images. Copyright (c) 2021, Marvin Häuser. All rights reserved.
diff --git a/MdePkg/Library/DxeServicesLib/DxeServicesLib.c b/MdePkg/Library/DxeServicesLib/DxeServicesLib.c index 8f5a15dedc..942ef2a19e 100644 --- a/MdePkg/Library/DxeServicesLib/DxeServicesLib.c +++ b/MdePkg/Library/DxeServicesLib/DxeServicesLib.c @@ -76,10 +76,6 @@ InternalImageHandleToFvHandle ( The details of this search order is defined in description of EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection () found in PI Specification. - If SectionType is EFI_SECTION_TE, EFI_SECTION_TE is used as section type to start the search. If EFI_SECTION_TE section - is not found, EFI_SECTION_PE32 will be used to try the search again. If no EFI_SECTION_PE32 section is found, EFI_NOT_FOUND - is returned. - The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated by this function. This function can be only called at TPL_NOTIFY and below. @@ -157,23 +153,6 @@ InternalGetSectionFromFv ( &AuthenticationStatus ); - if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) { - // - // Try reading PE32 section, if the required section is TE type - // - *Buffer = NULL; - *Size = 0; - Status = Fv->ReadSection ( - Fv, - NameGuid, - EFI_SECTION_PE32, - SectionInstance, - Buffer, - Size, - &AuthenticationStatus - ); - } - return Status; } @@ -191,8 +170,6 @@ InternalGetSectionFromFv ( See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from an FFS file based on SectionType and SectionInstance. - If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, - the search will be retried with a section type of EFI_SECTION_PE32. This function must be called with a TPL <= TPL_NOTIFY. If Buffer is NULL, then ASSERT(). @@ -338,8 +315,6 @@ GetSectionFromAnyFvByFileType ( See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from an FFS file based on SectionType and SectionInstance. - If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, - the search will be retried with a section type of EFI_SECTION_PE32. This function must be called with a TPL <= TPL_NOTIFY. If NameGuid is NULL, then ASSERT(). @@ -461,10 +436,6 @@ GetSectionFromAnyFv ( See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from an FFS file based on SectionType and SectionInstance. - If the currently executing module was not loaded from a firmware volume, then EFI_NOT_FOUND is returned. - If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, - the search will be retried with a section type of EFI_SECTION_PE32. - This function must be called with a TPL <= TPL_NOTIFY. If NameGuid is NULL, then ASSERT(). If Buffer is NULL, then ASSERT(). @@ -524,9 +495,6 @@ GetSectionFromFv ( to use FreePool() to free the allocated buffer. See EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection() for details on how sections are retrieved from an FFS file based on SectionType and SectionInstance. - If the currently executing module was not loaded from an FFS file, then EFI_NOT_FOUND is returned. - If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, - the search will be retried with a section type of EFI_SECTION_PE32. This function must be called with a TPL <= TPL_NOTIFY. If Buffer is NULL, then ASSERT(). @@ -951,8 +919,6 @@ GetFileBufferByFilePath ( The order that the firmware volumes is searched is not deterministic. For each FFS file found a search is made for FFS sections of type SectionType. - If SectionType is EFI_SECTION_TE, and the search with an FFS file fails, - the search will be retried with a section type of EFI_SECTION_PE32. This function must be called with a TPL <= TPL_NOTIFY. If NameGuid is NULL, then ASSERT(). diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 257841d492..24cd311483 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -2351,12 +2351,6 @@ # @Prompt Image Loader Alignment Policy. gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAlignmentPolicy|0xFFFFFFFF|UINT32|0x4000101E - ## Indicates whether TE Images are allowed.

- # TRUE - TE Images are forbidden.
- # FALSE - TE Images are allowed.
- # @Prompt Prohibit TE Images Loading. - gEfiMdePkgTokenSpaceGuid.PcdImageLoaderProhibitTe|FALSE|BOOLEAN|0x4000101F - ## Indicates whether PE32+ header offset is sufficiently aligned.

# TRUE - Execution Header offset may be not aligned.
# FALSE - Execution Header offset must be sufficiently aligned.
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c index ccd1e8e060..d2add7d6c4 100644 --- a/OvmfPkg/Sec/SecMain.c +++ b/OvmfPkg/Sec/SecMain.c @@ -503,16 +503,8 @@ FindPeiCoreImageBaseInFv ( &Section ); if (EFI_ERROR (Status)) { - Status = FindFfsFileAndSection ( - Fv, - EFI_FV_FILETYPE_PEI_CORE, - EFI_SECTION_TE, - &Section - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n")); - return Status; - } + DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n")); + return Status; } *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1); @@ -682,7 +674,7 @@ FindImageBase ( // // Look for executable sections // - if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) { + if (Section->Type == EFI_SECTION_PE32) { if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) { *SecCoreImageBase = (PHYSICAL_ADDRESS)(UINTN)(Section + 1); *SecCoreImageSize = Size - sizeof (*Section); diff --git a/PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c b/PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c index 15792777b7..5cc1867d40 100644 --- a/PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c +++ b/PrmPkg/Library/DxePrmPeCoffLib/DxePrmPeCoffLib.c @@ -205,7 +205,7 @@ GetExportDirectoryInPeCoffImage ( ); // - // Check the PE/COFF Header Signature. Determine if the image is valid and/or a TE image. + // Check the PE/COFF Header Signature. Determine if the image is valid image. // if (OptionalHeaderPtrUnion.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { DEBUG ((DEBUG_ERROR, "%a %a: The PE signature is not valid for the current image.\n", _DBGMSGID_, __func__)); @@ -330,7 +330,7 @@ GetImageVersionInPeCoffImage ( PeCoffLoaderImageContext->PeCoffHeaderOffset ); // - // Check the PE/COFF Header Signature. Determine if the image is valid and/or a TE image. + // Check the PE/COFF Header Signature. Determine if the image is valid image. // if (OptionalHeaderPtrUnion.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { DEBUG ((DEBUG_ERROR, "%a %a: The PE signature is not valid for the current image.\n", _DBGMSGID_, __func__)); diff --git a/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm b/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm index 904c22df2f..c65f5497e6 100644 --- a/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm @@ -109,7 +109,6 @@ secCoreEntryPointWasFound: OneTimeCallRet Flat32SearchForSecEntryPoint %define EFI_SECTION_PE32 0x10 -%define EFI_SECTION_TE 0x12 ; ; Input: @@ -134,9 +133,6 @@ getEntryPointOfFfsFileLoopForSections: cmp byte [eax + 3], EFI_SECTION_PE32 je getEntryPointOfFfsFileFoundPe32Section - cmp byte [eax + 3], EFI_SECTION_TE - je getEntryPointOfFfsFileFoundTeSection - ; ; The section type was not PE32 or TE, so move to next section ; @@ -170,22 +166,6 @@ getEntryPointOfFfsFileFoundPe32Section: add eax, [ebx + 0x4 + 0x14 + 0x10] jmp getEntryPointOfFfsFileReturn -getEntryPointOfFfsFileFoundTeSection: - add eax, 4 ; EAX = Start of TE image - mov ebx, eax - - ; if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) - cmp word [ebx], 'VZ' - jne getEntryPointOfFfsFileErrorReturn - ; *EntryPoint = (VOID *)((UINTN)Pe32Data + - ; (UINTN)(Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + - ; sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize); - add eax, [ebx + 0x8] - add eax, 0x28 - movzx ebx, word [ebx + 0x6] - sub eax, ebx - jmp getEntryPointOfFfsFileReturn - getEntryPointOfFfsFileErrorReturn: mov eax, 0 diff --git a/UefiCpuPkg/SecCore/FindPeiCore.c b/UefiCpuPkg/SecCore/FindPeiCore.c index 3187dcf60f..3cded940d3 100644 --- a/UefiCpuPkg/SecCore/FindPeiCore.c +++ b/UefiCpuPkg/SecCore/FindPeiCore.c @@ -107,7 +107,7 @@ FindImageBase ( // // Look for executable sections // - if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) { + if (Section->Type == EFI_SECTION_PE32) { if (File->Type == FileType) { if (IS_SECTION2 (Section)) { *CoreImageBase = (PHYSICAL_ADDRESS)(UINTN)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2)); From 544c7bdda8d32b65fe9a4d0a06a999622d37398f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Sat, 15 Apr 2023 19:57:36 +0200 Subject: [PATCH 065/341] BaseTools/build_rule: Drop deprecated ASM16 definition --- BaseTools/Conf/build_rule.template | 35 +------------------- BaseTools/Source/Python/build/BuildReport.py | 2 -- 2 files changed, 1 insertion(+), 36 deletions(-) diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template index 7a85d73e09..a18d3f58a4 100755 --- a/BaseTools/Conf/build_rule.template +++ b/BaseTools/Conf/build_rule.template @@ -548,39 +548,6 @@ "$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.dll $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.pecoff ImageTool GetAcpi -o ${dst} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.pecoff -[Masm16-Code-File] - - ?.asm16, ?.Asm16, ?.ASM16, ?.s16, ?.S16 - - - $(MAKE_FILE) - - - $(OUTPUT_DIR)(+)${s_base}.com - - - Trim --asm-file -o ${d_path}(+)${s_base}.i -i $(INC_LIST) ${src} - "$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii - Trim --source-code --convert-hex --trim-long -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.ii - cd $(OUTPUT_DIR)(+)${s_dir} - "$(ASM16)" /nologo /c /omf $(ASM16_FLAGS) $(INC) /Fo$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj ${d_path}(+)${s_base}.iii - "$(ASMLINK)" $(ASMLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj,${dst},,,, - - - Trim --asm-file -o {d_path}(+)${s_base}.i -i $(INC_LIST) ${src} - "$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii - Trim --source-code -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.ii - "$(ASM)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASM_FLAGS) $(INC) ${d_path}(+)${s_base}.iii - "$(DLINK)" -o ${dst} $(DLINK_FLAGS) --start-group $(DLINK_SPATH) $(LIBS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj --end-group - - - Trim --asm-file -o ${d_path}(+)${s_base}.i -i $(INC_LIST) ${src} - "$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii - Trim --source-code -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.ii - "$(ASM)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASM_FLAGS) $(INC) ${d_path}(+)${s_base}.iii - "$(SLINK)" $(SLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.slib $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj - otool -t $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.slib | hex2bin.py ${dst} - [Nasm-to-Binary-Code-File] @@ -597,7 +564,7 @@ "$(PP)" $(DEPS_FLAGS) $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.ii Trim --source-code --convert-hex -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.ii "$(NASM)" -I${s_path}(+) -l ${d_path}(+)${s_base}.lst $(NASMB_FLAGS) $(NASM_INC) -o $dst ${d_path}(+)${s_base}.iii - # copy the output file with .com postfix that be same to the output file of .asm16 + # copy the output file with .com postfix that be same to the output file of .nasmb $(CP) ${dst} $(OUTPUT_DIR)(+)${s_base}.com [Microcode-File.USER_DEFINED, Microcode-File.Microcode] diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py index b9a720d605..7ec6abdf18 100644 --- a/BaseTools/Source/Python/build/BuildReport.py +++ b/BaseTools/Source/Python/build/BuildReport.py @@ -508,8 +508,6 @@ def __init__(self, M): BuildOptions["ASLCC"] = 1 BuildOptions["ASLDLINK"] = 1 BuildOptions["CC"] = 1 - elif Ext in [".asm16"]: - BuildOptions["ASMLINK"] = 1 BuildOptions["SLINK"] = 1 BuildOptions["DLINK"] = 1 From 64ff005ed9e53842f01cd2c12a9b0ccb2a994d30 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 27 Feb 2025 14:12:27 +0300 Subject: [PATCH 066/341] Added STATUS.md file summarizing current states of packages. --- STATUS.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 STATUS.md diff --git a/STATUS.md b/STATUS.md new file mode 100644 index 0000000000..c0c25990ac --- /dev/null +++ b/STATUS.md @@ -0,0 +1,81 @@ +# Current states of packages + +| Name | Architectures | Targets | Compilable | Tested | +| :--- | :-----------: | :-----: | :--------: | :----: | +| $${\color{lightblue}ArmPkg/}$$ | +| ArmPkg.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF | ❌ | +| Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc | AARCH64 | DEBUG | ❓ | ❌ | +| $${\color{lightblue}ArmPlatformPkg/}$$ | +| ArmPlatformPkg.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF | ❌ | +| $${\color{lightblue}ArmVirtPkg/}$$ | +| ArmVirtCloudHv.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| ArmVirtKvmTool.dsc | ARM AARCH64 | DEBUG RELEASE | ❓ | ❌ | +| ArmVirtQemu.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF | ✔ | +| ArmVirtQemuKernel.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| ArmVirtXen.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| $${\color{lightblue}CryptoPkg/}$$ | +| CryptoPkg.dsc | IA32 X64 ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| Test/CryptoPkgHostUnitTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | +| $${\color{lightblue}DynamicTablesPkg/}$$ | +| DynamicTablesPkg.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| $${\color{lightblue}EmbeddedPkg/}$$ | +| EmbeddedPkg.dsc | IA32 X64 ARM AARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| $${\color{lightblue}EmulatorPkg/}$$ | +| EmulatorPkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| $${\color{lightblue}Ext4Pkg/}$$ | +| Ext4Pkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| $${\color{lightblue}FatPkg/}$$ | +| FatPkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| $${\color{lightblue}FmpDevicePkg/}$$ | +| FmpDevicePkg.dsc | IA32 X64 ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| Test/FmpDeviceHostPkgTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | +| $${\color{lightblue}IntelFsp2Pkg/}$$ | +| IntelFsp2Pkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| Tools/Tests/QemuFspPkg.dsc | IA32 X64 | DEBUG RELEASE | ❓ | ❌ | +| $${\color{lightblue}IntelFsp2WrapperPkg/}$$ | +| IntelFsp2WrapperPkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| $${\color{lightblue}MdeModulePkg/}$$ | +| MdeModulePkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| Test/MdeModulePkgHostTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | +| $${\color{lightblue}MdePkg/}$$ | +| MdePkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| Test/MdePkgHostTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | +| $${\color{lightblue}NetworkPkg/}$$ | +| NetworkPkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| $${\color{lightblue}OvmfPkg/}$$ | +| OvmfPkgIa32.dsc | IA32 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ✔ | +| OvmfPkgIa32X64.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ✔ | +| OvmfPkgX64.dsc | X64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ✔ | +| OvmfXen.dsc | X64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| AmdSev/AmdSevX64.dsc | X64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| Bhyve/BhyveX64.dsc | X64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| CloudHv/CloudHvX64.dsc | X64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| IntelTdx/IntelTdxX64.dsc | X64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| Microvm/MicrovmX64.dsc | X64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| RiscVVirt/RiscVVirtQemu.dsc | RISCV64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| $${\color{lightblue}PcAtChipsetPkg/}$$ | +| PcAtChipsetPkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| $${\color{lightblue}PrmPkg/}$$ | +| PrmPkg.dsc | IA32 X64 AARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| Test/PrmPkgHostTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | +| $${\color{lightblue}RedfishPkg/}$$ | +| RedfishPkg.dsc | IA32 X64 ARM AARCH64 RISCV64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| $${\color{lightblue}SecurityPkg/}$$ | +| SecurityPkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| Test/SecurityPkgHostTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | +| $${\color{lightblue}ShellPkg/}$$ | +| ShellPkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| $${\color{lightblue}SignedCapsulePkg/}$$ | +| SignedCapsulePkg.dsc | IA32 X64 ARM AARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| $${\color{lightblue}SourceLevelDebugPkg/}$$ | +| SourceLevelDebugPkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| $${\color{lightblue}StandaloneMmPkg/}$$ | +| StandaloneMmPkg.dsc | X64 ARM AARCH64 | DEBUG RELEASE | ❓ | ❌ | +| $${\color{lightblue}UefiCpuPkg/}$$ | +| UefiCpuPkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| Test/UefiCpuPkgHostTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | +| $${\color{lightblue}UefiPayloadPkg/}$$ | +| UefiPayloadPkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| $${\color{lightblue}UnitTestFrameworkPkg/}$$ | +| UnitTestFrameworkPkg.dsc | IA32 X64 ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| Test/UnitTestFrameworkPkgHostTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | From f7146c7ae7f6671a66494bbb6ead65203c24f4d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Sat, 22 Apr 2023 01:40:42 +0200 Subject: [PATCH 067/341] Remove hacks related to former lack of XCODE5 .hii support --- EmulatorPkg/EmulatorPkg.dsc | 4 ---- EmulatorPkg/EmulatorPkg.fdf | 4 ---- MdeModulePkg/MdeModulePkg.dsc | 2 -- OvmfPkg/Include/Dsc/ShellComponents.dsc.inc | 2 -- OvmfPkg/Include/Fdf/ShellDxe.fdf.inc | 2 -- 5 files changed, 14 deletions(-) diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc index c6cf430605..f9c09b1f2c 100644 --- a/EmulatorPkg/EmulatorPkg.dsc +++ b/EmulatorPkg/EmulatorPkg.dsc @@ -433,9 +433,7 @@ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf MdeModulePkg/Universal/BdsDxe/BdsDxe.inf -!if "XCODE5" not in $(TOOL_CHAIN_TAG) MdeModulePkg/Logo/LogoDxe.inf -!endif MdeModulePkg/Universal/LoadFileOnFv2/LoadFileOnFv2.inf MdeModulePkg/Application/UiApp/UiApp.inf { @@ -478,12 +476,10 @@ FatPkg/EnhancedFatDxe/Fat.inf -!if "XCODE5" not in $(TOOL_CHAIN_TAG) ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf { gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE } -!endif ShellPkg/Application/Shell/Shell.inf { ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf diff --git a/EmulatorPkg/EmulatorPkg.fdf b/EmulatorPkg/EmulatorPkg.fdf index 73d5b0068d..f1e81654e1 100644 --- a/EmulatorPkg/EmulatorPkg.fdf +++ b/EmulatorPkg/EmulatorPkg.fdf @@ -185,9 +185,7 @@ INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf INF MdeModulePkg/Universal/PrintDxe/PrintDxe.inf INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf -!if "XCODE5" not in $(TOOL_CHAIN_TAG) INF MdeModulePkg/Logo/LogoDxe.inf -!endif INF MdeModulePkg/Universal/LoadFileOnFv2/LoadFileOnFv2.inf INF RuleOverride = UI MdeModulePkg/Application/UiApp/UiApp.inf INF MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf @@ -225,9 +223,7 @@ INF EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf INF FatPkg/EnhancedFatDxe/Fat.inf -!if "XCODE5" not in $(TOOL_CHAIN_TAG) INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf -!endif INF ShellPkg/Application/Shell/Shell.inf [Rule.Common.SEC] diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 08c2530d11..2e9fe859ad 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -466,10 +466,8 @@ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf } -!if $(TOOL_CHAIN_TAG) != "XCODE5" MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteStandaloneMm.inf MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf -!endif [Components.IA32, Components.X64] MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf diff --git a/OvmfPkg/Include/Dsc/ShellComponents.dsc.inc b/OvmfPkg/Include/Dsc/ShellComponents.dsc.inc index e8f4f42b33..1786da7cd3 100644 --- a/OvmfPkg/Include/Dsc/ShellComponents.dsc.inc +++ b/OvmfPkg/Include/Dsc/ShellComponents.dsc.inc @@ -4,7 +4,6 @@ !if $(BUILD_SHELL) == TRUE -!if $(TOOL_CHAIN_TAG) != "XCODE5" !if $(NETWORK_ENABLE) == TRUE ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf { @@ -23,7 +22,6 @@ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE } -!endif ShellPkg/Application/Shell/Shell.inf { diff --git a/OvmfPkg/Include/Fdf/ShellDxe.fdf.inc b/OvmfPkg/Include/Fdf/ShellDxe.fdf.inc index eef89be88e..4bb34d57ab 100644 --- a/OvmfPkg/Include/Fdf/ShellDxe.fdf.inc +++ b/OvmfPkg/Include/Fdf/ShellDxe.fdf.inc @@ -8,14 +8,12 @@ # !if $(BUILD_SHELL) == TRUE && $(SECURE_BOOT_ENABLE) == FALSE -!if $(TOOL_CHAIN_TAG) != "XCODE5" !if $(NETWORK_ENABLE) == TRUE INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf INF ShellPkg/DynamicCommand/HttpDynamicCommand/HttpDynamicCommand.inf !endif INF ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicyDynamicCommand.inf INF OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf -!endif INF ShellPkg/Application/Shell/Shell.inf !endif From 4c392eb10447e3b9f09e26642d149db7ea77e695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Tue, 21 Mar 2023 20:02:55 +0100 Subject: [PATCH 068/341] BaseTools/GenFv: Remove .text and .data from FV map --- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 27 +-------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 6e162fccd6..d5de8f732c 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -764,14 +764,10 @@ Routine Description: EFI_PHYSICAL_ADDRESS FunctionAddress; UINT32 FunctionType; CHAR8 FunctionTypeName [MAX_LINE_LEN]; - UINT32 Index; UINT32 AddressOfEntryPoint; UINT32 Offset; EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - EFI_IMAGE_SECTION_HEADER *SectionHeader; long long TempLongAddress; - UINT32 TextVirtualAddress; - UINT32 DataVirtualAddress; EFI_PHYSICAL_ADDRESS LinkTimeBaseAddress; BOOLEAN IsUseClang; @@ -843,13 +839,6 @@ Routine Description: ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINT8 *) pImageContext->Handle + pImageContext->PeCoffHeaderOffset); AddressOfEntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint; Offset = 0; - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( - (UINT8 *) ImgHdr + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - Index = ImgHdr->Pe32.FileHeader.NumberOfSections; // // module information output @@ -866,21 +855,7 @@ Routine Description: fprintf (FvMapFile, "Type=PE"); fprintf (FvMapFile, ")\n"); - fprintf (FvMapFile, "(GUID=%s", FileGuidName); - TextVirtualAddress = 0; - DataVirtualAddress = 0; - for (; Index > 0; Index --, SectionHeader ++) { - if (stricmp ((CHAR8 *)SectionHeader->Name, ".text") == 0) { - TextVirtualAddress = SectionHeader->VirtualAddress; - } else if (stricmp ((CHAR8 *)SectionHeader->Name, ".data") == 0) { - DataVirtualAddress = SectionHeader->VirtualAddress; - } else if (stricmp ((CHAR8 *)SectionHeader->Name, ".sdata") == 0) { - DataVirtualAddress = SectionHeader->VirtualAddress; - } - } - fprintf (FvMapFile, " .textbaseaddress=0x%010llx", (unsigned long long) (ImageBaseAddress + TextVirtualAddress)); - fprintf (FvMapFile, " .databaseaddress=0x%010llx", (unsigned long long) (ImageBaseAddress + DataVirtualAddress)); - fprintf (FvMapFile, ")\n\n"); + fprintf (FvMapFile, "(GUID=%s)\n\n", FileGuidName); // // Open PeMapFile From 54c0f644f9d8d0f1d979dc52a4139c000f321f7f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 15 Dec 2023 15:07:47 +0300 Subject: [PATCH 069/341] BaseTools/C: Consume UefiImageLib and ImageToolEmit --- BaseTools/ImageTool/BinEmit.c | 3 + BaseTools/ImageTool/ElfScan.c | 15 +- BaseTools/Source/C/Common/BasePeCoff.c | 1417 ----------------- BaseTools/Source/C/Common/CommonLib.c | 66 + BaseTools/Source/C/Common/CommonLib.h | 6 + BaseTools/Source/C/Common/GNUmakefile | 40 +- BaseTools/Source/C/Common/Makefile | 40 +- BaseTools/Source/C/Common/PeCoffLib.h | 213 --- BaseTools/Source/C/Common/PeCoffLoaderEx.c | 385 ----- BaseTools/Source/C/EfiRom/EfiRom.c | 132 +- BaseTools/Source/C/EfiRom/EfiRom.h | 13 +- BaseTools/Source/C/GenFfs/GenFfs.c | 100 -- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 573 +++---- BaseTools/Source/C/GenFv/GenFvInternalLib.h | 6 +- BaseTools/Source/C/GenSec/GenSec.c | 100 -- BaseTools/Source/C/Include/Common/AutoGen.h | 272 ++-- BaseTools/Source/C/Include/Common/PeImageEx.h | 59 - BaseTools/Source/C/Makefiles/header.makefile | 2 +- BaseTools/Source/C/Makefiles/ms.common | 2 +- BaseTools/Source/C/Makefiles/ms.rule | 24 + BaseTools/Source/C/VolInfo/VolInfo.c | 269 +--- 21 files changed, 701 insertions(+), 3036 deletions(-) delete mode 100644 BaseTools/Source/C/Common/BasePeCoff.c delete mode 100644 BaseTools/Source/C/Common/PeCoffLib.h delete mode 100644 BaseTools/Source/C/Common/PeCoffLoaderEx.c delete mode 100644 BaseTools/Source/C/Include/Common/PeImageEx.h diff --git a/BaseTools/ImageTool/BinEmit.c b/BaseTools/ImageTool/BinEmit.c index 51fbb6f5a7..828c357a7a 100644 --- a/BaseTools/ImageTool/BinEmit.c +++ b/BaseTools/ImageTool/BinEmit.c @@ -5,6 +5,9 @@ #include "ImageTool.h" +#include +#include + static EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY * CreateEntry ( diff --git a/BaseTools/ImageTool/ElfScan.c b/BaseTools/ImageTool/ElfScan.c index ca2a1010b2..60fd9184b5 100644 --- a/BaseTools/ImageTool/ElfScan.c +++ b/BaseTools/ImageTool/ElfScan.c @@ -52,13 +52,6 @@ typedef struct { bool HasPieRelocs; } tool_elf_scan_context; -#if defined (_MSC_EXTENSIONS) -#define EFI_IMAGE_MACHINE_IA32 0x014C -#define EFI_IMAGE_MACHINE_X64 0x8664 -#define EFI_IMAGE_MACHINE_ARMTHUMB_MIXED 0x01C2 -#define EFI_IMAGE_MACHINE_AARCH64 0xAA64 -#endif - #define GetShrbyIndex ELF_SUFFIX(GetShrbyIndex) static @@ -687,17 +680,17 @@ ScanElf ( switch (Ehdr->e_machine) { #if ELF_ARCH == 64 case EM_X86_64: - ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_X64; + ImageInfo->HeaderInfo.Machine = IMAGE_FILE_MACHINE_X64; break; case EM_AARCH64: - ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_AARCH64; + ImageInfo->HeaderInfo.Machine = IMAGE_FILE_MACHINE_ARM64; break; #elif ELF_ARCH == 32 case EM_386: - ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_IA32; + ImageInfo->HeaderInfo.Machine = IMAGE_FILE_MACHINE_I386; break; case EM_ARM: - ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_ARMTHUMB_MIXED; + ImageInfo->HeaderInfo.Machine = IMAGE_FILE_MACHINE_ARMTHUMB_MIXED; break; #endif default: diff --git a/BaseTools/Source/C/Common/BasePeCoff.c b/BaseTools/Source/C/Common/BasePeCoff.c deleted file mode 100644 index c38180af69..0000000000 --- a/BaseTools/Source/C/Common/BasePeCoff.c +++ /dev/null @@ -1,1417 +0,0 @@ -/** @file - - Functions to get info and load PE/COFF image. - -Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
-Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
-Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
-Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include -#include -#include "PeCoffLib.h" - -typedef union { - VOID *Header; - EFI_IMAGE_OPTIONAL_HEADER32 *Optional32; - EFI_IMAGE_OPTIONAL_HEADER64 *Optional64; -} EFI_IMAGE_OPTIONAL_HEADER_POINTER; - -STATIC -RETURN_STATUS -PeCoffLoaderGetPeHeader ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - OUT EFI_IMAGE_OPTIONAL_HEADER_UNION **PeHdr, - OUT EFI_TE_IMAGE_HEADER **TeHdr - ); - -STATIC -RETURN_STATUS -PeCoffLoaderCheckImageType ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr, - IN EFI_TE_IMAGE_HEADER *TeHdr - ); - -STATIC -VOID * -PeCoffLoaderImageAddress ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN UINTN Address - ); - -RETURN_STATUS -PeCoffLoaderRelocateIa32Image ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ); - - -RETURN_STATUS -PeCoffLoaderRelocateArmImage ( - IN UINT16 **Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ); - -RETURN_STATUS -PeCoffLoaderRelocateRiscVImage ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ); - -RETURN_STATUS -PeCoffLoaderRelocateLoongArch64Image ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ); - -/** - Retrieves the PE or TE Header from a PE/COFF or TE image - - @param ImageContext The context of the image being loaded - @param PeHdr The buffer in which to return the PE header - @param TeHdr The buffer in which to return the TE header - - @return RETURN_SUCCESS if the PE or TE Header is read, - Otherwise, the error status from reading the PE/COFF or TE image using the ImageRead function. -**/ -STATIC -RETURN_STATUS -PeCoffLoaderGetPeHeader ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - OUT EFI_IMAGE_OPTIONAL_HEADER_UNION **PeHdr, - OUT EFI_TE_IMAGE_HEADER **TeHdr - ) -{ - RETURN_STATUS Status; - EFI_IMAGE_DOS_HEADER DosHdr; - UINTN Size; - - ImageContext->IsTeImage = FALSE; - // - // Read the DOS image headers - // - Size = sizeof (EFI_IMAGE_DOS_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - 0, - &Size, - &DosHdr - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - ImageContext->PeCoffHeaderOffset = 0; - if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header - // - ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew; - } - // - // Get the PE/COFF Header pointer - // - *PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINTN)ImageContext->Handle + ImageContext->PeCoffHeaderOffset); - if ((*PeHdr)->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { - // - // Check the PE/COFF Header Signature. If not, then try to get a TE header - // - *TeHdr = (EFI_TE_IMAGE_HEADER *)*PeHdr; - if ((*TeHdr)->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) { - return RETURN_UNSUPPORTED; - } - ImageContext->IsTeImage = TRUE; - } - - return RETURN_SUCCESS; -} - -/** - Checks the PE or TE header of a PE/COFF or TE image to determine if it supported - - @param ImageContext The context of the image being loaded - @param PeHdr The buffer in which to return the PE header - @param TeHdr The buffer in which to return the TE header - - @retval RETURN_SUCCESS if the PE/COFF or TE image is supported - @retval RETURN_UNSUPPORTED of the PE/COFF or TE image is not supported. - -**/ -STATIC -RETURN_STATUS -PeCoffLoaderCheckImageType ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr, - IN EFI_TE_IMAGE_HEADER *TeHdr - ) -{ - // - // See if the machine type is supported. - // We support a native machine type (IA-32/Itanium-based) - // - if (ImageContext->IsTeImage == FALSE) { - ImageContext->Machine = PeHdr->Pe32.FileHeader.Machine; - } else { - ImageContext->Machine = TeHdr->Machine; - } - - if (ImageContext->Machine != IMAGE_FILE_MACHINE_I386 && \ - ImageContext->Machine != IMAGE_FILE_MACHINE_X64 && \ - ImageContext->Machine != IMAGE_FILE_MACHINE_ARMTHUMB_MIXED && \ - ImageContext->Machine != IMAGE_FILE_MACHINE_EBC && \ - ImageContext->Machine != IMAGE_FILE_MACHINE_ARM64 && \ - ImageContext->Machine != IMAGE_FILE_MACHINE_RISCV64 && \ - ImageContext->Machine != IMAGE_FILE_MACHINE_LOONGARCH64) { - // - // unsupported PeImage machine type - // - return RETURN_UNSUPPORTED; - } - - // - // See if the image type is supported. We support EFI Applications, - // EFI Boot Service Drivers, EFI Runtime Drivers and EFI SAL Drivers. - // - if (ImageContext->IsTeImage == FALSE) { - ImageContext->ImageType = PeHdr->Pe32.OptionalHeader.Subsystem; - } else { - ImageContext->ImageType = (UINT16) (TeHdr->Subsystem); - } - - if (ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION && \ - ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER && \ - ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER && \ - ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) { - // - // unsupported PeImage subsystem type - // - return RETURN_UNSUPPORTED; - } - - return RETURN_SUCCESS; -} - -/** - Retrieves information on a PE/COFF image - - @param This Calling context - @param ImageContext The context of the image being loaded - - @retval RETURN_SUCCESS The information on the PE/COFF image was collected. - @retval RETURN_INVALID_PARAMETER ImageContext is NULL. - @retval RETURN_UNSUPPORTED The PE/COFF image is not supported. - @retval Otherwise The error status from reading the PE/COFF image using the - ImageContext->ImageRead() function - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderGetImageInfo ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -{ - RETURN_STATUS Status; - EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr; - EFI_TE_IMAGE_HEADER *TeHdr; - EFI_IMAGE_DATA_DIRECTORY *DebugDirectoryEntry; - UINTN Size; - UINTN Index; - UINTN DebugDirectoryEntryRva; - UINTN DebugDirectoryEntryFileOffset; - UINTN SectionHeaderOffset; - EFI_IMAGE_SECTION_HEADER SectionHeader; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry; - EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader; - - PeHdr = NULL; - TeHdr = NULL; - DebugDirectoryEntry = NULL; - DebugDirectoryEntryRva = 0; - - if (NULL == ImageContext) { - return RETURN_INVALID_PARAMETER; - } - // - // Assume success - // - ImageContext->ImageError = IMAGE_ERROR_SUCCESS; - - Status = PeCoffLoaderGetPeHeader (ImageContext, &PeHdr, &TeHdr); - if (RETURN_ERROR (Status)) { - return Status; - } - - // - // Verify machine type - // - Status = PeCoffLoaderCheckImageType (ImageContext, PeHdr, TeHdr); - if (RETURN_ERROR (Status)) { - return Status; - } - OptionHeader.Header = (VOID *) &(PeHdr->Pe32.OptionalHeader); - - // - // Retrieve the base address of the image - // - if (!(ImageContext->IsTeImage)) { - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - ImageContext->ImageAddress = (PHYSICAL_ADDRESS) OptionHeader.Optional32->ImageBase; - } else { - ImageContext->ImageAddress = (PHYSICAL_ADDRESS) OptionHeader.Optional64->ImageBase; - } - } else { - ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr->ImageBase + TeHdr->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER)); - } - // - // Initialize the alternate destination address to 0 indicating that it - // should not be used. - // - ImageContext->DestinationAddress = 0; - - // - // Initialize the codeview pointer. - // - ImageContext->CodeView = NULL; - ImageContext->PdbPointer = NULL; - - // - // Three cases with regards to relocations: - // - Image has base relocs, RELOCS_STRIPPED==0 => image is relocatable - // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable - // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but - // has no base relocs to apply - // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid. - // - // Look at the file header to determine if relocations have been stripped, and - // save this info in the image context for later use. - // - if ((!(ImageContext->IsTeImage)) && ((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) { - ImageContext->RelocationsStripped = TRUE; - } else if ((ImageContext->IsTeImage) && (TeHdr->DataDirectory[0].Size == 0) && (TeHdr->DataDirectory[0].VirtualAddress == 0)) { - ImageContext->RelocationsStripped = TRUE; - } else { - ImageContext->RelocationsStripped = FALSE; - } - - if (!(ImageContext->IsTeImage)) { - - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - ImageContext->ImageSize = (UINT64) OptionHeader.Optional32->SizeOfImage; - ImageContext->SectionAlignment = OptionHeader.Optional32->SectionAlignment; - ImageContext->SizeOfHeaders = OptionHeader.Optional32->SizeOfHeaders; - - // - // Modify ImageSize to contain .PDB file name if required and initialize - // PdbRVA field... - // - if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { - DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress; - } - } else { - ImageContext->ImageSize = (UINT64) OptionHeader.Optional64->SizeOfImage; - ImageContext->SectionAlignment = OptionHeader.Optional64->SectionAlignment; - ImageContext->SizeOfHeaders = OptionHeader.Optional64->SizeOfHeaders; - - // - // Modify ImageSize to contain .PDB file name if required and initialize - // PdbRVA field... - // - if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { - DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress; - } - } - - if (DebugDirectoryEntryRva != 0) { - // - // Determine the file offset of the debug directory... This means we walk - // the sections to find which section contains the RVA of the debug - // directory - // - DebugDirectoryEntryFileOffset = 0; - - SectionHeaderOffset = (UINTN)( - ImageContext->PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - PeHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - - for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) { - // - // Read section header from file - // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress && - DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) { - DebugDirectoryEntryFileOffset = - DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData; - break; - } - - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); - } - - if (DebugDirectoryEntryFileOffset != 0) { - for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) { - // - // Read next debug directory entry - // - Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - DebugDirectoryEntryFileOffset + Index, - &Size, - &DebugEntry - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { - ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index); - if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) { - ImageContext->ImageSize += DebugEntry.SizeOfData; - } - - return RETURN_SUCCESS; - } - } - } - } - } else { - ImageContext->ImageSize = 0; - ImageContext->SectionAlignment = 4096; - ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) TeHdr->BaseOfCode - (UINTN) TeHdr->StrippedSize; - - DebugDirectoryEntry = &TeHdr->DataDirectory[1]; - DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress; - SectionHeaderOffset = (UINTN) (sizeof (EFI_TE_IMAGE_HEADER)); - - DebugDirectoryEntryFileOffset = 0; - - for (Index = 0; Index < TeHdr->NumberOfSections;) { - // - // Read section header from file - // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress && - DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) { - DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva - - SectionHeader.VirtualAddress + - SectionHeader.PointerToRawData + - sizeof (EFI_TE_IMAGE_HEADER) - - TeHdr->StrippedSize; - - // - // File offset of the debug directory was found, if this is not the last - // section, then skip to the last section for calculating the image size. - // - if (Index < (UINTN) TeHdr->NumberOfSections - 1) { - SectionHeaderOffset += (TeHdr->NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER); - Index = TeHdr->NumberOfSections - 1; - continue; - } - } - - // - // In Te image header there is not a field to describe the ImageSize. - // Actually, the ImageSize equals the RVA plus the VirtualSize of - // the last section mapped into memory (Must be rounded up to - // a multiple of Section Alignment). Per the PE/COFF specification, the - // section headers in the Section Table must appear in order of the RVA - // values for the corresponding sections. So the ImageSize can be determined - // by the RVA and the VirtualSize of the last section header in the - // Section Table. - // - if ((++Index) == (UINTN) TeHdr->NumberOfSections) { - ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize + - ImageContext->SectionAlignment - 1) & ~(ImageContext->SectionAlignment - 1); - } - - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); - } - - if (DebugDirectoryEntryFileOffset != 0) { - for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) { - // - // Read next debug directory entry - // - Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - DebugDirectoryEntryFileOffset, - &Size, - &DebugEntry - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { - ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index); - return RETURN_SUCCESS; - } - } - } - } - - return RETURN_SUCCESS; -} - -/** - Converts an image address to the loaded address - - @param ImageContext The context of the image being loaded - @param Address The address to be converted to the loaded address - - @return NULL if the address can not be converted, otherwise, the converted address - ---*/ -STATIC -VOID * -PeCoffLoaderImageAddress ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN UINTN Address - ) -{ - if (Address >= ImageContext->ImageSize) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS; - return NULL; - } - - return (UINT8 *) ((UINTN) ImageContext->ImageAddress + Address); -} - -/** - Relocates a PE/COFF image in memory - - @param This Calling context - @param ImageContext Contains information on the loaded image to relocate - - @retval RETURN_SUCCESS if the PE/COFF image was relocated - @retval RETURN_LOAD_ERROR if the image is not a valid PE/COFF image - @retval RETURN_UNSUPPORTED not support - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderRelocateImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -{ - RETURN_STATUS Status; - EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr; - EFI_TE_IMAGE_HEADER *TeHdr; - EFI_IMAGE_DATA_DIRECTORY *RelocDir; - UINT64 Adjust; - EFI_IMAGE_BASE_RELOCATION *RelocBase; - EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd; - UINT16 *Reloc; - UINT16 *RelocEnd; - CHAR8 *Fixup; - CHAR8 *FixupBase; - UINT16 *F16; - UINT32 *F32; - UINT64 *F64; - CHAR8 *FixupData; - PHYSICAL_ADDRESS BaseAddress; - UINT16 MachineType; - EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader; - - PeHdr = NULL; - TeHdr = NULL; - // - // Assume success - // - ImageContext->ImageError = IMAGE_ERROR_SUCCESS; - - // - // If there are no relocation entries, then we are done - // - if (ImageContext->RelocationsStripped) { - return RETURN_SUCCESS; - } - - // - // Use DestinationAddress field of ImageContext as the relocation address even if it is 0. - // - BaseAddress = ImageContext->DestinationAddress; - - if (!(ImageContext->IsTeImage)) { - PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN)ImageContext->ImageAddress + - ImageContext->PeCoffHeaderOffset); - OptionHeader.Header = (VOID *) &(PeHdr->Pe32.OptionalHeader); - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - Adjust = (UINT64) BaseAddress - OptionHeader.Optional32->ImageBase; - OptionHeader.Optional32->ImageBase = (UINT32) BaseAddress; - MachineType = ImageContext->Machine; - // - // Find the relocation block - // - // Per the PE/COFF spec, you can't assume that a given data directory - // is present in the image. You have to check the NumberOfRvaAndSizes in - // the optional header to verify a desired directory entry is there. - // - if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - RelocDir = &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - if ((RelocDir != NULL) && (RelocDir->Size > 0)) { - RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress); - RelocBaseEnd = PeCoffLoaderImageAddress ( - ImageContext, - RelocDir->VirtualAddress + RelocDir->Size - 1 - ); - if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) { - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return RETURN_LOAD_ERROR; - } - } else { - // - // Set base and end to bypass processing below. - // - RelocBase = RelocBaseEnd = 0; - } - } else { - // - // Set base and end to bypass processing below. - // - RelocBase = RelocBaseEnd = 0; - } - } else { - Adjust = (UINT64) BaseAddress - OptionHeader.Optional64->ImageBase; - OptionHeader.Optional64->ImageBase = BaseAddress; - MachineType = ImageContext->Machine; - // - // Find the relocation block - // - // Per the PE/COFF spec, you can't assume that a given data directory - // is present in the image. You have to check the NumberOfRvaAndSizes in - // the optional header to verify a desired directory entry is there. - // - if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - RelocDir = &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - if ((RelocDir != NULL) && (RelocDir->Size > 0)) { - RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress); - RelocBaseEnd = PeCoffLoaderImageAddress ( - ImageContext, - RelocDir->VirtualAddress + RelocDir->Size - 1 - ); - if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) { - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return RETURN_LOAD_ERROR; - } - } else { - // - // Set base and end to bypass processing below. - // - RelocBase = RelocBaseEnd = 0; - } - } else { - // - // Set base and end to bypass processing below. - // - RelocBase = RelocBaseEnd = 0; - } - } - } else { - TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress); - Adjust = (UINT64) (BaseAddress - TeHdr->ImageBase); - TeHdr->ImageBase = (UINT64) (BaseAddress); - MachineType = TeHdr->Machine; - - // - // Find the relocation block - // - RelocDir = &TeHdr->DataDirectory[0]; - RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)( - ImageContext->ImageAddress + - RelocDir->VirtualAddress + - sizeof(EFI_TE_IMAGE_HEADER) - - TeHdr->StrippedSize - ); - RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1); - } - - // - // Run the relocation information and apply the fixups - // - FixupData = ImageContext->FixupData; - while (RelocBase < RelocBaseEnd) { - - Reloc = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION)); - RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock); - if (!(ImageContext->IsTeImage)) { - FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress); - if (FixupBase == NULL) { - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return RETURN_LOAD_ERROR; - } - } else { - FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress + - RelocBase->VirtualAddress + - sizeof(EFI_TE_IMAGE_HEADER) - - TeHdr->StrippedSize - ); - } - - if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) || - (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + - (UINTN)ImageContext->ImageSize)) { - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return RETURN_LOAD_ERROR; - } - - // - // Run this relocation record - // - while (Reloc < RelocEnd) { - - Fixup = FixupBase + (*Reloc & 0xFFF); - switch ((*Reloc) >> 12) { - case EFI_IMAGE_REL_BASED_ABSOLUTE: - break; - - case EFI_IMAGE_REL_BASED_HIGH: - F16 = (UINT16 *) Fixup; - *F16 = (UINT16) (*F16 + ((UINT16) ((UINT32) Adjust >> 16))); - if (FixupData != NULL) { - *(UINT16 *) FixupData = *F16; - FixupData = FixupData + sizeof (UINT16); - } - break; - - case EFI_IMAGE_REL_BASED_LOW: - F16 = (UINT16 *) Fixup; - *F16 = (UINT16) (*F16 + (UINT16) Adjust); - if (FixupData != NULL) { - *(UINT16 *) FixupData = *F16; - FixupData = FixupData + sizeof (UINT16); - } - break; - - case EFI_IMAGE_REL_BASED_HIGHLOW: - F32 = (UINT32 *) Fixup; - *F32 = *F32 + (UINT32) Adjust; - if (FixupData != NULL) { - FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32)); - *(UINT32 *) FixupData = *F32; - FixupData = FixupData + sizeof (UINT32); - } - break; - - case EFI_IMAGE_REL_BASED_DIR64: - F64 = (UINT64 *) Fixup; - *F64 = *F64 + (UINT64) Adjust; - if (FixupData != NULL) { - FixupData = ALIGN_POINTER (FixupData, sizeof (UINT64)); - *(UINT64 *) FixupData = *F64; - FixupData = FixupData + sizeof (UINT64); - } - break; - - case EFI_IMAGE_REL_BASED_HIGHADJ: - // - // Return the same EFI_UNSUPPORTED return code as - // PeCoffLoaderRelocateImageEx() returns if it does not recognize - // the relocation type. - // - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return RETURN_UNSUPPORTED; - - default: - switch (MachineType) { - case IMAGE_FILE_MACHINE_I386: - Status = PeCoffLoaderRelocateIa32Image (Reloc, Fixup, &FixupData, Adjust); - break; - case IMAGE_FILE_MACHINE_ARMTHUMB_MIXED: - Status = PeCoffLoaderRelocateArmImage (&Reloc, Fixup, &FixupData, Adjust); - break; - case IMAGE_FILE_MACHINE_RISCV64: - Status = PeCoffLoaderRelocateRiscVImage (Reloc, Fixup, &FixupData, Adjust); - break; - case IMAGE_FILE_MACHINE_LOONGARCH64: - Status = PeCoffLoaderRelocateLoongArch64Image (Reloc, Fixup, &FixupData, Adjust); - break; - default: - Status = RETURN_UNSUPPORTED; - break; - } - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return Status; - } - } - - // - // Next relocation record - // - Reloc += 1; - } - - // - // Next reloc block - // - RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd; - } - - return RETURN_SUCCESS; -} - -/** - Loads a PE/COFF image into memory - - @param This Calling context - @param ImageContext Contains information on image to load into memory - - @retval RETURN_SUCCESS if the PE/COFF image was loaded - @retval RETURN_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer - @retval RETURN_LOAD_ERROR if the image is a runtime driver with no relocations - @retval RETURN_INVALID_PARAMETER if the image address is invalid - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderLoadImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -{ - RETURN_STATUS Status; - EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr; - EFI_TE_IMAGE_HEADER *TeHdr; - PE_COFF_LOADER_IMAGE_CONTEXT CheckContext; - EFI_IMAGE_SECTION_HEADER *FirstSection; - EFI_IMAGE_SECTION_HEADER *Section; - UINTN NumberOfSections; - UINTN Index; - CHAR8 *Base; - CHAR8 *End; - CHAR8 *MaxEnd; - EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; - UINTN Size; - UINT32 TempDebugEntryRva; - EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader; - - PeHdr = NULL; - TeHdr = NULL; - OptionHeader.Header = NULL; - // - // Assume success - // - ImageContext->ImageError = IMAGE_ERROR_SUCCESS; - - // - // Copy the provided context info into our local version, get what we - // can from the original image, and then use that to make sure everything - // is legit. - // - CopyMem (&CheckContext, ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); - - Status = PeCoffLoaderGetImageInfo (&CheckContext); - if (RETURN_ERROR (Status)) { - return Status; - } - - // - // Make sure there is enough allocated space for the image being loaded - // - if (ImageContext->ImageSize < CheckContext.ImageSize) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE; - return RETURN_BUFFER_TOO_SMALL; - } - - // - // If there's no relocations, then make sure it's not a runtime driver, - // and that it's being loaded at the linked address. - // - if (CheckContext.RelocationsStripped) { - // - // If the image does not contain relocations and it is a runtime driver - // then return an error. - // - if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM; - return RETURN_LOAD_ERROR; - } - // - // If the image does not contain relocations, and the requested load address - // is not the linked address, then return an error. - // - if (CheckContext.ImageAddress != ImageContext->ImageAddress) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS; - return RETURN_INVALID_PARAMETER; - } - } - // - // Make sure the allocated space has the proper section alignment - // - if (!(ImageContext->IsTeImage)) { - if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT; - return RETURN_INVALID_PARAMETER; - } - } - // - // Read the entire PE/COFF or TE header into memory - // - if (!(ImageContext->IsTeImage)) { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - 0, - &ImageContext->SizeOfHeaders, - (VOID *) (UINTN) ImageContext->ImageAddress - ); - - PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) - ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset); - - OptionHeader.Header = (VOID *) &(PeHdr->Pe32.OptionalHeader); - - FirstSection = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN)ImageContext->ImageAddress + - ImageContext->PeCoffHeaderOffset + - sizeof(UINT32) + - sizeof(EFI_IMAGE_FILE_HEADER) + - PeHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - NumberOfSections = (UINTN) (PeHdr->Pe32.FileHeader.NumberOfSections); - } else { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - 0, - &ImageContext->SizeOfHeaders, - (VOID *) (UINTN) ImageContext->ImageAddress - ); - - TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress); - - FirstSection = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN)ImageContext->ImageAddress + - sizeof(EFI_TE_IMAGE_HEADER) - ); - NumberOfSections = (UINTN) (TeHdr->NumberOfSections); - - } - - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return RETURN_LOAD_ERROR; - } - - // - // Load each section of the image - // - Section = FirstSection; - for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) { - - // - // Compute sections address - // - Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress); - End = PeCoffLoaderImageAddress ( - ImageContext, - Section->VirtualAddress + Section->Misc.VirtualSize - 1 - ); - - // - // If the base start or end address resolved to 0, then fail. - // - if ((Base == NULL) || (End == NULL)) { - ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED; - return RETURN_LOAD_ERROR; - } - - - if (ImageContext->IsTeImage) { - Base = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize); - End = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize); - } - - if (End > MaxEnd) { - MaxEnd = End; - } - - // - // Read the section - // - Size = (UINTN) Section->Misc.VirtualSize; - if ((Size == 0) || (Size > Section->SizeOfRawData)) { - Size = (UINTN) Section->SizeOfRawData; - } - - if (Section->SizeOfRawData) { - if (!(ImageContext->IsTeImage)) { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - Section->PointerToRawData, - &Size, - Base - ); - } else { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize, - &Size, - Base - ); - } - - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - } - - // - // If raw size is less then virt size, zero fill the remaining - // - - if (Size < Section->Misc.VirtualSize) { - ZeroMem (Base + Size, Section->Misc.VirtualSize - Size); - } - - // - // Next Section - // - Section += 1; - } - - // - // Get image's entry point - // - if (!(ImageContext->IsTeImage)) { - ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress ( - ImageContext, - PeHdr->Pe32.OptionalHeader.AddressOfEntryPoint - ); - } else { - ImageContext->EntryPoint = (UINTN)ImageContext->ImageAddress + - (UINTN)TeHdr->AddressOfEntryPoint + - (UINTN)sizeof(EFI_TE_IMAGE_HEADER) - - (UINTN) TeHdr->StrippedSize; - } - - // - // Determine the size of the fixup data - // - // Per the PE/COFF spec, you can't assume that a given data directory - // is present in the image. You have to check the NumberOfRvaAndSizes in - // the optional header to verify a desired directory entry is there. - // - if (!(ImageContext->IsTeImage)) { - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) - &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN); - } else { - ImageContext->FixupDataSize = 0; - } - } else { - if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) - &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN); - } else { - ImageContext->FixupDataSize = 0; - } - } - } else { - DirectoryEntry = &TeHdr->DataDirectory[0]; - ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN); - } - // - // Consumer must allocate a buffer for the relocation fixup log. - // Only used for runtime drivers. - // - ImageContext->FixupData = NULL; - - // - // Load the Codeview info if present - // - if (ImageContext->DebugDirectoryEntryRva != 0) { - if (!(ImageContext->IsTeImage)) { - DebugEntry = PeCoffLoaderImageAddress ( - ImageContext, - ImageContext->DebugDirectoryEntryRva - ); - } else { - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)( - ImageContext->ImageAddress + - ImageContext->DebugDirectoryEntryRva + - sizeof(EFI_TE_IMAGE_HEADER) - - TeHdr->StrippedSize - ); - } - - if (DebugEntry != NULL) { - TempDebugEntryRva = DebugEntry->RVA; - if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) { - Section--; - if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) { - TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize; - } else { - TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData; - } - } - - if (TempDebugEntryRva != 0) { - if (!(ImageContext->IsTeImage)) { - ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva); - } else { - ImageContext->CodeView = (VOID *)( - (UINTN)ImageContext->ImageAddress + - (UINTN)TempDebugEntryRva + - (UINTN)sizeof(EFI_TE_IMAGE_HEADER) - - (UINTN) TeHdr->StrippedSize - ); - } - - if (ImageContext->CodeView == NULL) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return RETURN_LOAD_ERROR; - } - - if (DebugEntry->RVA == 0) { - Size = DebugEntry->SizeOfData; - if (!(ImageContext->IsTeImage)) { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - DebugEntry->FileOffset, - &Size, - ImageContext->CodeView - ); - } else { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - TeHdr->StrippedSize, - &Size, - ImageContext->CodeView - ); - // - // Should we apply fix up to this field according to the size difference between PE and TE? - // Because now we maintain TE header fields unfixed, this field will also remain as they are - // in original PE image. - // - } - - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return RETURN_LOAD_ERROR; - } - - DebugEntry->RVA = TempDebugEntryRva; - } - - switch (*(UINT32 *) ImageContext->CodeView) { - case CODEVIEW_SIGNATURE_NB10: - ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY); - break; - - case CODEVIEW_SIGNATURE_RSDS: - ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY); - break; - - case CODEVIEW_SIGNATURE_MTOC: - ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY); - - default: - break; - } - } - } - } - - return Status; -} - -/** - Returns a pointer to the PDB file name for a raw PE/COFF image that is not - loaded into system memory with the PE/COFF Loader Library functions. - - Returns the PDB file name for the PE/COFF image specified by Pe32Data. If - the PE/COFF image specified by Pe32Data is not a valid, then NULL is - returned. If the PE/COFF image specified by Pe32Data does not contain a - debug directory entry, then NULL is returned. If the debug directory entry - in the PE/COFF image specified by Pe32Data does not contain a PDB file name, - then NULL is returned. - If Pe32Data is NULL, then return NULL. - - @param Pe32Data Pointer to the PE/COFF image that is loaded in system - memory. - - @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL - if it cannot be retrieved. - -**/ -VOID * -EFIAPI -PeCoffLoaderGetPdbPointer ( - IN VOID *Pe32Data - ) -{ - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; - UINTN DirCount; - VOID *CodeViewEntryPointer; - INTN TEImageAdjust; - UINT32 NumberOfRvaAndSizes; - UINT16 Magic; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - UINT32 Index, Index1; - - if (Pe32Data == NULL) { - return NULL; - } - - TEImageAdjust = 0; - DirectoryEntry = NULL; - DebugEntry = NULL; - NumberOfRvaAndSizes = 0; - Index = 0; - Index1 = 0; - SectionHeader = NULL; - - DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (EFI_IMAGE_DOS_SIGNATURE == DosHdr->e_magic) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; - } - - if (EFI_TE_IMAGE_HEADER_SIGNATURE == Hdr.Te->Signature) { - if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) { - DirectoryEntry = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG]; - TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize; - - // - // Get the DebugEntry offset in the raw data image. - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (Hdr.Te + 1); - Index = Hdr.Te->NumberOfSections; - for (Index1 = 0; Index1 < Index; Index1 ++) { - if ((DirectoryEntry->VirtualAddress >= SectionHeader[Index1].VirtualAddress) && - (DirectoryEntry->VirtualAddress < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) { - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te + - DirectoryEntry->VirtualAddress - - SectionHeader [Index1].VirtualAddress + - SectionHeader [Index1].PointerToRawData + - TEImageAdjust); - break; - } - } - } - } else if (EFI_IMAGE_NT_SIGNATURE == Hdr.Pe32->Signature) { - // - // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic. - // It is due to backward-compatibility, for some system might - // generate PE32+ image with PE32 Magic. - // - switch (Hdr.Pe32->FileHeader.Machine) { - case IMAGE_FILE_MACHINE_I386: - case IMAGE_FILE_MACHINE_ARMTHUMB_MIXED: - // - // Assume PE32 image with IA32 Machine field. - // - Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; - break; - case IMAGE_FILE_MACHINE_X64: - // - // Assume PE32+ image with X64 Machine field - // - Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - break; - default: - // - // For unknown Machine field, use Magic in optional Header - // - Magic = Hdr.Pe32->OptionalHeader.Magic; - } - - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( - (UINT8 *) Hdr.Pe32 + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - Hdr.Pe32->FileHeader.SizeOfOptionalHeader - ); - Index = Hdr.Pe32->FileHeader.NumberOfSections; - - if (EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC == Magic) { - // - // Use PE32 offset get Debug Directory Entry - // - NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes; - DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - // - // Use PE32+ offset get Debug Directory Entry - // - NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes; - DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - } - - if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG || DirectoryEntry->VirtualAddress == 0) { - DirectoryEntry = NULL; - DebugEntry = NULL; - } else { - // - // Get the DebugEntry offset in the raw data image. - // - for (Index1 = 0; Index1 < Index; Index1 ++) { - if ((DirectoryEntry->VirtualAddress >= SectionHeader[Index1].VirtualAddress) && - (DirectoryEntry->VirtualAddress < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) { - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ( - (UINTN) Pe32Data + - DirectoryEntry->VirtualAddress - - SectionHeader[Index1].VirtualAddress + - SectionHeader[Index1].PointerToRawData); - break; - } - } - } - } else { - return NULL; - } - - if (NULL == DebugEntry || NULL == DirectoryEntry) { - return NULL; - } - - // - // Scan the directory to find the debug entry. - // - for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) { - if (EFI_IMAGE_DEBUG_TYPE_CODEVIEW == DebugEntry->Type) { - if (DebugEntry->SizeOfData > 0) { - // - // Get the DebugEntry offset in the raw data image. - // - CodeViewEntryPointer = NULL; - for (Index1 = 0; Index1 < Index; Index1 ++) { - if ((DebugEntry->RVA >= SectionHeader[Index1].VirtualAddress) && - (DebugEntry->RVA < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) { - CodeViewEntryPointer = (VOID *) ( - ((UINTN)Pe32Data) + - (UINTN) DebugEntry->RVA - - SectionHeader[Index1].VirtualAddress + - SectionHeader[Index1].PointerToRawData + - (UINTN)TEImageAdjust); - break; - } - } - if (Index1 >= Index) { - // - // Can't find CodeViewEntryPointer in raw PE/COFF image. - // - continue; - } - switch (* (UINT32 *) CodeViewEntryPointer) { - case CODEVIEW_SIGNATURE_NB10: - return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)); - case CODEVIEW_SIGNATURE_RSDS: - return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY)); - case CODEVIEW_SIGNATURE_MTOC: - return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY)); - default: - break; - } - } - } - } - - return NULL; -} - - -RETURN_STATUS -EFIAPI -PeCoffLoaderGetEntryPoint ( - IN VOID *Pe32Data, - OUT VOID **EntryPoint, - OUT VOID **BaseOfImage - ) -{ - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - - DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; - } - - // - // Calculate the entry point relative to the start of the image. - // AddressOfEntryPoint is common for PE32 & PE32+ - // - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - *BaseOfImage = (VOID *)(UINTN)(Hdr.Te->ImageBase + Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER)); - *EntryPoint = (VOID *)((UINTN)*BaseOfImage + (Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize); - return RETURN_SUCCESS; - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - *EntryPoint = (VOID *)(UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint; - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - *BaseOfImage = (VOID *)(UINTN)Hdr.Pe32->OptionalHeader.ImageBase; - } else { - *BaseOfImage = (VOID *)(UINTN)Hdr.Pe32Plus->OptionalHeader.ImageBase; - } - *EntryPoint = (VOID *)(UINTN)((UINTN)*EntryPoint + (UINTN)*BaseOfImage); - return RETURN_SUCCESS; - } - - return RETURN_UNSUPPORTED; -} diff --git a/BaseTools/Source/C/Common/CommonLib.c b/BaseTools/Source/C/Common/CommonLib.c index 80b62897ca..d5f845b568 100644 --- a/BaseTools/Source/C/Common/CommonLib.c +++ b/BaseTools/Source/C/Common/CommonLib.c @@ -14,12 +14,17 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #else #include +#include #endif #include "CommonLib.h" #include "EfiUtilityMsgs.h" +#include "FvLib.h" + +#include #include #include +#include GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode; @@ -615,3 +620,64 @@ CpuDeadLoop ( { abort (); } + +EFI_STATUS +GetAlignmentFromFile ( + IN CHAR8 *InFile, + OUT UINT32 *Alignment + ) + /*++ + InFile is input file for getting alignment + return the alignment + --*/ +{ + FILE *InFileHandle; + UINT8 *ImageFileBuffer; + UINTN ImageFileSize; + UINT32 CurSecHdrSize; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + EFI_COMMON_SECTION_HEADER *CommonHeader; + EFI_STATUS Status; + + InFileHandle = NULL; + ImageFileBuffer = NULL; + *Alignment = 0; + + InFileHandle = fopen(LongFilePath(InFile), "rb"); + if (InFileHandle == NULL){ + Error (NULL, 0, 0001, "Error opening file", InFile); + return EFI_ABORTED; + } + ImageFileSize = _filelength (fileno(InFileHandle)); + ImageFileBuffer = (UINT8 *) malloc (ImageFileSize); + if (ImageFileBuffer == NULL) { + fclose (InFileHandle); + Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile); + return EFI_OUT_OF_RESOURCES; + } + fread (ImageFileBuffer, sizeof (UINT8), ImageFileSize, InFileHandle); + fclose (InFileHandle); + + CommonHeader = (EFI_COMMON_SECTION_HEADER *) ImageFileBuffer; + CurSecHdrSize = GetSectionHeaderLength(CommonHeader); + + Status = UefiImageInitializeContext ( + &ImageContext, + ImageFileBuffer + CurSecHdrSize, + ImageFileSize, + UEFI_IMAGE_SOURCE_FV + ); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 3000, "Invalid UefiImage", "The input file is %s and return status is %x", InFile, (int) Status); + return Status; + } + + *Alignment = UefiImageGetSegmentAlignment (&ImageContext); + // Free the allocated memory resource + if (ImageFileBuffer != NULL) { + free (ImageFileBuffer); + ImageFileBuffer = NULL; + } + + return EFI_SUCCESS; +} diff --git a/BaseTools/Source/C/Common/CommonLib.h b/BaseTools/Source/C/Common/CommonLib.h index 6ac64897f1..02bb63e6ba 100644 --- a/BaseTools/Source/C/Common/CommonLib.h +++ b/BaseTools/Source/C/Common/CommonLib.h @@ -113,6 +113,12 @@ LongFilePath ( IN CHAR8 *FileName ); +EFI_STATUS +GetAlignmentFromFile ( + IN CHAR8 *InFile, + OUT UINT32 *Alignment + ); + /*++ Routine Description: diff --git a/BaseTools/Source/C/Common/GNUmakefile b/BaseTools/Source/C/Common/GNUmakefile index c5a49ffe2f..1396c3f578 100644 --- a/BaseTools/Source/C/Common/GNUmakefile +++ b/BaseTools/Source/C/Common/GNUmakefile @@ -11,7 +11,6 @@ MAKEROOT ?= .. LIBNAME = Common OBJECTS = \ - BasePeCoff.o \ BinderFuncs.o \ CommonLib.o \ Crc32.o \ @@ -25,13 +24,26 @@ OBJECTS = \ OsPath.o \ ParseGuidedSectionTools.o \ ParseInf.o \ - PeCoffLoaderEx.o \ SimpleFileParsing.o \ StringFuncs.o \ TianoCompress.o OBJECTS += AutoGen.o DebugLib.o +OBJECTS += \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/ImageToolEmit.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/Image.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/ElfScan32.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/ElfScan64.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/ElfScanCommon.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/UefiImageScan.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/PeScan.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit32.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit64.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmitCommon.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/BinEmit.o \ + $(EDK2_OBJPATH)/OpenCorePkg/User/Library/UserFile.o + OBJECTS += \ $(EDK2_OBJPATH)/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.o @@ -92,6 +104,30 @@ OBJECTS += \ $(EDK2_OBJPATH)/MdePkg/Library/BasePrintLib/PrintLib.o \ $(EDK2_OBJPATH)/MdePkg/Library/BasePrintLib/PrintLibInternal.o +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseAlignment.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseBitOverflow.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseMath.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseNativeOverflow.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseTripleOverflow.o + +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffDebug.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffHash.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffHii.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffInit.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffRelocate.o + +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/CommonSupport.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.o + +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageExtraActionLibNull/UefiImageExtraActionLib.o + OBJECTS += \ $(EDK2_OBJPATH)/MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.o diff --git a/BaseTools/Source/C/Common/Makefile b/BaseTools/Source/C/Common/Makefile index e4982cbff4..af704876dd 100644 --- a/BaseTools/Source/C/Common/Makefile +++ b/BaseTools/Source/C/Common/Makefile @@ -11,7 +11,6 @@ LIBNAME = Common OBJECTS = \ - BasePeCoff.obj \ BinderFuncs.obj \ CommonLib.obj \ Crc32.obj \ @@ -25,13 +24,26 @@ OBJECTS = \ OsPath.obj \ ParseGuidedSectionTools.obj \ ParseInf.obj \ - PeCoffLoaderEx.obj \ SimpleFileParsing.obj \ StringFuncs.obj \ TianoCompress.obj OBJECTS = $(OBJECTS) AutoGen.obj DebugLib.obj +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\ImageToolEmit.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\Image.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\ElfScan32.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\ElfScan64.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\ElfScanCommon.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\UefiImageScan.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\PeScan.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit32.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit64.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmitCommon.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\BinEmit.obj \ + $(EDK2_OBJPATH)\OpenCorePkg\User\Library\UserFile.obj + OBJECTS = $(OBJECTS) \ $(EDK2_OBJPATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib\BaseDebugPrintErrorLevelLib.obj @@ -91,6 +103,30 @@ OBJECTS = $(OBJECTS) \ $(EDK2_OBJPATH)\MdePkg\Library\BasePrintLib\PrintLib.obj \ $(EDK2_OBJPATH)\MdePkg\Library\BasePrintLib\PrintLibInternal.obj +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseAlignment.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseBitOverflow.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseMath.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseNativeOverflow.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseTripleOverflow.obj + +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffDebug.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffHash.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffHii.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffInfo.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffInit.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffLoad.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffRelocate.obj + +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\CommonSupport.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\PeCoffSupport.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\UefiImageLibPeCoff.obj + +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull\UefiImageExtraActionLib.obj + OBJECTS = $(OBJECTS) \ $(EDK2_OBJPATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull\BaseMemoryProfileLibNull.obj diff --git a/BaseTools/Source/C/Common/PeCoffLib.h b/BaseTools/Source/C/Common/PeCoffLib.h deleted file mode 100644 index dd38f442f9..0000000000 --- a/BaseTools/Source/C/Common/PeCoffLib.h +++ /dev/null @@ -1,213 +0,0 @@ -/** @file - Function prototypes and defines on Memory Only PE COFF loader - - Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __BASE_PE_COFF_LIB_H__ -#define __BASE_PE_COFF_LIB_H__ - -// -// Return status codes from the PE/COFF Loader services -// BUGBUG: Find where used and see if can be replaced by RETURN_STATUS codes -// -#define IMAGE_ERROR_SUCCESS 0 -#define IMAGE_ERROR_IMAGE_READ 1 -#define IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE 2 -#define IMAGE_ERROR_INVALID_MACHINE_TYPE 3 -#define IMAGE_ERROR_INVALID_SUBSYSTEM 4 -#define IMAGE_ERROR_INVALID_IMAGE_ADDRESS 5 -#define IMAGE_ERROR_INVALID_IMAGE_SIZE 6 -#define IMAGE_ERROR_INVALID_SECTION_ALIGNMENT 7 -#define IMAGE_ERROR_SECTION_NOT_LOADED 8 -#define IMAGE_ERROR_FAILED_RELOCATION 9 -#define IMAGE_ERROR_FAILED_ICACHE_FLUSH 10 - -// -// Macro definitions for RISC-V architecture. -// -#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1)) -#define RISCV_IMM_BITS 12 -#define RISCV_IMM_REACH (1LL<ImageRead() function - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderGetImageInfo ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -; - -/** - Relocates a PE/COFF image in memory - - @param ImageContext Contains information on the loaded image to relocate - - @retval EFI_SUCCESS if the PE/COFF image was relocated - @retval EFI_LOAD_ERROR if the image is not a valid PE/COFF image - @retval EFI_UNSUPPORTED not support - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderRelocateImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -; - -/** - Loads a PE/COFF image into memory - - @param ImageContext Contains information on image to load into memory - - @retval EFI_SUCCESS if the PE/COFF image was loaded - @retval EFI_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer - @retval EFI_LOAD_ERROR if the image is a runtime driver with no relocations - @retval EFI_INVALID_PARAMETER if the image address is invalid - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderLoadImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -; - -VOID * -EFIAPI -PeCoffLoaderGetPdbPointer ( - IN VOID *Pe32Data - ) -; - -RETURN_STATUS -EFIAPI -PeCoffLoaderGetEntryPoint ( - IN VOID *Pe32Data, - OUT VOID **EntryPoint, - OUT VOID **BaseOfImage - ) -; - -// -// These functions are used by the ARM PE/COFF relocation code and by -// the ELF to PE/COFF converter so that is why they are public -// - -/** - Pass in a pointer to an ARM MOVT or MOVW immediate instruction and - return the immediate data encoded in the instruction - - @param Instruction Pointer to ARM MOVT or MOVW immediate instruction - - @return Immediate address encoded in the instruction - -**/ -UINT16 -EFIAPI -ThumbMovtImmediateAddress ( - IN UINT16 *Instruction - ); - -/** - Update an ARM MOVT or MOVW immediate instruction immediate data. - - @param Instruction Pointer to ARM MOVT or MOVW immediate instruction - @param Address New address to patch into the instruction - -**/ -VOID -EFIAPI -ThumbMovtImmediatePatch ( - IN OUT UINT16 *Instruction, - IN UINT16 Address - ); - - -/** - Pass in a pointer to an ARM MOVW/MOVT instruction pair and - return the immediate data encoded in the two` instruction - - @param Instructions Pointer to ARM MOVW/MOVT instruction pair - - @return Immediate address encoded in the instructions - -**/ -UINT32 -EFIAPI -ThumbMovwMovtImmediateAddress ( - IN UINT16 *Instructions - ); - -/** - Update an ARM MOVW/MOVT immediate instruction instruction pair. - - @param Instructions Pointer to ARM MOVW/MOVT instruction pair - @param Address New address to patch into the instructions -**/ -VOID -EFIAPI -ThumbMovwMovtImmediatePatch ( - IN OUT UINT16 *Instructions, - IN UINT32 Address - ); - - - -#endif diff --git a/BaseTools/Source/C/Common/PeCoffLoaderEx.c b/BaseTools/Source/C/Common/PeCoffLoaderEx.c deleted file mode 100644 index 088e470d17..0000000000 --- a/BaseTools/Source/C/Common/PeCoffLoaderEx.c +++ /dev/null @@ -1,385 +0,0 @@ -/** @file -IA32 and X64 Specific relocation fixups - -Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
-Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
-Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
-Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - ---*/ - -#include -#include -#include "PeCoffLib.h" -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" - -#define IMM64_IMM7B_INST_WORD_X 3 -#define IMM64_IMM7B_SIZE_X 7 -#define IMM64_IMM7B_INST_WORD_POS_X 4 -#define IMM64_IMM7B_VAL_POS_X 0 - -#define IMM64_IMM9D_INST_WORD_X 3 -#define IMM64_IMM9D_SIZE_X 9 -#define IMM64_IMM9D_INST_WORD_POS_X 18 -#define IMM64_IMM9D_VAL_POS_X 7 - -#define IMM64_IMM5C_INST_WORD_X 3 -#define IMM64_IMM5C_SIZE_X 5 -#define IMM64_IMM5C_INST_WORD_POS_X 13 -#define IMM64_IMM5C_VAL_POS_X 16 - -#define IMM64_IC_INST_WORD_X 3 -#define IMM64_IC_SIZE_X 1 -#define IMM64_IC_INST_WORD_POS_X 12 -#define IMM64_IC_VAL_POS_X 21 - -#define IMM64_IMM41a_INST_WORD_X 1 -#define IMM64_IMM41a_SIZE_X 10 -#define IMM64_IMM41a_INST_WORD_POS_X 14 -#define IMM64_IMM41a_VAL_POS_X 22 - -#define IMM64_IMM41b_INST_WORD_X 1 -#define IMM64_IMM41b_SIZE_X 8 -#define IMM64_IMM41b_INST_WORD_POS_X 24 -#define IMM64_IMM41b_VAL_POS_X 32 - -#define IMM64_IMM41c_INST_WORD_X 2 -#define IMM64_IMM41c_SIZE_X 23 -#define IMM64_IMM41c_INST_WORD_POS_X 0 -#define IMM64_IMM41c_VAL_POS_X 40 - -#define IMM64_SIGN_INST_WORD_X 3 -#define IMM64_SIGN_SIZE_X 1 -#define IMM64_SIGN_INST_WORD_POS_X 27 -#define IMM64_SIGN_VAL_POS_X 63 - -UINT32 *RiscVHi20Fixup = NULL; - -/** - Performs an IA-32 specific relocation fixup - - @param Reloc Pointer to the relocation record - @param Fixup Pointer to the address to fix up - @param FixupData Pointer to a buffer to log the fixups - @param Adjust The offset to adjust the fixup - - @retval EFI_UNSUPPORTED - Unsupported now -**/ -RETURN_STATUS -PeCoffLoaderRelocateIa32Image ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ) -{ - return RETURN_UNSUPPORTED; -} - -/** - Performs an RISC-V specific relocation fixup - - @param Reloc Pointer to the relocation record - @param Fixup Pointer to the address to fix up - @param FixupData Pointer to a buffer to log the fixups - @param Adjust The offset to adjust the fixup - - @return Status code -**/ -RETURN_STATUS -PeCoffLoaderRelocateRiscVImage ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ) -{ - UINT32 Value; - UINT32 Value2; - - switch ((*Reloc) >> 12) { - case EFI_IMAGE_REL_BASED_RISCV_HI20: - RiscVHi20Fixup = (UINT32 *) Fixup; - break; - - case EFI_IMAGE_REL_BASED_RISCV_LOW12I: - if (RiscVHi20Fixup != NULL) { - Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12); - Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 20, 12)); - if (Value2 & (RISCV_IMM_REACH/2)) { - Value2 |= ~(RISCV_IMM_REACH-1); - } - Value += Value2; - Value += (UINT32)Adjust; - Value2 = RISCV_CONST_HIGH_PART (Value); - *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \ - (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12)); - *(UINT32 *)Fixup = (RV_X (Value, 0, 12) << 20) | \ - (RV_X (*(UINT32 *)Fixup, 0, 20)); - } - RiscVHi20Fixup = NULL; - break; - - case EFI_IMAGE_REL_BASED_RISCV_LOW12S: - if (RiscVHi20Fixup != NULL) { - Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12); - Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 7, 5) | (RV_X(*(UINT32 *)Fixup, 25, 7) << 5)); - if (Value2 & (RISCV_IMM_REACH/2)) { - Value2 |= ~(RISCV_IMM_REACH-1); - } - Value += Value2; - Value += (UINT32)Adjust; - Value2 = RISCV_CONST_HIGH_PART (Value); - *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \ - (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12)); - Value2 = *(UINT32 *)Fixup & 0x01fff07f; - Value &= RISCV_IMM_REACH - 1; - *(UINT32 *)Fixup = Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (RV_X(Value, 5, 7) << 25))); - } - RiscVHi20Fixup = NULL; - break; - - default: - return EFI_UNSUPPORTED; - - } - return RETURN_SUCCESS; -} - -/** - Pass in a pointer to an ARM MOVT or MOVW immediate instruction and - return the immediate data encoded in the instruction - - @param Instruction Pointer to ARM MOVT or MOVW immediate instruction - - @return Immediate address encoded in the instruction - -**/ -UINT16 -EFIAPI -ThumbMovtImmediateAddress ( - IN UINT16 *Instruction - ) -{ - UINT32 Movt; - UINT16 Address; - - // Thumb2 is two 16-bit instructions working together. Not a single 32-bit instruction - // Example MOVT R0, #0 is 0x0000f2c0 or 0xf2c0 0x0000 - Movt = (*Instruction << 16) | (*(Instruction + 1)); - - // imm16 = imm4:i:imm3:imm8 - // imm4 -> Bit19:Bit16 - // i -> Bit26 - // imm3 -> Bit14:Bit12 - // imm8 -> Bit7:Bit0 - Address = (UINT16)(Movt & 0x000000ff); // imm8 - Address |= (UINT16)((Movt >> 4) & 0x0000f700); // imm4 imm3 - Address |= (((Movt & BIT26) != 0) ? BIT11 : 0); // i - return Address; -} - - -/** - Update an ARM MOVT or MOVW immediate instruction immediate data. - - @param Instruction Pointer to ARM MOVT or MOVW immediate instruction - @param Address New address to patch into the instruction -**/ -VOID -EFIAPI -ThumbMovtImmediatePatch ( - IN OUT UINT16 *Instruction, - IN UINT16 Address - ) -{ - UINT16 Patch; - - // First 16-bit chunk of instruction - Patch = ((Address >> 12) & 0x000f); // imm4 - Patch |= (((Address & BIT11) != 0) ? BIT10 : 0); // i - *Instruction = (*Instruction & ~0x040f) | Patch; - - // Second 16-bit chunk of instruction - Patch = Address & 0x000000ff; // imm8 - Patch |= ((Address << 4) & 0x00007000); // imm3 - Instruction++; - *Instruction = (*Instruction & ~0x70ff) | Patch; -} - -/** - Pass in a pointer to an ARM MOVW/MOVT instruction pair and - return the immediate data encoded in the two` instruction - - @param Instructions Pointer to ARM MOVW/MOVT instruction pair - - @return Immediate address encoded in the instructions - -**/ -UINT32 -EFIAPI -ThumbMovwMovtImmediateAddress ( - IN UINT16 *Instructions - ) -{ - UINT16 *Word; - UINT16 *Top; - - Word = Instructions; // MOVW - Top = Word + 2; // MOVT - - return (ThumbMovtImmediateAddress (Top) << 16) + ThumbMovtImmediateAddress (Word); -} - - -/** - Update an ARM MOVW/MOVT immediate instruction instruction pair. - - @param Instructions Pointer to ARM MOVW/MOVT instruction pair - @param Address New address to patch into the instructions -**/ -VOID -EFIAPI -ThumbMovwMovtImmediatePatch ( - IN OUT UINT16 *Instructions, - IN UINT32 Address - ) -{ - UINT16 *Word; - UINT16 *Top; - - Word = (UINT16 *)Instructions; // MOVW - Top = Word + 2; // MOVT - - ThumbMovtImmediatePatch (Word, (UINT16)(Address & 0xffff)); - ThumbMovtImmediatePatch (Top, (UINT16)(Address >> 16)); -} - - -/** - Performs an ARM-based specific relocation fixup and is a no-op on other - instruction sets. - - @param Reloc Pointer to the relocation record. - @param Fixup Pointer to the address to fix up. - @param FixupData Pointer to a buffer to log the fixups. - @param Adjust The offset to adjust the fixup. - - @return Status code. - -**/ -RETURN_STATUS -PeCoffLoaderRelocateArmImage ( - IN UINT16 **Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ) -{ - UINT16 *Fixup16; - UINT32 FixupVal; - - Fixup16 = (UINT16 *) Fixup; - - switch ((**Reloc) >> 12) { - - case EFI_IMAGE_REL_BASED_ARM_MOV32T: - FixupVal = ThumbMovwMovtImmediateAddress (Fixup16) + (UINT32)Adjust; - ThumbMovwMovtImmediatePatch (Fixup16, FixupVal); - - - if (*FixupData != NULL) { - *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64)); - CopyMem (*FixupData, Fixup16, sizeof (UINT64)); - *FixupData = *FixupData + sizeof(UINT64); - } - break; - - case EFI_IMAGE_REL_BASED_ARM_MOV32A: - // break omitted - ARM instruction encoding not implemented - default: - return RETURN_UNSUPPORTED; - } - - return RETURN_SUCCESS; -} - -/** - Performs a LoongArch specific relocation fixup. - - @param[in] Reloc Pointer to the relocation record. - @param[in, out] Fixup Pointer to the address to fix up. - @param[in, out] FixupData Pointer to a buffer to log the fixups. - @param[in] Adjust The offset to adjust the fixup. - - @return Status code. -**/ -RETURN_STATUS -PeCoffLoaderRelocateLoongArch64Image ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ) -{ - UINT8 RelocType; - UINT64 Value; - UINT64 Tmp1; - UINT64 Tmp2; - - RelocType = ((*Reloc) >> 12); - Value = 0; - Tmp1 = 0; - Tmp2 = 0; - - switch (RelocType) { - case EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA: - // The next four instructions are used to load a 64 bit address, relocate all of them - Value = (*(UINT32 *)Fixup & 0x1ffffe0) << 7 | // lu12i.w 20bits from bit5 - (*((UINT32 *)Fixup + 1) & 0x3ffc00) >> 10; // ori 12bits from bit10 - Tmp1 = *((UINT32 *)Fixup + 2) & 0x1ffffe0; // lu32i.d 20bits from bit5 - Tmp2 = *((UINT32 *)Fixup + 3) & 0x3ffc00; // lu52i.d 12bits from bit10 - Value = Value | (Tmp1 << 27) | (Tmp2 << 42); - Value += Adjust; - - *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x1ffffe0) | (((Value >> 12) & 0xfffff) << 5); - if (*FixupData != NULL) { - *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32)); - *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup; - *FixupData = *FixupData + sizeof (UINT32); - } - - Fixup += sizeof (UINT32); - *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x3ffc00) | ((Value & 0xfff) << 10); - if (*FixupData != NULL) { - *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32)); - *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup; - *FixupData = *FixupData + sizeof (UINT32); - } - - Fixup += sizeof (UINT32); - *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x1ffffe0) | (((Value >> 32) & 0xfffff) << 5); - if (*FixupData != NULL) { - *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32)); - *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup; - *FixupData = *FixupData + sizeof (UINT32); - } - - Fixup += sizeof (UINT32); - *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x3ffc00) | (((Value >> 52) & 0xfff) << 10); - if (*FixupData != NULL) { - *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32)); - *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup; - *FixupData = *FixupData + sizeof (UINT32); - } - - break; - default: - Error (NULL, 0, 3000, "", "PeCoffLoaderRelocateLoongArch64Image: Fixup[0x%x] Adjust[0x%llx] *Reloc[0x%x], type[0x%x].", *(UINT32 *)Fixup, Adjust, *Reloc, RelocType); - return RETURN_UNSUPPORTED; - } - - return RETURN_SUCCESS; -} diff --git a/BaseTools/Source/C/EfiRom/EfiRom.c b/BaseTools/Source/C/EfiRom/EfiRom.c index fa7bf0e62e..9a41a34baf 100644 --- a/BaseTools/Source/C/EfiRom/EfiRom.c +++ b/BaseTools/Source/C/EfiRom/EfiRom.c @@ -1,5 +1,5 @@ /** @file -Utility program to create an EFI option ROM image from binary and EFI PE32 files. +Utility program to create an EFI option ROM image from binary and UEFI image files. Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -426,12 +426,12 @@ ProcessEfiFile ( Routine Description: - Process a PE32 EFI file. + Process an UEFI image file. Arguments: OutFptr - file pointer to output binary ROM image file we're creating - InFile - structure contains information on the PE32 file to process + InFile - structure contains information on the UEFI image file to process VendId - vendor ID as required in the option ROM header DevId - device ID as required in the option ROM header Size - pointer to where to return the size added to the output file @@ -471,21 +471,39 @@ Routine Description: // // Initialize our buffer pointers to null. // - Buffer = NULL; CompressedBuffer = NULL; // - // Double-check the file to make sure it's what we expect it to be + // Seek to the end of the input file and get the file size // - Status = CheckPE32File (InFptr, &MachineType, &SubSystem); - if (Status != STATUS_SUCCESS) { + fseek (InFptr, 0, SEEK_END); + FileSize = ftell (InFptr); + + // + // Allocate memory for the entire file (in case we have to compress), then + // seek back to the beginning of the file and read it into our buffer. + // + Buffer = (UINT8 *) malloc (FileSize); + if (Buffer == NULL) { + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); + Status = STATUS_ERROR; + goto BailOut; + } + + fseek (InFptr, 0, SEEK_SET); + if (fread (Buffer, FileSize, 1, InFptr) != 1) { + Error (NULL, 0, 0004, "Error reading file", "File %s", InFile->FileName); + Status = STATUS_ERROR; goto BailOut; } + // - // Seek to the end of the input file and get the file size + // Double-check the file to make sure it's what we expect it to be // - fseek (InFptr, 0, SEEK_END); - FileSize = ftell (InFptr); + Status = CheckUefiImageFile (Buffer, FileSize, &MachineType, &SubSystem); + if (Status != STATUS_SUCCESS) { + goto BailOut; + } // // Get the size of the headers we're going to put in front of the image. The @@ -519,23 +537,6 @@ Routine Description: VerboseMsg(" File size = 0x%X\n", (unsigned) FileSize); } // - // Allocate memory for the entire file (in case we have to compress), then - // seek back to the beginning of the file and read it into our buffer. - // - Buffer = (UINT8 *) malloc (FileSize); - if (Buffer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - Status = STATUS_ERROR; - goto BailOut; - } - - fseek (InFptr, 0, SEEK_SET); - if (fread (Buffer, FileSize, 1, InFptr) != 1) { - Error (NULL, 0, 0004, "Error reading file", "File %s", InFile->FileName); - Status = STATUS_ERROR; - goto BailOut; - } - // // Now determine the size of the final output file. It's either the header size // plus the file's size, or the header size plus the compressed file size. // @@ -805,8 +806,9 @@ Routine Description: static int -CheckPE32File ( - FILE *Fptr, +CheckUefiImageFile ( + VOID *FileBuffer, + UINT32 FileSize, UINT16 *MachineType, UINT16 *SubSystem ) @@ -814,13 +816,14 @@ CheckPE32File ( Routine Description: - Given a file pointer to a supposed PE32 image file, verify that it is indeed a - PE32 image file, and then return the machine type in the supplied pointer. + Given a file pointer to a supposed UEFI image file, verify that it is indeed a + UEFI image file, and then return the machine type in the supplied pointer. Arguments: - Fptr File pointer to the already-opened PE32 file - MachineType Location to stuff the machine type of the PE32 file. This is needed + FileBuffer File buffer of the UEFI image file + FileSize File size, in bytes, of FileBuffer + MachineType Location to stuff the machine type of the UEFI file. This is needed because the image may be Itanium-based, IA32, or EBC. Returns: @@ -830,67 +833,24 @@ Routine Description: --*/ { - EFI_IMAGE_DOS_HEADER DosHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr; - - // - // Position to the start of the file - // - fseek (Fptr, 0, SEEK_SET); - - // - // Read the DOS header - // - if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) { - Error (NULL, 0, 0004, "Failed to read the DOS stub from the input file!", NULL); - return STATUS_ERROR; - } - // - // Check the magic number (0x5A4D) - // - if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) { - Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (magic number)!"); - return STATUS_ERROR; - } - // - // Position into the file and check the PE signature - // - fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET); - - // - // Read PE headers - // - if (fread (&PeHdr, sizeof (PeHdr), 1, Fptr) != 1) { - Error (NULL, 0, 0004, "Failed to read PE/COFF headers from input file!", NULL); - return STATUS_ERROR; - } - + RETURN_STATUS Status; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT Context; - // - // Check the PE signature in the header "PE\0\0" - // - if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { - Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (signature)!"); + Status = UefiImageInitializeContext (&Context, FileBuffer, FileSize); + if (RETURN_ERROR (Status)) { + Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be an UEFI image - %llu!", Status); return STATUS_ERROR; } - memcpy ((char *) MachineType, &PeHdr.Pe32.FileHeader.Machine, 2); - - if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - *SubSystem = PeHdr.Pe32.OptionalHeader.Subsystem; - } else if (PeHdr.Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - *SubSystem = PeHdr.Pe32Plus.OptionalHeader.Subsystem; - } else { - Error (NULL, 0, 2000, "Invalid parameter", "Unable to find subsystem type!"); - return STATUS_ERROR; - } + *MachineType = UefiImageGetMachine (&Context); + *SubSystem = UefiImageGetSubsystem (&Context); if (mOptions.Verbose) { VerboseMsg(" Got subsystem = 0x%X from image\n", *SubSystem); } // - // File was successfully identified as a PE32 + // File was successfully identified as an UEFI image // return STATUS_SUCCESS; } @@ -1354,9 +1314,9 @@ Routine Description: fprintf (stdout, " -o FileName, --output FileName\n\ File will be created to store the output content.\n"); fprintf (stdout, " -e EfiFileName\n\ - EFI PE32 image files.\n"); + UEFI image files.\n"); fprintf (stdout, " -ec EfiFileName\n\ - EFI PE32 image files and will be compressed.\n"); + UEFI image files and will be compressed.\n"); fprintf (stdout, " -b BinFileName\n\ Legacy binary files.\n"); fprintf (stdout, " -l ClassCode\n\ diff --git a/BaseTools/Source/C/EfiRom/EfiRom.h b/BaseTools/Source/C/EfiRom/EfiRom.h index f05198713e..c51bebb0fe 100644 --- a/BaseTools/Source/C/EfiRom/EfiRom.h +++ b/BaseTools/Source/C/EfiRom/EfiRom.h @@ -14,7 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include // for PE32 structure definitions +#include // for PE32 structure definitions #include // for option ROM header structures #include @@ -22,6 +22,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "Compress.h" #include "CommonLib.h" +#include + // // Version of this utility // @@ -203,8 +205,9 @@ Routine Description: static int -CheckPE32File ( - FILE *Fptr, +CheckUefiImageFile ( + VOID *FileBuffer, + UINT32 FileSize, UINT16 *MachineType, UINT16 *SubSystem ) @@ -242,12 +245,12 @@ ProcessEfiFile ( Routine Description: - Process a PE32 EFI file. + Process a UEFI image file. Arguments: OutFptr - file pointer to output binary ROM image file we're creating - InFile - structure contains information on the PE32 file to process + InFile - structure contains information on the UEFI image file to process VendId - vendor ID as required in the option ROM header DevId - device ID as required in the option ROM header Size - pointer to where to return the size added to the output file diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c index 857c5c294f..d38b39236a 100644 --- a/BaseTools/Source/C/GenFfs/GenFfs.c +++ b/BaseTools/Source/C/GenFfs/GenFfs.c @@ -27,14 +27,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include #include #include "CommonLib.h" #include "ParseInf.h" #include "EfiUtilityMsgs.h" #include "FvLib.h" -#include "PeCoffLib.h" #define UTILITY_NAME "GenFfs" #define UTILITY_MAJOR_VERSION 0 @@ -453,104 +451,6 @@ Routine Description: } } -EFI_STATUS -EFIAPI -FfsRebaseImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINT32 *ReadSize, - OUT VOID *Buffer - ) - /*++ - - Routine Description: - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - - Arguments: - - FileHandle - The handle to the PE/COFF file - - FileOffset - The offset, in bytes, into the file to read - - ReadSize - The number of bytes to read from the file starting at FileOffset - - Buffer - A pointer to the buffer to read the data into. - - Returns: - - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - - --*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINT32 Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -GetAlignmentFromFile(char *InFile, UINT32 *Alignment) - /*++ - InFile is input file for getting alignment - return the alignment - --*/ -{ - FILE *InFileHandle; - UINT8 *PeFileBuffer; - UINTN PeFileSize; - UINT32 CurSecHdrSize; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - EFI_COMMON_SECTION_HEADER *CommonHeader; - EFI_STATUS Status; - - InFileHandle = NULL; - PeFileBuffer = NULL; - *Alignment = 0; - - memset (&ImageContext, 0, sizeof (ImageContext)); - - InFileHandle = fopen(LongFilePath(InFile), "rb"); - if (InFileHandle == NULL){ - Error (NULL, 0, 0001, "Error opening file", InFile); - return EFI_ABORTED; - } - PeFileSize = _filelength (fileno(InFileHandle)); - PeFileBuffer = (UINT8 *) malloc (PeFileSize); - if (PeFileBuffer == NULL) { - fclose (InFileHandle); - Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile); - return EFI_OUT_OF_RESOURCES; - } - fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle); - fclose (InFileHandle); - CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer; - CurSecHdrSize = GetSectionHeaderLength(CommonHeader); - ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize); - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead; - Status = PeCoffLoaderGetImageInfo(&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status); - return Status; - } - *Alignment = ImageContext.SectionAlignment; - // Free the allocated memory resource - if (PeFileBuffer != NULL) { - free (PeFileBuffer); - PeFileBuffer = NULL; - } - return EFI_SUCCESS; -} - int main ( int argc, diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index d5de8f732c..091d469890 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -31,12 +31,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #endif #include +#include #include #include "GenFvInternalLib.h" #include "FvLib.h" -#include "PeCoffLib.h" +#include +#include + +#include "../../../ImageTool/ImageToolEmit.h" #define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION 0x14000000 @@ -727,24 +731,24 @@ Routine Description: EFI_STATUS WriteMapFile ( IN OUT FILE *FvMapFile, - IN CHAR8 *FileName, + IN CONST CHAR8 *FileName, IN EFI_FFS_FILE_HEADER *FfsFile, IN EFI_PHYSICAL_ADDRESS ImageBaseAddress, - IN PE_COFF_LOADER_IMAGE_CONTEXT *pImageContext + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *pImageContext ) /*++ Routine Description: This function gets the basic debug information (entrypoint, baseaddress, .text, .data section base address) - from PE/COFF image and abstracts Pe Map file information and add them into FvMap file for Debug. + from UEFI image and abstracts UEFI image Map file information and add them into FvMap file for Debug. Arguments: FvMapFile A pointer to FvMap File FileName Ffs File PathName FfsFile A pointer to Ffs file image. - ImageBaseAddress PeImage Base Address. + ImageBaseAddress UefiImage Base Address. pImageContext Image Context Information. Returns: @@ -764,9 +768,8 @@ Routine Description: EFI_PHYSICAL_ADDRESS FunctionAddress; UINT32 FunctionType; CHAR8 FunctionTypeName [MAX_LINE_LEN]; + UINT8 Format; UINT32 AddressOfEntryPoint; - UINT32 Offset; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; long long TempLongAddress; EFI_PHYSICAL_ADDRESS LinkTimeBaseAddress; BOOLEAN IsUseClang; @@ -832,13 +835,9 @@ Routine Description: *Cptr2 = '.'; // - // AddressOfEntryPoint and Offset in Image + // AddressOfEntryPoint in Image // - assert (!pImageContext->IsTeImage); - - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINT8 *) pImageContext->Handle + pImageContext->PeCoffHeaderOffset); - AddressOfEntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint; - Offset = 0; + AddressOfEntryPoint = UefiImageGetEntryPointAddress (pImageContext); // // module information output @@ -848,11 +847,18 @@ Routine Description: fprintf (FvMapFile, "BaseAddress=%010llx, ", (unsigned long long) ImageBaseAddress); } else { fprintf (FvMapFile, "%s (Fixed Flash Address, ", KeyWord); - fprintf (FvMapFile, "BaseAddress=0x%010llx, ", (unsigned long long) (ImageBaseAddress + Offset)); + fprintf (FvMapFile, "BaseAddress=0x%010llx, ", (unsigned long long) ImageBaseAddress); } + Format = UefiImageGetFormat (pImageContext); + fprintf (FvMapFile, "EntryPoint=0x%010llx, ", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint)); - fprintf (FvMapFile, "Type=PE"); + if (Format == UefiImageFormatPe) { + fprintf (FvMapFile, "Type=PE"); + } else { + assert (FALSE); + fprintf (FvMapFile, "Type=Unknown"); + } fprintf (FvMapFile, ")\n"); fprintf (FvMapFile, "(GUID=%s)\n\n", FileGuidName); @@ -1269,7 +1275,7 @@ Routine Description: return EFI_ABORTED; } // - // Rebase the PE image in FileBuffer of FFS file for XIP + // Rebase the UEFI image in FileBuffer of FFS file for XIP // Rebase for the debug genfvmap tool // Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER **)&FileBuffer, &FileSize, (UINTN) *VtfFileImage - (UINTN) FvImage->FileImage, FvMapFile); @@ -1321,7 +1327,7 @@ Routine Description: // if ((UINTN) (FvImage->CurrentFilePointer + FileSize) <= (UINTN) (*VtfFileImage)) { // - // Rebase the PE image in FileBuffer of FFS file for XIP. + // Rebase the UEFI image in FileBuffer of FFS file for XIP. // Rebase Bs and Rt drivers for the debug genfvmap tool. // Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER **)&FileBuffer, &FileSize, (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage, FvMapFile); @@ -1558,14 +1564,15 @@ Routine Description: } SecHeaderSize = GetSectionHeaderLength(Pe32Section.CommonHeader); - Status = GetPe32Info ( + Status = GetUefiImageInfo ( (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize), + GetSectionFileLength (Pe32Section.CommonHeader) - SecHeaderSize, &EntryPoint, &MachineType ); if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the SEC core."); + Error (NULL, 0, 3000, "Invalid", "could not get the UEFI image entry point for the SEC core."); return EFI_ABORTED; } @@ -1583,7 +1590,7 @@ Routine Description: } // - // Physical address is FV base + offset of PE32 + offset of the entry point + // Physical address is FV base + offset of UEFI image + offset of the entry point // SecCorePhysicalAddress = FvInfo->BaseAddress; SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + SecHeaderSize - (UINTN) FvImage->FileImage; @@ -1606,18 +1613,19 @@ Routine Description: } SecHeaderSize = GetSectionHeaderLength(Pe32Section.CommonHeader); - Status = GetPe32Info ( + Status = GetUefiImageInfo ( (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize), + GetSectionFileLength (Pe32Section.CommonHeader) - SecHeaderSize, &EntryPoint, &MachineType ); if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the PEI core."); + Error (NULL, 0, 3000, "Invalid", "could not get the UEFI image entry point for the PEI core."); return EFI_ABORTED; } // - // Physical address is FV base + offset of PE32 + offset of the entry point + // Physical address is FV base + offset of UEFI image + offset of the entry point // PeiCorePhysicalAddress = FvInfo->BaseAddress; PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + SecHeaderSize - (UINTN) FvImage->FileImage; @@ -1851,13 +1859,14 @@ Routine Description: return EFI_INVALID_PARAMETER; } - Status = GetPe32Info( + Status = GetUefiImageInfo( (VOID *)((UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)), + GetSectionFileLength (Pe32Section.CommonHeader) - GetSectionHeaderLength(Pe32Section.CommonHeader), &EntryPoint, CoreMachineType ); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "could not get the PE32 machine type for the core."); + Error(NULL, 0, 3000, "Invalid", "could not get the UEFI image machine type for the core."); return EFI_ABORTED; } @@ -1881,7 +1890,7 @@ Routine Description: FvImageBuffer Pointer to buffer containing FV data FvInfo Info for the parent FV - Pe32Section PE32 section data + Pe32Section UEFI image section data CoreEntryAddress The extracted core entry physical address Returns: @@ -1901,18 +1910,19 @@ Routine Description: return EFI_INVALID_PARAMETER; } - Status = GetPe32Info( + Status = GetUefiImageInfo( (VOID *)((UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)), + GetSectionFileLength (Pe32Section.CommonHeader) - GetSectionHeaderLength(Pe32Section.CommonHeader), &EntryPoint, &MachineType ); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the core."); + Error(NULL, 0, 3000, "Invalid", "could not get the UEFI image entry point for the core."); return EFI_ABORTED; } // - // Physical address is FV base + offset of PE32 + offset of the entry point + // Physical address is FV base + offset of UEFI image + offset of the entry point // EntryPhysicalAddress = FvInfo->BaseAddress; EntryPhysicalAddress += (UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader) - (UINTN)FvImageBuffer; @@ -1998,13 +2008,13 @@ Routine Description: Status = GetCoreMachineType(SecPe32, &MachineType); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for SEC Core."); return EFI_ABORTED; } Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image entry point address for SEC Core."); return EFI_ABORTED; } @@ -2020,13 +2030,13 @@ Routine Description: Status = GetCoreMachineType(PeiPe32, &PeiMachineType); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for PEI Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for PEI Core."); return EFI_ABORTED; } Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, PeiPe32, &PeiCoreEntryAddress); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for PEI Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image entry point address for PEI Core."); return EFI_ABORTED; } @@ -2217,7 +2227,7 @@ Routine Description: Status = GetCoreMachineType(SecPe32, &MachineType); if(EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for SEC core."); return EFI_ABORTED; } @@ -2228,7 +2238,7 @@ Routine Description: Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress); if(EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image entry point address for SEC Core."); return EFI_ABORTED; } @@ -2306,13 +2316,13 @@ Routine Description: Status = GetCoreMachineType(SecPe32, &MachineType); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for SEC Core."); return EFI_ABORTED; } Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image entry point address for SEC Core."); return EFI_ABORTED; } @@ -2349,8 +2359,9 @@ Routine Description: } EFI_STATUS -GetPe32Info ( - IN UINT8 *Pe32, +GetUefiImageInfo ( + IN UINT8 *UefiImage, + IN UINT32 UefiImageSize, OUT UINT32 *EntryPoint, OUT UINT16 *MachineType ) @@ -2358,14 +2369,15 @@ GetPe32Info ( Routine Description: - Retrieves the PE32 entry point offset and machine type from PE image or TeImage. + Retrieves the UEFI image entry point offset and machine type from UEFI image. See EfiImage.h for machine types. The entry point offset is from the beginning - of the PE32 buffer passed in. + of the UEFI image buffer passed in. Arguments: - Pe32 Beginning of the PE32. - EntryPoint Offset from the beginning of the PE32 to the image entry point. + UefiImage Beginning of the UEFI image. + UefiImageSize The size, in bytes, of UefiImage. + EntryPoint Offset from the beginning of the UEFI image to the image entry point. MachineType Magic number for the machine type. Returns: @@ -2377,46 +2389,23 @@ Routine Description: --*/ { - EFI_IMAGE_DOS_HEADER *DosHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT Context; // // Verify input parameters // - if (Pe32 == NULL) { + if (UefiImage == NULL) { return EFI_INVALID_PARAMETER; } - // - // Check whether - // First is the DOS header - // - DosHeader = (EFI_IMAGE_DOS_HEADER *) Pe32; - - // - // Verify DOS header is expected - // - if (DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - Error (NULL, 0, 3000, "Invalid", "Unknown magic number in the DOS header, 0x%04X.", DosHeader->e_magic); - return EFI_UNSUPPORTED; + RETURN_STATUS Status = UefiImageInitializeContext (&Context, UefiImage, UefiImageSize); + if (RETURN_ERROR (Status)) { + Error (NULL, 0, 3000, "Invalid", "Unrecognized UEFI image file."); + return Status; } - // - // Immediately following is the NT header. - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINTN) Pe32 + DosHeader->e_lfanew); - // - // Verify NT header is expected - // - if (ImgHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { - Error (NULL, 0, 3000, "Invalid", "Unrecognized image signature 0x%08X.", (unsigned) ImgHdr->Pe32.Signature); - return EFI_UNSUPPORTED; - } - // - // Get output - // - *EntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint; - *MachineType = ImgHdr->Pe32.FileHeader.Machine; + *EntryPoint = UefiImageGetEntryPointAddress (&Context); + *MachineType = UefiImageGetMachine (&Context); // // Verify machine type is supported @@ -2424,7 +2413,7 @@ Routine Description: if ((*MachineType != IMAGE_FILE_MACHINE_I386) && (*MachineType != IMAGE_FILE_MACHINE_X64) && (*MachineType != IMAGE_FILE_MACHINE_EBC) && (*MachineType != IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) && (*MachineType != IMAGE_FILE_MACHINE_ARM64) && (*MachineType != IMAGE_FILE_MACHINE_RISCV64) && (*MachineType != IMAGE_FILE_MACHINE_LOONGARCH64)) { - Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the PE32 file."); + Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the UEFI image file."); return EFI_UNSUPPORTED; } @@ -3272,50 +3261,6 @@ Routine Description: return EFI_SUCCESS; } -EFI_STATUS -EFIAPI -FfsRebaseImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINT32 *ReadSize, - OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - -Arguments: - - FileHandle - The handle to the PE/COFF file - - FileOffset - The offset, in bytes, into the file to read - - ReadSize - The number of bytes to read from the file starting at FileOffset - - Buffer - A pointer to the buffer to read the data into. - -Returns: - - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - ---*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINT32 Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} - EFI_STATUS GetChildFvFromFfs ( IN FV_INFO *FvInfo, @@ -3369,7 +3314,7 @@ Routine Description: if (!EFI_ERROR(Status)) { Status = GetCoreMachineType(CorePe32, &MachineType); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC/PEI Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for SEC/PEI Core."); return EFI_ABORTED; } @@ -3528,32 +3473,40 @@ Routine Description: --*/ { EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - PE_COFF_LOADER_IMAGE_CONTEXT OrigImageContext; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UINT16 Machine; EFI_PHYSICAL_ADDRESS XipBase; - EFI_PHYSICAL_ADDRESS NewPe32BaseAddress; + EFI_PHYSICAL_ADDRESS NewBaseAddress; UINTN Index; EFI_FILE_SECTION_POINTER CurrentPe32Section; EFI_FFS_FILE_STATE SavedState; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - UINT8 *MemoryImagePointer; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - CHAR8 PeFileName [MAX_LONG_FILE_PATH]; + CHAR8 UefiImageFileName [MAX_LONG_FILE_PATH]; CHAR8 *Cptr; - FILE *PeFile; - UINT8 *PeFileBuffer; - UINT32 PeFileSize; - CHAR8 *PdbPointer; + FILE *UefiImageFile; + UINT8 *UefiImageFileBuffer; + UINT32 UefiImageFileSize; + BOOLEAN FreeUefiImageFile; + CONST CHAR8 *SymbolsPath; + UINT32 SymbolsPathSize; + CHAR8 *SymbolsPathCpy; UINT32 FfsHeaderSize; UINT32 CurSecHdrSize; - - Index = 0; - MemoryImagePointer = NULL; - ImgHdr = NULL; - SectionHeader = NULL; - Cptr = NULL; - PeFile = NULL; - PeFileBuffer = NULL; + UINT32 SectPeSize; + UINT32 ImageSize; + UINT32 DestinationPages; + UINT32 DestinationSize; + UINT32 ImageAlignment; + VOID *Destination; + BOOLEAN Strip; + UINT8 ImageFormat; + UINT32 RebasedImageSize; + VOID *RebasedImage; + + Index = 0; + Cptr = NULL; + UefiImageFile = NULL; + UefiImageFileBuffer = NULL; + FreeUefiImageFile = FALSE; // // Don't need to relocate image when BaseAddress is zero and no ForceRebase Flag specified. @@ -3571,6 +3524,8 @@ Routine Description: XipBase = FvInfo->BaseAddress + XipOffset; + Strip = FALSE; + // // We only process files potentially containing PE32 sections. // @@ -3605,7 +3560,7 @@ Routine Description: // // Init Value // - NewPe32BaseAddress = 0; + NewBaseAddress = 0; // // Find Pe Image @@ -3619,140 +3574,76 @@ Routine Description: // // Initialize context // - memset (&ImageContext, 0, sizeof (ImageContext)); - ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize); - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead; - Status = PeCoffLoaderGetImageInfo (&ImageContext); + SectPeSize = GetSectionFileLength (CurrentPe32Section.CommonHeader) - CurSecHdrSize; + Status = UefiImageInitializeContext ( + &ImageContext, + (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize), + SectPeSize + ); if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, (int) Status); + Error (NULL, 0, 3000, "Invalid UefiImage", "The input file is %s and the return status is %x", FileName, (int) Status); return Status; } - if ( (ImageContext.Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) || - (ImageContext.Machine == IMAGE_FILE_MACHINE_ARM64) ) { + Machine = UefiImageGetMachine (&ImageContext); + + if ( (Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) || + (Machine == IMAGE_FILE_MACHINE_AARCH64) ) { mArm = TRUE; } - if (ImageContext.Machine == IMAGE_FILE_MACHINE_RISCV64) { + if (Machine == IMAGE_FILE_MACHINE_RISCV64) { mRiscV = TRUE; } - if (ImageContext.Machine == IMAGE_FILE_MACHINE_LOONGARCH64) { + if (Machine == IMAGE_FILE_MACHINE_LOONGARCH64) { mLoongArch = TRUE; } - // - // Keep Image Context for PE image in FV - // - memcpy (&OrigImageContext, &ImageContext, sizeof (ImageContext)); + ImageFormat = UefiImageGetFormat (&ImageContext); - // - // Get File PdbPointer - // - PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle); + ImageSize = UefiImageGetImageSize (&ImageContext); + DestinationPages = EFI_SIZE_TO_PAGES (ImageSize); + DestinationSize = EFI_PAGES_TO_SIZE (DestinationPages); + ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext); + Destination = AllocateAlignedCodePages (DestinationPages, ImageAlignment); + if (Destination == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = UefiImageLoadImage (&ImageContext, Destination, DestinationSize); + if (EFI_ERROR (Status)) { + return Status; + } + + SymbolsPathCpy = NULL; // - // Get PeHeader pointer + // Get File SymbolsPath // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize + ImageContext.PeCoffHeaderOffset); + Status = UefiImageGetSymbolsPath (&ImageContext, &SymbolsPath, &SymbolsPathSize); + if (!RETURN_ERROR (Status)) { + SymbolsPathCpy = malloc (SymbolsPathSize); + if (SymbolsPathCpy == NULL) { + FreeAlignedPages (Destination, DestinationPages); + return EFI_OUT_OF_RESOURCES; + } + + memmove (SymbolsPathCpy, SymbolsPath, SymbolsPathSize); + } + + FreeAlignedPages (Destination, DestinationPages); // - // Calculate the PE32 base address, based on file type + // Calculate the UEFI image base address, based on file type // switch ((*FfsFile)->Type) { case EFI_FV_FILETYPE_SECURITY_CORE: case EFI_FV_FILETYPE_PEI_CORE: case EFI_FV_FILETYPE_PEIM: case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: - // - // Check if section-alignment and file-alignment match or not - // - if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) { - // - // Xip module has the same section alignment and file alignment. - // - Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName); - return EFI_ABORTED; - } - // - // PeImage has no reloc section. It will try to get reloc data from the original EFI image. - // - if (ImageContext.RelocationsStripped) { - // - // Construct the original efi file Name - // - if (strlen (FileName) >= MAX_LONG_FILE_PATH) { - Error (NULL, 0, 2000, "Invalid", "The file name %s is too long.", FileName); - return EFI_ABORTED; - } - strncpy (PeFileName, FileName, MAX_LONG_FILE_PATH - 1); - PeFileName[MAX_LONG_FILE_PATH - 1] = 0; - Cptr = PeFileName + strlen (PeFileName); - while (*Cptr != '.') { - Cptr --; - } - if (*Cptr != '.') { - Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName); - return EFI_ABORTED; - } else { - *(Cptr + 1) = 'e'; - *(Cptr + 2) = 'f'; - *(Cptr + 3) = 'i'; - *(Cptr + 4) = '\0'; - } - PeFile = fopen (LongFilePath (PeFileName), "rb"); - if (PeFile == NULL) { - Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName); - //Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName); - //return EFI_ABORTED; - break; - } - // - // Get the file size - // - PeFileSize = _filelength (fileno (PeFile)); - PeFileBuffer = (UINT8 *) malloc (PeFileSize); - if (PeFileBuffer == NULL) { - fclose (PeFile); - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); - return EFI_OUT_OF_RESOURCES; - } - // - // Read Pe File - // - fread (PeFileBuffer, sizeof (UINT8), PeFileSize, PeFile); - // - // close file - // - fclose (PeFile); - // - // Handle pointer to the original efi image. - // - ImageContext.Handle = PeFileBuffer; - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, (int) Status); - return Status; - } - ImageContext.RelocationsStripped = FALSE; - } - - NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile); - break; - case EFI_FV_FILETYPE_DRIVER: case EFI_FV_FILETYPE_DXE_CORE: - // - // Check if section-alignment and file-alignment match or not - // - if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) { - // - // Xip module has the same section alignment and file alignment. - // - Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName); - return EFI_ABORTED; - } - NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile); + NewBaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile); break; default: @@ -3762,97 +3653,122 @@ Routine Description: return EFI_SUCCESS; } - // - // Relocation doesn't exist - // - if (ImageContext.RelocationsStripped) { - Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName); - continue; - } - - // - // Relocation exist and rebase - // - // - // Load and Relocate Image Data - // - MemoryImagePointer = (UINT8 *) calloc (1, (UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment); - if (MemoryImagePointer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); - return EFI_OUT_OF_RESOURCES; - } - ImageContext.ImageAddress = ALIGN_VALUE ((UINTN)MemoryImagePointer, ImageContext.SectionAlignment); + Strip = UefiImageGetRelocsStripped (&ImageContext); - if (!(IS_ALIGNED (NewPe32BaseAddress, ImageContext.SectionAlignment))) { - Status = AddPadSection (&NewPe32BaseAddress, ImageContext.SectionAlignment, FfsFile, FileSize, &CurrentPe32Section); + if (!(IS_ALIGNED (NewBaseAddress, ImageAlignment))) { + Status = AddPadSection (&NewBaseAddress, ImageAlignment, FfsFile, FileSize, &CurrentPe32Section); if (EFI_ERROR (Status)) { - free ((VOID *) MemoryImagePointer); return Status; } - CurSecHdrSize = GetSectionHeaderLength (CurrentPe32Section.CommonHeader); - ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize); - PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle); + CurSecHdrSize = GetSectionHeaderLength (CurrentPe32Section.CommonHeader); - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize + ImageContext.PeCoffHeaderOffset); + SectPeSize = GetSectionFileLength (CurrentPe32Section.CommonHeader) - CurSecHdrSize; } - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName); - free ((VOID *) MemoryImagePointer); - return Status; - } - - ImageContext.DestinationAddress = NewPe32BaseAddress; + UefiImageFileBuffer = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize); + UefiImageFileSize = SectPeSize; + // + // UefiImage has no reloc section. It will try to get reloc data from the original UEFI image. + // + if (Strip) { + // + // Construct the original efi file Name + // + if (strlen (FileName) >= MAX_LONG_FILE_PATH) { + Error (NULL, 0, 2000, "Invalid", "The file name %s is too long.", FileName); + return EFI_ABORTED; + } + strncpy (UefiImageFileName, FileName, MAX_LONG_FILE_PATH - 1); + UefiImageFileName[MAX_LONG_FILE_PATH - 1] = 0; + Cptr = UefiImageFileName + strlen (UefiImageFileName); + while (*Cptr != '.') { + Cptr --; + } + if (*Cptr != '.') { + Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName); + return EFI_ABORTED; + } else { + *(Cptr + 1) = 'e'; + *(Cptr + 2) = 'f'; + *(Cptr + 3) = 'i'; + *(Cptr + 4) = '\0'; + } + UefiImageFile = fopen (LongFilePath (UefiImageFileName), "rb"); + if (UefiImageFile == NULL) { + Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName); + //Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName); + //return EFI_ABORTED; + break; + } + // + // Get the file size + // + UefiImageFileSize = _filelength (fileno (UefiImageFile)); + UefiImageFileBuffer = (UINT8 *) malloc (UefiImageFileSize); + if (UefiImageFileBuffer == NULL) { + fclose (UefiImageFile); + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); + return EFI_OUT_OF_RESOURCES; + } - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s Status=%d", FileName, Status); - free ((VOID *) MemoryImagePointer); - return Status; + FreeUefiImageFile = TRUE; + // + // Read Pe File + // + fread (UefiImageFileBuffer, sizeof (UINT8), UefiImageFileSize, UefiImageFile); + // + // close file + // + fclose (UefiImageFile); } // - // Copy Relocated data to raw image file. + // Load and Relocate Image Data // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN) ImgHdr + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - - for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - CopyMem ( - (UINT8 *) CurrentPe32Section.Pe32Section + CurSecHdrSize + SectionHeader->PointerToRawData, - (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), - SectionHeader->SizeOfRawData - ); + RebasedImage = ToolImageEmit ( + &RebasedImageSize, + UefiImageFileBuffer, + UefiImageFileSize, + ImageFormat, + -1, + NULL, + 0, + true, + NewBaseAddress, + NULL, + Strip, + FALSE + ); + + if (FreeUefiImageFile) { + free (UefiImageFileBuffer); } - free ((VOID *) MemoryImagePointer); - MemoryImagePointer = NULL; - if (PeFileBuffer != NULL) { - free (PeFileBuffer); - PeFileBuffer = NULL; + if (RebasedImage == NULL) { + Error (NULL, 0, 4001, "Invalid", "failed to rebase (%s)", FileName); + return EFI_UNSUPPORTED; } - // - // Update Image Base Address - // - if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress; - } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress; - } else { - Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s", - ImgHdr->Pe32.OptionalHeader.Magic, - FileName - ); - return EFI_ABORTED; + UefiImageFileBuffer = NULL; + UefiImageFileSize = 0; + + if (RebasedImageSize > SectPeSize) { + Error (NULL, 0, 4001, "Invalid", "rebased file is too large (%s)", FileName); + return EFI_UNSUPPORTED; } + memmove ( + (UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize, + RebasedImage, + RebasedImageSize + ); + memset ( + (UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize + RebasedImageSize, + 0, + SectPeSize - RebasedImageSize + ); + // // Now update file checksum // @@ -3871,14 +3787,25 @@ Routine Description: // Get this module function address from ModulePeMapFile and add them into FvMap file // + Status = UefiImageInitializeContext ( + &ImageContext, + (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize), + RebasedImageSize + ); + ASSERT_EFI_ERROR (Status); + // // Default use FileName as map file path // - if (PdbPointer == NULL) { - PdbPointer = FileName; - } + WriteMapFile ( + FvMapFile, + SymbolsPathCpy != NULL ? SymbolsPathCpy : FileName, + *FfsFile, + NewBaseAddress, + &ImageContext + ); - WriteMapFile (FvMapFile, PdbPointer, *FfsFile, NewPe32BaseAddress, &ImageContext); + free (SymbolsPathCpy); } return EFI_SUCCESS; diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.h b/BaseTools/Source/C/GenFv/GenFvInternalLib.h index dc6b2aca91..ff668f385b 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.h +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.h @@ -22,7 +22,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include #include "CommonLib.h" #include "ParseInf.h" @@ -304,8 +303,9 @@ Routine Description: ; EFI_STATUS -GetPe32Info ( - IN UINT8 *Pe32, +GetUefiImageInfo ( + IN UINT8 *UefiImage, + IN UINT32 UefiImageSize, OUT UINT32 *EntryPoint, OUT UINT16 *MachineType ); diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c index d585d10cd5..3965f9bdac 100644 --- a/BaseTools/Source/C/GenSec/GenSec.c +++ b/BaseTools/Source/C/GenSec/GenSec.c @@ -24,7 +24,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include #include "CommonLib.h" #include "Compress.h" @@ -32,7 +31,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "EfiUtilityMsgs.h" #include "ParseInf.h" #include "FvLib.h" -#include "PeCoffLib.h" // // GenSec Tool Information @@ -1127,104 +1125,6 @@ Routine Description: return EFI_SUCCESS; } -EFI_STATUS -EFIAPI -FfsRebaseImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINT32 *ReadSize, - OUT VOID *Buffer - ) - /*++ - - Routine Description: - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - - Arguments: - - FileHandle - The handle to the PE/COFF file - - FileOffset - The offset, in bytes, into the file to read - - ReadSize - The number of bytes to read from the file starting at FileOffset - - Buffer - A pointer to the buffer to read the data into. - - Returns: - - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - - --*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINT32 Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -GetAlignmentFromFile(char *InFile, UINT32 *Alignment) - /* - InFile is input file for getting alignment - return the alignment - */ -{ - FILE *InFileHandle; - UINT8 *PeFileBuffer; - UINTN PeFileSize; - UINT32 CurSecHdrSize; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - EFI_COMMON_SECTION_HEADER *CommonHeader; - EFI_STATUS Status; - - InFileHandle = NULL; - PeFileBuffer = NULL; - *Alignment = 0; - - memset (&ImageContext, 0, sizeof (ImageContext)); - - InFileHandle = fopen(LongFilePath(InFile), "rb"); - if (InFileHandle == NULL){ - Error (NULL, 0, 0001, "Error opening file", InFile); - return EFI_ABORTED; - } - PeFileSize = _filelength (fileno(InFileHandle)); - PeFileBuffer = (UINT8 *) malloc (PeFileSize); - if (PeFileBuffer == NULL) { - fclose (InFileHandle); - Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile); - return EFI_OUT_OF_RESOURCES; - } - fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle); - fclose (InFileHandle); - CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer; - CurSecHdrSize = GetSectionHeaderLength(CommonHeader); - ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize); - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead; - Status = PeCoffLoaderGetImageInfo(&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status); - return Status; - } - *Alignment = ImageContext.SectionAlignment; - // Free the allocated memory resource - if (PeFileBuffer != NULL) { - free (PeFileBuffer); - PeFileBuffer = NULL; - } - return EFI_SUCCESS; -} - int main ( int argc, diff --git a/BaseTools/Source/C/Include/Common/AutoGen.h b/BaseTools/Source/C/Include/Common/AutoGen.h index 150994a7e1..bf5bc9a063 100644 --- a/BaseTools/Source/C/Include/Common/AutoGen.h +++ b/BaseTools/Source/C/Include/Common/AutoGen.h @@ -1,101 +1,171 @@ -/** @file - AutoGen definitions for edk2 package code consumption in BaseTools. - - Copyright (c) 2023, Marvin Häuser. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _BT_AUTOGENH -#define _BT_AUTOGENH - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -extern GUID gEfiCallerIdGuid; -extern GUID gEdkiiDscPlatformGuid; -extern CHAR8 *gEfiCallerBaseName; - -#define EFI_CALLER_ID_GUID \ - {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} -#define EDKII_DSC_PLATFORM_GUID \ - {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} - -// Definition of SkuId Array -extern UINT64 _gPcd_SkuId_Array[]; - -// Definition of PCDs used in this module - -#define _PCD_TOKEN_PcdMaximumAsciiStringLength 0U -#define _PCD_SIZE_PcdMaximumAsciiStringLength 4 -#define _PCD_GET_MODE_SIZE_PcdMaximumAsciiStringLength _PCD_SIZE_PcdMaximumAsciiStringLength -#define _PCD_VALUE_PcdMaximumAsciiStringLength 0U -#define _PCD_GET_MODE_32_PcdMaximumAsciiStringLength _PCD_VALUE_PcdMaximumAsciiStringLength -//#define _PCD_SET_MODE_32_PcdMaximumAsciiStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdMaximumUnicodeStringLength 0U -#define _PCD_SIZE_PcdMaximumUnicodeStringLength 4 -#define _PCD_GET_MODE_SIZE_PcdMaximumUnicodeStringLength _PCD_SIZE_PcdMaximumUnicodeStringLength -#define _PCD_VALUE_PcdMaximumUnicodeStringLength 0U -#define _PCD_GET_MODE_32_PcdMaximumUnicodeStringLength _PCD_VALUE_PcdMaximumUnicodeStringLength -//#define _PCD_SET_MODE_32_PcdMaximumUnicodeStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdMaximumLinkedListLength 0U -#define _PCD_SIZE_PcdMaximumLinkedListLength 4 -#define _PCD_GET_MODE_SIZE_PcdMaximumLinkedListLength _PCD_SIZE_PcdMaximumLinkedListLength -#define _PCD_VALUE_PcdMaximumLinkedListLength 0U -#define _PCD_GET_MODE_32_PcdMaximumLinkedListLength _PCD_VALUE_PcdMaximumLinkedListLength -//#define _PCD_SET_MODE_32_PcdMaximumLinkedListLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdMaximumDevicePathNodeCount 0U -#define _PCD_SIZE_PcdMaximumDevicePathNodeCount 4 -#define _PCD_GET_MODE_SIZE_PcdMaximumDevicePathNodeCount _PCD_SIZE_PcdMaximumDevicePathNodeCount -#define _PCD_VALUE_PcdMaximumDevicePathNodeCount 0U -#define _PCD_GET_MODE_32_PcdMaximumDevicePathNodeCount _PCD_VALUE_PcdMaximumDevicePathNodeCount -//#define _PCD_SET_MODE_32_PcdMaximumDevicePathNodeCount ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdVerifyNodeInList 0U -#define _PCD_SIZE_PcdVerifyNodeInList 1 -#define _PCD_GET_MODE_SIZE_PcdVerifyNodeInList _PCD_SIZE_PcdVerifyNodeInList -#define _PCD_VALUE_PcdVerifyNodeInList 1U -#define _PCD_GET_MODE_BOOL_PcdVerifyNodeInList _PCD_VALUE_PcdVerifyNodeInList -//#define _PCD_SET_MODE_BOOL_PcdVerifyNodeInList ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdFixedDebugPrintErrorLevel 0U -#define _PCD_SIZE_PcdFixedDebugPrintErrorLevel 4 -#define _PCD_GET_MODE_SIZE_PcdFixedDebugPrintErrorLevel _PCD_SIZE_PcdFixedDebugPrintErrorLevel -#define _PCD_VALUE_PcdFixedDebugPrintErrorLevel 0xFFFFFFFFU -#define _PCD_GET_MODE_32_PcdFixedDebugPrintErrorLevel _PCD_VALUE_PcdFixedDebugPrintErrorLevel -//#define _PCD_SET_MODE_32_PcdFixedDebugPrintErrorLevel ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdDebugPropertyMask 0U -#define _PCD_SIZE_PcdDebugPropertyMask 1 -#define _PCD_GET_MODE_SIZE_PcdDebugPropertyMask _PCD_SIZE_PcdDebugPropertyMask -#define _PCD_VALUE_PcdDebugPropertyMask 0xFFU -#define _PCD_GET_MODE_8_PcdDebugPropertyMask _PCD_VALUE_PcdDebugPropertyMask -//#define _PCD_SET_MODE_8_PcdDebugPropertyMask ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdDebugClearMemoryValue 0U -#define _PCD_SIZE_PcdDebugClearMemoryValue 1 -#define _PCD_GET_MODE_SIZE_PcdDebugClearMemoryValue _PCD_SIZE_PcdDebugClearMemoryValue -#define _PCD_VALUE_PcdDebugClearMemoryValue 0xAFU -#define _PCD_GET_MODE_8_PcdDebugClearMemoryValue _PCD_VALUE_PcdDebugClearMemoryValue -//#define _PCD_SET_MODE_8_PcdDebugClearMemoryValue ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdDebugPrintErrorLevel 0U -#define _PCD_SIZE_PcdDebugPrintErrorLevel 4 -#define _PCD_GET_MODE_SIZE_PcdDebugPrintErrorLevel _PCD_SIZE_PcdDebugPrintErrorLevel -#define _PCD_VALUE_PcdDebugPrintErrorLevel 0x8000004F -#define _PCD_GET_MODE_32_PcdDebugPrintErrorLevel _PCD_VALUE_PcdDebugPrintErrorLevel -//#define _PCD_SET_MODE_32_PcdDebugPrintErrorLevel ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - - -#ifdef __cplusplus -} -#endif - -#endif +/** @file + AutoGen definitions for edk2 package code consumption in BaseTools. + + Copyright (c) 2023, Marvin Häuser. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _BT_AUTOGENH +#define _BT_AUTOGENH + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +extern GUID gEfiCallerIdGuid; +extern GUID gEdkiiDscPlatformGuid; +extern CHAR8 *gEfiCallerBaseName; + +#define EFI_CALLER_ID_GUID \ + {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} +#define EDKII_DSC_PLATFORM_GUID \ + {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} + +// Definition of SkuId Array +extern UINT64 _gPcd_SkuId_Array[]; + +// Definition of PCDs used in this module + +#define _PCD_TOKEN_PcdMaximumAsciiStringLength 0U +#define _PCD_SIZE_PcdMaximumAsciiStringLength 4 +#define _PCD_GET_MODE_SIZE_PcdMaximumAsciiStringLength _PCD_SIZE_PcdMaximumAsciiStringLength +#define _PCD_VALUE_PcdMaximumAsciiStringLength 0U +#define _PCD_GET_MODE_32_PcdMaximumAsciiStringLength _PCD_VALUE_PcdMaximumAsciiStringLength +//#define _PCD_SET_MODE_32_PcdMaximumAsciiStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdMaximumUnicodeStringLength 0U +#define _PCD_SIZE_PcdMaximumUnicodeStringLength 4 +#define _PCD_GET_MODE_SIZE_PcdMaximumUnicodeStringLength _PCD_SIZE_PcdMaximumUnicodeStringLength +#define _PCD_VALUE_PcdMaximumUnicodeStringLength 0U +#define _PCD_GET_MODE_32_PcdMaximumUnicodeStringLength _PCD_VALUE_PcdMaximumUnicodeStringLength +//#define _PCD_SET_MODE_32_PcdMaximumUnicodeStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdMaximumLinkedListLength 0U +#define _PCD_SIZE_PcdMaximumLinkedListLength 4 +#define _PCD_GET_MODE_SIZE_PcdMaximumLinkedListLength _PCD_SIZE_PcdMaximumLinkedListLength +#define _PCD_VALUE_PcdMaximumLinkedListLength 0U +#define _PCD_GET_MODE_32_PcdMaximumLinkedListLength _PCD_VALUE_PcdMaximumLinkedListLength +//#define _PCD_SET_MODE_32_PcdMaximumLinkedListLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdMaximumDevicePathNodeCount 0U +#define _PCD_SIZE_PcdMaximumDevicePathNodeCount 4 +#define _PCD_GET_MODE_SIZE_PcdMaximumDevicePathNodeCount _PCD_SIZE_PcdMaximumDevicePathNodeCount +#define _PCD_VALUE_PcdMaximumDevicePathNodeCount 0U +#define _PCD_GET_MODE_32_PcdMaximumDevicePathNodeCount _PCD_VALUE_PcdMaximumDevicePathNodeCount +//#define _PCD_SET_MODE_32_PcdMaximumDevicePathNodeCount ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdVerifyNodeInList 0U +#define _PCD_SIZE_PcdVerifyNodeInList 1 +#define _PCD_GET_MODE_SIZE_PcdVerifyNodeInList _PCD_SIZE_PcdVerifyNodeInList +#define _PCD_VALUE_PcdVerifyNodeInList 1U +#define _PCD_GET_MODE_BOOL_PcdVerifyNodeInList _PCD_VALUE_PcdVerifyNodeInList +//#define _PCD_SET_MODE_BOOL_PcdVerifyNodeInList ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdFixedDebugPrintErrorLevel 0U +#define _PCD_SIZE_PcdFixedDebugPrintErrorLevel 4 +#define _PCD_GET_MODE_SIZE_PcdFixedDebugPrintErrorLevel _PCD_SIZE_PcdFixedDebugPrintErrorLevel +#define _PCD_VALUE_PcdFixedDebugPrintErrorLevel 0xFFFFFFFFU +#define _PCD_GET_MODE_32_PcdFixedDebugPrintErrorLevel _PCD_VALUE_PcdFixedDebugPrintErrorLevel +//#define _PCD_SET_MODE_32_PcdFixedDebugPrintErrorLevel ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdDebugPropertyMask 0U +#define _PCD_SIZE_PcdDebugPropertyMask 1 +#define _PCD_GET_MODE_SIZE_PcdDebugPropertyMask _PCD_SIZE_PcdDebugPropertyMask +#define _PCD_VALUE_PcdDebugPropertyMask 0xFFU +#define _PCD_GET_MODE_8_PcdDebugPropertyMask _PCD_VALUE_PcdDebugPropertyMask +//#define _PCD_SET_MODE_8_PcdDebugPropertyMask ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdDebugClearMemoryValue 0U +#define _PCD_SIZE_PcdDebugClearMemoryValue 1 +#define _PCD_GET_MODE_SIZE_PcdDebugClearMemoryValue _PCD_SIZE_PcdDebugClearMemoryValue +#define _PCD_VALUE_PcdDebugClearMemoryValue 0xAFU +#define _PCD_GET_MODE_8_PcdDebugClearMemoryValue _PCD_VALUE_PcdDebugClearMemoryValue +//#define _PCD_SET_MODE_8_PcdDebugClearMemoryValue ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdDebugPrintErrorLevel 0U +#define _PCD_SIZE_PcdDebugPrintErrorLevel 4 +#define _PCD_GET_MODE_SIZE_PcdDebugPrintErrorLevel _PCD_SIZE_PcdDebugPrintErrorLevel +#define _PCD_VALUE_PcdDebugPrintErrorLevel 0x8000004F +#define _PCD_GET_MODE_32_PcdDebugPrintErrorLevel _PCD_VALUE_PcdDebugPrintErrorLevel +//#define _PCD_SET_MODE_32_PcdDebugPrintErrorLevel ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderDebugSupport 0U +#define _PCD_SIZE_PcdImageLoaderDebugSupport 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderDebugSupport _PCD_SIZE_PcdImageLoaderDebugSupport +#define _PCD_VALUE_PcdImageLoaderDebugSupport TRUE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderDebugSupport _PCD_VALUE_PcdImageLoaderDebugSupport +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderDebugSupport ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderHashProhibitOverlap 0U +#define _PCD_SIZE_PcdImageLoaderHashProhibitOverlap 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderHashProhibitOverlap _PCD_SIZE_PcdImageLoaderHashProhibitOverlap +#define _PCD_VALUE_PcdImageLoaderHashProhibitOverlap FALSE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderHashProhibitOverlap _PCD_VALUE_PcdImageLoaderHashProhibitOverlap +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderHashProhibitOverlap ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderAllowMisalignedOffset 0U +#define _PCD_SIZE_PcdImageLoaderAllowMisalignedOffset 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderAllowMisalignedOffset _PCD_SIZE_PcdImageLoaderAllowMisalignedOffset +#define _PCD_VALUE_PcdImageLoaderAllowMisalignedOffset FALSE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderAllowMisalignedOffset _PCD_VALUE_PcdImageLoaderAllowMisalignedOffset +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderAllowMisalignedOffset ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderRemoveXForWX 0U +#define _PCD_SIZE_PcdImageLoaderRemoveXForWX 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderRemoveXForWX _PCD_SIZE_PcdImageLoaderRemoveXForWX +#define _PCD_VALUE_PcdImageLoaderRemoveXForWX FALSE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderRemoveXForWX _PCD_VALUE_PcdImageLoaderRemoveXForWX +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderRemoveXForWX ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderWXorX 0U +#define _PCD_SIZE_PcdImageLoaderWXorX 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderWXorX _PCD_SIZE_PcdImageLoaderWXorX +#define _PCD_VALUE_PcdImageLoaderWXorX TRUE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderWXorX _PCD_VALUE_PcdImageLoaderWXorX +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderWXorX ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderLoadHeader 0U +#define _PCD_SIZE_PcdImageLoaderLoadHeader 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderLoadHeader _PCD_SIZE_PcdImageLoaderLoadHeader +#define _PCD_VALUE_PcdImageLoaderLoadHeader TRUE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderLoadHeader _PCD_VALUE_PcdImageLoaderLoadHeader +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderLoadHeader ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderRtRelocAllowTargetMismatch 0U +#define _PCD_SIZE_PcdImageLoaderRtRelocAllowTargetMismatch 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderRtRelocAllowTargetMismatch _PCD_SIZE_PcdImageLoaderRtRelocAllowTargetMismatch +#define _PCD_VALUE_PcdImageLoaderRtRelocAllowTargetMismatch TRUE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderRtRelocAllowTargetMismatch _PCD_VALUE_PcdImageLoaderRtRelocAllowTargetMismatch +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderRtRelocAllowTargetMismatch ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderAlignmentPolicy 0U +#define _PCD_SIZE_PcdImageLoaderAlignmentPolicy 4 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderAlignmentPolicy _PCD_SIZE_PcdImageLoaderAlignmentPolicy +#define _PCD_VALUE_PcdImageLoaderAlignmentPolicy 0U +#define _PCD_GET_MODE_32_PcdImageLoaderAlignmentPolicy _PCD_VALUE_PcdImageLoaderAlignmentPolicy +//#define _PCD_SET_MODE_32_PcdImageLoaderAlignmentPolicy ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderRelocTypePolicy 0U +#define _PCD_SIZE_PcdImageLoaderRelocTypePolicy 4 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderRelocTypePolicy _PCD_SIZE_PcdImageLoaderRelocTypePolicy +#define _PCD_VALUE_PcdImageLoaderRelocTypePolicy 0U +#define _PCD_GET_MODE_32_PcdImageLoaderRelocTypePolicy _PCD_VALUE_PcdImageLoaderRelocTypePolicy +//#define _PCD_SET_MODE_32_PcdImageLoaderRelocTypePolicy ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdDebugRaisePropertyMask 0U +#define _PCD_SIZE_PcdDebugRaisePropertyMask 1 +#define _PCD_GET_MODE_SIZE_PcdDebugRaisePropertyMask _PCD_SIZE_PcdDebugRaisePropertyMask +#define _PCD_VALUE_PcdDebugRaisePropertyMask 0xFFU +#define _PCD_GET_MODE_8_PcdDebugRaisePropertyMask _PCD_VALUE_PcdDebugRaisePropertyMask +//#define _PCD_SET_MODE_8_PcdDebugRaisePropertyMask ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BaseTools/Source/C/Include/Common/PeImageEx.h b/BaseTools/Source/C/Include/Common/PeImageEx.h deleted file mode 100644 index 3e4e129778..0000000000 --- a/BaseTools/Source/C/Include/Common/PeImageEx.h +++ /dev/null @@ -1,59 +0,0 @@ -/** @file - EFI image format for PE32+. Please note some data structures are different - for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64 - - @bug Fix text - doc as defined in MSFT EFI specification. - - Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
- Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
- Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __BT_PE_IMAGE_H__ -#define __BT_PE_IMAGE_H__ - -#include - -// -// PE32+ Machine type for EFI images -// -#define IMAGE_FILE_MACHINE_ARM 0x01c0 -#define IMAGE_FILE_MACHINE_ARMT IMAGE_FILE_MACHINE_ARMTHUMB_MIXED - -// -// Support old names for backward compatible -// -#define EFI_IMAGE_MACHINE_ARMT EFI_IMAGE_MACHINE_ARMTHUMB_MIXED - -#define EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // Supports addresses > 2-GB - -// -// Based export types. -// -#define EFI_IMAGE_EXPORT_ORDINAL_BASE 1 -#define EFI_IMAGE_EXPORT_ADDR_SIZE 4 -#define EFI_IMAGE_EXPORT_ORDINAL_SIZE 2 - -// -// .pdata entries for X64 -// -typedef struct { - UINT32 FunctionStartAddress; - UINT32 FunctionEndAddress; - UINT32 UnwindInfoAddress; -} RUNTIME_FUNCTION; - -typedef struct { - UINT8 Version:3; - UINT8 Flags:5; - UINT8 SizeOfProlog; - UINT8 CountOfUnwindCodes; - UINT8 FrameRegister:4; - UINT8 FrameRegisterOffset:4; -} UNWIND_INFO; - -#endif diff --git a/BaseTools/Source/C/Makefiles/header.makefile b/BaseTools/Source/C/Makefiles/header.makefile index 31f94e9be9..ebf2f573d5 100644 --- a/BaseTools/Source/C/Makefiles/header.makefile +++ b/BaseTools/Source/C/Makefiles/header.makefile @@ -86,7 +86,7 @@ endif INCLUDE = $(TOOL_INCLUDE) -I $(MAKEROOT) -I $(MAKEROOT)/Include/Common -I $(MAKEROOT)/Include/ -I $(MAKEROOT)/Include/IndustryStandard -I $(MAKEROOT)/Common/ -I .. -I . $(ARCH_INCLUDE) -INCLUDE += -I $(EDK2_PATH)/MdePkg/Include/ -I $(EDK2_PATH)/MdeModulePkg/Include/ +INCLUDE += -I $(EDK2_PATH)/MdePkg/Include/ -I $(EDK2_PATH)/MdeModulePkg/Include/ -I $(EDK2_PATH)/OpenCorePkg/User/Include EDK2_INCLUDE = -include $(MAKEROOT)/Include/Common/AutoGen.h diff --git a/BaseTools/Source/C/Makefiles/ms.common b/BaseTools/Source/C/Makefiles/ms.common index 291e8f180c..bd066b9cd3 100644 --- a/BaseTools/Source/C/Makefiles/ms.common +++ b/BaseTools/Source/C/Makefiles/ms.common @@ -86,7 +86,7 @@ LINKER = $(LD) INC = $(INC) -I . -I $(SOURCE_PATH)\Include -I $(ARCH_INCLUDE) -I $(SOURCE_PATH)\Common INC = $(INC) -I $(EDK2_PATH)\MdePkg\Include -INC = $(INC) -I $(EDK2_PATH)\MdePkg\Include -I $(EDK2_PATH)\MdeModulePkg\Include +INC = $(INC) -I $(EDK2_PATH)\MdePkg\Include -I $(EDK2_PATH)\MdeModulePkg\Include -I $(EDK2_PATH)/OpenCorePkg/User/Include EDK2_INC = $(INC) /FI..\Include\Common\AutoGen.h diff --git a/BaseTools/Source/C/Makefiles/ms.rule b/BaseTools/Source/C/Makefiles/ms.rule index 97f43126ad..c00df83714 100644 --- a/BaseTools/Source/C/Makefiles/ms.rule +++ b/BaseTools/Source/C/Makefiles/ms.rule @@ -7,6 +7,10 @@ #DEPFILES = $(OBJECTS:%.o=%.d) +{$(EDK2_PATH)\BaseTools\ImageTool\}.c{$(EDK2_OBJPATH)\BaseTools\ImageTool\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + {$(EDK2_PATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib\}.obj : -@if not exist $(@D)\ mkdir $(@D) $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ @@ -27,6 +31,22 @@ -@if not exist $(@D)\ mkdir $(@D) $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ +{$(EDK2_PATH)\MdePkg\Library\BaseOverflowLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + +{$(EDK2_PATH)\MdePkg\Library\BasePeCoffLib2\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + +{$(EDK2_PATH)\MdePkg\Library\BaseUefiImageLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + +{$(EDK2_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + {$(EDK2_PATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull\}.c{$(EDK2_OBJPATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull\}.obj : -@if not exist $(@D)\ mkdir $(@D) $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ @@ -35,6 +55,10 @@ -@if not exist $(@D)\ mkdir $(@D) $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ +{$(EDK2_PATH)\OpenCorePkg\User\Library\}.c{$(EDK2_OBJPATH)\OpenCorePkg\User\Library\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + .c.obj : $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ diff --git a/BaseTools/Source/C/VolInfo/VolInfo.c b/BaseTools/Source/C/VolInfo/VolInfo.c index 5fe962729f..c16d07ca11 100644 --- a/BaseTools/Source/C/VolInfo/VolInfo.c +++ b/BaseTools/Source/C/VolInfo/VolInfo.c @@ -9,6 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include +#include #include #include #include @@ -24,7 +25,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include #include #include "Compress.h" @@ -37,7 +37,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "ParseGuidedSectionTools.h" #include "StringFuncs.h" #include "ParseInf.h" -#include "PeCoffLib.h" + +#include "../../../ImageTool/ImageToolEmit.h" // // Utility global variables @@ -1417,249 +1418,63 @@ Routine Description: return EFI_SUCCESS; } -EFI_STATUS -EFIAPI -RebaseImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINT32 *ReadSize, - OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - -Arguments: - - FileHandle - The handle to the PE/COFF file - - FileOffset - The offset, in bytes, into the file to read - - ReadSize - The number of bytes to read from the file starting at FileOffset - - Buffer - A pointer to the buffer to read the data into. - -Returns: - - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - ---*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINT32 Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -SetAddressToSectionHeader ( - IN CHAR8 *FileName, - IN OUT UINT8 *FileBuffer, - IN UINT64 NewPe32BaseAddress - ) -/*++ - -Routine Description: - - Set new base address into the section header of PeImage - -Arguments: - - FileName - Name of file - FileBuffer - Pointer to PeImage. - NewPe32BaseAddress - New Base Address for PE image. - -Returns: - - EFI_SUCCESS Set new base address into this image successfully. - ---*/ -{ - EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - UINTN Index; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - - // - // Initialize context - // - memset (&ImageContext, 0, sizeof (ImageContext)); - ImageContext.Handle = (VOID *) FileBuffer; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead; - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName); - return Status; - } - - if (ImageContext.RelocationsStripped) { - Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName); - return Status; - } - - // - // Get PeHeader pointer - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset); - - // - // Get section header list - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN) ImgHdr + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - - // - // Set base address into the first section header that doesn't point to code section. - // - for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) { - *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress; - break; - } - } - - // - // BaseAddress is set to section header. - // - return EFI_SUCCESS; -} - EFI_STATUS RebaseImage ( IN CHAR8 *FileName, IN OUT UINT8 *FileBuffer, - IN UINT64 NewPe32BaseAddress + IN UINT32 FileBufferSize, + IN UINT64 NewBaseAddress ) /*++ Routine Description: - Set new base address into PeImage, and fix up PeImage based on new address. + Set new base address into UefiImage, and fix up UefiImage based on new address. Arguments: FileName - Name of file - FileBuffer - Pointer to PeImage. - NewPe32BaseAddress - New Base Address for PE image. + FileBuffer - Pointer to UefiImage. + NewBaseAddress - New Base Address for UEFI image. Returns: EFI_INVALID_PARAMETER - BaseAddress is not valid. - EFI_SUCCESS - Update PeImage is correctly. + EFI_SUCCESS - Update UefiImage is correctly. --*/ { - EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - UINTN Index; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - UINT8 *MemoryImagePointer; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - - // - // Initialize context - // - memset (&ImageContext, 0, sizeof (ImageContext)); - ImageContext.Handle = (VOID *) FileBuffer; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead; - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName); - return Status; - } + UINT32 RebasedSize; + VOID *RebasedBuffer; + + RebasedBuffer = ToolImageEmit ( + &RebasedSize, + FileBuffer, + FileBufferSize, + -1, + -1, + NULL, + 0, + true, + NewBaseAddress, + NULL, + FALSE, + TRUE + ); + if (RebasedBuffer == NULL) { + Error (NULL, 0, 3000, "Invalid", "The input UefiImage %s is not valid", FileName); + return EFI_UNSUPPORTED; + } + + if (RebasedSize > FileBufferSize) { + Error (NULL, 0, 3000, "Invalid", "Rebased %s too large: %u vs %u", FileName, RebasedSize, FileBufferSize); + return EFI_UNSUPPORTED; + } + + memmove (FileBuffer, RebasedBuffer, RebasedSize); + memset (FileBuffer + RebasedSize, 0, FileBufferSize - RebasedSize); - if (ImageContext.RelocationsStripped) { - Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName); - return Status; - } - - // - // Get PeHeader pointer - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset); - - // - // Load and Relocate Image Data - // - MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); - if (MemoryImagePointer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); - return EFI_OUT_OF_RESOURCES; - } - memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); - ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1)); - - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName); - free ((VOID *) MemoryImagePointer); - return Status; - } - - ImageContext.DestinationAddress = NewPe32BaseAddress; - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName); - free ((VOID *) MemoryImagePointer); - return Status; - } - - // - // Copy Relocated data to raw image file. - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN) ImgHdr + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - - for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - CopyMem ( - FileBuffer + SectionHeader->PointerToRawData, - (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), - SectionHeader->SizeOfRawData - ); - } - - free ((VOID *) MemoryImagePointer); - - // - // Update Image Base Address - // - if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress; - } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress; - } else { - Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s", - ImgHdr->Pe32.OptionalHeader.Magic, - FileName - ); - return EFI_ABORTED; - } - - // - // Set new base address into section header - // - Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress); - - return Status; + return EFI_SUCCESS; } EFI_STATUS @@ -1795,7 +1610,7 @@ Routine Description: if (EnableHash) { ToolInputFileName = "edk2Temp_InputEfi.tmp"; ToolOutputFileName = "edk2Temp_OutputHash.tmp"; - RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, 0); + RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, SectionLength - SectionHeaderLen, 0); PutFileImage ( ToolInputFileName, (CHAR8*)Ptr + SectionHeaderLen, @@ -1830,7 +1645,7 @@ Routine Description: CHAR8 *NewStr; UINT32 nFileLen; if((fp = fopen(ToolOutputFileName,"r")) == NULL) { - Error (NULL, 0, 0004, "Hash the PE32 image failed.", NULL); + Error (NULL, 0, 0004, "Hash the UEFI image failed.", NULL); } else { fseek(fp,0,SEEK_SET); @@ -2517,7 +2332,7 @@ Routine Description: The offset from the start of the input file to start \n\ processing an FV\n"); fprintf (stdout, " --hash\n\ - Generate HASH value of the entire PE image\n"); + Generate HASH value of the entire UEFI image\n"); fprintf (stdout, " --sfo\n\ Reserved for future use\n"); } From 7193c4e313b39af6e3ae582aaaf3a48fa0275676 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 26 Jun 2023 11:32:29 +0300 Subject: [PATCH 070/341] BaseTools: Introduce new HII section design --- BaseTools/Conf/build_rule.template | 43 +---- BaseTools/Conf/tools_def.template | 29 +++- BaseTools/ImageTool/ImageTool.c | 104 ++++++++---- BaseTools/ImageTool/ImageToolEmit.c | 9 - BaseTools/ImageTool/ImageToolEmit.h | 2 - BaseTools/Scripts/Base.lds | 6 +- BaseTools/Scripts/Merge.lds | 6 +- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 2 - BaseTools/Source/C/VolInfo/VolInfo.c | 2 - BaseTools/Source/Python/AutoGen/GenC.py | 8 + .../Source/Python/GenFds/FfsInfStatement.py | 4 +- MdeModulePkg/Logo/Logo.c | 25 +-- .../HiiResourcesSample.c | 20 +-- NetworkPkg/Application/VConfig/VConfig.c | 24 +-- .../LinuxInitrdDynamicShellCommand.c | 23 +-- PrmPkg/Application/PrmInfo/PrmInfo.c | 20 +-- ShellPkg/Application/Shell/ShellManParser.c | 156 ++---------------- ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c | 23 +-- .../DynamicCommand/HttpDynamicCommand/Http.c | 23 +-- .../DynamicCommand/TftpDynamicCommand/Tftp.c | 23 +-- 20 files changed, 144 insertions(+), 408 deletions(-) diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template index a18d3f58a4..a218dad9d8 100755 --- a/BaseTools/Conf/build_rule.template +++ b/BaseTools/Conf/build_rule.template @@ -408,45 +408,6 @@ $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) -[Dynamic-Library-File.UEFI_HII] - - ?.dll - - - $(OUTPUT_DIR)(+)$(MODULE_NAME).efi - $(DEBUG_DIR)(+)$(MODULE_NAME).efi - $(OUTPUT_DIR)(+)$(MODULE_NAME).map - - - $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc - - - ImageTool GenImage -c PE -t $(MODULE_TYPE) -h $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc -o ${dst} ${src} - $(CP) ${dst} $(DEBUG_DIR) - $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi - -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) - -$(CP) $(DEBUG_DIR)(+)*.pdb $(OUTPUT_DIR) - - - $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).strip - $(OBJCOPY) $(OBJCOPY_STRIPFLAG) $(DEBUG_DIR)(+)$(MODULE_NAME).strip - - ImageTool GenImage -c PE -t $(MODULE_TYPE) -h $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).strip - - $(CP) ${dst} $(DEBUG_DIR) - $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi - -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) - - - # tool to convert Mach-O to PE/COFF - "$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff - # create symbol file for GDB debug - -$(DSYMUTIL) ${src} - ImageTool GenImage -c PE -t $(MODULE_TYPE) -h $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff - $(CP) ${dst} $(DEBUG_DIR) - $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi - -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) - [Dependency-Expression-File] ?.dxs, ?.Dxs, ?.DXS @@ -672,7 +633,7 @@ *.hpk - $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc + $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.c - ImageTool HiiBin $(MODULE_GUID) -o $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.rc $(HII_BINARY_PACKAGES) + ImageTool HiiSrc $(MODULE_GUID) -o $(OUTPUT_DIR)(+)$(MODULE_NAME)hii.c $(HII_BINARY_PACKAGES) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index bee52d1cd7..2e55ba9a83 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -27,6 +27,19 @@ IDENTIFIER = Default TOOL_CHAIN_CONF +# +# FIXME: For GCC, the linker script must be utilized to merge image sections. +# Currently, there is no easy way to perform conditional merges due to the lack +# of conditions or preprocessing. +# +!ifdef $(EDK2_SEPARATE_HII) +DEFINE MSFT_HII = +DEFINE XCODE_HII = +!else +DEFINE MSFT_HII = /MERGE:.hii=.rdata +DEFINE XCODE_HII = -rename_section __HII __hii __DATA_CONST __hii +!endif + !ifdef $(EDK2_MERGE_RODATA_INTO_TEXT) DEFINE DLINK_SCRIPT = -Wl,--script=$(EDK_TOOLS_PATH)/Scripts/Merge.lds DEFINE MSFT_MERGE = /MERGE:.rdata=.text @@ -129,7 +142,7 @@ DEFINE MSFT_DEPS_FLAGS = /showIncludes DEFINE MSFT_ASLPP_FLAGS = /nologo /E /C /FIAutoGen.h DEFINE MSFT_ASLCC_FLAGS = /nologo /c /FIAutoGen.h /TC /Dmain=ReferenceAcpiTable DEFINE MSFT_ASLDLINK_FLAGS = /NODEFAULTLIB /ENTRY:ReferenceAcpiTable /SUBSYSTEM:CONSOLE -DEFINE MSFT_DLINK_COMMON = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER DEF(MSFT_ALIGN) DEF(MSFT_MERGE) +DEFINE MSFT_DLINK_COMMON = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER DEF(MSFT_ALIGN) DEF(MSFT_HII) DEF(MSFT_MERGE) DEFINE DTCPP_BIN = ENV(DTCPP_PREFIX)cpp DEFINE DTC_BIN = ENV(DTC_PREFIX)dtc @@ -1923,7 +1936,7 @@ RELEASE_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_DLINK_FLAGS) -fl # image. This also makes the usage of "-read_only_relocs suppress" safe, as # relocations can now target __TEXT without triggering the same issue. # -DEFINE XCODE5_RORELOCS_ARGS = -segprot __RO_RELOCS rw- rw- -segment_order __RO_RELOCS:__TEXT:__DATA_CONST:__DATA -rename_section __TEXT __text __RO_RELOCS __text -rename_section __RO_RELOCS __text __TEXT __text +DEFINE XCODE5_RORELOCS_ARGS = -segprot __RO_RELOCS rw- rw- -segment_order __RO_RELOCS:__TEXT:__DATA_CONST:__DATA:__HII -rename_section __TEXT __text __RO_RELOCS __text -rename_section __RO_RELOCS __text __TEXT __text DEFINE XCODE5_RODATA_ARGS = DEF(XCODE5_RORELOCS_ARGS) -segprot __DATA_CONST r-- r-- -rename_section __DATA __const __DATA_CONST __const -rename_section __TEXT __const __DATA_CONST __text_const -rename_section __TEXT __cstring __DATA_CONST __cstring -rename_section __TEXT __ustring __DATA_CONST __ustring ################## @@ -1946,9 +1959,9 @@ RELEASE_XCODE5_*_MTOC_FLAGS = -align DEF(XCODE_ALIGN) -require_read_only_relocs #################### # IA-32 definitions #################### - DEBUG_XCODE5_IA32_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_MERGE) - NOOPT_XCODE5_IA32_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_MERGE) -RELEASE_XCODE5_IA32_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_MERGE) + DEBUG_XCODE5_IA32_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_HII) DEF(XCODE_MERGE) + NOOPT_XCODE5_IA32_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_HII) DEF(XCODE_MERGE) +RELEASE_XCODE5_IA32_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_HII) DEF(XCODE_MERGE) *_XCODE5_IA32_SLINK_FLAGS = -static -o DEBUG_XCODE5_IA32_ASM_FLAGS = -arch i386 -g @@ -1964,9 +1977,9 @@ RELEASE_XCODE5_IA32_CC_FLAGS = -arch i386 -c -Os -Wall -Werror -inclu ################## # X64 definitions ################## - DEBUG_XCODE5_X64_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_MERGE) - NOOPT_XCODE5_X64_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_MERGE) -RELEASE_XCODE5_X64_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_MERGE) + DEBUG_XCODE5_X64_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_HII) DEF(XCODE_MERGE) + NOOPT_XCODE5_X64_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_HII) DEF(XCODE_MERGE) +RELEASE_XCODE5_X64_DLINK_FLAGS = DEF(XCODE5_RODATA_ARGS) -arch x86_64 -u _$(IMAGE_ENTRY_POINT) -e _$(IMAGE_ENTRY_POINT) -preload -segalign DEF(XCODE_ALIGN) -pie -all_load -dead_strip -seg1addr DEF(XCODE_ADDR) -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map DEF(XCODE_HII) DEF(XCODE_MERGE) *_XCODE5_X64_SLINK_FLAGS = -static -o DEBUG_XCODE5_X64_ASM_FLAGS = -arch x86_64 -g diff --git a/BaseTools/ImageTool/ImageTool.c b/BaseTools/ImageTool/ImageTool.c index 866a369a9a..4a39ab3cab 100644 --- a/BaseTools/ImageTool/ImageTool.c +++ b/BaseTools/ImageTool/ImageTool.c @@ -16,9 +16,14 @@ #define EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x0 +#define DO_NOT_EDIT_HEADER \ + "//\n" \ + "// DO NOT EDIT -- auto-generated file\n" \ + "//\n" + static RETURN_STATUS -HiiBin ( +HiiSrc ( IN const char *HiiName, IN const char *Guid, IN const char *FileNames[], @@ -29,6 +34,8 @@ HiiBin ( void *Hii; UINT32 HiiSize; GUID HiiGuid; + FILE *FilePtr; + UINT32 Index; assert (FileNames != NULL); assert (HiiName != NULL); @@ -42,11 +49,69 @@ HiiBin ( Status = ConstructHii (FileNames, NumOfFiles, &HiiGuid, &Hii, &HiiSize); if (RETURN_ERROR (Status)) { - fprintf (stderr, "ImageTool: Could not construct HiiBin\n"); + fprintf (stderr, "ImageTool: Could not construct HiiSrc\n"); return Status; } - UserWriteFile (HiiName, Hii, HiiSize); + FilePtr = fopen (HiiName, "w"); + if (FilePtr == NULL) { + free (Hii); + return RETURN_NO_MEDIA; + } + + fprintf ( + FilePtr, + DO_NOT_EDIT_HEADER + "\n" + "#include \"AutoGen.h\"\n" + "\n" + "typedef struct {\n" + " UINT32 Size;\n" + " UINT8 Data[%u];\n" + "} MODULE_HII_PACKAGE_LIST_%u;\n" + "\n" + "STATIC_ASSERT (\n" + " OFFSET_OF (MODULE_HII_PACKAGE_LIST_%u, Size) == OFFSET_OF (MODULE_HII_PACKAGE_LIST, Size) &&\n" + " OFFSET_OF (MODULE_HII_PACKAGE_LIST_%u, Data) == OFFSET_OF (MODULE_HII_PACKAGE_LIST, Header) &&\n" + " sizeof (MODULE_HII_PACKAGE_LIST) == sizeof (UINT32) + sizeof (EFI_HII_PACKAGE_LIST_HEADER),\n" + " \"MODULE_HII_PACKAGE_LIST does not have the expected structure.\"\n" + " );\n" + "\n" + "#if defined (__APPLE__)\n" + "__attribute__ ((section (\"__HII,__hii\")))\n" + "#elif defined (__GNUC__) || defined (__clang__)\n" + "__attribute__ ((section (\".hii\")))\n" + "#elif defined (_MSC_EXTENSIONS)\n" + "#pragma section (\".hii\", read)\n" + "__declspec (allocate(\".hii\"))\n" + "#endif\n" + "STATIC CONST MODULE_HII_PACKAGE_LIST_%u mModuleHiiPackageList = {\n" + " %u,\n" + " {", + HiiSize, + HiiSize, + HiiSize, + HiiSize, + HiiSize, + HiiSize + ); + + for (Index = 0; Index < HiiSize; ++Index) { + if (Index % 12 == 0) { + fprintf (FilePtr, "\n "); + } + fprintf (FilePtr, " 0x%02X,", ((const uint8_t *)Hii)[Index]); + } + + fprintf ( + FilePtr, + "\n" + " }\n" + "};\n" + "\n" + "GLOBAL_REMOVE_IF_UNREFERENCED CONST MODULE_HII_PACKAGE_LIST *gModuleHiiPackageList =\n" + " (CONST MODULE_HII_PACKAGE_LIST *)&mModuleHiiPackageList;\n" + ); free (Hii); @@ -290,7 +355,6 @@ GenExecutable ( IN const char *InputFileName, IN const char *FormatName, IN const char *TypeName, - IN const char *HiiFileName, IN const char *BaseAddress, IN bool Strip, IN bool FixedAddress @@ -300,8 +364,6 @@ GenExecutable ( VOID *InputFile; int8_t Format; int32_t Type; - UINT32 HiiFileSize; - VOID *HiiFile; RETURN_STATUS Status; UINT64 NewBaseAddress; void *OutputFile; @@ -340,24 +402,12 @@ GenExecutable ( return RETURN_ABORTED; } - HiiFile = NULL; - HiiFileSize = 0; - if (HiiFileName != NULL) { - HiiFile = UserReadFile (HiiFileName, &HiiFileSize); - if (HiiFile == NULL) { - fprintf (stderr, "ImageTool: Could not open %s: %s\n", HiiFileName, strerror (errno)); - return RETURN_ABORTED; - } - } - OutputFile = ToolImageEmit ( &OutputFileSize, InputFile, InputFileSize, Format, Type, - HiiFile, - HiiFileSize, BaseAddress != NULL, NewBaseAddress, InputFileName, @@ -366,7 +416,6 @@ GenExecutable ( ); if (OutputFile == NULL) { - free (HiiFile); return RETURN_ABORTED; } @@ -385,7 +434,6 @@ int main (int argc, const char *argv[]) const char *InputName; const char *FormatName; const char *TypeName; - const char *HiiFileName; const char *BaseAddress; bool Strip; bool FixedAddress; @@ -404,7 +452,7 @@ int main (int argc, const char *argv[]) if (strcmp (argv[1], "GenImage") == 0) { if (argc < 5) { fprintf (stderr, "ImageTool: Command arguments are missing\n"); - fprintf (stderr, " Usage: ImageTool GenImage [-c Format] [-t ModuleType] [-h HiiRc] [-b BaseAddress] [-s] [-f] -o OutputFile InputFile\n"); + fprintf (stderr, " Usage: ImageTool GenImage [-c Format] [-t ModuleType] [-b BaseAddress] [-s] [-f] -o OutputFile InputFile\n"); raise (); return -1; } @@ -413,7 +461,6 @@ int main (int argc, const char *argv[]) InputName = NULL; FormatName = NULL; TypeName = NULL; - HiiFileName = NULL; BaseAddress = NULL; Strip = false; FixedAddress = false; @@ -442,14 +489,6 @@ int main (int argc, const char *argv[]) } TypeName = argv[ArgIndex]; - } else if (strcmp (argv[ArgIndex], "-h") == 0) { - ++ArgIndex; - if (ArgIndex == argc) { - fprintf (stderr, "Must specify an argument to -h\n"); - return -1; - } - - HiiFileName = argv[ArgIndex]; } else if (strcmp (argv[ArgIndex], "-b") == 0) { ++ArgIndex; if (ArgIndex == argc) { @@ -487,7 +526,6 @@ int main (int argc, const char *argv[]) InputName, FormatName, TypeName, - HiiFileName, BaseAddress, Strip, FixedAddress @@ -496,7 +534,7 @@ int main (int argc, const char *argv[]) raise (); return -1; } - } else if (strcmp (argv[1], "HiiBin") == 0) { + } else if (strcmp (argv[1], "HiiSrc") == 0) { if (argc < 5 || strcmp (argv[3], "-o") != 0) { fprintf (stderr, "ImageTool: Command arguments are missing\n"); fprintf (stderr, " Usage: ImageTool HiiBin GUID -o OutputFile InputFile1 InputFile2 ...\n"); @@ -506,7 +544,7 @@ int main (int argc, const char *argv[]) NumOfFiles = (UINT32)argc - 5U; - Status = HiiBin (argv[4], argv[2], &argv[5], NumOfFiles); + Status = HiiSrc (argv[4], argv[2], &argv[5], NumOfFiles); if (RETURN_ERROR (Status)) { raise (); return -1; diff --git a/BaseTools/ImageTool/ImageToolEmit.c b/BaseTools/ImageTool/ImageToolEmit.c index 338ac0fce2..043e949dc2 100644 --- a/BaseTools/ImageTool/ImageToolEmit.c +++ b/BaseTools/ImageTool/ImageToolEmit.c @@ -91,8 +91,6 @@ ToolImageEmit ( IN uint32_t BufferSize, IN int8_t Format, IN int32_t Type, - IN void *HiiFile, - IN uint32_t HiiFileSize, IN bool Relocate, IN uint64_t BaseAddress, IN const char *SymbolsPath OPTIONAL, @@ -136,13 +134,6 @@ ToolImageEmit ( ImageInfo.HeaderInfo.Subsystem = (uint16_t)Type; } - if (HiiFile != NULL) { - free (ImageInfo.HiiInfo.Data); - - ImageInfo.HiiInfo.Data = HiiFile; - ImageInfo.HiiInfo.DataSize = HiiFileSize; - } - ToolImageSortRelocs (&ImageInfo); Success = CheckToolImage (&ImageInfo); diff --git a/BaseTools/ImageTool/ImageToolEmit.h b/BaseTools/ImageTool/ImageToolEmit.h index 6bf7493f3f..ae803fcd3a 100644 --- a/BaseTools/ImageTool/ImageToolEmit.h +++ b/BaseTools/ImageTool/ImageToolEmit.h @@ -17,8 +17,6 @@ ToolImageEmit ( IN uint32_t BufferSize, IN int8_t Format, IN int32_t Type, - IN void *HiiFile, - IN uint32_t HiiFileSize, IN bool Relocate, IN uint64_t BaseAddress, IN const char *SymbolsPath OPTIONAL, diff --git a/BaseTools/Scripts/Base.lds b/BaseTools/Scripts/Base.lds index 8823db55c2..b8318facdb 100644 --- a/BaseTools/Scripts/Base.lds +++ b/BaseTools/Scripts/Base.lds @@ -20,7 +20,7 @@ SECTIONS { } .rodata : ALIGN(CONSTANT(MAXPAGESIZE)) { - *(.rodata .rodata.* .data.rel.ro .data.rel.ro.* .gnu.linkonce.r.*) + *(.rodata .rodata.* .data.rel.ro .data.rel.ro.* .gnu.linkonce.r.* .hii) *(.got .got.*) /* @@ -39,10 +39,6 @@ SECTIONS { *(.bss .bss.*) } - .hii : ALIGN(CONSTANT(MAXPAGESIZE)) { - KEEP (*(.hii)) - } - .eh_frame : ALIGN(CONSTANT(MAXPAGESIZE)) { KEEP (*(.eh_frame)) } diff --git a/BaseTools/Scripts/Merge.lds b/BaseTools/Scripts/Merge.lds index d9514283a9..6a4a75cccf 100644 --- a/BaseTools/Scripts/Merge.lds +++ b/BaseTools/Scripts/Merge.lds @@ -17,7 +17,7 @@ SECTIONS { .text : ALIGN(CONSTANT(MAXPAGESIZE)) { *(.text .text.* .stub .gnu.linkonce.t.*) - *(.rodata .rodata.* .data.rel.ro .data.rel.ro.* .gnu.linkonce.r.*) + *(.rodata .rodata.* .data.rel.ro .data.rel.ro.* .gnu.linkonce.r.* .hii) *(.got .got.*) /* @@ -36,10 +36,6 @@ SECTIONS { *(.bss .bss.*) } - .hii : ALIGN(CONSTANT(MAXPAGESIZE)) { - KEEP (*(.hii)) - } - .eh_frame : ALIGN(CONSTANT(MAXPAGESIZE)) { KEEP (*(.eh_frame)) } diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 091d469890..3584552e99 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -3732,8 +3732,6 @@ Routine Description: UefiImageFileSize, ImageFormat, -1, - NULL, - 0, true, NewBaseAddress, NULL, diff --git a/BaseTools/Source/C/VolInfo/VolInfo.c b/BaseTools/Source/C/VolInfo/VolInfo.c index c16d07ca11..d36b1c83e9 100644 --- a/BaseTools/Source/C/VolInfo/VolInfo.c +++ b/BaseTools/Source/C/VolInfo/VolInfo.c @@ -1453,8 +1453,6 @@ Routine Description: FileBufferSize, -1, -1, - NULL, - 0, true, NewBaseAddress, NULL, diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py index 86991e7675..feea54492a 100755 --- a/BaseTools/Source/Python/AutoGen/GenC.py +++ b/BaseTools/Source/Python/AutoGen/GenC.py @@ -1994,6 +1994,14 @@ def CreateHeaderCode(Info, AutoGenC, AutoGenH): AutoGenH.Append('\nextern GUID gEdkiiDscPlatformGuid;') AutoGenH.Append('\nextern CHAR8 *gEfiCallerBaseName;\n\n') + if Info.BuildType == 'UEFI_HII': + AutoGenH.Append('typedef struct {\n') + AutoGenH.Append(' UINT32 Size;\n') + AutoGenH.Append(' EFI_HII_PACKAGE_LIST_HEADER Header;\n') + AutoGenH.Append('} MODULE_HII_PACKAGE_LIST;\n') + + AutoGenH.Append('\nextern CONST MODULE_HII_PACKAGE_LIST *gModuleHiiPackageList;\n\n') + if Info.IsLibrary: return diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py index b68f363b39..6fdb295441 100644 --- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -789,7 +789,7 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): if not os.path.exists(FileBeforeStrip) or \ (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): CopyLongFilePath(File, FileBeforeStrip) - StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') + StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stripped') GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, File, @@ -823,7 +823,7 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)): CopyLongFilePath(GenSecInputFile, FileBeforeStrip) - StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') + StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stripped') GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, GenSecInputFile, diff --git a/MdeModulePkg/Logo/Logo.c b/MdeModulePkg/Logo/Logo.c index 8ab874d2da..90e32c7165 100644 --- a/MdeModulePkg/Logo/Logo.c +++ b/MdeModulePkg/Logo/Logo.c @@ -99,10 +99,9 @@ InitializeLogo ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; - EFI_HII_PACKAGE_LIST_HEADER *PackageList; - EFI_HII_DATABASE_PROTOCOL *HiiDatabase; - EFI_HANDLE Handle; + EFI_STATUS Status; + EFI_HII_DATABASE_PROTOCOL *HiiDatabase; + EFI_HANDLE Handle; Status = gBS->LocateProtocol ( &gEfiHiiDatabaseProtocolGuid, @@ -118,28 +117,12 @@ InitializeLogo ( ); ASSERT_EFI_ERROR (Status); - // - // Retrieve HII package list from ImageHandle - // - Status = gBS->OpenProtocol ( - ImageHandle, - &gEfiHiiPackageListProtocolGuid, - (VOID **)&PackageList, - ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "HII Image Package with logo not found in PE/COFF resource section\n")); - return Status; - } - // // Publish HII package list to HII Database. // Status = HiiDatabase->NewPackageList ( HiiDatabase, - PackageList, + &gModuleHiiPackageList->Header, NULL, &mHiiHandle ); diff --git a/MdeModulePkg/Universal/HiiResourcesSampleDxe/HiiResourcesSample.c b/MdeModulePkg/Universal/HiiResourcesSampleDxe/HiiResourcesSample.c index dd0ae5001d..6a3fc2273d 100644 --- a/MdeModulePkg/Universal/HiiResourcesSampleDxe/HiiResourcesSample.c +++ b/MdeModulePkg/Universal/HiiResourcesSampleDxe/HiiResourcesSample.c @@ -67,23 +67,7 @@ HiiResourcesSampleInit ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; - EFI_HII_PACKAGE_LIST_HEADER *PackageList; - - // - // Retrieve HII package list from ImageHandle - // - Status = gBS->OpenProtocol ( - ImageHandle, - &gEfiHiiPackageListProtocolGuid, - (VOID **)&PackageList, - ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } + EFI_STATUS Status; // // Publish sample Fromset @@ -103,7 +87,7 @@ HiiResourcesSampleInit ( // Status = gHiiDatabase->NewPackageList ( gHiiDatabase, - PackageList, + &gModuleHiiPackageList->Header, mDriverHandle, &mHiiHandle ); diff --git a/NetworkPkg/Application/VConfig/VConfig.c b/NetworkPkg/Application/VConfig/VConfig.c index 2c323e377b..8004f5380f 100644 --- a/NetworkPkg/Application/VConfig/VConfig.c +++ b/NetworkPkg/Application/VConfig/VConfig.c @@ -606,34 +606,18 @@ VlanConfigMain ( IN EFI_SYSTEM_TABLE *SystemTable ) { - LIST_ENTRY *List; - CONST CHAR16 *Str; - EFI_HII_PACKAGE_LIST_HEADER *PackageList; - EFI_STATUS Status; + LIST_ENTRY *List; + CONST CHAR16 *Str; + EFI_STATUS Status; mImageHandle = ImageHandle; - // - // Retrieve HII package list from ImageHandle - // - Status = gBS->OpenProtocol ( - ImageHandle, - &gEfiHiiPackageListProtocolGuid, - (VOID **)&PackageList, - ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } - // // Publish HII package list to HII Database. // Status = gHiiDatabase->NewPackageList ( gHiiDatabase, - PackageList, + &gModuleHiiPackageList->Header, NULL, &mHiiHandle ); diff --git a/OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.c b/OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.c index 2edd92c754..f548ca85ce 100644 --- a/OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.c +++ b/OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.c @@ -441,32 +441,15 @@ InitializeHiiPackage ( EFI_HANDLE ImageHandle ) { - EFI_STATUS Status; - EFI_HII_PACKAGE_LIST_HEADER *PackageList; - EFI_HII_HANDLE HiiHandle; - - // - // Retrieve HII package list from ImageHandle - // - Status = gBS->OpenProtocol ( - ImageHandle, - &gEfiHiiPackageListProtocolGuid, - (VOID **)&PackageList, - ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - return NULL; - } + EFI_STATUS Status; + EFI_HII_HANDLE HiiHandle; // // Publish HII package list to HII Database. // Status = gHiiDatabase->NewPackageList ( gHiiDatabase, - PackageList, + &gModuleHiiPackageList->Header, NULL, &HiiHandle ); diff --git a/PrmPkg/Application/PrmInfo/PrmInfo.c b/PrmPkg/Application/PrmInfo/PrmInfo.c index d7ce0d03be..27e6ffda7a 100644 --- a/PrmPkg/Application/PrmInfo/PrmInfo.c +++ b/PrmPkg/Application/PrmInfo/PrmInfo.c @@ -678,30 +678,14 @@ UefiMain ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; - EFI_HII_PACKAGE_LIST_HEADER *PackageList; - - // - // Retrieve the HII package list from ImageHandle - // - Status = gBS->OpenProtocol ( - ImageHandle, - &gEfiHiiPackageListProtocolGuid, - (VOID **)&PackageList, - ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } + EFI_STATUS Status; // // Publish the HII package list to the HII Database // Status = gHiiDatabase->NewPackageList ( gHiiDatabase, - PackageList, + &gModuleHiiPackageList->Header, NULL, &mPrmInfoHiiHandle ); diff --git a/ShellPkg/Application/Shell/ShellManParser.c b/ShellPkg/Application/Shell/ShellManParser.c index f7082467c7..06993d994e 100644 --- a/ShellPkg/Application/Shell/ShellManParser.c +++ b/ShellPkg/Application/Shell/ShellManParser.c @@ -561,19 +561,14 @@ ProcessManFile ( OUT CHAR16 **HelpText ) { - CHAR16 *TempString; - SHELL_FILE_HANDLE FileHandle; - EFI_HANDLE CmdFileImgHandle; - EFI_STATUS Status; - UINTN HelpSize; - UINTN BriefSize; - UINTN StringIdWalker; - BOOLEAN Ascii; - CHAR16 *CmdFileName; - CHAR16 *CmdFilePathName; - EFI_DEVICE_PATH_PROTOCOL *FileDevPath; - EFI_DEVICE_PATH_PROTOCOL *DevPath; - EFI_HII_PACKAGE_LIST_HEADER *PackageListHeader; + CHAR16 *TempString; + SHELL_FILE_HANDLE FileHandle; + EFI_STATUS Status; + UINTN HelpSize; + UINTN BriefSize; + BOOLEAN Ascii; + EFI_DEVICE_PATH_PROTOCOL *FileDevPath; + EFI_DEVICE_PATH_PROTOCOL *DevPath; if ( (ManFileName == NULL) || (Command == NULL) @@ -583,17 +578,12 @@ ProcessManFile ( return (EFI_INVALID_PARAMETER); } - HelpSize = 0; - BriefSize = 0; - StringIdWalker = 0; - TempString = NULL; - Ascii = FALSE; - CmdFileName = NULL; - CmdFilePathName = NULL; - CmdFileImgHandle = NULL; - PackageListHeader = NULL; - FileDevPath = NULL; - DevPath = NULL; + HelpSize = 0; + BriefSize = 0; + TempString = NULL; + Ascii = FALSE; + FileDevPath = NULL; + DevPath = NULL; // // See if it's in HII first @@ -662,118 +652,6 @@ ProcessManFile ( goto Done; } } - - // - // Load the app image to check EFI_HII_PACKAGE_LIST_PROTOCOL. - // - CmdFileName = GetExecuatableFileName (TempString); - if (CmdFileName == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - // - // If the file in CWD then use the file name, else use the full - // path name. - // - CmdFilePathName = ShellFindFilePath (CmdFileName); - if (CmdFilePathName == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - - DevPath = ShellInfoObject.NewEfiShellProtocol->GetDevicePathFromFilePath (CmdFilePathName); - Status = gBS->LoadImage (FALSE, gImageHandle, DevPath, NULL, 0, &CmdFileImgHandle); - if (EFI_ERROR (Status)) { - // - // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created - // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now. - // If the caller doesn't have the option to defer the execution of an image, we should - // unload image for the EFI_SECURITY_VIOLATION to avoid the resource leak. - // - if (Status == EFI_SECURITY_VIOLATION) { - gBS->UnloadImage (CmdFileImgHandle); - } - - *HelpText = NULL; - goto Done; - } - - Status = gBS->OpenProtocol ( - CmdFileImgHandle, - &gEfiHiiPackageListProtocolGuid, - (VOID **)&PackageListHeader, - gImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - *HelpText = NULL; - goto Done; - } - - // - // If get package list on image handle, install it on HiiDatabase. - // - Status = gBS->InstallProtocolInterface ( - &mShellManDriverHandle, - &gEfiDevicePathProtocolGuid, - EFI_NATIVE_INTERFACE, - &mShellManHiiDevicePath - ); - if (EFI_ERROR (Status)) { - goto Done; - } - - Status = gHiiDatabase->NewPackageList ( - gHiiDatabase, - PackageListHeader, - mShellManDriverHandle, - &mShellManHiiHandle - ); - if (EFI_ERROR (Status)) { - goto Done; - } - - StringIdWalker = 1; - do { - SHELL_FREE_NON_NULL (TempString); - if (BriefDesc != NULL) { - SHELL_FREE_NON_NULL (*BriefDesc); - } - - TempString = HiiGetString (mShellManHiiHandle, (EFI_STRING_ID)StringIdWalker, NULL); - if (TempString == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - - FileHandle = ConvertEfiFileProtocolToShellHandle (CreateFileInterfaceMem (TRUE), NULL); - if (FileHandle == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - HelpSize = StrLen (TempString) * sizeof (CHAR16); - ShellWriteFile (FileHandle, &HelpSize, TempString); - ShellSetFilePosition (FileHandle, 0); - HelpSize = 0; - BriefSize = 0; - Status = ManFileFindTitleSection (FileHandle, Command, BriefDesc, &BriefSize, &Ascii); - if (!EFI_ERROR (Status) && (HelpText != NULL)) { - Status = ManFileFindSections (FileHandle, Sections, HelpText, &HelpSize, Ascii); - } - - ShellCloseFile (&FileHandle); - if (!EFI_ERROR (Status)) { - // - // Found what we need and return - // - goto Done; - } - - StringIdWalker += 1; - } while (StringIdWalker < 0xFFFF && TempString != NULL); } Done: @@ -791,13 +669,7 @@ ProcessManFile ( mShellManHiiHandle = NULL; } - if (CmdFileImgHandle != NULL) { - Status = gBS->UnloadImage (CmdFileImgHandle); - } - SHELL_FREE_NON_NULL (TempString); - SHELL_FREE_NON_NULL (CmdFileName); - SHELL_FREE_NON_NULL (CmdFilePathName); SHELL_FREE_NON_NULL (FileDevPath); SHELL_FREE_NON_NULL (DevPath); diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c index 98c84d2ef9..1db179a3ef 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c @@ -993,32 +993,15 @@ InitializeHiiPackage ( EFI_HANDLE ImageHandle ) { - EFI_STATUS Status; - EFI_HII_PACKAGE_LIST_HEADER *PackageList; - EFI_HII_HANDLE HiiHandle; - - // - // Retrieve HII package list from ImageHandle - // - Status = gBS->OpenProtocol ( - ImageHandle, - &gEfiHiiPackageListProtocolGuid, - (VOID **)&PackageList, - ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - return NULL; - } + EFI_STATUS Status; + EFI_HII_HANDLE HiiHandle; // // Publish HII package list to HII Database. // Status = gHiiDatabase->NewPackageList ( gHiiDatabase, - PackageList, + &gModuleHiiPackageList->Header, NULL, &HiiHandle ); diff --git a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c index d67f9af3b7..bd98923371 100644 --- a/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c +++ b/ShellPkg/DynamicCommand/HttpDynamicCommand/Http.c @@ -1870,32 +1870,15 @@ InitializeHiiPackage ( IN EFI_HANDLE ImageHandle ) { - EFI_STATUS Status; - EFI_HII_PACKAGE_LIST_HEADER *PackageList; - EFI_HII_HANDLE HiiHandle; - - // - // Retrieve HII package list from ImageHandle. - // - Status = gBS->OpenProtocol ( - ImageHandle, - &gEfiHiiPackageListProtocolGuid, - (VOID **)&PackageList, - ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - return NULL; - } + EFI_STATUS Status; + EFI_HII_HANDLE HiiHandle; // // Publish HII package list to HII Database. // Status = gHiiDatabase->NewPackageList ( gHiiDatabase, - PackageList, + &gModuleHiiPackageList->Header, NULL, &HiiHandle ); diff --git a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c index a60d6be2d6..3a72a549df 100644 --- a/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c +++ b/ShellPkg/DynamicCommand/TftpDynamicCommand/Tftp.c @@ -1214,32 +1214,15 @@ InitializeHiiPackage ( EFI_HANDLE ImageHandle ) { - EFI_STATUS Status; - EFI_HII_PACKAGE_LIST_HEADER *PackageList; - EFI_HII_HANDLE HiiHandle; - - // - // Retrieve HII package list from ImageHandle - // - Status = gBS->OpenProtocol ( - ImageHandle, - &gEfiHiiPackageListProtocolGuid, - (VOID **)&PackageList, - ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - return NULL; - } + EFI_STATUS Status; + EFI_HII_HANDLE HiiHandle; // // Publish HII package list to HII Database. // Status = gHiiDatabase->NewPackageList ( gHiiDatabase, - PackageList, + &gModuleHiiPackageList->Header, NULL, &HiiHandle ); From a759ddb400b021e85052b944dca33062a1c0e658 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 7 Apr 2025 12:20:19 +0300 Subject: [PATCH 071/341] BaseTools/Conf/tools_def.template: Added -Wno-maybe-uninitialized to fix gcc-12.3.0 compilation. --- BaseTools/Conf/tools_def.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index 2e55ba9a83..45a68c7ed2 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -931,7 +931,7 @@ NOOPT_VS2022_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF *_*_*_DTC_PATH = DEF(DTC_BIN) # All supported GCC archs except LOONGARCH64 support -mstack-protector-guard=global, so set that on everything except LOONGARCH64 -DEFINE GCC_ALL_CC_FLAGS = -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -fno-common -fstack-protector +DEFINE GCC_ALL_CC_FLAGS = -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -Wno-maybe-uninitialized -include AutoGen.h -fno-common -fstack-protector DEFINE GCC_IA32_X64_CC_FLAGS = -mstack-protector-guard=global DEFINE GCC_ARM_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -march=armv7-a -mthumb -mlittle-endian -mabi=aapcs -fno-short-enums -funsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -Wno-address -fno-pic -fno-pie -mstack-protector-guard=global DEFINE GCC_LOONGARCH64_CC_FLAGS = DEF(GCC_ALL_CC_FLAGS) -mabi=lp64d -fno-asynchronous-unwind-tables -Wno-address -fno-short-enums -fsigned-char -ffunction-sections -fdata-sections From 20dd836214276e86898ac325a29e4464ca5121e3 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 7 Apr 2025 12:23:28 +0300 Subject: [PATCH 072/341] MdeModulePkg/Core/Dxe: Integrate CPU Architectural producer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3223 In the current design, memory protection is not available till CpuDxe is loaded. To resolve this, introduce CpuArchLib to move the CPU Architectural initialization to DxeCore. Cc: Eric Dong Cc: Ray Ni Cc: Laszlo Ersek Cc: Rahul Kumar Cc: Vitaly Cheptsov Signed-off-by: Marvin Häuser --- ArmPkg/ArmPkg.dsc | 3 +- .../CpuArchLib}/AArch64/Mmu.c | 0 .../CpuDxe => Library/CpuArchLib}/Arm/Mmu.c | 0 .../CpuArchLib/CpuArchLib.inf} | 12 +- .../CpuDxe => Library/CpuArchLib}/CpuDxe.c | 16 +- .../CpuDxe => Library/CpuArchLib}/CpuDxe.h | 0 .../CpuArchLib}/CpuMmuCommon.c | 0 .../CpuDxe => Library/CpuArchLib}/Exception.c | 0 .../CpuArchLib}/MemoryAttribute.c | 0 ArmVirtPkg/ArmVirt.dsc.inc | 1 + ArmVirtPkg/ArmVirtCloudHv.dsc | 4 +- ArmVirtPkg/ArmVirtCloudHv.fdf | 1 - ArmVirtPkg/ArmVirtKvmTool.dsc | 4 +- ArmVirtPkg/ArmVirtKvmTool.fdf | 1 - ArmVirtPkg/ArmVirtQemu.dsc | 4 +- ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 1 - ArmVirtPkg/ArmVirtQemuKernel.dsc | 4 +- ArmVirtPkg/ArmVirtXen.dsc | 4 +- ArmVirtPkg/ArmVirtXen.fdf | 1 - MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c | 2 +- MdeModulePkg/Core/Dxe/DxeMain.h | 26 +-- MdeModulePkg/Core/Dxe/DxeMain.inf | 2 + MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 176 +++++++++--------- .../Core/Dxe/DxeMain/DxeProtocolNotify.c | 6 +- MdeModulePkg/Core/Dxe/Gcd/Gcd.c | 14 +- MdeModulePkg/Core/Dxe/Hand/Handle.c | 2 +- MdeModulePkg/Core/Dxe/Image/Image.c | 6 +- MdeModulePkg/Core/Dxe/Mem/Page.c | 2 +- MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c | 2 +- .../Core/Dxe/Misc/InstallConfigurationTable.c | 34 ++-- .../DxeCoreDxeServicesTableLib.c | 48 +++++ .../DxeCoreDxeServicesTableLib.inf | 40 ++++ .../DxeCoreDxeServicesTableLib.uni | 13 ++ .../DxeCoreUefiBootServicesTableLib.c | 44 +++++ .../DxeCoreUefiBootServicesTableLib.inf | 34 ++++ .../DxeCoreUefiBootServicesTableLib.uni | 13 ++ .../DxeCoreUefiRuntimeServicesTableLib.c | 39 ++++ .../DxeCoreUefiRuntimeServicesTableLib.inf | 35 ++++ .../DxeCoreUefiRuntimeServicesTableLib.uni | 13 ++ MdeModulePkg/MdeModulePkg.dsc | 20 +- OvmfPkg/Include/Library/PlatformInitLib.h | 3 + OvmfPkg/IntelTdx/IntelTdxX64.dsc | 28 +-- OvmfPkg/IntelTdx/IntelTdxX64.fdf | 3 - OvmfPkg/OvmfPkgIa32.dsc | 6 +- OvmfPkg/OvmfPkgIa32.fdf | 1 - OvmfPkg/OvmfPkgIa32X64.dsc | 6 +- OvmfPkg/OvmfPkgIa32X64.fdf | 1 - OvmfPkg/OvmfPkgX64.dsc | 28 +-- OvmfPkg/OvmfPkgX64.fdf | 3 - OvmfPkg/PlatformPei/AmdSev.c | 6 + OvmfPkg/PlatformPei/IntelTdx.c | 9 +- OvmfPkg/PlatformPei/Platform.c | 2 +- OvmfPkg/PlatformPei/Platform.h | 2 +- UefiCpuPkg/CpuDxe/CpuDxe.uni | 16 -- UefiCpuPkg/Include/Library/CpuArchLib.h | 31 +++ .../CpuArchLib/CpuArchLib.inf} | 18 +- UefiCpuPkg/Library/CpuArchLib/CpuArchLib.uni | 13 ++ .../Library/CpuArchLib/CpuArchLibNull.inf | 24 +++ .../{CpuDxe => Library/CpuArchLib}/CpuDxe.c | 35 ++-- .../{CpuDxe => Library/CpuArchLib}/CpuDxe.h | 6 +- .../CpuArchLib}/CpuDxeExtra.uni | 4 +- UefiCpuPkg/Library/CpuArchLib/CpuDxeNull.c | 25 +++ .../{CpuDxe => Library/CpuArchLib}/CpuGdt.c | 0 .../{CpuDxe => Library/CpuArchLib}/CpuGdt.h | 0 .../{CpuDxe => Library/CpuArchLib}/CpuMp.c | 0 .../{CpuDxe => Library/CpuArchLib}/CpuMp.h | 9 - .../CpuArchLib}/CpuPageTable.c | 12 +- .../CpuArchLib}/CpuPageTable.h | 0 .../CpuArchLib}/Ia32/CpuAsm.nasm | 0 .../CpuArchLib}/Ia32/PagingAttribute.c | 0 .../CpuArchLib}/LoongArch64/CpuDxe.c | 0 .../CpuArchLib}/LoongArch64/CpuDxe.h | 0 .../CpuArchLib}/LoongArch64/CpuMp.c | 0 .../CpuArchLib}/LoongArch64/Exception.c | 0 .../CpuArchLib}/X64/CpuAsm.nasm | 0 .../CpuArchLib}/X64/PagingAttribute.c | 0 UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf | 8 +- UefiCpuPkg/Library/MpInitLib/MpLib.c | 32 ++-- UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf | 6 +- UefiCpuPkg/UefiCpuPkg.dec | 4 + UefiCpuPkg/UefiCpuPkg.dsc | 7 +- UefiPayloadPkg/UefiPayloadPkg.dsc | 6 +- UefiPayloadPkg/UefiPayloadPkg.fdf | 1 - 83 files changed, 678 insertions(+), 304 deletions(-) rename ArmPkg/{Drivers/CpuDxe => Library/CpuArchLib}/AArch64/Mmu.c (100%) rename ArmPkg/{Drivers/CpuDxe => Library/CpuArchLib}/Arm/Mmu.c (100%) rename ArmPkg/{Drivers/CpuDxe/CpuDxe.inf => Library/CpuArchLib/CpuArchLib.inf} (78%) rename ArmPkg/{Drivers/CpuDxe => Library/CpuArchLib}/CpuDxe.c (95%) rename ArmPkg/{Drivers/CpuDxe => Library/CpuArchLib}/CpuDxe.h (100%) rename ArmPkg/{Drivers/CpuDxe => Library/CpuArchLib}/CpuMmuCommon.c (100%) rename ArmPkg/{Drivers/CpuDxe => Library/CpuArchLib}/Exception.c (100%) rename ArmPkg/{Drivers/CpuDxe => Library/CpuArchLib}/MemoryAttribute.c (100%) create mode 100644 MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.c create mode 100644 MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf create mode 100644 MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.uni create mode 100644 MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.c create mode 100644 MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf create mode 100644 MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.uni create mode 100644 MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.c create mode 100644 MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf create mode 100644 MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.uni delete mode 100644 UefiCpuPkg/CpuDxe/CpuDxe.uni create mode 100644 UefiCpuPkg/Include/Library/CpuArchLib.h rename UefiCpuPkg/{CpuDxe/CpuDxe.inf => Library/CpuArchLib/CpuArchLib.inf} (81%) create mode 100644 UefiCpuPkg/Library/CpuArchLib/CpuArchLib.uni create mode 100644 UefiCpuPkg/Library/CpuArchLib/CpuArchLibNull.inf rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/CpuDxe.c (94%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/CpuDxe.h (94%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/CpuDxeExtra.uni (77%) create mode 100644 UefiCpuPkg/Library/CpuArchLib/CpuDxeNull.c rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/CpuGdt.c (100%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/CpuGdt.h (100%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/CpuMp.c (100%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/CpuMp.h (97%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/CpuPageTable.c (95%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/CpuPageTable.h (100%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/Ia32/CpuAsm.nasm (100%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/Ia32/PagingAttribute.c (100%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/LoongArch64/CpuDxe.c (100%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/LoongArch64/CpuDxe.h (100%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/LoongArch64/CpuMp.c (100%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/LoongArch64/Exception.c (100%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/X64/CpuAsm.nasm (100%) rename UefiCpuPkg/{CpuDxe => Library/CpuArchLib}/X64/PagingAttribute.c (100%) diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 8fb18bd32d..87653c4427 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -57,6 +57,7 @@ PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf + CpuArchLib|ArmPkg/Library/CpuArchLib/CpuArchLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf @@ -118,8 +119,8 @@ ArmPkg/Library/SemiHostingSerialPortLib/SemiHostingSerialPortLib.inf ArmPkg/Library/SemihostLib/SemihostLib.inf ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf + ArmPkg/Library/CpuArchLib/CpuArchLib.inf - ArmPkg/Drivers/CpuDxe/CpuDxe.inf ArmPkg/Drivers/CpuPei/CpuPei.inf ArmPkg/Drivers/ArmGicDxe/ArmGicDxe.inf ArmPkg/Drivers/ArmGicDxe/ArmGicV2Dxe.inf diff --git a/ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c b/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c similarity index 100% rename from ArmPkg/Drivers/CpuDxe/AArch64/Mmu.c rename to ArmPkg/Library/CpuArchLib/AArch64/Mmu.c diff --git a/ArmPkg/Drivers/CpuDxe/Arm/Mmu.c b/ArmPkg/Library/CpuArchLib/Arm/Mmu.c similarity index 100% rename from ArmPkg/Drivers/CpuDxe/Arm/Mmu.c rename to ArmPkg/Library/CpuArchLib/Arm/Mmu.c diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf b/ArmPkg/Library/CpuArchLib/CpuArchLib.inf similarity index 78% rename from ArmPkg/Drivers/CpuDxe/CpuDxe.inf rename to ArmPkg/Library/CpuArchLib/CpuArchLib.inf index 9e6b8805af..3284522a6f 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuDxe.inf +++ b/ArmPkg/Library/CpuArchLib/CpuArchLib.inf @@ -1,6 +1,6 @@ #/** @file # -# DXE CPU driver +# This library installs CPU Architecture Protocol # # Copyright (c) 2009, Apple Inc. All rights reserved.
# Copyright (c) 2011-2013, ARM Limited. All rights reserved. @@ -11,12 +11,11 @@ [Defines] INF_VERSION = 0x00010005 - BASE_NAME = ArmCpuDxe - FILE_GUID = B8D9777E-D72A-451F-9BDB-BAFB52A68415 - MODULE_TYPE = DXE_DRIVER + BASE_NAME = CpuArchLib + FILE_GUID = 47EE96CC-33FA-482B-8AD6-DD8C21AA3752 + MODULE_TYPE = DXE_CORE VERSION_STRING = 1.0 - - ENTRY_POINT = CpuDxeInitialize + LIBRARY_CLASS = CpuArchLib [Sources.Common] CpuDxe.c @@ -49,7 +48,6 @@ DxeServicesTableLib HobLib MemoryAllocationLib - UefiDriverEntryPoint UefiLib [Protocols] diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.c b/ArmPkg/Library/CpuArchLib/CpuDxe.c similarity index 95% rename from ArmPkg/Drivers/CpuDxe/CpuDxe.c rename to ArmPkg/Library/CpuArchLib/CpuDxe.c index 39e5e9beea..4dd428d9c5 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuDxe.c +++ b/ArmPkg/Library/CpuArchLib/CpuDxe.c @@ -395,9 +395,8 @@ HardwareInterruptProtocolNotify ( } EFI_STATUS -CpuDxeInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable +InitializeCpu ( + VOID ) { EFI_STATUS Status; @@ -475,3 +474,14 @@ CpuDxeInitialize ( return EFI_SUCCESS; } + +/** + Initialize Multi-processor support. + +**/ +VOID +InitializeMpSupport ( + VOID + ) +{ +} diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/ArmPkg/Library/CpuArchLib/CpuDxe.h similarity index 100% rename from ArmPkg/Drivers/CpuDxe/CpuDxe.h rename to ArmPkg/Library/CpuArchLib/CpuDxe.h diff --git a/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c b/ArmPkg/Library/CpuArchLib/CpuMmuCommon.c similarity index 100% rename from ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c rename to ArmPkg/Library/CpuArchLib/CpuMmuCommon.c diff --git a/ArmPkg/Drivers/CpuDxe/Exception.c b/ArmPkg/Library/CpuArchLib/Exception.c similarity index 100% rename from ArmPkg/Drivers/CpuDxe/Exception.c rename to ArmPkg/Library/CpuArchLib/Exception.c diff --git a/ArmPkg/Drivers/CpuDxe/MemoryAttribute.c b/ArmPkg/Library/CpuArchLib/MemoryAttribute.c similarity index 100% rename from ArmPkg/Drivers/CpuDxe/MemoryAttribute.c rename to ArmPkg/Library/CpuArchLib/MemoryAttribute.c diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index c8250dc264..2d23a9ec78 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -236,6 +236,7 @@ MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf + CpuArchLib|ArmPkg/Library/CpuArchLib/CpuArchLib.inf [LibraryClasses.common.DXE_DRIVER] SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf diff --git a/ArmVirtPkg/ArmVirtCloudHv.dsc b/ArmVirtPkg/ArmVirtCloudHv.dsc index ca1aa13e1f..100e688020 100644 --- a/ArmVirtPkg/ArmVirtCloudHv.dsc +++ b/ArmVirtPkg/ArmVirtCloudHv.dsc @@ -235,6 +235,9 @@ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + DxeServicesTableLib|MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf + UefiBootServicesTableLib|MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf } MdeModulePkg/Universal/PCD/Dxe/Pcd.inf { @@ -244,7 +247,6 @@ # # Architectural Protocols # - ArmPkg/Drivers/CpuDxe/CpuDxe.inf MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { diff --git a/ArmVirtPkg/ArmVirtCloudHv.fdf b/ArmVirtPkg/ArmVirtCloudHv.fdf index 7bad8ed0b2..d3cb55de2f 100644 --- a/ArmVirtPkg/ArmVirtCloudHv.fdf +++ b/ArmVirtPkg/ArmVirtCloudHv.fdf @@ -112,7 +112,6 @@ READ_LOCK_STATUS = TRUE # # PI DXE Drivers producing Architectural Protocols (EFI Services) # - INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc index 278ec1b629..c12f48c5af 100644 --- a/ArmVirtPkg/ArmVirtKvmTool.dsc +++ b/ArmVirtPkg/ArmVirtKvmTool.dsc @@ -260,6 +260,9 @@ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + DxeServicesTableLib|MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf + UefiBootServicesTableLib|MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf } MdeModulePkg/Universal/PCD/Dxe/Pcd.inf { @@ -269,7 +272,6 @@ # # Architectural Protocols # - ArmPkg/Drivers/CpuDxe/CpuDxe.inf MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { diff --git a/ArmVirtPkg/ArmVirtKvmTool.fdf b/ArmVirtPkg/ArmVirtKvmTool.fdf index b20ef9c844..32583d4126 100644 --- a/ArmVirtPkg/ArmVirtKvmTool.fdf +++ b/ArmVirtPkg/ArmVirtKvmTool.fdf @@ -127,7 +127,6 @@ READ_LOCK_STATUS = TRUE # # PI DXE Drivers producing Architectural Protocols (EFI Services) # - INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 6193a4bb05..98a1a3ae1f 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -368,6 +368,9 @@ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + DxeServicesTableLib|MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf + UefiBootServicesTableLib|MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf } MdeModulePkg/Universal/PCD/Dxe/Pcd.inf { @@ -377,7 +380,6 @@ # # Architectural Protocols # - ArmPkg/Drivers/CpuDxe/CpuDxe.inf MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc index 622409af8a..7d6d05acf4 100644 --- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc +++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc @@ -47,7 +47,6 @@ READ_LOCK_STATUS = TRUE # # PI DXE Drivers producing Architectural Protocols (EFI Services) # - INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc index 61d2536123..ba1f75b6e0 100644 --- a/ArmVirtPkg/ArmVirtQemuKernel.dsc +++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc @@ -290,6 +290,9 @@ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + DxeServicesTableLib|MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf + UefiBootServicesTableLib|MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf } MdeModulePkg/Universal/PCD/Dxe/Pcd.inf { @@ -299,7 +302,6 @@ # # Architectural Protocols # - ArmPkg/Drivers/CpuDxe/CpuDxe.inf MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc index 1df6dca23f..27378a049d 100644 --- a/ArmVirtPkg/ArmVirtXen.dsc +++ b/ArmVirtPkg/ArmVirtXen.dsc @@ -163,6 +163,9 @@ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + DxeServicesTableLib|MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf + UefiBootServicesTableLib|MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf } MdeModulePkg/Universal/PCD/Dxe/Pcd.inf { @@ -172,7 +175,6 @@ # # Architectural Protocols # - ArmPkg/Drivers/CpuDxe/CpuDxe.inf MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf diff --git a/ArmVirtPkg/ArmVirtXen.fdf b/ArmVirtPkg/ArmVirtXen.fdf index d149f9b6d5..fb1a5219ff 100644 --- a/ArmVirtPkg/ArmVirtXen.fdf +++ b/ArmVirtPkg/ArmVirtXen.fdf @@ -144,7 +144,6 @@ READ_LOCK_STATUS = TRUE # # PI DXE Drivers producing Architectural Protocols (EFI Services) # - INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf diff --git a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c index cf9d556877..6bd35b9d3d 100644 --- a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c +++ b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c @@ -453,7 +453,7 @@ CoreDispatcher ( DEBUG ((DEBUG_INFO, "Loading driver %g\n", &DriverEntry->FileName)); Status = CoreLoadImage ( FALSE, - gDxeCoreImageHandle, + gImageHandle, DriverEntry->FvFileDevicePath, NULL, 0, diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 9ebbd2b853..deb3ced94c 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -85,6 +85,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include // // attributes for reserved memory before it is promoted to system memory @@ -232,14 +233,14 @@ typedef struct { // // DXE Core Global Variables // -extern EFI_SYSTEM_TABLE *gDxeCoreST; -extern EFI_RUNTIME_SERVICES *gDxeCoreRT; -extern EFI_DXE_SERVICES *gDxeCoreDS; -extern EFI_HANDLE gDxeCoreImageHandle; +extern EFI_SYSTEM_TABLE *gST; +extern EFI_RUNTIME_SERVICES *gRT; +extern EFI_DXE_SERVICES *gDS; +extern EFI_HANDLE gImageHandle; -extern BOOLEAN gMemoryMapTerminated; +extern BOOLEAN gMemoryMapTerminated; -extern EFI_DECOMPRESS_PROTOCOL gEfiDecompress; +extern EFI_DECOMPRESS_PROTOCOL gEfiDecompress; extern EFI_RUNTIME_ARCH_PROTOCOL *gRuntime; extern EFI_CPU_ARCH_PROTOCOL *gCpu; @@ -251,20 +252,21 @@ extern EFI_SECURITY2_ARCH_PROTOCOL *gSecurity2; extern EFI_BDS_ARCH_PROTOCOL *gBds; extern EFI_SMM_BASE2_PROTOCOL *gSmmBase2; -extern EFI_TPL gEfiCurrentTpl; +extern EFI_TPL gEfiCurrentTpl; -extern EFI_GUID *gDxeCoreFileName; -extern EFI_LOADED_IMAGE_PROTOCOL *gDxeCoreLoadedImage; +extern EFI_GUID *gDxeCoreFileName; +extern EFI_LOADED_IMAGE_PROTOCOL *gDxeCoreLoadedImage; -extern EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1]; +extern EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1]; -extern BOOLEAN gDispatcherRunning; -extern EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate; +extern BOOLEAN gDispatcherRunning; +extern EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate; extern BOOLEAN gMemoryAttributesTableForwardCfi; extern EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE gLoadModuleAtFixAddressConfigurationTable; extern BOOLEAN gLoadFixedAddressCodeMemoryReady; +extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage; // // Service Initialization Functions // diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 4f20d6420f..bb64caad50 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -71,6 +71,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses] BaseMemoryLib @@ -95,6 +96,7 @@ PcdLib ImagePropertiesRecordLib OrderedCollectionLib + CpuArchLib [Guids] gEfiEventMemoryMapChangeGuid ## PRODUCES ## Event diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index da8d411d9b..7d700055c3 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -120,28 +120,6 @@ EFI_DXE_SERVICES mDxeServices = { (EFI_SET_MEMORY_SPACE_CAPABILITIES)CoreSetMemorySpaceCapabilities, // SetMemorySpaceCapabilities }; -EFI_SYSTEM_TABLE mEfiSystemTableTemplate = { - { - EFI_SYSTEM_TABLE_SIGNATURE, // Signature - EFI_SYSTEM_TABLE_REVISION, // Revision - sizeof (EFI_SYSTEM_TABLE), // HeaderSize - 0, // CRC32 - 0 // Reserved - }, - NULL, // FirmwareVendor - 0, // FirmwareRevision - NULL, // ConsoleInHandle - NULL, // ConIn - NULL, // ConsoleOutHandle - NULL, // ConOut - NULL, // StandardErrorHandle - NULL, // StdErr - NULL, // RuntimeServices - &mBootServices, // BootServices - 0, // NumberOfConfigurationTableEntries - NULL // ConfigurationTable -}; - EFI_RUNTIME_SERVICES mEfiRuntimeServicesTableTemplate = { { EFI_RUNTIME_SERVICES_SIGNATURE, // Signature @@ -166,6 +144,28 @@ EFI_RUNTIME_SERVICES mEfiRuntimeServicesTableTemplate = { (EFI_QUERY_VARIABLE_INFO)CoreEfiNotAvailableYetArg4 // QueryVariableInfo }; +EFI_SYSTEM_TABLE mEfiSystemTableTemplate = { + { + EFI_SYSTEM_TABLE_SIGNATURE, // Signature + EFI_SYSTEM_TABLE_REVISION, // Revision + sizeof (EFI_SYSTEM_TABLE), // HeaderSize + 0, // CRC32 + 0 // Reserved + }, + NULL, // FirmwareVendor + 0, // FirmwareRevision + NULL, // ConsoleInHandle + NULL, // ConIn + NULL, // ConsoleOutHandle + NULL, // ConOut + NULL, // StandardErrorHandle + NULL, // StdErr + &mEfiRuntimeServicesTableTemplate, // RuntimeServices + &mBootServices, // BootServices + 0, // NumberOfConfigurationTableEntries + NULL // ConfigurationTable +}; + EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate = { INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.ImageHead), INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.EventHead), @@ -190,18 +190,19 @@ EFI_RUNTIME_ARCH_PROTOCOL *gRuntime = &gRuntimeTemplate; // DXE Core Global Variables for the EFI System Table, Boot Services Table, // DXE Services Table, and Runtime Services Table // -EFI_DXE_SERVICES *gDxeCoreDS = &mDxeServices; -EFI_SYSTEM_TABLE *gDxeCoreST = NULL; +EFI_DXE_SERVICES *gDS = &mDxeServices; +EFI_BOOT_SERVICES *gBS = &mBootServices; +EFI_SYSTEM_TABLE *gST = &mEfiSystemTableTemplate; // -// For debug initialize gDxeCoreRT to template. gDxeCoreRT must be allocated from RT memory -// but gDxeCoreRT is used for ASSERT () and DEBUG () type macros so lets give it +// For debug initialize gRT to template. gRT must be allocated from RT memory +// but gRT is used for ASSERT () and DEBUG () type macros so lets give it // a value that will not cause debug infrastructure to crash early on. // -EFI_RUNTIME_SERVICES *gDxeCoreRT = &mEfiRuntimeServicesTableTemplate; -EFI_HANDLE gDxeCoreImageHandle = NULL; +EFI_RUNTIME_SERVICES *gRT = &mEfiRuntimeServicesTableTemplate; +EFI_HANDLE gImageHandle = NULL; -BOOLEAN gMemoryMapTerminated = FALSE; +BOOLEAN gMemoryMapTerminated = FALSE; static BOOLEAN mExitBootServicesCalled = FALSE; @@ -245,18 +246,6 @@ DxeMain ( EFI_VECTOR_HANDOFF_INFO *VectorInfoList; EFI_VECTOR_HANDOFF_INFO *VectorInfo; - // - // Setup the default exception handlers - // - VectorInfoList = NULL; - GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart); - if (GuidHob != NULL) { - VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *)(GET_GUID_HOB_DATA (GuidHob)); - } - - Status = InitializeCpuExceptionHandlers (VectorInfoList); - ASSERT_EFI_ERROR (Status); - // // Setup Stack Guard // @@ -299,26 +288,63 @@ DxeMain ( // Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData // Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table // - gDxeCoreST = AllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate); - ASSERT (gDxeCoreST != NULL); + gST = AllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate); + ASSERT (gST != NULL); + + gRT = AllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate); + ASSERT (gRT != NULL); - gDxeCoreRT = AllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate); - ASSERT (gDxeCoreRT != NULL); + gST->RuntimeServices = gRT; - gDxeCoreST->RuntimeServices = gDxeCoreRT; + // + // Install the DXE Services Table into the EFI System Tables's Configuration Table + // + Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDS); + ASSERT_EFI_ERROR (Status); // // Update DXE Core Loaded Image Protocol with allocated UEFI System Table // - gDxeCoreLoadedImage->SystemTable = gDxeCoreST; + gDxeCoreLoadedImage->SystemTable = gST; + + // + // Initialize the Event Services + // + Status = CoreInitializeEventServices (); + ASSERT_EFI_ERROR (Status); + + // + // Register for the GUIDs of the Architectural Protocols, so the rest of the + // EFI Boot Services and EFI Runtime Services tables can be filled in. + // Also register for the GUIDs of optional protocols. + // + CoreNotifyOnProtocolInstallation (); + + // + // Initialize CPU Architectural Protocol + // + InitializeCpu (); + + MemoryProfileInstallProtocol (); + + CoreInitializeMemoryAttributesTable (); + + CoreInitializeMemoryProtection (); + + ProtectUefiImage (mCurrentImage, &ImageContext); // // Call constructor for all libraries // - ProcessLibraryConstructorList (gDxeCoreImageHandle, gDxeCoreST); + ProcessLibraryConstructorList (gImageHandle, gST); PERF_CROSSMODULE_END ("PEI"); PERF_CROSSMODULE_BEGIN ("DXE"); + // + // Initialize Multi-processor support + // + InitializeMpSupport (); + // // Log MemoryBaseAddress and MemoryLength again (from // CoreInitializeMemoryServices()), now that library constructors have @@ -338,12 +364,6 @@ DxeMain ( // UefiImageLoaderRelocateImageExtraAction (&ImageContext); - // - // Install the DXE Services Table into the EFI System Tables's Configuration Table - // - Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDxeCoreDS); - ASSERT_EFI_ERROR (Status); - // // Install the HOB List into the EFI System Tables's Configuration Table // @@ -383,7 +403,7 @@ DxeMain ( CoreNewDebugImageInfoEntry ( EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, gDxeCoreLoadedImage, - gDxeCoreImageHandle, + gImageHandle, &ImageContext ); @@ -447,26 +467,11 @@ DxeMain ( DEBUG_CODE_END (); - // - // Initialize the Event Services - // - Status = CoreInitializeEventServices (); - ASSERT_EFI_ERROR (Status); - - // - // Give the debug agent a chance to initialize with events. - // - InitializeDebugAgent (DEBUG_AGENT_INIT_DXE_CORE_LATE, HobStart, NULL); - - MemoryProfileInstallProtocol (); - - CoreInitializeMemoryAttributesTable (); - CoreInitializeMemoryProtection (); - // // Get persisted vector hand-off info from GUIDeed HOB again due to HobStart may be updated, // and install configuration table // + VectorInfoList = NULL; GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart); if (GuidHob != NULL) { VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *)(GET_GUID_HOB_DATA (GuidHob)); @@ -506,26 +511,19 @@ DxeMain ( ); ASSERT_EFI_ERROR (Status); - // - // Register for the GUIDs of the Architectural Protocols, so the rest of the - // EFI Boot Services and EFI Runtime Services tables can be filled in. - // Also register for the GUIDs of optional protocols. - // - CoreNotifyOnProtocolInstallation (); - // // Produce Firmware Volume Protocols, one for each FV in the HOB list. // - Status = FwVolBlockDriverInit (gDxeCoreImageHandle, gDxeCoreST); + Status = FwVolBlockDriverInit (gImageHandle, gST); ASSERT_EFI_ERROR (Status); - Status = FwVolDriverInit (gDxeCoreImageHandle, gDxeCoreST); + Status = FwVolDriverInit (gImageHandle, gST); ASSERT_EFI_ERROR (Status); // // Produce the Section Extraction Protocol // - Status = InitializeSectionExtraction (gDxeCoreImageHandle, gDxeCoreST); + Status = InitializeSectionExtraction (gImageHandle, gST); ASSERT_EFI_ERROR (Status); // @@ -827,18 +825,18 @@ CoreExitBootServices ( // // Clear the non-runtime values of the EFI System Table // - gDxeCoreST->BootServices = NULL; - gDxeCoreST->ConIn = NULL; - gDxeCoreST->ConsoleInHandle = NULL; - gDxeCoreST->ConOut = NULL; - gDxeCoreST->ConsoleOutHandle = NULL; - gDxeCoreST->StdErr = NULL; - gDxeCoreST->StandardErrorHandle = NULL; + gST->BootServices = NULL; + gST->ConIn = NULL; + gST->ConsoleInHandle = NULL; + gST->ConOut = NULL; + gST->ConsoleOutHandle = NULL; + gST->StdErr = NULL; + gST->StandardErrorHandle = NULL; // // Recompute the 32-bit CRC of the EFI System Table // - CalculateEfiHdrCrc (&gDxeCoreST->Hdr); + CalculateEfiHdrCrc (&gST->Hdr); // // Zero out the Boot Service Table diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c index 3fe02940ed..1f85d33f97 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c @@ -194,10 +194,10 @@ GenericProtocolNotify ( // // It's over kill to do them all every time, but it saves a lot of code. // - CalculateEfiHdrCrc (&gDxeCoreRT->Hdr); + CalculateEfiHdrCrc (&gRT->Hdr); CalculateEfiHdrCrc (&gBS->Hdr); - CalculateEfiHdrCrc (&gDxeCoreST->Hdr); - CalculateEfiHdrCrc (&gDxeCoreDS->Hdr); + CalculateEfiHdrCrc (&gST->Hdr); + CalculateEfiHdrCrc (&gDS->Hdr); } /** diff --git a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c index 6ea89fbc8b..6ddbe60f07 100644 --- a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c +++ b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c @@ -1498,7 +1498,7 @@ CoreAddMemorySpace ( EFI_PAGE_SHIFT, PageLength, &PageBaseAddress, - gDxeCoreImageHandle, + gImageHandle, NULL ); @@ -1517,7 +1517,7 @@ CoreAddMemorySpace ( EFI_PAGE_SHIFT, EFI_PAGE_SIZE, &PageBaseAddress, - gDxeCoreImageHandle, + gImageHandle, NULL ); @@ -2735,7 +2735,7 @@ CoreInitializeGcdServices ( 0, MemoryLength, &MemoryBaseAddress, - gDxeCoreImageHandle, + gImageHandle, NULL ); } @@ -2756,7 +2756,7 @@ CoreInitializeGcdServices ( 0, MemoryHob->AllocDescriptor.MemoryLength, &BaseAddress, - gDxeCoreImageHandle, + gImageHandle, NULL ); if (!EFI_ERROR (Status) && @@ -2782,7 +2782,7 @@ CoreInitializeGcdServices ( 0, FirmwareVolumeHob->Length, &BaseAddress, - gDxeCoreImageHandle, + gImageHandle, NULL ); } @@ -2830,7 +2830,7 @@ CoreInitializeGcdServices ( 0, Length, &BaseAddress, - gDxeCoreImageHandle, + gImageHandle, NULL ); } @@ -2872,7 +2872,7 @@ CoreInitializeGcdServices ( 0, Length, &BaseAddress, - gDxeCoreImageHandle, + gImageHandle, NULL ); } diff --git a/MdeModulePkg/Core/Dxe/Hand/Handle.c b/MdeModulePkg/Core/Dxe/Hand/Handle.c index 93e69eea73..4a0f83ff2e 100644 --- a/MdeModulePkg/Core/Dxe/Hand/Handle.c +++ b/MdeModulePkg/Core/Dxe/Hand/Handle.c @@ -1047,7 +1047,7 @@ CoreHandleProtocol ( UserHandle, Protocol, Interface, - gDxeCoreImageHandle, + gImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL ); diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 948d3478ee..30a290572f 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -271,7 +271,7 @@ CoreInitializeImageServices ( // // Fill in DXE globals // - gDxeCoreImageHandle = Image->Handle; + gImageHandle = Image->Handle; gDxeCoreLoadedImage = &Image->Info; // @@ -298,8 +298,6 @@ CoreInitializeImageServices ( InitializeListHead (&mAvailableEmulators); - ProtectUefiImage (Image, ImageContext); - return Status; } @@ -1285,7 +1283,7 @@ CoreLoadImageCommon ( // Initialize the fields for an internal driver // Image->Signature = LOADED_IMAGE_PRIVATE_DATA_SIGNATURE; - Image->Info.SystemTable = gDxeCoreST; + Image->Info.SystemTable = gST; Image->Info.DeviceHandle = DeviceHandle; Image->Info.Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; Image->Info.FilePath = DuplicateDevicePath (FilePath); diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index e4daa741b9..15c93ba5ef 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -419,7 +419,7 @@ PromoteMemoryResource ( } Entry->Capabilities |= EFI_MEMORY_TESTED; - Entry->ImageHandle = gDxeCoreImageHandle; + Entry->ImageHandle = gImageHandle; Entry->DeviceHandle = NULL; // diff --git a/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c b/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c index d6e732e021..9074de9670 100644 --- a/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c +++ b/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c @@ -119,7 +119,7 @@ CoreInitializeDebugImageInfoTable ( // Initialize EFI_SYSTEM_TABLE_POINTER structure // mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE; - mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS)(UINTN)gDxeCoreST; + mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS)(UINTN)gST; mDebugTable->Crc32 = 0; // diff --git a/MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c b/MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c index f47f3bd804..e7cc4764b9 100755 --- a/MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c +++ b/MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c @@ -45,18 +45,18 @@ CoreInstallConfigurationTable ( return EFI_INVALID_PARAMETER; } - EfiConfigurationTable = gDxeCoreST->ConfigurationTable; + EfiConfigurationTable = gST->ConfigurationTable; // // Search all the table for an entry that matches Guid // - for (Index = 0; Index < gDxeCoreST->NumberOfTableEntries; Index++) { - if (CompareGuid (Guid, &(gDxeCoreST->ConfigurationTable[Index].VendorGuid))) { + for (Index = 0; Index < gST->NumberOfTableEntries; Index++) { + if (CompareGuid (Guid, &(gST->ConfigurationTable[Index].VendorGuid))) { break; } } - if (Index < gDxeCoreST->NumberOfTableEntries) { + if (Index < gST->NumberOfTableEntries) { // // A match was found, so this is either a modify or a delete operation // @@ -65,7 +65,7 @@ CoreInstallConfigurationTable ( // If Table is not NULL, then this is a modify operation. // Modify the table entry and return. // - gDxeCoreST->ConfigurationTable[Index].VendorTable = Table; + gST->ConfigurationTable[Index].VendorTable = Table; // // Signal Configuration Table change @@ -78,15 +78,15 @@ CoreInstallConfigurationTable ( // // A match was found and Table is NULL, so this is a delete operation. // - gDxeCoreST->NumberOfTableEntries--; + gST->NumberOfTableEntries--; // // Copy over deleted entry // CopyMem ( &(EfiConfigurationTable[Index]), - &(gDxeCoreST->ConfigurationTable[Index + 1]), - (gDxeCoreST->NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE) + &(gST->ConfigurationTable[Index + 1]), + (gST->NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE) ); } else { // @@ -101,7 +101,7 @@ CoreInstallConfigurationTable ( } // - // Assume that Index == gDxeCoreST->NumberOfTableEntries + // Assume that Index == gST->NumberOfTableEntries // if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSystemTableAllocateSize) { // @@ -116,30 +116,30 @@ CoreInstallConfigurationTable ( return EFI_OUT_OF_RESOURCES; } - if (gDxeCoreST->ConfigurationTable != NULL) { + if (gST->ConfigurationTable != NULL) { // // Copy the old table to the new table. // CopyMem ( EfiConfigurationTable, - gDxeCoreST->ConfigurationTable, + gST->ConfigurationTable, Index * sizeof (EFI_CONFIGURATION_TABLE) ); // // Record the old table pointer. // - OldTable = gDxeCoreST->ConfigurationTable; + OldTable = gST->ConfigurationTable; // // As the CoreInstallConfigurationTable() may be re-entered by CoreFreePool() // in its calling stack, updating System table to the new table pointer must // be done before calling CoreFreePool() to free the old table. - // It can make sure the gDxeCoreST->ConfigurationTable point to the new table + // It can make sure the gST->ConfigurationTable point to the new table // and avoid the errors of use-after-free to the old table by the reenter of // CoreInstallConfigurationTable() in CoreFreePool()'s calling stack. // - gDxeCoreST->ConfigurationTable = EfiConfigurationTable; + gST->ConfigurationTable = EfiConfigurationTable; // // Free the old table after updating System Table to the new table pointer. @@ -149,7 +149,7 @@ CoreInstallConfigurationTable ( // // Update System Table // - gDxeCoreST->ConfigurationTable = EfiConfigurationTable; + gST->ConfigurationTable = EfiConfigurationTable; } } @@ -162,13 +162,13 @@ CoreInstallConfigurationTable ( // // This is an add operation, so increment the number of table entries // - gDxeCoreST->NumberOfTableEntries++; + gST->NumberOfTableEntries++; } // // Fix up the CRC-32 in the EFI System Table // - CalculateEfiHdrCrc (&gDxeCoreST->Hdr); + CalculateEfiHdrCrc (&gST->Hdr); // // Signal Configuration Table change diff --git a/MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.c b/MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.c new file mode 100644 index 0000000000..a683ea5dd3 --- /dev/null +++ b/MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.c @@ -0,0 +1,48 @@ +/** @file + Dummy instance of DXE Services Table Library for DxeCore. + + Relies on and sanity-checks that DxeCore provides the variables itself. + + Copyright (c) 2021, Marvin Häuser. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +/** + The constructor function sanity-checks the variables set by DxeCore. + It will always return EFI_SUCCESS. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +DxeServicesTableLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_DXE_SERVICES *DS; + + // + // ASSERT that DxeCore provides the services correctly and in time + // + DEBUG_CODE_BEGIN (); + Status = EfiGetSystemConfigurationTable (&gEfiDxeServicesTableGuid, (VOID **) &DS); + ASSERT_EFI_ERROR (Status); + ASSERT (gDS == DS); + DEBUG_CODE_END (); + ASSERT (gDS != NULL); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf b/MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf new file mode 100644 index 0000000000..dd5633bdf6 --- /dev/null +++ b/MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf @@ -0,0 +1,40 @@ +## @file +# Dummy instance of DXE Services Table Library for DxeCore. +# +# Copyright (c) 2021, Marvin Häuser. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeCoreDxeServicesTableLib + MODULE_UNI_FILE = DxeCoreDxeServicesTableLib.uni + FILE_GUID = 898fc74c-b07c-4b68-bdd3-365c9ce26a9d + MODULE_TYPE = DXE_CORE + VERSION_STRING = 1.0 + LIBRARY_CLASS = DxeServicesTableLib|DXE_CORE + + CONSTRUCTOR = DxeServicesTableLibConstructor + +# +# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 +# + +[Sources] + DxeCoreDxeServicesTableLib.c + + +[Packages] + MdePkg/MdePkg.dec + + +[LibraryClasses] + UefiLib + DebugLib + + +[Guids] + gEfiDxeServicesTableGuid ## CONSUMES ## SystemTable diff --git a/MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.uni b/MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.uni new file mode 100644 index 0000000000..0019a62e3f --- /dev/null +++ b/MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.uni @@ -0,0 +1,13 @@ +// /** @file +// Dummy instance of DXE Services Table Library for DxeCore. +// +// Copyright (c) 2021, Marvin Häuser. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Dummy instance for DxeCore" + +#string STR_MODULE_DESCRIPTION #language en-US "DXE Services Table Library retrieves a pointer to the DXE Services Table from the Configuration Table in the EFI System Table." diff --git a/MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.c b/MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.c new file mode 100644 index 0000000000..aa95351214 --- /dev/null +++ b/MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.c @@ -0,0 +1,44 @@ +/** @file + Dummy instance of UEFI Boot Services Table Library for DxeCore. + + Relies on and sanity-checks that DxeCore provides the variables itself. + + Copyright (c) 2021, Marvin Häuser. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include + +/** + The constructor function sanity-checks the variables set by DxeCore. + It will always return EFI_SUCCESS. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +UefiBootServicesTableLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + // + // ASSERT that DxeCore provides the services correctly and in time + // + ASSERT (gImageHandle == ImageHandle); + ASSERT (gImageHandle != NULL); + ASSERT (gST == SystemTable); + ASSERT (gST != NULL); + ASSERT (gBS == gST->BootServices); + ASSERT (gBS != NULL); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf b/MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf new file mode 100644 index 0000000000..81b70fac3f --- /dev/null +++ b/MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf @@ -0,0 +1,34 @@ +## @file +# Dummy instance of UEFI Boot Services Table Library for DxeCore. +# +# Copyright (c) 2021, Marvin Häuser. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeCoreUefiBootServicesTableLib + MODULE_UNI_FILE = DxeCoreUefiBootServicesTableLib.uni + FILE_GUID = 67ecd0d0-5e42-4933-baee-cb129e4f4c55 + MODULE_TYPE = DXE_CORE + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiBootServicesTableLib|DXE_CORE + + CONSTRUCTOR = UefiBootServicesTableLibConstructor + +# +# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 +# + +[Sources] + DxeCoreUefiBootServicesTableLib.c + +[Packages] + MdePkg/MdePkg.dec + + +[LibraryClasses] + DebugLib diff --git a/MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.uni b/MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.uni new file mode 100644 index 0000000000..4f060a394d --- /dev/null +++ b/MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.uni @@ -0,0 +1,13 @@ +// /** @file +// Dummy instance of UEFI Boot Services Table Library for DxeCore. +// +// Copyright (c) 2021, Marvin Häuser. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Dummy instance of UEFI Boot Services Table Library for DxeCore" + +#string STR_MODULE_DESCRIPTION #language en-US "Dummy instance of UEFI Boot Services Table Library for DxeCore." diff --git a/MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.c b/MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.c new file mode 100644 index 0000000000..3c92746ab1 --- /dev/null +++ b/MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.c @@ -0,0 +1,39 @@ +/** @file + Dummy instance of UEFI Runtime Services Table Library for DxeCore. + + Relies on and sanity-checks that DxeCore provides the variables itself. + + Copyright (c) 2021, Marvin Häuser. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include + +/** + The constructor function sanity-checks the variables set by DxeCore. + It will always return EFI_SUCCESS. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +UefiRuntimeServicesTableLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + // + // ASSERT that DxeCore provides the services correctly and in time + // + ASSERT (gRT == SystemTable->RuntimeServices); + ASSERT (gRT != NULL); + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf b/MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf new file mode 100644 index 0000000000..5ff3fd8eee --- /dev/null +++ b/MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf @@ -0,0 +1,35 @@ +## @file +# Dummy instance of UEFI Runtime Services Table Library for DxeCore. +# +# Copyright (c) 2021, Marvin Häuser. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeCoreUefiRuntimeServicesTableLib + MODULE_UNI_FILE = DxeCoreUefiRuntimeServicesTableLib.uni + FILE_GUID = 59a35203-341d-46b6-96f6-ec69e035b02e + MODULE_TYPE = DXE_CORE + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiRuntimeServicesTableLib|DXE_CORE + + CONSTRUCTOR = UefiRuntimeServicesTableLibConstructor + +# +# VALID_ARCHITECTURES = IA32 X64 EBC ARM AARCH64 +# + +[Sources] + DxeCoreUefiRuntimeServicesTableLib.c + + +[Packages] + MdePkg/MdePkg.dec + + +[LibraryClasses] + DebugLib diff --git a/MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.uni b/MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.uni new file mode 100644 index 0000000000..b860b3f996 --- /dev/null +++ b/MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.uni @@ -0,0 +1,13 @@ +// /** @file +// Dummy instance of UEFI Runtime Services Table Library for DxeCore. +// +// Copyright (c) 2021, Marvin Häuser. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Dummy instance of UEFI Runtime Services Table Library for DxeCore" + +#string STR_MODULE_DESCRIPTION #language en-US "Dummy instance of UEFI Runtime Services Table Library for DxeCore." diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 2e9fe859ad..8b2caee209 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -127,6 +127,22 @@ HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + DxeServicesTableLib|MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf + UefiBootServicesTableLib|MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf + CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf + MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf + LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf + UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf + MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf + MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf + MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf + +[LibraryClasses.IA32.DXE_CORE] + CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf + +[LibraryClasses.X64.DXE_CORE] + CcExitLib|OvmfPkg/Library/CcExitLib/CcExitLib.inf [LibraryClasses.common.DXE_DRIVER] HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf @@ -345,6 +361,9 @@ MdeModulePkg/Library/DisplayUpdateProgressLibText/DisplayUpdateProgressLibText.inf MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf + MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf + MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf + MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf MdeModulePkg/Universal/BdsDxe/BdsDxe.inf MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf @@ -527,4 +546,3 @@ MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf [BuildOptions] - diff --git a/OvmfPkg/Include/Library/PlatformInitLib.h b/OvmfPkg/Include/Library/PlatformInitLib.h index 57b18b94d9..36f23e37ac 100644 --- a/OvmfPkg/Include/Library/PlatformInitLib.h +++ b/OvmfPkg/Include/Library/PlatformInitLib.h @@ -55,6 +55,9 @@ typedef struct { BOOLEAN QemuFwCfgChecked; BOOLEAN QemuFwCfgSupported; BOOLEAN QemuFwCfgDmaSupported; + + UINT64 PteMemoryEncryptionAddressOrMask; + UINT64 GhcbBase; } EFI_HOB_PLATFORM_INFO; #pragma pack() diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc index 840159d118..28fbc45767 100644 --- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc +++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc @@ -256,6 +256,8 @@ ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf + MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -573,6 +575,9 @@ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + DxeServicesTableLib|MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf + UefiBootServicesTableLib|MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf } MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf @@ -595,29 +600,6 @@ MdeModulePkg/Universal/EbcDxe/EbcDxe.inf UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf - UefiCpuPkg/CpuDxe/CpuDxe.inf { - - # - # Directly use DxeMpInitLib. It depends on DxeMpInitLibMpDepLib which - # checks the Protocol of gEfiMpInitLibMpDepProtocolGuid. - # - MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf - NULL|OvmfPkg/Library/MpInitLibDepLib/DxeMpInitLibMpDepLib.inf - } - - UefiCpuPkg/CpuDxe/CpuDxe.inf { - - FILE_GUID = $(UP_CPU_DXE_GUID) - - - # - # Directly use MpInitLibUp. It depends on DxeMpInitLibUpDepLib which - # checks the Protocol of gEfiMpInitLibUpDepProtocolGuid. - # - MpInitLib|UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.inf - NULL|OvmfPkg/Library/MpInitLibDepLib/DxeMpInitLibUpDepLib.inf - } - OvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.inf OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.fdf b/OvmfPkg/IntelTdx/IntelTdxX64.fdf index 01581c0a0b..23c449aeca 100644 --- a/OvmfPkg/IntelTdx/IntelTdxX64.fdf +++ b/OvmfPkg/IntelTdx/IntelTdxX64.fdf @@ -189,9 +189,6 @@ INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf -INF UefiCpuPkg/CpuDxe/CpuDxe.inf -INF FILE_GUID = $(UP_CPU_DXE_GUID) UefiCpuPkg/CpuDxe/CpuDxe.inf - INF OvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.inf INF OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf INF OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 735f828797..07e5495463 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -327,6 +327,8 @@ !endif CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf + MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -731,6 +733,9 @@ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + DxeServicesTableLib|MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf + UefiBootServicesTableLib|MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf } MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf @@ -752,7 +757,6 @@ MdeModulePkg/Universal/EbcDxe/EbcDxe.inf UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf - UefiCpuPkg/CpuDxe/CpuDxe.inf OvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.inf OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index bc7bb678b4..010a3cec91 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -218,7 +218,6 @@ INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf -INF UefiCpuPkg/CpuDxe/CpuDxe.inf INF OvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.inf INF OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf INF OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 4aa7f236a7..572b18352e 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -332,6 +332,8 @@ !endif CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf + MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -747,6 +749,9 @@ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + DxeServicesTableLib|MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf + UefiBootServicesTableLib|MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf } MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf @@ -768,7 +773,6 @@ MdeModulePkg/Universal/EbcDxe/EbcDxe.inf UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf - UefiCpuPkg/CpuDxe/CpuDxe.inf OvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.inf OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index 7f971dd9c2..34a78831f5 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -219,7 +219,6 @@ INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf -INF UefiCpuPkg/CpuDxe/CpuDxe.inf INF OvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.inf INF OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf INF OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index a167addb60..1797b50530 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -354,6 +354,8 @@ !endif CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf + MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -793,6 +795,9 @@ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + DxeServicesTableLib|MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf + UefiBootServicesTableLib|MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf } MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf @@ -815,29 +820,6 @@ MdeModulePkg/Universal/EbcDxe/EbcDxe.inf UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf - UefiCpuPkg/CpuDxe/CpuDxe.inf { - - # - # Directly use DxeMpInitLib. It depends on DxeMpInitLibMpDepLib which - # checks the Protocol of gEfiMpInitLibMpDepProtocolGuid. - # - MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf - NULL|OvmfPkg/Library/MpInitLibDepLib/DxeMpInitLibMpDepLib.inf - } - - UefiCpuPkg/CpuDxe/CpuDxe.inf { - - FILE_GUID = $(UP_CPU_DXE_GUID) - - - # - # Directly use MpInitLibUp. It depends on DxeMpInitLibUpDepLib which - # checks the Protocol of gEfiMpInitLibUpDepProtocolGuid. - # - MpInitLib|UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.inf - NULL|OvmfPkg/Library/MpInitLibDepLib/DxeMpInitLibUpDepLib.inf - } - OvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.inf OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 547c6ee3b7..9b26b3192c 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -251,9 +251,6 @@ INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf -INF UefiCpuPkg/CpuDxe/CpuDxe.inf -INF FILE_GUID = $(UP_CPU_DXE_GUID) UefiCpuPkg/CpuDxe/CpuDxe.inf - INF OvmfPkg/LocalApicTimerDxe/LocalApicTimerDxe.inf INF OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf INF OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf diff --git a/OvmfPkg/PlatformPei/AmdSev.c b/OvmfPkg/PlatformPei/AmdSev.c index 8562787035..2a666eebdd 100644 --- a/OvmfPkg/PlatformPei/AmdSev.c +++ b/OvmfPkg/PlatformPei/AmdSev.c @@ -348,6 +348,9 @@ AmdSevEsInitialize ( Status = PcdSet64S (PcdGhcbBase, GhcbBasePa); ASSERT_RETURN_ERROR (Status); + + PlatformInfoHob->GhcbBase = GhcbBasePa; + Status = PcdSet64S (PcdGhcbSize, EFI_PAGES_TO_SIZE (GhcbPageCount)); ASSERT_RETURN_ERROR (Status); @@ -459,6 +462,8 @@ AmdSevInitialize ( PcdStatus = PcdSet64S (PcdPteMemoryEncryptionAddressOrMask, EncryptionMask); ASSERT_RETURN_ERROR (PcdStatus); + PlatformInfoHob->PteMemoryEncryptionAddressOrMask = EncryptionMask; + DEBUG ((DEBUG_INFO, "SEV is enabled (mask 0x%lx)\n", EncryptionMask)); // @@ -530,6 +535,7 @@ AmdSevInitialize ( } PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCGuestAttr); + PlatformInfoHob->PcdConfidentialComputingGuestAttr = CCGuestAttr; ASSERT_RETURN_ERROR (PcdStatus); } diff --git a/OvmfPkg/PlatformPei/IntelTdx.c b/OvmfPkg/PlatformPei/IntelTdx.c index 8aa796b3e9..a364c77de6 100644 --- a/OvmfPkg/PlatformPei/IntelTdx.c +++ b/OvmfPkg/PlatformPei/IntelTdx.c @@ -30,11 +30,12 @@ **/ VOID IntelTdxInitialize ( - VOID + IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob ) { #ifdef MDE_CPU_X64 RETURN_STATUS PcdStatus; + UINT64 PageMask; if (!TdIsEnabled ()) { return; @@ -43,8 +44,12 @@ IntelTdxInitialize ( PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, CCAttrIntelTdx); ASSERT_RETURN_ERROR (PcdStatus); - PcdStatus = PcdSet64S (PcdTdxSharedBitMask, TdSharedPageMask ()); + PlatformInfoHob->PcdConfidentialComputingGuestAttr = CCAttrIntelTdx; + + PageMask = TdSharedPageMask (); + PcdStatus = PcdSet64S (PcdTdxSharedBitMask, PageMask); ASSERT_RETURN_ERROR (PcdStatus); + PlatformInfoHob->PcdTdxSharedBitMask = PageMask; #endif } diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c index 7b4ea1b827..4b74ff3a26 100644 --- a/OvmfPkg/PlatformPei/Platform.c +++ b/OvmfPkg/PlatformPei/Platform.c @@ -368,7 +368,7 @@ InitializePlatform ( PlatformIdInitialization (PeiServices); } - IntelTdxInitialize (); + IntelTdxInitialize (PlatformInfoHob); InstallFeatureControlCallback (PlatformInfoHob); if (PlatformInfoHob->SmmSmramRequire) { RelocateSmBase (); diff --git a/OvmfPkg/PlatformPei/Platform.h b/OvmfPkg/PlatformPei/Platform.h index 0a59547cfc..39ef3107e9 100644 --- a/OvmfPkg/PlatformPei/Platform.h +++ b/OvmfPkg/PlatformPei/Platform.h @@ -95,7 +95,7 @@ AmdSevInitialize ( **/ VOID IntelTdxInitialize ( - VOID + IN EFI_HOB_PLATFORM_INFO *PlatformInfoHob ); /** diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.uni b/UefiCpuPkg/CpuDxe/CpuDxe.uni deleted file mode 100644 index 85d977d8c8..0000000000 --- a/UefiCpuPkg/CpuDxe/CpuDxe.uni +++ /dev/null @@ -1,16 +0,0 @@ -// /** @file -// CPU driver installs CPU Architecture Protocol and CPU MP Protocol. -// -// CPU driver installs CPU Architecture Protocol and CPU MP Protocol. -// -// Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
-// -// SPDX-License-Identifier: BSD-2-Clause-Patent -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "CPU driver installs CPU Architecture Protocol and CPU MP Protocol." - -#string STR_MODULE_DESCRIPTION #language en-US "CPU driver installs CPU Architecture Protocol and CPU MP Protocol." - diff --git a/UefiCpuPkg/Include/Library/CpuArchLib.h b/UefiCpuPkg/Include/Library/CpuArchLib.h new file mode 100644 index 0000000000..e9521d4e4f --- /dev/null +++ b/UefiCpuPkg/Include/Library/CpuArchLib.h @@ -0,0 +1,31 @@ +/** @file + CPU DXE Module to produce CPU ARCH Protocol. + Copyright (c) 2008 - 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef _CPU_ARCH_LIB_H_ +#define _CPU_ARCH_LIB_H_ + +/** + Initialize the state information for the CPU Architectural Protocol. + + @retval EFI_SUCCESS Thread can be successfully created + @retval EFI_OUT_OF_RESOURCES Can not allocate protocol data structure + @retval EFI_DEVICE_ERROR Can not create the thread +**/ +EFI_STATUS +InitializeCpu ( + VOID + ); + +/** + Initialize Multi-processor support. + +**/ +VOID +InitializeMpSupport ( + VOID + ); + +#endif // _CPU_ARCH_LIB_H_ diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.inf b/UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf similarity index 81% rename from UefiCpuPkg/CpuDxe/CpuDxe.inf rename to UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf index b2954ba234..c09c28d996 100644 --- a/UefiCpuPkg/CpuDxe/CpuDxe.inf +++ b/UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf @@ -1,5 +1,5 @@ ## @file -# CPU driver installs CPU Architecture Protocol and CPU MP protocol. +# This library installs CPU Architecture Protocol and CPU MP protocol. # # Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
# Copyright (c) 2017, AMD Incorporated. All rights reserved.
@@ -11,16 +11,17 @@ [Defines] INF_VERSION = 0x00010005 - BASE_NAME = CpuDxe - MODULE_UNI_FILE = CpuDxe.uni - FILE_GUID = 1A1E4886-9517-440e-9FDE-3BE44CEE2136 - MODULE_TYPE = DXE_DRIVER + BASE_NAME = CpuArchLib + MODULE_UNI_FILE = CpuArchLib.uni + FILE_GUID = EF9CBDF2-BD7C-48F1-9D87-EE83A0269EEE + MODULE_TYPE = DXE_CORE VERSION_STRING = 1.0 - ENTRY_POINT = InitializeCpu + LIBRARY_CLASS = CpuArchLib [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses.common] @@ -33,11 +34,10 @@ HobLib MemoryAllocationLib MpInitLib - PeCoffGetEntryPointLib ReportStatusCodeLib + SerialPortLib TimerLib UefiBootServicesTableLib - UefiDriverEntryPoint UefiLib [LibraryClasses.IA32, LibraryClasses.X64] @@ -82,13 +82,13 @@ [Guids] gIdleLoopEventGuid ## CONSUMES ## Event gEfiVectorHandoffTableGuid ## SOMETIMES_CONSUMES ## SystemTable + gUefiOvmfPkgPlatformInfoGuid ## CONSUMES ## HOB [Ppis] gEfiSecPlatformInformation2PpiGuid ## UNDEFINED # HOB gEfiSecPlatformInformationPpiGuid ## UNDEFINED # HOB [Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuArchLib.uni b/UefiCpuPkg/Library/CpuArchLib/CpuArchLib.uni new file mode 100644 index 0000000000..2c9429979a --- /dev/null +++ b/UefiCpuPkg/Library/CpuArchLib/CpuArchLib.uni @@ -0,0 +1,13 @@ +// /** @file +// This library installs CPU Architecture Protocol and CPU MP Protocol. +// +// Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "This library installs CPU Architecture Protocol and CPU MP Protocol." + +#string STR_MODULE_DESCRIPTION #language en-US "This library installs CPU Architecture Protocol and CPU MP Protocol." diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuArchLibNull.inf b/UefiCpuPkg/Library/CpuArchLib/CpuArchLibNull.inf new file mode 100644 index 0000000000..febba954bd --- /dev/null +++ b/UefiCpuPkg/Library/CpuArchLib/CpuArchLibNull.inf @@ -0,0 +1,24 @@ +## @file +# This library provides dummy InitializeCpu() for DxeMain.inf. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CpuArchLib + FILE_GUID = EF9CBDF2-BD7C-48F1-9D87-EE83A0269EEE + MODULE_TYPE = DXE_CORE + VERSION_STRING = 1.0 + LIBRARY_CLASS = CpuArchLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + +[Sources] + CpuDxeNull.c diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.c b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c similarity index 94% rename from UefiCpuPkg/CpuDxe/CpuDxe.c rename to UefiCpuPkg/Library/CpuArchLib/CpuDxe.c index 472de55180..1d539ee3f7 100644 --- a/UefiCpuPkg/CpuDxe/CpuDxe.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c @@ -21,7 +21,7 @@ BOOLEAN mIsFlushingGCD; BOOLEAN mIsAllocatingPageTable = FALSE; UINT64 mTimerPeriod = 0; -EFI_CPU_ARCH_PROTOCOL gCpu = { +EFI_CPU_ARCH_PROTOCOL gCpuImpl = { CpuFlushCpuDataCache, CpuEnableInterrupt, CpuDisableInterrupt, @@ -34,6 +34,8 @@ EFI_CPU_ARCH_PROTOCOL gCpu = { 4 // DmaBufferAlignment }; +EFI_HOB_PLATFORM_INFO *mPlatformInfoHob2 = NULL; + // // CPU Arch Protocol Functions // @@ -947,7 +949,7 @@ AddMemoryMappedIoSpace ( **/ VOID AddLocalApicMemorySpace ( - IN EFI_HANDLE ImageHandle + VOID ) { EFI_STATUS Status; @@ -968,7 +970,7 @@ AddLocalApicMemorySpace ( 0, SIZE_4KB, &BaseAddress, - ImageHandle, + gImageHandle, NULL ); if (EFI_ERROR (Status)) { @@ -985,23 +987,24 @@ AddLocalApicMemorySpace ( /** Initialize the state information for the CPU Architectural Protocol. - @param ImageHandle Image handle this driver. - @param SystemTable Pointer to the System Table. - @retval EFI_SUCCESS Thread can be successfully created - @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure - @retval EFI_DEVICE_ERROR Cannot create the thread + @retval EFI_OUT_OF_RESOURCES Can not allocate protocol data structure + @retval EFI_DEVICE_ERROR Can not create the thread **/ EFI_STATUS -EFIAPI InitializeCpu ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable + VOID ) { - EFI_STATUS Status; - EFI_EVENT IdleLoopEvent; + EFI_STATUS Status; + EFI_EVENT IdleLoopEvent; + EFI_HOB_GUID_TYPE *GuidHob; + + GuidHob = GetFirstGuidHob (&gUefiOvmfPkgPlatformInfoGuid); + if (GuidHob != NULL) { + mPlatformInfoHob2 = (EFI_HOB_PLATFORM_INFO *)(GET_GUID_HOB_DATA (GuidHob)); + } InitializePageTableLib (); @@ -1028,7 +1031,7 @@ InitializeCpu ( Status = gBS->InstallMultipleProtocolInterfaces ( &mCpuHandle, &gEfiCpuArchProtocolGuid, - &gCpu, + &gCpuImpl, NULL ); ASSERT_EFI_ERROR (Status); @@ -1046,7 +1049,7 @@ InitializeCpu ( // // Add and allocate local APIC memory mapped space // - AddLocalApicMemorySpace (ImageHandle); + AddLocalApicMemorySpace (); // // Setup a callback for idle events @@ -1061,7 +1064,5 @@ InitializeCpu ( ); ASSERT_EFI_ERROR (Status); - InitializeMpSupport (); - return Status; } diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.h b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.h similarity index 94% rename from UefiCpuPkg/CpuDxe/CpuDxe.h rename to UefiCpuPkg/Library/CpuArchLib/CpuDxe.h index 0e7d88dd35..34a865d1dd 100644 --- a/UefiCpuPkg/CpuDxe/CpuDxe.h +++ b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -293,7 +294,8 @@ PageFaultExceptionHandler ( IN EFI_SYSTEM_CONTEXT SystemContext ); -extern BOOLEAN mIsAllocatingPageTable; -extern UINTN mNumberOfProcessors; +extern BOOLEAN mIsAllocatingPageTable; +extern UINTN mNumberOfProcessors; +extern EFI_HOB_PLATFORM_INFO *mPlatformInfoHob2; #endif diff --git a/UefiCpuPkg/CpuDxe/CpuDxeExtra.uni b/UefiCpuPkg/Library/CpuArchLib/CpuDxeExtra.uni similarity index 77% rename from UefiCpuPkg/CpuDxe/CpuDxeExtra.uni rename to UefiCpuPkg/Library/CpuArchLib/CpuDxeExtra.uni index 5bb116fee7..57bf2691e7 100644 --- a/UefiCpuPkg/CpuDxe/CpuDxeExtra.uni +++ b/UefiCpuPkg/Library/CpuArchLib/CpuDxeExtra.uni @@ -9,6 +9,4 @@ #string STR_PROPERTIES_MODULE_NAME #language en-US -"CPU Architectural and CPU Multi-processor DXE Driver" - - +"CPU Architectural and CPU Multi-processor DXE library" diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuDxeNull.c b/UefiCpuPkg/Library/CpuArchLib/CpuDxeNull.c new file mode 100644 index 0000000000..d61890e05b --- /dev/null +++ b/UefiCpuPkg/Library/CpuArchLib/CpuDxeNull.c @@ -0,0 +1,25 @@ +/** + Initialize the state information for the CPU Architectural Protocol. + + @retval EFI_SUCCESS Thread can be successfully created + @retval EFI_OUT_OF_RESOURCES Can not allocate protocol data structure + @retval EFI_DEVICE_ERROR Can not create the thread +**/ +EFI_STATUS +InitializeCpu ( + VOID + ) +{ + return EFI_SUCCESS; +} + +/** + Initialize Multi-processor support. + +**/ +VOID +InitializeMpSupport ( + VOID + ) +{ +} diff --git a/UefiCpuPkg/CpuDxe/CpuGdt.c b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c similarity index 100% rename from UefiCpuPkg/CpuDxe/CpuGdt.c rename to UefiCpuPkg/Library/CpuArchLib/CpuGdt.c diff --git a/UefiCpuPkg/CpuDxe/CpuGdt.h b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h similarity index 100% rename from UefiCpuPkg/CpuDxe/CpuGdt.h rename to UefiCpuPkg/Library/CpuArchLib/CpuGdt.h diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/Library/CpuArchLib/CpuMp.c similarity index 100% rename from UefiCpuPkg/CpuDxe/CpuMp.c rename to UefiCpuPkg/Library/CpuArchLib/CpuMp.c diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/Library/CpuArchLib/CpuMp.h similarity index 97% rename from UefiCpuPkg/CpuDxe/CpuMp.h rename to UefiCpuPkg/Library/CpuArchLib/CpuMp.h index b461753510..c42a617bcf 100644 --- a/UefiCpuPkg/CpuDxe/CpuMp.h +++ b/UefiCpuPkg/Library/CpuArchLib/CpuMp.h @@ -9,15 +9,6 @@ #ifndef _CPU_MP_H_ #define _CPU_MP_H_ -/** - Initialize Multi-processor support. - -**/ -VOID -InitializeMpSupport ( - VOID - ); - /** This service retrieves the number of logical processor in the platform and the number of those logical processors that are enabled on this boot. diff --git a/UefiCpuPkg/CpuDxe/CpuPageTable.c b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c similarity index 95% rename from UefiCpuPkg/CpuDxe/CpuPageTable.c rename to UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c index 6a3f1f34ed..1092a30d28 100644 --- a/UefiCpuPkg/CpuDxe/CpuPageTable.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c @@ -90,13 +90,13 @@ PAGE_ATTRIBUTE_TABLE mPageAttributeTable[] = { PAGE_TABLE_POOL *mPageTablePool = NULL; BOOLEAN mPageTablePoolLock = FALSE; PAGE_TABLE_LIB_PAGING_CONTEXT mPagingContext; -EFI_SMM_BASE2_PROTOCOL *mSmmBase2 = NULL; +EFI_SMM_BASE2_PROTOCOL *mSmmBase2 = NULL; // // Record the page fault exception count for one instruction execution. // UINTN *mPFEntryCount; -UINT64 *(*mLastPFEntryPointer)[MAX_PF_ENTRY_COUNT]; +UINT64 *(*mLastPFEntryPointer)[MAX_PF_ENTRY_COUNT]; /** Check if current execution environment is in SMM mode or not, via @@ -308,9 +308,9 @@ GetPageTableEntry ( // Make sure AddressEncMask is contained to smallest supported address field. // - AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; + AddressEncMask = mPlatformInfoHob2->PteMemoryEncryptionAddressOrMask & PAGING_1G_ADDRESS_MASK_64; if (AddressEncMask == 0) { - AddressEncMask = PcdGet64 (PcdTdxSharedBitMask) & PAGING_1G_ADDRESS_MASK_64; + AddressEncMask = mPlatformInfoHob2->PcdTdxSharedBitMask & PAGING_1G_ADDRESS_MASK_64; } if (PagingContext->MachineType == IMAGE_FILE_MACHINE_X64) { @@ -566,7 +566,7 @@ SplitPage ( // Make sure AddressEncMask is contained to smallest supported address field. // - AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; + AddressEncMask = mPlatformInfoHob2->PteMemoryEncryptionAddressOrMask & PAGING_1G_ADDRESS_MASK_64; if (PageAttribute == Page2M) { // @@ -1654,7 +1654,7 @@ EfiGetMemoryAttributes ( // Make sure AddressEncMask is contained to smallest supported address field. // - AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; + AddressEncMask = mPlatformInfoHob2->PteMemoryEncryptionAddressOrMask & PAGING_1G_ADDRESS_MASK_64; GetCurrentPagingContext (&CurrentPagingContext); diff --git a/UefiCpuPkg/CpuDxe/CpuPageTable.h b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.h similarity index 100% rename from UefiCpuPkg/CpuDxe/CpuPageTable.h rename to UefiCpuPkg/Library/CpuArchLib/CpuPageTable.h diff --git a/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.nasm b/UefiCpuPkg/Library/CpuArchLib/Ia32/CpuAsm.nasm similarity index 100% rename from UefiCpuPkg/CpuDxe/Ia32/CpuAsm.nasm rename to UefiCpuPkg/Library/CpuArchLib/Ia32/CpuAsm.nasm diff --git a/UefiCpuPkg/CpuDxe/Ia32/PagingAttribute.c b/UefiCpuPkg/Library/CpuArchLib/Ia32/PagingAttribute.c similarity index 100% rename from UefiCpuPkg/CpuDxe/Ia32/PagingAttribute.c rename to UefiCpuPkg/Library/CpuArchLib/Ia32/PagingAttribute.c diff --git a/UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.c b/UefiCpuPkg/Library/CpuArchLib/LoongArch64/CpuDxe.c similarity index 100% rename from UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.c rename to UefiCpuPkg/Library/CpuArchLib/LoongArch64/CpuDxe.c diff --git a/UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.h b/UefiCpuPkg/Library/CpuArchLib/LoongArch64/CpuDxe.h similarity index 100% rename from UefiCpuPkg/CpuDxe/LoongArch64/CpuDxe.h rename to UefiCpuPkg/Library/CpuArchLib/LoongArch64/CpuDxe.h diff --git a/UefiCpuPkg/CpuDxe/LoongArch64/CpuMp.c b/UefiCpuPkg/Library/CpuArchLib/LoongArch64/CpuMp.c similarity index 100% rename from UefiCpuPkg/CpuDxe/LoongArch64/CpuMp.c rename to UefiCpuPkg/Library/CpuArchLib/LoongArch64/CpuMp.c diff --git a/UefiCpuPkg/CpuDxe/LoongArch64/Exception.c b/UefiCpuPkg/Library/CpuArchLib/LoongArch64/Exception.c similarity index 100% rename from UefiCpuPkg/CpuDxe/LoongArch64/Exception.c rename to UefiCpuPkg/Library/CpuArchLib/LoongArch64/Exception.c diff --git a/UefiCpuPkg/CpuDxe/X64/CpuAsm.nasm b/UefiCpuPkg/Library/CpuArchLib/X64/CpuAsm.nasm similarity index 100% rename from UefiCpuPkg/CpuDxe/X64/CpuAsm.nasm rename to UefiCpuPkg/Library/CpuArchLib/X64/CpuAsm.nasm diff --git a/UefiCpuPkg/CpuDxe/X64/PagingAttribute.c b/UefiCpuPkg/Library/CpuArchLib/X64/PagingAttribute.c similarity index 100% rename from UefiCpuPkg/CpuDxe/X64/PagingAttribute.c rename to UefiCpuPkg/Library/CpuArchLib/X64/PagingAttribute.c diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf index 922c7b12d3..7a2fd88f50 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf @@ -14,7 +14,7 @@ FILE_GUID = B88F7146-9834-4c55-BFAC-481CC0C33736 MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.1 - LIBRARY_CLASS = MpInitLib|DXE_DRIVER + LIBRARY_CLASS = MpInitLib|DXE_DRIVER DXE_CORE # # The following information is for reference only and not required by the build tools. @@ -49,6 +49,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses] @@ -80,16 +81,13 @@ gEfiEventLegacyBootGuid ## SOMETIMES_CONSUMES ## Event gEdkiiMicrocodePatchHobGuid ## SOMETIMES_CONSUMES ## HOB gGhcbApicIdsGuid ## SOMETIMES_CONSUMES ## HOB + gUefiOvmfPkgPlatformInfoGuid ## CONSUMES ## HOB [Guids.LoongArch64] gProcessorResourceHobGuid ## SOMETIMES_CONSUMES ## HOB [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES - gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr ## CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## SOMETIMES_CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index fdcc21d794..84625c0646 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -9,13 +9,17 @@ **/ #include "MpLib.h" + #include #include +#include + #include -EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID; -EFI_GUID mMpHandOffGuid = MP_HANDOFF_GUID; -EFI_GUID mMpHandOffConfigGuid = MP_HANDOFF_CONFIG_GUID; +EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID; +EFI_GUID mMpHandOffGuid = MP_HANDOFF_GUID; +EFI_GUID mMpHandOffConfigGuid = MP_HANDOFF_CONFIG_GUID; +EFI_HOB_PLATFORM_INFO *mPlatformInfoHob = NULL; RELOCATE_AP_LOOP_ENTRY mReservedApLoop; UINTN mReservedTopOfApStack; @@ -589,7 +593,7 @@ CollectProcessorCount ( // FinishedCount is the number of check-in APs. // CpuMpData->CpuCount = CpuMpData->FinishedCount + 1; - ASSERT (CpuMpData->CpuCount <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + ASSERT (CpuMpData->CpuCount <= mPlatformInfoHob->PcdCpuMaxLogicalProcessorNumber); return CpuMpData->CpuCount; } @@ -1151,7 +1155,7 @@ AllocateResetVectorBelow1Mb ( // of processors for calculating the total stack area. // ApResetStackSize = (AP_RESET_STACK_SIZE * - PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + mPlatformInfoHob->PcdCpuMaxLogicalProcessorNumber); // // Invoke GetWakeupBuffer a second time to allocate the stack area @@ -1303,7 +1307,7 @@ WakeUpAP ( } if (CpuMpData->InitFlag == ApInitConfig) { - if (PcdGet32 (PcdCpuBootLogicalProcessorNumber) > 0) { + if (mPlatformInfoHob->PcdCpuBootLogicalProcessorNumber > 0) { // // The AP enumeration algorithm below is suitable only when the // platform can tell us the *exact* boot CPU count in advance. @@ -1319,7 +1323,7 @@ WakeUpAP ( // TimedWaitForApFinish ( CpuMpData, - PcdGet32 (PcdCpuBootLogicalProcessorNumber) - 1, + mPlatformInfoHob->PcdCpuBootLogicalProcessorNumber - 1, MAX_UINT32 // approx. 71 minutes ); } else { @@ -1357,7 +1361,7 @@ WakeUpAP ( // TimedWaitForApFinish ( CpuMpData, - PcdGet32 (PcdCpuMaxLogicalProcessorNumber) - 1, + mPlatformInfoHob->PcdCpuMaxLogicalProcessorNumber - 1, PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds) ); @@ -2067,6 +2071,12 @@ MpInitLibInitialize ( UINTN ApResetVectorSizeAbove1Mb; UINTN BackupBufferAddr; UINTN ApIdtBase; + EFI_HOB_GUID_TYPE *GuidHob; + + GuidHob = GetFirstGuidHob (&gUefiOvmfPkgPlatformInfoGuid); + if (GuidHob != NULL) { + mPlatformInfoHob = (EFI_HOB_PLATFORM_INFO *)(GET_GUID_HOB_DATA (GuidHob)); + } FirstMpHandOff = GetNextMpHandOffHob (NULL); if (FirstMpHandOff != NULL) { @@ -2086,7 +2096,7 @@ MpInitLibInitialize ( MaxLogicalProcessorNumber += MpHandOff->CpuCount; } } else { - MaxLogicalProcessorNumber = PcdGet32 (PcdCpuMaxLogicalProcessorNumber); + MaxLogicalProcessorNumber = mPlatformInfoHob->PcdCpuMaxLogicalProcessorNumber; } ASSERT (MaxLogicalProcessorNumber != 0); @@ -2170,7 +2180,7 @@ MpInitLibInitialize ( CpuMpData->SevEsIsEnabled = ConfidentialComputingGuestHas (CCAttrAmdSevEs); CpuMpData->SevSnpIsEnabled = ConfidentialComputingGuestHas (CCAttrAmdSevSnp); CpuMpData->SevEsAPBuffer = (UINTN)-1; - CpuMpData->GhcbBase = PcdGet64 (PcdGhcbBase); + CpuMpData->GhcbBase = mPlatformInfoHob->GhcbBase; CpuMpData->UseSevEsAPMethod = CpuMpData->SevEsIsEnabled && !CpuMpData->SevSnpIsEnabled; if (CpuMpData->SevSnpIsEnabled) { @@ -3342,7 +3352,7 @@ ConfidentialComputingGuestHas ( // // Get the current CC attribute. // - CurrentAttr = PcdGet64 (PcdConfidentialComputingGuestAttr); + CurrentAttr = mPlatformInfoHob->PcdConfidentialComputingGuestAttr; // // If attr is for the AMD group then call AMD specific checks. diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf index d1e8312c02..2dc5e0cc0f 100644 --- a/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf @@ -49,6 +49,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses] @@ -70,10 +71,6 @@ CpuPageTableLib [Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES - gEfiMdePkgTokenSpaceGuid.PcdConfidentialComputingGuestAttr ## CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuBootLogicalProcessorNumber ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds ## SOMETIMES_CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES @@ -91,6 +88,7 @@ gEdkiiMicrocodePatchHobGuid gGhcbApicIdsGuid ## SOMETIMES_CONSUMES gEdkiiEndOfS3ResumeGuid + gUefiOvmfPkgPlatformInfoGuid ## CONSUMES ## HOB [Guids.LoongArch64] gProcessorResourceHobGuid ## SOMETIMES_CONSUMES ## HOB diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 42919debdb..18f01dd7b6 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -76,6 +76,10 @@ ## @libraryclass Provides functions for SMM Relocation Operation. SmmRelocationLib|Include/Library/SmmRelocationLib.h + + ## @libraryclass Installs CPU Architecture Protocol. + ## + CpuArchLib|Include/Library/CpuArchLib.h [LibraryClasses.RISCV64] ## @libraryclass Provides function to initialize the FPU. diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index ff9768375d..66a7082ce5 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -75,6 +75,7 @@ HobLib|MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf MemoryAllocationLib|MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf [LibraryClasses.common.SEC] PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf @@ -143,7 +144,6 @@ CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf [Components.IA32, Components.X64] - UefiCpuPkg/CpuDxe/CpuDxe.inf UefiCpuPkg/CpuFeatures/CpuFeaturesPei.inf { NULL|UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf @@ -156,8 +156,11 @@ UefiCpuPkg/CpuIo2Smm/CpuIo2StandaloneMm.inf UefiCpuPkg/CpuMpPei/CpuMpPei.inf UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf + UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf + UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf + UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf @@ -176,9 +179,7 @@ UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf - UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf UefiCpuPkg/Library/TdxMeasurementLibNull/TdxMeasurementLibNull.inf - UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf UefiCpuPkg/SecCore/SecCore.inf diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 931e5461c2..98ea4774b9 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -382,6 +382,8 @@ !if $(PERFORMANCE_MEASUREMENT_ENABLE) PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf !endif + CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf + MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf [LibraryClasses.common.DXE_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -726,6 +728,9 @@ SerialPortLib|UefiPayloadPkg/Library/BaseSerialPortLibHob/DxeBaseSerialPortLibHob.inf !endif NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + DxeServicesTableLib|MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf + UefiBootServicesTableLib|MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf } # @@ -744,7 +749,6 @@ SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf !endif - UefiCpuPkg/CpuDxe/CpuDxe.inf MdeModulePkg/Universal/BdsDxe/BdsDxe.inf !if $(BOOTSPLASH_IMAGE) MdeModulePkg/Logo/LogoDxe.inf diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 283df03ac4..71ca5254e6 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -161,7 +161,6 @@ INF CryptoPkg/Driver/CryptoDxe.inf !if $(SECURITY_STUB_ENABLE) == TRUE INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf !endif -INF UefiCpuPkg/CpuDxe/CpuDxe.inf !if $(TIMER_SUPPORT) == "HPET" INF PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf From 51c4b78146dacf6ec4ba620ea101368231de2422 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 26 Jun 2023 12:04:30 +0300 Subject: [PATCH 073/341] Revert "MdeModulePkg: Enable forward edge CFI in mem attributes table" This reverts commit e4ef609319236a018c60b84f68d9d923c4ba383e. --- MdeModulePkg/Core/Dxe/DxeMain.h | 2 -- MdeModulePkg/Core/Dxe/Image/Image.c | 10 ---------- MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c | 8 +------- 3 files changed, 1 insertion(+), 19 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index deb3ced94c..e520a3b345 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -262,8 +262,6 @@ extern EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType extern BOOLEAN gDispatcherRunning; extern EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate; -extern BOOLEAN gMemoryAttributesTableForwardCfi; - extern EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE gLoadModuleAtFixAddressConfigurationTable; extern BOOLEAN gLoadFixedAddressCodeMemoryReady; extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage; diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 30a290572f..f38a97fede 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1336,16 +1336,6 @@ CoreLoadImageCommon ( CoreNewDebugImageInfoEntry (EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, &Image->Info, Image->Handle, &ImageContext); } - // - // Check whether we are loading a runtime image that lacks support for - // IBT/BTI landing pads. - // - if ((Image->ImageContext.ImageCodeMemoryType == EfiRuntimeServicesCode) && - ((Image->ImageContext.DllCharacteristicsEx & EFI_IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT) == 0)) - { - gMemoryAttributesTableForwardCfi = FALSE; - } - // // Reinstall loaded image protocol to fire any notifications // diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c index 670297a339..54078c2f99 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c @@ -92,7 +92,6 @@ BOOLEAN mMemoryAttributesTableEnable = TRUE; BOOLEAN mMemoryAttributesTableEndOfDxe = FALSE; EFI_MEMORY_ATTRIBUTES_TABLE *mMemoryAttributesTable = NULL; BOOLEAN mMemoryAttributesTableReadyToBoot = FALSE; -BOOLEAN gMemoryAttributesTableForwardCfi = TRUE; /** Install MemoryAttributesTable. @@ -186,12 +185,7 @@ InstallMemoryAttributesTable ( MemoryAttributesTable->Version = EFI_MEMORY_ATTRIBUTES_TABLE_VERSION; MemoryAttributesTable->NumberOfEntries = RuntimeEntryCount; MemoryAttributesTable->DescriptorSize = (UINT32)DescriptorSize; - if (gMemoryAttributesTableForwardCfi) { - MemoryAttributesTable->Flags = EFI_MEMORY_ATTRIBUTES_FLAGS_RT_FORWARD_CONTROL_FLOW_GUARD; - } else { - MemoryAttributesTable->Flags = 0; - } - + MemoryAttributesTable->Flags = 0; DEBUG ((DEBUG_VERBOSE, "MemoryAttributesTable:\n")); DEBUG ((DEBUG_VERBOSE, " Version - 0x%08x\n", MemoryAttributesTable->Version)); DEBUG ((DEBUG_VERBOSE, " NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries)); From 63b9e567e5e580f3978127dfc0907ccaf9fe446e Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 3 Jul 2023 12:32:49 +0300 Subject: [PATCH 074/341] Build: Replaced GCC5 toolchain with GCC. --- .github/workflows/build_arm.yaml | 30 +- .github/workflows/build_common.yml | 20 +- .github/workflows/build_x86.yaml | 22 +- ArmPlatformPkg/Scripts/Makefile | 2 +- ArmVirtPkg/PlatformCI/ReadMe.md | 2 +- BaseTools/Conf/tools_def.template | 265 ++---------------- BaseTools/Edk2ToolsBuild.py | 2 +- .../HostBasedUnitTestRunner.py | 2 +- CryptoPkg/Library/OpensslLib/OpensslLib.inf | 2 +- .../Library/OpensslLib/OpensslLibAccel.inf | 2 +- .../Library/OpensslLib/OpensslLibCrypto.inf | 2 +- .../Library/OpensslLib/OpensslLibFull.inf | 2 +- .../OpensslLib/OpensslLibFullAccel.inf | 2 +- DynamicTablesPkg/Readme.md | 10 +- EmulatorPkg/PlatformCI/ReadMe.md | 2 +- EmulatorPkg/Readme.md | 8 +- EmulatorPkg/Unix/Host/Host.inf | 3 +- EmulatorPkg/build.sh | 4 +- IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc | 8 +- OvmfPkg/CloudHv/README | 2 +- OvmfPkg/IntelTdx/README.md | 6 +- OvmfPkg/PlatformCI/ReadMe.md | 2 +- OvmfPkg/README | 2 +- OvmfPkg/build.sh | 2 +- PrmPkg/Readme.md | 6 +- STATUS.md | 32 +-- UnitTestFrameworkPkg/ReadMe.md | 8 +- 27 files changed, 113 insertions(+), 337 deletions(-) diff --git a/.github/workflows/build_arm.yaml b/.github/workflows/build_arm.yaml index be83e78d4e..02e37fe57e 100644 --- a/.github/workflows/build_arm.yaml +++ b/.github/workflows/build_arm.yaml @@ -16,7 +16,7 @@ env: jobs: build-linux-gcc5: - name: Linux GCC5 + name: Linux GCC runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 @@ -51,13 +51,13 @@ jobs: env: SELFPKG: ArmPkg SELFPKG_DIR: ArmPkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: ARM,AARCH64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 SKIP_PACKAGE: 1 - GCC5_ARM_PREFIX: arm-linux-gnueabi- - GCC5_AARCH64_PREFIX: aarch64-linux-gnu- + GCC_ARM_PREFIX: arm-linux-gnueabi- + GCC_AARCH64_PREFIX: aarch64-linux-gnu- - name: Build ArmPlatformPkg if: always() @@ -65,13 +65,13 @@ jobs: env: SELFPKG: ArmPlatformPkg SELFPKG_DIR: ArmPlatformPkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: ARM,AARCH64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 SKIP_PACKAGE: 1 - GCC5_ARM_PREFIX: arm-linux-gnueabi- - GCC5_AARCH64_PREFIX: aarch64-linux-gnu- + GCC_ARM_PREFIX: arm-linux-gnueabi- + GCC_AARCH64_PREFIX: aarch64-linux-gnu- - name: Build ArmVirtQemu if: always() @@ -79,13 +79,13 @@ jobs: env: SELFPKG: ArmVirtQemu SELFPKG_DIR: ArmVirtPkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: ARM,AARCH64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 SKIP_PACKAGE: 1 - GCC5_ARM_PREFIX: arm-linux-gnueabi- - GCC5_AARCH64_PREFIX: aarch64-linux-gnu- + GCC_ARM_PREFIX: arm-linux-gnueabi- + GCC_AARCH64_PREFIX: aarch64-linux-gnu- - name: Prepare artifacts with firmwares if: always() @@ -101,16 +101,16 @@ jobs: env: ARCHS: ARM,AARCH64 TARGETS: RELEASE,DEBUG,NOOPT - TOOLCHAIN: GCC5 + TOOLCHAIN: GCC - name: Zip artifacts - run: zip GCC5_fw_arm_artifacts.zip ./firmware_artifacts/* -r + run: zip GCC_fw_arm_artifacts.zip ./firmware_artifacts/* -r - name: Upload to Artifacts uses: actions/upload-artifact@v4 with: - name: GCC5 Firmware ARM Artifacts - path: GCC5_fw_arm_artifacts.zip + name: GCC Firmware ARM Artifacts + path: GCC_fw_arm_artifacts.zip build-linux-clangdwarf: name: Linux CLANGDWARF @@ -217,7 +217,7 @@ jobs: fail-fast: false matrix: package: [ - {name: "ArmVirtQemu", archs: "ARM,AARCH64", toolchain: "GCC5", targets: "RELEASE,DEBUG,NOOPT"}, + {name: "ArmVirtQemu", archs: "ARM,AARCH64", toolchain: "GCC", targets: "RELEASE,DEBUG,NOOPT"}, {name: "ArmVirtQemu", archs: "ARM,AARCH64", toolchain: "CLANGDWARF", targets: "RELEASE,DEBUG,NOOPT"}, ] steps: diff --git a/.github/workflows/build_common.yml b/.github/workflows/build_common.yml index 6762225eda..23b1cc29f3 100644 --- a/.github/workflows/build_common.yml +++ b/.github/workflows/build_common.yml @@ -540,7 +540,7 @@ jobs: SKIP_PACKAGE: 1 build-linux-gcc5: - name: Linux GCC5 + name: Linux GCC runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 @@ -561,7 +561,7 @@ jobs: env: SELFPKG: Ext4Pkg SELFPKG_DIR: Ext4Pkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: IA32,X64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 @@ -573,7 +573,7 @@ jobs: env: SELFPKG: FatPkg SELFPKG_DIR: FatPkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: IA32,X64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 @@ -585,7 +585,7 @@ jobs: env: SELFPKG: IntelFsp2Pkg SELFPKG_DIR: IntelFsp2Pkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: IA32,X64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 @@ -597,7 +597,7 @@ jobs: env: SELFPKG: IntelFsp2WrapperPkg SELFPKG_DIR: IntelFsp2WrapperPkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: IA32,X64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 @@ -609,7 +609,7 @@ jobs: env: SELFPKG: MdeModulePkg SELFPKG_DIR: MdeModulePkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: IA32,X64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 @@ -621,7 +621,7 @@ jobs: env: SELFPKG: MdePkg SELFPKG_DIR: MdePkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: IA32,X64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 @@ -633,7 +633,7 @@ jobs: env: SELFPKG: UefiCpuPkg SELFPKG_DIR: UefiCpuPkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: IA32,X64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 @@ -645,7 +645,7 @@ jobs: env: SELFPKG: UnitTestFrameworkPkg SELFPKG_DIR: UnitTestFrameworkPkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: IA32,X64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 @@ -657,7 +657,7 @@ jobs: env: SELFPKG: NetworkPkg SELFPKG_DIR: NetworkPkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: IA32,X64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 diff --git a/.github/workflows/build_x86.yaml b/.github/workflows/build_x86.yaml index c7d72fbf40..47fcc276ca 100644 --- a/.github/workflows/build_x86.yaml +++ b/.github/workflows/build_x86.yaml @@ -454,7 +454,7 @@ jobs: path: CLANGDWARF_fw_artifacts.zip build-linux-gcc5: - name: Linux GCC5 + name: Linux GCC runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 @@ -476,7 +476,7 @@ jobs: env: SELFPKG: OvmfPkgIa32 SELFPKG_DIR: OvmfPkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: IA32 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 @@ -489,7 +489,7 @@ jobs: env: SELFPKG: OvmfPkgX64 SELFPKG_DIR: OvmfPkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: X64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 @@ -501,7 +501,7 @@ jobs: env: SELFPKG: OvmfPkgIa32X64 SELFPKG_DIR: OvmfPkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: X64 ARCHS_EXT: IA32 TARGETS: RELEASE,DEBUG,NOOPT @@ -514,7 +514,7 @@ jobs: env: SELFPKG: UefiPayloadPkg SELFPKG_DIR: UefiPayloadPkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: X64 TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 @@ -526,7 +526,7 @@ jobs: env: SELFPKG: UefiPayloadPkg SELFPKG_DIR: UefiPayloadPkg - TOOLCHAINS: GCC5 + TOOLCHAINS: GCC ARCHS: X64 ARCHS_EXT: IA32 TARGETS: RELEASE,DEBUG,NOOPT @@ -547,16 +547,16 @@ jobs: env: ARCHS: Ia32,X64,3264 TARGETS: RELEASE,DEBUG,NOOPT - TOOLCHAIN: GCC5 + TOOLCHAIN: GCC - name: Zip artifacts - run: zip GCC5_fw_artifacts.zip ./firmware_artifacts/* -r + run: zip GCC_fw_artifacts.zip ./firmware_artifacts/* -r - name: Upload to Artifacts uses: actions/upload-artifact@v4 with: - name: GCC5 Firmware Artifacts - path: GCC5_fw_artifacts.zip + name: GCC Firmware Artifacts + path: GCC_fw_artifacts.zip test-firmwares: name: Test @@ -571,7 +571,7 @@ jobs: {name: "Ovmf", archs: "Ia32,X64,3264", toolchain: "VS2019", targets: "RELEASE,DEBUG,NOOPT"}, {name: "Ovmf", archs: "Ia32,X64,3264", toolchain: "CLANGPDB", targets: "RELEASE,DEBUG,NOOPT"}, {name: "Ovmf", archs: "Ia32,X64,3264", toolchain: "CLANGDWARF", targets: "RELEASE,DEBUG,NOOPT"}, - {name: "Ovmf", archs: "Ia32,X64,3264", toolchain: "GCC5", targets: "RELEASE,DEBUG,NOOPT"}, + {name: "Ovmf", archs: "Ia32,X64,3264", toolchain: "GCC", targets: "RELEASE,DEBUG,NOOPT"}, ] steps: - name: Checkout ocbuild repository diff --git a/ArmPlatformPkg/Scripts/Makefile b/ArmPlatformPkg/Scripts/Makefile index baa6184564..686b68614f 100644 --- a/ArmPlatformPkg/Scripts/Makefile +++ b/ArmPlatformPkg/Scripts/Makefile @@ -5,7 +5,7 @@ # #*/ -EDK2_TOOLCHAIN ?= GCC5 +EDK2_TOOLCHAIN ?= GCC EDK2_ARCH ?= ARM EDK2_BUILD ?= DEBUG diff --git a/ArmVirtPkg/PlatformCI/ReadMe.md b/ArmVirtPkg/PlatformCI/ReadMe.md index 4e3709492b..7f54978414 100644 --- a/ArmVirtPkg/PlatformCI/ReadMe.md +++ b/ArmVirtPkg/PlatformCI/ReadMe.md @@ -6,7 +6,7 @@ to use the same Pytools based build infrastructure locally. ## Supported Configuration Details This solution for building and running ArmVirtPkg has been validated with Fedora -37 Linux and the GCC5 toolchain. The following different firmware builds are +37 Linux and the GCC toolchain. The following different firmware builds are supported. | Configuration name | Architecture | DSC File | Additional Flags | diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index 45a68c7ed2..b480904507 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -17,9 +17,8 @@ # - Change RC path to use plugin # 3.00 - Update toolchains # - Add support for ARM and AARCH64 to CLANGDWARF -# - Remove VS2008, VS2010, VS2012, VS2013, CLANG35, CLANG38, EBC, GCC48, GCC49 +# - Remove VS2008, VS2010, VS2012, VS2013, CLANG35, CLANG38, EBC, GCC48, GCC49, GCC5 # - Add GCC and GCCNOLTO -# - Deprecate GCC5. # 3.01 - Add toolchain for VS2022 # 3.02 - Enable stack cookies for IA32, X64, ARM, and AARCH64 builds for GCC and MSVC # @@ -120,8 +119,6 @@ DEFINE CYGWIN_BINX64 = c:/cygwin/opt/tiano/x86_64-pc-mingw64/x86_64-pc DEFINE GCCNOLTO_IA32_PREFIX = ENV(GCCNOLTO_BIN) DEFINE GCCNOLTO_X64_PREFIX = ENV(GCCNOLTO_BIN) -DEFINE GCC5_IA32_PREFIX = ENV(GCC5_BIN) -DEFINE GCC5_X64_PREFIX = ENV(GCC5_BIN) DEFINE GCC_IA32_PREFIX = ENV(GCC_BIN) DEFINE GCC_X64_PREFIX = ENV(GCC_BIN) DEFINE GCC_HOST_PREFIX = ENV(GCC_HOST_BIN) @@ -200,7 +197,7 @@ DEFINE DTC_BIN = ENV(DTC_PREFIX)dtc # Required to build EBC drivers: # Intel(r) Compiler for Efi Byte Code (Intel(r) EBC Compiler) # GCCNOLTO -Linux,Windows- Requires: -# GCC 4.9 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi +# GCC 5 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi # Optional: # Required to build platforms or ACPI tables: # Intel(r) ACPI Compiler from @@ -231,15 +228,6 @@ DEFINE DTC_BIN = ENV(DTC_PREFIX)dtc # Intel(r) ACPI Compiler (iasl.exe) from # https://acpica.org/downloads # -# Deprecated Tool Chains -# ====================== -# GCC5 -Linux,Windows- Requires: -# GCC 5 with LTO support, targeting x86_64-linux-gnu, aarch64-linux-gnu, arm-linux-gnueabi, riscv64-linux-gnu or loongarch64-linux-gnu -# Optional: -# Required to build platforms or ACPI tables: -# Intel(r) ACPI Compiler from -# https://acpica.org/downloads -# #################################################################################### #################################################################################### # @@ -1145,213 +1133,6 @@ RELEASE_GCCNOLTO_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 NOOPT_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -O0 NOOPT_GCCNOLTO_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 -O0 -#################################################################################### -# -# GCC 5 - This configuration is used to compile under Linux to produce -# PE/COFF binaries using GCC 5 -# -#################################################################################### -*_GCC5_*_*_FAMILY = GCC - -*_GCC5_*_MAKE_PATH = DEF(GCC_HOST_PREFIX)make -*_GCC5_*_*_DLL = ENV(GCC5_DLL) -*_GCC5_*_ASL_PATH = DEF(UNIX_IASL_BIN) - -*_GCC5_*_PP_FLAGS = DEF(GCC_PP_FLAGS) -*_GCC5_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) -*_GCC5_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -*_GCC5_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -*_GCC5_*_APP_FLAGS = -*_GCC5_*_ASL_FLAGS = DEF(IASL_FLAGS) -*_GCC5_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS) -*_GCC5_*_DEPS_FLAGS = DEF(GCC_DEPS_FLAGS) - -################## -# GCC5 IA32 definitions -################## -*_GCC5_IA32_OBJCOPY_PATH = DEF(GCC5_IA32_PREFIX)objcopy -*_GCC5_IA32_CC_PATH = DEF(GCC5_IA32_PREFIX)gcc -*_GCC5_IA32_SLINK_PATH = DEF(GCC5_IA32_PREFIX)gcc-ar -*_GCC5_IA32_DLINK_PATH = DEF(GCC5_IA32_PREFIX)gcc -*_GCC5_IA32_ASLDLINK_PATH = DEF(GCC5_IA32_PREFIX)gcc -*_GCC5_IA32_ASM_PATH = DEF(GCC5_IA32_PREFIX)gcc -*_GCC5_IA32_PP_PATH = DEF(GCC5_IA32_PREFIX)gcc -*_GCC5_IA32_VFRPP_PATH = DEF(GCC5_IA32_PREFIX)gcc -*_GCC5_IA32_ASLCC_PATH = DEF(GCC5_IA32_PREFIX)gcc -*_GCC5_IA32_ASLPP_PATH = DEF(GCC5_IA32_PREFIX)gcc -*_GCC5_IA32_RC_PATH = DEF(GCC5_IA32_PREFIX)objcopy - -*_GCC5_IA32_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) -m32 -*_GCC5_IA32_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-q,-m,elf_i386 -no-pie -*_GCC5_IA32_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m32 -march=i386 -*_GCC5_IA32_DLINK2_FLAGS = DEF(GCC5_IA32_DLINK2_FLAGS) -no-pie -*_GCC5_IA32_NASM_FLAGS = -f elf32 -DRODATA_SECTION_NAME=.rodata - - DEBUG_GCC5_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -flto -Os - DEBUG_GCC5_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-q,-m,elf_i386,--oformat=elf32-i386 - -RELEASE_GCC5_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -flto -Os -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC5_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-q,-m,elf_i386,--oformat=elf32-i386 - - NOOPT_GCC5_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -O0 - NOOPT_GCC5_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-q,-m,elf_i386,--oformat=elf32-i386 -O0 - -################## -# GCC5 X64 definitions -################## -*_GCC5_X64_OBJCOPY_PATH = DEF(GCC5_X64_PREFIX)objcopy -*_GCC5_X64_CC_PATH = DEF(GCC5_X64_PREFIX)gcc -*_GCC5_X64_SLINK_PATH = DEF(GCC5_X64_PREFIX)gcc-ar -*_GCC5_X64_DLINK_PATH = DEF(GCC5_X64_PREFIX)gcc -*_GCC5_X64_ASLDLINK_PATH = DEF(GCC5_X64_PREFIX)gcc -*_GCC5_X64_ASM_PATH = DEF(GCC5_X64_PREFIX)gcc -*_GCC5_X64_PP_PATH = DEF(GCC5_X64_PREFIX)gcc -*_GCC5_X64_VFRPP_PATH = DEF(GCC5_X64_PREFIX)gcc -*_GCC5_X64_ASLCC_PATH = DEF(GCC5_X64_PREFIX)gcc -*_GCC5_X64_ASLPP_PATH = DEF(GCC5_X64_PREFIX)gcc -*_GCC5_X64_RC_PATH = DEF(GCC5_X64_PREFIX)objcopy - -*_GCC5_X64_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) -m64 -*_GCC5_X64_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 -*_GCC5_X64_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m64 -*_GCC5_X64_DLINK2_FLAGS = DEF(GCC5_X64_DLINK2_FLAGS) -*_GCC5_X64_NASM_FLAGS = -f elf64 -DRODATA_SECTION_NAME=.rodata - - DEBUG_GCC5_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -flto -DUSING_LTO - DEBUG_GCC5_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os - -RELEASE_GCC5_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -flto -DUSING_LTO -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC5_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os - - NOOPT_GCC5_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -O0 - NOOPT_GCC5_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -O0 - -################## -# GCC5 ARM definitions -################## -*_GCC5_ARM_OBJCOPY_PATH = ENV(GCC5_ARM_PREFIX)objcopy -*_GCC5_ARM_CC_PATH = ENV(GCC5_ARM_PREFIX)gcc -*_GCC5_ARM_SLINK_PATH = ENV(GCC5_ARM_PREFIX)gcc-ar -*_GCC5_ARM_DLINK_PATH = ENV(GCC5_ARM_PREFIX)gcc -*_GCC5_ARM_ASLDLINK_PATH = ENV(GCC5_ARM_PREFIX)gcc -*_GCC5_ARM_ASM_PATH = ENV(GCC5_ARM_PREFIX)gcc -*_GCC5_ARM_PP_PATH = ENV(GCC5_ARM_PREFIX)gcc -*_GCC5_ARM_VFRPP_PATH = ENV(GCC5_ARM_PREFIX)gcc -*_GCC5_ARM_ASLCC_PATH = ENV(GCC5_ARM_PREFIX)gcc -*_GCC5_ARM_ASLPP_PATH = ENV(GCC5_ARM_PREFIX)gcc -*_GCC5_ARM_RC_PATH = ENV(GCC5_ARM_PREFIX)objcopy - -*_GCC5_ARM_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) -*_GCC5_ARM_ASLDLINK_FLAGS = DEF(GCC5_ARM_ASLDLINK_FLAGS) -*_GCC5_ARM_ASM_FLAGS = DEF(GCC5_ARM_ASM_FLAGS) -*_GCC5_ARM_DLINK2_FLAGS = DEF(GCC5_ARM_DLINK2_FLAGS) -*_GCC5_ARM_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC5_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS) -mthumb -march=armv7-a -*_GCC5_ARM_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -mthumb -march=armv7-a -*_GCC5_ARM_CC_SECPEIFLAGS = DEF(GCC_ARM_CC_SECPEIFLAGS) - - DEBUG_GCC5_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable - DEBUG_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm - -RELEASE_GCC5_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm - - NOOPT_GCC5_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -O0 - NOOPT_GCC5_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -O0 - -################## -# GCC5 AARCH64 definitions -################## -*_GCC5_AARCH64_OBJCOPY_PATH = ENV(GCC5_AARCH64_PREFIX)objcopy -*_GCC5_AARCH64_CC_PATH = ENV(GCC5_AARCH64_PREFIX)gcc -*_GCC5_AARCH64_SLINK_PATH = ENV(GCC5_AARCH64_PREFIX)gcc-ar -*_GCC5_AARCH64_DLINK_PATH = ENV(GCC5_AARCH64_PREFIX)gcc -*_GCC5_AARCH64_ASLDLINK_PATH = ENV(GCC5_AARCH64_PREFIX)gcc -*_GCC5_AARCH64_ASM_PATH = ENV(GCC5_AARCH64_PREFIX)gcc -*_GCC5_AARCH64_PP_PATH = ENV(GCC5_AARCH64_PREFIX)gcc -*_GCC5_AARCH64_VFRPP_PATH = ENV(GCC5_AARCH64_PREFIX)gcc -*_GCC5_AARCH64_ASLCC_PATH = ENV(GCC5_AARCH64_PREFIX)gcc -*_GCC5_AARCH64_ASLPP_PATH = ENV(GCC5_AARCH64_PREFIX)gcc -*_GCC5_AARCH64_RC_PATH = ENV(GCC5_AARCH64_PREFIX)objcopy - -*_GCC5_AARCH64_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) -*_GCC5_AARCH64_ASLDLINK_FLAGS = DEF(GCC5_AARCH64_ASLDLINK_FLAGS) -*_GCC5_AARCH64_ASM_FLAGS = DEF(GCC5_AARCH64_ASM_FLAGS) -*_GCC5_AARCH64_DLINK2_FLAGS = DEF(GCC5_AARCH64_DLINK2_FLAGS) -*_GCC5_AARCH64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC5_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) -*_GCC5_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -*_GCC5_AARCH64_CC_SECPEIFLAGS = DEF(GCC_AARCH64_CC_SECPEIFLAGS) - - DEBUG_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable - DEBUG_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch - DEBUG_GCC5_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) - -RELEASE_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch -RELEASE_GCC5_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) - - NOOPT_GCC5_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 - NOOPT_GCC5_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -O0 - NOOPT_GCC5_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) -O0 - -#################################################################################### -# -# GCC RISC-V This configuration is used to compile under Linux to produce -# PE/COFF binaries using GCC RISC-V tool chain -# -#################################################################################### - -################## -# GCC5 RISCV64 definitions -################## -*_GCC5_RISCV64_OBJCOPY_PATH = ENV(GCC5_RISCV64_PREFIX)objcopy -*_GCC5_RISCV64_CC_PATH = ENV(GCC5_RISCV64_PREFIX)gcc -*_GCC5_RISCV64_SLINK_PATH = ENV(GCC5_RISCV64_PREFIX)gcc-ar -*_GCC5_RISCV64_DLINK_PATH = ENV(GCC5_RISCV64_PREFIX)gcc -*_GCC5_RISCV64_ASLDLINK_PATH = ENV(GCC5_RISCV64_PREFIX)gcc -*_GCC5_RISCV64_ASM_PATH = ENV(GCC5_RISCV64_PREFIX)gcc -*_GCC5_RISCV64_PP_PATH = ENV(GCC5_RISCV64_PREFIX)gcc -*_GCC5_RISCV64_VFRPP_PATH = ENV(GCC5_RISCV64_PREFIX)gcc -*_GCC5_RISCV64_ASLCC_PATH = ENV(GCC5_RISCV64_PREFIX)gcc -*_GCC5_RISCV64_ASLPP_PATH = ENV(GCC5_RISCV64_PREFIX)gcc -*_GCC5_RISCV64_RC_PATH = ENV(GCC5_RISCV64_PREFIX)objcopy - -*_GCC5_RISCV64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -*_GCC5_RISCV64_ASLDLINK_FLAGS = DEF(GCC5_RISCV32_RISCV64_ASLDLINK_FLAGS) -*_GCC5_RISCV64_ASM_FLAGS = DEF(GCC5_RISCV64_ASM_FLAGS) -*_GCC5_RISCV64_CC_FLAGS = DEF(GCC5_RISCV64_CC_FLAGS) -save-temps -*_GCC5_RISCV64_DLINK_FLAGS = DEF(GCC5_RISCV64_DLINK_FLAGS) -*_GCC5_RISCV64_DLINK2_FLAGS = DEF(GCC5_RISCV64_DLINK2_FLAGS) -*_GCC5_RISCV64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC5_RISCV64_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(GCC5_RISCV_OPENSBI_TYPES) - -################## -# GCC5 LOONGARCH64 definitions -################## -*_GCC5_LOONGARCH64_OBJCOPY_PATH = ENV(GCC5_LOONGARCH64_PREFIX)objcopy -*_GCC5_LOONGARCH64_CC_PATH = ENV(GCC5_LOONGARCH64_PREFIX)gcc -*_GCC5_LOONGARCH64_SLINK_PATH = ENV(GCC5_LOONGARCH64_PREFIX)gcc-ar -*_GCC5_LOONGARCH64_DLINK_PATH = ENV(GCC5_LOONGARCH64_PREFIX)gcc -*_GCC5_LOONGARCH64_ASLDLINK_PATH = ENV(GCC5_LOONGARCH64_PREFIX)gcc -*_GCC5_LOONGARCH64_ASM_PATH = ENV(GCC5_LOONGARCH64_PREFIX)gcc -*_GCC5_LOONGARCH64_PP_PATH = ENV(GCC5_LOONGARCH64_PREFIX)gcc -*_GCC5_LOONGARCH64_VFRPP_PATH = ENV(GCC5_LOONGARCH64_PREFIX)gcc -*_GCC5_LOONGARCH64_ASLCC_PATH = ENV(GCC5_LOONGARCH64_PREFIX)gcc -*_GCC5_LOONGARCH64_ASLPP_PATH = ENV(GCC5_LOONGARCH64_PREFIX)gcc -*_GCC5_LOONGARCH64_RC_PATH = ENV(GCC5_LOONGARCH64_PREFIX)objcopy - -*_GCC5_LOONGARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -*_GCC5_LOONGARCH64_ASLDLINK_FLAGS = DEF(GCC5_LOONGARCH64_ASLDLINK_FLAGS) -*_GCC5_LOONGARCH64_ASM_FLAGS = DEF(GCC5_LOONGARCH64_ASM_FLAGS) -*_GCC5_LOONGARCH64_DLINK_FLAGS = DEF(GCC5_LOONGARCH64_DLINK_FLAGS) -*_GCC5_LOONGARCH64_DLINK2_FLAGS = DEF(GCC5_LOONGARCH64_DLINK2_FLAGS) -*_GCC5_LOONGARCH64_NASM_FLAGS = -f elf32 -*_GCC5_LOONGARCH64_PP_FLAGS = DEF(GCC5_LOONGARCH64_PP_FLAGS) - -DEBUG_GCC5_LOONGARCH64_CC_FLAGS = DEF(GCC5_LOONGARCH64_CC_FLAGS) -RELEASE_GCC5_LOONGARCH64_CC_FLAGS = DEF(GCC5_LOONGARCH64_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-variable - #################################################################################### # # GCC - This configuration is used to compile under Linux to produce @@ -1361,7 +1142,7 @@ RELEASE_GCC5_LOONGARCH64_CC_FLAGS = DEF(GCC5_LOONGARCH64_CC_FLAGS) -Wno-un *_GCC_*_*_FAMILY = GCC *_GCC_*_MAKE_PATH = DEF(GCC_HOST_PREFIX)make -*_GCC_*_*_DLL = ENV(GCC_DLL) +*_GCC_*_*_DLL = ENV(GCC5_DLL) *_GCC_*_ASL_PATH = DEF(UNIX_IASL_BIN) *_GCC_*_PP_FLAGS = DEF(GCC_PP_FLAGS) @@ -1371,7 +1152,7 @@ RELEASE_GCC5_LOONGARCH64_CC_FLAGS = DEF(GCC5_LOONGARCH64_CC_FLAGS) -Wno-un *_GCC_*_APP_FLAGS = *_GCC_*_ASL_FLAGS = DEF(IASL_FLAGS) *_GCC_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS) -*_GCC_*_DEPS_FLAGS = DEF(GCC_DEPS_FLAGS) +*_GCC_*_DEPS_FLAGS = DEF(GCC_DEPS_FLAGS) ################## # GCC IA32 definitions @@ -1389,20 +1170,19 @@ RELEASE_GCC5_LOONGARCH64_CC_FLAGS = DEF(GCC5_LOONGARCH64_CC_FLAGS) -Wno-un *_GCC_IA32_RC_PATH = DEF(GCC_IA32_PREFIX)objcopy *_GCC_IA32_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) -m32 -*_GCC_IA32_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -no-pie +*_GCC_IA32_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-q,-m,elf_i386 -no-pie *_GCC_IA32_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m32 -march=i386 *_GCC_IA32_DLINK2_FLAGS = DEF(GCC5_IA32_DLINK2_FLAGS) -no-pie -*_GCC_IA32_OBJCOPY_FLAGS = -*_GCC_IA32_NASM_FLAGS = -f elf32 +*_GCC_IA32_NASM_FLAGS = -f elf32 -DRODATA_SECTION_NAME=.rodata - DEBUG_GCC_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -flto - DEBUG_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-m,elf_i386,--oformat=elf32-i386 + DEBUG_GCC_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -flto -Os + DEBUG_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-q,-m,elf_i386,--oformat=elf32-i386 -RELEASE_GCC_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-m,elf_i386,--oformat=elf32-i386 +RELEASE_GCC_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -flto -Os -Wno-unused-but-set-variable -Wno-unused-const-variable +RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-q,-m,elf_i386,--oformat=elf32-i386 NOOPT_GCC_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -O0 - NOOPT_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-m,elf_i386,--oformat=elf32-i386 -O0 + NOOPT_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-q,-m,elf_i386,--oformat=elf32-i386 -O0 ################## # GCC X64 definitions @@ -1423,8 +1203,7 @@ RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,- *_GCC_X64_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 *_GCC_X64_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m64 *_GCC_X64_DLINK2_FLAGS = DEF(GCC5_X64_DLINK2_FLAGS) -*_GCC_X64_OBJCOPY_FLAGS = -*_GCC_X64_NASM_FLAGS = -f elf64 +*_GCC_X64_NASM_FLAGS = -f elf64 -DRODATA_SECTION_NAME=.rodata DEBUG_GCC_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -flto -DUSING_LTO DEBUG_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os @@ -1438,6 +1217,7 @@ RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os ################## # GCC ARM definitions ################## +*_GCC_ARM_OBJCOPY_PATH = ENV(GCC_ARM_PREFIX)objcopy *_GCC_ARM_CC_PATH = ENV(GCC_ARM_PREFIX)gcc *_GCC_ARM_SLINK_PATH = ENV(GCC_ARM_PREFIX)gcc-ar *_GCC_ARM_DLINK_PATH = ENV(GCC_ARM_PREFIX)gcc @@ -1454,9 +1234,8 @@ RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os *_GCC_ARM_ASM_FLAGS = DEF(GCC5_ARM_ASM_FLAGS) *_GCC_ARM_DLINK2_FLAGS = DEF(GCC5_ARM_DLINK2_FLAGS) *_GCC_ARM_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC_ARM_PLATFORM_FLAGS = -march=armv7-a -mfloat-abi=soft -*_GCC_ARM_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) -*_GCC_ARM_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) +*_GCC_ARM_PP_FLAGS = DEF(GCC_PP_FLAGS) -mthumb -march=armv7-a +*_GCC_ARM_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -mthumb -march=armv7-a *_GCC_ARM_CC_SECPEIFLAGS = DEF(GCC_ARM_CC_SECPEIFLAGS) DEBUG_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable @@ -1471,6 +1250,7 @@ RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSP ################## # GCC AARCH64 definitions ################## +*_GCC_AARCH64_OBJCOPY_PATH = ENV(GCC_AARCH64_PREFIX)objcopy *_GCC_AARCH64_CC_PATH = ENV(GCC_AARCH64_PREFIX)gcc *_GCC_AARCH64_SLINK_PATH = ENV(GCC_AARCH64_PREFIX)gcc-ar *_GCC_AARCH64_DLINK_PATH = ENV(GCC_AARCH64_PREFIX)gcc @@ -1487,22 +1267,21 @@ RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSP *_GCC_AARCH64_ASM_FLAGS = DEF(GCC5_AARCH64_ASM_FLAGS) *_GCC_AARCH64_DLINK2_FLAGS = DEF(GCC5_AARCH64_DLINK2_FLAGS) *_GCC_AARCH64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCC_AARCH64_PLATFORM_FLAGS = -*_GCC_AARCH64_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) -*_GCC_AARCH64_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) +*_GCC_AARCH64_PP_FLAGS = DEF(GCC_PP_FLAGS) +*_GCC_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) *_GCC_AARCH64_CC_SECPEIFLAGS = DEF(GCC_AARCH64_CC_SECPEIFLAGS) DEBUG_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable DEBUG_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch - DEBUG_GCC_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 + DEBUG_GCC_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) RELEASE_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable RELEASE_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch -RELEASE_GCC_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 +RELEASE_GCC_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) NOOPT_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 NOOPT_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -O0 - NOOPT_GCC_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 -O0 + NOOPT_GCC_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) -O0 #################################################################################### # @@ -1532,7 +1311,6 @@ RELEASE_GCC_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 *_GCC_RISCV64_CC_FLAGS = DEF(GCC5_RISCV64_CC_FLAGS) -save-temps *_GCC_RISCV64_DLINK_FLAGS = DEF(GCC5_RISCV64_DLINK_FLAGS) *_GCC_RISCV64_DLINK2_FLAGS = DEF(GCC5_RISCV64_DLINK2_FLAGS) -*_GCC_RISCV64_OBJCOPY_FLAGS = *_GCC_RISCV64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) *_GCC_RISCV64_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(GCC5_RISCV_OPENSBI_TYPES) @@ -1556,7 +1334,6 @@ RELEASE_GCC_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 *_GCC_LOONGARCH64_ASM_FLAGS = DEF(GCC5_LOONGARCH64_ASM_FLAGS) *_GCC_LOONGARCH64_DLINK_FLAGS = DEF(GCC5_LOONGARCH64_DLINK_FLAGS) *_GCC_LOONGARCH64_DLINK2_FLAGS = DEF(GCC5_LOONGARCH64_DLINK2_FLAGS) -*_GCC_LOONGARCH64_OBJCOPY_FLAGS = *_GCC_LOONGARCH64_NASM_FLAGS = -f elf32 *_GCC_LOONGARCH64_PP_FLAGS = DEF(GCC5_LOONGARCH64_PP_FLAGS) diff --git a/BaseTools/Edk2ToolsBuild.py b/BaseTools/Edk2ToolsBuild.py index 9ed5367d2d..bc6d573d86 100644 --- a/BaseTools/Edk2ToolsBuild.py +++ b/BaseTools/Edk2ToolsBuild.py @@ -1,7 +1,7 @@ # @file Edk2ToolsBuild.py # Invocable class that builds the basetool c files. # -# Supports VS2019, VS2022, and GCC5 +# Supports VS2019, VS2022, and GCC ## # Copyright (c) Microsoft Corporation # diff --git a/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py b/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py index c39dae236c..39063b40bc 100644 --- a/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py +++ b/BaseTools/Plugin/HostBasedUnitTestRunner/HostBasedUnitTestRunner.py @@ -138,7 +138,7 @@ def do_post_build(self, thebuilder): failure_count += 1 if thebuilder.env.GetValue("CODE_COVERAGE") != "FALSE": - if thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "GCC5": + if thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "GCC": ret = self.gen_code_coverage_gcc(thebuilder) if ret != 0: failure_count += 1 diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf index 21d63b15ea..2233459398 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf @@ -757,7 +757,7 @@ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize # Revisit after switching to 3.0 branch - GCC:*_GCC5_*_CC_FLAGS = -Wno-unused-but-set-variable + GCC:*_GCC_*_CC_FLAGS = -Wno-unused-but-set-variable # suppress the following warnings in openssl so we don't break the build with warnings-as-errors: # 1295: Deprecated declaration - give arg types diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf index d112dfc3ec..582912192a 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibAccel.inf @@ -2140,7 +2140,7 @@ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=gnu99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize # Revisit after switching to 3.0 branch - GCC:*_GCC5_*_CC_FLAGS = -Wno-unused-but-set-variable + GCC:*_GCC_*_CC_FLAGS = -Wno-unused-but-set-variable # suppress the following warnings in openssl so we don't break the build with warnings-as-errors: # 1295: Deprecated declaration - give arg types diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf index 66aa304afb..140639fa68 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf @@ -708,7 +708,7 @@ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize # Revisit after switching to 3.0 branch - GCC:*_GCC5_*_CC_FLAGS = -Wno-unused-but-set-variable + GCC:*_GCC_*_CC_FLAGS = -Wno-unused-but-set-variable # suppress the following warnings in openssl so we don't break the build with warnings-as-errors: # 1295: Deprecated declaration - give arg types diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf b/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf index d063e9abb0..2c13e36998 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibFull.inf @@ -814,7 +814,7 @@ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize # Revisit after switching to 3.0 branch - GCC:*_GCC5_*_CC_FLAGS = -Wno-unused-but-set-variable + GCC:*_GCC_*_CC_FLAGS = -Wno-unused-but-set-variable # suppress the following warnings in openssl so we don't break the build with warnings-as-errors: # 1295: Deprecated declaration - give arg types diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf index e7bf8c8294..11e3380311 100644 --- a/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf +++ b/CryptoPkg/Library/OpensslLib/OpensslLibFullAccel.inf @@ -2301,7 +2301,7 @@ GCC:*_CLANGDWARF_*_CC_FLAGS = -std=gnu99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize GCC:*_CLANGPDB_*_CC_FLAGS = -std=c99 -Wno-error=uninitialized -Wno-error=incompatible-pointer-types -Wno-error=pointer-sign -Wno-error=implicit-function-declaration -Wno-error=ignored-pragma-optimize # Revisit after switching to 3.0 branch - GCC:*_GCC5_*_CC_FLAGS = -Wno-unused-but-set-variable + GCC:*_GCC_*_CC_FLAGS = -Wno-unused-but-set-variable # suppress the following warnings in openssl so we don't break the build with warnings-as-errors: # 1295: Deprecated declaration - give arg types diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md index d329641e4f..f7ca1252e7 100644 --- a/DynamicTablesPkg/Readme.md +++ b/DynamicTablesPkg/Readme.md @@ -314,12 +314,12 @@ parameter to the edk2 build system. Example: >build -a AARCH64 -p Platform\ARM\JunoPkg\ArmJuno.dsc - -t GCC5 **-D DYNAMIC_TABLES_FRAMEWORK** + -t GCC **-D DYNAMIC_TABLES_FRAMEWORK** or >build -a AARCH64 -p Platform\ARM\VExpressPkg\ArmVExpress-FVP-AArch64.dsc - -t GCC5 **-D DYNAMIC_TABLES_FRAMEWORK** + -t GCC **-D DYNAMIC_TABLES_FRAMEWORK** # Prerequisites @@ -369,7 +369,7 @@ The instructions to setup the CI environment are in *'edk2\\.pytool\\Readme.md'* ``` stuart_setup -c .pytool/CISettings.py TOOL_CHAIN_TAG= -a - e.g. stuart_setup -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5 + e.g. stuart_setup -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC ``` 5. Initialize & Update Dependencies - only as needed when ext_deps change @@ -377,7 +377,7 @@ The instructions to setup the CI environment are in *'edk2\\.pytool\\Readme.md'* ``` stuart_update -c .pytool/CISettings.py TOOL_CHAIN_TAG= -a - e.g. stuart_update -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5 + e.g. stuart_update -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC ``` 6. Compile the basetools if necessary - only when basetools C source files change @@ -391,7 +391,7 @@ The instructions to setup the CI environment are in *'edk2\\.pytool\\Readme.md'* ``` stuart_build-c .pytool/CISettings.py TOOL_CHAIN_TAG= -a - e.g. stuart_ci_build -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5 -p DynamicTablesPkg -a AARCH64 --verbose + e.g. stuart_ci_build -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC -p DynamicTablesPkg -a AARCH64 --verbose ``` - use `stuart_build -c .pytool/CISettings.py -h` option to see help on additional options. diff --git a/EmulatorPkg/PlatformCI/ReadMe.md b/EmulatorPkg/PlatformCI/ReadMe.md index 3e85a7296b..54a7330734 100644 --- a/EmulatorPkg/PlatformCI/ReadMe.md +++ b/EmulatorPkg/PlatformCI/ReadMe.md @@ -6,7 +6,7 @@ to use the same Pytools based build infrastructure locally. ## Supported Configuration Details This solution for building and running EmulatorPkg has only been validated with Windows 10 -with VS2022 and Ubuntu 18.04 with GCC5 toolchain. Four different firmware builds are +with VS2022 and Ubuntu 18.04 with GCC toolchain. Four different firmware builds are supported and are described below. | Configuration name | Architectures | DSC File |Additional Flags | diff --git a/EmulatorPkg/Readme.md b/EmulatorPkg/Readme.md index 2e6837ca4c..1cf267c92f 100644 --- a/EmulatorPkg/Readme.md +++ b/EmulatorPkg/Readme.md @@ -29,11 +29,11 @@ https://github.com/tianocore/tianocore.github.io/wiki/EmulatorPkg * 32bit emulator in Linux: - `build -p EmulatorPkg\EmulatorPkg.dsc -t GCC5 -a IA32` + `build -p EmulatorPkg\EmulatorPkg.dsc -t GCC -a IA32` * 64bit emulator in Linux: - `build -p EmulatorPkg\EmulatorPkg.dsc -t GCC5 -a X64` + `build -p EmulatorPkg\EmulatorPkg.dsc -t GCC -a X64` **You can start/run the emulator using the following command:** * 32bit emulator in Windows: @@ -46,11 +46,11 @@ https://github.com/tianocore/tianocore.github.io/wiki/EmulatorPkg * 32bit emulator in Linux: - `cd Build/EmulatorIA32/DEBUG_GCC5/IA32/ && ./Host` + `cd Build/EmulatorIA32/DEBUG_GCC/IA32/ && ./Host` * 64bit emulator in Linux: - `cd Build/EmulatorX64/DEBUG_GCC5/X64/ && ./Host` + `cd Build/EmulatorX64/DEBUG_GCC/X64/ && ./Host` **On posix-like environment with the bash shell you can use EmulatorPkg/build.sh to simplify building and running emulator.** diff --git a/EmulatorPkg/Unix/Host/Host.inf b/EmulatorPkg/Unix/Host/Host.inf index f44d060721..d2c4a69d48 100644 --- a/EmulatorPkg/Unix/Host/Host.inf +++ b/EmulatorPkg/Unix/Host/Host.inf @@ -120,9 +120,8 @@ GCC:*_*_IA32_ASM_FLAGS == -m32 -c -x assembler -imacros $(DEST_DIR_DEBUG)/AutoGen.h GCC:*_*_X64_DLINK_FLAGS == -o $(BIN_DIR)/Host -m64 -L/usr/X11R6/lib - GCC:*_GCC5_X64_DLINK_FLAGS == -flto -o $(BIN_DIR)/Host -m64 -L/usr/X11R6/lib + GCC:*_GCC_X64_DLINK_FLAGS == -flto -o $(BIN_DIR)/Host -m64 -L/usr/X11R6/lib GCC:*_*_X64_CC_FLAGS == -m64 -g -fshort-wchar -fno-strict-aliasing -Wall -malign-double -idirafter/usr/include -c -include $(DEST_DIR_DEBUG)/AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings - GCC:*_GCC5_X64_CC_FLAGS = "-DEFIAPI=__attribute__((ms_abi))" -flto -DUSING_LTO -Os GCC:*_GCC_X64_CC_FLAGS = "-DEFIAPI=__attribute__((ms_abi))" -flto -DUSING_LTO -Os GCC:*_*_X64_PP_FLAGS == -m64 -E -x assembler-with-cpp -include $(DEST_DIR_DEBUG)/AutoGen.h GCC:*_*_X64_ASM_FLAGS == -m64 -c -x assembler -imacros $(DEST_DIR_DEBUG)/AutoGen.h diff --git a/EmulatorPkg/build.sh b/EmulatorPkg/build.sh index 5bf1a82d83..7d92892141 100755 --- a/EmulatorPkg/build.sh +++ b/EmulatorPkg/build.sh @@ -42,7 +42,7 @@ PLATFORMFILE= LAST_ARG= RUN_EMULATOR=no CLEAN_TYPE=none -TARGET_TOOLS=GCC5 +TARGET_TOOLS=GCC NETWORK_SUPPORT= BUILD_NEW_SHELL= BUILD_FAT= @@ -92,7 +92,7 @@ case `uname` in exit 1 ;; *) - TARGET_TOOLS=GCC5 + TARGET_TOOLS=GCC ;; esac ;; diff --git a/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc b/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc index c9478d49c2..fa35cf86ab 100644 --- a/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc +++ b/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc @@ -461,7 +461,7 @@ ################################################################################################### [BuildOptions] # Append build options for EDK and EDKII drivers (= is Append, == is Replace) - *_GCC5_IA32_CC_FLAGS = -fno-pic - *_GCC5_IA32_DLINK_FLAGS = -no-pie - *_GCC5_IA32_ASLCC_FLAGS = -fno-pic - *_GCC5_IA32_ASLDLINK_FLAGS = -no-pie + *_GCC_IA32_CC_FLAGS = -fno-pic + *_GCC_IA32_DLINK_FLAGS = -no-pie + *_GCC_IA32_ASLCC_FLAGS = -fno-pic + *_GCC_IA32_ASLDLINK_FLAGS = -no-pie diff --git a/OvmfPkg/CloudHv/README b/OvmfPkg/CloudHv/README index 63e28860e0..10c48219b0 100644 --- a/OvmfPkg/CloudHv/README +++ b/OvmfPkg/CloudHv/README @@ -46,7 +46,7 @@ follows: ./cloud-hypervisor \ --cpus boot=1 \ --memory size=1G \ - --kernel Build/CloudHvX64/DEBUG_GCC5/FV/CLOUDHV.fd \ + --kernel Build/CloudHvX64/DEBUG_GCC/FV/CLOUDHV.fd \ --disk path=/path/to/disk.raw Releases diff --git a/OvmfPkg/IntelTdx/README.md b/OvmfPkg/IntelTdx/README.md index 6e13c1748e..9e0eda6840 100644 --- a/OvmfPkg/IntelTdx/README.md +++ b/OvmfPkg/IntelTdx/README.md @@ -62,17 +62,17 @@ cd /path/to/edk2 source edksetup.sh ## CC_MEASUREMENT disabled -build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC5 -D CC_MEASUREMENT_ENABLE=FALSE -b RELEASE +build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC -D CC_MEASUREMENT_ENABLE=FALSE -b RELEASE ## CC_MEASUREMENT enabled -build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC5 -D CC_MEASUREMENT_ENABLE=TRUE -b RELEASE +build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC -D CC_MEASUREMENT_ENABLE=TRUE -b RELEASE ``` - Build the TDVF (Config-B) target: ``` cd /path/to/edk2 source edksetup.sh -build -p OvmfPkg/IntelTdx/IntelTdxX64.dsc -a X64 -t GCC5 -b RELEASE +build -p OvmfPkg/IntelTdx/IntelTdxX64.dsc -a X64 -t GCC -b RELEASE ``` Usage diff --git a/OvmfPkg/PlatformCI/ReadMe.md b/OvmfPkg/PlatformCI/ReadMe.md index 50d56c3995..1ca5ed02ba 100644 --- a/OvmfPkg/PlatformCI/ReadMe.md +++ b/OvmfPkg/PlatformCI/ReadMe.md @@ -6,7 +6,7 @@ to use the same Pytools based build infrastructure locally. ## Supported Configuration Details This solution for building and running OvmfPkg has only been validated with Windows 10 -with VS2022 and Ubuntu 18.04 with GCC5 toolchain. Four different firmware builds are +with VS2022 and Ubuntu 18.04 with GCC toolchain. Four different firmware builds are supported and are described below. | Configuration name | Architectures | DSC File |Additional Flags | diff --git a/OvmfPkg/README b/OvmfPkg/README index 73c85099d2..4b6ba2af1b 100644 --- a/OvmfPkg/README +++ b/OvmfPkg/README @@ -120,7 +120,7 @@ And to run a 64-bit UEFI bootable ISO image: $ OvmfPkg/build.sh -a X64 qemu -cdrom /path/to/disk-image.iso To build a 32-bit OVMF without debug messages using GCC 5: -$ OvmfPkg/build.sh -a IA32 -b RELEASE -t GCC5 +$ OvmfPkg/build.sh -a IA32 -b RELEASE -t GCC === Secure Boot === diff --git a/OvmfPkg/build.sh b/OvmfPkg/build.sh index f14b7f72ff..1832b44d25 100755 --- a/OvmfPkg/build.sh +++ b/OvmfPkg/build.sh @@ -82,7 +82,7 @@ case `uname` in exit 1 ;; *) - TARGET_TOOLS=GCC5 + TARGET_TOOLS=GCC ;; esac esac diff --git a/PrmPkg/Readme.md b/PrmPkg/Readme.md index 557cb9cbef..999283229b 100644 --- a/PrmPkg/Readme.md +++ b/PrmPkg/Readme.md @@ -71,10 +71,10 @@ on IA32 with the unique UEFI configuration required. > later in this document and dump the PRMT table in the OS to check if your PRM module is represented as expected. * AArch64 - ``build -p PrmPkg/PrmPkg.dsc -a AARCH64 -t GCC5`` + ``build -p PrmPkg/PrmPkg.dsc -a AARCH64 -t GCC`` - > ***Note***: Only builds with the GCC5 toolchain have been tested. - > ***Note***: For builds with the GCC5 toolchain, the PrmModuleExportDescriptor and any other handler entry points + > ***Note***: Only builds with the GCC toolchain have been tested. + > ***Note***: For builds with the GCC toolchain, the PrmModuleExportDescriptor and any other handler entry points symbols, to be listed in the PRMT, must be explicitly preserved by enumerating these in the AARCH64 linker flags. The --require-defined linker flag must be used for each symbol to be preserved. diff --git a/STATUS.md b/STATUS.md index c0c25990ac..c55c07dd37 100644 --- a/STATUS.md +++ b/STATUS.md @@ -3,14 +3,14 @@ | Name | Architectures | Targets | Compilable | Tested | | :--- | :-----------: | :-----: | :--------: | :----: | | $${\color{lightblue}ArmPkg/}$$ | -| ArmPkg.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF | ❌ | +| ArmPkg.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF | ❌ | | Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.dsc | AARCH64 | DEBUG | ❓ | ❌ | | $${\color{lightblue}ArmPlatformPkg/}$$ | -| ArmPlatformPkg.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF | ❌ | +| ArmPlatformPkg.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF | ❌ | | $${\color{lightblue}ArmVirtPkg/}$$ | | ArmVirtCloudHv.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | | ArmVirtKvmTool.dsc | ARM AARCH64 | DEBUG RELEASE | ❓ | ❌ | -| ArmVirtQemu.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF | ✔ | +| ArmVirtQemu.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF | ✔ | | ArmVirtQemuKernel.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | | ArmVirtXen.dsc | ARM AARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | | $${\color{lightblue}CryptoPkg/}$$ | @@ -23,29 +23,29 @@ | $${\color{lightblue}EmulatorPkg/}$$ | | EmulatorPkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | ❓ | ❌ | | $${\color{lightblue}Ext4Pkg/}$$ | -| Ext4Pkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| Ext4Pkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | | $${\color{lightblue}FatPkg/}$$ | -| FatPkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| FatPkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | | $${\color{lightblue}FmpDevicePkg/}$$ | | FmpDevicePkg.dsc | IA32 X64 ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | | Test/FmpDeviceHostPkgTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | | $${\color{lightblue}IntelFsp2Pkg/}$$ | -| IntelFsp2Pkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| IntelFsp2Pkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | | Tools/Tests/QemuFspPkg.dsc | IA32 X64 | DEBUG RELEASE | ❓ | ❌ | | $${\color{lightblue}IntelFsp2WrapperPkg/}$$ | -| IntelFsp2WrapperPkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| IntelFsp2WrapperPkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | | $${\color{lightblue}MdeModulePkg/}$$ | -| MdeModulePkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| MdeModulePkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | | Test/MdeModulePkgHostTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | | $${\color{lightblue}MdePkg/}$$ | -| MdePkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| MdePkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | | Test/MdePkgHostTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | | $${\color{lightblue}NetworkPkg/}$$ | -| NetworkPkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| NetworkPkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | | $${\color{lightblue}OvmfPkg/}$$ | -| OvmfPkgIa32.dsc | IA32 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ✔ | -| OvmfPkgIa32X64.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ✔ | -| OvmfPkgX64.dsc | X64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ✔ | +| OvmfPkgIa32.dsc | IA32 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ✔ | +| OvmfPkgIa32X64.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ✔ | +| OvmfPkgX64.dsc | X64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ✔ | | OvmfXen.dsc | X64 | DEBUG RELEASE NOOPT | ❓ | ❌ | | AmdSev/AmdSevX64.dsc | X64 | DEBUG RELEASE NOOPT | ❓ | ❌ | | Bhyve/BhyveX64.dsc | X64 | DEBUG RELEASE NOOPT | ❓ | ❌ | @@ -72,10 +72,10 @@ | $${\color{lightblue}StandaloneMmPkg/}$$ | | StandaloneMmPkg.dsc | X64 ARM AARCH64 | DEBUG RELEASE | ❓ | ❌ | | $${\color{lightblue}UefiCpuPkg/}$$ | -| UefiCpuPkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| UefiCpuPkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | | Test/UefiCpuPkgHostTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | | $${\color{lightblue}UefiPayloadPkg/}$$ | -| UefiPayloadPkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| UefiPayloadPkg.dsc | IA32 X64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | | $${\color{lightblue}UnitTestFrameworkPkg/}$$ | -| UnitTestFrameworkPkg.dsc | IA32 X64 ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC5 CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | +| UnitTestFrameworkPkg.dsc | IA32 X64 ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | | Test/UnitTestFrameworkPkgHostTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | diff --git a/UnitTestFrameworkPkg/ReadMe.md b/UnitTestFrameworkPkg/ReadMe.md index 9c069fb7a7..0f13acd0cb 100644 --- a/UnitTestFrameworkPkg/ReadMe.md +++ b/UnitTestFrameworkPkg/ReadMe.md @@ -1379,15 +1379,15 @@ After that, the following commands will set up the build and run the host-based ```bash # Setup repo for building -# stuart_setup -c ./.pytool/CISettings.py TOOL_CHAIN_TAG= +# stuart_setup -c ./.pytool/CISettings.py TOOL_CHAIN_TAG= stuart_setup -c ./.pytool/CISettings.py TOOL_CHAIN_TAG=VS2022 # Update all binary dependencies -# stuart_update -c ./.pytool/CISettings.py TOOL_CHAIN_TAG= +# stuart_update -c ./.pytool/CISettings.py TOOL_CHAIN_TAG= stuart_update -c ./.pytool/CISettings.py TOOL_CHAIN_TAG=VS2022 # Build and run the tests -# stuart_ci_build -c ./.pytool/CISettings.py TOOL_CHAIN_TAG= -t NOOPT [-p ] +# stuart_ci_build -c ./.pytool/CISettings.py TOOL_CHAIN_TAG= -t NOOPT [-p ] stuart_ci_build -c ./.pytool/CISettings.py TOOL_CHAIN_TAG=VS2022 -t NOOPT -p MdePkg ``` @@ -1561,7 +1561,7 @@ lcov linux tool, and parsed using the lcov_cobertura python tool to parse it to ```bash sudo apt-get install -y lcov python -m pip install --upgrade -r ./pip-requirements.txt - stuart_ci_build -c .pytool/CISettings.py -t NOOPT TOOL_CHAIN_TAG=GCC5 -p MdeModulePkg + stuart_ci_build -c .pytool/CISettings.py -t NOOPT TOOL_CHAIN_TAG=GCC -p MdeModulePkg Open Build/coverage.xml ``` - How to see code coverage data on IDE Visual Studio Code From c041043886ba229e42a1370c335aa592cb752b44 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 3 Jul 2023 18:23:09 +0300 Subject: [PATCH 075/341] BaseTools/Conf: Added EDK2_GCC_NOLTO build option. --- BaseTools/Conf/tools_def.template | 203 +++++------------------------- 1 file changed, 33 insertions(+), 170 deletions(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index b480904507..9db8c77278 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -18,7 +18,7 @@ # 3.00 - Update toolchains # - Add support for ARM and AARCH64 to CLANGDWARF # - Remove VS2008, VS2010, VS2012, VS2013, CLANG35, CLANG38, EBC, GCC48, GCC49, GCC5 -# - Add GCC and GCCNOLTO +# - Add GCC # 3.01 - Add toolchain for VS2022 # 3.02 - Enable stack cookies for IA32, X64, ARM, and AARCH64 builds for GCC and MSVC # @@ -61,6 +61,22 @@ DEFINE XCODE_ALIGN = 0x1000 DEFINE XCODE_ADDR = 0x1000 !endif +# +# This configuration is used to compile under Linux to produce +# PE/COFF binaries using GCC without Link Time Optimization +# +!ifdef $(EDK2_GCC_NOLTO) +DEFINE LTO = +DEFINE X64_LTO = +DEFINE ARM_LTO = +DEFINE AARCH64_LTO = +!else +DEFINE LTO = -flto +DEFINE X64_LTO = -flto -DUSING_LTO +DEFINE ARM_LTO = -flto -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm +DEFINE AARCH64_LTO = -flto -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch +!endif + # common path macros DEFINE VS2015_BIN = ENV(VS2015_PREFIX)Vc\bin DEFINE VS2015_DLL = ENV(VS2015_PREFIX)Common7\IDE;DEF(VS2015_BIN) @@ -196,12 +212,6 @@ DEFINE DTC_BIN = ENV(DTC_PREFIX)dtc # Optional: # Required to build EBC drivers: # Intel(r) Compiler for Efi Byte Code (Intel(r) EBC Compiler) -# GCCNOLTO -Linux,Windows- Requires: -# GCC 5 targeting x86_64-linux-gnu, aarch64-linux-gnu, or arm-linux-gnueabi -# Optional: -# Required to build platforms or ACPI tables: -# Intel(r) ACPI Compiler from -# https://acpica.org/downloads # GCC -Linux,Windows- Requires: # GCC 5 with LTO support, targeting x86_64-linux-gnu, aarch64-linux-gnu, arm-linux-gnueabi, riscv64-linux-gnu or loongarch64-linux-gnu # Optional: @@ -993,146 +1003,6 @@ DEFINE GCC5_LOONGARCH64_ASLDLINK_FLAGS = DEF(GCC_LOONGARCH64_ASLDLINK_FLAGS) DEFINE GCC5_LOONGARCH64_ASM_FLAGS = -x assembler-with-cpp -mabi=lp64d -march=loongarch64 -fno-builtin -c -Wall -mno-explicit-relocs DEFINE GCC5_LOONGARCH64_PP_FLAGS = -mabi=lp64d -march=loongarch64 DEF(GCC_PP_FLAGS) -#################################################################################### -# -# GCC NOLTO - This configuration is used to compile under Linux to produce -# PE/COFF binaries using GCC without Link Time Optimization -# -#################################################################################### -*_GCCNOLTO_*_*_FAMILY = GCC - -*_GCCNOLTO_*_MAKE_PATH = DEF(GCC_HOST_PREFIX)make -*_GCCNOLTO_*_*_DLL = ENV(GCCNOLTO_DLL) -*_GCCNOLTO_*_ASL_PATH = DEF(UNIX_IASL_BIN) - -*_GCCNOLTO_*_PP_FLAGS = DEF(GCC_PP_FLAGS) -*_GCCNOLTO_*_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) -*_GCCNOLTO_*_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -*_GCCNOLTO_*_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -*_GCCNOLTO_*_APP_FLAGS = -*_GCCNOLTO_*_ASL_FLAGS = DEF(IASL_FLAGS) -*_GCCNOLTO_*_ASL_OUTFLAGS = DEF(IASL_OUTFLAGS) -*_GCCNOLTO_*_DEPS_FLAGS = DEF(GCC_DEPS_FLAGS) - -################## -# GCCNOLTO IA32 definitions -################## -*_GCCNOLTO_IA32_OBJCOPY_PATH = DEF(GCCNOLTO_IA32_PREFIX)objcopy -*_GCCNOLTO_IA32_CC_PATH = DEF(GCCNOLTO_IA32_PREFIX)gcc -*_GCCNOLTO_IA32_SLINK_PATH = DEF(GCCNOLTO_IA32_PREFIX)ar -*_GCCNOLTO_IA32_DLINK_PATH = DEF(GCCNOLTO_IA32_PREFIX)gcc -*_GCCNOLTO_IA32_ASLDLINK_PATH = DEF(GCCNOLTO_IA32_PREFIX)gcc -*_GCCNOLTO_IA32_ASM_PATH = DEF(GCCNOLTO_IA32_PREFIX)gcc -*_GCCNOLTO_IA32_PP_PATH = DEF(GCCNOLTO_IA32_PREFIX)gcc -*_GCCNOLTO_IA32_VFRPP_PATH = DEF(GCCNOLTO_IA32_PREFIX)gcc -*_GCCNOLTO_IA32_ASLCC_PATH = DEF(GCCNOLTO_IA32_PREFIX)gcc -*_GCCNOLTO_IA32_ASLPP_PATH = DEF(GCCNOLTO_IA32_PREFIX)gcc -*_GCCNOLTO_IA32_RC_PATH = DEF(GCCNOLTO_IA32_PREFIX)objcopy - -*_GCCNOLTO_IA32_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) -m32 -*_GCCNOLTO_IA32_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_i386 -*_GCCNOLTO_IA32_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m32 -march=i386 -*_GCCNOLTO_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-m,elf_i386,--oformat=elf32-i386 -*_GCCNOLTO_IA32_DLINK2_FLAGS = DEF(GCC5_IA32_DLINK2_FLAGS) -*_GCCNOLTO_IA32_OBJCOPY_FLAGS = -*_GCCNOLTO_IA32_NASM_FLAGS = -f elf32 - - DEBUG_GCCNOLTO_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -RELEASE_GCCNOLTO_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable - NOOPT_GCCNOLTO_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -O0 - -################## -# GCCNOLTO X64 definitions -################## -*_GCCNOLTO_X64_OBJCOPY_PATH = DEF(GCCNOLTO_X64_PREFIX)objcopy -*_GCCNOLTO_X64_CC_PATH = DEF(GCCNOLTO_X64_PREFIX)gcc -*_GCCNOLTO_X64_SLINK_PATH = DEF(GCCNOLTO_X64_PREFIX)ar -*_GCCNOLTO_X64_DLINK_PATH = DEF(GCCNOLTO_X64_PREFIX)gcc -*_GCCNOLTO_X64_ASLDLINK_PATH = DEF(GCCNOLTO_X64_PREFIX)gcc -*_GCCNOLTO_X64_ASM_PATH = DEF(GCCNOLTO_X64_PREFIX)gcc -*_GCCNOLTO_X64_PP_PATH = DEF(GCCNOLTO_X64_PREFIX)gcc -*_GCCNOLTO_X64_VFRPP_PATH = DEF(GCCNOLTO_X64_PREFIX)gcc -*_GCCNOLTO_X64_ASLCC_PATH = DEF(GCCNOLTO_X64_PREFIX)gcc -*_GCCNOLTO_X64_ASLPP_PATH = DEF(GCCNOLTO_X64_PREFIX)gcc -*_GCCNOLTO_X64_RC_PATH = DEF(GCCNOLTO_X64_PREFIX)objcopy - -*_GCCNOLTO_X64_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) -m64 -*_GCCNOLTO_X64_ASLDLINK_FLAGS = DEF(GCC5_IA32_X64_ASLDLINK_FLAGS) -Wl,-m,elf_x86_64 -*_GCCNOLTO_X64_ASM_FLAGS = DEF(GCC5_ASM_FLAGS) -m64 -*_GCCNOLTO_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -*_GCCNOLTO_X64_DLINK2_FLAGS = DEF(GCC5_X64_DLINK2_FLAGS) -*_GCCNOLTO_X64_OBJCOPY_FLAGS = -*_GCCNOLTO_X64_NASM_FLAGS = -f elf64 - - DEBUG_GCCNOLTO_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -RELEASE_GCCNOLTO_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable - NOOPT_GCCNOLTO_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -O0 - -################## -# GCCNOLTO ARM definitions -################## -*_GCCNOLTO_ARM_CC_PATH = ENV(GCCNOLTO_ARM_PREFIX)gcc -*_GCCNOLTO_ARM_SLINK_PATH = ENV(GCCNOLTO_ARM_PREFIX)ar -*_GCCNOLTO_ARM_DLINK_PATH = ENV(GCCNOLTO_ARM_PREFIX)gcc -*_GCCNOLTO_ARM_ASLDLINK_PATH = ENV(GCCNOLTO_ARM_PREFIX)gcc -*_GCCNOLTO_ARM_ASM_PATH = ENV(GCCNOLTO_ARM_PREFIX)gcc -*_GCCNOLTO_ARM_PP_PATH = ENV(GCCNOLTO_ARM_PREFIX)gcc -*_GCCNOLTO_ARM_VFRPP_PATH = ENV(GCCNOLTO_ARM_PREFIX)gcc -*_GCCNOLTO_ARM_ASLCC_PATH = ENV(GCCNOLTO_ARM_PREFIX)gcc -*_GCCNOLTO_ARM_ASLPP_PATH = ENV(GCCNOLTO_ARM_PREFIX)gcc -*_GCCNOLTO_ARM_RC_PATH = ENV(GCCNOLTO_ARM_PREFIX)objcopy - -*_GCCNOLTO_ARM_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) -*_GCCNOLTO_ARM_ASLDLINK_FLAGS = DEF(GCC5_ARM_ASLDLINK_FLAGS) -*_GCCNOLTO_ARM_ASM_FLAGS = DEF(GCC5_ARM_ASM_FLAGS) -*_GCCNOLTO_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -*_GCCNOLTO_ARM_DLINK2_FLAGS = DEF(GCC5_ARM_DLINK2_FLAGS) -*_GCCNOLTO_ARM_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCCNOLTO_ARM_PLATFORM_FLAGS = -march=armv7-a -*_GCCNOLTO_ARM_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) -*_GCCNOLTO_ARM_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) -*_GCCNOLTO_ARM_CC_SECPEIFLAGS = DEF(GCC_ARM_CC_SECPEIFLAGS) - - DEBUG_GCCNOLTO_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -O0 -RELEASE_GCCNOLTO_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable - NOOPT_GCCNOLTO_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -O0 - -################## -# GCCNOLTO AARCH64 definitions -################## -*_GCCNOLTO_AARCH64_CC_PATH = ENV(GCCNOLTO_AARCH64_PREFIX)gcc -*_GCCNOLTO_AARCH64_SLINK_PATH = ENV(GCCNOLTO_AARCH64_PREFIX)ar -*_GCCNOLTO_AARCH64_DLINK_PATH = ENV(GCCNOLTO_AARCH64_PREFIX)gcc -*_GCCNOLTO_AARCH64_ASLDLINK_PATH = ENV(GCCNOLTO_AARCH64_PREFIX)gcc -*_GCCNOLTO_AARCH64_ASM_PATH = ENV(GCCNOLTO_AARCH64_PREFIX)gcc -*_GCCNOLTO_AARCH64_PP_PATH = ENV(GCCNOLTO_AARCH64_PREFIX)gcc -*_GCCNOLTO_AARCH64_VFRPP_PATH = ENV(GCCNOLTO_AARCH64_PREFIX)gcc -*_GCCNOLTO_AARCH64_ASLCC_PATH = ENV(GCCNOLTO_AARCH64_PREFIX)gcc -*_GCCNOLTO_AARCH64_ASLPP_PATH = ENV(GCCNOLTO_AARCH64_PREFIX)gcc -*_GCCNOLTO_AARCH64_RC_PATH = ENV(GCCNOLTO_AARCH64_PREFIX)objcopy - -*_GCCNOLTO_AARCH64_ASLCC_FLAGS = DEF(GCC5_ASLCC_FLAGS) -*_GCCNOLTO_AARCH64_ASLDLINK_FLAGS = DEF(GCC5_AARCH64_ASLDLINK_FLAGS) -*_GCCNOLTO_AARCH64_ASM_FLAGS = DEF(GCC5_AARCH64_ASM_FLAGS) -*_GCCNOLTO_AARCH64_DLINK2_FLAGS = DEF(GCC5_AARCH64_DLINK2_FLAGS) -*_GCCNOLTO_AARCH64_DTCPP_FLAGS = DEF(GCC_DTCPP_FLAGS) -*_GCCNOLTO_AARCH64_PLATFORM_FLAGS = -*_GCCNOLTO_AARCH64_PP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_PP_FLAGS) -*_GCCNOLTO_AARCH64_VFRPP_FLAGS = $(PLATFORM_FLAGS) DEF(GCC_VFRPP_FLAGS) -*_GCCNOLTO_AARCH64_CC_SECPEIFLAGS = DEF(GCC_AARCH64_CC_SECPEIFLAGS) - - DEBUG_GCCNOLTO_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 - DEBUG_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) - DEBUG_GCCNOLTO_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 - -RELEASE_GCCNOLTO_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -RELEASE_GCCNOLTO_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 - - NOOPT_GCCNOLTO_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 - NOOPT_GCCNOLTO_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -O0 - NOOPT_GCCNOLTO_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 -O0 - #################################################################################### # # GCC - This configuration is used to compile under Linux to produce @@ -1175,11 +1045,11 @@ RELEASE_GCCNOLTO_AARCH64_DLINK_SECPEIFLAGS = -z common-page-size=0x20 *_GCC_IA32_DLINK2_FLAGS = DEF(GCC5_IA32_DLINK2_FLAGS) -no-pie *_GCC_IA32_NASM_FLAGS = -f elf32 -DRODATA_SECTION_NAME=.rodata - DEBUG_GCC_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -flto -Os - DEBUG_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-q,-m,elf_i386,--oformat=elf32-i386 + DEBUG_GCC_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) DEF(LTO) -Os + DEBUG_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) DEF(LTO) -Os -Wl,-q,-m,elf_i386,--oformat=elf32-i386 -RELEASE_GCC_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -flto -Os -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,-q,-m,elf_i386,--oformat=elf32-i386 +RELEASE_GCC_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) DEF(LTO) -Os -Wno-unused-but-set-variable -Wno-unused-const-variable +RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) DEF(LTO) -Os -Wl,-q,-m,elf_i386,--oformat=elf32-i386 NOOPT_GCC_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -O0 NOOPT_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-q,-m,elf_i386,--oformat=elf32-i386 -O0 @@ -1205,11 +1075,11 @@ RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -flto -Os -Wl,- *_GCC_X64_DLINK2_FLAGS = DEF(GCC5_X64_DLINK2_FLAGS) *_GCC_X64_NASM_FLAGS = -f elf64 -DRODATA_SECTION_NAME=.rodata - DEBUG_GCC_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -flto -DUSING_LTO - DEBUG_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os + DEBUG_GCC_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) DEF(X64_LTO) + DEBUG_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) DEF(LTO) -Os -RELEASE_GCC_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -flto -DUSING_LTO -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os +RELEASE_GCC_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) DEF(X64_LTO) -Wno-unused-but-set-variable -Wno-unused-const-variable +RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) DEF(LTO) -Os NOOPT_GCC_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -O0 NOOPT_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -O0 @@ -1238,11 +1108,11 @@ RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -flto -Os *_GCC_ARM_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) -mthumb -march=armv7-a *_GCC_ARM_CC_SECPEIFLAGS = DEF(GCC_ARM_CC_SECPEIFLAGS) - DEBUG_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable - DEBUG_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm + DEBUG_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) DEF(LTO) -Wno-unused-but-set-variable -Wno-unused-const-variable + DEBUG_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) DEF(ARM_LTO) -Os -RELEASE_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm +RELEASE_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) DEF(LTO) -Wno-unused-but-set-variable -Wno-unused-const-variable +RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) DEF(ARM_LTO) -Os NOOPT_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -O0 NOOPT_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -O0 @@ -1271,25 +1141,18 @@ RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -flto -Os -L$(WORKSP *_GCC_AARCH64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) *_GCC_AARCH64_CC_SECPEIFLAGS = DEF(GCC_AARCH64_CC_SECPEIFLAGS) - DEBUG_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable - DEBUG_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch + DEBUG_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) DEF(LTO) -Wno-unused-but-set-variable -Wno-unused-const-variable + DEBUG_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) DEF(AARCH64_LTO) -Os DEBUG_GCC_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) -RELEASE_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -flto -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -flto -Os -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch +RELEASE_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) DEF(LTO) -Wno-unused-but-set-variable -Wno-unused-const-variable +RELEASE_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) DEF(AARCH64_LTO) -Os RELEASE_GCC_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) NOOPT_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 NOOPT_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -O0 NOOPT_GCC_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) -O0 -#################################################################################### -# -# GCC RISC-V This configuration is used to compile under Linux to produce -# PE/COFF binaries using GCC RISC-V tool chain -# -#################################################################################### - ################## # GCC RISCV64 definitions ################## From 4e04fa016ecc1add98feaaf673c659a150332cc5 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Wed, 5 Jul 2023 16:17:12 +0600 Subject: [PATCH 076/341] CI: Remove Dependabot configuration --- .github/dependabot.yml | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 479440fe63..0000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,36 +0,0 @@ -## @file -# Dependabot configuration file to enable GitHub services for managing and updating -# dependencies. -# -# Copyright (c) Microsoft Corporation. -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -# Please see the documentation for all configuration options: -# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates -## -version: 2 -updates: - - package-ecosystem: "pip" - directory: "/" - schedule: - interval: "daily" - commit-message: - prefix: "pip" - reviewers: - - "makubacki" - - "mdkinney" - - "spbrogan" - rebase-strategy: "disabled" - - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - day: "monday" - commit-message: - prefix: "GitHub Action" - reviewers: - - "makubacki" - - "mdkinney" - - "spbrogan" - rebase-strategy: "disabled" From ec35a44c1e643c7439cf0e407d12bdc86ac1a3dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Fri, 5 May 2023 11:33:30 +0200 Subject: [PATCH 077/341] MdeModulePkg/DxeCore: Re-use ImageIsFromFv for memory protection --- MdeModulePkg/Core/Dxe/DxeMain.h | 7 +- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 2 +- MdeModulePkg/Core/Dxe/Image/Image.c | 2 +- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 92 +++---------------- 4 files changed, 20 insertions(+), 83 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index e520a3b345..53df82381d 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2727,12 +2727,15 @@ RemoveImageRecord ( Protect UEFI image. @param[in] LoadedImage The loaded image protocol + @param[in] ImageType Whether File comes from FV. Must be FALSE + or TRUE. @param[in] LoadedImageDevicePath The loaded image device path protocol **/ VOID ProtectUefiImage ( - IN LOADED_IMAGE_PRIVATE_DATA *Image, - UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN BOOLEAN ImageIsFromFv, + UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); /** diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 7d700055c3..d567400e1e 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -331,7 +331,7 @@ DxeMain ( CoreInitializeMemoryProtection (); - ProtectUefiImage (mCurrentImage, &ImageContext); + ProtectUefiImage (&mCurrentImage->Info, TRUE, &ImageContext); // // Call constructor for all libraries diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index f38a97fede..7e7cdc3103 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1383,7 +1383,7 @@ CoreLoadImageCommon ( } Status = EFI_SUCCESS; - ProtectUefiImage (Image, &ImageContext); + ProtectUefiImage (&Image->Info, ImageIsFromFv, &ImageContext); RegisterMemoryProfileImage ( Image->LoadedImageDevicePath, diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 2d568b2463..5692900e2d 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -47,12 +47,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "ProcessorBind.h" #include "Uefi/UefiMultiPhase.h" -// -// Image type definitions -// -#define IMAGE_UNKNOWN 0x00000001 -#define IMAGE_FROM_FV 0x00000002 - // // Protection policy bit definition // @@ -71,67 +65,21 @@ extern LIST_ENTRY mGcdMemorySpaceMap; STATIC LIST_ENTRY mProtectedImageRecordList; -/** - Get the image type. - - @param[in] File This is a pointer to the device path of the file that is - being dispatched. - - @return UINT32 Image Type -**/ -UINT32 -GetImageType ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *File - ) -{ - EFI_STATUS Status; - EFI_HANDLE DeviceHandle; - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - - if (File == NULL) { - return IMAGE_UNKNOWN; - } - - // - // First check to see if File is from a Firmware Volume - // - DeviceHandle = NULL; - TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File; - Status = gBS->LocateDevicePath ( - &gEfiFirmwareVolume2ProtocolGuid, - &TempDevicePath, - &DeviceHandle - ); - if (!EFI_ERROR (Status)) { - Status = gBS->OpenProtocol ( - DeviceHandle, - &gEfiFirmwareVolume2ProtocolGuid, - NULL, - NULL, - NULL, - EFI_OPEN_PROTOCOL_TEST_PROTOCOL - ); - if (!EFI_ERROR (Status)) { - return IMAGE_FROM_FV; - } - } - - return IMAGE_UNKNOWN; -} - /** Get UEFI image protection policy based upon image type. - @param[in] ImageType The UEFI image type + @param[in] ImageIsFromFv Whether File comes from FV. Must be FALSE or TRUE. @return UEFI image protection policy **/ UINT32 GetProtectionPolicyFromImageType ( - IN UINT32 ImageType + IN BOOLEAN ImageIsFromFv ) { - if ((ImageType & mImageProtectionPolicy) == 0) { + ASSERT (ImageIsFromFv == FALSE || ImageIsFromFv == TRUE); + + if (((ImageIsFromFv + 1) & mImageProtectionPolicy) == 0) { return DO_NOT_PROTECT; } else { return PROTECT_IF_ALIGNED_ELSE_ALLOW; @@ -141,19 +89,16 @@ GetProtectionPolicyFromImageType ( /** Get UEFI image protection policy based upon loaded image device path. - @param[in] LoadedImage The loaded image protocol - @param[in] LoadedImageDevicePath The loaded image device path protocol + @param[in] ImageIsFromFv Whether File comes from FV. Must be FALSE or TRUE. @return UEFI image protection policy **/ UINT32 GetUefiImageProtectionPolicy ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath + IN BOOLEAN ImageIsFromFv ) { BOOLEAN InSmm; - UINT32 ImageType; UINT32 ProtectionPolicy; // @@ -168,16 +113,7 @@ GetUefiImageProtectionPolicy ( return FALSE; } - // - // Check DevicePath - // - if (LoadedImage == gDxeCoreLoadedImage) { - ImageType = IMAGE_FROM_FV; - } else { - ImageType = GetImageType (LoadedImageDevicePath); - } - - ProtectionPolicy = GetProtectionPolicyFromImageType (ImageType); + ProtectionPolicy = GetProtectionPolicyFromImageType (ImageIsFromFv); return ProtectionPolicy; } @@ -288,17 +224,18 @@ IsMemoryProtectionSectionAligned ( Protect UEFI PE/COFF image. @param[in] LoadedImage The loaded image protocol + @param[in] ImageIsFromFv Whether File comes from FV. Must be FALSE + or TRUE. @param[in] LoadedImageDevicePath The loaded image device path protocol **/ VOID ProtectUefiImage ( - IN LOADED_IMAGE_PRIVATE_DATA *Image, + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN BOOLEAN ImageIsFromFv, UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { RETURN_STATUS PdbStatus; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; UINT32 SectionAlignment; UEFI_IMAGE_RECORD *ImageRecord; CONST CHAR8 *PdbPointer; @@ -306,13 +243,10 @@ ProtectUefiImage ( BOOLEAN IsAligned; UINT32 ProtectionPolicy; - LoadedImage = &Image->Info; - LoadedImageDevicePath = Image->LoadedImageDevicePath; - DEBUG ((DEBUG_INFO, "ProtectUefiImageCommon - 0x%x\n", LoadedImage)); DEBUG ((DEBUG_INFO, " - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase, LoadedImage->ImageSize)); - ProtectionPolicy = GetUefiImageProtectionPolicy (LoadedImage, LoadedImageDevicePath); + ProtectionPolicy = GetUefiImageProtectionPolicy (ImageIsFromFv); switch (ProtectionPolicy) { case DO_NOT_PROTECT: return; From e46d356fc96b56410267f4b49aee9ee7f0560245 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 18 Dec 2023 11:01:58 +0300 Subject: [PATCH 078/341] MdePkg/UefiImageLib: Support multi-format and multi-source architecture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marvin Häuser --- ArmPkg/ArmPkg.dsc | 1 - .../ArmStandaloneMmCoreEntryPoint.c | 7 +- .../DebugAgentSymbolsBaseLib.c | 7 +- ArmPlatformPkg/ArmPlatformPkg.dsc | 1 - ArmVirtPkg/ArmVirt.dsc.inc | 1 - .../PrePi/ArmVirtPrePiUniCoreRelocatable.inf | 2 +- ArmVirtPkg/PrePi/PrePi.c | 7 +- BaseTools/ImageTool/GNUmakefile | 4 +- BaseTools/ImageTool/Makefile | 4 +- BaseTools/ImageTool/UefiImageScan.c | 22 +- BaseTools/Source/C/Common/GNUmakefile | 4 +- BaseTools/Source/C/Common/Makefile | 4 +- BaseTools/Source/C/EfiRom/EfiRom.c | 7 +- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 13 +- BaseTools/Source/C/Include/Common/AutoGen.h | 14 + BaseTools/Source/C/Makefiles/header.makefile | 2 + BaseTools/Source/C/Makefiles/ms.rule | 2 +- EmbeddedPkg/EmbeddedPkg.dsc | 1 - EmbeddedPkg/Library/PrePiLib/PrePiLib.c | 7 +- EmulatorPkg/EmulatorPkg.dsc | 1 - EmulatorPkg/Unix/Host/Host.c | 7 +- EmulatorPkg/Unix/Host/Host.inf | 2 +- EmulatorPkg/Win/Host/WinHost.c | 7 +- EmulatorPkg/Win/Host/WinHost.inf | 2 +- IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc | 1 - .../FspWrapperNotifyDxe.inf | 2 +- .../FspWrapperNotifyDxe/LoadBelow4G.c | 7 +- IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc | 1 - MdeModulePkg/Core/Dxe/DxeMain.inf | 2 +- MdeModulePkg/Core/Dxe/Image/Image.c | 20 +- MdeModulePkg/Core/Pei/Image/Image.c | 16 +- MdeModulePkg/Core/Pei/PeiMain.inf | 2 +- MdeModulePkg/Core/Pei/Ppi/Ppi.c | 7 +- MdeModulePkg/Core/PiSmmCore/Dispatcher.c | 7 +- MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf | 2 +- MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c | 7 +- MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf | 2 +- MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf | 2 +- MdeModulePkg/MdeModulePkg.dsc | 1 - .../BootScriptExecutorDxe.inf | 2 +- .../BootScriptExecutorDxe/ScriptExecute.c | 7 +- MdePkg/Include/Library/PeCoffLib2.h | 13 - MdePkg/Include/Library/UefiImageLib.h | 44 +- MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c | 10 - .../BaseUefiImageLib/BaseUefiImageAllLib.inf | 48 ++ ...bPeCoff.inf => BaseUefiImageOnlyFvLib.inf} | 20 +- .../BaseUefiImageOnlyNonFvLib.inf | 48 ++ .../Library/BaseUefiImageLib/CommonSupport.c | 18 +- .../BaseUefiImageLib/ExecutionSupport.c | 2 +- .../Library/BaseUefiImageLib/PeCoffSupport.h | 37 -- .../{PeCoffSupport.c => PeSupport.c} | 317 ++++++++- MdePkg/Library/BaseUefiImageLib/PeSupport.h | 16 + .../BaseUefiImageLib/UefiImageFormat.h | 235 +++++++ .../Library/BaseUefiImageLib/UefiImageLib.c | 629 ++++++++++++++++++ .../BaseUefiImageLib/UefiImageLibPeCoff.c | 299 --------- MdePkg/MdeLibs.dsc.inc | 33 + MdePkg/MdePkg.dec | 10 + MdePkg/MdePkg.dsc | 4 +- NetworkPkg/NetworkPkg.dsc | 1 - OvmfPkg/AmdSev/AmdSevX64.dsc | 3 - OvmfPkg/Bhyve/BhyveX64.dsc | 3 - OvmfPkg/OvmfPkgIa32.dsc | 3 - OvmfPkg/OvmfPkgIa32X64.dsc | 3 - OvmfPkg/OvmfPkgX64.dsc | 3 - OvmfPkg/OvmfXen.dsc | 3 - OvmfPkg/Sec/SecMain.c | 14 +- OvmfPkg/Sec/SecMain.inf | 2 +- SecurityPkg/SecurityPkg.dsc | 1 - .../Tcg/Tcg2Dxe/MeasureBootUefiImage.c | 3 +- SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf | 2 +- .../SecureBootConfigDxe.inf | 2 +- .../SecureBootConfigImpl.c | 10 +- SignedCapsulePkg/SignedCapsulePkg.dsc | 1 - StandaloneMmPkg/Core/Dispatcher.c | 7 +- StandaloneMmPkg/Core/StandaloneMmCore.inf | 2 +- StandaloneMmPkg/StandaloneMmPkg.dsc | 1 - UefiCpuPkg/SecCore/FindPeiCore.c | 6 +- UefiCpuPkg/SecCore/SecCoreNative.inf | 2 +- UefiCpuPkg/UefiCpuPkg.dsc | 1 - UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c | 7 +- .../UefiPayloadEntry/UefiPayloadEntry.inf | 2 +- .../UniversalPayloadEntry.inf | 2 +- UefiPayloadPkg/UefiPayloadPkg.dsc | 1 - 83 files changed, 1561 insertions(+), 524 deletions(-) create mode 100644 MdePkg/Library/BaseUefiImageLib/BaseUefiImageAllLib.inf rename MdePkg/Library/BaseUefiImageLib/{BaseUefiImageLibPeCoff.inf => BaseUefiImageOnlyFvLib.inf} (53%) create mode 100644 MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf delete mode 100644 MdePkg/Library/BaseUefiImageLib/PeCoffSupport.h rename MdePkg/Library/BaseUefiImageLib/{PeCoffSupport.c => PeSupport.c} (66%) create mode 100644 MdePkg/Library/BaseUefiImageLib/PeSupport.h create mode 100644 MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h create mode 100644 MdePkg/Library/BaseUefiImageLib/UefiImageLib.c delete mode 100644 MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.c diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 87653c4427..cfa9f6d12a 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -55,7 +55,6 @@ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf CpuArchLib|ArmPkg/Library/CpuArchLib/CpuArchLib.inf diff --git a/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.c b/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.c index 5fd320c3ad..05052f2ba5 100644 --- a/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.c +++ b/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.c @@ -1064,7 +1064,12 @@ CEntryPoint ( DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", TeData)); // Obtain the PE/COFF Section information for the Standalone MM core module - Status = UefiImageInitializeContext (&ImageContext, TeData, TeDataSize); + Status = UefiImageInitializeContext ( + &ImageContext, + TeData, + TeDataSize, + UEFI_IMAGE_SOURCE_FV + ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Section information - %r\n", Status)); goto finish; diff --git a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c index dad2dd9d29..525483a440 100644 --- a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c +++ b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c @@ -214,7 +214,12 @@ GetImageContext ( // Initialize the Image Context // FIXME: Common FFS API with size checks - Status = UefiImageInitializeContext (ImageContext, EfiImage, SectionLength - sizeof (*Section)); + Status = UefiImageInitializeContext ( + ImageContext, + EfiImage, + SectionLength - sizeof (*Section), + UEFI_IMAGE_SOURCE_FV + ); if (!EFI_ERROR(Status)) { Status = UefiImageLoadImageInplace( ImageContext); } diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index f6655a4911..5941e75533 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -54,7 +54,6 @@ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 2d23a9ec78..865bb20895 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -59,7 +59,6 @@ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf diff --git a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf index 9db6dd4dbe..0830def199 100755 --- a/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf +++ b/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf @@ -46,7 +46,7 @@ TimerLib SerialPortLib ExtractGuidedSectionLib - UefiImageLib + UefiImageOnlyFvLib PrePiLib MemoryAllocationLib HobLib diff --git a/ArmVirtPkg/PrePi/PrePi.c b/ArmVirtPkg/PrePi/PrePi.c index 4dabd6e467..ef5214f39c 100644 --- a/ArmVirtPkg/PrePi/PrePi.c +++ b/ArmVirtPkg/PrePi/PrePi.c @@ -150,7 +150,12 @@ RelocateUefiImage ( Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SectionData, &SectionSize); ASSERT_EFI_ERROR (Status); - Status = UefiImageInitializeContext (&ImageContext, SectionData, SectionSize); + Status = UefiImageInitializeContext ( + &ImageContext, + SectionData, + SectionSize, + UEFI_IMAGE_SOURCE_FV + ); ASSERT_RETURN_ERROR (Status); Status = UefiImageRelocateImageInplaceForExecution (&ImageContext); diff --git a/BaseTools/ImageTool/GNUmakefile b/BaseTools/ImageTool/GNUmakefile index f4e13585ef..3765720da8 100644 --- a/BaseTools/ImageTool/GNUmakefile +++ b/BaseTools/ImageTool/GNUmakefile @@ -10,7 +10,7 @@ OBJS = $(PROJECT).o OBJS += Image.o UefiImageScan.o PeEmit32.o PeEmit64.o PeEmitCommon.o PeScan.o ElfScan32.o ElfScan64.o ElfScanCommon.o BinEmit.o ImageToolEmit.o OBJS += UefiImageExtraActionLib.o OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o PeCoffHash.o -OBJS += UefiImageLibPeCoff.o PeCoffSupport.o CommonSupport.o +OBJS += PeSupport.o UefiImageLib.o CommonSupport.o WERROR = 1 DEBUG = 1 @@ -23,3 +23,5 @@ VPATH += ../../MdePkg/Library/BasePeCoffLib2:$\ ../../MdePkg/Library/BaseUefiImageLib include $(OC_USER)/User/Makefile + +CFLAGS += -DUEFI_IMAGE_FORMAT_SUPPORT_SOURCES=0x02 diff --git a/BaseTools/ImageTool/Makefile b/BaseTools/ImageTool/Makefile index fe1e197b5a..a6a0b6a48c 100644 --- a/BaseTools/ImageTool/Makefile +++ b/BaseTools/ImageTool/Makefile @@ -33,7 +33,7 @@ CMEM = $(UDK_PATH)\MdeModulePkg\Library\CommonMemoryAllocationLib USER = $(OC_USER)\User\Library OBJECTS = $(OBJECTS) {$(BASE)}SafeString.obj String.obj SwapBytes16.obj SwapBytes32.obj CpuDeadLoop.obj CheckSum.obj QuickSort.obj LinkedList.obj OBJECTS = $(OBJECTS) {$(OUT)}DebugLib.obj {$(PRIN)}PrintLib.obj PrintLibInternal.obj {$(ERRO)}BaseDebugPrintErrorLevelLib.obj -OBJECTS = $(OBJECTS) {$(UIMG)}UefiImageLibPeCoff.obj PeCoffSupport.obj CommonSupport.obj +OBJECTS = $(OBJECTS) {$(UIMG)}UefiImageLib.obj PeSupport.obj CommonSupport.obj OBJECTS = $(OBJECTS) {$(USER)}UserFile.obj UserBaseMemoryLib.obj UserMath.obj UserPcd.obj UserMisc.obj UserGlobalVar.obj UserBootServices.obj OBJECTS = $(OBJECTS) {$(BMPN)}BaseMemoryProfileLibNull.obj {$(CMEM)}CommonMemoryAllocationLib.obj {$(CMEM)}CommonMemoryAllocationLibEx.obj @@ -102,7 +102,7 @@ cleanall: @move $@ $(OUT_DIR)\ {$(UIMG)}.c.obj : - $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + $(CC) -c $(CFLAGS) -DUEFI_IMAGE_FORMAT_SUPPORT_SOURCES=0x02 $(INC) $< -Fo$@ @move $@ $(OUT_DIR)\ {$(USER)}.c.obj : diff --git a/BaseTools/ImageTool/UefiImageScan.c b/BaseTools/ImageTool/UefiImageScan.c index c02a62b7e9..5180be4407 100644 --- a/BaseTools/ImageTool/UefiImageScan.c +++ b/BaseTools/ImageTool/UefiImageScan.c @@ -21,10 +21,7 @@ ScanUefiImageGetHeaderInfo ( RETURN_STATUS Status; UINT64 Address; - assert (HeaderInfo != NULL); - assert (Context != NULL); - - HeaderInfo->BaseAddress = UefiImageGetPreferredAddress (Context); + HeaderInfo->BaseAddress = UefiImageGetBaseAddress (Context); HeaderInfo->EntryPointAddress = UefiImageGetEntryPointAddress (Context); HeaderInfo->Machine = UefiImageGetMachine (Context); HeaderInfo->Subsystem = UefiImageGetSubsystem (Context); @@ -66,10 +63,7 @@ ScanUefiImageGetRelocInfo ( RelocInfo->RelocsStripped = UefiImageGetRelocsStripped (Context); if (FormatIndex == UefiImageFormatPe) { - return ScanPeGetRelocInfo ( - RelocInfo, - (PE_COFF_LOADER_IMAGE_CONTEXT *)Context - ); + return ScanPeGetRelocInfo (RelocInfo, &Context->Ctx.Pe); } fprintf ( @@ -97,10 +91,7 @@ ScanUefiImageGetSegmentInfo ( SegmentInfo->SegmentAlignment = UefiImageGetSegmentAlignment (Context); if (FormatIndex == UefiImageFormatPe) { - return ScanPeGetSegmentInfo ( - SegmentInfo, - (PE_COFF_LOADER_IMAGE_CONTEXT *)Context - ); + return ScanPeGetSegmentInfo (SegmentInfo, &Context->Ctx.Pe); } fprintf ( @@ -211,7 +202,12 @@ ToolContextConstructUefiImage ( return RETURN_UNSUPPORTED; } - Status = UefiImageInitializeContext (&Context, File, (UINT32)FileSize); + Status = UefiImageInitializeContext ( + &Context, + File, + (UINT32)FileSize, + UEFI_IMAGE_SOURCE_FV + ); if (RETURN_ERROR (Status)) { return Status; } diff --git a/BaseTools/Source/C/Common/GNUmakefile b/BaseTools/Source/C/Common/GNUmakefile index 1396c3f578..1166736e43 100644 --- a/BaseTools/Source/C/Common/GNUmakefile +++ b/BaseTools/Source/C/Common/GNUmakefile @@ -122,8 +122,8 @@ OBJECTS += \ OBJECTS += \ $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/CommonSupport.o \ - $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.o \ - $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.o + $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/PeSupport.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/UefiImageLib.o OBJECTS += \ $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageExtraActionLibNull/UefiImageExtraActionLib.o diff --git a/BaseTools/Source/C/Common/Makefile b/BaseTools/Source/C/Common/Makefile index af704876dd..03a9e73539 100644 --- a/BaseTools/Source/C/Common/Makefile +++ b/BaseTools/Source/C/Common/Makefile @@ -121,8 +121,8 @@ OBJECTS = $(OBJECTS) \ OBJECTS = $(OBJECTS) \ $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\CommonSupport.obj \ - $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\PeCoffSupport.obj \ - $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\UefiImageLibPeCoff.obj + $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\PeSupport.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\UefiImageLib.obj OBJECTS = $(OBJECTS) \ $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull\UefiImageExtraActionLib.obj diff --git a/BaseTools/Source/C/EfiRom/EfiRom.c b/BaseTools/Source/C/EfiRom/EfiRom.c index 9a41a34baf..053849202a 100644 --- a/BaseTools/Source/C/EfiRom/EfiRom.c +++ b/BaseTools/Source/C/EfiRom/EfiRom.c @@ -836,7 +836,12 @@ Routine Description: RETURN_STATUS Status; UEFI_IMAGE_LOADER_IMAGE_CONTEXT Context; - Status = UefiImageInitializeContext (&Context, FileBuffer, FileSize); + Status = UefiImageInitializeContext ( + &Context, + FileBuffer, + FileSize, + UEFI_IMAGE_SOURCE_FV + ); if (RETURN_ERROR (Status)) { Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be an UEFI image - %llu!", Status); return STATUS_ERROR; diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 3584552e99..2f97c26ef7 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -2398,7 +2398,12 @@ Routine Description: return EFI_INVALID_PARAMETER; } - RETURN_STATUS Status = UefiImageInitializeContext (&Context, UefiImage, UefiImageSize); + RETURN_STATUS Status = UefiImageInitializeContext ( + &Context, + UefiImage, + UefiImageSize, + UEFI_IMAGE_SOURCE_FV + ); if (RETURN_ERROR (Status)) { Error (NULL, 0, 3000, "Invalid", "Unrecognized UEFI image file."); return Status; @@ -3578,7 +3583,8 @@ Routine Description: Status = UefiImageInitializeContext ( &ImageContext, (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize), - SectPeSize + SectPeSize, + UEFI_IMAGE_SOURCE_FV ); if (EFI_ERROR (Status)) { Error (NULL, 0, 3000, "Invalid UefiImage", "The input file is %s and the return status is %x", FileName, (int) Status); @@ -3788,7 +3794,8 @@ Routine Description: Status = UefiImageInitializeContext ( &ImageContext, (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize), - RebasedImageSize + RebasedImageSize, + UEFI_IMAGE_SOURCE_FV ); ASSERT_EFI_ERROR (Status); diff --git a/BaseTools/Source/C/Include/Common/AutoGen.h b/BaseTools/Source/C/Include/Common/AutoGen.h index bf5bc9a063..52135a9977 100644 --- a/BaseTools/Source/C/Include/Common/AutoGen.h +++ b/BaseTools/Source/C/Include/Common/AutoGen.h @@ -163,6 +163,20 @@ extern UINT64 _gPcd_SkuId_Array[]; #define _PCD_GET_MODE_8_PcdDebugRaisePropertyMask _PCD_VALUE_PcdDebugRaisePropertyMask //#define _PCD_SET_MODE_8_PcdDebugRaisePropertyMask ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD +#define _PCD_TOKEN_PcdUefiImageFormatSupportNonFv 0U +#define _PCD_VALUE_PcdUefiImageFormatSupportNonFv 0x00 +#define _PCD_SIZE_PcdUefiImageFormatSupportNonFv 1 +#define _PCD_GET_MODE_SIZE_PcdUefiImageFormatSupportNonFv _PCD_SIZE_PcdUefiImageFormatSupportNonFv +#define _PCD_GET_MODE_8_PcdUefiImageFormatSupportNonFv _PCD_VALUE_PcdUefiImageFormatSupportNonFv +//#define _PCD_SET_MODE_8_PcdUefiImageFormatSupportNonFv ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdUefiImageFormatSupportFv 0U +#define _PCD_VALUE_PcdUefiImageFormatSupportFv 0x01 +#define _PCD_SIZE_PcdUefiImageFormatSupportFv 1 +#define _PCD_GET_MODE_SIZE_PcdUefiImageFormatSupportFv _PCD_SIZE_PcdUefiImageFormatSupportFv +#define _PCD_GET_MODE_8_PcdUefiImageFormatSupportFv _PCD_VALUE_PcdUefiImageFormatSupportFv +//#define _PCD_SET_MODE_8_PcdUefiImageFormatSupportFv ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + #ifdef __cplusplus } diff --git a/BaseTools/Source/C/Makefiles/header.makefile b/BaseTools/Source/C/Makefiles/header.makefile index ebf2f573d5..c32243cab4 100644 --- a/BaseTools/Source/C/Makefiles/header.makefile +++ b/BaseTools/Source/C/Makefiles/header.makefile @@ -138,6 +138,8 @@ ifeq ($(DARWIN),Darwin) endif endif +CFLAGS += -DUEFI_IMAGE_FORMAT_SUPPORT_SOURCES=0x02 + # keep BUILD_OPTFLAGS last CFLAGS += $(BUILD_OPTFLAGS) CXXFLAGS += $(BUILD_OPTFLAGS) diff --git a/BaseTools/Source/C/Makefiles/ms.rule b/BaseTools/Source/C/Makefiles/ms.rule index c00df83714..5b9a90785c 100644 --- a/BaseTools/Source/C/Makefiles/ms.rule +++ b/BaseTools/Source/C/Makefiles/ms.rule @@ -41,7 +41,7 @@ {$(EDK2_PATH)\MdePkg\Library\BaseUefiImageLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\}.obj : -@if not exist $(@D)\ mkdir $(@D) - $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + $(CC) -c $(CFLAGS) -DUEFI_IMAGE_FORMAT_SUPPORT_SOURCES=0x02 $(EDK2_INC) $< -Fo$@ {$(EDK2_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull\}.obj : -@if not exist $(@D)\ mkdir $(@D) diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc index 44f220eb7e..e1ac21d511 100644 --- a/EmbeddedPkg/EmbeddedPkg.dsc +++ b/EmbeddedPkg/EmbeddedPkg.dsc @@ -59,7 +59,6 @@ ReportStatusCodeLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf diff --git a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c index 98d5eee1cc..9826e9493e 100644 --- a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c +++ b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c @@ -40,7 +40,12 @@ LoadUefiImage ( UINT32 BufferPages; UINT32 BufferAlignment; - Status = UefiImageInitializeContext (&ImageContext, UefiImage, UefiImageSize); + Status = UefiImageInitializeContext ( + &ImageContext, + UefiImage, + UefiImageSize, + UEFI_IMAGE_SOURCE_FV + ); ASSERT_EFI_ERROR (Status); ImageSize = UefiImageGetImageSize (&ImageContext); diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc index f9c09b1f2c..4a1ef25198 100644 --- a/EmulatorPkg/EmulatorPkg.dsc +++ b/EmulatorPkg/EmulatorPkg.dsc @@ -63,7 +63,6 @@ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf diff --git a/EmulatorPkg/Unix/Host/Host.c b/EmulatorPkg/Unix/Host/Host.c index b8faa54fdf..5400f8b5ce 100644 --- a/EmulatorPkg/Unix/Host/Host.c +++ b/EmulatorPkg/Unix/Host/Host.c @@ -746,7 +746,12 @@ SecUefiImageGetEntryPoint ( EFI_STATUS Status; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; - Status = UefiImageInitializeContext (&ImageContext, Pe32Data, Pe32Size); + Status = UefiImageInitializeContext ( + &ImageContext, + Pe32Data, + Pe32Size, + UEFI_IMAGE_SOURCE_FV + ); if (EFI_ERROR (Status)) { return Status; } diff --git a/EmulatorPkg/Unix/Host/Host.inf b/EmulatorPkg/Unix/Host/Host.inf index d2c4a69d48..6f5ed96242 100644 --- a/EmulatorPkg/Unix/Host/Host.inf +++ b/EmulatorPkg/Unix/Host/Host.inf @@ -55,7 +55,7 @@ PrintLib BaseMemoryLib BaseLib - UefiImageLib + UefiImageOnlyFvLib ThunkPpiList ThunkProtocolList PpiListLib diff --git a/EmulatorPkg/Win/Host/WinHost.c b/EmulatorPkg/Win/Host/WinHost.c index e7fa542a33..40d6901ec7 100644 --- a/EmulatorPkg/Win/Host/WinHost.c +++ b/EmulatorPkg/Win/Host/WinHost.c @@ -804,7 +804,12 @@ SecUefiImageGetEntryPoint ( EFI_STATUS Status; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; - Status = UefiImageInitializeContext (&ImageContext, Pe32Data, Pe32Size); + Status = UefiImageInitializeContext ( + &ImageContext, + Pe32Data, + Pe32Size, + UEFI_IMAGE_SOURCE_FV + ); if (EFI_ERROR (Status)) { return Status; } diff --git a/EmulatorPkg/Win/Host/WinHost.inf b/EmulatorPkg/Win/Host/WinHost.inf index fd7a33ce71..3dfd56cbfc 100644 --- a/EmulatorPkg/Win/Host/WinHost.inf +++ b/EmulatorPkg/Win/Host/WinHost.inf @@ -49,7 +49,7 @@ PrintLib BaseMemoryLib BaseLib - UefiImageLib + UefiImageOnlyFvLib ThunkPpiList ThunkProtocolList PpiListLib diff --git a/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc b/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc index fa35cf86ab..6d1a84ca26 100644 --- a/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc +++ b/IntelFsp2Pkg/Tools/Tests/QemuFspPkg.dsc @@ -93,7 +93,6 @@ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf index 37db0a5a21..c23aff4368 100644 --- a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf +++ b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf @@ -39,7 +39,7 @@ BaseMemoryLib UefiLib FspWrapperApiLib - UefiImageLib + UefiImageOnlyFvLib CacheMaintenanceLib DxeServicesLib PerformanceLib diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c index 1a1d052b4d..17d9ced288 100644 --- a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c +++ b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c @@ -90,7 +90,12 @@ RelocateImageUnder4GIfNeeded ( // // Get information about the image being loaded // - Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize); + Status = UefiImageInitializeContext ( + &ImageContext, + Buffer, + (UINT32) BufferSize, + UEFI_IMAGE_SOURCE_FV + ); ASSERT_EFI_ERROR (Status); ImageSize = UefiImageGetImageSize (&ImageContext); ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext); diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc index 4276859e72..84c8acde86 100644 --- a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc +++ b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc @@ -29,7 +29,6 @@ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index bb64caad50..0c3578ba2c 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -83,7 +83,7 @@ UefiLib DebugLib DxeCoreEntryPoint - UefiImageLib + UefiImageAllLib UefiImageExtraActionLib ExtractGuidedSectionLib MemoryAllocationLib diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 7e7cdc3103..34db9746ea 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -239,12 +239,17 @@ CoreInitializeImageServices ( Status = UefiImageInitializeContext ( ImageContext, (VOID *) (UINTN) DxeCoreImageBaseAddress, - (UINT32) DxeCoreImageLength + (UINT32) DxeCoreImageLength, + UEFI_IMAGE_SOURCE_FV ); ASSERT_EFI_ERROR (Status); // FIXME: DxeCore is dynamically loaded by DxeIpl, can't it pass the context? - ImageContext->ImageBuffer = (VOID *) ImageContext->FileBuffer; + if (ImageContext->FormatIndex == UefiImageFormatPe) { + ImageContext->Ctx.Pe.ImageBuffer = (VOID *) ImageContext->Ctx.Pe.FileBuffer; + } else { + ASSERT (FALSE); + } ASSERT ((UINTN) DxeCoreEntryPoint == UefiImageLoaderGetImageEntryPoint (ImageContext)); @@ -590,7 +595,7 @@ CoreLoadPeImage ( Status = GetUefiImageFixLoadingAssignedAddress (&BufferAddress, ValueInSectionHeader, DstBufSize); if (!EFI_ERROR (Status)) { - if (BufferAddress != UefiImageGetPreferredAddress (ImageContext) && UefiImageGetRelocsStripped (ImageContext)) { + if (BufferAddress != UefiImageGetBaseAddress (ImageContext) && UefiImageGetRelocsStripped (ImageContext)) { Status = EFI_UNSUPPORTED; DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since relocs have been stripped.\n")); } @@ -602,7 +607,7 @@ CoreLoadPeImage ( } } if (EFI_ERROR (Status)) { - BufferAddress = UefiImageGetPreferredAddress (ImageContext); + BufferAddress = UefiImageGetBaseAddress (ImageContext); if ((BufferAddress >= 0x100000) || UefiImageGetRelocsStripped (ImageContext)) { Status = AllocatePagesEx ( AllocateAddress, @@ -1191,7 +1196,12 @@ CoreLoadImageCommon ( // // Get information about the image being loaded // - Status = UefiImageInitializeContextPreHash (&ImageContext, FHand.Source, (UINT32) FHand.SourceSize); + Status = UefiImageInitializeContextPreHash ( + &ImageContext, + FHand.Source, + (UINT32) FHand.SourceSize, + ImageIsFromFv + ); if (EFI_ERROR (Status)) { ASSERT (FALSE); return Status; diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c index 094fc80fe6..506e3488a0 100644 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ b/MdeModulePkg/Core/Pei/Image/Image.c @@ -183,7 +183,12 @@ LoadAndRelocateUefiImage ( ReturnStatus = EFI_SUCCESS; - Status = UefiImageInitializeContext (ImageContext, Pe32Data, Pe32DataSize); + Status = UefiImageInitializeContext ( + ImageContext, + Pe32Data, + Pe32DataSize, + UEFI_IMAGE_SOURCE_FV + ); if (EFI_ERROR (Status)) { return Status; } @@ -270,7 +275,7 @@ LoadAndRelocateUefiImage ( } if (!EFI_ERROR (Status)){ - Success = Destination == UefiImageGetPreferredAddress (ImageContext); + Success = Destination == UefiImageGetBaseAddress (ImageContext); if (!Success) { DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since relocs have been stripped.\n")); @@ -362,7 +367,12 @@ LoadAndRelocateUefiImageInPlace ( CopyMem (ImageAddress, Pe32Data, ImageSize); - Status = UefiImageInitializeContext (&ImageContext, ImageAddress, ImageSize); + Status = UefiImageInitializeContext ( + &ImageContext, + ImageAddress, + ImageSize, + UEFI_IMAGE_SOURCE_FV + ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf index e3e7f51d76..dd2f381c3c 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.inf +++ b/MdeModulePkg/Core/Pei/PeiMain.inf @@ -62,7 +62,7 @@ DebugLib MemoryAllocationLib CacheMaintenanceLib - UefiImageLib + UefiImageOnlyFvLib PeiServicesTablePointerLib PcdLib TimerLib diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c b/MdeModulePkg/Core/Pei/Ppi/Ppi.c index 0184f206b9..0ea343c252 100644 --- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c +++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c @@ -1117,7 +1117,12 @@ ConvertPeiCorePpiPointers ( // Find PEI Core EntryPoint in the BFV in temporary memory. // // FIXME: "Assume" sanity and skip full initialisation? - Status = UefiImageInitializeContext (&ImageContext, (VOID *) (UINTN) PeiCoreImageBase, PeiCoreImageSize); + Status = UefiImageInitializeContext ( + &ImageContext, + (VOID *) (UINTN) PeiCoreImageBase, + PeiCoreImageSize, + UEFI_IMAGE_SOURCE_FV + ); ASSERT_EFI_ERROR (Status); OrgImageBase = (UINTN)PeiCoreImageBase; diff --git a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c index 324140a0b0..068fcee891 100644 --- a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c +++ b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c @@ -339,7 +339,12 @@ SmmLoadImage ( // // Get information about the image being loaded // - Status = UefiImageInitializeContextPreHash (ImageContext, Buffer, (UINT32) Size); + Status = UefiImageInitializeContextPreHash ( + ImageContext, + Buffer, + (UINT32) Size, + UEFI_IMAGE_SOURCE_FV + ); if (EFI_ERROR (Status)) { if (Buffer != NULL) { gBS->FreePool (Buffer); diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf index d14f76b65f..d0cbf48f8d 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf @@ -48,7 +48,7 @@ UefiDriverEntryPoint BaseLib BaseMemoryLib - UefiImageLib + UefiImageOnlyFvLib CacheMaintenanceLib DebugLib ReportStatusCodeLib diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c index 524a74bdc4..8b78d965af 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c @@ -1003,7 +1003,12 @@ ExecuteSmmCoreFromSmram ( // // Get information about the image being loaded // - Status = UefiImageInitializeContext (&gSmmCorePrivate->PiSmmCoreImageContext, SourceBuffer, (UINT32) SourceSize); + Status = UefiImageInitializeContext ( + &gSmmCorePrivate->PiSmmCoreImageContext, + SourceBuffer, + (UINT32) SourceSize, + UEFI_IMAGE_SOURCE_FV + ); if (EFI_ERROR (Status)) { return Status; } diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf index 60d14cd59c..a8d0858b51 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf @@ -35,7 +35,7 @@ UefiDriverEntryPoint BaseLib BaseMemoryLib - UefiImageLib + UefiImageOnlyFvLib CacheMaintenanceLib MemoryAllocationLib DebugLib diff --git a/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf b/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf index 36d282d69a..1162d54983 100644 --- a/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf +++ b/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf @@ -39,7 +39,7 @@ MdePkg/MdePkg.dec [LibraryClasses] - UefiImageLib + UefiImageAllLib CacheMaintenanceLib UefiBootServicesTableLib UefiLib diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 8b2caee209..55f83dde5a 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -44,7 +44,6 @@ PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf # # UEFI & PI diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf index 22a28df8e6..3d25b12748 100644 --- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf +++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf @@ -49,7 +49,7 @@ UefiDriverEntryPoint BaseLib S3BootScriptLib - UefiImageLib + UefiImageOnlyFvLib DxeServicesLib UefiBootServicesTableLib CacheMaintenanceLib diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c index 4599425859..04dd595f79 100644 --- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c +++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c @@ -310,7 +310,12 @@ ReadyToLockEventNotify ( // // Get information about the image being loaded // - Status = UefiImageInitializeContext (&ImageContext, Buffer, (UINT32) BufferSize); + Status = UefiImageInitializeContext ( + &ImageContext, + Buffer, + (UINT32) BufferSize, + UEFI_IMAGE_SOURCE_FV + ); ASSERT_EFI_ERROR (Status); ImageSize = UefiImageGetImageSize (&ImageContext); ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext); diff --git a/MdePkg/Include/Library/PeCoffLib2.h b/MdePkg/Include/Library/PeCoffLib2.h index 95222dfdef..d1438b8a6a 100644 --- a/MdePkg/Include/Library/PeCoffLib2.h +++ b/MdePkg/Include/Library/PeCoffLib2.h @@ -497,19 +497,6 @@ PeCoffGetSizeOfImage ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context ); -/** - Retrieves the size, in Bytes, of the Image memory space for in-place loading. - - @param[in,out] Context The context describing the Image. Must have been - initialised by PeCoffInitializeContext(). - - @returns The size of the Image memory space for in-place loading. -**/ -UINT32 -PeCoffGetSizeOfImageInplace ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context - ); - /** Retrieves the Image preferred load address. diff --git a/MdePkg/Include/Library/UefiImageLib.h b/MdePkg/Include/Library/UefiImageLib.h index ecdb706fd9..1bd574e775 100644 --- a/MdePkg/Include/Library/UefiImageLib.h +++ b/MdePkg/Include/Library/UefiImageLib.h @@ -2,18 +2,28 @@ #ifndef UEFI_IMAGE_LIB_H_ #define UEFI_IMAGE_LIB_H_ +#include + typedef enum { UefiImageFormatPe = 0, UefiImageFormatMax } UEFI_IMAGE_FORMAT; -// FIXME: Work on reasonable abstraction -#ifndef UEFI_IMAGE_LOADER_IMAGE_CONTEXT - #include +#define UEFI_IMAGE_SOURCE_NON_FV 0U +#define UEFI_IMAGE_SOURCE_FV 1U +#define UEFI_IMAGE_SOURCE_ALL 2U +#define UEFI_IMAGE_SOURCE_MAX 3U + +typedef UINT8 UEFI_IMAGE_SOURCE; - #define UEFI_IMAGE_LOADER_IMAGE_CONTEXT PE_COFF_LOADER_IMAGE_CONTEXT - #define UEFI_IMAGE_LOADER_RUNTIME_CONTEXT PE_COFF_LOADER_RUNTIME_CONTEXT -#endif +typedef struct { + UINT8 FormatIndex; + union { + PE_COFF_LOADER_IMAGE_CONTEXT Pe; + } Ctx; +} UEFI_IMAGE_LOADER_IMAGE_CONTEXT; + +typedef struct UEFI_IMAGE_LOADER_RUNTIME_CONTEXT_ UEFI_IMAGE_LOADER_RUNTIME_CONTEXT; /// /// Image record segment that desribes the UEFI memory permission configuration @@ -95,7 +105,8 @@ RETURN_STATUS UefiImageInitializeContextPreHash ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UEFI_IMAGE_SOURCE Source ); RETURN_STATUS @@ -122,7 +133,8 @@ RETURN_STATUS UefiImageInitializeContext ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UEFI_IMAGE_SOURCE Source ); /** @@ -235,7 +247,7 @@ UefiImageLoaderGetRuntimeContextSize ( Relocate the Image for boot-time usage. May only be called when UefiImageGetRelocsStripped() returns FALSE, or with - BaseAddress == UefiImageGetPreferredAddress(). + BaseAddress == UefiImageGetBaseAddress(). @param[in,out] Context The context describing the Image. Must have been loaded by UefiImageLoadImage(). @@ -263,7 +275,7 @@ UefiImageRelocateImage ( the Image. May only be called when UefiImageGetRelocsStripped() returns FALSE, or with - BaseAddress == UefiImageGetPreferredAddress(). + BaseAddress == UefiImageGetBaseAddress(). @param[in,out] Context The context describing the Image. Must have been initialised by @@ -296,7 +308,7 @@ UefiImageLoadImageForExecution ( Relocate Image for Runtime usage. May only be called when UefiImageGetRelocsStripped() returns FALSE, or with - BaseAddress == UefiImageGetPreferredAddress(). + BaseAddress == UefiImageGetBaseAddress(). @param[in,out] Image The Image destination memory. Must have been relocated by UefiImageRelocateImage(). @@ -321,7 +333,7 @@ UefiImageRuntimeRelocateImage ( required to execute code from the Image. May only be called when UefiImageGetRelocsStripped() returns FALSE, or with - BaseAddress == UefiImageGetPreferredAddress(). + BaseAddress == UefiImageGetBaseAddress(). @param[in,out] Image The Image destination memory. Must have been relocated by UefiImageRelocateImage(). @@ -521,12 +533,6 @@ UefiImageGetImageSize ( IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context ); -// FIXME: Docs -UINT32 -UefiImageGetImageSizeInplace ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ); - /** Retrieves the Image preferred load address. @@ -536,7 +542,7 @@ UefiImageGetImageSizeInplace ( @returns The Image preferred load address. **/ UINT64 -UefiImageGetPreferredAddress ( +UefiImageGetBaseAddress ( IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context ); diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c b/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c index 5b36cf2794..b6e76b923b 100644 --- a/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.c @@ -70,16 +70,6 @@ PeCoffGetSizeOfImage ( return Context->SizeOfImage; } -UINT32 -PeCoffGetSizeOfImageInplace ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context - ) -{ - ASSERT (Context != NULL); - - return Context->SizeOfImage; -} - UINT64 PeCoffGetImageBase ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context diff --git a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageAllLib.inf b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageAllLib.inf new file mode 100644 index 0000000000..6ad64cb959 --- /dev/null +++ b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageAllLib.inf @@ -0,0 +1,48 @@ +## @file +# UEFI Image Loader library implementation for UE FV and PE non-FV Images. +# +# Copyright (c) 2023, Marvin Häuser. All rights reserved.
+# +# SPDX-License-Identifier: BSD-3-Clause +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseUefiImageLibAll + FILE_GUID = 499d294d-9f0f-4e8d-82fa-1892e6378996 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiImageLib + LIBRARY_CLASS = UefiImageAllLib + +[Sources] + CommonSupport.c + ExecutionSupport.c + PeSupport.c + UefiImageLib.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + BaseOverflowLib + BaseMemoryLib + CacheMaintenanceLib + DebugLib + MemoryAllocationLib + PeCoffLib2 + UefiImageExtraActionLib + +[FixedPcd] + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAlignmentPolicy + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderLoadHeader + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX + gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask + + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportNonFv + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv + +[BuildOptions] + *_*_*_CC_FLAGS = -DUEFI_IMAGE_FORMAT_SUPPORT_SOURCES=0x03 + MSFT:*_*_*_CC_FLAGS = /wd4204 diff --git a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf similarity index 53% rename from MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf rename to MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf index 4e1cfe6058..cbdcc58644 100644 --- a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf +++ b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf @@ -1,25 +1,25 @@ ## @file -# UEFI Image Loader library implementation for PE/COFF Images. +# UEFI Image Loader library implementation for UE FV Images. # -# Copyright (c) 2021, Marvin Häuser. All rights reserved.
+# Copyright (c) 2023, Marvin Häuser. All rights reserved.
# # SPDX-License-Identifier: BSD-3-Clause ## [Defines] INF_VERSION = 0x00010005 - BASE_NAME = BaseUefiImageLibPeCoff - FILE_GUID = 357AD87E-8D6B-468A-B3FA-0D9CC4C725CD + BASE_NAME = BaseUefiImageLibOnlyFv + FILE_GUID = 11bb7a90-175d-4117-a66f-65b84a9544b7 MODULE_TYPE = BASE VERSION_STRING = 1.0 LIBRARY_CLASS = UefiImageLib + LIBRARY_CLASS = UefiImageOnlyFvLib [Sources] CommonSupport.c ExecutionSupport.c - PeCoffSupport.h - PeCoffSupport.c - UefiImageLibPeCoff.c + PeSupport.c + UefiImageLib.c [Packages] MdePkg/MdePkg.dec @@ -39,3 +39,9 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderLoadHeader gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportNonFv + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv + +[BuildOptions] + *_*_*_CC_FLAGS = -DUEFI_IMAGE_FORMAT_SUPPORT_SOURCES=0x02 + MSFT:*_*_*_CC_FLAGS = /wd4204 diff --git a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf new file mode 100644 index 0000000000..3c8f23e895 --- /dev/null +++ b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf @@ -0,0 +1,48 @@ +## @file +# UEFI Image Loader library implementation for UE non-FV Images. +# +# Copyright (c) 2023, Marvin Häuser. All rights reserved.
+# +# SPDX-License-Identifier: BSD-3-Clause +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseUefiImageLibOnlyNonFv + FILE_GUID = 297b4e3e-2cfa-4350-8fa5-ad11dec48e75 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiImageLib + LIBRARY_CLASS = UefiImageOnlyNonFvLib + +[Sources] + CommonSupport.c + ExecutionSupport.c + PeSupport.c + UefiImageLib.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + BaseOverflowLib + BaseMemoryLib + CacheMaintenanceLib + DebugLib + MemoryAllocationLib + PeCoffLib2 + UefiImageExtraActionLib + +[FixedPcd] + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAlignmentPolicy + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderLoadHeader + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX + gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask + + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportNonFv + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv + +[BuildOptions] + *_*_*_CC_FLAGS = -DUEFI_IMAGE_FORMAT_SUPPORT_SOURCES=0x01 + MSFT:*_*_*_CC_FLAGS = /wd4204 diff --git a/MdePkg/Library/BaseUefiImageLib/CommonSupport.c b/MdePkg/Library/BaseUefiImageLib/CommonSupport.c index 70a191c2af..90124bc7cd 100644 --- a/MdePkg/Library/BaseUefiImageLib/CommonSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/CommonSupport.c @@ -18,12 +18,18 @@ RETURN_STATUS UefiImageInitializeContext ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UEFI_IMAGE_SOURCE Source ) { RETURN_STATUS Status; - Status = UefiImageInitializeContextPreHash (Context, FileBuffer, FileSize); + Status = UefiImageInitializeContextPreHash ( + Context, + FileBuffer, + FileSize, + Source + ); if (RETURN_ERROR (Status)) { return Status; } @@ -31,6 +37,14 @@ UefiImageInitializeContext ( return UefiImageInitializeContextPostHash (Context); } +UINT8 +UefiImageGetFormat ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return Context->FormatIndex; +} + UINTN UefiImageLoaderGetImageEntryPoint ( IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context diff --git a/MdePkg/Library/BaseUefiImageLib/ExecutionSupport.c b/MdePkg/Library/BaseUefiImageLib/ExecutionSupport.c index 63f5b00466..a4a576d3fd 100644 --- a/MdePkg/Library/BaseUefiImageLib/ExecutionSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/ExecutionSupport.c @@ -30,7 +30,7 @@ UefiImageRelocateImageInplaceForExecution ( } ImageAddress = UefiImageLoaderGetImageAddress (Context); - ImageSize = UefiImageGetImageSizeInplace (Context); + ImageSize = UefiImageGetImageSize (Context); // // Flush the instruction cache so the image data is written before // execution. diff --git a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.h b/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.h deleted file mode 100644 index 6c5098362d..0000000000 --- a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.h +++ /dev/null @@ -1,37 +0,0 @@ -/** @file - UEFI Image Loader library implementation for PE/COFF Images. - - Copyright (c) 2021, Marvin Häuser. All rights reserved.
- - SPDX-License-Identifier: BSD-3-Clause -**/ - -#ifndef PE_COFF_SUPPORT_H_ -#define PE_COFF_SUPPORT_H_ - -#include -#include - -UEFI_IMAGE_RECORD * -UefiImageLoaderGetImageRecordPeCoff ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context - ); - -RETURN_STATUS -UefiImageDebugLocateImagePeCoff ( - OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address - ); - -RETURN_STATUS -UefiImageGetFixedAddressPeCoff ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, - OUT UINT64 *Address - ); - -VOID -UefiImageDebugPrintSegmentsPeCoff ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context - ); - -#endif // PE_COFF_SUPPORT_H_ diff --git a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c b/MdePkg/Library/BaseUefiImageLib/PeSupport.c similarity index 66% rename from MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c rename to MdePkg/Library/BaseUefiImageLib/PeSupport.c index 926914e7c9..0698a60461 100644 --- a/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/PeSupport.c @@ -19,6 +19,222 @@ #include #include #include +#include + +#include "PeSupport.h" + +RETURN_STATUS +UefiImageInitializeContextPreHashPe ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN CONST VOID *FileBuffer, + IN UINT32 FileSize + ) +{ + return PeCoffInitializeContext (&Context->Ctx.Pe, FileBuffer, FileSize); +} + +BOOLEAN +UefiImageHashImageDefaultPe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN OUT VOID *HashContext, + IN UEFI_IMAGE_LOADER_HASH_UPDATE HashUpdate + ) +{ + return PeCoffHashImageAuthenticode (&Context->Ctx.Pe, HashContext, HashUpdate); +} + +RETURN_STATUS +UefiImageInitializeContextPostHashPe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return RETURN_SUCCESS; +} + +RETURN_STATUS +UefiImageLoadImagePe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT VOID *Destination, + IN UINT32 DestinationSize + ) +{ + return PeCoffLoadImage (&Context->Ctx.Pe, Destination, DestinationSize); +} + +BOOLEAN +UefiImageImageIsInplacePe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffImageIsInplace (&Context->Ctx.Pe); +} + +RETURN_STATUS +UefiImageLoadImageInplacePe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffLoadImageInplace (&Context->Ctx.Pe); +} + +RETURN_STATUS +UefiImageRelocateImageInplacePe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffRelocateImageInplace (&Context->Ctx.Pe); +} + +RETURN_STATUS +UefiImageLoaderGetRuntimeContextSizePe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *Size + ) +{ + return PeCoffLoaderGetRuntimeContextSize (&Context->Ctx.Pe, Size); +} + +RETURN_STATUS +UefiImageRelocateImagePe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINT64 BaseAddress, + OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize + ) +{ + return PeCoffRelocateImage ( + &Context->Ctx.Pe, + BaseAddress, + (PE_COFF_LOADER_RUNTIME_CONTEXT *)RuntimeContext, + RuntimeContextSize + ); +} + +RETURN_STATUS +UefiImageRuntimeRelocateImagePe ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN UINT64 BaseAddress, + IN CONST VOID *RuntimeContext + ) +{ + return PeCoffRuntimeRelocateImage ( + Image, + ImageSize, + BaseAddress, + (CONST PE_COFF_LOADER_RUNTIME_CONTEXT *)RuntimeContext + ); +} + +VOID +UefiImageDiscardSegmentsPe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + PeCoffDiscardSections (&Context->Ctx.Pe); +} + +RETURN_STATUS +UefiImageGetSymbolsPathPe ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST CHAR8 **SymbolsPath, + OUT UINT32 *SymbolsPathSize + ) +{ + return PeCoffGetPdbPath (&Context->Ctx.Pe, SymbolsPath, SymbolsPathSize); +} + +RETURN_STATUS +UefiImageGetFirstCertificatePe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST WIN_CERTIFICATE **Certificate + ) +{ + return PeCoffGetFirstCertificate (&Context->Ctx.Pe, Certificate); +} + +RETURN_STATUS +UefiImageGetNextCertificatePe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN OUT CONST WIN_CERTIFICATE **Certificate + ) +{ + return PeCoffGetNextCertificate (&Context->Ctx.Pe, Certificate); +} + +RETURN_STATUS +UefiImageGetHiiDataRvaPe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *HiiRva, + OUT UINT32 *HiiSize + ) +{ + return PeCoffGetHiiDataRva (&Context->Ctx.Pe, HiiRva, HiiSize); +} + +UINT32 +UefiImageGetEntryPointAddressPe ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetAddressOfEntryPoint (&Context->Ctx.Pe); +} + +UINT16 +UefiImageGetMachinePe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetMachine (&Context->Ctx.Pe); +} + +UINT16 +UefiImageGetSubsystemPe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetSubsystem (&Context->Ctx.Pe); +} + +UINT32 +UefiImageGetSegmentAlignmentPe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetSectionAlignment (&Context->Ctx.Pe); +} + +UINT32 +UefiImageGetImageSizePe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetSizeOfImage (&Context->Ctx.Pe); +} + +UINT64 +UefiImageGetBaseAddressPe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetImageBase (&Context->Ctx.Pe); +} + +BOOLEAN +UefiImageGetRelocsStrippedPe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffGetRelocsStripped (&Context->Ctx.Pe); +} + +UINTN +UefiImageLoaderGetImageAddressPe ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffLoaderGetImageAddress (&Context->Ctx.Pe); +} /** Retrieves the memory protection attributes corresponding to PE/COFF Image @@ -107,8 +323,8 @@ InternalInsertImageRecordSegmentPadding ( } UEFI_IMAGE_RECORD * -UefiImageLoaderGetImageRecordPeCoff ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context +UefiImageLoaderGetImageRecordPe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context ) { UEFI_IMAGE_RECORD *ImageRecord; @@ -135,7 +351,7 @@ UefiImageLoaderGetImageRecordPeCoff ( // Determine the maximum amount of Image record sections and allocate the // Image record. // - NumberOfSections = PeCoffGetSectionTable (Context, &Sections); + NumberOfSections = PeCoffGetSectionTable (&Context->Ctx.Pe, &Sections); STATIC_ASSERT ( MAX_UINT16 <= MAX_UINT32 / 2 - 1, @@ -162,14 +378,13 @@ UefiImageLoaderGetImageRecordPeCoff ( + MaxNumRecordSegments * sizeof (*ImageRecord->Segments) ); if (ImageRecord == NULL) { - DEBUG_RAISE (); return NULL; } ImageRecord->Signature = UEFI_IMAGE_RECORD_SIGNATURE; InitializeListHead (&ImageRecord->Link); - SectionAlignment = PeCoffGetSectionAlignment (Context); + SectionAlignment = PeCoffGetSectionAlignment (&Context->Ctx.Pe); // // Map the Image Headers as read-only data. If the first Image section is // loaded at the start of the Image memory space, the condition @@ -177,7 +392,7 @@ UefiImageLoaderGetImageRecordPeCoff ( // ignored. // StartAddress = 0; - EndAddress = PeCoffGetSizeOfHeaders (Context); + EndAddress = PeCoffGetSizeOfHeaders (&Context->Ctx.Pe); Characteristics = EFI_IMAGE_SCN_MEM_READ; Attributes = EFI_MEMORY_XP | EFI_MEMORY_RO; ASSERT (Attributes == InternalCharacteristicsToAttributes (Characteristics)); @@ -268,8 +483,8 @@ UefiImageLoaderGetImageRecordPeCoff ( RecordSegment->Attributes = Attributes; ++NumRecordSegments; - ImageAddress = PeCoffLoaderGetImageAddress (Context); - SizeOfImage = PeCoffGetSizeOfImage (Context); + ImageAddress = PeCoffLoaderGetImageAddress (&Context->Ctx.Pe); + SizeOfImage = PeCoffGetSizeOfImage (&Context->Ctx.Pe); // // The Image trailer, if existent, is treated as padding and as such is // reported as read-only data, as intended. Because it is not part of the @@ -318,14 +533,16 @@ InternalDebugLocateImage ( // // Search for the Image Header in 4 Byte steps. All dynamically loaded // Images start at a page boundary to allow for Image section protection, - // but XIP Images may not. + // but XIP Images may not. As all Image Headers are at least 4 Byte aligned + // due to natural alignment, even XIP TE Image Headers should start at a + // 4 Byte boundary. // // Do not attempt to access memory of the first page as it may be protected as // part of NULL dereference detection. // for (; EFI_PAGE_SIZE <= (UINTN) Buffer; Buffer -= 4) { // - // Try to parse the current memory as PE/COFF Image. Pass MAX_UINT32 + // Try to parse the current memory as PE/COFF or TE Image. Pass MAX_UINT32 // as the file size as there isn't any more information available. Only the // Image Header memory will be accessed as part of initialisation. // @@ -362,6 +579,7 @@ InternalDebugLocateImage ( // // We know that (UINTN) Buffer <= Address from the initialisation. // + // FIXME: Set to non-stripped base for XIP TE Images. if (Address < (UINTN) Buffer + PeCoffGetSizeOfImage (Context)) { Context->ImageBuffer = Buffer; // @@ -374,7 +592,7 @@ InternalDebugLocateImage ( return RETURN_SUCCESS; } // - // Continue for the unlikely case that a PE/COFF Image embeds another + // Continue for the unlikely case that a PE/COFF or TE Image embeds another // one within its data, the outer Image may still follow. // } @@ -383,9 +601,9 @@ InternalDebugLocateImage ( } RETURN_STATUS -UefiImageDebugLocateImagePeCoff ( - OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address +UefiImageDebugLocateImagePe ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINTN Address ) { RETURN_STATUS Status; @@ -404,14 +622,15 @@ UefiImageDebugLocateImagePeCoff ( // the Image base to not access too much (potentially protected) memory. // if (!PcdGetBool (PcdImageLoaderLoadHeader)) { - DEBUG_RAISE (); return RETURN_NOT_FOUND; } + + Context->FormatIndex = UefiImageFormatPe; // // Align the search buffer to a 4 Byte boundary. // Status = InternalDebugLocateImage ( - Context, + &Context->Ctx.Pe, (CHAR8 *) (Address & ~(UINTN) 3U), Address, FALSE @@ -423,24 +642,27 @@ UefiImageDebugLocateImagePeCoff ( } RETURN_STATUS -UefiImageGetFixedAddressPeCoff ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, - OUT UINT64 *Address +UefiImageGetFixedAddressPe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT64 *Address ) { + UINT32 SectionAlignment; CONST EFI_IMAGE_SECTION_HEADER *Sections; UINT16 NumberOfSections; UINT16 SectionIndex; UINT64 FixedAddress; ASSERT (Address != NULL); + + SectionAlignment = PeCoffGetSectionAlignment (&Context->Ctx.Pe); // // If this feature is enabled, the build tool will save the address in the // PointerToRelocations and PointerToLineNumbers fields of the first Image // section header that doesn't hold code. The 64-bit value across those fields // will be non-zero if and only if the module has been assigned an address. // - NumberOfSections = PeCoffGetSectionTable (Context, &Sections); + NumberOfSections = PeCoffGetSectionTable (&Context->Ctx.Pe, &Sections); for (SectionIndex = 0; SectionIndex < NumberOfSections; ++SectionIndex) { if ((Sections[SectionIndex].Characteristics & EFI_IMAGE_SCN_CNT_CODE) != 0) { continue; @@ -450,7 +672,7 @@ UefiImageGetFixedAddressPeCoff ( (CONST VOID *) &Sections[SectionIndex].PointerToRelocations ); if (FixedAddress != 0) { - if (!IS_ALIGNED (FixedAddress, Context->SectionAlignment)) { + if (!IS_ALIGNED (FixedAddress, SectionAlignment)) { return RETURN_UNSUPPORTED; } @@ -465,8 +687,8 @@ UefiImageGetFixedAddressPeCoff ( } VOID -UefiImageDebugPrintSegmentsPeCoff ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context +UefiImageDebugPrintSegmentsPe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context ) { CONST EFI_IMAGE_SECTION_HEADER *Sections; @@ -474,30 +696,27 @@ UefiImageDebugPrintSegmentsPeCoff ( UINT16 SectionIndex; CONST UINT8 *Name; - NumberOfSections = PeCoffGetSectionTable (Context, &Sections); + NumberOfSections = PeCoffGetSectionTable (&Context->Ctx.Pe, &Sections); for (SectionIndex = 0; SectionIndex < NumberOfSections; ++SectionIndex) { Name = Sections[SectionIndex].Name; DEBUG (( DEBUG_VERBOSE, - " Section - '%c%c%c%c%c%c%c%c'\n" + " Section - '%c%c%c%c%c%c%c%c'\n", " VirtualSize - 0x%08x\n" " VirtualAddress - 0x%08x\n" " SizeOfRawData - 0x%08x\n" - " PointerToRawData - 0x%08x\n", - Name[0], Name[1], Name[2], Name[3], Name[4], Name[5], Name[6], Name[7], - Sections[SectionIndex].VirtualSize, - Sections[SectionIndex].VirtualAddress, - Sections[SectionIndex].SizeOfRawData, - Sections[SectionIndex].PointerToRawData - )); - DEBUG (( - DEBUG_VERBOSE, + " PointerToRawData - 0x%08x\n" " PointerToRelocations - 0x%08x\n" " PointerToLinenumbers - 0x%08x\n" " NumberOfRelocations - 0x%08x\n" " NumberOfLinenumbers - 0x%08x\n" " Characteristics - 0x%08x\n", + Name[0], Name[1], Name[2], Name[3], Name[4], Name[5], Name[6], Name[7], + Sections[SectionIndex].VirtualSize, + Sections[SectionIndex].VirtualAddress, + Sections[SectionIndex].SizeOfRawData, + Sections[SectionIndex].PointerToRawData, Sections[SectionIndex].PointerToRelocations, Sections[SectionIndex].PointerToLinenumbers, Sections[SectionIndex].NumberOfRelocations, @@ -506,3 +725,33 @@ UefiImageDebugPrintSegmentsPeCoff ( )); } } + +GLOBAL_REMOVE_IF_UNREFERENCED CONST UEFI_IMAGE_FORMAT_SUPPORT mPeSupport = { + UefiImageInitializeContextPreHashPe, + UefiImageHashImageDefaultPe, + UefiImageInitializeContextPostHashPe, + UefiImageLoadImagePe, + UefiImageImageIsInplacePe, + UefiImageLoadImageInplacePe, + UefiImageRelocateImageInplacePe, + UefiImageLoaderGetRuntimeContextSizePe, + UefiImageRelocateImagePe, + UefiImageRuntimeRelocateImagePe, + UefiImageDiscardSegmentsPe, + UefiImageGetSymbolsPathPe, + UefiImageGetFirstCertificatePe, + UefiImageGetNextCertificatePe, + UefiImageGetHiiDataRvaPe, + UefiImageGetEntryPointAddressPe, + UefiImageGetMachinePe, + UefiImageGetSubsystemPe, + UefiImageGetSegmentAlignmentPe, + UefiImageGetImageSizePe, + UefiImageGetBaseAddressPe, + UefiImageGetRelocsStrippedPe, + UefiImageLoaderGetImageAddressPe, + UefiImageLoaderGetImageRecordPe, + UefiImageDebugLocateImagePe, + UefiImageGetFixedAddressPe, + UefiImageDebugPrintSegmentsPe +}; diff --git a/MdePkg/Library/BaseUefiImageLib/PeSupport.h b/MdePkg/Library/BaseUefiImageLib/PeSupport.h new file mode 100644 index 0000000000..e25b122972 --- /dev/null +++ b/MdePkg/Library/BaseUefiImageLib/PeSupport.h @@ -0,0 +1,16 @@ +/** @file + UEFI Image Loader library implementation for PE/COFF Images. + + Copyright (c) 2021, Marvin Häuser. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef PE_SUPPORT_H +#define PE_SUPPORT_H + +#include "UefiImageFormat.h" + +extern CONST UEFI_IMAGE_FORMAT_SUPPORT mPeSupport; + +#endif // PE_SUPPORT_H diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h b/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h new file mode 100644 index 0000000000..f9e96287bf --- /dev/null +++ b/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h @@ -0,0 +1,235 @@ +/** @file + UEFI Image Loader library fornat support infrastructure. + + Copyright (c) 2023, Marvin Häuser. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef UEFI_IMAGE_FORMAT_H +#define UEFI_IMAGE_FORMAT_H + +#include + +#include + +typedef +RETURN_STATUS +(*UEFI_IMAGE_INITIALIZE_CONTEXT_PRE_HASH) ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN CONST VOID *FileBuffer, + IN UINT32 FileSize + ); + +typedef +BOOLEAN +(*UEFI_IMAGE_HASH_IMAGE_DEFAULT) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN OUT VOID *HashContext, + IN UEFI_IMAGE_LOADER_HASH_UPDATE HashUpdate + ); + +typedef +RETURN_STATUS +(*UEFI_IMAGE_INITIALIZE_CONTEXT_POST_HASH) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +RETURN_STATUS +(*UEFI_IMAGE_LOAD_IMAGE) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT VOID *Destination, + IN UINT32 DestinationSize + ); + +typedef +BOOLEAN +(*UEFI_IMAGE_IMAGE_IS_IN_PLACE) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +RETURN_STATUS +(*UEFI_IMAGE_LOAD_IMAGE_INPLACE) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +RETURN_STATUS +(*UEFI_IMAGE_RELOCAE_IMAGE_INPLACE) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +RETURN_STATUS +(*UEFI_IMAGE_LOADER_GET_RUNTIME_CONTEXT_SIZE) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *Size + ); + +typedef +RETURN_STATUS +(*UEFI_IMAGE_RELOCARE_IMAGE) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINT64 BaseAddress, + OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize + ); + +typedef +RETURN_STATUS +(*UEFI_IMAGE_RUNTIME_RELOCATE_IMAGE) ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN UINT64 BaseAddress, + IN CONST VOID *RuntimeContext + ); + +typedef +VOID +(*UEFI_IMAGE_DISCARD_SEGMENTS) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +RETURN_STATUS +(*UEFI_IMAGE_GET_SYMBOLS_PATH) ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST CHAR8 **SymbolsPath, + OUT UINT32 *SymbolsPathSize + ); + +typedef +RETURN_STATUS +(*UEFI_IMAGE_GET_FIRST_CERTIFICATE) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST WIN_CERTIFICATE **Certificate + ); + +typedef +RETURN_STATUS +(*UEFI_IMAGE_GET_NEXT_CERTIFICATE) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN OUT CONST WIN_CERTIFICATE **Certificate + ); + +typedef +RETURN_STATUS +(*UEFI_IMAGE_GET_HII_DATA_RVA) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *HiiRva, + OUT UINT32 *HiiSize + ); + +typedef +UINT32 +(*UEFI_IMAGE_GET_ENTRY_POINT_ADDRESS) ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +UINT16 +(*UEFI_IMAGE_GET_MACHINE) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +UINT16 +(*UEFI_IMAGE_GET_SUBSYSTEM) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +UINT32 +(*UEFI_IMAGE_GET_SEGMENT_ALIGNMENT) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +UINT32 +(*UEFI_IMAGE_GET_IMAGE_SIZE) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +UINT32 +(*UEFI_IMAGE_GET_IMAGE_SIZE_INPLACE) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +UINT64 +(*UEFI_IMAGE_GET_BASE_ADDRESS) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +BOOLEAN +(*UEFI_IMAGE_GET_RELOCS_STRIPPED) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +UINTN +(*UEFI_IMAGE_LOADER_GET_IMAGE_ADDRESS) ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +UEFI_IMAGE_RECORD * +(*UEFI_IMAGE_LOADER_GET_IMAGE_RECORD) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef +RETURN_STATUS +(*UEFI_IMAGE_DEBUG_LOCATE_IMAGE) ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINTN Address + ); + +typedef +RETURN_STATUS +(*UEFI_IMAGE_GET_FIXED_ADDRESS) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT64 *Address + ); + +typedef +VOID +(*UEFI_IMAGE_DEBUG_PRINT_SEGMENTS) ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + +typedef struct { + UEFI_IMAGE_INITIALIZE_CONTEXT_PRE_HASH InitializeContextPreHash; + UEFI_IMAGE_HASH_IMAGE_DEFAULT HashImageDefault; + UEFI_IMAGE_INITIALIZE_CONTEXT_POST_HASH InitializeContextPostHash; + UEFI_IMAGE_LOAD_IMAGE LoadImage; + UEFI_IMAGE_IMAGE_IS_IN_PLACE ImageIsInplace; + UEFI_IMAGE_LOAD_IMAGE_INPLACE LoadImageInplace; + UEFI_IMAGE_RELOCAE_IMAGE_INPLACE RelocateImageInplace; + UEFI_IMAGE_LOADER_GET_RUNTIME_CONTEXT_SIZE LoaderGetRuntimeContextSize; + UEFI_IMAGE_RELOCARE_IMAGE RelocateImage; + UEFI_IMAGE_RUNTIME_RELOCATE_IMAGE RuntimeRelocateImage; + UEFI_IMAGE_DISCARD_SEGMENTS DiscardSegments; + UEFI_IMAGE_GET_SYMBOLS_PATH GetSymbolsPath; + UEFI_IMAGE_GET_FIRST_CERTIFICATE GetFirstCertificate; + UEFI_IMAGE_GET_NEXT_CERTIFICATE GetNextCertificate; + UEFI_IMAGE_GET_HII_DATA_RVA GetHiiDataRva; + UEFI_IMAGE_GET_ENTRY_POINT_ADDRESS GetEntryPointAddress; + UEFI_IMAGE_GET_MACHINE GetMachine; + UEFI_IMAGE_GET_SUBSYSTEM GetSubsystem; + UEFI_IMAGE_GET_SEGMENT_ALIGNMENT GetSegmentAlignment; + UEFI_IMAGE_GET_IMAGE_SIZE GetImageSize; + UEFI_IMAGE_GET_BASE_ADDRESS GetBaseAddress; + UEFI_IMAGE_GET_RELOCS_STRIPPED GetRelocsStripped; + UEFI_IMAGE_LOADER_GET_IMAGE_ADDRESS LoaderGetImageAddress; + UEFI_IMAGE_LOADER_GET_IMAGE_RECORD LoaderGetImageRecord; + UEFI_IMAGE_DEBUG_LOCATE_IMAGE DebugLocateImage; + UEFI_IMAGE_GET_FIXED_ADDRESS GetFixedAddress; + UEFI_IMAGE_DEBUG_PRINT_SEGMENTS DebugPrintSegments; +} UEFI_IMAGE_FORMAT_SUPPORT; + +#endif // UEFI_IMAGE_FORMAT_H diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c b/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c new file mode 100644 index 0000000000..1803b49035 --- /dev/null +++ b/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c @@ -0,0 +1,629 @@ +/** @file + UEFI Image Loader library implementation. + + Copyright (c) 2023, Marvin Häuser. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "PeSupport.h" + +STATIC_ASSERT ( + UEFI_IMAGE_FORMAT_SUPPORT_SOURCES != 0, + "At least one UEFI image format support source must be enabled." + ); + +#if (UEFI_IMAGE_FORMAT_SUPPORT_SOURCES & (1 << UEFI_IMAGE_SOURCE_NON_FV)) != 0 +#define UEFI_IMAGE_FORMAT_SUPPORT_NON_FV PcdGet8 (PcdUefiImageFormatSupportNonFv) +#else +#define UEFI_IMAGE_FORMAT_SUPPORT_NON_FV 0 +#endif + +#if (UEFI_IMAGE_FORMAT_SUPPORT_SOURCES & (1 << UEFI_IMAGE_SOURCE_FV)) != 0 +#define UEFI_IMAGE_FORMAT_SUPPORT_FV PcdGet8 (PcdUefiImageFormatSupportFv) +#else +#define UEFI_IMAGE_FORMAT_SUPPORT_FV 0 +#endif + +#define UEFI_IMAGE_SUPPORT \ + (UEFI_IMAGE_FORMAT_SUPPORT_NON_FV | UEFI_IMAGE_FORMAT_SUPPORT_FV) + +#define FORMAT_EQ(FormatIndex, Format) \ + (UEFI_IMAGE_SUPPORT == (1U << (Format)) || \ + ((UEFI_IMAGE_SUPPORT & (1U << (Format))) != 0 && \ + (FormatIndex) == (Format))) + +#define UEFI_IMAGE_EXEC(Result, FormatIndex, Func, ...) \ + do { \ + ASSERT ((FormatIndex) == UefiImageFormatPe); \ + Result = mPeSupport.Func (__VA_ARGS__); \ + } while (FALSE) + +#define UEFI_IMAGE_EXEC_VOID(FormatIndex, Func, ...) \ + do { \ + ASSERT ((FormatIndex) == UefiImageFormatPe); \ + mPeSupport.Func (__VA_ARGS__); \ + } while (FALSE) + +STATIC_ASSERT ( + UefiImageFormatPe == UefiImageFormatMax - 1, + "Support for more formats needs to be added above." + ); + +#define FORMAT_SUPPORTED(Format, Source) \ + ((UEFI_IMAGE_SUPPORT & (1U << (Format))) != 0 && \ + (mUefiImageSupportSource[Source] & (1U << (Format))) != 0) + +STATIC +RETURN_STATUS +InternalInitializeContextPreHash ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN CONST VOID *FileBuffer, + IN UINT32 FileSize, + IN UINT8 FormatIndex + ) +{ + RETURN_STATUS Status; + + UEFI_IMAGE_EXEC ( + Status, + FormatIndex, + InitializeContextPreHash, + Context, + FileBuffer, + FileSize + ); + + return Status; +} + +RETURN_STATUS +UefiImageInitializeContextPreHash ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN CONST VOID *FileBuffer, + IN UINT32 FileSize, + IN UEFI_IMAGE_SOURCE Source + ) +{ + CONST UINT8 mUefiImageSupportSource[UEFI_IMAGE_SOURCE_MAX] = { + UEFI_IMAGE_FORMAT_SUPPORT_NON_FV, + UEFI_IMAGE_FORMAT_SUPPORT_FV, + UEFI_IMAGE_SUPPORT + }; + + RETURN_STATUS Status; + +#if (UEFI_IMAGE_FORMAT_SUPPORT_SOURCES & (1U << UEFI_IMAGE_SOURCE_NON_FV)) != 0 + ASSERT ((PcdGet8 (PcdUefiImageFormatSupportNonFv) & ~((1ULL << UefiImageFormatMax) - 1ULL)) == 0); + ASSERT (PcdGet8 (PcdUefiImageFormatSupportNonFv) != 0); +#else + ASSERT (Source != UEFI_IMAGE_SOURCE_NON_FV); +#endif + +#if (UEFI_IMAGE_FORMAT_SUPPORT_SOURCES & (1U << UEFI_IMAGE_SOURCE_FV)) != 0 + ASSERT ((PcdGet8 (PcdUefiImageFormatSupportFv) & ~((1ULL << UefiImageFormatMax) - 1ULL)) == 0); + ASSERT (PcdGet8 (PcdUefiImageFormatSupportFv) != 0); +#else + ASSERT (Source != UEFI_IMAGE_SOURCE_FV); +#endif + + Status = RETURN_UNSUPPORTED; + + STATIC_ASSERT ( + UefiImageFormatPe == UefiImageFormatMax - 1, + "Support for more formats needs to be added above." + ); + + if (FORMAT_SUPPORTED (UefiImageFormatPe, Source)) { + Status = InternalInitializeContextPreHash ( + Context, + FileBuffer, + FileSize, + UefiImageFormatPe + ); + if (!RETURN_ERROR (Status)) { + Context->FormatIndex = UefiImageFormatPe; + return RETURN_SUCCESS; + } + } + + return Status; +} + +BOOLEAN +UefiImageHashImageDefault ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN OUT VOID *HashContext, + IN UEFI_IMAGE_LOADER_HASH_UPDATE HashUpdate + ) +{ + BOOLEAN Success; + + UEFI_IMAGE_EXEC ( + Success, + Context->FormatIndex, + HashImageDefault, + Context, + HashContext, + HashUpdate + ); + + return Success; +} + +RETURN_STATUS +UefiImageInitializeContextPostHash ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + RETURN_STATUS Status; + + UEFI_IMAGE_EXEC ( + Status, + Context->FormatIndex, + InitializeContextPostHash, + Context + ); + + return Status; +} + +RETURN_STATUS +UefiImageLoadImage ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT VOID *Destination, + IN UINT32 DestinationSize + ) +{ + RETURN_STATUS Status; + + UEFI_IMAGE_EXEC ( + Status, + Context->FormatIndex, + LoadImage, + Context, + Destination, + DestinationSize + ); + + return Status; +} + +BOOLEAN +UefiImageImageIsInplace ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + BOOLEAN Result; + + UEFI_IMAGE_EXEC ( + Result, + Context->FormatIndex, + ImageIsInplace, + Context + ); + + return Result; +} + +RETURN_STATUS +UefiImageLoadImageInplace ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + RETURN_STATUS Status; + + UEFI_IMAGE_EXEC ( + Status, + Context->FormatIndex, + LoadImageInplace, + Context + ); + + return Status; +} + +RETURN_STATUS +UefiImageRelocateImageInplace ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + RETURN_STATUS Status; + + UEFI_IMAGE_EXEC ( + Status, + Context->FormatIndex, + RelocateImageInplace, + Context + ); + + return Status; +} + +RETURN_STATUS +UefiImageLoaderGetRuntimeContextSize ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *Size + ) +{ + RETURN_STATUS Status; + + UEFI_IMAGE_EXEC ( + Status, + Context->FormatIndex, + LoaderGetRuntimeContextSize, + Context, + Size + ); + if (!RETURN_ERROR (Status)) { + *Size += 8; + } + + return Status; +} + +RETURN_STATUS +UefiImageRelocateImage ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINT64 BaseAddress, + OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize + ) +{ + RETURN_STATUS Status; + + if (RuntimeContext != NULL) { + *(UINT64 *)RuntimeContext = Context->FormatIndex; + RuntimeContext = (UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *)((UINT64 *)RuntimeContext + 1); + ASSERT (RuntimeContextSize >= 8); + RuntimeContextSize -= 8; + } + + UEFI_IMAGE_EXEC ( + Status, + Context->FormatIndex, + RelocateImage, + Context, + BaseAddress, + RuntimeContext, + RuntimeContextSize + ); + + if (!RETURN_ERROR (Status)) { + UefiImageLoaderRelocateImageExtraAction (Context); + } + + return Status; +} + +RETURN_STATUS +UefiImageRuntimeRelocateImage ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN UINT64 BaseAddress, + IN CONST UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext + ) +{ + RETURN_STATUS Status; + + UEFI_IMAGE_EXEC ( + Status, + *(UINT8 *)RuntimeContext, + RuntimeRelocateImage, + Image, + ImageSize, + BaseAddress, + ((UINT64 *)RuntimeContext + 1) + ); + + return Status; +} + +VOID +UefiImageDiscardSegments ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UEFI_IMAGE_EXEC_VOID ( + Context->FormatIndex, + DiscardSegments, + Context + ); +} + +RETURN_STATUS +UefiImageGetSymbolsPath ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST CHAR8 **SymbolsPath, + OUT UINT32 *SymbolsPathSize + ) +{ + RETURN_STATUS Status; + + UEFI_IMAGE_EXEC ( + Status, + Context->FormatIndex, + GetSymbolsPath, + Context, + SymbolsPath, + SymbolsPathSize + ); + + return Status; +} + +RETURN_STATUS +UefiImageGetFirstCertificate ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST WIN_CERTIFICATE **Certificate + ) +{ + RETURN_STATUS Status; + + UEFI_IMAGE_EXEC ( + Status, + Context->FormatIndex, + GetFirstCertificate, + Context, + Certificate + ); + + return Status; +} + +RETURN_STATUS +UefiImageGetNextCertificate ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN OUT CONST WIN_CERTIFICATE **Certificate + ) +{ + RETURN_STATUS Status; + + UEFI_IMAGE_EXEC ( + Status, + Context->FormatIndex, + GetNextCertificate, + Context, + Certificate + ); + + return Status; +} + +RETURN_STATUS +UefiImageGetHiiDataRva ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *HiiRva, + OUT UINT32 *HiiSize + ) +{ + RETURN_STATUS Status; + + UEFI_IMAGE_EXEC ( + Status, + Context->FormatIndex, + GetHiiDataRva, + Context, + HiiRva, + HiiSize + ); + + return Status; +} + +UINT32 +UefiImageGetEntryPointAddress ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINT32 Result; + + UEFI_IMAGE_EXEC ( + Result, + Context->FormatIndex, + GetEntryPointAddress, + Context + ); + + return Result; +} + +UINT16 +UefiImageGetMachine ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINT16 Result; + + UEFI_IMAGE_EXEC ( + Result, + Context->FormatIndex, + GetMachine, + Context + ); + + return Result; +} + +UINT16 +UefiImageGetSubsystem ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINT16 Result; + + UEFI_IMAGE_EXEC ( + Result, + Context->FormatIndex, + GetSubsystem, + Context + ); + + return Result; +} + +UINT32 +UefiImageGetSegmentAlignment ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINT32 Result; + + UEFI_IMAGE_EXEC ( + Result, + Context->FormatIndex, + GetSegmentAlignment, + Context + ); + + return Result; +} + +UINT32 +UefiImageGetImageSize ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINT32 Result; + + UEFI_IMAGE_EXEC ( + Result, + Context->FormatIndex, + GetImageSize, + Context + ); + + return Result; +} + +UINT64 +UefiImageGetBaseAddress ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINT64 Result; + + UEFI_IMAGE_EXEC ( + Result, + Context->FormatIndex, + GetBaseAddress, + Context + ); + + return Result; +} + +BOOLEAN +UefiImageGetRelocsStripped ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + BOOLEAN Result; + + UEFI_IMAGE_EXEC ( + Result, + Context->FormatIndex, + GetRelocsStripped, + Context + ); + + return Result; +} + +UINTN +UefiImageLoaderGetImageAddress ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINTN Result; + + UEFI_IMAGE_EXEC ( + Result, + Context->FormatIndex, + LoaderGetImageAddress, + Context + ); + + return Result; +} + +UEFI_IMAGE_RECORD * +UefiImageLoaderGetImageRecord ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UEFI_IMAGE_RECORD *Result; + + UEFI_IMAGE_EXEC ( + Result, + Context->FormatIndex, + LoaderGetImageRecord, + Context + ); + + return Result; +} + +RETURN_STATUS +UefiImageDebugLocateImage ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINTN Address + ) +{ + RETURN_STATUS Status; + + UEFI_IMAGE_EXEC ( + Status, + Context->FormatIndex, + DebugLocateImage, + Context, + Address + ); + + return Status; +} + +RETURN_STATUS +UefiImageGetFixedAddress ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT64 *Address + ) +{ + RETURN_STATUS Status; + + UEFI_IMAGE_EXEC ( + Status, + Context->FormatIndex, + GetFixedAddress, + Context, + Address + ); + + return Status; +} + +VOID +UefiImageDebugPrintSegments ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UEFI_IMAGE_EXEC_VOID ( + Context->FormatIndex, + DebugPrintSegments, + Context + ); +} diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.c b/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.c deleted file mode 100644 index 3350c92466..0000000000 --- a/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.c +++ /dev/null @@ -1,299 +0,0 @@ -/** @file - UEFI Image Loader library implementation for PE/COFF Images. - - Copyright (c) 2021, Marvin Häuser. All rights reserved.
- - SPDX-License-Identifier: BSD-3-Clause -**/ - -#define UEFI_IMAGE_LOADER_IMAGE_CONTEXT PE_COFF_LOADER_IMAGE_CONTEXT -#define UEFI_IMAGE_LOADER_RUNTIME_CONTEXT PE_COFF_LOADER_RUNTIME_CONTEXT - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "PeCoffSupport.h" - -RETURN_STATUS -UefiImageInitializeContextPreHash ( - OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN CONST VOID *FileBuffer, - IN UINT32 FileSize - ) -{ - return PeCoffInitializeContext (Context, FileBuffer, FileSize); -} - -RETURN_STATUS -UefiImageInitializeContextPostHash ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - ASSERT (Context != NULL); - - return RETURN_SUCCESS; -} - -UINT8 -UefiImageGetFormat ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return UefiImageFormatPe; -} - -BOOLEAN -UefiImageHashImageDefault ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN OUT VOID *HashContext, - IN UEFI_IMAGE_LOADER_HASH_UPDATE HashUpdate - ) -{ - return PeCoffHashImageAuthenticode (Context, HashContext, HashUpdate); -} - -RETURN_STATUS -UefiImageLoadImage ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - OUT VOID *Destination, - IN UINT32 DestinationSize - ) -{ - return PeCoffLoadImage (Context, Destination, DestinationSize); -} - -BOOLEAN -UefiImageImageIsInplace ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return PeCoffImageIsInplace (Context); -} - -RETURN_STATUS -UefiImageLoadImageInplace ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return PeCoffLoadImageInplace (Context); -} - -RETURN_STATUS -UefiImageRelocateImageInplace ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return PeCoffRelocateImageInplace (Context); -} - -RETURN_STATUS -UefiImageLoaderGetRuntimeContextSize ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - OUT UINT32 *Size - ) -{ - return PeCoffLoaderGetRuntimeContextSize (Context, Size); -} - -RETURN_STATUS -UefiImageRelocateImage ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINT64 BaseAddress, - OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, - IN UINT32 RuntimeContextSize - ) -{ - RETURN_STATUS Status; - - Status = PeCoffRelocateImage ( - Context, - BaseAddress, - RuntimeContext, - RuntimeContextSize - ); - if (!RETURN_ERROR (Status)) { - UefiImageLoaderRelocateImageExtraAction (Context); - } - - return Status; -} - -RETURN_STATUS -UefiImageRuntimeRelocateImage ( - IN OUT VOID *Image, - IN UINT32 ImageSize, - IN UINT64 BaseAddress, - IN CONST UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext - ) -{ - return PeCoffRuntimeRelocateImage ( - Image, - ImageSize, - BaseAddress, - RuntimeContext - ); -} - -VOID -UefiImageDiscardSegments ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - PeCoffDiscardSections (Context); -} - -RETURN_STATUS -UefiImageGetSymbolsPath ( - IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - OUT CONST CHAR8 **SymbolsPath, - OUT UINT32 *SymbolsPathSize - ) -{ - return PeCoffGetPdbPath (Context, SymbolsPath, SymbolsPathSize); -} - -RETURN_STATUS -UefiImageGetFirstCertificate ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - OUT CONST WIN_CERTIFICATE **Certificate - ) -{ - return PeCoffGetFirstCertificate (Context, Certificate); -} - -RETURN_STATUS -UefiImageGetNextCertificate ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN OUT CONST WIN_CERTIFICATE **Certificate - ) -{ - return PeCoffGetNextCertificate (Context, Certificate); -} - -RETURN_STATUS -UefiImageGetHiiDataRva ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - OUT UINT32 *HiiRva, - OUT UINT32 *HiiSize - ) -{ - return PeCoffGetHiiDataRva (Context, HiiRva, HiiSize); -} - -UINT32 -UefiImageGetEntryPointAddress ( - IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return PeCoffGetAddressOfEntryPoint (Context); -} - -UINT16 -UefiImageGetMachine ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return PeCoffGetMachine (Context); -} - -UINT16 -UefiImageGetSubsystem ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return PeCoffGetSubsystem (Context); -} - -UINT32 -UefiImageGetSegmentAlignment ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return PeCoffGetSectionAlignment (Context); -} - -UINT32 -UefiImageGetImageSize ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return PeCoffGetSizeOfImage (Context); -} - -UINT32 -UefiImageGetImageSizeInplace ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return PeCoffGetSizeOfImageInplace (Context); -} - -UINT64 -UefiImageGetPreferredAddress ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return PeCoffGetImageBase (Context); -} - -BOOLEAN -UefiImageGetRelocsStripped ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return PeCoffGetRelocsStripped (Context); -} - -UINTN -UefiImageLoaderGetImageAddress ( - IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return PeCoffLoaderGetImageAddress (Context); -} - -UEFI_IMAGE_RECORD * -UefiImageLoaderGetImageRecord ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - return UefiImageLoaderGetImageRecordPeCoff (Context); -} - -RETURN_STATUS -UefiImageDebugLocateImage ( - OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address - ) -{ - return UefiImageDebugLocateImagePeCoff (Context, Address); -} - -RETURN_STATUS -UefiImageGetFixedAddress ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - OUT UINT64 *Address - ) -{ - return UefiImageGetFixedAddressPeCoff (Context, Address); -} - -VOID -UefiImageDebugPrintSegments ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context - ) -{ - UefiImageDebugPrintSegmentsPeCoff (Context); -} diff --git a/MdePkg/MdeLibs.dsc.inc b/MdePkg/MdeLibs.dsc.inc index fc0c53538d..f83a07ad13 100644 --- a/MdePkg/MdeLibs.dsc.inc +++ b/MdePkg/MdeLibs.dsc.inc @@ -57,6 +57,39 @@ StackCheckLib|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf !endif + # + # For security and code size optimization reasons, the UefiImageLib design is + # complicated. To not expose FV-only UEFI image formats via, e.g., DxeCore to + # untrusted sources, UefiImageLib can be configured to support different UEFI + # image formats per source. While compilers generally manage to optimize the + # initial parsing steps, complex control flow can make them lose track of the + # UefiImageLib source property and thus conditionally call into code for UEFI + # image formats that are not required by the module at all (e.g., because it + # only ever deals with FV images). + # + # To have the code for unsupported UEFI image file formats removed, + # UefiImageLib comes in multiple flavours that support FV-only, non-FV-only, + # or all UEFI image formats. These flavours are supposed to be used by + # top-level modules that have a clear scope. As libraries may depend on + # UefiImageLib too, however, they should consume the general UefiImageLib with + # no clear flavour. + # + # If they consume libraries with UefiImageLib dependencies, modules must have + # their general UefiImageLib set to their corresponding flavour for correct + # linkage. In order to make this easier, there is a heuristic below, based on + # module types, to set the most likely instance of UefiImageLib. In rare + # cases, manual overriding in the platform DSC may be necessary. + # + UefiImageOnlyNonFvLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf + UefiImageOnlyFvLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf + UefiImageAllLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageAllLib.inf + +[LibraryClasses.common.USER_DEFINED, LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM, LibraryClasses.common.SMM_CORE, LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.DXE_SMM_DRIVER, LibraryClasses.common.MM_STANDALONE] + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf + +[LibraryClasses.common.DXE_CORE, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION] + UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageAllLib.inf + [LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE] # edk2 does not implement exception handling for SEC and PEI_CORE, so StackCheckLibNull is used, as failing # stack cookies will generate an exception, which if unhandled can lead to a hung system state. If a platform diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 24cd311483..d893bec5d0 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -2366,6 +2366,16 @@ # @Prompt Remove X permission from WX sections. gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX|FALSE|BOOLEAN|0x40001021 + ## Indicates the UEFI image file formats supported outside FVs.

+ # BIT0 - PE.
+ # @Prompt Supported UEFI image file formats outside FVs. + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportNonFv|0x01|UINT8|0x40002000 + + ## Indicates the UEFI image file formats supported inside FVs.

+ # BIT0 - PE.
+ # @Prompt Supported UEFI image file formats inside FVs. + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x01|UINT8|0x40002001 + [PcdsFixedAtBuild,PcdsPatchableInModule] ## Indicates the maximum length of unicode string used in the following # BaseLib functions: StrLen(), StrSize(), StrCmp(), StrnCmp(), StrCpy(), StrnCpy()

diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index cb549d6f42..9e9de024c8 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -59,7 +59,9 @@ MdePkg/Library/BaseS3PciSegmentLib/BaseS3PciSegmentLib.inf MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf + MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf + MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf + MdePkg/Library/BaseUefiImageLib/BaseUefiImageAllLib.inf MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf MdePkg/Library/BasePostCodeLibDebug/BasePostCodeLibDebug.inf diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc index f69df9d4c2..6880255c9f 100644 --- a/NetworkPkg/NetworkPkg.dsc +++ b/NetworkPkg/NetworkPkg.dsc @@ -47,7 +47,6 @@ RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc index 0c3ddaf445..4413cace23 100644 --- a/OvmfPkg/AmdSev/AmdSevX64.dsc +++ b/OvmfPkg/AmdSev/AmdSevX64.dsc @@ -123,7 +123,6 @@ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf @@ -249,7 +248,6 @@ !endif CcProbeLib|OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -265,7 +263,6 @@ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc index d1e3616dc3..0ee4e0c9bc 100644 --- a/OvmfPkg/Bhyve/BhyveX64.dsc +++ b/OvmfPkg/Bhyve/BhyveX64.dsc @@ -134,7 +134,6 @@ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf @@ -276,7 +275,6 @@ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -292,7 +290,6 @@ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 07e5495463..488e2245d6 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -134,7 +134,6 @@ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf @@ -280,7 +279,6 @@ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -296,7 +294,6 @@ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 572b18352e..3f3195d7e2 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -141,7 +141,6 @@ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf @@ -285,7 +284,6 @@ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -301,7 +299,6 @@ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 1797b50530..96c7dd5ab0 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -151,7 +151,6 @@ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf @@ -302,7 +301,6 @@ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CcProbeLib|OvmfPkg/Library/CcProbeLib/SecPeiCcProbeLib.inf [LibraryClasses.common.PEIM] @@ -319,7 +317,6 @@ DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf !endif PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc index 10f2992ceb..a74d487dbc 100644 --- a/OvmfPkg/OvmfXen.dsc +++ b/OvmfPkg/OvmfXen.dsc @@ -135,7 +135,6 @@ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf @@ -272,7 +271,6 @@ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf @@ -283,7 +281,6 @@ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf !if $(SOURCE_DEBUG_ENABLE) == TRUE diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c index d2add7d6c4..c3bf9d3995 100644 --- a/OvmfPkg/Sec/SecMain.c +++ b/OvmfPkg/Sec/SecMain.c @@ -724,7 +724,12 @@ FindAndReportEntryPoints ( // // Report SEC Core debug information when remote debug is enabled // - Status = UefiImageInitializeContext (&ImageContext, (VOID *) (UINTN) SecCoreImageBase, SecCoreImageSize); + Status = UefiImageInitializeContext ( + &ImageContext, + (VOID *) (UINTN) SecCoreImageBase, + SecCoreImageSize, + UEFI_IMAGE_SOURCE_FV + ); ASSERT_EFI_ERROR (Status); Status = UefiImageLoadImageInplace (&ImageContext); @@ -735,7 +740,12 @@ FindAndReportEntryPoints ( // // Find PEI Core entry point // - Status = UefiImageInitializeContext (&ImageContext, (VOID *) (UINTN) PeiCoreImageBase, PeiCoreImageSize); + Status = UefiImageInitializeContext ( + &ImageContext, + (VOID *) (UINTN) PeiCoreImageBase, + PeiCoreImageSize, + UEFI_IMAGE_SOURCE_FV + ); ASSERT_EFI_ERROR (Status); Status = UefiImageLoadImageInplace (&ImageContext); diff --git a/OvmfPkg/Sec/SecMain.inf b/OvmfPkg/Sec/SecMain.inf index 0383c4f999..7cfdddcbf9 100644 --- a/OvmfPkg/Sec/SecMain.inf +++ b/OvmfPkg/Sec/SecMain.inf @@ -47,7 +47,7 @@ CpuLib DebugAgentLib IoLib - UefiImageLib + UefiImageOnlyFvLib UefiImageExtraActionLib ExtractGuidedSectionLib LocalApicLib diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index 5000e05b7c..56f2467297 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -33,7 +33,6 @@ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf # FIXME: ARM? CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf diff --git a/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootUefiImage.c b/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootUefiImage.c index 51956c5e6d..34e87d84e1 100644 --- a/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootUefiImage.c +++ b/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootUefiImage.c @@ -77,7 +77,8 @@ MeasureUefiImageAndExtend ( Status = UefiImageInitializeContextPreHash ( &ImageContext, (VOID *) (UINTN) ImageAddress, - (UINT32) ImageSize + (UINT32) ImageSize, + UEFI_IMAGE_SOURCE_ALL ); if (EFI_ERROR (Status)) { // diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf index 3e86b6c999..ad7cbcb7a7 100644 --- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf +++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf @@ -63,7 +63,7 @@ PerformanceLib ReportStatusCodeLib Tcg2PhysicalPresenceLib - UefiImageLib + UefiImageAllLib [Guids] ## SOMETIMES_CONSUMES ## Variable:L"SecureBoot" diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf index ba5775198f..ace9b343c8 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf @@ -53,7 +53,7 @@ PlatformSecureLib DevicePathLib FileExplorerLib - UefiImageLib + UefiImageOnlyNonFvLib SecureBootVariableLib SecureBootVariableProvisionLib diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c index dd953e63ac..e1c81acb9f 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c @@ -1985,7 +1985,15 @@ EnrollImageSignatureToSigDB ( goto ON_EXIT; } - Status = UefiImageInitializeContextPreHash (&ImageContext, ImageBase, (UINT32)ImageSize); + // + // Secure Boot does not apply to images from FVs. + // + Status = UefiImageInitializeContextPreHash ( + &ImageContext, + ImageBase, + (UINT32)ImageSize, + UEFI_IMAGE_SOURCE_NON_FV + ); if (EFI_ERROR (Status)) { goto ON_EXIT; } diff --git a/SignedCapsulePkg/SignedCapsulePkg.dsc b/SignedCapsulePkg/SignedCapsulePkg.dsc index c840a1acb2..5039964aac 100644 --- a/SignedCapsulePkg/SignedCapsulePkg.dsc +++ b/SignedCapsulePkg/SignedCapsulePkg.dsc @@ -41,7 +41,6 @@ PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf # # UEFI & PI diff --git a/StandaloneMmPkg/Core/Dispatcher.c b/StandaloneMmPkg/Core/Dispatcher.c index eeed408eb6..529ca7d127 100644 --- a/StandaloneMmPkg/Core/Dispatcher.c +++ b/StandaloneMmPkg/Core/Dispatcher.c @@ -202,7 +202,12 @@ MmLoadImage ( // // Get information about the image being loaded // - Status = UefiImageInitializeContext (ImageContext, DriverEntry->Pe32Data, DriverEntry->Pe32DataSize); + Status = UefiImageInitializeContext ( + ImageContext, + DriverEntry->Pe32Data, + DriverEntry->Pe32DataSize, + UEFI_IMAGE_SOURCE_FV + ); if (EFI_ERROR (Status)) { return Status; } diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf index ec9283df7a..6dd6845ca6 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.inf +++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf @@ -50,7 +50,7 @@ HobLib MemoryAllocationLib MemLib - UefiImageLib + UefiImageOnlyFvLib ReportStatusCodeLib StandaloneMmProtectionLib StandaloneMmCoreEntryPoint diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index dfe51ad519..2cb2df7e94 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -54,7 +54,6 @@ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf diff --git a/UefiCpuPkg/SecCore/FindPeiCore.c b/UefiCpuPkg/SecCore/FindPeiCore.c index 3cded940d3..a5d1686fc2 100644 --- a/UefiCpuPkg/SecCore/FindPeiCore.c +++ b/UefiCpuPkg/SecCore/FindPeiCore.c @@ -172,7 +172,8 @@ FindAndReportEntryPoints ( Status = UefiImageInitializeContext ( &ImageContext, (VOID*) (UINTN) SecCoreImageBase, - SecCoreImageSize + SecCoreImageSize, + UEFI_IMAGE_SOURCE_FV ); ASSERT_EFI_ERROR (Status); @@ -198,7 +199,8 @@ FindAndReportEntryPoints ( Status = UefiImageInitializeContext ( &ImageContext, (VOID*)(UINTN)PeiCoreImageBase, - PeiCoreImageSize + PeiCoreImageSize, + UEFI_IMAGE_SOURCE_FV ); ASSERT_EFI_ERROR (Status); diff --git a/UefiCpuPkg/SecCore/SecCoreNative.inf b/UefiCpuPkg/SecCore/SecCoreNative.inf index 5edff00946..0e1f77fc6f 100644 --- a/UefiCpuPkg/SecCore/SecCoreNative.inf +++ b/UefiCpuPkg/SecCore/SecCoreNative.inf @@ -45,7 +45,7 @@ PcdLib DebugAgentLib CpuLib - UefiImageLib + UefiImageOnlyFvLib UefiImageExtraActionLib CpuExceptionHandlerLib ReportStatusCodeLib diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 66a7082ce5..f14e1eb26d 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -59,7 +59,6 @@ SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf SmmCpuSyncLib|UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf UefiImageExtraActionLib|MdePkg/Library/BaseUefiImageExtraActionLibNull/BaseUefiImageExtraActionLibNull.inf TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c index 6763416060..3382aad7ce 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c @@ -36,7 +36,12 @@ LoadUefiImage ( UINT32 BufferSize; VOID *Buffer; - Status = UefiImageInitializeContext (&ImageContext, UefiImage, UefiImageSize); + Status = UefiImageInitializeContext ( + &ImageContext, + UefiImage, + UefiImageSize, + UEFI_IMAGE_SOURCE_FV + ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf index f012299f41..5d7b2acf8c 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf @@ -51,7 +51,7 @@ IoLib BlParseLib HobLib - UefiImageLib + UefiImageOnlyFvLib PlatformSupportLib CpuLib StackCheckLib diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf index 2e8dec529f..b978ad606a 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf @@ -46,7 +46,7 @@ CpuLib HobPrintLib StackCheckLib - UefiImageLib + UefiImageOnlyFvLib MemoryAllocationLib [Guids] diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 98ea4774b9..93bf6e392f 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -210,7 +210,6 @@ PciSegmentLib|MdePkg/Library/PciSegmentLibSegmentInfo/BasePciSegmentLibSegmentInfo.inf PciSegmentInfoLib|UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.inf PeCoffLib2|MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf - UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageLibPeCoff.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf DxeHobListLib|UefiPayloadPkg/Library/DxeHobListLib/DxeHobListLib.inf From ba9aad0b56f2804d9ce3b49419e3119fc1937a08 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 15 Dec 2023 16:28:15 +0300 Subject: [PATCH 079/341] ImageTool: Rework PeEmit with dynamically-growing buffers --- BaseTools/Conf/build_rule.template | 10 +- BaseTools/ImageTool/BinEmit.c | 17 +- BaseTools/ImageTool/DynamicBuffer.c | 215 +++ BaseTools/ImageTool/DynamicBuffer.h | 74 + BaseTools/ImageTool/ElfScan.c | 30 +- BaseTools/ImageTool/GNUmakefile | 2 +- BaseTools/ImageTool/Image.c | 375 +++-- BaseTools/ImageTool/ImageTool.c | 56 +- BaseTools/ImageTool/ImageTool.h | 31 +- BaseTools/ImageTool/ImageToolEmit.c | 21 +- BaseTools/ImageTool/ImageToolEmit.h | 1 + BaseTools/ImageTool/Makefile | 2 +- BaseTools/ImageTool/PeEmit.c | 1322 ++++++----------- BaseTools/ImageTool/PeEmitCommon.c | 5 +- BaseTools/ImageTool/PeEmitCommon.h | 6 +- BaseTools/ImageTool/PeScan.c | 159 +- BaseTools/ImageTool/PeScan.h | 4 +- BaseTools/ImageTool/UefiImageScan.c | 86 +- BaseTools/Source/C/Common/GNUmakefile | 1 + BaseTools/Source/C/Common/Makefile | 1 + BaseTools/Source/C/GenFv/GenFvInternalLib.c | 1 + BaseTools/Source/C/VolInfo/VolInfo.c | 1 + BaseTools/Source/Python/GenFds/DataSection.py | 1 + BaseTools/Source/Python/GenFds/EfiSection.py | 1 + .../Source/Python/GenFds/FfsInfStatement.py | 2 + .../Python/GenFds/GenFdsGlobalVariable.py | 4 +- BaseTools/Source/Python/build/BuildReport.py | 2 +- BaseTools/Source/Python/build/build.py | 8 +- MdePkg/Library/BaseUefiImageLib/PeSupport.c | 8 +- .../BaseUefiImageLib/UefiImageFormat.h | 8 +- .../Library/BaseUefiImageLib/UefiImageLib.c | 14 +- 31 files changed, 1222 insertions(+), 1246 deletions(-) create mode 100644 BaseTools/ImageTool/DynamicBuffer.c create mode 100644 BaseTools/ImageTool/DynamicBuffer.h diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template index a218dad9d8..37e14708e5 100755 --- a/BaseTools/Conf/build_rule.template +++ b/BaseTools/Conf/build_rule.template @@ -134,8 +134,8 @@ "$(CC)" $(DEPS_FLAGS) $(CC_FLAGS) -o ${dst} $(INC) ${src} -## Early stages on ARM/AArch64 execute with strict alignment enabled and will crash, -# when compiler generates misaligned access. +## Early stages on ARM/AArch64 execute with strict alignment enabled and will crash, +# when compiler generates misaligned access. # [C-Code-File.BASE.AARCH64,C-Code-File.SEC.AARCH64,C-Code-File.PEI_CORE.AARCH64,C-Code-File.PEIM.AARCH64,C-Code-File.BASE.ARM,C-Code-File.SEC.ARM,C-Code-File.PEI_CORE.ARM,C-Code-File.PEIM.ARM] @@ -382,7 +382,7 @@ $(OUTPUT_DIR)(+)$(MODULE_NAME).map - ImageTool GenImage -c PE -t $(MODULE_TYPE) -o ${dst} ${src} + ImageTool GenImage -c PE -x -t $(MODULE_TYPE) -o ${dst} ${src} $(CP) ${dst} $(DEBUG_DIR) $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) @@ -392,7 +392,7 @@ $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).strip $(OBJCOPY) $(OBJCOPY_STRIPFLAG) $(DEBUG_DIR)(+)$(MODULE_NAME).strip - ImageTool GenImage -c PE -t $(MODULE_TYPE) -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).strip + ImageTool GenImage -c PE -x -t $(MODULE_TYPE) -d ${src} -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).strip $(CP) ${dst} $(DEBUG_DIR) $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi @@ -403,7 +403,7 @@ "$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff # create symbol file for GDB debug -$(DSYMUTIL) ${src} - ImageTool GenImage -c PE -t $(MODULE_TYPE) -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff + ImageTool GenImage -c PE -x -t $(MODULE_TYPE) -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff $(CP) ${dst} $(DEBUG_DIR) $(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi -$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR) diff --git a/BaseTools/ImageTool/BinEmit.c b/BaseTools/ImageTool/BinEmit.c index 828c357a7a..ed459f0caf 100644 --- a/BaseTools/ImageTool/BinEmit.c +++ b/BaseTools/ImageTool/BinEmit.c @@ -19,9 +19,6 @@ CreateEntry ( EFI_IMAGE_RESOURCE_DIRECTORY *RDir; EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *Entry; - assert (HiiSectionHeader != NULL); - assert (HiiSectionOffset != NULL); - RDir = (EFI_IMAGE_RESOURCE_DIRECTORY *)(HiiSectionHeader + *HiiSectionOffset); *HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY); RDir->NumberOfNamedEntries = 1; @@ -49,11 +46,6 @@ CreateStringEntry ( { EFI_IMAGE_RESOURCE_DIRECTORY_STRING *RDStr; - assert (Entry != NULL); - assert (HiiSectionHeader != NULL); - assert (HiiSectionOffset != NULL); - assert (String != NULL); - Entry->u1.s.NameOffset = *HiiSectionOffset; RDStr = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *)(HiiSectionHeader + *HiiSectionOffset); RDStr->Length = (UINT16)StrLen (String); @@ -78,8 +70,6 @@ InitializeHiiResouceSectionHeader ( EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *LangRDirEntry; EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry; - assert (HiiSectionHeader != NULL); - HiiSectionOffset = 0; // // Create Type, Name, Language entries @@ -123,10 +113,6 @@ ConstructHii ( UINT32 FileSize; UINT8 NumberOfFormPackages; - assert (Hii != NULL); - assert (HiiGuid != NULL); - assert (FileNames != NULL); - NumberOfFormPackages = 0; EndPackage.Length = sizeof (EFI_HII_PACKAGE_HEADER); @@ -173,7 +159,7 @@ ConstructHii ( CopyGuid (&HiiPackageListHeader.PackageListGuid, HiiGuid); - HiiPackageData = calloc (1, HiiPackageListHeader.PackageLength); + HiiPackageData = AllocateZeroPool (HiiPackageListHeader.PackageLength); if (HiiPackageData == NULL) { return RETURN_OUT_OF_RESOURCES; } @@ -185,6 +171,7 @@ ConstructHii ( File = UserReadFile (FileNames[Index], &FileSize); if (File == NULL) { fprintf (stderr, "ImageTool: Could not open %s: %s\n", FileNames[Index], strerror (errno)); + free (HiiPackageData); return RETURN_ABORTED; } diff --git a/BaseTools/ImageTool/DynamicBuffer.c b/BaseTools/ImageTool/DynamicBuffer.c new file mode 100644 index 0000000000..71ae192737 --- /dev/null +++ b/BaseTools/ImageTool/DynamicBuffer.c @@ -0,0 +1,215 @@ +#include +#include +#include +#include + +#include + +#include + +#include "ImageTool.h" +#include "DynamicBuffer.h" + +#define IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH 0x1000 + +void +ImageToolBufferInit ( + image_tool_dynamic_buffer *Buffer + ) +{ + memset (Buffer, 0, sizeof (*Buffer)); +} + +static +uint32_t +ImageToolBufferExpand ( + image_tool_dynamic_buffer *Buffer, + uint32_t Size + ) +{ + bool Overflow; + uint32_t NewAllocatedSize; + uint8_t *NewMemory; + uint32_t Offset; + + assert (Buffer->DataSize <= Buffer->AllocatedSize); + assert (IS_ALIGNED (Buffer->AllocatedSize, IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH)); + + if (Buffer->AllocatedSize - Buffer->DataSize < Size) { + Overflow = BaseOverflowAlignUpU32 ( + Size, + IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH, + &NewAllocatedSize + ); + if (Overflow) { + DEBUG_RAISE (); + return MAX_UINT32; + } + + Overflow = BaseOverflowAddU32 ( + NewAllocatedSize, + Buffer->AllocatedSize, + &NewAllocatedSize + ); + if (Overflow) { + DEBUG_RAISE (); + return MAX_UINT32; + } + + NewMemory = AllocatePool (NewAllocatedSize); + if (NewMemory == NULL) { + DEBUG_RAISE (); + return MAX_UINT32; + } + + if (Buffer->Memory != NULL) { + memmove (NewMemory, Buffer->Memory, Buffer->DataSize); + FreePool (Buffer->Memory); + } + + memset ( + NewMemory + Buffer->DataSize, + 0, + NewAllocatedSize - Buffer->DataSize + ); + + Buffer->Memory = NewMemory; + Buffer->AllocatedSize = NewAllocatedSize; + } + + Offset = Buffer->DataSize; + Buffer->DataSize += Size; + + return Offset; +} + +void +ImageToolBufferRead ( + void *Data, + uint32_t Size, + const image_tool_dynamic_buffer *Buffer, + uint32_t Offset + ) +{ + assert (Offset + Size > Offset); + assert (Offset + Size <= Buffer->DataSize); + + memmove (Data, &Buffer->Memory[Offset], Size); +} + +void +ImageToolBufferWrite ( + image_tool_dynamic_buffer *Buffer, + uint32_t Offset, + const void *Data, + uint32_t Size + ) +{ + assert (Offset + Size > Offset); + assert (Offset + Size <= Buffer->DataSize); + + memmove (&Buffer->Memory[Offset], Data, Size); +} + +uint32_t +ImageToolBufferAppend ( + image_tool_dynamic_buffer *Buffer, + const void *Data, + uint32_t Size + ) +{ + uint32_t Offset; + + Offset = ImageToolBufferExpand (Buffer, Size); + if (Offset != MAX_UINT32) { + memmove (&Buffer->Memory[Offset], Data, Size); + } + + return Offset; +} + +uint32_t +ImageToolBufferAppendReserve ( + image_tool_dynamic_buffer *Buffer, + uint32_t Size + ) +{ + uint32_t Offset; + + Offset = ImageToolBufferExpand (Buffer, Size); + if (Offset != MAX_UINT32) { + memset (&Buffer->Memory[Offset], 0, Size); + } + + return Offset; +} + +uint32_t +ImageToolBufferAppendReserveAlign ( + image_tool_dynamic_buffer *Buffer, + uint32_t Alignment + ) +{ + assert (IS_POW2 (Alignment)); + + return ImageToolBufferAppendReserve ( + Buffer, + ALIGN_VALUE_ADDEND (ImageToolBufferGetSize (Buffer), Alignment) + ); +} + +void * +ImageToolBufferGetPointer ( + const image_tool_dynamic_buffer *Buffer, + uint32_t Offset + ) +{ + assert (Offset < Buffer->DataSize); + + return &Buffer->Memory[Offset]; +} + +uint32_t +ImageToolBufferGetSize ( + const image_tool_dynamic_buffer *Buffer + ) +{ + return Buffer->DataSize; +} + +void * +ImageToolBufferDump ( + uint32_t *Size, + image_tool_dynamic_buffer *Buffer + ) +{ + void *Data; + uint32_t DataSize; + + if (Buffer->Memory == NULL) { + return NULL; + } + + DataSize = ImageToolBufferGetSize (Buffer); + + Data = AllocateCopyPool (DataSize, Buffer->Memory); + if (Data == NULL) { + return NULL; + } + + *Size = DataSize; + + return Data; +} + +void +ImageToolBufferFree ( + image_tool_dynamic_buffer *Buffer + ) +{ + if (Buffer->Memory != NULL) { + FreePool (Buffer->Memory); + } + + ImageToolBufferInit (Buffer); +} diff --git a/BaseTools/ImageTool/DynamicBuffer.h b/BaseTools/ImageTool/DynamicBuffer.h new file mode 100644 index 0000000000..d71d106d88 --- /dev/null +++ b/BaseTools/ImageTool/DynamicBuffer.h @@ -0,0 +1,74 @@ +#ifndef DYNAMIC_BUFFER_H +#define DYNAMIC_BUFFER_H + +#include + +typedef struct { + uint32_t AllocatedSize; + uint32_t DataSize; + uint8_t *Memory; +} image_tool_dynamic_buffer; + +void +ImageToolBufferInit ( + image_tool_dynamic_buffer *Buffer + ); + +uint32_t +ImageToolBufferAppend ( + image_tool_dynamic_buffer *Buffer, + const void *Data, + uint32_t Size + ); + +uint32_t +ImageToolBufferAppendReserve ( + image_tool_dynamic_buffer *Buffer, + uint32_t Size + ); + +uint32_t +ImageToolBufferAppendReserveAlign ( + image_tool_dynamic_buffer *Buffer, + uint32_t Alignment + ); + +void +ImageToolBufferRead ( + void *Data, + uint32_t Size, + const image_tool_dynamic_buffer *Buffer, + uint32_t Offset + ); + +void +ImageToolBufferWrite ( + image_tool_dynamic_buffer *Buffer, + uint32_t Offset, + const void *Data, + uint32_t Size + ); + +void * +ImageToolBufferGetPointer ( + const image_tool_dynamic_buffer *Buffer, + uint32_t Offset + ); + +uint32_t +ImageToolBufferGetSize ( + const image_tool_dynamic_buffer *Buffer + ); + +void * +ImageToolBufferDump ( + uint32_t *Size, + image_tool_dynamic_buffer *Buffer + ); + +void +ImageToolBufferFree ( + image_tool_dynamic_buffer *Buffer + ); + +#endif // DYNAMIC_BUFFER_H diff --git a/BaseTools/ImageTool/ElfScan.c b/BaseTools/ImageTool/ElfScan.c index 60fd9184b5..102e795143 100644 --- a/BaseTools/ImageTool/ElfScan.c +++ b/BaseTools/ImageTool/ElfScan.c @@ -103,8 +103,6 @@ IsShdrLoadable ( IN const Elf_Shdr *Shdr ) { - assert (Shdr != NULL); - return (Shdr->sh_flags & SHF_ALLOC) != 0; } @@ -360,7 +358,12 @@ SetRelocs ( // break; default: - fprintf (stderr, "ImageTool: Unsupported ELF EM_X86_64 relocation 0x%llx in %s\n", ELF_R_TYPE(Rel->r_info), ImageInfo->DebugInfo.SymbolsPath); + fprintf ( + stderr, + "ImageTool: Unsupported ELF EM_X86_64 relocation 0x%llx in %s\n", + (unsigned long long)ELF_R_TYPE(Rel->r_info), + ImageInfo->DebugInfo.SymbolsPath + ); return RETURN_INCOMPATIBLE_VERSION; } } else if (Ehdr->e_machine == EM_AARCH64) { @@ -402,7 +405,12 @@ SetRelocs ( break; default: - fprintf (stderr, "ImageTool: Unsupported ELF EM_AARCH64 relocation 0x%llx in %s\n", ELF_R_TYPE(Rel->r_info), ImageInfo->DebugInfo.SymbolsPath); + fprintf ( + stderr, + "ImageTool: Unsupported ELF EM_AARCH64 relocation 0x%llx in %s\n", + (unsigned long long)ELF_R_TYPE(Rel->r_info), + ImageInfo->DebugInfo.SymbolsPath + ); return RETURN_INCOMPATIBLE_VERSION; } } @@ -571,7 +579,7 @@ CreateIntermediate ( return RETURN_VOLUME_CORRUPTED; } - Segments = calloc (1, sizeof (*Segments) * ImageInfo->SegmentInfo.NumSegments); + Segments = AllocateZeroPool (sizeof (*Segments) * ImageInfo->SegmentInfo.NumSegments); if (Segments == NULL) { fprintf (stderr, "ImageTool: Could not allocate memory for Segments\n"); return RETURN_OUT_OF_RESOURCES; @@ -580,7 +588,7 @@ CreateIntermediate ( ImageInfo->SegmentInfo.Segments = Segments; if (NumRelocs != 0) { - Relocs = calloc (1, sizeof (*Relocs) * NumRelocs); + Relocs = AllocateZeroPool (sizeof (*Relocs) * NumRelocs); if (Relocs == NULL) { fprintf (stderr, "ImageTool: Could not allocate memory for Relocs\n"); return RETURN_OUT_OF_RESOURCES; @@ -606,7 +614,7 @@ CreateIntermediate ( return RETURN_VOLUME_CORRUPTED; } - Segments[SIndex].Name = calloc (1, strlen (Name) + 1); + Segments[SIndex].Name = AllocateZeroPool (strlen (Name) + 1); if (Segments[SIndex].Name == NULL) { fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Name\n", Index); return RETURN_OUT_OF_RESOURCES; @@ -620,7 +628,7 @@ CreateIntermediate ( Segments[SIndex].Write = (Shdr->sh_flags & SHF_WRITE) != 0; Segments[SIndex].Execute = (Shdr->sh_flags & SHF_EXECINSTR) != 0; - Segments[SIndex].Data = calloc (1, Segments[SIndex].ImageSize); + Segments[SIndex].Data = AllocateZeroPool (Segments[SIndex].ImageSize); if (Segments[SIndex].Data == NULL) { fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Data\n", Index); return RETURN_OUT_OF_RESOURCES; @@ -652,7 +660,6 @@ ScanElf ( const Elf_Ehdr *Ehdr; Elf_Addr BaseAddress; - assert (ImageInfo != NULL); assert (File != NULL || FileSize == 0); Status = ParseElfFile (&Context, File, FileSize); @@ -667,7 +674,6 @@ ScanElf ( ImageInfo->HeaderInfo.BaseAddress = BaseAddress; ImageInfo->HeaderInfo.EntryPointAddress = (uint32_t)(Ehdr->e_entry - BaseAddress); - ImageInfo->HeaderInfo.IsXip = true; ImageInfo->SegmentInfo.SegmentAlignment = (uint32_t)Context.Alignment; ImageInfo->RelocInfo.RelocsStripped = false; @@ -698,11 +704,11 @@ ScanElf ( return RETURN_INCOMPATIBLE_VERSION; } - ImageInfo->DebugInfo.SymbolsPath = malloc (ImageInfo->DebugInfo.SymbolsPathLen + 1); + ImageInfo->DebugInfo.SymbolsPath = AllocatePool (ImageInfo->DebugInfo.SymbolsPathLen + 1); if (ImageInfo->DebugInfo.SymbolsPath == NULL) { fprintf (stderr, "ImageTool: Could not allocate memory for Debug Data\n"); return RETURN_OUT_OF_RESOURCES; - }; + } if (SymbolsPath != NULL) { memmove (ImageInfo->DebugInfo.SymbolsPath, SymbolsPath, ImageInfo->DebugInfo.SymbolsPathLen + 1); diff --git a/BaseTools/ImageTool/GNUmakefile b/BaseTools/ImageTool/GNUmakefile index 3765720da8..2981bc86ac 100644 --- a/BaseTools/ImageTool/GNUmakefile +++ b/BaseTools/ImageTool/GNUmakefile @@ -10,7 +10,7 @@ OBJS = $(PROJECT).o OBJS += Image.o UefiImageScan.o PeEmit32.o PeEmit64.o PeEmitCommon.o PeScan.o ElfScan32.o ElfScan64.o ElfScanCommon.o BinEmit.o ImageToolEmit.o OBJS += UefiImageExtraActionLib.o OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o PeCoffHash.o -OBJS += PeSupport.o UefiImageLib.o CommonSupport.o +OBJS += PeSupport.o UefiImageLib.o CommonSupport.o DynamicBuffer.o WERROR = 1 DEBUG = 1 diff --git a/BaseTools/ImageTool/Image.c b/BaseTools/ImageTool/Image.c index 699bd89242..68c913f988 100644 --- a/BaseTools/ImageTool/Image.c +++ b/BaseTools/ImageTool/Image.c @@ -16,22 +16,18 @@ CheckToolImageSegment ( { bool Overflow; - assert (Segment != NULL); - assert (PreviousEndAddress != NULL); - if (!IS_ALIGNED (Segment->ImageSize, SegmentInfo->SegmentAlignment)) { - raise (); + DEBUG_RAISE (); return false; } if (Segment->Write && Segment->Execute) { - raise (); + DEBUG_RAISE (); return false; } - // FIXME: Expand prior segment if (Segment->ImageAddress != *PreviousEndAddress) { - raise (); + DEBUG_RAISE (); return false; } @@ -41,7 +37,7 @@ CheckToolImageSegment ( PreviousEndAddress ); if (Overflow) { - raise (); + DEBUG_RAISE (); return false; } @@ -58,21 +54,18 @@ CheckToolImageSegmentInfo ( uint32_t Index; bool Result; - assert (SegmentInfo != NULL); - assert (ImageSize != NULL); - if (!IS_POW2 (SegmentInfo->SegmentAlignment)) { - raise (); + DEBUG_RAISE (); return false; } if (SegmentInfo->NumSegments == 0) { - raise (); + DEBUG_RAISE (); return false; } if (!IS_ALIGNED (SegmentInfo->Segments[0].ImageAddress, SegmentInfo->SegmentAlignment)) { - raise (); + DEBUG_RAISE (); return false; } @@ -84,7 +77,7 @@ CheckToolImageSegmentInfo ( ImageSize ); if (!Result) { - raise (); + DEBUG_RAISE (); return false; } } @@ -93,6 +86,32 @@ CheckToolImageSegmentInfo ( } static +bool +CheckToolImageHeaderInfo ( + const image_tool_header_info_t *HeaderInfo, + const image_tool_segment_info_t *SegmentInfo, + uint32_t ImageSize + ) +{ + if (SegmentInfo->Segments[0].ImageAddress > HeaderInfo->EntryPointAddress || + HeaderInfo->EntryPointAddress > ImageSize) { + DEBUG_RAISE (); + return false; + } + + if (!IS_ALIGNED (HeaderInfo->BaseAddress, SegmentInfo->SegmentAlignment)) { + DEBUG_RAISE (); + return false; + } + + if (HeaderInfo->BaseAddress + ImageSize < HeaderInfo->BaseAddress) { + DEBUG_RAISE (); + return false; + } + + return true; +} + const image_tool_segment_t * ImageGetSegmentByAddress ( uint32_t *Address, @@ -102,9 +121,6 @@ ImageGetSegmentByAddress ( { uint32_t Index; - assert (Address != NULL); - assert (SegmentInfo != NULL); - for (Index = 0; Index < SegmentInfo->NumSegments; ++Index) { if ((SegmentInfo->Segments[Index].ImageAddress <= *Address) && (*Address < SegmentInfo->Segments[Index].ImageAddress + SegmentInfo->Segments[Index].ImageSize)) { @@ -117,22 +133,52 @@ ImageGetSegmentByAddress ( return NULL; } +uint8_t +ToolImageGetRelocSize ( + uint8_t Type + ) +{ + switch (Type) { + case EFI_IMAGE_REL_BASED_HIGHLOW: + { + return sizeof (UINT32); + } + + case EFI_IMAGE_REL_BASED_DIR64: + { + return sizeof (UINT64); + } + +#if 0 + case EFI_IMAGE_REL_BASED_ARM_MOV32T: + { + return sizeof (UINT32); + } +#endif + + default: + { + return 0; + } + } +} + static bool CheckToolImageReloc ( const image_tool_image_info_t *Image, - uint32_t ImageSize, - const image_tool_reloc_t *Reloc + const image_tool_reloc_t *Reloc, + uint8_t RelocSize ) { uint32_t RelocOffset; uint32_t RemainingSize; const image_tool_segment_t *Segment; + +#if 0 uint16_t MovHigh; uint16_t MovLow; - - assert (Image != NULL); - assert (Reloc != NULL); +#endif RelocOffset = Reloc->Target; Segment = ImageGetSegmentByAddress ( @@ -141,64 +187,40 @@ CheckToolImageReloc ( &Image->SegmentInfo ); if (Segment == NULL) { - raise (); + DEBUG_RAISE (); return false; } - switch (Reloc->Type) { - case EFI_IMAGE_REL_BASED_HIGHLOW: - { - if (RemainingSize < sizeof (UINT32)) { - raise (); - return false; - } - - break; - } - - case EFI_IMAGE_REL_BASED_DIR64: - { - if (RemainingSize < sizeof (UINT64)) { - raise (); - return false; - } - - break; - } - - case EFI_IMAGE_REL_BASED_ARM_MOV32T: - { - if (RemainingSize < sizeof (UINT32)) { - raise (); - return false; - } - - if (!IS_ALIGNED (Reloc->Target, ALIGNOF (UINT16))) { - raise (); - return false; - } - - MovHigh = *(const uint16_t *)&Segment->Data[RelocOffset]; - MovLow = *(const uint16_t *)&Segment->Data[RelocOffset + 2]; - if (((MovHigh & 0xFBF0U) != 0xF200U && (MovHigh & 0xFBF0U) != 0xF2C0U) || - (MovLow & 0x8000U) != 0) { - raise (); - return false; - } + if (RelocSize > RemainingSize) { + DEBUG_RAISE (); + return false; + } - break; +#if 0 + if (Reloc->Type == EFI_IMAGE_REL_BASED_ARM_MOV32T) { + if (!IS_ALIGNED (Reloc->Target, ALIGNOF (UINT16))) { + DEBUG_RAISE (); + return false; } - default: - { - raise (); + MovHigh = *(const uint16_t *)&Segment->Data[RelocOffset]; + MovLow = *(const uint16_t *)&Segment->Data[RelocOffset + 2]; + if (((MovHigh & 0xFBF0U) != 0xF200U && (MovHigh & 0xFBF0U) != 0xF2C0U) || + (MovLow & 0x8000U) != 0) { + DEBUG_RAISE (); return false; } } +#endif - /*if (Segment->Write) { + // FIXME: Update drivers? + if ((Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER || + Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) && + Segment->Write) { printf("!!! writable reloc at %x !!!\n", Reloc->Target); - }*/ + //DEBUG_RAISE (); + //return false; + } return true; } @@ -206,49 +228,52 @@ CheckToolImageReloc ( static bool CheckToolImageRelocInfo ( - const image_tool_image_info_t *Image, - uint32_t ImageSize + const image_tool_image_info_t *Image ) { const image_tool_reloc_info_t *RelocInfo; + uint8_t RelocSize; + uint32_t MinRelocTarget; uint32_t Index; bool Result; - assert (Image != NULL); - RelocInfo = &Image->RelocInfo; if (RelocInfo->NumRelocs == 0) { return true; } - if (RelocInfo->RelocsStripped && (RelocInfo->NumRelocs > 0)) { - raise (); + if (RelocInfo->RelocsStripped) { + DEBUG_RAISE (); return false; } if (RelocInfo->NumRelocs > (MAX_UINT32 / sizeof (UINT16))) { - raise (); + DEBUG_RAISE (); return false; } - Result = CheckToolImageReloc (Image, ImageSize, &RelocInfo->Relocs[0]); - if (!Result) { - raise (); - return false; - } + MinRelocTarget = 0; + + for (Index = 0; Index < RelocInfo->NumRelocs; ++Index) { + if (RelocInfo->Relocs[Index].Target < MinRelocTarget) { + DEBUG_RAISE (); + return false; + } - for (Index = 1; Index < RelocInfo->NumRelocs; ++Index) { - if (RelocInfo->Relocs[Index].Target < RelocInfo->Relocs[Index - 1].Target) { - assert (false); + RelocSize = ToolImageGetRelocSize (RelocInfo->Relocs[Index].Type); + if (RelocSize == 0) { + DEBUG_RAISE (); return false; } - Result = CheckToolImageReloc (Image, ImageSize, &RelocInfo->Relocs[Index]); + Result = CheckToolImageReloc (Image, &RelocInfo->Relocs[Index], RelocSize); if (!Result) { - raise (); + DEBUG_RAISE (); return false; } + + MinRelocTarget = RelocInfo->Relocs[Index].Target + RelocSize; } return true; @@ -260,14 +285,9 @@ CheckToolImageDebugInfo ( const image_tool_debug_info_t *DebugInfo ) { - assert (DebugInfo != NULL); - - if (DebugInfo->SymbolsPath != NULL) { - // FIXME: UE-only? - if (DebugInfo->SymbolsPathLen > MAX_UINT8) { - raise (); - return false; - } + if (DebugInfo->SymbolsPathLen > MAX_UINT8) { + DEBUG_RAISE (); + return false; } return true; @@ -281,23 +301,31 @@ CheckToolImage ( bool Result; uint32_t ImageSize; - assert (Image != NULL); - Result = CheckToolImageSegmentInfo (&Image->SegmentInfo, &ImageSize); if (!Result) { - raise (); + DEBUG_RAISE (); return false; } - Result = CheckToolImageRelocInfo (Image, ImageSize); + Result = CheckToolImageHeaderInfo ( + &Image->HeaderInfo, + &Image->SegmentInfo, + ImageSize + ); if (!Result) { - raise (); + DEBUG_RAISE (); + return false; + } + + Result = CheckToolImageRelocInfo (Image); + if (!Result) { + DEBUG_RAISE (); return false; } Result = CheckToolImageDebugInfo (&Image->DebugInfo); if (!Result) { - raise (); + DEBUG_RAISE (); return false; } @@ -316,10 +344,6 @@ ImageInitUnpaddedSize ( Segment = &Image->SegmentInfo.Segments[Index]; Segment->UnpaddedSize = Segment->ImageSize; - if (Image->HeaderInfo.IsXip) { - continue; - } - for (; Segment->UnpaddedSize > 0; --Segment->UnpaddedSize) { if (Segment->Data[Segment->UnpaddedSize - 1] != 0) { break; @@ -335,20 +359,33 @@ ToolImageDestruct ( { uint8_t Index; - assert (Image != NULL); - if (Image->SegmentInfo.Segments != NULL) { for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { - free (Image->SegmentInfo.Segments[Index].Name); - free (Image->SegmentInfo.Segments[Index].Data); + if (Image->SegmentInfo.Segments[Index].Name != NULL) { + FreePool (Image->SegmentInfo.Segments[Index].Name); + } + + if (Image->SegmentInfo.Segments[Index].Data != NULL) { + FreePool (Image->SegmentInfo.Segments[Index].Data); + } } - free (Image->SegmentInfo.Segments); + if (Image->SegmentInfo.Segments != NULL) { + FreePool (Image->SegmentInfo.Segments); + } } - free (Image->HiiInfo.Data); - free (Image->RelocInfo.Relocs); - free (Image->DebugInfo.SymbolsPath); + if (Image->HiiInfo.Data != NULL) { + FreePool (Image->HiiInfo.Data); + } + + if (Image->RelocInfo.Relocs != NULL) { + FreePool (Image->RelocInfo.Relocs); + } + + if (Image->DebugInfo.SymbolsPath != NULL) { + FreePool (Image->DebugInfo.SymbolsPath); + } memset (Image, 0, sizeof (*Image)); } @@ -356,9 +393,12 @@ ToolImageDestruct ( bool ToolImageRelocate ( image_tool_image_info_t *Image, - uint64_t BaseAddress + uint64_t BaseAddress, + uint32_t IgnorePrefix ) { + const image_tool_segment_t *LastSegment; + uint32_t ImageSize; uint64_t Adjust; const image_tool_reloc_t *Reloc; uint32_t RelocOffset; @@ -368,10 +408,28 @@ ToolImageRelocate ( uint32_t RelocTarget32; uint64_t RelocTarget64; + if (!IS_ALIGNED (BaseAddress, Image->SegmentInfo.SegmentAlignment)) { + DEBUG_RAISE (); + return false; + } + Adjust = BaseAddress - Image->HeaderInfo.BaseAddress; if (Adjust == 0) { - return TRUE; + return true; + } + + LastSegment = &Image->SegmentInfo.Segments[Image->SegmentInfo.NumSegments - 1]; + ImageSize = LastSegment->ImageAddress + LastSegment->ImageSize; + + // + // When removing the image header prefix, BaseAddress + ImageSize may indeed + // overflow. The important part is that the address starting from the first + // image segment does not. + // + if (BaseAddress + ImageSize < BaseAddress + IgnorePrefix) { + DEBUG_RAISE (); + return false; } for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) { @@ -383,10 +441,7 @@ ToolImageRelocate ( &RemainingSize, &Image->SegmentInfo ); - if (Segment == NULL) { - raise (); - return false; - } + assert (Segment != NULL); switch (Reloc->Type) { case EFI_IMAGE_REL_BASED_HIGHLOW: @@ -409,6 +464,7 @@ ToolImageRelocate ( break; } +#if 0 case EFI_IMAGE_REL_BASED_ARM_MOV32T: { assert (RemainingSize >= sizeof (UINT32)); @@ -417,10 +473,11 @@ ToolImageRelocate ( PeCoffThumbMovwMovtImmediateFixup (&Segment->Data[RelocOffset], Adjust); break; } +#endif default: { - raise (); + assert (false); return false; } } @@ -494,7 +551,7 @@ ToolImageCompare ( sizeof (Image1->HeaderInfo) ); if (CmpResult != 0) { - raise (); + DEBUG_RAISE (); return false; } @@ -510,7 +567,7 @@ ToolImageCompare ( OFFSET_OF (image_tool_segment_info_t, Segments) ); if (CmpResult != 0) { - raise (); + DEBUG_RAISE (); return false; } @@ -521,7 +578,7 @@ ToolImageCompare ( OFFSET_OF (image_tool_segment_t, Name) ); if (CmpResult != 0) { - raise (); + DEBUG_RAISE (); return false; } @@ -538,20 +595,22 @@ ToolImageCompare ( ++NameIndex ) { if (Name1[NameIndex] != Name2[NameIndex]) { - raise (); + DEBUG_RAISE (); return false; } } } - CmpResult = memcmp ( - Image1->SegmentInfo.Segments[SegIndex].Data, - Image2->SegmentInfo.Segments[SegIndex].Data, - Image1->SegmentInfo.Segments[SegIndex].ImageSize - ); - if (CmpResult != 0) { - raise (); - return false; + if (Image1->SegmentInfo.Segments[SegIndex].ImageSize != 0) { + CmpResult = memcmp ( + Image1->SegmentInfo.Segments[SegIndex].Data, + Image2->SegmentInfo.Segments[SegIndex].Data, + Image1->SegmentInfo.Segments[SegIndex].ImageSize + ); + if (CmpResult != 0) { + DEBUG_RAISE (); + return false; + } } } @@ -565,18 +624,20 @@ ToolImageCompare ( OFFSET_OF (image_tool_reloc_info_t, Relocs) ); if (CmpResult != 0) { - raise (); + DEBUG_RAISE (); return false; } - CmpResult = memcmp ( - Image1->RelocInfo.Relocs, - Image2->RelocInfo.Relocs, - Image1->RelocInfo.NumRelocs * sizeof (*Image1->RelocInfo.Relocs) - ); - if (CmpResult != 0) { - raise (); - return false; + if (Image1->RelocInfo.NumRelocs != 0) { + CmpResult = memcmp ( + Image1->RelocInfo.Relocs, + Image2->RelocInfo.Relocs, + Image1->RelocInfo.NumRelocs * sizeof (*Image1->RelocInfo.Relocs) + ); + if (CmpResult != 0) { + DEBUG_RAISE (); + return false; + } } // @@ -589,18 +650,20 @@ ToolImageCompare ( OFFSET_OF (image_tool_hii_info_t, Data) ); if (CmpResult != 0) { - raise (); + DEBUG_RAISE (); return false; } - CmpResult = memcmp ( - Image1->HiiInfo.Data, - Image2->HiiInfo.Data, - Image1->HiiInfo.DataSize - ); - if (CmpResult != 0) { - raise (); - return false; + if (Image1->HiiInfo.DataSize != 0) { + CmpResult = memcmp ( + Image1->HiiInfo.Data, + Image2->HiiInfo.Data, + Image1->HiiInfo.DataSize + ); + if (CmpResult != 0) { + DEBUG_RAISE (); + return false; + } } // @@ -613,12 +676,12 @@ ToolImageCompare ( OFFSET_OF (image_tool_debug_info_t, SymbolsPath) ); if (CmpResult != 0) { - raise (); + DEBUG_RAISE (); return false; } if ((Image1->DebugInfo.SymbolsPath != NULL) != (Image2->DebugInfo.SymbolsPath != NULL)) { - raise (); + DEBUG_RAISE (); return false; } @@ -628,7 +691,7 @@ ToolImageCompare ( Image2->DebugInfo.SymbolsPath ); if (CmpResult != 0) { - raise (); + DEBUG_RAISE (); return false; } } @@ -642,7 +705,11 @@ ToolImageStripRelocs ( ) { Image->RelocInfo.NumRelocs = 0; - free (Image->RelocInfo.Relocs); + + if (Image->RelocInfo.Relocs != NULL) { + FreePool (Image->RelocInfo.Relocs); + } + Image->RelocInfo.Relocs = NULL; Image->RelocInfo.RelocsStripped = TRUE; diff --git a/BaseTools/ImageTool/ImageTool.c b/BaseTools/ImageTool/ImageTool.c index 4a39ab3cab..a93192945d 100644 --- a/BaseTools/ImageTool/ImageTool.c +++ b/BaseTools/ImageTool/ImageTool.c @@ -37,10 +37,6 @@ HiiSrc ( FILE *FilePtr; UINT32 Index; - assert (FileNames != NULL); - assert (HiiName != NULL); - assert (Guid != NULL); - Status = AsciiStrToGuid (Guid, &HiiGuid); if (RETURN_ERROR (Status)) { fprintf (stderr, "ImageTool: Invalid GUID - %s\n", Guid); @@ -55,7 +51,7 @@ HiiSrc ( FilePtr = fopen (HiiName, "w"); if (FilePtr == NULL) { - free (Hii); + FreePool (Hii); return RETURN_NO_MEDIA; } @@ -113,7 +109,8 @@ HiiSrc ( " (CONST MODULE_HII_PACKAGE_LIST *)&mModuleHiiPackageList;\n" ); - free (Hii); + fclose (FilePtr); + FreePool (Hii); return RETURN_SUCCESS; } @@ -247,9 +244,6 @@ GetAcpi ( UINT16 Index; UINT32 FileLength; - assert (PeName != NULL); - assert (AcpiName != NULL); - Pe = UserReadFile (PeName, &PeSize); if (Pe == NULL) { fprintf (stderr, "ImageTool: Could not open %s: %s\n", PeName, strerror (errno)); @@ -353,9 +347,11 @@ RETURN_STATUS GenExecutable ( IN const char *OutputFileName, IN const char *InputFileName, + IN const char *SymbolsPath OPTIONAL, IN const char *FormatName, IN const char *TypeName, IN const char *BaseAddress, + IN bool Xip, IN bool Strip, IN bool FixedAddress ) @@ -402,6 +398,10 @@ GenExecutable ( return RETURN_ABORTED; } + if (SymbolsPath == NULL) { + SymbolsPath = InputFileName; + } + OutputFile = ToolImageEmit ( &OutputFileSize, InputFile, @@ -410,18 +410,20 @@ GenExecutable ( Type, BaseAddress != NULL, NewBaseAddress, - InputFileName, + SymbolsPath, + Xip, Strip, FixedAddress ); if (OutputFile == NULL) { + DEBUG_RAISE (); return RETURN_ABORTED; } UserWriteFile (OutputFileName, OutputFile, OutputFileSize); - free (OutputFile); + FreePool (OutputFile); return RETURN_SUCCESS; } @@ -432,16 +434,18 @@ int main (int argc, const char *argv[]) UINT32 NumOfFiles; const char *OutputName; const char *InputName; + const char *SymbolsPath; const char *FormatName; const char *TypeName; const char *BaseAddress; + bool Xip; bool Strip; bool FixedAddress; int ArgIndex; if (argc < 2) { fprintf (stderr, "ImageTool: No command is specified\n"); - raise (); + DEBUG_RAISE (); return -1; } // @@ -452,16 +456,18 @@ int main (int argc, const char *argv[]) if (strcmp (argv[1], "GenImage") == 0) { if (argc < 5) { fprintf (stderr, "ImageTool: Command arguments are missing\n"); - fprintf (stderr, " Usage: ImageTool GenImage [-c Format] [-t ModuleType] [-b BaseAddress] [-s] [-f] -o OutputFile InputFile\n"); - raise (); + fprintf (stderr, " Usage: ImageTool GenImage [-c Format] [-t ModuleType] [-b BaseAddress] [-d SymbolsPath] [-x] [-s] [-f] -o OutputFile InputFile\n"); + DEBUG_RAISE (); return -1; } OutputName = NULL; InputName = NULL; + SymbolsPath = NULL; FormatName = NULL; TypeName = NULL; BaseAddress = NULL; + Xip = false; Strip = false; FixedAddress = false; for (ArgIndex = 2; ArgIndex < argc; ++ArgIndex) { @@ -497,6 +503,16 @@ int main (int argc, const char *argv[]) } BaseAddress = argv[ArgIndex]; + } else if (strcmp (argv[ArgIndex], "-d") == 0) { + ++ArgIndex; + if (ArgIndex == argc) { + fprintf (stderr, "Must specify an argument to -d\n"); + return -1; + } + + SymbolsPath = argv[ArgIndex]; + } else if (strcmp (argv[ArgIndex], "-x") == 0) { + Xip = true; } else if (strcmp (argv[ArgIndex], "-s") == 0) { Strip = true; } else if (strcmp (argv[ArgIndex], "-f") == 0) { @@ -524,21 +540,23 @@ int main (int argc, const char *argv[]) Status = GenExecutable ( OutputName, InputName, + SymbolsPath, FormatName, TypeName, BaseAddress, + Xip, Strip, FixedAddress ); if (RETURN_ERROR (Status)) { - raise (); + DEBUG_RAISE (); return -1; } } else if (strcmp (argv[1], "HiiSrc") == 0) { if (argc < 5 || strcmp (argv[3], "-o") != 0) { fprintf (stderr, "ImageTool: Command arguments are missing\n"); fprintf (stderr, " Usage: ImageTool HiiBin GUID -o OutputFile InputFile1 InputFile2 ...\n"); - raise (); + DEBUG_RAISE (); return -1; } @@ -546,20 +564,20 @@ int main (int argc, const char *argv[]) Status = HiiSrc (argv[4], argv[2], &argv[5], NumOfFiles); if (RETURN_ERROR (Status)) { - raise (); + DEBUG_RAISE (); return -1; } } else if (strcmp (argv[1], "GetAcpi") == 0) { if (argc != 5 || strcmp (argv[2], "-o") != 0) { fprintf (stderr, "ImageTool: Command arguments are missing\n"); fprintf (stderr, " Usage: ImageTool GetAcpi -o OutputFile InputFile\n"); - raise (); + DEBUG_RAISE (); return -1; } Status = GetAcpi (argv[4], argv[3]); if (RETURN_ERROR (Status)) { - raise (); + DEBUG_RAISE (); return -1; } } diff --git a/BaseTools/ImageTool/ImageTool.h b/BaseTools/ImageTool/ImageTool.h index 048579a315..a0382d79d8 100644 --- a/BaseTools/ImageTool/ImageTool.h +++ b/BaseTools/ImageTool/ImageTool.h @@ -18,19 +18,12 @@ #include #include #include +#include #include #include #define MAX_PE_ALIGNMENT 0x10000 -#define raise() assert(false) - -typedef struct { - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY Dir; - EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY Nb10; - char Name[]; -} DebugData; - #define PAGE(x) ((x) & ~4095U) #define PAGE_OFF(x) ((x) & 4095U) @@ -39,9 +32,8 @@ typedef struct { uint32_t EntryPointAddress; uint16_t Machine; uint16_t Subsystem; - uint8_t IsXip; uint8_t FixedAddress; - uint8_t Reserved[6]; + uint8_t Reserved[7]; } image_tool_header_info_t; typedef struct { @@ -60,7 +52,8 @@ typedef struct { typedef struct { uint32_t SegmentAlignment; - uint32_t NumSegments; + uint16_t NumSegments; + uint8_t Reserved[2]; image_tool_segment_t *Segments; } image_tool_segment_info_t; @@ -117,7 +110,8 @@ ImageInitUnpaddedSize ( bool ToolImageRelocate ( image_tool_image_info_t *Image, - uint64_t BaseAddress + uint64_t BaseAddress, + uint32_t IgnorePrefix ); void @@ -136,6 +130,11 @@ ToolImageStripRelocs ( image_tool_image_info_t *Image ); +uint8_t +ToolImageGetRelocSize ( + uint8_t Type + ); + RETURN_STATUS ToolContextConstructUefiImage ( OUT image_tool_image_info_t *Image, @@ -153,6 +152,7 @@ void * ToolImageEmitPe ( image_tool_image_info_t *Image, uint32_t *FileSize, + bool Xip, bool Strip ); @@ -182,4 +182,11 @@ ConstructHii ( OUT UINT32 *HiiSize ); +const image_tool_segment_t * +ImageGetSegmentByAddress ( + uint32_t *Address, + uint32_t *RemainingSize, + const image_tool_segment_info_t *SegmentInfo + ); + #endif // IMAGE_TOOL_H diff --git a/BaseTools/ImageTool/ImageToolEmit.c b/BaseTools/ImageTool/ImageToolEmit.c index 043e949dc2..b874843532 100644 --- a/BaseTools/ImageTool/ImageToolEmit.c +++ b/BaseTools/ImageTool/ImageToolEmit.c @@ -33,9 +33,11 @@ ToolContextConstruct ( File, FileSize ); +#ifndef IMAGE_TOOL_DISABLE_ELF if (Status == RETURN_UNSUPPORTED) { Status = ScanElf (ImageInfo, File, FileSize, SymbolsPath); } +#endif return Status; } @@ -61,13 +63,13 @@ ValidateOutputFile ( NULL ); if (EFI_ERROR (Status)) { - assert (false); + assert (Status == RETURN_OUT_OF_RESOURCES); return Status; } Result = CheckToolImage (&OutputImageInfo); if (!Result) { - raise (); + assert (false); ToolImageDestruct (&OutputImageInfo); return RETURN_UNSUPPORTED; } @@ -94,6 +96,7 @@ ToolImageEmit ( IN bool Relocate, IN uint64_t BaseAddress, IN const char *SymbolsPath OPTIONAL, + IN bool Xip, IN bool Strip, IN bool FixedAddress ) @@ -138,12 +141,13 @@ ToolImageEmit ( Success = CheckToolImage (&ImageInfo); if (!Success) { + DEBUG_RAISE (); ToolImageDestruct (&ImageInfo); return NULL; } if (Relocate) { - Success = ToolImageRelocate (&ImageInfo, BaseAddress); + Success = ToolImageRelocate (&ImageInfo, BaseAddress, 0); if (!Success) { fprintf (stderr, "ImageTool: Failed to relocate input file %s\n", SymbolsPath); ToolImageDestruct (&ImageInfo); @@ -157,17 +161,24 @@ ToolImageEmit ( OutputFile = NULL; if (Format == UefiImageFormatPe) { - OutputFile = ToolImageEmitPe (&ImageInfo, OutputFileSize, Strip); + OutputFile = ToolImageEmitPe (&ImageInfo, OutputFileSize, Xip, Strip); } else { assert (false); } + if (OutputFile == NULL) { + DEBUG_RAISE (); + ToolImageDestruct (&ImageInfo); + return NULL; + } + Status = ValidateOutputFile (OutputFile, *OutputFileSize, &ImageInfo); ToolImageDestruct (&ImageInfo); if (EFI_ERROR (Status)) { - assert (false); + assert (Status == RETURN_OUT_OF_RESOURCES); + FreePool (OutputFile); return NULL; } diff --git a/BaseTools/ImageTool/ImageToolEmit.h b/BaseTools/ImageTool/ImageToolEmit.h index ae803fcd3a..f83c4a6a7a 100644 --- a/BaseTools/ImageTool/ImageToolEmit.h +++ b/BaseTools/ImageTool/ImageToolEmit.h @@ -20,6 +20,7 @@ ToolImageEmit ( IN bool Relocate, IN uint64_t BaseAddress, IN const char *SymbolsPath OPTIONAL, + IN bool Xip, IN bool Strip, IN bool FixedAddress ); diff --git a/BaseTools/ImageTool/Makefile b/BaseTools/ImageTool/Makefile index a6a0b6a48c..3e91a6ecae 100644 --- a/BaseTools/ImageTool/Makefile +++ b/BaseTools/ImageTool/Makefile @@ -20,7 +20,7 @@ PE = $(UDK_PATH)\MdePkg\Library\BasePeCoffLib2 UA = $(UDK_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull OBJECTS = ImageTool.obj Image.obj PeEmit32.obj PeEmit64.obj PeEmitCommon.obj UefiImageScan.obj PeScan.obj ElfScan32.obj ElfScan64.obj ElfScanCommon.obj BinEmit.obj ImageToolEmit.obj -OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UA)}UefiImageExtraActionLib.obj +OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UA)}UefiImageExtraActionLib.obj DynamicBuffer.obj OBJECTS = $(OBJECTS) {$(PE)}PeCoffInit.obj PeCoffInfo.obj PeCoffRelocate.obj PeCoffLoad.obj PeCoffHii.obj PeCoffDebug.obj PeCoffHash.obj BASE = $(UDK_PATH)\MdePkg\Library\BaseLib diff --git a/BaseTools/ImageTool/PeEmit.c b/BaseTools/ImageTool/PeEmit.c index ef4ffb30df..910d5125a7 100644 --- a/BaseTools/ImageTool/PeEmit.c +++ b/BaseTools/ImageTool/PeEmit.c @@ -6,14 +6,19 @@ #include "ImageTool.h" +#include "DynamicBuffer.h" +#include "PeEmitCommon.h" + #if PE_ARCH == 32 -#define EFI_IMAGE_NT_HEADERS EFI_IMAGE_NT_HEADERS32 +typedef UINT32 EFI_IMAGE_NT_BASE_ADDRESS; +typedef EFI_IMAGE_NT_HEADERS32 EFI_IMAGE_NT_HEADERS; #define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC #elif PE_ARCH == 64 -#define EFI_IMAGE_NT_HEADERS EFI_IMAGE_NT_HEADERS64 +typedef UINT64 EFI_IMAGE_NT_BASE_ADDRESS; +typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS; #define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC #endif @@ -23,878 +28,615 @@ #define PE_SUFFIX(Name) PE_SUFFIX_ (Name, PE_ARCH) typedef struct { - uint8_t NumExtraSections; - uint32_t SizeOfHeaders; - uint8_t NumberOfRvaAndSizes; - uint16_t SizeOfOptionalHeader; - uint32_t SectionHeadersSize; - uint32_t ExtraSectionHeadersSize; -} image_tool_emit_pe_hdr_info_t; - -typedef struct { - const image_tool_image_info_t *Image; - EFI_IMAGE_NT_HEADERS *PeHdr; - image_tool_emit_pe_hdr_info_t HdrInfo; - uint32_t SectionsSize; - uint32_t HiiSectionAddress; - uint32_t ExtraSectionsSize; - uint32_t UnsignedFileSize; - uint32_t RelocTableSize; - uint32_t DebugTableSize; - uint32_t FileAlignment; -} image_tool_pe_emit_context_t; - -#define EmitPeGetHeaderSizes PE_SUFFIX (EmitPeGetHeaderSizes) -static -bool -EmitPeGetHeaderSizes ( - const image_tool_image_info_t *Image, - image_tool_emit_pe_hdr_info_t *HdrInfo - ) -{ - assert (Image != NULL); - assert (HdrInfo != NULL); - - if (Image->RelocInfo.NumRelocs > 0) { - HdrInfo->ExtraSectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER); - } - - if (Image->HiiInfo.DataSize > 0) { - HdrInfo->ExtraSectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER); - } - - if (Image->DebugInfo.SymbolsPath != NULL) { - HdrInfo->ExtraSectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER); - } - - HdrInfo->SectionHeadersSize = (uint32_t)Image->SegmentInfo.NumSegments * sizeof (EFI_IMAGE_SECTION_HEADER); - HdrInfo->NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES; - HdrInfo->SizeOfOptionalHeader = sizeof (EFI_IMAGE_NT_HEADERS) - sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR) - + HdrInfo->NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY); - HdrInfo->SizeOfHeaders = sizeof (EFI_IMAGE_DOS_HEADER) + sizeof (EFI_IMAGE_NT_HEADERS) - + HdrInfo->NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY) - + HdrInfo->SectionHeadersSize + HdrInfo->ExtraSectionHeadersSize; - - return true; -} - -#define EmitPeGetSectionsSize PE_SUFFIX (EmitPeGetSectionsSize) -static -bool -EmitPeGetSectionsSize ( - const image_tool_pe_emit_context_t *Context, - uint32_t *SectionsSize - ) -{ - const image_tool_image_info_t *Image; - uint8_t Index; - uint32_t DataSize; - bool Overflow; - - assert (Context != NULL); - assert (SectionsSize != NULL); - - Image = Context->Image; - *SectionsSize = 0; - - for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { - Overflow = BaseOverflowAlignUpU32 ( - Image->SegmentInfo.Segments[Index].UnpaddedSize, - Context->FileAlignment, - &DataSize - ); - if (Overflow) { - raise (); - return false; - } + EFI_IMAGE_DEBUG_DIRECTORY_ENTRY Dir; + EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY Nb10; +} image_tool_debug_dir_t; - Overflow = BaseOverflowAddU32 (*SectionsSize, DataSize, SectionsSize); - if (Overflow) { - raise (); - return false; - } - } +#define SIZE_OF_DATA_DIRECRORY \ + EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES * sizeof (EFI_IMAGE_DATA_DIRECTORY) - return true; -} +#define SIZE_OF_OPTIONAL_HEADER \ + sizeof (EFI_IMAGE_NT_HEADERS) - sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR) \ + + SIZE_OF_DATA_DIRECRORY -#define EmitPeGetRelocSectionSize PE_SUFFIX (EmitPeGetRelocSectionSize) static bool -EmitPeGetRelocSectionSize ( - const image_tool_image_info_t *Image, - uint32_t *RelocsSize - ) -{ - uint32_t RelocTableSize; - uint32_t BlockAddress; - uint32_t BlockSize; - uint32_t Index; - uint32_t RelocAddress; - - assert (Image != NULL); - assert (RelocsSize != NULL); - - if (Image->RelocInfo.NumRelocs == 0) { - *RelocsSize = 0; - return true; - } - - assert (Image->RelocInfo.NumRelocs <= MAX_UINT32); - - RelocTableSize = 0; - BlockAddress = PAGE(Image->RelocInfo.Relocs[0].Target); - BlockSize = sizeof (EFI_IMAGE_BASE_RELOCATION_BLOCK); - - for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) { - RelocAddress = PAGE(Image->RelocInfo.Relocs[Index].Target); - if (RelocAddress != BlockAddress) { - BlockSize = ALIGN_VALUE (BlockSize, 4); - - RelocTableSize += BlockSize; - - BlockAddress = RelocAddress; - BlockSize = sizeof (EFI_IMAGE_BASE_RELOCATION_BLOCK); - } - - BlockSize += sizeof (UINT16); - } - - BlockSize = ALIGN_VALUE (BlockSize, 4); - RelocTableSize += BlockSize; - - *RelocsSize = RelocTableSize; - - return true; -} - -#define EmitPeGetDebugSectionSize PE_SUFFIX (EmitPeGetDebugSectionSize) -static -void -EmitPeGetDebugSectionSize ( - const image_tool_image_info_t *Image, - uint32_t *DebugSize +InternalFinalizeExtraSection ( + image_tool_dynamic_buffer *Buffer, + EFI_IMAGE_NT_HEADERS *PeHdr, + EFI_IMAGE_SECTION_HEADER *SectionHeader, + const char *Name, + uint32_t Size, + uint32_t Offset ) { - uint32_t Size; + uint32_t BufferOffset; - assert (Image != NULL); - assert (DebugSize != NULL); - - Size = 0; - if (Image->DebugInfo.SymbolsPath != NULL) { - Size = sizeof (DebugData) + Image->DebugInfo.SymbolsPathLen + 1; - } + assert (Size == ImageToolBufferGetSize (Buffer) - Offset); - *DebugSize = Size; + strncpy ( + (char *)SectionHeader->Name, + Name, + sizeof (SectionHeader->Name) + ); + SectionHeader->Name[ARRAY_SIZE (SectionHeader->Name) - 1] = 0; + + SectionHeader->VirtualSize = ALIGN_VALUE (Size, PeHdr->SectionAlignment); + SectionHeader->VirtualAddress = PeHdr->SizeOfImage; + SectionHeader->SizeOfRawData = ALIGN_VALUE (Size, PeHdr->FileAlignment); + SectionHeader->PointerToRawData = Offset; + SectionHeader->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_READ; + + PeHdr->SizeOfInitializedData += SectionHeader->VirtualSize; + PeHdr->SizeOfImage += SectionHeader->VirtualSize; + + BufferOffset = ImageToolBufferAppendReserve ( + Buffer, + SectionHeader->SizeOfRawData - Size + ); + return BufferOffset != MAX_UINT32; } -#define EmitPeGetExtraSectionsSize PE_SUFFIX (EmitPeGetExtraSectionsSize) +#define ToolImageEmitPeHiiTable PE_SUFFIX (ToolImageEmitPeHiiTable) static bool -EmitPeGetExtraSectionsSize ( - image_tool_pe_emit_context_t *Context, - uint32_t *SectionsSize +ToolImageEmitPeHiiTable ( + image_tool_dynamic_buffer *Buffer, + EFI_IMAGE_NT_HEADERS *PeHdr, + EFI_IMAGE_SECTION_HEADER *SectionHeader, + const image_tool_image_info_t *Image ) { - const image_tool_image_info_t *Image; - bool Result; - uint32_t AlignedRelocTableSize; - bool Overflow; - uint32_t AlignedDebugTableSize; - uint32_t AlignedHiiTableSize; - - assert (Context != NULL); - assert (SectionsSize != NULL); - - Image = Context->Image; - - Result = EmitPeGetRelocSectionSize (Image, &Context->RelocTableSize); - if (!Result) { - raise (); + bool Success; + uint32_t HiiTableOffset; + uint32_t HiiTableSize; + void *HiiTable; + uint32_t Offset; + + HiiTableOffset = ImageToolBufferAppendReserve ( + Buffer, + mHiiResourceSectionHeaderSize + ); + if (HiiTableOffset == MAX_UINT32) { + DEBUG_RAISE (); return false; } - EmitPeGetDebugSectionSize (Image, &Context->DebugTableSize); - - Overflow = BaseOverflowAlignUpU32 ( - Context->RelocTableSize, - Context->FileAlignment, - &AlignedRelocTableSize - ); - if (Overflow) { - raise (); - return false; - } + assert (IS_ALIGNED (HiiTableOffset, PeHdr->FileAlignment)); - Overflow = BaseOverflowAlignUpU32 ( - Context->DebugTableSize, - Context->FileAlignment, - &AlignedDebugTableSize + HiiTable = ImageToolBufferGetPointer (Buffer, HiiTableOffset); + InitializeHiiResouceSectionHeader ( + HiiTable, + SectionHeader->VirtualAddress, + Image->HiiInfo.DataSize ); - if (Overflow) { - raise (); + HiiTable = NULL; + + Offset = ImageToolBufferAppend ( + Buffer, + Image->HiiInfo.Data, + Image->HiiInfo.DataSize + ); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); return false; } - AlignedHiiTableSize = 0; - if (Context->Image->HiiInfo.DataSize > 0) { - Overflow = BaseOverflowAddU32 ( - mHiiResourceSectionHeaderSize, - Context->Image->HiiInfo.DataSize, - &AlignedHiiTableSize - ); - - Overflow |= BaseOverflowAlignUpU32 ( - AlignedHiiTableSize, - Context->FileAlignment, - &AlignedHiiTableSize - ); - if (Overflow) { - raise (); - return false; - } - } + HiiTableSize = ImageToolBufferGetSize (Buffer) - HiiTableOffset; - Overflow = BaseOverflowAddU32 ( - AlignedRelocTableSize, - AlignedDebugTableSize, - SectionsSize - ); - if (Overflow) { - raise (); + Success = InternalFinalizeExtraSection ( + Buffer, + PeHdr, + SectionHeader, + ".rsrc", + HiiTableSize, + HiiTableOffset + ); + if (!Success) { + DEBUG_RAISE (); return false; } - Overflow = BaseOverflowAddU32 ( - *SectionsSize, - AlignedHiiTableSize, - SectionsSize - ); - if (Overflow) { - raise (); - return false; - } + PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader->VirtualAddress; + PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = HiiTableSize; return true; } -#define ToolImageEmitPeSectionHeaders PE_SUFFIX (ToolImageEmitPeSectionHeaders) +#define ToolImageEmitPeRelocTable PE_SUFFIX (ToolImageEmitPeRelocTable) static bool -ToolImageEmitPeSectionHeaders ( - const image_tool_pe_emit_context_t *Context, - uint8_t **Buffer, - uint32_t *BufferSize, - uint32_t AlignedHeaderSize +ToolImageEmitPeRelocTable ( + image_tool_dynamic_buffer *Buffer, + EFI_IMAGE_NT_HEADERS *PeHdr, + EFI_IMAGE_SECTION_HEADER *SectionHeader, + const image_tool_image_info_t *Image ) { - const image_tool_image_info_t *Image; - uint16_t SectionHeadersSize; - uint32_t SectionOffset; - EFI_IMAGE_SECTION_HEADER *Sections; - uint8_t Index; - - assert (Context != NULL); - assert (Buffer != NULL); - assert (BufferSize != NULL); - - Image = Context->Image; - SectionHeadersSize = (uint16_t) (Image->SegmentInfo.NumSegments * sizeof (EFI_IMAGE_SECTION_HEADER)); - SectionOffset = AlignedHeaderSize; - Sections = (void *) *Buffer; - - assert (SectionHeadersSize <= *BufferSize); + bool Success; + uint32_t RelocTableSize; + EFI_IMAGE_BASE_RELOCATION_BLOCK RelocBlock; + uint32_t BlockAddress; + uint32_t Index; + uint32_t RelocAddress; + uint16_t Relocation; + uint32_t RelocTableOffset; + uint32_t RelocTableEnd; + uint32_t RelocBlockOffset; + uint32_t NewRelocBlockOffset; + uint32_t Offset; + + RelocBlockOffset = ImageToolBufferAppendReserve (Buffer, sizeof (RelocBlock)); + if (RelocBlockOffset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } - for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { - assert (Sections[Index].Characteristics == 0); + RelocTableOffset = RelocBlockOffset; - if (Image->SegmentInfo.Segments[Index].Read) { - Sections[Index].Characteristics |= EFI_IMAGE_SCN_MEM_READ; - } + assert (IS_ALIGNED (RelocTableOffset, PeHdr->FileAlignment)); - if (Image->SegmentInfo.Segments[Index].Write) { - Sections[Index].Characteristics |= EFI_IMAGE_SCN_MEM_WRITE; - } + BlockAddress = PAGE (Image->RelocInfo.Relocs[0].Target); - if (Image->SegmentInfo.Segments[Index].Execute) { - Sections[Index].Characteristics |= EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_CNT_CODE; - } else { - Sections[Index].Characteristics |= EFI_IMAGE_SCN_CNT_INITIALIZED_DATA; - } + for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) { + RelocAddress = PAGE (Image->RelocInfo.Relocs[Index].Target); + if (RelocAddress != BlockAddress) { + Offset = ImageToolBufferAppendReserveAlign ( + Buffer, + ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK) + ); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } - Sections[Index].PointerToRawData = SectionOffset; - Sections[Index].VirtualAddress = SectionOffset; - Sections[Index].SizeOfRawData = ALIGN_VALUE (Image->SegmentInfo.Segments[Index].UnpaddedSize, Context->FileAlignment); - Sections[Index].VirtualSize = Image->SegmentInfo.Segments[Index].ImageSize; + NewRelocBlockOffset = ImageToolBufferAppendReserve ( + Buffer, + sizeof (RelocBlock) + ); + if (NewRelocBlockOffset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } - strncpy ( - (char *) Sections[Index].Name, - Image->SegmentInfo.Segments[Index].Name, - sizeof (Sections[Index].Name) - ); + RelocBlock.VirtualAddress = BlockAddress; + RelocBlock.SizeOfBlock = NewRelocBlockOffset - RelocBlockOffset; + ImageToolBufferWrite ( + Buffer, + RelocBlockOffset, + &RelocBlock, + sizeof (RelocBlock) + ); - SectionOffset += Sections[Index].SizeOfRawData; - } + RelocBlockOffset = NewRelocBlockOffset; - if (Image->HeaderInfo.FixedAddress) { - for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { - if ((Sections[Index].Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) == 0) { - WriteUnaligned64 ( - (VOID *)&Sections[Index].PointerToRelocations, - Image->HeaderInfo.BaseAddress - ); - break; - } + BlockAddress = RelocAddress; } - if (Index == Image->SegmentInfo.NumSegments) { - raise (); + Relocation = PAGE_OFF(Image->RelocInfo.Relocs[Index].Target); + Relocation |= ((uint16_t)Image->RelocInfo.Relocs[Index].Type) << 12U; + + Offset = ImageToolBufferAppend (Buffer, &Relocation, sizeof (Relocation)); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); return false; } } - *BufferSize -= SectionHeadersSize; - *Buffer += SectionHeadersSize; - - assert (SectionHeadersSize == Context->HdrInfo.SectionHeadersSize); - - return true; -} - -#define ToolImageEmitPeExtraSectionHeaders PE_SUFFIX (ToolImageEmitPeExtraSectionHeaders) -static -bool -ToolImageEmitPeExtraSectionHeaders ( - image_tool_pe_emit_context_t *Context, - uint8_t **Buffer, - uint32_t *BufferSize, - uint32_t AlignedHeaderSize - ) -{ - uint32_t SectionHeadersSize; - EFI_IMAGE_SECTION_HEADER *Section; - uint32_t SectionOffset; - uint32_t HiiSectionSize; - - assert (Context != NULL); - assert (Buffer != NULL); - assert (BufferSize != NULL); - - SectionHeadersSize = 0; - SectionOffset = AlignedHeaderSize + Context->SectionsSize; - - if (Context->Image->HiiInfo.DataSize > 0) { - ++Context->PeHdr->CommonHeader.FileHeader.NumberOfSections; - - assert (sizeof (EFI_IMAGE_SECTION_HEADER) <= *BufferSize); - - HiiSectionSize = mHiiResourceSectionHeaderSize + Context->Image->HiiInfo.DataSize; - - Section = (void *) *Buffer; - - strncpy ((char *)Section->Name, ".rsrc", sizeof (Section->Name)); - Section->SizeOfRawData = ALIGN_VALUE (HiiSectionSize, Context->FileAlignment); - Section->VirtualSize = ALIGN_VALUE (HiiSectionSize, Context->Image->SegmentInfo.SegmentAlignment); - Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_READ; - Section->PointerToRawData = SectionOffset; - Section->VirtualAddress = Section->PointerToRawData; - - Context->HiiSectionAddress = SectionOffset; - - SectionOffset += Section->SizeOfRawData; - - Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = HiiSectionSize; - Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = Section->PointerToRawData; - - *BufferSize -= sizeof (EFI_IMAGE_SECTION_HEADER); - *Buffer += sizeof (EFI_IMAGE_SECTION_HEADER); - SectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER); - } - - if (Context->RelocTableSize > 0) { - ++Context->PeHdr->CommonHeader.FileHeader.NumberOfSections; - - assert (sizeof (EFI_IMAGE_SECTION_HEADER) <= *BufferSize); - - Section = (void *) *Buffer; - - strncpy ((char *)Section->Name, ".reloc", sizeof (Section->Name)); - Section->SizeOfRawData = ALIGN_VALUE (Context->RelocTableSize, Context->FileAlignment); - Section->VirtualSize = Section->SizeOfRawData; - Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_DISCARDABLE | EFI_IMAGE_SCN_MEM_READ; - Section->PointerToRawData = SectionOffset; - Section->VirtualAddress = Section->PointerToRawData; - - SectionOffset += Section->SizeOfRawData; - - Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = Context->RelocTableSize; - Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Section->PointerToRawData; - - *BufferSize -= sizeof (EFI_IMAGE_SECTION_HEADER); - *Buffer += sizeof (EFI_IMAGE_SECTION_HEADER); - SectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER); + Offset = ImageToolBufferAppendReserveAlign ( + Buffer, + ALIGNOF (EFI_IMAGE_BASE_RELOCATION_BLOCK) + ); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; } - if (Context->DebugTableSize > 0) { - ++Context->PeHdr->CommonHeader.FileHeader.NumberOfSections; - - assert (sizeof (EFI_IMAGE_SECTION_HEADER) <= *BufferSize); - - Section = (void *) *Buffer; + RelocTableEnd = ImageToolBufferGetSize (Buffer); - strncpy ((char *)Section->Name, ".debug", sizeof (Section->Name)); - Section->SizeOfRawData = ALIGN_VALUE (Context->DebugTableSize, Context->FileAlignment); - Section->VirtualSize = Section->SizeOfRawData; - Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_READ; - Section->PointerToRawData = SectionOffset; - Section->VirtualAddress = Section->PointerToRawData; - - SectionOffset += Section->SizeOfRawData; - - Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = Section->VirtualAddress; + RelocBlock.VirtualAddress = BlockAddress; + RelocBlock.SizeOfBlock = RelocTableEnd - RelocBlockOffset; + ImageToolBufferWrite ( + Buffer, + RelocBlockOffset, + &RelocBlock, + sizeof (RelocBlock) + ); - *BufferSize -= sizeof (EFI_IMAGE_SECTION_HEADER); - *Buffer += sizeof (EFI_IMAGE_SECTION_HEADER); - SectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER); + RelocTableSize = RelocTableEnd - RelocTableOffset; + + Success = InternalFinalizeExtraSection ( + Buffer, + PeHdr, + SectionHeader, + ".reloc", + RelocTableSize, + RelocTableOffset + ); + if (!Success) { + DEBUG_RAISE (); + return false; } + SectionHeader->Characteristics |= EFI_IMAGE_SCN_MEM_DISCARDABLE; - assert (SectionHeadersSize == Context->HdrInfo.ExtraSectionHeadersSize); - assert (SectionOffset == Context->UnsignedFileSize); + PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = SectionHeader->VirtualAddress; + PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = RelocTableSize; return true; } -#define ToolImageEmitPeHeaders PE_SUFFIX (ToolImageEmitPeHeaders) +#define ToolImageEmitPeDebugTable PE_SUFFIX (ToolImageEmitPeDebugTable) static bool -ToolImageEmitPeHeaders ( - image_tool_pe_emit_context_t *Context, - uint8_t **Buffer, - uint32_t *BufferSize, - uint32_t AlignedHeaderSize +ToolImageEmitPeDebugTable ( + image_tool_dynamic_buffer *Buffer, + EFI_IMAGE_NT_HEADERS *PeHdr, + EFI_IMAGE_SECTION_HEADER *SectionHeader, + const image_tool_image_info_t *Image ) { - const image_tool_image_info_t *Image; - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_NT_HEADERS *PePlusHdr; - bool Result; - uint32_t HeaderPadding; - - assert (Context != NULL); - assert (Buffer != NULL); - assert (BufferSize != NULL); - - assert (sizeof (EFI_IMAGE_DOS_HEADER) <= *BufferSize); - - Image = Context->Image; - DosHdr = (void *) *Buffer; - - DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE; - DosHdr->e_lfanew = sizeof (EFI_IMAGE_DOS_HEADER); + bool Success; + uint32_t DebugDirOffset; + uint32_t DebugDirSize; + image_tool_debug_dir_t *Data; + uint32_t Offset; - *BufferSize -= sizeof (EFI_IMAGE_DOS_HEADER); - *Buffer += sizeof (EFI_IMAGE_DOS_HEADER); - - assert (sizeof (EFI_IMAGE_NT_HEADERS) <= *BufferSize); - - PePlusHdr = (EFI_IMAGE_NT_HEADERS *)(VOID *) *Buffer; - - PePlusHdr->CommonHeader.Signature = EFI_IMAGE_NT_SIGNATURE; - PePlusHdr->CommonHeader.FileHeader.Machine = Image->HeaderInfo.Machine; - PePlusHdr->CommonHeader.FileHeader.NumberOfSections = (UINT16)Image->SegmentInfo.NumSegments; - PePlusHdr->CommonHeader.FileHeader.SizeOfOptionalHeader = Context->HdrInfo.SizeOfOptionalHeader; - PePlusHdr->CommonHeader.FileHeader.Characteristics = - EFI_IMAGE_FILE_EXECUTABLE_IMAGE | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED | - EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; + assert (Image->DebugInfo.SymbolsPath != NULL); - if (Image->RelocInfo.RelocsStripped) { - PePlusHdr->CommonHeader.FileHeader.Characteristics |= EFI_IMAGE_FILE_RELOCS_STRIPPED; + DebugDirOffset = ImageToolBufferAppendReserve (Buffer, sizeof (*Data)); + if (DebugDirOffset == MAX_UINT32) { + DEBUG_RAISE (); + return false; } - PePlusHdr->Magic = EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC; - PePlusHdr->AddressOfEntryPoint = Image->HeaderInfo.EntryPointAddress; - PePlusHdr->SectionAlignment = Image->SegmentInfo.SegmentAlignment; - PePlusHdr->FileAlignment = Context->FileAlignment; - PePlusHdr->SizeOfHeaders = AlignedHeaderSize; - PePlusHdr->SizeOfImage = AlignedHeaderSize; - PePlusHdr->ImageBase = (UINTN)Image->HeaderInfo.BaseAddress; - PePlusHdr->Subsystem = Image->HeaderInfo.Subsystem; - PePlusHdr->NumberOfRvaAndSizes = Context->HdrInfo.NumberOfRvaAndSizes; - - STATIC_ASSERT( - OFFSET_OF(EFI_IMAGE_NT_HEADERS, DataDirectory) == sizeof (EFI_IMAGE_NT_HEADERS), - "The following code needs to be updated to consider padding." - ); - - Context->PeHdr = PePlusHdr; - - *BufferSize -= sizeof (EFI_IMAGE_NT_HEADERS) + PePlusHdr->NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY); - *Buffer += sizeof (EFI_IMAGE_NT_HEADERS) + PePlusHdr->NumberOfRvaAndSizes * sizeof (EFI_IMAGE_DATA_DIRECTORY); + assert (IS_ALIGNED (DebugDirOffset, PeHdr->FileAlignment)); - Result = ToolImageEmitPeSectionHeaders (Context, Buffer, BufferSize, AlignedHeaderSize); - if (!Result) { + Offset = ImageToolBufferAppend ( + Buffer, + Image->DebugInfo.SymbolsPath, + Image->DebugInfo.SymbolsPathLen + 1 + ); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); return false; } - Result = ToolImageEmitPeExtraSectionHeaders (Context, Buffer, BufferSize, AlignedHeaderSize); - if (!Result) { + DebugDirSize = ImageToolBufferGetSize (Buffer) - DebugDirOffset; + + Success = InternalFinalizeExtraSection ( + Buffer, + PeHdr, + SectionHeader, + ".debug", + DebugDirSize, + DebugDirOffset + ); + if (!Success) { + DEBUG_RAISE (); return false; } + SectionHeader->Characteristics |= EFI_IMAGE_SCN_MEM_DISCARDABLE; - HeaderPadding = AlignedHeaderSize - Context->HdrInfo.SizeOfHeaders; + PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = SectionHeader->VirtualAddress; + PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (Data->Dir); - assert (HeaderPadding <= *BufferSize); + Data = ImageToolBufferGetPointer (Buffer, DebugDirOffset); - *BufferSize -= HeaderPadding; - *Buffer += HeaderPadding; + memset (Data, 0, sizeof (*Data)); + Data->Dir.Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW; + Data->Dir.SizeOfData = DebugDirSize - OFFSET_OF (image_tool_debug_dir_t, Nb10); + Data->Dir.RVA = SectionHeader->VirtualAddress + OFFSET_OF (image_tool_debug_dir_t, Nb10); + Data->Dir.FileOffset = SectionHeader->PointerToRawData + OFFSET_OF (image_tool_debug_dir_t, Nb10); + Data->Nb10.Signature = CODEVIEW_SIGNATURE_NB10; + + Data = NULL; return true; } -#define ToolImageEmitPeSections PE_SUFFIX (ToolImageEmitPeSections) static bool -ToolImageEmitPeSections ( - const image_tool_pe_emit_context_t *Context, - uint8_t **Buffer, - uint32_t *BufferSize +ToolImagePeHiiTableRequired ( + const image_tool_image_info_t *Image ) { - const image_tool_image_info_t *Image; - uint32_t SectionsSize; - uint8_t Index; - const image_tool_segment_t *Segment; - uint32_t SectionPadding; - bool FirstCode; - -#if PE_ARCH == 32 - bool FirstData; -#endif - - assert (Context != NULL); - assert (Buffer != NULL); - assert (BufferSize != NULL); - - assert (Context->SectionsSize <= *BufferSize); - - Image = Context->Image; - SectionsSize = 0; - FirstCode = true; - -#if PE_ARCH == 32 - FirstData = true; -#endif - - for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { - Segment = &Image->SegmentInfo.Segments[Index]; - - Context->PeHdr->SizeOfImage += Segment->ImageSize; - - if (Segment->Execute) { - if (FirstCode) { - Context->PeHdr->BaseOfCode = Segment->ImageAddress; - FirstCode = false; - } - } -#if PE_ARCH == 32 - else { - if (FirstData) { - Context->PeHdr->BaseOfData = Segment->ImageAddress; - FirstData = false; - } - } -#endif - - assert (Segment->UnpaddedSize <= *BufferSize); - - memmove (*Buffer, Segment->Data, Segment->UnpaddedSize); - - *BufferSize -= Segment->UnpaddedSize; - *Buffer += Segment->UnpaddedSize; - SectionsSize += Segment->UnpaddedSize; - - SectionPadding = ALIGN_VALUE_ADDEND ( - Segment->UnpaddedSize, - Context->FileAlignment - ); - - assert (SectionPadding <= *BufferSize); - - *BufferSize -= SectionPadding; - *Buffer += SectionPadding; - SectionsSize += SectionPadding; - - if (Segment->Execute) { - Context->PeHdr->BaseOfCode = MIN(Context->PeHdr->BaseOfCode, Segment->ImageAddress); - Context->PeHdr->SizeOfCode += Segment->ImageSize; - } else { -#if PE_ARCH == 32 - Context->PeHdr->BaseOfData = MIN(Context->PeHdr->BaseOfData, Segment->ImageAddress); -#endif - Context->PeHdr->SizeOfInitializedData += Segment->ImageSize; - } - } - - assert (SectionsSize == Context->SectionsSize); - - return true; + return Image->HiiInfo.DataSize != 0; } -#define ToolImageEmitPeRelocTable PE_SUFFIX (ToolImageEmitPeRelocTable) static bool -ToolImageEmitPeRelocTable ( - const image_tool_pe_emit_context_t *Context, - uint8_t **Buffer, - uint32_t *BufferSize +ToolImagePeRelocTableRequired ( + const image_tool_image_info_t *Image ) { - const image_tool_image_info_t *Image; - uint32_t RelocTableSize; - EFI_IMAGE_BASE_RELOCATION_BLOCK *RelocBlock; - uint32_t BlockAddress; - uint32_t BlockNumRelocs; - uint32_t Index; - uint32_t RelocAddress; - uint32_t RelocTablePadding; - - assert (Context != NULL); - assert (Buffer != NULL); - assert (BufferSize != NULL); - - if (Context->RelocTableSize == 0) { - return true; - } - - Image = Context->Image; - - Context->PeHdr->SizeOfImage += ALIGN_VALUE (Context->RelocTableSize, Image->SegmentInfo.SegmentAlignment); - - assert (Image->RelocInfo.NumRelocs > 0); - assert (Image->RelocInfo.NumRelocs <= MAX_UINT32); - - assert (sizeof (EFI_IMAGE_BASE_RELOCATION_BLOCK) <= *BufferSize); - - RelocTableSize = 0; - RelocBlock = (void *) *Buffer; - BlockAddress = PAGE(Image->RelocInfo.Relocs[0].Target); - BlockNumRelocs = 0; - - RelocBlock->VirtualAddress = BlockAddress; - RelocBlock->SizeOfBlock = sizeof (*RelocBlock); - - for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) { - RelocAddress = PAGE(Image->RelocInfo.Relocs[Index].Target); - if (RelocAddress != BlockAddress) { - RelocBlock->SizeOfBlock = ALIGN_VALUE (RelocBlock->SizeOfBlock, 4); - - assert (RelocBlock->SizeOfBlock <= *BufferSize); - - *BufferSize -= RelocBlock->SizeOfBlock; - *Buffer += RelocBlock->SizeOfBlock; - RelocTableSize += RelocBlock->SizeOfBlock; - - RelocBlock = (void *) *Buffer; - - BlockAddress = RelocAddress; - BlockNumRelocs = 0; - - RelocBlock->VirtualAddress = BlockAddress; - RelocBlock->SizeOfBlock = sizeof (*RelocBlock); - } - - RelocBlock->SizeOfBlock += sizeof (*RelocBlock->Relocations); - - assert (RelocBlock->SizeOfBlock <= *BufferSize); - - RelocBlock->Relocations[BlockNumRelocs] = PAGE_OFF(Image->RelocInfo.Relocs[Index].Target); - RelocBlock->Relocations[BlockNumRelocs] |= ((uint16_t)Image->RelocInfo.Relocs[Index].Type) << 12U; - - ++BlockNumRelocs; - } - - RelocBlock->SizeOfBlock = ALIGN_VALUE (RelocBlock->SizeOfBlock, 4); - - assert (RelocBlock->SizeOfBlock <= *BufferSize); - - *BufferSize -= RelocBlock->SizeOfBlock; - *Buffer += RelocBlock->SizeOfBlock; - RelocTableSize += RelocBlock->SizeOfBlock; - - assert (RelocTableSize == Context->RelocTableSize); - - RelocTablePadding = ALIGN_VALUE_ADDEND ( - RelocTableSize, - Context->FileAlignment - ); - - assert (RelocTablePadding <= *BufferSize); - - *BufferSize -= RelocTablePadding; - *Buffer += RelocTablePadding; - - return true; + return Image->RelocInfo.NumRelocs != 0; } -typedef struct { - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY CodeViewDirEntry; - EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY CodeViewEntry; - uint8_t PdbPath[]; -} image_tool_debug_dir_t; - -STATIC_ASSERT( - OFFSET_OF(image_tool_debug_dir_t, PdbPath) == sizeof (image_tool_debug_dir_t), - "Flexible array aliases padding." - ); - -#define ToolImageEmitPeDebugTable PE_SUFFIX (ToolImageEmitPeDebugTable) static bool -ToolImageEmitPeDebugTable ( - const image_tool_pe_emit_context_t *Context, - uint8_t **Buffer, - uint32_t *BufferSize +ToolImagePeDebugTableRequired ( + const image_tool_image_info_t *Image ) { - const image_tool_image_info_t *Image; - uint32_t DebugTablePadding; - DebugData *Data; + return Image->DebugInfo.SymbolsPath != NULL; +} - assert (Context != NULL); - assert (Buffer != NULL); - assert (BufferSize != NULL); +#define ToolImageEmitPeSection PE_SUFFIX (ToolImageEmitPeSection) +static +bool +ToolImageEmitPeSection ( + image_tool_dynamic_buffer *Buffer, + EFI_IMAGE_NT_HEADERS *PeHdr, + EFI_IMAGE_SECTION_HEADER *SectionHeader, + const image_tool_image_info_t *Image, + bool Xip, + const image_tool_segment_t *Segment + ) +{ + uint32_t SectionOffset; + uint32_t SizeOfRawData; + uint32_t Offset; + + SectionOffset = ImageToolBufferAppend ( + Buffer, + Segment->Data, + Segment->UnpaddedSize + ); + if (SectionOffset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } - Image = Context->Image; + assert (IS_ALIGNED (SectionOffset, PeHdr->FileAlignment)); - if (Context->DebugTableSize == 0) { - return true; + if (!Xip) { + SizeOfRawData = Segment->UnpaddedSize; + } else { + SizeOfRawData = Segment->ImageSize; } - Context->PeHdr->SizeOfImage += ALIGN_VALUE (Context->DebugTableSize, Image->SegmentInfo.SegmentAlignment); - - assert (Image->DebugInfo.SymbolsPathLen + 1 <= Context->DebugTableSize); - assert (Context->DebugTableSize <= *BufferSize); + strncpy ( + (char *)SectionHeader->Name, + Segment->Name, + sizeof (SectionHeader->Name) + ); + SectionHeader->Name[ARRAY_SIZE (SectionHeader->Name) - 1] = 0; - Data = (DebugData *) *Buffer; + SectionHeader->VirtualSize = Segment->ImageSize; + SectionHeader->VirtualAddress = Segment->ImageAddress; + SectionHeader->SizeOfRawData = ALIGN_VALUE (SizeOfRawData, PeHdr->FileAlignment); + SectionHeader->PointerToRawData = SectionOffset; - Data->Dir.Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW; - Data->Dir.SizeOfData = sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Image->DebugInfo.SymbolsPathLen + 1; - Data->Dir.RVA = (Context->UnsignedFileSize - ALIGN_VALUE (Context->DebugTableSize, Context->FileAlignment)) + sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - Data->Dir.FileOffset = Data->Dir.RVA; + assert (SectionHeader->Characteristics == 0); - Data->Nb10.Signature = CODEVIEW_SIGNATURE_NB10; - memmove (Data->Name, Image->DebugInfo.SymbolsPath, Image->DebugInfo.SymbolsPathLen + 1); + if (Segment->Read) { + SectionHeader->Characteristics |= EFI_IMAGE_SCN_MEM_READ; + } - assert (sizeof (*Data) + Image->DebugInfo.SymbolsPathLen + 1 == Context->DebugTableSize); + if (Segment->Write) { + SectionHeader->Characteristics |= EFI_IMAGE_SCN_MEM_WRITE; + } - *BufferSize -= Context->DebugTableSize; - *Buffer += Context->DebugTableSize; + if (Segment->Execute) { + SectionHeader->Characteristics |= EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_CNT_CODE; - DebugTablePadding = ALIGN_VALUE_ADDEND( - Context->DebugTableSize, - Context->FileAlignment - ); + PeHdr->SizeOfCode += Segment->ImageSize; + if (PeHdr->BaseOfCode == 0) { + PeHdr->BaseOfCode = Segment->ImageAddress; + } + } else { + SectionHeader->Characteristics |= EFI_IMAGE_SCN_CNT_INITIALIZED_DATA; - assert (DebugTablePadding <= *BufferSize); + PeHdr->SizeOfInitializedData += Segment->ImageSize; +#if PE_ARCH == 32 + if (PeHdr->BaseOfData == 0) { + PeHdr->BaseOfData = Segment->ImageAddress; + } +#endif + } - *BufferSize -= DebugTablePadding; - *Buffer += DebugTablePadding; + assert (PeHdr->SizeOfImage == SectionHeader->VirtualAddress); + PeHdr->SizeOfImage += SectionHeader->VirtualSize; - return true; + Offset = ImageToolBufferAppendReserve ( + Buffer, + SectionHeader->SizeOfRawData - Segment->UnpaddedSize + ); + return Offset != MAX_UINT32; } -#define ToolImageEmitPeHiiTable PE_SUFFIX (ToolImageEmitPeHiiTable) +#define ToolImageEmitPeSections PE_SUFFIX (ToolImageEmitPeSections) static bool -ToolImageEmitPeHiiTable ( - const image_tool_pe_emit_context_t *Context, - uint8_t **Buffer, - uint32_t *BufferSize +ToolImageEmitPeSections ( + image_tool_dynamic_buffer *Buffer, + EFI_IMAGE_NT_HEADERS *PeHdr, + EFI_IMAGE_SECTION_HEADER *SectionHeaders, + const image_tool_image_info_t *Image, + bool Xip ) { - const image_tool_image_info_t *Image; - uint32_t HiiTablePadding; - - assert (Context != NULL); - assert (Buffer != NULL); - assert (BufferSize != NULL); + bool Success; + uint16_t Index; + const image_tool_segment_t *Segment; + EFI_IMAGE_SECTION_HEADER *SectionHeader; - Image = Context->Image; - - if (Image->HiiInfo.DataSize == 0) { - return true; + if (PeHdr->SizeOfImage != Image->SegmentInfo.Segments[0].ImageAddress) { + DEBUG_RAISE (); + return false; } - Context->PeHdr->SizeOfImage += ALIGN_VALUE (mHiiResourceSectionHeaderSize + Image->HiiInfo.DataSize, Image->SegmentInfo.SegmentAlignment); + for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { + Segment = &Image->SegmentInfo.Segments[Index]; + SectionHeader = &SectionHeaders[Index]; + + Success = ToolImageEmitPeSection ( + Buffer, + PeHdr, + SectionHeader, + Image, + Xip, + Segment + ); + if (!Success) { + DEBUG_RAISE (); + return false; + } + } - assert (mHiiResourceSectionHeaderSize <= *BufferSize); + if (ToolImagePeHiiTableRequired (Image)) { + Success = ToolImageEmitPeHiiTable (Buffer, PeHdr, &SectionHeaders[Index], Image); + if (!Success) { + DEBUG_RAISE (); + return false; + } - InitializeHiiResouceSectionHeader ( - *Buffer, - Context->HiiSectionAddress, - Context->Image->HiiInfo.DataSize - ); + ++Index; + } - *BufferSize -= mHiiResourceSectionHeaderSize; - *Buffer += mHiiResourceSectionHeaderSize; + if (ToolImagePeRelocTableRequired (Image)) { + Success = ToolImageEmitPeRelocTable (Buffer, PeHdr, &SectionHeaders[Index], Image); + if (!Success) { + DEBUG_RAISE (); + return false; + } - assert (Image->HiiInfo.DataSize <= *BufferSize); + ++Index; + } - memmove (*Buffer, Image->HiiInfo.Data, Image->HiiInfo.DataSize); + if (ToolImagePeDebugTableRequired (Image)) { + Success = ToolImageEmitPeDebugTable (Buffer, PeHdr, &SectionHeaders[Index], Image); + if (!Success) { + DEBUG_RAISE (); + return false; + } - *BufferSize -= Image->HiiInfo.DataSize; - *Buffer += Image->HiiInfo.DataSize; + ++Index; + } - HiiTablePadding = ALIGN_VALUE_ADDEND( - mHiiResourceSectionHeaderSize + Image->HiiInfo.DataSize, - Context->FileAlignment - ); + assert (Index == PeHdr->CommonHeader.FileHeader.NumberOfSections); - assert (HiiTablePadding <= *BufferSize); + if (Image->HeaderInfo.FixedAddress) { + for (Index = 0; Index < PeHdr->CommonHeader.FileHeader.NumberOfSections; ++Index) { + if ((SectionHeaders[Index].Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) == 0) { + WriteUnaligned64 ( + (VOID *)&SectionHeaders[Index].PointerToRelocations, + PeHdr->ImageBase + ); + break; + } + } - *BufferSize -= HiiTablePadding; - *Buffer += HiiTablePadding; + if (Index == PeHdr->CommonHeader.FileHeader.NumberOfSections) { + DEBUG_RAISE (); + return false; + } + } return true; } -#define ToolImageEmitPeExtraSections PE_SUFFIX (ToolImageEmitPeExtraSections) +STATIC CONST EFI_IMAGE_DOS_HEADER mDosHdr = { + .e_magic = EFI_IMAGE_DOS_SIGNATURE, + .e_lfanew = sizeof (mDosHdr) +}; + +#define ToolImageEmitPeFile PE_SUFFIX (ToolImageEmitPeFile) static bool -ToolImageEmitPeExtraSections ( - const image_tool_pe_emit_context_t *Context, - uint8_t **Buffer, - uint32_t *BufferSize +ToolImageEmitPeFile ( + image_tool_dynamic_buffer *Buffer, + const image_tool_image_info_t *Image, + bool Xip ) { - uint32_t OldBufferSize; - bool Result; - - assert (Context != NULL); - assert (Buffer != NULL); - assert (BufferSize != NULL); + bool Success; + uint32_t FileAlignment; + uint32_t PeOffset; + EFI_IMAGE_NT_HEADERS *PeHdr; + uint16_t NumSections; + EFI_IMAGE_SECTION_HEADER *SectionHeaders; + uint32_t SectionHeadersOffset; + uint32_t SectionHeadersSize; + uint32_t SizeOfPeHeaders; + uint32_t SizeOfHeaders; + uint32_t AlignedSizeOfHeaders; + void *BufferPeHdr; + uint32_t Offset; + + if (!Xip) { + FileAlignment = 64; + } else { + FileAlignment = Image->SegmentInfo.SegmentAlignment; + } + + NumSections = Image->SegmentInfo.NumSegments; + NumSections += ToolImagePeHiiTableRequired (Image) ? 1 : 0; + NumSections += ToolImagePeRelocTableRequired (Image) ? 1 : 0; + NumSections += ToolImagePeDebugTableRequired (Image) ? 1 : 0; + + Offset = ImageToolBufferAppend (Buffer, &mDosHdr, sizeof (mDosHdr)); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } - OldBufferSize = *BufferSize; + SectionHeadersOffset = sizeof (*PeHdr) + SIZE_OF_DATA_DIRECRORY; + SectionHeadersSize = NumSections * sizeof (EFI_IMAGE_SECTION_HEADER); + SizeOfPeHeaders = SectionHeadersOffset + SectionHeadersSize; + SizeOfHeaders = sizeof (mDosHdr) + SizeOfPeHeaders; + AlignedSizeOfHeaders = ALIGN_VALUE (SizeOfHeaders, FileAlignment); - Result = ToolImageEmitPeHiiTable (Context, Buffer, BufferSize); - if (!Result) { + PeOffset = ImageToolBufferAppendReserve ( + Buffer, + AlignedSizeOfHeaders - sizeof (mDosHdr) + ); + if (PeOffset == MAX_UINT32) { + DEBUG_RAISE (); return false; } - Result = ToolImageEmitPeRelocTable (Context, Buffer, BufferSize); - if (!Result) { + PeHdr = AllocateZeroPool (SizeOfPeHeaders); + if (PeHdr == NULL) { + DEBUG_RAISE (); return false; } - Result = ToolImageEmitPeDebugTable (Context, Buffer, BufferSize); - if (!Result) { + SectionHeaders = (EFI_IMAGE_SECTION_HEADER *)((UINT8 *)PeHdr + SectionHeadersOffset); + + PeHdr->CommonHeader.Signature = EFI_IMAGE_NT_SIGNATURE; + PeHdr->CommonHeader.FileHeader.Machine = Image->HeaderInfo.Machine; + PeHdr->CommonHeader.FileHeader.NumberOfSections = NumSections; + PeHdr->CommonHeader.FileHeader.SizeOfOptionalHeader = SIZE_OF_OPTIONAL_HEADER; + PeHdr->CommonHeader.FileHeader.Characteristics = + EFI_IMAGE_FILE_EXECUTABLE_IMAGE | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED | + EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; + + if (Image->RelocInfo.RelocsStripped) { + PeHdr->CommonHeader.FileHeader.Characteristics |= EFI_IMAGE_FILE_RELOCS_STRIPPED; + } + + PeHdr->Magic = EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC; + PeHdr->AddressOfEntryPoint = Image->HeaderInfo.EntryPointAddress; + PeHdr->ImageBase = (EFI_IMAGE_NT_BASE_ADDRESS)Image->HeaderInfo.BaseAddress; + PeHdr->SectionAlignment = Image->SegmentInfo.SegmentAlignment; + PeHdr->FileAlignment = FileAlignment; + PeHdr->SizeOfImage = ALIGN_VALUE (SizeOfHeaders, PeHdr->SectionAlignment); + PeHdr->SizeOfHeaders = AlignedSizeOfHeaders; + PeHdr->Subsystem = Image->HeaderInfo.Subsystem; + PeHdr->NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES; + + Success = ToolImageEmitPeSections (Buffer, PeHdr, SectionHeaders, Image, Xip); + if (!Success) { + FreePool (PeHdr); + DEBUG_RAISE (); return false; } - assert ((OldBufferSize - *BufferSize) == Context->ExtraSectionsSize); + BufferPeHdr = ImageToolBufferGetPointer (Buffer, PeOffset); + memmove (BufferPeHdr, PeHdr, SizeOfPeHeaders); + FreePool (PeHdr); + BufferPeHdr = NULL; return true; } @@ -902,135 +644,37 @@ ToolImageEmitPeExtraSections ( #define ToolImageEmitPe PE_SUFFIX (ToolImageEmitPe) void * ToolImageEmitPe ( - image_tool_image_info_t *Image, - uint32_t *FileSize + const image_tool_image_info_t *Image, + uint32_t *FileSize, + bool Xip ) { - image_tool_pe_emit_context_t Context; - bool Result; - uint32_t AlignedHeaderSize; - bool Overflow; - uint32_t SectionsOffset; - void *FileBuffer; - uint8_t *Buffer; - uint32_t RemainingSize; - uint32_t ExpectedSize; + bool Success; + image_tool_dynamic_buffer Buffer; + void *FileBuffer; assert (Image != NULL); assert (FileSize != NULL); - memset (&Context, 0, sizeof (Context)); - - // FIXME: Non-XIP is not well-supported right now. - Context.FileAlignment = Image->SegmentInfo.SegmentAlignment; - Image->HeaderInfo.IsXip = true; - ImageInitUnpaddedSize (Image); - Context.Image = Image; + ImageToolBufferInit (&Buffer); - Result = EmitPeGetHeaderSizes (Image, &Context.HdrInfo); - if (!Result) { - raise (); + Success = ToolImageEmitPeFile (&Buffer, Image, Xip); + if (!Success) { + DEBUG_RAISE (); + ImageToolBufferFree (&Buffer); return NULL; } - Overflow = BaseOverflowAlignUpU32 ( - Context.HdrInfo.SizeOfHeaders, - Context.FileAlignment, - &AlignedHeaderSize - ); - if (Overflow) { - raise (); - return NULL; - } + FileBuffer = ImageToolBufferDump (FileSize, &Buffer); - if (AlignedHeaderSize > Image->SegmentInfo.Segments[0].ImageAddress) { - raise (); - return NULL; - } - - AlignedHeaderSize = (uint32_t)Image->SegmentInfo.Segments[0].ImageAddress; + ImageToolBufferFree (&Buffer); - Result = EmitPeGetSectionsSize (&Context, &Context.SectionsSize); - if (!Result) { - raise (); - return NULL; - } - - Overflow = BaseOverflowAddU32 ( - AlignedHeaderSize, - Context.SectionsSize, - &SectionsOffset - ); - if (Overflow) { - raise (); - return NULL; - } - - Result = EmitPeGetExtraSectionsSize (&Context, &Context.ExtraSectionsSize); - if (!Result) { - raise (); - return NULL; - } - - Overflow = BaseOverflowAddU32 ( - SectionsOffset, - Context.ExtraSectionsSize, - &Context.UnsignedFileSize - ); - if (Overflow) { - raise (); - return NULL; - } - - FileBuffer = calloc (1, Context.UnsignedFileSize); if (FileBuffer == NULL) { - raise (); - return NULL; - } - - Buffer = FileBuffer; - RemainingSize = Context.UnsignedFileSize; - ExpectedSize = Context.UnsignedFileSize; - - Result = ToolImageEmitPeHeaders (&Context, &Buffer, &RemainingSize, AlignedHeaderSize); - if (!Result) { - raise (); - free (FileBuffer); - return NULL; - } - - ExpectedSize -= AlignedHeaderSize; - - assert (RemainingSize == ExpectedSize); - - Result = ToolImageEmitPeSections (&Context, &Buffer, &RemainingSize); - if (!Result) { - raise (); - free (FileBuffer); - return NULL; - } - - ExpectedSize -= Context.SectionsSize; - - assert (RemainingSize == ExpectedSize); - - Result = ToolImageEmitPeExtraSections (&Context, &Buffer, &RemainingSize); - if (!Result) { - raise (); - free (FileBuffer); + DEBUG_RAISE (); return NULL; } - ExpectedSize -= Context.ExtraSectionsSize; - - assert (RemainingSize == ExpectedSize); - assert (RemainingSize == 0); - - Context.PeHdr->SizeOfInitializedData += Context.ExtraSectionsSize; - - *FileSize = Context.UnsignedFileSize; - return FileBuffer; } diff --git a/BaseTools/ImageTool/PeEmitCommon.c b/BaseTools/ImageTool/PeEmitCommon.c index c136721a19..9946bdfe11 100644 --- a/BaseTools/ImageTool/PeEmitCommon.c +++ b/BaseTools/ImageTool/PeEmitCommon.c @@ -9,6 +9,7 @@ void * ToolImageEmitPe ( image_tool_image_info_t *Image, uint32_t *FileSize, + bool Xip, bool Strip ) { @@ -20,13 +21,13 @@ ToolImageEmitPe ( case IMAGE_FILE_MACHINE_I386: case IMAGE_FILE_MACHINE_ARMTHUMB_MIXED: { - return ToolImageEmitPe32 (Image, FileSize); + return ToolImageEmitPe32 (Image, FileSize, Xip); } case IMAGE_FILE_MACHINE_X64: case IMAGE_FILE_MACHINE_ARM64: { - return ToolImageEmitPe64 (Image, FileSize); + return ToolImageEmitPe64 (Image, FileSize, Xip); } default: diff --git a/BaseTools/ImageTool/PeEmitCommon.h b/BaseTools/ImageTool/PeEmitCommon.h index a65761f06f..0d28aa96d3 100644 --- a/BaseTools/ImageTool/PeEmitCommon.h +++ b/BaseTools/ImageTool/PeEmitCommon.h @@ -13,13 +13,15 @@ void * ToolImageEmitPe32 ( const image_tool_image_info_t *Image, - uint32_t *FileSize + uint32_t *FileSize, + bool Xip ); void * ToolImageEmitPe64 ( const image_tool_image_info_t *Image, - uint32_t *FileSize + uint32_t *FileSize, + bool Xip ); #endif // PE_EMIT_COMMON_H diff --git a/BaseTools/ImageTool/PeScan.c b/BaseTools/ImageTool/PeScan.c index 8c7585a2a1..42aff03009 100644 --- a/BaseTools/ImageTool/PeScan.c +++ b/BaseTools/ImageTool/PeScan.c @@ -6,11 +6,13 @@ #include "ImageTool.h" +#include "PeScan.h" + #define PE_COFF_SECT_NAME_RELOC ".reloc\0" #define PE_COFF_SECT_NAME_RESRC ".rsrc\0\0" #define PE_COFF_SECT_NAME_DEBUG ".debug\0" -bool +RETURN_STATUS ScanPeGetRelocInfo ( OUT image_tool_reloc_info_t *RelocInfo, IN PE_COFF_LOADER_IMAGE_CONTEXT *Context @@ -29,9 +31,7 @@ ScanPeGetRelocInfo ( const char *ImageBuffer; UINT16 RelocType; UINT16 RelocOffset; - - assert (RelocInfo != NULL); - assert (Context != NULL); + uint32_t ToolRelocsSize; // FIXME: PE/COFF context access RelocBlockRva = Context->RelocDirRva; @@ -40,13 +40,28 @@ ScanPeGetRelocInfo ( // Verify the Relocation Directory is not empty. // if (RelocDirSize == 0) { - return true; + return RETURN_SUCCESS; + } + + STATIC_ASSERT ( + sizeof (*RelocInfo->Relocs) % sizeof (UINT16) == 0, + "The division below is inaccurate." + ); + + Overflow = BaseOverflowMulU32 ( + RelocDirSize, + sizeof (*RelocInfo->Relocs) / sizeof (UINT16), + &ToolRelocsSize + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_OUT_OF_RESOURCES; } - RelocInfo->Relocs = calloc (RelocDirSize / sizeof (UINT16), sizeof (*RelocInfo->Relocs)); + RelocInfo->Relocs = AllocateZeroPool (ToolRelocsSize); if (RelocInfo->Relocs == NULL) { fprintf (stderr, "ImageTool: Could not allocate memory for Relocs[]\n"); - return false; + return RETURN_OUT_OF_RESOURCES; } TopOfRelocDir = RelocBlockRva + RelocDirSize; @@ -65,7 +80,7 @@ ScanPeGetRelocInfo ( ); if (Overflow) { fprintf (stderr, "ImageTool: Overflow during TopOfRelocDir calculation\n"); - return false; + return RETURN_VOLUME_CORRUPTED; } // // Apply all Base Relocations of the Image. @@ -83,7 +98,7 @@ ScanPeGetRelocInfo ( ); if (Overflow) { fprintf (stderr, "ImageTool: Overflow during SizeOfRelocs calculation\n"); - return false; + return RETURN_VOLUME_CORRUPTED; } // // Verify the Base Relocation Block is in bounds of the Relocation @@ -91,7 +106,7 @@ ScanPeGetRelocInfo ( // if (SizeOfRelocs > RelocBlockRvaMax - RelocBlockRva) { fprintf (stderr, "ImageTool: Base Relocation Block is out of bounds of the Relocation Directory\n"); - return false; + return RETURN_VOLUME_CORRUPTED; } // // This arithmetic cannot overflow because we know @@ -113,7 +128,6 @@ ScanPeGetRelocInfo ( RelocType = IMAGE_RELOC_TYPE (RelocBlock->Relocations[RelocIndex]); RelocOffset = IMAGE_RELOC_OFFSET (RelocBlock->Relocations[RelocIndex]); - // FIXME: Make separate functions for UE switch (RelocType) { case EFI_IMAGE_REL_BASED_ABSOLUTE: continue; @@ -123,7 +137,7 @@ ScanPeGetRelocInfo ( break; default: fprintf (stderr, "ImageTool: Unknown RelocType = 0x%x\n", RelocType); - return false; + return RETURN_UNSUPPORTED; } RelocInfo->Relocs[RelocInfo->NumRelocs].Target = RelocBlock->VirtualAddress + RelocOffset; @@ -140,13 +154,13 @@ ScanPeGetRelocInfo ( // if (RelocBlockRva != TopOfRelocDir) { fprintf (stderr, "ImageTool: Relocation Directory size does not match the contained data\n"); - return false; + return RETURN_VOLUME_CORRUPTED; } - return true; + return RETURN_SUCCESS; } -bool +RETURN_STATUS ScanPeGetSegmentInfo ( OUT image_tool_segment_info_t *SegmentInfo, IN PE_COFF_LOADER_IMAGE_CONTEXT *Context @@ -158,15 +172,19 @@ ScanPeGetSegmentInfo ( const char *ImageBuffer; uint32_t Index; - assert (SegmentInfo != NULL); - assert (Context != NULL); - NumSections = PeCoffGetSectionTable (Context, &Section); - SegmentInfo->Segments = calloc (NumSections, sizeof (*SegmentInfo->Segments)); + STATIC_ASSERT ( + sizeof (*SegmentInfo->Segments) <= sizeof (*Section), + "The multiplication below may overflow." + ); + + SegmentInfo->Segments = AllocateZeroPool ( + NumSections * sizeof (*SegmentInfo->Segments) + ); if (SegmentInfo->Segments == NULL) { fprintf (stderr, "ImageTool: Could not allocate memory for Segments[]\n"); - return false; + return RETURN_OUT_OF_RESOURCES; } ImageBuffer = (char *)PeCoffLoaderGetImageAddress (Context); @@ -184,112 +202,35 @@ ScanPeGetSegmentInfo ( && memcmp (Section->Name, PE_COFF_SECT_NAME_RELOC, sizeof (Section->Name)) != 0 && memcmp (Section->Name, PE_COFF_SECT_NAME_RESRC, sizeof (Section->Name)) != 0 && memcmp (Section->Name, PE_COFF_SECT_NAME_DEBUG, sizeof (Section->Name)) != 0) { - ImageSegment->Name = calloc (1, sizeof (Section->Name)); + ImageSegment->Name = AllocateCopyPool ( + sizeof (Section->Name), + Section->Name + ); if (ImageSegment->Name == NULL) { fprintf (stderr, "ImageTool: Could not allocate memory for Segment Name\n"); - return false; + return RETURN_OUT_OF_RESOURCES; } - memmove (ImageSegment->Name, Section->Name, sizeof (Section->Name)); - ImageSegment->ImageAddress = Section->VirtualAddress; ImageSegment->ImageSize = ALIGN_VALUE (Section->VirtualSize, SegmentInfo->SegmentAlignment); ImageSegment->Read = (Section->Characteristics & EFI_IMAGE_SCN_MEM_READ) != 0; ImageSegment->Write = (Section->Characteristics & EFI_IMAGE_SCN_MEM_WRITE) != 0; ImageSegment->Execute = (Section->Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) != 0; - ImageSegment->Data = malloc (ImageSegment->ImageSize); + ImageSegment->Data = AllocateCopyPool ( + ImageSegment->ImageSize, + ImageBuffer + Section->VirtualAddress + ); if (ImageSegment->Data == NULL) { fprintf (stderr, "ImageTool: Could not allocate memory for Segment Data\n"); - free (ImageSegment->Name); - return false; + FreePool (ImageSegment->Name); + return RETURN_OUT_OF_RESOURCES; } - memmove ( - ImageSegment->Data, - ImageBuffer + Section->VirtualAddress, - ImageSegment->ImageSize - ); - ++SegmentInfo->NumSegments; ++ImageSegment; } } - return true; -} - -bool -ScanPeGetDebugInfo ( - OUT image_tool_debug_info_t *DebugInfo, - IN PE_COFF_LOADER_IMAGE_CONTEXT *Context - ) -{ - const CHAR8 *PdbPath; - UINT32 PdbPathSize; - RETURN_STATUS Status; - - assert (DebugInfo != NULL); - assert (Context != NULL); - - Status = PeCoffGetPdbPath (Context, &PdbPath, &PdbPathSize); - if (Status == RETURN_NOT_FOUND) { - return true; - } - if (RETURN_ERROR (Status)) { - fprintf (stderr, "ImageTool: Could not get PdbPath\n"); - return false; - } - - DebugInfo->SymbolsPath = malloc (PdbPathSize); - if (DebugInfo->SymbolsPath == NULL) { - fprintf (stderr, "ImageTool: Could not allocate memory for SymbolsPath\n"); - return false; - } - - memmove (DebugInfo->SymbolsPath, PdbPath, PdbPathSize); - - assert (PdbPathSize >= 1); - assert (DebugInfo->SymbolsPath[PdbPathSize - 1] == '\0'); - - DebugInfo->SymbolsPathLen = PdbPathSize - 1; - - return true; -} - -bool -ScanPeGetHiiInfo ( - OUT image_tool_hii_info_t *HiiInfo, - IN PE_COFF_LOADER_IMAGE_CONTEXT *Context - ) -{ - UINT32 HiiRva; - UINT32 HiiSize; - RETURN_STATUS Status; - const char *ImageBuffer; - - assert (HiiInfo != NULL); - assert (Context != NULL); - - Status = PeCoffGetHiiDataRva (Context, &HiiRva, &HiiSize); - if (Status == RETURN_NOT_FOUND) { - return true; - } - if (RETURN_ERROR (Status)) { - fprintf (stderr, "ImageTool: Could not get HiiRva\n"); - return false; - } - - HiiInfo->Data = calloc (1, HiiSize); - if (HiiInfo->Data == NULL) { - fprintf (stderr, "ImageTool: Could not allocate memory for HiiInfo Data\n"); - return false; - } - - ImageBuffer = (char *)PeCoffLoaderGetImageAddress (Context); - - memmove (HiiInfo->Data, ImageBuffer + HiiRva, HiiSize); - HiiInfo->DataSize = HiiSize; - - return true; + return RETURN_SUCCESS; } diff --git a/BaseTools/ImageTool/PeScan.h b/BaseTools/ImageTool/PeScan.h index bdcf2078f8..2a63ab9be0 100644 --- a/BaseTools/ImageTool/PeScan.h +++ b/BaseTools/ImageTool/PeScan.h @@ -8,13 +8,13 @@ #include "ImageTool.h" -bool +RETURN_STATUS ScanPeGetRelocInfo ( OUT image_tool_reloc_info_t *RelocInfo, IN PE_COFF_LOADER_IMAGE_CONTEXT *Context ); -bool +RETURN_STATUS ScanPeGetSegmentInfo ( OUT image_tool_segment_info_t *SegmentInfo, IN PE_COFF_LOADER_IMAGE_CONTEXT *Context diff --git a/BaseTools/ImageTool/UefiImageScan.c b/BaseTools/ImageTool/UefiImageScan.c index 5180be4407..65b7903bff 100644 --- a/BaseTools/ImageTool/UefiImageScan.c +++ b/BaseTools/ImageTool/UefiImageScan.c @@ -25,8 +25,6 @@ ScanUefiImageGetHeaderInfo ( HeaderInfo->EntryPointAddress = UefiImageGetEntryPointAddress (Context); HeaderInfo->Machine = UefiImageGetMachine (Context); HeaderInfo->Subsystem = UefiImageGetSubsystem (Context); - // FIXME: - HeaderInfo->IsXip = true; Status = UefiImageGetFixedAddress (Context, &Address); if (!RETURN_ERROR (Status)) { @@ -47,7 +45,7 @@ ScanUefiImageGetHeaderInfo ( } static -bool +RETURN_STATUS ScanUefiImageGetRelocInfo ( OUT image_tool_reloc_info_t *RelocInfo, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context @@ -55,9 +53,6 @@ ScanUefiImageGetRelocInfo ( { UINT8 FormatIndex; - assert (RelocInfo != NULL); - assert (Context != NULL); - FormatIndex = UefiImageGetFormat (Context); RelocInfo->RelocsStripped = UefiImageGetRelocsStripped (Context); @@ -71,11 +66,11 @@ ScanUefiImageGetRelocInfo ( "ImageTool: Unsupported UefiImage format %u\n", FormatIndex ); - return false; + return RETURN_UNSUPPORTED; } static -bool +RETURN_STATUS ScanUefiImageGetSegmentInfo ( OUT image_tool_segment_info_t *SegmentInfo, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context @@ -83,9 +78,6 @@ ScanUefiImageGetSegmentInfo ( { UINT8 FormatIndex; - assert (SegmentInfo != NULL); - assert (Context != NULL); - FormatIndex = UefiImageGetFormat (Context); SegmentInfo->SegmentAlignment = UefiImageGetSegmentAlignment (Context); @@ -99,10 +91,10 @@ ScanUefiImageGetSegmentInfo ( "ImageTool: Unsupported UefiImage format %u\n", FormatIndex ); - return false; + return RETURN_UNSUPPORTED; } -bool +RETURN_STATUS ScanUefiImageGetDebugInfo ( OUT image_tool_debug_info_t *DebugInfo, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context @@ -112,35 +104,31 @@ ScanUefiImageGetDebugInfo ( const CHAR8 *SymbolsPath; UINT32 SymbolsPathSize; - assert (DebugInfo != NULL); - assert (Context != NULL); - Status = UefiImageGetSymbolsPath (Context, &SymbolsPath, &SymbolsPathSize); - if (Status == RETURN_NOT_FOUND) { - return true; + if (Status == RETURN_NOT_FOUND || Status == RETURN_UNSUPPORTED) { + return RETURN_SUCCESS; } if (RETURN_ERROR (Status)) { fprintf (stderr, "ImageTool: Could not get SymbolsPath\n"); - return false; + return Status; } assert (SymbolsPathSize >= 1); - DebugInfo->SymbolsPath = malloc (SymbolsPathSize + 1); + DebugInfo->SymbolsPath = AllocateCopyPool (SymbolsPathSize, SymbolsPath); if (DebugInfo->SymbolsPath == NULL) { fprintf (stderr, "ImageTool: Could not allocate memory for SymbolsPath\n"); - return false; + return RETURN_OUT_OF_RESOURCES; } - memmove (DebugInfo->SymbolsPath, SymbolsPath, SymbolsPathSize); assert (DebugInfo->SymbolsPath[SymbolsPathSize - 1] == '\0'); DebugInfo->SymbolsPathLen = SymbolsPathSize - 1; - return true; + return RETURN_SUCCESS; } -bool +RETURN_STATUS ScanUefiImageGetHiiInfo ( OUT image_tool_hii_info_t *HiiInfo, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context @@ -151,30 +139,26 @@ ScanUefiImageGetHiiInfo ( UINT32 HiiSize; const char *ImageBuffer; - assert (HiiInfo != NULL); - assert (Context != NULL); - Status = UefiImageGetHiiDataRva (Context, &HiiRva, &HiiSize); if (Status == RETURN_NOT_FOUND) { - return true; + return RETURN_SUCCESS; } if (RETURN_ERROR (Status)) { fprintf (stderr, "ImageTool: Malformed HII data\n"); - return false; + return Status; } - HiiInfo->Data = malloc (HiiSize); + ImageBuffer = (char *)UefiImageLoaderGetImageAddress (Context); + + HiiInfo->Data = AllocateCopyPool (HiiSize, ImageBuffer + HiiRva); if (HiiInfo->Data == NULL) { fprintf (stderr, "ImageTool: Could not allocate memory for HiiInfo Data\n"); - return false; + return RETURN_OUT_OF_RESOURCES; } - ImageBuffer = (char *)UefiImageLoaderGetImageAddress (Context); - - memmove (HiiInfo->Data, ImageBuffer + HiiRva, HiiSize); HiiInfo->DataSize = HiiSize; - return true; + return RETURN_SUCCESS; } RETURN_STATUS @@ -194,7 +178,6 @@ ToolContextConstructUefiImage ( void *Destination; bool Success; - assert (Image != NULL); assert (File != NULL || FileSize == 0); if (FileSize > MAX_UINT32) { @@ -229,7 +212,7 @@ ToolContextConstructUefiImage ( if (RETURN_ERROR (Status)) { fprintf (stderr, "ImageTool: Could not Load Image\n"); FreeAlignedPages (Destination, DestinationPages); - return RETURN_VOLUME_CORRUPTED; + return Status; } memset (Image, 0, sizeof (*Image)); @@ -237,36 +220,41 @@ ToolContextConstructUefiImage ( Success = ScanUefiImageGetHeaderInfo (&Image->HeaderInfo, &Context); if (!Success) { fprintf (stderr, "ImageTool: Could not retrieve header info\n"); + ToolImageDestruct (Image); FreeAlignedPages (Destination, DestinationPages); return RETURN_VOLUME_CORRUPTED; } - Success = ScanUefiImageGetSegmentInfo (&Image->SegmentInfo, &Context); - if (!Success) { + Status = ScanUefiImageGetSegmentInfo (&Image->SegmentInfo, &Context); + if (RETURN_ERROR (Status)) { fprintf (stderr, "ImageTool: Could not retrieve segment info\n"); + ToolImageDestruct (Image); FreeAlignedPages (Destination, DestinationPages); - return RETURN_VOLUME_CORRUPTED; + return Status; } - Success = ScanUefiImageGetRelocInfo (&Image->RelocInfo, &Context); - if (!Success) { + Status = ScanUefiImageGetRelocInfo (&Image->RelocInfo, &Context); + if (RETURN_ERROR (Status)) { fprintf (stderr, "ImageTool: Could not retrieve reloc info\n"); + ToolImageDestruct (Image); FreeAlignedPages (Destination, DestinationPages); - return RETURN_VOLUME_CORRUPTED; + return Status; } - Success = ScanUefiImageGetHiiInfo (&Image->HiiInfo, &Context); - if (!Success) { + Status = ScanUefiImageGetHiiInfo (&Image->HiiInfo, &Context); + if (RETURN_ERROR (Status)) { fprintf (stderr, "ImageTool: Could not retrieve HII info\n"); + ToolImageDestruct (Image); FreeAlignedPages (Destination, DestinationPages); - return RETURN_VOLUME_CORRUPTED; + return Status; } - Success = ScanUefiImageGetDebugInfo (&Image->DebugInfo, &Context); - if (!Success) { + Status = ScanUefiImageGetDebugInfo (&Image->DebugInfo, &Context); + if (RETURN_ERROR (Status)) { fprintf (stderr, "ImageTool: Could not retrieve debug info\n"); + ToolImageDestruct (Image); FreeAlignedPages (Destination, DestinationPages); - return RETURN_VOLUME_CORRUPTED; + return Status; } FreeAlignedPages (Destination, DestinationPages); diff --git a/BaseTools/Source/C/Common/GNUmakefile b/BaseTools/Source/C/Common/GNUmakefile index 1166736e43..5ec953cda0 100644 --- a/BaseTools/Source/C/Common/GNUmakefile +++ b/BaseTools/Source/C/Common/GNUmakefile @@ -42,6 +42,7 @@ OBJECTS += \ $(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit64.o \ $(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmitCommon.o \ $(EDK2_OBJPATH)/BaseTools/ImageTool/BinEmit.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/DynamicBuffer.o \ $(EDK2_OBJPATH)/OpenCorePkg/User/Library/UserFile.o OBJECTS += \ diff --git a/BaseTools/Source/C/Common/Makefile b/BaseTools/Source/C/Common/Makefile index 03a9e73539..db0198c640 100644 --- a/BaseTools/Source/C/Common/Makefile +++ b/BaseTools/Source/C/Common/Makefile @@ -42,6 +42,7 @@ OBJECTS = $(OBJECTS) \ $(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit64.obj \ $(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmitCommon.obj \ $(EDK2_OBJPATH)\BaseTools\ImageTool\BinEmit.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\DynamicBuffer.obj \ $(EDK2_OBJPATH)\OpenCorePkg\User\Library\UserFile.obj OBJECTS = $(OBJECTS) \ diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 2f97c26ef7..ef986d09e1 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -3741,6 +3741,7 @@ Routine Description: true, NewBaseAddress, NULL, + TRUE, Strip, FALSE ); diff --git a/BaseTools/Source/C/VolInfo/VolInfo.c b/BaseTools/Source/C/VolInfo/VolInfo.c index d36b1c83e9..1edc2e375d 100644 --- a/BaseTools/Source/C/VolInfo/VolInfo.c +++ b/BaseTools/Source/C/VolInfo/VolInfo.c @@ -1456,6 +1456,7 @@ Routine Description: true, NewBaseAddress, NULL, + TRUE, FALSE, TRUE ); diff --git a/BaseTools/Source/Python/GenFds/DataSection.py b/BaseTools/Source/Python/GenFds/DataSection.py index 61d162f31b..365f9695bc 100644 --- a/BaseTools/Source/Python/GenFds/DataSection.py +++ b/BaseTools/Source/Python/GenFds/DataSection.py @@ -95,6 +95,7 @@ def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = No GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict), + Xip=True, Strip=True, IsMakefile = IsMakefile ) diff --git a/BaseTools/Source/Python/GenFds/EfiSection.py b/BaseTools/Source/Python/GenFds/EfiSection.py index 809260651f..6816aeb129 100644 --- a/BaseTools/Source/Python/GenFds/EfiSection.py +++ b/BaseTools/Source/Python/GenFds/EfiSection.py @@ -290,6 +290,7 @@ def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = Non GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, File, + Xip=True, Strip=True, IsMakefile = IsMakefile ) diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py index 6fdb295441..1c78b71886 100644 --- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -793,6 +793,7 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, File, + Xip=True, Strip=True, IsMakefile=IsMakefile ) @@ -827,6 +828,7 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, GenSecInputFile, + Xip=True, Strip=True, IsMakefile=IsMakefile ) diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py index 68faace90f..6c78a67ca6 100644 --- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py +++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py @@ -607,7 +607,7 @@ def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Ca GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV") @staticmethod - def GenerateFirmwareImage(Output, Input, Format="Auto", Strip=False, IsMakefile=False): + def GenerateFirmwareImage(Output, Input, Format="Auto", Xip=False, Strip=False, IsMakefile=False): if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile: return GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) @@ -615,6 +615,8 @@ def GenerateFirmwareImage(Output, Input, Format="Auto", Strip=False, IsMakefile= Cmd = ["ImageTool GenImage"] if Format != "Auto": Cmd += ("-c", Format) + if Xip: + Cmd.append("-x") if Strip: Cmd.append("-s") Cmd += ("-o", Output, Input) diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py index 7ec6abdf18..1ca78bfc52 100644 --- a/BaseTools/Source/Python/build/BuildReport.py +++ b/BaseTools/Source/Python/build/BuildReport.py @@ -642,7 +642,7 @@ def GenerateReport(self, File, GlobalPcdReport, GlobalPredictionReport, GlobalDe if os.path.isfile(DefaultEFIfile): Tempfile = os.path.join(OutputDir, self.ModuleName + "_hash.tmp") # rebase the efi image since its base address may not zero - cmd = ["ImageTool GenImage -b 0 -o", Tempfile, DefaultEFIfile] + cmd = ["ImageTool GenImage -x -b 0 -o", Tempfile, DefaultEFIfile] try: PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) except Exception as X: diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py index ac2c8d6bc4..65ddf7c775 100755 --- a/BaseTools/Source/Python/build/build.py +++ b/BaseTools/Source/Python/build/build.py @@ -1542,16 +1542,16 @@ def _RebaseModule (self, MapBuffer, BaseAddress, ModuleList, AddrIsOffset = True # # Update Image to new BaseAddress by ImageTool tool # - LaunchCommand(["ImageTool", "GenImage", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir) - LaunchCommand(["ImageTool", "GenImage", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir) + LaunchCommand(["ImageTool", "GenImage", "-x", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir) + LaunchCommand(["ImageTool", "GenImage", "-x", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir) ## for SMM module in SMRAM, the SMRAM will be allocated from base to top. else: BaseAddress = AlignUp(BaseAddress, ModuleInfo.Image.SectionAlignment) # # Set new address to the section header only for SMM driver. # - LaunchCommand(["ImageTool", "GenImage", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir) - LaunchCommand(["ImageTool", "GenImage", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir) + LaunchCommand(["ImageTool", "GenImage", "-x", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir) + LaunchCommand(["ImageTool", "GenImage", "-x", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir) # # Collect function address from Map file # diff --git a/MdePkg/Library/BaseUefiImageLib/PeSupport.c b/MdePkg/Library/BaseUefiImageLib/PeSupport.c index 0698a60461..b03b85ee25 100644 --- a/MdePkg/Library/BaseUefiImageLib/PeSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/PeSupport.c @@ -96,10 +96,10 @@ UefiImageLoaderGetRuntimeContextSizePe ( RETURN_STATUS UefiImageRelocateImagePe ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINT64 BaseAddress, - OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, - IN UINT32 RuntimeContextSize + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINT64 BaseAddress, + OUT VOID *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize ) { return PeCoffRelocateImage ( diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h b/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h index f9e96287bf..efe7048891 100644 --- a/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h +++ b/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h @@ -71,10 +71,10 @@ RETURN_STATUS typedef RETURN_STATUS (*UEFI_IMAGE_RELOCARE_IMAGE) ( - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINT64 BaseAddress, - OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, - IN UINT32 RuntimeContextSize + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINT64 BaseAddress, + OUT VOID *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize ); typedef diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c b/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c index 1803b49035..6e9eaa9364 100644 --- a/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c +++ b/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c @@ -285,12 +285,16 @@ UefiImageRelocateImage ( ) { RETURN_STATUS Status; + VOID *FormatContext; + UINT32 FormatContextSize; + FormatContext = RuntimeContext; + FormatContextSize = RuntimeContextSize; if (RuntimeContext != NULL) { *(UINT64 *)RuntimeContext = Context->FormatIndex; - RuntimeContext = (UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *)((UINT64 *)RuntimeContext + 1); - ASSERT (RuntimeContextSize >= 8); - RuntimeContextSize -= 8; + FormatContext = (VOID *)((UINT64 *)RuntimeContext + 1); + ASSERT (FormatContextSize >= 8); + FormatContextSize -= 8; } UEFI_IMAGE_EXEC ( @@ -299,8 +303,8 @@ UefiImageRelocateImage ( RelocateImage, Context, BaseAddress, - RuntimeContext, - RuntimeContextSize + FormatContext, + FormatContextSize ); if (!RETURN_ERROR (Status)) { From 1fef202932ded6f8d6fc1b1a1d089b0248e3fa1b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 15 Dec 2023 16:34:17 +0300 Subject: [PATCH 080/341] MdePkg/UefiImageLib: Introduce DebugAddress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marvin Häuser --- .../DebugUefiImageExtraActionLib.c | 14 +-- .../AArch64/DefaultExceptionHandler.c | 18 ++-- .../Arm/DefaultExceptionHandler.c | 8 +- .../DefaultExceptionHandlerUefi.c | 19 ++-- BaseTools/ImageTool/PeEmit.c | 6 +- EmbeddedPkg/GdbStub/GdbStub.c | 8 +- EmulatorPkg/Unix/Host/Host.c | 14 +-- .../MemoryProfileInfo/MemoryProfileInfo.c | 7 +- MdeModulePkg/Core/Dxe/DxeMain.h | 11 +-- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 1 - MdeModulePkg/Core/Dxe/Image/Image.c | 2 +- .../Core/Dxe/Mem/MemoryProfileRecord.c | 1 + MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c | 93 ++++++++++--------- MdeModulePkg/Core/Pei/Image/Image.c | 12 ++- MdeModulePkg/Core/PiSmmCore/DebugImageInfo.c | 45 ++++----- MdeModulePkg/Core/PiSmmCore/Dispatcher.c | 1 - MdeModulePkg/Core/PiSmmCore/PiSmmCore.c | 1 - MdeModulePkg/Core/PiSmmCore/PiSmmCore.h | 11 +-- MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c | 3 + .../Core/PiSmmCore/SmramProfileRecord.c | 6 +- MdeModulePkg/Include/Guid/MemoryProfile.h | 2 + .../Universal/EbcDxe/EbcDebugger/EdbSymbol.c | 6 +- MdePkg/Include/Guid/DebugImageInfoTable.h | 51 ++++++++-- MdePkg/Include/IndustryStandard/PeImage.h | 2 +- MdePkg/Include/Library/UefiImageLib.h | 5 + MdePkg/Library/BaseUefiImageLib/PeSupport.c | 9 ++ .../BaseUefiImageLib/UefiImageFormat.h | 7 ++ .../Library/BaseUefiImageLib/UefiImageLib.c | 17 ++++ .../DpDynamicCommand/DpUtilities.c | 10 +- .../UefiImageExtraActionLib.c | 10 +- .../CpuExceptionCommon.c | 8 +- .../CpuExceptionCommon.h | 1 + .../CpuExceptionHandlerLib/DxeException.c | 22 +++-- .../CpuExceptionHandlerLib/PeiCpuException.c | 2 + .../SecPeiCpuException.c | 1 + .../CpuExceptionHandlerLib/SmmException.c | 22 +++-- UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c | 16 ++-- 37 files changed, 294 insertions(+), 178 deletions(-) diff --git a/ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.c b/ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.c index db74ff779b..2ffcba1646 100644 --- a/ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.c +++ b/ArmPkg/Library/DebugUefiImageExtraActionLib/DebugUefiImageExtraActionLib.c @@ -84,19 +84,19 @@ UefiImageLoaderRelocateImageExtraAction ( #ifdef __CC_ARM #if (__ARMCC_VERSION < 500000) // Print out the command for the RVD debugger to load symbols for this image - DEBUG ((DEBUG_LOAD | DEBUG_INFO, "load /a /ni /np %a &0x%p\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), UefiImageLoaderGetImageAddress (ImageContext))); + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "load /a /ni /np %a &0x%p\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), UefiImageLoaderGetDebugAddress (ImageContext))); #else // Print out the command for the DS-5 to load symbols for this image - DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a -o 0x%p\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), UefiImageLoaderGetImageAddress (ImageContext))); + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a -o 0x%p\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), UefiImageLoaderGetDebugAddress (ImageContext))); #endif #elif __GNUC__ // This may not work correctly if you generate PE/COFF directly as then the Offset would not be required - DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a -o 0x%p\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), UefiImageLoaderGetImageAddress (ImageContext))); + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "add-symbol-file %a -o 0x%p\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), UefiImageLoaderGetDebugAddress (ImageContext))); #else - DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Loading driver at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)UefiImageLoaderGetImageAddress (ImageContext), FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext)))); + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Loading driver at 0x%11p DebugBase=0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)UefiImageLoaderGetImageAddress (ImageContext), (VOID *)(UINTN)UefiImageLoaderGetDebugAddress (ImageContext), FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext)))); #endif } else { - DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Loading driver at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)UefiImageLoaderGetImageAddress (ImageContext), FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext)))); + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Loading driver at 0x%11p DebugBase=0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)UefiImageLoaderGetImageAddress (ImageContext), (VOID *)(UINTN)UefiImageLoaderGetDebugAddress (ImageContext), FUNCTION_ENTRY_POINT (UefiImageLoaderGetImageEntryPoint (ImageContext)))); } } @@ -131,11 +131,11 @@ UefiImageLoaderUnloadImageExtraAction ( DEBUG ((DEBUG_LOAD | DEBUG_INFO, "unload symbols_only %a\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)))); #elif __GNUC__ // This may not work correctly if you generate PE/COFF directly as then the Offset would not be required - DEBUG ((DEBUG_LOAD | DEBUG_INFO, "remove-symbol-file %a 0x%08x\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), (UINTN)UefiImageLoaderGetImageAddress (ImageContext))); + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "remove-symbol-file %a 0x%08x\n", DeCygwinPathIfNeeded (PdbPath, Temp, sizeof (Temp)), (UINTN)UefiImageLoaderGetDebugAddress (ImageContext))); #else DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Unloading %a\n", PdbPath)); #endif } else { - DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Unloading driver at 0x%11p\n", (VOID *)(UINTN)UefiImageLoaderGetImageAddress (ImageContext))); + DEBUG ((DEBUG_LOAD | DEBUG_INFO, "Unloading driver at 0x%11p DebugBase=0x%11p\n", (VOID *)(UINTN)UefiImageLoaderGetImageAddress (ImageContext), (VOID *)(UINTN)UefiImageLoaderGetDebugAddress (ImageContext))); } } diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index 93814bb266..a5f04c04ce 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -38,7 +38,8 @@ STATIC BOOLEAN mRecursiveException; CONST CHAR8 * GetImageName ( IN UINTN FaultAddress, - OUT UINTN *ImageBase + OUT UINTN *ImageBase, + OUT UINTN *DebugBase ); STATIC @@ -211,18 +212,20 @@ DefaultExceptionHandler ( DEBUG_CODE_BEGIN (); CONST CHAR8 *Pdb, *PrevPdb; UINTN ImageBase; + UINTN DebugBase; UINT64 *Fp; UINT64 RootFp[2]; UINTN Idx; - PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase); + PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase, &DebugBase); if (Pdb != NULL) { DEBUG (( DEBUG_ERROR, - "PC 0x%012lx (0x%012lx+0x%08x) [ 0] %a\n", + "PC 0x%012lx (0x%012lx+0x%08x) (DebugBase=%012lx) [ 0] %a\n", SystemContext.SystemContextAArch64->ELR, ImageBase, SystemContext.SystemContextAArch64->ELR - ImageBase, + DebugBase, BaseName (Pdb) )); } else { @@ -240,7 +243,7 @@ DefaultExceptionHandler ( } for (Fp = RootFp; Fp[0] != 0; Fp = (UINT64 *)Fp[0]) { - Pdb = GetImageName (Fp[1], &ImageBase); + Pdb = GetImageName (Fp[1], &ImageBase, &DebugBase); if (Pdb != NULL) { if (Pdb != PrevPdb) { Idx++; @@ -249,10 +252,11 @@ DefaultExceptionHandler ( DEBUG (( DEBUG_ERROR, - "PC 0x%012lx (0x%012lx+0x%08x) [% 2d] %a\n", + "PC 0x%012lx (0x%012lx+0x%08x) (DebugBase=0x%012lx) [% 2d] %a\n", Fp[1], ImageBase, Fp[1] - ImageBase, + DebugBase, Idx, BaseName (Pdb) )); @@ -261,14 +265,14 @@ DefaultExceptionHandler ( } } - PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase); + PrevPdb = Pdb = GetImageName (SystemContext.SystemContextAArch64->ELR, &ImageBase, &DebugBase); if (Pdb != NULL) { DEBUG ((DEBUG_ERROR, "\n[ 0] %a\n", Pdb)); } Idx = 0; for (Fp = RootFp; Fp[0] != 0; Fp = (UINT64 *)Fp[0]) { - Pdb = GetImageName (Fp[1], &ImageBase); + Pdb = GetImageName (Fp[1], &ImageBase, &DebugBase); if ((Pdb != NULL) && (Pdb != PrevPdb)) { DEBUG ((DEBUG_ERROR, "[% 2d] %a\n", ++Idx, Pdb)); PrevPdb = Pdb; diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c index d05b2f7d80..eb9b4ee7b7 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c @@ -55,7 +55,8 @@ STATIC CONST CPSR_CHAR mCpsrChar[] = { CONST CHAR8 * GetImageName ( IN UINTN FaultAddress, - OUT UINTN *ImageBase + OUT UINTN *ImageBase, + OUT UINTN *DebugBase ); /** @@ -225,6 +226,7 @@ DefaultExceptionHandler ( DEBUG_CODE_BEGIN (); CONST CHAR8 *Pdb; UINT32 ImageBase; + UINT32 DebugBase; UINT32 Offset; CHAR8 CpsrStr[CPSR_STRING_SIZE]; // char per bit. Lower 5-bits are mode // that is a 3 char string @@ -232,7 +234,7 @@ DefaultExceptionHandler ( CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr); DEBUG ((DEBUG_ERROR, "%a\n", CpsrStr)); - Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase); + Pdb = GetImageName (SystemContext.SystemContextArm->PC, &ImageBase, &DebugBase); Offset = SystemContext.SystemContextArm->PC - ImageBase; if (Pdb != NULL) { DEBUG ((DEBUG_ERROR, "%a\n", Pdb)); @@ -247,7 +249,7 @@ DefaultExceptionHandler ( // // FIXME: Used to have (ELF or Mach-O offset) 0x%x // Substitute with .text address (better + may be needed for GDB symbols?) - DEBUG ((EFI_D_ERROR, "loaded at 0x%08x (PE/COFF offset) 0x%x", ImageBase, Offset)); + DEBUG ((EFI_D_ERROR, "loaded at 0x%08x (DebugBase=0x%08x) (PE/COFF offset) 0x%x", ImageBase, DebugBase, Offset)); } DEBUG_CODE_END (); diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c index 290827a99b..dc049ae6b4 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerUefi.c @@ -19,6 +19,7 @@ @param FaultAddress Address to find PE/COFF image for. @param ImageBase Return load address of found image + @param ImageBase Return debug address of found image @retval NULL FaultAddress not in a loaded PE/COFF image. @retval Path and file name of PE/COFF image. @@ -27,7 +28,8 @@ CONST CHAR8 * GetImageName ( IN UINTN FaultAddress, - OUT UINTN *ImageBase + OUT UINTN *ImageBase, + OUT UINTN *DebugBase ) { EFI_STATUS Status; @@ -48,15 +50,16 @@ GetImageName ( Address = (CHAR8 *)(UINTN)FaultAddress; for (Entry = 0; Entry < DebugTableHeader->TableSize; Entry++, DebugTable++) { - if (DebugTable->NormalImage != NULL) { - if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && - (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) + if (DebugTable->NormalImage2 != NULL) { + if ((DebugTable->NormalImage2->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL2) && + (DebugTable->NormalImage2->LoadedImageProtocolInstance != NULL)) { - if ((Address >= (CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase) && - (Address <= ((CHAR8 *)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase + DebugTable->NormalImage->LoadedImageProtocolInstance->ImageSize))) + if ((Address >= (CHAR8 *)DebugTable->NormalImage2->LoadedImageProtocolInstance->ImageBase) && + (Address <= ((CHAR8 *)DebugTable->NormalImage2->LoadedImageProtocolInstance->ImageBase + DebugTable->NormalImage2->LoadedImageProtocolInstance->ImageSize))) { - *ImageBase = (UINTN)DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase; - return DebugTable->NormalImage->PdbPath; + *ImageBase = (UINTN)DebugTable->NormalImage2->LoadedImageProtocolInstance->ImageBase; + *DebugBase = (UINTN)DebugTable->NormalImage2->DebugBase; + return DebugTable->NormalImage2->PdbPath; } } } diff --git a/BaseTools/ImageTool/PeEmit.c b/BaseTools/ImageTool/PeEmit.c index 910d5125a7..305f42f945 100644 --- a/BaseTools/ImageTool/PeEmit.c +++ b/BaseTools/ImageTool/PeEmit.c @@ -32,12 +32,12 @@ typedef struct { EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY Nb10; } image_tool_debug_dir_t; -#define SIZE_OF_DATA_DIRECRORY \ +#define SIZE_OF_DATA_DIRECTORY \ EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES * sizeof (EFI_IMAGE_DATA_DIRECTORY) #define SIZE_OF_OPTIONAL_HEADER \ sizeof (EFI_IMAGE_NT_HEADERS) - sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR) \ - + SIZE_OF_DATA_DIRECRORY + + SIZE_OF_DATA_DIRECTORY static bool @@ -581,7 +581,7 @@ ToolImageEmitPeFile ( return false; } - SectionHeadersOffset = sizeof (*PeHdr) + SIZE_OF_DATA_DIRECRORY; + SectionHeadersOffset = sizeof (*PeHdr) + SIZE_OF_DATA_DIRECTORY; SectionHeadersSize = NumSections * sizeof (EFI_IMAGE_SECTION_HEADER); SizeOfPeHeaders = SectionHeadersOffset + SectionHeadersSize; SizeOfHeaders = sizeof (mDosHdr) + SizeOfPeHeaders; diff --git a/EmbeddedPkg/GdbStub/GdbStub.c b/EmbeddedPkg/GdbStub/GdbStub.c index 3d317cb05a..6e4f894a21 100644 --- a/EmbeddedPkg/GdbStub/GdbStub.c +++ b/EmbeddedPkg/GdbStub/GdbStub.c @@ -873,10 +873,10 @@ QxferLibrary ( if (gDebugTable != NULL) { for ( ; gEfiDebugImageTableEntry < gDebugImageTableHeader->TableSize; gEfiDebugImageTableEntry++, gDebugTable++) { - if (gDebugTable->NormalImage != NULL) { - if ((gDebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && - (gDebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) { - Pdb = gDebugTable->NormalImage->PdbPath; + if (gDebugTable->NormalImage2 != NULL) { + if ((gDebugTable->NormalImage2->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL2) && + (gDebugTable->NormalImage2->LoadedImageProtocolInstance != NULL)) { + Pdb = gDebugTable->NormalImage2->PdbPath; if (Pdb != NULL) { Size = AsciiSPrint ( gXferLibraryBuffer, diff --git a/EmulatorPkg/Unix/Host/Host.c b/EmulatorPkg/Unix/Host/Host.c index 5400f8b5ce..8142e8c5c6 100644 --- a/EmulatorPkg/Unix/Host/Host.c +++ b/EmulatorPkg/Unix/Host/Host.c @@ -892,15 +892,17 @@ PrintLoadAddress ( if (EFI_ERROR (Status)) { fprintf ( stderr, - "0x%08lx Loading NO DEBUG with entry point 0x%08lx\n", + "0x%08lx (0x%08lx) Loading NO DEBUG with entry point 0x%08lx\n", (unsigned long) UefiImageLoaderGetImageAddress (ImageContext), + (unsigned long) UefiImageLoaderGetDebugAddress (ImageContext), (unsigned long) UefiImageLoaderGetImageEntryPoint (ImageContext) ); } else { fprintf ( stderr, - "0x%08lx Loading %s with entry point 0x%08lx\n", + "0x%08lx (0x%08lx) Loading %s with entry point 0x%08lx\n", (unsigned long) UefiImageLoaderGetImageAddress (ImageContext), + (unsigned long) UefiImageLoaderGetDebugAddress (ImageContext), PdbPath, (unsigned long) UefiImageLoaderGetImageEntryPoint (ImageContext) ); @@ -952,7 +954,7 @@ GdbScriptAddImage ( if (FeaturePcdGet (PcdEmulatorLazyLoadSymbols)) { GdbTempFile = fopen (gGdbWorkingFileName, "a"); if (GdbTempFile != NULL) { - long unsigned int SymbolsAddr = (long unsigned int)UefiImageLoaderGetImageAddress (ImageContext); + long unsigned int SymbolsAddr = (long unsigned int)UefiImageLoaderGetDebugAddress (ImageContext); mScriptSymbolChangesCount++; fprintf ( GdbTempFile, @@ -963,7 +965,7 @@ GdbScriptAddImage ( ); fclose (GdbTempFile); // This is for the lldb breakpoint only - SecGdbScriptBreak (PdbPath, PdbPathSize, (long unsigned int)UefiImageLoaderGetImageAddress (ImageContext), 1); + SecGdbScriptBreak (PdbPath, PdbPathSize, (long unsigned int)UefiImageLoaderGetDebugAddress (ImageContext), 1); } else { ASSERT (FALSE); } @@ -974,7 +976,7 @@ GdbScriptAddImage ( GdbTempFile, "add-symbol-file %s -o 0x%08lx\n", PdbPath, - (long unsigned int)UefiImageLoaderGetImageAddress (ImageContext) + (long unsigned int)UefiImageLoaderGetDebugAddress (ImageContext) ); fclose (GdbTempFile); @@ -984,7 +986,7 @@ GdbScriptAddImage ( // Also used for the lldb breakpoint script. The lldb breakpoint script does // not use the file, it uses the arguments. // - SecGdbScriptBreak (PdbPath, PdbPathSize, (long unsigned int)UefiImageLoaderGetImageAddress (ImageContext), 1); + SecGdbScriptBreak (PdbPath, PdbPathSize, (long unsigned int)UefiImageLoaderGetDebugAddress (ImageContext), 1); } else { ASSERT (FALSE); } diff --git a/MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.c b/MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.c index 326603503f..80f2eb26ac 100644 --- a/MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.c +++ b/MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.c @@ -452,6 +452,7 @@ DumpMemoryProfileDriverInfo ( } Print (L" ImageBase - 0x%016lx\n", DriverInfo->ImageBase); + Print (L" DebugBase - 0x%016lx\n", DriverInfo->DebugBase); Print (L" ImageSize - 0x%016lx\n", DriverInfo->ImageSize); Print (L" EntryPoint - 0x%016lx\n", DriverInfo->EntryPoint); Print (L" ImageSubsystem - 0x%04x (%a)\n", DriverInfo->ImageSubsystem, mSubsystemString[(DriverInfo->ImageSubsystem < sizeof (mSubsystemString)/sizeof (mSubsystemString[0])) ? DriverInfo->ImageSubsystem : 0]); @@ -947,7 +948,11 @@ DumpContextSummaryData ( } if (DriverInfo->PdbStringOffset != 0) { - Print (L" (Pdb - %a)\n", (CHAR8 *)((UINTN)DriverInfo + DriverInfo->PdbStringOffset)); + Print ( + L" (DebugBase - 0x%016lx, Pdb - %a)\n", + (UINT64)DriverInfo->DebugBase, + (CHAR8 *)((UINTN)DriverInfo + DriverInfo->PdbStringOffset) + ); } else { Print (L"\n"); } diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 53df82381d..77397b6367 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2374,20 +2374,19 @@ CoreUpdateDebugTableCrc32 ( /** Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates - the table if it's not large enough to accomidate another entry. + the table if it's not large enough to accommodate another entry. - @param ImageInfoType type of debug image information @param LoadedImage pointer to the loaded image protocol for the image being loaded @param ImageHandle image handle for the image being loaded + @param ImageContext image context for the image being loaded **/ VOID CoreNewDebugImageInfoEntry ( - IN UINT32 ImageInfoType, - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_HANDLE ImageHandle, - IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN EFI_HANDLE ImageHandle, + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); /** diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index d567400e1e..83cd23363a 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -401,7 +401,6 @@ DxeMain ( // CoreInitializeDebugImageInfoTable (); CoreNewDebugImageInfoEntry ( - EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, gDxeCoreLoadedImage, gImageHandle, &ImageContext diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 34db9746ea..c12d234dfa 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1343,7 +1343,7 @@ CoreLoadImageCommon ( // Register the image in the Debug Image Info Table if the attribute is set // if ((Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION) != 0) { - CoreNewDebugImageInfoEntry (EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, &Image->Info, Image->Handle, &ImageContext); + CoreNewDebugImageInfoEntry (&Image->Info, Image->Handle, &ImageContext); } // diff --git a/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c b/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c index b67596f48e..f19a5d8abd 100644 --- a/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c +++ b/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c @@ -315,6 +315,7 @@ BuildDriverInfo ( } DriverInfo->ImageBase = UefiImageLoaderGetImageAddress (ImageContext); + DriverInfo->DebugBase = UefiImageLoaderGetDebugAddress (ImageContext); DriverInfo->ImageSize = UefiImageGetImageSize (ImageContext); DriverInfo->EntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext); DriverInfo->ImageSubsystem = UefiImageGetSubsystem (ImageContext); diff --git a/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c b/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c index 9074de9670..072d55c105 100644 --- a/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c +++ b/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c @@ -150,30 +150,29 @@ CoreUpdateDebugTableCrc32 ( /** Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates - the table if it's not large enough to accomidate another entry. + the table if it's not large enough to accommodate another entry. - @param ImageInfoType type of debug image information @param LoadedImage pointer to the loaded image protocol for the image being loaded @param ImageHandle image handle for the image being loaded + @param ImageContext image context for the image being loaded **/ VOID CoreNewDebugImageInfoEntry ( - IN UINT32 ImageInfoType, - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_HANDLE ImageHandle, - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN EFI_HANDLE ImageHandle, + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { - EFI_DEBUG_IMAGE_INFO *Table; - EFI_DEBUG_IMAGE_INFO *NewTable; - UINTN Index; - UINTN TableSize; - EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; - RETURN_STATUS Status; - CONST CHAR8 *PdbPath; - UINT32 PdbPathSize; + EFI_DEBUG_IMAGE_INFO *Table; + EFI_DEBUG_IMAGE_INFO *NewTable; + UINTN Index; + UINTN TableSize; + EFI_DEBUG_IMAGE_INFO_NORMAL2 *NormalImage2; + RETURN_STATUS Status; + CONST CHAR8 *PdbPath; + UINT32 PdbPathSize; // // Set the flag indicating that we're in the process of updating the table. @@ -187,7 +186,7 @@ CoreNewDebugImageInfoEntry ( // We still have empty entires in the Table, find the first empty entry. // Index = 0; - while (Table[Index].NormalImage != NULL) { + while (Table[Index].NormalImage2 != NULL) { Index++; } @@ -232,24 +231,26 @@ CoreNewDebugImageInfoEntry ( // // Allocate data for new entry // - NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL)); - if (NormalImage != NULL) { + NormalImage2 = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL2)); + if (NormalImage2 != NULL) { // // Update the entry // - NormalImage->ImageInfoType = (UINT32)ImageInfoType; - NormalImage->LoadedImageProtocolInstance = LoadedImage; - NormalImage->ImageHandle = ImageHandle; + NormalImage2->ImageInfoType = EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL2; + NormalImage2->LoadedImageProtocolInstance = LoadedImage; + NormalImage2->ImageHandle = ImageHandle; Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize); if (!RETURN_ERROR (Status)) { - NormalImage->PdbPath = AllocateCopyPool (PdbPathSize, PdbPath); + NormalImage2->PdbPath = AllocateCopyPool (PdbPathSize, PdbPath); } + + NormalImage2->DebugBase = UefiImageLoaderGetDebugAddress (ImageContext); // // Increase the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status. // mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED; - Table[Index].NormalImage = NormalImage; + Table[Index].NormalImage2 = NormalImage2; mDebugInfoTableHeader.TableSize++; } @@ -267,34 +268,42 @@ CoreRemoveDebugImageInfoEntry ( EFI_HANDLE ImageHandle ) { - EFI_DEBUG_IMAGE_INFO *Table; - UINTN Index; - EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; + EFI_DEBUG_IMAGE_INFO *Table; + UINTN Index; + EFI_DEBUG_IMAGE_INFO_NORMAL2 *NormalImage2; mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; Table = mDebugInfoTableHeader.EfiDebugImageInfoTable; for (Index = 0; Index < mMaxTableEntries; Index++) { - if ((Table[Index].NormalImage != NULL) && (Table[Index].NormalImage->ImageHandle == ImageHandle)) { - // - // Found a match. Free up the record, then NULL the pointer to indicate the slot - // is free. - // - NormalImage = Table[Index].NormalImage; - // - // Decrease the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status. - // - mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED; - mDebugInfoTableHeader.TableSize--; - Table[Index].NormalImage = NULL; - - if (NormalImage->PdbPath != NULL) { - FreePool (NormalImage->PdbPath); + if (Table[Index].NormalImage2 != NULL) { + if (*Table[Index].ImageInfoType != EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL2) + { + ASSERT (FALSE); + continue; } - CoreFreePool (NormalImage); - break; + if (Table[Index].NormalImage2->ImageHandle == ImageHandle) { + // + // Found a match. Free up the record, then NULL the pointer to indicate the slot + // is free. + // + NormalImage2 = Table[Index].NormalImage2; + // + // Decrease the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status. + // + mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED; + mDebugInfoTableHeader.TableSize--; + Table[Index].NormalImage2 = NULL; + + if (NormalImage2->PdbPath != NULL) { + FreePool (NormalImage2->PdbPath); + } + + CoreFreePool (NormalImage2); + break; + } } } diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c index 506e3488a0..277e2806d7 100644 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ b/MdeModulePkg/Core/Pei/Image/Image.c @@ -158,7 +158,8 @@ LoadAndRelocateUefiImage ( IN VOID *Pe32Data, IN UINT32 Pe32DataSize, OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, - OUT EFI_PHYSICAL_ADDRESS *ImageAddress + OUT EFI_PHYSICAL_ADDRESS *ImageAddress, + OUT UINTN *DebugBase ) { EFI_STATUS Status; @@ -339,6 +340,7 @@ LoadAndRelocateUefiImage ( } *ImageAddress = UefiImageLoaderGetImageAddress (ImageContext); + *DebugBase = UefiImageLoaderGetDebugAddress (ImageContext); return ReturnStatus; } @@ -457,6 +459,7 @@ PeiLoadImageLoadImage ( VOID *Pe32Data; UINT32 Pe32DataSize; EFI_PHYSICAL_ADDRESS ImageAddress; + UINTN DebugBase; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; *EntryPoint = 0; @@ -491,7 +494,8 @@ PeiLoadImageLoadImage ( Pe32Data, Pe32DataSize, &ImageContext, - &ImageAddress + &ImageAddress, + &DebugBase ); if (EFI_ERROR (Status)) { @@ -521,12 +525,12 @@ PeiLoadImageLoadImage ( // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi // if (Machine != EFI_IMAGE_MACHINE_IA64) { - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)*EntryPoint)); + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p DebugBase=0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)DebugBase, (VOID *)(UINTN)*EntryPoint)); } else { // // For IPF Image, the real entry point should be print. // - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint))); + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p DebugBase=0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)DebugBase, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint))); } // diff --git a/MdeModulePkg/Core/PiSmmCore/DebugImageInfo.c b/MdeModulePkg/Core/PiSmmCore/DebugImageInfo.c index 1812eacc2d..499e93791a 100644 --- a/MdeModulePkg/Core/PiSmmCore/DebugImageInfo.c +++ b/MdeModulePkg/Core/PiSmmCore/DebugImageInfo.c @@ -49,30 +49,29 @@ SmmInitializeDebugImageInfoTable ( /** Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates - the table if it's not large enough to accomidate another entry. + the table if it's not large enough to accommodate another entry. - @param ImageInfoType type of debug image information @param LoadedImage pointer to the loaded image protocol for the image being loaded @param ImageHandle image handle for the image being loaded + @param ImageContext image context for the image being loaded **/ VOID SmmNewDebugImageInfoEntry ( - IN UINT32 ImageInfoType, - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_HANDLE ImageHandle, - IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN EFI_HANDLE ImageHandle, + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { - EFI_DEBUG_IMAGE_INFO *Table; - EFI_DEBUG_IMAGE_INFO *NewTable; - UINTN Index; - UINTN TableSize; - EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; - RETURN_STATUS Status; - CONST CHAR8 *PdbPath; - UINT32 PdbPathSize; + EFI_DEBUG_IMAGE_INFO *Table; + EFI_DEBUG_IMAGE_INFO *NewTable; + UINTN Index; + UINTN TableSize; + EFI_DEBUG_IMAGE_INFO_NORMAL2 *NormalImage2; + RETURN_STATUS Status; + CONST CHAR8 *PdbPath; + UINT32 PdbPathSize; // // Set the flag indicating that we're in the process of updating the table. @@ -86,7 +85,7 @@ SmmNewDebugImageInfoEntry ( // We still have empty entires in the Table, find the first empty entry. // Index = 0; - while (Table[Index].NormalImage != NULL) { + while (Table[Index].NormalImage2 != NULL) { Index++; } // @@ -129,24 +128,26 @@ SmmNewDebugImageInfoEntry ( // // Allocate data for new entry // - NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL)); - if (NormalImage != NULL) { + NormalImage2 = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL2)); + if (NormalImage2 != NULL) { // // Update the entry // - NormalImage->ImageInfoType = (UINT32) ImageInfoType; - NormalImage->LoadedImageProtocolInstance = LoadedImage; - NormalImage->ImageHandle = ImageHandle; + NormalImage2->ImageInfoType = EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL2; + NormalImage2->LoadedImageProtocolInstance = LoadedImage; + NormalImage2->ImageHandle = ImageHandle; Status = UefiImageGetSymbolsPath (ImageContext, &PdbPath, &PdbPathSize); if (!RETURN_ERROR (Status)) { - NormalImage->PdbPath = AllocateCopyPool (PdbPathSize, PdbPath); + NormalImage2->PdbPath = AllocateCopyPool (PdbPathSize, PdbPath); } + + NormalImage2->DebugBase = UefiImageLoaderGetDebugAddress (ImageContext); // // Increase the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status. // mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED; - Table[Index].NormalImage = NormalImage; + Table[Index].NormalImage2 = NormalImage2; mDebugInfoTableHeader.TableSize++; } mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; diff --git a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c index 068fcee891..fb0e861463 100644 --- a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c +++ b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c @@ -571,7 +571,6 @@ SmmLoadImage ( // Register the image in the Debug Image Info Table if the attribute is set // SmmNewDebugImageInfoEntry ( - EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, &DriverEntry->SmmLoadedImage, DriverEntry->SmmImageHandle, ImageContext diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c index 9f3e9392e8..0a6d8c9aab 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c @@ -876,7 +876,6 @@ SmmCoreInstallLoadedImage ( // SmmInitializeDebugImageInfoTable (); SmmNewDebugImageInfoEntry ( - EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, &mSmmCoreDriverEntry->SmmLoadedImage, mSmmCoreDriverEntry->SmmImageHandle, &gSmmCorePrivate->PiSmmCoreImageContext diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h index 6b33a9d34a..71e826e198 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h @@ -1375,20 +1375,19 @@ SmmInitializeDebugImageInfoTable ( /** Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates - the table if it's not large enough to accomidate another entry. + the table if it's not large enough to accommodate another entry. - @param ImageInfoType type of debug image information @param LoadedImage pointer to the loaded image protocol for the image being loaded @param ImageHandle image handle for the image being loaded + @param ImageContext image context for the image being loaded **/ VOID SmmNewDebugImageInfoEntry ( - IN UINT32 ImageInfoType, - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_HANDLE ImageHandle, - IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN EFI_HANDLE ImageHandle, + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); /** diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c index 8b78d965af..b3ca963049 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c @@ -984,6 +984,7 @@ ExecuteSmmCoreFromSmram ( UINTN PageCount; EFI_IMAGE_ENTRY_POINT EntryPoint; EFI_PHYSICAL_ADDRESS LoadAddress; + UINTN DebugBase; // // Search all Firmware Volumes for a PE/COFF image in a file of type SMM_CORE @@ -1106,6 +1107,7 @@ ExecuteSmmCoreFromSmram ( Status = UefiImageLoadImageForExecution (&gSmmCorePrivate->PiSmmCoreImageContext, (VOID *)(UINTN)LoadAddress, DestinationSize, NULL, 0); if (!EFI_ERROR (Status)) { LoadAddress = UefiImageLoaderGetImageAddress (&gSmmCorePrivate->PiSmmCoreImageContext); + DebugBase = UefiImageLoaderGetDebugAddress (&gSmmCorePrivate->PiSmmCoreImageContext); // // Print debug message showing SMM Core entry point address. // @@ -1113,6 +1115,7 @@ ExecuteSmmCoreFromSmram ( gSmmCorePrivate->PiSmmCoreImageBase = LoadAddress; DEBUG ((DEBUG_INFO, "PiSmmCoreImageBase - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageBase)); + DEBUG ((DEBUG_INFO, "PiSmmCoreDebugBase - 0x%016lx\n", DebugBase)); DEBUG ((DEBUG_INFO, "PiSmmCoreImageSize - 0x%016lx\n", UefiImageGetImageSize (&gSmmCorePrivate->PiSmmCoreImageContext))); // diff --git a/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c b/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c index 1fa33efbbe..ebd7ff1c8c 100644 --- a/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c +++ b/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c @@ -267,7 +267,6 @@ BuildDriverInfo ( IN MEMORY_PROFILE_CONTEXT_DATA *ContextData, IN EFI_GUID *FileName, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, - IN EFI_PHYSICAL_ADDRESS LoadAddress, IN EFI_FV_FILETYPE FileType ) { @@ -313,7 +312,8 @@ BuildDriverInfo ( CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID)); } - DriverInfo->ImageBase = LoadAddress; + DriverInfo->ImageBase = UefiImageLoaderGetImageAddress (ImageContext); + DriverInfo->DebugBase = UefiImageLoaderGetDebugAddress (ImageContext); DriverInfo->ImageSize = UefiImageGetImageSize (ImageContext); DriverInfo->EntryPoint = UefiImageLoaderGetImageEntryPoint (ImageContext); DriverInfo->ImageSubsystem = UefiImageGetSubsystem (ImageContext); @@ -505,7 +505,6 @@ RegisterSmmCore ( ContextData, &gEfiCallerIdGuid, &gSmmCorePrivate->PiSmmCoreImageContext, - gSmmCorePrivate->PiSmmCoreImageBase, EFI_FV_FILETYPE_SMM_CORE ); if (DriverInfoData == NULL) { @@ -668,7 +667,6 @@ RegisterSmramProfileImage ( ContextData, FileName, ImageContext, - UefiImageLoaderGetImageAddress (ImageContext), EFI_FV_FILETYPE_SMM ); if (DriverInfoData == NULL) { diff --git a/MdeModulePkg/Include/Guid/MemoryProfile.h b/MdeModulePkg/Include/Guid/MemoryProfile.h index 33a033bb00..ab24477cc9 100644 --- a/MdeModulePkg/Include/Guid/MemoryProfile.h +++ b/MdeModulePkg/Include/Guid/MemoryProfile.h @@ -58,6 +58,8 @@ typedef struct { UINT64 PeakUsageByType[EfiMaxMemoryType + 2]; UINT16 PdbStringOffset; UINT8 Reserved2[6]; + // FIXME: Changes struct layout. + UINT64 DebugBase; // CHAR8 PdbString[]; } MEMORY_PROFILE_DRIVER_INFO; diff --git a/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSymbol.c b/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSymbol.c index cf8ff3d371..c00cef68b1 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSymbol.c +++ b/MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSymbol.c @@ -949,15 +949,15 @@ EdbPatchSymbolRVA ( CandidateImageBase = NULL; ImageTable = mDebuggerPrivate.DebugImageInfoTableHeader->EfiDebugImageInfoTable; for (ImageNumber = 0; ImageNumber < mDebuggerPrivate.DebugImageInfoTableHeader->TableSize; ImageNumber++) { - if (ImageTable[ImageNumber].NormalImage == NULL) { + if (ImageTable[ImageNumber].NormalImage2 == NULL) { continue; } - ImageBase = ImageTable[ImageNumber].NormalImage->LoadedImageProtocolInstance->ImageBase; + ImageBase = ImageTable[ImageNumber].NormalImage2->LoadedImageProtocolInstance->ImageBase; // // Get PDB path // - PdbPath = ImageTable[ImageNumber].NormalImage->PdbPath; + PdbPath = ImageTable[ImageNumber].NormalImage2->PdbPath; if (PdbPath == NULL) { continue; } diff --git a/MdePkg/Include/Guid/DebugImageInfoTable.h b/MdePkg/Include/Guid/DebugImageInfoTable.h index 82f337f67e..44b9fce337 100644 --- a/MdePkg/Include/Guid/DebugImageInfoTable.h +++ b/MdePkg/Include/Guid/DebugImageInfoTable.h @@ -25,7 +25,8 @@ #define EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS 0x01 #define EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED 0x02 -#define EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL 0x01 +#define EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL 0x01 +#define EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL2 0x02 typedef struct { UINT64 Signature; ///< A constant UINT64 that has the value EFI_SYSTEM_TABLE_SIGNATURE @@ -35,8 +36,8 @@ typedef struct { typedef struct { /// - /// Indicates the type of image info structure. For PE32 EFI images, - /// this is set to EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL. + /// When this debug image info structure is present, ImageInfoType is set + /// to EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL indicating a loaded PE32 EFI image. /// UINT32 ImageInfoType; /// @@ -47,12 +48,50 @@ typedef struct { /// Indicates the image handle of the associated image. /// EFI_HANDLE ImageHandle; - CHAR8 *PdbPath; } EFI_DEBUG_IMAGE_INFO_NORMAL; +typedef struct { + /// + /// When this debug image info structure is present, ImageInfoType is + /// set to EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL2, indicating that PdbPath + /// and DebugBase fields are available for symbolication. The format + /// of the loaded image is not specified and may or may not be PE. + /// + UINT32 ImageInfoType; + /// + /// A pointer to an instance of the loaded image protocol for the associated image. + /// + EFI_LOADED_IMAGE_PROTOCOL *LoadedImageProtocolInstance; + /// + /// Indicates the image handle of the associated image. + /// + EFI_HANDLE ImageHandle; + /// + /// Symbol file path for debug symbolication. + /// + CHAR8 *PdbPath; + /// + /// Image base address for debug symbolication. + /// + UINTN DebugBase; +} EFI_DEBUG_IMAGE_INFO_NORMAL2; + typedef union { - UINT32 *ImageInfoType; - EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; + /// + /// Indicates the type of image info structure which is present. For + /// PE32 EFI images loaded with the old image loader, this is set to + /// EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL. For all images loaded with the new + /// image loader, this is set to EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL2. + /// + UINT32 *ImageInfoType; + /// + /// Present when ImageInfoType is EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL. + /// + EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; + /// + /// Present when ImageInfoType is EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL2. + /// + EFI_DEBUG_IMAGE_INFO_NORMAL2 *NormalImage2; } EFI_DEBUG_IMAGE_INFO; typedef struct { diff --git a/MdePkg/Include/IndustryStandard/PeImage.h b/MdePkg/Include/IndustryStandard/PeImage.h index cfcabad63f..bafe707600 100644 --- a/MdePkg/Include/IndustryStandard/PeImage.h +++ b/MdePkg/Include/IndustryStandard/PeImage.h @@ -234,7 +234,7 @@ typedef struct { UINT64 SizeOfHeapCommit; UINT32 LoaderFlags; UINT32 NumberOfRvaAndSizes; - EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; + EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES]; } EFI_IMAGE_OPTIONAL_HEADER64; diff --git a/MdePkg/Include/Library/UefiImageLib.h b/MdePkg/Include/Library/UefiImageLib.h index 1bd574e775..7528f3a6eb 100644 --- a/MdePkg/Include/Library/UefiImageLib.h +++ b/MdePkg/Include/Library/UefiImageLib.h @@ -650,4 +650,9 @@ UefiImageDebugPrintImageRecord ( IN CONST UEFI_IMAGE_RECORD *ImageRecord ); +UINTN +UefiImageLoaderGetDebugAddress ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + #endif // UEFI_IMAGE_LIB_H_ diff --git a/MdePkg/Library/BaseUefiImageLib/PeSupport.c b/MdePkg/Library/BaseUefiImageLib/PeSupport.c index b03b85ee25..27dff54b7f 100644 --- a/MdePkg/Library/BaseUefiImageLib/PeSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/PeSupport.c @@ -236,6 +236,14 @@ UefiImageLoaderGetImageAddressPe ( return PeCoffLoaderGetImageAddress (&Context->Ctx.Pe); } +UINTN +UefiImageLoaderGetDebugAddressPe ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return PeCoffLoaderGetImageAddress (&Context->Ctx.Pe); +} + /** Retrieves the memory protection attributes corresponding to PE/COFF Image section permissions. @@ -750,6 +758,7 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST UEFI_IMAGE_FORMAT_SUPPORT mPeSupport = { UefiImageGetBaseAddressPe, UefiImageGetRelocsStrippedPe, UefiImageLoaderGetImageAddressPe, + UefiImageLoaderGetDebugAddressPe, UefiImageLoaderGetImageRecordPe, UefiImageDebugLocateImagePe, UefiImageGetFixedAddressPe, diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h b/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h index efe7048891..da64c5c462 100644 --- a/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h +++ b/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h @@ -176,6 +176,12 @@ UINTN IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context ); +typedef +UINTN +(*UEFI_IMAGE_LOADER_GET_DEBUG_ADDRESS) ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + typedef UEFI_IMAGE_RECORD * (*UEFI_IMAGE_LOADER_GET_IMAGE_RECORD) ( @@ -226,6 +232,7 @@ typedef struct { UEFI_IMAGE_GET_BASE_ADDRESS GetBaseAddress; UEFI_IMAGE_GET_RELOCS_STRIPPED GetRelocsStripped; UEFI_IMAGE_LOADER_GET_IMAGE_ADDRESS LoaderGetImageAddress; + UEFI_IMAGE_LOADER_GET_DEBUG_ADDRESS LoaderGetDebugAddress; UEFI_IMAGE_LOADER_GET_IMAGE_RECORD LoaderGetImageRecord; UEFI_IMAGE_DEBUG_LOCATE_IMAGE DebugLocateImage; UEFI_IMAGE_GET_FIXED_ADDRESS GetFixedAddress; diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c b/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c index 6e9eaa9364..18d323f585 100644 --- a/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c +++ b/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c @@ -565,6 +565,23 @@ UefiImageLoaderGetImageAddress ( return Result; } +UINTN +UefiImageLoaderGetDebugAddress ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINTN Result; + + UEFI_IMAGE_EXEC ( + Result, + Context->FormatIndex, + LoaderGetDebugAddress, + Context + ); + + return Result; +} + UEFI_IMAGE_RECORD * UefiImageLoaderGetImageRecord ( IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c b/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c index 240093dc26..4d0079898c 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c @@ -211,11 +211,11 @@ GetImagePdb ( } for (Entry = 0; Entry < DebugTableHeader->TableSize; Entry++, DebugTable++) { - if (DebugTable->NormalImage != NULL) { - if ((DebugTable->NormalImage->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) && - (DebugTable->NormalImage->LoadedImageProtocolInstance != NULL)) { - if (ImageBase == DebugTable->NormalImage->LoadedImageProtocolInstance->ImageBase) { - return DebugTable->NormalImage->PdbPath; + if (DebugTable->NormalImage2 != NULL) { + if ((DebugTable->NormalImage2->ImageInfoType == EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL2) && + (DebugTable->NormalImage2->LoadedImageProtocolInstance != NULL)) { + if (ImageBase == DebugTable->NormalImage2->LoadedImageProtocolInstance->ImageBase) { + return DebugTable->NormalImage2->PdbPath; } } } diff --git a/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.c b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.c index 35f7db1258..c624f911f6 100644 --- a/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.c +++ b/SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLib.c @@ -66,7 +66,7 @@ UefiImageLoaderExtraActionCommon ( RETURN_STATUS Status; CONST CHAR8 *PdbPath; UINT32 PdbPathSize; - EFI_PHYSICAL_ADDRESS ImageBase; + EFI_PHYSICAL_ADDRESS DebugBase; ASSERT (ImageContext != NULL); @@ -111,7 +111,7 @@ UefiImageLoaderExtraActionCommon ( } } - ImageBase = UefiImageLoaderGetImageAddress (ImageContext); + DebugBase = UefiImageLoaderGetDebugAddress (ImageContext); // // Save Debug Register State @@ -126,7 +126,7 @@ UefiImageLoaderExtraActionCommon ( // // DR0 = Signature // DR1 = The address of the Null-terminated ASCII string for the PE/COFF image's PDB file name - // DR2 = The pointer to the ImageBase address + // DR2 = The pointer to the DebugBase address // DR3 = IO_PORT_BREAKPOINT_ADDRESS // DR7 = Disables all HW breakpoints except for DR3 I/O port access of length 1 byte // CR4 = Make sure DE(BIT3) is set @@ -134,7 +134,7 @@ UefiImageLoaderExtraActionCommon ( AsmWriteDr7 (BIT10); AsmWriteDr0 (Signature); AsmWriteDr1 ((UINTN)PdbPath); - AsmWriteDr2 ((UINTN)&ImageBase); + AsmWriteDr2 ((UINTN)&DebugBase); AsmWriteDr3 (IO_PORT_BREAKPOINT_ADDRESS); if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) { @@ -172,7 +172,7 @@ UefiImageLoaderExtraActionCommon ( AsmWriteDr1 (Dr1); } - if (!IsDrxEnabled (2, NewDr7) && (AsmReadDr2 () == (UINTN)&ImageBase)) { + if (!IsDrxEnabled (2, NewDr7) && (AsmReadDr2 () == (UINTN)&DebugBase)) { AsmWriteDr2 (Dr2); } diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c index 76ea152955..1599fa8e51 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c @@ -120,9 +120,10 @@ DumpModuleImageInfo ( { BOOLEAN Result; UINTN ImageBase; + UINTN DebugBase; CONST CHAR8 *PdbPath; - Result = GetImageInfoByIp (&ImageBase, &PdbPath, CurrentEip); + Result = GetImageInfoByIp (&ImageBase, &DebugBase, &PdbPath, CurrentEip); if (!Result) { InternalPrintMessage ("!!!! Can't find image information. !!!!\n"); @@ -139,8 +140,9 @@ DumpModuleImageInfo ( } InternalPrintMessage ( - " (ImageBase=%016lp) !!!!\n", - (EFI_PHYSICAL_ADDRESS) ImageBase + " (ImageBase=%016lp, DebugBase=%016lp) !!!!\n", + (EFI_PHYSICAL_ADDRESS) ImageBase, + (EFI_PHYSICAL_ADDRESS) DebugBase ); } } diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h index 6d3dc46b6e..0356abd7ab 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h @@ -327,6 +327,7 @@ AsmGetTssTemplateMap ( BOOLEAN GetImageInfoByIp ( OUT UINTN *ImageBase, + OUT UINTN *DebugBase, OUT CONST CHAR8 **SymbolsPath, IN UINTN CurrentEip ); diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c index 2a4fca621a..30731a8071 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c @@ -143,13 +143,14 @@ InitializeSeparateExceptionStacks ( BOOLEAN GetImageInfoByIp ( OUT UINTN *ImageBase, + OUT UINTN *DebugBase, OUT CONST CHAR8 **SymbolsPath, IN UINTN CurrentEip ) { - EFI_STATUS Status; - UINT32 Index; - CONST EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; + EFI_STATUS Status; + UINT32 Index; + CONST EFI_DEBUG_IMAGE_INFO_NORMAL2 *NormalImage2; if (mDebugImageInfoTable == NULL) { Status = EfiGetSystemConfigurationTable ( @@ -169,18 +170,19 @@ GetImageInfoByIp ( continue; } - if (*mDebugImageInfoTable->EfiDebugImageInfoTable[Index].ImageInfoType != EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) { + if (*mDebugImageInfoTable->EfiDebugImageInfoTable[Index].ImageInfoType != EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL2) { continue; } - NormalImage = mDebugImageInfoTable->EfiDebugImageInfoTable[Index].NormalImage; + NormalImage2 = mDebugImageInfoTable->EfiDebugImageInfoTable[Index].NormalImage2; - ASSERT (NormalImage->LoadedImageProtocolInstance != NULL); + ASSERT (NormalImage2->LoadedImageProtocolInstance != NULL); - if (CurrentEip >= (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase && - CurrentEip < (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase + NormalImage->LoadedImageProtocolInstance->ImageSize) { - *ImageBase = (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase; - *SymbolsPath = NormalImage->PdbPath; + if (CurrentEip >= (UINTN) NormalImage2->LoadedImageProtocolInstance->ImageBase && + CurrentEip < (UINTN) NormalImage2->LoadedImageProtocolInstance->ImageBase + NormalImage2->LoadedImageProtocolInstance->ImageSize) { + *ImageBase = (UINTN) NormalImage2->LoadedImageProtocolInstance->ImageBase; + *DebugBase = NormalImage2->DebugBase; + *SymbolsPath = NormalImage2->PdbPath; return TRUE; } } diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c index 2e49bd88b6..6c109f6353 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c @@ -230,6 +230,7 @@ InitializeSeparateExceptionStacks ( BOOLEAN GetImageInfoByIp ( OUT UINTN *ImageBase, + OUT UINTN *DebugBase, OUT CONST CHAR8 **SymbolsPath, IN UINTN CurrentEip ) @@ -244,6 +245,7 @@ GetImageInfoByIp ( } *ImageBase = UefiImageLoaderGetImageAddress (&ImageContext); + *DebugBase = UefiImageLoaderGetDebugAddress (&ImageContext); Status = UefiImageGetSymbolsPath (&ImageContext, SymbolsPath, &PdbPathSize); return !RETURN_ERROR (Status); diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c index 8351d29b96..41e9091e1a 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c @@ -226,6 +226,7 @@ InitializeSeparateExceptionStacks ( BOOLEAN GetImageInfoByIp ( OUT UINTN *ImageBase, + OUT UINTN *DebugBase, OUT CONST CHAR8 **SymbolsPath, IN UINTN CurrentEip ) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c index d14d00aa7e..4e02f35fa2 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c @@ -150,13 +150,14 @@ InternalGetSystemConfigurationTable ( BOOLEAN GetImageInfoByIp ( OUT UINTN *ImageBase, + OUT UINTN *DebugBase, OUT CONST CHAR8 **SymbolsPath, IN UINTN CurrentEip ) { - EFI_STATUS Status; - UINT32 Index; - CONST EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; + EFI_STATUS Status; + UINT32 Index; + CONST EFI_DEBUG_IMAGE_INFO_NORMAL2 *NormalImage2; if (mDebugImageInfoTableHeader == NULL) { Status = InternalGetSystemConfigurationTable ( @@ -176,18 +177,19 @@ GetImageInfoByIp ( continue; } - if (*mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].ImageInfoType != EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) { + if (*mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].ImageInfoType != EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL2) { continue; } - NormalImage = mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].NormalImage; + NormalImage2 = mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].NormalImage2; - ASSERT (NormalImage->LoadedImageProtocolInstance != NULL); + ASSERT (NormalImage2->LoadedImageProtocolInstance != NULL); - if (CurrentEip >= (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase && - CurrentEip < (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase + NormalImage->LoadedImageProtocolInstance->ImageSize) { - *ImageBase = (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase; - *SymbolsPath = NormalImage->PdbPath; + if (CurrentEip >= (UINTN) NormalImage2->LoadedImageProtocolInstance->ImageBase && + CurrentEip < (UINTN) NormalImage2->LoadedImageProtocolInstance->ImageBase + NormalImage2->LoadedImageProtocolInstance->ImageSize) { + *ImageBase = (UINTN) NormalImage2->LoadedImageProtocolInstance->ImageBase; + *DebugBase = NormalImage2->DebugBase; + *SymbolsPath = NormalImage2->PdbPath; return TRUE; } } diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c index 38724cddd7..d19eda5c31 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c @@ -52,14 +52,14 @@ SmmGetSystemConfigurationTable ( CONST EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *mDebugImageInfoTableHeader = NULL; // FIXME: -CONST EFI_DEBUG_IMAGE_INFO_NORMAL * +CONST EFI_DEBUG_IMAGE_INFO_NORMAL2 * InternalLocateImage ( IN UINTN CurrentEip ) { EFI_STATUS Status; UINT32 Index; - CONST EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage; + CONST EFI_DEBUG_IMAGE_INFO_NORMAL2 *NormalImage2; if (mDebugImageInfoTableHeader == NULL) { Status = SmmGetSystemConfigurationTable ( @@ -79,17 +79,17 @@ InternalLocateImage ( continue; } - if (*mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].ImageInfoType != EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL) { + if (*mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].ImageInfoType != EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL2) { continue; } - NormalImage = mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].NormalImage; + NormalImage2 = mDebugImageInfoTableHeader->EfiDebugImageInfoTable[Index].NormalImage2; - ASSERT (NormalImage->LoadedImageProtocolInstance != NULL); + ASSERT (NormalImage2->LoadedImageProtocolInstance != NULL); - if (CurrentEip >= (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase && - CurrentEip < (UINTN) NormalImage->LoadedImageProtocolInstance->ImageBase + NormalImage->LoadedImageProtocolInstance->ImageSize) { - return NormalImage; + if (CurrentEip >= (UINTN) NormalImage2->LoadedImageProtocolInstance->ImageBase && + CurrentEip < (UINTN) NormalImage2->LoadedImageProtocolInstance->ImageBase + NormalImage2->LoadedImageProtocolInstance->ImageSize) { + return NormalImage2; } } From 8171958c4e67aff24346a47e25f0eb60ef26119b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Tue, 13 Jun 2023 13:34:59 +0200 Subject: [PATCH 081/341] BaseTools/CommonLib: Replace aligned_alloc with posix_memalign --- BaseTools/Source/C/Common/CommonLib.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/BaseTools/Source/C/Common/CommonLib.c b/BaseTools/Source/C/Common/CommonLib.c index d5f845b568..98176555af 100644 --- a/BaseTools/Source/C/Common/CommonLib.c +++ b/BaseTools/Source/C/Common/CommonLib.c @@ -502,7 +502,15 @@ InternalAlignedAlloc ( ) { #ifndef _WIN32 - return aligned_alloc (Alignment, Size); + int Result; + void *Buffer; + + Result = posix_memalign (&Buffer, Alignment, Size); + if (Result != 0) { + return NULL; + } + + return Buffer; #else return _aligned_malloc (Size, Alignment); #endif From 577c44620cb01cb37b43814bd1ff21ca5c40bee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Thu, 4 May 2023 17:55:53 +0200 Subject: [PATCH 082/341] BaseTools/build_rule: Always pass CC_FLAGS to DLINK --- BaseTools/Conf/build_rule.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template index 37e14708e5..c925098211 100755 --- a/BaseTools/Conf/build_rule.template +++ b/BaseTools/Conf/build_rule.template @@ -343,7 +343,7 @@ "$(DLINK)" $(DLINK_FLAGS) $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) - "$(DLINK)" $(DLINK_FLAGS) -Wl,--start-group,@$(STATIC_LIBRARY_FILES_LIST),--end-group $(DLINK2_FLAGS) + "$(DLINK)" $(DLINK_FLAGS) -Wl,--start-group,@$(STATIC_LIBRARY_FILES_LIST),--end-group $(CC_FLAGS) $(DLINK2_FLAGS) "$(DLINK)" -o ${dst} $(DLINK_FLAGS) $(DLINK_SPATH) -filelist $(STATIC_LIBRARY_FILES_LIST) $(DLINK2_FLAGS) From d13d798fdd6a4f927cdd327bb32119d5c5b60ce6 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 17 Jul 2023 09:25:27 +0300 Subject: [PATCH 083/341] BaseTools/tools_def: Deduplicate DLINK_FLAGS from CC_FLAGS --- BaseTools/Conf/tools_def.template | 76 +++++++++++++++---------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index 9db8c77278..5a201f30a9 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -73,8 +73,8 @@ DEFINE AARCH64_LTO = !else DEFINE LTO = -flto DEFINE X64_LTO = -flto -DUSING_LTO -DEFINE ARM_LTO = -flto -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm -DEFINE AARCH64_LTO = -flto -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch +DEFINE ARM_LTO = -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm +DEFINE AARCH64_LTO = -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 -Wno-lto-type-mismatch !endif # common path macros @@ -1046,13 +1046,13 @@ DEFINE GCC5_LOONGARCH64_PP_FLAGS = -mabi=lp64d -march=loongarch64 DEF( *_GCC_IA32_NASM_FLAGS = -f elf32 -DRODATA_SECTION_NAME=.rodata DEBUG_GCC_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) DEF(LTO) -Os - DEBUG_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) DEF(LTO) -Os -Wl,-q,-m,elf_i386,--oformat=elf32-i386 + DEBUG_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-q,-m,elf_i386,--oformat=elf32-i386 RELEASE_GCC_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) DEF(LTO) -Os -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) DEF(LTO) -Os -Wl,-q,-m,elf_i386,--oformat=elf32-i386 +RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-q,-m,elf_i386,--oformat=elf32-i386 NOOPT_GCC_IA32_CC_FLAGS = DEF(GCC5_IA32_CC_FLAGS) -O0 - NOOPT_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-q,-m,elf_i386,--oformat=elf32-i386 -O0 + NOOPT_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-q,-m,elf_i386,--oformat=elf32-i386 ################## # GCC X64 definitions @@ -1076,13 +1076,13 @@ RELEASE_GCC_IA32_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) DEF(LTO) -Os -W *_GCC_X64_NASM_FLAGS = -f elf64 -DRODATA_SECTION_NAME=.rodata DEBUG_GCC_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) DEF(X64_LTO) - DEBUG_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) DEF(LTO) -Os + DEBUG_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) RELEASE_GCC_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) DEF(X64_LTO) -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) DEF(LTO) -Os +RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) NOOPT_GCC_X64_CC_FLAGS = DEF(GCC5_X64_CC_FLAGS) -O0 - NOOPT_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) -O0 + NOOPT_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) ################## # GCC ARM definitions @@ -1109,13 +1109,13 @@ RELEASE_GCC_X64_DLINK_FLAGS = DEF(GCC5_X64_DLINK_FLAGS) DEF(LTO) -Os *_GCC_ARM_CC_SECPEIFLAGS = DEF(GCC_ARM_CC_SECPEIFLAGS) DEBUG_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) DEF(LTO) -Wno-unused-but-set-variable -Wno-unused-const-variable - DEBUG_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) DEF(ARM_LTO) -Os + DEBUG_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) DEF(ARM_LTO) RELEASE_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) DEF(LTO) -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) DEF(ARM_LTO) -Os +RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) DEF(ARM_LTO) NOOPT_GCC_ARM_CC_FLAGS = DEF(GCC5_ARM_CC_FLAGS) -O0 - NOOPT_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) -O0 + NOOPT_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) ################## # GCC AARCH64 definitions @@ -1142,16 +1142,16 @@ RELEASE_GCC_ARM_DLINK_FLAGS = DEF(GCC5_ARM_DLINK_FLAGS) DEF(ARM_LTO) -Os *_GCC_AARCH64_CC_SECPEIFLAGS = DEF(GCC_AARCH64_CC_SECPEIFLAGS) DEBUG_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) DEF(LTO) -Wno-unused-but-set-variable -Wno-unused-const-variable - DEBUG_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) DEF(AARCH64_LTO) -Os + DEBUG_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) DEF(AARCH64_LTO) DEBUG_GCC_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) RELEASE_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) DEF(LTO) -Wno-unused-but-set-variable -Wno-unused-const-variable -RELEASE_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) DEF(AARCH64_LTO) -Os +RELEASE_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) DEF(AARCH64_LTO) RELEASE_GCC_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) NOOPT_GCC_AARCH64_CC_FLAGS = DEF(GCC5_AARCH64_CC_FLAGS) -O0 - NOOPT_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) -O0 - NOOPT_GCC_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) -O0 + NOOPT_GCC_AARCH64_DLINK_FLAGS = DEF(GCC5_AARCH64_DLINK_FLAGS) + NOOPT_GCC_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) ################## # GCC RISCV64 definitions @@ -1264,7 +1264,7 @@ NOOPT_CLANGPDB_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /DRIVER /MACHINE:X NOOPT_CLANGPDB_IA32_DLINK2_FLAGS = ########################## -# CLANGWIN X64 definitions +# CLANGPDB X64 definitions ########################## *_CLANGPDB_X64_CC_PATH = DEF(CLANGPDB_X64_PREFIX)clang *_CLANGPDB_X64_SLINK_PATH = DEF(CLANGPDB_X64_PREFIX)llvm-lib @@ -1357,16 +1357,16 @@ DEFINE CLANGDWARF_ALL_CC_FLAGS = DEF(GCC5_ALL_CC_FLAGS) DEF(CLANGDWARF_WARN *_CLANGDWARF_IA32_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_IA32_TARGET) DEBUG_CLANGDWARF_IA32_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m32 -malign-double -Oz -flto -march=i586 DEF(CLANGDWARF_IA32_TARGET) -g -fno-pic -fno-pie -DEBUG_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-q,-O3 -Wl,-melf_i386 -Wl,--oformat,elf32-i386 -DEBUG_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O3 -fuse-ld=lld +DEBUG_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-q -Wl,-melf_i386 -Wl,--oformat,elf32-i386 +DEBUG_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -fuse-ld=lld RELEASE_CLANGDWARF_IA32_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m32 -malign-double -Oz -flto -march=i586 DEF(CLANGDWARF_IA32_TARGET) -fno-pic -fno-pie -RELEASE_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-q,-O3 -Wl,-melf_i386 -Wl,--oformat,elf32-i386 -RELEASE_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O3 -fuse-ld=lld +RELEASE_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-q -Wl,-melf_i386 -Wl,--oformat,elf32-i386 +RELEASE_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -fuse-ld=lld NOOPT_CLANGDWARF_IA32_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m32 -malign-double -O0 -march=i586 DEF(CLANGDWARF_IA32_TARGET) -g -fno-pic -fno-pie -NOOPT_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-O0 -Wl,-q,-melf_i386 -Wl,--oformat,elf32-i386 -NOOPT_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O0 -fuse-ld=lld +NOOPT_CLANGDWARF_IA32_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-q,-melf_i386 -Wl,--oformat,elf32-i386 +NOOPT_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -fuse-ld=lld ########################### # CLANGDWARF X64 definitions @@ -1392,16 +1392,16 @@ NOOPT_CLANGDWARF_IA32_DLINK2_FLAGS = DEF(CLANGDWARF_IA32_DLINK2_FLAGS) -O0 - *_CLANGDWARF_X64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_X64_TARGET) DEBUG_CLANGDWARF_X64_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -fpie -fdirect-access-external-data -Oz -flto DEF(CLANGDWARF_X64_TARGET) -g -DEBUG_CLANGDWARF_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-O3 -Wl,-melf_x86_64 -Wl,--oformat,elf64-x86-64 -Wl,-pie -mcmodel=small -Wl,--apply-dynamic-relocs -DEBUG_CLANGDWARF_X64_DLINK2_FLAGS = -O3 -fuse-ld=lld +DEBUG_CLANGDWARF_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-melf_x86_64 -Wl,--oformat,elf64-x86-64 -Wl,-pie -mcmodel=small -Wl,--apply-dynamic-relocs +DEBUG_CLANGDWARF_X64_DLINK2_FLAGS = -fuse-ld=lld RELEASE_CLANGDWARF_X64_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -fpie -fdirect-access-external-data -Oz -flto DEF(CLANGDWARF_X64_TARGET) -RELEASE_CLANGDWARF_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -flto -Wl,-O3 -Wl,-melf_x86_64 -Wl,--oformat,elf64-x86-64 -Wl,-pie -mcmodel=small -Wl,--apply-dynamic-relocs -RELEASE_CLANGDWARF_X64_DLINK2_FLAGS = -O3 -fuse-ld=lld +RELEASE_CLANGDWARF_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-melf_x86_64 -Wl,--oformat,elf64-x86-64 -Wl,-pie -mcmodel=small -Wl,--apply-dynamic-relocs +RELEASE_CLANGDWARF_X64_DLINK2_FLAGS = -fuse-ld=lld NOOPT_CLANGDWARF_X64_CC_FLAGS = DEF(CLANGDWARF_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -fpie -fdirect-access-external-data -O0 DEF(CLANGDWARF_X64_TARGET) -g -NOOPT_CLANGDWARF_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-O0 -Wl,-melf_x86_64 -Wl,--oformat,elf64-x86-64 -Wl,-pie -mcmodel=small -Wl,--apply-dynamic-relocs -NOOPT_CLANGDWARF_X64_DLINK2_FLAGS = -O0 -fuse-ld=lld +NOOPT_CLANGDWARF_X64_DLINK_FLAGS = DEF(CLANGDWARF_IA32_X64_DLINK_FLAGS) -Wl,-melf_x86_64 -Wl,--oformat,elf64-x86-64 -Wl,-pie -mcmodel=small -Wl,--apply-dynamic-relocs +NOOPT_CLANGDWARF_X64_DLINK2_FLAGS = -fuse-ld=lld ################## # CLANGDWARF ARM definitions @@ -1438,11 +1438,11 @@ DEFINE CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_TARGET) DEF(GCC_ARM_DLI *_CLANGDWARF_ARM_CC_SECPEIFLAGS = DEF(GCC_ARM_CC_SECPEIFLAGS) DEBUG_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) -flto -O1 - DEBUG_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O1 -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm + DEBUG_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm NOOPT_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) -O0 NOOPT_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) RELEASE_CLANGDWARF_ARM_CC_FLAGS = DEF(CLANGDWARF_ARM_CC_FLAGS) -flto -Oz -RELEASE_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -flto -Wl,-O3 -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm +RELEASE_CLANGDWARF_ARM_DLINK_FLAGS = DEF(CLANGDWARF_ARM_DLINK_FLAGS) -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-arm -Wl,-plugin-opt=-pass-through=-llto-arm ################## # CLANGDWARF AARCH64 definitions @@ -1481,11 +1481,11 @@ DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_ *_CLANGDWARF_AARCH64_CC_SECPEIFLAGS = DEF(GCC_AARCH64_CC_SECPEIFLAGS) DEBUG_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) -flto -O1 - DEBUG_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O1 -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 + DEBUG_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 NOOPT_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) -O0 NOOPT_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) RELEASE_CLANGDWARF_AARCH64_CC_FLAGS = DEF(CLANGDWARF_AARCH64_CC_FLAGS) -flto -Oz -RELEASE_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -flto -Wl,-O3 -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 +RELEASE_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_DLINK_FLAGS) -L$(WORKSPACE)/BaseTools/Bin/GccLto -llto-aarch64 -Wl,-plugin-opt=-pass-through=-llto-aarch64 ################## # CLANGDWARF RISCV64 definitions @@ -1610,9 +1610,9 @@ RELEASE_XCODE5_IA32_ASM_FLAGS = -arch i386 *_XCODE5_IA32_NASM_FLAGS = -f macho32 -DRODATA_SECTION_NAME=.rodata - DEBUG_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -RELEASE_XCODE5_IA32_CC_FLAGS = -arch i386 -c -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -Wno-unused-const-variable -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang - NOOPT_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -O0 -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang + DEBUG_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -flto -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang +RELEASE_XCODE5_IA32_CC_FLAGS = -arch i386 -c -flto -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -Wno-unused-const-variable -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang + NOOPT_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -O0 -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang ################## # X64 definitions @@ -1629,9 +1629,9 @@ RELEASE_XCODE5_X64_ASM_FLAGS = -arch x86_64 *_XCODE5_*_PP_FLAGS = -E -x assembler-with-cpp -include AutoGen.h *_XCODE5_*_VFRPP_FLAGS = -x c -E -P -DVFRCOMPILE -include $(MODULE_NAME)StrDefs.h - DEBUG_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -gdwarf -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS - NOOPT_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -gdwarf -O0 -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS -RELEASE_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unused-const-variable -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS + DEBUG_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -gdwarf -flto -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS + NOOPT_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -gdwarf -O0 -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS +RELEASE_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -flto -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unused-const-variable -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS ################# # ASM 16 linker definitions From ae364ad6d3c415a5b00f1600fc4b11388c38b2ac Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 27 Feb 2025 14:23:02 +0300 Subject: [PATCH 084/341] Docs: Updated README.md. --- PEvsTE.png | Bin 0 -> 27455 bytes README.md | 94 +++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 PEvsTE.png diff --git a/PEvsTE.png b/PEvsTE.png new file mode 100644 index 0000000000000000000000000000000000000000..d46f19f9c38e44bb1cc481398161b121d132aeb6 GIT binary patch literal 27455 zcmb5W2{=}3+c&;Y$PjmfBoa!KDG3!(M1zV58IvSah>*Dq5rrf}p$I8Mk_?$Mgv?{e z5Hds*nTPMU+RyjB@AJOz_Z|QLKK9g#=lPq?<*R&Fk(q&mfglLxlPBcQ z69m;P{!yl<#s5(?HebXK9wu^f$|vRIwprb{oi?;NjrdC@wj^UQts;-M7}aTq$SUFTU1|0o{_D zbl4oOmMA5B_vI_O{QQ21_|@a8d{Mj)UPYXpJ62{GGRbC~tYcK|^m~)H&3vV3tI1lv z+s6ft-l1Q8;gPcUefH!-yV=gaaDy3GuHFOi^SLc%vM(P{%pIPz7BrX9m`vCivQBh zqSJFD>SMxr@;=dCKCLKEEE03X9K+`481gnFJI3PdeL^XO7bi z(oxnP;y8EQ_!dEIBTmX6RdZ+`{c5kHR^CoG(M`?hV;i_`o6jZLdoMN9*72G0GPL9t zt=qUmp_DyOBeniX*wBw=otPr;)g8zp5tvuyKvQj}N{7zA|>R3u;*m?1ujP)=rQ=_7S!JmmlaH%J3)F z?#ATH{__u-=`Zt!skiUk+4m`k?^9*vy7!5%Uw`cE51s%Mdh?Zv~&zI+KM z>b_S$iGHm#SQELv#%1Q`SG5Zlj^Dab{_+wvEk?ht2O-#m?wUbH4{HOYasACjRTKyBdV%z1g>HVJzq_aN}-iX*m|^ zDlfmPYme>TUb!mt)o^{RLsiBDK0OkYfaTxym3Qx zE%y=sA`dz_MMXMmYimiDd9fGgchfR+G+mOgzH(*zy7lY#IZRxd`uX)k{oC%`TkG$x z<+>9TL~(X;dBRm$AmQoSs=H@*kBMiRs4VS)BIqdxr zu&=C5Tk6x#-vdwzeg1%ah!MdtBU(_t(EN zaC38;cVx>&_<#biB9th}J7JLZ;e%moiZ1ix!=j?=zUJKY$jp>zXlUs9`SU?# zW#v^D?XCj10;`|jzkheYousg{)8nHB^m5rBJa`~!JH(1DdCAbQvEQ1HkFP%N^d<*K z$8R_rLk)3^F|n}*hK3$-r$fnmU|?Y2Fc@ji%E`$@e)+E4%>+l%VZzdA3CCc;&GO^T zJ0I-F8Cstk*E~H*MMbrp%`Z_SRqs(?psc)nX=&*db91GLh=}c>RlYu->god9-&>rX zo12rD?;jsOM|^5)3w!wR;kB{$4BLsGqrAKvl2+TOo@JP|uA`{v>20OjW?^CRu;R*w z4IAW%YqJx*$Fe&+JLw58Pfu1#eMRujHN@u4n}d}2`FLaW@*LN+23A#7RTLNBnV%Y# zlb0W?jowMTb6uLJt(C^Dmz=?w3l0g{7#a-9v&tGl_AA8_qj6P zzI`YlD46Ip^HW~_-Sw}BsAbJsl6ZJyp3B``M`&f3h8*LXUszzAlhL-fR3(?-b+>lw zaZ58ZKNguq)~d&XszdQBleIEIPo6N^*x2~U^Ahe+QCoj@<@p8gJa-wJ>R5YCTvGIfX&#YU{w;zw1SZLLEW5yjk5qF+b(n>b5?}+0RJ>h9Ki*;wmofZ=l z)0@q3-15&^;^^73aFvBPpQzTR?qu;^?(SL!lOJ31bQh8f9xL>o^A1K>53bN+=>C za_udXkr7%w7gwaCjC|OWCo~SCCzu>WmFwEtG!yIl&pnZ}j+t<>vU)S&q@qF@9UG$} zx}7JPU%h%2A$5JMr(|l%7B#!|;Nw@XOoIn*z5m%YJ&!gp{dm>v$cSn03^uJ}2I9URK75#oL+oX}3ze+4_7*}}Pw&B_M;qjiALkJlXA=!)LV5X^ zsG8vU_EBi)-cfB$O?sl($HvXg?V716HPL?~dm{Z@^pQ7j-ngsnDNVYVu6+Ld9aMSG zyLTltQxd9lw!BGBPUZ=%O1oOk@ghE+f%~fKY%kqYsaxw56ckXDWtEj#2{Fgct~{rY zMMYGEh|9b!Pu=*}51WWfSFWt;IhlFuTu%}Jt`}h1ZGBOb&2GrP)6k`5&mGEwH@yE0*Tb1wfa@sPxVbTE;YpN)mK*KYA&Heuu)bVe41gJxEKkD7l?dx_+F)=gm zyHrRlVr6uW`lq#?l9zw+*}30;DP&+^;HbWSK?M;V9o^kCIr+W%W6sSVS)!W_Q-urt z<;|#>HHQmBlrz$Qk7P0J-!j|O|6Wb8&{CkbY9>dW;s~w{19;D50 zW@neOcTdeQuHC8>F1i}6{KUC)mMt5qaA2geLJUR^go&A~LoW>s3c9`DxW>v$q)f7K ze+vf+p#K($wS;Hf&CQ1XG*X7ivH(B?5h|?zz48(Xr;;+>WM*M3&f#p2z-lc158d0B1Gb|_Z z!p)mEA3b_h`1vyvK+|1c-;AE~;Of8F(!WSFsmXhJdD-@VqTIM~gLmi7ou`zPHZ-&}H3ddTa|7=&SBOoBK>(C)Bp7Fump`r`hckI}$n{eR3fh$+9#w+V5N9N}r85kTac$Dk! z?@vz*eE+`A&_C}~a*khDL&G}V4|b*a`jm|uFAUC=2XOQ4*s;1Wc=$y0^5a7W#jAQd z>_UZfSvPEW(X`L3;AX+X&kuFY&0c7D3J*AahlZ}beD&(vM;00R>(_;do({``<2b9+ zqhDyaxVU%%D0~W++TWS5AH1<0m!S7j=ge5}!-scJ<9F#M?AfzNL`PCz)V?Ld7Js<)Rgn{#8Vj=8EJN7T2c-Z#E;fg zMFRsK^;A7(OUrS`P5Z(R-Q0sudILDZdW;?!)#j&_mSXkn360bgh*d;7nUgEpH{EuTeVmYf4gMxwrf8MHUZaad% z-n@N#CpMN3?{Vq+^#?#3#VsxBZQaGi)Y4AVNx_y_o#n;Jb6CA^fIsDLjjF5$Yq(q$ zQQzohTNTkL)2~(+qh$q!hx?+z%FD|amX{|Kxg1%VQhgB@SJd6j4czGU;ltqv+%jv4 zT>=8~$Bx~ZxK{J|3X1PFv=%@|#%I4e;$FRey)mU);zG*c!O+3xY#U?jGHN1!;pbsB z4UN8rxYLUdE|YvNRYO*mz&XMF)*{O!`~Is+9;fZPKG?Gmbt$@sSJBb+0lU<-w3NLw zX(R~6fUU=YslCb<=O#n;e8im~YY>ojELNF_>WtUm4p;KVK8(c|Jr(-nR?UDB_NXVe z`#nFuIj&N6L(U$3VO3RCr6{S*WPNE#*8Vk|5G@`y{Y7N}>s0b^$7wJoKF9|-paU;c3>5Z-E78hYe+#0aTT7o=+gw>) zT^h(E=XrhDyGi2q8j1m`$n39j?ljjWM?gC{`uyzd?6%xn>Br{Zz7-YFdPfg9yIy^p zQ`e0H838#thZq^deAEo z=UFRFP0dR+PY+swUFPLUgWFjzOj|4t%B+}7g`w80yKc5H-C>EZ?S_WXhXuaYn!%H?c<17*q65ILt8EDooEiO(h&2-1c#89I%oH%`2&cQ*l;0e3os30#d z?>b-k>XC;QW50j@2I%s9`jqoULITP9(Hm2z!hl+`oMwdHWn}aY4QYjO@8{0ekQ4YxzwrMfj9nPGKg0Ii$zzuR`*lrH_C6kbnI^BV|S# zCFc%u+@Wy)^)mx`Pm7NCy*N_J7cO|ErR{V4GqM`xpNabjC-KH@#TBH5W}WXU4h{|- z6UY%Lt7GI*MoBQhVZ>39J9dnk+&ay#H5g3*0R15tv~qL?2M70l`&KN>YUrOvYrV;Z z4;aA{HBt7=SjFHoaPV!rcAen4k54SSzh$Pq^3gx7Wy0^{-vcwr%M0jDyL$ENV)1k5 z&UqbIL|L)MIXJZNeQ=PEmzTO=X?hE~(1xh0ni>Uja{(Xvo#&!Tz&U@6x(zq%812Yp zsjsgue&3O4Y1s5qCGf=d6KBpGcXpNn-UJ_l*2R599(_erRMgW2ZHINs7Qf=+W1NR< zPZ;F7%kvgN)36?C+WqN@sA~}kju!Pl$}In40g)*B@@4b$=g+tCqAt+_v8*O^KG-pD z-MV#RdOBtOQxFWlC~2pdw{O>7y?T`-Qe@rd0d50$*DP?A#_76`)?HLp#d!Pn?c!xV z1^>Uz=;>1to9{~G(Jl;5xdmt}d5+h5Dt1nZ%r&h*PIdy>wey{wq7YeD=(pr~^)zU7dROzrmdwrJ`keyO(LZJ1cD#%0avHn3x;pm$aU~_Dtun6uz@du^-796&V;yPG ze}D;Y>svv16q;|rYB~|_KqowslI)v=^*rCd7e{?;8FD4@I4OfgL~xKjZvM}YFp}Qp zp4fignWCmP@q%xFgj-6Hhc-qYx_KudA)(ktSPqH;Kqs4!&MqnSWG%0KhGi3eHDvYB zE-+SnJu~`cJqa6te(+sA76kS4IkA7}nV3p&VxYv`G5F}c`{rkGn%VhzUP(#KMD1SC zwI@qdg#hRh*E?l(beG)ExFZC#jk`KR8Yj{(6;V%( zcXLAoEow?stG3IoWptVEkxF_K1(?ht8RX z8t35T^zqXtdc1=o1WO%V-CwnC%j>USzmB5O24n`r^B^pYeQ|kVeD+VPzSm?!Q&Y)p z8ajf2Qs|M9aX{?Af%*bBH`jXow00Kn`+o?O*Q#xQyO8kGAxpEs&`>%kd8CFYEzJeh z@6G%7*KZW0=Fc+#JK+8@1EHws==h^8_O@r3X=Yy64PMZ=aN+s0X9UhN&`s6#%a?hj z^mTNYAlSToDK+OjJ<%)oY2XGF>2D}iBI4rerdOr2bsj*G3JVVh#f;XUpk-%g$4BZK zEPD(#=esxoE^p)GqZ!X%5YiAb91ZC`@~YHJ%AF$_dKy-sPet)8X8{hcM&us>S7gH%)jPr1oAj0 zD_h7oumiHp%^&JIxekE!96*01v%mVRac~Et8Uf8&A(zsxS#vbuY^0vk5`Z-?iZb?e zp5vcl?D>!*trEI+WnG7)E(jW?TE1#W?+Av30$pW~prFh1-2BDgr$;(6g>h~u6csd& zgOZYUcUCicimh3*W&FG)8 z_hBd!TgIr&erD$j8X5b47}~tRsErDY?l4g;(Jg!WG$TnX>g!F^x1wt|H#gHWGkbv; zunA}qX`24fbqt{8V_#4F`c?GjM{Cg2r~aVhhJezLBFSD(JVQr&laX=!#0h$6?ax7a zIy-f2e|ByLpUt{8$q(j5PYglcS+{N-j@c@-=PA@G!V2Gyzp*I?FTusE!hT0xiUGPP zwm~D7y!HD^Ub=+%&6Et?g>#|0dqTc}3f%k+!KxHZD^)EVHP*2#%P;>Ty827igtM!j zb=?I#_?l%MTj30%=H&tm3OK2&2GAidulRtIXUmo?)UxQFBrhj>Qn-==E@meohBi9V zn#xVJ4R8^+ZU?kpYFR-3*oP0-iSFCSL-hard6v{0aRUSI-DBXAatQP}ktilFPoYpy z!H)0Vz55*s;z(z9`kRPvj|H{q376%$!FNVgY;WJaOKLpc-Il#hCGxGJynJ9l0842} zNnQAU;}ddn9z@-}je8&MS#Owpo3*F8scE)|#kFaYkVS8GF|o{n*&)u}Nu`W0vwPpZ zv;o&Fc<;jLiyaO%rT3TFM@?u$c^5jYKM;`VM+1YE3KJ@v7 zgJ`h3mrwBl{n7X8swUtR|6NsgBrhDr0#H~@Q?sq-z-)ZYpD%BtW!$3Prl5G5}Kie z%7Ik^&-V@tTrlQ&K2PousIjL)$bw4{&^(C3uOIBeQ=f~Z8_JoyefySVY$!>WV2MER zrY68ndh%wv+XmgJ1U8J`uB`4nr%l+WL+u%R^OvTzKSv(k#JEYQ1aJ(n z6kolce-eA!V%oanok{G3!SQghj3QMWXHD^2zrK|!YiN{1!l5N@Qrp_p;`C(HxI&8| z9UmWh=$0E(T4}DmQ}WMXle!m`);fenOb`+hnVTvTl9HHUw5ZQc=Q_x zcWZwA`b84zmK5FB%HFs&By`tIZx$L`=yDp*v(nolaa~?b?NPBf^iGEoRw18V0>wTL4w^M#NFQ1!t0kKqnNeI~^+ zdwYA7eL4Q%-qA1VFB21w0#m#1%q-vSlv4Xx`tac`pqn(r;$-xSCwLL5)8H%+j7;G*3q`KKE}a;{(euGYSEf+E>TU7cL%sF_HmOmk6c%{l%LVNVRLHcIUXqf__03z z%oY$c#@oMZWmeRNDrH<3C9ikqGZQ{OKFaK&HUpI#{kdhfLL)^{;)2VilOV+$NAW9d zOE+f03R=UJBKH$c6A6m}rvPu)py!aPCb!EJ1-t55e7rY$ih;mU)xml5FA0$RfC_Pi zJfLi-mP4J{`>%*z3^ux)l+iPAd9zt@m5xwLbu}{yLVz^uVRsGIkT>{7HYcbi(0I_B z#nHySjMTD5MmtEy!X?@znWQxP_EE53J>gQ4MUsw=&Y*a+QDf8N9dHi$`T1|EYYXh& zeN;h#7F9kdI+{gVS{kMUxlV;aP8j`v#limo9*acrtPWlS-=%EWoMiX z7xPb(h%MFi2)KWr>;>pZ&r?#?^6K)x|KC{v6c>N?eboE*?YsH7Tgq;f9d{J3d4M7d z1Y)qfI46P?X&^mRlvTJicd=MjW-4QXhhZfsIyyQAn?(IoSK~hiQD(HefP4Sd&tP7+ zy}fC#cjfw`sPjlkaUMT@y!urriNEH5q@qcAq@)OWvv9A4XK-TsI!`aJHIo4(ScV|v zYBIT1C;P_gy&5U`P6Qv>zbHf$;0q5eJ}& zy6_q0-WXtbzKA z{6QzK^?wSo{WEeQu2D?loUi;b&=ci0OKf)B@LxKACZVFR67AVG3B`8VI%nL(JJIV(kMHq5RI(_`eJC0jcj zHUp;*c4HG&!UemWsh6SnP}tbKp`h)u-4cKu0d@T&(iTC%!Lbv`uktOm;Gwee=PUD9 zr`PTd9?Y`t+t85vDKn?t@Q9On&~ zh<;>bgkAIseg6E&YYDxYgpRYQBM?6DxAX6cotpX1bK0uWwdsp#qU$$heBZcAyW{|A z5(?<%Yyd!4rT>{>8rr$a9qc|yFOOqoQf5WfQep~#@7GuRZUdOxni-}SJj$Ixvy+mN zI0QpQO*l^L>+0SoJ>j-D1`L+V#wWM0dkVD=q7S>sCE3W106lrbTV#U*Lm?5W52?|pE=`91*Z5>zOG&6+K{MZj~5F$c+ zmysC^!q%RKd~W9nD$)J>(=5A>Tr)9w4jcsPqAuCxC*bwLtW}6?Xrw^rLysl_vynAw zye*9n2FhvzuVZT;h<|Vkt{2Qo51*cafz?QBbmrbt4ePCkatY70c#%$ATpaS9h1HxP z>Lj8Qz1Y}+r{dVft|@zb9Ywb$bw6yQAMcE7O$DpyGkq*4HVNs-V*ll}Dw{UbR-_x( z9@`Tl?(pOESTPSamBmyTwzOgJzJ>*A82tlL8>HjY5{~FfKrD=MDXs~MUOZM zTRgRk%KZW9%O&)rl7epqf?7h#1xu((A~*U^yfbTE8y6Rc&6aU~4yln%_+StsE@;~# zu8R&h@YdTeC7)L<;v%M|rmV2H$yiKRR~Ixu59re{{tUqUkr^Qa66lpBZwx+?<{6o< zAh7|Mi99dGae8zOJj~7lH+`P4=Fo(<-H&F*yIBa4{rf$#vk#J{&MI13@-6%}345c` zlI{W;M_XIluA84feL7(~+^`yksie(!rX1VhJK*>Dqf5gLae&rGVWf238svh8{Sohg zhR>F74mC%4_F-T|#J$SOQ>4@Hw$RZn;y85;2Dm5@ZU=pM6{$uvUy8t23-tB%otQx?gq~pLlnmro3X{d!AIY%n)-&KX zY7moH0tOnuzG=Zf34S zY9~50yVm)75_M2+fEi2gZR{Tz+2e1CEffbtwC2|8RjcS*d!Fo>ta~n30oe#8eh4`Z zHC^56)}Al=$Hopgz*{%aR;_9gfA?;@_v76)1oIYgf5@9dXgjvwKZg%$F-QPlX3@e8 zbVG;YRaI>~Gz^{2YarO;pY+G6Xhrnei&|ReQMd3t03dI+uO{A^Ht+G8bj?YL(p{Dm z77ic+p~+NS5k=eMCB&R(Ck~yazx#g+qx5KZh!zXR_~pOv$bp$W{A2fh-Gs!Hl$4pr zDR9*orKuoGC)(>9HSBtlpQs%N8GB;(mmzk=p8i&-)(SHVqv^FG*vVcN$cd>OvV{Br zh$*YD&;2i@$@APBm`KM#-RGyrUf1o7F%JixBvlBX(r;IFyDlXiIB)l*-8gg_8jlx< z$b+rY_sFbBcfJeusbc!?q*|m!06{eTH}8+Hv6-Hp4m)VWPl~C+`Lon85>Nf3cZ7uO zP^y=L{)TNCSCR6&jGcqyGOAx-)c}xovG4kw9OesV8hexS9zl)xS8U}->yP^L?|caT zj<0$jlobtg?8k+4ek2AU&H-(0pWSGi!X#Wd)8O*+{MCLhYAY-6XbO}Sdok)eMv8~n z+uDke2=BNbTTx@9YM90%@Gz^dJo5t@hY+KyNf|2Sr46!KSy>f&GjAbHF*w>xoRX{% zX%ulE^&NKWfF&qJh@G5WfVlP#)BllLP=>v#tfh4iM5w3noXmw0sjbqEtBB&8&R9LX z!GzZj%gRT)HFIotQ&UruDggW{F~_Qz#xZr5VJ-5ue&cWkRqXx#-5bbpcaq4TcYqwR zIXN6~`K|2jA@p3y6Yc>UgJ%-4CBnIO?H_cPf8LXoh7(;9tbgk#lE@u zqvh(rm$3F8T3G{w=VbBd=%69;=e}=wu91;wsHLqeRpk=X-7c_wNieVo|Qvn*_ByjjA5+W@>xAwA136w5bt*MxKsP>VE2_VGHL|uU?&R>(cCkr~&SG2O^&mznqQ^Cn_tH^SV@h8B(CZK0D?L zkpU^PQz79#Be|~rOB8I(O+}BUADk}T#s1E zlg2S;LHWvZ_!U#PwZ+kHt`8s$QqD0jm$o!R$(tjO>Xt(g?Rjd5HLs&tLo6>Z7u(jK z6W-rB@|be{l<@7lG? z2Vq8elx5Wu_PxccIS$(;iCh}!uL!>R8~x6vvHOF4fI`4lL8hL-iYufjZlDeO8{eRD zpenSYy*+{meD!M25=7;cnJ~!4FCf;hCw@;&y+AsPm7-#2CvMS|8{X91d{RRr^u75P zUM6<4UE?q^gF&>yBO)5e%nj8(h`~s@q48kH@Hsg-k?EVc+1Wry=1UVFS?+&#!fg~i za9{_*j)!ja)1R~bxV#Rp{TrT>eUFO_JtilY7!z~H$LC-9p5lelf5JUOAd3AxJ+j10 zX#B`bZ0`?$^hh4+pO|qCXT)K9p_?O3zEBOk2DemBUW989e=?YVjZymlzZ_85`Eqc! zzbPQi{|_mk9lSAEp+La>;gOLBs46hU0|3x~`h$?CM3m_vG~5h}j>o)wd|p(x&~JBw z#kNDS#lgGJe=bT1VYN@`b`yOQy&re)+^IO6W41=C|3(_DpAz&lQrm(cEk1jnjljiO z!>qq%X7;hZUWMJf{votgC_zP^Kaa+p+1H`g1(g7sfi=FT8Wuy=SOV;w;o)JJFze&X zn;RM&1&v(4I=s@Fes#e9OFKF|e*e+q$KO!Jt!~_S)mXj6|G3ysb_Tyt zk+P8-q!>9lIiprNKu89SOW9a90?m{PL^Z`H6M$_s>Le{T7@|K>D6agUQ-weOnx7Jj zg-t2m*woZ7?w95$C0#A7??EQ9wRrx?ZT~-9$=OY+7cb7WKlmeFd$MqHhe%mgq{-$c zt;Pz@!*)!)y}i(66alM0fBr1uw(Jc1Ggmo(VP?D>{SaRLGccvfN;d>UlC&}y@bX=I z_Pmlf12e~U>5oP~qE;Fjo1h8aMKoypx;2PVK?g#f`AhmvoLOcUm!;72?@{+iLjw5m zBPi5d;Qt#pZDQmN|M%pi{wY21|5ffcY;1g`xglseLQK=oS&MMOFo@y{ zSloMd?Rtj&+yLZ|2vZG0${8@~XSn?J6cwahsGdc;Ennmbz(HvQ;>JQ79lALpj~w?- z-Wc`z<11sC-Mp|7ou)@`BZ&OQrNoC4CT_t&riJkKalcQUJXwSf*zg{Pw;?D@>VOVn zNfAnh=H^Kg>5orrCxhKczUiO*5+%LWaI_i?Mgb`gSQ>OLE-nVr6#Tobz5Oy$2k_i1 z-kte1F;Pgz?OZsfw72COjq`uX1AXv~KO1=uADg86fsF_Z4klX#{_4S5&bl#hFK`-W z1^WTh4Y;j{0;B)IH)%C2o<2)2_4i}z}utpP@%VUpaaXG z80DRni%WN~dh#vk9hr`RF>ptTUo}UdFxbqXV0nHo@YtTumPtxo2M-?ffe?Z(2(Ue+ zRW2gZ(taP1tbXu-m>4jik3u7;L_s~VBH9sN*3N$2Sh7%J2vQn053q9b%&mW9)n443 zwzo!%sAEWtlOCQyZ}DGF0+E@PIC1u@_v6QGkdJ)O);4V1NZLUY6BF*4nVEruK&AUk z8n#36dIn>N%!)%VBaqWon_UI=Z9dwb!HE1Ndal~gMW1{3?jY8273pIjw7j?TbBIfj zQFDkbfDg~nU3cx>tNKa+>M|Mf!Ux?&E)x`4D=`=7j11Bu%Dfg58M}yvpmd`@Ye1xU~mv;|YS)=9%M%F)9!q7RE{m0%yAA=y)E7w_@N%grqfZ z;;UB;;4Z#CL$LuzV!oss?;R~bWU)6VOKlI?6;OR%O)Pe=EZak)r=+YnIXKi6-ljRZ zCuAL^9x^YPTrd9P{9l~sTT2KJozWw8svX3!i_xwin++f%zCJHsyzoS3I%anDa{mVk{xwy6-%F zLi|Nej#ieqFqmb9iuxC@FHEWc@I(mHg z&d3>MTldj|m6u%pWiwdK?sOPKI(>ltE`no9hGSfr`%~5Z3TVeM?|}|4ub{AJRlODo zw82!K9<&+xS`Z&k3vPg{s>X;zMl>fxi1q2 zog-J^y5#A;GIf`kcir^46DP>E$LtJbTWIpi7cZ{ym8VWrdu5g6P1=DDH-?|*51M8I zO@C}}=P)euF9O;p9hD@V>~+XGo_QRnU*HN?{3Dz-uSL{F7&sx7PkctW(rVeA<{)x= zjAypbjHi#CLZ?FTpsgpaBD9{o(Jm83be%Q1r;-g~w(!QlLgo-RXNNZGha#&8G%kk7 z8UlV#jvaz64Dmna%oFi?;ey3uC^v}i@JbcH_BemxLL8c6AOj=gFzB2Zqz!6W#5{Mx zmjjo$VrF(4cK37gSHU`VNlQomgG8ag@j)yH9EpMXJknhtgS+2|>O6#k(0R&zj*I+%R~`@hz>_eS_9yskD8DzHYMdO+y>IN ztE{a}00j&N^`P2@Ha&=WMig~iDji62%EwBerjrZ z1ne;cIa8{>S`~^DJ+YCE?e`~5f78a>b!`FIfjdf#kux{Y3n&Cte>w0?7E$3 z!tjnkU?(_y1!lj>9&l+}<_o_@>Ac@-_q}=T+w~NRuY8Q-hfM95(NS}xtT(|+x3abM zym#;N&f{oOB6g#iWNrkYa0v7!((F6<7BZ13>En%na0s#2A%j9ILnSfIocm8&;8;Mh z-`Ru?_WzRwXb#`|Eb%Qe^SnqOKus%t7lQ2Sse!Lr|HK2hplS*~4MmazTMzmTNAAy0 z95XeC$9pP6_LAd8S)yIM%o(dI-`Qi2NRfTVVPYH1VeM9(DdG}*@I}4@WyQrYMS~bS zdy@bDc?`9&@!;U~{%E1T*GxY%jBZ+4Ii$QritZT%O(IGs-Rx|al8S{y96poIzGXzL ziEURSS#9p=1s60_ASS&{Mur=PKh;pOM| z)_0lK`iiu0VeqYz&4!~FR2QnAzKr1DKl}7ks-%-4teI5=Df?;A8u}L$?QhX)stMM0 zI?exgU@*z+uvHHM8G@yQgU=@&}U!1TYjq2C0k9?$qhiY1o5t z*Nu%vQ!zThP1Y{-#|gwq))TH19^Ch(VD&zEdbF~x?oEyB<+L!wP)wk?7e5RgowNAz z)@y}(t|)+iYsTq02Hh!?9F?%t$bGaW<>h_YT*VCq_n~E+joi!wLoxgG@mrn# zEM9h}Q?NovhBQ#`MT`#*`&#DDd7Js9B`gBeo=VjzRlSyf1l0F?)jfadKJ;6pTQ|h( z52{Q7z-#U;`8x#hZ-Wm1!w>%qUTQM7eB1OSsA`}s=jL7{{SiK3CUvOA*<*{2Mu&SyMwxphX&f3gm&7t$;WuNj3;5N<+w8I6FJn zVYD&SZV?kiFlB&4Vt@z25E?Hy&E7XXl5C!ym1lZvOlJz&?VEm2pUlIac!4T{vb2#x ziHnbah>;mV%{M)9{n40zD=I1~?*5OsMo45M0=`}cy)eP$H3pVe>^$f}$Kq;K9(}-! zjcS{|es{rQ=OAovK4JqaYu)8q1K1qNSGO*F4l5dK)^5%KC?MEringr15c<9L7=7{{a{AmWijemH4*k}C-Fk~s-fkTx~|LTCnzRc`qVIFiNV z-rnBD<9Jyy=f~6=T53SG%l#cWM@kG~93g?-U)eMLsyX9gr(Q;bkfX2s9e@_BOmTfZ z1#*TvvQfaZh_x$wy_2x)DuHB44j}34>w5{sXlGt0_qO~hVPRpMB4p~3_x?{KolFS5 zAP*Z0JpiAC5Oq`_IqZpOEiR!K8C~!IY628P&{hQwz7uptdKQ+u7}>;)(ld1tvwQGw z)1aQvg!hha;o>4qmEzLUxQlZTPFT0!_QveqAFqr$^{kyrb*F?wfH&$6Tro71gDVw-6rPvZf6H;~ zKN)x43xlS8CJ4Y_3=;CyX>vT{ZCV=g^bm0|KDZI6DByE-^%?@Pl{24K5~5vs;WZs{ zo)uX_S4VnY0o;g(mlq8UN05hTLadoYwoqx-5xD7Yd4rFhJ{5S{Nb(%Yyj*t5zuw`nbCivx-(#-<0 zDx;2UY$+c5`a#0z>Q#(x-nw=0qNb)YMtwG8qm6MYr$H_37vYt|pTrWLA4w3oz;9EBiarB)lxR_%% zb_%)ebz3dk-z837H5uiE*g;R2n3)AD@y9-UwvAer%z z@$$klpq9l18nh^RTw@$gV#EJn9c*4ZVY#c&4W`8^7{?Srt#>}i2_G!9ar#p{cEP4Y z;CkvTM{WZojX(sQpoOk!b^Ir>vKrlyEIf$LA*x@59IX{L10f6LKu9Oc9a^qI0T@aj zpff!^z4H95+w$B_aBqW4m$nJiBf)tW2Ny$s=XsLh77_GjexaeE65(!OyGVixNR9ju zG9Bea{Yx|WNV_<`vMdZ^!|Gef8iF;YQ8&wq3Kkc}KQ`q|MCHXdYc8Mrff$00j?M%* z0D{mpknG+6@B@wkv3t-mf6H%|xPsO}5=fAkH;#WynYK!?gPZE?>(tA8H+?FcEI+LY z$LVH~MnP(4E8xT|{8?*EdywKZ@lOoq3Whe;cu1o``hX?K@djOjn?%Np3B&{YD%@B7 zmD!bN@2V?|CG%u>T#Zs!R<0Y$zmdHd*Cb~+NKcS4(RU~9b^mu30G1Ug@I$*G2p@U^ z9>YvO_tE16*^{XVylE%w>v&^8LlUp3s0WBnegm@TtSmT6nt$-s4X$4GMx}X<#D5m1 zyEK?GHBi)wr(fYhu+F1hdD^odkSc1+bIP1Ze2sHByTK8n58)1DADSYWOfWMuBV-*N z4?PSH{?V_$uqJa~#>)1;)2bIQ?q>StfU!SC42WRfh8ym3Apq(|g%8w)hsSeih+RTL z3TT|^lWy(lZpKDN2EY3&B<+84f~8}w@HUvwjngaM5QkV`^pMX8fEMISMMJx7`*zR0 z-W_|dr)phvYX0_N2t=49?p_wqPRS+)1Xq`EjvHeWvf#}Sys_DiLP{sIFCXkJB_$;Z z0z+s*xz^KQ+&vYZ%o)0>pdv3{zGOX8+Oj-~6dQI0(gXq64WI!$5)z~#TD)cEi%Znf zToO44>*h8;o-kuE%Grk~59axCm5^6^VQ>>=XjEq|>wjxB_1Gx{hA# zv73ugQV6aE9xWzm`T&xS#g=tRF)}iOR?$NHB7?q|SOYlGuN>1FO>NdYkXik0dgOp< zg~uqCx}v!`1nI*eve!aSuSfK=0<)`Rs@@jehZmL@wJcf~=E;Tqbua|FQNe)v8G!Y9 zWWFdA60HL>lFGMwlIBsE9(-`64PKbSIj2yd^9Lm-3%X2yF%~l{VOZ)rvmT9l{zvxt>r)Su3 zvWT)v`g`){zJn31vimjYY%)aE9t^(GxusP%cFm~#2G_Z3Dh&0Nxk)9fs>P%uw0zvX z@9;6~+Q#sb$-2P5=kw&k$MI3_(B8)mN4rxqG>5vPzc{%?u}n(sPnSuzr|kT)Pygl~ z{iUv_rOu@nr?_4vCI-Qipip)T2|b2mDIOfGml_Il4nJSdNJ&dm!Toy_o+QX^+^*=v zMC*YF?!S79L5FL zRebt16qNp++ml+D_XZ4}9chOT9;^Tq(d-FN4NG+ld%QYdQGY0Y*oy+h8)75;T~k~8 zV|RD==%J8Pt7T*g#JO9;PYU2TP5k+j_xjhh*8zJ%7;plv_FcVfX2y75frd;z{Jg=` zVah_VNKdiKL===u|0-E8Y5i@Lp5yQiQrE-Gdod~wW$V_O9ufV0`oB1(D1WYi$h2iz za^ox-h_JI#D7WG7opqDG=krr=kGK0!SO3^pva{fjy6phR6cm_Q$W{|2>(5;(y0e-D zxY!4GXJ;MoY=#@kKAJtgFAp==D0ZL8*M%_ThbttHJM5?p3jXY51-T3#hm)O`&4G7> zOsOkE5V5>!Q>dL)^5-I`d`#!$;K=EGtQ<%PYf0B9FD4*A~#&)kxqtX2f(3A**%ws`kH}>@T z{HeOyrN^*mbd(9xQAXEgO-zQlWV|soJ-~eO)G3A)5#P_SuV96!v*z-YHf`FZ z;Qew<-!Nu3o+z>$T~{khZaW}K`s zTkoun^3gizIJHa9`PXqWMFxWujGGSXcSRxVpKZBng7wm;5*m-nU!O~O9Zf*g>O1E) zzdl7L`wnhjA0DP)WWDq9?VT}Er&3${nlHG=cmP@Pn3@p zCX~no2q`fm)jWY08z4Bu#6)4l##94dle4lCA@kor+T@*5e=6T(^NY_hhVGFMdD-MJ z14etiksazq#9iR0yugHflj;Qx4MV&S(v$A>*W|&V@>iA@gt`O0u|J&zV(Wd-!VHni zBSY}`Q#_L74LU`~``QC$EhOqd&+D`p*N0q=rKe9;uPSntMSZx00V;ASpl-2pa|Z+* znWumJSc&el#%B$I36?;KE(aP!T*xUbQhgkGoq8D?4NLs<@tEOqNj@e;c^!D|6AlTQ`(sJVsH_`33B28Kih!+*t*0NxnOCDg0=A$!;7WK-d z`X7JD7!YtNeTEh@!7k+>0yJM=S7%k#k(!)*91Aw`1dI_PRyPA z{)CmXc8ca3Mi-9aEm6CEwH7RItf;798QtMP)}gJdo*wUBi~S0?dNwPx5b*XV0xWn0jJwYzP+Ro5txd#R=eZltTf{i-6Rd=7*La)B58{@?p5-fP)vCOf&G5jVkc$D+nM_%aTy! zwR-Zp$g?}4rhY@xhrqO@g1o%AWfxh4-{P9SAeHb^Z4VX|X~q|51*G{+^y3Lbk8VwV z_XQOr0zscLIx;a59cPI}<}}|A{b98`&cUCyBa#OXt|6@L>>k5An;QCse4Pi0N?Dh! zMfFt};j^zNMBzG9D7}hPTx~FOAsJH!q=%*O zxQzSQOn7Js43Q1UX#%$wKH9B{Cyw|)R{Z?*plbHl?-;5EHKal=4kt)4yP4a{=KUn7 zAUSD`m#hb_y&W0J1*e>JltNC$nJc1hg6UVTJ_VjyLWL|f9H=0qxNzwAvy*3lg`RD8 zEz@SvRa(hxw^(NzmDaw-CIRD?TJv$flJkOF~qQz^LJ zckbTYz17RNLxB<@sT7r!(URFOu$6tVO#g!7cUsB6E88#^22m8l6RT_waY1shLcW@S zfJsHjVq-z2spPgbCTAImM<@56L4+Z5K{K}g)6wnDa0GPcpYVO(`+YCl?1G+!g`oKL z&Xfm-6XEMAK*Ykpi3rdb zxzfZNOlJ)Erei#TaKC?_+5HLknMiE%xq08=kfi!+CCHeHn74`G@mSCE^S6SB;S81{ z1pjE~^~UM%u9FF7@ol>-+SCu=#U7OdEomORsk$jWs{#xH7hJ{OKFbgmt|yrAh1AweKD zeYIock0ahb6mEk04~{KccJT4Z3F+sXPg}>kyeq#Xastno0J3{O-_Dp;m|nPka$|yyt zTVA|H6hg|h`q_CwgnL5T4po0Fv!TsChuZBf!*#j4dD1>PEt4a0TK2iBI zh;#LX>bu?^zIDt#bhzaOe6P~z<*A)`@6s(nNX)8a)7~+ydv=s?hh29GF-Ct@mGw{- zN?~Hebjo}D6l#=2q<|c2F_iU*@bUBeh-U!M!xkW(Ucr=)tv)(CFYn)fkr?j3|L4E{ zXm%kK+Ycq1JbMs1w?SpY*ecp*xkbky##}}47@rQu;hwTG1#)n{2xrF+&m$ruf1Ktx z5Z_-f_}t^U*1g3t_cknV&Lht3=oOe)hpk%zNjYcW>L!Ga5h5u9zIbE=Baxi106*#J z>$B0G&#>w}=DhT$wQ^+!(|jvS<8HGU+W35Q=jHs%`QHxDE8+ZYzz$wm5aPNH9@jcaY8)zBist5hiu(M*4ePfKNaGiF#qg`C|%Y*N>WLnE>!P zA9}0^6@F#N_7IF|p8fmRqmW_@p#;Y(C?v!S3eoJ`9P)G2P)-RVS=|phom{dyIq8ht zFLAv~rw1Z9;f@>xr$Q_RC#&w77!+604q*&{4dm01&%q*}=msqY52AbGah5#wrS=mu z1&Z7*8#wOM;eL5r*IBA_N9MKzt02tof$6&*Tytd(9=CMg%x@V z^1(n17z3Z(nEP!+p@4O*$0cu;c6{gKLq1i5T9$l*N4D!y4q$kd4~0)&e!HmXdEyg> zsgBEELCwc2=K6!LE?}c&5rOESu<6&KKhAyRUf!k-uC7w0X#$RQRG}oWodx+ zPAvUMK|V|ayA2$MaEDWl2RGiu zP%*YCl2E694q{jE)rdX9!j>~>3bAQl|G>Ee9xsFu z(ewQ~E#-F6rJlm|`#?g|3cI_}+|%%6wt*GIQrohu`J!B=FB0xWmz4FquHx}V1iC1m zP~n5A`yw1ZQdXl&R_`!fh}Xy(`}O-bwUv!`lJBtd7tjkg`)+^@Heo$~3@ly7!!^j< z81Aw)CQQ~!{k>Gi#UNy0H$O(5b@8ds}X67)iBRa}u zH*v=GxJ-tMuxU)j$Ve((h$OoVqkBn{VJC)>+)`2V}$q`K3-W@ZO)H{PL|1*ty(pKj=gO8^0le){|THjX8pb-+HP|0G<)-1y(5QaY%nbi znM1hdxJLPj-9bB;+FfU#pBB23>_cS8H|CC}P1Mg6P3WDSDB9*EtA?7S zGiRGllz+Rn-n?JsXdtA&d6qWPJWj*va~D~j ztHIDP*+>$ryG)ibxo5a|_k{89zco#R8IIjpF2ADo)t`T@#mionl760dRphQ26nIIm zXB5pTAJ$h>9DSbW%i)`{D;2gR#R(yrz;jTo72UB#yMZ`9pI(Bte}v`%<&gws@3(ef zp+UlFN$P?Q97LEqvpJOJPHGv*K+WULVB11ICcN*I{we$ASNs-Cc=B=(BL-DmO=9)^ zK;SF3bQA~+NkVeu-2U^aNT0vpPgj$Sx}KNz{g{!4tvp#!*)Kwy+*s#i?~&h z?o-2~qT%tdP#aKm=Rldusp8TacjVI&eAXm36YT-AX*lxSw7h6nQZ9{27%2p3M8V}c z8a=(H*Ei2N7der{ToWXgEglcF?e)~U0?WY`qVsPD|5*L!Ft-38cJZyj8JQ@yHKbuP z+;p-#>iaMQ1{2^Y)Kco2eWlz*9y|vx^?Q!aJI~MWr>f^$jhB}9o%@Em3Tw0(eKp`@ z3?dsZqB}RY)h__U$*g{vMiL~gPaRwo@6T`20Ins)z27EPnsiTR$ zd(IVjM<6HAmEuJRyDZ2cAWx5yFZ)h=nv?i1vm*L2xm+tO+_56=DnRFIq)Xtue~w`V z1{bX-dbHmAFvWT=5@>)2V z=oN9)WGh@x`rJyu4*YXg#J;Xld6@$r_uh`7{BPBy3?~zdQNa6N$BRWTJ9D42Ol%D! zx0sBi{bQs2meI|}5(2Ddf~w%o**UhZ-6uj&K1hSKwDKJ8s*^V|O2R3yH>?fL=z&oB|7`ka;34Sa%>J$h4Z zHnFIZgo`C6HB}47S#jsi)&xZl^9DMRS>58|%OjX!^J@3Zklxug(8K@tSQV$5nwpgK z3u8IZdoQ3j244ZYO5k26RD*QqY*RhWuheGrQhUCO1j%>4ZKTA5>toDcbLmEtI-!s&ngka{Z2dOxS9&rK*7 zDV##dPwdzq`B#jxl0?kL38T#-N?Kx;?Dfqv$5_zJXwIqk0+-juZg)THJKR7dn~lWXD?$x| zmCF6tFBZ+68(7i;_$`L@UZWr=lBg!@9yan6U8$+DJzDwtmp+pTz1pi(ig;hZ+bcJ3 zE?IGY)hFQkLq)5Jby>8CS35r2-NmIMSK78&@&fyl^7G8wB(eM7@1(puyu(Pb`S zM=y$Rg@%@%`^wh!meup)3;6QKeWUIM6^^$;m_h|m8O(IPG$nFkP&H53dD*;<-es@}z2ogzJ zsZi(N=IX3&jyP54J>>|(Gu;ZJ387ddFW)3ld092_e<8=H`T?l-ldcOC4D zZP)bn)lt6Ut7;apSD`d8%XFm*u(59Rs6lskucd;`#IfwG1#6uMK#007mpk37cJ*V+ z{XkoMMu7hH?yg1y0U+1ajlxjunmUs@edV11-_o+8sw8)ep= zYfO`3t|tTKYIU`ZQ_(SfD#aE?4PbyDktL+Q>bSY5d8obLXcoaOnIyh^Ze?|Jz`z$D zr#;Yn%_w$>I1E6x^vdz~fe^LGDYDpgqi{1)B#OOTr2U19a;93hhLwhywW)ru9vl`u zP9P?8gET+65pn#u*lj8*E8VLTKW+B?8e=vxCJjlT$#c3plPlrpW>eDN@6#uU0>xu!9HdKuM4bnE3grwk&yt1rts)D#=*D$1`qS&HG&-STsAY2>0fa zQ|b~YQ;+|Sde(JBNbr(VmvM&e5{h)ld8aqt@Kvg3Hx0d7(jOfg;u*@o_>YuwyQXi# zAHH^JsjzO(!uKRF4v*$zC21&hRy0c|KxVkuB9r5}kAIxwmrIu9rPXc=LA>LUe>OSs zsIjj{W`G`-|Hy2ApYS&=&WiB!o6b(lU&v72ZAj$a`-Hnq=hpQ`BE@d~sZBzei_k~# zUWF!sO;(ZeIAn6Rh%p(UtsPu$=ldc4SD6?|k&rn2vf~5LF-2+-D4~$K2#OTT=}y5^ zNjQjh0qQy+XO1l$$Zfccm!R56OTu3{8ID$+Y;|FDVBeibq(xlz7=3+VyI?Qg8r~)@ zL{-g0G8Ky2QywHDNl0mYLoCQ<;D=#*7dod{>&)Du!9jB_YXRI5c}sW;;N5)1uypa_ za;rH!{5r-y9|=qn?<^$rJtx0e!^3a7Y^>GY8$YwgUm=$pTYE+YMS-mVzkey069}hI zMQ8IZK34?jx0Zg~JPDP463L9K$hNxAcD03jHE^IHVva?4>dxAFTJ^ldtl)J{SMw$@ z^YF7|vZ)XzAN22USw&uA^;6K&l=NCweDBu{r>;6r->v-I+nafe-zTlH$I6~gPlBG^$CC*IfZ-Tz|W0_2#-N?3* z+Zw)5SpU_?>jGH?X=Q%9+uLhyS0EI$ZFm%~GaR`1cGqc}^|yz9^pQzIIUiZk4^QNk zsP4}7;<4+f51D+yrR?k^*QWjf9qLf$y%;b7>6Tl)W#LJ2X?pbN)bU$gbwT}~5V0Q1zN}Fq3`Z1 zc|A_dN8EGr96n|_CKV3mfT2To{q)mM203fW!z#8eT;E<(nb_Ros3&V|$Vka0WBwAn zWUc?ph$IE`z9^T8Yp(7#d>R%{px32)_eKB&oBr+0Pa?SX-AQ2h*;lp%^lsuhCSyWSKqC;caz^8f@Tg8 zFGoJzxFYTWu7g0lmv3>ij{829i3(4qDPt_FT;Zg_1Cx_a>|Ln0XQ5;AI?bTDuU?AM zf(rIGup3Q=A%{}K$AE|sB?i8x)mw7JtL@tLp2)+5C5btG`hD8)=;h;{jr73LE9P8b z4{=usnj8yUTj8`@7c-0CE1p&qzNoo)u3^J>vCTvsNSG2-PYcEuyQE-gx(sp4CvEhT zh-Vc;)^i_Y$PbYb$gfB7WPF=ps5x}#;Yn9x*KKyI%>O|=p$5(CE%Wy(|CwE`8~RvS zv;~9&rC^0_?^t{_q^A+Mhnk5U?I9iWv6wjNt7{v7J+sW*e6*}YVMX5JXNHC${K1H2 zR(S_$-8$;a?-1+;h2kJkvRuF<-fx=I9^ipGz=^XE@zf9CK^_kb`$8Y6Cu!~VL7dp3 zIOA!+8&d2`69IBo85tRAY$sgrx(HYDcoW5h1~4-O^uQ`(>lr`%8)9Lq%y5q@iH&z{ zsm-ZX*xQV-!7~__ZJ*_1anGk|Vy{uqgJFUaaB>tM=+RJ{lOrJo3wO$Q2PFhc8%izo zrp4*^V8k|?vep^Qw%z-sx%rRcQ!T)su3o>sNRYtsGx;uJkp zKT@55Zh?j;V2QfA;xqq1nU}{F8zJr?z#K> pCxd$M1>MM?|K^LLBkQ_*b!?BB)4e2sAxV-JEm$HyKhNR2e*t1r^{@Z{ literal 0 HcmV?d00001 diff --git a/README.md b/README.md index efa9528d4d..eaf9aac2f1 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,34 @@ -# PE/COFF loader designed with formal methods +# Acidanthera UEFI Development Kit + +AUDK is a fork of [EDK II project](https://github.com/tianocore/edk2) focused on security.
+The main goal of AUDK project is to bring the best practices of secure code development into firmware domain.
+These practices include (but are not limited to) static analysis, fuzzing, formal verification,
+code hardening through various compiler optimizations and codebase architectural refactoring. + +[STATUS.md](STATUS.md) lists current states of the supported packages (toolchains, targets, CI supervision). + +Stable branches in AUDK project are constructed by rebasing all the commits in master branch upon EDK II stable tag.
+Available stable branches:
+[audk-stable-202211](https://github.com/acidanthera/audk/tree/audk-stable-202211)
+[audk-stable-202302](https://github.com/acidanthera/audk/tree/audk-stable-202302)
+[audk-stable-202305](https://github.com/acidanthera/audk/tree/audk-stable-202305)
+[audk-stable-202311](https://github.com/acidanthera/audk/tree/audk-stable-202311)
+[audk-stable-202405](https://github.com/acidanthera/audk/tree/audk-stable-202405)
+ +## Supported features +[PE loader designed with formal methods](#pe-loader-designed-with-formal-methods)
+[UEFI Executable File Format](#uefi-executable-file-format)
+[ImageTool](#imagetool)
+Ext4Pkg, FatPkg: Various improvements based on [Sydr](https://github.com/ispras/oss-sydr-fuzz) fuzzing results
+Introduced CpuArchLib to move the CPU Architectural initialization to DxeCore (https://bugzilla.tianocore.org/show_bug.cgi?id=3223)
+CI checks not only compilation results of various packages but also boot results of Windows 10 / Linux kernels for OVMF, ArmVirtQemu
+Introduced new image protection policy, which forbids loading of unaligned images
+ +## PE loader designed with formal methods This branch demonstrates the integration of a new PE/COFF loader designed with the help of formal methods into the EDK II infrastructure. -## Introduction +### Introduction The PE/COFF loader is one of the central components of the firmware core and its trust base. Every Image which is part of a UEFI system, including platform drivers from the primary firmware storage, Option ROMs from external hardware, and OS loaders from arbitrary storage, is verified and loaded by this library. Clearly it is a key component to ensure platform reliability and software compatibility, and can only be modified with great care. It also is an essential component for security technologies such as Secure Boot and Measured Boot. @@ -14,41 +40,45 @@ The usage of formal methods to design the new solution greatly helped restore th Please also refer to the new work-in-progress documentation available at [MdePkg/Library/BasePeCoffLib2/Documentation.md](MdePkg/Library/BasePeCoffLib2/Documentation.md) -## Further abstraction +### Further abstraction The new solution has been implemented as a new library class in MdePkg. ``PeCoffLib2`` features a new API that allows for a more resilient and a more flexible caller design. Most notably, all Image operations have been integrated into the API design rather than the callers accessing the library context and duplicating certain work. ``PeCoffLib`` remains intact as deprecated API to support legacy code during the transition period. To increase platform flexibility, a new layer of abstraction is introduced in the form of the library class ``UefiImageLib``, which can be found at [MdePkg/Include/Library/UefiImageLib.h](MdePkg/Include/Library/UefiImageLib.h). Currently, it is a subset of the APIs provided by ``PeCoffLib2`` that is expected to be compatible with most other common executable formats, plus a few convenience functions. As part of the proposal, the instance ``UefiImageLibPeCoff`` is provided, which is basically a shim for ``PeCoffLib2``. In the future, instances to support other file formats can be introduced without having to integrate them across the entire EDK II tree. -## Issues of the current solution +For security and code size optimization reasons, the ``UefiImageLib`` design is complicated. +To not expose FV-only UEFI image formats via, e.g., DxeCore to untrusted sources, +``UefiImageLib`` can be configured to support different UEFI image formats per source. + +### Issues of the current solution * High level of maintenance cost due to convoluted function contracts * Error-prone design promoting the introduction of code bugs * Multiple real-world bugs affecting reliability, some unaddressed for years * A lot of duplicate caller-side code that decreases the flexibility of porting and integration (e.g. Image permissions in PEI) * Dependency on Image re-parsing for production code -## Benefits of the new solution +### Benefits of the new solution * Fixes all known reported BugZilla tickets on PE/COFF loader reliability * Formal methods increase confidence in a high level of reliability and security * Improved design eases future maintenance and extension * Architecture-independent Image processing (e.g. for emulation) * Support for more granular Image section permissions (e.g. read-only) -## Benefits of the formal methods involved +### Benefits of the formal methods involved * Complete proof arithmetic cannot overflow (excluding intentional modulo arithmetic) * Mostly complete proof memory accesses are safe (requires axioms) * Complete proof of Image format compliance verification * Complete proof of Image loading * Mostly complete proof of Image relocation (final memory state cannot be easily described) -## Further notes about the formal approach +### Further notes about the formal approach * A snapshot of the new PE/COFF loader code will be provided with annotations and proving results * The snapshot will not be current and updating the old code is out of the scope of this project, however the functional changes should be manageable to review * We are currently investigating whether deploying the proving environment as a Docker container is feasible * There may be aids to compare the updates over the last fully verified state (e.g. stripped versions of the code with diffs) * If accepted, the new PE/COFF loader code should be developed further without updating the formal annotations, but with thorough review of important invariants and sufficient documentation -## Current progress, future goals, and further notes +### Current progress, future goals, and further notes * OVMF boots to Shell with SMM and Secure Boot enabled * Linux EmulatorPkg boots * Extended support for Image protection has been implemented @@ -58,14 +88,58 @@ To increase platform flexibility, a new layer of abstraction is introduced in th * Specified interfaces need adjustments (e.g. security architectural protocol) * Some validation is still absent -## BZs fixed by integrating the new PE/COFF loader +### BZs fixed by integrating the new PE/COFF loader * https://bugzilla.tianocore.org/show_bug.cgi?id=1860 * https://bugzilla.tianocore.org/show_bug.cgi?id=1999 * https://bugzilla.tianocore.org/show_bug.cgi?id=2120 * https://bugzilla.tianocore.org/show_bug.cgi?id=3329 * More to be added shortly... -## BZs easier to address by integrating the new PE/COFF loader +### BZs easier to address by integrating the new PE/COFF loader * https://bugzilla.tianocore.org/show_bug.cgi?id=3326 * https://bugzilla.tianocore.org/show_bug.cgi?id=3331 * More to be added shortly... + +## UEFI Executable File Format + +The Terse Executable (TE) format is a curious approach to reducing the size of PE files. +Essentially, it replaces the multi-layer Portable Executable (PE) image file header with a single, denser image file header. + +![image](PEvsTE.png) + +However, the conversion does not fix the internal offsets — this must be done by the image file loading — and +it is unlikely to reduce the size of memory page-aligned execute-in-place (XIP) image files. +The simpler parsing properties of having only a single, simple image file header are contrasted by the complexity of +considering the shift in data offsets and the semantic change to the image address space. +For XIP files, the replacement of the PE image file header also shifts the addresses of all image segments. +To account for this, EDK II’s PeiCore has a workaround to apply the shift to the load address, +so that the image file header is technically misaligned, but the image segments are correctly aligned. +This is especially important when enforcing memory permissions during PEI. + +We propose a novel executable file format (UEFI Executable File Format, [UE](https://github.com/mhaeuser/MastersThesis/tree/main)), +accompanied by a trivial digital signature scheme. (In our repository TE format is completely replaced with UE.) +Both help reduce the complexity of parsing and validation, while also encoding metadata much more efficiently than +the PE and the TE formats. They are specifically designed for UEFI firmware implementations and are explicitly not optimized +for the needs of modern operating systems. Compared to existing alternatives such as ELF and the Mach-O format, +the proposed alternative makes extensive use of encoding techniques to impose certain constraints on the metadata, +reducing the need for conformance validation. + +## ImageTool + +For compiler toolchain configurations based on GCC and Clang, EDK II generates ELF files in the first step. +To convert these into PE files, the TianoCore tool ``GenFw`` is used. It converts ELF image file sections to PE image file sections +while ignoring ELF image segments. Due to the great flexibility offered by ELF image file sections, conversion is done by using +custom static linking scripts to merge ELF image file sections as desired. +An undocumented detail of the EDK II build system is that all image files are generated as XIP, regardless of their phase or purpose. + +The main architectural flaw of ``GenFw`` and [other TianoCore tools](BaseTools/Source/C) is code duplication, i.e. +instead of using standard library modules of the already existing packages in the repository, necessary source files (or functions) +are simply copied into the building directory of those tools. + +We addressed that issue in our AUDK project greatly increasing code reuse among BaseTools and, in addition, +to make image file conversion easier to maintain, extend, and validate, we have replaced ``GenFw`` with ``ImageTool``. +``ImageTool`` implements an approach based on an intermediate representation. +This allows input and output formats to be processed independently of each other. +At the same time, operations such as relocating an image became format-independent, contributing to improved extensibility. +Because we designed the intermediate representation to be semi-canonical, we were able to use it to reduce the validation of the output file +to parsing the input file and comparing the resulting intermediate representation to the original one. From 4ac2e8a4d017efbe16ca82c54c7bff7ce18f547d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 24 Jul 2023 15:26:20 +0300 Subject: [PATCH 085/341] OvmfPkg: Increased SECFV_SIZE at FVMAIN_COMPACT's expense to fix CLANGPDB compilation. --- OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc b/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc index 6170c5993c..a933961464 100644 --- a/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc +++ b/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc @@ -62,9 +62,9 @@ DEFINE FW_BLOCKS = 0x400 DEFINE CODE_BASE_ADDRESS = 0xFFC84000 DEFINE CODE_SIZE = 0x0037C000 DEFINE CODE_BLOCKS = 0x37C -DEFINE FVMAIN_SIZE = 0x00348000 -DEFINE SECFV_OFFSET = 0x003CC000 -DEFINE SECFV_SIZE = 0x34000 +DEFINE FVMAIN_SIZE = 0x00345000 +DEFINE SECFV_OFFSET = 0x003C9000 +DEFINE SECFV_SIZE = 0x37000 !endif SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress = $(FW_BASE_ADDRESS) From 48b806f46f907e81bbd188663a63e597f4a0e26a Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 1 Jul 2024 12:18:06 +0300 Subject: [PATCH 086/341] UE: Support UE generation and consumption. --- ArmVirtPkg/ArmVirtCloudHv.dsc | 5 + ArmVirtPkg/ArmVirtKvmTool.dsc | 5 + ArmVirtPkg/ArmVirtQemu.dsc | 5 + ArmVirtPkg/ArmVirtQemuKernel.dsc | 5 + ArmVirtPkg/ArmVirtRules.fdf.inc | 52 +- ArmVirtPkg/ArmVirtXen.dsc | 5 + BaseTools/ImageTool/DynamicBuffer.c | 4 + BaseTools/ImageTool/GNUmakefile | 9 +- BaseTools/ImageTool/Image.c | 201 ++- BaseTools/ImageTool/ImageTool.c | 9 +- BaseTools/ImageTool/ImageTool.h | 13 +- BaseTools/ImageTool/ImageToolEmit.c | 22 +- BaseTools/ImageTool/Makefile | 11 +- BaseTools/ImageTool/PeEmit.c | 14 +- BaseTools/ImageTool/UeEmit.c | 1118 +++++++++++++ BaseTools/ImageTool/UeEmit.h | 10 + BaseTools/ImageTool/UeScan.c | 485 ++++++ BaseTools/ImageTool/UeScan.h | 19 + BaseTools/ImageTool/UefiImageScan.c | 42 +- BaseTools/Source/C/Common/GNUmakefile | 6 + BaseTools/Source/C/Common/Makefile | 6 + BaseTools/Source/C/GenFv/GenFvInternalLib.c | 146 +- BaseTools/Source/C/Include/Common/AutoGen.h | 2 +- BaseTools/Source/C/Makefiles/ms.rule | 4 + BaseTools/Source/Python/Common/DataType.py | 1 + BaseTools/Source/Python/GenFds/DataSection.py | 14 +- BaseTools/Source/Python/GenFds/EfiSection.py | 14 +- BaseTools/Source/Python/GenFds/FdfParser.py | 21 +- BaseTools/Source/Python/GenFds/Ffs.py | 1 + .../Source/Python/GenFds/FfsInfStatement.py | 24 +- BaseTools/Source/Python/GenFds/GenFds.py | 6 +- BaseTools/Source/Python/GenFds/Section.py | 5 +- .../Source/Python/UPT/Library/DataType.py | 1 + .../FspWrapperNotifyDxe/LoadBelow4G.c | 18 +- MdeModulePkg/Core/Dxe/DxeMain.inf | 2 + MdeModulePkg/Core/Dxe/Image/Image.c | 59 +- MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 6 +- MdeModulePkg/Core/DxeIplPeim/DxeLoad.c | 14 +- MdeModulePkg/Core/Pei/Image/Image.c | 216 ++- MdeModulePkg/Core/Pei/PeiMain.h | 17 +- MdeModulePkg/Core/Pei/PeiMain.inf | 1 + MdeModulePkg/Core/PiSmmCore/PiSmmCore.h | 11 + .../BootScriptExecutorDxe/ScriptExecute.c | 20 +- MdePkg/Include/IndustryStandard/UeImage.h | 667 ++++++++ MdePkg/Include/Library/UeImageLib.h | 181 +++ MdePkg/Include/Library/UefiImageLib.h | 59 + MdePkg/Include/Ppi/LoadFile.h | 19 + .../Library/BaseUeImageLib/BaseUeImageLib.inf | 33 + MdePkg/Library/BaseUeImageLib/UeImageLib.c | 1392 +++++++++++++++++ .../BaseUefiImageLib/BaseUefiImageAllLib.inf | 2 + .../BaseUefiImageOnlyFvLib.inf | 2 + .../BaseUefiImageOnlyNonFvLib.inf | 5 +- .../Library/BaseUefiImageLib/CommonSupport.c | 12 +- MdePkg/Library/BaseUefiImageLib/UeSupport.c | 560 +++++++ MdePkg/Library/BaseUefiImageLib/UeSupport.h | 16 + .../Library/BaseUefiImageLib/UefiImageLib.c | 68 +- MdePkg/MdeLibs.dsc.inc | 1 + MdePkg/MdePkg.dec | 13 +- MdePkg/MdePkg.dsc | 1 + OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc | 6 +- OvmfPkg/IntelTdx/IntelTdxX64.dsc | 5 + OvmfPkg/OvmfPkg.dec | 1 + OvmfPkg/OvmfPkgIa32.dsc | 5 + OvmfPkg/OvmfPkgIa32.fdf | 68 +- OvmfPkg/OvmfPkgIa32X64.dsc | 5 + OvmfPkg/OvmfPkgIa32X64.fdf | 70 +- OvmfPkg/OvmfPkgX64.dsc | 5 + OvmfPkg/OvmfPkgX64.fdf | 70 +- .../Vtf0/Ia32/SearchForSecEntry.asm | 13 +- UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c | 14 +- UefiPayloadPkg/UefiPayloadPkg.dsc | 5 + UefiPayloadPkg/UefiPayloadPkg.fdf | 18 +- 72 files changed, 5567 insertions(+), 398 deletions(-) create mode 100644 BaseTools/ImageTool/UeEmit.c create mode 100644 BaseTools/ImageTool/UeEmit.h create mode 100644 BaseTools/ImageTool/UeScan.c create mode 100644 BaseTools/ImageTool/UeScan.h create mode 100644 MdePkg/Include/IndustryStandard/UeImage.h create mode 100644 MdePkg/Include/Library/UeImageLib.h create mode 100644 MdePkg/Library/BaseUeImageLib/BaseUeImageLib.inf create mode 100644 MdePkg/Library/BaseUeImageLib/UeImageLib.c create mode 100644 MdePkg/Library/BaseUefiImageLib/UeSupport.c create mode 100644 MdePkg/Library/BaseUefiImageLib/UeSupport.h diff --git a/ArmVirtPkg/ArmVirtCloudHv.dsc b/ArmVirtPkg/ArmVirtCloudHv.dsc index 100e688020..3bda1c4210 100644 --- a/ArmVirtPkg/ArmVirtCloudHv.dsc +++ b/ArmVirtPkg/ArmVirtCloudHv.dsc @@ -156,6 +156,11 @@ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|3 gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize|0x20000 + # + # Firmware volume supports UE, and may require PE. + # + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03 + [PcdsFixedAtBuild.AARCH64] # Clearing BIT0 in this PCD prevents installing a 32-bit SMBIOS entry point, # if the entry point version is >= 3.0. AARCH64 OSes cannot assume the diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc index c12f48c5af..042ccabecf 100644 --- a/ArmVirtPkg/ArmVirtKvmTool.dsc +++ b/ArmVirtPkg/ArmVirtKvmTool.dsc @@ -162,6 +162,11 @@ # gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|16 + # + # Firmware volume supports UE, and may require PE. + # + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03 + [PcdsPatchableInModule.common] # # This will be overridden in the code diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 98a1a3ae1f..6f6a0e87a4 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -233,6 +233,11 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize | 0x40000 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize | 0x40000 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize | 0x40000 + + # + # Firmware volume supports UE, and may require PE. + # + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03 [PcdsFixedAtBuild.AARCH64] # Clearing BIT0 in this PCD prevents installing a 32-bit SMBIOS entry point, diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc index ba1f75b6e0..9330a7e7c6 100644 --- a/ArmVirtPkg/ArmVirtQemuKernel.dsc +++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc @@ -185,6 +185,11 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize | 0x40000 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize | 0x40000 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize | 0x40000 + + # + # Firmware volume supports UE, and may require PE. + # + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03 [PcdsPatchableInModule.common] # we need to provide a resolution for this PCD that supports PcdSet64() diff --git a/ArmVirtPkg/ArmVirtRules.fdf.inc b/ArmVirtPkg/ArmVirtRules.fdf.inc index 5865c2ef31..fbbac1d484 100644 --- a/ArmVirtPkg/ArmVirtRules.fdf.inc +++ b/ArmVirtPkg/ArmVirtRules.fdf.inc @@ -35,61 +35,61 @@ ############################################################################ [Rule.Common.SEC] - FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED FIXED { - PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + FILE SEC = $(NAMED_GUID) { + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi } [Rule.Common.SEC.SELF_RELOC] FILE SEC = $(NAMED_GUID) { - PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi } [Rule.Common.PEI_CORE] - FILE PEI_CORE = $(NAMED_GUID) FIXED { - PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING ="$(MODULE_NAME)" Optional + FILE PEI_CORE = $(NAMED_GUID) { + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional } [Rule.Common.PEIM] - FILE PEIM = $(NAMED_GUID) FIXED { - PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 Align = Auto $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional + FILE PEIM = $(NAMED_GUID) { + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional } [Rule.Common.DXE_CORE] FILE DXE_CORE = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional } [Rule.Common.UEFI_DRIVER] FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional } [Rule.Common.DXE_DRIVER] FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - RAW ACPI Optional |.acpi - RAW ASL Optional |.aml + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + RAW ACPI Optional |.acpi + RAW ASL Optional |.aml } [Rule.Common.DXE_RUNTIME_DRIVER] FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional } [Rule.Common.UEFI_APPLICATION] FILE APPLICATION = $(NAMED_GUID) { - UI STRING ="$(MODULE_NAME)" Optional - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi } [Rule.Common.UEFI_DRIVER.BINARY] @@ -102,7 +102,7 @@ [Rule.Common.UEFI_APPLICATION.BINARY] FILE APPLICATION = $(NAMED_GUID) { - PE32 PE32 |.efi + UE UE |.efi UI STRING="$(MODULE_NAME)" Optional VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc index 27378a049d..3cae4fa731 100644 --- a/ArmVirtPkg/ArmVirtXen.dsc +++ b/ArmVirtPkg/ArmVirtXen.dsc @@ -99,6 +99,11 @@ # gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE + # + # Firmware volume supports UE, and may require PE. + # + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03 + [PcdsPatchableInModule.common] # we need to provide a resolution for this PCD that supports PcdSet64() # being called from ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c, diff --git a/BaseTools/ImageTool/DynamicBuffer.c b/BaseTools/ImageTool/DynamicBuffer.c index 71ae192737..4ae0a0b1fc 100644 --- a/BaseTools/ImageTool/DynamicBuffer.c +++ b/BaseTools/ImageTool/DynamicBuffer.c @@ -10,7 +10,9 @@ #include "ImageTool.h" #include "DynamicBuffer.h" +#ifndef IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH #define IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH 0x1000 +#endif // IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH void ImageToolBufferInit ( @@ -186,9 +188,11 @@ ImageToolBufferDump ( void *Data; uint32_t DataSize; + // LCOV_EXCL_START if (Buffer->Memory == NULL) { return NULL; } + // LCOV_EXCL_STOP DataSize = ImageToolBufferGetSize (Buffer); diff --git a/BaseTools/ImageTool/GNUmakefile b/BaseTools/ImageTool/GNUmakefile index 2981bc86ac..c7594fa4c9 100644 --- a/BaseTools/ImageTool/GNUmakefile +++ b/BaseTools/ImageTool/GNUmakefile @@ -7,10 +7,10 @@ PROJECT = ImageTool PRODUCT = $(PROJECT)$(INFIX)$(SUFFIX) OBJS = $(PROJECT).o -OBJS += Image.o UefiImageScan.o PeEmit32.o PeEmit64.o PeEmitCommon.o PeScan.o ElfScan32.o ElfScan64.o ElfScanCommon.o BinEmit.o ImageToolEmit.o -OBJS += UefiImageExtraActionLib.o +OBJS += Image.o UefiImageScan.o UeEmit.o UeScan.o PeEmit32.o PeEmit64.o PeEmitCommon.o PeScan.o ElfScan32.o ElfScan64.o ElfScanCommon.o BinEmit.o ImageToolEmit.o +OBJS += UeImageLib.o UefiImageExtraActionLib.o OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o PeCoffHash.o -OBJS += PeSupport.o UefiImageLib.o CommonSupport.o DynamicBuffer.o +OBJS += PeSupport.o UeSupport.o UefiImageLib.o CommonSupport.o DynamicBuffer.o WERROR = 1 DEBUG = 1 @@ -20,7 +20,8 @@ UDK_PATH = ../.. VPATH += ../../MdePkg/Library/BasePeCoffLib2:$\ ../../MdePkg/Library/BaseUefiImageExtraActionLibNull:$\ - ../../MdePkg/Library/BaseUefiImageLib + ../../MdePkg/Library/BaseUefiImageLib:$\ + ../../MdePkg/Library/BaseUeImageLib include $(OC_USER)/User/Makefile diff --git a/BaseTools/ImageTool/Image.c b/BaseTools/ImageTool/Image.c index 68c913f988..bc2a03d6ce 100644 --- a/BaseTools/ImageTool/Image.c +++ b/BaseTools/ImageTool/Image.c @@ -16,10 +16,12 @@ CheckToolImageSegment ( { bool Overflow; + // LCOV_EXCL_START if (!IS_ALIGNED (Segment->ImageSize, SegmentInfo->SegmentAlignment)) { - DEBUG_RAISE (); + assert (false); return false; } + // LCOV_EXCL_STOP if (Segment->Write && Segment->Execute) { DEBUG_RAISE (); @@ -32,14 +34,16 @@ CheckToolImageSegment ( } Overflow = BaseOverflowAddU32 ( - Segment->ImageAddress, - Segment->ImageSize, - PreviousEndAddress - ); + Segment->ImageAddress, + Segment->ImageSize, + PreviousEndAddress + ); + // LCOV_EXCL_START if (Overflow) { - DEBUG_RAISE (); + assert (false); return false; } + // LCOV_EXCL_STOP return true; } @@ -54,28 +58,32 @@ CheckToolImageSegmentInfo ( uint32_t Index; bool Result; + // LCOV_EXCL_START if (!IS_POW2 (SegmentInfo->SegmentAlignment)) { - DEBUG_RAISE (); + assert (false); return false; } + // LCOV_EXCL_STOP if (SegmentInfo->NumSegments == 0) { DEBUG_RAISE (); return false; } + // LCOV_EXCL_START if (!IS_ALIGNED (SegmentInfo->Segments[0].ImageAddress, SegmentInfo->SegmentAlignment)) { - DEBUG_RAISE (); + assert (false); return false; } + // LCOV_EXCL_STOP *ImageSize = SegmentInfo->Segments[0].ImageAddress; for (Index = 0; Index < SegmentInfo->NumSegments; ++Index) { Result = CheckToolImageSegment ( - SegmentInfo, - &SegmentInfo->Segments[Index], - ImageSize - ); + SegmentInfo, + &SegmentInfo->Segments[Index], + ImageSize + ); if (!Result) { DEBUG_RAISE (); return false; @@ -99,15 +107,19 @@ CheckToolImageHeaderInfo ( return false; } + // LCOV_EXCL_START if (!IS_ALIGNED (HeaderInfo->BaseAddress, SegmentInfo->SegmentAlignment)) { - DEBUG_RAISE (); + assert (false); return false; } + // LCOV_EXCL_STOP + // LCOV_EXCL_START if (HeaderInfo->BaseAddress + ImageSize < HeaderInfo->BaseAddress) { - DEBUG_RAISE (); + assert (false); return false; } + // LCOV_EXCL_STOP return true; } @@ -138,7 +150,9 @@ ToolImageGetRelocSize ( uint8_t Type ) { + // LCOV_EXCL_START switch (Type) { + // LCOV_EXCL_STOP case EFI_IMAGE_REL_BASED_HIGHLOW: { return sizeof (UINT32); @@ -156,11 +170,18 @@ ToolImageGetRelocSize ( } #endif + // LCOV_EXCL_START default: { - return 0; + break; } + // LCOV_EXCL_STOP } + + // LCOV_EXCL_START + assert (false); + return 0; + // LCOV_EXCL_STOP } static @@ -214,9 +235,8 @@ CheckToolImageReloc ( #endif // FIXME: Update drivers? - if ((Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER || - Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) && - Segment->Write) { + if (Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER && + Segment->Write) { printf("!!! writable reloc at %x !!!\n", Reloc->Target); //DEBUG_RAISE (); //return false; @@ -243,10 +263,12 @@ CheckToolImageRelocInfo ( return true; } + // LCOV_EXCL_START if (RelocInfo->RelocsStripped) { - DEBUG_RAISE (); + assert (false); return false; } + // LCOV_EXCL_STOP if (RelocInfo->NumRelocs > (MAX_UINT32 / sizeof (UINT16))) { DEBUG_RAISE (); @@ -262,10 +284,12 @@ CheckToolImageRelocInfo ( } RelocSize = ToolImageGetRelocSize (RelocInfo->Relocs[Index].Type); + // LCOV_EXCL_START if (RelocSize == 0) { - DEBUG_RAISE (); + assert (false); return false; } + // LCOV_EXCL_STOP Result = CheckToolImageReloc (Image, &RelocInfo->Relocs[Index], RelocSize); if (!Result) { @@ -357,33 +381,47 @@ ToolImageDestruct ( image_tool_image_info_t *Image ) { - uint8_t Index; + uint16_t Index; + // LCOV_EXCL_START if (Image->SegmentInfo.Segments != NULL) { + // LCOV_EXCL_STOP for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { + // LCOV_EXCL_START if (Image->SegmentInfo.Segments[Index].Name != NULL) { + // LCOV_EXCL_STOP FreePool (Image->SegmentInfo.Segments[Index].Name); } + // LCOV_EXCL_START if (Image->SegmentInfo.Segments[Index].Data != NULL) { + // LCOV_EXCL_STOP FreePool (Image->SegmentInfo.Segments[Index].Data); } } + // LCOV_EXCL_START if (Image->SegmentInfo.Segments != NULL) { + // LCOV_EXCL_STOP FreePool (Image->SegmentInfo.Segments); } } + // LCOV_EXCL_START if (Image->HiiInfo.Data != NULL) { + // LCOV_EXCL_STOP FreePool (Image->HiiInfo.Data); } + // LCOV_EXCL_START if (Image->RelocInfo.Relocs != NULL) { + // LCOV_EXCL_STOP FreePool (Image->RelocInfo.Relocs); } + // LCOV_EXCL_START if (Image->DebugInfo.SymbolsPath != NULL) { + // LCOV_EXCL_STOP FreePool (Image->DebugInfo.SymbolsPath); } @@ -443,7 +481,9 @@ ToolImageRelocate ( ); assert (Segment != NULL); + // LCOV_EXCL_START switch (Reloc->Type) { + // LCOV_EXCL_STOP case EFI_IMAGE_REL_BASED_HIGHLOW: { assert (RemainingSize >= sizeof (UINT32)); @@ -475,11 +515,13 @@ ToolImageRelocate ( } #endif + // LCOV_EXCL_START default: { assert (false); return false; } + // LCOV_EXCL_STOP } } @@ -531,14 +573,14 @@ ToolImageSortRelocs ( bool ToolImageCompare ( - const image_tool_image_info_t *Image1, - const image_tool_image_info_t *Image2 + const image_tool_image_info_t *DestImage, + const image_tool_image_info_t *SourceImage ) { int CmpResult; uint32_t SegIndex; - const char *Name1; - const char *Name2; + const char *DestName; + const char *SourceName; uint32_t NameIndex; // @@ -546,14 +588,16 @@ ToolImageCompare ( // CmpResult = memcmp ( - &Image1->HeaderInfo, - &Image2->HeaderInfo, - sizeof (Image1->HeaderInfo) + &DestImage->HeaderInfo, + &SourceImage->HeaderInfo, + sizeof (DestImage->HeaderInfo) ); + // LCOV_EXCL_START if (CmpResult != 0) { DEBUG_RAISE (); return false; } + // LCOV_EXCL_STOP // // Compare SegmentInfo. @@ -562,55 +606,78 @@ ToolImageCompare ( // CmpResult = memcmp ( - &Image1->SegmentInfo, - &Image2->SegmentInfo, + &DestImage->SegmentInfo, + &SourceImage->SegmentInfo, OFFSET_OF (image_tool_segment_info_t, Segments) ); + // LCOV_EXCL_START if (CmpResult != 0) { DEBUG_RAISE (); return false; } + // LCOV_EXCL_STOP - for (SegIndex = 0; SegIndex < Image1->SegmentInfo.NumSegments; ++SegIndex) { + for (SegIndex = 0; SegIndex < DestImage->SegmentInfo.NumSegments; ++SegIndex) { CmpResult = memcmp ( - &Image1->SegmentInfo.Segments[SegIndex], - &Image2->SegmentInfo.Segments[SegIndex], + &DestImage->SegmentInfo.Segments[SegIndex], + &SourceImage->SegmentInfo.Segments[SegIndex], OFFSET_OF (image_tool_segment_t, Name) ); + // LCOV_EXCL_START if (CmpResult != 0) { DEBUG_RAISE (); return false; } + // LCOV_EXCL_STOP // // Don't assume images generally support arbitrarily long names or names in // general. Check prefix equiality as a best effort. // - Name1 = Image1->SegmentInfo.Segments[SegIndex].Name; - Name2 = Image2->SegmentInfo.Segments[SegIndex].Name; - if (Name1 != NULL && Name2 != NULL) { + DestName = DestImage->SegmentInfo.Segments[SegIndex].Name; + SourceName = SourceImage->SegmentInfo.Segments[SegIndex].Name; + + // LCOV_EXCL_START + if (DestName != NULL && SourceName == NULL) { + assert (false); + return false; + } + // LCOV_EXCL_STOP + + // + // When omitting the debug info, some file formats (e.g., UE) may not + // contain segment names. + // + if (DestName != NULL) { for ( NameIndex = 0; - Name1[NameIndex] != '\0' && Name2[NameIndex] != '\0'; + DestName[NameIndex] != '\0' && + // LCOV_EXCL_START + SourceName[NameIndex] != '\0'; + // LCOV_EXCL_STOP ++NameIndex ) { - if (Name1[NameIndex] != Name2[NameIndex]) { + // LCOV_EXCL_START + if (DestName[NameIndex] != SourceName[NameIndex]) { DEBUG_RAISE (); return false; } + // LCOV_EXCL_STOP } } - if (Image1->SegmentInfo.Segments[SegIndex].ImageSize != 0) { + if (DestImage->SegmentInfo.Segments[SegIndex].ImageSize != 0) { CmpResult = memcmp ( - Image1->SegmentInfo.Segments[SegIndex].Data, - Image2->SegmentInfo.Segments[SegIndex].Data, - Image1->SegmentInfo.Segments[SegIndex].ImageSize + DestImage->SegmentInfo.Segments[SegIndex].Data, + SourceImage->SegmentInfo.Segments[SegIndex].Data, + DestImage->SegmentInfo.Segments[SegIndex].ImageSize ); + // LCOV_EXCL_START if (CmpResult != 0) { DEBUG_RAISE (); return false; } + // LCOV_EXCL_STOP } } @@ -619,25 +686,29 @@ ToolImageCompare ( // CmpResult = memcmp ( - &Image1->RelocInfo, - &Image2->RelocInfo, + &DestImage->RelocInfo, + &SourceImage->RelocInfo, OFFSET_OF (image_tool_reloc_info_t, Relocs) ); + // LCOV_EXCL_START if (CmpResult != 0) { DEBUG_RAISE (); return false; } + // LCOV_EXCL_STOP - if (Image1->RelocInfo.NumRelocs != 0) { + if (DestImage->RelocInfo.NumRelocs != 0) { CmpResult = memcmp ( - Image1->RelocInfo.Relocs, - Image2->RelocInfo.Relocs, - Image1->RelocInfo.NumRelocs * sizeof (*Image1->RelocInfo.Relocs) + DestImage->RelocInfo.Relocs, + SourceImage->RelocInfo.Relocs, + DestImage->RelocInfo.NumRelocs * sizeof (*DestImage->RelocInfo.Relocs) ); + // LCOV_EXCL_START if (CmpResult != 0) { DEBUG_RAISE (); return false; } + // LCOV_EXCL_STOP } // @@ -645,55 +716,65 @@ ToolImageCompare ( // CmpResult = memcmp ( - &Image1->HiiInfo, - &Image2->HiiInfo, + &DestImage->HiiInfo, + &SourceImage->HiiInfo, OFFSET_OF (image_tool_hii_info_t, Data) ); + // LCOV_EXCL_START if (CmpResult != 0) { DEBUG_RAISE (); return false; } + // LCOV_EXCL_STOP - if (Image1->HiiInfo.DataSize != 0) { + // LCOV_EXCL_START + if (DestImage->HiiInfo.DataSize != 0) { CmpResult = memcmp ( - Image1->HiiInfo.Data, - Image2->HiiInfo.Data, - Image1->HiiInfo.DataSize + DestImage->HiiInfo.Data, + SourceImage->HiiInfo.Data, + DestImage->HiiInfo.DataSize ); if (CmpResult != 0) { DEBUG_RAISE (); return false; } } + // LCOV_EXCL_STOP // // Compare DebugInfo. // CmpResult = memcmp ( - &Image1->DebugInfo, - &Image2->DebugInfo, + &DestImage->DebugInfo, + &SourceImage->DebugInfo, OFFSET_OF (image_tool_debug_info_t, SymbolsPath) ); + // LCOV_EXCL_START if (CmpResult != 0) { DEBUG_RAISE (); return false; } + // LCOV_EXCL_STOP - if ((Image1->DebugInfo.SymbolsPath != NULL) != (Image2->DebugInfo.SymbolsPath != NULL)) { + // LCOV_EXCL_START + if ((DestImage->DebugInfo.SymbolsPath != NULL) != (SourceImage->DebugInfo.SymbolsPath != NULL)) { DEBUG_RAISE (); return false; } + // LCOV_EXCL_STOP - if (Image1->DebugInfo.SymbolsPath != NULL) { + if (DestImage->DebugInfo.SymbolsPath != NULL) { CmpResult = strcmp ( - Image1->DebugInfo.SymbolsPath, - Image2->DebugInfo.SymbolsPath + DestImage->DebugInfo.SymbolsPath, + SourceImage->DebugInfo.SymbolsPath ); + // LCOV_EXCL_START if (CmpResult != 0) { DEBUG_RAISE (); return false; } + // LCOV_EXCL_STOP } return true; diff --git a/BaseTools/ImageTool/ImageTool.c b/BaseTools/ImageTool/ImageTool.c index a93192945d..d3a4378e5c 100644 --- a/BaseTools/ImageTool/ImageTool.c +++ b/BaseTools/ImageTool/ImageTool.c @@ -321,11 +321,6 @@ NameToType ( return EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER; } - if ((strcmp (TypeName, "DXE_SAL_DRIVER") == 0) - || (strcmp (TypeName, "SAL_RT_DRIVER") == 0)) { - return EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER; - } - return -1; } @@ -335,6 +330,10 @@ NameToFormat ( IN const char *FormatName ) { + if (strcmp (FormatName, "UE") == 0) { + return UefiImageFormatUe; + } + if (strcmp (FormatName, "PE") == 0) { return UefiImageFormatPe; } diff --git a/BaseTools/ImageTool/ImageTool.h b/BaseTools/ImageTool/ImageTool.h index a0382d79d8..5ca3930872 100644 --- a/BaseTools/ImageTool/ImageTool.h +++ b/BaseTools/ImageTool/ImageTool.h @@ -13,8 +13,11 @@ #include #include +#include #include +#include #include +#include #include #include #include @@ -135,12 +138,20 @@ ToolImageGetRelocSize ( uint8_t Type ); +void * +ToolImageEmitUe ( + image_tool_image_info_t *Image, + uint32_t *FileSize, + bool Xip, + bool Strip + ); + RETURN_STATUS ToolContextConstructUefiImage ( OUT image_tool_image_info_t *Image, OUT INT8 *Format, IN const void *File, - IN size_t FileSize + IN uint32_t FileSize ); bool diff --git a/BaseTools/ImageTool/ImageToolEmit.c b/BaseTools/ImageTool/ImageToolEmit.c index b874843532..4f7be6786f 100644 --- a/BaseTools/ImageTool/ImageToolEmit.c +++ b/BaseTools/ImageTool/ImageToolEmit.c @@ -68,20 +68,24 @@ ValidateOutputFile ( } Result = CheckToolImage (&OutputImageInfo); + // LCOV_EXCL_START if (!Result) { assert (false); ToolImageDestruct (&OutputImageInfo); return RETURN_UNSUPPORTED; } + // LCOV_EXCL_STOP Result = ToolImageCompare (&OutputImageInfo, ImageInfo); ToolImageDestruct (&OutputImageInfo); + // LCOV_EXCL_START if (!Result) { assert (false); return RETURN_VOLUME_CORRUPTED; } + // LCOV_EXCL_STOP return RETURN_SUCCESS; } @@ -115,15 +119,18 @@ ToolImageEmit ( SymbolsPath ); + // LCOV_EXCL_START if (SymbolsPath == NULL) { SymbolsPath = ""; } + // LCOV_EXCL_STOP if (RETURN_ERROR (Status)) { fprintf (stderr, "ImageTool: Could not parse input file %s - %llx\n", SymbolsPath, (unsigned long long)Status); return NULL; } + // LCOV_EXCL_START if (Format == -1) { Format = SourceFormat; if (Format == -1) { @@ -136,6 +143,7 @@ ToolImageEmit ( if (Type != -1) { ImageInfo.HeaderInfo.Subsystem = (uint16_t)Type; } + // LCOV_EXCL_STOP ToolImageSortRelocs (&ImageInfo); @@ -160,11 +168,18 @@ ToolImageEmit ( } OutputFile = NULL; - if (Format == UefiImageFormatPe) { + // LCOV_EXCL_START + if (Format == UefiImageFormatUe) { + // LCOV_EXCL_STOP + OutputFile = ToolImageEmitUe (&ImageInfo, OutputFileSize, Xip, Strip); + } + // LCOV_EXCL_START + else if (Format == UefiImageFormatPe) { OutputFile = ToolImageEmitPe (&ImageInfo, OutputFileSize, Xip, Strip); } else { assert (false); } + // LCOV_EXCL_STOP if (OutputFile == NULL) { DEBUG_RAISE (); @@ -172,6 +187,11 @@ ToolImageEmit ( return NULL; } + if ((Format == UefiImageFormatUe) && Xip) { + ToolImageDestruct (&ImageInfo); + return OutputFile; + } + Status = ValidateOutputFile (OutputFile, *OutputFileSize, &ImageInfo); ToolImageDestruct (&ImageInfo); diff --git a/BaseTools/ImageTool/Makefile b/BaseTools/ImageTool/Makefile index 3e91a6ecae..ec1dfd28d2 100644 --- a/BaseTools/ImageTool/Makefile +++ b/BaseTools/ImageTool/Makefile @@ -17,10 +17,11 @@ OUT_DIR = .\Windows OV = $(UDK_PATH)\MdePkg\Library\BaseOverflowLib PE = $(UDK_PATH)\MdePkg\Library\BasePeCoffLib2 +UE = $(UDK_PATH)\MdePkg\Library\BaseUeImageLib UA = $(UDK_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull -OBJECTS = ImageTool.obj Image.obj PeEmit32.obj PeEmit64.obj PeEmitCommon.obj UefiImageScan.obj PeScan.obj ElfScan32.obj ElfScan64.obj ElfScanCommon.obj BinEmit.obj ImageToolEmit.obj -OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UA)}UefiImageExtraActionLib.obj DynamicBuffer.obj +OBJECTS = ImageTool.obj Image.obj PeEmit32.obj PeEmit64.obj PeEmitCommon.obj UefiImageScan.obj PeScan.obj UeScan.obj UeEmit.obj ElfScan32.obj ElfScan64.obj ElfScanCommon.obj BinEmit.obj ImageToolEmit.obj +OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UE)}UeImageLib.obj {$(UA)}UefiImageExtraActionLib.obj DynamicBuffer.obj OBJECTS = $(OBJECTS) {$(PE)}PeCoffInit.obj PeCoffInfo.obj PeCoffRelocate.obj PeCoffLoad.obj PeCoffHii.obj PeCoffDebug.obj PeCoffHash.obj BASE = $(UDK_PATH)\MdePkg\Library\BaseLib @@ -33,7 +34,7 @@ CMEM = $(UDK_PATH)\MdeModulePkg\Library\CommonMemoryAllocationLib USER = $(OC_USER)\User\Library OBJECTS = $(OBJECTS) {$(BASE)}SafeString.obj String.obj SwapBytes16.obj SwapBytes32.obj CpuDeadLoop.obj CheckSum.obj QuickSort.obj LinkedList.obj OBJECTS = $(OBJECTS) {$(OUT)}DebugLib.obj {$(PRIN)}PrintLib.obj PrintLibInternal.obj {$(ERRO)}BaseDebugPrintErrorLevelLib.obj -OBJECTS = $(OBJECTS) {$(UIMG)}UefiImageLib.obj PeSupport.obj CommonSupport.obj +OBJECTS = $(OBJECTS) {$(UIMG)}UefiImageLib.obj UeSupport.obj PeSupport.obj CommonSupport.obj OBJECTS = $(OBJECTS) {$(USER)}UserFile.obj UserBaseMemoryLib.obj UserMath.obj UserPcd.obj UserMisc.obj UserGlobalVar.obj UserBootServices.obj OBJECTS = $(OBJECTS) {$(BMPN)}BaseMemoryProfileLibNull.obj {$(CMEM)}CommonMemoryAllocationLib.obj {$(CMEM)}CommonMemoryAllocationLibEx.obj @@ -73,6 +74,10 @@ cleanall: $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ @move $@ $(OUT_DIR)\ +{$(UE)}.c.obj : + $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ + @move $@ $(OUT_DIR)\ + {$(UA)}.c.obj : $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ @move $@ $(OUT_DIR)\ diff --git a/BaseTools/ImageTool/PeEmit.c b/BaseTools/ImageTool/PeEmit.c index 305f42f945..fb0ea39a52 100644 --- a/BaseTools/ImageTool/PeEmit.c +++ b/BaseTools/ImageTool/PeEmit.c @@ -395,12 +395,14 @@ ToolImageEmitPeSection ( SizeOfRawData = Segment->ImageSize; } - strncpy ( - (char *)SectionHeader->Name, - Segment->Name, - sizeof (SectionHeader->Name) - ); - SectionHeader->Name[ARRAY_SIZE (SectionHeader->Name) - 1] = 0; + if (Segment->Name != NULL) { + strncpy ( + (char *)SectionHeader->Name, + Segment->Name, + sizeof (SectionHeader->Name) + ); + SectionHeader->Name[ARRAY_SIZE (SectionHeader->Name) - 1] = 0; + } SectionHeader->VirtualSize = Segment->ImageSize; SectionHeader->VirtualAddress = Segment->ImageAddress; diff --git a/BaseTools/ImageTool/UeEmit.c b/BaseTools/ImageTool/UeEmit.c new file mode 100644 index 0000000000..9fd42a737c --- /dev/null +++ b/BaseTools/ImageTool/UeEmit.c @@ -0,0 +1,1118 @@ +/** @file + Copyright (c) 2023, Marvin Häuser. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "ImageTool.h" + +#include "DynamicBuffer.h" + +static +uint8_t +AlignmentToExponent ( + uint64_t Alignment + ) +{ + uint8_t Index; + + assert (IS_POW2 (Alignment)); + + for ( + Index = 0; + // LCOV_EXCL_START + Index < 64; + // LCOV_EXCL_STOP + ++Index + ) { + if ((Alignment & (1ULL << Index)) == Alignment) { + return Index; + } + } + + // LCOV_EXCL_START + assert (false); + return 0; + // LCOV_EXCL_STOP +} + +static +bool +ToolImageEmitUeSegmentHeaders ( + image_tool_dynamic_buffer *Buffer, + const image_tool_image_info_t *Image, + bool Xip + ) +{ + uint16_t Index; + uint8_t Permissions; + UE_SEGMENT Segment; + uint32_t Offset; + + for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { + // LCOV_EXCL_START + if (Image->SegmentInfo.Segments[Index].Write && + Image->SegmentInfo.Segments[Index].Execute) { + assert (false); + return false; + } + // LCOV_EXCL_STOP + + if (!Image->SegmentInfo.Segments[Index].Read && + !Image->SegmentInfo.Segments[Index].Write && + Image->SegmentInfo.Segments[Index].Execute) { + Permissions = UeSegmentPermX; + } else if (Image->SegmentInfo.Segments[Index].Read && + !Image->SegmentInfo.Segments[Index].Write && + Image->SegmentInfo.Segments[Index].Execute) { + Permissions = UeSegmentPermRX; + } else if (Image->SegmentInfo.Segments[Index].Read && + Image->SegmentInfo.Segments[Index].Write) { + assert (!Image->SegmentInfo.Segments[Index].Execute); + Permissions = UeSegmentPermRW; + } else if (Image->SegmentInfo.Segments[Index].Read) { + assert (!Image->SegmentInfo.Segments[Index].Write); + assert (!Image->SegmentInfo.Segments[Index].Execute); + Permissions = UeSegmentPermR; + } else { + DEBUG_RAISE (); + return false; + } + + Segment.ImageInfo = Image->SegmentInfo.Segments[Index].ImageSize >> 12U; + Segment.ImageInfo |= Permissions << 20U; + assert (UE_SEGMENT_SIZE (Segment.ImageInfo) == Image->SegmentInfo.Segments[Index].ImageSize); + assert (UE_SEGMENT_PERMISSIONS (Segment.ImageInfo) == Permissions); + + Segment.FileSize = Xip ? Image->SegmentInfo.Segments[Index].ImageSize : Image->SegmentInfo.Segments[Index].UnpaddedSize; + + Offset = ImageToolBufferAppend (Buffer, &Segment, sizeof (Segment)); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + } + + return true; +} + +static +bool +ToolImageUeRelocTableRequired ( + const image_tool_image_info_t *Image + ) +{ + return Image->RelocInfo.NumRelocs != 0; +} + +static +bool +ToolImageUeDebugTableRequired ( + const image_tool_image_info_t *Image + ) +{ + // FIXME: Segment names when symbols are absent? + return Image->DebugInfo.SymbolsPath != NULL; +} + +static +int8_t +InternalGetUeMachine ( + uint16_t Machine + ) +{ + switch (Machine) { + case IMAGE_FILE_MACHINE_I386: + { + return UeMachineI386; + } + + case IMAGE_FILE_MACHINE_X64: + { + return UeMachineX64; + } + + case IMAGE_FILE_MACHINE_ARMTHUMB_MIXED: + { + return UeMachineArmThumbMixed; + } + + case IMAGE_FILE_MACHINE_ARM64: + { + return UeMachineArm64; + } + + case IMAGE_FILE_MACHINE_RISCV32: + { + return UeMachineRiscV32; + } + + case IMAGE_FILE_MACHINE_RISCV64: + { + return UeMachineRiscV64; + } + + case IMAGE_FILE_MACHINE_RISCV128: + { + return UeMachineRiscV128; + } + + default: + { + DEBUG_RAISE (); + return -1; + } + } +} + +static +bool +ToolImageEmitUeSegments ( + image_tool_dynamic_buffer *Buffer, + const image_tool_image_info_t *Image + ) +{ + uint16_t Index; + uint32_t Offset; + + for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { + Offset = ImageToolBufferAppend ( + Buffer, + Image->SegmentInfo.Segments[Index].Data, + Image->SegmentInfo.Segments[Index].UnpaddedSize + ); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + } + + Offset = ImageToolBufferAppendReserveAlign (Buffer, UE_LOAD_TABLE_ALIGNMENT); + return Offset != MAX_UINT32; +} + +static +void +ToolImageEmitUePadChainedRelocs ( + const image_tool_image_info_t *Image + ) +{ + uint16_t SegIndex; + image_tool_segment_t *Segment; + uint32_t RelocIndex; + const image_tool_reloc_t *Reloc; + uint32_t EndOfReloc; + bool HasReloc; + uint32_t LastRelocEnd; + uint32_t EndOfRelocOffset; + + LastRelocEnd = 0; + + RelocIndex = 0; + for (SegIndex = 0; SegIndex < Image->SegmentInfo.NumSegments; ++SegIndex) { + Segment = &Image->SegmentInfo.Segments[SegIndex]; + + HasReloc = false; + for (; RelocIndex < Image->RelocInfo.NumRelocs; ++RelocIndex) { + Reloc = &Image->RelocInfo.Relocs[RelocIndex]; + EndOfReloc = Reloc->Target + ToolImageGetRelocSize (Reloc->Type); + + if (EndOfReloc > Segment->ImageAddress + Segment->ImageSize) { + break; + } + + HasReloc = true; + LastRelocEnd = EndOfReloc; + } + + if (HasReloc) { + assert (Segment->ImageAddress <= LastRelocEnd); + EndOfRelocOffset = LastRelocEnd - Segment->ImageAddress; + + if (Segment->UnpaddedSize < EndOfRelocOffset) { + Segment->UnpaddedSize = EndOfRelocOffset; + } + } + } +} + +static +uint32_t +ToolImageEmitUeGetFileOffset ( + const image_tool_dynamic_buffer *Buffer, + uint32_t SegmentHeadersOffset, + uint32_t SegmentsOffset, + uint16_t NumSegments, + uint32_t Address, + uint32_t *Size + ) +{ + CONST UE_SEGMENT *Segments; + uint16_t Index; + uint32_t SegmentAddress; + uint32_t SegmentSize; + uint32_t SegmentOffset; + uint32_t OffsetInSegment; + + Segments = ImageToolBufferGetPointer (Buffer, SegmentHeadersOffset); + + SegmentAddress = 0; + SegmentOffset = SegmentsOffset; + for ( + Index = 0; + // LCOV_EXCL_START + Index < NumSegments; + // LCOV_EXCL_STOP + ++Index + ) { + // LCOV_EXCL_START + if (SegmentAddress > Address) { + break; + } + // LCOV_EXCL_STOP + + SegmentSize = UE_SEGMENT_SIZE (Segments[Index].ImageInfo); + OffsetInSegment = Address - SegmentAddress; + if (OffsetInSegment < SegmentSize) { + assert (OffsetInSegment < Segments[Index].FileSize); + *Size = Segments[Index].FileSize - OffsetInSegment; + return SegmentOffset + OffsetInSegment; + } + + SegmentAddress += SegmentSize; + SegmentOffset += Segments[Index].FileSize; + } + + // LCOV_EXCL_START + assert (false); + return MAX_UINT32; + // LCOV_EXCL_STOP +} + +static +bool +ToolImageEmitUeRelocTable ( + image_tool_dynamic_buffer *Buffer, + uint32_t LoadTableOffset, + uint32_t SegmentHeadersOffset, + uint32_t SegmentsOffset, + const image_tool_image_info_t *Image, + bool Chaining + ) +{ + uint32_t RelocTableOffset; + uint32_t RelocTableSize; + + UE_FIXUP_ROOT RelocRoot; + + uint32_t EntryFileOffset; + uint32_t PrevEntryFileOffset; + + uint8_t RelocType; + uint32_t RelocTarget; + uint32_t RelocFileOffset; + uint64_t RelocValue; + uint8_t RelocSize; + + uint32_t RelocOffset; + + uint64_t ChainRelocInfo; + uint32_t ChainRelocInfo32; + + uint8_t PrevRelocType; + uint32_t PrevRelocTarget; + uint32_t PrevRelocFileOffset; + uint64_t PrevRelocValue; + uint8_t PrevRelocSize; + + uint64_t PrevChainRelocInfo; + uint32_t PrevChainRelocInfo32; + + bool ChainInProgress; + bool ChainSupported; + + uint16_t Fixup; + + UE_LOAD_TABLE LoadTable; + + uint32_t Index; + uint32_t RemainingSize; + uint32_t Offset; + + assert (Image->RelocInfo.NumRelocs > 0); + + ChainInProgress = false; + + RelocTableOffset = ImageToolBufferGetSize (Buffer); + assert (IS_ALIGNED (RelocTableOffset, UE_LOAD_TABLE_ALIGNMENT)); + + PrevRelocType = 0; + PrevRelocTarget = 0; + PrevRelocFileOffset = 0; + PrevRelocValue = 0; + PrevRelocSize = 0; + + EntryFileOffset = 0; + PrevEntryFileOffset = 0; + + for ( + Index = 0; + Index < Image->RelocInfo.NumRelocs; + ++Index, + PrevRelocType = RelocType, + PrevRelocTarget = RelocTarget, + PrevRelocFileOffset = RelocFileOffset, + PrevRelocValue = RelocValue, + PrevRelocSize = RelocSize, + PrevEntryFileOffset = EntryFileOffset + ) { + // + // Get current UE relocation fixup info. + // + + RelocTarget = Image->RelocInfo.Relocs[Index].Target; + + RelocFileOffset = ToolImageEmitUeGetFileOffset ( + Buffer, + SegmentHeadersOffset, + SegmentsOffset, + Image->SegmentInfo.NumSegments, + RelocTarget, + &RemainingSize + ); + assert (RelocFileOffset != MAX_UINT32); + + // LCOV_EXCL_START + switch (Image->RelocInfo.Relocs[Index].Type) { + // LCOV_EXCL_STOP + case EFI_IMAGE_REL_BASED_HIGHLOW: + { + RelocSize = sizeof (UINT32); + RelocType = UeReloc32; + ChainSupported = Chaining; + break; + } + + case EFI_IMAGE_REL_BASED_DIR64: + { + RelocSize = sizeof (UINT64); + RelocType = UeReloc64; + ChainSupported = Chaining; + break; + } + + // LCOV_EXCL_START + default: + { + assert (false); + return false; + } + // LCOV_EXCL_STOP + } + + // LCOV_EXCL_START + if (RemainingSize < RelocSize) { + assert (false); + return false; + } + // LCOV_EXCL_STOP + + assert (RelocSize <= sizeof (RelocValue)); + + RelocValue = 0; + ImageToolBufferRead (&RelocValue, RelocSize, Buffer, RelocFileOffset); + + assert (RelocTarget >= (PrevRelocTarget + PrevRelocSize)); + RelocOffset = RelocTarget - (PrevRelocTarget + PrevRelocSize); + + // + // Handle UE relocation fixup chaining. + // + + if (ChainInProgress) { + ChainInProgress = ChainSupported && (RelocOffset <= UE_CHAINED_RELOC_FIXUP_MAX_OFFSET) && (PrevRelocType == RelocType); + + if (ChainInProgress && (RelocType == UeReloc32)) { + ChainRelocInfo32 = UE_CHAINED_RELOC_FIXUP_OFFSET_END; + ChainRelocInfo32 |= RelocValue << UE_CHAINED_RELOC_FIXUP_VALUE_32_SHIFT; + if ((ChainRelocInfo32 >> UE_CHAINED_RELOC_FIXUP_VALUE_32_SHIFT) != RelocValue) { + ChainInProgress = false; + ChainSupported = false; + RelocType = UeReloc32NoMeta; + } + } + + if (ChainInProgress && (RelocType == UeReloc64)) { + PrevChainRelocInfo = RelocType; + PrevChainRelocInfo |= RelocOffset << 4U; + PrevChainRelocInfo |= PrevRelocValue << 16U; + assert (UE_CHAINED_RELOC_FIXUP_NEXT_OFFSET (PrevChainRelocInfo) == RelocOffset); + assert (UE_CHAINED_RELOC_FIXUP_NEXT_TYPE (PrevChainRelocInfo) == RelocType); + assert (UE_CHAINED_RELOC_FIXUP_VALUE (PrevChainRelocInfo) == PrevRelocValue); + + assert (PrevRelocSize <= sizeof (PrevChainRelocInfo)); + + ImageToolBufferWrite ( + Buffer, + PrevRelocFileOffset, + &PrevChainRelocInfo, + PrevRelocSize + ); + } else if (ChainInProgress && (RelocType == UeReloc32)) { + PrevChainRelocInfo32 = RelocOffset; + PrevChainRelocInfo32 |= PrevRelocValue << UE_CHAINED_RELOC_FIXUP_VALUE_32_SHIFT; + + assert (PrevRelocSize <= sizeof (PrevChainRelocInfo32)); + + ImageToolBufferWrite ( + Buffer, + PrevRelocFileOffset, + &PrevChainRelocInfo32, + PrevRelocSize + ); + } + } + + if (ChainSupported && (RelocType == UeReloc64)) { + ChainRelocInfo = UE_CHAINED_RELOC_FIXUP_OFFSET_END << 4U; + ChainRelocInfo |= RelocValue << 16U; + if ((ChainRelocInfo >> 16U) != RelocValue) { + DEBUG_RAISE (); + return false; + } + assert (UE_CHAINED_RELOC_FIXUP_NEXT_OFFSET (ChainRelocInfo) == UE_CHAINED_RELOC_FIXUP_OFFSET_END); + assert (UE_CHAINED_RELOC_FIXUP_NEXT_TYPE (ChainRelocInfo) == 0); + assert (UE_CHAINED_RELOC_FIXUP_VALUE (ChainRelocInfo) == RelocValue); + + assert (RelocSize <= sizeof (ChainRelocInfo)); + + ImageToolBufferWrite ( + Buffer, + RelocFileOffset, + &ChainRelocInfo, + RelocSize + ); + + if (ChainInProgress) { + continue; + } + + ChainInProgress = true; + } else if (ChainSupported && (RelocType == UeReloc32)) { + ChainRelocInfo32 = UE_CHAINED_RELOC_FIXUP_OFFSET_END; + ChainRelocInfo32 |= RelocValue << UE_CHAINED_RELOC_FIXUP_VALUE_32_SHIFT; + if ((ChainRelocInfo32 >> UE_CHAINED_RELOC_FIXUP_VALUE_32_SHIFT) != RelocValue) { + ChainInProgress = false; + ChainSupported = false; + RelocType = UeReloc32NoMeta; + } else { + assert (RelocSize <= sizeof (ChainRelocInfo32)); + + ImageToolBufferWrite ( + Buffer, + RelocFileOffset, + &ChainRelocInfo32, + RelocSize + ); + + if (ChainInProgress) { + continue; + } + + ChainInProgress = true; + } + } + + if (Index > 0 && RelocOffset <= UE_HEAD_FIXUP_MAX_OFFSET) { + Fixup = PrevRelocType; + Fixup |= RelocOffset << 4U; + assert (UE_RELOC_FIXUP_TYPE (Fixup) == PrevRelocType); + assert (UE_RELOC_FIXUP_OFFSET (Fixup) == RelocOffset); + + ImageToolBufferWrite ( + Buffer, + PrevEntryFileOffset, + &Fixup, + sizeof (Fixup) + ); + } else { + Offset = ImageToolBufferAppendReserveAlign ( + Buffer, + UE_FIXUP_ROOT_ALIGNMENT + ); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + + RelocRoot.FirstOffset = RelocOffset; + + Offset = ImageToolBufferAppend (Buffer, &RelocRoot, sizeof (RelocRoot)); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + } + + Fixup = RelocType; + Fixup |= UE_HEAD_FIXUP_OFFSET_END << 4U; + assert (UE_RELOC_FIXUP_TYPE (Fixup) == RelocType); + assert (UE_RELOC_FIXUP_OFFSET (Fixup) == UE_HEAD_FIXUP_OFFSET_END); + + EntryFileOffset = ImageToolBufferAppend (Buffer, &Fixup, sizeof (Fixup)); + if (EntryFileOffset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + } + + Offset = ImageToolBufferAppendReserveAlign (Buffer, UE_LOAD_TABLE_ALIGNMENT); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + + RelocTableSize = ImageToolBufferGetSize (Buffer) - RelocTableOffset; + + LoadTable.FileInfo = RelocTableSize >> 3U; + LoadTable.FileInfo |= UeLoadTableIdReloc << 29U; + assert (UE_LOAD_TABLE_ID (LoadTable.FileInfo) == UeLoadTableIdReloc); + assert (UE_LOAD_TABLE_SIZE (LoadTable.FileInfo) == RelocTableSize); + + ImageToolBufferWrite ( + Buffer, + LoadTableOffset, + &LoadTable, + sizeof (LoadTable) + ); + + return true; +} + +static +bool +ToolImageEmitUeDebugTable ( + image_tool_dynamic_buffer *Buffer, + uint32_t LoadTableOffset, + const image_tool_image_info_t *Image, + uint32_t BaseAddressSubtrahend + ) +{ + UE_DEBUG_TABLE DebugTable; + uint8_t SymSubtrahendFactor; + uint32_t DebugTableOffset; + uint32_t DebugTableSize; + uint16_t Index; + UE_SEGMENT_NAME SegmentName; + UE_LOAD_TABLE LoadTable; + uint32_t Offset; + + assert (Image->DebugInfo.SymbolsPathLen <= MAX_UINT8); + assert (IS_ALIGNED (BaseAddressSubtrahend, Image->SegmentInfo.SegmentAlignment)); + + SymSubtrahendFactor = (uint8_t)(BaseAddressSubtrahend / Image->SegmentInfo.SegmentAlignment); + if (SymSubtrahendFactor > 0x03) { + DEBUG_RAISE (); + return false; + } + + DebugTable.ImageInfo = SymSubtrahendFactor; + assert (UE_DEBUG_TABLE_IMAGE_INFO_SYM_SUBTRAHEND_FACTOR (DebugTable.ImageInfo) == SymSubtrahendFactor); + assert ((DebugTable.ImageInfo & 0xFCU) == 0); + + DebugTable.SymbolsPathLength = (uint8_t)Image->DebugInfo.SymbolsPathLen; + + DebugTableOffset = ImageToolBufferAppend ( + Buffer, + &DebugTable, + sizeof (DebugTable) + ); + if (DebugTableOffset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + + assert (IS_ALIGNED (DebugTableOffset, UE_LOAD_TABLE_ALIGNMENT)); + + // + // Currently, this condition is always TRUE. However, it is not clear whether + // a debug table cannot make sense when debug symbols are stripped. + // + assert (Image->DebugInfo.SymbolsPath != NULL); + + Offset = ImageToolBufferAppend ( + Buffer, + Image->DebugInfo.SymbolsPath, + Image->DebugInfo.SymbolsPathLen + 1 + ); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + + for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { + memset (&SegmentName, 0, sizeof (SegmentName)); + strncpy ( + (char *)SegmentName, + Image->SegmentInfo.Segments[Index].Name, + sizeof (SegmentName) + ); + SegmentName[ARRAY_SIZE (SegmentName) - 1] = 0; + + Offset = ImageToolBufferAppend (Buffer, SegmentName, sizeof (SegmentName)); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + } + + Offset = ImageToolBufferAppendReserveAlign (Buffer, UE_LOAD_TABLE_ALIGNMENT); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + + DebugTableSize = ImageToolBufferGetSize (Buffer) - DebugTableOffset; + + LoadTable.FileInfo = DebugTableSize >> 3U; + LoadTable.FileInfo |= UeLoadTableIdDebug << 29U; + assert (UE_LOAD_TABLE_ID (LoadTable.FileInfo) == UeLoadTableIdDebug); + assert (UE_LOAD_TABLE_SIZE (LoadTable.FileInfo) == DebugTableSize); + + ImageToolBufferWrite ( + Buffer, + LoadTableOffset, + &LoadTable, + sizeof (LoadTable) + ); + + return true; +} + +static +bool +ToolImageEmitUeLoadTables ( + image_tool_dynamic_buffer *Buffer, + uint32_t LoadTablesOffset, + uint32_t SegmentHeadersOffset, + uint32_t SegmentsOffset, + const image_tool_image_info_t *Image, + uint32_t BaseAddressSubtrahend, + bool Chaining + ) +{ + bool Success; + + if (ToolImageUeRelocTableRequired (Image)) { + Success = ToolImageEmitUeRelocTable ( + Buffer, + LoadTablesOffset, + SegmentHeadersOffset, + SegmentsOffset, + Image, + Chaining + ); + if (!Success) { + DEBUG_RAISE (); + return false; + } + + LoadTablesOffset += sizeof (UE_LOAD_TABLE); + } + + if (ToolImageUeDebugTableRequired (Image)) { + Success = ToolImageEmitUeDebugTable ( + Buffer, + LoadTablesOffset, + Image, + BaseAddressSubtrahend + ); + if (!Success) { + DEBUG_RAISE (); + return false; + } + } + + return true; +} + +static +bool +ToolImageStripEmptyPrefix ( + uint32_t *BaseAddressSubtrahend, + image_tool_image_info_t *Image + ) +{ + bool Success; + uint32_t Subtrahend; + uint32_t Index; + + if (Image->RelocInfo.RelocsStripped) { + DEBUG_RAISE (); + return false; + } + + Subtrahend = Image->SegmentInfo.Segments[0].ImageAddress; + + Success = ToolImageRelocate ( + Image, + Image->HeaderInfo.BaseAddress - Subtrahend, + Subtrahend + ); + // LCOV_EXCL_START + if (!Success) { + DEBUG_RAISE (); + return false; + } + // LCOV_EXCL_STOP + + Image->HeaderInfo.BaseAddress += Subtrahend; + + Image->HeaderInfo.EntryPointAddress -= Subtrahend; + + for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { + Image->SegmentInfo.Segments[Index].ImageAddress -= Subtrahend; + } + + for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) { + Image->RelocInfo.Relocs[Index].Target -= Subtrahend; + } + + *BaseAddressSubtrahend = Subtrahend; + + return true; +} + +static +bool +ToolImageEmitUeFile ( + image_tool_dynamic_buffer *Buffer, + const image_tool_image_info_t *Image, + uint32_t BaseAddressSubtrahend + ) +{ + bool Success; + UE_HEADER UeHdr; + uint8_t AlignmentExponent; + int8_t Machine; + uint8_t Subsystem; + uint8_t LastSegmentIndex; + uint8_t NumLoadTables; + uint32_t Offset; + bool Chaining; + uint32_t SegmentHeadersOffset; + uint32_t LoadTablesOffset; + uint32_t SegmentsOffset; + + assert (Image->SegmentInfo.NumSegments > 0); + + if (Image->SegmentInfo.NumSegments > UE_HEADER_NUM_SEGMENTS_MAX) { + DEBUG_RAISE (); + return false; + } + + if (Image->HiiInfo.DataSize > 0) { + DEBUG_RAISE (); + return false; + } + + AlignmentExponent = AlignmentToExponent (Image->SegmentInfo.SegmentAlignment); + if (12 > AlignmentExponent || AlignmentExponent > 27) { + DEBUG_RAISE (); + return false; + } + + Machine = InternalGetUeMachine (Image->HeaderInfo.Machine); + if (Machine < 0) { + DEBUG_RAISE (); + return false; + } + + NumLoadTables = ToolImageUeRelocTableRequired (Image) ? 1U : 0U; + NumLoadTables += ToolImageUeDebugTableRequired (Image) ? 1U : 0U; + + Subsystem = (uint8_t)(Image->HeaderInfo.Subsystem - 10U); + LastSegmentIndex = (uint8_t)(Image->SegmentInfo.NumSegments - 1U); + + Chaining = Image->HeaderInfo.BaseAddress == 0 && + !Image->HeaderInfo.FixedAddress; + + UeHdr.Magic = UE_HEADER_MAGIC; + + UeHdr.Type = (Machine << 3U) | Subsystem; + assert (UE_HEADER_SUBSYSTEM (UeHdr.Type) == Subsystem); + assert (UE_HEADER_ARCH (UeHdr.Type) == Machine); + + UeHdr.TableCounts = NumLoadTables; + UeHdr.TableCounts |= LastSegmentIndex << 3U; + assert (UE_HEADER_LAST_SEGMENT_INDEX (UeHdr.TableCounts) == LastSegmentIndex); + assert (UE_HEADER_NUM_LOAD_TABLES (UeHdr.TableCounts) == NumLoadTables); + + UeHdr.EntryPointAddress = Image->HeaderInfo.EntryPointAddress; + + UeHdr.ImageInfo = Image->HeaderInfo.BaseAddress >> 12ULL; + UeHdr.ImageInfo |= (uint64_t)Image->HeaderInfo.FixedAddress << 57ULL; + UeHdr.ImageInfo |= (uint64_t)Image->RelocInfo.RelocsStripped << 58ULL; + UeHdr.ImageInfo |= (uint64_t)Chaining << 59ULL; + UeHdr.ImageInfo |= (uint64_t)(AlignmentExponent - 12U) << 60ULL; + assert (UE_HEADER_BASE_ADDRESS (UeHdr.ImageInfo) == Image->HeaderInfo.BaseAddress); + assert ((UeHdr.ImageInfo & (0x1FULL << 52ULL)) == 0); + assert (((UeHdr.ImageInfo & UE_HEADER_IMAGE_INFO_FIXED_ADDRESS) != 0) == Image->HeaderInfo.FixedAddress); + assert (((UeHdr.ImageInfo & UE_HEADER_IMAGE_INFO_RELOCATION_FIXUPS_STRIPPED) != 0) == Image->RelocInfo.RelocsStripped); + assert (((UeHdr.ImageInfo & UE_HEADER_IMAGE_INFO_CHAINED_FIXUPS) != 0) == Chaining); + assert (UE_HEADER_SEGMENT_ALIGNMENT (UeHdr.ImageInfo) == Image->SegmentInfo.SegmentAlignment); + + Offset = ImageToolBufferAppend (Buffer, &UeHdr, sizeof (UeHdr)); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + + SegmentHeadersOffset = ImageToolBufferGetSize (Buffer); + + Success = ToolImageEmitUeSegmentHeaders (Buffer, Image, false); + if (!Success) { + DEBUG_RAISE (); + return false; + } + + LoadTablesOffset = ImageToolBufferAppendReserve ( + Buffer, + NumLoadTables * sizeof (UE_LOAD_TABLE) + ); + if (LoadTablesOffset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + + SegmentsOffset = ImageToolBufferGetSize (Buffer); + + Success = ToolImageEmitUeSegments (Buffer, Image); + if (!Success) { + DEBUG_RAISE (); + return false; + } + + Success = ToolImageEmitUeLoadTables ( + Buffer, + LoadTablesOffset, + SegmentHeadersOffset, + SegmentsOffset, + Image, + BaseAddressSubtrahend, + Chaining + ); + if (!Success) { + DEBUG_RAISE (); + return false; + } + + return true; +} + +// FIXME: Find a better solution. Separate metadata storage? +static +bool +ToolImageEmitUeXipFile ( + image_tool_dynamic_buffer *Buffer, + image_tool_image_info_t *Image, + bool Strip + ) +{ + bool Success; + UE_HEADER UeHdr; + uint8_t AlignmentExponent; + int8_t Machine; + uint8_t Subsystem; + uint8_t LastSegmentIndex; + uint8_t NumLoadTables; + uint32_t Offset; + uint16_t Index; + uint32_t SegmentHeadersOffset; + uint32_t LoadTablesOffset; + uint32_t SegmentsOffset; + + assert (Image->SegmentInfo.NumSegments > 0); + + if (Image->SegmentInfo.NumSegments > UE_HEADER_NUM_SEGMENTS_MAX) { + DEBUG_RAISE (); + return false; + } + + if (Image->HiiInfo.DataSize > 0) { + DEBUG_RAISE (); + return false; + } + + AlignmentExponent = AlignmentToExponent (Image->SegmentInfo.SegmentAlignment); + if (12 > AlignmentExponent || AlignmentExponent > 27) { + DEBUG_RAISE (); + return false; + } + + Machine = InternalGetUeMachine (Image->HeaderInfo.Machine); + if (Machine < 0) { + DEBUG_RAISE (); + return false; + } + + NumLoadTables = (!Strip && ToolImageUeRelocTableRequired (Image)) ? 1U : 0U; + Subsystem = (uint8_t)(Image->HeaderInfo.Subsystem - 10U); + LastSegmentIndex = (uint8_t)(Image->SegmentInfo.NumSegments - 1U); + + UeHdr.Magic = UE_HEADER_MAGIC; + + UeHdr.Type = (Machine << 3U) | Subsystem; + assert (UE_HEADER_SUBSYSTEM (UeHdr.Type) == Subsystem); + assert (UE_HEADER_ARCH (UeHdr.Type) == Machine); + + UeHdr.TableCounts = NumLoadTables; + UeHdr.TableCounts |= LastSegmentIndex << 3U; + assert (UE_HEADER_LAST_SEGMENT_INDEX (UeHdr.TableCounts) == LastSegmentIndex); + assert (UE_HEADER_NUM_LOAD_TABLES (UeHdr.TableCounts) == NumLoadTables); + + UeHdr.ImageInfo = Image->HeaderInfo.BaseAddress >> 12ULL; + UeHdr.ImageInfo |= UE_HEADER_IMAGE_INFO_XIP; + UeHdr.ImageInfo |= (uint64_t)Image->HeaderInfo.FixedAddress << 57ULL; + UeHdr.ImageInfo |= (uint64_t)Strip << 58ULL; + UeHdr.ImageInfo |= (uint64_t)(AlignmentExponent - 12U) << 60ULL; + assert (UE_HEADER_BASE_ADDRESS (UeHdr.ImageInfo) == Image->HeaderInfo.BaseAddress); + assert ((UeHdr.ImageInfo & (0xFULL << 52ULL)) == 0); + assert (((UeHdr.ImageInfo & UE_HEADER_IMAGE_INFO_FIXED_ADDRESS) != 0) == Image->HeaderInfo.FixedAddress); + assert (((UeHdr.ImageInfo & UE_HEADER_IMAGE_INFO_RELOCATION_FIXUPS_STRIPPED) != 0) == Strip); + assert (((UeHdr.ImageInfo & UE_HEADER_IMAGE_INFO_CHAINED_FIXUPS) != 0) == FALSE); + assert (((UeHdr.ImageInfo & UE_HEADER_IMAGE_INFO_XIP) != 0) == TRUE); + assert (UE_HEADER_SEGMENT_ALIGNMENT (UeHdr.ImageInfo) == Image->SegmentInfo.SegmentAlignment); + + Offset = ImageToolBufferAppendReserve (Buffer, sizeof (UeHdr)); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + + SegmentHeadersOffset = ImageToolBufferGetSize (Buffer); + + Success = ToolImageEmitUeSegmentHeaders (Buffer, Image, true); + if (!Success) { + DEBUG_RAISE (); + return false; + } + + LoadTablesOffset = ImageToolBufferAppendReserve ( + Buffer, + NumLoadTables * sizeof (UE_LOAD_TABLE) + ); + if (LoadTablesOffset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + + Offset = ImageToolBufferAppendReserveAlign ( + Buffer, + Image->SegmentInfo.SegmentAlignment + ); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + + SegmentsOffset = ImageToolBufferGetSize (Buffer); + + UeHdr.EntryPointAddress = Image->HeaderInfo.EntryPointAddress + SegmentsOffset; + ImageToolBufferWrite (Buffer, 0, &UeHdr, sizeof (UeHdr)); + + Success = ToolImageRelocate (Image, Image->HeaderInfo.BaseAddress + SegmentsOffset, 0); + if (!Success) { + DEBUG_RAISE (); + return false; + } + + for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) { + Offset = ImageToolBufferAppend ( + Buffer, + Image->SegmentInfo.Segments[Index].Data, + Image->SegmentInfo.Segments[Index].UnpaddedSize + ); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + + Offset = ImageToolBufferAppendReserve ( + Buffer, + Image->SegmentInfo.Segments[Index].ImageSize - Image->SegmentInfo.Segments[Index].UnpaddedSize + ); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return false; + } + } + + if (!Strip && ToolImageUeRelocTableRequired (Image)) { + Success = ToolImageEmitUeRelocTable ( + Buffer, + LoadTablesOffset, + SegmentHeadersOffset, + SegmentsOffset, + Image, + false + ); + if (!Success) { + DEBUG_RAISE (); + return false; + } + } + + return true; +} + +void * +ToolImageEmitUe ( + image_tool_image_info_t *Image, + uint32_t *FileSize, + bool Xip, + bool Strip + ) +{ + bool Success; + image_tool_dynamic_buffer Buffer; + uint32_t BaseAddressSubtrahend; + void *FileBuffer; + + ImageToolBufferInit (&Buffer); + + ImageInitUnpaddedSize (Image); + ToolImageEmitUePadChainedRelocs (Image); + + if (Xip) { + Success = ToolImageEmitUeXipFile (&Buffer, Image, Strip); + } else { + Success = ToolImageStripEmptyPrefix (&BaseAddressSubtrahend, Image); + if (!Success) { + DEBUG_RAISE (); + return NULL; + } + + if (Strip) { + ToolImageStripRelocs (Image); + } + + Success = ToolImageEmitUeFile (&Buffer, Image, BaseAddressSubtrahend); + } + + if (!Success) { + DEBUG_RAISE (); + ImageToolBufferFree (&Buffer); + return NULL; + } + + FileBuffer = ImageToolBufferDump (FileSize, &Buffer); + + ImageToolBufferFree (&Buffer); + + if (FileBuffer == NULL) { + DEBUG_RAISE (); + return NULL; + } + + return FileBuffer; +} diff --git a/BaseTools/ImageTool/UeEmit.h b/BaseTools/ImageTool/UeEmit.h new file mode 100644 index 0000000000..8133d36b11 --- /dev/null +++ b/BaseTools/ImageTool/UeEmit.h @@ -0,0 +1,10 @@ +#ifndef UE_EMIT_H +#define UE_EMIT_H + +#include + +#include "ImageTool.h" + +void *ToolImageEmitUe(image_tool_image_info_t *Image, uint32_t *FileSize); + +#endif // UE_EMIT_H diff --git a/BaseTools/ImageTool/UeScan.c b/BaseTools/ImageTool/UeScan.c new file mode 100644 index 0000000000..880d8bd02d --- /dev/null +++ b/BaseTools/ImageTool/UeScan.c @@ -0,0 +1,485 @@ +/** @file + Copyright (c) 2021 - 2023, Marvin Häuser. All rights reserved. + Copyright (c) 2022, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "ImageTool.h" +#include "UeScan.h" +#include "DynamicBuffer.h" + +typedef union { + UINT32 Value32; + UINT64 Value64; +} UE_RELOC_FIXUP_VALUE; + +static +RETURN_STATUS +InternalProcessRelocChain ( + image_tool_dynamic_buffer *Buffer, + const image_tool_segment_info_t *SegmentInfo, + UINT16 FirstRelocType, + UINT32 *ChainStart + ) +{ + uint32_t OffsetInSegment; + const image_tool_segment_t *Segment; + image_tool_reloc_t Reloc; + uint32_t Offset; + + UINT16 RelocType; + UINT16 RelocOffset; + UINT32 RelocTarget; + + UINT32 RemRelocTargetSize; + + VOID *Fixup; + UE_RELOC_FIXUP_VALUE FixupInfo; + UINT8 FixupSize; + UE_RELOC_FIXUP_VALUE FixupValue; + + memset (&Reloc, 0, sizeof (Reloc)); + + RelocType = FirstRelocType; + RelocTarget = *ChainStart; + + while (TRUE) { + OffsetInSegment = RelocTarget; + Segment = ImageGetSegmentByAddress ( + &OffsetInSegment, + &RemRelocTargetSize, + SegmentInfo + ); + if (Segment == NULL) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + Fixup = &Segment->Data[OffsetInSegment]; + + Reloc.Target = RelocTarget; + + if (RelocType < UeRelocGenericMax) { + if (RelocType == UeReloc64) { + FixupSize = sizeof (UINT64); + // + // Verify the relocation fixup target is in bounds of the Image buffer. + // + if (FixupSize > RemRelocTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Relocate the target instruction. + // + FixupInfo.Value64 = ReadUnaligned64 (Fixup); + FixupValue.Value64 = UE_CHAINED_RELOC_FIXUP_VALUE (FixupInfo.Value64); + WriteUnaligned64 (Fixup, FixupValue.Value64); + + Reloc.Type = EFI_IMAGE_REL_BASED_DIR64; + } else if (RelocType == UeReloc32) { + FixupSize = sizeof (UINT32); + // + // Verify the image relocation fixup target is in bounds of the image + // buffer. + // + if (FixupSize > RemRelocTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Relocate the target instruction. + // + FixupInfo.Value32 = ReadUnaligned32 (Fixup); + FixupValue.Value32 = UE_CHAINED_RELOC_FIXUP_VALUE_32 (FixupInfo.Value32); + WriteUnaligned32 (Fixup, FixupValue.Value32); + + Reloc.Type = EFI_IMAGE_REL_BASED_HIGHLOW; + // + // Imitate the common header of UE chained relocation fixups, + // as for 32-bit files all relocs have the same type. + // + FixupInfo.Value32 = FixupInfo.Value32 << 4; + FixupInfo.Value32 |= UeReloc32; + } else { + // + // The Image relocation fixup type is unknown, disallow the Image. + // + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + } else { + // + // The Image relocation fixup type is unknown, disallow the Image. + // + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + + RelocTarget += FixupSize; + + Offset = ImageToolBufferAppend (Buffer, &Reloc, sizeof (Reloc)); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + return RETURN_OUT_OF_RESOURCES; + } + + RelocOffset = UE_CHAINED_RELOC_FIXUP_NEXT_OFFSET (FixupInfo.Value32); + if (RelocOffset == UE_CHAINED_RELOC_FIXUP_OFFSET_END) { + *ChainStart = RelocTarget; + return RETURN_SUCCESS; + } + // + // It holds that ImageSize mod 4 KiB = 0, thus ImageSize <= 0xFFFFF000. + // Furthermore, it holds that RelocTarget <= ImageSize. + // Finally, it holds that RelocOffset <= 0xFFE. + // It follows that this cannot overflow. + // + RelocTarget += RelocOffset; + assert (RelocOffset <= RelocTarget); + + RelocType = UE_CHAINED_RELOC_FIXUP_NEXT_TYPE (FixupInfo.Value32); + } +} + +STATIC +RETURN_STATUS +InternalApplyRelocation ( + image_tool_dynamic_buffer *Buffer, + const image_tool_segment_info_t *SegmentInfo, + UINT16 RelocType, + UINT32 *RelocTarget + ) +{ + BOOLEAN Overflow; + + const image_tool_segment_t *LastSegment; + uint32_t ImageSize; + UINT32 RemRelocTargetSize; + + UINT32 FixupTarget; + UINT8 FixupSize; + + image_tool_reloc_t Reloc; + uint32_t Offset; + + FixupTarget = *RelocTarget; + + LastSegment = &SegmentInfo->Segments[SegmentInfo->NumSegments - 1]; + ImageSize = LastSegment->ImageAddress + LastSegment->ImageSize; + // + // Verify the relocation fixup target address is in bounds of the image buffer. + // + Overflow = BaseOverflowSubU32 (ImageSize, FixupTarget, &RemRelocTargetSize); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + memset (&Reloc, 0, sizeof (Reloc)); + Reloc.Target = FixupTarget; + // + // Apply the relocation fixup per type. + // + if (RelocType < UeRelocGenericMax) { + if ((RelocType == UeReloc32) || (RelocType == UeReloc32NoMeta)) { + FixupSize = sizeof (UINT32); + Reloc.Type = EFI_IMAGE_REL_BASED_HIGHLOW; + } else { + assert (RelocType == UeReloc64); + + FixupSize = sizeof (UINT64); + Reloc.Type = EFI_IMAGE_REL_BASED_DIR64; + } + } else { + // + // The image relocation fixup type is unknown, disallow the image. + // + fprintf (stderr, "ImageTool: Unknown RelocType = 0x%x\n", RelocType); + ImageToolBufferFree (Buffer); + return RETURN_UNSUPPORTED; + } + // + // Verify the relocation fixup target is in bounds of the image buffer. + // + if (FixupSize > RemRelocTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + Offset = ImageToolBufferAppend (Buffer, &Reloc, sizeof (Reloc)); + if (Offset == MAX_UINT32) { + DEBUG_RAISE (); + ImageToolBufferFree (Buffer); + return RETURN_OUT_OF_RESOURCES; + } + + *RelocTarget = FixupTarget + FixupSize; + + return RETURN_SUCCESS; +} + +RETURN_STATUS +ScanUeGetRelocInfo ( + OUT image_tool_reloc_info_t *RelocInfo, + IN const image_tool_segment_info_t *SegmentInfo, + IN UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + RETURN_STATUS Status; + BOOLEAN Overflow; + CONST UE_HEADER *UeHdr; + BOOLEAN Chaining; + UINT32 RootOffsetMax; + UINT32 EntryOffsetMax; + UINT32 EndOfRelocTable; + UINT32 TableOffset; + const UE_FIXUP_ROOT *RelocRoot; + UINT16 FixupInfo; + UINT16 RelocType; + UINT16 RelocOffset; + UINT32 RelocTarget; + image_tool_dynamic_buffer Buffer; + uint32_t RelocBufferSize; + UINT32 OldTableOffset; + // + // Verify the Relocation Directory is not empty. + // + if (Context->RelocTableSize == 0) { + return RETURN_SUCCESS; + } + + ImageToolBufferInit (&Buffer); + + UeHdr = (CONST UE_HEADER *)Context->FileBuffer; + Chaining = (UeHdr->ImageInfo & UE_HEADER_IMAGE_INFO_CHAINED_FIXUPS) != 0; + + EndOfRelocTable = Context->LoadTablesFileOffset + Context->RelocTableSize; + + RelocTarget = 0; + + RootOffsetMax = EndOfRelocTable - MIN_SIZE_OF_UE_FIXUP_ROOT; + EntryOffsetMax = EndOfRelocTable - sizeof (*RelocRoot->Heads); + // + // Apply all Base Relocations of the Image. + // + for (TableOffset = Context->LoadTablesFileOffset; TableOffset <= RootOffsetMax;) { + RelocRoot = (CONST UE_FIXUP_ROOT *)( + (CONST UINT8 *)Context->FileBuffer + TableOffset + ); + // + // This cannot overflow due to the TableOffset upper bound. + // + TableOffset += sizeof (*RelocRoot); + + Overflow = BaseOverflowAddU32 ( + RelocTarget, + RelocRoot->FirstOffset, + &RelocTarget + ); + if (Overflow) { + DEBUG_RAISE (); + ImageToolBufferFree (&Buffer); + return RETURN_VOLUME_CORRUPTED; + } + // + // Process all relocation fixups of the current root. + // + while (TRUE) { + FixupInfo = *(CONST UINT16 *)((CONST UINT8 *)Context->FileBuffer + TableOffset); + // + // This cannot overflow due to the upper bound of TableOffset. + // + TableOffset += sizeof (*RelocRoot->Heads); + // + // Apply the image relocation fixup. + // + RelocType = UE_RELOC_FIXUP_TYPE (FixupInfo); + + if (Chaining && (RelocType != UeReloc32NoMeta)) { + Status = InternalProcessRelocChain ( + &Buffer, + SegmentInfo, + RelocType, + &RelocTarget + ); + } else { + Status = InternalApplyRelocation ( + &Buffer, + SegmentInfo, + RelocType, + &RelocTarget + ); + } + + if (RETURN_ERROR (Status)) { + DEBUG_RAISE (); + ImageToolBufferFree (&Buffer); + return Status; + } + + RelocOffset = UE_RELOC_FIXUP_OFFSET (FixupInfo); + if (RelocOffset == UE_HEAD_FIXUP_OFFSET_END) { + break; + } + // + // It holds that ImageSize mod 4 KiB = 0, thus ImageSize <= 0xFFFFF000. + // Furthermore, it holds that RelocTarget <= ImageSize. + // Finally, it holds that RelocOffset <= 0xFFE. + // It follows that this cannot overflow. + // + RelocTarget += RelocOffset; + assert (RelocOffset <= RelocTarget); + + if (TableOffset > EntryOffsetMax) { + DEBUG_RAISE (); + ImageToolBufferFree (&Buffer); + return RETURN_VOLUME_CORRUPTED; + } + } + // + // This cannot overflow due to the TableOffset upper bounds and the + // alignment guarantee of RelocTableSize. + // + OldTableOffset = TableOffset; + TableOffset = ALIGN_VALUE (TableOffset, ALIGNOF (UE_FIXUP_ROOT)); + assert (OldTableOffset <= TableOffset); + } + + RelocInfo->Relocs = ImageToolBufferDump (&RelocBufferSize, &Buffer); + + ImageToolBufferFree (&Buffer); + + if (RelocInfo->Relocs == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for Relocs[]\n"); + return RETURN_OUT_OF_RESOURCES; + } + + assert (IS_ALIGNED (RelocBufferSize, sizeof (*RelocInfo->Relocs))); + RelocInfo->NumRelocs = RelocBufferSize / sizeof (*RelocInfo->Relocs); + + return RETURN_SUCCESS; +} + +RETURN_STATUS +ScanUeGetSegmentInfo ( + OUT image_tool_segment_info_t *SegmentInfo, + IN UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + RETURN_STATUS Status; + const UE_SEGMENT *Segment; + uint16_t NumSegments; + image_tool_segment_t *ImageSegment; + const char *ImageBuffer; + uint16_t Index; + uint32_t SegmentAddress; + uint32_t SegmentSize; + uint8_t SegmentPermissions; + const UE_SEGMENT_NAME *SegmentNames; + + NumSegments = UeGetSegments (Context, &Segment); + + STATIC_ASSERT ( + sizeof (*SegmentInfo->Segments) <= MAX_UINT16 / UE_HEADER_NUM_SEGMENTS_MAX, + "The following arithmetics cannot overflow." + ); + + SegmentInfo->Segments = AllocateZeroPool ( + NumSegments * sizeof (*SegmentInfo->Segments) + ); + if (SegmentInfo->Segments == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for Segments[]\n"); + return RETURN_OUT_OF_RESOURCES; + } + + Status = UeGetSegmentNames (Context, &SegmentNames); + if (RETURN_ERROR (Status)) { + if (Status != RETURN_NOT_FOUND) { + DEBUG_RAISE (); + return Status; + } + + SegmentNames = NULL; + } + + ImageBuffer = (char *)UeLoaderGetImageAddress (Context); + + SegmentAddress = 0; + ImageSegment = SegmentInfo->Segments; + for (Index = 0; Index < NumSegments; ++Index, ++Segment) { + if (SegmentNames != NULL) { + ImageSegment->Name = AllocateCopyPool ( + sizeof (SegmentNames[Index]), + SegmentNames[Index] + ); + if (ImageSegment->Name == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for Segment Name\n"); + return RETURN_OUT_OF_RESOURCES; + } + } else { + assert (ImageSegment->Name == NULL); + } + + SegmentSize = UE_SEGMENT_SIZE (Segment->ImageInfo); + + ImageSegment->Data = AllocateCopyPool ( + SegmentSize, + ImageBuffer + SegmentAddress + ); + if (ImageSegment->Data == NULL) { + fprintf (stderr, "ImageTool: Could not allocate memory for Segment Data\n"); + if (ImageSegment->Name != NULL) { + FreePool (ImageSegment->Name); + } + return RETURN_OUT_OF_RESOURCES; + } + + ImageSegment->ImageAddress = SegmentAddress; + ImageSegment->ImageSize = SegmentSize; + + SegmentPermissions = UE_SEGMENT_PERMISSIONS (Segment->ImageInfo); + switch (SegmentPermissions) { + case UeSegmentPermX: + { + ImageSegment->Execute = true; + assert (!ImageSegment->Read); + assert (!ImageSegment->Write); + break; + } + + case UeSegmentPermRX: + { + ImageSegment->Read = true; + ImageSegment->Execute = true; + assert (!ImageSegment->Write); + break; + } + + case UeSegmentPermRW: + { + ImageSegment->Read = true; + ImageSegment->Write = true; + assert (!ImageSegment->Execute); + break; + } + + default: + case UeSegmentPermR: + { + assert (SegmentPermissions == UeSegmentPermR); + ImageSegment->Read = true; + assert (!ImageSegment->Write); + assert (!ImageSegment->Execute); + break; + } + } + + SegmentAddress += SegmentSize; + + ++SegmentInfo->NumSegments; + ++ImageSegment; + } + + return RETURN_SUCCESS; +} diff --git a/BaseTools/ImageTool/UeScan.h b/BaseTools/ImageTool/UeScan.h new file mode 100644 index 0000000000..aa38cf83bd --- /dev/null +++ b/BaseTools/ImageTool/UeScan.h @@ -0,0 +1,19 @@ +#ifndef UE_SCAN_H +#define UE_SCAN_H + +#include "ImageTool.h" + +RETURN_STATUS +ScanUeGetRelocInfo ( + OUT image_tool_reloc_info_t *RelocInfo, + IN const image_tool_segment_info_t *SegmentInfo, + IN UE_LOADER_IMAGE_CONTEXT *Context + ); + +RETURN_STATUS +ScanUeGetSegmentInfo ( + OUT image_tool_segment_info_t *SegmentInfo, + IN UE_LOADER_IMAGE_CONTEXT *Context + ); + +#endif // UE_SCAN_H diff --git a/BaseTools/ImageTool/UefiImageScan.c b/BaseTools/ImageTool/UefiImageScan.c index 65b7903bff..bbf791f703 100644 --- a/BaseTools/ImageTool/UefiImageScan.c +++ b/BaseTools/ImageTool/UefiImageScan.c @@ -10,6 +10,7 @@ #include #include "PeScan.h" +#include "UeScan.h" static bool @@ -24,7 +25,12 @@ ScanUefiImageGetHeaderInfo ( HeaderInfo->BaseAddress = UefiImageGetBaseAddress (Context); HeaderInfo->EntryPointAddress = UefiImageGetEntryPointAddress (Context); HeaderInfo->Machine = UefiImageGetMachine (Context); - HeaderInfo->Subsystem = UefiImageGetSubsystem (Context); + if (HeaderInfo->Machine == 0xFFFF) { + DEBUG_RAISE (); + return false; + } + + HeaderInfo->Subsystem = UefiImageGetSubsystem (Context); Status = UefiImageGetFixedAddress (Context, &Address); if (!RETURN_ERROR (Status)) { @@ -48,6 +54,7 @@ static RETURN_STATUS ScanUefiImageGetRelocInfo ( OUT image_tool_reloc_info_t *RelocInfo, + IN const image_tool_segment_info_t *SegmentInfo, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context ) { @@ -61,12 +68,21 @@ ScanUefiImageGetRelocInfo ( return ScanPeGetRelocInfo (RelocInfo, &Context->Ctx.Pe); } + // LCOV_EXCL_START + if (FormatIndex == UefiImageFormatUe) { + // LCOV_EXCL_STOP + return ScanUeGetRelocInfo (RelocInfo, SegmentInfo, &Context->Ctx.Ue); + } + + // LCOV_EXCL_START fprintf ( stderr, "ImageTool: Unsupported UefiImage format %u\n", FormatIndex ); + assert (false); return RETURN_UNSUPPORTED; + // LCOV_EXCL_STOP } static @@ -86,12 +102,21 @@ ScanUefiImageGetSegmentInfo ( return ScanPeGetSegmentInfo (SegmentInfo, &Context->Ctx.Pe); } + // LCOV_EXCL_START + if (FormatIndex == UefiImageFormatUe) { + // LCOV_EXCL_STOP + return ScanUeGetSegmentInfo (SegmentInfo, &Context->Ctx.Ue); + } + + // LCOV_EXCL_START fprintf ( stderr, "ImageTool: Unsupported UefiImage format %u\n", FormatIndex ); + assert (false); return RETURN_UNSUPPORTED; + // LCOV_EXCL_STOP } RETURN_STATUS @@ -166,7 +191,7 @@ ToolContextConstructUefiImage ( OUT image_tool_image_info_t *Image, OUT int8_t *Format, IN const void *File, - IN size_t FileSize + IN uint32_t FileSize ) { RETURN_STATUS Status; @@ -180,11 +205,6 @@ ToolContextConstructUefiImage ( assert (File != NULL || FileSize == 0); - if (FileSize > MAX_UINT32) { - fprintf (stderr, "ImageTool: FileSize is too huge\n"); - return RETURN_UNSUPPORTED; - } - Status = UefiImageInitializeContext ( &Context, File, @@ -209,11 +229,13 @@ ToolContextConstructUefiImage ( } Status = UefiImageLoadImage (&Context, Destination, DestinationSize); + // LCOV_EXCL_START if (RETURN_ERROR (Status)) { fprintf (stderr, "ImageTool: Could not Load Image\n"); FreeAlignedPages (Destination, DestinationPages); return Status; } + // LCOV_EXCL_STOP memset (Image, 0, sizeof (*Image)); @@ -233,7 +255,11 @@ ToolContextConstructUefiImage ( return Status; } - Status = ScanUefiImageGetRelocInfo (&Image->RelocInfo, &Context); + Status = ScanUefiImageGetRelocInfo ( + &Image->RelocInfo, + &Image->SegmentInfo, + &Context + ); if (RETURN_ERROR (Status)) { fprintf (stderr, "ImageTool: Could not retrieve reloc info\n"); ToolImageDestruct (Image); diff --git a/BaseTools/Source/C/Common/GNUmakefile b/BaseTools/Source/C/Common/GNUmakefile index 5ec953cda0..8c70b90f4e 100644 --- a/BaseTools/Source/C/Common/GNUmakefile +++ b/BaseTools/Source/C/Common/GNUmakefile @@ -37,6 +37,8 @@ OBJECTS += \ $(EDK2_OBJPATH)/BaseTools/ImageTool/ElfScan64.o \ $(EDK2_OBJPATH)/BaseTools/ImageTool/ElfScanCommon.o \ $(EDK2_OBJPATH)/BaseTools/ImageTool/UefiImageScan.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/UeScan.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/UeEmit.o \ $(EDK2_OBJPATH)/BaseTools/ImageTool/PeScan.o \ $(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit32.o \ $(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit64.o \ @@ -121,8 +123,12 @@ OBJECTS += \ $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.o \ $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffRelocate.o +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseUeImageLib/UeImageLib.o + OBJECTS += \ $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/CommonSupport.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/UeSupport.o \ $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/PeSupport.o \ $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/UefiImageLib.o diff --git a/BaseTools/Source/C/Common/Makefile b/BaseTools/Source/C/Common/Makefile index db0198c640..a6cd6f5e9c 100644 --- a/BaseTools/Source/C/Common/Makefile +++ b/BaseTools/Source/C/Common/Makefile @@ -37,6 +37,8 @@ OBJECTS = $(OBJECTS) \ $(EDK2_OBJPATH)\BaseTools\ImageTool\ElfScan64.obj \ $(EDK2_OBJPATH)\BaseTools\ImageTool\ElfScanCommon.obj \ $(EDK2_OBJPATH)\BaseTools\ImageTool\UefiImageScan.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\UeScan.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\UeEmit.obj \ $(EDK2_OBJPATH)\BaseTools\ImageTool\PeScan.obj \ $(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit32.obj \ $(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit64.obj \ @@ -120,8 +122,12 @@ OBJECTS = $(OBJECTS) \ $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffLoad.obj \ $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffRelocate.obj +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseUeImageLib\UeImageLib.obj + OBJECTS = $(OBJECTS) \ $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\CommonSupport.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\UeSupport.obj \ $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\PeSupport.obj \ $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\UefiImageLib.obj diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index ef986d09e1..fa31c1c808 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -855,6 +855,8 @@ Routine Description: fprintf (FvMapFile, "EntryPoint=0x%010llx, ", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint)); if (Format == UefiImageFormatPe) { fprintf (FvMapFile, "Type=PE"); + } else if (Format == UefiImageFormatUe) { + fprintf (FvMapFile, "Type=UE"); } else { assert (FALSE); fprintf (FvMapFile, "Type=Unknown"); @@ -3506,6 +3508,11 @@ Routine Description: UINT8 ImageFormat; UINT32 RebasedImageSize; VOID *RebasedImage; + UINT32 FfsFileLength; + UINTN FileOffset; + EFI_FFS_INTEGRITY_CHECK *IntegrityCheck; + UINT8 *AfterPePart; + UINT32 AfterPeSize; Index = 0; Cptr = NULL; @@ -3674,6 +3681,7 @@ Routine Description: UefiImageFileBuffer = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize); UefiImageFileSize = SectPeSize; + FileOffset = (UINTN)UefiImageFileBuffer - (UINTN)(*FfsFile); // // UefiImage has no reloc section. It will try to get reloc data from the original UEFI image. // @@ -3742,7 +3750,7 @@ Routine Description: NewBaseAddress, NULL, TRUE, - Strip, + ImageFormat == UefiImageFormatUe ? (*FfsFile)->Type == EFI_FV_FILETYPE_SECURITY_CORE : Strip, FALSE ); @@ -3755,37 +3763,112 @@ Routine Description: return EFI_UNSUPPORTED; } - UefiImageFileBuffer = NULL; - UefiImageFileSize = 0; + if (ImageFormat == UefiImageFormatUe) { + if ((RebasedImageSize + sizeof (EFI_COMMON_SECTION_HEADER)) >= 0x00FFFFFFU) { + Error (NULL, 0, 4001, "Invalid", "rebased file is too large (%s)", FileName); + return EFI_UNSUPPORTED; + } - if (RebasedImageSize > SectPeSize) { - Error (NULL, 0, 4001, "Invalid", "rebased file is too large (%s)", FileName); - return EFI_UNSUPPORTED; - } + AfterPeSize = GetFfsFileLength (*FfsFile) - (FileOffset + SectPeSize); + AfterPePart = calloc (1, AfterPeSize); + if (AfterPePart == NULL) { + fprintf (stderr, "GenFv: Could not allocate memory for AfterPePart\n"); + return EFI_OUT_OF_RESOURCES; + } + + memmove ( + AfterPePart, + (UINT8 *)((UINTN)(*FfsFile) + FileOffset + SectPeSize), + AfterPeSize + ); + + FfsFileLength = GetFfsFileLength (*FfsFile) - SectPeSize + RebasedImageSize; + *FfsFile = realloc (*FfsFile, FfsFileLength); + if (*FfsFile == NULL) { + fprintf (stderr, "GenFv: Could not reallocate memory for rebased FfsFile\n"); + return EFI_OUT_OF_RESOURCES; + } + *FileSize = FfsFileLength; + + CurrentPe32Section.CommonHeader = (EFI_COMMON_SECTION_HEADER *)((UINTN)(*FfsFile) + FileOffset - CurSecHdrSize); + CurrentPe32Section.CommonHeader->Size[0] = (UINT8)((RebasedImageSize + sizeof (EFI_COMMON_SECTION_HEADER)) & 0x000000FF); + CurrentPe32Section.CommonHeader->Size[1] = (UINT8)(((RebasedImageSize + sizeof (EFI_COMMON_SECTION_HEADER)) & 0x0000FF00) >> 8); + CurrentPe32Section.CommonHeader->Size[2] = (UINT8)(((RebasedImageSize + sizeof (EFI_COMMON_SECTION_HEADER)) & 0x00FF0000) >> 16); + + memmove ( + (UINT8 *)((UINTN)(*FfsFile) + FileOffset), + RebasedImage, + RebasedImageSize + ); + + memmove ( + (UINT8 *)((UINTN)(*FfsFile) + FileOffset + RebasedImageSize), + AfterPePart, + AfterPeSize + ); + + if (FfsHeaderSize > sizeof(EFI_FFS_FILE_HEADER)) { + ((EFI_FFS_FILE_HEADER2 *)(*FfsFile))->ExtendedSize = FfsFileLength; + } else { + (*FfsFile)->Size[0] = (UINT8)(FfsFileLength & 0x000000FF); + (*FfsFile)->Size[1] = (UINT8)((FfsFileLength & 0x0000FF00) >> 8); + (*FfsFile)->Size[2] = (UINT8)((FfsFileLength & 0x00FF0000) >> 16); + } + + // + // Recalculate the FFS header checksum. Instead of setting Header and State + // both to zero, set Header to (UINT8)(-State) so State preserves its original + // value + // + IntegrityCheck = &(*FfsFile)->IntegrityCheck; + IntegrityCheck->Checksum.Header = (UINT8) (0x100 - (*FfsFile)->State); + IntegrityCheck->Checksum.File = 0; + + IntegrityCheck->Checksum.Header = CalculateChecksum8 ( + (UINT8 *)(*FfsFile), FfsHeaderSize + ); - memmove ( - (UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize, - RebasedImage, - RebasedImageSize + if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) { + // + // Ffs header checksum = zero, so only need to calculate ffs body. + // + IntegrityCheck->Checksum.File = CalculateChecksum8 ( + (UINT8 *)(*FfsFile) + FfsHeaderSize, + FfsFileLength - FfsHeaderSize + ); + } else { + IntegrityCheck->Checksum.File = FFS_FIXED_CHECKSUM; + } + } else { + if (RebasedImageSize > SectPeSize) { + Error (NULL, 0, 4001, "Invalid", "rebased file is too large (%s)", FileName); + return EFI_UNSUPPORTED; + } + + memmove ( + (UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize, + RebasedImage, + RebasedImageSize ); - memset ( - (UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize + RebasedImageSize, - 0, - SectPeSize - RebasedImageSize + memset ( + (UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize + RebasedImageSize, + 0, + SectPeSize - RebasedImageSize ); - // - // Now update file checksum - // - if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) { - SavedState = (*FfsFile)->State; - (*FfsFile)->IntegrityCheck.Checksum.File = 0; - (*FfsFile)->State = 0; - (*FfsFile)->IntegrityCheck.Checksum.File = CalculateChecksum8 ( - (UINT8 *) ((UINT8 *)(*FfsFile) + FfsHeaderSize), - GetFfsFileLength (*FfsFile) - FfsHeaderSize - ); - (*FfsFile)->State = SavedState; + // + // Now update file checksum + // + if ((*FfsFile)->Attributes & FFS_ATTRIB_CHECKSUM) { + SavedState = (*FfsFile)->State; + (*FfsFile)->IntegrityCheck.Checksum.File = 0; + (*FfsFile)->State = 0; + (*FfsFile)->IntegrityCheck.Checksum.File = CalculateChecksum8 ( + (UINT8 *) ((UINT8 *)(*FfsFile) + FfsHeaderSize), + GetFfsFileLength (*FfsFile) - FfsHeaderSize + ); + (*FfsFile)->State = SavedState; + } } // @@ -3794,7 +3877,7 @@ Routine Description: Status = UefiImageInitializeContext ( &ImageContext, - (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize), + (VOID *) ((UINTN)(*FfsFile) + FileOffset), RebasedImageSize, UEFI_IMAGE_SOURCE_FV ); @@ -3811,7 +3894,12 @@ Routine Description: &ImageContext ); - free (SymbolsPathCpy); + UefiImageFileBuffer = NULL; + UefiImageFileSize = 0; + + if (SymbolsPathCpy != NULL) { + free (SymbolsPathCpy); + } } return EFI_SUCCESS; diff --git a/BaseTools/Source/C/Include/Common/AutoGen.h b/BaseTools/Source/C/Include/Common/AutoGen.h index 52135a9977..8b5f42bd03 100644 --- a/BaseTools/Source/C/Include/Common/AutoGen.h +++ b/BaseTools/Source/C/Include/Common/AutoGen.h @@ -171,7 +171,7 @@ extern UINT64 _gPcd_SkuId_Array[]; //#define _PCD_SET_MODE_8_PcdUefiImageFormatSupportNonFv ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD #define _PCD_TOKEN_PcdUefiImageFormatSupportFv 0U -#define _PCD_VALUE_PcdUefiImageFormatSupportFv 0x01 +#define _PCD_VALUE_PcdUefiImageFormatSupportFv 0x03 #define _PCD_SIZE_PcdUefiImageFormatSupportFv 1 #define _PCD_GET_MODE_SIZE_PcdUefiImageFormatSupportFv _PCD_SIZE_PcdUefiImageFormatSupportFv #define _PCD_GET_MODE_8_PcdUefiImageFormatSupportFv _PCD_VALUE_PcdUefiImageFormatSupportFv diff --git a/BaseTools/Source/C/Makefiles/ms.rule b/BaseTools/Source/C/Makefiles/ms.rule index 5b9a90785c..19d37846db 100644 --- a/BaseTools/Source/C/Makefiles/ms.rule +++ b/BaseTools/Source/C/Makefiles/ms.rule @@ -39,6 +39,10 @@ -@if not exist $(@D)\ mkdir $(@D) $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ +{$(EDK2_PATH)\MdePkg\Library\BaseUeImageLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseUeImageLib\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + {$(EDK2_PATH)\MdePkg\Library\BaseUefiImageLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\}.obj : -@if not exist $(@D)\ mkdir $(@D) $(CC) -c $(CFLAGS) -DUEFI_IMAGE_FORMAT_SUPPORT_SOURCES=0x02 $(EDK2_INC) $< -Fo$@ diff --git a/BaseTools/Source/Python/Common/DataType.py b/BaseTools/Source/Python/Common/DataType.py index fdbcdbc308..51d122858c 100644 --- a/BaseTools/Source/Python/Common/DataType.py +++ b/BaseTools/Source/Python/Common/DataType.py @@ -122,6 +122,7 @@ BINARY_FILE_TYPE_PEI_DEPEX = 'PEI_DEPEX' BINARY_FILE_TYPE_DXE_DEPEX = 'DXE_DEPEX' BINARY_FILE_TYPE_SMM_DEPEX = 'SMM_DEPEX' +BINARY_FILE_TYPE_UE = 'UE' BINARY_FILE_TYPE_VER = 'VER' BINARY_FILE_TYPE_UI = 'UI' BINARY_FILE_TYPE_BIN = 'BIN' diff --git a/BaseTools/Source/Python/GenFds/DataSection.py b/BaseTools/Source/Python/GenFds/DataSection.py index 365f9695bc..3bbbd2f295 100644 --- a/BaseTools/Source/Python/GenFds/DataSection.py +++ b/BaseTools/Source/Python/GenFds/DataSection.py @@ -79,10 +79,10 @@ def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = No CopyLongFilePath(MapFile, CopyMapFile) #Get PE Section alignment when align is set to AUTO - if self.Alignment == 'Auto' and self.SecType in (BINARY_FILE_TYPE_PE32): + if self.Alignment == 'Auto' and self.SecType in (BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_UE): self.Alignment = "0" NoStrip = True - if self.SecType in (BINARY_FILE_TYPE_PE32): + if self.SecType in (BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_UE): if self.KeepReloc is not None: NoStrip = self.KeepReloc @@ -101,6 +101,16 @@ def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = No ) self.SectFileName = StrippedFile + if self.SecType == BINARY_FILE_TYPE_UE: + UeFile = os.path.join( OutputPath, ModuleName + 'Ue.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + UeFile, + GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict), + Format = "UE", + IsMakefile = IsMakefile + ) + self.SectFileName = UeFile + OutputFile = os.path.join (OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get(self.SecType)) OutputFile = os.path.normpath(OutputFile) GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType), IsMakefile = IsMakefile) diff --git a/BaseTools/Source/Python/GenFds/EfiSection.py b/BaseTools/Source/Python/GenFds/EfiSection.py index 6816aeb129..3fe4094d6b 100644 --- a/BaseTools/Source/Python/GenFds/EfiSection.py +++ b/BaseTools/Source/Python/GenFds/EfiSection.py @@ -62,7 +62,7 @@ def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = Non StringData = FfsInf.__ExtendMacro__(self.StringData) ModuleNameStr = FfsInf.__ExtendMacro__('$(MODULE_NAME)') NoStrip = True - if FfsInf.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE) and SectionType in (BINARY_FILE_TYPE_PE32): + if FfsInf.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE) and SectionType in (BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_UE): if FfsInf.KeepReloc is not None: NoStrip = FfsInf.KeepReloc elif FfsInf.KeepRelocFromRule is not None: @@ -259,7 +259,7 @@ def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = Non File = GenFdsGlobalVariable.MacroExtend(File, Dict) #Get PE Section alignment when align is set to AUTO - if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32): + if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_UE): Align = "0" if File[(len(File)-4):] == '.efi' and FfsInf.InfModule.BaseName == os.path.basename(File)[:-4]: MapFile = File.replace('.efi', '.map') @@ -296,6 +296,16 @@ def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = Non ) File = StrippedFile + if SectionType == BINARY_FILE_TYPE_UE: + UeFile = os.path.join( OutputPath, ModuleName + 'Ue.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + UeFile, + File, + Format = "UE", + IsMakefile = IsMakefile + ) + File = UeFile + """Call GenSection""" GenFdsGlobalVariable.GenerateSection(OutputFile, [File], diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py index cdc448adcc..160fe9c458 100644 --- a/BaseTools/Source/Python/GenFds/FdfParser.py +++ b/BaseTools/Source/Python/GenFds/FdfParser.py @@ -2597,7 +2597,7 @@ def _FileCouldHaveRelocFlag (FileType): # @staticmethod def _SectionCouldHaveRelocFlag (SectionType): - if SectionType in {BINARY_FILE_TYPE_PE32}: + if SectionType in {BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_UE}: return True else: return False @@ -2923,10 +2923,10 @@ def _GetLeafSection(self, Obj): self.SetFileBufferPos(OldPos) return False - if self._Token not in {"COMPAT16", BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_PIC, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\ + if self._Token not in {"COMPAT16", BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_UE, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\ BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX}: raise Warning("Unknown section type '%s'" % self._Token, self.FileName, self.CurrentLineNumber) - if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32): + if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32) and (not self._Token == BINARY_FILE_TYPE_UE): raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber) # DataSection @@ -3726,7 +3726,7 @@ def _GetRuleFileStatements(self): if SectionName not in { "COMPAT16", BINARY_FILE_TYPE_PE32, - BINARY_FILE_TYPE_PIC, "FV_IMAGE", + BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_UE, "FV_IMAGE", "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX}: @@ -3743,7 +3743,7 @@ def _GetRuleFileStatements(self): if self._GetAlignment(): if self._Token not in ALIGNMENTS: raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber) - if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32): + if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_UE): raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber) SectAlignment = self._Token @@ -3796,7 +3796,7 @@ def _GetEfiSection(self, Obj): if SectionName not in { "COMPAT16", BINARY_FILE_TYPE_PE32, - BINARY_FILE_TYPE_PIC, "FV_IMAGE", + BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_UE, "FV_IMAGE", "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX, BINARY_FILE_TYPE_GUID}: @@ -3843,7 +3843,7 @@ def _GetEfiSection(self, Obj): elif self._GetNextToken(): if self._Token not in { T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32, - BINARY_FILE_TYPE_PIC, + BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_UE, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID, @@ -3907,7 +3907,7 @@ def _GetEfiSection(self, Obj): if self._GetAlignment(): if self._Token not in ALIGNMENTS: raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber) - if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32): + if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_UE): raise Warning("Auto alignment can only be used in PE32 section ", self.FileName, self.CurrentLineNumber) EfiSectionObj.Alignment = self._Token @@ -3928,7 +3928,7 @@ def _GetEfiSection(self, Obj): elif self._GetNextToken(): if self._Token not in { T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32, - BINARY_FILE_TYPE_PIC, + BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_UE, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID, @@ -4020,6 +4020,9 @@ def _CheckRuleSectionFileType(self, SectionType, FileType): elif SectionType == BINARY_FILE_TYPE_PIC: if FileType not in {BINARY_FILE_TYPE_PIC, "SEC_PIC"}: raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == BINARY_FILE_TYPE_UE: + if FileType not in {BINARY_FILE_TYPE_UE, "SEC_UE"}: + raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) elif SectionType == "RAW": if FileType not in {BINARY_FILE_TYPE_BIN, "SEC_BIN", "RAW", "ASL", "ACPI"}: raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) diff --git a/BaseTools/Source/Python/GenFds/Ffs.py b/BaseTools/Source/Python/GenFds/Ffs.py index 64b031f33f..b54cf33de9 100644 --- a/BaseTools/Source/Python/GenFds/Ffs.py +++ b/BaseTools/Source/Python/GenFds/Ffs.py @@ -33,6 +33,7 @@ SectionSuffix = { BINARY_FILE_TYPE_PE32 : '.pe32', BINARY_FILE_TYPE_PIC : '.pic', + BINARY_FILE_TYPE_UE : '.pe32', BINARY_FILE_TYPE_DXE_DEPEX : '.dpx', 'VERSION' : '.ver', BINARY_FILE_TYPE_UI : '.ui', diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py index 1c78b71886..7a214953fc 100644 --- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -775,7 +775,7 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch) #Get PE Section alignment when align is set to AUTO - if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32): + if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_UE): ImageObj = PeImageClass (File) if ImageObj.SectionAlignment < 0x400: self.Alignment = str (ImageObj.SectionAlignment) @@ -799,6 +799,16 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): ) File = StrippedFile + if SectionType == BINARY_FILE_TYPE_UE: + UeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Ue.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + UeFile, + File, + Format = "UE", + IsMakefile=IsMakefile + ) + File = UeFile + GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile) OutputFileList.append(OutputFile) else: @@ -809,7 +819,7 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch) #Get PE Section alignment when align is set to AUTO - if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32): + if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_UE): ImageObj = PeImageClass (GenSecInputFile) if ImageObj.SectionAlignment < 0x400: self.Alignment = str (ImageObj.SectionAlignment) @@ -834,6 +844,16 @@ def __GenSimpleFileSection__(self, Rule, IsMakefile = False): ) GenSecInputFile = StrippedFile + if SectionType == BINARY_FILE_TYPE_UE: + UeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Ue.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + UeFile, + GenSecInputFile, + Format = "UE", + IsMakefile=IsMakefile + ) + GenSecInputFile = UeFile + GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile) OutputFileList.append(OutputFile) diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py index 14a2afc143..abfce043d9 100644 --- a/BaseTools/Source/Python/GenFds/GenFds.py +++ b/BaseTools/Source/Python/GenFds/GenFds.py @@ -733,12 +733,12 @@ def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj): if not os.path.exists(FfsPath[0]): continue MatchDict = {} - ReFileEnds = compile(r'\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$') + ReFileEnds = compile(r'\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.ue.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$') FileList = os.listdir(FfsPath[0]) for File in FileList: Match = ReFileEnds.search(File) if Match: - for Index in range(1, 7): + for Index in range(1, 8): if Match.group(Index) and Match.group(Index) in MatchDict: MatchDict[Match.group(Index)].append(File) elif Match.group(Index): @@ -759,6 +759,8 @@ def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj): FileList = MatchDict['fv.sec.txt'] elif '.pe32.txt' in MatchDict: FileList = MatchDict['.pe32.txt'] + elif '.ue.txt' in MatchDict: + FileList = MatchDict['.ue.txt'] elif '.pic.txt' in MatchDict: FileList = MatchDict['.pic.txt'] elif '.raw.txt' in MatchDict: diff --git a/BaseTools/Source/Python/GenFds/Section.py b/BaseTools/Source/Python/GenFds/Section.py index d05d656417..0156c5ed87 100644 --- a/BaseTools/Source/Python/GenFds/Section.py +++ b/BaseTools/Source/Python/GenFds/Section.py @@ -26,6 +26,7 @@ class Section (SectionClassObject): 'FREEFORM' : 'EFI_SECTION_FREEFORM_SUBTYPE_GUID', BINARY_FILE_TYPE_PE32 : 'EFI_SECTION_PE32', BINARY_FILE_TYPE_PIC : 'EFI_SECTION_PIC', + BINARY_FILE_TYPE_UE : 'EFI_SECTION_PE32', 'FV_IMAGE' : 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', 'COMPAT16' : 'EFI_SECTION_COMPATIBILITY16', BINARY_FILE_TYPE_DXE_DEPEX : 'EFI_SECTION_DXE_DEPEX', @@ -46,6 +47,7 @@ class Section (SectionClassObject): BINARY_FILE_TYPE_PIC : '.pic', BINARY_FILE_TYPE_PEI_DEPEX : '.depex', 'SEC_PEI_DEPEX' : '.depex', + BINARY_FILE_TYPE_UE : '.pe32', BINARY_FILE_TYPE_UNI_VER : '.ver', BINARY_FILE_TYPE_VER : '.ver', BINARY_FILE_TYPE_UNI_UI : '.ui', @@ -121,7 +123,8 @@ def GetFileList(FfsInf, FileType, FileExtension, Dict = None, IsMakefile=False, for File in FfsInf.BinFileList: if File.Arch == TAB_ARCH_COMMON or FfsInf.CurrentArch == File.Arch: if File.Type == FileType or (int(FfsInf.PiSpecVersion, 16) >= 0x0001000A \ - and FileType == 'DXE_DPEX' and File.Type == BINARY_FILE_TYPE_SMM_DEPEX): + and FileType == 'DXE_DPEX' and File.Type == BINARY_FILE_TYPE_SMM_DEPEX) \ + or (FileType == BINARY_FILE_TYPE_UE and File.Type == BINARY_FILE_TYPE_PE32): if TAB_STAR in FfsInf.TargetOverrideList or File.Target == TAB_STAR or File.Target in FfsInf.TargetOverrideList or FfsInf.TargetOverrideList == []: FileList.append(FfsInf.PatchEfiFile(File.Path, File.Type)) else: diff --git a/BaseTools/Source/Python/UPT/Library/DataType.py b/BaseTools/Source/Python/UPT/Library/DataType.py index b212786a6d..b69b24f326 100644 --- a/BaseTools/Source/Python/UPT/Library/DataType.py +++ b/BaseTools/Source/Python/UPT/Library/DataType.py @@ -424,6 +424,7 @@ BINARY_FILE_TYPE_PEI_DEPEX = 'PEI_DEPEX' BINARY_FILE_TYPE_DXE_DEPEX = 'DXE_DEPEX' BINARY_FILE_TYPE_SMM_DEPEX = 'SMM_DEPEX' +BINARY_FILE_TYPE_UE = 'UE' BINARY_FILE_TYPE_VER = 'VER' BINARY_FILE_TYPE_UI = 'UI' BINARY_FILE_TYPE_BIN = 'BIN' diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c index 17d9ced288..55ee2c6f9a 100644 --- a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c +++ b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c @@ -35,16 +35,16 @@ RelocateImageUnder4GIfNeeded ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; - UINT8 *Buffer; - UINTN BufferSize; - EFI_HANDLE NewImageHandle; - UINT32 ImageSize; - UINT32 ImageAlignment; - UINTN Pages; - EFI_PHYSICAL_ADDRESS FfsBuffer; + EFI_STATUS Status; + UINT8 *Buffer; + UINTN BufferSize; + EFI_HANDLE NewImageHandle; + UINT32 ImageSize; + UINT32 ImageAlignment; + UINTN Pages; + EFI_PHYSICAL_ADDRESS FfsBuffer; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; - VOID *Interface; + VOID *Interface; // // If it is already <4G, no need do relocate diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 0c3578ba2c..e7e9579ead 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -72,6 +72,7 @@ MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec UefiCpuPkg/UefiCpuPkg.dec + OvmfPkg/OvmfPkg.dec [LibraryClasses] BaseMemoryLib @@ -126,6 +127,7 @@ gEfiMemoryAttributesTableGuid ## SOMETIMES_PRODUCES ## SystemTable gEfiEndOfDxeEventGroupGuid ## SOMETIMES_CONSUMES ## Event gEfiHobMemoryAllocStackGuid ## SOMETIMES_CONSUMES ## SystemTable + gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB [Ppis] gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index c12d234dfa..cfc82980a8 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -205,6 +205,8 @@ CoreInitializeImageServices ( UINT64 DxeCoreImageLength; VOID *DxeCoreEntryPoint; EFI_PEI_HOB_POINTERS DxeCoreHob; + EFI_HOB_GUID_TYPE *GuidHob; + HOB_IMAGE_CONTEXT *Hob; // // Searching for image hob @@ -233,20 +235,43 @@ CoreInitializeImageServices ( // Image = &mCorePrivateImage; - // - // FIXME: This is not a proper solution, because DxeCore may not be XIP - // - Status = UefiImageInitializeContext ( - ImageContext, - (VOID *) (UINTN) DxeCoreImageBaseAddress, - (UINT32) DxeCoreImageLength, - UEFI_IMAGE_SOURCE_FV - ); - ASSERT_EFI_ERROR (Status); + GuidHob = GetFirstGuidHob (&gUefiImageLoaderImageContextGuid); + if (GuidHob == NULL) { + DEBUG ((DEBUG_ERROR, "UefiImageLoaderImageContextGuid HOB is missing!\n")); + ASSERT (FALSE); + } + + Hob = (HOB_IMAGE_CONTEXT *)GET_GUID_HOB_DATA (GuidHob); + + ImageContext->FormatIndex = Hob->FormatIndex; - // FIXME: DxeCore is dynamically loaded by DxeIpl, can't it pass the context? if (ImageContext->FormatIndex == UefiImageFormatPe) { - ImageContext->Ctx.Pe.ImageBuffer = (VOID *) ImageContext->Ctx.Pe.FileBuffer; + ImageContext->Ctx.Pe.ImageBuffer = (VOID *)(UINTN)Hob->Ctx.Pe.ImageBuffer; + ImageContext->Ctx.Pe.AddressOfEntryPoint = Hob->Ctx.Pe.AddressOfEntryPoint; + ImageContext->Ctx.Pe.ImageType = Hob->Ctx.Pe.ImageType; + ImageContext->Ctx.Pe.FileBuffer = (CONST VOID *)(UINTN)Hob->Ctx.Pe.FileBuffer; + ImageContext->Ctx.Pe.ExeHdrOffset = Hob->Ctx.Pe.ExeHdrOffset; + ImageContext->Ctx.Pe.SizeOfImage = Hob->Ctx.Pe.SizeOfImage; + ImageContext->Ctx.Pe.FileSize = Hob->Ctx.Pe.FileSize; + ImageContext->Ctx.Pe.Subsystem = Hob->Ctx.Pe.Subsystem; + ImageContext->Ctx.Pe.SectionAlignment = Hob->Ctx.Pe.SectionAlignment; + ImageContext->Ctx.Pe.SectionsOffset = Hob->Ctx.Pe.SectionsOffset; + ImageContext->Ctx.Pe.NumberOfSections = Hob->Ctx.Pe.NumberOfSections; + ImageContext->Ctx.Pe.SizeOfHeaders = Hob->Ctx.Pe.SizeOfHeaders; + } else if (ImageContext->FormatIndex == UefiImageFormatUe) { + ImageContext->Ctx.Ue.ImageBuffer = (VOID *)(UINTN)Hob->Ctx.Ue.ImageBuffer; + ImageContext->Ctx.Ue.FileBuffer = (CONST UINT8 *)(UINTN)Hob->Ctx.Ue.FileBuffer; + ImageContext->Ctx.Ue.EntryPointAddress = Hob->Ctx.Ue.EntryPointAddress; + ImageContext->Ctx.Ue.LoadTablesFileOffset = Hob->Ctx.Ue.LoadTablesFileOffset; + ImageContext->Ctx.Ue.NumLoadTables = Hob->Ctx.Ue.NumLoadTables; + ImageContext->Ctx.Ue.LoadTables = (CONST UE_LOAD_TABLE *)(UINTN)Hob->Ctx.Ue.LoadTables; + ImageContext->Ctx.Ue.Segments = (CONST VOID *)(UINTN)Hob->Ctx.Ue.Segments; + ImageContext->Ctx.Ue.LastSegmentIndex = Hob->Ctx.Ue.LastSegmentIndex; + ImageContext->Ctx.Ue.SegmentAlignment = Hob->Ctx.Ue.SegmentAlignment; + ImageContext->Ctx.Ue.ImageSize = Hob->Ctx.Ue.ImageSize; + ImageContext->Ctx.Ue.Subsystem = Hob->Ctx.Ue.Subsystem; + ImageContext->Ctx.Ue.SegmentImageInfoIterSize = Hob->Ctx.Ue.SegmentImageInfoIterSize; + ImageContext->Ctx.Ue.SegmentsFileOffset = Hob->Ctx.Ue.SegmentsFileOffset; } else { ASSERT (FALSE); } @@ -426,7 +451,7 @@ GetUefiImageFixLoadingAssignedAddress ( Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoadingAddress, ImageDestSize); *LoadAddress = FixLoadingAddress; - DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status = %r \n", (VOID *)(UINTN)FixLoadingAddress, Status)); + DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status = %r \n", (VOID *)(UINTN)FixLoadingAddress, Status)); return Status; } @@ -715,7 +740,7 @@ CoreLoadPeImage ( // // Get the image entry point. // - Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UefiImageLoaderGetImageEntryPoint (ImageContext)); + Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UefiImageLoaderGetImageEntryPoint (ImageContext)); // // Fill in the image information for the Loaded Image Protocol @@ -1200,7 +1225,7 @@ CoreLoadImageCommon ( &ImageContext, FHand.Source, (UINT32) FHand.SourceSize, - ImageIsFromFv + ImageIsFromFv ? UEFI_IMAGE_SOURCE_FV : UEFI_IMAGE_SOURCE_NON_FV ); if (EFI_ERROR (Status)) { ASSERT (FALSE); @@ -1215,8 +1240,8 @@ CoreLoadImageCommon ( SecurityStatus = gSecurity2->FileAuthentication ( gSecurity2, OriginalFilePath, - &ImageContext, - sizeof (ImageContext), + &ImageContext, + sizeof (ImageContext), BootPolicy ); if (!EFI_ERROR (SecurityStatus) && ImageIsFromFv) { diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf index f1990eac77..1473be8f95 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -51,6 +51,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec [LibraryClasses] PcdLib @@ -73,7 +74,7 @@ gEfiPeiDecompressPpiGuid ## PRODUCES gEfiEndOfPeiSignalPpiGuid ## SOMETIMES_PRODUCES # Not produced on S3 boot path gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_CONSUMES - gEfiPeiLoadFilePpiGuid ## SOMETIMES_CONSUMES + gEfiPeiLoadFileWithHobPpiGuid ## SOMETIMES_CONSUMES gEfiPeiS3Resume2PpiGuid ## SOMETIMES_CONSUMES # Consumed on S3 boot path gEfiPeiRecoveryModulePpiGuid ## SOMETIMES_CONSUMES # Consumed on recovery boot path ## SOMETIMES_CONSUMES @@ -88,6 +89,7 @@ ## SOMETIMES_CONSUMES ## Variable:L"MemoryTypeInformation" ## SOMETIMES_PRODUCES ## HOB gEfiMemoryTypeInformationGuid + gUefiImageLoaderImageContextGuid [FeaturePcd.IA32] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES @@ -116,7 +118,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES [Depex] - gEfiPeiLoadFilePpiGuid AND gEfiPeiMasterBootModePpiGuid + gEfiPeiLoadFileWithHobPpiGuid AND gEfiPeiMasterBootModePpiGuid # # [BootMode] diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c index b9fe70332e..9c8bd7bd97 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c +++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c @@ -10,6 +10,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "DxeIpl.h" +#include + // // Module Globals used in the DXE to PEI hand off // These must be module globals, so the stack can be switched @@ -258,7 +260,7 @@ DxeLoadCore ( EFI_BOOT_MODE BootMode; EFI_PEI_FILE_HANDLE FileHandle; EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable; - EFI_PEI_LOAD_FILE_PPI *LoadFile; + EFI_PEI_LOAD_FILE_WITH_HOB_PPI *LoadFile; UINTN Instance; UINT32 AuthenticationState; UINTN DataSize; @@ -267,6 +269,7 @@ DxeLoadCore ( EDKII_PEI_CAPSULE_ON_DISK_PPI *PeiCapsuleOnDisk; EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1]; VOID *CapsuleOnDiskModePpi; + HOB_IMAGE_CONTEXT *ImageContext; // // if in S3 Resume, restore configure @@ -399,24 +402,27 @@ DxeLoadCore ( // FileHandle = DxeIplFindDxeCore (); + ImageContext = BuildGuidHob (&gUefiImageLoaderImageContextGuid, sizeof (HOB_IMAGE_CONTEXT)); + ASSERT (ImageContext != NULL); + // // Load the DXE Core from a Firmware Volume. // Instance = 0; do { - Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **)&LoadFile); + Status = PeiServicesLocatePpi (&gEfiPeiLoadFileWithHobPpiGuid, Instance++, NULL, (VOID **)&LoadFile); // // These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully. // ASSERT_EFI_ERROR (Status); Status = LoadFile->LoadFile ( - LoadFile, FileHandle, &DxeCoreAddress, &DxeCoreSize, &DxeCoreEntryPoint, - &AuthenticationState + &AuthenticationState, + ImageContext ); } while (EFI_ERROR (Status)); diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c index 277e2806d7..a32f1b949a 100644 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ b/MdeModulePkg/Core/Pei/Image/Image.c @@ -12,10 +12,21 @@ EFI_PEI_LOAD_FILE_PPI mPeiLoadImagePpi = { PeiLoadImageLoadImageWrapper }; -EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gEfiPeiLoadFilePpiGuid, - &mPeiLoadImagePpi +EFI_PEI_LOAD_FILE_WITH_HOB_PPI mPeiLoadImageWithHobPpi = { + PeiLoadImageLoadImageWithHob +}; + +EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiPeiLoadFileWithHobPpiGuid, + &mPeiLoadImageWithHobPpi + }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiLoadFilePpiGuid, + &mPeiLoadImagePpi + } }; /** @@ -154,31 +165,31 @@ GetUefiImageFixLoadingAssignedAddress ( **/ EFI_STATUS LoadAndRelocateUefiImage ( - IN EFI_PEI_FILE_HANDLE FileHandle, - IN VOID *Pe32Data, - IN UINT32 Pe32DataSize, - OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, - OUT EFI_PHYSICAL_ADDRESS *ImageAddress, - OUT UINTN *DebugBase + IN EFI_PEI_FILE_HANDLE FileHandle, + IN VOID *Pe32Data, + IN UINT32 Pe32DataSize, + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + OUT EFI_PHYSICAL_ADDRESS *ImageAddress, + OUT UINTN *DebugBase ) { EFI_STATUS Status; BOOLEAN Success; PEI_CORE_INSTANCE *Private; - UINT32 ImageSize; - UINT32 ImageAlignment; - UINT64 ValueInSectionHeader; + UINT32 ImageSize; + UINT32 ImageAlignment; + UINT64 ValueInSectionHeader; BOOLEAN IsXipImage; EFI_STATUS ReturnStatus; BOOLEAN IsS3Boot; BOOLEAN IsPeiModule; BOOLEAN IsRegisterForShadow; EFI_FV_FILE_INFO FileInfo; - UINT32 DestinationPages; - UINT32 DestinationSize; - EFI_PHYSICAL_ADDRESS Destination; - UINT16 Machine; - BOOLEAN LoadDynamically; + UINT32 DestinationPages; + UINT32 DestinationSize; + EFI_PHYSICAL_ADDRESS Destination; + UINT16 Machine; + BOOLEAN LoadDynamically; Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ()); @@ -357,12 +368,12 @@ LoadAndRelocateUefiImage ( **/ EFI_STATUS LoadAndRelocateUefiImageInPlace ( - IN VOID *Pe32Data, + IN VOID *Pe32Data, IN VOID *ImageAddress, IN UINT32 ImageSize ) { - EFI_STATUS Status; + EFI_STATUS Status; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; ASSERT (Pe32Data != ImageAddress); @@ -455,11 +466,11 @@ PeiLoadImageLoadImage ( OUT UINT32 *AuthenticationState ) { - EFI_STATUS Status; - VOID *Pe32Data; - UINT32 Pe32DataSize; - EFI_PHYSICAL_ADDRESS ImageAddress; - UINTN DebugBase; + EFI_STATUS Status; + VOID *Pe32Data; + UINT32 Pe32DataSize; + EFI_PHYSICAL_ADDRESS ImageAddress; + UINTN DebugBase; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; *EntryPoint = 0; @@ -492,12 +503,11 @@ PeiLoadImageLoadImage ( Status = LoadAndRelocateUefiImage ( FileHandle, Pe32Data, - Pe32DataSize, - &ImageContext, - &ImageAddress, - &DebugBase + Pe32DataSize, + &ImageContext, + &ImageAddress, + &DebugBase ); - if (EFI_ERROR (Status)) { return Status; } @@ -541,7 +551,149 @@ PeiLoadImageLoadImage ( EfiFileName, sizeof (EfiFileName) ); + if (!RETURN_ERROR (Status)) { + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); + } + + DEBUG_CODE_END (); + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n")); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +PeiLoadImageLoadImageWithHob ( + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL, + OUT UINT64 *ImageSizeArg OPTIONAL, + OUT EFI_PHYSICAL_ADDRESS *EntryPoint, + OUT UINT32 *AuthenticationState, + OUT HOB_IMAGE_CONTEXT *Hob + ) +{ + EFI_STATUS Status; + VOID *Pe32Data; + UINT32 Pe32DataSize; + EFI_PHYSICAL_ADDRESS ImageAddress; + UINTN DebugBase; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + + *EntryPoint = 0; + *AuthenticationState = 0; + + // + // Try to find the exe section. + // + Status = PeiServicesFfsFindSectionData4 ( + EFI_SECTION_PE32, + 0, + FileHandle, + &Pe32Data, + &Pe32DataSize, + AuthenticationState + ); + if (EFI_ERROR (Status)) { + // + // PEI core only carry the loader function for PE32 executables + // If this two section does not exist, just return. + // + return Status; + } + + DEBUG ((DEBUG_INFO, "Loading PEIM %g\n", FileHandle)); + + // + // If memory is installed, perform the shadow operations + // + Status = LoadAndRelocateUefiImage ( + FileHandle, + Pe32Data, + Pe32DataSize, + &ImageContext, + &ImageAddress, + &DebugBase + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Save ImageContext into DXE CORE HOB + // + Hob->FormatIndex = ImageContext.FormatIndex; + + if (Hob->FormatIndex == UefiImageFormatPe) { + Hob->Ctx.Pe.ImageBuffer = (UINT32)(UINTN)ImageContext.Ctx.Pe.ImageBuffer; + Hob->Ctx.Pe.AddressOfEntryPoint = ImageContext.Ctx.Pe.AddressOfEntryPoint; + Hob->Ctx.Pe.ImageType = ImageContext.Ctx.Pe.ImageType; + Hob->Ctx.Pe.FileBuffer = (UINT32)(UINTN)ImageContext.Ctx.Pe.FileBuffer; + Hob->Ctx.Pe.ExeHdrOffset = ImageContext.Ctx.Pe.ExeHdrOffset; + Hob->Ctx.Pe.SizeOfImage = ImageContext.Ctx.Pe.SizeOfImage; + Hob->Ctx.Pe.FileSize = ImageContext.Ctx.Pe.FileSize; + Hob->Ctx.Pe.Subsystem = ImageContext.Ctx.Pe.Subsystem; + Hob->Ctx.Pe.SectionAlignment = ImageContext.Ctx.Pe.SectionAlignment; + Hob->Ctx.Pe.SectionsOffset = ImageContext.Ctx.Pe.SectionsOffset; + Hob->Ctx.Pe.NumberOfSections = ImageContext.Ctx.Pe.NumberOfSections; + Hob->Ctx.Pe.SizeOfHeaders = ImageContext.Ctx.Pe.SizeOfHeaders; + } else if (Hob->FormatIndex == UefiImageFormatUe) { + Hob->Ctx.Ue.ImageBuffer = (UINT32)(UINTN)ImageContext.Ctx.Ue.ImageBuffer; + Hob->Ctx.Ue.FileBuffer = (UINT32)(UINTN)ImageContext.Ctx.Ue.FileBuffer; + Hob->Ctx.Ue.EntryPointAddress = ImageContext.Ctx.Ue.EntryPointAddress; + Hob->Ctx.Ue.LoadTablesFileOffset = ImageContext.Ctx.Ue.LoadTablesFileOffset; + Hob->Ctx.Ue.NumLoadTables = ImageContext.Ctx.Ue.NumLoadTables; + Hob->Ctx.Ue.LoadTables = (UINT32)(UINTN)ImageContext.Ctx.Ue.LoadTables; + Hob->Ctx.Ue.Segments = (UINT32)(UINTN)ImageContext.Ctx.Ue.Segments; + Hob->Ctx.Ue.LastSegmentIndex = ImageContext.Ctx.Ue.LastSegmentIndex; + Hob->Ctx.Ue.SegmentAlignment = ImageContext.Ctx.Ue.SegmentAlignment; + Hob->Ctx.Ue.ImageSize = ImageContext.Ctx.Ue.ImageSize; + Hob->Ctx.Ue.Subsystem = ImageContext.Ctx.Ue.Subsystem; + Hob->Ctx.Ue.SegmentImageInfoIterSize = ImageContext.Ctx.Ue.SegmentImageInfoIterSize; + Hob->Ctx.Ue.SegmentsFileOffset = ImageContext.Ctx.Ue.SegmentsFileOffset; + } else { + ASSERT (FALSE); + } + + // + // Got the entry point from the loaded Pe32Data + // + *EntryPoint = UefiImageLoaderGetImageEntryPoint (&ImageContext); + + if (ImageAddressArg != NULL) { + *ImageAddressArg = ImageAddress; + } + + if (ImageSizeArg != NULL) { + *ImageSizeArg =UefiImageGetImageSize (&ImageContext); + } + + DEBUG_CODE_BEGIN (); + CHAR8 EfiFileName[512]; + UINT16 Machine; + + Machine = UefiImageGetMachine (&ImageContext); + + // + // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi + // + if (Machine != EFI_IMAGE_MACHINE_IA64) { + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p DebugBase=0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)DebugBase, (VOID *)(UINTN)*EntryPoint)); + } else { + // + // For IPF Image, the real entry point should be print. + // + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading PEIM at 0x%11p DebugBase=0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)DebugBase, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint))); + } + + // + // Print Module Name by PeImage PDB file name. + // + Status = UefiImageGetModuleNameFromSymbolsPath ( + &ImageContext, + EfiFileName, + sizeof (EfiFileName) + ); if (!RETURN_ERROR (Status)) { DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); } @@ -748,13 +900,13 @@ InitializeImageServices ( // The first time we are XIP (running from FLASH). We need to remember the // FLASH address so we can reinstall the memory version that runs faster // - PrivateData->XipLoadFile = &gPpiLoadFilePpiList; + PrivateData->XipLoadFile = gPpiLoadFilePpiList; PeiServicesInstallPpi (PrivateData->XipLoadFile); } else { // // 2nd time we are running from memory so replace the XIP version with the // new memory version. // - PeiServicesReInstallPpi (PrivateData->XipLoadFile, &gPpiLoadFilePpiList); + PeiServicesReInstallPpi (PrivateData->XipLoadFile, gPpiLoadFilePpiList); } } diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h index 9a89e71b03..e96c3b93c4 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.h +++ b/MdeModulePkg/Core/Pei/PeiMain.h @@ -1443,7 +1443,7 @@ InitializeImageServices ( **/ EFI_STATUS LoadAndRelocateUefiImageInPlace ( - IN VOID *Pe32Data, + IN VOID *Pe32Data, IN VOID *ImageAddress, IN UINT32 ImageSize ); @@ -1461,8 +1461,8 @@ LoadAndRelocateUefiImageInPlace ( EFI_STATUS PeiGetPe32Data ( IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **Pe32Data, - OUT UINT32 *Pe32DataSize + OUT VOID **Pe32Data, + OUT UINT32 *Pe32DataSize ); /** @@ -1489,6 +1489,17 @@ PeiLoadImageLoadImageWrapper ( OUT UINT32 *AuthenticationState ); +EFI_STATUS +EFIAPI +PeiLoadImageLoadImageWithHob ( + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL, + OUT UINT64 *ImageSizeArg OPTIONAL, + OUT EFI_PHYSICAL_ADDRESS *EntryPoint, + OUT UINT32 *AuthenticationState, + OUT HOB_IMAGE_CONTEXT *Hob + ); + /** Provide a callback for when the security PPI is installed. diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf index dd2f381c3c..b26e254887 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.inf +++ b/MdeModulePkg/Core/Pei/PeiMain.inf @@ -97,6 +97,7 @@ ## PRODUCES ## CONSUMES gEfiPeiLoadFilePpiGuid + gEfiPeiLoadFileWithHobPpiGuid gEfiPeiSecurity2PpiGuid ## NOTIFY gEfiTemporaryRamSupportPpiGuid ## SOMETIMES_CONSUMES gEfiTemporaryRamDonePpiGuid ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h index 71e826e198..73330b8216 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h @@ -1401,4 +1401,15 @@ SmmInsertImageRecord ( IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); +/** + Insert image record. + + @param[in] DriverEntry Driver information +**/ +VOID +SmmInsertImageRecord ( + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + ); + #endif diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c index 04dd595f79..ef71a3a7e1 100644 --- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c +++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c @@ -317,17 +317,19 @@ ReadyToLockEventNotify ( UEFI_IMAGE_SOURCE_FV ); ASSERT_EFI_ERROR (Status); + ImageSize = UefiImageGetImageSize (&ImageContext); ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext); - Pages = EFI_SIZE_TO_PAGES (ImageSize); - LoadAddress = 0xFFFFFFFF; - Status = AllocateAlignedPagesEx ( - AllocateMaxAddress, - EfiReservedMemoryType, - Pages, - ImageAlignment, - &LoadAddress - ); + Pages = EFI_SIZE_TO_PAGES (ImageSize); + LoadAddress = 0xFFFFFFFF; + + Status = AllocateAlignedPagesEx ( + AllocateMaxAddress, + EfiReservedMemoryType, + Pages, + ImageAlignment, + &LoadAddress + ); ASSERT_EFI_ERROR (Status); // diff --git a/MdePkg/Include/IndustryStandard/UeImage.h b/MdePkg/Include/IndustryStandard/UeImage.h new file mode 100644 index 0000000000..6f1a188bc5 --- /dev/null +++ b/MdePkg/Include/IndustryStandard/UeImage.h @@ -0,0 +1,667 @@ +/** @file + Definitions of the UEFI Executable (UE) file format. + + Copyright (c) 2021 - 2023, Marvin Häuser. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef UE_IMAGE_H_ +#define UE_IMAGE_H_ + +#include + +// +// UE segment definitions. +// + +/// +/// Definition of the UE segment permission configurations. +/// +enum { + UeSegmentPermX = 0, + UeSegmentPermRX = 1, + UeSegmentPermRW = 2, + // + // Read-only is the last value, as this makes it easier to implement it as + // the else/default case. + // + UeSegmentPermR = 3, + UeSegmentPermMax +}; + +/// +/// The minimum alignment requirement, in bytes, of each UE segment in the UE +/// address space. +/// +#define UE_SEGMENT_MIN_ALIGNMENT 0x00001000U + +/// +/// The maximum alignment requirement, in bytes, of each UE segment in the UE +/// address space. +/// +#define UE_SEGMENT_MAX_ALIGNMENT 0x08000000U + +/// +/// Information about the UE segment in the UE address space. +/// +/// [Bits 19:0] The size, in 4-KiB units, of the UE segment in the UE address +/// space. +/// [Bits 21:20] The UE segment permissions. +/// [Bits 31:22] Reserved for future use. Must be zero. +/// +typedef UINT32 UE_SEGMENT_IMAGE_INFO; + +/// +/// Definition of a UE segment header. +/// +typedef struct { + /// + /// Information about the UE segment in the UE address space. + /// + UE_SEGMENT_IMAGE_INFO ImageInfo; + /// + /// The size, in bytes, of the UE segment in the UE file. + /// + UINT32 FileSize; +} UE_SEGMENT; + +STATIC_ASSERT ( + sizeof (UE_SEGMENT) == 8 && ALIGNOF (UE_SEGMENT) == 4, + "The UE segment definition does not meet the specification." + ); + +/// +/// Definition of a UE XIP segment header. +/// +typedef struct { + /// + /// Information about the UE segment in the UE address space. + /// + UE_SEGMENT_IMAGE_INFO ImageInfo; +} UE_SEGMENT_XIP; + +STATIC_ASSERT ( + sizeof (UE_SEGMENT_XIP) == 4 && ALIGNOF (UE_SEGMENT_XIP) == 4, + "The UE XIP segment definition does not meet the specification." + ); + +/** + Retrieve the UE segment memory permissions. + + @param[in] ImageInfo The UE segment image information. +**/ +#define UE_SEGMENT_PERMISSIONS(ImageInfo) \ + ((UINT8)(((ImageInfo) >> 20U) & 0x03U)) + +/** + Retrieve the size, in bytes, of the UE segment in the UE address space. + + @param[in] ImageInfo The UE segment image information. +**/ +#define UE_SEGMENT_SIZE(ImageInfo) ((ImageInfo) << 12U) + +STATIC_ASSERT ( + IS_ALIGNED (UE_SEGMENT_SIZE (0xFFFFFFFF), UE_SEGMENT_MIN_ALIGNMENT), + "The UE segment size definition does not meet the specification." + ); + +// +// UE load table definitions. +// + +/// +/// The alignment, in bytes, of each UE load table in the UE file. +/// +#define UE_LOAD_TABLE_ALIGNMENT 8U + +/// +/// Definition of the UE load table identifiers. +/// +enum { + // + // An array of UE fixup roots. Blocks are ordered ascending by their + // base address. + // + UeLoadTableIdReloc = 0x00, + // + // An instance of the UE debug table.. + // + UeLoadTableIdDebug = 0x01 +}; + +/// +/// Definition of a UE load table header. +/// +typedef struct { + /// + /// Information about the UE load table. + /// + /// [Bits 28:0] The size, in 8-byte units, of the UE load table in the UE + /// file. + /// [Bits 31:29] The identifier of the UE load table. + /// + UINT32 FileInfo; +} UE_LOAD_TABLE; + +STATIC_ASSERT ( + sizeof (UE_LOAD_TABLE) == 4 && ALIGNOF (UE_LOAD_TABLE) == 4, + "The UE load table definition does not meet the specification." + ); + +/** + Retrieves the UE load table identifier. + + @param[in] FileInfo The UE load table file information. +**/ +#define UE_LOAD_TABLE_ID(FileInfo) ((UINT8)((FileInfo) >> 29U)) + +/** + Retrieves the size, in bytes, of the UE load table in the UE file. + + @param[in] FileInfo The UE load table file information. +**/ +#define UE_LOAD_TABLE_SIZE(FileInfo) ((FileInfo) << 3U) + +STATIC_ASSERT ( + IS_ALIGNED (UE_LOAD_TABLE_SIZE (0xFFFFFFFF), UE_LOAD_TABLE_ALIGNMENT), + "The UE load table size definition does not meet the specification." + ); + +// +// UE relocation table definitions. +// + +/// +/// Definitions of the generic UE relocation identifiers. +/// +enum { + UeReloc32 = 0x00, + UeReloc64 = 0x01, + UeReloc32NoMeta = 0x02, + UeRelocGenericMax +}; + +#if 0 +/// +/// Definition of the ARM UE relocation identifiers. +/// +enum { + UeRelocArmMovtMovw = 0x02 +}; +#endif + +/// +/// The alignment requirement for a UE fixup root. +/// +#define UE_FIXUP_ROOT_ALIGNMENT 4U + +STATIC_ASSERT ( + UE_FIXUP_ROOT_ALIGNMENT <= UE_LOAD_TABLE_ALIGNMENT, + "The UE fixup root definition does not meet the specification." + ); + +/// +/// Definition of a UE fixup root. +/// +typedef struct { + /// + /// The offset of the first head fixup, in bytes, from the end of the previous + /// UE relocation fixup (chained or not). The first UE fixup root is + /// relative to 0. + /// + UINT32 FirstOffset; + /// + /// The head fixups of the UE fixup root. + /// + /// [Bits 3:0] The type of the UE relocation fixup. + /// [Bits 15:4] The offset of the next UE head fixup from the end of the last + /// UE relocation fixup in the chain (if chained). If 0x0FFF, the + /// current fixup root is terminated. + /// + UINT16 Heads[]; +} UE_FIXUP_ROOT; + +STATIC_ASSERT ( + sizeof (UE_FIXUP_ROOT) == 4 && ALIGNOF (UE_FIXUP_ROOT) == UE_FIXUP_ROOT_ALIGNMENT, + "The UE fixup root definition does not meet the specification." + ); + +STATIC_ASSERT ( + OFFSET_OF (UE_FIXUP_ROOT, Heads) == sizeof (UE_FIXUP_ROOT), + "The UE fixup root definition does not meet the specification." + ); + +STATIC_ASSERT ( + sizeof (UE_FIXUP_ROOT) <= UE_LOAD_TABLE_ALIGNMENT, + "The UE fixup root definition is misaligned." + ); + +#define MIN_SIZE_OF_UE_FIXUP_ROOT (sizeof (UE_FIXUP_ROOT) + sizeof (UINT16)) + +/// +/// The maximum offset, in bytes, of the next UE head fixup. +/// +#define UE_HEAD_FIXUP_MAX_OFFSET 0x0FFEU + +/// +/// UE head fixup offset that terminates a fixup root. +/// +#define UE_HEAD_FIXUP_OFFSET_END 0x0FFFU + +/** + Retrieves the target offset of the UE relocation fixup. + + @param[in] FixupInfo The UE relocation fixup information. +**/ +#define UE_RELOC_FIXUP_OFFSET(FixupInfo) ((UINT16)((FixupInfo) >> 4U)) + +/** + Retrieves the type of the UE relocation fixup. + + @param[in] FixupInfo The UE relocation fixup information. +**/ +#define UE_RELOC_FIXUP_TYPE(FixupInfo) ((FixupInfo) & 0x000FU) + +/** + Retrieves the offset of the next UE chained relocation fixup. + + @param[in] FixupInfo The UE relocation fixup information. +**/ +#define UE_CHAINED_RELOC_FIXUP_NEXT_OFFSET(FixupInfo) \ + ((UINT16)((UINT16)(FixupInfo) >> 4U) & 0x0FFFU) + +/// +/// The maximum offset, in bytes, of the next UE chained relocation fixup. +/// +#define UE_CHAINED_RELOC_FIXUP_MAX_OFFSET 0x0FFEU + +/// +/// UE chained relocation fixup offset that terminates a chain. +/// +#define UE_CHAINED_RELOC_FIXUP_OFFSET_END 0x0FFFU + +/** + Retrieves the type of the next UE chained relocation fixup. + + @param[in] FixupInfo The UE relocation fixup information. +**/ +#define UE_CHAINED_RELOC_FIXUP_NEXT_TYPE(FixupInfo) \ + ((UINT8)((UINT16)(FixupInfo) & 0x0FU)) + +/// +/// The shift exponent for UE chained relocation fixup values. +/// +#define UE_CHAINED_RELOC_FIXUP_VALUE_SHIFT 16U + +/** + Retrieves the value of the current UE chained relocation fixup. + + @param[in] FixupInfo The UE relocation fixup information. +**/ +#define UE_CHAINED_RELOC_FIXUP_VALUE(FixupInfo) \ + RShiftU64 (FixupInfo, UE_CHAINED_RELOC_FIXUP_VALUE_SHIFT) + +/// +/// Definition of the common header of UE chained relocation fixups. +/// +/// [Bits 3:0] The relocation type of the next chained relocation fixup. Only +/// valid when [Bits 15:4] are not 0x0FFF. +/// [Bits 15:4] The offset to the next chained relocation fixup from the end +/// of the current one. If 0x0FFF, the current chain is terminated. +/// Consult the fixup root for further relocation fixups. +/// +typedef UINT16 UE_RELOC_FIXUP_HDR; + +/// +/// Definition of the generic 64-bit UE chained relocation fixup. +/// +/// [Bits 15:0] The common header of UE chained relocation fixups. +/// [Bits 47:16] The address value to relocate. +/// [Bits 63:48] Must be zero. +/// +typedef UINT64 UE_RELOC_FIXUP_64; + +/// +/// The shift exponent for UE chained 32-bit relocation fixup values. +/// +#define UE_CHAINED_RELOC_FIXUP_VALUE_32_SHIFT 12U + +/** + Retrieves the value of the current UE chained 32-bit relocation fixup. + + @param[in] FixupInfo The UE relocation fixup information. +**/ +#define UE_CHAINED_RELOC_FIXUP_VALUE_32(FixupInfo) \ + (UINT32)((UINT32)(FixupInfo) >> UE_CHAINED_RELOC_FIXUP_VALUE_32_SHIFT) + +/// +/// Definition of the generic 32-bit UE chained relocation fixup. +/// +/// [Bits 11:0] The offset to the next chained relocation fixup from the end +/// of the current one. If 0x0FFF, the current chain is terminated. +/// Consult the fixup root for further relocation fixups. +/// [Bits 31:12] The address value to relocate. +/// +typedef UINT32 UE_RELOC_FIXUP_32; + +#if 0 +/// +/// Definition of the ARM Thumb MOVT/MOVW UE chained relocation fixup. +/// +/// [Bits 15:0] The common header of UE chained relocation fixups. +/// [Bits 31:16] The 16-bit immediate value to relocate. +/// +typedef UINT32 UE_RELOC_FIXUP_ARM_MOVT_MOVW; +#endif + +// +// UE debug table definitions. +// +// NOTE: The UE symbols base address offset is required for conversion of +// PE Images that have their first section start after the end of the +// Image headers. As PDBs cannot easily be rebased, store the offset. +// + +/// +/// Definition of a UE segment name. Must be \0-terminated. +/// +typedef UINT8 UE_SEGMENT_NAME[8]; + +STATIC_ASSERT ( + sizeof (UE_SEGMENT_NAME) == 8 && ALIGNOF (UE_SEGMENT_NAME) == 1, + "The UE segment name definition does not meet the specification." + ); + +/// +/// Definition of the UE debug table header. +/// +typedef struct { + /// + /// Information about the image regarding the symbols file. + /// + /// [Bits 1:0] The offset, in image alignment units, to be subtracted from the + /// UE base address in order to retrieve the UE symbols base + /// address. + /// [Bits 7:2] Reserved for future use. Must be zero. + /// + UINT8 ImageInfo; + /// + /// The length, in bytes, of the UE symbols path (excluding the terminator). + /// + UINT8 SymbolsPathLength; + /// + /// The UE symbols path. Must be \0-terminated. + /// + UINT8 SymbolsPath[]; + /// + /// The UE segment name table. The order matches the UE segment table. + /// +//UE_SEGMENT_NAME SegmentNames[]; +} UE_DEBUG_TABLE; + +/// +/// The minimum size, in bytes, of the UE debug table. +/// +#define MIN_SIZE_OF_UE_DEBUG_TABLE \ + (OFFSET_OF (UE_DEBUG_TABLE, SymbolsPath) + 1U) + +/** + Retrieves the UE symbol address subtrahend in SegmentAlignment-units. + + @param[in] ImageInfo The UE debug table image information. +**/ +#define UE_DEBUG_TABLE_IMAGE_INFO_SYM_SUBTRAHEND_FACTOR(ImageInfo) \ + ((UINT8)((ImageInfo) & 0x03U)) + +/** + Retrieves the UE segment name table of a UE debug table. + + @param[in] DebugTable The UE debug table. +**/ +#define UE_DEBUG_TABLE_SEGMENT_NAMES(DebugTable) \ + (CONST UE_SEGMENT_NAME *) ( \ + (DebugTable)->SymbolsPath + (DebugTable)->SymbolsPathLength + 1 \ + ) + +STATIC_ASSERT ( + sizeof (UE_DEBUG_TABLE) == 2 && ALIGNOF (UE_DEBUG_TABLE) == 1, + "The UE debug table definition does not meet the specification." + ); + +STATIC_ASSERT ( + ALIGNOF (UE_DEBUG_TABLE) <= UE_LOAD_TABLE_ALIGNMENT, + "The UE debug table definition is misaligned." + ); + +STATIC_ASSERT ( + OFFSET_OF (UE_DEBUG_TABLE, SymbolsPath) == sizeof (UE_DEBUG_TABLE), + "The UE fixup root definition does not meet the specification." + ); + +// +// UE header definitions. +// + +/// +/// The file magic number of a UE header. +/// +#define UE_HEADER_MAGIC SIGNATURE_16 ('U', 'E') + +/// +/// Definition of the UE machine identifiers. +/// +enum { + UeMachineI386 = 0, + UeMachineX64 = 1, + UeMachineArmThumbMixed = 2, + UeMachineArm64 = 3, + UeMachineRiscV32 = 4, + UeMachineRiscV64 = 5, + UeMachineRiscV128 = 6 +}; + +/// +/// Definition of the UE subsystem identifiers. +/// +enum { + UeSubsystemEfiApplication = 0, + UeSubsystemEfiBootServicesDriver = 1, + UeSubsystemEfiRuntimeDriver = 2 +}; + +/// +/// Definition of a UE file header. +/// +typedef struct { + /// + /// The file magic number to identify the UE file format. Must be 'UE'. + /// + UINT16 Magic; + /// + /// Information about the image kind and supported architectures. + /// + /// [Bits 2:0] Indicates the subsystem. + /// [Bits 7:3] Indicates the supported architectures. + /// + UINT8 Type; + /// + /// Information about the UE load tables and segments. + /// + /// [Bits 2:0] The number of UE load tables. + /// [Bits 7:3] The index of the last segment in the UE segment table. + /// + UINT8 TableCounts; + /// + /// Indicates the offset of the UE entry point in the UE address space. + /// + UINT32 EntryPointAddress; + /// + /// Information about the UE image. + /// + /// [Bits 51:0] The base UEFI page of the UE image, i.e., the base address in + /// 4 KiB units. + /// [Bits 55:52] Reserved for future use. Must be zero. + /// [Bit 56] Indicates whether the UE image is XIP + /// [Bit 57] Indicates whether the UE image is designated for a fixed + /// address. + /// [Bit 58] Indicates whether the UE relocation table has been stripped. + /// [Bit 59] Indicates whether UE chained fixups are used. + /// [Bits 63:60] The shift exponent, offset by -12, for the UE segment + /// alignment in bytes. + /// + UINT64 ImageInfo; + /// + /// The UE segment table. It contains all data of the UE address space. + /// + /// All UE segments are contiguous in the UE address space. + /// The offset of the first UE segment in the UE address space is 0. + /// + /// All UE segments' data are contiguous in the UE file. + /// The offset of the first UE segment in the UE file is the end of the UE + /// file header. + /// + UE_SEGMENT Segments[]; + /// + /// The UE load tables. They contain data useful for UE loading. + /// + /// All UE load tables are contiguous in the UE file. + /// The offset of the first UE load table in the UE file is the end of the last + /// UE segment in the UE file. + /// + /// All UE load tables are ordered ascending by their identifier. + /// +//UE_LOAD_TABLE LoadTables[]; +} UE_HEADER; + +/// +/// The minimum size, in bytes, of a valid UE header. +/// +#define MIN_SIZE_OF_UE_HEADER \ + (OFFSET_OF (UE_HEADER, Segments) + sizeof (UE_SEGMENT)) + +STATIC_ASSERT ( + sizeof (UE_HEADER) == 16 && ALIGNOF (UE_HEADER) == 8, + "The UE header definition does not meet the specification." + ); + +STATIC_ASSERT ( + ALIGNOF (UE_SEGMENT) <= ALIGNOF (UE_LOAD_TABLE), + "The UE header definition is misaligned." + ); + +STATIC_ASSERT ( + OFFSET_OF (UE_HEADER, Segments) == sizeof (UE_HEADER), + "The UE header definition does not meet the specification." + ); + +/** + Retrieves the UE base address. + + @param[in] ImageInfo The UE header image information. +**/ +#define UE_HEADER_BASE_ADDRESS(ImageInfo) LShiftU64 (ImageInfo, 12) + +/** + Retrieves the UE segment alignment, in bytes, as a power of two. + + @param[in] ImageInfo The UE header image information. +**/ +#define UE_HEADER_SEGMENT_ALIGNMENT(ImageInfo) \ + (1U << ((UINT8)RShiftU64 (ImageInfo, 60) + 12U)) + +/// +/// UE header image information bit that indicates whether the image is XIP. +/// +#define UE_HEADER_IMAGE_INFO_XIP 0x0100000000000000ULL + +/// +/// UE header image information bit that indicates whether the image is +/// designated to be loaded to a fixed address. +/// +#define UE_HEADER_IMAGE_INFO_FIXED_ADDRESS 0x0200000000000000ULL + +/// +/// UE header image information bit that indicates whether the relocation fixups +/// have been stripped. +/// +#define UE_HEADER_IMAGE_INFO_RELOCATION_FIXUPS_STRIPPED 0x0400000000000000ULL + +/// +/// UE header image information bit that indicates whether UE relocation fixup +/// chains are utilized. +/// +#define UE_HEADER_IMAGE_INFO_CHAINED_FIXUPS 0x0800000000000000ULL + +/** + Retrieves the UE subsystem. + + @param[in] Type The UE header type information. +**/ +#define UE_HEADER_SUBSYSTEM(Type) ((Type) & 0x07U) + +/** + Retrieves the UE supported architectures. + + @param[in] Type The UE header type information. +**/ +#define UE_HEADER_ARCH(Type) ((Type) >> 3U) + +/// +/// The maximum number of UE load tables. +/// +#define UE_HEADER_NUM_LOAD_TABLES_MAX 7U + +/** + Retrieves the number of UE load tables. + + @param[in] TableCounts The UE header segment and load table information. +**/ +#define UE_HEADER_NUM_LOAD_TABLES(TableCounts) ((TableCounts) & 0x07U) + +STATIC_ASSERT ( + UE_HEADER_NUM_LOAD_TABLES (0xFFU) == UE_HEADER_NUM_LOAD_TABLES_MAX, + "The number of load tables violates the specification." + ); + +/// +/// The maximum number of UE segments. +/// +#define UE_HEADER_NUM_SEGMENTS_MAX 32U + +/** + Retrieves the index of the last UE segment, i.e., their amount minus 1. + + @param[in] TableCounts The UE header segment and load table information. +**/ +#define UE_HEADER_LAST_SEGMENT_INDEX(TableCounts) ((TableCounts) >> 3U) + +STATIC_ASSERT ( + UE_HEADER_LAST_SEGMENT_INDEX (0xFFU) + 1U == UE_HEADER_NUM_SEGMENTS_MAX, + "The number of load tables violates the specification." + ); + +/** + Retrieves the 8 byte aligned UE file size. + + If the file size is larger than this value, the appended data may be the UE + certificate table. + + @param[in] FileInfo The UE header file information. +**/ +#define UE_HEADER_FILE_SIZE(FileInfo) ((FileInfo) << 3U) + +STATIC_ASSERT ( + IS_ALIGNED (UE_HEADER_FILE_SIZE (0xFFFFFFFF), UE_LOAD_TABLE_ALIGNMENT), + "The UE file size definition does not meet the specification." + ); + +/// +/// The maximum size, in bytes, of a valid UE header. +/// +#define MAX_SIZE_OF_UE_HEADER \ + MIN_SIZE_OF_UE_HEADER + \ + UE_HEADER_NUM_SEGMENTS_MAX * sizeof (UE_SEGMENT) + \ + UE_HEADER_NUM_LOAD_TABLES_MAX * sizeof (UE_LOAD_TABLE) + +#endif // UE_IMAGE_H_ diff --git a/MdePkg/Include/Library/UeImageLib.h b/MdePkg/Include/Library/UeImageLib.h new file mode 100644 index 0000000000..850ca6b3df --- /dev/null +++ b/MdePkg/Include/Library/UeImageLib.h @@ -0,0 +1,181 @@ +/** @file + UEFI Image Loader library implementation for UE Images. + + Copyright (c) 2021 - 2023, Marvin Häuser. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef UE_LIB_H_ +#define UE_LIB_H_ + +#include + +typedef struct { + CONST UINT8 *FileBuffer; + UINT32 UnsignedFileSize; + UINT8 Subsystem; + UINT8 Machine; + BOOLEAN FixedAddress; + BOOLEAN XIP; + UINT8 LastSegmentIndex; + UINT32 SegmentsFileOffset; // Unused for XIP + UINT32 SegmentAlignment; + CONST VOID *Segments; + UINT8 SegmentImageInfoIterSize; + BOOLEAN RelocsStripped; + UINT8 NumLoadTables; + UINT32 LoadTablesFileOffset; + UINT32 RelocTableSize; + CONST UE_LOAD_TABLE *LoadTables; + VOID *ImageBuffer; + UINT32 ImageSize; + UINT32 EntryPointAddress; + UINT64 BaseAddress; // Unused for XIP +} UE_LOADER_IMAGE_CONTEXT; + +typedef struct UE_LOADER_RUNTIME_CONTEXT_ UE_LOADER_RUNTIME_CONTEXT; + +/** + Adds the digest of Data to HashContext. This function can be called multiple + times to compute the digest of discontinuous data. + + @param[in,out] HashContext The context of the current hash. + @param[in] Data The data to be hashed. + @param[in] DataSize The size, in Bytes, of Data. + + @returns Whether hashing has been successful. +**/ +typedef +BOOLEAN +(EFIAPI *UE_LOADER_HASH_UPDATE)( + IN OUT VOID *HashContext, + IN CONST VOID *Data, + IN UINTN DataSize + ); + +RETURN_STATUS +UeInitializeContextPreHash ( + OUT UE_LOADER_IMAGE_CONTEXT *Context, + IN CONST VOID *FileBuffer, + IN UINT32 FileSize + ); + +RETURN_STATUS +UeInitializeContextPostHash ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ); + +BOOLEAN +UeHashImageDefault ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context, + IN OUT VOID *HashContext, + IN UE_LOADER_HASH_UPDATE HashUpdate + ); + +RETURN_STATUS +UeLoadImage ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context, + OUT VOID *Destination, + IN UINT32 DestinationSize + ); + +RETURN_STATUS +UeLoaderGetRuntimeContextSize ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *Size + ); + +RETURN_STATUS +UeRelocateImage ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context, + IN UINT64 BaseAddress, + OUT UE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize + ); + +RETURN_STATUS +UeRelocateImageForRuntime ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN CONST UE_LOADER_RUNTIME_CONTEXT *RuntimeContext, + IN UINT64 BaseAddress + ); + +RETURN_STATUS +UeGetSymbolsPath ( + IN CONST UE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST CHAR8 **SymbolsPath, + OUT UINT32 *SymbolsPathSize + ); + +UINTN +UeLoaderGetImageDebugAddress ( + IN CONST UE_LOADER_IMAGE_CONTEXT *Context + ); + +RETURN_STATUS +UeGetSegmentNames ( + IN CONST UE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST UE_SEGMENT_NAME **SegmentNames + ); + +UINT32 +UeGetEntryPointAddress ( + IN CONST UE_LOADER_IMAGE_CONTEXT *Context + ); + +UINT16 +UeGetMachine ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ); + +UINT16 +UeGetSubsystem ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ); + +UINT32 +UeGetSegmentAlignment ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ); + +UINT32 +UeGetImageSize ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ); + +UINT64 +UeGetBaseAddress ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ); + +BOOLEAN +UeGetRelocsStripped ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ); + +BOOLEAN +UeGetFixedAddress( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ); + +UINTN +UeLoaderGetImageAddress ( + IN CONST UE_LOADER_IMAGE_CONTEXT *Context + ); + +UINT16 +UeGetSegments ( + IN CONST UE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST UE_SEGMENT **Segments + ); + +UINT16 +UeGetSegmentImageInfos ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST UINT32 **SegmentImageInfos, + OUT UINT8 *SegmentImageInfoIterSize + ); + +#endif // UE_LIB_H_ diff --git a/MdePkg/Include/Library/UefiImageLib.h b/MdePkg/Include/Library/UefiImageLib.h index 7528f3a6eb..957b7f17be 100644 --- a/MdePkg/Include/Library/UefiImageLib.h +++ b/MdePkg/Include/Library/UefiImageLib.h @@ -2,10 +2,12 @@ #ifndef UEFI_IMAGE_LIB_H_ #define UEFI_IMAGE_LIB_H_ +#include #include typedef enum { UefiImageFormatPe = 0, + UefiImageFormatUe = 1, UefiImageFormatMax } UEFI_IMAGE_FORMAT; @@ -14,11 +16,52 @@ typedef enum { #define UEFI_IMAGE_SOURCE_ALL 2U #define UEFI_IMAGE_SOURCE_MAX 3U +// FIXME: Get rid of pointers. +typedef struct { + UINT32 ImageBuffer; + UINT32 AddressOfEntryPoint; + UINT8 ImageType; + UINT32 FileBuffer; + UINT32 ExeHdrOffset; + UINT32 SizeOfImage; + UINT32 FileSize; + UINT16 Subsystem; + UINT32 SectionAlignment; + UINT32 SectionsOffset; + UINT16 NumberOfSections; + UINT32 SizeOfHeaders; +} PE_HOB_IMAGE_CONTEXT; + +typedef struct { + UINT32 ImageBuffer; + UINT32 FileBuffer; + UINT32 EntryPointAddress; + UINT32 LoadTablesFileOffset; + UINT8 NumLoadTables; + UINT32 LoadTables; + UINT32 Segments; + UINT8 LastSegmentIndex; + UINT32 SegmentAlignment; + UINT32 ImageSize; + UINT8 Subsystem; + UINT8 SegmentImageInfoIterSize; + UINT32 SegmentsFileOffset; +} UE_HOB_IMAGE_CONTEXT; + +typedef struct { + UINT8 FormatIndex; + union { + UE_HOB_IMAGE_CONTEXT Ue; + PE_HOB_IMAGE_CONTEXT Pe; + } Ctx; +} HOB_IMAGE_CONTEXT; + typedef UINT8 UEFI_IMAGE_SOURCE; typedef struct { UINT8 FormatIndex; union { + UE_LOADER_IMAGE_CONTEXT Ue; PE_COFF_LOADER_IMAGE_CONTEXT Pe; } Ctx; } UEFI_IMAGE_LOADER_IMAGE_CONTEXT; @@ -574,6 +617,22 @@ UefiImageLoaderGetImageAddress ( IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context ); +/** + Retrieves the Image debug address. Due to post-processing, the debug address + may deviate from the load address. Symbolication must use this address. + + May be called only after UefiImageLoadImage() has succeeded. + + @param[in,out] Context The context describing the Image. Must have been + initialised by UefiImageInitializeContext(). + + @returns The Image debug address. +**/ +UINTN +UefiImageLoaderGetDebugAddress ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ); + /** Retrieve the Image entry point address. diff --git a/MdePkg/Include/Ppi/LoadFile.h b/MdePkg/Include/Ppi/LoadFile.h index 838e3fda90..22c2071191 100644 --- a/MdePkg/Include/Ppi/LoadFile.h +++ b/MdePkg/Include/Ppi/LoadFile.h @@ -12,10 +12,13 @@ #ifndef __LOAD_FILE_PPI_H__ #define __LOAD_FILE_PPI_H__ +#include + #define EFI_PEI_LOAD_FILE_PPI_GUID \ { 0xb9e0abfe, 0x5979, 0x4914, { 0x97, 0x7f, 0x6d, 0xee, 0x78, 0xc2, 0x78, 0xa6 } } typedef struct _EFI_PEI_LOAD_FILE_PPI EFI_PEI_LOAD_FILE_PPI; +typedef struct _EFI_PEI_LOAD_FILE_WITH_HOB_PPI EFI_PEI_LOAD_FILE_WITH_HOB_PPI; /** Loads a PEIM into memory for subsequent execution. @@ -56,6 +59,17 @@ EFI_STATUS OUT UINT32 *AuthenticationState ); +typedef +EFI_STATUS +(EFIAPI *EFI_PEI_LOAD_FILE_WITH_HOB)( + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_PHYSICAL_ADDRESS *ImageAddress, + OUT UINT64 *ImageSize, + OUT EFI_PHYSICAL_ADDRESS *EntryPoint, + OUT UINT32 *AuthenticationState, + OUT HOB_IMAGE_CONTEXT *Hob + ); + /// /// This PPI is a pointer to the Load File service. /// This service will be published by a PEIM. The PEI Foundation @@ -65,6 +79,11 @@ struct _EFI_PEI_LOAD_FILE_PPI { EFI_PEI_LOAD_FILE LoadFile; }; +struct _EFI_PEI_LOAD_FILE_WITH_HOB_PPI { + EFI_PEI_LOAD_FILE_WITH_HOB LoadFile; +}; + extern EFI_GUID gEfiPeiLoadFilePpiGuid; +extern EFI_GUID gEfiPeiLoadFileWithHobPpiGuid; #endif diff --git a/MdePkg/Library/BaseUeImageLib/BaseUeImageLib.inf b/MdePkg/Library/BaseUeImageLib/BaseUeImageLib.inf new file mode 100644 index 0000000000..557b0961e3 --- /dev/null +++ b/MdePkg/Library/BaseUeImageLib/BaseUeImageLib.inf @@ -0,0 +1,33 @@ +## @file +# UEFI Image Loader library implementation for UE Images. +# +# Copyright (c) 2021, Marvin Häuser. All rights reserved.
+# +# SPDX-License-Identifier: BSD-3-Clause +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UeImageLib + FILE_GUID = 357AD87E-8D6B-468A-B3FA-0D9CC4C725CD + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = BaseUeImageLib + +[Sources] + UeImageLib.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + BaseOverflowLib + DebugLib + PcdLib + +[FixedPcd] + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRelocTypePolicy + gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRtRelocAllowTargetMismatch diff --git a/MdePkg/Library/BaseUeImageLib/UeImageLib.c b/MdePkg/Library/BaseUeImageLib/UeImageLib.c new file mode 100644 index 0000000000..f5f6e8720b --- /dev/null +++ b/MdePkg/Library/BaseUeImageLib/UeImageLib.c @@ -0,0 +1,1392 @@ +/** @file + UEFI image loader library implementation for UE images. + + Copyright (c) 2021 - 2023, Marvin Häuser. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct UE_LOADER_RUNTIME_CONTEXT_ { + UINT8 Machine; + UINT8 Reserved[7]; + UINT32 FixupSize; + UINT64 *FixupData; + UINT32 UnchainedRelocsSize; + UINT8 *UnchainedRelocs; +}; + +typedef union { + UINT32 Value32; + UINT64 Value64; +} UE_RELOC_FIXUP_VALUE; + +STATIC +RETURN_STATUS +InternalVerifySegments ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + CONST UE_SEGMENT *Segments; + UINT8 LastSegmentIndex; + UINT8 SegmentIndex; + UINT32 SegmentEndFileOffset; + UINT32 SegmentEndImageAddress; + BOOLEAN Overflow; + UINT32 SegmentImageSize; + + Segments = Context->Segments; + LastSegmentIndex = Context->LastSegmentIndex; + // + // As it holds that SegmentEndFileOffset - Context->SegmentsFileOffset <= SegmentEndImageAddress, + // and it holds that SegmentEndImageAddress % 4 KiB = 0, SegmentEndFileOffset - Context->SegmentsFileOffset + // can be at most 0xFFFFF000. As it holds that Context->SegmentsFileOffset <= MAX_SIZE_OF_UE_HEADER <= 0xFF0, + // this cannot overflow. + // + STATIC_ASSERT ( + MAX_SIZE_OF_UE_HEADER <= BASE_4KB - 8, + "The arithmetic below may overflow." + ); + + SegmentEndFileOffset = Context->SegmentsFileOffset; + // + // The first image segment must begin the image address space. + // + SegmentEndImageAddress = 0; + + for (SegmentIndex = 0; SegmentIndex <= LastSegmentIndex; ++SegmentIndex) { + SegmentImageSize = UE_SEGMENT_SIZE (Segments[SegmentIndex].ImageInfo); + + if (Segments[SegmentIndex].FileSize > SegmentImageSize) { + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + // + // Verify the image segments are aligned. + // + if (!IS_ALIGNED (SegmentImageSize, Context->SegmentAlignment)) { + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + // + // Determine the end of the current image segment. + // + Overflow = BaseOverflowAddU32 ( + SegmentEndImageAddress, + SegmentImageSize, + &SegmentEndImageAddress + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + // + // As it holds that SegmentFileSize <= SegmentImageSize and thus + // SegmentEndFileOffset - Context->SegmentsFileOffset <= SegmentEndImageAddress, + // this cannot overflow (see above). + // + SegmentEndFileOffset += Segments[SegmentIndex].FileSize; + } + // + // As it holds that SegmentEndFileOffset <= 0xFFFFFFF0, this cannot overflow. + // + SegmentEndFileOffset = ALIGN_VALUE ( + SegmentEndFileOffset, + UE_LOAD_TABLE_ALIGNMENT + ); + // + // Verify all image segment data are in bounds of the file buffer. + // + ASSERT (Context->SegmentsFileOffset <= SegmentEndFileOffset); + if (SegmentEndFileOffset > Context->UnsignedFileSize) { + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + + Context->LoadTablesFileOffset = SegmentEndFileOffset; + Context->ImageSize = SegmentEndImageAddress; + + if (Context->XIP) { + Context->ImageSize += Context->SegmentsFileOffset; + } + + return RETURN_SUCCESS; +} + +STATIC +RETURN_STATUS +InternalVerifyLoadTables ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + BOOLEAN Overflow; + CONST UE_LOAD_TABLE *LoadTable; + UINT8 LoadTableIndex; + INT16 PrevLoadTableId; + UINT32 LoadTableFileOffset; + UINT32 LoadTableFileSize; + UINT8 LoadTableId; + UINT32 LoadTableEndFileOffset; + UINT8 NumLoadTables; + + Context->RelocTableSize = 0; + + LoadTableEndFileOffset = Context->LoadTablesFileOffset; + NumLoadTables = Context->NumLoadTables; + PrevLoadTableId = -1; + + if (0 < NumLoadTables) { + LoadTableIndex = 0; + do { + LoadTable = Context->LoadTables + LoadTableIndex; + LoadTableId = UE_LOAD_TABLE_ID (LoadTable->FileInfo); + + if (PrevLoadTableId >= LoadTableId) { + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + + LoadTableFileOffset = LoadTableEndFileOffset; + LoadTableFileSize = UE_LOAD_TABLE_SIZE (LoadTable->FileInfo); + + Overflow = BaseOverflowAddU32 ( + LoadTableFileOffset, + LoadTableFileSize, + &LoadTableEndFileOffset + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + + PrevLoadTableId = LoadTableId; + ++LoadTableIndex; + } while (LoadTableIndex < NumLoadTables); + + if (UE_LOAD_TABLE_ID (Context->LoadTables[0].FileInfo) == UeLoadTableIdReloc) { + if (Context->RelocsStripped) { + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + + Context->RelocTableSize = UE_LOAD_TABLE_SIZE ( + Context->LoadTables[0].FileInfo + ); + } + } + + if (LoadTableEndFileOffset != Context->UnsignedFileSize) { + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + + return RETURN_SUCCESS; +} + +RETURN_STATUS +UeInitializeContextPreHash ( + OUT UE_LOADER_IMAGE_CONTEXT *Context, + IN CONST VOID *FileBuffer, + IN UINT32 FileSize + ) +{ + //BOOLEAN Overflow; + CONST UE_HEADER *UeHdr; + //UINT32 UnsignedFileSize; + + ASSERT (Context != NULL); + ASSERT (FileBuffer != NULL || FileSize == 0); + + if (MIN_SIZE_OF_UE_HEADER > FileSize) { + return RETURN_UNSUPPORTED; + } + + UeHdr = (CONST UE_HEADER *) FileBuffer; + + if (UeHdr->Magic != UE_HEADER_MAGIC) { + return RETURN_UNSUPPORTED; + } + + ZeroMem (Context, sizeof (*Context)); + + /*UnsignedFileSize = UE_HEADER_FILE_SIZE (UeHdr->FileInfo); + + Overflow = BaseOverflowSubU32 ( + FileSize, + UnsignedFileSize, + &Context->CertTableSize + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + }*/ + + Context->FileBuffer = (CONST UINT8 *)UeHdr; + //Context->UnsignedFileSize = UnsignedFileSize; + Context->UnsignedFileSize = FileSize; + + return RETURN_SUCCESS; +} + +BOOLEAN +UeHashImageDefault ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context, + IN OUT VOID *HashContext, + IN UE_LOADER_HASH_UPDATE HashUpdate + ) +{ + BOOLEAN Result; + + ASSERT (Context != NULL); + ASSERT (HashContext != NULL); + ASSERT (HashUpdate != NULL); + + Result = HashUpdate ( + HashContext, + Context->FileBuffer, + Context->UnsignedFileSize + ); + if (!Result) { + DEBUG_RAISE (); + } + + return Result; +} + +STATIC +RETURN_STATUS +InternalInitializeContextLate ( + OUT UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + if (Context->EntryPointAddress > Context->ImageSize) { + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + + return InternalVerifyLoadTables (Context); +} + +RETURN_STATUS +UeInitializeContextPostHash ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + CONST UE_HEADER *UeHdr; + UINT8 LastSegmentIndex; + UINT8 NumLoadTables; + UINT32 LoadTablesFileOffset; + UINT32 HeaderSize; + UINT64 BaseAddress; + RETURN_STATUS Status; + + ASSERT (Context != NULL); + + UeHdr = (CONST UE_HEADER *)Context->FileBuffer; + + Context->FixedAddress = (UeHdr->ImageInfo & UE_HEADER_IMAGE_INFO_FIXED_ADDRESS) != 0; + Context->RelocsStripped = (UeHdr->ImageInfo & UE_HEADER_IMAGE_INFO_RELOCATION_FIXUPS_STRIPPED) != 0; + Context->XIP = (UeHdr->ImageInfo & UE_HEADER_IMAGE_INFO_XIP) != 0; + + Context->Segments = UeHdr->Segments; + Context->SegmentImageInfoIterSize = sizeof (*UeHdr->Segments); + Context->SegmentAlignment = UE_HEADER_SEGMENT_ALIGNMENT (UeHdr->ImageInfo); + + LastSegmentIndex = UE_HEADER_LAST_SEGMENT_INDEX (UeHdr->TableCounts); + NumLoadTables = UE_HEADER_NUM_LOAD_TABLES (UeHdr->TableCounts); + + LoadTablesFileOffset = MIN_SIZE_OF_UE_HEADER + + (UINT32) LastSegmentIndex * sizeof (UE_SEGMENT); + + HeaderSize = LoadTablesFileOffset + (UINT32) NumLoadTables * sizeof (UE_LOAD_TABLE); + ASSERT (HeaderSize <= MAX_SIZE_OF_UE_HEADER); + if (Context->XIP) { + HeaderSize = ALIGN_VALUE (HeaderSize, Context->SegmentAlignment); + } + + if (HeaderSize > Context->UnsignedFileSize) { + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + + ASSERT (IS_ALIGNED (LoadTablesFileOffset, ALIGNOF (UE_LOAD_TABLE))); + + Context->LoadTables = (CONST UE_LOAD_TABLE *)( + (CONST UINT8 *) UeHdr + LoadTablesFileOffset + ); + + Context->SegmentsFileOffset = HeaderSize; + Context->LastSegmentIndex = LastSegmentIndex; + Context->NumLoadTables = NumLoadTables; + + BaseAddress = UE_HEADER_BASE_ADDRESS (UeHdr->ImageInfo); + + if (!IS_ALIGNED (BaseAddress, Context->SegmentAlignment)) { + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + + Context->FileBuffer = (CONST UINT8 *)UeHdr; + + Status = InternalVerifySegments (Context); + if (RETURN_ERROR (Status)) { + return Status; + } + + Context->BaseAddress = BaseAddress; + Context->EntryPointAddress = UeHdr->EntryPointAddress; + + Context->Subsystem = UE_HEADER_SUBSYSTEM (UeHdr->Type); + Context->Machine = UE_HEADER_ARCH (UeHdr->Type); + + return InternalInitializeContextLate (Context); +} + +RETURN_STATUS +UeLoadImage ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context, + OUT VOID *Destination, + IN UINT32 DestinationSize + ) +{ + UINT8 SegmentIndex; + UINT32 SegmentFileOffset; + UINT32 SegmentFileSize; + UINT32 SegmentImageAddress; + UINT32 SegmentImageSize; + UINT32 PrevSegmentDataEnd; + + CONST UE_SEGMENT *Segments; + + ASSERT (Context != NULL); + ASSERT (Destination != NULL); + ASSERT (ADDRESS_IS_ALIGNED (Destination, Context->SegmentAlignment)); + + Context->ImageBuffer = Destination; + + // + // Load all image load tables into the address space. + // + Segments = Context->Segments; + + // + // Start zeroing from the start of the destination buffer. + // + PrevSegmentDataEnd = 0; + + SegmentFileOffset = Context->SegmentsFileOffset; + SegmentImageAddress = 0; + + SegmentIndex = 0; + do { + SegmentFileSize = Segments[SegmentIndex].FileSize; + SegmentImageSize = UE_SEGMENT_SIZE (Segments[SegmentIndex].ImageInfo); + // + // Zero from the end of the previous image segment to the start of this + // image segment. + // + ZeroMem ( + (UINT8 *)Destination + PrevSegmentDataEnd, + SegmentImageAddress - PrevSegmentDataEnd + ); + // + // Load the current Image segment into the address space. + // + ASSERT (SegmentFileSize <= SegmentImageSize); + CopyMem ( + (UINT8 *)Destination + SegmentImageAddress, + Context->FileBuffer + SegmentFileOffset, + SegmentFileSize + ); + PrevSegmentDataEnd = SegmentImageAddress + SegmentFileSize; + + SegmentFileOffset += SegmentFileSize; + SegmentImageAddress += SegmentImageSize; + ++SegmentIndex; + } while (SegmentIndex <= Context->LastSegmentIndex); + // + // Zero the trailing data after the last image segment. + // + ZeroMem ( + (UINT8 *)Destination + PrevSegmentDataEnd, + DestinationSize - PrevSegmentDataEnd + ); + + return RETURN_SUCCESS; +} + +RETURN_STATUS +UeLoaderGetRuntimeContextSize ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *Size + ) +{ + ASSERT (Context != NULL); + ASSERT (Size != NULL); + + *Size = sizeof (UE_LOADER_RUNTIME_CONTEXT); + return RETURN_SUCCESS; +} + +/** + Apply an image relocation fixup. + + Only a subset of the PE/COFF relocation fixup types are permited. + The relocation fixup target must be in bounds, aligned, and must not overlap + with the Relocation Directory. + + @param[in] Context The context describing the image. Must have been + loaded by PeCoffLoadImage(). + @param[in] RelocIndex The index of the relocation fixup to apply. + @param[in] Adjust The delta to add to the addresses. + + @retval RETURN_SUCCESS The relocation fixup has been applied successfully. + @retval other The relocation fixup could not be applied successfully. +**/ +STATIC +RETURN_STATUS +InternalApplyRelocation ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN UINT8 Machine, + IN UINT16 RelocType, + IN UINT32 *RelocTarget, + IN UINT64 Adjust, + IN OUT UINT64 *FixupData, + IN BOOLEAN IsRuntime + ) +{ + BOOLEAN Overflow; + + UINT32 RemFixupTargetSize; + + UINT32 FixupTarget; + VOID *Fixup; + UINT8 FixupSize; + UE_RELOC_FIXUP_VALUE FixupValue; + + ASSERT (FixupData != NULL); + + FixupTarget = *RelocTarget; + // + // Verify the relocation fixup target address is in bounds of the image buffer. + // + Overflow = BaseOverflowSubU32 (ImageSize, FixupTarget, &RemFixupTargetSize); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + Fixup = (UINT8 *)Image + FixupTarget; + // + // Apply the relocation fixup per type. + // + if (RelocType < UeRelocGenericMax) { + if (RelocType == UeReloc32) { + FixupSize = sizeof (UINT32); + // + // Verify the relocation fixup target is in bounds of the image buffer. + // + if (FixupSize > RemFixupTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Relocate the target instruction. + // + FixupValue.Value32 = ReadUnaligned32 (Fixup); + // + // If the Image relocation target value mismatches, skip or abort. + // + if (IsRuntime && (FixupValue.Value32 != (UINT32)*FixupData)) { + if (PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) { + return RETURN_SUCCESS; + } + + return RETURN_VOLUME_CORRUPTED; + } + + FixupValue.Value32 += (UINT32) Adjust; + WriteUnaligned32 (Fixup, FixupValue.Value32); + } else if (RelocType == UeReloc64) { + FixupSize = sizeof (UINT64); + // + // Verify the image relocation fixup target is in bounds of the image + // buffer. + // + if (FixupSize > RemFixupTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Relocate target the instruction. + // + FixupValue.Value64 = ReadUnaligned64 (Fixup); + // + // If the Image relocation target value mismatches, skip or abort. + // + if (IsRuntime && (FixupValue.Value64 != *FixupData)) { + if (PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) { + return RETURN_SUCCESS; + } + + return RETURN_VOLUME_CORRUPTED; + } + + FixupValue.Value64 += Adjust; + WriteUnaligned64 (Fixup, FixupValue.Value64); + } else if (RelocType == UeReloc32NoMeta) { + FixupSize = sizeof (UINT32); + // + // Verify the relocation fixup target is in bounds of the image buffer. + // + if (FixupSize > RemFixupTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Relocate the target instruction. + // + FixupValue.Value32 = ReadUnaligned32 (Fixup); + // + // If the Image relocation target value mismatches, skip or abort. + // + if (IsRuntime && (FixupValue.Value32 != (UINT32)*FixupData)) { + if (PcdGetBool (PcdImageLoaderRtRelocAllowTargetMismatch)) { + return RETURN_SUCCESS; + } + + return RETURN_VOLUME_CORRUPTED; + } + + FixupValue.Value32 += (UINT32) Adjust; + WriteUnaligned32 (Fixup, FixupValue.Value32); + + if (!IsRuntime) { + *FixupData = FixupValue.Value32; + } + } else { + // + // The image relocation fixup type is unknown, disallow the image. + // + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + } else { +#if 0 + if (Machine == UeMachineArmThumbMixed) { + switch (RelocType) { + // TODO: MOVW + case (UeMachineArmThumbMixed << 4U) | UeRelocArmMovt: + { + // + // Verify the relocation fixup target is in bounds of the image buffer. + // + if (sizeof (UINT64) > RemFixupTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Verify the relocation fixup target is sufficiently aligned. + // The ARM Thumb instruction pait must start on a 16-bit boundary. + // + if (!IS_ALIGNED (RelocTarget, ALIGNOF (UINT16))) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Relocate the target instruction. + // + PeCoffThumbMovwMovtImmediateFixup (Fixup, Adjust); + + break; + } + + default: + { + // + // The image relocation fixup type is unknown, disallow the image. + // + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + } + } +#endif + // + // The image relocation fixup type is unknown, disallow the image. + // + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + + *RelocTarget = FixupTarget + FixupSize; + + return RETURN_SUCCESS; +} + +STATIC +RETURN_STATUS +UnchainReloc ( + IN OUT UE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, + IN CONST UINT8 *MetaSource OPTIONAL, + IN UINT32 MetaSize, + IN BOOLEAN IsRuntime, + IN UINT16 RelocOffset, + IN UINT64 *FixupData + ) +{ + UINT32 OldSize; + UINT16 FixupHdr; + UINT32 FixupIndex; + UINT8 Addend; + + if ((RuntimeContext != NULL) && !IsRuntime) { + if (MetaSource == NULL) { + FixupIndex = RuntimeContext->UnchainedRelocsSize - sizeof (UINT16); + + FixupHdr = *(UINT16 *)&RuntimeContext->UnchainedRelocs[FixupIndex]; + FixupHdr = (RelocOffset << 4U) | UE_RELOC_FIXUP_TYPE(FixupHdr); + + *(UINT16 *)&RuntimeContext->UnchainedRelocs[FixupIndex] = FixupHdr; + + Addend = ALIGN_VALUE_ADDEND(RuntimeContext->UnchainedRelocsSize, ALIGNOF(UE_FIXUP_ROOT)); + if ((RelocOffset == UE_HEAD_FIXUP_OFFSET_END) && (Addend != 0)) { + OldSize = RuntimeContext->UnchainedRelocsSize; + RuntimeContext->UnchainedRelocs = ReallocateRuntimePool ( + OldSize, + OldSize + Addend, + RuntimeContext->UnchainedRelocs + ); + if (RuntimeContext->UnchainedRelocs == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + + ZeroMem (RuntimeContext->UnchainedRelocs + OldSize, Addend); + RuntimeContext->UnchainedRelocsSize += Addend; + } + + return RETURN_SUCCESS; + } + + OldSize = RuntimeContext->UnchainedRelocsSize; + RuntimeContext->UnchainedRelocs = ReallocateRuntimePool ( + OldSize, + OldSize + MetaSize, + RuntimeContext->UnchainedRelocs + ); + if (RuntimeContext->UnchainedRelocs == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + + CopyMem (RuntimeContext->UnchainedRelocs + OldSize, MetaSource, MetaSize); + + RuntimeContext->UnchainedRelocsSize += MetaSize; + + if (FixupData != NULL) { + OldSize = RuntimeContext->FixupSize; + RuntimeContext->FixupData = ReallocateRuntimePool ( + OldSize, + OldSize + sizeof (*FixupData), + RuntimeContext->FixupData + ); + if (RuntimeContext->FixupData == NULL) { + return RETURN_OUT_OF_RESOURCES; + } + + CopyMem ((UINT8 *)RuntimeContext->FixupData + OldSize, FixupData, sizeof (*FixupData)); + + RuntimeContext->FixupSize += sizeof (*FixupData); + } + } + + return RETURN_SUCCESS; +} + +STATIC +RETURN_STATUS +InternalProcessRelocChain ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN UINT8 Machine, + IN UINT16 FirstRelocType, + IN UINT32 *ChainStart, + IN UINT64 Adjust, + IN OUT UE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL + ) +{ + RETURN_STATUS Status; + UINT16 RelocType; + UINT16 RelocOffset; + UINT32 RelocTarget; + + BOOLEAN Overflow; + UINT32 RemFixupTargetSize; + + UINT8 *Fixup; + UE_RELOC_FIXUP_VALUE FixupInfo; + UINT8 FixupSize; + UE_RELOC_FIXUP_VALUE FixupValue; + UINT16 FixupHdr; + UINT64 FixupData; + + RelocType = FirstRelocType; + RelocTarget = *ChainStart; + + while (TRUE) { + Overflow = BaseOverflowSubU32 (ImageSize, RelocTarget, &RemFixupTargetSize); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + Fixup = (UINT8 *)Image + RelocTarget; + + if (RelocType < UeRelocGenericMax) { + if (RelocType == UeReloc64) { + FixupSize = sizeof (UINT64); + // + // Verify the relocation fixup target is in bounds of the image memory. + // + if (FixupSize > RemFixupTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Relocate the target instruction. + // + FixupInfo.Value64 = ReadUnaligned64 ((CONST VOID *)Fixup); + FixupValue.Value64 = UE_CHAINED_RELOC_FIXUP_VALUE (FixupInfo.Value64); + FixupValue.Value64 += Adjust; + WriteUnaligned64 ((VOID *)Fixup, FixupValue.Value64); + + FixupData = FixupValue.Value64; + } else if (RelocType == UeReloc32) { + FixupSize = sizeof (UINT32); + // + // Verify the image relocation fixup target is in bounds of the image + // buffer. + // + if (FixupSize > RemFixupTargetSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + // + // Relocate the target instruction. + // + FixupInfo.Value32 = ReadUnaligned32 ((CONST VOID *)Fixup); + FixupValue.Value32 = UE_CHAINED_RELOC_FIXUP_VALUE_32 (FixupInfo.Value32); + FixupValue.Value32 += (UINT32) Adjust; + WriteUnaligned32 ((VOID *)Fixup, FixupValue.Value32); + + FixupData = FixupValue.Value32; + // + // Imitate the common header of UE chained relocation fixups, + // as for 32-bit files all relocs have the same type. + // + FixupInfo.Value32 = FixupInfo.Value32 << 4U; + FixupInfo.Value32 |= UeReloc32; + } else { + // + // The image relocation fixup type is unknown, disallow the image. + // + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + } else { + // + // The image relocation fixup type is unknown, disallow the image. + // + DEBUG_RAISE (); + return RETURN_UNSUPPORTED; + } + + RelocTarget += FixupSize; + + RelocOffset = UE_CHAINED_RELOC_FIXUP_NEXT_OFFSET (FixupInfo.Value32); + FixupHdr = (RelocOffset << 4U) | RelocType; + + Status = UnchainReloc ( + RuntimeContext, + (CONST UINT8 *)&FixupHdr, + sizeof (FixupHdr), + FALSE, + 0, + &FixupData + ); + if (RETURN_ERROR (Status)) { + return Status; + } + + if (RelocOffset == UE_CHAINED_RELOC_FIXUP_OFFSET_END) { + *ChainStart = RelocTarget; + return RETURN_SUCCESS; + } + // + // It holds that ImageSize mod 4 KiB = 0, thus ImageSize <= 0xFFFFF000. + // Furthermore, it holds that RelocTarget <= ImageSize. + // Finally, it holds that RelocOffset <= 0xFFE. + // It follows that this cannot overflow. + // + RelocTarget += RelocOffset; + ASSERT (RelocOffset <= RelocTarget); + + RelocType = UE_CHAINED_RELOC_FIXUP_NEXT_TYPE (FixupInfo.Value32); + } +} + +STATIC +RETURN_STATUS +InternaRelocateImage ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN UINT8 Machine, + IN UINT64 OldBaseAddress, + IN CONST VOID *RelocTable, + IN UINT32 RelocTableSize, + IN BOOLEAN Chaining, + IN UINT64 BaseAddress, + OUT UE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, + IN BOOLEAN IsRuntime + ) +{ + RETURN_STATUS Status; + BOOLEAN Overflow; + + UINT64 Adjust; + + UINT32 RootOffsetMax; + UINT32 EntryOffsetMax; + + UINT32 TableOffset; + CONST UE_FIXUP_ROOT *RelocRoot; + + UINT16 FixupInfo; + UINT16 RelocType; + UINT16 RelocOffset; + UINT32 RelocTarget; + + UINT32 OldTableOffset; + UINT64 FixupData; + UINT64 *FixupPointer; + + ASSERT (Image != NULL); + ASSERT (RelocTable != NULL || RelocTableSize == 0); + // + // Verify the Relocation Directory is not empty. + // + if (RelocTableSize == 0) { + return RETURN_SUCCESS; + } + // + // Calculate the image displacement from its prefered load address. + // + Adjust = BaseAddress - OldBaseAddress; + // + // FIXME: RT driver check is removed in the hope we can force no relocs in + // writable segments. + // + // Skip explicit Relocation when the image is already loaded at its base + // address. + // + if (Adjust == 0 && !Chaining) { + return RETURN_SUCCESS; + } + + RelocTarget = 0; + + if (IsRuntime) { + FixupPointer = RuntimeContext->FixupData; + } + + STATIC_ASSERT ( + MIN_SIZE_OF_UE_FIXUP_ROOT <= UE_LOAD_TABLE_ALIGNMENT, + "The following arithmetic may overflow." + ); + + RootOffsetMax = RelocTableSize - MIN_SIZE_OF_UE_FIXUP_ROOT; + EntryOffsetMax = RelocTableSize - sizeof (*RelocRoot->Heads); + // + // Apply all relocation fixups of the Image. + // + for (TableOffset = 0; TableOffset <= RootOffsetMax;) { + RelocRoot = (CONST UE_FIXUP_ROOT *)( + (CONST UINT8 *)RelocTable + TableOffset + ); + TableOffset += sizeof (*RelocRoot); + + Overflow = BaseOverflowAddU32 ( + RelocTarget, + RelocRoot->FirstOffset, + &RelocTarget + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + Status = UnchainReloc ( + RuntimeContext, + (CONST UINT8 *)RelocRoot, + sizeof (*RelocRoot), + IsRuntime, + 0, + NULL + ); + if (RETURN_ERROR (Status)) { + return Status; + } + // + // Process all relocation fixups of the current root. + // + while (TRUE) { + FixupInfo = *(CONST UINT16 *)((CONST UINT8 *)RelocTable + TableOffset); + // + // This cannot overflow due to the upper bound of TableOffset. + // + TableOffset += sizeof (*RelocRoot->Heads); + // + // Apply the image relocation fixup. + // + RelocType = UE_RELOC_FIXUP_TYPE (FixupInfo); + + if (Chaining && !IsRuntime && (RelocType != UeReloc32NoMeta)) { + Status = InternalProcessRelocChain ( + Image, + ImageSize, + Machine, + RelocType, + &RelocTarget, + Adjust, + RuntimeContext + ); + } else { + Status = InternalApplyRelocation ( + Image, + ImageSize, + Machine, + RelocType, + &RelocTarget, + Adjust, + IsRuntime ? FixupPointer : &FixupData, + IsRuntime + ); + + if (RETURN_ERROR (Status)) { + return Status; + } + + Status = UnchainReloc ( + RuntimeContext, + (CONST UINT8 *)&FixupInfo, + sizeof (FixupInfo), + IsRuntime, + 0, + &FixupData + ); + + if (IsRuntime) { + ++FixupPointer; + } + } + + if (RETURN_ERROR (Status)) { + return Status; + } + + RelocOffset = UE_RELOC_FIXUP_OFFSET (FixupInfo); + + Status = UnchainReloc ( + RuntimeContext, + NULL, + 0, + IsRuntime, + RelocOffset, + NULL + ); + if (RETURN_ERROR (Status)) { + return Status; + } + + if (RelocOffset == UE_HEAD_FIXUP_OFFSET_END) { + break; + } + // + // It holds that ImageSize mod 4 KiB = 0, thus ImageSize <= 0xFFFFF000. + // Furthermore, it holds that RelocTarget <= ImageSize. + // Finally, it holds that RelocOffset <= 0xFFE. + // It follows that this cannot overflow. + // + RelocTarget += RelocOffset; + ASSERT (RelocOffset <= RelocTarget); + + if (TableOffset > EntryOffsetMax) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + } + // + // This cannot overflow due to the TableOffset upper bounds and the + // alignment guarantee of RelocTableSize. + // + OldTableOffset = TableOffset; + TableOffset = ALIGN_VALUE (TableOffset, ALIGNOF (UE_FIXUP_ROOT)); + ASSERT (OldTableOffset <= TableOffset); + } + + STATIC_ASSERT ( + sizeof (UE_FIXUP_ROOT) <= UE_LOAD_TABLE_ALIGNMENT, + "The following ASSERT may not hold." + ); + + return RETURN_SUCCESS; +} + +RETURN_STATUS +UeRelocateImage ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context, + IN UINT64 BaseAddress, + OUT UE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize + ) +{ + CONST UE_HEADER *UeHdr; + BOOLEAN Chaining; + CONST VOID *RelocTable; + + ASSERT (Context != NULL); + ASSERT (IS_ALIGNED (Context->LoadTablesFileOffset, UE_LOAD_TABLE_ALIGNMENT)); + ASSERT (IS_ALIGNED (Context->RelocTableSize, UE_LOAD_TABLE_ALIGNMENT)); + ASSERT (IS_ALIGNED (BaseAddress, Context->SegmentAlignment)); + ASSERT (RuntimeContext != NULL || RuntimeContextSize == 0); + ASSERT (RuntimeContextSize == 0 || sizeof (*RuntimeContext) <= RuntimeContextSize); + + RelocTable = Context->FileBuffer + Context->LoadTablesFileOffset; + + UeHdr = (CONST UE_HEADER *)Context->FileBuffer; + Chaining = (UeHdr->ImageInfo & UE_HEADER_IMAGE_INFO_CHAINED_FIXUPS) != 0; + + if (RuntimeContext != NULL) { + RuntimeContext->Machine = Context->Machine; + } + + if (Context->XIP) { + Context->EntryPointAddress -= Context->SegmentsFileOffset; + } + + return InternaRelocateImage ( + Context->ImageBuffer, + Context->ImageSize, + Context->Machine, + Context->XIP ? (Context->BaseAddress + Context->SegmentsFileOffset) : Context->BaseAddress, + RelocTable, + Context->RelocTableSize, + Chaining, + BaseAddress, + RuntimeContext, + FALSE + ); +} + +RETURN_STATUS +UeRelocateImageForRuntime ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN CONST UE_LOADER_RUNTIME_CONTEXT *RuntimeContext, + IN UINT64 BaseAddress + ) +{ + ASSERT (RuntimeContext != NULL); + + return InternaRelocateImage ( + Image, + ImageSize, + RuntimeContext->Machine, + (UINTN)Image, + RuntimeContext->UnchainedRelocs, + RuntimeContext->UnchainedRelocsSize, + FALSE, + BaseAddress, + (UE_LOADER_RUNTIME_CONTEXT *)RuntimeContext, + TRUE + ); +} + +STATIC +RETURN_STATUS +InternalGetDebugTable ( + IN CONST UE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST UE_DEBUG_TABLE **DebugTable + ) +{ + BOOLEAN Overflow; + CONST UE_LOAD_TABLE *LoadTable; + UINT8 LoadTableIndex; + UINT8 NumLoadTables; + UINT32 LoadTableFileOffset; + UINT32 LoadTableFileSize; + CONST UE_DEBUG_TABLE *DbgTable; + CONST UE_SEGMENT *Segments; + UINT16 NumSegments; + UINT32 LoadTableExtraSize; + UINT32 MinLoadTableExtraSize; + + ASSERT (Context != NULL); + ASSERT (DebugTable != NULL); + + LoadTableFileOffset = Context->LoadTablesFileOffset; + NumLoadTables = Context->NumLoadTables; + + for (LoadTableIndex = 0; LoadTableIndex < NumLoadTables; ++LoadTableIndex) { + LoadTable = Context->LoadTables + LoadTableIndex; + if (UE_LOAD_TABLE_ID (LoadTable->FileInfo) != UeLoadTableIdDebug) { + LoadTableFileOffset += UE_LOAD_TABLE_SIZE (LoadTable->FileInfo); + continue; + } + + ASSERT (IS_ALIGNED (LoadTableFileOffset, ALIGNOF (UE_DEBUG_TABLE))); + + LoadTableFileSize = UE_LOAD_TABLE_SIZE (LoadTable->FileInfo); + + Overflow = BaseOverflowSubU32 ( + LoadTableFileSize, + MIN_SIZE_OF_UE_DEBUG_TABLE, + &LoadTableExtraSize + ); + if (Overflow) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + DbgTable = (CONST UE_DEBUG_TABLE *)(CONST VOID *)( + Context->FileBuffer + LoadTableFileOffset + ); + + NumSegments = UeGetSegments (Context, &Segments); + + MinLoadTableExtraSize = DbgTable->SymbolsPathLength + + (UINT32)NumSegments * sizeof (UE_SEGMENT_NAME); + if (MinLoadTableExtraSize > LoadTableExtraSize) { + DEBUG_RAISE (); + return RETURN_VOLUME_CORRUPTED; + } + + *DebugTable = DbgTable; + return RETURN_SUCCESS; + } + + return RETURN_NOT_FOUND; +} + +RETURN_STATUS +UeGetSymbolsPath ( + IN CONST UE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST CHAR8 **SymbolsPath, + OUT UINT32 *SymbolsPathSize + ) +{ + RETURN_STATUS Status; + CONST UE_DEBUG_TABLE *DebugTable; + + ASSERT (Context != NULL); + ASSERT (SymbolsPath != NULL); + ASSERT (SymbolsPathSize != NULL); + + Status = InternalGetDebugTable (Context, &DebugTable); + if (RETURN_ERROR (Status)) { + return Status; + } + + if (DebugTable->SymbolsPathLength == 0) { + return RETURN_NOT_FOUND; + } + + if (DebugTable->SymbolsPath[DebugTable->SymbolsPathLength] != 0) { + return RETURN_VOLUME_CORRUPTED; + } + + *SymbolsPath = (CONST CHAR8 *)DebugTable->SymbolsPath; + *SymbolsPathSize = (UINT32)DebugTable->SymbolsPathLength + 1; + return RETURN_SUCCESS; +} + +UINTN +UeLoaderGetImageDebugAddress ( + IN CONST UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + RETURN_STATUS Status; + CONST UE_DEBUG_TABLE *DebugTable; + UINT8 SymOffsetFactor; + UINT32 SymOffsetSubtrahend; + + ASSERT (Context != NULL); + + SymOffsetSubtrahend = 0; + + Status = InternalGetDebugTable (Context, &DebugTable); + if (!RETURN_ERROR (Status)) { + SymOffsetFactor = UE_DEBUG_TABLE_IMAGE_INFO_SYM_SUBTRAHEND_FACTOR ( + DebugTable->ImageInfo + ); + SymOffsetSubtrahend = (UINT32)SymOffsetFactor * Context->SegmentAlignment; + } + + return UeLoaderGetImageAddress (Context) - SymOffsetSubtrahend; +} + +RETURN_STATUS +UeGetSegmentNames ( + IN CONST UE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST UE_SEGMENT_NAME **SegmentNames + ) +{ + RETURN_STATUS Status; + CONST UE_DEBUG_TABLE *DebugTable; + + ASSERT (Context != NULL); + ASSERT (SegmentNames != NULL); + + Status = InternalGetDebugTable (Context, &DebugTable); + if (RETURN_ERROR (Status)) { + return Status; + } + + *SegmentNames = UE_DEBUG_TABLE_SEGMENT_NAMES (DebugTable); + + return RETURN_SUCCESS; +} + +UINT32 +UeGetEntryPointAddress ( + IN CONST UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->EntryPointAddress; +} + +UINT16 +UeGetMachine ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->Machine; +} + +UINT16 +UeGetSubsystem ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->Subsystem; +} + +UINT32 +UeGetSegmentAlignment ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->SegmentAlignment; +} + +UINT32 +UeGetImageSize ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->ImageSize; +} + +UINT64 +UeGetBaseAddress ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->BaseAddress; +} + +BOOLEAN +UeGetRelocsStripped ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->RelocsStripped; +} + +BOOLEAN +UeGetFixedAddress( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return Context->FixedAddress; +} + +UINTN +UeLoaderGetImageAddress ( + IN CONST UE_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + return (UINTN) Context->ImageBuffer; +} + +UINT16 +UeGetSegments ( + IN CONST UE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST UE_SEGMENT **Segments + ) +{ + ASSERT (Context != NULL); + ASSERT (Segments != NULL); + + *Segments = Context->Segments; + return (UINT16)Context->LastSegmentIndex + 1; +} + +UINT16 +UeGetSegmentImageInfos ( + IN OUT UE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST UINT32 **SegmentImageInfos, + OUT UINT8 *SegmentImageInfoIterSize + ) +{ + ASSERT (Context != NULL); + ASSERT (SegmentImageInfos != NULL); + ASSERT (SegmentImageInfoIterSize != NULL); + + ASSERT (IS_ALIGNED (Context->SegmentImageInfoIterSize, ALIGNOF (UINT32))); + + *SegmentImageInfos = Context->Segments; + *SegmentImageInfoIterSize = Context->SegmentImageInfoIterSize; + return (UINT16)Context->LastSegmentIndex + 1; +} diff --git a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageAllLib.inf b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageAllLib.inf index 6ad64cb959..f0640bcd73 100644 --- a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageAllLib.inf +++ b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageAllLib.inf @@ -18,6 +18,7 @@ [Sources] CommonSupport.c ExecutionSupport.c + UeSupport.c PeSupport.c UefiImageLib.c @@ -32,6 +33,7 @@ DebugLib MemoryAllocationLib PeCoffLib2 + UeImageLib UefiImageExtraActionLib [FixedPcd] diff --git a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf index cbdcc58644..f6f1801c6a 100644 --- a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf +++ b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf @@ -18,6 +18,7 @@ [Sources] CommonSupport.c ExecutionSupport.c + UeSupport.c PeSupport.c UefiImageLib.c @@ -32,6 +33,7 @@ DebugLib MemoryAllocationLib PeCoffLib2 + UeImageLib UefiImageExtraActionLib [FixedPcd] diff --git a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf index 3c8f23e895..9ae93ed4aa 100644 --- a/MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf +++ b/MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf @@ -18,6 +18,7 @@ [Sources] CommonSupport.c ExecutionSupport.c + UeSupport.c PeSupport.c UefiImageLib.c @@ -32,14 +33,14 @@ DebugLib MemoryAllocationLib PeCoffLib2 + UeImageLib UefiImageExtraActionLib [FixedPcd] gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAlignmentPolicy gEfiMdePkgTokenSpaceGuid.PcdImageLoaderLoadHeader - gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask - + gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportNonFv gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv diff --git a/MdePkg/Library/BaseUefiImageLib/CommonSupport.c b/MdePkg/Library/BaseUefiImageLib/CommonSupport.c index 90124bc7cd..9355719ec2 100644 --- a/MdePkg/Library/BaseUefiImageLib/CommonSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/CommonSupport.c @@ -92,11 +92,7 @@ UefiImageGetModuleNameFromSymbolsPath ( // the debug symbols for the Image. // StartIndex = 0; - for ( - Index = 0; - Index < SymbolsPathSize && SymbolsPath[Index] != '\0'; - ++Index - ) { + for (Index = 0; Index < SymbolsPathSize - 1; ++Index) { if (SymbolsPath[Index] == '\\' || SymbolsPath[Index] == '/') { StartIndex = Index + 1; } @@ -107,7 +103,7 @@ UefiImageGetModuleNameFromSymbolsPath ( // for ( Index = 0; - Index < MIN (ModuleNameSize, SymbolsPathSize); + Index < MIN (ModuleNameSize, SymbolsPathSize) - 1; ++Index ) { ModuleName[Index] = SymbolsPath[Index + StartIndex]; @@ -115,7 +111,7 @@ UefiImageGetModuleNameFromSymbolsPath ( ModuleName[Index] = '.'; } if (ModuleName[Index] == '.') { - if (Index > ModuleNameSize - 3) { + if (Index >= ModuleNameSize - 4) { break; } @@ -139,7 +135,7 @@ UefiImageDebugPrintImageRecord ( IN CONST UEFI_IMAGE_RECORD *ImageRecord ) { - UINT16 SegmentIndex; + UINT32 SegmentIndex; UINTN SegmentAddress; ASSERT (ImageRecord != NULL); diff --git a/MdePkg/Library/BaseUefiImageLib/UeSupport.c b/MdePkg/Library/BaseUefiImageLib/UeSupport.c new file mode 100644 index 0000000000..3e7c35d1ce --- /dev/null +++ b/MdePkg/Library/BaseUefiImageLib/UeSupport.c @@ -0,0 +1,560 @@ +/** @file + UEFI Image Loader library implementation for UE Images. + + Copyright (c) 2023, Marvin Häuser. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "UeSupport.h" + +STATIC CONST UINT16 mPeMachines[] = { + IMAGE_FILE_MACHINE_I386, + IMAGE_FILE_MACHINE_X64, + IMAGE_FILE_MACHINE_ARMTHUMB_MIXED, + IMAGE_FILE_MACHINE_ARM64, + IMAGE_FILE_MACHINE_RISCV32, + IMAGE_FILE_MACHINE_RISCV64, + IMAGE_FILE_MACHINE_RISCV128 +}; + +RETURN_STATUS +UefiImageInitializeContextPreHashUe ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN CONST VOID *FileBuffer, + IN UINT32 FileSize + ) +{ + return UeInitializeContextPreHash (&Context->Ctx.Ue, FileBuffer, FileSize); +} + +RETURN_STATUS +UefiImageInitializeContextPostHashUe ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return UeInitializeContextPostHash (&Context->Ctx.Ue); +} + +BOOLEAN +UefiImageHashImageDefaultUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN OUT VOID *HashContext, + IN UEFI_IMAGE_LOADER_HASH_UPDATE HashUpdate + ) +{ + return UeHashImageDefault (&Context->Ctx.Ue, HashContext, HashUpdate); +} + +RETURN_STATUS +UefiImageLoadImageUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT VOID *Destination, + IN UINT32 DestinationSize + ) +{ + return UeLoadImage (&Context->Ctx.Ue, Destination, DestinationSize); +} + +// +// In-place semantics are currently unsupported. +// + +// LCOV_EXCL_START +BOOLEAN +UefiImageImageIsInplaceUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return FALSE; +} + +RETURN_STATUS +UefiImageLoadImageInplaceUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + ASSERT (Context != NULL); + + if (Context->Ctx.Ue.XIP) { + Context->Ctx.Ue.ImageBuffer = (UINT8 *) Context->Ctx.Ue.FileBuffer; + + return RETURN_SUCCESS; + } + + return RETURN_UNSUPPORTED; +} + +RETURN_STATUS +UefiImageRelocateImageInplaceUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return RETURN_UNSUPPORTED; +} +// LCOV_EXCL_STOP + +RETURN_STATUS +UefiImageLoaderGetRuntimeContextSizeUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *Size + ) +{ + return UeLoaderGetRuntimeContextSize (&Context->Ctx.Ue, Size); +} + +RETURN_STATUS +UefiImageRelocateImageUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINT64 BaseAddress, + OUT VOID *RuntimeContext OPTIONAL, + IN UINT32 RuntimeContextSize + ) +{ + return UeRelocateImage ( + &Context->Ctx.Ue, + BaseAddress, + (UE_LOADER_RUNTIME_CONTEXT *)RuntimeContext, + RuntimeContextSize + ); +} + +RETURN_STATUS +UefiImageRuntimeRelocateImageUe ( + IN OUT VOID *Image, + IN UINT32 ImageSize, + IN UINT64 BaseAddress, + IN CONST VOID *RuntimeContext + ) +{ + return UeRelocateImageForRuntime ( + Image, + ImageSize, + (UE_LOADER_RUNTIME_CONTEXT *)RuntimeContext, + BaseAddress + ); +} + +VOID +UefiImageDiscardSegmentsUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + // + // Anything discardable is not loaded in the first place. + // +} + +RETURN_STATUS +UefiImageGetSymbolsPathUe ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST CHAR8 **SymbolsPath, + OUT UINT32 *SymbolsPathSize + ) +{ + return UeGetSymbolsPath (&Context->Ctx.Ue, SymbolsPath, SymbolsPathSize); +} + +// +// UE does not support embedded certificates (yet). +// + +// LCOV_EXCL_START +RETURN_STATUS +UefiImageGetFirstCertificateUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT CONST WIN_CERTIFICATE **Certificate + ) +{ + return RETURN_UNSUPPORTED; +} + +RETURN_STATUS +UefiImageGetNextCertificateUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN OUT CONST WIN_CERTIFICATE **Certificate + ) +{ + return RETURN_UNSUPPORTED; +} + +RETURN_STATUS +UefiImageGetHiiDataRvaUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT32 *HiiRva, + OUT UINT32 *HiiSize + ) +{ + // + // UE does not support legacy HII. + // + return RETURN_NOT_FOUND; +} +// LCOV_EXCL_STOP + +UINT32 +UefiImageGetEntryPointAddressUe ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return UeGetEntryPointAddress (&Context->Ctx.Ue); +} + +UINT16 +UefiImageGetMachineUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UINT16 UeMachine; + + UeMachine = UeGetMachine (&Context->Ctx.Ue); + if (UeMachine >= ARRAY_SIZE (mPeMachines)) { + DEBUG_RAISE (); + return 0xFFFF; + } + + return mPeMachines[UeMachine]; +} + +UINT16 +UefiImageGetSubsystemUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return UeGetSubsystem (&Context->Ctx.Ue) + 10; +} + +UINT32 +UefiImageGetSegmentAlignmentUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return UeGetSegmentAlignment (&Context->Ctx.Ue); +} + +UINT32 +UefiImageGetImageSizeUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return UeGetImageSize (&Context->Ctx.Ue); +} + +UINT64 +UefiImageGetBaseAddressUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return UeGetBaseAddress (&Context->Ctx.Ue); +} + +BOOLEAN +UefiImageGetRelocsStrippedUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return UeGetRelocsStripped (&Context->Ctx.Ue); +} + +UINTN +UefiImageLoaderGetImageAddressUe ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return UeLoaderGetImageAddress (&Context->Ctx.Ue); +} + +UINTN +UefiImageLoaderGetDebugAddressUe ( + IN CONST UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + return UeLoaderGetImageDebugAddress (&Context->Ctx.Ue); +} + +STATIC +UINT32 +InternalPermissionsToAttributes ( + IN UINT8 Permissions + ) +{ + switch (Permissions) { + case UeSegmentPermX: + { + return EFI_MEMORY_RP | EFI_MEMORY_RO; + } + + case UeSegmentPermRX: + { + return EFI_MEMORY_RO; + } + + case UeSegmentPermRW: + { + return EFI_MEMORY_XP; + } + + case UeSegmentPermR: + default: + { + ASSERT (Permissions == UeSegmentPermR); + return EFI_MEMORY_XP | EFI_MEMORY_RO; + } + } +} + +UEFI_IMAGE_RECORD * +UefiImageLoaderGetImageRecordUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + UEFI_IMAGE_RECORD *ImageRecord; + UINTN ImageAddress; + UINT32 ImageSize; + UINT32 ImageSizeRecord; + UINT32 NumRecordSegments; + UEFI_IMAGE_RECORD_SEGMENT *RecordSegment; + UINT16 NumSegments; + UINT8 SegmentIterSize; + CONST UINT32 *SegmentImageInfos; + CONST UINT8 *SegmentImageInfoPtr; + UINT32 SegmentImageInfo; + UINT32 SegmentSize; + UINT8 SegmentPermissions; + UINT32 RangeSize; + UINT8 Permissions; + + ASSERT (Context != NULL); + + NumSegments = UeGetSegmentImageInfos ( + &Context->Ctx.Ue, + &SegmentImageInfos, + &SegmentIterSize + ); + + ImageRecord = AllocatePool ( + sizeof (*ImageRecord) + + NumSegments * sizeof (*ImageRecord->Segments) + ); + if (ImageRecord == NULL) { + return NULL; + } + + ImageRecord->Signature = UEFI_IMAGE_RECORD_SIGNATURE; + InitializeListHead (&ImageRecord->Link); + + SegmentImageInfo = *SegmentImageInfos; + + RangeSize = UE_SEGMENT_SIZE (SegmentImageInfo); + Permissions = UE_SEGMENT_PERMISSIONS (SegmentImageInfo); + + ImageSizeRecord = RangeSize; + NumRecordSegments = 0; + + STATIC_ASSERT ( + OFFSET_OF (UE_SEGMENT, ImageInfo) == 0 && + OFFSET_OF (UE_SEGMENT, ImageInfo) == OFFSET_OF (UE_SEGMENT_XIP, ImageInfo), + "Below's logic assumes the given layout." + ); + + for ( + SegmentImageInfoPtr = (CONST UINT8 *) SegmentImageInfos + SegmentIterSize; + SegmentImageInfoPtr < (CONST UINT8 *) SegmentImageInfos + (UINT32) SegmentIterSize * NumSegments; + ImageSizeRecord += SegmentSize, + SegmentImageInfoPtr += SegmentIterSize + ) { + SegmentImageInfo = *(CONST UINT32 *) SegmentImageInfoPtr; + + SegmentSize = UE_SEGMENT_SIZE (SegmentImageInfo); + SegmentPermissions = UE_SEGMENT_PERMISSIONS (SegmentImageInfo); + // + // Skip Image segments with the same memory permissions as the current range + // as they can be merged. + // + if (SegmentPermissions == Permissions) { + RangeSize += SegmentSize; + continue; + } + // + // Create an Image record LoadTable for the current memory permission range. + // + RecordSegment = &ImageRecord->Segments[NumRecordSegments]; + RecordSegment->Size = RangeSize; + RecordSegment->Attributes = InternalPermissionsToAttributes (Permissions); + ++NumRecordSegments; + // + // Start a Image record LoadTable with the current Image LoadTable. + // + RangeSize = SegmentSize; + Permissions = SegmentPermissions; + } + // + // Create an Image record LoadTable for the current memory permission range. + // + RecordSegment = &ImageRecord->Segments[NumRecordSegments]; + RecordSegment->Size = RangeSize; + RecordSegment->Attributes = InternalPermissionsToAttributes (Permissions); + ++NumRecordSegments; + + ImageAddress = UeLoaderGetImageAddress (&Context->Ctx.Ue); + ImageSize = UeGetImageSize (&Context->Ctx.Ue); + ASSERT (ImageSize == ImageSizeRecord); + + ImageRecord->NumSegments = NumRecordSegments; + ImageRecord->StartAddress = ImageAddress; + ImageRecord->EndAddress = ImageAddress + ImageSize; + // + // Zero the remaining array entries to avoid uninitialised data. + // + ZeroMem ( + ImageRecord->Segments + NumRecordSegments, + (NumSegments - NumRecordSegments) * sizeof (*ImageRecord->Segments) + ); + + return ImageRecord; +} + +// LCOV_EXCL_START +RETURN_STATUS +UefiImageDebugLocateImageUe ( + OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + IN UINTN Address + ) +{ + ASSERT (Context != NULL); + (VOID) Address; + // + // UE does not support this feature. + // + return RETURN_NOT_FOUND; +} +// LCOV_EXCL_STOP + +RETURN_STATUS +UefiImageGetFixedAddressUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, + OUT UINT64 *Address + ) +{ + BOOLEAN FixedAddress; + + ASSERT (Context != NULL); + ASSERT (Address != NULL); + + FixedAddress = UeGetFixedAddress (&Context->Ctx.Ue); + if (!FixedAddress) { + return RETURN_NOT_FOUND; + } + + *Address = Context->Ctx.Ue.BaseAddress; + return RETURN_SUCCESS; +} + +VOID +UefiImageDebugPrintSegmentsUe ( + IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context + ) +{ + RETURN_STATUS Status; + CONST CHAR8 *Name; + CONST UE_SEGMENT *Segments; + UINT16 NumSegments; + UINT16 SegmentIndex; + UINT32 SegmentFileOffset; + UINT32 SegmentImageAddress; + CONST UE_SEGMENT_NAME *NameTable; + UINT32 ImageSize; + + NumSegments = UeGetSegments (&Context->Ctx.Ue, &Segments); + + Status = UeGetSegmentNames (&Context->Ctx.Ue, &NameTable); + if (RETURN_ERROR (Status)) { + NameTable = NULL; + } + + SegmentFileOffset = Context->Ctx.Ue.SegmentsFileOffset; + // + // The first Image segment must begin the Image memory space. + // + SegmentImageAddress = 0; + + for (SegmentIndex = 0; SegmentIndex < NumSegments; ++SegmentIndex) { + if (NameTable != NULL) { + Name = (CONST CHAR8 *)NameTable[SegmentIndex]; + } else { + STATIC_ASSERT ( + sizeof (*NameTable) == sizeof ("Unknown"), + "The following may cause prohibited memory accesses." + ); + + Name = "Unknown"; + } + + ImageSize = UE_SEGMENT_SIZE (Segments[SegmentIndex].ImageInfo); + + DEBUG (( + DEBUG_VERBOSE, + " Segment - '%c%c%c%c%c%c%c%c'\n" + " ImageAddress - 0x%08x\n" + " ImageSize - 0x%08x\n" + " FileOffset - 0x%08x\n" + " FileSize - 0x%08x\n" + " Permissions - 0x%08x\n", + Name[0], Name[1], Name[2], Name[3], Name[4], Name[5], Name[6], Name[7], + SegmentImageAddress, + ImageSize, + SegmentFileOffset, + Segments[SegmentIndex].FileSize, + UE_SEGMENT_PERMISSIONS (Segments[SegmentIndex].ImageInfo) + )); + + SegmentImageAddress += ImageSize; + SegmentFileOffset += Segments[SegmentIndex].FileSize; + } +} + +GLOBAL_REMOVE_IF_UNREFERENCED CONST UEFI_IMAGE_FORMAT_SUPPORT mUeSupport = { + UefiImageInitializeContextPreHashUe, + UefiImageHashImageDefaultUe, + UefiImageInitializeContextPostHashUe, + UefiImageLoadImageUe, + UefiImageImageIsInplaceUe, + UefiImageLoadImageInplaceUe, + UefiImageRelocateImageInplaceUe, + UefiImageLoaderGetRuntimeContextSizeUe, + UefiImageRelocateImageUe, + UefiImageRuntimeRelocateImageUe, + UefiImageDiscardSegmentsUe, + UefiImageGetSymbolsPathUe, + UefiImageGetFirstCertificateUe, + UefiImageGetNextCertificateUe, + UefiImageGetHiiDataRvaUe, + UefiImageGetEntryPointAddressUe, + UefiImageGetMachineUe, + UefiImageGetSubsystemUe, + UefiImageGetSegmentAlignmentUe, + UefiImageGetImageSizeUe, + UefiImageGetBaseAddressUe, + UefiImageGetRelocsStrippedUe, + UefiImageLoaderGetImageAddressUe, + UefiImageLoaderGetDebugAddressUe, + UefiImageLoaderGetImageRecordUe, + UefiImageDebugLocateImageUe, + UefiImageGetFixedAddressUe, + UefiImageDebugPrintSegmentsUe +}; diff --git a/MdePkg/Library/BaseUefiImageLib/UeSupport.h b/MdePkg/Library/BaseUefiImageLib/UeSupport.h new file mode 100644 index 0000000000..e62052ebe1 --- /dev/null +++ b/MdePkg/Library/BaseUefiImageLib/UeSupport.h @@ -0,0 +1,16 @@ +/** @file + UEFI Image Loader library implementation for UE Images. + + Copyright (c) 2023, Marvin Häuser. All rights reserved.
+ + SPDX-License-Identifier: BSD-3-Clause +**/ + +#ifndef UE_SUPPORT_H +#define UE_SUPPORT_H + +#include "UefiImageFormat.h" + +extern CONST UEFI_IMAGE_FORMAT_SUPPORT mUeSupport; + +#endif // UE_SUPPORT_H diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c b/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c index 18d323f585..9739e50b29 100644 --- a/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c +++ b/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c @@ -20,6 +20,7 @@ #include #include +#include "UeSupport.h" #include "PeSupport.h" STATIC_ASSERT ( @@ -39,34 +40,50 @@ STATIC_ASSERT ( #define UEFI_IMAGE_FORMAT_SUPPORT_FV 0 #endif -#define UEFI_IMAGE_SUPPORT \ +#define UEFI_IMAGE_FORMAT_SUPPORT \ (UEFI_IMAGE_FORMAT_SUPPORT_NON_FV | UEFI_IMAGE_FORMAT_SUPPORT_FV) -#define FORMAT_EQ(FormatIndex, Format) \ - (UEFI_IMAGE_SUPPORT == (1U << (Format)) || \ - ((UEFI_IMAGE_SUPPORT & (1U << (Format))) != 0 && \ +#define FORMAT_EQ(FormatIndex, Format) \ + (UEFI_IMAGE_FORMAT_SUPPORT == (1U << (Format)) || \ + ((UEFI_IMAGE_FORMAT_SUPPORT & (1U << (Format))) != 0 && \ (FormatIndex) == (Format))) #define UEFI_IMAGE_EXEC(Result, FormatIndex, Func, ...) \ do { \ - ASSERT ((FormatIndex) == UefiImageFormatPe); \ - Result = mPeSupport.Func (__VA_ARGS__); \ + if (FORMAT_EQ ((FormatIndex), UefiImageFormatUe)) { \ + ASSERT ((FormatIndex) == UefiImageFormatUe); \ + Result = mUeSupport.Func (__VA_ARGS__); \ + } else { \ + ASSERT ((FormatIndex) == UefiImageFormatPe); \ + Result = mPeSupport.Func (__VA_ARGS__); \ + } \ } while (FALSE) -#define UEFI_IMAGE_EXEC_VOID(FormatIndex, Func, ...) \ - do { \ - ASSERT ((FormatIndex) == UefiImageFormatPe); \ - mPeSupport.Func (__VA_ARGS__); \ +#define UEFI_IMAGE_EXEC_VOID(FormatIndex, Func, ...) \ + do { \ + if (FORMAT_EQ ((FormatIndex), UefiImageFormatUe)) { \ + ASSERT ((FormatIndex) == UefiImageFormatUe); \ + mUeSupport.Func (__VA_ARGS__); \ + } else { \ + ASSERT ((FormatIndex) == UefiImageFormatPe); \ + mPeSupport.Func (__VA_ARGS__); \ + } \ } while (FALSE) STATIC_ASSERT ( - UefiImageFormatPe == UefiImageFormatMax - 1, + UefiImageFormatMax == 2, "Support for more formats needs to be added above." ); -#define FORMAT_SUPPORTED(Format, Source) \ - ((UEFI_IMAGE_SUPPORT & (1U << (Format))) != 0 && \ - (mUefiImageSupportSource[Source] & (1U << (Format))) != 0) +#define FORMAT_SUPPORTED(Format, Source) \ + ((UEFI_IMAGE_FORMAT_SUPPORT & (1U << (Format))) != 0 && \ + (((Source) == UEFI_IMAGE_SOURCE_NON_FV && (UEFI_IMAGE_FORMAT_SUPPORT_NON_FV & (1U << (Format))) != 0) || \ + ((Source) == UEFI_IMAGE_SOURCE_FV && (UEFI_IMAGE_FORMAT_SUPPORT_FV & (1U << (Format))) != 0))) + +STATIC_ASSERT ( + UEFI_IMAGE_SOURCE_MAX == 3, + "Support for more sources needs to be added above." + ); STATIC RETURN_STATUS @@ -99,12 +116,6 @@ UefiImageInitializeContextPreHash ( IN UEFI_IMAGE_SOURCE Source ) { - CONST UINT8 mUefiImageSupportSource[UEFI_IMAGE_SOURCE_MAX] = { - UEFI_IMAGE_FORMAT_SUPPORT_NON_FV, - UEFI_IMAGE_FORMAT_SUPPORT_FV, - UEFI_IMAGE_SUPPORT - }; - RETURN_STATUS Status; #if (UEFI_IMAGE_FORMAT_SUPPORT_SOURCES & (1U << UEFI_IMAGE_SOURCE_NON_FV)) != 0 @@ -124,11 +135,23 @@ UefiImageInitializeContextPreHash ( Status = RETURN_UNSUPPORTED; STATIC_ASSERT ( - UefiImageFormatPe == UefiImageFormatMax - 1, + UefiImageFormatUe == UefiImageFormatMax - 1, "Support for more formats needs to be added above." ); - if (FORMAT_SUPPORTED (UefiImageFormatPe, Source)) { + if (FORMAT_SUPPORTED (UefiImageFormatUe, Source)) { + Status = InternalInitializeContextPreHash ( + Context, + FileBuffer, + FileSize, + UefiImageFormatUe + ); + if (!RETURN_ERROR (Status)) { + Context->FormatIndex = UefiImageFormatUe; + } + } + + if (RETURN_ERROR (Status) && FORMAT_SUPPORTED (UefiImageFormatPe, Source)) { Status = InternalInitializeContextPreHash ( Context, FileBuffer, @@ -137,7 +160,6 @@ UefiImageInitializeContextPreHash ( ); if (!RETURN_ERROR (Status)) { Context->FormatIndex = UefiImageFormatPe; - return RETURN_SUCCESS; } } diff --git a/MdePkg/MdeLibs.dsc.inc b/MdePkg/MdeLibs.dsc.inc index f83a07ad13..ca244c9c27 100644 --- a/MdePkg/MdeLibs.dsc.inc +++ b/MdePkg/MdeLibs.dsc.inc @@ -83,6 +83,7 @@ UefiImageOnlyNonFvLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf UefiImageOnlyFvLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf UefiImageAllLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageAllLib.inf + UeImageLib|MdePkg/Library/BaseUeImageLib/BaseUeImageLib.inf [LibraryClasses.common.USER_DEFINED, LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses.common.PEIM, LibraryClasses.common.SMM_CORE, LibraryClasses.common.MM_CORE_STANDALONE, LibraryClasses.common.DXE_SMM_DRIVER, LibraryClasses.common.MM_STANDALONE] UefiImageLib|MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index d893bec5d0..e74ae4d953 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -992,6 +992,7 @@ ## Include/Ppi/LoadFile.h gEfiPeiLoadFilePpiGuid = { 0xb9e0abfe, 0x5979, 0x4914, { 0x97, 0x7f, 0x6d, 0xee, 0x78, 0xc2, 0x78, 0xa6 } } + gEfiPeiLoadFileWithHobPpiGuid = { 0x14c2d0d0, 0xccfd, 0x40e5, { 0xae, 0xa7, 0x57, 0x23, 0x58, 0xdd, 0xbf, 0xe8 } } ## Include/Ppi/Decompress.h gEfiPeiDecompressPpiGuid = { 0x1a36e4e7, 0xfab6, 0x476a, { 0x8e, 0x75, 0x69, 0x5a, 0x5, 0x76, 0xfd, 0xd7 } } @@ -2366,13 +2367,21 @@ # @Prompt Remove X permission from WX sections. gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX|FALSE|BOOLEAN|0x40001021 - ## Indicates the UEFI image file formats supported outside FVs.

+ ## Indicates the UEFI image file formats supported outside FVs. + # UE is experimental and not enabled by default. + # For correct usage in a platform which opts in to UE support, this should + # be overridden globally, not within individual modules.

# BIT0 - PE.
+ # BIT1 - UE.
# @Prompt Supported UEFI image file formats outside FVs. gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportNonFv|0x01|UINT8|0x40002000 - ## Indicates the UEFI image file formats supported inside FVs.

+ ## Indicates the UEFI image file formats supported inside FVs. + # UE is experimental and not enabled by default. + # For correct usage in a platform which opts in to UE support, this should + # be overridden globally, not within individual modules.

# BIT0 - PE.
+ # BIT1 - UE.
# @Prompt Supported UEFI image file formats inside FVs. gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x01|UINT8|0x40002001 diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 9e9de024c8..c86d64cd84 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -58,6 +58,7 @@ MdePkg/Library/PciSegmentLibSegmentInfo/DxeRuntimePciSegmentLibSegmentInfo.inf MdePkg/Library/BaseS3PciSegmentLib/BaseS3PciSegmentLib.inf MdePkg/Library/BaseArmTrngLibNull/BaseArmTrngLibNull.inf + MdePkg/Library/BaseUeImageLib/BaseUeImageLib.inf MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyNonFvLib.inf MdePkg/Library/BaseUefiImageLib/BaseUefiImageOnlyFvLib.inf diff --git a/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc b/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc index a933961464..0c3e551d1f 100644 --- a/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc +++ b/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc @@ -62,9 +62,9 @@ DEFINE FW_BLOCKS = 0x400 DEFINE CODE_BASE_ADDRESS = 0xFFC84000 DEFINE CODE_SIZE = 0x0037C000 DEFINE CODE_BLOCKS = 0x37C -DEFINE FVMAIN_SIZE = 0x00345000 -DEFINE SECFV_OFFSET = 0x003C9000 -DEFINE SECFV_SIZE = 0x37000 +DEFINE FVMAIN_SIZE = 0x00342000 +DEFINE SECFV_OFFSET = 0x003C6000 +DEFINE SECFV_SIZE = 0x3a000 !endif SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress = $(FW_BASE_ADDRESS) diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc index 28fbc45767..4b43bce448 100644 --- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc +++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc @@ -487,6 +487,11 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF45 !endif + # + # Firmware volume is PE. + # + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x01 + ################################################################################ # # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index 7e13d313e6..d136c4df2e 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -173,6 +173,7 @@ gOvmfVariableGuid = {0x50bea1e5, 0xa2c5, 0x46e9, {0x9b, 0x3a, 0x59, 0x59, 0x65, 0x16, 0xb0, 0x0a}} gQemuFirmwareResourceHobGuid = {0x3cc47b04, 0x0d3e, 0xaa64, {0x06, 0xa6, 0x4b, 0xdc, 0x9a, 0x2c, 0x61, 0x19}} gRtcRegisterBaseAddressHobGuid = {0x40435d97, 0xeb37, 0x4a4b, {0x7f, 0xad, 0xb7, 0xed, 0x72, 0xa1, 0x43, 0xc5}} + gUefiImageLoaderImageContextGuid = {0x05cc29cc, 0xfbdf, 0x4cc8, {0x98, 0x25, 0x71, 0x76, 0x08, 0x5b, 0x05, 0x01}} [Ppis] # PPI whose presence in the PPI database signals that the TPM base address diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 488e2245d6..12e94a4e57 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -596,6 +596,11 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x0 !endif + # + # Firmware volume supports UE, and may require PE. + # + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03 + ################################################################################ # # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index 010a3cec91..3e3476d897 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -403,57 +403,57 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { [Rule.Common.SEC] FILE SEC = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING ="$(MODULE_NAME)" Optional VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.PEI_CORE] FILE PEI_CORE = $(NAMED_GUID) { - PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING ="$(MODULE_NAME)" Optional VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.PEIM] FILE PEIM = $(NAMED_GUID) { - PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.DXE_CORE] FILE DXE_CORE = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.DXE_DRIVER] FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - RAW ACPI Optional |.acpi - RAW ASL Optional |.aml + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + RAW ACPI Optional |.acpi + RAW ASL Optional |.aml } [Rule.Common.DXE_RUNTIME_DRIVER] FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.UEFI_DRIVER] FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.UEFI_DRIVER.BINARY] @@ -466,14 +466,14 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { [Rule.Common.UEFI_APPLICATION] FILE APPLICATION = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.UEFI_APPLICATION.BINARY] FILE APPLICATION = $(NAMED_GUID) { - PE32 PE32 |.efi + UE UE |.efi UI STRING="$(MODULE_NAME)" Optional VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } @@ -485,15 +485,15 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { [Rule.Common.SMM_CORE] FILE SMM_CORE = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.DXE_SMM_DRIVER] FILE SMM = $(NAMED_GUID) { - SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 3f3195d7e2..6835e78181 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -566,6 +566,11 @@ gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask|0x1 gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 + # + # Firmware volume supports UE, and may require PE. + # + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03 + [PcdsFixedAtBuild.IA32] # # The NumberOfPages values below are ad-hoc. They are updated sporadically at diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index 34a78831f5..58a273fcc8 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -305,7 +305,7 @@ INF SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.inf # !if $(E1000_ENABLE) FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 { - SECTION PE32 = Intel3.5/EFIX64/E3522X2.EFI + SECTION UE = Intel3.5/EFIX64/E3522X2.EFI } !endif !include NetworkPkg/Network.fdf.inc @@ -407,57 +407,57 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { [Rule.Common.SEC] FILE SEC = $(NAMED_GUID) { - PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING ="$(MODULE_NAME)" Optional VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.PEI_CORE] FILE PEI_CORE = $(NAMED_GUID) { - PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING ="$(MODULE_NAME)" Optional VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.PEIM] FILE PEIM = $(NAMED_GUID) { - PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.DXE_CORE] FILE DXE_CORE = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.DXE_DRIVER] FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - RAW ACPI Optional |.acpi - RAW ASL Optional |.aml + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + RAW ACPI Optional |.acpi + RAW ASL Optional |.aml } [Rule.Common.DXE_RUNTIME_DRIVER] FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.UEFI_DRIVER] FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.UEFI_DRIVER.BINARY] @@ -470,14 +470,14 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { [Rule.Common.UEFI_APPLICATION] FILE APPLICATION = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.UEFI_APPLICATION.BINARY] FILE APPLICATION = $(NAMED_GUID) { - PE32 PE32 |.efi + UE UE |.efi UI STRING="$(MODULE_NAME)" Optional VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } @@ -489,15 +489,15 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { [Rule.Common.SMM_CORE] FILE SMM_CORE = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.DXE_SMM_DRIVER] FILE SMM = $(NAMED_GUID) { - SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 96c7dd5ab0..9019052a90 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -625,6 +625,11 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE !endif + # + # Firmware volume supports UE, and may require PE. + # + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03 + ################################################################################ # # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 9b26b3192c..e0cb9cc909 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -339,7 +339,7 @@ INF SecurityPkg/Hash2DxeCrypto/Hash2DxeCrypto.inf # !if $(E1000_ENABLE) FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 { - SECTION PE32 = Intel3.5/EFIX64/E3522X2.EFI + SECTION UE = Intel3.5/EFIX64/E3522X2.EFI } !endif !include NetworkPkg/Network.fdf.inc @@ -448,57 +448,57 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { [Rule.Common.SEC] FILE SEC = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING ="$(MODULE_NAME)" Optional VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.PEI_CORE] FILE PEI_CORE = $(NAMED_GUID) { - PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING ="$(MODULE_NAME)" Optional VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.PEIM] FILE PEIM = $(NAMED_GUID) { - PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.DXE_CORE] FILE DXE_CORE = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.DXE_DRIVER] FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) - RAW ACPI Optional |.acpi - RAW ASL Optional |.aml + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + RAW ACPI Optional |.acpi + RAW ASL Optional |.aml } [Rule.Common.DXE_RUNTIME_DRIVER] FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.UEFI_DRIVER] FILE DRIVER = $(NAMED_GUID) { - DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.UEFI_DRIVER.BINARY] @@ -511,14 +511,14 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { [Rule.Common.UEFI_APPLICATION] FILE APPLICATION = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.UEFI_APPLICATION.BINARY] FILE APPLICATION = $(NAMED_GUID) { - PE32 PE32 |.efi + UE UE |.efi UI STRING="$(MODULE_NAME)" Optional VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } @@ -530,15 +530,15 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { [Rule.Common.SMM_CORE] FILE SMM_CORE = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.DXE_SMM_DRIVER] FILE SMM = $(NAMED_GUID) { - SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi - UI STRING="$(MODULE_NAME)" Optional - VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } diff --git a/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm b/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm index c65f5497e6..c1ab35e968 100644 --- a/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm +++ b/UefiCpuPkg/ResetVector/Vtf0/Ia32/SearchForSecEntry.asm @@ -150,10 +150,20 @@ getEntryPointOfFfsFileLoopForSections: jmp getEntryPointOfFfsFileLoopForSections getEntryPointOfFfsFileFoundPe32Section: - add eax, 4 ; EAX = Start of PE32 image + add eax, 4 ; EAX = Start of PE or UE image cmp word [eax], 'MZ' + je getEntryPointOfFfsFileFoundPeFile + + cmp word [eax], 'UE' jne getEntryPointOfFfsFileErrorReturn + + ; *EntryPoint = (VOID *)((UINTN)UeData + UeHdr.EntryPointAddress) + mov ebx, dword [eax + 0x4] + add eax, ebx + jmp getEntryPointOfFfsFileReturn + +getEntryPointOfFfsFileFoundPeFile: movzx ebx, word [eax + 0x3c] add ebx, eax @@ -171,4 +181,3 @@ getEntryPointOfFfsFileErrorReturn: getEntryPointOfFfsFileReturn: OneTimeCallRet GetEntryPointOfFfsFile - diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c index 3382aad7ce..b2baac1105 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c @@ -28,13 +28,13 @@ LoadUefiImage ( OUT EFI_PHYSICAL_ADDRESS *EntryPoint ) { - RETURN_STATUS Status; - UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; - UINT32 ImageSize; - UINT32 ImageAlignment; - UINT32 BufferPages; - UINT32 BufferSize; - VOID *Buffer; + RETURN_STATUS Status; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UINT32 ImageSize; + UINT32 ImageAlignment; + UINT32 BufferPages; + UINT32 BufferSize; + VOID *Buffer; Status = UefiImageInitializeContext ( &ImageContext, diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 93bf6e392f..8eab1e00d8 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -544,6 +544,11 @@ gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04 !endif + # + # Firmware volume supports UE, and may require PE. + # + gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x03 + [PcdsPatchableInModule.X64] !if $(NETWORK_DRIVER_ENABLE) == TRUE gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections|TRUE diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 71ca5254e6..c3cd03e4d1 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -407,7 +407,7 @@ INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.in [Rule.Common.DXE_DRIVER] FILE DRIVER = $(NAMED_GUID) { DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING="$(MODULE_NAME)" Optional VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } @@ -415,21 +415,21 @@ INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.in [Rule.Common.DXE_RUNTIME_DRIVER] FILE DRIVER = $(NAMED_GUID) { DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING="$(MODULE_NAME)" Optional VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.DXE_SMM_DRIVER] FILE SMM = $(NAMED_GUID) { SMM_DEPEX SMM_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING="$(MODULE_NAME)" Optional VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.SMM_CORE] FILE SMM_CORE = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING="$(MODULE_NAME)" Optional VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } @@ -437,7 +437,7 @@ INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.in [Rule.Common.UEFI_DRIVER] FILE DRIVER = $(NAMED_GUID) { DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING="$(MODULE_NAME)" Optional VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } @@ -445,21 +445,21 @@ INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.in [Rule.Common.UEFI_DRIVER.BINARY] FILE DRIVER = $(NAMED_GUID) { DXE_DEPEX DXE_DEPEX Optional |.depex - PE32 PE32 |.efi + UE UE |.efi UI STRING="$(MODULE_NAME)" Optional VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.UEFI_APPLICATION] FILE APPLICATION = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING="$(MODULE_NAME)" Optional VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } [Rule.Common.UEFI_APPLICATION.BINARY] FILE APPLICATION = $(NAMED_GUID) { - PE32 PE32 |.efi + UE UE |.efi UI STRING="$(MODULE_NAME)" Optional VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } @@ -482,7 +482,7 @@ INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.in [Rule.Common.UEFI_APPLICATION.UI] FILE APPLICATION = $(NAMED_GUID) { - PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UE UE $(INF_OUTPUT)/$(MODULE_NAME).efi UI STRING="Enter Setup" VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) } From 4d3a62c2e7154ff30cd59c569b2a835e8b22537d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 3 Nov 2023 15:48:52 +0300 Subject: [PATCH 087/341] BaseTools: Fixed '-D EDK2_REDUCE_FW_SIZE' build option. --- BaseTools/ImageTool/PeEmit.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/BaseTools/ImageTool/PeEmit.c b/BaseTools/ImageTool/PeEmit.c index fb0ea39a52..ba8dce05a8 100644 --- a/BaseTools/ImageTool/PeEmit.c +++ b/BaseTools/ImageTool/PeEmit.c @@ -588,6 +588,12 @@ ToolImageEmitPeFile ( SizeOfPeHeaders = SectionHeadersOffset + SectionHeadersSize; SizeOfHeaders = sizeof (mDosHdr) + SizeOfPeHeaders; AlignedSizeOfHeaders = ALIGN_VALUE (SizeOfHeaders, FileAlignment); + // + // Necessary adjustment for '-D EDK2_REDUCE_FW_SIZE' build option. + // + if (AlignedSizeOfHeaders < Image->SegmentInfo.Segments[0].ImageAddress) { + AlignedSizeOfHeaders = (uint32_t)Image->SegmentInfo.Segments[0].ImageAddress; + } PeOffset = ImageToolBufferAppendReserve ( Buffer, @@ -623,7 +629,7 @@ ToolImageEmitPeFile ( PeHdr->ImageBase = (EFI_IMAGE_NT_BASE_ADDRESS)Image->HeaderInfo.BaseAddress; PeHdr->SectionAlignment = Image->SegmentInfo.SegmentAlignment; PeHdr->FileAlignment = FileAlignment; - PeHdr->SizeOfImage = ALIGN_VALUE (SizeOfHeaders, PeHdr->SectionAlignment); + PeHdr->SizeOfImage = AlignedSizeOfHeaders; PeHdr->SizeOfHeaders = AlignedSizeOfHeaders; PeHdr->Subsystem = Image->HeaderInfo.Subsystem; PeHdr->NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES; From 992385e15e05964e0022d5b889986a7ef484fbff Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 7 Apr 2025 12:30:28 +0300 Subject: [PATCH 088/341] SecurePE: Defined new PcdImageProtectionPolicy. --- .../ArmStandaloneMmCoreEntryPoint.c | 5 +- .../DebugAgentSymbolsBaseLib.c | 3 +- ArmVirtPkg/ArmVirt.dsc.inc | 6 -- ArmVirtPkg/PrePi/PrePi.c | 3 +- BaseTools/ImageTool/ImageTool.c | 6 +- BaseTools/ImageTool/UefiImageScan.c | 3 +- BaseTools/Source/C/Common/CommonLib.c | 3 +- BaseTools/Source/C/EfiRom/EfiRom.c | 3 +- BaseTools/Source/C/GenFv/GenFvInternalLib.c | 19 ++-- BaseTools/Source/C/Include/Common/AutoGen.h | 6 ++ EmbeddedPkg/Library/PrePiLib/PrePiLib.c | 3 +- EmulatorPkg/EmulatorPkg.dsc | 2 +- .../FspWrapperNotifyDxe/LoadBelow4G.c | 3 +- MdeModulePkg/Core/Dxe/DxeMain.h | 5 +- MdeModulePkg/Core/Dxe/DxeMain.inf | 3 +- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 5 +- MdeModulePkg/Core/Dxe/Image/Image.c | 31 ++++-- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 94 +++---------------- MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 2 +- MdeModulePkg/Core/Pei/Image/Image.c | 6 +- MdeModulePkg/Core/Pei/Ppi/Ppi.c | 3 +- MdeModulePkg/Core/PiSmmCore/Dispatcher.c | 3 +- MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c | 3 +- MdeModulePkg/MdeModulePkg.dec | 15 --- MdeModulePkg/MdeModulePkg.uni | 12 --- .../BootScriptExecutorDxe/ScriptExecute.c | 3 +- MdePkg/Include/Library/PeCoffLib2.h | 14 ++- MdePkg/Include/Library/UefiImageLib.h | 13 ++- .../Library/BasePeCoffLib2/BasePeCoffLib2.inf | 1 + MdePkg/Library/BasePeCoffLib2/PeCoffInit.c | 29 +++++- .../Library/BaseUefiImageLib/CommonSupport.c | 6 +- MdePkg/Library/BaseUefiImageLib/PeSupport.c | 22 +++-- MdePkg/Library/BaseUefiImageLib/UeSupport.c | 6 +- .../BaseUefiImageLib/UefiImageFormat.h | 6 +- .../Library/BaseUefiImageLib/UefiImageLib.c | 21 +++-- MdePkg/MdePkg.dec | 21 +++++ OvmfPkg/IntelTdx/IntelTdxX64.dsc | 1 + .../PeilessStartupLib/PeilessStartupLib.inf | 2 +- OvmfPkg/OvmfPkgIa32.dsc | 3 +- OvmfPkg/OvmfPkgIa32X64.dsc | 6 +- OvmfPkg/OvmfPkgX64.dsc | 1 + OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc | 6 -- OvmfPkg/Sec/SecMain.c | 6 +- OvmfPkg/Tcg/TdTcg2Dxe/MeasureBootPeCoff.c | 8 +- .../Tcg/Tcg2Dxe/MeasureBootUefiImage.c | 3 +- .../SecureBootConfigImpl.c | 3 +- .../CpuExceptionHandlerLib/PeiCpuException.c | 2 +- UefiCpuPkg/SecCore/FindPeiCore.c | 6 +- UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c | 3 +- .../UefiPayloadEntry/UefiPayloadEntry.inf | 2 +- .../UniversalPayloadEntry.inf | 2 +- 51 files changed, 239 insertions(+), 204 deletions(-) diff --git a/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.c b/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.c index 05052f2ba5..3701a88e2d 100644 --- a/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.c +++ b/ArmPkg/Library/ArmStandaloneMmCoreEntryPoint/ArmStandaloneMmCoreEntryPoint.c @@ -1008,7 +1008,7 @@ CEntryPoint ( IN UINTN Arg3 ) { - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; ARM_SVC_ARGS EventCompleteSvcArgs; EFI_STATUS Status; COMM_PROTOCOL CommProtocol; @@ -1068,7 +1068,8 @@ CEntryPoint ( &ImageContext, TeData, TeDataSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Section information - %r\n", Status)); diff --git a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c index 525483a440..1d25b82455 100644 --- a/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c +++ b/ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.c @@ -218,7 +218,8 @@ GetImageContext ( ImageContext, EfiImage, SectionLength - sizeof (*Section), - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (!EFI_ERROR(Status)) { Status = UefiImageLoadImageInplace( ImageContext); diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 865bb20895..c34165ac29 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -380,12 +380,6 @@ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20 gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0 - # - # Enable strict image permissions for all images. (This applies - # only to images that were built with >= 4 KB section alignment.) - # - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x3 - # # Enable NX memory protection for all non-code regions, including OEM and OS # reserved ones. diff --git a/ArmVirtPkg/PrePi/PrePi.c b/ArmVirtPkg/PrePi/PrePi.c index ef5214f39c..73818a9bfb 100644 --- a/ArmVirtPkg/PrePi/PrePi.c +++ b/ArmVirtPkg/PrePi/PrePi.c @@ -154,7 +154,8 @@ RelocateUefiImage ( &ImageContext, SectionData, SectionSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_RETURN_ERROR (Status); diff --git a/BaseTools/ImageTool/ImageTool.c b/BaseTools/ImageTool/ImageTool.c index d3a4378e5c..7734228141 100644 --- a/BaseTools/ImageTool/ImageTool.c +++ b/BaseTools/ImageTool/ImageTool.c @@ -250,7 +250,7 @@ GetAcpi ( return RETURN_ABORTED; } - Status = PeCoffInitializeContext (&Context, Pe, (UINT32)PeSize); + Status = PeCoffInitializeContext (&Context, Pe, (UINT32)PeSize, UefiImageOriginFv); if (RETURN_ERROR (Status)) { fprintf (stderr, "ImageTool: Could not initialise Context\n"); free (Pe); @@ -442,6 +442,10 @@ int main (int argc, const char *argv[]) bool FixedAddress; int ArgIndex; + PcdGet8 (PcdUefiImageFormatSupportNonFv) = 0x00; + PcdGet8 (PcdUefiImageFormatSupportFv) = 0x03; + PcdGet32 (PcdImageProtectionPolicy) = 0x00; + if (argc < 2) { fprintf (stderr, "ImageTool: No command is specified\n"); DEBUG_RAISE (); diff --git a/BaseTools/ImageTool/UefiImageScan.c b/BaseTools/ImageTool/UefiImageScan.c index bbf791f703..d9c4faafa4 100644 --- a/BaseTools/ImageTool/UefiImageScan.c +++ b/BaseTools/ImageTool/UefiImageScan.c @@ -209,7 +209,8 @@ ToolContextConstructUefiImage ( &Context, File, (UINT32)FileSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (RETURN_ERROR (Status)) { return Status; diff --git a/BaseTools/Source/C/Common/CommonLib.c b/BaseTools/Source/C/Common/CommonLib.c index 98176555af..08d4b6d81d 100644 --- a/BaseTools/Source/C/Common/CommonLib.c +++ b/BaseTools/Source/C/Common/CommonLib.c @@ -673,7 +673,8 @@ GetAlignmentFromFile ( &ImageContext, ImageFileBuffer + CurSecHdrSize, ImageFileSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { Error (NULL, 0, 3000, "Invalid UefiImage", "The input file is %s and return status is %x", InFile, (int) Status); diff --git a/BaseTools/Source/C/EfiRom/EfiRom.c b/BaseTools/Source/C/EfiRom/EfiRom.c index 053849202a..4929dac36b 100644 --- a/BaseTools/Source/C/EfiRom/EfiRom.c +++ b/BaseTools/Source/C/EfiRom/EfiRom.c @@ -840,7 +840,8 @@ Routine Description: &Context, FileBuffer, FileSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (RETURN_ERROR (Status)) { Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be an UEFI image - %llu!", Status); diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index fa31c1c808..2756cc65cc 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -2404,7 +2404,8 @@ Routine Description: &Context, UefiImage, UefiImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (RETURN_ERROR (Status)) { Error (NULL, 0, 3000, "Invalid", "Unrecognized UEFI image file."); @@ -3587,11 +3588,13 @@ Routine Description: // Initialize context // SectPeSize = GetSectionFileLength (CurrentPe32Section.CommonHeader) - CurSecHdrSize; + Status = UefiImageInitializeContext ( &ImageContext, (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize), SectPeSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { Error (NULL, 0, 3000, "Invalid UefiImage", "The input file is %s and the return status is %x", FileName, (int) Status); @@ -3874,13 +3877,13 @@ Routine Description: // // Get this module function address from ModulePeMapFile and add them into FvMap file // - Status = UefiImageInitializeContext ( - &ImageContext, - (VOID *) ((UINTN)(*FfsFile) + FileOffset), - RebasedImageSize, - UEFI_IMAGE_SOURCE_FV - ); + &ImageContext, + (VOID *) ((UINTN)(*FfsFile) + FileOffset), + RebasedImageSize, + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv + ); ASSERT_EFI_ERROR (Status); // diff --git a/BaseTools/Source/C/Include/Common/AutoGen.h b/BaseTools/Source/C/Include/Common/AutoGen.h index 8b5f42bd03..c9af984cc8 100644 --- a/BaseTools/Source/C/Include/Common/AutoGen.h +++ b/BaseTools/Source/C/Include/Common/AutoGen.h @@ -177,6 +177,12 @@ extern UINT64 _gPcd_SkuId_Array[]; #define _PCD_GET_MODE_8_PcdUefiImageFormatSupportFv _PCD_VALUE_PcdUefiImageFormatSupportFv //#define _PCD_SET_MODE_8_PcdUefiImageFormatSupportFv ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD +#define _PCD_TOKEN_PcdImageProtectionPolicy 0U +#define _PCD_SIZE_PcdImageProtectionPolicy 4 +#define _PCD_GET_MODE_SIZE_PcdImageProtectionPolicy _PCD_SIZE_PcdImageProtectionPolicy +#define _PCD_VALUE_PcdImageProtectionPolicy 0U +#define _PCD_GET_MODE_32_PcdImageProtectionPolicy _PCD_VALUE_PcdImageProtectionPolicy +//#define _PCD_SET_MODE_32_PcdImageProtectionPolicy ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD #ifdef __cplusplus } diff --git a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c index 9826e9493e..c94dc0d45a 100644 --- a/EmbeddedPkg/Library/PrePiLib/PrePiLib.c +++ b/EmbeddedPkg/Library/PrePiLib/PrePiLib.c @@ -44,7 +44,8 @@ LoadUefiImage ( &ImageContext, UefiImage, UefiImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc index 4a1ef25198..c5829427b4 100644 --- a/EmulatorPkg/EmulatorPkg.dsc +++ b/EmulatorPkg/EmulatorPkg.dsc @@ -214,7 +214,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables|FALSE [PcdsFixedAtBuild] - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000000 + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000000 gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000040 gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x0f diff --git a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c index 55ee2c6f9a..eac36f5d10 100644 --- a/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c +++ b/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c @@ -94,7 +94,8 @@ RelocateImageUnder4GIfNeeded ( &ImageContext, Buffer, (UINT32) BufferSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); ImageSize = UefiImageGetImageSize (&ImageContext); diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 77397b6367..012e2d379d 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2726,14 +2726,13 @@ RemoveImageRecord ( Protect UEFI image. @param[in] LoadedImage The loaded image protocol - @param[in] ImageType Whether File comes from FV. Must be FALSE - or TRUE. + @param[in] ImageOrigin Where File comes from. @param[in] LoadedImageDevicePath The loaded image device path protocol **/ VOID ProtectUefiImage ( IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN BOOLEAN ImageIsFromFv, + IN UINT8 ImageOrigin, UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ); diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index e7e9579ead..17b449caa0 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -184,7 +184,6 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileMemoryType ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfilePropertyMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType ## CONSUMES @@ -193,6 +192,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdImageLargeAddressLoad ## CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask ## CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES # [Hob] # RESOURCE_DESCRIPTOR ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 83cd23363a..0b3c222ed1 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -203,6 +203,7 @@ EFI_RUNTIME_SERVICES *gRT = &mEfiRuntimeServicesTableTemplate; EFI_HANDLE gImageHandle = NULL; BOOLEAN gMemoryMapTerminated = FALSE; +BOOLEAN gBdsStarted = FALSE; static BOOLEAN mExitBootServicesCalled = FALSE; @@ -331,7 +332,7 @@ DxeMain ( CoreInitializeMemoryProtection (); - ProtectUefiImage (&mCurrentImage->Info, TRUE, &ImageContext); + ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext); // // Call constructor for all libraries @@ -574,6 +575,8 @@ DxeMain ( (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT) ); + gBdsStarted = TRUE; + // // Transfer control to the BDS Architectural Protocol // diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index cfc82980a8..9f0f7c0f64 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -24,6 +24,8 @@ STATIC LIST_ENTRY mAvailableEmulators; STATIC EFI_EVENT mPeCoffEmuProtocolRegistrationEvent; STATIC VOID *mPeCoffEmuProtocolNotifyRegistration; +extern BOOLEAN gBdsStarted; + // // This code is needed to build the Image handle for the DXE Core // @@ -1101,11 +1103,13 @@ CoreLoadImageCommon ( BOOLEAN ImageIsFromFv; BOOLEAN ImageIsFromLoadFile; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UINT8 ImageOrigin; SecurityStatus = EFI_SUCCESS; ASSERT (gEfiCurrentTpl < TPL_NOTIFY); ParentImage = NULL; + Image = NULL; // // The caller must pass in a valid ParentImageHandle @@ -1171,6 +1175,7 @@ CoreLoadImageCommon ( Status = CoreLocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &HandleFilePath, &DeviceHandle); if (!EFI_ERROR (Status)) { ImageIsFromFv = TRUE; + ImageOrigin = UefiImageOriginFv; } else { HandleFilePath = FilePath; Status = CoreLocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &HandleFilePath, &DeviceHandle); @@ -1189,6 +1194,8 @@ CoreLoadImageCommon ( } } } + + ImageOrigin = UefiImageOriginOptionROM; } // @@ -1214,10 +1221,13 @@ CoreLoadImageCommon ( } if (EFI_ERROR (Status)) { - Image = NULL; goto Done; } + if (gBdsStarted) { + ImageOrigin = UefiImageOriginUserImage; + } + // // Get information about the image being loaded // @@ -1225,11 +1235,15 @@ CoreLoadImageCommon ( &ImageContext, FHand.Source, (UINT32) FHand.SourceSize, - ImageIsFromFv ? UEFI_IMAGE_SOURCE_FV : UEFI_IMAGE_SOURCE_NON_FV + ImageIsFromFv ? UEFI_IMAGE_SOURCE_FV : UEFI_IMAGE_SOURCE_NON_FV, + ImageOrigin ); if (EFI_ERROR (Status)) { - ASSERT (FALSE); - return Status; + if ((ImageOrigin != UefiImageOriginUserImage) && (Status != EFI_NOT_STARTED)) { + CpuDeadLoop (); + } + + goto Done; } // FIXME: Context @@ -1284,12 +1298,15 @@ CoreLoadImageCommon ( } Status = SecurityStatus; - Image = NULL; goto Done; } Status = UefiImageInitializeContextPostHash (&ImageContext); - if (RETURN_ERROR (Status)) { + if (EFI_ERROR (Status)) { + if (ImageOrigin != UefiImageOriginUserImage) { + CpuDeadLoop (); + } + goto Done; } @@ -1418,7 +1435,7 @@ CoreLoadImageCommon ( } Status = EFI_SUCCESS; - ProtectUefiImage (&Image->Info, ImageIsFromFv, &ImageContext); + ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext); RegisterMemoryProfileImage ( Image->LoadedImageDevicePath, diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 5692900e2d..5b0fe44a23 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -10,7 +10,6 @@ requirement. 3) This policy is applied only if the Source UEFI image matches the PcdImageProtectionPolicy definition. - 4) This policy is not applied to the non-PE image region. The DxeCore calls CpuArchProtocol->SetMemoryAttributes() to protect the image. If the CpuArch protocol is not installed yet, the DxeCore @@ -47,12 +46,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "ProcessorBind.h" #include "Uefi/UefiMultiPhase.h" -// -// Protection policy bit definition -// -#define DO_NOT_PROTECT 0x00000000 -#define PROTECT_IF_ALIGNED_ELSE_ALLOW 0x00000001 - #define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 #define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 @@ -65,58 +58,6 @@ extern LIST_ENTRY mGcdMemorySpaceMap; STATIC LIST_ENTRY mProtectedImageRecordList; -/** - Get UEFI image protection policy based upon image type. - - @param[in] ImageIsFromFv Whether File comes from FV. Must be FALSE or TRUE. - - @return UEFI image protection policy -**/ -UINT32 -GetProtectionPolicyFromImageType ( - IN BOOLEAN ImageIsFromFv - ) -{ - ASSERT (ImageIsFromFv == FALSE || ImageIsFromFv == TRUE); - - if (((ImageIsFromFv + 1) & mImageProtectionPolicy) == 0) { - return DO_NOT_PROTECT; - } else { - return PROTECT_IF_ALIGNED_ELSE_ALLOW; - } -} - -/** - Get UEFI image protection policy based upon loaded image device path. - - @param[in] ImageIsFromFv Whether File comes from FV. Must be FALSE or TRUE. - - @return UEFI image protection policy -**/ -UINT32 -GetUefiImageProtectionPolicy ( - IN BOOLEAN ImageIsFromFv - ) -{ - BOOLEAN InSmm; - UINT32 ProtectionPolicy; - - // - // Check SMM - // - InSmm = FALSE; - if (gSmmBase2 != NULL) { - gSmmBase2->InSmm (gSmmBase2, &InSmm); - } - - if (InSmm) { - return FALSE; - } - - ProtectionPolicy = GetProtectionPolicyFromImageType (ImageIsFromFv); - return ProtectionPolicy; -} - /** Set UEFI image memory attributes. @@ -224,39 +165,32 @@ IsMemoryProtectionSectionAligned ( Protect UEFI PE/COFF image. @param[in] LoadedImage The loaded image protocol - @param[in] ImageIsFromFv Whether File comes from FV. Must be FALSE - or TRUE. + @param[in] ImageOrigin Where File comes from. @param[in] LoadedImageDevicePath The loaded image device path protocol **/ VOID ProtectUefiImage ( IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN BOOLEAN ImageIsFromFv, + IN UINT8 ImageOrigin, UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext ) { - RETURN_STATUS PdbStatus; - UINT32 SectionAlignment; - UEFI_IMAGE_RECORD *ImageRecord; - CONST CHAR8 *PdbPointer; - UINT32 PdbSize; - BOOLEAN IsAligned; - UINT32 ProtectionPolicy; + RETURN_STATUS PdbStatus; + UINT32 SectionAlignment; + UEFI_IMAGE_RECORD *ImageRecord; + CONST CHAR8 *PdbPointer; + UINT32 PdbSize; + BOOLEAN IsAligned; + // + // Do not protect images, if policy allows. + // + if ((mImageProtectionPolicy & (BIT30 >> ImageOrigin)) != 0) { + return; + } DEBUG ((DEBUG_INFO, "ProtectUefiImageCommon - 0x%x\n", LoadedImage)); DEBUG ((DEBUG_INFO, " - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase, LoadedImage->ImageSize)); - ProtectionPolicy = GetUefiImageProtectionPolicy (ImageIsFromFv); - switch (ProtectionPolicy) { - case DO_NOT_PROTECT: - return; - case PROTECT_IF_ALIGNED_ELSE_ALLOW: - break; - default: - ASSERT (FALSE); - return; - } - PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize); if (!RETURN_ERROR (PdbStatus)) { DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer)); diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf index 1473be8f95..e231e7bd6f 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -112,7 +112,7 @@ [Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c index a32f1b949a..772233fd97 100644 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ b/MdeModulePkg/Core/Pei/Image/Image.c @@ -199,7 +199,8 @@ LoadAndRelocateUefiImage ( ImageContext, Pe32Data, Pe32DataSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { return Status; @@ -384,7 +385,8 @@ LoadAndRelocateUefiImageInPlace ( &ImageContext, ImageAddress, ImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c b/MdeModulePkg/Core/Pei/Ppi/Ppi.c index 0ea343c252..ab6cb2e16b 100644 --- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c +++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c @@ -1121,7 +1121,8 @@ ConvertPeiCorePpiPointers ( &ImageContext, (VOID *) (UINTN) PeiCoreImageBase, PeiCoreImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); diff --git a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c index fb0e861463..64d1e359f8 100644 --- a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c +++ b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c @@ -343,7 +343,8 @@ SmmLoadImage ( ImageContext, Buffer, (UINT32) Size, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { if (Buffer != NULL) { diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c index b3ca963049..247037f5c4 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c @@ -1008,7 +1008,8 @@ ExecuteSmmCoreFromSmram ( &gSmmCorePrivate->PiSmmCoreImageContext, SourceBuffer, (UINT32) SourceSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { return Status; diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 5446443296..f51dc7c9a1 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -1462,21 +1462,6 @@ # @Prompt Memory profile driver path. gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath|{0x0}|VOID*|0x00001043 - ## Set image protection policy. The policy is bitwise. - # If a bit is set, the image will be protected by DxeCore if it is aligned. - # The code section becomes read-only, and the data section becomes non-executable. - # If a bit is clear, nothing will be done to image code/data sections.

- # BIT0 - Image from unknown device.
- # BIT1 - Image from firmware volume.
- #
- # Note: If a bit is cleared, the data section could be still non-executable if - # PcdDxeNxMemoryProtectionPolicy is enabled for EfiLoaderData, EfiBootServicesData - # and/or EfiRuntimeServicesData.
- #
- # @Prompt Set image protection policy. - # @ValidRange 0x80000002 | 0x00000000 - 0x0000001F - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000002|UINT32|0x00001047 - ## Set DXE memory protection policy. The policy is bitwise. # If a bit is set, memory regions of the associated type will be mapped # non-executable.
diff --git a/MdeModulePkg/MdeModulePkg.uni b/MdeModulePkg/MdeModulePkg.uni index 7124f07a71..a5b7d87483 100644 --- a/MdeModulePkg/MdeModulePkg.uni +++ b/MdeModulePkg/MdeModulePkg.uni @@ -1098,18 +1098,6 @@ #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdSmiHandlerProfilePropertyMask_HELP #language en-US "The mask is used to control SmiHandlerProfile behavior.

\n" "BIT0 - Enable SmiHandlerProfile.
" -#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdImageProtectionPolicy_PROMPT #language en-US "Set image protection policy." - -#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdImageProtectionPolicy_HELP #language en-US "Set image protection policy. The policy is bitwise.\n" - "If a bit is set, the image will be protected by DxeCore if it is aligned.\n" - "The code section becomes read-only, and the data section becomes non-executable.\n" - "If a bit is clear, nothing will be done to image code/data sections.

\n" - "BIT0 - Image from unknown device.
\n" - "BIT1 - Image from firmware volume.
" - "Note: If a bit is cleared, the data section could be still non-executable if\n" - "PcdDxeNxMemoryProtectionPolicy is enabled for EfiLoaderData, EfiBootServicesData\n" - "and/or EfiRuntimeServicesData.
" - #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdDxeNxMemoryProtectionPolicy_PROMPT #language en-US "Set DXE memory protection policy." #string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdDxeNxMemoryProtectionPolicy_HELP #language en-US "Set DXE memory protection policy. The policy is bitwise.\n" diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c index ef71a3a7e1..812425c53f 100644 --- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c +++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/ScriptExecute.c @@ -314,7 +314,8 @@ ReadyToLockEventNotify ( &ImageContext, Buffer, (UINT32) BufferSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); diff --git a/MdePkg/Include/Library/PeCoffLib2.h b/MdePkg/Include/Library/PeCoffLib2.h index d1438b8a6a..18bb77236a 100644 --- a/MdePkg/Include/Library/PeCoffLib2.h +++ b/MdePkg/Include/Library/PeCoffLib2.h @@ -22,6 +22,17 @@ #include +typedef enum { + UefiImageOriginFv = 0, + UefiImageOriginOptionROM = 1, + UefiImageOriginUserImage = 2, + UefiImageOriginMax +} UEFI_IMAGE_ORIGIN; +/// +/// If set, less than 4KB aligned image from firmware volume prevents boot. +/// +#define PCD_IMAGE_PROTECTION_POLICY_FV_STOP_BOOT BIT31 + // FIXME: Where to put this? // // PcdImageLoaderAlignmentPolicy bits. @@ -186,7 +197,8 @@ RETURN_STATUS PeCoffInitializeContext ( OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UINT8 ImageOrigin ); /** diff --git a/MdePkg/Include/Library/UefiImageLib.h b/MdePkg/Include/Library/UefiImageLib.h index 957b7f17be..45a4423675 100644 --- a/MdePkg/Include/Library/UefiImageLib.h +++ b/MdePkg/Include/Library/UefiImageLib.h @@ -149,7 +149,8 @@ UefiImageInitializeContextPreHash ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, IN UINT32 FileSize, - IN UEFI_IMAGE_SOURCE Source + IN UEFI_IMAGE_SOURCE Source, + IN UINT8 ImageOrigin ); RETURN_STATUS @@ -168,7 +169,9 @@ UefiImageInitializeContextPostHash ( @param[out] Context The context describing the Image. @param[in] FileBuffer The file data to parse as UEFI Image. @param[in] FileSize The size, in Bytes, of FileBuffer. - + @param[in] Source Determines supported loaders (PE/UE). + @param[in] ImageOrigin Determines image protection policy. + @retval RETURN_SUCCESS The Image context has been initialised successfully. @retval other The file data is malformed. **/ @@ -177,7 +180,8 @@ UefiImageInitializeContext ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, IN UINT32 FileSize, - IN UEFI_IMAGE_SOURCE Source + IN UEFI_IMAGE_SOURCE Source, + IN UINT8 ImageOrigin ); /** @@ -671,7 +675,8 @@ UefiImageLoaderGetImageRecord ( RETURN_STATUS UefiImageDebugLocateImage ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address + IN UINTN Address, + IN UINT8 ImageOrigin ); /** diff --git a/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf index 95cfb62beb..57dcf57438 100644 --- a/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf +++ b/MdePkg/Library/BasePeCoffLib2/BasePeCoffLib2.inf @@ -46,3 +46,4 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask gEfiMdePkgTokenSpaceGuid.PcdImageLoaderRemoveXForWX + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy diff --git a/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c index 897b168fdd..ccac007595 100644 --- a/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c +++ b/MdePkg/Library/BasePeCoffLib2/PeCoffInit.c @@ -339,7 +339,8 @@ STATIC RETURN_STATUS InternalInitializePe ( IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UINT8 ImageOrigin ) { BOOLEAN Overflow; @@ -356,6 +357,7 @@ InternalInitializePe ( UINT32 NumberOfRvaAndSizes; RETURN_STATUS Status; UINT32 StartAddress; + UINT32 Policy; ASSERT (Context != NULL); ASSERT (sizeof (EFI_IMAGE_NT_HEADERS_COMMON_HDR) + sizeof (UINT16) <= FileSize - Context->ExeHdrOffset); @@ -479,6 +481,26 @@ InternalInitializePe ( DEBUG_RAISE (); return RETURN_VOLUME_CORRUPTED; } + // + // Apply image protection policy + // + if (Context->SectionAlignment < EFI_PAGE_SIZE) { + Policy = PcdGet32 (PcdImageProtectionPolicy); + // + // Images, which are less than 4KB aligned, won't be loaded, if policy demands. + // + if ((Policy & (1U << ImageOrigin)) != 0) { + // + // Such an image from firmware volume will stop boot process, if policy orders. + // + if (((Policy & PCD_IMAGE_PROTECTION_POLICY_FV_STOP_BOOT) != 0) + && (ImageOrigin == UefiImageOriginFv)) { + return RETURN_SECURITY_VIOLATION; + } + + return RETURN_NOT_STARTED; + } + } STATIC_ASSERT ( sizeof (EFI_IMAGE_DATA_DIRECTORY) <= MAX_UINT32 / EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES, @@ -649,7 +671,8 @@ RETURN_STATUS PeCoffInitializeContext ( OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -711,7 +734,7 @@ PeCoffInitializeContext ( // // Verify the PE Image Header is well-formed. // - Status = InternalInitializePe (Context, FileSize); + Status = InternalInitializePe (Context, FileSize, ImageOrigin); if (Status != RETURN_SUCCESS) { return Status; } diff --git a/MdePkg/Library/BaseUefiImageLib/CommonSupport.c b/MdePkg/Library/BaseUefiImageLib/CommonSupport.c index 9355719ec2..154b867822 100644 --- a/MdePkg/Library/BaseUefiImageLib/CommonSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/CommonSupport.c @@ -19,7 +19,8 @@ UefiImageInitializeContext ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, IN UINT32 FileSize, - IN UEFI_IMAGE_SOURCE Source + IN UEFI_IMAGE_SOURCE Source, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -28,7 +29,8 @@ UefiImageInitializeContext ( Context, FileBuffer, FileSize, - Source + Source, + ImageOrigin ); if (RETURN_ERROR (Status)) { return Status; diff --git a/MdePkg/Library/BaseUefiImageLib/PeSupport.c b/MdePkg/Library/BaseUefiImageLib/PeSupport.c index 27dff54b7f..aa027d343d 100644 --- a/MdePkg/Library/BaseUefiImageLib/PeSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/PeSupport.c @@ -27,10 +27,11 @@ RETURN_STATUS UefiImageInitializeContextPreHashPe ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UINT8 ImageOrigin ) { - return PeCoffInitializeContext (&Context->Ctx.Pe, FileBuffer, FileSize); + return PeCoffInitializeContext (&Context->Ctx.Pe, FileBuffer, FileSize, ImageOrigin); } BOOLEAN @@ -528,7 +529,8 @@ InternalDebugLocateImage ( OUT PE_COFF_LOADER_IMAGE_CONTEXT *Context, IN CHAR8 *Buffer, IN UINTN Address, - IN BOOLEAN Recurse + IN BOOLEAN Recurse, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -557,7 +559,8 @@ InternalDebugLocateImage ( Status = PeCoffInitializeContext ( Context, Buffer, - MAX_UINT32 + MAX_UINT32, + ImageOrigin ); if (RETURN_ERROR (Status)) { continue; @@ -576,7 +579,8 @@ InternalDebugLocateImage ( &DosContext, Buffer - 4, Address, - TRUE + TRUE, + ImageOrigin ); if (!RETURN_ERROR (DosStatus)) { Buffer = DosContext.ImageBuffer; @@ -611,7 +615,8 @@ InternalDebugLocateImage ( RETURN_STATUS UefiImageDebugLocateImagePe ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address + IN UINTN Address, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -641,7 +646,8 @@ UefiImageDebugLocateImagePe ( &Context->Ctx.Pe, (CHAR8 *) (Address & ~(UINTN) 3U), Address, - FALSE + FALSE, + ImageOrigin ); DEBUG_CODE_END (); @@ -710,7 +716,7 @@ UefiImageDebugPrintSegmentsPe ( Name = Sections[SectionIndex].Name; DEBUG (( DEBUG_VERBOSE, - " Section - '%c%c%c%c%c%c%c%c'\n", + " Section - '%c%c%c%c%c%c%c%c'\n" " VirtualSize - 0x%08x\n" " VirtualAddress - 0x%08x\n" " SizeOfRawData - 0x%08x\n" diff --git a/MdePkg/Library/BaseUefiImageLib/UeSupport.c b/MdePkg/Library/BaseUefiImageLib/UeSupport.c index 3e7c35d1ce..04a2f0d5fc 100644 --- a/MdePkg/Library/BaseUefiImageLib/UeSupport.c +++ b/MdePkg/Library/BaseUefiImageLib/UeSupport.c @@ -37,7 +37,8 @@ RETURN_STATUS UefiImageInitializeContextPreHashUe ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UINT8 ImageOrigin ) { return UeInitializeContextPreHash (&Context->Ctx.Ue, FileBuffer, FileSize); @@ -433,7 +434,8 @@ UefiImageLoaderGetImageRecordUe ( RETURN_STATUS UefiImageDebugLocateImageUe ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address + IN UINTN Address, + IN UINT8 ImageOrigin ) { ASSERT (Context != NULL); diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h b/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h index da64c5c462..88056571e7 100644 --- a/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h +++ b/MdePkg/Library/BaseUefiImageLib/UefiImageFormat.h @@ -18,7 +18,8 @@ RETURN_STATUS (*UEFI_IMAGE_INITIALIZE_CONTEXT_PRE_HASH) ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, - IN UINT32 FileSize + IN UINT32 FileSize, + IN UINT8 ImageOrigin ); typedef @@ -192,7 +193,8 @@ typedef RETURN_STATUS (*UEFI_IMAGE_DEBUG_LOCATE_IMAGE) ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address + IN UINTN Address, + IN UINT8 ImageOrigin ); typedef diff --git a/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c b/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c index 9739e50b29..9596b1102a 100644 --- a/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c +++ b/MdePkg/Library/BaseUefiImageLib/UefiImageLib.c @@ -91,7 +91,8 @@ InternalInitializeContextPreHash ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, IN UINT32 FileSize, - IN UINT8 FormatIndex + IN UINT8 FormatIndex, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -102,7 +103,8 @@ InternalInitializeContextPreHash ( InitializeContextPreHash, Context, FileBuffer, - FileSize + FileSize, + ImageOrigin ); return Status; @@ -113,7 +115,8 @@ UefiImageInitializeContextPreHash ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, IN CONST VOID *FileBuffer, IN UINT32 FileSize, - IN UEFI_IMAGE_SOURCE Source + IN UEFI_IMAGE_SOURCE Source, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -144,7 +147,8 @@ UefiImageInitializeContextPreHash ( Context, FileBuffer, FileSize, - UefiImageFormatUe + UefiImageFormatUe, + ImageOrigin ); if (!RETURN_ERROR (Status)) { Context->FormatIndex = UefiImageFormatUe; @@ -156,7 +160,8 @@ UefiImageInitializeContextPreHash ( Context, FileBuffer, FileSize, - UefiImageFormatPe + UefiImageFormatPe, + ImageOrigin ); if (!RETURN_ERROR (Status)) { Context->FormatIndex = UefiImageFormatPe; @@ -624,7 +629,8 @@ UefiImageLoaderGetImageRecord ( RETURN_STATUS UefiImageDebugLocateImage ( OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context, - IN UINTN Address + IN UINTN Address, + IN UINT8 ImageOrigin ) { RETURN_STATUS Status; @@ -634,7 +640,8 @@ UefiImageDebugLocateImage ( Context->FormatIndex, DebugLocateImage, Context, - Address + Address, + ImageOrigin ); return Status; diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index e74ae4d953..ed3b85cf3e 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -2385,6 +2385,27 @@ # @Prompt Supported UEFI image file formats inside FVs. gEfiMdePkgTokenSpaceGuid.PcdUefiImageFormatSupportFv|0x01|UINT8|0x40002001 + ## Set image protection policy. The policy is applied for each source individually. + # If a bit is set, aligned images from this source will be protected and + # unaligned images won't be loaded. Image protection means that + # the code section becomes read-only, and the data section becomes non-executable.
+ # If a bit is cleared, both aligned and unaligned images from this source will + # be loaded but protection will be applied only to aligned images.
+ # Image is aligned, if its SectionAlignment is a power of 2 and >= 4KB.
+ # If BIT31 is set, unaligned image from firmware volume will stop boot process.
+ # If BIT31 is cleared, unaligned images from firmware volume will be ignored.
+ # + # BIT0 - Images from firmware volume.
+ # BIT1 - Images from option ROM.
+ # BIT2 - Images supplied by user.
+ #
+ # BIT31 - Firmware volume policy.
+ # BIT30 - Turn off protection for images from firmware volume.
+ # BIT29 - Turn off protection for images from option ROM.
+ # BIT28 - Turn off protection for images supplied by user.
+ # @Prompt Set image protection policy. + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000007|UINT32|0x40002002 + [PcdsFixedAtBuild,PcdsPatchableInModule] ## Indicates the maximum length of unicode string used in the following # BaseLib functions: StrLen(), StrSize(), StrCmp(), StrnCmp(), StrCpy(), StrnCpy()

diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc index 4b43bce448..f9774c10dd 100644 --- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc +++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc @@ -482,6 +482,7 @@ # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF40 gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !else # Allow execution of EfiConventionalMemory and EfiBootServicesData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF45 diff --git a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf index 585d504637..49025f3063 100644 --- a/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf +++ b/OvmfPkg/Library/PeilessStartupLib/PeilessStartupLib.inf @@ -78,7 +78,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 12e94a4e57..129e155c44 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -590,10 +590,11 @@ # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF40 gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !elseif $(WINDOWS_10_IA32) == TRUE # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiRuntimeServicesData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF04 - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x0 + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x70000000 !endif # diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 6835e78181..6919357a14 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -564,7 +564,6 @@ gUefiCpuPkgTokenSpaceGuid.PcdFirstTimeWakeUpAPsBySipi|FALSE gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementPropertyMask|0x1 - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 # # Firmware volume supports UE, and may require PE. @@ -609,10 +608,7 @@ # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF40 gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE - !elseif $(WINDOWS_10_IA32) == TRUE - # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiRuntimeServicesData memory regions. - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF04 - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x0 + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !endif ################################################################################ diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 9019052a90..f72ca4e95e 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -623,6 +623,7 @@ # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiLoaderData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF40 gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !endif # diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc index 19a1dcc436..79e0a000c0 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc +++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc @@ -270,12 +270,6 @@ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20 gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0 - # - # Enable strict image permissions for all images. (This applies - # only to images that were built with >= 4 KB section alignment.) - # - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x3 - # # Enable NX memory protection for all non-code regions, including OEM and OS # reserved ones, with the exception of LoaderData regions, of which OS loaders diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c index c3bf9d3995..d3f3baf31c 100644 --- a/OvmfPkg/Sec/SecMain.c +++ b/OvmfPkg/Sec/SecMain.c @@ -728,7 +728,8 @@ FindAndReportEntryPoints ( &ImageContext, (VOID *) (UINTN) SecCoreImageBase, SecCoreImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); @@ -744,7 +745,8 @@ FindAndReportEntryPoints ( &ImageContext, (VOID *) (UINTN) PeiCoreImageBase, PeiCoreImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); diff --git a/OvmfPkg/Tcg/TdTcg2Dxe/MeasureBootPeCoff.c b/OvmfPkg/Tcg/TdTcg2Dxe/MeasureBootPeCoff.c index e6e372b6b6..68ebd9ad97 100644 --- a/OvmfPkg/Tcg/TdTcg2Dxe/MeasureBootPeCoff.c +++ b/OvmfPkg/Tcg/TdTcg2Dxe/MeasureBootPeCoff.c @@ -131,7 +131,13 @@ MeasurePeImageAndExtend ( // // Get information about the image being loaded // - Status = UefiImageInitializeContext (&ImageContext, (VOID *) (UINTN) ImageAddress, ImageSize); + Status = UefiImageInitializeContext ( + &ImageContext, + (VOID *)(UINTN)ImageAddress, + (UINT32)ImageSize, + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv + ); if (EFI_ERROR (Status)) { // // The information can't be got from the invalid PeImage diff --git a/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootUefiImage.c b/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootUefiImage.c index 34e87d84e1..338e603c33 100644 --- a/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootUefiImage.c +++ b/SecurityPkg/Tcg/Tcg2Dxe/MeasureBootUefiImage.c @@ -78,7 +78,8 @@ MeasureUefiImageAndExtend ( &ImageContext, (VOID *) (UINTN) ImageAddress, (UINT32) ImageSize, - UEFI_IMAGE_SOURCE_ALL + UEFI_IMAGE_SOURCE_ALL, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { // diff --git a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c index e1c81acb9f..402e4a2f03 100644 --- a/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c +++ b/SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c @@ -1992,7 +1992,8 @@ EnrollImageSignatureToSigDB ( &ImageContext, ImageBase, (UINT32)ImageSize, - UEFI_IMAGE_SOURCE_NON_FV + UEFI_IMAGE_SOURCE_NON_FV, + UefiImageOriginOptionROM ); if (EFI_ERROR (Status)) { goto ON_EXIT; diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c index 6c109f6353..65cc52b827 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuException.c @@ -239,7 +239,7 @@ GetImageInfoByIp ( UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UINT32 PdbPathSize; - Status = UefiImageDebugLocateImage (&ImageContext, CurrentEip); + Status = UefiImageDebugLocateImage (&ImageContext, CurrentEip, UefiImageOriginFv); if (RETURN_ERROR (Status)) { return FALSE; } diff --git a/UefiCpuPkg/SecCore/FindPeiCore.c b/UefiCpuPkg/SecCore/FindPeiCore.c index a5d1686fc2..2b73c07880 100644 --- a/UefiCpuPkg/SecCore/FindPeiCore.c +++ b/UefiCpuPkg/SecCore/FindPeiCore.c @@ -173,7 +173,8 @@ FindAndReportEntryPoints ( &ImageContext, (VOID*) (UINTN) SecCoreImageBase, SecCoreImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); @@ -200,7 +201,8 @@ FindAndReportEntryPoints ( &ImageContext, (VOID*)(UINTN)PeiCoreImageBase, PeiCoreImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); ASSERT_EFI_ERROR (Status); diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c index b2baac1105..9d569e88bb 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c @@ -40,7 +40,8 @@ LoadUefiImage ( &ImageContext, UefiImage, UefiImageSize, - UEFI_IMAGE_SOURCE_FV + UEFI_IMAGE_SOURCE_FV, + UefiImageOriginFv ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf index 5d7b2acf8c..d2a5cb42d6 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.inf @@ -95,6 +95,6 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate ## PRODUCES diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf index b978ad606a..21ccb19b49 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf @@ -82,4 +82,4 @@ gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## SOMETIMES_CONSUMES From 0d9d6f987be6d03ac229244feacc0dbd7b80fcb2 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 22 Jul 2024 13:51:38 +0300 Subject: [PATCH 089/341] Fixed compilation of all packages tracked by CI after rebasing upon edk2-stable202311. --- BaseTools/Conf/tools_def.template | 1 - BaseTools/Source/C/Common/Decompress.c | 5 -- BaseTools/Source/C/Common/WinNtInclude.h | 76 +++++++++++++++++++ BaseTools/Source/C/GenFfs/GenFfs.c | 3 - BaseTools/Source/C/GenFv/GenFvInternalLib.c | 2 +- BaseTools/Source/C/GenSec/GenSec.c | 4 +- BaseTools/Source/C/Include/Common/BaseTypes.h | 4 - CryptoPkg/Library/IntrinsicLib/CopyMem.c | 8 ++ .../Library/IntrinsicLib/IntrinsicLib.inf | 8 +- .../FspmWrapperPeim/FspmWrapperPeim.inf | 1 - .../FspsWrapperPeim/FspsWrapperPeim.inf | 1 - .../UsbNetwork/NetworkCommon/PxeFunction.c | 2 +- MdeModulePkg/MdeModulePkg.dsc | 3 +- .../RegularExpressionDxe.inf | 2 +- MdePkg/Include/IndustryStandard/PeImage2.h | 2 + MdePkg/Library/BaseFdtLib/BaseFdtLib.inf | 2 +- NetworkPkg/NetworkPkg.dsc | 1 + OvmfPkg/Library/PlatformInitLib/IntelTdx.c | 1 + OvmfPkg/OvmfPkgIa32X64.dsc | 1 + OvmfPkg/OvmfPkgX64.dsc | 1 + OvmfPkg/VirtioSerialDxe/VirtioSerial.inf | 3 + .../VariablePolicy.c | 23 +----- SourceLevelDebugPkg/SourceLevelDebugPkg.dsc | 1 - UefiCpuPkg/SecCore/SecCore.inf | 1 - UefiCpuPkg/SecCore/SecMain.h | 1 - UefiPayloadPkg/UefiPayloadPkg.dsc | 1 + 26 files changed, 105 insertions(+), 53 deletions(-) create mode 100644 BaseTools/Source/C/Common/WinNtInclude.h diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index 5a201f30a9..d900b39dc5 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -1527,7 +1527,6 @@ DEFINE CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_TARGET) DEF *_CLANGDWARF_RISCV64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wl,--defsym=PECOFF_HEADER_SIZE=0x240 *_CLANGDWARF_RISCV64_PLATFORM_FLAGS = *_CLANGDWARF_RISCV64_PP_FLAGS = DEF(GCC_PP_FLAGS) DEF(CLANGDWARF_RISCV64_TARGET) $(PLATFORM_FLAGS) -*_CLANGDWARF_RISCV64_RC_FLAGS = DEF(GCC_RISCV64_RC_FLAGS) *_CLANGDWARF_RISCV64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGDWARF_RISCV64_TARGET) $(PLATFORM_FLAGS) *_CLANGDWARF_RISCV64_ASLPP_FLAGS = DEF(GCC_ASLPP_FLAGS) DEF(CLANGDWARF_RISCV64_TARGET) *_CLANGDWARF_RISCV64_CC_SECPEIFLAGS = DEF(GCC_RISCV64_CC_SECPEIFLAGS) diff --git a/BaseTools/Source/C/Common/Decompress.c b/BaseTools/Source/C/Common/Decompress.c index 0cf0c4a0a8..1b2f40d42b 100644 --- a/BaseTools/Source/C/Common/Decompress.c +++ b/BaseTools/Source/C/Common/Decompress.c @@ -15,9 +15,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent // // Decompression algorithm begins here // -#ifndef UINT8_MAX -#define UINT8_MAX 0xff -#endif #define BITBUFSIZ 32 #define MAXMATCH 256 #define THRESHOLD 3 @@ -901,5 +898,3 @@ Extract ( return Status; } - - diff --git a/BaseTools/Source/C/Common/WinNtInclude.h b/BaseTools/Source/C/Common/WinNtInclude.h new file mode 100644 index 0000000000..c549dc7d73 --- /dev/null +++ b/BaseTools/Source/C/Common/WinNtInclude.h @@ -0,0 +1,76 @@ +/** @file +Include file for the WinNt Library + +Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __WIN_NT_INCLUDE_H__ +#define __WIN_NT_INCLUDE_H__ + +#define GUID _WINNT_DUP_GUID_____ +#define _LIST_ENTRY _WINNT_DUP_LIST_ENTRY_FORWARD +#define LIST_ENTRY _WINNT_DUP_LIST_ENTRY + +#if (_MSC_VER < 1800) +#define InterlockedIncrement _WINNT_DUP_InterlockedIncrement +#define InterlockedDecrement _WINNT_DUP_InterlockedDecrement +#define InterlockedCompareExchange64 _WINNT_DUP_InterlockedCompareExchange64 +#endif + +#undef UNALIGNED +#undef CONST +#undef VOID + +#ifndef __GNUC__ +#include "windows.h" + +// +// Win32 include files do not compile clean with /W4, so we use the warning +// pragma to suppress the warnings for Win32 only. This way our code can still +// compile at /W4 (highest warning level) with /WX (warnings cause build +// errors). +// +#pragma warning(disable : 4115) +#pragma warning(disable : 4201) +#pragma warning(disable : 4214) +#pragma warning(disable : 4028) +#pragma warning(disable : 4133) + +// +// Set the warnings back on as the EFI code must be /W4. +// +#pragma warning(default : 4115) +#pragma warning(default : 4201) + +#endif + +#undef GUID +#undef _LIST_ENTRY +#undef LIST_ENTRY +#undef InterlockedIncrement +#undef InterlockedDecrement +#undef InterlockedCompareExchange64 +#undef InterlockedCompareExchangePointer + +#define VOID void + +// +// Prevent collisions with Windows API name macros that deal with Unicode/Not issues +// +#undef LoadImage +#undef CreateEvent + +// +// FAR is used as a struct member name by DebugSupport.h. +// +#undef FAR + +// +// These two macros collide with re-definitions and case labels. +// +#undef ERROR +#undef MAX_PATH + +#endif diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c index d38b39236a..12f9641ed8 100644 --- a/BaseTools/Source/C/GenFfs/GenFfs.c +++ b/BaseTools/Source/C/GenFfs/GenFfs.c @@ -9,9 +9,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "WinNtInclude.h" #ifndef __GNUC__ -#define RUNTIME_FUNCTION _WINNT_DUP_RUNTIME_FUNCTION -#include -#undef RUNTIME_FUNCTION #include #include #include diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index 2756cc65cc..411ec2d4e1 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -3604,7 +3604,7 @@ Routine Description: Machine = UefiImageGetMachine (&ImageContext); if ( (Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) || - (Machine == IMAGE_FILE_MACHINE_AARCH64) ) { + (Machine == IMAGE_FILE_MACHINE_ARM64) ) { mArm = TRUE; } diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c index 3965f9bdac..01383c9530 100644 --- a/BaseTools/Source/C/GenSec/GenSec.c +++ b/BaseTools/Source/C/GenSec/GenSec.c @@ -5,12 +5,10 @@ Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ + #include "WinNtInclude.h" #ifndef __GNUC__ -#define RUNTIME_FUNCTION _WINNT_DUP_RUNTIME_FUNCTION -#include -#undef RUNTIME_FUNCTION #include #include #include diff --git a/BaseTools/Source/C/Include/Common/BaseTypes.h b/BaseTools/Source/C/Include/Common/BaseTypes.h index f81449c91b..95b87498b7 100644 --- a/BaseTools/Source/C/Include/Common/BaseTypes.h +++ b/BaseTools/Source/C/Include/Common/BaseTypes.h @@ -13,10 +13,6 @@ #ifndef __BT_BASE_TYPES_H__ #define __BT_BASE_TYPES_H__ -// -// To be able to safely include Windows headers, we need to include -// WinNtInclude.h first. -// #include "WinNtInclude.h" #include diff --git a/CryptoPkg/Library/IntrinsicLib/CopyMem.c b/CryptoPkg/Library/IntrinsicLib/CopyMem.c index 14a213d1da..530d092c8b 100644 --- a/CryptoPkg/Library/IntrinsicLib/CopyMem.c +++ b/CryptoPkg/Library/IntrinsicLib/CopyMem.c @@ -44,4 +44,12 @@ memcpy ( return CopyMem (dest, src, (UINTN)count); } +void +__bzero ( + void *src, + unsigned int count + ) +{ + ZeroMem (src, count); +} #endif diff --git a/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf b/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf index 8602a513b0..80aead02fa 100644 --- a/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf +++ b/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf @@ -23,10 +23,9 @@ [Sources] MemoryIntrinsics.c - -[Sources.IA32] CopyMem.c +[Sources.IA32] Ia32/MathDivU64xU64Rem.c | MSFT Ia32/MathLShiftS64.c | MSFT Ia32/MathRShiftU64.c | MSFT @@ -36,7 +35,6 @@ Ia32/MathUlldiv.asm | MSFT Ia32/MathUlldvrm.asm | MSFT Ia32/MathLldiv.asm | MSFT - Ia32/MathUllrem.asm | MSFT Ia32/MathDivU64xU64Rem.c | INTEL Ia32/MathLShiftS64.c | INTEL @@ -49,10 +47,6 @@ Ia32/MathDivS64x64.c | GCC Ia32/MathDivU64x64.c | GCC Ia32/MathModU64x64.c | GCC -[Sources.X64] - CopyMem.c -[Sources.RISCV64] - CopyMem.c [Packages] MdePkg/MdePkg.dec diff --git a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf index 6b0b422773..39b0d810b4 100644 --- a/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf +++ b/IntelFsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf @@ -38,7 +38,6 @@ FspWrapperPlatformLib FspWrapperHobProcessLib CpuLib - UefiCpuLib UefiImageExtraActionLib PerformanceLib TimerLib diff --git a/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf index bc5be2f4cc..e9a8a19532 100644 --- a/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf +++ b/IntelFsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf @@ -39,7 +39,6 @@ FspWrapperPlatformLib FspWrapperHobProcessLib CpuLib - UefiCpuLib UefiImageExtraActionLib PerformanceLib FspWrapperApiLib diff --git a/MdeModulePkg/Bus/Usb/UsbNetwork/NetworkCommon/PxeFunction.c b/MdeModulePkg/Bus/Usb/UsbNetwork/NetworkCommon/PxeFunction.c index 62df4e92ea..049618b6c6 100644 --- a/MdeModulePkg/Bus/Usb/UsbNetwork/NetworkCommon/PxeFunction.c +++ b/MdeModulePkg/Bus/Usb/UsbNetwork/NetworkCommon/PxeFunction.c @@ -760,7 +760,7 @@ UndiReceiveFilter ( Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED; } - if ((Cdb->CPBsize == 0)) { + if (Cdb->CPBsize == 0) { Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED; } } diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 55f83dde5a..4efb102874 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -107,6 +107,7 @@ VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf IpmiCommandLib|MdeModulePkg/Library/BaseIpmiCommandLibNull/BaseIpmiCommandLibNull.inf SpiHcPlatformLib|MdeModulePkg/Library/BaseSpiHcPlatformLibNull/BaseSpiHcPlatformLibNull.inf + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf [LibraryClasses.EBC.PEIM] IoLib|MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf @@ -132,10 +133,10 @@ CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf - UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf + CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf [LibraryClasses.IA32.DXE_CORE] CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf diff --git a/MdeModulePkg/Universal/RegularExpressionDxe/RegularExpressionDxe.inf b/MdeModulePkg/Universal/RegularExpressionDxe/RegularExpressionDxe.inf index 04149b19c6..8d91355507 100644 --- a/MdeModulePkg/Universal/RegularExpressionDxe/RegularExpressionDxe.inf +++ b/MdeModulePkg/Universal/RegularExpressionDxe/RegularExpressionDxe.inf @@ -127,7 +127,7 @@ # Onigurama: corrects build for llvm-15 CLANGPDB:*_*_*_CC_FLAGS = -Wno-deprecated-non-prototype - CLANGGCC:*_*_*_CC_FLAGS = -Wno-deprecated-non-prototype + GCC:*_CLANGDWARF_*_CC_FLAGS = -Wno-deprecated-non-prototype # Not add -Wno-error=maybe-uninitialized option for XCODE # XCODE doesn't know this option diff --git a/MdePkg/Include/IndustryStandard/PeImage2.h b/MdePkg/Include/IndustryStandard/PeImage2.h index 29c4e706e5..c17104722d 100644 --- a/MdePkg/Include/IndustryStandard/PeImage2.h +++ b/MdePkg/Include/IndustryStandard/PeImage2.h @@ -40,6 +40,8 @@ #define IMAGE_FILE_MACHINE_RISCV32 0x5032 #define IMAGE_FILE_MACHINE_RISCV64 0x5064 #define IMAGE_FILE_MACHINE_RISCV128 0x5128 +#define IMAGE_FILE_MACHINE_LOONGARCH32 0x6232 +#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // // EXE file formats diff --git a/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf b/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf index b5815380c5..a850816042 100644 --- a/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf +++ b/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf @@ -62,4 +62,4 @@ # in BaseFdtLib\libfdt\libfdt\fdt_rw.c (wait for sub module update to remove this) MSFT:*_*_IA32_CC_FLAGS = /wd4146 /wd4245 /wd4706 MSFT:*_*_X64_CC_FLAGS = /wd4146 /wd4244 /wd4245 /wd4267 /wd4706 - + XCODE:*_*_X64_CC_FLAGS = -U__APPLE__ diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc index 6880255c9f..9488a9b384 100644 --- a/NetworkPkg/NetworkPkg.dsc +++ b/NetworkPkg/NetworkPkg.dsc @@ -35,6 +35,7 @@ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf UefiLib|MdePkg/Library/UefiLib/UefiLib.inf UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c index 12e4501c5b..79b822985e 100644 --- a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c +++ b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 6919357a14..ed2d12e42e 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -331,6 +331,7 @@ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf + CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index f72ca4e95e..40e76a68e1 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -353,6 +353,7 @@ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf + CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf diff --git a/OvmfPkg/VirtioSerialDxe/VirtioSerial.inf b/OvmfPkg/VirtioSerialDxe/VirtioSerial.inf index d63a08b928..c852385cdd 100644 --- a/OvmfPkg/VirtioSerialDxe/VirtioSerial.inf +++ b/OvmfPkg/VirtioSerialDxe/VirtioSerial.inf @@ -38,3 +38,6 @@ [Protocols] gVirtioDeviceProtocolGuid ## TO_START gEfiSerialIoProtocolGuid + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /wd4204 diff --git a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.c b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.c index ed991be4ed..6d019746a1 100644 --- a/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.c +++ b/ShellPkg/DynamicCommand/VariablePolicyDynamicCommand/VariablePolicy.c @@ -859,32 +859,15 @@ InitializeHiiPackage ( IN EFI_HANDLE ImageHandle ) { - EFI_STATUS Status; - EFI_HII_PACKAGE_LIST_HEADER *PackageList; - EFI_HII_HANDLE HiiHandle; - - // - // Retrieve HII package list from ImageHandle - // - Status = gBS->OpenProtocol ( - ImageHandle, - &gEfiHiiPackageListProtocolGuid, - (VOID **)&PackageList, - ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - return NULL; - } + EFI_STATUS Status; + EFI_HII_HANDLE HiiHandle; // // Publish HII package list to HII Database. // Status = gHiiDatabase->NewPackageList ( gHiiDatabase, - PackageList, + &gModuleHiiPackageList->Header, NULL, &HiiHandle ); diff --git a/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc b/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc index 744b9527b4..11870b8ae6 100644 --- a/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc +++ b/SourceLevelDebugPkg/SourceLevelDebugPkg.dsc @@ -35,7 +35,6 @@ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf - UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf UefiImageExtraActionLib|SourceLevelDebugPkg/Library/UefiImageExtraActionLibDebug/UefiImageExtraActionLibDebug.inf TimerLib|UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf diff --git a/UefiCpuPkg/SecCore/SecCore.inf b/UefiCpuPkg/SecCore/SecCore.inf index 7d3a80cf04..7c8fccb2d6 100644 --- a/UefiCpuPkg/SecCore/SecCore.inf +++ b/UefiCpuPkg/SecCore/SecCore.inf @@ -48,7 +48,6 @@ PcdLib DebugAgentLib CpuLib - UefiCpuLib UefiImageExtraActionLib CpuExceptionHandlerLib ReportStatusCodeLib diff --git a/UefiCpuPkg/SecCore/SecMain.h b/UefiCpuPkg/SecCore/SecMain.h index f26d337843..fb2537998b 100644 --- a/UefiCpuPkg/SecCore/SecMain.h +++ b/UefiCpuPkg/SecCore/SecMain.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 8eab1e00d8..4a6b647877 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -383,6 +383,7 @@ !endif CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf + CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf [LibraryClasses.common.DXE_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf From 0146e644f0e6aa9dda7f211119a01296acec52e9 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Wed, 27 Mar 2024 10:44:24 +0300 Subject: [PATCH 090/341] BaseTools: Provide fat Mach-O binaries on Darwin Merge pull request #63 from acidanthera/vit9696-fattools-20240327 --- BaseTools/Source/C/Makefiles/header.makefile | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/BaseTools/Source/C/Makefiles/header.makefile b/BaseTools/Source/C/Makefiles/header.makefile index c32243cab4..5c643324e5 100644 --- a/BaseTools/Source/C/Makefiles/header.makefile +++ b/BaseTools/Source/C/Makefiles/header.makefile @@ -125,17 +125,13 @@ ifeq ($(HOST_ARCH), X64) CPPFLAGS += "-DEFIAPI=__attribute__((ms_abi))" endif -ifeq ($(HOST_ARCH), IA32) # -# Snow Leopard is a 32-bit and 64-bit environment. uname -m returns i386, but gcc defaults -# to x86_64. So make sure tools match uname -m. You can manual have a 64-bit kernal on Snow Leopard -# so only do this is uname -m returns i386. +# Provide fat binaries on Darwin # ifeq ($(DARWIN),Darwin) - CFLAGS += -arch i386 - CPPFLAGS += -arch i386 - LDFLAGS += -arch i386 -endif + CFLAGS += -arch x86_64 -arch arm64 -mmacosx-version-min=10.9 + CPPFLAGS += -arch x86_64 -arch arm64 -mmacosx-version-min=10.9 + EXTRA_LDFLAGS += -arch x86_64 -arch arm64 -mmacosx-version-min=10.9 endif CFLAGS += -DUEFI_IMAGE_FORMAT_SUPPORT_SOURCES=0x02 From b89875486ae5af53c001c1bcafc1b2344c9c9c70 Mon Sep 17 00:00:00 2001 From: Mike Beaton Date: Tue, 16 Apr 2024 12:49:16 +0100 Subject: [PATCH 091/341] BaseTools: Enable symbolic debugging with LTO in XCODE toolchain (#64) --- BaseTools/Conf/build_rule.template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BaseTools/Conf/build_rule.template b/BaseTools/Conf/build_rule.template index c925098211..62b11dd83b 100755 --- a/BaseTools/Conf/build_rule.template +++ b/BaseTools/Conf/build_rule.template @@ -308,7 +308,7 @@ "$(DLINK)" -o ${dst} $(DLINK_FLAGS) -Wl,--start-group,@$(STATIC_LIBRARY_FILES_LIST),--end-group $(CC_FLAGS) $(DLINK2_FLAGS) - "$(DLINK)" $(DLINK_FLAGS) -o ${dst} $(DLINK_SPATH) -filelist $(STATIC_LIBRARY_FILES_LIST) $(DLINK2_FLAGS) + "$(DLINK)" $(DLINK_FLAGS) -o ${dst} -object_path_lto ${dst}.lto $(DLINK_SPATH) -filelist $(STATIC_LIBRARY_FILES_LIST) $(DLINK2_FLAGS) [Static-Library-File.SEC, Static-Library-File.PEI_CORE, Static-Library-File.PEIM] @@ -346,7 +346,7 @@ "$(DLINK)" $(DLINK_FLAGS) -Wl,--start-group,@$(STATIC_LIBRARY_FILES_LIST),--end-group $(CC_FLAGS) $(DLINK2_FLAGS) - "$(DLINK)" -o ${dst} $(DLINK_FLAGS) $(DLINK_SPATH) -filelist $(STATIC_LIBRARY_FILES_LIST) $(DLINK2_FLAGS) + "$(DLINK)" -o ${dst} -object_path_lto ${dst}.lto $(DLINK_FLAGS) $(DLINK_SPATH) -filelist $(STATIC_LIBRARY_FILES_LIST) $(DLINK2_FLAGS) [Static-Library-File.HOST_APPLICATION] From ba561ef7ff9860f9074ea209ab7f4b3bd2b4ae88 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 28 Jun 2024 11:01:20 +0300 Subject: [PATCH 092/341] Fixed compilation of all packages tracked by CI after rebasing upon edk2-stable202405 tag. --- CryptoPkg/Library/IntrinsicLib/CopyMem.c | 2 + .../MemoryAllocationLib.c | 57 ------------------- .../Spi/SpiNorFlashJedecSfdp/SpiNorFlash.c | 1 + MdeModulePkg/MdeModulePkg.dsc | 6 ++ OvmfPkg/Library/PlatformInitLib/IntelTdx.c | 1 - OvmfPkg/OvmfPkgIa32.fdf | 4 +- OvmfPkg/OvmfPkgX64.fdf | 4 +- UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c | 9 ++- UefiPayloadPkg/UefiPayloadPkg.dsc | 2 +- .../SampleUnitTestDxeExpectFail.inf | 3 + .../SampleUnitTestHostExpectFail.inf | 3 + .../SampleUnitTestPeiExpectFail.inf | 3 + .../SampleUnitTestSmmExpectFail.inf | 3 + .../SampleUnitTestUefiShellExpectFail.inf | 3 + .../SampleUnitTestDxeGenerateException.inf | 3 + .../SampleUnitTestHostGenerateException.inf | 3 + .../SampleUnitTestPeiGenerateException.inf | 3 + .../SampleUnitTestSmmGenerateException.inf | 3 + ...mpleUnitTestUefiShellGenerateException.inf | 3 + 19 files changed, 51 insertions(+), 65 deletions(-) diff --git a/CryptoPkg/Library/IntrinsicLib/CopyMem.c b/CryptoPkg/Library/IntrinsicLib/CopyMem.c index 530d092c8b..b3487db891 100644 --- a/CryptoPkg/Library/IntrinsicLib/CopyMem.c +++ b/CryptoPkg/Library/IntrinsicLib/CopyMem.c @@ -10,6 +10,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include +#if !defined (__arm__) #if defined (__clang__) && !defined (__APPLE__) /* Copies bytes between buffers */ @@ -53,3 +54,4 @@ __bzero ( ZeroMem (src, count); } #endif +#endif diff --git a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c index 24bf5142d9..253ace4e54 100644 --- a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c +++ b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c @@ -156,60 +156,3 @@ PhaseFreePool ( { // Not implemented yet } - -/** - Reallocates a buffer of type EfiBootServicesData. - - Allocates and zeros the number bytes specified by NewSize from memory of type - EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and - NewSize bytes are copied from OldBuffer to the newly allocated buffer, and - OldBuffer is freed. A pointer to the newly allocated buffer is returned. - If NewSize is 0, then a valid buffer of 0 size is returned. If there is not - enough memory remaining to satisfy the request, then NULL is returned. - - If the allocation of the new buffer is successful and the smaller of NewSize and OldSize - is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). - - @param OldSize The size, in bytes, of OldBuffer. - @param NewSize The size, in bytes, of the buffer to reallocate. - @param OldBuffer The buffer to copy to the allocated buffer. This is an optional - parameter that may be NULL. - - @return A pointer to the allocated buffer or NULL if allocation fails. - -**/ -VOID * -EFIAPI -ReallocatePool ( - IN UINTN OldSize, - IN UINTN NewSize, - IN VOID *OldBuffer OPTIONAL - ) -{ - VOID *NewBuffer; - - // Validate the OldBuffer is HobAllocated. - DEBUG_CODE_BEGIN (); - EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob; - - if (OldBuffer != NULL) { - HandOffHob = GetHobList (); - ASSERT (((EFI_PHYSICAL_ADDRESS)(UINTN)OldBuffer >= HandOffHob->EfiMemoryBottom)); - ASSERT (((EFI_PHYSICAL_ADDRESS)((UINTN)OldBuffer + OldSize) <= HandOffHob->EfiFreeMemoryBottom)); - } - - DEBUG_CODE_END (); - - // If new buffer would be smaller just return old buffer as FreePool isn't supported. - if ((OldBuffer != NULL) && (OldSize >= NewSize)) { - return OldBuffer; - } - - NewBuffer = AllocateZeroPool (NewSize); - if ((NewBuffer != NULL) && (OldBuffer != NULL)) { - CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); - FreePool (OldBuffer); - } - - return NewBuffer; -} diff --git a/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlash.c b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlash.c index 3ac5420fbf..018a2b3a4a 100644 --- a/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlash.c +++ b/MdeModulePkg/Bus/Spi/SpiNorFlashJedecSfdp/SpiNorFlash.c @@ -49,6 +49,7 @@ FillWriteBuffer ( UINT8 SfdpAddressBytes; SfdpAddressBytes = (UINT8)Instance->SfdpBasicFlash->AddressBytes; + AddressSize = 0; // Copy Opcode into Write Buffer Instance->SpiTransactionWriteBuffer[0] = Opcode; diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 4efb102874..6f01cc2cfd 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -109,6 +109,12 @@ SpiHcPlatformLib|MdeModulePkg/Library/BaseSpiHcPlatformLibNull/BaseSpiHcPlatformLibNull.inf IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf +[LibraryClasses.IA32] + AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf + +[LibraryClasses.X64] + AmdSvsmLib|OvmfPkg/Library/AmdSvsmLib/AmdSvsmLib.inf + [LibraryClasses.EBC.PEIM] IoLib|MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf diff --git a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c index 79b822985e..12e4501c5b 100644 --- a/OvmfPkg/Library/PlatformInitLib/IntelTdx.c +++ b/OvmfPkg/Library/PlatformInitLib/IntelTdx.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index 3e3476d897..f8da53e140 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -82,11 +82,11 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvm 0x010000|0x010000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize -0x020000|0x0E0000 +0x020000|0x100000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize FV = PEIFV -0x100000|0xE80000 +0x120000|0xE60000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize FV = DXEFV diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index e0cb9cc909..5202c71b39 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -103,11 +103,11 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableBase|gUefiOvmfPkgTokenSpaceGui 0x011000|0x00F000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize -0x020000|0x110000 +0x020000|0x120000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize FV = PEIFV -0x130000|0xE50000 +0x140000|0xE40000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize FV = DXEFV diff --git a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c index a75e1e2018..c8b75455ce 100644 --- a/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c +++ b/UefiCpuPkg/Library/MpInitLib/X64/AmdSev.c @@ -9,13 +9,18 @@ **/ #include "MpLib.h" -#include + #include +#include +#include + #include #include #define _IS_ALIGNED(x, y) (ALIGN_POINTER((x), (y)) == (x)) +extern EFI_HOB_PLATFORM_INFO *mPlatformInfoHob; + /** Perform the requested AP Creation action. @@ -293,7 +298,7 @@ SevSnpCreateAP ( // GuidHob = GetFirstGuidHob (&gGhcbApicIdsGuid); GhcbApicIds = (GHCB_APIC_IDS *)(*(UINTN *)GET_GUID_HOB_DATA (GuidHob)); - MaxIndex = MIN (GhcbApicIds->NumEntries, PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + MaxIndex = MIN (GhcbApicIds->NumEntries, mPlatformInfoHob->PcdCpuMaxLogicalProcessorNumber); } else { // // APs have been previously started. diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 4a6b647877..446320031f 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -22,7 +22,7 @@ SUPPORTED_ARCHITECTURES = IA32|X64 BUILD_TARGETS = DEBUG|RELEASE|NOOPT SKUID_IDENTIFIER = DEFAULT - OUTPUT_DIRECTORY = Build/UefiPayloadPkg$(BUILD_ARCH) + OUTPUT_DIRECTORY = Build/UefiPayloadPkg FLASH_DEFINITION = UefiPayloadPkg/UefiPayloadPkg.fdf PCD_DYNAMIC_AS_DYNAMICEX = TRUE diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestDxeExpectFail.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestDxeExpectFail.inf index 6757434952..5b68355c48 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestDxeExpectFail.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestDxeExpectFail.inf @@ -39,3 +39,6 @@ [Depex] TRUE + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestHostExpectFail.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestHostExpectFail.inf index dcaedbf7e4..06f3c94393 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestHostExpectFail.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestHostExpectFail.inf @@ -33,3 +33,6 @@ [Pcd] gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestPeiExpectFail.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestPeiExpectFail.inf index 763d80e532..0d5b27919f 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestPeiExpectFail.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestPeiExpectFail.inf @@ -39,3 +39,6 @@ [Depex] gEfiPeiMemoryDiscoveredPpiGuid + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestSmmExpectFail.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestSmmExpectFail.inf index d4c2f4b707..08f861cbb1 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestSmmExpectFail.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestSmmExpectFail.inf @@ -40,3 +40,6 @@ [Depex] gEfiSmmCpuProtocolGuid + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestUefiShellExpectFail.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestUefiShellExpectFail.inf index 324b4ff52e..73eb37414d 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestUefiShellExpectFail.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestExpectFail/SampleUnitTestUefiShellExpectFail.inf @@ -36,3 +36,6 @@ [Pcd] gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestDxeGenerateException.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestDxeGenerateException.inf index b742befe4d..7490f9a904 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestDxeGenerateException.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestDxeGenerateException.inf @@ -41,3 +41,6 @@ [Depex] TRUE + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestHostGenerateException.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestHostGenerateException.inf index a9f10ff184..1528209cda 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestHostGenerateException.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestHostGenerateException.inf @@ -35,3 +35,6 @@ [Pcd] gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestPeiGenerateException.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestPeiGenerateException.inf index cb26961568..f0084c5b14 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestPeiGenerateException.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestPeiGenerateException.inf @@ -41,3 +41,6 @@ [Depex] gEfiPeiMemoryDiscoveredPpiGuid + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestSmmGenerateException.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestSmmGenerateException.inf index 5aee6a52bd..ab0c60e8d0 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestSmmGenerateException.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestSmmGenerateException.inf @@ -42,3 +42,6 @@ [Depex] gEfiSmmCpuProtocolGuid + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved diff --git a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestUefiShellGenerateException.inf b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestUefiShellGenerateException.inf index 32d6f4270a..306adf1ddf 100644 --- a/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestUefiShellGenerateException.inf +++ b/UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTestGenerateException/SampleUnitTestUefiShellGenerateException.inf @@ -38,3 +38,6 @@ [Pcd] gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask + +[BuildOptions] + NOOPT_CLANGPDB_*_DLINK_FLAGS = /force:unresolved From 19ca21653362e4deb0533ce343439b1fb514510f Mon Sep 17 00:00:00 2001 From: vit9696 Date: Sun, 27 Oct 2024 04:30:33 +0300 Subject: [PATCH 093/341] MdeModulePkg/EhciDxe: Fix legacy handoff logic references acidanthera/bugtracker#2436 --- MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c index 912048eee9..fadb25652a 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c +++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c @@ -309,6 +309,17 @@ EhcClearLegacySupport ( PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value); PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap + 0x4, 1, &Value); + // + // Disable the SMI in USBLEGCTLSTS firstly + // Not doing this may result in a hardlock soon after + // + PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap + 0x4, 1, &Value); + Value &= 0xFFFF0000; + PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, ExtendCap + 0x4, 1, &Value); + + // + // Get EHCI Ownership from legacy bios + // PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value); Value |= (0x1 << 24); PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value); From 9cdba17a1ac5300c548846f2e698ee43d1d60174 Mon Sep 17 00:00:00 2001 From: Mike Beaton Date: Sat, 7 Sep 2024 20:51:50 +0100 Subject: [PATCH 094/341] IntrinsicLib: Move from CryptoPkg to MdePkg --- ArmVirtPkg/ArmVirt.dsc.inc | 2 +- CryptoPkg/CryptoPkg.dsc | 3 +-- CryptoPkg/CryptoPkgMbedTls.dsc | 2 +- CryptoPkg/Readme.md | 16 ++++++++-------- EmulatorPkg/EmulatorPkg.dsc | 2 +- FmpDevicePkg/FmpDevicePkg.dsc | 2 +- MdeModulePkg/MdeModulePkg.dsc | 2 +- MdePkg/Library/CompilerIntrinsicsLib/memset.c | 8 ++++---- .../Library/IntrinsicLib/BaseIntrinsicLib.uni | 0 .../Library/IntrinsicLib/CopyMem.c | 0 .../Library/IntrinsicLib/Ia32/MathDivModU64x64.c | 0 .../Library/IntrinsicLib/Ia32/MathDivS64x64.c | 0 .../Library/IntrinsicLib/Ia32/MathDivU64x64.c | 0 .../IntrinsicLib/Ia32/MathDivU64xU64Rem.c | 0 .../Library/IntrinsicLib/Ia32/MathFtol.c | 0 .../Library/IntrinsicLib/Ia32/MathLShiftS64.c | 0 .../Library/IntrinsicLib/Ia32/MathLShiftS64.nasm | 0 .../Library/IntrinsicLib/Ia32/MathLldiv.asm | 0 .../Library/IntrinsicLib/Ia32/MathLlmul.asm | 0 .../Library/IntrinsicLib/Ia32/MathLlshr.asm | 0 .../Library/IntrinsicLib/Ia32/MathModU64x64.c | 0 .../Library/IntrinsicLib/Ia32/MathRShiftU64.c | 0 .../Library/IntrinsicLib/Ia32/MathRShiftU64.nasm | 0 .../Library/IntrinsicLib/Ia32/MathUlldiv.asm | 0 .../Library/IntrinsicLib/Ia32/MathUlldvrm.asm | 0 .../Library/IntrinsicLib/Ia32/MathUllrem.asm | 0 .../Library/IntrinsicLib/IntrinsicLib.inf | 0 .../Library/IntrinsicLib/MemoryIntrinsics.c | 0 MdePkg/MdePkg.dsc | 2 ++ NetworkPkg/NetworkPkg.dsc | 2 +- NetworkPkg/Test/NetworkPkgHostTest.dsc | 2 +- OvmfPkg/AmdSev/AmdSevX64.dsc | 2 +- OvmfPkg/Bhyve/BhyveX64.dsc | 2 +- OvmfPkg/CloudHv/CloudHvX64.dsc | 2 +- OvmfPkg/IntelTdx/IntelTdxX64.dsc | 2 +- OvmfPkg/Microvm/MicrovmX64.dsc | 2 +- OvmfPkg/OvmfPkgIa32.dsc | 2 +- OvmfPkg/OvmfPkgIa32X64.dsc | 2 +- OvmfPkg/OvmfPkgX64.dsc | 2 +- OvmfPkg/OvmfXen.dsc | 2 +- OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc | 2 +- SecurityPkg/SecurityPkg.dsc | 10 +++++----- SignedCapsulePkg/SignedCapsulePkg.dsc | 12 ++++++------ UefiCpuPkg/UefiCpuPkg.dsc | 4 ++-- UefiPayloadPkg/UefiPayloadPkg.dsc | 2 +- 45 files changed, 46 insertions(+), 45 deletions(-) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/BaseIntrinsicLib.uni (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/CopyMem.c (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathDivModU64x64.c (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathDivS64x64.c (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathDivU64x64.c (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathDivU64xU64Rem.c (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathFtol.c (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathLShiftS64.c (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathLShiftS64.nasm (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathLldiv.asm (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathLlmul.asm (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathLlshr.asm (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathModU64x64.c (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathRShiftU64.c (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathRShiftU64.nasm (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathUlldiv.asm (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathUlldvrm.asm (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/Ia32/MathUllrem.asm (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/IntrinsicLib.inf (100%) rename {CryptoPkg => MdePkg}/Library/IntrinsicLib/MemoryIntrinsics.c (100%) diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index c34165ac29..68cefda0d4 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -146,7 +146,7 @@ # # CryptoPkg libraries needed by multiple firmware features # - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc index 475bdd41e4..044652f039 100644 --- a/CryptoPkg/CryptoPkg.dsc +++ b/CryptoPkg/CryptoPkg.dsc @@ -117,7 +117,7 @@ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf HashApiLib|CryptoPkg/Library/BaseHashApiLib/BaseHashApiLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf [LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64] RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf @@ -377,7 +377,6 @@ CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf CryptoPkg/Library/MbedTlsLib/MbedTlsLibFull.inf CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf - CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf CryptoPkg/Library/TlsLib/TlsLib.inf CryptoPkg/Library/TlsLibNull/TlsLibNull.inf CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf diff --git a/CryptoPkg/CryptoPkgMbedTls.dsc b/CryptoPkg/CryptoPkgMbedTls.dsc index 1700aea7e4..64494a90f0 100644 --- a/CryptoPkg/CryptoPkgMbedTls.dsc +++ b/CryptoPkg/CryptoPkgMbedTls.dsc @@ -77,7 +77,7 @@ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf MbedTlsLib|CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf [LibraryClasses.common.PEIM] diff --git a/CryptoPkg/Readme.md b/CryptoPkg/Readme.md index cb2228b6b8..c122b76d2a 100644 --- a/CryptoPkg/Readme.md +++ b/CryptoPkg/Readme.md @@ -267,7 +267,7 @@ TLS services are not typically used in SEC. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf ``` ### PEI Phase Library Mappings @@ -283,7 +283,7 @@ TlsLib because TLS services are not typically used in PEI. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf ``` If dynamic linking is used, then all PEIMs except CryptoPei use the following @@ -300,7 +300,7 @@ library mappings. The CryptoPei module uses the static linking settings. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf } ``` @@ -318,7 +318,7 @@ OpensslLib instance can be used. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibFull.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf ``` If dynamic linking is used, then all DXE Drivers except CryptoDxe use the @@ -336,7 +336,7 @@ settings. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibFull.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf } ``` @@ -353,7 +353,7 @@ TlsLib. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf ``` If dynamic linking is used, then all SMM Drivers except CryptoSmm use the @@ -371,7 +371,7 @@ settings. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf } ``` @@ -388,7 +388,7 @@ TlsLib because TLS services are not typically used at runtime. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf ``` ### PCD Configuration Settings diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc index c5829427b4..c794bf5d76 100644 --- a/EmulatorPkg/EmulatorPkg.dsc +++ b/EmulatorPkg/EmulatorPkg.dsc @@ -127,7 +127,7 @@ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf RngLib|MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc index f7cadb2e4b..195e9904fa 100644 --- a/FmpDevicePkg/FmpDevicePkg.dsc +++ b/FmpDevicePkg/FmpDevicePkg.dsc @@ -58,7 +58,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 6f01cc2cfd..e78a950e15 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -107,7 +107,7 @@ VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf IpmiCommandLib|MdeModulePkg/Library/BaseIpmiCommandLibNull/BaseIpmiCommandLibNull.inf SpiHcPlatformLib|MdeModulePkg/Library/BaseSpiHcPlatformLibNull/BaseSpiHcPlatformLibNull.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf [LibraryClasses.IA32] AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf diff --git a/MdePkg/Library/CompilerIntrinsicsLib/memset.c b/MdePkg/Library/CompilerIntrinsicsLib/memset.c index 3e45302fe6..03ddbfe953 100644 --- a/MdePkg/Library/CompilerIntrinsicsLib/memset.c +++ b/MdePkg/Library/CompilerIntrinsicsLib/memset.c @@ -29,10 +29,10 @@ __memset ( } // -// Other modules (such as CryptoPkg/IntrinsicLib) may provide another -// implementation of memset(), which may conflict with this one if this -// object was pulled into the link due to the definitions below. So make -// our memset() 'weak' to let the other implementation take precedence. +// Other modules (such as MdePkg/IntrinsicLib, formerly in CryptoPkg) may +// provide another implementation of memset(), which may conflict with this +// one if this object was pulled into the link due to the definitions below. +// So make our memset() 'weak' to let the other implementation take precedence. // __attribute__ ((__weak__, __alias__ ("__memset"))) void * diff --git a/CryptoPkg/Library/IntrinsicLib/BaseIntrinsicLib.uni b/MdePkg/Library/IntrinsicLib/BaseIntrinsicLib.uni similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/BaseIntrinsicLib.uni rename to MdePkg/Library/IntrinsicLib/BaseIntrinsicLib.uni diff --git a/CryptoPkg/Library/IntrinsicLib/CopyMem.c b/MdePkg/Library/IntrinsicLib/CopyMem.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/CopyMem.c rename to MdePkg/Library/IntrinsicLib/CopyMem.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathDivModU64x64.c b/MdePkg/Library/IntrinsicLib/Ia32/MathDivModU64x64.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathDivModU64x64.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathDivModU64x64.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathDivS64x64.c b/MdePkg/Library/IntrinsicLib/Ia32/MathDivS64x64.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathDivS64x64.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathDivS64x64.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathDivU64x64.c b/MdePkg/Library/IntrinsicLib/Ia32/MathDivU64x64.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathDivU64x64.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathDivU64x64.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathDivU64xU64Rem.c b/MdePkg/Library/IntrinsicLib/Ia32/MathDivU64xU64Rem.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathDivU64xU64Rem.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathDivU64xU64Rem.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathFtol.c b/MdePkg/Library/IntrinsicLib/Ia32/MathFtol.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathFtol.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathFtol.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathLShiftS64.c b/MdePkg/Library/IntrinsicLib/Ia32/MathLShiftS64.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathLShiftS64.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathLShiftS64.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathLShiftS64.nasm b/MdePkg/Library/IntrinsicLib/Ia32/MathLShiftS64.nasm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathLShiftS64.nasm rename to MdePkg/Library/IntrinsicLib/Ia32/MathLShiftS64.nasm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathLldiv.asm b/MdePkg/Library/IntrinsicLib/Ia32/MathLldiv.asm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathLldiv.asm rename to MdePkg/Library/IntrinsicLib/Ia32/MathLldiv.asm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathLlmul.asm b/MdePkg/Library/IntrinsicLib/Ia32/MathLlmul.asm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathLlmul.asm rename to MdePkg/Library/IntrinsicLib/Ia32/MathLlmul.asm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathLlshr.asm b/MdePkg/Library/IntrinsicLib/Ia32/MathLlshr.asm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathLlshr.asm rename to MdePkg/Library/IntrinsicLib/Ia32/MathLlshr.asm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathModU64x64.c b/MdePkg/Library/IntrinsicLib/Ia32/MathModU64x64.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathModU64x64.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathModU64x64.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathRShiftU64.c b/MdePkg/Library/IntrinsicLib/Ia32/MathRShiftU64.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathRShiftU64.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathRShiftU64.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathRShiftU64.nasm b/MdePkg/Library/IntrinsicLib/Ia32/MathRShiftU64.nasm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathRShiftU64.nasm rename to MdePkg/Library/IntrinsicLib/Ia32/MathRShiftU64.nasm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathUlldiv.asm b/MdePkg/Library/IntrinsicLib/Ia32/MathUlldiv.asm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathUlldiv.asm rename to MdePkg/Library/IntrinsicLib/Ia32/MathUlldiv.asm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathUlldvrm.asm b/MdePkg/Library/IntrinsicLib/Ia32/MathUlldvrm.asm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathUlldvrm.asm rename to MdePkg/Library/IntrinsicLib/Ia32/MathUlldvrm.asm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathUllrem.asm b/MdePkg/Library/IntrinsicLib/Ia32/MathUllrem.asm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathUllrem.asm rename to MdePkg/Library/IntrinsicLib/Ia32/MathUllrem.asm diff --git a/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf b/MdePkg/Library/IntrinsicLib/IntrinsicLib.inf similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf rename to MdePkg/Library/IntrinsicLib/IntrinsicLib.inf diff --git a/CryptoPkg/Library/IntrinsicLib/MemoryIntrinsics.c b/MdePkg/Library/IntrinsicLib/MemoryIntrinsics.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/MemoryIntrinsics.c rename to MdePkg/Library/IntrinsicLib/MemoryIntrinsics.c diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index c86d64cd84..d5381fcaf3 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -151,6 +151,8 @@ MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf + MdePkg/Library/IntrinsicLib/IntrinsicLib.inf + [Components.IA32, Components.X64, Components.ARM, Components.AARCH64] # # Add UEFI Target Based Unit Tests diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc index 9488a9b384..35060b386f 100644 --- a/NetworkPkg/NetworkPkg.dsc +++ b/NetworkPkg/NetworkPkg.dsc @@ -57,7 +57,7 @@ !else BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf !endif DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc index 667be95587..043f8cef7f 100644 --- a/NetworkPkg/Test/NetworkPkgHostTest.dsc +++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc @@ -71,7 +71,7 @@ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(TOOL_CHAIN_TAG) == VS2019 or $(TOOL_CHAIN_TAG) == VS2022 [LibraryClasses.X64] diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc index 4413cace23..db3f859851 100644 --- a/OvmfPkg/AmdSev/AmdSevX64.dsc +++ b/OvmfPkg/AmdSev/AmdSevX64.dsc @@ -184,7 +184,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf RngLib|MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc index 0ee4e0c9bc..b31eed2113 100644 --- a/OvmfPkg/Bhyve/BhyveX64.dsc +++ b/OvmfPkg/Bhyve/BhyveX64.dsc @@ -196,7 +196,7 @@ IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc index 1223e6f6a1..877269a39c 100644 --- a/OvmfPkg/CloudHv/CloudHvX64.dsc +++ b/OvmfPkg/CloudHv/CloudHvX64.dsc @@ -210,7 +210,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc index f9774c10dd..38eb27132e 100644 --- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc +++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc @@ -185,7 +185,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf RngLib|MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc index 84d587d069..50e46ac927 100644 --- a/OvmfPkg/Microvm/MicrovmX64.dsc +++ b/OvmfPkg/Microvm/MicrovmX64.dsc @@ -205,7 +205,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 129e155c44..1caf85d272 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -197,7 +197,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index ed2d12e42e..15c719be28 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -202,7 +202,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 40e76a68e1..0bc5f711e7 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -217,7 +217,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc index a74d487dbc..5491b3bbb7 100644 --- a/OvmfPkg/OvmfXen.dsc +++ b/OvmfPkg/OvmfXen.dsc @@ -194,7 +194,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc index 79e0a000c0..6643133a4b 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc +++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc @@ -109,7 +109,7 @@ # # CryptoPkg libraries needed by multiple firmware features # - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index 56f2467297..32455b0bd9 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -110,7 +110,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf !endif @@ -128,7 +128,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf !endif @@ -149,7 +149,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf !endif @@ -161,7 +161,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf !endif @@ -180,7 +180,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf !endif diff --git a/SignedCapsulePkg/SignedCapsulePkg.dsc b/SignedCapsulePkg/SignedCapsulePkg.dsc index 5039964aac..9c6fde6c30 100644 --- a/SignedCapsulePkg/SignedCapsulePkg.dsc +++ b/SignedCapsulePkg/SignedCapsulePkg.dsc @@ -111,7 +111,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf !endif @@ -126,7 +126,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf !endif @@ -140,7 +140,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf !endif @@ -163,7 +163,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf !endif @@ -175,7 +175,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf !endif @@ -187,7 +187,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf !endif diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index f14e1eb26d..73e57bdfae 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -73,7 +73,7 @@ LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf HobLib|MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf MemoryAllocationLib|MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf [LibraryClasses.common.SEC] @@ -140,7 +140,7 @@ UefiCpuPkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLib.inf [Components.IA32] - CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + MdePkg/Library/IntrinsicLib/IntrinsicLib.inf [Components.IA32, Components.X64] UefiCpuPkg/CpuFeatures/CpuFeaturesPei.inf { diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 446320031f..82f71c62d2 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -220,7 +220,7 @@ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf !endif - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf HobLib|UefiPayloadPkg/Library/DxeHobLib/DxeHobLib.inf From eff8bca8e0117845047dece2b41b69535fee71fc Mon Sep 17 00:00:00 2001 From: Mike Beaton Date: Fri, 13 Dec 2024 01:05:14 +0000 Subject: [PATCH 095/341] HttpBootDxe: Allow user-specified static IP address, as long as boot file is also specified --- NetworkPkg/HttpBootDxe/HttpBootClient.c | 150 +++++++++++++++++++++--- 1 file changed, 133 insertions(+), 17 deletions(-) diff --git a/NetworkPkg/HttpBootDxe/HttpBootClient.c b/NetworkPkg/HttpBootDxe/HttpBootClient.c index 858e7c2103..401b33c624 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootClient.c +++ b/NetworkPkg/HttpBootDxe/HttpBootClient.c @@ -186,7 +186,8 @@ HttpBootUpdateDevicePath ( **/ EFI_STATUS HttpBootDhcp4ExtractUriInfo ( - IN HTTP_BOOT_PRIVATE_DATA *Private + IN HTTP_BOOT_PRIVATE_DATA *Private, + IN BOOLEAN UseDhcp ) { HTTP_BOOT_DHCP4_PACKET_CACHE *SelectOffer; @@ -198,19 +199,23 @@ HttpBootDhcp4ExtractUriInfo ( EFI_STATUS Status; ASSERT (Private != NULL); - ASSERT (Private->SelectIndex != 0); - SelectIndex = Private->SelectIndex - 1; - ASSERT (SelectIndex < HTTP_BOOT_OFFER_MAX_NUM); - DnsServerIndex = 0; + if (UseDhcp) { + ASSERT (Private->SelectIndex != 0); + SelectIndex = Private->SelectIndex - 1; + ASSERT (SelectIndex < HTTP_BOOT_OFFER_MAX_NUM); + + // + // SelectOffer contains the IP address configuration and name server configuration. + // HttpOffer contains the boot file URL. + // + SelectOffer = &Private->OfferBuffer[SelectIndex].Dhcp4; + } else { + ASSERT (Private->FilePathUri != NULL); + } Status = EFI_SUCCESS; - // - // SelectOffer contains the IP address configuration and name server configuration. - // HttpOffer contains the boot file URL. - // - SelectOffer = &Private->OfferBuffer[SelectIndex].Dhcp4; if (Private->FilePathUri == NULL) { // // In Corporate environment, we need a HttpOffer. @@ -251,9 +256,12 @@ HttpBootDhcp4ExtractUriInfo ( return Status; } - if ((SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns) || + if (UseDhcp && ( + (SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns) || (SelectOffer->OfferType == HttpOfferTypeDhcpDns) || - (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns)) + (SelectOffer->OfferType == HttpOfferTypeDhcpIpUriDns) + ) + ) { Option = SelectOffer->OptList[HTTP_BOOT_DHCP4_TAG_INDEX_DNS_SERVER]; ASSERT (Option != NULL); @@ -540,19 +548,127 @@ HttpBootDiscoverBootInfo ( IN OUT HTTP_BOOT_PRIVATE_DATA *Private ) { - EFI_STATUS Status; + EFI_STATUS Status; + EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2; + EFI_IP4_CONFIG2_POLICY Policy; + EFI_IP4_CONFIG2_MANUAL_ADDRESS Ip4ManualAddress; + EFI_IPv4_ADDRESS Ip4Gateway; + EFI_IPv4_ADDRESS *DnsList; + UINTN DataSize; + BOOLEAN UseDhcp; + UINTN DnsServerIndex; + + UseDhcp = TRUE; + + // + // Allow user configured static IPv4 address, if already present, but only if boot file is also specified. + // + if (!Private->UsingIpv6 && Private->FilePathUri != NULL) { + Ip4Config2 = Private->Ip4Config2; + + DataSize = sizeof (EFI_IP4_CONFIG2_POLICY); + Status = Ip4Config2->GetData ( + Ip4Config2, + Ip4Config2DataTypePolicy, + &DataSize, + &Policy + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Policy == Ip4Config2PolicyStatic) { + DataSize = sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS); + Status = Ip4Config2->GetData ( + Ip4Config2, + Ip4Config2DataTypeManualAddress, + &DataSize, + &Ip4ManualAddress + ); + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + return Status; + } + } + + if ((Policy == Ip4Config2PolicyStatic) && (Status != EFI_NOT_FOUND)) { + DataSize = sizeof (EFI_IPv4_ADDRESS); + Status = Ip4Config2->GetData ( + Ip4Config2, + Ip4Config2DataTypeGateway, + &DataSize, + &Ip4Gateway + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DataSize = 0; + Status = Ip4Config2->GetData ( + Ip4Config2, + Ip4Config2DataTypeDnsServer, + &DataSize, + NULL + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + DnsList = AllocatePool (DataSize); + if (DnsList == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = Ip4Config2->GetData ( + Ip4Config2, + Ip4Config2DataTypeDnsServer, + &DataSize, + DnsList + ); + if (EFI_ERROR (Status)) { + FreePool (DnsList); + return Status; + } + } + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { + return Status; + } + + CopyMem (&Private->StationIp, &Ip4ManualAddress.Address, sizeof (EFI_IPv4_ADDRESS)); + CopyMem (&Private->SubnetMask, &Ip4ManualAddress.SubnetMask, sizeof (EFI_IPv4_ADDRESS)); + CopyMem (&Private->GatewayIp, &Ip4Gateway, sizeof (EFI_IPv4_ADDRESS)); + + if (DataSize > 0) { + Private->DnsServerCount = (UINT32)(DataSize / sizeof (EFI_IPv4_ADDRESS)); + + Private->DnsServerIp = AllocateZeroPool (Private->DnsServerCount * sizeof (EFI_IP_ADDRESS)); + if (Private->DnsServerIp == NULL) { + FreePool (DnsList); + return EFI_OUT_OF_RESOURCES; + } + + for (DnsServerIndex = 0; DnsServerIndex < Private->DnsServerCount; DnsServerIndex++) { + CopyMem (&(Private->DnsServerIp[DnsServerIndex].v4), &DnsList[DnsServerIndex], sizeof (EFI_IPv4_ADDRESS)); + } + FreePool (DnsList); + } + + AsciiPrint ("\n Static IP address is "); + HttpBootShowIp4Addr (&Private->StationIp.v4); + AsciiPrint ("\n"); + + UseDhcp = FALSE; + } + } // // Start D.O.R.A/S.A.R.R exchange to acquire station ip address and // other Http boot information. // - Status = HttpBootDhcp (Private); - if (EFI_ERROR (Status)) { - return Status; + if (UseDhcp) { + Status = HttpBootDhcp (Private); + if (EFI_ERROR (Status)) { + return Status; + } } if (!Private->UsingIpv6) { - Status = HttpBootDhcp4ExtractUriInfo (Private); + Status = HttpBootDhcp4ExtractUriInfo (Private, UseDhcp); } else { Status = HttpBootDhcp6ExtractUriInfo (Private); } From 13cc1c02bbcc26b69076e1409626828301436bf0 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 25 Feb 2025 12:42:11 +0300 Subject: [PATCH 096/341] Build: Upgraded OpenCorePkg. --- OpenCorePkg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenCorePkg b/OpenCorePkg index ca9a501490..35d9b3706f 160000 --- a/OpenCorePkg +++ b/OpenCorePkg @@ -1 +1 @@ -Subproject commit ca9a501490ccce20431f095182b4fb0d359d80e3 +Subproject commit 35d9b3706f0772134c8e6a62b9684a699d628518 From 709984a981aa03b7076c11a6bd045d66bd276fba Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 7 Apr 2025 13:54:15 +0300 Subject: [PATCH 097/341] Fixed compilation of all packages tracked by CI after rebasing upon edk2-stable202502 tag. --- .github/workflows/build_arm.yaml | 2 +- .github/workflows/build_nolto.yaml | 2 +- BaseTools/Source/C/VolInfo/VolInfo.h | 2 - Ext4Pkg/Ext4Pkg.dsc | 5 --- .../VarCheckHiiLibStandaloneMm.c | 2 + .../SmmServicesTableLib/SmmServicesTableLib.c | 28 +++++++++++++ .../StandaloneSmmServicesTableLib.inf | 39 +++++++++++++++++++ OvmfPkg/OvmfPkgX64.fdf | 4 +- SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf | 1 + .../SmmCpuExceptionHandlerLib.inf | 1 + UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c | 1 - UefiCpuPkg/UefiCpuPkg.dsc | 1 + 12 files changed, 76 insertions(+), 12 deletions(-) create mode 100644 MdePkg/Library/SmmServicesTableLib/StandaloneSmmServicesTableLib.inf diff --git a/.github/workflows/build_arm.yaml b/.github/workflows/build_arm.yaml index 02e37fe57e..f8944f9a22 100644 --- a/.github/workflows/build_arm.yaml +++ b/.github/workflows/build_arm.yaml @@ -17,7 +17,7 @@ env: jobs: build-linux-gcc5: name: Linux GCC - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/build_nolto.yaml b/.github/workflows/build_nolto.yaml index ad48934a31..a719457b25 100644 --- a/.github/workflows/build_nolto.yaml +++ b/.github/workflows/build_nolto.yaml @@ -17,7 +17,7 @@ env: jobs: build-linux-arm: name: Linux GCC ARM - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: diff --git a/BaseTools/Source/C/VolInfo/VolInfo.h b/BaseTools/Source/C/VolInfo/VolInfo.h index 377cde80f7..91d02c04bb 100644 --- a/BaseTools/Source/C/VolInfo/VolInfo.h +++ b/BaseTools/Source/C/VolInfo/VolInfo.h @@ -9,8 +9,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #ifndef _VOLINFO_H_ #define _VOLINFO_H_ 1 -#define PI_SPECIFICATION_VERSION 0x00010000 - #define EFI_DEP_BEFORE 0x00 #define EFI_DEP_AFTER 0x01 #define EFI_DEP_PUSH 0x02 diff --git a/Ext4Pkg/Ext4Pkg.dsc b/Ext4Pkg/Ext4Pkg.dsc index 18cfc102b8..0a9032eb79 100644 --- a/Ext4Pkg/Ext4Pkg.dsc +++ b/Ext4Pkg/Ext4Pkg.dsc @@ -47,11 +47,6 @@ OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf BaseUcs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf - # - # Required for stack protector support - # - NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf - ################################################################################################### # # Components Section - list of the modules and components that will be processed by compilation diff --git a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.c b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.c index c1ee55bb2e..16accb17f6 100644 --- a/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.c +++ b/MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLibStandaloneMm.c @@ -54,6 +54,8 @@ VarCheckHiiLibReceiveHiiBinHandler ( { EFI_STATUS Status; + Status = EFI_INVALID_PARAMETER; + // // If input is invalid, stop processing this SMI // diff --git a/MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.c b/MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.c index 73e76af219..8a07a3d02c 100644 --- a/MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.c +++ b/MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.c @@ -55,6 +55,34 @@ SmmServicesTableLibConstructor ( return EFI_SUCCESS; } +EFI_STATUS +EFIAPI +StandaloneSmmServicesTableLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_MM_SYSTEM_TABLE *MmSystemTable + ) +{ + EFI_STATUS Status; + EFI_SMM_BASE2_PROTOCOL *InternalSmmBase2; + + InternalSmmBase2 = NULL; + Status = MmSystemTable->MmLocateProtocol ( + &gEfiSmmBase2ProtocolGuid, + NULL, + (VOID **)&InternalSmmBase2 + ); + ASSERT_EFI_ERROR (Status); + ASSERT (InternalSmmBase2 != NULL); + + // + // We are in SMM, retrieve the pointer to SMM System Table + // + InternalSmmBase2->GetSmstLocation (InternalSmmBase2, &gSmst); + ASSERT (gSmst != NULL); + + return EFI_SUCCESS; +} + /** This function allows the caller to determine if the driver is executing in System Management Mode(SMM). diff --git a/MdePkg/Library/SmmServicesTableLib/StandaloneSmmServicesTableLib.inf b/MdePkg/Library/SmmServicesTableLib/StandaloneSmmServicesTableLib.inf new file mode 100644 index 0000000000..59d6de5fde --- /dev/null +++ b/MdePkg/Library/SmmServicesTableLib/StandaloneSmmServicesTableLib.inf @@ -0,0 +1,39 @@ +## @file +# SMM Services Table Library. +# +# Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SmmServicesTableLib + MODULE_UNI_FILE = SmmServicesTableLib.uni + FILE_GUID = CC74318B-16F5-4165-B9E5-7B19F335D0D7 + MODULE_TYPE = MM_STANDALONE + VERSION_STRING = 1.0 + LIBRARY_CLASS = SmmServicesTableLib|MM_STANDALONE + PI_SPECIFICATION_VERSION = 0x00010032 + CONSTRUCTOR = StandaloneSmmServicesTableLibConstructor + +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + SmmServicesTableLib.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + DebugLib + +[Protocols] + gEfiSmmBase2ProtocolGuid ## CONSUMES + +[Depex] + gEfiSmmBase2ProtocolGuid diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 5202c71b39..5c93be7ca8 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -103,11 +103,11 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableBase|gUefiOvmfPkgTokenSpaceGui 0x011000|0x00F000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize -0x020000|0x120000 +0x020000|0x130000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize FV = PEIFV -0x140000|0xE40000 +0x150000|0xE30000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize FV = DXEFV diff --git a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf index d7686251f4..fb13463ea0 100644 --- a/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf +++ b/SecurityPkg/Tcg/Tcg2Acpi/Tcg2Acpi.inf @@ -58,6 +58,7 @@ Tcg2PhysicalPresenceLib PcdLib HobLib + IntrinsicLib [Guids] gEfiTpmDeviceInstanceTpm20DtpmGuid ## PRODUCES ## GUID # TPM device identifier diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf index de88041442..3217886d4c 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf @@ -51,6 +51,7 @@ PrintLib SerialPortLib SynchronizationLib + SmmServicesTableLib [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c index 12fdf7463f..de28bacb65 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c @@ -14,7 +14,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include #include #include "PiSmmCpuCommon.h" diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 73e57bdfae..94d8a17826 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -110,6 +110,7 @@ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf [LibraryClasses.common.MM_STANDALONE] + SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/StandaloneSmmServicesTableLib.inf MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf From 229824f0093b570def5d53a06deb0affccbdad5d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 27 Feb 2025 11:52:16 +0300 Subject: [PATCH 098/341] ArmVirtPkg/ArmPlatformLibQemu: Disabled EL2&0 translation regime to fix Windows 10 boot. --- .../Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S b/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S index 55c01035bb..dc77b3507e 100644 --- a/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S +++ b/ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S @@ -66,11 +66,14 @@ ASM_FUNC(ArmPlatformPeiBootAction) tst x0, #ID_AA64MMFR1_VH_MASK b.eq 0f +/* + * Do not enable EL2&0 translation regime, as it breaks Windows 10 boot. + * mrs x0, hcr_el2 // Enable VHE support orr x0, x0, #HCR_EL2_E2H msr hcr_el2, x0 isb - +*/ .Learly_idmap: mov_i x0, mairval mov_i x1, tcrval From b3bf2495f397f4e7c6ec700f6d1476c51f21d92f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 27 Feb 2025 17:38:05 +0300 Subject: [PATCH 099/341] UefiCpuPkg: Fixed OpenCorePkg/Utilities compilation. --- UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c index a5181ebd74..c86a774446 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -166,6 +166,14 @@ MtrrLibIsMtrrSupported ( // MTRR is not supported in TD-Guest. // if (TdIsEnabled ()) { + if (FixedMtrrSupported != NULL) { + *FixedMtrrSupported = FALSE; + } + + if (VariableMtrrCount != NULL) { + *VariableMtrrCount = 0; + } + return FALSE; } From 2068113e8b2ab49ae662737b25fc66b2de31a46f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 4 Mar 2025 16:48:34 +0300 Subject: [PATCH 100/341] UefiCpuPkg: Fixed stack corruption. --- UefiCpuPkg/Library/CpuArchLib/CpuMp.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuMp.c b/UefiCpuPkg/Library/CpuArchLib/CpuMp.c index b5478ff7c4..e85dce0d46 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuMp.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuMp.c @@ -659,6 +659,7 @@ InitializeMpExceptionStackSwitchHandlers ( UINTN BufferSize; EFI_STATUS Status; UINT8 *Buffer; + EFI_PHYSICAL_ADDRESS BufferAddress; SwitchStackData = AllocateZeroPool (mNumberOfProcessors * sizeof (EXCEPTION_STACK_SWITCH_CONTEXT)); if (SwitchStackData == NULL) { @@ -697,19 +698,21 @@ InitializeMpExceptionStackSwitchHandlers ( // we are allocating the buffer that will hold the new GDT and IDT for the APs. These must be allocated below // 4GB as they are used by protected mode code on the APs when they are started up after this point. If they are // above 4GB, the APs will triple fault because the 32 bit code segment is invalid - Buffer = (UINT8 *)(UINTN)(BASE_4GB - 1); - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiRuntimeServicesData, - EFI_SIZE_TO_PAGES (BufferSize), - (EFI_PHYSICAL_ADDRESS *)&Buffer - ); + BufferAddress = BASE_4GB - 1; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiRuntimeServicesData, + EFI_SIZE_TO_PAGES (BufferSize), + &BufferAddress + ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Failed to allocate buffer for InitializeExceptionStackSwitchHandlers Status %r\n", Status)); ASSERT_EFI_ERROR (Status); goto Exit; } + Buffer = (UINT8 *)(UINTN)BufferAddress; + ZeroMem (Buffer, BufferSize); BufferSize = 0; From ee37e305bda6a5f83569a7b202b73df4d00151f1 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Fri, 7 Mar 2025 15:47:24 +0300 Subject: [PATCH 101/341] NetworkPkg/DxeNetLib: Fix unaligned access in NetblockChecksum Into this routine the caller passes different data structures with different alignment that is why casting bulk pointer to UINT16 violates strict aliasing rule. --- NetworkPkg/Library/DxeNetLib/NetBuffer.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/NetworkPkg/Library/DxeNetLib/NetBuffer.c b/NetworkPkg/Library/DxeNetLib/NetBuffer.c index 4721fbd270..ec22708c0e 100644 --- a/NetworkPkg/Library/DxeNetLib/NetBuffer.c +++ b/NetworkPkg/Library/DxeNetLib/NetBuffer.c @@ -1618,20 +1618,12 @@ NetblockChecksum ( ) { register UINT32 Sum; + UINT32 BulkPtr; Sum = 0; - // - // Add left-over byte, if any - // - if (Len % 2 != 0) { - Sum += *(Bulk + Len - 1); - } - - while (Len > 1) { - Sum += *(UINT16 *)Bulk; - Bulk += 2; - Len -= 2; + for (BulkPtr = 0; BulkPtr < Len; BulkPtr++, Bulk++) { + Sum += ((*Bulk) << ((BulkPtr & 1U) * 8U)); } // From a46a56fd37df2533a7954fb9d8cc09e92f8fe38d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 13 Mar 2025 11:41:38 +0300 Subject: [PATCH 102/341] CI: Upgraded QEMU version. --- .github/workflows/build_arm.yaml | 2 +- .github/workflows/build_nolto.yaml | 2 +- .github/workflows/build_x86.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_arm.yaml b/.github/workflows/build_arm.yaml index f8944f9a22..b4afa966ee 100644 --- a/.github/workflows/build_arm.yaml +++ b/.github/workflows/build_arm.yaml @@ -11,7 +11,7 @@ env: PROJECT_TYPE: UEFI FORCE_INSTALL: 1 WERROR: 1 - QEMU_VERSION_TAG: qemu-ci-8.1.5-r1 + QEMU_VERSION_TAG: qemu-ci-9.2.2-r1 WINPE_VERSION_TAG: images-winpe-1.0 jobs: diff --git a/.github/workflows/build_nolto.yaml b/.github/workflows/build_nolto.yaml index a719457b25..72d31d53d0 100644 --- a/.github/workflows/build_nolto.yaml +++ b/.github/workflows/build_nolto.yaml @@ -11,7 +11,7 @@ env: PROJECT_TYPE: UEFI FORCE_INSTALL: 1 WERROR: 1 - QEMU_VERSION_TAG: qemu-ci-8.1.5-r1 + QEMU_VERSION_TAG: qemu-ci-9.2.2-r1 WINPE_VERSION_TAG: images-winpe-1.0 jobs: diff --git a/.github/workflows/build_x86.yaml b/.github/workflows/build_x86.yaml index 47fcc276ca..4fb36ec57c 100644 --- a/.github/workflows/build_x86.yaml +++ b/.github/workflows/build_x86.yaml @@ -11,7 +11,7 @@ env: PROJECT_TYPE: UEFI FORCE_INSTALL: 1 WERROR: 1 - QEMU_VERSION_TAG: qemu-ci-8.1.5-r1 + QEMU_VERSION_TAG: qemu-ci-9.2.2-r1 WINPE_VERSION_TAG: images-winpe-1.0 jobs: From 0e277463fad4f1d691d33a6251555e88cb9ceea4 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Sat, 5 Apr 2025 16:31:57 +0300 Subject: [PATCH 103/341] CryptoPkg: Fix compilation with newer Xcode due to bugged type conversion --- CryptoPkg/Library/BaseCryptLib/Pem/CryptPem.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CryptoPkg/Library/BaseCryptLib/Pem/CryptPem.c b/CryptoPkg/Library/BaseCryptLib/Pem/CryptPem.c index d64cf3d680..53739d7104 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pem/CryptPem.c +++ b/CryptoPkg/Library/BaseCryptLib/Pem/CryptPem.c @@ -20,22 +20,22 @@ SPDX-License-Identifier: BSD-2-Clause-Patent @retval The number of characters in the passphrase or 0 if an error occurred. **/ -INTN +INT32 PasswordCallback ( OUT CHAR8 *Buf, - IN INTN Size, - IN INTN Flag, + IN INT32 Size, + IN INT32 Flag, IN VOID *Key ) { - INTN KeyLength; + INT32 KeyLength; ZeroMem ((VOID *)Buf, (UINTN)Size); if (Key != NULL) { // // Duplicate key phrase directly. // - KeyLength = (INTN)AsciiStrLen ((CHAR8 *)Key); + KeyLength = (INT32)AsciiStrLen ((CHAR8 *)Key); KeyLength = (KeyLength > Size) ? Size : KeyLength; CopyMem (Buf, Key, (UINTN)KeyLength); return KeyLength; From d61b269edf473c79a690816262e81bf7f785de4d Mon Sep 17 00:00:00 2001 From: vit9696 Date: Sat, 5 Apr 2025 17:39:25 +0300 Subject: [PATCH 104/341] MdeModulePkg/EbcDxe: Fix Xcode compilation due to bad type conversion --- MdeModulePkg/Universal/EbcDxe/EbcInt.c | 53 ++++++++++++++++---------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/MdeModulePkg/Universal/EbcDxe/EbcInt.c b/MdeModulePkg/Universal/EbcDxe/EbcInt.c index 46c4020102..a48e885ee3 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcInt.c +++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.c @@ -186,11 +186,18 @@ InitEbcVmTestProtocol ( @return EFI_UNSUPPORTED This function always return EFI_UNSUPPORTED status. **/ +STATIC EFI_STATUS EFIAPI EbcVmTestUnsupported ( - VOID - ); + IN EFI_EBC_VM_TEST_PROTOCOL *This, + IN CHAR16 *AsmText, + IN OUT INT8 *Buffer, + IN OUT UINTN *BufferLen + ) +{ + return EFI_UNSUPPORTED; +} /** Registers a callback function that the EBC interpreter calls to flush the @@ -374,6 +381,27 @@ EbcIsImageSupported ( return TRUE; } +/** + This is a wrapper for the Flush callback routine needed for type compatibility. + + @param Start The beginning physical address to flush from the processor's instruction cache. + @param Length The number of bytes to flush from the processor's instruction cache. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +STATIC +EFI_STATUS +EFIAPI +EbcInvalidateInstructionCache ( + IN EFI_PHYSICAL_ADDRESS Start, + IN UINT64 Length + ) +{ + InvalidateInstructionCacheRange((VOID*)(UINTN)Start, (UINTN)Length); + return EFI_SUCCESS; +} + /** Register a supported PE/COFF image with the emulator. After this call completes successfully, the PE/COFF image may be started as usual, and @@ -407,7 +435,7 @@ EbcRegisterImage ( { EbcRegisterICacheFlush ( NULL, - (EBC_ICACHE_FLUSH)InvalidateInstructionCacheRange + EbcInvalidateInstructionCache ); return EbcCreateThunk ( @@ -1489,8 +1517,8 @@ InitEbcVmTestProtocol ( EbcVmTestProtocol->Execute = (EBC_VM_TEST_EXECUTE)EbcExecuteInstructions; DEBUG_CODE_BEGIN (); - EbcVmTestProtocol->Assemble = (EBC_VM_TEST_ASM)EbcVmTestUnsupported; - EbcVmTestProtocol->Disassemble = (EBC_VM_TEST_DASM)EbcVmTestUnsupported; + EbcVmTestProtocol->Assemble = EbcVmTestUnsupported; + EbcVmTestProtocol->Disassemble = EbcVmTestUnsupported; DEBUG_CODE_END (); // @@ -1505,21 +1533,6 @@ InitEbcVmTestProtocol ( return Status; } -/** - Returns the EFI_UNSUPPORTED Status. - - @return EFI_UNSUPPORTED This function always return EFI_UNSUPPORTED status. - -**/ -EFI_STATUS -EFIAPI -EbcVmTestUnsupported ( - VOID - ) -{ - return EFI_UNSUPPORTED; -} - /** Allocates a buffer of type EfiBootServicesCode. From 6f0af031d70f7083ccf4c0ad674a6abbd5073de1 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Sat, 5 Apr 2025 17:45:53 +0300 Subject: [PATCH 105/341] BaseTools: Disable cast-function-type-mismatch for Xcode Currently DxeCore and PeiCore rely on type cast violation too heavily. --- BaseTools/Conf/tools_def.template | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index d900b39dc5..b2a37bdb4f 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -1609,9 +1609,9 @@ RELEASE_XCODE5_IA32_ASM_FLAGS = -arch i386 *_XCODE5_IA32_NASM_FLAGS = -f macho32 -DRODATA_SECTION_NAME=.rodata - DEBUG_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -flto -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -RELEASE_XCODE5_IA32_CC_FLAGS = -arch i386 -c -flto -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -Wno-unused-const-variable -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang - NOOPT_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -O0 -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang + DEBUG_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -flto -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-cast-function-type-mismatch -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang +RELEASE_XCODE5_IA32_CC_FLAGS = -arch i386 -c -flto -Os -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-cast-function-type-mismatch -Wno-unknown-warning-option -Wno-unused-const-variable -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang + NOOPT_XCODE5_IA32_CC_FLAGS = -arch i386 -c -g -O0 -Wall -Werror -include AutoGen.h -funsigned-char -fno-stack-protector -fno-builtin -fshort-wchar -fasm-blocks -mdynamic-no-pic -mno-implicit-float -mms-bitfields -msoft-float -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-cast-function-type-mismatch -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang ################## # X64 definitions @@ -1628,9 +1628,9 @@ RELEASE_XCODE5_X64_ASM_FLAGS = -arch x86_64 *_XCODE5_*_PP_FLAGS = -E -x assembler-with-cpp -include AutoGen.h *_XCODE5_*_VFRPP_FLAGS = -x c -E -P -DVFRCOMPILE -include $(MODULE_NAME)StrDefs.h - DEBUG_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -gdwarf -flto -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS - NOOPT_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -gdwarf -O0 -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS -RELEASE_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -flto -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-unused-const-variable -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS + DEBUG_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -gdwarf -flto -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-cast-function-type-mismatch -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS + NOOPT_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -g -gdwarf -O0 -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-cast-function-type-mismatch -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS +RELEASE_XCODE5_X64_CC_FLAGS = -target x86_64-pc-win32-macho -c -flto -Os -Wall -Werror -Wextra -include AutoGen.h -funsigned-char -fno-ms-extensions -fno-stack-protector -fno-builtin -fshort-wchar -mno-implicit-float -mms-bitfields -Wno-unused-parameter -Wno-missing-braces -Wno-missing-field-initializers -Wno-tautological-compare -Wno-sign-compare -Wno-varargs -Wno-cast-function-type-mismatch -Wno-unused-const-variable -Wno-unknown-warning-option -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang -D NO_MSABI_VA_FUNCS ################# # ASM 16 linker definitions From 9e8d89ff384c836c768e0a29c091d1e4cc3ec9ce Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 9 Apr 2025 12:08:06 +0300 Subject: [PATCH 106/341] CodeQL: Removed --npt option, as there are no pip basetools any longer. --- .github/workflows/codeql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 017b827647..f4198a7909 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -253,7 +253,7 @@ jobs: - name: CI Build env: STUART_CODEQL_PATH: ${{ steps.cache_key_gen.outputs.codeql_cli_ext_dep_dir }} - run: stuart_ci_build -c .pytool/CISettings.py -t DEBUG -p ${{ matrix.Package }} -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2022 --codeql --npt + run: stuart_ci_build -c .pytool/CISettings.py -t DEBUG -p ${{ matrix.Package }} -a ${{ matrix.ArchList }} TOOL_CHAIN_TAG=VS2022 --codeql - name: Build Cleanup id: build_cleanup From 0e5812812d22a9b04ed442e8cab754eac434aaef Mon Sep 17 00:00:00 2001 From: Vitaly Cheptsov Date: Mon, 28 Apr 2025 18:09:39 +0300 Subject: [PATCH 107/341] BaseTools/VfrCompile: Fix memory issues Using GCC 13.3.0 discovers an out of bounds memory access in VfrCompile when building DriverSampleDxe. This is also discoverable with ASan. The issue here is that EFI_IFR_TYPE_VALUE is a flexible type and when passed by value for string types only the header part is accessible. Assuming the remainder is zero seems to be ok as gZeroEfiIfrTypeValue is used as a variable source. This change also fixes a warning for new[]/delete[] mismatch discovered by ASan. Signed-off-by: Vitaly Cheptsov --- BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp index 11470de45c..d0ef0d8f26 100644 --- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp +++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp @@ -80,6 +80,12 @@ SConfigInfo::SConfigInfo ( return; } + memset (mValue, 0, mWidth); + + if (mWidth > sizeof(EFI_IFR_TYPE_VALUE)) { + mWidth = sizeof(EFI_IFR_TYPE_VALUE); + } + switch (Type) { case EFI_IFR_TYPE_NUM_SIZE_8 : memcpy (mValue, &Value.u8, mWidth); @@ -2380,7 +2386,7 @@ CVfrDefaultStore::ReRegisterDefaultStoreById ( } if (RefName != NULL) { - delete pNode->mRefName; + delete [] pNode->mRefName; pNode->mRefName = new CHAR8[strlen (RefName) + 1]; if (pNode->mRefName != NULL) { strcpy (pNode->mRefName, RefName); From 03db93400e7e98b0a9c77830de777d737148c611 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 3 Jul 2025 16:39:05 +0300 Subject: [PATCH 108/341] CI: Removed Stale Check. --- .github/workflows/stale.yml | 44 ------------------------------------- 1 file changed, 44 deletions(-) delete mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index b9160b548a..0000000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,44 +0,0 @@ -# This workflow warns and then closes issues and PRs that have had no activity -# for a specified amount of time. -# -# For more information, see: -# https://github.com/actions/stale -# -# Copyright (c) Microsoft Corporation. -# SPDX-License-Identifier: BSD-2-Clause-Patent -# - -name: Stale Check - -on: - schedule: - # At 23:35 on every day-of-week from Sunday through Saturday - # https://crontab.guru/#35_23_*_*_0-6 - - cron: '35 23 * * 0-6' - workflow_dispatch: - -jobs: - stale: - name: Stale - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - - steps: - - name: Check for Stale Items - uses: actions/stale@v8 - with: - days-before-issue-close: -1 - days-before-issue-stale: -1 - days-before-pr-stale: 60 - days-before-pr-close: 7 - stale-pr-message: > - This PR has been automatically marked as stale because it has not had - activity in 60 days. It will be closed if no further activity occurs within - 7 days. Thank you for your contributions. - close-pr-message: > - This pull request has been automatically been closed because it did not have any - activity in 60 days and no follow up within 7 days after being marked stale. - Thank you for your contributions. - stale-pr-label: stale From 1b53daee2423321be20050caa83ba3ef2d7a6667 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 4 Jul 2025 18:00:48 +0300 Subject: [PATCH 109/341] MdeModulePkg: Added IntrinsicLib to fix VS2022 CodeQL stuart_ci_build. --- MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf | 1 + 1 file changed, 1 insertion(+) diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf b/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf index 07e19140b4..59cf288c75 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf +++ b/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf @@ -45,6 +45,7 @@ HiiLib MemoryAllocationLib CustomizedDisplayLib + IntrinsicLib [Protocols] gEdkiiFormDisplayEngineProtocolGuid ## PRODUCES From f39c4bc76a5bc4904159996dd752ac4bb4601a72 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 4 Jul 2025 18:49:14 +0300 Subject: [PATCH 110/341] ShellPkg: Added IntrinsicLib to fix VS2022 CodeQL stuart_ci_build. --- ShellPkg/Application/Shell/Shell.inf | 1 + 1 file changed, 1 insertion(+) diff --git a/ShellPkg/Application/Shell/Shell.inf b/ShellPkg/Application/Shell/Shell.inf index f1e41de133..bc0c82654f 100644 --- a/ShellPkg/Application/Shell/Shell.inf +++ b/ShellPkg/Application/Shell/Shell.inf @@ -66,6 +66,7 @@ SortLib HandleParsingLib UefiHiiServicesLib + IntrinsicLib [Guids] gShellVariableGuid ## SOMETIMES_CONSUMES ## GUID From cf948b80ca29793fe5975ac65d0f9e9c5cc9548f Mon Sep 17 00:00:00 2001 From: MikhailKrichanov <65890930+MikhailKrichanov@users.noreply.github.com> Date: Wed, 16 Jul 2025 15:38:54 +0300 Subject: [PATCH 111/341] Updated links in README.md as Bugzilla moved to GitHub Issues. --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index eaf9aac2f1..772abee533 100644 --- a/README.md +++ b/README.md @@ -89,15 +89,15 @@ To not expose FV-only UEFI image formats via, e.g., DxeCore to untrusted sources * Some validation is still absent ### BZs fixed by integrating the new PE/COFF loader -* https://bugzilla.tianocore.org/show_bug.cgi?id=1860 -* https://bugzilla.tianocore.org/show_bug.cgi?id=1999 -* https://bugzilla.tianocore.org/show_bug.cgi?id=2120 -* https://bugzilla.tianocore.org/show_bug.cgi?id=3329 +* [Verify that loading images with <4k section alignment either succeeds or fails gracefully (Bugzilla Bug 1860)](https://github.com/tianocore/edk2-test/issues/222) +* [PE loader should zero out dest buffer on allocation (Bugzilla Bug 1999)](https://github.com/tianocore/edk2/issues/9757) +* [[PeCoffLib] Provide flexibility for platform to disable TE image support (Bugzilla Bug 2120)](https://github.com/tianocore/edk2/issues/9784) +* [DxeCore: No support for granular PE section permissions (Bugzilla Bug 3329)](https://github.com/tianocore/edk2/issues/10074) * More to be added shortly... ### BZs easier to address by integrating the new PE/COFF loader -* https://bugzilla.tianocore.org/show_bug.cgi?id=3326 -* https://bugzilla.tianocore.org/show_bug.cgi?id=3331 +* [Enforce W^X design principles (Bugzilla Bug 3326)](https://github.com/tianocore/edk2/issues/10072) +* [Treat memory protection attributes separately (Bugzilla Bug 3331)](https://github.com/tianocore/edk2/issues/10075) * More to be added shortly... ## UEFI Executable File Format From 073c953af99d1c17e31e1b41ac39d803d8a1ad99 Mon Sep 17 00:00:00 2001 From: MikhailKrichanov <65890930+MikhailKrichanov@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:19:52 +0300 Subject: [PATCH 112/341] Docs: Added links to README.md and restyled lists. --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 772abee533..b167f33481 100644 --- a/README.md +++ b/README.md @@ -9,20 +9,20 @@ code hardening through various compiler optimizations and codebase architectural Stable branches in AUDK project are constructed by rebasing all the commits in master branch upon EDK II stable tag.
Available stable branches:
-[audk-stable-202211](https://github.com/acidanthera/audk/tree/audk-stable-202211)
-[audk-stable-202302](https://github.com/acidanthera/audk/tree/audk-stable-202302)
-[audk-stable-202305](https://github.com/acidanthera/audk/tree/audk-stable-202305)
-[audk-stable-202311](https://github.com/acidanthera/audk/tree/audk-stable-202311)
-[audk-stable-202405](https://github.com/acidanthera/audk/tree/audk-stable-202405)
+* [audk-stable-202211](https://github.com/acidanthera/audk/tree/audk-stable-202211)
+* [audk-stable-202302](https://github.com/acidanthera/audk/tree/audk-stable-202302)
+* [audk-stable-202305](https://github.com/acidanthera/audk/tree/audk-stable-202305)
+* [audk-stable-202311](https://github.com/acidanthera/audk/tree/audk-stable-202311)
+* [audk-stable-202405](https://github.com/acidanthera/audk/tree/audk-stable-202405)
## Supported features -[PE loader designed with formal methods](#pe-loader-designed-with-formal-methods)
-[UEFI Executable File Format](#uefi-executable-file-format)
-[ImageTool](#imagetool)
-Ext4Pkg, FatPkg: Various improvements based on [Sydr](https://github.com/ispras/oss-sydr-fuzz) fuzzing results
-Introduced CpuArchLib to move the CPU Architectural initialization to DxeCore (https://bugzilla.tianocore.org/show_bug.cgi?id=3223)
-CI checks not only compilation results of various packages but also boot results of Windows 10 / Linux kernels for OVMF, ArmVirtQemu
-Introduced new image protection policy, which forbids loading of unaligned images
+* [PE loader designed with formal methods](#pe-loader-designed-with-formal-methods)
+* [UEFI Executable File Format](#uefi-executable-file-format)
+* [ImageTool](#imagetool)
+* Ext4Pkg, FatPkg: Various improvements based on [Sydr](https://github.com/ispras/oss-sydr-fuzz) fuzzing results
+* [Introduced CpuArchLib to move the CPU Architectural initialization to DxeCore](https://github.com/tianocore/projects/issues/26) ([Bugzilla Bug 3223](https://bugzilla.tianocore.org/show_bug.cgi?id=3223))
+* CI checks not only compilation results of various packages but also boot results of Windows 10 / Linux kernels for [OVMF](.github/workflows/build_x86.yaml) and [ArmVirtQemu](.github/workflows/build_arm.yaml)
+* Introduced [new image protection policy](MdePkg/MdePkg.dec#L2388-L2407), which forbids loading of unaligned images
## PE loader designed with formal methods @@ -116,7 +116,7 @@ To account for this, EDK II’s PeiCore has a workaround to apply the shift to t so that the image file header is technically misaligned, but the image segments are correctly aligned. This is especially important when enforcing memory permissions during PEI. -We propose a novel executable file format (UEFI Executable File Format, [UE](https://github.com/mhaeuser/MastersThesis/tree/main)), +We propose a novel executable file format ([UEFI Executable File Format](MdePkg/Library/BaseUeImageLib), [UE](https://github.com/mhaeuser/MastersThesis/tree/main)), accompanied by a trivial digital signature scheme. (In our repository TE format is completely replaced with UE.) Both help reduce the complexity of parsing and validation, while also encoding metadata much more efficiently than the PE and the TE formats. They are specifically designed for UEFI firmware implementations and are explicitly not optimized @@ -138,7 +138,7 @@ are simply copied into the building directory of those tools. We addressed that issue in our AUDK project greatly increasing code reuse among BaseTools and, in addition, to make image file conversion easier to maintain, extend, and validate, we have replaced ``GenFw`` with ``ImageTool``. -``ImageTool`` implements an approach based on an intermediate representation. +[``ImageTool``](BaseTools/ImageTool) implements an approach based on an intermediate representation. This allows input and output formats to be processed independently of each other. At the same time, operations such as relocating an image became format-independent, contributing to improved extensibility. Because we designed the intermediate representation to be semi-canonical, we were able to use it to reduce the validation of the output file From 6284beb03a18b450d787cf713aae0ebf384b9375 Mon Sep 17 00:00:00 2001 From: MikhailKrichanov <65890930+MikhailKrichanov@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:30:38 +0300 Subject: [PATCH 113/341] Docs: Added new HII design in README.md features' list. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b167f33481..a83bdd6612 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ Available stable branches:
* [Introduced CpuArchLib to move the CPU Architectural initialization to DxeCore](https://github.com/tianocore/projects/issues/26) ([Bugzilla Bug 3223](https://bugzilla.tianocore.org/show_bug.cgi?id=3223))
* CI checks not only compilation results of various packages but also boot results of Windows 10 / Linux kernels for [OVMF](.github/workflows/build_x86.yaml) and [ArmVirtQemu](.github/workflows/build_arm.yaml)
* Introduced [new image protection policy](MdePkg/MdePkg.dec#L2388-L2407), which forbids loading of unaligned images
+* Replaced [PE/COFF resource sections](https://github.com/tianocore/edk2/issues/9583) with a [single C struct](https://github.com/acidanthera/audk/blob/master/BaseTools/ImageTool/ImageTool.c#L24-L116) ## PE loader designed with formal methods From ece0d16e5639047cade55faa382c3f5ed4182b6b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 4 Aug 2025 09:34:47 +0300 Subject: [PATCH 114/341] BaseTools: Removed edk2-stable202502 rebase debris. --- BaseTools/Scripts/GccBase.lds | 96 - BaseTools/Source/C/GenFw/Elf32Convert.c | 1172 -------- BaseTools/Source/C/GenFw/Elf64Convert.c | 2443 ----------------- BaseTools/Source/C/GenFw/ElfConvert.c | 253 -- BaseTools/Source/C/GenFw/GNUmakefile | 27 - BaseTools/Source/C/GenFw/GenFw.c | 3333 ----------------------- 6 files changed, 7324 deletions(-) delete mode 100644 BaseTools/Scripts/GccBase.lds delete mode 100644 BaseTools/Source/C/GenFw/Elf32Convert.c delete mode 100644 BaseTools/Source/C/GenFw/Elf64Convert.c delete mode 100644 BaseTools/Source/C/GenFw/ElfConvert.c delete mode 100644 BaseTools/Source/C/GenFw/GNUmakefile delete mode 100644 BaseTools/Source/C/GenFw/GenFw.c diff --git a/BaseTools/Scripts/GccBase.lds b/BaseTools/Scripts/GccBase.lds deleted file mode 100644 index 8d6c29d7b6..0000000000 --- a/BaseTools/Scripts/GccBase.lds +++ /dev/null @@ -1,96 +0,0 @@ -/** @file - - Unified linker script for GCC and CLANG based builds - - Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.
- Copyright (c) 2015, Linaro Ltd. All rights reserved.
- (C) Copyright 2016 Hewlett Packard Enterprise Development LP
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -PHDRS { - text PT_LOAD FLAGS(5); /* R_X */ - data PT_LOAD FLAGS(6); /* RW_ */ - dynamic PT_DYNAMIC FLAGS(4); /* R__ */ -} - -SECTIONS { - - /* - * The PE/COFF binary consists of DOS and PE/COFF headers, and a sequence of - * section headers adding up to PECOFF_HEADER_SIZE bytes (which differs - * between 32-bit and 64-bit builds). The actual start of the .text section - * will be rounded up based on its actual alignment. - */ - . = PECOFF_HEADER_SIZE; - - .text : ALIGN(CONSTANT(COMMONPAGESIZE)) { - KEEP(*(.entry)) - *(.text .text.* .stub .gnu.linkonce.t.*) - *(.rodata .rodata.* .gnu.linkonce.r.*) - *(.got .got.*) - - /* - * The contents of AutoGen.c files are mostly constant from the POV of the - * program, but most of it ends up in .data or .bss by default since few of - * the variable definitions that get emitted are declared as CONST. - * Unfortunately, we cannot pull it into the .text section entirely, since - * patchable PCDs are also emitted here, but we can at least move all of the - * emitted GUIDs here. - */ - *:AutoGen.obj(.data.g*Guid) - } :text - - /* - * The alignment of the .data section should be less than or equal to the - * alignment of the .text section. This ensures that the relative offset - * between these sections is the same in the ELF and the PE/COFF versions of - * this binary. - */ - .data ALIGN(ALIGNOF(.text)) : ALIGN(CONSTANT(COMMONPAGESIZE)) { - *(.data .data.* .gnu.linkonce.d.*) - *(.bss .bss.*) - } :data - - .eh_frame ALIGN(CONSTANT(COMMONPAGESIZE)) : { - KEEP (*(.eh_frame)) - } - - .dynamic : { *(.dynamic) } :data :dynamic - - .rela (INFO) : { - *(.rela .rela.*) - } - - .hii : ALIGN(CONSTANT(COMMONPAGESIZE)) { - KEEP (*(.hii)) - } :data - - .got : { - *(.got) - } - ASSERT(SIZEOF(.got) == 0, "Unexpected GOT entries detected!") - - .got.plt (INFO) : { - *(.got.plt) - } - ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0xc || SIZEOF(.got.plt) == 0x18, "Unexpected GOT/PLT entries detected!") - - /* - * Retain the GNU build id but in a non-allocatable section so GenFw - * does not copy it into the PE/COFF image. - */ - .build-id (INFO) : { *(.note.gnu.build-id) } - - /DISCARD/ : { - *(.note.GNU-stack) - *(.gnu_debuglink) - *(.interp) - *(.dynsym) - *(.dynstr) - *(.hash .gnu.hash) - *(.comment) - } -} diff --git a/BaseTools/Source/C/GenFw/Elf32Convert.c b/BaseTools/Source/C/GenFw/Elf32Convert.c deleted file mode 100644 index 246497a718..0000000000 --- a/BaseTools/Source/C/GenFw/Elf32Convert.c +++ /dev/null @@ -1,1172 +0,0 @@ -/** @file -Elf32 Convert solution - -Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.
-Portions copyright (c) 2013, ARM Ltd. All rights reserved.
-Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __GNUC__ -#define RUNTIME_FUNCTION _WINNT_DUP_RUNTIME_FUNCTION -#include -#undef RUNTIME_FUNCTION -#include -#endif -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "PeCoffLib.h" -#include "EfiUtilityMsgs.h" - -#include "GenFw.h" -#include "ElfConvert.h" -#include "Elf32Convert.h" - -STATIC -VOID -ScanSections32 ( - VOID - ); - -STATIC -BOOLEAN -WriteSections32 ( - SECTION_FILTER_TYPES FilterType - ); - -STATIC -VOID -WriteRelocations32 ( - VOID - ); - -STATIC -VOID -WriteDebug32 ( - VOID - ); - -STATIC -VOID -SetImageSize32 ( - VOID - ); - -STATIC -VOID -CleanUp32 ( - VOID - ); - -// -// Rename ELF32 structures to common names to help when porting to ELF64. -// -typedef Elf32_Shdr Elf_Shdr; -typedef Elf32_Ehdr Elf_Ehdr; -typedef Elf32_Rel Elf_Rel; -typedef Elf32_Sym Elf_Sym; -typedef Elf32_Phdr Elf_Phdr; -typedef Elf32_Dyn Elf_Dyn; -#define ELFCLASS ELFCLASS32 -#define ELF_R_TYPE(r) ELF32_R_TYPE(r) -#define ELF_R_SYM(r) ELF32_R_SYM(r) - -// -// Well known ELF structures. -// -STATIC Elf_Ehdr *mEhdr; -STATIC Elf_Shdr *mShdrBase; -STATIC Elf_Phdr *mPhdrBase; - -// -// Coff information -// -STATIC UINT32 mCoffAlignment = 0x20; - -// -// PE section alignment. -// -STATIC const UINT16 mCoffNbrSections = 4; - -// -// ELF sections to offset in Coff file. -// -STATIC UINT32 *mCoffSectionsOffset = NULL; - -// -// Offsets in COFF file -// -STATIC UINT32 mNtHdrOffset; -STATIC UINT32 mTextOffset; -STATIC UINT32 mDataOffset; -STATIC UINT32 mHiiRsrcOffset; -STATIC UINT32 mRelocOffset; -STATIC UINT32 mDebugOffset; - -// -// Initialization Function -// -BOOLEAN -InitializeElf32 ( - UINT8 *FileBuffer, - ELF_FUNCTION_TABLE *ElfFunctions - ) -{ - // - // Initialize data pointer and structures. - // - mEhdr = (Elf_Ehdr*) FileBuffer; - - // - // Check the ELF32 specific header information. - // - if (mEhdr->e_ident[EI_CLASS] != ELFCLASS32) { - Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFCLASS32"); - return FALSE; - } - if (mEhdr->e_ident[EI_DATA] != ELFDATA2LSB) { - Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFDATA2LSB"); - return FALSE; - } - if ((mEhdr->e_type != ET_EXEC) && (mEhdr->e_type != ET_DYN)) { - Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN"); - return FALSE; - } - if (!((mEhdr->e_machine == EM_386) || (mEhdr->e_machine == EM_ARM) || (mEhdr->e_machine == EM_RISCV))) { - Warning (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf32 machine."); - } - if (mEhdr->e_version != EV_CURRENT) { - Error (NULL, 0, 3000, "Unsupported", "ELF e_version (%u) not EV_CURRENT (%d)", (unsigned) mEhdr->e_version, EV_CURRENT); - return FALSE; - } - - // - // Update section header pointers - // - mShdrBase = (Elf_Shdr *)((UINT8 *)mEhdr + mEhdr->e_shoff); - mPhdrBase = (Elf_Phdr *)((UINT8 *)mEhdr + mEhdr->e_phoff); - - // - // Create COFF Section offset buffer and zero. - // - mCoffSectionsOffset = (UINT32 *)malloc(mEhdr->e_shnum * sizeof (UINT32)); - if (mCoffSectionsOffset == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - return FALSE; - } - memset(mCoffSectionsOffset, 0, mEhdr->e_shnum * sizeof(UINT32)); - - // - // Fill in function pointers. - // - ElfFunctions->ScanSections = ScanSections32; - ElfFunctions->WriteSections = WriteSections32; - ElfFunctions->WriteRelocations = WriteRelocations32; - ElfFunctions->WriteDebug = WriteDebug32; - ElfFunctions->SetImageSize = SetImageSize32; - ElfFunctions->CleanUp = CleanUp32; - - return TRUE; -} - - -// -// Header by Index functions -// -STATIC -Elf_Shdr* -GetShdrByIndex ( - UINT32 Num - ) -{ - if (Num >= mEhdr->e_shnum) { - Error (NULL, 0, 3000, "Invalid", "GetShdrByIndex: Index %u is too high.", Num); - exit(EXIT_FAILURE); - } - - return (Elf_Shdr*)((UINT8*)mShdrBase + Num * mEhdr->e_shentsize); -} - -STATIC -Elf_Phdr* -GetPhdrByIndex ( - UINT32 num - ) -{ - if (num >= mEhdr->e_phnum) { - Error (NULL, 0, 3000, "Invalid", "GetPhdrByIndex: Index %u is too high.", num); - exit(EXIT_FAILURE); - } - - return (Elf_Phdr *)((UINT8*)mPhdrBase + num * mEhdr->e_phentsize); -} - -STATIC -UINT32 -CoffAlign ( - UINT32 Offset - ) -{ - return (Offset + mCoffAlignment - 1) & ~(mCoffAlignment - 1); -} - -STATIC -UINT32 -DebugRvaAlign ( - UINT32 Offset - ) -{ - return (Offset + 3) & ~3; -} - -// -// filter functions -// -STATIC -BOOLEAN -IsTextShdr ( - Elf_Shdr *Shdr - ) -{ - return (BOOLEAN) (((Shdr->sh_flags & (SHF_EXECINSTR | SHF_ALLOC)) == (SHF_EXECINSTR | SHF_ALLOC)) || - ((Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC)); -} - -STATIC -BOOLEAN -IsHiiRsrcShdr ( - Elf_Shdr *Shdr - ) -{ - Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx); - - return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); -} - -STATIC -BOOLEAN -IsDataShdr ( - Elf_Shdr *Shdr - ) -{ - if (IsHiiRsrcShdr(Shdr)) { - return FALSE; - } - return (BOOLEAN) (Shdr->sh_flags & (SHF_EXECINSTR | SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE); -} - -STATIC -BOOLEAN -IsStrtabShdr ( - Elf_Shdr *Shdr - ) -{ - Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx); - - return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_STRTAB_SECTION_NAME) == 0); -} - -STATIC -Elf_Shdr * -FindStrtabShdr ( - VOID - ) -{ - UINT32 i; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsStrtabShdr(shdr)) { - return shdr; - } - } - return NULL; -} - -STATIC -const UINT8 * -GetSymName ( - Elf_Sym *Sym - ) -{ - Elf_Shdr *StrtabShdr; - UINT8 *StrtabContents; - BOOLEAN foundEnd; - UINT32 i; - - if (Sym->st_name == 0) { - return NULL; - } - - StrtabShdr = FindStrtabShdr(); - if (StrtabShdr == NULL) { - return NULL; - } - - assert(Sym->st_name < StrtabShdr->sh_size); - - StrtabContents = (UINT8*)mEhdr + StrtabShdr->sh_offset; - - foundEnd = FALSE; - for (i = Sym->st_name; (i < StrtabShdr->sh_size) && !foundEnd; i++) { - foundEnd = (BOOLEAN)(StrtabContents[i] == 0); - } - assert(foundEnd); - - return StrtabContents + Sym->st_name; -} - -// -// Elf functions interface implementation -// - -STATIC -VOID -ScanSections32 ( - VOID - ) -{ - UINT32 i; - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - UINT32 CoffEntry; - UINT32 SectionCount; - BOOLEAN FoundSection; - - CoffEntry = 0; - mCoffOffset = 0; - - // - // Coff file start with a DOS header. - // - mCoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40; - mNtHdrOffset = mCoffOffset; - switch (mEhdr->e_machine) { - case EM_386: - case EM_ARM: - mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32); - break; - default: - VerboseMsg ("%u unknown e_machine type. Assume IA-32", (UINTN)mEhdr->e_machine); - mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32); - break; - } - - mTableOffset = mCoffOffset; - mCoffOffset += mCoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER); - - // - // Set mCoffAlignment to the maximum alignment of the input sections - // we care about - // - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (shdr->sh_addralign <= mCoffAlignment) { - continue; - } - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) { - mCoffAlignment = (UINT32)shdr->sh_addralign; - } - } - - // - // Check if mCoffAlignment is larger than MAX_COFF_ALIGNMENT - // - if (mCoffAlignment > MAX_COFF_ALIGNMENT) { - Error (NULL, 0, 3000, "Invalid", "Section alignment is larger than MAX_COFF_ALIGNMENT."); - assert (FALSE); - } - - // - // Move the PE/COFF header right before the first section. This will help us - // save space when converting to TE. - // - if (mCoffAlignment > mCoffOffset) { - mNtHdrOffset += mCoffAlignment - mCoffOffset; - mTableOffset += mCoffAlignment - mCoffOffset; - mCoffOffset = mCoffAlignment; - } - - // - // First text sections. - // - mCoffOffset = CoffAlign(mCoffOffset); - mTextOffset = mCoffOffset; - FoundSection = FALSE; - SectionCount = 0; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsTextShdr(shdr)) { - if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { - // the alignment field is valid - if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { - // if the section address is aligned we must align PE/COFF - mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1); - } else { - Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment."); - } - } - - /* Relocate entry. */ - if ((mEhdr->e_entry >= shdr->sh_addr) && - (mEhdr->e_entry < shdr->sh_addr + shdr->sh_size)) { - CoffEntry = mCoffOffset + mEhdr->e_entry - shdr->sh_addr; - } - - // - // Set mTextOffset with the offset of the first '.text' section - // - if (!FoundSection) { - mTextOffset = mCoffOffset; - FoundSection = TRUE; - } - - mCoffSectionsOffset[i] = mCoffOffset; - mCoffOffset += shdr->sh_size; - SectionCount ++; - } - } - - if (!FoundSection && mOutImageType != FW_ACPI_IMAGE) { - Error (NULL, 0, 3000, "Invalid", "Did not find any '.text' section."); - assert (FALSE); - } - - mDebugOffset = DebugRvaAlign(mCoffOffset); - mCoffOffset = CoffAlign(mCoffOffset); - - if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) { - Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged into 1 text section. Source level debug might not work correctly.", mInImageName); - } - - // - // Then data sections. - // - mDataOffset = mCoffOffset; - FoundSection = FALSE; - SectionCount = 0; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsDataShdr(shdr)) { - if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { - // the alignment field is valid - if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { - // if the section address is aligned we must align PE/COFF - mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1); - } else { - Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment."); - } - } - - // - // Set mDataOffset with the offset of the first '.data' section - // - if (!FoundSection) { - mDataOffset = mCoffOffset; - FoundSection = TRUE; - } - - mCoffSectionsOffset[i] = mCoffOffset; - mCoffOffset += shdr->sh_size; - SectionCount ++; - } - } - - if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) { - Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName); - } - - // - // Make room for .debug data in .data (or .text if .data is empty) instead of - // putting it in a section of its own. This is explicitly allowed by the - // PE/COFF spec, and prevents bloat in the binary when using large values for - // section alignment. - // - if (SectionCount > 0) { - mDebugOffset = DebugRvaAlign(mCoffOffset); - } - mCoffOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) + - sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + - strlen(mInImageName) + 1; - - mCoffOffset = CoffAlign(mCoffOffset); - if (SectionCount == 0) { - mDataOffset = mCoffOffset; - } - - // - // The HII resource sections. - // - mHiiRsrcOffset = mCoffOffset; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsHiiRsrcShdr(shdr)) { - if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { - // the alignment field is valid - if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { - // if the section address is aligned we must align PE/COFF - mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1); - } else { - Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment."); - } - } - if (shdr->sh_size != 0) { - mHiiRsrcOffset = mCoffOffset; - mCoffSectionsOffset[i] = mCoffOffset; - mCoffOffset += shdr->sh_size; - mCoffOffset = CoffAlign(mCoffOffset); - SetHiiResourceHeader ((UINT8*) mEhdr + shdr->sh_offset, mHiiRsrcOffset); - } - break; - } - } - - mRelocOffset = mCoffOffset; - - // - // Allocate base Coff file. Will be expanded later for relocations. - // - mCoffFile = (UINT8 *)malloc(mCoffOffset); - if (mCoffFile == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - } - assert (mCoffFile != NULL); - memset(mCoffFile, 0, mCoffOffset); - - // - // Fill headers. - // - DosHdr = (EFI_IMAGE_DOS_HEADER *)mCoffFile; - DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE; - DosHdr->e_lfanew = mNtHdrOffset; - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(mCoffFile + mNtHdrOffset); - - NtHdr->Pe32.Signature = EFI_IMAGE_NT_SIGNATURE; - - switch (mEhdr->e_machine) { - case EM_386: - NtHdr->Pe32.FileHeader.Machine = IMAGE_FILE_MACHINE_I386; - NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; - break; - case EM_ARM: - NtHdr->Pe32.FileHeader.Machine = IMAGE_FILE_MACHINE_ARMTHUMB_MIXED; - NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; - break; - default: - VerboseMsg ("%s unknown e_machine type %hu. Assume IA-32", mInImageName, mEhdr->e_machine); - NtHdr->Pe32.FileHeader.Machine = IMAGE_FILE_MACHINE_I386; - NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; - } - - NtHdr->Pe32.FileHeader.NumberOfSections = mCoffNbrSections; - NtHdr->Pe32.FileHeader.TimeDateStamp = (UINT32) time(NULL); - mImageTimeStamp = NtHdr->Pe32.FileHeader.TimeDateStamp; - NtHdr->Pe32.FileHeader.PointerToSymbolTable = 0; - NtHdr->Pe32.FileHeader.NumberOfSymbols = 0; - NtHdr->Pe32.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32.OptionalHeader); - NtHdr->Pe32.FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE - | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED - | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED - | EFI_IMAGE_FILE_32BIT_MACHINE; - - NtHdr->Pe32.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset; - NtHdr->Pe32.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset; - NtHdr->Pe32.OptionalHeader.SizeOfUninitializedData = 0; - NtHdr->Pe32.OptionalHeader.AddressOfEntryPoint = CoffEntry; - - NtHdr->Pe32.OptionalHeader.BaseOfCode = mTextOffset; - - NtHdr->Pe32.OptionalHeader.BaseOfData = mDataOffset; - NtHdr->Pe32.OptionalHeader.ImageBase = 0; - NtHdr->Pe32.OptionalHeader.SectionAlignment = mCoffAlignment; - NtHdr->Pe32.OptionalHeader.FileAlignment = mCoffAlignment; - NtHdr->Pe32.OptionalHeader.SizeOfImage = 0; - - NtHdr->Pe32.OptionalHeader.SizeOfHeaders = mTextOffset; - NtHdr->Pe32.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES; - - // - // Section headers. - // - if ((mDataOffset - mTextOffset) > 0) { - CreateSectionHeader (".text", mTextOffset, mDataOffset - mTextOffset, - EFI_IMAGE_SCN_CNT_CODE - | EFI_IMAGE_SCN_MEM_EXECUTE - | EFI_IMAGE_SCN_MEM_READ); - } else { - // Don't make a section of size 0. - NtHdr->Pe32.FileHeader.NumberOfSections--; - } - - if ((mHiiRsrcOffset - mDataOffset) > 0) { - CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_WRITE - | EFI_IMAGE_SCN_MEM_READ); - } else { - // Don't make a section of size 0. - NtHdr->Pe32.FileHeader.NumberOfSections--; - } - - if ((mRelocOffset - mHiiRsrcOffset) > 0) { - CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_READ); - - NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = mRelocOffset - mHiiRsrcOffset; - NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = mHiiRsrcOffset; - } else { - // Don't make a section of size 0. - NtHdr->Pe32.FileHeader.NumberOfSections--; - } - -} - -STATIC -BOOLEAN -WriteSections32 ( - SECTION_FILTER_TYPES FilterType - ) -{ - UINT32 Idx; - Elf_Shdr *SecShdr; - UINT32 SecOffset; - BOOLEAN (*Filter)(Elf_Shdr *); - - // - // Initialize filter pointer - // - switch (FilterType) { - case SECTION_TEXT: - Filter = IsTextShdr; - break; - case SECTION_HII: - Filter = IsHiiRsrcShdr; - break; - case SECTION_DATA: - Filter = IsDataShdr; - break; - default: - return FALSE; - } - - // - // First: copy sections. - // - for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) { - Elf_Shdr *Shdr = GetShdrByIndex(Idx); - if ((*Filter)(Shdr)) { - switch (Shdr->sh_type) { - case SHT_PROGBITS: - /* Copy. */ - if (Shdr->sh_offset + Shdr->sh_size > mFileBufferSize) { - return FALSE; - } - memcpy(mCoffFile + mCoffSectionsOffset[Idx], - (UINT8*)mEhdr + Shdr->sh_offset, - Shdr->sh_size); - break; - - case SHT_NOBITS: - memset(mCoffFile + mCoffSectionsOffset[Idx], 0, Shdr->sh_size); - break; - - default: - // - // Ignore for unknown section type. - // - VerboseMsg ("%s unknown section type %x. We ignore this unknown section type.", mInImageName, (unsigned)Shdr->sh_type); - break; - } - } - } - - // - // Second: apply relocations. - // - for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) { - // - // Determine if this is a relocation section. - // - Elf_Shdr *RelShdr = GetShdrByIndex(Idx); - if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) { - continue; - } - - // - // Relocation section found. Now extract section information that the relocations - // apply to in the ELF data and the new COFF data. - // - SecShdr = GetShdrByIndex(RelShdr->sh_info); - SecOffset = mCoffSectionsOffset[RelShdr->sh_info]; - - // - // Only process relocations for the current filter type. - // - if (RelShdr->sh_type == SHT_REL && (*Filter)(SecShdr)) { - UINT32 RelOffset; - - // - // Determine the symbol table referenced by the relocation data. - // - Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link); - UINT8 *Symtab = (UINT8*)mEhdr + SymtabShdr->sh_offset; - - // - // Process all relocation entries for this section. - // - for (RelOffset = 0; RelOffset < RelShdr->sh_size; RelOffset += RelShdr->sh_entsize) { - // - // Set pointer to relocation entry - // - Elf_Rel *Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelOffset); - - // - // Set pointer to symbol table entry associated with the relocation entry. - // - Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize); - - Elf_Shdr *SymShdr; - UINT8 *Targ; - UINT16 Address; - - // - // Check section header index found in symbol table and get the section - // header location. - // - if (Sym->st_shndx == SHN_UNDEF - || Sym->st_shndx >= mEhdr->e_shnum) { - const UINT8 *SymName = GetSymName(Sym); - if (SymName == NULL) { - SymName = (const UINT8 *)""; - } - continue; - } - SymShdr = GetShdrByIndex(Sym->st_shndx); - - // - // Convert the relocation data to a pointer into the coff file. - // - // Note: - // r_offset is the virtual address of the storage unit to be relocated. - // sh_addr is the virtual address for the base of the section. - // - Targ = mCoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr); - - // - // Determine how to handle each relocation type based on the machine type. - // - if (mEhdr->e_machine == EM_386) { - switch (ELF_R_TYPE(Rel->r_info)) { - case R_386_NONE: - break; - case R_386_32: - // - // Absolute relocation. - // Converts Targ from a absolute virtual address to the absolute - // COFF address. - // - *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr - + mCoffSectionsOffset[Sym->st_shndx]; - break; - case R_386_PC32: - // - // Relative relocation: Symbol - Ip + Addend - // - *(UINT32 *)Targ = *(UINT32 *)Targ - + (mCoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr) - - (SecOffset - SecShdr->sh_addr); - break; - default: - Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_386 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } - } else if (mEhdr->e_machine == EM_ARM) { - switch (ELF32_R_TYPE(Rel->r_info)) { - case R_ARM_RBASE: - // No relocation - no action required - // break skipped - - case R_ARM_PC24: - case R_ARM_REL32: - case R_ARM_XPC25: - case R_ARM_THM_PC22: - case R_ARM_THM_JUMP19: - case R_ARM_CALL: - case R_ARM_JMP24: - case R_ARM_THM_JUMP24: - case R_ARM_PREL31: - case R_ARM_MOVW_PREL_NC: - case R_ARM_MOVT_PREL: - case R_ARM_THM_MOVW_PREL_NC: - case R_ARM_THM_MOVT_PREL: - case R_ARM_THM_JMP6: - case R_ARM_THM_ALU_PREL_11_0: - case R_ARM_THM_PC12: - case R_ARM_REL32_NOI: - case R_ARM_ALU_PC_G0_NC: - case R_ARM_ALU_PC_G0: - case R_ARM_ALU_PC_G1_NC: - case R_ARM_ALU_PC_G1: - case R_ARM_ALU_PC_G2: - case R_ARM_LDR_PC_G1: - case R_ARM_LDR_PC_G2: - case R_ARM_LDRS_PC_G0: - case R_ARM_LDRS_PC_G1: - case R_ARM_LDRS_PC_G2: - case R_ARM_LDC_PC_G0: - case R_ARM_LDC_PC_G1: - case R_ARM_LDC_PC_G2: - case R_ARM_THM_JUMP11: - case R_ARM_THM_JUMP8: - case R_ARM_TLS_GD32: - case R_ARM_TLS_LDM32: - case R_ARM_TLS_IE32: - // Thease are all PC-relative relocations and don't require modification - // GCC does not seem to have the concept of a application that just needs to get relocated. - break; - - case R_ARM_THM_MOVW_ABS_NC: - // MOVW is only lower 16-bits of the addres - Address = (UINT16)(Sym->st_value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]); - ThumbMovtImmediatePatch ((UINT16 *)Targ, Address); - break; - - case R_ARM_THM_MOVT_ABS: - // MOVT is only upper 16-bits of the addres - Address = (UINT16)((Sym->st_value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]) >> 16); - ThumbMovtImmediatePatch ((UINT16 *)Targ, Address); - break; - - case R_ARM_ABS32: - case R_ARM_RABS32: - // - // Absolute relocation. - // - *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]; - break; - - default: - Error (NULL, 0, 3000, "Invalid", "WriteSections (): %s unsupported ELF EM_ARM relocation 0x%x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info)); - } - } - } - } - } - - return TRUE; -} - -UINTN gMovwOffset = 0; - -STATIC -VOID -WriteRelocations32 ( - VOID - ) -{ - UINT32 Index; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - EFI_IMAGE_DATA_DIRECTORY *Dir; - BOOLEAN FoundRelocations; - Elf_Dyn *Dyn; - Elf_Rel *Rel; - UINTN RelElementSize; - UINTN RelSize; - UINTN RelOffset; - UINTN K; - Elf32_Phdr *DynamicSegment; - - for (Index = 0, FoundRelocations = FALSE; Index < mEhdr->e_shnum; Index++) { - Elf_Shdr *RelShdr = GetShdrByIndex(Index); - if ((RelShdr->sh_type == SHT_REL) || (RelShdr->sh_type == SHT_RELA)) { - Elf_Shdr *SecShdr = GetShdrByIndex (RelShdr->sh_info); - if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) { - UINT32 RelIdx; - - FoundRelocations = TRUE; - for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) { - Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx); - - if (mEhdr->e_machine == EM_386) { - switch (ELF_R_TYPE(Rel->r_info)) { - case R_386_NONE: - case R_386_PC32: - // - // No fixup entry required. - // - break; - case R_386_32: - // - // Creates a relative relocation entry from the absolute entry. - // - CoffAddFixup(mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr), - EFI_IMAGE_REL_BASED_HIGHLOW); - break; - default: - Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_386 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } - } else if (mEhdr->e_machine == EM_ARM) { - switch (ELF32_R_TYPE(Rel->r_info)) { - case R_ARM_RBASE: - // No relocation - no action required - // break skipped - - case R_ARM_PC24: - case R_ARM_REL32: - case R_ARM_XPC25: - case R_ARM_THM_PC22: - case R_ARM_THM_JUMP19: - case R_ARM_CALL: - case R_ARM_JMP24: - case R_ARM_THM_JUMP24: - case R_ARM_PREL31: - case R_ARM_MOVW_PREL_NC: - case R_ARM_MOVT_PREL: - case R_ARM_THM_MOVW_PREL_NC: - case R_ARM_THM_MOVT_PREL: - case R_ARM_THM_JMP6: - case R_ARM_THM_ALU_PREL_11_0: - case R_ARM_THM_PC12: - case R_ARM_REL32_NOI: - case R_ARM_ALU_PC_G0_NC: - case R_ARM_ALU_PC_G0: - case R_ARM_ALU_PC_G1_NC: - case R_ARM_ALU_PC_G1: - case R_ARM_ALU_PC_G2: - case R_ARM_LDR_PC_G1: - case R_ARM_LDR_PC_G2: - case R_ARM_LDRS_PC_G0: - case R_ARM_LDRS_PC_G1: - case R_ARM_LDRS_PC_G2: - case R_ARM_LDC_PC_G0: - case R_ARM_LDC_PC_G1: - case R_ARM_LDC_PC_G2: - case R_ARM_THM_JUMP11: - case R_ARM_THM_JUMP8: - case R_ARM_TLS_GD32: - case R_ARM_TLS_LDM32: - case R_ARM_TLS_IE32: - // Thease are all PC-relative relocations and don't require modification - break; - - case R_ARM_THM_MOVW_ABS_NC: - CoffAddFixup ( - mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr), - EFI_IMAGE_REL_BASED_ARM_MOV32T - ); - - // PE/COFF treats MOVW/MOVT relocation as single 64-bit instruction - // Track this address so we can log an error for unsupported sequence of MOVW/MOVT - gMovwOffset = mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr); - break; - - case R_ARM_THM_MOVT_ABS: - if ((gMovwOffset + 4) != (mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr))) { - Error (NULL, 0, 3000, "Not Supported", "PE/COFF requires MOVW+MOVT instruction sequence %x +4 != %x.", gMovwOffset, mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr)); - } - break; - - case R_ARM_ABS32: - case R_ARM_RABS32: - CoffAddFixup ( - mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr), - EFI_IMAGE_REL_BASED_HIGHLOW - ); - break; - - default: - Error (NULL, 0, 3000, "Invalid", "WriteRelocations(): %s unsupported ELF EM_ARM relocation 0x%x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info)); - } - } else { - Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine); - } - } - } - } - } - - if (!FoundRelocations && (mEhdr->e_machine == EM_ARM)) { - /* Try again, but look for PT_DYNAMIC instead of SHT_REL */ - - for (Index = 0; Index < mEhdr->e_phnum; Index++) { - RelElementSize = 0; - RelSize = 0; - RelOffset = 0; - - DynamicSegment = GetPhdrByIndex (Index); - - if (DynamicSegment->p_type == PT_DYNAMIC) { - Dyn = (Elf32_Dyn *) ((UINT8 *)mEhdr + DynamicSegment->p_offset); - - while (Dyn->d_tag != DT_NULL) { - switch (Dyn->d_tag) { - case DT_REL: - RelOffset = Dyn->d_un.d_val; - break; - - case DT_RELSZ: - RelSize = Dyn->d_un.d_val; - break; - - case DT_RELENT: - RelElementSize = Dyn->d_un.d_val; - break; - - default: - break; - } - Dyn++; - } - if (( RelOffset == 0 ) || ( RelSize == 0 ) || ( RelElementSize == 0 )) { - Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations.", mInImageName); - } - - for (Index = 0; Index < mEhdr->e_shnum; Index++) { - Elf_Shdr *shdr = GetShdrByIndex(Index); - - // - // The PT_DYNAMIC section contains DT_REL relocations whose r_offset - // field is relative to the base of a segment (or the entire image), - // and not to the base of an ELF input section as is the case for - // SHT_REL sections. This means that we cannot fix up such relocations - // unless we cross-reference ELF sections and segments, considering - // that the output placement recorded in mCoffSectionsOffset[] is - // section based, not segment based. - // - // Fortunately, there is a simple way around this: we require that the - // in-memory layout of the ELF and PE/COFF versions of the binary is - // identical. That way, r_offset will retain its validity as a PE/COFF - // image offset, and we can record it in the COFF fixup table - // unmodified. - // - if (shdr->sh_addr != mCoffSectionsOffset[Index]) { - Error (NULL, 0, 3000, - "Invalid", "%s: PT_DYNAMIC relocations require identical ELF and PE/COFF section offsets.", - mInImageName); - } - } - - for (K = 0; K < RelSize; K += RelElementSize) { - - if (DynamicSegment->p_paddr == 0) { - // Older versions of the ARM ELF (SWS ESPC 0003 B-02) specification define DT_REL - // as an offset in the dynamic segment. p_paddr is defined to be zero for ARM tools - Rel = (Elf32_Rel *) ((UINT8 *) mEhdr + DynamicSegment->p_offset + RelOffset + K); - } else { - // This is how it reads in the generic ELF specification - Rel = (Elf32_Rel *) ((UINT8 *) mEhdr + RelOffset + K); - } - - switch (ELF32_R_TYPE (Rel->r_info)) { - case R_ARM_RBASE: - break; - - case R_ARM_RABS32: - CoffAddFixup (Rel->r_offset, EFI_IMAGE_REL_BASED_HIGHLOW); - break; - - default: - Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations, unknown type %d.", mInImageName, ELF32_R_TYPE (Rel->r_info)); - break; - } - } - break; - } - } - } - - // - // Pad by adding empty entries. - // - while (mCoffOffset & (mCoffAlignment - 1)) { - CoffAddFixupEntry(0); - } - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); - Dir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - Dir->Size = mCoffOffset - mRelocOffset; - if (Dir->Size == 0) { - // If no relocations, null out the directory entry and don't add the .reloc section - Dir->VirtualAddress = 0; - NtHdr->Pe32.FileHeader.NumberOfSections--; - } else { - Dir->VirtualAddress = mRelocOffset; - CreateSectionHeader (".reloc", mRelocOffset, mCoffOffset - mRelocOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_DISCARDABLE - | EFI_IMAGE_SCN_MEM_READ); - } - -} - -STATIC -VOID -WriteDebug32 ( - VOID - ) -{ - UINT32 Len; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - EFI_IMAGE_DATA_DIRECTORY *DataDir; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir; - EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10; - - Len = strlen(mInImageName) + 1; - - Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + mDebugOffset); - Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW; - Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len; - Dir->RVA = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - Dir->FileOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - - Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1); - Nb10->Signature = CODEVIEW_SIGNATURE_NB10; - strcpy ((char *)(Nb10 + 1), mInImageName); - - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); - DataDir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]; - DataDir->VirtualAddress = mDebugOffset; - DataDir->Size = sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); -} - -STATIC -VOID -SetImageSize32 ( - VOID - ) -{ - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - - // - // Set image size - // - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); - NtHdr->Pe32.OptionalHeader.SizeOfImage = mCoffOffset; -} - -STATIC -VOID -CleanUp32 ( - VOID - ) -{ - if (mCoffSectionsOffset != NULL) { - free (mCoffSectionsOffset); - } -} - - diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c b/BaseTools/Source/C/GenFw/Elf64Convert.c deleted file mode 100644 index 6919e18809..0000000000 --- a/BaseTools/Source/C/GenFw/Elf64Convert.c +++ /dev/null @@ -1,2443 +0,0 @@ -/** @file -Elf64 convert solution - -Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.
-Portions copyright (c) 2013-2022, ARM Ltd. All rights reserved.
-Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
-Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __GNUC__ -#define RUNTIME_FUNCTION _WINNT_DUP_RUNTIME_FUNCTION -#include -#undef RUNTIME_FUNCTION -#include -#endif -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "PeCoffLib.h" -#include "EfiUtilityMsgs.h" - -#include "GenFw.h" -#include "ElfConvert.h" -#include "Elf64Convert.h" - -STATIC -VOID -ScanSections64 ( - VOID - ); - -STATIC -BOOLEAN -WriteSections64 ( - SECTION_FILTER_TYPES FilterType - ); - -STATIC -VOID -WriteRelocations64 ( - VOID - ); - -STATIC -VOID -WriteDebug64 ( - VOID - ); - -STATIC -VOID -WriteExport64 ( - VOID - ); - -STATIC -VOID -SetImageSize64 ( - VOID - ); - -STATIC -VOID -CleanUp64 ( - VOID - ); - -// -// Rename ELF32 structures to common names to help when porting to ELF64. -// -typedef Elf64_Shdr Elf_Shdr; -typedef Elf64_Ehdr Elf_Ehdr; -typedef Elf64_Rel Elf_Rel; -typedef Elf64_Rela Elf_Rela; -typedef Elf64_Sym Elf_Sym; -typedef Elf64_Phdr Elf_Phdr; -typedef Elf64_Dyn Elf_Dyn; -#define ELFCLASS ELFCLASS64 -#define ELF_R_TYPE(r) ELF64_R_TYPE(r) -#define ELF_R_SYM(r) ELF64_R_SYM(r) - -// -// Well known ELF structures. -// -STATIC Elf_Ehdr *mEhdr; -STATIC Elf_Shdr *mShdrBase; -STATIC Elf_Phdr *mPhdrBase; - -// -// GOT information -// -STATIC Elf_Shdr *mGOTShdr = NULL; -STATIC UINT32 mGOTShindex = 0; -STATIC UINT32 *mGOTCoffEntries = NULL; -STATIC UINT32 mGOTMaxCoffEntries = 0; -STATIC UINT32 mGOTNumCoffEntries = 0; - -// -// Coff information -// -STATIC UINT32 mCoffAlignment = 0x20; - -// -// PE section alignment. -// -STATIC UINT16 mCoffNbrSections = 4; - -// -// ELF sections to offset in Coff file. -// -STATIC UINT32 *mCoffSectionsOffset = NULL; - -// -// Offsets in COFF file -// -STATIC UINT32 mNtHdrOffset; -STATIC UINT32 mTextOffset; -STATIC UINT32 mDataOffset; -STATIC UINT32 mHiiRsrcOffset; -STATIC UINT32 mRelocOffset; -STATIC UINT32 mDebugOffset; -STATIC UINT32 mExportOffset; -// -// Used for RISC-V relocations. -// -STATIC UINT8 *mRiscVPass1Targ = NULL; -STATIC Elf_Shdr *mRiscVPass1Sym = NULL; -STATIC Elf64_Half mRiscVPass1SymSecIndex = 0; -STATIC INT32 mRiscVPass1Offset; -STATIC INT32 mRiscVPass1GotFixup; - -// -// Used for Export section. -// -STATIC UINT32 mExportSize; -STATIC UINT32 mExportRVA[PRM_MODULE_EXPORT_SYMBOL_NUM]; -STATIC UINT32 mExportSymNum; -STATIC CHAR8 mExportSymName[PRM_MODULE_EXPORT_SYMBOL_NUM][PRM_HANDLER_NAME_MAXIMUM_LENGTH]; - -// -// Initialization Function -// -BOOLEAN -InitializeElf64 ( - UINT8 *FileBuffer, - ELF_FUNCTION_TABLE *ElfFunctions - ) -{ - // - // Initialize data pointer and structures. - // - VerboseMsg ("Set EHDR"); - mEhdr = (Elf_Ehdr*) FileBuffer; - - // - // Check the ELF64 specific header information. - // - VerboseMsg ("Check ELF64 Header Information"); - if (mEhdr->e_ident[EI_CLASS] != ELFCLASS64) { - Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFCLASS64"); - return FALSE; - } - if (mEhdr->e_ident[EI_DATA] != ELFDATA2LSB) { - Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFDATA2LSB"); - return FALSE; - } - if ((mEhdr->e_type != ET_EXEC) && (mEhdr->e_type != ET_DYN)) { - Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN"); - return FALSE; - } - if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64) || (mEhdr->e_machine == EM_RISCV64) || (mEhdr->e_machine == EM_LOONGARCH))) { - Warning (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf64 machine."); - } - if (mEhdr->e_version != EV_CURRENT) { - Error (NULL, 0, 3000, "Unsupported", "ELF e_version (%u) not EV_CURRENT (%d)", (unsigned) mEhdr->e_version, EV_CURRENT); - return FALSE; - } - - if (mExportFlag) { - if ((mEhdr->e_machine != EM_X86_64) && (mEhdr->e_machine != EM_AARCH64)) { - Error (NULL, 0, 3000, "Unsupported", "--prm option currently only supports X64 and AArch64 archs."); - return FALSE; - } - } - - // - // Update section header pointers - // - VerboseMsg ("Update Header Pointers"); - mShdrBase = (Elf_Shdr *)((UINT8 *)mEhdr + mEhdr->e_shoff); - mPhdrBase = (Elf_Phdr *)((UINT8 *)mEhdr + mEhdr->e_phoff); - - // - // Create COFF Section offset buffer and zero. - // - VerboseMsg ("Create COFF Section Offset Buffer"); - mCoffSectionsOffset = (UINT32 *)malloc(mEhdr->e_shnum * sizeof (UINT32)); - if (mCoffSectionsOffset == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - return FALSE; - } - memset(mCoffSectionsOffset, 0, mEhdr->e_shnum * sizeof(UINT32)); - - // - // Fill in function pointers. - // - VerboseMsg ("Fill in Function Pointers"); - ElfFunctions->ScanSections = ScanSections64; - ElfFunctions->WriteSections = WriteSections64; - ElfFunctions->WriteRelocations = WriteRelocations64; - ElfFunctions->WriteDebug = WriteDebug64; - ElfFunctions->SetImageSize = SetImageSize64; - ElfFunctions->CleanUp = CleanUp64; - - if (mExportFlag) { - mCoffNbrSections ++; - ElfFunctions->WriteExport = WriteExport64; - } - - return TRUE; -} - - -// -// Header by Index functions -// -STATIC -Elf_Shdr* -GetShdrByIndex ( - UINT32 Num - ) -{ - if (Num >= mEhdr->e_shnum) { - Error (NULL, 0, 3000, "Invalid", "GetShdrByIndex: Index %u is too high.", Num); - exit(EXIT_FAILURE); - } - - return (Elf_Shdr*)((UINT8*)mShdrBase + Num * mEhdr->e_shentsize); -} - -STATIC -UINT32 -CoffAlign ( - UINT32 Offset - ) -{ - return (Offset + mCoffAlignment - 1) & ~(mCoffAlignment - 1); -} - -STATIC -UINT32 -DebugRvaAlign ( - UINT32 Offset - ) -{ - return (Offset + 3) & ~3; -} - -// -// filter functions -// -STATIC -BOOLEAN -IsTextShdr ( - Elf_Shdr *Shdr - ) -{ - return (BOOLEAN) (((Shdr->sh_flags & (SHF_EXECINSTR | SHF_ALLOC)) == (SHF_EXECINSTR | SHF_ALLOC)) || - ((Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC)); -} - -STATIC -BOOLEAN -IsHiiRsrcShdr ( - Elf_Shdr *Shdr - ) -{ - Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx); - - return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); -} - -STATIC -BOOLEAN -IsSymbolShdr ( - Elf_Shdr *Shdr - ) -{ - Elf_Shdr *Namehdr = GetShdrByIndex(mEhdr->e_shstrndx); - - return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namehdr->sh_offset + Shdr->sh_name, ELF_SYMBOL_SECTION_NAME) == 0); -} - -STATIC -BOOLEAN -IsDataShdr ( - Elf_Shdr *Shdr - ) -{ - if (IsHiiRsrcShdr(Shdr)) { - return FALSE; - } - return (BOOLEAN) (Shdr->sh_flags & (SHF_EXECINSTR | SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE); -} - -STATIC -BOOLEAN -IsStrtabShdr ( - Elf_Shdr *Shdr - ) -{ - Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx); - - return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_STRTAB_SECTION_NAME) == 0); -} - -STATIC -Elf_Shdr * -FindStrtabShdr ( - VOID - ) -{ - UINT32 i; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsStrtabShdr(shdr)) { - return shdr; - } - } - return NULL; -} - -STATIC -const UINT8 * -GetSymName ( - Elf_Sym *Sym - ) -{ - Elf_Shdr *StrtabShdr; - UINT8 *StrtabContents; - BOOLEAN foundEnd; - UINT32 i; - - if (Sym->st_name == 0) { - return NULL; - } - - StrtabShdr = FindStrtabShdr(); - if (StrtabShdr == NULL) { - return NULL; - } - - assert(Sym->st_name < StrtabShdr->sh_size); - - StrtabContents = (UINT8*)mEhdr + StrtabShdr->sh_offset; - - foundEnd = FALSE; - for (i= Sym->st_name; (i < StrtabShdr->sh_size) && !foundEnd; i++) { - foundEnd = (BOOLEAN)(StrtabContents[i] == 0); - } - assert(foundEnd); - - return StrtabContents + Sym->st_name; -} - -// -// Get Prm Handler number and name -// -STATIC -VOID -FindPrmHandler ( - UINT64 Offset - ) -{ - PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER *PrmExport; - PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT *PrmHandler; - UINT32 HandlerNum; - - PrmExport = (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER*)((UINT8*)mEhdr + Offset); - PrmHandler = (PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT *)(PrmExport + 1); - - for (HandlerNum = 0; HandlerNum < PrmExport->NumberPrmHandlers; HandlerNum++) { - strcpy(mExportSymName[mExportSymNum], PrmHandler->PrmHandlerName); - mExportSymNum ++; - PrmHandler += 1; - - // - // Check if PRM handler number is larger than (PRM_MODULE_EXPORT_SYMBOL_NUM - 1) - // - if (mExportSymNum >= (PRM_MODULE_EXPORT_SYMBOL_NUM - 1)) { - Error (NULL, 0, 3000, "Invalid", "FindPrmHandler: Number %u is too high.", mExportSymNum); - exit(EXIT_FAILURE); - } - } -} - -// -// Find the ELF section hosting the GOT from an ELF Rva -// of a single GOT entry. Normally, GOT is placed in -// ELF .text section, so assume once we find in which -// section the GOT is, all GOT entries are there, and -// just verify this. -// -STATIC -VOID -FindElfGOTSectionFromGOTEntryElfRva ( - Elf64_Addr GOTEntryElfRva - ) -{ - UINT32 i; - if (mGOTShdr != NULL) { - if (GOTEntryElfRva >= mGOTShdr->sh_addr && - GOTEntryElfRva < mGOTShdr->sh_addr + mGOTShdr->sh_size) { - return; - } - Error (NULL, 0, 3000, "Unsupported", "FindElfGOTSectionFromGOTEntryElfRva: GOT entries found in multiple sections."); - exit(EXIT_FAILURE); - } - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (GOTEntryElfRva >= shdr->sh_addr && - GOTEntryElfRva < shdr->sh_addr + shdr->sh_size) { - mGOTShdr = shdr; - mGOTShindex = i; - return; - } - } - Error (NULL, 0, 3000, "Invalid", "FindElfGOTSectionFromGOTEntryElfRva: ElfRva 0x%016LX for GOT entry not found in any section.", GOTEntryElfRva); - exit(EXIT_FAILURE); -} - -// -// Stores locations of GOT entries in COFF image. -// Returns TRUE if GOT entry is new. -// Simple implementation as number of GOT -// entries is expected to be low. -// - -STATIC -BOOLEAN -AccumulateCoffGOTEntries ( - UINT32 GOTCoffEntry - ) -{ - UINT32 i; - if (mGOTCoffEntries != NULL) { - for (i = 0; i < mGOTNumCoffEntries; i++) { - if (mGOTCoffEntries[i] == GOTCoffEntry) { - return FALSE; - } - } - } - if (mGOTCoffEntries == NULL) { - mGOTCoffEntries = (UINT32*)malloc(5 * sizeof *mGOTCoffEntries); - if (mGOTCoffEntries == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - } - assert (mGOTCoffEntries != NULL); - mGOTMaxCoffEntries = 5; - mGOTNumCoffEntries = 0; - } else if (mGOTNumCoffEntries == mGOTMaxCoffEntries) { - mGOTCoffEntries = (UINT32*)realloc(mGOTCoffEntries, 2 * mGOTMaxCoffEntries * sizeof *mGOTCoffEntries); - if (mGOTCoffEntries == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - } - assert (mGOTCoffEntries != NULL); - mGOTMaxCoffEntries += mGOTMaxCoffEntries; - } - mGOTCoffEntries[mGOTNumCoffEntries++] = GOTCoffEntry; - return TRUE; -} - -// -// 32-bit Unsigned integer comparator for qsort. -// -STATIC -int -UINT32Comparator ( - const void* lhs, - const void* rhs - ) -{ - if (*(const UINT32*)lhs < *(const UINT32*)rhs) { - return -1; - } - return *(const UINT32*)lhs > *(const UINT32*)rhs; -} - -// -// Emit accumulated Coff GOT entry relocations into -// Coff image. This function performs its job -// once and then releases the entry list, so -// it can safely be called multiple times. -// -STATIC -VOID -EmitGOTRelocations ( - VOID - ) -{ - UINT32 i; - if (mGOTCoffEntries == NULL) { - return; - } - // - // Emit Coff relocations with Rvas ordered. - // - qsort( - mGOTCoffEntries, - mGOTNumCoffEntries, - sizeof *mGOTCoffEntries, - UINT32Comparator); - for (i = 0; i < mGOTNumCoffEntries; i++) { - VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08X", mGOTCoffEntries[i]); - CoffAddFixup( - mGOTCoffEntries[i], - EFI_IMAGE_REL_BASED_DIR64); - } - free(mGOTCoffEntries); - mGOTCoffEntries = NULL; - mGOTMaxCoffEntries = 0; - mGOTNumCoffEntries = 0; -} -// -// RISC-V 64 specific Elf WriteSection function. -// -STATIC -VOID -WriteSectionRiscV64 ( - Elf_Rela *Rel, - UINT8 *Targ, - Elf_Shdr *SymShdr, - Elf_Sym *Sym - ) -{ - UINT32 Value; - UINT32 Value2; - Elf64_Addr GOTEntryRva; - - switch (ELF_R_TYPE(Rel->r_info)) { - case R_RISCV_NONE: - break; - - case R_RISCV_32: - *(UINT64 *)Targ = Sym->st_value + Rel->r_addend; - break; - - case R_RISCV_64: - *(UINT64 *)Targ = Sym->st_value + Rel->r_addend; - break; - - case R_RISCV_HI20: - mRiscVPass1Targ = Targ; - mRiscVPass1Sym = SymShdr; - mRiscVPass1SymSecIndex = Sym->st_shndx; - break; - - case R_RISCV_LO12_I: - if (mRiscVPass1Sym == SymShdr && mRiscVPass1Targ != NULL && mRiscVPass1SymSecIndex == Sym->st_shndx && mRiscVPass1SymSecIndex != 0) { - Value = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20) << 12); - Value2 = (UINT32)(RV_X(*(UINT32 *)Targ, 20, 12)); - if (Value2 & (RISCV_IMM_REACH/2)) { - Value2 |= ~(RISCV_IMM_REACH-1); - } - Value += Value2; - Value = Value - (UINT32)SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]; - Value2 = RISCV_CONST_HIGH_PART (Value); - *(UINT32 *)mRiscVPass1Targ = (RV_X (Value2, 12, 20) << 12) | \ - (RV_X (*(UINT32 *)mRiscVPass1Targ, 0, 12)); - *(UINT32 *)Targ = (RV_X (Value, 0, 12) << 20) | \ - (RV_X (*(UINT32 *)Targ, 0, 20)); - } - mRiscVPass1Sym = NULL; - mRiscVPass1Targ = NULL; - mRiscVPass1SymSecIndex = 0; - break; - - case R_RISCV_LO12_S: - if (mRiscVPass1Sym == SymShdr && mRiscVPass1Targ != NULL && mRiscVPass1SymSecIndex == Sym->st_shndx && mRiscVPass1SymSecIndex != 0) { - Value = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20) << 12); - Value2 = (UINT32)(RV_X(*(UINT32 *)Targ, 7, 5) | (RV_X(*(UINT32 *)Targ, 25, 7) << 5)); - if (Value2 & (RISCV_IMM_REACH/2)) { - Value2 |= ~(RISCV_IMM_REACH-1); - } - Value += Value2; - Value = Value - (UINT32)SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]; - Value2 = RISCV_CONST_HIGH_PART (Value); - *(UINT32 *)mRiscVPass1Targ = (RV_X (Value2, 12, 20) << 12) | \ - (RV_X (*(UINT32 *)mRiscVPass1Targ, 0, 12)); - Value2 = *(UINT32 *)Targ & 0x01fff07f; - Value &= RISCV_IMM_REACH - 1; - *(UINT32 *)Targ = Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (RV_X(Value, 5, 7) << 25))); - } - mRiscVPass1Sym = NULL; - mRiscVPass1Targ = NULL; - mRiscVPass1SymSecIndex = 0; - break; - - case R_RISCV_GOT_HI20: - GOTEntryRva = (Sym->st_value - Rel->r_offset); - mRiscVPass1Offset = RV_X(GOTEntryRva, 0, 12); - Value = (UINT32)RV_X(GOTEntryRva, 12, 20); - *(UINT32 *)Targ = (Value << 12) | (RV_X(*(UINT32*)Targ, 0, 12)); - - mRiscVPass1Targ = Targ; - mRiscVPass1Sym = SymShdr; - mRiscVPass1SymSecIndex = Sym->st_shndx; - mRiscVPass1GotFixup = 1; - break; - - case R_RISCV_PCREL_HI20: - mRiscVPass1Targ = Targ; - mRiscVPass1Sym = SymShdr; - mRiscVPass1SymSecIndex = Sym->st_shndx; - - Value = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20)); - break; - - case R_RISCV_PCREL_LO12_S: - if (mRiscVPass1Targ != NULL && mRiscVPass1Sym != NULL && mRiscVPass1SymSecIndex != 0) { - int i; - Value2 = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20)); - - Value = ((UINT32)(RV_X(*(UINT32 *)Targ, 25, 7)) << 5); - Value = (Value | (UINT32)(RV_X(*(UINT32 *)Targ, 7, 5))); - - if(Value & (RISCV_IMM_REACH/2)) { - Value |= ~(RISCV_IMM_REACH-1); - } - Value = Value - (UINT32)mRiscVPass1Sym->sh_addr + mCoffSectionsOffset[mRiscVPass1SymSecIndex]; - - if(-2048 > (INT32)Value) { - i = (((INT32)Value * -1) / 4096); - Value2 -= i; - Value += 4096 * i; - if(-2048 > (INT32)Value) { - Value2 -= 1; - Value += 4096; - } - } - else if( 2047 < (INT32)Value) { - i = (Value / 4096); - Value2 += i; - Value -= 4096 * i; - if(2047 < (INT32)Value) { - Value2 += 1; - Value -= 4096; - } - } - - // Update the IMM of SD instruction - // - // |31 25|24 20|19 15|14 12 |11 7|6 0| - // |-------------------------------------------|-------| - // |imm[11:5] | rs2 | rs1 | funct3 |imm[4:0] | opcode| - // --------------------------------------------------- - - // First Zero out current IMM - *(UINT32 *)Targ &= ~0xfe000f80; - - // Update with new IMM - *(UINT32 *)Targ |= (RV_X(Value, 5, 7) << 25); - *(UINT32 *)Targ |= (RV_X(Value, 0, 5) << 7); - - // Update previous instruction - *(UINT32 *)mRiscVPass1Targ = (RV_X(Value2, 0, 20)<<12) | (RV_X(*(UINT32 *)mRiscVPass1Targ, 0, 12)); - } - mRiscVPass1Sym = NULL; - mRiscVPass1Targ = NULL; - mRiscVPass1SymSecIndex = 0; - break; - - case R_RISCV_PCREL_LO12_I: - if (mRiscVPass1Targ != NULL && mRiscVPass1Sym != NULL && mRiscVPass1SymSecIndex != 0) { - int i; - Value2 = (UINT32)(RV_X(*(UINT32 *)mRiscVPass1Targ, 12, 20)); - - if(mRiscVPass1GotFixup) { - Value = (UINT32)(mRiscVPass1Offset); - } else { - Value = (UINT32)(RV_X(*(UINT32 *)Targ, 20, 12)); - if(Value & (RISCV_IMM_REACH/2)) { - Value |= ~(RISCV_IMM_REACH-1); - } - } - Value = Value - (UINT32)mRiscVPass1Sym->sh_addr + mCoffSectionsOffset[mRiscVPass1SymSecIndex]; - - if(-2048 > (INT32)Value) { - i = (((INT32)Value * -1) / 4096); - Value2 -= i; - Value += 4096 * i; - if(-2048 > (INT32)Value) { - Value2 -= 1; - Value += 4096; - } - } - else if( 2047 < (INT32)Value) { - i = (Value / 4096); - Value2 += i; - Value -= 4096 * i; - if(2047 < (INT32)Value) { - Value2 += 1; - Value -= 4096; - } - } - - if(mRiscVPass1GotFixup) { - *(UINT32 *)Targ = (RV_X((UINT32)Value, 0, 12) << 20) - | (RV_X(*(UINT32*)Targ, 0, 20)); - // Convert LD instruction to ADDI - // - // |31 20|19 15|14 12|11 7|6 0| - // |-----------------------------------------| - // |imm[11:0] | rs1 | 011 | rd | 0000011 | LD - // ----------------------------------------- - - // |-----------------------------------------| - // |imm[11:0] | rs1 | 000 | rd | 0010011 | ADDI - // ----------------------------------------- - - // To convert, let's first reset bits 12-14 and 0-6 using ~0x707f - // Then modify the opcode to ADDI (0010011) - // All other fields will remain same. - - *(UINT32 *)Targ = ((*(UINT32 *)Targ & ~0x707f) | 0x13); - } else { - *(UINT32 *)Targ = (RV_X(Value, 0, 12) << 20) | (RV_X(*(UINT32*)Targ, 0, 20)); - } - *(UINT32 *)mRiscVPass1Targ = (RV_X(Value2, 0, 20)<<12) | (RV_X(*(UINT32 *)mRiscVPass1Targ, 0, 12)); - } - mRiscVPass1Sym = NULL; - mRiscVPass1Targ = NULL; - mRiscVPass1SymSecIndex = 0; - mRiscVPass1Offset = 0; - mRiscVPass1GotFixup = 0; - break; - - case R_RISCV_ADD64: - case R_RISCV_SUB64: - case R_RISCV_ADD32: - case R_RISCV_SUB32: - case R_RISCV_BRANCH: - case R_RISCV_JAL: - case R_RISCV_GPREL_I: - case R_RISCV_GPREL_S: - case R_RISCV_CALL: - case R_RISCV_CALL_PLT: - case R_RISCV_RVC_BRANCH: - case R_RISCV_RVC_JUMP: - case R_RISCV_RELAX: - case R_RISCV_SUB6: - case R_RISCV_SET6: - case R_RISCV_SET8: - case R_RISCV_SET16: - case R_RISCV_SET32: - break; - - default: - Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } -} - -STATIC UINT16 mDllCharacteristicsEx; - -STATIC -VOID -ParseNoteSection ( - CONST Elf_Shdr *Shdr - ) -{ - CONST Elf_Note *Note; - CONST UINT32 *Prop; - UINT32 Prop0; - UINT32 Prop2; - - Note = (Elf_Note *)((UINT8 *)mEhdr + Shdr->sh_offset); - - if ((Note->n_type == NT_GNU_PROPERTY_TYPE_0) && - (Note->n_namesz == sizeof ("GNU")) && - (strcmp ((CHAR8 *)(Note + 1), "GNU") == 0) && - (Note->n_descsz > sizeof (UINT32[2]))) { - Prop = (UINT32 *)((UINT8 *)(Note + 1) + sizeof("GNU")); - - switch (mEhdr->e_machine) { - case EM_AARCH64: - Prop0 = GNU_PROPERTY_AARCH64_FEATURE_1_AND; - Prop2 = GNU_PROPERTY_AARCH64_FEATURE_1_BTI; - break; - - case EM_X86_64: - Prop0 = GNU_PROPERTY_X86_FEATURE_1_AND; - Prop2 = GNU_PROPERTY_X86_FEATURE_1_IBT; - break; - - default: - return; - } - if ((Prop[0] == Prop0) && - (Prop[1] >= sizeof (UINT32)) && - ((Prop[2] & Prop2) != 0)) { - mDllCharacteristicsEx |= EFI_IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT; - } - } -} - -// -// Elf functions interface implementation -// - -STATIC -VOID -ScanSections64 ( - VOID - ) -{ - UINT32 i; - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - UINT32 CoffEntry; - UINT32 SectionCount; - BOOLEAN FoundSection; - UINT32 Offset; - - CoffEntry = 0; - mCoffOffset = 0; - - // - // Coff file start with a DOS header. - // - mCoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40; - mNtHdrOffset = mCoffOffset; - switch (mEhdr->e_machine) { - case EM_X86_64: - case EM_AARCH64: - case EM_RISCV64: - case EM_LOONGARCH: - mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64); - break; - default: - VerboseMsg ("%s unknown e_machine type %hu. Assume X64", mInImageName, mEhdr->e_machine); - mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64); - break; - } - - mTableOffset = mCoffOffset; - mCoffOffset += mCoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER); - - // - // Set mCoffAlignment to the maximum alignment of the input sections - // we care about - // - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (shdr->sh_addralign <= mCoffAlignment) { - continue; - } - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) { - mCoffAlignment = (UINT32)shdr->sh_addralign; - } - } - - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (shdr->sh_type == SHT_NOTE) { - ParseNoteSection (shdr); - } - } - - // - // Check if mCoffAlignment is larger than MAX_COFF_ALIGNMENT - // - if (mCoffAlignment > MAX_COFF_ALIGNMENT) { - Error (NULL, 0, 3000, "Invalid", "Section alignment is larger than MAX_COFF_ALIGNMENT."); - assert (FALSE); - } - - - // - // Move the PE/COFF header right before the first section. This will help us - // save space when converting to TE. - // - if (mCoffAlignment > mCoffOffset) { - mNtHdrOffset += mCoffAlignment - mCoffOffset; - mTableOffset += mCoffAlignment - mCoffOffset; - mCoffOffset = mCoffAlignment; - } - - // - // First text sections. - // - mCoffOffset = CoffAlign(mCoffOffset); - mTextOffset = mCoffOffset; - FoundSection = FALSE; - SectionCount = 0; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsTextShdr(shdr)) { - if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { - // the alignment field is valid - if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { - // if the section address is aligned we must align PE/COFF - mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1)); - } else { - Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment."); - } - } - - /* Relocate entry. */ - if ((mEhdr->e_entry >= shdr->sh_addr) && - (mEhdr->e_entry < shdr->sh_addr + shdr->sh_size)) { - CoffEntry = (UINT32) (mCoffOffset + mEhdr->e_entry - shdr->sh_addr); - } - - // - // Set mTextOffset with the offset of the first '.text' section - // - if (!FoundSection) { - mTextOffset = mCoffOffset; - FoundSection = TRUE; - } - - mCoffSectionsOffset[i] = mCoffOffset; - mCoffOffset += (UINT32) shdr->sh_size; - SectionCount ++; - } - } - - if (!FoundSection && mOutImageType != FW_ACPI_IMAGE) { - Error (NULL, 0, 3000, "Invalid", "Did not find any '.text' section."); - assert (FALSE); - } - - mDebugOffset = DebugRvaAlign(mCoffOffset); - mCoffOffset = CoffAlign(mCoffOffset); - - if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) { - Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged into 1 text section. Source level debug might not work correctly.", mInImageName); - } - - // - // Then data sections. - // - mDataOffset = mCoffOffset; - FoundSection = FALSE; - SectionCount = 0; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsDataShdr(shdr)) { - if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { - // the alignment field is valid - if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { - // if the section address is aligned we must align PE/COFF - mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1)); - } else { - Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment."); - } - } - - // - // Set mDataOffset with the offset of the first '.data' section - // - if (!FoundSection) { - mDataOffset = mCoffOffset; - FoundSection = TRUE; - } - mCoffSectionsOffset[i] = mCoffOffset; - mCoffOffset += (UINT32) shdr->sh_size; - SectionCount ++; - } - } - - // - // Make room for .debug data in .data (or .text if .data is empty) instead of - // putting it in a section of its own. This is explicitly allowed by the - // PE/COFF spec, and prevents bloat in the binary when using large values for - // section alignment. - // - if (SectionCount > 0) { - mDebugOffset = DebugRvaAlign(mCoffOffset); - } - mCoffOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) + - sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + - strlen(mInImageName) + 1; - - // - // Add more space in the .debug data region for the DllCharacteristicsEx - // field. - // - if (mDllCharacteristicsEx != 0) { - mCoffOffset = DebugRvaAlign(mCoffOffset) + - sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) + - sizeof (EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY); - } - - mCoffOffset = CoffAlign(mCoffOffset); - if (SectionCount == 0) { - mDataOffset = mCoffOffset; - } - - if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) { - Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName); - } - - // - // The Symbol sections. - // - if (mExportFlag) { - UINT32 SymIndex; - Elf_Sym *Sym; - UINT64 SymNum; - const UINT8 *SymName; - - mExportOffset = mCoffOffset; - mExportSize = sizeof(EFI_IMAGE_EXPORT_DIRECTORY) + strlen(mInImageName) + 1; - - for (i = 0; i < mEhdr->e_shnum; i++) { - - // - // Determine if this is a symbol section. - // - Elf_Shdr *shdr = GetShdrByIndex(i); - if (!IsSymbolShdr(shdr)) { - continue; - } - - UINT8 *Symtab = (UINT8*)mEhdr + shdr->sh_offset; - SymNum = (shdr->sh_size) / (shdr->sh_entsize); - - // - // First Get PrmModuleExportDescriptor - // - for (SymIndex = 0; SymIndex < SymNum; SymIndex++) { - Sym = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize); - SymName = GetSymName(Sym); - if (SymName == NULL) { - continue; - } - - if (strcmp((CHAR8*)SymName, PRM_MODULE_EXPORT_DESCRIPTOR_NAME) == 0) { - // - // Find PrmHandler Number and Name - // - FindPrmHandler(Sym->st_value); - - strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName); - mExportRVA[mExportSymNum] = (UINT32)(Sym->st_value); - mExportSize += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + strlen((CHAR8 *)SymName) + 1; - mExportSymNum ++; - break; - } - } - - // - // Second Get PrmHandler - // - for (SymIndex = 0; SymIndex < SymNum; SymIndex++) { - UINT32 ExpIndex; - Sym = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize); - SymName = GetSymName(Sym); - if (SymName == NULL) { - continue; - } - - for (ExpIndex = 0; ExpIndex < (mExportSymNum -1); ExpIndex++) { - if (strcmp((CHAR8*)SymName, mExportSymName[ExpIndex]) != 0) { - continue; - } - mExportRVA[ExpIndex] = (UINT32)(Sym->st_value); - mExportSize += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + strlen((CHAR8 *)SymName) + 1; - } - } - - break; - } - - mCoffOffset += mExportSize; - mCoffOffset = CoffAlign(mCoffOffset); - } - - // - // The HII resource sections. - // - mHiiRsrcOffset = mCoffOffset; - for (i = 0; i < mEhdr->e_shnum; i++) { - Elf_Shdr *shdr = GetShdrByIndex(i); - if (IsHiiRsrcShdr(shdr)) { - if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) { - // the alignment field is valid - if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) { - // if the section address is aligned we must align PE/COFF - mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1)); - } else { - Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment."); - } - } - if (shdr->sh_size != 0) { - mHiiRsrcOffset = mCoffOffset; - mCoffSectionsOffset[i] = mCoffOffset; - mCoffOffset += (UINT32) shdr->sh_size; - mCoffOffset = CoffAlign(mCoffOffset); - SetHiiResourceHeader ((UINT8*) mEhdr + shdr->sh_offset, mHiiRsrcOffset); - } - break; - } - } - - mRelocOffset = mCoffOffset; - - // - // Allocate base Coff file. Will be expanded later for relocations. - // - mCoffFile = (UINT8 *)malloc(mCoffOffset); - if (mCoffFile == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - } - assert (mCoffFile != NULL); - memset(mCoffFile, 0, mCoffOffset); - - // - // Fill headers. - // - DosHdr = (EFI_IMAGE_DOS_HEADER *)mCoffFile; - DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE; - DosHdr->e_lfanew = mNtHdrOffset; - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(mCoffFile + mNtHdrOffset); - - NtHdr->Pe32Plus.Signature = EFI_IMAGE_NT_SIGNATURE; - - switch (mEhdr->e_machine) { - case EM_X86_64: - NtHdr->Pe32Plus.FileHeader.Machine = IMAGE_FILE_MACHINE_X64; - NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - break; - case EM_AARCH64: - NtHdr->Pe32Plus.FileHeader.Machine = IMAGE_FILE_MACHINE_ARM64; - NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - break; - case EM_RISCV64: - NtHdr->Pe32Plus.FileHeader.Machine = IMAGE_FILE_MACHINE_RISCV64; - NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - break; - case EM_LOONGARCH: - NtHdr->Pe32Plus.FileHeader.Machine = IMAGE_FILE_MACHINE_LOONGARCH64; - NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - break; - - default: - VerboseMsg ("%u unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine); - NtHdr->Pe32Plus.FileHeader.Machine = IMAGE_FILE_MACHINE_X64; - NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - } - - NtHdr->Pe32Plus.FileHeader.NumberOfSections = mCoffNbrSections; - NtHdr->Pe32Plus.FileHeader.TimeDateStamp = (UINT32) time(NULL); - mImageTimeStamp = NtHdr->Pe32Plus.FileHeader.TimeDateStamp; - NtHdr->Pe32Plus.FileHeader.PointerToSymbolTable = 0; - NtHdr->Pe32Plus.FileHeader.NumberOfSymbols = 0; - NtHdr->Pe32Plus.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32Plus.OptionalHeader); - NtHdr->Pe32Plus.FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE - | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED - | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED - | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; - - NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset; - NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset; - NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0; - NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry; - - NtHdr->Pe32Plus.OptionalHeader.BaseOfCode = mTextOffset; - - NtHdr->Pe32Plus.OptionalHeader.ImageBase = 0; - NtHdr->Pe32Plus.OptionalHeader.SectionAlignment = mCoffAlignment; - NtHdr->Pe32Plus.OptionalHeader.FileAlignment = mCoffAlignment; - NtHdr->Pe32Plus.OptionalHeader.SizeOfImage = 0; - - NtHdr->Pe32Plus.OptionalHeader.SizeOfHeaders = mTextOffset; - NtHdr->Pe32Plus.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES; - - // - // Section headers. - // - if ((mDataOffset - mTextOffset) > 0) { - CreateSectionHeader (".text", mTextOffset, mDataOffset - mTextOffset, - EFI_IMAGE_SCN_CNT_CODE - | EFI_IMAGE_SCN_MEM_EXECUTE - | EFI_IMAGE_SCN_MEM_READ); - } else { - // Don't make a section of size 0. - NtHdr->Pe32Plus.FileHeader.NumberOfSections--; - } - - // - // If found symbol, add edata section between data and rsrc section - // - if(mExportFlag) { - Offset = mExportOffset; - } else { - Offset = mHiiRsrcOffset; - } - - if ((mHiiRsrcOffset - mDataOffset) > 0) { - CreateSectionHeader (".data", mDataOffset, Offset - mDataOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_WRITE - | EFI_IMAGE_SCN_MEM_READ); - } else { - // Don't make a section of size 0. - NtHdr->Pe32Plus.FileHeader.NumberOfSections--; - } - - if(mExportFlag) { - if ((mHiiRsrcOffset - mExportOffset) > 0) { - CreateSectionHeader (".edata", mExportOffset, mHiiRsrcOffset - mExportOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_READ); - NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size = mHiiRsrcOffset - mExportOffset; - NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = mExportOffset; - - } else { - // Don't make a section of size 0. - NtHdr->Pe32Plus.FileHeader.NumberOfSections--; - } - } - - if ((mRelocOffset - mHiiRsrcOffset) > 0) { - CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_READ); - - NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = mRelocOffset - mHiiRsrcOffset; - NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = mHiiRsrcOffset; - } else { - // Don't make a section of size 0. - NtHdr->Pe32Plus.FileHeader.NumberOfSections--; - } - -} - -STATIC -BOOLEAN -WriteSections64 ( - SECTION_FILTER_TYPES FilterType - ) -{ - UINT32 Idx; - Elf_Shdr *SecShdr; - UINT32 SecOffset; - BOOLEAN (*Filter)(Elf_Shdr *); - Elf64_Addr GOTEntryRva; - - // - // Initialize filter pointer - // - switch (FilterType) { - case SECTION_TEXT: - Filter = IsTextShdr; - break; - case SECTION_HII: - Filter = IsHiiRsrcShdr; - break; - case SECTION_DATA: - Filter = IsDataShdr; - break; - default: - return FALSE; - } - - // - // First: copy sections. - // - for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) { - Elf_Shdr *Shdr = GetShdrByIndex(Idx); - if ((*Filter)(Shdr)) { - switch (Shdr->sh_type) { - case SHT_PROGBITS: - /* Copy. */ - if (Shdr->sh_offset + Shdr->sh_size > mFileBufferSize) { - return FALSE; - } - memcpy(mCoffFile + mCoffSectionsOffset[Idx], - (UINT8*)mEhdr + Shdr->sh_offset, - (size_t) Shdr->sh_size); - break; - - case SHT_NOBITS: - memset(mCoffFile + mCoffSectionsOffset[Idx], 0, (size_t) Shdr->sh_size); - break; - - default: - // - // Ignore for unknown section type. - // - VerboseMsg ("%s unknown section type %x. We ignore this unknown section type.", mInImageName, (unsigned)Shdr->sh_type); - break; - } - } - } - - // - // Second: apply relocations. - // - VerboseMsg ("Applying Relocations..."); - for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) { - // - // Determine if this is a relocation section. - // - Elf_Shdr *RelShdr = GetShdrByIndex(Idx); - if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) { - continue; - } - - // - // If this is a ET_DYN (PIE) executable, we will encounter a dynamic SHT_RELA - // section that applies to the entire binary, and which will have its section - // index set to #0 (which is a NULL section with the SHF_ALLOC bit cleared). - // - // In the absence of GOT based relocations, - // this RELA section will contain redundant R_xxx_RELATIVE relocations, one - // for every R_xxx_xx64 relocation appearing in the per-section RELA sections. - // (i.e., .rela.text and .rela.data) - // - if (RelShdr->sh_info == 0) { - continue; - } - - // - // Relocation section found. Now extract section information that the relocations - // apply to in the ELF data and the new COFF data. - // - SecShdr = GetShdrByIndex(RelShdr->sh_info); - SecOffset = mCoffSectionsOffset[RelShdr->sh_info]; - - // - // Only process relocations for the current filter type. - // - if (RelShdr->sh_type == SHT_RELA && (*Filter)(SecShdr)) { - UINT64 RelIdx; - - // - // Determine the symbol table referenced by the relocation data. - // - Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link); - UINT8 *Symtab = (UINT8*)mEhdr + SymtabShdr->sh_offset; - - // - // Process all relocation entries for this section. - // - for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += (UINT32) RelShdr->sh_entsize) { - - // - // Set pointer to relocation entry - // - Elf_Rela *Rel = (Elf_Rela *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx); - - // - // Set pointer to symbol table entry associated with the relocation entry. - // - Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize); - - Elf_Shdr *SymShdr; - UINT8 *Targ; - - // - // The _GLOBAL_OFFSET_TABLE_ symbol is not actually an absolute symbol, - // but carries the SHN_ABS section index for historical reasons. - // It must be accompanied by a R_*_GOT_* type relocation on a - // subsequent instruction, which we handle below, specifically to avoid - // the GOT indirection, and to refer to the symbol directly. This means - // we can simply disregard direct references to the GOT symbol itself, - // as the resulting value will never be used. - // - if (Sym->st_shndx == SHN_ABS) { - const UINT8 *SymName = GetSymName (Sym); - if (strcmp ((CHAR8 *)SymName, "_GLOBAL_OFFSET_TABLE_") == 0) { - continue; - } - } - - // - // Check section header index found in symbol table and get the section - // header location. - // - if (Sym->st_shndx == SHN_UNDEF - || Sym->st_shndx >= mEhdr->e_shnum) { - const UINT8 *SymName = GetSymName(Sym); - if (SymName == NULL) { - SymName = (const UINT8 *)""; - } - - // - // Skip error on EM_RISCV64 and EM_LOONGARCH because no symbol name is built - // from RISC-V and LoongArch toolchain. - // - if ((mEhdr->e_machine != EM_RISCV64) && (mEhdr->e_machine != EM_LOONGARCH)) { - Error (NULL, 0, 3000, "Invalid", - "%s: Bad definition for symbol '%s'@%#llx or unsupported symbol type. " - "For example, absolute and undefined symbols are not supported.", - mInImageName, SymName, Sym->st_value); - - exit(EXIT_FAILURE); - } - continue; - } - SymShdr = GetShdrByIndex(Sym->st_shndx); - - // - // Convert the relocation data to a pointer into the coff file. - // - // Note: - // r_offset is the virtual address of the storage unit to be relocated. - // sh_addr is the virtual address for the base of the section. - // - // r_offset in a memory address. - // Convert it to a pointer in the coff file. - // - Targ = mCoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr); - - // - // Determine how to handle each relocation type based on the machine type. - // - if (mEhdr->e_machine == EM_X86_64) { - switch (ELF_R_TYPE(Rel->r_info)) { - case R_X86_64_NONE: - break; - case R_X86_64_64: - // - // Absolute relocation. - // - VerboseMsg ("R_X86_64_64"); - VerboseMsg ("Offset: 0x%08X, Addend: 0x%016LX", - (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), - *(UINT64 *)Targ); - *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]; - VerboseMsg ("Relocation: 0x%016LX", *(UINT64*)Targ); - break; - case R_X86_64_32: - VerboseMsg ("R_X86_64_32"); - VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", - (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), - *(UINT32 *)Targ); - *(UINT32 *)Targ = (UINT32)((UINT64)(*(UINT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]); - VerboseMsg ("Relocation: 0x%08X", *(UINT32*)Targ); - break; - case R_X86_64_32S: - VerboseMsg ("R_X86_64_32S"); - VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", - (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), - *(UINT32 *)Targ); - *(INT32 *)Targ = (INT32)((INT64)(*(INT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]); - VerboseMsg ("Relocation: 0x%08X", *(UINT32*)Targ); - break; - - case R_X86_64_PLT32: - // - // Treat R_X86_64_PLT32 relocations as R_X86_64_PC32: this is - // possible since we know all code symbol references resolve to - // definitions in the same module (UEFI has no shared libraries), - // and so there is never a reason to jump via a PLT entry, - // allowing us to resolve the reference using the symbol directly. - // - VerboseMsg ("Treating R_X86_64_PLT32 as R_X86_64_PC32 ..."); - /* fall through */ - case R_X86_64_PC32: - // - // Relative relocation: Symbol - Ip + Addend - // - VerboseMsg ("R_X86_64_PC32"); - VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", - (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), - *(UINT32 *)Targ); - *(UINT32 *)Targ = (UINT32) (*(UINT32 *)Targ - + (mCoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr) - - (SecOffset - SecShdr->sh_addr)); - VerboseMsg ("Relocation: 0x%08X", *(UINT32 *)Targ); - break; - case R_X86_64_REX_GOTPCRELX: - // - // This is a relaxable GOTPCREL relocation, and the linker may have - // applied this relaxation without updating the relocation type. - // In the position independent code model, only transformations - // from MOV to LEA are possible for REX-prefixed instructions. - // - if (Targ[-2] == 0x8d) { // LEA - break; - } - case R_X86_64_GOTPCREL: - case R_X86_64_GOTPCRELX: - VerboseMsg ("R_X86_64_GOTPCREL family"); - VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", - (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), - *(UINT32 *)Targ); - GOTEntryRva = Rel->r_offset - Rel->r_addend + *(INT32 *)Targ; - FindElfGOTSectionFromGOTEntryElfRva(GOTEntryRva); - *(UINT32 *)Targ = (UINT32) (*(UINT32 *)Targ - + (mCoffSectionsOffset[mGOTShindex] - mGOTShdr->sh_addr) - - (SecOffset - SecShdr->sh_addr)); - VerboseMsg ("Relocation: 0x%08X", *(UINT32 *)Targ); - GOTEntryRva += (mCoffSectionsOffset[mGOTShindex] - mGOTShdr->sh_addr); // ELF Rva -> COFF Rva - if (AccumulateCoffGOTEntries((UINT32)GOTEntryRva)) { - // - // Relocate GOT entry if it's the first time we run into it - // - Targ = mCoffFile + GOTEntryRva; - // - // Limitation: The following three statements assume memory - // at *Targ is valid because the section containing the GOT - // has already been copied from the ELF image to the Coff image. - // This pre-condition presently holds because the GOT is placed - // in section .text, and the ELF text sections are all copied - // prior to reaching this point. - // If the pre-condition is violated in the future, this fixup - // either needs to be deferred after the GOT section is copied - // to the Coff image, or the fixup should be performed on the - // source Elf image instead of the destination Coff image. - // - VerboseMsg ("Offset: 0x%08X, Addend: 0x%016LX", - (UINT32)GOTEntryRva, - *(UINT64 *)Targ); - *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]; - VerboseMsg ("Relocation: 0x%016LX", *(UINT64*)Targ); - } - break; - default: - Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_X86_64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } - } else if (mEhdr->e_machine == EM_AARCH64) { - - switch (ELF_R_TYPE(Rel->r_info)) { - INT64 Offset; - - case R_AARCH64_LD64_GOTOFF_LO15: - case R_AARCH64_LD64_GOTPAGE_LO15: - // - // Convert into an ADR instruction that refers to the symbol directly. - // - Offset = Sym->st_value - Rel->r_offset; - - *(UINT32 *)Targ &= 0x1000001f; - *(UINT32 *)Targ |= ((Offset & 0x1ffffc) << (5 - 2)) | ((Offset & 0x3) << 29); - - if (Offset < -0x100000 || Offset > 0xfffff) { - Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s failed to relax GOT based symbol reference - image is too big (>1 MiB).", - mInImageName); - break; - } - break; - - case R_AARCH64_LD64_GOT_LO12_NC: - // - // Convert into an ADD instruction - see R_AARCH64_ADR_GOT_PAGE below. - // - *(UINT32 *)Targ &= 0x3ff; - *(UINT32 *)Targ |= 0x91000000 | ((Sym->st_value & 0xfff) << 10); - break; - - case R_AARCH64_ADR_GOT_PAGE: - // - // This relocation points to the GOT entry that contains the absolute - // address of the symbol we are referring to. Since EDK2 only uses - // fully linked binaries, we can avoid the indirection, and simply - // refer to the symbol directly. This implies having to patch the - // subsequent LDR instruction (covered by a R_AARCH64_LD64_GOT_LO12_NC - // relocation) into an ADD instruction - this is handled above. - // - // In order to handle Cortex-A53 erratum #843419, the GCC toolchain - // may convert an ADRP instruction at the end of a page (0xffc - // offset) into an ADR instruction. If so, be sure to calculate the - // offset for an ADR instead of ADRP. - // - if ((*(UINT32 *)Targ & BIT31) == 0) { - // - // Calculate the offset for an ADR. - // - Offset = (Sym->st_value & ~0xfff) - Rel->r_offset; - if (Offset < -0x100000 || Offset > 0xfffff) { - Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s due to its size (> 1 MB), unable to relocate ADR.", - mInImageName); - break; - } - } else { - // - // Calculate the offset for an ADRP. - // - Offset = (Sym->st_value - (Rel->r_offset & ~0xfff)) >> 12; - } - - *(UINT32 *)Targ &= 0x9000001f; - *(UINT32 *)Targ |= ((Offset & 0x1ffffc) << (5 - 2)) | ((Offset & 0x3) << 29); - - /* fall through */ - - case R_AARCH64_ADR_PREL_PG_HI21: - // - // In order to handle Cortex-A53 erratum #843419, the LD linker may - // convert ADRP instructions into ADR instructions, but without - // updating the static relocation type, and so we may end up here - // while the instruction in question is actually ADR. So let's - // just disregard it: the section offset check we apply below to - // ADR instructions will trigger for its R_AARCH64_xxx_ABS_LO12_NC - // companion instruction as well, so it is safe to omit it here. - // - if ((*(UINT32 *)Targ & BIT31) == 0) { - break; - } - - // - // AArch64 PG_H21 relocations are typically paired with ABS_LO12 - // relocations, where a PC-relative reference with +/- 4 GB range is - // split into a relative high part and an absolute low part. Since - // the absolute low part represents the offset into a 4 KB page, we - // either have to convert the ADRP into an ADR instruction, or we - // need to use a section alignment of at least 4 KB, so that the - // binary appears at a correct offset at runtime. In any case, we - // have to make sure that the 4 KB relative offsets of both the - // section containing the reference as well as the section to which - // it refers have not been changed during PE/COFF conversion (i.e., - // in ScanSections64() above). - // - if (mCoffAlignment < 0x1000) { - // - // Attempt to convert the ADRP into an ADR instruction. - // This is only possible if the symbol is within +/- 1 MB. - // - - // Decode the ADRP instruction - Offset = (INT32)((*(UINT32 *)Targ & 0xffffe0) << 8); - Offset = (Offset << (6 - 5)) | ((*(UINT32 *)Targ & 0x60000000) >> (29 - 12)); - - // - // ADRP offset is relative to the previous page boundary, - // whereas ADR offset is relative to the instruction itself. - // So fix up the offset so it points to the page containing - // the symbol. - // - Offset -= (UINTN)(Targ - mCoffFile) & 0xfff; - - if (Offset < -0x100000 || Offset > 0xfffff) { - Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s due to its size (> 1 MB), this module requires 4 KB section alignment.", - mInImageName); - break; - } - - // Re-encode the offset as an ADR instruction - *(UINT32 *)Targ &= 0x1000001f; - *(UINT32 *)Targ |= ((Offset & 0x1ffffc) << (5 - 2)) | ((Offset & 0x3) << 29); - } - /* fall through */ - - case R_AARCH64_ADD_ABS_LO12_NC: - case R_AARCH64_LDST8_ABS_LO12_NC: - case R_AARCH64_LDST16_ABS_LO12_NC: - case R_AARCH64_LDST32_ABS_LO12_NC: - case R_AARCH64_LDST64_ABS_LO12_NC: - case R_AARCH64_LDST128_ABS_LO12_NC: - if (((SecShdr->sh_addr ^ SecOffset) & 0xfff) != 0 || - ((SymShdr->sh_addr ^ mCoffSectionsOffset[Sym->st_shndx]) & 0xfff) != 0) { - Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s AARCH64 small code model requires identical ELF and PE/COFF section offsets modulo 4 KB.", - mInImageName); - break; - } - /* fall through */ - - case R_AARCH64_ADR_PREL_LO21: - case R_AARCH64_CONDBR19: - case R_AARCH64_LD_PREL_LO19: - case R_AARCH64_CALL26: - case R_AARCH64_JUMP26: - case R_AARCH64_PREL64: - case R_AARCH64_PREL32: - case R_AARCH64_PREL16: - // - // The GCC toolchains (i.e., binutils) may corrupt section relative - // relocations when emitting relocation sections into fully linked - // binaries. More specifically, they tend to fail to take into - // account the fact that a '.rodata + XXX' relocation needs to have - // its addend recalculated once .rodata is merged into the .text - // section, and the relocation emitted into the .rela.text section. - // - // We cannot really recover from this loss of information, so the - // only workaround is to prevent having to recalculate any relative - // relocations at all, by using a linker script that ensures that - // the offset between the Place and the Symbol is the same in both - // the ELF and the PE/COFF versions of the binary. - // - if ((SymShdr->sh_addr - SecShdr->sh_addr) != - (mCoffSectionsOffset[Sym->st_shndx] - SecOffset)) { - Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s AARCH64 relative relocations require identical ELF and PE/COFF section offsets", - mInImageName); - } - break; - - // Absolute relocations. - case R_AARCH64_ABS64: - *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]; - break; - - default: - Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } - } else if (mEhdr->e_machine == EM_RISCV64) { - // - // Write section for RISC-V 64 architecture. - // - WriteSectionRiscV64 (Rel, Targ, SymShdr, Sym); - } else if (mEhdr->e_machine == EM_LOONGARCH) { - switch (ELF_R_TYPE(Rel->r_info)) { - INT64 Offset; - INT32 Lo, Hi; - - case R_LARCH_SOP_PUSH_ABSOLUTE: - // - // Absolute relocation. - // - *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]; - break; - - case R_LARCH_MARK_LA: - case R_LARCH_64: - case R_LARCH_NONE: - case R_LARCH_32: - case R_LARCH_RELATIVE: - case R_LARCH_COPY: - case R_LARCH_JUMP_SLOT: - case R_LARCH_TLS_DTPMOD32: - case R_LARCH_TLS_DTPMOD64: - case R_LARCH_TLS_DTPREL32: - case R_LARCH_TLS_DTPREL64: - case R_LARCH_TLS_TPREL32: - case R_LARCH_TLS_TPREL64: - case R_LARCH_IRELATIVE: - case R_LARCH_MARK_PCREL: - case R_LARCH_SOP_PUSH_PCREL: - case R_LARCH_SOP_PUSH_DUP: - case R_LARCH_SOP_PUSH_GPREL: - case R_LARCH_SOP_PUSH_TLS_TPREL: - case R_LARCH_SOP_PUSH_TLS_GOT: - case R_LARCH_SOP_PUSH_TLS_GD: - case R_LARCH_SOP_PUSH_PLT_PCREL: - case R_LARCH_SOP_ASSERT: - case R_LARCH_SOP_NOT: - case R_LARCH_SOP_SUB: - case R_LARCH_SOP_SL: - case R_LARCH_SOP_SR: - case R_LARCH_SOP_ADD: - case R_LARCH_SOP_AND: - case R_LARCH_SOP_IF_ELSE: - case R_LARCH_SOP_POP_32_S_10_5: - case R_LARCH_SOP_POP_32_U_10_12: - case R_LARCH_SOP_POP_32_S_10_12: - case R_LARCH_SOP_POP_32_S_10_16: - case R_LARCH_SOP_POP_32_S_10_16_S2: - case R_LARCH_SOP_POP_32_S_5_20: - case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: - case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: - case R_LARCH_SOP_POP_32_U: - case R_LARCH_ADD8: - case R_LARCH_ADD16: - case R_LARCH_ADD24: - case R_LARCH_ADD32: - case R_LARCH_ADD64: - case R_LARCH_SUB8: - case R_LARCH_SUB16: - case R_LARCH_SUB24: - case R_LARCH_SUB32: - case R_LARCH_SUB64: - case R_LARCH_GNU_VTINHERIT: - case R_LARCH_GNU_VTENTRY: - case R_LARCH_B16: - case R_LARCH_B21: - case R_LARCH_B26: - case R_LARCH_ABS_HI20: - case R_LARCH_ABS_LO12: - case R_LARCH_ABS64_LO20: - case R_LARCH_ABS64_HI12: - case R_LARCH_PCALA_LO12: - case R_LARCH_PCALA64_LO20: - case R_LARCH_PCALA64_HI12: - case R_LARCH_GOT_PC_LO12: - case R_LARCH_GOT64_PC_LO20: - case R_LARCH_GOT64_PC_HI12: - case R_LARCH_GOT64_HI20: - case R_LARCH_GOT64_LO12: - case R_LARCH_GOT64_LO20: - case R_LARCH_GOT64_HI12: - case R_LARCH_TLS_LE_HI20: - case R_LARCH_TLS_LE_LO12: - case R_LARCH_TLS_LE64_LO20: - case R_LARCH_TLS_LE64_HI12: - case R_LARCH_TLS_IE_PC_HI20: - case R_LARCH_TLS_IE_PC_LO12: - case R_LARCH_TLS_IE64_PC_LO20: - case R_LARCH_TLS_IE64_PC_HI12: - case R_LARCH_TLS_IE64_HI20: - case R_LARCH_TLS_IE64_LO12: - case R_LARCH_TLS_IE64_LO20: - case R_LARCH_TLS_IE64_HI12: - case R_LARCH_TLS_LD_PC_HI20: - case R_LARCH_TLS_LD64_HI20: - case R_LARCH_TLS_GD_PC_HI20: - case R_LARCH_TLS_GD64_HI20: - case R_LARCH_32_PCREL: - case R_LARCH_RELAX: - case R_LARCH_DELETE: - case R_LARCH_ALIGN: - case R_LARCH_PCREL20_S2: - case R_LARCH_CFA: - case R_LARCH_ADD6: - case R_LARCH_SUB6: - case R_LARCH_ADD_ULEB128: - case R_LARCH_SUB_ULEB128: - case R_LARCH_64_PCREL: - // - // These types are not used or do not require fixup. - // - break; - - case R_LARCH_GOT_PC_HI20: - Offset = Sym->st_value - (UINTN)(Targ - mCoffFile); - if (Offset < 0) { - Offset = (UINTN)(Targ - mCoffFile) - Sym->st_value; - Hi = Offset & ~0xfff; - Lo = (INT32)((Offset & 0xfff) << 20) >> 20; - if ((Lo < 0) && (Lo > -2048)) { - Hi += 0x1000; - Lo = ~(0x1000 - Lo) + 1; - } - Hi = ~Hi + 1; - Lo = ~Lo + 1; - } else { - Hi = Offset & ~0xfff; - Lo = (INT32)((Offset & 0xfff) << 20) >> 20; - if (Lo < 0) { - Hi += 0x1000; - Lo = ~(0x1000 - Lo) + 1; - } - } - // Re-encode the offset as PCADDU12I + ADDI.D(Convert LD.D) instruction - *(UINT32 *)Targ &= 0x1f; - *(UINT32 *)Targ |= 0x1c000000; - *(UINT32 *)Targ |= (((Hi >> 12) & 0xfffff) << 5); - *(UINT32 *)(Targ + 4) &= 0x3ff; - *(UINT32 *)(Targ + 4) |= 0x2c00000 | ((Lo & 0xfff) << 10); - break; - - // - // Attempt to convert instruction. - // - case R_LARCH_PCALA_HI20: - // Decode the PCALAU12I instruction and the instruction that following it. - Offset = ((INT32)((*(UINT32 *)Targ & 0x1ffffe0) << 7)); - Offset += ((INT32)((*(UINT32 *)(Targ + 4) & 0x3ffc00) << 10) >> 20); - // - // PCALA offset is relative to the previous page boundary, - // whereas PCADD offset is relative to the instruction itself. - // So fix up the offset so it points to the page containing - // the symbol. - // - Offset -= (UINTN)(Targ - mCoffFile) & 0xfff; - if (Offset < 0) { - Offset = -Offset; - Hi = Offset & ~0xfff; - Lo = (INT32)((Offset & 0xfff) << 20) >> 20; - if ((Lo < 0) && (Lo > -2048)) { - Hi += 0x1000; - Lo = ~(0x1000 - Lo) + 1; - } - Hi = ~Hi + 1; - Lo = ~Lo + 1; - } else { - Hi = Offset & ~0xfff; - Lo = (INT32)((Offset & 0xfff) << 20) >> 20; - if (Lo < 0) { - Hi += 0x1000; - Lo = ~(0x1000 - Lo) + 1; - } - } - // Convert the first instruction from PCALAU12I to PCADDU12I and re-encode the offset into them. - *(UINT32 *)Targ &= 0x1f; - *(UINT32 *)Targ |= 0x1c000000; - *(UINT32 *)Targ |= (((Hi >> 12) & 0xfffff) << 5); - *(UINT32 *)(Targ + 4) &= 0xffc003ff; - *(UINT32 *)(Targ + 4) |= (Lo & 0xfff) << 10; - break; - default: - Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_LOONGARCH relocation 0x%x.", mInImageName, (unsigned) ELF64_R_TYPE(Rel->r_info)); - } - } else { - Error (NULL, 0, 3000, "Invalid", "Not a supported machine type"); - } - } - } - } - - return TRUE; -} - -STATIC -VOID -WriteRelocations64 ( - VOID - ) -{ - UINT32 Index; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - EFI_IMAGE_DATA_DIRECTORY *Dir; - UINT32 RiscVRelType; - - for (Index = 0; Index < mEhdr->e_shnum; Index++) { - Elf_Shdr *RelShdr = GetShdrByIndex(Index); - if ((RelShdr->sh_type == SHT_REL) || (RelShdr->sh_type == SHT_RELA)) { - Elf_Shdr *SecShdr = GetShdrByIndex (RelShdr->sh_info); - if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) { - UINT64 RelIdx; - - for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) { - Elf_Rela *Rel = (Elf_Rela *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx); - - if (mEhdr->e_machine == EM_X86_64) { - switch (ELF_R_TYPE(Rel->r_info)) { - case R_X86_64_NONE: - case R_X86_64_PC32: - case R_X86_64_PLT32: - case R_X86_64_GOTPCREL: - case R_X86_64_GOTPCRELX: - case R_X86_64_REX_GOTPCRELX: - break; - case R_X86_64_64: - VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08llX", - mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr)); - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_DIR64); - break; - // - // R_X86_64_32 and R_X86_64_32S are ELF64 relocations emitted when using - // the SYSV X64 ABI small non-position-independent code model. - // R_X86_64_32 is used for unsigned 32-bit immediates with a 32-bit operand - // size. The value is either not extended, or zero-extended to 64 bits. - // R_X86_64_32S is used for either signed 32-bit non-rip-relative displacements - // or signed 32-bit immediates with a 64-bit operand size. The value is - // sign-extended to 64 bits. - // EFI_IMAGE_REL_BASED_HIGHLOW is a PE relocation that uses 32-bit arithmetic - // for rebasing an image. - // EFI PE binaries declare themselves EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE and - // may load above 2GB. If an EFI PE binary with a converted R_X86_64_32S - // relocation is loaded above 2GB, the value will get sign-extended to the - // negative part of the 64-bit address space. The negative part of the 64-bit - // address space is unmapped, so accessing such an address page-faults. - // In order to support R_X86_64_32S, it is necessary to unset - // EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE, and the EFI PE loader must implement - // this flag and abstain from loading such a PE binary above 2GB. - // Since this feature is not supported, support for R_X86_64_32S (and hence - // the small non-position-independent code model) is disabled. - // - // case R_X86_64_32S: - case R_X86_64_32: - VerboseMsg ("EFI_IMAGE_REL_BASED_HIGHLOW Offset: 0x%08llX", - mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr)); - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_HIGHLOW); - break; - default: - Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_X86_64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } - } else if (mEhdr->e_machine == EM_AARCH64) { - - switch (ELF_R_TYPE(Rel->r_info)) { - case R_AARCH64_ADR_PREL_LO21: - case R_AARCH64_CONDBR19: - case R_AARCH64_LD_PREL_LO19: - case R_AARCH64_CALL26: - case R_AARCH64_JUMP26: - case R_AARCH64_PREL64: - case R_AARCH64_PREL32: - case R_AARCH64_PREL16: - case R_AARCH64_ADR_PREL_PG_HI21: - case R_AARCH64_ADD_ABS_LO12_NC: - case R_AARCH64_LDST8_ABS_LO12_NC: - case R_AARCH64_LDST16_ABS_LO12_NC: - case R_AARCH64_LDST32_ABS_LO12_NC: - case R_AARCH64_LDST64_ABS_LO12_NC: - case R_AARCH64_LDST128_ABS_LO12_NC: - case R_AARCH64_ADR_GOT_PAGE: - case R_AARCH64_LD64_GOT_LO12_NC: - case R_AARCH64_LD64_GOTOFF_LO15: - case R_AARCH64_LD64_GOTPAGE_LO15: - // - // No fixups are required for relative relocations, provided that - // the relative offsets between sections have been preserved in - // the ELF to PE/COFF conversion. We have already asserted that - // this is the case in WriteSections64 (). - // - break; - - case R_AARCH64_ABS64: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_DIR64); - break; - - case R_AARCH64_ABS32: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_HIGHLOW); - break; - - default: - Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } - } else if (mEhdr->e_machine == EM_RISCV64) { - RiscVRelType = ELF_R_TYPE(Rel->r_info); - switch (RiscVRelType) { - case R_RISCV_NONE: - break; - - case R_RISCV_32: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_HIGHLOW); - break; - - case R_RISCV_64: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_DIR64); - break; - - case R_RISCV_HI20: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_RISCV_HI20); - break; - - case R_RISCV_LO12_I: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_RISCV_LOW12I); - break; - - case R_RISCV_LO12_S: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_RISCV_LOW12S); - break; - - case R_RISCV_ADD64: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_ABSOLUTE); - break; - - case R_RISCV_SUB64: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_ABSOLUTE); - break; - - case R_RISCV_ADD32: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_ABSOLUTE); - break; - - case R_RISCV_SUB32: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_ABSOLUTE); - break; - - case R_RISCV_BRANCH: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_ABSOLUTE); - break; - - case R_RISCV_JAL: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_ABSOLUTE); - break; - - case R_RISCV_GPREL_I: - case R_RISCV_GPREL_S: - case R_RISCV_CALL: - case R_RISCV_CALL_PLT: - case R_RISCV_RVC_BRANCH: - case R_RISCV_RVC_JUMP: - case R_RISCV_RELAX: - case R_RISCV_SUB6: - case R_RISCV_SET6: - case R_RISCV_SET8: - case R_RISCV_SET16: - case R_RISCV_SET32: - case R_RISCV_PCREL_HI20: - case R_RISCV_GOT_HI20: - case R_RISCV_PCREL_LO12_I: - case R_RISCV_PCREL_LO12_S: - break; - - default: - Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info)); - } - } else if (mEhdr->e_machine == EM_LOONGARCH) { - switch (ELF_R_TYPE(Rel->r_info)) { - case R_LARCH_MARK_LA: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA); - break; - case R_LARCH_64: - CoffAddFixup( - (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info] - + (Rel->r_offset - SecShdr->sh_addr)), - EFI_IMAGE_REL_BASED_DIR64); - break; - case R_LARCH_NONE: - case R_LARCH_32: - case R_LARCH_RELATIVE: - case R_LARCH_COPY: - case R_LARCH_JUMP_SLOT: - case R_LARCH_TLS_DTPMOD32: - case R_LARCH_TLS_DTPMOD64: - case R_LARCH_TLS_DTPREL32: - case R_LARCH_TLS_DTPREL64: - case R_LARCH_TLS_TPREL32: - case R_LARCH_TLS_TPREL64: - case R_LARCH_IRELATIVE: - case R_LARCH_MARK_PCREL: - case R_LARCH_SOP_PUSH_PCREL: - case R_LARCH_SOP_PUSH_ABSOLUTE: - case R_LARCH_SOP_PUSH_DUP: - case R_LARCH_SOP_PUSH_GPREL: - case R_LARCH_SOP_PUSH_TLS_TPREL: - case R_LARCH_SOP_PUSH_TLS_GOT: - case R_LARCH_SOP_PUSH_TLS_GD: - case R_LARCH_SOP_PUSH_PLT_PCREL: - case R_LARCH_SOP_ASSERT: - case R_LARCH_SOP_NOT: - case R_LARCH_SOP_SUB: - case R_LARCH_SOP_SL: - case R_LARCH_SOP_SR: - case R_LARCH_SOP_ADD: - case R_LARCH_SOP_AND: - case R_LARCH_SOP_IF_ELSE: - case R_LARCH_SOP_POP_32_S_10_5: - case R_LARCH_SOP_POP_32_U_10_12: - case R_LARCH_SOP_POP_32_S_10_12: - case R_LARCH_SOP_POP_32_S_10_16: - case R_LARCH_SOP_POP_32_S_10_16_S2: - case R_LARCH_SOP_POP_32_S_5_20: - case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: - case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: - case R_LARCH_SOP_POP_32_U: - case R_LARCH_ADD8: - case R_LARCH_ADD16: - case R_LARCH_ADD24: - case R_LARCH_ADD32: - case R_LARCH_ADD64: - case R_LARCH_SUB8: - case R_LARCH_SUB16: - case R_LARCH_SUB24: - case R_LARCH_SUB32: - case R_LARCH_SUB64: - case R_LARCH_GNU_VTINHERIT: - case R_LARCH_GNU_VTENTRY: - case R_LARCH_B16: - case R_LARCH_B21: - case R_LARCH_B26: - case R_LARCH_ABS_HI20: - case R_LARCH_ABS_LO12: - case R_LARCH_ABS64_LO20: - case R_LARCH_ABS64_HI12: - case R_LARCH_PCALA_HI20: - case R_LARCH_PCALA_LO12: - case R_LARCH_PCALA64_LO20: - case R_LARCH_PCALA64_HI12: - case R_LARCH_GOT_PC_HI20: - case R_LARCH_GOT_PC_LO12: - case R_LARCH_GOT64_PC_LO20: - case R_LARCH_GOT64_PC_HI12: - case R_LARCH_GOT64_HI20: - case R_LARCH_GOT64_LO12: - case R_LARCH_GOT64_LO20: - case R_LARCH_GOT64_HI12: - case R_LARCH_TLS_LE_HI20: - case R_LARCH_TLS_LE_LO12: - case R_LARCH_TLS_LE64_LO20: - case R_LARCH_TLS_LE64_HI12: - case R_LARCH_TLS_IE_PC_HI20: - case R_LARCH_TLS_IE_PC_LO12: - case R_LARCH_TLS_IE64_PC_LO20: - case R_LARCH_TLS_IE64_PC_HI12: - case R_LARCH_TLS_IE64_HI20: - case R_LARCH_TLS_IE64_LO12: - case R_LARCH_TLS_IE64_LO20: - case R_LARCH_TLS_IE64_HI12: - case R_LARCH_TLS_LD_PC_HI20: - case R_LARCH_TLS_LD64_HI20: - case R_LARCH_TLS_GD_PC_HI20: - case R_LARCH_TLS_GD64_HI20: - case R_LARCH_32_PCREL: - case R_LARCH_RELAX: - case R_LARCH_DELETE: - case R_LARCH_ALIGN: - case R_LARCH_PCREL20_S2: - case R_LARCH_CFA: - case R_LARCH_ADD6: - case R_LARCH_SUB6: - case R_LARCH_ADD_ULEB128: - case R_LARCH_SUB_ULEB128: - case R_LARCH_64_PCREL: - // - // These types are not used or do not require fixup in PE format files. - // - break; - default: - Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_LOONGARCH relocation 0x%x.", mInImageName, (unsigned) ELF64_R_TYPE(Rel->r_info)); - } - } else { - Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine); - } - } - if (mEhdr->e_machine == EM_X86_64 && RelShdr->sh_info == mGOTShindex) { - // - // Tack relocations for GOT entries after other relocations for - // the section the GOT is in, as it's usually found at the end - // of the section. This is done in order to maintain Rva order - // of Coff relocations. - // - EmitGOTRelocations(); - } - } - } - } - - if (mEhdr->e_machine == EM_X86_64) { - // - // This is a safety net just in case the GOT is in a section - // with no other relocations and the first invocation of - // EmitGOTRelocations() above was skipped. This invocation - // does not maintain Rva order of Coff relocations. - // At present, with a single text section, all references to - // the GOT and the GOT itself reside in section .text, so - // if there's a GOT at all, the first invocation above - // is executed. - // - EmitGOTRelocations(); - } - // - // Pad by adding empty entries. - // - while (mCoffOffset & (mCoffAlignment - 1)) { - CoffAddFixupEntry(0); - } - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); - Dir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - Dir->Size = mCoffOffset - mRelocOffset; - if (Dir->Size == 0) { - // If no relocations, null out the directory entry and don't add the .reloc section - Dir->VirtualAddress = 0; - NtHdr->Pe32Plus.FileHeader.NumberOfSections--; - } else { - Dir->VirtualAddress = mRelocOffset; - CreateSectionHeader (".reloc", mRelocOffset, mCoffOffset - mRelocOffset, - EFI_IMAGE_SCN_CNT_INITIALIZED_DATA - | EFI_IMAGE_SCN_MEM_DISCARDABLE - | EFI_IMAGE_SCN_MEM_READ); - } -} - -STATIC -VOID -WriteDebug64 ( - VOID - ) -{ - UINT32 Len; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - EFI_IMAGE_DATA_DIRECTORY *DataDir; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir; - EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10; - EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY *DllEntry; - - Len = strlen(mInImageName) + 1; - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); - DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]; - DataDir->VirtualAddress = mDebugOffset; - DataDir->Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - - Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + mDebugOffset); - - if (mDllCharacteristicsEx != 0) { - DataDir->Size += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - - Dir->Type = EFI_IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS; - Dir->SizeOfData = sizeof (EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY); - Dir->FileOffset = mDebugOffset + DataDir->Size + - sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + - DebugRvaAlign(Len); - Dir->RVA = Dir->FileOffset; - - DllEntry = (VOID *)(mCoffFile + Dir->FileOffset); - - DllEntry->DllCharacteristicsEx = mDllCharacteristicsEx; - - Dir++; - } - - Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW; - Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len; - Dir->RVA = mDebugOffset + DataDir->Size; - Dir->FileOffset = mDebugOffset + DataDir->Size; - - Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1); - Nb10->Signature = CODEVIEW_SIGNATURE_NB10; - strcpy ((char *)(Nb10 + 1), mInImageName); -} - -STATIC -VOID -SetImageSize64 ( - VOID - ) -{ - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - - // - // Set image size - // - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); - NtHdr->Pe32Plus.OptionalHeader.SizeOfImage = mCoffOffset; -} - -STATIC -VOID -CleanUp64 ( - VOID - ) -{ - if (mCoffSectionsOffset != NULL) { - free (mCoffSectionsOffset); - } -} - -STATIC -VOID -WriteExport64 ( - VOID - ) -{ - EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; - EFI_IMAGE_EXPORT_DIRECTORY *ExportDir; - EFI_IMAGE_DATA_DIRECTORY *DataDir; - UINT32 FileNameOffset; - UINT32 NameOffset; - UINT16 Index; - UINT8 *Tdata = NULL; - - ExportDir = (EFI_IMAGE_EXPORT_DIRECTORY*)(mCoffFile + mExportOffset); - ExportDir->Characteristics = 0; - ExportDir->TimeDateStamp = 0; - ExportDir->MajorVersion = 0; - ExportDir->MinorVersion =0; - ExportDir->Name = 0; - ExportDir->NumberOfFunctions = mExportSymNum; - ExportDir->NumberOfNames = mExportSymNum; - ExportDir->Base = EFI_IMAGE_EXPORT_ORDINAL_BASE; - ExportDir->AddressOfFunctions = mExportOffset + sizeof(EFI_IMAGE_EXPORT_DIRECTORY); - ExportDir->AddressOfNames = ExportDir->AddressOfFunctions + EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum; - ExportDir->AddressOfNameOrdinals = ExportDir->AddressOfNames + EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum; - - FileNameOffset = ExportDir->AddressOfNameOrdinals + EFI_IMAGE_EXPORT_ORDINAL_SIZE * mExportSymNum; - NameOffset = FileNameOffset + strlen(mInImageName) + 1; - - // Write Input image Name RVA - ExportDir->Name = FileNameOffset; - - // Write Input image Name - strcpy((char *)(mCoffFile + FileNameOffset), mInImageName); - - for (Index = 0; Index < mExportSymNum; Index++) { - // - // Write Export Address Table - // - Tdata = mCoffFile + ExportDir->AddressOfFunctions + Index * EFI_IMAGE_EXPORT_ADDR_SIZE; - *(UINT32 *)Tdata = mExportRVA[Index]; - - // - // Write Export Name Pointer Table - // - Tdata = mCoffFile + ExportDir->AddressOfNames + Index * EFI_IMAGE_EXPORT_ADDR_SIZE; - *(UINT32 *)Tdata = NameOffset; - - // - // Write Export Ordinal table - // - Tdata = mCoffFile + ExportDir->AddressOfNameOrdinals + Index * EFI_IMAGE_EXPORT_ORDINAL_SIZE; - *(UINT16 *)Tdata = Index; - - // - // Write Export Name Table - // - strcpy((char *)(mCoffFile + NameOffset), mExportSymName[Index]); - NameOffset += strlen(mExportSymName[Index]) + 1; - } - - NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); - DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT]; - DataDir->VirtualAddress = mExportOffset; - DataDir->Size = mExportSize; - -} - diff --git a/BaseTools/Source/C/GenFw/ElfConvert.c b/BaseTools/Source/C/GenFw/ElfConvert.c deleted file mode 100644 index d6d9feb7d8..0000000000 --- a/BaseTools/Source/C/GenFw/ElfConvert.c +++ /dev/null @@ -1,253 +0,0 @@ -/** @file -Elf convert solution - -Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
- -SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __GNUC__ -#define RUNTIME_FUNCTION _WINNT_DUP_RUNTIME_FUNCTION -#include -#undef RUNTIME_FUNCTION -#include -#endif -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "EfiUtilityMsgs.h" - -#include "GenFw.h" -#include "ElfConvert.h" -#include "Elf32Convert.h" -#include "Elf64Convert.h" - -// -// Result Coff file in memory. -// -UINT8 *mCoffFile = NULL; - -// -// COFF relocation data -// -EFI_IMAGE_BASE_RELOCATION *mCoffBaseRel; -UINT16 *mCoffEntryRel; - -// -// Current offset in coff file. -// -UINT32 mCoffOffset; - -// -// Offset in Coff file of headers and sections. -// -UINT32 mTableOffset; - -// -//mFileBufferSize -// -UINT32 mFileBufferSize; - -// -//***************************************************************************** -// Common ELF Functions -//***************************************************************************** -// - -VOID -CoffAddFixupEntry( - UINT16 Val - ) -{ - *mCoffEntryRel = Val; - mCoffEntryRel++; - mCoffBaseRel->SizeOfBlock += 2; - mCoffOffset += 2; -} - -VOID -CoffAddFixup( - UINT32 Offset, - UINT8 Type - ) -{ - if (mCoffBaseRel == NULL - || mCoffBaseRel->VirtualAddress != (Offset & ~0xfff)) { - if (mCoffBaseRel != NULL) { - // - // Add a null entry (is it required ?) - // - CoffAddFixupEntry (0); - - // - // Pad for alignment. - // - if (mCoffOffset % 4 != 0) - CoffAddFixupEntry (0); - } - - mCoffFile = realloc ( - mCoffFile, - mCoffOffset + sizeof(EFI_IMAGE_BASE_RELOCATION) + 2 * MAX_COFF_ALIGNMENT - ); - if (mCoffFile == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - } - assert (mCoffFile != NULL); - memset ( - mCoffFile + mCoffOffset, 0, - sizeof(EFI_IMAGE_BASE_RELOCATION) + 2 * MAX_COFF_ALIGNMENT - ); - - mCoffBaseRel = (EFI_IMAGE_BASE_RELOCATION*)(mCoffFile + mCoffOffset); - mCoffBaseRel->VirtualAddress = Offset & ~0xfff; - mCoffBaseRel->SizeOfBlock = sizeof(EFI_IMAGE_BASE_RELOCATION); - - mCoffEntryRel = (UINT16 *)(mCoffBaseRel + 1); - mCoffOffset += sizeof(EFI_IMAGE_BASE_RELOCATION); - } - - // - // Fill the entry. - // - CoffAddFixupEntry((UINT16) ((Type << 12) | (Offset & 0xfff))); -} - -VOID -CreateSectionHeader ( - const CHAR8 *Name, - UINT32 Offset, - UINT32 Size, - UINT32 Flags - ) -{ - EFI_IMAGE_SECTION_HEADER *Hdr; - Hdr = (EFI_IMAGE_SECTION_HEADER*)(mCoffFile + mTableOffset); - - strcpy((char *)Hdr->Name, Name); - Hdr->Misc.VirtualSize = Size; - Hdr->VirtualAddress = Offset; - Hdr->SizeOfRawData = Size; - Hdr->PointerToRawData = Offset; - Hdr->PointerToRelocations = 0; - Hdr->PointerToLinenumbers = 0; - Hdr->NumberOfRelocations = 0; - Hdr->NumberOfLinenumbers = 0; - Hdr->Characteristics = Flags; - - mTableOffset += sizeof (EFI_IMAGE_SECTION_HEADER); -} - -// -//***************************************************************************** -// Functions called from GenFw main code. -//***************************************************************************** -// - -INTN -IsElfHeader ( - UINT8 *FileBuffer -) -{ - return (FileBuffer[EI_MAG0] == ELFMAG0 && - FileBuffer[EI_MAG1] == ELFMAG1 && - FileBuffer[EI_MAG2] == ELFMAG2 && - FileBuffer[EI_MAG3] == ELFMAG3); -} - -BOOLEAN -ConvertElf ( - UINT8 **FileBuffer, - UINT32 *FileLength - ) -{ - ELF_FUNCTION_TABLE ElfFunctions; - UINT8 EiClass; - - mFileBufferSize = *FileLength; - // - // Determine ELF type and set function table pointer correctly. - // - VerboseMsg ("Check Elf Image Header"); - EiClass = (*FileBuffer)[EI_CLASS]; - if (EiClass == ELFCLASS32) { - if (!InitializeElf32 (*FileBuffer, &ElfFunctions)) { - return FALSE; - } - } else if (EiClass == ELFCLASS64) { - if (!InitializeElf64 (*FileBuffer, &ElfFunctions)) { - return FALSE; - } - } else { - Error (NULL, 0, 3000, "Unsupported", "ELF EI_CLASS not supported."); - return FALSE; - } - - // - // Compute sections new address. - // - VerboseMsg ("Compute sections new address."); - ElfFunctions.ScanSections (); - - // - // Write and relocate sections. - // - VerboseMsg ("Write and relocate sections."); - if (!ElfFunctions.WriteSections (SECTION_TEXT)) { - return FALSE; - } - if (!ElfFunctions.WriteSections (SECTION_DATA)) { - return FALSE; - } - if (!ElfFunctions.WriteSections (SECTION_HII)) { - return FALSE; - } - - // - // Translate and write relocations. - // - VerboseMsg ("Translate and write relocations."); - ElfFunctions.WriteRelocations (); - - // - // Write debug info. - // - VerboseMsg ("Write debug info."); - ElfFunctions.WriteDebug (); - - // - // For PRM Driver to Write export info. - // - if (mExportFlag) { - VerboseMsg ("Write export info."); - ElfFunctions.WriteExport (); - } - - // - // Make sure image size is correct before returning the new image. - // - VerboseMsg ("Set image size."); - ElfFunctions.SetImageSize (); - - // - // Replace. - // - free (*FileBuffer); - *FileBuffer = mCoffFile; - *FileLength = mCoffOffset; - - // - // Free resources used by ELF functions. - // - ElfFunctions.CleanUp (); - - return TRUE; -} diff --git a/BaseTools/Source/C/GenFw/GNUmakefile b/BaseTools/Source/C/GenFw/GNUmakefile deleted file mode 100644 index 2079835df7..0000000000 --- a/BaseTools/Source/C/GenFw/GNUmakefile +++ /dev/null @@ -1,27 +0,0 @@ -## @file -# GNU/Linux makefile for 'GenFw' module build. -# -# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
-# SPDX-License-Identifier: BSD-2-Clause-Patent -# -MAKEROOT ?= .. - -APPNAME = GenFw - -OBJECTS = GenFw.o ElfConvert.o Elf32Convert.o Elf64Convert.o - -include $(MAKEROOT)/Makefiles/app.makefile - -LIBS = -lCommon -ifeq ($(CYGWIN), CYGWIN) - LIBS += -L/lib/e2fsprogs -luuid -endif - -ifeq ($(LINUX), Linux) -ifndef CROSS_LIB_UUID - LIBS += -luuid -else - LIBS += -L$(CROSS_LIB_UUID) -endif -endif - diff --git a/BaseTools/Source/C/GenFw/GenFw.c b/BaseTools/Source/C/GenFw/GenFw.c deleted file mode 100644 index daf840c3cd..0000000000 --- a/BaseTools/Source/C/GenFw/GenFw.c +++ /dev/null @@ -1,3333 +0,0 @@ -/** @file -Converts a pe32+ image to an FW, Te image type, or other specific image. - -Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __GNUC__ -#define RUNTIME_FUNCTION _WINNT_DUP_RUNTIME_FUNCTION -#include -#undef RUNTIME_FUNCTION -#include -#include -#include -#endif -#include -#include -#include -#include -#include - -#include -#include -#include - -// -// Acpi Table definition -// -#include -#include -#include -#include -#include - -#include "CommonLib.h" -#include "PeCoffLib.h" -#include "ParseInf.h" -#include "EfiUtilityMsgs.h" - -#include "GenFw.h" - -// -// Version of this utility -// -#define UTILITY_NAME "GenFw" -#define UTILITY_MAJOR_VERSION 0 -#define UTILITY_MINOR_VERSION 2 - -#define HII_RESOURCE_SECTION_INDEX 1 -#define HII_RESOURCE_SECTION_NAME "HII" - -#define DEFAULT_MC_PAD_BYTE_VALUE 0xFF -#define DEFAULT_MC_ALIGNMENT 16 - -#define STATUS_IGNORE 0xA -// -// Structure definition for a microcode header -// -typedef struct { - UINT32 HeaderVersion; - UINT32 PatchId; - UINT32 Date; - UINT32 CpuId; - UINT32 Checksum; - UINT32 LoaderVersion; - UINT32 PlatformId; - UINT32 DataSize; // if 0, then TotalSize = 2048, and TotalSize field is invalid - UINT32 TotalSize; // number of bytes - UINT32 Reserved[3]; -} MICROCODE_IMAGE_HEADER; - -static EFI_GUID mZeroGuid = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; - -static const char *gHiiPackageRCFileHeader[] = { - "//", - "// DO NOT EDIT -- auto-generated file", - "//", - NULL -}; - -// -// Module image information -// -CHAR8 *mInImageName; -UINT32 mImageTimeStamp = 0; -UINT32 mImageSize = 0; -UINT32 mOutImageType = FW_DUMMY_IMAGE; -BOOLEAN mIsConvertXip = FALSE; -BOOLEAN mExportFlag = FALSE; -BOOLEAN mNoNxCompat = FALSE; - -STATIC -EFI_STATUS -ZeroDebugData ( - IN OUT UINT8 *FileBuffer, - BOOLEAN ZeroDebug - ); - -STATIC -EFI_STATUS -SetStamp ( - IN OUT UINT8 *FileBuffer, - IN CHAR8 *TimeStamp - ); - -STATIC -STATUS -MicrocodeReadData ( - FILE *InFptr, - UINT32 *Data - ); - -STATIC -VOID -Version ( - VOID - ) -/*++ - -Routine Description: - - Print out version information for this utility. - -Arguments: - - None - -Returns: - - None - ---*/ -{ - fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION); -} - -STATIC -VOID -Usage ( - VOID - ) -/*++ - -Routine Description: - - Print Help message. - -Arguments: - - VOID - -Returns: - - None - ---*/ -{ - // - // Summary usage - // - fprintf (stdout, "\nUsage: %s [options] \n\n", UTILITY_NAME); - - // - // Copyright declaration - // - fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n"); - - // - // Details Option - // - fprintf (stdout, "Options:\n"); - fprintf (stdout, " -o FileName, --outputfile FileName\n\ - File will be created to store the output content.\n"); - fprintf (stdout, " -e EFI_FILETYPE, --efiImage EFI_FILETYPE\n\ - Create Efi Image. EFI_FILETYPE is one of BASE,SMM_CORE,\n\ - PEI_CORE, PEIM, DXE_CORE, DXE_DRIVER, UEFI_APPLICATION,\n\ - SEC, DXE_SAL_DRIVER, UEFI_DRIVER, DXE_RUNTIME_DRIVER,\n\ - DXE_SMM_DRIVER, SECURITY_CORE, COMBINED_PEIM_DRIVER,\n\ - MM_STANDALONE, MM_CORE_STANDALONE,\n\ - PIC_PEIM, RELOCATABLE_PEIM, BS_DRIVER, RT_DRIVER,\n\ - APPLICATION, SAL_RT_DRIVER to support all module types\n\ - It can only be used together with --keepexceptiontable,\n\ - --keepzeropending, --keepoptionalheader, -r, -o option.\n\ - It is a action option. If it is combined with other action options,\n\ - the later input action option will override the previous one.\n"); - fprintf (stdout, " -c, --acpi Create Acpi table.\n\ - It can't be combined with other action options\n\ - except for -o, -r option. It is a action option.\n\ - If it is combined with other action options, the later\n\ - input action option will override the previous one.\n"); - fprintf (stdout, " -t, --terse Create Te Image.\n\ - It can only be used together with --keepexceptiontable,\n\ - --keepzeropending, --keepoptionalheader, -r, -o option.\n\ - It is a action option. If it is combined with other action options,\n\ - the later input action option will override the previous one.\n"); - fprintf (stdout, " -u, --dump Dump TeImage Header.\n\ - It can't be combined with other action options\n\ - except for -o, -r option. It is a action option.\n\ - If it is combined with other action options, the later\n\ - input action option will override the previous one.\n"); - fprintf (stdout, " -z, --zero Zero the Debug Data Fields in the PE input image file.\n\ - It also zeros the time stamp fields.\n\ - This option can be used to compare the binary efi image.\n\ - It can't be combined with other action options\n\ - except for -o, -r option. It is a action option.\n\ - If it is combined with other action options, the later\n\ - input action option will override the previous one.\n"); - fprintf (stdout, " -b, --exe2bin Convert the input EXE to the output BIN file.\n\ - It can't be combined with other action options\n\ - except for -o, -r option. It is a action option.\n\ - If it is combined with other action options, the later\n\ - input action option will override the previous one.\n");; - fprintf (stdout, " -l, --stripped Strip off the relocation info from PE or TE image.\n\ - It can't be combined with other action options\n\ - except for -o, -r option. It is a action option.\n\ - If it is combined with other action options, the later\n\ - input action option will override the previous one.\n"); - fprintf (stdout, " -s timedate, --stamp timedate\n\ - timedate format is \"yyyy-mm-dd 00:00:00\". if timedata \n\ - is set to NOW, current system time is used. The support\n\ - date scope is 1970-01-01 00+timezone:00:00\n\ - ~ 2038-01-19 03+timezone:14:07\n\ - The scope is adjusted according to the different zones.\n\ - It can't be combined with other action options\n\ - except for -o, -r option. It is a action option.\n\ - If it is combined with other action options, the later\n\ - input action option will override the previous one.\n"); - fprintf (stdout, " -m, --mcifile Convert input microcode txt file to microcode bin file.\n\ - It can't be combined with other action options\n\ - except for -o option. It is a action option.\n\ - If it is combined with other action options, the later\n\ - input action option will override the previous one.\n"); - fprintf (stdout, " -j, --join Combine multi microcode bin files to one file.\n\ - It can be specified with -a, -p, -o option.\n\ - No other options can be combined with it.\n\ - If it is combined with other action options, the later\n\ - input action option will override the previous one.\n"); - fprintf (stdout, " -a NUM, --align NUM NUM is one HEX or DEC format alignment value.\n\ - This option is only used together with -j option.\n"); - fprintf (stdout, " -p NUM, --pad NUM NUM is one HEX or DEC format padding value.\n\ - This option is only used together with -j option.\n"); - fprintf (stdout, " --keepexceptiontable Don't clear exception table.\n\ - This option can be used together with -e or -t.\n\ - It doesn't work for other options.\n"); - fprintf (stdout, " --keepoptionalheader Don't zero PE/COFF optional header fields.\n\ - This option can be used together with -e or -t.\n\ - It doesn't work for other options.\n"); - fprintf (stdout, " --keepzeropending Don't strip zero pending of .reloc.\n\ - This option can be used together with -e or -t.\n\ - It doesn't work for other options.\n"); - fprintf (stdout, " -r, --replace Overwrite the input file with the output content.\n\ - If more input files are specified,\n\ - the last input file will be as the output file.\n"); - fprintf (stdout, " -g HiiPackageListGuid, --hiiguid HiiPackageListGuid\n\ - Guid is used to specify hii package list guid.\n\ - Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\ - If not specified, the first Form FormSet guid is used.\n"); - fprintf (stdout, " --hiipackage Combine all input binary hii packages into \n\ - a single package list as the text resource data(RC).\n\ - It can't be combined with other action options\n\ - except for -o option. It is a action option.\n\ - If it is combined with other action options, the later\n\ - input action option will override the previous one.\n"); - fprintf (stdout, " --hiibinpackage Combine all input binary hii packages into \n\ - a single package list as the binary resource section.\n\ - It can't be combined with other action options\n\ - except for -o option. It is a action option.\n\ - If it is combined with other action options, the later\n\ - input action option will override the previous one.\n"); - fprintf (stdout, " --rebase NewAddress Rebase image to new base address. New address \n\ - is also set to the first none code section header.\n\ - It can't be combined with other action options\n\ - except for -o or -r option. It is a action option.\n\ - If it is combined with other action options, the later\n\ - input action option will override the previous one.\n"); - fprintf (stdout, " --address NewAddress Set new address into the first none code \n\ - section header of the input image.\n\ - It can't be combined with other action options\n\ - except for -o or -r option. It is a action option.\n\ - If it is combined with other action options, the later\n\ - input action option will override the previous one.\n"); - fprintf (stdout, " --prm Scan symbol section from ELF image and \n\ - write export table into PE-COFF.\n\ - This option can be used together with -e.\n\ - It doesn't work for other options.\n"); - fprintf (stdout, " --nonxcompat Do not set the IMAGE_DLLCHARACTERISTICS_NX_COMPAT bit \n\ - of the optional header in the PE header even if the \n\ - requirements are met.\n"); - fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n"); - fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n"); - fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n"); - fprintf (stdout, " --version Show program's version number and exit\n"); - fprintf (stdout, " -h, --help Show this help message and exit\n"); -} - -STATIC -STATUS -CheckAcpiTable ( - VOID *AcpiTable, - UINT32 Length - ) -/*++ - -Routine Description: - - Check Acpi Table - -Arguments: - - AcpiTable Buffer for AcpiSection - Length AcpiSection Length - -Returns: - - 0 success - non-zero otherwise - ---*/ -{ - EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader; - EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs; - UINT32 ExpectedLength; - - AcpiHeader = (EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable; - - // - // Generic check for AcpiTable length. - // - if (AcpiHeader->Length > Length) { - Error (NULL, 0, 3000, "Invalid", "AcpiTable length check failed.", NULL); - return STATUS_ERROR; - } - - // - // Currently, we only check must-have tables: FADT, FACS, DSDT, - // and some important tables: MADT, MCFG. - // - switch (AcpiHeader->Signature) { - - // - // "FACP" Fixed ACPI Description Table - // - case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE: - switch (AcpiHeader->Revision) { - case EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION: - ExpectedLength = sizeof(EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE); - break; - case EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION: - ExpectedLength = sizeof(EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE); - break; - case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION: - ExpectedLength = sizeof(EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE); - break; - default: - if (AcpiHeader->Revision > EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) { - ExpectedLength = AcpiHeader->Length; - break; - } - Error (NULL, 0, 3000, "Invalid", "FACP revision check failed."); - return STATUS_ERROR; - } - if (ExpectedLength != AcpiHeader->Length) { - Error (NULL, 0, 3000, "Invalid", "FACP length check failed."); - return STATUS_ERROR; - } - break; - - // - // "FACS" Firmware ACPI Control Structure - // - case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE: - Facs = (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)AcpiTable; - if (Facs->Version > EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) { - break; - } - if ((Facs->Version != 0 /* field is reserved in ACPI 1.0 */) && - (Facs->Version != EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) && - (Facs->Version != EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION)){ - Error (NULL, 0, 3000, "Invalid", "FACS version check failed."); - return STATUS_ERROR; - } - if ((Facs->Length != sizeof(EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE)) && - (Facs->Length != sizeof(EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE)) && - (Facs->Length != sizeof(EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE))) { - Error (NULL, 0, 3000, "Invalid", "FACS length check failed."); - return STATUS_ERROR; - } - break; - - // - // "DSDT" Differentiated System Description Table - // - case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: - if (AcpiHeader->Revision > EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION) { - break; - } - if (AcpiHeader->Length <= sizeof(EFI_ACPI_DESCRIPTION_HEADER)) { - Error (NULL, 0, 3000, "Invalid", "DSDT length check failed."); - return STATUS_ERROR; - } - break; - - // - // "APIC" Multiple APIC Description Table - // - case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE: - if (AcpiHeader->Revision > EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) { - break; - } - if ((AcpiHeader->Revision != EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) && - (AcpiHeader->Revision != EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) && - (AcpiHeader->Revision != EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION)) { - Error (NULL, 0, 3000, "Invalid", "APIC revision check failed."); - return STATUS_ERROR; - } - if (AcpiHeader->Length <= sizeof(EFI_ACPI_DESCRIPTION_HEADER) + sizeof(UINT32) + sizeof(UINT32)) { - Error (NULL, 0, 3000, "Invalid", "APIC length check failed."); - return STATUS_ERROR; - } - break; - - // - // "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table - // - case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE: - if (AcpiHeader->Revision > EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION) { - break; - } - if (AcpiHeader->Revision != EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION) { - Error (NULL, 0, 3000, "Invalid", "MCFG revision check failed."); - return STATUS_ERROR; - } - if (AcpiHeader->Length <= sizeof(EFI_ACPI_DESCRIPTION_HEADER) + sizeof(UINT64)) { - Error (NULL, 0, 3000, "Invalid", "MCFG length check failed."); - return STATUS_ERROR; - } - break; - - // - // Other table pass check - // - default: - break; - } - - return STATUS_SUCCESS; -} - -/** - - Checks if the Pe image is nxcompat compliant. - - Must meet the following conditions: - 1. The PE is 64bit - 2. The section alignment is evenly divisible by 4k - 3. No section is writable and executable. - - @param PeHdr - The PE header - - @retval TRUE - The PE is nx compat compliant - @retval FALSE - The PE is not nx compat compliant - -**/ -STATIC -BOOLEAN -IsNxCompatCompliant ( - EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr - ) -{ - EFI_IMAGE_SECTION_HEADER *SectionHeader; - UINT32 Index; - UINT32 Mask; - - // Must have an optional header to perform verification - if (PeHdr->Pe32.FileHeader.SizeOfOptionalHeader == 0) { - return FALSE; - } - - // Verify PE is 64 bit - if (!(PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC)) { - return FALSE; - } - - // Verify Section Alignment is divisible by 4K - if (!((PeHdr->Pe32Plus.OptionalHeader.SectionAlignment % EFI_PAGE_SIZE) == 0)) { - return FALSE; - } - - // Verify sections are not Write & Execute - Mask = EFI_IMAGE_SCN_MEM_EXECUTE | EFI_IMAGE_SCN_MEM_WRITE; - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32Plus.OptionalHeader) + PeHdr->Pe32Plus.FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->Pe32Plus.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - if ((SectionHeader->Characteristics & Mask) == Mask) { - return FALSE; - } - } - - // Passed all requirements, return TRUE - return TRUE; -} - -VOID -SetHiiResourceHeader ( - UINT8 *HiiBinData, - UINT32 OffsetToFile - ) -{ - UINT32 Index; - EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory; - EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *ResourceDirectoryEntry; - EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString; - EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry; - - // - // Fill Resource section entry - // - ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData); - ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1); - for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries; Index ++) { - if (ResourceDirectoryEntry->u1.s.NameIsString) { - ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiBinData + ResourceDirectoryEntry->u1.s.NameOffset); - - if (ResourceDirectoryString->Length == 3 && - ResourceDirectoryString->String[0] == L'H' && - ResourceDirectoryString->String[1] == L'I' && - ResourceDirectoryString->String[2] == L'I') { - // - // Resource Type "HII" found - // - if (ResourceDirectoryEntry->u2.s.DataIsDirectory) { - // - // Move to next level - resource Name - // - ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory); - ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1); - - if (ResourceDirectoryEntry->u2.s.DataIsDirectory) { - // - // Move to next level - resource Language - // - ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory); - ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1); - } - } - - // - // Now it ought to be resource Data and update its OffsetToData value - // - if (!ResourceDirectoryEntry->u2.s.DataIsDirectory) { - ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiBinData + ResourceDirectoryEntry->u2.OffsetToData); - ResourceDataEntry->OffsetToData = ResourceDataEntry->OffsetToData + OffsetToFile; - break; - } - } - } - ResourceDirectoryEntry++; - } - - return; -} - -EFI_IMAGE_OPTIONAL_HEADER_UNION * -GetPeCoffHeader ( - void *Data - ) -{ - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr; - - // - // Read the dos & pe hdrs of the image - // - DosHdr = (EFI_IMAGE_DOS_HEADER *)Data; - if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - // NO DOS header, check for PE/COFF header - PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(Data); - if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { - return NULL; - } - } else { - - PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(((UINT8 *)Data) + DosHdr->e_lfanew); - if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { - return NULL; - } - } - - return PeHdr; -} - -void -PeCoffConvertImageToXip ( - UINT8 **FileBuffer, - UINT32 *FileLength - ) -{ - EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr; - EFI_IMAGE_OPTIONAL_HEADER_UNION *NewPeHdr; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - UINTN TotalNecessaryFileSize; - UINTN SectionSize; - UINT8 *XipFile; - UINT32 XipLength; - UINTN Index; - UINTN FirstSectionOffset; - BOOLEAN ConversionNeeded; - - PeHdr = GetPeCoffHeader ((void *) *FileBuffer); - if (PeHdr == NULL) { - return; - } - - if (PeHdr->Pe32.OptionalHeader.SectionAlignment != PeHdr->Pe32.OptionalHeader.FileAlignment) { - // - // The only reason to expand zero fill sections is to make them compatible with XIP images. - // If SectionAlignment is not equal to FileAlignment then it is not an XIP type image. - // - return; - } - - // - // Calculate size of XIP file, and determine if the conversion is needed. - // - ConversionNeeded = FALSE; - XipLength = 0; - FirstSectionOffset = *FileLength; - TotalNecessaryFileSize = 0; - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - SectionSize = MAX (SectionHeader->Misc.VirtualSize, SectionHeader->SizeOfRawData); - TotalNecessaryFileSize += SectionSize; - if (SectionSize > 0) { - FirstSectionOffset = MIN (FirstSectionOffset, SectionHeader->VirtualAddress); - XipLength = MAX (XipLength, SectionHeader->VirtualAddress + SectionSize); - if (SectionHeader->VirtualAddress != SectionHeader->PointerToRawData) { - ConversionNeeded = TRUE; - } - } - if (SectionHeader->Misc.VirtualSize > SectionHeader->SizeOfRawData) { - ConversionNeeded = TRUE; - } - } - - if (FirstSectionOffset < PeHdr->Pe32.OptionalHeader.SizeOfHeaders) { - // - // If one of the sections should be loaded to an offset overlapping with - // the executable header, then it cannot be made into an XIP image. - // - VerboseMsg ("PE/COFF conversion to XIP is impossible due to overlap"); - VerboseMsg ("of section data with the executable header."); - return; - } - - if (FirstSectionOffset == *FileLength) { - // - // If we never found a section with a non-zero size, then we - // skip the conversion. - // - return; - } - - TotalNecessaryFileSize += FirstSectionOffset; - - if (!ConversionNeeded) { - return; - } - - if (XipLength > (2 * TotalNecessaryFileSize)) { - VerboseMsg ("PE/COFF conversion to XIP appears to be larger than necessary."); - VerboseMsg ("The image linking process may have left unused memory ranges."); - } - - if (PeHdr->Pe32.FileHeader.PointerToSymbolTable != 0) { - // - // This field is obsolete and should be zero - // - PeHdr->Pe32.FileHeader.PointerToSymbolTable = 0; - } - - // - // Allocate the extra space that we need to grow the image - // - XipFile = malloc (XipLength); - if (XipFile == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - return; - } - memset (XipFile, 0, XipLength); - - // - // Copy the file headers - // - memcpy (XipFile, *FileBuffer, PeHdr->Pe32.OptionalHeader.SizeOfHeaders); - - NewPeHdr = GetPeCoffHeader ((void *)XipFile); - if (NewPeHdr == NULL) { - free (XipFile); - return; - } - - // - // Copy the section data over to the appropriate XIP offsets - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(NewPeHdr->Pe32.OptionalHeader) + NewPeHdr->Pe32.FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - if (SectionHeader->SizeOfRawData > 0) { - memcpy ( - XipFile + SectionHeader->VirtualAddress, - *FileBuffer + SectionHeader->PointerToRawData, - SectionHeader->SizeOfRawData - ); - } - // - // Make the size of raw data in section header alignment. - // - SectionSize = (SectionHeader->Misc.VirtualSize + PeHdr->Pe32.OptionalHeader.FileAlignment - 1) & (~(PeHdr->Pe32.OptionalHeader.FileAlignment - 1)); - if (SectionSize < SectionHeader->SizeOfRawData) { - SectionHeader->SizeOfRawData = SectionSize; - } - - SectionHeader->PointerToRawData = SectionHeader->VirtualAddress; - } - - free (*FileBuffer); - *FileLength = XipLength; - *FileBuffer = XipFile; - - mIsConvertXip = TRUE; -} - -UINT8 * -CreateHiiResouceSectionHeader ( - UINT32 *pSectionHeaderSize, - UINT32 HiiDataSize - ) -/*++ - -Routine Description: - - Create COFF resource section header - -Arguments: - - pSectionHeaderSize - Pointer to section header size. - HiiDataSize - Size of the total HII data in section. - -Returns: - The created section header buffer. - ---*/ -{ - UINT32 HiiSectionHeaderSize; - UINT32 HiiSectionOffset; - UINT8 *HiiSectionHeader; - EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory; - EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *TypeResourceDirectoryEntry; - EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *NameResourceDirectoryEntry; - EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *LanguageResourceDirectoryEntry; - EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString; - EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry; - - // - // Calculate the total size for the resource header (include Type, Name and Language) - // then allocate memory for the resource header. - // - HiiSectionHeaderSize = 3 * (sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY)) - + 3 * (sizeof (UINT16) + 3 * sizeof (CHAR16)) - + sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY); - HiiSectionHeader = malloc (HiiSectionHeaderSize); - if (HiiSectionHeader == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - return NULL; - } - memset (HiiSectionHeader, 0, HiiSectionHeaderSize); - - HiiSectionOffset = 0; - // - // Create Type entry - // - ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset); - HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY); - ResourceDirectory->NumberOfNamedEntries = 1; - TypeResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset); - HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY); - TypeResourceDirectoryEntry->u1.s.NameIsString = 1; - TypeResourceDirectoryEntry->u2.s.DataIsDirectory = 1; - TypeResourceDirectoryEntry->u2.s.OffsetToDirectory = HiiSectionOffset; - // - // Create Name entry - // - ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset); - HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY); - ResourceDirectory->NumberOfNamedEntries = 1; - NameResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset); - HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY); - NameResourceDirectoryEntry->u1.s.NameIsString = 1; - NameResourceDirectoryEntry->u2.s.DataIsDirectory = 1; - NameResourceDirectoryEntry->u2.s.OffsetToDirectory = HiiSectionOffset; - // - // Create Language entry - // - ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset); - HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY); - ResourceDirectory->NumberOfNamedEntries = 1; - LanguageResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset); - HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY); - LanguageResourceDirectoryEntry->u1.s.NameIsString = 1; - // - // Create string entry for Type - // - TypeResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset; - ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset); - ResourceDirectoryString->Length = 3; - ResourceDirectoryString->String[0] = L'H'; - ResourceDirectoryString->String[1] = L'I'; - ResourceDirectoryString->String[2] = L'I'; - HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]); - // - // Create string entry for Name - // - NameResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset; - ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset); - ResourceDirectoryString->Length = 3; - ResourceDirectoryString->String[0] = L'E'; - ResourceDirectoryString->String[1] = L'F'; - ResourceDirectoryString->String[2] = L'I'; - HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]); - // - // Create string entry for Language - // - LanguageResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset; - ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset); - ResourceDirectoryString->Length = 3; - ResourceDirectoryString->String[0] = L'B'; - ResourceDirectoryString->String[1] = L'I'; - ResourceDirectoryString->String[2] = L'N'; - HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]); - // - // Create Leaf data - // - LanguageResourceDirectoryEntry->u2.OffsetToData = HiiSectionOffset; - ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiSectionHeader + HiiSectionOffset); - HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY); - ResourceDataEntry->OffsetToData = HiiSectionOffset; - ResourceDataEntry->Size = HiiDataSize; - - *pSectionHeaderSize = HiiSectionHeaderSize; - return HiiSectionHeader; -} - -EFI_STATUS -RebaseImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINT32 *ReadSize, - OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - -Arguments: - - FileHandle - The handle to the PE/COFF file - - FileOffset - The offset, in bytes, into the file to read - - ReadSize - The number of bytes to read from the file starting at FileOffset - - Buffer - A pointer to the buffer to read the data into. - -Returns: - - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - ---*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINT32 Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -SetAddressToSectionHeader ( - IN CHAR8 *FileName, - IN OUT UINT8 *FileBuffer, - IN UINT64 NewPe32BaseAddress - ) -/*++ - -Routine Description: - - Set new base address into the section header of PeImage - -Arguments: - - FileName - Name of file - FileBuffer - Pointer to PeImage. - NewPe32BaseAddress - New Base Address for PE image. - -Returns: - - EFI_SUCCESS Set new base address into this image successfully. - ---*/ -{ - EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - UINTN Index; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - - // - // Initialize context - // - memset (&ImageContext, 0, sizeof (ImageContext)); - ImageContext.Handle = (VOID *) FileBuffer; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead; - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName); - return Status; - } - - if (ImageContext.RelocationsStripped) { - Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName); - return Status; - } - - // - // Get PeHeader pointer - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset); - - // - // Get section header list - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN) ImgHdr + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - - // - // Set base address into the first section header that doesn't point to code section. - // - for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) { - *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress; - break; - } - } - - // - // BaseAddress is set to section header. - // - return EFI_SUCCESS; -} - -EFI_STATUS -RebaseImage ( - IN CHAR8 *FileName, - IN OUT UINT8 *FileBuffer, - IN UINT64 NewPe32BaseAddress - ) -/*++ - -Routine Description: - - Set new base address into PeImage, and fix up PeImage based on new address. - -Arguments: - - FileName - Name of file - FileBuffer - Pointer to PeImage. - NewPe32BaseAddress - New Base Address for PE image. - -Returns: - - EFI_INVALID_PARAMETER - BaseAddress is not valid. - EFI_SUCCESS - Update PeImage is correctly. - ---*/ -{ - EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - UINTN Index; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - UINT8 *MemoryImagePointer; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - - // - // Initialize context - // - memset (&ImageContext, 0, sizeof (ImageContext)); - ImageContext.Handle = (VOID *) FileBuffer; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead; - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName); - return Status; - } - - if (ImageContext.RelocationsStripped) { - Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName); - return Status; - } - - // - // Get PeHeader pointer - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset); - - // - // Load and Relocate Image Data - // - MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); - if (MemoryImagePointer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); - return EFI_OUT_OF_RESOURCES; - } - memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); - ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1)); - - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName); - free ((VOID *) MemoryImagePointer); - return Status; - } - - ImageContext.DestinationAddress = NewPe32BaseAddress; - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName); - free ((VOID *) MemoryImagePointer); - return Status; - } - - // - // Copy Relocated data to raw image file. - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN) ImgHdr + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - - for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - CopyMem ( - FileBuffer + SectionHeader->PointerToRawData, - (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), - SectionHeader->SizeOfRawData < SectionHeader->Misc.VirtualSize ? SectionHeader->SizeOfRawData : SectionHeader->Misc.VirtualSize - ); - } - - free ((VOID *) MemoryImagePointer); - - // - // Update Image Base Address - // - if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress; - } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress; - } else { - Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s", - ImgHdr->Pe32.OptionalHeader.Magic, - FileName - ); - return EFI_ABORTED; - } - - // - // Set new base address into section header - // - Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress); - - return Status; -} - -int -main ( - int argc, - char *argv[] - ) -/*++ - -Routine Description: - - Main function. - -Arguments: - - argc - Number of command line parameters. - argv - Array of pointers to command line parameter strings. - -Returns: - STATUS_SUCCESS - Utility exits successfully. - STATUS_ERROR - Some error occurred during execution. - ---*/ -{ - UINT32 Type; - UINT32 InputFileNum; - CHAR8 **InputFileName; - char *OutImageName; - char *ModuleType; - CHAR8 *TimeStamp; - FILE *fpIn; - FILE *fpOut; - FILE *fpInOut; - UINT32 Data; - UINT32 *DataPointer; - UINT32 *OldDataPointer; - UINT32 CheckSum; - UINT32 Index; - UINT32 Index1; - UINT32 Index2; - UINT64 Temp64; - UINT32 MciAlignment; - UINT8 MciPadValue; - UINT32 AllignedRelocSize; - UINT8 *FileBuffer; - UINT32 FileLength; - UINT8 *OutputFileBuffer; - UINT32 OutputFileLength; - UINT8 *InputFileBuffer; - UINT32 InputFileLength; - RUNTIME_FUNCTION *RuntimeFunction; - UNWIND_INFO *UnwindInfo; - STATUS Status; - BOOLEAN ReplaceFlag; - BOOLEAN KeepExceptionTableFlag; - BOOLEAN KeepOptionalHeaderFlag; - BOOLEAN KeepZeroPendingFlag; - UINT64 LogLevel; - EFI_TE_IMAGE_HEADER TEImageHeader; - EFI_TE_IMAGE_HEADER *TeHdr; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr; - EFI_IMAGE_OPTIONAL_HEADER32 *Optional32; - EFI_IMAGE_OPTIONAL_HEADER64 *Optional64; - EFI_IMAGE_DOS_HEADER BackupDosHdr; - MICROCODE_IMAGE_HEADER *MciHeader; - UINT8 *HiiPackageListBuffer; - UINT8 *HiiPackageDataPointer; - EFI_GUID HiiPackageListGuid; - EFI_HII_PACKAGE_LIST_HEADER HiiPackageListHeader; - EFI_HII_PACKAGE_HEADER HiiPackageHeader; - EFI_IFR_FORM_SET IfrFormSet; - UINT8 NumberOfFormPackage; - EFI_HII_PACKAGE_HEADER EndPackage; - UINT32 HiiSectionHeaderSize; - UINT8 *HiiSectionHeader; - UINT64 NewBaseAddress; - BOOLEAN NegativeAddr; - FILE *ReportFile; - CHAR8 *ReportFileName; - UINTN FileLen; - time_t InputFileTime; - time_t OutputFileTime; - struct stat Stat_Buf; - BOOLEAN ZeroDebugFlag; - - SetUtilityName (UTILITY_NAME); - - // - // Assign to fix compile warning - // - FileLen = 0; - InputFileNum = 0; - InputFileName = NULL; - mInImageName = NULL; - OutImageName = NULL; - ModuleType = NULL; - Type = 0; - Status = STATUS_SUCCESS; - FileBuffer = NULL; - fpIn = NULL; - fpOut = NULL; - fpInOut = NULL; - TimeStamp = NULL; - MciAlignment = DEFAULT_MC_ALIGNMENT; - MciPadValue = DEFAULT_MC_PAD_BYTE_VALUE; - FileLength = 0; - MciHeader = NULL; - CheckSum = 0; - ReplaceFlag = FALSE; - LogLevel = 0; - OutputFileBuffer = NULL; - OutputFileLength = 0; - InputFileBuffer = NULL; - InputFileLength = 0; - Optional32 = NULL; - Optional64 = NULL; - KeepExceptionTableFlag = FALSE; - KeepOptionalHeaderFlag = FALSE; - KeepZeroPendingFlag = FALSE; - NumberOfFormPackage = 0; - HiiPackageListBuffer = NULL; - HiiPackageDataPointer = NULL; - EndPackage.Length = sizeof (EFI_HII_PACKAGE_HEADER); - EndPackage.Type = EFI_HII_PACKAGE_END; - memset (&HiiPackageListGuid, 0, sizeof (HiiPackageListGuid)); - HiiSectionHeaderSize = 0; - HiiSectionHeader = NULL; - NewBaseAddress = 0; - NegativeAddr = FALSE; - InputFileTime = 0; - OutputFileTime = 0; - ZeroDebugFlag = FALSE; - - if (argc == 1) { - Error (NULL, 0, 1001, "Missing options", "No input options."); - Usage (); - return STATUS_ERROR; - } - - argc --; - argv ++; - - if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) { - Version (); - Usage (); - return STATUS_SUCCESS; - } - - if (stricmp (argv[0], "--version") == 0) { - Version (); - return STATUS_SUCCESS; - } - - while (argc > 0) { - if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) { - if (argv[1] == NULL || argv[1][0] == '-') { - Error (NULL, 0, 1003, "Invalid option value", "Output file name is missing for -o option"); - goto Finish; - } - OutImageName = argv[1]; - argc -= 2; - argv += 2; - continue; - } - - if ((stricmp (argv[0], "-e") == 0) || (stricmp (argv[0], "--efiImage") == 0)) { - if (argv[1] == NULL || argv[1][0] == '-') { - Error (NULL, 0, 1003, "Invalid option value", "Module Type is missing for -o option"); - goto Finish; - } - ModuleType = argv[1]; - if (mOutImageType == FW_ZERO_DEBUG_IMAGE) { - ZeroDebugFlag = TRUE; - } - if (mOutImageType != FW_TE_IMAGE) { - mOutImageType = FW_EFI_IMAGE; - } - argc -= 2; - argv += 2; - continue; - } - - if ((stricmp (argv[0], "-l") == 0) || (stricmp (argv[0], "--stripped") == 0)) { - mOutImageType = FW_RELOC_STRIPEED_IMAGE; - argc --; - argv ++; - continue; - } - - if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--acpi") == 0)) { - mOutImageType = FW_ACPI_IMAGE; - argc --; - argv ++; - continue; - } - - if ((stricmp (argv[0], "-t") == 0) || (stricmp (argv[0], "--terse") == 0)) { - if (mOutImageType == FW_ZERO_DEBUG_IMAGE) { - ZeroDebugFlag = TRUE; - } - mOutImageType = FW_TE_IMAGE; - argc --; - argv ++; - continue; - } - - if ((stricmp (argv[0], "-u") == 0) || (stricmp (argv[0], "--dump") == 0)) { - mOutImageType = DUMP_TE_HEADER; - argc --; - argv ++; - continue; - } - - if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--exe2bin") == 0)) { - mOutImageType = FW_BIN_IMAGE; - argc --; - argv ++; - continue; - } - - if ((stricmp (argv[0], "-z") == 0) || (stricmp (argv[0], "--zero") == 0)) { - if (mOutImageType == FW_DUMMY_IMAGE) { - mOutImageType = FW_ZERO_DEBUG_IMAGE; - } - if (mOutImageType == FW_TE_IMAGE || mOutImageType == FW_EFI_IMAGE) { - ZeroDebugFlag = TRUE; - } - argc --; - argv ++; - continue; - } - - if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--stamp") == 0)) { - mOutImageType = FW_SET_STAMP_IMAGE; - if (argv[1] == NULL || argv[1][0] == '-') { - Error (NULL, 0, 1003, "Invalid option value", "time stamp is missing for -s option"); - goto Finish; - } - TimeStamp = argv[1]; - argc -= 2; - argv += 2; - continue; - } - - if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--replace") == 0)) { - ReplaceFlag = TRUE; - argc --; - argv ++; - continue; - } - - if (stricmp (argv[0], "--keepexceptiontable") == 0) { - KeepExceptionTableFlag = TRUE; - argc --; - argv ++; - continue; - } - - if (stricmp(argv[0], "--keepoptionalheader") == 0) { - KeepOptionalHeaderFlag = TRUE; - argc--; - argv++; - continue; - } - - if (stricmp (argv[0], "--keepzeropending") == 0) { - KeepZeroPendingFlag = TRUE; - argc --; - argv ++; - continue; - } - - if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--mcifile") == 0)) { - mOutImageType = FW_MCI_IMAGE; - argc --; - argv ++; - continue; - } - - if ((stricmp (argv[0], "-j") == 0) || (stricmp (argv[0], "--join") == 0)) { - mOutImageType = FW_MERGE_IMAGE; - argc --; - argv ++; - continue; - } - - if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--align") == 0)) { - if (AsciiStringToUint64 (argv[1], FALSE, &Temp64) != EFI_SUCCESS) { - Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]); - goto Finish; - } - MciAlignment = (UINT32) Temp64; - argc -= 2; - argv += 2; - continue; - } - - if ((stricmp (argv[0], "--rebase") == 0)) { - if (argv[1][0] == '-') { - NegativeAddr = TRUE; - Status = AsciiStringToUint64 (argv[1] + 1, FALSE, &Temp64); - } else { - NegativeAddr = FALSE; - Status = AsciiStringToUint64 (argv[1], FALSE, &Temp64); - } - if (Status != EFI_SUCCESS) { - Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]); - goto Finish; - } - mOutImageType = FW_REBASE_IMAGE; - NewBaseAddress = (UINT64) Temp64; - argc -= 2; - argv += 2; - continue; - } - - if ((stricmp (argv[0], "--address") == 0)) { - if (argv[1][0] == '-') { - NegativeAddr = TRUE; - Status = AsciiStringToUint64 (argv[1] + 1, FALSE, &Temp64); - } else { - NegativeAddr = FALSE; - Status = AsciiStringToUint64 (argv[1], FALSE, &Temp64); - } - if (Status != EFI_SUCCESS) { - Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]); - goto Finish; - } - mOutImageType = FW_SET_ADDRESS_IMAGE; - NewBaseAddress = (UINT64) Temp64; - argc -= 2; - argv += 2; - continue; - } - - if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--pad") == 0)) { - if (AsciiStringToUint64 (argv[1], FALSE, &Temp64) != EFI_SUCCESS) { - Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]); - goto Finish; - } - MciPadValue = (UINT8) Temp64; - argc -= 2; - argv += 2; - continue; - } - - if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) { - SetPrintLevel (VERBOSE_LOG_LEVEL); - VerboseMsg ("Verbose output Mode Set!"); - argc --; - argv ++; - continue; - } - - if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) { - SetPrintLevel (KEY_LOG_LEVEL); - KeyMsg ("Quiet output Mode Set!"); - argc --; - argv ++; - continue; - } - - if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) { - Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]); - goto Finish; - } - if (LogLevel > 9) { - Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, current input level is %d", (int) LogLevel); - goto Finish; - } - SetPrintLevel (LogLevel); - DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]); - argc -= 2; - argv += 2; - continue; - } - - if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--hiiguid") == 0)) { - Status = StringToGuid (argv[1], &HiiPackageListGuid); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]); - goto Finish; - } - argc -= 2; - argv += 2; - continue; - } - - if (stricmp (argv[0], "--hiipackage") == 0) { - mOutImageType = FW_HII_PACKAGE_LIST_RCIMAGE; - argc --; - argv ++; - continue; - } - - if (stricmp (argv[0], "--hiibinpackage") == 0) { - mOutImageType = FW_HII_PACKAGE_LIST_BINIMAGE; - argc --; - argv ++; - continue; - } - - if (stricmp (argv[0], "--prm") == 0) { - if (stricmp (ModuleType, "DXE_RUNTIME_DRIVER") != 0 ){ - Error (NULL, 0, 1001, "Invalid", "--prm option only supports DXE RUNTIME driver."); - goto Finish; - } - - if (!mExportFlag) { - mExportFlag = TRUE; - } - argc --; - argv ++; - continue; - } - - if (stricmp (argv[0], "--nonxcompat") == 0) { - mNoNxCompat = TRUE; - argc --; - argv ++; - continue; - } - - if (argv[0][0] == '-') { - Error (NULL, 0, 1000, "Unknown option", argv[0]); - goto Finish; - } - // - // Get Input file name - // - if ((InputFileNum == 0) && (InputFileName == NULL)) { - InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)); - if (InputFileName == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - goto Finish; - } - - memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *))); - } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) { - // - // InputFileName buffer too small, need to realloc - // - InputFileName = (CHAR8 **) realloc ( - InputFileName, - (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *) - ); - - if (InputFileName == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - goto Finish; - } - - memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *))); - } - - InputFileName [InputFileNum ++] = argv[0]; - argc --; - argv ++; - } - - VerboseMsg ("%s tool start.", UTILITY_NAME); - - if (mOutImageType == FW_DUMMY_IMAGE) { - Error (NULL, 0, 1001, "Missing option", "No create file action specified; pls specify -e, -c or -t option to create efi image, or acpi table or TeImage!"); - if (ReplaceFlag) { - Error (NULL, 0, 1001, "Missing option", "-r option is not supported as the independent option. It can be used together with other create file option specified at the above."); - } - goto Finish; - } - - // - // check input files - // - if (InputFileNum == 0) { - Error (NULL, 0, 1001, "Missing option", "Input files"); - goto Finish; - } - - // - // Combine MciBinary files to one file - // - if ((mOutImageType == FW_MERGE_IMAGE) && ReplaceFlag) { - Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with -j merge files option."); - goto Finish; - } - - // - // Combine HiiBinary packages to a single package list - // - if ((mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) && ReplaceFlag) { - Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with --hiipackage merge files option."); - goto Finish; - } - - if ((mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) && ReplaceFlag) { - Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with --hiibinpackage merge files option."); - goto Finish; - } - - // - // Input image file - // - mInImageName = InputFileName [InputFileNum - 1]; - VerboseMsg ("the input file name is %s", mInImageName); - - // - // Action will be taken for the input file. - // - switch (mOutImageType) { - case FW_EFI_IMAGE: - VerboseMsg ("Create efi image on module type %s based on the input PE image.", ModuleType); - break; - case FW_TE_IMAGE: - VerboseMsg ("Create Te Image based on the input PE image."); - break; - case FW_ACPI_IMAGE: - VerboseMsg ("Get acpi table data from the input PE image."); - break; - case FW_RELOC_STRIPEED_IMAGE: - VerboseMsg ("Remove relocation section from Pe or Te image."); - break; - case FW_BIN_IMAGE: - VerboseMsg ("Convert the input EXE to the output BIN file."); - break; - case FW_ZERO_DEBUG_IMAGE: - VerboseMsg ("Zero the Debug Data Fields and Time Stamp in input PE image."); - break; - case FW_SET_STAMP_IMAGE: - VerboseMsg ("Set new time stamp %s in the input PE image.", TimeStamp); - break; - case DUMP_TE_HEADER: - VerboseMsg ("Dump the TE header information of the input TE image."); - break; - case FW_MCI_IMAGE: - VerboseMsg ("Convert input MicroCode.txt file to MicroCode.bin file."); - break; - case FW_MERGE_IMAGE: - VerboseMsg ("Combine the input multi microcode bin files to one bin file."); - break; - case FW_HII_PACKAGE_LIST_RCIMAGE: - VerboseMsg ("Combine the input multi hii bin packages to one text package list RC file."); - break; - case FW_HII_PACKAGE_LIST_BINIMAGE: - VerboseMsg ("Combine the input multi hii bin packages to one binary package list file."); - break; - case FW_REBASE_IMAGE: - VerboseMsg ("Rebase the input image to new base address."); - break; - case FW_SET_ADDRESS_IMAGE: - VerboseMsg ("Set the preferred address into the section header of the input image"); - break; - default: - break; - } - - if (ReplaceFlag) { - VerboseMsg ("Overwrite the input file with the output content."); - } - - // - // Open output file and Write image into the output file. - // - if (OutImageName != NULL) { - fpOut = fopen (LongFilePath (OutImageName), "rb"); - if (fpOut != NULL) { - // - // Get Output file time stamp - // - fstat(fileno (fpOut), &Stat_Buf); - OutputFileTime = Stat_Buf.st_mtime; - // - // Get Output file data - // - OutputFileLength = _filelength (fileno (fpOut)); - OutputFileBuffer = malloc (OutputFileLength); - if (OutputFileBuffer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - fclose (fpOut); - fpOut = NULL; - goto Finish; - } - fread (OutputFileBuffer, 1, OutputFileLength, fpOut); - fclose (fpOut); - fpOut = NULL; - } - VerboseMsg ("Output file name is %s", OutImageName); - } else if (!ReplaceFlag && mOutImageType != DUMP_TE_HEADER) { - Error (NULL, 0, 1001, "Missing option", "output file"); - goto Finish; - } - - // - // Open input file and read file data into file buffer. - // - fpIn = fopen (LongFilePath (mInImageName), "rb"); - if (fpIn == NULL) { - Error (NULL, 0, 0001, "Error opening file", mInImageName); - goto Finish; - } - // - // Get Iutput file time stamp - // - fstat(fileno (fpIn), &Stat_Buf); - InputFileTime = Stat_Buf.st_mtime; - // - // Get Input file data - // - InputFileLength = _filelength (fileno (fpIn)); - InputFileBuffer = malloc (InputFileLength); - if (InputFileBuffer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - fclose (fpIn); - goto Finish; - } - fread (InputFileBuffer, 1, InputFileLength, fpIn); - fclose (fpIn); - DebugMsg (NULL, 0, 9, "input file info", "the input file size is %u bytes", (unsigned) InputFileLength); - - // - // Combine multi binary HII package files. - // - if (mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE || mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) { - // - // Open output file handle. - // - fpOut = fopen (LongFilePath (OutImageName), "wb"); - if (!fpOut) { - Error (NULL, 0, 0001, "Error opening output file", OutImageName); - goto Finish; - } - // - // Get hii package list length - // - HiiPackageListHeader.PackageLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER); - for (Index = 0; Index < InputFileNum; Index ++) { - fpIn = fopen (LongFilePath (InputFileName [Index]), "rb"); - if (fpIn == NULL) { - Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]); - goto Finish; - } - FileLength = _filelength (fileno (fpIn)); - fread (&HiiPackageHeader, 1, sizeof (HiiPackageHeader), fpIn); - if (HiiPackageHeader.Type == EFI_HII_PACKAGE_FORM) { - if (HiiPackageHeader.Length != FileLength) { - Error (NULL, 0, 3000, "Invalid", "The wrong package size is in HII package file %s", InputFileName [Index]); - fclose (fpIn); - goto Finish; - } - if (memcmp (&HiiPackageListGuid, &mZeroGuid, sizeof (EFI_GUID)) == 0) { - fread (&IfrFormSet, 1, sizeof (IfrFormSet), fpIn); - memcpy (&HiiPackageListGuid, &IfrFormSet.Guid, sizeof (EFI_GUID)); - } - NumberOfFormPackage ++; - } - HiiPackageListHeader.PackageLength += FileLength; - fclose (fpIn); - } - HiiPackageListHeader.PackageLength += sizeof (EndPackage); - // - // Check whether hii packages are valid - // - if (NumberOfFormPackage > 1) { - Error (NULL, 0, 3000, "Invalid", "The input hii packages contains more than one hii form package"); - goto Finish; - } - if (memcmp (&HiiPackageListGuid, &mZeroGuid, sizeof (EFI_GUID)) == 0) { - Error (NULL, 0, 3000, "Invalid", "HII package list guid is not specified!"); - goto Finish; - } - memcpy (&HiiPackageListHeader.PackageListGuid, &HiiPackageListGuid, sizeof (EFI_GUID)); - // - // read hii packages - // - HiiPackageListBuffer = malloc (HiiPackageListHeader.PackageLength); - if (HiiPackageListBuffer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - goto Finish; - } - memcpy (HiiPackageListBuffer, &HiiPackageListHeader, sizeof (HiiPackageListHeader)); - HiiPackageDataPointer = HiiPackageListBuffer + sizeof (HiiPackageListHeader); - for (Index = 0; Index < InputFileNum; Index ++) { - fpIn = fopen (LongFilePath (InputFileName [Index]), "rb"); - if (fpIn == NULL) { - Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]); - free (HiiPackageListBuffer); - goto Finish; - } - - FileLength = _filelength (fileno (fpIn)); - fread (HiiPackageDataPointer, 1, FileLength, fpIn); - fclose (fpIn); - HiiPackageDataPointer = HiiPackageDataPointer + FileLength; - } - memcpy (HiiPackageDataPointer, &EndPackage, sizeof (EndPackage)); - - // - // write the hii package into the binary package list file with the resource section header - // - if (mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) { - // - // Create the resource section header - // - HiiSectionHeader = CreateHiiResouceSectionHeader (&HiiSectionHeaderSize, HiiPackageListHeader.PackageLength); - if (HiiSectionHeader == NULL) { - free (HiiPackageListBuffer); - goto Finish; - } - // - // Wrtie section header and HiiData into File. - // - fwrite (HiiSectionHeader, 1, HiiSectionHeaderSize, fpOut); - fwrite (HiiPackageListBuffer, 1, HiiPackageListHeader.PackageLength, fpOut); - // - // Free allocated resources. - // - free (HiiSectionHeader); - free (HiiPackageListBuffer); - // - // Done successfully - // - goto Finish; - } - - // - // write the hii package into the text package list rc file. - // - if (mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) { - for (Index = 0; gHiiPackageRCFileHeader[Index] != NULL; Index++) { - fprintf (fpOut, "%s\n", gHiiPackageRCFileHeader[Index]); - } - fprintf (fpOut, "\n%d %s\n{", HII_RESOURCE_SECTION_INDEX, HII_RESOURCE_SECTION_NAME); - - HiiPackageDataPointer = HiiPackageListBuffer; - for (Index = 0; Index + 2 < HiiPackageListHeader.PackageLength; Index += 2) { - if (Index % 16 == 0) { - fprintf (fpOut, "\n "); - } - fprintf (fpOut, " 0x%04X,", *(UINT16 *) HiiPackageDataPointer); - HiiPackageDataPointer += 2; - } - - if (Index % 16 == 0) { - fprintf (fpOut, "\n "); - } - if ((Index + 2) == HiiPackageListHeader.PackageLength) { - fprintf (fpOut, " 0x%04X\n}\n", *(UINT16 *) HiiPackageDataPointer); - } - if ((Index + 1) == HiiPackageListHeader.PackageLength) { - fprintf (fpOut, " 0x%04X\n}\n", *(UINT8 *) HiiPackageDataPointer); - } - free (HiiPackageListBuffer); - // - // Done successfully - // - goto Finish; - } - } - - // - // Combine MciBinary files to one file - // - if (mOutImageType == FW_MERGE_IMAGE) { - // - // Open output file handle. - // - fpOut = fopen (LongFilePath (OutImageName), "wb"); - if (!fpOut) { - Error (NULL, 0, 0001, "Error opening output file", OutImageName); - goto Finish; - } - for (Index = 0; Index < InputFileNum; Index ++) { - fpIn = fopen (LongFilePath (InputFileName [Index]), "rb"); - if (!fpIn) { - Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]); - goto Finish; - } - - FileLength = _filelength (fileno (fpIn)); - FileBuffer = malloc (FileLength); - if (FileBuffer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - fclose (fpIn); - goto Finish; - } - - fread (FileBuffer, 1, FileLength, fpIn); - fclose (fpIn); - // - // write input file to out file - // - fwrite (FileBuffer, 1, FileLength, fpOut); - // - // write pad value to out file. - // - while (FileLength ++ % MciAlignment != 0) { - fwrite (&MciPadValue, 1, 1, fpOut); - } - // - // free allocated memory space - // - free (FileBuffer); - FileBuffer = NULL; - } - // - // Done successfully - // - goto Finish; - } - - // - // Convert MicroCode.txt file to MicroCode.bin file - // - if (mOutImageType == FW_MCI_IMAGE) { - fpIn = fopen (LongFilePath (mInImageName), "r"); - if (fpIn == NULL) { - Error (NULL, 0, 0001, "Error opening file", mInImageName); - goto Finish; - } - - // - // The first pass is to determine - // how much data is in the file so we can allocate a working buffer. - // - FileLength = 0; - do { - Status = MicrocodeReadData (fpIn, &Data); - if (Status == STATUS_SUCCESS) { - FileLength += sizeof (Data); - } - if (Status == STATUS_IGNORE) { - Status = STATUS_SUCCESS; - } - } while (Status == STATUS_SUCCESS); - // - // Error if no data. - // - if (FileLength == 0) { - Error (NULL, 0, 3000, "Invalid", "no parseable data found in file %s", mInImageName); - goto Finish; - } - if (FileLength < sizeof (MICROCODE_IMAGE_HEADER)) { - Error (NULL, 0, 3000, "Invalid", "amount of parseable data in %s is insufficient to contain a microcode header", mInImageName); - goto Finish; - } - - // - // Allocate a buffer for the data - // - FileBuffer = malloc (FileLength); - if (FileBuffer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - goto Finish; - } - // - // Re-read the file, storing the data into our buffer - // - fseek (fpIn, 0, SEEK_SET); - DataPointer = (UINT32 *) FileBuffer; - OldDataPointer = DataPointer; - do { - OldDataPointer = DataPointer; - Status = MicrocodeReadData (fpIn, DataPointer++); - if (Status == STATUS_IGNORE) { - DataPointer = OldDataPointer; - Status = STATUS_SUCCESS; - } - } while (Status == STATUS_SUCCESS); - // - // close input file after read data - // - fclose (fpIn); - - // - // Can't do much checking on the header because, per the spec, the - // DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K, - // and the TotalSize field is invalid (actually missing). Thus we can't - // even verify the Reserved fields are 0. - // - MciHeader = (MICROCODE_IMAGE_HEADER *) FileBuffer; - if (MciHeader->DataSize == 0) { - Index = 2048; - } else { - Index = MciHeader->TotalSize; - } - - if (Index != FileLength) { - Error (NULL, 0, 3000, "Invalid", "file length of %s (0x%x) does not equal expected TotalSize: 0x%04X.", mInImageName, (unsigned) FileLength, (unsigned) Index); - goto Finish; - } - - // - // Checksum the contents - // - DataPointer = (UINT32 *) FileBuffer; - CheckSum = 0; - Index = 0; - while (Index < FileLength) { - CheckSum += *DataPointer; - DataPointer ++; - Index += sizeof (*DataPointer); - } - if (CheckSum != 0) { - Error (NULL, 0, 3000, "Invalid", "checksum (0x%x) failed on file %s.", (unsigned) CheckSum, mInImageName); - goto Finish; - } - // - // Open the output file and write the buffer contents - // - VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength); - goto WriteFile; - } - - // - // Open input file and read file data into file buffer. - // - FileLength = InputFileLength; - FileBuffer = malloc (FileLength); - if (FileBuffer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - goto Finish; - } - memcpy (FileBuffer, InputFileBuffer, InputFileLength); - - // - // Dump TeImage Header into output file. - // - if (mOutImageType == DUMP_TE_HEADER) { - memcpy (&TEImageHeader, FileBuffer, sizeof (TEImageHeader)); - if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) { - Error (NULL, 0, 3000, "Invalid", "TE header signature of file %s is not correct.", mInImageName); - goto Finish; - } - // - // Open the output file handle. - // - if (ReplaceFlag) { - fpInOut = fopen (LongFilePath (mInImageName), "wb"); - if (fpInOut == NULL) { - Error (NULL, 0, 0001, "Error opening file", mInImageName); - goto Finish; - } - } else { - if (OutImageName != NULL) { - fpOut = fopen (LongFilePath (OutImageName), "wb"); - } else { - fpOut = stdout; - } - if (fpOut == NULL) { - Error (NULL, 0, 0001, "Error opening output file", OutImageName); - goto Finish; - } - } - if (fpInOut != NULL) { - fprintf (fpInOut, "Dump of file %s\n\n", mInImageName); - fprintf (fpInOut, "TE IMAGE HEADER VALUES\n"); - fprintf (fpInOut, "%17X machine\n", TEImageHeader.Machine); - fprintf (fpInOut, "%17X number of sections\n", TEImageHeader.NumberOfSections); - fprintf (fpInOut, "%17X subsystems\n", TEImageHeader.Subsystem); - fprintf (fpInOut, "%17X stripped size\n", TEImageHeader.StrippedSize); - fprintf (fpInOut, "%17X entry point\n", (unsigned) TEImageHeader.AddressOfEntryPoint); - fprintf (fpInOut, "%17X base of code\n", (unsigned) TEImageHeader.BaseOfCode); - fprintf (fpInOut, "%17llX image base\n", (unsigned long long)TEImageHeader.ImageBase); - fprintf (fpInOut, "%17X [%8X] RVA [size] of Base Relocation Directory\n", (unsigned) TEImageHeader.DataDirectory[0].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[0].Size); - fprintf (fpInOut, "%17X [%8X] RVA [size] of Debug Directory\n", (unsigned) TEImageHeader.DataDirectory[1].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[1].Size); - } - if (fpOut != NULL) { - fprintf (fpOut, "Dump of file %s\n\n", mInImageName); - fprintf (fpOut, "TE IMAGE HEADER VALUES\n"); - fprintf (fpOut, "%17X machine\n", TEImageHeader.Machine); - fprintf (fpOut, "%17X number of sections\n", TEImageHeader.NumberOfSections); - fprintf (fpOut, "%17X subsystems\n", TEImageHeader.Subsystem); - fprintf (fpOut, "%17X stripped size\n", TEImageHeader.StrippedSize); - fprintf (fpOut, "%17X entry point\n", (unsigned) TEImageHeader.AddressOfEntryPoint); - fprintf (fpOut, "%17X base of code\n", (unsigned) TEImageHeader.BaseOfCode); - fprintf (fpOut, "%17llX image base\n", (unsigned long long)TEImageHeader.ImageBase); - fprintf (fpOut, "%17X [%8X] RVA [size] of Base Relocation Directory\n", (unsigned) TEImageHeader.DataDirectory[0].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[0].Size); - fprintf (fpOut, "%17X [%8X] RVA [size] of Debug Directory\n", (unsigned) TEImageHeader.DataDirectory[1].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[1].Size); - } - goto Finish; - } - - // - // Following code to convert dll to efi image or te image. - // Get new image type - // - if ((mOutImageType == FW_EFI_IMAGE) || (mOutImageType == FW_TE_IMAGE)) { - if (ModuleType == NULL) { - if (mOutImageType == FW_EFI_IMAGE) { - Error (NULL, 0, 1001, "Missing option", "EFI_FILETYPE"); - goto Finish; - } else if (mOutImageType == FW_TE_IMAGE) { - // - // Default TE Image Type is Boot service driver - // - Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER; - VerboseMsg ("Efi Image subsystem type is efi boot service driver."); - } - } else { - if (stricmp (ModuleType, "BASE") == 0 || - stricmp (ModuleType, "SEC") == 0 || - stricmp (ModuleType, "SECURITY_CORE") == 0 || - stricmp (ModuleType, "PEI_CORE") == 0 || - stricmp (ModuleType, "PEIM") == 0 || - stricmp (ModuleType, "COMBINED_PEIM_DRIVER") == 0 || - stricmp (ModuleType, "PIC_PEIM") == 0 || - stricmp (ModuleType, "RELOCATABLE_PEIM") == 0 || - stricmp (ModuleType, "DXE_CORE") == 0 || - stricmp (ModuleType, "BS_DRIVER") == 0 || - stricmp (ModuleType, "DXE_DRIVER") == 0 || - stricmp (ModuleType, "DXE_SMM_DRIVER") == 0 || - stricmp (ModuleType, "UEFI_DRIVER") == 0 || - stricmp (ModuleType, "SMM_CORE") == 0 || - stricmp (ModuleType, "MM_STANDALONE") == 0 || - stricmp (ModuleType, "MM_CORE_STANDALONE") == 0) { - Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER; - VerboseMsg ("Efi Image subsystem type is efi boot service driver."); - - } else if (stricmp (ModuleType, "UEFI_APPLICATION") == 0 || - stricmp (ModuleType, "APPLICATION") == 0) { - Type = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION; - VerboseMsg ("Efi Image subsystem type is efi application."); - - } else if (stricmp (ModuleType, "DXE_RUNTIME_DRIVER") == 0 || - stricmp (ModuleType, "RT_DRIVER") == 0) { - Type = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER; - VerboseMsg ("Efi Image subsystem type is efi runtime driver."); - - } else if (stricmp (ModuleType, "DXE_SAL_DRIVER") == 0 || - stricmp (ModuleType, "SAL_RT_DRIVER") == 0) { - Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER; - VerboseMsg ("Efi Image subsystem type is efi sal runtime driver."); - - } else { - Error (NULL, 0, 1003, "Invalid option value", "EFI_FILETYPE = %s", ModuleType); - goto Finish; - } - } - } - - // - // Convert ELF image to PeImage - // - if (IsElfHeader(FileBuffer)) { - VerboseMsg ("Convert %s from ELF to PE/COFF.", mInImageName); - if (!ConvertElf(&FileBuffer, &FileLength)) { - Error (NULL, 0, 3000, "Invalid", "Unable to convert %s from ELF to PE/COFF.", mInImageName); - goto Finish; - } - } - - // - // Make sure File Offsets and Virtual Offsets are the same in the image so it is XIP - // XIP == eXecute In Place - // - PeCoffConvertImageToXip (&FileBuffer, &FileLength); - - // - // Remove reloc section from PE or TE image - // - if (mOutImageType == FW_RELOC_STRIPEED_IMAGE) { - // - // Check TeImage - // - TeHdr = (EFI_TE_IMAGE_HEADER *) FileBuffer; - if (TeHdr->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TeHdr + 1); - for (Index = 0; Index < TeHdr->NumberOfSections; Index ++, SectionHeader ++) { - if (strcmp ((char *)SectionHeader->Name, ".reloc") == 0) { - // - // Check the reloc section is in the end of image. - // - if ((SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData) == - (FileLength + TeHdr->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER))) { - // - // Remove .reloc section and update TeImage Header - // - FileLength = FileLength - SectionHeader->SizeOfRawData; - SectionHeader->SizeOfRawData = 0; - SectionHeader->Misc.VirtualSize = 0; - TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0; - TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0; - break; - } - } - } - } else { - // - // Check PE Image - // - DosHdr = (EFI_IMAGE_DOS_HEADER *) FileBuffer; - if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer); - if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { - Error (NULL, 0, 3000, "Invalid", "TE and DOS header signatures were not found in %s image.", mInImageName); - goto Finish; - } - DosHdr = NULL; - } else { - PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + DosHdr->e_lfanew); - if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { - Error (NULL, 0, 3000, "Invalid", "PE header signature was not found in %s image.", mInImageName); - goto Finish; - } - } - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - if (strcmp ((char *)SectionHeader->Name, ".reloc") == 0) { - // - // Check the reloc section is in the end of image. - // - if ((SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData) == FileLength) { - // - // Remove .reloc section and update PeImage Header - // - FileLength = FileLength - SectionHeader->SizeOfRawData; - - PeHdr->Pe32.FileHeader.Characteristics |= EFI_IMAGE_FILE_RELOCS_STRIPPED; - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader; - Optional32->SizeOfImage -= SectionHeader->SizeOfRawData; - Optional32->SizeOfInitializedData -= SectionHeader->SizeOfRawData; - if (Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0; - Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0; - } - } - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader; - Optional64->SizeOfImage -= SectionHeader->SizeOfRawData; - Optional64->SizeOfInitializedData -= SectionHeader->SizeOfRawData; - if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0; - Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0; - } - } - SectionHeader->Misc.VirtualSize = 0; - SectionHeader->SizeOfRawData = 0; - break; - } - } - } - } - // - // Write file - // - goto WriteFile; - } - // - // Read the dos & pe hdrs of the image - // - DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer; - if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - // NO DOS header, check for PE/COFF header - PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer); - if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { - Error (NULL, 0, 3000, "Invalid", "DOS header signature was not found in %s image.", mInImageName); - goto Finish; - } - DosHdr = NULL; - } else { - - PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + DosHdr->e_lfanew); - if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { - Error (NULL, 0, 3000, "Invalid", "PE header signature was not found in %s image.", mInImageName); - goto Finish; - } - } - - // - // Set new base address into image - // - if (mOutImageType == FW_REBASE_IMAGE || mOutImageType == FW_SET_ADDRESS_IMAGE) { - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - if (NewBaseAddress >= 0x100000000ULL) { - Error (NULL, 0, 3000, "Invalid", "New base address is larger than 4G for 32bit PE image"); - goto Finish; - } - } - - if (NegativeAddr) { - // - // Set Base Address to a negative value. - // - NewBaseAddress = (UINT64) (0 - NewBaseAddress); - } - if (mOutImageType == FW_REBASE_IMAGE) { - Status = RebaseImage (mInImageName, FileBuffer, NewBaseAddress); - } else { - Status = SetAddressToSectionHeader (mInImageName, FileBuffer, NewBaseAddress); - } - if (EFI_ERROR (Status)) { - if (NegativeAddr) { - Error (NULL, 0, 3000, "Invalid", "Rebase/Set Image %s to Base address -0x%llx can't success", mInImageName, 0 - NewBaseAddress); - } else { - Error (NULL, 0, 3000, "Invalid", "Rebase/Set Image %s to Base address 0x%llx can't success", mInImageName, NewBaseAddress); - } - goto Finish; - } - - // - // Write file - // - goto WriteFile; - } - - // - // Extract bin data from Pe image. - // - if (mOutImageType == FW_BIN_IMAGE) { - if (FileLength < PeHdr->Pe32.OptionalHeader.SizeOfHeaders) { - Error (NULL, 0, 3000, "Invalid", "FileSize of %s is not a legal size.", mInImageName); - goto Finish; - } - // - // Output bin data from exe file - // - FileLength = FileLength - PeHdr->Pe32.OptionalHeader.SizeOfHeaders; - memmove (FileBuffer, FileBuffer + PeHdr->Pe32.OptionalHeader.SizeOfHeaders, FileLength); - VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength); - goto WriteFile; - } - - // - // Zero Debug Information of Pe Image - // - if (mOutImageType == FW_ZERO_DEBUG_IMAGE) { - Status = ZeroDebugData (FileBuffer, TRUE); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "Zero DebugData Error status is 0x%x", (int) Status); - goto Finish; - } - - // - // Write the updated Image - // - VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength); - goto WriteFile; - } - - // - // Set Time Stamp of Pe Image - // - if (mOutImageType == FW_SET_STAMP_IMAGE) { - Status = SetStamp (FileBuffer, TimeStamp); - if (EFI_ERROR (Status)) { - goto Finish; - } - - // - // Write the updated Image - // - VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength); - goto WriteFile; - } - - // - // Extract acpi data from pe image. - // - if (mOutImageType == FW_ACPI_IMAGE) { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - if (strcmp ((char *)SectionHeader->Name, ".data") == 0 || strcmp ((char *)SectionHeader->Name, ".sdata") == 0) { - // - // Check Acpi Table - // - if (SectionHeader->Misc.VirtualSize < SectionHeader->SizeOfRawData) { - FileLength = SectionHeader->Misc.VirtualSize; - } else { - FileLength = SectionHeader->SizeOfRawData; - } - - if (CheckAcpiTable (FileBuffer + SectionHeader->PointerToRawData, FileLength) != STATUS_SUCCESS) { - Error (NULL, 0, 3000, "Invalid", "ACPI table check failed in %s.", mInImageName); - goto Finish; - } - - // - // Output Apci data to file - // - memmove (FileBuffer, FileBuffer + SectionHeader->PointerToRawData, FileLength); - VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength); - goto WriteFile; - } - } - Error (NULL, 0, 3000, "Invalid", "failed to get ACPI table from %s.", mInImageName); - goto Finish; - } - // - // Zero all unused fields of the DOS header - // - if (DosHdr != NULL) { - memcpy (&BackupDosHdr, DosHdr, sizeof (EFI_IMAGE_DOS_HEADER)); - memset (DosHdr, 0, sizeof (EFI_IMAGE_DOS_HEADER)); - DosHdr->e_magic = BackupDosHdr.e_magic; - DosHdr->e_lfanew = BackupDosHdr.e_lfanew; - - for (Index = sizeof (EFI_IMAGE_DOS_HEADER); Index < (UINT32 ) DosHdr->e_lfanew; Index++) { - FileBuffer[Index] = (UINT8) DosHdr->e_cp; - } - } - - // - // Initialize TeImage Header - // - memset (&TEImageHeader, 0, sizeof (EFI_TE_IMAGE_HEADER)); - TEImageHeader.Signature = EFI_TE_IMAGE_HEADER_SIGNATURE; - TEImageHeader.Machine = PeHdr->Pe32.FileHeader.Machine; - TEImageHeader.NumberOfSections = (UINT8) PeHdr->Pe32.FileHeader.NumberOfSections; - TEImageHeader.StrippedSize = (UINT16) ((UINTN) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader) - (UINTN) FileBuffer); - TEImageHeader.Subsystem = (UINT8) Type; - - // - // Patch the PE header - // - PeHdr->Pe32.OptionalHeader.Subsystem = (UINT16) Type; - - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader; - if (!KeepOptionalHeaderFlag) { - Optional32->MajorOperatingSystemVersion = 0; - Optional32->MinorOperatingSystemVersion = 0; - Optional32->MajorImageVersion = 0; - Optional32->MinorImageVersion = 0; - Optional32->MajorSubsystemVersion = 0; - Optional32->MinorSubsystemVersion = 0; - Optional32->Win32VersionValue = 0; - Optional32->CheckSum = 0; - Optional32->SizeOfStackReserve = 0; - Optional32->SizeOfStackCommit = 0; - Optional32->SizeOfHeapReserve = 0; - Optional32->SizeOfHeapCommit = 0; - } - TEImageHeader.AddressOfEntryPoint = Optional32->AddressOfEntryPoint; - TEImageHeader.BaseOfCode = Optional32->BaseOfCode; - TEImageHeader.ImageBase = (UINT64) (Optional32->ImageBase); - - if (Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; - } - - if (Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; - } - - // - // Zero .pdata section data. - // - if (!KeepExceptionTableFlag && Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION && - Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 && - Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) { - if (SectionHeader->VirtualAddress == Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) { - // - // Zero .pdata Section data - // - memset (FileBuffer + SectionHeader->PointerToRawData, 0, SectionHeader->SizeOfRawData); - // - // Zero .pdata Section header name - // - memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name)); - // - // Zero Exception Table - // - Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0; - Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0; - DebugMsg (NULL, 0, 9, "Zero the .pdata section for PE image", NULL); - break; - } - } - } - - // - // Strip zero padding at the end of the .reloc section - // - if (!KeepZeroPendingFlag && Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - if (Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0) { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) { - // - // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory - // - if (SectionHeader->VirtualAddress == Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) { - SectionHeader->Misc.VirtualSize = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; - AllignedRelocSize = (Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size + Optional32->FileAlignment - 1) & (~(Optional32->FileAlignment - 1)); - // - // Check to see if there is zero padding at the end of the base relocations - // - if (AllignedRelocSize < SectionHeader->SizeOfRawData) { - // - // Check to see if the base relocations are at the end of the file - // - if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional32->SizeOfImage) { - // - // All the required conditions are met to strip the zero padding of the end of the base relocations section - // - Optional32->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize); - Optional32->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize); - SectionHeader->SizeOfRawData = AllignedRelocSize; - FileLength = Optional32->SizeOfImage; - DebugMsg (NULL, 0, 9, "Remove the zero padding bytes at the end of the base relocations", "The size of padding bytes is %u", (unsigned) (SectionHeader->SizeOfRawData - AllignedRelocSize)); - } - } - } - } - } - } - } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader; - if (!KeepOptionalHeaderFlag) { - Optional64->MajorOperatingSystemVersion = 0; - Optional64->MinorOperatingSystemVersion = 0; - Optional64->MajorImageVersion = 0; - Optional64->MinorImageVersion = 0; - Optional64->MajorSubsystemVersion = 0; - Optional64->MinorSubsystemVersion = 0; - Optional64->Win32VersionValue = 0; - Optional64->CheckSum = 0; - Optional64->SizeOfStackReserve = 0; - Optional64->SizeOfStackCommit = 0; - Optional64->SizeOfHeapReserve = 0; - Optional64->SizeOfHeapCommit = 0; - } - TEImageHeader.AddressOfEntryPoint = Optional64->AddressOfEntryPoint; - TEImageHeader.BaseOfCode = Optional64->BaseOfCode; - TEImageHeader.ImageBase = (UINT64) (Optional64->ImageBase); - - // Set NxCompat flag - if (IsNxCompatCompliant (PeHdr) && !mNoNxCompat) { - Optional64->DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_NX_COMPAT; - } - - if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; - } - - if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; - } - - // - // Zero the .pdata section for X64 machine and don't check the Debug Directory is empty - // For Itaninum and X64 Image, remove .pdata section. - // - if ((!KeepExceptionTableFlag && PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_X64)) { - if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION && - Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 && - Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) { - if (SectionHeader->VirtualAddress == Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) { - // - // Zero .pdata Section header name - // - memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name)); - - RuntimeFunction = (RUNTIME_FUNCTION *)(FileBuffer + SectionHeader->PointerToRawData); - for (Index1 = 0; Index1 < Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size / sizeof (RUNTIME_FUNCTION); Index1++, RuntimeFunction++) { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader); - for (Index2 = 0; Index2 < PeHdr->Pe32.FileHeader.NumberOfSections; Index2++, SectionHeader++) { - if (RuntimeFunction->UnwindInfoAddress >= SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) { - UnwindInfo = (UNWIND_INFO *)(FileBuffer + SectionHeader->PointerToRawData + (RuntimeFunction->UnwindInfoAddress - SectionHeader->VirtualAddress)); - if (UnwindInfo->Version == 1) { - memset (UnwindInfo + 1, 0, UnwindInfo->CountOfUnwindCodes * sizeof (UINT16)); - memset (UnwindInfo, 0, sizeof (UNWIND_INFO)); - } - break; - } - } - memset (RuntimeFunction, 0, sizeof (RUNTIME_FUNCTION)); - } - // - // Zero Exception Table - // - Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0; - Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0; - DebugMsg (NULL, 0, 9, "Zero the .pdata section if the machine type is X64 for PE32+ image", NULL); - break; - } - } - } - } - - // - // Strip zero padding at the end of the .reloc section - // - if (!KeepZeroPendingFlag && Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { - if (Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0) { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) { - // - // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory - // - if (SectionHeader->VirtualAddress == Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) { - SectionHeader->Misc.VirtualSize = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; - AllignedRelocSize = (Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size + Optional64->FileAlignment - 1) & (~(Optional64->FileAlignment - 1)); - // - // Check to see if there is zero padding at the end of the base relocations - // - if (AllignedRelocSize < SectionHeader->SizeOfRawData) { - // - // Check to see if the base relocations are at the end of the file - // - if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional64->SizeOfImage) { - // - // All the required conditions are met to strip the zero padding of the end of the base relocations section - // - Optional64->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize); - Optional64->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize); - SectionHeader->SizeOfRawData = AllignedRelocSize; - FileLength = Optional64->SizeOfImage; - DebugMsg (NULL, 0, 9, "Remove the zero padding bytes at the end of the base relocations", "The size of padding bytes is %u", (unsigned) (SectionHeader->SizeOfRawData - AllignedRelocSize)); - } - } - } - } - } - } - } else { - Error (NULL, 0, 3000, "Invalid", "Magic 0x%x of PeImage %s is unknown.", PeHdr->Pe32.OptionalHeader.Magic, mInImageName); - goto Finish; - } - - if (((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) == 0) && \ - (TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress == 0) && \ - (TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size == 0)) { - // - // PeImage can be loaded into memory, but it has no relocation section. - // Fix TeImage Header to set VA of relocation data directory to not zero, the size is still zero. - // - if (Optional32 != NULL) { - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional32->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION); - } else if (Optional64 != NULL) { - TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional64->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION); - } - } - - // - // Fill HII section data - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) { - if (stricmp ((char *)SectionHeader[Index].Name, ".hii") == 0) { - // - // Update resource section header offset - // - SetHiiResourceHeader ((UINT8*) FileBuffer + SectionHeader[Index].PointerToRawData, SectionHeader[Index].VirtualAddress); - // - // Update resource section name - // - strcpy((char *) SectionHeader[Index].Name, ".rsrc"); - // - // Update resource data directory. - // - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader; - Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress; - Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize; - } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader; - Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress; - Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize; - } - break; - } - } - - // - // Zero ExceptionTable Xdata - // - if (!KeepExceptionTableFlag) { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader); - for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) { - if (stricmp ((char *)SectionHeader[Index].Name, ".xdata") == 0) { - // - // zero .xdata section - // - memset (FileBuffer + SectionHeader[Index].PointerToRawData, 0, SectionHeader[Index].SizeOfRawData); - DebugMsg (NULL, 0, 9, NULL, "Zero the .xdata section for PE image at Offset 0x%x and Length 0x%x", (unsigned) SectionHeader[Index].PointerToRawData, (unsigned) SectionHeader[Index].SizeOfRawData); - break; - } - } - } - - // - // Zero Time/Data field - // - ZeroDebugData (FileBuffer, ZeroDebugFlag); - - if (mOutImageType == FW_TE_IMAGE) { - if ((PeHdr->Pe32.FileHeader.NumberOfSections &~0xFF) || (Type &~0xFF)) { - // - // Pack the subsystem and NumberOfSections into 1 byte. Make sure they fit both. - // - Error (NULL, 0, 3000, "Invalid", "Image's subsystem or NumberOfSections of PeImage %s cannot be packed into 1 byte.", mInImageName); - goto Finish; - } - - if ((PeHdr->Pe32.OptionalHeader.SectionAlignment != PeHdr->Pe32.OptionalHeader.FileAlignment)) { - // - // TeImage has the same section alignment and file alignment. - // - Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment of PeImage %s do not match, they must be equal for a TeImage.", mInImageName); - goto Finish; - } - - DebugMsg (NULL, 0, 9, "TeImage Header Info", "Machine type is %X, Number of sections is %X, Stripped size is %X, EntryPoint is %X, BaseOfCode is %X, ImageBase is %llX", - TEImageHeader.Machine, TEImageHeader.NumberOfSections, TEImageHeader.StrippedSize, (unsigned) TEImageHeader.AddressOfEntryPoint, (unsigned) TEImageHeader.BaseOfCode, (unsigned long long) TEImageHeader.ImageBase); - // - // Update Image to TeImage - // - FileLength = FileLength - TEImageHeader.StrippedSize; - memmove (FileBuffer + sizeof (EFI_TE_IMAGE_HEADER), FileBuffer + TEImageHeader.StrippedSize, FileLength); - FileLength = FileLength + sizeof (EFI_TE_IMAGE_HEADER); - memcpy (FileBuffer, &TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER)); - VerboseMsg ("the size of output file is %u bytes", (unsigned) (FileLength)); - } else { - - // - // Following codes are to fix the objcopy's issue: - // objcopy in binutil 2.50.18 will set PE image's charactices to "RELOC_STRIPPED" if image has no ".reloc" section - // It cause issue for EFI image which has no ".reloc" sections. - // Following codes will be removed when objcopy in binutil fix this problem for PE image. - // - if ((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0) { - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader; - if (Optional32->ImageBase == 0) { - PeHdr->Pe32.FileHeader.Characteristics &= ~EFI_IMAGE_FILE_RELOCS_STRIPPED; - } - } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader; - if (Optional64->ImageBase == 0) { - PeHdr->Pe32.FileHeader.Characteristics &= ~EFI_IMAGE_FILE_RELOCS_STRIPPED; - } - } - } - } - -WriteFile: - // - // Update Image to EfiImage or TE image - // - if (ReplaceFlag) { - if ((FileLength != InputFileLength) || (memcmp (FileBuffer, InputFileBuffer, FileLength) != 0)) { - // - // Update File when File is changed. - // - fpInOut = fopen (LongFilePath (mInImageName), "wb"); - if (fpInOut == NULL) { - Error (NULL, 0, 0001, "Error opening file", mInImageName); - goto Finish; - } - fwrite (FileBuffer, 1, FileLength, fpInOut); - VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength); - } - } else { - if ((OutputFileTime < InputFileTime) || (FileLength != OutputFileLength) || (memcmp (FileBuffer, OutputFileBuffer, FileLength) != 0)) { - // - // Update File when File is changed or File is old. - // - fpOut = fopen (LongFilePath (OutImageName), "wb"); - if (fpOut == NULL) { - Error (NULL, 0, 0001, "Error opening output file", OutImageName); - goto Finish; - } - fwrite (FileBuffer, 1, FileLength, fpOut); - VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength); - } - } - mImageSize = FileLength; - -Finish: - if (fpInOut != NULL) { - if (GetUtilityStatus () != STATUS_SUCCESS) { - // - // when file updates failed, original file is still recovered. - // - fwrite (InputFileBuffer, 1, InputFileLength, fpInOut); - } - // - // Write converted data into fpInOut file and close input file. - // - fclose (fpInOut); - } - - if (FileBuffer != NULL) { - free (FileBuffer); - } - - if (InputFileName != NULL) { - free (InputFileName); - } - - if (fpOut != NULL) { - // - // Write converted data into fpOut file and close output file. - // - fclose (fpOut); - if (GetUtilityStatus () != STATUS_SUCCESS) { - if (OutputFileBuffer == NULL) { - remove (OutImageName); - } else { - fpOut = fopen (LongFilePath (OutImageName), "wb"); - fwrite (OutputFileBuffer, 1, OutputFileLength, fpOut); - fclose (fpOut); - } - } - } - - if (InputFileBuffer != NULL) { - free (InputFileBuffer); - } - - if (OutputFileBuffer != NULL) { - free (OutputFileBuffer); - } - - // - // Write module size and time stamp to report file. - // - if (OutImageName != NULL) { - FileLen = strlen (OutImageName); - } - if (FileLen >= 4 && strcmp (OutImageName + (FileLen - 4), ".efi") == 0) { - ReportFileName = (CHAR8 *) malloc (FileLen + 1); - if (ReportFileName != NULL) { - strcpy (ReportFileName, OutImageName); - strcpy (ReportFileName + (FileLen - 4), ".txt"); - ReportFile = fopen (LongFilePath (ReportFileName), "w+"); - if (ReportFile != NULL) { - fprintf (ReportFile, "MODULE_SIZE = %u\n", (unsigned) mImageSize); - fprintf (ReportFile, "TIME_STAMP = %u\n", (unsigned) mImageTimeStamp); - fclose(ReportFile); - } - free (ReportFileName); - } - } - VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ()); - - return GetUtilityStatus (); -} - -STATIC -EFI_STATUS -ZeroDebugData ( - IN OUT UINT8 *FileBuffer, - BOOLEAN ZeroDebugFlag - ) -/*++ - -Routine Description: - - Zero debug information in PeImage. - -Arguments: - - FileBuffer - Pointer to PeImage. - ZeroDebugFlag - TRUE to zero Debug information, FALSE to only zero time/stamp - -Returns: - - EFI_ABORTED - PeImage is invalid. - EFI_SUCCESS - Zero debug data successfully. - ---*/ -{ - UINT32 Index; - UINT32 DebugDirectoryEntryRva; - UINT32 DebugDirectoryEntrySize; - UINT32 DebugDirectoryEntryFileOffset; - UINT32 ExportDirectoryEntryRva; - UINT32 ExportDirectoryEntryFileOffset; - UINT32 ResourceDirectoryEntryRva; - UINT32 ResourceDirectoryEntryFileOffset; - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_FILE_HEADER *FileHdr; - EFI_IMAGE_OPTIONAL_HEADER32 *Optional32Hdr; - EFI_IMAGE_OPTIONAL_HEADER64 *Optional64Hdr; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; - EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY *RsdsEntry; - UINT32 *NewTimeStamp; - - // - // Init variable. - // - DebugDirectoryEntryRva = 0; - DebugDirectoryEntrySize = 0; - ExportDirectoryEntryRva = 0; - ResourceDirectoryEntryRva = 0; - DebugDirectoryEntryFileOffset = 0; - ExportDirectoryEntryFileOffset = 0; - ResourceDirectoryEntryFileOffset = 0; - DosHdr = (EFI_IMAGE_DOS_HEADER *) FileBuffer; - FileHdr = (EFI_IMAGE_FILE_HEADER *) (FileBuffer + DosHdr->e_lfanew + sizeof (UINT32)); - - - DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer; - if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - // NO DOS header, must start with PE/COFF header - FileHdr = (EFI_IMAGE_FILE_HEADER *)(FileBuffer + sizeof (UINT32)); - } else { - FileHdr = (EFI_IMAGE_FILE_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof (UINT32)); - } - - // - // Get Debug, Export and Resource EntryTable RVA address. - // Resource Directory entry need to review. - // - Optional32Hdr = (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER)); - Optional64Hdr = (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER)); - if (Optional32Hdr->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional32Hdr + FileHdr->SizeOfOptionalHeader); - if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \ - Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) { - ExportDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - } - if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && \ - Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size != 0) { - ResourceDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; - } - if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \ - Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) { - DebugDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; - DebugDirectoryEntrySize = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; - if (ZeroDebugFlag) { - Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = 0; - Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = 0; - } - } - } else { - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional64Hdr + FileHdr->SizeOfOptionalHeader); - if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \ - Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) { - ExportDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - } - if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && \ - Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size != 0) { - ResourceDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; - } - if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \ - Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) { - DebugDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; - DebugDirectoryEntrySize = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size; - if (ZeroDebugFlag) { - Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = 0; - Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = 0; - } - } - } - - // - // Get DirectoryEntryTable file offset. - // - for (Index = 0; Index < FileHdr->NumberOfSections; Index ++, SectionHeader ++) { - if (DebugDirectoryEntryRva >= SectionHeader->VirtualAddress && - DebugDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) { - DebugDirectoryEntryFileOffset = - DebugDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData; - } - if (ExportDirectoryEntryRva >= SectionHeader->VirtualAddress && - ExportDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) { - ExportDirectoryEntryFileOffset = - ExportDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData; - } - if (ResourceDirectoryEntryRva >= SectionHeader->VirtualAddress && - ResourceDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) { - ResourceDirectoryEntryFileOffset = - ResourceDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData; - } - } - - // - //Zero Debug Data and TimeStamp - // - FileHdr->TimeDateStamp = 0; - mImageTimeStamp = 0; - if (ExportDirectoryEntryFileOffset != 0) { - NewTimeStamp = (UINT32 *) (FileBuffer + ExportDirectoryEntryFileOffset + sizeof (UINT32)); - *NewTimeStamp = 0; - } - - if (ResourceDirectoryEntryFileOffset != 0) { - NewTimeStamp = (UINT32 *) (FileBuffer + ResourceDirectoryEntryFileOffset + sizeof (UINT32)); - *NewTimeStamp = 0; - } - - if (DebugDirectoryEntryFileOffset != 0) { - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (FileBuffer + DebugDirectoryEntryFileOffset); - Index = 0; - for (Index=0; Index < DebugDirectoryEntrySize / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); Index ++, DebugEntry ++) { - DebugEntry->TimeDateStamp = 0; - if (mIsConvertXip) { - DebugEntry->FileOffset = DebugEntry->RVA; - } - if ((ZeroDebugFlag || DebugEntry->Type != EFI_IMAGE_DEBUG_TYPE_CODEVIEW) && - (DebugEntry->Type != EFI_IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS)) { - memset (FileBuffer + DebugEntry->FileOffset, 0, DebugEntry->SizeOfData); - memset (DebugEntry, 0, sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)); - } - if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { - RsdsEntry = (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY *) (FileBuffer + DebugEntry->FileOffset); - if (RsdsEntry->Signature == CODEVIEW_SIGNATURE_MTOC) { - // MTOC sets DebugDirectoryEntrySize to size of the .debug section, so fix it. - if (!ZeroDebugFlag) { - if (Optional32Hdr->Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - } else { - Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - } - } - break; - } - } - } - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -SetStamp ( - IN OUT UINT8 *FileBuffer, - IN CHAR8 *TimeStamp - ) -/*++ - -Routine Description: - - Set new time stamp into PeImage FileHdr and Directory table: - Debug, Export and Resource. - -Arguments: - - FileBuffer - Pointer to PeImage. - TimeStamp - Time stamp string. - -Returns: - - EFI_INVALID_PARAMETER - TimeStamp format is not recognized. - EFI_SUCCESS - Set new time stamp in this image successfully. - ---*/ -{ - struct tm stime; - struct tm *ptime; - time_t newtime; - UINT32 Index; - UINT32 DebugDirectoryEntryRva; - UINT32 DebugDirectoryEntryFileOffset; - UINT32 ExportDirectoryEntryRva; - UINT32 ExportDirectoryEntryFileOffset; - UINT32 ResourceDirectoryEntryRva; - UINT32 ResourceDirectoryEntryFileOffset; - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_FILE_HEADER *FileHdr; - EFI_IMAGE_OPTIONAL_HEADER32 *Optional32Hdr; - EFI_IMAGE_OPTIONAL_HEADER64 *Optional64Hdr; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - UINT32 *NewTimeStamp; - - // - // Init variable. - // - DebugDirectoryEntryRva = 0; - DebugDirectoryEntryFileOffset = 0; - ExportDirectoryEntryRva = 0; - ExportDirectoryEntryFileOffset = 0; - ResourceDirectoryEntryRva = 0; - ResourceDirectoryEntryFileOffset = 0; - // - // Get time and date that will be set. - // - if (TimeStamp == NULL) { - Error (NULL, 0, 3000, "Invalid", "TimeStamp cannot be NULL."); - return EFI_INVALID_PARAMETER; - } - // - // compare the value with "NOW", if yes, current system time is set. - // - if (stricmp (TimeStamp, "NOW") == 0) { - // - // get system current time and date - // - time (&newtime); - } else { - // - // Check Time Format strictly yyyy-mm-dd 00:00:00 - // - for (Index = 0; TimeStamp[Index] != '\0' && Index < 20; Index ++) { - if (Index == 4 || Index == 7) { - if (TimeStamp[Index] == '-') { - continue; - } - } else if (Index == 13 || Index == 16) { - if (TimeStamp[Index] == ':') { - continue; - } - } else if (Index == 10 && TimeStamp[Index] == ' ') { - continue; - } else if ((TimeStamp[Index] < '0') || (TimeStamp[Index] > '9')) { - break; - } - } - - if (Index < 19 || TimeStamp[19] != '\0') { - Error (NULL, 0, 1003, "Invalid option value", "Incorrect Time \"%s\"\n Correct Format \"yyyy-mm-dd 00:00:00\"", TimeStamp); - return EFI_INVALID_PARAMETER; - } - - // - // get the date and time from TimeStamp - // - if (sscanf (TimeStamp, "%d-%d-%d %d:%d:%d", - &stime.tm_year, - &stime.tm_mon, - &stime.tm_mday, - &stime.tm_hour, - &stime.tm_min, - &stime.tm_sec - ) != 6) { - Error (NULL, 0, 1003, "Invalid option value", "Incorrect Tiem \"%s\"\n Correct Format \"yyyy-mm-dd 00:00:00\"", TimeStamp); - return EFI_INVALID_PARAMETER; - } - - // - // in struct, Month (0 - 11; Jan = 0). So decrease 1 from it - // - if (stime.tm_mon <= 0 || stime.tm_mday <=0) { - Error (NULL, 0, 3000, "Invalid", "%s Invalid date!", TimeStamp); - return EFI_INVALID_PARAMETER; - } - stime.tm_mon -= 1; - - // - // in struct, Year (current year minus 1900) - // and only the dates can be handled from Jan 1, 1970 to Jan 18, 2038 - // - // - // convert 0 -> 100 (2000), 1 -> 101 (2001), ..., 38 -> 138 (2038) - // - if (stime.tm_year >= 1970 && stime.tm_year <= 2038) { - // - // convert 1970 -> 70, 2000 -> 100, ... - // - stime.tm_year -= 1900; - } else { - Error (NULL, 0, 3000, "Invalid", "%s Invalid or unsupported datetime!", TimeStamp); - return EFI_INVALID_PARAMETER; - } - - // - // convert the date and time to time_t format - // - newtime = mktime (&stime); - if (newtime == (time_t) - 1) { - Error (NULL, 0, 3000, "Invalid", "%s Invalid or unsupported datetime!", TimeStamp); - return EFI_INVALID_PARAMETER; - } - } - - ptime = localtime (&newtime); - if (ptime != NULL) { - DebugMsg (NULL, 0, 9, "New Image Time Stamp", "%04d-%02d-%02d %02d:%02d:%02d", - ptime->tm_year + 1900, ptime->tm_mon + 1, ptime->tm_mday, ptime->tm_hour, ptime->tm_min, ptime->tm_sec); - } - // - // Set new time and data into PeImage. - // - DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer; - if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - // NO DOS header, must start with PE/COFF header - FileHdr = (EFI_IMAGE_FILE_HEADER *)(FileBuffer + sizeof (UINT32)); - } else { - FileHdr = (EFI_IMAGE_FILE_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof (UINT32)); - } - - // - // Get Debug, Export and Resource EntryTable RVA address. - // Resource Directory entry need to review. - // - if (FileHdr->Machine == IMAGE_FILE_MACHINE_I386) { - Optional32Hdr = (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER)); - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional32Hdr + FileHdr->SizeOfOptionalHeader); - if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \ - Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) { - ExportDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - } - if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && \ - Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size != 0) { - ResourceDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; - } - if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \ - Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) { - DebugDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; - } - } else { - Optional64Hdr = (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER)); - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional64Hdr + FileHdr->SizeOfOptionalHeader); - if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \ - Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) { - ExportDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - } - if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && \ - Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size != 0) { - ResourceDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; - } - if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \ - Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) { - DebugDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; - } - } - - // - // Get DirectoryEntryTable file offset. - // - for (Index = 0; Index < FileHdr->NumberOfSections; Index ++, SectionHeader ++) { - if (DebugDirectoryEntryRva >= SectionHeader->VirtualAddress && - DebugDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) { - DebugDirectoryEntryFileOffset = - DebugDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData; - } - if (ExportDirectoryEntryRva >= SectionHeader->VirtualAddress && - ExportDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) { - ExportDirectoryEntryFileOffset = - ExportDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData; - } - if (ResourceDirectoryEntryRva >= SectionHeader->VirtualAddress && - ResourceDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) { - ResourceDirectoryEntryFileOffset = - ResourceDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData; - } - } - - // - // Set new stamp - // - FileHdr->TimeDateStamp = (UINT32) newtime; - mImageTimeStamp = (UINT32) newtime; - if (ExportDirectoryEntryRva != 0) { - NewTimeStamp = (UINT32 *) (FileBuffer + ExportDirectoryEntryFileOffset + sizeof (UINT32)); - *NewTimeStamp = (UINT32) newtime; - } - - if (ResourceDirectoryEntryRva != 0) { - NewTimeStamp = (UINT32 *) (FileBuffer + ResourceDirectoryEntryFileOffset + sizeof (UINT32)); - *NewTimeStamp = (UINT32) newtime; - } - - if (DebugDirectoryEntryRva != 0) { - NewTimeStamp = (UINT32 *) (FileBuffer + DebugDirectoryEntryFileOffset + sizeof (UINT32)); - *NewTimeStamp = (UINT32) newtime; - } - - return EFI_SUCCESS; -} - -STATIC -STATUS -MicrocodeReadData ( - FILE *InFptr, - UINT32 *Data - ) -/*++ - -Routine Description: - Read a 32-bit microcode data value from a text file and convert to raw binary form. - -Arguments: - InFptr - file pointer to input text file - Data - pointer to where to return the data parsed - -Returns: - STATUS_SUCCESS - no errors or warnings, Data contains valid information - STATUS_ERROR - errors were encountered - ---*/ -{ - CHAR8 Line[MAX_LINE_LEN]; - CHAR8 *cptr; - int ScannedData = 0; - - Line[MAX_LINE_LEN - 1] = 0; - while (1) { - if (fgets (Line, MAX_LINE_LEN, InFptr) == NULL) { - return STATUS_ERROR; - } - // - // If it was a binary file, then it may have overwritten our null terminator - // - if (Line[MAX_LINE_LEN - 1] != 0) { - return STATUS_ERROR; - } - - // - // strip space - // - for (cptr = Line; *cptr && isspace((int)*cptr); cptr++) { - } - - // Skip Blank Lines and Comment Lines - if ((strlen(cptr) != 0) && (*cptr != ';')) { - break; - } - } - - // Look for - // dd 000000001h ; comment - // dd XXXXXXXX - // DD XXXXXXXXX - // DD XXXXXXXXX - // - if ((tolower((int)cptr[0]) == 'd') && (tolower((int)cptr[1]) == 'd') && isspace ((int)cptr[2])) { - // - // Skip blanks and look for a hex digit - // - cptr += 3; - for (; *cptr && isspace((int)*cptr); cptr++) { - } - if (isxdigit ((int)*cptr)) { - if (sscanf (cptr, "%X", &ScannedData) != 1) { - return STATUS_ERROR; - } - } - *Data = (UINT32) ScannedData; - return STATUS_SUCCESS; - } - - return STATUS_ERROR; -} From 21e77e0659fc70c8f34a0d267df53ba3cb9346ca Mon Sep 17 00:00:00 2001 From: vit9696 Date: Thu, 7 Aug 2025 11:49:47 +0300 Subject: [PATCH 115/341] MdeModulePkg: Fix UEFI runtime driver loading after EndOfDxe Memory Attributes Table needs to be updated to contain executable permissions for UEFI runtime drivers loaded after EndOfDxe. Fixes a regression introduced by bb248a9. Signed-off-by: Vitaly Cheptsov --- MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c index 54078c2f99..6acd6126ed 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c @@ -89,7 +89,6 @@ STATIC IMAGE_PROPERTIES_PRIVATE_DATA mImagePropertiesPrivateData = { STATIC EFI_LOCK mMemoryAttributesTableLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); BOOLEAN mMemoryAttributesTableEnable = TRUE; -BOOLEAN mMemoryAttributesTableEndOfDxe = FALSE; EFI_MEMORY_ATTRIBUTES_TABLE *mMemoryAttributesTable = NULL; BOOLEAN mMemoryAttributesTableReadyToBoot = FALSE; @@ -278,7 +277,6 @@ InstallMemoryAttributesTableOnEndOfDxe ( IN VOID *Context ) { - mMemoryAttributesTableEndOfDxe = TRUE; InstallMemoryAttributesTable (); } @@ -648,12 +646,6 @@ InsertImageRecord ( RuntimeImage = Image->RuntimeData; DEBUG ((DEBUG_VERBOSE, "InsertImageRecord - 0x%x\n", RuntimeImage)); - - if (mMemoryAttributesTableEndOfDxe) { - DEBUG ((DEBUG_INFO, "Do not insert runtime image record after EndOfDxe\n")); - return; - } - DEBUG ((DEBUG_VERBOSE, "ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount)); PdbStatus = UefiImageGetSymbolsPath (ImageContext, &PdbPointer, &PdbSize); @@ -750,11 +742,6 @@ RemoveImageRecord ( DEBUG ((DEBUG_VERBOSE, "RemoveImageRecord - 0x%x\n", RuntimeImage)); DEBUG ((DEBUG_VERBOSE, "RemoveImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize)); - if (mMemoryAttributesTableEndOfDxe) { - DEBUG ((DEBUG_INFO, "Do not remove runtime image record after EndOfDxe\n")); - return; - } - ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase); if (ImageRecord == NULL) { DEBUG ((DEBUG_ERROR, "!!!!!!!! ImageRecord not found !!!!!!!!\n")); From 926dbfc4322f5942c020bde29131396d46b4ec04 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Thu, 11 Sep 2025 14:58:14 +0300 Subject: [PATCH 116/341] OpenCorePkg: Updated with new version --- OpenCorePkg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenCorePkg b/OpenCorePkg index 35d9b3706f..d9d77331ea 160000 --- a/OpenCorePkg +++ b/OpenCorePkg @@ -1 +1 @@ -Subproject commit 35d9b3706f0772134c8e6a62b9684a699d628518 +Subproject commit d9d77331ea0683638813d3eef3f7b4c2ad7ac223 From a1bff2105f5e80ee36db3409df57125a0641856e Mon Sep 17 00:00:00 2001 From: Pavel Naberezhnev <78569117+stokescat@users.noreply.github.com> Date: Thu, 11 Sep 2025 16:41:17 +0300 Subject: [PATCH 117/341] Added UserEvent into Makefile for Windows (#77) Support for EFI Events has been added to userspace in the OpenCorePkg project. To pass CI for VS2019, the UserEvent file needs to be added to Makefiles in this commit Signed-off-by: Pavel Naberezhnev --- BaseTools/ImageTool/Makefile | 2 +- BaseTools/MicroTool/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BaseTools/ImageTool/Makefile b/BaseTools/ImageTool/Makefile index ec1dfd28d2..70e329d355 100644 --- a/BaseTools/ImageTool/Makefile +++ b/BaseTools/ImageTool/Makefile @@ -35,7 +35,7 @@ USER = $(OC_USER)\User\Library OBJECTS = $(OBJECTS) {$(BASE)}SafeString.obj String.obj SwapBytes16.obj SwapBytes32.obj CpuDeadLoop.obj CheckSum.obj QuickSort.obj LinkedList.obj OBJECTS = $(OBJECTS) {$(OUT)}DebugLib.obj {$(PRIN)}PrintLib.obj PrintLibInternal.obj {$(ERRO)}BaseDebugPrintErrorLevelLib.obj OBJECTS = $(OBJECTS) {$(UIMG)}UefiImageLib.obj UeSupport.obj PeSupport.obj CommonSupport.obj -OBJECTS = $(OBJECTS) {$(USER)}UserFile.obj UserBaseMemoryLib.obj UserMath.obj UserPcd.obj UserMisc.obj UserGlobalVar.obj UserBootServices.obj +OBJECTS = $(OBJECTS) {$(USER)}UserFile.obj UserBaseMemoryLib.obj UserMath.obj UserPcd.obj UserMisc.obj UserGlobalVar.obj UserEvent.obj UserBootServices.obj OBJECTS = $(OBJECTS) {$(BMPN)}BaseMemoryProfileLibNull.obj {$(CMEM)}CommonMemoryAllocationLib.obj {$(CMEM)}CommonMemoryAllocationLibEx.obj INC = -I . -I $(OC_USER)\User\Include -I $(OC_USER)\Include\Acidanthera diff --git a/BaseTools/MicroTool/Makefile b/BaseTools/MicroTool/Makefile index 44d23ca0de..0449fa54c4 100644 --- a/BaseTools/MicroTool/Makefile +++ b/BaseTools/MicroTool/Makefile @@ -26,7 +26,7 @@ CMEM = $(UDK_PATH)\MdeModulePkg\Library\CommonMemoryAllocationLib USER = $(OC_USER)\User\Library OBJECTS = $(OBJECTS) {$(BASE)}SafeString.obj String.obj SwapBytes16.obj SwapBytes32.obj CpuDeadLoop.obj CheckSum.obj OBJECTS = $(OBJECTS) {$(OUT)}DebugLib.obj {$(PRIN)}PrintLib.obj PrintLibInternal.obj {$(ERRO)}BaseDebugPrintErrorLevelLib.obj -OBJECTS = $(OBJECTS) {$(USER)}UserFile.obj UserBaseMemoryLib.obj UserMath.obj UserPcd.obj UserMisc.obj UserGlobalVar.obj UserBootServices.obj +OBJECTS = $(OBJECTS) {$(USER)}UserFile.obj UserBaseMemoryLib.obj UserMath.obj UserPcd.obj UserMisc.obj UserGlobalVar.obj UserEvent.obj UserBootServices.obj OBJECTS = $(OBJECTS) {$(BMPN)}BaseMemoryProfileLibNull.obj {$(CMEM)}CommonMemoryAllocationLib.obj {$(CMEM)}CommonMemoryAllocationLibEx.obj INC = -I . -I $(OC_USER)\User\Include -I $(OC_USER)\Include\Acidanthera From c85c584c662e04d9a648ea5ac0ba863023586bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20H=C3=A4user?= <8659494+mhaeuser@users.noreply.github.com> Date: Thu, 25 Sep 2025 23:14:27 +0200 Subject: [PATCH 118/341] BaseTools/tools_def: Fix XCODE5 __RO_RELOCS generation The Xcode 26 linker no longer supports two-way section renaming used to generate the empty __RO_RELOCS segment. Instead, generate it from the new, empty XcodeRoRelocsEmptyFile file. --- BaseTools/Conf/tools_def.template | 2 +- BaseTools/XcodeRoRelocsEmptyFile | 0 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 BaseTools/XcodeRoRelocsEmptyFile diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index b2a37bdb4f..d8b544c209 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -1575,7 +1575,7 @@ RELEASE_CLANGDWARF_RISCV64_DLINK_FLAGS = DEF(CLANGDWARF_RISCV64_DLINK_FLAGS) -fl # image. This also makes the usage of "-read_only_relocs suppress" safe, as # relocations can now target __TEXT without triggering the same issue. # -DEFINE XCODE5_RORELOCS_ARGS = -segprot __RO_RELOCS rw- rw- -segment_order __RO_RELOCS:__TEXT:__DATA_CONST:__DATA:__HII -rename_section __TEXT __text __RO_RELOCS __text -rename_section __RO_RELOCS __text __TEXT __text +DEFINE XCODE5_RORELOCS_ARGS = -sectcreate __RO_RELOCS __ro_relocs $(EDK_TOOLS_PATH)/XcodeRoRelocsEmptyFile -segprot __RO_RELOCS rw- rw- -segment_order __RO_RELOCS:__TEXT:__DATA_CONST:__DATA:__HII DEFINE XCODE5_RODATA_ARGS = DEF(XCODE5_RORELOCS_ARGS) -segprot __DATA_CONST r-- r-- -rename_section __DATA __const __DATA_CONST __const -rename_section __TEXT __const __DATA_CONST __text_const -rename_section __TEXT __cstring __DATA_CONST __cstring -rename_section __TEXT __ustring __DATA_CONST __ustring ################## diff --git a/BaseTools/XcodeRoRelocsEmptyFile b/BaseTools/XcodeRoRelocsEmptyFile new file mode 100644 index 0000000000..e69de29bb2 From 1b4ee1e78590bd92559c776a2d279b7dfeaf8f35 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 20 Nov 2023 21:37:25 +0300 Subject: [PATCH 119/341] UefiCpuPkg: Added segment descriptors' data structures. --- UefiCpuPkg/Library/CpuArchLib/CpuGdt.c | 250 ++++++++++++++++--------- UefiCpuPkg/Library/CpuArchLib/CpuGdt.h | 155 +++++++++++++-- 2 files changed, 297 insertions(+), 108 deletions(-) diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c index cf571138e5..7457eb840e 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c @@ -14,104 +14,174 @@ // Global descriptor table (GDT) Template // STATIC GDT_ENTRIES mGdtTemplate = { - // - // NULL_SEL - // - { - 0x0, // limit 15:0 - 0x0, // base 15:0 - 0x0, // base 23:16 - 0x0, // type - 0x0, // limit 19:16, flags - 0x0, // base 31:24 + .Null = { + .SegmentLimit_15_0 = 0x0, + .BaseAddress_15_0 = 0x0, + .BaseAddress_23_16 = 0x0, + .Type = 0x0, + .S = 0, + .DPL = 0, + .P = 0, + .SegmentLimit_19_16 = 0x0, + .AVL = 0, + .L = 0, + .D_B = 0, + .G = 0, + .BaseAddress_31_24 = 0x0 }, - // - // LINEAR_SEL - // - { - 0x0FFFF, // limit 15:0 - 0x0, // base 15:0 - 0x0, // base 23:16 - 0x092, // present, ring 0, data, read/write - 0x0CF, // page-granular, 32-bit - 0x0, + .Linear = { + .SegmentLimit_15_0 = 0xFFFF, + .BaseAddress_15_0 = 0x0, + .BaseAddress_23_16 = 0x0, + + .Accessed = 0, + .Writable = 1, + .ExpansionDirection = 0, + .IsCode = 0, + .IsNotSystemSegment = 1, + .DescriptorPrivilegeLevel = 0, + .SegmentPresent = 1, + + .SegmentLimit_19_16 = 0xF, + .Available = 0, + .Reserved = 0, + .UpperBound = 1, + .Granularity = 1, + .BaseAddress_31_24 = 0x0 }, - // - // LINEAR_CODE_SEL - // - { - 0x0FFFF, // limit 15:0 - 0x0, // base 15:0 - 0x0, // base 23:16 - 0x09F, // present, ring 0, code, execute/read, conforming, accessed - 0x0CF, // page-granular, 32-bit - 0x0, + .LinearCode = { + .SegmentLimit_15_0 = 0xFFFF, + .BaseAddress_15_0 = 0x0, + .BaseAddress_23_16 = 0x0, + + .Accessed = 1, + .Readable = 1, + .Conforming = 1, + .IsCode = 1, + .IsNotSystemSegment = 1, + .DescriptorPrivilegeLevel = 0, + .SegmentPresent = 1, + + .SegmentLimit_19_16 = 0xF, + .Available = 0, + .Reserved = 0, + .Is32Bit = 1, + .Granularity = 1, + .BaseAddress_31_24 = 0x0 }, - // - // SYS_DATA_SEL - // - { - 0x0FFFF, // limit 15:0 - 0x0, // base 15:0 - 0x0, // base 23:16 - 0x093, // present, ring 0, data, read/write, accessed - 0x0CF, // page-granular, 32-bit - 0x0, + .SysData = { + .SegmentLimit_15_0 = 0xFFFF, + .BaseAddress_15_0 = 0x0, + .BaseAddress_23_16 = 0x0, + + .Accessed = 1, + .Writable = 1, + .ExpansionDirection = 0, + .IsCode = 0, + .IsNotSystemSegment = 1, + .DescriptorPrivilegeLevel = 0, + .SegmentPresent = 1, + + .SegmentLimit_19_16 = 0xF, + .Available = 0, + .Reserved = 0, + .UpperBound = 1, + .Granularity = 1, + .BaseAddress_31_24 = 0x0 }, - // - // SYS_CODE_SEL - // - { - 0x0FFFF, // limit 15:0 - 0x0, // base 15:0 - 0x0, // base 23:16 - 0x09A, // present, ring 0, code, execute/read - 0x0CF, // page-granular, 32-bit - 0x0, + .SysCode = { + .SegmentLimit_15_0 = 0xFFFF, + .BaseAddress_15_0 = 0x0, + .BaseAddress_23_16 = 0x0, + + .Accessed = 0, + .Readable = 1, + .Conforming = 0, + .IsCode = 1, + .IsNotSystemSegment = 1, + .DescriptorPrivilegeLevel = 0, + .SegmentPresent = 1, + + .SegmentLimit_19_16 = 0xF, + .Available = 0, + .Reserved = 0, + .Is32Bit = 1, + .Granularity = 1, + .BaseAddress_31_24 = 0x0 }, - // - // SYS_CODE16_SEL - // - { - 0x0FFFF, // limit 15:0 - 0x0, // base 15:0 - 0x0, // base 23:16 - 0x09A, // present, ring 0, code, execute/read - 0x08F, // page-granular, 16-bit - 0x0, // base 31:24 + .SysCode16 = { + .SegmentLimit_15_0 = 0xFFFF, + .BaseAddress_15_0 = 0x0, + .BaseAddress_23_16 = 0x0, + + .Accessed = 0, + .Readable = 1, + .Conforming = 0, + .IsCode = 1, + .IsNotSystemSegment = 1, + .DescriptorPrivilegeLevel = 0, + .SegmentPresent = 1, + + .SegmentLimit_19_16 = 0xF, + .Available = 0, + .Reserved = 0, + .Is32Bit = 0, + .Granularity = 1, + .BaseAddress_31_24 = 0x0 }, - // - // LINEAR_DATA64_SEL - // - { - 0x0FFFF, // limit 15:0 - 0x0, // base 15:0 - 0x0, // base 23:16 - 0x092, // present, ring 0, data, read/write - 0x0CF, // page-granular, 32-bit - 0x0, + .LinearData64 = { + .SegmentLimit_15_0 = 0xFFFF, + .BaseAddress_15_0 = 0x0, + .BaseAddress_23_16 = 0x0, + + .Accessed = 0, + .Writable = 1, + .ExpansionDirection = 0, + .IsCode = 0, + .IsNotSystemSegment = 1, + .DescriptorPrivilegeLevel = 0, + .SegmentPresent = 1, + + .SegmentLimit_19_16 = 0xF, + .Available = 0, + .Reserved = 0, + .UpperBound = 1, + .Granularity = 1, + .BaseAddress_31_24 = 0x0 }, - // - // LINEAR_CODE64_SEL - // - { - 0x0FFFF, // limit 15:0 - 0x0, // base 15:0 - 0x0, // base 23:16 - 0x09A, // present, ring 0, code, execute/read - 0x0AF, // page-granular, 64-bit code - 0x0, // base (high) + .LinearCode64 = { + .Reserved1 = 0x0, + .Reserved2 = 0x0, + + .Accessed = 0, + .Readable = 1, + .Conforming = 0, + .IsCode = 1, + .IsNotSystemSegment = 1, + .DescriptorPrivilegeLevel = 0, + .SegmentPresent = 1, + + .Reserved3 = 0x0, + .Available = 0, + .LongMode = 1, + .Is32Bit = 0, + .Granularity = 1, + .Reserved4 = 0x0 }, - // - // SPARE5_SEL - // - { - 0x0, // limit 15:0 - 0x0, // base 15:0 - 0x0, // base 23:16 - 0x0, // type - 0x0, // limit 19:16, flags - 0x0, // base 31:24 + .Spare5 = { + .SegmentLimit_15_0 = 0x0, + .BaseAddress_15_0 = 0x0, + .BaseAddress_23_16 = 0x0, + .Type = 0x0, + .S = 0, + .DPL = 0, + .P = 0, + .SegmentLimit_19_16 = 0x0, + .AVL = 0, + .L = 0, + .D_B = 0, + .G = 0, + .BaseAddress_31_24 = 0x0, }, }; diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h index b09f15725a..62bf5c8a36 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h +++ b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h @@ -20,26 +20,145 @@ // Global Descriptor Entry structures // -typedef struct _GDT_ENTRY { - UINT16 Limit15_0; - UINT16 Base15_0; - UINT8 Base23_16; - UINT8 Type; - UINT8 Limit19_16_and_flags; - UINT8 Base31_24; +typedef struct { + UINT16 SegmentLimit_15_0; + UINT16 BaseAddress_15_0; + UINT8 BaseAddress_23_16; + UINT8 Type : 4; + UINT8 S : 1; + UINT8 DPL : 2; + UINT8 P : 1; + UINT8 SegmentLimit_19_16 : 4; + UINT8 AVL : 1; + UINT8 L : 1; + UINT8 D_B : 1; + UINT8 G : 1; + UINT8 BaseAddress_31_24; +} SEGMENT_DESCRIPTOR; + +typedef struct { + UINT16 SegmentLimit_15_0; + UINT16 BaseAddress_15_0; + UINT8 BaseAddress_23_16; + // + // Type + // + UINT8 Accessed : 1; + UINT8 Writable : 1; + UINT8 ExpansionDirection : 1; + UINT8 IsCode : 1; + UINT8 IsNotSystemSegment : 1; + UINT8 DescriptorPrivilegeLevel : 2; + UINT8 SegmentPresent : 1; + + UINT8 SegmentLimit_19_16 : 4; + UINT8 Available : 1; + UINT8 Reserved : 1; + UINT8 UpperBound : 1; + UINT8 Granularity : 1; + UINT8 BaseAddress_31_24; +} DATA_SEGMENT_32; + +typedef struct { + UINT16 SegmentLimit_15_0; + UINT16 BaseAddress_15_0; + UINT8 BaseAddress_23_16; + // + // Type + // + UINT8 Accessed : 1; + UINT8 Readable : 1; + UINT8 Conforming : 1; + UINT8 IsCode : 1; + UINT8 IsNotSystemSegment : 1; + UINT8 DescriptorPrivilegeLevel : 2; + UINT8 SegmentPresent : 1; + + UINT8 SegmentLimit_19_16 : 4; + UINT8 Available : 1; + UINT8 Reserved : 1; + UINT8 Is32Bit : 1; + UINT8 Granularity : 1; + UINT8 BaseAddress_31_24; +} CODE_SEGMENT_32; + +typedef struct { + UINT32 Reserved1; + UINT8 Reserved2; + // + // Type + // + UINT8 Accessed : 1; + UINT8 Readable : 1; + UINT8 Conforming : 1; + UINT8 IsCode : 1; + UINT8 IsNotSystemSegment : 1; + UINT8 DescriptorPrivilegeLevel : 2; + UINT8 SegmentPresent : 1; + + UINT8 Reserved3 : 4; + UINT8 Available : 1; + UINT8 LongMode : 1; + UINT8 Is32Bit : 1; + UINT8 Granularity : 1; + UINT8 Reserved4; +} CODE_SEGMENT_64; + +typedef struct { + UINT16 SegmentLimit_15_0; + UINT16 BaseAddress_15_0; + UINT8 BaseAddress_23_16; + + UINT8 Type : 4; + UINT8 IsNotSystemSegment : 1; + UINT8 DescriptorPrivilegeLevel : 2; + UINT8 SegmentPresent : 1; + + UINT8 SegmentLimit_19_16 : 4; + UINT8 Reserved : 3; + UINT8 Granularity : 1; + UINT8 BaseAddress_31_24; +} SYSTEM_SEGMENT; + +typedef struct { + UINT16 OffsetInSegment_15_0; + UINT16 SegmentSelector; + + UINT8 ParameterCount : 5; + UINT8 Reserved : 3; + + UINT8 Type : 4; + UINT8 IsNotSystemSegment : 1; + UINT8 DescriptorPrivilegeLevel : 2; + UINT8 SegmentPresent : 1; + UINT16 OffsetInSegment_31_16; +} CALL_GATE_32; + +typedef struct { + CALL_GATE_32 Common; + UINT32 OffsetInSegment_63_31; + UINT32 Reserved; +} CALL_GATE_64; + +typedef union { + DATA_SEGMENT_32 DataSegment32; + CODE_SEGMENT_32 CodeSegment32; + CODE_SEGMENT_64 CodeSegment64; + CALL_GATE_32 CallGate32; + SYSTEM_SEGMENT SystemSegment; + SEGMENT_DESCRIPTOR SegmentDescriptor; } GDT_ENTRY; -typedef - struct _GDT_ENTRIES { - GDT_ENTRY Null; - GDT_ENTRY Linear; - GDT_ENTRY LinearCode; - GDT_ENTRY SysData; - GDT_ENTRY SysCode; - GDT_ENTRY SysCode16; - GDT_ENTRY LinearData64; - GDT_ENTRY LinearCode64; - GDT_ENTRY Spare5; +typedef struct { + SEGMENT_DESCRIPTOR Null; + DATA_SEGMENT_32 Linear; + CODE_SEGMENT_32 LinearCode; + DATA_SEGMENT_32 SysData; + CODE_SEGMENT_32 SysCode; + CODE_SEGMENT_32 SysCode16; + DATA_SEGMENT_32 LinearData64; + CODE_SEGMENT_64 LinearCode64; + SEGMENT_DESCRIPTOR Spare5; } GDT_ENTRIES; #pragma pack () From 3f01166069865b0a5ba2d2f3b4e29dcbfc1cb4cf Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 25 Dec 2023 15:35:05 +0300 Subject: [PATCH 120/341] Ring3: Some drafts. --- UefiCpuPkg/Library/CpuArchLib/CpuGdt.c | 54 +++++++++++++++++++ UefiCpuPkg/Library/CpuArchLib/CpuGdt.h | 5 ++ .../X64/ArchExceptionHandler.c | 2 + 3 files changed, 61 insertions(+) diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c index 7457eb840e..d569d3be53 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c @@ -183,6 +183,60 @@ STATIC GDT_ENTRIES mGdtTemplate = { .G = 0, .BaseAddress_31_24 = 0x0, }, + .Ring3Data64 = { + .SegmentLimit_15_0 = 0xFFFF, + .BaseAddress_15_0 = 0x0, + .BaseAddress_23_16 = 0x0, + + .Accessed = 0, + .Writable = 1, + .ExpansionDirection = 0, + .IsCode = 0, + .IsNotSystemSegment = 1, + .DescriptorPrivilegeLevel = 3, + .SegmentPresent = 1, + + .SegmentLimit_19_16 = 0xF, + .Available = 0, + .Reserved = 0, + .UpperBound = 1, + .Granularity = 1, + .BaseAddress_31_24 = 0x0 + }, + .Ring3Code64 = { // SetCodeSelector () | 5.8.6 Returning from a Called Procedure + .Reserved1 = 0x0, + .Reserved2 = 0x0, + + .Accessed = 0, + .Readable = 1, + .Conforming = 0, + .IsCode = 1, + .IsNotSystemSegment = 1, + .DescriptorPrivilegeLevel = 3, + .SegmentPresent = 1, + + .Reserved3 = 0x0, + .Available = 0, + .LongMode = 1, + .Is32Bit = 0, + .Granularity = 1, + .Reserved4 = 0x0 + }, + // .FromRing3ToRing0 = { + // .Common.OffsetInSegment_15_0 = 0x?, + // .Common.SegmentSelector = (UINT16)LINEAR_CODE64_SEL, + // + // .Common.ParameterCount = 0, + // .Common.Reserved = 0, + // + // .Common.Type = 0xC, + // .Common.IsNotSystemSegment = 0, + // .Common.DescriptorPrivilegeLevel = 3, + // .Common.SegmentPresent = 1, + // .Common.OffsetInSegment_31_16 = 0x?, + // .OffsetInSegment_63_31 = 0x?, + // .Reserved = 0x0 + // }, }; /** diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h index 62bf5c8a36..d1659293cb 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h +++ b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h @@ -159,6 +159,9 @@ typedef struct { DATA_SEGMENT_32 LinearData64; CODE_SEGMENT_64 LinearCode64; SEGMENT_DESCRIPTOR Spare5; + DATA_SEGMENT_32 Ring3Data64; + CODE_SEGMENT_64 Ring3Code64; + // CALL_GATE_64 FromRing3ToRing0; } GDT_ENTRIES; #pragma pack () @@ -172,6 +175,8 @@ typedef struct { #define LINEAR_DATA64_SEL OFFSET_OF (GDT_ENTRIES, LinearData64) #define LINEAR_CODE64_SEL OFFSET_OF (GDT_ENTRIES, LinearCode64) #define SPARE5_SEL OFFSET_OF (GDT_ENTRIES, Spare5) +#define RING3_DATA64_SEL OFFSET_OF (GDT_ENTRIES, Ring3Data64) +#define RING3_CODE64_SEL OFFSET_OF (GDT_ENTRIES, Ring3Code64) #if defined (MDE_CPU_IA32) #define CPU_CODE_SEL LINEAR_CODE_SEL diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index 4e85880ed4..b1763e756b 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -249,6 +249,8 @@ ArchSetupExceptionStack ( IdtTable[Vector].Bits.Reserved_0 = (UINT8)(Index + 1); } + // Tss->RSP0 = %rsp + // // Publish GDT // From 589ea318ee29fe07558eee23a9515f9b3f821a38 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 25 Dec 2023 16:08:53 +0300 Subject: [PATCH 121/341] Ring3: Added EFI_MEMORY_USER attribute. --- MdeModulePkg/Core/Dxe/Image/Image.c | 2 +- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 13 ++++++++---- MdePkg/Include/Uefi/UefiSpec.h | 7 ++++++- UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c | 21 +++++++++++++++++++ 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 9f0f7c0f64..5065c01fb3 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -828,7 +828,7 @@ CoreLoadPeImage ( if (DstBufAlocated) { ZeroMem ((VOID *)(UINTN)BufferAddress, EFI_PAGES_TO_SIZE (Image->NumberOfPages)); FreeAlignedPages ((VOID *)(UINTN)BufferAddress, Image->NumberOfPages); - Image->ImageBasePage = 0; + Image->ImageBasePage = 0; } if (RelocationData != NULL) { diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 5b0fe44a23..8c173eaf6a 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -94,7 +94,8 @@ SetUefiImageMemoryAttributes ( **/ VOID SetUefiImageProtectionAttributes ( - IN UEFI_IMAGE_RECORD *ImageRecord + IN UEFI_IMAGE_RECORD *ImageRecord, + IN BOOLEAN IsUser ) { UEFI_IMAGE_RECORD_SEGMENT *ImageRecordSegment; @@ -107,7 +108,7 @@ SetUefiImageProtectionAttributes ( SetUefiImageMemoryAttributes ( SectionAddress, ImageRecordSegment->Size, - ImageRecordSegment->Attributes + IsUser ? ImageRecordSegment->Attributes | (UINT32)EFI_MEMORY_USER : ImageRecordSegment->Attributes ); SectionAddress += ImageRecordSegment->Size; @@ -231,7 +232,11 @@ ProtectUefiImage ( // // CPU ARCH present. Update memory attribute directly. // - SetUefiImageProtectionAttributes (ImageRecord); + if (AsciiStrStr (PdbPointer, "Ntfs") != NULL) { + SetUefiImageProtectionAttributes (ImageRecord, TRUE); + } else { + SetUefiImageProtectionAttributes (ImageRecord, FALSE); + } } Finish: @@ -663,7 +668,7 @@ MemoryProtectionCpuArchProtocolNotify ( // // CPU ARCH present. Update memory attribute directly. // - SetUefiImageProtectionAttributes (ImageRecord); + SetUefiImageProtectionAttributes (ImageRecord, FALSE); } Done: diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index bb395a2cb2..cfaa8363f1 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -114,6 +114,11 @@ typedef enum { // capable of being dynamically removed from the platform at runtime. // #define EFI_MEMORY_HOT_PLUGGABLE 0x0000000000100000 +// +// If this flag is set, the memory region contains user code or data. +// If this flag is clear, the memory region contains supervisor code or data. +// +#define EFI_MEMORY_USER 0x0000000000200000ULL // // Runtime memory attribute @@ -140,7 +145,7 @@ typedef enum { // #define EFI_CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP) #define EFI_MEMORY_ACCESS_MASK (EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RO) -#define EFI_MEMORY_ATTRIBUTE_MASK (EFI_MEMORY_ACCESS_MASK | EFI_MEMORY_SP | EFI_MEMORY_CPU_CRYPTO) +#define EFI_MEMORY_ATTRIBUTE_MASK (EFI_MEMORY_ACCESS_MASK | EFI_MEMORY_SP | EFI_MEMORY_CPU_CRYPTO | EFI_MEMORY_USER) /// /// Memory descriptor version number. diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c index 1092a30d28..3844030398 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c @@ -467,6 +467,27 @@ ConvertPageEntryAttribute ( } } + if ((Attributes & EFI_MEMORY_USER) != 0) { + switch (PageAction) { + case PageActionAssign: + case PageActionSet: + NewPageEntry |= IA32_PG_U; + break; + case PageActionClear: + NewPageEntry &= ~(UINT64)IA32_PG_U; + break; + } + } else { + switch (PageAction) { + case PageActionAssign: + NewPageEntry &= ~(UINT64)IA32_PG_U; + break; + case PageActionSet: + case PageActionClear: + break; + } + } + GetPagingDetails (&PagingContext->ContextData, NULL, &PageAttributes); if ((*PageAttributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED) != 0) { From d598f6c281214400749a2809be41ab377d85bff4 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 9 Jan 2024 14:20:48 +0300 Subject: [PATCH 122/341] Ring3: Enabled SMAP and SMEP. --- .../Core/DxeIplPeim/X64/VirtualMemory.c | 20 +++++++++++ MdePkg/Include/Library/BaseLib.h | 18 ++++++++++ MdePkg/Library/BaseLib/BaseLib.inf | 1 + MdePkg/Library/BaseLib/X64/WriteEflags.nasm | 33 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 MdePkg/Library/BaseLib/X64/WriteEflags.nasm diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index 1fb2a3b2ea..b3f00ce7da 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -704,6 +704,10 @@ CreateIdentityMappingPageTables ( PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; UINT64 AddressEncMask; IA32_CR4 Cr4; + IA32_EFLAGS32 Eflags; + UINT32 Ebx; + + Ebx = 0; // // Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings @@ -973,5 +977,21 @@ CreateIdentityMappingPageTables ( EnableExecuteDisableBit (); } + // + // Forbid supervisor-mode accesses to any user-mode pages. + // SMEP and SMAP must be supported. + // + AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); + if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMAP = 1; + Cr4.Bits.SMEP = 1; + AsmWriteCr4 (Cr4.UintN); + + Eflags.UintN = AsmReadEflags (); + Eflags.Bits.AC = 0; + AsmWriteEflags (Eflags.UintN); + } + return (UINTN)PageMap; } diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 9658026d9c..d82433ed11 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -6602,6 +6602,24 @@ AsmReadCr4 ( VOID ); +/** + Writes a value to the EFLAGS register. + + Writes and returns a new value to the EFLAGS register. This function is + only available on IA-32 and x64. This writes a 32-bit value on IA-32 and + a 64-bit value on x64. + + @param EFLAGS The value to write to EFLAGS. + + @return The value written to EFLAGS. + +**/ +UINTN +EFIAPI +AsmWriteEflags ( + UINTN Eflags + ); + /** Writes a value to Control Register 0 (CR0). diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf index 317d32cf68..909f2e6ee4 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -294,6 +294,7 @@ X64/ReadCr2.nasm| MSFT X64/ReadCr0.nasm| MSFT X64/ReadEflags.nasm| MSFT + X64/WriteEflags.nasm X64/TdCall.nasm X64/TdVmcall.nasm diff --git a/MdePkg/Library/BaseLib/X64/WriteEflags.nasm b/MdePkg/Library/BaseLib/X64/WriteEflags.nasm new file mode 100644 index 0000000000..85866a9899 --- /dev/null +++ b/MdePkg/Library/BaseLib/X64/WriteEflags.nasm @@ -0,0 +1,33 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +; +; Module Name: +; +; WriteEflags.Asm +; +; Abstract: +; +; AsmWriteEflags function +; +; Notes: +; +;------------------------------------------------------------------------------ + + DEFAULT REL + SECTION .text + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteEflags ( +; UINTN Eflags +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(AsmWriteEflags) +ASM_PFX(AsmWriteEflags): + push rcx + popfq + mov rax, rcx + ret From 012962ac2fadbe9606dfa48472a27faf8c7a0114 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 9 Jan 2024 16:53:36 +0300 Subject: [PATCH 123/341] Ring3: Set USER bit in all page table structures. --- .../Core/DxeIplPeim/X64/VirtualMemory.c | 27 +++++++++++-------- .../Core/DxeIplPeim/X64/VirtualMemory.h | 1 + UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c | 10 ++++--- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index b3f00ce7da..a7f2c57614 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -377,7 +377,7 @@ Split2MPageTo4K ( // // Fill in 2M page entry. // - *PageEntry2M = (UINT64)(UINTN)PageTableEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW; + *PageEntry2M = (UINT64)(UINTN)PageTableEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW | IA32_PG_U; PhysicalAddress4K = PhysicalAddress; for (IndexOfPageTableEntries = 0; IndexOfPageTableEntries < 512; IndexOfPageTableEntries++, PageTableEntry++, PhysicalAddress4K += SIZE_4KB) { @@ -459,7 +459,7 @@ Split1GPageTo2M ( // // Fill in 1G page entry. // - *PageEntry1G = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW; + *PageEntry1G = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW | IA32_PG_U; PhysicalAddress2M = PhysicalAddress; for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) { @@ -594,6 +594,8 @@ SetPageTablePoolReadOnly ( IA32_PG_P | IA32_PG_RW; if (Level > 2) { NewPageTable[EntryIndex] |= IA32_PG_PS; + } else { + NewPageTable[EntryIndex] |= IA32_PG_U; } PhysicalAddress += LevelSize[Level - 1]; @@ -864,9 +866,10 @@ CreateIdentityMappingPageTables ( // // Make a PML5 Entry // - PageMapLevel5Entry->Uint64 = (UINT64)(UINTN)PageMapLevel4Entry | AddressEncMask; - PageMapLevel5Entry->Bits.ReadWrite = 1; - PageMapLevel5Entry->Bits.Present = 1; + PageMapLevel5Entry->Uint64 = (UINT64)(UINTN)PageMapLevel4Entry | AddressEncMask; + PageMapLevel5Entry->Bits.ReadWrite = 1; + PageMapLevel5Entry->Bits.UserSupervisor = 1; + PageMapLevel5Entry->Bits.Present = 1; PageMapLevel5Entry++; } @@ -884,9 +887,10 @@ CreateIdentityMappingPageTables ( // // Make a PML4 Entry // - PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | AddressEncMask; - PageMapLevel4Entry->Bits.ReadWrite = 1; - PageMapLevel4Entry->Bits.Present = 1; + PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | AddressEncMask; + PageMapLevel4Entry->Bits.ReadWrite = 1; + PageMapLevel4Entry->Bits.UserSupervisor = 1; + PageMapLevel4Entry->Bits.Present = 1; if (Page1GSupport) { PageDirectory1GEntry = (VOID *)PageDirectoryPointerEntry; @@ -919,9 +923,10 @@ CreateIdentityMappingPageTables ( // // Fill in a Page Directory Pointer Entries // - PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask; - PageDirectoryPointerEntry->Bits.ReadWrite = 1; - PageDirectoryPointerEntry->Bits.Present = 1; + PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask; + PageDirectoryPointerEntry->Bits.ReadWrite = 1; + PageDirectoryPointerEntry->Bits.UserSupervisor = 1; + PageDirectoryPointerEntry->Bits.Present = 1; for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) { if (ToSplitPageTable (PageAddress, SIZE_2MB, StackBase, StackSize, GhcbBase, GhcbSize)) { diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h index e0352844d7..3459da8560 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h @@ -145,6 +145,7 @@ typedef union { #define IA32_PG_P BIT0 #define IA32_PG_RW BIT1 +#define IA32_PG_U BIT2 #define IA32_PG_PS BIT7 #define PAGING_PAE_INDEX_MASK 0x1FF diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c index 3844030398..46d9344e86 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c @@ -38,7 +38,7 @@ #define IA32_PG_NX BIT63 #define PAGE_ATTRIBUTE_BITS (IA32_PG_D | IA32_PG_A | IA32_PG_U | IA32_PG_RW | IA32_PG_P) -#define PAGE_ATTRIBUTE_BITS_POST_SPLIT (IA32_PG_RW | IA32_PG_P) +#define PAGE_ATTRIBUTE_BITS_POST_SPLIT (IA32_PG_RW | IA32_PG_P | IA32_PG_U) // // Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE @@ -398,6 +398,10 @@ GetAttributesFromPageEntry ( Attributes |= EFI_MEMORY_XP; } + if ((*PageEntry & IA32_PG_U) != 0) { + Attributes |= EFI_MEMORY_USER; + } + return Attributes; } @@ -1012,9 +1016,9 @@ RefreshGcdMemoryAttributesFromPaging ( PageLength = 0; if (IsExecuteDisableEnabled ()) { - Capabilities = EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP; + Capabilities = EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_USER; } else { - Capabilities = EFI_MEMORY_RO | EFI_MEMORY_RP; + Capabilities = EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_USER; } for (Index = 0; Index < NumberOfDescriptors; Index++) { From 517c8340f4a94aea08e00f4b3c72e9e4e6a39a1a Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 15 Jan 2024 10:53:36 +0300 Subject: [PATCH 124/341] Ring3: Added IsUserImage field into LOADED_IMAGE_PRIVATE_DATA structure. --- MdeModulePkg/Core/Dxe/DxeMain.h | 11 +++++++---- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 2 +- MdeModulePkg/Core/Dxe/Image/Image.c | 7 +++++-- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 10 +++++++--- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 012e2d379d..512fc871cf 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -224,7 +224,8 @@ typedef struct { /// Status returned by LoadImage() service. EFI_STATUS LoadImageStatus; - VOID *HiiData; + VOID *HiiData; + BOOLEAN IsUserImage; } LOADED_IMAGE_PRIVATE_DATA; #define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \ @@ -2728,12 +2729,14 @@ RemoveImageRecord ( @param[in] LoadedImage The loaded image protocol @param[in] ImageOrigin Where File comes from. @param[in] LoadedImageDevicePath The loaded image device path protocol + @param[out] IsUserImage Whether the loaded image is in user space. **/ VOID ProtectUefiImage ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN UINT8 ImageOrigin, - UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN UINT8 ImageOrigin, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + OUT BOOLEAN *IsUserImage ); /** diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 0b3c222ed1..d36d0061af 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -332,7 +332,7 @@ DxeMain ( CoreInitializeMemoryProtection (); - ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext); + ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, &mCurrentImage->IsUserImage); // // Call constructor for all libraries diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 5065c01fb3..3843f32935 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -64,7 +64,10 @@ LOADED_IMAGE_PRIVATE_DATA mCorePrivateImage = { 0, // Machine NULL, // PeCoffEmu NULL, // RuntimeData - NULL // LoadedImageDevicePath + NULL, // LoadedImageDevicePath + EFI_SUCCESS, // LoadImageStatus + NULL, // HiiData + FALSE // IsUserImage }; // // The field is define for Loading modules at fixed address feature to tracker the PEI code @@ -1435,7 +1438,7 @@ CoreLoadImageCommon ( } Status = EFI_SUCCESS; - ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext); + ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, &Image->IsUserImage); RegisterMemoryProfileImage ( Image->LoadedImageDevicePath, diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 8c173eaf6a..910958370a 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -168,12 +168,14 @@ IsMemoryProtectionSectionAligned ( @param[in] LoadedImage The loaded image protocol @param[in] ImageOrigin Where File comes from. @param[in] LoadedImageDevicePath The loaded image device path protocol + @param[out] IsUserImage Whether the loaded image is in user space. **/ VOID ProtectUefiImage ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN UINT8 ImageOrigin, - UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN UINT8 ImageOrigin, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + OUT BOOLEAN *IsUserImage ) { RETURN_STATUS PdbStatus; @@ -234,8 +236,10 @@ ProtectUefiImage ( // if (AsciiStrStr (PdbPointer, "Ntfs") != NULL) { SetUefiImageProtectionAttributes (ImageRecord, TRUE); + *IsUserImage = TRUE; } else { SetUefiImageProtectionAttributes (ImageRecord, FALSE); + *IsUserImage = FALSE; } } From 381e339bbe8121d351c53534df14fea6c77ab3d1 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 15 Jan 2024 11:01:00 +0300 Subject: [PATCH 125/341] Ring3: Added GetMemoryAttributes() into EFI_CPU_ARCH_PROTOCOL. --- MdeModulePkg/Core/Dxe/Image/Image.c | 11 ++++++++- MdePkg/Include/Protocol/Cpu.h | 11 ++++++++- UefiCpuPkg/Library/CpuArchLib/CpuDxe.c | 3 ++- UefiCpuPkg/Library/CpuArchLib/CpuDxe.h | 8 +++++++ UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c | 24 ++++++++++++++++++++ 5 files changed, 54 insertions(+), 3 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 3843f32935..f0148f875b 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1595,6 +1595,7 @@ CoreStartImage ( UINT64 HandleDatabaseKey; UINTN SetJumpFlag; EFI_HANDLE Handle; + UINT64 Attributes; Handle = ImageHandle; @@ -1686,7 +1687,15 @@ CoreStartImage ( // Call the image's entry point // Image->Started = TRUE; - Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); + + if (!Image->IsUserImage) { + Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); + } else { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); + } // // Add some debug information if the image returned with error. diff --git a/MdePkg/Include/Protocol/Cpu.h b/MdePkg/Include/Protocol/Cpu.h index 3d25ad08f8..ccaec43cb4 100644 --- a/MdePkg/Include/Protocol/Cpu.h +++ b/MdePkg/Include/Protocol/Cpu.h @@ -244,12 +244,20 @@ EFI_STATUS typedef EFI_STATUS (EFIAPI *EFI_CPU_SET_MEMORY_ATTRIBUTES)( - IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes ); +typedef +EFI_STATUS +(EFIAPI *EFI_CPU_GET_MEMORY_ATTRIBUTES)( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS Address, + OUT UINT64 *Attributes + ); + /// /// The EFI_CPU_ARCH_PROTOCOL is used to abstract processor-specific functions from the DXE /// Foundation. This includes flushing caches, enabling and disabling interrupts, hooking interrupt @@ -279,6 +287,7 @@ struct _EFI_CPU_ARCH_PROTOCOL { /// a read-only field. /// UINT32 DmaBufferAlignment; + EFI_CPU_GET_MEMORY_ATTRIBUTES GetMemoryAttributes; }; extern EFI_GUID gEfiCpuArchProtocolGuid; diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c index 1d539ee3f7..db4551ac69 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c @@ -31,7 +31,8 @@ EFI_CPU_ARCH_PROTOCOL gCpuImpl = { CpuGetTimerValue, CpuSetMemoryAttributes, 1, // NumberOfTimers - 4 // DmaBufferAlignment + 4, // DmaBufferAlignment + CpuGetMemoryAttributes }; EFI_HOB_PLATFORM_INFO *mPlatformInfoHob2 = NULL; diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuDxe.h b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.h index 34a865d1dd..731dbd6d13 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuDxe.h +++ b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.h @@ -221,6 +221,14 @@ CpuSetMemoryAttributes ( IN UINT64 Attributes ); +EFI_STATUS +EFIAPI +CpuGetMemoryAttributes ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS Address, + OUT UINT64 *Attributes + ); + /** Initialize Global Descriptor Table. diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c index 46d9344e86..04f768e01d 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c @@ -405,6 +405,30 @@ GetAttributesFromPageEntry ( return Attributes; } +EFI_STATUS +EFIAPI +CpuGetMemoryAttributes ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS Address, + OUT UINT64 *Attributes + ) +{ + PAGE_TABLE_LIB_PAGING_CONTEXT PagingContext; + PAGE_ATTRIBUTE PageAttribute; + UINT64 *PageEntry; + + GetCurrentPagingContext (&PagingContext); + + PageEntry = GetPageTableEntry (&PagingContext, Address, &PageAttribute); + if (PageEntry == NULL) { + return EFI_NOT_FOUND; + } + + *Attributes = GetAttributesFromPageEntry (PageEntry); + + return EFI_SUCCESS; +} + /** Modify memory attributes of page entry. From 623aa7c271201fe61c700a9230dfb07cc2b57a6e Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 16 Jan 2024 17:06:50 +0300 Subject: [PATCH 126/341] Ring3: Added EnterUserImage(). --- MdeModulePkg/Core/Dxe/DxeMain.h | 16 ++ MdeModulePkg/Core/Dxe/Image/Image.c | 30 ++- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 1 + MdePkg/Include/Library/BaseLib.h | 157 ++++++++++++++++ MdePkg/Library/BaseLib/BaseLibInternals.h | 11 ++ MdePkg/Library/BaseLib/SwitchStack.c | 22 +++ MdePkg/Library/BaseLib/X64/SwitchStack.nasm | 48 +++++ UefiCpuPkg/Library/CpuArchLib/CpuGdt.c | 6 +- UefiCpuPkg/Library/CpuArchLib/CpuGdt.h | 172 +----------------- 9 files changed, 296 insertions(+), 167 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 512fc871cf..3b2231eab3 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -114,6 +114,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent /// #define DEPEX_STACK_SIZE_INCREMENT 0x1000 +#define USER_STACK_SIZE 0x20000 + typedef struct { EFI_GUID *ProtocolGuid; VOID **Protocol; @@ -2811,5 +2813,19 @@ EFI_STATUS CoreInitializeHandleServices ( VOID ); + +/** + Set UEFI image memory attributes. + + @param[in] BaseAddress Specified start address + @param[in] Length Specified length + @param[in] Attributes Specified attributes +**/ +VOID +SetUefiImageMemoryAttributes ( + IN UINT64 BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); #endif diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index f0148f875b..ead8195baf 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1596,6 +1596,9 @@ CoreStartImage ( UINTN SetJumpFlag; EFI_HANDLE Handle; UINT64 Attributes; + VOID *BaseOfStack; + VOID *TopOfStack; + UINTN SizeOfStack; Handle = ImageHandle; @@ -1694,7 +1697,32 @@ CoreStartImage ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); + // + // Allocate 128KB for the User Stack. + // + BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); + ASSERT (BaseOfStack != NULL); + + SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; + + SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); + + // + // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. + // + TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + // DEBUG ((DEBUG_ERROR, "RING3_CODE64_SEL = 0x%x RING3_DATA64_SEL = 0x%x\n", (UINT16)RING3_CODE64_SEL, (UINT16)RING3_DATA64_SEL)); + + EnterUserImage ( + (SWITCH_STACK_ENTRY_POINT)(UINTN)Image->EntryPoint, + ImageHandle, + Image->Info.SystemTable, + TopOfStack, + (UINT16)RING3_CODE64_SEL, + (UINT16)RING3_DATA64_SEL + ); + Image->Status = EFI_SUCCESS; } // diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 910958370a..76ab3fbbd6 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -91,6 +91,7 @@ SetUefiImageMemoryAttributes ( Set UEFI image protection attributes. @param[in] ImageRecord A UEFI image record + @param[in] IsUser Whether UEFI image record is User Image. **/ VOID SetUefiImageProtectionAttributes ( diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index d82433ed11..8d2a5a509d 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -5218,6 +5218,17 @@ SwitchStack ( ... ); +VOID +EFIAPI +EnterUserImage ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1 OPTIONAL, + IN VOID *Context2 OPTIONAL, + IN VOID *NewStack, + IN UINT16 CodeSelector, + IN UINT16 DataSelector + ); + /** Generates a breakpoint on the CPU. @@ -5530,6 +5541,152 @@ typedef union { UINTN UintN; } IA32_CR4; +#pragma pack (1) + +// +// Global Descriptor Entry structures +// + +typedef struct { + UINT16 SegmentLimit_15_0; + UINT16 BaseAddress_15_0; + UINT8 BaseAddress_23_16; + UINT8 Type : 4; + UINT8 S : 1; + UINT8 DPL : 2; + UINT8 P : 1; + UINT8 SegmentLimit_19_16 : 4; + UINT8 AVL : 1; + UINT8 L : 1; + UINT8 D_B : 1; + UINT8 G : 1; + UINT8 BaseAddress_31_24; +} SEGMENT_DESCRIPTOR; + +typedef struct { + UINT16 SegmentLimit_15_0; + UINT16 BaseAddress_15_0; + UINT8 BaseAddress_23_16; + // + // Type + // + UINT8 Accessed : 1; + UINT8 Writable : 1; + UINT8 ExpansionDirection : 1; + UINT8 IsCode : 1; + UINT8 IsNotSystemSegment : 1; + UINT8 DescriptorPrivilegeLevel : 2; + UINT8 SegmentPresent : 1; + + UINT8 SegmentLimit_19_16 : 4; + UINT8 Available : 1; + UINT8 Reserved : 1; + UINT8 UpperBound : 1; + UINT8 Granularity : 1; + UINT8 BaseAddress_31_24; +} DATA_SEGMENT_32; + +typedef struct { + UINT16 SegmentLimit_15_0; + UINT16 BaseAddress_15_0; + UINT8 BaseAddress_23_16; + // + // Type + // + UINT8 Accessed : 1; + UINT8 Readable : 1; + UINT8 Conforming : 1; + UINT8 IsCode : 1; + UINT8 IsNotSystemSegment : 1; + UINT8 DescriptorPrivilegeLevel : 2; + UINT8 SegmentPresent : 1; + + UINT8 SegmentLimit_19_16 : 4; + UINT8 Available : 1; + UINT8 Reserved : 1; + UINT8 Is32Bit : 1; + UINT8 Granularity : 1; + UINT8 BaseAddress_31_24; +} CODE_SEGMENT_32; + +typedef struct { + UINT32 Reserved1; + UINT8 Reserved2; + // + // Type + // + UINT8 Accessed : 1; + UINT8 Readable : 1; + UINT8 Conforming : 1; + UINT8 IsCode : 1; + UINT8 IsNotSystemSegment : 1; + UINT8 DescriptorPrivilegeLevel : 2; + UINT8 SegmentPresent : 1; + + UINT8 Reserved3 : 4; + UINT8 Available : 1; + UINT8 LongMode : 1; + UINT8 Is32Bit : 1; + UINT8 Granularity : 1; + UINT8 Reserved4; +} CODE_SEGMENT_64; + +typedef struct { + UINT16 SegmentLimit_15_0; + UINT16 BaseAddress_15_0; + UINT8 BaseAddress_23_16; + + UINT8 Type : 4; + UINT8 IsNotSystemSegment : 1; + UINT8 DescriptorPrivilegeLevel : 2; + UINT8 SegmentPresent : 1; + + UINT8 SegmentLimit_19_16 : 4; + UINT8 Reserved : 3; + UINT8 Granularity : 1; + UINT8 BaseAddress_31_24; +} SYSTEM_SEGMENT; + +typedef struct { + UINT16 OffsetInSegment_15_0; + UINT16 SegmentSelector; + + UINT8 ParameterCount : 5; + UINT8 Reserved : 3; + + UINT8 Type : 4; + UINT8 IsNotSystemSegment : 1; + UINT8 DescriptorPrivilegeLevel : 2; + UINT8 SegmentPresent : 1; + UINT16 OffsetInSegment_31_16; +} CALL_GATE_32; + +typedef struct { + CALL_GATE_32 Common; + UINT32 OffsetInSegment_63_31; + UINT32 Reserved; +} CALL_GATE_64; + +typedef struct { + SEGMENT_DESCRIPTOR Null; + DATA_SEGMENT_32 Linear; + CODE_SEGMENT_32 LinearCode; + DATA_SEGMENT_32 SysData; + CODE_SEGMENT_32 SysCode; + CODE_SEGMENT_32 SysCode16; + DATA_SEGMENT_32 LinearData64; + CODE_SEGMENT_64 LinearCode64; + SEGMENT_DESCRIPTOR Spare5; + DATA_SEGMENT_32 Ring3Data64; + CODE_SEGMENT_64 Ring3Code64; + // CALL_GATE_64 FromRing3ToRing0; +} GDT; + +#pragma pack () + +#define RING3_DATA64_SEL OFFSET_OF (GDT, Ring3Data64) +#define RING3_CODE64_SEL OFFSET_OF (GDT, Ring3Code64) + /// /// Byte packed structure for a segment descriptor in a GDT/LDT. /// diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h b/MdePkg/Library/BaseLib/BaseLibInternals.h index d61e604385..340ad96284 100644 --- a/MdePkg/Library/BaseLib/BaseLibInternals.h +++ b/MdePkg/Library/BaseLib/BaseLibInternals.h @@ -332,6 +332,17 @@ InternalSwitchStack ( IN VA_LIST Marker ); +VOID +EFIAPI +InternalEnterUserImage ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1 OPTIONAL, + IN VOID *Context2 OPTIONAL, + IN VOID *NewStack, + IN UINT16 CodeSelector, + IN UINT16 DataSelector + ); + /** Worker function that returns a bit field from Operand. diff --git a/MdePkg/Library/BaseLib/SwitchStack.c b/MdePkg/Library/BaseLib/SwitchStack.c index 954e863fc1..14ad7cd4bf 100644 --- a/MdePkg/Library/BaseLib/SwitchStack.c +++ b/MdePkg/Library/BaseLib/SwitchStack.c @@ -68,3 +68,25 @@ SwitchStack ( // ASSERT (FALSE); } + +VOID +EFIAPI +EnterUserImage ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1 OPTIONAL, + IN VOID *Context2 OPTIONAL, + IN VOID *NewStack, + IN UINT16 CodeSelector, + IN UINT16 DataSelector + ) +{ + ASSERT (EntryPoint != NULL); + ASSERT (NewStack != NULL); + + // + // New stack must be aligned with CPU_STACK_ALIGNMENT + // + ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0); + + InternalEnterUserImage (EntryPoint, Context1, Context2, NewStack, CodeSelector, DataSelector); +} diff --git a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm index 7be666dbd3..0f8aa12014 100644 --- a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm +++ b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm @@ -1,4 +1,6 @@ ;------------------------------------------------------------------------------ +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause ; ; Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
; SPDX-License-Identifier: BSD-2-Clause-Patent @@ -43,3 +45,49 @@ ASM_PFX(InternalSwitchStack): lea rsp, [r9 - 0x20] call rax +;------------------------------------------------------------------------------ +; Routine Description: +; +; Routine for transfering control to user image with 2 parameters +; +; Arguments: +; +; (rcx) EntryPoint - Entry point with new stack. +; (rdx) Context1 - Parameter1 for entry point. +; (r8) Context2 - Parameter2 for entry point. +; (r9) NewStack - The pointer to new stack. +;On stack CodeSelector - Segment selector for code. +;On stack DataSelector - Segment selector for data. +; +; Returns: +; +; None +; +;------------------------------------------------------------------------------ +global ASM_PFX(InternalEnterUserImage) +ASM_PFX(InternalEnterUserImage): + ; Set Data selectors + mov rax, [rsp + 8*6] + or rax, 3H ; RPL = 3 + +o16 mov ds, ax +o16 mov es, ax +o16 mov fs, ax +o16 mov gs, ax + + ; Save Code selector + mov r10, [rsp + 8*5] + or r10, 3H ; RPL = 3 + + ; Prepare stack before swithcing + push rax ; ss + push r9 ; rsp + push r10 ; cs + push rcx ; rip + + ; Save 2 parameters + mov rcx, rdx + mov rdx, r8 + + ; Pass control to user image + retfq diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c index d569d3be53..e8047b1207 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c @@ -13,7 +13,7 @@ // // Global descriptor table (GDT) Template // -STATIC GDT_ENTRIES mGdtTemplate = { +STATIC GDT mGdtTemplate = { .Null = { .SegmentLimit_15_0 = 0x0, .BaseAddress_15_0 = 0x0, @@ -249,7 +249,7 @@ InitGlobalDescriptorTable ( ) { EFI_STATUS Status; - GDT_ENTRIES *Gdt; + GDT *Gdt; IA32_DESCRIPTOR Gdtr; EFI_PHYSICAL_ADDRESS Memory; @@ -267,7 +267,7 @@ InitGlobalDescriptorTable ( ); ASSERT_EFI_ERROR (Status); ASSERT ((Memory != 0) && (Memory < SIZE_4GB)); - Gdt = (GDT_ENTRIES *)(UINTN)Memory; + Gdt = (GDT *)(UINTN)Memory; // // Initialize all GDT entries diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h index d1659293cb..21ad6df184 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h +++ b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h @@ -14,169 +14,15 @@ // Local structure definitions // -#pragma pack (1) - -// -// Global Descriptor Entry structures -// - -typedef struct { - UINT16 SegmentLimit_15_0; - UINT16 BaseAddress_15_0; - UINT8 BaseAddress_23_16; - UINT8 Type : 4; - UINT8 S : 1; - UINT8 DPL : 2; - UINT8 P : 1; - UINT8 SegmentLimit_19_16 : 4; - UINT8 AVL : 1; - UINT8 L : 1; - UINT8 D_B : 1; - UINT8 G : 1; - UINT8 BaseAddress_31_24; -} SEGMENT_DESCRIPTOR; - -typedef struct { - UINT16 SegmentLimit_15_0; - UINT16 BaseAddress_15_0; - UINT8 BaseAddress_23_16; - // - // Type - // - UINT8 Accessed : 1; - UINT8 Writable : 1; - UINT8 ExpansionDirection : 1; - UINT8 IsCode : 1; - UINT8 IsNotSystemSegment : 1; - UINT8 DescriptorPrivilegeLevel : 2; - UINT8 SegmentPresent : 1; - - UINT8 SegmentLimit_19_16 : 4; - UINT8 Available : 1; - UINT8 Reserved : 1; - UINT8 UpperBound : 1; - UINT8 Granularity : 1; - UINT8 BaseAddress_31_24; -} DATA_SEGMENT_32; - -typedef struct { - UINT16 SegmentLimit_15_0; - UINT16 BaseAddress_15_0; - UINT8 BaseAddress_23_16; - // - // Type - // - UINT8 Accessed : 1; - UINT8 Readable : 1; - UINT8 Conforming : 1; - UINT8 IsCode : 1; - UINT8 IsNotSystemSegment : 1; - UINT8 DescriptorPrivilegeLevel : 2; - UINT8 SegmentPresent : 1; - - UINT8 SegmentLimit_19_16 : 4; - UINT8 Available : 1; - UINT8 Reserved : 1; - UINT8 Is32Bit : 1; - UINT8 Granularity : 1; - UINT8 BaseAddress_31_24; -} CODE_SEGMENT_32; - -typedef struct { - UINT32 Reserved1; - UINT8 Reserved2; - // - // Type - // - UINT8 Accessed : 1; - UINT8 Readable : 1; - UINT8 Conforming : 1; - UINT8 IsCode : 1; - UINT8 IsNotSystemSegment : 1; - UINT8 DescriptorPrivilegeLevel : 2; - UINT8 SegmentPresent : 1; - - UINT8 Reserved3 : 4; - UINT8 Available : 1; - UINT8 LongMode : 1; - UINT8 Is32Bit : 1; - UINT8 Granularity : 1; - UINT8 Reserved4; -} CODE_SEGMENT_64; - -typedef struct { - UINT16 SegmentLimit_15_0; - UINT16 BaseAddress_15_0; - UINT8 BaseAddress_23_16; - - UINT8 Type : 4; - UINT8 IsNotSystemSegment : 1; - UINT8 DescriptorPrivilegeLevel : 2; - UINT8 SegmentPresent : 1; - - UINT8 SegmentLimit_19_16 : 4; - UINT8 Reserved : 3; - UINT8 Granularity : 1; - UINT8 BaseAddress_31_24; -} SYSTEM_SEGMENT; - -typedef struct { - UINT16 OffsetInSegment_15_0; - UINT16 SegmentSelector; - - UINT8 ParameterCount : 5; - UINT8 Reserved : 3; - - UINT8 Type : 4; - UINT8 IsNotSystemSegment : 1; - UINT8 DescriptorPrivilegeLevel : 2; - UINT8 SegmentPresent : 1; - UINT16 OffsetInSegment_31_16; -} CALL_GATE_32; - -typedef struct { - CALL_GATE_32 Common; - UINT32 OffsetInSegment_63_31; - UINT32 Reserved; -} CALL_GATE_64; - -typedef union { - DATA_SEGMENT_32 DataSegment32; - CODE_SEGMENT_32 CodeSegment32; - CODE_SEGMENT_64 CodeSegment64; - CALL_GATE_32 CallGate32; - SYSTEM_SEGMENT SystemSegment; - SEGMENT_DESCRIPTOR SegmentDescriptor; -} GDT_ENTRY; - -typedef struct { - SEGMENT_DESCRIPTOR Null; - DATA_SEGMENT_32 Linear; - CODE_SEGMENT_32 LinearCode; - DATA_SEGMENT_32 SysData; - CODE_SEGMENT_32 SysCode; - CODE_SEGMENT_32 SysCode16; - DATA_SEGMENT_32 LinearData64; - CODE_SEGMENT_64 LinearCode64; - SEGMENT_DESCRIPTOR Spare5; - DATA_SEGMENT_32 Ring3Data64; - CODE_SEGMENT_64 Ring3Code64; - // CALL_GATE_64 FromRing3ToRing0; -} GDT_ENTRIES; - -#pragma pack () - -#define NULL_SEL OFFSET_OF (GDT_ENTRIES, Null) -#define LINEAR_SEL OFFSET_OF (GDT_ENTRIES, Linear) -#define LINEAR_CODE_SEL OFFSET_OF (GDT_ENTRIES, LinearCode) -#define SYS_DATA_SEL OFFSET_OF (GDT_ENTRIES, SysData) -#define SYS_CODE_SEL OFFSET_OF (GDT_ENTRIES, SysCode) -#define SYS_CODE16_SEL OFFSET_OF (GDT_ENTRIES, SysCode16) -#define LINEAR_DATA64_SEL OFFSET_OF (GDT_ENTRIES, LinearData64) -#define LINEAR_CODE64_SEL OFFSET_OF (GDT_ENTRIES, LinearCode64) -#define SPARE5_SEL OFFSET_OF (GDT_ENTRIES, Spare5) -#define RING3_DATA64_SEL OFFSET_OF (GDT_ENTRIES, Ring3Data64) -#define RING3_CODE64_SEL OFFSET_OF (GDT_ENTRIES, Ring3Code64) +#define NULL_SEL OFFSET_OF (GDT, Null) +#define LINEAR_SEL OFFSET_OF (GDT, Linear) +#define LINEAR_CODE_SEL OFFSET_OF (GDT, LinearCode) +#define SYS_DATA_SEL OFFSET_OF (GDT, SysData) +#define SYS_CODE_SEL OFFSET_OF (GDT, SysCode) +#define SYS_CODE16_SEL OFFSET_OF (GDT, SysCode16) +#define LINEAR_DATA64_SEL OFFSET_OF (GDT, LinearData64) +#define LINEAR_CODE64_SEL OFFSET_OF (GDT, LinearCode64) +#define SPARE5_SEL OFFSET_OF (GDT, Spare5) #if defined (MDE_CPU_IA32) #define CPU_CODE_SEL LINEAR_CODE_SEL From 81e47cc0a8d4c711d64bb0f95337a45cb0d850bd Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 16 Jan 2024 20:42:10 +0300 Subject: [PATCH 127/341] MdePkg: Added Ring3UefiBootServicesTableLib draft. --- .../Ring3UefiBootServicesTableLib/Ring3.h | 999 ++++++++++++++++++ .../Ring3UefiBootServicesTableLib.c | 561 ++++++++++ .../Ring3UefiBootServicesTableLib.inf | 34 + .../Ring3UefiBootServicesTableLib.uni | 12 + 4 files changed, 1606 insertions(+) create mode 100644 MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h create mode 100644 MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c create mode 100644 MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf create mode 100644 MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.uni diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h new file mode 100644 index 0000000000..eb2b5ff660 --- /dev/null +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h @@ -0,0 +1,999 @@ +/** + Raise the task priority level to the new level. + High level is implemented by disabling processor interrupts. + + @param NewTpl New task priority level + + @return The previous task priority level + +**/ +EFI_TPL +EFIAPI +Ring3RaiseTpl ( + IN EFI_TPL NewTpl + ); + +/** + Lowers the task priority to the previous value. If the new + priority unmasks events at a higher priority, they are dispatched. + + @param NewTpl New, lower, task priority + +**/ +VOID +EFIAPI +Ring3RestoreTpl ( + IN EFI_TPL NewTpl + ); + +/** + Allocates pages from the memory map. + + @param Type The type of allocation to perform + @param MemoryType The type of memory to turn the allocated pages + into + @param NumberOfPages The number of pages to allocate + @param Memory A pointer to receive the base allocated memory + address + + @return Status. On success, Memory is filled in with the base address allocated + @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in + spec. + @retval EFI_NOT_FOUND Could not allocate pages match the requirement. + @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. + @retval EFI_SUCCESS Pages successfully allocated. + +**/ +EFI_STATUS +EFIAPI +Ring3AllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +/** + Frees previous allocated pages. + + @param Memory Base address of memory being freed + @param NumberOfPages The number of pages to free + + @retval EFI_NOT_FOUND Could not find the entry that covers the range + @retval EFI_INVALID_PARAMETER Address not aligned + @return EFI_SUCCESS -Pages successfully freed. + +**/ +EFI_STATUS +EFIAPI +Ring3FreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ); + +/** + This function returns a copy of the current memory map. The map is an array of + memory descriptors, each of which describes a contiguous block of memory. + + @param MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the buffer allocated by the caller. On output, + it is the size of the buffer returned by the + firmware if the buffer was large enough, or the + size of the buffer needed to contain the map if + the buffer was too small. + @param MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param MapKey A pointer to the location in which firmware + returns the key for the current memory map. + @param DescriptorSize A pointer to the location in which firmware + returns the size, in bytes, of an individual + EFI_MEMORY_DESCRIPTOR. + @param DescriptorVersion A pointer to the location in which firmware + returns the version number associated with the + EFI_MEMORY_DESCRIPTOR. + + @retval EFI_SUCCESS The memory map was returned in the MemoryMap + buffer. + @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current + buffer size needed to hold the memory map is + returned in MemoryMapSize. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +Ring3GetMemoryMap ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ); + +/** + Allocate pool of a particular type. + + @param PoolType Type of pool to allocate + @param Size The amount of pool to allocate + @param Buffer The address to return a pointer to the allocated + pool + + @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL + @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. + @retval EFI_SUCCESS Pool successfully allocated. + +**/ +EFI_STATUS +EFIAPI +Ring3AllocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +/** + Frees pool. + + @param Buffer The allocated pool entry to free + + @retval EFI_INVALID_PARAMETER Buffer is not a valid value. + @retval EFI_SUCCESS Pool successfully freed. + +**/ +EFI_STATUS +EFIAPI +Ring3FreePool ( + IN VOID *Buffer + ); + +/** + Creates an event. + + @param Type The type of event to create and its mode and + attributes + @param NotifyTpl The task priority level of event notifications + @param NotifyFunction Pointer to the events notification function + @param NotifyContext Pointer to the notification functions context; + corresponds to parameter "Context" in the + notification function + @param Event Pointer to the newly created event if the call + succeeds; undefined otherwise + + @retval EFI_SUCCESS The event structure was created + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + @retval EFI_OUT_OF_RESOURCES The event could not be allocated + +**/ +EFI_STATUS +EFIAPI +Ring3CreateEvent ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN VOID *NotifyContext OPTIONAL, + OUT EFI_EVENT *Event + ); + +/** + Sets the type of timer and the trigger time for a timer event. + + @param UserEvent The timer event that is to be signaled at the + specified time + @param Type The type of time that is specified in + TriggerTime + @param TriggerTime The number of 100ns units until the timer + expires + + @retval EFI_SUCCESS The event has been set to be signaled at the + requested time + @retval EFI_INVALID_PARAMETER Event or Type is not valid + +**/ +EFI_STATUS +EFIAPI +Ring3SetTimer ( + IN EFI_EVENT UserEvent, + IN EFI_TIMER_DELAY Type, + IN UINT64 TriggerTime + ); + +/** + Stops execution until an event is signaled. + + @param NumberOfEvents The number of events in the UserEvents array + @param UserEvents An array of EFI_EVENT + @param UserIndex Pointer to the index of the event which + satisfied the wait condition + + @retval EFI_SUCCESS The event indicated by Index was signaled. + @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification + function or Event was not a valid type + @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION + +**/ +EFI_STATUS +EFIAPI +Ring3WaitForEvent ( + IN UINTN NumberOfEvents, + IN EFI_EVENT *UserEvents, + OUT UINTN *UserIndex + ); + +/** + Signals the event. Queues the event to be notified if needed. + + @param UserEvent The event to signal . + + @retval EFI_INVALID_PARAMETER Parameters are not valid. + @retval EFI_SUCCESS The event was signaled. + +**/ +EFI_STATUS +EFIAPI +Ring3SignalEvent ( + IN EFI_EVENT UserEvent + ); + +/** + Closes an event and frees the event structure. + + @param UserEvent Event to close + + @retval EFI_INVALID_PARAMETER Parameters are not valid. + @retval EFI_SUCCESS The event has been closed + +**/ +EFI_STATUS +EFIAPI +Ring3CloseEvent ( + IN EFI_EVENT UserEvent + ); + +/** + Check the status of an event. + + @param UserEvent The event to check + + @retval EFI_SUCCESS The event is in the signaled state + @retval EFI_NOT_READY The event is not in the signaled state + @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL + +**/ +EFI_STATUS +EFIAPI +Ring3CheckEvent ( + IN EFI_EVENT UserEvent + ); + +/** + Wrapper function to CoreInstallProtocolInterfaceNotify. This is the public API which + Calls the private one which contains a BOOLEAN parameter for notifications + + @param UserHandle The handle to install the protocol handler on, + or NULL if a new handle is to be allocated + @param Protocol The protocol to add to the handle + @param InterfaceType Indicates whether Interface is supplied in + native form. + @param Interface The interface for the protocol being added + + @return Status code + +**/ +EFI_STATUS +EFIAPI +Ring3InstallProtocolInterface ( + IN OUT EFI_HANDLE *UserHandle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface + ); + +/** + Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface. + + @param UserHandle Handle on which the interface is to be + reinstalled + @param Protocol The numeric ID of the interface + @param OldInterface A pointer to the old interface + @param NewInterface A pointer to the new interface + + @retval EFI_SUCCESS The protocol interface was installed + @retval EFI_NOT_FOUND The OldInterface on the handle was not found + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + +**/ +EFI_STATUS +EFIAPI +Ring3ReinstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *OldInterface, + IN VOID *NewInterface + ); + +/** + Uninstalls all instances of a protocol:interfacer from a handle. + If the last protocol interface is remove from the handle, the + handle is freed. + + @param UserHandle The handle to remove the protocol handler from + @param Protocol The protocol, of protocol:interface, to remove + @param Interface The interface, of protocol:interface, to remove + + @retval EFI_INVALID_PARAMETER Protocol is NULL. + @retval EFI_SUCCESS Protocol interface successfully uninstalled. + +**/ +EFI_STATUS +EFIAPI +Ring3UninstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ); + +/** + Queries a handle to determine if it supports a specified protocol. + + @param UserHandle The handle being queried. + @param Protocol The published unique identifier of the protocol. + @param Interface Supplies the address where a pointer to the + corresponding Protocol Interface is returned. + + @return The requested protocol interface for the handle + +**/ +EFI_STATUS +EFIAPI +Ring3HandleProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ); + +/** + Add a new protocol notification record for the request protocol. + + @param Protocol The requested protocol to add the notify + registration + @param Event The event to signal + @param Registration Returns the registration record + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCCESS Successfully returned the registration record + that has been added + +**/ +EFI_STATUS +EFIAPI +Ring3RegisterProtocolNotify ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration + ); + +/** + Locates the requested handle(s) and returns them in Buffer. + + @param SearchType The type of search to perform to locate the + handles + @param Protocol The protocol to search for + @param SearchKey Dependant on SearchType + @param BufferSize On input the size of Buffer. On output the + size of data returned. + @param Buffer The buffer to return the results in + + @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is + returned in BufferSize. + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCCESS Successfully found the requested handle(s) and + returns them in Buffer. + +**/ +EFI_STATUS +EFIAPI +Ring3LocateHandle ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ); + +/** + Locates the handle to a device on the device path that best matches the specified protocol. + + @param Protocol The protocol to search for. + @param DevicePath On input, a pointer to a pointer to the device + path. On output, the device path pointer is + modified to point to the remaining part of the + devicepath. + @param Device A pointer to the returned device handle. + + @retval EFI_SUCCESS The resulting handle was returned. + @retval EFI_NOT_FOUND No handles matched the search. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +Ring3LocateDevicePath ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT EFI_HANDLE *Device + ); + +/** + Boot Service called to add, modify, or remove a system configuration table from + the EFI System Table. + + @param Guid Pointer to the GUID for the entry to add, update, or + remove + @param Table Pointer to the configuration table for the entry to add, + update, or remove, may be NULL. + + @return EFI_SUCCESS Guid, Table pair added, updated, or removed. + @return EFI_INVALID_PARAMETER Input GUID not valid. + @return EFI_NOT_FOUND Attempted to delete non-existant entry + @return EFI_OUT_OF_RESOURCES Not enough memory available + +**/ +EFI_STATUS +EFIAPI +Ring3InstallConfigurationTable ( + IN EFI_GUID *Guid, + IN VOID *Table + ); + +/** + Loads an EFI image into memory and returns a handle to the image. + + @param BootPolicy If TRUE, indicates that the request originates + from the boot manager, and that the boot + manager is attempting to load FilePath as a + boot selection. + @param ParentImageHandle The caller's image handle. + @param FilePath The specific file path from which the image is + loaded. + @param SourceBuffer If not NULL, a pointer to the memory location + containing a copy of the image to be loaded. + @param SourceSize The size in bytes of SourceBuffer. + @param ImageHandle Pointer to the returned image handle that is + created when the image is successfully loaded. + + @retval EFI_SUCCESS The image was loaded into memory. + @retval EFI_NOT_FOUND The FilePath was not found. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_UNSUPPORTED The image type is not supported, or the device + path cannot be parsed to locate the proper + protocol for loading the file. + @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient + resources. + @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not + understood. + @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error. + @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the + image from being loaded. NULL is returned in *ImageHandle. + @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a + valid EFI_LOADED_IMAGE_PROTOCOL. However, the current + platform policy specifies that the image should not be started. + +**/ +EFI_STATUS +EFIAPI +Ring3LoadImage ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ); + +/** + Transfer control to a loaded image's entry point. + + @param ImageHandle Handle of image to be started. + @param ExitDataSize Pointer of the size to ExitData + @param ExitData Pointer to a pointer to a data buffer that + includes a Null-terminated string, + optionally followed by additional binary data. + The string is a description that the caller may + use to further indicate the reason for the + image's exit. + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate + @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started. + @retval EFI_SUCCESS Successfully transfer control to the image's + entry point. + +**/ +EFI_STATUS +EFIAPI +Ring3StartImage ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ); + +/** + Terminates the currently loaded EFI image and returns control to boot services. + + @param ImageHandle Handle that identifies the image. This + parameter is passed to the image on entry. + @param Status The image's exit code. + @param ExitDataSize The size, in bytes, of ExitData. Ignored if + ExitStatus is EFI_SUCCESS. + @param ExitData Pointer to a data buffer that includes a + Null-terminated Unicode string, optionally + followed by additional binary data. The string + is a description that the caller may use to + further indicate the reason for the image's + exit. + + @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current + image. + @retval EFI_SUCCESS Successfully terminates the currently loaded + EFI image. + @retval EFI_ACCESS_DENIED Should never reach there. + @retval EFI_OUT_OF_RESOURCES Could not allocate pool + +**/ +EFI_STATUS +EFIAPI +Ring3Exit ( + IN EFI_HANDLE ImageHandle, + IN EFI_STATUS Status, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ); + +/** + Unloads an image. + + @param ImageHandle Handle that identifies the image to be + unloaded. + + @retval EFI_SUCCESS The image has been unloaded. + @retval EFI_UNSUPPORTED The image has been started, and does not support + unload. + @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle. + +**/ +EFI_STATUS +EFIAPI +Ring3UnloadImage ( + IN EFI_HANDLE ImageHandle + ); + +/** + Terminates all boot services. + + @param ImageHandle Handle that identifies the exiting image. + @param MapKey Key to the latest memory map. + + @retval EFI_SUCCESS Boot Services terminated + @retval EFI_INVALID_PARAMETER MapKey is incorrect. + +**/ +EFI_STATUS +EFIAPI +Ring3ExitBootServices ( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey + ); + +/** + Returns a monotonically increasing count for the platform. + + @param[out] Count The pointer to returned value. + + @retval EFI_SUCCESS The next monotonic count was returned. + @retval EFI_INVALID_PARAMETER Count is NULL. + @retval EFI_DEVICE_ERROR The device is not functioning properly. + +**/ +EFI_STATUS +EFIAPI +Ring3GetNextMonotonicCount ( + OUT UINT64 *Count + ); + +/** + Introduces a fine-grained stall. + + @param Microseconds The number of microseconds to stall execution. + + @retval EFI_SUCCESS Execution was stalled for at least the requested + amount of microseconds. + @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet + +**/ +EFI_STATUS +EFIAPI +Ring3Stall ( + IN UINTN Microseconds + ); + +/** + Sets the system's watchdog timer. + + @param Timeout The number of seconds to set the watchdog timer to. + A value of zero disables the timer. + @param WatchdogCode The numeric code to log on a watchdog timer timeout + event. The firmware reserves codes 0x0000 to 0xFFFF. + Loaders and operating systems may use other timeout + codes. + @param DataSize The size, in bytes, of WatchdogData. + @param WatchdogData A data buffer that includes a Null-terminated Unicode + string, optionally followed by additional binary data. + The string is a description that the call may use to + further indicate the reason to be logged with a + watchdog event. + + @return EFI_SUCCESS Timeout has been set + @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet + @return EFI_UNSUPPORTED System does not have a timer (currently not used) + @return EFI_DEVICE_ERROR Could not complete due to hardware error + +**/ +EFI_STATUS +EFIAPI +Ring3SetWatchdogTimer ( + IN UINTN Timeout, + IN UINT64 WatchdogCode, + IN UINTN DataSize, + IN CHAR16 *WatchdogData OPTIONAL + ); + +/** + Connects one or more drivers to a controller. + + @param ControllerHandle The handle of the controller to which driver(s) are to be connected. + @param DriverImageHandle A pointer to an ordered list handles that support the + EFI_DRIVER_BINDING_PROTOCOL. + @param RemainingDevicePath A pointer to the device path that specifies a child of the + controller specified by ControllerHandle. + @param Recursive If TRUE, then ConnectController() is called recursively + until the entire tree of controllers below the controller specified + by ControllerHandle have been created. If FALSE, then + the tree of controllers is only expanded one level. + + @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle. + 2) No drivers were connected to ControllerHandle, but + RemainingDevicePath is not NULL, and it is an End Device + Path Node. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances + present in the system. + 2) No drivers were connected to ControllerHandle. + @retval EFI_SECURITY_VIOLATION + The user has no permission to start UEFI device drivers on the device path + associated with the ControllerHandle or specified by the RemainingDevicePath. + +**/ +EFI_STATUS +EFIAPI +Ring3ConnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE *DriverImageHandle OPTIONAL, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, + IN BOOLEAN Recursive + ); + +/** + Disonnects a controller from a driver + + @param ControllerHandle ControllerHandle The handle of + the controller from which + driver(s) are to be + disconnected. + @param DriverImageHandle DriverImageHandle The driver to + disconnect from ControllerHandle. + @param ChildHandle ChildHandle The handle of the + child to destroy. + + @retval EFI_SUCCESS One or more drivers were + disconnected from the controller. + @retval EFI_SUCCESS On entry, no drivers are managing + ControllerHandle. + @retval EFI_SUCCESS DriverImageHandle is not NULL, + and on entry DriverImageHandle is + not managing ControllerHandle. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL, + and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it + is not a valid EFI_HANDLE. + @retval EFI_OUT_OF_RESOURCES There are not enough resources + available to disconnect any + drivers from ControllerHandle. + @retval EFI_DEVICE_ERROR The controller could not be + disconnected because of a device + error. + +**/ +EFI_STATUS +EFIAPI +Ring3DisconnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverImageHandle OPTIONAL, + IN EFI_HANDLE ChildHandle OPTIONAL + ); + +/** + Locates the installed protocol handler for the handle, and + invokes it to obtain the protocol interface. Usage information + is registered in the protocol data base. + + @param UserHandle The handle to obtain the protocol interface on + @param Protocol The ID of the protocol + @param Interface The location to return the protocol interface + @param ImageHandle The handle of the Image that is opening the + protocol interface specified by Protocol and + Interface. + @param ControllerHandle The controller handle that is requiring this + interface. + @param Attributes The open mode of the protocol interface + specified by Handle and Protocol. + + @retval EFI_INVALID_PARAMETER Protocol is NULL. + @retval EFI_SUCCESS Get the protocol interface. + +**/ +EFI_STATUS +EFIAPI +Ring3OpenProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface OPTIONAL, + IN EFI_HANDLE ImageHandle, + IN EFI_HANDLE ControllerHandle, + IN UINT32 Attributes + ); + +/** + Closes a protocol on a handle that was opened using OpenProtocol(). + + @param UserHandle The handle for the protocol interface that was + previously opened with OpenProtocol(), and is + now being closed. + @param Protocol The published unique identifier of the protocol. + It is the caller's responsibility to pass in a + valid GUID. + @param AgentHandle The handle of the agent that is closing the + protocol interface. + @param ControllerHandle If the agent that opened a protocol is a driver + that follows the EFI Driver Model, then this + parameter is the controller handle that required + the protocol interface. If the agent does not + follow the EFI Driver Model, then this parameter + is optional and may be NULL. + + @retval EFI_SUCCESS The protocol instance was closed. + @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a + valid EFI_HANDLE. + @retval EFI_NOT_FOUND Can not find the specified protocol or + AgentHandle. + +**/ +EFI_STATUS +EFIAPI +Ring3CloseProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN EFI_HANDLE AgentHandle, + IN EFI_HANDLE ControllerHandle + ); + +/** + Return information about Opened protocols in the system + + @param UserHandle The handle to close the protocol interface on + @param Protocol The ID of the protocol + @param EntryBuffer A pointer to a buffer of open protocol + information in the form of + EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures. + @param EntryCount Number of EntryBuffer entries + +**/ +EFI_STATUS +EFIAPI +Ring3OpenProtocolInformation ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, + OUT UINTN *EntryCount + ); + +/** + Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated + from pool. + + @param UserHandle The handle from which to retrieve the list of + protocol interface GUIDs. + @param ProtocolBuffer A pointer to the list of protocol interface GUID + pointers that are installed on Handle. + @param ProtocolBufferCount A pointer to the number of GUID pointers present + in ProtocolBuffer. + + @retval EFI_SUCCESS The list of protocol interface GUIDs installed + on Handle was returned in ProtocolBuffer. The + number of protocol interface GUIDs was returned + in ProtocolBufferCount. + @retval EFI_INVALID_PARAMETER Handle is NULL. + @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL. + @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the + results. + +**/ +EFI_STATUS +EFIAPI +Ring3ProtocolsPerHandle ( + IN EFI_HANDLE UserHandle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount + ); + +/** + Function returns an array of handles that support the requested protocol + in a buffer allocated from pool. This is a version of Ring3LocateHandle() + that allocates a buffer for the caller. + + @param SearchType Specifies which handle(s) are to be returned. + @param Protocol Provides the protocol to search by. This + parameter is only valid for SearchType + ByProtocol. + @param SearchKey Supplies the search key depending on the + SearchType. + @param NumberHandles The number of handles returned in Buffer. + @param Buffer A pointer to the buffer to return the requested + array of handles that support Protocol. + + @retval EFI_SUCCESS The result array of handles was returned. + @retval EFI_NOT_FOUND No handles match the search. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the + matching results. + @retval EFI_INVALID_PARAMETER One or more parameters are not valid. + +**/ +EFI_STATUS +EFIAPI +Ring3LocateHandleBuffer ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer + ); + +/** + Return the first Protocol Interface that matches the Protocol GUID. If + Registration is passed in, return a Protocol Instance that was just add + to the system. If Registration is NULL return the first Protocol Interface + you find. + + @param Protocol The protocol to search for + @param Registration Optional Registration Key returned from + RegisterProtocolNotify() + @param Interface Return the Protocol interface (instance). + + @retval EFI_SUCCESS If a valid Interface is returned + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_NOT_FOUND Protocol interface not found + +**/ +EFI_STATUS +EFIAPI +Ring3LocateProtocol ( + IN EFI_GUID *Protocol, + IN VOID *Registration OPTIONAL, + OUT VOID **Interface + ); + +/** + Installs a list of protocol interface into the boot services environment. + This function calls InstallProtocolInterface() in a loop. If any error + occures all the protocols added by this function are removed. This is + basically a lib function to save space. + + @param Handle The handle to install the protocol handlers on, + or NULL if a new handle is to be allocated + @param ... EFI_GUID followed by protocol instance. A NULL + terminates the list. The pairs are the + arguments to InstallProtocolInterface(). All the + protocols are added to Handle. + + @retval EFI_SUCCESS All the protocol interface was installed. + @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols. + @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in + the handle database. + @retval EFI_INVALID_PARAMETER Handle is NULL. + @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle. + +**/ +EFI_STATUS +EFIAPI +Ring3InstallMultipleProtocolInterfaces ( + IN OUT EFI_HANDLE *Handle, + ... + ); + +/** + Uninstalls a list of protocol interface in the boot services environment. + This function calls UnisatllProtocolInterface() in a loop. This is + basically a lib function to save space. + + @param Handle The handle to uninstall the protocol + @param ... EFI_GUID followed by protocol instance. A NULL + terminates the list. The pairs are the + arguments to UninstallProtocolInterface(). All + the protocols are added to Handle. + + @return Status code + +**/ +EFI_STATUS +EFIAPI +Ring3UninstallMultipleProtocolInterfaces ( + IN EFI_HANDLE Handle, + ... + ); + +/** + Computes and returns a 32-bit CRC for a data buffer. + + @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed. + @param[in] DataSize The number of bytes in the buffer Data. + @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data + and DataSize. + + @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in + Crc32. + @retval EFI_INVALID_PARAMETER Data is NULL. + @retval EFI_INVALID_PARAMETER Crc32 is NULL. + @retval EFI_INVALID_PARAMETER DataSize is 0. + +**/ +EFI_STATUS +EFIAPI +Ring3CalculateCrc32 ( + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 + ); + +/** + Creates an event in a group. + + @param Type The type of event to create and its mode and + attributes + @param NotifyTpl The task priority level of event notifications + @param NotifyFunction Pointer to the events notification function + @param NotifyContext Pointer to the notification functions context; + corresponds to parameter "Context" in the + notification function + @param EventGroup GUID for EventGroup if NULL act the same as + gBS->CreateEvent(). + @param Event Pointer to the newly created event if the call + succeeds; undefined otherwise + + @retval EFI_SUCCESS The event structure was created + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + @retval EFI_OUT_OF_RESOURCES The event could not be allocated + +**/ +EFI_STATUS +EFIAPI +Ring3CreateEventEx ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN CONST VOID *NotifyContext OPTIONAL, + IN CONST EFI_GUID *EventGroup OPTIONAL, + OUT EFI_EVENT *Event + ); diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c new file mode 100644 index 0000000000..663d74f806 --- /dev/null +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -0,0 +1,561 @@ +/** @file + This library constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include + +#include + +#include "Ring3.h" + +EFI_BOOT_SERVICES mBootServices = { + { + EFI_BOOT_SERVICES_SIGNATURE, // Signature + EFI_BOOT_SERVICES_REVISION, // Revision + sizeof (EFI_BOOT_SERVICES), // HeaderSize + 0, // CRC32 + 0 // Reserved + }, + (EFI_RAISE_TPL)Ring3RaiseTpl, // RaiseTPL + (EFI_RESTORE_TPL)Ring3RestoreTpl, // RestoreTPL + (EFI_ALLOCATE_PAGES)Ring3AllocatePages, // AllocatePages + (EFI_FREE_PAGES)Ring3FreePages, // FreePages + (EFI_GET_MEMORY_MAP)Ring3GetMemoryMap, // GetMemoryMap + (EFI_ALLOCATE_POOL)Ring3AllocatePool, // AllocatePool + (EFI_FREE_POOL)Ring3FreePool, // FreePool + (EFI_CREATE_EVENT)Ring3CreateEvent, // CreateEvent + (EFI_SET_TIMER)Ring3SetTimer, // SetTimer + (EFI_WAIT_FOR_EVENT)Ring3WaitForEvent, // WaitForEvent + (EFI_SIGNAL_EVENT)Ring3SignalEvent, // SignalEvent + (EFI_CLOSE_EVENT)Ring3CloseEvent, // CloseEvent + (EFI_CHECK_EVENT)Ring3CheckEvent, // CheckEvent + (EFI_INSTALL_PROTOCOL_INTERFACE)Ring3InstallProtocolInterface, // InstallProtocolInterface + (EFI_REINSTALL_PROTOCOL_INTERFACE)Ring3ReinstallProtocolInterface, // ReinstallProtocolInterface + (EFI_UNINSTALL_PROTOCOL_INTERFACE)Ring3UninstallProtocolInterface, // UninstallProtocolInterface + (EFI_HANDLE_PROTOCOL)Ring3HandleProtocol, // HandleProtocol + (VOID *)NULL, // Reserved + (EFI_REGISTER_PROTOCOL_NOTIFY)Ring3RegisterProtocolNotify, // RegisterProtocolNotify + (EFI_LOCATE_HANDLE)Ring3LocateHandle, // LocateHandle + (EFI_LOCATE_DEVICE_PATH)Ring3LocateDevicePath, // LocateDevicePath + (EFI_INSTALL_CONFIGURATION_TABLE)Ring3InstallConfigurationTable, // InstallConfigurationTable + (EFI_IMAGE_LOAD)Ring3LoadImage, // LoadImage + (EFI_IMAGE_START)Ring3StartImage, // StartImage + (EFI_EXIT)Ring3Exit, // Exit + (EFI_IMAGE_UNLOAD)Ring3UnloadImage, // UnloadImage + (EFI_EXIT_BOOT_SERVICES)Ring3ExitBootServices, // ExitBootServices + (EFI_GET_NEXT_MONOTONIC_COUNT)Ring3GetNextMonotonicCount, // GetNextMonotonicCount + (EFI_STALL)Ring3Stall, // Stall + (EFI_SET_WATCHDOG_TIMER)Ring3SetWatchdogTimer, // SetWatchdogTimer + (EFI_CONNECT_CONTROLLER)Ring3ConnectController, // ConnectController + (EFI_DISCONNECT_CONTROLLER)Ring3DisconnectController, // DisconnectController + (EFI_OPEN_PROTOCOL)Ring3OpenProtocol, // OpenProtocol + (EFI_CLOSE_PROTOCOL)Ring3CloseProtocol, // CloseProtocol + (EFI_OPEN_PROTOCOL_INFORMATION)Ring3OpenProtocolInformation, // OpenProtocolInformation + (EFI_PROTOCOLS_PER_HANDLE)Ring3ProtocolsPerHandle, // ProtocolsPerHandle + (EFI_LOCATE_HANDLE_BUFFER)Ring3LocateHandleBuffer, // LocateHandleBuffer + (EFI_LOCATE_PROTOCOL)Ring3LocateProtocol, // LocateProtocol + (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3InstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces + (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3UninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces + (EFI_CALCULATE_CRC32)Ring3CalculateCrc32, // CalculateCrc32 + (EFI_COPY_MEM)CopyMem, // CopyMem + (EFI_SET_MEM)SetMem, // SetMem + (EFI_CREATE_EVENT_EX)Ring3CreateEventEx // CreateEventEx +}; + +// EFI_HANDLE gImageHandle = NULL; +// EFI_SYSTEM_TABLE *gST = NULL; +EFI_BOOT_SERVICES *gBS = &mBootServices; + +/** + The function constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +UefiBootServicesTableLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + // + // Cache the Image Handle + // + // gImageHandle = ImageHandle; + // ASSERT (gImageHandle != NULL); + + // + // Cache pointer to the EFI System Table + // + // gST = SystemTable; + // ASSERT (gST != NULL); + + // + // Cache pointer to the EFI Boot Services Table + // + // gBS = SystemTable->BootServices; + // ASSERT (gBS != NULL); + + return EFI_SUCCESS; +} + +EFI_TPL +EFIAPI +Ring3RaiseTpl ( + IN EFI_TPL NewTpl + ) +{ + return NewTpl; +} + +VOID +EFIAPI +Ring3RestoreTpl ( + IN EFI_TPL NewTpl + ) +{ + +} + +EFI_STATUS +EFIAPI +Ring3AllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3FreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3GetMemoryMap ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3AllocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3FreePool ( + IN VOID *Buffer + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3CreateEvent ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN VOID *NotifyContext OPTIONAL, + OUT EFI_EVENT *Event + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3SetTimer ( + IN EFI_EVENT UserEvent, + IN EFI_TIMER_DELAY Type, + IN UINT64 TriggerTime + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3WaitForEvent ( + IN UINTN NumberOfEvents, + IN EFI_EVENT *UserEvents, + OUT UINTN *UserIndex + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3SignalEvent ( + IN EFI_EVENT UserEvent + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3CloseEvent ( + IN EFI_EVENT UserEvent + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3CheckEvent ( + IN EFI_EVENT UserEvent + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3InstallProtocolInterface ( + IN OUT EFI_HANDLE *UserHandle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3ReinstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *OldInterface, + IN VOID *NewInterface + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3UninstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3HandleProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3RegisterProtocolNotify ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3LocateHandle ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3LocateDevicePath ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT EFI_HANDLE *Device + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3InstallConfigurationTable ( + IN EFI_GUID *Guid, + IN VOID *Table + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3LoadImage ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3StartImage ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3Exit ( + IN EFI_HANDLE ImageHandle, + IN EFI_STATUS Status, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3UnloadImage ( + IN EFI_HANDLE ImageHandle + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3ExitBootServices ( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3GetNextMonotonicCount ( + OUT UINT64 *Count + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3Stall ( + IN UINTN Microseconds + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3SetWatchdogTimer ( + IN UINTN Timeout, + IN UINT64 WatchdogCode, + IN UINTN DataSize, + IN CHAR16 *WatchdogData OPTIONAL + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3ConnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE *DriverImageHandle OPTIONAL, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, + IN BOOLEAN Recursive + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3DisconnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverImageHandle OPTIONAL, + IN EFI_HANDLE ChildHandle OPTIONAL + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3OpenProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface OPTIONAL, + IN EFI_HANDLE ImageHandle, + IN EFI_HANDLE ControllerHandle, + IN UINT32 Attributes + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3CloseProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN EFI_HANDLE AgentHandle, + IN EFI_HANDLE ControllerHandle + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3OpenProtocolInformation ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, + OUT UINTN *EntryCount + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3ProtocolsPerHandle ( + IN EFI_HANDLE UserHandle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3LocateHandleBuffer ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3LocateProtocol ( + IN EFI_GUID *Protocol, + IN VOID *Registration OPTIONAL, + OUT VOID **Interface + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3InstallMultipleProtocolInterfaces ( + IN OUT EFI_HANDLE *Handle, + ... + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3UninstallMultipleProtocolInterfaces ( + IN EFI_HANDLE Handle, + ... + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3CalculateCrc32 ( + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 + ) +{ + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +Ring3CreateEventEx ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN CONST VOID *NotifyContext OPTIONAL, + IN CONST EFI_GUID *EventGroup OPTIONAL, + OUT EFI_EVENT *Event + ) +{ + return EFI_SUCCESS; +} diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf new file mode 100644 index 0000000000..fd2b92ed50 --- /dev/null +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf @@ -0,0 +1,34 @@ +## @file +# Ring 3 wrapper for UEFI Boot Services Table Library implementation. +# +# Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Ring3UefiBootServicesTableLib + MODULE_UNI_FILE = Ring3UefiBootServicesTableLib.uni + FILE_GUID = b503b4b4-6dc1-412b-965f-a0f330b1d453 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiBootServicesTableLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER + + CONSTRUCTOR = UefiBootServicesTableLibConstructor + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + Ring3.h + Ring3UefiBootServicesTableLib.c + +[Packages] + MdePkg/MdePkg.dec + + +[LibraryClasses] + BaseMemoryLib diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.uni b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.uni new file mode 100644 index 0000000000..1121e5078f --- /dev/null +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.uni @@ -0,0 +1,12 @@ +// /** @file +// Ring 3 wrapper for UEFI Boot Services Table Library implementation. +// +// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Ring 3 wrapper for UEFI Boot Services Table Library implementation." + +#string STR_MODULE_DESCRIPTION #language en-US "Ring 3 wrapper for UEFI Boot Services Table Library implementation." From fea88557d5936d92ccd384892f2af3708c8ffaa0 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 18 Jan 2024 14:00:47 +0300 Subject: [PATCH 128/341] Ring3: Fixed LibraryConstructors' initialization and allowed user to access ports. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 2 ++ MdeModulePkg/Core/Dxe/Image/Image.c | 9 +++++++++ MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 17b449caa0..05e0f14222 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -194,6 +194,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdImageLargeAddressLoad ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase ## CONSUMES + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize ## CONSUMES # [Hob] # RESOURCE_DESCRIPTOR ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index ead8195baf..5fd119f3f2 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1714,6 +1714,15 @@ CoreStartImage ( TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); // DEBUG ((DEBUG_ERROR, "RING3_CODE64_SEL = 0x%x RING3_DATA64_SEL = 0x%x\n", (UINT16)RING3_CODE64_SEL, (UINT16)RING3_DATA64_SEL)); + // + // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() + // + SetUefiImageMemoryAttributes ( + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + EnterUserImage ( (SWITCH_STACK_ENTRY_POINT)(UINTN)Image->EntryPoint, ImageHandle, diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index a7f2c57614..a70511c187 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -995,6 +995,10 @@ CreateIdentityMappingPageTables ( Eflags.UintN = AsmReadEflags (); Eflags.Bits.AC = 0; + // + // Allow user image to access ports. + // + Eflags.Bits.IOPL = 3; AsmWriteEflags (Eflags.UintN); } From fc33fa2b2c3937c7243f40280ad704cd123b096a Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 22 Jan 2024 17:29:38 +0300 Subject: [PATCH 129/341] Ring3: Added SYSCALL draft. --- MdeModulePkg/Core/Dxe/Image/Image.c | 17 ++++++ .../Core/DxeIplPeim/X64/VirtualMemory.c | 17 +++++- MdePkg/Include/Library/BaseLib.h | 12 +++- MdePkg/Library/BaseLib/X64/SwitchStack.nasm | 46 ++++++++++++++++ .../Ring3UefiBootServicesTableLib/Ring3.h | 15 +++++ .../Ring3UefiBootServicesTableLib.c | 37 +++++++------ .../Ring3UefiBootServicesTableLib.inf | 5 +- .../X64/SysCall.nasm | 26 +++++++++ UefiCpuPkg/Library/CpuArchLib/CpuGdt.c | 55 +++++++------------ .../X64/ArchExceptionHandler.c | 2 - 10 files changed, 173 insertions(+), 59 deletions(-) create mode 100644 MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 5fd119f3f2..d15849f0b2 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -9,6 +9,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "DxeMain.h" #include "Image.h" +#include + // // Module Globals // @@ -1599,6 +1601,7 @@ CoreStartImage ( VOID *BaseOfStack; VOID *TopOfStack; UINTN SizeOfStack; + UINT64 Msr; Handle = ImageHandle; @@ -1713,6 +1716,7 @@ CoreStartImage ( TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); // DEBUG ((DEBUG_ERROR, "RING3_CODE64_SEL = 0x%x RING3_DATA64_SEL = 0x%x\n", (UINT16)RING3_CODE64_SEL, (UINT16)RING3_DATA64_SEL)); + // DEBUG ((DEBUG_ERROR, "Core: BootServices = %p\n", Image->Info.SystemTable->BootServices)); // // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() @@ -1723,6 +1727,19 @@ CoreStartImage ( EFI_MEMORY_XP | EFI_MEMORY_USER ); + // + // Initialize MSR_IA32_STAR and MSR_IA32_LSTAR for SYSCALL and SYSRET. + // + Msr = ((((UINT64)RING3_CODE64_SEL - 16) << 16) | (UINT64)RING0_CODE64_SEL) << 32; + AsmWriteMsr64 (MSR_IA32_STAR, Msr); + + Msr = (UINT64)(UINTN)CoreBootServices; + AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); + + // protection keys + // Software can access the old stack, if necessary, by referencing the old + // stack-segment selector and stack pointer saved on the new process stack. + EnterUserImage ( (SWITCH_STACK_ENTRY_POINT)(UINTN)Image->EntryPoint, ImageHandle, diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index a70511c187..4d29050336 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -22,7 +22,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ +#include #include + #include "DxeIpl.h" #include "VirtualMemory.h" @@ -708,8 +710,11 @@ CreateIdentityMappingPageTables ( IA32_CR4 Cr4; IA32_EFLAGS32 Eflags; UINT32 Ebx; + UINT32 Edx; + MSR_IA32_EFER_REGISTER MsrEfer; Ebx = 0; + Edx = 0; // // Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings @@ -987,7 +992,11 @@ CreateIdentityMappingPageTables ( // SMEP and SMAP must be supported. // AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); - if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { + // + // SYSCALL and SYSRET must be also supported. + // + AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); + if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) { Cr4.UintN = AsmReadCr4 (); Cr4.Bits.SMAP = 1; Cr4.Bits.SMEP = 1; @@ -1000,6 +1009,12 @@ CreateIdentityMappingPageTables ( // Eflags.Bits.IOPL = 3; AsmWriteEflags (Eflags.UintN); + // + // Enable SYSCALL and SYSRET + // + MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); + MsrEfer.Bits.SCE = 1; + AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); } return (UINTN)PageMap; diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 8d2a5a509d..570b06ee44 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -5674,16 +5674,17 @@ typedef struct { DATA_SEGMENT_32 SysData; CODE_SEGMENT_32 SysCode; CODE_SEGMENT_32 SysCode16; - DATA_SEGMENT_32 LinearData64; CODE_SEGMENT_64 LinearCode64; + DATA_SEGMENT_32 LinearData64; SEGMENT_DESCRIPTOR Spare5; DATA_SEGMENT_32 Ring3Data64; CODE_SEGMENT_64 Ring3Code64; - // CALL_GATE_64 FromRing3ToRing0; } GDT; #pragma pack () +#define RING0_DATA64_SEL OFFSET_OF (GDT, LinearData64) +#define RING0_CODE64_SEL OFFSET_OF (GDT, LinearCode64) #define RING3_DATA64_SEL OFFSET_OF (GDT, Ring3Data64) #define RING3_CODE64_SEL OFFSET_OF (GDT, Ring3Code64) @@ -6695,6 +6696,13 @@ AsmReadEflags ( VOID ); +UINTN +EFIAPI +CoreBootServices ( + IN UINTN FunctionAddress, + ... + ); + /** Reads the current value of the Control Register 0 (CR0). diff --git a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm index 0f8aa12014..986e5eab41 100644 --- a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm +++ b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm @@ -91,3 +91,49 @@ o16 mov gs, ax ; Pass control to user image retfq + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; CoreBootServices ( +; IN UINTN FunctionAddress, +; ... +; ); +; +; (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). +; (rdx) Argument 1 of the called function. +; (r8) Argument 2 of the called function. +; (r9) Argument 3 of the called function. +; (r10) FunctionAddress. +; (r11) RFLAGS saved by SYSCALL in SysCall(). +;On stack Argument 4, 5, ... +;------------------------------------------------------------------------------ +global ASM_PFX(CoreBootServices) +ASM_PFX(CoreBootServices): + cmp r10, 0 + je readMemory + + ; Save return address and RFLAGS for SYSRET. + mov [rsp], rcx + mov [rsp + 8], r11 + + ; Replace argument according to UEFI calling convention. + mov rcx, rdx + mov rdx, r8 + mov r8, r9 + mov r9, [rsp + 8*3] + + ; Call Boot Service by FunctionAddress. + call r10 + + ; Prepare SYSRET arguments. + mov rcx, [rsp] + mov r11, [rsp + 8] + + ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. +o64 sysret + ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. + +readMemory: + mov rax, [rdx] +o64 sysret diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h index eb2b5ff660..11d8819e4e 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h @@ -1,3 +1,18 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +UINTN +EFIAPI +SysCall ( + IN UINTN FunctionAddress, + ... + ); + + /** Raise the task priority level to the new level. High level is implemented by disabling processor interrupts. diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index 663d74f806..cb5e21107e 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -9,6 +9,7 @@ #include #include +#include #include "Ring3.h" @@ -66,9 +67,8 @@ EFI_BOOT_SERVICES mBootServices = { (EFI_CREATE_EVENT_EX)Ring3CreateEventEx // CreateEventEx }; -// EFI_HANDLE gImageHandle = NULL; -// EFI_SYSTEM_TABLE *gST = NULL; -EFI_BOOT_SERVICES *gBS = &mBootServices; +EFI_BOOT_SERVICES *gBS = &mBootServices; +EFI_BOOT_SERVICES *mCoreBS = NULL; /** The function constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. @@ -86,23 +86,15 @@ UefiBootServicesTableLibConstructor ( IN EFI_SYSTEM_TABLE *SystemTable ) { - // - // Cache the Image Handle - // - // gImageHandle = ImageHandle; - // ASSERT (gImageHandle != NULL); - - // - // Cache pointer to the EFI System Table - // - // gST = SystemTable; - // ASSERT (gST != NULL); - // // Cache pointer to the EFI Boot Services Table // - // gBS = SystemTable->BootServices; - // ASSERT (gBS != NULL); + mCoreBS = (EFI_BOOT_SERVICES *)SysCall ( + 0, + (UINTN)SystemTable + OFFSET_OF (EFI_SYSTEM_TABLE, BootServices) + ); + ASSERT (mCoreBS != NULL); + // DEBUG ((DEBUG_ERROR, "User: BootServices = %p\n", mCoreBS)); return EFI_SUCCESS; } @@ -512,7 +504,16 @@ Ring3LocateProtocol ( OUT VOID **Interface ) { - return EFI_SUCCESS; + EFI_STATUS Status; + + Status = (EFI_STATUS)SysCall ( + (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, LocateProtocol), + Protocol, + Registration, + Interface + ); + + return Status; } EFI_STATUS diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf index fd2b92ed50..f1128c94d3 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf @@ -26,9 +26,12 @@ Ring3.h Ring3UefiBootServicesTableLib.c +[Sources.X64] + X64/SysCall.nasm + [Packages] MdePkg/MdePkg.dec - [LibraryClasses] BaseMemoryLib + DebugLib diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm b/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm new file mode 100644 index 0000000000..64670a6a25 --- /dev/null +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm @@ -0,0 +1,26 @@ +;------------------------------------------------------------------------------ +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +;------------------------------------------------------------------------------ + + DEFAULT REL + SECTION .text + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; SysCall ( +; IN UINTN FunctionAddress, +; ... +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(SysCall) +ASM_PFX(SysCall): + ; Save FunctionAddress for CoreBootServices(). + mov r10, rcx + + ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. + syscall + ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. + + ret diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c index e8047b1207..415d4126aa 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c @@ -129,6 +129,25 @@ STATIC GDT mGdtTemplate = { .Granularity = 1, .BaseAddress_31_24 = 0x0 }, + .LinearCode64 = { + .Reserved1 = 0x0, + .Reserved2 = 0x0, + + .Accessed = 0, + .Readable = 1, + .Conforming = 0, + .IsCode = 1, + .IsNotSystemSegment = 1, + .DescriptorPrivilegeLevel = 0, + .SegmentPresent = 1, + + .Reserved3 = 0x0, + .Available = 0, + .LongMode = 1, + .Is32Bit = 0, + .Granularity = 1, + .Reserved4 = 0x0 + }, .LinearData64 = { .SegmentLimit_15_0 = 0xFFFF, .BaseAddress_15_0 = 0x0, @@ -149,25 +168,6 @@ STATIC GDT mGdtTemplate = { .Granularity = 1, .BaseAddress_31_24 = 0x0 }, - .LinearCode64 = { - .Reserved1 = 0x0, - .Reserved2 = 0x0, - - .Accessed = 0, - .Readable = 1, - .Conforming = 0, - .IsCode = 1, - .IsNotSystemSegment = 1, - .DescriptorPrivilegeLevel = 0, - .SegmentPresent = 1, - - .Reserved3 = 0x0, - .Available = 0, - .LongMode = 1, - .Is32Bit = 0, - .Granularity = 1, - .Reserved4 = 0x0 - }, .Spare5 = { .SegmentLimit_15_0 = 0x0, .BaseAddress_15_0 = 0x0, @@ -203,7 +203,7 @@ STATIC GDT mGdtTemplate = { .Granularity = 1, .BaseAddress_31_24 = 0x0 }, - .Ring3Code64 = { // SetCodeSelector () | 5.8.6 Returning from a Called Procedure + .Ring3Code64 = { .Reserved1 = 0x0, .Reserved2 = 0x0, @@ -222,21 +222,6 @@ STATIC GDT mGdtTemplate = { .Granularity = 1, .Reserved4 = 0x0 }, - // .FromRing3ToRing0 = { - // .Common.OffsetInSegment_15_0 = 0x?, - // .Common.SegmentSelector = (UINT16)LINEAR_CODE64_SEL, - // - // .Common.ParameterCount = 0, - // .Common.Reserved = 0, - // - // .Common.Type = 0xC, - // .Common.IsNotSystemSegment = 0, - // .Common.DescriptorPrivilegeLevel = 3, - // .Common.SegmentPresent = 1, - // .Common.OffsetInSegment_31_16 = 0x?, - // .OffsetInSegment_63_31 = 0x?, - // .Reserved = 0x0 - // }, }; /** diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index b1763e756b..4e85880ed4 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -249,8 +249,6 @@ ArchSetupExceptionStack ( IdtTable[Vector].Bits.Reserved_0 = (UINT8)(Index + 1); } - // Tss->RSP0 = %rsp - // // Publish GDT // From 35199885ba89fc87e5597a7abf93fa437e85a4a2 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 23 Jan 2024 19:54:19 +0300 Subject: [PATCH 130/341] Ring3: Added CoreSysCallStack. --- MdeModulePkg/Core/Dxe/Image/Image.c | 35 +++++++++++----- .../Core/DxeIplPeim/X64/VirtualMemory.c | 4 +- MdePkg/Library/BaseLib/X64/SwitchStack.nasm | 40 ++++++++++++++++--- .../Ring3UefiBootServicesTableLib.c | 2 +- 4 files changed, 63 insertions(+), 18 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index d15849f0b2..24498b132c 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -27,6 +27,7 @@ STATIC EFI_EVENT mPeCoffEmuProtocolRegistrationEvent; STATIC VOID *mPeCoffEmuProtocolNotifyRegistration; extern BOOLEAN gBdsStarted; +extern VOID *gCoreSysCallStackTop; // // This code is needed to build the Image handle for the DXE Core @@ -1700,23 +1701,41 @@ CoreStartImage ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; + + // + // Allocate 128KB for the Core SysCall Stack. + // + BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); + ASSERT (BaseOfStack != NULL); + + // + // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. + // + TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + gCoreSysCallStackTop = TopOfStack; + DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); + + SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP); + // // Allocate 128KB for the User Stack. // BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); ASSERT (BaseOfStack != NULL); - SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; - - SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); - // // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. // TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - // DEBUG ((DEBUG_ERROR, "RING3_CODE64_SEL = 0x%x RING3_DATA64_SEL = 0x%x\n", (UINT16)RING3_CODE64_SEL, (UINT16)RING3_DATA64_SEL)); - // DEBUG ((DEBUG_ERROR, "Core: BootServices = %p\n", Image->Info.SystemTable->BootServices)); + + SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); + DEBUG ((DEBUG_ERROR, "Core: UserTopOfStack = %p\n", TopOfStack)); + + DEBUG ((DEBUG_ERROR, "Core: BootServices = %p\n", Image->Info.SystemTable->BootServices)); // // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() @@ -1736,10 +1755,6 @@ CoreStartImage ( Msr = (UINT64)(UINTN)CoreBootServices; AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); - // protection keys - // Software can access the old stack, if necessary, by referencing the old - // stack-segment selector and stack pointer saved on the new process stack. - EnterUserImage ( (SWITCH_STACK_ENTRY_POINT)(UINTN)Image->EntryPoint, ImageHandle, diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index 4d29050336..79c2dbbd0e 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -998,7 +998,7 @@ CreateIdentityMappingPageTables ( AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) { Cr4.UintN = AsmReadCr4 (); - Cr4.Bits.SMAP = 1; + // Cr4.Bits.SMAP = 1; Cr4.Bits.SMEP = 1; AsmWriteCr4 (Cr4.UintN); @@ -1010,7 +1010,7 @@ CreateIdentityMappingPageTables ( Eflags.Bits.IOPL = 3; AsmWriteEflags (Eflags.UintN); // - // Enable SYSCALL and SYSRET + // Enable SYSCALL and SYSRET. // MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); MsrEfer.Bits.SCE = 1; diff --git a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm index 986e5eab41..f7fb758269 100644 --- a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm +++ b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm @@ -113,22 +113,45 @@ ASM_PFX(CoreBootServices): cmp r10, 0 je readMemory + mov ax, ss + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; Save User Stack pointer and switch to Core SysCall Stack. + mov rax, [ASM_PFX(gCoreSysCallStackTop)] + sub rax, 8 + mov [rax], rsp + mov rsp, rax + + push rbp + mov rbp, rsp + ; Save return address and RFLAGS for SYSRET. - mov [rsp], rcx - mov [rsp + 8], r11 + push rcx + push r11 ; Replace argument according to UEFI calling convention. mov rcx, rdx mov rdx, r8 mov r8, r9 - mov r9, [rsp + 8*3] + ; mov r9, [rax + 8*3] + ; mov r11, [rax + 8*4] + ; push r11 + ; ... ; Call Boot Service by FunctionAddress. call r10 ; Prepare SYSRET arguments. - mov rcx, [rsp] - mov r11, [rsp + 8] + pop r11 + pop rcx + + ; Switch to User Stack. + pop rbp + pop rdx + mov rsp, rdx ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. o64 sysret @@ -137,3 +160,10 @@ o64 sysret readMemory: mov rax, [rdx] o64 sysret + + +SECTION .data + +global ASM_PFX(gCoreSysCallStackTop) +ASM_PFX(gCoreSysCallStackTop): + resq 1 diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index cb5e21107e..1d5ae5064f 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -94,7 +94,7 @@ UefiBootServicesTableLibConstructor ( (UINTN)SystemTable + OFFSET_OF (EFI_SYSTEM_TABLE, BootServices) ); ASSERT (mCoreBS != NULL); - // DEBUG ((DEBUG_ERROR, "User: BootServices = %p\n", mCoreBS)); + DEBUG ((DEBUG_ERROR, "User: BootServices = %p\n", mCoreBS)); return EFI_SUCCESS; } From 1fcc570610f52c8a32d75c753e104d41a5f81e76 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 26 Jan 2024 12:29:01 +0300 Subject: [PATCH 131/341] Ring3: Fixed bug in calling Boot Service and did some refactoring. --- MdeModulePkg/Core/Dxe/Image/Image.c | 6 +- .../Core/DxeIplPeim/X64/VirtualMemory.c | 2 +- MdePkg/Library/BaseLib/X64/SwitchStack.nasm | 55 ++++++++++++------- .../Ring3UefiBootServicesTableLib.c | 2 +- 4 files changed, 40 insertions(+), 25 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 24498b132c..84f038a9e4 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1716,9 +1716,9 @@ CoreStartImage ( TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); gCoreSysCallStackTop = TopOfStack; - DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP); + DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); // // Allocate 128KB for the User Stack. @@ -1735,8 +1735,6 @@ CoreStartImage ( SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); DEBUG ((DEBUG_ERROR, "Core: UserTopOfStack = %p\n", TopOfStack)); - DEBUG ((DEBUG_ERROR, "Core: BootServices = %p\n", Image->Info.SystemTable->BootServices)); - // // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() // @@ -1746,6 +1744,8 @@ CoreStartImage ( EFI_MEMORY_XP | EFI_MEMORY_USER ); + DEBUG ((DEBUG_ERROR, "Core: BootServices = 0x%lx\n", (UINTN)Image->Info.SystemTable->BootServices)); + // // Initialize MSR_IA32_STAR and MSR_IA32_LSTAR for SYSCALL and SYSRET. // diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index 79c2dbbd0e..0810cc1aee 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -998,7 +998,7 @@ CreateIdentityMappingPageTables ( AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) { Cr4.UintN = AsmReadCr4 (); - // Cr4.Bits.SMAP = 1; + Cr4.Bits.SMAP = 1; Cr4.Bits.SMEP = 1; AsmWriteCr4 (Cr4.UintN); diff --git a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm index f7fb758269..868d23df87 100644 --- a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm +++ b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm @@ -70,10 +70,10 @@ ASM_PFX(InternalEnterUserImage): mov rax, [rsp + 8*6] or rax, 3H ; RPL = 3 -o16 mov ds, ax -o16 mov es, ax -o16 mov fs, ax -o16 mov gs, ax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax ; Save Code selector mov r10, [rsp + 8*5] @@ -108,10 +108,30 @@ o16 mov gs, ax ; (r11) RFLAGS saved by SYSCALL in SysCall(). ;On stack Argument 4, 5, ... ;------------------------------------------------------------------------------ +%macro CallSysRet 0 +o16 mov ds, r11 +o16 mov es, r11 +o16 mov fs, r11 +o16 mov gs, r11 + + ; Restore RFLAGS in R11 for SYSRET. + pushfq + pop r11 + + ; Switch to User Stack. + pop rbp + pop rdx + mov rsp, rdx + + ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. +o64 sysret + ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. +%endmacro + global ASM_PFX(CoreBootServices) ASM_PFX(CoreBootServices): - cmp r10, 0 - je readMemory + ; Save User data segment selector. + mov r11, ds mov ax, ss mov ds, ax @@ -119,7 +139,7 @@ ASM_PFX(CoreBootServices): mov fs, ax mov gs, ax - ; Save User Stack pointer and switch to Core SysCall Stack. + ; Save User Stack pointers and switch to Core SysCall Stack. mov rax, [ASM_PFX(gCoreSysCallStackTop)] sub rax, 8 mov [rax], rsp @@ -128,9 +148,11 @@ ASM_PFX(CoreBootServices): push rbp mov rbp, rsp - ; Save return address and RFLAGS for SYSRET. + cmp r10, 0 + je readMemory + + ; Save return address for SYSRET. push rcx - push r11 ; Replace argument according to UEFI calling convention. mov rcx, rdx @@ -142,24 +164,17 @@ ASM_PFX(CoreBootServices): ; ... ; Call Boot Service by FunctionAddress. - call r10 + call [r10] ; Prepare SYSRET arguments. - pop r11 pop rcx - ; Switch to User Stack. - pop rbp - pop rdx - mov rsp, rdx - - ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. -o64 sysret - ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. + CallSysRet readMemory: mov rax, [rdx] -o64 sysret + + CallSysRet SECTION .data diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index 1d5ae5064f..cce038ba87 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -94,7 +94,7 @@ UefiBootServicesTableLibConstructor ( (UINTN)SystemTable + OFFSET_OF (EFI_SYSTEM_TABLE, BootServices) ); ASSERT (mCoreBS != NULL); - DEBUG ((DEBUG_ERROR, "User: BootServices = %p\n", mCoreBS)); + DEBUG ((DEBUG_ERROR, "User: BootServices = 0x%lx\n", (UINTN)mCoreBS)); return EFI_SUCCESS; } From a0ad59ec23e3bc5e007db63c24a90fe4efa9ce5c Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 26 Jan 2024 17:01:01 +0300 Subject: [PATCH 132/341] Ring3: Added helper function AllocateRing3Pages() and draft of Ring3LocateProtocol(). --- MdeModulePkg/Core/Dxe/DxeMain.h | 9 +- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 3 +- MdeModulePkg/Core/Dxe/Image/Image.c | 23 +++- MdePkg/Include/Uefi/UefiSpec.h | 8 ++ .../Ring3UefiBootServicesTableLib.c | 115 ++++++++++++------ 5 files changed, 116 insertions(+), 42 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 3b2231eab3..d16309444b 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -1174,6 +1174,13 @@ CoreAllocatePages ( IN OUT EFI_PHYSICAL_ADDRESS *Memory ); +EFI_STATUS +EFIAPI +AllocateRing3Pages ( + IN UINTN NumberOfPages, + IN OUT VOID **Memory + ); + /** Frees previous allocated pages. @@ -1360,7 +1367,7 @@ CoreLoadImage ( @retval EFI_SUCCESS The image has been unloaded. @retval EFI_UNSUPPORTED The image has been started, and does not support unload. - @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle. + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. **/ EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index d36d0061af..ef2e563b6b 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -89,7 +89,8 @@ EFI_BOOT_SERVICES mBootServices = { (EFI_CALCULATE_CRC32)CoreEfiNotAvailableYetArg3, // CalculateCrc32 (EFI_COPY_MEM)CopyMem, // CopyMem (EFI_SET_MEM)SetMem, // SetMem - (EFI_CREATE_EVENT_EX)CoreCreateEventEx // CreateEventEx + (EFI_CREATE_EVENT_EX)CoreCreateEventEx, // CreateEventEx + (EFI_ALLOCATE_RING3_PAGES)AllocateRing3Pages }; EFI_DXE_SERVICES mDxeServices = { diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 84f038a9e4..60bdde5549 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1565,6 +1565,27 @@ CoreLoadImage ( return Status; } +EFI_STATUS +EFIAPI +AllocateRing3Pages ( + IN UINTN NumberOfPages, + IN OUT VOID **Memory + ) +{ + if (Memory == NULL) { + return EFI_INVALID_PARAMETER; + } + + *Memory = AllocatePages (NumberOfPages); + if (*Memory == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SetUefiImageMemoryAttributes ((UINTN)*Memory, EFI_PAGES_TO_SIZE (NumberOfPages), EFI_MEMORY_USER); + + return EFI_SUCCESS; +} + /** Transfer control to a loaded image's entry point. @@ -1974,7 +1995,7 @@ CoreExit ( @retval EFI_SUCCESS The image has been unloaded. @retval EFI_UNSUPPORTED The image has been started, and does not support unload. - @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle. + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. **/ EFI_STATUS diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index cfaa8363f1..53a11b5ce9 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -222,6 +222,13 @@ EFI_STATUS IN OUT EFI_PHYSICAL_ADDRESS *Memory ); +typedef +EFI_STATUS +(EFIAPI *EFI_ALLOCATE_RING3_PAGES)( + IN UINTN Pages, + IN OUT VOID **Memory + ); + /** Frees memory pages. @@ -2023,6 +2030,7 @@ typedef struct { EFI_COPY_MEM CopyMem; EFI_SET_MEM SetMem; EFI_CREATE_EVENT_EX CreateEventEx; + EFI_ALLOCATE_RING3_PAGES AllocateRing3Pages; } EFI_BOOT_SERVICES; /// diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index cce038ba87..a2eab99121 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -11,6 +11,8 @@ #include #include +#include + #include "Ring3.h" EFI_BOOT_SERVICES mBootServices = { @@ -64,12 +66,14 @@ EFI_BOOT_SERVICES mBootServices = { (EFI_CALCULATE_CRC32)Ring3CalculateCrc32, // CalculateCrc32 (EFI_COPY_MEM)CopyMem, // CopyMem (EFI_SET_MEM)SetMem, // SetMem - (EFI_CREATE_EVENT_EX)Ring3CreateEventEx // CreateEventEx + (EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx }; EFI_BOOT_SERVICES *gBS = &mBootServices; EFI_BOOT_SERVICES *mCoreBS = NULL; +EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mCoreDevicePathUtilitiesProtocol = NULL; + /** The function constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. @@ -126,7 +130,7 @@ Ring3AllocatePages ( IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -136,7 +140,7 @@ Ring3FreePages ( IN UINTN NumberOfPages ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -149,7 +153,7 @@ Ring3GetMemoryMap ( OUT UINT32 *DescriptorVersion ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -160,7 +164,7 @@ Ring3AllocatePool ( OUT VOID **Buffer ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -169,7 +173,7 @@ Ring3FreePool ( IN VOID *Buffer ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -182,7 +186,7 @@ Ring3CreateEvent ( OUT EFI_EVENT *Event ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -193,7 +197,7 @@ Ring3SetTimer ( IN UINT64 TriggerTime ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -204,7 +208,7 @@ Ring3WaitForEvent ( OUT UINTN *UserIndex ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -213,7 +217,7 @@ Ring3SignalEvent ( IN EFI_EVENT UserEvent ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -222,7 +226,7 @@ Ring3CloseEvent ( IN EFI_EVENT UserEvent ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -231,7 +235,7 @@ Ring3CheckEvent ( IN EFI_EVENT UserEvent ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -243,7 +247,7 @@ Ring3InstallProtocolInterface ( IN VOID *Interface ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -255,7 +259,7 @@ Ring3ReinstallProtocolInterface ( IN VOID *NewInterface ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -266,7 +270,7 @@ Ring3UninstallProtocolInterface ( IN VOID *Interface ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -277,7 +281,7 @@ Ring3HandleProtocol ( OUT VOID **Interface ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -288,7 +292,7 @@ Ring3RegisterProtocolNotify ( OUT VOID **Registration ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -301,7 +305,7 @@ Ring3LocateHandle ( OUT EFI_HANDLE *Buffer ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -312,7 +316,7 @@ Ring3LocateDevicePath ( OUT EFI_HANDLE *Device ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -322,7 +326,7 @@ Ring3InstallConfigurationTable ( IN VOID *Table ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -336,7 +340,7 @@ Ring3LoadImage ( OUT EFI_HANDLE *ImageHandle ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -347,7 +351,7 @@ Ring3StartImage ( OUT CHAR16 **ExitData OPTIONAL ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -359,7 +363,7 @@ Ring3Exit ( IN CHAR16 *ExitData OPTIONAL ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -368,7 +372,7 @@ Ring3UnloadImage ( IN EFI_HANDLE ImageHandle ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -378,7 +382,7 @@ Ring3ExitBootServices ( IN UINTN MapKey ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -387,7 +391,7 @@ Ring3GetNextMonotonicCount ( OUT UINT64 *Count ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -396,7 +400,7 @@ Ring3Stall ( IN UINTN Microseconds ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -408,7 +412,7 @@ Ring3SetWatchdogTimer ( IN CHAR16 *WatchdogData OPTIONAL ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -420,7 +424,7 @@ Ring3ConnectController ( IN BOOLEAN Recursive ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -431,7 +435,7 @@ Ring3DisconnectController ( IN EFI_HANDLE ChildHandle OPTIONAL ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -445,7 +449,7 @@ Ring3OpenProtocol ( IN UINT32 Attributes ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -457,7 +461,7 @@ Ring3CloseProtocol ( IN EFI_HANDLE ControllerHandle ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -469,7 +473,7 @@ Ring3OpenProtocolInformation ( OUT UINTN *EntryCount ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -480,7 +484,7 @@ Ring3ProtocolsPerHandle ( OUT UINTN *ProtocolBufferCount ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -493,7 +497,7 @@ Ring3LocateHandleBuffer ( OUT EFI_HANDLE **Buffer ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -512,6 +516,39 @@ Ring3LocateProtocol ( Registration, Interface ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to loacate protocol %g\n", Protocol)); + return Status; + } + + if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { + EFI_DEVICE_PATH_UTILITIES_PROTOCOL *UserProtocol; + + mCoreDevicePathUtilitiesProtocol = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; + + Status = (EFI_STATUS)SysCall ( + (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, AllocateRing3Pages), + EFI_SIZE_TO_PAGES (sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL)), + (VOID **)&UserProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate pages for Ring3\n")); + return Status; + } + + UserProtocol->GetDevicePathSize = NULL; + UserProtocol->DuplicateDevicePath = NULL; + UserProtocol->AppendDevicePath = NULL; + UserProtocol->AppendDeviceNode = NULL; + UserProtocol->AppendDevicePathInstance = NULL; + UserProtocol->GetNextDevicePathInstance = NULL; + UserProtocol->IsDevicePathMultiInstance = NULL; + UserProtocol->CreateDeviceNode = NULL; + + *Interface = UserProtocol; + + return Status; + } return Status; } @@ -523,7 +560,7 @@ Ring3InstallMultipleProtocolInterfaces ( ... ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -533,7 +570,7 @@ Ring3UninstallMultipleProtocolInterfaces ( ... ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -544,7 +581,7 @@ Ring3CalculateCrc32 ( OUT UINT32 *Crc32 ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -558,5 +595,5 @@ Ring3CreateEventEx ( OUT EFI_EVENT *Event ) { - return EFI_SUCCESS; + return EFI_UNSUPPORTED; } From 303a93a9c2d28efb6b3fc459d5efdd6bb91ea89b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 29 Jan 2024 14:00:43 +0300 Subject: [PATCH 133/341] Ring3: Added helper function AllocateCoreCopy(), refactored SysCall. --- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 3 +- MdePkg/Include/Library/BaseLib.h | 1 + MdePkg/Include/Uefi/UefiSpec.h | 8 + MdePkg/Library/BaseLib/X64/SwitchStack.nasm | 178 +++++++++++++++--- .../Ring3UefiBootServicesTableLib/Ring3.h | 10 +- .../Ring3UefiBootServicesTableLib.c | 28 ++- .../X64/SysCall.nasm | 3 +- 7 files changed, 192 insertions(+), 39 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index ef2e563b6b..c726671d91 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -90,7 +90,8 @@ EFI_BOOT_SERVICES mBootServices = { (EFI_COPY_MEM)CopyMem, // CopyMem (EFI_SET_MEM)SetMem, // SetMem (EFI_CREATE_EVENT_EX)CoreCreateEventEx, // CreateEventEx - (EFI_ALLOCATE_RING3_PAGES)AllocateRing3Pages + (EFI_ALLOCATE_RING3_PAGES)AllocateRing3Pages, + (EFI_ALLOCATE_CORE_COPY)AllocateCopyPool }; EFI_DXE_SERVICES mDxeServices = { diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 570b06ee44..09a24c1e27 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -6699,6 +6699,7 @@ AsmReadEflags ( UINTN EFIAPI CoreBootServices ( + IN UINT8 Type, IN UINTN FunctionAddress, ... ); diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 53a11b5ce9..f586847500 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -229,6 +229,13 @@ EFI_STATUS IN OUT VOID **Memory ); +typedef +VOID * +(EFIAPI *EFI_ALLOCATE_CORE_COPY)( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ); + /** Frees memory pages. @@ -2031,6 +2038,7 @@ typedef struct { EFI_SET_MEM SetMem; EFI_CREATE_EVENT_EX CreateEventEx; EFI_ALLOCATE_RING3_PAGES AllocateRing3Pages; + EFI_ALLOCATE_CORE_COPY AllocateCoreCopy; } EFI_BOOT_SERVICES; /// diff --git a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm index 868d23df87..21112847a4 100644 --- a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm +++ b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm @@ -93,22 +93,27 @@ ASM_PFX(InternalEnterUserImage): retfq ;------------------------------------------------------------------------------ -; UINTN -; EFIAPI -; CoreBootServices ( -; IN UINTN FunctionAddress, -; ... -; ); -; -; (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). -; (rdx) Argument 1 of the called function. -; (r8) Argument 2 of the called function. -; (r9) Argument 3 of the called function. -; (r10) FunctionAddress. -; (r11) RFLAGS saved by SYSCALL in SysCall(). -;On stack Argument 4, 5, ... +; typedef enum { +; SysCallReadMemory = 0, +; SysCallAllocateRing3Pages = 1, +; SysCallAllocateCoreCopy = 2, +; SysCallLocateProtocol = 3, +; SysCallMax +; } SYS_CALL_TYPE; ;------------------------------------------------------------------------------ + +%define READ_MEMORY 0 +%define ALLOCATE_RING3_PAGES 1 +%define ALLOCATE_CORE_COPY 2 +%define LOCATE_PROTOCOL 3 + %macro CallSysRet 0 + ; Prepare SYSRET arguments. + pop rcx + + ; Switch from Core to User data segment selectors. + pop r11 + o16 mov ds, r11 o16 mov es, r11 o16 mov fs, r11 @@ -128,11 +133,45 @@ o64 sysret ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. %endmacro +%macro DisableSMAP 0 + pushfq + pop rcx + or rcx, 0x40000 ; Set AC (bit 18) + push rcx + popfq +%endmacro + +%macro EnableSMAP 0 + pushfq + pop rcx + and rcx, ~0x40000 ; Clear AC (bit 18) + push rcx + popfq +%endmacro + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; CoreBootServices ( +; IN UINT8 Type, +; IN UINTN FunctionAddress, +; ... +; ); +; +; (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). +; (rdx) FunctionAddress. +; (r8) Argument 1 of the called function. +; (r9) Argument 2 of the called function. +; (r10) Type. +; (r11) RFLAGS saved by SYSCALL in SysCall(). +;On stack Argument 3, 4, ... +;------------------------------------------------------------------------------ global ASM_PFX(CoreBootServices) ASM_PFX(CoreBootServices): - ; Save User data segment selector. + ; Save User data segment selector temporarily in R11. mov r11, ds + ; Switch from User to Core data segment selectors. mov ax, ss mov ds, ax mov es, ax @@ -148,34 +187,115 @@ ASM_PFX(CoreBootServices): push rbp mov rbp, rsp - cmp r10, 0 - je readMemory + ; Save User data segment selector on Core SysCall Stack. + push r11 + + ; Save FunctionAddress in R11 as it will be called later. + mov r11, rdx ; Save return address for SYSRET. push rcx + cmp r10, READ_MEMORY + je readMemory + + cmp r10, ALLOCATE_RING3_PAGES + je allocateRing3Pages + + cmp r10, ALLOCATE_CORE_COPY + je allocateCoreCopy + + cmp r10, LOCATE_PROTOCOL + je locateProtocol + +;------------------------------------------------------------------------------ +; UINTN +; ReadMemory ( +; IN UINTN Address +; ); +readMemory: + mov rax, [rdx] + + CallSysRet + +;------------------------------------------------------------------------------ +; EFI_STATUS +; AllocateRing3Pages ( +; IN UINTN NumberOfPages, +; IN OUT VOID **Memory +; ); +allocateRing3Pages: + ; Save User (VOID **)Memory on Core SysCall Stack. + push r9 + ; Replace argument according to UEFI calling convention. - mov rcx, rdx - mov rdx, r8 - mov r8, r9 - ; mov r9, [rax + 8*3] - ; mov r11, [rax + 8*4] - ; push r11 - ; ... + mov rcx, r8 + ; Allocate space for (VOID *)Memory on Core SysCall Stack. + sub rsp, 8 + mov rdx, rsp ; Call Boot Service by FunctionAddress. - call [r10] + call [r11] - ; Prepare SYSRET arguments. - pop rcx + DisableSMAP + + ; Copy (VOID *)Memory from Core SysCall Stack to User Stack. + pop rdx + pop r9 + mov [r9], rdx + + EnableSMAP CallSysRet -readMemory: - mov rax, [rdx] +;------------------------------------------------------------------------------ +; VOID * +; AllocateCoreCopy ( +; IN UINTN AllocationSize, +; IN CONST VOID *Buffer +; ); +allocateCoreCopy: + DisableSMAP + + ; Replace argument according to UEFI calling convention. + mov rcx, r8 + mov rdx, r9 + + ; Call Boot Service by FunctionAddress. + call [r11] + + EnableSMAP CallSysRet +;------------------------------------------------------------------------------ +; EFI_STATUS +; LocateProtocol ( +; IN EFI_GUID *Protocol, +; IN VOID *Registration OPTIONAL, +; OUT VOID **Interface +; ); +locateProtocol: + ; Replace argument according to UEFI calling convention. + mov rcx, r8 + mov rdx, r9 + ; Allocate space for (VOID *)Interface on Core SysCall Stack. + sub rsp, 8 + mov r8, rsp + + ; Call Boot Service by FunctionAddress. + call [r11] + + DisableSMAP + + ; Copy (VOID *)Interface from Core SysCall Stack to User Stack. + pop rcx + mov rdx, [rbp + 8] ; rdx = User rsp + mov [rdx + 8*4], rcx ; 5th argument of SysCall (SysCallLocateProtocol) + + EnableSMAP + + CallSysRet SECTION .data diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h index 11d8819e4e..f0b64ae0c9 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h @@ -5,14 +5,22 @@ **/ +typedef enum { + SysCallReadMemory = 0, + SysCallAllocateRing3Pages = 1, + SysCallAllocateCoreCopy = 2, + SysCallLocateProtocol = 3, + SysCallMax +} SYS_CALL_TYPE; + UINTN EFIAPI SysCall ( + IN UINT8 Type, IN UINTN FunctionAddress, ... ); - /** Raise the task priority level to the new level. High level is implemented by disabling processor interrupts. diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index a2eab99121..5995ad4870 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -94,7 +94,7 @@ UefiBootServicesTableLibConstructor ( // Cache pointer to the EFI Boot Services Table // mCoreBS = (EFI_BOOT_SERVICES *)SysCall ( - 0, + SysCallReadMemory, (UINTN)SystemTable + OFFSET_OF (EFI_SYSTEM_TABLE, BootServices) ); ASSERT (mCoreBS != NULL); @@ -504,16 +504,31 @@ EFI_STATUS EFIAPI Ring3LocateProtocol ( IN EFI_GUID *Protocol, - IN VOID *Registration OPTIONAL, + IN VOID *CoreRegistration OPTIONAL, OUT VOID **Interface ) { - EFI_STATUS Status; + EFI_STATUS Status; + EFI_GUID *CoreProtocol; + + EFI_DEVICE_PATH_UTILITIES_PROTOCOL *UserProtocol; + + CoreProtocol = (VOID *)SysCall ( + SysCallAllocateCoreCopy, + (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, AllocateCoreCopy), + sizeof (EFI_GUID), + Protocol + ); + if (CoreProtocol == NULL) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate core copy of the Protocol variable.\n")); + return EFI_OUT_OF_RESOURCES; + } Status = (EFI_STATUS)SysCall ( + SysCallLocateProtocol, (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, LocateProtocol), - Protocol, - Registration, + CoreProtocol, + CoreRegistration, Interface ); if (EFI_ERROR (Status)) { @@ -522,11 +537,10 @@ Ring3LocateProtocol ( } if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { - EFI_DEVICE_PATH_UTILITIES_PROTOCOL *UserProtocol; - mCoreDevicePathUtilitiesProtocol = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; Status = (EFI_STATUS)SysCall ( + SysCallAllocateRing3Pages, (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, AllocateRing3Pages), EFI_SIZE_TO_PAGES (sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL)), (VOID **)&UserProtocol diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm b/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm index 64670a6a25..b888ab5d8c 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm @@ -10,13 +10,14 @@ ; UINTN ; EFIAPI ; SysCall ( +; IN UINT8 Type, ; IN UINTN FunctionAddress, ; ... ; ); ;------------------------------------------------------------------------------ global ASM_PFX(SysCall) ASM_PFX(SysCall): - ; Save FunctionAddress for CoreBootServices(). + ; Save Type for CoreBootServices(). mov r10, rcx ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. From c6ba2933e38d1eb892589f7abf9500b41a6edbbc Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 29 Jan 2024 20:21:14 +0300 Subject: [PATCH 134/341] Ring3: Added SysCallOpenProtocol. --- MdePkg/Library/BaseLib/X64/SwitchStack.nasm | 73 ++++++++++++++--- .../Ring3UefiBootServicesTableLib/Ring3.h | 1 + .../Ring3UefiBootServicesTableLib.c | 82 +++++++++++++++++-- 3 files changed, 141 insertions(+), 15 deletions(-) diff --git a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm index 21112847a4..9b25802690 100644 --- a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm +++ b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm @@ -98,6 +98,7 @@ ASM_PFX(InternalEnterUserImage): ; SysCallAllocateRing3Pages = 1, ; SysCallAllocateCoreCopy = 2, ; SysCallLocateProtocol = 3, +; SysCallOpenProtocol = 4, ; SysCallMax ; } SYS_CALL_TYPE; ;------------------------------------------------------------------------------ @@ -106,6 +107,7 @@ ASM_PFX(InternalEnterUserImage): %define ALLOCATE_RING3_PAGES 1 %define ALLOCATE_CORE_COPY 2 %define LOCATE_PROTOCOL 3 +%define OPEN_PROTOCOL 4 %macro CallSysRet 0 ; Prepare SYSRET arguments. @@ -135,17 +137,17 @@ o64 sysret %macro DisableSMAP 0 pushfq - pop rcx - or rcx, 0x40000 ; Set AC (bit 18) - push rcx + pop r10 + or r10, 0x40000 ; Set AC (bit 18) + push r10 popfq %endmacro %macro EnableSMAP 0 pushfq - pop rcx - and rcx, ~0x40000 ; Clear AC (bit 18) - push rcx + pop r10 + and r10, ~0x40000 ; Clear AC (bit 18) + push r10 popfq %endmacro @@ -208,6 +210,9 @@ ASM_PFX(CoreBootServices): cmp r10, LOCATE_PROTOCOL je locateProtocol + cmp r10, OPEN_PROTOCOL + je openProtocol + ;------------------------------------------------------------------------------ ; UINTN ; ReadMemory ( @@ -228,7 +233,7 @@ allocateRing3Pages: ; Save User (VOID **)Memory on Core SysCall Stack. push r9 - ; Replace argument according to UEFI calling convention. + ; Replace arguments according to UEFI calling convention. mov rcx, r8 ; Allocate space for (VOID *)Memory on Core SysCall Stack. sub rsp, 8 @@ -257,7 +262,7 @@ allocateRing3Pages: allocateCoreCopy: DisableSMAP - ; Replace argument according to UEFI calling convention. + ; Replace arguments according to UEFI calling convention. mov rcx, r8 mov rdx, r9 @@ -276,7 +281,7 @@ allocateCoreCopy: ; OUT VOID **Interface ; ); locateProtocol: - ; Replace argument according to UEFI calling convention. + ; Replace arguments according to UEFI calling convention. mov rcx, r8 mov rdx, r9 ; Allocate space for (VOID *)Interface on Core SysCall Stack. @@ -291,7 +296,55 @@ locateProtocol: ; Copy (VOID *)Interface from Core SysCall Stack to User Stack. pop rcx mov rdx, [rbp + 8] ; rdx = User rsp - mov [rdx + 8*4], rcx ; 5th argument of SysCall (SysCallLocateProtocol) + mov [rdx + 8*5], rcx ; 5th argument of SysCall (SysCallLocateProtocol) + + EnableSMAP + + CallSysRet + +;------------------------------------------------------------------------------ +; EFI_STATUS +; OpenProtocol ( +; IN EFI_HANDLE UserHandle, +; IN EFI_GUID *Protocol, +; OUT VOID **Interface OPTIONAL, +; IN EFI_HANDLE ImageHandle, +; IN EFI_HANDLE ControllerHandle, +; IN UINT32 Attributes +; ); +openProtocol: + ; Replace arguments according to UEFI calling convention. + mov rcx, r8 ; UserHandle + mov rdx, r9 ; Protocol + ; Allocate space for (VOID *)Interface on Core SysCall Stack. + sub rsp, 8 + mov r8, rsp ; Interface + + DisableSMAP + + ; Copy ImageHandle, ControllerHandle, Attributes from User Stack to Core SysCall Stack. + mov rax, [rbp + 8] ; rax = User rsp + mov r9, [rax + 8*8] ; Attributes - 8th argument of SysCall (SysCallOpenProtocol) + push r9 + mov r9, [rax + 8*7] ; ControllerHandle - 7th argument of SysCall (SysCallOpenProtocol) + push r9 + mov r9, [rax + 8*6] ; ImageHandle - 6th argument of SysCall (SysCallOpenProtocol) + + EnableSMAP + + ; Step over first 4 arguments, which are passed through registers. + sub rsp, 8*4 + + ; Call Boot Service by FunctionAddress. + call [r11] + + DisableSMAP + + ; Copy (VOID *)Interface from Core SysCall Stack to User Stack. + add rsp, 8*6 + pop rcx + mov rdx, [rbp + 8] ; rdx = User rsp + mov [rdx + 8*5], rcx ; 5th argument of SysCall (SysCallOpenProtocol) EnableSMAP diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h index f0b64ae0c9..4f14ead758 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h @@ -10,6 +10,7 @@ typedef enum { SysCallAllocateRing3Pages = 1, SysCallAllocateCoreCopy = 2, SysCallLocateProtocol = 3, + SysCallOpenProtocol = 4, SysCallMax } SYS_CALL_TYPE; diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index 5995ad4870..d62d8d50ef 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -12,6 +12,7 @@ #include #include +#include #include "Ring3.h" @@ -73,6 +74,7 @@ EFI_BOOT_SERVICES *gBS = &mBootServices; EFI_BOOT_SERVICES *mCoreBS = NULL; EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mCoreDevicePathUtilitiesProtocol = NULL; +EFI_LOADED_IMAGE_PROTOCOL *mCoreLoadedImageProtocol = NULL; /** The function constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. @@ -441,14 +443,82 @@ Ring3DisconnectController ( EFI_STATUS EFIAPI Ring3OpenProtocol ( - IN EFI_HANDLE UserHandle, + IN EFI_HANDLE CoreUserHandle, IN EFI_GUID *Protocol, OUT VOID **Interface OPTIONAL, - IN EFI_HANDLE ImageHandle, - IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE CoreImageHandle, + IN EFI_HANDLE CoreControllerHandle, IN UINT32 Attributes ) { + EFI_STATUS Status; + EFI_GUID *CoreProtocol; + + EFI_LOADED_IMAGE_PROTOCOL *UserProtocol; + + CoreProtocol = (VOID *)SysCall ( + SysCallAllocateCoreCopy, + (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, AllocateCoreCopy), + sizeof (EFI_GUID), + Protocol + ); + if (CoreProtocol == NULL) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate core copy of the Protocol variable.\n")); + return EFI_OUT_OF_RESOURCES; + } + + Status = (EFI_STATUS)SysCall ( + SysCallOpenProtocol, + (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, OpenProtocol), + CoreUserHandle, + CoreProtocol, + Interface, + CoreImageHandle, + CoreControllerHandle, + Attributes + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to open protocol %g\n", Protocol)); + return Status; + } + + // TODO: FreePool (CoreProtocol); + + if (CompareGuid (Protocol, &gEfiLoadedImageProtocolGuid)) { + mCoreLoadedImageProtocol = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; + + Status = (EFI_STATUS)SysCall ( + SysCallAllocateRing3Pages, + (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, AllocateRing3Pages), + EFI_SIZE_TO_PAGES (sizeof (EFI_LOADED_IMAGE_PROTOCOL)), + (VOID **)&UserProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate pages for Ring3 EFI_LOADED_IMAGE_PROTOCOL structure.\n")); + return Status; + } + + // TODO: Copy Core Interface fields with AllocateRing3Pages(). + + UserProtocol->Revision = 0; + UserProtocol->ParentHandle = NULL; + UserProtocol->SystemTable = NULL; + UserProtocol->DeviceHandle = NULL; + UserProtocol->FilePath = NULL; + UserProtocol->Reserved = 0; + UserProtocol->LoadOptionsSize = 0; + UserProtocol->LoadOptions = NULL; + UserProtocol->ImageBase = NULL; + UserProtocol->ImageSize = 0; + UserProtocol->ImageCodeType = 0; + UserProtocol->ImageDataType = 0; + UserProtocol->Unload = NULL; + + *Interface = UserProtocol; + + return Status; + } + return EFI_UNSUPPORTED; } @@ -536,6 +606,8 @@ Ring3LocateProtocol ( return Status; } + // TODO: FreePool (CoreProtocol); + if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { mCoreDevicePathUtilitiesProtocol = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; @@ -546,7 +618,7 @@ Ring3LocateProtocol ( (VOID **)&UserProtocol ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate pages for Ring3\n")); + DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate pages for Ring3 EFI_DEVICE_PATH_UTILITIES_PROTOCOL structure.\n")); return Status; } @@ -564,7 +636,7 @@ Ring3LocateProtocol ( return Status; } - return Status; + return EFI_UNSUPPORTED; } EFI_STATUS From 63423898d012e38ee03badd9f1f6867f3907bf6f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 1 Feb 2024 13:47:52 +0300 Subject: [PATCH 135/341] Ring3: Moved some .nasm code to .c. --- MdePkg/Library/BaseLib/BaseLibInternals.h | 54 +++++ MdePkg/Library/BaseLib/SwitchStack.c | 88 +++++++++ MdePkg/Library/BaseLib/X64/SwitchStack.nasm | 208 +++----------------- 3 files changed, 169 insertions(+), 181 deletions(-) diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h b/MdePkg/Library/BaseLib/BaseLibInternals.h index 340ad96284..93a3ffaa3b 100644 --- a/MdePkg/Library/BaseLib/BaseLibInternals.h +++ b/MdePkg/Library/BaseLib/BaseLibInternals.h @@ -343,6 +343,60 @@ InternalEnterUserImage ( IN UINT16 DataSelector ); +VOID +EFIAPI +DisableSMAP ( + VOID + ); + +VOID +EFIAPI +EnableSMAP ( + VOID + ); + +typedef enum { + SysCallReadMemory = 0, + SysCallAllocateRing3Pages = 1, + SysCallAllocateCoreCopy = 2, + SysCallLocateProtocol = 3, + SysCallOpenProtocol = 4, + SysCallMax +} SYS_CALL_TYPE; + +typedef +UINTN +(EFIAPI *EFI_ALLOCATE_RING3_PAGES)( + IN UINTN Pages, + IN OUT VOID **Memory + ); + +typedef +VOID * +(EFIAPI *EFI_ALLOCATE_CORE_COPY)( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ); + +typedef +UINTN +(EFIAPI *EFI_LOCATE_PROTOCOL)( + IN VOID *Protocol, + IN VOID *Registration OPTIONAL, + OUT VOID **Interface + ); + +typedef +UINTN +(EFIAPI *EFI_OPEN_PROTOCOL)( + IN VOID * Handle, + IN VOID *Protocol, + OUT VOID **Interface OPTIONAL, + IN VOID * AgentHandle, + IN VOID * ControllerHandle, + IN UINT32 Attributes + ); + /** Worker function that returns a bit field from Operand. diff --git a/MdePkg/Library/BaseLib/SwitchStack.c b/MdePkg/Library/BaseLib/SwitchStack.c index 14ad7cd4bf..df3d249717 100644 --- a/MdePkg/Library/BaseLib/SwitchStack.c +++ b/MdePkg/Library/BaseLib/SwitchStack.c @@ -90,3 +90,91 @@ EnterUserImage ( InternalEnterUserImage (EntryPoint, Context1, Context2, NewStack, CodeSelector, DataSelector); } + +UINTN +EFIAPI +CallBootService ( + IN UINT8 Type, + IN VOID **FunctionAddress, + IN UINTN CoreRbp, + IN UINTN UserRsp + ) +{ + UINTN Status; + VOID *Pointer; + VOID * Arg4; + VOID * Arg5; + UINT32 Arg6; + EFI_ALLOCATE_RING3_PAGES Func1; + EFI_ALLOCATE_CORE_COPY Func2; + EFI_LOCATE_PROTOCOL Func3; + EFI_OPEN_PROTOCOL Func4; + // Stack: + // rcx - Rip for SYSCALL + // r8 - Argument 1 + // rbp - User Rbp + // r9 - Argument 2 + // r11 - User data segment selector <- CoreRbp + // rsp - User Rsp + switch (Type) { + case SysCallReadMemory: + return *(UINTN *)FunctionAddress; + + case SysCallAllocateRing3Pages: + Func1 = (EFI_ALLOCATE_RING3_PAGES)*FunctionAddress; + Status = Func1 ( + *((UINTN *)CoreRbp + 3), + &Pointer + ); + DisableSMAP (); + *(UINTN *)(*((UINTN *)CoreRbp + 1)) = (UINTN)Pointer; + EnableSMAP (); + return (UINTN)Status; + + case SysCallAllocateCoreCopy: + DisableSMAP (); + Func2 = (EFI_ALLOCATE_CORE_COPY)*FunctionAddress; + Status = (UINTN)Func2 ( + *((UINTN *)CoreRbp + 3), + (VOID *)*((UINTN *)CoreRbp + 1) + ); + EnableSMAP (); + return (UINTN)Status; + + case SysCallLocateProtocol: + Func3 = (EFI_LOCATE_PROTOCOL)*FunctionAddress; + Status = Func3 ( + (VOID *)*((UINTN *)CoreRbp + 3), + (VOID *)*((UINTN *)CoreRbp + 1), + &Pointer + ); + DisableSMAP (); + *((UINTN *)UserRsp + 5) = (UINTN)Pointer; + EnableSMAP (); + return (UINTN)Status; + + case SysCallOpenProtocol: + DisableSMAP (); + Arg4 = (VOID *)*((UINTN *)UserRsp + 6); + Arg5 = (VOID *)*((UINTN *)UserRsp + 7); + Arg6 = (UINT32)*((UINTN *)UserRsp + 8); + EnableSMAP (); + Func4 = (EFI_OPEN_PROTOCOL)*FunctionAddress; + Status = Func4 ( + (VOID *)*((UINTN *)CoreRbp + 3), + (VOID *)*((UINTN *)CoreRbp + 1), + &Pointer, + Arg4, + Arg5, + Arg6 + ); + DisableSMAP (); + *((UINTN *)UserRsp + 5) = (UINTN)Pointer; + EnableSMAP (); + return (UINTN)Status; + default: + break; + } + + return 0; +} diff --git a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm index 9b25802690..eb29524c82 100644 --- a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm +++ b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm @@ -16,6 +16,8 @@ DEFAULT REL SECTION .text +extern ASM_PFX(CallBootService) + ;------------------------------------------------------------------------------ ; Routine Description: ; @@ -92,26 +94,10 @@ ASM_PFX(InternalEnterUserImage): ; Pass control to user image retfq -;------------------------------------------------------------------------------ -; typedef enum { -; SysCallReadMemory = 0, -; SysCallAllocateRing3Pages = 1, -; SysCallAllocateCoreCopy = 2, -; SysCallLocateProtocol = 3, -; SysCallOpenProtocol = 4, -; SysCallMax -; } SYS_CALL_TYPE; -;------------------------------------------------------------------------------ - -%define READ_MEMORY 0 -%define ALLOCATE_RING3_PAGES 1 -%define ALLOCATE_CORE_COPY 2 -%define LOCATE_PROTOCOL 3 -%define OPEN_PROTOCOL 4 - %macro CallSysRet 0 ; Prepare SYSRET arguments. - pop rcx + mov rcx, [rbp + 8*4] + pop rdx ; Switch from Core to User data segment selectors. pop r11 @@ -127,7 +113,7 @@ o16 mov gs, r11 ; Switch to User Stack. pop rbp - pop rdx + pop rbp mov rsp, rdx ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. @@ -135,21 +121,23 @@ o64 sysret ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. %endmacro -%macro DisableSMAP 0 +global ASM_PFX(DisableSMAP) +ASM_PFX(DisableSMAP): pushfq pop r10 or r10, 0x40000 ; Set AC (bit 18) push r10 popfq -%endmacro + ret -%macro EnableSMAP 0 +global ASM_PFX(EnableSMAP) +ASM_PFX(EnableSMAP): pushfq pop r10 and r10, ~0x40000 ; Clear AC (bit 18) push r10 popfq -%endmacro + ret ;------------------------------------------------------------------------------ ; UINTN @@ -182,171 +170,29 @@ ASM_PFX(CoreBootServices): ; Save User Stack pointers and switch to Core SysCall Stack. mov rax, [ASM_PFX(gCoreSysCallStackTop)] + ; Save return address for SYSRET. sub rax, 8 - mov [rax], rsp - mov rsp, rax - - push rbp - mov rbp, rsp - + mov [rax], rcx + mov rcx, r10 + sub rax, 8 + mov [rax], r8 + sub rax, 8 + mov [rax], rbp + sub rax, 8 + mov [rax], r9 ; Save User data segment selector on Core SysCall Stack. - push r11 - - ; Save FunctionAddress in R11 as it will be called later. - mov r11, rdx - - ; Save return address for SYSRET. - push rcx - - cmp r10, READ_MEMORY - je readMemory - - cmp r10, ALLOCATE_RING3_PAGES - je allocateRing3Pages - - cmp r10, ALLOCATE_CORE_COPY - je allocateCoreCopy - - cmp r10, LOCATE_PROTOCOL - je locateProtocol - - cmp r10, OPEN_PROTOCOL - je openProtocol - -;------------------------------------------------------------------------------ -; UINTN -; ReadMemory ( -; IN UINTN Address -; ); -readMemory: - mov rax, [rdx] - - CallSysRet - -;------------------------------------------------------------------------------ -; EFI_STATUS -; AllocateRing3Pages ( -; IN UINTN NumberOfPages, -; IN OUT VOID **Memory -; ); -allocateRing3Pages: - ; Save User (VOID **)Memory on Core SysCall Stack. - push r9 - - ; Replace arguments according to UEFI calling convention. - mov rcx, r8 - ; Allocate space for (VOID *)Memory on Core SysCall Stack. - sub rsp, 8 - mov rdx, rsp - - ; Call Boot Service by FunctionAddress. - call [r11] - - DisableSMAP - - ; Copy (VOID *)Memory from Core SysCall Stack to User Stack. - pop rdx - pop r9 - mov [r9], rdx - - EnableSMAP - - CallSysRet - -;------------------------------------------------------------------------------ -; VOID * -; AllocateCoreCopy ( -; IN UINTN AllocationSize, -; IN CONST VOID *Buffer -; ); -allocateCoreCopy: - DisableSMAP - - ; Replace arguments according to UEFI calling convention. - mov rcx, r8 - mov rdx, r9 - - ; Call Boot Service by FunctionAddress. - call [r11] - - EnableSMAP - - CallSysRet - -;------------------------------------------------------------------------------ -; EFI_STATUS -; LocateProtocol ( -; IN EFI_GUID *Protocol, -; IN VOID *Registration OPTIONAL, -; OUT VOID **Interface -; ); -locateProtocol: - ; Replace arguments according to UEFI calling convention. - mov rcx, r8 - mov rdx, r9 - ; Allocate space for (VOID *)Interface on Core SysCall Stack. - sub rsp, 8 - mov r8, rsp - - ; Call Boot Service by FunctionAddress. - call [r11] - - DisableSMAP - - ; Copy (VOID *)Interface from Core SysCall Stack to User Stack. - pop rcx - mov rdx, [rbp + 8] ; rdx = User rsp - mov [rdx + 8*5], rcx ; 5th argument of SysCall (SysCallLocateProtocol) - - EnableSMAP - - CallSysRet + sub rax, 8 + mov [rax], r11 -;------------------------------------------------------------------------------ -; EFI_STATUS -; OpenProtocol ( -; IN EFI_HANDLE UserHandle, -; IN EFI_GUID *Protocol, -; OUT VOID **Interface OPTIONAL, -; IN EFI_HANDLE ImageHandle, -; IN EFI_HANDLE ControllerHandle, -; IN UINT32 Attributes -; ); -openProtocol: - ; Replace arguments according to UEFI calling convention. - mov rcx, r8 ; UserHandle - mov rdx, r9 ; Protocol - ; Allocate space for (VOID *)Interface on Core SysCall Stack. - sub rsp, 8 - mov r8, rsp ; Interface + mov r9, rsp - DisableSMAP + mov rsp, rax - ; Copy ImageHandle, ControllerHandle, Attributes from User Stack to Core SysCall Stack. - mov rax, [rbp + 8] ; rax = User rsp - mov r9, [rax + 8*8] ; Attributes - 8th argument of SysCall (SysCallOpenProtocol) - push r9 - mov r9, [rax + 8*7] ; ControllerHandle - 7th argument of SysCall (SysCallOpenProtocol) + mov rbp, rsp + mov r8, rbp push r9 - mov r9, [rax + 8*6] ; ImageHandle - 6th argument of SysCall (SysCallOpenProtocol) - - EnableSMAP - - ; Step over first 4 arguments, which are passed through registers. - sub rsp, 8*4 - - ; Call Boot Service by FunctionAddress. - call [r11] - - DisableSMAP - - ; Copy (VOID *)Interface from Core SysCall Stack to User Stack. - add rsp, 8*6 - pop rcx - mov rdx, [rbp + 8] ; rdx = User rsp - mov [rdx + 8*5], rcx ; 5th argument of SysCall (SysCallOpenProtocol) - EnableSMAP + call ASM_PFX(CallBootService) CallSysRet From 7f80c73cce3b3ed2f792652b6fb92cb62dd894e1 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 2 Feb 2024 11:26:53 +0300 Subject: [PATCH 136/341] Ring3: Moved SysCall code to DxeCore. --- MdeModulePkg/Core/Dxe/DxeMain.h | 19 +++ MdeModulePkg/Core/Dxe/DxeMain.inf | 4 + MdeModulePkg/Core/Dxe/Image/Image.c | 2 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 154 +++++++++++++++++ .../Dxe/SysCall/X64/CoreBootServices.nasm | 161 ++++++++++++++++++ MdePkg/Include/Library/BaseLib.h | 19 --- MdePkg/Library/BaseLib/BaseLibInternals.h | 65 ------- MdePkg/Library/BaseLib/SwitchStack.c | 110 ------------ MdePkg/Library/BaseLib/X64/SwitchStack.nasm | 159 ----------------- 9 files changed, 339 insertions(+), 354 deletions(-) create mode 100644 MdeModulePkg/Core/Dxe/SysCall/BootServices.c create mode 100644 MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index d16309444b..59a56d0148 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2835,4 +2835,23 @@ SetUefiImageMemoryAttributes ( IN UINT64 Attributes ); +UINTN +EFIAPI +CoreBootServices ( + IN UINT8 Type, + IN UINTN FunctionAddress, + ... + ); + +VOID +EFIAPI +EnterUserImage ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1 OPTIONAL, + IN VOID *Context2 OPTIONAL, + IN VOID *NewStack, + IN UINT16 CodeSelector, + IN UINT16 DataSelector + ); + #endif diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 05e0f14222..b922f2102c 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -67,6 +67,10 @@ Dispatcher/Dispatcher.c DxeMain/DxeProtocolNotify.c DxeMain/DxeMain.c + SysCall/BootServices.c + +[Sources.X64] + SysCall/X64/CoreBootServices.nasm [Packages] MdePkg/MdePkg.dec diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 60bdde5549..4dc510d919 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -27,7 +27,7 @@ STATIC EFI_EVENT mPeCoffEmuProtocolRegistrationEvent; STATIC VOID *mPeCoffEmuProtocolNotifyRegistration; extern BOOLEAN gBdsStarted; -extern VOID *gCoreSysCallStackTop; +VOID *gCoreSysCallStackTop; // // This code is needed to build the Image handle for the DXE Core diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c new file mode 100644 index 0000000000..83afff65d5 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -0,0 +1,154 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include +#include +#include +#include +#include + +VOID +EFIAPI +DisableSMAP ( + VOID + ); + +VOID +EFIAPI +EnableSMAP ( + VOID + ); + +VOID +EFIAPI +InternalEnterUserImage ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1 OPTIONAL, + IN VOID *Context2 OPTIONAL, + IN VOID *NewStack, + IN UINT16 CodeSelector, + IN UINT16 DataSelector + ); + +typedef enum { + SysCallReadMemory = 0, + SysCallAllocateRing3Pages = 1, + SysCallAllocateCoreCopy = 2, + SysCallLocateProtocol = 3, + SysCallOpenProtocol = 4, + SysCallMax +} SYS_CALL_TYPE; + +UINTN +EFIAPI +CallBootService ( + IN UINT8 Type, + IN VOID **FunctionAddress, + IN UINTN CoreRbp, + IN UINTN UserRsp + ) +{ + UINTN Status; + VOID *Pointer; + VOID * Arg4; + VOID * Arg5; + UINT32 Arg6; + EFI_ALLOCATE_RING3_PAGES Func1; + EFI_ALLOCATE_CORE_COPY Func2; + EFI_LOCATE_PROTOCOL Func3; + EFI_OPEN_PROTOCOL Func4; + // Stack: + // rcx - Rip for SYSCALL + // r8 - Argument 1 + // rbp - User Rbp + // r9 - Argument 2 + // r11 - User data segment selector <- CoreRbp + // rsp - User Rsp + switch (Type) { + case SysCallReadMemory: + return *(UINTN *)FunctionAddress; + + case SysCallAllocateRing3Pages: + Func1 = (EFI_ALLOCATE_RING3_PAGES)*FunctionAddress; + Status = Func1 ( + *((UINTN *)CoreRbp + 3), + &Pointer + ); + DisableSMAP (); + *(UINTN *)(*((UINTN *)CoreRbp + 1)) = (UINTN)Pointer; + EnableSMAP (); + return (UINTN)Status; + + case SysCallAllocateCoreCopy: + DisableSMAP (); + Func2 = (EFI_ALLOCATE_CORE_COPY)*FunctionAddress; + Status = (UINTN)Func2 ( + *((UINTN *)CoreRbp + 3), + (VOID *)*((UINTN *)CoreRbp + 1) + ); + EnableSMAP (); + return (UINTN)Status; + + case SysCallLocateProtocol: + Func3 = (EFI_LOCATE_PROTOCOL)*FunctionAddress; + Status = Func3 ( + (VOID *)*((UINTN *)CoreRbp + 3), + (VOID *)*((UINTN *)CoreRbp + 1), + &Pointer + ); + DisableSMAP (); + *((UINTN *)UserRsp + 5) = (UINTN)Pointer; + EnableSMAP (); + return (UINTN)Status; + + case SysCallOpenProtocol: + DisableSMAP (); + Arg4 = (VOID *)*((UINTN *)UserRsp + 6); + Arg5 = (VOID *)*((UINTN *)UserRsp + 7); + Arg6 = (UINT32)*((UINTN *)UserRsp + 8); + EnableSMAP (); + Func4 = (EFI_OPEN_PROTOCOL)*FunctionAddress; + Status = Func4 ( + (VOID *)*((UINTN *)CoreRbp + 3), + (VOID *)*((UINTN *)CoreRbp + 1), + &Pointer, + Arg4, + Arg5, + Arg6 + ); + DisableSMAP (); + *((UINTN *)UserRsp + 5) = (UINTN)Pointer; + EnableSMAP (); + return (UINTN)Status; + default: + break; + } + + return 0; +} + +VOID +EFIAPI +EnterUserImage ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1 OPTIONAL, + IN VOID *Context2 OPTIONAL, + IN VOID *NewStack, + IN UINT16 CodeSelector, + IN UINT16 DataSelector + ) +{ + ASSERT (EntryPoint != NULL); + ASSERT (NewStack != NULL); + + // + // New stack must be aligned with CPU_STACK_ALIGNMENT + // + ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0); + + InternalEnterUserImage (EntryPoint, Context1, Context2, NewStack, CodeSelector, DataSelector); +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm new file mode 100644 index 0000000000..421dbcc8da --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -0,0 +1,161 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +; +;------------------------------------------------------------------------------ + +DEFAULT REL +SECTION .text + +extern ASM_PFX(CallBootService) +extern ASM_PFX(gCoreSysCallStackTop) + +%macro CallSysRet 0 + ; Prepare SYSRET arguments. + mov rcx, [rbp + 8*4] + pop rdx + + ; Switch from Core to User data segment selectors. + pop r11 + +o16 mov ds, r11 +o16 mov es, r11 +o16 mov fs, r11 +o16 mov gs, r11 + + ; Restore RFLAGS in R11 for SYSRET. + pushfq + pop r11 + + ; Switch to User Stack. + pop rbp + pop rbp + mov rsp, rdx + + ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. +o64 sysret + ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. +%endmacro + +global ASM_PFX(DisableSMAP) +ASM_PFX(DisableSMAP): + pushfq + pop r10 + or r10, 0x40000 ; Set AC (bit 18) + push r10 + popfq + ret + +global ASM_PFX(EnableSMAP) +ASM_PFX(EnableSMAP): + pushfq + pop r10 + and r10, ~0x40000 ; Clear AC (bit 18) + push r10 + popfq + ret + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; CoreBootServices ( +; IN UINT8 Type, +; IN UINTN FunctionAddress, +; ... +; ); +; +; (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). +; (rdx) FunctionAddress. +; (r8) Argument 1 of the called function. +; (r9) Argument 2 of the called function. +; (r10) Type. +; (r11) RFLAGS saved by SYSCALL in SysCall(). +;On stack Argument 3, 4, ... +;------------------------------------------------------------------------------ +global ASM_PFX(CoreBootServices) +ASM_PFX(CoreBootServices): + ; Save User data segment selector temporarily in R11. + mov r11, ds + + ; Switch from User to Core data segment selectors. + mov ax, ss + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; Save User Stack pointers and switch to Core SysCall Stack. + mov rax, [ASM_PFX(gCoreSysCallStackTop)] + ; Save return address for SYSRET. + sub rax, 8 + mov [rax], rcx + mov rcx, r10 + sub rax, 8 + mov [rax], r8 + sub rax, 8 + mov [rax], rbp + sub rax, 8 + mov [rax], r9 + ; Save User data segment selector on Core SysCall Stack. + sub rax, 8 + mov [rax], r11 + + mov r9, rsp + + mov rsp, rax + + mov rbp, rsp + mov r8, rbp + push r9 + + call ASM_PFX(CallBootService) + + CallSysRet + +;------------------------------------------------------------------------------ +; Routine Description: +; +; Routine for transfering control to user image with 2 parameters +; +; Arguments: +; +; (rcx) EntryPoint - Entry point with new stack. +; (rdx) Context1 - Parameter1 for entry point. +; (r8) Context2 - Parameter2 for entry point. +; (r9) NewStack - The pointer to new stack. +;On stack CodeSelector - Segment selector for code. +;On stack DataSelector - Segment selector for data. +; +; Returns: +; +; None +; +;------------------------------------------------------------------------------ +global ASM_PFX(InternalEnterUserImage) +ASM_PFX(InternalEnterUserImage): + ; Set Data selectors + mov rax, [rsp + 8*6] + or rax, 3H ; RPL = 3 + + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; Save Code selector + mov r10, [rsp + 8*5] + or r10, 3H ; RPL = 3 + + ; Prepare stack before swithcing + push rax ; ss + push r9 ; rsp + push r10 ; cs + push rcx ; rip + + ; Save 2 parameters + mov rcx, rdx + mov rdx, r8 + + ; Pass control to user image + retfq diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 09a24c1e27..cb4ef6a134 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -5218,17 +5218,6 @@ SwitchStack ( ... ); -VOID -EFIAPI -EnterUserImage ( - IN SWITCH_STACK_ENTRY_POINT EntryPoint, - IN VOID *Context1 OPTIONAL, - IN VOID *Context2 OPTIONAL, - IN VOID *NewStack, - IN UINT16 CodeSelector, - IN UINT16 DataSelector - ); - /** Generates a breakpoint on the CPU. @@ -6696,14 +6685,6 @@ AsmReadEflags ( VOID ); -UINTN -EFIAPI -CoreBootServices ( - IN UINT8 Type, - IN UINTN FunctionAddress, - ... - ); - /** Reads the current value of the Control Register 0 (CR0). diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h b/MdePkg/Library/BaseLib/BaseLibInternals.h index 93a3ffaa3b..d61e604385 100644 --- a/MdePkg/Library/BaseLib/BaseLibInternals.h +++ b/MdePkg/Library/BaseLib/BaseLibInternals.h @@ -332,71 +332,6 @@ InternalSwitchStack ( IN VA_LIST Marker ); -VOID -EFIAPI -InternalEnterUserImage ( - IN SWITCH_STACK_ENTRY_POINT EntryPoint, - IN VOID *Context1 OPTIONAL, - IN VOID *Context2 OPTIONAL, - IN VOID *NewStack, - IN UINT16 CodeSelector, - IN UINT16 DataSelector - ); - -VOID -EFIAPI -DisableSMAP ( - VOID - ); - -VOID -EFIAPI -EnableSMAP ( - VOID - ); - -typedef enum { - SysCallReadMemory = 0, - SysCallAllocateRing3Pages = 1, - SysCallAllocateCoreCopy = 2, - SysCallLocateProtocol = 3, - SysCallOpenProtocol = 4, - SysCallMax -} SYS_CALL_TYPE; - -typedef -UINTN -(EFIAPI *EFI_ALLOCATE_RING3_PAGES)( - IN UINTN Pages, - IN OUT VOID **Memory - ); - -typedef -VOID * -(EFIAPI *EFI_ALLOCATE_CORE_COPY)( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ); - -typedef -UINTN -(EFIAPI *EFI_LOCATE_PROTOCOL)( - IN VOID *Protocol, - IN VOID *Registration OPTIONAL, - OUT VOID **Interface - ); - -typedef -UINTN -(EFIAPI *EFI_OPEN_PROTOCOL)( - IN VOID * Handle, - IN VOID *Protocol, - OUT VOID **Interface OPTIONAL, - IN VOID * AgentHandle, - IN VOID * ControllerHandle, - IN UINT32 Attributes - ); - /** Worker function that returns a bit field from Operand. diff --git a/MdePkg/Library/BaseLib/SwitchStack.c b/MdePkg/Library/BaseLib/SwitchStack.c index df3d249717..954e863fc1 100644 --- a/MdePkg/Library/BaseLib/SwitchStack.c +++ b/MdePkg/Library/BaseLib/SwitchStack.c @@ -68,113 +68,3 @@ SwitchStack ( // ASSERT (FALSE); } - -VOID -EFIAPI -EnterUserImage ( - IN SWITCH_STACK_ENTRY_POINT EntryPoint, - IN VOID *Context1 OPTIONAL, - IN VOID *Context2 OPTIONAL, - IN VOID *NewStack, - IN UINT16 CodeSelector, - IN UINT16 DataSelector - ) -{ - ASSERT (EntryPoint != NULL); - ASSERT (NewStack != NULL); - - // - // New stack must be aligned with CPU_STACK_ALIGNMENT - // - ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0); - - InternalEnterUserImage (EntryPoint, Context1, Context2, NewStack, CodeSelector, DataSelector); -} - -UINTN -EFIAPI -CallBootService ( - IN UINT8 Type, - IN VOID **FunctionAddress, - IN UINTN CoreRbp, - IN UINTN UserRsp - ) -{ - UINTN Status; - VOID *Pointer; - VOID * Arg4; - VOID * Arg5; - UINT32 Arg6; - EFI_ALLOCATE_RING3_PAGES Func1; - EFI_ALLOCATE_CORE_COPY Func2; - EFI_LOCATE_PROTOCOL Func3; - EFI_OPEN_PROTOCOL Func4; - // Stack: - // rcx - Rip for SYSCALL - // r8 - Argument 1 - // rbp - User Rbp - // r9 - Argument 2 - // r11 - User data segment selector <- CoreRbp - // rsp - User Rsp - switch (Type) { - case SysCallReadMemory: - return *(UINTN *)FunctionAddress; - - case SysCallAllocateRing3Pages: - Func1 = (EFI_ALLOCATE_RING3_PAGES)*FunctionAddress; - Status = Func1 ( - *((UINTN *)CoreRbp + 3), - &Pointer - ); - DisableSMAP (); - *(UINTN *)(*((UINTN *)CoreRbp + 1)) = (UINTN)Pointer; - EnableSMAP (); - return (UINTN)Status; - - case SysCallAllocateCoreCopy: - DisableSMAP (); - Func2 = (EFI_ALLOCATE_CORE_COPY)*FunctionAddress; - Status = (UINTN)Func2 ( - *((UINTN *)CoreRbp + 3), - (VOID *)*((UINTN *)CoreRbp + 1) - ); - EnableSMAP (); - return (UINTN)Status; - - case SysCallLocateProtocol: - Func3 = (EFI_LOCATE_PROTOCOL)*FunctionAddress; - Status = Func3 ( - (VOID *)*((UINTN *)CoreRbp + 3), - (VOID *)*((UINTN *)CoreRbp + 1), - &Pointer - ); - DisableSMAP (); - *((UINTN *)UserRsp + 5) = (UINTN)Pointer; - EnableSMAP (); - return (UINTN)Status; - - case SysCallOpenProtocol: - DisableSMAP (); - Arg4 = (VOID *)*((UINTN *)UserRsp + 6); - Arg5 = (VOID *)*((UINTN *)UserRsp + 7); - Arg6 = (UINT32)*((UINTN *)UserRsp + 8); - EnableSMAP (); - Func4 = (EFI_OPEN_PROTOCOL)*FunctionAddress; - Status = Func4 ( - (VOID *)*((UINTN *)CoreRbp + 3), - (VOID *)*((UINTN *)CoreRbp + 1), - &Pointer, - Arg4, - Arg5, - Arg6 - ); - DisableSMAP (); - *((UINTN *)UserRsp + 5) = (UINTN)Pointer; - EnableSMAP (); - return (UINTN)Status; - default: - break; - } - - return 0; -} diff --git a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm index eb29524c82..81648ccc9f 100644 --- a/MdePkg/Library/BaseLib/X64/SwitchStack.nasm +++ b/MdePkg/Library/BaseLib/X64/SwitchStack.nasm @@ -1,6 +1,4 @@ ;------------------------------------------------------------------------------ -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -; SPDX-License-Identifier: BSD-3-Clause ; ; Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
; SPDX-License-Identifier: BSD-2-Clause-Patent @@ -16,8 +14,6 @@ DEFAULT REL SECTION .text -extern ASM_PFX(CallBootService) - ;------------------------------------------------------------------------------ ; Routine Description: ; @@ -46,158 +42,3 @@ ASM_PFX(InternalSwitchStack): ; lea rsp, [r9 - 0x20] call rax - -;------------------------------------------------------------------------------ -; Routine Description: -; -; Routine for transfering control to user image with 2 parameters -; -; Arguments: -; -; (rcx) EntryPoint - Entry point with new stack. -; (rdx) Context1 - Parameter1 for entry point. -; (r8) Context2 - Parameter2 for entry point. -; (r9) NewStack - The pointer to new stack. -;On stack CodeSelector - Segment selector for code. -;On stack DataSelector - Segment selector for data. -; -; Returns: -; -; None -; -;------------------------------------------------------------------------------ -global ASM_PFX(InternalEnterUserImage) -ASM_PFX(InternalEnterUserImage): - ; Set Data selectors - mov rax, [rsp + 8*6] - or rax, 3H ; RPL = 3 - - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - ; Save Code selector - mov r10, [rsp + 8*5] - or r10, 3H ; RPL = 3 - - ; Prepare stack before swithcing - push rax ; ss - push r9 ; rsp - push r10 ; cs - push rcx ; rip - - ; Save 2 parameters - mov rcx, rdx - mov rdx, r8 - - ; Pass control to user image - retfq - -%macro CallSysRet 0 - ; Prepare SYSRET arguments. - mov rcx, [rbp + 8*4] - pop rdx - - ; Switch from Core to User data segment selectors. - pop r11 - -o16 mov ds, r11 -o16 mov es, r11 -o16 mov fs, r11 -o16 mov gs, r11 - - ; Restore RFLAGS in R11 for SYSRET. - pushfq - pop r11 - - ; Switch to User Stack. - pop rbp - pop rbp - mov rsp, rdx - - ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. -o64 sysret - ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. -%endmacro - -global ASM_PFX(DisableSMAP) -ASM_PFX(DisableSMAP): - pushfq - pop r10 - or r10, 0x40000 ; Set AC (bit 18) - push r10 - popfq - ret - -global ASM_PFX(EnableSMAP) -ASM_PFX(EnableSMAP): - pushfq - pop r10 - and r10, ~0x40000 ; Clear AC (bit 18) - push r10 - popfq - ret - -;------------------------------------------------------------------------------ -; UINTN -; EFIAPI -; CoreBootServices ( -; IN UINT8 Type, -; IN UINTN FunctionAddress, -; ... -; ); -; -; (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). -; (rdx) FunctionAddress. -; (r8) Argument 1 of the called function. -; (r9) Argument 2 of the called function. -; (r10) Type. -; (r11) RFLAGS saved by SYSCALL in SysCall(). -;On stack Argument 3, 4, ... -;------------------------------------------------------------------------------ -global ASM_PFX(CoreBootServices) -ASM_PFX(CoreBootServices): - ; Save User data segment selector temporarily in R11. - mov r11, ds - - ; Switch from User to Core data segment selectors. - mov ax, ss - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - ; Save User Stack pointers and switch to Core SysCall Stack. - mov rax, [ASM_PFX(gCoreSysCallStackTop)] - ; Save return address for SYSRET. - sub rax, 8 - mov [rax], rcx - mov rcx, r10 - sub rax, 8 - mov [rax], r8 - sub rax, 8 - mov [rax], rbp - sub rax, 8 - mov [rax], r9 - ; Save User data segment selector on Core SysCall Stack. - sub rax, 8 - mov [rax], r11 - - mov r9, rsp - - mov rsp, rax - - mov rbp, rsp - mov r8, rbp - push r9 - - call ASM_PFX(CallBootService) - - CallSysRet - -SECTION .data - -global ASM_PFX(gCoreSysCallStackTop) -ASM_PFX(gCoreSysCallStackTop): - resq 1 From b8af28318329b99425bdbc080a625d5a47563290 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 2 Feb 2024 12:26:12 +0300 Subject: [PATCH 137/341] Ring3: Refactored out AllocateCoreCopy() BootService. --- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 3 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 67 ++++++++----------- MdePkg/Include/Uefi/UefiSpec.h | 15 ++--- .../Ring3UefiBootServicesTableLib/Ring3.h | 9 --- .../Ring3UefiBootServicesTableLib.c | 51 ++------------ 5 files changed, 42 insertions(+), 103 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index c726671d91..ef2e563b6b 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -90,8 +90,7 @@ EFI_BOOT_SERVICES mBootServices = { (EFI_COPY_MEM)CopyMem, // CopyMem (EFI_SET_MEM)SetMem, // SetMem (EFI_CREATE_EVENT_EX)CoreCreateEventEx, // CreateEventEx - (EFI_ALLOCATE_RING3_PAGES)AllocateRing3Pages, - (EFI_ALLOCATE_CORE_COPY)AllocateCopyPool + (EFI_ALLOCATE_RING3_PAGES)AllocateRing3Pages }; EFI_DXE_SERVICES mDxeServices = { diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 83afff65d5..915d14f493 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -5,11 +5,11 @@ **/ -#include -#include -#include +#include + #include -#include +#include +#include VOID EFIAPI @@ -34,15 +34,6 @@ InternalEnterUserImage ( IN UINT16 DataSelector ); -typedef enum { - SysCallReadMemory = 0, - SysCallAllocateRing3Pages = 1, - SysCallAllocateCoreCopy = 2, - SysCallLocateProtocol = 3, - SysCallOpenProtocol = 4, - SysCallMax -} SYS_CALL_TYPE; - UINTN EFIAPI CallBootService ( @@ -57,10 +48,9 @@ CallBootService ( VOID * Arg4; VOID * Arg5; UINT32 Arg6; - EFI_ALLOCATE_RING3_PAGES Func1; - EFI_ALLOCATE_CORE_COPY Func2; - EFI_LOCATE_PROTOCOL Func3; - EFI_OPEN_PROTOCOL Func4; + + EFI_GUID *CoreProtocol; + // Stack: // rcx - Rip for SYSCALL // r8 - Argument 1 @@ -69,37 +59,29 @@ CallBootService ( // r11 - User data segment selector <- CoreRbp // rsp - User Rsp switch (Type) { - case SysCallReadMemory: - return *(UINTN *)FunctionAddress; - case SysCallAllocateRing3Pages: - Func1 = (EFI_ALLOCATE_RING3_PAGES)*FunctionAddress; - Status = Func1 ( - *((UINTN *)CoreRbp + 3), - &Pointer - ); + Status = gBS->AllocateRing3Pages (*((UINTN *)CoreRbp + 3), &Pointer); DisableSMAP (); *(UINTN *)(*((UINTN *)CoreRbp + 1)) = (UINTN)Pointer; EnableSMAP (); return (UINTN)Status; - case SysCallAllocateCoreCopy: + case SysCallLocateProtocol: DisableSMAP (); - Func2 = (EFI_ALLOCATE_CORE_COPY)*FunctionAddress; - Status = (UINTN)Func2 ( - *((UINTN *)CoreRbp + 3), - (VOID *)*((UINTN *)CoreRbp + 1) - ); + CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)*((UINTN *)CoreRbp + 3)); EnableSMAP (); - return (UINTN)Status; + if (CoreProtocol == NULL) { + DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate core copy of the Protocol variable.\n")); + return EFI_OUT_OF_RESOURCES; + } - case SysCallLocateProtocol: - Func3 = (EFI_LOCATE_PROTOCOL)*FunctionAddress; - Status = Func3 ( - (VOID *)*((UINTN *)CoreRbp + 3), + Status = gBS->LocateProtocol ( + CoreProtocol, (VOID *)*((UINTN *)CoreRbp + 1), &Pointer ); + + FreePool (CoreProtocol); DisableSMAP (); *((UINTN *)UserRsp + 5) = (UINTN)Pointer; EnableSMAP (); @@ -107,19 +89,26 @@ CallBootService ( case SysCallOpenProtocol: DisableSMAP (); + CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)*((UINTN *)CoreRbp + 1)); Arg4 = (VOID *)*((UINTN *)UserRsp + 6); Arg5 = (VOID *)*((UINTN *)UserRsp + 7); Arg6 = (UINT32)*((UINTN *)UserRsp + 8); EnableSMAP (); - Func4 = (EFI_OPEN_PROTOCOL)*FunctionAddress; - Status = Func4 ( + if (CoreProtocol == NULL) { + DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate core copy of the Protocol variable.\n")); + return EFI_OUT_OF_RESOURCES; + } + + Status = gBS->OpenProtocol ( (VOID *)*((UINTN *)CoreRbp + 3), - (VOID *)*((UINTN *)CoreRbp + 1), + CoreProtocol, &Pointer, Arg4, Arg5, Arg6 ); + + FreePool (CoreProtocol); DisableSMAP (); *((UINTN *)UserRsp + 5) = (UINTN)Pointer; EnableSMAP (); diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index f586847500..42139faf71 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -229,13 +229,6 @@ EFI_STATUS IN OUT VOID **Memory ); -typedef -VOID * -(EFIAPI *EFI_ALLOCATE_CORE_COPY)( - IN UINTN AllocationSize, - IN CONST VOID *Buffer - ); - /** Frees memory pages. @@ -2038,9 +2031,15 @@ typedef struct { EFI_SET_MEM SetMem; EFI_CREATE_EVENT_EX CreateEventEx; EFI_ALLOCATE_RING3_PAGES AllocateRing3Pages; - EFI_ALLOCATE_CORE_COPY AllocateCoreCopy; } EFI_BOOT_SERVICES; +typedef enum { + SysCallLocateProtocol = 1, + SysCallOpenProtocol = 2, + SysCallAllocateRing3Pages = 3, + SysCallMax +} SYS_CALL_TYPE; + /// /// Contains a set of GUID/pointer pairs comprised of the ConfigurationTable field in the /// EFI System Table. diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h index 4f14ead758..e13c3e4daa 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h @@ -5,15 +5,6 @@ **/ -typedef enum { - SysCallReadMemory = 0, - SysCallAllocateRing3Pages = 1, - SysCallAllocateCoreCopy = 2, - SysCallLocateProtocol = 3, - SysCallOpenProtocol = 4, - SysCallMax -} SYS_CALL_TYPE; - UINTN EFIAPI SysCall ( diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index d62d8d50ef..b764b51080 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -71,7 +71,6 @@ EFI_BOOT_SERVICES mBootServices = { }; EFI_BOOT_SERVICES *gBS = &mBootServices; -EFI_BOOT_SERVICES *mCoreBS = NULL; EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mCoreDevicePathUtilitiesProtocol = NULL; EFI_LOADED_IMAGE_PROTOCOL *mCoreLoadedImageProtocol = NULL; @@ -92,16 +91,6 @@ UefiBootServicesTableLibConstructor ( IN EFI_SYSTEM_TABLE *SystemTable ) { - // - // Cache pointer to the EFI Boot Services Table - // - mCoreBS = (EFI_BOOT_SERVICES *)SysCall ( - SysCallReadMemory, - (UINTN)SystemTable + OFFSET_OF (EFI_SYSTEM_TABLE, BootServices) - ); - ASSERT (mCoreBS != NULL); - DEBUG ((DEBUG_ERROR, "User: BootServices = 0x%lx\n", (UINTN)mCoreBS)); - return EFI_SUCCESS; } @@ -452,26 +441,14 @@ Ring3OpenProtocol ( ) { EFI_STATUS Status; - EFI_GUID *CoreProtocol; EFI_LOADED_IMAGE_PROTOCOL *UserProtocol; - CoreProtocol = (VOID *)SysCall ( - SysCallAllocateCoreCopy, - (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, AllocateCoreCopy), - sizeof (EFI_GUID), - Protocol - ); - if (CoreProtocol == NULL) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate core copy of the Protocol variable.\n")); - return EFI_OUT_OF_RESOURCES; - } - Status = (EFI_STATUS)SysCall ( SysCallOpenProtocol, - (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, OpenProtocol), + 0, CoreUserHandle, - CoreProtocol, + Protocol, Interface, CoreImageHandle, CoreControllerHandle, @@ -482,14 +459,12 @@ Ring3OpenProtocol ( return Status; } - // TODO: FreePool (CoreProtocol); - if (CompareGuid (Protocol, &gEfiLoadedImageProtocolGuid)) { mCoreLoadedImageProtocol = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; Status = (EFI_STATUS)SysCall ( SysCallAllocateRing3Pages, - (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, AllocateRing3Pages), + 0, EFI_SIZE_TO_PAGES (sizeof (EFI_LOADED_IMAGE_PROTOCOL)), (VOID **)&UserProtocol ); @@ -579,25 +554,13 @@ Ring3LocateProtocol ( ) { EFI_STATUS Status; - EFI_GUID *CoreProtocol; EFI_DEVICE_PATH_UTILITIES_PROTOCOL *UserProtocol; - CoreProtocol = (VOID *)SysCall ( - SysCallAllocateCoreCopy, - (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, AllocateCoreCopy), - sizeof (EFI_GUID), - Protocol - ); - if (CoreProtocol == NULL) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate core copy of the Protocol variable.\n")); - return EFI_OUT_OF_RESOURCES; - } - Status = (EFI_STATUS)SysCall ( SysCallLocateProtocol, - (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, LocateProtocol), - CoreProtocol, + 0, + Protocol, CoreRegistration, Interface ); @@ -606,14 +569,12 @@ Ring3LocateProtocol ( return Status; } - // TODO: FreePool (CoreProtocol); - if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { mCoreDevicePathUtilitiesProtocol = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; Status = (EFI_STATUS)SysCall ( SysCallAllocateRing3Pages, - (UINTN)mCoreBS + OFFSET_OF (EFI_BOOT_SERVICES, AllocateRing3Pages), + 0, EFI_SIZE_TO_PAGES (sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL)), (VOID **)&UserProtocol ); From 666d806bce291716f626f640dcd002136b873877 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 2 Feb 2024 14:49:47 +0300 Subject: [PATCH 138/341] Ring3: Refactored out AllocateRing3Pages() BootService. --- MdeModulePkg/Core/Dxe/DxeMain.h | 8 +-- MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 3 +- MdeModulePkg/Core/Dxe/Image/Image.c | 24 ++++----- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 53 +++++++++++++------ MdePkg/Include/Uefi/UefiSpec.h | 9 ---- .../Ring3UefiBootServicesTableLib.c | 53 +++---------------- 7 files changed, 62 insertions(+), 89 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 59a56d0148..3270f83bda 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -1174,11 +1174,11 @@ CoreAllocatePages ( IN OUT EFI_PHYSICAL_ADDRESS *Memory ); -EFI_STATUS +VOID * EFIAPI -AllocateRing3Pages ( - IN UINTN NumberOfPages, - IN OUT VOID **Memory +AllocateRing3CopyPages ( + IN VOID *MemoryCore, + IN UINT32 MemoryCoreSize ); /** diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index b922f2102c..c62b25f0fc 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -163,6 +163,7 @@ gEfiHiiPackageListProtocolGuid ## SOMETIMES_PRODUCES gEfiSmmBase2ProtocolGuid ## SOMETIMES_CONSUMES gEdkiiPeCoffImageEmulatorProtocolGuid ## SOMETIMES_CONSUMES + gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES # Arch Protocols gEfiBdsArchProtocolGuid ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index ef2e563b6b..d36d0061af 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -89,8 +89,7 @@ EFI_BOOT_SERVICES mBootServices = { (EFI_CALCULATE_CRC32)CoreEfiNotAvailableYetArg3, // CalculateCrc32 (EFI_COPY_MEM)CopyMem, // CopyMem (EFI_SET_MEM)SetMem, // SetMem - (EFI_CREATE_EVENT_EX)CoreCreateEventEx, // CreateEventEx - (EFI_ALLOCATE_RING3_PAGES)AllocateRing3Pages + (EFI_CREATE_EVENT_EX)CoreCreateEventEx // CreateEventEx }; EFI_DXE_SERVICES mDxeServices = { diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 4dc510d919..e9f030fb3d 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1565,25 +1565,25 @@ CoreLoadImage ( return Status; } -EFI_STATUS +VOID * EFIAPI -AllocateRing3Pages ( - IN UINTN NumberOfPages, - IN OUT VOID **Memory +AllocateRing3CopyPages ( + IN VOID *MemoryCore, + IN UINT32 MemoryCoreSize ) { - if (Memory == NULL) { - return EFI_INVALID_PARAMETER; - } + VOID *MemoryRing3; - *Memory = AllocatePages (NumberOfPages); - if (*Memory == NULL) { - return EFI_OUT_OF_RESOURCES; + MemoryRing3 = AllocatePages (EFI_SIZE_TO_PAGES (MemoryCoreSize)); + if (MemoryRing3 == NULL) { + return NULL; } - SetUefiImageMemoryAttributes ((UINTN)*Memory, EFI_PAGES_TO_SIZE (NumberOfPages), EFI_MEMORY_USER); + CopyMem (MemoryRing3, MemoryCore, MemoryCoreSize); - return EFI_SUCCESS; + SetUefiImageMemoryAttributes ((UINTN)MemoryRing3, EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (MemoryCoreSize)), EFI_MEMORY_USER); + + return MemoryRing3; } /** diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 915d14f493..98b3ab6662 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -5,11 +5,9 @@ **/ -#include +#include "DxeMain.h" -#include -#include -#include +#include VOID EFIAPI @@ -50,6 +48,7 @@ CallBootService ( UINT32 Arg6; EFI_GUID *CoreProtocol; + UINT32 MemoryCoreSize; // Stack: // rcx - Rip for SYSCALL @@ -59,13 +58,6 @@ CallBootService ( // r11 - User data segment selector <- CoreRbp // rsp - User Rsp switch (Type) { - case SysCallAllocateRing3Pages: - Status = gBS->AllocateRing3Pages (*((UINTN *)CoreRbp + 3), &Pointer); - DisableSMAP (); - *(UINTN *)(*((UINTN *)CoreRbp + 1)) = (UINTN)Pointer; - EnableSMAP (); - return (UINTN)Status; - case SysCallLocateProtocol: DisableSMAP (); CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)*((UINTN *)CoreRbp + 3)); @@ -81,10 +73,25 @@ CallBootService ( &Pointer ); - FreePool (CoreProtocol); + if (CompareGuid (CoreProtocol, &gEfiDevicePathUtilitiesProtocolGuid)) { + MemoryCoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); + } else { + MemoryCoreSize = 0; + } + + Pointer = AllocateRing3CopyPages (Pointer, MemoryCoreSize); + if (Pointer == NULL) { + DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n")); + FreePool (CoreProtocol); + return EFI_OUT_OF_RESOURCES; + } + DisableSMAP (); - *((UINTN *)UserRsp + 5) = (UINTN)Pointer; + *(UINTN *)(*((UINTN *)UserRsp + 5)) = (UINTN)Pointer; EnableSMAP (); + + FreePool (CoreProtocol); + return (UINTN)Status; case SysCallOpenProtocol: @@ -108,11 +115,27 @@ CallBootService ( Arg6 ); - FreePool (CoreProtocol); + if (CompareGuid (CoreProtocol, &gEfiLoadedImageProtocolGuid)) { + MemoryCoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); + } else { + MemoryCoreSize = 0; + } + + Pointer = AllocateRing3CopyPages (Pointer, MemoryCoreSize); + if (Pointer == NULL) { + DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n")); + FreePool (CoreProtocol); + return EFI_OUT_OF_RESOURCES; + } + DisableSMAP (); - *((UINTN *)UserRsp + 5) = (UINTN)Pointer; + *(UINTN *)(*((UINTN *)UserRsp + 5)) = (UINTN)Pointer; EnableSMAP (); + + FreePool (CoreProtocol); + return (UINTN)Status; + default: break; } diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 42139faf71..a7dedecace 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -222,13 +222,6 @@ EFI_STATUS IN OUT EFI_PHYSICAL_ADDRESS *Memory ); -typedef -EFI_STATUS -(EFIAPI *EFI_ALLOCATE_RING3_PAGES)( - IN UINTN Pages, - IN OUT VOID **Memory - ); - /** Frees memory pages. @@ -2030,13 +2023,11 @@ typedef struct { EFI_COPY_MEM CopyMem; EFI_SET_MEM SetMem; EFI_CREATE_EVENT_EX CreateEventEx; - EFI_ALLOCATE_RING3_PAGES AllocateRing3Pages; } EFI_BOOT_SERVICES; typedef enum { SysCallLocateProtocol = 1, SysCallOpenProtocol = 2, - SysCallAllocateRing3Pages = 3, SysCallMax } SYS_CALL_TYPE; diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index b764b51080..cfd204559b 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -70,10 +70,7 @@ EFI_BOOT_SERVICES mBootServices = { (EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx }; -EFI_BOOT_SERVICES *gBS = &mBootServices; - -EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mCoreDevicePathUtilitiesProtocol = NULL; -EFI_LOADED_IMAGE_PROTOCOL *mCoreLoadedImageProtocol = NULL; +EFI_BOOT_SERVICES *gBS = &mBootServices; /** The function constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. @@ -460,36 +457,11 @@ Ring3OpenProtocol ( } if (CompareGuid (Protocol, &gEfiLoadedImageProtocolGuid)) { - mCoreLoadedImageProtocol = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; - - Status = (EFI_STATUS)SysCall ( - SysCallAllocateRing3Pages, - 0, - EFI_SIZE_TO_PAGES (sizeof (EFI_LOADED_IMAGE_PROTOCOL)), - (VOID **)&UserProtocol - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate pages for Ring3 EFI_LOADED_IMAGE_PROTOCOL structure.\n")); - return Status; - } - - // TODO: Copy Core Interface fields with AllocateRing3Pages(). - - UserProtocol->Revision = 0; - UserProtocol->ParentHandle = NULL; - UserProtocol->SystemTable = NULL; - UserProtocol->DeviceHandle = NULL; - UserProtocol->FilePath = NULL; - UserProtocol->Reserved = 0; - UserProtocol->LoadOptionsSize = 0; - UserProtocol->LoadOptions = NULL; - UserProtocol->ImageBase = NULL; - UserProtocol->ImageSize = 0; - UserProtocol->ImageCodeType = 0; - UserProtocol->ImageDataType = 0; - UserProtocol->Unload = NULL; + UserProtocol = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; - *Interface = UserProtocol; + // TODO: Copy User changes to Core? Resembles InstallMultipleProtocolInterfaces(). + + UserProtocol->Unload = NULL; return Status; } @@ -570,18 +542,7 @@ Ring3LocateProtocol ( } if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { - mCoreDevicePathUtilitiesProtocol = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; - - Status = (EFI_STATUS)SysCall ( - SysCallAllocateRing3Pages, - 0, - EFI_SIZE_TO_PAGES (sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL)), - (VOID **)&UserProtocol - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate pages for Ring3 EFI_DEVICE_PATH_UTILITIES_PROTOCOL structure.\n")); - return Status; - } + UserProtocol = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; UserProtocol->GetDevicePathSize = NULL; UserProtocol->DuplicateDevicePath = NULL; @@ -592,8 +553,6 @@ Ring3LocateProtocol ( UserProtocol->IsDevicePathMultiInstance = NULL; UserProtocol->CreateDeviceNode = NULL; - *Interface = UserProtocol; - return Status; } From 9a69d39c323e551ebf8f0e524a07644a2b8509b1 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 5 Feb 2024 11:49:13 +0300 Subject: [PATCH 139/341] Ring3: Refactored out FunctionAddress from API. --- MdeModulePkg/Core/Dxe/DxeMain.h | 1 - MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 16 ++++++++-------- .../Dxe/SysCall/X64/CoreBootServices.nasm | 19 ++++++++++--------- .../Ring3UefiBootServicesTableLib/Ring3.h | 1 - .../Ring3UefiBootServicesTableLib.c | 2 -- .../Ring3UefiBootServicesTableLib.inf | 4 ++++ .../X64/SysCall.nasm | 1 - 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 3270f83bda..4786759b00 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2839,7 +2839,6 @@ UINTN EFIAPI CoreBootServices ( IN UINT8 Type, - IN UINTN FunctionAddress, ... ); diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 98b3ab6662..689754fb9e 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -36,7 +36,6 @@ UINTN EFIAPI CallBootService ( IN UINT8 Type, - IN VOID **FunctionAddress, IN UINTN CoreRbp, IN UINTN UserRsp ) @@ -52,11 +51,12 @@ CallBootService ( // Stack: // rcx - Rip for SYSCALL - // r8 - Argument 1 + // rdx - Argument 1 // rbp - User Rbp - // r9 - Argument 2 + // r8 - Argument 2 // r11 - User data segment selector <- CoreRbp // rsp - User Rsp + // r9 - Argument 3 switch (Type) { case SysCallLocateProtocol: DisableSMAP (); @@ -87,7 +87,7 @@ CallBootService ( } DisableSMAP (); - *(UINTN *)(*((UINTN *)UserRsp + 5)) = (UINTN)Pointer; + *(UINTN *)(*((UINTN *)CoreRbp - 2)) = (UINTN)Pointer; EnableSMAP (); FreePool (CoreProtocol); @@ -97,9 +97,9 @@ CallBootService ( case SysCallOpenProtocol: DisableSMAP (); CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)*((UINTN *)CoreRbp + 1)); - Arg4 = (VOID *)*((UINTN *)UserRsp + 6); - Arg5 = (VOID *)*((UINTN *)UserRsp + 7); - Arg6 = (UINT32)*((UINTN *)UserRsp + 8); + Arg4 = (VOID *)*((UINTN *)UserRsp + 5); + Arg5 = (VOID *)*((UINTN *)UserRsp + 6); + Arg6 = (UINT32)*((UINTN *)UserRsp + 7); EnableSMAP (); if (CoreProtocol == NULL) { DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate core copy of the Protocol variable.\n")); @@ -129,7 +129,7 @@ CallBootService ( } DisableSMAP (); - *(UINTN *)(*((UINTN *)UserRsp + 5)) = (UINTN)Pointer; + *(UINTN *)(*((UINTN *)CoreRbp - 2)) = (UINTN)Pointer; EnableSMAP (); FreePool (CoreProtocol); diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 421dbcc8da..3eb32b75bd 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -15,6 +15,7 @@ extern ASM_PFX(gCoreSysCallStackTop) ; Prepare SYSRET arguments. mov rcx, [rbp + 8*4] pop rdx + pop rdx ; Switch from Core to User data segment selectors. pop r11 @@ -61,17 +62,16 @@ ASM_PFX(EnableSMAP): ; EFIAPI ; CoreBootServices ( ; IN UINT8 Type, -; IN UINTN FunctionAddress, ; ... ; ); ; ; (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). -; (rdx) FunctionAddress. -; (r8) Argument 1 of the called function. -; (r9) Argument 2 of the called function. +; (rdx) Argument 1 of the called function. +; (r8) Argument 2 of the called function. +; (r9) Argument 3 of the called function. ; (r10) Type. ; (r11) RFLAGS saved by SYSCALL in SysCall(). -;On stack Argument 3, 4, ... +;On stack Argument 4, 5, ... ;------------------------------------------------------------------------------ global ASM_PFX(CoreBootServices) ASM_PFX(CoreBootServices): @@ -92,21 +92,22 @@ ASM_PFX(CoreBootServices): mov [rax], rcx mov rcx, r10 sub rax, 8 - mov [rax], r8 + mov [rax], rdx sub rax, 8 mov [rax], rbp sub rax, 8 - mov [rax], r9 + mov [rax], r8 ; Save User data segment selector on Core SysCall Stack. sub rax, 8 mov [rax], r11 - mov r9, rsp + mov r8, rsp mov rsp, rax mov rbp, rsp - mov r8, rbp + mov rdx, rbp + push r8 push r9 call ASM_PFX(CallBootService) diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h index e13c3e4daa..66e566f751 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h @@ -9,7 +9,6 @@ UINTN EFIAPI SysCall ( IN UINT8 Type, - IN UINTN FunctionAddress, ... ); diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index cfd204559b..4c336e1a29 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -443,7 +443,6 @@ Ring3OpenProtocol ( Status = (EFI_STATUS)SysCall ( SysCallOpenProtocol, - 0, CoreUserHandle, Protocol, Interface, @@ -531,7 +530,6 @@ Ring3LocateProtocol ( Status = (EFI_STATUS)SysCall ( SysCallLocateProtocol, - 0, Protocol, CoreRegistration, Interface diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf index f1128c94d3..c17cb16fe5 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf @@ -35,3 +35,7 @@ [LibraryClasses] BaseMemoryLib DebugLib + +[Protocols] + gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES + gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm b/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm index b888ab5d8c..f6ea57d787 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm @@ -11,7 +11,6 @@ ; EFIAPI ; SysCall ( ; IN UINT8 Type, -; IN UINTN FunctionAddress, ; ... ; ); ;------------------------------------------------------------------------------ From 269f75447aa4a8e88baeec66c8346a66f0c816c3 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 5 Feb 2024 13:36:43 +0300 Subject: [PATCH 140/341] Ring3: Refactored stack operations. --- MdeModulePkg/Core/Dxe/DxeMain.h | 2 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 120 +++++++++++------- .../Dxe/SysCall/X64/CoreBootServices.nasm | 89 ++++++------- .../Ring3UefiBootServicesTableLib/Ring3.h | 2 +- .../Ring3UefiBootServicesTableLib.c | 30 ++--- .../X64/SysCall.nasm | 2 +- 6 files changed, 132 insertions(+), 113 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 4786759b00..b6004f293c 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2835,7 +2835,7 @@ SetUefiImageMemoryAttributes ( IN UINT64 Attributes ); -UINTN +EFI_STATUS EFIAPI CoreBootServices ( IN UINT8 Type, diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 689754fb9e..925b5d6eea 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -32,35 +32,55 @@ InternalEnterUserImage ( IN UINT16 DataSelector ); -UINTN +typedef struct { + UINTN Argument1; + UINTN Argument2; + UINTN Argument3; +} CORE_STACK; + +typedef struct { + UINTN Rip; + UINTN Arguments[]; +} RING3_STACK; +// +// Stack: +// rsp - User Rsp +// rbp - User Rbp +// rcx - Rip for SYSCALL +// r11 - User data segment selector +// r9 - Argument 3 +// r8 - Argument 2 +// rdx - Argument 1 <- CoreRbp +// +EFI_STATUS EFIAPI CallBootService ( - IN UINT8 Type, - IN UINTN CoreRbp, - IN UINTN UserRsp + IN UINT8 Type, + IN CORE_STACK *CoreRbp, + IN RING3_STACK *UserRsp ) { - UINTN Status; - VOID *Pointer; - VOID * Arg4; - VOID * Arg5; - UINT32 Arg6; - - EFI_GUID *CoreProtocol; - UINT32 MemoryCoreSize; - - // Stack: - // rcx - Rip for SYSCALL - // rdx - Argument 1 - // rbp - User Rbp - // r8 - Argument 2 - // r11 - User data segment selector <- CoreRbp - // rsp - User Rsp - // r9 - Argument 3 + EFI_STATUS Status; + UINT64 Attributes; + VOID *Interface; + EFI_GUID *CoreProtocol; + UINT32 MemoryCoreSize; + EFI_HANDLE Argument4; + EFI_HANDLE Argument5; + UINT32 Argument6; + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + switch (Type) { case SysCallLocateProtocol: + // + // Argument 1: EFI_GUID *Protocol + // Argument 2: VOID *CoreRegistration + // Argument 3: VOID **Interface + // DisableSMAP (); - CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)*((UINTN *)CoreRbp + 3)); + CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)CoreRbp->Argument1); EnableSMAP (); if (CoreProtocol == NULL) { DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate core copy of the Protocol variable.\n")); @@ -68,10 +88,10 @@ CallBootService ( } Status = gBS->LocateProtocol ( - CoreProtocol, - (VOID *)*((UINTN *)CoreRbp + 1), - &Pointer - ); + CoreProtocol, + (VOID *)CoreRbp->Argument2, + &Interface + ); if (CompareGuid (CoreProtocol, &gEfiDevicePathUtilitiesProtocolGuid)) { MemoryCoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); @@ -79,27 +99,35 @@ CallBootService ( MemoryCoreSize = 0; } - Pointer = AllocateRing3CopyPages (Pointer, MemoryCoreSize); - if (Pointer == NULL) { + Interface = AllocateRing3CopyPages (Interface, MemoryCoreSize); + if (Interface == NULL) { DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n")); FreePool (CoreProtocol); return EFI_OUT_OF_RESOURCES; } DisableSMAP (); - *(UINTN *)(*((UINTN *)CoreRbp - 2)) = (UINTN)Pointer; + *(VOID **)CoreRbp->Argument3 = Interface; EnableSMAP (); FreePool (CoreProtocol); - return (UINTN)Status; + return Status; case SysCallOpenProtocol: + // + // Argument 1: EFI_HANDLE CoreUserHandle + // Argument 2: EFI_GUID *Protocol + // Argument 3: VOID **Interface + // Argument 4: EFI_HANDLE CoreImageHandle + // Argument 5: EFI_HANDLE CoreControllerHandle + // Argument 6: UINT32 Attributes + // DisableSMAP (); - CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)*((UINTN *)CoreRbp + 1)); - Arg4 = (VOID *)*((UINTN *)UserRsp + 5); - Arg5 = (VOID *)*((UINTN *)UserRsp + 6); - Arg6 = (UINT32)*((UINTN *)UserRsp + 7); + CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)CoreRbp->Argument2); + Argument4 = (EFI_HANDLE)UserRsp->Arguments[4]; + Argument5 = (EFI_HANDLE)UserRsp->Arguments[5]; + Argument6 = (UINT32)UserRsp->Arguments[6]; EnableSMAP (); if (CoreProtocol == NULL) { DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate core copy of the Protocol variable.\n")); @@ -107,13 +135,13 @@ CallBootService ( } Status = gBS->OpenProtocol ( - (VOID *)*((UINTN *)CoreRbp + 3), - CoreProtocol, - &Pointer, - Arg4, - Arg5, - Arg6 - ); + (EFI_HANDLE)CoreRbp->Argument1, + CoreProtocol, + &Interface, + Argument4, + Argument5, + Argument6 + ); if (CompareGuid (CoreProtocol, &gEfiLoadedImageProtocolGuid)) { MemoryCoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); @@ -121,26 +149,26 @@ CallBootService ( MemoryCoreSize = 0; } - Pointer = AllocateRing3CopyPages (Pointer, MemoryCoreSize); - if (Pointer == NULL) { + Interface = AllocateRing3CopyPages (Interface, MemoryCoreSize); + if (Interface == NULL) { DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n")); FreePool (CoreProtocol); return EFI_OUT_OF_RESOURCES; } DisableSMAP (); - *(UINTN *)(*((UINTN *)CoreRbp - 2)) = (UINTN)Pointer; + *(VOID **)CoreRbp->Argument3 = Interface; EnableSMAP (); FreePool (CoreProtocol); - return (UINTN)Status; + return Status; default: break; } - return 0; + return EFI_UNSUPPORTED; } VOID diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 3eb32b75bd..34d21a02e7 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -11,34 +11,6 @@ SECTION .text extern ASM_PFX(CallBootService) extern ASM_PFX(gCoreSysCallStackTop) -%macro CallSysRet 0 - ; Prepare SYSRET arguments. - mov rcx, [rbp + 8*4] - pop rdx - pop rdx - - ; Switch from Core to User data segment selectors. - pop r11 - -o16 mov ds, r11 -o16 mov es, r11 -o16 mov fs, r11 -o16 mov gs, r11 - - ; Restore RFLAGS in R11 for SYSRET. - pushfq - pop r11 - - ; Switch to User Stack. - pop rbp - pop rbp - mov rsp, rdx - - ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. -o64 sysret - ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. -%endmacro - global ASM_PFX(DisableSMAP) ASM_PFX(DisableSMAP): pushfq @@ -58,7 +30,7 @@ ASM_PFX(EnableSMAP): ret ;------------------------------------------------------------------------------ -; UINTN +; EFI_STATUS ; EFIAPI ; CoreBootServices ( ; IN UINT8 Type, @@ -71,7 +43,8 @@ ASM_PFX(EnableSMAP): ; (r9) Argument 3 of the called function. ; (r10) Type. ; (r11) RFLAGS saved by SYSCALL in SysCall(). -;On stack Argument 4, 5, ... +; +; (On User Stack) Argument 4, 5, ... ;------------------------------------------------------------------------------ global ASM_PFX(CoreBootServices) ASM_PFX(CoreBootServices): @@ -87,32 +60,50 @@ ASM_PFX(CoreBootServices): ; Save User Stack pointers and switch to Core SysCall Stack. mov rax, [ASM_PFX(gCoreSysCallStackTop)] - ; Save return address for SYSRET. - sub rax, 8 - mov [rax], rcx - mov rcx, r10 - sub rax, 8 - mov [rax], rdx sub rax, 8 - mov [rax], rbp - sub rax, 8 - mov [rax], r8 - ; Save User data segment selector on Core SysCall Stack. - sub rax, 8 - mov [rax], r11 - - mov r8, rsp - + mov [rax], rsp mov rsp, rax - + push rbp + ; Save return address for SYSRET. + push rcx + ; Save User data segment selector. + push r11 + ; Save User Arguments [1..3]. + push r9 + push r8 + push rdx mov rbp, rsp + + ; Prepare CallBootService arguments. + mov rcx, r10 mov rdx, rbp - push r8 - push r9 + mov r8, [rbp + 8*6] call ASM_PFX(CallBootService) - CallSysRet + ; Step over Arguments [1..3]. + add rsp, 8*3 + + ; Switch from Core to User data segment selectors. + pop r11 + +o16 mov ds, r11 +o16 mov es, r11 +o16 mov fs, r11 +o16 mov gs, r11 + + ; Prepare SYSRET arguments. + pop rcx + pushfq + pop r11 + + ; Switch to User Stack. + pop rbp + pop rsp + + ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. +o64 sysret + ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. ;------------------------------------------------------------------------------ ; Routine Description: diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h index 66e566f751..2713748f40 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h @@ -5,7 +5,7 @@ **/ -UINTN +EFI_STATUS EFIAPI SysCall ( IN UINT8 Type, diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index 4c336e1a29..24b87c3f91 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -441,15 +441,15 @@ Ring3OpenProtocol ( EFI_LOADED_IMAGE_PROTOCOL *UserProtocol; - Status = (EFI_STATUS)SysCall ( - SysCallOpenProtocol, - CoreUserHandle, - Protocol, - Interface, - CoreImageHandle, - CoreControllerHandle, - Attributes - ); + Status = SysCall ( + SysCallOpenProtocol, + CoreUserHandle, + Protocol, + Interface, + CoreImageHandle, + CoreControllerHandle, + Attributes + ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Ring3: Failed to open protocol %g\n", Protocol)); return Status; @@ -528,12 +528,12 @@ Ring3LocateProtocol ( EFI_DEVICE_PATH_UTILITIES_PROTOCOL *UserProtocol; - Status = (EFI_STATUS)SysCall ( - SysCallLocateProtocol, - Protocol, - CoreRegistration, - Interface - ); + Status = SysCall ( + SysCallLocateProtocol, + Protocol, + CoreRegistration, + Interface + ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Ring3: Failed to loacate protocol %g\n", Protocol)); return Status; diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm b/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm index f6ea57d787..742063ce72 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm @@ -7,7 +7,7 @@ SECTION .text ;------------------------------------------------------------------------------ -; UINTN +; EFI_STATUS ; EFIAPI ; SysCall ( ; IN UINT8 Type, From 59af4e0b0fe69bc955452906915ab002b3594eba Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 5 Feb 2024 17:26:13 +0300 Subject: [PATCH 141/341] Ring3: Added SysCallInstallMultipleProtocolInterfaces draft. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 3 + MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 91 +++++++++++++------ .../Core/Dxe/SysCall/DriverBindingProtocol.c | 42 +++++++++ .../Core/Dxe/SysCall/SupportedProtocols.h | 31 +++++++ MdePkg/Include/Uefi/UefiSpec.h | 5 +- .../Ring3UefiBootServicesTableLib.c | 5 +- 6 files changed, 147 insertions(+), 30 deletions(-) create mode 100644 MdeModulePkg/Core/Dxe/SysCall/DriverBindingProtocol.c create mode 100644 MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index c62b25f0fc..46e1310d6d 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -68,6 +68,8 @@ DxeMain/DxeProtocolNotify.c DxeMain/DxeMain.c SysCall/BootServices.c + SysCall/SupportedProtocols.h + SysCall/DriverBindingProtocol.c [Sources.X64] SysCall/X64/CoreBootServices.nasm @@ -164,6 +166,7 @@ gEfiSmmBase2ProtocolGuid ## SOMETIMES_CONSUMES gEdkiiPeCoffImageEmulatorProtocolGuid ## SOMETIMES_CONSUMES gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES + gEfiComponentNameProtocolGuid ## SOMETIMES_CONSUMES # Arch Protocols gEfiBdsArchProtocolGuid ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 925b5d6eea..c579873bec 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -6,9 +6,13 @@ **/ #include "DxeMain.h" +#include "SupportedProtocols.h" +#include #include +#define MAX_LIST 32 + VOID EFIAPI DisableSMAP ( @@ -68,6 +72,10 @@ CallBootService ( EFI_HANDLE Argument4; EFI_HANDLE Argument5; UINT32 Argument6; + UINT32 Index; + UINTN *ArgList[MAX_LIST]; + + EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -80,12 +88,14 @@ CallBootService ( // Argument 3: VOID **Interface // DisableSMAP (); - CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)CoreRbp->Argument1); - EnableSMAP (); - if (CoreProtocol == NULL) { - DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate core copy of the Protocol variable.\n")); - return EFI_OUT_OF_RESOURCES; + if (CompareGuid ((EFI_GUID *)CoreRbp->Argument1, &gEfiDevicePathUtilitiesProtocolGuid)) { + CoreProtocol = &gEfiDevicePathUtilitiesProtocolGuid; + MemoryCoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); + } else { + CoreProtocol = NULL; + MemoryCoreSize = 0; } + EnableSMAP (); Status = gBS->LocateProtocol ( CoreProtocol, @@ -93,16 +103,9 @@ CallBootService ( &Interface ); - if (CompareGuid (CoreProtocol, &gEfiDevicePathUtilitiesProtocolGuid)) { - MemoryCoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); - } else { - MemoryCoreSize = 0; - } - Interface = AllocateRing3CopyPages (Interface, MemoryCoreSize); if (Interface == NULL) { DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n")); - FreePool (CoreProtocol); return EFI_OUT_OF_RESOURCES; } @@ -110,8 +113,6 @@ CallBootService ( *(VOID **)CoreRbp->Argument3 = Interface; EnableSMAP (); - FreePool (CoreProtocol); - return Status; case SysCallOpenProtocol: @@ -124,15 +125,18 @@ CallBootService ( // Argument 6: UINT32 Attributes // DisableSMAP (); - CoreProtocol = AllocateCopyPool (sizeof (EFI_GUID), (VOID *)CoreRbp->Argument2); + if (CompareGuid ((EFI_GUID *)CoreRbp->Argument2, &gEfiLoadedImageProtocolGuid)) { + CoreProtocol = &gEfiLoadedImageProtocolGuid; + MemoryCoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); + } else { + CoreProtocol = NULL; + MemoryCoreSize = 0; + } + Argument4 = (EFI_HANDLE)UserRsp->Arguments[4]; Argument5 = (EFI_HANDLE)UserRsp->Arguments[5]; Argument6 = (UINT32)UserRsp->Arguments[6]; EnableSMAP (); - if (CoreProtocol == NULL) { - DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate core copy of the Protocol variable.\n")); - return EFI_OUT_OF_RESOURCES; - } Status = gBS->OpenProtocol ( (EFI_HANDLE)CoreRbp->Argument1, @@ -143,16 +147,9 @@ CallBootService ( Argument6 ); - if (CompareGuid (CoreProtocol, &gEfiLoadedImageProtocolGuid)) { - MemoryCoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); - } else { - MemoryCoreSize = 0; - } - Interface = AllocateRing3CopyPages (Interface, MemoryCoreSize); if (Interface == NULL) { DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n")); - FreePool (CoreProtocol); return EFI_OUT_OF_RESOURCES; } @@ -160,7 +157,47 @@ CallBootService ( *(VOID **)CoreRbp->Argument3 = Interface; EnableSMAP (); - FreePool (CoreProtocol); + return Status; + + case SysCallInstallMultipleProtocolInterfaces: + // + // Argument 1: EFI_HANDLE *Handle + // ... + // + DisableSMAP (); + for (Index = 0; ((VOID *)UserRsp->Arguments[Index] != NULL) && (Index < MAX_LIST); Index += 2) { + if (CompareGuid ((EFI_GUID *)UserRsp->Arguments[Index], &gEfiDriverBindingProtocolGuid)) { + ArgList[Index] = (UINTN *)&gEfiDriverBindingProtocolGuid; + MemoryCoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL); + } else if (CompareGuid ((EFI_GUID *)UserRsp->Arguments[Index], &gEfiComponentNameProtocolGuid)) { + ArgList[Index] = (UINTN *)&gEfiComponentNameProtocolGuid; + MemoryCoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); + } else { + DEBUG ((DEBUG_INFO, "Ring0: Argument %d is not a GUID.\n", Index)); + } + + ArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserRsp->Arguments[Index + 1]); + } + EnableSMAP (); + + if ((Index == MAX_LIST) && ((VOID *)UserRsp->Arguments[Index] != NULL)) { + DEBUG ((DEBUG_ERROR, "Ring0: Too many protocols!\n")); + return EFI_OUT_OF_RESOURCES; + } + + ArgList[Index] = NULL; + + for (Index = 0; ArgList[Index] != NULL; Index += 2) { + if (CompareGuid ((EFI_GUID *)ArgList[Index], &gEfiDriverBindingProtocolGuid)) { + CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)ArgList[Index + 1]; + + CoreDriverBinding->Supported = CoreDriverBindingSupported; + CoreDriverBinding->Start = CoreDriverBindingStart; + CoreDriverBinding->Stop = CoreDriverBindingStop; + } + } + + Status = gBS->InstallMultipleProtocolInterfaces ((EFI_HANDLE *)ArgList); return Status; diff --git a/MdeModulePkg/Core/Dxe/SysCall/DriverBindingProtocol.c b/MdeModulePkg/Core/Dxe/SysCall/DriverBindingProtocol.c new file mode 100644 index 0000000000..80143dccb6 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/DriverBindingProtocol.c @@ -0,0 +1,42 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +EFI_STATUS +EFIAPI +CoreDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h new file mode 100644 index 0000000000..07c43d162a --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -0,0 +1,31 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +EFI_STATUS +EFIAPI +CoreDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +EFI_STATUS +EFIAPI +CoreDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +EFI_STATUS +EFIAPI +CoreDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ); diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index a7dedecace..a6745db6ba 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2026,8 +2026,9 @@ typedef struct { } EFI_BOOT_SERVICES; typedef enum { - SysCallLocateProtocol = 1, - SysCallOpenProtocol = 2, + SysCallLocateProtocol = 1, + SysCallOpenProtocol = 2, + SysCallInstallMultipleProtocolInterfaces = 3, SysCallMax } SYS_CALL_TYPE; diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index 24b87c3f91..27f0c39fdd 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -564,7 +564,10 @@ Ring3InstallMultipleProtocolInterfaces ( ... ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallInstallMultipleProtocolInterfaces, + Handle + ); } EFI_STATUS From 8018bfb4e1cbe19b311b937c351ae885d34d3599 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 6 Feb 2024 18:48:23 +0300 Subject: [PATCH 142/341] Ring3: Added Ring3EntryPoint draft. --- MdeModulePkg/Core/Dxe/DxeMain.h | 5 +- MdeModulePkg/Core/Dxe/DxeMain.inf | 2 +- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 2 +- MdeModulePkg/Core/Dxe/Image/Image.c | 20 ++++- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 12 ++- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 4 + .../Core/Dxe/SysCall/DriverBindingProtocol.c | 42 --------- MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c | 18 ++++ MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf | 42 +++++++++ .../Core/Dxe/SysCall/SupportedProtocols.c | 88 +++++++++++++++++++ .../Core/Dxe/SysCall/SupportedProtocols.h | 6 +- .../Dxe/SysCall/X64/CoreBootServices.nasm | 46 ++++++++++ .../Core/Dxe/SysCall/X64/Ring3Dxe.nasm | 21 +++++ 13 files changed, 256 insertions(+), 52 deletions(-) delete mode 100644 MdeModulePkg/Core/Dxe/SysCall/DriverBindingProtocol.c create mode 100644 MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c create mode 100644 MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf create mode 100644 MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c create mode 100644 MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index b6004f293c..16091d3f09 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -228,6 +228,7 @@ typedef struct { VOID *HiiData; BOOLEAN IsUserImage; + BOOLEAN IsRing3EntryPoint; } LOADED_IMAGE_PRIVATE_DATA; #define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \ @@ -2739,13 +2740,15 @@ RemoveImageRecord ( @param[in] ImageOrigin Where File comes from. @param[in] LoadedImageDevicePath The loaded image device path protocol @param[out] IsUserImage Whether the loaded image is in user space. + @param[out] IsRing3EntryPoint Whether the loaded image is a wrapper for Ring3 calls. **/ VOID ProtectUefiImage ( IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN UINT8 ImageOrigin, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, - OUT BOOLEAN *IsUserImage + OUT BOOLEAN *IsUserImage, + OUT BOOLEAN *IsRing3EntryPoint ); /** diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 46e1310d6d..014f6576c5 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -69,7 +69,7 @@ DxeMain/DxeMain.c SysCall/BootServices.c SysCall/SupportedProtocols.h - SysCall/DriverBindingProtocol.c + SysCall/SupportedProtocols.c [Sources.X64] SysCall/X64/CoreBootServices.nasm diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index d36d0061af..937194f4fc 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -332,7 +332,7 @@ DxeMain ( CoreInitializeMemoryProtection (); - ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, &mCurrentImage->IsUserImage); + ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, &mCurrentImage->IsUserImage, &mCurrentImage->IsRing3EntryPoint); // // Call constructor for all libraries diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index e9f030fb3d..89d3658d09 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -28,6 +28,8 @@ STATIC VOID *mPeCoffEmuProtocolNotifyRegistration; extern BOOLEAN gBdsStarted; VOID *gCoreSysCallStackTop; +VOID *gRing3CallStackTop; +VOID *gRing3EntryPoint; // // This code is needed to build the Image handle for the DXE Core @@ -70,7 +72,8 @@ LOADED_IMAGE_PRIVATE_DATA mCorePrivateImage = { NULL, // LoadedImageDevicePath EFI_SUCCESS, // LoadImageStatus NULL, // HiiData - FALSE // IsUserImage + FALSE, // IsUserImage + FALSE // IsRing3EntryPoint }; // // The field is define for Loading modules at fixed address feature to tracker the PEI code @@ -1441,7 +1444,7 @@ CoreLoadImageCommon ( } Status = EFI_SUCCESS; - ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, &Image->IsUserImage); + ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, &Image->IsUserImage, &Image->IsRing3EntryPoint); RegisterMemoryProfileImage ( Image->LoadedImageDevicePath, @@ -1718,6 +1721,13 @@ CoreStartImage ( if (!Image->IsUserImage) { Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); + } else if (Image->IsRing3EntryPoint) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + gRing3EntryPoint = (VOID *)Image->EntryPoint; + + Image->Status = EFI_SUCCESS; } else { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1753,8 +1763,10 @@ CoreStartImage ( TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + gRing3CallStackTop = TopOfStack; + SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); - DEBUG ((DEBUG_ERROR, "Core: UserTopOfStack = %p\n", TopOfStack)); + DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); // // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() @@ -1780,7 +1792,7 @@ CoreStartImage ( (SWITCH_STACK_ENTRY_POINT)(UINTN)Image->EntryPoint, ImageHandle, Image->Info.SystemTable, - TopOfStack, + gRing3CallStackTop, (UINT16)RING3_CODE64_SEL, (UINT16)RING3_DATA64_SEL ); diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 76ab3fbbd6..9a24006ee0 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -170,13 +170,15 @@ IsMemoryProtectionSectionAligned ( @param[in] ImageOrigin Where File comes from. @param[in] LoadedImageDevicePath The loaded image device path protocol @param[out] IsUserImage Whether the loaded image is in user space. + @param[out] IsRing3EntryPoint Whether the loaded image is a wrapper for Ring3 calls. **/ VOID ProtectUefiImage ( IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN UINT8 ImageOrigin, IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, - OUT BOOLEAN *IsUserImage + OUT BOOLEAN *IsUserImage, + OUT BOOLEAN *IsRing3EntryPoint ) { RETURN_STATUS PdbStatus; @@ -231,6 +233,8 @@ ProtectUefiImage ( // InsertTailList (&mProtectedImageRecordList, &ImageRecord->Link); + *IsRing3EntryPoint = FALSE; + if (gCpu != NULL) { // // CPU ARCH present. Update memory attribute directly. @@ -238,7 +242,11 @@ ProtectUefiImage ( if (AsciiStrStr (PdbPointer, "Ntfs") != NULL) { SetUefiImageProtectionAttributes (ImageRecord, TRUE); *IsUserImage = TRUE; - } else { + } else if (AsciiStrStr (PdbPointer, "Ring3") != NULL) { + SetUefiImageProtectionAttributes (ImageRecord, TRUE); + *IsUserImage = TRUE; + *IsRing3EntryPoint = TRUE; + } else { SetUefiImageProtectionAttributes (ImageRecord, FALSE); *IsUserImage = FALSE; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index c579873bec..df73724486 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -191,6 +191,10 @@ CallBootService ( if (CompareGuid ((EFI_GUID *)ArgList[Index], &gEfiDriverBindingProtocolGuid)) { CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)ArgList[Index + 1]; + mUserDriverBindingSupported = CoreDriverBinding->Supported; + mUserDriverBindingStart = CoreDriverBinding->Start; + mUserDriverBindingStop = CoreDriverBinding->Stop; + CoreDriverBinding->Supported = CoreDriverBindingSupported; CoreDriverBinding->Start = CoreDriverBindingStart; CoreDriverBinding->Stop = CoreDriverBindingStop; diff --git a/MdeModulePkg/Core/Dxe/SysCall/DriverBindingProtocol.c b/MdeModulePkg/Core/Dxe/SysCall/DriverBindingProtocol.c deleted file mode 100644 index 80143dccb6..0000000000 --- a/MdeModulePkg/Core/Dxe/SysCall/DriverBindingProtocol.c +++ /dev/null @@ -1,42 +0,0 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include "DxeMain.h" - -EFI_STATUS -EFIAPI -CoreDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ) -{ - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -CoreDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ) -{ - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -CoreDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer OPTIONAL - ) -{ - return EFI_UNSUPPORTED; -} diff --git a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c b/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c new file mode 100644 index 0000000000..d2e4b75816 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c @@ -0,0 +1,18 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include + +EFI_STATUS +EFIAPI +Ring3EntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf b/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf new file mode 100644 index 0000000000..f66a5def48 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf @@ -0,0 +1,42 @@ +## @file +# +# Ring3 driver for SysCalls. +# +# Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Ring3Dxe + FILE_GUID = 88EA50C2-0DEA-4F13-B691-B506554E632B + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = Ring3EntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + Ring3Dxe.c + +[Sources.X64] + X64/Ring3Dxe.nasm + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + +[Protocols] + +[Guids] + +[Depex] + TRUE diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c new file mode 100644 index 0000000000..952b88ddbe --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -0,0 +1,88 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +EFI_DRIVER_BINDING_SUPPORTED mUserDriverBindingSupported; +EFI_DRIVER_BINDING_START mUserDriverBindingStart; +EFI_DRIVER_BINDING_STOP mUserDriverBindingStop; + +typedef enum { + UserDriverBindingSupported = 1, + UserDriverBindingStart = 2, + UserDriverBindingStop = 3, + UserCallMax +} USER_CALL_TYPE; + +EFI_STATUS +EFIAPI +CallRing3 ( + IN UINT8 Type, + IN UINT16 CodeSelector, + IN UINT16 DataSelector, + IN VOID *FunctionAddress, + ... + ); + +EFI_STATUS +EFIAPI +CoreDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + return CallRing3 ( + UserDriverBindingSupported, + (UINT16)RING3_CODE64_SEL, + (UINT16)RING3_DATA64_SEL, + (VOID *)mUserDriverBindingSupported, + This, + ControllerHandle, + RemainingDevicePath + ); +} + +EFI_STATUS +EFIAPI +CoreDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + return CallRing3 ( + UserDriverBindingStart, + (UINT16)RING3_CODE64_SEL, + (UINT16)RING3_DATA64_SEL, + (VOID *)mUserDriverBindingStart, + This, + ControllerHandle, + RemainingDevicePath + ); +} + +EFI_STATUS +EFIAPI +CoreDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +{ + return CallRing3 ( + UserDriverBindingStop, + (UINT16)RING3_CODE64_SEL, + (UINT16)RING3_DATA64_SEL, + (VOID *)mUserDriverBindingStop, + This, + ControllerHandle, + NumberOfChildren, + ChildHandleBuffer + ); +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h index 07c43d162a..4737cc696e 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -5,6 +5,10 @@ **/ +extern EFI_DRIVER_BINDING_SUPPORTED mUserDriverBindingSupported; +extern EFI_DRIVER_BINDING_START mUserDriverBindingStart; +extern EFI_DRIVER_BINDING_STOP mUserDriverBindingStop; + EFI_STATUS EFIAPI CoreDriverBindingSupported ( @@ -12,7 +16,7 @@ CoreDriverBindingSupported ( IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ); - + EFI_STATUS EFIAPI CoreDriverBindingStart ( diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 34d21a02e7..83508675f2 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -10,6 +10,8 @@ SECTION .text extern ASM_PFX(CallBootService) extern ASM_PFX(gCoreSysCallStackTop) +extern ASM_PFX(gRing3CallStackTop) +extern ASM_PFX(gRing3EntryPoint) global ASM_PFX(DisableSMAP) ASM_PFX(DisableSMAP): @@ -151,3 +153,47 @@ ASM_PFX(InternalEnterUserImage): ; Pass control to user image retfq + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CallRing3 ( +; IN UINT8 Type, +; IN UINT16 CodeSelector, +; IN UINT16 DataSelector, +; IN VOID *FunctionAddress, +; ... +; ); +; +; (rcx) Type. +; (rdx) CodeSelector - Segment selector for code. +; (r8) DataSelector - Segment selector for data. +; (r9) FunctionAddress +; +; (On User Stack) Argument 1, 2, 3, ... +;------------------------------------------------------------------------------ +global ASM_PFX(CallRing3) +ASM_PFX(CallRing3): + ; Set Data selectors + or r8, 3H ; RPL = 3 + +o16 mov ds, r8 +o16 mov es, r8 +o16 mov fs, r8 +o16 mov gs, r8 + + ; Save Code selector + or rdx, 3H ; RPL = 3 + + ; Prepare stack before swithcing + push r8 ; ss + push qword [gRing3CallStackTop] ; rsp + push rdx ; cs + push qword [gRing3EntryPoint] ; rip + + ; Copy Arguments from Core Stack to User Stack + return address + + ; Pass control to User driver function. + retfq +coreReturnAddress: + ret diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm new file mode 100644 index 0000000000..ec4780bdc8 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm @@ -0,0 +1,21 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +; +;------------------------------------------------------------------------------ + +DEFAULT REL +SECTION .text + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; _ModuleEntryPoint ( +; IN EFI_HANDLE ImageHandle, +; IN EFI_SYSTEM_TABLE *SystemTable +; ) +;------------------------------------------------------------------------------ +global ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + ret From 8e4e21d3053b206609731d19fd4a1c528a4c4aa2 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 8 Feb 2024 19:15:55 +0300 Subject: [PATCH 143/341] Ring3: Fixed SysCallInstallMultipleProtocolInterfaces. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 69 ++++++++++++------- .../Dxe/SysCall/X64/CoreBootServices.nasm | 59 ++++++++++++++++ MdePkg/Include/Uefi/UefiSpec.h | 2 + .../Ring3UefiBootServicesTableLib.c | 24 ++++++- 4 files changed, 128 insertions(+), 26 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index df73724486..ad07e0c635 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -11,8 +11,6 @@ #include #include -#define MAX_LIST 32 - VOID EFIAPI DisableSMAP ( @@ -25,6 +23,15 @@ EnableSMAP ( VOID ); +EFI_STATUS +EFIAPI +CallInstallMultipleProtocolInterfaces ( + IN EFI_HANDLE *Handle, + IN VOID **ArgList, + IN UINT32 ArgListSize, + IN VOID *Function + ); + VOID EFIAPI InternalEnterUserImage ( @@ -73,7 +80,9 @@ CallBootService ( EFI_HANDLE Argument5; UINT32 Argument6; UINT32 Index; - UINTN *ArgList[MAX_LIST]; + VOID **UserArgList; + VOID *CoreArgList[MAX_LIST]; + EFI_HANDLE CoreHandle; EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; @@ -92,8 +101,9 @@ CallBootService ( CoreProtocol = &gEfiDevicePathUtilitiesProtocolGuid; MemoryCoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); } else { - CoreProtocol = NULL; - MemoryCoreSize = 0; + DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol.\n")); + EnableSMAP (); + return EFI_INVALID_PARAMETER; } EnableSMAP (); @@ -129,8 +139,9 @@ CallBootService ( CoreProtocol = &gEfiLoadedImageProtocolGuid; MemoryCoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); } else { - CoreProtocol = NULL; - MemoryCoreSize = 0; + DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol.\n")); + EnableSMAP (); + return EFI_INVALID_PARAMETER; } Argument4 = (EFI_HANDLE)UserRsp->Arguments[4]; @@ -165,31 +176,34 @@ CallBootService ( // ... // DisableSMAP (); - for (Index = 0; ((VOID *)UserRsp->Arguments[Index] != NULL) && (Index < MAX_LIST); Index += 2) { - if (CompareGuid ((EFI_GUID *)UserRsp->Arguments[Index], &gEfiDriverBindingProtocolGuid)) { - ArgList[Index] = (UINTN *)&gEfiDriverBindingProtocolGuid; + CoreHandle = *(EFI_HANDLE *)CoreRbp->Argument1; + UserArgList = (VOID **)CoreRbp->Argument2; + + for (Index = 0; UserArgList[Index] != NULL; ++Index) { + if (CompareGuid ((EFI_GUID *)UserArgList[Index], &gEfiDriverBindingProtocolGuid)) { + CoreArgList[Index] = (VOID *)&gEfiDriverBindingProtocolGuid; MemoryCoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL); - } else if (CompareGuid ((EFI_GUID *)UserRsp->Arguments[Index], &gEfiComponentNameProtocolGuid)) { - ArgList[Index] = (UINTN *)&gEfiComponentNameProtocolGuid; + continue; + } else if (CompareGuid ((EFI_GUID *)UserArgList[Index], &gEfiComponentNameProtocolGuid)) { + CoreArgList[Index] = (VOID *)&gEfiComponentNameProtocolGuid; MemoryCoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); - } else { - DEBUG ((DEBUG_INFO, "Ring0: Argument %d is not a GUID.\n", Index)); + continue; + } else if ((Index % 2) == 0) { + DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol.\n")); + EnableSMAP (); + return EFI_INVALID_PARAMETER; } - ArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserRsp->Arguments[Index + 1]); + CoreArgList[Index] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index]); } EnableSMAP (); - if ((Index == MAX_LIST) && ((VOID *)UserRsp->Arguments[Index] != NULL)) { - DEBUG ((DEBUG_ERROR, "Ring0: Too many protocols!\n")); - return EFI_OUT_OF_RESOURCES; - } - - ArgList[Index] = NULL; + ASSERT (Index < MAX_LIST); + CoreArgList[Index] = NULL; - for (Index = 0; ArgList[Index] != NULL; Index += 2) { - if (CompareGuid ((EFI_GUID *)ArgList[Index], &gEfiDriverBindingProtocolGuid)) { - CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)ArgList[Index + 1]; + for (Index = 0; CoreArgList[Index] != NULL; Index += 2) { + if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiDriverBindingProtocolGuid)) { + CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)CoreArgList[Index + 1]; mUserDriverBindingSupported = CoreDriverBinding->Supported; mUserDriverBindingStart = CoreDriverBinding->Start; @@ -201,7 +215,12 @@ CallBootService ( } } - Status = gBS->InstallMultipleProtocolInterfaces ((EFI_HANDLE *)ArgList); + Status = CallInstallMultipleProtocolInterfaces ( + &CoreHandle, + CoreArgList, + Index + 1, + (VOID *)gBS->InstallMultipleProtocolInterfaces + ); return Status; diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 83508675f2..d3f8f2635c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -13,6 +13,13 @@ extern ASM_PFX(gCoreSysCallStackTop) extern ASM_PFX(gRing3CallStackTop) extern ASM_PFX(gRing3EntryPoint) +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; DisableSMAP ( +; VOID +; ); +;------------------------------------------------------------------------------ global ASM_PFX(DisableSMAP) ASM_PFX(DisableSMAP): pushfq @@ -22,6 +29,13 @@ ASM_PFX(DisableSMAP): popfq ret +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; EnableSMAP ( +; VOID +; ); +;------------------------------------------------------------------------------ global ASM_PFX(EnableSMAP) ASM_PFX(EnableSMAP): pushfq @@ -31,6 +45,51 @@ ASM_PFX(EnableSMAP): popfq ret +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CallInstallMultipleProtocolInterfaces ( +; IN EFI_HANDLE *Handle, +; IN VOID **ArgList, +; IN UINT32 ArgListSize, +; IN VOID *Function +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(CallInstallMultipleProtocolInterfaces) +ASM_PFX(CallInstallMultipleProtocolInterfaces): + push r12 + + ; Save funtion input. + mov rax, rdx + mov r10, r8 + mov r11, r9 + + ; Prepare registers for call. + mov rdx, [rax] + mov r8, [rax + 8] + mov r9, [rax + 8*2] + + ; Prepare stack for call. + lea rax, [rax + r10 * 8] + mov r12, r10 +copy: + sub rax, 8 + push qword [rax] + cmp r10, 0 + sub r10, 1 + jne copy + push rcx + + call r11 + + ; Step over Function arguments. + pop rcx + lea rsp, [rsp + r12 * 8] + + pop r12 + + ret + ;------------------------------------------------------------------------------ ; EFI_STATUS ; EFIAPI diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index a6745db6ba..bcc771259a 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2032,6 +2032,8 @@ typedef enum { SysCallMax } SYS_CALL_TYPE; +#define MAX_LIST 32 + /// /// Contains a set of GUID/pointer pairs comprised of the ConfigurationTable field in the /// EFI System Table. diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c index 27f0c39fdd..c5cf04a03e 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c @@ -564,9 +564,31 @@ Ring3InstallMultipleProtocolInterfaces ( ... ) { + VA_LIST Marker; + VOID *Argument; + VOID *ArgList[MAX_LIST]; + UINTN Index; + + VA_START (Marker, Handle); + for (Index = 0; Index < MAX_LIST; ++Index) { + Argument = VA_ARG (Marker, VOID *); + ArgList[Index] = Argument; + + if (Argument == NULL) { + break; + } + } + VA_END (Marker); + + if (Index == MAX_LIST) { + DEBUG ((DEBUG_ERROR, "Ring3: Too many arguments\n")); + return EFI_INVALID_PARAMETER; + } + return SysCall ( SysCallInstallMultipleProtocolInterfaces, - Handle + Handle, + ArgList ); } From b1af78b4d3ffbfb771088e3f32d4c1df741c94ce Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 9 Feb 2024 15:25:06 +0300 Subject: [PATCH 144/341] Ring3: Refactored EnterUserImage() into CallRing3(). --- MdeModulePkg/Core/Dxe/DxeMain.h | 12 +- MdeModulePkg/Core/Dxe/Image/Image.c | 14 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 37 +---- .../Core/Dxe/SysCall/SupportedProtocols.c | 19 --- .../Dxe/SysCall/X64/CoreBootServices.nasm | 127 ++++++++---------- .../Core/Dxe/SysCall/X64/Ring3Dxe.nasm | 13 +- 6 files changed, 78 insertions(+), 144 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 16091d3f09..b9bbef7a8d 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2845,15 +2845,11 @@ CoreBootServices ( ... ); -VOID +EFI_STATUS EFIAPI -EnterUserImage ( - IN SWITCH_STACK_ENTRY_POINT EntryPoint, - IN VOID *Context1 OPTIONAL, - IN VOID *Context2 OPTIONAL, - IN VOID *NewStack, - IN UINT16 CodeSelector, - IN UINT16 DataSelector +CallRing3 ( + IN VOID *EntryPoint, + ... ); #endif diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 89d3658d09..3ac911f56f 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1788,15 +1788,11 @@ CoreStartImage ( Msr = (UINT64)(UINTN)CoreBootServices; AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); - EnterUserImage ( - (SWITCH_STACK_ENTRY_POINT)(UINTN)Image->EntryPoint, - ImageHandle, - Image->Info.SystemTable, - gRing3CallStackTop, - (UINT16)RING3_CODE64_SEL, - (UINT16)RING3_DATA64_SEL - ); - Image->Status = EFI_SUCCESS; + Image->Status = CallRing3 ( + (VOID *)Image->EntryPoint, + ImageHandle, + Image->Info.SystemTable + ); } // diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index ad07e0c635..7d3cc8beb0 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -32,17 +32,6 @@ CallInstallMultipleProtocolInterfaces ( IN VOID *Function ); -VOID -EFIAPI -InternalEnterUserImage ( - IN SWITCH_STACK_ENTRY_POINT EntryPoint, - IN VOID *Context1 OPTIONAL, - IN VOID *Context2 OPTIONAL, - IN VOID *NewStack, - IN UINT16 CodeSelector, - IN UINT16 DataSelector - ); - typedef struct { UINTN Argument1; UINTN Argument2; @@ -85,7 +74,9 @@ CallBootService ( EFI_HANDLE CoreHandle; EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; - + // + // TODO: Check User variables. + // gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -230,25 +221,3 @@ CallBootService ( return EFI_UNSUPPORTED; } - -VOID -EFIAPI -EnterUserImage ( - IN SWITCH_STACK_ENTRY_POINT EntryPoint, - IN VOID *Context1 OPTIONAL, - IN VOID *Context2 OPTIONAL, - IN VOID *NewStack, - IN UINT16 CodeSelector, - IN UINT16 DataSelector - ) -{ - ASSERT (EntryPoint != NULL); - ASSERT (NewStack != NULL); - - // - // New stack must be aligned with CPU_STACK_ALIGNMENT - // - ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0); - - InternalEnterUserImage (EntryPoint, Context1, Context2, NewStack, CodeSelector, DataSelector); -} diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 952b88ddbe..50c89956f4 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -18,16 +18,6 @@ typedef enum { UserCallMax } USER_CALL_TYPE; -EFI_STATUS -EFIAPI -CallRing3 ( - IN UINT8 Type, - IN UINT16 CodeSelector, - IN UINT16 DataSelector, - IN VOID *FunctionAddress, - ... - ); - EFI_STATUS EFIAPI CoreDriverBindingSupported ( @@ -37,9 +27,6 @@ CoreDriverBindingSupported ( ) { return CallRing3 ( - UserDriverBindingSupported, - (UINT16)RING3_CODE64_SEL, - (UINT16)RING3_DATA64_SEL, (VOID *)mUserDriverBindingSupported, This, ControllerHandle, @@ -56,9 +43,6 @@ CoreDriverBindingStart ( ) { return CallRing3 ( - UserDriverBindingStart, - (UINT16)RING3_CODE64_SEL, - (UINT16)RING3_DATA64_SEL, (VOID *)mUserDriverBindingStart, This, ControllerHandle, @@ -76,9 +60,6 @@ CoreDriverBindingStop ( ) { return CallRing3 ( - UserDriverBindingStop, - (UINT16)RING3_CODE64_SEL, - (UINT16)RING3_DATA64_SEL, (VOID *)mUserDriverBindingStop, This, ControllerHandle, diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index d3f8f2635c..0ab6eebd3a 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -5,14 +5,18 @@ ; ;------------------------------------------------------------------------------ -DEFAULT REL -SECTION .text +#include extern ASM_PFX(CallBootService) extern ASM_PFX(gCoreSysCallStackTop) extern ASM_PFX(gRing3CallStackTop) extern ASM_PFX(gRing3EntryPoint) +extern ASM_PFX(AsmReadMsr64) + +DEFAULT REL +SECTION .text + ;------------------------------------------------------------------------------ ; VOID ; EFIAPI @@ -167,92 +171,69 @@ o64 sysret ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. ;------------------------------------------------------------------------------ -; Routine Description: -; -; Routine for transfering control to user image with 2 parameters -; -; Arguments: +; EFI_STATUS +; EFIAPI +; CallRing3 ( +; IN VOID *EntryPoint, +; ... +; ); ; -; (rcx) EntryPoint - Entry point with new stack. +; (rcx) EntryPoint - Entry point in User address space. ; (rdx) Context1 - Parameter1 for entry point. ; (r8) Context2 - Parameter2 for entry point. -; (r9) NewStack - The pointer to new stack. -;On stack CodeSelector - Segment selector for code. -;On stack DataSelector - Segment selector for data. -; -; Returns: -; -; None -; ;------------------------------------------------------------------------------ -global ASM_PFX(InternalEnterUserImage) -ASM_PFX(InternalEnterUserImage): +global ASM_PFX(CallRing3) +ASM_PFX(CallRing3): + ; Save input Arguments. + push r12 + push r13 + push r14 + mov r12, rcx + mov r13, rdx + mov r14, r8 + + ; Extract User Data selector. + mov rcx, MSR_IA32_STAR + call ASM_PFX(AsmReadMsr64) + ; rax = ((RING3_CODE64_SEL - 16) << 16 | RING0_CODE64_SEL) << 32 + shr rax, 48 + add rax, 8 + ; Set Data selectors - mov rax, [rsp + 8*6] or rax, 3H ; RPL = 3 - mov ds, ax mov es, ax mov fs, ax mov gs, ax - ; Save Code selector - mov r10, [rsp + 8*5] - or r10, 3H ; RPL = 3 + ; Prepare SYSRET arguments. + mov rcx, [gRing3EntryPoint] + mov rdx, r12 + mov r8, r13 + mov r9, r14 + pushfq + pop r11 - ; Prepare stack before swithcing - push rax ; ss - push r9 ; rsp - push r10 ; cs - push rcx ; rip + ; Restore stack and registers. + pop r14 + pop r13 + pop r12 - ; Save 2 parameters - mov rcx, rdx - mov rdx, r8 + ; Save Core Stack pointers and switch to User Stack. + mov [ASM_PFX(CoreRsp)], rsp + mov [ASM_PFX(CoreRbp)], rbp + mov rsp, [ASM_PFX(gRing3CallStackTop)] + mov rbp, rsp ; Pass control to user image - retfq - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; CallRing3 ( -; IN UINT8 Type, -; IN UINT16 CodeSelector, -; IN UINT16 DataSelector, -; IN VOID *FunctionAddress, -; ... -; ); -; -; (rcx) Type. -; (rdx) CodeSelector - Segment selector for code. -; (r8) DataSelector - Segment selector for data. -; (r9) FunctionAddress -; -; (On User Stack) Argument 1, 2, 3, ... -;------------------------------------------------------------------------------ -global ASM_PFX(CallRing3) -ASM_PFX(CallRing3): - ; Set Data selectors - or r8, 3H ; RPL = 3 - -o16 mov ds, r8 -o16 mov es, r8 -o16 mov fs, r8 -o16 mov gs, r8 - - ; Save Code selector - or rdx, 3H ; RPL = 3 - - ; Prepare stack before swithcing - push r8 ; ss - push qword [gRing3CallStackTop] ; rsp - push rdx ; cs - push qword [gRing3EntryPoint] ; rip - - ; Copy Arguments from Core Stack to User Stack + return address +o64 sysret - ; Pass control to User driver function. - retfq coreReturnAddress: ret + +SECTION .data +ASM_PFX(CoreRsp): + resq 1 + +ASM_PFX(CoreRbp): + resq 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm index ec4780bdc8..09f0d866d2 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm @@ -15,7 +15,18 @@ SECTION .text ; IN EFI_HANDLE ImageHandle, ; IN EFI_SYSTEM_TABLE *SystemTable ; ) +; +; (rcx) _ModuleEntryPoint - Used by SYSRET. +; (rdx) EntryPoint - Function address in User address space. +; (r8) Context1 - Parameter1 for entry point. +; (r9) Context2 - Parameter2 for entry point. ;------------------------------------------------------------------------------ global ASM_PFX(_ModuleEntryPoint) ASM_PFX(_ModuleEntryPoint): - ret + mov rcx, r8 + mov r8, rdx + mov rdx, r9 + + call r8 + + ret From ea59514a9122fe59aa159e7ac09abb4ae0e1b3ee Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 9 Feb 2024 16:09:45 +0300 Subject: [PATCH 145/341] Ring3: Added SysCallReturnToCore. --- MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm | 6 ++++++ MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm | 6 ++++-- MdePkg/Include/Uefi/UefiSpec.h | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 0ab6eebd3a..90bcd4a0a0 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -123,6 +123,10 @@ ASM_PFX(CoreBootServices): mov fs, ax mov gs, ax + ; Special case for SysCallReturnToCore. + cmp r10, 0 + je coreReturnAddress + ; Save User Stack pointers and switch to Core SysCall Stack. mov rax, [ASM_PFX(gCoreSysCallStackTop)] sub rax, 8 @@ -229,6 +233,8 @@ ASM_PFX(CallRing3): o64 sysret coreReturnAddress: + mov rsp, [ASM_PFX(CoreRsp)] + mov rbp, [ASM_PFX(CoreRbp)] ret SECTION .data diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm index 09f0d866d2..410f6b41e6 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm @@ -28,5 +28,7 @@ ASM_PFX(_ModuleEntryPoint): mov rdx, r9 call r8 - - ret + + mov r10, 0 + + syscall diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index bcc771259a..2bf79d2d49 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2026,6 +2026,7 @@ typedef struct { } EFI_BOOT_SERVICES; typedef enum { + SysCallReturnToCore = 0, SysCallLocateProtocol = 1, SysCallOpenProtocol = 2, SysCallInstallMultipleProtocolInterfaces = 3, From 597f466a19a315a97c6c169df048f9c0e9fee44d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 13 Feb 2024 11:11:54 +0300 Subject: [PATCH 146/341] Ring3: Moved Ring3UefiBootServicesTableLib to Ring3Dxe. --- MdeModulePkg/Core/Dxe/DxeMain.h | 24 ++++++++++ MdeModulePkg/Core/Dxe/Image/Image.c | 15 +++++-- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 24 ++++++++-- MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c | 44 +++++++++++++++++++ MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf | 10 +---- .../Core/Dxe/SysCall/X64/Ring3Dxe.nasm | 34 -------------- MdePkg/Include/Uefi/UefiSpec.h | 6 +++ 7 files changed, 108 insertions(+), 49 deletions(-) delete mode 100644 MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index b9bbef7a8d..78511f9b82 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2852,4 +2852,28 @@ CallRing3 ( ... ); +VOID +EFIAPI +DisableSMAP ( + VOID + ); + +VOID +EFIAPI +EnableSMAP ( + VOID + ); + +VOID +EFIAPI +DisableSMEP ( + VOID + ); + +VOID +EFIAPI +EnableSMEP ( + VOID + ); + #endif diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 3ac911f56f..50392f24e6 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -30,6 +30,7 @@ extern BOOLEAN gBdsStarted; VOID *gCoreSysCallStackTop; VOID *gRing3CallStackTop; VOID *gRing3EntryPoint; +RING3_DATA *mRing3Data; // // This code is needed to build the Image handle for the DXE Core @@ -1725,9 +1726,17 @@ CoreStartImage ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gRing3EntryPoint = (VOID *)Image->EntryPoint; + mRing3Data = AllocateRing3CopyPages ((VOID *)Image->Info.SystemTable, sizeof (RING3_DATA)); - Image->Status = EFI_SUCCESS; + DisableSMAP (); + DisableSMEP (); + Image->Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)mRing3Data); + + gRing3EntryPoint = mRing3Data->EntryPoint; + + mRing3Data->SystemTable.BootServices = mRing3Data->BootServices; + EnableSMEP (); + EnableSMAP (); } else { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1791,7 +1800,7 @@ CoreStartImage ( Image->Status = CallRing3 ( (VOID *)Image->EntryPoint, ImageHandle, - Image->Info.SystemTable + (EFI_SYSTEM_TABLE *)mRing3Data ); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 7d3cc8beb0..3af5e62f99 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -13,15 +13,31 @@ VOID EFIAPI -DisableSMAP ( +DisableSMEP ( VOID - ); + ) +{ + IA32_CR4 Cr4; + + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMEP = 0; + + AsmWriteCr4 (Cr4.UintN); +} VOID EFIAPI -EnableSMAP ( +EnableSMEP ( VOID - ); + ) +{ + IA32_CR4 Cr4; + + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMEP = 1; + + AsmWriteCr4 (Cr4.UintN); +} EFI_STATUS EFIAPI diff --git a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c b/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c index d2e4b75816..55d971eda5 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c @@ -6,6 +6,23 @@ **/ #include +#include + +EFI_STATUS +EFIAPI +Ring3Call ( + IN VOID *Dummy, + IN VOID *EntryPoint, + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +SysCall ( + IN UINT8 Type, + ... + ); EFI_STATUS EFIAPI @@ -14,5 +31,32 @@ Ring3EntryPoint ( IN EFI_SYSTEM_TABLE *SystemTable ) { + RING3_DATA *Ring3Data; + + Ring3Data = (RING3_DATA *)SystemTable; + + Ring3Data->EntryPoint = (VOID *)Ring3Call; + Ring3Data->BootServices = gBS; + return EFI_SUCCESS; } + +EFI_STATUS +EFIAPI +Ring3Call ( + IN VOID *Dummy, + IN VOID *EntryPoint, + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_IMAGE_ENTRY_POINT Function; + + Function = (EFI_IMAGE_ENTRY_POINT)EntryPoint; + + Function (ImageHandle, SystemTable); + + SysCall (SysCallReturnToCore); + + return EFI_UNSUPPORTED; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf b/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf index f66a5def48..42f33e2d66 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf +++ b/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf @@ -24,19 +24,13 @@ [Sources] Ring3Dxe.c -[Sources.X64] - X64/Ring3Dxe.nasm - [Packages] MdePkg/MdePkg.dec [LibraryClasses] BaseLib - DebugLib - -[Protocols] - -[Guids] + UefiBootServicesTableLib + UefiDriverEntryPoint [Depex] TRUE diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm deleted file mode 100644 index 410f6b41e6..0000000000 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/Ring3Dxe.nasm +++ /dev/null @@ -1,34 +0,0 @@ -;------------------------------------------------------------------------------ -; -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -; SPDX-License-Identifier: BSD-3-Clause -; -;------------------------------------------------------------------------------ - -DEFAULT REL -SECTION .text - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; _ModuleEntryPoint ( -; IN EFI_HANDLE ImageHandle, -; IN EFI_SYSTEM_TABLE *SystemTable -; ) -; -; (rcx) _ModuleEntryPoint - Used by SYSRET. -; (rdx) EntryPoint - Function address in User address space. -; (r8) Context1 - Parameter1 for entry point. -; (r9) Context2 - Parameter2 for entry point. -;------------------------------------------------------------------------------ -global ASM_PFX(_ModuleEntryPoint) -ASM_PFX(_ModuleEntryPoint): - mov rcx, r8 - mov r8, rdx - mov rdx, r9 - - call r8 - - mov r10, 0 - - syscall diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 2bf79d2d49..4db3179f0f 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2120,6 +2120,12 @@ typedef struct { EFI_CONFIGURATION_TABLE *ConfigurationTable; } EFI_SYSTEM_TABLE; +typedef struct { + EFI_SYSTEM_TABLE SystemTable; + VOID *EntryPoint; + EFI_BOOT_SERVICES *BootServices; +} RING3_DATA; + /** This is the declaration of an EFI image entry point. This entry point is the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including From a053475490df20158a5be8b28ab17744c07f2836 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 13 Feb 2024 11:40:52 +0300 Subject: [PATCH 147/341] Ring3: Refactored Ring3 initialization. --- MdeModulePkg/Core/Dxe/DxeMain.h | 12 -- MdeModulePkg/Core/Dxe/Image/Image.c | 181 +++++++++++------- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 28 --- .../Core/DxeIplPeim/X64/VirtualMemory.c | 37 ---- 4 files changed, 112 insertions(+), 146 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 78511f9b82..f38e2960d1 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2864,16 +2864,4 @@ EnableSMAP ( VOID ); -VOID -EFIAPI -DisableSMEP ( - VOID - ); - -VOID -EFIAPI -EnableSMEP ( - VOID - ); - #endif diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 50392f24e6..a24f878918 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1590,6 +1590,113 @@ AllocateRing3CopyPages ( return MemoryRing3; } +VOID +EFIAPI +InitializeRing3 ( + IN EFI_HANDLE ImageHandle, + IN LOADED_IMAGE_PRIVATE_DATA *Image + ) +{ + VOID *BaseOfStack; + VOID *TopOfStack; + UINTN SizeOfStack; + UINT64 Msr; + IA32_CR4 Cr4; + IA32_EFLAGS32 Eflags; + UINT32 Ebx; + UINT32 Edx; + MSR_IA32_EFER_REGISTER MsrEfer; + + Ebx = 0; + Edx = 0; + + // + // Set Ring3 EntryPoint and BootServices. + // + mRing3Data = AllocateRing3CopyPages ((VOID *)Image->Info.SystemTable, sizeof (RING3_DATA)); + + Image->Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)mRing3Data); + + gRing3EntryPoint = mRing3Data->EntryPoint; + + mRing3Data->SystemTable.BootServices = mRing3Data->BootServices; + + // + // Forbid supervisor-mode accesses to any user-mode pages. + // SMEP and SMAP must be supported. + // + AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); + // + // SYSCALL and SYSRET must be also supported. + // + AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); + if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) { + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMAP = 1; + Cr4.Bits.SMEP = 1; + AsmWriteCr4 (Cr4.UintN); + + Eflags.UintN = AsmReadEflags (); + Eflags.Bits.AC = 0; + // + // Allow user image to access ports. + // + Eflags.Bits.IOPL = 3; + AsmWriteEflags (Eflags.UintN); + // + // Enable SYSCALL and SYSRET. + // + MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); + MsrEfer.Bits.SCE = 1; + AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); + } + + SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; + + // + // Allocate 128KB for the Core SysCall Stack. + // + BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); + ASSERT (BaseOfStack != NULL); + + // + // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. + // + TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + gCoreSysCallStackTop = TopOfStack; + + SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP); + DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); + + // + // Allocate 128KB for the User Stack. + // + BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); + ASSERT (BaseOfStack != NULL); + + // + // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. + // + TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + gRing3CallStackTop = TopOfStack; + + SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); + DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); + + // + // Initialize MSR_IA32_STAR and MSR_IA32_LSTAR for SYSCALL and SYSRET. + // + Msr = ((((UINT64)RING3_CODE64_SEL - 16) << 16) | (UINT64)RING0_CODE64_SEL) << 32; + AsmWriteMsr64 (MSR_IA32_STAR, Msr); + + Msr = (UINT64)(UINTN)CoreBootServices; + AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); +} + /** Transfer control to a loaded image's entry point. @@ -1624,10 +1731,6 @@ CoreStartImage ( UINTN SetJumpFlag; EFI_HANDLE Handle; UINT64 Attributes; - VOID *BaseOfStack; - VOID *TopOfStack; - UINTN SizeOfStack; - UINT64 Msr; Handle = ImageHandle; @@ -1720,63 +1823,12 @@ CoreStartImage ( // Image->Started = TRUE; - if (!Image->IsUserImage) { - Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); - } else if (Image->IsRing3EntryPoint) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - mRing3Data = AllocateRing3CopyPages ((VOID *)Image->Info.SystemTable, sizeof (RING3_DATA)); - - DisableSMAP (); - DisableSMEP (); - Image->Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)mRing3Data); - - gRing3EntryPoint = mRing3Data->EntryPoint; - - mRing3Data->SystemTable.BootServices = mRing3Data->BootServices; - EnableSMEP (); - EnableSMAP (); - } else { + if (Image->IsRing3EntryPoint) { + InitializeRing3 (ImageHandle, Image); + } else if (Image->IsUserImage) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; - - // - // Allocate 128KB for the Core SysCall Stack. - // - BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); - ASSERT (BaseOfStack != NULL); - - // - // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. - // - TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - gCoreSysCallStackTop = TopOfStack; - - SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP); - DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); - - // - // Allocate 128KB for the User Stack. - // - BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); - ASSERT (BaseOfStack != NULL); - - // - // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. - // - TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - gRing3CallStackTop = TopOfStack; - - SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); - DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); - // // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() // @@ -1786,22 +1838,13 @@ CoreStartImage ( EFI_MEMORY_XP | EFI_MEMORY_USER ); - DEBUG ((DEBUG_ERROR, "Core: BootServices = 0x%lx\n", (UINTN)Image->Info.SystemTable->BootServices)); - - // - // Initialize MSR_IA32_STAR and MSR_IA32_LSTAR for SYSCALL and SYSRET. - // - Msr = ((((UINT64)RING3_CODE64_SEL - 16) << 16) | (UINT64)RING0_CODE64_SEL) << 32; - AsmWriteMsr64 (MSR_IA32_STAR, Msr); - - Msr = (UINT64)(UINTN)CoreBootServices; - AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); - Image->Status = CallRing3 ( (VOID *)Image->EntryPoint, ImageHandle, (EFI_SYSTEM_TABLE *)mRing3Data ); + } else { + Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); } // diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 3af5e62f99..dcf07e66ee 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -11,34 +11,6 @@ #include #include -VOID -EFIAPI -DisableSMEP ( - VOID - ) -{ - IA32_CR4 Cr4; - - Cr4.UintN = AsmReadCr4 (); - Cr4.Bits.SMEP = 0; - - AsmWriteCr4 (Cr4.UintN); -} - -VOID -EFIAPI -EnableSMEP ( - VOID - ) -{ - IA32_CR4 Cr4; - - Cr4.UintN = AsmReadCr4 (); - Cr4.Bits.SMEP = 1; - - AsmWriteCr4 (Cr4.UintN); -} - EFI_STATUS EFIAPI CallInstallMultipleProtocolInterfaces ( diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index 0810cc1aee..7a40a0f8fd 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -708,13 +708,6 @@ CreateIdentityMappingPageTables ( PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; UINT64 AddressEncMask; IA32_CR4 Cr4; - IA32_EFLAGS32 Eflags; - UINT32 Ebx; - UINT32 Edx; - MSR_IA32_EFER_REGISTER MsrEfer; - - Ebx = 0; - Edx = 0; // // Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings @@ -987,35 +980,5 @@ CreateIdentityMappingPageTables ( EnableExecuteDisableBit (); } - // - // Forbid supervisor-mode accesses to any user-mode pages. - // SMEP and SMAP must be supported. - // - AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); - // - // SYSCALL and SYSRET must be also supported. - // - AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); - if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) { - Cr4.UintN = AsmReadCr4 (); - Cr4.Bits.SMAP = 1; - Cr4.Bits.SMEP = 1; - AsmWriteCr4 (Cr4.UintN); - - Eflags.UintN = AsmReadEflags (); - Eflags.Bits.AC = 0; - // - // Allow user image to access ports. - // - Eflags.Bits.IOPL = 3; - AsmWriteEflags (Eflags.UintN); - // - // Enable SYSCALL and SYSRET. - // - MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); - MsrEfer.Bits.SCE = 1; - AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); - } - return (UINTN)PageMap; } From 780e1875a246cae2e98e177c9e024a49009864cf Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 15 Feb 2024 11:43:50 +0300 Subject: [PATCH 148/341] Ring3: Merged Ring3Dxe and Ring3UefiBootServicesTableLib into DxeRing3. --- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 102 ++++++++++++++++++ .../Ring3Dxe.inf => DxeRing3/DxeRing3.inf} | 16 ++- .../Core/Dxe/DxeRing3}/Ring3.h | 0 .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 77 +------------ .../Core/Dxe/DxeRing3}/X64/SysCall.nasm | 0 MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c | 62 ----------- .../Ring3UefiBootServicesTableLib.inf | 41 ------- .../Ring3UefiBootServicesTableLib.uni | 12 --- 8 files changed, 116 insertions(+), 194 deletions(-) create mode 100644 MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c rename MdeModulePkg/Core/Dxe/{SysCall/Ring3Dxe.inf => DxeRing3/DxeRing3.inf} (69%) rename {MdePkg/Library/Ring3UefiBootServicesTableLib => MdeModulePkg/Core/Dxe/DxeRing3}/Ring3.h (100%) rename MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c => MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c (62%) rename {MdePkg/Library/Ring3UefiBootServicesTableLib => MdeModulePkg/Core/Dxe/DxeRing3}/X64/SysCall.nasm (100%) delete mode 100644 MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c delete mode 100644 MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf delete mode 100644 MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.uni diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c new file mode 100644 index 0000000000..94f8e78ef7 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -0,0 +1,102 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include +#include + +#include "Ring3.h" + +EFI_BOOT_SERVICES mBootServices = { + { + EFI_BOOT_SERVICES_SIGNATURE, // Signature + EFI_BOOT_SERVICES_REVISION, // Revision + sizeof (EFI_BOOT_SERVICES), // HeaderSize + 0, // CRC32 + 0 // Reserved + }, + (EFI_RAISE_TPL)Ring3RaiseTpl, // RaiseTPL + (EFI_RESTORE_TPL)Ring3RestoreTpl, // RestoreTPL + (EFI_ALLOCATE_PAGES)Ring3AllocatePages, // AllocatePages + (EFI_FREE_PAGES)Ring3FreePages, // FreePages + (EFI_GET_MEMORY_MAP)Ring3GetMemoryMap, // GetMemoryMap + (EFI_ALLOCATE_POOL)Ring3AllocatePool, // AllocatePool + (EFI_FREE_POOL)Ring3FreePool, // FreePool + (EFI_CREATE_EVENT)Ring3CreateEvent, // CreateEvent + (EFI_SET_TIMER)Ring3SetTimer, // SetTimer + (EFI_WAIT_FOR_EVENT)Ring3WaitForEvent, // WaitForEvent + (EFI_SIGNAL_EVENT)Ring3SignalEvent, // SignalEvent + (EFI_CLOSE_EVENT)Ring3CloseEvent, // CloseEvent + (EFI_CHECK_EVENT)Ring3CheckEvent, // CheckEvent + (EFI_INSTALL_PROTOCOL_INTERFACE)Ring3InstallProtocolInterface, // InstallProtocolInterface + (EFI_REINSTALL_PROTOCOL_INTERFACE)Ring3ReinstallProtocolInterface, // ReinstallProtocolInterface + (EFI_UNINSTALL_PROTOCOL_INTERFACE)Ring3UninstallProtocolInterface, // UninstallProtocolInterface + (EFI_HANDLE_PROTOCOL)Ring3HandleProtocol, // HandleProtocol + (VOID *)NULL, // Reserved + (EFI_REGISTER_PROTOCOL_NOTIFY)Ring3RegisterProtocolNotify, // RegisterProtocolNotify + (EFI_LOCATE_HANDLE)Ring3LocateHandle, // LocateHandle + (EFI_LOCATE_DEVICE_PATH)Ring3LocateDevicePath, // LocateDevicePath + (EFI_INSTALL_CONFIGURATION_TABLE)Ring3InstallConfigurationTable, // InstallConfigurationTable + (EFI_IMAGE_LOAD)Ring3LoadImage, // LoadImage + (EFI_IMAGE_START)Ring3StartImage, // StartImage + (EFI_EXIT)Ring3Exit, // Exit + (EFI_IMAGE_UNLOAD)Ring3UnloadImage, // UnloadImage + (EFI_EXIT_BOOT_SERVICES)Ring3ExitBootServices, // ExitBootServices + (EFI_GET_NEXT_MONOTONIC_COUNT)Ring3GetNextMonotonicCount, // GetNextMonotonicCount + (EFI_STALL)Ring3Stall, // Stall + (EFI_SET_WATCHDOG_TIMER)Ring3SetWatchdogTimer, // SetWatchdogTimer + (EFI_CONNECT_CONTROLLER)Ring3ConnectController, // ConnectController + (EFI_DISCONNECT_CONTROLLER)Ring3DisconnectController, // DisconnectController + (EFI_OPEN_PROTOCOL)Ring3OpenProtocol, // OpenProtocol + (EFI_CLOSE_PROTOCOL)Ring3CloseProtocol, // CloseProtocol + (EFI_OPEN_PROTOCOL_INFORMATION)Ring3OpenProtocolInformation, // OpenProtocolInformation + (EFI_PROTOCOLS_PER_HANDLE)Ring3ProtocolsPerHandle, // ProtocolsPerHandle + (EFI_LOCATE_HANDLE_BUFFER)Ring3LocateHandleBuffer, // LocateHandleBuffer + (EFI_LOCATE_PROTOCOL)Ring3LocateProtocol, // LocateProtocol + (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3InstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces + (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3UninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces + (EFI_CALCULATE_CRC32)Ring3CalculateCrc32, // CalculateCrc32 + (EFI_COPY_MEM)CopyMem, // CopyMem + (EFI_SET_MEM)SetMem, // SetMem + (EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx +}; + +EFI_STATUS +EFIAPI +Ring3Call ( + IN VOID *Dummy, + IN VOID *EntryPoint, + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_IMAGE_ENTRY_POINT Function; + + Function = (EFI_IMAGE_ENTRY_POINT)EntryPoint; + + Function (ImageHandle, SystemTable); + + SysCall (SysCallReturnToCore); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3EntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + RING3_DATA *Ring3Data; + + Ring3Data = (RING3_DATA *)SystemTable; + + Ring3Data->EntryPoint = (VOID *)Ring3Call; + Ring3Data->BootServices = &mBootServices; + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf similarity index 69% rename from MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf rename to MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index 42f33e2d66..9eb3b52184 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -9,7 +9,7 @@ [Defines] INF_VERSION = 0x00010005 - BASE_NAME = Ring3Dxe + BASE_NAME = DxeRing3 FILE_GUID = 88EA50C2-0DEA-4F13-B691-B506554E632B MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 @@ -22,15 +22,25 @@ # [Sources] - Ring3Dxe.c + Ring3.h + DxeRing3.c + Ring3UefiBootServices.c + +[Sources.X64] + X64/SysCall.nasm [Packages] MdePkg/MdePkg.dec [LibraryClasses] BaseLib - UefiBootServicesTableLib + BaseMemoryLib + DebugLib UefiDriverEntryPoint +[Protocols] + gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES + gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES + [Depex] TRUE diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h similarity index 100% rename from MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3.h rename to MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c similarity index 62% rename from MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c rename to MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index c5cf04a03e..fc15ffd278 100644 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -1,5 +1,5 @@ /** @file - This library constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. + This driver constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. Copyright (c) 2024, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause @@ -16,81 +16,6 @@ #include "Ring3.h" -EFI_BOOT_SERVICES mBootServices = { - { - EFI_BOOT_SERVICES_SIGNATURE, // Signature - EFI_BOOT_SERVICES_REVISION, // Revision - sizeof (EFI_BOOT_SERVICES), // HeaderSize - 0, // CRC32 - 0 // Reserved - }, - (EFI_RAISE_TPL)Ring3RaiseTpl, // RaiseTPL - (EFI_RESTORE_TPL)Ring3RestoreTpl, // RestoreTPL - (EFI_ALLOCATE_PAGES)Ring3AllocatePages, // AllocatePages - (EFI_FREE_PAGES)Ring3FreePages, // FreePages - (EFI_GET_MEMORY_MAP)Ring3GetMemoryMap, // GetMemoryMap - (EFI_ALLOCATE_POOL)Ring3AllocatePool, // AllocatePool - (EFI_FREE_POOL)Ring3FreePool, // FreePool - (EFI_CREATE_EVENT)Ring3CreateEvent, // CreateEvent - (EFI_SET_TIMER)Ring3SetTimer, // SetTimer - (EFI_WAIT_FOR_EVENT)Ring3WaitForEvent, // WaitForEvent - (EFI_SIGNAL_EVENT)Ring3SignalEvent, // SignalEvent - (EFI_CLOSE_EVENT)Ring3CloseEvent, // CloseEvent - (EFI_CHECK_EVENT)Ring3CheckEvent, // CheckEvent - (EFI_INSTALL_PROTOCOL_INTERFACE)Ring3InstallProtocolInterface, // InstallProtocolInterface - (EFI_REINSTALL_PROTOCOL_INTERFACE)Ring3ReinstallProtocolInterface, // ReinstallProtocolInterface - (EFI_UNINSTALL_PROTOCOL_INTERFACE)Ring3UninstallProtocolInterface, // UninstallProtocolInterface - (EFI_HANDLE_PROTOCOL)Ring3HandleProtocol, // HandleProtocol - (VOID *)NULL, // Reserved - (EFI_REGISTER_PROTOCOL_NOTIFY)Ring3RegisterProtocolNotify, // RegisterProtocolNotify - (EFI_LOCATE_HANDLE)Ring3LocateHandle, // LocateHandle - (EFI_LOCATE_DEVICE_PATH)Ring3LocateDevicePath, // LocateDevicePath - (EFI_INSTALL_CONFIGURATION_TABLE)Ring3InstallConfigurationTable, // InstallConfigurationTable - (EFI_IMAGE_LOAD)Ring3LoadImage, // LoadImage - (EFI_IMAGE_START)Ring3StartImage, // StartImage - (EFI_EXIT)Ring3Exit, // Exit - (EFI_IMAGE_UNLOAD)Ring3UnloadImage, // UnloadImage - (EFI_EXIT_BOOT_SERVICES)Ring3ExitBootServices, // ExitBootServices - (EFI_GET_NEXT_MONOTONIC_COUNT)Ring3GetNextMonotonicCount, // GetNextMonotonicCount - (EFI_STALL)Ring3Stall, // Stall - (EFI_SET_WATCHDOG_TIMER)Ring3SetWatchdogTimer, // SetWatchdogTimer - (EFI_CONNECT_CONTROLLER)Ring3ConnectController, // ConnectController - (EFI_DISCONNECT_CONTROLLER)Ring3DisconnectController, // DisconnectController - (EFI_OPEN_PROTOCOL)Ring3OpenProtocol, // OpenProtocol - (EFI_CLOSE_PROTOCOL)Ring3CloseProtocol, // CloseProtocol - (EFI_OPEN_PROTOCOL_INFORMATION)Ring3OpenProtocolInformation, // OpenProtocolInformation - (EFI_PROTOCOLS_PER_HANDLE)Ring3ProtocolsPerHandle, // ProtocolsPerHandle - (EFI_LOCATE_HANDLE_BUFFER)Ring3LocateHandleBuffer, // LocateHandleBuffer - (EFI_LOCATE_PROTOCOL)Ring3LocateProtocol, // LocateProtocol - (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3InstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces - (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3UninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces - (EFI_CALCULATE_CRC32)Ring3CalculateCrc32, // CalculateCrc32 - (EFI_COPY_MEM)CopyMem, // CopyMem - (EFI_SET_MEM)SetMem, // SetMem - (EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx -}; - -EFI_BOOT_SERVICES *gBS = &mBootServices; - -/** - The function constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. - - @param ImageHandle The firmware allocated handle for the EFI image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. - -**/ -EFI_STATUS -EFIAPI -UefiBootServicesTableLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - return EFI_SUCCESS; -} - EFI_TPL EFIAPI Ring3RaiseTpl ( diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm similarity index 100% rename from MdePkg/Library/Ring3UefiBootServicesTableLib/X64/SysCall.nasm rename to MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm diff --git a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c b/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c deleted file mode 100644 index 55d971eda5..0000000000 --- a/MdeModulePkg/Core/Dxe/SysCall/Ring3Dxe.c +++ /dev/null @@ -1,62 +0,0 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include -#include - -EFI_STATUS -EFIAPI -Ring3Call ( - IN VOID *Dummy, - IN VOID *EntryPoint, - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ); - -EFI_STATUS -EFIAPI -SysCall ( - IN UINT8 Type, - ... - ); - -EFI_STATUS -EFIAPI -Ring3EntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - RING3_DATA *Ring3Data; - - Ring3Data = (RING3_DATA *)SystemTable; - - Ring3Data->EntryPoint = (VOID *)Ring3Call; - Ring3Data->BootServices = gBS; - - return EFI_SUCCESS; -} - -EFI_STATUS -EFIAPI -Ring3Call ( - IN VOID *Dummy, - IN VOID *EntryPoint, - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_IMAGE_ENTRY_POINT Function; - - Function = (EFI_IMAGE_ENTRY_POINT)EntryPoint; - - Function (ImageHandle, SystemTable); - - SysCall (SysCallReturnToCore); - - return EFI_UNSUPPORTED; -} diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf deleted file mode 100644 index c17cb16fe5..0000000000 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.inf +++ /dev/null @@ -1,41 +0,0 @@ -## @file -# Ring 3 wrapper for UEFI Boot Services Table Library implementation. -# -# Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -# SPDX-License-Identifier: BSD-3-Clause -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = Ring3UefiBootServicesTableLib - MODULE_UNI_FILE = Ring3UefiBootServicesTableLib.uni - FILE_GUID = b503b4b4-6dc1-412b-965f-a0f330b1d453 - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = UefiBootServicesTableLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER - - CONSTRUCTOR = UefiBootServicesTableLibConstructor - -# -# VALID_ARCHITECTURES = IA32 X64 EBC -# - -[Sources] - Ring3.h - Ring3UefiBootServicesTableLib.c - -[Sources.X64] - X64/SysCall.nasm - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - BaseMemoryLib - DebugLib - -[Protocols] - gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES - gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES diff --git a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.uni b/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.uni deleted file mode 100644 index 1121e5078f..0000000000 --- a/MdePkg/Library/Ring3UefiBootServicesTableLib/Ring3UefiBootServicesTableLib.uni +++ /dev/null @@ -1,12 +0,0 @@ -// /** @file -// Ring 3 wrapper for UEFI Boot Services Table Library implementation. -// -// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Ring 3 wrapper for UEFI Boot Services Table Library implementation." - -#string STR_MODULE_DESCRIPTION #language en-US "Ring 3 wrapper for UEFI Boot Services Table Library implementation." From 9bec83d806f1e098b3bf9ce85a1250fdcb481d70 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 15 Feb 2024 16:42:30 +0300 Subject: [PATCH 149/341] Ring3: Added SysCallAllocatePool. --- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 14 +++++++++++++- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 13 ++++++++++--- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 15 +++++++++++++++ MdePkg/Include/Uefi/UefiMultiPhase.h | 4 ++++ MdePkg/Include/Uefi/UefiSpec.h | 9 +++++---- 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index fc15ffd278..47010db29b 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -77,7 +77,19 @@ Ring3AllocatePool ( OUT VOID **Buffer ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + + Status = SysCall ( + SysCallAllocatePool, + PoolType, + Size, + Buffer + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate %d bytes.\n", Size)); + } + + return Status; } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 9a24006ee0..2bf6d5aee8 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -310,6 +310,9 @@ GetPermissionAttributeForMemoryType ( ) { UINT64 TestBit; + UINT64 Attributes; + + Attributes = 0; if ((UINT32)MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) { TestBit = BIT63; @@ -320,10 +323,14 @@ GetPermissionAttributeForMemoryType ( } if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & TestBit) != 0) { - return EFI_MEMORY_XP; - } else { - return 0; + Attributes |= EFI_MEMORY_XP; } + + if (MemoryType == EfiRing3MemoryType) { + Attributes |= EFI_MEMORY_USER; + } + + return Attributes; } /** diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index dcf07e66ee..4ae6c6d5ad 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -203,6 +203,21 @@ CallBootService ( return Status; + case SysCallAllocatePool: + // + // Argument 1: EFI_MEMORY_TYPE PoolType + // Argument 2: UINTN Size + // Argument 3: VOID **Buffer + // + DisableSMAP (); + Status = gBS->AllocatePool ( + EfiRing3MemoryType, + CoreRbp->Argument2, + (VOID **)CoreRbp->Argument3 + ); + EnableSMAP (); + + return Status; default: break; } diff --git a/MdePkg/Include/Uefi/UefiMultiPhase.h b/MdePkg/Include/Uefi/UefiMultiPhase.h index 1f1f3f45e5..f0beb4a23d 100644 --- a/MdePkg/Include/Uefi/UefiMultiPhase.h +++ b/MdePkg/Include/Uefi/UefiMultiPhase.h @@ -108,6 +108,10 @@ typedef enum { /// by a corresponding call to the underlying isolation architecture. /// EfiUnacceptedMemoryType, + /// + /// Memory allocated for (by) Ring3 Images. + /// + EfiRing3MemoryType, EfiMaxMemoryType, // // +---------------------------------------------------+ diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 4db3179f0f..6933c37711 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2026,10 +2026,11 @@ typedef struct { } EFI_BOOT_SERVICES; typedef enum { - SysCallReturnToCore = 0, - SysCallLocateProtocol = 1, - SysCallOpenProtocol = 2, - SysCallInstallMultipleProtocolInterfaces = 3, + SysCallReturnToCore, // Must always be zero for CoreBootServices.nasm. + SysCallLocateProtocol, + SysCallOpenProtocol, + SysCallInstallMultipleProtocolInterfaces, + SysCallAllocatePool, SysCallMax } SYS_CALL_TYPE; From 3094b1cf6da6f2d7eec200a828765eaaa69d4d2c Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 15 Feb 2024 18:42:55 +0300 Subject: [PATCH 150/341] Ring3: Refactored CallRing3(). --- MdeModulePkg/Core/Dxe/DxeMain.h | 11 +- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 101 +++++++++++++++--- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf | 2 +- .../Core/Dxe/DxeRing3/X64/SysCall.nasm | 22 +++- MdeModulePkg/Core/Dxe/Image/Image.c | 5 +- .../Core/Dxe/SysCall/SupportedProtocols.c | 52 +++++++-- .../Dxe/SysCall/X64/CoreBootServices.nasm | 15 +-- MdeModulePkg/MdeModulePkg.dsc | 1 + MdePkg/Include/Uefi/UefiSpec.h | 6 ++ 9 files changed, 174 insertions(+), 41 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index f38e2960d1..b00386c1be 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2848,8 +2848,7 @@ CoreBootServices ( EFI_STATUS EFIAPI CallRing3 ( - IN VOID *EntryPoint, - ... + IN RING3_CALL_DATA *Data ); VOID @@ -2864,4 +2863,12 @@ EnableSMAP ( VOID ); +EFI_STATUS +EFIAPI +GoToRing3 ( + IN UINT8 Number, + IN VOID *EntryPoint, + ... + ); + #endif diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index 94f8e78ef7..ff5414ec10 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -64,29 +64,106 @@ EFI_BOOT_SERVICES mBootServices = { (EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx }; +VOID +EFIAPI +Ring3EntryPoint ( + IN RING3_CALL_DATA *Data + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_0)( + VOID + ); + +typedef EFI_STATUS +(EFIAPI *FUNCTION_1)( + IN UINTN Argument1 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_2)( + IN UINTN Argument1, + IN UINTN Argument2 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_3)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_4)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_5)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4, + IN UINTN Argument5 + ); + +VOID EFIAPI Ring3Call ( - IN VOID *Dummy, - IN VOID *EntryPoint, - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable + IN RING3_CALL_DATA *Data ) { - EFI_IMAGE_ENTRY_POINT Function; - - Function = (EFI_IMAGE_ENTRY_POINT)EntryPoint; + FUNCTION_0 Function0; + FUNCTION_1 Function1; + FUNCTION_2 Function2; + FUNCTION_3 Function3; + FUNCTION_4 Function4; + FUNCTION_5 Function5; - Function (ImageHandle, SystemTable); + switch (Data->NumberOfArguments) { + case 0: + Function0 = (FUNCTION_0)Data->EntryPoint; + Function0 (); + break; + case 1: + Function1 = (FUNCTION_1)Data->EntryPoint; + Function1 (Data->Arguments[0]); + break; + case 2: + Function2 = (FUNCTION_2)Data->EntryPoint; + Function2 (Data->Arguments[0], Data->Arguments[1]); + break; + case 3: + Function3 = (FUNCTION_3)Data->EntryPoint; + Function3 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2]); + break; + case 4: + Function4 = (FUNCTION_4)Data->EntryPoint; + Function4 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3]); + break; + case 5: + Function5 = (FUNCTION_5)Data->EntryPoint; + Function5 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4]); + break; + default: + break; + } SysCall (SysCallReturnToCore); - - return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3EntryPoint ( +Ring3Initialization ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) @@ -95,7 +172,7 @@ Ring3EntryPoint ( Ring3Data = (RING3_DATA *)SystemTable; - Ring3Data->EntryPoint = (VOID *)Ring3Call; + Ring3Data->EntryPoint = (VOID *)Ring3EntryPoint; Ring3Data->BootServices = &mBootServices; return EFI_SUCCESS; diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index 9eb3b52184..f22009b8cb 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -13,7 +13,7 @@ FILE_GUID = 88EA50C2-0DEA-4F13-B691-B506554E632B MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 - ENTRY_POINT = Ring3EntryPoint + ENTRY_POINT = Ring3Initialization # # The following information is for reference only and not required by the build tools. diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm index 742063ce72..fc27a0bddc 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm @@ -3,8 +3,10 @@ ; SPDX-License-Identifier: BSD-3-Clause ;------------------------------------------------------------------------------ - DEFAULT REL - SECTION .text +extern ASM_PFX(Ring3Call) + +DEFAULT REL +SECTION .text ;------------------------------------------------------------------------------ ; EFI_STATUS @@ -24,3 +26,19 @@ ASM_PFX(SysCall): ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; Ring3EntryPoint ( +; IN RING3_CALL_DATA *Data +; ); +; +; (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3(). +; (rdx) Data +;------------------------------------------------------------------------------ +global ASM_PFX(Ring3EntryPoint) +ASM_PFX(Ring3EntryPoint): + mov rcx, rdx + + call ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index a24f878918..124da21b33 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1838,10 +1838,11 @@ CoreStartImage ( EFI_MEMORY_XP | EFI_MEMORY_USER ); - Image->Status = CallRing3 ( + Image->Status = GoToRing3 ( + 2, (VOID *)Image->EntryPoint, ImageHandle, - (EFI_SYSTEM_TABLE *)mRing3Data + mRing3Data ); } else { Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 50c89956f4..e40e26cb5d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -11,12 +11,43 @@ EFI_DRIVER_BINDING_SUPPORTED mUserDriverBindingSupported; EFI_DRIVER_BINDING_START mUserDriverBindingStart; EFI_DRIVER_BINDING_STOP mUserDriverBindingStop; -typedef enum { - UserDriverBindingSupported = 1, - UserDriverBindingStart = 2, - UserDriverBindingStop = 3, - UserCallMax -} USER_CALL_TYPE; +EFI_STATUS +EFIAPI +GoToRing3 ( + IN UINT8 Number, + IN VOID *EntryPoint, + ... + ) +{ + EFI_STATUS Status; + RING3_CALL_DATA *Input; + VA_LIST Marker; + UINTN Index; + + DisableSMAP (); + Status = gBS->AllocatePool ( + EfiRing3MemoryType, + sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN), + (VOID **)&Input + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate memory for Input data.\n")); + EnableSMAP (); + return Status; + } + + Input->NumberOfArguments = Number; + Input->EntryPoint = EntryPoint; + + VA_START (Marker, EntryPoint); + for (Index = 0; Index < Number; ++Index) { + Input->Arguments[Index] = VA_ARG (Marker, UINTN); + } + VA_END (Marker); + EnableSMAP (); + + return CallRing3 (Input); +} EFI_STATUS EFIAPI @@ -26,7 +57,8 @@ CoreDriverBindingSupported ( IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ) { - return CallRing3 ( + return GoToRing3 ( + 3, (VOID *)mUserDriverBindingSupported, This, ControllerHandle, @@ -42,7 +74,8 @@ CoreDriverBindingStart ( IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ) { - return CallRing3 ( + return GoToRing3 ( + 3, (VOID *)mUserDriverBindingStart, This, ControllerHandle, @@ -59,7 +92,8 @@ CoreDriverBindingStop ( IN EFI_HANDLE *ChildHandleBuffer OPTIONAL ) { - return CallRing3 ( + return GoToRing3 ( + 4, (VOID *)mUserDriverBindingStop, This, ControllerHandle, diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 90bcd4a0a0..4f3071bb41 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -178,23 +178,16 @@ o64 sysret ; EFI_STATUS ; EFIAPI ; CallRing3 ( -; IN VOID *EntryPoint, -; ... +; IN RING3_CALL_DATA *Data ; ); ; -; (rcx) EntryPoint - Entry point in User address space. -; (rdx) Context1 - Parameter1 for entry point. -; (r8) Context2 - Parameter2 for entry point. +; (rcx) Data ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): ; Save input Arguments. push r12 - push r13 - push r14 mov r12, rcx - mov r13, rdx - mov r14, r8 ; Extract User Data selector. mov rcx, MSR_IA32_STAR @@ -213,14 +206,10 @@ ASM_PFX(CallRing3): ; Prepare SYSRET arguments. mov rcx, [gRing3EntryPoint] mov rdx, r12 - mov r8, r13 - mov r9, r14 pushfq pop r11 ; Restore stack and registers. - pop r14 - pop r13 pop r12 ; Save Core Stack pointers and switch to User Stack. diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index e78a950e15..68e986ecf0 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -304,6 +304,7 @@ MdeModulePkg/Bus/Spi/SpiHc/SpiHcDxe.inf MdeModulePkg/Bus/Spi/SpiHc/SpiHcSmm.inf + MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf MdeModulePkg/Core/Pei/PeiMain.inf MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 6933c37711..60802e495c 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2127,6 +2127,12 @@ typedef struct { EFI_BOOT_SERVICES *BootServices; } RING3_DATA; +typedef struct { + UINT8 NumberOfArguments; + VOID *EntryPoint; + UINTN Arguments[]; +} RING3_CALL_DATA; + /** This is the declaration of an EFI image entry point. This entry point is the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including From 89ef771b3c70c5dce7b13b38e52709cfc36468f7 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 16 Feb 2024 14:57:30 +0300 Subject: [PATCH 151/341] Ring3: Refactored AllocateRing3CopyPages() and mUserDriverBinding. --- MdeModulePkg/Core/Dxe/DxeMain.h | 7 +++-- MdeModulePkg/Core/Dxe/Image/Image.c | 28 ++++++++++++------- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 16 ++++++----- .../Core/Dxe/SysCall/SupportedProtocols.c | 10 +++---- .../Core/Dxe/SysCall/SupportedProtocols.h | 4 +-- 5 files changed, 36 insertions(+), 29 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index b00386c1be..44b371640a 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -1177,9 +1177,10 @@ CoreAllocatePages ( VOID * EFIAPI -AllocateRing3CopyPages ( - IN VOID *MemoryCore, - IN UINT32 MemoryCoreSize +AllocateRing3Copy ( + IN VOID *Source, + IN UINT32 AllocationSize, + IN UINT32 CopySize ); /** diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 124da21b33..2fadb7f5d0 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1571,21 +1571,24 @@ CoreLoadImage ( VOID * EFIAPI -AllocateRing3CopyPages ( - IN VOID *MemoryCore, - IN UINT32 MemoryCoreSize +AllocateRing3Copy ( + IN VOID *Source, + IN UINT32 AllocationSize, + IN UINT32 CopySize ) { - VOID *MemoryRing3; + EFI_STATUS Status; + VOID *MemoryRing3; - MemoryRing3 = AllocatePages (EFI_SIZE_TO_PAGES (MemoryCoreSize)); - if (MemoryRing3 == NULL) { + Status = CoreAllocatePool (EfiRing3MemoryType, AllocationSize, &MemoryRing3); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate %d bytes for Ring3.\n", AllocationSize)); return NULL; } - CopyMem (MemoryRing3, MemoryCore, MemoryCoreSize); + ASSERT (CopySize <= AllocationSize); - SetUefiImageMemoryAttributes ((UINTN)MemoryRing3, EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (MemoryCoreSize)), EFI_MEMORY_USER); + CopyMem (MemoryRing3, Source, CopySize); return MemoryRing3; } @@ -1613,8 +1616,13 @@ InitializeRing3 ( // // Set Ring3 EntryPoint and BootServices. // - mRing3Data = AllocateRing3CopyPages ((VOID *)Image->Info.SystemTable, sizeof (RING3_DATA)); - + mRing3Data = AllocateRing3Copy ( + (VOID *)Image->Info.SystemTable, + sizeof (RING3_DATA), + sizeof (EFI_SYSTEM_TABLE) + ); + ASSERT (mRing3Data != NULL); + Image->Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)mRing3Data); gRing3EntryPoint = mRing3Data->EntryPoint; diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 4ae6c6d5ad..92f931f0a1 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -92,13 +92,14 @@ CallBootService ( &Interface ); - Interface = AllocateRing3CopyPages (Interface, MemoryCoreSize); + DisableSMAP (); + Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); if (Interface == NULL) { DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n")); + EnableSMAP (); return EFI_OUT_OF_RESOURCES; } - DisableSMAP (); *(VOID **)CoreRbp->Argument3 = Interface; EnableSMAP (); @@ -137,13 +138,14 @@ CallBootService ( Argument6 ); - Interface = AllocateRing3CopyPages (Interface, MemoryCoreSize); + DisableSMAP (); + Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); if (Interface == NULL) { DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n")); + EnableSMAP (); return EFI_OUT_OF_RESOURCES; } - DisableSMAP (); *(VOID **)CoreRbp->Argument3 = Interface; EnableSMAP (); @@ -184,9 +186,9 @@ CallBootService ( if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiDriverBindingProtocolGuid)) { CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)CoreArgList[Index + 1]; - mUserDriverBindingSupported = CoreDriverBinding->Supported; - mUserDriverBindingStart = CoreDriverBinding->Start; - mUserDriverBindingStop = CoreDriverBinding->Stop; + mRing3DriverBindingProtocol.Supported = CoreDriverBinding->Supported; + mRing3DriverBindingProtocol.Start = CoreDriverBinding->Start; + mRing3DriverBindingProtocol.Stop = CoreDriverBinding->Stop; CoreDriverBinding->Supported = CoreDriverBindingSupported; CoreDriverBinding->Start = CoreDriverBindingStart; diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index e40e26cb5d..9140ce7ec1 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -7,9 +7,7 @@ #include "DxeMain.h" -EFI_DRIVER_BINDING_SUPPORTED mUserDriverBindingSupported; -EFI_DRIVER_BINDING_START mUserDriverBindingStart; -EFI_DRIVER_BINDING_STOP mUserDriverBindingStop; +EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; EFI_STATUS EFIAPI @@ -59,7 +57,7 @@ CoreDriverBindingSupported ( { return GoToRing3 ( 3, - (VOID *)mUserDriverBindingSupported, + (VOID *)mRing3DriverBindingProtocol.Supported, This, ControllerHandle, RemainingDevicePath @@ -76,7 +74,7 @@ CoreDriverBindingStart ( { return GoToRing3 ( 3, - (VOID *)mUserDriverBindingStart, + (VOID *)mRing3DriverBindingProtocol.Start, This, ControllerHandle, RemainingDevicePath @@ -94,7 +92,7 @@ CoreDriverBindingStop ( { return GoToRing3 ( 4, - (VOID *)mUserDriverBindingStop, + (VOID *)mRing3DriverBindingProtocol.Stop, This, ControllerHandle, NumberOfChildren, diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h index 4737cc696e..5e7e8b3a7a 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -5,9 +5,7 @@ **/ -extern EFI_DRIVER_BINDING_SUPPORTED mUserDriverBindingSupported; -extern EFI_DRIVER_BINDING_START mUserDriverBindingStart; -extern EFI_DRIVER_BINDING_STOP mUserDriverBindingStop; +extern EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; EFI_STATUS EFIAPI From c3736c6aeb6e1b448092992ea9e71f33637f05a6 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 16 Feb 2024 15:45:25 +0300 Subject: [PATCH 152/341] Ring3: Added SysCallFreePool, fixed wrappers for EFI_DRIVER_BINDING_PROTOCOL. --- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 12 ++- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 14 ++- .../Core/Dxe/SysCall/SupportedProtocols.c | 92 +++++++++++++++---- MdePkg/Include/Uefi/UefiSpec.h | 1 + 4 files changed, 100 insertions(+), 19 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 47010db29b..9d02c2c6b8 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -98,7 +98,17 @@ Ring3FreePool ( IN VOID *Buffer ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + + Status = SysCall ( + SysCallFreePool, + Buffer + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to free buffer.\n")); + } + + return Status; } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 92f931f0a1..55d38e4864 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -95,7 +95,6 @@ CallBootService ( DisableSMAP (); Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); if (Interface == NULL) { - DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n")); EnableSMAP (); return EFI_OUT_OF_RESOURCES; } @@ -141,7 +140,6 @@ CallBootService ( DisableSMAP (); Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); if (Interface == NULL) { - DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate pages for Ring3 PROTOCOL structure.\n")); EnableSMAP (); return EFI_OUT_OF_RESOURCES; } @@ -219,6 +217,18 @@ CallBootService ( ); EnableSMAP (); + return Status; + + case SysCallFreePool: + // + // Argument 1: IN VOID *Buffer + // + DisableSMAP (); + Status = gBS->FreePool ( + (VOID *)CoreRbp->Argument1 + ); + EnableSMAP (); + return Status; default: break; diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 9140ce7ec1..4557536998 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -55,13 +55,33 @@ CoreDriverBindingSupported ( IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ) { - return GoToRing3 ( - 3, - (VOID *)mRing3DriverBindingProtocol.Supported, + EFI_STATUS Status; + + DisableSMAP (); + This = AllocateRing3Copy ( This, - ControllerHandle, - RemainingDevicePath + sizeof (EFI_DRIVER_BINDING_PROTOCOL), + sizeof (EFI_DRIVER_BINDING_PROTOCOL) ); + if (This == NULL) { + EnableSMAP (); + return EFI_OUT_OF_RESOURCES; + } + EnableSMAP (); + + Status = GoToRing3 ( + 3, + (VOID *)mRing3DriverBindingProtocol.Supported, + This, + ControllerHandle, + RemainingDevicePath + ); + + DisableSMAP (); + FreePool (This); + EnableSMAP (); + + return Status; } EFI_STATUS @@ -72,13 +92,33 @@ CoreDriverBindingStart ( IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ) { - return GoToRing3 ( - 3, - (VOID *)mRing3DriverBindingProtocol.Start, + EFI_STATUS Status; + + DisableSMAP (); + This = AllocateRing3Copy ( This, - ControllerHandle, - RemainingDevicePath + sizeof (EFI_DRIVER_BINDING_PROTOCOL), + sizeof (EFI_DRIVER_BINDING_PROTOCOL) ); + if (This == NULL) { + EnableSMAP (); + return EFI_OUT_OF_RESOURCES; + } + EnableSMAP (); + + Status = GoToRing3 ( + 3, + (VOID *)mRing3DriverBindingProtocol.Start, + This, + ControllerHandle, + RemainingDevicePath + ); + + DisableSMAP (); + FreePool (This); + EnableSMAP (); + + return Status; } EFI_STATUS @@ -90,12 +130,32 @@ CoreDriverBindingStop ( IN EFI_HANDLE *ChildHandleBuffer OPTIONAL ) { - return GoToRing3 ( - 4, - (VOID *)mRing3DriverBindingProtocol.Stop, + EFI_STATUS Status; + + DisableSMAP (); + This = AllocateRing3Copy ( This, - ControllerHandle, - NumberOfChildren, - ChildHandleBuffer + sizeof (EFI_DRIVER_BINDING_PROTOCOL), + sizeof (EFI_DRIVER_BINDING_PROTOCOL) ); + if (This == NULL) { + EnableSMAP (); + return EFI_OUT_OF_RESOURCES; + } + EnableSMAP (); + + Status = GoToRing3 ( + 4, + (VOID *)mRing3DriverBindingProtocol.Stop, + This, + ControllerHandle, + NumberOfChildren, + ChildHandleBuffer + ); + + DisableSMAP (); + FreePool (This); + EnableSMAP (); + + return Status; } diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 60802e495c..42b57b356e 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2031,6 +2031,7 @@ typedef enum { SysCallOpenProtocol, SysCallInstallMultipleProtocolInterfaces, SysCallAllocatePool, + SysCallFreePool, SysCallMax } SYS_CALL_TYPE; From 982e17572b8c7581608949659118cc0414dce55b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 16 Feb 2024 16:40:30 +0300 Subject: [PATCH 153/341] Ring3: Refactored comparing of GUIDs. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 2 + MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf | 2 + .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 2 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 79 ++++++++++++------- .../Core/Dxe/SysCall/SupportedProtocols.h | 5 ++ 5 files changed, 59 insertions(+), 31 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 014f6576c5..d6656b3dff 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -167,6 +167,8 @@ gEdkiiPeCoffImageEmulatorProtocolGuid ## SOMETIMES_CONSUMES gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES gEfiComponentNameProtocolGuid ## SOMETIMES_CONSUMES + gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES # Arch Protocols gEfiBdsArchProtocolGuid ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index f22009b8cb..3dbe4b7532 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -41,6 +41,8 @@ [Protocols] gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES + gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES [Depex] TRUE diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 9d02c2c6b8..c1aec1b883 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -398,7 +398,7 @@ Ring3OpenProtocol ( Attributes ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to open protocol %g\n", Protocol)); + DEBUG ((DEBUG_ERROR, "Ring3: Failed to open protocol %g - %r\n", Protocol, Status)); return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 55d38e4864..24f5c79606 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -8,9 +8,6 @@ #include "DxeMain.h" #include "SupportedProtocols.h" -#include -#include - EFI_STATUS EFIAPI CallInstallMultipleProtocolInterfaces ( @@ -20,6 +17,43 @@ CallInstallMultipleProtocolInterfaces ( IN VOID *Function ); +EFI_STATUS +EFIAPI +FindGuid ( + IN EFI_GUID *Ring3, + OUT EFI_GUID **Core, + OUT UINT32 *CoreSize + ) +{ + ASSERT (Core != NULL); + ASSERT (CoreSize != NULL); + + if (CompareGuid (Ring3, &gEfiDevicePathUtilitiesProtocolGuid)) { + *Core = &gEfiDevicePathUtilitiesProtocolGuid; + *CoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiLoadedImageProtocolGuid)) { + *Core = &gEfiLoadedImageProtocolGuid; + *CoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiBlockIoProtocolGuid)) { + *Core = &gEfiBlockIoProtocolGuid; + *CoreSize = sizeof (EFI_BLOCK_IO_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiDiskIoProtocolGuid)) { + *Core = &gEfiDiskIoProtocolGuid; + *CoreSize = sizeof (EFI_DISK_IO_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiDriverBindingProtocolGuid)) { + *Core = &gEfiDriverBindingProtocolGuid; + *CoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiComponentNameProtocolGuid)) { + *Core = &gEfiComponentNameProtocolGuid; + *CoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); + } else { + DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol.\n")); + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + typedef struct { UINTN Argument1; UINTN Argument2; @@ -76,15 +110,11 @@ CallBootService ( // Argument 3: VOID **Interface // DisableSMAP (); - if (CompareGuid ((EFI_GUID *)CoreRbp->Argument1, &gEfiDevicePathUtilitiesProtocolGuid)) { - CoreProtocol = &gEfiDevicePathUtilitiesProtocolGuid; - MemoryCoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); - } else { - DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol.\n")); - EnableSMAP (); - return EFI_INVALID_PARAMETER; - } + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument1, &CoreProtocol, &MemoryCoreSize); EnableSMAP (); + if (EFI_ERROR (Status)) { + return Status; + } Status = gBS->LocateProtocol ( CoreProtocol, @@ -114,13 +144,10 @@ CallBootService ( // Argument 6: UINT32 Attributes // DisableSMAP (); - if (CompareGuid ((EFI_GUID *)CoreRbp->Argument2, &gEfiLoadedImageProtocolGuid)) { - CoreProtocol = &gEfiLoadedImageProtocolGuid; - MemoryCoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); - } else { - DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol.\n")); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + if (EFI_ERROR (Status)) { EnableSMAP (); - return EFI_INVALID_PARAMETER; + return Status; } Argument4 = (EFI_HANDLE)UserRsp->Arguments[4]; @@ -158,22 +185,14 @@ CallBootService ( CoreHandle = *(EFI_HANDLE *)CoreRbp->Argument1; UserArgList = (VOID **)CoreRbp->Argument2; - for (Index = 0; UserArgList[Index] != NULL; ++Index) { - if (CompareGuid ((EFI_GUID *)UserArgList[Index], &gEfiDriverBindingProtocolGuid)) { - CoreArgList[Index] = (VOID *)&gEfiDriverBindingProtocolGuid; - MemoryCoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL); - continue; - } else if (CompareGuid ((EFI_GUID *)UserArgList[Index], &gEfiComponentNameProtocolGuid)) { - CoreArgList[Index] = (VOID *)&gEfiComponentNameProtocolGuid; - MemoryCoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); - continue; - } else if ((Index % 2) == 0) { - DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol.\n")); + for (Index = 0; UserArgList[Index] != NULL; Index += 2) { + Status = FindGuid ((EFI_GUID *)UserArgList[Index], (EFI_GUID **)&CoreArgList[Index], &MemoryCoreSize); + if (EFI_ERROR (Status)) { EnableSMAP (); - return EFI_INVALID_PARAMETER; + return Status; } - CoreArgList[Index] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index]); + CoreArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index + 1]); } EnableSMAP (); diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h index 5e7e8b3a7a..6862030896 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -5,6 +5,11 @@ **/ +#include +#include +#include +#include + extern EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; EFI_STATUS From 9b963c638ed83ca3ec7bd6d3a526fa1628ed72d9 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 19 Feb 2024 11:35:25 +0300 Subject: [PATCH 154/341] Ring3: Added Ring3BlockIo and Ring3DiskIo drafts. --- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf | 1 + MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h | 156 ++++++++++++++++++ .../Core/Dxe/DxeRing3/Ring3Protocols.c | 82 +++++++++ .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 63 ++++--- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 35 ++++ 5 files changed, 318 insertions(+), 19 deletions(-) create mode 100644 MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index 3dbe4b7532..cfcb4d43ed 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -25,6 +25,7 @@ Ring3.h DxeRing3.c Ring3UefiBootServices.c + Ring3Protocols.c [Sources.X64] X64/SysCall.nasm diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h index 2713748f40..30680d35f2 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h @@ -5,6 +5,14 @@ **/ +#include +#include +#include +#include + +extern EFI_BLOCK_IO_PROTOCOL mCoreBlockIo; +extern EFI_DISK_IO_PROTOCOL mCoreDiskIo; + EFI_STATUS EFIAPI SysCall ( @@ -1011,3 +1019,151 @@ Ring3CreateEventEx ( IN CONST EFI_GUID *EventGroup OPTIONAL, OUT EFI_EVENT *Event ); + +/** + Reset the Block Device. + + @param This Indicates a pointer to the calling context. + @param ExtendedVerification Driver may perform diagnostics on reset. + + @retval EFI_SUCCESS The device was reset. + @retval EFI_DEVICE_ERROR The device is not functioning properly and could + not be reset. + +**/ +EFI_STATUS +EFIAPI +Ring3BlockIoReset ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +/** + Read BufferSize bytes from Lba into Buffer. + + @param This Indicates a pointer to the calling context. + @param MediaId Id of the media, changes every time the media is replaced. + @param Lba The starting Logical Block Address to read from + @param BufferSize Size of Buffer, must be a multiple of device block size. + @param Buffer A pointer to the destination buffer for the data. The caller is + responsible for either having implicit or explicit ownership of the buffer. + + @retval EFI_SUCCESS The data was read correctly from the device. + @retval EFI_DEVICE_ERROR The device reported an error while performing the read. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. + @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. + @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, + or the buffer is not on proper alignment. + +**/ +EFI_STATUS +EFIAPI +Ring3BlockIoRead ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + +/** + Write BufferSize bytes from Lba into Buffer. + + @param This Indicates a pointer to the calling context. + @param MediaId The media ID that the write request is for. + @param Lba The starting logical block address to be written. The caller is + responsible for writing to only legitimate locations. + @param BufferSize Size of Buffer, must be a multiple of device block size. + @param Buffer A pointer to the source buffer for the data. + + @retval EFI_SUCCESS The data was written correctly to the device. + @retval EFI_WRITE_PROTECTED The device can not be written to. + @retval EFI_DEVICE_ERROR The device reported an error while performing the write. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. + @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, + or the buffer is not on proper alignment. + +**/ +EFI_STATUS +EFIAPI +Ring3BlockIoWrite ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +/** + Flush the Block Device. + + @param This Indicates a pointer to the calling context. + + @retval EFI_SUCCESS All outstanding data was written to the device + @retval EFI_DEVICE_ERROR The device reported an error while writting back the data + @retval EFI_NO_MEDIA There is no media in the device. + +**/ +EFI_STATUS +EFIAPI +Ring3BlockIoFlush ( + IN EFI_BLOCK_IO_PROTOCOL *This + ); + +/** + Read BufferSize bytes from Offset into Buffer. + + @param This Protocol instance pointer. + @param MediaId Id of the media, changes every time the media is replaced. + @param Offset The starting byte offset to read from + @param BufferSize Size of Buffer + @param Buffer Buffer containing read data + + @retval EFI_SUCCESS The data was read correctly from the device. + @retval EFI_DEVICE_ERROR The device reported an error while performing the read. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not + valid for the device. + +**/ +EFI_STATUS +EFIAPI +Ring3DiskIoRead ( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + +/** + Writes a specified number of bytes to a device. + + @param This Indicates a pointer to the calling context. + @param MediaId ID of the medium to be written. + @param Offset The starting byte offset on the logical block I/O device to write. + @param BufferSize The size in bytes of Buffer. The number of bytes to write to the device. + @param Buffer A pointer to the buffer containing the data to be written. + + @retval EFI_SUCCESS The data was written correctly to the device. + @retval EFI_WRITE_PROTECTED The device can not be written to. + @retval EFI_DEVICE_ERROR The device reported an error while performing the write. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not + valid for the device. + +**/ +EFI_STATUS +EFIAPI +Ring3DiskIoWrite ( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + IN VOID *Buffer + ); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c new file mode 100644 index 0000000000..6bec0eee9e --- /dev/null +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c @@ -0,0 +1,82 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "Ring3.h" + +EFI_BLOCK_IO_PROTOCOL mCoreBlockIo; +EFI_DISK_IO_PROTOCOL mCoreDiskIo; + +EFI_STATUS +EFIAPI +Ring3BlockIoReset ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3BlockIoRead ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3BlockIoWrite ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3BlockIoFlush ( + IN EFI_BLOCK_IO_PROTOCOL *This + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3DiskIoRead ( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3DiskIoWrite ( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index c1aec1b883..84b30af06c 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -11,9 +11,6 @@ #include #include -#include -#include - #include "Ring3.h" EFI_TPL @@ -386,7 +383,9 @@ Ring3OpenProtocol ( { EFI_STATUS Status; - EFI_LOADED_IMAGE_PROTOCOL *UserProtocol; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; Status = SysCall ( SysCallOpenProtocol, @@ -403,16 +402,42 @@ Ring3OpenProtocol ( } if (CompareGuid (Protocol, &gEfiLoadedImageProtocolGuid)) { - UserProtocol = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; + + LoadedImage = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; // TODO: Copy User changes to Core? Resembles InstallMultipleProtocolInterfaces(). - UserProtocol->Unload = NULL; + LoadedImage->Unload = NULL; - return Status; + } else if (CompareGuid (Protocol, &gEfiBlockIoProtocolGuid)) { + + BlockIo = (EFI_BLOCK_IO_PROTOCOL *)*Interface; + + mCoreBlockIo.Reset = BlockIo->Reset; + mCoreBlockIo.ReadBlocks = BlockIo->ReadBlocks; + mCoreBlockIo.WriteBlocks = BlockIo->WriteBlocks; + mCoreBlockIo.FlushBlocks = BlockIo->FlushBlocks; + + BlockIo->Reset = Ring3BlockIoReset; + BlockIo->ReadBlocks = Ring3BlockIoRead; + BlockIo->WriteBlocks = Ring3BlockIoWrite; + BlockIo->FlushBlocks = Ring3BlockIoFlush; + + } else if (CompareGuid (Protocol, &gEfiDiskIoProtocolGuid)) { + + DiskIo = (EFI_DISK_IO_PROTOCOL *)*Interface; + + mCoreDiskIo.ReadDisk = DiskIo->ReadDisk; + mCoreDiskIo.WriteDisk = DiskIo->WriteDisk; + + DiskIo->ReadDisk = Ring3DiskIoRead; + DiskIo->WriteDisk = Ring3DiskIoWrite; + + } else { + Status = EFI_UNSUPPORTED; } - return EFI_UNSUPPORTED; + return Status; } EFI_STATUS @@ -473,7 +498,7 @@ Ring3LocateProtocol ( { EFI_STATUS Status; - EFI_DEVICE_PATH_UTILITIES_PROTOCOL *UserProtocol; + EFI_DEVICE_PATH_UTILITIES_PROTOCOL *DevicePath; Status = SysCall ( SysCallLocateProtocol, @@ -487,16 +512,16 @@ Ring3LocateProtocol ( } if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { - UserProtocol = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; - - UserProtocol->GetDevicePathSize = NULL; - UserProtocol->DuplicateDevicePath = NULL; - UserProtocol->AppendDevicePath = NULL; - UserProtocol->AppendDeviceNode = NULL; - UserProtocol->AppendDevicePathInstance = NULL; - UserProtocol->GetNextDevicePathInstance = NULL; - UserProtocol->IsDevicePathMultiInstance = NULL; - UserProtocol->CreateDeviceNode = NULL; + DevicePath = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; + + DevicePath->GetDevicePathSize = NULL; + DevicePath->DuplicateDevicePath = NULL; + DevicePath->AppendDevicePath = NULL; + DevicePath->AppendDeviceNode = NULL; + DevicePath->AppendDevicePathInstance = NULL; + DevicePath->GetNextDevicePathInstance = NULL; + DevicePath->IsDevicePathMultiInstance = NULL; + DevicePath->CreateDeviceNode = NULL; return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 24f5c79606..51a24a71b4 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -29,23 +29,35 @@ FindGuid ( ASSERT (CoreSize != NULL); if (CompareGuid (Ring3, &gEfiDevicePathUtilitiesProtocolGuid)) { + *Core = &gEfiDevicePathUtilitiesProtocolGuid; *CoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiLoadedImageProtocolGuid)) { + *Core = &gEfiLoadedImageProtocolGuid; *CoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiBlockIoProtocolGuid)) { + *Core = &gEfiBlockIoProtocolGuid; *CoreSize = sizeof (EFI_BLOCK_IO_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiDiskIoProtocolGuid)) { + *Core = &gEfiDiskIoProtocolGuid; *CoreSize = sizeof (EFI_DISK_IO_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiDriverBindingProtocolGuid)) { + *Core = &gEfiDriverBindingProtocolGuid; *CoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiComponentNameProtocolGuid)) { + *Core = &gEfiComponentNameProtocolGuid; *CoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); + } else { DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol.\n")); return EFI_NOT_FOUND; @@ -54,6 +66,26 @@ FindGuid ( return EFI_SUCCESS; } +VOID +EFIAPI +FixInterface ( + IN EFI_GUID *Guid, + IN OUT VOID *Interface + ) +{ + EFI_BLOCK_IO_PROTOCOL *BlockIo; + + if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) { + BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Interface; + + BlockIo->Media = AllocateRing3Copy ( + BlockIo->Media, + sizeof (EFI_BLOCK_IO_MEDIA), + sizeof (EFI_BLOCK_IO_MEDIA) + ); + } +} + typedef struct { UINTN Argument1; UINTN Argument2; @@ -171,6 +203,8 @@ CallBootService ( return EFI_OUT_OF_RESOURCES; } + FixInterface (CoreProtocol, Interface); + *(VOID **)CoreRbp->Argument3 = Interface; EnableSMAP (); @@ -189,6 +223,7 @@ CallBootService ( Status = FindGuid ((EFI_GUID *)UserArgList[Index], (EFI_GUID **)&CoreArgList[Index], &MemoryCoreSize); if (EFI_ERROR (Status)) { EnableSMAP (); + //TODO: Free CoreArgList. return Status; } From 887d84f20b15ed14461d85c92edb653281b4e337 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 19 Feb 2024 15:00:10 +0300 Subject: [PATCH 155/341] Ring3: Some refactoring. --- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 2 +- MdeModulePkg/Core/Dxe/Image/Image.c | 11 +------- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 25 +++++++++++-------- .../Core/Dxe/SysCall/SupportedProtocols.c | 19 +++++++++++++- .../Dxe/SysCall/X64/CoreBootServices.nasm | 1 - 5 files changed, 35 insertions(+), 23 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 84b30af06c..fb04ac7f32 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -397,7 +397,7 @@ Ring3OpenProtocol ( Attributes ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to open protocol %g - %r\n", Protocol, Status)); + // DEBUG ((DEBUG_ERROR, "Ring3: Failed to open protocol %g - %r\n", Protocol, Status)); return Status; } diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 2fadb7f5d0..23f5c535e3 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1698,7 +1698,7 @@ InitializeRing3 ( // // Initialize MSR_IA32_STAR and MSR_IA32_LSTAR for SYSCALL and SYSRET. // - Msr = ((((UINT64)RING3_CODE64_SEL - 16) << 16) | (UINT64)RING0_CODE64_SEL) << 32; + Msr = (((((UINT64)RING3_CODE64_SEL - 16) | 3) << 16) | (UINT64)RING0_CODE64_SEL) << 32; AsmWriteMsr64 (MSR_IA32_STAR, Msr); Msr = (UINT64)(UINTN)CoreBootServices; @@ -1837,15 +1837,6 @@ CoreStartImage ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - // - // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() - // - SetUefiImageMemoryAttributes ( - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - Image->Status = GoToRing3 ( 2, (VOID *)Image->EntryPoint, diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 51a24a71b4..c72242c3a1 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -155,10 +155,12 @@ CallBootService ( ); DisableSMAP (); - Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); - if (Interface == NULL) { - EnableSMAP (); - return EFI_OUT_OF_RESOURCES; + if (Interface != NULL) { + Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); + if (Interface == NULL) { + EnableSMAP (); + return EFI_OUT_OF_RESOURCES; + } } *(VOID **)CoreRbp->Argument3 = Interface; @@ -197,13 +199,15 @@ CallBootService ( ); DisableSMAP (); - Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); - if (Interface == NULL) { - EnableSMAP (); - return EFI_OUT_OF_RESOURCES; - } + if (Interface != NULL) { + Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); + if (Interface == NULL) { + EnableSMAP (); + return EFI_OUT_OF_RESOURCES; + } - FixInterface (CoreProtocol, Interface); + FixInterface (CoreProtocol, Interface); + } *(VOID **)CoreRbp->Argument3 = Interface; EnableSMAP (); @@ -285,6 +289,7 @@ CallBootService ( return Status; default: + DEBUG ((DEBUG_ERROR, "Ring0: Unknown syscall type.\n")); break; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 4557536998..bf7f7b6200 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -44,7 +44,24 @@ GoToRing3 ( VA_END (Marker); EnableSMAP (); - return CallRing3 (Input); + // + // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() + // + SetUefiImageMemoryAttributes ( + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + Status = CallRing3 (Input); + + SetUefiImageMemoryAttributes ( + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP + ); + + return Status; } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 4f3071bb41..0987cf9320 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -197,7 +197,6 @@ ASM_PFX(CallRing3): add rax, 8 ; Set Data selectors - or rax, 3H ; RPL = 3 mov ds, ax mov es, ax mov fs, ax From 5b5b4d79948de645d5c9bb488f84807a016c4ea7 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 20 Feb 2024 14:17:10 +0300 Subject: [PATCH 156/341] Ring3: Added BlockIo, DiskIo wrappers. --- MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h | 3 - .../Core/Dxe/DxeRing3/Ring3Protocols.c | 47 ++++- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 8 - MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 175 +++++++++++++++++- MdePkg/Include/Uefi/UefiSpec.h | 9 + 5 files changed, 215 insertions(+), 27 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h index 30680d35f2..83d64e50cf 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h @@ -10,9 +10,6 @@ #include #include -extern EFI_BLOCK_IO_PROTOCOL mCoreBlockIo; -extern EFI_DISK_IO_PROTOCOL mCoreDiskIo; - EFI_STATUS EFIAPI SysCall ( diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c index 6bec0eee9e..2bd03a1a37 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c @@ -17,7 +17,11 @@ Ring3BlockIoReset ( IN BOOLEAN ExtendedVerification ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallBlockIoReset, + This, + ExtendedVerification + ); } EFI_STATUS @@ -30,7 +34,14 @@ Ring3BlockIoRead ( OUT VOID *Buffer ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallBlockIoRead, + This, + MediaId, + Lba, + BufferSize, + Buffer + ); } EFI_STATUS @@ -43,7 +54,14 @@ Ring3BlockIoWrite ( IN VOID *Buffer ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallBlockIoWrite, + This, + MediaId, + Lba, + BufferSize, + Buffer + ); } EFI_STATUS @@ -52,7 +70,10 @@ Ring3BlockIoFlush ( IN EFI_BLOCK_IO_PROTOCOL *This ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallBlockIoFlush, + This + ); } EFI_STATUS @@ -65,7 +86,14 @@ Ring3DiskIoRead ( OUT VOID *Buffer ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallDiskIoRead, + This, + MediaId, + Offset, + BufferSize, + Buffer + ); } EFI_STATUS @@ -78,5 +106,12 @@ Ring3DiskIoWrite ( IN VOID *Buffer ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallDiskIoWrite, + This, + MediaId, + Offset, + BufferSize, + Buffer + ); } diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index fb04ac7f32..d6950485f5 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -413,11 +413,6 @@ Ring3OpenProtocol ( BlockIo = (EFI_BLOCK_IO_PROTOCOL *)*Interface; - mCoreBlockIo.Reset = BlockIo->Reset; - mCoreBlockIo.ReadBlocks = BlockIo->ReadBlocks; - mCoreBlockIo.WriteBlocks = BlockIo->WriteBlocks; - mCoreBlockIo.FlushBlocks = BlockIo->FlushBlocks; - BlockIo->Reset = Ring3BlockIoReset; BlockIo->ReadBlocks = Ring3BlockIoRead; BlockIo->WriteBlocks = Ring3BlockIoWrite; @@ -427,9 +422,6 @@ Ring3OpenProtocol ( DiskIo = (EFI_DISK_IO_PROTOCOL *)*Interface; - mCoreDiskIo.ReadDisk = DiskIo->ReadDisk; - mCoreDiskIo.WriteDisk = DiskIo->WriteDisk; - DiskIo->ReadDisk = Ring3DiskIoRead; DiskIo->WriteDisk = Ring3DiskIoWrite; diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index c72242c3a1..c7566b46d6 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -8,6 +8,9 @@ #include "DxeMain.h" #include "SupportedProtocols.h" +EFI_DISK_IO_PROTOCOL *mCoreDiskIoProtocol; +EFI_BLOCK_IO_PROTOCOL *mCoreBlockIoProtocol; + EFI_STATUS EFIAPI CallInstallMultipleProtocolInterfaces ( @@ -119,9 +122,9 @@ CallBootService ( VOID *Interface; EFI_GUID *CoreProtocol; UINT32 MemoryCoreSize; - EFI_HANDLE Argument4; - EFI_HANDLE Argument5; - UINT32 Argument6; + UINTN Argument4; + UINTN Argument5; + UINTN Argument6; UINT32 Index; VOID **UserArgList; VOID *CoreArgList[MAX_LIST]; @@ -160,7 +163,7 @@ CallBootService ( if (Interface == NULL) { EnableSMAP (); return EFI_OUT_OF_RESOURCES; - } + } } *(VOID **)CoreRbp->Argument3 = Interface; @@ -184,22 +187,28 @@ CallBootService ( return Status; } - Argument4 = (EFI_HANDLE)UserRsp->Arguments[4]; - Argument5 = (EFI_HANDLE)UserRsp->Arguments[5]; - Argument6 = (UINT32)UserRsp->Arguments[6]; + Argument4 = UserRsp->Arguments[4]; + Argument5 = UserRsp->Arguments[5]; + Argument6 = UserRsp->Arguments[6]; EnableSMAP (); Status = gBS->OpenProtocol ( (EFI_HANDLE)CoreRbp->Argument1, CoreProtocol, &Interface, - Argument4, - Argument5, - Argument6 + (EFI_HANDLE)Argument4, + (EFI_HANDLE)Argument5, + (UINT32)Argument6 ); DisableSMAP (); if (Interface != NULL) { + if (CompareGuid (CoreProtocol, &gEfiDiskIoProtocolGuid)) { + mCoreDiskIoProtocol = (EFI_DISK_IO_PROTOCOL *)Interface; + } else if (CompareGuid (CoreProtocol, &gEfiBlockIoProtocolGuid)) { + mCoreBlockIoProtocol = (EFI_BLOCK_IO_PROTOCOL *)Interface; + } + Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); if (Interface == NULL) { EnableSMAP (); @@ -287,6 +296,152 @@ CallBootService ( ); EnableSMAP (); + return Status; + + case SysCallBlockIoReset: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // Argument 2: BOOLEAN ExtendedVerification + // + return mCoreBlockIoProtocol->Reset ( + mCoreBlockIoProtocol, + (BOOLEAN)CoreRbp->Argument2 + ); + + case SysCallBlockIoRead: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: EFI_LBA Lba + // Argument 4: UINTN BufferSize + // Argument 5: VOID *Buffer + // + DisableSMAP (); + Argument4 = UserRsp->Arguments[4]; + EnableSMAP (); + + Argument5 = (UINTN)AllocatePool (Argument4); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = mCoreBlockIoProtocol->ReadBlocks ( + mCoreBlockIoProtocol, + (UINT32)CoreRbp->Argument2, + (EFI_LBA)CoreRbp->Argument3, + Argument4, + (VOID *)Argument5 + ); + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallBlockIoWrite: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: EFI_LBA Lba + // Argument 4: UINTN BufferSize + // Argument 5: VOID *Buffer + // + DisableSMAP (); + Argument4 = UserRsp->Arguments[4]; + EnableSMAP (); + + Argument5 = (UINTN)AllocatePool (Argument4); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = mCoreBlockIoProtocol->WriteBlocks ( + mCoreBlockIoProtocol, + (UINT32)CoreRbp->Argument2, + (EFI_LBA)CoreRbp->Argument3, + Argument4, + (VOID *)Argument5 + ); + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallBlockIoFlush: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // + return mCoreBlockIoProtocol->FlushBlocks ( + mCoreBlockIoProtocol + ); + + case SysCallDiskIoRead: + // + // Argument 1: EFI_DISK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: UINT64 Offset + // Argument 4: UINTN BufferSize + // Argument 5: VOID *Buffer + // + DisableSMAP (); + Argument4 = UserRsp->Arguments[4]; + EnableSMAP (); + + Argument5 = (UINTN)AllocatePool (Argument4); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = mCoreDiskIoProtocol->ReadDisk ( + mCoreDiskIoProtocol, + (UINT32)CoreRbp->Argument2, + (UINT64)CoreRbp->Argument3, + Argument4, + (VOID *)Argument5 + ); + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallDiskIoWrite: + // + // Argument 1: EFI_DISK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: UINT64 Offset + // Argument 4: UINTN BufferSize + // Argument 5: VOID *Buffer + // + DisableSMAP (); + Argument4 = UserRsp->Arguments[4]; + EnableSMAP (); + + Argument5 = (UINTN)AllocatePool (Argument4); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = mCoreDiskIoProtocol->WriteDisk ( + mCoreDiskIoProtocol, + (UINT32)CoreRbp->Argument2, + (UINT64)CoreRbp->Argument3, + Argument4, + (VOID *)Argument5 + ); + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + return Status; default: DEBUG ((DEBUG_ERROR, "Ring0: Unknown syscall type.\n")); diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 42b57b356e..b836a8f77c 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2032,6 +2032,15 @@ typedef enum { SysCallInstallMultipleProtocolInterfaces, SysCallAllocatePool, SysCallFreePool, + // + // Protocols + // + SysCallBlockIoReset, + SysCallBlockIoRead, + SysCallBlockIoWrite, + SysCallBlockIoFlush, + SysCallDiskIoRead, + SysCallDiskIoWrite, SysCallMax } SYS_CALL_TYPE; From f7d849e33bc601e0cdcb813eae24757a5bf0a8ef Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 22 Feb 2024 11:23:22 +0300 Subject: [PATCH 157/341] Ring3: Small fix. --- .../Core/Dxe/SysCall/SupportedProtocols.c | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index bf7f7b6200..0d93111f01 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -44,22 +44,26 @@ GoToRing3 ( VA_END (Marker); EnableSMAP (); - // - // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() - // - SetUefiImageMemoryAttributes ( - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); + if (Number == 2) { + // + // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() + // + SetUefiImageMemoryAttributes ( + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + } Status = CallRing3 (Input); - SetUefiImageMemoryAttributes ( - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP - ); + if (Number == 2) { + SetUefiImageMemoryAttributes ( + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP + ); + } return Status; } From d3eca9dca4dd352e80da3e922ada64889606a272 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 22 Feb 2024 12:42:53 +0300 Subject: [PATCH 158/341] Ring3: Added SysCallCloseProtocol. --- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 8 +++++- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 28 ++++++++++++++++++- MdePkg/Include/Uefi/UefiSpec.h | 1 + 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index d6950485f5..22acc09f50 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -441,7 +441,13 @@ Ring3CloseProtocol ( IN EFI_HANDLE ControllerHandle ) { - return EFI_UNSUPPORTED; + return SysCall ( + SysCallCloseProtocol, + UserHandle, + Protocol, + AgentHandle, + ControllerHandle + ); } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index c7566b46d6..b27abfcd92 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -288,7 +288,7 @@ CallBootService ( case SysCallFreePool: // - // Argument 1: IN VOID *Buffer + // Argument 1: VOID *Buffer // DisableSMAP (); Status = gBS->FreePool ( @@ -298,6 +298,32 @@ CallBootService ( return Status; + case SysCallCloseProtocol: + // + // Argument 1: EFI_HANDLE CoreUserHandle + // Argument 2: EFI_GUID *Protocol + // Argument 3: EFI_HANDLE CoreAgentHandle + // Argument 4: EFI_HANDLE CoreControllerHandle + // + DisableSMAP (); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + return Status; + } + + Argument4 = UserRsp->Arguments[4]; + EnableSMAP (); + + Status = gBS->CloseProtocol ( + (EFI_HANDLE)CoreRbp->Argument1, + CoreProtocol, + (EFI_HANDLE)CoreRbp->Argument3, + (EFI_HANDLE)Argument4 + ); + + return Status; + case SysCallBlockIoReset: // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index b836a8f77c..23b6b7d816 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2032,6 +2032,7 @@ typedef enum { SysCallInstallMultipleProtocolInterfaces, SysCallAllocatePool, SysCallFreePool, + SysCallCloseProtocol, // // Protocols // From d015d682f9ff3e00793d71431c0bc677a3ba0615 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 23 Feb 2024 12:57:09 +0300 Subject: [PATCH 159/341] Ring3: Added SysCallHandleProtocol and SIMPLE_FILE_SYSTEM_PROTOCOL wrapper. --- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf | 1 + .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 24 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 57 ++++- .../Core/Dxe/SysCall/SupportedProtocols.c | 231 +++++++++++++++++- .../Core/Dxe/SysCall/SupportedProtocols.h | 11 +- MdePkg/Include/Uefi/UefiSpec.h | 1 + 6 files changed, 319 insertions(+), 6 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index cfcb4d43ed..c2b0c004de 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -44,6 +44,7 @@ gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES [Depex] TRUE diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 22acc09f50..5e26a67fea 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -208,12 +208,31 @@ Ring3UninstallProtocolInterface ( EFI_STATUS EFIAPI Ring3HandleProtocol ( - IN EFI_HANDLE UserHandle, + IN EFI_HANDLE CoreUserHandle, IN EFI_GUID *Protocol, OUT VOID **Interface ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + + Status = SysCall ( + SysCallHandleProtocol, + CoreUserHandle, + Protocol, + Interface + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to get handle of protocol %g - %r\n", Protocol, Status)); + return Status; + } + + if (CompareGuid (Protocol, &gEfiDevicePathProtocolGuid)) { + Status = EFI_SUCCESS; + } else { + Status = EFI_UNSUPPORTED; + } + + return Status; } EFI_STATUS @@ -397,7 +416,6 @@ Ring3OpenProtocol ( Attributes ); if (EFI_ERROR (Status)) { - // DEBUG ((DEBUG_ERROR, "Ring3: Failed to open protocol %g - %r\n", Protocol, Status)); return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index b27abfcd92..c081e1c0e1 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -61,6 +61,16 @@ FindGuid ( *Core = &gEfiComponentNameProtocolGuid; *CoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiDevicePathProtocolGuid)) { + + *Core = &gEfiDevicePathProtocolGuid; + *CoreSize = sizeof (EFI_DEVICE_PATH_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiSimpleFileSystemProtocolGuid)) { + + *Core = &gEfiSimpleFileSystemProtocolGuid; + *CoreSize = sizeof (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL); + } else { DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol.\n")); return EFI_NOT_FOUND; @@ -130,7 +140,8 @@ CallBootService ( VOID *CoreArgList[MAX_LIST]; EFI_HANDLE CoreHandle; - EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; + EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem; // // TODO: Check User variables. // @@ -258,6 +269,16 @@ CallBootService ( CoreDriverBinding->Supported = CoreDriverBindingSupported; CoreDriverBinding->Start = CoreDriverBindingStart; CoreDriverBinding->Stop = CoreDriverBindingStop; + } else if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiSimpleFileSystemProtocolGuid)) { + CoreSimpleFileSystem = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)CoreArgList[Index + 1]; + + mRing3SimpleFileSystemProtocol.OpenVolume = CoreSimpleFileSystem->OpenVolume; + + CoreSimpleFileSystem->OpenVolume = CoreOpenVolume; + + DisableSMAP (); + mRing3SimpleFileSystemPointer = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)UserArgList[Index + 1]; + EnableSMAP (); } } @@ -324,6 +345,40 @@ CallBootService ( return Status; + case SysCallHandleProtocol: + // + // Argument 1: EFI_HANDLE CoreUserHandle + // Argument 2: EFI_GUID *Protocol + // Argument 3: VOID **Interface + // + DisableSMAP (); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + EnableSMAP (); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->HandleProtocol ( + (EFI_HANDLE)CoreRbp->Argument1, + CoreProtocol, + &Interface + ); + + DisableSMAP (); + if (Interface != NULL) { + + Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); + if (Interface == NULL) { + EnableSMAP (); + return EFI_OUT_OF_RESOURCES; + } + } + + *(VOID **)CoreRbp->Argument3 = Interface; + EnableSMAP (); + + return Status; + case SysCallBlockIoReset: // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 0d93111f01..2335423bf9 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -7,7 +7,12 @@ #include "DxeMain.h" -EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; +EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; +EFI_FILE_PROTOCOL mRing3FileProtocol; + +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; +EFI_FILE_PROTOCOL *mRing3FilePointer; EFI_STATUS EFIAPI @@ -180,3 +185,227 @@ CoreDriverBindingStop ( return Status; } + +EFI_STATUS +EFIAPI +CoreFileOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreFileClose ( + IN EFI_FILE_PROTOCOL *This + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreFileDelete ( + IN EFI_FILE_PROTOCOL *This + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreFileRead ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreFileWrite ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreFileSetPosition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreFileGetPosition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreFileGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreFileSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreFileFlush ( + IN EFI_FILE_PROTOCOL *This + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreFileOpenEx ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes, + IN OUT EFI_FILE_IO_TOKEN *Token + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreFileReadEx ( + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreFileWriteEx ( + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreFileFlushEx ( + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ) +{ + EFI_STATUS Status; + EFI_FILE_PROTOCOL **Ring3Root; + + DisableSMAP (); + Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (EFI_FILE_PROTOCOL *), (VOID **)&Ring3Root); + EnableSMAP (); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + + Status = GoToRing3 ( + 2, + (VOID *)mRing3SimpleFileSystemProtocol.OpenVolume, + mRing3SimpleFileSystemPointer, + Ring3Root + ); + if (EFI_ERROR (Status)) { + *Root = NULL; + DisableSMAP (); + FreePool (Ring3Root); + EnableSMAP (); + return Status; + } + + *Root = AllocatePool (sizeof (EFI_FILE_PROTOCOL)); + + DisableSMAP (); + mRing3FileProtocol.Revision = (*Ring3Root)->Revision; + mRing3FileProtocol.Open = (*Ring3Root)->Open; + mRing3FileProtocol.Close = (*Ring3Root)->Close; + mRing3FileProtocol.Delete = (*Ring3Root)->Delete; + mRing3FileProtocol.Read = (*Ring3Root)->Read; + mRing3FileProtocol.Write = (*Ring3Root)->Write; + mRing3FileProtocol.GetPosition = (*Ring3Root)->GetPosition; + mRing3FileProtocol.SetPosition = (*Ring3Root)->SetPosition; + mRing3FileProtocol.GetInfo = (*Ring3Root)->GetInfo; + mRing3FileProtocol.SetInfo = (*Ring3Root)->SetInfo; + mRing3FileProtocol.Flush = (*Ring3Root)->Flush; + mRing3FileProtocol.OpenEx = (*Ring3Root)->OpenEx; + mRing3FileProtocol.ReadEx = (*Ring3Root)->ReadEx; + mRing3FileProtocol.WriteEx = (*Ring3Root)->WriteEx; + mRing3FileProtocol.FlushEx = (*Ring3Root)->FlushEx; + + mRing3FilePointer = *Ring3Root; + + FreePool (Ring3Root); + EnableSMAP (); + + (*Root)->Revision = mRing3FileProtocol.Revision; + (*Root)->Open = CoreFileOpen; + (*Root)->Close = CoreFileClose; + (*Root)->Delete = CoreFileDelete; + (*Root)->Read = CoreFileRead; + (*Root)->Write = CoreFileWrite; + (*Root)->GetPosition = CoreFileGetPosition; + (*Root)->SetPosition = CoreFileSetPosition; + (*Root)->GetInfo = CoreFileGetInfo; + (*Root)->SetInfo = CoreFileSetInfo; + (*Root)->Flush = CoreFileFlush; + (*Root)->OpenEx = CoreFileOpenEx; + (*Root)->ReadEx = CoreFileReadEx; + (*Root)->WriteEx = CoreFileWriteEx; + (*Root)->FlushEx = CoreFileFlushEx; + + return Status; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h index 6862030896..200c51d242 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -10,7 +10,9 @@ #include #include -extern EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; +extern EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; +extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; +extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; EFI_STATUS EFIAPI @@ -36,3 +38,10 @@ CoreDriverBindingStop ( IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL ); + +EFI_STATUS +EFIAPI +CoreOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ); diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 23b6b7d816..b8b7790e6b 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2033,6 +2033,7 @@ typedef enum { SysCallAllocatePool, SysCallFreePool, SysCallCloseProtocol, + SysCallHandleProtocol, // // Protocols // From ffaebdb5e3f51b1da5906019a683e3daa3983d63 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 23 Feb 2024 17:29:17 +0300 Subject: [PATCH 160/341] Ring3: Added EFI_FILE_PROTOCOL wrappers. --- .../Core/Dxe/SysCall/SupportedProtocols.c | 336 ++++++++++++++++-- 1 file changed, 297 insertions(+), 39 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 2335423bf9..9d6837e729 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -12,7 +12,11 @@ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; EFI_FILE_PROTOCOL mRing3FileProtocol; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; -EFI_FILE_PROTOCOL *mRing3FilePointer; + +typedef struct { + EFI_FILE_PROTOCOL Protocol; + EFI_FILE_PROTOCOL *Ring3File; +} RING3_EFI_FILE_PROTOCOL; EFI_STATUS EFIAPI @@ -186,28 +190,30 @@ CoreDriverBindingStop ( return Status; } -EFI_STATUS -EFIAPI -CoreFileOpen ( - IN EFI_FILE_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **NewHandle, - IN CHAR16 *FileName, - IN UINT64 OpenMode, - IN UINT64 Attributes - ) -{ - return EFI_UNSUPPORTED; -} - +STATIC EFI_STATUS EFIAPI CoreFileClose ( IN EFI_FILE_PROTOCOL *This ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + + File = (RING3_EFI_FILE_PROTOCOL *)This; + + Status = GoToRing3 ( + 1, + (VOID *)mRing3FileProtocol.Close, + File->Ring3File + ); + + FreePool (This); + + return Status; } +STATIC EFI_STATUS EFIAPI CoreFileDelete ( @@ -217,6 +223,7 @@ CoreFileDelete ( return EFI_UNSUPPORTED; } +STATIC EFI_STATUS EFIAPI CoreFileRead ( @@ -225,9 +232,56 @@ CoreFileRead ( OUT VOID *Buffer ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + UINTN *Ring3BufferSize; + VOID *Ring3Buffer; + + File = (RING3_EFI_FILE_PROTOCOL *)This; + DEBUG ((DEBUG_INFO, "Ring3 Read: check 1\n")); + + DisableSMAP (); + Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (UINTN *), (VOID **)&Ring3BufferSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + return Status; + } + + Status = CoreAllocatePool (EfiRing3MemoryType, *BufferSize, (VOID **)&Ring3Buffer); + if (EFI_ERROR (Status)) { + FreePool (Ring3BufferSize); + EnableSMAP (); + return Status; + } + EnableSMAP (); + DEBUG ((DEBUG_INFO, "Ring3 Read: check 2\n")); + + Status = GoToRing3 ( + 3, + (VOID *)mRing3FileProtocol.Read, + File->Ring3File, + Ring3BufferSize, + Ring3Buffer + ); + DEBUG ((DEBUG_INFO, "Ring3 Read: check 3\n")); + + DisableSMAP (); + if ((!EFI_ERROR (Status)) && (Ring3Buffer != NULL) && (Buffer != NULL)) { + CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); + FreePool (Ring3Buffer); + } + + *BufferSize = *Ring3BufferSize; + + DEBUG ((DEBUG_INFO, "Ring3 Read: check 3.5\n")); + FreePool (Ring3BufferSize); + EnableSMAP (); + DEBUG ((DEBUG_INFO, "Ring3 Read: check 4\n")); + + return Status; } +STATIC EFI_STATUS EFIAPI CoreFileWrite ( @@ -239,6 +293,7 @@ CoreFileWrite ( return EFI_UNSUPPORTED; } +STATIC EFI_STATUS EFIAPI CoreFileSetPosition ( @@ -246,9 +301,19 @@ CoreFileSetPosition ( IN UINT64 Position ) { - return EFI_UNSUPPORTED; + RING3_EFI_FILE_PROTOCOL *File; + + File = (RING3_EFI_FILE_PROTOCOL *)This; + + return GoToRing3 ( + 2, + (VOID *)mRing3FileProtocol.SetPosition, + File->Ring3File, + Position + ); } +STATIC EFI_STATUS EFIAPI CoreFileGetPosition ( @@ -256,9 +321,36 @@ CoreFileGetPosition ( OUT UINT64 *Position ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + UINT64 *Ring3Position; + + File = (RING3_EFI_FILE_PROTOCOL *)This; + + DisableSMAP (); + Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (UINT64), (VOID **)&Ring3Position); + EnableSMAP (); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = GoToRing3 ( + 2, + (VOID *)mRing3FileProtocol.GetPosition, + File->Ring3File, + Ring3Position + ); + + DisableSMAP (); + *Position = *Ring3Position; + + FreePool (Ring3Position); + EnableSMAP (); + + return Status; } +STATIC EFI_STATUS EFIAPI CoreFileGetInfo ( @@ -268,9 +360,62 @@ CoreFileGetInfo ( OUT VOID *Buffer ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + EFI_GUID *Ring3InformationType; + UINTN *Ring3BufferSize; + VOID *Ring3Buffer; + + File = (RING3_EFI_FILE_PROTOCOL *)This; + + DisableSMAP (); + Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (UINTN *), (VOID **)&Ring3BufferSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + return Status; + } + + Status = CoreAllocatePool (EfiRing3MemoryType, *BufferSize, (VOID **)&Ring3Buffer); + if (EFI_ERROR (Status)) { + FreePool (Ring3BufferSize); + EnableSMAP (); + return Status; + } + + Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (EFI_GUID), (VOID **)&Ring3InformationType); + if (EFI_ERROR (Status)) { + FreePool (Ring3BufferSize); + FreePool (Ring3Buffer); + EnableSMAP (); + return Status; + } + + CopyGuid (Ring3InformationType, InformationType); + EnableSMAP (); + + Status = GoToRing3 ( + 4, + (VOID *)mRing3FileProtocol.GetInfo, + File->Ring3File, + Ring3InformationType, + Ring3BufferSize, + Ring3Buffer + ); + + DisableSMAP (); + *BufferSize = *Ring3BufferSize; + + CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); + + FreePool (Ring3BufferSize); + FreePool (Ring3Buffer); + FreePool (Ring3InformationType); + EnableSMAP (); + + return Status; } +STATIC EFI_STATUS EFIAPI CoreFileSetInfo ( @@ -283,6 +428,7 @@ CoreFileSetInfo ( return EFI_UNSUPPORTED; } +STATIC EFI_STATUS EFIAPI CoreFileFlush ( @@ -292,6 +438,7 @@ CoreFileFlush ( return EFI_UNSUPPORTED; } +STATIC EFI_STATUS EFIAPI CoreFileOpenEx ( @@ -306,6 +453,7 @@ CoreFileOpenEx ( return EFI_UNSUPPORTED; } +STATIC EFI_STATUS EFIAPI CoreFileReadEx ( @@ -316,6 +464,7 @@ CoreFileReadEx ( return EFI_UNSUPPORTED; } +STATIC EFI_STATUS EFIAPI CoreFileWriteEx ( @@ -326,6 +475,7 @@ CoreFileWriteEx ( return EFI_UNSUPPORTED; } +STATIC EFI_STATUS EFIAPI CoreFileFlushEx ( @@ -336,6 +486,104 @@ CoreFileFlushEx ( return EFI_UNSUPPORTED; } +STATIC +EFI_STATUS +EFIAPI +CoreFileOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + RING3_EFI_FILE_PROTOCOL *NewFile; + EFI_FILE_PROTOCOL **Ring3NewHandle; + CHAR16 *Ring3FileName; + + File = (RING3_EFI_FILE_PROTOCOL *)This; + + DisableSMAP (); + Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (EFI_FILE_PROTOCOL *), (VOID **)&Ring3NewHandle); + if (EFI_ERROR (Status)) { + EnableSMAP (); + return Status; + } + + Status = CoreAllocatePool (EfiRing3MemoryType, StrSize (FileName), (VOID **)&Ring3FileName); + if (EFI_ERROR (Status)) { + FreePool (Ring3NewHandle); + EnableSMAP (); + return Status; + } + + Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName); + if (EFI_ERROR (Status)) { + FreePool (Ring3NewHandle); + FreePool (Ring3FileName); + EnableSMAP (); + return Status; + } + EnableSMAP (); + + Status = GoToRing3 ( + 5, + (VOID *)mRing3FileProtocol.Open, + File->Ring3File, + Ring3NewHandle, + Ring3FileName, + OpenMode, + Attributes + ); + if (EFI_ERROR (Status)) { + *NewHandle = NULL; + DisableSMAP (); + FreePool (Ring3NewHandle); + FreePool (Ring3FileName); + EnableSMAP (); + return Status; + } + + NewFile = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); + if (NewFile == NULL) { + *NewHandle = NULL; + DisableSMAP (); + FreePool (Ring3NewHandle); + FreePool (Ring3FileName); + EnableSMAP (); + return EFI_OUT_OF_RESOURCES; + } + + NewFile->Protocol.Revision = mRing3FileProtocol.Revision; + NewFile->Protocol.Open = CoreFileOpen; + NewFile->Protocol.Close = CoreFileClose; + NewFile->Protocol.Delete = CoreFileDelete; + NewFile->Protocol.Read = CoreFileRead; + NewFile->Protocol.Write = CoreFileWrite; + NewFile->Protocol.GetPosition = CoreFileGetPosition; + NewFile->Protocol.SetPosition = CoreFileSetPosition; + NewFile->Protocol.GetInfo = CoreFileGetInfo; + NewFile->Protocol.SetInfo = CoreFileSetInfo; + NewFile->Protocol.Flush = CoreFileFlush; + NewFile->Protocol.OpenEx = CoreFileOpenEx; + NewFile->Protocol.ReadEx = CoreFileReadEx; + NewFile->Protocol.WriteEx = CoreFileWriteEx; + NewFile->Protocol.FlushEx = CoreFileFlushEx; + + DisableSMAP (); + NewFile->Ring3File = *Ring3NewHandle; + + FreePool (Ring3NewHandle); + FreePool (Ring3FileName); + EnableSMAP (); + + *NewHandle = (EFI_FILE_PROTOCOL *)NewFile; + + return Status; +} + EFI_STATUS EFIAPI CoreOpenVolume ( @@ -343,14 +591,15 @@ CoreOpenVolume ( OUT EFI_FILE_PROTOCOL **Root ) { - EFI_STATUS Status; - EFI_FILE_PROTOCOL **Ring3Root; + EFI_STATUS Status; + EFI_FILE_PROTOCOL **Ring3Root; + RING3_EFI_FILE_PROTOCOL *File; DisableSMAP (); Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (EFI_FILE_PROTOCOL *), (VOID **)&Ring3Root); EnableSMAP (); if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; + return Status; } Status = GoToRing3 ( @@ -367,7 +616,14 @@ CoreOpenVolume ( return Status; } - *Root = AllocatePool (sizeof (EFI_FILE_PROTOCOL)); + File = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); + if (File == NULL) { + *Root = NULL; + DisableSMAP (); + FreePool (Ring3Root); + EnableSMAP (); + return EFI_OUT_OF_RESOURCES; + } DisableSMAP (); mRing3FileProtocol.Revision = (*Ring3Root)->Revision; @@ -386,26 +642,28 @@ CoreOpenVolume ( mRing3FileProtocol.WriteEx = (*Ring3Root)->WriteEx; mRing3FileProtocol.FlushEx = (*Ring3Root)->FlushEx; - mRing3FilePointer = *Ring3Root; + File->Ring3File = *Ring3Root; FreePool (Ring3Root); EnableSMAP (); - (*Root)->Revision = mRing3FileProtocol.Revision; - (*Root)->Open = CoreFileOpen; - (*Root)->Close = CoreFileClose; - (*Root)->Delete = CoreFileDelete; - (*Root)->Read = CoreFileRead; - (*Root)->Write = CoreFileWrite; - (*Root)->GetPosition = CoreFileGetPosition; - (*Root)->SetPosition = CoreFileSetPosition; - (*Root)->GetInfo = CoreFileGetInfo; - (*Root)->SetInfo = CoreFileSetInfo; - (*Root)->Flush = CoreFileFlush; - (*Root)->OpenEx = CoreFileOpenEx; - (*Root)->ReadEx = CoreFileReadEx; - (*Root)->WriteEx = CoreFileWriteEx; - (*Root)->FlushEx = CoreFileFlushEx; + File->Protocol.Revision = mRing3FileProtocol.Revision; + File->Protocol.Open = CoreFileOpen; + File->Protocol.Close = CoreFileClose; + File->Protocol.Delete = CoreFileDelete; + File->Protocol.Read = CoreFileRead; + File->Protocol.Write = CoreFileWrite; + File->Protocol.GetPosition = CoreFileGetPosition; + File->Protocol.SetPosition = CoreFileSetPosition; + File->Protocol.GetInfo = CoreFileGetInfo; + File->Protocol.SetInfo = CoreFileSetInfo; + File->Protocol.Flush = CoreFileFlush; + File->Protocol.OpenEx = CoreFileOpenEx; + File->Protocol.ReadEx = CoreFileReadEx; + File->Protocol.WriteEx = CoreFileWriteEx; + File->Protocol.FlushEx = CoreFileFlushEx; + + *Root = (EFI_FILE_PROTOCOL *)File; return Status; } From caeea88ae9d787c92e7f60dcd95368a894f04f39 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 26 Feb 2024 11:37:39 +0300 Subject: [PATCH 161/341] Ring3: Fixed missing Ring3Call result. --- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 15 ++++++++------- .../Core/Dxe/SysCall/X64/CoreBootServices.nasm | 1 + 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index ff5414ec10..db933998ee 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -122,6 +122,7 @@ Ring3Call ( IN RING3_CALL_DATA *Data ) { + EFI_STATUS Status; FUNCTION_0 Function0; FUNCTION_1 Function1; FUNCTION_2 Function2; @@ -132,33 +133,33 @@ Ring3Call ( switch (Data->NumberOfArguments) { case 0: Function0 = (FUNCTION_0)Data->EntryPoint; - Function0 (); + Status = Function0 (); break; case 1: Function1 = (FUNCTION_1)Data->EntryPoint; - Function1 (Data->Arguments[0]); + Status = Function1 (Data->Arguments[0]); break; case 2: Function2 = (FUNCTION_2)Data->EntryPoint; - Function2 (Data->Arguments[0], Data->Arguments[1]); + Status = Function2 (Data->Arguments[0], Data->Arguments[1]); break; case 3: Function3 = (FUNCTION_3)Data->EntryPoint; - Function3 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2]); + Status = Function3 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2]); break; case 4: Function4 = (FUNCTION_4)Data->EntryPoint; - Function4 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3]); + Status = Function4 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3]); break; case 5: Function5 = (FUNCTION_5)Data->EntryPoint; - Function5 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4]); + Status = Function5 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4]); break; default: break; } - SysCall (SysCallReturnToCore); + SysCall (SysCallReturnToCore, Status); } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 0987cf9320..79ba899087 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -223,6 +223,7 @@ o64 sysret coreReturnAddress: mov rsp, [ASM_PFX(CoreRsp)] mov rbp, [ASM_PFX(CoreRbp)] + mov rax, rdx ret SECTION .data From e129d198445df0ad47a443da65fd157b6523e8a5 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 26 Feb 2024 11:56:44 +0300 Subject: [PATCH 162/341] Ring3: Added sanity checks. --- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 1 + .../Core/Dxe/SysCall/SupportedProtocols.c | 147 ++++++++++++------ 2 files changed, 97 insertions(+), 51 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index db933998ee..ec2405c08e 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -156,6 +156,7 @@ Ring3Call ( Status = Function5 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4]); break; default: + Status = EFI_UNSUPPORTED; break; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 9d6837e729..edca2fd49f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -237,24 +237,32 @@ CoreFileRead ( UINTN *Ring3BufferSize; VOID *Ring3Buffer; - File = (RING3_EFI_FILE_PROTOCOL *)This; - DEBUG ((DEBUG_INFO, "Ring3 Read: check 1\n")); + File = (RING3_EFI_FILE_PROTOCOL *)This; + Ring3Buffer = NULL; + Ring3BufferSize = NULL; DisableSMAP (); - Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (UINTN *), (VOID **)&Ring3BufferSize); - if (EFI_ERROR (Status)) { - EnableSMAP (); - return Status; + if (BufferSize != NULL) { + Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (UINTN *), (VOID **)&Ring3BufferSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + return Status; + } + + *Ring3BufferSize = *BufferSize; } - Status = CoreAllocatePool (EfiRing3MemoryType, *BufferSize, (VOID **)&Ring3Buffer); - if (EFI_ERROR (Status)) { - FreePool (Ring3BufferSize); - EnableSMAP (); - return Status; + if (Buffer != NULL) { + Status = CoreAllocatePool (EfiRing3MemoryType, *BufferSize, (VOID **)&Ring3Buffer); + if (EFI_ERROR (Status)) { + if (Ring3BufferSize != NULL) { + FreePool (Ring3BufferSize); + } + EnableSMAP (); + return Status; + } } EnableSMAP (); - DEBUG ((DEBUG_INFO, "Ring3 Read: check 2\n")); Status = GoToRing3 ( 3, @@ -263,20 +271,22 @@ CoreFileRead ( Ring3BufferSize, Ring3Buffer ); - DEBUG ((DEBUG_INFO, "Ring3 Read: check 3\n")); DisableSMAP (); - if ((!EFI_ERROR (Status)) && (Ring3Buffer != NULL) && (Buffer != NULL)) { + if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); + } + + if (Ring3Buffer != NULL) { FreePool (Ring3Buffer); } - *BufferSize = *Ring3BufferSize; + if (Ring3BufferSize != NULL) { + *BufferSize = *Ring3BufferSize; - DEBUG ((DEBUG_INFO, "Ring3 Read: check 3.5\n")); - FreePool (Ring3BufferSize); + FreePool (Ring3BufferSize); + } EnableSMAP (); - DEBUG ((DEBUG_INFO, "Ring3 Read: check 4\n")); return Status; } @@ -325,13 +335,19 @@ CoreFileGetPosition ( RING3_EFI_FILE_PROTOCOL *File; UINT64 *Ring3Position; - File = (RING3_EFI_FILE_PROTOCOL *)This; + File = (RING3_EFI_FILE_PROTOCOL *)This; + Ring3Position = NULL; - DisableSMAP (); - Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (UINT64), (VOID **)&Ring3Position); - EnableSMAP (); - if (EFI_ERROR (Status)) { - return Status; + if (Position != NULL) { + DisableSMAP (); + Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (UINT64), (VOID **)&Ring3Position); + if (EFI_ERROR (Status)) { + EnableSMAP (); + return Status; + } + + *Ring3Position = *Position; + EnableSMAP (); } Status = GoToRing3 ( @@ -341,11 +357,13 @@ CoreFileGetPosition ( Ring3Position ); - DisableSMAP (); - *Position = *Ring3Position; + if (Ring3Position != NULL) { + DisableSMAP (); + *Position = *Ring3Position; - FreePool (Ring3Position); - EnableSMAP (); + FreePool (Ring3Position); + EnableSMAP (); + } return Status; } @@ -366,31 +384,48 @@ CoreFileGetInfo ( UINTN *Ring3BufferSize; VOID *Ring3Buffer; - File = (RING3_EFI_FILE_PROTOCOL *)This; + File = (RING3_EFI_FILE_PROTOCOL *)This; + Ring3Buffer = NULL; + Ring3BufferSize = NULL; + Ring3InformationType = NULL; DisableSMAP (); - Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (UINTN *), (VOID **)&Ring3BufferSize); - if (EFI_ERROR (Status)) { - EnableSMAP (); - return Status; + if (BufferSize != NULL) { + Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (UINTN *), (VOID **)&Ring3BufferSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + return Status; + } + + *Ring3BufferSize = *BufferSize; } - Status = CoreAllocatePool (EfiRing3MemoryType, *BufferSize, (VOID **)&Ring3Buffer); - if (EFI_ERROR (Status)) { - FreePool (Ring3BufferSize); - EnableSMAP (); - return Status; + if (Buffer != NULL) { + Status = CoreAllocatePool (EfiRing3MemoryType, *BufferSize, (VOID **)&Ring3Buffer); + if (EFI_ERROR (Status)) { + if (Ring3BufferSize != NULL) { + FreePool (Ring3BufferSize); + } + EnableSMAP (); + return Status; + } } - Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (EFI_GUID), (VOID **)&Ring3InformationType); - if (EFI_ERROR (Status)) { - FreePool (Ring3BufferSize); - FreePool (Ring3Buffer); - EnableSMAP (); - return Status; + if (InformationType != NULL) { + Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (EFI_GUID), (VOID **)&Ring3InformationType); + if (EFI_ERROR (Status)) { + if (Ring3BufferSize != NULL) { + FreePool (Ring3BufferSize); + } + if (Ring3Buffer != NULL) { + FreePool (Ring3Buffer); + } + EnableSMAP (); + return Status; + } + + CopyGuid (Ring3InformationType, InformationType); } - - CopyGuid (Ring3InformationType, InformationType); EnableSMAP (); Status = GoToRing3 ( @@ -403,13 +438,23 @@ CoreFileGetInfo ( ); DisableSMAP (); - *BufferSize = *Ring3BufferSize; + if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { + CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); + } + + if (Ring3BufferSize != NULL) { + *BufferSize = *Ring3BufferSize; - CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); + FreePool (Ring3BufferSize); + } + + if (Ring3Buffer != NULL) { + FreePool (Ring3Buffer); + } - FreePool (Ring3BufferSize); - FreePool (Ring3Buffer); - FreePool (Ring3InformationType); + if (Ring3InformationType != NULL) { + FreePool (Ring3InformationType); + } EnableSMAP (); return Status; From 24ee35ca7a38b6fe2ac81d5fe239bb03bc01d00f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 27 Feb 2024 12:56:26 +0300 Subject: [PATCH 163/341] MdeModulePkg: Placed Core Pool functions into MemoryPoolLib. --- MdeModulePkg/Core/Dxe/DxeMain.h | 84 +---- MdeModulePkg/Core/Dxe/DxeMain.inf | 2 +- MdeModulePkg/Core/Dxe/Mem/Imem.h | 35 -- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 3 - MdeModulePkg/Include/Library/MemoryPoolLib.h | 146 ++++++++ .../Library/MemoryPoolLib/InternalPool.c | 9 + .../Library/MemoryPoolLib/InternalPool.h | 317 ++++++++++++++++++ .../Library/MemoryPoolLib/MemoryPoolLib.inf | 39 +++ .../Dxe/Mem => Library/MemoryPoolLib}/Pool.c | 12 +- MdeModulePkg/MdeModulePkg.dsc | 2 + 10 files changed, 524 insertions(+), 125 deletions(-) create mode 100644 MdeModulePkg/Include/Library/MemoryPoolLib.h create mode 100644 MdeModulePkg/Library/MemoryPoolLib/InternalPool.c create mode 100644 MdeModulePkg/Library/MemoryPoolLib/InternalPool.h create mode 100644 MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf rename MdeModulePkg/{Core/Dxe/Mem => Library/MemoryPoolLib}/Pool.c (95%) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 44b371640a..a8a92d0765 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -86,6 +86,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include +#include // // attributes for reserved memory before it is promoted to system memory @@ -273,15 +274,6 @@ extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage; // Service Initialization Functions // -/** - Called to initialize the pool. - -**/ -VOID -CoreInitializePool ( - VOID - ); - VOID CoreSetMemoryTypeInformationRange ( IN EFI_PHYSICAL_ADDRESS Start, @@ -1241,80 +1233,6 @@ CoreGetMemoryMap ( OUT UINT32 *DescriptorVersion ); -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ); - -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreInternalAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ); - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreFreePool ( - IN VOID *Buffer - ); - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - @param PoolType Pointer to pool type - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreInternalFreePool ( - IN VOID *Buffer, - OUT EFI_MEMORY_TYPE *PoolType OPTIONAL - ); - /** Loads an EFI image into memory and returns a handle to the image. diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index d6656b3dff..71b7a46998 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -44,7 +44,6 @@ Hand/Handle.h Gcd/Gcd.c Gcd/Gcd.h - Mem/Pool.c Mem/Page.c Mem/MemData.c Mem/Imem.h @@ -104,6 +103,7 @@ ImagePropertiesRecordLib OrderedCollectionLib CpuArchLib + MemoryPoolLib [Guids] gEfiEventMemoryMapChangeGuid ## PRODUCES ## Event diff --git a/MdeModulePkg/Core/Dxe/Mem/Imem.h b/MdeModulePkg/Core/Dxe/Mem/Imem.h index 84027d628b..dc971471e6 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Imem.h +++ b/MdeModulePkg/Core/Dxe/Mem/Imem.h @@ -64,41 +64,6 @@ CoreFreePoolPages ( IN UINTN NumberOfPages ); -/** - Internal function to allocate pool of a particular type. - Caller must have the memory lock held - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param NeedGuard Flag to indicate Guard page is needed or not - - @return The allocate pool, or NULL - -**/ -VOID * -CoreAllocatePoolI ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - IN BOOLEAN NeedGuard - ); - -/** - Internal function to free a pool entry. - Caller must have the memory lock held - - @param Buffer The allocated pool entry to free - @param PoolType Pointer to pool type - - @retval EFI_INVALID_PARAMETER Buffer not valid - @retval EFI_SUCCESS Buffer successfully freed. - -**/ -EFI_STATUS -CoreFreePoolI ( - IN VOID *Buffer, - OUT EFI_MEMORY_TYPE *PoolType OPTIONAL - ); - /** Enter critical section by gaining lock on gMemoryLock. diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 2bf6d5aee8..1627b99868 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -46,9 +46,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "ProcessorBind.h" #include "Uefi/UefiMultiPhase.h" -#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 -#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 - #define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) diff --git a/MdeModulePkg/Include/Library/MemoryPoolLib.h b/MdeModulePkg/Include/Library/MemoryPoolLib.h new file mode 100644 index 0000000000..b80dc71a70 --- /dev/null +++ b/MdeModulePkg/Include/Library/MemoryPoolLib.h @@ -0,0 +1,146 @@ +/** @file + UEFI Memory pool management functions. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _MEMORY_POOL_LIB_H_ +#define _MEMORY_POOL_LIB_H_ + +// +// +---------------------------------------------------+ +// | 0..(EfiMaxMemoryType - 1) - Normal memory type | +// +---------------------------------------------------+ +// | EfiMaxMemoryType..0x6FFFFFFF - Invalid | +// +---------------------------------------------------+ +// | 0x70000000..0x7FFFFFFF - OEM reserved | +// +---------------------------------------------------+ +// | 0x80000000..0xFFFFFFFF - OS reserved | +// +---------------------------------------------------+ +// +#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 +#define MEMORY_TYPE_OS_RESERVED_MAX 0xFFFFFFFF +#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 +#define MEMORY_TYPE_OEM_RESERVED_MAX 0x7FFFFFFF + +/** + Called to initialize the pool. + +**/ +VOID +CoreInitializePool ( + VOID + ); + +/** + Allocate pool of a particular type. + + @param PoolType Type of pool to allocate + @param Size The amount of pool to allocate + @param Buffer The address to return a pointer to the allocated + pool + + @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL + @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. + @retval EFI_SUCCESS Pool successfully allocated. + +**/ +EFI_STATUS +EFIAPI +CoreInternalAllocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +/** + Allocate pool of a particular type. + + @param PoolType Type of pool to allocate + @param Size The amount of pool to allocate + @param Buffer The address to return a pointer to the allocated + pool + + @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL + @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. + @retval EFI_SUCCESS Pool successfully allocated. + +**/ +EFI_STATUS +EFIAPI +CoreAllocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +/** + Internal function to allocate pool of a particular type. + Caller must have the memory lock held + + @param PoolType Type of pool to allocate + @param Size The amount of pool to allocate + @param NeedGuard Flag to indicate Guard page is needed or not + + @return The allocate pool, or NULL + +**/ +VOID * +CoreAllocatePoolI ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + IN BOOLEAN NeedGuard + ); + +/** + Frees pool. + + @param Buffer The allocated pool entry to free + @param PoolType Pointer to pool type + + @retval EFI_INVALID_PARAMETER Buffer is not a valid value. + @retval EFI_SUCCESS Pool successfully freed. + +**/ +EFI_STATUS +EFIAPI +CoreInternalFreePool ( + IN VOID *Buffer, + OUT EFI_MEMORY_TYPE *PoolType OPTIONAL + ); + +/** + Frees pool. + + @param Buffer The allocated pool entry to free + + @retval EFI_INVALID_PARAMETER Buffer is not a valid value. + @retval EFI_SUCCESS Pool successfully freed. + +**/ +EFI_STATUS +EFIAPI +CoreFreePool ( + IN VOID *Buffer + ); + +/** + Internal function to free a pool entry. + Caller must have the memory lock held + + @param Buffer The allocated pool entry to free + @param PoolType Pointer to pool type + + @retval EFI_INVALID_PARAMETER Buffer not valid + @retval EFI_SUCCESS Buffer successfully freed. + +**/ +EFI_STATUS +CoreFreePoolI ( + IN VOID *Buffer, + OUT EFI_MEMORY_TYPE *PoolType OPTIONAL + ); + +#endif diff --git a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.c b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.c new file mode 100644 index 0000000000..734f397c91 --- /dev/null +++ b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.c @@ -0,0 +1,9 @@ +/** @file + DXE Core functions necessary for pool management functions. + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include diff --git a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h new file mode 100644 index 0000000000..898d5d7177 --- /dev/null +++ b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h @@ -0,0 +1,317 @@ +/** @file + DXE Core functions necessary for pool management functions. + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#ifndef _INTERNAL_POOL_H_ +#define _INTERNAL_POOL_H_ + +extern BOOLEAN mOnGuarding; +extern EFI_LOCK gMemoryLock; + +#define GUARD_HEAP_TYPE_FREED BIT4 + +/** + Check to see if the pool at the given address should be guarded or not. + + @param[in] MemoryType Pool type to check. + + + @return TRUE The given type of pool should be guarded. + @return FALSE The given type of pool should not be guarded. +**/ +BOOLEAN +IsPoolTypeToGuard ( + IN EFI_MEMORY_TYPE MemoryType + ); + +/** + Initialize a basic mutual exclusion lock. Each lock + provides mutual exclusion access at it's task priority + level. Since there is no-premption (at any TPL) or + multiprocessor support, acquiring the lock only consists + of raising to the locks TPL. + + @param Lock The EFI_LOCK structure to initialize + + @retval EFI_SUCCESS Lock Owned. + @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned. + +**/ +EFI_STATUS +CoreAcquireLockOrFail ( + IN EFI_LOCK *Lock + ); + +/** + Releases ownership of the mutual exclusion lock, and + restores the previous task priority level. + + @param Lock The lock to release + + @return Lock unowned + +**/ +VOID +CoreReleaseLock ( + IN EFI_LOCK *Lock + ); + +/** + Update memory profile information. + + @param CallerAddress Address of caller who call Allocate or Free. + @param Action This Allocate or Free action. + @param MemoryType Memory type. + EfiMaxMemoryType means the MemoryType is unknown. + @param Size Buffer size. + @param Buffer Buffer address. + @param ActionString String for memory profile action. + Only needed for user defined allocate action. + + @return EFI_SUCCESS Memory profile is updated. + @return EFI_UNSUPPORTED Memory profile is unsupported, + or memory profile for the image is not required, + or memory profile for the memory type is not required. + @return EFI_ACCESS_DENIED It is during memory profile data getting. + @return EFI_ABORTED Memory profile recording is not enabled. + @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. + @return EFI_NOT_FOUND No matched allocate info found for free action. + +**/ +EFI_STATUS +EFIAPI +CoreUpdateProfile ( + IN EFI_PHYSICAL_ADDRESS CallerAddress, + IN MEMORY_PROFILE_ACTION Action, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool + IN VOID *Buffer, + IN CHAR8 *ActionString OPTIONAL + ); + +/** + Install MemoryAttributesTable on memory allocation. + + @param[in] MemoryType EFI memory type. +**/ +VOID +InstallMemoryAttributesTableOnMemoryAllocation ( + IN EFI_MEMORY_TYPE MemoryType + ); + +/** + Internal function. Used by the pool functions to allocate pages + to back pool allocation requests. + + @param PoolType The type of memory for the new pool pages + @param NumberOfPages No of pages to allocate + @param Alignment Bits to align. + @param NeedGuard Flag to indicate Guard page is needed or not + + @return The allocated memory, or NULL + +**/ +VOID * +CoreAllocatePoolPages ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN NumberOfPages, + IN UINTN Alignment, + IN BOOLEAN NeedGuard + ); + +/** + Exit critical section by releasing lock on gMemoryLock. + +**/ +VOID +CoreReleaseMemoryLock ( + VOID + ); + +/** + Set head Guard and tail Guard for the given memory range. + + @param[in] Memory Base address of memory to set guard for. + @param[in] NumberOfPages Memory size in pages. + + @return VOID. +**/ +VOID +SetGuardForMemory ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ); + +/** + Manage memory permission attributes on a memory range, according to the + configured DXE memory protection policy. + + @param OldType The old memory type of the range + @param NewType The new memory type of the range + @param Memory The base address of the range + @param Length The size of the range (in bytes) + + @return EFI_SUCCESS If the the CPU arch protocol is not installed yet + @return EFI_SUCCESS If no DXE memory protection policy has been configured + @return EFI_SUCCESS If OldType and NewType use the same permission attributes + @return other Return value of gCpu->SetMemoryAttributes() + +**/ +EFI_STATUS +EFIAPI +ApplyMemoryProtectionPolicy ( + IN EFI_MEMORY_TYPE OldType, + IN EFI_MEMORY_TYPE NewType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINT64 Length + ); + +/** + Check to see if the heap guard is enabled for page and/or pool allocation. + + @param[in] GuardType Specify the sub-type(s) of Heap Guard. + + @return TRUE/FALSE. +**/ +BOOLEAN +IsHeapGuardEnabled ( + UINT8 GuardType + ); + +/** + Adjust the pool head position to make sure the Guard page is adjavent to + pool tail or pool head. + + @param[in] Memory Base address of memory allocated. + @param[in] NoPages Number of pages actually allocated. + @param[in] Size Size of memory requested. + (plus pool head/tail overhead) + + @return Address of pool head. +**/ +VOID * +AdjustPoolHeadA ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages, + IN UINTN Size + ); + +/** + Raising to the task priority level of the mutual exclusion + lock, and then acquires ownership of the lock. + + @param Lock The lock to acquire + + @return Lock owned + +**/ +VOID +CoreAcquireLock ( + IN EFI_LOCK *Lock + ); + +/** + Enter critical section by gaining lock on gMemoryLock. + +**/ +VOID +CoreAcquireMemoryLock ( + VOID + ); + +/** + Internal function. Frees pool pages allocated via AllocatePoolPages () + + @param Memory The base address to free + @param NumberOfPages The number of pages to free + +**/ +VOID +CoreFreePoolPages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ); + +/** + Record freed pages as well as mark them as not-present, if enabled. + + @param[in] BaseAddress Base address of just freed pages. + @param[in] Pages Number of freed pages. + + @return VOID. +**/ +VOID +EFIAPI +GuardFreedPagesChecked ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINTN Pages + ); + +/** + Adjust the start address and number of pages to free according to Guard. + + The purpose of this function is to keep the shared Guard page with adjacent + memory block if it's still in guard, or free it if no more sharing. Another + is to reserve pages as Guard pages in partial page free situation. + + @param[in,out] Memory Base address of memory to free. + @param[in,out] NumberOfPages Size of memory to free. + + @return VOID. +**/ +VOID +AdjustMemoryF ( + IN OUT EFI_PHYSICAL_ADDRESS *Memory, + IN OUT UINTN *NumberOfPages + ); + +/** + Unset head Guard and tail Guard for the given memory range. + + @param[in] Memory Base address of memory to unset guard for. + @param[in] NumberOfPages Memory size in pages. + + @return VOID. +**/ +VOID +UnsetGuardForMemory ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ); + +/** + Check to see if the page at the given address is guarded or not. + + @param[in] Address The address to check for. + + @return TRUE The page at Address is guarded. + @return FALSE The page at Address is not guarded. +**/ +BOOLEAN +EFIAPI +IsMemoryGuarded ( + IN EFI_PHYSICAL_ADDRESS Address + ); + +/** + Get the page base address according to pool head address. + + @param[in] Memory Head address of pool to free. + @param[in] NoPages Number of pages actually allocated. + @param[in] Size Size of memory requested. + (plus pool head/tail overhead) + + @return Address of pool head. +**/ +VOID * +AdjustPoolHeadF ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages, + IN UINTN Size + ); + +#endif diff --git a/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf b/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf new file mode 100644 index 0000000000..a0bda89d15 --- /dev/null +++ b/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf @@ -0,0 +1,39 @@ +## @file +# UEFI Memory pool management functions. +# +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MemoryPoolLib + FILE_GUID = 084a3534-da19-435e-8eeb-be08237ed403 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = MemoryPoolLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + InternalPool.c + InternalPool.h + Pool.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + PcdLib + UefiBootServicesTableLib + UefiLib + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Library/MemoryPoolLib/Pool.c similarity index 95% rename from MdeModulePkg/Core/Dxe/Mem/Pool.c rename to MdeModulePkg/Library/MemoryPoolLib/Pool.c index 72293e6dfe..10344579f1 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Pool.c +++ b/MdeModulePkg/Library/MemoryPoolLib/Pool.c @@ -6,9 +6,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include "DxeMain.h" -#include "Imem.h" -#include "HeapGuard.h" +#include + +#include +#include +#include +#include + +#include "InternalPool.h" STATIC EFI_LOCK mPoolMemoryLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); @@ -137,6 +142,7 @@ CoreInitializePool ( @return Pointer of Corresponding pool head. **/ +STATIC POOL * LookupPoolHead ( IN EFI_MEMORY_TYPE MemoryType diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 68e986ecf0..b698dbfe89 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -143,6 +143,7 @@ MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf + MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf [LibraryClasses.IA32.DXE_CORE] CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf @@ -371,6 +372,7 @@ MdeModulePkg/Library/DxeCoreDxeServicesTableLib/DxeCoreDxeServicesTableLib.inf MdeModulePkg/Library/DxeCoreUefiBootServicesTableLib/DxeCoreUefiBootServicesTableLib.inf MdeModulePkg/Library/DxeCoreUefiRuntimeServicesTableLib/DxeCoreUefiRuntimeServicesTableLib.inf + MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf MdeModulePkg/Universal/BdsDxe/BdsDxe.inf MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf From 94d4fe0b2907063274294700b37241b0563b8d3f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 27 Feb 2024 14:43:20 +0300 Subject: [PATCH 164/341] MdeModulePkg: Moved CoreAllocatePoolPagesI() and CoreFreePoolPagesI() to Page.c. --- MdeModulePkg/Core/Dxe/Mem/Page.c | 75 ++++++++++ .../Library/MemoryPoolLib/InternalPool.h | 140 +++++------------- MdeModulePkg/Library/MemoryPoolLib/Pool.c | 77 ---------- 3 files changed, 110 insertions(+), 182 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index 15c93ba5ef..8f1983c0cd 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -2180,6 +2180,81 @@ CoreGetMemoryMap ( return Status; } +/** + Internal function. Used by the pool functions to allocate pages + to back pool allocation requests. + + @param PoolType The type of memory for the new pool pages + @param NoPages No of pages to allocate + @param Granularity Bits to align. + @param NeedGuard Flag to indicate Guard page is needed or not + + @return The allocated memory, or NULL + +**/ +VOID * +CoreAllocatePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN NoPages, + IN UINTN Granularity, + IN BOOLEAN NeedGuard + ) +{ + VOID *Buffer; + EFI_STATUS Status; + + Status = CoreAcquireLockOrFail (&gMemoryLock); + if (EFI_ERROR (Status)) { + return NULL; + } + + Buffer = CoreAllocatePoolPages (PoolType, NoPages, Granularity, NeedGuard); + CoreReleaseMemoryLock (); + + if (Buffer != NULL) { + if (NeedGuard) { + SetGuardForMemory ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, NoPages); + } + + ApplyMemoryProtectionPolicy ( + EfiConventionalMemory, + PoolType, + (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, + EFI_PAGES_TO_SIZE (NoPages) + ); + } + + return Buffer; +} + +/** + Internal function. Frees pool pages allocated via CoreAllocatePoolPagesI(). + + @param PoolType The type of memory for the pool pages + @param Memory The base address to free + @param NoPages The number of pages to free + +**/ +VOID +CoreFreePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ) +{ + CoreAcquireMemoryLock (); + CoreFreePoolPages (Memory, NoPages); + CoreReleaseMemoryLock (); + + GuardFreedPagesChecked (Memory, NoPages); + ApplyMemoryProtectionPolicy ( + PoolType, + EfiConventionalMemory, + (EFI_PHYSICAL_ADDRESS)(UINTN)Memory, + EFI_PAGES_TO_SIZE (NoPages) + ); +} + /** Internal function. Used by the pool functions to allocate pages to back pool allocation requests. diff --git a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h index 898d5d7177..019b4541c3 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h +++ b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h @@ -10,7 +10,6 @@ #define _INTERNAL_POOL_H_ extern BOOLEAN mOnGuarding; -extern EFI_LOCK gMemoryLock; #define GUARD_HEAP_TYPE_FREED BIT4 @@ -103,73 +102,6 @@ InstallMemoryAttributesTableOnMemoryAllocation ( IN EFI_MEMORY_TYPE MemoryType ); -/** - Internal function. Used by the pool functions to allocate pages - to back pool allocation requests. - - @param PoolType The type of memory for the new pool pages - @param NumberOfPages No of pages to allocate - @param Alignment Bits to align. - @param NeedGuard Flag to indicate Guard page is needed or not - - @return The allocated memory, or NULL - -**/ -VOID * -CoreAllocatePoolPages ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN NumberOfPages, - IN UINTN Alignment, - IN BOOLEAN NeedGuard - ); - -/** - Exit critical section by releasing lock on gMemoryLock. - -**/ -VOID -CoreReleaseMemoryLock ( - VOID - ); - -/** - Set head Guard and tail Guard for the given memory range. - - @param[in] Memory Base address of memory to set guard for. - @param[in] NumberOfPages Memory size in pages. - - @return VOID. -**/ -VOID -SetGuardForMemory ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ); - -/** - Manage memory permission attributes on a memory range, according to the - configured DXE memory protection policy. - - @param OldType The old memory type of the range - @param NewType The new memory type of the range - @param Memory The base address of the range - @param Length The size of the range (in bytes) - - @return EFI_SUCCESS If the the CPU arch protocol is not installed yet - @return EFI_SUCCESS If no DXE memory protection policy has been configured - @return EFI_SUCCESS If OldType and NewType use the same permission attributes - @return other Return value of gCpu->SetMemoryAttributes() - -**/ -EFI_STATUS -EFIAPI -ApplyMemoryProtectionPolicy ( - IN EFI_MEMORY_TYPE OldType, - IN EFI_MEMORY_TYPE NewType, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINT64 Length - ); - /** Check to see if the heap guard is enabled for page and/or pool allocation. @@ -214,43 +146,6 @@ CoreAcquireLock ( IN EFI_LOCK *Lock ); -/** - Enter critical section by gaining lock on gMemoryLock. - -**/ -VOID -CoreAcquireMemoryLock ( - VOID - ); - -/** - Internal function. Frees pool pages allocated via AllocatePoolPages () - - @param Memory The base address to free - @param NumberOfPages The number of pages to free - -**/ -VOID -CoreFreePoolPages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ); - -/** - Record freed pages as well as mark them as not-present, if enabled. - - @param[in] BaseAddress Base address of just freed pages. - @param[in] Pages Number of freed pages. - - @return VOID. -**/ -VOID -EFIAPI -GuardFreedPagesChecked ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINTN Pages - ); - /** Adjust the start address and number of pages to free according to Guard. @@ -314,4 +209,39 @@ AdjustPoolHeadF ( IN UINTN Size ); +/** + Internal function. Used by the pool functions to allocate pages + to back pool allocation requests. + + @param PoolType The type of memory for the new pool pages + @param NoPages No of pages to allocate + @param Granularity Bits to align. + @param NeedGuard Flag to indicate Guard page is needed or not + + @return The allocated memory, or NULL + +**/ +VOID * +CoreAllocatePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN NoPages, + IN UINTN Granularity, + IN BOOLEAN NeedGuard + ); + +/** + Internal function. Frees pool pages allocated via CoreAllocatePoolPagesI(). + + @param PoolType The type of memory for the pool pages + @param Memory The base address to free + @param NoPages The number of pages to free + +**/ +VOID +CoreFreePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ); + #endif diff --git a/MdeModulePkg/Library/MemoryPoolLib/Pool.c b/MdeModulePkg/Library/MemoryPoolLib/Pool.c index 10344579f1..0e9197fd6c 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/Pool.c +++ b/MdeModulePkg/Library/MemoryPoolLib/Pool.c @@ -294,54 +294,6 @@ CoreAllocatePool ( return Status; } -/** - Internal function. Used by the pool functions to allocate pages - to back pool allocation requests. - - @param PoolType The type of memory for the new pool pages - @param NoPages No of pages to allocate - @param Granularity Bits to align. - @param NeedGuard Flag to indicate Guard page is needed or not - - @return The allocated memory, or NULL - -**/ -STATIC -VOID * -CoreAllocatePoolPagesI ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN NoPages, - IN UINTN Granularity, - IN BOOLEAN NeedGuard - ) -{ - VOID *Buffer; - EFI_STATUS Status; - - Status = CoreAcquireLockOrFail (&gMemoryLock); - if (EFI_ERROR (Status)) { - return NULL; - } - - Buffer = CoreAllocatePoolPages (PoolType, NoPages, Granularity, NeedGuard); - CoreReleaseMemoryLock (); - - if (Buffer != NULL) { - if (NeedGuard) { - SetGuardForMemory ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, NoPages); - } - - ApplyMemoryProtectionPolicy ( - EfiConventionalMemory, - PoolType, - (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, - EFI_PAGES_TO_SIZE (NoPages) - ); - } - - return Buffer; -} - /** Internal function to allocate pool of a particular type. Caller must have the memory lock held @@ -617,35 +569,6 @@ CoreFreePool ( return Status; } -/** - Internal function. Frees pool pages allocated via CoreAllocatePoolPagesI(). - - @param PoolType The type of memory for the pool pages - @param Memory The base address to free - @param NoPages The number of pages to free - -**/ -STATIC -VOID -CoreFreePoolPagesI ( - IN EFI_MEMORY_TYPE PoolType, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages - ) -{ - CoreAcquireMemoryLock (); - CoreFreePoolPages (Memory, NoPages); - CoreReleaseMemoryLock (); - - GuardFreedPagesChecked (Memory, NoPages); - ApplyMemoryProtectionPolicy ( - PoolType, - EfiConventionalMemory, - (EFI_PHYSICAL_ADDRESS)(UINTN)Memory, - EFI_PAGES_TO_SIZE (NoPages) - ); -} - /** Internal function. Frees guarded pool pages. From d37c3cb64d05456b9fbd71b650af5ca12b762433 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 27 Feb 2024 14:44:49 +0300 Subject: [PATCH 165/341] MdeModulePkg: Moved IsHeapGuardEnabled() and IsMemoryTypeToGuard() to MemoryPoolLib. --- MdeModulePkg/Core/Dxe/Mem/HeapGuard.c | 67 ------------------- MdeModulePkg/Core/Dxe/Mem/HeapGuard.h | 21 ------ MdeModulePkg/Include/Library/MemoryPoolLib.h | 39 +++++++++++ .../Library/MemoryPoolLib/InternalPool.h | 14 ---- .../Library/MemoryPoolLib/MemoryPoolLib.inf | 2 + MdeModulePkg/Library/MemoryPoolLib/Pool.c | 67 +++++++++++++++++++ 6 files changed, 108 insertions(+), 102 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c index 3baeef0dfc..fa82b65358 100644 --- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c +++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c @@ -572,58 +572,6 @@ UnsetGuardPage ( mOnGuarding = FALSE; } -/** - Check to see if the memory at the given address should be guarded or not. - - @param[in] MemoryType Memory type to check. - @param[in] AllocateType Allocation type to check. - @param[in] PageOrPool Indicate a page allocation or pool allocation. - - - @return TRUE The given type of memory should be guarded. - @return FALSE The given type of memory should not be guarded. -**/ -BOOLEAN -IsMemoryTypeToGuard ( - IN EFI_MEMORY_TYPE MemoryType, - IN EFI_ALLOCATE_TYPE AllocateType, - IN UINT8 PageOrPool - ) -{ - UINT64 TestBit; - UINT64 ConfigBit; - - if (AllocateType == AllocateAddress) { - return FALSE; - } - - if ((PcdGet8 (PcdHeapGuardPropertyMask) & PageOrPool) == 0) { - return FALSE; - } - - if (PageOrPool == GUARD_HEAP_TYPE_POOL) { - ConfigBit = PcdGet64 (PcdHeapGuardPoolType); - } else if (PageOrPool == GUARD_HEAP_TYPE_PAGE) { - ConfigBit = PcdGet64 (PcdHeapGuardPageType); - } else { - ConfigBit = (UINT64)-1; - } - - if ((UINT32)MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) { - TestBit = BIT63; - } else if ((UINT32)MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) { - TestBit = BIT62; - } else if (MemoryType < EfiMaxMemoryType) { - TestBit = LShiftU64 (1, MemoryType); - } else if (MemoryType == EfiMaxMemoryType) { - TestBit = (UINT64)-1; - } else { - TestBit = 0; - } - - return ((ConfigBit & TestBit) != 0); -} - /** Check to see if the pool at the given address should be guarded or not. @@ -663,21 +611,6 @@ IsPageTypeToGuard ( return IsMemoryTypeToGuard (MemoryType, AllocateType, GUARD_HEAP_TYPE_PAGE); } -/** - Check to see if the heap guard is enabled for page and/or pool allocation. - - @param[in] GuardType Specify the sub-type(s) of Heap Guard. - - @return TRUE/FALSE. -**/ -BOOLEAN -IsHeapGuardEnabled ( - UINT8 GuardType - ) -{ - return IsMemoryTypeToGuard (EfiMaxMemoryType, AllocateAnyPages, GuardType); -} - /** Set head Guard and tail Guard for the given memory range. diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h index 578e857465..a4a5088b65 100644 --- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h +++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h @@ -149,15 +149,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent (1 << GUARDED_HEAP_MAP_ENTRY_SHIFT) - 1 \ } -// -// Memory type to guard (matching the related PCD definition) -// -#define GUARD_HEAP_TYPE_PAGE BIT0 -#define GUARD_HEAP_TYPE_POOL BIT1 -#define GUARD_HEAP_TYPE_FREED BIT4 -#define GUARD_HEAP_TYPE_ALL \ - (GUARD_HEAP_TYPE_PAGE|GUARD_HEAP_TYPE_POOL|GUARD_HEAP_TYPE_FREED) - // // Debug message level // @@ -391,18 +382,6 @@ AdjustPoolHeadF ( IN UINTN Size ); -/** - Check to see if the heap guard is enabled for page and/or pool allocation. - - @param[in] GuardType Specify the sub-type(s) of Heap Guard. - - @return TRUE/FALSE. -**/ -BOOLEAN -IsHeapGuardEnabled ( - UINT8 GuardType - ); - /** Notify function used to set all Guard pages after CPU Arch Protocol installed. **/ diff --git a/MdeModulePkg/Include/Library/MemoryPoolLib.h b/MdeModulePkg/Include/Library/MemoryPoolLib.h index b80dc71a70..a285040287 100644 --- a/MdeModulePkg/Include/Library/MemoryPoolLib.h +++ b/MdeModulePkg/Include/Library/MemoryPoolLib.h @@ -25,6 +25,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 #define MEMORY_TYPE_OEM_RESERVED_MAX 0x7FFFFFFF +// +// Memory type to guard (matching the related PCD definition) +// +#define GUARD_HEAP_TYPE_PAGE BIT0 +#define GUARD_HEAP_TYPE_POOL BIT1 +#define GUARD_HEAP_TYPE_FREED BIT4 +#define GUARD_HEAP_TYPE_ALL \ + (GUARD_HEAP_TYPE_PAGE|GUARD_HEAP_TYPE_POOL|GUARD_HEAP_TYPE_FREED) + /** Called to initialize the pool. @@ -143,4 +152,34 @@ CoreFreePoolI ( OUT EFI_MEMORY_TYPE *PoolType OPTIONAL ); +/** + Check to see if the heap guard is enabled for page and/or pool allocation. + + @param[in] GuardType Specify the sub-type(s) of Heap Guard. + + @return TRUE/FALSE. +**/ +BOOLEAN +IsHeapGuardEnabled ( + UINT8 GuardType + ); + +/** + Check to see if the memory at the given address should be guarded or not. + + @param[in] MemoryType Memory type to check. + @param[in] AllocateType Allocation type to check. + @param[in] PageOrPool Indicate a page allocation or pool allocation. + + + @return TRUE The given type of memory should be guarded. + @return FALSE The given type of memory should not be guarded. +**/ +BOOLEAN +IsMemoryTypeToGuard ( + IN EFI_MEMORY_TYPE MemoryType, + IN EFI_ALLOCATE_TYPE AllocateType, + IN UINT8 PageOrPool + ); + #endif diff --git a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h index 019b4541c3..9a62050831 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h +++ b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h @@ -11,8 +11,6 @@ extern BOOLEAN mOnGuarding; -#define GUARD_HEAP_TYPE_FREED BIT4 - /** Check to see if the pool at the given address should be guarded or not. @@ -102,18 +100,6 @@ InstallMemoryAttributesTableOnMemoryAllocation ( IN EFI_MEMORY_TYPE MemoryType ); -/** - Check to see if the heap guard is enabled for page and/or pool allocation. - - @param[in] GuardType Specify the sub-type(s) of Heap Guard. - - @return TRUE/FALSE. -**/ -BOOLEAN -IsHeapGuardEnabled ( - UINT8 GuardType - ); - /** Adjust the pool head position to make sure the Guard page is adjavent to pool tail or pool head. diff --git a/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf b/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf index a0bda89d15..91bbda57a3 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf +++ b/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf @@ -36,4 +36,6 @@ UefiLib [Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES diff --git a/MdeModulePkg/Library/MemoryPoolLib/Pool.c b/MdeModulePkg/Library/MemoryPoolLib/Pool.c index 0e9197fd6c..83d53286a3 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/Pool.c +++ b/MdeModulePkg/Library/MemoryPoolLib/Pool.c @@ -809,3 +809,70 @@ CoreFreePoolI ( return EFI_SUCCESS; } + +/** + Check to see if the heap guard is enabled for page and/or pool allocation. + + @param[in] GuardType Specify the sub-type(s) of Heap Guard. + + @return TRUE/FALSE. +**/ +BOOLEAN +IsHeapGuardEnabled ( + UINT8 GuardType + ) +{ + return IsMemoryTypeToGuard (EfiMaxMemoryType, AllocateAnyPages, GuardType); +} + +/** + Check to see if the memory at the given address should be guarded or not. + + @param[in] MemoryType Memory type to check. + @param[in] AllocateType Allocation type to check. + @param[in] PageOrPool Indicate a page allocation or pool allocation. + + + @return TRUE The given type of memory should be guarded. + @return FALSE The given type of memory should not be guarded. +**/ +BOOLEAN +IsMemoryTypeToGuard ( + IN EFI_MEMORY_TYPE MemoryType, + IN EFI_ALLOCATE_TYPE AllocateType, + IN UINT8 PageOrPool + ) +{ + UINT64 TestBit; + UINT64 ConfigBit; + + if (AllocateType == AllocateAddress) { + return FALSE; + } + + if ((PcdGet8 (PcdHeapGuardPropertyMask) & PageOrPool) == 0) { + return FALSE; + } + + if (PageOrPool == GUARD_HEAP_TYPE_POOL) { + ConfigBit = PcdGet64 (PcdHeapGuardPoolType); + } else if (PageOrPool == GUARD_HEAP_TYPE_PAGE) { + ConfigBit = PcdGet64 (PcdHeapGuardPageType); + } else { + ConfigBit = (UINT64)-1; + } + + if ((UINT32)MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) { + TestBit = BIT63; + } else if ((UINT32)MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) { + TestBit = BIT62; + } else if (MemoryType < EfiMaxMemoryType) { + TestBit = LShiftU64 (1, MemoryType); + } else if (MemoryType == EfiMaxMemoryType) { + TestBit = (UINT64)-1; + } else { + TestBit = 0; + } + + return ((ConfigBit & TestBit) != 0); +} From 5d061d7d3c63a9d63799f7dcdc044cf215d39da9 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 27 Feb 2024 15:18:58 +0300 Subject: [PATCH 166/341] MdeModulePkg: Moved IsPoolTypeToGuard(), CoreAcquireLockOrFail(), CoreReleaseLock() and CoreAcquireLock() to MemoryPoolLib. --- MdeModulePkg/Core/Dxe/DxeMain.h | 46 --------- MdeModulePkg/Core/Dxe/DxeMain.inf | 1 - MdeModulePkg/Core/Dxe/Library/Library.c | 94 ------------------- MdeModulePkg/Core/Dxe/Mem/HeapGuard.c | 21 ----- MdeModulePkg/Core/Dxe/Mem/HeapGuard.h | 14 --- MdeModulePkg/Include/Library/MemoryPoolLib.h | 62 ++++++++++++ .../Library/MemoryPoolLib/InternalPool.c | 56 +++++++++++ .../Library/MemoryPoolLib/InternalPool.h | 60 ------------ MdeModulePkg/Library/MemoryPoolLib/Pool.c | 21 +++++ 9 files changed, 139 insertions(+), 236 deletions(-) delete mode 100644 MdeModulePkg/Core/Dxe/Library/Library.c diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index a8a92d0765..3db3ec8d3f 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2389,52 +2389,6 @@ ProduceFVBProtocolOnBuffer ( OUT EFI_HANDLE *FvProtocol OPTIONAL ); -/** - Raising to the task priority level of the mutual exclusion - lock, and then acquires ownership of the lock. - - @param Lock The lock to acquire - - @return Lock owned - -**/ -VOID -CoreAcquireLock ( - IN EFI_LOCK *Lock - ); - -/** - Initialize a basic mutual exclusion lock. Each lock - provides mutual exclusion access at it's task priority - level. Since there is no-premption (at any TPL) or - multiprocessor support, acquiring the lock only consists - of raising to the locks TPL. - - @param Lock The EFI_LOCK structure to initialize - - @retval EFI_SUCCESS Lock Owned. - @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned. - -**/ -EFI_STATUS -CoreAcquireLockOrFail ( - IN EFI_LOCK *Lock - ); - -/** - Releases ownership of the mutual exclusion lock, and - restores the previous task priority level. - - @param Lock The lock to release - - @return Lock unowned - -**/ -VOID -CoreReleaseLock ( - IN EFI_LOCK *Lock - ); - /** Read data from Firmware Block by FVB protocol Read. The data may cross the multi block ranges. diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 71b7a46998..32c2382da8 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -36,7 +36,6 @@ Misc/InstallConfigurationTable.c Misc/MemoryAttributesTable.c Misc/MemoryProtection.c - Library/Library.c Hand/DriverSupport.c Hand/Notify.c Hand/Locate.c diff --git a/MdeModulePkg/Core/Dxe/Library/Library.c b/MdeModulePkg/Core/Dxe/Library/Library.c deleted file mode 100644 index 63cef1daca..0000000000 --- a/MdeModulePkg/Core/Dxe/Library/Library.c +++ /dev/null @@ -1,94 +0,0 @@ -/** @file - DXE Core library services. - -Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "DxeMain.h" - -// -// Lock Stuff -// - -/** - Initialize a basic mutual exclusion lock. Each lock - provides mutual exclusion access at it's task priority - level. Since there is no-premption (at any TPL) or - multiprocessor support, acquiring the lock only consists - of raising to the locks TPL. - - @param Lock The EFI_LOCK structure to initialize - - @retval EFI_SUCCESS Lock Owned. - @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned. - -**/ -EFI_STATUS -CoreAcquireLockOrFail ( - IN EFI_LOCK *Lock - ) -{ - ASSERT (Lock != NULL); - ASSERT (Lock->Lock != EfiLockUninitialized); - - if (Lock->Lock == EfiLockAcquired) { - // - // Lock is already owned, so bail out - // - return EFI_ACCESS_DENIED; - } - - Lock->OwnerTpl = CoreRaiseTpl (Lock->Tpl); - - Lock->Lock = EfiLockAcquired; - return EFI_SUCCESS; -} - -/** - Raising to the task priority level of the mutual exclusion - lock, and then acquires ownership of the lock. - - @param Lock The lock to acquire - - @return Lock owned - -**/ -VOID -CoreAcquireLock ( - IN EFI_LOCK *Lock - ) -{ - ASSERT (Lock != NULL); - ASSERT (Lock->Lock == EfiLockReleased); - - Lock->OwnerTpl = CoreRaiseTpl (Lock->Tpl); - Lock->Lock = EfiLockAcquired; -} - -/** - Releases ownership of the mutual exclusion lock, and - restores the previous task priority level. - - @param Lock The lock to release - - @return Lock unowned - -**/ -VOID -CoreReleaseLock ( - IN EFI_LOCK *Lock - ) -{ - EFI_TPL Tpl; - - ASSERT (Lock != NULL); - ASSERT (Lock->Lock == EfiLockAcquired); - - Tpl = Lock->OwnerTpl; - - Lock->Lock = EfiLockReleased; - - CoreRestoreTpl (Tpl); -} diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c index fa82b65358..04bcf53588 100644 --- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c +++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c @@ -572,27 +572,6 @@ UnsetGuardPage ( mOnGuarding = FALSE; } -/** - Check to see if the pool at the given address should be guarded or not. - - @param[in] MemoryType Pool type to check. - - - @return TRUE The given type of pool should be guarded. - @return FALSE The given type of pool should not be guarded. -**/ -BOOLEAN -IsPoolTypeToGuard ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - return IsMemoryTypeToGuard ( - MemoryType, - AllocateAnyPages, - GUARD_HEAP_TYPE_POOL - ); -} - /** Check to see if the page at the given address should be guarded or not. diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h index a4a5088b65..7289549ee8 100644 --- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h +++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h @@ -281,20 +281,6 @@ AdjustMemoryS ( IN UINT64 SizeRequested ); -/** - Check to see if the pool at the given address should be guarded or not. - - @param[in] MemoryType Pool type to check. - - - @return TRUE The given type of pool should be guarded. - @return FALSE The given type of pool should not be guarded. -**/ -BOOLEAN -IsPoolTypeToGuard ( - IN EFI_MEMORY_TYPE MemoryType - ); - /** Check to see if the page at the given address should be guarded or not. diff --git a/MdeModulePkg/Include/Library/MemoryPoolLib.h b/MdeModulePkg/Include/Library/MemoryPoolLib.h index a285040287..ff1da3cca8 100644 --- a/MdeModulePkg/Include/Library/MemoryPoolLib.h +++ b/MdeModulePkg/Include/Library/MemoryPoolLib.h @@ -9,6 +9,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #ifndef _MEMORY_POOL_LIB_H_ #define _MEMORY_POOL_LIB_H_ +#include + // // +---------------------------------------------------+ // | 0..(EfiMaxMemoryType - 1) - Normal memory type | @@ -164,6 +166,20 @@ IsHeapGuardEnabled ( UINT8 GuardType ); +/** + Check to see if the pool at the given address should be guarded or not. + + @param[in] MemoryType Pool type to check. + + + @return TRUE The given type of pool should be guarded. + @return FALSE The given type of pool should not be guarded. +**/ +BOOLEAN +IsPoolTypeToGuard ( + IN EFI_MEMORY_TYPE MemoryType + ); + /** Check to see if the memory at the given address should be guarded or not. @@ -182,4 +198,50 @@ IsMemoryTypeToGuard ( IN UINT8 PageOrPool ); +/** + Raising to the task priority level of the mutual exclusion + lock, and then acquires ownership of the lock. + + @param Lock The lock to acquire + + @return Lock owned + +**/ +VOID +CoreAcquireLock ( + IN EFI_LOCK *Lock + ); + +/** + Initialize a basic mutual exclusion lock. Each lock + provides mutual exclusion access at it's task priority + level. Since there is no-premption (at any TPL) or + multiprocessor support, acquiring the lock only consists + of raising to the locks TPL. + + @param Lock The EFI_LOCK structure to initialize + + @retval EFI_SUCCESS Lock Owned. + @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned. + +**/ +EFI_STATUS +CoreAcquireLockOrFail ( + IN EFI_LOCK *Lock + ); + +/** + Releases ownership of the mutual exclusion lock, and + restores the previous task priority level. + + @param Lock The lock to release + + @return Lock unowned + +**/ +VOID +CoreReleaseLock ( + IN EFI_LOCK *Lock + ); + #endif diff --git a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.c b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.c index 734f397c91..5e506e080b 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.c +++ b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.c @@ -7,3 +7,59 @@ **/ #include +#include + +/** + Initialize a basic mutual exclusion lock. Each lock + provides mutual exclusion access at it's task priority + level. Since there is no-premption (at any TPL) or + multiprocessor support, acquiring the lock only consists + of raising to the locks TPL. + + @param Lock The EFI_LOCK structure to initialize + + @retval EFI_SUCCESS Lock Owned. + @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned. + +**/ +EFI_STATUS +CoreAcquireLockOrFail ( + IN EFI_LOCK *Lock + ) +{ + return EfiAcquireLockOrFail (Lock); +} + +/** + Raising to the task priority level of the mutual exclusion + lock, and then acquires ownership of the lock. + + @param Lock The lock to acquire + + @return Lock owned + +**/ +VOID +CoreAcquireLock ( + IN EFI_LOCK *Lock + ) +{ + EfiAcquireLock (Lock); +} + +/** + Releases ownership of the mutual exclusion lock, and + restores the previous task priority level. + + @param Lock The lock to release + + @return Lock unowned + +**/ +VOID +CoreReleaseLock ( + IN EFI_LOCK *Lock + ) +{ + EfiReleaseLock (Lock); +} diff --git a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h index 9a62050831..a8dfc1b5ce 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h +++ b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h @@ -11,52 +11,6 @@ extern BOOLEAN mOnGuarding; -/** - Check to see if the pool at the given address should be guarded or not. - - @param[in] MemoryType Pool type to check. - - - @return TRUE The given type of pool should be guarded. - @return FALSE The given type of pool should not be guarded. -**/ -BOOLEAN -IsPoolTypeToGuard ( - IN EFI_MEMORY_TYPE MemoryType - ); - -/** - Initialize a basic mutual exclusion lock. Each lock - provides mutual exclusion access at it's task priority - level. Since there is no-premption (at any TPL) or - multiprocessor support, acquiring the lock only consists - of raising to the locks TPL. - - @param Lock The EFI_LOCK structure to initialize - - @retval EFI_SUCCESS Lock Owned. - @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned. - -**/ -EFI_STATUS -CoreAcquireLockOrFail ( - IN EFI_LOCK *Lock - ); - -/** - Releases ownership of the mutual exclusion lock, and - restores the previous task priority level. - - @param Lock The lock to release - - @return Lock unowned - -**/ -VOID -CoreReleaseLock ( - IN EFI_LOCK *Lock - ); - /** Update memory profile information. @@ -118,20 +72,6 @@ AdjustPoolHeadA ( IN UINTN Size ); -/** - Raising to the task priority level of the mutual exclusion - lock, and then acquires ownership of the lock. - - @param Lock The lock to acquire - - @return Lock owned - -**/ -VOID -CoreAcquireLock ( - IN EFI_LOCK *Lock - ); - /** Adjust the start address and number of pages to free according to Guard. diff --git a/MdeModulePkg/Library/MemoryPoolLib/Pool.c b/MdeModulePkg/Library/MemoryPoolLib/Pool.c index 83d53286a3..9e8fb90904 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/Pool.c +++ b/MdeModulePkg/Library/MemoryPoolLib/Pool.c @@ -825,6 +825,27 @@ IsHeapGuardEnabled ( return IsMemoryTypeToGuard (EfiMaxMemoryType, AllocateAnyPages, GuardType); } +/** + Check to see if the pool at the given address should be guarded or not. + + @param[in] MemoryType Pool type to check. + + + @return TRUE The given type of pool should be guarded. + @return FALSE The given type of pool should not be guarded. +**/ +BOOLEAN +IsPoolTypeToGuard ( + IN EFI_MEMORY_TYPE MemoryType + ) +{ + return IsMemoryTypeToGuard ( + MemoryType, + AllocateAnyPages, + GUARD_HEAP_TYPE_POOL + ); +} + /** Check to see if the memory at the given address should be guarded or not. From 5aeb15a8564bcb17aa8c2cb951f7aa3788f5d7a7 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 27 Feb 2024 16:09:34 +0300 Subject: [PATCH 167/341] MdeModulePkg: Moved CoreFreePoolPagesWithGuard() to Page.c and AdjustPoolHeadA(), AdjustPoolHeadF() to MemoryPoolLib. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 2 - MdeModulePkg/Core/Dxe/Mem/HeapGuard.c | 65 ----------- MdeModulePkg/Core/Dxe/Mem/HeapGuard.h | 35 ------ MdeModulePkg/Core/Dxe/Mem/Page.c | 35 ++++++ .../Library/MemoryPoolLib/InternalPool.h | 66 ++--------- MdeModulePkg/Library/MemoryPoolLib/Pool.c | 103 ++++++++++++------ 6 files changed, 109 insertions(+), 197 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 32c2382da8..9e5e57cb30 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -195,8 +195,6 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c index 04bcf53588..848739de67 100644 --- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c +++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.c @@ -913,71 +913,6 @@ AdjustMemoryA ( } } -/** - Adjust the pool head position to make sure the Guard page is adjavent to - pool tail or pool head. - - @param[in] Memory Base address of memory allocated. - @param[in] NoPages Number of pages actually allocated. - @param[in] Size Size of memory requested. - (plus pool head/tail overhead) - - @return Address of pool head. -**/ -VOID * -AdjustPoolHeadA ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages, - IN UINTN Size - ) -{ - if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) { - // - // Pool head is put near the head Guard - // - return (VOID *)(UINTN)Memory; - } - - // - // Pool head is put near the tail Guard - // - Size = ALIGN_VALUE (Size, 8); - return (VOID *)(UINTN)(Memory + EFI_PAGES_TO_SIZE (NoPages) - Size); -} - -/** - Get the page base address according to pool head address. - - @param[in] Memory Head address of pool to free. - @param[in] NoPages Number of pages actually allocated. - @param[in] Size Size of memory requested. - (plus pool head/tail overhead) - - @return Address of pool head. -**/ -VOID * -AdjustPoolHeadF ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages, - IN UINTN Size - ) -{ - if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) { - // - // Pool head is put near the head Guard - // - return (VOID *)(UINTN)Memory; - } - - // - // Pool head is put near the tail Guard. We need to exactly undo the addition done in AdjustPoolHeadA - // because we may not have allocated the pool head on the first allocated page, since we are aligned to - // the tail and on some architectures, the runtime page allocation granularity is > one page. So we allocate - // more pages than we need and put the pool head somewhere past the first page. - // - return (VOID *)(UINTN)(Memory + Size - EFI_PAGES_TO_SIZE (NoPages)); -} - /** Allocate or free guarded memory. diff --git a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h index 7289549ee8..e9d4031c0f 100644 --- a/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h +++ b/MdeModulePkg/Core/Dxe/Mem/HeapGuard.h @@ -333,41 +333,6 @@ DumpGuardedMemoryBitmap ( VOID ); -/** - Adjust the pool head position to make sure the Guard page is adjavent to - pool tail or pool head. - - @param[in] Memory Base address of memory allocated. - @param[in] NoPages Number of pages actually allocated. - @param[in] Size Size of memory requested. - (plus pool head/tail overhead) - - @return Address of pool head. -**/ -VOID * -AdjustPoolHeadA ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages, - IN UINTN Size - ); - -/** - Get the page base address according to pool head address. - - @param[in] Memory Head address of pool to free. - @param[in] NoPages Number of pages actually allocated. - @param[in] Size Size of memory requested. - (plus pool head/tail overhead) - - @return Address of pool head. -**/ -VOID * -AdjustPoolHeadF ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages, - IN UINTN Size - ); - /** Notify function used to set all Guard pages after CPU Arch Protocol installed. **/ diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index 8f1983c0cd..b61debf41d 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -2255,6 +2255,41 @@ CoreFreePoolPagesI ( ); } +/** + Internal function. Frees guarded pool pages. + + @param PoolType The type of memory for the pool pages + @param Memory The base address to free + @param NoPages The number of pages to free + +**/ +VOID +CoreFreePoolPagesWithGuard ( + IN EFI_MEMORY_TYPE PoolType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ) +{ + EFI_PHYSICAL_ADDRESS MemoryGuarded; + UINTN NoPagesGuarded; + + MemoryGuarded = Memory; + NoPagesGuarded = NoPages; + + AdjustMemoryF (&Memory, &NoPages); + // + // It's safe to unset Guard page inside memory lock because there should + // be no memory allocation occurred in updating memory page attribute at + // this point. And unsetting Guard page before free will prevent Guard + // page just freed back to pool from being allocated right away before + // marking it usable (from non-present to present). + // + UnsetGuardForMemory (MemoryGuarded, NoPagesGuarded); + if (NoPages > 0) { + CoreFreePoolPagesI (PoolType, Memory, NoPages); + } +} + /** Internal function. Used by the pool functions to allocate pages to back pool allocation requests. diff --git a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h index a8dfc1b5ce..b0bb574f21 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h +++ b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h @@ -55,53 +55,18 @@ InstallMemoryAttributesTableOnMemoryAllocation ( ); /** - Adjust the pool head position to make sure the Guard page is adjavent to - pool tail or pool head. + Internal function. Frees guarded pool pages. - @param[in] Memory Base address of memory allocated. - @param[in] NoPages Number of pages actually allocated. - @param[in] Size Size of memory requested. - (plus pool head/tail overhead) - - @return Address of pool head. -**/ -VOID * -AdjustPoolHeadA ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages, - IN UINTN Size - ); - -/** - Adjust the start address and number of pages to free according to Guard. - - The purpose of this function is to keep the shared Guard page with adjacent - memory block if it's still in guard, or free it if no more sharing. Another - is to reserve pages as Guard pages in partial page free situation. - - @param[in,out] Memory Base address of memory to free. - @param[in,out] NumberOfPages Size of memory to free. - - @return VOID. -**/ -VOID -AdjustMemoryF ( - IN OUT EFI_PHYSICAL_ADDRESS *Memory, - IN OUT UINTN *NumberOfPages - ); - -/** - Unset head Guard and tail Guard for the given memory range. - - @param[in] Memory Base address of memory to unset guard for. - @param[in] NumberOfPages Memory size in pages. + @param PoolType The type of memory for the pool pages + @param Memory The base address to free + @param NoPages The number of pages to free - @return VOID. **/ VOID -UnsetGuardForMemory ( +CoreFreePoolPagesWithGuard ( + IN EFI_MEMORY_TYPE PoolType, IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages + IN UINTN NoPages ); /** @@ -118,23 +83,6 @@ IsMemoryGuarded ( IN EFI_PHYSICAL_ADDRESS Address ); -/** - Get the page base address according to pool head address. - - @param[in] Memory Head address of pool to free. - @param[in] NoPages Number of pages actually allocated. - @param[in] Size Size of memory requested. - (plus pool head/tail overhead) - - @return Address of pool head. -**/ -VOID * -AdjustPoolHeadF ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages, - IN UINTN Size - ); - /** Internal function. Used by the pool functions to allocate pages to back pool allocation requests. diff --git a/MdeModulePkg/Library/MemoryPoolLib/Pool.c b/MdeModulePkg/Library/MemoryPoolLib/Pool.c index 9e8fb90904..a35fa80058 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/Pool.c +++ b/MdeModulePkg/Library/MemoryPoolLib/Pool.c @@ -87,6 +87,73 @@ POOL mPoolHead[EfiMaxMemoryType]; // LIST_ENTRY mPoolHeadList = INITIALIZE_LIST_HEAD_VARIABLE (mPoolHeadList); +/** + Adjust the pool head position to make sure the Guard page is adjavent to + pool tail or pool head. + + @param[in] Memory Base address of memory allocated. + @param[in] NoPages Number of pages actually allocated. + @param[in] Size Size of memory requested. + (plus pool head/tail overhead) + + @return Address of pool head. +**/ +STATIC +VOID * +AdjustPoolHeadA ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages, + IN UINTN Size + ) +{ + if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) { + // + // Pool head is put near the head Guard + // + return (VOID *)(UINTN)Memory; + } + + // + // Pool head is put near the tail Guard + // + Size = ALIGN_VALUE (Size, 8); + return (VOID *)(UINTN)(Memory + EFI_PAGES_TO_SIZE (NoPages) - Size); +} + +/** + Get the page base address according to pool head address. + + @param[in] Memory Head address of pool to free. + @param[in] NoPages Number of pages actually allocated. + @param[in] Size Size of memory requested. + (plus pool head/tail overhead) + + @return Address of pool head. +**/ +STATIC +VOID * +AdjustPoolHeadF ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages, + IN UINTN Size + ) +{ + if ((Memory == 0) || ((PcdGet8 (PcdHeapGuardPropertyMask) & BIT7) != 0)) { + // + // Pool head is put near the head Guard + // + return (VOID *)(UINTN)Memory; + } + + // + // Pool head is put near the tail Guard. We need to exactly undo the addition done in AdjustPoolHeadA + // because we may not have allocated the pool head on the first allocated page, since we are aligned to + // the tail and on some architectures, the runtime page allocation granularity is > one page. So we allocate + // more pages than we need and put the pool head somewhere past the first page. + // + return (VOID *)(UINTN)(Memory + Size - EFI_PAGES_TO_SIZE (NoPages)); +} + /** Get pool size table index from the specified size. @@ -569,42 +636,6 @@ CoreFreePool ( return Status; } -/** - Internal function. Frees guarded pool pages. - - @param PoolType The type of memory for the pool pages - @param Memory The base address to free - @param NoPages The number of pages to free - -**/ -STATIC -VOID -CoreFreePoolPagesWithGuard ( - IN EFI_MEMORY_TYPE PoolType, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages - ) -{ - EFI_PHYSICAL_ADDRESS MemoryGuarded; - UINTN NoPagesGuarded; - - MemoryGuarded = Memory; - NoPagesGuarded = NoPages; - - AdjustMemoryF (&Memory, &NoPages); - // - // It's safe to unset Guard page inside memory lock because there should - // be no memory allocation occurred in updating memory page attribute at - // this point. And unsetting Guard page before free will prevent Guard - // page just freed back to pool from being allocated right away before - // marking it usable (from non-present to present). - // - UnsetGuardForMemory (MemoryGuarded, NoPagesGuarded); - if (NoPages > 0) { - CoreFreePoolPagesI (PoolType, Memory, NoPages); - } -} - /** Internal function to free a pool entry. Caller must have the memory lock held From 04c92e330326f30018fd5e9e8291cbc4b75c884d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 27 Feb 2024 19:08:41 +0300 Subject: [PATCH 168/341] Ring3: Added MemoryPoolLib into DxeRing3. --- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 10 +- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf | 5 +- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 148 ++++++++++++------ MdeModulePkg/Core/Dxe/Mem/Page.c | 13 +- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 3 - MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 74 +++++---- MdePkg/Include/Uefi/UefiSpec.h | 6 +- 7 files changed, 172 insertions(+), 87 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index ec2405c08e..20659b11b3 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -7,6 +7,8 @@ #include #include +#include +#include #include "Ring3.h" @@ -23,8 +25,8 @@ EFI_BOOT_SERVICES mBootServices = { (EFI_ALLOCATE_PAGES)Ring3AllocatePages, // AllocatePages (EFI_FREE_PAGES)Ring3FreePages, // FreePages (EFI_GET_MEMORY_MAP)Ring3GetMemoryMap, // GetMemoryMap - (EFI_ALLOCATE_POOL)Ring3AllocatePool, // AllocatePool - (EFI_FREE_POOL)Ring3FreePool, // FreePool + (EFI_ALLOCATE_POOL)CoreAllocatePool, // AllocatePool + (EFI_FREE_POOL)CoreFreePool, // FreePool (EFI_CREATE_EVENT)Ring3CreateEvent, // CreateEvent (EFI_SET_TIMER)Ring3SetTimer, // SetTimer (EFI_WAIT_FOR_EVENT)Ring3WaitForEvent, // WaitForEvent @@ -177,5 +179,9 @@ Ring3Initialization ( Ring3Data->EntryPoint = (VOID *)Ring3EntryPoint; Ring3Data->BootServices = &mBootServices; + gBS = &mBootServices; + + CoreInitializePool (); + return EFI_SUCCESS; } diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index c2b0c004de..1e29851e32 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -32,13 +32,16 @@ [Packages] MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec [LibraryClasses] BaseLib BaseMemoryLib DebugLib + MemoryPoolLib + UefiBootServicesTableLib UefiDriverEntryPoint - + [Protocols] gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 5e26a67fea..2fc863a1e4 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -8,18 +8,25 @@ #include +#include + #include #include #include "Ring3.h" +BOOLEAN mOnGuarding = FALSE; + EFI_TPL EFIAPI Ring3RaiseTpl ( IN EFI_TPL NewTpl ) { - return NewTpl; + return (EFI_TPL)SysCall ( + SysCallRaiseTpl, + NewTpl + ); } VOID @@ -28,7 +35,10 @@ Ring3RestoreTpl ( IN EFI_TPL NewTpl ) { - + SysCall ( + SysCallRestoreTpl, + NewTpl + ); } EFI_STATUS @@ -40,7 +50,20 @@ Ring3AllocatePages ( IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { - return EFI_UNSUPPORTED; + EFI_STATUS Status; + + Status = SysCall ( + SysCallAllocatePages, + Type, + MemoryType, + NumberOfPages, + Memory + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate %d pages.\n", NumberOfPages)); + } + + return Status; } EFI_STATUS @@ -49,41 +72,16 @@ Ring3FreePages ( IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages ) -{ - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3GetMemoryMap ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion - ) -{ - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3AllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ) { EFI_STATUS Status; Status = SysCall ( - SysCallAllocatePool, - PoolType, - Size, - Buffer + SysCallFreePages, + Memory, + NumberOfPages ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate %d bytes.\n", Size)); + DEBUG ((DEBUG_ERROR, "Ring3: Failed to free %d pages.\n", NumberOfPages)); } return Status; @@ -91,21 +89,15 @@ Ring3AllocatePool ( EFI_STATUS EFIAPI -Ring3FreePool ( - IN VOID *Buffer +Ring3GetMemoryMap ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion ) { - EFI_STATUS Status; - - Status = SysCall ( - SysCallFreePool, - Buffer - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to free buffer.\n")); - } - - return Status; + return EFI_UNSUPPORTED; } EFI_STATUS @@ -614,3 +606,69 @@ Ring3CreateEventEx ( { return EFI_UNSUPPORTED; } + +EFI_STATUS +EFIAPI +CoreUpdateProfile ( + IN EFI_PHYSICAL_ADDRESS CallerAddress, + IN MEMORY_PROFILE_ACTION Action, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool + IN VOID *Buffer, + IN CHAR8 *ActionString OPTIONAL + ) +{ + return EFI_SUCCESS; +} + +VOID +InstallMemoryAttributesTableOnMemoryAllocation ( + IN EFI_MEMORY_TYPE MemoryType + ) +{ + return; +} + +BOOLEAN +EFIAPI +IsMemoryGuarded ( + IN EFI_PHYSICAL_ADDRESS Address + ) +{ + return FALSE; +} + +VOID * +CoreAllocatePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN NoPages, + IN UINTN Granularity, + IN BOOLEAN NeedGuard + ) +{ + EFI_PHYSICAL_ADDRESS Memory; + + Ring3AllocatePages (AllocateAnyPages, EfiRing3MemoryType, NoPages, &Memory); + + return (VOID *)Memory; +} + +VOID +CoreFreePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ) +{ + Ring3FreePages (Memory, NoPages); +} + +VOID +CoreFreePoolPagesWithGuard ( + IN EFI_MEMORY_TYPE PoolType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ) +{ + CoreFreePoolPagesI (PoolType, Memory, NoPages); +} diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index b61debf41d..6ca4b3d45f 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -1742,6 +1742,13 @@ CoreFreePages ( EFI_STATUS Status; EFI_MEMORY_TYPE MemoryType; + ApplyMemoryProtectionPolicy ( + EfiMaxMemoryType, + EfiConventionalMemory, + Memory, + EFI_PAGES_TO_SIZE (NumberOfPages) + ); + Status = CoreInternalFreePages (Memory, NumberOfPages, &MemoryType); if (!EFI_ERROR (Status)) { GuardFreedPagesChecked (Memory, NumberOfPages); @@ -1754,12 +1761,6 @@ CoreFreePages ( NULL ); InstallMemoryAttributesTableOnMemoryAllocation (MemoryType); - ApplyMemoryProtectionPolicy ( - MemoryType, - EfiConventionalMemory, - Memory, - EFI_PAGES_TO_SIZE (NumberOfPages) - ); } return Status; diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 1627b99868..6436566576 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -950,9 +950,6 @@ ApplyMemoryProtectionPolicy ( // policy is the same between OldType and NewType return EFI_SUCCESS; } - } else if (NewAttributes == 0) { - // newly added region of a type that does not require protection - return EFI_SUCCESS; } return gCpu->SetMemoryAttributes (gCpu, Memory, Length, NewAttributes); diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index c081e1c0e1..5cb08ce4fa 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -291,34 +291,6 @@ CallBootService ( return Status; - case SysCallAllocatePool: - // - // Argument 1: EFI_MEMORY_TYPE PoolType - // Argument 2: UINTN Size - // Argument 3: VOID **Buffer - // - DisableSMAP (); - Status = gBS->AllocatePool ( - EfiRing3MemoryType, - CoreRbp->Argument2, - (VOID **)CoreRbp->Argument3 - ); - EnableSMAP (); - - return Status; - - case SysCallFreePool: - // - // Argument 1: VOID *Buffer - // - DisableSMAP (); - Status = gBS->FreePool ( - (VOID *)CoreRbp->Argument1 - ); - EnableSMAP (); - - return Status; - case SysCallCloseProtocol: // // Argument 1: EFI_HANDLE CoreUserHandle @@ -379,6 +351,52 @@ CallBootService ( return Status; + case SysCallAllocatePages: + // + // Argument 1: EFI_ALLOCATE_TYPE Type + // Argument 2: EFI_MEMORY_TYPE MemoryType + // Argument 3: UINTN NumberOfPages + // Argument 4: EFI_PHYSICAL_ADDRESS *Memory + // + Status = gBS->AllocatePages ( + (EFI_ALLOCATE_TYPE)CoreRbp->Argument1, + (EFI_MEMORY_TYPE)CoreRbp->Argument2, + CoreRbp->Argument3, + (EFI_PHYSICAL_ADDRESS *)&Argument4 + ); + + DisableSMAP (); + *(EFI_PHYSICAL_ADDRESS *)UserRsp->Arguments[4] = (EFI_PHYSICAL_ADDRESS)Argument4; + EnableSMAP (); + + return Status; + + case SysCallFreePages: + // + // Argument 1: EFI_PHYSICAL_ADDRESS Memory + // Argument 2: UINTN NumberOfPages + // + return gBS->FreePages ( + (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, + CoreRbp->Argument2 + ); + + case SysCallRaiseTpl: + // + // Argument 1: EFI_TPL NewTpl + // + return (EFI_STATUS)gBS->RaiseTPL ( + (EFI_TPL)CoreRbp->Argument1 + ); + + case SysCallRestoreTpl: + // + // Argument 1: EFI_TPL NewTpl + // + gBS->RestoreTPL ((EFI_TPL)CoreRbp->Argument1); + + return EFI_SUCCESS; + case SysCallBlockIoReset: // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index b8b7790e6b..8c37d72be7 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2030,10 +2030,12 @@ typedef enum { SysCallLocateProtocol, SysCallOpenProtocol, SysCallInstallMultipleProtocolInterfaces, - SysCallAllocatePool, - SysCallFreePool, SysCallCloseProtocol, SysCallHandleProtocol, + SysCallAllocatePages, + SysCallFreePages, + SysCallRaiseTpl, + SysCallRestoreTpl, // // Protocols // From deded6820dee019df202e17fadb34982d5371caf Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 29 Feb 2024 11:57:30 +0300 Subject: [PATCH 169/341] MdeModulePkg: Refactored out CoreAcquireLockOrFail(), CoreAcquireLock() and CoreReleaseLock(). --- MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c | 4 +- MdeModulePkg/Core/Dxe/Event/Event.c | 4 +- MdeModulePkg/Core/Dxe/Event/Timer.c | 16 ++--- MdeModulePkg/Core/Dxe/Gcd/Gcd.c | 8 +-- MdeModulePkg/Core/Dxe/Hand/Handle.c | 4 +- MdeModulePkg/Core/Dxe/Hand/Locate.c | 2 +- .../Core/Dxe/Mem/MemoryProfileRecord.c | 4 +- MdeModulePkg/Core/Dxe/Mem/Page.c | 6 +- .../Core/Dxe/Misc/MemoryAttributesTable.c | 4 +- MdeModulePkg/Include/Library/MemoryPoolLib.h | 46 ------------- .../Library/MemoryPoolLib/InternalPool.c | 65 ------------------- .../Library/MemoryPoolLib/InternalPool.h | 3 + .../Library/MemoryPoolLib/MemoryPoolLib.inf | 1 - MdeModulePkg/Library/MemoryPoolLib/Pool.c | 8 +-- 14 files changed, 33 insertions(+), 142 deletions(-) delete mode 100644 MdeModulePkg/Library/MemoryPoolLib/InternalPool.c diff --git a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c index 6bd35b9d3d..d18599b2d2 100644 --- a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c +++ b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c @@ -204,7 +204,7 @@ CoreAcquireDispatcherLock ( VOID ) { - CoreAcquireLock (&mDispatcherLock); + EfiAcquireLock (&mDispatcherLock); } /** @@ -216,7 +216,7 @@ CoreReleaseDispatcherLock ( VOID ) { - CoreReleaseLock (&mDispatcherLock); + EfiReleaseLock (&mDispatcherLock); } /** diff --git a/MdeModulePkg/Core/Dxe/Event/Event.c b/MdeModulePkg/Core/Dxe/Event/Event.c index dc82abb021..a9896ea554 100644 --- a/MdeModulePkg/Core/Dxe/Event/Event.c +++ b/MdeModulePkg/Core/Dxe/Event/Event.c @@ -95,7 +95,7 @@ CoreAcquireEventLock ( VOID ) { - CoreAcquireLock (&gEventQueueLock); + EfiAcquireLock (&gEventQueueLock); } /** @@ -107,7 +107,7 @@ CoreReleaseEventLock ( VOID ) { - CoreReleaseLock (&gEventQueueLock); + EfiReleaseLock (&gEventQueueLock); } /** diff --git a/MdeModulePkg/Core/Dxe/Event/Timer.c b/MdeModulePkg/Core/Dxe/Event/Timer.c index 29e507c67c..c52925670d 100644 --- a/MdeModulePkg/Core/Dxe/Event/Timer.c +++ b/MdeModulePkg/Core/Dxe/Event/Timer.c @@ -74,9 +74,9 @@ CoreCurrentSystemTime ( { UINT64 SystemTime; - CoreAcquireLock (&mEfiSystemTimeLock); + EfiAcquireLock (&mEfiSystemTimeLock); SystemTime = mEfiSystemTime; - CoreReleaseLock (&mEfiSystemTimeLock); + EfiReleaseLock (&mEfiSystemTimeLock); return SystemTime; } @@ -102,7 +102,7 @@ CoreCheckTimers ( // // Check the timer database for expired timers // - CoreAcquireLock (&mEfiTimerLock); + EfiAcquireLock (&mEfiTimerLock); SystemTime = CoreCurrentSystemTime (); while (!IsListEmpty (&mEfiTimerList)) { @@ -151,7 +151,7 @@ CoreCheckTimers ( } } - CoreReleaseLock (&mEfiTimerLock); + EfiReleaseLock (&mEfiTimerLock); } /** @@ -194,7 +194,7 @@ CoreTimerTick ( // // Check runtiem flag in case there are ticks while exiting boot services // - CoreAcquireLock (&mEfiSystemTimeLock); + EfiAcquireLock (&mEfiSystemTimeLock); // // Update the system time @@ -213,7 +213,7 @@ CoreTimerTick ( } } - CoreReleaseLock (&mEfiSystemTimeLock); + EfiReleaseLock (&mEfiSystemTimeLock); } /** @@ -255,7 +255,7 @@ CoreSetTimer ( return EFI_INVALID_PARAMETER; } - CoreAcquireLock (&mEfiTimerLock); + EfiAcquireLock (&mEfiTimerLock); // // If the timer is queued to the timer database, remove it @@ -285,7 +285,7 @@ CoreSetTimer ( } } - CoreReleaseLock (&mEfiTimerLock); + EfiReleaseLock (&mEfiTimerLock); return EFI_SUCCESS; } diff --git a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c index 6ddbe60f07..301e54f5ca 100644 --- a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c +++ b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c @@ -267,7 +267,7 @@ CoreAcquireGcdMemoryLock ( VOID ) { - CoreAcquireLock (&mGcdMemorySpaceLock); + EfiAcquireLock (&mGcdMemorySpaceLock); } /** @@ -279,7 +279,7 @@ CoreReleaseGcdMemoryLock ( VOID ) { - CoreReleaseLock (&mGcdMemorySpaceLock); + EfiReleaseLock (&mGcdMemorySpaceLock); } /** @@ -291,7 +291,7 @@ CoreAcquireGcdIoLock ( VOID ) { - CoreAcquireLock (&mGcdIoSpaceLock); + EfiAcquireLock (&mGcdIoSpaceLock); } /** @@ -303,7 +303,7 @@ CoreReleaseGcdIoLock ( VOID ) { - CoreReleaseLock (&mGcdIoSpaceLock); + EfiReleaseLock (&mGcdIoSpaceLock); } // diff --git a/MdeModulePkg/Core/Dxe/Hand/Handle.c b/MdeModulePkg/Core/Dxe/Hand/Handle.c index 4a0f83ff2e..59bd63f745 100644 --- a/MdeModulePkg/Core/Dxe/Hand/Handle.c +++ b/MdeModulePkg/Core/Dxe/Hand/Handle.c @@ -30,7 +30,7 @@ CoreAcquireProtocolLock ( VOID ) { - CoreAcquireLock (&gProtocolDatabaseLock); + EfiAcquireLock (&gProtocolDatabaseLock); } /** @@ -42,7 +42,7 @@ CoreReleaseProtocolLock ( VOID ) { - CoreReleaseLock (&gProtocolDatabaseLock); + EfiReleaseLock (&gProtocolDatabaseLock); } /** diff --git a/MdeModulePkg/Core/Dxe/Hand/Locate.c b/MdeModulePkg/Core/Dxe/Hand/Locate.c index 8f20c6332d..674e414971 100644 --- a/MdeModulePkg/Core/Dxe/Hand/Locate.c +++ b/MdeModulePkg/Core/Dxe/Hand/Locate.c @@ -600,7 +600,7 @@ CoreLocateProtocol ( // // Lock the protocol database // - Status = CoreAcquireLockOrFail (&gProtocolDatabaseLock); + Status = EfiAcquireLockOrFail (&gProtocolDatabaseLock); if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; } diff --git a/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c b/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c index f19a5d8abd..168a27fef3 100644 --- a/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c +++ b/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c @@ -222,7 +222,7 @@ CoreAcquireMemoryProfileLock ( VOID ) { - CoreAcquireLock (&mMemoryProfileLock); + EfiAcquireLock (&mMemoryProfileLock); } /** @@ -233,7 +233,7 @@ CoreReleaseMemoryProfileLock ( VOID ) { - CoreReleaseLock (&mMemoryProfileLock); + EfiReleaseLock (&mMemoryProfileLock); } /** diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index 6ca4b3d45f..f479cea6b2 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -104,7 +104,7 @@ CoreAcquireMemoryLock ( VOID ) { - CoreAcquireLock (&gMemoryLock); + EfiAcquireLock (&gMemoryLock); } /** @@ -116,7 +116,7 @@ CoreReleaseMemoryLock ( VOID ) { - CoreReleaseLock (&gMemoryLock); + EfiReleaseLock (&gMemoryLock); } /** @@ -2204,7 +2204,7 @@ CoreAllocatePoolPagesI ( VOID *Buffer; EFI_STATUS Status; - Status = CoreAcquireLockOrFail (&gMemoryLock); + Status = EfiAcquireLockOrFail (&gMemoryLock); if (EFI_ERROR (Status)) { return NULL; } diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c index 6acd6126ed..11cb2b8deb 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c @@ -337,7 +337,7 @@ CoreAcquiremMemoryAttributesTableLock ( VOID ) { - CoreAcquireLock (&mMemoryAttributesTableLock); + EfiAcquireLock (&mMemoryAttributesTableLock); } /** @@ -349,7 +349,7 @@ CoreReleasemMemoryAttributesTableLock ( VOID ) { - CoreReleaseLock (&mMemoryAttributesTableLock); + EfiReleaseLock (&mMemoryAttributesTableLock); } /** diff --git a/MdeModulePkg/Include/Library/MemoryPoolLib.h b/MdeModulePkg/Include/Library/MemoryPoolLib.h index ff1da3cca8..787046f1de 100644 --- a/MdeModulePkg/Include/Library/MemoryPoolLib.h +++ b/MdeModulePkg/Include/Library/MemoryPoolLib.h @@ -198,50 +198,4 @@ IsMemoryTypeToGuard ( IN UINT8 PageOrPool ); -/** - Raising to the task priority level of the mutual exclusion - lock, and then acquires ownership of the lock. - - @param Lock The lock to acquire - - @return Lock owned - -**/ -VOID -CoreAcquireLock ( - IN EFI_LOCK *Lock - ); - -/** - Initialize a basic mutual exclusion lock. Each lock - provides mutual exclusion access at it's task priority - level. Since there is no-premption (at any TPL) or - multiprocessor support, acquiring the lock only consists - of raising to the locks TPL. - - @param Lock The EFI_LOCK structure to initialize - - @retval EFI_SUCCESS Lock Owned. - @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned. - -**/ -EFI_STATUS -CoreAcquireLockOrFail ( - IN EFI_LOCK *Lock - ); - -/** - Releases ownership of the mutual exclusion lock, and - restores the previous task priority level. - - @param Lock The lock to release - - @return Lock unowned - -**/ -VOID -CoreReleaseLock ( - IN EFI_LOCK *Lock - ); - #endif diff --git a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.c b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.c deleted file mode 100644 index 5e506e080b..0000000000 --- a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.c +++ /dev/null @@ -1,65 +0,0 @@ -/** @file - DXE Core functions necessary for pool management functions. - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include -#include - -/** - Initialize a basic mutual exclusion lock. Each lock - provides mutual exclusion access at it's task priority - level. Since there is no-premption (at any TPL) or - multiprocessor support, acquiring the lock only consists - of raising to the locks TPL. - - @param Lock The EFI_LOCK structure to initialize - - @retval EFI_SUCCESS Lock Owned. - @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned. - -**/ -EFI_STATUS -CoreAcquireLockOrFail ( - IN EFI_LOCK *Lock - ) -{ - return EfiAcquireLockOrFail (Lock); -} - -/** - Raising to the task priority level of the mutual exclusion - lock, and then acquires ownership of the lock. - - @param Lock The lock to acquire - - @return Lock owned - -**/ -VOID -CoreAcquireLock ( - IN EFI_LOCK *Lock - ) -{ - EfiAcquireLock (Lock); -} - -/** - Releases ownership of the mutual exclusion lock, and - restores the previous task priority level. - - @param Lock The lock to release - - @return Lock unowned - -**/ -VOID -CoreReleaseLock ( - IN EFI_LOCK *Lock - ) -{ - EfiReleaseLock (Lock); -} diff --git a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h index b0bb574f21..e800fd7acb 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h +++ b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h @@ -4,6 +4,9 @@ Copyright (c) 2024, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + **/ #ifndef _INTERNAL_POOL_H_ diff --git a/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf b/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf index 91bbda57a3..acc7c606be 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf +++ b/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf @@ -20,7 +20,6 @@ # [Sources] - InternalPool.c InternalPool.h Pool.c diff --git a/MdeModulePkg/Library/MemoryPoolLib/Pool.c b/MdeModulePkg/Library/MemoryPoolLib/Pool.c index a35fa80058..19cb969d51 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/Pool.c +++ b/MdeModulePkg/Library/MemoryPoolLib/Pool.c @@ -310,13 +310,13 @@ CoreInternalAllocatePool ( // // Acquire the memory lock and make the allocation // - Status = CoreAcquireLockOrFail (&mPoolMemoryLock); + Status = EfiAcquireLockOrFail (&mPoolMemoryLock); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } *Buffer = CoreAllocatePoolI (PoolType, Size, NeedGuard); - CoreReleaseLock (&mPoolMemoryLock); + EfiReleaseLock (&mPoolMemoryLock); return (*Buffer != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES; } @@ -596,9 +596,9 @@ CoreInternalFreePool ( return EFI_INVALID_PARAMETER; } - CoreAcquireLock (&mPoolMemoryLock); + EfiAcquireLock (&mPoolMemoryLock); Status = CoreFreePoolI (Buffer, PoolType); - CoreReleaseLock (&mPoolMemoryLock); + EfiReleaseLock (&mPoolMemoryLock); return Status; } From 8a88be66b32a1558ac8272593da7a449b1e33f42 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 29 Feb 2024 12:25:40 +0300 Subject: [PATCH 170/341] DxeRing3: Added FixInterface(). --- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 122 +++++++++--------- 1 file changed, 64 insertions(+), 58 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 2fc863a1e4..addb5c5d84 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -17,6 +17,67 @@ BOOLEAN mOnGuarding = FALSE; +STATIC +EFI_STATUS +EFIAPI +FixInterface ( + IN EFI_GUID *Protocol, + IN OUT VOID **Interface + ) +{ + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_DEVICE_PATH_UTILITIES_PROTOCOL *DevicePath; + + ASSERT (Protocol != NULL); + ASSERT (Interface != NULL); + + if (CompareGuid (Protocol, &gEfiDevicePathProtocolGuid)) { + + } else if (CompareGuid (Protocol, &gEfiLoadedImageProtocolGuid)) { + + LoadedImage = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; + + // TODO: Copy User changes to Core? Resembles InstallMultipleProtocolInterfaces(). + + LoadedImage->Unload = NULL; + + } else if (CompareGuid (Protocol, &gEfiBlockIoProtocolGuid)) { + + BlockIo = (EFI_BLOCK_IO_PROTOCOL *)*Interface; + + BlockIo->Reset = Ring3BlockIoReset; + BlockIo->ReadBlocks = Ring3BlockIoRead; + BlockIo->WriteBlocks = Ring3BlockIoWrite; + BlockIo->FlushBlocks = Ring3BlockIoFlush; + + } else if (CompareGuid (Protocol, &gEfiDiskIoProtocolGuid)) { + + DiskIo = (EFI_DISK_IO_PROTOCOL *)*Interface; + + DiskIo->ReadDisk = Ring3DiskIoRead; + DiskIo->WriteDisk = Ring3DiskIoWrite; + + } else if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { + DevicePath = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; + + DevicePath->GetDevicePathSize = NULL; + DevicePath->DuplicateDevicePath = NULL; + DevicePath->AppendDevicePath = NULL; + DevicePath->AppendDeviceNode = NULL; + DevicePath->AppendDevicePathInstance = NULL; + DevicePath->GetNextDevicePathInstance = NULL; + DevicePath->IsDevicePathMultiInstance = NULL; + DevicePath->CreateDeviceNode = NULL; + + } else { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + EFI_TPL EFIAPI Ring3RaiseTpl ( @@ -218,13 +279,7 @@ Ring3HandleProtocol ( return Status; } - if (CompareGuid (Protocol, &gEfiDevicePathProtocolGuid)) { - Status = EFI_SUCCESS; - } else { - Status = EFI_UNSUPPORTED; - } - - return Status; + return FixInterface (Protocol, Interface); } EFI_STATUS @@ -394,10 +449,6 @@ Ring3OpenProtocol ( { EFI_STATUS Status; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_DISK_IO_PROTOCOL *DiskIo; - Status = SysCall ( SysCallOpenProtocol, CoreUserHandle, @@ -411,35 +462,7 @@ Ring3OpenProtocol ( return Status; } - if (CompareGuid (Protocol, &gEfiLoadedImageProtocolGuid)) { - - LoadedImage = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; - - // TODO: Copy User changes to Core? Resembles InstallMultipleProtocolInterfaces(). - - LoadedImage->Unload = NULL; - - } else if (CompareGuid (Protocol, &gEfiBlockIoProtocolGuid)) { - - BlockIo = (EFI_BLOCK_IO_PROTOCOL *)*Interface; - - BlockIo->Reset = Ring3BlockIoReset; - BlockIo->ReadBlocks = Ring3BlockIoRead; - BlockIo->WriteBlocks = Ring3BlockIoWrite; - BlockIo->FlushBlocks = Ring3BlockIoFlush; - - } else if (CompareGuid (Protocol, &gEfiDiskIoProtocolGuid)) { - - DiskIo = (EFI_DISK_IO_PROTOCOL *)*Interface; - - DiskIo->ReadDisk = Ring3DiskIoRead; - DiskIo->WriteDisk = Ring3DiskIoWrite; - - } else { - Status = EFI_UNSUPPORTED; - } - - return Status; + return FixInterface (Protocol, Interface); } EFI_STATUS @@ -506,8 +529,6 @@ Ring3LocateProtocol ( { EFI_STATUS Status; - EFI_DEVICE_PATH_UTILITIES_PROTOCOL *DevicePath; - Status = SysCall ( SysCallLocateProtocol, Protocol, @@ -519,22 +540,7 @@ Ring3LocateProtocol ( return Status; } - if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { - DevicePath = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; - - DevicePath->GetDevicePathSize = NULL; - DevicePath->DuplicateDevicePath = NULL; - DevicePath->AppendDevicePath = NULL; - DevicePath->AppendDeviceNode = NULL; - DevicePath->AppendDevicePathInstance = NULL; - DevicePath->GetNextDevicePathInstance = NULL; - DevicePath->IsDevicePathMultiInstance = NULL; - DevicePath->CreateDeviceNode = NULL; - - return Status; - } - - return EFI_UNSUPPORTED; + return FixInterface (Protocol, Interface); } EFI_STATUS From 87c3c580173bd931cebbb784beb7c12a24a68d2e Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 29 Feb 2024 12:42:54 +0300 Subject: [PATCH 171/341] SysCall: Fixed bug in BlockIo, DiskIo Write functions. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 5cb08ce4fa..2fa445ceab 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -456,6 +456,10 @@ CallBootService ( return EFI_OUT_OF_RESOURCES; } + DisableSMAP (); + CopyMem ((VOID *)Argument5,(VOID *)UserRsp->Arguments[5], Argument4); + EnableSMAP (); + Status = mCoreBlockIoProtocol->WriteBlocks ( mCoreBlockIoProtocol, (UINT32)CoreRbp->Argument2, @@ -463,9 +467,6 @@ CallBootService ( Argument4, (VOID *)Argument5 ); - DisableSMAP (); - CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); - EnableSMAP (); FreePool ((VOID *)Argument5); @@ -528,6 +529,10 @@ CallBootService ( return EFI_OUT_OF_RESOURCES; } + DisableSMAP (); + CopyMem ((VOID *)Argument5, (VOID *)UserRsp->Arguments[5], Argument4); + EnableSMAP (); + Status = mCoreDiskIoProtocol->WriteDisk ( mCoreDiskIoProtocol, (UINT32)CoreRbp->Argument2, @@ -535,9 +540,6 @@ CallBootService ( Argument4, (VOID *)Argument5 ); - DisableSMAP (); - CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); - EnableSMAP (); FreePool ((VOID *)Argument5); From b05242aadb51d6dcd9ccac9ca5fb249570ccf178 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 29 Feb 2024 20:19:02 +0300 Subject: [PATCH 172/341] Ring3: Added PrepareRing3Interface(). --- MdeModulePkg/Core/Dxe/DxeMain.h | 5 ++ MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 10 +++ .../Core/Dxe/DxeRing3/Ring3Protocols.c | 3 - MdeModulePkg/Core/Dxe/Image/Image.c | 53 ++++++++---- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 83 +++++++++++-------- 5 files changed, 102 insertions(+), 52 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 3db3ec8d3f..efcd5e198d 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -116,6 +116,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define DEPEX_STACK_SIZE_INCREMENT 0x1000 #define USER_STACK_SIZE 0x20000 +#define RING3_INTERFACES_PAGES 20 typedef struct { EFI_GUID *ProtocolGuid; @@ -270,6 +271,10 @@ extern EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate; extern EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE gLoadModuleAtFixAddressConfigurationTable; extern BOOLEAN gLoadFixedAddressCodeMemoryReady; extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage; + +extern RING3_DATA *gRing3Data; +extern VOID *gRing3Interfaces; + // // Service Initialization Functions // diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 937194f4fc..1e9fd2a3c2 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -851,6 +851,16 @@ CoreExitBootServices ( // gRuntime->AtRuntime = TRUE; + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)gRing3Data, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + ); + + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)gRing3Interfaces, + RING3_INTERFACES_PAGES + ); + return Status; } diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c index 2bd03a1a37..a3b082af82 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c @@ -7,9 +7,6 @@ #include "Ring3.h" -EFI_BLOCK_IO_PROTOCOL mCoreBlockIo; -EFI_DISK_IO_PROTOCOL mCoreDiskIo; - EFI_STATUS EFIAPI Ring3BlockIoReset ( diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 23f5c535e3..ab839f4001 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -30,7 +30,8 @@ extern BOOLEAN gBdsStarted; VOID *gCoreSysCallStackTop; VOID *gRing3CallStackTop; VOID *gRing3EntryPoint; -RING3_DATA *mRing3Data; +RING3_DATA *gRing3Data; +VOID *gRing3Interfaces; // // This code is needed to build the Image handle for the DXE Core @@ -1593,13 +1594,14 @@ AllocateRing3Copy ( return MemoryRing3; } -VOID +EFI_STATUS EFIAPI InitializeRing3 ( IN EFI_HANDLE ImageHandle, IN LOADED_IMAGE_PRIVATE_DATA *Image ) { + EFI_STATUS Status; VOID *BaseOfStack; VOID *TopOfStack; UINTN SizeOfStack; @@ -1616,18 +1618,39 @@ InitializeRing3 ( // // Set Ring3 EntryPoint and BootServices. // - mRing3Data = AllocateRing3Copy ( - (VOID *)Image->Info.SystemTable, - sizeof (RING3_DATA), - sizeof (EFI_SYSTEM_TABLE) - ); - ASSERT (mRing3Data != NULL); - - Image->Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)mRing3Data); + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)), + (EFI_PHYSICAL_ADDRESS *)&gRing3Data + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Data.\n")); + return Status; + } + + CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); - gRing3EntryPoint = mRing3Data->EntryPoint; + Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); - mRing3Data->SystemTable.BootServices = mRing3Data->BootServices; + gRing3EntryPoint = gRing3Data->EntryPoint; + + gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + RING3_INTERFACES_PAGES, + (EFI_PHYSICAL_ADDRESS *)&gRing3Interfaces + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Interfaces.\n")); + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)gRing3Data, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + ); + return Status; + } // // Forbid supervisor-mode accesses to any user-mode pages. @@ -1703,6 +1726,8 @@ InitializeRing3 ( Msr = (UINT64)(UINTN)CoreBootServices; AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); + + return Status; } /** @@ -1832,7 +1857,7 @@ CoreStartImage ( Image->Started = TRUE; if (Image->IsRing3EntryPoint) { - InitializeRing3 (ImageHandle, Image); + Image->Status = InitializeRing3 (ImageHandle, Image); } else if (Image->IsUserImage) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1841,7 +1866,7 @@ CoreStartImage ( 2, (VOID *)Image->EntryPoint, ImageHandle, - mRing3Data + gRing3Data ); } else { Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 2fa445ceab..b17f748676 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -10,6 +10,7 @@ EFI_DISK_IO_PROTOCOL *mCoreDiskIoProtocol; EFI_BLOCK_IO_PROTOCOL *mCoreBlockIoProtocol; +UINTN mRing3InterfacePointer = 0; EFI_STATUS EFIAPI @@ -20,6 +21,7 @@ CallInstallMultipleProtocolInterfaces ( IN VOID *Function ); +STATIC EFI_STATUS EFIAPI FindGuid ( @@ -79,24 +81,56 @@ FindGuid ( return EFI_SUCCESS; } -VOID +STATIC +VOID * EFIAPI -FixInterface ( - IN EFI_GUID *Guid, - IN OUT VOID *Interface +PrepareRing3Interface ( + IN EFI_GUID *Guid, + IN VOID *CoreInterface, + IN UINT32 CoreSize ) { + UINTN Ring3Limit; + VOID *Ring3Interface; EFI_BLOCK_IO_PROTOCOL *BlockIo; - if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) { - BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Interface; + ASSERT (Guid != NULL); + ASSERT (CoreInterface != NULL); - BlockIo->Media = AllocateRing3Copy ( - BlockIo->Media, - sizeof (EFI_BLOCK_IO_MEDIA), - sizeof (EFI_BLOCK_IO_MEDIA) - ); + if (mRing3InterfacePointer == 0) { + mRing3InterfacePointer = (UINTN)gRing3Interfaces; } + + Ring3Limit = (UINTN)gRing3Interfaces + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES); + + ASSERT ((mRing3InterfacePointer + sizeof (EFI_GUID) + CoreSize) <= Ring3Limit); + + CopyMem ((VOID *)mRing3InterfacePointer, (VOID *)Guid, sizeof (EFI_GUID)); + mRing3InterfacePointer += sizeof (EFI_GUID); + + Ring3Interface = (VOID *)mRing3InterfacePointer; + + CopyMem ((VOID *)mRing3InterfacePointer, CoreInterface, CoreSize); + mRing3InterfacePointer += CoreSize; + + if (CompareGuid (Guid, &gEfiDiskIoProtocolGuid)) { + + mCoreDiskIoProtocol = (EFI_DISK_IO_PROTOCOL *)CoreInterface; + + } else if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) { + ASSERT ((mRing3InterfacePointer + sizeof (EFI_BLOCK_IO_MEDIA)) <= Ring3Limit); + + mCoreBlockIoProtocol = (EFI_BLOCK_IO_PROTOCOL *)CoreInterface; + BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Ring3Interface; + + CopyMem ((VOID *)mRing3InterfacePointer, (VOID *)BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA)); + + BlockIo->Media = (EFI_BLOCK_IO_MEDIA *)mRing3InterfacePointer; + + mRing3InterfacePointer += sizeof (EFI_BLOCK_IO_MEDIA); + } + + return Ring3Interface; } typedef struct { @@ -170,11 +204,7 @@ CallBootService ( DisableSMAP (); if (Interface != NULL) { - Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); - if (Interface == NULL) { - EnableSMAP (); - return EFI_OUT_OF_RESOURCES; - } + Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); } *(VOID **)CoreRbp->Argument3 = Interface; @@ -214,19 +244,7 @@ CallBootService ( DisableSMAP (); if (Interface != NULL) { - if (CompareGuid (CoreProtocol, &gEfiDiskIoProtocolGuid)) { - mCoreDiskIoProtocol = (EFI_DISK_IO_PROTOCOL *)Interface; - } else if (CompareGuid (CoreProtocol, &gEfiBlockIoProtocolGuid)) { - mCoreBlockIoProtocol = (EFI_BLOCK_IO_PROTOCOL *)Interface; - } - - Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); - if (Interface == NULL) { - EnableSMAP (); - return EFI_OUT_OF_RESOURCES; - } - - FixInterface (CoreProtocol, Interface); + Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); } *(VOID **)CoreRbp->Argument3 = Interface; @@ -338,12 +356,7 @@ CallBootService ( DisableSMAP (); if (Interface != NULL) { - - Interface = AllocateRing3Copy (Interface, MemoryCoreSize, MemoryCoreSize); - if (Interface == NULL) { - EnableSMAP (); - return EFI_OUT_OF_RESOURCES; - } + Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); } *(VOID **)CoreRbp->Argument3 = Interface; From c67e58deea1be34354241f64ee3acf6589fbbf5b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 29 Feb 2024 20:53:02 +0300 Subject: [PATCH 173/341] Ring3: Refactored out AllocateRing3Copy(). --- MdeModulePkg/Core/Dxe/DxeMain.h | 8 --- MdeModulePkg/Core/Dxe/Image/Image.c | 24 ------- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 12 ++-- .../Core/Dxe/SysCall/SupportedProtocols.c | 67 ++++++++++--------- 4 files changed, 41 insertions(+), 70 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index efcd5e198d..353561c627 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -1172,14 +1172,6 @@ CoreAllocatePages ( IN OUT EFI_PHYSICAL_ADDRESS *Memory ); -VOID * -EFIAPI -AllocateRing3Copy ( - IN VOID *Source, - IN UINT32 AllocationSize, - IN UINT32 CopySize - ); - /** Frees previous allocated pages. diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index ab839f4001..4c8c877595 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1570,30 +1570,6 @@ CoreLoadImage ( return Status; } -VOID * -EFIAPI -AllocateRing3Copy ( - IN VOID *Source, - IN UINT32 AllocationSize, - IN UINT32 CopySize - ) -{ - EFI_STATUS Status; - VOID *MemoryRing3; - - Status = CoreAllocatePool (EfiRing3MemoryType, AllocationSize, &MemoryRing3); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate %d bytes for Ring3.\n", AllocationSize)); - return NULL; - } - - ASSERT (CopySize <= AllocationSize); - - CopyMem (MemoryRing3, Source, CopySize); - - return MemoryRing3; -} - EFI_STATUS EFIAPI InitializeRing3 ( diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index b17f748676..d494ae7622 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -103,10 +103,7 @@ PrepareRing3Interface ( Ring3Limit = (UINTN)gRing3Interfaces + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES); - ASSERT ((mRing3InterfacePointer + sizeof (EFI_GUID) + CoreSize) <= Ring3Limit); - - CopyMem ((VOID *)mRing3InterfacePointer, (VOID *)Guid, sizeof (EFI_GUID)); - mRing3InterfacePointer += sizeof (EFI_GUID); + ASSERT ((mRing3InterfacePointer + CoreSize) <= Ring3Limit); Ring3Interface = (VOID *)mRing3InterfacePointer; @@ -265,7 +262,12 @@ CallBootService ( Status = FindGuid ((EFI_GUID *)UserArgList[Index], (EFI_GUID **)&CoreArgList[Index], &MemoryCoreSize); if (EFI_ERROR (Status)) { EnableSMAP (); - //TODO: Free CoreArgList. + + while (Index > 0) { + FreePool (CoreArgList[Index - 1]); + Index -= 2; + } + return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index edca2fd49f..4639fe6e11 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -77,6 +77,34 @@ GoToRing3 ( return Status; } +STATIC +EFIAPI +VOID * +Ring3Copy ( + IN VOID *Core, + IN UINT32 Size + ) +{ + EFI_STATUS Status; + VOID *Ring3; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + 1, + (EFI_PHYSICAL_ADDRESS *)&Ring3 + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + DisableSMAP (); + CopyMem (Ring3, Core, Size); + EnableSMAP (); + + return Ring3; +} + EFI_STATUS EFIAPI CoreDriverBindingSupported ( @@ -87,17 +115,10 @@ CoreDriverBindingSupported ( { EFI_STATUS Status; - DisableSMAP (); - This = AllocateRing3Copy ( - This, - sizeof (EFI_DRIVER_BINDING_PROTOCOL), - sizeof (EFI_DRIVER_BINDING_PROTOCOL) - ); + This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); if (This == NULL) { - EnableSMAP (); return EFI_OUT_OF_RESOURCES; } - EnableSMAP (); Status = GoToRing3 ( 3, @@ -107,9 +128,7 @@ CoreDriverBindingSupported ( RemainingDevicePath ); - DisableSMAP (); - FreePool (This); - EnableSMAP (); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)This, 1); return Status; } @@ -124,17 +143,10 @@ CoreDriverBindingStart ( { EFI_STATUS Status; - DisableSMAP (); - This = AllocateRing3Copy ( - This, - sizeof (EFI_DRIVER_BINDING_PROTOCOL), - sizeof (EFI_DRIVER_BINDING_PROTOCOL) - ); + This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); if (This == NULL) { - EnableSMAP (); return EFI_OUT_OF_RESOURCES; } - EnableSMAP (); Status = GoToRing3 ( 3, @@ -144,9 +156,7 @@ CoreDriverBindingStart ( RemainingDevicePath ); - DisableSMAP (); - FreePool (This); - EnableSMAP (); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)This, 1); return Status; } @@ -162,17 +172,10 @@ CoreDriverBindingStop ( { EFI_STATUS Status; - DisableSMAP (); - This = AllocateRing3Copy ( - This, - sizeof (EFI_DRIVER_BINDING_PROTOCOL), - sizeof (EFI_DRIVER_BINDING_PROTOCOL) - ); + This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); if (This == NULL) { - EnableSMAP (); return EFI_OUT_OF_RESOURCES; } - EnableSMAP (); Status = GoToRing3 ( 4, @@ -183,9 +186,7 @@ CoreDriverBindingStop ( ChildHandleBuffer ); - DisableSMAP (); - FreePool (This); - EnableSMAP (); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)This, 1); return Status; } From 8b4e26ad8f621385ce45dc300d4e04b330ce08ae Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 1 Mar 2024 12:10:21 +0300 Subject: [PATCH 174/341] SysCall: Refactored EFI_FILE_PROTOCOL wrappers. --- .../Core/Dxe/SysCall/SupportedProtocols.c | 248 +++++++++--------- 1 file changed, 123 insertions(+), 125 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 4639fe6e11..07dd4a9f6e 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -237,33 +237,38 @@ CoreFileRead ( RING3_EFI_FILE_PROTOCOL *File; UINTN *Ring3BufferSize; VOID *Ring3Buffer; + VOID *Ring3Pages; + UINT32 PagesNumber; - File = (RING3_EFI_FILE_PROTOCOL *)This; - Ring3Buffer = NULL; - Ring3BufferSize = NULL; + if ((This == NULL) || (BufferSize == NULL)) { + return EFI_INVALID_PARAMETER; + } - DisableSMAP (); - if (BufferSize != NULL) { - Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (UINTN *), (VOID **)&Ring3BufferSize); - if (EFI_ERROR (Status)) { - EnableSMAP (); - return Status; - } - - *Ring3BufferSize = *BufferSize; + File = (RING3_EFI_FILE_PROTOCOL *)This; + Ring3Buffer = NULL; + Ring3Pages = NULL; + + PagesNumber = EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + (EFI_PHYSICAL_ADDRESS *)&Ring3Pages + ); + if (EFI_ERROR (Status)) { + return Status; } + Ring3BufferSize = (UINTN *)Ring3Pages; + + DisableSMAP (); + *Ring3BufferSize = *BufferSize; + EnableSMAP (); + if (Buffer != NULL) { - Status = CoreAllocatePool (EfiRing3MemoryType, *BufferSize, (VOID **)&Ring3Buffer); - if (EFI_ERROR (Status)) { - if (Ring3BufferSize != NULL) { - FreePool (Ring3BufferSize); - } - EnableSMAP (); - return Status; - } + Ring3Buffer = (VOID *)((UINTN *)Ring3Pages + 1); } - EnableSMAP (); Status = GoToRing3 ( 3, @@ -278,17 +283,11 @@ CoreFileRead ( CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); } - if (Ring3Buffer != NULL) { - FreePool (Ring3Buffer); - } - - if (Ring3BufferSize != NULL) { - *BufferSize = *Ring3BufferSize; - - FreePool (Ring3BufferSize); - } + *BufferSize = *Ring3BufferSize; EnableSMAP (); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Pages, PagesNumber); + return Status; } @@ -336,21 +335,27 @@ CoreFileGetPosition ( RING3_EFI_FILE_PROTOCOL *File; UINT64 *Ring3Position; + if ((This == NULL) || (Position == NULL)) { + return EFI_INVALID_PARAMETER; + } + File = (RING3_EFI_FILE_PROTOCOL *)This; Ring3Position = NULL; - if (Position != NULL) { - DisableSMAP (); - Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (UINT64), (VOID **)&Ring3Position); - if (EFI_ERROR (Status)) { - EnableSMAP (); - return Status; - } - - *Ring3Position = *Position; - EnableSMAP (); + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + 1, + (EFI_PHYSICAL_ADDRESS *)&Ring3Position + ); + if (EFI_ERROR (Status)) { + return Status; } + DisableSMAP (); + *Ring3Position = *Position; + EnableSMAP (); + Status = GoToRing3 ( 2, (VOID *)mRing3FileProtocol.GetPosition, @@ -358,13 +363,11 @@ CoreFileGetPosition ( Ring3Position ); - if (Ring3Position != NULL) { - DisableSMAP (); - *Position = *Ring3Position; + DisableSMAP (); + *Position = *Ring3Position; + EnableSMAP (); - FreePool (Ring3Position); - EnableSMAP (); - } + CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Position, 1); return Status; } @@ -384,50 +387,47 @@ CoreFileGetInfo ( EFI_GUID *Ring3InformationType; UINTN *Ring3BufferSize; VOID *Ring3Buffer; + VOID *Ring3Pages; + UINT32 PagesNumber; + + if ((This == NULL) || (BufferSize == NULL)) { + return EFI_INVALID_PARAMETER; + } File = (RING3_EFI_FILE_PROTOCOL *)This; Ring3Buffer = NULL; - Ring3BufferSize = NULL; Ring3InformationType = NULL; + Ring3Pages = NULL; - DisableSMAP (); - if (BufferSize != NULL) { - Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (UINTN *), (VOID **)&Ring3BufferSize); - if (EFI_ERROR (Status)) { - EnableSMAP (); - return Status; - } - - *Ring3BufferSize = *BufferSize; + PagesNumber = EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize + sizeof (EFI_GUID)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + (EFI_PHYSICAL_ADDRESS *)&Ring3Pages + ); + if (EFI_ERROR (Status)) { + return Status; } + Ring3BufferSize = (UINTN *)Ring3Pages; + + DisableSMAP (); + *Ring3BufferSize = *BufferSize; + EnableSMAP (); + if (Buffer != NULL) { - Status = CoreAllocatePool (EfiRing3MemoryType, *BufferSize, (VOID **)&Ring3Buffer); - if (EFI_ERROR (Status)) { - if (Ring3BufferSize != NULL) { - FreePool (Ring3BufferSize); - } - EnableSMAP (); - return Status; - } + Ring3Buffer = (VOID *)((UINTN *)Ring3Pages + 1); } if (InformationType != NULL) { - Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (EFI_GUID), (VOID **)&Ring3InformationType); - if (EFI_ERROR (Status)) { - if (Ring3BufferSize != NULL) { - FreePool (Ring3BufferSize); - } - if (Ring3Buffer != NULL) { - FreePool (Ring3Buffer); - } - EnableSMAP (); - return Status; - } + Ring3InformationType = (EFI_GUID *)((UINTN)Ring3Pages + sizeof (UINTN *) + *BufferSize); + DisableSMAP (); CopyGuid (Ring3InformationType, InformationType); + EnableSMAP (); } - EnableSMAP (); Status = GoToRing3 ( 4, @@ -443,21 +443,11 @@ CoreFileGetInfo ( CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); } - if (Ring3BufferSize != NULL) { - *BufferSize = *Ring3BufferSize; - - FreePool (Ring3BufferSize); - } - - if (Ring3Buffer != NULL) { - FreePool (Ring3Buffer); - } - - if (Ring3InformationType != NULL) { - FreePool (Ring3InformationType); - } + *BufferSize = *Ring3BufferSize; EnableSMAP (); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Pages, PagesNumber); + return Status; } @@ -548,31 +538,42 @@ CoreFileOpen ( RING3_EFI_FILE_PROTOCOL *NewFile; EFI_FILE_PROTOCOL **Ring3NewHandle; CHAR16 *Ring3FileName; + VOID *Ring3Pages; + UINT32 PagesNumber; - File = (RING3_EFI_FILE_PROTOCOL *)This; - - DisableSMAP (); - Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (EFI_FILE_PROTOCOL *), (VOID **)&Ring3NewHandle); - if (EFI_ERROR (Status)) { - EnableSMAP (); - return Status; + if ((This == NULL) || (NewHandle == NULL) || (FileName == NULL)) { + return EFI_INVALID_PARAMETER; } - Status = CoreAllocatePool (EfiRing3MemoryType, StrSize (FileName), (VOID **)&Ring3FileName); + File = (RING3_EFI_FILE_PROTOCOL *)This; + Ring3NewHandle = NULL; + Ring3FileName = NULL; + Ring3Pages = NULL; + + PagesNumber = EFI_SIZE_TO_PAGES (sizeof (EFI_FILE_PROTOCOL *) + StrSize (FileName)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + (EFI_PHYSICAL_ADDRESS *)&Ring3Pages + ); if (EFI_ERROR (Status)) { - FreePool (Ring3NewHandle); - EnableSMAP (); + *NewHandle = NULL; return Status; } + Ring3NewHandle = (EFI_FILE_PROTOCOL **)Ring3Pages; + Ring3FileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)Ring3Pages + 1); + + DisableSMAP (); Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName); + EnableSMAP (); if (EFI_ERROR (Status)) { - FreePool (Ring3NewHandle); - FreePool (Ring3FileName); - EnableSMAP (); + *NewHandle = NULL; + CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Pages, PagesNumber); return Status; } - EnableSMAP (); Status = GoToRing3 ( 5, @@ -585,20 +586,14 @@ CoreFileOpen ( ); if (EFI_ERROR (Status)) { *NewHandle = NULL; - DisableSMAP (); - FreePool (Ring3NewHandle); - FreePool (Ring3FileName); - EnableSMAP (); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Pages, PagesNumber); return Status; } NewFile = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); if (NewFile == NULL) { *NewHandle = NULL; - DisableSMAP (); - FreePool (Ring3NewHandle); - FreePool (Ring3FileName); - EnableSMAP (); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Pages, PagesNumber); return EFI_OUT_OF_RESOURCES; } @@ -620,13 +615,12 @@ CoreFileOpen ( DisableSMAP (); NewFile->Ring3File = *Ring3NewHandle; - - FreePool (Ring3NewHandle); - FreePool (Ring3FileName); EnableSMAP (); *NewHandle = (EFI_FILE_PROTOCOL *)NewFile; + CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Pages, PagesNumber); + return Status; } @@ -641,10 +635,18 @@ CoreOpenVolume ( EFI_FILE_PROTOCOL **Ring3Root; RING3_EFI_FILE_PROTOCOL *File; - DisableSMAP (); - Status = CoreAllocatePool (EfiRing3MemoryType, sizeof (EFI_FILE_PROTOCOL *), (VOID **)&Ring3Root); - EnableSMAP (); + if (Root == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + 1, + (EFI_PHYSICAL_ADDRESS *)&Ring3Root + ); if (EFI_ERROR (Status)) { + *Root = NULL; return Status; } @@ -656,18 +658,14 @@ CoreOpenVolume ( ); if (EFI_ERROR (Status)) { *Root = NULL; - DisableSMAP (); - FreePool (Ring3Root); - EnableSMAP (); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Root, 1); return Status; } File = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); if (File == NULL) { *Root = NULL; - DisableSMAP (); - FreePool (Ring3Root); - EnableSMAP (); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Root, 1); return EFI_OUT_OF_RESOURCES; } @@ -689,8 +687,6 @@ CoreOpenVolume ( mRing3FileProtocol.FlushEx = (*Ring3Root)->FlushEx; File->Ring3File = *Ring3Root; - - FreePool (Ring3Root); EnableSMAP (); File->Protocol.Revision = mRing3FileProtocol.Revision; @@ -711,5 +707,7 @@ CoreOpenVolume ( *Root = (EFI_FILE_PROTOCOL *)File; + CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Root, 1); + return Status; } From 0cdb4c67ca6e0a9a1ae161b85228612ff4de0d5a Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 5 Mar 2024 10:04:50 +0300 Subject: [PATCH 175/341] Ring3: Fixed interrrupts handling. --- .../Dxe/SysCall/X64/CoreBootServices.nasm | 11 +++++++ .../X64/ExceptionHandlerAsm.nasm | 29 ++++++++++++++++--- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 79ba899087..7a89cded04 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -113,6 +113,7 @@ copy: ;------------------------------------------------------------------------------ global ASM_PFX(CoreBootServices) ASM_PFX(CoreBootServices): + cli ; Save User data segment selector temporarily in R11. mov r11, ds @@ -148,8 +149,12 @@ ASM_PFX(CoreBootServices): mov rdx, rbp mov r8, [rbp + 8*6] + sti + call ASM_PFX(CallBootService) + cli + ; Step over Arguments [1..3]. add rsp, 8*3 @@ -170,6 +175,8 @@ o16 mov gs, r11 pop rbp pop rsp + sti + ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. o64 sysret ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. @@ -185,6 +192,7 @@ o64 sysret ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): + cli ; Save input Arguments. push r12 mov r12, rcx @@ -217,6 +225,8 @@ ASM_PFX(CallRing3): mov rsp, [ASM_PFX(gRing3CallStackTop)] mov rbp, rsp + sti + ; Pass control to user image o64 sysret @@ -224,6 +234,7 @@ coreReturnAddress: mov rsp, [ASM_PFX(CoreRsp)] mov rbp, [ASM_PFX(CoreRbp)] mov rax, rdx + sti ret SECTION .data diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm index 4863686f14..bd0ff04de8 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm @@ -207,6 +207,12 @@ HasErrorCode: mov rax, gs push rax + mov rax, ss + mov ds, rax + mov es, rax + mov fs, rax + mov gs, rax + mov [rbp + 8], rcx ; save vector number ;; UINT64 Rip; @@ -356,7 +362,6 @@ DrFinish: incsspq rax ; SSP should be 0xFC0 now CetDone: %endif - cli ;; UINT64 ExceptionData; add rsp, 8 @@ -398,10 +403,9 @@ CetDone: ;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; pop rax - ; mov gs, rax ; not for gs + mov gs, rax pop rax - ; mov fs, rax ; not for fs - ; (X64 will not use fs and gs, so we do not restore it) + mov fs, rax pop rax mov es, rax pop rax @@ -428,6 +432,16 @@ CetDone: pop r14 pop r15 + ; Check whether Ring3 process was interrupted. + push rax + mov rax, ss + push rcx + mov rcx, ds + cmp rax, rcx + jne ReturnToRing3 + pop rcx + pop rax + mov rsp, rbp pop rbp add rsp, 16 @@ -454,6 +468,13 @@ DoReturn: retfq DoIret: iretq +ReturnToRing3: + pop rcx + pop rax + mov rsp, rbp + pop rbp + add rsp, 16 + iretq ;------------------------------------------------------------------------------------- ; GetTemplateAddressMap (&AddressMap); From 13bb3971ceb418244f084dbf2cb0e5cd070cb8cb Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 5 Mar 2024 16:21:52 +0300 Subject: [PATCH 176/341] SysCall: Added checks of user variables. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 107 ++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index d494ae7622..ec049f6ead 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -174,7 +174,7 @@ CallBootService ( EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem; // - // TODO: Check User variables. + // Check User variables. // gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -186,6 +186,15 @@ CallBootService ( // Argument 2: VOID *CoreRegistration // Argument 3: VOID **Interface // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + DisableSMAP (); Status = FindGuid ((EFI_GUID *)CoreRbp->Argument1, &CoreProtocol, &MemoryCoreSize); EnableSMAP (); @@ -218,6 +227,17 @@ CallBootService ( // Argument 5: EFI_HANDLE CoreControllerHandle // Argument 6: UINT32 Attributes // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + DisableSMAP (); Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); if (EFI_ERROR (Status)) { @@ -254,11 +274,27 @@ CallBootService ( // Argument 1: EFI_HANDLE *Handle // ... // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + sizeof (EFI_HANDLE *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (VOID **) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + DisableSMAP (); CoreHandle = *(EFI_HANDLE *)CoreRbp->Argument1; UserArgList = (VOID **)CoreRbp->Argument2; for (Index = 0; UserArgList[Index] != NULL; Index += 2) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserArgList[Index], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArgList[Index] + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + Status = FindGuid ((EFI_GUID *)UserArgList[Index], (EFI_GUID **)&CoreArgList[Index], &MemoryCoreSize); if (EFI_ERROR (Status)) { EnableSMAP (); @@ -271,7 +307,15 @@ CallBootService ( return Status; } + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserArgList[Index + 1], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArgList[Index + 1] + MemoryCoreSize - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + CoreArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index + 1]); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] + sizeof (VOID *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); } EnableSMAP (); @@ -318,6 +362,13 @@ CallBootService ( // Argument 3: EFI_HANDLE CoreAgentHandle // Argument 4: EFI_HANDLE CoreControllerHandle // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + DisableSMAP (); Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); if (EFI_ERROR (Status)) { @@ -343,6 +394,15 @@ CallBootService ( // Argument 2: EFI_GUID *Protocol // Argument 3: VOID **Interface // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + DisableSMAP (); Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); EnableSMAP (); @@ -373,6 +433,9 @@ CallBootService ( // Argument 3: UINTN NumberOfPages // Argument 4: EFI_PHYSICAL_ADDRESS *Memory // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + Status = gBS->AllocatePages ( (EFI_ALLOCATE_TYPE)CoreRbp->Argument1, (EFI_MEMORY_TYPE)CoreRbp->Argument2, @@ -381,6 +444,11 @@ CallBootService ( ); DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + sizeof (EFI_PHYSICAL_ADDRESS) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + *(EFI_PHYSICAL_ADDRESS *)UserRsp->Arguments[4] = (EFI_PHYSICAL_ADDRESS)Argument4; EnableSMAP (); @@ -391,6 +459,11 @@ CallBootService ( // Argument 1: EFI_PHYSICAL_ADDRESS Memory // Argument 2: UINTN NumberOfPages // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + CoreRbp->Argument2 * EFI_PAGE_SIZE - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + return gBS->FreePages ( (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, CoreRbp->Argument2 @@ -430,6 +503,9 @@ CallBootService ( // Argument 4: UINTN BufferSize // Argument 5: VOID *Buffer // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + DisableSMAP (); Argument4 = UserRsp->Arguments[4]; EnableSMAP (); @@ -447,6 +523,11 @@ CallBootService ( (VOID *)Argument5 ); DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[5] + Argument4 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); EnableSMAP (); @@ -462,6 +543,9 @@ CallBootService ( // Argument 4: UINTN BufferSize // Argument 5: VOID *Buffer // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + DisableSMAP (); Argument4 = UserRsp->Arguments[4]; EnableSMAP (); @@ -472,6 +556,11 @@ CallBootService ( } DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[5] + Argument4 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + CopyMem ((VOID *)Argument5,(VOID *)UserRsp->Arguments[5], Argument4); EnableSMAP (); @@ -503,6 +592,9 @@ CallBootService ( // Argument 4: UINTN BufferSize // Argument 5: VOID *Buffer // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + DisableSMAP (); Argument4 = UserRsp->Arguments[4]; EnableSMAP (); @@ -520,6 +612,11 @@ CallBootService ( (VOID *)Argument5 ); DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[5] + Argument4 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); EnableSMAP (); @@ -535,6 +632,9 @@ CallBootService ( // Argument 4: UINTN BufferSize // Argument 5: VOID *Buffer // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + DisableSMAP (); Argument4 = UserRsp->Arguments[4]; EnableSMAP (); @@ -545,6 +645,11 @@ CallBootService ( } DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[5] + Argument4 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + CopyMem ((VOID *)Argument5, (VOID *)UserRsp->Arguments[5], Argument4); EnableSMAP (); From 2660173180aef1f0f43f77cf79c285a6e1931cca Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 5 Mar 2024 20:01:19 +0300 Subject: [PATCH 177/341] Ring3: Forbade Ring3 accsess to all ports but for UART to allow DEBUG printing. --- MdeModulePkg/Core/Dxe/Image/Image.c | 4 ---- .../X64/ArchExceptionHandler.c | 23 +++++++++++++++++-- .../X64/ArchInterruptDefs.h | 6 ++++- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 4c8c877595..1b0a02ee49 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1645,10 +1645,6 @@ InitializeRing3 ( Eflags.UintN = AsmReadEflags (); Eflags.Bits.AC = 0; - // - // Allow user image to access ports. - // - Eflags.Bits.IOPL = 3; AsmWriteEflags (Eflags.UintN); // // Enable SYSCALL and SYSRET. diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index 4e85880ed4..76a51e28d0 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -139,6 +139,7 @@ ArchSetupExceptionStack ( UINTN TssBase; UINT8 *StackSwitchExceptions; UINTN NeedBufferSize; + UINT8 *IOBitMap; if (BufferSize == NULL) { return EFI_INVALID_PARAMETER; @@ -210,12 +211,12 @@ ArchSetupExceptionStack ( TssDesc->Uint128.Uint64 = 0; TssDesc->Uint128.Uint64_1 = 0; - TssDesc->Bits.LimitLow = sizeof (IA32_TASK_STATE_SEGMENT) - 1; + TssDesc->Bits.LimitLow = (UINT16)(CPU_TSS_SIZE - 1); TssDesc->Bits.BaseLow = (UINT16)TssBase; TssDesc->Bits.BaseMidl = (UINT8)(TssBase >> 16); TssDesc->Bits.Type = IA32_GDT_TYPE_TSS; TssDesc->Bits.P = 1; - TssDesc->Bits.LimitHigh = 0; + TssDesc->Bits.LimitHigh = (CPU_TSS_SIZE - 1) >> 16; TssDesc->Bits.BaseMidh = (UINT8)(TssBase >> 24); TssDesc->Bits.BaseHigh = (UINT32)(TssBase >> 32); @@ -254,6 +255,24 @@ ArchSetupExceptionStack ( // AsmWriteGdtr (&Gdtr); + // + // Set I/O Permission Bit Map + // + Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); + // + // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06 + // + IOBitMap = (UINT8 *)((UINTN)Tss + Tss->IOMapBaseAddress); + for (Index = 0; Index < IO_BIT_MAP_SIZE; ++Index) { + if ((Index * 8) == 0x3F8) { + *IOBitMap = 0x84; + } else { + *IOBitMap = 0xFF; + } + + ++IOBitMap; + } + // // Load current task // diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h index 008670cb0d..39f19f3b3b 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h @@ -38,6 +38,10 @@ typedef struct { } RESERVED_VECTORS_DATA; #define CPU_TSS_DESC_SIZE sizeof (IA32_TSS_DESCRIPTOR) -#define CPU_TSS_SIZE sizeof (IA32_TASK_STATE_SEGMENT) +// +// 0x81 is needed to allow Ring3 code access to Uart in I/O Permission Bit Map. +// +#define IO_BIT_MAP_SIZE 0x81 +#define CPU_TSS_SIZE (sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE) #endif From 969c46973339d9496a869c053282936dc6e309af Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 8 Mar 2024 12:12:00 +0300 Subject: [PATCH 178/341] SysCall: Refactored data segment selectors' switching. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 4 +- .../Dxe/SysCall/X64/CoreBootServices.nasm | 55 ++++++++----------- 2 files changed, 25 insertions(+), 34 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index ec049f6ead..0e6ee879b2 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -144,8 +144,8 @@ typedef struct { // Stack: // rsp - User Rsp // rbp - User Rbp -// rcx - Rip for SYSCALL -// r11 - User data segment selector +// rcx - User Rip for SYSCALL +// r11 - User RFLAGS for SYSCALL // r9 - Argument 3 // r8 - Argument 2 // rdx - Argument 1 <- CoreRbp diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 7a89cded04..6f9099a5a8 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -94,6 +94,19 @@ copy: ret +%macro SetRing3DataSegmentSelectors 0 + mov rcx, MSR_IA32_STAR + call ASM_PFX(AsmReadMsr64) + ; rax = ((RING3_CODE64_SEL - 16) << 16 | RING0_CODE64_SEL) << 32 + shr rax, 48 + add rax, 8 + + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax +%endmacro + ;------------------------------------------------------------------------------ ; EFI_STATUS ; EFIAPI @@ -114,9 +127,6 @@ copy: global ASM_PFX(CoreBootServices) ASM_PFX(CoreBootServices): cli - ; Save User data segment selector temporarily in R11. - mov r11, ds - ; Switch from User to Core data segment selectors. mov ax, ss mov ds, ax @@ -136,7 +146,7 @@ ASM_PFX(CoreBootServices): push rbp ; Save return address for SYSRET. push rcx - ; Save User data segment selector. + ; Save User RFLAGS for SYSRET. push r11 ; Save User Arguments [1..3]. push r9 @@ -152,24 +162,20 @@ ASM_PFX(CoreBootServices): sti call ASM_PFX(CallBootService) + push rax cli - ; Step over Arguments [1..3]. - add rsp, 8*3 + SetRing3DataSegmentSelectors - ; Switch from Core to User data segment selectors. - pop r11 + pop rax -o16 mov ds, r11 -o16 mov es, r11 -o16 mov fs, r11 -o16 mov gs, r11 + ; Step over Arguments [1..3]. + add rsp, 8*3 ; Prepare SYSRET arguments. - pop rcx - pushfq pop r11 + pop rcx ; Switch to User Stack. pop rbp @@ -194,31 +200,16 @@ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): cli ; Save input Arguments. - push r12 - mov r12, rcx - - ; Extract User Data selector. - mov rcx, MSR_IA32_STAR - call ASM_PFX(AsmReadMsr64) - ; rax = ((RING3_CODE64_SEL - 16) << 16 | RING0_CODE64_SEL) << 32 - shr rax, 48 - add rax, 8 + push rcx - ; Set Data selectors - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax + SetRing3DataSegmentSelectors ; Prepare SYSRET arguments. mov rcx, [gRing3EntryPoint] - mov rdx, r12 + pop rdx pushfq pop r11 - ; Restore stack and registers. - pop r12 - ; Save Core Stack pointers and switch to User Stack. mov [ASM_PFX(CoreRsp)], rsp mov [ASM_PFX(CoreRbp)], rbp From 8f5981c764914e69d7359e46fa6be85d09739d41 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 8 Mar 2024 13:04:47 +0300 Subject: [PATCH 179/341] Ring3: Refactored exception handling. --- MdeModulePkg/Core/Dxe/Image/Image.c | 7 ++++++- .../Dxe/SysCall/X64/CoreBootServices.nasm | 12 +++--------- .../X64/ExceptionHandlerAsm.nasm | 19 ++++++++++++------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 1b0a02ee49..18112c3441 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1691,13 +1691,18 @@ InitializeRing3 ( DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); // - // Initialize MSR_IA32_STAR and MSR_IA32_LSTAR for SYSCALL and SYSRET. + // Initialize MSR_IA32_STAR, MSR_IA32_LSTAR and MSR_IA32_FMASK for SYSCALL and SYSRET. // Msr = (((((UINT64)RING3_CODE64_SEL - 16) | 3) << 16) | (UINT64)RING0_CODE64_SEL) << 32; AsmWriteMsr64 (MSR_IA32_STAR, Msr); Msr = (UINT64)(UINTN)CoreBootServices; AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); + // + // Disable maskable interrupts at SYSCALL. + // + Msr = (UINT64)BIT9; + AsmWriteMsr64 (MSR_IA32_FMASK, Msr); return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 6f9099a5a8..16b182a764 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -126,7 +126,6 @@ copy: ;------------------------------------------------------------------------------ global ASM_PFX(CoreBootServices) ASM_PFX(CoreBootServices): - cli ; Switch from User to Core data segment selectors. mov ax, ss mov ds, ax @@ -160,10 +159,8 @@ ASM_PFX(CoreBootServices): mov r8, [rbp + 8*6] sti - call ASM_PFX(CallBootService) push rax - cli SetRing3DataSegmentSelectors @@ -181,8 +178,6 @@ ASM_PFX(CoreBootServices): pop rbp pop rsp - sti - ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. o64 sysret ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. @@ -198,7 +193,10 @@ o64 sysret ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): + pushfq + pop r11 cli + ; Save input Arguments. push rcx @@ -207,8 +205,6 @@ ASM_PFX(CallRing3): ; Prepare SYSRET arguments. mov rcx, [gRing3EntryPoint] pop rdx - pushfq - pop r11 ; Save Core Stack pointers and switch to User Stack. mov [ASM_PFX(CoreRsp)], rsp @@ -216,8 +212,6 @@ ASM_PFX(CallRing3): mov rsp, [ASM_PFX(gRing3CallStackTop)] mov rbp, rsp - sti - ; Pass control to user image o64 sysret diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm index bd0ff04de8..a8c69026db 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm @@ -207,6 +207,15 @@ HasErrorCode: mov rax, gs push rax + ; Check whether Ring3 process was interrupted. + and rax, 3 + cmp rax, 3 + jne SkipHook + mov rax, cr2 + cmp rax, 0xFFFFFFFFFFFFFFF8 + jne SkipHook + mov rcx, 32 +SkipHook: mov rax, ss mov ds, rax mov es, rax @@ -433,14 +442,12 @@ CetDone: pop r15 ; Check whether Ring3 process was interrupted. - push rax - mov rax, ss push rcx mov rcx, ds - cmp rax, rcx - jne ReturnToRing3 + and rcx, 3 + cmp rcx, 3 pop rcx - pop rax + je ReturnToRing3 mov rsp, rbp pop rbp @@ -469,8 +476,6 @@ DoReturn: DoIret: iretq ReturnToRing3: - pop rcx - pop rax mov rsp, rbp pop rbp add rsp, 16 From 53235899c159d22790c3eb5326fc2948291511e2 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 8 Mar 2024 16:59:46 +0300 Subject: [PATCH 180/341] Ring3: Added debug printings and some fixes for FAT wrappers. --- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 62 ++++++++++++++++++- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 2 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 25 +++++--- 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index addb5c5d84..d7490da4d8 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -158,6 +158,8 @@ Ring3GetMemoryMap ( OUT UINT32 *DescriptorVersion ) { + DEBUG ((DEBUG_ERROR, "Ring3: GetMemoryMap is not supported\n")); + return EFI_UNSUPPORTED; } @@ -171,6 +173,8 @@ Ring3CreateEvent ( OUT EFI_EVENT *Event ) { + DEBUG ((DEBUG_ERROR, "Ring3: CreateEvent is not supported\n")); + return EFI_UNSUPPORTED; } @@ -182,6 +186,8 @@ Ring3SetTimer ( IN UINT64 TriggerTime ) { + DEBUG ((DEBUG_ERROR, "Ring3: SetTimer is not supported\n")); + return EFI_UNSUPPORTED; } @@ -193,6 +199,8 @@ Ring3WaitForEvent ( OUT UINTN *UserIndex ) { + DEBUG ((DEBUG_ERROR, "Ring3: WaitForEvent is not supported\n")); + return EFI_UNSUPPORTED; } @@ -202,6 +210,8 @@ Ring3SignalEvent ( IN EFI_EVENT UserEvent ) { + DEBUG ((DEBUG_ERROR, "Ring3: SignalEvent is not supported\n")); + return EFI_UNSUPPORTED; } @@ -211,6 +221,8 @@ Ring3CloseEvent ( IN EFI_EVENT UserEvent ) { + DEBUG ((DEBUG_ERROR, "Ring3: CloseEvent is not supported\n")); + return EFI_UNSUPPORTED; } @@ -220,6 +232,8 @@ Ring3CheckEvent ( IN EFI_EVENT UserEvent ) { + DEBUG ((DEBUG_ERROR, "Ring3: CheckEvent is not supported\n")); + return EFI_UNSUPPORTED; } @@ -232,6 +246,8 @@ Ring3InstallProtocolInterface ( IN VOID *Interface ) { + DEBUG ((DEBUG_ERROR, "Ring3: InstallProtocolInterface is not supported\n")); + return EFI_UNSUPPORTED; } @@ -244,6 +260,8 @@ Ring3ReinstallProtocolInterface ( IN VOID *NewInterface ) { + DEBUG ((DEBUG_ERROR, "Ring3: ReinstallProtocolInterface is not supported\n")); + return EFI_UNSUPPORTED; } @@ -255,6 +273,8 @@ Ring3UninstallProtocolInterface ( IN VOID *Interface ) { + DEBUG ((DEBUG_ERROR, "Ring3: UninstallProtocolInterface is not supported\n")); + return EFI_UNSUPPORTED; } @@ -290,6 +310,8 @@ Ring3RegisterProtocolNotify ( OUT VOID **Registration ) { + DEBUG ((DEBUG_ERROR, "Ring3: RegisterProtocolNotify is not supported\n")); + return EFI_UNSUPPORTED; } @@ -303,6 +325,8 @@ Ring3LocateHandle ( OUT EFI_HANDLE *Buffer ) { + DEBUG ((DEBUG_ERROR, "Ring3: LocateHandle is not supported\n")); + return EFI_UNSUPPORTED; } @@ -314,6 +338,8 @@ Ring3LocateDevicePath ( OUT EFI_HANDLE *Device ) { + DEBUG ((DEBUG_ERROR, "Ring3: LocateDevicePath is not supported\n")); + return EFI_UNSUPPORTED; } @@ -324,6 +350,8 @@ Ring3InstallConfigurationTable ( IN VOID *Table ) { + DEBUG ((DEBUG_ERROR, "Ring3: InstallConfigurationTable is not supported\n")); + return EFI_UNSUPPORTED; } @@ -338,6 +366,8 @@ Ring3LoadImage ( OUT EFI_HANDLE *ImageHandle ) { + DEBUG ((DEBUG_ERROR, "Ring3: LoadImage is not supported\n")); + return EFI_UNSUPPORTED; } @@ -349,6 +379,8 @@ Ring3StartImage ( OUT CHAR16 **ExitData OPTIONAL ) { + DEBUG ((DEBUG_ERROR, "Ring3: StartImage is not supported\n")); + return EFI_UNSUPPORTED; } @@ -361,6 +393,8 @@ Ring3Exit ( IN CHAR16 *ExitData OPTIONAL ) { + DEBUG ((DEBUG_ERROR, "Ring3: Exit is not supported\n")); + return EFI_UNSUPPORTED; } @@ -370,6 +404,8 @@ Ring3UnloadImage ( IN EFI_HANDLE ImageHandle ) { + DEBUG ((DEBUG_ERROR, "Ring3: UnloadImage is not supported\n")); + return EFI_UNSUPPORTED; } @@ -380,6 +416,8 @@ Ring3ExitBootServices ( IN UINTN MapKey ) { + DEBUG ((DEBUG_ERROR, "Ring3: ExitBootServices is not supported\n")); + return EFI_UNSUPPORTED; } @@ -389,6 +427,8 @@ Ring3GetNextMonotonicCount ( OUT UINT64 *Count ) { + DEBUG ((DEBUG_ERROR, "Ring3: GetNextMonotonicCount is not supported\n")); + return EFI_UNSUPPORTED; } @@ -398,6 +438,8 @@ Ring3Stall ( IN UINTN Microseconds ) { + DEBUG ((DEBUG_ERROR, "Ring3: Stall is not supported\n")); + return EFI_UNSUPPORTED; } @@ -410,6 +452,8 @@ Ring3SetWatchdogTimer ( IN CHAR16 *WatchdogData OPTIONAL ) { + DEBUG ((DEBUG_ERROR, "Ring3: SetWatchdogTimer is not supported\n")); + return EFI_UNSUPPORTED; } @@ -422,6 +466,8 @@ Ring3ConnectController ( IN BOOLEAN Recursive ) { + DEBUG ((DEBUG_ERROR, "Ring3: ConnectController is not supported\n")); + return EFI_UNSUPPORTED; } @@ -433,6 +479,8 @@ Ring3DisconnectController ( IN EFI_HANDLE ChildHandle OPTIONAL ) { + DEBUG ((DEBUG_ERROR, "Ring3: DisconnectController is not supported\n")); + return EFI_UNSUPPORTED; } @@ -462,7 +510,7 @@ Ring3OpenProtocol ( return Status; } - return FixInterface (Protocol, Interface); + return (Interface != NULL) ? FixInterface (Protocol, Interface) : Status; } EFI_STATUS @@ -492,6 +540,8 @@ Ring3OpenProtocolInformation ( OUT UINTN *EntryCount ) { + DEBUG ((DEBUG_ERROR, "Ring3: OpenProtocolInformation is not supported\n")); + return EFI_UNSUPPORTED; } @@ -503,6 +553,8 @@ Ring3ProtocolsPerHandle ( OUT UINTN *ProtocolBufferCount ) { + DEBUG ((DEBUG_ERROR, "Ring3: ProtocolsPerHandle is not supported\n")); + return EFI_UNSUPPORTED; } @@ -516,6 +568,8 @@ Ring3LocateHandleBuffer ( OUT EFI_HANDLE **Buffer ) { + DEBUG ((DEBUG_ERROR, "Ring3: LocateHandleBuffer is not supported\n")); + return EFI_UNSUPPORTED; } @@ -585,6 +639,8 @@ Ring3UninstallMultipleProtocolInterfaces ( ... ) { + DEBUG ((DEBUG_ERROR, "Ring3: UninstallMultipleProtocolInterfaces is not supported\n")); + return EFI_UNSUPPORTED; } @@ -596,6 +652,8 @@ Ring3CalculateCrc32 ( OUT UINT32 *Crc32 ) { + DEBUG ((DEBUG_ERROR, "Ring3: CalculateCrc32 is not supported\n")); + return EFI_UNSUPPORTED; } @@ -610,6 +668,8 @@ Ring3CreateEventEx ( OUT EFI_EVENT *Event ) { + DEBUG ((DEBUG_ERROR, "Ring3: CreateEventEx is not supported\n")); + return EFI_UNSUPPORTED; } diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 6436566576..4be5f37fbf 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -236,7 +236,7 @@ ProtectUefiImage ( // // CPU ARCH present. Update memory attribute directly. // - if (AsciiStrStr (PdbPointer, "Ntfs") != NULL) { + if (AsciiStrStr (PdbPointer, "Fat") != NULL) { SetUefiImageProtectionAttributes (ImageRecord, TRUE); *IsUserImage = TRUE; } else if (AsciiStrStr (PdbPointer, "Ring3") != NULL) { diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 0e6ee879b2..a4ab6ac7eb 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -63,6 +63,11 @@ FindGuid ( *Core = &gEfiComponentNameProtocolGuid; *CoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiComponentName2ProtocolGuid)) { + + *Core = &gEfiComponentName2ProtocolGuid; + *CoreSize = sizeof (EFI_COMPONENT_NAME2_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiDevicePathProtocolGuid)) { *Core = &gEfiDevicePathProtocolGuid; @@ -74,7 +79,7 @@ FindGuid ( *CoreSize = sizeof (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL); } else { - DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol.\n")); + DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol - %g.\n", Ring3)); return EFI_NOT_FOUND; } @@ -222,7 +227,7 @@ CallBootService ( // // Argument 1: EFI_HANDLE CoreUserHandle // Argument 2: EFI_GUID *Protocol - // Argument 3: VOID **Interface + // Argument 3: VOID **Interface OPTIONAL // Argument 4: EFI_HANDLE CoreImageHandle // Argument 5: EFI_HANDLE CoreControllerHandle // Argument 6: UINT32 Attributes @@ -231,10 +236,12 @@ CallBootService ( ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + if ((VOID **)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + } gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -253,7 +260,7 @@ CallBootService ( Status = gBS->OpenProtocol ( (EFI_HANDLE)CoreRbp->Argument1, CoreProtocol, - &Interface, + ((VOID **)CoreRbp->Argument3 != NULL) ? &Interface : NULL, (EFI_HANDLE)Argument4, (EFI_HANDLE)Argument5, (UINT32)Argument6 @@ -264,7 +271,9 @@ CallBootService ( Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); } - *(VOID **)CoreRbp->Argument3 = Interface; + if ((VOID **)CoreRbp->Argument3 != NULL) { + *(VOID **)CoreRbp->Argument3 = Interface; + } EnableSMAP (); return Status; From 197b86175517012d018e1e4b026f893a07225a9b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 8 Mar 2024 17:32:28 +0300 Subject: [PATCH 181/341] Ring3: Added Runtime Services wrappers. --- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 24 ++ MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf | 3 +- MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h | 383 ++++++++++++++++++ .../Dxe/DxeRing3/Ring3UefiRuntimeServices.c | 189 +++++++++ MdePkg/Include/Uefi/UefiSpec.h | 6 + 5 files changed, 604 insertions(+), 1 deletion(-) create mode 100644 MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index 20659b11b3..53c7ff00f4 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -66,6 +66,30 @@ EFI_BOOT_SERVICES mBootServices = { (EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx }; +EFI_RUNTIME_SERVICES mRuntimeServices = { + { + EFI_RUNTIME_SERVICES_SIGNATURE, // Signature + EFI_RUNTIME_SERVICES_REVISION, // Revision + sizeof (EFI_RUNTIME_SERVICES), // HeaderSize + 0, // CRC32 + 0 // Reserved + }, + (EFI_GET_TIME)Ring3GetTime, // GetTime + (EFI_SET_TIME)Ring3SetTime, // SetTime + (EFI_GET_WAKEUP_TIME)Ring3GetWakeupTime, // GetWakeupTime + (EFI_SET_WAKEUP_TIME)Ring3SetWakeupTime, // SetWakeupTime + (EFI_SET_VIRTUAL_ADDRESS_MAP)Ring3SetVirtualAddressMap, // SetVirtualAddressMap + (EFI_CONVERT_POINTER)Ring3ConvertPointer, // ConvertPointer + (EFI_GET_VARIABLE)Ring3GetVariable, // GetVariable + (EFI_GET_NEXT_VARIABLE_NAME)Ring3GetNextVariableName, // GetNextVariableName + (EFI_SET_VARIABLE)Ring3SetVariable, // SetVariable + (EFI_GET_NEXT_HIGH_MONO_COUNT)Ring3GetNextHighMonotonicCount, // GetNextHighMonotonicCount + (EFI_RESET_SYSTEM)Ring3ResetSystem, // ResetSystem + (EFI_UPDATE_CAPSULE)Ring3UpdateCapsule, // UpdateCapsule + (EFI_QUERY_CAPSULE_CAPABILITIES)Ring3QueryCapsuleCapabilities, // QueryCapsuleCapabilities + (EFI_QUERY_VARIABLE_INFO)Ring3QueryVariableInfo // QueryVariableInfo +}; + VOID EFIAPI Ring3EntryPoint ( diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index 1e29851e32..0552c91116 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -25,6 +25,7 @@ Ring3.h DxeRing3.c Ring3UefiBootServices.c + Ring3UefiRuntimeServices.c Ring3Protocols.c [Sources.X64] @@ -41,7 +42,7 @@ MemoryPoolLib UefiBootServicesTableLib UefiDriverEntryPoint - + [Protocols] gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h index 83d64e50cf..bd0ba2bfa5 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h @@ -1164,3 +1164,386 @@ Ring3DiskIoWrite ( IN UINTN BufferSize, IN VOID *Buffer ); + +/** + Returns the current time and date information, and the time-keeping capabilities + of the hardware platform. + + @param[out] Time A pointer to storage to receive a snapshot of the current time. + @param[out] Capabilities An optional pointer to a buffer to receive the real time clock + device's capabilities. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER Time is NULL. + @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error. + +**/ +EFI_STATUS +EFIAPI +Ring3GetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ); + +/** + Sets the current local time and date information. + + @param[in] Time A pointer to the current time. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error. + +**/ +EFI_STATUS +EFIAPI +Ring3SetTime ( + IN EFI_TIME *Time + ); + +/** + Returns the current wakeup alarm clock setting. + + @param[out] Enabled Indicates if the alarm is currently enabled or disabled. + @param[out] Pending Indicates if the alarm signal is pending and requires acknowledgement. + @param[out] Time The current alarm setting. + + @retval EFI_SUCCESS The alarm settings were returned. + @retval EFI_INVALID_PARAMETER Enabled is NULL. + @retval EFI_INVALID_PARAMETER Pending is NULL. + @retval EFI_INVALID_PARAMETER Time is NULL. + @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error. + @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. + +**/ +EFI_STATUS +EFIAPI +Ring3GetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ); + +/** + Sets the system wakeup alarm clock time. + + @param[in] Enable Enable or disable the wakeup alarm. + @param[in] Time If Enable is TRUE, the time to set the wakeup alarm for. + If Enable is FALSE, then this parameter is optional, and may be NULL. + + @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If + Enable is FALSE, then the wakeup alarm was disabled. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error. + @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. + +**/ +EFI_STATUS +EFIAPI +Ring3SetWakeupTime ( + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL + ); + +/** + Changes the runtime addressing mode of EFI firmware from physical to virtual. + + @param[in] MemoryMapSize The size in bytes of VirtualMap. + @param[in] DescriptorSize The size in bytes of an entry in the VirtualMap. + @param[in] DescriptorVersion The version of the structure entries in VirtualMap. + @param[in] VirtualMap An array of memory descriptors which contain new virtual + address mapping information for all runtime ranges. + + @retval EFI_SUCCESS The virtual address map has been applied. + @retval EFI_UNSUPPORTED EFI firmware is not at runtime, or the EFI firmware is already in + virtual address mapped mode. + @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is invalid. + @retval EFI_NO_MAPPING A virtual address was not supplied for a range in the memory + map that requires a mapping. + @retval EFI_NOT_FOUND A virtual address was supplied for an address that is not found + in the memory map. + +**/ +EFI_STATUS +EFIAPI +Ring3SetVirtualAddressMap ( + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap + ); + +/** + Determines the new virtual address that is to be used on subsequent memory accesses. + + @param[in] DebugDisposition Supplies type information for the pointer being converted. + @param[in, out] Address A pointer to a pointer that is to be fixed to be the value needed + for the new virtual address mappings being applied. + + @retval EFI_SUCCESS The pointer pointed to by Address was modified. + @retval EFI_INVALID_PARAMETER 1) Address is NULL. + 2) *Address is NULL and DebugDisposition does + not have the EFI_OPTIONAL_PTR bit set. + @retval EFI_NOT_FOUND The pointer pointed to by Address was not found to be part + of the current memory map. This is normally fatal. + +**/ +EFI_STATUS +EFIAPI +Ring3ConvertPointer ( + IN UINTN DebugDisposition, + IN OUT VOID **Address + ); + +/** + Returns the value of a variable. + + @param[in] VariableName A Null-terminated string that is the name of the vendor's + variable. + @param[in] VendorGuid A unique identifier for the vendor. + @param[out] Attributes If not NULL, a pointer to the memory location to return the + attributes bitmask for the variable. + @param[in, out] DataSize On input, the size in bytes of the return Data buffer. + On output the size of data returned in Data. + @param[out] Data The buffer to return the contents of the variable. May be NULL + with a zero DataSize in order to determine the size buffer needed. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND The variable was not found. + @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. + @retval EFI_INVALID_PARAMETER VariableName is NULL. + @retval EFI_INVALID_PARAMETER VendorGuid is NULL. + @retval EFI_INVALID_PARAMETER DataSize is NULL. + @retval EFI_INVALID_PARAMETER The DataSize is not too small and Data is NULL. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. + @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure. + +**/ +EFI_STATUS +EFIAPI +Ring3GetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data OPTIONAL + ); + +/** + Enumerates the current variable names. + + @param[in, out] VariableNameSize The size of the VariableName buffer. The size must be large + enough to fit input string supplied in VariableName buffer. + @param[in, out] VariableName On input, supplies the last VariableName that was returned + by GetNextVariableName(). On output, returns the Nullterminated + string of the current variable. + @param[in, out] VendorGuid On input, supplies the last VendorGuid that was returned by + GetNextVariableName(). On output, returns the + VendorGuid of the current variable. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND The next variable was not found. + @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result. + VariableNameSize has been updated with the size needed to complete the request. + @retval EFI_INVALID_PARAMETER VariableNameSize is NULL. + @retval EFI_INVALID_PARAMETER VariableName is NULL. + @retval EFI_INVALID_PARAMETER VendorGuid is NULL. + @retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and + GUID of an existing variable. + @retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of + the input VariableName buffer. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. + +**/ +EFI_STATUS +EFIAPI +Ring3GetNextVariableName ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ); + +/** + Sets the value of a variable. + + @param[in] VariableName A Null-terminated string that is the name of the vendor's variable. + Each VariableName is unique for each VendorGuid. VariableName must + contain 1 or more characters. If VariableName is an empty string, + then EFI_INVALID_PARAMETER is returned. + @param[in] VendorGuid A unique identifier for the vendor. + @param[in] Attributes Attributes bitmask to set for the variable. + @param[in] DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE or + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero + causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is + set, then a SetVariable() call with a DataSize of zero will not cause any change to + the variable value (the timestamp associated with the variable may be updated however + even if no new data value is provided,see the description of the + EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not + be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated). + @param[in] Data The contents for the variable. + + @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as + defined by the Attributes. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the + DataSize exceeds the maximum allowed. + @retval EFI_INVALID_PARAMETER VariableName is an empty string. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. + @retval EFI_WRITE_PROTECTED The variable in question is read-only. + @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. + @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, + but the AuthInfo does NOT pass the validation check carried out by the firmware. + + @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. + +**/ +EFI_STATUS +EFIAPI +Ring3SetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + +/** + Returns the next high 32 bits of the platform's monotonic counter. + + @param[out] HighCount The pointer to returned value. + + @retval EFI_SUCCESS The next high monotonic count was returned. + @retval EFI_INVALID_PARAMETER HighCount is NULL. + @retval EFI_DEVICE_ERROR The device is not functioning properly. + +**/ +EFI_STATUS +EFIAPI +Ring3GetNextHighMonotonicCount ( + OUT UINT32 *HighCount + ); + +/** + Resets the entire platform. + + @param[in] ResetType The type of reset to perform. + @param[in] ResetStatus The status code for the reset. + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or + EfiResetShutdown the data buffer starts with a Null-terminated + string, optionally followed by additional binary data. + The string is a description that the caller may use to further + indicate the reason for the system reset. + For a ResetType of EfiResetPlatformSpecific the data buffer + also starts with a Null-terminated string that is followed + by an EFI_GUID that describes the specific type of reset to perform. +**/ +VOID +EFIAPI +Ring3ResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ); + +/** + Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended + consumption, the firmware may process the capsule immediately. If the payload should persist + across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must + be passed into ResetSystem() and will cause the capsule to be processed by the firmware as + part of the reset process. + + @param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules + being passed into update capsule. + @param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in + CaspuleHeaderArray. + @param[in] ScatterGatherList Physical pointer to a set of + EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the + location in physical memory of a set of capsules. + + @retval EFI_SUCCESS Valid capsule was passed. If + CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the + capsule has been successfully processed by the firmware. + @retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were + set in the capsule header. + @retval EFI_INVALID_PARAMETER CapsuleCount is 0. + @retval EFI_DEVICE_ERROR The capsule update was started, but failed due to a device error. + @retval EFI_UNSUPPORTED The capsule type is not supported on this platform. + @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule + is compatible with this platform but is not capable of being submitted or processed + in runtime. The caller may resubmit the capsule prior to ExitBootServices(). + @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates + the capsule is compatible with this platform but there are insufficient resources to process. + +**/ +EFI_STATUS +EFIAPI +Ring3UpdateCapsule ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL + ); + +/** + Returns if the capsule can be supported via UpdateCapsule(). + + @param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules + being passed into update capsule. + @param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in + CaspuleHeaderArray. + @param[out] MaxiumCapsuleSize On output the maximum size that UpdateCapsule() can + support as an argument to UpdateCapsule() via + CapsuleHeaderArray and ScatterGatherList. + @param[out] ResetType Returns the type of reset required for the capsule update. + + @retval EFI_SUCCESS Valid answer returned. + @retval EFI_UNSUPPORTED The capsule type is not supported on this platform, and + MaximumCapsuleSize and ResetType are undefined. + @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL. + @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule + is compatible with this platform but is not capable of being submitted or processed + in runtime. The caller may resubmit the capsule prior to ExitBootServices(). + @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates + the capsule is compatible with this platform but there are insufficient resources to process. + +**/ +EFI_STATUS +EFIAPI +Ring3QueryCapsuleCapabilities ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + OUT UINT64 *MaximumCapsuleSize, + OUT EFI_RESET_TYPE *ResetType + ); + +/** + Returns information about the EFI variables. + + @param[in] Attributes Attributes bitmask to specify the type of variables on + which to return information. + @param[out] MaximumVariableStorageSize On output the maximum size of the storage space + available for the EFI variables associated with the + attributes specified. + @param[out] RemainingVariableStorageSize Returns the remaining size of the storage space + available for the EFI variables associated with the + attributes specified. + @param[out] MaximumVariableSize Returns the maximum size of the individual EFI + variables associated with the attributes specified. + + @retval EFI_SUCCESS Valid answer returned. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied + @retval EFI_UNSUPPORTED The attribute is not supported on this platform, and the + MaximumVariableStorageSize, + RemainingVariableStorageSize, MaximumVariableSize + are undefined. + +**/ +EFI_STATUS +EFIAPI +Ring3QueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize + ); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c new file mode 100644 index 0000000000..bb579e8b15 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c @@ -0,0 +1,189 @@ +#include + +#include +#include + +#include "Ring3.h" + +EFI_STATUS +EFIAPI +Ring3GetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetTime is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetTime ( + IN EFI_TIME *Time + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetTime is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3GetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetWakeupTime is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetWakeupTime ( + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetWakeupTime is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetVirtualAddressMap ( + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetVirtualAddressMap is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3ConvertPointer ( + IN UINTN DebugDisposition, + IN OUT VOID **Address + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ConvertPointer is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3GetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetVariable is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3GetNextVariableName ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetNextVariableName is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetVariable is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3GetNextHighMonotonicCount ( + OUT UINT32 *HighCount + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetNextHighMonotonicCount is not supported\n")); + + return EFI_UNSUPPORTED; +} + +VOID +EFIAPI +Ring3ResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ResetSystem is not supported\n")); + + return; +} + +EFI_STATUS +EFIAPI +Ring3UpdateCapsule ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: UpdateCapsule is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3QueryCapsuleCapabilities ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + OUT UINT64 *MaximumCapsuleSize, + OUT EFI_RESET_TYPE *ResetType + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: QueryCapsuleCapabilities is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3QueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: QueryVariableInfo is not supported\n")); + + return EFI_UNSUPPORTED; +} diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 8c37d72be7..ec0c22ab9a 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2026,6 +2026,9 @@ typedef struct { } EFI_BOOT_SERVICES; typedef enum { + // + // BootServices + // SysCallReturnToCore, // Must always be zero for CoreBootServices.nasm. SysCallLocateProtocol, SysCallOpenProtocol, @@ -2037,6 +2040,9 @@ typedef enum { SysCallRaiseTpl, SysCallRestoreTpl, // + // RuntimeServices + // + // // Protocols // SysCallBlockIoReset, From 7be740aaedf2c86080eea1fadec0d3fc08416b62 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Sat, 9 Mar 2024 14:18:31 +0300 Subject: [PATCH 182/341] Ring3: Added UnicodeCollationProtocol wrappers. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf | 1 + MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h | 115 +++++ .../Core/Dxe/DxeRing3/Ring3Protocols.c | 96 ++++ .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 22 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 424 +++++++++++++++++- .../Core/Dxe/SysCall/SupportedProtocols.h | 1 + MdePkg/Include/Uefi/UefiSpec.h | 7 + 8 files changed, 658 insertions(+), 9 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 9e5e57cb30..a5041925f6 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -168,6 +168,7 @@ gEfiComponentNameProtocolGuid ## SOMETIMES_CONSUMES gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiUnicodeCollationProtocolGuid ## SOMETIMES_CONSUMES # Arch Protocols gEfiBdsArchProtocolGuid ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index 0552c91116..71cc66b2e2 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -49,6 +49,7 @@ gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES + gEfiUnicodeCollationProtocolGuid ## SOMETIMES_CONSUMES [Depex] TRUE diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h index bd0ba2bfa5..fd5a605505 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h @@ -9,6 +9,7 @@ #include #include #include +#include EFI_STATUS EFIAPI @@ -1547,3 +1548,117 @@ Ring3QueryVariableInfo ( OUT UINT64 *RemainingVariableStorageSize, OUT UINT64 *MaximumVariableSize ); + +/** + Performs a case-insensitive comparison of two Null-terminated strings. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param Str1 A pointer to a Null-terminated string. + @param Str2 A pointer to a Null-terminated string. + + @retval 0 Str1 is equivalent to Str2. + @retval >0 Str1 is lexically greater than Str2. + @retval <0 Str1 is lexically less than Str2. + +**/ +INTN +EFIAPI +Ring3UnicodeStriColl ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *Str1, + IN CHAR16 *Str2 + ); + +/** + Performs a case-insensitive comparison of a Null-terminated + pattern string and a Null-terminated string. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + @param Pattern A pointer to a Null-terminated pattern string. + + @retval TRUE Pattern was found in String. + @retval FALSE Pattern was not found in String. + +**/ +BOOLEAN +EFIAPI +Ring3UnicodeMetaiMatch ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ); + +/** + Converts all the characters in a Null-terminated string to + lower case characters. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + +**/ +VOID +EFIAPI +Ring3UnicodeStrLwr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ); + +/** + Converts all the characters in a Null-terminated string to upper + case characters. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + +**/ +VOID +EFIAPI +Ring3UnicodeStrUpr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ); + +/** + Converts an 8.3 FAT file name in an OEM character set to a Null-terminated + string. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param FatSize The size of the string Fat in bytes. + @param Fat A pointer to a Null-terminated string that contains an 8.3 file + name using an 8-bit OEM character set. + @param String A pointer to a Null-terminated string. The string must + be allocated in advance to hold FatSize characters. + +**/ +VOID +EFIAPI +Ring3UnicodeFatToStr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ); + +/** + Converts a Null-terminated string to legal characters in a FAT + filename using an OEM character set. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + @param FatSize The size of the string Fat in bytes. + @param Fat A pointer to a string that contains the converted version of + String using legal FAT characters from an OEM character set. + + @retval TRUE One or more conversions failed and were substituted with '_' + @retval FALSE None of the conversions failed. + +**/ +BOOLEAN +EFIAPI +Ring3UnicodeStrToFat ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c index a3b082af82..4bd19be66e 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c @@ -112,3 +112,99 @@ Ring3DiskIoWrite ( Buffer ); } + +INTN +EFIAPI +Ring3UnicodeStriColl ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *Str1, + IN CHAR16 *Str2 + ) +{ + return (INTN)SysCall ( + SysCallUnicodeStriColl, + This, + Str1, + Str2 + ); +} + +BOOLEAN +EFIAPI +Ring3UnicodeMetaiMatch ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ) +{ + return (BOOLEAN)SysCall ( + SysCallUnicodeMetaiMatch, + This, + String, + Pattern + ); +} + +VOID +EFIAPI +Ring3UnicodeStrLwr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +{ + SysCall ( + SysCallUnicodeStrLwr, + This, + Str + ); +} + +VOID +EFIAPI +Ring3UnicodeStrUpr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +{ + SysCall ( + SysCallUnicodeStrUpr, + This, + Str + ); +} + +VOID +EFIAPI +Ring3UnicodeFatToStr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ) +{ + SysCall ( + SysCallUnicodeFatToStr, + This, + FatSize, + Fat, + String + ); +} + +BOOLEAN +EFIAPI +Ring3UnicodeStrToFat ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ) +{ + return (BOOLEAN)SysCall ( + SysCallUnicodeStrToFat, + This, + String, + FatSize, + Fat + ); +} diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index d7490da4d8..cda6f373be 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -29,6 +29,7 @@ FixInterface ( EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_DISK_IO_PROTOCOL *DiskIo; EFI_DEVICE_PATH_UTILITIES_PROTOCOL *DevicePath; + EFI_UNICODE_COLLATION_PROTOCOL *Unicode; ASSERT (Protocol != NULL); ASSERT (Interface != NULL); @@ -71,6 +72,16 @@ FixInterface ( DevicePath->IsDevicePathMultiInstance = NULL; DevicePath->CreateDeviceNode = NULL; + } else if (CompareGuid (Protocol, &gEfiUnicodeCollationProtocolGuid)) { + Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)*Interface; + + Unicode->StriColl = Ring3UnicodeStriColl; + Unicode->MetaiMatch = Ring3UnicodeMetaiMatch; + Unicode->StrLwr = Ring3UnicodeStrLwr; + Unicode->StrUpr = Ring3UnicodeStrUpr; + Unicode->FatToStr = Ring3UnicodeFatToStr; + Unicode->StrToFat = Ring3UnicodeStrToFat; + } else { return EFI_UNSUPPORTED; } @@ -568,9 +579,14 @@ Ring3LocateHandleBuffer ( OUT EFI_HANDLE **Buffer ) { - DEBUG ((DEBUG_ERROR, "Ring3: LocateHandleBuffer is not supported\n")); - - return EFI_UNSUPPORTED; + return SysCall ( + SysCallLocateHandleBuffer, + SearchType, + Protocol, + SearchKey, + NumberHandles, + Buffer + ); } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index a4ab6ac7eb..f6a1b79f4e 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -8,9 +8,11 @@ #include "DxeMain.h" #include "SupportedProtocols.h" -EFI_DISK_IO_PROTOCOL *mCoreDiskIoProtocol; -EFI_BLOCK_IO_PROTOCOL *mCoreBlockIoProtocol; -UINTN mRing3InterfacePointer = 0; +EFI_DISK_IO_PROTOCOL *mCoreDiskIoProtocol; +EFI_BLOCK_IO_PROTOCOL *mCoreBlockIoProtocol; +EFI_UNICODE_COLLATION_PROTOCOL *mCoreUnicodeCollationProtocol; + +UINTN mRing3InterfacePointer = 0; EFI_STATUS EFIAPI @@ -78,6 +80,11 @@ FindGuid ( *Core = &gEfiSimpleFileSystemProtocolGuid; *CoreSize = sizeof (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiUnicodeCollationProtocolGuid)) { + + *Core = &gEfiUnicodeCollationProtocolGuid; + *CoreSize = sizeof (EFI_UNICODE_COLLATION_PROTOCOL); + } else { DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol - %g.\n", Ring3)); return EFI_NOT_FOUND; @@ -95,9 +102,11 @@ PrepareRing3Interface ( IN UINT32 CoreSize ) { - UINTN Ring3Limit; - VOID *Ring3Interface; - EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_STATUS Status; + UINTN Ring3Limit; + VOID *Ring3Interface; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_UNICODE_COLLATION_PROTOCOL *Unicode; ASSERT (Guid != NULL); ASSERT (CoreInterface != NULL); @@ -130,6 +139,25 @@ PrepareRing3Interface ( BlockIo->Media = (EFI_BLOCK_IO_MEDIA *)mRing3InterfacePointer; mRing3InterfacePointer += sizeof (EFI_BLOCK_IO_MEDIA); + } else if (CompareGuid (Guid, &gEfiUnicodeCollationProtocolGuid)) { + + mCoreUnicodeCollationProtocol = (EFI_UNICODE_COLLATION_PROTOCOL *)CoreInterface; + Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)Ring3Interface; + + ASSERT ((mRing3InterfacePointer + AsciiStrSize (Unicode->SupportedLanguages)) <= Ring3Limit); + + Status = AsciiStrCpyS ( + (CHAR8 *)mRing3InterfacePointer, + AsciiStrSize (Unicode->SupportedLanguages), + Unicode->SupportedLanguages + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + Unicode->SupportedLanguages = (CHAR8 *)mRing3InterfacePointer; + + mRing3InterfacePointer += AsciiStrSize (Unicode->SupportedLanguages); } return Ring3Interface; @@ -164,6 +192,7 @@ CallBootService ( ) { EFI_STATUS Status; + EFI_STATUS StatusBS; UINT64 Attributes; VOID *Interface; EFI_GUID *CoreProtocol; @@ -175,9 +204,15 @@ CallBootService ( VOID **UserArgList; VOID *CoreArgList[MAX_LIST]; EFI_HANDLE CoreHandle; + VOID *Ring3Pages; + UINT32 PagesNumber; EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem; + + Argument4 = 0; + Argument5 = 0; + Argument6 = 0; // // Check User variables. // @@ -494,6 +529,77 @@ CallBootService ( return EFI_SUCCESS; + case SysCallLocateHandleBuffer: + // + // Argument 1: EFI_LOCATE_SEARCH_TYPE SearchType + // Argument 2: EFI_GUID *Protocol OPTIONAL + // Argument 3: VOID *SearchKey OPTIONAL, + // Argument 4: UINTN *NumberHandles, + // Argument 5: EFI_HANDLE **Buffer + // + if ((EFI_GUID *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + EnableSMAP (); + if (EFI_ERROR (Status)) { + return Status; + } + } + + StatusBS = gBS->LocateHandleBuffer ( + (EFI_LOCATE_SEARCH_TYPE)CoreRbp->Argument1, + CoreProtocol, + (VOID *)CoreRbp->Argument3, + &Argument4, + (EFI_HANDLE **)&Argument5 + ); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + if ((UINTN *)UserRsp->Arguments[4] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + *(UINTN *)UserRsp->Arguments[4] = Argument4; + } + + if ((UINTN *)UserRsp->Arguments[5] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + sizeof (EFI_HANDLE *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + PagesNumber = EFI_SIZE_TO_PAGES (Argument4 * sizeof (EFI_HANDLE *)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + (EFI_PHYSICAL_ADDRESS *)&Ring3Pages + ); + if (EFI_ERROR (Status)) { + return Status; + } + + CopyMem (Ring3Pages, (VOID *)Argument5, Argument4 * sizeof (EFI_HANDLE *)); + + FreePool ((VOID *)Argument5); + + *(EFI_HANDLE **)UserRsp->Arguments[5] = (EFI_HANDLE *)Ring3Pages; + } + EnableSMAP (); + + return StatusBS; + case SysCallBlockIoReset: // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This @@ -673,6 +779,312 @@ CallBootService ( FreePool ((VOID *)Argument5); return Status; + + case SysCallUnicodeStriColl: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *Str1 + // Argument 3: CHAR16 *Str2 + // + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + if ((CHAR16 *)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); + EnableSMAP (); + if ((VOID *)Argument5 == NULL) { + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + return EFI_OUT_OF_RESOURCES; + } + } + + Status = (EFI_STATUS)mCoreUnicodeCollationProtocol->StriColl ( + mCoreUnicodeCollationProtocol, + (CHAR16 *)Argument4, + (CHAR16 *)Argument5 + ); + + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + if ((VOID *)Argument5 != NULL) { + FreePool ((VOID *)Argument5); + } + + return Status; + + case SysCallUnicodeMetaiMatch: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *String + // Argument 3: CHAR16 *Pattern + // + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + if ((CHAR16 *)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); + EnableSMAP (); + if ((VOID *)Argument5 == NULL) { + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + return EFI_OUT_OF_RESOURCES; + } + } + + Status = (EFI_STATUS)mCoreUnicodeCollationProtocol->MetaiMatch ( + mCoreUnicodeCollationProtocol, + (CHAR16 *)Argument4, + (CHAR16 *)Argument5 + ); + + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + if ((VOID *)Argument5 != NULL) { + FreePool ((VOID *)Argument5); + } + + return Status; + + case SysCallUnicodeStrLwr: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *Str + // + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + mCoreUnicodeCollationProtocol->StrLwr ( + mCoreUnicodeCollationProtocol, + (CHAR16 *)Argument4 + ); + + if ((VOID *)Argument4 != NULL) { + DisableSMAP (); + Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument4); + } + + return Status; + + case SysCallUnicodeStrUpr: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *Str + // + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + mCoreUnicodeCollationProtocol->StrUpr ( + mCoreUnicodeCollationProtocol, + (CHAR16 *)Argument4 + ); + + if ((VOID *)Argument4 != NULL) { + DisableSMAP (); + Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument4); + } + + return Status; + + case SysCallUnicodeFatToStr: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: UINTN FatSize + // Argument 3: CHAR8 *Fat + // Argument 4: CHAR16 *String + // + if ((CHAR8 *)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + CoreRbp->Argument2 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Argument4 = (UINTN)AllocateCopyPool (CoreRbp->Argument2, (CHAR8 *)CoreRbp->Argument3); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + if ((CHAR16 *)UserRsp->Arguments[4] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + 2 * CoreRbp->Argument2 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (2 * CoreRbp->Argument2); + if ((VOID *)Argument5 == NULL) { + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + return EFI_OUT_OF_RESOURCES; + } + } + + mCoreUnicodeCollationProtocol->FatToStr ( + mCoreUnicodeCollationProtocol, + CoreRbp->Argument2, + (CHAR8 *)Argument4, + (CHAR16 *)Argument5 + ); + + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + if ((VOID *)Argument5 != NULL) { + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, 2 * CoreRbp->Argument2); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + } + + return EFI_SUCCESS; + + case SysCallUnicodeStrToFat: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *String + // Argument 3: UINTN FatSize + // Argument 4: CHAR8 *Fat + // + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + if ((CHAR8 *)UserRsp->Arguments[4] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + if ((VOID *)Argument5 == NULL) { + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + return EFI_OUT_OF_RESOURCES; + } + } + + mCoreUnicodeCollationProtocol->StrToFat ( + mCoreUnicodeCollationProtocol, + (CHAR16 *)Argument4, + CoreRbp->Argument3, + (CHAR8 *)Argument5 + ); + + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + if ((VOID *)Argument5 != NULL) { + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + } + + return EFI_SUCCESS; + default: DEBUG ((DEBUG_ERROR, "Ring0: Unknown syscall type.\n")); break; diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h index 200c51d242..8f77026355 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -9,6 +9,7 @@ #include #include #include +#include extern EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index ec0c22ab9a..e5097bd8d0 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2039,6 +2039,7 @@ typedef enum { SysCallFreePages, SysCallRaiseTpl, SysCallRestoreTpl, + SysCallLocateHandleBuffer, // // RuntimeServices // @@ -2051,6 +2052,12 @@ typedef enum { SysCallBlockIoFlush, SysCallDiskIoRead, SysCallDiskIoWrite, + SysCallUnicodeStriColl, + SysCallUnicodeMetaiMatch, + SysCallUnicodeStrLwr, + SysCallUnicodeStrUpr, + SysCallUnicodeFatToStr, + SysCallUnicodeStrToFat, SysCallMax } SYS_CALL_TYPE; From 8a5b1b0e87eeeeff30f5c10b0273ffd3ae38d41b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 11 Mar 2024 13:07:10 +0300 Subject: [PATCH 183/341] Ring3: Added SysCallGetVariable wrapper. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 7 +- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf | 1 + .../Dxe/DxeRing3/Ring3UefiRuntimeServices.c | 11 +- MdeModulePkg/Core/Dxe/Image/Image.c | 3 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 108 ++++++++++++++++-- MdePkg/Include/Uefi/UefiSpec.h | 8 +- 7 files changed, 123 insertions(+), 16 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index a5041925f6..1b3377f943 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -133,6 +133,7 @@ gEfiEndOfDxeEventGroupGuid ## SOMETIMES_CONSUMES ## Event gEfiHobMemoryAllocStackGuid ## SOMETIMES_CONSUMES ## SystemTable gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB + gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## SysCall [Ppis] gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index 53c7ff00f4..e0800f446f 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "Ring3.h" @@ -200,10 +201,12 @@ Ring3Initialization ( Ring3Data = (RING3_DATA *)SystemTable; - Ring3Data->EntryPoint = (VOID *)Ring3EntryPoint; - Ring3Data->BootServices = &mBootServices; + Ring3Data->EntryPoint = (VOID *)Ring3EntryPoint; + Ring3Data->BootServices = &mBootServices; + Ring3Data->RuntimeServices = &mRuntimeServices; gBS = &mBootServices; + gRT = &mRuntimeServices; CoreInitializePool (); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index 71cc66b2e2..426e9e07c3 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -42,6 +42,7 @@ MemoryPoolLib UefiBootServicesTableLib UefiDriverEntryPoint + UefiRuntimeServicesTableLib [Protocols] gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c index bb579e8b15..aabd1f1e26 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c @@ -89,9 +89,14 @@ Ring3GetVariable ( OUT VOID *Data OPTIONAL ) { - DEBUG ((DEBUG_ERROR, "Ring3: GetVariable is not supported\n")); - - return EFI_UNSUPPORTED; + return SysCall ( + SysCallGetVariable, + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 18112c3441..d96e23420c 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1611,7 +1611,8 @@ InitializeRing3 ( gRing3EntryPoint = gRing3Data->EntryPoint; - gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; + gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; + gRing3Data->SystemTable.RuntimeServices = gRing3Data->RuntimeServices; Status = CoreAllocatePages ( AllocateAnyPages, diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index f6a1b79f4e..212204e5cb 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -85,6 +85,10 @@ FindGuid ( *Core = &gEfiUnicodeCollationProtocolGuid; *CoreSize = sizeof (EFI_UNICODE_COLLATION_PROTOCOL); + } else if (CompareGuid (Ring3, &gEfiGlobalVariableGuid)) { + + *Core = &gEfiGlobalVariableGuid; + } else { DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol - %g.\n", Ring3)); return EFI_NOT_FOUND; @@ -533,8 +537,8 @@ CallBootService ( // // Argument 1: EFI_LOCATE_SEARCH_TYPE SearchType // Argument 2: EFI_GUID *Protocol OPTIONAL - // Argument 3: VOID *SearchKey OPTIONAL, - // Argument 4: UINTN *NumberHandles, + // Argument 3: VOID *SearchKey OPTIONAL + // Argument 4: UINTN *NumberHandles // Argument 5: EFI_HANDLE **Buffer // if ((EFI_GUID *)CoreRbp->Argument2 != NULL) { @@ -581,11 +585,11 @@ CallBootService ( PagesNumber = EFI_SIZE_TO_PAGES (Argument4 * sizeof (EFI_HANDLE *)); Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - PagesNumber, - (EFI_PHYSICAL_ADDRESS *)&Ring3Pages - ); + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + (EFI_PHYSICAL_ADDRESS *)&Ring3Pages + ); if (EFI_ERROR (Status)) { return Status; } @@ -600,6 +604,96 @@ CallBootService ( return StatusBS; + case SysCallGetVariable: + // + // Argument 1: CHAR16 *VariableName + // Argument 2: EFI_GUID *VendorGuid + // Argument 3: UINT32 *Attributes OPTIONAL + // Argument 4: UINTN *DataSize + // Argument 5: VOID *Data OPTIONAL + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + if ((UINT32 *)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (UINT32) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + } + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + StrSize ((CHAR16 *)CoreRbp->Argument1) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument6 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument1), (CHAR16 *)CoreRbp->Argument1); + if ((VOID *)Argument6 == NULL) { + EnableSMAP (); + return EFI_OUT_OF_RESOURCES; + } + + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + FreePool ((VOID *)Argument6); + return Status; + } + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = *(UINTN *)UserRsp->Arguments[4]; + + if ((VOID *)UserRsp->Arguments[5] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + Argument4 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (Argument4); + if ((VOID *)Argument5 == NULL) { + EnableSMAP (); + FreePool ((VOID *)Argument6); + return EFI_OUT_OF_RESOURCES; + } + } + EnableSMAP (); + + Status = gRT->GetVariable ( + (CHAR16 *)Argument6, + CoreProtocol, + (UINT32 *)&Attributes, + &Argument4, + (VOID *)Argument5 + ); + + DisableSMAP (); + if ((VOID *)UserRsp->Arguments[5] != NULL) { + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + } + + *(UINTN *)UserRsp->Arguments[4] = Argument4; + + if ((UINT32 *)CoreRbp->Argument3 != NULL) { + *(UINT32 *)CoreRbp->Argument3 = (UINT32)Attributes; + } + EnableSMAP (); + + FreePool ((VOID *)Argument6); + + if ((VOID *)Argument5 != NULL) { + FreePool ((VOID *)Argument5); + } + + return Status; + case SysCallBlockIoReset: // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index e5097bd8d0..25a50391c9 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2043,6 +2043,7 @@ typedef enum { // // RuntimeServices // + SysCallGetVariable, // // Protocols // @@ -2149,9 +2150,10 @@ typedef struct { } EFI_SYSTEM_TABLE; typedef struct { - EFI_SYSTEM_TABLE SystemTable; - VOID *EntryPoint; - EFI_BOOT_SERVICES *BootServices; + EFI_SYSTEM_TABLE SystemTable; + VOID *EntryPoint; + EFI_BOOT_SERVICES *BootServices; + EFI_RUNTIME_SERVICES *RuntimeServices; } RING3_DATA; typedef struct { From 1cd671b9c0d637c007ab1bc15100e63e0b431b31 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 11 Mar 2024 17:00:20 +0300 Subject: [PATCH 184/341] Ring3: Fixed Ring3LocateHandleBuffer(). --- MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h | 36 --------------- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 45 +++++++++++++++---- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 2 +- 3 files changed, 38 insertions(+), 45 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h index fd5a605505..235af1eddb 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h @@ -131,42 +131,6 @@ Ring3GetMemoryMap ( OUT UINT32 *DescriptorVersion ); -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -Ring3AllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ); - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -Ring3FreePool ( - IN VOID *Buffer - ); - /** Creates an event. diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index cda6f373be..6a23b4ba79 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -12,6 +12,7 @@ #include #include +#include #include "Ring3.h" @@ -579,14 +580,42 @@ Ring3LocateHandleBuffer ( OUT EFI_HANDLE **Buffer ) { - return SysCall ( - SysCallLocateHandleBuffer, - SearchType, - Protocol, - SearchKey, - NumberHandles, - Buffer - ); + EFI_STATUS Status; + EFI_STATUS StatusBS; + VOID *Pool; + UINTN PoolSize; + + StatusBS = SysCall ( + SysCallLocateHandleBuffer, + SearchType, + Protocol, + SearchKey, + NumberHandles, + Buffer + ); + + if ((NumberHandles != NULL) && (Buffer != NULL) && (*Buffer != NULL)) { + PoolSize = *NumberHandles * sizeof (EFI_HANDLE *); + + Status = CoreAllocatePool (EfiRing3MemoryType, PoolSize, &Pool); + if (EFI_ERROR (Status)) { + return Status; + } + + CopyMem (Pool, *Buffer, PoolSize); + + Status = Ring3FreePages ( + (EFI_PHYSICAL_ADDRESS)*Buffer, + EFI_SIZE_TO_PAGES (PoolSize) + ); + if (EFI_ERROR (Status)) { + return Status; + } + + *Buffer = Pool; + } + + return StatusBS; } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 212204e5cb..320a4b4235 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -576,7 +576,7 @@ CallBootService ( *(UINTN *)UserRsp->Arguments[4] = Argument4; } - if ((UINTN *)UserRsp->Arguments[5] != NULL) { + if ((EFI_HANDLE **)UserRsp->Arguments[5] != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + sizeof (EFI_HANDLE *) - 1), &Attributes); From 9f95ddaede6c95e91d2fb722a3bd1662bf8f4319 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 12 Mar 2024 12:44:35 +0300 Subject: [PATCH 185/341] SysCall: Refactored protocols handling. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 278 +++++++++++++------ 1 file changed, 197 insertions(+), 81 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 320a4b4235..6005cf7ec8 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -7,10 +7,16 @@ #include "DxeMain.h" #include "SupportedProtocols.h" +// +// TODO: Free LIST in ExitBootServices +// +LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead); -EFI_DISK_IO_PROTOCOL *mCoreDiskIoProtocol; -EFI_BLOCK_IO_PROTOCOL *mCoreBlockIoProtocol; -EFI_UNICODE_COLLATION_PROTOCOL *mCoreUnicodeCollationProtocol; +typedef struct { + VOID *Core; + VOID *Ring3; + LIST_ENTRY Link; +} INTERFACE; UINTN mRing3InterfacePointer = 0; @@ -97,6 +103,34 @@ FindGuid ( return EFI_SUCCESS; } +STATIC +VOID * +EFIAPI +FindInterface ( + IN BOOLEAN FindRing3, + IN VOID *Interface + ) +{ + LIST_ENTRY *Link; + INTERFACE *Protocol; + + for (Link = mProtocolsHead.ForwardLink; Link != &mProtocolsHead; Link = Link->ForwardLink) { + Protocol = BASE_CR (Link, INTERFACE, Link); + + if (FindRing3) { + if (Protocol->Core == Interface) { + return Protocol->Ring3; + } + } else { + if (Protocol->Ring3 == Interface) { + return Protocol->Core; + } + } + } + + return NULL; +} + STATIC VOID * EFIAPI @@ -111,6 +145,7 @@ PrepareRing3Interface ( VOID *Ring3Interface; EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_UNICODE_COLLATION_PROTOCOL *Unicode; + INTERFACE *Protocol; ASSERT (Guid != NULL); ASSERT (CoreInterface != NULL); @@ -119,6 +154,12 @@ PrepareRing3Interface ( mRing3InterfacePointer = (UINTN)gRing3Interfaces; } + Ring3Interface = FindInterface (TRUE, CoreInterface); + + if (Ring3Interface != NULL) { + return Ring3Interface; + } + Ring3Limit = (UINTN)gRing3Interfaces + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES); ASSERT ((mRing3InterfacePointer + CoreSize) <= Ring3Limit); @@ -128,15 +169,17 @@ PrepareRing3Interface ( CopyMem ((VOID *)mRing3InterfacePointer, CoreInterface, CoreSize); mRing3InterfacePointer += CoreSize; - if (CompareGuid (Guid, &gEfiDiskIoProtocolGuid)) { + Protocol = AllocatePool (sizeof (INTERFACE)); - mCoreDiskIoProtocol = (EFI_DISK_IO_PROTOCOL *)CoreInterface; + Protocol->Core = CoreInterface; + Protocol->Ring3 = Ring3Interface; - } else if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) { + InsertTailList (&mProtocolsHead, &Protocol->Link); + + if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) { ASSERT ((mRing3InterfacePointer + sizeof (EFI_BLOCK_IO_MEDIA)) <= Ring3Limit); - mCoreBlockIoProtocol = (EFI_BLOCK_IO_PROTOCOL *)CoreInterface; - BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Ring3Interface; + BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Ring3Interface; CopyMem ((VOID *)mRing3InterfacePointer, (VOID *)BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA)); @@ -145,8 +188,7 @@ PrepareRing3Interface ( mRing3InterfacePointer += sizeof (EFI_BLOCK_IO_MEDIA); } else if (CompareGuid (Guid, &gEfiUnicodeCollationProtocolGuid)) { - mCoreUnicodeCollationProtocol = (EFI_UNICODE_COLLATION_PROTOCOL *)CoreInterface; - Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)Ring3Interface; + Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)Ring3Interface; ASSERT ((mRing3InterfacePointer + AsciiStrSize (Unicode->SupportedLanguages)) <= Ring3Limit); @@ -214,6 +256,10 @@ CallBootService ( EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_UNICODE_COLLATION_PROTOCOL *Unicode; + Argument4 = 0; Argument5 = 0; Argument6 = 0; @@ -305,15 +351,15 @@ CallBootService ( (UINT32)Argument6 ); - DisableSMAP (); - if (Interface != NULL) { - Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); - } - if ((VOID **)CoreRbp->Argument3 != NULL) { + DisableSMAP (); + if (Interface != NULL) { + Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); + } + *(VOID **)CoreRbp->Argument3 = Interface; + EnableSMAP (); } - EnableSMAP (); return Status; @@ -699,10 +745,16 @@ CallBootService ( // Argument 1: EFI_BLOCK_IO_PROTOCOL *This // Argument 2: BOOLEAN ExtendedVerification // - return mCoreBlockIoProtocol->Reset ( - mCoreBlockIoProtocol, - (BOOLEAN)CoreRbp->Argument2 - ); + BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (BlockIo == NULL) { + return EFI_NOT_FOUND; + } + + return BlockIo->Reset ( + BlockIo, + (BOOLEAN)CoreRbp->Argument2 + ); case SysCallBlockIoRead: // @@ -712,6 +764,12 @@ CallBootService ( // Argument 4: UINTN BufferSize // Argument 5: VOID *Buffer // + BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (BlockIo == NULL) { + return EFI_NOT_FOUND; + } + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -724,13 +782,13 @@ CallBootService ( return EFI_OUT_OF_RESOURCES; } - Status = mCoreBlockIoProtocol->ReadBlocks ( - mCoreBlockIoProtocol, - (UINT32)CoreRbp->Argument2, - (EFI_LBA)CoreRbp->Argument3, - Argument4, - (VOID *)Argument5 - ); + Status = BlockIo->ReadBlocks ( + BlockIo, + (UINT32)CoreRbp->Argument2, + (EFI_LBA)CoreRbp->Argument3, + Argument4, + (VOID *)Argument5 + ); DisableSMAP (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -752,6 +810,12 @@ CallBootService ( // Argument 4: UINTN BufferSize // Argument 5: VOID *Buffer // + BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (BlockIo == NULL) { + return EFI_NOT_FOUND; + } + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -773,13 +837,13 @@ CallBootService ( CopyMem ((VOID *)Argument5,(VOID *)UserRsp->Arguments[5], Argument4); EnableSMAP (); - Status = mCoreBlockIoProtocol->WriteBlocks ( - mCoreBlockIoProtocol, - (UINT32)CoreRbp->Argument2, - (EFI_LBA)CoreRbp->Argument3, - Argument4, - (VOID *)Argument5 - ); + Status = BlockIo->WriteBlocks ( + BlockIo, + (UINT32)CoreRbp->Argument2, + (EFI_LBA)CoreRbp->Argument3, + Argument4, + (VOID *)Argument5 + ); FreePool ((VOID *)Argument5); @@ -789,9 +853,13 @@ CallBootService ( // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This // - return mCoreBlockIoProtocol->FlushBlocks ( - mCoreBlockIoProtocol - ); + BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (BlockIo == NULL) { + return EFI_NOT_FOUND; + } + + return BlockIo->FlushBlocks (BlockIo); case SysCallDiskIoRead: // @@ -801,6 +869,12 @@ CallBootService ( // Argument 4: UINTN BufferSize // Argument 5: VOID *Buffer // + DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (DiskIo == NULL) { + return EFI_NOT_FOUND; + } + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -813,13 +887,13 @@ CallBootService ( return EFI_OUT_OF_RESOURCES; } - Status = mCoreDiskIoProtocol->ReadDisk ( - mCoreDiskIoProtocol, - (UINT32)CoreRbp->Argument2, - (UINT64)CoreRbp->Argument3, - Argument4, - (VOID *)Argument5 - ); + Status = DiskIo->ReadDisk ( + DiskIo, + (UINT32)CoreRbp->Argument2, + (UINT64)CoreRbp->Argument3, + Argument4, + (VOID *)Argument5 + ); DisableSMAP (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -841,6 +915,12 @@ CallBootService ( // Argument 4: UINTN BufferSize // Argument 5: VOID *Buffer // + DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (DiskIo == NULL) { + return EFI_NOT_FOUND; + } + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -862,13 +942,13 @@ CallBootService ( CopyMem ((VOID *)Argument5, (VOID *)UserRsp->Arguments[5], Argument4); EnableSMAP (); - Status = mCoreDiskIoProtocol->WriteDisk ( - mCoreDiskIoProtocol, - (UINT32)CoreRbp->Argument2, - (UINT64)CoreRbp->Argument3, - Argument4, - (VOID *)Argument5 - ); + Status = DiskIo->WriteDisk ( + DiskIo, + (UINT32)CoreRbp->Argument2, + (UINT64)CoreRbp->Argument3, + Argument4, + (VOID *)Argument5 + ); FreePool ((VOID *)Argument5); @@ -880,6 +960,12 @@ CallBootService ( // Argument 2: CHAR16 *Str1 // Argument 3: CHAR16 *Str2 // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -914,11 +1000,11 @@ CallBootService ( } } - Status = (EFI_STATUS)mCoreUnicodeCollationProtocol->StriColl ( - mCoreUnicodeCollationProtocol, - (CHAR16 *)Argument4, - (CHAR16 *)Argument5 - ); + Status = (EFI_STATUS)Unicode->StriColl ( + Unicode, + (CHAR16 *)Argument4, + (CHAR16 *)Argument5 + ); if ((VOID *)Argument4 != NULL) { FreePool ((VOID *)Argument4); @@ -936,6 +1022,12 @@ CallBootService ( // Argument 2: CHAR16 *String // Argument 3: CHAR16 *Pattern // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -970,11 +1062,11 @@ CallBootService ( } } - Status = (EFI_STATUS)mCoreUnicodeCollationProtocol->MetaiMatch ( - mCoreUnicodeCollationProtocol, - (CHAR16 *)Argument4, - (CHAR16 *)Argument5 - ); + Status = (EFI_STATUS)Unicode->MetaiMatch ( + Unicode, + (CHAR16 *)Argument4, + (CHAR16 *)Argument5 + ); if ((VOID *)Argument4 != NULL) { FreePool ((VOID *)Argument4); @@ -991,6 +1083,12 @@ CallBootService ( // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This // Argument 2: CHAR16 *Str // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1006,10 +1104,10 @@ CallBootService ( } } - mCoreUnicodeCollationProtocol->StrLwr ( - mCoreUnicodeCollationProtocol, - (CHAR16 *)Argument4 - ); + Unicode->StrLwr ( + Unicode, + (CHAR16 *)Argument4 + ); if ((VOID *)Argument4 != NULL) { DisableSMAP (); @@ -1026,6 +1124,12 @@ CallBootService ( // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This // Argument 2: CHAR16 *Str // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1041,10 +1145,10 @@ CallBootService ( } } - mCoreUnicodeCollationProtocol->StrUpr ( - mCoreUnicodeCollationProtocol, - (CHAR16 *)Argument4 - ); + Unicode->StrUpr ( + Unicode, + (CHAR16 *)Argument4 + ); if ((VOID *)Argument4 != NULL) { DisableSMAP (); @@ -1063,6 +1167,12 @@ CallBootService ( // Argument 3: CHAR8 *Fat // Argument 4: CHAR16 *String // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + if ((CHAR8 *)CoreRbp->Argument3 != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1096,12 +1206,12 @@ CallBootService ( } } - mCoreUnicodeCollationProtocol->FatToStr ( - mCoreUnicodeCollationProtocol, - CoreRbp->Argument2, - (CHAR8 *)Argument4, - (CHAR16 *)Argument5 - ); + Unicode->FatToStr ( + Unicode, + CoreRbp->Argument2, + (CHAR8 *)Argument4, + (CHAR16 *)Argument5 + ); if ((VOID *)Argument4 != NULL) { FreePool ((VOID *)Argument4); @@ -1124,6 +1234,12 @@ CallBootService ( // Argument 3: UINTN FatSize // Argument 4: CHAR8 *Fat // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1158,12 +1274,12 @@ CallBootService ( } } - mCoreUnicodeCollationProtocol->StrToFat ( - mCoreUnicodeCollationProtocol, - (CHAR16 *)Argument4, - CoreRbp->Argument3, - (CHAR8 *)Argument5 - ); + Unicode->StrToFat ( + Unicode, + (CHAR16 *)Argument4, + CoreRbp->Argument3, + (CHAR8 *)Argument5 + ); if ((VOID *)Argument4 != NULL) { FreePool ((VOID *)Argument4); From c2df986ad8b47d5cdb748481bfc778108a1d9067 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 12 Mar 2024 12:45:40 +0300 Subject: [PATCH 186/341] SysCall: Fixed UnicodeCollation wrappers. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 6005cf7ec8..366fb45a77 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -1190,6 +1190,7 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + DisableSMAP (); if ((CHAR16 *)UserRsp->Arguments[4] != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1205,6 +1206,7 @@ CallBootService ( return EFI_OUT_OF_RESOURCES; } } + EnableSMAP (); Unicode->FatToStr ( Unicode, @@ -1258,6 +1260,7 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + DisableSMAP (); if ((CHAR8 *)UserRsp->Arguments[4] != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1273,6 +1276,7 @@ CallBootService ( return EFI_OUT_OF_RESOURCES; } } + EnableSMAP (); Unicode->StrToFat ( Unicode, From 44d092b687fa3cd6a840109c3180c2293a72d7e3 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 12 Mar 2024 13:25:08 +0300 Subject: [PATCH 187/341] Ring3: Added SysCallCalculateCrc32 wrapper. --- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 9 +++-- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 36 +++++++++++++++++++ MdePkg/Include/Uefi/UefiSpec.h | 1 + 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 6a23b4ba79..54943444de 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -697,9 +697,12 @@ Ring3CalculateCrc32 ( OUT UINT32 *Crc32 ) { - DEBUG ((DEBUG_ERROR, "Ring3: CalculateCrc32 is not supported\n")); - - return EFI_UNSUPPORTED; + return SysCall ( + SysCallCalculateCrc32, + Data, + DataSize, + Crc32 + ); } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 366fb45a77..13abe746b6 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -650,6 +650,42 @@ CallBootService ( return StatusBS; + case SysCallCalculateCrc32: + // + // Argument 1: VOID *Data + // Argument 2: UINTN DataSize + // Argument 3: UINT32 *Crc32 + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + CoreRbp->Argument2 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (UINT32 *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocatePool (CoreRbp->Argument2); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + DisableSMAP (); + CopyMem ((VOID *)Argument4, (VOID *)CoreRbp->Argument1, CoreRbp->Argument2); + EnableSMAP (); + + Status = gBS->CalculateCrc32 ( + (VOID *)Argument4, + CoreRbp->Argument2, + (UINT32 *)&Argument5 + ); + + DisableSMAP (); + *(UINT32 *)CoreRbp->Argument3 = (UINT32)Argument5; + EnableSMAP (); + + return Status; + case SysCallGetVariable: // // Argument 1: CHAR16 *VariableName diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 25a50391c9..b6273143eb 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2040,6 +2040,7 @@ typedef enum { SysCallRaiseTpl, SysCallRestoreTpl, SysCallLocateHandleBuffer, + SysCallCalculateCrc32, // // RuntimeServices // From 178f3349ed0815ff0b7f1dc2d3d356aebb54618d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 12 Mar 2024 13:26:18 +0300 Subject: [PATCH 188/341] SysCall: Fixed UnicodeFatToStr wrapper. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 13abe746b6..c861e05797 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -1230,10 +1230,10 @@ CallBootService ( if ((CHAR16 *)UserRsp->Arguments[4] != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + 2 * CoreRbp->Argument2 - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + 2 * (CoreRbp->Argument2 + 1) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument5 = (UINTN)AllocatePool (2 * CoreRbp->Argument2); + Argument5 = (UINTN)AllocatePool (2 * (CoreRbp->Argument2 + 1)); if ((VOID *)Argument5 == NULL) { if ((VOID *)Argument4 != NULL) { FreePool ((VOID *)Argument4); @@ -1257,7 +1257,7 @@ CallBootService ( if ((VOID *)Argument5 != NULL) { DisableSMAP (); - CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, 2 * CoreRbp->Argument2); + CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, 2 * (CoreRbp->Argument2 + 1)); EnableSMAP (); FreePool ((VOID *)Argument5); From ee9ee1a92ea5e95880610d2989b0e16ea84bdd6d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 12 Mar 2024 13:41:07 +0300 Subject: [PATCH 189/341] Ring3: Moved InitializeRing3() to SysCall directory. --- MdeModulePkg/Core/Dxe/DxeMain.h | 7 + MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + MdeModulePkg/Core/Dxe/Image/Image.c | 145 ----------------- .../Core/Dxe/SysCall/Initialization.c | 154 ++++++++++++++++++ 4 files changed, 162 insertions(+), 145 deletions(-) create mode 100644 MdeModulePkg/Core/Dxe/SysCall/Initialization.c diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 353561c627..2232146b99 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2741,4 +2741,11 @@ GoToRing3 ( ... ); +EFI_STATUS +EFIAPI +InitializeRing3 ( + IN EFI_HANDLE ImageHandle, + IN LOADED_IMAGE_PRIVATE_DATA *Image + ); + #endif diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 1b3377f943..d94c569fd5 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -66,6 +66,7 @@ DxeMain/DxeProtocolNotify.c DxeMain/DxeMain.c SysCall/BootServices.c + SysCall/Initialization.c SysCall/SupportedProtocols.h SysCall/SupportedProtocols.c diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index d96e23420c..9b6f334e51 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -9,8 +9,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "DxeMain.h" #include "Image.h" -#include - // // Module Globals // @@ -27,11 +25,6 @@ STATIC EFI_EVENT mPeCoffEmuProtocolRegistrationEvent; STATIC VOID *mPeCoffEmuProtocolNotifyRegistration; extern BOOLEAN gBdsStarted; -VOID *gCoreSysCallStackTop; -VOID *gRing3CallStackTop; -VOID *gRing3EntryPoint; -RING3_DATA *gRing3Data; -VOID *gRing3Interfaces; // // This code is needed to build the Image handle for the DXE Core @@ -1570,144 +1563,6 @@ CoreLoadImage ( return Status; } -EFI_STATUS -EFIAPI -InitializeRing3 ( - IN EFI_HANDLE ImageHandle, - IN LOADED_IMAGE_PRIVATE_DATA *Image - ) -{ - EFI_STATUS Status; - VOID *BaseOfStack; - VOID *TopOfStack; - UINTN SizeOfStack; - UINT64 Msr; - IA32_CR4 Cr4; - IA32_EFLAGS32 Eflags; - UINT32 Ebx; - UINT32 Edx; - MSR_IA32_EFER_REGISTER MsrEfer; - - Ebx = 0; - Edx = 0; - - // - // Set Ring3 EntryPoint and BootServices. - // - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)), - (EFI_PHYSICAL_ADDRESS *)&gRing3Data - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Data.\n")); - return Status; - } - - CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); - - Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); - - gRing3EntryPoint = gRing3Data->EntryPoint; - - gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; - gRing3Data->SystemTable.RuntimeServices = gRing3Data->RuntimeServices; - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - RING3_INTERFACES_PAGES, - (EFI_PHYSICAL_ADDRESS *)&gRing3Interfaces - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Interfaces.\n")); - CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)gRing3Data, - EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) - ); - return Status; - } - - // - // Forbid supervisor-mode accesses to any user-mode pages. - // SMEP and SMAP must be supported. - // - AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); - // - // SYSCALL and SYSRET must be also supported. - // - AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); - if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) { - Cr4.UintN = AsmReadCr4 (); - Cr4.Bits.SMAP = 1; - Cr4.Bits.SMEP = 1; - AsmWriteCr4 (Cr4.UintN); - - Eflags.UintN = AsmReadEflags (); - Eflags.Bits.AC = 0; - AsmWriteEflags (Eflags.UintN); - // - // Enable SYSCALL and SYSRET. - // - MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); - MsrEfer.Bits.SCE = 1; - AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); - } - - SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; - - // - // Allocate 128KB for the Core SysCall Stack. - // - BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); - ASSERT (BaseOfStack != NULL); - - // - // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. - // - TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - gCoreSysCallStackTop = TopOfStack; - - SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP); - DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); - - // - // Allocate 128KB for the User Stack. - // - BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); - ASSERT (BaseOfStack != NULL); - - // - // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. - // - TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - gRing3CallStackTop = TopOfStack; - - SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); - DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); - - // - // Initialize MSR_IA32_STAR, MSR_IA32_LSTAR and MSR_IA32_FMASK for SYSCALL and SYSRET. - // - Msr = (((((UINT64)RING3_CODE64_SEL - 16) | 3) << 16) | (UINT64)RING0_CODE64_SEL) << 32; - AsmWriteMsr64 (MSR_IA32_STAR, Msr); - - Msr = (UINT64)(UINTN)CoreBootServices; - AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); - // - // Disable maskable interrupts at SYSCALL. - // - Msr = (UINT64)BIT9; - AsmWriteMsr64 (MSR_IA32_FMASK, Msr); - - return Status; -} - /** Transfer control to a loaded image's entry point. diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c new file mode 100644 index 0000000000..7ad0424a30 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -0,0 +1,154 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +#include + +VOID *gCoreSysCallStackTop; +VOID *gRing3CallStackTop; +VOID *gRing3EntryPoint; +RING3_DATA *gRing3Data; +VOID *gRing3Interfaces; + +EFI_STATUS +EFIAPI +InitializeRing3 ( + IN EFI_HANDLE ImageHandle, + IN LOADED_IMAGE_PRIVATE_DATA *Image + ) +{ + EFI_STATUS Status; + VOID *BaseOfStack; + VOID *TopOfStack; + UINTN SizeOfStack; + UINT64 Msr; + IA32_CR4 Cr4; + IA32_EFLAGS32 Eflags; + UINT32 Ebx; + UINT32 Edx; + MSR_IA32_EFER_REGISTER MsrEfer; + + Ebx = 0; + Edx = 0; + + // + // Set Ring3 EntryPoint and BootServices. + // + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)), + (EFI_PHYSICAL_ADDRESS *)&gRing3Data + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Data.\n")); + return Status; + } + + CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); + + Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); + + gRing3EntryPoint = gRing3Data->EntryPoint; + + gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; + gRing3Data->SystemTable.RuntimeServices = gRing3Data->RuntimeServices; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + RING3_INTERFACES_PAGES, + (EFI_PHYSICAL_ADDRESS *)&gRing3Interfaces + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Interfaces.\n")); + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)gRing3Data, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + ); + return Status; + } + + // + // Forbid supervisor-mode accesses to any user-mode pages. + // SMEP and SMAP must be supported. + // + AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); + // + // SYSCALL and SYSRET must be also supported. + // + AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); + if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) { + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMAP = 1; + Cr4.Bits.SMEP = 1; + AsmWriteCr4 (Cr4.UintN); + + Eflags.UintN = AsmReadEflags (); + Eflags.Bits.AC = 0; + AsmWriteEflags (Eflags.UintN); + // + // Enable SYSCALL and SYSRET. + // + MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); + MsrEfer.Bits.SCE = 1; + AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); + } + + SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; + + // + // Allocate 128KB for the Core SysCall Stack. + // + BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); + ASSERT (BaseOfStack != NULL); + + // + // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. + // + TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + gCoreSysCallStackTop = TopOfStack; + + SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP); + DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); + + // + // Allocate 128KB for the User Stack. + // + BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); + ASSERT (BaseOfStack != NULL); + + // + // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. + // + TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + gRing3CallStackTop = TopOfStack; + + SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); + DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); + + // + // Initialize MSR_IA32_STAR, MSR_IA32_LSTAR and MSR_IA32_FMASK for SYSCALL and SYSRET. + // + Msr = (((((UINT64)RING3_CODE64_SEL - 16) | 3) << 16) | (UINT64)RING0_CODE64_SEL) << 32; + AsmWriteMsr64 (MSR_IA32_STAR, Msr); + + Msr = (UINT64)(UINTN)CoreBootServices; + AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); + // + // Disable maskable interrupts at SYSCALL. + // + Msr = (UINT64)BIT9; + AsmWriteMsr64 (MSR_IA32_FMASK, Msr); + + return Status; +} From 3b854ffa0b31a10dfbda4feb5bbeb1159bfa23e8 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 12 Mar 2024 13:56:29 +0300 Subject: [PATCH 190/341] Ring3: Added FreeProtocolsList(). --- MdeModulePkg/Core/Dxe/DxeMain.h | 6 ++++++ MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 2 ++ MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 20 +++++++++++++++++--- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 2232146b99..05f48efc20 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2748,4 +2748,10 @@ InitializeRing3 ( IN LOADED_IMAGE_PRIVATE_DATA *Image ); +VOID +EFIAPI +FreeProtocolsList ( + VOID + ); + #endif diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 1e9fd2a3c2..08d533051f 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -861,6 +861,8 @@ CoreExitBootServices ( RING3_INTERFACES_PAGES ); + FreeProtocolsList (); + return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index c861e05797..dadb6cd12a 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -7,9 +7,7 @@ #include "DxeMain.h" #include "SupportedProtocols.h" -// -// TODO: Free LIST in ExitBootServices -// + LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead); typedef struct { @@ -29,6 +27,22 @@ CallInstallMultipleProtocolInterfaces ( IN VOID *Function ); +VOID +EFIAPI +FreeProtocolsList ( + VOID + ) +{ + LIST_ENTRY *Link; + INTERFACE *Protocol; + + for (Link = mProtocolsHead.BackLink; Link != &mProtocolsHead; Link = mProtocolsHead.BackLink) { + Protocol = BASE_CR (Link, INTERFACE, Link); + RemoveEntryList (Link); + FreePool (Protocol); + } +} + STATIC EFI_STATUS EFIAPI From 10f4ef7dba848ef66ee652defb492b810341c80b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 12 Mar 2024 16:02:30 +0300 Subject: [PATCH 191/341] Ring3: Properly freed Ring3 resources. --- MdeModulePkg/Core/Dxe/DxeMain.h | 2 + MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 41 +++++++++++++------ .../Core/Dxe/SysCall/Initialization.c | 19 +++++---- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 05f48efc20..a9253cb783 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -274,6 +274,8 @@ extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage; extern RING3_DATA *gRing3Data; extern VOID *gRing3Interfaces; +extern VOID *gCoreSysCallStackBase; +extern VOID *gRing3CallStackBase; // // Service Initialization Functions diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 08d533051f..a892df0d54 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -771,6 +771,35 @@ CoreExitBootServices ( { EFI_STATUS Status; + // + // Free resources allocated for Ring3. + // + if (gRing3Data != NULL) { + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)gRing3Data, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + ); + + gRing3Data = NULL; + + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)gRing3Interfaces, + RING3_INTERFACES_PAGES + ); + + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)gCoreSysCallStackBase, + EFI_SIZE_TO_PAGES (USER_STACK_SIZE) + ); + + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)gRing3CallStackBase, + EFI_SIZE_TO_PAGES (USER_STACK_SIZE) + ); + + FreeProtocolsList (); + } + // // Notify other drivers of their last chance to use boot services // before the memory map is terminated. @@ -851,18 +880,6 @@ CoreExitBootServices ( // gRuntime->AtRuntime = TRUE; - CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)gRing3Data, - EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) - ); - - CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)gRing3Interfaces, - RING3_INTERFACES_PAGES - ); - - FreeProtocolsList (); - return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 7ad0424a30..ec1b645acb 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -10,7 +10,9 @@ #include VOID *gCoreSysCallStackTop; +VOID *gCoreSysCallStackBase; VOID *gRing3CallStackTop; +VOID *gRing3CallStackBase; VOID *gRing3EntryPoint; RING3_DATA *gRing3Data; VOID *gRing3Interfaces; @@ -23,7 +25,6 @@ InitializeRing3 ( ) { EFI_STATUS Status; - VOID *BaseOfStack; VOID *TopOfStack; UINTN SizeOfStack; UINT64 Msr; @@ -105,35 +106,35 @@ InitializeRing3 ( // // Allocate 128KB for the Core SysCall Stack. // - BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); - ASSERT (BaseOfStack != NULL); + gCoreSysCallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); + ASSERT (gCoreSysCallStackBase != NULL); // // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. // - TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); + TopOfStack = (VOID *)((UINTN)gCoreSysCallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT); TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); gCoreSysCallStackTop = TopOfStack; - SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP); + SetUefiImageMemoryAttributes ((UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); // // Allocate 128KB for the User Stack. // - BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); - ASSERT (BaseOfStack != NULL); + gRing3CallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); + ASSERT (gRing3CallStackBase != NULL); // // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. // - TopOfStack = (VOID *)((UINTN)BaseOfStack + SizeOfStack - CPU_STACK_ALIGNMENT); + TopOfStack = (VOID *)((UINTN)gRing3CallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT); TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); gRing3CallStackTop = TopOfStack; - SetUefiImageMemoryAttributes ((UINTN)BaseOfStack, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); + SetUefiImageMemoryAttributes ((UINTN)gRing3CallStackBase, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); // From 608cd5c16adcdeeea7c9f80686ce77d42055b18c Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 12 Mar 2024 16:13:38 +0300 Subject: [PATCH 192/341] OvmfPkg: Added DxeRing3 driver, placed Fat driver into Ring3. --- OvmfPkg/OvmfPkgX64.dsc | 5 +++++ OvmfPkg/OvmfPkgX64.fdf | 2 ++ 2 files changed, 7 insertions(+) diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 0bc5f711e7..62ae6f3134 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -354,6 +354,7 @@ CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf + MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -891,6 +892,10 @@ MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf FatPkg/EnhancedFatDxe/Fat.inf + MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { + + MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf + } MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 5c93be7ca8..63d881cd92 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -235,6 +235,7 @@ APRIORI DXE { !if $(SMM_REQUIRE) == FALSE INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf !endif + INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf } # @@ -322,6 +323,7 @@ INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf INF FatPkg/EnhancedFatDxe/Fat.inf +INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf From 94324bcc1e4f310e3a270608600b57e6e41c514b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 12 Mar 2024 17:30:43 +0300 Subject: [PATCH 193/341] MdeModulePkg: Fixed MdeModulePkg compilation. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 3 + MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 10 +- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf | 3 + .../Core/Dxe/DxeRing3/IA32/SysCall.nasm | 38 +++++++ .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 4 +- MdeModulePkg/Core/Dxe/Image/Image.c | 2 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 31 +++--- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 98 +++++++++++++++++++ .../Core/Dxe/SysCall/Initialization.c | 2 +- .../Core/Dxe/SysCall/SupportedProtocols.c | 26 ++--- MdeModulePkg/MdeModulePkg.dsc | 5 +- MdePkg/Library/BaseLib/BaseLib.inf | 1 + MdePkg/Library/BaseLib/Ia32/WriteEflags.nasm | 33 +++++++ 13 files changed, 218 insertions(+), 38 deletions(-) create mode 100644 MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm create mode 100644 MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm create mode 100644 MdePkg/Library/BaseLib/Ia32/WriteEflags.nasm diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index d94c569fd5..18295d597a 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -70,6 +70,9 @@ SysCall/SupportedProtocols.h SysCall/SupportedProtocols.c +[Sources.IA32] + SysCall/IA32/CoreBootServices.nasm + [Sources.X64] SysCall/X64/CoreBootServices.nasm diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index a892df0d54..345aa25cf7 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -776,24 +776,24 @@ CoreExitBootServices ( // if (gRing3Data != NULL) { CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)gRing3Data, + (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) ); - + gRing3Data = NULL; CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)gRing3Interfaces, + (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Interfaces, RING3_INTERFACES_PAGES ); CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)gCoreSysCallStackBase, + (EFI_PHYSICAL_ADDRESS)(UINTN)gCoreSysCallStackBase, EFI_SIZE_TO_PAGES (USER_STACK_SIZE) ); CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)gRing3CallStackBase, + (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3CallStackBase, EFI_SIZE_TO_PAGES (USER_STACK_SIZE) ); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index 426e9e07c3..4c36e5a97e 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -28,6 +28,9 @@ Ring3UefiRuntimeServices.c Ring3Protocols.c +[Sources.IA32] + IA32/SysCall.nasm + [Sources.X64] X64/SysCall.nasm diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm new file mode 100644 index 0000000000..2f37ffe619 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +;------------------------------------------------------------------------------ + +extern ASM_PFX(Ring3Call) + +DEFAULT REL +SECTION .text + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; SysCall ( +; IN UINT8 Type, +; ... +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(SysCall) +ASM_PFX(SysCall): + sysenter + + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; Ring3EntryPoint ( +; IN RING3_CALL_DATA *Data +; ); +; +; (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3(). +; (rdx) Data +;------------------------------------------------------------------------------ +global ASM_PFX(Ring3EntryPoint) +ASM_PFX(Ring3EntryPoint): + + call ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 54943444de..e42fa8752b 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -605,7 +605,7 @@ Ring3LocateHandleBuffer ( CopyMem (Pool, *Buffer, PoolSize); Status = Ring3FreePages ( - (EFI_PHYSICAL_ADDRESS)*Buffer, + (EFI_PHYSICAL_ADDRESS)(UINTN)*Buffer, EFI_SIZE_TO_PAGES (PoolSize) ); if (EFI_ERROR (Status)) { @@ -764,7 +764,7 @@ CoreAllocatePoolPagesI ( Ring3AllocatePages (AllocateAnyPages, EfiRing3MemoryType, NoPages, &Memory); - return (VOID *)Memory; + return (VOID *)(UINTN)Memory; } VOID diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 9b6f334e51..a5d4e554e2 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1692,7 +1692,7 @@ CoreStartImage ( if (Image->IsRing3EntryPoint) { Image->Status = InitializeRing3 (ImageHandle, Image); } else if (Image->IsUserImage) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Image->EntryPoint, &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); Image->Status = GoToRing3 ( diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index dadb6cd12a..323cbb4ce3 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -274,13 +274,14 @@ CallBootService ( EFI_DISK_IO_PROTOCOL *DiskIo; EFI_UNICODE_COLLATION_PROTOCOL *Unicode; - Argument4 = 0; - Argument5 = 0; - Argument6 = 0; + CoreProtocol = NULL; + Argument4 = 0; + Argument5 = 0; + Argument6 = 0; // // Check User variables. // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp, &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserRsp, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); switch (Type) { @@ -398,7 +399,7 @@ CallBootService ( for (Index = 0; UserArgList[Index] != NULL; Index += 2) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserArgList[Index], &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArgList[Index], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArgList[Index] + sizeof (EFI_GUID) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -415,7 +416,7 @@ CallBootService ( return Status; } - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserArgList[Index + 1], &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArgList[Index + 1], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArgList[Index + 1] + MemoryCoreSize - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1167,7 +1168,7 @@ CallBootService ( FreePool ((VOID *)Argument4); } - return Status; + return EFI_SUCCESS; case SysCallUnicodeStrUpr: // @@ -1208,7 +1209,7 @@ CallBootService ( FreePool ((VOID *)Argument4); } - return Status; + return EFI_SUCCESS; case SysCallUnicodeFatToStr: // @@ -1328,12 +1329,12 @@ CallBootService ( } EnableSMAP (); - Unicode->StrToFat ( - Unicode, - (CHAR16 *)Argument4, - CoreRbp->Argument3, - (CHAR8 *)Argument5 - ); + Status = (EFI_STATUS)Unicode->StrToFat ( + Unicode, + (CHAR16 *)Argument4, + CoreRbp->Argument3, + (CHAR8 *)Argument5 + ); if ((VOID *)Argument4 != NULL) { FreePool ((VOID *)Argument4); @@ -1347,7 +1348,7 @@ CallBootService ( FreePool ((VOID *)Argument5); } - return EFI_SUCCESS; + return Status; default: DEBUG ((DEBUG_ERROR, "Ring0: Unknown syscall type.\n")); diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm new file mode 100644 index 0000000000..99297a6ff2 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -0,0 +1,98 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +; +;------------------------------------------------------------------------------ + +#include + +extern ASM_PFX(CallBootService) +extern ASM_PFX(gCoreSysCallStackTop) +extern ASM_PFX(gRing3CallStackTop) +extern ASM_PFX(gRing3EntryPoint) + +extern ASM_PFX(AsmReadMsr64) + +DEFAULT REL +SECTION .text + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; DisableSMAP ( +; VOID +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(DisableSMAP) +ASM_PFX(DisableSMAP): + pushfd + pop eax + or eax, 0x40000 ; Set AC (bit 18) + push eax + popfd + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; EnableSMAP ( +; VOID +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(EnableSMAP) +ASM_PFX(EnableSMAP): + pushfd + pop eax + and eax, ~0x40000 ; Clear AC (bit 18) + push eax + popfd + ret + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CallInstallMultipleProtocolInterfaces ( +; IN EFI_HANDLE *Handle, +; IN VOID **ArgList, +; IN UINT32 ArgListSize, +; IN VOID *Function +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(CallInstallMultipleProtocolInterfaces) +ASM_PFX(CallInstallMultipleProtocolInterfaces): + ret + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CoreBootServices ( +; IN UINT8 Type, +; ... +; ); +; +; (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). +; (rdx) Argument 1 of the called function. +; (r8) Argument 2 of the called function. +; (r9) Argument 3 of the called function. +; (r10) Type. +; (r11) RFLAGS saved by SYSCALL in SysCall(). +; +; (On User Stack) Argument 4, 5, ... +;------------------------------------------------------------------------------ +global ASM_PFX(CoreBootServices) +ASM_PFX(CoreBootServices): + ret + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CallRing3 ( +; IN RING3_CALL_DATA *Data +; ); +; +; (rcx) Data +;------------------------------------------------------------------------------ +global ASM_PFX(CallRing3) +ASM_PFX(CallRing3): + ret diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index ec1b645acb..be4e9f6a48 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -69,7 +69,7 @@ InitializeRing3 ( if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Interfaces.\n")); CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)gRing3Data, + (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) ); return Status; diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 07dd4a9f6e..38f7d977cc 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -128,7 +128,7 @@ CoreDriverBindingSupported ( RemainingDevicePath ); - CoreFreePages ((EFI_PHYSICAL_ADDRESS)This, 1); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); return Status; } @@ -156,7 +156,7 @@ CoreDriverBindingStart ( RemainingDevicePath ); - CoreFreePages ((EFI_PHYSICAL_ADDRESS)This, 1); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); return Status; } @@ -186,7 +186,7 @@ CoreDriverBindingStop ( ChildHandleBuffer ); - CoreFreePages ((EFI_PHYSICAL_ADDRESS)This, 1); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); return Status; } @@ -286,7 +286,7 @@ CoreFileRead ( *BufferSize = *Ring3BufferSize; EnableSMAP (); - CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Pages, PagesNumber); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Pages, PagesNumber); return Status; } @@ -367,7 +367,7 @@ CoreFileGetPosition ( *Position = *Ring3Position; EnableSMAP (); - CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Position, 1); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Position, 1); return Status; } @@ -446,7 +446,7 @@ CoreFileGetInfo ( *BufferSize = *Ring3BufferSize; EnableSMAP (); - CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Pages, PagesNumber); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Pages, PagesNumber); return Status; } @@ -571,7 +571,7 @@ CoreFileOpen ( EnableSMAP (); if (EFI_ERROR (Status)) { *NewHandle = NULL; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Pages, PagesNumber); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Pages, PagesNumber); return Status; } @@ -586,14 +586,14 @@ CoreFileOpen ( ); if (EFI_ERROR (Status)) { *NewHandle = NULL; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Pages, PagesNumber); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Pages, PagesNumber); return Status; } NewFile = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); if (NewFile == NULL) { *NewHandle = NULL; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Pages, PagesNumber); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Pages, PagesNumber); return EFI_OUT_OF_RESOURCES; } @@ -619,7 +619,7 @@ CoreFileOpen ( *NewHandle = (EFI_FILE_PROTOCOL *)NewFile; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Pages, PagesNumber); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Pages, PagesNumber); return Status; } @@ -658,14 +658,14 @@ CoreOpenVolume ( ); if (EFI_ERROR (Status)) { *Root = NULL; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Root, 1); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Root, 1); return Status; } File = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); if (File == NULL) { *Root = NULL; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Root, 1); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Root, 1); return EFI_OUT_OF_RESOURCES; } @@ -707,7 +707,7 @@ CoreOpenVolume ( *Root = (EFI_FILE_PROTOCOL *)File; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)Ring3Root, 1); + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Root, 1); return Status; } diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index b698dbfe89..059658f533 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -305,7 +305,10 @@ MdeModulePkg/Bus/Spi/SpiHc/SpiHcDxe.inf MdeModulePkg/Bus/Spi/SpiHc/SpiHcSmm.inf - MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf + MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { + + MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf + } MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf MdeModulePkg/Core/Pei/PeiMain.inf MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf index 909f2e6ee4..f249ac6014 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -154,6 +154,7 @@ Ia32/ARShiftU64.c | MSFT Ia32/EnableCache.c | MSFT Ia32/DisableCache.c | MSFT + Ia32/WriteEflags.nasm Ia32/GccInline.c | GCC diff --git a/MdePkg/Library/BaseLib/Ia32/WriteEflags.nasm b/MdePkg/Library/BaseLib/Ia32/WriteEflags.nasm new file mode 100644 index 0000000000..b462bff812 --- /dev/null +++ b/MdePkg/Library/BaseLib/Ia32/WriteEflags.nasm @@ -0,0 +1,33 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +; +; Module Name: +; +; WriteEflags.Asm +; +; Abstract: +; +; AsmWriteEflags function +; +; Notes: +; +;------------------------------------------------------------------------------ + + DEFAULT REL + SECTION .text + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteEflags ( +; UINTN Eflags +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(AsmWriteEflags) +ASM_PFX(AsmWriteEflags): + push ecx + popfd + mov eax, ecx + ret From 3e1c2dee26633e6316ca7b607da2c76501261010 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 13 Mar 2024 11:00:04 +0300 Subject: [PATCH 194/341] SysCall: Fixed MdeModulePkg compilation for VS2019. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 2 +- MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 323cbb4ce3..c0b89ae0e6 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -643,7 +643,7 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + sizeof (EFI_HANDLE *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - PagesNumber = EFI_SIZE_TO_PAGES (Argument4 * sizeof (EFI_HANDLE *)); + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (Argument4 * sizeof (EFI_HANDLE *)); Status = CoreAllocatePages ( AllocateAnyPages, diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 38f7d977cc..4ee53708bb 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -78,8 +78,8 @@ GoToRing3 ( } STATIC -EFIAPI VOID * +EFIAPI Ring3Copy ( IN VOID *Core, IN UINT32 Size @@ -248,7 +248,7 @@ CoreFileRead ( Ring3Buffer = NULL; Ring3Pages = NULL; - PagesNumber = EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize); + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize); Status = CoreAllocatePages ( AllocateAnyPages, @@ -399,7 +399,7 @@ CoreFileGetInfo ( Ring3InformationType = NULL; Ring3Pages = NULL; - PagesNumber = EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize + sizeof (EFI_GUID)); + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize + sizeof (EFI_GUID)); Status = CoreAllocatePages ( AllocateAnyPages, @@ -550,7 +550,7 @@ CoreFileOpen ( Ring3FileName = NULL; Ring3Pages = NULL; - PagesNumber = EFI_SIZE_TO_PAGES (sizeof (EFI_FILE_PROTOCOL *) + StrSize (FileName)); + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (EFI_FILE_PROTOCOL *) + StrSize (FileName)); Status = CoreAllocatePages ( AllocateAnyPages, From 695d1523a3d1f2f54307afe78a739a4b163983f4 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 13 Mar 2024 11:28:03 +0300 Subject: [PATCH 195/341] SysCall: Fixed MdeModulePkg compilation for XCODE5. --- MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 16b182a764..3d0e96b5a0 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -203,7 +203,7 @@ ASM_PFX(CallRing3): SetRing3DataSegmentSelectors ; Prepare SYSRET arguments. - mov rcx, [gRing3EntryPoint] + mov rcx, [ASM_PFX(gRing3EntryPoint)] pop rdx ; Save Core Stack pointers and switch to User Stack. From 812f715ada802a0c4fefa94d95960f5fffef3f80 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 15 Mar 2024 15:43:21 +0300 Subject: [PATCH 196/341] Ring3: Moved platform dependant initialization to separate files. --- MdeModulePkg/Core/Dxe/DxeMain.h | 1 + MdeModulePkg/Core/Dxe/DxeMain.inf | 2 + .../Core/Dxe/SysCall/IA32/InitializeMsr.c | 62 ++++++++++++++++ .../Core/Dxe/SysCall/Initialization.c | 57 ++------------- .../Core/Dxe/SysCall/X64/InitializeMsr.c | 70 +++++++++++++++++++ MdePkg/Include/Library/BaseLib.h | 9 ++- UefiCpuPkg/Library/CpuArchLib/CpuGdt.c | 44 +++++++++++- 7 files changed, 192 insertions(+), 53 deletions(-) create mode 100644 MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c create mode 100644 MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index a9253cb783..8634a1597c 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -275,6 +275,7 @@ extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage; extern RING3_DATA *gRing3Data; extern VOID *gRing3Interfaces; extern VOID *gCoreSysCallStackBase; +extern VOID *gCoreSysCallStackTop; extern VOID *gRing3CallStackBase; // diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 18295d597a..02c4bd8a04 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -71,9 +71,11 @@ SysCall/SupportedProtocols.c [Sources.IA32] + SysCall/IA32/InitializeMsr.c SysCall/IA32/CoreBootServices.nasm [Sources.X64] + SysCall/X64/InitializeMsr.c SysCall/X64/CoreBootServices.nasm [Packages] diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c new file mode 100644 index 0000000000..8c1859163e --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c @@ -0,0 +1,62 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +#include + +VOID +EFIAPI +InitializeMsr ( + VOID + ) +{ + UINT64 Msr; + IA32_CR4 Cr4; + IA32_EFLAGS32 Eflags; + UINT32 Ebx; + UINT32 Edx; + + Ebx = 0; + Edx = 0; + + // + // Forbid supervisor-mode accesses to any user-mode pages. + // SMEP and SMAP must be supported. + // + AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); + // + // SYSENTER and SYSEXIT must be also supported. + // + AsmCpuidEx (0x01, 0x0, NULL, NULL, NULL, &Edx); + if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) { + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMAP = 1; + Cr4.Bits.SMEP = 1; + AsmWriteCr4 (Cr4.UintN); + + Eflags.UintN = AsmReadEflags (); + Eflags.Bits.AC = 0; + AsmWriteEflags (Eflags.UintN); + } else { + DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n")); + ASSERT (FALSE); + } + + // + // Initialize MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_EIP and + // MSR_IA32_SYSENTER_ESP for SYSENTER and SYSEXIT. + // + Msr = RING0_CODE32_SEL; + AsmWriteMsr64 (MSR_IA32_SYSENTER_CS, Msr); + + Msr = (UINT64)(UINTN)CoreBootServices; + AsmWriteMsr64 (MSR_IA32_SYSENTER_EIP, Msr); + + Msr = (UINT64)(UINTN)gCoreSysCallStackTop; + AsmWriteMsr64 (MSR_IA32_SYSENTER_ESP, Msr); +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index be4e9f6a48..2d965b8a80 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -7,8 +7,6 @@ #include "DxeMain.h" -#include - VOID *gCoreSysCallStackTop; VOID *gCoreSysCallStackBase; VOID *gRing3CallStackTop; @@ -17,6 +15,12 @@ VOID *gRing3EntryPoint; RING3_DATA *gRing3Data; VOID *gRing3Interfaces; +VOID +EFIAPI +InitializeMsr ( + VOID + ); + EFI_STATUS EFIAPI InitializeRing3 ( @@ -27,15 +31,6 @@ InitializeRing3 ( EFI_STATUS Status; VOID *TopOfStack; UINTN SizeOfStack; - UINT64 Msr; - IA32_CR4 Cr4; - IA32_EFLAGS32 Eflags; - UINT32 Ebx; - UINT32 Edx; - MSR_IA32_EFER_REGISTER MsrEfer; - - Ebx = 0; - Edx = 0; // // Set Ring3 EntryPoint and BootServices. @@ -75,32 +70,6 @@ InitializeRing3 ( return Status; } - // - // Forbid supervisor-mode accesses to any user-mode pages. - // SMEP and SMAP must be supported. - // - AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); - // - // SYSCALL and SYSRET must be also supported. - // - AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); - if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) { - Cr4.UintN = AsmReadCr4 (); - Cr4.Bits.SMAP = 1; - Cr4.Bits.SMEP = 1; - AsmWriteCr4 (Cr4.UintN); - - Eflags.UintN = AsmReadEflags (); - Eflags.Bits.AC = 0; - AsmWriteEflags (Eflags.UintN); - // - // Enable SYSCALL and SYSRET. - // - MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); - MsrEfer.Bits.SCE = 1; - AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); - } - SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; // @@ -137,19 +106,7 @@ InitializeRing3 ( SetUefiImageMemoryAttributes ((UINTN)gRing3CallStackBase, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); - // - // Initialize MSR_IA32_STAR, MSR_IA32_LSTAR and MSR_IA32_FMASK for SYSCALL and SYSRET. - // - Msr = (((((UINT64)RING3_CODE64_SEL - 16) | 3) << 16) | (UINT64)RING0_CODE64_SEL) << 32; - AsmWriteMsr64 (MSR_IA32_STAR, Msr); - - Msr = (UINT64)(UINTN)CoreBootServices; - AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); - // - // Disable maskable interrupts at SYSCALL. - // - Msr = (UINT64)BIT9; - AsmWriteMsr64 (MSR_IA32_FMASK, Msr); + InitializeMsr (); return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c new file mode 100644 index 0000000000..171fdc5e7d --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c @@ -0,0 +1,70 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +#include + +VOID +EFIAPI +InitializeMsr ( + VOID + ) +{ + UINT64 Msr; + IA32_CR4 Cr4; + IA32_EFLAGS32 Eflags; + UINT32 Ebx; + UINT32 Edx; + MSR_IA32_EFER_REGISTER MsrEfer; + + Ebx = 0; + Edx = 0; + + // + // Forbid supervisor-mode accesses to any user-mode pages. + // SMEP and SMAP must be supported. + // + AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); + // + // SYSCALL and SYSRET must be also supported. + // + AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); + if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) { + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMAP = 1; + Cr4.Bits.SMEP = 1; + AsmWriteCr4 (Cr4.UintN); + + Eflags.UintN = AsmReadEflags (); + Eflags.Bits.AC = 0; + AsmWriteEflags (Eflags.UintN); + // + // Enable SYSCALL and SYSRET. + // + MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); + MsrEfer.Bits.SCE = 1; + AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); + } else { + DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n")); + ASSERT (FALSE); + } + + // + // Initialize MSR_IA32_STAR, MSR_IA32_LSTAR and MSR_IA32_FMASK for SYSCALL and SYSRET. + // + Msr = (((((UINT64)RING3_CODE64_SEL - 16) | 3) << 16) | (UINT64)RING0_CODE64_SEL) << 32; + AsmWriteMsr64 (MSR_IA32_STAR, Msr); + + Msr = (UINT64)(UINTN)CoreBootServices; + AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); + // + // Disable maskable interrupts at SYSCALL. + // + Msr = (UINT64)BIT9; + AsmWriteMsr64 (MSR_IA32_FMASK, Msr); +} diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index cb4ef6a134..9e6c2aa5c1 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -5660,8 +5660,10 @@ typedef struct { SEGMENT_DESCRIPTOR Null; DATA_SEGMENT_32 Linear; CODE_SEGMENT_32 LinearCode; - DATA_SEGMENT_32 SysData; CODE_SEGMENT_32 SysCode; + DATA_SEGMENT_32 SysData; + CODE_SEGMENT_32 Ring3Code32; + DATA_SEGMENT_32 Ring3Data32; CODE_SEGMENT_32 SysCode16; CODE_SEGMENT_64 LinearCode64; DATA_SEGMENT_32 LinearData64; @@ -5672,6 +5674,11 @@ typedef struct { #pragma pack () +#define RING0_DATA32_SEL OFFSET_OF (GDT, SysData) +#define RING0_CODE32_SEL OFFSET_OF (GDT, SysCode) +#define RING3_DATA32_SEL OFFSET_OF (GDT, Ring3Data32) +#define RING3_CODE32_SEL OFFSET_OF (GDT, Ring3Code32) + #define RING0_DATA64_SEL OFFSET_OF (GDT, LinearData64) #define RING0_CODE64_SEL OFFSET_OF (GDT, LinearCode64) #define RING3_DATA64_SEL OFFSET_OF (GDT, Ring3Data64) diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c index 415d4126aa..9f029c12af 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.c @@ -69,6 +69,26 @@ STATIC GDT mGdtTemplate = { .Granularity = 1, .BaseAddress_31_24 = 0x0 }, + .SysCode = { + .SegmentLimit_15_0 = 0xFFFF, + .BaseAddress_15_0 = 0x0, + .BaseAddress_23_16 = 0x0, + + .Accessed = 0, + .Readable = 1, + .Conforming = 0, + .IsCode = 1, + .IsNotSystemSegment = 1, + .DescriptorPrivilegeLevel = 0, + .SegmentPresent = 1, + + .SegmentLimit_19_16 = 0xF, + .Available = 0, + .Reserved = 0, + .Is32Bit = 1, + .Granularity = 1, + .BaseAddress_31_24 = 0x0 + }, .SysData = { .SegmentLimit_15_0 = 0xFFFF, .BaseAddress_15_0 = 0x0, @@ -89,7 +109,7 @@ STATIC GDT mGdtTemplate = { .Granularity = 1, .BaseAddress_31_24 = 0x0 }, - .SysCode = { + .Ring3Code32 = { .SegmentLimit_15_0 = 0xFFFF, .BaseAddress_15_0 = 0x0, .BaseAddress_23_16 = 0x0, @@ -99,7 +119,7 @@ STATIC GDT mGdtTemplate = { .Conforming = 0, .IsCode = 1, .IsNotSystemSegment = 1, - .DescriptorPrivilegeLevel = 0, + .DescriptorPrivilegeLevel = 3, .SegmentPresent = 1, .SegmentLimit_19_16 = 0xF, @@ -109,6 +129,26 @@ STATIC GDT mGdtTemplate = { .Granularity = 1, .BaseAddress_31_24 = 0x0 }, + .Ring3Data32 = { + .SegmentLimit_15_0 = 0xFFFF, + .BaseAddress_15_0 = 0x0, + .BaseAddress_23_16 = 0x0, + + .Accessed = 1, + .Writable = 1, + .ExpansionDirection = 0, + .IsCode = 0, + .IsNotSystemSegment = 1, + .DescriptorPrivilegeLevel = 3, + .SegmentPresent = 1, + + .SegmentLimit_19_16 = 0xF, + .Available = 0, + .Reserved = 0, + .UpperBound = 1, + .Granularity = 1, + .BaseAddress_31_24 = 0x0 + }, .SysCode16 = { .SegmentLimit_15_0 = 0xFFFF, .BaseAddress_15_0 = 0x0, From 5cffa7a147f4ffdcd12e671fa1388a0d02fe2596 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 18 Mar 2024 11:57:57 +0300 Subject: [PATCH 197/341] SysCall: Added IA32 support. --- .../Core/Dxe/DxeRing3/IA32/SysCall.nasm | 12 +- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 137 ++++++++++++++++-- 2 files changed, 137 insertions(+), 12 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm index 2f37ffe619..1e50f950dc 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm @@ -18,8 +18,13 @@ SECTION .text ;------------------------------------------------------------------------------ global ASM_PFX(SysCall) ASM_PFX(SysCall): - sysenter + mov edx, esp + mov ecx, [esp + 4] ; Type + lea eax, [userReturnAddress] + sysenter +userReturnAddress: + ; sti ret ;------------------------------------------------------------------------------ @@ -29,10 +34,11 @@ ASM_PFX(SysCall): ; IN RING3_CALL_DATA *Data ; ); ; -; (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3(). -; (rdx) Data +; (eax) Data ;------------------------------------------------------------------------------ global ASM_PFX(Ring3EntryPoint) ASM_PFX(Ring3EntryPoint): + push eax + ; sti call ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index 99297a6ff2..0ff6cf68a2 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -61,8 +61,43 @@ ASM_PFX(EnableSMAP): ;------------------------------------------------------------------------------ global ASM_PFX(CallInstallMultipleProtocolInterfaces) ASM_PFX(CallInstallMultipleProtocolInterfaces): + push ebp + mov ebp, esp + + ; Prepare stack for call. + mov eax, [ebp + 2 * 4] ; eax = ArgList + mov ecx, [ebp + 3 * 4] ; ecx = ArgListSize + lea eax, [eax + ecx * 4] +copy: + sub eax, 4 + push dword [eax] + sub ecx, 1 + jnz copy + push dword [ebp + 4] + + call [ebp + 4 * 4] + + ; Step over Function arguments. + mov esp, ebp + pop ebp + ret +%macro SetRing3DataSegmentSelectors 0 + push dword MSR_IA32_SYSENTER_CS + call ASM_PFX(AsmReadMsr64) + ; eax = RING0_CODE32_SEL + add eax, 24 ; GDT: RING0_CODE32, RING0_DATA32, RING3_CODE32, RING3_DATA32 + or eax, 3 ; RPL = 3 + + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + pop eax +%endmacro + ;------------------------------------------------------------------------------ ; EFI_STATUS ; EFIAPI @@ -71,18 +106,62 @@ ASM_PFX(CallInstallMultipleProtocolInterfaces): ; ... ; ); ; -; (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). -; (rdx) Argument 1 of the called function. -; (r8) Argument 2 of the called function. -; (r9) Argument 3 of the called function. -; (r10) Type. -; (r11) RFLAGS saved by SYSCALL in SysCall(). +; (eax) User return address. +; (ecx) Type. +; (edx) User Stack Pointer. ; -; (On User Stack) Argument 4, 5, ... +; (On User Stack) Argument 1, 2, ... ;------------------------------------------------------------------------------ global ASM_PFX(CoreBootServices) ASM_PFX(CoreBootServices): - ret + ; Save User return address and Stack pointers. + push edx + push ebp + push eax + + ; Switch from User to Core data segment selectors. + mov ax, ss + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; Special case for SysCallReturnToCore. + cmp ecx, 0 + je coreReturnAddress + + ; Prepare CallBootService arguments. + call ASM_PFX(DisableSMAP) + mov eax, [edx + 4 * 4] ; User Argument 3 + push eax + mov eax, [edx + 3 * 4] ; User Argument 2 + push eax + mov eax, [edx + 2 * 4] ; User Argument 1 + push eax + call ASM_PFX(EnableSMAP) + mov ebp, esp + push edx + push ebp + push ecx + + sti + call ASM_PFX(CallBootService) + push eax + cli + + SetRing3DataSegmentSelectors + + pop eax + + ; Step over User Arguments [1..3] and CallBootService input. + add esp, 4*6 + + ; Prepare SYSEXIT arguments. + pop edx ; User return address. + pop ebp + pop ecx ; User Stack Pointer. + + sysexit ;------------------------------------------------------------------------------ ; EFI_STATUS @@ -91,8 +170,48 @@ ASM_PFX(CoreBootServices): ; IN RING3_CALL_DATA *Data ; ); ; -; (rcx) Data +; (On User Stack) Data ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): + cli + + ; Save Core Stack pointers. + mov [ASM_PFX(CoreEsp)], esp + mov [ASM_PFX(CoreEbp)], ebp + + push dword [ASM_PFX(gRing3EntryPoint)] + push dword [ASM_PFX(gRing3CallStackTop)] + + SetRing3DataSegmentSelectors + + ; Prepare SYSEXIT arguments. + pop ecx + pop edx + mov eax, [esp + 4] ; Data + + ; Switch to User Stack. + mov ebp, ecx + + ; Pass control to user image + sysexit + +coreReturnAddress: + mov esp, [ASM_PFX(CoreEsp)] + mov ebp, [ASM_PFX(CoreEbp)] + + call ASM_PFX(DisableSMAP) + mov eax, [edx + 2 * 4] ; User Argument 1 + push eax + call ASM_PFX(EnableSMAP) + pop eax + + sti ret + +SECTION .data +ASM_PFX(CoreEsp): + resd 1 + +ASM_PFX(CoreEbp): + resd 1 From 354070fae319bf5fd7718a0114214f283f6feb8f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 18 Mar 2024 16:43:42 +0300 Subject: [PATCH 198/341] SysCall: Fixed memory corruption in IA32. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 36 ++++----- .../Core/Dxe/SysCall/Initialization.c | 9 ++- .../Core/Dxe/SysCall/SupportedProtocols.c | 75 ++++++++++--------- 3 files changed, 64 insertions(+), 56 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index c0b89ae0e6..ea5940f924 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -251,21 +251,21 @@ CallBootService ( IN RING3_STACK *UserRsp ) { - EFI_STATUS Status; - EFI_STATUS StatusBS; - UINT64 Attributes; - VOID *Interface; - EFI_GUID *CoreProtocol; - UINT32 MemoryCoreSize; - UINTN Argument4; - UINTN Argument5; - UINTN Argument6; - UINT32 Index; - VOID **UserArgList; - VOID *CoreArgList[MAX_LIST]; - EFI_HANDLE CoreHandle; - VOID *Ring3Pages; - UINT32 PagesNumber; + EFI_STATUS Status; + EFI_STATUS StatusBS; + UINT64 Attributes; + VOID *Interface; + EFI_GUID *CoreProtocol; + UINT32 MemoryCoreSize; + UINTN Argument4; + UINTN Argument5; + UINTN Argument6; + UINT32 Index; + VOID **UserArgList; + VOID *CoreArgList[MAX_LIST]; + EFI_HANDLE CoreHandle; + UINT32 PagesNumber; + EFI_PHYSICAL_ADDRESS Ring3Pages; EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem; @@ -649,17 +649,17 @@ CallBootService ( AllocateAnyPages, EfiRing3MemoryType, PagesNumber, - (EFI_PHYSICAL_ADDRESS *)&Ring3Pages + &Ring3Pages ); if (EFI_ERROR (Status)) { return Status; } - CopyMem (Ring3Pages, (VOID *)Argument5, Argument4 * sizeof (EFI_HANDLE *)); + CopyMem ((VOID *)(UINTN)Ring3Pages, (VOID *)Argument5, Argument4 * sizeof (EFI_HANDLE *)); FreePool ((VOID *)Argument5); - *(EFI_HANDLE **)UserRsp->Arguments[5] = (EFI_HANDLE *)Ring3Pages; + *(EFI_HANDLE **)UserRsp->Arguments[5] = (EFI_HANDLE *)(UINTN)Ring3Pages; } EnableSMAP (); diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 2d965b8a80..3bf1d4d74c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -31,6 +31,7 @@ InitializeRing3 ( EFI_STATUS Status; VOID *TopOfStack; UINTN SizeOfStack; + EFI_PHYSICAL_ADDRESS Physical; // // Set Ring3 EntryPoint and BootServices. @@ -39,13 +40,15 @@ InitializeRing3 ( AllocateAnyPages, EfiRing3MemoryType, EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)), - (EFI_PHYSICAL_ADDRESS *)&gRing3Data + &Physical ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Data.\n")); return Status; } + gRing3Data = (RING3_DATA *)(UINTN)Physical; + CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); @@ -59,7 +62,7 @@ InitializeRing3 ( AllocateAnyPages, EfiRing3MemoryType, RING3_INTERFACES_PAGES, - (EFI_PHYSICAL_ADDRESS *)&gRing3Interfaces + &Physical ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Interfaces.\n")); @@ -70,6 +73,8 @@ InitializeRing3 ( return Status; } + gRing3Interfaces = (VOID *)(UINTN)Physical; + SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; // diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 4ee53708bb..989ff9d4fa 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -85,24 +85,24 @@ Ring3Copy ( IN UINT32 Size ) { - EFI_STATUS Status; - VOID *Ring3; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Ring3; Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, 1, - (EFI_PHYSICAL_ADDRESS *)&Ring3 + &Ring3 ); if (EFI_ERROR (Status)) { return NULL; } DisableSMAP (); - CopyMem (Ring3, Core, Size); + CopyMem ((VOID *)(UINTN)Ring3, Core, Size); EnableSMAP (); - return Ring3; + return (VOID *)(UINTN)Ring3; } EFI_STATUS @@ -237,7 +237,7 @@ CoreFileRead ( RING3_EFI_FILE_PROTOCOL *File; UINTN *Ring3BufferSize; VOID *Ring3Buffer; - VOID *Ring3Pages; + EFI_PHYSICAL_ADDRESS Ring3Pages; UINT32 PagesNumber; if ((This == NULL) || (BufferSize == NULL)) { @@ -246,7 +246,7 @@ CoreFileRead ( File = (RING3_EFI_FILE_PROTOCOL *)This; Ring3Buffer = NULL; - Ring3Pages = NULL; + Ring3Pages = 0; PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize); @@ -254,20 +254,20 @@ CoreFileRead ( AllocateAnyPages, EfiRing3MemoryType, PagesNumber, - (EFI_PHYSICAL_ADDRESS *)&Ring3Pages + &Ring3Pages ); if (EFI_ERROR (Status)) { return Status; } - Ring3BufferSize = (UINTN *)Ring3Pages; + Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; DisableSMAP (); *Ring3BufferSize = *BufferSize; EnableSMAP (); if (Buffer != NULL) { - Ring3Buffer = (VOID *)((UINTN *)Ring3Pages + 1); + Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); } Status = GoToRing3 ( @@ -286,7 +286,7 @@ CoreFileRead ( *BufferSize = *Ring3BufferSize; EnableSMAP (); - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Pages, PagesNumber); + CoreFreePages (Ring3Pages, PagesNumber); return Status; } @@ -333,27 +333,27 @@ CoreFileGetPosition ( { EFI_STATUS Status; RING3_EFI_FILE_PROTOCOL *File; - UINT64 *Ring3Position; + EFI_PHYSICAL_ADDRESS Ring3Position; if ((This == NULL) || (Position == NULL)) { return EFI_INVALID_PARAMETER; } File = (RING3_EFI_FILE_PROTOCOL *)This; - Ring3Position = NULL; + Ring3Position = 0; Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, 1, - (EFI_PHYSICAL_ADDRESS *)&Ring3Position + &Ring3Position ); if (EFI_ERROR (Status)) { return Status; } DisableSMAP (); - *Ring3Position = *Position; + *(UINT64 *)(UINTN)Ring3Position = *Position; EnableSMAP (); Status = GoToRing3 ( @@ -364,10 +364,10 @@ CoreFileGetPosition ( ); DisableSMAP (); - *Position = *Ring3Position; + *Position = *(UINT64 *)(UINTN)Ring3Position; EnableSMAP (); - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Position, 1); + CoreFreePages (Ring3Position, 1); return Status; } @@ -387,7 +387,7 @@ CoreFileGetInfo ( EFI_GUID *Ring3InformationType; UINTN *Ring3BufferSize; VOID *Ring3Buffer; - VOID *Ring3Pages; + EFI_PHYSICAL_ADDRESS Ring3Pages; UINT32 PagesNumber; if ((This == NULL) || (BufferSize == NULL)) { @@ -397,7 +397,7 @@ CoreFileGetInfo ( File = (RING3_EFI_FILE_PROTOCOL *)This; Ring3Buffer = NULL; Ring3InformationType = NULL; - Ring3Pages = NULL; + Ring3Pages = 0; PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize + sizeof (EFI_GUID)); @@ -405,20 +405,20 @@ CoreFileGetInfo ( AllocateAnyPages, EfiRing3MemoryType, PagesNumber, - (EFI_PHYSICAL_ADDRESS *)&Ring3Pages + &Ring3Pages ); if (EFI_ERROR (Status)) { return Status; } - Ring3BufferSize = (UINTN *)Ring3Pages; + Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; DisableSMAP (); *Ring3BufferSize = *BufferSize; EnableSMAP (); if (Buffer != NULL) { - Ring3Buffer = (VOID *)((UINTN *)Ring3Pages + 1); + Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); } if (InformationType != NULL) { @@ -446,7 +446,7 @@ CoreFileGetInfo ( *BufferSize = *Ring3BufferSize; EnableSMAP (); - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Pages, PagesNumber); + CoreFreePages (Ring3Pages, PagesNumber); return Status; } @@ -538,7 +538,7 @@ CoreFileOpen ( RING3_EFI_FILE_PROTOCOL *NewFile; EFI_FILE_PROTOCOL **Ring3NewHandle; CHAR16 *Ring3FileName; - VOID *Ring3Pages; + EFI_PHYSICAL_ADDRESS Ring3Pages; UINT32 PagesNumber; if ((This == NULL) || (NewHandle == NULL) || (FileName == NULL)) { @@ -548,7 +548,7 @@ CoreFileOpen ( File = (RING3_EFI_FILE_PROTOCOL *)This; Ring3NewHandle = NULL; Ring3FileName = NULL; - Ring3Pages = NULL; + Ring3Pages = 0; PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (EFI_FILE_PROTOCOL *) + StrSize (FileName)); @@ -556,22 +556,22 @@ CoreFileOpen ( AllocateAnyPages, EfiRing3MemoryType, PagesNumber, - (EFI_PHYSICAL_ADDRESS *)&Ring3Pages + &Ring3Pages ); if (EFI_ERROR (Status)) { *NewHandle = NULL; return Status; } - Ring3NewHandle = (EFI_FILE_PROTOCOL **)Ring3Pages; - Ring3FileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)Ring3Pages + 1); + Ring3NewHandle = (EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages; + Ring3FileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages + 1); DisableSMAP (); Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName); EnableSMAP (); if (EFI_ERROR (Status)) { *NewHandle = NULL; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Pages, PagesNumber); + CoreFreePages (Ring3Pages, PagesNumber); return Status; } @@ -586,14 +586,14 @@ CoreFileOpen ( ); if (EFI_ERROR (Status)) { *NewHandle = NULL; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Pages, PagesNumber); + CoreFreePages (Ring3Pages, PagesNumber); return Status; } NewFile = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); if (NewFile == NULL) { *NewHandle = NULL; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Pages, PagesNumber); + CoreFreePages (Ring3Pages, PagesNumber); return EFI_OUT_OF_RESOURCES; } @@ -619,7 +619,7 @@ CoreFileOpen ( *NewHandle = (EFI_FILE_PROTOCOL *)NewFile; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Pages, PagesNumber); + CoreFreePages (Ring3Pages, PagesNumber); return Status; } @@ -634,6 +634,7 @@ CoreOpenVolume ( EFI_STATUS Status; EFI_FILE_PROTOCOL **Ring3Root; RING3_EFI_FILE_PROTOCOL *File; + EFI_PHYSICAL_ADDRESS Physical; if (Root == NULL) { return EFI_INVALID_PARAMETER; @@ -643,13 +644,15 @@ CoreOpenVolume ( AllocateAnyPages, EfiRing3MemoryType, 1, - (EFI_PHYSICAL_ADDRESS *)&Ring3Root + &Physical ); if (EFI_ERROR (Status)) { *Root = NULL; return Status; } + Ring3Root = (EFI_FILE_PROTOCOL **)(UINTN)Physical; + Status = GoToRing3 ( 2, (VOID *)mRing3SimpleFileSystemProtocol.OpenVolume, @@ -658,14 +661,14 @@ CoreOpenVolume ( ); if (EFI_ERROR (Status)) { *Root = NULL; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Root, 1); + CoreFreePages (Physical, 1); return Status; } File = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); if (File == NULL) { *Root = NULL; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Root, 1); + CoreFreePages (Physical, 1); return EFI_OUT_OF_RESOURCES; } @@ -707,7 +710,7 @@ CoreOpenVolume ( *Root = (EFI_FILE_PROTOCOL *)File; - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Ring3Root, 1); + CoreFreePages (Physical, 1); return Status; } From 16959dbb6dddc900799bd0e23dbaf15d9c1d72b4 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 18 Mar 2024 17:30:41 +0300 Subject: [PATCH 199/341] Build: Fixed compilation of X86 Firmwares. --- OvmfPkg/OvmfPkgIa32.dsc | 5 +++++ OvmfPkg/OvmfPkgIa32.fdf | 2 ++ OvmfPkg/OvmfPkgIa32X64.dsc | 5 +++++ OvmfPkg/OvmfPkgIa32X64.fdf | 2 ++ UefiPayloadPkg/UefiPayloadPkg.dsc | 5 +++++ UefiPayloadPkg/UefiPayloadPkg.fdf | 2 ++ 6 files changed, 21 insertions(+) diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 1caf85d272..fe00692f94 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -326,6 +326,7 @@ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf + MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -826,6 +827,10 @@ MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf FatPkg/EnhancedFatDxe/Fat.inf + MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { + + MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf + } MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index f8da53e140..47bc9d9f43 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -203,6 +203,7 @@ APRIORI DXE { !if $(SMM_REQUIRE) == FALSE INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf !endif + INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf } # @@ -288,6 +289,7 @@ INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf INF FatPkg/EnhancedFatDxe/Fat.inf +INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 15c719be28..e3d68396b4 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -332,6 +332,7 @@ CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf + MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -839,6 +840,10 @@ MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf FatPkg/EnhancedFatDxe/Fat.inf + MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { + + MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf + } MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index 58a273fcc8..6a6832bcd7 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -204,6 +204,7 @@ APRIORI DXE { !if $(SMM_REQUIRE) == FALSE INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf !endif + INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf } # @@ -290,6 +291,7 @@ INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf INF FatPkg/EnhancedFatDxe/Fat.inf +INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 82f71c62d2..3e40695b9a 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -384,6 +384,7 @@ CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf + MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf [LibraryClasses.common.DXE_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -845,6 +846,10 @@ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf FatPkg/EnhancedFatDxe/Fat.inf + MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { + + MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf + } !if $(ATA_ENABLE) == TRUE MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index c3cd03e4d1..af014c73c4 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -143,6 +143,7 @@ APRIORI DXE { INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf INF UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf + INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf } # @@ -285,6 +286,7 @@ INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf !endif INF FatPkg/EnhancedFatDxe/Fat.inf +INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf # # SD/eMMC Support From b9ed8f5beee9f9abfbb2da41645fbd0cb3eed91e Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 21 Mar 2024 17:51:18 +0300 Subject: [PATCH 200/341] Ring3: Fixed TSS initialization. --- OvmfPkg/OvmfPkgIa32.dsc | 1 + OvmfPkg/OvmfPkgIa32X64.dsc | 1 + OvmfPkg/OvmfPkgX64.dsc | 1 + UefiCpuPkg/Library/CpuArchLib/CpuGdt.h | 4 +-- .../Ia32/ArchExceptionHandler.c | 34 +++++++++++++++---- .../Ia32/ArchInterruptDefs.h | 3 +- .../X64/ArchExceptionHandler.c | 1 + 7 files changed, 36 insertions(+), 9 deletions(-) diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index fe00692f94..7be0dfb098 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -597,6 +597,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF04 gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x70000000 !endif + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE # # Firmware volume supports UE, and may require PE. diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index e3d68396b4..ab14245392 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -612,6 +612,7 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !endif + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE ################################################################################ # diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 62ae6f3134..3ce9d08828 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -627,6 +627,7 @@ gEfiMdePkgTokenSpaceGuid.PcdImageLoaderAllowMisalignedOffset|TRUE gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !endif + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE # # Firmware volume supports UE, and may require PE. diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h index 21ad6df184..865561042e 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h +++ b/UefiCpuPkg/Library/CpuArchLib/CpuGdt.h @@ -25,8 +25,8 @@ #define SPARE5_SEL OFFSET_OF (GDT, Spare5) #if defined (MDE_CPU_IA32) -#define CPU_CODE_SEL LINEAR_CODE_SEL -#define CPU_DATA_SEL LINEAR_SEL +#define CPU_CODE_SEL SYS_CODE_SEL +#define CPU_DATA_SEL SYS_DATA_SEL #elif defined (MDE_CPU_X64) #define CPU_CODE_SEL LINEAR_CODE64_SEL #define CPU_DATA_SEL LINEAR_DATA64_SEL diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c index c30ece1dc9..865bd10534 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c @@ -135,6 +135,7 @@ ArchSetupExceptionStack ( UINT8 *StackSwitchExceptions; UINTN NeedBufferSize; EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap; + UINT8 *IOBitMap; if (BufferSize == NULL) { return EFI_INVALID_PARAMETER; @@ -203,14 +204,38 @@ ArchSetupExceptionStack ( TssBase = (UINTN)Tss; TssDesc->Uint64 = 0; - TssDesc->Bits.LimitLow = sizeof (IA32_TASK_STATE_SEGMENT) - 1; + TssDesc->Bits.LimitLow = (UINT16)(sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE - 1); TssDesc->Bits.BaseLow = (UINT16)TssBase; TssDesc->Bits.BaseMid = (UINT8)(TssBase >> 16); TssDesc->Bits.Type = IA32_GDT_TYPE_TSS; + TssDesc->Bits.DPL = 3; TssDesc->Bits.P = 1; - TssDesc->Bits.LimitHigh = 0; + TssDesc->Bits.LimitHigh = (sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE - 1) >> 16; TssDesc->Bits.BaseHigh = (UINT8)(TssBase >> 24); + // + // Set I/O Permission Bit Map + // + ZeroMem (Tss, sizeof (*Tss)); + + Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); + // + // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06 + // + IOBitMap = (UINT8 *)((UINTN)Tss + Tss->IOMapBaseAddress); + for (Index = 0; Index < IO_BIT_MAP_SIZE; ++Index) { + if ((Index * 8) == 0x3F8) { + *IOBitMap = 0x84; + } else { + *IOBitMap = 0xFF; + } + + ++IOBitMap; + } + + Tss = (IA32_TASK_STATE_SEGMENT *)((UINTN)Tss + sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE); + ++TssDesc; + // // Fixup exception task descriptor and task-state segment // @@ -221,10 +246,7 @@ ArchSetupExceptionStack ( StackTop = StackTop - CPU_STACK_ALIGNMENT + 1; StackTop = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)Idtr.Base; - for (Index = 0; Index < CPU_STACK_SWITCH_EXCEPTION_NUMBER; ++Index) { - TssDesc += 1; - Tss += 1; - + for (Index = 0; Index < CPU_STACK_SWITCH_EXCEPTION_NUMBER; ++Index, ++TssDesc, ++Tss) { // // Fixup TSS descriptor // diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h index 211d2abe48..675c45436c 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h @@ -39,8 +39,9 @@ typedef struct { (sizeof (IA32_TSS_DESCRIPTOR) * \ (FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + 1)) +#define IO_BIT_MAP_SIZE (ALIGN_VALUE (0x81, 16)) #define CPU_TSS_SIZE \ (sizeof (IA32_TASK_STATE_SEGMENT) * \ - (FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + 1)) + (FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + 1) + IO_BIT_MAP_SIZE) #endif diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index 76a51e28d0..a1275b53df 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -215,6 +215,7 @@ ArchSetupExceptionStack ( TssDesc->Bits.BaseLow = (UINT16)TssBase; TssDesc->Bits.BaseMidl = (UINT8)(TssBase >> 16); TssDesc->Bits.Type = IA32_GDT_TYPE_TSS; + TssDesc->Bits.DPL = 3; TssDesc->Bits.P = 1; TssDesc->Bits.LimitHigh = (CPU_TSS_SIZE - 1) >> 16; TssDesc->Bits.BaseMidh = (UINT8)(TssBase >> 24); From 2fb6809ac3db95cc38cfd72029c513895ef0aace Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 22 Mar 2024 18:09:42 +0300 Subject: [PATCH 201/341] SysCall: Replaced AllocatePool() with CoreAllocatePages(). --- .../Core/Dxe/SysCall/SupportedProtocols.c | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 989ff9d4fa..ac908a3005 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -26,23 +26,28 @@ GoToRing3 ( ... ) { - EFI_STATUS Status; - RING3_CALL_DATA *Input; - VA_LIST Marker; - UINTN Index; + EFI_STATUS Status; + RING3_CALL_DATA *Input; + VA_LIST Marker; + UINTN Index; + EFI_PHYSICAL_ADDRESS Ring3Pages; + UINT32 PagesNumber; - DisableSMAP (); - Status = gBS->AllocatePool ( - EfiRing3MemoryType, - sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN), - (VOID **)&Input - ); + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + &Ring3Pages + ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring0: Failed to allocate memory for Input data.\n")); - EnableSMAP (); return Status; } + Input = (RING3_CALL_DATA *)(UINTN)Ring3Pages; + + DisableSMAP (); Input->NumberOfArguments = Number; Input->EntryPoint = EntryPoint; @@ -74,6 +79,8 @@ GoToRing3 ( ); } + CoreFreePages (Ring3Pages, PagesNumber); + return Status; } From c998da3a35a0e367b476aa25f6e4bc1d78cd6a03 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 22 Mar 2024 18:11:00 +0300 Subject: [PATCH 202/341] SysCall: Fixed bug in IA32 CallInstallMultipleProtocolInterfaces(). --- MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index 0ff6cf68a2..c5e8b68ad3 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -65,17 +65,17 @@ ASM_PFX(CallInstallMultipleProtocolInterfaces): mov ebp, esp ; Prepare stack for call. - mov eax, [ebp + 2 * 4] ; eax = ArgList - mov ecx, [ebp + 3 * 4] ; ecx = ArgListSize + mov eax, [ebp + 3 * 4] ; eax = ArgList + mov ecx, [ebp + 4 * 4] ; ecx = ArgListSize lea eax, [eax + ecx * 4] copy: sub eax, 4 push dword [eax] sub ecx, 1 jnz copy - push dword [ebp + 4] + push dword [ebp + 2 * 4] - call [ebp + 4 * 4] + call [ebp + 5 * 4] ; Step over Function arguments. mov esp, ebp From 2c9f8e203915c10b4c5799412a2fde8207814822 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 25 Mar 2024 11:56:13 +0300 Subject: [PATCH 203/341] Ring3: Moved UINT64 arguments to the end of argument list to fix IA32 stack. --- .../Core/Dxe/DxeRing3/Ring3Protocols.c | 16 +-- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 6 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 100 +++++++++--------- 3 files changed, 59 insertions(+), 63 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c index 4bd19be66e..9731dedb67 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c @@ -35,9 +35,9 @@ Ring3BlockIoRead ( SysCallBlockIoRead, This, MediaId, - Lba, BufferSize, - Buffer + Buffer, + Lba ); } @@ -55,9 +55,9 @@ Ring3BlockIoWrite ( SysCallBlockIoWrite, This, MediaId, - Lba, BufferSize, - Buffer + Buffer, + Lba ); } @@ -87,9 +87,9 @@ Ring3DiskIoRead ( SysCallDiskIoRead, This, MediaId, - Offset, BufferSize, - Buffer + Buffer, + Offset ); } @@ -107,9 +107,9 @@ Ring3DiskIoWrite ( SysCallDiskIoWrite, This, MediaId, - Offset, BufferSize, - Buffer + Buffer, + Offset ); } diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index e42fa8752b..54f0b2abd1 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -150,8 +150,8 @@ Ring3FreePages ( Status = SysCall ( SysCallFreePages, - Memory, - NumberOfPages + NumberOfPages, + Memory ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Ring3: Failed to free %d pages.\n", NumberOfPages)); @@ -594,7 +594,7 @@ Ring3LocateHandleBuffer ( Buffer ); - if ((NumberHandles != NULL) && (Buffer != NULL) && (*Buffer != NULL)) { + if ((NumberHandles != NULL) && (*NumberHandles != 0) && (Buffer != NULL) && (*Buffer != NULL)) { PoolSize = *NumberHandles * sizeof (EFI_HANDLE *); Status = CoreAllocatePool (EfiRing3MemoryType, PoolSize, &Pool); diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index ea5940f924..f6d004c012 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -565,17 +565,17 @@ CallBootService ( case SysCallFreePages: // - // Argument 1: EFI_PHYSICAL_ADDRESS Memory - // Argument 2: UINTN NumberOfPages + // Argument 1: UINTN NumberOfPages + // Argument 2: EFI_PHYSICAL_ADDRESS Memory // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + CoreRbp->Argument2 * EFI_PAGE_SIZE - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + CoreRbp->Argument1 * EFI_PAGE_SIZE - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); return gBS->FreePages ( - (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, - CoreRbp->Argument2 + *(EFI_PHYSICAL_ADDRESS *)&CoreRbp->Argument2, + CoreRbp->Argument1 ); case SysCallRaiseTpl: @@ -811,9 +811,9 @@ CallBootService ( // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This // Argument 2: UINT32 MediaId - // Argument 3: EFI_LBA Lba - // Argument 4: UINTN BufferSize - // Argument 5: VOID *Buffer + // Argument 3: UINTN BufferSize + // Argument 4: VOID *Buffer + // Argument 5: EFI_LBA Lba // BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); @@ -825,10 +825,10 @@ CallBootService ( ASSERT ((Attributes & EFI_MEMORY_USER) != 0); DisableSMAP (); - Argument4 = UserRsp->Arguments[4]; + Attributes = *(UINT64 *)&UserRsp->Arguments[5]; EnableSMAP (); - Argument5 = (UINTN)AllocatePool (Argument4); + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); if ((VOID *)Argument5 == NULL) { return EFI_OUT_OF_RESOURCES; } @@ -836,17 +836,17 @@ CallBootService ( Status = BlockIo->ReadBlocks ( BlockIo, (UINT32)CoreRbp->Argument2, - (EFI_LBA)CoreRbp->Argument3, - Argument4, + (EFI_LBA)Attributes, + CoreRbp->Argument3, (VOID *)Argument5 ); DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[5] + Argument4 - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); EnableSMAP (); FreePool ((VOID *)Argument5); @@ -857,9 +857,9 @@ CallBootService ( // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This // Argument 2: UINT32 MediaId - // Argument 3: EFI_LBA Lba - // Argument 4: UINTN BufferSize - // Argument 5: VOID *Buffer + // Argument 3: UINTN BufferSize + // Argument 4: VOID *Buffer + // Argument 5: EFI_LBA Lba // BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); @@ -870,29 +870,27 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); - Argument4 = UserRsp->Arguments[4]; - EnableSMAP (); - - Argument5 = (UINTN)AllocatePool (Argument4); + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); if ((VOID *)Argument5 == NULL) { return EFI_OUT_OF_RESOURCES; } DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[5] + Argument4 - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - CopyMem ((VOID *)Argument5,(VOID *)UserRsp->Arguments[5], Argument4); + CopyMem ((VOID *)Argument5,(VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); + + Attributes = *(UINT64 *)&UserRsp->Arguments[5]; EnableSMAP (); Status = BlockIo->WriteBlocks ( BlockIo, (UINT32)CoreRbp->Argument2, - (EFI_LBA)CoreRbp->Argument3, - Argument4, + (EFI_LBA)Attributes, + CoreRbp->Argument3, (VOID *)Argument5 ); @@ -916,9 +914,9 @@ CallBootService ( // // Argument 1: EFI_DISK_IO_PROTOCOL *This // Argument 2: UINT32 MediaId - // Argument 3: UINT64 Offset - // Argument 4: UINTN BufferSize - // Argument 5: VOID *Buffer + // Argument 3: UINTN BufferSize + // Argument 4: VOID *Buffer + // Argument 5: UINT64 Offset // DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); @@ -930,10 +928,10 @@ CallBootService ( ASSERT ((Attributes & EFI_MEMORY_USER) != 0); DisableSMAP (); - Argument4 = UserRsp->Arguments[4]; + Attributes = *(UINT64 *)&UserRsp->Arguments[5]; EnableSMAP (); - Argument5 = (UINTN)AllocatePool (Argument4); + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); if ((VOID *)Argument5 == NULL) { return EFI_OUT_OF_RESOURCES; } @@ -941,17 +939,17 @@ CallBootService ( Status = DiskIo->ReadDisk ( DiskIo, (UINT32)CoreRbp->Argument2, - (UINT64)CoreRbp->Argument3, - Argument4, + Attributes, + CoreRbp->Argument3, (VOID *)Argument5 ); DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[5] + Argument4 - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); EnableSMAP (); FreePool ((VOID *)Argument5); @@ -962,9 +960,9 @@ CallBootService ( // // Argument 1: EFI_DISK_IO_PROTOCOL *This // Argument 2: UINT32 MediaId - // Argument 3: UINT64 Offset - // Argument 4: UINTN BufferSize - // Argument 5: VOID *Buffer + // Argument 3: UINTN BufferSize + // Argument 4: VOID *Buffer + // Argument 5: UINT64 Offset // DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); @@ -975,29 +973,27 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); - Argument4 = UserRsp->Arguments[4]; - EnableSMAP (); - - Argument5 = (UINTN)AllocatePool (Argument4); + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); if ((VOID *)Argument5 == NULL) { return EFI_OUT_OF_RESOURCES; } DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[5] + Argument4 - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - CopyMem ((VOID *)Argument5, (VOID *)UserRsp->Arguments[5], Argument4); + CopyMem ((VOID *)Argument5, (VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); + + Attributes = *(UINT64 *)&UserRsp->Arguments[5]; EnableSMAP (); Status = DiskIo->WriteDisk ( DiskIo, (UINT32)CoreRbp->Argument2, - (UINT64)CoreRbp->Argument3, - Argument4, + Attributes, + CoreRbp->Argument3, (VOID *)Argument5 ); From 343e10059d0a57121c74941a13159ccd24dd3176 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 25 Mar 2024 14:35:19 +0300 Subject: [PATCH 204/341] Ring3: Fixed bug in Ring3LocateHandleBuffer(), added SysCallNames. --- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 3 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 54f0b2abd1..0dab6fc79e 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -594,7 +594,8 @@ Ring3LocateHandleBuffer ( Buffer ); - if ((NumberHandles != NULL) && (*NumberHandles != 0) && (Buffer != NULL) && (*Buffer != NULL)) { + if ((!EFI_ERROR (StatusBS)) && (NumberHandles != NULL) && (*NumberHandles != 0) + && (Buffer != NULL) && (*Buffer != NULL)) { PoolSize = *NumberHandles * sizeof (EFI_HANDLE *); Status = CoreAllocatePool (EfiRing3MemoryType, PoolSize, &Pool); diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index f6d004c012..8ae1175bdf 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -18,6 +18,44 @@ typedef struct { UINTN mRing3InterfacePointer = 0; +CHAR8 *SysCallNames[] = { + // + // BootServices + // + "SysCallReturnToCore", // Must always be zero for CoreBootServices.nasm. + "SysCallLocateProtocol", + "SysCallOpenProtocol", + "SysCallInstallMultipleProtocolInterfaces", + "SysCallCloseProtocol", + "SysCallHandleProtocol", + "SysCallAllocatePages", + "SysCallFreePages", + "SysCallRaiseTpl", + "SysCallRestoreTpl", + "SysCallLocateHandleBuffer", + "SysCallCalculateCrc32", + // + // RuntimeServices + // + "SysCallGetVariable", + // + // Protocols + // + "SysCallBlockIoReset", + "SysCallBlockIoRead", + "SysCallBlockIoWrite", + "SysCallBlockIoFlush", + "SysCallDiskIoRead", + "SysCallDiskIoWrite", + "SysCallUnicodeStriColl", + "SysCallUnicodeMetaiMatch", + "SysCallUnicodeStrLwr", + "SysCallUnicodeStrUpr", + "SysCallUnicodeFatToStr", + "SysCallUnicodeStrToFat", + "SysCallMax" +}; + EFI_STATUS EFIAPI CallInstallMultipleProtocolInterfaces ( From bb72d025be5706bc10a7f45be6698f415070dc8b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 25 Mar 2024 14:37:06 +0300 Subject: [PATCH 205/341] Ring3: Fixed bug in IA32 SetPosition() and Open(). --- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 33 +++++++++++++++++++ .../Core/Dxe/SysCall/SupportedProtocols.c | 32 ++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index e0800f446f..da40513a94 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -143,6 +143,29 @@ EFI_STATUS IN UINTN Argument5 ); +typedef +EFI_STATUS +(EFIAPI *FUNCTION_6)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4, + IN UINTN Argument5, + IN UINTN Argument6 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_7)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4, + IN UINTN Argument5, + IN UINTN Argument6, + IN UINTN Argument7 + ); + VOID EFIAPI Ring3Call ( @@ -156,6 +179,8 @@ Ring3Call ( FUNCTION_3 Function3; FUNCTION_4 Function4; FUNCTION_5 Function5; + FUNCTION_6 Function6; + FUNCTION_7 Function7; switch (Data->NumberOfArguments) { case 0: @@ -182,6 +207,14 @@ Ring3Call ( Function5 = (FUNCTION_5)Data->EntryPoint; Status = Function5 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4]); break; + case 6: + Function6 = (FUNCTION_6)Data->EntryPoint; + Status = Function6 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5]); + break; + case 7: + Function7 = (FUNCTION_7)Data->EntryPoint; + Status = Function7 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5], Data->Arguments[6]); + break; default: Status = EFI_UNSUPPORTED; break; diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index ac908a3005..a7acb4ceb8 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -322,12 +322,27 @@ CoreFileSetPosition ( File = (RING3_EFI_FILE_PROTOCOL *)This; +#if defined (MDE_CPU_X64) return GoToRing3 ( 2, (VOID *)mRing3FileProtocol.SetPosition, File->Ring3File, Position ); +#endif + +#if defined (MDE_CPU_IA32) + // + // UINT64 Position is passed as 2 double words on stack. + // + return GoToRing3 ( + 3, + (VOID *)mRing3FileProtocol.SetPosition, + File->Ring3File, + Position + ); +#endif + } STATIC @@ -582,6 +597,7 @@ CoreFileOpen ( return Status; } +#if defined (MDE_CPU_X64) Status = GoToRing3 ( 5, (VOID *)mRing3FileProtocol.Open, @@ -591,6 +607,22 @@ CoreFileOpen ( OpenMode, Attributes ); +#endif + +#if defined (MDE_CPU_IA32) + // + // UINT64 OpenMode and Attributes are each passed as 2 double words on stack. + // + Status = GoToRing3 ( + 7, + (VOID *)mRing3FileProtocol.Open, + File->Ring3File, + Ring3NewHandle, + Ring3FileName, + OpenMode, + Attributes + ); +#endif if (EFI_ERROR (Status)) { *NewHandle = NULL; CoreFreePages (Ring3Pages, PagesNumber); From e3c3aff26456149313837c18dcacdd6c0d6c2ba2 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 25 Mar 2024 19:26:12 +0300 Subject: [PATCH 206/341] Ring3: Fixed interrupts handling for IA32. --- .../Core/Dxe/DxeRing3/IA32/SysCall.nasm | 2 - .../Dxe/SysCall/IA32/CoreBootServices.nasm | 2 + .../Ia32/ExceptionHandlerAsm.nasm | 47 ++++++++++++++++++- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm index 1e50f950dc..25817aded8 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm @@ -24,7 +24,6 @@ ASM_PFX(SysCall): sysenter userReturnAddress: - ; sti ret ;------------------------------------------------------------------------------ @@ -39,6 +38,5 @@ userReturnAddress: global ASM_PFX(Ring3EntryPoint) ASM_PFX(Ring3EntryPoint): push eax - ; sti call ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index c5e8b68ad3..f0ae792209 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -161,6 +161,7 @@ ASM_PFX(CoreBootServices): pop ebp pop ecx ; User Stack Pointer. + sti sysexit ;------------------------------------------------------------------------------ @@ -194,6 +195,7 @@ ASM_PFX(CallRing3): mov ebp, ecx ; Pass control to user image + sti sysexit coreReturnAddress: diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm index 9a92c931dd..c6876eff64 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm @@ -167,6 +167,10 @@ ErrorCodeAndVectorOnStack: ; ; Stack: ; +---------------------+ + ; + Old SS + on CPL change + ; +---------------------+ + ; + Old ESP + on CPL change + ; +---------------------+ ; + EFlags + ; +---------------------+ ; + CS + @@ -198,6 +202,12 @@ ErrorCodeAndVectorOnStack: push edx push ebx lea ecx, [ebp + 6 * 4] + ; Check whether Ring0 process was interrupted. + mov eax, ds + and eax, 3 + jz sameCPL_0 + mov ecx, [ecx] +sameCPL_0: push ecx ; ESP push dword [ebp] ; EBP push esi @@ -205,9 +215,15 @@ ErrorCodeAndVectorOnStack: ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; mov eax, ss - push eax + ; Check whether Ring0 process was interrupted. + mov ecx, ds + and ecx, 3 + jz sameCPL_1 + movzx eax, word [ebp + 7 * 4] +sameCPL_1: + push eax ; for ss movzx eax, word [ebp + 4 * 4] - push eax + push eax ; for cs mov eax, ds push eax mov eax, es @@ -217,6 +233,12 @@ ErrorCodeAndVectorOnStack: mov eax, gs push eax + mov eax, ss + mov ds, eax + mov es, eax + mov fs, eax + mov gs, eax + ;; UINT32 Eip; mov eax, [ebp + 3 * 4] push eax @@ -367,7 +389,15 @@ ErrorCodeAndVectorOnStack: pop es pop ds pop dword [ebp + 4 * 4] + ; Check whether Ring0 process was interrupted. + mov ecx, ss + and ecx, 3 + jz sameCPL_2 + pop dword [ebp + 7 * 4] + jmp continue +sameCPL_2: pop ss +continue: ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; pop edi @@ -379,6 +409,14 @@ ErrorCodeAndVectorOnStack: pop ecx pop eax + ; Check whether Ring3 process was interrupted. + push ecx + mov ecx, ds + and ecx, 3 + cmp ecx, 3 + pop ecx + je ReturnToRing3 + pop dword [ebp - 8] pop dword [ebp - 4] mov esp, ebp @@ -406,6 +444,11 @@ DoReturn: DoIret: iretd +ReturnToRing3: + mov esp, ebp + pop ebp + add esp, 8 + iretd ;---------------------------------------; ; _AsmGetTemplateAddressMap ; From f558fd0923b5841773c0a589abd7a2c5e586f822 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 26 Mar 2024 15:50:46 +0300 Subject: [PATCH 207/341] SysCall: Some refactoring. --- .../Dxe/SysCall/X64/CoreBootServices.nasm | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 3d0e96b5a0..4d14d81d74 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -12,8 +12,6 @@ extern ASM_PFX(gCoreSysCallStackTop) extern ASM_PFX(gRing3CallStackTop) extern ASM_PFX(gRing3EntryPoint) -extern ASM_PFX(AsmReadMsr64) - DEFAULT REL SECTION .text @@ -79,9 +77,8 @@ ASM_PFX(CallInstallMultipleProtocolInterfaces): copy: sub rax, 8 push qword [rax] - cmp r10, 0 sub r10, 1 - jne copy + jnz copy push rcx call r11 @@ -96,7 +93,9 @@ copy: %macro SetRing3DataSegmentSelectors 0 mov rcx, MSR_IA32_STAR - call ASM_PFX(AsmReadMsr64) + rdmsr + shl rdx, 0x20 + or rax, rdx ; rax = ((RING3_CODE64_SEL - 16) << 16 | RING0_CODE64_SEL) << 32 shr rax, 48 add rax, 8 @@ -197,19 +196,23 @@ ASM_PFX(CallRing3): pop r11 cli + ; Save Core Stack pointers. + mov [ASM_PFX(CoreRsp)], rsp + mov [ASM_PFX(CoreRbp)], rbp + ; Save input Arguments. - push rcx + mov r8, [ASM_PFX(gRing3CallStackTop)] + mov r9, [ASM_PFX(gRing3EntryPoint)] + mov r10, rcx SetRing3DataSegmentSelectors ; Prepare SYSRET arguments. - mov rcx, [ASM_PFX(gRing3EntryPoint)] - pop rdx + mov rdx, r10 + mov rcx, r9 - ; Save Core Stack pointers and switch to User Stack. - mov [ASM_PFX(CoreRsp)], rsp - mov [ASM_PFX(CoreRbp)], rbp - mov rsp, [ASM_PFX(gRing3CallStackTop)] + ; Switch to User Stack. + mov rsp, r8 mov rbp, rsp ; Pass control to user image From 68e050497a75e5b90527738e7100ef749027cad4 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 13 May 2024 12:57:58 +0300 Subject: [PATCH 208/341] Ring3: Added dummy functions for ARM, AARCH64. --- ArmVirtPkg/ArmVirt.dsc.inc | 1 + ArmVirtPkg/ArmVirtQemu.dsc | 4 + ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 5 ++ MdeModulePkg/Core/Dxe/DxeMain.inf | 11 ++- .../Core/Dxe/DxeRing3/AARCH64/SysCall.S | 32 ++++++++ MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S | 32 ++++++++ MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf | 9 ++- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 73 +++++++++++++++++++ .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 17 +++++ .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 73 +++++++++++++++++++ .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 17 +++++ .../Core/Dxe/SysCall/SupportedProtocols.c | 25 +++++-- 12 files changed, 291 insertions(+), 8 deletions(-) create mode 100644 MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S create mode 100644 MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S create mode 100644 MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S create mode 100644 MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c create mode 100644 MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S create mode 100644 MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 68cefda0d4..8fdc172aca 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -236,6 +236,7 @@ ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf CpuArchLib|ArmPkg/Library/CpuArchLib/CpuArchLib.inf + MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf [LibraryClasses.common.DXE_DRIVER] SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index 6f6a0e87a4..fa8a51b35b 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -471,6 +471,10 @@ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf FatPkg/EnhancedFatDxe/Fat.inf + MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { + + MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf + } MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc index 7d6d05acf4..60a1634550 100644 --- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc +++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc @@ -38,6 +38,10 @@ READ_STATUS = TRUE READ_LOCK_CAP = TRUE READ_LOCK_STATUS = TRUE +APRIORI DXE { + INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +} + INF MdeModulePkg/Core/Dxe/DxeMain.inf INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf INF OvmfPkg/Fdt/VirtioFdtDxe/VirtioFdtDxe.inf @@ -82,6 +86,7 @@ READ_LOCK_STATUS = TRUE INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF FatPkg/EnhancedFatDxe/Fat.inf + INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 02c4bd8a04..7623b10e62 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -22,7 +22,7 @@ # # The following information is for reference only and not required by the build tools. # -# VALID_ARCHITECTURES = IA32 X64 EBC (EBC is for build only) +# VALID_ARCHITECTURES = IA32 X64 EBC (EBC is for build only) ARM AARCH64 # [Sources] @@ -78,11 +78,20 @@ SysCall/X64/InitializeMsr.c SysCall/X64/CoreBootServices.nasm +[Sources.ARM] + SysCall/ARM/InitializeMsr.c + SysCall/ARM/CoreBootServices.S + +[Sources.AARCH64] + SysCall/AARCH64/InitializeMsr.c + SysCall/AARCH64/CoreBootServices.S + [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec UefiCpuPkg/UefiCpuPkg.dec OvmfPkg/OvmfPkg.dec + ArmPkg/ArmPkg.dec [LibraryClasses] BaseMemoryLib diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S new file mode 100644 index 0000000000..2a22be0c0a --- /dev/null +++ b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S @@ -0,0 +1,32 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +//------------------------------------------------------------------------------ + +#include + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// SysCall ( +// IN UINT8 Type, +// ... +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(SysCall) + + ret + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// Ring3EntryPoint ( +// IN RING3_CALL_DATA *Data +// ); +// +// (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3(). +// (rdx) Data +//------------------------------------------------------------------------------ +ASM_FUNC(Ring3EntryPoint) + + ret diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S new file mode 100644 index 0000000000..dd9d6d8721 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S @@ -0,0 +1,32 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +//------------------------------------------------------------------------------ + +#include + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// SysCall ( +// IN UINT8 Type, +// ... +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(SysCall) + + bx LR + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// Ring3EntryPoint ( +// IN RING3_CALL_DATA *Data +// ); +// +// (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3(). +// (rdx) Data +//------------------------------------------------------------------------------ +ASM_FUNC(Ring3EntryPoint) + + bx LR diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index 4c36e5a97e..ca5e9a0f5b 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -18,7 +18,7 @@ # # The following information is for reference only and not required by the build tools. # -# VALID_ARCHITECTURES = IA32 X64 +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 # [Sources] @@ -34,9 +34,16 @@ [Sources.X64] X64/SysCall.nasm +[Sources.ARM] + ARM/SysCall.S + +[Sources.AARCH64] + AARCH64/SysCall.S + [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + ArmPkg/ArmPkg.dec [LibraryClasses] BaseLib diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S new file mode 100644 index 0000000000..1d26d79473 --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +//------------------------------------------------------------------------------ + +#include + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// DisableSMAP ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(DisableSMAP) + ret + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// EnableSMAP ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(EnableSMAP) + ret + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CallInstallMultipleProtocolInterfaces ( +// IN EFI_HANDLE *Handle, +// IN VOID **ArgList, +// IN UINT32 ArgListSize, +// IN VOID *Function +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(CallInstallMultipleProtocolInterfaces) + ret + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CoreBootServices ( +// IN UINT8 Type, +// ... +// ); +// +// (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). +// (rdx) Argument 1 of the called function. +// (r8) Argument 2 of the called function. +// (r9) Argument 3 of the called function. +// (r10) Type. +// (r11) RFLAGS saved by SYSCALL in SysCall(). +// +// (On User Stack) Argument 4, 5, ... +//------------------------------------------------------------------------------ +ASM_FUNC(CoreBootServices) + ret + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CallRing3 ( +// IN RING3_CALL_DATA *Data +// ); +// +// (rcx) Data +//------------------------------------------------------------------------------ +ASM_FUNC(CallRing3) + ret diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c new file mode 100644 index 0000000000..bc844910fd --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -0,0 +1,17 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +VOID +EFIAPI +InitializeMsr ( + VOID + ) +{ + +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S new file mode 100644 index 0000000000..406a7f66cf --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +//------------------------------------------------------------------------------ + +#include + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// DisableSMAP ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(DisableSMAP) + bx LR + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// EnableSMAP ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(EnableSMAP) + bx LR + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CallInstallMultipleProtocolInterfaces ( +// IN EFI_HANDLE *Handle, +// IN VOID **ArgList, +// IN UINT32 ArgListSize, +// IN VOID *Function +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(CallInstallMultipleProtocolInterfaces) + bx LR + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CoreBootServices ( +// IN UINT8 Type, +// ... +// ); +// +// (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). +// (rdx) Argument 1 of the called function. +// (r8) Argument 2 of the called function. +// (r9) Argument 3 of the called function. +// (r10) Type. +// (r11) RFLAGS saved by SYSCALL in SysCall(). +// +// (On User Stack) Argument 4, 5, ... +//------------------------------------------------------------------------------ +ASM_FUNC(CoreBootServices) + bx LR + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CallRing3 ( +// IN RING3_CALL_DATA *Data +// ); +// +// (rcx) Data +//------------------------------------------------------------------------------ +ASM_FUNC(CallRing3) + bx LR diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c new file mode 100644 index 0000000000..bc844910fd --- /dev/null +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -0,0 +1,17 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +VOID +EFIAPI +InitializeMsr ( + VOID + ) +{ + +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index a7acb4ceb8..95f98b3ef8 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -329,9 +329,7 @@ CoreFileSetPosition ( File->Ring3File, Position ); -#endif - -#if defined (MDE_CPU_IA32) +#elif defined (MDE_CPU_IA32) // // UINT64 Position is passed as 2 double words on stack. // @@ -341,6 +339,13 @@ CoreFileSetPosition ( File->Ring3File, Position ); +#else + return GoToRing3 ( + 2, + (VOID *)mRing3FileProtocol.SetPosition, + File->Ring3File, + Position + ); #endif } @@ -607,9 +612,7 @@ CoreFileOpen ( OpenMode, Attributes ); -#endif - -#if defined (MDE_CPU_IA32) +#elif defined (MDE_CPU_IA32) // // UINT64 OpenMode and Attributes are each passed as 2 double words on stack. // @@ -622,6 +625,16 @@ CoreFileOpen ( OpenMode, Attributes ); +#else + Status = GoToRing3 ( + 5, + (VOID *)mRing3FileProtocol.Open, + File->Ring3File, + Ring3NewHandle, + Ring3FileName, + OpenMode, + Attributes + ); #endif if (EFI_ERROR (Status)) { *NewHandle = NULL; From 75d1a87072a5527064952c830bb664cfaa113f0d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 16 May 2024 15:41:46 +0300 Subject: [PATCH 209/341] Ring3: Added EL0 and PAN support for AARCH64. --- ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c | 15 +++++++++++ .../Library/ArmLib/AArch64/AArch64Support.S | 10 +++++++ .../Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 22 +++++++++++++--- ArmPkg/Library/CpuArchLib/AArch64/Mmu.c | 20 +++++++++++--- ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 1 + BaseTools/Conf/tools_def.template | 4 +-- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 26 +++++++++++++++++++ MdePkg/Include/AArch64/AArch64.h | 16 ++++++++++++ MdePkg/Include/AArch64/AArch64Mmu.h | 4 +++ MdePkg/Include/Library/ArmLib.h | 12 +++++++++ 10 files changed, 121 insertions(+), 9 deletions(-) diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c index 53b202ff34..b64177bc5f 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Lib.c @@ -65,6 +65,21 @@ ArmHasVhe ( return ((ArmReadIdAA64Mmfr1 () & AARCH64_MMFR1_VH) != 0); } +/** + Checks whether the CPU implements the Privileged Access Never. + + @retval TRUE FEAT_PAN is implemented. + @retval FALSE FEAT_PAN is not mplemented. +**/ +BOOLEAN +EFIAPI +ArmHasPan ( + VOID + ) +{ + return ((ArmReadIdAA64Mmfr1 () & AARCH64_MMFR1_PAN) != 0); +} + /** Checks whether the CPU implements the Trace Buffer Extension. diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S index 66daa27fb4..2d45b9c733 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S @@ -338,6 +338,16 @@ ASM_FUNC(ArmReadCurrentEL) mrs x0, CurrentEL ret +// VOID ArmSetPan(VOID) +ASM_FUNC(ArmSetPan) + msr pan, #1 + ret + +// VOID ArmClearPan(VOID) +ASM_FUNC(ArmClearPan) + msr pan, #0 + ret + // UINT32 ArmReadCntHctl(VOID) ASM_FUNC(ArmReadCntHctl) mrs x0, cnthctl_el2 diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index cb45102bcc..74b5e16c9e 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -475,14 +475,28 @@ GcdAttributeToPageAttribute ( } } - if ((GcdAttributes & EFI_MEMORY_RO) != 0) { - PageAttributes |= TT_AP_NO_RO; - } - if ((GcdAttributes & EFI_MEMORY_RP) == 0) { PageAttributes |= TT_AF; } + if ((GcdAttributes & EFI_MEMORY_USER) != 0) { + PageAttributes |= TT_PXN_MASK; + + if ((GcdAttributes & EFI_MEMORY_RO) != 0) { + PageAttributes |= TT_AP_RO_RO; + } else { + PageAttributes |= TT_AP_RW_RW; + } + } else { + PageAttributes |= TT_UXN_MASK; + + if ((GcdAttributes & EFI_MEMORY_RO) != 0) { + PageAttributes |= TT_AP_NO_RO; + } else { + PageAttributes |= TT_AP_NO_RW; + } + } + return PageAttributes; } diff --git a/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c b/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c index ff14c2f814..922fdbbb14 100644 --- a/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c +++ b/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c @@ -385,13 +385,27 @@ EfiAttributeToArmAttribute ( } // Determine protection attributes - if ((EfiAttributes & EFI_MEMORY_RO) != 0) { - ArmAttributes |= TT_AP_NO_RO; + if ((EfiAttributes & EFI_MEMORY_USER) != 0) { + ArmAttributes |= TT_PXN_MASK; + + if ((EfiAttributes & EFI_MEMORY_RO) != 0) { + ArmAttributes |= TT_AP_RO_RO; + } else { + ArmAttributes |= TT_AP_RW_RW; + } + } else { + ArmAttributes |= TT_UXN_MASK; + + if ((EfiAttributes & EFI_MEMORY_RO) != 0) { + ArmAttributes |= TT_AP_NO_RO; + } else { + ArmAttributes |= TT_AP_NO_RW; + } } // Process eXecute Never attribute if ((EfiAttributes & EFI_MEMORY_XP) != 0) { - ArmAttributes |= TT_PXN_MASK; + ArmAttributes |= TT_PXN_MASK | TT_UXN_MASK; } return ArmAttributes; diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc index 60a1634550..7592700b68 100644 --- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc +++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc @@ -39,6 +39,7 @@ READ_LOCK_CAP = TRUE READ_LOCK_STATUS = TRUE APRIORI DXE { + INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf } diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index d8b544c209..a7ecc289ac 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -969,7 +969,7 @@ DEFINE GCC5_X64_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-melf_ DEFINE GCC5_X64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wno-error DEFINE GCC5_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEFINE GCC5_ARM_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian -march=armv7-a -DEFINE GCC5_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian +DEFINE GCC5_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian -mcpu=cortex-a76 DEFINE GCC5_ARM_CC_FLAGS = DEF(GCC_ARM_CC_FLAGS) -mword-relocations DEFINE GCC5_AARCH64_CC_FLAGS = DEF(GCC5_ALL_CC_FLAGS) DEF(GCC_AARCH64_CC_FLAGS) -mcmodel=small DEFINE GCC5_ARM_DLINK_FLAGS = DEF(GCC_ARM_DLINK_FLAGS) -Wl,--oformat=elf32-littlearm @@ -1471,7 +1471,7 @@ DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_ *_CLANGDWARF_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -fno-lto *_CLANGDWARF_AARCH64_ASLDLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_ASLDLINK_FLAGS) -fuse-ld=lld -*_CLANGDWARF_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) -Qunused-arguments +*_CLANGDWARF_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) -Qunused-arguments -mcpu=cortex-a76 *_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_DLINK_FLAGS) DEF(GCC_ALIGN) *_CLANGDWARF_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) *_CLANGDWARF_AARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index bc844910fd..a6466e0cf2 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -5,6 +5,9 @@ **/ +#include +#include + #include "DxeMain.h" VOID @@ -13,5 +16,28 @@ InitializeMsr ( VOID ) { + UINTN Tcr; + // + // If HCR_EL2.NV is 1 and the current Exception level is EL1, + // then EL1 read accesses to the CurrentEL register return a value of 0x2 in bits[3:2]. + // CurrentEL == 1 -> HCR_EL2.NV == 0 + // + // If stage 1 is enabled and stage 1 Base permissions use Direct permissions, + // then GCS access is not permitted and UnprivGCS and PrivGCS are not present. + // + // Disable Hierarchical permissions just in case. + // + Tcr = ArmGetTCR (); + Tcr |= TCR_EL1_HPD0_MASK | TCR_EL1_HPD1_MASK; + ArmSetTCR (Tcr); + if (ArmHasPan ()) { + // + // Enable Privileged Access Never feature. + // + ArmSetPan (); + } else { + DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n")); + ASSERT (FALSE); + } } diff --git a/MdePkg/Include/AArch64/AArch64.h b/MdePkg/Include/AArch64/AArch64.h index 4e5830c375..54b41fd662 100644 --- a/MdePkg/Include/AArch64/AArch64.h +++ b/MdePkg/Include/AArch64/AArch64.h @@ -28,6 +28,7 @@ // ID_AA64MMFR1 - AArch64 Memory Model Feature Register 0 definitions #define AARCH64_MMFR1_VH (0xF << 8) +#define AARCH64_MMFR1_PAN (0xF << 20) // ID_AA64PFR0 - AArch64 Processor Feature Register 0 definitions #define AARCH64_PFR0_FP (0xF << 16) @@ -241,6 +242,21 @@ ArmReadCurrentEL ( VOID ); +VOID +ArmSetPan ( + VOID + ); + +VOID +ArmClearPan ( + VOID + ); + +UINTN +ArmWriteCptr ( + IN UINT64 Cptr + ); + UINT32 ArmReadCntHctl ( VOID diff --git a/MdePkg/Include/AArch64/AArch64Mmu.h b/MdePkg/Include/AArch64/AArch64Mmu.h index 763dc53908..032713b29e 100644 --- a/MdePkg/Include/AArch64/AArch64Mmu.h +++ b/MdePkg/Include/AArch64/AArch64Mmu.h @@ -135,6 +135,8 @@ #define TCR_EL1_AS_FIELD (36) #define TCR_EL1_TBI0_FIELD (37) #define TCR_EL1_TBI1_FIELD (38) +#define TCR_EL1_HPD0_FIELD (41) +#define TCR_EL1_HPD1_FIELD (42) #define TCR_EL1_T0SZ_MASK (0x1FUL << TCR_EL1_T0SZ_FIELD) #define TCR_EL1_EPD0_MASK (0x01UL << TCR_EL1_EPD0_FIELD) #define TCR_EL1_IRGN0_MASK (0x03UL << TCR_EL1_IRGN0_FIELD) @@ -152,6 +154,8 @@ #define TCR_EL1_AS_MASK (0x01UL << TCR_EL1_AS_FIELD) #define TCR_EL1_TBI0_MASK (0x01UL << TCR_EL1_TBI0_FIELD) #define TCR_EL1_TBI1_MASK (0x01UL << TCR_EL1_TBI1_FIELD) +#define TCR_EL1_HPD0_MASK (0x01UL << TCR_EL1_HPD0_FIELD) +#define TCR_EL1_HPD1_MASK (0x01UL << TCR_EL1_HPD1_FIELD) #define TCR_EL23_T0SZ_FIELD (0) #define TCR_EL23_IRGN0_FIELD (8) diff --git a/MdePkg/Include/Library/ArmLib.h b/MdePkg/Include/Library/ArmLib.h index a5823afdb2..7b5fb28205 100644 --- a/MdePkg/Include/Library/ArmLib.h +++ b/MdePkg/Include/Library/ArmLib.h @@ -727,6 +727,18 @@ ArmHasVhe ( VOID ); +/** + Checks whether the CPU implements the Privileged Access Never. + + @retval TRUE FEAT_PAN is implemented. + @retval FALSE FEAT_PAN is not mplemented. +**/ +BOOLEAN +EFIAPI +ArmHasPan ( + VOID + ); + /** Checks whether the CPU implements the Trace Buffer Extension. From 16a994633b0b5e429edc953814d7f0686afd3da4 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 17 May 2024 13:50:08 +0300 Subject: [PATCH 210/341] Ring3: Initialized DxeRing3 with Supervisor privileges. --- MdeModulePkg/Core/Dxe/DxeMain.h | 14 +++++++ MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 38 +++++++++++++++++++ .../Core/Dxe/SysCall/Initialization.c | 6 +++ 3 files changed, 58 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 8634a1597c..cea44409a2 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2636,6 +2636,20 @@ UnprotectUefiImage ( IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath ); +/** + Change UEFI image owner: Supervisor / Privileged or User / Unprivileged. + + @param[in] LoadedImage The loaded image protocol + @param[in] LoadedImageDevicePath The loaded image device path protocol + @param[in] IsUser Whether UEFI image record is User Image. +**/ +VOID +ChangeUefiImageRing ( + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath, + IN BOOLEAN IsUser + ); + /** ExitBootServices Callback function for memory protection. **/ diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 4be5f37fbf..1652a59c68 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -294,6 +294,44 @@ UnprotectUefiImage ( } } +/** + Change UEFI image owner: Supervisor / Privileged or User / Unprivileged. + + @param[in] LoadedImage The loaded image protocol + @param[in] LoadedImageDevicePath The loaded image device path protocol + @param[in] IsUser Whether UEFI image record is User Image. +**/ +VOID +ChangeUefiImageRing ( + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath, + IN BOOLEAN IsUser + ) +{ + UEFI_IMAGE_RECORD *ImageRecord; + LIST_ENTRY *ImageRecordLink; + + for (ImageRecordLink = mProtectedImageRecordList.ForwardLink; + ImageRecordLink != &mProtectedImageRecordList; + ImageRecordLink = ImageRecordLink->ForwardLink) + { + ImageRecord = CR ( + ImageRecordLink, + UEFI_IMAGE_RECORD, + Link, + UEFI_IMAGE_RECORD_SIGNATURE + ); + + if (ImageRecord->StartAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) { + ASSERT (gCpu != NULL); + + SetUefiImageProtectionAttributes (ImageRecord, IsUser); + + return; + } + } +} + /** Return the EFI memory permission attribute associated with memory type 'MemoryType' under the configured DXE memory protection policy. diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 3bf1d4d74c..0b108d34fa 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -50,9 +50,15 @@ InitializeRing3 ( gRing3Data = (RING3_DATA *)(UINTN)Physical; CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); + // + // Initialize DxeRing3 with Supervisor privileges. + // + ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, FALSE); Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); + ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, TRUE); + gRing3EntryPoint = gRing3Data->EntryPoint; gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; From 0501e0e2c3f6b58a25f99e9e3f315342d098b569 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 20 May 2024 11:34:40 +0300 Subject: [PATCH 211/341] Ring3: Defined CpuGetMemoryAttributes(), DisableSMAP(), EnableSMAP() for AARCH64. --- ArmPkg/Library/CpuArchLib/AArch64/Mmu.c | 6 +++++ ArmPkg/Library/CpuArchLib/CpuDxe.c | 1 + ArmPkg/Library/CpuArchLib/CpuDxe.h | 8 ++++++ ArmPkg/Library/CpuArchLib/CpuMmuCommon.c | 25 +++++++++++++++++++ .../Dxe/SysCall/AARCH64/CoreBootServices.S | 20 --------------- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 18 +++++++++++++ 6 files changed, 58 insertions(+), 20 deletions(-) diff --git a/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c b/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c index 922fdbbb14..c1f80aa612 100644 --- a/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c +++ b/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c @@ -95,6 +95,12 @@ PageAttributeToGcdAttribute ( GcdAttributes |= EFI_MEMORY_XP; } + if (((PageAttributes & TT_AP_MASK) == TT_AP_RW_RW) || + ((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO)) + { + GcdAttributes |= EFI_MEMORY_USER; + } + return GcdAttributes; } diff --git a/ArmPkg/Library/CpuArchLib/CpuDxe.c b/ArmPkg/Library/CpuArchLib/CpuDxe.c index 4dd428d9c5..6dd313a069 100644 --- a/ArmPkg/Library/CpuArchLib/CpuDxe.c +++ b/ArmPkg/Library/CpuArchLib/CpuDxe.c @@ -278,6 +278,7 @@ STATIC EFI_CPU_ARCH_PROTOCOL mCpu = { CpuSetMemoryAttributes, 0, // NumberOfTimers 2048, // DmaBufferAlignment + CpuGetMemoryAttributes }; STATIC diff --git a/ArmPkg/Library/CpuArchLib/CpuDxe.h b/ArmPkg/Library/CpuArchLib/CpuDxe.h index a86de6800f..b80ba2d0d3 100644 --- a/ArmPkg/Library/CpuArchLib/CpuDxe.h +++ b/ArmPkg/Library/CpuArchLib/CpuDxe.h @@ -96,6 +96,14 @@ CpuSetMemoryAttributes ( IN UINT64 Attributes ); +EFI_STATUS +EFIAPI +CpuGetMemoryAttributes ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS Address, + OUT UINT64 *Attributes + ); + EFI_STATUS InitializeExceptions ( VOID diff --git a/ArmPkg/Library/CpuArchLib/CpuMmuCommon.c b/ArmPkg/Library/CpuArchLib/CpuMmuCommon.c index 489c0a17a4..97db7672e8 100644 --- a/ArmPkg/Library/CpuArchLib/CpuMmuCommon.c +++ b/ArmPkg/Library/CpuArchLib/CpuMmuCommon.c @@ -266,3 +266,28 @@ CpuSetMemoryAttributes ( return EFI_SUCCESS; } } + +EFI_STATUS +EFIAPI +CpuGetMemoryAttributes ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS Address, + OUT UINT64 *Attributes + ) +{ + EFI_STATUS Status; + UINTN RegionBaseAddress; + UINTN RegionLength; + UINTN RegionArmAttributes; + + RegionBaseAddress = Address; + Status = GetMemoryRegion (&RegionBaseAddress, &RegionLength, &RegionArmAttributes); + + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + *Attributes = RegionAttributeToGcdAttribute (RegionArmAttributes); + + return Status; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 1d26d79473..35e0c3f6c9 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -7,26 +7,6 @@ #include -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// DisableSMAP ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(DisableSMAP) - ret - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// EnableSMAP ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(EnableSMAP) - ret - //------------------------------------------------------------------------------ // EFI_STATUS // EFIAPI diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index a6466e0cf2..470773a19a 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -41,3 +41,21 @@ InitializeMsr ( ASSERT (FALSE); } } + +VOID +EFIAPI +DisableSMAP ( + VOID + ) +{ + ArmClearPan (); +} + +VOID +EFIAPI +EnableSMAP ( + VOID + ) +{ + ArmSetPan (); +} From 5422bf48f29c534188be32049e7f9717a915c95e Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 20 May 2024 17:27:09 +0300 Subject: [PATCH 212/341] Ring3: Defined CallRing3() for AARCH64. --- .../AArch64/DefaultExceptionHandler.c | 4 +++ MdeModulePkg/Core/Dxe/DxeMain.h | 2 ++ .../Core/Dxe/DxeRing3/AARCH64/SysCall.S | 8 ++--- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 36 +++++++++++++++++-- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 17 +++++++++ 5 files changed, 60 insertions(+), 7 deletions(-) diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index a5f04c04ce..42b093e315 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -8,6 +8,8 @@ **/ +#include + #include #include #include @@ -232,6 +234,8 @@ DefaultExceptionHandler ( DEBUG ((DEBUG_ERROR, "PC 0x%012lx\n", SystemContext.SystemContextAArch64->ELR)); } + ArmClearPan (); + if ((UINT64 *)SystemContext.SystemContextAArch64->FP != 0) { Idx = 0; diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index cea44409a2..251bce67b9 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -277,6 +277,8 @@ extern VOID *gRing3Interfaces; extern VOID *gCoreSysCallStackBase; extern VOID *gCoreSysCallStackTop; extern VOID *gRing3CallStackBase; +extern VOID *gRing3CallStackTop; +extern VOID *gRing3EntryPoint; // // Service Initialization Functions diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S index 2a22be0c0a..8678dacbfe 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S @@ -5,6 +5,8 @@ #include +.extern ASM_PFX(Ring3Call) + //------------------------------------------------------------------------------ // EFI_STATUS // EFIAPI @@ -24,9 +26,7 @@ ASM_FUNC(SysCall) // IN RING3_CALL_DATA *Data // ); // -// (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3(). -// (rdx) Data +// (x0) Data //------------------------------------------------------------------------------ ASM_FUNC(Ring3EntryPoint) - - ret + b ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 35e0c3f6c9..06d28f0c3e 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -47,7 +47,37 @@ ASM_FUNC(CoreBootServices) // IN RING3_CALL_DATA *Data // ); // -// (rcx) Data +// (x0) Data +// (x1) gRing3CallStackTop +// (x2) gRing3EntryPoint //------------------------------------------------------------------------------ -ASM_FUNC(CallRing3) - ret +ASM_FUNC(ArmCallRing3) + // Disable interrupts + msr daifset, #0xf + isb + + // Use SP_ELx for Exception level ELx. + msr SPsel, #1 + + msr sp_el0, x1 + + msr elr_el1, x2 + + // Copy PSTATE to SPSR. + mrs x1, nzcv + mrs x2, pan + orr x1, x1, x2 + mrs x2, daif + orr x1, x1, x2 + // + // M[3:0], bits [3:0] AArch64 Exception level and selected Stack Pointer. + // 0b0000 - EL0. + // 0b0100 - EL1 with SP_EL0 (ELt). + // 0b0101 - EL1 with SP_EL1 (EL1h). + // + msr spsr_el1, x1 + + isb + dsb sy + + eret diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 470773a19a..0510fc5957 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -10,6 +10,14 @@ #include "DxeMain.h" +EFI_STATUS +EFIAPI +ArmCallRing3 ( + IN RING3_CALL_DATA *Data, + IN VOID *StackPointer, + IN VOID *EntryPoint + ); + VOID EFIAPI InitializeMsr ( @@ -59,3 +67,12 @@ EnableSMAP ( { ArmSetPan (); } + +EFI_STATUS +EFIAPI +CallRing3 ( + IN RING3_CALL_DATA *Data + ) +{ + return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint); +} From 212344dde701f1960de19be8e9e826a9848e713e Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 21 May 2024 15:12:24 +0300 Subject: [PATCH 213/341] Ring3: Defined SysCallBootService() for AARCH64. --- .../Library/DefaultExceptionHandlerLib.h | 3 ++- .../AArch64/ExceptionSupport.S | 11 ++++++++++ .../Library/ArmExceptionLib/ArmExceptionLib.c | 6 +++--- .../AArch64/DefaultExceptionHandler.c | 13 +++++++++++- MdeModulePkg/Core/Dxe/DxeMain.h | 8 ++++++++ MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 3 ++- .../Core/Dxe/DxeRing3/AARCH64/SysCall.S | 2 +- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 20 ------------------- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 15 ++++++++++++++ .../Core/Dxe/SysCall/SupportedProtocols.c | 4 ++-- MdePkg/Include/AArch64/AArch64.h | 1 + MdePkg/Include/Uefi/UefiSpec.h | 9 +++++++++ 12 files changed, 66 insertions(+), 29 deletions(-) diff --git a/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h b/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h index 63d5dc78de..f5ddc256bd 100644 --- a/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h +++ b/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h @@ -16,7 +16,8 @@ @param SystemContext Register state at the time of the Exception **/ -VOID +EFI_STATUS +EFIAPI DefaultExceptionHandler ( IN EFI_EXCEPTION_TYPE ExceptionType, IN OUT EFI_SYSTEM_CONTEXT SystemContext diff --git a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S index 714ead608f..787c9d4652 100644 --- a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S @@ -315,7 +315,18 @@ ASM_PFX(CommonExceptionEntry): ldp x22, x23, [sp, #0xb0] ldp x24, x25, [sp, #0xc0] ldp x26, x27, [sp, #0xd0] + // Preserve return value for SVC. + mrs x1, esr_el1 + lsr x1, x1, #26 + and x1, x1, #0x3F + cmp x1, #0x15 + b.eq is_SVC + ldp x0, x1, [sp], #0xe0 + b continue +is_SVC: + ldr x1, [sp, #0x8] +continue: // Pop FP regs from Stack. ldp q2, q3, [x28, #0x20] diff --git a/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c b/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c index 9832aba4b3..83d5543df3 100644 --- a/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c +++ b/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c @@ -131,7 +131,7 @@ RegisterCpuInterruptHandler ( return RETURN_SUCCESS; } -VOID +EFI_STATUS EFIAPI CommonCExceptionHandler ( IN EFI_EXCEPTION_TYPE ExceptionType, @@ -141,14 +141,14 @@ CommonCExceptionHandler ( if ((UINTN)ExceptionType <= gMaxExceptionNumber) { if (gExceptionHandlers[ExceptionType]) { gExceptionHandlers[ExceptionType](ExceptionType, SystemContext); - return; + return EFI_SUCCESS; } } else { DEBUG ((DEBUG_ERROR, "Unknown exception type %d\n", ExceptionType)); ASSERT (FALSE); } - DefaultExceptionHandler (ExceptionType, SystemContext); + return DefaultExceptionHandler (ExceptionType, SystemContext); } /** diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index 42b093e315..8168ea61c1 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -185,7 +185,8 @@ BaseName ( @param SystemContext Register state at the time of the Exception **/ -VOID +EFI_STATUS +EFIAPI DefaultExceptionHandler ( IN EFI_EXCEPTION_TYPE ExceptionType, IN OUT EFI_SYSTEM_CONTEXT SystemContext @@ -196,6 +197,14 @@ DefaultExceptionHandler ( UINTN CharCount; INT32 Offset; + if (AARCH64_ESR_EC (SystemContext.SystemContextAArch64->ESR) == AARCH64_ESR_EC_SVC64) { + return gBS->SysCallBootService ( + SystemContext.SystemContextAArch64->X0, + &(SystemContext.SystemContextAArch64->X1), + &(SystemContext.SystemContextAArch64->X0) + ); + } + if (mRecursiveException) { STATIC CHAR8 CONST Message[] = "\nRecursive exception occurred while dumping the CPU state\n"; SerialPortWrite ((UINT8 *)Message, sizeof Message - 1); @@ -343,4 +352,6 @@ DefaultExceptionHandler ( ASSERT (FALSE); CpuDeadLoop (); + + return EFI_SUCCESS; } diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 251bce67b9..41af06179c 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2734,6 +2734,14 @@ CoreBootServices ( ... ); +EFI_STATUS +EFIAPI +SysCallBootService ( + IN UINT8 Type, + IN VOID *CoreRbp, + IN VOID *UserRsp + ); + EFI_STATUS EFIAPI CallRing3 ( diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 345aa25cf7..6789d6eadc 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -89,7 +89,8 @@ EFI_BOOT_SERVICES mBootServices = { (EFI_CALCULATE_CRC32)CoreEfiNotAvailableYetArg3, // CalculateCrc32 (EFI_COPY_MEM)CopyMem, // CopyMem (EFI_SET_MEM)SetMem, // SetMem - (EFI_CREATE_EVENT_EX)CoreCreateEventEx // CreateEventEx + (EFI_CREATE_EVENT_EX)CoreCreateEventEx, // CreateEventEx + (EFI_SYS_CALL_BOOT_SERVICE)SysCallBootService }; EFI_DXE_SERVICES mDxeServices = { diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S index 8678dacbfe..b3cc3d7c72 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S @@ -16,7 +16,7 @@ // ); //------------------------------------------------------------------------------ ASM_FUNC(SysCall) - + svc #0 ret //------------------------------------------------------------------------------ diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 06d28f0c3e..b6eef51714 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -20,26 +20,6 @@ ASM_FUNC(CallInstallMultipleProtocolInterfaces) ret -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// CoreBootServices ( -// IN UINT8 Type, -// ... -// ); -// -// (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). -// (rdx) Argument 1 of the called function. -// (r8) Argument 2 of the called function. -// (r9) Argument 3 of the called function. -// (r10) Type. -// (r11) RFLAGS saved by SYSCALL in SysCall(). -// -// (On User Stack) Argument 4, 5, ... -//------------------------------------------------------------------------------ -ASM_FUNC(CoreBootServices) - ret - //------------------------------------------------------------------------------ // EFI_STATUS // EFIAPI diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 8ae1175bdf..98d06a6229 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -1391,3 +1391,18 @@ CallBootService ( return EFI_UNSUPPORTED; } + +EFI_STATUS +EFIAPI +SysCallBootService ( + IN UINT8 Type, + IN VOID *CoreRbp, + IN VOID *UserRsp + ) +{ + return CallBootService ( + Type, + (CORE_STACK *)CoreRbp, + (RING3_STACK *)UserRsp + ); +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 95f98b3ef8..b6fd7d7cc1 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -322,7 +322,7 @@ CoreFileSetPosition ( File = (RING3_EFI_FILE_PROTOCOL *)This; -#if defined (MDE_CPU_X64) +#if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) return GoToRing3 ( 2, (VOID *)mRing3FileProtocol.SetPosition, @@ -602,7 +602,7 @@ CoreFileOpen ( return Status; } -#if defined (MDE_CPU_X64) +#if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) Status = GoToRing3 ( 5, (VOID *)mRing3FileProtocol.Open, diff --git a/MdePkg/Include/AArch64/AArch64.h b/MdePkg/Include/AArch64/AArch64.h index 54b41fd662..55d7ef15f1 100644 --- a/MdePkg/Include/AArch64/AArch64.h +++ b/MdePkg/Include/AArch64/AArch64.h @@ -74,6 +74,7 @@ #define AARCH64_ESR_ISS(Ecr) ((0x1FFFFFF) & (Ecr)) #define AARCH64_ESR_EC_SMC32 (0x13 << 26) +#define AARCH64_ESR_EC_SVC64 (0x15 << 26) #define AARCH64_ESR_EC_SMC64 (0x17 << 26) // AArch64 Exception Level diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index b6273143eb..df261d82f5 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -1840,6 +1840,14 @@ EFI_STATUS OUT UINT64 *MaximumVariableSize ); +typedef +EFI_STATUS +(EFIAPI *EFI_SYS_CALL_BOOT_SERVICE)( + IN UINT8 Type, + IN VOID *CoreRbp, + IN VOID *UserRsp + ); + // // Firmware should stop at a firmware user interface on next boot // @@ -2023,6 +2031,7 @@ typedef struct { EFI_COPY_MEM CopyMem; EFI_SET_MEM SetMem; EFI_CREATE_EVENT_EX CreateEventEx; + EFI_SYS_CALL_BOOT_SERVICE SysCallBootService; } EFI_BOOT_SERVICES; typedef enum { From 8e260babaa10e486b000f70b3daf39f10a4cc636 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 23 May 2024 13:49:08 +0300 Subject: [PATCH 214/341] Ring3: Fixed some page faults caused by wrong memory attribution. --- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 9 ++++++ MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 31 ++++++++++++++++--- .../Core/Dxe/SysCall/Initialization.c | 24 ++++++++++++++ .../Core/Dxe/SysCall/SupportedProtocols.c | 4 +++ 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 6789d6eadc..dcf3fdf610 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -776,6 +776,15 @@ CoreExitBootServices ( // Free resources allocated for Ring3. // if (gRing3Data != NULL) { + DisableSMAP (); + if (gRing3Data->SystemTable.ConfigurationTable != NULL) { + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data->SystemTable.ConfigurationTable, + EFI_SIZE_TO_PAGES (gRing3Data->SystemTable.NumberOfTableEntries * sizeof (EFI_CONFIGURATION_TABLE)) + ); + } + EnableSMAP (); + CoreFreePages ( (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 98d06a6229..508fe4fba6 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -1400,9 +1400,30 @@ SysCallBootService ( IN VOID *UserRsp ) { - return CallBootService ( - Type, - (CORE_STACK *)CoreRbp, - (RING3_STACK *)UserRsp - ); + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Physical; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (8 * sizeof (UINTN)), + &Physical + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DisableSMAP (); + CopyMem ((VOID *)(UINTN)Physical, (VOID *)UserRsp, 8 * sizeof (UINTN)); + EnableSMAP (); + + Status = CallBootService ( + Type, + (CORE_STACK *)CoreRbp, + (RING3_STACK *)(UINTN)Physical + ); + + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (8 * sizeof (UINTN))); + + return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 0b108d34fa..58651a4963 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -32,6 +32,8 @@ InitializeRing3 ( VOID *TopOfStack; UINTN SizeOfStack; EFI_PHYSICAL_ADDRESS Physical; + UINTN Index; + EFI_CONFIGURATION_TABLE *Conf; // // Set Ring3 EntryPoint and BootServices. @@ -50,6 +52,28 @@ InitializeRing3 ( gRing3Data = (RING3_DATA *)(UINTN)Physical; CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (gRing3Data->SystemTable.NumberOfTableEntries * sizeof (EFI_CONFIGURATION_TABLE)), + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); + return Status; + } + + Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + + for (Index = 0; Index < gRing3Data->SystemTable.NumberOfTableEntries; ++Index) { + Conf->VendorGuid = gRing3Data->SystemTable.ConfigurationTable[Index].VendorGuid; + Conf->VendorTable = gRing3Data->SystemTable.ConfigurationTable[Index].VendorTable; + ++Conf; + } + + gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + // // Initialize DxeRing3 with Supervisor privileges. // diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index b6fd7d7cc1..90fd9761a1 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -58,6 +58,7 @@ GoToRing3 ( VA_END (Marker); EnableSMAP (); +#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) if (Number == 2) { // // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() @@ -68,9 +69,11 @@ GoToRing3 ( EFI_MEMORY_XP | EFI_MEMORY_USER ); } +#endif Status = CallRing3 (Input); +#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) if (Number == 2) { SetUefiImageMemoryAttributes ( FixedPcdGet32 (PcdOvmfWorkAreaBase), @@ -78,6 +81,7 @@ GoToRing3 ( EFI_MEMORY_XP ); } +#endif CoreFreePages (Ring3Pages, PagesNumber); From a8b91d14350791019e46d1035e334de301e32e27 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 23 May 2024 20:46:54 +0300 Subject: [PATCH 215/341] Ring3: Defined SysCallReturnToCore for AARCH64, forbade ExceptionHanlders to use EL0 stack. --- .../AArch64/ExceptionSupport.S | 27 ++--------------- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 30 +++++++++++++++---- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 8 +++-- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 13 ++++++++ 4 files changed, 47 insertions(+), 31 deletions(-) diff --git a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S index 787c9d4652..2de7be7c8b 100644 --- a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S @@ -111,23 +111,7 @@ GCC_ASM_EXPORT(CommonCExceptionHandler) VECTOR_BASE(ExceptionHandlersStart) - .macro ExceptionEntry, val, sp=SPx - // - // Our backtrace and register dump code is written in C and so it requires - // a stack. This makes it difficult to produce meaningful diagnostics when - // the stack pointer has been corrupted. So in such cases (i.e., when taking - // synchronous exceptions), this macro is expanded with \sp set to SP0, in - // which case we switch to the SP_EL0 stack pointer, which has been - // initialized to point to a buffer that has been set aside for this purpose. - // - // Since 'sp' may no longer refer to the stack frame that was active when - // the exception was taken, we may have to switch back and forth between - // SP_EL0 and SP_ELx to record the correct value for SP in the context struct. - // - .ifnc \sp, SPx - msr SPsel, xzr - .endif - + .macro ExceptionEntry, val // Move the stackpointer so we can reach our structure with the str instruction. sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE) @@ -149,13 +133,7 @@ VECTOR_BASE(ExceptionHandlersStart) stp x28, x29, [sp, #0xe0] add x28, sp, #(GP_CONTEXT_SIZE + FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE) - .ifnc \sp, SPx - msr SPsel, #1 - mov x7, sp - msr SPsel, xzr - .else mov x7, x28 - .endif stp x30, x7, [sp, #0xf0] @@ -190,7 +168,7 @@ ASM_PFX(SErrorSP0): // VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPX_SYNC) ASM_PFX(SynchronousExceptionSPx): - ExceptionEntry EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS, SP0 + ExceptionEntry EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPX_IRQ) ASM_PFX(IrqSPx): @@ -326,6 +304,7 @@ ASM_PFX(CommonExceptionEntry): b continue is_SVC: ldr x1, [sp, #0x8] + add sp, sp, #0xe0 continue: // Pop FP regs from Stack. diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index b6eef51714..c6cc39d265 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -30,18 +30,22 @@ ASM_FUNC(CallInstallMultipleProtocolInterfaces) // (x0) Data // (x1) gRing3CallStackTop // (x2) gRing3EntryPoint +// (x3) gCoreSysCallStackTop +// (x4) &CoreSp //------------------------------------------------------------------------------ ASM_FUNC(ArmCallRing3) + // Save FP and LR on Core Stack. + stp x29, x30, [sp, #-0x10]! // Disable interrupts msr daifset, #0xf isb - - // Use SP_ELx for Exception level ELx. - msr SPsel, #1 - + // Prepare Ring3 SP and EntryPoint. msr sp_el0, x1 - msr elr_el1, x2 + // Save Core SP and switch to Ring3Call Stack. + mov x5, sp + str x5, [x4] + mov sp, x3 // Copy PSTATE to SPSR. mrs x1, nzcv @@ -61,3 +65,19 @@ ASM_FUNC(ArmCallRing3) dsb sy eret + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ReturnToCore ( +// IN EFI_STATUS Status, +// IN UINTN CoreSp +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ReturnToCore) + // Switch to Core Stack. + mov sp, x1 + // Restore Stack. + ldp x29, x30, [sp] + add sp, sp, #0x10 + ret diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 0510fc5957..6db895d8de 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -10,12 +10,16 @@ #include "DxeMain.h" +extern UINTN CoreSp; + EFI_STATUS EFIAPI ArmCallRing3 ( IN RING3_CALL_DATA *Data, IN VOID *StackPointer, - IN VOID *EntryPoint + IN VOID *EntryPoint, + IN VOID *SysCallStack, + IN VOID *CoreStack ); VOID @@ -74,5 +78,5 @@ CallRing3 ( IN RING3_CALL_DATA *Data ) { - return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint); + return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &CoreSp); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 508fe4fba6..061ac97855 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -8,6 +8,8 @@ #include "DxeMain.h" #include "SupportedProtocols.h" +UINTN CoreSp; + LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead); typedef struct { @@ -65,6 +67,13 @@ CallInstallMultipleProtocolInterfaces ( IN VOID *Function ); +VOID +EFIAPI +ReturnToCore ( + IN EFI_STATUS Status, + IN UINTN CoreSp + ); + VOID EFIAPI FreeProtocolsList ( @@ -1403,6 +1412,10 @@ SysCallBootService ( EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Physical; + if (Type == SysCallReturnToCore) { + ReturnToCore (*(EFI_STATUS *)CoreRbp, CoreSp); + } + Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, From c69bfe6c4e25445f2cc25bf8e7ec1d1fb5271ba8 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 23 May 2024 21:30:10 +0300 Subject: [PATCH 216/341] Ring3: Refactored SysCallBootService() out of EFI_BOOT_SERVICES. --- .../Library/DefaultExceptionHandlerLib.h | 6 ++ .../AArch64/DefaultExceptionHandler.c | 30 ++++++++-- MdeModulePkg/Core/Dxe/DxeMain.h | 21 +++++-- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 3 +- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 52 +++++++++++++++- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 59 ------------------- MdePkg/Include/Uefi/UefiSpec.h | 9 --- 7 files changed, 98 insertions(+), 82 deletions(-) diff --git a/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h b/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h index f5ddc256bd..1381cb4f6d 100644 --- a/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h +++ b/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h @@ -23,4 +23,10 @@ DefaultExceptionHandler ( IN OUT EFI_SYSTEM_CONTEXT SystemContext ); +VOID +EFIAPI +InitializeSysCallHandler ( + IN VOID *Handler + ); + #endif // DEFAULT_EXCEPTION_HANDLER_LIB_H_ diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index 8168ea61c1..5dfcf51cda 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -28,6 +28,14 @@ // #define MAX_PRINT_CHARS 100 +typedef +EFI_STATUS +(EFIAPI *EFI_SYS_CALL_BOOT_SERVICE)( + IN UINT8 Type, + IN VOID *CoreRbp, + IN VOID *UserRsp + ); + STATIC CHAR8 *gExceptionTypeString[] = { "Synchronous", "IRQ", @@ -35,7 +43,8 @@ STATIC CHAR8 *gExceptionTypeString[] = { "SError" }; -STATIC BOOLEAN mRecursiveException; +STATIC BOOLEAN mRecursiveException; +STATIC EFI_SYS_CALL_BOOT_SERVICE mSysCallHandler; CONST CHAR8 * GetImageName ( @@ -176,6 +185,15 @@ BaseName ( return Str; } +VOID +EFIAPI +InitializeSysCallHandler ( + IN VOID *Handler + ) +{ + mSysCallHandler = (EFI_SYS_CALL_BOOT_SERVICE)Handler; +} + /** This is the default action to take on an unexpected exception @@ -198,11 +216,11 @@ DefaultExceptionHandler ( INT32 Offset; if (AARCH64_ESR_EC (SystemContext.SystemContextAArch64->ESR) == AARCH64_ESR_EC_SVC64) { - return gBS->SysCallBootService ( - SystemContext.SystemContextAArch64->X0, - &(SystemContext.SystemContextAArch64->X1), - &(SystemContext.SystemContextAArch64->X0) - ); + return mSysCallHandler ( + SystemContext.SystemContextAArch64->X0, + &(SystemContext.SystemContextAArch64->X1), + &(SystemContext.SystemContextAArch64->X0) + ); } if (mRecursiveException) { diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 41af06179c..cbe7402fa4 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -233,6 +233,17 @@ typedef struct { BOOLEAN IsRing3EntryPoint; } LOADED_IMAGE_PRIVATE_DATA; +typedef struct { + UINTN Argument1; + UINTN Argument2; + UINTN Argument3; +} CORE_STACK; + +typedef struct { + UINTN Rip; + UINTN Arguments[]; +} RING3_STACK; + #define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \ CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE) @@ -2736,11 +2747,11 @@ CoreBootServices ( EFI_STATUS EFIAPI -SysCallBootService ( - IN UINT8 Type, - IN VOID *CoreRbp, - IN VOID *UserRsp - ); +CallBootService ( + IN UINT8 Type, + IN CORE_STACK *CoreRbp, + IN RING3_STACK *UserRsp + ); EFI_STATUS EFIAPI diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index dcf3fdf610..e674c9f788 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -89,8 +89,7 @@ EFI_BOOT_SERVICES mBootServices = { (EFI_CALCULATE_CRC32)CoreEfiNotAvailableYetArg3, // CalculateCrc32 (EFI_COPY_MEM)CopyMem, // CopyMem (EFI_SET_MEM)SetMem, // SetMem - (EFI_CREATE_EVENT_EX)CoreCreateEventEx, // CreateEventEx - (EFI_SYS_CALL_BOOT_SERVICE)SysCallBootService + (EFI_CREATE_EVENT_EX)CoreCreateEventEx // CreateEventEx }; EFI_DXE_SERVICES mDxeServices = { diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 6db895d8de..9bed7c8d7d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -7,10 +7,11 @@ #include #include +#include #include "DxeMain.h" -extern UINTN CoreSp; +UINTN CoreSp; EFI_STATUS EFIAPI @@ -22,6 +23,53 @@ ArmCallRing3 ( IN VOID *CoreStack ); +VOID +EFIAPI +ReturnToCore ( + IN EFI_STATUS Status, + IN UINTN CoreSp + ); + +EFI_STATUS +EFIAPI +SysCallBootService ( + IN UINT8 Type, + IN VOID *CoreRbp, + IN VOID *UserRsp + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Physical; + + if (Type == SysCallReturnToCore) { + ReturnToCore (*(EFI_STATUS *)CoreRbp, CoreSp); + } + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (8 * sizeof (UINTN)), + &Physical + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DisableSMAP (); + CopyMem ((VOID *)(UINTN)Physical, (VOID *)UserRsp, 8 * sizeof (UINTN)); + EnableSMAP (); + + Status = CallBootService ( + Type, + (CORE_STACK *)CoreRbp, + (RING3_STACK *)(UINTN)Physical + ); + + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (8 * sizeof (UINTN))); + + return Status; +} + VOID EFIAPI InitializeMsr ( @@ -52,6 +100,8 @@ InitializeMsr ( DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n")); ASSERT (FALSE); } + + InitializeSysCallHandler ((VOID *)SysCallBootService); } VOID diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 061ac97855..7a00ec8dea 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -8,8 +8,6 @@ #include "DxeMain.h" #include "SupportedProtocols.h" -UINTN CoreSp; - LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead); typedef struct { @@ -67,13 +65,6 @@ CallInstallMultipleProtocolInterfaces ( IN VOID *Function ); -VOID -EFIAPI -ReturnToCore ( - IN EFI_STATUS Status, - IN UINTN CoreSp - ); - VOID EFIAPI FreeProtocolsList ( @@ -270,16 +261,6 @@ PrepareRing3Interface ( return Ring3Interface; } -typedef struct { - UINTN Argument1; - UINTN Argument2; - UINTN Argument3; -} CORE_STACK; - -typedef struct { - UINTN Rip; - UINTN Arguments[]; -} RING3_STACK; // // Stack: // rsp - User Rsp @@ -1400,43 +1381,3 @@ CallBootService ( return EFI_UNSUPPORTED; } - -EFI_STATUS -EFIAPI -SysCallBootService ( - IN UINT8 Type, - IN VOID *CoreRbp, - IN VOID *UserRsp - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Physical; - - if (Type == SysCallReturnToCore) { - ReturnToCore (*(EFI_STATUS *)CoreRbp, CoreSp); - } - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (8 * sizeof (UINTN)), - &Physical - ); - if (EFI_ERROR (Status)) { - return Status; - } - - DisableSMAP (); - CopyMem ((VOID *)(UINTN)Physical, (VOID *)UserRsp, 8 * sizeof (UINTN)); - EnableSMAP (); - - Status = CallBootService ( - Type, - (CORE_STACK *)CoreRbp, - (RING3_STACK *)(UINTN)Physical - ); - - CoreFreePages (Physical, EFI_SIZE_TO_PAGES (8 * sizeof (UINTN))); - - return Status; -} diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index df261d82f5..b6273143eb 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -1840,14 +1840,6 @@ EFI_STATUS OUT UINT64 *MaximumVariableSize ); -typedef -EFI_STATUS -(EFIAPI *EFI_SYS_CALL_BOOT_SERVICE)( - IN UINT8 Type, - IN VOID *CoreRbp, - IN VOID *UserRsp - ); - // // Firmware should stop at a firmware user interface on next boot // @@ -2031,7 +2023,6 @@ typedef struct { EFI_COPY_MEM CopyMem; EFI_SET_MEM SetMem; EFI_CREATE_EVENT_EX CreateEventEx; - EFI_SYS_CALL_BOOT_SERVICE SysCallBootService; } EFI_BOOT_SERVICES; typedef enum { From 2c41ed6b5fc08b9054e237207017bdef13af68e4 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 24 May 2024 12:38:24 +0300 Subject: [PATCH 217/341] Ring3: Defined CallInstallMultipleProtocolInterfaces() for AARCH64. --- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index c6cc39d265..8973f9fa33 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -18,6 +18,39 @@ // ); //------------------------------------------------------------------------------ ASM_FUNC(CallInstallMultipleProtocolInterfaces) + stp x29, x30, [sp, #-0x10]! + mov x29, sp + // Save funtion input. + mov x9, x1 + mov x10, x2 + mov x11, x3 + // Prepare registers for call. + ldp x1, x2, [x9] + ldp x3, x4, [x9, #0x10] + ldp x5, x6, [x9, #0x20] + ldr x7, [x9, #0x30] + // Prepare stack for call. + cmp x10, #7 + b.le call + add x9, x9, x10, LSL #3 + sub x10, x10, #7 + tst x10, #1 + b.eq copy + // To align stack on 16 bytes. + add x9, x9, #0x8 + add x10, x10, #1 +copy: + ldp x12, x13, [x9, #-0x10]! + stp x12, x13, [sp, #-0x10]! + subs x10, x10, #2 + b.ne copy + +call: + blr x11 + + mov sp, x29 + ldp x29, x30, [sp] + add sp, sp, #0x10 ret //------------------------------------------------------------------------------ @@ -35,7 +68,7 @@ ASM_FUNC(CallInstallMultipleProtocolInterfaces) //------------------------------------------------------------------------------ ASM_FUNC(ArmCallRing3) // Save FP and LR on Core Stack. - stp x29, x30, [sp, #-0x10]! + stp x29, x30, [sp, #-0x10]! // Disable interrupts msr daifset, #0xf isb From 869e81b2cc1aadd9e934ea9d828de54092d30821 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 27 May 2024 13:16:48 +0300 Subject: [PATCH 218/341] SysCall: Fixed uninitialized variable. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 7a00ec8dea..95364f0e08 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -90,6 +90,7 @@ FindGuid ( OUT UINT32 *CoreSize ) { + ASSERT (Ring3 != NULL); ASSERT (Core != NULL); ASSERT (CoreSize != NULL); @@ -306,6 +307,7 @@ CallBootService ( Argument4 = 0; Argument5 = 0; Argument6 = 0; + Interface = NULL; // // Check User variables. // From 47de6b340740bf4cecbb2af61bbeb23038a89a9f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 27 May 2024 13:18:02 +0300 Subject: [PATCH 219/341] SysCall: Made CoreSp STATIC, fixed UserRsp for AARCH64. --- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 9bed7c8d7d..bfdb466eb7 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -11,7 +11,7 @@ #include "DxeMain.h" -UINTN CoreSp; +STATIC UINTN mCoreSp; EFI_STATUS EFIAPI @@ -30,6 +30,7 @@ ReturnToCore ( IN UINTN CoreSp ); +STATIC EFI_STATUS EFIAPI SysCallBootService ( @@ -42,13 +43,13 @@ SysCallBootService ( EFI_PHYSICAL_ADDRESS Physical; if (Type == SysCallReturnToCore) { - ReturnToCore (*(EFI_STATUS *)CoreRbp, CoreSp); + ReturnToCore (*(EFI_STATUS *)CoreRbp, mCoreSp); } Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (8 * sizeof (UINTN)), + EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), &Physical ); if (EFI_ERROR (Status)) { @@ -56,7 +57,7 @@ SysCallBootService ( } DisableSMAP (); - CopyMem ((VOID *)(UINTN)Physical, (VOID *)UserRsp, 8 * sizeof (UINTN)); + CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)UserRsp, 8 * sizeof (UINTN)); EnableSMAP (); Status = CallBootService ( @@ -65,7 +66,7 @@ SysCallBootService ( (RING3_STACK *)(UINTN)Physical ); - CoreFreePages (Physical, EFI_SIZE_TO_PAGES (8 * sizeof (UINTN))); + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); return Status; } @@ -128,5 +129,5 @@ CallRing3 ( IN RING3_CALL_DATA *Data ) { - return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &CoreSp); + return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp); } From ad5661c67e6d7863d81f453d6edf3dfdfa8b0a57 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 29 May 2024 09:40:29 +0300 Subject: [PATCH 220/341] SysCall: Added sanity checks. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 95364f0e08..eb9c9b0924 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -251,6 +251,7 @@ PrepareRing3Interface ( Unicode->SupportedLanguages ); if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Could not copy string!\n")); return NULL; } @@ -346,9 +347,10 @@ CallBootService ( DisableSMAP (); if (Interface != NULL) { Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); - } + ASSERT (Interface != NULL); - *(VOID **)CoreRbp->Argument3 = Interface; + *(VOID **)CoreRbp->Argument3 = Interface; + } EnableSMAP (); return Status; @@ -558,9 +560,10 @@ CallBootService ( DisableSMAP (); if (Interface != NULL) { Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); - } + ASSERT (Interface != NULL); - *(VOID **)CoreRbp->Argument3 = Interface; + *(VOID **)CoreRbp->Argument3 = Interface; + } EnableSMAP (); return Status; From fa470cdb75a4a49c7d1572bd7d6e4dc287fe6fe1 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 29 May 2024 09:53:49 +0300 Subject: [PATCH 221/341] Ring3: Removed -mcpu=cortex-a76 option from tools_def.template. --- .../Library/ArmLib/AArch64/AArch64Support.S | 10 -------- .../AArch64/DefaultExceptionHandler.c | 6 +++++ BaseTools/Conf/tools_def.template | 4 ++-- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 24 +++++++++++++++++++ .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 12 ++++++++++ MdePkg/Include/AArch64/AArch64.h | 10 -------- 6 files changed, 44 insertions(+), 22 deletions(-) diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S index 2d45b9c733..66daa27fb4 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S @@ -338,16 +338,6 @@ ASM_FUNC(ArmReadCurrentEL) mrs x0, CurrentEL ret -// VOID ArmSetPan(VOID) -ASM_FUNC(ArmSetPan) - msr pan, #1 - ret - -// VOID ArmClearPan(VOID) -ASM_FUNC(ArmClearPan) - msr pan, #0 - ret - // UINT32 ArmReadCntHctl(VOID) ASM_FUNC(ArmReadCntHctl) mrs x0, cnthctl_el2 diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index 5dfcf51cda..9a0a9a83cd 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -53,6 +53,12 @@ GetImageName ( OUT UINTN *DebugBase ); +VOID +EFIAPI +ArmClearPan ( + VOID + ); + STATIC VOID DescribeInstructionOrDataAbort ( diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index a7ecc289ac..d8b544c209 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -969,7 +969,7 @@ DEFINE GCC5_X64_DLINK_FLAGS = DEF(GCC5_IA32_X64_DLINK_FLAGS) -Wl,-melf_ DEFINE GCC5_X64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) -Wno-error DEFINE GCC5_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEFINE GCC5_ARM_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian -march=armv7-a -DEFINE GCC5_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian -mcpu=cortex-a76 +DEFINE GCC5_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) -mlittle-endian DEFINE GCC5_ARM_CC_FLAGS = DEF(GCC_ARM_CC_FLAGS) -mword-relocations DEFINE GCC5_AARCH64_CC_FLAGS = DEF(GCC5_ALL_CC_FLAGS) DEF(GCC_AARCH64_CC_FLAGS) -mcmodel=small DEFINE GCC5_ARM_DLINK_FLAGS = DEF(GCC_ARM_DLINK_FLAGS) -Wl,--oformat=elf32-littlearm @@ -1471,7 +1471,7 @@ DEFINE CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_ *_CLANGDWARF_AARCH64_ASLCC_FLAGS = DEF(GCC_ASLCC_FLAGS) -fno-lto *_CLANGDWARF_AARCH64_ASLDLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_ASLDLINK_FLAGS) -fuse-ld=lld -*_CLANGDWARF_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) -Qunused-arguments -mcpu=cortex-a76 +*_CLANGDWARF_AARCH64_ASM_FLAGS = DEF(GCC_ASM_FLAGS) DEF(CLANGDWARF_AARCH64_TARGET) -Qunused-arguments *_CLANGDWARF_AARCH64_DLINK_FLAGS = DEF(CLANGDWARF_AARCH64_TARGET) DEF(GCC_AARCH64_DLINK_FLAGS) DEF(GCC_ALIGN) *_CLANGDWARF_AARCH64_DLINK_SECPEIFLAGS = DEF(GCC_ALIGN) *_CLANGDWARF_AARCH64_DLINK2_FLAGS = DEF(GCC_DLINK2_FLAGS_COMMON) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 8973f9fa33..f570b318e6 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -7,6 +7,8 @@ #include +.cpu cortex-a76 + //------------------------------------------------------------------------------ // EFI_STATUS // EFIAPI @@ -114,3 +116,25 @@ ASM_FUNC(ReturnToCore) ldp x29, x30, [sp] add sp, sp, #0x10 ret + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ArmSetPan ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ArmSetPan) + msr pan, #1 + ret + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ArmClearPan ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ArmClearPan) + msr pan, #0 + ret diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index bfdb466eb7..88b06ac53a 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -30,6 +30,18 @@ ReturnToCore ( IN UINTN CoreSp ); +VOID +EFIAPI +ArmSetPan ( + VOID + ); + +VOID +EFIAPI +ArmClearPan ( + VOID + ); + STATIC EFI_STATUS EFIAPI diff --git a/MdePkg/Include/AArch64/AArch64.h b/MdePkg/Include/AArch64/AArch64.h index 55d7ef15f1..c30282defa 100644 --- a/MdePkg/Include/AArch64/AArch64.h +++ b/MdePkg/Include/AArch64/AArch64.h @@ -243,16 +243,6 @@ ArmReadCurrentEL ( VOID ); -VOID -ArmSetPan ( - VOID - ); - -VOID -ArmClearPan ( - VOID - ); - UINTN ArmWriteCptr ( IN UINT64 Cptr From 214bb904dda4680859da4da2fca7b0de7b97d2da Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 29 May 2024 14:24:52 +0300 Subject: [PATCH 222/341] SysCall: Fixed random crashes of QEMU. --- MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index f570b318e6..e0a27b930e 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -112,6 +112,9 @@ ASM_FUNC(ArmCallRing3) ASM_FUNC(ReturnToCore) // Switch to Core Stack. mov sp, x1 + // Zero Exception Syndrome Register to prevent QEMU from random crashing. + mov x1, #0 + msr esr_el1, x1 // Restore Stack. ldp x29, x30, [sp] add sp, sp, #0x10 From 55c1e40fc5a85faa087aaa46259062d2f4f76fd9 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 29 May 2024 14:35:33 +0300 Subject: [PATCH 223/341] SysCall/AARCH64: Enabled interrupts. --- .../Core/Dxe/SysCall/AARCH64/CoreBootServices.S | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index e0a27b930e..7c56d717f8 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -71,7 +71,7 @@ call: ASM_FUNC(ArmCallRing3) // Save FP and LR on Core Stack. stp x29, x30, [sp, #-0x10]! - // Disable interrupts + // Disable interrupts. msr daifset, #0xf isb // Prepare Ring3 SP and EntryPoint. @@ -81,13 +81,10 @@ ASM_FUNC(ArmCallRing3) mov x5, sp str x5, [x4] mov sp, x3 - // Copy PSTATE to SPSR. mrs x1, nzcv mrs x2, pan orr x1, x1, x2 - mrs x2, daif - orr x1, x1, x2 // // M[3:0], bits [3:0] AArch64 Exception level and selected Stack Pointer. // 0b0000 - EL0. @@ -95,10 +92,8 @@ ASM_FUNC(ArmCallRing3) // 0b0101 - EL1 with SP_EL1 (EL1h). // msr spsr_el1, x1 - isb - dsb sy - + dsb sy eret //------------------------------------------------------------------------------ @@ -110,14 +105,16 @@ ASM_FUNC(ArmCallRing3) // ); //------------------------------------------------------------------------------ ASM_FUNC(ReturnToCore) + // Zero Exception Syndrome Register to prevent QEMU from random crashing. + msr esr_el1, xzr // Switch to Core Stack. mov sp, x1 - // Zero Exception Syndrome Register to prevent QEMU from random crashing. - mov x1, #0 - msr esr_el1, x1 // Restore Stack. ldp x29, x30, [sp] add sp, sp, #0x10 + // Enable interrupts. + msr daifclr, #0xf + isb ret //------------------------------------------------------------------------------ From 12ce05f26c9239ccf41f8a47dfc73ec673a3570f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 29 May 2024 14:55:26 +0300 Subject: [PATCH 224/341] SysCall/AARCH64: Increased probability of QEMU's normal work. --- MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 7c56d717f8..068db95b1d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -107,6 +107,9 @@ ASM_FUNC(ArmCallRing3) ASM_FUNC(ReturnToCore) // Zero Exception Syndrome Register to prevent QEMU from random crashing. msr esr_el1, xzr + msr spsr_el1, xzr + msr elr_el1, xzr + msr far_el1, xzr // Switch to Core Stack. mov sp, x1 // Restore Stack. From 0bf4f0c3cd3829dc8698f3061f700a563d5d55dc Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 4 Jun 2024 13:48:37 +0300 Subject: [PATCH 225/341] Ring3: Summarized all known problems for AARCH64. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 3 +- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 36 ++++++++-- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 68 ++++++++++++++++++- .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 3 +- .../Core/Dxe/SysCall/IA32/InitializeMsr.c | 3 +- .../Core/Dxe/SysCall/Initialization.c | 8 ++- .../Core/Dxe/SysCall/SupportedProtocols.c | 29 +++++++- .../Core/Dxe/SysCall/X64/InitializeMsr.c | 3 +- 8 files changed, 139 insertions(+), 14 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 7623b10e62..ac0b0f84dc 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -92,7 +92,8 @@ UefiCpuPkg/UefiCpuPkg.dec OvmfPkg/OvmfPkg.dec ArmPkg/ArmPkg.dec - + ArmVirtPkg/ArmVirtPkg.dec + [LibraryClasses] BaseMemoryLib CacheMaintenanceLib diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 068db95b1d..2b0f498d87 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -69,8 +69,22 @@ call: // (x4) &CoreSp //------------------------------------------------------------------------------ ASM_FUNC(ArmCallRing3) - // Save FP and LR on Core Stack. - stp x29, x30, [sp, #-0x10]! + // Save registers. + sub sp, sp, #0x100 + + stp q8, q9, [sp, #0xe0] + stp q10, q11, [sp, #0xc0] + stp q12, q13, [sp, #0xa0] + stp q14, q15, [sp, #0x80] + + stp xzr, x16, [sp, #0x70] + stp x17, x18, [sp, #0x60] + stp x19, x20, [sp, #0x50] + stp x21, x22, [sp, #0x40] + stp x23, x24, [sp, #0x30] + stp x25, x26, [sp, #0x20] + stp x27, x28, [sp, #0x10] + stp x29, x30, [sp] // Disable interrupts. msr daifset, #0xf isb @@ -112,9 +126,21 @@ ASM_FUNC(ReturnToCore) msr far_el1, xzr // Switch to Core Stack. mov sp, x1 - // Restore Stack. - ldp x29, x30, [sp] - add sp, sp, #0x10 + // Restore registers and Stack. + ldp q8, q9, [sp, #0xe0] + ldp q10, q11, [sp, #0xc0] + ldp q12, q13, [sp, #0xa0] + ldp q14, q15, [sp, #0x80] + + ldr x16, [sp, #0x78] + ldp x17, x18, [sp, #0x60] + ldp x19, x20, [sp, #0x50] + ldp x21, x22, [sp, #0x40] + ldp x23, x24, [sp, #0x30] + ldp x25, x26, [sp, #0x20] + ldp x27, x28, [sp, #0x10] + ldp x29, x30, [sp] + add sp, sp, #0x100 // Enable interrupts. msr daifclr, #0xf isb diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 88b06ac53a..ab2f1b536b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -6,12 +6,14 @@ **/ #include +#include #include #include #include "DxeMain.h" STATIC UINTN mCoreSp; +UINTN gUartBaseAddress; EFI_STATUS EFIAPI @@ -70,6 +72,12 @@ SysCallBootService ( DisableSMAP (); CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)UserRsp, 8 * sizeof (UINTN)); + + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP + ); EnableSMAP (); Status = CallBootService ( @@ -78,6 +86,12 @@ SysCallBootService ( (RING3_STACK *)(UINTN)Physical ); + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); return Status; @@ -86,10 +100,17 @@ SysCallBootService ( VOID EFIAPI InitializeMsr ( - VOID + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries ) { - UINTN Tcr; + UINTN Tcr; + UINTN Index; + EARLY_PL011_BASE_ADDRESS *UartBase; + EFI_PHYSICAL_ADDRESS Physical; + EFI_HOB_GENERIC_HEADER *Ring3Hob; + UINT16 HobLength; + EFI_STATUS Status; // // If HCR_EL2.NV is 1 and the current Exception level is EL1, // then EL1 read accesses to the CurrentEL register return a value of 0x2 in bits[3:2]. @@ -103,6 +124,49 @@ InitializeMsr ( Tcr = ArmGetTCR (); Tcr |= TCR_EL1_HPD0_MASK | TCR_EL1_HPD1_MASK; ArmSetTCR (Tcr); + // + // Problem 1: Uart is memory maped. + // + for (Index = 0; Index < NumberOfEntries; ++Index) { + if (CompareGuid (&gEfiHobListGuid, &(Table[Index].VendorGuid))) { + UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); + gUartBaseAddress = UartBase->DebugAddress; + // + // Copy Hob into Ring3. + // + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + 1, + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Hob.\n")); + ASSERT (FALSE); + } + DEBUG ((DEBUG_ERROR, "UartBaseAddress = %p.\n", gUartBaseAddress)); + + Ring3Hob = (EFI_HOB_GENERIC_HEADER *)(UINTN)Physical; + + HobLength = (UINT16)((sizeof (EFI_HOB_GUID_TYPE) + sizeof (EARLY_PL011_BASE_ADDRESS) + 0x7) & (~0x7)); + + Ring3Hob->HobType = EFI_HOB_TYPE_GUID_EXTENSION; + Ring3Hob->HobLength = HobLength; + Ring3Hob->Reserved = 0; + + CopyGuid (&((EFI_HOB_GUID_TYPE *)Ring3Hob)->Name, &gEarlyPL011BaseAddressGuid); + + Ring3Hob = (EFI_HOB_GENERIC_HEADER *)((UINTN)Ring3Hob + HobLength); + + Ring3Hob->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; + Ring3Hob->HobLength = sizeof (EFI_HOB_GENERIC_HEADER); + Ring3Hob->Reserved = 0; + + Table[Index].VendorTable = (VOID *)(UINTN)Physical; + UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); + UartBase->DebugAddress = gUartBaseAddress; + } + } if (ArmHasPan ()) { // diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index bc844910fd..fb7c2c35b6 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -10,7 +10,8 @@ VOID EFIAPI InitializeMsr ( - VOID + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries ) { diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c index 8c1859163e..e08d97a336 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c @@ -12,7 +12,8 @@ VOID EFIAPI InitializeMsr ( - VOID + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries ) { UINT64 Msr; diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 58651a4963..facc9d543d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -18,7 +18,8 @@ VOID *gRing3Interfaces; VOID EFIAPI InitializeMsr ( - VOID + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries ); EFI_STATUS @@ -141,7 +142,10 @@ InitializeRing3 ( SetUefiImageMemoryAttributes ((UINTN)gRing3CallStackBase, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); - InitializeMsr (); + InitializeMsr ( + gRing3Data->SystemTable.ConfigurationTable, + gRing3Data->SystemTable.NumberOfTableEntries + ); return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 90fd9761a1..852ec7c663 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -13,6 +13,10 @@ EFI_FILE_PROTOCOL mRing3FileProtocol; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; +#if defined (MDE_CPU_AARCH64) +extern UINTN gUartBaseAddress; +#endif + typedef struct { EFI_FILE_PROTOCOL Protocol; EFI_FILE_PROTOCOL *Ring3File; @@ -69,8 +73,16 @@ GoToRing3 ( EFI_MEMORY_XP | EFI_MEMORY_USER ); } +#elif defined (MDE_CPU_AARCH64) + // + // Necessary fix for DEBUG printings. + // + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); #endif - Status = CallRing3 (Input); #if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) @@ -81,6 +93,21 @@ GoToRing3 ( EFI_MEMORY_XP ); } +#elif defined (MDE_CPU_AARCH64) + // + // Problem 2: Uart memory maped page is not allocated at the very beginnig + // and can be used for translation table later. + // + DisableSMAP (); + // + // Problem 3: QEMU ramdomly breaks GP registers' context. + // + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP + ); + EnableSMAP (); #endif CoreFreePages (Ring3Pages, PagesNumber); diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c index 171fdc5e7d..fded58d6fa 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c @@ -12,7 +12,8 @@ VOID EFIAPI InitializeMsr ( - VOID + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries ) { UINT64 Msr; From 432b45f8e27d0a2cb66472c0e33bd89439887a7a Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 4 Jul 2024 17:21:51 +0300 Subject: [PATCH 226/341] Ring3: Added PAN support for ARM. --- ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S | 4 ++ ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c | 15 +++++++ ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h | 10 +++++ .../Arm/DefaultExceptionHandler.c | 5 ++- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 42 ++++++++++--------- .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 40 ++++++++++++++++++ MdePkg/Include/Arm/AArch32.h | 3 ++ MdePkg/Include/Library/ArmLib.h | 24 +++++------ 8 files changed, 111 insertions(+), 32 deletions(-) diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S index d207876a21..e0115b6e6a 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S +++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupportV7.S @@ -64,6 +64,10 @@ ASM_FUNC(ArmReadIdMmfr4) mrc p15,0,r0,c0,c2,6 @ Read ID_MMFR4 Register bx lr +ASM_FUNC(ArmReadIdMmfr3) + mrc p15,0,r0,c0,c1,7 @ Read ID_MMFR3 Register + bx lr + // UINTN // ReadCCSIDR ( // IN UINT32 CSSELR diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c index dd1e8c5930..9d32d95fba 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c +++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.c @@ -64,3 +64,18 @@ ArmHasCcidx ( Mmfr4 = ArmReadIdMmfr4 (); return (((Mmfr4 >> 24) & 0xF) == 1) ? TRUE : FALSE; } + +/** + Checks whether the CPU implements the Privileged Access Never. + + @retval TRUE FEAT_PAN is implemented. + @retval FALSE FEAT_PAN is not mplemented. +**/ +BOOLEAN +EFIAPI +ArmHasPan ( + VOID + ) +{ + return ((ArmReadIdMmfr3 () & ARM_MMFR3_PAN) != 0); +} diff --git a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h index 548be5cf28..23fd59c43b 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h +++ b/ArmPkg/Library/ArmLib/Arm/ArmV7Lib.h @@ -33,6 +33,16 @@ ArmReadIdMmfr4 ( VOID ); +/** Reads the ID_MMFR3 register. + + @return The contents of the ID_MMFR3 register. +**/ +UINT32 +EFIAPI +ArmReadIdMmfr3 ( + VOID + ); + UINTN EFIAPI ArmReadIdPfr1 ( diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c index eb9b4ee7b7..4f8b23f653 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c @@ -196,7 +196,8 @@ STATIC CHAR8 *gExceptionTypeString[] = { **/ -VOID +EFI_STATUS +EFIAPI DefaultExceptionHandler ( IN EFI_EXCEPTION_TYPE ExceptionType, IN OUT EFI_SYSTEM_CONTEXT SystemContext @@ -287,4 +288,6 @@ DefaultExceptionHandler ( // Clear the error registers that we have already displayed incase some one wants to keep going SystemContext.SystemContextArm->DFSR = 0; SystemContext.SystemContextArm->IFSR = 0; + + return EFI_SUCCESS; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 406a7f66cf..90b000fc0d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -7,25 +7,7 @@ #include -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// DisableSMAP ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(DisableSMAP) - bx LR - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// EnableSMAP ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(EnableSMAP) - bx LR +.arch armv8.1a //------------------------------------------------------------------------------ // EFI_STATUS @@ -71,3 +53,25 @@ ASM_FUNC(CoreBootServices) //------------------------------------------------------------------------------ ASM_FUNC(CallRing3) bx LR + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ArmSetPan ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ArmSetPan) + setpan #1 + bx LR + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ArmClearPan ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ArmClearPan) + setpan #0 + bx LR diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index fb7c2c35b6..02845996d9 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -5,8 +5,22 @@ **/ +#include + #include "DxeMain.h" +VOID +EFIAPI +ArmSetPan ( + VOID + ); + +VOID +EFIAPI +ArmClearPan ( + VOID + ); + VOID EFIAPI InitializeMsr ( @@ -14,5 +28,31 @@ InitializeMsr ( IN UINTN NumberOfEntries ) { + if (ArmHasPan ()) { + // + // Enable Privileged Access Never feature. + // + ArmSetPan (); + } else { + DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n")); + ASSERT (FALSE); + } +} + +VOID +EFIAPI +DisableSMAP ( + VOID + ) +{ + ArmClearPan (); +} +VOID +EFIAPI +EnableSMAP ( + VOID + ) +{ + ArmSetPan (); } diff --git a/MdePkg/Include/Arm/AArch32.h b/MdePkg/Include/Arm/AArch32.h index e7e6e4dcd0..584705ec54 100644 --- a/MdePkg/Include/Arm/AArch32.h +++ b/MdePkg/Include/Arm/AArch32.h @@ -20,6 +20,9 @@ #define ARM_PFR1_TIMER (0xFUL << 16) #define ARM_PFR1_GIC (0xFUL << 28) +// ID_MMFR3 - ARM Memory Model Feature Register 3 definitions +#define ARM_MMFR3_PAN (0xFUL << 16) + // Domain Access Control Register #define DOMAIN_ACCESS_CONTROL_MASK(a) (3UL << (2 * (a))) #define DOMAIN_ACCESS_CONTROL_NONE(a) (0UL << (2 * (a))) diff --git a/MdePkg/Include/Library/ArmLib.h b/MdePkg/Include/Library/ArmLib.h index 7b5fb28205..a7f89e23b5 100644 --- a/MdePkg/Include/Library/ArmLib.h +++ b/MdePkg/Include/Library/ArmLib.h @@ -710,6 +710,18 @@ ArmHasCcidx ( VOID ); +/** + Checks whether the CPU implements the Privileged Access Never. + + @retval TRUE FEAT_PAN is implemented. + @retval FALSE FEAT_PAN is not mplemented. +**/ +BOOLEAN +EFIAPI +ArmHasPan ( + VOID + ); + #ifdef MDE_CPU_AARCH64 /// /// AArch64-only ID Register Helper functions @@ -727,18 +739,6 @@ ArmHasVhe ( VOID ); -/** - Checks whether the CPU implements the Privileged Access Never. - - @retval TRUE FEAT_PAN is implemented. - @retval FALSE FEAT_PAN is not mplemented. -**/ -BOOLEAN -EFIAPI -ArmHasPan ( - VOID - ); - /** Checks whether the CPU implements the Trace Buffer Extension. From feb9024ef7f524d7e88cd59432be5ce14fa19748 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 4 Jul 2024 17:22:39 +0300 Subject: [PATCH 227/341] Ring3: Added EL0 support for ARM. --- .../Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c | 17 ++++++++++--- ArmPkg/Library/CpuArchLib/Arm/Mmu.c | 24 +++++++++++++++---- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c index b8b8a7016d..0410883a90 100644 --- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c +++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c @@ -142,10 +142,21 @@ UpdatePageEntries ( EntryValue |= TT_DESCRIPTOR_PAGE_AF; } - if ((Attributes & EFI_MEMORY_RO) != 0) { - EntryValue |= TT_DESCRIPTOR_PAGE_AP_RO_RO; + if ((Attributes & EFI_MEMORY_USER) != 0) { + // + // TODO: Add PXN for Translation table descriptors. + // + if ((Attributes & EFI_MEMORY_RO) != 0) { + EntryValue |= TT_DESCRIPTOR_PAGE_AP_RO_RO; + } else { + EntryValue |= TT_DESCRIPTOR_PAGE_AP_RW_RW; + } } else { - EntryValue |= TT_DESCRIPTOR_PAGE_AP_RW_RW; + if ((Attributes & EFI_MEMORY_RO) != 0) { + EntryValue |= TT_DESCRIPTOR_PAGE_AP_NO_RO; + } else { + EntryValue |= TT_DESCRIPTOR_PAGE_AP_NO_RW; + } } if ((Attributes & EFI_MEMORY_XP) != 0) { diff --git a/ArmPkg/Library/CpuArchLib/Arm/Mmu.c b/ArmPkg/Library/CpuArchLib/Arm/Mmu.c index 8c4de284e1..86c375075a 100644 --- a/ArmPkg/Library/CpuArchLib/Arm/Mmu.c +++ b/ArmPkg/Library/CpuArchLib/Arm/Mmu.c @@ -63,15 +63,18 @@ SectionToGcdAttributes ( // determine protection attributes switch (SectionAttributes & TT_DESCRIPTOR_SECTION_AP_MASK) { case TT_DESCRIPTOR_SECTION_AP_NO_RW: + break; case TT_DESCRIPTOR_SECTION_AP_RW_RW: - // normal read/write access, do not add additional attributes + *GcdAttributes |= EFI_MEMORY_USER; break; // read only cases map to write-protect case TT_DESCRIPTOR_SECTION_AP_NO_RO: - case TT_DESCRIPTOR_SECTION_AP_RO_RO: *GcdAttributes |= EFI_MEMORY_RO; break; + case TT_DESCRIPTOR_SECTION_AP_RO_RO: + *GcdAttributes |= EFI_MEMORY_USER | EFI_MEMORY_RO; + break; } // now process eXectue Never attribute @@ -468,10 +471,21 @@ EfiAttributeToArmAttribute ( } // Determine protection attributes - if ((EfiAttributes & EFI_MEMORY_RO) != 0) { - ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RO_RO; + if ((EfiAttributes & EFI_MEMORY_USER) != 0) { + // + // TODO: Add PXN for Translation table descriptors. + // + if ((EfiAttributes & EFI_MEMORY_RO) != 0) { + ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RO_RO; + } else { + ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RW_RW; + } } else { - ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RW_RW; + if ((EfiAttributes & EFI_MEMORY_RO) != 0) { + ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_NO_RO; + } else { + ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_NO_RW; + } } // Determine eXecute Never attribute From 39aac5595d1fac9b201269d806be840f826e2320 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 5 Jul 2024 16:14:21 +0300 Subject: [PATCH 228/341] Ring3: Defined CallRing3() for ARM. --- MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S | 12 +++--- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 2 +- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 41 +++++++++++++++++-- .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 31 ++++++++++++-- 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S index dd9d6d8721..25fcc31ab2 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S @@ -5,6 +5,8 @@ #include +.extern ASM_PFX(Ring3Call) + //------------------------------------------------------------------------------ // EFI_STATUS // EFIAPI @@ -14,8 +16,8 @@ // ); //------------------------------------------------------------------------------ ASM_FUNC(SysCall) - - bx LR + svc #0 + bx LR //------------------------------------------------------------------------------ // VOID @@ -24,9 +26,7 @@ ASM_FUNC(SysCall) // IN RING3_CALL_DATA *Data // ); // -// (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3(). -// (rdx) Data +// (r0) Data //------------------------------------------------------------------------------ ASM_FUNC(Ring3EntryPoint) - - bx LR + b ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 2b0f498d87..2174d0dbba 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -91,7 +91,7 @@ ASM_FUNC(ArmCallRing3) // Prepare Ring3 SP and EntryPoint. msr sp_el0, x1 msr elr_el1, x2 - // Save Core SP and switch to Ring3Call Stack. + // Save Core SP and switch to CoreSysCall Stack. mov x5, sp str x5, [x4] mov sp, x3 diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 90b000fc0d..cdbbacf501 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -49,10 +49,45 @@ ASM_FUNC(CoreBootServices) // IN RING3_CALL_DATA *Data // ); // -// (rcx) Data +// (r0) Data +// (r1) gRing3CallStackTop +// (r2) gRing3EntryPoint +// (r3) gCoreSysCallStackTop +// +// (On Core Stack) &CoreSp //------------------------------------------------------------------------------ -ASM_FUNC(CallRing3) - bx LR +ASM_FUNC(ArmCallRing3) + // Save registers. + push {R4-R12, LR} + // R6 is &CoreSp + ldr R6, [SP, #0x28] + +#if (FixedPcdGet32(PcdVFPEnabled)) + // Save vstm registers in case they are used in optimizations. + vpush {d0-d15} +#endif + + // Disable interrupts. + mrs R4, CPSR + orr R5, R4, #0x80 + msr CPSR_c, R5 + + // Set SP_usr to gRing3CallStackTop. + push {R1} + mov R1, SP + ldmia R1, {SP}^ + pop {R1} + // Set SPSR M[3:0] bits to User mode. + and R4, R4, #0xFFFFFFF0 + + // Save Core SP and switch to CoreSysCall Stack. + mov R5, SP + str R5, [R6] + mov SP, R3 + + push {R4} + push {R2} + rfefd SP //------------------------------------------------------------------------------ // VOID diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index 02845996d9..adf5509d06 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -9,6 +9,18 @@ #include "DxeMain.h" +STATIC UINTN mCoreSp; + +EFI_STATUS +EFIAPI +ArmCallRing3 ( + IN RING3_CALL_DATA *Data, + IN VOID *StackPointer, + IN VOID *EntryPoint, + IN VOID *SysCallStack, + IN VOID *CoreStack + ); + VOID EFIAPI ArmSetPan ( @@ -35,7 +47,7 @@ InitializeMsr ( ArmSetPan (); } else { DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n")); - ASSERT (FALSE); + // ASSERT (FALSE); } } @@ -45,7 +57,9 @@ DisableSMAP ( VOID ) { - ArmClearPan (); + if (ArmHasPan ()) { + ArmClearPan (); + } } VOID @@ -54,5 +68,16 @@ EnableSMAP ( VOID ) { - ArmSetPan (); + if (ArmHasPan ()) { + ArmSetPan (); + } +} + +EFI_STATUS +EFIAPI +CallRing3 ( + IN RING3_CALL_DATA *Data + ) +{ + return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp); } From 930e0f12be99614ebf32d8f47b72df9e59b6f3e7 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 9 Jul 2024 11:40:26 +0300 Subject: [PATCH 229/341] Ring3: Defined SysCallBootService() for ARM. --- .../Library/DefaultExceptionHandlerLib.h | 10 +++- .../ArmExceptionLib/Arm/ExceptionSupport.S | 31 +++++------- .../AArch64/DefaultExceptionHandler.c | 13 ++--- .../Arm/DefaultExceptionHandler.c | 19 ++++++++ .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 20 -------- .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 47 +++++++++++++++++++ 6 files changed, 90 insertions(+), 50 deletions(-) diff --git a/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h b/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h index 1381cb4f6d..24893c6fa8 100644 --- a/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h +++ b/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h @@ -9,6 +9,14 @@ #ifndef DEFAULT_EXCEPTION_HANDLER_LIB_H_ #define DEFAULT_EXCEPTION_HANDLER_LIB_H_ +typedef +EFI_STATUS +(EFIAPI *EFI_SYS_CALL_BOOT_SERVICE)( + IN UINT8 Type, + IN VOID *CoreRbp, + IN VOID *UserRsp + ); + /** This is the default action to take on an unexpected exception @@ -26,7 +34,7 @@ DefaultExceptionHandler ( VOID EFIAPI InitializeSysCallHandler ( - IN VOID *Handler + IN EFI_SYS_CALL_BOOT_SERVICE Handler ); #endif // DEFAULT_EXCEPTION_HANDLER_LIB_H_ diff --git a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S index d9ad775934..5d2a5617f8 100644 --- a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S @@ -220,8 +220,12 @@ ASM_PFX(AsmCommonExceptionEntry): cmp R3, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f)) cmpne R3, #0x10 @ stmdaeq R2, {lr}^ @ save unbanked lr + addeq R2, SP, #0x34 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.SP + stmdaeq R2, {sp}^ @ save unbanked sp @ else stmdane R2, {lr} @ save SVC lr + addne R1, SP, #0x60 @ We pushed 0x60 bytes on the stack + strne R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd @@ -230,6 +234,7 @@ ASM_PFX(AsmCommonExceptionEntry): cmp r4, #1 @ // UND & SVC have different LR adjust for Thumb bhi NoAdjustNeeded + ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry addne R5, R5, #2 @ PC += 2; strne R5,[SP,#0x58] @ Update LR value pushed by srsfd @@ -238,9 +243,6 @@ NoAdjustNeeded: str R5, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC - add R1, SP, #0x60 @ We pushed 0x60 bytes on the stack - str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP - @ R0 is ExceptionType mov R1,SP @ R1 is SystemContext @@ -253,7 +255,7 @@ NoAdjustNeeded: subne SP, SP, #4 @ Adjust SP if not 8-byte aligned /* -VOID +EFI_STATUS EFIAPI CommonCExceptionHandler ( IN EFI_EXCEPTION_TYPE ExceptionType, R0 @@ -261,6 +263,8 @@ CommonCExceptionHandler ( ) */ + mov R5, R0 @ R5 is ExceptionType + blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler mov SP, R4 @ Restore SP @@ -275,25 +279,14 @@ CommonCExceptionHandler ( ldr R1, [SP, #0x44] @ Restore EFI_SYSTEM_CONTEXT_ARM.DFSR mcr p15, 0, R1, c5, c0, 0 @ Write DFSR - ldr R1,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC - str R1,[SP,#0x58] @ Store it back to srsfd stack slot so it can be restored - - ldr R1,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR - str R1,[SP,#0x5c] @ Store it back to srsfd stack slot so it can be restored - - add R3, SP, #0x54 @ Make R3 point to SVC LR saved on entry - add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR - and R1, R1, #0x1f @ Check to see if User or System Mode - cmp R1, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f)) - cmpne R1, #0x10 @ - ldmibeq R2, {lr}^ @ restore unbanked lr + cmp R5, #2 @ if (ExceptionType == SoftwareInterrupt) + addeq SP, SP, #0x4 @ Preserve EFI_STATUS return result in R0. + ldmfdeq SP!, {R1-R12} @ @ else - ldmibne R3, {lr} @ restore SVC lr, via ldmfd SP!, {LR} + ldmfdne SP!, {R0-R12} @ Restore general purpose registers - ldmfd SP!,{R0-R12} @ Restore general purpose registers @ Exception handler can not change SP add SP,SP,#0x20 @ Clear out the remaining stack space ldmfd SP!,{LR} @ restore the link register for this context rfefd SP! @ return from exception via srsfd stack slot - diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index 9a0a9a83cd..2c47a5f2f0 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -21,6 +21,7 @@ #include #include #include +#include // // Maximum number of characters to print to serial (UINT8s) and to console if @@ -28,14 +29,6 @@ // #define MAX_PRINT_CHARS 100 -typedef -EFI_STATUS -(EFIAPI *EFI_SYS_CALL_BOOT_SERVICE)( - IN UINT8 Type, - IN VOID *CoreRbp, - IN VOID *UserRsp - ); - STATIC CHAR8 *gExceptionTypeString[] = { "Synchronous", "IRQ", @@ -194,10 +187,10 @@ BaseName ( VOID EFIAPI InitializeSysCallHandler ( - IN VOID *Handler + IN EFI_SYS_CALL_BOOT_SERVICE Handler ) { - mSysCallHandler = (EFI_SYS_CALL_BOOT_SERVICE)Handler; + mSysCallHandler = Handler; } /** diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c index 4f8b23f653..077c01bb38 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c @@ -38,6 +38,8 @@ typedef struct { CHAR8 Char; } CPSR_CHAR; +STATIC EFI_SYS_CALL_BOOT_SERVICE mSysCallHandler; + STATIC CONST CPSR_CHAR mCpsrChar[] = { { 31, 'n' }, { 30, 'z' }, @@ -186,6 +188,15 @@ STATIC CHAR8 *gExceptionTypeString[] = { "FIQ" }; +VOID +EFIAPI +InitializeSysCallHandler ( + IN EFI_SYS_CALL_BOOT_SERVICE Handler + ) +{ + mSysCallHandler = Handler; +} + /** This is the default action to take on an unexpected exception @@ -210,6 +221,14 @@ DefaultExceptionHandler ( UINT32 IfsrStatus; BOOLEAN DfsrWrite; + if (ExceptionType == EXCEPT_ARM_SOFTWARE_INTERRUPT) { + return mSysCallHandler ( + SystemContext.SystemContextArm->R0, + &(SystemContext.SystemContextArm->R1), + &(SystemContext.SystemContextArm->SP) + ); + } + CharCount = AsciiSPrint ( Buffer, sizeof (Buffer), diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index cdbbacf501..718812ad43 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -22,26 +22,6 @@ ASM_FUNC(CallInstallMultipleProtocolInterfaces) bx LR -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// CoreBootServices ( -// IN UINT8 Type, -// ... -// ); -// -// (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). -// (rdx) Argument 1 of the called function. -// (r8) Argument 2 of the called function. -// (r9) Argument 3 of the called function. -// (r10) Type. -// (r11) RFLAGS saved by SYSCALL in SysCall(). -// -// (On User Stack) Argument 4, 5, ... -//------------------------------------------------------------------------------ -ASM_FUNC(CoreBootServices) - bx LR - //------------------------------------------------------------------------------ // EFI_STATUS // EFIAPI diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index adf5509d06..f07ba49e2c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -6,6 +6,7 @@ **/ #include +#include #include "DxeMain.h" @@ -33,6 +34,50 @@ ArmClearPan ( VOID ); +STATIC +EFI_STATUS +EFIAPI +SysCallBootService ( + IN UINT8 Type, + IN VOID *CoreRbp, + IN VOID *UserRsp + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Physical; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), + &Physical + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DisableSMAP (); + // + // First 3 arguments are passed through R1-R3 and copied to SysCall Stack. + // + CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)CoreRbp, 3 * sizeof (UINTN)); + // + // All remaining arguments are on User Stack. + // + CopyMem ((VOID *)((UINTN)Physical + 4 * sizeof (UINTN)), (VOID *)UserRsp, 5 * sizeof (UINTN)); + EnableSMAP (); + + Status = CallBootService ( + Type, + (CORE_STACK *)CoreRbp, + (RING3_STACK *)(UINTN)Physical + ); + + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); + + return Status; +} + VOID EFIAPI InitializeMsr ( @@ -49,6 +94,8 @@ InitializeMsr ( DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n")); // ASSERT (FALSE); } + + InitializeSysCallHandler (SysCallBootService); } VOID From 21b70cd6168e192695443375407c7e887c007d34 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 9 Jul 2024 11:47:24 +0300 Subject: [PATCH 230/341] Ring3: Defined CallInstallMultipleProtocolInterfaces() for ARM. --- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 718812ad43..60df4c47e5 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -20,7 +20,38 @@ // ); //------------------------------------------------------------------------------ ASM_FUNC(CallInstallMultipleProtocolInterfaces) - bx LR + push {R4-R8, LR} + mov R7, SP + // Save function input. + mov R4, R3 + mov R5, R1 + mov R6, R2 + // Prepare registers for call. + ldmfd R5, {R1-R3} + // Prepare stack for call. + cmp R6, #3 + ble call + + add R5, R5, R6, LSL #2 + sub R6, R6, #3 + tst R6, #1 + beq copy + // To align stack on 8 bytes. + add R5, R5, #0x4 + add R6, R6, #1 +copy: + sub R5, R5, #0x4 + ldmfd R5, {R8} + push {R8} + subs R6, R6, #1 + bne copy + +call: + blx R4 + + mov SP, R7 + pop {R4-R8, LR} + bx LR //------------------------------------------------------------------------------ // EFI_STATUS From 9be149a5e26b6f0f22e7195fe4d4988aca4dd435 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 9 Jul 2024 11:48:23 +0300 Subject: [PATCH 231/341] SysCall: Fixed typos. --- MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S | 2 +- MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 2174d0dbba..0e705ddbce 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -22,7 +22,7 @@ ASM_FUNC(CallInstallMultipleProtocolInterfaces) stp x29, x30, [sp, #-0x10]! mov x29, sp - // Save funtion input. + // Save function input. mov x9, x1 mov x10, x2 mov x11, x3 diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 4d14d81d74..555387bba7 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -61,7 +61,7 @@ global ASM_PFX(CallInstallMultipleProtocolInterfaces) ASM_PFX(CallInstallMultipleProtocolInterfaces): push r12 - ; Save funtion input. + ; Save function input. mov rax, rdx mov r10, r8 mov r11, r9 From d28f9b4a17101788cd62779901c3290a5aa362b6 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 9 Jul 2024 14:03:39 +0300 Subject: [PATCH 232/341] Ring3: Defined ReturnToCore() for ARM. --- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 29 +++++++++++++++++-- .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 11 +++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 60df4c47e5..0804cf453f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -80,8 +80,8 @@ ASM_FUNC(ArmCallRing3) // Disable interrupts. mrs R4, CPSR - orr R5, R4, #0x80 - msr CPSR_c, R5 + cpsid if + isb // Set SP_usr to gRing3CallStackTop. push {R1} @@ -100,6 +100,31 @@ ASM_FUNC(ArmCallRing3) push {R2} rfefd SP +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ReturnToCore ( +// IN EFI_STATUS Status, +// IN UINTN CoreSp +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ReturnToCore) + // Switch to Core Stack. + mov SP, R1 + + // Restore registers and Stack. +#if (FixedPcdGet32(PcdVFPEnabled)) + vpop {d0-d15} +#endif + + pop {R4-R12, LR} + + // Enable interrupts. + cpsie if + isb + + bx LR + //------------------------------------------------------------------------------ // VOID // EFIAPI diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index f07ba49e2c..8fc8db82ad 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -22,6 +22,13 @@ ArmCallRing3 ( IN VOID *CoreStack ); +VOID +EFIAPI +ReturnToCore ( + IN EFI_STATUS Status, + IN UINTN CoreSp + ); + VOID EFIAPI ArmSetPan ( @@ -46,6 +53,10 @@ SysCallBootService ( EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Physical; + if (Type == SysCallReturnToCore) { + ReturnToCore (*(EFI_STATUS *)CoreRbp, mCoreSp); + } + Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, From 571f5dd304defbf26905c825da34ddff18287ecf Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 9 Jul 2024 16:17:27 +0300 Subject: [PATCH 233/341] Ring3: Fixed several bugs for ARM. --- .../Arm/DefaultExceptionHandler.c | 2 +- .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 4 ++-- .../Core/Dxe/SysCall/SupportedProtocols.c | 21 ++----------------- 3 files changed, 5 insertions(+), 22 deletions(-) diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c index 077c01bb38..d6c9cca286 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c @@ -225,7 +225,7 @@ DefaultExceptionHandler ( return mSysCallHandler ( SystemContext.SystemContextArm->R0, &(SystemContext.SystemContextArm->R1), - &(SystemContext.SystemContextArm->SP) + (VOID *)SystemContext.SystemContextArm->SP ); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index 8fc8db82ad..eb6d555734 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -71,11 +71,11 @@ SysCallBootService ( // // First 3 arguments are passed through R1-R3 and copied to SysCall Stack. // - CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)CoreRbp, 3 * sizeof (UINTN)); + CopyMem ((VOID *)((UINTN)Physical + 2 * sizeof (UINTN)), (VOID *)CoreRbp, 3 * sizeof (UINTN)); // // All remaining arguments are on User Stack. // - CopyMem ((VOID *)((UINTN)Physical + 4 * sizeof (UINTN)), (VOID *)UserRsp, 5 * sizeof (UINTN)); + CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN)); EnableSMAP (); Status = CallBootService ( diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 852ec7c663..43e7e93920 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -360,7 +360,7 @@ CoreFileSetPosition ( File->Ring3File, Position ); -#elif defined (MDE_CPU_IA32) +#elif defined (MDE_CPU_IA32) || defined (MDE_CPU_ARM) // // UINT64 Position is passed as 2 double words on stack. // @@ -370,13 +370,6 @@ CoreFileSetPosition ( File->Ring3File, Position ); -#else - return GoToRing3 ( - 2, - (VOID *)mRing3FileProtocol.SetPosition, - File->Ring3File, - Position - ); #endif } @@ -643,7 +636,7 @@ CoreFileOpen ( OpenMode, Attributes ); -#elif defined (MDE_CPU_IA32) +#elif defined (MDE_CPU_IA32) || defined (MDE_CPU_ARM) // // UINT64 OpenMode and Attributes are each passed as 2 double words on stack. // @@ -656,16 +649,6 @@ CoreFileOpen ( OpenMode, Attributes ); -#else - Status = GoToRing3 ( - 5, - (VOID *)mRing3FileProtocol.Open, - File->Ring3File, - Ring3NewHandle, - Ring3FileName, - OpenMode, - Attributes - ); #endif if (EFI_ERROR (Status)) { *NewHandle = NULL; From d3abd58fe3dec2849ab3b4c8bbc7131659da79ce Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 10 Jul 2024 13:29:20 +0300 Subject: [PATCH 234/341] Ring3: Fixed arguments alignment bug for ARM. --- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 18 ++++++++ MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 46 +++++++++++++++++++ .../Core/Dxe/SysCall/SupportedProtocols.c | 31 ++++++++++++- 3 files changed, 93 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index da40513a94..492b2cd372 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -166,6 +166,19 @@ EFI_STATUS IN UINTN Argument7 ); +typedef +EFI_STATUS +(EFIAPI *FUNCTION_8)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4, + IN UINTN Argument5, + IN UINTN Argument6, + IN UINTN Argument7, + IN UINTN Argument8 + ); + VOID EFIAPI Ring3Call ( @@ -181,6 +194,7 @@ Ring3Call ( FUNCTION_5 Function5; FUNCTION_6 Function6; FUNCTION_7 Function7; + FUNCTION_8 Function8; switch (Data->NumberOfArguments) { case 0: @@ -215,6 +229,10 @@ Ring3Call ( Function7 = (FUNCTION_7)Data->EntryPoint; Status = Function7 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5], Data->Arguments[6]); break; + case 8: + Function8 = (FUNCTION_8)Data->EntryPoint; + Status = Function8 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5], Data->Arguments[6], Data->Arguments[7]); + break; default: Status = EFI_UNSUPPORTED; break; diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index eb9c9b0924..9b6b82f5c7 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -315,6 +315,8 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserRsp, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + DEBUG ((DEBUG_VERBOSE, "Type: %a\n", SysCallNames[Type])); + switch (Type) { case SysCallLocateProtocol: // @@ -854,11 +856,22 @@ CallBootService ( return EFI_NOT_FOUND; } +#if defined (MDE_CPU_ARM) + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); +#else gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); +#endif ASSERT ((Attributes & EFI_MEMORY_USER) != 0); DisableSMAP (); +#if defined (MDE_CPU_ARM) + // + // EFI_LBA Lba is aligned on 8 bytes. + // + Attributes = *(UINT64 *)&UserRsp->Arguments[6]; +#else Attributes = *(UINT64 *)&UserRsp->Arguments[5]; +#endif EnableSMAP (); Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); @@ -900,7 +913,11 @@ CallBootService ( return EFI_NOT_FOUND; } +#if defined (MDE_CPU_ARM) + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); +#else gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); +#endif ASSERT ((Attributes & EFI_MEMORY_USER) != 0); Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); @@ -916,7 +933,14 @@ CallBootService ( CopyMem ((VOID *)Argument5,(VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); +#if defined (MDE_CPU_ARM) + // + // EFI_LBA Lba is aligned on 8 bytes. + // + Attributes = *(UINT64 *)&UserRsp->Arguments[6]; +#else Attributes = *(UINT64 *)&UserRsp->Arguments[5]; +#endif EnableSMAP (); Status = BlockIo->WriteBlocks ( @@ -957,11 +981,22 @@ CallBootService ( return EFI_NOT_FOUND; } +#if defined (MDE_CPU_ARM) + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); +#else gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); +#endif ASSERT ((Attributes & EFI_MEMORY_USER) != 0); DisableSMAP (); +#if defined (MDE_CPU_ARM) + // + // UINT64 Offset is aligned on 8 bytes. + // + Attributes = *(UINT64 *)&UserRsp->Arguments[6]; +#else Attributes = *(UINT64 *)&UserRsp->Arguments[5]; +#endif EnableSMAP (); Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); @@ -1003,7 +1038,11 @@ CallBootService ( return EFI_NOT_FOUND; } +#if defined (MDE_CPU_ARM) + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); +#else gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); +#endif ASSERT ((Attributes & EFI_MEMORY_USER) != 0); Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); @@ -1019,7 +1058,14 @@ CallBootService ( CopyMem ((VOID *)Argument5, (VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); +#if defined (MDE_CPU_ARM) + // + // UINT64 Offset is aligned on 8 bytes. + // + Attributes = *(UINT64 *)&UserRsp->Arguments[6]; +#else Attributes = *(UINT64 *)&UserRsp->Arguments[5]; +#endif EnableSMAP (); Status = DiskIo->WriteDisk ( diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 43e7e93920..349b29b9bc 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -360,7 +360,7 @@ CoreFileSetPosition ( File->Ring3File, Position ); -#elif defined (MDE_CPU_IA32) || defined (MDE_CPU_ARM) +#elif defined (MDE_CPU_IA32) // // UINT64 Position is passed as 2 double words on stack. // @@ -370,6 +370,17 @@ CoreFileSetPosition ( File->Ring3File, Position ); +#elif defined (MDE_CPU_ARM) + // + // UINT64 Position is passed as 2 words in 2 registers and is aligned on 8 bytes. + // R0 == File->Ring3File, R1 == NULL, R2 == Position_Low, R3 == Position_High. + // + return GoToRing3 ( + 4, + (VOID *)mRing3FileProtocol.SetPosition, + File->Ring3File, + Position + ); #endif } @@ -636,7 +647,7 @@ CoreFileOpen ( OpenMode, Attributes ); -#elif defined (MDE_CPU_IA32) || defined (MDE_CPU_ARM) +#elif defined (MDE_CPU_IA32) // // UINT64 OpenMode and Attributes are each passed as 2 double words on stack. // @@ -649,6 +660,22 @@ CoreFileOpen ( OpenMode, Attributes ); +#elif defined (MDE_CPU_ARM) + // + // UINT64 OpenMode and Attributes are each passed as 2 words on stack. + // Each of them is aligned on 8 bytes. + // R0 == File->Ring3File, R1 == Ring3NewHandle, R2 == Ring3FileName, R3 == NULL, + // [SP] == OpenMode, [SP + 8] == Attributes. + // + Status = GoToRing3 ( + 8, + (VOID *)mRing3FileProtocol.Open, + File->Ring3File, + Ring3NewHandle, + Ring3FileName, + OpenMode, + Attributes + ); #endif if (EFI_ERROR (Status)) { *NewHandle = NULL; From e354e275a2dcd6aff7595ee00fdcd9514f959fc8 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 11 Jul 2024 11:45:07 +0300 Subject: [PATCH 235/341] SysCall/ARM: Added TODO comments. --- MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index eb6d555734..d08066df46 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -96,12 +96,19 @@ InitializeMsr ( IN UINTN NumberOfEntries ) { + // + // TODO: EFI_CONFIGURATION_TABLE, HOB_DATA, Uart are accessible to User. + // Fix PageTable initialization. + // if (ArmHasPan ()) { // // Enable Privileged Access Never feature. // ArmSetPan (); } else { + // + // TODO: Refactoring. + // DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n")); // ASSERT (FALSE); } @@ -109,6 +116,9 @@ InitializeMsr ( InitializeSysCallHandler (SysCallBootService); } +// +// TODO: Refactoring. +// VOID EFIAPI DisableSMAP ( From 4595caaf043c024d815711631564945c3368c2c8 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 2 Sep 2024 11:14:11 +0300 Subject: [PATCH 236/341] SysCall: Restored nonvolatile registers for IA32, X64. --- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 18 +++++++------ .../Dxe/SysCall/X64/CoreBootServices.nasm | 25 ++++++++++++++----- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index f0ae792209..32a8dad0dd 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -176,10 +176,14 @@ ASM_PFX(CoreBootServices): global ASM_PFX(CallRing3) ASM_PFX(CallRing3): cli + ; Save nonvolatile registers EBX, EBP, EDI, ESI, ESP. + push ebx + push ebp + push edi + push esi - ; Save Core Stack pointers. + ; Save Core Stack pointer. mov [ASM_PFX(CoreEsp)], esp - mov [ASM_PFX(CoreEbp)], ebp push dword [ASM_PFX(gRing3EntryPoint)] push dword [ASM_PFX(gRing3CallStackTop)] @@ -189,7 +193,7 @@ ASM_PFX(CallRing3): ; Prepare SYSEXIT arguments. pop ecx pop edx - mov eax, [esp + 4] ; Data + mov eax, [esp + 4 * 5] ; Data ; Switch to User Stack. mov ebp, ecx @@ -200,7 +204,10 @@ ASM_PFX(CallRing3): coreReturnAddress: mov esp, [ASM_PFX(CoreEsp)] - mov ebp, [ASM_PFX(CoreEbp)] + pop esi + pop edi + pop ebp + pop ebx call ASM_PFX(DisableSMAP) mov eax, [edx + 2 * 4] ; User Argument 1 @@ -214,6 +221,3 @@ coreReturnAddress: SECTION .data ASM_PFX(CoreEsp): resd 1 - -ASM_PFX(CoreEbp): - resd 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 555387bba7..a18680ed6c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -195,10 +195,18 @@ ASM_PFX(CallRing3): pushfq pop r11 cli + ; Save nonvolatile registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15. + push rbx + push rbp + push rdi + push rsi + push r12 + push r13 + push r14 + push r15 - ; Save Core Stack pointers. + ; Save Core Stack pointer. mov [ASM_PFX(CoreRsp)], rsp - mov [ASM_PFX(CoreRbp)], rbp ; Save input Arguments. mov r8, [ASM_PFX(gRing3CallStackTop)] @@ -220,7 +228,15 @@ o64 sysret coreReturnAddress: mov rsp, [ASM_PFX(CoreRsp)] - mov rbp, [ASM_PFX(CoreRbp)] + pop r15 + pop r14 + pop r13 + pop r12 + pop rsi + pop rdi + pop rbp + pop rbx + mov rax, rdx sti ret @@ -228,6 +244,3 @@ coreReturnAddress: SECTION .data ASM_PFX(CoreRsp): resq 1 - -ASM_PFX(CoreRbp): - resq 1 From 006342603971ade9c6477193f4c7849696cce7b0 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 2 Sep 2024 12:15:38 +0300 Subject: [PATCH 237/341] MdeModulePkg: Added PcdEnableUserSpace. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 21 ++++++++++++------- MdeModulePkg/MdeModulePkg.dec | 6 ++++++ OvmfPkg/OvmfPkgX64.dsc | 1 + 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index ac0b0f84dc..76c9618e7a 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -217,6 +217,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdImageLargeAddressLoad ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 1652a59c68..929602305c 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -236,14 +236,19 @@ ProtectUefiImage ( // // CPU ARCH present. Update memory attribute directly. // - if (AsciiStrStr (PdbPointer, "Fat") != NULL) { - SetUefiImageProtectionAttributes (ImageRecord, TRUE); - *IsUserImage = TRUE; - } else if (AsciiStrStr (PdbPointer, "Ring3") != NULL) { - SetUefiImageProtectionAttributes (ImageRecord, TRUE); - *IsUserImage = TRUE; - *IsRing3EntryPoint = TRUE; - } else { + if (PcdGetBool (PcdEnableUserSpace)) { + if (AsciiStrStr (PdbPointer, "Fat") != NULL) { + SetUefiImageProtectionAttributes (ImageRecord, TRUE); + *IsUserImage = TRUE; + } else if (AsciiStrStr (PdbPointer, "Ring3") != NULL) { + SetUefiImageProtectionAttributes (ImageRecord, TRUE); + *IsUserImage = TRUE; + *IsRing3EntryPoint = TRUE; + } else { + SetUefiImageProtectionAttributes (ImageRecord, FALSE); + *IsUserImage = FALSE; + } + } else { SetUefiImageProtectionAttributes (ImageRecord, FALSE); *IsUserImage = FALSE; } diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index f51dc7c9a1..335a0d86c9 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -1204,6 +1204,12 @@ # @Prompt Defines the page allocation for the MM communication buffer; default is 128 pages (512KB). gEfiMdeModulePkgTokenSpaceGuid.PcdMmCommBufferPages|128|UINT32|0x30001061 + ## Indicates whether some DXE drivers will be loaded in user memory. + # TRUE - Some DXE drivers will be loaded in user memory.
+ # FALSE - All DXE drivers will be loaded in supervisor memory.
+ # @Prompt Enable User Space. + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|FALSE|BOOLEAN|0x30001062 + [PcdsFixedAtBuild, PcdsPatchableInModule] ## Dynamic type PCD can be registered callback function for Pcd setting action. # PcdMaxPeiPcdCallBackNumberPerPcdEntry indicates the maximum number of callback function diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 3ce9d08828..a20e45a908 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -628,6 +628,7 @@ gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !endif gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE # # Firmware volume supports UE, and may require PE. From ca1b2d88813f93f180345b92b58a426320118783 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 2 Sep 2024 12:19:00 +0300 Subject: [PATCH 238/341] SysCall: Made SMEP, SMAP, PAN optional features. --- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 11 +++++----- .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 6 ------ .../Core/Dxe/SysCall/IA32/InitializeMsr.c | 19 +++++++++-------- .../Core/Dxe/SysCall/X64/InitializeMsr.c | 21 +++++++++---------- 4 files changed, 26 insertions(+), 31 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index ab2f1b536b..f764309f11 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -173,9 +173,6 @@ InitializeMsr ( // Enable Privileged Access Never feature. // ArmSetPan (); - } else { - DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n")); - ASSERT (FALSE); } InitializeSysCallHandler ((VOID *)SysCallBootService); @@ -187,7 +184,9 @@ DisableSMAP ( VOID ) { - ArmClearPan (); + if (ArmHasPan ()) { + ArmClearPan (); + } } VOID @@ -196,7 +195,9 @@ EnableSMAP ( VOID ) { - ArmSetPan (); + if (ArmHasPan ()) { + ArmSetPan (); + } } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index d08066df46..79ca473028 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -105,12 +105,6 @@ InitializeMsr ( // Enable Privileged Access Never feature. // ArmSetPan (); - } else { - // - // TODO: Refactoring. - // - DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n")); - // ASSERT (FALSE); } InitializeSysCallHandler (SysCallBootService); diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c index e08d97a336..aabfb9e5c4 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c @@ -27,14 +27,9 @@ InitializeMsr ( // // Forbid supervisor-mode accesses to any user-mode pages. - // SMEP and SMAP must be supported. // AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); - // - // SYSENTER and SYSEXIT must be also supported. - // - AsmCpuidEx (0x01, 0x0, NULL, NULL, NULL, &Edx); - if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) { + if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { Cr4.UintN = AsmReadCr4 (); Cr4.Bits.SMAP = 1; Cr4.Bits.SMEP = 1; @@ -43,9 +38,15 @@ InitializeMsr ( Eflags.UintN = AsmReadEflags (); Eflags.Bits.AC = 0; AsmWriteEflags (Eflags.UintN); - } else { - DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n")); - ASSERT (FALSE); + } + + // + // SYSENTER and SYSEXIT must be supported. + // + AsmCpuidEx (0x01, 0x0, NULL, NULL, NULL, &Edx); + if ((Edx & BIT11) == 0) { + DEBUG ((DEBUG_ERROR, "Core: SYSENTER and SYSEXIT are not supported.\n")); + CpuDeadLoop (); } // diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c index fded58d6fa..348d850f1c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c @@ -28,14 +28,9 @@ InitializeMsr ( // // Forbid supervisor-mode accesses to any user-mode pages. - // SMEP and SMAP must be supported. // AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); - // - // SYSCALL and SYSRET must be also supported. - // - AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); - if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0) && ((Edx & BIT11) != 0)) { + if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { Cr4.UintN = AsmReadCr4 (); Cr4.Bits.SMAP = 1; Cr4.Bits.SMEP = 1; @@ -44,15 +39,19 @@ InitializeMsr ( Eflags.UintN = AsmReadEflags (); Eflags.Bits.AC = 0; AsmWriteEflags (Eflags.UintN); - // - // Enable SYSCALL and SYSRET. - // + } + + // + // Enable SYSCALL and SYSRET. + // + AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); + if ((Edx & BIT11) != 0) { MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); MsrEfer.Bits.SCE = 1; AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); } else { - DEBUG ((DEBUG_ERROR, "Core: Failed to initialize MSRs for Ring3.\n")); - ASSERT (FALSE); + DEBUG ((DEBUG_ERROR, "Core: SYSCALL and SYSRET are not supported.\n")); + CpuDeadLoop (); } // From dd1da4af6c5d84556b8c7bc3e49305f0fc68344f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 2 Sep 2024 12:26:15 +0300 Subject: [PATCH 239/341] Core/Dxe: Changed line ending to Windows style. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 32 +- .../Core/Dxe/DxeRing3/AARCH64/SysCall.S | 64 +- MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S | 64 +- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 530 +-- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf | 132 +- .../Core/Dxe/DxeRing3/IA32/SysCall.nasm | 84 +- MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h | 3256 ++++++++--------- .../Core/Dxe/DxeRing3/Ring3Protocols.c | 420 +-- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 1578 ++++---- .../Dxe/DxeRing3/Ring3UefiRuntimeServices.c | 388 +- .../Core/Dxe/DxeRing3/X64/SysCall.nasm | 88 +- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 338 +- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 420 +-- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 282 +- .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 290 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 2868 +++++++-------- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 446 +-- .../Core/Dxe/SysCall/IA32/InitializeMsr.c | 128 +- .../Core/Dxe/SysCall/Initialization.c | 302 +- .../Core/Dxe/SysCall/SupportedProtocols.c | 1618 ++++---- .../Core/Dxe/SysCall/SupportedProtocols.h | 96 +- .../Dxe/SysCall/X64/CoreBootServices.nasm | 492 +-- .../Core/Dxe/SysCall/X64/InitializeMsr.c | 140 +- 23 files changed, 7028 insertions(+), 7028 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 76c9618e7a..8e88d449b9 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -70,21 +70,21 @@ SysCall/SupportedProtocols.h SysCall/SupportedProtocols.c -[Sources.IA32] - SysCall/IA32/InitializeMsr.c - SysCall/IA32/CoreBootServices.nasm - -[Sources.X64] - SysCall/X64/InitializeMsr.c - SysCall/X64/CoreBootServices.nasm - -[Sources.ARM] - SysCall/ARM/InitializeMsr.c - SysCall/ARM/CoreBootServices.S - -[Sources.AARCH64] - SysCall/AARCH64/InitializeMsr.c - SysCall/AARCH64/CoreBootServices.S +[Sources.IA32] + SysCall/IA32/InitializeMsr.c + SysCall/IA32/CoreBootServices.nasm + +[Sources.X64] + SysCall/X64/InitializeMsr.c + SysCall/X64/CoreBootServices.nasm + +[Sources.ARM] + SysCall/ARM/InitializeMsr.c + SysCall/ARM/CoreBootServices.S + +[Sources.AARCH64] + SysCall/AARCH64/InitializeMsr.c + SysCall/AARCH64/CoreBootServices.S [Packages] MdePkg/MdePkg.dec @@ -93,7 +93,7 @@ OvmfPkg/OvmfPkg.dec ArmPkg/ArmPkg.dec ArmVirtPkg/ArmVirtPkg.dec - + [LibraryClasses] BaseMemoryLib CacheMaintenanceLib diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S index b3cc3d7c72..7ed039d821 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S @@ -1,32 +1,32 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause -//------------------------------------------------------------------------------ - -#include - -.extern ASM_PFX(Ring3Call) - -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// SysCall ( -// IN UINT8 Type, -// ... -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(SysCall) - svc #0 - ret - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// Ring3EntryPoint ( -// IN RING3_CALL_DATA *Data -// ); -// -// (x0) Data -//------------------------------------------------------------------------------ -ASM_FUNC(Ring3EntryPoint) - b ASM_PFX(Ring3Call) +//------------------------------------------------------------------------------ +// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +//------------------------------------------------------------------------------ + +#include + +.extern ASM_PFX(Ring3Call) + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// SysCall ( +// IN UINT8 Type, +// ... +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(SysCall) + svc #0 + ret + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// Ring3EntryPoint ( +// IN RING3_CALL_DATA *Data +// ); +// +// (x0) Data +//------------------------------------------------------------------------------ +ASM_FUNC(Ring3EntryPoint) + b ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S index 25fcc31ab2..2f0495f31f 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S @@ -1,32 +1,32 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause -//------------------------------------------------------------------------------ - -#include - -.extern ASM_PFX(Ring3Call) - -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// SysCall ( -// IN UINT8 Type, -// ... -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(SysCall) - svc #0 - bx LR - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// Ring3EntryPoint ( -// IN RING3_CALL_DATA *Data -// ); -// -// (r0) Data -//------------------------------------------------------------------------------ -ASM_FUNC(Ring3EntryPoint) - b ASM_PFX(Ring3Call) +//------------------------------------------------------------------------------ +// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +//------------------------------------------------------------------------------ + +#include + +.extern ASM_PFX(Ring3Call) + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// SysCall ( +// IN UINT8 Type, +// ... +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(SysCall) + svc #0 + bx LR + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// Ring3EntryPoint ( +// IN RING3_CALL_DATA *Data +// ); +// +// (r0) Data +//------------------------------------------------------------------------------ +ASM_FUNC(Ring3EntryPoint) + b ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index 492b2cd372..3afb8f37e4 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -1,265 +1,265 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include -#include -#include -#include -#include - -#include "Ring3.h" - -EFI_BOOT_SERVICES mBootServices = { - { - EFI_BOOT_SERVICES_SIGNATURE, // Signature - EFI_BOOT_SERVICES_REVISION, // Revision - sizeof (EFI_BOOT_SERVICES), // HeaderSize - 0, // CRC32 - 0 // Reserved - }, - (EFI_RAISE_TPL)Ring3RaiseTpl, // RaiseTPL - (EFI_RESTORE_TPL)Ring3RestoreTpl, // RestoreTPL - (EFI_ALLOCATE_PAGES)Ring3AllocatePages, // AllocatePages - (EFI_FREE_PAGES)Ring3FreePages, // FreePages - (EFI_GET_MEMORY_MAP)Ring3GetMemoryMap, // GetMemoryMap - (EFI_ALLOCATE_POOL)CoreAllocatePool, // AllocatePool - (EFI_FREE_POOL)CoreFreePool, // FreePool - (EFI_CREATE_EVENT)Ring3CreateEvent, // CreateEvent - (EFI_SET_TIMER)Ring3SetTimer, // SetTimer - (EFI_WAIT_FOR_EVENT)Ring3WaitForEvent, // WaitForEvent - (EFI_SIGNAL_EVENT)Ring3SignalEvent, // SignalEvent - (EFI_CLOSE_EVENT)Ring3CloseEvent, // CloseEvent - (EFI_CHECK_EVENT)Ring3CheckEvent, // CheckEvent - (EFI_INSTALL_PROTOCOL_INTERFACE)Ring3InstallProtocolInterface, // InstallProtocolInterface - (EFI_REINSTALL_PROTOCOL_INTERFACE)Ring3ReinstallProtocolInterface, // ReinstallProtocolInterface - (EFI_UNINSTALL_PROTOCOL_INTERFACE)Ring3UninstallProtocolInterface, // UninstallProtocolInterface - (EFI_HANDLE_PROTOCOL)Ring3HandleProtocol, // HandleProtocol - (VOID *)NULL, // Reserved - (EFI_REGISTER_PROTOCOL_NOTIFY)Ring3RegisterProtocolNotify, // RegisterProtocolNotify - (EFI_LOCATE_HANDLE)Ring3LocateHandle, // LocateHandle - (EFI_LOCATE_DEVICE_PATH)Ring3LocateDevicePath, // LocateDevicePath - (EFI_INSTALL_CONFIGURATION_TABLE)Ring3InstallConfigurationTable, // InstallConfigurationTable - (EFI_IMAGE_LOAD)Ring3LoadImage, // LoadImage - (EFI_IMAGE_START)Ring3StartImage, // StartImage - (EFI_EXIT)Ring3Exit, // Exit - (EFI_IMAGE_UNLOAD)Ring3UnloadImage, // UnloadImage - (EFI_EXIT_BOOT_SERVICES)Ring3ExitBootServices, // ExitBootServices - (EFI_GET_NEXT_MONOTONIC_COUNT)Ring3GetNextMonotonicCount, // GetNextMonotonicCount - (EFI_STALL)Ring3Stall, // Stall - (EFI_SET_WATCHDOG_TIMER)Ring3SetWatchdogTimer, // SetWatchdogTimer - (EFI_CONNECT_CONTROLLER)Ring3ConnectController, // ConnectController - (EFI_DISCONNECT_CONTROLLER)Ring3DisconnectController, // DisconnectController - (EFI_OPEN_PROTOCOL)Ring3OpenProtocol, // OpenProtocol - (EFI_CLOSE_PROTOCOL)Ring3CloseProtocol, // CloseProtocol - (EFI_OPEN_PROTOCOL_INFORMATION)Ring3OpenProtocolInformation, // OpenProtocolInformation - (EFI_PROTOCOLS_PER_HANDLE)Ring3ProtocolsPerHandle, // ProtocolsPerHandle - (EFI_LOCATE_HANDLE_BUFFER)Ring3LocateHandleBuffer, // LocateHandleBuffer - (EFI_LOCATE_PROTOCOL)Ring3LocateProtocol, // LocateProtocol - (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3InstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces - (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3UninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces - (EFI_CALCULATE_CRC32)Ring3CalculateCrc32, // CalculateCrc32 - (EFI_COPY_MEM)CopyMem, // CopyMem - (EFI_SET_MEM)SetMem, // SetMem - (EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx -}; - -EFI_RUNTIME_SERVICES mRuntimeServices = { - { - EFI_RUNTIME_SERVICES_SIGNATURE, // Signature - EFI_RUNTIME_SERVICES_REVISION, // Revision - sizeof (EFI_RUNTIME_SERVICES), // HeaderSize - 0, // CRC32 - 0 // Reserved - }, - (EFI_GET_TIME)Ring3GetTime, // GetTime - (EFI_SET_TIME)Ring3SetTime, // SetTime - (EFI_GET_WAKEUP_TIME)Ring3GetWakeupTime, // GetWakeupTime - (EFI_SET_WAKEUP_TIME)Ring3SetWakeupTime, // SetWakeupTime - (EFI_SET_VIRTUAL_ADDRESS_MAP)Ring3SetVirtualAddressMap, // SetVirtualAddressMap - (EFI_CONVERT_POINTER)Ring3ConvertPointer, // ConvertPointer - (EFI_GET_VARIABLE)Ring3GetVariable, // GetVariable - (EFI_GET_NEXT_VARIABLE_NAME)Ring3GetNextVariableName, // GetNextVariableName - (EFI_SET_VARIABLE)Ring3SetVariable, // SetVariable - (EFI_GET_NEXT_HIGH_MONO_COUNT)Ring3GetNextHighMonotonicCount, // GetNextHighMonotonicCount - (EFI_RESET_SYSTEM)Ring3ResetSystem, // ResetSystem - (EFI_UPDATE_CAPSULE)Ring3UpdateCapsule, // UpdateCapsule - (EFI_QUERY_CAPSULE_CAPABILITIES)Ring3QueryCapsuleCapabilities, // QueryCapsuleCapabilities - (EFI_QUERY_VARIABLE_INFO)Ring3QueryVariableInfo // QueryVariableInfo -}; - -VOID -EFIAPI -Ring3EntryPoint ( - IN RING3_CALL_DATA *Data - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_0)( - VOID - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_1)( - IN UINTN Argument1 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_2)( - IN UINTN Argument1, - IN UINTN Argument2 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_3)( - IN UINTN Argument1, - IN UINTN Argument2, - IN UINTN Argument3 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_4)( - IN UINTN Argument1, - IN UINTN Argument2, - IN UINTN Argument3, - IN UINTN Argument4 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_5)( - IN UINTN Argument1, - IN UINTN Argument2, - IN UINTN Argument3, - IN UINTN Argument4, - IN UINTN Argument5 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_6)( - IN UINTN Argument1, - IN UINTN Argument2, - IN UINTN Argument3, - IN UINTN Argument4, - IN UINTN Argument5, - IN UINTN Argument6 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_7)( - IN UINTN Argument1, - IN UINTN Argument2, - IN UINTN Argument3, - IN UINTN Argument4, - IN UINTN Argument5, - IN UINTN Argument6, - IN UINTN Argument7 - ); - -typedef -EFI_STATUS -(EFIAPI *FUNCTION_8)( - IN UINTN Argument1, - IN UINTN Argument2, - IN UINTN Argument3, - IN UINTN Argument4, - IN UINTN Argument5, - IN UINTN Argument6, - IN UINTN Argument7, - IN UINTN Argument8 - ); - -VOID -EFIAPI -Ring3Call ( - IN RING3_CALL_DATA *Data - ) -{ - EFI_STATUS Status; - FUNCTION_0 Function0; - FUNCTION_1 Function1; - FUNCTION_2 Function2; - FUNCTION_3 Function3; - FUNCTION_4 Function4; - FUNCTION_5 Function5; - FUNCTION_6 Function6; - FUNCTION_7 Function7; - FUNCTION_8 Function8; - - switch (Data->NumberOfArguments) { - case 0: - Function0 = (FUNCTION_0)Data->EntryPoint; - Status = Function0 (); - break; - case 1: - Function1 = (FUNCTION_1)Data->EntryPoint; - Status = Function1 (Data->Arguments[0]); - break; - case 2: - Function2 = (FUNCTION_2)Data->EntryPoint; - Status = Function2 (Data->Arguments[0], Data->Arguments[1]); - break; - case 3: - Function3 = (FUNCTION_3)Data->EntryPoint; - Status = Function3 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2]); - break; - case 4: - Function4 = (FUNCTION_4)Data->EntryPoint; - Status = Function4 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3]); - break; - case 5: - Function5 = (FUNCTION_5)Data->EntryPoint; - Status = Function5 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4]); - break; - case 6: - Function6 = (FUNCTION_6)Data->EntryPoint; - Status = Function6 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5]); - break; - case 7: - Function7 = (FUNCTION_7)Data->EntryPoint; - Status = Function7 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5], Data->Arguments[6]); - break; - case 8: - Function8 = (FUNCTION_8)Data->EntryPoint; - Status = Function8 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5], Data->Arguments[6], Data->Arguments[7]); - break; - default: - Status = EFI_UNSUPPORTED; - break; - } - - SysCall (SysCallReturnToCore, Status); -} - -EFI_STATUS -EFIAPI -Ring3Initialization ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - RING3_DATA *Ring3Data; - - Ring3Data = (RING3_DATA *)SystemTable; - - Ring3Data->EntryPoint = (VOID *)Ring3EntryPoint; - Ring3Data->BootServices = &mBootServices; - Ring3Data->RuntimeServices = &mRuntimeServices; - - gBS = &mBootServices; - gRT = &mRuntimeServices; - - CoreInitializePool (); - - return EFI_SUCCESS; -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include +#include +#include +#include +#include + +#include "Ring3.h" + +EFI_BOOT_SERVICES mBootServices = { + { + EFI_BOOT_SERVICES_SIGNATURE, // Signature + EFI_BOOT_SERVICES_REVISION, // Revision + sizeof (EFI_BOOT_SERVICES), // HeaderSize + 0, // CRC32 + 0 // Reserved + }, + (EFI_RAISE_TPL)Ring3RaiseTpl, // RaiseTPL + (EFI_RESTORE_TPL)Ring3RestoreTpl, // RestoreTPL + (EFI_ALLOCATE_PAGES)Ring3AllocatePages, // AllocatePages + (EFI_FREE_PAGES)Ring3FreePages, // FreePages + (EFI_GET_MEMORY_MAP)Ring3GetMemoryMap, // GetMemoryMap + (EFI_ALLOCATE_POOL)CoreAllocatePool, // AllocatePool + (EFI_FREE_POOL)CoreFreePool, // FreePool + (EFI_CREATE_EVENT)Ring3CreateEvent, // CreateEvent + (EFI_SET_TIMER)Ring3SetTimer, // SetTimer + (EFI_WAIT_FOR_EVENT)Ring3WaitForEvent, // WaitForEvent + (EFI_SIGNAL_EVENT)Ring3SignalEvent, // SignalEvent + (EFI_CLOSE_EVENT)Ring3CloseEvent, // CloseEvent + (EFI_CHECK_EVENT)Ring3CheckEvent, // CheckEvent + (EFI_INSTALL_PROTOCOL_INTERFACE)Ring3InstallProtocolInterface, // InstallProtocolInterface + (EFI_REINSTALL_PROTOCOL_INTERFACE)Ring3ReinstallProtocolInterface, // ReinstallProtocolInterface + (EFI_UNINSTALL_PROTOCOL_INTERFACE)Ring3UninstallProtocolInterface, // UninstallProtocolInterface + (EFI_HANDLE_PROTOCOL)Ring3HandleProtocol, // HandleProtocol + (VOID *)NULL, // Reserved + (EFI_REGISTER_PROTOCOL_NOTIFY)Ring3RegisterProtocolNotify, // RegisterProtocolNotify + (EFI_LOCATE_HANDLE)Ring3LocateHandle, // LocateHandle + (EFI_LOCATE_DEVICE_PATH)Ring3LocateDevicePath, // LocateDevicePath + (EFI_INSTALL_CONFIGURATION_TABLE)Ring3InstallConfigurationTable, // InstallConfigurationTable + (EFI_IMAGE_LOAD)Ring3LoadImage, // LoadImage + (EFI_IMAGE_START)Ring3StartImage, // StartImage + (EFI_EXIT)Ring3Exit, // Exit + (EFI_IMAGE_UNLOAD)Ring3UnloadImage, // UnloadImage + (EFI_EXIT_BOOT_SERVICES)Ring3ExitBootServices, // ExitBootServices + (EFI_GET_NEXT_MONOTONIC_COUNT)Ring3GetNextMonotonicCount, // GetNextMonotonicCount + (EFI_STALL)Ring3Stall, // Stall + (EFI_SET_WATCHDOG_TIMER)Ring3SetWatchdogTimer, // SetWatchdogTimer + (EFI_CONNECT_CONTROLLER)Ring3ConnectController, // ConnectController + (EFI_DISCONNECT_CONTROLLER)Ring3DisconnectController, // DisconnectController + (EFI_OPEN_PROTOCOL)Ring3OpenProtocol, // OpenProtocol + (EFI_CLOSE_PROTOCOL)Ring3CloseProtocol, // CloseProtocol + (EFI_OPEN_PROTOCOL_INFORMATION)Ring3OpenProtocolInformation, // OpenProtocolInformation + (EFI_PROTOCOLS_PER_HANDLE)Ring3ProtocolsPerHandle, // ProtocolsPerHandle + (EFI_LOCATE_HANDLE_BUFFER)Ring3LocateHandleBuffer, // LocateHandleBuffer + (EFI_LOCATE_PROTOCOL)Ring3LocateProtocol, // LocateProtocol + (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3InstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces + (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3UninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces + (EFI_CALCULATE_CRC32)Ring3CalculateCrc32, // CalculateCrc32 + (EFI_COPY_MEM)CopyMem, // CopyMem + (EFI_SET_MEM)SetMem, // SetMem + (EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx +}; + +EFI_RUNTIME_SERVICES mRuntimeServices = { + { + EFI_RUNTIME_SERVICES_SIGNATURE, // Signature + EFI_RUNTIME_SERVICES_REVISION, // Revision + sizeof (EFI_RUNTIME_SERVICES), // HeaderSize + 0, // CRC32 + 0 // Reserved + }, + (EFI_GET_TIME)Ring3GetTime, // GetTime + (EFI_SET_TIME)Ring3SetTime, // SetTime + (EFI_GET_WAKEUP_TIME)Ring3GetWakeupTime, // GetWakeupTime + (EFI_SET_WAKEUP_TIME)Ring3SetWakeupTime, // SetWakeupTime + (EFI_SET_VIRTUAL_ADDRESS_MAP)Ring3SetVirtualAddressMap, // SetVirtualAddressMap + (EFI_CONVERT_POINTER)Ring3ConvertPointer, // ConvertPointer + (EFI_GET_VARIABLE)Ring3GetVariable, // GetVariable + (EFI_GET_NEXT_VARIABLE_NAME)Ring3GetNextVariableName, // GetNextVariableName + (EFI_SET_VARIABLE)Ring3SetVariable, // SetVariable + (EFI_GET_NEXT_HIGH_MONO_COUNT)Ring3GetNextHighMonotonicCount, // GetNextHighMonotonicCount + (EFI_RESET_SYSTEM)Ring3ResetSystem, // ResetSystem + (EFI_UPDATE_CAPSULE)Ring3UpdateCapsule, // UpdateCapsule + (EFI_QUERY_CAPSULE_CAPABILITIES)Ring3QueryCapsuleCapabilities, // QueryCapsuleCapabilities + (EFI_QUERY_VARIABLE_INFO)Ring3QueryVariableInfo // QueryVariableInfo +}; + +VOID +EFIAPI +Ring3EntryPoint ( + IN RING3_CALL_DATA *Data + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_0)( + VOID + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_1)( + IN UINTN Argument1 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_2)( + IN UINTN Argument1, + IN UINTN Argument2 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_3)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_4)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_5)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4, + IN UINTN Argument5 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_6)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4, + IN UINTN Argument5, + IN UINTN Argument6 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_7)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4, + IN UINTN Argument5, + IN UINTN Argument6, + IN UINTN Argument7 + ); + +typedef +EFI_STATUS +(EFIAPI *FUNCTION_8)( + IN UINTN Argument1, + IN UINTN Argument2, + IN UINTN Argument3, + IN UINTN Argument4, + IN UINTN Argument5, + IN UINTN Argument6, + IN UINTN Argument7, + IN UINTN Argument8 + ); + +VOID +EFIAPI +Ring3Call ( + IN RING3_CALL_DATA *Data + ) +{ + EFI_STATUS Status; + FUNCTION_0 Function0; + FUNCTION_1 Function1; + FUNCTION_2 Function2; + FUNCTION_3 Function3; + FUNCTION_4 Function4; + FUNCTION_5 Function5; + FUNCTION_6 Function6; + FUNCTION_7 Function7; + FUNCTION_8 Function8; + + switch (Data->NumberOfArguments) { + case 0: + Function0 = (FUNCTION_0)Data->EntryPoint; + Status = Function0 (); + break; + case 1: + Function1 = (FUNCTION_1)Data->EntryPoint; + Status = Function1 (Data->Arguments[0]); + break; + case 2: + Function2 = (FUNCTION_2)Data->EntryPoint; + Status = Function2 (Data->Arguments[0], Data->Arguments[1]); + break; + case 3: + Function3 = (FUNCTION_3)Data->EntryPoint; + Status = Function3 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2]); + break; + case 4: + Function4 = (FUNCTION_4)Data->EntryPoint; + Status = Function4 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3]); + break; + case 5: + Function5 = (FUNCTION_5)Data->EntryPoint; + Status = Function5 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4]); + break; + case 6: + Function6 = (FUNCTION_6)Data->EntryPoint; + Status = Function6 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5]); + break; + case 7: + Function7 = (FUNCTION_7)Data->EntryPoint; + Status = Function7 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5], Data->Arguments[6]); + break; + case 8: + Function8 = (FUNCTION_8)Data->EntryPoint; + Status = Function8 (Data->Arguments[0], Data->Arguments[1], Data->Arguments[2], Data->Arguments[3], Data->Arguments[4], Data->Arguments[5], Data->Arguments[6], Data->Arguments[7]); + break; + default: + Status = EFI_UNSUPPORTED; + break; + } + + SysCall (SysCallReturnToCore, Status); +} + +EFI_STATUS +EFIAPI +Ring3Initialization ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + RING3_DATA *Ring3Data; + + Ring3Data = (RING3_DATA *)SystemTable; + + Ring3Data->EntryPoint = (VOID *)Ring3EntryPoint; + Ring3Data->BootServices = &mBootServices; + Ring3Data->RuntimeServices = &mRuntimeServices; + + gBS = &mBootServices; + gRT = &mRuntimeServices; + + CoreInitializePool (); + + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index ca5e9a0f5b..c4ba281f51 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -1,66 +1,66 @@ -## @file -# -# Ring3 driver for SysCalls. -# -# Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -# SPDX-License-Identifier: BSD-3-Clause -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = DxeRing3 - FILE_GUID = 88EA50C2-0DEA-4F13-B691-B506554E632B - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = Ring3Initialization - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 -# - -[Sources] - Ring3.h - DxeRing3.c - Ring3UefiBootServices.c - Ring3UefiRuntimeServices.c - Ring3Protocols.c - -[Sources.IA32] - IA32/SysCall.nasm - -[Sources.X64] - X64/SysCall.nasm - -[Sources.ARM] - ARM/SysCall.S - -[Sources.AARCH64] - AARCH64/SysCall.S - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - ArmPkg/ArmPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - MemoryPoolLib - UefiBootServicesTableLib - UefiDriverEntryPoint - UefiRuntimeServicesTableLib - -[Protocols] - gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES - gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES - gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES - gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES - gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES - gEfiUnicodeCollationProtocolGuid ## SOMETIMES_CONSUMES - -[Depex] - TRUE +## @file +# +# Ring3 driver for SysCalls. +# +# Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +# SPDX-License-Identifier: BSD-3-Clause +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DxeRing3 + FILE_GUID = 88EA50C2-0DEA-4F13-B691-B506554E632B + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = Ring3Initialization + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 +# + +[Sources] + Ring3.h + DxeRing3.c + Ring3UefiBootServices.c + Ring3UefiRuntimeServices.c + Ring3Protocols.c + +[Sources.IA32] + IA32/SysCall.nasm + +[Sources.X64] + X64/SysCall.nasm + +[Sources.ARM] + ARM/SysCall.S + +[Sources.AARCH64] + AARCH64/SysCall.S + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPkg/ArmPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryPoolLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeServicesTableLib + +[Protocols] + gEfiDevicePathUtilitiesProtocolGuid ## SOMETIMES_CONSUMES + gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES + gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES + gEfiUnicodeCollationProtocolGuid ## SOMETIMES_CONSUMES + +[Depex] + TRUE diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm index 25817aded8..40e22ef83e 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm @@ -1,42 +1,42 @@ -;------------------------------------------------------------------------------ -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -; SPDX-License-Identifier: BSD-3-Clause -;------------------------------------------------------------------------------ - -extern ASM_PFX(Ring3Call) - -DEFAULT REL -SECTION .text - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; SysCall ( -; IN UINT8 Type, -; ... -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(SysCall) -ASM_PFX(SysCall): - mov edx, esp - mov ecx, [esp + 4] ; Type - lea eax, [userReturnAddress] - - sysenter -userReturnAddress: - ret - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; Ring3EntryPoint ( -; IN RING3_CALL_DATA *Data -; ); -; -; (eax) Data -;------------------------------------------------------------------------------ -global ASM_PFX(Ring3EntryPoint) -ASM_PFX(Ring3EntryPoint): - push eax - - call ASM_PFX(Ring3Call) +;------------------------------------------------------------------------------ +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +;------------------------------------------------------------------------------ + +extern ASM_PFX(Ring3Call) + +DEFAULT REL +SECTION .text + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; SysCall ( +; IN UINT8 Type, +; ... +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(SysCall) +ASM_PFX(SysCall): + mov edx, esp + mov ecx, [esp + 4] ; Type + lea eax, [userReturnAddress] + + sysenter +userReturnAddress: + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; Ring3EntryPoint ( +; IN RING3_CALL_DATA *Data +; ); +; +; (eax) Data +;------------------------------------------------------------------------------ +global ASM_PFX(Ring3EntryPoint) +ASM_PFX(Ring3EntryPoint): + push eax + + call ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h index 235af1eddb..a2d5e6416d 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h @@ -1,1628 +1,1628 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include -#include -#include -#include -#include - -EFI_STATUS -EFIAPI -SysCall ( - IN UINT8 Type, - ... - ); - -/** - Raise the task priority level to the new level. - High level is implemented by disabling processor interrupts. - - @param NewTpl New task priority level - - @return The previous task priority level - -**/ -EFI_TPL -EFIAPI -Ring3RaiseTpl ( - IN EFI_TPL NewTpl - ); - -/** - Lowers the task priority to the previous value. If the new - priority unmasks events at a higher priority, they are dispatched. - - @param NewTpl New, lower, task priority - -**/ -VOID -EFIAPI -Ring3RestoreTpl ( - IN EFI_TPL NewTpl - ); - -/** - Allocates pages from the memory map. - - @param Type The type of allocation to perform - @param MemoryType The type of memory to turn the allocated pages - into - @param NumberOfPages The number of pages to allocate - @param Memory A pointer to receive the base allocated memory - address - - @return Status. On success, Memory is filled in with the base address allocated - @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in - spec. - @retval EFI_NOT_FOUND Could not allocate pages match the requirement. - @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. - @retval EFI_SUCCESS Pages successfully allocated. - -**/ -EFI_STATUS -EFIAPI -Ring3AllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - IN OUT EFI_PHYSICAL_ADDRESS *Memory - ); - -/** - Frees previous allocated pages. - - @param Memory Base address of memory being freed - @param NumberOfPages The number of pages to free - - @retval EFI_NOT_FOUND Could not find the entry that covers the range - @retval EFI_INVALID_PARAMETER Address not aligned - @return EFI_SUCCESS -Pages successfully freed. - -**/ -EFI_STATUS -EFIAPI -Ring3FreePages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ); - -/** - This function returns a copy of the current memory map. The map is an array of - memory descriptors, each of which describes a contiguous block of memory. - - @param MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - the buffer allocated by the caller. On output, - it is the size of the buffer returned by the - firmware if the buffer was large enough, or the - size of the buffer needed to contain the map if - the buffer was too small. - @param MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param MapKey A pointer to the location in which firmware - returns the key for the current memory map. - @param DescriptorSize A pointer to the location in which firmware - returns the size, in bytes, of an individual - EFI_MEMORY_DESCRIPTOR. - @param DescriptorVersion A pointer to the location in which firmware - returns the version number associated with the - EFI_MEMORY_DESCRIPTOR. - - @retval EFI_SUCCESS The memory map was returned in the MemoryMap - buffer. - @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current - buffer size needed to hold the memory map is - returned in MemoryMapSize. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -Ring3GetMemoryMap ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion - ); - -/** - Creates an event. - - @param Type The type of event to create and its mode and - attributes - @param NotifyTpl The task priority level of event notifications - @param NotifyFunction Pointer to the events notification function - @param NotifyContext Pointer to the notification functions context; - corresponds to parameter "Context" in the - notification function - @param Event Pointer to the newly created event if the call - succeeds; undefined otherwise - - @retval EFI_SUCCESS The event structure was created - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - @retval EFI_OUT_OF_RESOURCES The event could not be allocated - -**/ -EFI_STATUS -EFIAPI -Ring3CreateEvent ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, - IN VOID *NotifyContext OPTIONAL, - OUT EFI_EVENT *Event - ); - -/** - Sets the type of timer and the trigger time for a timer event. - - @param UserEvent The timer event that is to be signaled at the - specified time - @param Type The type of time that is specified in - TriggerTime - @param TriggerTime The number of 100ns units until the timer - expires - - @retval EFI_SUCCESS The event has been set to be signaled at the - requested time - @retval EFI_INVALID_PARAMETER Event or Type is not valid - -**/ -EFI_STATUS -EFIAPI -Ring3SetTimer ( - IN EFI_EVENT UserEvent, - IN EFI_TIMER_DELAY Type, - IN UINT64 TriggerTime - ); - -/** - Stops execution until an event is signaled. - - @param NumberOfEvents The number of events in the UserEvents array - @param UserEvents An array of EFI_EVENT - @param UserIndex Pointer to the index of the event which - satisfied the wait condition - - @retval EFI_SUCCESS The event indicated by Index was signaled. - @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification - function or Event was not a valid type - @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION - -**/ -EFI_STATUS -EFIAPI -Ring3WaitForEvent ( - IN UINTN NumberOfEvents, - IN EFI_EVENT *UserEvents, - OUT UINTN *UserIndex - ); - -/** - Signals the event. Queues the event to be notified if needed. - - @param UserEvent The event to signal . - - @retval EFI_INVALID_PARAMETER Parameters are not valid. - @retval EFI_SUCCESS The event was signaled. - -**/ -EFI_STATUS -EFIAPI -Ring3SignalEvent ( - IN EFI_EVENT UserEvent - ); - -/** - Closes an event and frees the event structure. - - @param UserEvent Event to close - - @retval EFI_INVALID_PARAMETER Parameters are not valid. - @retval EFI_SUCCESS The event has been closed - -**/ -EFI_STATUS -EFIAPI -Ring3CloseEvent ( - IN EFI_EVENT UserEvent - ); - -/** - Check the status of an event. - - @param UserEvent The event to check - - @retval EFI_SUCCESS The event is in the signaled state - @retval EFI_NOT_READY The event is not in the signaled state - @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL - -**/ -EFI_STATUS -EFIAPI -Ring3CheckEvent ( - IN EFI_EVENT UserEvent - ); - -/** - Wrapper function to CoreInstallProtocolInterfaceNotify. This is the public API which - Calls the private one which contains a BOOLEAN parameter for notifications - - @param UserHandle The handle to install the protocol handler on, - or NULL if a new handle is to be allocated - @param Protocol The protocol to add to the handle - @param InterfaceType Indicates whether Interface is supplied in - native form. - @param Interface The interface for the protocol being added - - @return Status code - -**/ -EFI_STATUS -EFIAPI -Ring3InstallProtocolInterface ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface - ); - -/** - Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface. - - @param UserHandle Handle on which the interface is to be - reinstalled - @param Protocol The numeric ID of the interface - @param OldInterface A pointer to the old interface - @param NewInterface A pointer to the new interface - - @retval EFI_SUCCESS The protocol interface was installed - @retval EFI_NOT_FOUND The OldInterface on the handle was not found - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - -**/ -EFI_STATUS -EFIAPI -Ring3ReinstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *OldInterface, - IN VOID *NewInterface - ); - -/** - Uninstalls all instances of a protocol:interfacer from a handle. - If the last protocol interface is remove from the handle, the - handle is freed. - - @param UserHandle The handle to remove the protocol handler from - @param Protocol The protocol, of protocol:interface, to remove - @param Interface The interface, of protocol:interface, to remove - - @retval EFI_INVALID_PARAMETER Protocol is NULL. - @retval EFI_SUCCESS Protocol interface successfully uninstalled. - -**/ -EFI_STATUS -EFIAPI -Ring3UninstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ); - -/** - Queries a handle to determine if it supports a specified protocol. - - @param UserHandle The handle being queried. - @param Protocol The published unique identifier of the protocol. - @param Interface Supplies the address where a pointer to the - corresponding Protocol Interface is returned. - - @return The requested protocol interface for the handle - -**/ -EFI_STATUS -EFIAPI -Ring3HandleProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface - ); - -/** - Add a new protocol notification record for the request protocol. - - @param Protocol The requested protocol to add the notify - registration - @param Event The event to signal - @param Registration Returns the registration record - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully returned the registration record - that has been added - -**/ -EFI_STATUS -EFIAPI -Ring3RegisterProtocolNotify ( - IN EFI_GUID *Protocol, - IN EFI_EVENT Event, - OUT VOID **Registration - ); - -/** - Locates the requested handle(s) and returns them in Buffer. - - @param SearchType The type of search to perform to locate the - handles - @param Protocol The protocol to search for - @param SearchKey Dependant on SearchType - @param BufferSize On input the size of Buffer. On output the - size of data returned. - @param Buffer The buffer to return the results in - - @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is - returned in BufferSize. - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully found the requested handle(s) and - returns them in Buffer. - -**/ -EFI_STATUS -EFIAPI -Ring3LocateHandle ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *BufferSize, - OUT EFI_HANDLE *Buffer - ); - -/** - Locates the handle to a device on the device path that best matches the specified protocol. - - @param Protocol The protocol to search for. - @param DevicePath On input, a pointer to a pointer to the device - path. On output, the device path pointer is - modified to point to the remaining part of the - devicepath. - @param Device A pointer to the returned device handle. - - @retval EFI_SUCCESS The resulting handle was returned. - @retval EFI_NOT_FOUND No handles matched the search. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -Ring3LocateDevicePath ( - IN EFI_GUID *Protocol, - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, - OUT EFI_HANDLE *Device - ); - -/** - Boot Service called to add, modify, or remove a system configuration table from - the EFI System Table. - - @param Guid Pointer to the GUID for the entry to add, update, or - remove - @param Table Pointer to the configuration table for the entry to add, - update, or remove, may be NULL. - - @return EFI_SUCCESS Guid, Table pair added, updated, or removed. - @return EFI_INVALID_PARAMETER Input GUID not valid. - @return EFI_NOT_FOUND Attempted to delete non-existant entry - @return EFI_OUT_OF_RESOURCES Not enough memory available - -**/ -EFI_STATUS -EFIAPI -Ring3InstallConfigurationTable ( - IN EFI_GUID *Guid, - IN VOID *Table - ); - -/** - Loads an EFI image into memory and returns a handle to the image. - - @param BootPolicy If TRUE, indicates that the request originates - from the boot manager, and that the boot - manager is attempting to load FilePath as a - boot selection. - @param ParentImageHandle The caller's image handle. - @param FilePath The specific file path from which the image is - loaded. - @param SourceBuffer If not NULL, a pointer to the memory location - containing a copy of the image to be loaded. - @param SourceSize The size in bytes of SourceBuffer. - @param ImageHandle Pointer to the returned image handle that is - created when the image is successfully loaded. - - @retval EFI_SUCCESS The image was loaded into memory. - @retval EFI_NOT_FOUND The FilePath was not found. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - @retval EFI_UNSUPPORTED The image type is not supported, or the device - path cannot be parsed to locate the proper - protocol for loading the file. - @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient - resources. - @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not - understood. - @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error. - @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the - image from being loaded. NULL is returned in *ImageHandle. - @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a - valid EFI_LOADED_IMAGE_PROTOCOL. However, the current - platform policy specifies that the image should not be started. - -**/ -EFI_STATUS -EFIAPI -Ring3LoadImage ( - IN BOOLEAN BootPolicy, - IN EFI_HANDLE ParentImageHandle, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN VOID *SourceBuffer OPTIONAL, - IN UINTN SourceSize, - OUT EFI_HANDLE *ImageHandle - ); - -/** - Transfer control to a loaded image's entry point. - - @param ImageHandle Handle of image to be started. - @param ExitDataSize Pointer of the size to ExitData - @param ExitData Pointer to a pointer to a data buffer that - includes a Null-terminated string, - optionally followed by additional binary data. - The string is a description that the caller may - use to further indicate the reason for the - image's exit. - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate - @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started. - @retval EFI_SUCCESS Successfully transfer control to the image's - entry point. - -**/ -EFI_STATUS -EFIAPI -Ring3StartImage ( - IN EFI_HANDLE ImageHandle, - OUT UINTN *ExitDataSize, - OUT CHAR16 **ExitData OPTIONAL - ); - -/** - Terminates the currently loaded EFI image and returns control to boot services. - - @param ImageHandle Handle that identifies the image. This - parameter is passed to the image on entry. - @param Status The image's exit code. - @param ExitDataSize The size, in bytes, of ExitData. Ignored if - ExitStatus is EFI_SUCCESS. - @param ExitData Pointer to a data buffer that includes a - Null-terminated Unicode string, optionally - followed by additional binary data. The string - is a description that the caller may use to - further indicate the reason for the image's - exit. - - @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current - image. - @retval EFI_SUCCESS Successfully terminates the currently loaded - EFI image. - @retval EFI_ACCESS_DENIED Should never reach there. - @retval EFI_OUT_OF_RESOURCES Could not allocate pool - -**/ -EFI_STATUS -EFIAPI -Ring3Exit ( - IN EFI_HANDLE ImageHandle, - IN EFI_STATUS Status, - IN UINTN ExitDataSize, - IN CHAR16 *ExitData OPTIONAL - ); - -/** - Unloads an image. - - @param ImageHandle Handle that identifies the image to be - unloaded. - - @retval EFI_SUCCESS The image has been unloaded. - @retval EFI_UNSUPPORTED The image has been started, and does not support - unload. - @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle. - -**/ -EFI_STATUS -EFIAPI -Ring3UnloadImage ( - IN EFI_HANDLE ImageHandle - ); - -/** - Terminates all boot services. - - @param ImageHandle Handle that identifies the exiting image. - @param MapKey Key to the latest memory map. - - @retval EFI_SUCCESS Boot Services terminated - @retval EFI_INVALID_PARAMETER MapKey is incorrect. - -**/ -EFI_STATUS -EFIAPI -Ring3ExitBootServices ( - IN EFI_HANDLE ImageHandle, - IN UINTN MapKey - ); - -/** - Returns a monotonically increasing count for the platform. - - @param[out] Count The pointer to returned value. - - @retval EFI_SUCCESS The next monotonic count was returned. - @retval EFI_INVALID_PARAMETER Count is NULL. - @retval EFI_DEVICE_ERROR The device is not functioning properly. - -**/ -EFI_STATUS -EFIAPI -Ring3GetNextMonotonicCount ( - OUT UINT64 *Count - ); - -/** - Introduces a fine-grained stall. - - @param Microseconds The number of microseconds to stall execution. - - @retval EFI_SUCCESS Execution was stalled for at least the requested - amount of microseconds. - @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet - -**/ -EFI_STATUS -EFIAPI -Ring3Stall ( - IN UINTN Microseconds - ); - -/** - Sets the system's watchdog timer. - - @param Timeout The number of seconds to set the watchdog timer to. - A value of zero disables the timer. - @param WatchdogCode The numeric code to log on a watchdog timer timeout - event. The firmware reserves codes 0x0000 to 0xFFFF. - Loaders and operating systems may use other timeout - codes. - @param DataSize The size, in bytes, of WatchdogData. - @param WatchdogData A data buffer that includes a Null-terminated Unicode - string, optionally followed by additional binary data. - The string is a description that the call may use to - further indicate the reason to be logged with a - watchdog event. - - @return EFI_SUCCESS Timeout has been set - @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet - @return EFI_UNSUPPORTED System does not have a timer (currently not used) - @return EFI_DEVICE_ERROR Could not complete due to hardware error - -**/ -EFI_STATUS -EFIAPI -Ring3SetWatchdogTimer ( - IN UINTN Timeout, - IN UINT64 WatchdogCode, - IN UINTN DataSize, - IN CHAR16 *WatchdogData OPTIONAL - ); - -/** - Connects one or more drivers to a controller. - - @param ControllerHandle The handle of the controller to which driver(s) are to be connected. - @param DriverImageHandle A pointer to an ordered list handles that support the - EFI_DRIVER_BINDING_PROTOCOL. - @param RemainingDevicePath A pointer to the device path that specifies a child of the - controller specified by ControllerHandle. - @param Recursive If TRUE, then ConnectController() is called recursively - until the entire tree of controllers below the controller specified - by ControllerHandle have been created. If FALSE, then - the tree of controllers is only expanded one level. - - @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle. - 2) No drivers were connected to ControllerHandle, but - RemainingDevicePath is not NULL, and it is an End Device - Path Node. - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances - present in the system. - 2) No drivers were connected to ControllerHandle. - @retval EFI_SECURITY_VIOLATION - The user has no permission to start UEFI device drivers on the device path - associated with the ControllerHandle or specified by the RemainingDevicePath. - -**/ -EFI_STATUS -EFIAPI -Ring3ConnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE *DriverImageHandle OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, - IN BOOLEAN Recursive - ); - -/** - Disonnects a controller from a driver - - @param ControllerHandle ControllerHandle The handle of - the controller from which - driver(s) are to be - disconnected. - @param DriverImageHandle DriverImageHandle The driver to - disconnect from ControllerHandle. - @param ChildHandle ChildHandle The handle of the - child to destroy. - - @retval EFI_SUCCESS One or more drivers were - disconnected from the controller. - @retval EFI_SUCCESS On entry, no drivers are managing - ControllerHandle. - @retval EFI_SUCCESS DriverImageHandle is not NULL, - and on entry DriverImageHandle is - not managing ControllerHandle. - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL, - and it is not a valid EFI_HANDLE. - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it - is not a valid EFI_HANDLE. - @retval EFI_OUT_OF_RESOURCES There are not enough resources - available to disconnect any - drivers from ControllerHandle. - @retval EFI_DEVICE_ERROR The controller could not be - disconnected because of a device - error. - -**/ -EFI_STATUS -EFIAPI -Ring3DisconnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE DriverImageHandle OPTIONAL, - IN EFI_HANDLE ChildHandle OPTIONAL - ); - -/** - Locates the installed protocol handler for the handle, and - invokes it to obtain the protocol interface. Usage information - is registered in the protocol data base. - - @param UserHandle The handle to obtain the protocol interface on - @param Protocol The ID of the protocol - @param Interface The location to return the protocol interface - @param ImageHandle The handle of the Image that is opening the - protocol interface specified by Protocol and - Interface. - @param ControllerHandle The controller handle that is requiring this - interface. - @param Attributes The open mode of the protocol interface - specified by Handle and Protocol. - - @retval EFI_INVALID_PARAMETER Protocol is NULL. - @retval EFI_SUCCESS Get the protocol interface. - -**/ -EFI_STATUS -EFIAPI -Ring3OpenProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface OPTIONAL, - IN EFI_HANDLE ImageHandle, - IN EFI_HANDLE ControllerHandle, - IN UINT32 Attributes - ); - -/** - Closes a protocol on a handle that was opened using OpenProtocol(). - - @param UserHandle The handle for the protocol interface that was - previously opened with OpenProtocol(), and is - now being closed. - @param Protocol The published unique identifier of the protocol. - It is the caller's responsibility to pass in a - valid GUID. - @param AgentHandle The handle of the agent that is closing the - protocol interface. - @param ControllerHandle If the agent that opened a protocol is a driver - that follows the EFI Driver Model, then this - parameter is the controller handle that required - the protocol interface. If the agent does not - follow the EFI Driver Model, then this parameter - is optional and may be NULL. - - @retval EFI_SUCCESS The protocol instance was closed. - @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a - valid EFI_HANDLE. - @retval EFI_NOT_FOUND Can not find the specified protocol or - AgentHandle. - -**/ -EFI_STATUS -EFIAPI -Ring3CloseProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN EFI_HANDLE AgentHandle, - IN EFI_HANDLE ControllerHandle - ); - -/** - Return information about Opened protocols in the system - - @param UserHandle The handle to close the protocol interface on - @param Protocol The ID of the protocol - @param EntryBuffer A pointer to a buffer of open protocol - information in the form of - EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures. - @param EntryCount Number of EntryBuffer entries - -**/ -EFI_STATUS -EFIAPI -Ring3OpenProtocolInformation ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, - OUT UINTN *EntryCount - ); - -/** - Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated - from pool. - - @param UserHandle The handle from which to retrieve the list of - protocol interface GUIDs. - @param ProtocolBuffer A pointer to the list of protocol interface GUID - pointers that are installed on Handle. - @param ProtocolBufferCount A pointer to the number of GUID pointers present - in ProtocolBuffer. - - @retval EFI_SUCCESS The list of protocol interface GUIDs installed - on Handle was returned in ProtocolBuffer. The - number of protocol interface GUIDs was returned - in ProtocolBufferCount. - @retval EFI_INVALID_PARAMETER Handle is NULL. - @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE. - @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL. - @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL. - @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the - results. - -**/ -EFI_STATUS -EFIAPI -Ring3ProtocolsPerHandle ( - IN EFI_HANDLE UserHandle, - OUT EFI_GUID ***ProtocolBuffer, - OUT UINTN *ProtocolBufferCount - ); - -/** - Function returns an array of handles that support the requested protocol - in a buffer allocated from pool. This is a version of Ring3LocateHandle() - that allocates a buffer for the caller. - - @param SearchType Specifies which handle(s) are to be returned. - @param Protocol Provides the protocol to search by. This - parameter is only valid for SearchType - ByProtocol. - @param SearchKey Supplies the search key depending on the - SearchType. - @param NumberHandles The number of handles returned in Buffer. - @param Buffer A pointer to the buffer to return the requested - array of handles that support Protocol. - - @retval EFI_SUCCESS The result array of handles was returned. - @retval EFI_NOT_FOUND No handles match the search. - @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the - matching results. - @retval EFI_INVALID_PARAMETER One or more parameters are not valid. - -**/ -EFI_STATUS -EFIAPI -Ring3LocateHandleBuffer ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *NumberHandles, - OUT EFI_HANDLE **Buffer - ); - -/** - Return the first Protocol Interface that matches the Protocol GUID. If - Registration is passed in, return a Protocol Instance that was just add - to the system. If Registration is NULL return the first Protocol Interface - you find. - - @param Protocol The protocol to search for - @param Registration Optional Registration Key returned from - RegisterProtocolNotify() - @param Interface Return the Protocol interface (instance). - - @retval EFI_SUCCESS If a valid Interface is returned - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_NOT_FOUND Protocol interface not found - -**/ -EFI_STATUS -EFIAPI -Ring3LocateProtocol ( - IN EFI_GUID *Protocol, - IN VOID *Registration OPTIONAL, - OUT VOID **Interface - ); - -/** - Installs a list of protocol interface into the boot services environment. - This function calls InstallProtocolInterface() in a loop. If any error - occures all the protocols added by this function are removed. This is - basically a lib function to save space. - - @param Handle The handle to install the protocol handlers on, - or NULL if a new handle is to be allocated - @param ... EFI_GUID followed by protocol instance. A NULL - terminates the list. The pairs are the - arguments to InstallProtocolInterface(). All the - protocols are added to Handle. - - @retval EFI_SUCCESS All the protocol interface was installed. - @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols. - @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in - the handle database. - @retval EFI_INVALID_PARAMETER Handle is NULL. - @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle. - -**/ -EFI_STATUS -EFIAPI -Ring3InstallMultipleProtocolInterfaces ( - IN OUT EFI_HANDLE *Handle, - ... - ); - -/** - Uninstalls a list of protocol interface in the boot services environment. - This function calls UnisatllProtocolInterface() in a loop. This is - basically a lib function to save space. - - @param Handle The handle to uninstall the protocol - @param ... EFI_GUID followed by protocol instance. A NULL - terminates the list. The pairs are the - arguments to UninstallProtocolInterface(). All - the protocols are added to Handle. - - @return Status code - -**/ -EFI_STATUS -EFIAPI -Ring3UninstallMultipleProtocolInterfaces ( - IN EFI_HANDLE Handle, - ... - ); - -/** - Computes and returns a 32-bit CRC for a data buffer. - - @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed. - @param[in] DataSize The number of bytes in the buffer Data. - @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data - and DataSize. - - @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in - Crc32. - @retval EFI_INVALID_PARAMETER Data is NULL. - @retval EFI_INVALID_PARAMETER Crc32 is NULL. - @retval EFI_INVALID_PARAMETER DataSize is 0. - -**/ -EFI_STATUS -EFIAPI -Ring3CalculateCrc32 ( - IN VOID *Data, - IN UINTN DataSize, - OUT UINT32 *Crc32 - ); - -/** - Creates an event in a group. - - @param Type The type of event to create and its mode and - attributes - @param NotifyTpl The task priority level of event notifications - @param NotifyFunction Pointer to the events notification function - @param NotifyContext Pointer to the notification functions context; - corresponds to parameter "Context" in the - notification function - @param EventGroup GUID for EventGroup if NULL act the same as - gBS->CreateEvent(). - @param Event Pointer to the newly created event if the call - succeeds; undefined otherwise - - @retval EFI_SUCCESS The event structure was created - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - @retval EFI_OUT_OF_RESOURCES The event could not be allocated - -**/ -EFI_STATUS -EFIAPI -Ring3CreateEventEx ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, - IN CONST VOID *NotifyContext OPTIONAL, - IN CONST EFI_GUID *EventGroup OPTIONAL, - OUT EFI_EVENT *Event - ); - -/** - Reset the Block Device. - - @param This Indicates a pointer to the calling context. - @param ExtendedVerification Driver may perform diagnostics on reset. - - @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could - not be reset. - -**/ -EFI_STATUS -EFIAPI -Ring3BlockIoReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ); - -/** - Read BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId Id of the media, changes every time the media is replaced. - @param Lba The starting Logical Block Address to read from - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the destination buffer for the data. The caller is - responsible for either having implicit or explicit ownership of the buffer. - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -Ring3BlockIoRead ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Write BufferSize bytes from Lba into Buffer. - - @param This Indicates a pointer to the calling context. - @param MediaId The media ID that the write request is for. - @param Lba The starting logical block address to be written. The caller is - responsible for writing to only legitimate locations. - @param BufferSize Size of Buffer, must be a multiple of device block size. - @param Buffer A pointer to the source buffer for the data. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. - @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, - or the buffer is not on proper alignment. - -**/ -EFI_STATUS -EFIAPI -Ring3BlockIoWrite ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -/** - Flush the Block Device. - - @param This Indicates a pointer to the calling context. - - @retval EFI_SUCCESS All outstanding data was written to the device - @retval EFI_DEVICE_ERROR The device reported an error while writting back the data - @retval EFI_NO_MEDIA There is no media in the device. - -**/ -EFI_STATUS -EFIAPI -Ring3BlockIoFlush ( - IN EFI_BLOCK_IO_PROTOCOL *This - ); - -/** - Read BufferSize bytes from Offset into Buffer. - - @param This Protocol instance pointer. - @param MediaId Id of the media, changes every time the media is replaced. - @param Offset The starting byte offset to read from - @param BufferSize Size of Buffer - @param Buffer Buffer containing read data - - @retval EFI_SUCCESS The data was read correctly from the device. - @retval EFI_DEVICE_ERROR The device reported an error while performing the read. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not - valid for the device. - -**/ -EFI_STATUS -EFIAPI -Ring3DiskIoRead ( - IN EFI_DISK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Offset, - IN UINTN BufferSize, - OUT VOID *Buffer - ); - -/** - Writes a specified number of bytes to a device. - - @param This Indicates a pointer to the calling context. - @param MediaId ID of the medium to be written. - @param Offset The starting byte offset on the logical block I/O device to write. - @param BufferSize The size in bytes of Buffer. The number of bytes to write to the device. - @param Buffer A pointer to the buffer containing the data to be written. - - @retval EFI_SUCCESS The data was written correctly to the device. - @retval EFI_WRITE_PROTECTED The device can not be written to. - @retval EFI_DEVICE_ERROR The device reported an error while performing the write. - @retval EFI_NO_MEDIA There is no media in the device. - @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. - @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not - valid for the device. - -**/ -EFI_STATUS -EFIAPI -Ring3DiskIoWrite ( - IN EFI_DISK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Offset, - IN UINTN BufferSize, - IN VOID *Buffer - ); - -/** - Returns the current time and date information, and the time-keeping capabilities - of the hardware platform. - - @param[out] Time A pointer to storage to receive a snapshot of the current time. - @param[out] Capabilities An optional pointer to a buffer to receive the real time clock - device's capabilities. - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_INVALID_PARAMETER Time is NULL. - @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error. - -**/ -EFI_STATUS -EFIAPI -Ring3GetTime ( - OUT EFI_TIME *Time, - OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL - ); - -/** - Sets the current local time and date information. - - @param[in] Time A pointer to the current time. - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_INVALID_PARAMETER A time field is out of range. - @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error. - -**/ -EFI_STATUS -EFIAPI -Ring3SetTime ( - IN EFI_TIME *Time - ); - -/** - Returns the current wakeup alarm clock setting. - - @param[out] Enabled Indicates if the alarm is currently enabled or disabled. - @param[out] Pending Indicates if the alarm signal is pending and requires acknowledgement. - @param[out] Time The current alarm setting. - - @retval EFI_SUCCESS The alarm settings were returned. - @retval EFI_INVALID_PARAMETER Enabled is NULL. - @retval EFI_INVALID_PARAMETER Pending is NULL. - @retval EFI_INVALID_PARAMETER Time is NULL. - @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error. - @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. - -**/ -EFI_STATUS -EFIAPI -Ring3GetWakeupTime ( - OUT BOOLEAN *Enabled, - OUT BOOLEAN *Pending, - OUT EFI_TIME *Time - ); - -/** - Sets the system wakeup alarm clock time. - - @param[in] Enable Enable or disable the wakeup alarm. - @param[in] Time If Enable is TRUE, the time to set the wakeup alarm for. - If Enable is FALSE, then this parameter is optional, and may be NULL. - - @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If - Enable is FALSE, then the wakeup alarm was disabled. - @retval EFI_INVALID_PARAMETER A time field is out of range. - @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error. - @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. - -**/ -EFI_STATUS -EFIAPI -Ring3SetWakeupTime ( - IN BOOLEAN Enable, - IN EFI_TIME *Time OPTIONAL - ); - -/** - Changes the runtime addressing mode of EFI firmware from physical to virtual. - - @param[in] MemoryMapSize The size in bytes of VirtualMap. - @param[in] DescriptorSize The size in bytes of an entry in the VirtualMap. - @param[in] DescriptorVersion The version of the structure entries in VirtualMap. - @param[in] VirtualMap An array of memory descriptors which contain new virtual - address mapping information for all runtime ranges. - - @retval EFI_SUCCESS The virtual address map has been applied. - @retval EFI_UNSUPPORTED EFI firmware is not at runtime, or the EFI firmware is already in - virtual address mapped mode. - @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is invalid. - @retval EFI_NO_MAPPING A virtual address was not supplied for a range in the memory - map that requires a mapping. - @retval EFI_NOT_FOUND A virtual address was supplied for an address that is not found - in the memory map. - -**/ -EFI_STATUS -EFIAPI -Ring3SetVirtualAddressMap ( - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN UINT32 DescriptorVersion, - IN EFI_MEMORY_DESCRIPTOR *VirtualMap - ); - -/** - Determines the new virtual address that is to be used on subsequent memory accesses. - - @param[in] DebugDisposition Supplies type information for the pointer being converted. - @param[in, out] Address A pointer to a pointer that is to be fixed to be the value needed - for the new virtual address mappings being applied. - - @retval EFI_SUCCESS The pointer pointed to by Address was modified. - @retval EFI_INVALID_PARAMETER 1) Address is NULL. - 2) *Address is NULL and DebugDisposition does - not have the EFI_OPTIONAL_PTR bit set. - @retval EFI_NOT_FOUND The pointer pointed to by Address was not found to be part - of the current memory map. This is normally fatal. - -**/ -EFI_STATUS -EFIAPI -Ring3ConvertPointer ( - IN UINTN DebugDisposition, - IN OUT VOID **Address - ); - -/** - Returns the value of a variable. - - @param[in] VariableName A Null-terminated string that is the name of the vendor's - variable. - @param[in] VendorGuid A unique identifier for the vendor. - @param[out] Attributes If not NULL, a pointer to the memory location to return the - attributes bitmask for the variable. - @param[in, out] DataSize On input, the size in bytes of the return Data buffer. - On output the size of data returned in Data. - @param[out] Data The buffer to return the contents of the variable. May be NULL - with a zero DataSize in order to determine the size buffer needed. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_NOT_FOUND The variable was not found. - @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. - @retval EFI_INVALID_PARAMETER VariableName is NULL. - @retval EFI_INVALID_PARAMETER VendorGuid is NULL. - @retval EFI_INVALID_PARAMETER DataSize is NULL. - @retval EFI_INVALID_PARAMETER The DataSize is not too small and Data is NULL. - @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. - @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure. - -**/ -EFI_STATUS -EFIAPI -Ring3GetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - OUT UINT32 *Attributes OPTIONAL, - IN OUT UINTN *DataSize, - OUT VOID *Data OPTIONAL - ); - -/** - Enumerates the current variable names. - - @param[in, out] VariableNameSize The size of the VariableName buffer. The size must be large - enough to fit input string supplied in VariableName buffer. - @param[in, out] VariableName On input, supplies the last VariableName that was returned - by GetNextVariableName(). On output, returns the Nullterminated - string of the current variable. - @param[in, out] VendorGuid On input, supplies the last VendorGuid that was returned by - GetNextVariableName(). On output, returns the - VendorGuid of the current variable. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_NOT_FOUND The next variable was not found. - @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result. - VariableNameSize has been updated with the size needed to complete the request. - @retval EFI_INVALID_PARAMETER VariableNameSize is NULL. - @retval EFI_INVALID_PARAMETER VariableName is NULL. - @retval EFI_INVALID_PARAMETER VendorGuid is NULL. - @retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and - GUID of an existing variable. - @retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of - the input VariableName buffer. - @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. - -**/ -EFI_STATUS -EFIAPI -Ring3GetNextVariableName ( - IN OUT UINTN *VariableNameSize, - IN OUT CHAR16 *VariableName, - IN OUT EFI_GUID *VendorGuid - ); - -/** - Sets the value of a variable. - - @param[in] VariableName A Null-terminated string that is the name of the vendor's variable. - Each VariableName is unique for each VendorGuid. VariableName must - contain 1 or more characters. If VariableName is an empty string, - then EFI_INVALID_PARAMETER is returned. - @param[in] VendorGuid A unique identifier for the vendor. - @param[in] Attributes Attributes bitmask to set for the variable. - @param[in] DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE or - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero - causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is - set, then a SetVariable() call with a DataSize of zero will not cause any change to - the variable value (the timestamp associated with the variable may be updated however - even if no new data value is provided,see the description of the - EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not - be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated). - @param[in] Data The contents for the variable. - - @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as - defined by the Attributes. - @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the - DataSize exceeds the maximum allowed. - @retval EFI_INVALID_PARAMETER VariableName is an empty string. - @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. - @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. - @retval EFI_WRITE_PROTECTED The variable in question is read-only. - @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. - @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, - but the AuthInfo does NOT pass the validation check carried out by the firmware. - - @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. - -**/ -EFI_STATUS -EFIAPI -Ring3SetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - IN UINT32 Attributes, - IN UINTN DataSize, - IN VOID *Data - ); - -/** - Returns the next high 32 bits of the platform's monotonic counter. - - @param[out] HighCount The pointer to returned value. - - @retval EFI_SUCCESS The next high monotonic count was returned. - @retval EFI_INVALID_PARAMETER HighCount is NULL. - @retval EFI_DEVICE_ERROR The device is not functioning properly. - -**/ -EFI_STATUS -EFIAPI -Ring3GetNextHighMonotonicCount ( - OUT UINT32 *HighCount - ); - -/** - Resets the entire platform. - - @param[in] ResetType The type of reset to perform. - @param[in] ResetStatus The status code for the reset. - @param[in] DataSize The size, in bytes, of ResetData. - @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or - EfiResetShutdown the data buffer starts with a Null-terminated - string, optionally followed by additional binary data. - The string is a description that the caller may use to further - indicate the reason for the system reset. - For a ResetType of EfiResetPlatformSpecific the data buffer - also starts with a Null-terminated string that is followed - by an EFI_GUID that describes the specific type of reset to perform. -**/ -VOID -EFIAPI -Ring3ResetSystem ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL - ); - -/** - Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended - consumption, the firmware may process the capsule immediately. If the payload should persist - across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must - be passed into ResetSystem() and will cause the capsule to be processed by the firmware as - part of the reset process. - - @param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules - being passed into update capsule. - @param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in - CaspuleHeaderArray. - @param[in] ScatterGatherList Physical pointer to a set of - EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the - location in physical memory of a set of capsules. - - @retval EFI_SUCCESS Valid capsule was passed. If - CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the - capsule has been successfully processed by the firmware. - @retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were - set in the capsule header. - @retval EFI_INVALID_PARAMETER CapsuleCount is 0. - @retval EFI_DEVICE_ERROR The capsule update was started, but failed due to a device error. - @retval EFI_UNSUPPORTED The capsule type is not supported on this platform. - @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule - is compatible with this platform but is not capable of being submitted or processed - in runtime. The caller may resubmit the capsule prior to ExitBootServices(). - @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates - the capsule is compatible with this platform but there are insufficient resources to process. - -**/ -EFI_STATUS -EFIAPI -Ring3UpdateCapsule ( - IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, - IN UINTN CapsuleCount, - IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL - ); - -/** - Returns if the capsule can be supported via UpdateCapsule(). - - @param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules - being passed into update capsule. - @param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in - CaspuleHeaderArray. - @param[out] MaxiumCapsuleSize On output the maximum size that UpdateCapsule() can - support as an argument to UpdateCapsule() via - CapsuleHeaderArray and ScatterGatherList. - @param[out] ResetType Returns the type of reset required for the capsule update. - - @retval EFI_SUCCESS Valid answer returned. - @retval EFI_UNSUPPORTED The capsule type is not supported on this platform, and - MaximumCapsuleSize and ResetType are undefined. - @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL. - @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule - is compatible with this platform but is not capable of being submitted or processed - in runtime. The caller may resubmit the capsule prior to ExitBootServices(). - @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates - the capsule is compatible with this platform but there are insufficient resources to process. - -**/ -EFI_STATUS -EFIAPI -Ring3QueryCapsuleCapabilities ( - IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, - IN UINTN CapsuleCount, - OUT UINT64 *MaximumCapsuleSize, - OUT EFI_RESET_TYPE *ResetType - ); - -/** - Returns information about the EFI variables. - - @param[in] Attributes Attributes bitmask to specify the type of variables on - which to return information. - @param[out] MaximumVariableStorageSize On output the maximum size of the storage space - available for the EFI variables associated with the - attributes specified. - @param[out] RemainingVariableStorageSize Returns the remaining size of the storage space - available for the EFI variables associated with the - attributes specified. - @param[out] MaximumVariableSize Returns the maximum size of the individual EFI - variables associated with the attributes specified. - - @retval EFI_SUCCESS Valid answer returned. - @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied - @retval EFI_UNSUPPORTED The attribute is not supported on this platform, and the - MaximumVariableStorageSize, - RemainingVariableStorageSize, MaximumVariableSize - are undefined. - -**/ -EFI_STATUS -EFIAPI -Ring3QueryVariableInfo ( - IN UINT32 Attributes, - OUT UINT64 *MaximumVariableStorageSize, - OUT UINT64 *RemainingVariableStorageSize, - OUT UINT64 *MaximumVariableSize - ); - -/** - Performs a case-insensitive comparison of two Null-terminated strings. - - @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. - @param Str1 A pointer to a Null-terminated string. - @param Str2 A pointer to a Null-terminated string. - - @retval 0 Str1 is equivalent to Str2. - @retval >0 Str1 is lexically greater than Str2. - @retval <0 Str1 is lexically less than Str2. - -**/ -INTN -EFIAPI -Ring3UnicodeStriColl ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *Str1, - IN CHAR16 *Str2 - ); - -/** - Performs a case-insensitive comparison of a Null-terminated - pattern string and a Null-terminated string. - - @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. - @param String A pointer to a Null-terminated string. - @param Pattern A pointer to a Null-terminated pattern string. - - @retval TRUE Pattern was found in String. - @retval FALSE Pattern was not found in String. - -**/ -BOOLEAN -EFIAPI -Ring3UnicodeMetaiMatch ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN CHAR16 *Pattern - ); - -/** - Converts all the characters in a Null-terminated string to - lower case characters. - - @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. - @param String A pointer to a Null-terminated string. - -**/ -VOID -EFIAPI -Ring3UnicodeStrLwr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str - ); - -/** - Converts all the characters in a Null-terminated string to upper - case characters. - - @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. - @param String A pointer to a Null-terminated string. - -**/ -VOID -EFIAPI -Ring3UnicodeStrUpr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str - ); - -/** - Converts an 8.3 FAT file name in an OEM character set to a Null-terminated - string. - - @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. - @param FatSize The size of the string Fat in bytes. - @param Fat A pointer to a Null-terminated string that contains an 8.3 file - name using an 8-bit OEM character set. - @param String A pointer to a Null-terminated string. The string must - be allocated in advance to hold FatSize characters. - -**/ -VOID -EFIAPI -Ring3UnicodeFatToStr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN UINTN FatSize, - IN CHAR8 *Fat, - OUT CHAR16 *String - ); - -/** - Converts a Null-terminated string to legal characters in a FAT - filename using an OEM character set. - - @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. - @param String A pointer to a Null-terminated string. - @param FatSize The size of the string Fat in bytes. - @param Fat A pointer to a string that contains the converted version of - String using legal FAT characters from an OEM character set. - - @retval TRUE One or more conversions failed and were substituted with '_' - @retval FALSE None of the conversions failed. - -**/ -BOOLEAN -EFIAPI -Ring3UnicodeStrToFat ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN UINTN FatSize, - OUT CHAR8 *Fat - ); +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include +#include +#include +#include +#include + +EFI_STATUS +EFIAPI +SysCall ( + IN UINT8 Type, + ... + ); + +/** + Raise the task priority level to the new level. + High level is implemented by disabling processor interrupts. + + @param NewTpl New task priority level + + @return The previous task priority level + +**/ +EFI_TPL +EFIAPI +Ring3RaiseTpl ( + IN EFI_TPL NewTpl + ); + +/** + Lowers the task priority to the previous value. If the new + priority unmasks events at a higher priority, they are dispatched. + + @param NewTpl New, lower, task priority + +**/ +VOID +EFIAPI +Ring3RestoreTpl ( + IN EFI_TPL NewTpl + ); + +/** + Allocates pages from the memory map. + + @param Type The type of allocation to perform + @param MemoryType The type of memory to turn the allocated pages + into + @param NumberOfPages The number of pages to allocate + @param Memory A pointer to receive the base allocated memory + address + + @return Status. On success, Memory is filled in with the base address allocated + @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in + spec. + @retval EFI_NOT_FOUND Could not allocate pages match the requirement. + @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. + @retval EFI_SUCCESS Pages successfully allocated. + +**/ +EFI_STATUS +EFIAPI +Ring3AllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +/** + Frees previous allocated pages. + + @param Memory Base address of memory being freed + @param NumberOfPages The number of pages to free + + @retval EFI_NOT_FOUND Could not find the entry that covers the range + @retval EFI_INVALID_PARAMETER Address not aligned + @return EFI_SUCCESS -Pages successfully freed. + +**/ +EFI_STATUS +EFIAPI +Ring3FreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ); + +/** + This function returns a copy of the current memory map. The map is an array of + memory descriptors, each of which describes a contiguous block of memory. + + @param MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the buffer allocated by the caller. On output, + it is the size of the buffer returned by the + firmware if the buffer was large enough, or the + size of the buffer needed to contain the map if + the buffer was too small. + @param MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param MapKey A pointer to the location in which firmware + returns the key for the current memory map. + @param DescriptorSize A pointer to the location in which firmware + returns the size, in bytes, of an individual + EFI_MEMORY_DESCRIPTOR. + @param DescriptorVersion A pointer to the location in which firmware + returns the version number associated with the + EFI_MEMORY_DESCRIPTOR. + + @retval EFI_SUCCESS The memory map was returned in the MemoryMap + buffer. + @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current + buffer size needed to hold the memory map is + returned in MemoryMapSize. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +Ring3GetMemoryMap ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ); + +/** + Creates an event. + + @param Type The type of event to create and its mode and + attributes + @param NotifyTpl The task priority level of event notifications + @param NotifyFunction Pointer to the events notification function + @param NotifyContext Pointer to the notification functions context; + corresponds to parameter "Context" in the + notification function + @param Event Pointer to the newly created event if the call + succeeds; undefined otherwise + + @retval EFI_SUCCESS The event structure was created + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + @retval EFI_OUT_OF_RESOURCES The event could not be allocated + +**/ +EFI_STATUS +EFIAPI +Ring3CreateEvent ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN VOID *NotifyContext OPTIONAL, + OUT EFI_EVENT *Event + ); + +/** + Sets the type of timer and the trigger time for a timer event. + + @param UserEvent The timer event that is to be signaled at the + specified time + @param Type The type of time that is specified in + TriggerTime + @param TriggerTime The number of 100ns units until the timer + expires + + @retval EFI_SUCCESS The event has been set to be signaled at the + requested time + @retval EFI_INVALID_PARAMETER Event or Type is not valid + +**/ +EFI_STATUS +EFIAPI +Ring3SetTimer ( + IN EFI_EVENT UserEvent, + IN EFI_TIMER_DELAY Type, + IN UINT64 TriggerTime + ); + +/** + Stops execution until an event is signaled. + + @param NumberOfEvents The number of events in the UserEvents array + @param UserEvents An array of EFI_EVENT + @param UserIndex Pointer to the index of the event which + satisfied the wait condition + + @retval EFI_SUCCESS The event indicated by Index was signaled. + @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification + function or Event was not a valid type + @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION + +**/ +EFI_STATUS +EFIAPI +Ring3WaitForEvent ( + IN UINTN NumberOfEvents, + IN EFI_EVENT *UserEvents, + OUT UINTN *UserIndex + ); + +/** + Signals the event. Queues the event to be notified if needed. + + @param UserEvent The event to signal . + + @retval EFI_INVALID_PARAMETER Parameters are not valid. + @retval EFI_SUCCESS The event was signaled. + +**/ +EFI_STATUS +EFIAPI +Ring3SignalEvent ( + IN EFI_EVENT UserEvent + ); + +/** + Closes an event and frees the event structure. + + @param UserEvent Event to close + + @retval EFI_INVALID_PARAMETER Parameters are not valid. + @retval EFI_SUCCESS The event has been closed + +**/ +EFI_STATUS +EFIAPI +Ring3CloseEvent ( + IN EFI_EVENT UserEvent + ); + +/** + Check the status of an event. + + @param UserEvent The event to check + + @retval EFI_SUCCESS The event is in the signaled state + @retval EFI_NOT_READY The event is not in the signaled state + @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL + +**/ +EFI_STATUS +EFIAPI +Ring3CheckEvent ( + IN EFI_EVENT UserEvent + ); + +/** + Wrapper function to CoreInstallProtocolInterfaceNotify. This is the public API which + Calls the private one which contains a BOOLEAN parameter for notifications + + @param UserHandle The handle to install the protocol handler on, + or NULL if a new handle is to be allocated + @param Protocol The protocol to add to the handle + @param InterfaceType Indicates whether Interface is supplied in + native form. + @param Interface The interface for the protocol being added + + @return Status code + +**/ +EFI_STATUS +EFIAPI +Ring3InstallProtocolInterface ( + IN OUT EFI_HANDLE *UserHandle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface + ); + +/** + Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface. + + @param UserHandle Handle on which the interface is to be + reinstalled + @param Protocol The numeric ID of the interface + @param OldInterface A pointer to the old interface + @param NewInterface A pointer to the new interface + + @retval EFI_SUCCESS The protocol interface was installed + @retval EFI_NOT_FOUND The OldInterface on the handle was not found + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + +**/ +EFI_STATUS +EFIAPI +Ring3ReinstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *OldInterface, + IN VOID *NewInterface + ); + +/** + Uninstalls all instances of a protocol:interfacer from a handle. + If the last protocol interface is remove from the handle, the + handle is freed. + + @param UserHandle The handle to remove the protocol handler from + @param Protocol The protocol, of protocol:interface, to remove + @param Interface The interface, of protocol:interface, to remove + + @retval EFI_INVALID_PARAMETER Protocol is NULL. + @retval EFI_SUCCESS Protocol interface successfully uninstalled. + +**/ +EFI_STATUS +EFIAPI +Ring3UninstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ); + +/** + Queries a handle to determine if it supports a specified protocol. + + @param UserHandle The handle being queried. + @param Protocol The published unique identifier of the protocol. + @param Interface Supplies the address where a pointer to the + corresponding Protocol Interface is returned. + + @return The requested protocol interface for the handle + +**/ +EFI_STATUS +EFIAPI +Ring3HandleProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ); + +/** + Add a new protocol notification record for the request protocol. + + @param Protocol The requested protocol to add the notify + registration + @param Event The event to signal + @param Registration Returns the registration record + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCCESS Successfully returned the registration record + that has been added + +**/ +EFI_STATUS +EFIAPI +Ring3RegisterProtocolNotify ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration + ); + +/** + Locates the requested handle(s) and returns them in Buffer. + + @param SearchType The type of search to perform to locate the + handles + @param Protocol The protocol to search for + @param SearchKey Dependant on SearchType + @param BufferSize On input the size of Buffer. On output the + size of data returned. + @param Buffer The buffer to return the results in + + @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is + returned in BufferSize. + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCCESS Successfully found the requested handle(s) and + returns them in Buffer. + +**/ +EFI_STATUS +EFIAPI +Ring3LocateHandle ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ); + +/** + Locates the handle to a device on the device path that best matches the specified protocol. + + @param Protocol The protocol to search for. + @param DevicePath On input, a pointer to a pointer to the device + path. On output, the device path pointer is + modified to point to the remaining part of the + devicepath. + @param Device A pointer to the returned device handle. + + @retval EFI_SUCCESS The resulting handle was returned. + @retval EFI_NOT_FOUND No handles matched the search. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +Ring3LocateDevicePath ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT EFI_HANDLE *Device + ); + +/** + Boot Service called to add, modify, or remove a system configuration table from + the EFI System Table. + + @param Guid Pointer to the GUID for the entry to add, update, or + remove + @param Table Pointer to the configuration table for the entry to add, + update, or remove, may be NULL. + + @return EFI_SUCCESS Guid, Table pair added, updated, or removed. + @return EFI_INVALID_PARAMETER Input GUID not valid. + @return EFI_NOT_FOUND Attempted to delete non-existant entry + @return EFI_OUT_OF_RESOURCES Not enough memory available + +**/ +EFI_STATUS +EFIAPI +Ring3InstallConfigurationTable ( + IN EFI_GUID *Guid, + IN VOID *Table + ); + +/** + Loads an EFI image into memory and returns a handle to the image. + + @param BootPolicy If TRUE, indicates that the request originates + from the boot manager, and that the boot + manager is attempting to load FilePath as a + boot selection. + @param ParentImageHandle The caller's image handle. + @param FilePath The specific file path from which the image is + loaded. + @param SourceBuffer If not NULL, a pointer to the memory location + containing a copy of the image to be loaded. + @param SourceSize The size in bytes of SourceBuffer. + @param ImageHandle Pointer to the returned image handle that is + created when the image is successfully loaded. + + @retval EFI_SUCCESS The image was loaded into memory. + @retval EFI_NOT_FOUND The FilePath was not found. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_UNSUPPORTED The image type is not supported, or the device + path cannot be parsed to locate the proper + protocol for loading the file. + @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient + resources. + @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not + understood. + @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error. + @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the + image from being loaded. NULL is returned in *ImageHandle. + @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a + valid EFI_LOADED_IMAGE_PROTOCOL. However, the current + platform policy specifies that the image should not be started. + +**/ +EFI_STATUS +EFIAPI +Ring3LoadImage ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ); + +/** + Transfer control to a loaded image's entry point. + + @param ImageHandle Handle of image to be started. + @param ExitDataSize Pointer of the size to ExitData + @param ExitData Pointer to a pointer to a data buffer that + includes a Null-terminated string, + optionally followed by additional binary data. + The string is a description that the caller may + use to further indicate the reason for the + image's exit. + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate + @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started. + @retval EFI_SUCCESS Successfully transfer control to the image's + entry point. + +**/ +EFI_STATUS +EFIAPI +Ring3StartImage ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ); + +/** + Terminates the currently loaded EFI image and returns control to boot services. + + @param ImageHandle Handle that identifies the image. This + parameter is passed to the image on entry. + @param Status The image's exit code. + @param ExitDataSize The size, in bytes, of ExitData. Ignored if + ExitStatus is EFI_SUCCESS. + @param ExitData Pointer to a data buffer that includes a + Null-terminated Unicode string, optionally + followed by additional binary data. The string + is a description that the caller may use to + further indicate the reason for the image's + exit. + + @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current + image. + @retval EFI_SUCCESS Successfully terminates the currently loaded + EFI image. + @retval EFI_ACCESS_DENIED Should never reach there. + @retval EFI_OUT_OF_RESOURCES Could not allocate pool + +**/ +EFI_STATUS +EFIAPI +Ring3Exit ( + IN EFI_HANDLE ImageHandle, + IN EFI_STATUS Status, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ); + +/** + Unloads an image. + + @param ImageHandle Handle that identifies the image to be + unloaded. + + @retval EFI_SUCCESS The image has been unloaded. + @retval EFI_UNSUPPORTED The image has been started, and does not support + unload. + @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle. + +**/ +EFI_STATUS +EFIAPI +Ring3UnloadImage ( + IN EFI_HANDLE ImageHandle + ); + +/** + Terminates all boot services. + + @param ImageHandle Handle that identifies the exiting image. + @param MapKey Key to the latest memory map. + + @retval EFI_SUCCESS Boot Services terminated + @retval EFI_INVALID_PARAMETER MapKey is incorrect. + +**/ +EFI_STATUS +EFIAPI +Ring3ExitBootServices ( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey + ); + +/** + Returns a monotonically increasing count for the platform. + + @param[out] Count The pointer to returned value. + + @retval EFI_SUCCESS The next monotonic count was returned. + @retval EFI_INVALID_PARAMETER Count is NULL. + @retval EFI_DEVICE_ERROR The device is not functioning properly. + +**/ +EFI_STATUS +EFIAPI +Ring3GetNextMonotonicCount ( + OUT UINT64 *Count + ); + +/** + Introduces a fine-grained stall. + + @param Microseconds The number of microseconds to stall execution. + + @retval EFI_SUCCESS Execution was stalled for at least the requested + amount of microseconds. + @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet + +**/ +EFI_STATUS +EFIAPI +Ring3Stall ( + IN UINTN Microseconds + ); + +/** + Sets the system's watchdog timer. + + @param Timeout The number of seconds to set the watchdog timer to. + A value of zero disables the timer. + @param WatchdogCode The numeric code to log on a watchdog timer timeout + event. The firmware reserves codes 0x0000 to 0xFFFF. + Loaders and operating systems may use other timeout + codes. + @param DataSize The size, in bytes, of WatchdogData. + @param WatchdogData A data buffer that includes a Null-terminated Unicode + string, optionally followed by additional binary data. + The string is a description that the call may use to + further indicate the reason to be logged with a + watchdog event. + + @return EFI_SUCCESS Timeout has been set + @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet + @return EFI_UNSUPPORTED System does not have a timer (currently not used) + @return EFI_DEVICE_ERROR Could not complete due to hardware error + +**/ +EFI_STATUS +EFIAPI +Ring3SetWatchdogTimer ( + IN UINTN Timeout, + IN UINT64 WatchdogCode, + IN UINTN DataSize, + IN CHAR16 *WatchdogData OPTIONAL + ); + +/** + Connects one or more drivers to a controller. + + @param ControllerHandle The handle of the controller to which driver(s) are to be connected. + @param DriverImageHandle A pointer to an ordered list handles that support the + EFI_DRIVER_BINDING_PROTOCOL. + @param RemainingDevicePath A pointer to the device path that specifies a child of the + controller specified by ControllerHandle. + @param Recursive If TRUE, then ConnectController() is called recursively + until the entire tree of controllers below the controller specified + by ControllerHandle have been created. If FALSE, then + the tree of controllers is only expanded one level. + + @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle. + 2) No drivers were connected to ControllerHandle, but + RemainingDevicePath is not NULL, and it is an End Device + Path Node. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances + present in the system. + 2) No drivers were connected to ControllerHandle. + @retval EFI_SECURITY_VIOLATION + The user has no permission to start UEFI device drivers on the device path + associated with the ControllerHandle or specified by the RemainingDevicePath. + +**/ +EFI_STATUS +EFIAPI +Ring3ConnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE *DriverImageHandle OPTIONAL, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, + IN BOOLEAN Recursive + ); + +/** + Disonnects a controller from a driver + + @param ControllerHandle ControllerHandle The handle of + the controller from which + driver(s) are to be + disconnected. + @param DriverImageHandle DriverImageHandle The driver to + disconnect from ControllerHandle. + @param ChildHandle ChildHandle The handle of the + child to destroy. + + @retval EFI_SUCCESS One or more drivers were + disconnected from the controller. + @retval EFI_SUCCESS On entry, no drivers are managing + ControllerHandle. + @retval EFI_SUCCESS DriverImageHandle is not NULL, + and on entry DriverImageHandle is + not managing ControllerHandle. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL, + and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it + is not a valid EFI_HANDLE. + @retval EFI_OUT_OF_RESOURCES There are not enough resources + available to disconnect any + drivers from ControllerHandle. + @retval EFI_DEVICE_ERROR The controller could not be + disconnected because of a device + error. + +**/ +EFI_STATUS +EFIAPI +Ring3DisconnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverImageHandle OPTIONAL, + IN EFI_HANDLE ChildHandle OPTIONAL + ); + +/** + Locates the installed protocol handler for the handle, and + invokes it to obtain the protocol interface. Usage information + is registered in the protocol data base. + + @param UserHandle The handle to obtain the protocol interface on + @param Protocol The ID of the protocol + @param Interface The location to return the protocol interface + @param ImageHandle The handle of the Image that is opening the + protocol interface specified by Protocol and + Interface. + @param ControllerHandle The controller handle that is requiring this + interface. + @param Attributes The open mode of the protocol interface + specified by Handle and Protocol. + + @retval EFI_INVALID_PARAMETER Protocol is NULL. + @retval EFI_SUCCESS Get the protocol interface. + +**/ +EFI_STATUS +EFIAPI +Ring3OpenProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface OPTIONAL, + IN EFI_HANDLE ImageHandle, + IN EFI_HANDLE ControllerHandle, + IN UINT32 Attributes + ); + +/** + Closes a protocol on a handle that was opened using OpenProtocol(). + + @param UserHandle The handle for the protocol interface that was + previously opened with OpenProtocol(), and is + now being closed. + @param Protocol The published unique identifier of the protocol. + It is the caller's responsibility to pass in a + valid GUID. + @param AgentHandle The handle of the agent that is closing the + protocol interface. + @param ControllerHandle If the agent that opened a protocol is a driver + that follows the EFI Driver Model, then this + parameter is the controller handle that required + the protocol interface. If the agent does not + follow the EFI Driver Model, then this parameter + is optional and may be NULL. + + @retval EFI_SUCCESS The protocol instance was closed. + @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a + valid EFI_HANDLE. + @retval EFI_NOT_FOUND Can not find the specified protocol or + AgentHandle. + +**/ +EFI_STATUS +EFIAPI +Ring3CloseProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN EFI_HANDLE AgentHandle, + IN EFI_HANDLE ControllerHandle + ); + +/** + Return information about Opened protocols in the system + + @param UserHandle The handle to close the protocol interface on + @param Protocol The ID of the protocol + @param EntryBuffer A pointer to a buffer of open protocol + information in the form of + EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures. + @param EntryCount Number of EntryBuffer entries + +**/ +EFI_STATUS +EFIAPI +Ring3OpenProtocolInformation ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, + OUT UINTN *EntryCount + ); + +/** + Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated + from pool. + + @param UserHandle The handle from which to retrieve the list of + protocol interface GUIDs. + @param ProtocolBuffer A pointer to the list of protocol interface GUID + pointers that are installed on Handle. + @param ProtocolBufferCount A pointer to the number of GUID pointers present + in ProtocolBuffer. + + @retval EFI_SUCCESS The list of protocol interface GUIDs installed + on Handle was returned in ProtocolBuffer. The + number of protocol interface GUIDs was returned + in ProtocolBufferCount. + @retval EFI_INVALID_PARAMETER Handle is NULL. + @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL. + @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the + results. + +**/ +EFI_STATUS +EFIAPI +Ring3ProtocolsPerHandle ( + IN EFI_HANDLE UserHandle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount + ); + +/** + Function returns an array of handles that support the requested protocol + in a buffer allocated from pool. This is a version of Ring3LocateHandle() + that allocates a buffer for the caller. + + @param SearchType Specifies which handle(s) are to be returned. + @param Protocol Provides the protocol to search by. This + parameter is only valid for SearchType + ByProtocol. + @param SearchKey Supplies the search key depending on the + SearchType. + @param NumberHandles The number of handles returned in Buffer. + @param Buffer A pointer to the buffer to return the requested + array of handles that support Protocol. + + @retval EFI_SUCCESS The result array of handles was returned. + @retval EFI_NOT_FOUND No handles match the search. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the + matching results. + @retval EFI_INVALID_PARAMETER One or more parameters are not valid. + +**/ +EFI_STATUS +EFIAPI +Ring3LocateHandleBuffer ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer + ); + +/** + Return the first Protocol Interface that matches the Protocol GUID. If + Registration is passed in, return a Protocol Instance that was just add + to the system. If Registration is NULL return the first Protocol Interface + you find. + + @param Protocol The protocol to search for + @param Registration Optional Registration Key returned from + RegisterProtocolNotify() + @param Interface Return the Protocol interface (instance). + + @retval EFI_SUCCESS If a valid Interface is returned + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_NOT_FOUND Protocol interface not found + +**/ +EFI_STATUS +EFIAPI +Ring3LocateProtocol ( + IN EFI_GUID *Protocol, + IN VOID *Registration OPTIONAL, + OUT VOID **Interface + ); + +/** + Installs a list of protocol interface into the boot services environment. + This function calls InstallProtocolInterface() in a loop. If any error + occures all the protocols added by this function are removed. This is + basically a lib function to save space. + + @param Handle The handle to install the protocol handlers on, + or NULL if a new handle is to be allocated + @param ... EFI_GUID followed by protocol instance. A NULL + terminates the list. The pairs are the + arguments to InstallProtocolInterface(). All the + protocols are added to Handle. + + @retval EFI_SUCCESS All the protocol interface was installed. + @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols. + @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in + the handle database. + @retval EFI_INVALID_PARAMETER Handle is NULL. + @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle. + +**/ +EFI_STATUS +EFIAPI +Ring3InstallMultipleProtocolInterfaces ( + IN OUT EFI_HANDLE *Handle, + ... + ); + +/** + Uninstalls a list of protocol interface in the boot services environment. + This function calls UnisatllProtocolInterface() in a loop. This is + basically a lib function to save space. + + @param Handle The handle to uninstall the protocol + @param ... EFI_GUID followed by protocol instance. A NULL + terminates the list. The pairs are the + arguments to UninstallProtocolInterface(). All + the protocols are added to Handle. + + @return Status code + +**/ +EFI_STATUS +EFIAPI +Ring3UninstallMultipleProtocolInterfaces ( + IN EFI_HANDLE Handle, + ... + ); + +/** + Computes and returns a 32-bit CRC for a data buffer. + + @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed. + @param[in] DataSize The number of bytes in the buffer Data. + @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data + and DataSize. + + @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in + Crc32. + @retval EFI_INVALID_PARAMETER Data is NULL. + @retval EFI_INVALID_PARAMETER Crc32 is NULL. + @retval EFI_INVALID_PARAMETER DataSize is 0. + +**/ +EFI_STATUS +EFIAPI +Ring3CalculateCrc32 ( + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 + ); + +/** + Creates an event in a group. + + @param Type The type of event to create and its mode and + attributes + @param NotifyTpl The task priority level of event notifications + @param NotifyFunction Pointer to the events notification function + @param NotifyContext Pointer to the notification functions context; + corresponds to parameter "Context" in the + notification function + @param EventGroup GUID for EventGroup if NULL act the same as + gBS->CreateEvent(). + @param Event Pointer to the newly created event if the call + succeeds; undefined otherwise + + @retval EFI_SUCCESS The event structure was created + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + @retval EFI_OUT_OF_RESOURCES The event could not be allocated + +**/ +EFI_STATUS +EFIAPI +Ring3CreateEventEx ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN CONST VOID *NotifyContext OPTIONAL, + IN CONST EFI_GUID *EventGroup OPTIONAL, + OUT EFI_EVENT *Event + ); + +/** + Reset the Block Device. + + @param This Indicates a pointer to the calling context. + @param ExtendedVerification Driver may perform diagnostics on reset. + + @retval EFI_SUCCESS The device was reset. + @retval EFI_DEVICE_ERROR The device is not functioning properly and could + not be reset. + +**/ +EFI_STATUS +EFIAPI +Ring3BlockIoReset ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +/** + Read BufferSize bytes from Lba into Buffer. + + @param This Indicates a pointer to the calling context. + @param MediaId Id of the media, changes every time the media is replaced. + @param Lba The starting Logical Block Address to read from + @param BufferSize Size of Buffer, must be a multiple of device block size. + @param Buffer A pointer to the destination buffer for the data. The caller is + responsible for either having implicit or explicit ownership of the buffer. + + @retval EFI_SUCCESS The data was read correctly from the device. + @retval EFI_DEVICE_ERROR The device reported an error while performing the read. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. + @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. + @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, + or the buffer is not on proper alignment. + +**/ +EFI_STATUS +EFIAPI +Ring3BlockIoRead ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + +/** + Write BufferSize bytes from Lba into Buffer. + + @param This Indicates a pointer to the calling context. + @param MediaId The media ID that the write request is for. + @param Lba The starting logical block address to be written. The caller is + responsible for writing to only legitimate locations. + @param BufferSize Size of Buffer, must be a multiple of device block size. + @param Buffer A pointer to the source buffer for the data. + + @retval EFI_SUCCESS The data was written correctly to the device. + @retval EFI_WRITE_PROTECTED The device can not be written to. + @retval EFI_DEVICE_ERROR The device reported an error while performing the write. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device. + @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, + or the buffer is not on proper alignment. + +**/ +EFI_STATUS +EFIAPI +Ring3BlockIoWrite ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +/** + Flush the Block Device. + + @param This Indicates a pointer to the calling context. + + @retval EFI_SUCCESS All outstanding data was written to the device + @retval EFI_DEVICE_ERROR The device reported an error while writting back the data + @retval EFI_NO_MEDIA There is no media in the device. + +**/ +EFI_STATUS +EFIAPI +Ring3BlockIoFlush ( + IN EFI_BLOCK_IO_PROTOCOL *This + ); + +/** + Read BufferSize bytes from Offset into Buffer. + + @param This Protocol instance pointer. + @param MediaId Id of the media, changes every time the media is replaced. + @param Offset The starting byte offset to read from + @param BufferSize Size of Buffer + @param Buffer Buffer containing read data + + @retval EFI_SUCCESS The data was read correctly from the device. + @retval EFI_DEVICE_ERROR The device reported an error while performing the read. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not + valid for the device. + +**/ +EFI_STATUS +EFIAPI +Ring3DiskIoRead ( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + OUT VOID *Buffer + ); + +/** + Writes a specified number of bytes to a device. + + @param This Indicates a pointer to the calling context. + @param MediaId ID of the medium to be written. + @param Offset The starting byte offset on the logical block I/O device to write. + @param BufferSize The size in bytes of Buffer. The number of bytes to write to the device. + @param Buffer A pointer to the buffer containing the data to be written. + + @retval EFI_SUCCESS The data was written correctly to the device. + @retval EFI_WRITE_PROTECTED The device can not be written to. + @retval EFI_DEVICE_ERROR The device reported an error while performing the write. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device. + @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not + valid for the device. + +**/ +EFI_STATUS +EFIAPI +Ring3DiskIoWrite ( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +/** + Returns the current time and date information, and the time-keeping capabilities + of the hardware platform. + + @param[out] Time A pointer to storage to receive a snapshot of the current time. + @param[out] Capabilities An optional pointer to a buffer to receive the real time clock + device's capabilities. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER Time is NULL. + @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error. + +**/ +EFI_STATUS +EFIAPI +Ring3GetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ); + +/** + Sets the current local time and date information. + + @param[in] Time A pointer to the current time. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error. + +**/ +EFI_STATUS +EFIAPI +Ring3SetTime ( + IN EFI_TIME *Time + ); + +/** + Returns the current wakeup alarm clock setting. + + @param[out] Enabled Indicates if the alarm is currently enabled or disabled. + @param[out] Pending Indicates if the alarm signal is pending and requires acknowledgement. + @param[out] Time The current alarm setting. + + @retval EFI_SUCCESS The alarm settings were returned. + @retval EFI_INVALID_PARAMETER Enabled is NULL. + @retval EFI_INVALID_PARAMETER Pending is NULL. + @retval EFI_INVALID_PARAMETER Time is NULL. + @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error. + @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. + +**/ +EFI_STATUS +EFIAPI +Ring3GetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ); + +/** + Sets the system wakeup alarm clock time. + + @param[in] Enable Enable or disable the wakeup alarm. + @param[in] Time If Enable is TRUE, the time to set the wakeup alarm for. + If Enable is FALSE, then this parameter is optional, and may be NULL. + + @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If + Enable is FALSE, then the wakeup alarm was disabled. + @retval EFI_INVALID_PARAMETER A time field is out of range. + @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error. + @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. + +**/ +EFI_STATUS +EFIAPI +Ring3SetWakeupTime ( + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL + ); + +/** + Changes the runtime addressing mode of EFI firmware from physical to virtual. + + @param[in] MemoryMapSize The size in bytes of VirtualMap. + @param[in] DescriptorSize The size in bytes of an entry in the VirtualMap. + @param[in] DescriptorVersion The version of the structure entries in VirtualMap. + @param[in] VirtualMap An array of memory descriptors which contain new virtual + address mapping information for all runtime ranges. + + @retval EFI_SUCCESS The virtual address map has been applied. + @retval EFI_UNSUPPORTED EFI firmware is not at runtime, or the EFI firmware is already in + virtual address mapped mode. + @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is invalid. + @retval EFI_NO_MAPPING A virtual address was not supplied for a range in the memory + map that requires a mapping. + @retval EFI_NOT_FOUND A virtual address was supplied for an address that is not found + in the memory map. + +**/ +EFI_STATUS +EFIAPI +Ring3SetVirtualAddressMap ( + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap + ); + +/** + Determines the new virtual address that is to be used on subsequent memory accesses. + + @param[in] DebugDisposition Supplies type information for the pointer being converted. + @param[in, out] Address A pointer to a pointer that is to be fixed to be the value needed + for the new virtual address mappings being applied. + + @retval EFI_SUCCESS The pointer pointed to by Address was modified. + @retval EFI_INVALID_PARAMETER 1) Address is NULL. + 2) *Address is NULL and DebugDisposition does + not have the EFI_OPTIONAL_PTR bit set. + @retval EFI_NOT_FOUND The pointer pointed to by Address was not found to be part + of the current memory map. This is normally fatal. + +**/ +EFI_STATUS +EFIAPI +Ring3ConvertPointer ( + IN UINTN DebugDisposition, + IN OUT VOID **Address + ); + +/** + Returns the value of a variable. + + @param[in] VariableName A Null-terminated string that is the name of the vendor's + variable. + @param[in] VendorGuid A unique identifier for the vendor. + @param[out] Attributes If not NULL, a pointer to the memory location to return the + attributes bitmask for the variable. + @param[in, out] DataSize On input, the size in bytes of the return Data buffer. + On output the size of data returned in Data. + @param[out] Data The buffer to return the contents of the variable. May be NULL + with a zero DataSize in order to determine the size buffer needed. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND The variable was not found. + @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the result. + @retval EFI_INVALID_PARAMETER VariableName is NULL. + @retval EFI_INVALID_PARAMETER VendorGuid is NULL. + @retval EFI_INVALID_PARAMETER DataSize is NULL. + @retval EFI_INVALID_PARAMETER The DataSize is not too small and Data is NULL. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. + @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure. + +**/ +EFI_STATUS +EFIAPI +Ring3GetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data OPTIONAL + ); + +/** + Enumerates the current variable names. + + @param[in, out] VariableNameSize The size of the VariableName buffer. The size must be large + enough to fit input string supplied in VariableName buffer. + @param[in, out] VariableName On input, supplies the last VariableName that was returned + by GetNextVariableName(). On output, returns the Nullterminated + string of the current variable. + @param[in, out] VendorGuid On input, supplies the last VendorGuid that was returned by + GetNextVariableName(). On output, returns the + VendorGuid of the current variable. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND The next variable was not found. + @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result. + VariableNameSize has been updated with the size needed to complete the request. + @retval EFI_INVALID_PARAMETER VariableNameSize is NULL. + @retval EFI_INVALID_PARAMETER VariableName is NULL. + @retval EFI_INVALID_PARAMETER VendorGuid is NULL. + @retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and + GUID of an existing variable. + @retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of + the input VariableName buffer. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. + +**/ +EFI_STATUS +EFIAPI +Ring3GetNextVariableName ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ); + +/** + Sets the value of a variable. + + @param[in] VariableName A Null-terminated string that is the name of the vendor's variable. + Each VariableName is unique for each VendorGuid. VariableName must + contain 1 or more characters. If VariableName is an empty string, + then EFI_INVALID_PARAMETER is returned. + @param[in] VendorGuid A unique identifier for the vendor. + @param[in] Attributes Attributes bitmask to set for the variable. + @param[in] DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE or + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero + causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is + set, then a SetVariable() call with a DataSize of zero will not cause any change to + the variable value (the timestamp associated with the variable may be updated however + even if no new data value is provided,see the description of the + EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not + be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated). + @param[in] Data The contents for the variable. + + @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as + defined by the Attributes. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the + DataSize exceeds the maximum allowed. + @retval EFI_INVALID_PARAMETER VariableName is an empty string. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. + @retval EFI_WRITE_PROTECTED The variable in question is read-only. + @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. + @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, + but the AuthInfo does NOT pass the validation check carried out by the firmware. + + @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. + +**/ +EFI_STATUS +EFIAPI +Ring3SetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + +/** + Returns the next high 32 bits of the platform's monotonic counter. + + @param[out] HighCount The pointer to returned value. + + @retval EFI_SUCCESS The next high monotonic count was returned. + @retval EFI_INVALID_PARAMETER HighCount is NULL. + @retval EFI_DEVICE_ERROR The device is not functioning properly. + +**/ +EFI_STATUS +EFIAPI +Ring3GetNextHighMonotonicCount ( + OUT UINT32 *HighCount + ); + +/** + Resets the entire platform. + + @param[in] ResetType The type of reset to perform. + @param[in] ResetStatus The status code for the reset. + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or + EfiResetShutdown the data buffer starts with a Null-terminated + string, optionally followed by additional binary data. + The string is a description that the caller may use to further + indicate the reason for the system reset. + For a ResetType of EfiResetPlatformSpecific the data buffer + also starts with a Null-terminated string that is followed + by an EFI_GUID that describes the specific type of reset to perform. +**/ +VOID +EFIAPI +Ring3ResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ); + +/** + Passes capsules to the firmware with both virtual and physical mapping. Depending on the intended + consumption, the firmware may process the capsule immediately. If the payload should persist + across a system reset, the reset value returned from EFI_QueryCapsuleCapabilities must + be passed into ResetSystem() and will cause the capsule to be processed by the firmware as + part of the reset process. + + @param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules + being passed into update capsule. + @param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in + CaspuleHeaderArray. + @param[in] ScatterGatherList Physical pointer to a set of + EFI_CAPSULE_BLOCK_DESCRIPTOR that describes the + location in physical memory of a set of capsules. + + @retval EFI_SUCCESS Valid capsule was passed. If + CAPSULE_FLAGS_PERSIT_ACROSS_RESET is not set, the + capsule has been successfully processed by the firmware. + @retval EFI_INVALID_PARAMETER CapsuleSize is NULL, or an incompatible set of flags were + set in the capsule header. + @retval EFI_INVALID_PARAMETER CapsuleCount is 0. + @retval EFI_DEVICE_ERROR The capsule update was started, but failed due to a device error. + @retval EFI_UNSUPPORTED The capsule type is not supported on this platform. + @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule + is compatible with this platform but is not capable of being submitted or processed + in runtime. The caller may resubmit the capsule prior to ExitBootServices(). + @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates + the capsule is compatible with this platform but there are insufficient resources to process. + +**/ +EFI_STATUS +EFIAPI +Ring3UpdateCapsule ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL + ); + +/** + Returns if the capsule can be supported via UpdateCapsule(). + + @param[in] CapsuleHeaderArray Virtual pointer to an array of virtual pointers to the capsules + being passed into update capsule. + @param[in] CapsuleCount Number of pointers to EFI_CAPSULE_HEADER in + CaspuleHeaderArray. + @param[out] MaxiumCapsuleSize On output the maximum size that UpdateCapsule() can + support as an argument to UpdateCapsule() via + CapsuleHeaderArray and ScatterGatherList. + @param[out] ResetType Returns the type of reset required for the capsule update. + + @retval EFI_SUCCESS Valid answer returned. + @retval EFI_UNSUPPORTED The capsule type is not supported on this platform, and + MaximumCapsuleSize and ResetType are undefined. + @retval EFI_INVALID_PARAMETER MaximumCapsuleSize is NULL. + @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has been previously called this error indicates the capsule + is compatible with this platform but is not capable of being submitted or processed + in runtime. The caller may resubmit the capsule prior to ExitBootServices(). + @retval EFI_OUT_OF_RESOURCES When ExitBootServices() has not been previously called then this error indicates + the capsule is compatible with this platform but there are insufficient resources to process. + +**/ +EFI_STATUS +EFIAPI +Ring3QueryCapsuleCapabilities ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + OUT UINT64 *MaximumCapsuleSize, + OUT EFI_RESET_TYPE *ResetType + ); + +/** + Returns information about the EFI variables. + + @param[in] Attributes Attributes bitmask to specify the type of variables on + which to return information. + @param[out] MaximumVariableStorageSize On output the maximum size of the storage space + available for the EFI variables associated with the + attributes specified. + @param[out] RemainingVariableStorageSize Returns the remaining size of the storage space + available for the EFI variables associated with the + attributes specified. + @param[out] MaximumVariableSize Returns the maximum size of the individual EFI + variables associated with the attributes specified. + + @retval EFI_SUCCESS Valid answer returned. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied + @retval EFI_UNSUPPORTED The attribute is not supported on this platform, and the + MaximumVariableStorageSize, + RemainingVariableStorageSize, MaximumVariableSize + are undefined. + +**/ +EFI_STATUS +EFIAPI +Ring3QueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize + ); + +/** + Performs a case-insensitive comparison of two Null-terminated strings. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param Str1 A pointer to a Null-terminated string. + @param Str2 A pointer to a Null-terminated string. + + @retval 0 Str1 is equivalent to Str2. + @retval >0 Str1 is lexically greater than Str2. + @retval <0 Str1 is lexically less than Str2. + +**/ +INTN +EFIAPI +Ring3UnicodeStriColl ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *Str1, + IN CHAR16 *Str2 + ); + +/** + Performs a case-insensitive comparison of a Null-terminated + pattern string and a Null-terminated string. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + @param Pattern A pointer to a Null-terminated pattern string. + + @retval TRUE Pattern was found in String. + @retval FALSE Pattern was not found in String. + +**/ +BOOLEAN +EFIAPI +Ring3UnicodeMetaiMatch ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ); + +/** + Converts all the characters in a Null-terminated string to + lower case characters. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + +**/ +VOID +EFIAPI +Ring3UnicodeStrLwr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ); + +/** + Converts all the characters in a Null-terminated string to upper + case characters. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + +**/ +VOID +EFIAPI +Ring3UnicodeStrUpr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ); + +/** + Converts an 8.3 FAT file name in an OEM character set to a Null-terminated + string. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param FatSize The size of the string Fat in bytes. + @param Fat A pointer to a Null-terminated string that contains an 8.3 file + name using an 8-bit OEM character set. + @param String A pointer to a Null-terminated string. The string must + be allocated in advance to hold FatSize characters. + +**/ +VOID +EFIAPI +Ring3UnicodeFatToStr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ); + +/** + Converts a Null-terminated string to legal characters in a FAT + filename using an OEM character set. + + @param This A pointer to the EFI_UNICODE_COLLATION_PROTOCOL instance. + @param String A pointer to a Null-terminated string. + @param FatSize The size of the string Fat in bytes. + @param Fat A pointer to a string that contains the converted version of + String using legal FAT characters from an OEM character set. + + @retval TRUE One or more conversions failed and were substituted with '_' + @retval FALSE None of the conversions failed. + +**/ +BOOLEAN +EFIAPI +Ring3UnicodeStrToFat ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c index 9731dedb67..7c01109a3e 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c @@ -1,210 +1,210 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include "Ring3.h" - -EFI_STATUS -EFIAPI -Ring3BlockIoReset ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN BOOLEAN ExtendedVerification - ) -{ - return SysCall ( - SysCallBlockIoReset, - This, - ExtendedVerification - ); -} - -EFI_STATUS -EFIAPI -Ring3BlockIoRead ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - return SysCall ( - SysCallBlockIoRead, - This, - MediaId, - BufferSize, - Buffer, - Lba - ); -} - -EFI_STATUS -EFIAPI -Ring3BlockIoWrite ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - return SysCall ( - SysCallBlockIoWrite, - This, - MediaId, - BufferSize, - Buffer, - Lba - ); -} - -EFI_STATUS -EFIAPI -Ring3BlockIoFlush ( - IN EFI_BLOCK_IO_PROTOCOL *This - ) -{ - return SysCall ( - SysCallBlockIoFlush, - This - ); -} - -EFI_STATUS -EFIAPI -Ring3DiskIoRead ( - IN EFI_DISK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Offset, - IN UINTN BufferSize, - OUT VOID *Buffer - ) -{ - return SysCall ( - SysCallDiskIoRead, - This, - MediaId, - BufferSize, - Buffer, - Offset - ); -} - -EFI_STATUS -EFIAPI -Ring3DiskIoWrite ( - IN EFI_DISK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Offset, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - return SysCall ( - SysCallDiskIoWrite, - This, - MediaId, - BufferSize, - Buffer, - Offset - ); -} - -INTN -EFIAPI -Ring3UnicodeStriColl ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *Str1, - IN CHAR16 *Str2 - ) -{ - return (INTN)SysCall ( - SysCallUnicodeStriColl, - This, - Str1, - Str2 - ); -} - -BOOLEAN -EFIAPI -Ring3UnicodeMetaiMatch ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN CHAR16 *Pattern - ) -{ - return (BOOLEAN)SysCall ( - SysCallUnicodeMetaiMatch, - This, - String, - Pattern - ); -} - -VOID -EFIAPI -Ring3UnicodeStrLwr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str - ) -{ - SysCall ( - SysCallUnicodeStrLwr, - This, - Str - ); -} - -VOID -EFIAPI -Ring3UnicodeStrUpr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str - ) -{ - SysCall ( - SysCallUnicodeStrUpr, - This, - Str - ); -} - -VOID -EFIAPI -Ring3UnicodeFatToStr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN UINTN FatSize, - IN CHAR8 *Fat, - OUT CHAR16 *String - ) -{ - SysCall ( - SysCallUnicodeFatToStr, - This, - FatSize, - Fat, - String - ); -} - -BOOLEAN -EFIAPI -Ring3UnicodeStrToFat ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN UINTN FatSize, - OUT CHAR8 *Fat - ) -{ - return (BOOLEAN)SysCall ( - SysCallUnicodeStrToFat, - This, - String, - FatSize, - Fat - ); -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "Ring3.h" + +EFI_STATUS +EFIAPI +Ring3BlockIoReset ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + return SysCall ( + SysCallBlockIoReset, + This, + ExtendedVerification + ); +} + +EFI_STATUS +EFIAPI +Ring3BlockIoRead ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + return SysCall ( + SysCallBlockIoRead, + This, + MediaId, + BufferSize, + Buffer, + Lba + ); +} + +EFI_STATUS +EFIAPI +Ring3BlockIoWrite ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + return SysCall ( + SysCallBlockIoWrite, + This, + MediaId, + BufferSize, + Buffer, + Lba + ); +} + +EFI_STATUS +EFIAPI +Ring3BlockIoFlush ( + IN EFI_BLOCK_IO_PROTOCOL *This + ) +{ + return SysCall ( + SysCallBlockIoFlush, + This + ); +} + +EFI_STATUS +EFIAPI +Ring3DiskIoRead ( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + OUT VOID *Buffer + ) +{ + return SysCall ( + SysCallDiskIoRead, + This, + MediaId, + BufferSize, + Buffer, + Offset + ); +} + +EFI_STATUS +EFIAPI +Ring3DiskIoWrite ( + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + return SysCall ( + SysCallDiskIoWrite, + This, + MediaId, + BufferSize, + Buffer, + Offset + ); +} + +INTN +EFIAPI +Ring3UnicodeStriColl ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *Str1, + IN CHAR16 *Str2 + ) +{ + return (INTN)SysCall ( + SysCallUnicodeStriColl, + This, + Str1, + Str2 + ); +} + +BOOLEAN +EFIAPI +Ring3UnicodeMetaiMatch ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ) +{ + return (BOOLEAN)SysCall ( + SysCallUnicodeMetaiMatch, + This, + String, + Pattern + ); +} + +VOID +EFIAPI +Ring3UnicodeStrLwr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +{ + SysCall ( + SysCallUnicodeStrLwr, + This, + Str + ); +} + +VOID +EFIAPI +Ring3UnicodeStrUpr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +{ + SysCall ( + SysCallUnicodeStrUpr, + This, + Str + ); +} + +VOID +EFIAPI +Ring3UnicodeFatToStr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ) +{ + SysCall ( + SysCallUnicodeFatToStr, + This, + FatSize, + Fat, + String + ); +} + +BOOLEAN +EFIAPI +Ring3UnicodeStrToFat ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ) +{ + return (BOOLEAN)SysCall ( + SysCallUnicodeStrToFat, + This, + String, + FatSize, + Fat + ); +} diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 0dab6fc79e..f21bf6c1aa 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -1,789 +1,789 @@ -/** @file - This driver constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include - -#include - -#include -#include -#include - -#include "Ring3.h" - -BOOLEAN mOnGuarding = FALSE; - -STATIC -EFI_STATUS -EFIAPI -FixInterface ( - IN EFI_GUID *Protocol, - IN OUT VOID **Interface - ) -{ - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_DISK_IO_PROTOCOL *DiskIo; - EFI_DEVICE_PATH_UTILITIES_PROTOCOL *DevicePath; - EFI_UNICODE_COLLATION_PROTOCOL *Unicode; - - ASSERT (Protocol != NULL); - ASSERT (Interface != NULL); - - if (CompareGuid (Protocol, &gEfiDevicePathProtocolGuid)) { - - } else if (CompareGuid (Protocol, &gEfiLoadedImageProtocolGuid)) { - - LoadedImage = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; - - // TODO: Copy User changes to Core? Resembles InstallMultipleProtocolInterfaces(). - - LoadedImage->Unload = NULL; - - } else if (CompareGuid (Protocol, &gEfiBlockIoProtocolGuid)) { - - BlockIo = (EFI_BLOCK_IO_PROTOCOL *)*Interface; - - BlockIo->Reset = Ring3BlockIoReset; - BlockIo->ReadBlocks = Ring3BlockIoRead; - BlockIo->WriteBlocks = Ring3BlockIoWrite; - BlockIo->FlushBlocks = Ring3BlockIoFlush; - - } else if (CompareGuid (Protocol, &gEfiDiskIoProtocolGuid)) { - - DiskIo = (EFI_DISK_IO_PROTOCOL *)*Interface; - - DiskIo->ReadDisk = Ring3DiskIoRead; - DiskIo->WriteDisk = Ring3DiskIoWrite; - - } else if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { - DevicePath = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; - - DevicePath->GetDevicePathSize = NULL; - DevicePath->DuplicateDevicePath = NULL; - DevicePath->AppendDevicePath = NULL; - DevicePath->AppendDeviceNode = NULL; - DevicePath->AppendDevicePathInstance = NULL; - DevicePath->GetNextDevicePathInstance = NULL; - DevicePath->IsDevicePathMultiInstance = NULL; - DevicePath->CreateDeviceNode = NULL; - - } else if (CompareGuid (Protocol, &gEfiUnicodeCollationProtocolGuid)) { - Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)*Interface; - - Unicode->StriColl = Ring3UnicodeStriColl; - Unicode->MetaiMatch = Ring3UnicodeMetaiMatch; - Unicode->StrLwr = Ring3UnicodeStrLwr; - Unicode->StrUpr = Ring3UnicodeStrUpr; - Unicode->FatToStr = Ring3UnicodeFatToStr; - Unicode->StrToFat = Ring3UnicodeStrToFat; - - } else { - return EFI_UNSUPPORTED; - } - - return EFI_SUCCESS; -} - -EFI_TPL -EFIAPI -Ring3RaiseTpl ( - IN EFI_TPL NewTpl - ) -{ - return (EFI_TPL)SysCall ( - SysCallRaiseTpl, - NewTpl - ); -} - -VOID -EFIAPI -Ring3RestoreTpl ( - IN EFI_TPL NewTpl - ) -{ - SysCall ( - SysCallRestoreTpl, - NewTpl - ); -} - -EFI_STATUS -EFIAPI -Ring3AllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - IN OUT EFI_PHYSICAL_ADDRESS *Memory - ) -{ - EFI_STATUS Status; - - Status = SysCall ( - SysCallAllocatePages, - Type, - MemoryType, - NumberOfPages, - Memory - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate %d pages.\n", NumberOfPages)); - } - - return Status; -} - -EFI_STATUS -EFIAPI -Ring3FreePages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ) -{ - EFI_STATUS Status; - - Status = SysCall ( - SysCallFreePages, - NumberOfPages, - Memory - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to free %d pages.\n", NumberOfPages)); - } - - return Status; -} - -EFI_STATUS -EFIAPI -Ring3GetMemoryMap ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: GetMemoryMap is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3CreateEvent ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, - IN VOID *NotifyContext OPTIONAL, - OUT EFI_EVENT *Event - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: CreateEvent is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SetTimer ( - IN EFI_EVENT UserEvent, - IN EFI_TIMER_DELAY Type, - IN UINT64 TriggerTime - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SetTimer is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3WaitForEvent ( - IN UINTN NumberOfEvents, - IN EFI_EVENT *UserEvents, - OUT UINTN *UserIndex - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: WaitForEvent is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SignalEvent ( - IN EFI_EVENT UserEvent - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SignalEvent is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3CloseEvent ( - IN EFI_EVENT UserEvent - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: CloseEvent is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3CheckEvent ( - IN EFI_EVENT UserEvent - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: CheckEvent is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3InstallProtocolInterface ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: InstallProtocolInterface is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3ReinstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *OldInterface, - IN VOID *NewInterface - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: ReinstallProtocolInterface is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3UninstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: UninstallProtocolInterface is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3HandleProtocol ( - IN EFI_HANDLE CoreUserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface - ) -{ - EFI_STATUS Status; - - Status = SysCall ( - SysCallHandleProtocol, - CoreUserHandle, - Protocol, - Interface - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to get handle of protocol %g - %r\n", Protocol, Status)); - return Status; - } - - return FixInterface (Protocol, Interface); -} - -EFI_STATUS -EFIAPI -Ring3RegisterProtocolNotify ( - IN EFI_GUID *Protocol, - IN EFI_EVENT Event, - OUT VOID **Registration - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: RegisterProtocolNotify is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3LocateHandle ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *BufferSize, - OUT EFI_HANDLE *Buffer - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: LocateHandle is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3LocateDevicePath ( - IN EFI_GUID *Protocol, - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, - OUT EFI_HANDLE *Device - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: LocateDevicePath is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3InstallConfigurationTable ( - IN EFI_GUID *Guid, - IN VOID *Table - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: InstallConfigurationTable is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3LoadImage ( - IN BOOLEAN BootPolicy, - IN EFI_HANDLE ParentImageHandle, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN VOID *SourceBuffer OPTIONAL, - IN UINTN SourceSize, - OUT EFI_HANDLE *ImageHandle - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: LoadImage is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3StartImage ( - IN EFI_HANDLE ImageHandle, - OUT UINTN *ExitDataSize, - OUT CHAR16 **ExitData OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: StartImage is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3Exit ( - IN EFI_HANDLE ImageHandle, - IN EFI_STATUS Status, - IN UINTN ExitDataSize, - IN CHAR16 *ExitData OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: Exit is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3UnloadImage ( - IN EFI_HANDLE ImageHandle - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: UnloadImage is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3ExitBootServices ( - IN EFI_HANDLE ImageHandle, - IN UINTN MapKey - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: ExitBootServices is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3GetNextMonotonicCount ( - OUT UINT64 *Count - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: GetNextMonotonicCount is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3Stall ( - IN UINTN Microseconds - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: Stall is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SetWatchdogTimer ( - IN UINTN Timeout, - IN UINT64 WatchdogCode, - IN UINTN DataSize, - IN CHAR16 *WatchdogData OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SetWatchdogTimer is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3ConnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE *DriverImageHandle OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, - IN BOOLEAN Recursive - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: ConnectController is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3DisconnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE DriverImageHandle OPTIONAL, - IN EFI_HANDLE ChildHandle OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: DisconnectController is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3OpenProtocol ( - IN EFI_HANDLE CoreUserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface OPTIONAL, - IN EFI_HANDLE CoreImageHandle, - IN EFI_HANDLE CoreControllerHandle, - IN UINT32 Attributes - ) -{ - EFI_STATUS Status; - - Status = SysCall ( - SysCallOpenProtocol, - CoreUserHandle, - Protocol, - Interface, - CoreImageHandle, - CoreControllerHandle, - Attributes - ); - if (EFI_ERROR (Status)) { - return Status; - } - - return (Interface != NULL) ? FixInterface (Protocol, Interface) : Status; -} - -EFI_STATUS -EFIAPI -Ring3CloseProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN EFI_HANDLE AgentHandle, - IN EFI_HANDLE ControllerHandle - ) -{ - return SysCall ( - SysCallCloseProtocol, - UserHandle, - Protocol, - AgentHandle, - ControllerHandle - ); -} - -EFI_STATUS -EFIAPI -Ring3OpenProtocolInformation ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, - OUT UINTN *EntryCount - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: OpenProtocolInformation is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3ProtocolsPerHandle ( - IN EFI_HANDLE UserHandle, - OUT EFI_GUID ***ProtocolBuffer, - OUT UINTN *ProtocolBufferCount - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: ProtocolsPerHandle is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3LocateHandleBuffer ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *NumberHandles, - OUT EFI_HANDLE **Buffer - ) -{ - EFI_STATUS Status; - EFI_STATUS StatusBS; - VOID *Pool; - UINTN PoolSize; - - StatusBS = SysCall ( - SysCallLocateHandleBuffer, - SearchType, - Protocol, - SearchKey, - NumberHandles, - Buffer - ); - - if ((!EFI_ERROR (StatusBS)) && (NumberHandles != NULL) && (*NumberHandles != 0) - && (Buffer != NULL) && (*Buffer != NULL)) { - PoolSize = *NumberHandles * sizeof (EFI_HANDLE *); - - Status = CoreAllocatePool (EfiRing3MemoryType, PoolSize, &Pool); - if (EFI_ERROR (Status)) { - return Status; - } - - CopyMem (Pool, *Buffer, PoolSize); - - Status = Ring3FreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)*Buffer, - EFI_SIZE_TO_PAGES (PoolSize) - ); - if (EFI_ERROR (Status)) { - return Status; - } - - *Buffer = Pool; - } - - return StatusBS; -} - -EFI_STATUS -EFIAPI -Ring3LocateProtocol ( - IN EFI_GUID *Protocol, - IN VOID *CoreRegistration OPTIONAL, - OUT VOID **Interface - ) -{ - EFI_STATUS Status; - - Status = SysCall ( - SysCallLocateProtocol, - Protocol, - CoreRegistration, - Interface - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to loacate protocol %g\n", Protocol)); - return Status; - } - - return FixInterface (Protocol, Interface); -} - -EFI_STATUS -EFIAPI -Ring3InstallMultipleProtocolInterfaces ( - IN OUT EFI_HANDLE *Handle, - ... - ) -{ - VA_LIST Marker; - VOID *Argument; - VOID *ArgList[MAX_LIST]; - UINTN Index; - - VA_START (Marker, Handle); - for (Index = 0; Index < MAX_LIST; ++Index) { - Argument = VA_ARG (Marker, VOID *); - ArgList[Index] = Argument; - - if (Argument == NULL) { - break; - } - } - VA_END (Marker); - - if (Index == MAX_LIST) { - DEBUG ((DEBUG_ERROR, "Ring3: Too many arguments\n")); - return EFI_INVALID_PARAMETER; - } - - return SysCall ( - SysCallInstallMultipleProtocolInterfaces, - Handle, - ArgList - ); -} - -EFI_STATUS -EFIAPI -Ring3UninstallMultipleProtocolInterfaces ( - IN EFI_HANDLE Handle, - ... - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: UninstallMultipleProtocolInterfaces is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3CalculateCrc32 ( - IN VOID *Data, - IN UINTN DataSize, - OUT UINT32 *Crc32 - ) -{ - return SysCall ( - SysCallCalculateCrc32, - Data, - DataSize, - Crc32 - ); -} - -EFI_STATUS -EFIAPI -Ring3CreateEventEx ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, - IN CONST VOID *NotifyContext OPTIONAL, - IN CONST EFI_GUID *EventGroup OPTIONAL, - OUT EFI_EVENT *Event - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: CreateEventEx is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -CoreUpdateProfile ( - IN EFI_PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool - IN VOID *Buffer, - IN CHAR8 *ActionString OPTIONAL - ) -{ - return EFI_SUCCESS; -} - -VOID -InstallMemoryAttributesTableOnMemoryAllocation ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - return; -} - -BOOLEAN -EFIAPI -IsMemoryGuarded ( - IN EFI_PHYSICAL_ADDRESS Address - ) -{ - return FALSE; -} - -VOID * -CoreAllocatePoolPagesI ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN NoPages, - IN UINTN Granularity, - IN BOOLEAN NeedGuard - ) -{ - EFI_PHYSICAL_ADDRESS Memory; - - Ring3AllocatePages (AllocateAnyPages, EfiRing3MemoryType, NoPages, &Memory); - - return (VOID *)(UINTN)Memory; -} - -VOID -CoreFreePoolPagesI ( - IN EFI_MEMORY_TYPE PoolType, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages - ) -{ - Ring3FreePages (Memory, NoPages); -} - -VOID -CoreFreePoolPagesWithGuard ( - IN EFI_MEMORY_TYPE PoolType, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages - ) -{ - CoreFreePoolPagesI (PoolType, Memory, NoPages); -} +/** @file + This driver constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include + +#include + +#include +#include +#include + +#include "Ring3.h" + +BOOLEAN mOnGuarding = FALSE; + +STATIC +EFI_STATUS +EFIAPI +FixInterface ( + IN EFI_GUID *Protocol, + IN OUT VOID **Interface + ) +{ + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_DEVICE_PATH_UTILITIES_PROTOCOL *DevicePath; + EFI_UNICODE_COLLATION_PROTOCOL *Unicode; + + ASSERT (Protocol != NULL); + ASSERT (Interface != NULL); + + if (CompareGuid (Protocol, &gEfiDevicePathProtocolGuid)) { + + } else if (CompareGuid (Protocol, &gEfiLoadedImageProtocolGuid)) { + + LoadedImage = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; + + // TODO: Copy User changes to Core? Resembles InstallMultipleProtocolInterfaces(). + + LoadedImage->Unload = NULL; + + } else if (CompareGuid (Protocol, &gEfiBlockIoProtocolGuid)) { + + BlockIo = (EFI_BLOCK_IO_PROTOCOL *)*Interface; + + BlockIo->Reset = Ring3BlockIoReset; + BlockIo->ReadBlocks = Ring3BlockIoRead; + BlockIo->WriteBlocks = Ring3BlockIoWrite; + BlockIo->FlushBlocks = Ring3BlockIoFlush; + + } else if (CompareGuid (Protocol, &gEfiDiskIoProtocolGuid)) { + + DiskIo = (EFI_DISK_IO_PROTOCOL *)*Interface; + + DiskIo->ReadDisk = Ring3DiskIoRead; + DiskIo->WriteDisk = Ring3DiskIoWrite; + + } else if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { + DevicePath = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; + + DevicePath->GetDevicePathSize = NULL; + DevicePath->DuplicateDevicePath = NULL; + DevicePath->AppendDevicePath = NULL; + DevicePath->AppendDeviceNode = NULL; + DevicePath->AppendDevicePathInstance = NULL; + DevicePath->GetNextDevicePathInstance = NULL; + DevicePath->IsDevicePathMultiInstance = NULL; + DevicePath->CreateDeviceNode = NULL; + + } else if (CompareGuid (Protocol, &gEfiUnicodeCollationProtocolGuid)) { + Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)*Interface; + + Unicode->StriColl = Ring3UnicodeStriColl; + Unicode->MetaiMatch = Ring3UnicodeMetaiMatch; + Unicode->StrLwr = Ring3UnicodeStrLwr; + Unicode->StrUpr = Ring3UnicodeStrUpr; + Unicode->FatToStr = Ring3UnicodeFatToStr; + Unicode->StrToFat = Ring3UnicodeStrToFat; + + } else { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +EFI_TPL +EFIAPI +Ring3RaiseTpl ( + IN EFI_TPL NewTpl + ) +{ + return (EFI_TPL)SysCall ( + SysCallRaiseTpl, + NewTpl + ); +} + +VOID +EFIAPI +Ring3RestoreTpl ( + IN EFI_TPL NewTpl + ) +{ + SysCall ( + SysCallRestoreTpl, + NewTpl + ); +} + +EFI_STATUS +EFIAPI +Ring3AllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ) +{ + EFI_STATUS Status; + + Status = SysCall ( + SysCallAllocatePages, + Type, + MemoryType, + NumberOfPages, + Memory + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate %d pages.\n", NumberOfPages)); + } + + return Status; +} + +EFI_STATUS +EFIAPI +Ring3FreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ) +{ + EFI_STATUS Status; + + Status = SysCall ( + SysCallFreePages, + NumberOfPages, + Memory + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to free %d pages.\n", NumberOfPages)); + } + + return Status; +} + +EFI_STATUS +EFIAPI +Ring3GetMemoryMap ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetMemoryMap is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3CreateEvent ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN VOID *NotifyContext OPTIONAL, + OUT EFI_EVENT *Event + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: CreateEvent is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetTimer ( + IN EFI_EVENT UserEvent, + IN EFI_TIMER_DELAY Type, + IN UINT64 TriggerTime + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetTimer is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3WaitForEvent ( + IN UINTN NumberOfEvents, + IN EFI_EVENT *UserEvents, + OUT UINTN *UserIndex + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: WaitForEvent is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SignalEvent ( + IN EFI_EVENT UserEvent + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SignalEvent is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3CloseEvent ( + IN EFI_EVENT UserEvent + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: CloseEvent is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3CheckEvent ( + IN EFI_EVENT UserEvent + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: CheckEvent is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3InstallProtocolInterface ( + IN OUT EFI_HANDLE *UserHandle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: InstallProtocolInterface is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3ReinstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *OldInterface, + IN VOID *NewInterface + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ReinstallProtocolInterface is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3UninstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: UninstallProtocolInterface is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3HandleProtocol ( + IN EFI_HANDLE CoreUserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ) +{ + EFI_STATUS Status; + + Status = SysCall ( + SysCallHandleProtocol, + CoreUserHandle, + Protocol, + Interface + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to get handle of protocol %g - %r\n", Protocol, Status)); + return Status; + } + + return FixInterface (Protocol, Interface); +} + +EFI_STATUS +EFIAPI +Ring3RegisterProtocolNotify ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: RegisterProtocolNotify is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3LocateHandle ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: LocateHandle is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3LocateDevicePath ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT EFI_HANDLE *Device + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: LocateDevicePath is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3InstallConfigurationTable ( + IN EFI_GUID *Guid, + IN VOID *Table + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: InstallConfigurationTable is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3LoadImage ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: LoadImage is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3StartImage ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: StartImage is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3Exit ( + IN EFI_HANDLE ImageHandle, + IN EFI_STATUS Status, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: Exit is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3UnloadImage ( + IN EFI_HANDLE ImageHandle + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: UnloadImage is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3ExitBootServices ( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ExitBootServices is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3GetNextMonotonicCount ( + OUT UINT64 *Count + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetNextMonotonicCount is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3Stall ( + IN UINTN Microseconds + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: Stall is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetWatchdogTimer ( + IN UINTN Timeout, + IN UINT64 WatchdogCode, + IN UINTN DataSize, + IN CHAR16 *WatchdogData OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetWatchdogTimer is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3ConnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE *DriverImageHandle OPTIONAL, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, + IN BOOLEAN Recursive + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ConnectController is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3DisconnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverImageHandle OPTIONAL, + IN EFI_HANDLE ChildHandle OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: DisconnectController is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3OpenProtocol ( + IN EFI_HANDLE CoreUserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface OPTIONAL, + IN EFI_HANDLE CoreImageHandle, + IN EFI_HANDLE CoreControllerHandle, + IN UINT32 Attributes + ) +{ + EFI_STATUS Status; + + Status = SysCall ( + SysCallOpenProtocol, + CoreUserHandle, + Protocol, + Interface, + CoreImageHandle, + CoreControllerHandle, + Attributes + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return (Interface != NULL) ? FixInterface (Protocol, Interface) : Status; +} + +EFI_STATUS +EFIAPI +Ring3CloseProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN EFI_HANDLE AgentHandle, + IN EFI_HANDLE ControllerHandle + ) +{ + return SysCall ( + SysCallCloseProtocol, + UserHandle, + Protocol, + AgentHandle, + ControllerHandle + ); +} + +EFI_STATUS +EFIAPI +Ring3OpenProtocolInformation ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, + OUT UINTN *EntryCount + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: OpenProtocolInformation is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3ProtocolsPerHandle ( + IN EFI_HANDLE UserHandle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ProtocolsPerHandle is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3LocateHandleBuffer ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer + ) +{ + EFI_STATUS Status; + EFI_STATUS StatusBS; + VOID *Pool; + UINTN PoolSize; + + StatusBS = SysCall ( + SysCallLocateHandleBuffer, + SearchType, + Protocol, + SearchKey, + NumberHandles, + Buffer + ); + + if ((!EFI_ERROR (StatusBS)) && (NumberHandles != NULL) && (*NumberHandles != 0) + && (Buffer != NULL) && (*Buffer != NULL)) { + PoolSize = *NumberHandles * sizeof (EFI_HANDLE *); + + Status = CoreAllocatePool (EfiRing3MemoryType, PoolSize, &Pool); + if (EFI_ERROR (Status)) { + return Status; + } + + CopyMem (Pool, *Buffer, PoolSize); + + Status = Ring3FreePages ( + (EFI_PHYSICAL_ADDRESS)(UINTN)*Buffer, + EFI_SIZE_TO_PAGES (PoolSize) + ); + if (EFI_ERROR (Status)) { + return Status; + } + + *Buffer = Pool; + } + + return StatusBS; +} + +EFI_STATUS +EFIAPI +Ring3LocateProtocol ( + IN EFI_GUID *Protocol, + IN VOID *CoreRegistration OPTIONAL, + OUT VOID **Interface + ) +{ + EFI_STATUS Status; + + Status = SysCall ( + SysCallLocateProtocol, + Protocol, + CoreRegistration, + Interface + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Ring3: Failed to loacate protocol %g\n", Protocol)); + return Status; + } + + return FixInterface (Protocol, Interface); +} + +EFI_STATUS +EFIAPI +Ring3InstallMultipleProtocolInterfaces ( + IN OUT EFI_HANDLE *Handle, + ... + ) +{ + VA_LIST Marker; + VOID *Argument; + VOID *ArgList[MAX_LIST]; + UINTN Index; + + VA_START (Marker, Handle); + for (Index = 0; Index < MAX_LIST; ++Index) { + Argument = VA_ARG (Marker, VOID *); + ArgList[Index] = Argument; + + if (Argument == NULL) { + break; + } + } + VA_END (Marker); + + if (Index == MAX_LIST) { + DEBUG ((DEBUG_ERROR, "Ring3: Too many arguments\n")); + return EFI_INVALID_PARAMETER; + } + + return SysCall ( + SysCallInstallMultipleProtocolInterfaces, + Handle, + ArgList + ); +} + +EFI_STATUS +EFIAPI +Ring3UninstallMultipleProtocolInterfaces ( + IN EFI_HANDLE Handle, + ... + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: UninstallMultipleProtocolInterfaces is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3CalculateCrc32 ( + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 + ) +{ + return SysCall ( + SysCallCalculateCrc32, + Data, + DataSize, + Crc32 + ); +} + +EFI_STATUS +EFIAPI +Ring3CreateEventEx ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN CONST VOID *NotifyContext OPTIONAL, + IN CONST EFI_GUID *EventGroup OPTIONAL, + OUT EFI_EVENT *Event + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: CreateEventEx is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +CoreUpdateProfile ( + IN EFI_PHYSICAL_ADDRESS CallerAddress, + IN MEMORY_PROFILE_ACTION Action, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool + IN VOID *Buffer, + IN CHAR8 *ActionString OPTIONAL + ) +{ + return EFI_SUCCESS; +} + +VOID +InstallMemoryAttributesTableOnMemoryAllocation ( + IN EFI_MEMORY_TYPE MemoryType + ) +{ + return; +} + +BOOLEAN +EFIAPI +IsMemoryGuarded ( + IN EFI_PHYSICAL_ADDRESS Address + ) +{ + return FALSE; +} + +VOID * +CoreAllocatePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN NoPages, + IN UINTN Granularity, + IN BOOLEAN NeedGuard + ) +{ + EFI_PHYSICAL_ADDRESS Memory; + + Ring3AllocatePages (AllocateAnyPages, EfiRing3MemoryType, NoPages, &Memory); + + return (VOID *)(UINTN)Memory; +} + +VOID +CoreFreePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ) +{ + Ring3FreePages (Memory, NoPages); +} + +VOID +CoreFreePoolPagesWithGuard ( + IN EFI_MEMORY_TYPE PoolType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ) +{ + CoreFreePoolPagesI (PoolType, Memory, NoPages); +} diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c index aabd1f1e26..e4e9af3299 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c @@ -1,194 +1,194 @@ -#include - -#include -#include - -#include "Ring3.h" - -EFI_STATUS -EFIAPI -Ring3GetTime ( - OUT EFI_TIME *Time, - OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: GetTime is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SetTime ( - IN EFI_TIME *Time - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SetTime is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3GetWakeupTime ( - OUT BOOLEAN *Enabled, - OUT BOOLEAN *Pending, - OUT EFI_TIME *Time - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: GetWakeupTime is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SetWakeupTime ( - IN BOOLEAN Enable, - IN EFI_TIME *Time OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SetWakeupTime is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SetVirtualAddressMap ( - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN UINT32 DescriptorVersion, - IN EFI_MEMORY_DESCRIPTOR *VirtualMap - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SetVirtualAddressMap is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3ConvertPointer ( - IN UINTN DebugDisposition, - IN OUT VOID **Address - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: ConvertPointer is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3GetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - OUT UINT32 *Attributes OPTIONAL, - IN OUT UINTN *DataSize, - OUT VOID *Data OPTIONAL - ) -{ - return SysCall ( - SysCallGetVariable, - VariableName, - VendorGuid, - Attributes, - DataSize, - Data - ); -} - -EFI_STATUS -EFIAPI -Ring3GetNextVariableName ( - IN OUT UINTN *VariableNameSize, - IN OUT CHAR16 *VariableName, - IN OUT EFI_GUID *VendorGuid - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: GetNextVariableName is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3SetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - IN UINT32 Attributes, - IN UINTN DataSize, - IN VOID *Data - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: SetVariable is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3GetNextHighMonotonicCount ( - OUT UINT32 *HighCount - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: GetNextHighMonotonicCount is not supported\n")); - - return EFI_UNSUPPORTED; -} - -VOID -EFIAPI -Ring3ResetSystem ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: ResetSystem is not supported\n")); - - return; -} - -EFI_STATUS -EFIAPI -Ring3UpdateCapsule ( - IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, - IN UINTN CapsuleCount, - IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: UpdateCapsule is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3QueryCapsuleCapabilities ( - IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, - IN UINTN CapsuleCount, - OUT UINT64 *MaximumCapsuleSize, - OUT EFI_RESET_TYPE *ResetType - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: QueryCapsuleCapabilities is not supported\n")); - - return EFI_UNSUPPORTED; -} - -EFI_STATUS -EFIAPI -Ring3QueryVariableInfo ( - IN UINT32 Attributes, - OUT UINT64 *MaximumVariableStorageSize, - OUT UINT64 *RemainingVariableStorageSize, - OUT UINT64 *MaximumVariableSize - ) -{ - DEBUG ((DEBUG_ERROR, "Ring3: QueryVariableInfo is not supported\n")); - - return EFI_UNSUPPORTED; -} +#include + +#include +#include + +#include "Ring3.h" + +EFI_STATUS +EFIAPI +Ring3GetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetTime is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetTime ( + IN EFI_TIME *Time + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetTime is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3GetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetWakeupTime is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetWakeupTime ( + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetWakeupTime is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetVirtualAddressMap ( + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetVirtualAddressMap is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3ConvertPointer ( + IN UINTN DebugDisposition, + IN OUT VOID **Address + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ConvertPointer is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3GetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data OPTIONAL + ) +{ + return SysCall ( + SysCallGetVariable, + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); +} + +EFI_STATUS +EFIAPI +Ring3GetNextVariableName ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetNextVariableName is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3SetVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: SetVariable is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3GetNextHighMonotonicCount ( + OUT UINT32 *HighCount + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: GetNextHighMonotonicCount is not supported\n")); + + return EFI_UNSUPPORTED; +} + +VOID +EFIAPI +Ring3ResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: ResetSystem is not supported\n")); + + return; +} + +EFI_STATUS +EFIAPI +Ring3UpdateCapsule ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: UpdateCapsule is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3QueryCapsuleCapabilities ( + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + OUT UINT64 *MaximumCapsuleSize, + OUT EFI_RESET_TYPE *ResetType + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: QueryCapsuleCapabilities is not supported\n")); + + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +Ring3QueryVariableInfo ( + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize + ) +{ + DEBUG ((DEBUG_ERROR, "Ring3: QueryVariableInfo is not supported\n")); + + return EFI_UNSUPPORTED; +} diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm index fc27a0bddc..d9c3d1162d 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm @@ -1,44 +1,44 @@ -;------------------------------------------------------------------------------ -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -; SPDX-License-Identifier: BSD-3-Clause -;------------------------------------------------------------------------------ - -extern ASM_PFX(Ring3Call) - -DEFAULT REL -SECTION .text - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; SysCall ( -; IN UINT8 Type, -; ... -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(SysCall) -ASM_PFX(SysCall): - ; Save Type for CoreBootServices(). - mov r10, rcx - - ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. - syscall - ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. - - ret - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; Ring3EntryPoint ( -; IN RING3_CALL_DATA *Data -; ); -; -; (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3(). -; (rdx) Data -;------------------------------------------------------------------------------ -global ASM_PFX(Ring3EntryPoint) -ASM_PFX(Ring3EntryPoint): - mov rcx, rdx - - call ASM_PFX(Ring3Call) +;------------------------------------------------------------------------------ +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +;------------------------------------------------------------------------------ + +extern ASM_PFX(Ring3Call) + +DEFAULT REL +SECTION .text + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; SysCall ( +; IN UINT8 Type, +; ... +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(SysCall) +ASM_PFX(SysCall): + ; Save Type for CoreBootServices(). + mov r10, rcx + + ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. + syscall + ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. + + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; Ring3EntryPoint ( +; IN RING3_CALL_DATA *Data +; ); +; +; (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3(). +; (rdx) Data +;------------------------------------------------------------------------------ +global ASM_PFX(Ring3EntryPoint) +ASM_PFX(Ring3EntryPoint): + mov rcx, rdx + + call ASM_PFX(Ring3Call) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 0e705ddbce..cf6f098b7b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -1,169 +1,169 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause -// -//------------------------------------------------------------------------------ - -#include - -.cpu cortex-a76 - -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// CallInstallMultipleProtocolInterfaces ( -// IN EFI_HANDLE *Handle, -// IN VOID **ArgList, -// IN UINT32 ArgListSize, -// IN VOID *Function -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(CallInstallMultipleProtocolInterfaces) - stp x29, x30, [sp, #-0x10]! - mov x29, sp - // Save function input. - mov x9, x1 - mov x10, x2 - mov x11, x3 - // Prepare registers for call. - ldp x1, x2, [x9] - ldp x3, x4, [x9, #0x10] - ldp x5, x6, [x9, #0x20] - ldr x7, [x9, #0x30] - // Prepare stack for call. - cmp x10, #7 - b.le call - add x9, x9, x10, LSL #3 - sub x10, x10, #7 - tst x10, #1 - b.eq copy - // To align stack on 16 bytes. - add x9, x9, #0x8 - add x10, x10, #1 -copy: - ldp x12, x13, [x9, #-0x10]! - stp x12, x13, [sp, #-0x10]! - subs x10, x10, #2 - b.ne copy - -call: - blr x11 - - mov sp, x29 - ldp x29, x30, [sp] - add sp, sp, #0x10 - ret - -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// CallRing3 ( -// IN RING3_CALL_DATA *Data -// ); -// -// (x0) Data -// (x1) gRing3CallStackTop -// (x2) gRing3EntryPoint -// (x3) gCoreSysCallStackTop -// (x4) &CoreSp -//------------------------------------------------------------------------------ -ASM_FUNC(ArmCallRing3) - // Save registers. - sub sp, sp, #0x100 - - stp q8, q9, [sp, #0xe0] - stp q10, q11, [sp, #0xc0] - stp q12, q13, [sp, #0xa0] - stp q14, q15, [sp, #0x80] - - stp xzr, x16, [sp, #0x70] - stp x17, x18, [sp, #0x60] - stp x19, x20, [sp, #0x50] - stp x21, x22, [sp, #0x40] - stp x23, x24, [sp, #0x30] - stp x25, x26, [sp, #0x20] - stp x27, x28, [sp, #0x10] - stp x29, x30, [sp] - // Disable interrupts. - msr daifset, #0xf - isb - // Prepare Ring3 SP and EntryPoint. - msr sp_el0, x1 - msr elr_el1, x2 - // Save Core SP and switch to CoreSysCall Stack. - mov x5, sp - str x5, [x4] - mov sp, x3 - // Copy PSTATE to SPSR. - mrs x1, nzcv - mrs x2, pan - orr x1, x1, x2 - // - // M[3:0], bits [3:0] AArch64 Exception level and selected Stack Pointer. - // 0b0000 - EL0. - // 0b0100 - EL1 with SP_EL0 (ELt). - // 0b0101 - EL1 with SP_EL1 (EL1h). - // - msr spsr_el1, x1 - isb - dsb sy - eret - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ReturnToCore ( -// IN EFI_STATUS Status, -// IN UINTN CoreSp -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ReturnToCore) - // Zero Exception Syndrome Register to prevent QEMU from random crashing. - msr esr_el1, xzr - msr spsr_el1, xzr - msr elr_el1, xzr - msr far_el1, xzr - // Switch to Core Stack. - mov sp, x1 - // Restore registers and Stack. - ldp q8, q9, [sp, #0xe0] - ldp q10, q11, [sp, #0xc0] - ldp q12, q13, [sp, #0xa0] - ldp q14, q15, [sp, #0x80] - - ldr x16, [sp, #0x78] - ldp x17, x18, [sp, #0x60] - ldp x19, x20, [sp, #0x50] - ldp x21, x22, [sp, #0x40] - ldp x23, x24, [sp, #0x30] - ldp x25, x26, [sp, #0x20] - ldp x27, x28, [sp, #0x10] - ldp x29, x30, [sp] - add sp, sp, #0x100 - // Enable interrupts. - msr daifclr, #0xf - isb - ret - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ArmSetPan ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ArmSetPan) - msr pan, #1 - ret - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ArmClearPan ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ArmClearPan) - msr pan, #0 - ret +//------------------------------------------------------------------------------ +// +// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +//------------------------------------------------------------------------------ + +#include + +.cpu cortex-a76 + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CallInstallMultipleProtocolInterfaces ( +// IN EFI_HANDLE *Handle, +// IN VOID **ArgList, +// IN UINT32 ArgListSize, +// IN VOID *Function +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(CallInstallMultipleProtocolInterfaces) + stp x29, x30, [sp, #-0x10]! + mov x29, sp + // Save function input. + mov x9, x1 + mov x10, x2 + mov x11, x3 + // Prepare registers for call. + ldp x1, x2, [x9] + ldp x3, x4, [x9, #0x10] + ldp x5, x6, [x9, #0x20] + ldr x7, [x9, #0x30] + // Prepare stack for call. + cmp x10, #7 + b.le call + add x9, x9, x10, LSL #3 + sub x10, x10, #7 + tst x10, #1 + b.eq copy + // To align stack on 16 bytes. + add x9, x9, #0x8 + add x10, x10, #1 +copy: + ldp x12, x13, [x9, #-0x10]! + stp x12, x13, [sp, #-0x10]! + subs x10, x10, #2 + b.ne copy + +call: + blr x11 + + mov sp, x29 + ldp x29, x30, [sp] + add sp, sp, #0x10 + ret + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CallRing3 ( +// IN RING3_CALL_DATA *Data +// ); +// +// (x0) Data +// (x1) gRing3CallStackTop +// (x2) gRing3EntryPoint +// (x3) gCoreSysCallStackTop +// (x4) &CoreSp +//------------------------------------------------------------------------------ +ASM_FUNC(ArmCallRing3) + // Save registers. + sub sp, sp, #0x100 + + stp q8, q9, [sp, #0xe0] + stp q10, q11, [sp, #0xc0] + stp q12, q13, [sp, #0xa0] + stp q14, q15, [sp, #0x80] + + stp xzr, x16, [sp, #0x70] + stp x17, x18, [sp, #0x60] + stp x19, x20, [sp, #0x50] + stp x21, x22, [sp, #0x40] + stp x23, x24, [sp, #0x30] + stp x25, x26, [sp, #0x20] + stp x27, x28, [sp, #0x10] + stp x29, x30, [sp] + // Disable interrupts. + msr daifset, #0xf + isb + // Prepare Ring3 SP and EntryPoint. + msr sp_el0, x1 + msr elr_el1, x2 + // Save Core SP and switch to CoreSysCall Stack. + mov x5, sp + str x5, [x4] + mov sp, x3 + // Copy PSTATE to SPSR. + mrs x1, nzcv + mrs x2, pan + orr x1, x1, x2 + // + // M[3:0], bits [3:0] AArch64 Exception level and selected Stack Pointer. + // 0b0000 - EL0. + // 0b0100 - EL1 with SP_EL0 (ELt). + // 0b0101 - EL1 with SP_EL1 (EL1h). + // + msr spsr_el1, x1 + isb + dsb sy + eret + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ReturnToCore ( +// IN EFI_STATUS Status, +// IN UINTN CoreSp +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ReturnToCore) + // Zero Exception Syndrome Register to prevent QEMU from random crashing. + msr esr_el1, xzr + msr spsr_el1, xzr + msr elr_el1, xzr + msr far_el1, xzr + // Switch to Core Stack. + mov sp, x1 + // Restore registers and Stack. + ldp q8, q9, [sp, #0xe0] + ldp q10, q11, [sp, #0xc0] + ldp q12, q13, [sp, #0xa0] + ldp q14, q15, [sp, #0x80] + + ldr x16, [sp, #0x78] + ldp x17, x18, [sp, #0x60] + ldp x19, x20, [sp, #0x50] + ldp x21, x22, [sp, #0x40] + ldp x23, x24, [sp, #0x30] + ldp x25, x26, [sp, #0x20] + ldp x27, x28, [sp, #0x10] + ldp x29, x30, [sp] + add sp, sp, #0x100 + // Enable interrupts. + msr daifclr, #0xf + isb + ret + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ArmSetPan ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ArmSetPan) + msr pan, #1 + ret + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ArmClearPan ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ArmClearPan) + msr pan, #0 + ret diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index f764309f11..21e8bf98dd 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -1,210 +1,210 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include -#include -#include -#include - -#include "DxeMain.h" - -STATIC UINTN mCoreSp; -UINTN gUartBaseAddress; - -EFI_STATUS -EFIAPI -ArmCallRing3 ( - IN RING3_CALL_DATA *Data, - IN VOID *StackPointer, - IN VOID *EntryPoint, - IN VOID *SysCallStack, - IN VOID *CoreStack - ); - -VOID -EFIAPI -ReturnToCore ( - IN EFI_STATUS Status, - IN UINTN CoreSp - ); - -VOID -EFIAPI -ArmSetPan ( - VOID - ); - -VOID -EFIAPI -ArmClearPan ( - VOID - ); - -STATIC -EFI_STATUS -EFIAPI -SysCallBootService ( - IN UINT8 Type, - IN VOID *CoreRbp, - IN VOID *UserRsp - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Physical; - - if (Type == SysCallReturnToCore) { - ReturnToCore (*(EFI_STATUS *)CoreRbp, mCoreSp); - } - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), - &Physical - ); - if (EFI_ERROR (Status)) { - return Status; - } - - DisableSMAP (); - CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)UserRsp, 8 * sizeof (UINTN)); - - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP - ); - EnableSMAP (); - - Status = CallBootService ( - Type, - (CORE_STACK *)CoreRbp, - (RING3_STACK *)(UINTN)Physical - ); - - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - - CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); - - return Status; -} - -VOID -EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries - ) -{ - UINTN Tcr; - UINTN Index; - EARLY_PL011_BASE_ADDRESS *UartBase; - EFI_PHYSICAL_ADDRESS Physical; - EFI_HOB_GENERIC_HEADER *Ring3Hob; - UINT16 HobLength; - EFI_STATUS Status; - // - // If HCR_EL2.NV is 1 and the current Exception level is EL1, - // then EL1 read accesses to the CurrentEL register return a value of 0x2 in bits[3:2]. - // CurrentEL == 1 -> HCR_EL2.NV == 0 - // - // If stage 1 is enabled and stage 1 Base permissions use Direct permissions, - // then GCS access is not permitted and UnprivGCS and PrivGCS are not present. - // - // Disable Hierarchical permissions just in case. - // - Tcr = ArmGetTCR (); - Tcr |= TCR_EL1_HPD0_MASK | TCR_EL1_HPD1_MASK; - ArmSetTCR (Tcr); - // - // Problem 1: Uart is memory maped. - // - for (Index = 0; Index < NumberOfEntries; ++Index) { - if (CompareGuid (&gEfiHobListGuid, &(Table[Index].VendorGuid))) { - UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); - gUartBaseAddress = UartBase->DebugAddress; - // - // Copy Hob into Ring3. - // - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - 1, - &Physical - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Hob.\n")); - ASSERT (FALSE); - } - DEBUG ((DEBUG_ERROR, "UartBaseAddress = %p.\n", gUartBaseAddress)); - - Ring3Hob = (EFI_HOB_GENERIC_HEADER *)(UINTN)Physical; - - HobLength = (UINT16)((sizeof (EFI_HOB_GUID_TYPE) + sizeof (EARLY_PL011_BASE_ADDRESS) + 0x7) & (~0x7)); - - Ring3Hob->HobType = EFI_HOB_TYPE_GUID_EXTENSION; - Ring3Hob->HobLength = HobLength; - Ring3Hob->Reserved = 0; - - CopyGuid (&((EFI_HOB_GUID_TYPE *)Ring3Hob)->Name, &gEarlyPL011BaseAddressGuid); - - Ring3Hob = (EFI_HOB_GENERIC_HEADER *)((UINTN)Ring3Hob + HobLength); - - Ring3Hob->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; - Ring3Hob->HobLength = sizeof (EFI_HOB_GENERIC_HEADER); - Ring3Hob->Reserved = 0; - - Table[Index].VendorTable = (VOID *)(UINTN)Physical; - UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); - UartBase->DebugAddress = gUartBaseAddress; - } - } - - if (ArmHasPan ()) { - // - // Enable Privileged Access Never feature. - // - ArmSetPan (); - } - - InitializeSysCallHandler ((VOID *)SysCallBootService); -} - -VOID -EFIAPI -DisableSMAP ( - VOID - ) -{ - if (ArmHasPan ()) { - ArmClearPan (); - } -} - -VOID -EFIAPI -EnableSMAP ( - VOID - ) -{ - if (ArmHasPan ()) { - ArmSetPan (); - } -} - -EFI_STATUS -EFIAPI -CallRing3 ( - IN RING3_CALL_DATA *Data - ) -{ - return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp); -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include +#include +#include +#include + +#include "DxeMain.h" + +STATIC UINTN mCoreSp; +UINTN gUartBaseAddress; + +EFI_STATUS +EFIAPI +ArmCallRing3 ( + IN RING3_CALL_DATA *Data, + IN VOID *StackPointer, + IN VOID *EntryPoint, + IN VOID *SysCallStack, + IN VOID *CoreStack + ); + +VOID +EFIAPI +ReturnToCore ( + IN EFI_STATUS Status, + IN UINTN CoreSp + ); + +VOID +EFIAPI +ArmSetPan ( + VOID + ); + +VOID +EFIAPI +ArmClearPan ( + VOID + ); + +STATIC +EFI_STATUS +EFIAPI +SysCallBootService ( + IN UINT8 Type, + IN VOID *CoreRbp, + IN VOID *UserRsp + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Physical; + + if (Type == SysCallReturnToCore) { + ReturnToCore (*(EFI_STATUS *)CoreRbp, mCoreSp); + } + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), + &Physical + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DisableSMAP (); + CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)UserRsp, 8 * sizeof (UINTN)); + + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP + ); + EnableSMAP (); + + Status = CallBootService ( + Type, + (CORE_STACK *)CoreRbp, + (RING3_STACK *)(UINTN)Physical + ); + + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); + + return Status; +} + +VOID +EFIAPI +InitializeMsr ( + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries + ) +{ + UINTN Tcr; + UINTN Index; + EARLY_PL011_BASE_ADDRESS *UartBase; + EFI_PHYSICAL_ADDRESS Physical; + EFI_HOB_GENERIC_HEADER *Ring3Hob; + UINT16 HobLength; + EFI_STATUS Status; + // + // If HCR_EL2.NV is 1 and the current Exception level is EL1, + // then EL1 read accesses to the CurrentEL register return a value of 0x2 in bits[3:2]. + // CurrentEL == 1 -> HCR_EL2.NV == 0 + // + // If stage 1 is enabled and stage 1 Base permissions use Direct permissions, + // then GCS access is not permitted and UnprivGCS and PrivGCS are not present. + // + // Disable Hierarchical permissions just in case. + // + Tcr = ArmGetTCR (); + Tcr |= TCR_EL1_HPD0_MASK | TCR_EL1_HPD1_MASK; + ArmSetTCR (Tcr); + // + // Problem 1: Uart is memory maped. + // + for (Index = 0; Index < NumberOfEntries; ++Index) { + if (CompareGuid (&gEfiHobListGuid, &(Table[Index].VendorGuid))) { + UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); + gUartBaseAddress = UartBase->DebugAddress; + // + // Copy Hob into Ring3. + // + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + 1, + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Hob.\n")); + ASSERT (FALSE); + } + DEBUG ((DEBUG_ERROR, "UartBaseAddress = %p.\n", gUartBaseAddress)); + + Ring3Hob = (EFI_HOB_GENERIC_HEADER *)(UINTN)Physical; + + HobLength = (UINT16)((sizeof (EFI_HOB_GUID_TYPE) + sizeof (EARLY_PL011_BASE_ADDRESS) + 0x7) & (~0x7)); + + Ring3Hob->HobType = EFI_HOB_TYPE_GUID_EXTENSION; + Ring3Hob->HobLength = HobLength; + Ring3Hob->Reserved = 0; + + CopyGuid (&((EFI_HOB_GUID_TYPE *)Ring3Hob)->Name, &gEarlyPL011BaseAddressGuid); + + Ring3Hob = (EFI_HOB_GENERIC_HEADER *)((UINTN)Ring3Hob + HobLength); + + Ring3Hob->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; + Ring3Hob->HobLength = sizeof (EFI_HOB_GENERIC_HEADER); + Ring3Hob->Reserved = 0; + + Table[Index].VendorTable = (VOID *)(UINTN)Physical; + UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); + UartBase->DebugAddress = gUartBaseAddress; + } + } + + if (ArmHasPan ()) { + // + // Enable Privileged Access Never feature. + // + ArmSetPan (); + } + + InitializeSysCallHandler ((VOID *)SysCallBootService); +} + +VOID +EFIAPI +DisableSMAP ( + VOID + ) +{ + if (ArmHasPan ()) { + ArmClearPan (); + } +} + +VOID +EFIAPI +EnableSMAP ( + VOID + ) +{ + if (ArmHasPan ()) { + ArmSetPan (); + } +} + +EFI_STATUS +EFIAPI +CallRing3 ( + IN RING3_CALL_DATA *Data + ) +{ + return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp); +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 0804cf453f..4596465672 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -1,148 +1,148 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -// SPDX-License-Identifier: BSD-3-Clause -// -//------------------------------------------------------------------------------ - -#include - -.arch armv8.1a - -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// CallInstallMultipleProtocolInterfaces ( -// IN EFI_HANDLE *Handle, -// IN VOID **ArgList, -// IN UINT32 ArgListSize, -// IN VOID *Function -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(CallInstallMultipleProtocolInterfaces) - push {R4-R8, LR} - mov R7, SP - // Save function input. - mov R4, R3 - mov R5, R1 - mov R6, R2 - // Prepare registers for call. - ldmfd R5, {R1-R3} - // Prepare stack for call. - cmp R6, #3 - ble call - - add R5, R5, R6, LSL #2 - sub R6, R6, #3 - tst R6, #1 - beq copy - // To align stack on 8 bytes. - add R5, R5, #0x4 - add R6, R6, #1 -copy: - sub R5, R5, #0x4 - ldmfd R5, {R8} - push {R8} - subs R6, R6, #1 - bne copy - -call: - blx R4 - - mov SP, R7 - pop {R4-R8, LR} - bx LR - -//------------------------------------------------------------------------------ -// EFI_STATUS -// EFIAPI -// CallRing3 ( -// IN RING3_CALL_DATA *Data -// ); -// -// (r0) Data -// (r1) gRing3CallStackTop -// (r2) gRing3EntryPoint -// (r3) gCoreSysCallStackTop -// -// (On Core Stack) &CoreSp -//------------------------------------------------------------------------------ -ASM_FUNC(ArmCallRing3) - // Save registers. - push {R4-R12, LR} - // R6 is &CoreSp - ldr R6, [SP, #0x28] - +//------------------------------------------------------------------------------ +// +// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// SPDX-License-Identifier: BSD-3-Clause +// +//------------------------------------------------------------------------------ + +#include + +.arch armv8.1a + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CallInstallMultipleProtocolInterfaces ( +// IN EFI_HANDLE *Handle, +// IN VOID **ArgList, +// IN UINT32 ArgListSize, +// IN VOID *Function +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(CallInstallMultipleProtocolInterfaces) + push {R4-R8, LR} + mov R7, SP + // Save function input. + mov R4, R3 + mov R5, R1 + mov R6, R2 + // Prepare registers for call. + ldmfd R5, {R1-R3} + // Prepare stack for call. + cmp R6, #3 + ble call + + add R5, R5, R6, LSL #2 + sub R6, R6, #3 + tst R6, #1 + beq copy + // To align stack on 8 bytes. + add R5, R5, #0x4 + add R6, R6, #1 +copy: + sub R5, R5, #0x4 + ldmfd R5, {R8} + push {R8} + subs R6, R6, #1 + bne copy + +call: + blx R4 + + mov SP, R7 + pop {R4-R8, LR} + bx LR + +//------------------------------------------------------------------------------ +// EFI_STATUS +// EFIAPI +// CallRing3 ( +// IN RING3_CALL_DATA *Data +// ); +// +// (r0) Data +// (r1) gRing3CallStackTop +// (r2) gRing3EntryPoint +// (r3) gCoreSysCallStackTop +// +// (On Core Stack) &CoreSp +//------------------------------------------------------------------------------ +ASM_FUNC(ArmCallRing3) + // Save registers. + push {R4-R12, LR} + // R6 is &CoreSp + ldr R6, [SP, #0x28] + #if (FixedPcdGet32(PcdVFPEnabled)) // Save vstm registers in case they are used in optimizations. vpush {d0-d15} #endif - - // Disable interrupts. - mrs R4, CPSR - cpsid if - isb - - // Set SP_usr to gRing3CallStackTop. - push {R1} - mov R1, SP - ldmia R1, {SP}^ - pop {R1} - // Set SPSR M[3:0] bits to User mode. - and R4, R4, #0xFFFFFFF0 - - // Save Core SP and switch to CoreSysCall Stack. - mov R5, SP - str R5, [R6] - mov SP, R3 - - push {R4} - push {R2} - rfefd SP - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ReturnToCore ( -// IN EFI_STATUS Status, -// IN UINTN CoreSp -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ReturnToCore) - // Switch to Core Stack. - mov SP, R1 - - // Restore registers and Stack. + + // Disable interrupts. + mrs R4, CPSR + cpsid if + isb + + // Set SP_usr to gRing3CallStackTop. + push {R1} + mov R1, SP + ldmia R1, {SP}^ + pop {R1} + // Set SPSR M[3:0] bits to User mode. + and R4, R4, #0xFFFFFFF0 + + // Save Core SP and switch to CoreSysCall Stack. + mov R5, SP + str R5, [R6] + mov SP, R3 + + push {R4} + push {R2} + rfefd SP + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ReturnToCore ( +// IN EFI_STATUS Status, +// IN UINTN CoreSp +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ReturnToCore) + // Switch to Core Stack. + mov SP, R1 + + // Restore registers and Stack. #if (FixedPcdGet32(PcdVFPEnabled)) vpop {d0-d15} #endif - - pop {R4-R12, LR} - - // Enable interrupts. - cpsie if - isb - - bx LR - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ArmSetPan ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ArmSetPan) - setpan #1 - bx LR - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ArmClearPan ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ArmClearPan) - setpan #0 - bx LR + + pop {R4-R12, LR} + + // Enable interrupts. + cpsie if + isb + + bx LR + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ArmSetPan ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ArmSetPan) + setpan #1 + bx LR + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// ArmClearPan ( +// VOID +// ); +//------------------------------------------------------------------------------ +ASM_FUNC(ArmClearPan) + setpan #0 + bx LR diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index 79ca473028..8ab94b67d7 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -1,145 +1,145 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include -#include - -#include "DxeMain.h" - -STATIC UINTN mCoreSp; - -EFI_STATUS -EFIAPI -ArmCallRing3 ( - IN RING3_CALL_DATA *Data, - IN VOID *StackPointer, - IN VOID *EntryPoint, - IN VOID *SysCallStack, - IN VOID *CoreStack - ); - -VOID -EFIAPI -ReturnToCore ( - IN EFI_STATUS Status, - IN UINTN CoreSp - ); - -VOID -EFIAPI -ArmSetPan ( - VOID - ); - -VOID -EFIAPI -ArmClearPan ( - VOID - ); - -STATIC -EFI_STATUS -EFIAPI -SysCallBootService ( - IN UINT8 Type, - IN VOID *CoreRbp, - IN VOID *UserRsp - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Physical; - - if (Type == SysCallReturnToCore) { - ReturnToCore (*(EFI_STATUS *)CoreRbp, mCoreSp); - } - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), - &Physical - ); - if (EFI_ERROR (Status)) { - return Status; - } - - DisableSMAP (); - // - // First 3 arguments are passed through R1-R3 and copied to SysCall Stack. - // - CopyMem ((VOID *)((UINTN)Physical + 2 * sizeof (UINTN)), (VOID *)CoreRbp, 3 * sizeof (UINTN)); - // - // All remaining arguments are on User Stack. - // - CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN)); - EnableSMAP (); - - Status = CallBootService ( - Type, - (CORE_STACK *)CoreRbp, - (RING3_STACK *)(UINTN)Physical - ); - - CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); - - return Status; -} - -VOID -EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries - ) -{ - // - // TODO: EFI_CONFIGURATION_TABLE, HOB_DATA, Uart are accessible to User. - // Fix PageTable initialization. - // - if (ArmHasPan ()) { - // - // Enable Privileged Access Never feature. - // - ArmSetPan (); - } - - InitializeSysCallHandler (SysCallBootService); -} - -// -// TODO: Refactoring. -// -VOID -EFIAPI -DisableSMAP ( - VOID - ) -{ - if (ArmHasPan ()) { - ArmClearPan (); - } -} - -VOID -EFIAPI -EnableSMAP ( - VOID - ) -{ - if (ArmHasPan ()) { - ArmSetPan (); - } -} - -EFI_STATUS -EFIAPI -CallRing3 ( - IN RING3_CALL_DATA *Data - ) -{ - return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp); -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include +#include + +#include "DxeMain.h" + +STATIC UINTN mCoreSp; + +EFI_STATUS +EFIAPI +ArmCallRing3 ( + IN RING3_CALL_DATA *Data, + IN VOID *StackPointer, + IN VOID *EntryPoint, + IN VOID *SysCallStack, + IN VOID *CoreStack + ); + +VOID +EFIAPI +ReturnToCore ( + IN EFI_STATUS Status, + IN UINTN CoreSp + ); + +VOID +EFIAPI +ArmSetPan ( + VOID + ); + +VOID +EFIAPI +ArmClearPan ( + VOID + ); + +STATIC +EFI_STATUS +EFIAPI +SysCallBootService ( + IN UINT8 Type, + IN VOID *CoreRbp, + IN VOID *UserRsp + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Physical; + + if (Type == SysCallReturnToCore) { + ReturnToCore (*(EFI_STATUS *)CoreRbp, mCoreSp); + } + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), + &Physical + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DisableSMAP (); + // + // First 3 arguments are passed through R1-R3 and copied to SysCall Stack. + // + CopyMem ((VOID *)((UINTN)Physical + 2 * sizeof (UINTN)), (VOID *)CoreRbp, 3 * sizeof (UINTN)); + // + // All remaining arguments are on User Stack. + // + CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN)); + EnableSMAP (); + + Status = CallBootService ( + Type, + (CORE_STACK *)CoreRbp, + (RING3_STACK *)(UINTN)Physical + ); + + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); + + return Status; +} + +VOID +EFIAPI +InitializeMsr ( + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries + ) +{ + // + // TODO: EFI_CONFIGURATION_TABLE, HOB_DATA, Uart are accessible to User. + // Fix PageTable initialization. + // + if (ArmHasPan ()) { + // + // Enable Privileged Access Never feature. + // + ArmSetPan (); + } + + InitializeSysCallHandler (SysCallBootService); +} + +// +// TODO: Refactoring. +// +VOID +EFIAPI +DisableSMAP ( + VOID + ) +{ + if (ArmHasPan ()) { + ArmClearPan (); + } +} + +VOID +EFIAPI +EnableSMAP ( + VOID + ) +{ + if (ArmHasPan ()) { + ArmSetPan (); + } +} + +EFI_STATUS +EFIAPI +CallRing3 ( + IN RING3_CALL_DATA *Data + ) +{ + return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp); +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 9b6b82f5c7..e729c3c10f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -1,1434 +1,1434 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include "DxeMain.h" -#include "SupportedProtocols.h" - -LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead); - -typedef struct { - VOID *Core; - VOID *Ring3; - LIST_ENTRY Link; -} INTERFACE; - -UINTN mRing3InterfacePointer = 0; - -CHAR8 *SysCallNames[] = { - // - // BootServices - // - "SysCallReturnToCore", // Must always be zero for CoreBootServices.nasm. - "SysCallLocateProtocol", - "SysCallOpenProtocol", - "SysCallInstallMultipleProtocolInterfaces", - "SysCallCloseProtocol", - "SysCallHandleProtocol", - "SysCallAllocatePages", - "SysCallFreePages", - "SysCallRaiseTpl", - "SysCallRestoreTpl", - "SysCallLocateHandleBuffer", - "SysCallCalculateCrc32", - // - // RuntimeServices - // - "SysCallGetVariable", - // - // Protocols - // - "SysCallBlockIoReset", - "SysCallBlockIoRead", - "SysCallBlockIoWrite", - "SysCallBlockIoFlush", - "SysCallDiskIoRead", - "SysCallDiskIoWrite", - "SysCallUnicodeStriColl", - "SysCallUnicodeMetaiMatch", - "SysCallUnicodeStrLwr", - "SysCallUnicodeStrUpr", - "SysCallUnicodeFatToStr", - "SysCallUnicodeStrToFat", - "SysCallMax" -}; - -EFI_STATUS -EFIAPI -CallInstallMultipleProtocolInterfaces ( - IN EFI_HANDLE *Handle, - IN VOID **ArgList, - IN UINT32 ArgListSize, - IN VOID *Function - ); - -VOID -EFIAPI -FreeProtocolsList ( - VOID - ) -{ - LIST_ENTRY *Link; - INTERFACE *Protocol; - - for (Link = mProtocolsHead.BackLink; Link != &mProtocolsHead; Link = mProtocolsHead.BackLink) { - Protocol = BASE_CR (Link, INTERFACE, Link); - RemoveEntryList (Link); - FreePool (Protocol); - } -} - -STATIC -EFI_STATUS -EFIAPI -FindGuid ( - IN EFI_GUID *Ring3, - OUT EFI_GUID **Core, - OUT UINT32 *CoreSize - ) -{ - ASSERT (Ring3 != NULL); - ASSERT (Core != NULL); - ASSERT (CoreSize != NULL); - - if (CompareGuid (Ring3, &gEfiDevicePathUtilitiesProtocolGuid)) { - - *Core = &gEfiDevicePathUtilitiesProtocolGuid; - *CoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiLoadedImageProtocolGuid)) { - - *Core = &gEfiLoadedImageProtocolGuid; - *CoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiBlockIoProtocolGuid)) { - - *Core = &gEfiBlockIoProtocolGuid; - *CoreSize = sizeof (EFI_BLOCK_IO_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiDiskIoProtocolGuid)) { - - *Core = &gEfiDiskIoProtocolGuid; - *CoreSize = sizeof (EFI_DISK_IO_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiDriverBindingProtocolGuid)) { - - *Core = &gEfiDriverBindingProtocolGuid; - *CoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiComponentNameProtocolGuid)) { - - *Core = &gEfiComponentNameProtocolGuid; - *CoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiComponentName2ProtocolGuid)) { - - *Core = &gEfiComponentName2ProtocolGuid; - *CoreSize = sizeof (EFI_COMPONENT_NAME2_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiDevicePathProtocolGuid)) { - - *Core = &gEfiDevicePathProtocolGuid; - *CoreSize = sizeof (EFI_DEVICE_PATH_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiSimpleFileSystemProtocolGuid)) { - - *Core = &gEfiSimpleFileSystemProtocolGuid; - *CoreSize = sizeof (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiUnicodeCollationProtocolGuid)) { - - *Core = &gEfiUnicodeCollationProtocolGuid; - *CoreSize = sizeof (EFI_UNICODE_COLLATION_PROTOCOL); - - } else if (CompareGuid (Ring3, &gEfiGlobalVariableGuid)) { - - *Core = &gEfiGlobalVariableGuid; - - } else { - DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol - %g.\n", Ring3)); - return EFI_NOT_FOUND; - } - - return EFI_SUCCESS; -} - -STATIC -VOID * -EFIAPI -FindInterface ( - IN BOOLEAN FindRing3, - IN VOID *Interface - ) -{ - LIST_ENTRY *Link; - INTERFACE *Protocol; - - for (Link = mProtocolsHead.ForwardLink; Link != &mProtocolsHead; Link = Link->ForwardLink) { - Protocol = BASE_CR (Link, INTERFACE, Link); - - if (FindRing3) { - if (Protocol->Core == Interface) { - return Protocol->Ring3; - } - } else { - if (Protocol->Ring3 == Interface) { - return Protocol->Core; - } - } - } - - return NULL; -} - -STATIC -VOID * -EFIAPI -PrepareRing3Interface ( - IN EFI_GUID *Guid, - IN VOID *CoreInterface, - IN UINT32 CoreSize - ) -{ - EFI_STATUS Status; - UINTN Ring3Limit; - VOID *Ring3Interface; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_UNICODE_COLLATION_PROTOCOL *Unicode; - INTERFACE *Protocol; - - ASSERT (Guid != NULL); - ASSERT (CoreInterface != NULL); - - if (mRing3InterfacePointer == 0) { - mRing3InterfacePointer = (UINTN)gRing3Interfaces; - } - - Ring3Interface = FindInterface (TRUE, CoreInterface); - - if (Ring3Interface != NULL) { - return Ring3Interface; - } - - Ring3Limit = (UINTN)gRing3Interfaces + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES); - - ASSERT ((mRing3InterfacePointer + CoreSize) <= Ring3Limit); - - Ring3Interface = (VOID *)mRing3InterfacePointer; - - CopyMem ((VOID *)mRing3InterfacePointer, CoreInterface, CoreSize); - mRing3InterfacePointer += CoreSize; - - Protocol = AllocatePool (sizeof (INTERFACE)); - - Protocol->Core = CoreInterface; - Protocol->Ring3 = Ring3Interface; - - InsertTailList (&mProtocolsHead, &Protocol->Link); - - if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) { - ASSERT ((mRing3InterfacePointer + sizeof (EFI_BLOCK_IO_MEDIA)) <= Ring3Limit); - - BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Ring3Interface; - - CopyMem ((VOID *)mRing3InterfacePointer, (VOID *)BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA)); - - BlockIo->Media = (EFI_BLOCK_IO_MEDIA *)mRing3InterfacePointer; - - mRing3InterfacePointer += sizeof (EFI_BLOCK_IO_MEDIA); - } else if (CompareGuid (Guid, &gEfiUnicodeCollationProtocolGuid)) { - - Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)Ring3Interface; - - ASSERT ((mRing3InterfacePointer + AsciiStrSize (Unicode->SupportedLanguages)) <= Ring3Limit); - - Status = AsciiStrCpyS ( - (CHAR8 *)mRing3InterfacePointer, - AsciiStrSize (Unicode->SupportedLanguages), - Unicode->SupportedLanguages - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Could not copy string!\n")); - return NULL; - } - - Unicode->SupportedLanguages = (CHAR8 *)mRing3InterfacePointer; - - mRing3InterfacePointer += AsciiStrSize (Unicode->SupportedLanguages); - } - - return Ring3Interface; -} - -// -// Stack: -// rsp - User Rsp -// rbp - User Rbp -// rcx - User Rip for SYSCALL -// r11 - User RFLAGS for SYSCALL -// r9 - Argument 3 -// r8 - Argument 2 -// rdx - Argument 1 <- CoreRbp -// -EFI_STATUS -EFIAPI -CallBootService ( - IN UINT8 Type, - IN CORE_STACK *CoreRbp, - IN RING3_STACK *UserRsp - ) -{ - EFI_STATUS Status; - EFI_STATUS StatusBS; - UINT64 Attributes; - VOID *Interface; - EFI_GUID *CoreProtocol; - UINT32 MemoryCoreSize; - UINTN Argument4; - UINTN Argument5; - UINTN Argument6; - UINT32 Index; - VOID **UserArgList; - VOID *CoreArgList[MAX_LIST]; - EFI_HANDLE CoreHandle; - UINT32 PagesNumber; - EFI_PHYSICAL_ADDRESS Ring3Pages; - - EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem; - - EFI_BLOCK_IO_PROTOCOL *BlockIo; - EFI_DISK_IO_PROTOCOL *DiskIo; - EFI_UNICODE_COLLATION_PROTOCOL *Unicode; - - CoreProtocol = NULL; - Argument4 = 0; - Argument5 = 0; - Argument6 = 0; - Interface = NULL; - // - // Check User variables. - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserRsp, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DEBUG ((DEBUG_VERBOSE, "Type: %a\n", SysCallNames[Type])); - - switch (Type) { - case SysCallLocateProtocol: - // - // Argument 1: EFI_GUID *Protocol - // Argument 2: VOID *CoreRegistration - // Argument 3: VOID **Interface - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument1, &CoreProtocol, &MemoryCoreSize); - EnableSMAP (); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = gBS->LocateProtocol ( - CoreProtocol, - (VOID *)CoreRbp->Argument2, - &Interface - ); - - DisableSMAP (); - if (Interface != NULL) { - Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); - ASSERT (Interface != NULL); - - *(VOID **)CoreRbp->Argument3 = Interface; - } - EnableSMAP (); - - return Status; - - case SysCallOpenProtocol: - // - // Argument 1: EFI_HANDLE CoreUserHandle - // Argument 2: EFI_GUID *Protocol - // Argument 3: VOID **Interface OPTIONAL - // Argument 4: EFI_HANDLE CoreImageHandle - // Argument 5: EFI_HANDLE CoreControllerHandle - // Argument 6: UINT32 Attributes - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - if ((VOID **)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - } - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); - if (EFI_ERROR (Status)) { - EnableSMAP (); - return Status; - } - - Argument4 = UserRsp->Arguments[4]; - Argument5 = UserRsp->Arguments[5]; - Argument6 = UserRsp->Arguments[6]; - EnableSMAP (); - - Status = gBS->OpenProtocol ( - (EFI_HANDLE)CoreRbp->Argument1, - CoreProtocol, - ((VOID **)CoreRbp->Argument3 != NULL) ? &Interface : NULL, - (EFI_HANDLE)Argument4, - (EFI_HANDLE)Argument5, - (UINT32)Argument6 - ); - - if ((VOID **)CoreRbp->Argument3 != NULL) { - DisableSMAP (); - if (Interface != NULL) { - Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); - } - - *(VOID **)CoreRbp->Argument3 = Interface; - EnableSMAP (); - } - - return Status; - - case SysCallInstallMultipleProtocolInterfaces: - // - // Argument 1: EFI_HANDLE *Handle - // ... - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + sizeof (EFI_HANDLE *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (VOID **) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - CoreHandle = *(EFI_HANDLE *)CoreRbp->Argument1; - UserArgList = (VOID **)CoreRbp->Argument2; - - for (Index = 0; UserArgList[Index] != NULL; Index += 2) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArgList[Index], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArgList[Index] + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Status = FindGuid ((EFI_GUID *)UserArgList[Index], (EFI_GUID **)&CoreArgList[Index], &MemoryCoreSize); - if (EFI_ERROR (Status)) { - EnableSMAP (); - - while (Index > 0) { - FreePool (CoreArgList[Index - 1]); - Index -= 2; - } - - return Status; - } - - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArgList[Index + 1], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArgList[Index + 1] + MemoryCoreSize - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - CoreArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index + 1]); - - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] + sizeof (VOID *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - } - EnableSMAP (); - - ASSERT (Index < MAX_LIST); - CoreArgList[Index] = NULL; - - for (Index = 0; CoreArgList[Index] != NULL; Index += 2) { - if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiDriverBindingProtocolGuid)) { - CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)CoreArgList[Index + 1]; - - mRing3DriverBindingProtocol.Supported = CoreDriverBinding->Supported; - mRing3DriverBindingProtocol.Start = CoreDriverBinding->Start; - mRing3DriverBindingProtocol.Stop = CoreDriverBinding->Stop; - - CoreDriverBinding->Supported = CoreDriverBindingSupported; - CoreDriverBinding->Start = CoreDriverBindingStart; - CoreDriverBinding->Stop = CoreDriverBindingStop; - } else if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiSimpleFileSystemProtocolGuid)) { - CoreSimpleFileSystem = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)CoreArgList[Index + 1]; - - mRing3SimpleFileSystemProtocol.OpenVolume = CoreSimpleFileSystem->OpenVolume; - - CoreSimpleFileSystem->OpenVolume = CoreOpenVolume; - - DisableSMAP (); - mRing3SimpleFileSystemPointer = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)UserArgList[Index + 1]; - EnableSMAP (); - } - } - - Status = CallInstallMultipleProtocolInterfaces ( - &CoreHandle, - CoreArgList, - Index + 1, - (VOID *)gBS->InstallMultipleProtocolInterfaces - ); - - return Status; - - case SysCallCloseProtocol: - // - // Argument 1: EFI_HANDLE CoreUserHandle - // Argument 2: EFI_GUID *Protocol - // Argument 3: EFI_HANDLE CoreAgentHandle - // Argument 4: EFI_HANDLE CoreControllerHandle - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); - if (EFI_ERROR (Status)) { - EnableSMAP (); - return Status; - } - - Argument4 = UserRsp->Arguments[4]; - EnableSMAP (); - - Status = gBS->CloseProtocol ( - (EFI_HANDLE)CoreRbp->Argument1, - CoreProtocol, - (EFI_HANDLE)CoreRbp->Argument3, - (EFI_HANDLE)Argument4 - ); - - return Status; - - case SysCallHandleProtocol: - // - // Argument 1: EFI_HANDLE CoreUserHandle - // Argument 2: EFI_GUID *Protocol - // Argument 3: VOID **Interface - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); - EnableSMAP (); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = gBS->HandleProtocol ( - (EFI_HANDLE)CoreRbp->Argument1, - CoreProtocol, - &Interface - ); - - DisableSMAP (); - if (Interface != NULL) { - Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); - ASSERT (Interface != NULL); - - *(VOID **)CoreRbp->Argument3 = Interface; - } - EnableSMAP (); - - return Status; - - case SysCallAllocatePages: - // - // Argument 1: EFI_ALLOCATE_TYPE Type - // Argument 2: EFI_MEMORY_TYPE MemoryType - // Argument 3: UINTN NumberOfPages - // Argument 4: EFI_PHYSICAL_ADDRESS *Memory - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Status = gBS->AllocatePages ( - (EFI_ALLOCATE_TYPE)CoreRbp->Argument1, - (EFI_MEMORY_TYPE)CoreRbp->Argument2, - CoreRbp->Argument3, - (EFI_PHYSICAL_ADDRESS *)&Argument4 - ); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + sizeof (EFI_PHYSICAL_ADDRESS) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - *(EFI_PHYSICAL_ADDRESS *)UserRsp->Arguments[4] = (EFI_PHYSICAL_ADDRESS)Argument4; - EnableSMAP (); - - return Status; - - case SysCallFreePages: - // - // Argument 1: UINTN NumberOfPages - // Argument 2: EFI_PHYSICAL_ADDRESS Memory - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + CoreRbp->Argument1 * EFI_PAGE_SIZE - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - return gBS->FreePages ( - *(EFI_PHYSICAL_ADDRESS *)&CoreRbp->Argument2, - CoreRbp->Argument1 - ); - - case SysCallRaiseTpl: - // - // Argument 1: EFI_TPL NewTpl - // - return (EFI_STATUS)gBS->RaiseTPL ( - (EFI_TPL)CoreRbp->Argument1 - ); - - case SysCallRestoreTpl: - // - // Argument 1: EFI_TPL NewTpl - // - gBS->RestoreTPL ((EFI_TPL)CoreRbp->Argument1); - - return EFI_SUCCESS; - - case SysCallLocateHandleBuffer: - // - // Argument 1: EFI_LOCATE_SEARCH_TYPE SearchType - // Argument 2: EFI_GUID *Protocol OPTIONAL - // Argument 3: VOID *SearchKey OPTIONAL - // Argument 4: UINTN *NumberHandles - // Argument 5: EFI_HANDLE **Buffer - // - if ((EFI_GUID *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); - EnableSMAP (); - if (EFI_ERROR (Status)) { - return Status; - } - } - - StatusBS = gBS->LocateHandleBuffer ( - (EFI_LOCATE_SEARCH_TYPE)CoreRbp->Argument1, - CoreProtocol, - (VOID *)CoreRbp->Argument3, - &Argument4, - (EFI_HANDLE **)&Argument5 - ); - - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - if ((UINTN *)UserRsp->Arguments[4] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - *(UINTN *)UserRsp->Arguments[4] = Argument4; - } - - if ((EFI_HANDLE **)UserRsp->Arguments[5] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + sizeof (EFI_HANDLE *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (Argument4 * sizeof (EFI_HANDLE *)); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - PagesNumber, - &Ring3Pages - ); - if (EFI_ERROR (Status)) { - return Status; - } - - CopyMem ((VOID *)(UINTN)Ring3Pages, (VOID *)Argument5, Argument4 * sizeof (EFI_HANDLE *)); - - FreePool ((VOID *)Argument5); - - *(EFI_HANDLE **)UserRsp->Arguments[5] = (EFI_HANDLE *)(UINTN)Ring3Pages; - } - EnableSMAP (); - - return StatusBS; - - case SysCallCalculateCrc32: - // - // Argument 1: VOID *Data - // Argument 2: UINTN DataSize - // Argument 3: UINT32 *Crc32 - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + CoreRbp->Argument2 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (UINT32 *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = (UINTN)AllocatePool (CoreRbp->Argument2); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - DisableSMAP (); - CopyMem ((VOID *)Argument4, (VOID *)CoreRbp->Argument1, CoreRbp->Argument2); - EnableSMAP (); - - Status = gBS->CalculateCrc32 ( - (VOID *)Argument4, - CoreRbp->Argument2, - (UINT32 *)&Argument5 - ); - - DisableSMAP (); - *(UINT32 *)CoreRbp->Argument3 = (UINT32)Argument5; - EnableSMAP (); - - return Status; - - case SysCallGetVariable: - // - // Argument 1: CHAR16 *VariableName - // Argument 2: EFI_GUID *VendorGuid - // Argument 3: UINT32 *Attributes OPTIONAL - // Argument 4: UINTN *DataSize - // Argument 5: VOID *Data OPTIONAL - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - if ((UINT32 *)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (UINT32) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - } - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + StrSize ((CHAR16 *)CoreRbp->Argument1) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument6 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument1), (CHAR16 *)CoreRbp->Argument1); - if ((VOID *)Argument6 == NULL) { - EnableSMAP (); - return EFI_OUT_OF_RESOURCES; - } - - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); - if (EFI_ERROR (Status)) { - EnableSMAP (); - FreePool ((VOID *)Argument6); - return Status; - } - - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = *(UINTN *)UserRsp->Arguments[4]; - - if ((VOID *)UserRsp->Arguments[5] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + Argument4 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocatePool (Argument4); - if ((VOID *)Argument5 == NULL) { - EnableSMAP (); - FreePool ((VOID *)Argument6); - return EFI_OUT_OF_RESOURCES; - } - } - EnableSMAP (); - - Status = gRT->GetVariable ( - (CHAR16 *)Argument6, - CoreProtocol, - (UINT32 *)&Attributes, - &Argument4, - (VOID *)Argument5 - ); - - DisableSMAP (); - if ((VOID *)UserRsp->Arguments[5] != NULL) { - CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); - } - - *(UINTN *)UserRsp->Arguments[4] = Argument4; - - if ((UINT32 *)CoreRbp->Argument3 != NULL) { - *(UINT32 *)CoreRbp->Argument3 = (UINT32)Attributes; - } - EnableSMAP (); - - FreePool ((VOID *)Argument6); - - if ((VOID *)Argument5 != NULL) { - FreePool ((VOID *)Argument5); - } - - return Status; - - case SysCallBlockIoReset: - // - // Argument 1: EFI_BLOCK_IO_PROTOCOL *This - // Argument 2: BOOLEAN ExtendedVerification - // - BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (BlockIo == NULL) { - return EFI_NOT_FOUND; - } - - return BlockIo->Reset ( - BlockIo, - (BOOLEAN)CoreRbp->Argument2 - ); - - case SysCallBlockIoRead: - // - // Argument 1: EFI_BLOCK_IO_PROTOCOL *This - // Argument 2: UINT32 MediaId - // Argument 3: UINTN BufferSize - // Argument 4: VOID *Buffer - // Argument 5: EFI_LBA Lba - // - BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (BlockIo == NULL) { - return EFI_NOT_FOUND; - } - -#if defined (MDE_CPU_ARM) - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); -#else - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); -#endif - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); -#if defined (MDE_CPU_ARM) - // - // EFI_LBA Lba is aligned on 8 bytes. - // - Attributes = *(UINT64 *)&UserRsp->Arguments[6]; -#else - Attributes = *(UINT64 *)&UserRsp->Arguments[5]; -#endif - EnableSMAP (); - - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); - if ((VOID *)Argument5 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = BlockIo->ReadBlocks ( - BlockIo, - (UINT32)CoreRbp->Argument2, - (EFI_LBA)Attributes, - CoreRbp->Argument3, - (VOID *)Argument5 - ); - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); - EnableSMAP (); - - FreePool ((VOID *)Argument5); - - return Status; - - case SysCallBlockIoWrite: - // - // Argument 1: EFI_BLOCK_IO_PROTOCOL *This - // Argument 2: UINT32 MediaId - // Argument 3: UINTN BufferSize - // Argument 4: VOID *Buffer - // Argument 5: EFI_LBA Lba - // - BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (BlockIo == NULL) { - return EFI_NOT_FOUND; - } - -#if defined (MDE_CPU_ARM) - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); -#else - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); -#endif - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); - if ((VOID *)Argument5 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - CopyMem ((VOID *)Argument5,(VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); - -#if defined (MDE_CPU_ARM) - // - // EFI_LBA Lba is aligned on 8 bytes. - // - Attributes = *(UINT64 *)&UserRsp->Arguments[6]; -#else - Attributes = *(UINT64 *)&UserRsp->Arguments[5]; -#endif - EnableSMAP (); - - Status = BlockIo->WriteBlocks ( - BlockIo, - (UINT32)CoreRbp->Argument2, - (EFI_LBA)Attributes, - CoreRbp->Argument3, - (VOID *)Argument5 - ); - - FreePool ((VOID *)Argument5); - - return Status; - - case SysCallBlockIoFlush: - // - // Argument 1: EFI_BLOCK_IO_PROTOCOL *This - // - BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (BlockIo == NULL) { - return EFI_NOT_FOUND; - } - - return BlockIo->FlushBlocks (BlockIo); - - case SysCallDiskIoRead: - // - // Argument 1: EFI_DISK_IO_PROTOCOL *This - // Argument 2: UINT32 MediaId - // Argument 3: UINTN BufferSize - // Argument 4: VOID *Buffer - // Argument 5: UINT64 Offset - // - DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (DiskIo == NULL) { - return EFI_NOT_FOUND; - } - -#if defined (MDE_CPU_ARM) - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); -#else - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); -#endif - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); -#if defined (MDE_CPU_ARM) - // - // UINT64 Offset is aligned on 8 bytes. - // - Attributes = *(UINT64 *)&UserRsp->Arguments[6]; -#else - Attributes = *(UINT64 *)&UserRsp->Arguments[5]; -#endif - EnableSMAP (); - - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); - if ((VOID *)Argument5 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = DiskIo->ReadDisk ( - DiskIo, - (UINT32)CoreRbp->Argument2, - Attributes, - CoreRbp->Argument3, - (VOID *)Argument5 - ); - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); - EnableSMAP (); - - FreePool ((VOID *)Argument5); - - return Status; - - case SysCallDiskIoWrite: - // - // Argument 1: EFI_DISK_IO_PROTOCOL *This - // Argument 2: UINT32 MediaId - // Argument 3: UINTN BufferSize - // Argument 4: VOID *Buffer - // Argument 5: UINT64 Offset - // - DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (DiskIo == NULL) { - return EFI_NOT_FOUND; - } - -#if defined (MDE_CPU_ARM) - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); -#else - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); -#endif - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); - if ((VOID *)Argument5 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - CopyMem ((VOID *)Argument5, (VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); - -#if defined (MDE_CPU_ARM) - // - // UINT64 Offset is aligned on 8 bytes. - // - Attributes = *(UINT64 *)&UserRsp->Arguments[6]; -#else - Attributes = *(UINT64 *)&UserRsp->Arguments[5]; -#endif - EnableSMAP (); - - Status = DiskIo->WriteDisk ( - DiskIo, - (UINT32)CoreRbp->Argument2, - Attributes, - CoreRbp->Argument3, - (VOID *)Argument5 - ); - - FreePool ((VOID *)Argument5); - - return Status; - - case SysCallUnicodeStriColl: - // - // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This - // Argument 2: CHAR16 *Str1 - // Argument 3: CHAR16 *Str2 - // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (Unicode == NULL) { - return EFI_NOT_FOUND; - } - - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - if ((CHAR16 *)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); - EnableSMAP (); - if ((VOID *)Argument5 == NULL) { - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - return EFI_OUT_OF_RESOURCES; - } - } - - Status = (EFI_STATUS)Unicode->StriColl ( - Unicode, - (CHAR16 *)Argument4, - (CHAR16 *)Argument5 - ); - - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - if ((VOID *)Argument5 != NULL) { - FreePool ((VOID *)Argument5); - } - - return Status; - - case SysCallUnicodeMetaiMatch: - // - // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This - // Argument 2: CHAR16 *String - // Argument 3: CHAR16 *Pattern - // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (Unicode == NULL) { - return EFI_NOT_FOUND; - } - - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - if ((CHAR16 *)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); - EnableSMAP (); - if ((VOID *)Argument5 == NULL) { - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - return EFI_OUT_OF_RESOURCES; - } - } - - Status = (EFI_STATUS)Unicode->MetaiMatch ( - Unicode, - (CHAR16 *)Argument4, - (CHAR16 *)Argument5 - ); - - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - if ((VOID *)Argument5 != NULL) { - FreePool ((VOID *)Argument5); - } - - return Status; - - case SysCallUnicodeStrLwr: - // - // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This - // Argument 2: CHAR16 *Str - // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (Unicode == NULL) { - return EFI_NOT_FOUND; - } - - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - Unicode->StrLwr ( - Unicode, - (CHAR16 *)Argument4 - ); - - if ((VOID *)Argument4 != NULL) { - DisableSMAP (); - Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); - EnableSMAP (); - - FreePool ((VOID *)Argument4); - } - - return EFI_SUCCESS; - - case SysCallUnicodeStrUpr: - // - // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This - // Argument 2: CHAR16 *Str - // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (Unicode == NULL) { - return EFI_NOT_FOUND; - } - - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - Unicode->StrUpr ( - Unicode, - (CHAR16 *)Argument4 - ); - - if ((VOID *)Argument4 != NULL) { - DisableSMAP (); - Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); - EnableSMAP (); - - FreePool ((VOID *)Argument4); - } - - return EFI_SUCCESS; - - case SysCallUnicodeFatToStr: - // - // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This - // Argument 2: UINTN FatSize - // Argument 3: CHAR8 *Fat - // Argument 4: CHAR16 *String - // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (Unicode == NULL) { - return EFI_NOT_FOUND; - } - - if ((CHAR8 *)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + CoreRbp->Argument2 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - Argument4 = (UINTN)AllocateCopyPool (CoreRbp->Argument2, (CHAR8 *)CoreRbp->Argument3); - EnableSMAP (); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - if ((CHAR16 *)UserRsp->Arguments[4] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + 2 * (CoreRbp->Argument2 + 1) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocatePool (2 * (CoreRbp->Argument2 + 1)); - if ((VOID *)Argument5 == NULL) { - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - return EFI_OUT_OF_RESOURCES; - } - } - EnableSMAP (); - - Unicode->FatToStr ( - Unicode, - CoreRbp->Argument2, - (CHAR8 *)Argument4, - (CHAR16 *)Argument5 - ); - - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - if ((VOID *)Argument5 != NULL) { - DisableSMAP (); - CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, 2 * (CoreRbp->Argument2 + 1)); - EnableSMAP (); - - FreePool ((VOID *)Argument5); - } - - return EFI_SUCCESS; - - case SysCallUnicodeStrToFat: - // - // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This - // Argument 2: CHAR16 *String - // Argument 3: UINTN FatSize - // Argument 4: CHAR8 *Fat - // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (Unicode == NULL) { - return EFI_NOT_FOUND; - } - - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); - if ((VOID *)Argument4 == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - DisableSMAP (); - if ((CHAR8 *)UserRsp->Arguments[4] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); - if ((VOID *)Argument5 == NULL) { - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - return EFI_OUT_OF_RESOURCES; - } - } - EnableSMAP (); - - Status = (EFI_STATUS)Unicode->StrToFat ( - Unicode, - (CHAR16 *)Argument4, - CoreRbp->Argument3, - (CHAR8 *)Argument5 - ); - - if ((VOID *)Argument4 != NULL) { - FreePool ((VOID *)Argument4); - } - - if ((VOID *)Argument5 != NULL) { - DisableSMAP (); - CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); - EnableSMAP (); - - FreePool ((VOID *)Argument5); - } - - return Status; - - default: - DEBUG ((DEBUG_ERROR, "Ring0: Unknown syscall type.\n")); - break; - } - - return EFI_UNSUPPORTED; -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" +#include "SupportedProtocols.h" + +LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead); + +typedef struct { + VOID *Core; + VOID *Ring3; + LIST_ENTRY Link; +} INTERFACE; + +UINTN mRing3InterfacePointer = 0; + +CHAR8 *SysCallNames[] = { + // + // BootServices + // + "SysCallReturnToCore", // Must always be zero for CoreBootServices.nasm. + "SysCallLocateProtocol", + "SysCallOpenProtocol", + "SysCallInstallMultipleProtocolInterfaces", + "SysCallCloseProtocol", + "SysCallHandleProtocol", + "SysCallAllocatePages", + "SysCallFreePages", + "SysCallRaiseTpl", + "SysCallRestoreTpl", + "SysCallLocateHandleBuffer", + "SysCallCalculateCrc32", + // + // RuntimeServices + // + "SysCallGetVariable", + // + // Protocols + // + "SysCallBlockIoReset", + "SysCallBlockIoRead", + "SysCallBlockIoWrite", + "SysCallBlockIoFlush", + "SysCallDiskIoRead", + "SysCallDiskIoWrite", + "SysCallUnicodeStriColl", + "SysCallUnicodeMetaiMatch", + "SysCallUnicodeStrLwr", + "SysCallUnicodeStrUpr", + "SysCallUnicodeFatToStr", + "SysCallUnicodeStrToFat", + "SysCallMax" +}; + +EFI_STATUS +EFIAPI +CallInstallMultipleProtocolInterfaces ( + IN EFI_HANDLE *Handle, + IN VOID **ArgList, + IN UINT32 ArgListSize, + IN VOID *Function + ); + +VOID +EFIAPI +FreeProtocolsList ( + VOID + ) +{ + LIST_ENTRY *Link; + INTERFACE *Protocol; + + for (Link = mProtocolsHead.BackLink; Link != &mProtocolsHead; Link = mProtocolsHead.BackLink) { + Protocol = BASE_CR (Link, INTERFACE, Link); + RemoveEntryList (Link); + FreePool (Protocol); + } +} + +STATIC +EFI_STATUS +EFIAPI +FindGuid ( + IN EFI_GUID *Ring3, + OUT EFI_GUID **Core, + OUT UINT32 *CoreSize + ) +{ + ASSERT (Ring3 != NULL); + ASSERT (Core != NULL); + ASSERT (CoreSize != NULL); + + if (CompareGuid (Ring3, &gEfiDevicePathUtilitiesProtocolGuid)) { + + *Core = &gEfiDevicePathUtilitiesProtocolGuid; + *CoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiLoadedImageProtocolGuid)) { + + *Core = &gEfiLoadedImageProtocolGuid; + *CoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiBlockIoProtocolGuid)) { + + *Core = &gEfiBlockIoProtocolGuid; + *CoreSize = sizeof (EFI_BLOCK_IO_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiDiskIoProtocolGuid)) { + + *Core = &gEfiDiskIoProtocolGuid; + *CoreSize = sizeof (EFI_DISK_IO_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiDriverBindingProtocolGuid)) { + + *Core = &gEfiDriverBindingProtocolGuid; + *CoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiComponentNameProtocolGuid)) { + + *Core = &gEfiComponentNameProtocolGuid; + *CoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiComponentName2ProtocolGuid)) { + + *Core = &gEfiComponentName2ProtocolGuid; + *CoreSize = sizeof (EFI_COMPONENT_NAME2_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiDevicePathProtocolGuid)) { + + *Core = &gEfiDevicePathProtocolGuid; + *CoreSize = sizeof (EFI_DEVICE_PATH_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiSimpleFileSystemProtocolGuid)) { + + *Core = &gEfiSimpleFileSystemProtocolGuid; + *CoreSize = sizeof (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiUnicodeCollationProtocolGuid)) { + + *Core = &gEfiUnicodeCollationProtocolGuid; + *CoreSize = sizeof (EFI_UNICODE_COLLATION_PROTOCOL); + + } else if (CompareGuid (Ring3, &gEfiGlobalVariableGuid)) { + + *Core = &gEfiGlobalVariableGuid; + + } else { + DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol - %g.\n", Ring3)); + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +STATIC +VOID * +EFIAPI +FindInterface ( + IN BOOLEAN FindRing3, + IN VOID *Interface + ) +{ + LIST_ENTRY *Link; + INTERFACE *Protocol; + + for (Link = mProtocolsHead.ForwardLink; Link != &mProtocolsHead; Link = Link->ForwardLink) { + Protocol = BASE_CR (Link, INTERFACE, Link); + + if (FindRing3) { + if (Protocol->Core == Interface) { + return Protocol->Ring3; + } + } else { + if (Protocol->Ring3 == Interface) { + return Protocol->Core; + } + } + } + + return NULL; +} + +STATIC +VOID * +EFIAPI +PrepareRing3Interface ( + IN EFI_GUID *Guid, + IN VOID *CoreInterface, + IN UINT32 CoreSize + ) +{ + EFI_STATUS Status; + UINTN Ring3Limit; + VOID *Ring3Interface; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_UNICODE_COLLATION_PROTOCOL *Unicode; + INTERFACE *Protocol; + + ASSERT (Guid != NULL); + ASSERT (CoreInterface != NULL); + + if (mRing3InterfacePointer == 0) { + mRing3InterfacePointer = (UINTN)gRing3Interfaces; + } + + Ring3Interface = FindInterface (TRUE, CoreInterface); + + if (Ring3Interface != NULL) { + return Ring3Interface; + } + + Ring3Limit = (UINTN)gRing3Interfaces + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES); + + ASSERT ((mRing3InterfacePointer + CoreSize) <= Ring3Limit); + + Ring3Interface = (VOID *)mRing3InterfacePointer; + + CopyMem ((VOID *)mRing3InterfacePointer, CoreInterface, CoreSize); + mRing3InterfacePointer += CoreSize; + + Protocol = AllocatePool (sizeof (INTERFACE)); + + Protocol->Core = CoreInterface; + Protocol->Ring3 = Ring3Interface; + + InsertTailList (&mProtocolsHead, &Protocol->Link); + + if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) { + ASSERT ((mRing3InterfacePointer + sizeof (EFI_BLOCK_IO_MEDIA)) <= Ring3Limit); + + BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Ring3Interface; + + CopyMem ((VOID *)mRing3InterfacePointer, (VOID *)BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA)); + + BlockIo->Media = (EFI_BLOCK_IO_MEDIA *)mRing3InterfacePointer; + + mRing3InterfacePointer += sizeof (EFI_BLOCK_IO_MEDIA); + } else if (CompareGuid (Guid, &gEfiUnicodeCollationProtocolGuid)) { + + Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)Ring3Interface; + + ASSERT ((mRing3InterfacePointer + AsciiStrSize (Unicode->SupportedLanguages)) <= Ring3Limit); + + Status = AsciiStrCpyS ( + (CHAR8 *)mRing3InterfacePointer, + AsciiStrSize (Unicode->SupportedLanguages), + Unicode->SupportedLanguages + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Could not copy string!\n")); + return NULL; + } + + Unicode->SupportedLanguages = (CHAR8 *)mRing3InterfacePointer; + + mRing3InterfacePointer += AsciiStrSize (Unicode->SupportedLanguages); + } + + return Ring3Interface; +} + +// +// Stack: +// rsp - User Rsp +// rbp - User Rbp +// rcx - User Rip for SYSCALL +// r11 - User RFLAGS for SYSCALL +// r9 - Argument 3 +// r8 - Argument 2 +// rdx - Argument 1 <- CoreRbp +// +EFI_STATUS +EFIAPI +CallBootService ( + IN UINT8 Type, + IN CORE_STACK *CoreRbp, + IN RING3_STACK *UserRsp + ) +{ + EFI_STATUS Status; + EFI_STATUS StatusBS; + UINT64 Attributes; + VOID *Interface; + EFI_GUID *CoreProtocol; + UINT32 MemoryCoreSize; + UINTN Argument4; + UINTN Argument5; + UINTN Argument6; + UINT32 Index; + VOID **UserArgList; + VOID *CoreArgList[MAX_LIST]; + EFI_HANDLE CoreHandle; + UINT32 PagesNumber; + EFI_PHYSICAL_ADDRESS Ring3Pages; + + EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem; + + EFI_BLOCK_IO_PROTOCOL *BlockIo; + EFI_DISK_IO_PROTOCOL *DiskIo; + EFI_UNICODE_COLLATION_PROTOCOL *Unicode; + + CoreProtocol = NULL; + Argument4 = 0; + Argument5 = 0; + Argument6 = 0; + Interface = NULL; + // + // Check User variables. + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserRsp, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DEBUG ((DEBUG_VERBOSE, "Type: %a\n", SysCallNames[Type])); + + switch (Type) { + case SysCallLocateProtocol: + // + // Argument 1: EFI_GUID *Protocol + // Argument 2: VOID *CoreRegistration + // Argument 3: VOID **Interface + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument1, &CoreProtocol, &MemoryCoreSize); + EnableSMAP (); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->LocateProtocol ( + CoreProtocol, + (VOID *)CoreRbp->Argument2, + &Interface + ); + + DisableSMAP (); + if (Interface != NULL) { + Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); + ASSERT (Interface != NULL); + + *(VOID **)CoreRbp->Argument3 = Interface; + } + EnableSMAP (); + + return Status; + + case SysCallOpenProtocol: + // + // Argument 1: EFI_HANDLE CoreUserHandle + // Argument 2: EFI_GUID *Protocol + // Argument 3: VOID **Interface OPTIONAL + // Argument 4: EFI_HANDLE CoreImageHandle + // Argument 5: EFI_HANDLE CoreControllerHandle + // Argument 6: UINT32 Attributes + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + if ((VOID **)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + } + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + return Status; + } + + Argument4 = UserRsp->Arguments[4]; + Argument5 = UserRsp->Arguments[5]; + Argument6 = UserRsp->Arguments[6]; + EnableSMAP (); + + Status = gBS->OpenProtocol ( + (EFI_HANDLE)CoreRbp->Argument1, + CoreProtocol, + ((VOID **)CoreRbp->Argument3 != NULL) ? &Interface : NULL, + (EFI_HANDLE)Argument4, + (EFI_HANDLE)Argument5, + (UINT32)Argument6 + ); + + if ((VOID **)CoreRbp->Argument3 != NULL) { + DisableSMAP (); + if (Interface != NULL) { + Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); + } + + *(VOID **)CoreRbp->Argument3 = Interface; + EnableSMAP (); + } + + return Status; + + case SysCallInstallMultipleProtocolInterfaces: + // + // Argument 1: EFI_HANDLE *Handle + // ... + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + sizeof (EFI_HANDLE *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (VOID **) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + CoreHandle = *(EFI_HANDLE *)CoreRbp->Argument1; + UserArgList = (VOID **)CoreRbp->Argument2; + + for (Index = 0; UserArgList[Index] != NULL; Index += 2) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArgList[Index], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArgList[Index] + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Status = FindGuid ((EFI_GUID *)UserArgList[Index], (EFI_GUID **)&CoreArgList[Index], &MemoryCoreSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + + while (Index > 0) { + FreePool (CoreArgList[Index - 1]); + Index -= 2; + } + + return Status; + } + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArgList[Index + 1], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArgList[Index + 1] + MemoryCoreSize - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + CoreArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index + 1]); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] + sizeof (VOID *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + } + EnableSMAP (); + + ASSERT (Index < MAX_LIST); + CoreArgList[Index] = NULL; + + for (Index = 0; CoreArgList[Index] != NULL; Index += 2) { + if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiDriverBindingProtocolGuid)) { + CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)CoreArgList[Index + 1]; + + mRing3DriverBindingProtocol.Supported = CoreDriverBinding->Supported; + mRing3DriverBindingProtocol.Start = CoreDriverBinding->Start; + mRing3DriverBindingProtocol.Stop = CoreDriverBinding->Stop; + + CoreDriverBinding->Supported = CoreDriverBindingSupported; + CoreDriverBinding->Start = CoreDriverBindingStart; + CoreDriverBinding->Stop = CoreDriverBindingStop; + } else if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiSimpleFileSystemProtocolGuid)) { + CoreSimpleFileSystem = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)CoreArgList[Index + 1]; + + mRing3SimpleFileSystemProtocol.OpenVolume = CoreSimpleFileSystem->OpenVolume; + + CoreSimpleFileSystem->OpenVolume = CoreOpenVolume; + + DisableSMAP (); + mRing3SimpleFileSystemPointer = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)UserArgList[Index + 1]; + EnableSMAP (); + } + } + + Status = CallInstallMultipleProtocolInterfaces ( + &CoreHandle, + CoreArgList, + Index + 1, + (VOID *)gBS->InstallMultipleProtocolInterfaces + ); + + return Status; + + case SysCallCloseProtocol: + // + // Argument 1: EFI_HANDLE CoreUserHandle + // Argument 2: EFI_GUID *Protocol + // Argument 3: EFI_HANDLE CoreAgentHandle + // Argument 4: EFI_HANDLE CoreControllerHandle + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + return Status; + } + + Argument4 = UserRsp->Arguments[4]; + EnableSMAP (); + + Status = gBS->CloseProtocol ( + (EFI_HANDLE)CoreRbp->Argument1, + CoreProtocol, + (EFI_HANDLE)CoreRbp->Argument3, + (EFI_HANDLE)Argument4 + ); + + return Status; + + case SysCallHandleProtocol: + // + // Argument 1: EFI_HANDLE CoreUserHandle + // Argument 2: EFI_GUID *Protocol + // Argument 3: VOID **Interface + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + EnableSMAP (); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->HandleProtocol ( + (EFI_HANDLE)CoreRbp->Argument1, + CoreProtocol, + &Interface + ); + + DisableSMAP (); + if (Interface != NULL) { + Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); + ASSERT (Interface != NULL); + + *(VOID **)CoreRbp->Argument3 = Interface; + } + EnableSMAP (); + + return Status; + + case SysCallAllocatePages: + // + // Argument 1: EFI_ALLOCATE_TYPE Type + // Argument 2: EFI_MEMORY_TYPE MemoryType + // Argument 3: UINTN NumberOfPages + // Argument 4: EFI_PHYSICAL_ADDRESS *Memory + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Status = gBS->AllocatePages ( + (EFI_ALLOCATE_TYPE)CoreRbp->Argument1, + (EFI_MEMORY_TYPE)CoreRbp->Argument2, + CoreRbp->Argument3, + (EFI_PHYSICAL_ADDRESS *)&Argument4 + ); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + sizeof (EFI_PHYSICAL_ADDRESS) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + *(EFI_PHYSICAL_ADDRESS *)UserRsp->Arguments[4] = (EFI_PHYSICAL_ADDRESS)Argument4; + EnableSMAP (); + + return Status; + + case SysCallFreePages: + // + // Argument 1: UINTN NumberOfPages + // Argument 2: EFI_PHYSICAL_ADDRESS Memory + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + CoreRbp->Argument1 * EFI_PAGE_SIZE - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + return gBS->FreePages ( + *(EFI_PHYSICAL_ADDRESS *)&CoreRbp->Argument2, + CoreRbp->Argument1 + ); + + case SysCallRaiseTpl: + // + // Argument 1: EFI_TPL NewTpl + // + return (EFI_STATUS)gBS->RaiseTPL ( + (EFI_TPL)CoreRbp->Argument1 + ); + + case SysCallRestoreTpl: + // + // Argument 1: EFI_TPL NewTpl + // + gBS->RestoreTPL ((EFI_TPL)CoreRbp->Argument1); + + return EFI_SUCCESS; + + case SysCallLocateHandleBuffer: + // + // Argument 1: EFI_LOCATE_SEARCH_TYPE SearchType + // Argument 2: EFI_GUID *Protocol OPTIONAL + // Argument 3: VOID *SearchKey OPTIONAL + // Argument 4: UINTN *NumberHandles + // Argument 5: EFI_HANDLE **Buffer + // + if ((EFI_GUID *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + EnableSMAP (); + if (EFI_ERROR (Status)) { + return Status; + } + } + + StatusBS = gBS->LocateHandleBuffer ( + (EFI_LOCATE_SEARCH_TYPE)CoreRbp->Argument1, + CoreProtocol, + (VOID *)CoreRbp->Argument3, + &Argument4, + (EFI_HANDLE **)&Argument5 + ); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + if ((UINTN *)UserRsp->Arguments[4] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + *(UINTN *)UserRsp->Arguments[4] = Argument4; + } + + if ((EFI_HANDLE **)UserRsp->Arguments[5] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + sizeof (EFI_HANDLE *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (Argument4 * sizeof (EFI_HANDLE *)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + &Ring3Pages + ); + if (EFI_ERROR (Status)) { + return Status; + } + + CopyMem ((VOID *)(UINTN)Ring3Pages, (VOID *)Argument5, Argument4 * sizeof (EFI_HANDLE *)); + + FreePool ((VOID *)Argument5); + + *(EFI_HANDLE **)UserRsp->Arguments[5] = (EFI_HANDLE *)(UINTN)Ring3Pages; + } + EnableSMAP (); + + return StatusBS; + + case SysCallCalculateCrc32: + // + // Argument 1: VOID *Data + // Argument 2: UINTN DataSize + // Argument 3: UINT32 *Crc32 + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + CoreRbp->Argument2 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (UINT32 *) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocatePool (CoreRbp->Argument2); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + DisableSMAP (); + CopyMem ((VOID *)Argument4, (VOID *)CoreRbp->Argument1, CoreRbp->Argument2); + EnableSMAP (); + + Status = gBS->CalculateCrc32 ( + (VOID *)Argument4, + CoreRbp->Argument2, + (UINT32 *)&Argument5 + ); + + DisableSMAP (); + *(UINT32 *)CoreRbp->Argument3 = (UINT32)Argument5; + EnableSMAP (); + + return Status; + + case SysCallGetVariable: + // + // Argument 1: CHAR16 *VariableName + // Argument 2: EFI_GUID *VendorGuid + // Argument 3: UINT32 *Attributes OPTIONAL + // Argument 4: UINTN *DataSize + // Argument 5: VOID *Data OPTIONAL + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + if ((UINT32 *)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (UINT32) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + } + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + StrSize ((CHAR16 *)CoreRbp->Argument1) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument6 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument1), (CHAR16 *)CoreRbp->Argument1); + if ((VOID *)Argument6 == NULL) { + EnableSMAP (); + return EFI_OUT_OF_RESOURCES; + } + + Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + if (EFI_ERROR (Status)) { + EnableSMAP (); + FreePool ((VOID *)Argument6); + return Status; + } + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = *(UINTN *)UserRsp->Arguments[4]; + + if ((VOID *)UserRsp->Arguments[5] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + Argument4 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (Argument4); + if ((VOID *)Argument5 == NULL) { + EnableSMAP (); + FreePool ((VOID *)Argument6); + return EFI_OUT_OF_RESOURCES; + } + } + EnableSMAP (); + + Status = gRT->GetVariable ( + (CHAR16 *)Argument6, + CoreProtocol, + (UINT32 *)&Attributes, + &Argument4, + (VOID *)Argument5 + ); + + DisableSMAP (); + if ((VOID *)UserRsp->Arguments[5] != NULL) { + CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + } + + *(UINTN *)UserRsp->Arguments[4] = Argument4; + + if ((UINT32 *)CoreRbp->Argument3 != NULL) { + *(UINT32 *)CoreRbp->Argument3 = (UINT32)Attributes; + } + EnableSMAP (); + + FreePool ((VOID *)Argument6); + + if ((VOID *)Argument5 != NULL) { + FreePool ((VOID *)Argument5); + } + + return Status; + + case SysCallBlockIoReset: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // Argument 2: BOOLEAN ExtendedVerification + // + BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (BlockIo == NULL) { + return EFI_NOT_FOUND; + } + + return BlockIo->Reset ( + BlockIo, + (BOOLEAN)CoreRbp->Argument2 + ); + + case SysCallBlockIoRead: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: UINTN BufferSize + // Argument 4: VOID *Buffer + // Argument 5: EFI_LBA Lba + // + BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (BlockIo == NULL) { + return EFI_NOT_FOUND; + } + +#if defined (MDE_CPU_ARM) + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); +#else + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); +#endif + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); +#if defined (MDE_CPU_ARM) + // + // EFI_LBA Lba is aligned on 8 bytes. + // + Attributes = *(UINT64 *)&UserRsp->Arguments[6]; +#else + Attributes = *(UINT64 *)&UserRsp->Arguments[5]; +#endif + EnableSMAP (); + + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = BlockIo->ReadBlocks ( + BlockIo, + (UINT32)CoreRbp->Argument2, + (EFI_LBA)Attributes, + CoreRbp->Argument3, + (VOID *)Argument5 + ); + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallBlockIoWrite: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: UINTN BufferSize + // Argument 4: VOID *Buffer + // Argument 5: EFI_LBA Lba + // + BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (BlockIo == NULL) { + return EFI_NOT_FOUND; + } + +#if defined (MDE_CPU_ARM) + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); +#else + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); +#endif + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + CopyMem ((VOID *)Argument5,(VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); + +#if defined (MDE_CPU_ARM) + // + // EFI_LBA Lba is aligned on 8 bytes. + // + Attributes = *(UINT64 *)&UserRsp->Arguments[6]; +#else + Attributes = *(UINT64 *)&UserRsp->Arguments[5]; +#endif + EnableSMAP (); + + Status = BlockIo->WriteBlocks ( + BlockIo, + (UINT32)CoreRbp->Argument2, + (EFI_LBA)Attributes, + CoreRbp->Argument3, + (VOID *)Argument5 + ); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallBlockIoFlush: + // + // Argument 1: EFI_BLOCK_IO_PROTOCOL *This + // + BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (BlockIo == NULL) { + return EFI_NOT_FOUND; + } + + return BlockIo->FlushBlocks (BlockIo); + + case SysCallDiskIoRead: + // + // Argument 1: EFI_DISK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: UINTN BufferSize + // Argument 4: VOID *Buffer + // Argument 5: UINT64 Offset + // + DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (DiskIo == NULL) { + return EFI_NOT_FOUND; + } + +#if defined (MDE_CPU_ARM) + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); +#else + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); +#endif + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); +#if defined (MDE_CPU_ARM) + // + // UINT64 Offset is aligned on 8 bytes. + // + Attributes = *(UINT64 *)&UserRsp->Arguments[6]; +#else + Attributes = *(UINT64 *)&UserRsp->Arguments[5]; +#endif + EnableSMAP (); + + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = DiskIo->ReadDisk ( + DiskIo, + (UINT32)CoreRbp->Argument2, + Attributes, + CoreRbp->Argument3, + (VOID *)Argument5 + ); + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallDiskIoWrite: + // + // Argument 1: EFI_DISK_IO_PROTOCOL *This + // Argument 2: UINT32 MediaId + // Argument 3: UINTN BufferSize + // Argument 4: VOID *Buffer + // Argument 5: UINT64 Offset + // + DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (DiskIo == NULL) { + return EFI_NOT_FOUND; + } + +#if defined (MDE_CPU_ARM) + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); +#else + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); +#endif + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + if ((VOID *)Argument5 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + CopyMem ((VOID *)Argument5, (VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); + +#if defined (MDE_CPU_ARM) + // + // UINT64 Offset is aligned on 8 bytes. + // + Attributes = *(UINT64 *)&UserRsp->Arguments[6]; +#else + Attributes = *(UINT64 *)&UserRsp->Arguments[5]; +#endif + EnableSMAP (); + + Status = DiskIo->WriteDisk ( + DiskIo, + (UINT32)CoreRbp->Argument2, + Attributes, + CoreRbp->Argument3, + (VOID *)Argument5 + ); + + FreePool ((VOID *)Argument5); + + return Status; + + case SysCallUnicodeStriColl: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *Str1 + // Argument 3: CHAR16 *Str2 + // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + if ((CHAR16 *)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); + EnableSMAP (); + if ((VOID *)Argument5 == NULL) { + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + return EFI_OUT_OF_RESOURCES; + } + } + + Status = (EFI_STATUS)Unicode->StriColl ( + Unicode, + (CHAR16 *)Argument4, + (CHAR16 *)Argument5 + ); + + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + if ((VOID *)Argument5 != NULL) { + FreePool ((VOID *)Argument5); + } + + return Status; + + case SysCallUnicodeMetaiMatch: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *String + // Argument 3: CHAR16 *Pattern + // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + if ((CHAR16 *)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); + EnableSMAP (); + if ((VOID *)Argument5 == NULL) { + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + return EFI_OUT_OF_RESOURCES; + } + } + + Status = (EFI_STATUS)Unicode->MetaiMatch ( + Unicode, + (CHAR16 *)Argument4, + (CHAR16 *)Argument5 + ); + + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + if ((VOID *)Argument5 != NULL) { + FreePool ((VOID *)Argument5); + } + + return Status; + + case SysCallUnicodeStrLwr: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *Str + // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + Unicode->StrLwr ( + Unicode, + (CHAR16 *)Argument4 + ); + + if ((VOID *)Argument4 != NULL) { + DisableSMAP (); + Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument4); + } + + return EFI_SUCCESS; + + case SysCallUnicodeStrUpr: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *Str + // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + Unicode->StrUpr ( + Unicode, + (CHAR16 *)Argument4 + ); + + if ((VOID *)Argument4 != NULL) { + DisableSMAP (); + Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); + EnableSMAP (); + + FreePool ((VOID *)Argument4); + } + + return EFI_SUCCESS; + + case SysCallUnicodeFatToStr: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: UINTN FatSize + // Argument 3: CHAR8 *Fat + // Argument 4: CHAR16 *String + // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + + if ((CHAR8 *)CoreRbp->Argument3 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + CoreRbp->Argument2 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + Argument4 = (UINTN)AllocateCopyPool (CoreRbp->Argument2, (CHAR8 *)CoreRbp->Argument3); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + if ((CHAR16 *)UserRsp->Arguments[4] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + 2 * (CoreRbp->Argument2 + 1) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (2 * (CoreRbp->Argument2 + 1)); + if ((VOID *)Argument5 == NULL) { + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + return EFI_OUT_OF_RESOURCES; + } + } + EnableSMAP (); + + Unicode->FatToStr ( + Unicode, + CoreRbp->Argument2, + (CHAR8 *)Argument4, + (CHAR16 *)Argument5 + ); + + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + if ((VOID *)Argument5 != NULL) { + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, 2 * (CoreRbp->Argument2 + 1)); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + } + + return EFI_SUCCESS; + + case SysCallUnicodeStrToFat: + // + // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This + // Argument 2: CHAR16 *String + // Argument 3: UINTN FatSize + // Argument 4: CHAR8 *Fat + // + Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + + if (Unicode == NULL) { + return EFI_NOT_FOUND; + } + + if ((CHAR16 *)CoreRbp->Argument2 != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + EnableSMAP (); + if ((VOID *)Argument4 == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + DisableSMAP (); + if ((CHAR8 *)UserRsp->Arguments[4] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + if ((VOID *)Argument5 == NULL) { + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + return EFI_OUT_OF_RESOURCES; + } + } + EnableSMAP (); + + Status = (EFI_STATUS)Unicode->StrToFat ( + Unicode, + (CHAR16 *)Argument4, + CoreRbp->Argument3, + (CHAR8 *)Argument5 + ); + + if ((VOID *)Argument4 != NULL) { + FreePool ((VOID *)Argument4); + } + + if ((VOID *)Argument5 != NULL) { + DisableSMAP (); + CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); + EnableSMAP (); + + FreePool ((VOID *)Argument5); + } + + return Status; + + default: + DEBUG ((DEBUG_ERROR, "Ring0: Unknown syscall type.\n")); + break; + } + + return EFI_UNSUPPORTED; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index 32a8dad0dd..ade43fc05d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -1,223 +1,223 @@ -;------------------------------------------------------------------------------ -; -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -; SPDX-License-Identifier: BSD-3-Clause -; -;------------------------------------------------------------------------------ - -#include - -extern ASM_PFX(CallBootService) -extern ASM_PFX(gCoreSysCallStackTop) -extern ASM_PFX(gRing3CallStackTop) -extern ASM_PFX(gRing3EntryPoint) - -extern ASM_PFX(AsmReadMsr64) - -DEFAULT REL -SECTION .text - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; DisableSMAP ( -; VOID -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(DisableSMAP) -ASM_PFX(DisableSMAP): - pushfd - pop eax - or eax, 0x40000 ; Set AC (bit 18) - push eax - popfd - ret - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; EnableSMAP ( -; VOID -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(EnableSMAP) -ASM_PFX(EnableSMAP): - pushfd - pop eax - and eax, ~0x40000 ; Clear AC (bit 18) - push eax - popfd - ret - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; CallInstallMultipleProtocolInterfaces ( -; IN EFI_HANDLE *Handle, -; IN VOID **ArgList, -; IN UINT32 ArgListSize, -; IN VOID *Function -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(CallInstallMultipleProtocolInterfaces) -ASM_PFX(CallInstallMultipleProtocolInterfaces): - push ebp - mov ebp, esp - - ; Prepare stack for call. - mov eax, [ebp + 3 * 4] ; eax = ArgList - mov ecx, [ebp + 4 * 4] ; ecx = ArgListSize - lea eax, [eax + ecx * 4] -copy: - sub eax, 4 - push dword [eax] - sub ecx, 1 - jnz copy - push dword [ebp + 2 * 4] - - call [ebp + 5 * 4] - - ; Step over Function arguments. - mov esp, ebp - pop ebp - - ret - -%macro SetRing3DataSegmentSelectors 0 - push dword MSR_IA32_SYSENTER_CS - call ASM_PFX(AsmReadMsr64) - ; eax = RING0_CODE32_SEL - add eax, 24 ; GDT: RING0_CODE32, RING0_DATA32, RING3_CODE32, RING3_DATA32 - or eax, 3 ; RPL = 3 - - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - pop eax -%endmacro - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; CoreBootServices ( -; IN UINT8 Type, -; ... -; ); -; -; (eax) User return address. -; (ecx) Type. -; (edx) User Stack Pointer. -; -; (On User Stack) Argument 1, 2, ... -;------------------------------------------------------------------------------ -global ASM_PFX(CoreBootServices) -ASM_PFX(CoreBootServices): - ; Save User return address and Stack pointers. - push edx - push ebp - push eax - - ; Switch from User to Core data segment selectors. - mov ax, ss - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - ; Special case for SysCallReturnToCore. - cmp ecx, 0 - je coreReturnAddress - - ; Prepare CallBootService arguments. - call ASM_PFX(DisableSMAP) - mov eax, [edx + 4 * 4] ; User Argument 3 - push eax - mov eax, [edx + 3 * 4] ; User Argument 2 - push eax - mov eax, [edx + 2 * 4] ; User Argument 1 - push eax - call ASM_PFX(EnableSMAP) - mov ebp, esp - push edx - push ebp - push ecx - - sti - call ASM_PFX(CallBootService) - push eax - cli - - SetRing3DataSegmentSelectors - - pop eax - - ; Step over User Arguments [1..3] and CallBootService input. - add esp, 4*6 - - ; Prepare SYSEXIT arguments. - pop edx ; User return address. - pop ebp - pop ecx ; User Stack Pointer. - - sti - sysexit - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; CallRing3 ( -; IN RING3_CALL_DATA *Data -; ); -; -; (On User Stack) Data -;------------------------------------------------------------------------------ -global ASM_PFX(CallRing3) -ASM_PFX(CallRing3): - cli - ; Save nonvolatile registers EBX, EBP, EDI, ESI, ESP. - push ebx - push ebp - push edi - push esi - - ; Save Core Stack pointer. - mov [ASM_PFX(CoreEsp)], esp - - push dword [ASM_PFX(gRing3EntryPoint)] - push dword [ASM_PFX(gRing3CallStackTop)] - - SetRing3DataSegmentSelectors - - ; Prepare SYSEXIT arguments. - pop ecx - pop edx - mov eax, [esp + 4 * 5] ; Data - - ; Switch to User Stack. - mov ebp, ecx - - ; Pass control to user image - sti - sysexit - -coreReturnAddress: - mov esp, [ASM_PFX(CoreEsp)] - pop esi - pop edi - pop ebp - pop ebx - - call ASM_PFX(DisableSMAP) - mov eax, [edx + 2 * 4] ; User Argument 1 - push eax - call ASM_PFX(EnableSMAP) - pop eax - - sti - ret - -SECTION .data -ASM_PFX(CoreEsp): - resd 1 +;------------------------------------------------------------------------------ +; +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +; +;------------------------------------------------------------------------------ + +#include + +extern ASM_PFX(CallBootService) +extern ASM_PFX(gCoreSysCallStackTop) +extern ASM_PFX(gRing3CallStackTop) +extern ASM_PFX(gRing3EntryPoint) + +extern ASM_PFX(AsmReadMsr64) + +DEFAULT REL +SECTION .text + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; DisableSMAP ( +; VOID +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(DisableSMAP) +ASM_PFX(DisableSMAP): + pushfd + pop eax + or eax, 0x40000 ; Set AC (bit 18) + push eax + popfd + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; EnableSMAP ( +; VOID +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(EnableSMAP) +ASM_PFX(EnableSMAP): + pushfd + pop eax + and eax, ~0x40000 ; Clear AC (bit 18) + push eax + popfd + ret + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CallInstallMultipleProtocolInterfaces ( +; IN EFI_HANDLE *Handle, +; IN VOID **ArgList, +; IN UINT32 ArgListSize, +; IN VOID *Function +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(CallInstallMultipleProtocolInterfaces) +ASM_PFX(CallInstallMultipleProtocolInterfaces): + push ebp + mov ebp, esp + + ; Prepare stack for call. + mov eax, [ebp + 3 * 4] ; eax = ArgList + mov ecx, [ebp + 4 * 4] ; ecx = ArgListSize + lea eax, [eax + ecx * 4] +copy: + sub eax, 4 + push dword [eax] + sub ecx, 1 + jnz copy + push dword [ebp + 2 * 4] + + call [ebp + 5 * 4] + + ; Step over Function arguments. + mov esp, ebp + pop ebp + + ret + +%macro SetRing3DataSegmentSelectors 0 + push dword MSR_IA32_SYSENTER_CS + call ASM_PFX(AsmReadMsr64) + ; eax = RING0_CODE32_SEL + add eax, 24 ; GDT: RING0_CODE32, RING0_DATA32, RING3_CODE32, RING3_DATA32 + or eax, 3 ; RPL = 3 + + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + pop eax +%endmacro + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CoreBootServices ( +; IN UINT8 Type, +; ... +; ); +; +; (eax) User return address. +; (ecx) Type. +; (edx) User Stack Pointer. +; +; (On User Stack) Argument 1, 2, ... +;------------------------------------------------------------------------------ +global ASM_PFX(CoreBootServices) +ASM_PFX(CoreBootServices): + ; Save User return address and Stack pointers. + push edx + push ebp + push eax + + ; Switch from User to Core data segment selectors. + mov ax, ss + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; Special case for SysCallReturnToCore. + cmp ecx, 0 + je coreReturnAddress + + ; Prepare CallBootService arguments. + call ASM_PFX(DisableSMAP) + mov eax, [edx + 4 * 4] ; User Argument 3 + push eax + mov eax, [edx + 3 * 4] ; User Argument 2 + push eax + mov eax, [edx + 2 * 4] ; User Argument 1 + push eax + call ASM_PFX(EnableSMAP) + mov ebp, esp + push edx + push ebp + push ecx + + sti + call ASM_PFX(CallBootService) + push eax + cli + + SetRing3DataSegmentSelectors + + pop eax + + ; Step over User Arguments [1..3] and CallBootService input. + add esp, 4*6 + + ; Prepare SYSEXIT arguments. + pop edx ; User return address. + pop ebp + pop ecx ; User Stack Pointer. + + sti + sysexit + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CallRing3 ( +; IN RING3_CALL_DATA *Data +; ); +; +; (On User Stack) Data +;------------------------------------------------------------------------------ +global ASM_PFX(CallRing3) +ASM_PFX(CallRing3): + cli + ; Save nonvolatile registers EBX, EBP, EDI, ESI, ESP. + push ebx + push ebp + push edi + push esi + + ; Save Core Stack pointer. + mov [ASM_PFX(CoreEsp)], esp + + push dword [ASM_PFX(gRing3EntryPoint)] + push dword [ASM_PFX(gRing3CallStackTop)] + + SetRing3DataSegmentSelectors + + ; Prepare SYSEXIT arguments. + pop ecx + pop edx + mov eax, [esp + 4 * 5] ; Data + + ; Switch to User Stack. + mov ebp, ecx + + ; Pass control to user image + sti + sysexit + +coreReturnAddress: + mov esp, [ASM_PFX(CoreEsp)] + pop esi + pop edi + pop ebp + pop ebx + + call ASM_PFX(DisableSMAP) + mov eax, [edx + 2 * 4] ; User Argument 1 + push eax + call ASM_PFX(EnableSMAP) + pop eax + + sti + ret + +SECTION .data +ASM_PFX(CoreEsp): + resd 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c index aabfb9e5c4..23bd212ffe 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c @@ -1,64 +1,64 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include "DxeMain.h" - -#include - -VOID -EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries - ) -{ - UINT64 Msr; - IA32_CR4 Cr4; - IA32_EFLAGS32 Eflags; - UINT32 Ebx; - UINT32 Edx; - - Ebx = 0; - Edx = 0; - - // - // Forbid supervisor-mode accesses to any user-mode pages. - // - AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); - if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { - Cr4.UintN = AsmReadCr4 (); - Cr4.Bits.SMAP = 1; - Cr4.Bits.SMEP = 1; - AsmWriteCr4 (Cr4.UintN); - - Eflags.UintN = AsmReadEflags (); - Eflags.Bits.AC = 0; - AsmWriteEflags (Eflags.UintN); - } - - // - // SYSENTER and SYSEXIT must be supported. - // - AsmCpuidEx (0x01, 0x0, NULL, NULL, NULL, &Edx); - if ((Edx & BIT11) == 0) { - DEBUG ((DEBUG_ERROR, "Core: SYSENTER and SYSEXIT are not supported.\n")); - CpuDeadLoop (); - } - - // - // Initialize MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_EIP and - // MSR_IA32_SYSENTER_ESP for SYSENTER and SYSEXIT. - // - Msr = RING0_CODE32_SEL; - AsmWriteMsr64 (MSR_IA32_SYSENTER_CS, Msr); - - Msr = (UINT64)(UINTN)CoreBootServices; - AsmWriteMsr64 (MSR_IA32_SYSENTER_EIP, Msr); - - Msr = (UINT64)(UINTN)gCoreSysCallStackTop; - AsmWriteMsr64 (MSR_IA32_SYSENTER_ESP, Msr); -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +#include + +VOID +EFIAPI +InitializeMsr ( + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries + ) +{ + UINT64 Msr; + IA32_CR4 Cr4; + IA32_EFLAGS32 Eflags; + UINT32 Ebx; + UINT32 Edx; + + Ebx = 0; + Edx = 0; + + // + // Forbid supervisor-mode accesses to any user-mode pages. + // + AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); + if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMAP = 1; + Cr4.Bits.SMEP = 1; + AsmWriteCr4 (Cr4.UintN); + + Eflags.UintN = AsmReadEflags (); + Eflags.Bits.AC = 0; + AsmWriteEflags (Eflags.UintN); + } + + // + // SYSENTER and SYSEXIT must be supported. + // + AsmCpuidEx (0x01, 0x0, NULL, NULL, NULL, &Edx); + if ((Edx & BIT11) == 0) { + DEBUG ((DEBUG_ERROR, "Core: SYSENTER and SYSEXIT are not supported.\n")); + CpuDeadLoop (); + } + + // + // Initialize MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_EIP and + // MSR_IA32_SYSENTER_ESP for SYSENTER and SYSEXIT. + // + Msr = RING0_CODE32_SEL; + AsmWriteMsr64 (MSR_IA32_SYSENTER_CS, Msr); + + Msr = (UINT64)(UINTN)CoreBootServices; + AsmWriteMsr64 (MSR_IA32_SYSENTER_EIP, Msr); + + Msr = (UINT64)(UINTN)gCoreSysCallStackTop; + AsmWriteMsr64 (MSR_IA32_SYSENTER_ESP, Msr); +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index facc9d543d..3a0af40149 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -1,151 +1,151 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include "DxeMain.h" - -VOID *gCoreSysCallStackTop; -VOID *gCoreSysCallStackBase; -VOID *gRing3CallStackTop; -VOID *gRing3CallStackBase; -VOID *gRing3EntryPoint; -RING3_DATA *gRing3Data; -VOID *gRing3Interfaces; - -VOID -EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries - ); - -EFI_STATUS -EFIAPI -InitializeRing3 ( - IN EFI_HANDLE ImageHandle, - IN LOADED_IMAGE_PRIVATE_DATA *Image - ) -{ - EFI_STATUS Status; - VOID *TopOfStack; - UINTN SizeOfStack; - EFI_PHYSICAL_ADDRESS Physical; - UINTN Index; - EFI_CONFIGURATION_TABLE *Conf; - - // - // Set Ring3 EntryPoint and BootServices. - // - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)), - &Physical - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Data.\n")); - return Status; - } - - gRing3Data = (RING3_DATA *)(UINTN)Physical; - - CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (gRing3Data->SystemTable.NumberOfTableEntries * sizeof (EFI_CONFIGURATION_TABLE)), - &Physical - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); - return Status; - } - - Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; - - for (Index = 0; Index < gRing3Data->SystemTable.NumberOfTableEntries; ++Index) { - Conf->VendorGuid = gRing3Data->SystemTable.ConfigurationTable[Index].VendorGuid; - Conf->VendorTable = gRing3Data->SystemTable.ConfigurationTable[Index].VendorTable; - ++Conf; - } - - gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; - - // - // Initialize DxeRing3 with Supervisor privileges. - // - ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, FALSE); - - Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); - - ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, TRUE); - - gRing3EntryPoint = gRing3Data->EntryPoint; - - gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; - gRing3Data->SystemTable.RuntimeServices = gRing3Data->RuntimeServices; - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - RING3_INTERFACES_PAGES, - &Physical - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Interfaces.\n")); - CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, - EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) - ); - return Status; - } - - gRing3Interfaces = (VOID *)(UINTN)Physical; - - SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; - - // - // Allocate 128KB for the Core SysCall Stack. - // - gCoreSysCallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); - ASSERT (gCoreSysCallStackBase != NULL); - - // - // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. - // - TopOfStack = (VOID *)((UINTN)gCoreSysCallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - gCoreSysCallStackTop = TopOfStack; - - SetUefiImageMemoryAttributes ((UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); - DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); - - // - // Allocate 128KB for the User Stack. - // - gRing3CallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); - ASSERT (gRing3CallStackBase != NULL); - - // - // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. - // - TopOfStack = (VOID *)((UINTN)gRing3CallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - gRing3CallStackTop = TopOfStack; - - SetUefiImageMemoryAttributes ((UINTN)gRing3CallStackBase, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); - DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); - - InitializeMsr ( - gRing3Data->SystemTable.ConfigurationTable, - gRing3Data->SystemTable.NumberOfTableEntries - ); - - return Status; -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +VOID *gCoreSysCallStackTop; +VOID *gCoreSysCallStackBase; +VOID *gRing3CallStackTop; +VOID *gRing3CallStackBase; +VOID *gRing3EntryPoint; +RING3_DATA *gRing3Data; +VOID *gRing3Interfaces; + +VOID +EFIAPI +InitializeMsr ( + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries + ); + +EFI_STATUS +EFIAPI +InitializeRing3 ( + IN EFI_HANDLE ImageHandle, + IN LOADED_IMAGE_PRIVATE_DATA *Image + ) +{ + EFI_STATUS Status; + VOID *TopOfStack; + UINTN SizeOfStack; + EFI_PHYSICAL_ADDRESS Physical; + UINTN Index; + EFI_CONFIGURATION_TABLE *Conf; + + // + // Set Ring3 EntryPoint and BootServices. + // + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)), + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Data.\n")); + return Status; + } + + gRing3Data = (RING3_DATA *)(UINTN)Physical; + + CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (gRing3Data->SystemTable.NumberOfTableEntries * sizeof (EFI_CONFIGURATION_TABLE)), + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); + return Status; + } + + Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + + for (Index = 0; Index < gRing3Data->SystemTable.NumberOfTableEntries; ++Index) { + Conf->VendorGuid = gRing3Data->SystemTable.ConfigurationTable[Index].VendorGuid; + Conf->VendorTable = gRing3Data->SystemTable.ConfigurationTable[Index].VendorTable; + ++Conf; + } + + gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + + // + // Initialize DxeRing3 with Supervisor privileges. + // + ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, FALSE); + + Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); + + ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, TRUE); + + gRing3EntryPoint = gRing3Data->EntryPoint; + + gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; + gRing3Data->SystemTable.RuntimeServices = gRing3Data->RuntimeServices; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + RING3_INTERFACES_PAGES, + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Interfaces.\n")); + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + ); + return Status; + } + + gRing3Interfaces = (VOID *)(UINTN)Physical; + + SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; + + // + // Allocate 128KB for the Core SysCall Stack. + // + gCoreSysCallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); + ASSERT (gCoreSysCallStackBase != NULL); + + // + // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. + // + TopOfStack = (VOID *)((UINTN)gCoreSysCallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + gCoreSysCallStackTop = TopOfStack; + + SetUefiImageMemoryAttributes ((UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); + DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); + + // + // Allocate 128KB for the User Stack. + // + gRing3CallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); + ASSERT (gRing3CallStackBase != NULL); + + // + // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. + // + TopOfStack = (VOID *)((UINTN)gRing3CallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + gRing3CallStackTop = TopOfStack; + + SetUefiImageMemoryAttributes ((UINTN)gRing3CallStackBase, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); + DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); + + InitializeMsr ( + gRing3Data->SystemTable.ConfigurationTable, + gRing3Data->SystemTable.NumberOfTableEntries + ); + + return Status; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 349b29b9bc..c89a431d10 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -1,809 +1,809 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include "DxeMain.h" - -EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; -EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; -EFI_FILE_PROTOCOL mRing3FileProtocol; - -EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; - -#if defined (MDE_CPU_AARCH64) -extern UINTN gUartBaseAddress; -#endif - -typedef struct { - EFI_FILE_PROTOCOL Protocol; - EFI_FILE_PROTOCOL *Ring3File; -} RING3_EFI_FILE_PROTOCOL; - -EFI_STATUS -EFIAPI -GoToRing3 ( - IN UINT8 Number, - IN VOID *EntryPoint, - ... - ) -{ - EFI_STATUS Status; - RING3_CALL_DATA *Input; - VA_LIST Marker; - UINTN Index; - EFI_PHYSICAL_ADDRESS Ring3Pages; - UINT32 PagesNumber; - - PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN)); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - PagesNumber, - &Ring3Pages - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Input = (RING3_CALL_DATA *)(UINTN)Ring3Pages; - - DisableSMAP (); - Input->NumberOfArguments = Number; - Input->EntryPoint = EntryPoint; - - VA_START (Marker, EntryPoint); - for (Index = 0; Index < Number; ++Index) { - Input->Arguments[Index] = VA_ARG (Marker, UINTN); - } - VA_END (Marker); - EnableSMAP (); - -#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) - if (Number == 2) { - // - // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() - // - SetUefiImageMemoryAttributes ( - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - } -#elif defined (MDE_CPU_AARCH64) - // - // Necessary fix for DEBUG printings. - // - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); -#endif - Status = CallRing3 (Input); - -#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) - if (Number == 2) { - SetUefiImageMemoryAttributes ( - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP - ); - } -#elif defined (MDE_CPU_AARCH64) - // - // Problem 2: Uart memory maped page is not allocated at the very beginnig - // and can be used for translation table later. - // - DisableSMAP (); - // - // Problem 3: QEMU ramdomly breaks GP registers' context. - // - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP - ); - EnableSMAP (); -#endif - - CoreFreePages (Ring3Pages, PagesNumber); - - return Status; -} - -STATIC -VOID * -EFIAPI -Ring3Copy ( - IN VOID *Core, - IN UINT32 Size - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Ring3; - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - 1, - &Ring3 - ); - if (EFI_ERROR (Status)) { - return NULL; - } - - DisableSMAP (); - CopyMem ((VOID *)(UINTN)Ring3, Core, Size); - EnableSMAP (); - - return (VOID *)(UINTN)Ring3; -} - -EFI_STATUS -EFIAPI -CoreDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ) -{ - EFI_STATUS Status; - - This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); - if (This == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = GoToRing3 ( - 3, - (VOID *)mRing3DriverBindingProtocol.Supported, - This, - ControllerHandle, - RemainingDevicePath - ); - - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); - - return Status; -} - -EFI_STATUS -EFIAPI -CoreDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ) -{ - EFI_STATUS Status; - - This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); - if (This == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = GoToRing3 ( - 3, - (VOID *)mRing3DriverBindingProtocol.Start, - This, - ControllerHandle, - RemainingDevicePath - ); - - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); - - return Status; -} - -EFI_STATUS -EFIAPI -CoreDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer OPTIONAL - ) -{ - EFI_STATUS Status; - - This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); - if (This == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = GoToRing3 ( - 4, - (VOID *)mRing3DriverBindingProtocol.Stop, - This, - ControllerHandle, - NumberOfChildren, - ChildHandleBuffer - ); - - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileClose ( - IN EFI_FILE_PROTOCOL *This - ) -{ - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - - File = (RING3_EFI_FILE_PROTOCOL *)This; - - Status = GoToRing3 ( - 1, - (VOID *)mRing3FileProtocol.Close, - File->Ring3File - ); - - FreePool (This); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileDelete ( - IN EFI_FILE_PROTOCOL *This - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileRead ( - IN EFI_FILE_PROTOCOL *This, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - UINTN *Ring3BufferSize; - VOID *Ring3Buffer; - EFI_PHYSICAL_ADDRESS Ring3Pages; - UINT32 PagesNumber; - - if ((This == NULL) || (BufferSize == NULL)) { - return EFI_INVALID_PARAMETER; - } - - File = (RING3_EFI_FILE_PROTOCOL *)This; - Ring3Buffer = NULL; - Ring3Pages = 0; - - PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - PagesNumber, - &Ring3Pages - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; - - DisableSMAP (); - *Ring3BufferSize = *BufferSize; - EnableSMAP (); - - if (Buffer != NULL) { - Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); - } - - Status = GoToRing3 ( - 3, - (VOID *)mRing3FileProtocol.Read, - File->Ring3File, - Ring3BufferSize, - Ring3Buffer - ); - - DisableSMAP (); - if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { - CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); - } - - *BufferSize = *Ring3BufferSize; - EnableSMAP (); - - CoreFreePages (Ring3Pages, PagesNumber); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileWrite ( - IN EFI_FILE_PROTOCOL *This, - IN OUT UINTN *BufferSize, - IN VOID *Buffer - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileSetPosition ( - IN EFI_FILE_PROTOCOL *This, - IN UINT64 Position - ) -{ - RING3_EFI_FILE_PROTOCOL *File; - - File = (RING3_EFI_FILE_PROTOCOL *)This; - -#if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) - return GoToRing3 ( - 2, - (VOID *)mRing3FileProtocol.SetPosition, - File->Ring3File, - Position - ); -#elif defined (MDE_CPU_IA32) - // - // UINT64 Position is passed as 2 double words on stack. - // - return GoToRing3 ( - 3, - (VOID *)mRing3FileProtocol.SetPosition, - File->Ring3File, - Position - ); -#elif defined (MDE_CPU_ARM) - // - // UINT64 Position is passed as 2 words in 2 registers and is aligned on 8 bytes. - // R0 == File->Ring3File, R1 == NULL, R2 == Position_Low, R3 == Position_High. - // - return GoToRing3 ( - 4, - (VOID *)mRing3FileProtocol.SetPosition, - File->Ring3File, - Position - ); -#endif - -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileGetPosition ( - IN EFI_FILE_PROTOCOL *This, - OUT UINT64 *Position - ) -{ - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - EFI_PHYSICAL_ADDRESS Ring3Position; - - if ((This == NULL) || (Position == NULL)) { - return EFI_INVALID_PARAMETER; - } - - File = (RING3_EFI_FILE_PROTOCOL *)This; - Ring3Position = 0; - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - 1, - &Ring3Position - ); - if (EFI_ERROR (Status)) { - return Status; - } - - DisableSMAP (); - *(UINT64 *)(UINTN)Ring3Position = *Position; - EnableSMAP (); - - Status = GoToRing3 ( - 2, - (VOID *)mRing3FileProtocol.GetPosition, - File->Ring3File, - Ring3Position - ); - - DisableSMAP (); - *Position = *(UINT64 *)(UINTN)Ring3Position; - EnableSMAP (); - - CoreFreePages (Ring3Position, 1); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileGetInfo ( - IN EFI_FILE_PROTOCOL *This, - IN EFI_GUID *InformationType, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ) -{ - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - EFI_GUID *Ring3InformationType; - UINTN *Ring3BufferSize; - VOID *Ring3Buffer; - EFI_PHYSICAL_ADDRESS Ring3Pages; - UINT32 PagesNumber; - - if ((This == NULL) || (BufferSize == NULL)) { - return EFI_INVALID_PARAMETER; - } - - File = (RING3_EFI_FILE_PROTOCOL *)This; - Ring3Buffer = NULL; - Ring3InformationType = NULL; - Ring3Pages = 0; - - PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize + sizeof (EFI_GUID)); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - PagesNumber, - &Ring3Pages - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; - - DisableSMAP (); - *Ring3BufferSize = *BufferSize; - EnableSMAP (); - - if (Buffer != NULL) { - Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); - } - - if (InformationType != NULL) { - Ring3InformationType = (EFI_GUID *)((UINTN)Ring3Pages + sizeof (UINTN *) + *BufferSize); - - DisableSMAP (); - CopyGuid (Ring3InformationType, InformationType); - EnableSMAP (); - } - - Status = GoToRing3 ( - 4, - (VOID *)mRing3FileProtocol.GetInfo, - File->Ring3File, - Ring3InformationType, - Ring3BufferSize, - Ring3Buffer - ); - - DisableSMAP (); - if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { - CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); - } - - *BufferSize = *Ring3BufferSize; - EnableSMAP (); - - CoreFreePages (Ring3Pages, PagesNumber); - - return Status; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileSetInfo ( - IN EFI_FILE_PROTOCOL *This, - IN EFI_GUID *InformationType, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileFlush ( - IN EFI_FILE_PROTOCOL *This - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileOpenEx ( - IN EFI_FILE_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **NewHandle, - IN CHAR16 *FileName, - IN UINT64 OpenMode, - IN UINT64 Attributes, - IN OUT EFI_FILE_IO_TOKEN *Token - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileReadEx ( - IN EFI_FILE_PROTOCOL *This, - IN OUT EFI_FILE_IO_TOKEN *Token - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileWriteEx ( - IN EFI_FILE_PROTOCOL *This, - IN OUT EFI_FILE_IO_TOKEN *Token - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileFlushEx ( - IN EFI_FILE_PROTOCOL *This, - IN OUT EFI_FILE_IO_TOKEN *Token - ) -{ - return EFI_UNSUPPORTED; -} - -STATIC -EFI_STATUS -EFIAPI -CoreFileOpen ( - IN EFI_FILE_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **NewHandle, - IN CHAR16 *FileName, - IN UINT64 OpenMode, - IN UINT64 Attributes - ) -{ - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - RING3_EFI_FILE_PROTOCOL *NewFile; - EFI_FILE_PROTOCOL **Ring3NewHandle; - CHAR16 *Ring3FileName; - EFI_PHYSICAL_ADDRESS Ring3Pages; - UINT32 PagesNumber; - - if ((This == NULL) || (NewHandle == NULL) || (FileName == NULL)) { - return EFI_INVALID_PARAMETER; - } - - File = (RING3_EFI_FILE_PROTOCOL *)This; - Ring3NewHandle = NULL; - Ring3FileName = NULL; - Ring3Pages = 0; - - PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (EFI_FILE_PROTOCOL *) + StrSize (FileName)); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - PagesNumber, - &Ring3Pages - ); - if (EFI_ERROR (Status)) { - *NewHandle = NULL; - return Status; - } - - Ring3NewHandle = (EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages; - Ring3FileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages + 1); - - DisableSMAP (); - Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName); - EnableSMAP (); - if (EFI_ERROR (Status)) { - *NewHandle = NULL; - CoreFreePages (Ring3Pages, PagesNumber); - return Status; - } - -#if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) - Status = GoToRing3 ( - 5, - (VOID *)mRing3FileProtocol.Open, - File->Ring3File, - Ring3NewHandle, - Ring3FileName, - OpenMode, - Attributes - ); -#elif defined (MDE_CPU_IA32) - // - // UINT64 OpenMode and Attributes are each passed as 2 double words on stack. - // - Status = GoToRing3 ( - 7, - (VOID *)mRing3FileProtocol.Open, - File->Ring3File, - Ring3NewHandle, - Ring3FileName, - OpenMode, - Attributes - ); -#elif defined (MDE_CPU_ARM) - // - // UINT64 OpenMode and Attributes are each passed as 2 words on stack. - // Each of them is aligned on 8 bytes. - // R0 == File->Ring3File, R1 == Ring3NewHandle, R2 == Ring3FileName, R3 == NULL, - // [SP] == OpenMode, [SP + 8] == Attributes. - // - Status = GoToRing3 ( - 8, - (VOID *)mRing3FileProtocol.Open, - File->Ring3File, - Ring3NewHandle, - Ring3FileName, - OpenMode, - Attributes - ); -#endif - if (EFI_ERROR (Status)) { - *NewHandle = NULL; - CoreFreePages (Ring3Pages, PagesNumber); - return Status; - } - - NewFile = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); - if (NewFile == NULL) { - *NewHandle = NULL; - CoreFreePages (Ring3Pages, PagesNumber); - return EFI_OUT_OF_RESOURCES; - } - - NewFile->Protocol.Revision = mRing3FileProtocol.Revision; - NewFile->Protocol.Open = CoreFileOpen; - NewFile->Protocol.Close = CoreFileClose; - NewFile->Protocol.Delete = CoreFileDelete; - NewFile->Protocol.Read = CoreFileRead; - NewFile->Protocol.Write = CoreFileWrite; - NewFile->Protocol.GetPosition = CoreFileGetPosition; - NewFile->Protocol.SetPosition = CoreFileSetPosition; - NewFile->Protocol.GetInfo = CoreFileGetInfo; - NewFile->Protocol.SetInfo = CoreFileSetInfo; - NewFile->Protocol.Flush = CoreFileFlush; - NewFile->Protocol.OpenEx = CoreFileOpenEx; - NewFile->Protocol.ReadEx = CoreFileReadEx; - NewFile->Protocol.WriteEx = CoreFileWriteEx; - NewFile->Protocol.FlushEx = CoreFileFlushEx; - - DisableSMAP (); - NewFile->Ring3File = *Ring3NewHandle; - EnableSMAP (); - - *NewHandle = (EFI_FILE_PROTOCOL *)NewFile; - - CoreFreePages (Ring3Pages, PagesNumber); - - return Status; -} - -EFI_STATUS -EFIAPI -CoreOpenVolume ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **Root - ) -{ - EFI_STATUS Status; - EFI_FILE_PROTOCOL **Ring3Root; - RING3_EFI_FILE_PROTOCOL *File; - EFI_PHYSICAL_ADDRESS Physical; - - if (Root == NULL) { - return EFI_INVALID_PARAMETER; - } - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - 1, - &Physical - ); - if (EFI_ERROR (Status)) { - *Root = NULL; - return Status; - } - - Ring3Root = (EFI_FILE_PROTOCOL **)(UINTN)Physical; - - Status = GoToRing3 ( - 2, - (VOID *)mRing3SimpleFileSystemProtocol.OpenVolume, - mRing3SimpleFileSystemPointer, - Ring3Root - ); - if (EFI_ERROR (Status)) { - *Root = NULL; - CoreFreePages (Physical, 1); - return Status; - } - - File = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); - if (File == NULL) { - *Root = NULL; - CoreFreePages (Physical, 1); - return EFI_OUT_OF_RESOURCES; - } - - DisableSMAP (); - mRing3FileProtocol.Revision = (*Ring3Root)->Revision; - mRing3FileProtocol.Open = (*Ring3Root)->Open; - mRing3FileProtocol.Close = (*Ring3Root)->Close; - mRing3FileProtocol.Delete = (*Ring3Root)->Delete; - mRing3FileProtocol.Read = (*Ring3Root)->Read; - mRing3FileProtocol.Write = (*Ring3Root)->Write; - mRing3FileProtocol.GetPosition = (*Ring3Root)->GetPosition; - mRing3FileProtocol.SetPosition = (*Ring3Root)->SetPosition; - mRing3FileProtocol.GetInfo = (*Ring3Root)->GetInfo; - mRing3FileProtocol.SetInfo = (*Ring3Root)->SetInfo; - mRing3FileProtocol.Flush = (*Ring3Root)->Flush; - mRing3FileProtocol.OpenEx = (*Ring3Root)->OpenEx; - mRing3FileProtocol.ReadEx = (*Ring3Root)->ReadEx; - mRing3FileProtocol.WriteEx = (*Ring3Root)->WriteEx; - mRing3FileProtocol.FlushEx = (*Ring3Root)->FlushEx; - - File->Ring3File = *Ring3Root; - EnableSMAP (); - - File->Protocol.Revision = mRing3FileProtocol.Revision; - File->Protocol.Open = CoreFileOpen; - File->Protocol.Close = CoreFileClose; - File->Protocol.Delete = CoreFileDelete; - File->Protocol.Read = CoreFileRead; - File->Protocol.Write = CoreFileWrite; - File->Protocol.GetPosition = CoreFileGetPosition; - File->Protocol.SetPosition = CoreFileSetPosition; - File->Protocol.GetInfo = CoreFileGetInfo; - File->Protocol.SetInfo = CoreFileSetInfo; - File->Protocol.Flush = CoreFileFlush; - File->Protocol.OpenEx = CoreFileOpenEx; - File->Protocol.ReadEx = CoreFileReadEx; - File->Protocol.WriteEx = CoreFileWriteEx; - File->Protocol.FlushEx = CoreFileFlushEx; - - *Root = (EFI_FILE_PROTOCOL *)File; - - CoreFreePages (Physical, 1); - - return Status; -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; +EFI_FILE_PROTOCOL mRing3FileProtocol; + +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; + +#if defined (MDE_CPU_AARCH64) +extern UINTN gUartBaseAddress; +#endif + +typedef struct { + EFI_FILE_PROTOCOL Protocol; + EFI_FILE_PROTOCOL *Ring3File; +} RING3_EFI_FILE_PROTOCOL; + +EFI_STATUS +EFIAPI +GoToRing3 ( + IN UINT8 Number, + IN VOID *EntryPoint, + ... + ) +{ + EFI_STATUS Status; + RING3_CALL_DATA *Input; + VA_LIST Marker; + UINTN Index; + EFI_PHYSICAL_ADDRESS Ring3Pages; + UINT32 PagesNumber; + + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + &Ring3Pages + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Input = (RING3_CALL_DATA *)(UINTN)Ring3Pages; + + DisableSMAP (); + Input->NumberOfArguments = Number; + Input->EntryPoint = EntryPoint; + + VA_START (Marker, EntryPoint); + for (Index = 0; Index < Number; ++Index) { + Input->Arguments[Index] = VA_ARG (Marker, UINTN); + } + VA_END (Marker); + EnableSMAP (); + +#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) + if (Number == 2) { + // + // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() + // + SetUefiImageMemoryAttributes ( + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + } +#elif defined (MDE_CPU_AARCH64) + // + // Necessary fix for DEBUG printings. + // + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); +#endif + Status = CallRing3 (Input); + +#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) + if (Number == 2) { + SetUefiImageMemoryAttributes ( + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP + ); + } +#elif defined (MDE_CPU_AARCH64) + // + // Problem 2: Uart memory maped page is not allocated at the very beginnig + // and can be used for translation table later. + // + DisableSMAP (); + // + // Problem 3: QEMU ramdomly breaks GP registers' context. + // + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP + ); + EnableSMAP (); +#endif + + CoreFreePages (Ring3Pages, PagesNumber); + + return Status; +} + +STATIC +VOID * +EFIAPI +Ring3Copy ( + IN VOID *Core, + IN UINT32 Size + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Ring3; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + 1, + &Ring3 + ); + if (EFI_ERROR (Status)) { + return NULL; + } + + DisableSMAP (); + CopyMem ((VOID *)(UINTN)Ring3, Core, Size); + EnableSMAP (); + + return (VOID *)(UINTN)Ring3; +} + +EFI_STATUS +EFIAPI +CoreDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + EFI_STATUS Status; + + This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); + if (This == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = GoToRing3 ( + 3, + (VOID *)mRing3DriverBindingProtocol.Supported, + This, + ControllerHandle, + RemainingDevicePath + ); + + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); + + return Status; +} + +EFI_STATUS +EFIAPI +CoreDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + EFI_STATUS Status; + + This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); + if (This == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = GoToRing3 ( + 3, + (VOID *)mRing3DriverBindingProtocol.Start, + This, + ControllerHandle, + RemainingDevicePath + ); + + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); + + return Status; +} + +EFI_STATUS +EFIAPI +CoreDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +{ + EFI_STATUS Status; + + This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); + if (This == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = GoToRing3 ( + 4, + (VOID *)mRing3DriverBindingProtocol.Stop, + This, + ControllerHandle, + NumberOfChildren, + ChildHandleBuffer + ); + + CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); + + return Status; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileClose ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + + File = (RING3_EFI_FILE_PROTOCOL *)This; + + Status = GoToRing3 ( + 1, + (VOID *)mRing3FileProtocol.Close, + File->Ring3File + ); + + FreePool (This); + + return Status; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileDelete ( + IN EFI_FILE_PROTOCOL *This + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileRead ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + UINTN *Ring3BufferSize; + VOID *Ring3Buffer; + EFI_PHYSICAL_ADDRESS Ring3Pages; + UINT32 PagesNumber; + + if ((This == NULL) || (BufferSize == NULL)) { + return EFI_INVALID_PARAMETER; + } + + File = (RING3_EFI_FILE_PROTOCOL *)This; + Ring3Buffer = NULL; + Ring3Pages = 0; + + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + &Ring3Pages + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; + + DisableSMAP (); + *Ring3BufferSize = *BufferSize; + EnableSMAP (); + + if (Buffer != NULL) { + Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); + } + + Status = GoToRing3 ( + 3, + (VOID *)mRing3FileProtocol.Read, + File->Ring3File, + Ring3BufferSize, + Ring3Buffer + ); + + DisableSMAP (); + if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { + CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); + } + + *BufferSize = *Ring3BufferSize; + EnableSMAP (); + + CoreFreePages (Ring3Pages, PagesNumber); + + return Status; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileWrite ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileSetPosition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ) +{ + RING3_EFI_FILE_PROTOCOL *File; + + File = (RING3_EFI_FILE_PROTOCOL *)This; + +#if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) + return GoToRing3 ( + 2, + (VOID *)mRing3FileProtocol.SetPosition, + File->Ring3File, + Position + ); +#elif defined (MDE_CPU_IA32) + // + // UINT64 Position is passed as 2 double words on stack. + // + return GoToRing3 ( + 3, + (VOID *)mRing3FileProtocol.SetPosition, + File->Ring3File, + Position + ); +#elif defined (MDE_CPU_ARM) + // + // UINT64 Position is passed as 2 words in 2 registers and is aligned on 8 bytes. + // R0 == File->Ring3File, R1 == NULL, R2 == Position_Low, R3 == Position_High. + // + return GoToRing3 ( + 4, + (VOID *)mRing3FileProtocol.SetPosition, + File->Ring3File, + Position + ); +#endif + +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileGetPosition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ) +{ + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + EFI_PHYSICAL_ADDRESS Ring3Position; + + if ((This == NULL) || (Position == NULL)) { + return EFI_INVALID_PARAMETER; + } + + File = (RING3_EFI_FILE_PROTOCOL *)This; + Ring3Position = 0; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + 1, + &Ring3Position + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DisableSMAP (); + *(UINT64 *)(UINTN)Ring3Position = *Position; + EnableSMAP (); + + Status = GoToRing3 ( + 2, + (VOID *)mRing3FileProtocol.GetPosition, + File->Ring3File, + Ring3Position + ); + + DisableSMAP (); + *Position = *(UINT64 *)(UINTN)Ring3Position; + EnableSMAP (); + + CoreFreePages (Ring3Position, 1); + + return Status; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + EFI_GUID *Ring3InformationType; + UINTN *Ring3BufferSize; + VOID *Ring3Buffer; + EFI_PHYSICAL_ADDRESS Ring3Pages; + UINT32 PagesNumber; + + if ((This == NULL) || (BufferSize == NULL)) { + return EFI_INVALID_PARAMETER; + } + + File = (RING3_EFI_FILE_PROTOCOL *)This; + Ring3Buffer = NULL; + Ring3InformationType = NULL; + Ring3Pages = 0; + + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize + sizeof (EFI_GUID)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + &Ring3Pages + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; + + DisableSMAP (); + *Ring3BufferSize = *BufferSize; + EnableSMAP (); + + if (Buffer != NULL) { + Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); + } + + if (InformationType != NULL) { + Ring3InformationType = (EFI_GUID *)((UINTN)Ring3Pages + sizeof (UINTN *) + *BufferSize); + + DisableSMAP (); + CopyGuid (Ring3InformationType, InformationType); + EnableSMAP (); + } + + Status = GoToRing3 ( + 4, + (VOID *)mRing3FileProtocol.GetInfo, + File->Ring3File, + Ring3InformationType, + Ring3BufferSize, + Ring3Buffer + ); + + DisableSMAP (); + if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { + CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); + } + + *BufferSize = *Ring3BufferSize; + EnableSMAP (); + + CoreFreePages (Ring3Pages, PagesNumber); + + return Status; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileFlush ( + IN EFI_FILE_PROTOCOL *This + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileOpenEx ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes, + IN OUT EFI_FILE_IO_TOKEN *Token + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileReadEx ( + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileWriteEx ( + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileFlushEx ( + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token + ) +{ + return EFI_UNSUPPORTED; +} + +STATIC +EFI_STATUS +EFIAPI +CoreFileOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + EFI_STATUS Status; + RING3_EFI_FILE_PROTOCOL *File; + RING3_EFI_FILE_PROTOCOL *NewFile; + EFI_FILE_PROTOCOL **Ring3NewHandle; + CHAR16 *Ring3FileName; + EFI_PHYSICAL_ADDRESS Ring3Pages; + UINT32 PagesNumber; + + if ((This == NULL) || (NewHandle == NULL) || (FileName == NULL)) { + return EFI_INVALID_PARAMETER; + } + + File = (RING3_EFI_FILE_PROTOCOL *)This; + Ring3NewHandle = NULL; + Ring3FileName = NULL; + Ring3Pages = 0; + + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (EFI_FILE_PROTOCOL *) + StrSize (FileName)); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + PagesNumber, + &Ring3Pages + ); + if (EFI_ERROR (Status)) { + *NewHandle = NULL; + return Status; + } + + Ring3NewHandle = (EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages; + Ring3FileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages + 1); + + DisableSMAP (); + Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName); + EnableSMAP (); + if (EFI_ERROR (Status)) { + *NewHandle = NULL; + CoreFreePages (Ring3Pages, PagesNumber); + return Status; + } + +#if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) + Status = GoToRing3 ( + 5, + (VOID *)mRing3FileProtocol.Open, + File->Ring3File, + Ring3NewHandle, + Ring3FileName, + OpenMode, + Attributes + ); +#elif defined (MDE_CPU_IA32) + // + // UINT64 OpenMode and Attributes are each passed as 2 double words on stack. + // + Status = GoToRing3 ( + 7, + (VOID *)mRing3FileProtocol.Open, + File->Ring3File, + Ring3NewHandle, + Ring3FileName, + OpenMode, + Attributes + ); +#elif defined (MDE_CPU_ARM) + // + // UINT64 OpenMode and Attributes are each passed as 2 words on stack. + // Each of them is aligned on 8 bytes. + // R0 == File->Ring3File, R1 == Ring3NewHandle, R2 == Ring3FileName, R3 == NULL, + // [SP] == OpenMode, [SP + 8] == Attributes. + // + Status = GoToRing3 ( + 8, + (VOID *)mRing3FileProtocol.Open, + File->Ring3File, + Ring3NewHandle, + Ring3FileName, + OpenMode, + Attributes + ); +#endif + if (EFI_ERROR (Status)) { + *NewHandle = NULL; + CoreFreePages (Ring3Pages, PagesNumber); + return Status; + } + + NewFile = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); + if (NewFile == NULL) { + *NewHandle = NULL; + CoreFreePages (Ring3Pages, PagesNumber); + return EFI_OUT_OF_RESOURCES; + } + + NewFile->Protocol.Revision = mRing3FileProtocol.Revision; + NewFile->Protocol.Open = CoreFileOpen; + NewFile->Protocol.Close = CoreFileClose; + NewFile->Protocol.Delete = CoreFileDelete; + NewFile->Protocol.Read = CoreFileRead; + NewFile->Protocol.Write = CoreFileWrite; + NewFile->Protocol.GetPosition = CoreFileGetPosition; + NewFile->Protocol.SetPosition = CoreFileSetPosition; + NewFile->Protocol.GetInfo = CoreFileGetInfo; + NewFile->Protocol.SetInfo = CoreFileSetInfo; + NewFile->Protocol.Flush = CoreFileFlush; + NewFile->Protocol.OpenEx = CoreFileOpenEx; + NewFile->Protocol.ReadEx = CoreFileReadEx; + NewFile->Protocol.WriteEx = CoreFileWriteEx; + NewFile->Protocol.FlushEx = CoreFileFlushEx; + + DisableSMAP (); + NewFile->Ring3File = *Ring3NewHandle; + EnableSMAP (); + + *NewHandle = (EFI_FILE_PROTOCOL *)NewFile; + + CoreFreePages (Ring3Pages, PagesNumber); + + return Status; +} + +EFI_STATUS +EFIAPI +CoreOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ) +{ + EFI_STATUS Status; + EFI_FILE_PROTOCOL **Ring3Root; + RING3_EFI_FILE_PROTOCOL *File; + EFI_PHYSICAL_ADDRESS Physical; + + if (Root == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + 1, + &Physical + ); + if (EFI_ERROR (Status)) { + *Root = NULL; + return Status; + } + + Ring3Root = (EFI_FILE_PROTOCOL **)(UINTN)Physical; + + Status = GoToRing3 ( + 2, + (VOID *)mRing3SimpleFileSystemProtocol.OpenVolume, + mRing3SimpleFileSystemPointer, + Ring3Root + ); + if (EFI_ERROR (Status)) { + *Root = NULL; + CoreFreePages (Physical, 1); + return Status; + } + + File = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); + if (File == NULL) { + *Root = NULL; + CoreFreePages (Physical, 1); + return EFI_OUT_OF_RESOURCES; + } + + DisableSMAP (); + mRing3FileProtocol.Revision = (*Ring3Root)->Revision; + mRing3FileProtocol.Open = (*Ring3Root)->Open; + mRing3FileProtocol.Close = (*Ring3Root)->Close; + mRing3FileProtocol.Delete = (*Ring3Root)->Delete; + mRing3FileProtocol.Read = (*Ring3Root)->Read; + mRing3FileProtocol.Write = (*Ring3Root)->Write; + mRing3FileProtocol.GetPosition = (*Ring3Root)->GetPosition; + mRing3FileProtocol.SetPosition = (*Ring3Root)->SetPosition; + mRing3FileProtocol.GetInfo = (*Ring3Root)->GetInfo; + mRing3FileProtocol.SetInfo = (*Ring3Root)->SetInfo; + mRing3FileProtocol.Flush = (*Ring3Root)->Flush; + mRing3FileProtocol.OpenEx = (*Ring3Root)->OpenEx; + mRing3FileProtocol.ReadEx = (*Ring3Root)->ReadEx; + mRing3FileProtocol.WriteEx = (*Ring3Root)->WriteEx; + mRing3FileProtocol.FlushEx = (*Ring3Root)->FlushEx; + + File->Ring3File = *Ring3Root; + EnableSMAP (); + + File->Protocol.Revision = mRing3FileProtocol.Revision; + File->Protocol.Open = CoreFileOpen; + File->Protocol.Close = CoreFileClose; + File->Protocol.Delete = CoreFileDelete; + File->Protocol.Read = CoreFileRead; + File->Protocol.Write = CoreFileWrite; + File->Protocol.GetPosition = CoreFileGetPosition; + File->Protocol.SetPosition = CoreFileSetPosition; + File->Protocol.GetInfo = CoreFileGetInfo; + File->Protocol.SetInfo = CoreFileSetInfo; + File->Protocol.Flush = CoreFileFlush; + File->Protocol.OpenEx = CoreFileOpenEx; + File->Protocol.ReadEx = CoreFileReadEx; + File->Protocol.WriteEx = CoreFileWriteEx; + File->Protocol.FlushEx = CoreFileFlushEx; + + *Root = (EFI_FILE_PROTOCOL *)File; + + CoreFreePages (Physical, 1); + + return Status; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h index 8f77026355..235d62872d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -1,48 +1,48 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include -#include -#include -#include -#include - -extern EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; -extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; -extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; - -EFI_STATUS -EFIAPI -CoreDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ); - -EFI_STATUS -EFIAPI -CoreDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ); - -EFI_STATUS -EFIAPI -CoreDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer OPTIONAL - ); - -EFI_STATUS -EFIAPI -CoreOpenVolume ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **Root - ); +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include +#include +#include +#include +#include + +extern EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; +extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; +extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; + +EFI_STATUS +EFIAPI +CoreDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +EFI_STATUS +EFIAPI +CoreDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +EFI_STATUS +EFIAPI +CoreDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ); + +EFI_STATUS +EFIAPI +CoreOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ); diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index a18680ed6c..cf1bd7c94b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -1,246 +1,246 @@ -;------------------------------------------------------------------------------ -; -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. -; SPDX-License-Identifier: BSD-3-Clause -; -;------------------------------------------------------------------------------ - -#include - -extern ASM_PFX(CallBootService) -extern ASM_PFX(gCoreSysCallStackTop) -extern ASM_PFX(gRing3CallStackTop) -extern ASM_PFX(gRing3EntryPoint) - -DEFAULT REL -SECTION .text - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; DisableSMAP ( -; VOID -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(DisableSMAP) -ASM_PFX(DisableSMAP): - pushfq - pop r10 - or r10, 0x40000 ; Set AC (bit 18) - push r10 - popfq - ret - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; EnableSMAP ( -; VOID -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(EnableSMAP) -ASM_PFX(EnableSMAP): - pushfq - pop r10 - and r10, ~0x40000 ; Clear AC (bit 18) - push r10 - popfq - ret - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; CallInstallMultipleProtocolInterfaces ( -; IN EFI_HANDLE *Handle, -; IN VOID **ArgList, -; IN UINT32 ArgListSize, -; IN VOID *Function -; ); -;------------------------------------------------------------------------------ -global ASM_PFX(CallInstallMultipleProtocolInterfaces) -ASM_PFX(CallInstallMultipleProtocolInterfaces): - push r12 - - ; Save function input. - mov rax, rdx - mov r10, r8 - mov r11, r9 - - ; Prepare registers for call. - mov rdx, [rax] - mov r8, [rax + 8] - mov r9, [rax + 8*2] - - ; Prepare stack for call. - lea rax, [rax + r10 * 8] - mov r12, r10 -copy: - sub rax, 8 - push qword [rax] - sub r10, 1 - jnz copy - push rcx - - call r11 - - ; Step over Function arguments. - pop rcx - lea rsp, [rsp + r12 * 8] - - pop r12 - - ret - -%macro SetRing3DataSegmentSelectors 0 - mov rcx, MSR_IA32_STAR - rdmsr - shl rdx, 0x20 - or rax, rdx - ; rax = ((RING3_CODE64_SEL - 16) << 16 | RING0_CODE64_SEL) << 32 - shr rax, 48 - add rax, 8 - - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax -%endmacro - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; CoreBootServices ( -; IN UINT8 Type, -; ... -; ); -; -; (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). -; (rdx) Argument 1 of the called function. -; (r8) Argument 2 of the called function. -; (r9) Argument 3 of the called function. -; (r10) Type. -; (r11) RFLAGS saved by SYSCALL in SysCall(). -; -; (On User Stack) Argument 4, 5, ... -;------------------------------------------------------------------------------ -global ASM_PFX(CoreBootServices) -ASM_PFX(CoreBootServices): - ; Switch from User to Core data segment selectors. - mov ax, ss - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - ; Special case for SysCallReturnToCore. - cmp r10, 0 - je coreReturnAddress - - ; Save User Stack pointers and switch to Core SysCall Stack. - mov rax, [ASM_PFX(gCoreSysCallStackTop)] - sub rax, 8 - mov [rax], rsp - mov rsp, rax - push rbp - ; Save return address for SYSRET. - push rcx - ; Save User RFLAGS for SYSRET. - push r11 - ; Save User Arguments [1..3]. - push r9 - push r8 - push rdx - mov rbp, rsp - - ; Prepare CallBootService arguments. - mov rcx, r10 - mov rdx, rbp - mov r8, [rbp + 8*6] - - sti - call ASM_PFX(CallBootService) - push rax - cli - - SetRing3DataSegmentSelectors - - pop rax - - ; Step over Arguments [1..3]. - add rsp, 8*3 - - ; Prepare SYSRET arguments. - pop r11 - pop rcx - - ; Switch to User Stack. - pop rbp - pop rsp - - ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. -o64 sysret - ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. - -;------------------------------------------------------------------------------ -; EFI_STATUS -; EFIAPI -; CallRing3 ( -; IN RING3_CALL_DATA *Data -; ); -; -; (rcx) Data -;------------------------------------------------------------------------------ -global ASM_PFX(CallRing3) -ASM_PFX(CallRing3): - pushfq - pop r11 - cli - ; Save nonvolatile registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15. - push rbx - push rbp - push rdi - push rsi - push r12 - push r13 - push r14 - push r15 - - ; Save Core Stack pointer. - mov [ASM_PFX(CoreRsp)], rsp - - ; Save input Arguments. - mov r8, [ASM_PFX(gRing3CallStackTop)] - mov r9, [ASM_PFX(gRing3EntryPoint)] - mov r10, rcx - - SetRing3DataSegmentSelectors - - ; Prepare SYSRET arguments. - mov rdx, r10 - mov rcx, r9 - - ; Switch to User Stack. - mov rsp, r8 - mov rbp, rsp - - ; Pass control to user image -o64 sysret - -coreReturnAddress: - mov rsp, [ASM_PFX(CoreRsp)] - pop r15 - pop r14 - pop r13 - pop r12 - pop rsi - pop rdi - pop rbp - pop rbx - - mov rax, rdx - sti - ret - -SECTION .data -ASM_PFX(CoreRsp): - resq 1 +;------------------------------------------------------------------------------ +; +; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; SPDX-License-Identifier: BSD-3-Clause +; +;------------------------------------------------------------------------------ + +#include + +extern ASM_PFX(CallBootService) +extern ASM_PFX(gCoreSysCallStackTop) +extern ASM_PFX(gRing3CallStackTop) +extern ASM_PFX(gRing3EntryPoint) + +DEFAULT REL +SECTION .text + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; DisableSMAP ( +; VOID +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(DisableSMAP) +ASM_PFX(DisableSMAP): + pushfq + pop r10 + or r10, 0x40000 ; Set AC (bit 18) + push r10 + popfq + ret + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; EnableSMAP ( +; VOID +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(EnableSMAP) +ASM_PFX(EnableSMAP): + pushfq + pop r10 + and r10, ~0x40000 ; Clear AC (bit 18) + push r10 + popfq + ret + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CallInstallMultipleProtocolInterfaces ( +; IN EFI_HANDLE *Handle, +; IN VOID **ArgList, +; IN UINT32 ArgListSize, +; IN VOID *Function +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(CallInstallMultipleProtocolInterfaces) +ASM_PFX(CallInstallMultipleProtocolInterfaces): + push r12 + + ; Save function input. + mov rax, rdx + mov r10, r8 + mov r11, r9 + + ; Prepare registers for call. + mov rdx, [rax] + mov r8, [rax + 8] + mov r9, [rax + 8*2] + + ; Prepare stack for call. + lea rax, [rax + r10 * 8] + mov r12, r10 +copy: + sub rax, 8 + push qword [rax] + sub r10, 1 + jnz copy + push rcx + + call r11 + + ; Step over Function arguments. + pop rcx + lea rsp, [rsp + r12 * 8] + + pop r12 + + ret + +%macro SetRing3DataSegmentSelectors 0 + mov rcx, MSR_IA32_STAR + rdmsr + shl rdx, 0x20 + or rax, rdx + ; rax = ((RING3_CODE64_SEL - 16) << 16 | RING0_CODE64_SEL) << 32 + shr rax, 48 + add rax, 8 + + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax +%endmacro + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CoreBootServices ( +; IN UINT8 Type, +; ... +; ); +; +; (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). +; (rdx) Argument 1 of the called function. +; (r8) Argument 2 of the called function. +; (r9) Argument 3 of the called function. +; (r10) Type. +; (r11) RFLAGS saved by SYSCALL in SysCall(). +; +; (On User Stack) Argument 4, 5, ... +;------------------------------------------------------------------------------ +global ASM_PFX(CoreBootServices) +ASM_PFX(CoreBootServices): + ; Switch from User to Core data segment selectors. + mov ax, ss + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; Special case for SysCallReturnToCore. + cmp r10, 0 + je coreReturnAddress + + ; Save User Stack pointers and switch to Core SysCall Stack. + mov rax, [ASM_PFX(gCoreSysCallStackTop)] + sub rax, 8 + mov [rax], rsp + mov rsp, rax + push rbp + ; Save return address for SYSRET. + push rcx + ; Save User RFLAGS for SYSRET. + push r11 + ; Save User Arguments [1..3]. + push r9 + push r8 + push rdx + mov rbp, rsp + + ; Prepare CallBootService arguments. + mov rcx, r10 + mov rdx, rbp + mov r8, [rbp + 8*6] + + sti + call ASM_PFX(CallBootService) + push rax + cli + + SetRing3DataSegmentSelectors + + pop rax + + ; Step over Arguments [1..3]. + add rsp, 8*3 + + ; Prepare SYSRET arguments. + pop r11 + pop rcx + + ; Switch to User Stack. + pop rbp + pop rsp + + ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. +o64 sysret + ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; CallRing3 ( +; IN RING3_CALL_DATA *Data +; ); +; +; (rcx) Data +;------------------------------------------------------------------------------ +global ASM_PFX(CallRing3) +ASM_PFX(CallRing3): + pushfq + pop r11 + cli + ; Save nonvolatile registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15. + push rbx + push rbp + push rdi + push rsi + push r12 + push r13 + push r14 + push r15 + + ; Save Core Stack pointer. + mov [ASM_PFX(CoreRsp)], rsp + + ; Save input Arguments. + mov r8, [ASM_PFX(gRing3CallStackTop)] + mov r9, [ASM_PFX(gRing3EntryPoint)] + mov r10, rcx + + SetRing3DataSegmentSelectors + + ; Prepare SYSRET arguments. + mov rdx, r10 + mov rcx, r9 + + ; Switch to User Stack. + mov rsp, r8 + mov rbp, rsp + + ; Pass control to user image +o64 sysret + +coreReturnAddress: + mov rsp, [ASM_PFX(CoreRsp)] + pop r15 + pop r14 + pop r13 + pop r12 + pop rsi + pop rdi + pop rbp + pop rbx + + mov rax, rdx + sti + ret + +SECTION .data +ASM_PFX(CoreRsp): + resq 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c index 348d850f1c..9694c071c2 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c @@ -1,70 +1,70 @@ -/** @file - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ - -#include "DxeMain.h" - -#include - -VOID -EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries - ) -{ - UINT64 Msr; - IA32_CR4 Cr4; - IA32_EFLAGS32 Eflags; - UINT32 Ebx; - UINT32 Edx; - MSR_IA32_EFER_REGISTER MsrEfer; - - Ebx = 0; - Edx = 0; - - // - // Forbid supervisor-mode accesses to any user-mode pages. - // - AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); - if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { - Cr4.UintN = AsmReadCr4 (); - Cr4.Bits.SMAP = 1; - Cr4.Bits.SMEP = 1; - AsmWriteCr4 (Cr4.UintN); - - Eflags.UintN = AsmReadEflags (); - Eflags.Bits.AC = 0; - AsmWriteEflags (Eflags.UintN); - } - - // - // Enable SYSCALL and SYSRET. - // - AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); - if ((Edx & BIT11) != 0) { - MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); - MsrEfer.Bits.SCE = 1; - AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); - } else { - DEBUG ((DEBUG_ERROR, "Core: SYSCALL and SYSRET are not supported.\n")); - CpuDeadLoop (); - } - - // - // Initialize MSR_IA32_STAR, MSR_IA32_LSTAR and MSR_IA32_FMASK for SYSCALL and SYSRET. - // - Msr = (((((UINT64)RING3_CODE64_SEL - 16) | 3) << 16) | (UINT64)RING0_CODE64_SEL) << 32; - AsmWriteMsr64 (MSR_IA32_STAR, Msr); - - Msr = (UINT64)(UINTN)CoreBootServices; - AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); - // - // Disable maskable interrupts at SYSCALL. - // - Msr = (UINT64)BIT9; - AsmWriteMsr64 (MSR_IA32_FMASK, Msr); -} +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + +#include "DxeMain.h" + +#include + +VOID +EFIAPI +InitializeMsr ( + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries + ) +{ + UINT64 Msr; + IA32_CR4 Cr4; + IA32_EFLAGS32 Eflags; + UINT32 Ebx; + UINT32 Edx; + MSR_IA32_EFER_REGISTER MsrEfer; + + Ebx = 0; + Edx = 0; + + // + // Forbid supervisor-mode accesses to any user-mode pages. + // + AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); + if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMAP = 1; + Cr4.Bits.SMEP = 1; + AsmWriteCr4 (Cr4.UintN); + + Eflags.UintN = AsmReadEflags (); + Eflags.Bits.AC = 0; + AsmWriteEflags (Eflags.UintN); + } + + // + // Enable SYSCALL and SYSRET. + // + AsmCpuidEx (0x80000001, 0x0, NULL, NULL, NULL, &Edx); + if ((Edx & BIT11) != 0) { + MsrEfer.Uint64 = AsmReadMsr64 (MSR_IA32_EFER); + MsrEfer.Bits.SCE = 1; + AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); + } else { + DEBUG ((DEBUG_ERROR, "Core: SYSCALL and SYSRET are not supported.\n")); + CpuDeadLoop (); + } + + // + // Initialize MSR_IA32_STAR, MSR_IA32_LSTAR and MSR_IA32_FMASK for SYSCALL and SYSRET. + // + Msr = (((((UINT64)RING3_CODE64_SEL - 16) | 3) << 16) | (UINT64)RING0_CODE64_SEL) << 32; + AsmWriteMsr64 (MSR_IA32_STAR, Msr); + + Msr = (UINT64)(UINTN)CoreBootServices; + AsmWriteMsr64 (MSR_IA32_LSTAR, Msr); + // + // Disable maskable interrupts at SYSCALL. + // + Msr = (UINT64)BIT9; + AsmWriteMsr64 (MSR_IA32_FMASK, Msr); +} From f12cc498570bc98738f3860971c11188cf98c527 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 2 Sep 2024 12:42:14 +0300 Subject: [PATCH 240/341] Core/Dxe: Refactored DisableSMAP(), EnableSMAP() names. --- MdeModulePkg/Core/Dxe/DxeMain.h | 4 +- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 4 +- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 8 +- .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 11 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 156 +++++++++--------- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 20 +-- .../Core/Dxe/SysCall/SupportedProtocols.c | 52 +++--- .../Dxe/SysCall/X64/CoreBootServices.nasm | 12 +- 8 files changed, 132 insertions(+), 135 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index cbe7402fa4..13abce957f 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2761,13 +2761,13 @@ CallRing3 ( VOID EFIAPI -DisableSMAP ( +AllowSupervisorAccessToUserMemory ( VOID ); VOID EFIAPI -EnableSMAP ( +ForbidSupervisorAccessToUserMemory ( VOID ); diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index e674c9f788..48d484826e 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -775,14 +775,14 @@ CoreExitBootServices ( // Free resources allocated for Ring3. // if (gRing3Data != NULL) { - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); if (gRing3Data->SystemTable.ConfigurationTable != NULL) { CoreFreePages ( (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data->SystemTable.ConfigurationTable, EFI_SIZE_TO_PAGES (gRing3Data->SystemTable.NumberOfTableEntries * sizeof (EFI_CONFIGURATION_TABLE)) ); } - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); CoreFreePages ( (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 21e8bf98dd..f9a8c3c2bd 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -70,7 +70,7 @@ SysCallBootService ( return Status; } - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)UserRsp, 8 * sizeof (UINTN)); SetUefiImageMemoryAttributes ( @@ -78,7 +78,7 @@ SysCallBootService ( EFI_PAGE_SIZE, EFI_MEMORY_XP ); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); Status = CallBootService ( Type, @@ -180,7 +180,7 @@ InitializeMsr ( VOID EFIAPI -DisableSMAP ( +AllowSupervisorAccessToUserMemory ( VOID ) { @@ -191,7 +191,7 @@ DisableSMAP ( VOID EFIAPI -EnableSMAP ( +ForbidSupervisorAccessToUserMemory ( VOID ) { diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index 8ab94b67d7..a3ab2a7484 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -67,7 +67,7 @@ SysCallBootService ( return Status; } - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); // // First 3 arguments are passed through R1-R3 and copied to SysCall Stack. // @@ -76,7 +76,7 @@ SysCallBootService ( // All remaining arguments are on User Stack. // CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN)); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); Status = CallBootService ( Type, @@ -110,12 +110,9 @@ InitializeMsr ( InitializeSysCallHandler (SysCallBootService); } -// -// TODO: Refactoring. -// VOID EFIAPI -DisableSMAP ( +AllowSupervisorAccessToUserMemory ( VOID ) { @@ -126,7 +123,7 @@ DisableSMAP ( VOID EFIAPI -EnableSMAP ( +ForbidSupervisorAccessToUserMemory ( VOID ) { diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index e729c3c10f..fabbb41e5f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -333,9 +333,9 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); Status = FindGuid ((EFI_GUID *)CoreRbp->Argument1, &CoreProtocol, &MemoryCoreSize); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { return Status; } @@ -346,14 +346,14 @@ CallBootService ( &Interface ); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); if (Interface != NULL) { Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); ASSERT (Interface != NULL); *(VOID **)CoreRbp->Argument3 = Interface; } - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); return Status; @@ -379,17 +379,17 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); if (EFI_ERROR (Status)) { - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); return Status; } Argument4 = UserRsp->Arguments[4]; Argument5 = UserRsp->Arguments[5]; Argument6 = UserRsp->Arguments[6]; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); Status = gBS->OpenProtocol ( (EFI_HANDLE)CoreRbp->Argument1, @@ -401,13 +401,13 @@ CallBootService ( ); if ((VOID **)CoreRbp->Argument3 != NULL) { - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); if (Interface != NULL) { Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); } *(VOID **)CoreRbp->Argument3 = Interface; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); } return Status; @@ -426,7 +426,7 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (VOID **) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); CoreHandle = *(EFI_HANDLE *)CoreRbp->Argument1; UserArgList = (VOID **)CoreRbp->Argument2; @@ -440,7 +440,7 @@ CallBootService ( Status = FindGuid ((EFI_GUID *)UserArgList[Index], (EFI_GUID **)&CoreArgList[Index], &MemoryCoreSize); if (EFI_ERROR (Status)) { - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); while (Index > 0) { FreePool (CoreArgList[Index - 1]); @@ -460,7 +460,7 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] + sizeof (VOID *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); } - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); ASSERT (Index < MAX_LIST); CoreArgList[Index] = NULL; @@ -483,9 +483,9 @@ CallBootService ( CoreSimpleFileSystem->OpenVolume = CoreOpenVolume; - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); mRing3SimpleFileSystemPointer = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)UserArgList[Index + 1]; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); } } @@ -512,15 +512,15 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); if (EFI_ERROR (Status)) { - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); return Status; } Argument4 = UserRsp->Arguments[4]; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); Status = gBS->CloseProtocol ( (EFI_HANDLE)CoreRbp->Argument1, @@ -546,9 +546,9 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { return Status; } @@ -559,14 +559,14 @@ CallBootService ( &Interface ); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); if (Interface != NULL) { Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); ASSERT (Interface != NULL); *(VOID **)CoreRbp->Argument3 = Interface; } - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); return Status; @@ -587,14 +587,14 @@ CallBootService ( (EFI_PHYSICAL_ADDRESS *)&Argument4 ); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + sizeof (EFI_PHYSICAL_ADDRESS) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); *(EFI_PHYSICAL_ADDRESS *)UserRsp->Arguments[4] = (EFI_PHYSICAL_ADDRESS)Argument4; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); return Status; @@ -643,9 +643,9 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { return Status; } @@ -662,7 +662,7 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); if ((UINTN *)UserRsp->Arguments[4] != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -696,7 +696,7 @@ CallBootService ( *(EFI_HANDLE **)UserRsp->Arguments[5] = (EFI_HANDLE *)(UINTN)Ring3Pages; } - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); return StatusBS; @@ -720,9 +720,9 @@ CallBootService ( return EFI_OUT_OF_RESOURCES; } - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); CopyMem ((VOID *)Argument4, (VOID *)CoreRbp->Argument1, CoreRbp->Argument2); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); Status = gBS->CalculateCrc32 ( (VOID *)Argument4, @@ -730,9 +730,9 @@ CallBootService ( (UINT32 *)&Argument5 ); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); *(UINT32 *)CoreRbp->Argument3 = (UINT32)Argument5; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); return Status; @@ -759,19 +759,19 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + StrSize ((CHAR16 *)CoreRbp->Argument1) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); Argument6 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument1), (CHAR16 *)CoreRbp->Argument1); if ((VOID *)Argument6 == NULL) { - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); return EFI_OUT_OF_RESOURCES; } Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); if (EFI_ERROR (Status)) { - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument6); return Status; } @@ -791,12 +791,12 @@ CallBootService ( Argument5 = (UINTN)AllocatePool (Argument4); if ((VOID *)Argument5 == NULL) { - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument6); return EFI_OUT_OF_RESOURCES; } } - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); Status = gRT->GetVariable ( (CHAR16 *)Argument6, @@ -806,7 +806,7 @@ CallBootService ( (VOID *)Argument5 ); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); if ((VOID *)UserRsp->Arguments[5] != NULL) { CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); } @@ -816,7 +816,7 @@ CallBootService ( if ((UINT32 *)CoreRbp->Argument3 != NULL) { *(UINT32 *)CoreRbp->Argument3 = (UINT32)Attributes; } - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument6); @@ -863,7 +863,7 @@ CallBootService ( #endif ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); #if defined (MDE_CPU_ARM) // // EFI_LBA Lba is aligned on 8 bytes. @@ -872,7 +872,7 @@ CallBootService ( #else Attributes = *(UINT64 *)&UserRsp->Arguments[5]; #endif - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); if ((VOID *)Argument5 == NULL) { @@ -886,14 +886,14 @@ CallBootService ( CoreRbp->Argument3, (VOID *)Argument5 ); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument5); @@ -925,7 +925,7 @@ CallBootService ( return EFI_OUT_OF_RESOURCES; } - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); @@ -941,7 +941,7 @@ CallBootService ( #else Attributes = *(UINT64 *)&UserRsp->Arguments[5]; #endif - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); Status = BlockIo->WriteBlocks ( BlockIo, @@ -988,7 +988,7 @@ CallBootService ( #endif ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); #if defined (MDE_CPU_ARM) // // UINT64 Offset is aligned on 8 bytes. @@ -997,7 +997,7 @@ CallBootService ( #else Attributes = *(UINT64 *)&UserRsp->Arguments[5]; #endif - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); if ((VOID *)Argument5 == NULL) { @@ -1011,14 +1011,14 @@ CallBootService ( CoreRbp->Argument3, (VOID *)Argument5 ); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument5); @@ -1050,7 +1050,7 @@ CallBootService ( return EFI_OUT_OF_RESOURCES; } - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); @@ -1066,7 +1066,7 @@ CallBootService ( #else Attributes = *(UINT64 *)&UserRsp->Arguments[5]; #endif - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); Status = DiskIo->WriteDisk ( DiskIo, @@ -1096,12 +1096,12 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { return EFI_OUT_OF_RESOURCES; } @@ -1111,12 +1111,12 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument5 == NULL) { if ((VOID *)Argument4 != NULL) { FreePool ((VOID *)Argument4); @@ -1158,12 +1158,12 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { return EFI_OUT_OF_RESOURCES; } @@ -1173,12 +1173,12 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument5 == NULL) { if ((VOID *)Argument4 != NULL) { FreePool ((VOID *)Argument4); @@ -1219,12 +1219,12 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { return EFI_OUT_OF_RESOURCES; } @@ -1236,9 +1236,9 @@ CallBootService ( ); if ((VOID *)Argument4 != NULL) { - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument4); } @@ -1260,12 +1260,12 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { return EFI_OUT_OF_RESOURCES; } @@ -1277,9 +1277,9 @@ CallBootService ( ); if ((VOID *)Argument4 != NULL) { - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument4); } @@ -1305,9 +1305,9 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + CoreRbp->Argument2 - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); Argument4 = (UINTN)AllocateCopyPool (CoreRbp->Argument2, (CHAR8 *)CoreRbp->Argument3); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { return EFI_OUT_OF_RESOURCES; } @@ -1316,7 +1316,7 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); if ((CHAR16 *)UserRsp->Arguments[4] != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1332,7 +1332,7 @@ CallBootService ( return EFI_OUT_OF_RESOURCES; } } - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); Unicode->FatToStr ( Unicode, @@ -1346,9 +1346,9 @@ CallBootService ( } if ((VOID *)Argument5 != NULL) { - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, 2 * (CoreRbp->Argument2 + 1)); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument5); } @@ -1372,12 +1372,12 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { return EFI_OUT_OF_RESOURCES; } @@ -1386,7 +1386,7 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); if ((CHAR8 *)UserRsp->Arguments[4] != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -1402,7 +1402,7 @@ CallBootService ( return EFI_OUT_OF_RESOURCES; } } - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); Status = (EFI_STATUS)Unicode->StrToFat ( Unicode, @@ -1416,9 +1416,9 @@ CallBootService ( } if ((VOID *)Argument5 != NULL) { - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument5); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index ade43fc05d..c4d3714f2c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -20,12 +20,12 @@ SECTION .text ;------------------------------------------------------------------------------ ; VOID ; EFIAPI -; DisableSMAP ( +; AllowSupervisorAccessToUserMemory ( ; VOID ; ); ;------------------------------------------------------------------------------ -global ASM_PFX(DisableSMAP) -ASM_PFX(DisableSMAP): +global ASM_PFX(AllowSupervisorAccessToUserMemory) +ASM_PFX(AllowSupervisorAccessToUserMemory): pushfd pop eax or eax, 0x40000 ; Set AC (bit 18) @@ -36,12 +36,12 @@ ASM_PFX(DisableSMAP): ;------------------------------------------------------------------------------ ; VOID ; EFIAPI -; EnableSMAP ( +; ForbidSupervisorAccessToUserMemory ( ; VOID ; ); ;------------------------------------------------------------------------------ -global ASM_PFX(EnableSMAP) -ASM_PFX(EnableSMAP): +global ASM_PFX(ForbidSupervisorAccessToUserMemory) +ASM_PFX(ForbidSupervisorAccessToUserMemory): pushfd pop eax and eax, ~0x40000 ; Clear AC (bit 18) @@ -131,14 +131,14 @@ ASM_PFX(CoreBootServices): je coreReturnAddress ; Prepare CallBootService arguments. - call ASM_PFX(DisableSMAP) + call ASM_PFX(AllowSupervisorAccessToUserMemory) mov eax, [edx + 4 * 4] ; User Argument 3 push eax mov eax, [edx + 3 * 4] ; User Argument 2 push eax mov eax, [edx + 2 * 4] ; User Argument 1 push eax - call ASM_PFX(EnableSMAP) + call ASM_PFX(ForbidSupervisorAccessToUserMemory) mov ebp, esp push edx push ebp @@ -209,10 +209,10 @@ coreReturnAddress: pop ebp pop ebx - call ASM_PFX(DisableSMAP) + call ASM_PFX(AllowSupervisorAccessToUserMemory) mov eax, [edx + 2 * 4] ; User Argument 1 push eax - call ASM_PFX(EnableSMAP) + call ASM_PFX(ForbidSupervisorAccessToUserMemory) pop eax sti diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index c89a431d10..d0e8944913 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -51,7 +51,7 @@ GoToRing3 ( Input = (RING3_CALL_DATA *)(UINTN)Ring3Pages; - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); Input->NumberOfArguments = Number; Input->EntryPoint = EntryPoint; @@ -60,7 +60,7 @@ GoToRing3 ( Input->Arguments[Index] = VA_ARG (Marker, UINTN); } VA_END (Marker); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); #if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) if (Number == 2) { @@ -98,7 +98,7 @@ GoToRing3 ( // Problem 2: Uart memory maped page is not allocated at the very beginnig // and can be used for translation table later. // - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); // // Problem 3: QEMU ramdomly breaks GP registers' context. // @@ -107,7 +107,7 @@ GoToRing3 ( EFI_PAGE_SIZE, EFI_MEMORY_XP ); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); #endif CoreFreePages (Ring3Pages, PagesNumber); @@ -136,9 +136,9 @@ Ring3Copy ( return NULL; } - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); CopyMem ((VOID *)(UINTN)Ring3, Core, Size); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); return (VOID *)(UINTN)Ring3; } @@ -300,9 +300,9 @@ CoreFileRead ( Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); *Ring3BufferSize = *BufferSize; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if (Buffer != NULL) { Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); @@ -316,13 +316,13 @@ CoreFileRead ( Ring3Buffer ); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); } *BufferSize = *Ring3BufferSize; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); CoreFreePages (Ring3Pages, PagesNumber); @@ -414,9 +414,9 @@ CoreFileGetPosition ( return Status; } - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); *(UINT64 *)(UINTN)Ring3Position = *Position; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); Status = GoToRing3 ( 2, @@ -425,9 +425,9 @@ CoreFileGetPosition ( Ring3Position ); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); *Position = *(UINT64 *)(UINTN)Ring3Position; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); CoreFreePages (Ring3Position, 1); @@ -475,9 +475,9 @@ CoreFileGetInfo ( Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); *Ring3BufferSize = *BufferSize; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if (Buffer != NULL) { Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); @@ -486,9 +486,9 @@ CoreFileGetInfo ( if (InformationType != NULL) { Ring3InformationType = (EFI_GUID *)((UINTN)Ring3Pages + sizeof (UINTN *) + *BufferSize); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); CopyGuid (Ring3InformationType, InformationType); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); } Status = GoToRing3 ( @@ -500,13 +500,13 @@ CoreFileGetInfo ( Ring3Buffer ); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); } *BufferSize = *Ring3BufferSize; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); CoreFreePages (Ring3Pages, PagesNumber); @@ -628,9 +628,9 @@ CoreFileOpen ( Ring3NewHandle = (EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages; Ring3FileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages + 1); - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName); - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { *NewHandle = NULL; CoreFreePages (Ring3Pages, PagesNumber); @@ -706,9 +706,9 @@ CoreFileOpen ( NewFile->Protocol.WriteEx = CoreFileWriteEx; NewFile->Protocol.FlushEx = CoreFileFlushEx; - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); NewFile->Ring3File = *Ring3NewHandle; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); *NewHandle = (EFI_FILE_PROTOCOL *)NewFile; @@ -765,7 +765,7 @@ CoreOpenVolume ( return EFI_OUT_OF_RESOURCES; } - DisableSMAP (); + AllowSupervisorAccessToUserMemory (); mRing3FileProtocol.Revision = (*Ring3Root)->Revision; mRing3FileProtocol.Open = (*Ring3Root)->Open; mRing3FileProtocol.Close = (*Ring3Root)->Close; @@ -783,7 +783,7 @@ CoreOpenVolume ( mRing3FileProtocol.FlushEx = (*Ring3Root)->FlushEx; File->Ring3File = *Ring3Root; - EnableSMAP (); + ForbidSupervisorAccessToUserMemory (); File->Protocol.Revision = mRing3FileProtocol.Revision; File->Protocol.Open = CoreFileOpen; diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index cf1bd7c94b..3c88b9a743 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -18,12 +18,12 @@ SECTION .text ;------------------------------------------------------------------------------ ; VOID ; EFIAPI -; DisableSMAP ( +; AllowSupervisorAccessToUserMemory ( ; VOID ; ); ;------------------------------------------------------------------------------ -global ASM_PFX(DisableSMAP) -ASM_PFX(DisableSMAP): +global ASM_PFX(AllowSupervisorAccessToUserMemory) +ASM_PFX(AllowSupervisorAccessToUserMemory): pushfq pop r10 or r10, 0x40000 ; Set AC (bit 18) @@ -34,12 +34,12 @@ ASM_PFX(DisableSMAP): ;------------------------------------------------------------------------------ ; VOID ; EFIAPI -; EnableSMAP ( +; ForbidSupervisorAccessToUserMemory ( ; VOID ; ); ;------------------------------------------------------------------------------ -global ASM_PFX(EnableSMAP) -ASM_PFX(EnableSMAP): +global ASM_PFX(ForbidSupervisorAccessToUserMemory) +ASM_PFX(ForbidSupervisorAccessToUserMemory): pushfq pop r10 and r10, ~0x40000 ; Clear AC (bit 18) From 0c0df841b9e359ee7abe02542c37faa42b18522b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 2 Sep 2024 19:50:25 +0300 Subject: [PATCH 241/341] Ring3: Fixed ArmPkg and ArmVirtPkg compilation. --- .../Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.c | 2 +- .../Library/ArmLib/AArch64/AArch64Support.S | 10 ++++++ ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S | 10 ++++++ .../AArch64/DefaultExceptionHandler.c | 7 +--- .../DefaultExceptionHandlerLib.inf | 1 + .../Dxe/SysCall/AARCH64/CoreBootServices.S | 22 ------------ .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 12 ------- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 24 ------------- .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 12 ------- MdePkg/Include/Library/ArmLib.h | 34 +++++++++++++------ 10 files changed, 46 insertions(+), 88 deletions(-) diff --git a/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.c b/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.c index 8bb8155590..ef1be216e4 100644 --- a/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.c +++ b/ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.c @@ -29,6 +29,6 @@ ArmCrashDumpDxeInitialize ( return mCpu->RegisterInterruptHandler ( mCpu, EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS, - &DefaultExceptionHandler + (EFI_CPU_INTERRUPT_HANDLER)&DefaultExceptionHandler ); } diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S index 66daa27fb4..e4a10c2526 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S @@ -398,4 +398,14 @@ ASM_FUNC(ArmReadIdAA64Pfr1) mrs x0, ID_AA64PFR1_EL1 ret +.cpu cortex-a76 + +ASM_FUNC(ArmSetPan) + msr pan, #1 + ret + +ASM_FUNC(ArmClearPan) + msr pan, #0 + ret + ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S index 86635cc093..bd2861c444 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S +++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S @@ -150,4 +150,14 @@ ASM_FUNC (ArmGetPhysicalAddressBits) movge r0, #40 // 40 bits if LPAE bx lr +.arch armv8.1-a + +ASM_FUNC(ArmSetPan) + setpan #1 + bx LR + +ASM_FUNC(ArmClearPan) + setpan #0 + bx LR + ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index 2c47a5f2f0..c87ef080da 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -46,12 +47,6 @@ GetImageName ( OUT UINTN *DebugBase ); -VOID -EFIAPI -ArmClearPan ( - VOID - ); - STATIC VOID DescribeInstructionOrDataAbort ( diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf index 40fa5d552e..15f62c6acb 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf @@ -36,6 +36,7 @@ DebugLib SerialPortLib UefiBootServicesTableLib + ArmLib [Guids] gEfiDebugImageInfoTableGuid diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index cf6f098b7b..1192c150de 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -145,25 +145,3 @@ ASM_FUNC(ReturnToCore) msr daifclr, #0xf isb ret - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ArmSetPan ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ArmSetPan) - msr pan, #1 - ret - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ArmClearPan ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ArmClearPan) - msr pan, #0 - ret diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index f9a8c3c2bd..3ab3bffde7 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -32,18 +32,6 @@ ReturnToCore ( IN UINTN CoreSp ); -VOID -EFIAPI -ArmSetPan ( - VOID - ); - -VOID -EFIAPI -ArmClearPan ( - VOID - ); - STATIC EFI_STATUS EFIAPI diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 4596465672..d710ab8079 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -7,8 +7,6 @@ #include -.arch armv8.1a - //------------------------------------------------------------------------------ // EFI_STATUS // EFIAPI @@ -124,25 +122,3 @@ ASM_FUNC(ReturnToCore) isb bx LR - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ArmSetPan ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ArmSetPan) - setpan #1 - bx LR - -//------------------------------------------------------------------------------ -// VOID -// EFIAPI -// ArmClearPan ( -// VOID -// ); -//------------------------------------------------------------------------------ -ASM_FUNC(ArmClearPan) - setpan #0 - bx LR diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index a3ab2a7484..8ffd808742 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -29,18 +29,6 @@ ReturnToCore ( IN UINTN CoreSp ); -VOID -EFIAPI -ArmSetPan ( - VOID - ); - -VOID -EFIAPI -ArmClearPan ( - VOID - ); - STATIC EFI_STATUS EFIAPI diff --git a/MdePkg/Include/Library/ArmLib.h b/MdePkg/Include/Library/ArmLib.h index a7f89e23b5..aaa3355b7e 100644 --- a/MdePkg/Include/Library/ArmLib.h +++ b/MdePkg/Include/Library/ArmLib.h @@ -710,17 +710,29 @@ ArmHasCcidx ( VOID ); -/** - Checks whether the CPU implements the Privileged Access Never. - - @retval TRUE FEAT_PAN is implemented. - @retval FALSE FEAT_PAN is not mplemented. -**/ -BOOLEAN -EFIAPI -ArmHasPan ( - VOID - ); +/** + Checks whether the CPU implements the Privileged Access Never. + + @retval TRUE FEAT_PAN is implemented. + @retval FALSE FEAT_PAN is not mplemented. +**/ +BOOLEAN +EFIAPI +ArmHasPan ( + VOID + ); + +VOID +EFIAPI +ArmSetPan ( + VOID + ); + +VOID +EFIAPI +ArmClearPan ( + VOID + ); #ifdef MDE_CPU_AARCH64 /// From 7372b312d44a3dd17c427a1d56a31ebb3a229315 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 3 Sep 2024 13:53:26 +0300 Subject: [PATCH 242/341] MdeModulePkg/Core/Dxe: Fixed compilation after rebasing upon new master. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 8e88d449b9..d2d0283770 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -213,6 +213,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdFwVolDxeMaxEncapsulationDepth ## CONSUMES From 0fbb3720c13ea61bf554df26eb7a50339adc5dde Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 5 Sep 2024 11:46:52 +0300 Subject: [PATCH 243/341] Ring3: Fixed buggy timer interrupt handling for IA32. --- MdePkg/Include/Library/BaseLib.h | 4 ++-- OvmfPkg/OvmfPkgIa32.dsc | 1 + .../Ia32/ArchExceptionHandler.c | 22 ++++++++++++------- .../Ia32/ExceptionHandlerAsm.nasm | 7 +++--- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 9e6c2aa5c1..367055c70a 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -5716,10 +5716,10 @@ typedef struct { } IA32_DESCRIPTOR; #pragma pack () -#define IA32_IDT_GATE_TYPE_TASK 0x85 +#define IA32_IDT_GATE_TYPE_TASK 0xE5 #define IA32_IDT_GATE_TYPE_INTERRUPT_16 0x86 #define IA32_IDT_GATE_TYPE_TRAP_16 0x87 -#define IA32_IDT_GATE_TYPE_INTERRUPT_32 0x8E +#define IA32_IDT_GATE_TYPE_INTERRUPT_32 0xEE #define IA32_IDT_GATE_TYPE_TRAP_32 0x8F #define IA32_GDT_TYPE_TSS 0x9 diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 7be0dfb098..d97b73cea4 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -598,6 +598,7 @@ gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x70000000 !endif gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE # # Firmware volume supports UE, and may require PE. diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c index 865bd10534..da588d6b3a 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c @@ -202,22 +202,31 @@ ArchSetupExceptionStack ( // be filled by processor during task switching. // TssBase = (UINTN)Tss; - + // + // Last byte of bitmap must be followed by a byte with all bits set. + // TssDesc->Uint64 = 0; - TssDesc->Bits.LimitLow = (UINT16)(sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE - 1); + TssDesc->Bits.LimitLow = (UINT16)(sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE - 2); TssDesc->Bits.BaseLow = (UINT16)TssBase; TssDesc->Bits.BaseMid = (UINT8)(TssBase >> 16); TssDesc->Bits.Type = IA32_GDT_TYPE_TSS; TssDesc->Bits.DPL = 3; TssDesc->Bits.P = 1; - TssDesc->Bits.LimitHigh = (sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE - 1) >> 16; + TssDesc->Bits.LimitHigh = (sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE - 2) >> 16; TssDesc->Bits.BaseHigh = (UINT8)(TssBase >> 24); // // Set I/O Permission Bit Map // ZeroMem (Tss, sizeof (*Tss)); + // + // Plus 1 byte is for compact stack layout in case StackTop is already aligned. + // + StackTop = StackTop - CPU_STACK_ALIGNMENT + 1; + StackTop = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); + Tss->ESP0 = StackTop; + Tss->SS0 = AsmReadSs (); Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); // // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06 @@ -240,11 +249,7 @@ ArchSetupExceptionStack ( // Fixup exception task descriptor and task-state segment // AsmGetTssTemplateMap (&TemplateMap); - // - // Plus 1 byte is for compact stack layout in case StackTop is already aligned. - // - StackTop = StackTop - CPU_STACK_ALIGNMENT + 1; - StackTop = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); + IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)Idtr.Base; for (Index = 0; Index < CPU_STACK_SWITCH_EXCEPTION_NUMBER; ++Index, ++TssDesc, ++Tss) { // @@ -257,6 +262,7 @@ ArchSetupExceptionStack ( TssDesc->Bits.BaseLow = (UINT16)TssBase; TssDesc->Bits.BaseMid = (UINT8)(TssBase >> 16); TssDesc->Bits.Type = IA32_GDT_TYPE_TSS; + TssDesc->Bits.DPL = 3; TssDesc->Bits.P = 1; TssDesc->Bits.LimitHigh = 0; TssDesc->Bits.BaseHigh = (UINT8)(TssBase >> 24); diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm index c6876eff64..b0cb2a9b4f 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm @@ -208,7 +208,7 @@ ErrorCodeAndVectorOnStack: jz sameCPL_0 mov ecx, [ecx] sameCPL_0: - push ecx ; ESP + push ecx ; ESP push dword [ebp] ; EBP push esi push edi @@ -390,7 +390,7 @@ sameCPL_1: pop ds pop dword [ebp + 4 * 4] ; Check whether Ring0 process was interrupted. - mov ecx, ss + mov ecx, ds and ecx, 3 jz sameCPL_2 pop dword [ebp + 7 * 4] @@ -413,9 +413,8 @@ continue: push ecx mov ecx, ds and ecx, 3 - cmp ecx, 3 pop ecx - je ReturnToRing3 + jnz ReturnToRing3 pop dword [ebp - 8] pop dword [ebp - 4] From 5ecb27693523946e14b337fb4c6b2fa6f97fcedc Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 5 Sep 2024 13:40:09 +0300 Subject: [PATCH 244/341] Core/Dxe/Misc: Fixed string comparison bug. --- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 929602305c..6dcd7da5e6 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -236,7 +236,7 @@ ProtectUefiImage ( // // CPU ARCH present. Update memory attribute directly. // - if (PcdGetBool (PcdEnableUserSpace)) { + if (PcdGetBool (PcdEnableUserSpace) && (PdbPointer != NULL)) { if (AsciiStrStr (PdbPointer, "Fat") != NULL) { SetUefiImageProtectionAttributes (ImageRecord, TRUE); *IsUserImage = TRUE; From b356236aaeb5ccbecb6ae9b95dd4f4a5147b3e64 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 5 Sep 2024 15:54:33 +0300 Subject: [PATCH 245/341] Ring3: Fixed buggy timer interrupt handling for X64. --- OvmfPkg/OvmfPkgIa32X64.dsc | 1 + .../X64/ArchExceptionHandler.c | 48 ++++++++++--------- .../X64/ArchInterruptDefs.h | 2 +- .../X64/ExceptionHandlerAsm.nasm | 24 +++------- 4 files changed, 35 insertions(+), 40 deletions(-) diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index ab14245392..d362658e92 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -613,6 +613,7 @@ gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000003 !endif gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE ################################################################################ # diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index a1275b53df..0d8edb6b81 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -208,21 +208,23 @@ ArchSetupExceptionStack ( // be filled by processor during task switching. // TssBase = (UINTN)Tss; - + // + // Last byte of bitmap must be followed by a byte with all bits set. + // TssDesc->Uint128.Uint64 = 0; TssDesc->Uint128.Uint64_1 = 0; - TssDesc->Bits.LimitLow = (UINT16)(CPU_TSS_SIZE - 1); + TssDesc->Bits.LimitLow = (UINT16)(CPU_TSS_SIZE - 2); TssDesc->Bits.BaseLow = (UINT16)TssBase; TssDesc->Bits.BaseMidl = (UINT8)(TssBase >> 16); TssDesc->Bits.Type = IA32_GDT_TYPE_TSS; TssDesc->Bits.DPL = 3; TssDesc->Bits.P = 1; - TssDesc->Bits.LimitHigh = (CPU_TSS_SIZE - 1) >> 16; + TssDesc->Bits.LimitHigh = (CPU_TSS_SIZE - 2) >> 16; TssDesc->Bits.BaseMidh = (UINT8)(TssBase >> 24); TssDesc->Bits.BaseHigh = (UINT32)(TssBase >> 32); // - // Fixup exception task descriptor and task-state segment + // Set I/O Permission Bit Map // ZeroMem (Tss, sizeof (*Tss)); // @@ -230,6 +232,26 @@ ArchSetupExceptionStack ( // StackTop = StackTop - CPU_STACK_ALIGNMENT + 1; StackTop = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); + + Tss->RSP0 = StackTop; + Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); + // + // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06 + // + IOBitMap = (UINT8 *)((UINTN)Tss + Tss->IOMapBaseAddress); + for (Index = 0; Index < IO_BIT_MAP_SIZE; ++Index) { + if ((Index * 8) == 0x3F8) { + *IOBitMap = 0x84; + } else { + *IOBitMap = 0xFF; + } + + ++IOBitMap; + } + + // + // Fixup IST and task-state segment + // IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)Idtr.Base; for (Index = 0; Index < CPU_STACK_SWITCH_EXCEPTION_NUMBER; ++Index) { // @@ -256,24 +278,6 @@ ArchSetupExceptionStack ( // AsmWriteGdtr (&Gdtr); - // - // Set I/O Permission Bit Map - // - Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); - // - // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06 - // - IOBitMap = (UINT8 *)((UINTN)Tss + Tss->IOMapBaseAddress); - for (Index = 0; Index < IO_BIT_MAP_SIZE; ++Index) { - if ((Index * 8) == 0x3F8) { - *IOBitMap = 0x84; - } else { - *IOBitMap = 0xFF; - } - - ++IOBitMap; - } - // // Load current task // diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h index 39f19f3b3b..21e469e358 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h @@ -41,7 +41,7 @@ typedef struct { // // 0x81 is needed to allow Ring3 code access to Uart in I/O Permission Bit Map. // -#define IO_BIT_MAP_SIZE 0x81 +#define IO_BIT_MAP_SIZE (ALIGN_VALUE (0x81, 16)) #define CPU_TSS_SIZE (sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE) #endif diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm index a8c69026db..81d86fb533 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm @@ -207,20 +207,11 @@ HasErrorCode: mov rax, gs push rax - ; Check whether Ring3 process was interrupted. - and rax, 3 - cmp rax, 3 - jne SkipHook - mov rax, cr2 - cmp rax, 0xFFFFFFFFFFFFFFF8 - jne SkipHook - mov rcx, 32 -SkipHook: - mov rax, ss - mov ds, rax - mov es, rax - mov fs, rax - mov gs, rax + mov ax, ss + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax mov [rbp + 8], rcx ; save vector number @@ -426,7 +417,7 @@ CetDone: ;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; pop rdi pop rsi - add rsp, 8 ; not for rbp + add rsp, 8 ; not for rbp pop qword [rbp + 48] ; for rsp pop rbx pop rdx @@ -445,9 +436,8 @@ CetDone: push rcx mov rcx, ds and rcx, 3 - cmp rcx, 3 pop rcx - je ReturnToRing3 + jnz ReturnToRing3 mov rsp, rbp pop rbp From 71e95bc70debf1024b2ed15aa1838ca9634dc29f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 5 Sep 2024 17:39:35 +0300 Subject: [PATCH 246/341] Ring3: Refactored I/O Map initialization using PcdUartBase and PcdDebugIoPort. --- OvmfPkg/OvmfPkg.dec | 5 ++++- PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf | 4 ++++ PcAtChipsetPkg/Library/SerialIoLib/SerialPortLib.c | 2 +- .../CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf | 3 +++ .../CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 7 +++++-- .../CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h | 2 +- .../CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf | 5 ++++- .../SecPeiCpuExceptionHandlerLib.inf | 3 +++ .../CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf | 3 +++ .../CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 7 +++++-- .../Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h | 5 +---- 11 files changed, 34 insertions(+), 12 deletions(-) diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index d136c4df2e..42332ab9df 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -206,9 +206,12 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeNonCcFvBase|0x0|UINT32|0x6a gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeNonCcFvSize|0x0|UINT32|0x6b - ## This flag is used to control the destination port for PlatformDebugLibIoPort + ## Controls the destination port for PlatformDebugLibIoPort gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort|0x402|UINT16|4 + ## Controls the destination ports for SerialPortLib + gUefiOvmfPkgTokenSpaceGuid.PcdUartBase|0x3F8|UINT16|0x104 + ## When VirtioScsiDxe is instantiated for a HBA, the numbers of targets and # LUNs are retrieved from the host during virtio-scsi setup. # MdeModulePkg/Bus/Scsi/ScsiBusDxe then scans all MaxTarget * MaxLun diff --git a/PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf b/PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf index d02259a07c..4f6d4c44ce 100644 --- a/PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf +++ b/PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf @@ -17,11 +17,15 @@ [Packages] MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec [LibraryClasses] BaseLib IoLib + PcdLib [Sources] SerialPortLib.c +[Pcd] + gUefiOvmfPkgTokenSpaceGuid.PcdUartBase ## CONSUMES diff --git a/PcAtChipsetPkg/Library/SerialIoLib/SerialPortLib.c b/PcAtChipsetPkg/Library/SerialIoLib/SerialPortLib.c index 11537ec276..a880266236 100644 --- a/PcAtChipsetPkg/Library/SerialIoLib/SerialPortLib.c +++ b/PcAtChipsetPkg/Library/SerialIoLib/SerialPortLib.c @@ -43,7 +43,7 @@ // --------------------------------------------- // UART Settings // --------------------------------------------- -UINT16 gUartBase = 0x3F8; +UINT16 gUartBase = FixedPcdGet16 (PcdUartBase); UINTN gBps = 115200; UINT8 gData = 8; UINT8 gStop = 1; diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf index 398c82d46f..03d209b81a 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf @@ -50,6 +50,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize + gUefiOvmfPkgTokenSpaceGuid.PcdUartBase ## CONSUMES + gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort ## CONSUMES [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES @@ -57,6 +59,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses.common] diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c index da588d6b3a..4b5898b33c 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c @@ -229,12 +229,15 @@ ArchSetupExceptionStack ( Tss->SS0 = AsmReadSs (); Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); // - // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06 + // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06; + // and DebugIoPort = 0x402. // IOBitMap = (UINT8 *)((UINTN)Tss + Tss->IOMapBaseAddress); for (Index = 0; Index < IO_BIT_MAP_SIZE; ++Index) { - if ((Index * 8) == 0x3F8) { + if ((Index * 8) == FixedPcdGet16 (PcdUartBase)) { *IOBitMap = 0x84; + } else if ((Index * 8) == (FixedPcdGet16 (PcdDebugIoPort) - 2)) { + *IOBitMap = 0xFB; } else { *IOBitMap = 0xFF; } diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h index 675c45436c..eeae24bdb3 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h @@ -39,7 +39,7 @@ typedef struct { (sizeof (IA32_TSS_DESCRIPTOR) * \ (FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + 1)) -#define IO_BIT_MAP_SIZE (ALIGN_VALUE (0x81, 16)) +#define IO_BIT_MAP_SIZE (ALIGN_VALUE (FixedPcdGet16 (PcdDebugIoPort) / 8 + 1, 16)) #define CPU_TSS_SIZE \ (sizeof (IA32_TASK_STATE_SEGMENT) * \ (FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + 1) + IO_BIT_MAP_SIZE) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf index 3caff1beb6..fbde353661 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf @@ -41,6 +41,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses] @@ -55,9 +56,11 @@ SynchronizationLib [Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard # CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard ## CONSUMES gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList + gUefiOvmfPkgTokenSpaceGuid.PcdUartBase ## CONSUMES + gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort ## CONSUMES [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf index 827bcd0e36..eeb09f089d 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf @@ -50,6 +50,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses.common] @@ -69,6 +70,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize + gUefiOvmfPkgTokenSpaceGuid.PcdUartBase ## CONSUMES + gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort ## CONSUMES [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf index 3217886d4c..c27821156a 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf @@ -41,6 +41,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + OvmfPkg/OvmfPkg.dec UefiCpuPkg/UefiCpuPkg.dec [LibraryClasses] @@ -57,6 +58,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize + gUefiOvmfPkgTokenSpaceGuid.PcdUartBase ## CONSUMES + gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort ## CONSUMES [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index 0d8edb6b81..7e61bb7e76 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -236,12 +236,15 @@ ArchSetupExceptionStack ( Tss->RSP0 = StackTop; Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); // - // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06 + // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06; + // and DebugIoPort = 0x402. // IOBitMap = (UINT8 *)((UINTN)Tss + Tss->IOMapBaseAddress); for (Index = 0; Index < IO_BIT_MAP_SIZE; ++Index) { - if ((Index * 8) == 0x3F8) { + if ((Index * 8) == FixedPcdGet16 (PcdUartBase)) { *IOBitMap = 0x84; + } else if ((Index * 8) == (FixedPcdGet16 (PcdDebugIoPort) - 2)) { + *IOBitMap = 0xFB; } else { *IOBitMap = 0xFF; } diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h index 21e469e358..7ae9ff7b0a 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h @@ -38,10 +38,7 @@ typedef struct { } RESERVED_VECTORS_DATA; #define CPU_TSS_DESC_SIZE sizeof (IA32_TSS_DESCRIPTOR) -// -// 0x81 is needed to allow Ring3 code access to Uart in I/O Permission Bit Map. -// -#define IO_BIT_MAP_SIZE (ALIGN_VALUE (0x81, 16)) +#define IO_BIT_MAP_SIZE (ALIGN_VALUE (FixedPcdGet16 (PcdDebugIoPort) / 8 + 1, 16)) #define CPU_TSS_SIZE (sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE) #endif From 5af1302bd55bba174f7b9000f35b5cce4cd9a5a2 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 9 Sep 2024 08:56:05 +0300 Subject: [PATCH 247/341] SysCall: Split SMEP and SMAP initialization. --- MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c | 13 +++++++++++-- MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c | 13 +++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c index 23bd212ffe..83b34b1d55 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c @@ -29,9 +29,8 @@ InitializeMsr ( // Forbid supervisor-mode accesses to any user-mode pages. // AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); - if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { + if ((Ebx & BIT7) != 0) { Cr4.UintN = AsmReadCr4 (); - Cr4.Bits.SMAP = 1; Cr4.Bits.SMEP = 1; AsmWriteCr4 (Cr4.UintN); @@ -40,6 +39,16 @@ InitializeMsr ( AsmWriteEflags (Eflags.UintN); } + if ((Ebx & BIT20) != 0) { + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMAP = 1; + AsmWriteCr4 (Cr4.UintN); + + Eflags.UintN = AsmReadEflags (); + Eflags.Bits.AC = 0; + AsmWriteEflags (Eflags.UintN); + } + // // SYSENTER and SYSEXIT must be supported. // diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c index 9694c071c2..3126f09d12 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c @@ -30,9 +30,8 @@ InitializeMsr ( // Forbid supervisor-mode accesses to any user-mode pages. // AsmCpuidEx (0x07, 0x0, NULL, &Ebx, NULL, NULL); - if (((Ebx & BIT20) != 0) && ((Ebx & BIT7) != 0)) { + if ((Ebx & BIT7) != 0) { Cr4.UintN = AsmReadCr4 (); - Cr4.Bits.SMAP = 1; Cr4.Bits.SMEP = 1; AsmWriteCr4 (Cr4.UintN); @@ -41,6 +40,16 @@ InitializeMsr ( AsmWriteEflags (Eflags.UintN); } + if ((Ebx & BIT20) != 0) { + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.SMAP = 1; + AsmWriteCr4 (Cr4.UintN); + + Eflags.UintN = AsmReadEflags (); + Eflags.Bits.AC = 0; + AsmWriteEflags (Eflags.UintN); + } + // // Enable SYSCALL and SYSRET. // From 17fb38d10cefef13b325ce0e6a12752c6dec5a1b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 9 Sep 2024 08:58:57 +0300 Subject: [PATCH 248/341] CpuExceptionHandlerLib: Added a separate stack for timer. --- UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h | 2 +- .../Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c | 1 + .../Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h index 0356abd7ab..93020e0b09 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h @@ -40,7 +40,7 @@ #include "ArchInterruptDefs.h" #define CPU_STACK_SWITCH_EXCEPTION_NUMBER \ - FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + (FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + 1) #define CPU_STACK_SWITCH_EXCEPTION_LIST \ FixedPcdGetPtr (PcdCpuStackSwitchExceptionList) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c index 4b5898b33c..ae39125a1c 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c @@ -226,6 +226,7 @@ ArchSetupExceptionStack ( StackTop = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); Tss->ESP0 = StackTop; + StackTop -= CPU_KNOWN_GOOD_STACK_SIZE; Tss->SS0 = AsmReadSs (); Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); // diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index 7e61bb7e76..1b35108e97 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -234,6 +234,7 @@ ArchSetupExceptionStack ( StackTop = (UINTN)ALIGN_POINTER (StackTop, CPU_STACK_ALIGNMENT); Tss->RSP0 = StackTop; + StackTop -= CPU_KNOWN_GOOD_STACK_SIZE; Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); // // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06; From e769416a1942f7b123bc3a4d46b8636a7db80094 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 9 Sep 2024 11:12:13 +0300 Subject: [PATCH 249/341] SysCall/X64: Fixed CallBootService() for NOOPT. --- MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 3c88b9a743..3f9f4661ce 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -151,6 +151,8 @@ ASM_PFX(CoreBootServices): push r8 push rdx mov rbp, rsp + ; Reserve space on stack for 3 CallBootService arguments (NOOPT prerequisite). + sub rsp, 8*3 ; Prepare CallBootService arguments. mov rcx, r10 @@ -166,8 +168,8 @@ ASM_PFX(CoreBootServices): pop rax - ; Step over Arguments [1..3]. - add rsp, 8*3 + ; Step over Arguments [1..3] and NOOPT buffer. + add rsp, 8*6 ; Prepare SYSRET arguments. pop r11 From 3dd846456ab36108371a19c9e27cde1c01a6cec3 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 9 Sep 2024 11:48:53 +0300 Subject: [PATCH 250/341] SysCall: Refactored SysCallReturnToCore handling to fix CLANGDWARF NOOPT. --- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 3 +++ MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 9 ++++++++ .../Dxe/SysCall/IA32/CoreBootServices.nasm | 22 +++++++++---------- .../Dxe/SysCall/X64/CoreBootServices.nasm | 16 +++++++++----- MdePkg/Include/Uefi/UefiSpec.h | 2 +- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 3ab3bffde7..7d11e063fe 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -45,6 +45,9 @@ SysCallBootService ( EFI_PHYSICAL_ADDRESS Physical; if (Type == SysCallReturnToCore) { + // + // TODO: Refactoring + // ReturnToCore (*(EFI_STATUS *)CoreRbp, mCoreSp); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index fabbb41e5f..aafdf60412 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -65,6 +65,12 @@ CallInstallMultipleProtocolInterfaces ( IN VOID *Function ); +VOID +EFIAPI +ReturnToCore ( + IN EFI_STATUS Status + ); + VOID EFIAPI FreeProtocolsList ( @@ -318,6 +324,9 @@ CallBootService ( DEBUG ((DEBUG_VERBOSE, "Type: %a\n", SysCallNames[Type])); switch (Type) { + case SysCallReturnToCore: + ReturnToCore (CoreRbp->Argument1); + break; case SysCallLocateProtocol: // // Argument 1: EFI_GUID *Protocol diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index c4d3714f2c..af51544705 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -126,10 +126,6 @@ ASM_PFX(CoreBootServices): mov fs, ax mov gs, ax - ; Special case for SysCallReturnToCore. - cmp ecx, 0 - je coreReturnAddress - ; Prepare CallBootService arguments. call ASM_PFX(AllowSupervisorAccessToUserMemory) mov eax, [edx + 4 * 4] ; User Argument 3 @@ -202,19 +198,23 @@ ASM_PFX(CallRing3): sti sysexit -coreReturnAddress: +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; ReturnToCore ( +; IN EFI_STATUS Status +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(ReturnToCore) +ASM_PFX(ReturnToCore): + mov eax, [esp + 4] + mov esp, [ASM_PFX(CoreEsp)] pop esi pop edi pop ebp pop ebx - call ASM_PFX(AllowSupervisorAccessToUserMemory) - mov eax, [edx + 2 * 4] ; User Argument 1 - push eax - call ASM_PFX(ForbidSupervisorAccessToUserMemory) - pop eax - sti ret diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 3f9f4661ce..9d72b81935 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -132,10 +132,6 @@ ASM_PFX(CoreBootServices): mov fs, ax mov gs, ax - ; Special case for SysCallReturnToCore. - cmp r10, 0 - je coreReturnAddress - ; Save User Stack pointers and switch to Core SysCall Stack. mov rax, [ASM_PFX(gCoreSysCallStackTop)] sub rax, 8 @@ -228,7 +224,15 @@ ASM_PFX(CallRing3): ; Pass control to user image o64 sysret -coreReturnAddress: +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; ReturnToCore ( +; IN EFI_STATUS Status +; ); +;------------------------------------------------------------------------------ +global ASM_PFX(ReturnToCore) +ASM_PFX(ReturnToCore): mov rsp, [ASM_PFX(CoreRsp)] pop r15 pop r14 @@ -239,7 +243,7 @@ coreReturnAddress: pop rbp pop rbx - mov rax, rdx + mov rax, rcx sti ret diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index b6273143eb..26a7fbf235 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2029,7 +2029,7 @@ typedef enum { // // BootServices // - SysCallReturnToCore, // Must always be zero for CoreBootServices.nasm. + SysCallReturnToCore, SysCallLocateProtocol, SysCallOpenProtocol, SysCallInstallMultipleProtocolInterfaces, From b84108516a26604114a8cf14a503c752962f0e0f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 9 Sep 2024 13:31:21 +0300 Subject: [PATCH 251/341] Dxe/Misc: Fixed CLANGPDB RELEASE. --- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 6dcd7da5e6..749dd96548 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -236,7 +236,7 @@ ProtectUefiImage ( // // CPU ARCH present. Update memory attribute directly. // - if (PcdGetBool (PcdEnableUserSpace) && (PdbPointer != NULL)) { + if (PcdGetBool (PcdEnableUserSpace) && (!RETURN_ERROR (PdbStatus))) { if (AsciiStrStr (PdbPointer, "Fat") != NULL) { SetUefiImageProtectionAttributes (ImageRecord, TRUE); *IsUserImage = TRUE; From e0b4bef0fdeab2b6968ab4ca498021cc94d827e9 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 9 Sep 2024 19:49:20 +0300 Subject: [PATCH 252/341] SysCall/X64: Fixed CallBootService() for VS2019. --- MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 9d72b81935..ca65415006 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -147,8 +147,8 @@ ASM_PFX(CoreBootServices): push r8 push rdx mov rbp, rsp - ; Reserve space on stack for 3 CallBootService arguments (NOOPT prerequisite). - sub rsp, 8*3 + ; Reserve space on stack for 4 CallBootService arguments (NOOPT prerequisite). + sub rsp, 8*4 ; Prepare CallBootService arguments. mov rcx, r10 @@ -165,7 +165,7 @@ ASM_PFX(CoreBootServices): pop rax ; Step over Arguments [1..3] and NOOPT buffer. - add rsp, 8*6 + add rsp, 8*7 ; Prepare SYSRET arguments. pop r11 From a3903f15643315ce896a16903b627571ab61a400 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 13 Sep 2024 14:40:24 +0300 Subject: [PATCH 253/341] ArmMmuLib: Worked around lack of EL2&0 translation support. --- ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index 74b5e16c9e..03d0925566 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -488,7 +488,12 @@ GcdAttributeToPageAttribute ( PageAttributes |= TT_AP_RW_RW; } } else { - PageAttributes |= TT_UXN_MASK; + if (ArmReadCurrentEL () == AARCH64_EL1) { + // + // TODO: Add EL2&0 support. + // + PageAttributes |= TT_UXN_MASK; + } if ((GcdAttributes & EFI_MEMORY_RO) != 0) { PageAttributes |= TT_AP_NO_RO; From 8f95af0efff269557e1010ece8543ae859759f22 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 16 Sep 2024 16:39:19 +0300 Subject: [PATCH 254/341] Core/Dxe/DxeMain: Set default value for gRing3Data. --- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 48d484826e..446e8eb42b 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -247,6 +247,8 @@ DxeMain ( EFI_VECTOR_HANDOFF_INFO *VectorInfoList; EFI_VECTOR_HANDOFF_INFO *VectorInfo; + gRing3Data = NULL; + // // Setup Stack Guard // From bd865b626264f2bae063f3ade3928bddd8ee083e Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 16 Sep 2024 17:56:05 +0300 Subject: [PATCH 255/341] ArmPkg: Forbade user access to supervisor sections. --- ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c | 2 +- .../Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c | 31 ++++++++--- ArmPkg/Library/CpuArchLib/Arm/Mmu.c | 32 ++++++++---- MdePkg/Include/Arm/AArch32Mmu.h | 51 +++++++++---------- 4 files changed, 71 insertions(+), 45 deletions(-) diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c index 60dc6c987c..c65f293b61 100644 --- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c @@ -252,7 +252,7 @@ FillTranslationTable ( break; case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_XP: Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK; - Attributes |= TT_DESCRIPTOR_SECTION_XN_MASK; + Attributes |= TT_DESCRIPTOR_SECTION_XN_MASK | TT_DESCRIPTOR_SECTION_PXN_MASK; break; case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH: Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH; diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c index 0410883a90..3fc73a391b 100644 --- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c +++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c @@ -295,14 +295,30 @@ UpdateSectionEntries ( return EFI_UNSUPPORTED; } - if ((Attributes & EFI_MEMORY_RO) != 0) { - EntryValue |= TT_DESCRIPTOR_SECTION_AP_RO_RO; - } else { - EntryValue |= TT_DESCRIPTOR_SECTION_AP_RW_RW; - } + if ((Attributes & EFI_MEMORY_USER) != 0) { + EntryValue |= TT_DESCRIPTOR_SECTION_PXN_MASK; - if ((Attributes & EFI_MEMORY_XP) != 0) { + if ((Attributes & EFI_MEMORY_RO) != 0) { + EntryValue |= TT_DESCRIPTOR_SECTION_AP_RO_RO; + } else { + EntryValue |= TT_DESCRIPTOR_SECTION_AP_RW_RW; + } + + if ((Attributes & EFI_MEMORY_XP) != 0) { + EntryValue |= TT_DESCRIPTOR_SECTION_XN_MASK; + } + } else { EntryValue |= TT_DESCRIPTOR_SECTION_XN_MASK; + + if ((Attributes & EFI_MEMORY_RO) != 0) { + EntryValue |= TT_DESCRIPTOR_SECTION_AP_NO_RO; + } else { + EntryValue |= TT_DESCRIPTOR_SECTION_AP_NO_RW; + } + + if ((Attributes & EFI_MEMORY_XP) != 0) { + EntryValue |= TT_DESCRIPTOR_SECTION_PXN_MASK; + } } if ((Attributes & EFI_MEMORY_RP) == 0) { @@ -549,7 +565,7 @@ ArmSetMemoryAttributes ( } if ((AttributeMask & EFI_MEMORY_XP) != 0) { - TtEntryMask |= TT_DESCRIPTOR_SECTION_XN_MASK; + TtEntryMask |= TT_DESCRIPTOR_SECTION_XN_MASK | TT_DESCRIPTOR_SECTION_PXN_MASK; } } else { ASSERT (AttributeMask == 0); @@ -559,6 +575,7 @@ ArmSetMemoryAttributes ( TtEntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK | TT_DESCRIPTOR_SECTION_XN_MASK | + TT_DESCRIPTOR_SECTION_PXN_MASK | TT_DESCRIPTOR_SECTION_AP_MASK | TT_DESCRIPTOR_SECTION_AF; } diff --git a/ArmPkg/Library/CpuArchLib/Arm/Mmu.c b/ArmPkg/Library/CpuArchLib/Arm/Mmu.c index 86c375075a..62c2a4ef3a 100644 --- a/ArmPkg/Library/CpuArchLib/Arm/Mmu.c +++ b/ArmPkg/Library/CpuArchLib/Arm/Mmu.c @@ -78,7 +78,10 @@ SectionToGcdAttributes ( } // now process eXectue Never attribute - if ((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0) { + if ((((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0) + && ((*GcdAttributes & EFI_MEMORY_USER) != 0)) + || (((SectionAttributes & TT_DESCRIPTOR_SECTION_PXN_MASK) != 0) + && ((*GcdAttributes & EFI_MEMORY_USER) == 0))) { *GcdAttributes |= EFI_MEMORY_XP; } @@ -159,20 +162,24 @@ PageToGcdAttributes ( // determine protection attributes switch (PageAttributes & TT_DESCRIPTOR_PAGE_AP_MASK) { case TT_DESCRIPTOR_PAGE_AP_NO_RW: + break; case TT_DESCRIPTOR_PAGE_AP_RW_RW: - // normal read/write access, do not add additional attributes + *GcdAttributes |= EFI_MEMORY_USER; break; // read only cases map to write-protect case TT_DESCRIPTOR_PAGE_AP_NO_RO: + *GcdAttributes |= EFI_MEMORY_RO; + break; case TT_DESCRIPTOR_PAGE_AP_RO_RO: - *GcdAttributes |= EFI_MEMORY_RO; + *GcdAttributes |= EFI_MEMORY_RO | EFI_MEMORY_USER; break; } // now process eXectue Never attribute - if ((PageAttributes & TT_DESCRIPTOR_PAGE_XN_MASK) != 0) { - *GcdAttributes |= EFI_MEMORY_XP; + if (((PageAttributes & TT_DESCRIPTOR_PAGE_XN_MASK) != 0) + && ((*GcdAttributes & EFI_MEMORY_USER) != 0)) { + *GcdAttributes |= EFI_MEMORY_XP; } if ((PageAttributes & TT_DESCRIPTOR_PAGE_AF) == 0) { @@ -472,6 +479,11 @@ EfiAttributeToArmAttribute ( // Determine protection attributes if ((EfiAttributes & EFI_MEMORY_USER) != 0) { + // Determine eXecute Never attribute + if ((EfiAttributes & EFI_MEMORY_XP) != 0) { + ArmAttributes |= TT_DESCRIPTOR_SECTION_XN_MASK; + } + // // TODO: Add PXN for Translation table descriptors. // @@ -481,6 +493,11 @@ EfiAttributeToArmAttribute ( ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_RW_RW; } } else { + // Determine eXecute Never attribute + if ((EfiAttributes & EFI_MEMORY_XP) != 0) { + ArmAttributes |= TT_DESCRIPTOR_SECTION_PXN_MASK; + } + if ((EfiAttributes & EFI_MEMORY_RO) != 0) { ArmAttributes |= TT_DESCRIPTOR_SECTION_AP_NO_RO; } else { @@ -488,11 +505,6 @@ EfiAttributeToArmAttribute ( } } - // Determine eXecute Never attribute - if ((EfiAttributes & EFI_MEMORY_XP) != 0) { - ArmAttributes |= TT_DESCRIPTOR_SECTION_XN_MASK; - } - if ((EfiAttributes & EFI_MEMORY_RP) == 0) { ArmAttributes |= TT_DESCRIPTOR_SECTION_AF; } diff --git a/MdePkg/Include/Arm/AArch32Mmu.h b/MdePkg/Include/Arm/AArch32Mmu.h index 89b81e33d0..a0af346582 100644 --- a/MdePkg/Include/Arm/AArch32Mmu.h +++ b/MdePkg/Include/Arm/AArch32Mmu.h @@ -97,6 +97,7 @@ #define TT_DESCRIPTOR_PAGE_AF (1UL << 4) #define TT_DESCRIPTOR_SECTION_XN_MASK (0x1UL << 4) +#define TT_DESCRIPTOR_SECTION_PXN_MASK (0x1UL << 0) #define TT_DESCRIPTOR_PAGE_XN_MASK (0x1UL << 0) #define TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK ((3UL << 12) | (1UL << 3) | (1UL << 2)) @@ -136,7 +137,7 @@ #define TT_DESCRIPTOR_SECTION_ATTRIBUTE_MASK (TT_DESCRIPTOR_SECTION_NS_MASK | TT_DESCRIPTOR_SECTION_NG_MASK | \ TT_DESCRIPTOR_SECTION_S_MASK | TT_DESCRIPTOR_SECTION_AP_MASK | \ - TT_DESCRIPTOR_SECTION_AF | \ + TT_DESCRIPTOR_SECTION_AF | TT_DESCRIPTOR_SECTION_PXN_MASK | \ TT_DESCRIPTOR_SECTION_XN_MASK | TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK) #define TT_DESCRIPTOR_PAGE_ATTRIBUTE_MASK (TT_DESCRIPTOR_PAGE_NG_MASK | TT_DESCRIPTOR_PAGE_S_MASK | \ @@ -161,7 +162,7 @@ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \ TT_DESCRIPTOR_SECTION_S_SHARED | \ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \ - TT_DESCRIPTOR_SECTION_AP_RW_RW | \ + TT_DESCRIPTOR_SECTION_AP_NO_RW | \ TT_DESCRIPTOR_SECTION_AF) #define TT_DESCRIPTOR_SECTION_WRITE_BACK (TT_DESCRIPTOR_SECTION_DEFAULT | \ @@ -176,31 +177,27 @@ #define TT_DESCRIPTOR_SECTION_UNCACHED (TT_DESCRIPTOR_SECTION_DEFAULT | \ TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE) -#define TT_DESCRIPTOR_PAGE_WRITE_BACK (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ - TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ - TT_DESCRIPTOR_PAGE_S_SHARED | \ - TT_DESCRIPTOR_PAGE_AP_RW_RW | \ - TT_DESCRIPTOR_PAGE_AF | \ - TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC) -#define TT_DESCRIPTOR_PAGE_WRITE_THROUGH (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ - TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ - TT_DESCRIPTOR_PAGE_S_SHARED | \ - TT_DESCRIPTOR_PAGE_AP_RW_RW | \ - TT_DESCRIPTOR_PAGE_AF | \ - TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC) -#define TT_DESCRIPTOR_PAGE_DEVICE (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ - TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ - TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \ - TT_DESCRIPTOR_PAGE_AP_RW_RW | \ - TT_DESCRIPTOR_PAGE_AF | \ - TT_DESCRIPTOR_PAGE_XN_MASK | \ - TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE) -#define TT_DESCRIPTOR_PAGE_UNCACHED (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ - TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ - TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \ - TT_DESCRIPTOR_PAGE_AP_RW_RW | \ - TT_DESCRIPTOR_PAGE_AF | \ - TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE) +#define TT_DESCRIPTOR_PAGE_DEFAULT (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ + TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ + TT_DESCRIPTOR_PAGE_AP_NO_RW | \ + TT_DESCRIPTOR_PAGE_AF) + +#define TT_DESCRIPTOR_PAGE_WRITE_BACK (TT_DESCRIPTOR_PAGE_DEFAULT | \ + TT_DESCRIPTOR_PAGE_S_SHARED | \ + TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC) + +#define TT_DESCRIPTOR_PAGE_WRITE_THROUGH (TT_DESCRIPTOR_PAGE_DEFAULT | \ + TT_DESCRIPTOR_PAGE_S_SHARED | \ + TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC) + +#define TT_DESCRIPTOR_PAGE_DEVICE (TT_DESCRIPTOR_PAGE_DEFAULT | \ + TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \ + TT_DESCRIPTOR_PAGE_XN_MASK | \ + TT_DESCRIPTOR_PAGE_CACHE_POLICY_SHAREABLE_DEVICE) + +#define TT_DESCRIPTOR_PAGE_UNCACHED (TT_DESCRIPTOR_PAGE_DEFAULT | \ + TT_DESCRIPTOR_PAGE_S_NOT_SHARED | \ + TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE) // First Level Descriptors typedef UINT32 ARM_FIRST_LEVEL_DESCRIPTOR; From 560c03a07974697712df88162472b20723533322 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 17 Sep 2024 11:37:46 +0300 Subject: [PATCH 256/341] CpuExceptionHandlerLib: Refactored IO Bit Map initialization. --- .../Ia32/ArchExceptionHandler.c | 22 ++++++++++--------- .../Ia32/ArchInterruptDefs.h | 2 +- .../X64/ArchExceptionHandler.c | 22 ++++++++++--------- .../X64/ArchInterruptDefs.h | 2 +- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c index ae39125a1c..dfd803c7a6 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c @@ -136,6 +136,8 @@ ArchSetupExceptionStack ( UINTN NeedBufferSize; EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap; UINT8 *IOBitMap; + UINT8 *IOBitMapPointer; + UINT8 Offset; if (BufferSize == NULL) { return EFI_INVALID_PARAMETER; @@ -234,17 +236,17 @@ ArchSetupExceptionStack ( // and DebugIoPort = 0x402. // IOBitMap = (UINT8 *)((UINTN)Tss + Tss->IOMapBaseAddress); - for (Index = 0; Index < IO_BIT_MAP_SIZE; ++Index) { - if ((Index * 8) == FixedPcdGet16 (PcdUartBase)) { - *IOBitMap = 0x84; - } else if ((Index * 8) == (FixedPcdGet16 (PcdDebugIoPort) - 2)) { - *IOBitMap = 0xFB; - } else { - *IOBitMap = 0xFF; - } + SetMem (IOBitMap, IO_BIT_MAP_SIZE, 0xFF); - ++IOBitMap; - } + IOBitMapPointer = (UINT8 *)((UINTN)IOBitMap + FixedPcdGet16 (PcdUartBase) / 8); + Offset = (UINT8)(FixedPcdGet16 (PcdUartBase) & 0x7U); + *(UINT16 *)IOBitMapPointer &= ~((1U << Offset) | (1U << (Offset + 1)) + | (1U << (Offset + 3)) | (1U << (Offset + 4)) + | (1U << (Offset + 5)) | (1U << (Offset + 6))); + + IOBitMapPointer = (UINT8 *)((UINTN)IOBitMap + FixedPcdGet16 (PcdDebugIoPort) / 8); + Offset = (UINT8)(FixedPcdGet16 (PcdDebugIoPort) & 0x7U); + *IOBitMapPointer &= ~(1U << Offset); Tss = (IA32_TASK_STATE_SEGMENT *)((UINTN)Tss + sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE); ++TssDesc; diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h index eeae24bdb3..f470cb2306 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h @@ -39,7 +39,7 @@ typedef struct { (sizeof (IA32_TSS_DESCRIPTOR) * \ (FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + 1)) -#define IO_BIT_MAP_SIZE (ALIGN_VALUE (FixedPcdGet16 (PcdDebugIoPort) / 8 + 1, 16)) +#define IO_BIT_MAP_SIZE (ALIGN_VALUE (MAX (FixedPcdGet16 (PcdUartBase) ,FixedPcdGet16 (PcdDebugIoPort)) / 8 + 1, 16)) #define CPU_TSS_SIZE \ (sizeof (IA32_TASK_STATE_SEGMENT) * \ (FixedPcdGetSize (PcdCpuStackSwitchExceptionList) + 1) + IO_BIT_MAP_SIZE) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index 1b35108e97..236e72b78b 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -140,6 +140,8 @@ ArchSetupExceptionStack ( UINT8 *StackSwitchExceptions; UINTN NeedBufferSize; UINT8 *IOBitMap; + UINT8 *IOBitMapPointer; + UINT8 Offset; if (BufferSize == NULL) { return EFI_INVALID_PARAMETER; @@ -241,17 +243,17 @@ ArchSetupExceptionStack ( // and DebugIoPort = 0x402. // IOBitMap = (UINT8 *)((UINTN)Tss + Tss->IOMapBaseAddress); - for (Index = 0; Index < IO_BIT_MAP_SIZE; ++Index) { - if ((Index * 8) == FixedPcdGet16 (PcdUartBase)) { - *IOBitMap = 0x84; - } else if ((Index * 8) == (FixedPcdGet16 (PcdDebugIoPort) - 2)) { - *IOBitMap = 0xFB; - } else { - *IOBitMap = 0xFF; - } + SetMem (IOBitMap, IO_BIT_MAP_SIZE, 0xFF); - ++IOBitMap; - } + IOBitMapPointer = (UINT8 *)((UINTN)IOBitMap + FixedPcdGet16 (PcdUartBase) / 8); + Offset = (UINT8)(FixedPcdGet16 (PcdUartBase) & 0x7U); + *(UINT16 *)IOBitMapPointer &= ~((1U << Offset) | (1U << (Offset + 1)) + | (1U << (Offset + 3)) | (1U << (Offset + 4)) + | (1U << (Offset + 5)) | (1U << (Offset + 6))); + + IOBitMapPointer = (UINT8 *)((UINTN)IOBitMap + FixedPcdGet16 (PcdDebugIoPort) / 8); + Offset = (UINT8)(FixedPcdGet16 (PcdDebugIoPort) & 0x7U); + *IOBitMapPointer &= ~(1U << Offset); // // Fixup IST and task-state segment diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h index 7ae9ff7b0a..0122b3c07f 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h @@ -38,7 +38,7 @@ typedef struct { } RESERVED_VECTORS_DATA; #define CPU_TSS_DESC_SIZE sizeof (IA32_TSS_DESCRIPTOR) -#define IO_BIT_MAP_SIZE (ALIGN_VALUE (FixedPcdGet16 (PcdDebugIoPort) / 8 + 1, 16)) +#define IO_BIT_MAP_SIZE (ALIGN_VALUE (MAX (FixedPcdGet16 (PcdUartBase) ,FixedPcdGet16 (PcdDebugIoPort)) / 8 + 1, 16)) #define CPU_TSS_SIZE (sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE) #endif From b2fb76795ff1930d14401188ae8b04bec446d8b9 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 23 Sep 2024 10:46:48 +0300 Subject: [PATCH 257/341] ArmVirtPkg: Switched DebugLibg from UartRam to UartFlash to eliminate HOB dependency. --- ArmVirtPkg/ArmVirt.dsc.inc | 11 +---------- .../DebugLibFdtPL011UartFlash.inf | 2 +- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 8fdc172aca..04a45a905b 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -48,7 +48,7 @@ !if $(TARGET) == RELEASE DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf !else - DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartRam.inf + DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf !endif DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf @@ -188,9 +188,6 @@ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf -!if $(TARGET) != RELEASE - DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf -!endif [LibraryClasses.common.PEI_CORE] PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf @@ -205,9 +202,6 @@ PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf SerialPortLib|ArmVirtPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.inf -!if $(TARGET) != RELEASE - DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf -!endif [LibraryClasses.common.PEIM] PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf @@ -222,9 +216,6 @@ PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf SerialPortLib|ArmVirtPkg/Library/FdtPL011SerialPortLib/EarlyFdtPL011SerialPortLib.inf -!if $(TARGET) != RELEASE - DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf -!endif [LibraryClasses.common.UEFI_DRIVER] # resolve RngLib via RngDxe's EFI_RNG_PROTOCOL for UEFI_DRIVER type drivers such as TlsDxe diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf index f35a0913f0..1ed861212b 100644 --- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartFlash.inf @@ -19,7 +19,7 @@ FILE_GUID = 43A4C56B-D071-4CE0-A157-9D59E6161DEC MODULE_TYPE = BASE VERSION_STRING = 1.0 - LIBRARY_CLASS = DebugLib|SEC PEI_CORE PEIM + LIBRARY_CLASS = DebugLib|SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION [Sources] DebugLib.c From c6c3b81b2b8211d5fcb7ca0e3946c3178ebfa4e2 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 23 Sep 2024 11:22:43 +0300 Subject: [PATCH 258/341] Ring3: Added DebugLibFdtPL011UartUser without HOB dependancy. --- ArmVirtPkg/ArmVirt.dsc.inc | 2 + ArmVirtPkg/ArmVirtQemu.dsc | 10 +- .../DebugLibFdtPL011UartUser.inf | 48 ++++++++++ .../Library/DebugLibFdtPL011Uart/User.c | 94 +++++++++++++++++++ MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 54 +---------- .../Core/Dxe/SysCall/Initialization.c | 64 ++++++++----- .../Core/Dxe/SysCall/SupportedProtocols.c | 4 +- 8 files changed, 198 insertions(+), 79 deletions(-) create mode 100644 ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf create mode 100644 ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 04a45a905b..2d93f0a17e 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -382,6 +382,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD5 gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE [Components.common] # diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index fa8a51b35b..f2cfc9620d 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -470,10 +470,18 @@ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf - FatPkg/EnhancedFatDxe/Fat.inf + FatPkg/EnhancedFatDxe/Fat.inf { + + !if $(TARGET) != RELEASE + DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf + !endif + } MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf + !if $(TARGET) != RELEASE + DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf + !endif } MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf new file mode 100644 index 0000000000..28149b30fe --- /dev/null +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf @@ -0,0 +1,48 @@ +## @file +# DebugLib instance that produces debug output directly via PL011UartLib. +# +# Copyright (C) Red Hat +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 1.27 + BASE_NAME = DebugLibFdtPL011UartUser + FILE_GUID = 5932FA0B-FC1A-43B9-B149-5C16137622B1 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = DebugLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION + CONSTRUCTOR = DebugLibFdtPL011UartUserConstructor + +[Sources] + DebugLib.c + User.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + ArmVirtPkg/ArmVirtPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugPrintErrorLevelLib + PL011UartLib + PcdLib + PrintLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask + gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel + +[FixedPcd] + gArmPlatformTokenSpaceGuid.PL011UartClkInHz + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits + +[Guids] + gEarlyPL011BaseAddressGuid diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c new file mode 100644 index 0000000000..2229cffde0 --- /dev/null +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c @@ -0,0 +1,94 @@ +/** @file + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + + Copyright (C) Red Hat + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +UINTN mDebugLibFdtPL011UartAddress; + +EFI_STATUS +EFIAPI +DebugLibFdtPL011UartUserConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + UINTN Index; + + mDebugLibFdtPL011UartAddress = 0; + + for (Index = 0; Index < SystemTable->NumberOfTableEntries; ++Index) { + if (CompareGuid (&gEarlyPL011BaseAddressGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) { + mDebugLibFdtPL011UartAddress = (UINTN)SystemTable->ConfigurationTable[Index].VendorTable; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +/** + (Copied from SerialPortWrite() in "MdePkg/Include/Library/SerialPortLib.h" at + commit c4547aefb3d0, with the Buffer non-nullity assertion removed:) + + Write data from buffer to serial device. + + Writes NumberOfBytes data bytes from Buffer to the serial device. + The number of bytes actually written to the serial device is returned. + If the return value is less than NumberOfBytes, then the write operation failed. + If NumberOfBytes is zero, then return 0. + + @param Buffer Pointer to the data buffer to be written. + @param NumberOfBytes Number of bytes to written to the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes written to the serial device. + If this value is less than NumberOfBytes, then the write operation failed. +**/ +UINTN +DebugLibFdtPL011UartWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + EFI_STATUS Status; + UINT64 BaudRate; + UINT32 ReceiveFifoDepth; + EFI_PARITY_TYPE Parity; + UINT8 DataBits; + EFI_STOP_BITS_TYPE StopBits; + + if (mDebugLibFdtPL011UartAddress == 0) { + return 0; + } + + BaudRate = (UINTN)FixedPcdGet64 (PcdUartDefaultBaudRate); + ReceiveFifoDepth = 0; // Use the default value for Fifo depth + Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity); + DataBits = FixedPcdGet8 (PcdUartDefaultDataBits); + StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits); + + Status = PL011UartInitializePort ( + mDebugLibFdtPL011UartAddress, + FixedPcdGet32 (PL011UartClkInHz), + &BaudRate, + &ReceiveFifoDepth, + &Parity, + &DataBits, + &StopBits + ); + if (EFI_ERROR (Status)) { + return 0; + } + + return PL011UartWrite (mDebugLibFdtPL011UartAddress, Buffer, NumberOfBytes); +} diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index d2d0283770..45ea642c96 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -224,6 +224,7 @@ gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES # [Hob] # RESOURCE_DESCRIPTOR ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 7d11e063fe..0ab3d85e38 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -6,14 +6,13 @@ **/ #include -#include #include #include #include "DxeMain.h" STATIC UINTN mCoreSp; -UINTN gUartBaseAddress; +extern UINTN gUartBaseAddress; EFI_STATUS EFIAPI @@ -95,13 +94,7 @@ InitializeMsr ( IN UINTN NumberOfEntries ) { - UINTN Tcr; - UINTN Index; - EARLY_PL011_BASE_ADDRESS *UartBase; - EFI_PHYSICAL_ADDRESS Physical; - EFI_HOB_GENERIC_HEADER *Ring3Hob; - UINT16 HobLength; - EFI_STATUS Status; + UINTN Tcr; // // If HCR_EL2.NV is 1 and the current Exception level is EL1, // then EL1 read accesses to the CurrentEL register return a value of 0x2 in bits[3:2]. @@ -115,49 +108,6 @@ InitializeMsr ( Tcr = ArmGetTCR (); Tcr |= TCR_EL1_HPD0_MASK | TCR_EL1_HPD1_MASK; ArmSetTCR (Tcr); - // - // Problem 1: Uart is memory maped. - // - for (Index = 0; Index < NumberOfEntries; ++Index) { - if (CompareGuid (&gEfiHobListGuid, &(Table[Index].VendorGuid))) { - UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); - gUartBaseAddress = UartBase->DebugAddress; - // - // Copy Hob into Ring3. - // - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - 1, - &Physical - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Hob.\n")); - ASSERT (FALSE); - } - DEBUG ((DEBUG_ERROR, "UartBaseAddress = %p.\n", gUartBaseAddress)); - - Ring3Hob = (EFI_HOB_GENERIC_HEADER *)(UINTN)Physical; - - HobLength = (UINT16)((sizeof (EFI_HOB_GUID_TYPE) + sizeof (EARLY_PL011_BASE_ADDRESS) + 0x7) & (~0x7)); - - Ring3Hob->HobType = EFI_HOB_TYPE_GUID_EXTENSION; - Ring3Hob->HobLength = HobLength; - Ring3Hob->Reserved = 0; - - CopyGuid (&((EFI_HOB_GUID_TYPE *)Ring3Hob)->Name, &gEarlyPL011BaseAddressGuid); - - Ring3Hob = (EFI_HOB_GENERIC_HEADER *)((UINTN)Ring3Hob + HobLength); - - Ring3Hob->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; - Ring3Hob->HobLength = sizeof (EFI_HOB_GENERIC_HEADER); - Ring3Hob->Reserved = 0; - - Table[Index].VendorTable = (VOID *)(UINTN)Physical; - UartBase = GET_GUID_HOB_DATA (Table[Index].VendorTable); - UartBase->DebugAddress = gUartBaseAddress; - } - } if (ArmHasPan ()) { // diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 3a0af40149..383e0579fc 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -5,6 +5,8 @@ **/ +#include + #include "DxeMain.h" VOID *gCoreSysCallStackTop; @@ -14,6 +16,7 @@ VOID *gRing3CallStackBase; VOID *gRing3EntryPoint; RING3_DATA *gRing3Data; VOID *gRing3Interfaces; +UINTN gUartBaseAddress; VOID EFIAPI @@ -29,12 +32,13 @@ InitializeRing3 ( IN LOADED_IMAGE_PRIVATE_DATA *Image ) { - EFI_STATUS Status; - VOID *TopOfStack; - UINTN SizeOfStack; - EFI_PHYSICAL_ADDRESS Physical; - UINTN Index; - EFI_CONFIGURATION_TABLE *Conf; + EFI_STATUS Status; + VOID *TopOfStack; + UINTN SizeOfStack; + EFI_PHYSICAL_ADDRESS Physical; + UINTN Index; + EFI_CONFIGURATION_TABLE *Conf; + EARLY_PL011_BASE_ADDRESS *UartBase; // // Set Ring3 EntryPoint and BootServices. @@ -54,27 +58,41 @@ InitializeRing3 ( CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (gRing3Data->SystemTable.NumberOfTableEntries * sizeof (EFI_CONFIGURATION_TABLE)), - &Physical - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); - return Status; - } + if (FixedPcdGetBool (PcdSerialUseMmio)) { + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES ((gRing3Data->SystemTable.NumberOfTableEntries + 1) * sizeof (EFI_CONFIGURATION_TABLE)), + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); + return Status; + } - Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; - for (Index = 0; Index < gRing3Data->SystemTable.NumberOfTableEntries; ++Index) { - Conf->VendorGuid = gRing3Data->SystemTable.ConfigurationTable[Index].VendorGuid; - Conf->VendorTable = gRing3Data->SystemTable.ConfigurationTable[Index].VendorTable; - ++Conf; - } + for (Index = 0; Index < gRing3Data->SystemTable.NumberOfTableEntries; ++Index) { + CopyGuid (&(Conf->VendorGuid), &gRing3Data->SystemTable.ConfigurationTable[Index].VendorGuid); + + Conf->VendorTable = gRing3Data->SystemTable.ConfigurationTable[Index].VendorTable; + + if (CompareGuid (&gEfiHobListGuid, &(Conf->VendorGuid))) { + UartBase = GET_GUID_HOB_DATA (Conf->VendorTable); + gUartBaseAddress = UartBase->DebugAddress; + } - gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + ++Conf; + } + CopyGuid (&(Conf->VendorGuid), &gEarlyPL011BaseAddressGuid); + Conf->VendorTable = (VOID *)gUartBaseAddress; + ++gRing3Data->SystemTable.NumberOfTableEntries; + + DEBUG ((DEBUG_ERROR, "Core: gUartBaseAddress = %p\n", gUartBaseAddress)); + + gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + } // // Initialize DxeRing3 with Supervisor privileges. // diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index d0e8944913..a04c7aa92c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -99,9 +99,7 @@ GoToRing3 ( // and can be used for translation table later. // AllowSupervisorAccessToUserMemory (); - // - // Problem 3: QEMU ramdomly breaks GP registers' context. - // + SetUefiImageMemoryAttributes ( gUartBaseAddress, EFI_PAGE_SIZE, From 45bfee105ccefe5086358d084bdf1861525ef202 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 23 Sep 2024 17:35:27 +0300 Subject: [PATCH 259/341] CpuExceptionHandlerLib: Added PcdSerialUseMmio condition. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + .../Core/Dxe/SysCall/Initialization.c | 4 +-- .../DxeCpuExceptionHandlerLib.inf | 1 + .../Ia32/ArchExceptionHandler.c | 29 ++++++++++-------- .../PeiCpuExceptionHandlerLib.inf | 1 + .../SecPeiCpuExceptionHandlerLib.inf | 1 + .../SmmCpuExceptionHandlerLib.inf | 1 + .../X64/ArchExceptionHandler.c | 30 ++++++++++--------- 8 files changed, 39 insertions(+), 29 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 45ea642c96..23fe346764 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -150,6 +150,7 @@ gEfiHobMemoryAllocStackGuid ## SOMETIMES_CONSUMES ## SystemTable gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## SysCall + gEarlyPL011BaseAddressGuid ## CONSUMES [Ppis] gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 383e0579fc..2a2995a704 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -58,7 +58,7 @@ InitializeRing3 ( CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); - if (FixedPcdGetBool (PcdSerialUseMmio)) { + if (PcdGetBool (PcdSerialUseMmio)) { Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, @@ -79,7 +79,7 @@ InitializeRing3 ( if (CompareGuid (&gEfiHobListGuid, &(Conf->VendorGuid))) { UartBase = GET_GUID_HOB_DATA (Conf->VendorTable); - gUartBaseAddress = UartBase->DebugAddress; + gUartBaseAddress = (UINTN)UartBase->DebugAddress; } ++Conf; diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf index 03d209b81a..8b0f85abb9 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf @@ -52,6 +52,7 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize gUefiOvmfPkgTokenSpaceGuid.PcdUartBase ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c index dfd803c7a6..ebc98b7b30 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c @@ -231,22 +231,25 @@ ArchSetupExceptionStack ( StackTop -= CPU_KNOWN_GOOD_STACK_SIZE; Tss->SS0 = AsmReadSs (); Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); - // - // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06; - // and DebugIoPort = 0x402. - // + IOBitMap = (UINT8 *)((UINTN)Tss + Tss->IOMapBaseAddress); SetMem (IOBitMap, IO_BIT_MAP_SIZE, 0xFF); - IOBitMapPointer = (UINT8 *)((UINTN)IOBitMap + FixedPcdGet16 (PcdUartBase) / 8); - Offset = (UINT8)(FixedPcdGet16 (PcdUartBase) & 0x7U); - *(UINT16 *)IOBitMapPointer &= ~((1U << Offset) | (1U << (Offset + 1)) - | (1U << (Offset + 3)) | (1U << (Offset + 4)) - | (1U << (Offset + 5)) | (1U << (Offset + 6))); - - IOBitMapPointer = (UINT8 *)((UINTN)IOBitMap + FixedPcdGet16 (PcdDebugIoPort) / 8); - Offset = (UINT8)(FixedPcdGet16 (PcdDebugIoPort) & 0x7U); - *IOBitMapPointer &= ~(1U << Offset); + if (!PcdGetBool (PcdSerialUseMmio)) { + // + // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06; + // and DebugIoPort = 0x402. + // + IOBitMapPointer = (UINT8 *)((UINTN)IOBitMap + FixedPcdGet16 (PcdUartBase) / 8); + Offset = (UINT8)(FixedPcdGet16 (PcdUartBase) & 0x7U); + *(UINT16 *)IOBitMapPointer &= ~((1U << Offset) | (1U << (Offset + 1)) + | (1U << (Offset + 3)) | (1U << (Offset + 4)) + | (1U << (Offset + 5)) | (1U << (Offset + 6))); + + IOBitMapPointer = (UINT8 *)((UINTN)IOBitMap + FixedPcdGet16 (PcdDebugIoPort) / 8); + Offset = (UINT8)(FixedPcdGet16 (PcdDebugIoPort) & 0x7U); + *IOBitMapPointer &= ~(1U << Offset); + } Tss = (IA32_TASK_STATE_SEGMENT *)((UINTN)Tss + sizeof (IA32_TASK_STATE_SEGMENT) + IO_BIT_MAP_SIZE); ++TssDesc; diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf index fbde353661..d03cafa91c 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf @@ -61,6 +61,7 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuStackSwitchExceptionList gUefiOvmfPkgTokenSpaceGuid.PcdUartBase ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf index eeb09f089d..436401cfde 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf @@ -72,6 +72,7 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize gUefiOvmfPkgTokenSpaceGuid.PcdUartBase ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf index c27821156a..6c24dd3181 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf @@ -60,6 +60,7 @@ gUefiCpuPkgTokenSpaceGuid.PcdCpuKnownGoodStackSize gUefiOvmfPkgTokenSpaceGuid.PcdUartBase ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES [FeaturePcd] gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c index 236e72b78b..95b8a9e962 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c @@ -238,23 +238,25 @@ ArchSetupExceptionStack ( Tss->RSP0 = StackTop; StackTop -= CPU_KNOWN_GOOD_STACK_SIZE; Tss->IOMapBaseAddress = sizeof (IA32_TASK_STATE_SEGMENT); - // - // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06; - // and DebugIoPort = 0x402. - // + IOBitMap = (UINT8 *)((UINTN)Tss + Tss->IOMapBaseAddress); SetMem (IOBitMap, IO_BIT_MAP_SIZE, 0xFF); - IOBitMapPointer = (UINT8 *)((UINTN)IOBitMap + FixedPcdGet16 (PcdUartBase) / 8); - Offset = (UINT8)(FixedPcdGet16 (PcdUartBase) & 0x7U); - *(UINT16 *)IOBitMapPointer &= ~((1U << Offset) | (1U << (Offset + 1)) - | (1U << (Offset + 3)) | (1U << (Offset + 4)) - | (1U << (Offset + 5)) | (1U << (Offset + 6))); - - IOBitMapPointer = (UINT8 *)((UINTN)IOBitMap + FixedPcdGet16 (PcdDebugIoPort) / 8); - Offset = (UINT8)(FixedPcdGet16 (PcdDebugIoPort) & 0x7U); - *IOBitMapPointer &= ~(1U << Offset); - + if (!PcdGetBool (PcdSerialUseMmio)) { + // + // Allow access to gUartBase = 0x3F8 and Offsets: 0x01, 0x03, 0x04, 0x05, 0x06; + // and DebugIoPort = 0x402. + // + IOBitMapPointer = (UINT8 *)((UINTN)IOBitMap + FixedPcdGet16 (PcdUartBase) / 8); + Offset = (UINT8)(FixedPcdGet16 (PcdUartBase) & 0x7U); + *(UINT16 *)IOBitMapPointer &= ~((1U << Offset) | (1U << (Offset + 1)) + | (1U << (Offset + 3)) | (1U << (Offset + 4)) + | (1U << (Offset + 5)) | (1U << (Offset + 6))); + + IOBitMapPointer = (UINT8 *)((UINTN)IOBitMap + FixedPcdGet16 (PcdDebugIoPort) / 8); + Offset = (UINT8)(FixedPcdGet16 (PcdDebugIoPort) & 0x7U); + *IOBitMapPointer &= ~(1U << Offset); + } // // Fixup IST and task-state segment // From c4d39fc0c1a7daaf8ccaf84b8ea4a5fc584945a3 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 25 Sep 2024 09:40:03 +0300 Subject: [PATCH 260/341] SysCall: Fixed page fault for ARM. --- .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 17 +++++++++++++---- .../Core/Dxe/SysCall/SupportedProtocols.c | 6 +++--- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index 8ffd808742..d208c9e0fe 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -11,6 +11,7 @@ #include "DxeMain.h" STATIC UINTN mCoreSp; +extern UINTN gUartBaseAddress; EFI_STATUS EFIAPI @@ -64,6 +65,12 @@ SysCallBootService ( // All remaining arguments are on User Stack. // CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN)); + + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP + ); ForbidSupervisorAccessToUserMemory (); Status = CallBootService ( @@ -72,6 +79,12 @@ SysCallBootService ( (RING3_STACK *)(UINTN)Physical ); + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); return Status; @@ -84,10 +97,6 @@ InitializeMsr ( IN UINTN NumberOfEntries ) { - // - // TODO: EFI_CONFIGURATION_TABLE, HOB_DATA, Uart are accessible to User. - // Fix PageTable initialization. - // if (ArmHasPan ()) { // // Enable Privileged Access Never feature. diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index a04c7aa92c..4da58f9839 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -13,7 +13,7 @@ EFI_FILE_PROTOCOL mRing3FileProtocol; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; -#if defined (MDE_CPU_AARCH64) +#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) extern UINTN gUartBaseAddress; #endif @@ -73,7 +73,7 @@ GoToRing3 ( EFI_MEMORY_XP | EFI_MEMORY_USER ); } -#elif defined (MDE_CPU_AARCH64) +#elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) // // Necessary fix for DEBUG printings. // @@ -93,7 +93,7 @@ GoToRing3 ( EFI_MEMORY_XP ); } -#elif defined (MDE_CPU_AARCH64) +#elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) // // Problem 2: Uart memory maped page is not allocated at the very beginnig // and can be used for translation table later. From f6e607ba4ede4d5713b9d166c971e3c136351766 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 26 Sep 2024 14:05:05 +0300 Subject: [PATCH 261/341] Ring3: Fixed Uart bug. --- ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c | 3 +-- MdeModulePkg/Core/Dxe/SysCall/Initialization.c | 12 ++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c index 2229cffde0..6e012ee85b 100644 --- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c @@ -29,11 +29,10 @@ DebugLibFdtPL011UartUserConstructor ( for (Index = 0; Index < SystemTable->NumberOfTableEntries; ++Index) { if (CompareGuid (&gEarlyPL011BaseAddressGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) { mDebugLibFdtPL011UartAddress = (UINTN)SystemTable->ConfigurationTable[Index].VendorTable; - return EFI_SUCCESS; } } - return EFI_NOT_FOUND; + return EFI_SUCCESS; } /** diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 2a2995a704..5ac1a7530b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -39,6 +39,7 @@ InitializeRing3 ( UINTN Index; EFI_CONFIGURATION_TABLE *Conf; EARLY_PL011_BASE_ADDRESS *UartBase; + CONST VOID *Hob; // // Set Ring3 EntryPoint and BootServices. @@ -77,19 +78,18 @@ InitializeRing3 ( Conf->VendorTable = gRing3Data->SystemTable.ConfigurationTable[Index].VendorTable; - if (CompareGuid (&gEfiHobListGuid, &(Conf->VendorGuid))) { - UartBase = GET_GUID_HOB_DATA (Conf->VendorTable); - gUartBaseAddress = (UINTN)UartBase->DebugAddress; - } - ++Conf; } + Hob = GetFirstGuidHob (&gEarlyPL011BaseAddressGuid); + UartBase = GET_GUID_HOB_DATA (Hob); + gUartBaseAddress = (UINTN)UartBase->DebugAddress; + CopyGuid (&(Conf->VendorGuid), &gEarlyPL011BaseAddressGuid); Conf->VendorTable = (VOID *)gUartBaseAddress; ++gRing3Data->SystemTable.NumberOfTableEntries; - DEBUG ((DEBUG_ERROR, "Core: gUartBaseAddress = %p\n", gUartBaseAddress)); + DEBUG ((DEBUG_ERROR, "Core: gUartBaseAddress = 0x%p\n", gUartBaseAddress)); gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; } From 2fa963dacb0965f3f262808a1da69de36a92367f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 26 Sep 2024 20:26:09 +0300 Subject: [PATCH 262/341] ArmPkg: Fixed buggy TT_DESCRIPTOR_SECTION_TYPE_MASK. --- MdePkg/Include/Arm/AArch32Mmu.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MdePkg/Include/Arm/AArch32Mmu.h b/MdePkg/Include/Arm/AArch32Mmu.h index a0af346582..959c29f2d5 100644 --- a/MdePkg/Include/Arm/AArch32Mmu.h +++ b/MdePkg/Include/Arm/AArch32Mmu.h @@ -46,11 +46,11 @@ #define TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(table, address) ((UINT32 *)(table) + (((UINTN)(address)) >> 20)) // Translation table descriptor types -#define TT_DESCRIPTOR_SECTION_TYPE_MASK ((1UL << 18) | (3UL << 0)) +#define TT_DESCRIPTOR_SECTION_TYPE_MASK ((1UL << 18) | (1UL << 1)) #define TT_DESCRIPTOR_SECTION_TYPE_FAULT (0UL << 0) #define TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE (1UL << 0) -#define TT_DESCRIPTOR_SECTION_TYPE_SECTION ((0UL << 18) | (2UL << 0)) -#define TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION ((1UL << 18) | (2UL << 0)) +#define TT_DESCRIPTOR_SECTION_TYPE_SECTION ((0UL << 18) | (1UL << 1)) +#define TT_DESCRIPTOR_SECTION_TYPE_SUPERSECTION ((1UL << 18) | (1UL << 1)) #define TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Desc) (((Desc) & 3UL) == TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE) // Translation table descriptor types From d3905a03ae5f12ba50a57be984e1892bcc1da7f0 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 27 Sep 2024 12:02:45 +0300 Subject: [PATCH 263/341] ArmPkg/Library/CpuArchLib: Refactored ARM to UEFI attribute conversion. --- ArmPkg/Library/CpuArchLib/AArch64/Mmu.c | 2 +- ArmPkg/Library/CpuArchLib/Arm/Mmu.c | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c b/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c index c1f80aa612..1805156e38 100644 --- a/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c +++ b/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c @@ -91,7 +91,7 @@ PageAttributeToGcdAttribute ( } // Process eXecute Never attribute - if ((PageAttributes & (TT_PXN_MASK | TT_UXN_MASK)) != 0) { + if ((PageAttributes & (TT_PXN_MASK | TT_UXN_MASK)) == (TT_PXN_MASK | TT_UXN_MASK)) { GcdAttributes |= EFI_MEMORY_XP; } diff --git a/ArmPkg/Library/CpuArchLib/Arm/Mmu.c b/ArmPkg/Library/CpuArchLib/Arm/Mmu.c index 62c2a4ef3a..51199b9594 100644 --- a/ArmPkg/Library/CpuArchLib/Arm/Mmu.c +++ b/ArmPkg/Library/CpuArchLib/Arm/Mmu.c @@ -78,10 +78,8 @@ SectionToGcdAttributes ( } // now process eXectue Never attribute - if ((((SectionAttributes & TT_DESCRIPTOR_SECTION_XN_MASK) != 0) - && ((*GcdAttributes & EFI_MEMORY_USER) != 0)) - || (((SectionAttributes & TT_DESCRIPTOR_SECTION_PXN_MASK) != 0) - && ((*GcdAttributes & EFI_MEMORY_USER) == 0))) { + if ((SectionAttributes & (TT_DESCRIPTOR_SECTION_XN_MASK | TT_DESCRIPTOR_SECTION_PXN_MASK)) + == (TT_DESCRIPTOR_SECTION_XN_MASK | TT_DESCRIPTOR_SECTION_PXN_MASK)) { *GcdAttributes |= EFI_MEMORY_XP; } From 10cdcb7907c7fdcdd6a0f9216c57c2d20cb4f1c4 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 27 Sep 2024 15:43:46 +0300 Subject: [PATCH 264/341] Ring3: Fixed buggy timer interrupt handling for AARCH64. --- ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S | 2 +- ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c | 3 +++ MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S | 6 ------ 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S index 2de7be7c8b..687d22e852 100644 --- a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S @@ -294,7 +294,7 @@ ASM_PFX(CommonExceptionEntry): ldp x24, x25, [sp, #0xc0] ldp x26, x27, [sp, #0xd0] // Preserve return value for SVC. - mrs x1, esr_el1 + ldr x1, [x28, #(FP_CONTEXT_SIZE + 0x18)] // Exception syndrome register lsr x1, x1, #26 and x1, x1, #0x3F cmp x1, #0x15 diff --git a/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c b/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c index 83d5543df3..1efb7f5c94 100644 --- a/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c +++ b/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c @@ -141,6 +141,9 @@ CommonCExceptionHandler ( if ((UINTN)ExceptionType <= gMaxExceptionNumber) { if (gExceptionHandlers[ExceptionType]) { gExceptionHandlers[ExceptionType](ExceptionType, SystemContext); +#if defined (MDE_CPU_AARCH64) + SystemContext.SystemContextAArch64->ESR = 0; +#endif return EFI_SUCCESS; } } else { diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 1192c150de..8307e93392 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -107,7 +107,6 @@ ASM_FUNC(ArmCallRing3) // msr spsr_el1, x1 isb - dsb sy eret //------------------------------------------------------------------------------ @@ -119,11 +118,6 @@ ASM_FUNC(ArmCallRing3) // ); //------------------------------------------------------------------------------ ASM_FUNC(ReturnToCore) - // Zero Exception Syndrome Register to prevent QEMU from random crashing. - msr esr_el1, xzr - msr spsr_el1, xzr - msr elr_el1, xzr - msr far_el1, xzr // Switch to Core Stack. mov sp, x1 // Restore registers and Stack. From 14b8f82b5166b3d7c289abf10feddef4f9a8dde8 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 1 Oct 2024 13:54:44 +0300 Subject: [PATCH 265/341] ArmLib: Added Instruction Synchronization Barriers for PAN changes. --- ArmPkg/Library/ArmLib/AArch64/AArch64Support.S | 2 ++ ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S | 2 ++ 2 files changed, 4 insertions(+) diff --git a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S index e4a10c2526..a188b40ed4 100644 --- a/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S +++ b/ArmPkg/Library/ArmLib/AArch64/AArch64Support.S @@ -402,10 +402,12 @@ ASM_FUNC(ArmReadIdAA64Pfr1) ASM_FUNC(ArmSetPan) msr pan, #1 + isb ret ASM_FUNC(ArmClearPan) msr pan, #0 + isb ret ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S index bd2861c444..6bde5bacc3 100644 --- a/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S +++ b/ArmPkg/Library/ArmLib/Arm/ArmLibSupport.S @@ -154,10 +154,12 @@ ASM_FUNC (ArmGetPhysicalAddressBits) ASM_FUNC(ArmSetPan) setpan #1 + isb bx LR ASM_FUNC(ArmClearPan) setpan #0 + isb bx LR ASM_FUNCTION_REMOVE_IF_UNREFERENCED From 15d79c471edece253398ae5a18f09a16af137cbf Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 1 Oct 2024 19:26:04 +0300 Subject: [PATCH 266/341] Ring3: Fixed PAN page faults. --- ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c | 4 ++++ .../AArch64/DefaultExceptionHandler.c | 2 -- MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 4 ++-- MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c | 4 ++-- MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c | 5 ----- 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c b/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c index 1efb7f5c94..38cf75dc34 100644 --- a/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c +++ b/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c @@ -138,6 +138,10 @@ CommonCExceptionHandler ( IN OUT EFI_SYSTEM_CONTEXT SystemContext ) { + if (ArmHasPan ()) { + ArmClearPan (); + } + if ((UINTN)ExceptionType <= gMaxExceptionNumber) { if (gExceptionHandlers[ExceptionType]) { gExceptionHandlers[ExceptionType](ExceptionType, SystemContext); diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index c87ef080da..04f218a724 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -255,8 +255,6 @@ DefaultExceptionHandler ( DEBUG ((DEBUG_ERROR, "PC 0x%012lx\n", SystemContext.SystemContextAArch64->ELR)); } - ArmClearPan (); - if ((UINT64 *)SystemContext.SystemContextAArch64->FP != 0) { Idx = 0; diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 0ab3d85e38..2ede70de1b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -76,14 +76,14 @@ SysCallBootService ( (RING3_STACK *)(UINTN)Physical ); + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); + SetUefiImageMemoryAttributes ( gUartBaseAddress, EFI_PAGE_SIZE, EFI_MEMORY_XP | EFI_MEMORY_USER ); - CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); - return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index d208c9e0fe..4e8c690116 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -79,14 +79,14 @@ SysCallBootService ( (RING3_STACK *)(UINTN)Physical ); + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); + SetUefiImageMemoryAttributes ( gUartBaseAddress, EFI_PAGE_SIZE, EFI_MEMORY_XP | EFI_MEMORY_USER ); - CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); - return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 4da58f9839..52fb93ff81 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -94,12 +94,7 @@ GoToRing3 ( ); } #elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) - // - // Problem 2: Uart memory maped page is not allocated at the very beginnig - // and can be used for translation table later. - // AllowSupervisorAccessToUserMemory (); - SetUefiImageMemoryAttributes ( gUartBaseAddress, EFI_PAGE_SIZE, From 620b3bbfc5a67dd2c1a81cd316d87351d5348193 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 18 Oct 2024 11:16:38 +0300 Subject: [PATCH 267/341] SysCall: Refactored ReturnToCore() for AARCH64, ARM. --- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 8 +++-- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 18 ++++++----- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 8 +++-- .../Core/Dxe/SysCall/ARM/InitializeMsr.c | 31 ++++++++++++------- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 8307e93392..3618257a82 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -113,11 +113,13 @@ ASM_FUNC(ArmCallRing3) // VOID // EFIAPI // ReturnToCore ( -// IN EFI_STATUS Status, -// IN UINTN CoreSp +// IN EFI_STATUS Status // ); +// +// (x0) Status +// (x1) mCoreSp //------------------------------------------------------------------------------ -ASM_FUNC(ReturnToCore) +ASM_FUNC(ArmReturnToCore) // Switch to Core Stack. mov sp, x1 // Restore registers and Stack. diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 2ede70de1b..531a3d6bf3 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -26,11 +26,20 @@ ArmCallRing3 ( VOID EFIAPI -ReturnToCore ( +ArmReturnToCore ( IN EFI_STATUS Status, IN UINTN CoreSp ); +VOID +EFIAPI +ReturnToCore ( + IN EFI_STATUS Status + ) +{ + ArmReturnToCore (Status, mCoreSp); +} + STATIC EFI_STATUS EFIAPI @@ -43,13 +52,6 @@ SysCallBootService ( EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Physical; - if (Type == SysCallReturnToCore) { - // - // TODO: Refactoring - // - ReturnToCore (*(EFI_STATUS *)CoreRbp, mCoreSp); - } - Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index d710ab8079..befe2d5f33 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -102,11 +102,13 @@ ASM_FUNC(ArmCallRing3) // VOID // EFIAPI // ReturnToCore ( -// IN EFI_STATUS Status, -// IN UINTN CoreSp +// IN EFI_STATUS Status // ); +// +// (r0) Status +// (r1) mCoreSp //------------------------------------------------------------------------------ -ASM_FUNC(ReturnToCore) +ASM_FUNC(ArmReturnToCore) // Switch to Core Stack. mov SP, R1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c index 4e8c690116..7f68d92fb7 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c @@ -25,11 +25,20 @@ ArmCallRing3 ( VOID EFIAPI -ReturnToCore ( +ArmReturnToCore ( IN EFI_STATUS Status, IN UINTN CoreSp ); +VOID +EFIAPI +ReturnToCore ( + IN EFI_STATUS Status + ) +{ + ArmReturnToCore (Status, mCoreSp); +} + STATIC EFI_STATUS EFIAPI @@ -42,10 +51,6 @@ SysCallBootService ( EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Physical; - if (Type == SysCallReturnToCore) { - ReturnToCore (*(EFI_STATUS *)CoreRbp, mCoreSp); - } - Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, @@ -78,14 +83,16 @@ SysCallBootService ( (CORE_STACK *)CoreRbp, (RING3_STACK *)(UINTN)Physical ); + // + // TODO: Fix memory leak for ReturnToCore(). + // + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); - CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); - - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); + SetUefiImageMemoryAttributes ( + gUartBaseAddress, + EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); return Status; } From 024ed67456d96e0e5a077898527a86a1a7f2cdac Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 21 Oct 2024 17:51:52 +0300 Subject: [PATCH 268/341] Ring3: Added support for AARCH64 EL2&0 translation regime. --- ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S | 9 +++ .../Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 56 +++++++++++-------- ArmVirtPkg/ArmVirt.dsc.inc | 2 +- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 25 ++++----- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 5 ++ MdePkg/Include/AArch64/AArch64.h | 4 ++ MdePkg/Include/Library/ArmLib.h | 4 +- 7 files changed, 66 insertions(+), 39 deletions(-) diff --git a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S index d35730704d..0a25ed5b39 100644 --- a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S +++ b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S @@ -133,6 +133,15 @@ ASM_FUNC(ArmInvalidateTlb) isb ret +ASM_FUNC(ArmWriteCptr) + EL1_OR_EL2_OR_EL3(x1) +1:ret +2:msr cptr_el2, x0 + b 4f +3:msr cptr_el3, x0 // EL3 Coprocessor Trap Reg (CPTR) +4:isb + ret + ASM_FUNC(ArmCallWFE) wfe ret diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index 03d0925566..3f89ad4816 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -63,6 +63,7 @@ ArmMemoryAttributeToPageAttribute ( } break; + default: Permissions = 0; break; @@ -479,29 +480,24 @@ GcdAttributeToPageAttribute ( PageAttributes |= TT_AF; } - if ((GcdAttributes & EFI_MEMORY_USER) != 0) { - PageAttributes |= TT_PXN_MASK; - - if ((GcdAttributes & EFI_MEMORY_RO) != 0) { - PageAttributes |= TT_AP_RO_RO; - } else { - PageAttributes |= TT_AP_RW_RW; - } - } else { - if (ArmReadCurrentEL () == AARCH64_EL1) { - // - // TODO: Add EL2&0 support. - // - PageAttributes |= TT_UXN_MASK; - } - - if ((GcdAttributes & EFI_MEMORY_RO) != 0) { - PageAttributes |= TT_AP_NO_RO; - } else { - PageAttributes |= TT_AP_NO_RW; - } - } - + if ((GcdAttributes & EFI_MEMORY_USER) != 0) { + PageAttributes |= TT_PXN_MASK; + + if ((GcdAttributes & EFI_MEMORY_RO) != 0) { + PageAttributes |= TT_AP_RO_RO; + } else { + PageAttributes |= TT_AP_RW_RW; + } + } else { + PageAttributes |= TT_UXN_MASK; + + if ((GcdAttributes & EFI_MEMORY_RO) != 0) { + PageAttributes |= TT_AP_NO_RO; + } else { + PageAttributes |= TT_AP_NO_RW; + } + } + return PageAttributes; } @@ -603,6 +599,7 @@ ArmConfigureMmu ( UINTN RootTableEntryCount; UINT64 TCR; EFI_STATUS Status; + UINTN Hcr; ASSERT (ArmReadCurrentEL () < AARCH64_EL3); if (ArmReadCurrentEL () == AARCH64_EL3) { @@ -627,6 +624,19 @@ ArmConfigureMmu ( T0SZ = 64 - MaxAddressBits; RootTableEntryCount = GetRootTableEntryCount (T0SZ); + if (ArmReadCurrentEL () == AARCH64_EL2) { + // + // Switch to EL2&0 translation regime. + // + Hcr = ArmReadHcr (); + Hcr |= ARM_HCR_E2H | ARM_HCR_TGE; + ArmWriteHcr (Hcr); + // + // Allow access to the Advanced SIMD and floating-point registers. + // + ArmWriteCptr (AARCH64_CPTR_FPEN); + } + // // Set TCR that allows us to retrieve T0SZ in the subsequent functions // diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 2d93f0a17e..19a874645a 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -107,7 +107,7 @@ CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf - ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf + ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf PlatformPeiLib|ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf MemoryInitPeiLib|ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.inf diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 3618257a82..5bc80d9966 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -88,24 +88,23 @@ ASM_FUNC(ArmCallRing3) // Disable interrupts. msr daifset, #0xf isb + // Copy PSTATE to SPSR. + mrs x6, nzcv + mrs x7, pan + orr x6, x6, x7 // Prepare Ring3 SP and EntryPoint. msr sp_el0, x1 - msr elr_el1, x2 + EL1_OR_EL2(x1) +1:msr elr_el1, x2 + msr spsr_el1, x6 + b 3f +2:msr elr_el2, x2 + msr spsr_el2, x6 // Save Core SP and switch to CoreSysCall Stack. - mov x5, sp +3:mov x5, sp str x5, [x4] mov sp, x3 - // Copy PSTATE to SPSR. - mrs x1, nzcv - mrs x2, pan - orr x1, x1, x2 - // - // M[3:0], bits [3:0] AArch64 Exception level and selected Stack Pointer. - // 0b0000 - EL0. - // 0b0100 - EL1 with SP_EL0 (ELt). - // 0b0101 - EL1 with SP_EL1 (EL1h). - // - msr spsr_el1, x1 + isb eret diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 531a3d6bf3..85a0edf599 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -97,6 +97,7 @@ InitializeMsr ( ) { UINTN Tcr; + UINTN Sctlr; // // If HCR_EL2.NV is 1 and the current Exception level is EL1, // then EL1 read accesses to the CurrentEL register return a value of 0x2 in bits[3:2]. @@ -115,6 +116,10 @@ InitializeMsr ( // // Enable Privileged Access Never feature. // + Sctlr = ArmReadSctlr (); + Sctlr |= SCTLR_EPAN; + ArmWriteSctlr (Sctlr); + ArmSetPan (); } diff --git a/MdePkg/Include/AArch64/AArch64.h b/MdePkg/Include/AArch64/AArch64.h index c30282defa..36f8e95cbf 100644 --- a/MdePkg/Include/AArch64/AArch64.h +++ b/MdePkg/Include/AArch64/AArch64.h @@ -25,6 +25,7 @@ #define AARCH64_CPTR_TFP (1 << 10) #define AARCH64_CPTR_RES1 0x33ff #define AARCH64_CPTR_DEFAULT AARCH64_CPTR_RES1 +#define AARCH64_CPTR_FPEN (3 << 20) // ID_AA64MMFR1 - AArch64 Memory Model Feature Register 0 definitions #define AARCH64_MMFR1_VH (0xF << 8) @@ -46,6 +47,9 @@ #define SCR_FW (1 << 4) #define SCR_AW (1 << 5) +// SCTLR - System Control Register definitions +#define SCTLR_EPAN BIT57 + // MIDR - Main ID Register definitions #define ARM_CPU_TYPE_SHIFT 4 #define ARM_CPU_TYPE_MASK 0xFFF diff --git a/MdePkg/Include/Library/ArmLib.h b/MdePkg/Include/Library/ArmLib.h index aaa3355b7e..11874c4caa 100644 --- a/MdePkg/Include/Library/ArmLib.h +++ b/MdePkg/Include/Library/ArmLib.h @@ -497,7 +497,7 @@ ArmEnableVFP ( VOID ); -UINT32 +UINTN EFIAPI ArmReadSctlr ( VOID @@ -506,7 +506,7 @@ ArmReadSctlr ( VOID EFIAPI ArmWriteSctlr ( - IN UINT32 Value + IN UINTN Value ); UINTN From 818b4c64cf98ef515c95e3c6d4f3767fc8614cb1 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 22 Oct 2024 13:18:11 +0300 Subject: [PATCH 269/341] ArmPkg: Disabled UserSpace by default to fix CI, as WinPE and Linux EFI stub can not boot in EL2&0 translation regime. --- ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 13 +++++++++++-- ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf | 5 +++++ ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf | 5 +++++ ArmVirtPkg/ArmVirt.dsc.inc | 2 +- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index 3f89ad4816..4d88bf6064 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -20,6 +20,8 @@ #include #include #include +#include + #include "ArmMmuLibInternal.h" STATIC ARM_REPLACE_LIVE_TRANSLATION_ENTRY mReplaceLiveEntryFunc = ArmReplaceLiveTranslationEntry; @@ -489,7 +491,9 @@ GcdAttributeToPageAttribute ( PageAttributes |= TT_AP_RW_RW; } } else { - PageAttributes |= TT_UXN_MASK; + if (PcdGetBool (PcdEnableUserSpace) || (ArmReadCurrentEL () == AARCH64_EL1)) { + PageAttributes |= TT_UXN_MASK; + } if ((GcdAttributes & EFI_MEMORY_RO) != 0) { PageAttributes |= TT_AP_NO_RO; @@ -624,7 +628,12 @@ ArmConfigureMmu ( T0SZ = 64 - MaxAddressBits; RootTableEntryCount = GetRootTableEntryCount (T0SZ); - if (ArmReadCurrentEL () == AARCH64_EL2) { + // + // Set TCR that allows us to retrieve T0SZ in the subsequent functions + // + // Ideally we will be running at EL2, but should support EL1 as well. + // UEFI should not run at EL3. + if (PcdGetBool (PcdEnableUserSpace) && (ArmReadCurrentEL () == AARCH64_EL2)) { // // Switch to EL2&0 translation regime. // diff --git a/ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf b/ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf index 510511bd41..babab4dca6 100644 --- a/ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf +++ b/ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf @@ -34,15 +34,20 @@ ArmPkg/ArmPkg.dec EmbeddedPkg/EmbeddedPkg.dec MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec [LibraryClasses] ArmLib CacheMaintenanceLib HobLib MemoryAllocationLib + PcdLib [Guids] gArmMmuReplaceLiveTranslationEntryFuncGuid [Pcd.ARM] gArmTokenSpaceGuid.PcdNormalMemoryNonshareableOverride + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace ## CONSUMES diff --git a/ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf b/ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf index 37424628aa..be33f6b37a 100644 --- a/ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf +++ b/ArmPkg/Library/ArmMmuLib/ArmMmuPeiLib.inf @@ -26,12 +26,17 @@ ArmPkg/ArmPkg.dec EmbeddedPkg/EmbeddedPkg.dec MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec [LibraryClasses] ArmLib CacheMaintenanceLib HobLib MemoryAllocationLib + PcdLib [Guids] gArmMmuReplaceLiveTranslationEntryFuncGuid + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace ## CONSUMES diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 19a874645a..ab1ca08104 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -382,7 +382,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD5 gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE - gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|FALSE gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE [Components.common] From bd2739315eb584c178c97a62a69f8b35b7f4a12d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 25 Oct 2024 12:02:51 +0300 Subject: [PATCH 270/341] Ring3: Added support for USER attribute in .fdf files. --- ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 6 ++-- BaseTools/Source/C/GenFfs/GenFfs.c | 7 ++++ .../Source/Python/CommonDataClass/FdfClass.py | 1 + BaseTools/Source/Python/GenFds/FdfParser.py | 2 ++ .../Source/Python/GenFds/FfsInfStatement.py | 6 ++-- .../Python/GenFds/GenFdsGlobalVariable.py | 4 ++- MdeModulePkg/Core/Dxe/DxeMain.h | 13 +++---- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 2 +- MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c | 4 +++ MdeModulePkg/Core/Dxe/Image/Image.c | 35 +++++++++++-------- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 29 ++++----------- .../DxeSecurityManagementLib.c | 5 +-- .../Library/UefiBootManagerLib/BmLoadOption.c | 3 +- MdeModulePkg/MdeModulePkg.dec | 4 +-- MdePkg/Include/Library/DxeServicesLib.h | 2 ++ MdePkg/Include/Pi/PiFirmwareFile.h | 1 + MdePkg/Include/Pi/PiFirmwareVolume.h | 1 + .../Library/DxeServicesLib/DxeServicesLib.c | 34 ++++++++++++------ OvmfPkg/OvmfPkgIa32.dsc | 5 +-- OvmfPkg/OvmfPkgIa32.fdf | 6 ++-- OvmfPkg/OvmfPkgIa32X64.fdf | 6 ++-- OvmfPkg/OvmfPkgX64.fdf | 6 ++-- 22 files changed, 107 insertions(+), 75 deletions(-) diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc index 7592700b68..270e0b87a1 100644 --- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc +++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc @@ -40,6 +40,8 @@ READ_LOCK_STATUS = TRUE APRIORI DXE { INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + # The driver responsible for UserSpace initialization (DxeRing3.inf) + # must be the first USER driver in APRIORI list. INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf } @@ -86,8 +88,8 @@ APRIORI DXE { # INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf - INF FatPkg/EnhancedFatDxe/Fat.inf - INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf + INF USER FatPkg/EnhancedFatDxe/Fat.inf + INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c index 12f9641ed8..392cf69d1f 100644 --- a/BaseTools/Source/C/GenFfs/GenFfs.c +++ b/BaseTools/Source/C/GenFfs/GenFfs.c @@ -592,6 +592,13 @@ Routine Description: continue; } + if ((stricmp (argv[0], "-u") == 0) || (stricmp (argv[0], "--user") == 0)) { + FfsAttrib |= FFS_ATTRIB_USER; + argc -= 1; + argv += 1; + continue; + } + if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--align") == 0)) { if (argv[1] == NULL || argv[1][0] == '-') { Error (NULL, 0, 1003, "Invalid option value", "Align value is missing for -a option"); diff --git a/BaseTools/Source/Python/CommonDataClass/FdfClass.py b/BaseTools/Source/Python/CommonDataClass/FdfClass.py index c8cfdaae32..b86b8fd621 100644 --- a/BaseTools/Source/Python/CommonDataClass/FdfClass.py +++ b/BaseTools/Source/Python/CommonDataClass/FdfClass.py @@ -81,6 +81,7 @@ def __init__(self): self.KeyStringList = [] self.KeepReloc = None self.UseArch = None + self.User = False ## section data in FDF # diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py index 160fe9c458..aa01fa4562 100644 --- a/BaseTools/Source/Python/GenFds/FdfParser.py +++ b/BaseTools/Source/Python/GenFds/FdfParser.py @@ -2500,6 +2500,8 @@ def _GetInfOptions(self, FfsInfObj): raise Warning.Expected("ARCH name", self.FileName, self.CurrentLineNumber) FfsInfObj.UseArch = self._Token + if self._IsKeyword("USER"): + FfsInfObj.User = True if self._GetNextToken(): p = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))') diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py index 7a214953fc..84c48a4050 100644 --- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -899,7 +899,8 @@ def __GenSimpleFileFfs__(self, Rule, InputFileList, MakefilePath = None): self.ModuleGuid, Fixed=Rule.Fixed, CheckSum=Rule.CheckSum, Align=Rule.Alignment, SectionAlign=SectionAlignments, - MakefilePath=MakefilePath + MakefilePath=MakefilePath, + User=self.User ) return FfsOutput @@ -1072,7 +1073,8 @@ def __GenComplexFileFfs__(self, Rule, InputFile, Alignments, MakefilePath = None self.ModuleGuid, Fixed=Rule.Fixed, CheckSum=Rule.CheckSum, Align=Rule.Alignment, SectionAlign=Alignments, - MakefilePath=MakefilePath + MakefilePath=MakefilePath, + User=self.User ) return FfsOutput diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py index 6c78a67ca6..62f2e6c619 100644 --- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py +++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py @@ -535,13 +535,15 @@ def GetAlignment (AlignString): @staticmethod def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None, - SectionAlign=None, MakefilePath=None): + SectionAlign=None, MakefilePath=None, User=False): Cmd = ["GenFfs", "-t", Type, "-g", Guid] mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"] if Fixed == True: Cmd.append("-x") if CheckSum: Cmd.append("-s") + if User: + Cmd.append("-u") if Align: if Align not in mFfsValidAlign: Align = GenFdsGlobalVariable.GetAlignment (Align) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 13abce957f..6dd4360913 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -230,7 +230,6 @@ typedef struct { VOID *HiiData; BOOLEAN IsUserImage; - BOOLEAN IsRing3EntryPoint; } LOADED_IMAGE_PRIVATE_DATA; typedef struct { @@ -2625,16 +2624,14 @@ RemoveImageRecord ( @param[in] LoadedImage The loaded image protocol @param[in] ImageOrigin Where File comes from. @param[in] LoadedImageDevicePath The loaded image device path protocol - @param[out] IsUserImage Whether the loaded image is in user space. - @param[out] IsRing3EntryPoint Whether the loaded image is a wrapper for Ring3 calls. + @param[in] IsUserImage Whether the loaded image is in user space. **/ VOID ProtectUefiImage ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN UINT8 ImageOrigin, - IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, - OUT BOOLEAN *IsUserImage, - OUT BOOLEAN *IsRing3EntryPoint + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN UINT8 ImageOrigin, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + IN BOOLEAN IsUserImage ); /** diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 446e8eb42b..9de6cfa2fe 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -334,7 +334,7 @@ DxeMain ( CoreInitializeMemoryProtection (); - ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, &mCurrentImage->IsUserImage, &mCurrentImage->IsRing3EntryPoint); + ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, mCurrentImage->IsUserImage); // // Call constructor for all libraries diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c b/MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c index 2ff22c93aa..1374894c2a 100644 --- a/MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c +++ b/MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c @@ -61,6 +61,10 @@ FfsAttributes2FvFileAttributes ( FileAttribute |= EFI_FV_FILE_ATTRIB_FIXED; } + if ((FfsAttributes & FFS_ATTRIB_USER) == FFS_ATTRIB_USER) { + FileAttribute |= EFI_FV_FILE_ATTRIB_USER; + } + return FileAttribute; } diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index a5d4e554e2..5526e5f503 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -67,8 +67,7 @@ LOADED_IMAGE_PRIVATE_DATA mCorePrivateImage = { NULL, // LoadedImageDevicePath EFI_SUCCESS, // LoadImageStatus NULL, // HiiData - FALSE, // IsUserImage - FALSE // IsRing3EntryPoint + FALSE // IsUserImage }; // // The field is define for Loading modules at fixed address feature to tracker the PEI code @@ -1108,6 +1107,7 @@ CoreLoadImageCommon ( BOOLEAN ImageIsFromLoadFile; UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UINT8 ImageOrigin; + EFI_FV_FILE_ATTRIBUTES FileAttributes; SecurityStatus = EFI_SUCCESS; @@ -1138,6 +1138,7 @@ CoreLoadImageCommon ( AuthenticationStatus = 0; ImageIsFromFv = FALSE; ImageIsFromLoadFile = FALSE; + FileAttributes = 0; // // If the caller passed a copy of the file, then just use it @@ -1209,6 +1210,7 @@ CoreLoadImageCommon ( BootPolicy, FilePath, &FHand.SourceSize, + &FileAttributes, &AuthenticationStatus ); if (FHand.Source == NULL) { @@ -1344,6 +1346,7 @@ CoreLoadImageCommon ( Image->Info.Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; Image->Info.FilePath = DuplicateDevicePath (FilePath); Image->Info.ParentHandle = ParentImageHandle; + Image->IsUserImage = (FileAttributes & EFI_FV_FILE_ATTRIB_USER) != 0; if (NumberOfPages != NULL) { Image->NumberOfPages = *NumberOfPages; @@ -1439,7 +1442,7 @@ CoreLoadImageCommon ( } Status = EFI_SUCCESS; - ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, &Image->IsUserImage, &Image->IsRing3EntryPoint); + ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, Image->IsUserImage); RegisterMemoryProfileImage ( Image->LoadedImageDevicePath, @@ -1689,18 +1692,20 @@ CoreStartImage ( // Image->Started = TRUE; - if (Image->IsRing3EntryPoint) { - Image->Status = InitializeRing3 (ImageHandle, Image); - } else if (Image->IsUserImage) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Image->Status = GoToRing3 ( - 2, - (VOID *)Image->EntryPoint, - ImageHandle, - gRing3Data - ); + if (PcdGetBool (PcdEnableUserSpace) && (Image->IsUserImage)) { + if (gRing3Data == NULL) { + Image->Status = InitializeRing3 (ImageHandle, Image); + } else { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + Image->Status = GoToRing3 ( + 2, + (VOID *)Image->EntryPoint, + ImageHandle, + gRing3Data + ); + } } else { Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); } diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 749dd96548..ce5cc87c62 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -166,16 +166,14 @@ IsMemoryProtectionSectionAligned ( @param[in] LoadedImage The loaded image protocol @param[in] ImageOrigin Where File comes from. @param[in] LoadedImageDevicePath The loaded image device path protocol - @param[out] IsUserImage Whether the loaded image is in user space. - @param[out] IsRing3EntryPoint Whether the loaded image is a wrapper for Ring3 calls. + @param[in] IsUserImage Whether the loaded image is in user space. **/ VOID ProtectUefiImage ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN UINT8 ImageOrigin, - IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, - OUT BOOLEAN *IsUserImage, - OUT BOOLEAN *IsRing3EntryPoint + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN UINT8 ImageOrigin, + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *ImageContext, + IN BOOLEAN IsUserImage ) { RETURN_STATUS PdbStatus; @@ -230,27 +228,14 @@ ProtectUefiImage ( // InsertTailList (&mProtectedImageRecordList, &ImageRecord->Link); - *IsRing3EntryPoint = FALSE; - if (gCpu != NULL) { // // CPU ARCH present. Update memory attribute directly. // - if (PcdGetBool (PcdEnableUserSpace) && (!RETURN_ERROR (PdbStatus))) { - if (AsciiStrStr (PdbPointer, "Fat") != NULL) { - SetUefiImageProtectionAttributes (ImageRecord, TRUE); - *IsUserImage = TRUE; - } else if (AsciiStrStr (PdbPointer, "Ring3") != NULL) { - SetUefiImageProtectionAttributes (ImageRecord, TRUE); - *IsUserImage = TRUE; - *IsRing3EntryPoint = TRUE; - } else { - SetUefiImageProtectionAttributes (ImageRecord, FALSE); - *IsUserImage = FALSE; - } + if (PcdGetBool (PcdEnableUserSpace)) { + SetUefiImageProtectionAttributes (ImageRecord, IsUserImage); } else { SetUefiImageProtectionAttributes (ImageRecord, FALSE); - *IsUserImage = FALSE; } } diff --git a/MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.c b/MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.c index 8b8cf3a7d3..2488fd219b 100644 --- a/MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.c +++ b/MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.c @@ -221,6 +221,7 @@ ExecuteSecurityHandlers ( EFI_HANDLE Handle; EFI_DEVICE_PATH_PROTOCOL *Node; EFI_DEVICE_PATH_PROTOCOL *FilePathToVerfiy; + EFI_FV_FILE_ATTRIBUTES FileAttributes; if (FilePath == NULL) { return EFI_INVALID_PARAMETER; @@ -252,12 +253,12 @@ ExecuteSecurityHandlers ( // // Try to get image by FALSE boot policy for the exact boot file path. // - FileBuffer = GetFileBufferByFilePath (FALSE, FilePath, &FileSize, &AuthenticationStatus); + FileBuffer = GetFileBufferByFilePath (FALSE, FilePath, &FileSize, &FileAttributes, &AuthenticationStatus); if (FileBuffer == NULL) { // // Try to get image by TRUE boot policy for the inexact boot file path. // - FileBuffer = GetFileBufferByFilePath (TRUE, FilePath, &FileSize, &AuthenticationStatus); + FileBuffer = GetFileBufferByFilePath (TRUE, FilePath, &FileSize, &FileAttributes, &AuthenticationStatus); } if ((FileBuffer != NULL) && (!EFI_ERROR (Status))) { diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c b/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c index 0e8154ae07..efe8ef8c03 100644 --- a/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c +++ b/MdeModulePkg/Library/UefiBootManagerLib/BmLoadOption.c @@ -1246,6 +1246,7 @@ BmGetNextLoadOptionBuffer ( EFI_DEVICE_PATH_PROTOCOL *CurFullPath; UINTN LocalFileSize; UINT32 AuthenticationStatus; + EFI_FV_FILE_ATTRIBUTES FileAttributes; LocalFileSize = 0; FileBuffer = NULL; @@ -1264,7 +1265,7 @@ BmGetNextLoadOptionBuffer ( break; } - FileBuffer = GetFileBufferByFilePath (TRUE, CurFullPath, &LocalFileSize, &AuthenticationStatus); + FileBuffer = GetFileBufferByFilePath (TRUE, CurFullPath, &LocalFileSize, &FileAttributes, &AuthenticationStatus); } while (FileBuffer == NULL); if (FileBuffer == NULL) { diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 335a0d86c9..7a303b80a2 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -1204,8 +1204,8 @@ # @Prompt Defines the page allocation for the MM communication buffer; default is 128 pages (512KB). gEfiMdeModulePkgTokenSpaceGuid.PcdMmCommBufferPages|128|UINT32|0x30001061 - ## Indicates whether some DXE drivers will be loaded in user memory. - # TRUE - Some DXE drivers will be loaded in user memory.
+ ## Indicates whether DXE drivers marked in .fdf file as USER will be loaded in user memory. + # TRUE - USER DXE drivers will be loaded in user memory.
# FALSE - All DXE drivers will be loaded in supervisor memory.
# @Prompt Enable User Space. gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|FALSE|BOOLEAN|0x30001062 diff --git a/MdePkg/Include/Library/DxeServicesLib.h b/MdePkg/Include/Library/DxeServicesLib.h index 9de8121b20..ea49c623de 100644 --- a/MdePkg/Include/Library/DxeServicesLib.h +++ b/MdePkg/Include/Library/DxeServicesLib.h @@ -230,6 +230,7 @@ GetSectionFromFfs ( @param[in] FilePath Pointer to the device path of the file that is abstracted to the file buffer. @param[out] FileSize Pointer to the size of the abstracted file buffer. + @param[out] FileAttributes Pointer to the attributes of the file that is abstracted to the file buffer. @param[out] AuthenticationStatus Pointer to the authentication status. @retval NULL FilePath is NULL, or FileSize is NULL, or AuthenticationStatus is NULL, or the file can't be found. @@ -241,6 +242,7 @@ GetFileBufferByFilePath ( IN BOOLEAN BootPolicy, IN CONST EFI_DEVICE_PATH_PROTOCOL *FilePath, OUT UINTN *FileSize, + OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes, OUT UINT32 *AuthenticationStatus ); diff --git a/MdePkg/Include/Pi/PiFirmwareFile.h b/MdePkg/Include/Pi/PiFirmwareFile.h index f8c65762b2..5cc267d895 100644 --- a/MdePkg/Include/Pi/PiFirmwareFile.h +++ b/MdePkg/Include/Pi/PiFirmwareFile.h @@ -88,6 +88,7 @@ typedef UINT8 EFI_FFS_FILE_STATE; #define FFS_ATTRIB_FIXED 0x04 #define FFS_ATTRIB_DATA_ALIGNMENT 0x38 #define FFS_ATTRIB_CHECKSUM 0x40 +#define FFS_ATTRIB_USER 0x80 /// /// FFS File State Bits. diff --git a/MdePkg/Include/Pi/PiFirmwareVolume.h b/MdePkg/Include/Pi/PiFirmwareVolume.h index 5cfec5ecb6..21df3a833c 100644 --- a/MdePkg/Include/Pi/PiFirmwareVolume.h +++ b/MdePkg/Include/Pi/PiFirmwareVolume.h @@ -23,6 +23,7 @@ typedef UINT32 EFI_FV_FILE_ATTRIBUTES; #define EFI_FV_FILE_ATTRIB_ALIGNMENT 0x0000001F #define EFI_FV_FILE_ATTRIB_FIXED 0x00000100 #define EFI_FV_FILE_ATTRIB_MEMORY_MAPPED 0x00000200 +#define EFI_FV_FILE_ATTRIB_USER 0x00000400 /// /// type of EFI FVB attribute diff --git a/MdePkg/Library/DxeServicesLib/DxeServicesLib.c b/MdePkg/Library/DxeServicesLib/DxeServicesLib.c index 942ef2a19e..9121a458db 100644 --- a/MdePkg/Library/DxeServicesLib/DxeServicesLib.c +++ b/MdePkg/Library/DxeServicesLib/DxeServicesLib.c @@ -565,6 +565,7 @@ GetSectionFromFfs ( that is abstracted to the file buffer. @param[out] FileSize The pointer to the size of the abstracted file buffer. + @param[out] FileAttributes Pointer to the attributes of the file that is abstracted to the file buffer. @param[out] AuthenticationStatus Pointer to the authentication status. @retval NULL FilePath is NULL, or FileSize is NULL, or AuthenticationStatus is NULL, or the file can't be found. @@ -576,6 +577,7 @@ GetFileBufferByFilePath ( IN BOOLEAN BootPolicy, IN CONST EFI_DEVICE_PATH_PROTOCOL *FilePath, OUT UINTN *FileSize, + OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes, OUT UINT32 *AuthenticationStatus ) { @@ -589,7 +591,6 @@ GetFileBufferByFilePath ( UINT8 *ImageBuffer; UINTN ImageBufferSize; EFI_FV_FILETYPE Type; - EFI_FV_FILE_ATTRIBUTES Attrib; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; EFI_FILE_HANDLE FileHandle; EFI_FILE_HANDLE LastHandle; @@ -646,15 +647,26 @@ GetFileBufferByFilePath ( if (!EFI_ERROR (Status)) { SectionType = EFI_SECTION_PE32; ImageBuffer = NULL; - Status = FwVol->ReadSection ( - FwVol, - FvNameGuid, - SectionType, - 0, - (VOID **)&ImageBuffer, - &ImageBufferSize, - AuthenticationStatus - ); + + Status = FwVol->ReadFile ( + FwVol, + FvNameGuid, + NULL, + &ImageBufferSize, + &Type, + FileAttributes, + AuthenticationStatus + ); + + Status = FwVol->ReadSection ( + FwVol, + FvNameGuid, + SectionType, + 0, + (VOID **)&ImageBuffer, + &ImageBufferSize, + AuthenticationStatus + ); if (EFI_ERROR (Status)) { // // Try a raw file, since a PE32 SECTION does not exist @@ -671,7 +683,7 @@ GetFileBufferByFilePath ( (VOID **)&ImageBuffer, &ImageBufferSize, &Type, - &Attrib, + FileAttributes, AuthenticationStatus ); } diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index d97b73cea4..03b84584cc 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -584,6 +584,8 @@ # # Security measures for memory protection. # + gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE !if $(LEGACY_WINDOWS_LOADER) == TRUE # Allow execution of EfiLoaderData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFFD1 @@ -596,9 +598,8 @@ # Allow execution of EfiReservedMemoryType, EfiConventionalMemory, EfiBootServicesData and EfiRuntimeServicesData memory regions. gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xFFFFFFFFFFFFFF04 gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x70000000 + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|FALSE !endif - gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE - gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE # # Firmware volume supports UE, and may require PE. diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index 47bc9d9f43..ee98e905b9 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -203,6 +203,8 @@ APRIORI DXE { !if $(SMM_REQUIRE) == FALSE INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf !endif + # The driver responsible for UserSpace initialization (DxeRing3.inf) + # must be the first USER driver in APRIORI list. INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf } @@ -288,8 +290,8 @@ INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf -INF FatPkg/EnhancedFatDxe/Fat.inf -INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +INF USER FatPkg/EnhancedFatDxe/Fat.inf +INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index 6a6832bcd7..f3d5243bde 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -204,6 +204,8 @@ APRIORI DXE { !if $(SMM_REQUIRE) == FALSE INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf !endif + # The driver responsible for UserSpace initialization (DxeRing3.inf) + # must be the first USER driver in APRIORI list. INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf } @@ -290,8 +292,8 @@ INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf -INF FatPkg/EnhancedFatDxe/Fat.inf -INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +INF USER FatPkg/EnhancedFatDxe/Fat.inf +INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 63d881cd92..d75733da6a 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -235,6 +235,8 @@ APRIORI DXE { !if $(SMM_REQUIRE) == FALSE INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf !endif + # The driver responsible for UserSpace initialization (DxeRing3.inf) + # must be the first USER driver in APRIORI list. INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf } @@ -322,8 +324,8 @@ INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf -INF FatPkg/EnhancedFatDxe/Fat.inf -INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +INF USER FatPkg/EnhancedFatDxe/Fat.inf +INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf From c58740767c8331a518a9ca61d760bb458e0a9430 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 29 Oct 2024 19:50:41 +0300 Subject: [PATCH 271/341] Ring3: Added build targets with '-D USER_SPACE' for ARM, AARCH64. --- .github/workflows/build_arm.yaml | 66 ++++++++++++++++++++++++++++++ .github/workflows/build_nolto.yaml | 36 ++++++++++++++++ ArmVirtPkg/ArmVirt.dsc.inc | 4 +- 3 files changed, 105 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_arm.yaml b/.github/workflows/build_arm.yaml index b4afa966ee..ea99581ed0 100644 --- a/.github/workflows/build_arm.yaml +++ b/.github/workflows/build_arm.yaml @@ -98,6 +98,38 @@ jobs: cp ./Build/ArmVirtQemu-"$arch"/"$target"_"$TOOLCHAIN"/FV/QEMU_EFI.fd ./firmware_artifacts/ArmVirtQemu/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd done done + rm -r ./Build/* + env: + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG,NOOPT + TOOLCHAIN: GCC + + - name: Build ArmVirtQemu for Linux + if: always() + run: ./efibuild.sh + env: + SELFPKG: ArmVirtQemu + SELFPKG_DIR: ArmVirtPkg + TOOLCHAINS: GCC + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + GCC_ARM_PREFIX: arm-linux-gnueabi- + GCC_AARCH64_PREFIX: aarch64-linux-gnu- + BUILD_ARGUMENTS: -D USER_SPACE + + - name: Prepare artifacts with firmwares for Linux + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + mkdir -p ./firmware_artifacts/ArmVirtQemu/Linux/"$arch"/"$target"_"$TOOLCHAIN" + cp ./Build/ArmVirtQemu-"$arch"/"$target"_"$TOOLCHAIN"/FV/QEMU_EFI.fd ./firmware_artifacts/ArmVirtQemu/Linux/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done env: ARCHS: ARM,AARCH64 TARGETS: RELEASE,DEBUG,NOOPT @@ -194,6 +226,36 @@ jobs: cp ./Build/ArmVirtQemu-"$arch"/"$target"_"$TOOLCHAIN"/FV/QEMU_EFI.fd ./firmware_artifacts/ArmVirtQemu/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd done done + rm -r ./Build/* + env: + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG,NOOPT + TOOLCHAIN: CLANGDWARF + + - name: Build ArmVirtQemu for Linux + if: always() + run: ./efibuild.sh + env: + SELFPKG: ArmVirtQemu + SELFPKG_DIR: ArmVirtPkg + TOOLCHAINS: CLANGDWARF + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + BUILD_ARGUMENTS: -D USER_SPACE + + - name: Prepare artifacts with firmwares for Linux + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + mkdir -p ./firmware_artifacts/ArmVirtQemu/Linux/"$arch"/"$target"_"$TOOLCHAIN" + cp ./Build/ArmVirtQemu-"$arch"/"$target"_"$TOOLCHAIN"/FV/QEMU_EFI.fd ./firmware_artifacts/ArmVirtQemu/Linux/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done env: ARCHS: ARM,AARCH64 TARGETS: RELEASE,DEBUG,NOOPT @@ -272,6 +334,8 @@ jobs: for arch in "${ARCHS[@]}"; do echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --fw-arch "$arch" + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" for Linux + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/Linux/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --fw-arch "$arch" done done env: @@ -289,6 +353,8 @@ jobs: for arch in "${ARCHS[@]}"; do echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --test-linux --fw-arch "$arch" + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" for Linux + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/Linux/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --test-linux --fw-arch "$arch" done done env: diff --git a/.github/workflows/build_nolto.yaml b/.github/workflows/build_nolto.yaml index 72d31d53d0..d97d130ff0 100644 --- a/.github/workflows/build_nolto.yaml +++ b/.github/workflows/build_nolto.yaml @@ -101,6 +101,38 @@ jobs: cp ./Build/ArmVirtQemu-"$arch"/"$target"_"$TOOLCHAIN"/FV/QEMU_EFI.fd ./firmware_artifacts/ArmVirtQemu/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd done done + rm -r ./Build/* + env: + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG + TOOLCHAIN: GCC + + - name: Build ArmVirtQemu for Linux + if: always() + run: ./efibuild.sh + env: + SELFPKG: ArmVirtQemu + SELFPKG_DIR: ArmVirtPkg + TOOLCHAINS: GCC + ARCHS: ARM,AARCH64 + TARGETS: RELEASE,DEBUG + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + GCC_ARM_PREFIX: arm-linux-gnueabi- + GCC_AARCH64_PREFIX: aarch64-linux-gnu- + BUILD_ARGUMENTS: -D EDK2_GCC_NOLTO -D USER_SPACE + + - name: Prepare artifacts with firmwares for Linux + if: always() + run: | + IFS=', ' read -r -a TARGETS <<< "$TARGETS" + IFS=', ' read -r -a ARCHS <<< "$ARCHS" + for target in "${TARGETS[@]}"; do + for arch in "${ARCHS[@]}"; do + mkdir -p ./firmware_artifacts/ArmVirtQemu/Linux/"$arch"/"$target"_"$TOOLCHAIN" + cp ./Build/ArmVirtQemu-"$arch"/"$target"_"$TOOLCHAIN"/FV/QEMU_EFI.fd ./firmware_artifacts/ArmVirtQemu/Linux/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd + done + done env: ARCHS: ARM,AARCH64 TARGETS: RELEASE,DEBUG @@ -420,6 +452,8 @@ jobs: for arch in "${ARCHS[@]}"; do echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --fw-arch "$arch" + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" for Linux + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/Linux/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --fw-arch "$arch" done done env: @@ -437,6 +471,8 @@ jobs: for arch in "${ARCHS[@]}"; do echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --test-linux --fw-arch "$arch" + echo Checking "$PACKAGE""$arch" "$target"_"$TOOLCHAIN" for Linux + python3 test_qemu_fw.py ./firmware_artifacts/"$PACKAGE"/Linux/"$arch"/"$target"_"$TOOLCHAIN"/FW.fd --test-linux --fw-arch "$arch" done done env: diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index ab1ca08104..87090a5e2a 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -382,7 +382,9 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD5 gEfiMdeModulePkgTokenSpaceGuid.PcdCpuStackGuard|TRUE - gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|FALSE +!ifdef $(USER_SPACE) + gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|TRUE +!endif gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|TRUE [Components.common] From 2c2299d64ba51b1bd98193909c13356c17c3b80c Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 1 Nov 2024 12:28:49 +0300 Subject: [PATCH 272/341] Ring3: Refactoring. --- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 5 ++++- MdePkg/Include/Library/BaseLib.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index ce5cc87c62..1dc47f9d00 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -99,6 +99,9 @@ SetUefiImageProtectionAttributes ( UEFI_IMAGE_RECORD_SEGMENT *ImageRecordSegment; UINTN SectionAddress; UINT32 Index; + UINT32 Attribute; + + Attribute = IsUser ? EFI_MEMORY_USER : 0; SectionAddress = ImageRecord->StartAddress; for (Index = 0; Index < ImageRecord->NumSegments; Index++) { @@ -106,7 +109,7 @@ SetUefiImageProtectionAttributes ( SetUefiImageMemoryAttributes ( SectionAddress, ImageRecordSegment->Size, - IsUser ? ImageRecordSegment->Attributes | (UINT32)EFI_MEMORY_USER : ImageRecordSegment->Attributes + ImageRecordSegment->Attributes | Attribute ); SectionAddress += ImageRecordSegment->Size; diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index 367055c70a..7c3696d51d 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -5783,6 +5783,7 @@ typedef struct { UINT16 Reserved_98; UINT16 T; UINT16 IOMapBaseAddress; + UINT32 SSP; } IA32_TASK_STATE_SEGMENT; typedef union { From 1c84b276dc59d25a59863c02c6a7e245ef37e65f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 26 Nov 2024 19:12:15 +0300 Subject: [PATCH 273/341] Ring3: Added support for separate User address space. --- MdeModulePkg/Core/Dxe/DxeMain.h | 11 + MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 2 + MdeModulePkg/Core/Dxe/Image/Image.c | 9 + MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 4 + .../Core/Dxe/SysCall/Initialization.c | 15 ++ .../Dxe/SysCall/X64/CoreBootServices.nasm | 21 +- .../Core/Dxe/SysCall/X64/InitializeMsr.c | 201 ++++++++++++++++++ MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 1 + .../Core/DxeIplPeim/X64/VirtualMemory.c | 11 + MdePkg/Include/Guid/MemoryAllocationHob.h | 4 + MdePkg/Include/Library/MemoryAllocationLib.h | 10 + MdePkg/Include/Protocol/Cpu.h | 11 + MdePkg/MdePkg.dec | 3 + OvmfPkg/Include/IndustryStandard/PageTable.h | 2 + UefiCpuPkg/Library/CpuArchLib/CpuDxe.c | 3 +- UefiCpuPkg/Library/CpuArchLib/CpuDxe.h | 10 + UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c | 29 +++ 18 files changed, 346 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 6dd4360913..5017f5155b 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -230,6 +230,7 @@ typedef struct { VOID *HiiData; BOOLEAN IsUserImage; + UINTN UserPageTable; } LOADED_IMAGE_PRIVATE_DATA; typedef struct { @@ -289,6 +290,10 @@ extern VOID *gCoreSysCallStackTop; extern VOID *gRing3CallStackBase; extern VOID *gRing3CallStackTop; extern VOID *gRing3EntryPoint; +extern VOID *gUserPageTableTemplate; +extern UINTN gUserPageTableTemplateSize; +extern UINTN gUserPageTable; +extern UINTN gCorePageTable; // // Service Initialization Functions @@ -2789,4 +2794,10 @@ FreeProtocolsList ( VOID ); +VOID +EFIAPI +MakeUserPageTableTemplate ( + VOID + ); + #endif diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 23fe346764..b93874a49e 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -151,6 +151,7 @@ gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## SysCall gEarlyPL011BaseAddressGuid ## CONSUMES + gEfiHobPageTableInfoGuid ## CONSUMES ## HOB [Ppis] gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 9de6cfa2fe..8e7362b216 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -336,6 +336,8 @@ DxeMain ( ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, mCurrentImage->IsUserImage); + MakeUserPageTableTemplate (); + // // Call constructor for all libraries // diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 5526e5f503..ff98785533 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1108,6 +1108,7 @@ CoreLoadImageCommon ( UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UINT8 ImageOrigin; EFI_FV_FILE_ATTRIBUTES FileAttributes; + VOID *UserPageTable; SecurityStatus = EFI_SUCCESS; @@ -1348,6 +1349,14 @@ CoreLoadImageCommon ( Image->Info.ParentHandle = ParentImageHandle; Image->IsUserImage = (FileAttributes & EFI_FV_FILE_ATTRIB_USER) != 0; + if ((gRing3Data != NULL) && Image->IsUserImage) { + UserPageTable = AllocatePages (EFI_SIZE_TO_PAGES (gUserPageTableTemplateSize)); + CopyMem (UserPageTable, gUserPageTableTemplate, gUserPageTableTemplateSize); + + Image->UserPageTable = (UINTN)UserPageTable; + gUserPageTable = Image->UserPageTable; + } + if (NumberOfPages != NULL) { Image->NumberOfPages = *NumberOfPages; } else { diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 1dc47f9d00..d9ada48738 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -82,6 +82,10 @@ SetUefiImageMemoryAttributes ( ASSERT (gCpu != NULL); gCpu->SetMemoryAttributes (gCpu, BaseAddress, Length, FinalAttributes); + + if ((Attributes & EFI_MEMORY_USER) != 0) { + gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, BaseAddress, Length, FinalAttributes); + } } /** diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 5ac1a7530b..dd2c9ccea3 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -59,6 +59,12 @@ InitializeRing3 ( CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); + SetUefiImageMemoryAttributes ( + (UINTN)gRing3Data, + ALIGN_VALUE (sizeof (RING3_DATA), EFI_PAGE_SIZE), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + if (PcdGetBool (PcdSerialUseMmio)) { Status = CoreAllocatePages ( AllocateAnyPages, @@ -124,6 +130,12 @@ InitializeRing3 ( gRing3Interfaces = (VOID *)(UINTN)Physical; + SetUefiImageMemoryAttributes ( + (UINTN)gRing3Interfaces, + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; // @@ -141,6 +153,9 @@ InitializeRing3 ( gCoreSysCallStackTop = TopOfStack; SetUefiImageMemoryAttributes ((UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); + // + // gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, (UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); + // DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); // diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index ca65415006..8a36fd849b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -123,8 +123,13 @@ copy: ; ; (On User Stack) Argument 4, 5, ... ;------------------------------------------------------------------------------ +ALIGN 4096 + global ASM_PFX(CoreBootServices) ASM_PFX(CoreBootServices): + mov rax, [ASM_PFX(gCorePageTable)] + mov cr3, rax + ; Switch from User to Core data segment selectors. mov ax, ss mov ds, ax @@ -175,6 +180,8 @@ ASM_PFX(CoreBootServices): pop rbp pop rsp + mov rdx, [ASM_PFX(gUserPageTable)] + mov cr3, rdx ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. o64 sysret ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. @@ -190,9 +197,9 @@ o64 sysret ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): + cli pushfq pop r11 - cli ; Save nonvolatile registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15. push rbx push rbp @@ -221,6 +228,8 @@ ASM_PFX(CallRing3): mov rsp, r8 mov rbp, rsp + mov r8, [ASM_PFX(gUserPageTable)] + mov cr3, r8 ; Pass control to user image o64 sysret @@ -248,5 +257,15 @@ ASM_PFX(ReturnToCore): ret SECTION .data +ALIGN 4096 + +global ASM_PFX(gCorePageTable) +ASM_PFX(gCorePageTable): + resq 1 + +global ASM_PFX(gUserPageTable) +ASM_PFX(gUserPageTable): + resq 1 + ASM_PFX(CoreRsp): resq 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c index 3126f09d12..7c0b84783f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c @@ -8,6 +8,202 @@ #include "DxeMain.h" #include +#include + +VOID *gUserPageTableTemplate; +UINTN gUserPageTableTemplateSize; + +VOID +EFIAPI +MakeUserPageTableTemplate ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EFI_PAGE_TABLE_INFO *PageTableInfo; + UINTN BigPageAddress; + EFI_PHYSICAL_ADDRESS PageAddress; + UINTN IndexOfPml5Entries; + UINTN IndexOfPml4Entries; + UINTN IndexOfPdpEntries; + UINTN IndexOfPageDirectoryEntries; + PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel5Entry; + PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry; + PAGE_MAP_AND_DIRECTORY_POINTER *PageMap; + PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry; + PAGE_TABLE_ENTRY *PageDirectoryEntry; + PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; + + GuidHob = GetFirstGuidHob (&gEfiHobPageTableInfoGuid); + if (GuidHob == NULL) { + DEBUG ((DEBUG_ERROR, "Core: Could not retrieve PageTableInfo HOB.\n")); + CpuDeadLoop (); + } + + PageTableInfo = (EFI_PAGE_TABLE_INFO *)(GET_GUID_HOB_DATA (GuidHob)); + + BigPageAddress = (UINTN)AllocateAlignedPages (PageTableInfo->TotalPagesNum, PAGE_TABLE_POOL_ALIGNMENT); + if (BigPageAddress == 0) { + DEBUG ((DEBUG_ERROR, "Core: Could not allocate buffer for User page table.\n")); + CpuDeadLoop (); + } + + // + // By architecture only one PageMapLevel4 exists - so lets allocate storage for it. + // + PageMap = (VOID *)BigPageAddress; + if (PageTableInfo->Page5LevelEnabled) { + // + // By architecture only one PageMapLevel5 exists - so lets allocate storage for it. + // + PageMapLevel5Entry = PageMap; + BigPageAddress += SIZE_4KB; + } + + PageAddress = 0; + + for ( IndexOfPml5Entries = 0 + ; IndexOfPml5Entries < PageTableInfo->NumberOfPml5EntriesNeeded + ; IndexOfPml5Entries++) + { + // + // Each PML5 entry points to a page of PML4 entires. + // So lets allocate space for them and fill them in in the IndexOfPml4Entries loop. + // When 5-Level Paging is disabled, below allocation happens only once. + // + PageMapLevel4Entry = (VOID *)BigPageAddress; + BigPageAddress += SIZE_4KB; + + if (PageTableInfo->Page5LevelEnabled) { + // + // Make a PML5 Entry + // + PageMapLevel5Entry->Uint64 = (UINT64)(UINTN)PageMapLevel4Entry | PageTableInfo->AddressEncMask; + PageMapLevel5Entry->Bits.ReadWrite = 1; + PageMapLevel5Entry->Bits.UserSupervisor = 1; + PageMapLevel5Entry->Bits.Present = 1; + PageMapLevel5Entry++; + } + + for ( IndexOfPml4Entries = 0 + ; IndexOfPml4Entries < (PageTableInfo->NumberOfPml5EntriesNeeded == 1 ? PageTableInfo->NumberOfPml4EntriesNeeded : 512) + ; IndexOfPml4Entries++, PageMapLevel4Entry++) + { + // + // Each PML4 entry points to a page of Page Directory Pointer entires. + // So lets allocate space for them and fill them in in the IndexOfPdpEntries loop. + // + PageDirectoryPointerEntry = (VOID *)BigPageAddress; + BigPageAddress += SIZE_4KB; + + // + // Make a PML4 Entry + // + PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | PageTableInfo->AddressEncMask; + PageMapLevel4Entry->Bits.ReadWrite = 1; + PageMapLevel4Entry->Bits.UserSupervisor = 1; + PageMapLevel4Entry->Bits.Present = 1; + + if (PageTableInfo->Page1GSupport) { + PageDirectory1GEntry = (VOID *)PageDirectoryPointerEntry; + + for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) { + // + // Fill in the Page Directory entries + // + PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | PageTableInfo->AddressEncMask; + PageDirectory1GEntry->Bits.ReadWrite = 1; + PageDirectory1GEntry->Bits.Present = 1; + PageDirectory1GEntry->Bits.MustBe1 = 1; + } + } else { + for ( IndexOfPdpEntries = 0 + ; IndexOfPdpEntries < (PageTableInfo->NumberOfPml4EntriesNeeded == 1 ? PageTableInfo->NumberOfPdpEntriesNeeded : 512) + ; IndexOfPdpEntries++, PageDirectoryPointerEntry++) + { + // + // Each Directory Pointer entries points to a page of Page Directory entires. + // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop. + // + PageDirectoryEntry = (VOID *)BigPageAddress; + BigPageAddress += SIZE_4KB; + + // + // Fill in a Page Directory Pointer Entries + // + PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | PageTableInfo->AddressEncMask; + PageDirectoryPointerEntry->Bits.ReadWrite = 1; + PageDirectoryPointerEntry->Bits.UserSupervisor = 1; + PageDirectoryPointerEntry->Bits.Present = 1; + + for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) { + // + // Fill in the Page Directory entries + // + PageDirectoryEntry->Uint64 = (UINT64)PageAddress | PageTableInfo->AddressEncMask; + PageDirectoryEntry->Bits.ReadWrite = 1; + PageDirectoryEntry->Bits.Present = 0; + PageDirectoryEntry->Bits.MustBe1 = 1; + } + } + + // + // Fill with null entry for unused PDPTE + // + ZeroMem (PageDirectoryPointerEntry, (512 - IndexOfPdpEntries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)); + } + } + + // + // For the PML4 entries we are not using fill in a null entry. + // + ZeroMem (PageMapLevel4Entry, (512 - IndexOfPml4Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)); + } + + if (PageTableInfo->Page5LevelEnabled) { + // + // For the PML5 entries we are not using fill in a null entry. + // + ZeroMem (PageMapLevel5Entry, (512 - IndexOfPml5Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)); + } + + gUserPageTableTemplate = (VOID *)PageMap; + gUserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (PageTableInfo->TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT); + gUserPageTable = (UINTN)gUserPageTableTemplate; + + SetUefiImageMemoryAttributes ((UINT64)PageMap, gUserPageTableTemplateSize, EFI_MEMORY_XP); + // + // Map CoreBootServices + // + gCpu->SetUserMemoryAttributes ( + gCpu, + (UINTN)PageMap, + (EFI_PHYSICAL_ADDRESS)(UINTN)CoreBootServices, + SIZE_4KB, + EFI_MEMORY_RO + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + (UINTN)PageMap, + (EFI_PHYSICAL_ADDRESS)(UINTN)&gCorePageTable, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + // + // Map ExceptionHandlerAsm: AsmIdtVectorBegin - AsmGetTemplateAddressMap + // mCorePageTable, gCoreSysCallStackTop + // + // gCpu->SetUserMemoryAttributes (gCpu, (UINTN)PageMap, BaseAddress, SIZE_4KB, EFI_MEMORY_RO); + + gCpu->SetUserMemoryAttributes ( + gCpu, + (UINTN)PageMap, + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); +} VOID EFIAPI @@ -26,6 +222,9 @@ InitializeMsr ( Ebx = 0; Edx = 0; + // The Intel-64 and IA-32 architectures also allow for global pages when the PGE flag (bit 7) is 1 in CR4. + // PGE must be zero. + // // Forbid supervisor-mode accesses to any user-mode pages. // @@ -76,4 +275,6 @@ InitializeMsr ( // Msr = (UINT64)BIT9; AsmWriteMsr64 (MSR_IA32_FMASK, Msr); + + gCorePageTable = AsmReadCr3 (); } diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf index e231e7bd6f..8a4d0eeab4 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -90,6 +90,7 @@ ## SOMETIMES_PRODUCES ## HOB gEfiMemoryTypeInformationGuid gUefiImageLoaderImageContextGuid + gEfiHobPageTableInfoGuid [FeaturePcd.IA32] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index 7a40a0f8fd..04aaadfec0 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -708,6 +708,7 @@ CreateIdentityMappingPageTables ( PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; UINT64 AddressEncMask; IA32_CR4 Cr4; + EFI_PAGE_TABLE_INFO PageTableInfo; // // Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings @@ -831,6 +832,16 @@ CreateIdentityMappingPageTables ( (UINT64)TotalPagesNum )); + PageTableInfo.NumberOfPml5EntriesNeeded = NumberOfPml5EntriesNeeded; + PageTableInfo.NumberOfPml4EntriesNeeded = NumberOfPml4EntriesNeeded; + PageTableInfo.NumberOfPdpEntriesNeeded = NumberOfPdpEntriesNeeded; + PageTableInfo.TotalPagesNum = TotalPagesNum; + PageTableInfo.Page5LevelEnabled = Page5LevelEnabled; + PageTableInfo.Page1GSupport = Page1GSupport; + PageTableInfo.AddressEncMask = AddressEncMask; + + BuildGuidDataHob (&gEfiHobPageTableInfoGuid, &PageTableInfo, sizeof (EFI_PAGE_TABLE_INFO)); + BigPageAddress = (UINTN)AllocatePageTableMemory (TotalPagesNum); ASSERT (BigPageAddress != 0); diff --git a/MdePkg/Include/Guid/MemoryAllocationHob.h b/MdePkg/Include/Guid/MemoryAllocationHob.h index e4c57bf1ac..9ebbd13992 100644 --- a/MdePkg/Include/Guid/MemoryAllocationHob.h +++ b/MdePkg/Include/Guid/MemoryAllocationHob.h @@ -21,8 +21,12 @@ #define EFI_HOB_MEMORY_ALLOC_MODULE_GUID \ {0xf8e21975, 0x899, 0x4f58, {0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6, 0xd7, 0x7a} } +#define EFI_HOB_PAGE_TABLE_INFO_GUID \ + {0xac992fe9, 0xb0cc, 0x45df, {0xae, 0xcf, 0x51, 0x5a, 0xd2, 0xc4, 0xe8, 0xb3} } + extern EFI_GUID gEfiHobMemoryAllocBspStoreGuid; extern EFI_GUID gEfiHobMemoryAllocStackGuid; extern EFI_GUID gEfiHobMemoryAllocModuleGuid; +extern EFI_GUID gEfiHobPageTableInfoGuid; #endif diff --git a/MdePkg/Include/Library/MemoryAllocationLib.h b/MdePkg/Include/Library/MemoryAllocationLib.h index 59d4b29c44..da7ac36b2f 100644 --- a/MdePkg/Include/Library/MemoryAllocationLib.h +++ b/MdePkg/Include/Library/MemoryAllocationLib.h @@ -14,6 +14,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #ifndef __MEMORY_ALLOCATION_LIB_H__ #define __MEMORY_ALLOCATION_LIB_H__ +typedef struct { + UINT32 NumberOfPml5EntriesNeeded; + UINT32 NumberOfPml4EntriesNeeded; + UINT32 NumberOfPdpEntriesNeeded; + UINTN TotalPagesNum; + BOOLEAN Page5LevelEnabled; + BOOLEAN Page1GSupport; + UINT64 AddressEncMask; +} EFI_PAGE_TABLE_INFO; + /** Allocates one or more 4KB pages of type EfiBootServicesData. diff --git a/MdePkg/Include/Protocol/Cpu.h b/MdePkg/Include/Protocol/Cpu.h index ccaec43cb4..cf263ce019 100644 --- a/MdePkg/Include/Protocol/Cpu.h +++ b/MdePkg/Include/Protocol/Cpu.h @@ -258,6 +258,16 @@ EFI_STATUS OUT UINT64 *Attributes ); +typedef +EFI_STATUS +(EFIAPI *EFI_CPU_SET_USER_MEMORY_ATTRIBUTES)( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN UINTN UserPageTable, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + /// /// The EFI_CPU_ARCH_PROTOCOL is used to abstract processor-specific functions from the DXE /// Foundation. This includes flushing caches, enabling and disabling interrupts, hooking interrupt @@ -288,6 +298,7 @@ struct _EFI_CPU_ARCH_PROTOCOL { /// UINT32 DmaBufferAlignment; EFI_CPU_GET_MEMORY_ATTRIBUTES GetMemoryAttributes; + EFI_CPU_SET_USER_MEMORY_ATTRIBUTES SetUserMemoryAttributes; }; extern EFI_GUID gEfiCpuArchProtocolGuid; diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index ed3b85cf3e..271c29198c 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -813,6 +813,9 @@ ## Include/Guid/MemoryAllocationHob.h gEfiHobMemoryAllocBspStoreGuid = { 0x564B33CD, 0xC92A, 0x4593, { 0x90, 0xBF, 0x24, 0x73, 0xE4, 0x3C, 0x63, 0x22 }} + ## Include/Guid/MemoryAllocationHob.h + gEfiHobPageTableInfoGuid = { 0xAC992FE9, 0xB0CC, 0x45DF, { 0xAE, 0xCF, 0x51, 0x5A, 0xD2, 0xC4, 0xE8, 0xB3 }} + ## Include/Guid/EventLegacyBios.h gEfiEventLegacyBootGuid = { 0x2A571201, 0x4966, 0x47F6, { 0x8B, 0x86, 0xF3, 0x1E, 0x41, 0xF3, 0x2F, 0x10 }} diff --git a/OvmfPkg/Include/IndustryStandard/PageTable.h b/OvmfPkg/Include/IndustryStandard/PageTable.h index a75b3fcfe7..d9a1195c04 100644 --- a/OvmfPkg/Include/IndustryStandard/PageTable.h +++ b/OvmfPkg/Include/IndustryStandard/PageTable.h @@ -158,4 +158,6 @@ typedef union { #define PTE_OFFSET(x) ( (x >> 12) & PAGETABLE_ENTRY_MASK) #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull +#define PAGE_TABLE_POOL_ALIGNMENT BASE_2MB + #endif diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c index db4551ac69..a058b0cec2 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c @@ -32,7 +32,8 @@ EFI_CPU_ARCH_PROTOCOL gCpuImpl = { CpuSetMemoryAttributes, 1, // NumberOfTimers 4, // DmaBufferAlignment - CpuGetMemoryAttributes + CpuGetMemoryAttributes, + CpuSetUserMemoryAttributes }; EFI_HOB_PLATFORM_INFO *mPlatformInfoHob2 = NULL; diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuDxe.h b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.h index 731dbd6d13..1ec897f1d9 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuDxe.h +++ b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.h @@ -229,6 +229,16 @@ CpuGetMemoryAttributes ( OUT UINT64 *Attributes ); +EFI_STATUS +EFIAPI +CpuSetUserMemoryAttributes ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN UINTN UserPageTable, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + /** Initialize Global Descriptor Table. diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c index 04f768e01d..862221d7e1 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c @@ -429,6 +429,35 @@ CpuGetMemoryAttributes ( return EFI_SUCCESS; } +EFI_STATUS +EFIAPI +CpuSetUserMemoryAttributes ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN UINTN UserPageTable, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ) +{ + UINT64 MemoryAttributes; + PAGE_TABLE_LIB_PAGING_CONTEXT PagingContext; + + MemoryAttributes = Attributes & EFI_MEMORY_ATTRIBUTE_MASK; + + GetCurrentPagingContext (&PagingContext); + + if (PagingContext.MachineType == IMAGE_FILE_MACHINE_I386) { + PagingContext.ContextData.Ia32.PageTableBase = (UINT32)UserPageTable; + } else { + PagingContext.ContextData.X64.PageTableBase = (UINT64)UserPageTable; + } + + // + // Set memory attribute by page table + // + return AssignMemoryPageAttributes (&PagingContext, BaseAddress, Length, MemoryAttributes, AllocatePages); +} + /** Modify memory attributes of page entry. From 1893344b647008f205c9ddee8777d99cc95c701e Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 27 Nov 2024 13:51:07 +0300 Subject: [PATCH 274/341] Ring3: Split Page Table template construction and initialization, removed ChangeUefiImageRing(), added GetUefiImageRecord(). --- MdeModulePkg/Core/Dxe/DxeMain.h | 35 ++--- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 4 +- MdeModulePkg/Core/Dxe/Image/Image.c | 14 +- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 33 ++--- .../Core/Dxe/SysCall/Initialization.c | 140 +++++++++++++++++- .../Core/Dxe/SysCall/X64/InitializeMsr.c | 44 +----- 6 files changed, 173 insertions(+), 97 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 5017f5155b..eb15d59eed 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -290,8 +290,6 @@ extern VOID *gCoreSysCallStackTop; extern VOID *gRing3CallStackBase; extern VOID *gRing3CallStackTop; extern VOID *gRing3EntryPoint; -extern VOID *gUserPageTableTemplate; -extern UINTN gUserPageTableTemplateSize; extern UINTN gUserPageTable; extern UINTN gCorePageTable; @@ -2651,18 +2649,9 @@ UnprotectUefiImage ( IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath ); -/** - Change UEFI image owner: Supervisor / Privileged or User / Unprivileged. - - @param[in] LoadedImage The loaded image protocol - @param[in] LoadedImageDevicePath The loaded image device path protocol - @param[in] IsUser Whether UEFI image record is User Image. -**/ -VOID -ChangeUefiImageRing ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath, - IN BOOLEAN IsUser +UEFI_IMAGE_RECORD * +GetUefiImageRecord ( + IN LOADED_IMAGE_PRIVATE_DATA *Image ); /** @@ -2740,6 +2729,18 @@ SetUefiImageMemoryAttributes ( IN UINT64 Attributes ); +/** + Set UEFI image protection attributes. + + @param[in] ImageRecord A UEFI image record + @param[in] IsUser Whether UEFI image record is User Image. +**/ +VOID +SetUefiImageProtectionAttributes ( + IN UEFI_IMAGE_RECORD *ImageRecord, + IN BOOLEAN IsUser + ); + EFI_STATUS EFIAPI CoreBootServices ( @@ -2794,10 +2795,10 @@ FreeProtocolsList ( VOID ); -VOID +UINTN EFIAPI -MakeUserPageTableTemplate ( - VOID +InitializeUserPageTable ( + IN LOADED_IMAGE_PRIVATE_DATA *Image ); #endif diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 8e7362b216..e012996135 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -248,7 +248,7 @@ DxeMain ( EFI_VECTOR_HANDOFF_INFO *VectorInfo; gRing3Data = NULL; - + // // Setup Stack Guard // @@ -336,8 +336,6 @@ DxeMain ( ProtectUefiImage (&mCurrentImage->Info, UefiImageOriginFv, &ImageContext, mCurrentImage->IsUserImage); - MakeUserPageTableTemplate (); - // // Call constructor for all libraries // diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index ff98785533..818c30f61a 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1108,7 +1108,6 @@ CoreLoadImageCommon ( UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UINT8 ImageOrigin; EFI_FV_FILE_ATTRIBUTES FileAttributes; - VOID *UserPageTable; SecurityStatus = EFI_SUCCESS; @@ -1349,14 +1348,6 @@ CoreLoadImageCommon ( Image->Info.ParentHandle = ParentImageHandle; Image->IsUserImage = (FileAttributes & EFI_FV_FILE_ATTRIB_USER) != 0; - if ((gRing3Data != NULL) && Image->IsUserImage) { - UserPageTable = AllocatePages (EFI_SIZE_TO_PAGES (gUserPageTableTemplateSize)); - CopyMem (UserPageTable, gUserPageTableTemplate, gUserPageTableTemplateSize); - - Image->UserPageTable = (UINTN)UserPageTable; - gUserPageTable = Image->UserPageTable; - } - if (NumberOfPages != NULL) { Image->NumberOfPages = *NumberOfPages; } else { @@ -1453,6 +1444,11 @@ CoreLoadImageCommon ( Status = EFI_SUCCESS; ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, Image->IsUserImage); + if ((gRing3Data != NULL) && Image->IsUserImage) { + Image->UserPageTable = InitializeUserPageTable (Image); + gUserPageTable = Image->UserPageTable; + } + RegisterMemoryProfileImage ( Image->LoadedImageDevicePath, (UefiImageGetSubsystem (&ImageContext) == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ? EFI_FV_FILETYPE_APPLICATION : EFI_FV_FILETYPE_DRIVER), diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index d9ada48738..1066a148bc 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -82,10 +82,6 @@ SetUefiImageMemoryAttributes ( ASSERT (gCpu != NULL); gCpu->SetMemoryAttributes (gCpu, BaseAddress, Length, FinalAttributes); - - if ((Attributes & EFI_MEMORY_USER) != 0) { - gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, BaseAddress, Length, FinalAttributes); - } } /** @@ -291,22 +287,13 @@ UnprotectUefiImage ( } } -/** - Change UEFI image owner: Supervisor / Privileged or User / Unprivileged. - - @param[in] LoadedImage The loaded image protocol - @param[in] LoadedImageDevicePath The loaded image device path protocol - @param[in] IsUser Whether UEFI image record is User Image. -**/ -VOID -ChangeUefiImageRing ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath, - IN BOOLEAN IsUser +UEFI_IMAGE_RECORD * +GetUefiImageRecord ( + IN LOADED_IMAGE_PRIVATE_DATA *Image ) { - UEFI_IMAGE_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; + UEFI_IMAGE_RECORD *ImageRecord; + LIST_ENTRY *ImageRecordLink; for (ImageRecordLink = mProtectedImageRecordList.ForwardLink; ImageRecordLink != &mProtectedImageRecordList; @@ -319,14 +306,12 @@ ChangeUefiImageRing ( UEFI_IMAGE_RECORD_SIGNATURE ); - if (ImageRecord->StartAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) { - ASSERT (gCpu != NULL); - - SetUefiImageProtectionAttributes (ImageRecord, IsUser); - - return; + if (ImageRecord->StartAddress == (EFI_PHYSICAL_ADDRESS)(UINTN)Image->Info.ImageBase) { + return ImageRecord; } } + + return NULL; } /** diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index dd2c9ccea3..dc80c10f4b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -18,6 +18,17 @@ RING3_DATA *gRing3Data; VOID *gRing3Interfaces; UINTN gUartBaseAddress; +UEFI_IMAGE_RECORD *mDxeRing3; +VOID *mUserPageTableTemplate; +UINTN mUserPageTableTemplateSize; + +VOID +EFIAPI +MakeUserPageTableTemplate ( + OUT VOID **UserPageTableTemplate, + OUT UINTN *UserPageTableTemplateSize + ); + VOID EFIAPI InitializeMsr ( @@ -102,11 +113,14 @@ InitializeRing3 ( // // Initialize DxeRing3 with Supervisor privileges. // - ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, FALSE); + mDxeRing3 = GetUefiImageRecord (Image); + ASSERT (mDxeRing3 != NULL); + + SetUefiImageProtectionAttributes (mDxeRing3, FALSE); Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); - ChangeUefiImageRing (&Image->Info, Image->LoadedImageDevicePath, TRUE); + SetUefiImageProtectionAttributes (mDxeRing3, TRUE); gRing3EntryPoint = gRing3Data->EntryPoint; @@ -153,9 +167,6 @@ InitializeRing3 ( gCoreSysCallStackTop = TopOfStack; SetUefiImageMemoryAttributes ((UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); - // - // gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, (UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); - // DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); // @@ -180,5 +191,124 @@ InitializeRing3 ( gRing3Data->SystemTable.NumberOfTableEntries ); + MakeUserPageTableTemplate (&mUserPageTableTemplate, &mUserPageTableTemplateSize); + return Status; } + +UINTN +EFIAPI +InitializeUserPageTable ( + IN LOADED_IMAGE_PRIVATE_DATA *Image + ) +{ + UINTN UserPageTable; + UEFI_IMAGE_RECORD_SEGMENT *ImageRecordSegment; + UINTN SectionAddress; + UINT32 Index; + UEFI_IMAGE_RECORD *UserImageRecord; + + UserPageTable = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (mUserPageTableTemplateSize)); + + CopyMem ((VOID *)UserPageTable, mUserPageTableTemplate, mUserPageTableTemplateSize); + + // + // Map gRing3Data, gRing3Interfaces, gRing3CallStackBase, DxeRing3 + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)gRing3Data, + ALIGN_VALUE (sizeof (RING3_DATA), EFI_PAGE_SIZE), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)gRing3Interfaces, + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)gRing3CallStackBase, + EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + SectionAddress = mDxeRing3->StartAddress; + for (Index = 0; Index < mDxeRing3->NumSegments; Index++) { + ImageRecordSegment = &mDxeRing3->Segments[Index]; + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + SectionAddress, + ImageRecordSegment->Size, + ImageRecordSegment->Attributes | EFI_MEMORY_USER + ); + + SectionAddress += ImageRecordSegment->Size; + } + + // + // Map CoreBootServices + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (EFI_PHYSICAL_ADDRESS)(UINTN)CoreBootServices, + SIZE_4KB, + EFI_MEMORY_RO + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (EFI_PHYSICAL_ADDRESS)(UINTN)&gCorePageTable, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + // + // Map ExceptionHandlerAsm: AsmIdtVectorBegin - AsmGetTemplateAddressMap + // mCorePageTable, gCoreSysCallStackTop + // + // gCpu->SetUserMemoryAttributes (gCpu, (UINTN)PageMap, BaseAddress, SIZE_4KB, EFI_MEMORY_RO); + // + // gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, (UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); + // + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + // + // Map User Image + // + UserImageRecord = GetUefiImageRecord (Image); + ASSERT (UserImageRecord != NULL); + + SectionAddress = UserImageRecord->StartAddress; + for (Index = 0; Index < UserImageRecord->NumSegments; Index++) { + ImageRecordSegment = &UserImageRecord->Segments[Index]; + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + SectionAddress, + ImageRecordSegment->Size, + ImageRecordSegment->Attributes | EFI_MEMORY_USER + ); + + SectionAddress += ImageRecordSegment->Size; + } + + return UserPageTable; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c index 7c0b84783f..fd7f39ef39 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c @@ -10,13 +10,11 @@ #include #include -VOID *gUserPageTableTemplate; -UINTN gUserPageTableTemplateSize; - VOID EFIAPI MakeUserPageTableTemplate ( - VOID + OUT VOID **UserPageTableTemplate, + OUT UINTN *UserPageTableTemplateSize ) { EFI_HOB_GUID_TYPE *GuidHob; @@ -167,42 +165,10 @@ MakeUserPageTableTemplate ( ZeroMem (PageMapLevel5Entry, (512 - IndexOfPml5Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)); } - gUserPageTableTemplate = (VOID *)PageMap; - gUserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (PageTableInfo->TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT); - gUserPageTable = (UINTN)gUserPageTableTemplate; + *UserPageTableTemplate = (VOID *)PageMap; + *UserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (PageTableInfo->TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT); - SetUefiImageMemoryAttributes ((UINT64)PageMap, gUserPageTableTemplateSize, EFI_MEMORY_XP); - // - // Map CoreBootServices - // - gCpu->SetUserMemoryAttributes ( - gCpu, - (UINTN)PageMap, - (EFI_PHYSICAL_ADDRESS)(UINTN)CoreBootServices, - SIZE_4KB, - EFI_MEMORY_RO - ); - - gCpu->SetUserMemoryAttributes ( - gCpu, - (UINTN)PageMap, - (EFI_PHYSICAL_ADDRESS)(UINTN)&gCorePageTable, - SIZE_4KB, - EFI_MEMORY_RO | EFI_MEMORY_XP - ); - // - // Map ExceptionHandlerAsm: AsmIdtVectorBegin - AsmGetTemplateAddressMap - // mCorePageTable, gCoreSysCallStackTop - // - // gCpu->SetUserMemoryAttributes (gCpu, (UINTN)PageMap, BaseAddress, SIZE_4KB, EFI_MEMORY_RO); - - gCpu->SetUserMemoryAttributes ( - gCpu, - (UINTN)PageMap, - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); + SetUefiImageMemoryAttributes ((UINT64)PageMap, *UserPageTableTemplateSize, EFI_MEMORY_XP); } VOID From 1d061f3dc7dc30af1aa6870774e4da1c935167e0 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Wed, 27 Nov 2024 18:03:30 +0300 Subject: [PATCH 275/341] Ring3: Added necessary Core pages to User page table. --- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 3 +- .../Core/Dxe/SysCall/Initialization.c | 61 ++++++++++++++----- .../Core/Dxe/SysCall/SupportedProtocols.c | 23 +------ .../Dxe/SysCall/X64/CoreBootServices.nasm | 11 +++- .../Include/Library/CpuExceptionHandlerLib.h | 14 +++++ .../CpuExceptionHandlerLib/DxeException.c | 28 +++++++++ .../X64/ExceptionHandlerAsm.nasm | 35 ++++++++++- 7 files changed, 134 insertions(+), 41 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 1066a148bc..2a271bf889 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -297,8 +297,7 @@ GetUefiImageRecord ( for (ImageRecordLink = mProtectedImageRecordList.ForwardLink; ImageRecordLink != &mProtectedImageRecordList; - ImageRecordLink = ImageRecordLink->ForwardLink) - { + ImageRecordLink = ImageRecordLink->ForwardLink) { ImageRecord = CR ( ImageRecordLink, UEFI_IMAGE_RECORD, diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index dc80c10f4b..f717ae720d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -18,9 +18,13 @@ RING3_DATA *gRing3Data; VOID *gRing3Interfaces; UINTN gUartBaseAddress; -UEFI_IMAGE_RECORD *mDxeRing3; -VOID *mUserPageTableTemplate; -UINTN mUserPageTableTemplateSize; +UEFI_IMAGE_RECORD *mDxeRing3; +VOID *mUserPageTableTemplate; +UINTN mUserPageTableTemplateSize; +EXCEPTION_ADDRESSES *mExceptionAddresses; + +extern UINTN SysCallBase; +extern UINTN SysCallEnd; VOID EFIAPI @@ -193,6 +197,8 @@ InitializeRing3 ( MakeUserPageTableTemplate (&mUserPageTableTemplate, &mUserPageTableTemplateSize); + mExceptionAddresses = GetExceptionAddresses (); + return Status; } @@ -255,32 +261,59 @@ InitializeUserPageTable ( } // - // Map CoreBootServices + // Map CoreBootServices, gCoreSysCallStackBase, ExceptionHandlers, ExceptionStacks // gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, - (EFI_PHYSICAL_ADDRESS)(UINTN)CoreBootServices, - SIZE_4KB, + (UINTN)&SysCallBase, + (UINTN)&SysCallEnd - (UINTN)&SysCallBase, EFI_MEMORY_RO ); gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, - (EFI_PHYSICAL_ADDRESS)(UINTN)&gCorePageTable, + (UINTN)&gCorePageTable, SIZE_4KB, EFI_MEMORY_RO | EFI_MEMORY_XP ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)gCoreSysCallStackBase, + EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, + EFI_MEMORY_XP + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionStackBase, + mExceptionAddresses->ExceptionStackSize, + EFI_MEMORY_XP + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionHandlerBase, + mExceptionAddresses->ExceptionHandlerSize, + EFI_MEMORY_RO + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionDataBase, + SIZE_4KB, + EFI_MEMORY_XP + ); + // - // Map ExceptionHandlerAsm: AsmIdtVectorBegin - AsmGetTemplateAddressMap - // mCorePageTable, gCoreSysCallStackTop - // - // gCpu->SetUserMemoryAttributes (gCpu, (UINTN)PageMap, BaseAddress, SIZE_4KB, EFI_MEMORY_RO); - // - // gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, (UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); + // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() // - gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 52fb93ff81..4ef2f87fb8 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -62,18 +62,7 @@ GoToRing3 ( VA_END (Marker); ForbidSupervisorAccessToUserMemory (); -#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) - if (Number == 2) { - // - // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() - // - SetUefiImageMemoryAttributes ( - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - } -#elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) +#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) // // Necessary fix for DEBUG printings. // @@ -85,15 +74,7 @@ GoToRing3 ( #endif Status = CallRing3 (Input); -#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) - if (Number == 2) { - SetUefiImageMemoryAttributes ( - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP - ); - } -#elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) +#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) AllowSupervisorAccessToUserMemory (); SetUefiImageMemoryAttributes ( gUartBaseAddress, diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 8a36fd849b..241c35df0a 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -106,6 +106,10 @@ copy: mov gs, ax %endmacro +ALIGN 4096 +global ASM_PFX(SysCallBase) +ASM_PFX(SysCallBase): + ;------------------------------------------------------------------------------ ; EFI_STATUS ; EFIAPI @@ -123,8 +127,6 @@ copy: ; ; (On User Stack) Argument 4, 5, ... ;------------------------------------------------------------------------------ -ALIGN 4096 - global ASM_PFX(CoreBootServices) ASM_PFX(CoreBootServices): mov rax, [ASM_PFX(gCorePageTable)] @@ -233,6 +235,10 @@ ASM_PFX(CallRing3): ; Pass control to user image o64 sysret +ALIGN 4096 +global ASM_PFX(SysCallEnd) +ASM_PFX(SysCallEnd): + ;------------------------------------------------------------------------------ ; VOID ; EFIAPI @@ -267,5 +273,6 @@ global ASM_PFX(gUserPageTable) ASM_PFX(gUserPageTable): resq 1 +ALIGN 4096 ASM_PFX(CoreRsp): resq 1 diff --git a/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h b/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h index 94e9b20ae1..6864d8cb6c 100644 --- a/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h +++ b/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h @@ -13,6 +13,14 @@ #include #include +typedef struct { + UINTN ExceptionStackBase; + UINTN ExceptionStackSize; + UINTN ExceptionHandlerBase; + UINTN ExceptionHandlerSize; + UINTN ExceptionDataBase; +} EXCEPTION_ADDRESSES; + /** Initializes all CPU exceptions entries and provides the default exception handlers. @@ -99,4 +107,10 @@ DumpCpuContext ( IN EFI_SYSTEM_CONTEXT SystemContext ); +EXCEPTION_ADDRESSES * +EFIAPI +GetExceptionAddresses ( + VOID + ); + #endif diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c index 30731a8071..91c2411e4c 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c @@ -30,6 +30,13 @@ UINT8 mBuffer[CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_STACK_SIZE STATIC CONST EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *mDebugImageInfoTable = NULL; +EXCEPTION_ADDRESSES mAddresses; + +extern UINTN ExceptionHandlerBase; +extern UINTN ExceptionHandlerEnd; +extern UINT8 mSwitchCr3Flag; +extern UINTN CorePageTable; + /** Common exception handler. @@ -129,13 +136,17 @@ InitializeSeparateExceptionStacks ( UINTN LocalBufferSize; EFI_STATUS Status; + mAddresses.ExceptionStackSize = CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_STACK_SIZE; + if ((Buffer == NULL) && (BufferSize == NULL)) { SetMem (mBuffer, sizeof (mBuffer), 0); LocalBufferSize = sizeof (mBuffer); Status = ArchSetupExceptionStack (mBuffer, &LocalBufferSize); ASSERT_EFI_ERROR (Status); + mAddresses.ExceptionStackBase = (UINTN)mBuffer; return Status; } else { + mAddresses.ExceptionStackBase = (UINTN)Buffer; return ArchSetupExceptionStack (Buffer, BufferSize); } } @@ -189,3 +200,20 @@ GetImageInfoByIp ( return FALSE; } + +EXCEPTION_ADDRESSES * +EFIAPI +GetExceptionAddresses ( + VOID + ) +{ + mSwitchCr3Flag = 1; + + mAddresses.ExceptionHandlerBase = (UINTN)&ExceptionHandlerBase; + mAddresses.ExceptionHandlerSize = (UINTN)&ExceptionHandlerEnd - mAddresses.ExceptionHandlerBase; + mAddresses.ExceptionDataBase = (UINTN)&CorePageTable; + + CorePageTable = AsmReadCr3 (); + + return &mAddresses; +} diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm index 81d86fb533..49f6267982 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm @@ -53,11 +53,27 @@ extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag extern ASM_PFX(CommonExceptionHandler) SECTION .data +ALIGN 4096 + +global ASM_PFX(CorePageTable) +ASM_PFX(CorePageTable): + resq 1 + +global ASM_PFX(UserPageTable) +ASM_PFX(UserPageTable): + resq 1 + +ALIGN 4096 +global ASM_PFX(mSwitchCr3Flag) +ASM_PFX(mSwitchCr3Flag): + db 0x0 DEFAULT REL SECTION .text -ALIGN 8 +ALIGN 4096 +global ASM_PFX(ExceptionHandlerBase) +ASM_PFX(ExceptionHandlerBase): ; Generate NUM_VECTORS IDT vectors. AsmIdtVectorBegin: @@ -121,6 +137,14 @@ HookAfterStubHeaderEnd: global ASM_PFX(CommonInterruptEntry) ASM_PFX(CommonInterruptEntry): cli + cmp byte [ASM_PFX(mSwitchCr3Flag)], 0 + jz NoCr3Switch + mov rax, cr3 + mov [ASM_PFX(UserPageTable)], rax + mov rax, [ASM_PFX(CorePageTable)] + mov cr3, rax + +NoCr3Switch: pop rax ; ; All interrupt handlers are invoked through interrupt gates, so @@ -436,8 +460,8 @@ CetDone: push rcx mov rcx, ds and rcx, 3 - pop rcx jnz ReturnToRing3 + pop rcx mov rsp, rbp pop rbp @@ -466,11 +490,18 @@ DoReturn: DoIret: iretq ReturnToRing3: + mov rcx, [ASM_PFX(UserPageTable)] + mov cr3, rcx + pop rcx mov rsp, rbp pop rbp add rsp, 16 iretq +ALIGN 4096 +global ASM_PFX(ExceptionHandlerEnd) +ASM_PFX(ExceptionHandlerEnd): + ;------------------------------------------------------------------------------------- ; GetTemplateAddressMap (&AddressMap); ;------------------------------------------------------------------------------------- From 6291fd8c861f17139f6e89639a3d91768bc89353 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 29 Nov 2024 11:30:49 +0300 Subject: [PATCH 276/341] Core/Dxe: Fixed memory type in Ring3AllocatePages(), and code alignment. --- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 2 +- .../Core/Dxe/SysCall/Initialization.c | 144 +++++++++--------- 2 files changed, 73 insertions(+), 73 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index f21bf6c1aa..cc62ba4f61 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -128,7 +128,7 @@ Ring3AllocatePages ( Status = SysCall ( SysCallAllocatePages, Type, - MemoryType, + EfiRing3MemoryType, NumberOfPages, Memory ); diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index f717ae720d..dd4b3a16d8 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -222,40 +222,40 @@ InitializeUserPageTable ( // Map gRing3Data, gRing3Interfaces, gRing3CallStackBase, DxeRing3 // gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - (UINTN)gRing3Data, - ALIGN_VALUE (sizeof (RING3_DATA), EFI_PAGE_SIZE), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); + gCpu, + UserPageTable, + (UINTN)gRing3Data, + ALIGN_VALUE (sizeof (RING3_DATA), EFI_PAGE_SIZE), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - (UINTN)gRing3Interfaces, - EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); + gCpu, + UserPageTable, + (UINTN)gRing3Interfaces, + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - (UINTN)gRing3CallStackBase, - EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); + gCpu, + UserPageTable, + (UINTN)gRing3CallStackBase, + EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); SectionAddress = mDxeRing3->StartAddress; for (Index = 0; Index < mDxeRing3->NumSegments; Index++) { ImageRecordSegment = &mDxeRing3->Segments[Index]; gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - SectionAddress, - ImageRecordSegment->Size, - ImageRecordSegment->Attributes | EFI_MEMORY_USER - ); + gCpu, + UserPageTable, + SectionAddress, + ImageRecordSegment->Size, + ImageRecordSegment->Attributes | EFI_MEMORY_USER + ); SectionAddress += ImageRecordSegment->Size; } @@ -264,63 +264,63 @@ InitializeUserPageTable ( // Map CoreBootServices, gCoreSysCallStackBase, ExceptionHandlers, ExceptionStacks // gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - (UINTN)&SysCallBase, - (UINTN)&SysCallEnd - (UINTN)&SysCallBase, - EFI_MEMORY_RO - ); + gCpu, + UserPageTable, + (UINTN)&SysCallBase, + (UINTN)&SysCallEnd - (UINTN)&SysCallBase, + EFI_MEMORY_RO + ); gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - (UINTN)&gCorePageTable, - SIZE_4KB, - EFI_MEMORY_RO | EFI_MEMORY_XP - ); + gCpu, + UserPageTable, + (UINTN)&gCorePageTable, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - (UINTN)gCoreSysCallStackBase, - EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, - EFI_MEMORY_XP - ); + gCpu, + UserPageTable, + (UINTN)gCoreSysCallStackBase, + EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, + EFI_MEMORY_XP + ); gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - mExceptionAddresses->ExceptionStackBase, - mExceptionAddresses->ExceptionStackSize, - EFI_MEMORY_XP - ); + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionStackBase, + mExceptionAddresses->ExceptionStackSize, + EFI_MEMORY_XP + ); gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - mExceptionAddresses->ExceptionHandlerBase, - mExceptionAddresses->ExceptionHandlerSize, - EFI_MEMORY_RO - ); + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionHandlerBase, + mExceptionAddresses->ExceptionHandlerSize, + EFI_MEMORY_RO + ); gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - mExceptionAddresses->ExceptionDataBase, - SIZE_4KB, - EFI_MEMORY_XP - ); + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionDataBase, + SIZE_4KB, + EFI_MEMORY_XP + ); // // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() // gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); + gCpu, + UserPageTable, + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); // // Map User Image @@ -333,12 +333,12 @@ InitializeUserPageTable ( ImageRecordSegment = &UserImageRecord->Segments[Index]; gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - SectionAddress, - ImageRecordSegment->Size, - ImageRecordSegment->Attributes | EFI_MEMORY_USER - ); + gCpu, + UserPageTable, + SectionAddress, + ImageRecordSegment->Size, + ImageRecordSegment->Attributes | EFI_MEMORY_USER + ); SectionAddress += ImageRecordSegment->Size; } From 355b1b5e8ffd319148119e630900a2e7f829b52d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 29 Nov 2024 11:35:26 +0300 Subject: [PATCH 277/341] SysCall: Disabled global pages, set User page table attibutes in paging syscalls. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 16 ++++++++++++++++ .../Core/Dxe/SysCall/X64/InitializeMsr.c | 8 ++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index aafdf60412..fbd32c8926 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -605,6 +605,14 @@ CallBootService ( *(EFI_PHYSICAL_ADDRESS *)UserRsp->Arguments[4] = (EFI_PHYSICAL_ADDRESS)Argument4; ForbidSupervisorAccessToUserMemory (); + gCpu->SetUserMemoryAttributes ( + gCpu, + gUserPageTable, + Argument4, + EFI_PAGES_TO_SIZE (CoreRbp->Argument3), + EFI_MEMORY_USER + ); + return Status; case SysCallFreePages: @@ -617,6 +625,14 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + CoreRbp->Argument1 * EFI_PAGE_SIZE - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->SetUserMemoryAttributes ( + gCpu, + gUserPageTable, + CoreRbp->Argument2, + EFI_PAGES_TO_SIZE (CoreRbp->Argument1), + EFI_MEMORY_RP + ); + return gBS->FreePages ( *(EFI_PHYSICAL_ADDRESS *)&CoreRbp->Argument2, CoreRbp->Argument1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c index fd7f39ef39..af451fe547 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c @@ -188,8 +188,12 @@ InitializeMsr ( Ebx = 0; Edx = 0; - // The Intel-64 and IA-32 architectures also allow for global pages when the PGE flag (bit 7) is 1 in CR4. - // PGE must be zero. + // + // Forbid global pages. + // + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.PGE = 0; + AsmWriteCr4 (Cr4.UintN); // // Forbid supervisor-mode accesses to any user-mode pages. From ca6eb09e5843367c1a6980c0da9321a54608718d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 29 Nov 2024 14:33:17 +0300 Subject: [PATCH 278/341] Ring3: Added SetExceptionAddresses(), aligned exceptions' stacks. --- .../Include/Library/CpuExceptionHandlerLib.h | 7 +++++ UefiCpuPkg/Library/CpuArchLib/CpuMp.c | 8 +++++- .../CpuExceptionHandlerLib/DxeException.c | 26 ++++++++++++------- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h b/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h index 6864d8cb6c..36fe66ed32 100644 --- a/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h +++ b/MdeModulePkg/Include/Library/CpuExceptionHandlerLib.h @@ -113,4 +113,11 @@ GetExceptionAddresses ( VOID ); +VOID +EFIAPI +SetExceptionAddresses ( + IN VOID *Buffer, + IN UINTN BufferSize + ); + #endif diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuMp.c b/UefiCpuPkg/Library/CpuArchLib/CpuMp.c index e85dce0d46..d4b0dc4e55 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuMp.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuMp.c @@ -623,6 +623,7 @@ InitializeExceptionStackSwitchHandlers ( EXCEPTION_STACK_SWITCH_CONTEXT *SwitchStackData; UINTN Index; EFI_STATUS Status; + MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr; Status = MpInitLibWhoAmI (&Index); @@ -631,7 +632,8 @@ InitializeExceptionStackSwitchHandlers ( return; } - SwitchStackData = (EXCEPTION_STACK_SWITCH_CONTEXT *)Buffer; + SwitchStackData = (EXCEPTION_STACK_SWITCH_CONTEXT *)Buffer; + ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); // // This may be called twice for each Cpu. Only run InitializeSeparateExceptionStacks @@ -639,6 +641,9 @@ InitializeExceptionStackSwitchHandlers ( // if ((SwitchStackData[Index].Status == EFI_NOT_STARTED) || (SwitchStackData[Index].Status == EFI_BUFFER_TOO_SMALL)) { SwitchStackData[Index].Status = InitializeSeparateExceptionStacks (SwitchStackData[Index].Buffer, &SwitchStackData[Index].BufferSize); + if ((ApicBaseMsr.Bits.BSP != 0) && (SwitchStackData[Index].Status == EFI_SUCCESS)) { + SetExceptionAddresses (SwitchStackData[Index].Buffer, SwitchStackData[Index].BufferSize); + } } } @@ -687,6 +692,7 @@ InitializeMpExceptionStackSwitchHandlers ( for (Index = 0; Index < mNumberOfProcessors; ++Index) { if (SwitchStackData[Index].Status == EFI_BUFFER_TOO_SMALL) { ASSERT (SwitchStackData[Index].BufferSize != 0); + SwitchStackData[Index].BufferSize = ALIGN_VALUE (SwitchStackData[Index].BufferSize, EFI_PAGE_SIZE); BufferSize += SwitchStackData[Index].BufferSize; } else { ASSERT (SwitchStackData[Index].Status == EFI_SUCCESS); diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c index 91c2411e4c..9429df0355 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c @@ -136,17 +136,13 @@ InitializeSeparateExceptionStacks ( UINTN LocalBufferSize; EFI_STATUS Status; - mAddresses.ExceptionStackSize = CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_STACK_SIZE; - if ((Buffer == NULL) && (BufferSize == NULL)) { SetMem (mBuffer, sizeof (mBuffer), 0); LocalBufferSize = sizeof (mBuffer); Status = ArchSetupExceptionStack (mBuffer, &LocalBufferSize); ASSERT_EFI_ERROR (Status); - mAddresses.ExceptionStackBase = (UINTN)mBuffer; return Status; } else { - mAddresses.ExceptionStackBase = (UINTN)Buffer; return ArchSetupExceptionStack (Buffer, BufferSize); } } @@ -209,11 +205,21 @@ GetExceptionAddresses ( { mSwitchCr3Flag = 1; - mAddresses.ExceptionHandlerBase = (UINTN)&ExceptionHandlerBase; - mAddresses.ExceptionHandlerSize = (UINTN)&ExceptionHandlerEnd - mAddresses.ExceptionHandlerBase; - mAddresses.ExceptionDataBase = (UINTN)&CorePageTable; - - CorePageTable = AsmReadCr3 (); - return &mAddresses; } + +VOID +EFIAPI +SetExceptionAddresses ( + IN VOID *Buffer, + IN UINTN BufferSize + ) +{ + mAddresses.ExceptionStackBase = (UINTN)Buffer; + mAddresses.ExceptionStackSize = BufferSize; + mAddresses.ExceptionHandlerBase = (UINTN)&ExceptionHandlerBase; + mAddresses.ExceptionHandlerSize = (UINTN)&ExceptionHandlerEnd - mAddresses.ExceptionHandlerBase; + mAddresses.ExceptionDataBase = (UINTN)&CorePageTable; + + CorePageTable = AsmReadCr3 (); +} From 0316d4db98afe0412a36d3daa37a2af72eed5c28 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 29 Nov 2024 19:40:26 +0300 Subject: [PATCH 279/341] Ring3: Added Idt to User page table. --- MdeModulePkg/Core/Dxe/SysCall/Initialization.c | 17 +++++++++++++++-- UefiCpuPkg/Library/CpuArchLib/CpuDxe.c | 3 ++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index dd4b3a16d8..d2c18cb3e0 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -213,6 +213,7 @@ InitializeUserPageTable ( UINTN SectionAddress; UINT32 Index; UEFI_IMAGE_RECORD *UserImageRecord; + IA32_DESCRIPTOR IdtDescriptor; UserPageTable = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (mUserPageTableTemplateSize)); @@ -261,7 +262,7 @@ InitializeUserPageTable ( } // - // Map CoreBootServices, gCoreSysCallStackBase, ExceptionHandlers, ExceptionStacks + // Map CoreBootServices, gCoreSysCallStackBase // gCpu->SetUserMemoryAttributes ( gCpu, @@ -286,7 +287,10 @@ InitializeUserPageTable ( EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, EFI_MEMORY_XP ); - + + // + // Map ExceptionHandlers, ExceptionStacks, Idt + // gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, @@ -311,6 +315,15 @@ InitializeUserPageTable ( EFI_MEMORY_XP ); + AsmReadIdtr (&IdtDescriptor); + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + IdtDescriptor.Base, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + // // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() // diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c index a058b0cec2..8fa87bf3d8 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c @@ -728,8 +728,9 @@ InitInterruptDescriptorTable ( // // Increase Interrupt Descriptor Table and Copy the old IDT table in // - IdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM); + IdtTable = AllocatePages (1); ASSERT (IdtTable != NULL); + SetMem (IdtTable, EFI_PAGE_SIZE, 0); CopyMem (IdtTable, (VOID *)IdtDescriptor.Base, sizeof (IA32_IDT_GATE_DESCRIPTOR) * IdtEntryCount); // From b52ebae6f5c7a45c277f636fea33613096a001c5 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 29 Nov 2024 19:42:10 +0300 Subject: [PATCH 280/341] Ring3: Set 1G User pages as not present by default, fixed padding. --- MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c | 2 +- .../CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c index af451fe547..c3bcc33919 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c @@ -111,7 +111,7 @@ MakeUserPageTableTemplate ( // PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | PageTableInfo->AddressEncMask; PageDirectory1GEntry->Bits.ReadWrite = 1; - PageDirectory1GEntry->Bits.Present = 1; + PageDirectory1GEntry->Bits.Present = 0; PageDirectory1GEntry->Bits.MustBe1 = 1; } } else { diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm index 49f6267982..31e1a70780 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm @@ -63,11 +63,14 @@ global ASM_PFX(UserPageTable) ASM_PFX(UserPageTable): resq 1 -ALIGN 4096 global ASM_PFX(mSwitchCr3Flag) ASM_PFX(mSwitchCr3Flag): db 0x0 +ALIGN 4096 +Padding: + db 0x0 + DEFAULT REL SECTION .text From cc4cbb642687f575c0f58dc715ff4af7b53898a5 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 2 Dec 2024 12:04:46 +0300 Subject: [PATCH 281/341] Ring3: Added support for User page table to AllocatePages(), FreePages(). --- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 3 ++- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 17 +++++++++++++++++ UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index e012996135..a2e74c24a8 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -247,7 +247,8 @@ DxeMain ( EFI_VECTOR_HANDOFF_INFO *VectorInfoList; EFI_VECTOR_HANDOFF_INFO *VectorInfo; - gRing3Data = NULL; + gRing3Data = NULL; + gUserPageTable = 0; // // Setup Stack Guard diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 2a271bf889..eaa10d62a1 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -909,6 +909,7 @@ ApplyMemoryProtectionPolicy ( { UINT64 OldAttributes; UINT64 NewAttributes; + UINT64 CurrentAttributes; // // The policy configured in PcdDxeNxMemoryProtectionPolicy @@ -964,11 +965,27 @@ ApplyMemoryProtectionPolicy ( NewAttributes = GetPermissionAttributeForMemoryType (NewType); if (OldType != EfiMaxMemoryType) { + // + // AllocatePages + // OldAttributes = GetPermissionAttributeForMemoryType (OldType); if (OldAttributes == NewAttributes) { // policy is the same between OldType and NewType return EFI_SUCCESS; } + + if ((gUserPageTable != 0) && (NewType == EfiRing3MemoryType)) { + gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, Memory, Length, NewAttributes); + } + } else { + // + // FreePages + // + gCpu->GetMemoryAttributes (gCpu, Memory, &CurrentAttributes); + + if ((gUserPageTable != 0) && ((CurrentAttributes & EFI_MEMORY_USER) != 0)) { + gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, Memory, Length, EFI_MEMORY_RP); + } } return gCpu->SetMemoryAttributes (gCpu, Memory, Length, NewAttributes); diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c index 862221d7e1..8e235e03d4 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c @@ -421,6 +421,7 @@ CpuGetMemoryAttributes ( PageEntry = GetPageTableEntry (&PagingContext, Address, &PageAttribute); if (PageEntry == NULL) { + *Attributes = 0; return EFI_NOT_FOUND; } From 90a7895f51ca9579914d93eeb5485761c096c97c Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 2 Dec 2024 12:12:32 +0300 Subject: [PATCH 282/341] SysCall: Turned on interrupts in User. --- MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 241c35df0a..6d079ee860 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -199,9 +199,9 @@ o64 sysret ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): - cli pushfq pop r11 + cli ; Save nonvolatile registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15. push rbx push rbp From c025da12163279769b2da25c24fae650012105c3 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 2 Dec 2024 12:48:18 +0300 Subject: [PATCH 283/341] Ring3: Removed gEfiHobPageTableInfoGuid. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 8 +- .../Core/Dxe/SysCall/X64/InitializeMsr.c | 183 ++++++++++++++---- MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 1 - .../Core/DxeIplPeim/X64/VirtualMemory.c | 11 -- MdePkg/Include/Guid/MemoryAllocationHob.h | 4 - MdePkg/Include/Library/MemoryAllocationLib.h | 10 - MdePkg/MdePkg.dec | 3 - 7 files changed, 155 insertions(+), 65 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index b93874a49e..8c6aedf8f1 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -151,7 +151,6 @@ gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## SysCall gEarlyPL011BaseAddressGuid ## CONSUMES - gEfiHobPageTableInfoGuid ## CONSUMES ## HOB [Ppis] gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB @@ -224,9 +223,14 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES + +[Pcd.IA32,Pcd.X64] + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES # [Hob] # RESOURCE_DESCRIPTOR ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c index c3bcc33919..51f89dcde9 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c @@ -8,6 +8,7 @@ #include "DxeMain.h" #include +#include #include VOID @@ -17,30 +18,144 @@ MakeUserPageTableTemplate ( OUT UINTN *UserPageTableTemplateSize ) { - EFI_HOB_GUID_TYPE *GuidHob; - EFI_PAGE_TABLE_INFO *PageTableInfo; - UINTN BigPageAddress; - EFI_PHYSICAL_ADDRESS PageAddress; - UINTN IndexOfPml5Entries; - UINTN IndexOfPml4Entries; - UINTN IndexOfPdpEntries; - UINTN IndexOfPageDirectoryEntries; - PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel5Entry; - PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry; - PAGE_MAP_AND_DIRECTORY_POINTER *PageMap; - PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry; - PAGE_TABLE_ENTRY *PageDirectoryEntry; - PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; - - GuidHob = GetFirstGuidHob (&gEfiHobPageTableInfoGuid); - if (GuidHob == NULL) { - DEBUG ((DEBUG_ERROR, "Core: Could not retrieve PageTableInfo HOB.\n")); - CpuDeadLoop (); + UINT32 RegEax; + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX EcxFlags; + UINT32 RegEdx; + UINT8 PhysicalAddressBits; + UINT32 NumberOfPml5EntriesNeeded; + UINT32 NumberOfPml4EntriesNeeded; + UINT32 NumberOfPdpEntriesNeeded; + VOID *Hob; + BOOLEAN Page5LevelEnabled; + BOOLEAN Page1GSupport; + UINT64 AddressEncMask; + IA32_CR4 Cr4; + UINTN TotalPagesNum; + UINTN BigPageAddress; + EFI_PHYSICAL_ADDRESS PageAddress; + UINTN IndexOfPml5Entries; + UINTN IndexOfPml4Entries; + UINTN IndexOfPdpEntries; + UINTN IndexOfPageDirectoryEntries; + PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel5Entry; + PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry; + PAGE_MAP_AND_DIRECTORY_POINTER *PageMap; + PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry; + PAGE_TABLE_ENTRY *PageDirectoryEntry; + PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; + + // + // Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings + // + PageMapLevel5Entry = NULL; + + // + // Make sure AddressEncMask is contained to smallest supported address field + // + AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; + + Page1GSupport = FALSE; + if (PcdGetBool (PcdUse1GPageTable)) { + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x80000001) { + AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT26) != 0) { + Page1GSupport = TRUE; + } + } + } + + // + // Get physical address bits supported. + // + Hob = GetFirstHob (EFI_HOB_TYPE_CPU); + if (Hob != NULL) { + PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace; + } else { + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x80000008) { + AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); + PhysicalAddressBits = (UINT8)RegEax; + } else { + PhysicalAddressBits = 36; + } + } + + if (sizeof (UINTN) == sizeof (UINT64)) { + // + // If cpu has already run in 64bit long mode PEI, Page table Level in DXE must align with previous level. + // + Cr4.UintN = AsmReadCr4 (); + Page5LevelEnabled = (Cr4.Bits.LA57 != 0); + if (Page5LevelEnabled) { + ASSERT (PcdGetBool (PcdUse5LevelPageTable)); + } + } else { + // + // If cpu runs in 32bit protected mode PEI, Page table Level in DXE is decided by PCD and feature capability. + // + Page5LevelEnabled = FALSE; + if (PcdGetBool (PcdUse5LevelPageTable)) { + AsmCpuidEx ( + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, + NULL, + NULL, + &EcxFlags.Uint32, + NULL + ); + if (EcxFlags.Bits.FiveLevelPage != 0) { + Page5LevelEnabled = TRUE; + } + } + } + + // + // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses + // when 5-Level Paging is disabled, + // due to either unsupported by HW, or disabled by PCD. + // + ASSERT (PhysicalAddressBits <= 52); + if (!Page5LevelEnabled && (PhysicalAddressBits > 48)) { + PhysicalAddressBits = 48; + } + + // + // Calculate the table entries needed. + // + NumberOfPml5EntriesNeeded = 1; + if (PhysicalAddressBits > 48) { + NumberOfPml5EntriesNeeded = (UINT32)LShiftU64 (1, PhysicalAddressBits - 48); + PhysicalAddressBits = 48; } - PageTableInfo = (EFI_PAGE_TABLE_INFO *)(GET_GUID_HOB_DATA (GuidHob)); + NumberOfPml4EntriesNeeded = 1; + if (PhysicalAddressBits > 39) { + NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, PhysicalAddressBits - 39); + PhysicalAddressBits = 39; + } + + NumberOfPdpEntriesNeeded = 1; + ASSERT (PhysicalAddressBits > 30); + NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, PhysicalAddressBits - 30); + + // + // Pre-allocate big pages to avoid later allocations. + // + if (!Page1GSupport) { + TotalPagesNum = ((NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1) * NumberOfPml5EntriesNeeded + 1; + } else { + TotalPagesNum = (NumberOfPml4EntriesNeeded + 1) * NumberOfPml5EntriesNeeded + 1; + } + + // + // Substract the one page occupied by PML5 entries if 5-Level Paging is disabled. + // + if (!Page5LevelEnabled) { + TotalPagesNum--; + } - BigPageAddress = (UINTN)AllocateAlignedPages (PageTableInfo->TotalPagesNum, PAGE_TABLE_POOL_ALIGNMENT); + BigPageAddress = (UINTN)AllocateAlignedPages (TotalPagesNum, PAGE_TABLE_POOL_ALIGNMENT); if (BigPageAddress == 0) { DEBUG ((DEBUG_ERROR, "Core: Could not allocate buffer for User page table.\n")); CpuDeadLoop (); @@ -50,7 +165,7 @@ MakeUserPageTableTemplate ( // By architecture only one PageMapLevel4 exists - so lets allocate storage for it. // PageMap = (VOID *)BigPageAddress; - if (PageTableInfo->Page5LevelEnabled) { + if (Page5LevelEnabled) { // // By architecture only one PageMapLevel5 exists - so lets allocate storage for it. // @@ -61,7 +176,7 @@ MakeUserPageTableTemplate ( PageAddress = 0; for ( IndexOfPml5Entries = 0 - ; IndexOfPml5Entries < PageTableInfo->NumberOfPml5EntriesNeeded + ; IndexOfPml5Entries < NumberOfPml5EntriesNeeded ; IndexOfPml5Entries++) { // @@ -72,11 +187,11 @@ MakeUserPageTableTemplate ( PageMapLevel4Entry = (VOID *)BigPageAddress; BigPageAddress += SIZE_4KB; - if (PageTableInfo->Page5LevelEnabled) { + if (Page5LevelEnabled) { // // Make a PML5 Entry // - PageMapLevel5Entry->Uint64 = (UINT64)(UINTN)PageMapLevel4Entry | PageTableInfo->AddressEncMask; + PageMapLevel5Entry->Uint64 = (UINT64)(UINTN)PageMapLevel4Entry | AddressEncMask; PageMapLevel5Entry->Bits.ReadWrite = 1; PageMapLevel5Entry->Bits.UserSupervisor = 1; PageMapLevel5Entry->Bits.Present = 1; @@ -84,7 +199,7 @@ MakeUserPageTableTemplate ( } for ( IndexOfPml4Entries = 0 - ; IndexOfPml4Entries < (PageTableInfo->NumberOfPml5EntriesNeeded == 1 ? PageTableInfo->NumberOfPml4EntriesNeeded : 512) + ; IndexOfPml4Entries < (NumberOfPml5EntriesNeeded == 1 ? NumberOfPml4EntriesNeeded : 512) ; IndexOfPml4Entries++, PageMapLevel4Entry++) { // @@ -97,26 +212,26 @@ MakeUserPageTableTemplate ( // // Make a PML4 Entry // - PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | PageTableInfo->AddressEncMask; + PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | AddressEncMask; PageMapLevel4Entry->Bits.ReadWrite = 1; PageMapLevel4Entry->Bits.UserSupervisor = 1; PageMapLevel4Entry->Bits.Present = 1; - if (PageTableInfo->Page1GSupport) { + if (Page1GSupport) { PageDirectory1GEntry = (VOID *)PageDirectoryPointerEntry; for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) { // // Fill in the Page Directory entries // - PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | PageTableInfo->AddressEncMask; + PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | AddressEncMask; PageDirectory1GEntry->Bits.ReadWrite = 1; PageDirectory1GEntry->Bits.Present = 0; PageDirectory1GEntry->Bits.MustBe1 = 1; } } else { for ( IndexOfPdpEntries = 0 - ; IndexOfPdpEntries < (PageTableInfo->NumberOfPml4EntriesNeeded == 1 ? PageTableInfo->NumberOfPdpEntriesNeeded : 512) + ; IndexOfPdpEntries < (NumberOfPml4EntriesNeeded == 1 ? NumberOfPdpEntriesNeeded : 512) ; IndexOfPdpEntries++, PageDirectoryPointerEntry++) { // @@ -129,7 +244,7 @@ MakeUserPageTableTemplate ( // // Fill in a Page Directory Pointer Entries // - PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | PageTableInfo->AddressEncMask; + PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask; PageDirectoryPointerEntry->Bits.ReadWrite = 1; PageDirectoryPointerEntry->Bits.UserSupervisor = 1; PageDirectoryPointerEntry->Bits.Present = 1; @@ -138,7 +253,7 @@ MakeUserPageTableTemplate ( // // Fill in the Page Directory entries // - PageDirectoryEntry->Uint64 = (UINT64)PageAddress | PageTableInfo->AddressEncMask; + PageDirectoryEntry->Uint64 = (UINT64)PageAddress | AddressEncMask; PageDirectoryEntry->Bits.ReadWrite = 1; PageDirectoryEntry->Bits.Present = 0; PageDirectoryEntry->Bits.MustBe1 = 1; @@ -158,7 +273,7 @@ MakeUserPageTableTemplate ( ZeroMem (PageMapLevel4Entry, (512 - IndexOfPml4Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)); } - if (PageTableInfo->Page5LevelEnabled) { + if (Page5LevelEnabled) { // // For the PML5 entries we are not using fill in a null entry. // @@ -166,7 +281,7 @@ MakeUserPageTableTemplate ( } *UserPageTableTemplate = (VOID *)PageMap; - *UserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (PageTableInfo->TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT); + *UserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT); SetUefiImageMemoryAttributes ((UINT64)PageMap, *UserPageTableTemplateSize, EFI_MEMORY_XP); } diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf index 8a4d0eeab4..e231e7bd6f 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -90,7 +90,6 @@ ## SOMETIMES_PRODUCES ## HOB gEfiMemoryTypeInformationGuid gUefiImageLoaderImageContextGuid - gEfiHobPageTableInfoGuid [FeaturePcd.IA32] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c index 04aaadfec0..7a40a0f8fd 100644 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c @@ -708,7 +708,6 @@ CreateIdentityMappingPageTables ( PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; UINT64 AddressEncMask; IA32_CR4 Cr4; - EFI_PAGE_TABLE_INFO PageTableInfo; // // Set PageMapLevel5Entry to suppress incorrect compiler/analyzer warnings @@ -832,16 +831,6 @@ CreateIdentityMappingPageTables ( (UINT64)TotalPagesNum )); - PageTableInfo.NumberOfPml5EntriesNeeded = NumberOfPml5EntriesNeeded; - PageTableInfo.NumberOfPml4EntriesNeeded = NumberOfPml4EntriesNeeded; - PageTableInfo.NumberOfPdpEntriesNeeded = NumberOfPdpEntriesNeeded; - PageTableInfo.TotalPagesNum = TotalPagesNum; - PageTableInfo.Page5LevelEnabled = Page5LevelEnabled; - PageTableInfo.Page1GSupport = Page1GSupport; - PageTableInfo.AddressEncMask = AddressEncMask; - - BuildGuidDataHob (&gEfiHobPageTableInfoGuid, &PageTableInfo, sizeof (EFI_PAGE_TABLE_INFO)); - BigPageAddress = (UINTN)AllocatePageTableMemory (TotalPagesNum); ASSERT (BigPageAddress != 0); diff --git a/MdePkg/Include/Guid/MemoryAllocationHob.h b/MdePkg/Include/Guid/MemoryAllocationHob.h index 9ebbd13992..e4c57bf1ac 100644 --- a/MdePkg/Include/Guid/MemoryAllocationHob.h +++ b/MdePkg/Include/Guid/MemoryAllocationHob.h @@ -21,12 +21,8 @@ #define EFI_HOB_MEMORY_ALLOC_MODULE_GUID \ {0xf8e21975, 0x899, 0x4f58, {0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6, 0xd7, 0x7a} } -#define EFI_HOB_PAGE_TABLE_INFO_GUID \ - {0xac992fe9, 0xb0cc, 0x45df, {0xae, 0xcf, 0x51, 0x5a, 0xd2, 0xc4, 0xe8, 0xb3} } - extern EFI_GUID gEfiHobMemoryAllocBspStoreGuid; extern EFI_GUID gEfiHobMemoryAllocStackGuid; extern EFI_GUID gEfiHobMemoryAllocModuleGuid; -extern EFI_GUID gEfiHobPageTableInfoGuid; #endif diff --git a/MdePkg/Include/Library/MemoryAllocationLib.h b/MdePkg/Include/Library/MemoryAllocationLib.h index da7ac36b2f..59d4b29c44 100644 --- a/MdePkg/Include/Library/MemoryAllocationLib.h +++ b/MdePkg/Include/Library/MemoryAllocationLib.h @@ -14,16 +14,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #ifndef __MEMORY_ALLOCATION_LIB_H__ #define __MEMORY_ALLOCATION_LIB_H__ -typedef struct { - UINT32 NumberOfPml5EntriesNeeded; - UINT32 NumberOfPml4EntriesNeeded; - UINT32 NumberOfPdpEntriesNeeded; - UINTN TotalPagesNum; - BOOLEAN Page5LevelEnabled; - BOOLEAN Page1GSupport; - UINT64 AddressEncMask; -} EFI_PAGE_TABLE_INFO; - /** Allocates one or more 4KB pages of type EfiBootServicesData. diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 271c29198c..ed3b85cf3e 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -813,9 +813,6 @@ ## Include/Guid/MemoryAllocationHob.h gEfiHobMemoryAllocBspStoreGuid = { 0x564B33CD, 0xC92A, 0x4593, { 0x90, 0xBF, 0x24, 0x73, 0xE4, 0x3C, 0x63, 0x22 }} - ## Include/Guid/MemoryAllocationHob.h - gEfiHobPageTableInfoGuid = { 0xAC992FE9, 0xB0CC, 0x45DF, { 0xAE, 0xCF, 0x51, 0x5A, 0xD2, 0xC4, 0xE8, 0xB3 }} - ## Include/Guid/EventLegacyBios.h gEfiEventLegacyBootGuid = { 0x2A571201, 0x4966, 0x47F6, { 0x8B, 0x86, 0xF3, 0x1E, 0x41, 0xF3, 0x2F, 0x10 }} From 89ec64d133391c9db853c61ebdfe9fbe040304be Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 2 Dec 2024 12:52:48 +0300 Subject: [PATCH 284/341] SysCall: Refactored InitializeMsr.c file name. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 8 ++++---- .../AARCH64/{InitializeMsr.c => InitializeAARCH64.c} | 0 .../Dxe/SysCall/ARM/{InitializeMsr.c => InitializeARM.c} | 0 .../SysCall/IA32/{InitializeMsr.c => InitializeIA32.c} | 0 .../Dxe/SysCall/X64/{InitializeMsr.c => InitializeX64.c} | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename MdeModulePkg/Core/Dxe/SysCall/AARCH64/{InitializeMsr.c => InitializeAARCH64.c} (100%) rename MdeModulePkg/Core/Dxe/SysCall/ARM/{InitializeMsr.c => InitializeARM.c} (100%) rename MdeModulePkg/Core/Dxe/SysCall/IA32/{InitializeMsr.c => InitializeIA32.c} (100%) rename MdeModulePkg/Core/Dxe/SysCall/X64/{InitializeMsr.c => InitializeX64.c} (100%) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 8c6aedf8f1..eda00cd6b1 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -71,19 +71,19 @@ SysCall/SupportedProtocols.c [Sources.IA32] - SysCall/IA32/InitializeMsr.c + SysCall/IA32/InitializeIA32.c SysCall/IA32/CoreBootServices.nasm [Sources.X64] - SysCall/X64/InitializeMsr.c + SysCall/X64/InitializeX64.c SysCall/X64/CoreBootServices.nasm [Sources.ARM] - SysCall/ARM/InitializeMsr.c + SysCall/ARM/InitializeARM.c SysCall/ARM/CoreBootServices.S [Sources.AARCH64] - SysCall/AARCH64/InitializeMsr.c + SysCall/AARCH64/InitializeAARCH64.c SysCall/AARCH64/CoreBootServices.S [Packages] diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c similarity index 100% rename from MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c rename to MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c similarity index 100% rename from MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeMsr.c rename to MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c similarity index 100% rename from MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeMsr.c rename to MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c similarity index 100% rename from MdeModulePkg/Core/Dxe/SysCall/X64/InitializeMsr.c rename to MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c From ecb4151862f77ea963ea401a934c468a6d69022b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 3 Dec 2024 14:40:52 +0300 Subject: [PATCH 285/341] Ring3: Added support for IA32 User page table. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 2 +- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 28 ++++++ .../Core/Dxe/SysCall/IA32/InitializeIA32.c | 89 +++++++++++++++++++ .../Ia32/ExceptionHandlerAsm.nasm | 42 +++++++-- 4 files changed, 155 insertions(+), 6 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index eda00cd6b1..e5311a929f 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -225,7 +225,7 @@ gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES -[Pcd.IA32,Pcd.X64] +[Pcd.IA32, Pcd.X64] gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index af51544705..3c26b07179 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -98,6 +98,10 @@ copy: pop eax %endmacro +ALIGN 4096 +global ASM_PFX(SysCallBase) +ASM_PFX(SysCallBase): + ;------------------------------------------------------------------------------ ; EFI_STATUS ; EFIAPI @@ -119,6 +123,9 @@ ASM_PFX(CoreBootServices): push ebp push eax + mov eax, [ASM_PFX(gCorePageTable)] + mov cr3, eax + ; Switch from User to Core data segment selectors. mov ax, ss mov ds, ax @@ -147,6 +154,9 @@ ASM_PFX(CoreBootServices): SetRing3DataSegmentSelectors + mov eax, [ASM_PFX(gUserPageTable)] + mov cr3, eax + pop eax ; Step over User Arguments [1..3] and CallBootService input. @@ -194,10 +204,17 @@ ASM_PFX(CallRing3): ; Switch to User Stack. mov ebp, ecx + mov ebx, [ASM_PFX(gUserPageTable)] + mov cr3, ebx + ; Pass control to user image sti sysexit +ALIGN 4096 +global ASM_PFX(SysCallEnd) +ASM_PFX(SysCallEnd): + ;------------------------------------------------------------------------------ ; VOID ; EFIAPI @@ -219,5 +236,16 @@ ASM_PFX(ReturnToCore): ret SECTION .data +ALIGN 4096 + +global ASM_PFX(gCorePageTable) +ASM_PFX(gCorePageTable): + resd 1 + +global ASM_PFX(gUserPageTable) +ASM_PFX(gUserPageTable): + resd 1 + +ALIGN 4096 ASM_PFX(CoreEsp): resd 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c index 83b34b1d55..edc6bed78f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c @@ -8,6 +8,86 @@ #include "DxeMain.h" #include +#include + +VOID +EFIAPI +MakeUserPageTableTemplate ( + OUT VOID **UserPageTableTemplate, + OUT UINTN *UserPageTableTemplateSize + ) +{ + UINT8 PhysicalAddressBits; + EFI_PHYSICAL_ADDRESS PhysicalAddress; + UINTN IndexOfPdpEntries; + UINTN IndexOfPageDirectoryEntries; + UINT32 NumberOfPdpEntriesNeeded; + PAGE_MAP_AND_DIRECTORY_POINTER *PageMap; + PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry; + PAGE_TABLE_ENTRY *PageDirectoryEntry; + UINTN TotalPagesNum; + UINTN PageAddress; + UINT64 AddressEncMask; + + // + // Make sure AddressEncMask is contained to smallest supported address field + // + AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; + + PhysicalAddressBits = 32; + + // + // Calculate the table entries needed. + // + NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30)); + + TotalPagesNum = NumberOfPdpEntriesNeeded + 1; + PageAddress = (UINTN)AllocateAlignedPages (TotalPagesNum, PAGE_TABLE_POOL_ALIGNMENT); + ASSERT (PageAddress != 0); + + PageMap = (VOID *)PageAddress; + PageAddress += SIZE_4KB; + + PageDirectoryPointerEntry = PageMap; + PhysicalAddress = 0; + + for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) { + // + // Each Directory Pointer entries points to a page of Page Directory entires. + // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop. + // + PageDirectoryEntry = (VOID *)PageAddress; + PageAddress += SIZE_4KB; + + // + // Fill in a Page Directory Pointer Entries + // + PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask; + PageDirectoryPointerEntry->Bits.Present = 1; + + for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += SIZE_2MB) { + // + // Fill in the Page Directory entries + // + PageDirectoryEntry->Uint64 = (UINT64)PhysicalAddress | AddressEncMask; + PageDirectoryEntry->Bits.ReadWrite = 1; + PageDirectoryEntry->Bits.Present = 0; + PageDirectoryEntry->Bits.MustBe1 = 1; + } + } + + for ( ; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) { + ZeroMem ( + PageDirectoryPointerEntry, + sizeof (PAGE_MAP_AND_DIRECTORY_POINTER) + ); + } + + *UserPageTableTemplate = (VOID *)PageMap; + *UserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT); + + SetUefiImageMemoryAttributes ((UINT64)(UINTN)PageMap, *UserPageTableTemplateSize, EFI_MEMORY_XP); +} VOID EFIAPI @@ -25,6 +105,13 @@ InitializeMsr ( Ebx = 0; Edx = 0; + // + // Forbid global pages. + // + Cr4.UintN = AsmReadCr4 (); + Cr4.Bits.PGE = 0; + AsmWriteCr4 (Cr4.UintN); + // // Forbid supervisor-mode accesses to any user-mode pages. // @@ -70,4 +157,6 @@ InitializeMsr ( Msr = (UINT64)(UINTN)gCoreSysCallStackTop; AsmWriteMsr64 (MSR_IA32_SYSENTER_ESP, Msr); + + gCorePageTable = AsmReadCr3 (); } diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm index b0cb2a9b4f..0c81564554 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm @@ -23,16 +23,33 @@ ; ; CommonExceptionHandler() ; +extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions +extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag extern ASM_PFX(CommonExceptionHandler) SECTION .data +ALIGN 4096 -extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions -extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag +global ASM_PFX(CorePageTable) +ASM_PFX(CorePageTable): + resq 1 -SECTION .text +global ASM_PFX(UserPageTable) +ASM_PFX(UserPageTable): + resq 1 + +global ASM_PFX(mSwitchCr3Flag) +ASM_PFX(mSwitchCr3Flag): + db 0x0 + +ALIGN 4096 +Padding: + db 0x0 -ALIGN 8 +SECTION .text +ALIGN 4096 +global ASM_PFX(ExceptionHandlerBase) +ASM_PFX(ExceptionHandlerBase): ; ; exception handler stub table @@ -88,6 +105,14 @@ HookAfterStubHeaderEnd: global ASM_PFX(CommonInterruptEntry) ASM_PFX(CommonInterruptEntry): cli + cmp byte [ASM_PFX(mSwitchCr3Flag)], 0 + jz NoCr3Switch + mov eax, cr3 + mov [ASM_PFX(UserPageTable)], eax + mov eax, [ASM_PFX(CorePageTable)] + mov cr3, eax + +NoCr3Switch: pop eax ; ; All interrupt handlers are invoked through interrupt gates, so @@ -413,8 +438,8 @@ continue: push ecx mov ecx, ds and ecx, 3 - pop ecx jnz ReturnToRing3 + pop ecx pop dword [ebp - 8] pop dword [ebp - 4] @@ -444,11 +469,18 @@ DoReturn: DoIret: iretd ReturnToRing3: + mov ecx, [ASM_PFX(UserPageTable)] + mov cr3, ecx + pop ecx mov esp, ebp pop ebp add esp, 8 iretd +ALIGN 4096 +global ASM_PFX(ExceptionHandlerEnd) +ASM_PFX(ExceptionHandlerEnd): + ;---------------------------------------; ; _AsmGetTemplateAddressMap ; ;----------------------------------------------------------------------------; From e3439441bc33c7a3d8c10f5d4dbc36917bdfd864 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 3 Dec 2024 19:19:52 +0300 Subject: [PATCH 286/341] OvmfPkg: Increased PEI size at the expense of DXE, increased SEC size at the expense of FVMAIN_COMPACT. --- OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc b/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc index 0c3e551d1f..062a154cda 100644 --- a/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc +++ b/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc @@ -62,9 +62,9 @@ DEFINE FW_BLOCKS = 0x400 DEFINE CODE_BASE_ADDRESS = 0xFFC84000 DEFINE CODE_SIZE = 0x0037C000 DEFINE CODE_BLOCKS = 0x37C -DEFINE FVMAIN_SIZE = 0x00342000 -DEFINE SECFV_OFFSET = 0x003C6000 -DEFINE SECFV_SIZE = 0x3a000 +DEFINE FVMAIN_SIZE = 0x00340000 +DEFINE SECFV_OFFSET = 0x003C4000 +DEFINE SECFV_SIZE = 0x3c000 !endif SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress = $(FW_BASE_ADDRESS) From b9286af6c49dcbf102de0a70c5d4f53f2d12b24b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 5 Dec 2024 12:28:28 +0300 Subject: [PATCH 287/341] SysCall: Removed superfluous User attributes settings. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index fbd32c8926..aafdf60412 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -605,14 +605,6 @@ CallBootService ( *(EFI_PHYSICAL_ADDRESS *)UserRsp->Arguments[4] = (EFI_PHYSICAL_ADDRESS)Argument4; ForbidSupervisorAccessToUserMemory (); - gCpu->SetUserMemoryAttributes ( - gCpu, - gUserPageTable, - Argument4, - EFI_PAGES_TO_SIZE (CoreRbp->Argument3), - EFI_MEMORY_USER - ); - return Status; case SysCallFreePages: @@ -625,14 +617,6 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + CoreRbp->Argument1 * EFI_PAGE_SIZE - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->SetUserMemoryAttributes ( - gCpu, - gUserPageTable, - CoreRbp->Argument2, - EFI_PAGES_TO_SIZE (CoreRbp->Argument1), - EFI_MEMORY_RP - ); - return gBS->FreePages ( *(EFI_PHYSICAL_ADDRESS *)&CoreRbp->Argument2, CoreRbp->Argument1 From 072c709cc51ba372aad651ffd5bb64587e813c24 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 5 Dec 2024 12:35:16 +0300 Subject: [PATCH 288/341] CpuArchLib: Specified IdtTable size precisely. --- UefiCpuPkg/Library/CpuArchLib/CpuDxe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c index 8fa87bf3d8..7250e6b6a2 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuDxe.c @@ -728,9 +728,9 @@ InitInterruptDescriptorTable ( // // Increase Interrupt Descriptor Table and Copy the old IDT table in // - IdtTable = AllocatePages (1); + IdtTable = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM)); ASSERT (IdtTable != NULL); - SetMem (IdtTable, EFI_PAGE_SIZE, 0); + SetMem (IdtTable, sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM, 0); CopyMem (IdtTable, (VOID *)IdtDescriptor.Base, sizeof (IA32_IDT_GATE_DESCRIPTOR) * IdtEntryCount); // From 3c236a3cec5148758dd22e00ce7c7ccb77aec6f2 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 5 Dec 2024 16:12:31 +0300 Subject: [PATCH 289/341] SysCall: Simplified MakeUserPageTableTemplate(). --- MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c | 6 ++---- MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c | 6 ++---- OvmfPkg/Include/IndustryStandard/PageTable.h | 2 -- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c index edc6bed78f..f9fe87feb6 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c @@ -42,7 +42,7 @@ MakeUserPageTableTemplate ( NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30)); TotalPagesNum = NumberOfPdpEntriesNeeded + 1; - PageAddress = (UINTN)AllocateAlignedPages (TotalPagesNum, PAGE_TABLE_POOL_ALIGNMENT); + PageAddress = (UINTN)AllocatePages (TotalPagesNum); ASSERT (PageAddress != 0); PageMap = (VOID *)PageAddress; @@ -84,9 +84,7 @@ MakeUserPageTableTemplate ( } *UserPageTableTemplate = (VOID *)PageMap; - *UserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT); - - SetUefiImageMemoryAttributes ((UINT64)(UINTN)PageMap, *UserPageTableTemplateSize, EFI_MEMORY_XP); + *UserPageTableTemplateSize = EFI_PAGES_TO_SIZE (TotalPagesNum); } VOID diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c index 51f89dcde9..3754ab65f4 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c @@ -155,7 +155,7 @@ MakeUserPageTableTemplate ( TotalPagesNum--; } - BigPageAddress = (UINTN)AllocateAlignedPages (TotalPagesNum, PAGE_TABLE_POOL_ALIGNMENT); + BigPageAddress = (UINTN)AllocatePages (TotalPagesNum); if (BigPageAddress == 0) { DEBUG ((DEBUG_ERROR, "Core: Could not allocate buffer for User page table.\n")); CpuDeadLoop (); @@ -281,9 +281,7 @@ MakeUserPageTableTemplate ( } *UserPageTableTemplate = (VOID *)PageMap; - *UserPageTableTemplateSize = ALIGN_VALUE (EFI_PAGES_TO_SIZE (TotalPagesNum), PAGE_TABLE_POOL_ALIGNMENT); - - SetUefiImageMemoryAttributes ((UINT64)PageMap, *UserPageTableTemplateSize, EFI_MEMORY_XP); + *UserPageTableTemplateSize = EFI_PAGES_TO_SIZE (TotalPagesNum); } VOID diff --git a/OvmfPkg/Include/IndustryStandard/PageTable.h b/OvmfPkg/Include/IndustryStandard/PageTable.h index d9a1195c04..a75b3fcfe7 100644 --- a/OvmfPkg/Include/IndustryStandard/PageTable.h +++ b/OvmfPkg/Include/IndustryStandard/PageTable.h @@ -158,6 +158,4 @@ typedef union { #define PTE_OFFSET(x) ( (x >> 12) & PAGETABLE_ENTRY_MASK) #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull -#define PAGE_TABLE_POOL_ALIGNMENT BASE_2MB - #endif From 716889c1fd6179b18dc298740c841e39f3e4cc53 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 5 Dec 2024 20:46:57 +0300 Subject: [PATCH 290/341] CpuArchLib: Fixed CpuGetMemoryAttributes(). --- UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c index 8e235e03d4..ec6871207e 100644 --- a/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c +++ b/UefiCpuPkg/Library/CpuArchLib/CpuPageTable.c @@ -417,8 +417,16 @@ CpuGetMemoryAttributes ( PAGE_ATTRIBUTE PageAttribute; UINT64 *PageEntry; + ASSERT (Attributes != NULL); + GetCurrentPagingContext (&PagingContext); + if ((PagingContext.MachineType == IMAGE_FILE_MACHINE_I386) && + ((PagingContext.ContextData.Ia32.Attributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE) == 0)) { + *Attributes = 0; + return EFI_UNSUPPORTED; + } + PageEntry = GetPageTableEntry (&PagingContext, Address, &PageAttribute); if (PageEntry == NULL) { *Attributes = 0; From 3d4ef5a9ab3acf38ce8adf4c5d5ba8344d528b97 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 9 Dec 2024 14:29:38 +0300 Subject: [PATCH 291/341] SysCall: Refactored MakeUserPageTableTemplate(). --- .../Core/Dxe/SysCall/IA32/InitializeIA32.c | 4 ++-- MdeModulePkg/Core/Dxe/SysCall/Initialization.c | 14 ++++++-------- MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c | 4 ++-- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c index f9fe87feb6..60a9672e47 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c @@ -13,7 +13,7 @@ VOID EFIAPI MakeUserPageTableTemplate ( - OUT VOID **UserPageTableTemplate, + OUT UINTN *UserPageTableTemplate, OUT UINTN *UserPageTableTemplateSize ) { @@ -83,7 +83,7 @@ MakeUserPageTableTemplate ( ); } - *UserPageTableTemplate = (VOID *)PageMap; + *UserPageTableTemplate = (UINTN)PageMap; *UserPageTableTemplateSize = EFI_PAGES_TO_SIZE (TotalPagesNum); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index d2c18cb3e0..df9fc4a8b5 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -19,8 +19,6 @@ VOID *gRing3Interfaces; UINTN gUartBaseAddress; UEFI_IMAGE_RECORD *mDxeRing3; -VOID *mUserPageTableTemplate; -UINTN mUserPageTableTemplateSize; EXCEPTION_ADDRESSES *mExceptionAddresses; extern UINTN SysCallBase; @@ -29,7 +27,7 @@ extern UINTN SysCallEnd; VOID EFIAPI MakeUserPageTableTemplate ( - OUT VOID **UserPageTableTemplate, + OUT UINTN *UserPageTableTemplate, OUT UINTN *UserPageTableTemplateSize ); @@ -195,8 +193,6 @@ InitializeRing3 ( gRing3Data->SystemTable.NumberOfTableEntries ); - MakeUserPageTableTemplate (&mUserPageTableTemplate, &mUserPageTableTemplateSize); - mExceptionAddresses = GetExceptionAddresses (); return Status; @@ -209,15 +205,17 @@ InitializeUserPageTable ( ) { UINTN UserPageTable; + UINTN UserPageTableSize; UEFI_IMAGE_RECORD_SEGMENT *ImageRecordSegment; UINTN SectionAddress; UINT32 Index; UEFI_IMAGE_RECORD *UserImageRecord; IA32_DESCRIPTOR IdtDescriptor; - UserPageTable = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (mUserPageTableTemplateSize)); - - CopyMem ((VOID *)UserPageTable, mUserPageTableTemplate, mUserPageTableTemplateSize); + // + // TODO: Remove ASSERTs, add proper checks and return status. + // + MakeUserPageTableTemplate (&UserPageTable, &UserPageTableSize); // // Map gRing3Data, gRing3Interfaces, gRing3CallStackBase, DxeRing3 diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c index 3754ab65f4..662e96b8b9 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c @@ -14,7 +14,7 @@ VOID EFIAPI MakeUserPageTableTemplate ( - OUT VOID **UserPageTableTemplate, + OUT UINTN *UserPageTableTemplate, OUT UINTN *UserPageTableTemplateSize ) { @@ -280,7 +280,7 @@ MakeUserPageTableTemplate ( ZeroMem (PageMapLevel5Entry, (512 - IndexOfPml5Entries) * sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)); } - *UserPageTableTemplate = (VOID *)PageMap; + *UserPageTableTemplate = (UINTN)PageMap; *UserPageTableTemplateSize = EFI_PAGES_TO_SIZE (TotalPagesNum); } From f2abde7036ca678a5bb2228855570862839213cb Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 9 Dec 2024 17:28:43 +0300 Subject: [PATCH 292/341] Ring3: Added MakeUserPageTableTemplate() for AARCH64. --- ArmPkg/Include/Library/ArmMmuLib.h | 8 ++++ .../Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 47 +++++++++++++++++++ MdeModulePkg/Core/Dxe/DxeMain.inf | 6 +++ .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 29 ++++++++++++ 4 files changed, 90 insertions(+) diff --git a/ArmPkg/Include/Library/ArmMmuLib.h b/ArmPkg/Include/Library/ArmMmuLib.h index 2ce948e8db..49410a8829 100644 --- a/ArmPkg/Include/Library/ArmMmuLib.h +++ b/ArmPkg/Include/Library/ArmMmuLib.h @@ -21,6 +21,14 @@ ArmConfigureMmu ( OUT UINTN *TranslationTableSize OPTIONAL ); +EFI_STATUS +EFIAPI +ArmMakeUserPageTableTemplate ( + IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable, + OUT UINTN *TranslationTableBase, + OUT UINTN *TranslationTableSize + ); + VOID EFIAPI ArmReplaceLiveTranslationEntry ( diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index 4d88bf6064..f638326738 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -786,6 +786,53 @@ ArmConfigureMmu ( return Status; } +EFI_STATUS +EFIAPI +ArmMakeUserPageTableTemplate ( + IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable, + OUT UINTN *TranslationTableBase, + OUT UINTN *TranslationTableSize + ) +{ + VOID *TranslationTable; + UINTN MaxAddressBits; + UINT64 MaxAddress; + UINTN T0SZ; + UINTN RootTableEntryCount; + EFI_STATUS Status; + + MaxAddressBits = MIN (ArmGetPhysicalAddressBits (), MAX_VA_BITS); + MaxAddress = LShiftU64 (1ULL, MaxAddressBits) - 1; + + T0SZ = 64 - MaxAddressBits; + RootTableEntryCount = GetRootTableEntryCount (T0SZ); + + TranslationTable = AllocatePages (1); + if (TranslationTable == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem (TranslationTable, RootTableEntryCount * sizeof (UINT64)); + + Status = UpdateRegionMapping ( + MemoryTable->VirtualBase, + MemoryTable->Length, + ArmMemoryAttributeToPageAttribute (MemoryTable->Attributes), + 0, + TranslationTable, + FALSE + ); + if (EFI_ERROR (Status)) { + FreePages (TranslationTable, 1); + return Status; + } + + *TranslationTableBase = (UINTN)TranslationTable; + *TranslationTableSize = RootTableEntryCount * sizeof (UINT64); + + return EFI_SUCCESS; +} + RETURN_STATUS EFIAPI ArmMmuBaseLibConstructor ( diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index e5311a929f..3533239c73 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -152,6 +152,9 @@ gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## SysCall gEarlyPL011BaseAddressGuid ## CONSUMES +[Guids.ARM, Guids.AARCH64] + gArmVirtSystemMemorySizeGuid ## CONSUMES + [Ppis] gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB @@ -232,6 +235,9 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize ## CONSUMES +[Pcd.ARM, Pcd.AARCH64] + gArmTokenSpaceGuid.PcdSystemMemoryBase ## CONSUMES + # [Hob] # RESOURCE_DESCRIPTOR ## CONSUMES # MEMORY_ALLOCATION ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index 85a0edf599..54dfd33a6f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -7,6 +7,7 @@ #include #include +#include #include #include "DxeMain.h" @@ -89,6 +90,34 @@ SysCallBootService ( return Status; } +VOID +EFIAPI +MakeUserPageTableTemplate ( + OUT UINTN *UserPageTableTemplate, + OUT UINTN *UserPageTableTemplateSize + ) +{ + ARM_MEMORY_REGION_DESCRIPTOR Descriptor; + VOID *MemorySizeHob; + + MemorySizeHob = GetFirstGuidHob (&gArmVirtSystemMemorySizeGuid); + ASSERT (MemorySizeHob != NULL); + if (MemorySizeHob == NULL) { + return; + } + + Descriptor.PhysicalBase = PcdGet64 (PcdSystemMemoryBase); + Descriptor.VirtualBase = Descriptor.PhysicalBase; + Descriptor.Length = *(UINT64 *)GET_GUID_HOB_DATA (MemorySizeHob); + Descriptor.Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK; + + ArmMakeUserPageTableTemplate ( + &Descriptor, + UserPageTableTemplate, + UserPageTableTemplateSize + ); +} + VOID EFIAPI InitializeMsr ( From 2e0c93292ad02f3dca4cdbecfc324807f9556d80 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 9 Dec 2024 17:32:37 +0300 Subject: [PATCH 293/341] ArmPkg: Added CpuSetUserMemoryAttributes() for AARCH64. --- ArmPkg/Drivers/CpuPei/CpuPei.c | 2 +- ArmPkg/Include/Library/ArmMmuLib.h | 4 +- .../Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 31 +++++++++---- ArmPkg/Library/CpuArchLib/AArch64/Mmu.c | 11 ++++- ArmPkg/Library/CpuArchLib/CpuDxe.c | 6 ++- ArmPkg/Library/CpuArchLib/CpuDxe.h | 13 +++++- ArmPkg/Library/CpuArchLib/CpuMmuCommon.c | 46 +++++++++++++++++-- ArmPkg/Library/CpuArchLib/MemoryAttribute.c | 7 +-- ArmPkg/Library/OpteeLib/Optee.c | 1 + 9 files changed, 99 insertions(+), 22 deletions(-) diff --git a/ArmPkg/Drivers/CpuPei/CpuPei.c b/ArmPkg/Drivers/CpuPei/CpuPei.c index 1c2b53100f..dd4c162414 100644 --- a/ArmPkg/Drivers/CpuPei/CpuPei.c +++ b/ArmPkg/Drivers/CpuPei/CpuPei.c @@ -95,7 +95,7 @@ SetMemoryPermissions ( return EFI_INVALID_PARAMETER; } - return ArmSetMemoryAttributes (BaseAddress, Length, Attributes, AttributeMask); + return ArmSetMemoryAttributes (BaseAddress, Length, Attributes, AttributeMask, 0); } STATIC CONST EDKII_MEMORY_ATTRIBUTE_PPI mMemoryAttributePpi = { diff --git a/ArmPkg/Include/Library/ArmMmuLib.h b/ArmPkg/Include/Library/ArmMmuLib.h index 49410a8829..b9d1b8b724 100644 --- a/ArmPkg/Include/Library/ArmMmuLib.h +++ b/ArmPkg/Include/Library/ArmMmuLib.h @@ -62,6 +62,7 @@ ArmReplaceLiveTranslationEntry ( @param[in] Length The size in bytes of the memory region. @param[in] Attributes Mask of memory attributes to set. @param[in] AttributeMask Mask of memory attributes to take into account. + @param[in] UserPageTable The base address of the User page table. @retval EFI_SUCCESS The attributes were set for the memory region. @retval EFI_INVALID_PARAMETER BaseAddress or Length is not suitably aligned. @@ -76,7 +77,8 @@ ArmSetMemoryAttributes ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes, - IN UINT64 AttributeMask + IN UINT64 AttributeMask, + IN UINTN UserPageTable OPTIONAL ); #endif // ARM_MMU_LIB_H_ diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index f638326738..fc06427593 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -529,6 +529,7 @@ GcdAttributeToPageAttribute ( @param[in] Length The size in bytes of the memory region. @param[in] Attributes Mask of memory attributes to set. @param[in] AttributeMask Mask of memory attributes to take into account. + @param[in] UserPageTable The base address of the User page table. @retval EFI_SUCCESS The attributes were set for the memory region. @retval EFI_INVALID_PARAMETER BaseAddress or Length is not suitably aligned. @@ -543,7 +544,8 @@ ArmSetMemoryAttributes ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes, - IN UINT64 AttributeMask + IN UINT64 AttributeMask, + IN UINTN UserPageTable OPTIONAL ) { UINT64 PageAttributes; @@ -578,14 +580,25 @@ ArmSetMemoryAttributes ( } } - return UpdateRegionMapping ( - BaseAddress, - Length, - PageAttributes, - PageAttributeMask, - ArmGetTTBR0BaseAddress (), - TRUE - ); + if (UserPageTable == 0) { + return UpdateRegionMapping ( + BaseAddress, + Length, + PageAttributes, + PageAttributeMask, + ArmGetTTBR0BaseAddress (), + TRUE + ); + } else { + return UpdateRegionMapping ( + BaseAddress, + Length, + PageAttributes, + PageAttributeMask, + (UINT64 *)UserPageTable, + FALSE + ); + } } EFI_STATUS diff --git a/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c b/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c index 1805156e38..8c8c73d6bb 100644 --- a/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c +++ b/ArmPkg/Library/CpuArchLib/AArch64/Mmu.c @@ -522,6 +522,7 @@ GetMemoryRegionRec ( updated to the end address of the retrieved region. @param[out] RegionLength The length of the retrieved memory region. @param[out] RegionAttributes The attributes of the retrieved memory region. + @param[in] UserPageTable The base address of the User page table. @retval EFI_STATUS Returns EFI_SUCCESS if the memory region is retrieved successfully, or the status of the @@ -535,7 +536,8 @@ EFI_STATUS GetMemoryRegion ( IN OUT UINTN *BaseAddress, OUT UINTN *RegionLength, - OUT UINTN *RegionAttributes + OUT UINTN *RegionAttributes, + IN UINTN UserPageTable OPTIONAL ) { EFI_STATUS Status; @@ -549,7 +551,12 @@ GetMemoryRegion ( return EFI_INVALID_PARAMETER; } - TranslationTable = ArmGetTTBR0BaseAddress (); + if (UserPageTable == 0) { + TranslationTable = ArmGetTTBR0BaseAddress (); + } else { + TranslationTable = (UINT64 *)UserPageTable; + } + // Initialize the output parameters. These paramaters are only valid if the // result is EFI_SUCCESS. diff --git a/ArmPkg/Library/CpuArchLib/CpuDxe.c b/ArmPkg/Library/CpuArchLib/CpuDxe.c index 6dd313a069..0c096f7e16 100644 --- a/ArmPkg/Library/CpuArchLib/CpuDxe.c +++ b/ArmPkg/Library/CpuArchLib/CpuDxe.c @@ -278,7 +278,8 @@ STATIC EFI_CPU_ARCH_PROTOCOL mCpu = { CpuSetMemoryAttributes, 0, // NumberOfTimers 2048, // DmaBufferAlignment - CpuGetMemoryAttributes + CpuGetMemoryAttributes, + CpuSetUserMemoryAttributes }; STATIC @@ -353,7 +354,8 @@ RemapUnusedMemoryNx ( MemoryMapEntry->PhysicalStart, EFI_PAGES_TO_SIZE (MemoryMapEntry->NumberOfPages), EFI_MEMORY_XP, - EFI_MEMORY_XP + EFI_MEMORY_XP, + 0 ); } diff --git a/ArmPkg/Library/CpuArchLib/CpuDxe.h b/ArmPkg/Library/CpuArchLib/CpuDxe.h index b80ba2d0d3..b88016ec75 100644 --- a/ArmPkg/Library/CpuArchLib/CpuDxe.h +++ b/ArmPkg/Library/CpuArchLib/CpuDxe.h @@ -104,6 +104,16 @@ CpuGetMemoryAttributes ( OUT UINT64 *Attributes ); +EFI_STATUS +EFIAPI +CpuSetUserMemoryAttributes ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN UINTN UserPageTable, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 EfiAttributes + ); + EFI_STATUS InitializeExceptions ( VOID @@ -124,7 +134,8 @@ EFI_STATUS GetMemoryRegion ( IN OUT UINTN *BaseAddress, OUT UINTN *RegionLength, - OUT UINTN *RegionAttributes + OUT UINTN *RegionAttributes, + IN UINTN UserPageTable OPTIONAL ); EFI_STATUS diff --git a/ArmPkg/Library/CpuArchLib/CpuMmuCommon.c b/ArmPkg/Library/CpuArchLib/CpuMmuCommon.c index 97db7672e8..7750881191 100644 --- a/ArmPkg/Library/CpuArchLib/CpuMmuCommon.c +++ b/ArmPkg/Library/CpuArchLib/CpuMmuCommon.c @@ -254,14 +254,14 @@ CpuSetMemoryAttributes ( // Get the region starting from 'BaseAddress' and its 'Attribute' RegionBaseAddress = BaseAddress; - Status = GetMemoryRegion (&RegionBaseAddress, &RegionLength, &RegionArmAttributes); + Status = GetMemoryRegion (&RegionBaseAddress, &RegionLength, &RegionArmAttributes, 0); // Data & Instruction Caches are flushed when we set new memory attributes. // So, we only set the attributes if the new region is different. if (EFI_ERROR (Status) || (RegionArmAttributes != ArmAttributes) || ((BaseAddress + Length) > (RegionBaseAddress + RegionLength))) { - return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes, 0); + return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes, 0, 0); } else { return EFI_SUCCESS; } @@ -281,7 +281,7 @@ CpuGetMemoryAttributes ( UINTN RegionArmAttributes; RegionBaseAddress = Address; - Status = GetMemoryRegion (&RegionBaseAddress, &RegionLength, &RegionArmAttributes); + Status = GetMemoryRegion (&RegionBaseAddress, &RegionLength, &RegionArmAttributes, 0); if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; @@ -291,3 +291,43 @@ CpuGetMemoryAttributes ( return Status; } + +EFI_STATUS +EFIAPI +CpuSetUserMemoryAttributes ( + IN EFI_CPU_ARCH_PROTOCOL *This, + IN UINTN UserPageTable, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 EfiAttributes + ) +{ + EFI_STATUS Status; + UINTN ArmAttributes; + UINTN RegionBaseAddress; + UINTN RegionLength; + UINTN RegionArmAttributes; + + if ((BaseAddress & (SIZE_4KB - 1)) != 0) { + // Minimum granularity is SIZE_4KB (4KB on ARM) + DEBUG ((DEBUG_PAGE, "CpuSetMemoryAttributes(%lx, %lx, %lx): Minimum granularity is SIZE_4KB\n", BaseAddress, Length, EfiAttributes)); + return EFI_UNSUPPORTED; + } + + // Convert the 'Attribute' into ARM Attribute + ArmAttributes = EfiAttributeToArmAttribute (EfiAttributes); + + // Get the region starting from 'BaseAddress' and its 'Attribute' + RegionBaseAddress = BaseAddress; + Status = GetMemoryRegion (&RegionBaseAddress, &RegionLength, &RegionArmAttributes, UserPageTable); + + // Data & Instruction Caches are flushed when we set new memory attributes. + // So, we only set the attributes if the new region is different. + if (EFI_ERROR (Status) || (RegionArmAttributes != ArmAttributes) || + ((BaseAddress + Length) > (RegionBaseAddress + RegionLength))) + { + return ArmSetMemoryAttributes (BaseAddress, Length, EfiAttributes, 0, UserPageTable); + } else { + return EFI_SUCCESS; + } +} diff --git a/ArmPkg/Library/CpuArchLib/MemoryAttribute.c b/ArmPkg/Library/CpuArchLib/MemoryAttribute.c index c77feb848c..ef9d63390c 100644 --- a/ArmPkg/Library/CpuArchLib/MemoryAttribute.c +++ b/ArmPkg/Library/CpuArchLib/MemoryAttribute.c @@ -114,7 +114,8 @@ GetMemoryAttributes ( Status = GetMemoryRegion ( &RegionAddress, &RegionLength, - &RegionAttributes + &RegionAttributes, + 0 ); DEBUG (( @@ -216,7 +217,7 @@ SetMemoryAttributes ( return EFI_UNSUPPORTED; } - return ArmSetMemoryAttributes (BaseAddress, Length, Attributes, Attributes); + return ArmSetMemoryAttributes (BaseAddress, Length, Attributes, Attributes, 0); } /** @@ -284,7 +285,7 @@ ClearMemoryAttributes ( return EFI_UNSUPPORTED; } - return ArmSetMemoryAttributes (BaseAddress, Length, 0, Attributes); + return ArmSetMemoryAttributes (BaseAddress, Length, 0, Attributes, 0); } EFI_MEMORY_ATTRIBUTE_PROTOCOL mMemoryAttribute = { diff --git a/ArmPkg/Library/OpteeLib/Optee.c b/ArmPkg/Library/OpteeLib/Optee.c index 3acf172b68..24d96a5cc6 100644 --- a/ArmPkg/Library/OpteeLib/Optee.c +++ b/ArmPkg/Library/OpteeLib/Optee.c @@ -90,6 +90,7 @@ OpteeSharedMemoryRemap ( PhysicalAddress, Size, EFI_MEMORY_WB | EFI_MEMORY_XP, + 0, 0 ); if (EFI_ERROR (Status)) { From 058b9739423e9a9f3b5dd342cc5b1a622866aa38 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 16 Dec 2024 18:10:18 +0300 Subject: [PATCH 294/341] Ring3: Added support for AARCH64 User page table. --- .../AArch64/ExceptionSupport.S | 58 +++++++++++++++++ .../Library/ArmExceptionLib/ArmExceptionLib.c | 43 +++++++++++-- .../AArch64/DefaultExceptionHandler.c | 4 ++ .../Dxe/SysCall/AARCH64/CoreBootServices.S | 17 +++-- .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 27 ++------ MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 2 +- .../Core/Dxe/SysCall/Initialization.c | 62 +++++++++++++------ .../Core/Dxe/SysCall/SupportedProtocols.c | 24 ------- 8 files changed, 163 insertions(+), 74 deletions(-) diff --git a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S index 687d22e852..0de25b71c0 100644 --- a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S @@ -101,6 +101,8 @@ GCC_ASM_EXPORT(CommonCExceptionHandler) #define FP_CONTEXT_SIZE (32 * 16) #define SYS_CONTEXT_SIZE ( 6 * 8) // 5 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10) +ASM_FUNC_ALIGN(ExceptionHandlerBase, 4096) + // // There are two methods for installing AArch64 exception vectors: // 1. Install a copy of the vectors to a location specified by a PCD @@ -264,6 +266,28 @@ ASM_PFX(CommonExceptionEntry): stp q28, q29, [x28, #0x1c0] stp q30, q31, [x28, #0x1e0] + ldr x2, [x28, #(FP_CONTEXT_SIZE + 0x8)] // Saved Processor Status Register + and x2, x2, #0xF + cmp x2, 0 // Check whether EL0 process was interrupted + b.ne NoTTBR0Switch + adrp x1, ASM_PFX(CorePageTable) + EL1_OR_EL2(x3) +1:mrs x4, ttbr0_el1 + str x4, [x1, #0x8] // UserPageTable + ldr x4, [x1] // CorePageTable + msr ttbr0_el1, x4 + tlbi vmalle1 + b 3f +2:mrs x4, ttbr0_el2 + str x4, [x1, #0x8] // UserPageTable + ldr x4, [x1] // CorePageTable + msr ttbr0_el2, x4 + tlbi alle2 +3:dsb sy + isb + +NoTTBR0Switch: + // x0 still holds the exception type. // Set x1 to point to the top of our struct on the Stack mov x1, sp @@ -279,6 +303,24 @@ ASM_PFX(CommonExceptionEntry): // We do not try to recover. bl ASM_PFX(CommonCExceptionHandler) // Call exception handler + ldr x2, [x28, #(FP_CONTEXT_SIZE + 0x8)] // Saved Processor Status Register + and x2, x2, #0xF + cmp x2, 0 // Check whether EL0 process was interrupted + b.ne NoTTBR0Switch2 + adrp x1, ASM_PFX(CorePageTable) + EL1_OR_EL2(x3) +1:ldr x4, [x1, #0x8] // UserPageTable + msr ttbr0_el1, x4 + tlbi vmalle1 + b 3f +2:ldr x4, [x1, #0x8] // UserPageTable + msr ttbr0_el2, x4 + tlbi alle2 +3:dsb sy + isb + +NoTTBR0Switch2: + // Pop as many GP regs as we can before entering the critical section below ldp x2, x3, [sp, #0x10] ldp x4, x5, [sp, #0x20] @@ -356,6 +398,22 @@ continue: eret +ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096) + ASM_FUNC(RegisterEl0Stack) msr sp_el0, x0 ret + +.data + +.global ASM_PFX(CorePageTable) +.balign 4096 +ASM_PFX(CorePageTable): +.ds.d 1 + +UserPageTable: +.ds.d 1 + +.balign 4096 +Padding: +.ds.b 1 diff --git a/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c b/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c index 38cf75dc34..768eda9226 100644 --- a/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c +++ b/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c @@ -41,6 +41,20 @@ extern UINTN gMaxExceptionNumber; extern EFI_EXCEPTION_CALLBACK gExceptionHandlers[]; extern PHYSICAL_ADDRESS gExceptionVectorAlignmentMask; +EXCEPTION_ADDRESSES mAddresses; + +VOID +ExceptionHandlerBase ( + VOID + ); + +VOID +ExceptionHandlerFinal ( + VOID + ); + +extern UINTN CorePageTable; + /** Initializes all CPU exceptions entries and provides the default exception handlers. @@ -138,10 +152,6 @@ CommonCExceptionHandler ( IN OUT EFI_SYSTEM_CONTEXT SystemContext ) { - if (ArmHasPan ()) { - ArmClearPan (); - } - if ((UINTN)ExceptionType <= gMaxExceptionNumber) { if (gExceptionHandlers[ExceptionType]) { gExceptionHandlers[ExceptionType](ExceptionType, SystemContext); @@ -181,3 +191,28 @@ InitializeSeparateExceptionStacks ( { return EFI_SUCCESS; } + +EXCEPTION_ADDRESSES * +EFIAPI +GetExceptionAddresses ( + VOID + ) +{ + return &mAddresses; +} + +VOID +EFIAPI +SetExceptionAddresses ( + IN VOID *Buffer, + IN UINTN BufferSize + ) +{ + mAddresses.ExceptionStackBase = (UINTN)Buffer; + mAddresses.ExceptionStackSize = BufferSize; + mAddresses.ExceptionHandlerBase = (UINTN)ExceptionHandlerBase; + mAddresses.ExceptionHandlerSize = (UINTN)ExceptionHandlerFinal - mAddresses.ExceptionHandlerBase; + mAddresses.ExceptionDataBase = (UINTN)&CorePageTable; + + CorePageTable = (UINTN)ArmGetTTBR0BaseAddress (); +} diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index 04f218a724..d5dd1fbbd2 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -232,6 +232,10 @@ DefaultExceptionHandler ( // gets reused. UnicodeSPrintAsciiFormat (UnicodeBuffer, MAX_PRINT_CHARS, Buffer); + if (ArmHasPan ()) { + ArmClearPan (); + } + DEBUG_CODE_BEGIN (); CONST CHAR8 *Pdb, *PrevPdb; UINTN ImageBase; diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 5bc80d9966..f6de8c0a71 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -55,6 +55,7 @@ call: add sp, sp, #0x10 ret +ASM_FUNC_ALIGN(SysCallBase, 4096) //------------------------------------------------------------------------------ // EFI_STATUS // EFIAPI @@ -67,6 +68,7 @@ call: // (x2) gRing3EntryPoint // (x3) gCoreSysCallStackTop // (x4) &CoreSp +// (x5) gUserPageTable //------------------------------------------------------------------------------ ASM_FUNC(ArmCallRing3) // Save registers. @@ -88,6 +90,10 @@ ASM_FUNC(ArmCallRing3) // Disable interrupts. msr daifset, #0xf isb + // Save Core SP and switch to CoreSysCall Stack. + mov x6, sp + str x6, [x4] + mov sp, x3 // Copy PSTATE to SPSR. mrs x6, nzcv mrs x7, pan @@ -97,17 +103,18 @@ ASM_FUNC(ArmCallRing3) EL1_OR_EL2(x1) 1:msr elr_el1, x2 msr spsr_el1, x6 + msr ttbr0_el1, x5 + tlbi vmalle1 b 3f 2:msr elr_el2, x2 msr spsr_el2, x6 - // Save Core SP and switch to CoreSysCall Stack. -3:mov x5, sp - str x5, [x4] - mov sp, x3 - + msr ttbr0_el2, x5 + tlbi alle2 +3:dsb sy isb eret +ASM_FUNC_ALIGN(SysCallEnd, 4096) //------------------------------------------------------------------------------ // VOID // EFIAPI diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index 54dfd33a6f..c9bf740fc3 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -13,7 +13,7 @@ #include "DxeMain.h" STATIC UINTN mCoreSp; -extern UINTN gUartBaseAddress; +UINTN gUserPageTable; EFI_STATUS EFIAPI @@ -22,7 +22,8 @@ ArmCallRing3 ( IN VOID *StackPointer, IN VOID *EntryPoint, IN VOID *SysCallStack, - IN VOID *CoreStack + IN VOID *CoreStack, + IN UINTN UserPageTable ); VOID @@ -65,12 +66,6 @@ SysCallBootService ( AllowSupervisorAccessToUserMemory (); CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)UserRsp, 8 * sizeof (UINTN)); - - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP - ); ForbidSupervisorAccessToUserMemory (); Status = CallBootService ( @@ -81,12 +76,6 @@ SysCallBootService ( CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - return Status; } @@ -128,13 +117,6 @@ InitializeMsr ( UINTN Tcr; UINTN Sctlr; // - // If HCR_EL2.NV is 1 and the current Exception level is EL1, - // then EL1 read accesses to the CurrentEL register return a value of 0x2 in bits[3:2]. - // CurrentEL == 1 -> HCR_EL2.NV == 0 - // - // If stage 1 is enabled and stage 1 Base permissions use Direct permissions, - // then GCS access is not permitted and UnprivGCS and PrivGCS are not present. - // // Disable Hierarchical permissions just in case. // Tcr = ArmGetTCR (); @@ -153,6 +135,7 @@ InitializeMsr ( } InitializeSysCallHandler ((VOID *)SysCallBootService); + SetExceptionAddresses (NULL, 0); } VOID @@ -183,5 +166,5 @@ CallRing3 ( IN RING3_CALL_DATA *Data ) { - return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp); + return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp, gUserPageTable); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index aafdf60412..683edef44a 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -22,7 +22,7 @@ CHAR8 *SysCallNames[] = { // // BootServices // - "SysCallReturnToCore", // Must always be zero for CoreBootServices.nasm. + "SysCallReturnToCore", "SysCallLocateProtocol", "SysCallOpenProtocol", "SysCallInstallMultipleProtocolInterfaces", diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index df9fc4a8b5..a175d47247 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -20,6 +20,8 @@ UINTN gUartBaseAddress; UEFI_IMAGE_RECORD *mDxeRing3; EXCEPTION_ADDRESSES *mExceptionAddresses; +UINTN mConfigurationTable; +UINTN mConfigurationTableSize; extern UINTN SysCallBase; extern UINTN SysCallEnd; @@ -79,10 +81,12 @@ InitializeRing3 ( ); if (PcdGetBool (PcdSerialUseMmio)) { + mConfigurationTableSize = (gRing3Data->SystemTable.NumberOfTableEntries + 1) * sizeof (EFI_CONFIGURATION_TABLE); + Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, - EFI_SIZE_TO_PAGES ((gRing3Data->SystemTable.NumberOfTableEntries + 1) * sizeof (EFI_CONFIGURATION_TABLE)), + EFI_SIZE_TO_PAGES (mConfigurationTableSize), &Physical ); if (EFI_ERROR (Status)) { @@ -111,6 +115,7 @@ InitializeRing3 ( DEBUG ((DEBUG_ERROR, "Core: gUartBaseAddress = 0x%p\n", gUartBaseAddress)); gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + mConfigurationTable = (UINTN)Physical; } // // Initialize DxeRing3 with Supervisor privileges. @@ -210,7 +215,6 @@ InitializeUserPageTable ( UINTN SectionAddress; UINT32 Index; UEFI_IMAGE_RECORD *UserImageRecord; - IA32_DESCRIPTOR IdtDescriptor; // // TODO: Remove ASSERTs, add proper checks and return status. @@ -270,14 +274,6 @@ InitializeUserPageTable ( EFI_MEMORY_RO ); - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - (UINTN)&gCorePageTable, - SIZE_4KB, - EFI_MEMORY_RO | EFI_MEMORY_XP - ); - gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, @@ -289,14 +285,6 @@ InitializeUserPageTable ( // // Map ExceptionHandlers, ExceptionStacks, Idt // - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - mExceptionAddresses->ExceptionStackBase, - mExceptionAddresses->ExceptionStackSize, - EFI_MEMORY_XP - ); - gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, @@ -313,6 +301,25 @@ InitializeUserPageTable ( EFI_MEMORY_XP ); +#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) + IA32_DESCRIPTOR IdtDescriptor; + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)&gCorePageTable, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionStackBase, + mExceptionAddresses->ExceptionStackSize, + EFI_MEMORY_XP + ); + AsmReadIdtr (&IdtDescriptor); gCpu->SetUserMemoryAttributes ( gCpu, @@ -332,6 +339,25 @@ InitializeUserPageTable ( FixedPcdGet32 (PcdOvmfWorkAreaSize), EFI_MEMORY_XP | EFI_MEMORY_USER ); +#elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mConfigurationTable, + ALIGN_VALUE (mConfigurationTableSize, EFI_PAGE_SIZE), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + // + // Necessary fix for DEBUG printings. + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + gUartBaseAddress, + SIZE_4KB, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); +#endif // // Map User Image diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 4ef2f87fb8..286ba9f834 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -13,10 +13,6 @@ EFI_FILE_PROTOCOL mRing3FileProtocol; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; -#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) -extern UINTN gUartBaseAddress; -#endif - typedef struct { EFI_FILE_PROTOCOL Protocol; EFI_FILE_PROTOCOL *Ring3File; @@ -62,28 +58,8 @@ GoToRing3 ( VA_END (Marker); ForbidSupervisorAccessToUserMemory (); -#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) - // - // Necessary fix for DEBUG printings. - // - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); -#endif Status = CallRing3 (Input); -#if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) - AllowSupervisorAccessToUserMemory (); - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP - ); - ForbidSupervisorAccessToUserMemory (); -#endif - CoreFreePages (Ring3Pages, PagesNumber); return Status; From a5a77d6720ec5f1a377aef2c4d10d7311cbedc82 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 17 Dec 2024 15:33:48 +0300 Subject: [PATCH 295/341] ArmPkg: Refactored SVC handling. --- .../ArmExceptionLib/AArch64/ExceptionSupport.S | 11 ++++------- ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c | 3 --- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S index 0de25b71c0..22a1ac50ce 100644 --- a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S @@ -89,7 +89,7 @@ UINT64 FPSR; 0x310 // Floating Point Status Register UINT64 ESR; 0x318 // Exception syndrome register UINT64 FAR; 0x320 // Fault Address Register - UINT64 Padding;0x328 // Required for stack alignment + UINT64 Type; 0x328 // Exception Type */ GCC_ASM_EXPORT(ExceptionHandlersEnd) @@ -246,7 +246,7 @@ ASM_PFX(CommonExceptionEntry): // Save the SYS regs stp x2, x3, [x28, #-SYS_CONTEXT_SIZE]! stp x4, x5, [x28, #0x10] - str x6, [x28, #0x20] + stp x6, x0, [x28, #0x20] // Push FP regs to Stack. stp q0, q1, [x28, #-FP_CONTEXT_SIZE]! @@ -336,12 +336,9 @@ NoTTBR0Switch2: ldp x24, x25, [sp, #0xc0] ldp x26, x27, [sp, #0xd0] // Preserve return value for SVC. - ldr x1, [x28, #(FP_CONTEXT_SIZE + 0x18)] // Exception syndrome register - lsr x1, x1, #26 - and x1, x1, #0x3F - cmp x1, #0x15 + ldr x1, [x28, #(FP_CONTEXT_SIZE + 0x28)] // Exception type + cmp x1, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS b.eq is_SVC - ldp x0, x1, [sp], #0xe0 b continue is_SVC: diff --git a/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c b/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c index 768eda9226..c315a4472f 100644 --- a/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c +++ b/ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.c @@ -155,9 +155,6 @@ CommonCExceptionHandler ( if ((UINTN)ExceptionType <= gMaxExceptionNumber) { if (gExceptionHandlers[ExceptionType]) { gExceptionHandlers[ExceptionType](ExceptionType, SystemContext); -#if defined (MDE_CPU_AARCH64) - SystemContext.SystemContextAArch64->ESR = 0; -#endif return EFI_SUCCESS; } } else { From 247851d48aebfd4931a0b47330257be1e186e568 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 17 Dec 2024 16:16:17 +0300 Subject: [PATCH 296/341] SysCall/AARCH64: Enabled interrupts in SysCall handlers. --- MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index c9bf740fc3..42ea8ac88f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -54,6 +54,8 @@ SysCallBootService ( EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Physical; + ArmEnableInterrupts (); + Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, @@ -76,6 +78,8 @@ SysCallBootService ( CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); + ArmDisableInterrupts (); + return Status; } From 9b471a3cb8d563620fdd1a3cadcb6e1830f26abd Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 19 Dec 2024 13:24:32 +0300 Subject: [PATCH 297/341] Ring3: Added MakeUserPageTableTemplate() for ARM. --- ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c | 48 +++++++++++++++++-- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 29 +++++++++++ MdePkg/Include/Arm/AArch32Mmu.h | 6 +-- 3 files changed, 75 insertions(+), 8 deletions(-) diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c index c65f293b61..a093d89f56 100644 --- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c @@ -86,7 +86,8 @@ PopulateLevel2PageTable ( IN UINT32 *SectionEntry, IN UINT32 PhysicalBase, IN UINT32 RemainLength, - IN ARM_MEMORY_REGION_ATTRIBUTES Attributes + IN ARM_MEMORY_REGION_ATTRIBUTES Attributes, + IN BOOLEAN UserTable ) { UINT32 *PageEntry; @@ -132,6 +133,10 @@ PopulateLevel2PageTable ( PageAttributes &= ~TT_DESCRIPTOR_PAGE_S_SHARED; } + if (!UserTable) { + PageAttributes |= TT_DESCRIPTOR_PAGE_AF; + } + // Check if the Section Entry has already been populated. Otherwise attach a // Level 2 Translation Table to it if (*SectionEntry != 0) { @@ -220,7 +225,8 @@ STATIC VOID FillTranslationTable ( IN UINT32 *TranslationTable, - IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion + IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion, + IN BOOLEAN UserTable ) { UINT32 *SectionEntry; @@ -272,6 +278,10 @@ FillTranslationTable ( Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED; } + if (!UserTable) { + Attributes |= TT_DESCRIPTOR_SECTION_AF; + } + // Get the first section entry for this mapping SectionEntry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS (TranslationTable, MemoryRegion->VirtualBase); @@ -307,7 +317,8 @@ FillTranslationTable ( SectionEntry, PhysicalBase, PageMapLength, - MemoryRegion->Attributes + MemoryRegion->Attributes, + UserTable ); // @@ -364,7 +375,7 @@ ArmConfigureMmu ( ZeroMem (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE); while (MemoryTable->Length != 0) { - FillTranslationTable (TranslationTable, MemoryTable); + FillTranslationTable (TranslationTable, MemoryTable, FALSE); MemoryTable++; } @@ -424,3 +435,32 @@ ArmConfigureMmu ( ArmEnableMmu (); return RETURN_SUCCESS; } + +EFI_STATUS +EFIAPI +ArmMakeUserPageTableTemplate ( + IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable, + OUT UINTN *TranslationTableBase, + OUT UINTN *TranslationTableSize + ) +{ + VOID *TranslationTable; + + TranslationTable = AllocateAlignedPages ( + EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE), + TRANSLATION_TABLE_SECTION_ALIGNMENT + ); + if (TranslationTable == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ZeroMem (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE); + + FillTranslationTable (TranslationTable, MemoryTable, TRUE); + + *TranslationTableBase = (UINTN)TranslationTable; + *TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE; + + return EFI_SUCCESS; + +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 7f68d92fb7..b090af890d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -6,6 +6,7 @@ **/ #include +#include #include #include "DxeMain.h" @@ -97,6 +98,34 @@ SysCallBootService ( return Status; } +VOID +EFIAPI +MakeUserPageTableTemplate ( + OUT UINTN *UserPageTableTemplate, + OUT UINTN *UserPageTableTemplateSize + ) +{ + ARM_MEMORY_REGION_DESCRIPTOR Descriptor; + VOID *MemorySizeHob; + + MemorySizeHob = GetFirstGuidHob (&gArmVirtSystemMemorySizeGuid); + ASSERT (MemorySizeHob != NULL); + if (MemorySizeHob == NULL) { + return; + } + + Descriptor.PhysicalBase = PcdGet64 (PcdSystemMemoryBase); + Descriptor.VirtualBase = Descriptor.PhysicalBase; + Descriptor.Length = *(UINT64 *)GET_GUID_HOB_DATA (MemorySizeHob); + Descriptor.Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK; + + ArmMakeUserPageTableTemplate ( + &Descriptor, + UserPageTableTemplate, + UserPageTableTemplateSize + ); +} + VOID EFIAPI InitializeMsr ( diff --git a/MdePkg/Include/Arm/AArch32Mmu.h b/MdePkg/Include/Arm/AArch32Mmu.h index 959c29f2d5..d0086246a4 100644 --- a/MdePkg/Include/Arm/AArch32Mmu.h +++ b/MdePkg/Include/Arm/AArch32Mmu.h @@ -162,8 +162,7 @@ TT_DESCRIPTOR_SECTION_NG_GLOBAL | \ TT_DESCRIPTOR_SECTION_S_SHARED | \ TT_DESCRIPTOR_SECTION_DOMAIN(0) | \ - TT_DESCRIPTOR_SECTION_AP_NO_RW | \ - TT_DESCRIPTOR_SECTION_AF) + TT_DESCRIPTOR_SECTION_AP_NO_RW) #define TT_DESCRIPTOR_SECTION_WRITE_BACK (TT_DESCRIPTOR_SECTION_DEFAULT | \ TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC) @@ -179,8 +178,7 @@ #define TT_DESCRIPTOR_PAGE_DEFAULT (TT_DESCRIPTOR_PAGE_TYPE_PAGE | \ TT_DESCRIPTOR_PAGE_NG_GLOBAL | \ - TT_DESCRIPTOR_PAGE_AP_NO_RW | \ - TT_DESCRIPTOR_PAGE_AF) + TT_DESCRIPTOR_PAGE_AP_NO_RW) #define TT_DESCRIPTOR_PAGE_WRITE_BACK (TT_DESCRIPTOR_PAGE_DEFAULT | \ TT_DESCRIPTOR_PAGE_S_SHARED | \ From c10e841ba2a59e0db2bbdaf85c6910276037cfef Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 19 Dec 2024 13:39:14 +0300 Subject: [PATCH 298/341] ArmPkg: Added CpuSetUserMemoryAttributes() for ARM. --- .../Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c | 94 ++++++++++--------- ArmPkg/Library/CpuArchLib/Arm/Mmu.c | 10 +- 2 files changed, 60 insertions(+), 44 deletions(-) diff --git a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c index 3fc73a391b..513568adf2 100644 --- a/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c +++ b/ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibUpdate.c @@ -31,7 +31,8 @@ STATIC EFI_STATUS ConvertSectionToPages ( - IN EFI_PHYSICAL_ADDRESS BaseAddress + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable ) { UINT32 FirstLevelIdx; @@ -40,14 +41,10 @@ ConvertSectionToPages ( UINT32 PageDescriptor; UINT32 Index; - volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; - volatile ARM_PAGE_TABLE_ENTRY *PageTable; + volatile ARM_PAGE_TABLE_ENTRY *PageTable; DEBUG ((DEBUG_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress)); - // Obtain page table base - FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress (); - // Calculate index into first level translation table for start of modification FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT; ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); @@ -79,11 +76,12 @@ ConvertSectionToPages ( STATIC EFI_STATUS UpdatePageEntries ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes, - IN UINT32 EntryMask, - OUT BOOLEAN *FlushTlbs OPTIONAL + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + IN UINT32 EntryMask, + OUT BOOLEAN *FlushTlbs OPTIONAL, + IN volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable ) { EFI_STATUS Status; @@ -98,8 +96,7 @@ UpdatePageEntries ( UINT32 CurrentPageTableEntry; VOID *Mva; - volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; - volatile ARM_PAGE_TABLE_ENTRY *PageTable; + volatile ARM_PAGE_TABLE_ENTRY *PageTable; Status = EFI_SUCCESS; @@ -163,9 +160,6 @@ UpdatePageEntries ( EntryValue |= TT_DESCRIPTOR_PAGE_XN_MASK; } - // Obtain page table base - FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress (); - // Calculate number of 4KB page table entries to change NumPageEntries = (UINT32)(Length / TT_DESCRIPTOR_PAGE_SIZE); @@ -193,7 +187,10 @@ UpdatePageEntries ( continue; } - Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT); + Status = ConvertSectionToPages ( + FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT, + FirstLevelTable + ); if (EFI_ERROR (Status)) { // Exit for loop break; @@ -240,21 +237,21 @@ UpdatePageEntries ( STATIC EFI_STATUS UpdateSectionEntries ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes, - IN UINT32 EntryMask + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes, + IN UINT32 EntryMask, + IN volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable ) { - EFI_STATUS Status; - UINT32 EntryValue; - UINT32 FirstLevelIdx; - UINT32 NumSections; - UINT32 i; - UINT32 CurrentDescriptor; - UINT32 Descriptor; - VOID *Mva; - volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; + EFI_STATUS Status; + UINT32 EntryValue; + UINT32 FirstLevelIdx; + UINT32 NumSections; + UINT32 i; + UINT32 CurrentDescriptor; + UINT32 Descriptor; + VOID *Mva; Status = EFI_SUCCESS; @@ -325,9 +322,6 @@ UpdateSectionEntries ( EntryValue |= TT_DESCRIPTOR_SECTION_AF; } - // obtain page table base - FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress (); - // calculate index into first level translation table for start of modification FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT; ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); @@ -347,7 +341,8 @@ UpdateSectionEntries ( TT_DESCRIPTOR_SECTION_SIZE, Attributes, ConvertSectionAttributesToPageAttributes (EntryMask), - NULL + NULL, + FirstLevelTable ); } else { // still a section entry @@ -385,6 +380,7 @@ UpdateSectionEntries ( @param Attributes A mask of EFI_MEMORY_xx constants. @param SectionMask A mask of short descriptor section attributes describing which descriptor bits to update. + @param UserPageTable The base address of the User page table. @retval EFI_SUCCESS The attributes were set successfully. @retval EFI_OUT_OF_RESOURCES The operation failed due to insufficient memory. @@ -396,12 +392,14 @@ SetMemoryAttributes ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes, - IN UINT32 SectionMask + IN UINT32 SectionMask, + IN UINTN UserPageTable OPTIONAL ) { - EFI_STATUS Status; - UINT64 ChunkLength; - BOOLEAN FlushTlbs; + EFI_STATUS Status; + UINT64 ChunkLength; + BOOLEAN FlushTlbs; + volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; if (BaseAddress > (UINT64)MAX_ADDRESS) { DEBUG (( @@ -419,6 +417,13 @@ SetMemoryAttributes ( return EFI_SUCCESS; } + // Obtain page table base + if (UserPageTable == 0) { + FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress (); + } else { + FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)UserPageTable; + } + FlushTlbs = FALSE; while (Length > 0) { if ((BaseAddress % TT_DESCRIPTOR_SECTION_SIZE == 0) && @@ -438,7 +443,8 @@ SetMemoryAttributes ( BaseAddress, ChunkLength, Attributes, - SectionMask + SectionMask, + FirstLevelTable ); FlushTlbs = TRUE; @@ -466,7 +472,8 @@ SetMemoryAttributes ( ChunkLength, Attributes, ConvertSectionAttributesToPageAttributes (SectionMask), - &FlushTlbs + &FlushTlbs, + FirstLevelTable ); } @@ -517,6 +524,7 @@ SetMemoryAttributes ( @param[in] Length The size in bytes of the memory region. @param[in] Attributes Mask of memory attributes to set. @param[in] AttributeMask Mask of memory attributes to take into account. + @param[in] UserPageTable The base address of the User page table. @retval EFI_SUCCESS The attributes were set for the memory region. @retval EFI_INVALID_PARAMETER BaseAddress or Length is not suitably aligned. @@ -531,7 +539,8 @@ ArmSetMemoryAttributes ( IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes, - IN UINT64 AttributeMask + IN UINT64 AttributeMask, + IN UINTN UserPageTable OPTIONAL ) { UINT32 TtEntryMask; @@ -584,6 +593,7 @@ ArmSetMemoryAttributes ( BaseAddress, Length, Attributes, - TtEntryMask + TtEntryMask, + UserPageTable ); } diff --git a/ArmPkg/Library/CpuArchLib/Arm/Mmu.c b/ArmPkg/Library/CpuArchLib/Arm/Mmu.c index 51199b9594..95a902861b 100644 --- a/ArmPkg/Library/CpuArchLib/Arm/Mmu.c +++ b/ArmPkg/Library/CpuArchLib/Arm/Mmu.c @@ -584,6 +584,7 @@ GetMemoryRegionPage ( On output, the base address of the region found. @param[out] RegionLength The length of the region found. @param[out] RegionAttributes The attributes of the region found. + @param[in] UserPageTable The base address of the User page table. @retval EFI_SUCCESS Region found @retval EFI_NOT_FOUND Region not found @@ -596,7 +597,8 @@ EFI_STATUS GetMemoryRegion ( IN OUT UINTN *BaseAddress, OUT UINTN *RegionLength, - OUT UINTN *RegionAttributes + OUT UINTN *RegionAttributes, + IN UINTN UserPageTable OPTIONAL ) { EFI_STATUS Status; @@ -612,7 +614,11 @@ GetMemoryRegion ( *RegionLength = 0; // Obtain page table base - FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress (); + if (UserPageTable == 0) { + FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress (); + } else { + FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)UserPageTable; + } // Calculate index into first level translation table for start of modification TableIndex = TT_DESCRIPTOR_SECTION_BASE_ADDRESS (*BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT; From 0bfc65587c25803b22c3e68bfc84d345a6914be2 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 19 Dec 2024 20:18:28 +0300 Subject: [PATCH 299/341] Ring3: Added support for ARM User page table. --- .../ArmExceptionLib/Arm/ExceptionSupport.S | 54 ++++++++++++++++++- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 16 +++++- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 22 +++----- MdePkg/Include/Arm/AsmMacroLib.h | 10 ++++ 4 files changed, 86 insertions(+), 16 deletions(-) diff --git a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S index 5d2a5617f8..257b0b05a9 100644 --- a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S @@ -11,6 +11,7 @@ #------------------------------------------------------------------------------ #include +#include /* @@ -59,8 +60,10 @@ GCC_ASM_EXPORT(CommonCExceptionHandler) #if !defined(__APPLE__) .fpu neon @ makes vpush/vpop assemble #endif -.align 5 +ASM_FUNC_ALIGN(ExceptionHandlerBase, 4096) + +.align 5 // // This code gets copied to the ARM vector table @@ -117,6 +120,8 @@ ASM_PFX(UndefinedInstructionEntry): bx R1 ASM_PFX(SoftwareInterruptEntry): + cpsid if + isb srsdb #0x13! @ Store return state on SVC stack @ We are already in SVC mode stmfd SP!,{LR} @ Store the link register for the current mode @@ -250,6 +255,24 @@ NoAdjustNeeded: vpush {d0-d15} @ save vstm registers in case they are used in optimizations #endif + ldr R5, [SP, #0x40] @ Saved Processor Status Register + and R5, R5, #0xF + cmp R5, 0 @ Check whether EL0 process was interrupted + bne NoTTBR0Switch + mrc p15,0,R5,c2,c0,0 @ R5 == TTBR0 + ADRL (R6, UserPageTable) + str R5, [R6] + and R5, R5, #0x7F @ Preserve TTBR0 attributes + LDRL (R6, ASM_PFX(CorePageTable)) + orr R6, R6, R5 @ Assign TTBR0 attributes + mcr p15,0,R6,c2,c0,0 @ TTBR0 == R6 + mcr p15,0,r0,c8,c7,0 @ TLBIALL, TLB Invalidate All. + mcr p15,0,r0,c7,c5,6 @ BPIALL, Branch Predictor Invalidate All. + dsb + isb + +NoTTBR0Switch: + mov R4, SP @ Save current SP tst R4, #4 subne SP, SP, #4 @ Adjust SP if not 8-byte aligned @@ -269,6 +292,19 @@ CommonCExceptionHandler ( mov SP, R4 @ Restore SP + ldr R4, [SP, #0x40] @ Saved Processor Status Register + and R4, R4, #0xF + cmp R4, 0 @ Check whether EL0 process was interrupted + bne NoTTBR0Switch2 + LDRL (R4, UserPageTable) + mcr p15,0,R4,c2,c0,0 @ TTBR0 == R4 + mcr p15,0,r0,c8,c7,0 @ TLBIALL, TLB Invalidate All. + mcr p15,0,r0,c7,c5,6 @ BPIALL, Branch Predictor Invalidate All. + dsb + isb + +NoTTBR0Switch2: + #if (FixedPcdGet32(PcdVFPEnabled)) vpop {d0-d15} #endif @@ -290,3 +326,19 @@ CommonCExceptionHandler ( add SP,SP,#0x20 @ Clear out the remaining stack space ldmfd SP!,{LR} @ restore the link register for this context rfefd SP! @ return from exception via srsfd stack slot + +ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096) + +.data + +.global ASM_PFX(CorePageTable) +.balign 4096 +ASM_PFX(CorePageTable): +.ds.l 1 + +UserPageTable: +.ds.l 1 + +.balign 4096 +Padding: +.ds.b 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index befe2d5f33..df40693d20 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -51,6 +51,7 @@ call: pop {R4-R8, LR} bx LR +ASM_FUNC_ALIGN(SysCallBase, 4096) //------------------------------------------------------------------------------ // EFI_STATUS // EFIAPI @@ -63,13 +64,15 @@ call: // (r2) gRing3EntryPoint // (r3) gCoreSysCallStackTop // -// (On Core Stack) &CoreSp +// (On Core Stack) &CoreSp, gUserPageTable //------------------------------------------------------------------------------ ASM_FUNC(ArmCallRing3) // Save registers. push {R4-R12, LR} // R6 is &CoreSp ldr R6, [SP, #0x28] + // R7 is gUserPageTable + ldr R7, [SP, #0x2C] #if (FixedPcdGet32(PcdVFPEnabled)) // Save vstm registers in case they are used in optimizations. @@ -94,10 +97,21 @@ ASM_FUNC(ArmCallRing3) str R5, [R6] mov SP, R3 + // Switch to UserPageTable. + mrc p15,0,R8,c2,c0,0 // R8 == TTBR0 + and R8, R8, #0x7F // Preserve Core TTBR0 attributes. + orr R7, R7, R8 // Assign Core attributes to UserPageTable. + mcr p15,0,R7,c2,c0,0 // TTBR0 == UserPageTable + mcr p15,0,r0,c8,c7,0 // TLBIALL, TLB Invalidate All. + mcr p15,0,r0,c7,c5,6 // BPIALL, Branch Predictor Invalidate All. + dsb + isb + push {R4} push {R2} rfefd SP +ASM_FUNC_ALIGN(SysCallEnd, 4096) //------------------------------------------------------------------------------ // VOID // EFIAPI diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index b090af890d..26984d4e58 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -12,7 +12,7 @@ #include "DxeMain.h" STATIC UINTN mCoreSp; -extern UINTN gUartBaseAddress; +UINTN gUserPageTable; EFI_STATUS EFIAPI @@ -21,7 +21,8 @@ ArmCallRing3 ( IN VOID *StackPointer, IN VOID *EntryPoint, IN VOID *SysCallStack, - IN VOID *CoreStack + IN VOID *CoreStack, + IN UINTN UserPageTable ); VOID @@ -52,6 +53,8 @@ SysCallBootService ( EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Physical; + ArmEnableInterrupts (); + Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, @@ -71,12 +74,6 @@ SysCallBootService ( // All remaining arguments are on User Stack. // CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN)); - - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP - ); ForbidSupervisorAccessToUserMemory (); Status = CallBootService ( @@ -89,11 +86,7 @@ SysCallBootService ( // CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); - SetUefiImageMemoryAttributes ( - gUartBaseAddress, - EFI_PAGE_SIZE, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); + ArmDisableInterrupts (); return Status; } @@ -141,6 +134,7 @@ InitializeMsr ( } InitializeSysCallHandler (SysCallBootService); + SetExceptionAddresses (NULL, 0); } VOID @@ -171,5 +165,5 @@ CallRing3 ( IN RING3_CALL_DATA *Data ) { - return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp); + return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp, gUserPageTable); } diff --git a/MdePkg/Include/Arm/AsmMacroLib.h b/MdePkg/Include/Arm/AsmMacroLib.h index 2493a15b7b..c15000245d 100644 --- a/MdePkg/Include/Arm/AsmMacroLib.h +++ b/MdePkg/Include/Arm/AsmMacroLib.h @@ -21,6 +21,16 @@ #define ASM_FUNC(Name) _ASM_FUNC(ASM_PFX(Name), .text. ## Name) +#define _ASM_FUNC_ALIGN(Name, Section, Align) \ + .global Name ; \ + .section #Section, "ax" ; \ + .type Name, %function ; \ + .balign Align ; \ + Name: + +#define ASM_FUNC_ALIGN(Name, Align) \ + _ASM_FUNC_ALIGN(ASM_PFX(Name), .text. ## Name, Align) + #define MOV32(Reg, Val) \ movw Reg, #(Val) & 0xffff ; \ movt Reg, #(Val) >> 16 From 84dd89f82a3dd7e14afc42bb583d3c0a36082474 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 23 Dec 2024 11:47:33 +0300 Subject: [PATCH 300/341] ArmPkg: Fixed compilation. --- ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 5 +---- ArmPkg/Library/CpuArchLib/CpuMmuCommon.c | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index fc06427593..cd1d5dd00e 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -809,14 +809,11 @@ ArmMakeUserPageTableTemplate ( { VOID *TranslationTable; UINTN MaxAddressBits; - UINT64 MaxAddress; UINTN T0SZ; UINTN RootTableEntryCount; EFI_STATUS Status; - MaxAddressBits = MIN (ArmGetPhysicalAddressBits (), MAX_VA_BITS); - MaxAddress = LShiftU64 (1ULL, MaxAddressBits) - 1; - + MaxAddressBits = MIN (ArmGetPhysicalAddressBits (), MAX_VA_BITS); T0SZ = 64 - MaxAddressBits; RootTableEntryCount = GetRootTableEntryCount (T0SZ); diff --git a/ArmPkg/Library/CpuArchLib/CpuMmuCommon.c b/ArmPkg/Library/CpuArchLib/CpuMmuCommon.c index 7750881191..0e4e130fd5 100644 --- a/ArmPkg/Library/CpuArchLib/CpuMmuCommon.c +++ b/ArmPkg/Library/CpuArchLib/CpuMmuCommon.c @@ -284,7 +284,8 @@ CpuGetMemoryAttributes ( Status = GetMemoryRegion (&RegionBaseAddress, &RegionLength, &RegionArmAttributes, 0); if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; + *Attributes = 0; + return Status; } *Attributes = RegionAttributeToGcdAttribute (RegionArmAttributes); From 1d8efe6762bb294634696177fd1b8ce1eaae50ec Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 9 Jan 2025 11:51:06 +0300 Subject: [PATCH 301/341] SysCall: Fixed line endings. --- .../Core/Dxe/SysCall/Initialization.c | 198 +++++++++--------- 1 file changed, 99 insertions(+), 99 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index a175d47247..171f70f962 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -232,36 +232,36 @@ InitializeUserPageTable ( EFI_MEMORY_XP | EFI_MEMORY_USER ); - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - (UINTN)gRing3Interfaces, - EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - (UINTN)gRing3CallStackBase, - EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - - SectionAddress = mDxeRing3->StartAddress; - for (Index = 0; Index < mDxeRing3->NumSegments; Index++) { - ImageRecordSegment = &mDxeRing3->Segments[Index]; - - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - SectionAddress, - ImageRecordSegment->Size, - ImageRecordSegment->Attributes | EFI_MEMORY_USER - ); - - SectionAddress += ImageRecordSegment->Size; - } + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)gRing3Interfaces, + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)gRing3CallStackBase, + EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + SectionAddress = mDxeRing3->StartAddress; + for (Index = 0; Index < mDxeRing3->NumSegments; Index++) { + ImageRecordSegment = &mDxeRing3->Segments[Index]; + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + SectionAddress, + ImageRecordSegment->Size, + ImageRecordSegment->Attributes | EFI_MEMORY_USER + ); + + SectionAddress += ImageRecordSegment->Size; + } // // Map CoreBootServices, gCoreSysCallStackBase @@ -274,61 +274,61 @@ InitializeUserPageTable ( EFI_MEMORY_RO ); - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - (UINTN)gCoreSysCallStackBase, - EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, - EFI_MEMORY_XP - ); - + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)gCoreSysCallStackBase, + EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, + EFI_MEMORY_XP + ); + // // Map ExceptionHandlers, ExceptionStacks, Idt // - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - mExceptionAddresses->ExceptionHandlerBase, - mExceptionAddresses->ExceptionHandlerSize, - EFI_MEMORY_RO - ); - - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - mExceptionAddresses->ExceptionDataBase, - SIZE_4KB, - EFI_MEMORY_XP - ); - -#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) - IA32_DESCRIPTOR IdtDescriptor; - - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - (UINTN)&gCorePageTable, - SIZE_4KB, - EFI_MEMORY_RO | EFI_MEMORY_XP - ); - - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - mExceptionAddresses->ExceptionStackBase, - mExceptionAddresses->ExceptionStackSize, - EFI_MEMORY_XP - ); - - AsmReadIdtr (&IdtDescriptor); - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - IdtDescriptor.Base, - SIZE_4KB, - EFI_MEMORY_RO | EFI_MEMORY_XP - ); - + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionHandlerBase, + mExceptionAddresses->ExceptionHandlerSize, + EFI_MEMORY_RO + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionDataBase, + SIZE_4KB, + EFI_MEMORY_XP + ); + +#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) + IA32_DESCRIPTOR IdtDescriptor; + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)&gCorePageTable, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionStackBase, + mExceptionAddresses->ExceptionStackSize, + EFI_MEMORY_XP + ); + + AsmReadIdtr (&IdtDescriptor); + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + IdtDescriptor.Base, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + // // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() // @@ -340,23 +340,23 @@ InitializeUserPageTable ( EFI_MEMORY_XP | EFI_MEMORY_USER ); #elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - mConfigurationTable, - ALIGN_VALUE (mConfigurationTableSize, EFI_PAGE_SIZE), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - // - // Necessary fix for DEBUG printings. - // - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - gUartBaseAddress, - SIZE_4KB, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mConfigurationTable, + ALIGN_VALUE (mConfigurationTableSize, EFI_PAGE_SIZE), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + // + // Necessary fix for DEBUG printings. + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + gUartBaseAddress, + SIZE_4KB, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); #endif // From d5fbfef345c0279952bf7c1fad67ca553fa610b3 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 9 Jan 2025 15:42:04 +0300 Subject: [PATCH 302/341] SysCall: Refactored Core wrappers to allow support for multiple User space drivers. --- MdeModulePkg/Core/Dxe/Image/Image.c | 3 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 22 +- .../Core/Dxe/SysCall/SupportedProtocols.c | 385 ++++++++++-------- .../Core/Dxe/SysCall/SupportedProtocols.h | 13 +- 4 files changed, 240 insertions(+), 183 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 818c30f61a..e95ccd62ab 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1446,7 +1446,6 @@ CoreLoadImageCommon ( if ((gRing3Data != NULL) && Image->IsUserImage) { Image->UserPageTable = InitializeUserPageTable (Image); - gUserPageTable = Image->UserPageTable; } RegisterMemoryProfileImage ( @@ -1704,6 +1703,8 @@ CoreStartImage ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gUserPageTable = Image->UserPageTable; + Image->Status = GoToRing3 ( 2, (VOID *)Image->EntryPoint, diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 683edef44a..92ec9ba360 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -1,6 +1,6 @@ /** @file - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause **/ @@ -302,6 +302,7 @@ CallBootService ( EFI_HANDLE CoreHandle; UINT32 PagesNumber; EFI_PHYSICAL_ADDRESS Ring3Pages; + USER_SPACE_DRIVER *UserDriver; EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem; @@ -465,6 +466,15 @@ CallBootService ( ASSERT ((Attributes & EFI_MEMORY_USER) != 0); CoreArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index + 1]); + // + // TODO: Check everywhere that Allocated != NULL + // + UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); + UserDriver->CoreWrapper = CoreArgList[Index + 1]; + UserDriver->UserSpaceDriver = UserArgList[Index + 1]; + UserDriver->UserPageTable = gUserPageTable; + + InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] + sizeof (VOID *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -478,23 +488,13 @@ CallBootService ( if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiDriverBindingProtocolGuid)) { CoreDriverBinding = (EFI_DRIVER_BINDING_PROTOCOL *)CoreArgList[Index + 1]; - mRing3DriverBindingProtocol.Supported = CoreDriverBinding->Supported; - mRing3DriverBindingProtocol.Start = CoreDriverBinding->Start; - mRing3DriverBindingProtocol.Stop = CoreDriverBinding->Stop; - CoreDriverBinding->Supported = CoreDriverBindingSupported; CoreDriverBinding->Start = CoreDriverBindingStart; CoreDriverBinding->Stop = CoreDriverBindingStop; } else if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiSimpleFileSystemProtocolGuid)) { CoreSimpleFileSystem = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)CoreArgList[Index + 1]; - mRing3SimpleFileSystemProtocol.OpenVolume = CoreSimpleFileSystem->OpenVolume; - CoreSimpleFileSystem->OpenVolume = CoreOpenVolume; - - AllowSupervisorAccessToUserMemory (); - mRing3SimpleFileSystemPointer = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)UserArgList[Index + 1]; - ForbidSupervisorAccessToUserMemory (); } } diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 286ba9f834..f7ccad525b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -1,22 +1,14 @@ /** @file - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause **/ #include "DxeMain.h" +#include "SupportedProtocols.h" -EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; -EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; -EFI_FILE_PROTOCOL mRing3FileProtocol; - -EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; - -typedef struct { - EFI_FILE_PROTOCOL Protocol; - EFI_FILE_PROTOCOL *Ring3File; -} RING3_EFI_FILE_PROTOCOL; +LIST_ENTRY mUserSpaceDriversHead = INITIALIZE_LIST_HEAD_VARIABLE (mUserSpaceDriversHead); EFI_STATUS EFIAPI @@ -66,31 +58,24 @@ GoToRing3 ( } STATIC -VOID * +USER_SPACE_DRIVER * EFIAPI -Ring3Copy ( - IN VOID *Core, - IN UINT32 Size +FindUserSpaceDriver ( + IN VOID *CoreWrapper ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Ring3; + LIST_ENTRY *Link; + USER_SPACE_DRIVER *UserDriver; - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - 1, - &Ring3 - ); - if (EFI_ERROR (Status)) { - return NULL; - } + for (Link = mUserSpaceDriversHead.ForwardLink; Link != &mUserSpaceDriversHead; Link = Link->ForwardLink) { + UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link); - AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)(UINTN)Ring3, Core, Size); - ForbidSupervisorAccessToUserMemory (); + if (UserDriver->CoreWrapper == CoreWrapper) { + return UserDriver; + } + } - return (VOID *)(UINTN)Ring3; + return NULL; } EFI_STATUS @@ -101,23 +86,28 @@ CoreDriverBindingSupported ( IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ) { - EFI_STATUS Status; + EFI_STATUS Status; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; - This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); - if (This == NULL) { - return EFI_OUT_OF_RESOURCES; - } + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + AllowSupervisorAccessToUserMemory (); + EntryPoint = (VOID *)This->Supported; + ForbidSupervisorAccessToUserMemory (); Status = GoToRing3 ( 3, - (VOID *)mRing3DriverBindingProtocol.Supported, + EntryPoint, This, ControllerHandle, RemainingDevicePath ); - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); - return Status; } @@ -129,23 +119,28 @@ CoreDriverBindingStart ( IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ) { - EFI_STATUS Status; + EFI_STATUS Status; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; - This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); - if (This == NULL) { - return EFI_OUT_OF_RESOURCES; - } + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + AllowSupervisorAccessToUserMemory (); + EntryPoint = (VOID *)This->Start; + ForbidSupervisorAccessToUserMemory (); Status = GoToRing3 ( 3, - (VOID *)mRing3DriverBindingProtocol.Start, + EntryPoint, This, ControllerHandle, RemainingDevicePath ); - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); - return Status; } @@ -158,24 +153,29 @@ CoreDriverBindingStop ( IN EFI_HANDLE *ChildHandleBuffer OPTIONAL ) { - EFI_STATUS Status; + EFI_STATUS Status; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; - This = Ring3Copy (This, sizeof (EFI_DRIVER_BINDING_PROTOCOL)); - if (This == NULL) { - return EFI_OUT_OF_RESOURCES; - } + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + AllowSupervisorAccessToUserMemory (); + EntryPoint = (VOID *)This->Stop; + ForbidSupervisorAccessToUserMemory (); Status = GoToRing3 ( 4, - (VOID *)mRing3DriverBindingProtocol.Stop, + EntryPoint, This, ControllerHandle, NumberOfChildren, ChildHandleBuffer ); - CoreFreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)This, 1); - return Status; } @@ -186,18 +186,27 @@ CoreFileClose ( IN EFI_FILE_PROTOCOL *This ) { - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; + EFI_STATUS Status; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); - File = (RING3_EFI_FILE_PROTOCOL *)This; + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + AllowSupervisorAccessToUserMemory (); + EntryPoint = (VOID *)This->Close; + ForbidSupervisorAccessToUserMemory (); Status = GoToRing3 ( 1, - (VOID *)mRing3FileProtocol.Close, - File->Ring3File + EntryPoint, + This ); - FreePool (This); + FreePool (UserDriver->CoreWrapper); return Status; } @@ -221,21 +230,20 @@ CoreFileRead ( OUT VOID *Buffer ) { - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - UINTN *Ring3BufferSize; - VOID *Ring3Buffer; - EFI_PHYSICAL_ADDRESS Ring3Pages; - UINT32 PagesNumber; + EFI_STATUS Status; + UINTN *Ring3BufferSize; + VOID *Ring3Buffer; + EFI_PHYSICAL_ADDRESS Ring3Pages; + UINT32 PagesNumber; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; if ((This == NULL) || (BufferSize == NULL)) { return EFI_INVALID_PARAMETER; } - File = (RING3_EFI_FILE_PROTOCOL *)This; Ring3Buffer = NULL; Ring3Pages = 0; - PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize); Status = CoreAllocatePages ( @@ -250,8 +258,15 @@ CoreFileRead ( Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + AllowSupervisorAccessToUserMemory (); *Ring3BufferSize = *BufferSize; + EntryPoint = (VOID *)This->Read; ForbidSupervisorAccessToUserMemory (); if (Buffer != NULL) { @@ -260,8 +275,8 @@ CoreFileRead ( Status = GoToRing3 ( 3, - (VOID *)mRing3FileProtocol.Read, - File->Ring3File, + EntryPoint, + This, Ring3BufferSize, Ring3Buffer ); @@ -299,15 +314,24 @@ CoreFileSetPosition ( IN UINT64 Position ) { - RING3_EFI_FILE_PROTOCOL *File; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; - File = (RING3_EFI_FILE_PROTOCOL *)This; + AllowSupervisorAccessToUserMemory (); + EntryPoint = (VOID *)This->SetPosition; + ForbidSupervisorAccessToUserMemory (); #if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) return GoToRing3 ( 2, - (VOID *)mRing3FileProtocol.SetPosition, - File->Ring3File, + EntryPoint, + This, Position ); #elif defined (MDE_CPU_IA32) @@ -316,8 +340,8 @@ CoreFileSetPosition ( // return GoToRing3 ( 3, - (VOID *)mRing3FileProtocol.SetPosition, - File->Ring3File, + EntryPoint, + This, Position ); #elif defined (MDE_CPU_ARM) @@ -327,8 +351,8 @@ CoreFileSetPosition ( // return GoToRing3 ( 4, - (VOID *)mRing3FileProtocol.SetPosition, - File->Ring3File, + EntryPoint, + This, Position ); #endif @@ -343,17 +367,15 @@ CoreFileGetPosition ( OUT UINT64 *Position ) { - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - EFI_PHYSICAL_ADDRESS Ring3Position; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Ring3Position; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; if ((This == NULL) || (Position == NULL)) { return EFI_INVALID_PARAMETER; } - File = (RING3_EFI_FILE_PROTOCOL *)This; - Ring3Position = 0; - Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, @@ -364,14 +386,21 @@ CoreFileGetPosition ( return Status; } + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + AllowSupervisorAccessToUserMemory (); *(UINT64 *)(UINTN)Ring3Position = *Position; + EntryPoint = (VOID *)This->GetPosition; ForbidSupervisorAccessToUserMemory (); Status = GoToRing3 ( 2, - (VOID *)mRing3FileProtocol.GetPosition, - File->Ring3File, + EntryPoint, + This, Ring3Position ); @@ -394,19 +423,19 @@ CoreFileGetInfo ( OUT VOID *Buffer ) { - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - EFI_GUID *Ring3InformationType; - UINTN *Ring3BufferSize; - VOID *Ring3Buffer; - EFI_PHYSICAL_ADDRESS Ring3Pages; - UINT32 PagesNumber; + EFI_STATUS Status; + EFI_GUID *Ring3InformationType; + UINTN *Ring3BufferSize; + VOID *Ring3Buffer; + EFI_PHYSICAL_ADDRESS Ring3Pages; + UINT32 PagesNumber; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; if ((This == NULL) || (BufferSize == NULL)) { return EFI_INVALID_PARAMETER; } - File = (RING3_EFI_FILE_PROTOCOL *)This; Ring3Buffer = NULL; Ring3InformationType = NULL; Ring3Pages = 0; @@ -425,8 +454,15 @@ CoreFileGetInfo ( Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + AllowSupervisorAccessToUserMemory (); *Ring3BufferSize = *BufferSize; + EntryPoint = (VOID *)This->GetInfo; ForbidSupervisorAccessToUserMemory (); if (Buffer != NULL) { @@ -443,8 +479,8 @@ CoreFileGetInfo ( Status = GoToRing3 ( 4, - (VOID *)mRing3FileProtocol.GetInfo, - File->Ring3File, + EntryPoint, + This, Ring3InformationType, Ring3BufferSize, Ring3Buffer @@ -545,19 +581,19 @@ CoreFileOpen ( IN UINT64 Attributes ) { - EFI_STATUS Status; - RING3_EFI_FILE_PROTOCOL *File; - RING3_EFI_FILE_PROTOCOL *NewFile; - EFI_FILE_PROTOCOL **Ring3NewHandle; - CHAR16 *Ring3FileName; - EFI_PHYSICAL_ADDRESS Ring3Pages; - UINT32 PagesNumber; + EFI_STATUS Status; + EFI_FILE_PROTOCOL *NewFile; + EFI_FILE_PROTOCOL **Ring3NewHandle; + CHAR16 *Ring3FileName; + EFI_PHYSICAL_ADDRESS Ring3Pages; + UINT32 PagesNumber; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; if ((This == NULL) || (NewHandle == NULL) || (FileName == NULL)) { return EFI_INVALID_PARAMETER; } - File = (RING3_EFI_FILE_PROTOCOL *)This; Ring3NewHandle = NULL; Ring3FileName = NULL; Ring3Pages = 0; @@ -578,8 +614,15 @@ CoreFileOpen ( Ring3NewHandle = (EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages; Ring3FileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages + 1); + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + AllowSupervisorAccessToUserMemory (); - Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName); + Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName); + EntryPoint = (VOID *)This->Open; ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { *NewHandle = NULL; @@ -590,8 +633,8 @@ CoreFileOpen ( #if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) Status = GoToRing3 ( 5, - (VOID *)mRing3FileProtocol.Open, - File->Ring3File, + EntryPoint, + This, Ring3NewHandle, Ring3FileName, OpenMode, @@ -603,8 +646,8 @@ CoreFileOpen ( // Status = GoToRing3 ( 7, - (VOID *)mRing3FileProtocol.Open, - File->Ring3File, + EntryPoint, + This, Ring3NewHandle, Ring3FileName, OpenMode, @@ -619,8 +662,8 @@ CoreFileOpen ( // Status = GoToRing3 ( 8, - (VOID *)mRing3FileProtocol.Open, - File->Ring3File, + EntryPoint, + This, Ring3NewHandle, Ring3FileName, OpenMode, @@ -633,33 +676,39 @@ CoreFileOpen ( return Status; } - NewFile = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); + NewFile = AllocatePool (sizeof (EFI_FILE_PROTOCOL)); if (NewFile == NULL) { *NewHandle = NULL; CoreFreePages (Ring3Pages, PagesNumber); return EFI_OUT_OF_RESOURCES; } - NewFile->Protocol.Revision = mRing3FileProtocol.Revision; - NewFile->Protocol.Open = CoreFileOpen; - NewFile->Protocol.Close = CoreFileClose; - NewFile->Protocol.Delete = CoreFileDelete; - NewFile->Protocol.Read = CoreFileRead; - NewFile->Protocol.Write = CoreFileWrite; - NewFile->Protocol.GetPosition = CoreFileGetPosition; - NewFile->Protocol.SetPosition = CoreFileSetPosition; - NewFile->Protocol.GetInfo = CoreFileGetInfo; - NewFile->Protocol.SetInfo = CoreFileSetInfo; - NewFile->Protocol.Flush = CoreFileFlush; - NewFile->Protocol.OpenEx = CoreFileOpenEx; - NewFile->Protocol.ReadEx = CoreFileReadEx; - NewFile->Protocol.WriteEx = CoreFileWriteEx; - NewFile->Protocol.FlushEx = CoreFileFlushEx; + UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); + UserDriver->CoreWrapper = NewFile; + UserDriver->UserPageTable = gUserPageTable; AllowSupervisorAccessToUserMemory (); - NewFile->Ring3File = *Ring3NewHandle; + UserDriver->UserSpaceDriver = *Ring3NewHandle; + NewFile->Revision = (*Ring3NewHandle)->Revision; ForbidSupervisorAccessToUserMemory (); + InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link); + + NewFile->Open = CoreFileOpen; + NewFile->Close = CoreFileClose; + NewFile->Delete = CoreFileDelete; + NewFile->Read = CoreFileRead; + NewFile->Write = CoreFileWrite; + NewFile->GetPosition = CoreFileGetPosition; + NewFile->SetPosition = CoreFileSetPosition; + NewFile->GetInfo = CoreFileGetInfo; + NewFile->SetInfo = CoreFileSetInfo; + NewFile->Flush = CoreFileFlush; + NewFile->OpenEx = CoreFileOpenEx; + NewFile->ReadEx = CoreFileReadEx; + NewFile->WriteEx = CoreFileWriteEx; + NewFile->FlushEx = CoreFileFlushEx; + *NewHandle = (EFI_FILE_PROTOCOL *)NewFile; CoreFreePages (Ring3Pages, PagesNumber); @@ -674,15 +723,27 @@ CoreOpenVolume ( OUT EFI_FILE_PROTOCOL **Root ) { - EFI_STATUS Status; - EFI_FILE_PROTOCOL **Ring3Root; - RING3_EFI_FILE_PROTOCOL *File; - EFI_PHYSICAL_ADDRESS Physical; + EFI_STATUS Status; + EFI_FILE_PROTOCOL **Ring3Root; + EFI_FILE_PROTOCOL *File; + EFI_PHYSICAL_ADDRESS Physical; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; if (Root == NULL) { return EFI_INVALID_PARAMETER; } + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + AllowSupervisorAccessToUserMemory (); + EntryPoint = (VOID *)This->OpenVolume; + ForbidSupervisorAccessToUserMemory (); + Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, @@ -698,8 +759,8 @@ CoreOpenVolume ( Status = GoToRing3 ( 2, - (VOID *)mRing3SimpleFileSystemProtocol.OpenVolume, - mRing3SimpleFileSystemPointer, + EntryPoint, + This, Ring3Root ); if (EFI_ERROR (Status)) { @@ -708,48 +769,38 @@ CoreOpenVolume ( return Status; } - File = AllocatePool (sizeof (RING3_EFI_FILE_PROTOCOL)); + File = AllocatePool (sizeof (EFI_FILE_PROTOCOL)); if (File == NULL) { *Root = NULL; CoreFreePages (Physical, 1); return EFI_OUT_OF_RESOURCES; } + UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); + UserDriver->CoreWrapper = File; + UserDriver->UserPageTable = gUserPageTable; + AllowSupervisorAccessToUserMemory (); - mRing3FileProtocol.Revision = (*Ring3Root)->Revision; - mRing3FileProtocol.Open = (*Ring3Root)->Open; - mRing3FileProtocol.Close = (*Ring3Root)->Close; - mRing3FileProtocol.Delete = (*Ring3Root)->Delete; - mRing3FileProtocol.Read = (*Ring3Root)->Read; - mRing3FileProtocol.Write = (*Ring3Root)->Write; - mRing3FileProtocol.GetPosition = (*Ring3Root)->GetPosition; - mRing3FileProtocol.SetPosition = (*Ring3Root)->SetPosition; - mRing3FileProtocol.GetInfo = (*Ring3Root)->GetInfo; - mRing3FileProtocol.SetInfo = (*Ring3Root)->SetInfo; - mRing3FileProtocol.Flush = (*Ring3Root)->Flush; - mRing3FileProtocol.OpenEx = (*Ring3Root)->OpenEx; - mRing3FileProtocol.ReadEx = (*Ring3Root)->ReadEx; - mRing3FileProtocol.WriteEx = (*Ring3Root)->WriteEx; - mRing3FileProtocol.FlushEx = (*Ring3Root)->FlushEx; - - File->Ring3File = *Ring3Root; + UserDriver->UserSpaceDriver = *Ring3Root; + File->Revision = (*Ring3Root)->Revision; ForbidSupervisorAccessToUserMemory (); - File->Protocol.Revision = mRing3FileProtocol.Revision; - File->Protocol.Open = CoreFileOpen; - File->Protocol.Close = CoreFileClose; - File->Protocol.Delete = CoreFileDelete; - File->Protocol.Read = CoreFileRead; - File->Protocol.Write = CoreFileWrite; - File->Protocol.GetPosition = CoreFileGetPosition; - File->Protocol.SetPosition = CoreFileSetPosition; - File->Protocol.GetInfo = CoreFileGetInfo; - File->Protocol.SetInfo = CoreFileSetInfo; - File->Protocol.Flush = CoreFileFlush; - File->Protocol.OpenEx = CoreFileOpenEx; - File->Protocol.ReadEx = CoreFileReadEx; - File->Protocol.WriteEx = CoreFileWriteEx; - File->Protocol.FlushEx = CoreFileFlushEx; + InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link); + + File->Open = CoreFileOpen; + File->Close = CoreFileClose; + File->Delete = CoreFileDelete; + File->Read = CoreFileRead; + File->Write = CoreFileWrite; + File->GetPosition = CoreFileGetPosition; + File->SetPosition = CoreFileSetPosition; + File->GetInfo = CoreFileGetInfo; + File->SetInfo = CoreFileSetInfo; + File->Flush = CoreFileFlush; + File->OpenEx = CoreFileOpenEx; + File->ReadEx = CoreFileReadEx; + File->WriteEx = CoreFileWriteEx; + File->FlushEx = CoreFileFlushEx; *Root = (EFI_FILE_PROTOCOL *)File; diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h index 235d62872d..0108bfb16f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -1,6 +1,6 @@ /** @file - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause **/ @@ -11,9 +11,14 @@ #include #include -extern EFI_DRIVER_BINDING_PROTOCOL mRing3DriverBindingProtocol; -extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mRing3SimpleFileSystemProtocol; -extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mRing3SimpleFileSystemPointer; +typedef struct { + VOID *CoreWrapper; + VOID *UserSpaceDriver; + UINTN UserPageTable; + LIST_ENTRY Link; +} USER_SPACE_DRIVER; + +extern LIST_ENTRY mUserSpaceDriversHead; EFI_STATUS EFIAPI From 780d48661e39928f223f6b5d1ef804ea81f61fbd Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 9 Jan 2025 16:07:06 +0300 Subject: [PATCH 303/341] CpuExceptionHandlerLibNull: Added dummy functions to fix MdeModulePkg compilation. --- .../CpuExceptionHandlerLibNull.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c b/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c index 74908a379b..52f46db3dc 100644 --- a/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c +++ b/MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.c @@ -104,3 +104,21 @@ InitializeSeparateExceptionStacks ( { return EFI_UNSUPPORTED; } + +EXCEPTION_ADDRESSES * +EFIAPI +GetExceptionAddresses ( + VOID + ) +{ + return NULL; +} + +VOID +EFIAPI +SetExceptionAddresses ( + IN VOID *Buffer, + IN UINTN BufferSize + ) +{ +} From 9c6d3c897efd5f99d97d4ad1cc90b67230cf632b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 9 Jan 2025 19:49:16 +0300 Subject: [PATCH 304/341] SysCall: Added support for UnicodeCollationProtocol in User space. --- ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 4 +- MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 22 ++ .../Core/Dxe/SysCall/SupportedProtocols.c | 313 ++++++++++++++++++ .../Core/Dxe/SysCall/SupportedProtocols.h | 48 +++ OvmfPkg/OvmfPkgIa32.fdf | 4 +- OvmfPkg/OvmfPkgIa32X64.fdf | 4 +- OvmfPkg/OvmfPkgX64.fdf | 4 +- 8 files changed, 392 insertions(+), 8 deletions(-) diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc index 270e0b87a1..1a60f4566d 100644 --- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc +++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc @@ -88,9 +88,9 @@ APRIORI DXE { # INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf - INF USER FatPkg/EnhancedFatDxe/Fat.inf + INF FatPkg/EnhancedFatDxe/Fat.inf INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf - INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 3533239c73..9dc23efd38 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -190,6 +190,7 @@ gEfiDiskIoProtocolGuid ## SOMETIMES_CONSUMES gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES gEfiUnicodeCollationProtocolGuid ## SOMETIMES_CONSUMES + gEfiUnicodeCollation2ProtocolGuid ## SOMETIMES_CONSUMES # Arch Protocols gEfiBdsArchProtocolGuid ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 92ec9ba360..deb8ef83c0 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -154,6 +154,11 @@ FindGuid ( *Core = &gEfiGlobalVariableGuid; + } else if (CompareGuid (Ring3, &gEfiUnicodeCollation2ProtocolGuid)) { + + *Core = &gEfiUnicodeCollation2ProtocolGuid; + *CoreSize = sizeof (EFI_UNICODE_COLLATION_PROTOCOL); + } else { DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol - %g.\n", Ring3)); return EFI_NOT_FOUND; @@ -306,6 +311,7 @@ CallBootService ( EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem; + EFI_UNICODE_COLLATION_PROTOCOL *CoreUnicodeCollation; EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_DISK_IO_PROTOCOL *DiskIo; @@ -495,6 +501,22 @@ CallBootService ( CoreSimpleFileSystem = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)CoreArgList[Index + 1]; CoreSimpleFileSystem->OpenVolume = CoreOpenVolume; + } else if ((CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiUnicodeCollationProtocolGuid)) + || (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiUnicodeCollation2ProtocolGuid))) { + CoreUnicodeCollation = (EFI_UNICODE_COLLATION_PROTOCOL *)CoreArgList[Index + 1]; + + CoreUnicodeCollation->StriColl = CoreUnicodeCollationStriColl; + CoreUnicodeCollation->MetaiMatch = CoreUnicodeCollationMetaiMatch; + CoreUnicodeCollation->StrLwr = CoreUnicodeCollationStrLwr; + CoreUnicodeCollation->StrUpr = CoreUnicodeCollationStrUpr; + CoreUnicodeCollation->FatToStr = CoreUnicodeCollationFatToStr; + CoreUnicodeCollation->StrToFat = CoreUnicodeCollationStrToFat; + AllowSupervisorAccessToUserMemory (); + CoreUnicodeCollation->SupportedLanguages = AllocateCopyPool ( + AsciiStrSize (CoreUnicodeCollation->SupportedLanguages), + (VOID *)CoreUnicodeCollation->SupportedLanguages + ); + ForbidSupervisorAccessToUserMemory (); } } diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index f7ccad525b..de06170e07 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -808,3 +808,316 @@ CoreOpenVolume ( return Status; } + +INTN +EFIAPI +CoreUnicodeCollationStriColl ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *Str1, + IN CHAR16 *Str2 + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS UserMem; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + UINTN Size1; + UINTN Size2; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + Size1 = StrSize (Str1); + Size2 = StrSize (Str2); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (Size1 + Size2), + &UserMem + ); + if (EFI_ERROR (Status)) { + return 0; + } + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)(UINTN)UserMem, (VOID *)Str1, Size1); + CopyMem ((VOID *)((UINTN)UserMem + Size1), (VOID *)Str2, Size2); + EntryPoint = (VOID *)This->StriColl; + ForbidSupervisorAccessToUserMemory (); + + Status = GoToRing3 ( + 3, + EntryPoint, + This, + (UINTN)UserMem, + (UINTN)UserMem + Size1 + ); + + CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1 + Size2)); + + return (INTN)Status; +} + +BOOLEAN +EFIAPI +CoreUnicodeCollationMetaiMatch ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS UserMem; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + UINTN Size1; + UINTN Size2; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + Size1 = StrSize (String); + Size2 = StrSize (Pattern); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (Size1 + Size2), + &UserMem + ); + if (EFI_ERROR (Status)) { + return FALSE; + } + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)(UINTN)UserMem, (VOID *)String, Size1); + CopyMem ((VOID *)((UINTN)UserMem + Size1), (VOID *)Pattern, Size2); + EntryPoint = (VOID *)This->MetaiMatch; + ForbidSupervisorAccessToUserMemory (); + + Status = GoToRing3 ( + 3, + EntryPoint, + This, + (UINTN)UserMem, + (UINTN)UserMem + Size1 + ); + + CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1 + Size2)); + + return (BOOLEAN)Status; +} + +VOID +EFIAPI +CoreUnicodeCollationStrLwr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS UserMem; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + UINTN Size1; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + Size1 = StrSize (Str); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (Size1), + &UserMem + ); + if (EFI_ERROR (Status)) { + return; + } + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)(UINTN)UserMem, (VOID *)Str, Size1); + EntryPoint = (VOID *)This->StrLwr; + ForbidSupervisorAccessToUserMemory (); + + Status = GoToRing3 ( + 2, + EntryPoint, + This, + (UINTN)UserMem + ); + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)Str, (VOID *)(UINTN)UserMem, Size1); + ForbidSupervisorAccessToUserMemory (); + + CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1)); +} + +VOID +EFIAPI +CoreUnicodeCollationStrUpr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS UserMem; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + UINTN Size1; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + Size1 = StrSize (Str); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (Size1), + &UserMem + ); + if (EFI_ERROR (Status)) { + return; + } + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)(UINTN)UserMem, (VOID *)Str, Size1); + EntryPoint = (VOID *)This->StrUpr; + ForbidSupervisorAccessToUserMemory (); + + Status = GoToRing3 ( + 2, + EntryPoint, + This, + (UINTN)UserMem + ); + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)Str, (VOID *)(UINTN)UserMem, Size1); + ForbidSupervisorAccessToUserMemory (); + + CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1)); +} + +VOID +EFIAPI +CoreUnicodeCollationFatToStr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS UserMem; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (FatSize * 3), + &UserMem + ); + if (EFI_ERROR (Status)) { + return; + } + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)(UINTN)UserMem, (VOID *)Fat, FatSize); + EntryPoint = (VOID *)This->FatToStr; + ForbidSupervisorAccessToUserMemory (); + + Status = GoToRing3 ( + 4, + EntryPoint, + This, + FatSize, + (UINTN)UserMem, + (UINTN)UserMem + FatSize + ); + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)String, (VOID *)((UINTN)UserMem + FatSize), FatSize * 2); + ForbidSupervisorAccessToUserMemory (); + + CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (FatSize * 3)); +} + +BOOLEAN +EFIAPI +CoreUnicodeCollationStrToFat ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS UserMem; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + UINTN Size1; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + Size1 = StrSize (String); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (FatSize + Size1), + &UserMem + ); + if (EFI_ERROR (Status)) { + return FALSE; + } + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)(UINTN)UserMem, (VOID *)String, Size1); + EntryPoint = (VOID *)This->StrToFat; + ForbidSupervisorAccessToUserMemory (); + + Status = GoToRing3 ( + 4, + EntryPoint, + This, + (UINTN)UserMem, + FatSize, + (UINTN)UserMem + Size1 + ); + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)Fat, (VOID *)((UINTN)UserMem + Size1), FatSize); + ForbidSupervisorAccessToUserMemory (); + + CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (FatSize + Size1)); + + return (BOOLEAN)Status; +} diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h index 0108bfb16f..4507db4a89 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -51,3 +51,51 @@ CoreOpenVolume ( IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, OUT EFI_FILE_PROTOCOL **Root ); + +INTN +EFIAPI +CoreUnicodeCollationStriColl ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *Str1, + IN CHAR16 *Str2 + ); + +BOOLEAN +EFIAPI +CoreUnicodeCollationMetaiMatch ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ); + +VOID +EFIAPI +CoreUnicodeCollationStrLwr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ); + +VOID +EFIAPI +CoreUnicodeCollationStrUpr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ); + +VOID +EFIAPI +CoreUnicodeCollationFatToStr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ); + +BOOLEAN +EFIAPI +CoreUnicodeCollationStrToFat ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ); diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index ee98e905b9..b1f0b66f2b 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -264,7 +264,7 @@ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf -INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf @@ -290,7 +290,7 @@ INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf -INF USER FatPkg/EnhancedFatDxe/Fat.inf +INF FatPkg/EnhancedFatDxe/Fat.inf INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index f3d5243bde..5e7f2a9d79 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -266,7 +266,7 @@ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf -INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf @@ -292,7 +292,7 @@ INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf -INF USER FatPkg/EnhancedFatDxe/Fat.inf +INF FatPkg/EnhancedFatDxe/Fat.inf INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index d75733da6a..6a2212032b 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -298,7 +298,7 @@ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf -INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf @@ -324,7 +324,7 @@ INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf -INF USER FatPkg/EnhancedFatDxe/Fat.inf +INF FatPkg/EnhancedFatDxe/Fat.inf INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf From 073c9aaefb65a3ac47d1a3ff48973501128f6579 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 10 Jan 2025 17:51:23 +0300 Subject: [PATCH 305/341] Ring3: Refactored User and SysCall stacks allocation. --- MdeModulePkg/Core/Dxe/DxeMain.h | 16 +++-- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 10 --- MdeModulePkg/Core/Dxe/Image/Image.c | 44 ++++++++++++- .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 4 +- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 4 +- .../Core/Dxe/SysCall/Initialization.c | 62 ++++--------------- 6 files changed, 69 insertions(+), 71 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index eb15d59eed..cc16c6a0bb 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -115,7 +115,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent /// #define DEPEX_STACK_SIZE_INCREMENT 0x1000 -#define USER_STACK_SIZE 0x20000 +#define STACK_SIZE 0x20000 #define RING3_INTERFACES_PAGES 20 typedef struct { @@ -231,6 +231,8 @@ typedef struct { VOID *HiiData; BOOLEAN IsUserImage; UINTN UserPageTable; + UINTN SysCallStackTop; + UINTN UserStackTop; } LOADED_IMAGE_PRIVATE_DATA; typedef struct { @@ -285,10 +287,8 @@ extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage; extern RING3_DATA *gRing3Data; extern VOID *gRing3Interfaces; -extern VOID *gCoreSysCallStackBase; -extern VOID *gCoreSysCallStackTop; -extern VOID *gRing3CallStackBase; -extern VOID *gRing3CallStackTop; +extern UINTN gCoreSysCallStackTop; +extern UINTN gRing3CallStackTop; extern VOID *gRing3EntryPoint; extern UINTN gUserPageTable; extern UINTN gCorePageTable; @@ -2798,7 +2798,11 @@ FreeProtocolsList ( UINTN EFIAPI InitializeUserPageTable ( - IN LOADED_IMAGE_PRIVATE_DATA *Image + IN LOADED_IMAGE_PRIVATE_DATA *Image, + IN UINTN SysCallStackBase, + IN UINTN SysCallStackSize, + IN UINTN UserStackBase, + IN UINTN UserStackSize ); #endif diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index a2e74c24a8..18173ae0be 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -799,16 +799,6 @@ CoreExitBootServices ( RING3_INTERFACES_PAGES ); - CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)gCoreSysCallStackBase, - EFI_SIZE_TO_PAGES (USER_STACK_SIZE) - ); - - CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3CallStackBase, - EFI_SIZE_TO_PAGES (USER_STACK_SIZE) - ); - FreeProtocolsList (); } diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index e95ccd62ab..270c4d61e9 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1033,6 +1033,30 @@ CoreUnloadAndCloseImage ( CoreFreePool (Image); } +STATIC +UINTN +EFIAPI +AllocateStack ( + IN UINTN Size, + OUT UINTN *Base + ) +{ + UINTN TopOfStack; + + ASSERT (Base != NULL); + ASSERT (IS_ALIGNED (Size, EFI_PAGE_SIZE)); + + *Base = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (Size)); + ASSERT (*Base != 0); + // + // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. + // + TopOfStack = *Base + Size - CPU_STACK_ALIGNMENT; + TopOfStack = ALIGN_VALUE (TopOfStack, CPU_STACK_ALIGNMENT); + + return TopOfStack; +} + /** Loads an EFI image into memory and returns a handle to the image. @@ -1108,6 +1132,8 @@ CoreLoadImageCommon ( UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UINT8 ImageOrigin; EFI_FV_FILE_ATTRIBUTES FileAttributes; + UINTN SysCallStackBase; + UINTN UserStackBase; SecurityStatus = EFI_SUCCESS; @@ -1445,7 +1471,19 @@ CoreLoadImageCommon ( ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, Image->IsUserImage); if ((gRing3Data != NULL) && Image->IsUserImage) { - Image->UserPageTable = InitializeUserPageTable (Image); + Image->SysCallStackTop = AllocateStack (STACK_SIZE, &SysCallStackBase); + SetUefiImageMemoryAttributes (SysCallStackBase, STACK_SIZE, EFI_MEMORY_XP); + + Image->UserStackTop = AllocateStack (STACK_SIZE, &UserStackBase); + SetUefiImageMemoryAttributes (UserStackBase, STACK_SIZE, EFI_MEMORY_XP | EFI_MEMORY_USER); + + Image->UserPageTable = InitializeUserPageTable ( + Image, + SysCallStackBase, + STACK_SIZE, + UserStackBase, + STACK_SIZE + ); } RegisterMemoryProfileImage ( @@ -1703,7 +1741,9 @@ CoreStartImage ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gUserPageTable = Image->UserPageTable; + gUserPageTable = Image->UserPageTable; + gRing3CallStackTop = Image->UserStackTop; + gCoreSysCallStackTop = Image->SysCallStackTop; Image->Status = GoToRing3 ( 2, diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index 42ea8ac88f..73400bfa43 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -19,9 +19,9 @@ EFI_STATUS EFIAPI ArmCallRing3 ( IN RING3_CALL_DATA *Data, - IN VOID *StackPointer, + IN UINTN StackPointer, IN VOID *EntryPoint, - IN VOID *SysCallStack, + IN UINTN SysCallStack, IN VOID *CoreStack, IN UINTN UserPageTable ); diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 26984d4e58..4d81587422 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -18,9 +18,9 @@ EFI_STATUS EFIAPI ArmCallRing3 ( IN RING3_CALL_DATA *Data, - IN VOID *StackPointer, + IN UINTN StackPointer, IN VOID *EntryPoint, - IN VOID *SysCallStack, + IN UINTN SysCallStack, IN VOID *CoreStack, IN UINTN UserPageTable ); diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 171f70f962..c1e6e927fc 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -9,10 +9,8 @@ #include "DxeMain.h" -VOID *gCoreSysCallStackTop; -VOID *gCoreSysCallStackBase; -VOID *gRing3CallStackTop; -VOID *gRing3CallStackBase; +UINTN gCoreSysCallStackTop; +UINTN gRing3CallStackTop; VOID *gRing3EntryPoint; RING3_DATA *gRing3Data; VOID *gRing3Interfaces; @@ -48,8 +46,6 @@ InitializeRing3 ( ) { EFI_STATUS Status; - VOID *TopOfStack; - UINTN SizeOfStack; EFI_PHYSICAL_ADDRESS Physical; UINTN Index; EFI_CONFIGURATION_TABLE *Conf; @@ -157,42 +153,6 @@ InitializeRing3 ( EFI_MEMORY_XP | EFI_MEMORY_USER ); - SizeOfStack = EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE; - - // - // Allocate 128KB for the Core SysCall Stack. - // - gCoreSysCallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); - ASSERT (gCoreSysCallStackBase != NULL); - - // - // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. - // - TopOfStack = (VOID *)((UINTN)gCoreSysCallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - gCoreSysCallStackTop = TopOfStack; - - SetUefiImageMemoryAttributes ((UINTN)gCoreSysCallStackBase, SizeOfStack, EFI_MEMORY_XP); - DEBUG ((DEBUG_ERROR, "Core: gCoreSysCallStackTop = %p\n", gCoreSysCallStackTop)); - - // - // Allocate 128KB for the User Stack. - // - gRing3CallStackBase = AllocatePages (EFI_SIZE_TO_PAGES (USER_STACK_SIZE)); - ASSERT (gRing3CallStackBase != NULL); - - // - // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. - // - TopOfStack = (VOID *)((UINTN)gRing3CallStackBase + SizeOfStack - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - gRing3CallStackTop = TopOfStack; - - SetUefiImageMemoryAttributes ((UINTN)gRing3CallStackBase, SizeOfStack, EFI_MEMORY_XP | EFI_MEMORY_USER); - DEBUG ((DEBUG_ERROR, "Core: gRing3CallStackTop = %p\n", gRing3CallStackTop)); - InitializeMsr ( gRing3Data->SystemTable.ConfigurationTable, gRing3Data->SystemTable.NumberOfTableEntries @@ -206,7 +166,11 @@ InitializeRing3 ( UINTN EFIAPI InitializeUserPageTable ( - IN LOADED_IMAGE_PRIVATE_DATA *Image + IN LOADED_IMAGE_PRIVATE_DATA *Image, + IN UINTN SysCallStackBase, + IN UINTN SysCallStackSize, + IN UINTN UserStackBase, + IN UINTN UserStackSize ) { UINTN UserPageTable; @@ -222,7 +186,7 @@ InitializeUserPageTable ( MakeUserPageTableTemplate (&UserPageTable, &UserPageTableSize); // - // Map gRing3Data, gRing3Interfaces, gRing3CallStackBase, DxeRing3 + // Map gRing3Data, gRing3Interfaces, UserStackBase, DxeRing3 // gCpu->SetUserMemoryAttributes ( gCpu, @@ -243,8 +207,8 @@ InitializeUserPageTable ( gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, - (UINTN)gRing3CallStackBase, - EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, + UserStackBase, + UserStackSize, EFI_MEMORY_XP | EFI_MEMORY_USER ); @@ -264,7 +228,7 @@ InitializeUserPageTable ( } // - // Map CoreBootServices, gCoreSysCallStackBase + // Map CoreBootServices, SysCallStackBase // gCpu->SetUserMemoryAttributes ( gCpu, @@ -277,8 +241,8 @@ InitializeUserPageTable ( gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, - (UINTN)gCoreSysCallStackBase, - EFI_SIZE_TO_PAGES (USER_STACK_SIZE) * EFI_PAGE_SIZE, + SysCallStackBase, + SysCallStackSize, EFI_MEMORY_XP ); From cc0e1a18da6675c64ce89edfe9339bb943aa39b2 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 10 Jan 2025 18:14:00 +0300 Subject: [PATCH 306/341] Ring3: Fixed line endings. --- .../AArch64/ExceptionSupport.S | 14 +- .../ArmExceptionLib/Arm/ExceptionSupport.S | 52 +- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 52 +- .../Core/Dxe/SysCall/SupportedProtocols.c | 624 +++++++++--------- .../Ia32/ExceptionHandlerAsm.nasm | 24 +- .../X64/ExceptionHandlerAsm.nasm | 28 +- 6 files changed, 397 insertions(+), 397 deletions(-) diff --git a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S index 22a1ac50ce..8e6512cee1 100644 --- a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S @@ -303,10 +303,10 @@ NoTTBR0Switch: // We do not try to recover. bl ASM_PFX(CommonCExceptionHandler) // Call exception handler - ldr x2, [x28, #(FP_CONTEXT_SIZE + 0x8)] // Saved Processor Status Register - and x2, x2, #0xF - cmp x2, 0 // Check whether EL0 process was interrupted - b.ne NoTTBR0Switch2 + ldr x2, [x28, #(FP_CONTEXT_SIZE + 0x8)] // Saved Processor Status Register + and x2, x2, #0xF + cmp x2, 0 // Check whether EL0 process was interrupted + b.ne NoTTBR0Switch2 adrp x1, ASM_PFX(CorePageTable) EL1_OR_EL2(x3) 1:ldr x4, [x1, #0x8] // UserPageTable @@ -411,6 +411,6 @@ ASM_PFX(CorePageTable): UserPageTable: .ds.d 1 -.balign 4096 -Padding: -.ds.b 1 +.balign 4096 +Padding: +.ds.b 1 diff --git a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S index 257b0b05a9..c36679308a 100644 --- a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S @@ -255,23 +255,23 @@ NoAdjustNeeded: vpush {d0-d15} @ save vstm registers in case they are used in optimizations #endif - ldr R5, [SP, #0x40] @ Saved Processor Status Register - and R5, R5, #0xF - cmp R5, 0 @ Check whether EL0 process was interrupted - bne NoTTBR0Switch - mrc p15,0,R5,c2,c0,0 @ R5 == TTBR0 - ADRL (R6, UserPageTable) - str R5, [R6] - and R5, R5, #0x7F @ Preserve TTBR0 attributes - LDRL (R6, ASM_PFX(CorePageTable)) - orr R6, R6, R5 @ Assign TTBR0 attributes + ldr R5, [SP, #0x40] @ Saved Processor Status Register + and R5, R5, #0xF + cmp R5, 0 @ Check whether EL0 process was interrupted + bne NoTTBR0Switch + mrc p15,0,R5,c2,c0,0 @ R5 == TTBR0 + ADRL (R6, UserPageTable) + str R5, [R6] + and R5, R5, #0x7F @ Preserve TTBR0 attributes + LDRL (R6, ASM_PFX(CorePageTable)) + orr R6, R6, R5 @ Assign TTBR0 attributes mcr p15,0,R6,c2,c0,0 @ TTBR0 == R6 mcr p15,0,r0,c8,c7,0 @ TLBIALL, TLB Invalidate All. mcr p15,0,r0,c7,c5,6 @ BPIALL, Branch Predictor Invalidate All. dsb isb -NoTTBR0Switch: +NoTTBR0Switch: mov R4, SP @ Save current SP tst R4, #4 @@ -327,18 +327,18 @@ NoTTBR0Switch2: ldmfd SP!,{LR} @ restore the link register for this context rfefd SP! @ return from exception via srsfd stack slot -ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096) - -.data - -.global ASM_PFX(CorePageTable) -.balign 4096 -ASM_PFX(CorePageTable): -.ds.l 1 - -UserPageTable: -.ds.l 1 - -.balign 4096 -Padding: -.ds.b 1 +ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096) + +.data + +.global ASM_PFX(CorePageTable) +.balign 4096 +ASM_PFX(CorePageTable): +.ds.l 1 + +UserPageTable: +.ds.l 1 + +.balign 4096 +Padding: +.ds.b 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 4d81587422..becb1812c2 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -91,32 +91,32 @@ SysCallBootService ( return Status; } -VOID -EFIAPI -MakeUserPageTableTemplate ( - OUT UINTN *UserPageTableTemplate, - OUT UINTN *UserPageTableTemplateSize - ) -{ - ARM_MEMORY_REGION_DESCRIPTOR Descriptor; - VOID *MemorySizeHob; - - MemorySizeHob = GetFirstGuidHob (&gArmVirtSystemMemorySizeGuid); - ASSERT (MemorySizeHob != NULL); - if (MemorySizeHob == NULL) { - return; - } - - Descriptor.PhysicalBase = PcdGet64 (PcdSystemMemoryBase); - Descriptor.VirtualBase = Descriptor.PhysicalBase; - Descriptor.Length = *(UINT64 *)GET_GUID_HOB_DATA (MemorySizeHob); - Descriptor.Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK; - - ArmMakeUserPageTableTemplate ( - &Descriptor, - UserPageTableTemplate, - UserPageTableTemplateSize - ); +VOID +EFIAPI +MakeUserPageTableTemplate ( + OUT UINTN *UserPageTableTemplate, + OUT UINTN *UserPageTableTemplateSize + ) +{ + ARM_MEMORY_REGION_DESCRIPTOR Descriptor; + VOID *MemorySizeHob; + + MemorySizeHob = GetFirstGuidHob (&gArmVirtSystemMemorySizeGuid); + ASSERT (MemorySizeHob != NULL); + if (MemorySizeHob == NULL) { + return; + } + + Descriptor.PhysicalBase = PcdGet64 (PcdSystemMemoryBase); + Descriptor.VirtualBase = Descriptor.PhysicalBase; + Descriptor.Length = *(UINT64 *)GET_GUID_HOB_DATA (MemorySizeHob); + Descriptor.Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK; + + ArmMakeUserPageTableTemplate ( + &Descriptor, + UserPageTableTemplate, + UserPageTableTemplateSize + ); } VOID diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index de06170e07..b263030aad 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -809,315 +809,315 @@ CoreOpenVolume ( return Status; } -INTN -EFIAPI -CoreUnicodeCollationStriColl ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *Str1, - IN CHAR16 *Str2 - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS UserMem; - USER_SPACE_DRIVER *UserDriver; - VOID *EntryPoint; - UINTN Size1; - UINTN Size2; - - UserDriver = FindUserSpaceDriver (This); - ASSERT (UserDriver != NULL); - - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; - - Size1 = StrSize (Str1); - Size2 = StrSize (Str2); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (Size1 + Size2), - &UserMem - ); - if (EFI_ERROR (Status)) { - return 0; - } - - AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)(UINTN)UserMem, (VOID *)Str1, Size1); - CopyMem ((VOID *)((UINTN)UserMem + Size1), (VOID *)Str2, Size2); - EntryPoint = (VOID *)This->StriColl; - ForbidSupervisorAccessToUserMemory (); - - Status = GoToRing3 ( - 3, - EntryPoint, - This, - (UINTN)UserMem, - (UINTN)UserMem + Size1 - ); - - CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1 + Size2)); - - return (INTN)Status; -} - -BOOLEAN -EFIAPI -CoreUnicodeCollationMetaiMatch ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN CHAR16 *Pattern - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS UserMem; - USER_SPACE_DRIVER *UserDriver; - VOID *EntryPoint; - UINTN Size1; - UINTN Size2; - - UserDriver = FindUserSpaceDriver (This); - ASSERT (UserDriver != NULL); - - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; - - Size1 = StrSize (String); - Size2 = StrSize (Pattern); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (Size1 + Size2), - &UserMem - ); - if (EFI_ERROR (Status)) { - return FALSE; - } - - AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)(UINTN)UserMem, (VOID *)String, Size1); - CopyMem ((VOID *)((UINTN)UserMem + Size1), (VOID *)Pattern, Size2); - EntryPoint = (VOID *)This->MetaiMatch; - ForbidSupervisorAccessToUserMemory (); - - Status = GoToRing3 ( - 3, - EntryPoint, - This, - (UINTN)UserMem, - (UINTN)UserMem + Size1 - ); - - CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1 + Size2)); - - return (BOOLEAN)Status; -} - -VOID -EFIAPI -CoreUnicodeCollationStrLwr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS UserMem; - USER_SPACE_DRIVER *UserDriver; - VOID *EntryPoint; - UINTN Size1; - - UserDriver = FindUserSpaceDriver (This); - ASSERT (UserDriver != NULL); - - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; - - Size1 = StrSize (Str); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (Size1), - &UserMem - ); - if (EFI_ERROR (Status)) { - return; - } - - AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)(UINTN)UserMem, (VOID *)Str, Size1); - EntryPoint = (VOID *)This->StrLwr; - ForbidSupervisorAccessToUserMemory (); - - Status = GoToRing3 ( - 2, - EntryPoint, - This, - (UINTN)UserMem - ); - - AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)Str, (VOID *)(UINTN)UserMem, Size1); - ForbidSupervisorAccessToUserMemory (); - - CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1)); -} - -VOID -EFIAPI -CoreUnicodeCollationStrUpr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS UserMem; - USER_SPACE_DRIVER *UserDriver; - VOID *EntryPoint; - UINTN Size1; - - UserDriver = FindUserSpaceDriver (This); - ASSERT (UserDriver != NULL); - - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; - - Size1 = StrSize (Str); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (Size1), - &UserMem - ); - if (EFI_ERROR (Status)) { - return; - } - - AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)(UINTN)UserMem, (VOID *)Str, Size1); - EntryPoint = (VOID *)This->StrUpr; - ForbidSupervisorAccessToUserMemory (); - - Status = GoToRing3 ( - 2, - EntryPoint, - This, - (UINTN)UserMem - ); - - AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)Str, (VOID *)(UINTN)UserMem, Size1); - ForbidSupervisorAccessToUserMemory (); - - CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1)); -} - -VOID -EFIAPI -CoreUnicodeCollationFatToStr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN UINTN FatSize, - IN CHAR8 *Fat, - OUT CHAR16 *String - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS UserMem; - USER_SPACE_DRIVER *UserDriver; - VOID *EntryPoint; - - UserDriver = FindUserSpaceDriver (This); - ASSERT (UserDriver != NULL); - - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (FatSize * 3), - &UserMem - ); - if (EFI_ERROR (Status)) { - return; - } - - AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)(UINTN)UserMem, (VOID *)Fat, FatSize); - EntryPoint = (VOID *)This->FatToStr; - ForbidSupervisorAccessToUserMemory (); - - Status = GoToRing3 ( - 4, - EntryPoint, - This, - FatSize, - (UINTN)UserMem, - (UINTN)UserMem + FatSize - ); - - AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)String, (VOID *)((UINTN)UserMem + FatSize), FatSize * 2); - ForbidSupervisorAccessToUserMemory (); - - CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (FatSize * 3)); -} - -BOOLEAN -EFIAPI -CoreUnicodeCollationStrToFat ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN UINTN FatSize, - OUT CHAR8 *Fat - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS UserMem; - USER_SPACE_DRIVER *UserDriver; - VOID *EntryPoint; - UINTN Size1; - - UserDriver = FindUserSpaceDriver (This); - ASSERT (UserDriver != NULL); - - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; - - Size1 = StrSize (String); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (FatSize + Size1), - &UserMem - ); - if (EFI_ERROR (Status)) { - return FALSE; - } - - AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)(UINTN)UserMem, (VOID *)String, Size1); - EntryPoint = (VOID *)This->StrToFat; - ForbidSupervisorAccessToUserMemory (); - - Status = GoToRing3 ( - 4, - EntryPoint, - This, - (UINTN)UserMem, - FatSize, - (UINTN)UserMem + Size1 - ); - - AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)Fat, (VOID *)((UINTN)UserMem + Size1), FatSize); - ForbidSupervisorAccessToUserMemory (); - - CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (FatSize + Size1)); - - return (BOOLEAN)Status; -} +INTN +EFIAPI +CoreUnicodeCollationStriColl ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *Str1, + IN CHAR16 *Str2 + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS UserMem; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + UINTN Size1; + UINTN Size2; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + Size1 = StrSize (Str1); + Size2 = StrSize (Str2); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (Size1 + Size2), + &UserMem + ); + if (EFI_ERROR (Status)) { + return 0; + } + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)(UINTN)UserMem, (VOID *)Str1, Size1); + CopyMem ((VOID *)((UINTN)UserMem + Size1), (VOID *)Str2, Size2); + EntryPoint = (VOID *)This->StriColl; + ForbidSupervisorAccessToUserMemory (); + + Status = GoToRing3 ( + 3, + EntryPoint, + This, + (UINTN)UserMem, + (UINTN)UserMem + Size1 + ); + + CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1 + Size2)); + + return (INTN)Status; +} + +BOOLEAN +EFIAPI +CoreUnicodeCollationMetaiMatch ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS UserMem; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + UINTN Size1; + UINTN Size2; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + Size1 = StrSize (String); + Size2 = StrSize (Pattern); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (Size1 + Size2), + &UserMem + ); + if (EFI_ERROR (Status)) { + return FALSE; + } + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)(UINTN)UserMem, (VOID *)String, Size1); + CopyMem ((VOID *)((UINTN)UserMem + Size1), (VOID *)Pattern, Size2); + EntryPoint = (VOID *)This->MetaiMatch; + ForbidSupervisorAccessToUserMemory (); + + Status = GoToRing3 ( + 3, + EntryPoint, + This, + (UINTN)UserMem, + (UINTN)UserMem + Size1 + ); + + CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1 + Size2)); + + return (BOOLEAN)Status; +} + +VOID +EFIAPI +CoreUnicodeCollationStrLwr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS UserMem; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + UINTN Size1; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + Size1 = StrSize (Str); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (Size1), + &UserMem + ); + if (EFI_ERROR (Status)) { + return; + } + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)(UINTN)UserMem, (VOID *)Str, Size1); + EntryPoint = (VOID *)This->StrLwr; + ForbidSupervisorAccessToUserMemory (); + + Status = GoToRing3 ( + 2, + EntryPoint, + This, + (UINTN)UserMem + ); + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)Str, (VOID *)(UINTN)UserMem, Size1); + ForbidSupervisorAccessToUserMemory (); + + CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1)); +} + +VOID +EFIAPI +CoreUnicodeCollationStrUpr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS UserMem; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + UINTN Size1; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + Size1 = StrSize (Str); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (Size1), + &UserMem + ); + if (EFI_ERROR (Status)) { + return; + } + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)(UINTN)UserMem, (VOID *)Str, Size1); + EntryPoint = (VOID *)This->StrUpr; + ForbidSupervisorAccessToUserMemory (); + + Status = GoToRing3 ( + 2, + EntryPoint, + This, + (UINTN)UserMem + ); + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)Str, (VOID *)(UINTN)UserMem, Size1); + ForbidSupervisorAccessToUserMemory (); + + CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1)); +} + +VOID +EFIAPI +CoreUnicodeCollationFatToStr ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS UserMem; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (FatSize * 3), + &UserMem + ); + if (EFI_ERROR (Status)) { + return; + } + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)(UINTN)UserMem, (VOID *)Fat, FatSize); + EntryPoint = (VOID *)This->FatToStr; + ForbidSupervisorAccessToUserMemory (); + + Status = GoToRing3 ( + 4, + EntryPoint, + This, + FatSize, + (UINTN)UserMem, + (UINTN)UserMem + FatSize + ); + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)String, (VOID *)((UINTN)UserMem + FatSize), FatSize * 2); + ForbidSupervisorAccessToUserMemory (); + + CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (FatSize * 3)); +} + +BOOLEAN +EFIAPI +CoreUnicodeCollationStrToFat ( + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS UserMem; + USER_SPACE_DRIVER *UserDriver; + VOID *EntryPoint; + UINTN Size1; + + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + gUserPageTable = UserDriver->UserPageTable; + + Size1 = StrSize (String); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (FatSize + Size1), + &UserMem + ); + if (EFI_ERROR (Status)) { + return FALSE; + } + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)(UINTN)UserMem, (VOID *)String, Size1); + EntryPoint = (VOID *)This->StrToFat; + ForbidSupervisorAccessToUserMemory (); + + Status = GoToRing3 ( + 4, + EntryPoint, + This, + (UINTN)UserMem, + FatSize, + (UINTN)UserMem + Size1 + ); + + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)Fat, (VOID *)((UINTN)UserMem + Size1), FatSize); + ForbidSupervisorAccessToUserMemory (); + + CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (FatSize + Size1)); + + return (BOOLEAN)Status; +} diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm index 0c81564554..ee2a061fd5 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm @@ -468,18 +468,18 @@ DoReturn: DoIret: iretd -ReturnToRing3: - mov ecx, [ASM_PFX(UserPageTable)] - mov cr3, ecx - pop ecx - mov esp, ebp - pop ebp - add esp, 8 - iretd - -ALIGN 4096 -global ASM_PFX(ExceptionHandlerEnd) -ASM_PFX(ExceptionHandlerEnd): +ReturnToRing3: + mov ecx, [ASM_PFX(UserPageTable)] + mov cr3, ecx + pop ecx + mov esp, ebp + pop ebp + add esp, 8 + iretd + +ALIGN 4096 +global ASM_PFX(ExceptionHandlerEnd) +ASM_PFX(ExceptionHandlerEnd): ;---------------------------------------; ; _AsmGetTemplateAddressMap ; diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm index 31e1a70780..9ba3ae5172 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm @@ -63,13 +63,13 @@ global ASM_PFX(UserPageTable) ASM_PFX(UserPageTable): resq 1 -global ASM_PFX(mSwitchCr3Flag) -ASM_PFX(mSwitchCr3Flag): - db 0x0 +global ASM_PFX(mSwitchCr3Flag) +ASM_PFX(mSwitchCr3Flag): + db 0x0 -ALIGN 4096 -Padding: - db 0x0 +ALIGN 4096 +Padding: + db 0x0 DEFAULT REL SECTION .text @@ -493,17 +493,17 @@ DoReturn: DoIret: iretq ReturnToRing3: - mov rcx, [ASM_PFX(UserPageTable)] - mov cr3, rcx - pop rcx - mov rsp, rbp - pop rbp - add rsp, 16 + mov rcx, [ASM_PFX(UserPageTable)] + mov cr3, rcx + pop rcx + mov rsp, rbp + pop rbp + add rsp, 16 iretq ALIGN 4096 -global ASM_PFX(ExceptionHandlerEnd) -ASM_PFX(ExceptionHandlerEnd): +global ASM_PFX(ExceptionHandlerEnd) +ASM_PFX(ExceptionHandlerEnd): ;------------------------------------------------------------------------------------- ; GetTemplateAddressMap (&AddressMap); From 9961f6900b1a96de1afb516450ba4b2a458bb886 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 13 Jan 2025 13:27:58 +0300 Subject: [PATCH 307/341] Ring3: Refactored out gCoreSysCallStackTop and gRing3CallStackTop. --- ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 4 +- MdeModulePkg/Core/Dxe/DxeMain.h | 14 +- MdeModulePkg/Core/Dxe/Image/Image.c | 16 +- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 8 +- .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 11 +- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 10 +- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 11 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 5 + .../Dxe/SysCall/IA32/CoreBootServices.nasm | 25 ++- .../Core/Dxe/SysCall/IA32/InitializeIA32.c | 3 - .../Core/Dxe/SysCall/Initialization.c | 2 - .../Core/Dxe/SysCall/SupportedProtocols.c | 180 +++++++++++------- .../Core/Dxe/SysCall/SupportedProtocols.h | 2 + .../Dxe/SysCall/X64/CoreBootServices.nasm | 22 ++- OvmfPkg/OvmfPkgIa32.fdf | 4 +- OvmfPkg/OvmfPkgIa32X64.fdf | 4 +- OvmfPkg/OvmfPkgX64.fdf | 4 +- 17 files changed, 208 insertions(+), 117 deletions(-) diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc index 1a60f4566d..270e0b87a1 100644 --- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc +++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc @@ -88,9 +88,9 @@ APRIORI DXE { # INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf - INF FatPkg/EnhancedFatDxe/Fat.inf + INF USER FatPkg/EnhancedFatDxe/Fat.inf INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf - INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index cc16c6a0bb..9d00273b26 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -287,8 +287,6 @@ extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage; extern RING3_DATA *gRing3Data; extern VOID *gRing3Interfaces; -extern UINTN gCoreSysCallStackTop; -extern UINTN gRing3CallStackTop; extern VOID *gRing3EntryPoint; extern UINTN gUserPageTable; extern UINTN gCorePageTable; @@ -2756,12 +2754,6 @@ CallBootService ( IN RING3_STACK *UserRsp ); -EFI_STATUS -EFIAPI -CallRing3 ( - IN RING3_CALL_DATA *Data - ); - VOID EFIAPI AllowSupervisorAccessToUserMemory ( @@ -2777,8 +2769,10 @@ ForbidSupervisorAccessToUserMemory ( EFI_STATUS EFIAPI GoToRing3 ( - IN UINT8 Number, - IN VOID *EntryPoint, + IN UINT8 Number, + IN VOID *EntryPoint, + IN UINTN UserStackTop, + IN UINTN SysCallStackTop, ... ); diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 270c4d61e9..9b85b0633a 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1741,16 +1741,16 @@ CoreStartImage ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gUserPageTable = Image->UserPageTable; - gRing3CallStackTop = Image->UserStackTop; - gCoreSysCallStackTop = Image->SysCallStackTop; + gUserPageTable = Image->UserPageTable; Image->Status = GoToRing3 ( - 2, - (VOID *)Image->EntryPoint, - ImageHandle, - gRing3Data - ); + 2, + (VOID *)Image->EntryPoint, + Image->UserStackTop, + Image->SysCallStackTop, + ImageHandle, + gRing3Data + ); } } else { Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index f6de8c0a71..45264f3197 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -60,13 +60,15 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) // EFI_STATUS // EFIAPI // CallRing3 ( -// IN RING3_CALL_DATA *Data +// IN RING3_CALL_DATA *Data, +// IN UINTN UserStackTop, +// IN UINTN SysCallStackTop // ); // // (x0) Data -// (x1) gRing3CallStackTop +// (x1) UserStackTop // (x2) gRing3EntryPoint -// (x3) gCoreSysCallStackTop +// (x3) SysCallStackTop // (x4) &CoreSp // (x5) gUserPageTable //------------------------------------------------------------------------------ diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index 73400bfa43..94321306b9 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -14,6 +14,8 @@ STATIC UINTN mCoreSp; UINTN gUserPageTable; +UINTN mRing3CallStackTop; +UINTN mCoreSysCallStackTop; EFI_STATUS EFIAPI @@ -167,8 +169,13 @@ ForbidSupervisorAccessToUserMemory ( EFI_STATUS EFIAPI CallRing3 ( - IN RING3_CALL_DATA *Data + IN RING3_CALL_DATA *Data, + IN UINTN UserStackTop, + IN UINTN SysCallStackTop ) { - return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp, gUserPageTable); + mRing3CallStackTop = UserStackTop; + mCoreSysCallStackTop = SysCallStackTop; + + return ArmCallRing3 (Data, UserStackTop, gRing3EntryPoint, SysCallStackTop, &mCoreSp, gUserPageTable); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index df40693d20..03b326f20d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -56,13 +56,15 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) // EFI_STATUS // EFIAPI // CallRing3 ( -// IN RING3_CALL_DATA *Data +// IN RING3_CALL_DATA *Data, +// IN UINTN UserStackTop, +// IN UINTN SysCallStackTop // ); // // (r0) Data -// (r1) gRing3CallStackTop +// (r1) UserStackTop // (r2) gRing3EntryPoint -// (r3) gCoreSysCallStackTop +// (r3) SysCallStackTop // // (On Core Stack) &CoreSp, gUserPageTable //------------------------------------------------------------------------------ @@ -84,7 +86,7 @@ ASM_FUNC(ArmCallRing3) cpsid if isb - // Set SP_usr to gRing3CallStackTop. + // Set SP_usr to UserStackTop. push {R1} mov R1, SP ldmia R1, {SP}^ diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index becb1812c2..2c20160c34 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -13,6 +13,8 @@ STATIC UINTN mCoreSp; UINTN gUserPageTable; +UINTN mRing3CallStackTop; +UINTN mCoreSysCallStackTop; EFI_STATUS EFIAPI @@ -162,8 +164,13 @@ ForbidSupervisorAccessToUserMemory ( EFI_STATUS EFIAPI CallRing3 ( - IN RING3_CALL_DATA *Data + IN RING3_CALL_DATA *Data, + IN UINTN UserStackTop, + IN UINTN SysCallStackTop ) { - return ArmCallRing3 (Data, gRing3CallStackTop, gRing3EntryPoint, gCoreSysCallStackTop, &mCoreSp, gUserPageTable); + mRing3CallStackTop = UserStackTop; + mCoreSysCallStackTop = SysCallStackTop; + + return ArmCallRing3 (Data, UserStackTop, gRing3EntryPoint, SysCallStackTop, &mCoreSp, gUserPageTable); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index deb8ef83c0..8da430831c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -8,6 +8,9 @@ #include "DxeMain.h" #include "SupportedProtocols.h" +extern UINTN mRing3CallStackTop; +extern UINTN mCoreSysCallStackTop; + LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead); typedef struct { @@ -479,6 +482,8 @@ CallBootService ( UserDriver->CoreWrapper = CoreArgList[Index + 1]; UserDriver->UserSpaceDriver = UserArgList[Index + 1]; UserDriver->UserPageTable = gUserPageTable; + UserDriver->SysCallStackTop = mCoreSysCallStackTop; + UserDriver->UserStackTop = mRing3CallStackTop; InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link); diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index 3c26b07179..303a18360d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -8,8 +8,6 @@ #include extern ASM_PFX(CallBootService) -extern ASM_PFX(gCoreSysCallStackTop) -extern ASM_PFX(gRing3CallStackTop) extern ASM_PFX(gRing3EntryPoint) extern ASM_PFX(AsmReadMsr64) @@ -174,7 +172,9 @@ ASM_PFX(CoreBootServices): ; EFI_STATUS ; EFIAPI ; CallRing3 ( -; IN RING3_CALL_DATA *Data +; IN RING3_CALL_DATA *Data, +; IN UINTN UserStackTop, +; IN UINTN SysCallStackTop ; ); ; ; (On User Stack) Data @@ -191,8 +191,17 @@ ASM_PFX(CallRing3): ; Save Core Stack pointer. mov [ASM_PFX(CoreEsp)], esp + mov ebx, [esp + 4 * 6] ; UserStackTop + mov [ASM_PFX(mRing3CallStackTop)], ebx + mov ebx, [esp + 4 * 7] ; SysCallStackTop + mov [ASM_PFX(mCoreSysCallStackTop)], ebx + mov edx, 0 + mov eax, ebx + mov ecx, MSR_IA32_SYSENTER_ESP + wrmsr + push dword [ASM_PFX(gRing3EntryPoint)] - push dword [ASM_PFX(gRing3CallStackTop)] + push dword [ASM_PFX(mRing3CallStackTop)] SetRing3DataSegmentSelectors @@ -249,3 +258,11 @@ ASM_PFX(gUserPageTable): ALIGN 4096 ASM_PFX(CoreEsp): resd 1 + +global ASM_PFX(mRing3CallStackTop) +ASM_PFX(mRing3CallStackTop): + resd 1 + +global ASM_PFX(mCoreSysCallStackTop) +ASM_PFX(mCoreSysCallStackTop): + resd 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c index 60a9672e47..84714cdf34 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c @@ -153,8 +153,5 @@ InitializeMsr ( Msr = (UINT64)(UINTN)CoreBootServices; AsmWriteMsr64 (MSR_IA32_SYSENTER_EIP, Msr); - Msr = (UINT64)(UINTN)gCoreSysCallStackTop; - AsmWriteMsr64 (MSR_IA32_SYSENTER_ESP, Msr); - gCorePageTable = AsmReadCr3 (); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index c1e6e927fc..275647f1d4 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -9,8 +9,6 @@ #include "DxeMain.h" -UINTN gCoreSysCallStackTop; -UINTN gRing3CallStackTop; VOID *gRing3EntryPoint; RING3_DATA *gRing3Data; VOID *gRing3Interfaces; diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index b263030aad..89cdd3a70b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -10,11 +10,21 @@ LIST_ENTRY mUserSpaceDriversHead = INITIALIZE_LIST_HEAD_VARIABLE (mUserSpaceDriversHead); +EFI_STATUS +EFIAPI +CallRing3 ( + IN RING3_CALL_DATA *Data, + IN UINTN UserStackTop, + IN UINTN SysCallStackTop + ); + EFI_STATUS EFIAPI GoToRing3 ( - IN UINT8 Number, - IN VOID *EntryPoint, + IN UINT8 Number, + IN VOID *EntryPoint, + IN UINTN UserStackTop, + IN UINTN SysCallStackTop, ... ) { @@ -43,14 +53,14 @@ GoToRing3 ( Input->NumberOfArguments = Number; Input->EntryPoint = EntryPoint; - VA_START (Marker, EntryPoint); + VA_START (Marker, SysCallStackTop); for (Index = 0; Index < Number; ++Index) { Input->Arguments[Index] = VA_ARG (Marker, UINTN); } VA_END (Marker); ForbidSupervisorAccessToUserMemory (); - Status = CallRing3 (Input); + Status = CallRing3 (Input, UserStackTop, SysCallStackTop); CoreFreePages (Ring3Pages, PagesNumber); @@ -71,6 +81,7 @@ FindUserSpaceDriver ( UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link); if (UserDriver->CoreWrapper == CoreWrapper) { + gUserPageTable = UserDriver->UserPageTable; return UserDriver; } } @@ -93,8 +104,7 @@ CoreDriverBindingSupported ( UserDriver = FindUserSpaceDriver (This); ASSERT (UserDriver != NULL); - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; + This = UserDriver->UserSpaceDriver; AllowSupervisorAccessToUserMemory (); EntryPoint = (VOID *)This->Supported; @@ -103,6 +113,8 @@ CoreDriverBindingSupported ( Status = GoToRing3 ( 3, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, ControllerHandle, RemainingDevicePath @@ -126,8 +138,7 @@ CoreDriverBindingStart ( UserDriver = FindUserSpaceDriver (This); ASSERT (UserDriver != NULL); - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; + This = UserDriver->UserSpaceDriver; AllowSupervisorAccessToUserMemory (); EntryPoint = (VOID *)This->Start; @@ -136,6 +147,8 @@ CoreDriverBindingStart ( Status = GoToRing3 ( 3, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, ControllerHandle, RemainingDevicePath @@ -160,8 +173,7 @@ CoreDriverBindingStop ( UserDriver = FindUserSpaceDriver (This); ASSERT (UserDriver != NULL); - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; + This = UserDriver->UserSpaceDriver; AllowSupervisorAccessToUserMemory (); EntryPoint = (VOID *)This->Stop; @@ -170,6 +182,8 @@ CoreDriverBindingStop ( Status = GoToRing3 ( 4, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, ControllerHandle, NumberOfChildren, @@ -193,8 +207,7 @@ CoreFileClose ( UserDriver = FindUserSpaceDriver (This); ASSERT (UserDriver != NULL); - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; + This = UserDriver->UserSpaceDriver; AllowSupervisorAccessToUserMemory (); EntryPoint = (VOID *)This->Close; @@ -203,10 +216,13 @@ CoreFileClose ( Status = GoToRing3 ( 1, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This ); FreePool (UserDriver->CoreWrapper); + RemoveEntryList (&UserDriver->Link); return Status; } @@ -241,6 +257,13 @@ CoreFileRead ( if ((This == NULL) || (BufferSize == NULL)) { return EFI_INVALID_PARAMETER; } + // + // gUserPageTable must be set before alloctation of EfiRing3MemoryType pages. + // + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; Ring3Buffer = NULL; Ring3Pages = 0; @@ -258,12 +281,6 @@ CoreFileRead ( Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; - UserDriver = FindUserSpaceDriver (This); - ASSERT (UserDriver != NULL); - - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; - AllowSupervisorAccessToUserMemory (); *Ring3BufferSize = *BufferSize; EntryPoint = (VOID *)This->Read; @@ -276,6 +293,8 @@ CoreFileRead ( Status = GoToRing3 ( 3, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, Ring3BufferSize, Ring3Buffer @@ -320,8 +339,7 @@ CoreFileSetPosition ( UserDriver = FindUserSpaceDriver (This); ASSERT (UserDriver != NULL); - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; + This = UserDriver->UserSpaceDriver; AllowSupervisorAccessToUserMemory (); EntryPoint = (VOID *)This->SetPosition; @@ -331,6 +349,8 @@ CoreFileSetPosition ( return GoToRing3 ( 2, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, Position ); @@ -341,17 +361,21 @@ CoreFileSetPosition ( return GoToRing3 ( 3, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, Position ); #elif defined (MDE_CPU_ARM) // // UINT64 Position is passed as 2 words in 2 registers and is aligned on 8 bytes. - // R0 == File->Ring3File, R1 == NULL, R2 == Position_Low, R3 == Position_High. + // R0 == This, R1 == NULL, R2 == Position_Low, R3 == Position_High. // return GoToRing3 ( 4, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, Position ); @@ -376,6 +400,11 @@ CoreFileGetPosition ( return EFI_INVALID_PARAMETER; } + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, @@ -386,12 +415,6 @@ CoreFileGetPosition ( return Status; } - UserDriver = FindUserSpaceDriver (This); - ASSERT (UserDriver != NULL); - - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; - AllowSupervisorAccessToUserMemory (); *(UINT64 *)(UINTN)Ring3Position = *Position; EntryPoint = (VOID *)This->GetPosition; @@ -400,6 +423,8 @@ CoreFileGetPosition ( Status = GoToRing3 ( 2, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, Ring3Position ); @@ -436,6 +461,11 @@ CoreFileGetInfo ( return EFI_INVALID_PARAMETER; } + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + Ring3Buffer = NULL; Ring3InformationType = NULL; Ring3Pages = 0; @@ -454,12 +484,6 @@ CoreFileGetInfo ( Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; - UserDriver = FindUserSpaceDriver (This); - ASSERT (UserDriver != NULL); - - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; - AllowSupervisorAccessToUserMemory (); *Ring3BufferSize = *BufferSize; EntryPoint = (VOID *)This->GetInfo; @@ -480,6 +504,8 @@ CoreFileGetInfo ( Status = GoToRing3 ( 4, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, Ring3InformationType, Ring3BufferSize, @@ -588,12 +614,18 @@ CoreFileOpen ( EFI_PHYSICAL_ADDRESS Ring3Pages; UINT32 PagesNumber; USER_SPACE_DRIVER *UserDriver; + USER_SPACE_DRIVER *NewDriver; VOID *EntryPoint; if ((This == NULL) || (NewHandle == NULL) || (FileName == NULL)) { return EFI_INVALID_PARAMETER; } + UserDriver = FindUserSpaceDriver (This); + ASSERT (UserDriver != NULL); + + This = UserDriver->UserSpaceDriver; + Ring3NewHandle = NULL; Ring3FileName = NULL; Ring3Pages = 0; @@ -614,12 +646,6 @@ CoreFileOpen ( Ring3NewHandle = (EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages; Ring3FileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages + 1); - UserDriver = FindUserSpaceDriver (This); - ASSERT (UserDriver != NULL); - - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; - AllowSupervisorAccessToUserMemory (); Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName); EntryPoint = (VOID *)This->Open; @@ -634,6 +660,8 @@ CoreFileOpen ( Status = GoToRing3 ( 5, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, Ring3NewHandle, Ring3FileName, @@ -647,6 +675,8 @@ CoreFileOpen ( Status = GoToRing3 ( 7, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, Ring3NewHandle, Ring3FileName, @@ -657,12 +687,14 @@ CoreFileOpen ( // // UINT64 OpenMode and Attributes are each passed as 2 words on stack. // Each of them is aligned on 8 bytes. - // R0 == File->Ring3File, R1 == Ring3NewHandle, R2 == Ring3FileName, R3 == NULL, + // R0 == This, R1 == Ring3NewHandle, R2 == Ring3FileName, R3 == NULL, // [SP] == OpenMode, [SP + 8] == Attributes. // Status = GoToRing3 ( 8, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, Ring3NewHandle, Ring3FileName, @@ -683,16 +715,22 @@ CoreFileOpen ( return EFI_OUT_OF_RESOURCES; } - UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); - UserDriver->CoreWrapper = NewFile; - UserDriver->UserPageTable = gUserPageTable; + NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); + NewDriver->CoreWrapper = NewFile; + NewDriver->UserPageTable = UserDriver->UserPageTable; + // + // TODO: Allocate new stacks, because UserDriver can be interrupted + // and interrupt handler may call the same UserDriver again. + // + NewDriver->UserStackTop = UserDriver->UserStackTop; + NewDriver->SysCallStackTop = UserDriver->SysCallStackTop; AllowSupervisorAccessToUserMemory (); - UserDriver->UserSpaceDriver = *Ring3NewHandle; - NewFile->Revision = (*Ring3NewHandle)->Revision; + NewDriver->UserSpaceDriver = *Ring3NewHandle; + NewFile->Revision = (*Ring3NewHandle)->Revision; ForbidSupervisorAccessToUserMemory (); - InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link); + InsertTailList (&mUserSpaceDriversHead, &NewDriver->Link); NewFile->Open = CoreFileOpen; NewFile->Close = CoreFileClose; @@ -728,6 +766,7 @@ CoreOpenVolume ( EFI_FILE_PROTOCOL *File; EFI_PHYSICAL_ADDRESS Physical; USER_SPACE_DRIVER *UserDriver; + USER_SPACE_DRIVER *NewDriver; VOID *EntryPoint; if (Root == NULL) { @@ -737,8 +776,7 @@ CoreOpenVolume ( UserDriver = FindUserSpaceDriver (This); ASSERT (UserDriver != NULL); - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; + This = UserDriver->UserSpaceDriver; AllowSupervisorAccessToUserMemory (); EntryPoint = (VOID *)This->OpenVolume; @@ -760,6 +798,8 @@ CoreOpenVolume ( Status = GoToRing3 ( 2, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, Ring3Root ); @@ -776,16 +816,18 @@ CoreOpenVolume ( return EFI_OUT_OF_RESOURCES; } - UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); - UserDriver->CoreWrapper = File; - UserDriver->UserPageTable = gUserPageTable; + NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); + NewDriver->CoreWrapper = File; + NewDriver->UserPageTable = UserDriver->UserPageTable; + NewDriver->UserStackTop = UserDriver->UserStackTop; + NewDriver->SysCallStackTop = UserDriver->SysCallStackTop; AllowSupervisorAccessToUserMemory (); - UserDriver->UserSpaceDriver = *Ring3Root; - File->Revision = (*Ring3Root)->Revision; + NewDriver->UserSpaceDriver = *Ring3Root; + File->Revision = (*Ring3Root)->Revision; ForbidSupervisorAccessToUserMemory (); - InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link); + InsertTailList (&mUserSpaceDriversHead, &NewDriver->Link); File->Open = CoreFileOpen; File->Close = CoreFileClose; @@ -827,8 +869,7 @@ CoreUnicodeCollationStriColl ( UserDriver = FindUserSpaceDriver (This); ASSERT (UserDriver != NULL); - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; + This = UserDriver->UserSpaceDriver; Size1 = StrSize (Str1); Size2 = StrSize (Str2); @@ -852,6 +893,8 @@ CoreUnicodeCollationStriColl ( Status = GoToRing3 ( 3, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, (UINTN)UserMem, (UINTN)UserMem + Size1 @@ -880,8 +923,7 @@ CoreUnicodeCollationMetaiMatch ( UserDriver = FindUserSpaceDriver (This); ASSERT (UserDriver != NULL); - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; + This = UserDriver->UserSpaceDriver; Size1 = StrSize (String); Size2 = StrSize (Pattern); @@ -905,6 +947,8 @@ CoreUnicodeCollationMetaiMatch ( Status = GoToRing3 ( 3, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, (UINTN)UserMem, (UINTN)UserMem + Size1 @@ -931,8 +975,7 @@ CoreUnicodeCollationStrLwr ( UserDriver = FindUserSpaceDriver (This); ASSERT (UserDriver != NULL); - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; + This = UserDriver->UserSpaceDriver; Size1 = StrSize (Str); @@ -954,6 +997,8 @@ CoreUnicodeCollationStrLwr ( Status = GoToRing3 ( 2, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, (UINTN)UserMem ); @@ -981,8 +1026,7 @@ CoreUnicodeCollationStrUpr ( UserDriver = FindUserSpaceDriver (This); ASSERT (UserDriver != NULL); - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; + This = UserDriver->UserSpaceDriver; Size1 = StrSize (Str); @@ -1004,6 +1048,8 @@ CoreUnicodeCollationStrUpr ( Status = GoToRing3 ( 2, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, (UINTN)UserMem ); @@ -1032,8 +1078,7 @@ CoreUnicodeCollationFatToStr ( UserDriver = FindUserSpaceDriver (This); ASSERT (UserDriver != NULL); - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; + This = UserDriver->UserSpaceDriver; Status = CoreAllocatePages ( AllocateAnyPages, @@ -1053,6 +1098,8 @@ CoreUnicodeCollationFatToStr ( Status = GoToRing3 ( 4, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, FatSize, (UINTN)UserMem, @@ -1084,8 +1131,7 @@ CoreUnicodeCollationStrToFat ( UserDriver = FindUserSpaceDriver (This); ASSERT (UserDriver != NULL); - This = UserDriver->UserSpaceDriver; - gUserPageTable = UserDriver->UserPageTable; + This = UserDriver->UserSpaceDriver; Size1 = StrSize (String); @@ -1107,6 +1153,8 @@ CoreUnicodeCollationStrToFat ( Status = GoToRing3 ( 4, EntryPoint, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, This, (UINTN)UserMem, FatSize, diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h index 4507db4a89..b3f8ba397f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -15,6 +15,8 @@ typedef struct { VOID *CoreWrapper; VOID *UserSpaceDriver; UINTN UserPageTable; + UINTN UserStackTop; + UINTN SysCallStackTop; LIST_ENTRY Link; } USER_SPACE_DRIVER; diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 6d079ee860..349708f761 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -8,8 +8,6 @@ #include extern ASM_PFX(CallBootService) -extern ASM_PFX(gCoreSysCallStackTop) -extern ASM_PFX(gRing3CallStackTop) extern ASM_PFX(gRing3EntryPoint) DEFAULT REL @@ -140,7 +138,7 @@ ASM_PFX(CoreBootServices): mov gs, ax ; Save User Stack pointers and switch to Core SysCall Stack. - mov rax, [ASM_PFX(gCoreSysCallStackTop)] + mov rax, [ASM_PFX(mCoreSysCallStackTop)] sub rax, 8 mov [rax], rsp mov rsp, rax @@ -192,10 +190,14 @@ o64 sysret ; EFI_STATUS ; EFIAPI ; CallRing3 ( -; IN RING3_CALL_DATA *Data +; IN RING3_CALL_DATA *Data, +; IN UINTN UserStackTop, +; IN UINTN SysCallStackTop ; ); ; ; (rcx) Data +; (rdx) UserStackTop +; (r8) SysCallStackTop ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): @@ -216,7 +218,9 @@ ASM_PFX(CallRing3): mov [ASM_PFX(CoreRsp)], rsp ; Save input Arguments. - mov r8, [ASM_PFX(gRing3CallStackTop)] + mov [ASM_PFX(mRing3CallStackTop)], rdx + mov [ASM_PFX(mCoreSysCallStackTop)], r8 + mov r8, [ASM_PFX(mRing3CallStackTop)] mov r9, [ASM_PFX(gRing3EntryPoint)] mov r10, rcx @@ -276,3 +280,11 @@ ASM_PFX(gUserPageTable): ALIGN 4096 ASM_PFX(CoreRsp): resq 1 + +global ASM_PFX(mRing3CallStackTop) +ASM_PFX(mRing3CallStackTop): + resq 1 + +global ASM_PFX(mCoreSysCallStackTop) +ASM_PFX(mCoreSysCallStackTop): + resq 1 diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index b1f0b66f2b..ee98e905b9 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -264,7 +264,7 @@ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf -INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf @@ -290,7 +290,7 @@ INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf -INF FatPkg/EnhancedFatDxe/Fat.inf +INF USER FatPkg/EnhancedFatDxe/Fat.inf INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index 5e7f2a9d79..f3d5243bde 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -266,7 +266,7 @@ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf -INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf @@ -292,7 +292,7 @@ INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf -INF FatPkg/EnhancedFatDxe/Fat.inf +INF USER FatPkg/EnhancedFatDxe/Fat.inf INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 6a2212032b..d75733da6a 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -298,7 +298,7 @@ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf -INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf @@ -324,7 +324,7 @@ INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf -INF FatPkg/EnhancedFatDxe/Fat.inf +INF USER FatPkg/EnhancedFatDxe/Fat.inf INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf From e4788e90e9edab8dc738b1b9f75ca868914d99ae Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 13 Jan 2025 13:31:06 +0300 Subject: [PATCH 308/341] Ring3: Fixed line endings. --- MdeModulePkg/Core/Dxe/DxeMain.h | 152 +++++++++--------- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 48 +++--- .../Dxe/SysCall/X64/CoreBootServices.nasm | 8 +- 3 files changed, 104 insertions(+), 104 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 9d00273b26..476e8832ef 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2647,10 +2647,10 @@ UnprotectUefiImage ( IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath ); -UEFI_IMAGE_RECORD * -GetUefiImageRecord ( - IN LOADED_IMAGE_PRIVATE_DATA *Image - ); +UEFI_IMAGE_RECORD * +GetUefiImageRecord ( + IN LOADED_IMAGE_PRIVATE_DATA *Image + ); /** ExitBootServices Callback function for memory protection. @@ -2712,7 +2712,7 @@ EFI_STATUS CoreInitializeHandleServices ( VOID ); - + /** Set UEFI image memory attributes. @@ -2727,76 +2727,76 @@ SetUefiImageMemoryAttributes ( IN UINT64 Attributes ); -/** - Set UEFI image protection attributes. - - @param[in] ImageRecord A UEFI image record - @param[in] IsUser Whether UEFI image record is User Image. -**/ -VOID -SetUefiImageProtectionAttributes ( - IN UEFI_IMAGE_RECORD *ImageRecord, - IN BOOLEAN IsUser - ); - -EFI_STATUS -EFIAPI -CoreBootServices ( - IN UINT8 Type, - ... - ); - -EFI_STATUS -EFIAPI -CallBootService ( - IN UINT8 Type, - IN CORE_STACK *CoreRbp, - IN RING3_STACK *UserRsp - ); - -VOID -EFIAPI -AllowSupervisorAccessToUserMemory ( - VOID - ); - -VOID -EFIAPI -ForbidSupervisorAccessToUserMemory ( - VOID - ); - -EFI_STATUS -EFIAPI -GoToRing3 ( - IN UINT8 Number, - IN VOID *EntryPoint, - IN UINTN UserStackTop, - IN UINTN SysCallStackTop, - ... - ); - -EFI_STATUS -EFIAPI -InitializeRing3 ( - IN EFI_HANDLE ImageHandle, - IN LOADED_IMAGE_PRIVATE_DATA *Image - ); - -VOID -EFIAPI -FreeProtocolsList ( - VOID - ); - -UINTN -EFIAPI -InitializeUserPageTable ( - IN LOADED_IMAGE_PRIVATE_DATA *Image, - IN UINTN SysCallStackBase, - IN UINTN SysCallStackSize, - IN UINTN UserStackBase, - IN UINTN UserStackSize - ); +/** + Set UEFI image protection attributes. + + @param[in] ImageRecord A UEFI image record + @param[in] IsUser Whether UEFI image record is User Image. +**/ +VOID +SetUefiImageProtectionAttributes ( + IN UEFI_IMAGE_RECORD *ImageRecord, + IN BOOLEAN IsUser + ); + +EFI_STATUS +EFIAPI +CoreBootServices ( + IN UINT8 Type, + ... + ); + +EFI_STATUS +EFIAPI +CallBootService ( + IN UINT8 Type, + IN CORE_STACK *CoreRbp, + IN RING3_STACK *UserRsp + ); + +VOID +EFIAPI +AllowSupervisorAccessToUserMemory ( + VOID + ); + +VOID +EFIAPI +ForbidSupervisorAccessToUserMemory ( + VOID + ); + +EFI_STATUS +EFIAPI +GoToRing3 ( + IN UINT8 Number, + IN VOID *EntryPoint, + IN UINTN UserStackTop, + IN UINTN SysCallStackTop, + ... + ); + +EFI_STATUS +EFIAPI +InitializeRing3 ( + IN EFI_HANDLE ImageHandle, + IN LOADED_IMAGE_PRIVATE_DATA *Image + ); + +VOID +EFIAPI +FreeProtocolsList ( + VOID + ); + +UINTN +EFIAPI +InitializeUserPageTable ( + IN LOADED_IMAGE_PRIVATE_DATA *Image, + IN UINTN SysCallStackBase, + IN UINTN SysCallStackSize, + IN UINTN UserStackBase, + IN UINTN UserStackSize + ); #endif diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index 303a18360d..0421d4a07f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -96,9 +96,9 @@ copy: pop eax %endmacro -ALIGN 4096 -global ASM_PFX(SysCallBase) -ASM_PFX(SysCallBase): +ALIGN 4096 +global ASM_PFX(SysCallBase) +ASM_PFX(SysCallBase): ;------------------------------------------------------------------------------ ; EFI_STATUS @@ -220,9 +220,9 @@ ASM_PFX(CallRing3): sti sysexit -ALIGN 4096 -global ASM_PFX(SysCallEnd) -ASM_PFX(SysCallEnd): +ALIGN 4096 +global ASM_PFX(SysCallEnd) +ASM_PFX(SysCallEnd): ;------------------------------------------------------------------------------ ; VOID @@ -245,24 +245,24 @@ ASM_PFX(ReturnToCore): ret SECTION .data -ALIGN 4096 - -global ASM_PFX(gCorePageTable) -ASM_PFX(gCorePageTable): - resd 1 - -global ASM_PFX(gUserPageTable) -ASM_PFX(gUserPageTable): - resd 1 - -ALIGN 4096 +ALIGN 4096 + +global ASM_PFX(gCorePageTable) +ASM_PFX(gCorePageTable): + resd 1 + +global ASM_PFX(gUserPageTable) +ASM_PFX(gUserPageTable): + resd 1 + +ALIGN 4096 ASM_PFX(CoreEsp): resd 1 -global ASM_PFX(mRing3CallStackTop) -ASM_PFX(mRing3CallStackTop): - resd 1 - -global ASM_PFX(mCoreSysCallStackTop) -ASM_PFX(mCoreSysCallStackTop): - resd 1 +global ASM_PFX(mRing3CallStackTop) +ASM_PFX(mRing3CallStackTop): + resd 1 + +global ASM_PFX(mCoreSysCallStackTop) +ASM_PFX(mCoreSysCallStackTop): + resd 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 349708f761..2f98fbd223 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -281,10 +281,10 @@ ALIGN 4096 ASM_PFX(CoreRsp): resq 1 -global ASM_PFX(mRing3CallStackTop) +global ASM_PFX(mRing3CallStackTop) ASM_PFX(mRing3CallStackTop): resq 1 -global ASM_PFX(mCoreSysCallStackTop) -ASM_PFX(mCoreSysCallStackTop): - resq 1 +global ASM_PFX(mCoreSysCallStackTop) +ASM_PFX(mCoreSysCallStackTop): + resq 1 From 2acb409486a64ff0661a40eb626c92269e3a16c1 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 13 Jan 2025 20:00:34 +0300 Subject: [PATCH 309/341] SysCall: Refactored out CORE_STACK and RING3_STACK. --- MdeModulePkg/Core/Dxe/DxeMain.h | 16 +- .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 3 +- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 3 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 693 ++++++++++-------- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 16 +- .../Dxe/SysCall/X64/CoreBootServices.nasm | 33 +- 6 files changed, 409 insertions(+), 355 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 476e8832ef..571fa96dcc 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -235,17 +235,6 @@ typedef struct { UINTN UserStackTop; } LOADED_IMAGE_PRIVATE_DATA; -typedef struct { - UINTN Argument1; - UINTN Argument2; - UINTN Argument3; -} CORE_STACK; - -typedef struct { - UINTN Rip; - UINTN Arguments[]; -} RING3_STACK; - #define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \ CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE) @@ -2749,9 +2738,8 @@ CoreBootServices ( EFI_STATUS EFIAPI CallBootService ( - IN UINT8 Type, - IN CORE_STACK *CoreRbp, - IN RING3_STACK *UserRsp + IN UINT8 Type, + IN UINTN *UserArguments ); VOID diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index 94321306b9..c7076578b3 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -74,8 +74,7 @@ SysCallBootService ( Status = CallBootService ( Type, - (CORE_STACK *)CoreRbp, - (RING3_STACK *)(UINTN)Physical + (UINTN *)((UINTN)Physical + sizeof (UINTN)) ); CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 2c20160c34..ec368ed17e 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -80,8 +80,7 @@ SysCallBootService ( Status = CallBootService ( Type, - (CORE_STACK *)CoreRbp, - (RING3_STACK *)(UINTN)Physical + (UINTN *)((UINTN)Physical + sizeof (UINTN)) ); // // TODO: Fix memory leak for ReturnToCore(). diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 8da430831c..bcad4bc769 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -73,7 +73,7 @@ EFIAPI ReturnToCore ( IN EFI_STATUS Status ); - + VOID EFIAPI FreeProtocolsList ( @@ -277,22 +277,41 @@ PrepareRing3Interface ( return Ring3Interface; } -// -// Stack: -// rsp - User Rsp -// rbp - User Rbp -// rcx - User Rip for SYSCALL -// r11 - User RFLAGS for SYSCALL -// r9 - Argument 3 -// r8 - Argument 2 -// rdx - Argument 1 <- CoreRbp -// +STATIC +UINTN * +EFIAPI +CopyUserArguments ( + IN UINTN NumberOfArguments, + IN UINTN *UserArguments + ) +{ + UINTN *Arguments; + UINT64 Attributes; + // + // Check User variables. + // + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArguments, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArguments + (NumberOfArguments + 1) * sizeof (UINTN) - 1), &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + + AllowSupervisorAccessToUserMemory (); + Arguments = AllocateCopyPool ( + (NumberOfArguments + 1) * sizeof (UINTN), + (VOID *)UserArguments + ); + ForbidSupervisorAccessToUserMemory (); + + ASSERT (Arguments != NULL); + + return Arguments; +} + EFI_STATUS EFIAPI CallBootService ( - IN UINT8 Type, - IN CORE_STACK *CoreRbp, - IN RING3_STACK *UserRsp + IN UINT8 Type, + IN UINTN *UserArguments ) { EFI_STATUS Status; @@ -311,6 +330,8 @@ CallBootService ( UINT32 PagesNumber; EFI_PHYSICAL_ADDRESS Ring3Pages; USER_SPACE_DRIVER *UserDriver; + UINTN *Arguments; + EFI_PHYSICAL_ADDRESS PhysAddr; EFI_DRIVER_BINDING_PROTOCOL *CoreDriverBinding; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *CoreSimpleFileSystem; @@ -325,17 +346,14 @@ CallBootService ( Argument5 = 0; Argument6 = 0; Interface = NULL; - // - // Check User variables. - // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserRsp, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); DEBUG ((DEBUG_VERBOSE, "Type: %a\n", SysCallNames[Type])); switch (Type) { case SysCallReturnToCore: - ReturnToCore (CoreRbp->Argument1); + Arguments = CopyUserArguments (1, UserArguments); + + ReturnToCore (Arguments[1]); break; case SysCallLocateProtocol: // @@ -343,25 +361,28 @@ CallBootService ( // Argument 2: VOID *CoreRegistration // Argument 3: VOID **Interface // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + Arguments = CopyUserArguments (3, UserArguments); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[1], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + sizeof (EFI_GUID) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[1] + sizeof (EFI_GUID) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + sizeof (VOID *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument1, &CoreProtocol, &MemoryCoreSize); + Status = FindGuid ((EFI_GUID *)Arguments[1], &CoreProtocol, &MemoryCoreSize); ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { + FreePool (Arguments); return Status; } Status = gBS->LocateProtocol ( CoreProtocol, - (VOID *)CoreRbp->Argument2, + (VOID *)Arguments[2], &Interface ); @@ -370,10 +391,11 @@ CallBootService ( Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); ASSERT (Interface != NULL); - *(VOID **)CoreRbp->Argument3 = Interface; + *(VOID **)Arguments[3] = Interface; } ForbidSupervisorAccessToUserMemory (); + FreePool (Arguments); return Status; case SysCallOpenProtocol: @@ -385,50 +407,47 @@ CallBootService ( // Argument 5: EFI_HANDLE CoreControllerHandle // Argument 6: UINT32 Attributes // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + Arguments = CopyUserArguments (6, UserArguments); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (EFI_GUID) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - if ((VOID **)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + if ((VOID **)Arguments[3] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + sizeof (VOID *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); } - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize); + ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { - ForbidSupervisorAccessToUserMemory (); + FreePool (Arguments); return Status; } - Argument4 = UserRsp->Arguments[4]; - Argument5 = UserRsp->Arguments[5]; - Argument6 = UserRsp->Arguments[6]; - ForbidSupervisorAccessToUserMemory (); - Status = gBS->OpenProtocol ( - (EFI_HANDLE)CoreRbp->Argument1, + (EFI_HANDLE)Arguments[1], CoreProtocol, - ((VOID **)CoreRbp->Argument3 != NULL) ? &Interface : NULL, - (EFI_HANDLE)Argument4, - (EFI_HANDLE)Argument5, - (UINT32)Argument6 + ((VOID **)Arguments[3] != NULL) ? &Interface : NULL, + (EFI_HANDLE)Arguments[4], + (EFI_HANDLE)Arguments[5], + (UINT32)Arguments[6] ); - if ((VOID **)CoreRbp->Argument3 != NULL) { + if ((VOID **)Arguments[3] != NULL) { AllowSupervisorAccessToUserMemory (); if (Interface != NULL) { Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); } - *(VOID **)CoreRbp->Argument3 = Interface; + *(VOID **)Arguments[3] = Interface; ForbidSupervisorAccessToUserMemory (); } + FreePool (Arguments); return Status; case SysCallInstallMultipleProtocolInterfaces: @@ -436,18 +455,20 @@ CallBootService ( // Argument 1: EFI_HANDLE *Handle // ... // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + Arguments = CopyUserArguments (2, UserArguments); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[1], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + sizeof (EFI_HANDLE *) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[1] + sizeof (EFI_HANDLE *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (VOID **) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (VOID **) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - CoreHandle = *(EFI_HANDLE *)CoreRbp->Argument1; - UserArgList = (VOID **)CoreRbp->Argument2; + CoreHandle = *(EFI_HANDLE *)Arguments[1]; + UserArgList = (VOID **)Arguments[2]; for (Index = 0; UserArgList[Index] != NULL; Index += 2) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] - 1), &Attributes); @@ -466,6 +487,7 @@ CallBootService ( Index -= 2; } + FreePool (Arguments); return Status; } @@ -532,6 +554,7 @@ CallBootService ( (VOID *)gBS->InstallMultipleProtocolInterfaces ); + FreePool (Arguments); return Status; case SysCallCloseProtocol: @@ -541,30 +564,29 @@ CallBootService ( // Argument 3: EFI_HANDLE CoreAgentHandle // Argument 4: EFI_HANDLE CoreControllerHandle // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + Arguments = CopyUserArguments (4, UserArguments); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (EFI_GUID) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize); + ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { - ForbidSupervisorAccessToUserMemory (); + FreePool (Arguments); return Status; } - Argument4 = UserRsp->Arguments[4]; - ForbidSupervisorAccessToUserMemory (); - Status = gBS->CloseProtocol ( - (EFI_HANDLE)CoreRbp->Argument1, + (EFI_HANDLE)Arguments[1], CoreProtocol, - (EFI_HANDLE)CoreRbp->Argument3, - (EFI_HANDLE)Argument4 + (EFI_HANDLE)Arguments[3], + (EFI_HANDLE)Arguments[4] ); + FreePool (Arguments); return Status; case SysCallHandleProtocol: @@ -573,24 +595,27 @@ CallBootService ( // Argument 2: EFI_GUID *Protocol // Argument 3: VOID **Interface // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + Arguments = CopyUserArguments (3, UserArguments); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (EFI_GUID) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (VOID *) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + sizeof (VOID *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize); ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { + FreePool (Arguments); return Status; } Status = gBS->HandleProtocol ( - (EFI_HANDLE)CoreRbp->Argument1, + (EFI_HANDLE)Arguments[1], CoreProtocol, &Interface ); @@ -600,10 +625,11 @@ CallBootService ( Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); ASSERT (Interface != NULL); - *(VOID **)CoreRbp->Argument3 = Interface; + *(VOID **)Arguments[3] = Interface; } ForbidSupervisorAccessToUserMemory (); + FreePool (Arguments); return Status; case SysCallAllocatePages: @@ -613,25 +639,25 @@ CallBootService ( // Argument 3: UINTN NumberOfPages // Argument 4: EFI_PHYSICAL_ADDRESS *Memory // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + Arguments = CopyUserArguments (4, UserArguments); Status = gBS->AllocatePages ( - (EFI_ALLOCATE_TYPE)CoreRbp->Argument1, - (EFI_MEMORY_TYPE)CoreRbp->Argument2, - CoreRbp->Argument3, + (EFI_ALLOCATE_TYPE)Arguments[1], + (EFI_MEMORY_TYPE)Arguments[2], + Arguments[3], (EFI_PHYSICAL_ADDRESS *)&Argument4 ); - AllowSupervisorAccessToUserMemory (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + sizeof (EFI_PHYSICAL_ADDRESS) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + sizeof (EFI_PHYSICAL_ADDRESS) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - *(EFI_PHYSICAL_ADDRESS *)UserRsp->Arguments[4] = (EFI_PHYSICAL_ADDRESS)Argument4; + AllowSupervisorAccessToUserMemory (); + *(EFI_PHYSICAL_ADDRESS *)Arguments[4] = (EFI_PHYSICAL_ADDRESS)Argument4; ForbidSupervisorAccessToUserMemory (); + FreePool (Arguments); return Status; case SysCallFreePages: @@ -639,30 +665,39 @@ CallBootService ( // Argument 1: UINTN NumberOfPages // Argument 2: EFI_PHYSICAL_ADDRESS Memory // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + Arguments = CopyUserArguments (3, UserArguments); + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[2]; + + gCpu->GetMemoryAttributes (gCpu, PhysAddr, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + CoreRbp->Argument1 * EFI_PAGE_SIZE - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, PhysAddr + Arguments[1] * EFI_PAGE_SIZE - 1, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - return gBS->FreePages ( - *(EFI_PHYSICAL_ADDRESS *)&CoreRbp->Argument2, - CoreRbp->Argument1 - ); + Status = gBS->FreePages (PhysAddr, Arguments[1]); + + FreePool (Arguments); + return Status; case SysCallRaiseTpl: // // Argument 1: EFI_TPL NewTpl // - return (EFI_STATUS)gBS->RaiseTPL ( - (EFI_TPL)CoreRbp->Argument1 - ); + Arguments = CopyUserArguments (1, UserArguments); + + Status = (EFI_STATUS)gBS->RaiseTPL ((EFI_TPL)Arguments[1]); + + FreePool (Arguments); + return Status; case SysCallRestoreTpl: // // Argument 1: EFI_TPL NewTpl // - gBS->RestoreTPL ((EFI_TPL)CoreRbp->Argument1); + Arguments = CopyUserArguments (1, UserArguments); + gBS->RestoreTPL ((EFI_TPL)Arguments[1]); + + FreePool (Arguments); return EFI_SUCCESS; case SysCallLocateHandleBuffer: @@ -673,45 +708,46 @@ CallBootService ( // Argument 4: UINTN *NumberHandles // Argument 5: EFI_HANDLE **Buffer // - if ((EFI_GUID *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + Arguments = CopyUserArguments (5, UserArguments); + + if ((EFI_GUID *)Arguments[2] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (EFI_GUID) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize); ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { + FreePool (Arguments); return Status; } } StatusBS = gBS->LocateHandleBuffer ( - (EFI_LOCATE_SEARCH_TYPE)CoreRbp->Argument1, + (EFI_LOCATE_SEARCH_TYPE)Arguments[1], CoreProtocol, - (VOID *)CoreRbp->Argument3, + (VOID *)Arguments[3], &Argument4, (EFI_HANDLE **)&Argument5 ); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - AllowSupervisorAccessToUserMemory (); - if ((UINTN *)UserRsp->Arguments[4] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + if ((UINTN *)Arguments[4] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + sizeof (UINTN) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - *(UINTN *)UserRsp->Arguments[4] = Argument4; + AllowSupervisorAccessToUserMemory (); + *(UINTN *)Arguments[4] = Argument4; + ForbidSupervisorAccessToUserMemory (); } - if ((EFI_HANDLE **)UserRsp->Arguments[5] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + if ((EFI_HANDLE **)Arguments[5] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[5], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + sizeof (EFI_HANDLE *) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[5] + sizeof (EFI_HANDLE *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (Argument4 * sizeof (EFI_HANDLE *)); @@ -723,17 +759,20 @@ CallBootService ( &Ring3Pages ); if (EFI_ERROR (Status)) { + FreePool (Arguments); return Status; } + AllowSupervisorAccessToUserMemory (); CopyMem ((VOID *)(UINTN)Ring3Pages, (VOID *)Argument5, Argument4 * sizeof (EFI_HANDLE *)); FreePool ((VOID *)Argument5); - *(EFI_HANDLE **)UserRsp->Arguments[5] = (EFI_HANDLE *)(UINTN)Ring3Pages; + *(EFI_HANDLE **)Arguments[5] = (EFI_HANDLE *)(UINTN)Ring3Pages; + ForbidSupervisorAccessToUserMemory (); } - ForbidSupervisorAccessToUserMemory (); + FreePool (Arguments); return StatusBS; case SysCallCalculateCrc32: @@ -742,34 +781,38 @@ CallBootService ( // Argument 2: UINTN DataSize // Argument 3: UINT32 *Crc32 // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + Arguments = CopyUserArguments (3, UserArguments); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[1], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + CoreRbp->Argument2 - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[1] + Arguments[2] - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (UINT32 *) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + sizeof (UINT32 *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument4 = (UINTN)AllocatePool (CoreRbp->Argument2); + Argument4 = (UINTN)AllocatePool (Arguments[2]); if ((VOID *)Argument4 == NULL) { + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)Argument4, (VOID *)CoreRbp->Argument1, CoreRbp->Argument2); + CopyMem ((VOID *)Argument4, (VOID *)Arguments[1], Arguments[2]); ForbidSupervisorAccessToUserMemory (); Status = gBS->CalculateCrc32 ( (VOID *)Argument4, - CoreRbp->Argument2, + Arguments[2], (UINT32 *)&Argument5 ); AllowSupervisorAccessToUserMemory (); - *(UINT32 *)CoreRbp->Argument3 = (UINT32)Argument5; + *(UINT32 *)Arguments[3] = (UINT32)Argument5; ForbidSupervisorAccessToUserMemory (); + FreePool (Arguments); return Status; case SysCallGetVariable: @@ -780,55 +823,58 @@ CallBootService ( // Argument 4: UINTN *DataSize // Argument 5: VOID *Data OPTIONAL // - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument1, &Attributes); + Arguments = CopyUserArguments (5, UserArguments); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[1], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + sizeof (EFI_GUID) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (EFI_GUID) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - if ((UINT32 *)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + if ((UINT32 *)Arguments[3] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + sizeof (UINT32) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + sizeof (UINT32) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); } - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument1 + StrSize ((CHAR16 *)CoreRbp->Argument1) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[1] + StrSize ((CHAR16 *)Arguments[1]) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument6 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument1), (CHAR16 *)CoreRbp->Argument1); + Argument6 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[1]), (CHAR16 *)Arguments[1]); if ((VOID *)Argument6 == NULL) { ForbidSupervisorAccessToUserMemory (); + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } - Status = FindGuid ((EFI_GUID *)CoreRbp->Argument2, &CoreProtocol, &MemoryCoreSize); + Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize); if (EFI_ERROR (Status)) { ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument6); + FreePool (Arguments); return Status; } - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + sizeof (UINTN) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + sizeof (UINTN) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument4 = *(UINTN *)UserRsp->Arguments[4]; + Argument4 = *(UINTN *)Arguments[4]; - if ((VOID *)UserRsp->Arguments[5] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[5], &Attributes); + if ((VOID *)Arguments[5] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[5], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[5] + Argument4 - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[5] + Argument4 - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); Argument5 = (UINTN)AllocatePool (Argument4); if ((VOID *)Argument5 == NULL) { ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument6); + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } } @@ -843,14 +889,14 @@ CallBootService ( ); AllowSupervisorAccessToUserMemory (); - if ((VOID *)UserRsp->Arguments[5] != NULL) { - CopyMem ((VOID *)UserRsp->Arguments[5], (VOID *)Argument5, Argument4); + if ((VOID *)Arguments[5] != NULL) { + CopyMem ((VOID *)Arguments[5], (VOID *)Argument5, Argument4); } - *(UINTN *)UserRsp->Arguments[4] = Argument4; + *(UINTN *)Arguments[4] = Argument4; - if ((UINT32 *)CoreRbp->Argument3 != NULL) { - *(UINT32 *)CoreRbp->Argument3 = (UINT32)Attributes; + if ((UINT32 *)Arguments[3] != NULL) { + *(UINT32 *)Arguments[3] = (UINT32)Attributes; } ForbidSupervisorAccessToUserMemory (); @@ -860,6 +906,7 @@ CallBootService ( FreePool ((VOID *)Argument5); } + FreePool (Arguments); return Status; case SysCallBlockIoReset: @@ -867,16 +914,22 @@ CallBootService ( // Argument 1: EFI_BLOCK_IO_PROTOCOL *This // Argument 2: BOOLEAN ExtendedVerification // - BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + Arguments = CopyUserArguments (2, UserArguments); + + BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]); if (BlockIo == NULL) { + FreePool (Arguments); return EFI_NOT_FOUND; } - return BlockIo->Reset ( - BlockIo, - (BOOLEAN)CoreRbp->Argument2 - ); + Status = BlockIo->Reset ( + BlockIo, + (BOOLEAN)Arguments[2] + ); + + FreePool (Arguments); + return Status; case SysCallBlockIoRead: // @@ -886,53 +939,50 @@ CallBootService ( // Argument 4: VOID *Buffer // Argument 5: EFI_LBA Lba // - BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (BlockIo == NULL) { - return EFI_NOT_FOUND; - } - -#if defined (MDE_CPU_ARM) - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); -#else - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); -#endif - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - AllowSupervisorAccessToUserMemory (); #if defined (MDE_CPU_ARM) // // EFI_LBA Lba is aligned on 8 bytes. // - Attributes = *(UINT64 *)&UserRsp->Arguments[6]; + Arguments = CopyUserArguments (7, UserArguments); + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[6]; #else - Attributes = *(UINT64 *)&UserRsp->Arguments[5]; + Arguments = CopyUserArguments (6, UserArguments); + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5]; #endif - ForbidSupervisorAccessToUserMemory (); - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]); + + if (BlockIo == NULL) { + FreePool (Arguments); + return EFI_NOT_FOUND; + } + + Argument5 = (UINTN)AllocatePool (Arguments[3]); if ((VOID *)Argument5 == NULL) { + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } Status = BlockIo->ReadBlocks ( BlockIo, - (UINT32)CoreRbp->Argument2, - (EFI_LBA)Attributes, - CoreRbp->Argument3, + (UINT32)Arguments[2], + (EFI_LBA)PhysAddr, + Arguments[3], (VOID *)Argument5 ); - AllowSupervisorAccessToUserMemory (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + Arguments[3] - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)Arguments[4], (VOID *)Argument5, Arguments[3]); ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument5); + FreePool (Arguments); return Status; case SysCallBlockIoWrite: @@ -943,65 +993,69 @@ CallBootService ( // Argument 4: VOID *Buffer // Argument 5: EFI_LBA Lba // - BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); +#if defined (MDE_CPU_ARM) + // + // EFI_LBA Lba is aligned on 8 bytes. + // + Arguments = CopyUserArguments (7, UserArguments); + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[6]; +#else + Arguments = CopyUserArguments (6, UserArguments); + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5]; +#endif + + BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]); if (BlockIo == NULL) { + FreePool (Arguments); return EFI_NOT_FOUND; } -#if defined (MDE_CPU_ARM) - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); -#else - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); -#endif - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + Argument5 = (UINTN)AllocatePool (Arguments[3]); if ((VOID *)Argument5 == NULL) { + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } - AllowSupervisorAccessToUserMemory (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + Arguments[3] - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - CopyMem ((VOID *)Argument5,(VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); - -#if defined (MDE_CPU_ARM) - // - // EFI_LBA Lba is aligned on 8 bytes. - // - Attributes = *(UINT64 *)&UserRsp->Arguments[6]; -#else - Attributes = *(UINT64 *)&UserRsp->Arguments[5]; -#endif + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)Argument5, (VOID *)Arguments[4], Arguments[3]); ForbidSupervisorAccessToUserMemory (); Status = BlockIo->WriteBlocks ( BlockIo, - (UINT32)CoreRbp->Argument2, - (EFI_LBA)Attributes, - CoreRbp->Argument3, + (UINT32)Arguments[2], + (EFI_LBA)PhysAddr, + Arguments[3], (VOID *)Argument5 ); FreePool ((VOID *)Argument5); + FreePool (Arguments); return Status; case SysCallBlockIoFlush: // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This // - BlockIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + Arguments = CopyUserArguments (1, UserArguments); + + BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]); if (BlockIo == NULL) { + FreePool (Arguments); return EFI_NOT_FOUND; } - return BlockIo->FlushBlocks (BlockIo); + Status = BlockIo->FlushBlocks (BlockIo); + + FreePool (Arguments); + return Status; case SysCallDiskIoRead: // @@ -1011,53 +1065,50 @@ CallBootService ( // Argument 4: VOID *Buffer // Argument 5: UINT64 Offset // - DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); - - if (DiskIo == NULL) { - return EFI_NOT_FOUND; - } - -#if defined (MDE_CPU_ARM) - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); -#else - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); -#endif - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - AllowSupervisorAccessToUserMemory (); #if defined (MDE_CPU_ARM) // // UINT64 Offset is aligned on 8 bytes. // - Attributes = *(UINT64 *)&UserRsp->Arguments[6]; + Arguments = CopyUserArguments (7, UserArguments); + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[6]; #else - Attributes = *(UINT64 *)&UserRsp->Arguments[5]; + Arguments = CopyUserArguments (6, UserArguments); + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5]; #endif - ForbidSupervisorAccessToUserMemory (); - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + DiskIo = FindInterface (FALSE, (VOID *)Arguments[1]); + + if (DiskIo == NULL) { + FreePool (Arguments); + return EFI_NOT_FOUND; + } + + Argument5 = (UINTN)AllocatePool (Arguments[3]); if ((VOID *)Argument5 == NULL) { + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } Status = DiskIo->ReadDisk ( DiskIo, - (UINT32)CoreRbp->Argument2, - Attributes, - CoreRbp->Argument3, + (UINT32)Arguments[2], + (UINT64)PhysAddr, + Arguments[3], (VOID *)Argument5 ); - AllowSupervisorAccessToUserMemory (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + Arguments[3] - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)Arguments[4], (VOID *)Argument5, Arguments[3]); ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument5); + FreePool (Arguments); return Status; case SysCallDiskIoWrite: @@ -1068,52 +1119,50 @@ CallBootService ( // Argument 4: VOID *Buffer // Argument 5: UINT64 Offset // - DiskIo = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); +#if defined (MDE_CPU_ARM) + // + // UINT64 Offset is aligned on 8 bytes. + // + Arguments = CopyUserArguments (7, UserArguments); + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[6]; +#else + Arguments = CopyUserArguments (6, UserArguments); + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5]; +#endif + + DiskIo = FindInterface (FALSE, (VOID *)Arguments[1]); if (DiskIo == NULL) { + FreePool (Arguments); return EFI_NOT_FOUND; } -#if defined (MDE_CPU_ARM) - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 8 * sizeof (UINTN) - 1), &Attributes); -#else - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 7 * sizeof (UINTN) - 1), &Attributes); -#endif - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + Argument5 = (UINTN)AllocatePool (Arguments[3]); if ((VOID *)Argument5 == NULL) { + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } - AllowSupervisorAccessToUserMemory (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + Arguments[3] - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - CopyMem ((VOID *)Argument5, (VOID *)UserRsp->Arguments[4], CoreRbp->Argument3); - -#if defined (MDE_CPU_ARM) - // - // UINT64 Offset is aligned on 8 bytes. - // - Attributes = *(UINT64 *)&UserRsp->Arguments[6]; -#else - Attributes = *(UINT64 *)&UserRsp->Arguments[5]; -#endif + AllowSupervisorAccessToUserMemory (); + CopyMem ((VOID *)Argument5, (VOID *)Arguments[4], Arguments[3]); ForbidSupervisorAccessToUserMemory (); Status = DiskIo->WriteDisk ( DiskIo, - (UINT32)CoreRbp->Argument2, - Attributes, - CoreRbp->Argument3, + (UINT32)Arguments[2], + (UINT64)PhysAddr, + Arguments[3], (VOID *)Argument5 ); FreePool ((VOID *)Argument5); + FreePool (Arguments); return Status; case SysCallUnicodeStriColl: @@ -1122,42 +1171,47 @@ CallBootService ( // Argument 2: CHAR16 *Str1 // Argument 3: CHAR16 *Str2 // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + Arguments = CopyUserArguments (3, UserArguments); + + Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { + FreePool (Arguments); return EFI_NOT_FOUND; } - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + if ((CHAR16 *)Arguments[2] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + StrSize ((CHAR16 *)Arguments[2]) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } } - if ((CHAR16 *)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + if ((CHAR16 *)Arguments[3] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + StrSize ((CHAR16 *)Arguments[3]) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); + Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[3]), (CHAR16 *)Arguments[3]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument5 == NULL) { if ((VOID *)Argument4 != NULL) { FreePool ((VOID *)Argument4); } + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } } @@ -1176,6 +1230,7 @@ CallBootService ( FreePool ((VOID *)Argument5); } + FreePool (Arguments); return Status; case SysCallUnicodeMetaiMatch: @@ -1184,42 +1239,47 @@ CallBootService ( // Argument 2: CHAR16 *String // Argument 3: CHAR16 *Pattern // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + Arguments = CopyUserArguments (3, UserArguments); + + Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { + FreePool (Arguments); return EFI_NOT_FOUND; } - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + if ((CHAR16 *)Arguments[2] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + StrSize ((CHAR16 *)Arguments[2]) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } } - if ((CHAR16 *)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + if ((CHAR16 *)Arguments[3] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + StrSize ((CHAR16 *)CoreRbp->Argument3) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + StrSize ((CHAR16 *)Arguments[3]) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument3), (CHAR16 *)CoreRbp->Argument3); + Argument5 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[3]), (CHAR16 *)Arguments[3]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument5 == NULL) { if ((VOID *)Argument4 != NULL) { FreePool ((VOID *)Argument4); } + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } } @@ -1238,6 +1298,7 @@ CallBootService ( FreePool ((VOID *)Argument5); } + FreePool (Arguments); return Status; case SysCallUnicodeStrLwr: @@ -1245,23 +1306,27 @@ CallBootService ( // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This // Argument 2: CHAR16 *Str // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + Arguments = CopyUserArguments (2, UserArguments); + + Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { + FreePool (Arguments); return EFI_NOT_FOUND; } - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + if ((CHAR16 *)Arguments[2] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + StrSize ((CHAR16 *)Arguments[2]) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } } @@ -1273,12 +1338,13 @@ CallBootService ( if ((VOID *)Argument4 != NULL) { AllowSupervisorAccessToUserMemory (); - Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); + Status = StrCpyS ((CHAR16 *)Arguments[2], StrLen ((CHAR16 *)Arguments[2]) + 1, (CHAR16 *)Argument4); ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument4); } + FreePool (Arguments); return EFI_SUCCESS; case SysCallUnicodeStrUpr: @@ -1286,23 +1352,27 @@ CallBootService ( // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This // Argument 2: CHAR16 *Str // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + Arguments = CopyUserArguments (2, UserArguments); + + Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { + FreePool (Arguments); return EFI_NOT_FOUND; } - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + if ((CHAR16 *)Arguments[2] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + StrSize ((CHAR16 *)Arguments[2]) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } } @@ -1314,12 +1384,13 @@ CallBootService ( if ((VOID *)Argument4 != NULL) { AllowSupervisorAccessToUserMemory (); - Status = StrCpyS ((CHAR16 *)CoreRbp->Argument2, StrLen ((CHAR16 *)CoreRbp->Argument2) + 1, (CHAR16 *)Argument4); + Status = StrCpyS ((CHAR16 *)Arguments[2], StrLen ((CHAR16 *)Arguments[2]) + 1, (CHAR16 *)Argument4); ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument4); } + FreePool (Arguments); return EFI_SUCCESS; case SysCallUnicodeFatToStr: @@ -1329,50 +1400,50 @@ CallBootService ( // Argument 3: CHAR8 *Fat // Argument 4: CHAR16 *String // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + Arguments = CopyUserArguments (4, UserArguments); + + Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { + FreePool (Arguments); return EFI_NOT_FOUND; } - if ((CHAR8 *)CoreRbp->Argument3 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument3, &Attributes); + if ((CHAR8 *)Arguments[3] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument3 + CoreRbp->Argument2 - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + Arguments[2] - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - Argument4 = (UINTN)AllocateCopyPool (CoreRbp->Argument2, (CHAR8 *)CoreRbp->Argument3); + Argument4 = (UINTN)AllocateCopyPool (Arguments[2], (CHAR8 *)Arguments[3]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } } - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - AllowSupervisorAccessToUserMemory (); - if ((CHAR16 *)UserRsp->Arguments[4] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + if ((CHAR16 *)Arguments[4] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + 2 * (CoreRbp->Argument2 + 1) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + 2 * (Arguments[2] + 1) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument5 = (UINTN)AllocatePool (2 * (CoreRbp->Argument2 + 1)); + Argument5 = (UINTN)AllocatePool (2 * (Arguments[2] + 1)); if ((VOID *)Argument5 == NULL) { if ((VOID *)Argument4 != NULL) { FreePool ((VOID *)Argument4); } + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } } - ForbidSupervisorAccessToUserMemory (); Unicode->FatToStr ( Unicode, - CoreRbp->Argument2, + Arguments[2], (CHAR8 *)Argument4, (CHAR16 *)Argument5 ); @@ -1383,12 +1454,13 @@ CallBootService ( if ((VOID *)Argument5 != NULL) { AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, 2 * (CoreRbp->Argument2 + 1)); + CopyMem ((VOID *)Arguments[4], (VOID *)Argument5, 2 * (Arguments[2] + 1)); ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument5); } + FreePool (Arguments); return EFI_SUCCESS; case SysCallUnicodeStrToFat: @@ -1398,52 +1470,52 @@ CallBootService ( // Argument 3: UINTN FatSize // Argument 4: CHAR8 *Fat // - Unicode = FindInterface (FALSE, (VOID *)CoreRbp->Argument1); + Arguments = CopyUserArguments (4, UserArguments); + + Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { + FreePool (Arguments); return EFI_NOT_FOUND; } - if ((CHAR16 *)CoreRbp->Argument2 != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)CoreRbp->Argument2, &Attributes); + if ((CHAR16 *)Arguments[2] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); AllowSupervisorAccessToUserMemory (); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(CoreRbp->Argument2 + StrSize ((CHAR16 *)CoreRbp->Argument2) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + StrSize ((CHAR16 *)Arguments[2]) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)CoreRbp->Argument2), (CHAR16 *)CoreRbp->Argument2); + Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } } - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserRsp + 6 * sizeof (UINTN) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - - AllowSupervisorAccessToUserMemory (); - if ((CHAR8 *)UserRsp->Arguments[4] != NULL) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)UserRsp->Arguments[4], &Attributes); + if ((CHAR8 *)Arguments[4] != NULL) { + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UserRsp->Arguments[4] + CoreRbp->Argument3 - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + Arguments[3] - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument5 = (UINTN)AllocatePool (CoreRbp->Argument3); + Argument5 = (UINTN)AllocatePool (Arguments[3]); if ((VOID *)Argument5 == NULL) { if ((VOID *)Argument4 != NULL) { FreePool ((VOID *)Argument4); } + FreePool (Arguments); return EFI_OUT_OF_RESOURCES; } } - ForbidSupervisorAccessToUserMemory (); Status = (EFI_STATUS)Unicode->StrToFat ( Unicode, (CHAR16 *)Argument4, - CoreRbp->Argument3, + Arguments[3], (CHAR8 *)Argument5 ); @@ -1453,12 +1525,13 @@ CallBootService ( if ((VOID *)Argument5 != NULL) { AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)UserRsp->Arguments[4], (VOID *)Argument5, CoreRbp->Argument3); + CopyMem ((VOID *)Arguments[4], (VOID *)Argument5, Arguments[3]); ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument5); } + FreePool (Arguments); return Status; default: diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index 0421d4a07f..bf70807f32 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -132,18 +132,10 @@ ASM_PFX(CoreBootServices): mov gs, ax ; Prepare CallBootService arguments. - call ASM_PFX(AllowSupervisorAccessToUserMemory) - mov eax, [edx + 4 * 4] ; User Argument 3 - push eax - mov eax, [edx + 3 * 4] ; User Argument 2 - push eax - mov eax, [edx + 2 * 4] ; User Argument 1 - push eax - call ASM_PFX(ForbidSupervisorAccessToUserMemory) mov ebp, esp + add edx, 4 ; User Arguments[] push edx - push ebp - push ecx + push ecx ; Type sti call ASM_PFX(CallBootService) @@ -157,8 +149,8 @@ ASM_PFX(CoreBootServices): pop eax - ; Step over User Arguments [1..3] and CallBootService input. - add esp, 4*6 + ; Step over CallBootService input. + add esp, 4*2 ; Prepare SYSEXIT arguments. pop edx ; User return address. diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 2f98fbd223..b3888c37c5 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -23,9 +23,9 @@ SECTION .text global ASM_PFX(AllowSupervisorAccessToUserMemory) ASM_PFX(AllowSupervisorAccessToUserMemory): pushfq - pop r10 - or r10, 0x40000 ; Set AC (bit 18) - push r10 + pop rax + or rax, 0x40000 ; Set AC (bit 18) + push rax popfq ret @@ -39,9 +39,9 @@ ASM_PFX(AllowSupervisorAccessToUserMemory): global ASM_PFX(ForbidSupervisorAccessToUserMemory) ASM_PFX(ForbidSupervisorAccessToUserMemory): pushfq - pop r10 - and r10, ~0x40000 ; Clear AC (bit 18) - push r10 + pop rax + and rax, ~0x40000 ; Clear AC (bit 18) + push rax popfq ret @@ -147,18 +147,21 @@ ASM_PFX(CoreBootServices): push rcx ; Save User RFLAGS for SYSRET. push r11 - ; Save User Arguments [1..3]. - push r9 - push r8 - push rdx + ; Save User Arguments [1..3] on User stack. + call ASM_PFX(AllowSupervisorAccessToUserMemory) + mov rax, [rsp + 8*3] + mov [rax + 8*2], rdx + mov [rax + 8*3], r8 + mov [rax + 8*4], r9 + call ASM_PFX(ForbidSupervisorAccessToUserMemory) mov rbp, rsp ; Reserve space on stack for 4 CallBootService arguments (NOOPT prerequisite). sub rsp, 8*4 ; Prepare CallBootService arguments. - mov rcx, r10 - mov rdx, rbp - mov r8, [rbp + 8*6] + mov rcx, r10 ; Type + mov rdx, [rbp + 8*3] + add rdx, 8 ; User Arguments[] sti call ASM_PFX(CallBootService) @@ -169,8 +172,8 @@ ASM_PFX(CoreBootServices): pop rax - ; Step over Arguments [1..3] and NOOPT buffer. - add rsp, 8*7 + ; Step over NOOPT buffer. + add rsp, 8*4 ; Prepare SYSRET arguments. pop r11 From 7f695f6f10cf63a8230be0be8f464cba6add4a7c Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 14 Jan 2025 12:02:38 +0300 Subject: [PATCH 310/341] SysCall: Refactored out mRing3CallStackTop and mCoreSysCallStackTop. --- MdeModulePkg/Core/Dxe/DxeMain.h | 4 ++- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 2 +- .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 27 ++++++++++++------- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 2 +- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 27 ++++++++++++------- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 11 ++++---- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 27 +++++++++---------- .../Dxe/SysCall/X64/CoreBootServices.nasm | 20 +++++++------- 8 files changed, 67 insertions(+), 53 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 571fa96dcc..2bb3569545 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2739,7 +2739,9 @@ EFI_STATUS EFIAPI CallBootService ( IN UINT8 Type, - IN UINTN *UserArguments + IN UINTN *UserArguments, + IN UINTN UserStackTop, + IN UINTN SysCallStackTop ); VOID diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 45264f3197..f0bf051cde 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -92,7 +92,7 @@ ASM_FUNC(ArmCallRing3) // Disable interrupts. msr daifset, #0xf isb - // Save Core SP and switch to CoreSysCall Stack. + // Save Core SP and switch to SysCallStackTop. mov x6, sp str x6, [x4] mov sp, x3 diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index c7076578b3..0802050fe2 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -13,17 +13,17 @@ #include "DxeMain.h" STATIC UINTN mCoreSp; +STATIC UINTN mUserStackTop; +STATIC UINTN mSysCallStackTop; UINTN gUserPageTable; -UINTN mRing3CallStackTop; -UINTN mCoreSysCallStackTop; EFI_STATUS EFIAPI ArmCallRing3 ( IN RING3_CALL_DATA *Data, - IN UINTN StackPointer, + IN UINTN UserStackTop, IN VOID *EntryPoint, - IN UINTN SysCallStack, + IN UINTN SysCallStackTop, IN VOID *CoreStack, IN UINTN UserPageTable ); @@ -74,7 +74,9 @@ SysCallBootService ( Status = CallBootService ( Type, - (UINTN *)((UINTN)Physical + sizeof (UINTN)) + (UINTN *)((UINTN)Physical + sizeof (UINTN)), + mUserStackTop, + mSysCallStackTop ); CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); @@ -173,8 +175,15 @@ CallRing3 ( IN UINTN SysCallStackTop ) { - mRing3CallStackTop = UserStackTop; - mCoreSysCallStackTop = SysCallStackTop; - - return ArmCallRing3 (Data, UserStackTop, gRing3EntryPoint, SysCallStackTop, &mCoreSp, gUserPageTable); + mUserStackTop = UserStackTop; + mSysCallStackTop = SysCallStackTop; + + return ArmCallRing3 ( + Data, + UserStackTop, + gRing3EntryPoint, + SysCallStackTop, + &mCoreSp, + gUserPageTable + ); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 03b326f20d..1a324bb0c5 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -94,7 +94,7 @@ ASM_FUNC(ArmCallRing3) // Set SPSR M[3:0] bits to User mode. and R4, R4, #0xFFFFFFF0 - // Save Core SP and switch to CoreSysCall Stack. + // Save Core SP and switch to SysCallStackTop. mov R5, SP str R5, [R6] mov SP, R3 diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index ec368ed17e..ee3675f6cc 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -12,17 +12,17 @@ #include "DxeMain.h" STATIC UINTN mCoreSp; +STATIC UINTN mUserStackTop; +STATIC UINTN mSysCallStackTop; UINTN gUserPageTable; -UINTN mRing3CallStackTop; -UINTN mCoreSysCallStackTop; EFI_STATUS EFIAPI ArmCallRing3 ( IN RING3_CALL_DATA *Data, - IN UINTN StackPointer, + IN UINTN UserStackTop, IN VOID *EntryPoint, - IN UINTN SysCallStack, + IN UINTN SysCallStackTop, IN VOID *CoreStack, IN UINTN UserPageTable ); @@ -80,7 +80,9 @@ SysCallBootService ( Status = CallBootService ( Type, - (UINTN *)((UINTN)Physical + sizeof (UINTN)) + (UINTN *)((UINTN)Physical + sizeof (UINTN)), + mUserStackTop, + mSysCallStackTop ); // // TODO: Fix memory leak for ReturnToCore(). @@ -168,8 +170,15 @@ CallRing3 ( IN UINTN SysCallStackTop ) { - mRing3CallStackTop = UserStackTop; - mCoreSysCallStackTop = SysCallStackTop; - - return ArmCallRing3 (Data, UserStackTop, gRing3EntryPoint, SysCallStackTop, &mCoreSp, gUserPageTable); + mUserStackTop = UserStackTop; + mSysCallStackTop = SysCallStackTop; + + return ArmCallRing3 ( + Data, + UserStackTop, + gRing3EntryPoint, + SysCallStackTop, + &mCoreSp, + gUserPageTable + ); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index bcad4bc769..c0a84d94b1 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -8,9 +8,6 @@ #include "DxeMain.h" #include "SupportedProtocols.h" -extern UINTN mRing3CallStackTop; -extern UINTN mCoreSysCallStackTop; - LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead); typedef struct { @@ -311,7 +308,9 @@ EFI_STATUS EFIAPI CallBootService ( IN UINT8 Type, - IN UINTN *UserArguments + IN UINTN *UserArguments, + IN UINTN UserStackTop, + IN UINTN SysCallStackTop ) { EFI_STATUS Status; @@ -504,8 +503,8 @@ CallBootService ( UserDriver->CoreWrapper = CoreArgList[Index + 1]; UserDriver->UserSpaceDriver = UserArgList[Index + 1]; UserDriver->UserPageTable = gUserPageTable; - UserDriver->SysCallStackTop = mCoreSysCallStackTop; - UserDriver->UserStackTop = mRing3CallStackTop; + UserDriver->UserStackTop = UserStackTop; + UserDriver->SysCallStackTop = SysCallStackTop; InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link); diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index bf70807f32..3f79aa05e1 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -133,6 +133,8 @@ ASM_PFX(CoreBootServices): ; Prepare CallBootService arguments. mov ebp, esp + push dword [ASM_PFX(SysCallStackTop)] + push dword [ASM_PFX(UserStackTop)] add edx, 4 ; User Arguments[] push edx push ecx ; Type @@ -150,7 +152,7 @@ ASM_PFX(CoreBootServices): pop eax ; Step over CallBootService input. - add esp, 4*2 + mov esp, ebp ; Prepare SYSEXIT arguments. pop edx ; User return address. @@ -169,7 +171,7 @@ ASM_PFX(CoreBootServices): ; IN UINTN SysCallStackTop ; ); ; -; (On User Stack) Data +; (On User Stack) Data, UserStackTop, SysCallStackTop ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): @@ -183,23 +185,20 @@ ASM_PFX(CallRing3): ; Save Core Stack pointer. mov [ASM_PFX(CoreEsp)], esp - mov ebx, [esp + 4 * 6] ; UserStackTop - mov [ASM_PFX(mRing3CallStackTop)], ebx - mov ebx, [esp + 4 * 7] ; SysCallStackTop - mov [ASM_PFX(mCoreSysCallStackTop)], ebx + mov ebx, [esp + 4 * 6] + mov [ASM_PFX(UserStackTop)], ebx + mov ebx, [esp + 4 * 7] + mov [ASM_PFX(SysCallStackTop)], ebx mov edx, 0 mov eax, ebx mov ecx, MSR_IA32_SYSENTER_ESP wrmsr - push dword [ASM_PFX(gRing3EntryPoint)] - push dword [ASM_PFX(mRing3CallStackTop)] - SetRing3DataSegmentSelectors ; Prepare SYSEXIT arguments. - pop ecx - pop edx + mov ecx, [ASM_PFX(UserStackTop)] + mov edx, [ASM_PFX(gRing3EntryPoint)] mov eax, [esp + 4 * 5] ; Data ; Switch to User Stack. @@ -251,10 +250,8 @@ ALIGN 4096 ASM_PFX(CoreEsp): resd 1 -global ASM_PFX(mRing3CallStackTop) -ASM_PFX(mRing3CallStackTop): +ASM_PFX(UserStackTop): resd 1 -global ASM_PFX(mCoreSysCallStackTop) -ASM_PFX(mCoreSysCallStackTop): +ASM_PFX(SysCallStackTop): resd 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index b3888c37c5..72b20f7289 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -138,7 +138,7 @@ ASM_PFX(CoreBootServices): mov gs, ax ; Save User Stack pointers and switch to Core SysCall Stack. - mov rax, [ASM_PFX(mCoreSysCallStackTop)] + mov rax, [ASM_PFX(SysCallStackTop)] sub rax, 8 mov [rax], rsp mov rsp, rax @@ -162,6 +162,8 @@ ASM_PFX(CoreBootServices): mov rcx, r10 ; Type mov rdx, [rbp + 8*3] add rdx, 8 ; User Arguments[] + mov r8, [ASM_PFX(UserStackTop)] + mov r9, [ASM_PFX(SysCallStackTop)] sti call ASM_PFX(CallBootService) @@ -221,20 +223,18 @@ ASM_PFX(CallRing3): mov [ASM_PFX(CoreRsp)], rsp ; Save input Arguments. - mov [ASM_PFX(mRing3CallStackTop)], rdx - mov [ASM_PFX(mCoreSysCallStackTop)], r8 - mov r8, [ASM_PFX(mRing3CallStackTop)] - mov r9, [ASM_PFX(gRing3EntryPoint)] + mov [ASM_PFX(UserStackTop)], rdx + mov [ASM_PFX(SysCallStackTop)], r8 mov r10, rcx SetRing3DataSegmentSelectors ; Prepare SYSRET arguments. mov rdx, r10 - mov rcx, r9 + mov rcx, [ASM_PFX(gRing3EntryPoint)] ; Switch to User Stack. - mov rsp, r8 + mov rsp, [ASM_PFX(UserStackTop)] mov rbp, rsp mov r8, [ASM_PFX(gUserPageTable)] @@ -284,10 +284,8 @@ ALIGN 4096 ASM_PFX(CoreRsp): resq 1 -global ASM_PFX(mRing3CallStackTop) -ASM_PFX(mRing3CallStackTop): +ASM_PFX(UserStackTop): resq 1 -global ASM_PFX(mCoreSysCallStackTop) -ASM_PFX(mCoreSysCallStackTop): +ASM_PFX(SysCallStackTop): resq 1 From 3fd50950b349016022b2b17695a3ced604dcc916 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 16 Jan 2025 15:43:34 +0300 Subject: [PATCH 311/341] Ring3: Refactored out CoreRsp and UserStackTop. --- MdeModulePkg/Core/Dxe/DxeMain.h | 22 ++-- MdeModulePkg/Core/Dxe/Image/Image.c | 13 +- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 14 ++- .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 32 +---- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 16 +-- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 32 +---- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 55 ++++++--- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 30 ++--- .../Core/Dxe/SysCall/Initialization.c | 2 +- .../Core/Dxe/SysCall/SupportedProtocols.c | 111 ++++++++---------- .../Core/Dxe/SysCall/SupportedProtocols.h | 11 -- .../Dxe/SysCall/X64/CoreBootServices.nasm | 30 +++-- 12 files changed, 174 insertions(+), 194 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 2bb3569545..234ee381c5 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -235,6 +235,16 @@ typedef struct { UINTN UserStackTop; } LOADED_IMAGE_PRIVATE_DATA; +typedef struct { + VOID *CoreWrapper; + VOID *UserSpaceDriver; + UINTN UserPageTable; + UINTN UserStackTop; + UINTN SysCallStackTop; + UINTN ReturnSP; + LIST_ENTRY Link; +} USER_SPACE_DRIVER; + #define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \ CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE) @@ -279,6 +289,7 @@ extern VOID *gRing3Interfaces; extern VOID *gRing3EntryPoint; extern UINTN gUserPageTable; extern UINTN gCorePageTable; +extern LIST_ENTRY gUserSpaceDriversHead; // // Service Initialization Functions @@ -2739,9 +2750,7 @@ EFI_STATUS EFIAPI CallBootService ( IN UINT8 Type, - IN UINTN *UserArguments, - IN UINTN UserStackTop, - IN UINTN SysCallStackTop + IN UINTN *UserArguments ); VOID @@ -2759,10 +2768,9 @@ ForbidSupervisorAccessToUserMemory ( EFI_STATUS EFIAPI GoToRing3 ( - IN UINT8 Number, - IN VOID *EntryPoint, - IN UINTN UserStackTop, - IN UINTN SysCallStackTop, + IN UINT8 Number, + IN VOID *EntryPoint, + IN USER_SPACE_DRIVER *UserDriver, ... ); diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 9b85b0633a..19c168e9c4 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1642,6 +1642,7 @@ CoreStartImage ( UINTN SetJumpFlag; EFI_HANDLE Handle; UINT64 Attributes; + USER_SPACE_DRIVER *UserDriver; Handle = ImageHandle; @@ -1743,11 +1744,19 @@ CoreStartImage ( gUserPageTable = Image->UserPageTable; + UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); + UserDriver->CoreWrapper = NULL; + UserDriver->UserSpaceDriver = (VOID *)Image->EntryPoint; + UserDriver->UserPageTable = Image->UserPageTable; + UserDriver->UserStackTop = Image->UserStackTop; + UserDriver->SysCallStackTop = Image->SysCallStackTop; + + InsertTailList (&gUserSpaceDriversHead, &UserDriver->Link); + Image->Status = GoToRing3 ( 2, (VOID *)Image->EntryPoint, - Image->UserStackTop, - Image->SysCallStackTop, + UserDriver, ImageHandle, gRing3Data ); diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index f0bf051cde..41b31b1b28 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------ // -// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. // SPDX-License-Identifier: BSD-3-Clause // //------------------------------------------------------------------------------ @@ -62,14 +62,15 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) // CallRing3 ( // IN RING3_CALL_DATA *Data, // IN UINTN UserStackTop, -// IN UINTN SysCallStackTop +// IN UINTN SysCallStackTop, +// IN UINTN *ReturnSP // ); // // (x0) Data // (x1) UserStackTop // (x2) gRing3EntryPoint // (x3) SysCallStackTop -// (x4) &CoreSp +// (x4) ReturnSP // (x5) gUserPageTable //------------------------------------------------------------------------------ ASM_FUNC(ArmCallRing3) @@ -121,13 +122,14 @@ ASM_FUNC_ALIGN(SysCallEnd, 4096) // VOID // EFIAPI // ReturnToCore ( -// IN EFI_STATUS Status +// IN EFI_STATUS Status, +// IN UINTN ReturnSP // ); // // (x0) Status -// (x1) mCoreSp +// (x1) ReturnSP //------------------------------------------------------------------------------ -ASM_FUNC(ArmReturnToCore) +ASM_FUNC(ReturnToCore) // Switch to Core Stack. mov sp, x1 // Restore registers and Stack. diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index 0802050fe2..8bf1b91529 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -1,6 +1,6 @@ /** @file - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause **/ @@ -12,8 +12,6 @@ #include "DxeMain.h" -STATIC UINTN mCoreSp; -STATIC UINTN mUserStackTop; STATIC UINTN mSysCallStackTop; UINTN gUserPageTable; @@ -24,26 +22,10 @@ ArmCallRing3 ( IN UINTN UserStackTop, IN VOID *EntryPoint, IN UINTN SysCallStackTop, - IN VOID *CoreStack, + IN UINTN *ReturnSP, IN UINTN UserPageTable ); -VOID -EFIAPI -ArmReturnToCore ( - IN EFI_STATUS Status, - IN UINTN CoreSp - ); - -VOID -EFIAPI -ReturnToCore ( - IN EFI_STATUS Status - ) -{ - ArmReturnToCore (Status, mCoreSp); -} - STATIC EFI_STATUS EFIAPI @@ -74,9 +56,7 @@ SysCallBootService ( Status = CallBootService ( Type, - (UINTN *)((UINTN)Physical + sizeof (UINTN)), - mUserStackTop, - mSysCallStackTop + (UINTN *)((UINTN)Physical + sizeof (UINTN)) ); CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); @@ -172,10 +152,10 @@ EFIAPI CallRing3 ( IN RING3_CALL_DATA *Data, IN UINTN UserStackTop, - IN UINTN SysCallStackTop + IN UINTN SysCallStackTop, + IN UINTN *ReturnSP ) { - mUserStackTop = UserStackTop; mSysCallStackTop = SysCallStackTop; return ArmCallRing3 ( @@ -183,7 +163,7 @@ CallRing3 ( UserStackTop, gRing3EntryPoint, SysCallStackTop, - &mCoreSp, + ReturnSP, gUserPageTable ); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 1a324bb0c5..2beb0b22ad 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -1,6 +1,6 @@ //------------------------------------------------------------------------------ // -// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. // SPDX-License-Identifier: BSD-3-Clause // //------------------------------------------------------------------------------ @@ -58,7 +58,8 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) // CallRing3 ( // IN RING3_CALL_DATA *Data, // IN UINTN UserStackTop, -// IN UINTN SysCallStackTop +// IN UINTN SysCallStackTop, +// IN UINTN *ReturnSP // ); // // (r0) Data @@ -66,12 +67,12 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) // (r2) gRing3EntryPoint // (r3) SysCallStackTop // -// (On Core Stack) &CoreSp, gUserPageTable +// (On Core Stack) ReturnSP, gUserPageTable //------------------------------------------------------------------------------ ASM_FUNC(ArmCallRing3) // Save registers. push {R4-R12, LR} - // R6 is &CoreSp + // R6 is ReturnSP ldr R6, [SP, #0x28] // R7 is gUserPageTable ldr R7, [SP, #0x2C] @@ -118,13 +119,14 @@ ASM_FUNC_ALIGN(SysCallEnd, 4096) // VOID // EFIAPI // ReturnToCore ( -// IN EFI_STATUS Status +// IN EFI_STATUS Status, +// IN UINTN ReturnSP // ); // // (r0) Status -// (r1) mCoreSp +// (r1) ReturnSP //------------------------------------------------------------------------------ -ASM_FUNC(ArmReturnToCore) +ASM_FUNC(ReturnToCore) // Switch to Core Stack. mov SP, R1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index ee3675f6cc..9238c2ea91 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -1,6 +1,6 @@ /** @file - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause **/ @@ -11,8 +11,6 @@ #include "DxeMain.h" -STATIC UINTN mCoreSp; -STATIC UINTN mUserStackTop; STATIC UINTN mSysCallStackTop; UINTN gUserPageTable; @@ -23,26 +21,10 @@ ArmCallRing3 ( IN UINTN UserStackTop, IN VOID *EntryPoint, IN UINTN SysCallStackTop, - IN VOID *CoreStack, + IN UINTN *ReturnSP, IN UINTN UserPageTable ); -VOID -EFIAPI -ArmReturnToCore ( - IN EFI_STATUS Status, - IN UINTN CoreSp - ); - -VOID -EFIAPI -ReturnToCore ( - IN EFI_STATUS Status - ) -{ - ArmReturnToCore (Status, mCoreSp); -} - STATIC EFI_STATUS EFIAPI @@ -80,9 +62,7 @@ SysCallBootService ( Status = CallBootService ( Type, - (UINTN *)((UINTN)Physical + sizeof (UINTN)), - mUserStackTop, - mSysCallStackTop + (UINTN *)((UINTN)Physical + sizeof (UINTN)) ); // // TODO: Fix memory leak for ReturnToCore(). @@ -167,10 +147,10 @@ EFIAPI CallRing3 ( IN RING3_CALL_DATA *Data, IN UINTN UserStackTop, - IN UINTN SysCallStackTop + IN UINTN SysCallStackTop, + IN UINTN *ReturnSP ) { - mUserStackTop = UserStackTop; mSysCallStackTop = SysCallStackTop; return ArmCallRing3 ( @@ -178,7 +158,7 @@ CallRing3 ( UserStackTop, gRing3EntryPoint, SysCallStackTop, - &mCoreSp, + ReturnSP, gUserPageTable ); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index c0a84d94b1..59bef0920e 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -68,7 +68,8 @@ CallInstallMultipleProtocolInterfaces ( VOID EFIAPI ReturnToCore ( - IN EFI_STATUS Status + IN EFI_STATUS Status, + IN UINTN ReturnSP ); VOID @@ -304,13 +305,32 @@ CopyUserArguments ( return Arguments; } +STATIC +USER_SPACE_DRIVER * +EFIAPI +FindUserInfo ( + VOID + ) +{ + LIST_ENTRY *Link; + USER_SPACE_DRIVER *UserDriver; + + for (Link = gUserSpaceDriversHead.ForwardLink; Link != &gUserSpaceDriversHead; Link = Link->ForwardLink) { + UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link); + + if ((UserDriver->UserPageTable == gUserPageTable) && (UserDriver->ReturnSP != 0)) { + return UserDriver; + } + } + + return NULL; +} + EFI_STATUS EFIAPI CallBootService ( IN UINT8 Type, - IN UINTN *UserArguments, - IN UINTN UserStackTop, - IN UINTN SysCallStackTop + IN UINTN *UserArguments ) { EFI_STATUS Status; @@ -329,6 +349,7 @@ CallBootService ( UINT32 PagesNumber; EFI_PHYSICAL_ADDRESS Ring3Pages; USER_SPACE_DRIVER *UserDriver; + USER_SPACE_DRIVER *NewDriver; UINTN *Arguments; EFI_PHYSICAL_ADDRESS PhysAddr; @@ -350,9 +371,11 @@ CallBootService ( switch (Type) { case SysCallReturnToCore: - Arguments = CopyUserArguments (1, UserArguments); + Arguments = CopyUserArguments (1, UserArguments); + UserDriver = FindUserInfo (); + ASSERT (UserDriver != NULL); - ReturnToCore (Arguments[1]); + ReturnToCore (Arguments[1], UserDriver->ReturnSP); break; case SysCallLocateProtocol: // @@ -496,17 +519,21 @@ CallBootService ( ASSERT ((Attributes & EFI_MEMORY_USER) != 0); CoreArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index + 1]); + + UserDriver = FindUserInfo (); + ASSERT (UserDriver != NULL); // // TODO: Check everywhere that Allocated != NULL // - UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); - UserDriver->CoreWrapper = CoreArgList[Index + 1]; - UserDriver->UserSpaceDriver = UserArgList[Index + 1]; - UserDriver->UserPageTable = gUserPageTable; - UserDriver->UserStackTop = UserStackTop; - UserDriver->SysCallStackTop = SysCallStackTop; - - InsertTailList (&mUserSpaceDriversHead, &UserDriver->Link); + NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); + NewDriver->CoreWrapper = CoreArgList[Index + 1]; + NewDriver->UserSpaceDriver = UserArgList[Index + 1]; + NewDriver->UserPageTable = UserDriver->UserPageTable; + NewDriver->UserStackTop = UserDriver->UserStackTop; + NewDriver->SysCallStackTop = UserDriver->SysCallStackTop; + NewDriver->ReturnSP = 0; + + InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] + sizeof (VOID *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index 3f79aa05e1..bac5bc1e21 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -1,6 +1,6 @@ ;------------------------------------------------------------------------------ ; -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. ; SPDX-License-Identifier: BSD-3-Clause ; ;------------------------------------------------------------------------------ @@ -133,8 +133,6 @@ ASM_PFX(CoreBootServices): ; Prepare CallBootService arguments. mov ebp, esp - push dword [ASM_PFX(SysCallStackTop)] - push dword [ASM_PFX(UserStackTop)] add edx, 4 ; User Arguments[] push edx push ecx ; Type @@ -168,10 +166,11 @@ ASM_PFX(CoreBootServices): ; CallRing3 ( ; IN RING3_CALL_DATA *Data, ; IN UINTN UserStackTop, -; IN UINTN SysCallStackTop +; IN UINTN SysCallStackTop, +; IN UINTN *ReturnSP ; ); ; -; (On User Stack) Data, UserStackTop, SysCallStackTop +; (On User Stack) Data, UserStackTop, SysCallStackTop, ReturnSP ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): @@ -183,10 +182,9 @@ ASM_PFX(CallRing3): push esi ; Save Core Stack pointer. - mov [ASM_PFX(CoreEsp)], esp + mov ebx, [esp + 4 * 8] ; ReturnSP + mov [ebx], esp - mov ebx, [esp + 4 * 6] - mov [ASM_PFX(UserStackTop)], ebx mov ebx, [esp + 4 * 7] mov [ASM_PFX(SysCallStackTop)], ebx mov edx, 0 @@ -197,7 +195,7 @@ ASM_PFX(CallRing3): SetRing3DataSegmentSelectors ; Prepare SYSEXIT arguments. - mov ecx, [ASM_PFX(UserStackTop)] + mov ecx, [esp + 4 * 6] ; UserStackTop mov edx, [ASM_PFX(gRing3EntryPoint)] mov eax, [esp + 4 * 5] ; Data @@ -219,14 +217,14 @@ ASM_PFX(SysCallEnd): ; VOID ; EFIAPI ; ReturnToCore ( -; IN EFI_STATUS Status +; IN EFI_STATUS Status, +; IN UINTN ReturnSP ; ); ;------------------------------------------------------------------------------ global ASM_PFX(ReturnToCore) ASM_PFX(ReturnToCore): - mov eax, [esp + 4] - - mov esp, [ASM_PFX(CoreEsp)] + mov eax, [esp + 4] ; Status + mov esp, [esp + 4*2] ; ReturnSP pop esi pop edi pop ebp @@ -247,11 +245,5 @@ ASM_PFX(gUserPageTable): resd 1 ALIGN 4096 -ASM_PFX(CoreEsp): - resd 1 - -ASM_PFX(UserStackTop): - resd 1 - ASM_PFX(SysCallStackTop): resd 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 275647f1d4..410cf40788 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -1,6 +1,6 @@ /** @file - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause **/ diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 89cdd3a70b..39c644fc63 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -8,23 +8,23 @@ #include "DxeMain.h" #include "SupportedProtocols.h" -LIST_ENTRY mUserSpaceDriversHead = INITIALIZE_LIST_HEAD_VARIABLE (mUserSpaceDriversHead); +LIST_ENTRY gUserSpaceDriversHead = INITIALIZE_LIST_HEAD_VARIABLE (gUserSpaceDriversHead); EFI_STATUS EFIAPI CallRing3 ( IN RING3_CALL_DATA *Data, IN UINTN UserStackTop, - IN UINTN SysCallStackTop + IN UINTN SysCallStackTop, + IN UINTN *ReturnSP ); EFI_STATUS EFIAPI GoToRing3 ( - IN UINT8 Number, - IN VOID *EntryPoint, - IN UINTN UserStackTop, - IN UINTN SysCallStackTop, + IN UINT8 Number, + IN VOID *EntryPoint, + IN USER_SPACE_DRIVER *UserDriver, ... ) { @@ -53,16 +53,28 @@ GoToRing3 ( Input->NumberOfArguments = Number; Input->EntryPoint = EntryPoint; - VA_START (Marker, SysCallStackTop); + VA_START (Marker, UserDriver); for (Index = 0; Index < Number; ++Index) { Input->Arguments[Index] = VA_ARG (Marker, UINTN); } VA_END (Marker); ForbidSupervisorAccessToUserMemory (); - - Status = CallRing3 (Input, UserStackTop, SysCallStackTop); + // + // TODO: Get(),Set() for old SysCallStackTop. + // + // + // TODO: Allocate new stacks (only for EFI_FILE_PROTOCOL instances?), + // because UserDriver can be interrupted and interrupt handler may call the same UserDriver again. + // + Status = CallRing3 ( + Input, + UserDriver->UserStackTop, + UserDriver->SysCallStackTop, + &UserDriver->ReturnSP + ); CoreFreePages (Ring3Pages, PagesNumber); + UserDriver->ReturnSP = 0; return Status; } @@ -77,7 +89,7 @@ FindUserSpaceDriver ( LIST_ENTRY *Link; USER_SPACE_DRIVER *UserDriver; - for (Link = mUserSpaceDriversHead.ForwardLink; Link != &mUserSpaceDriversHead; Link = Link->ForwardLink) { + for (Link = gUserSpaceDriversHead.ForwardLink; Link != &gUserSpaceDriversHead; Link = Link->ForwardLink) { UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link); if (UserDriver->CoreWrapper == CoreWrapper) { @@ -113,8 +125,7 @@ CoreDriverBindingSupported ( Status = GoToRing3 ( 3, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, ControllerHandle, RemainingDevicePath @@ -147,8 +158,7 @@ CoreDriverBindingStart ( Status = GoToRing3 ( 3, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, ControllerHandle, RemainingDevicePath @@ -182,8 +192,7 @@ CoreDriverBindingStop ( Status = GoToRing3 ( 4, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, ControllerHandle, NumberOfChildren, @@ -216,8 +225,7 @@ CoreFileClose ( Status = GoToRing3 ( 1, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This ); @@ -293,8 +301,7 @@ CoreFileRead ( Status = GoToRing3 ( 3, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, Ring3BufferSize, Ring3Buffer @@ -349,8 +356,7 @@ CoreFileSetPosition ( return GoToRing3 ( 2, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, Position ); @@ -361,8 +367,7 @@ CoreFileSetPosition ( return GoToRing3 ( 3, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, Position ); @@ -374,10 +379,11 @@ CoreFileSetPosition ( return GoToRing3 ( 4, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, - Position + NULL, + (UINT32)Position, + (UINT32)(Position >> 32) ); #endif @@ -423,8 +429,7 @@ CoreFileGetPosition ( Status = GoToRing3 ( 2, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, Ring3Position ); @@ -504,8 +509,7 @@ CoreFileGetInfo ( Status = GoToRing3 ( 4, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, Ring3InformationType, Ring3BufferSize, @@ -660,8 +664,7 @@ CoreFileOpen ( Status = GoToRing3 ( 5, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, Ring3NewHandle, Ring3FileName, @@ -675,8 +678,7 @@ CoreFileOpen ( Status = GoToRing3 ( 7, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, Ring3NewHandle, Ring3FileName, @@ -693,13 +695,15 @@ CoreFileOpen ( Status = GoToRing3 ( 8, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, Ring3NewHandle, Ring3FileName, - OpenMode, - Attributes + NULL, + (UINT32)OpenMode, + (UINT32)(OpenMode >> 32), + (UINT32)Attributes, + (UINT32)(Attributes >> 32) ); #endif if (EFI_ERROR (Status)) { @@ -718,10 +722,6 @@ CoreFileOpen ( NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); NewDriver->CoreWrapper = NewFile; NewDriver->UserPageTable = UserDriver->UserPageTable; - // - // TODO: Allocate new stacks, because UserDriver can be interrupted - // and interrupt handler may call the same UserDriver again. - // NewDriver->UserStackTop = UserDriver->UserStackTop; NewDriver->SysCallStackTop = UserDriver->SysCallStackTop; @@ -730,7 +730,7 @@ CoreFileOpen ( NewFile->Revision = (*Ring3NewHandle)->Revision; ForbidSupervisorAccessToUserMemory (); - InsertTailList (&mUserSpaceDriversHead, &NewDriver->Link); + InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); NewFile->Open = CoreFileOpen; NewFile->Close = CoreFileClose; @@ -798,8 +798,7 @@ CoreOpenVolume ( Status = GoToRing3 ( 2, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, Ring3Root ); @@ -827,7 +826,7 @@ CoreOpenVolume ( File->Revision = (*Ring3Root)->Revision; ForbidSupervisorAccessToUserMemory (); - InsertTailList (&mUserSpaceDriversHead, &NewDriver->Link); + InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); File->Open = CoreFileOpen; File->Close = CoreFileClose; @@ -893,8 +892,7 @@ CoreUnicodeCollationStriColl ( Status = GoToRing3 ( 3, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, (UINTN)UserMem, (UINTN)UserMem + Size1 @@ -947,8 +945,7 @@ CoreUnicodeCollationMetaiMatch ( Status = GoToRing3 ( 3, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, (UINTN)UserMem, (UINTN)UserMem + Size1 @@ -997,8 +994,7 @@ CoreUnicodeCollationStrLwr ( Status = GoToRing3 ( 2, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, (UINTN)UserMem ); @@ -1048,8 +1044,7 @@ CoreUnicodeCollationStrUpr ( Status = GoToRing3 ( 2, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, (UINTN)UserMem ); @@ -1098,8 +1093,7 @@ CoreUnicodeCollationFatToStr ( Status = GoToRing3 ( 4, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, FatSize, (UINTN)UserMem, @@ -1153,8 +1147,7 @@ CoreUnicodeCollationStrToFat ( Status = GoToRing3 ( 4, EntryPoint, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop, + UserDriver, This, (UINTN)UserMem, FatSize, diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h index b3f8ba397f..a6195035f2 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -11,17 +11,6 @@ #include #include -typedef struct { - VOID *CoreWrapper; - VOID *UserSpaceDriver; - UINTN UserPageTable; - UINTN UserStackTop; - UINTN SysCallStackTop; - LIST_ENTRY Link; -} USER_SPACE_DRIVER; - -extern LIST_ENTRY mUserSpaceDriversHead; - EFI_STATUS EFIAPI CoreDriverBindingSupported ( diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 72b20f7289..fd294cb7ae 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -1,6 +1,6 @@ ;------------------------------------------------------------------------------ ; -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. ; SPDX-License-Identifier: BSD-3-Clause ; ;------------------------------------------------------------------------------ @@ -162,8 +162,6 @@ ASM_PFX(CoreBootServices): mov rcx, r10 ; Type mov rdx, [rbp + 8*3] add rdx, 8 ; User Arguments[] - mov r8, [ASM_PFX(UserStackTop)] - mov r9, [ASM_PFX(SysCallStackTop)] sti call ASM_PFX(CallBootService) @@ -175,7 +173,7 @@ ASM_PFX(CoreBootServices): pop rax ; Step over NOOPT buffer. - add rsp, 8*4 + mov rsp, rbp ; Prepare SYSRET arguments. pop r11 @@ -197,12 +195,14 @@ o64 sysret ; CallRing3 ( ; IN RING3_CALL_DATA *Data, ; IN UINTN UserStackTop, -; IN UINTN SysCallStackTop +; IN UINTN SysCallStackTop, +; IN UINTN *ReturnSP ; ); ; ; (rcx) Data ; (rdx) UserStackTop ; (r8) SysCallStackTop +; (r9) ReturnSP ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): @@ -220,10 +220,10 @@ ASM_PFX(CallRing3): push r15 ; Save Core Stack pointer. - mov [ASM_PFX(CoreRsp)], rsp + mov [r9], rsp ; Save input Arguments. - mov [ASM_PFX(UserStackTop)], rdx + mov rbx, rdx mov [ASM_PFX(SysCallStackTop)], r8 mov r10, rcx @@ -234,7 +234,7 @@ ASM_PFX(CallRing3): mov rcx, [ASM_PFX(gRing3EntryPoint)] ; Switch to User Stack. - mov rsp, [ASM_PFX(UserStackTop)] + mov rsp, rbx mov rbp, rsp mov r8, [ASM_PFX(gUserPageTable)] @@ -250,12 +250,16 @@ ASM_PFX(SysCallEnd): ; VOID ; EFIAPI ; ReturnToCore ( -; IN EFI_STATUS Status +; IN EFI_STATUS Status, +; IN UINTN ReturnSP ; ); +; +; (rcx) Status +; (rdx) ReturnSP ;------------------------------------------------------------------------------ global ASM_PFX(ReturnToCore) ASM_PFX(ReturnToCore): - mov rsp, [ASM_PFX(CoreRsp)] + mov rsp, rdx pop r15 pop r14 pop r13 @@ -281,11 +285,5 @@ ASM_PFX(gUserPageTable): resq 1 ALIGN 4096 -ASM_PFX(CoreRsp): - resq 1 - -ASM_PFX(UserStackTop): - resq 1 - ASM_PFX(SysCallStackTop): resq 1 From 693d3f7cb48368501e053edd8a213335318cadd3 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 20 Jan 2025 12:57:14 +0300 Subject: [PATCH 312/341] Ring3: Placed UnicodeCollation driver into User space. --- .../AArch64/ExceptionSupport.S | 31 ++-- .../ArmExceptionLib/Arm/ExceptionSupport.S | 51 +++--- ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 2 +- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 6 +- .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 5 +- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 7 + .../Core/Dxe/SysCall/ARM/InitializeARM.c | 5 +- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 26 ++- .../Core/Dxe/SysCall/SupportedProtocols.c | 153 +++++++++++++----- .../Dxe/SysCall/X64/CoreBootServices.nasm | 2 + OvmfPkg/OvmfPkgIa32.fdf | 2 +- OvmfPkg/OvmfPkgIa32X64.fdf | 2 +- OvmfPkg/OvmfPkgX64.fdf | 2 +- 13 files changed, 190 insertions(+), 104 deletions(-) diff --git a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S index 8e6512cee1..e914ee0a48 100644 --- a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S @@ -90,6 +90,8 @@ UINT64 ESR; 0x318 // Exception syndrome register UINT64 FAR; 0x320 // Fault Address Register UINT64 Type; 0x328 // Exception Type + UINT64 TTBR0; 0x330 // User Page Table + UINT64 Padding;0x338 // Alignment requirement */ GCC_ASM_EXPORT(ExceptionHandlersEnd) @@ -99,7 +101,7 @@ GCC_ASM_EXPORT(CommonCExceptionHandler) #define GP_CONTEXT_SIZE (32 * 8) #define FP_CONTEXT_SIZE (32 * 16) -#define SYS_CONTEXT_SIZE ( 6 * 8) // 5 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10) +#define SYS_CONTEXT_SIZE ( 8 * 8) // 7 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10) ASM_FUNC_ALIGN(ExceptionHandlerBase, 4096) @@ -247,6 +249,11 @@ ASM_PFX(CommonExceptionEntry): stp x2, x3, [x28, #-SYS_CONTEXT_SIZE]! stp x4, x5, [x28, #0x10] stp x6, x0, [x28, #0x20] + EL1_OR_EL2(x1) +1:mrs x2, ttbr0_el1 + b 3f +2:mrs x2, ttbr0_el2 +3:stp x2, xzr, [x28, #0x30] // Push FP regs to Stack. stp q0, q1, [x28, #-FP_CONTEXT_SIZE]! @@ -271,17 +278,12 @@ ASM_PFX(CommonExceptionEntry): cmp x2, 0 // Check whether EL0 process was interrupted b.ne NoTTBR0Switch adrp x1, ASM_PFX(CorePageTable) + ldr x4, [x1] EL1_OR_EL2(x3) -1:mrs x4, ttbr0_el1 - str x4, [x1, #0x8] // UserPageTable - ldr x4, [x1] // CorePageTable - msr ttbr0_el1, x4 +1:msr ttbr0_el1, x4 tlbi vmalle1 b 3f -2:mrs x4, ttbr0_el2 - str x4, [x1, #0x8] // UserPageTable - ldr x4, [x1] // CorePageTable - msr ttbr0_el2, x4 +2:msr ttbr0_el2, x4 tlbi alle2 3:dsb sy isb @@ -307,14 +309,12 @@ NoTTBR0Switch: and x2, x2, #0xF cmp x2, 0 // Check whether EL0 process was interrupted b.ne NoTTBR0Switch2 - adrp x1, ASM_PFX(CorePageTable) + ldr x4, [x28, #(FP_CONTEXT_SIZE + 0x30)] // UserPageTable EL1_OR_EL2(x3) -1:ldr x4, [x1, #0x8] // UserPageTable - msr ttbr0_el1, x4 +1:msr ttbr0_el1, x4 tlbi vmalle1 b 3f -2:ldr x4, [x1, #0x8] // UserPageTable - msr ttbr0_el2, x4 +2:msr ttbr0_el2, x4 tlbi alle2 3:dsb sy isb @@ -408,9 +408,6 @@ ASM_FUNC(RegisterEl0Stack) ASM_PFX(CorePageTable): .ds.d 1 -UserPageTable: -.ds.d 1 - .balign 4096 Padding: .ds.b 1 diff --git a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S index c36679308a..9c5c6398c1 100644 --- a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S @@ -43,8 +43,11 @@ This is the stack constructed by the exception handler (low address to high addr LR 0x54 # SVC Link register (we need to restore it) - LR 0x58 # pushed by srsfd - CPSR 0x5c + TTBR0 0x58 +Padding 0x5c + + LR 0x60 # pushed by srsfd + CPSR 0x64 */ @@ -98,7 +101,7 @@ ASM_PFX(Fiq): ASM_PFX(ResetEntry): srsdb #0x13! @ Store return state on SVC stack @ We are already in SVC mode - + sub SP, SP, #0x8 @ Save space for TTBR0 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -111,6 +114,7 @@ ASM_PFX(UndefinedInstructionEntry): sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry srsdb #0x13! @ Store return state on SVC stack cps #0x13 @ Switch to SVC for common stack + sub SP, SP, #0x8 @ Save space for TTBR0 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -124,6 +128,7 @@ ASM_PFX(SoftwareInterruptEntry): isb srsdb #0x13! @ Store return state on SVC stack @ We are already in SVC mode + sub SP, SP, #0x8 @ Save space for TTBR0 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -136,6 +141,7 @@ ASM_PFX(PrefetchAbortEntry): sub LR,LR,#4 srsdb #0x13! @ Store return state on SVC stack cps #0x13 @ Switch to SVC for common stack + sub SP, SP, #0x8 @ Save space for TTBR0 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -148,6 +154,7 @@ ASM_PFX(DataAbortEntry): sub LR,LR,#8 srsdb #0x13! @ Store return state on SVC stack cps #0x13 @ Switch to SVC for common stack + sub SP, SP, #0x8 @ Save space for TTBR0 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -159,6 +166,7 @@ ASM_PFX(DataAbortEntry): ASM_PFX(ReservedExceptionEntry): srsdb #0x13! @ Store return state on SVC stack cps #0x13 @ Switch to SVC for common stack + sub SP, SP, #0x8 @ Save space for TTBR0 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -171,6 +179,7 @@ ASM_PFX(IrqEntry): sub LR,LR,#4 srsdb #0x13! @ Store return state on SVC stack cps #0x13 @ Switch to SVC for common stack + sub SP, SP, #0x8 @ Save space for TTBR0 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -183,6 +192,7 @@ ASM_PFX(FiqEntry): sub LR,LR,#4 srsdb #0x13! @ Store return state on SVC stack cps #0x13 @ Switch to SVC for common stack + sub SP, SP, #0x8 @ Save space for TTBR0 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -217,7 +227,7 @@ ASM_PFX(AsmCommonExceptionEntry): mrc p15, 0, R1, c5, c0, 0 @ Read DFSR str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR - ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack + ldr R1, [SP, #0x64] @ srsdb saved pre-exception CPSR on the stack str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR @@ -229,20 +239,20 @@ ASM_PFX(AsmCommonExceptionEntry): stmdaeq R2, {sp}^ @ save unbanked sp @ else stmdane R2, {lr} @ save SVC lr - addne R1, SP, #0x60 @ We pushed 0x60 bytes on the stack + addne R1, SP, #0x68 @ We pushed 0x68 bytes on the stack strne R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP - ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd + ldr R5, [SP, #0x60] @ PC is the LR pushed by srsfd @ Check to see if we have to adjust for Thumb entry sub r4, r0, #1 @ if (ExceptionType == 1 || ExceptionType == 2)) { cmp r4, #1 @ // UND & SVC have different LR adjust for Thumb bhi NoAdjustNeeded - ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack + ldr R1, [SP, #0x64] @ srsdb saved pre-exception CPSR on the stack tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry addne R5, R5, #2 @ PC += 2; - strne R5,[SP,#0x58] @ Update LR value pushed by srsfd + strne R5,[SP,#0x60] @ Update LR value pushed by srsfd NoAdjustNeeded: @@ -251,17 +261,12 @@ NoAdjustNeeded: @ R0 is ExceptionType mov R1,SP @ R1 is SystemContext -#if (FixedPcdGet32(PcdVFPEnabled)) - vpush {d0-d15} @ save vstm registers in case they are used in optimizations -#endif - ldr R5, [SP, #0x40] @ Saved Processor Status Register and R5, R5, #0xF cmp R5, 0 @ Check whether EL0 process was interrupted bne NoTTBR0Switch mrc p15,0,R5,c2,c0,0 @ R5 == TTBR0 - ADRL (R6, UserPageTable) - str R5, [R6] + str R5, [SP, #0x58] and R5, R5, #0x7F @ Preserve TTBR0 attributes LDRL (R6, ASM_PFX(CorePageTable)) orr R6, R6, R5 @ Assign TTBR0 attributes @@ -273,6 +278,10 @@ NoAdjustNeeded: NoTTBR0Switch: +#if (FixedPcdGet32(PcdVFPEnabled)) + vpush {d0-d15} @ save vstm registers in case they are used in optimizations +#endif + mov R4, SP @ Save current SP tst R4, #4 subne SP, SP, #4 @ Adjust SP if not 8-byte aligned @@ -292,11 +301,15 @@ CommonCExceptionHandler ( mov SP, R4 @ Restore SP +#if (FixedPcdGet32(PcdVFPEnabled)) + vpop {d0-d15} +#endif + ldr R4, [SP, #0x40] @ Saved Processor Status Register and R4, R4, #0xF cmp R4, 0 @ Check whether EL0 process was interrupted bne NoTTBR0Switch2 - LDRL (R4, UserPageTable) + ldr R4, [SP, #0x58] @ User Page Table mcr p15,0,R4,c2,c0,0 @ TTBR0 == R4 mcr p15,0,r0,c8,c7,0 @ TLBIALL, TLB Invalidate All. mcr p15,0,r0,c7,c5,6 @ BPIALL, Branch Predictor Invalidate All. @@ -305,10 +318,6 @@ CommonCExceptionHandler ( NoTTBR0Switch2: -#if (FixedPcdGet32(PcdVFPEnabled)) - vpop {d0-d15} -#endif - ldr R1, [SP, #0x4c] @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR mcr p15, 0, R1, c5, c0, 1 @ Write IFSR @@ -325,6 +334,7 @@ NoTTBR0Switch2: add SP,SP,#0x20 @ Clear out the remaining stack space ldmfd SP!,{LR} @ restore the link register for this context + add SP, SP, #0x8 @ Clear out TTBR0 and Padding rfefd SP! @ return from exception via srsfd stack slot ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096) @@ -336,9 +346,6 @@ ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096) ASM_PFX(CorePageTable): .ds.l 1 -UserPageTable: -.ds.l 1 - .balign 4096 Padding: .ds.b 1 diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc index 270e0b87a1..9579d1532d 100644 --- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc +++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc @@ -90,7 +90,7 @@ APRIORI DXE { INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF USER FatPkg/EnhancedFatDxe/Fat.inf INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf - INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 41b31b1b28..e6161dff8b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -82,7 +82,8 @@ ASM_FUNC(ArmCallRing3) stp q12, q13, [sp, #0xa0] stp q14, q15, [sp, #0x80] - stp xzr, x16, [sp, #0x70] + mrs x6, sp_el0 + stp x6, x16, [sp, #0x70] stp x17, x18, [sp, #0x60] stp x19, x20, [sp, #0x50] stp x21, x22, [sp, #0x40] @@ -138,7 +139,7 @@ ASM_FUNC(ReturnToCore) ldp q12, q13, [sp, #0xa0] ldp q14, q15, [sp, #0x80] - ldr x16, [sp, #0x78] + ldp x6, x16, [sp, #0x70] ldp x17, x18, [sp, #0x60] ldp x19, x20, [sp, #0x50] ldp x21, x22, [sp, #0x40] @@ -147,6 +148,7 @@ ASM_FUNC(ReturnToCore) ldp x27, x28, [sp, #0x10] ldp x29, x30, [sp] add sp, sp, #0x100 + msr sp_el0, x6 // Enable interrupts. msr daifclr, #0xf isb diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index 8bf1b91529..acbe3af845 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -12,8 +12,7 @@ #include "DxeMain.h" -STATIC UINTN mSysCallStackTop; -UINTN gUserPageTable; +UINTN gUserPageTable; EFI_STATUS EFIAPI @@ -156,8 +155,6 @@ CallRing3 ( IN UINTN *ReturnSP ) { - mSysCallStackTop = SysCallStackTop; - return ArmCallRing3 ( Data, UserStackTop, diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 2beb0b22ad..0fa82094ac 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -76,6 +76,9 @@ ASM_FUNC(ArmCallRing3) ldr R6, [SP, #0x28] // R7 is gUserPageTable ldr R7, [SP, #0x2C] + // Save old SP_usr and LR_usr on Core Stack. + sub SP, SP, #0x8 + stmia SP, {SP, LR}^ #if (FixedPcdGet32(PcdVFPEnabled)) // Save vstm registers in case they are used in optimizations. @@ -135,6 +138,10 @@ ASM_FUNC(ReturnToCore) vpop {d0-d15} #endif + // Restore old SP_usr and LR_usr. + ldmia SP, {SP, LR}^ + add SP, SP, #0x8 + pop {R4-R12, LR} // Enable interrupts. diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 9238c2ea91..34d5c43e2c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -11,8 +11,7 @@ #include "DxeMain.h" -STATIC UINTN mSysCallStackTop; -UINTN gUserPageTable; +UINTN gUserPageTable; EFI_STATUS EFIAPI @@ -151,8 +150,6 @@ CallRing3 ( IN UINTN *ReturnSP ) { - mSysCallStackTop = SysCallStackTop; - return ArmCallRing3 ( Data, UserStackTop, diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index bac5bc1e21..72f8e66a22 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -180,24 +180,27 @@ ASM_PFX(CallRing3): push ebp push edi push esi + ; Save old SysCallStackTop. + push dword MSR_IA32_SYSENTER_ESP + call ASM_PFX(AsmReadMsr64) + pop ebx + push eax ; Save Core Stack pointer. - mov ebx, [esp + 4 * 8] ; ReturnSP + mov ebx, [esp + 4 * 9] ; ReturnSP mov [ebx], esp - mov ebx, [esp + 4 * 7] - mov [ASM_PFX(SysCallStackTop)], ebx mov edx, 0 - mov eax, ebx + mov eax, [esp + 4 * 8] ; SysCallStackTop mov ecx, MSR_IA32_SYSENTER_ESP wrmsr SetRing3DataSegmentSelectors ; Prepare SYSEXIT arguments. - mov ecx, [esp + 4 * 6] ; UserStackTop + mov ecx, [esp + 4 * 7] ; UserStackTop mov edx, [ASM_PFX(gRing3EntryPoint)] - mov eax, [esp + 4 * 5] ; Data + mov eax, [esp + 4 * 6] ; Data ; Switch to User Stack. mov ebp, ecx @@ -223,8 +226,15 @@ ASM_PFX(SysCallEnd): ;------------------------------------------------------------------------------ global ASM_PFX(ReturnToCore) ASM_PFX(ReturnToCore): - mov eax, [esp + 4] ; Status + mov ebx, [esp + 4] ; Status mov esp, [esp + 4*2] ; ReturnSP + ; Restore old SysCallStackTop. + mov edx, 0 + pop eax + mov ecx, MSR_IA32_SYSENTER_ESP + wrmsr + + mov eax, ebx pop esi pop edi pop ebp @@ -245,5 +255,5 @@ ASM_PFX(gUserPageTable): resd 1 ALIGN 4096 -ASM_PFX(SysCallStackTop): +Padding: resd 1 diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 39c644fc63..eb4889c4ae 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -60,9 +60,6 @@ GoToRing3 ( VA_END (Marker); ForbidSupervisorAccessToUserMemory (); // - // TODO: Get(),Set() for old SysCallStackTop. - // - // // TODO: Allocate new stacks (only for EFI_FILE_PROTOCOL instances?), // because UserDriver can be interrupted and interrupt handler may call the same UserDriver again. // @@ -83,16 +80,20 @@ STATIC USER_SPACE_DRIVER * EFIAPI FindUserSpaceDriver ( - IN VOID *CoreWrapper + IN VOID *CoreWrapper, + OUT UINTN *OldPageTable ) { LIST_ENTRY *Link; USER_SPACE_DRIVER *UserDriver; + ASSERT (OldPageTable != NULL); + for (Link = gUserSpaceDriversHead.ForwardLink; Link != &gUserSpaceDriversHead; Link = Link->ForwardLink) { UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link); if (UserDriver->CoreWrapper == CoreWrapper) { + *OldPageTable = gUserPageTable; gUserPageTable = UserDriver->UserPageTable; return UserDriver; } @@ -112,8 +113,9 @@ CoreDriverBindingSupported ( EFI_STATUS Status; USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; + UINTN OldPageTable; - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -131,6 +133,8 @@ CoreDriverBindingSupported ( RemainingDevicePath ); + gUserPageTable = OldPageTable; + return Status; } @@ -145,8 +149,9 @@ CoreDriverBindingStart ( EFI_STATUS Status; USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; + UINTN OldPageTable; - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -164,6 +169,8 @@ CoreDriverBindingStart ( RemainingDevicePath ); + gUserPageTable = OldPageTable; + return Status; } @@ -179,8 +186,9 @@ CoreDriverBindingStop ( EFI_STATUS Status; USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; + UINTN OldPageTable; - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -199,6 +207,8 @@ CoreDriverBindingStop ( ChildHandleBuffer ); + gUserPageTable = OldPageTable; + return Status; } @@ -212,8 +222,9 @@ CoreFileClose ( EFI_STATUS Status; USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; + UINTN OldPageTable; - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -232,6 +243,8 @@ CoreFileClose ( FreePool (UserDriver->CoreWrapper); RemoveEntryList (&UserDriver->Link); + gUserPageTable = OldPageTable; + return Status; } @@ -261,6 +274,7 @@ CoreFileRead ( UINT32 PagesNumber; USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; + UINTN OldPageTable; if ((This == NULL) || (BufferSize == NULL)) { return EFI_INVALID_PARAMETER; @@ -268,7 +282,7 @@ CoreFileRead ( // // gUserPageTable must be set before alloctation of EfiRing3MemoryType pages. // - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -284,6 +298,7 @@ CoreFileRead ( &Ring3Pages ); if (EFI_ERROR (Status)) { + gUserPageTable = OldPageTable; return Status; } @@ -317,6 +332,8 @@ CoreFileRead ( CoreFreePages (Ring3Pages, PagesNumber); + gUserPageTable = OldPageTable; + return Status; } @@ -340,10 +357,12 @@ CoreFileSetPosition ( IN UINT64 Position ) { + EFI_STATUS Status; USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; + UINTN OldPageTable; - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -353,40 +372,43 @@ CoreFileSetPosition ( ForbidSupervisorAccessToUserMemory (); #if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) - return GoToRing3 ( - 2, - EntryPoint, - UserDriver, - This, - Position - ); + Status = GoToRing3 ( + 2, + EntryPoint, + UserDriver, + This, + Position + ); #elif defined (MDE_CPU_IA32) // // UINT64 Position is passed as 2 double words on stack. // - return GoToRing3 ( - 3, - EntryPoint, - UserDriver, - This, - Position - ); + Status = GoToRing3 ( + 3, + EntryPoint, + UserDriver, + This, + Position + ); #elif defined (MDE_CPU_ARM) // // UINT64 Position is passed as 2 words in 2 registers and is aligned on 8 bytes. // R0 == This, R1 == NULL, R2 == Position_Low, R3 == Position_High. // - return GoToRing3 ( - 4, - EntryPoint, - UserDriver, - This, - NULL, - (UINT32)Position, - (UINT32)(Position >> 32) - ); + Status = GoToRing3 ( + 4, + EntryPoint, + UserDriver, + This, + NULL, + (UINT32)Position, + (UINT32)(Position >> 32) + ); #endif + gUserPageTable = OldPageTable; + + return Status; } STATIC @@ -401,12 +423,13 @@ CoreFileGetPosition ( EFI_PHYSICAL_ADDRESS Ring3Position; USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; + UINTN OldPageTable; if ((This == NULL) || (Position == NULL)) { return EFI_INVALID_PARAMETER; } - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -418,6 +441,7 @@ CoreFileGetPosition ( &Ring3Position ); if (EFI_ERROR (Status)) { + gUserPageTable = OldPageTable; return Status; } @@ -440,6 +464,8 @@ CoreFileGetPosition ( CoreFreePages (Ring3Position, 1); + gUserPageTable = OldPageTable; + return Status; } @@ -461,12 +487,13 @@ CoreFileGetInfo ( UINT32 PagesNumber; USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; + UINTN OldPageTable; if ((This == NULL) || (BufferSize == NULL)) { return EFI_INVALID_PARAMETER; } - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -484,6 +511,7 @@ CoreFileGetInfo ( &Ring3Pages ); if (EFI_ERROR (Status)) { + gUserPageTable = OldPageTable; return Status; } @@ -526,6 +554,8 @@ CoreFileGetInfo ( CoreFreePages (Ring3Pages, PagesNumber); + gUserPageTable = OldPageTable; + return Status; } @@ -620,12 +650,13 @@ CoreFileOpen ( USER_SPACE_DRIVER *UserDriver; USER_SPACE_DRIVER *NewDriver; VOID *EntryPoint; + UINTN OldPageTable; if ((This == NULL) || (NewHandle == NULL) || (FileName == NULL)) { return EFI_INVALID_PARAMETER; } - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -644,6 +675,7 @@ CoreFileOpen ( ); if (EFI_ERROR (Status)) { *NewHandle = NULL; + gUserPageTable = OldPageTable; return Status; } @@ -657,6 +689,7 @@ CoreFileOpen ( if (EFI_ERROR (Status)) { *NewHandle = NULL; CoreFreePages (Ring3Pages, PagesNumber); + gUserPageTable = OldPageTable; return Status; } @@ -709,6 +742,7 @@ CoreFileOpen ( if (EFI_ERROR (Status)) { *NewHandle = NULL; CoreFreePages (Ring3Pages, PagesNumber); + gUserPageTable = OldPageTable; return Status; } @@ -716,6 +750,7 @@ CoreFileOpen ( if (NewFile == NULL) { *NewHandle = NULL; CoreFreePages (Ring3Pages, PagesNumber); + gUserPageTable = OldPageTable; return EFI_OUT_OF_RESOURCES; } @@ -751,6 +786,8 @@ CoreFileOpen ( CoreFreePages (Ring3Pages, PagesNumber); + gUserPageTable = OldPageTable; + return Status; } @@ -768,12 +805,13 @@ CoreOpenVolume ( USER_SPACE_DRIVER *UserDriver; USER_SPACE_DRIVER *NewDriver; VOID *EntryPoint; + UINTN OldPageTable; if (Root == NULL) { return EFI_INVALID_PARAMETER; } - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -790,6 +828,7 @@ CoreOpenVolume ( ); if (EFI_ERROR (Status)) { *Root = NULL; + gUserPageTable = OldPageTable; return Status; } @@ -805,6 +844,7 @@ CoreOpenVolume ( if (EFI_ERROR (Status)) { *Root = NULL; CoreFreePages (Physical, 1); + gUserPageTable = OldPageTable; return Status; } @@ -812,6 +852,7 @@ CoreOpenVolume ( if (File == NULL) { *Root = NULL; CoreFreePages (Physical, 1); + gUserPageTable = OldPageTable; return EFI_OUT_OF_RESOURCES; } @@ -847,6 +888,8 @@ CoreOpenVolume ( CoreFreePages (Physical, 1); + gUserPageTable = OldPageTable; + return Status; } @@ -864,8 +907,9 @@ CoreUnicodeCollationStriColl ( VOID *EntryPoint; UINTN Size1; UINTN Size2; + UINTN OldPageTable; - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -880,6 +924,7 @@ CoreUnicodeCollationStriColl ( &UserMem ); if (EFI_ERROR (Status)) { + gUserPageTable = OldPageTable; return 0; } @@ -900,6 +945,8 @@ CoreUnicodeCollationStriColl ( CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1 + Size2)); + gUserPageTable = OldPageTable; + return (INTN)Status; } @@ -917,8 +964,9 @@ CoreUnicodeCollationMetaiMatch ( VOID *EntryPoint; UINTN Size1; UINTN Size2; + UINTN OldPageTable; - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -933,6 +981,7 @@ CoreUnicodeCollationMetaiMatch ( &UserMem ); if (EFI_ERROR (Status)) { + gUserPageTable = OldPageTable; return FALSE; } @@ -953,6 +1002,8 @@ CoreUnicodeCollationMetaiMatch ( CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1 + Size2)); + gUserPageTable = OldPageTable; + return (BOOLEAN)Status; } @@ -968,8 +1019,9 @@ CoreUnicodeCollationStrLwr ( USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; UINTN Size1; + UINTN OldPageTable; - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -983,6 +1035,7 @@ CoreUnicodeCollationStrLwr ( &UserMem ); if (EFI_ERROR (Status)) { + gUserPageTable = OldPageTable; return; } @@ -1004,6 +1057,8 @@ CoreUnicodeCollationStrLwr ( ForbidSupervisorAccessToUserMemory (); CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1)); + + gUserPageTable = OldPageTable; } VOID @@ -1018,8 +1073,9 @@ CoreUnicodeCollationStrUpr ( USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; UINTN Size1; + UINTN OldPageTable; - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -1033,6 +1089,7 @@ CoreUnicodeCollationStrUpr ( &UserMem ); if (EFI_ERROR (Status)) { + gUserPageTable = OldPageTable; return; } @@ -1054,6 +1111,8 @@ CoreUnicodeCollationStrUpr ( ForbidSupervisorAccessToUserMemory (); CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (Size1)); + + gUserPageTable = OldPageTable; } VOID @@ -1069,8 +1128,9 @@ CoreUnicodeCollationFatToStr ( EFI_PHYSICAL_ADDRESS UserMem; USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; + UINTN OldPageTable; - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -1082,6 +1142,7 @@ CoreUnicodeCollationFatToStr ( &UserMem ); if (EFI_ERROR (Status)) { + gUserPageTable = OldPageTable; return; } @@ -1105,6 +1166,8 @@ CoreUnicodeCollationFatToStr ( ForbidSupervisorAccessToUserMemory (); CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (FatSize * 3)); + + gUserPageTable = OldPageTable; } BOOLEAN @@ -1121,8 +1184,9 @@ CoreUnicodeCollationStrToFat ( USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; UINTN Size1; + UINTN OldPageTable; - UserDriver = FindUserSpaceDriver (This); + UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; @@ -1136,6 +1200,7 @@ CoreUnicodeCollationStrToFat ( &UserMem ); if (EFI_ERROR (Status)) { + gUserPageTable = OldPageTable; return FALSE; } @@ -1160,5 +1225,7 @@ CoreUnicodeCollationStrToFat ( CoreFreePages (UserMem, EFI_SIZE_TO_PAGES (FatSize + Size1)); + gUserPageTable = OldPageTable; + return (BOOLEAN)Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index fd294cb7ae..baa3326a7c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -218,6 +218,7 @@ ASM_PFX(CallRing3): push r13 push r14 push r15 + push qword [ASM_PFX(SysCallStackTop)] ; Save Core Stack pointer. mov [r9], rsp @@ -260,6 +261,7 @@ ASM_PFX(SysCallEnd): global ASM_PFX(ReturnToCore) ASM_PFX(ReturnToCore): mov rsp, rdx + pop qword [ASM_PFX(SysCallStackTop)] pop r15 pop r14 pop r13 diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index ee98e905b9..f2580e130b 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -264,7 +264,7 @@ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf -INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index f3d5243bde..97af2a906d 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -266,7 +266,7 @@ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf -INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index d75733da6a..0a95e190a3 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -298,7 +298,7 @@ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf -INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf From 0a58c434b7359e968a72429c7f5b77b3771c923f Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 20 Jan 2025 16:28:26 +0300 Subject: [PATCH 313/341] CpuExceptionHandlerLib: Refactored out mSwitchCr3Flag. --- UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c | 3 --- .../CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm | 8 +++----- .../CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm | 8 +++----- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c index 9429df0355..ce4f32a58f 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c @@ -34,7 +34,6 @@ EXCEPTION_ADDRESSES mAddresses; extern UINTN ExceptionHandlerBase; extern UINTN ExceptionHandlerEnd; -extern UINT8 mSwitchCr3Flag; extern UINTN CorePageTable; /** @@ -203,8 +202,6 @@ GetExceptionAddresses ( VOID ) { - mSwitchCr3Flag = 1; - return &mAddresses; } diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm index ee2a061fd5..07fef59095 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm @@ -38,10 +38,6 @@ global ASM_PFX(UserPageTable) ASM_PFX(UserPageTable): resq 1 -global ASM_PFX(mSwitchCr3Flag) -ASM_PFX(mSwitchCr3Flag): - db 0x0 - ALIGN 4096 Padding: db 0x0 @@ -105,7 +101,9 @@ HookAfterStubHeaderEnd: global ASM_PFX(CommonInterruptEntry) ASM_PFX(CommonInterruptEntry): cli - cmp byte [ASM_PFX(mSwitchCr3Flag)], 0 + ; Check whether User Space process was interrupted. + mov eax, ds + and eax, 3 jz NoCr3Switch mov eax, cr3 mov [ASM_PFX(UserPageTable)], eax diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm index 9ba3ae5172..278ff4f592 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm @@ -63,10 +63,6 @@ global ASM_PFX(UserPageTable) ASM_PFX(UserPageTable): resq 1 -global ASM_PFX(mSwitchCr3Flag) -ASM_PFX(mSwitchCr3Flag): - db 0x0 - ALIGN 4096 Padding: db 0x0 @@ -140,7 +136,9 @@ HookAfterStubHeaderEnd: global ASM_PFX(CommonInterruptEntry) ASM_PFX(CommonInterruptEntry): cli - cmp byte [ASM_PFX(mSwitchCr3Flag)], 0 + ; Check whether User Space process was interrupted. + mov rax, ds + and rax, 3 jz NoCr3Switch mov rax, cr3 mov [ASM_PFX(UserPageTable)], rax From 00f99dd68812b528776e5107d7803199b6b7ef73 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 20 Jan 2025 16:30:21 +0300 Subject: [PATCH 314/341] Ring3: Fixed line endings. --- .../ArmExceptionLib/Arm/ExceptionSupport.S | 16 +++++----- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 6 ++-- .../Core/Dxe/SysCall/SupportedProtocols.c | 6 ++-- .../CpuExceptionHandlerLib/DxeException.c | 30 +++++++++---------- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S index 9c5c6398c1..9245a00dfe 100644 --- a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S @@ -101,7 +101,7 @@ ASM_PFX(Fiq): ASM_PFX(ResetEntry): srsdb #0x13! @ Store return state on SVC stack @ We are already in SVC mode - sub SP, SP, #0x8 @ Save space for TTBR0 + sub SP, SP, #0x8 @ Save space for TTBR0 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -128,7 +128,7 @@ ASM_PFX(SoftwareInterruptEntry): isb srsdb #0x13! @ Store return state on SVC stack @ We are already in SVC mode - sub SP, SP, #0x8 @ Save space for TTBR0 + sub SP, SP, #0x8 @ Save space for TTBR0 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -278,9 +278,9 @@ NoAdjustNeeded: NoTTBR0Switch: -#if (FixedPcdGet32(PcdVFPEnabled)) - vpush {d0-d15} @ save vstm registers in case they are used in optimizations -#endif +#if (FixedPcdGet32(PcdVFPEnabled)) + vpush {d0-d15} @ save vstm registers in case they are used in optimizations +#endif mov R4, SP @ Save current SP tst R4, #4 @@ -301,9 +301,9 @@ CommonCExceptionHandler ( mov SP, R4 @ Restore SP -#if (FixedPcdGet32(PcdVFPEnabled)) - vpop {d0-d15} -#endif +#if (FixedPcdGet32(PcdVFPEnabled)) + vpop {d0-d15} +#endif ldr R4, [SP, #0x40] @ Saved Processor Status Register and R4, R4, #0xF diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 0fa82094ac..73d968b971 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -139,9 +139,9 @@ ASM_FUNC(ReturnToCore) #endif // Restore old SP_usr and LR_usr. - ldmia SP, {SP, LR}^ - add SP, SP, #0x8 - + ldmia SP, {SP, LR}^ + add SP, SP, #0x8 + pop {R4-R12, LR} // Enable interrupts. diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index eb4889c4ae..ddfa59a657 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -169,7 +169,7 @@ CoreDriverBindingStart ( RemainingDevicePath ); - gUserPageTable = OldPageTable; + gUserPageTable = OldPageTable; return Status; } @@ -207,7 +207,7 @@ CoreDriverBindingStop ( ChildHandleBuffer ); - gUserPageTable = OldPageTable; + gUserPageTable = OldPageTable; return Status; } @@ -243,7 +243,7 @@ CoreFileClose ( FreePool (UserDriver->CoreWrapper); RemoveEntryList (&UserDriver->Link); - gUserPageTable = OldPageTable; + gUserPageTable = OldPageTable; return Status; } diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c index ce4f32a58f..8490142e8a 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c @@ -205,18 +205,18 @@ GetExceptionAddresses ( return &mAddresses; } -VOID -EFIAPI -SetExceptionAddresses ( - IN VOID *Buffer, - IN UINTN BufferSize - ) -{ - mAddresses.ExceptionStackBase = (UINTN)Buffer; - mAddresses.ExceptionStackSize = BufferSize; - mAddresses.ExceptionHandlerBase = (UINTN)&ExceptionHandlerBase; - mAddresses.ExceptionHandlerSize = (UINTN)&ExceptionHandlerEnd - mAddresses.ExceptionHandlerBase; - mAddresses.ExceptionDataBase = (UINTN)&CorePageTable; - - CorePageTable = AsmReadCr3 (); -} +VOID +EFIAPI +SetExceptionAddresses ( + IN VOID *Buffer, + IN UINTN BufferSize + ) +{ + mAddresses.ExceptionStackBase = (UINTN)Buffer; + mAddresses.ExceptionStackSize = BufferSize; + mAddresses.ExceptionHandlerBase = (UINTN)&ExceptionHandlerBase; + mAddresses.ExceptionHandlerSize = (UINTN)&ExceptionHandlerEnd - mAddresses.ExceptionHandlerBase; + mAddresses.ExceptionDataBase = (UINTN)&CorePageTable; + + CorePageTable = AsmReadCr3 (); +} From 2a36606f2ee63724a9c3f8dc039dff1b2f25b809 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 20 Jan 2025 19:45:00 +0300 Subject: [PATCH 315/341] Ring3: Saved ReturnSP on SysCallStack. --- .../Library/DefaultExceptionHandlerLib.h | 4 +--- .../ArmExceptionLib/Arm/ExceptionSupport.S | 22 ++++++++++--------- .../AArch64/DefaultExceptionHandler.c | 6 +---- .../Arm/DefaultExceptionHandler.c | 6 +---- MdeModulePkg/Core/Dxe/DxeMain.h | 4 ++-- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 14 +++++------- .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 18 ++++++--------- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 16 ++++++-------- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 20 +++++++---------- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 10 ++++----- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 16 ++++++++------ .../Core/Dxe/SysCall/SupportedProtocols.c | 7 ++---- .../Dxe/SysCall/X64/CoreBootServices.nasm | 11 +++++----- MdePkg/Include/Protocol/DebugSupport.h | 3 +++ 14 files changed, 69 insertions(+), 88 deletions(-) diff --git a/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h b/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h index 24893c6fa8..faa91fe589 100644 --- a/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h +++ b/ArmPkg/Include/Library/DefaultExceptionHandlerLib.h @@ -12,9 +12,7 @@ typedef EFI_STATUS (EFIAPI *EFI_SYS_CALL_BOOT_SERVICE)( - IN UINT8 Type, - IN VOID *CoreRbp, - IN VOID *UserRsp + IN EFI_SYSTEM_CONTEXT Context ); /** diff --git a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S index 9245a00dfe..ed6895a0ff 100644 --- a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S @@ -44,7 +44,7 @@ This is the stack constructed by the exception handler (low address to high addr LR 0x54 # SVC Link register (we need to restore it) TTBR0 0x58 -Padding 0x5c + SP_EL1 0x5c LR 0x60 # pushed by srsfd CPSR 0x64 @@ -101,7 +101,7 @@ ASM_PFX(Fiq): ASM_PFX(ResetEntry): srsdb #0x13! @ Store return state on SVC stack @ We are already in SVC mode - sub SP, SP, #0x8 @ Save space for TTBR0 + sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -114,7 +114,7 @@ ASM_PFX(UndefinedInstructionEntry): sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry srsdb #0x13! @ Store return state on SVC stack cps #0x13 @ Switch to SVC for common stack - sub SP, SP, #0x8 @ Save space for TTBR0 + sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -128,7 +128,7 @@ ASM_PFX(SoftwareInterruptEntry): isb srsdb #0x13! @ Store return state on SVC stack @ We are already in SVC mode - sub SP, SP, #0x8 @ Save space for TTBR0 + sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -141,7 +141,7 @@ ASM_PFX(PrefetchAbortEntry): sub LR,LR,#4 srsdb #0x13! @ Store return state on SVC stack cps #0x13 @ Switch to SVC for common stack - sub SP, SP, #0x8 @ Save space for TTBR0 + sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -154,7 +154,7 @@ ASM_PFX(DataAbortEntry): sub LR,LR,#8 srsdb #0x13! @ Store return state on SVC stack cps #0x13 @ Switch to SVC for common stack - sub SP, SP, #0x8 @ Save space for TTBR0 + sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -166,7 +166,7 @@ ASM_PFX(DataAbortEntry): ASM_PFX(ReservedExceptionEntry): srsdb #0x13! @ Store return state on SVC stack cps #0x13 @ Switch to SVC for common stack - sub SP, SP, #0x8 @ Save space for TTBR0 + sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -179,7 +179,7 @@ ASM_PFX(IrqEntry): sub LR,LR,#4 srsdb #0x13! @ Store return state on SVC stack cps #0x13 @ Switch to SVC for common stack - sub SP, SP, #0x8 @ Save space for TTBR0 + sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -192,7 +192,7 @@ ASM_PFX(FiqEntry): sub LR,LR,#4 srsdb #0x13! @ Store return state on SVC stack cps #0x13 @ Switch to SVC for common stack - sub SP, SP, #0x8 @ Save space for TTBR0 + sub SP, SP, #0x8 @ Save space for TTBR0 and SP_EL1 stmfd SP!,{LR} @ Store the link register for the current mode sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR stmfd SP!,{R0-R12} @ Store the register state @@ -242,6 +242,8 @@ ASM_PFX(AsmCommonExceptionEntry): addne R1, SP, #0x68 @ We pushed 0x68 bytes on the stack strne R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP + add R1, SP, #0x68 @ We pushed 0x68 bytes on the stack + str R1, [SP, #0x5c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP_EL1 ldr R5, [SP, #0x60] @ PC is the LR pushed by srsfd @ Check to see if we have to adjust for Thumb entry @@ -334,7 +336,7 @@ NoTTBR0Switch2: add SP,SP,#0x20 @ Clear out the remaining stack space ldmfd SP!,{LR} @ restore the link register for this context - add SP, SP, #0x8 @ Clear out TTBR0 and Padding + add SP, SP, #0x8 @ Clear out TTBR0 and SP_EL1 rfefd SP! @ return from exception via srsfd stack slot ASM_FUNC_ALIGN(ExceptionHandlerFinal, 4096) diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index d5dd1fbbd2..8f875c9e44 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -210,11 +210,7 @@ DefaultExceptionHandler ( INT32 Offset; if (AARCH64_ESR_EC (SystemContext.SystemContextAArch64->ESR) == AARCH64_ESR_EC_SVC64) { - return mSysCallHandler ( - SystemContext.SystemContextAArch64->X0, - &(SystemContext.SystemContextAArch64->X1), - &(SystemContext.SystemContextAArch64->X0) - ); + return mSysCallHandler (SystemContext); } if (mRecursiveException) { diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c index d6c9cca286..ae8a878b1e 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/Arm/DefaultExceptionHandler.c @@ -222,11 +222,7 @@ DefaultExceptionHandler ( BOOLEAN DfsrWrite; if (ExceptionType == EXCEPT_ARM_SOFTWARE_INTERRUPT) { - return mSysCallHandler ( - SystemContext.SystemContextArm->R0, - &(SystemContext.SystemContextArm->R1), - (VOID *)SystemContext.SystemContextArm->SP - ); + return mSysCallHandler (SystemContext); } CharCount = AsciiSPrint ( diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 234ee381c5..4444836347 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -241,7 +241,6 @@ typedef struct { UINTN UserPageTable; UINTN UserStackTop; UINTN SysCallStackTop; - UINTN ReturnSP; LIST_ENTRY Link; } USER_SPACE_DRIVER; @@ -2750,7 +2749,8 @@ EFI_STATUS EFIAPI CallBootService ( IN UINT8 Type, - IN UINTN *UserArguments + IN UINTN *UserArguments, + IN UINTN ReturnSP ); VOID diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index e6161dff8b..e5ea1c96a0 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -62,16 +62,14 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) // CallRing3 ( // IN RING3_CALL_DATA *Data, // IN UINTN UserStackTop, -// IN UINTN SysCallStackTop, -// IN UINTN *ReturnSP +// IN UINTN SysCallStackTop // ); // // (x0) Data // (x1) UserStackTop // (x2) gRing3EntryPoint // (x3) SysCallStackTop -// (x4) ReturnSP -// (x5) gUserPageTable +// (x4) gUserPageTable //------------------------------------------------------------------------------ ASM_FUNC(ArmCallRing3) // Save registers. @@ -94,10 +92,10 @@ ASM_FUNC(ArmCallRing3) // Disable interrupts. msr daifset, #0xf isb - // Save Core SP and switch to SysCallStackTop. + // Switch to SysCallStackTop and save ReturnSP on it. mov x6, sp - str x6, [x4] mov sp, x3 + stp x6, xzr, [sp, #-0x10]! // Copy PSTATE to SPSR. mrs x6, nzcv mrs x7, pan @@ -107,12 +105,12 @@ ASM_FUNC(ArmCallRing3) EL1_OR_EL2(x1) 1:msr elr_el1, x2 msr spsr_el1, x6 - msr ttbr0_el1, x5 + msr ttbr0_el1, x4 tlbi vmalle1 b 3f 2:msr elr_el2, x2 msr spsr_el2, x6 - msr ttbr0_el2, x5 + msr ttbr0_el2, x4 tlbi alle2 3:dsb sy isb diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index acbe3af845..fbc5581d81 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -21,7 +21,6 @@ ArmCallRing3 ( IN UINTN UserStackTop, IN VOID *EntryPoint, IN UINTN SysCallStackTop, - IN UINTN *ReturnSP, IN UINTN UserPageTable ); @@ -29,9 +28,7 @@ STATIC EFI_STATUS EFIAPI SysCallBootService ( - IN UINT8 Type, - IN VOID *CoreRbp, - IN VOID *UserRsp + IN EFI_SYSTEM_CONTEXT Context ) { EFI_STATUS Status; @@ -42,7 +39,7 @@ SysCallBootService ( Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), + EFI_SIZE_TO_PAGES (8 * sizeof (UINTN)), &Physical ); if (EFI_ERROR (Status)) { @@ -50,12 +47,13 @@ SysCallBootService ( } AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)((UINTN)Physical + sizeof (UINTN)), (VOID *)UserRsp, 8 * sizeof (UINTN)); + CopyMem ((VOID *)Physical, (VOID *)&(Context.SystemContextAArch64->X0), 8 * sizeof (UINTN)); ForbidSupervisorAccessToUserMemory (); Status = CallBootService ( - Type, - (UINTN *)((UINTN)Physical + sizeof (UINTN)) + Context.SystemContextAArch64->X0, + (UINTN *)Physical, + *(UINTN *)Context.SystemContextAArch64->SP ); CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); @@ -151,8 +149,7 @@ EFIAPI CallRing3 ( IN RING3_CALL_DATA *Data, IN UINTN UserStackTop, - IN UINTN SysCallStackTop, - IN UINTN *ReturnSP + IN UINTN SysCallStackTop ) { return ArmCallRing3 ( @@ -160,7 +157,6 @@ CallRing3 ( UserStackTop, gRing3EntryPoint, SysCallStackTop, - ReturnSP, gUserPageTable ); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 73d968b971..d34b6a8a07 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -58,8 +58,7 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) // CallRing3 ( // IN RING3_CALL_DATA *Data, // IN UINTN UserStackTop, -// IN UINTN SysCallStackTop, -// IN UINTN *ReturnSP +// IN UINTN SysCallStackTop // ); // // (r0) Data @@ -67,15 +66,13 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) // (r2) gRing3EntryPoint // (r3) SysCallStackTop // -// (On Core Stack) ReturnSP, gUserPageTable +// (On Core Stack) gUserPageTable //------------------------------------------------------------------------------ ASM_FUNC(ArmCallRing3) // Save registers. push {R4-R12, LR} - // R6 is ReturnSP - ldr R6, [SP, #0x28] // R7 is gUserPageTable - ldr R7, [SP, #0x2C] + ldr R7, [SP, #0x28] // Save old SP_usr and LR_usr on Core Stack. sub SP, SP, #0x8 stmia SP, {SP, LR}^ @@ -98,10 +95,11 @@ ASM_FUNC(ArmCallRing3) // Set SPSR M[3:0] bits to User mode. and R4, R4, #0xFFFFFFF0 - // Save Core SP and switch to SysCallStackTop. + // Switch to SysCallStackTop and save ReturnSP on it. mov R5, SP - str R5, [R6] mov SP, R3 + push {R5} + push {R5} // Align stack on 8 bytes // Switch to UserPageTable. mrc p15,0,R8,c2,c0,0 // R8 == TTBR0 @@ -115,7 +113,7 @@ ASM_FUNC(ArmCallRing3) push {R4} push {R2} - rfefd SP + rfefd SP! ASM_FUNC_ALIGN(SysCallEnd, 4096) //------------------------------------------------------------------------------ diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 34d5c43e2c..498037385b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -20,7 +20,6 @@ ArmCallRing3 ( IN UINTN UserStackTop, IN VOID *EntryPoint, IN UINTN SysCallStackTop, - IN UINTN *ReturnSP, IN UINTN UserPageTable ); @@ -28,9 +27,7 @@ STATIC EFI_STATUS EFIAPI SysCallBootService ( - IN UINT8 Type, - IN VOID *CoreRbp, - IN VOID *UserRsp + IN EFI_SYSTEM_CONTEXT Context ) { EFI_STATUS Status; @@ -41,7 +38,7 @@ SysCallBootService ( Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (9 * sizeof (UINTN)), + EFI_SIZE_TO_PAGES (8 * sizeof (UINTN)), &Physical ); if (EFI_ERROR (Status)) { @@ -52,16 +49,17 @@ SysCallBootService ( // // First 3 arguments are passed through R1-R3 and copied to SysCall Stack. // - CopyMem ((VOID *)((UINTN)Physical + 2 * sizeof (UINTN)), (VOID *)CoreRbp, 3 * sizeof (UINTN)); + CopyMem ((VOID *)(UINTN)Physical, (VOID *)&(Context.SystemContextArm->R0), 4 * sizeof (UINTN)); // // All remaining arguments are on User Stack. // - CopyMem ((VOID *)((UINTN)Physical + 5 * sizeof (UINTN)), (VOID *)UserRsp, 4 * sizeof (UINTN)); + CopyMem ((VOID *)((UINTN)Physical + 4 * sizeof (UINTN)), (VOID *)Context.SystemContextArm->SP, 4 * sizeof (UINTN)); ForbidSupervisorAccessToUserMemory (); Status = CallBootService ( - Type, - (UINTN *)((UINTN)Physical + sizeof (UINTN)) + Context.SystemContextArm->R0, + (UINTN *)(UINTN)Physical, + *(UINTN *)Context.SystemContextArm->SP_EL1 ); // // TODO: Fix memory leak for ReturnToCore(). @@ -146,8 +144,7 @@ EFIAPI CallRing3 ( IN RING3_CALL_DATA *Data, IN UINTN UserStackTop, - IN UINTN SysCallStackTop, - IN UINTN *ReturnSP + IN UINTN SysCallStackTop ) { return ArmCallRing3 ( @@ -155,7 +152,6 @@ CallRing3 ( UserStackTop, gRing3EntryPoint, SysCallStackTop, - ReturnSP, gUserPageTable ); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 59bef0920e..184c3a7b62 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -318,7 +318,7 @@ FindUserInfo ( for (Link = gUserSpaceDriversHead.ForwardLink; Link != &gUserSpaceDriversHead; Link = Link->ForwardLink) { UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link); - if ((UserDriver->UserPageTable == gUserPageTable) && (UserDriver->ReturnSP != 0)) { + if (UserDriver->UserPageTable == gUserPageTable) { return UserDriver; } } @@ -330,7 +330,8 @@ EFI_STATUS EFIAPI CallBootService ( IN UINT8 Type, - IN UINTN *UserArguments + IN UINTN *UserArguments, + IN UINTN ReturnSP ) { EFI_STATUS Status; @@ -372,10 +373,8 @@ CallBootService ( switch (Type) { case SysCallReturnToCore: Arguments = CopyUserArguments (1, UserArguments); - UserDriver = FindUserInfo (); - ASSERT (UserDriver != NULL); - ReturnToCore (Arguments[1], UserDriver->ReturnSP); + ReturnToCore (Arguments[1], ReturnSP); break; case SysCallLocateProtocol: // @@ -531,7 +530,6 @@ CallBootService ( NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserStackTop = UserDriver->UserStackTop; NewDriver->SysCallStackTop = UserDriver->SysCallStackTop; - NewDriver->ReturnSP = 0; InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index 72f8e66a22..9478b93345 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -133,6 +133,8 @@ ASM_PFX(CoreBootServices): ; Prepare CallBootService arguments. mov ebp, esp + mov eax, [esp + 4*3] + push eax ; ReturnSP add edx, 4 ; User Arguments[] push edx push ecx ; Type @@ -166,11 +168,10 @@ ASM_PFX(CoreBootServices): ; CallRing3 ( ; IN RING3_CALL_DATA *Data, ; IN UINTN UserStackTop, -; IN UINTN SysCallStackTop, -; IN UINTN *ReturnSP +; IN UINTN SysCallStackTop ; ); ; -; (On User Stack) Data, UserStackTop, SysCallStackTop, ReturnSP +; (On User Stack) Data, UserStackTop, SysCallStackTop ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): @@ -186,15 +187,16 @@ ASM_PFX(CallRing3): pop ebx push eax - ; Save Core Stack pointer. - mov ebx, [esp + 4 * 9] ; ReturnSP - mov [ebx], esp - + ; Set new SysCallStackTop. mov edx, 0 mov eax, [esp + 4 * 8] ; SysCallStackTop + sub eax, 4 mov ecx, MSR_IA32_SYSENTER_ESP wrmsr + ; Save ReturnSP on SysCallStack. + mov [eax], esp + SetRing3DataSegmentSelectors ; Prepare SYSEXIT arguments. diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index ddfa59a657..530f69238f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -15,8 +15,7 @@ EFIAPI CallRing3 ( IN RING3_CALL_DATA *Data, IN UINTN UserStackTop, - IN UINTN SysCallStackTop, - IN UINTN *ReturnSP + IN UINTN SysCallStackTop ); EFI_STATUS @@ -66,12 +65,10 @@ GoToRing3 ( Status = CallRing3 ( Input, UserDriver->UserStackTop, - UserDriver->SysCallStackTop, - &UserDriver->ReturnSP + UserDriver->SysCallStackTop ); CoreFreePages (Ring3Pages, PagesNumber); - UserDriver->ReturnSP = 0; return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index baa3326a7c..2b48d77740 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -162,6 +162,8 @@ ASM_PFX(CoreBootServices): mov rcx, r10 ; Type mov rdx, [rbp + 8*3] add rdx, 8 ; User Arguments[] + mov rax, [ASM_PFX(SysCallStackTop)] + mov r8, [rax] ; ReturnSP sti call ASM_PFX(CallBootService) @@ -195,14 +197,12 @@ o64 sysret ; CallRing3 ( ; IN RING3_CALL_DATA *Data, ; IN UINTN UserStackTop, -; IN UINTN SysCallStackTop, -; IN UINTN *ReturnSP +; IN UINTN SysCallStackTop ; ); ; ; (rcx) Data ; (rdx) UserStackTop ; (r8) SysCallStackTop -; (r9) ReturnSP ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): @@ -220,8 +220,9 @@ ASM_PFX(CallRing3): push r15 push qword [ASM_PFX(SysCallStackTop)] - ; Save Core Stack pointer. - mov [r9], rsp + ; Save ReturnSP on SysCallStack. + sub r8, 8 + mov [r8], rsp ; Save input Arguments. mov rbx, rdx diff --git a/MdePkg/Include/Protocol/DebugSupport.h b/MdePkg/Include/Protocol/DebugSupport.h index 5b7e331780..d8623d1938 100644 --- a/MdePkg/Include/Protocol/DebugSupport.h +++ b/MdePkg/Include/Protocol/DebugSupport.h @@ -507,6 +507,9 @@ typedef struct { UINT32 DFAR; UINT32 IFSR; UINT32 IFAR; + UINT32 SVC_LR; + UINT32 TTBR0; + UINT32 SP_EL1; } EFI_SYSTEM_CONTEXT_ARM; /// From 2504a9f48b53b963ecd38f3e98ba10879b0d1d20 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 21 Jan 2025 19:37:32 +0300 Subject: [PATCH 316/341] Ring3: Added NumberOfArguments to SysCall() and CallBootService(). --- MdeModulePkg/Core/Dxe/DxeMain.h | 1 + .../Core/Dxe/DxeRing3/AARCH64/SysCall.S | 3 +- MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S | 3 +- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 2 +- .../Core/Dxe/DxeRing3/IA32/SysCall.nasm | 26 +++++- MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h | 3 +- .../Core/Dxe/DxeRing3/Ring3Protocols.c | 12 +++ .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 11 +++ .../Dxe/DxeRing3/Ring3UefiRuntimeServices.c | 1 + .../Core/Dxe/DxeRing3/X64/SysCall.nasm | 19 +++- .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 7 +- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 57 +++++++++--- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 91 ++----------------- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 6 +- .../Dxe/SysCall/X64/CoreBootServices.nasm | 18 +--- MdePkg/Include/Uefi/UefiSpec.h | 15 ++- 16 files changed, 147 insertions(+), 128 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 4444836347..245e7be677 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2749,6 +2749,7 @@ EFI_STATUS EFIAPI CallBootService ( IN UINT8 Type, + IN UINT8 NumberOfArguments, IN UINTN *UserArguments, IN UINTN ReturnSP ); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S index 7ed039d821..4a63ec87e1 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S @@ -11,7 +11,8 @@ // EFI_STATUS // EFIAPI // SysCall ( -// IN UINT8 Type, +// IN UINT8 Type, +// IN UINT8 NumberOfArguments, // ... // ); //------------------------------------------------------------------------------ diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S index 2f0495f31f..2a0a28e32f 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S @@ -11,7 +11,8 @@ // EFI_STATUS // EFIAPI // SysCall ( -// IN UINT8 Type, +// IN UINT8 Type, +// IN UINT8 NumberOfArguments, // ... // ); //------------------------------------------------------------------------------ diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index 3afb8f37e4..b024fb5aac 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -238,7 +238,7 @@ Ring3Call ( break; } - SysCall (SysCallReturnToCore, Status); + SysCall (SysCallReturnToCore, 1, Status); } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm index 40e22ef83e..7b6ff6d1c4 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm @@ -3,6 +3,8 @@ ; SPDX-License-Identifier: BSD-3-Clause ;------------------------------------------------------------------------------ +#include + extern ASM_PFX(Ring3Call) DEFAULT REL @@ -12,18 +14,36 @@ SECTION .text ; EFI_STATUS ; EFIAPI ; SysCall ( -; IN UINT8 Type, +; IN UINT8 Type, +; IN UINT8 NumberOfArguments, ; ... ; ); ;------------------------------------------------------------------------------ global ASM_PFX(SysCall) ASM_PFX(SysCall): + push ebx mov edx, esp - mov ecx, [esp + 4] ; Type + mov ecx, [esp + 4*2] ; Type + mov ebx, [esp + 4*3] ; NumberOfArguments lea eax, [userReturnAddress] - + ; Fixup NumberOfArguments. + cmp ecx, SC_FREE_PAGES + je fixup + cmp ecx, SC_BLOCK_IO_READ + je fixup + cmp ecx, SC_BLOCK_IO_WRITE + je fixup + cmp ecx, SC_DISK_IO_READ + je fixup + cmp ecx, SC_DISK_IO_WRITE + je fixup + jmp makecall +fixup: + add ebx, 1 +makecall: sysenter userReturnAddress: + pop ebx ret ;------------------------------------------------------------------------------ diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h index a2d5e6416d..44c1938344 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h @@ -14,7 +14,8 @@ EFI_STATUS EFIAPI SysCall ( - IN UINT8 Type, + IN UINT8 Type, + IN UINT8 NumberOfArguments, ... ); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c index 7c01109a3e..7b7efeb12f 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c @@ -16,6 +16,7 @@ Ring3BlockIoReset ( { return SysCall ( SysCallBlockIoReset, + 2, This, ExtendedVerification ); @@ -33,6 +34,7 @@ Ring3BlockIoRead ( { return SysCall ( SysCallBlockIoRead, + 5, This, MediaId, BufferSize, @@ -53,6 +55,7 @@ Ring3BlockIoWrite ( { return SysCall ( SysCallBlockIoWrite, + 5, This, MediaId, BufferSize, @@ -69,6 +72,7 @@ Ring3BlockIoFlush ( { return SysCall ( SysCallBlockIoFlush, + 1, This ); } @@ -85,6 +89,7 @@ Ring3DiskIoRead ( { return SysCall ( SysCallDiskIoRead, + 5, This, MediaId, BufferSize, @@ -105,6 +110,7 @@ Ring3DiskIoWrite ( { return SysCall ( SysCallDiskIoWrite, + 5, This, MediaId, BufferSize, @@ -123,6 +129,7 @@ Ring3UnicodeStriColl ( { return (INTN)SysCall ( SysCallUnicodeStriColl, + 3, This, Str1, Str2 @@ -139,6 +146,7 @@ Ring3UnicodeMetaiMatch ( { return (BOOLEAN)SysCall ( SysCallUnicodeMetaiMatch, + 3, This, String, Pattern @@ -154,6 +162,7 @@ Ring3UnicodeStrLwr ( { SysCall ( SysCallUnicodeStrLwr, + 2, This, Str ); @@ -168,6 +177,7 @@ Ring3UnicodeStrUpr ( { SysCall ( SysCallUnicodeStrUpr, + 2, This, Str ); @@ -184,6 +194,7 @@ Ring3UnicodeFatToStr ( { SysCall ( SysCallUnicodeFatToStr, + 4, This, FatSize, Fat, @@ -202,6 +213,7 @@ Ring3UnicodeStrToFat ( { return (BOOLEAN)SysCall ( SysCallUnicodeStrToFat, + 4, This, String, FatSize, diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index cc62ba4f61..04ccc7b669 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -98,6 +98,7 @@ Ring3RaiseTpl ( { return (EFI_TPL)SysCall ( SysCallRaiseTpl, + 1, NewTpl ); } @@ -110,6 +111,7 @@ Ring3RestoreTpl ( { SysCall ( SysCallRestoreTpl, + 1, NewTpl ); } @@ -127,6 +129,7 @@ Ring3AllocatePages ( Status = SysCall ( SysCallAllocatePages, + 4, Type, EfiRing3MemoryType, NumberOfPages, @@ -150,6 +153,7 @@ Ring3FreePages ( Status = SysCall ( SysCallFreePages, + 2, NumberOfPages, Memory ); @@ -302,6 +306,7 @@ Ring3HandleProtocol ( Status = SysCall ( SysCallHandleProtocol, + 3, CoreUserHandle, Protocol, Interface @@ -511,6 +516,7 @@ Ring3OpenProtocol ( Status = SysCall ( SysCallOpenProtocol, + 6, CoreUserHandle, Protocol, Interface, @@ -536,6 +542,7 @@ Ring3CloseProtocol ( { return SysCall ( SysCallCloseProtocol, + 4, UserHandle, Protocol, AgentHandle, @@ -587,6 +594,7 @@ Ring3LocateHandleBuffer ( StatusBS = SysCall ( SysCallLocateHandleBuffer, + 5, SearchType, Protocol, SearchKey, @@ -631,6 +639,7 @@ Ring3LocateProtocol ( Status = SysCall ( SysCallLocateProtocol, + 3, Protocol, CoreRegistration, Interface @@ -673,6 +682,7 @@ Ring3InstallMultipleProtocolInterfaces ( return SysCall ( SysCallInstallMultipleProtocolInterfaces, + 2, Handle, ArgList ); @@ -700,6 +710,7 @@ Ring3CalculateCrc32 ( { return SysCall ( SysCallCalculateCrc32, + 3, Data, DataSize, Crc32 diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c index e4e9af3299..ed888b9b37 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c @@ -91,6 +91,7 @@ Ring3GetVariable ( { return SysCall ( SysCallGetVariable, + 5, VariableName, VendorGuid, Attributes, diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm index d9c3d1162d..6d82942e48 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm @@ -12,7 +12,8 @@ SECTION .text ; EFI_STATUS ; EFIAPI ; SysCall ( -; IN UINT8 Type, +; IN UINT8 Type, +; IN UINT8 NumberOfArguments, ; ... ; ); ;------------------------------------------------------------------------------ @@ -20,7 +21,21 @@ global ASM_PFX(SysCall) ASM_PFX(SysCall): ; Save Type for CoreBootServices(). mov r10, rcx - + ; Construct User Arguments[]. + cmp rdx, 2 + jg continue + push r9 + push r8 + mov r8, rsp + sub r8, 8 + add rsp, 8*2 + jmp makecall +continue: + mov [rsp + 8*4], r9 + mov [rsp + 8*3], r8 + mov r8, rsp + add r8, 8*2 +makecall: ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. syscall ; SYSRET copies the value in RCX into RIP and loads RFLAGS from R11. diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index fbc5581d81..eef01bd07d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -39,7 +39,7 @@ SysCallBootService ( Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (8 * sizeof (UINTN)), + EFI_SIZE_TO_PAGES (7 * sizeof (UINTN)), &Physical ); if (EFI_ERROR (Status)) { @@ -47,16 +47,17 @@ SysCallBootService ( } AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)Physical, (VOID *)&(Context.SystemContextAArch64->X0), 8 * sizeof (UINTN)); + CopyMem ((VOID *)Physical, (VOID *)&(Context.SystemContextAArch64->X1), 7 * sizeof (UINTN)); ForbidSupervisorAccessToUserMemory (); Status = CallBootService ( Context.SystemContextAArch64->X0, + Context.SystemContextAArch64->X1, (UINTN *)Physical, *(UINTN *)Context.SystemContextAArch64->SP ); - CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); + CoreFreePages (Physical, EFI_SIZE_TO_PAGES (7 * sizeof (UINTN))); ArmDisableInterrupts (); diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 498037385b..2ede13fe8c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -32,13 +32,26 @@ SysCallBootService ( { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Physical; + UINT8 Type; + UINT8 NumberOfArguments; ArmEnableInterrupts (); + Type = Context.SystemContextArm->R0; + NumberOfArguments = Context.SystemContextArm->R1; + + if ((Type == SysCallFreePages) + || (Type == SysCallBlockIoRead) + || (Type == SysCallBlockIoWrite) + || (Type == SysCallDiskIoRead) + || (Type == SysCallDiskIoWrite)) { + ++NumberOfArguments; + } + Status = CoreAllocatePages ( AllocateAnyPages, EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (8 * sizeof (UINTN)), + EFI_SIZE_TO_PAGES ((NumberOfArguments + 1) * sizeof (UINTN)), &Physical ); if (EFI_ERROR (Status)) { @@ -46,25 +59,47 @@ SysCallBootService ( } AllowSupervisorAccessToUserMemory (); - // - // First 3 arguments are passed through R1-R3 and copied to SysCall Stack. - // - CopyMem ((VOID *)(UINTN)Physical, (VOID *)&(Context.SystemContextArm->R0), 4 * sizeof (UINTN)); - // - // All remaining arguments are on User Stack. - // - CopyMem ((VOID *)((UINTN)Physical + 4 * sizeof (UINTN)), (VOID *)Context.SystemContextArm->SP, 4 * sizeof (UINTN)); + if (Type == SysCallFreePages) { + // + // R0 == Type, R1 == NumberOfArguments, R2 == NumberOfPages, R3 == NULL + // [SP] == Memory + // Memory is passed as 2 words on stack and aligned on 8 bytes. + // + CopyMem ((VOID *)(UINTN)Physical, (VOID *)&(Context.SystemContextArm->R1), 2 * sizeof (UINTN)); + CopyMem ( + (VOID *)((UINTN)Physical + 2 * sizeof (UINTN)), + (VOID *)Context.SystemContextArm->SP, + 2 * sizeof (UINTN) + ); + } else { + // + // First 2 arguments are passed through R2-R3 and copied to SysCall Stack. + // + CopyMem ((VOID *)(UINTN)Physical, (VOID *)&(Context.SystemContextArm->R1), 3 * sizeof (UINTN)); + + if (NumberOfArguments > 2) { + // + // All remaining arguments are on User Stack. + // + CopyMem ( + (VOID *)((UINTN)Physical + 3 * sizeof (UINTN)), + (VOID *)Context.SystemContextArm->SP, + (NumberOfArguments - 2) * sizeof (UINTN) + ); + } + } ForbidSupervisorAccessToUserMemory (); Status = CallBootService ( - Context.SystemContextArm->R0, + Type, + NumberOfArguments, (UINTN *)(UINTN)Physical, *(UINTN *)Context.SystemContextArm->SP_EL1 ); // // TODO: Fix memory leak for ReturnToCore(). // - CoreFreePages (Physical, EFI_SIZE_TO_PAGES (9 * sizeof (UINTN))); + CoreFreePages (Physical, EFI_SIZE_TO_PAGES ((NumberOfArguments + 1) * sizeof (UINTN))); ArmDisableInterrupts (); diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 184c3a7b62..640143ca27 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -279,7 +279,7 @@ STATIC UINTN * EFIAPI CopyUserArguments ( - IN UINTN NumberOfArguments, + IN UINT8 NumberOfArguments, IN UINTN *UserArguments ) { @@ -330,6 +330,7 @@ EFI_STATUS EFIAPI CallBootService ( IN UINT8 Type, + IN UINT8 NumberOfArguments, IN UINTN *UserArguments, IN UINTN ReturnSP ) @@ -367,13 +368,12 @@ CallBootService ( Argument5 = 0; Argument6 = 0; Interface = NULL; + Arguments = CopyUserArguments (NumberOfArguments, UserArguments); DEBUG ((DEBUG_VERBOSE, "Type: %a\n", SysCallNames[Type])); switch (Type) { case SysCallReturnToCore: - Arguments = CopyUserArguments (1, UserArguments); - ReturnToCore (Arguments[1], ReturnSP); break; case SysCallLocateProtocol: @@ -382,8 +382,6 @@ CallBootService ( // Argument 2: VOID *CoreRegistration // Argument 3: VOID **Interface // - Arguments = CopyUserArguments (3, UserArguments); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[1], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[1] + sizeof (EFI_GUID) - 1), &Attributes); @@ -428,8 +426,6 @@ CallBootService ( // Argument 5: EFI_HANDLE CoreControllerHandle // Argument 6: UINT32 Attributes // - Arguments = CopyUserArguments (6, UserArguments); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (EFI_GUID) - 1), &Attributes); @@ -476,8 +472,6 @@ CallBootService ( // Argument 1: EFI_HANDLE *Handle // ... // - Arguments = CopyUserArguments (2, UserArguments); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[1], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[1] + sizeof (EFI_HANDLE *) - 1), &Attributes); @@ -588,8 +582,6 @@ CallBootService ( // Argument 3: EFI_HANDLE CoreAgentHandle // Argument 4: EFI_HANDLE CoreControllerHandle // - Arguments = CopyUserArguments (4, UserArguments); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (EFI_GUID) - 1), &Attributes); @@ -619,8 +611,6 @@ CallBootService ( // Argument 2: EFI_GUID *Protocol // Argument 3: VOID **Interface // - Arguments = CopyUserArguments (3, UserArguments); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (EFI_GUID) - 1), &Attributes); @@ -663,8 +653,6 @@ CallBootService ( // Argument 3: UINTN NumberOfPages // Argument 4: EFI_PHYSICAL_ADDRESS *Memory // - Arguments = CopyUserArguments (4, UserArguments); - Status = gBS->AllocatePages ( (EFI_ALLOCATE_TYPE)Arguments[1], (EFI_MEMORY_TYPE)Arguments[2], @@ -689,8 +677,7 @@ CallBootService ( // Argument 1: UINTN NumberOfPages // Argument 2: EFI_PHYSICAL_ADDRESS Memory // - Arguments = CopyUserArguments (3, UserArguments); - PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[2]; + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[2]; gCpu->GetMemoryAttributes (gCpu, PhysAddr, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -706,8 +693,6 @@ CallBootService ( // // Argument 1: EFI_TPL NewTpl // - Arguments = CopyUserArguments (1, UserArguments); - Status = (EFI_STATUS)gBS->RaiseTPL ((EFI_TPL)Arguments[1]); FreePool (Arguments); @@ -717,8 +702,6 @@ CallBootService ( // // Argument 1: EFI_TPL NewTpl // - Arguments = CopyUserArguments (1, UserArguments); - gBS->RestoreTPL ((EFI_TPL)Arguments[1]); FreePool (Arguments); @@ -732,8 +715,6 @@ CallBootService ( // Argument 4: UINTN *NumberHandles // Argument 5: EFI_HANDLE **Buffer // - Arguments = CopyUserArguments (5, UserArguments); - if ((EFI_GUID *)Arguments[2] != NULL) { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); @@ -805,8 +786,6 @@ CallBootService ( // Argument 2: UINTN DataSize // Argument 3: UINT32 *Crc32 // - Arguments = CopyUserArguments (3, UserArguments); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[1], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[1] + Arguments[2] - 1), &Attributes); @@ -847,8 +826,6 @@ CallBootService ( // Argument 4: UINTN *DataSize // Argument 5: VOID *Data OPTIONAL // - Arguments = CopyUserArguments (5, UserArguments); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[1], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); @@ -938,8 +915,6 @@ CallBootService ( // Argument 1: EFI_BLOCK_IO_PROTOCOL *This // Argument 2: BOOLEAN ExtendedVerification // - Arguments = CopyUserArguments (2, UserArguments); - BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]); if (BlockIo == NULL) { @@ -963,16 +938,7 @@ CallBootService ( // Argument 4: VOID *Buffer // Argument 5: EFI_LBA Lba // -#if defined (MDE_CPU_ARM) - // - // EFI_LBA Lba is aligned on 8 bytes. - // - Arguments = CopyUserArguments (7, UserArguments); - PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[6]; -#else - Arguments = CopyUserArguments (6, UserArguments); - PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5]; -#endif + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5]; BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]); @@ -1017,16 +983,7 @@ CallBootService ( // Argument 4: VOID *Buffer // Argument 5: EFI_LBA Lba // -#if defined (MDE_CPU_ARM) - // - // EFI_LBA Lba is aligned on 8 bytes. - // - Arguments = CopyUserArguments (7, UserArguments); - PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[6]; -#else - Arguments = CopyUserArguments (6, UserArguments); - PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5]; -#endif + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5]; BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]); @@ -1067,8 +1024,6 @@ CallBootService ( // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This // - Arguments = CopyUserArguments (1, UserArguments); - BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]); if (BlockIo == NULL) { @@ -1089,16 +1044,7 @@ CallBootService ( // Argument 4: VOID *Buffer // Argument 5: UINT64 Offset // -#if defined (MDE_CPU_ARM) - // - // UINT64 Offset is aligned on 8 bytes. - // - Arguments = CopyUserArguments (7, UserArguments); - PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[6]; -#else - Arguments = CopyUserArguments (6, UserArguments); - PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5]; -#endif + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5]; DiskIo = FindInterface (FALSE, (VOID *)Arguments[1]); @@ -1143,16 +1089,7 @@ CallBootService ( // Argument 4: VOID *Buffer // Argument 5: UINT64 Offset // -#if defined (MDE_CPU_ARM) - // - // UINT64 Offset is aligned on 8 bytes. - // - Arguments = CopyUserArguments (7, UserArguments); - PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[6]; -#else - Arguments = CopyUserArguments (6, UserArguments); - PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5]; -#endif + PhysAddr = *(EFI_PHYSICAL_ADDRESS *)&Arguments[5]; DiskIo = FindInterface (FALSE, (VOID *)Arguments[1]); @@ -1195,8 +1132,6 @@ CallBootService ( // Argument 2: CHAR16 *Str1 // Argument 3: CHAR16 *Str2 // - Arguments = CopyUserArguments (3, UserArguments); - Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { @@ -1263,8 +1198,6 @@ CallBootService ( // Argument 2: CHAR16 *String // Argument 3: CHAR16 *Pattern // - Arguments = CopyUserArguments (3, UserArguments); - Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { @@ -1330,8 +1263,6 @@ CallBootService ( // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This // Argument 2: CHAR16 *Str // - Arguments = CopyUserArguments (2, UserArguments); - Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { @@ -1376,8 +1307,6 @@ CallBootService ( // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This // Argument 2: CHAR16 *Str // - Arguments = CopyUserArguments (2, UserArguments); - Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { @@ -1424,8 +1353,6 @@ CallBootService ( // Argument 3: CHAR8 *Fat // Argument 4: CHAR16 *String // - Arguments = CopyUserArguments (4, UserArguments); - Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { @@ -1494,8 +1421,6 @@ CallBootService ( // Argument 3: UINTN FatSize // Argument 4: CHAR8 *Fat // - Arguments = CopyUserArguments (4, UserArguments); - Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index 9478b93345..8662e53ae0 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -109,6 +109,7 @@ ASM_PFX(SysCallBase): ; ); ; ; (eax) User return address. +; (ebx) Number of User Arguments. ; (ecx) Type. ; (edx) User Stack Pointer. ; @@ -135,8 +136,9 @@ ASM_PFX(CoreBootServices): mov ebp, esp mov eax, [esp + 4*3] push eax ; ReturnSP - add edx, 4 ; User Arguments[] - push edx + add edx, 4*3 + push edx ; User Arguments[] + push ebx ; NumberOfArguments push ecx ; Type sti diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 2b48d77740..b9d3004163 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -117,13 +117,10 @@ ASM_PFX(SysCallBase): ; ); ; ; (rcx) RIP of the next instruction saved by SYSCALL in SysCall(). -; (rdx) Argument 1 of the called function. -; (r8) Argument 2 of the called function. -; (r9) Argument 3 of the called function. +; (rdx) Number of User Arguments. +; (r8) User Arguments[]. ; (r10) Type. ; (r11) RFLAGS saved by SYSCALL in SysCall(). -; -; (On User Stack) Argument 4, 5, ... ;------------------------------------------------------------------------------ global ASM_PFX(CoreBootServices) ASM_PFX(CoreBootServices): @@ -147,23 +144,14 @@ ASM_PFX(CoreBootServices): push rcx ; Save User RFLAGS for SYSRET. push r11 - ; Save User Arguments [1..3] on User stack. - call ASM_PFX(AllowSupervisorAccessToUserMemory) - mov rax, [rsp + 8*3] - mov [rax + 8*2], rdx - mov [rax + 8*3], r8 - mov [rax + 8*4], r9 - call ASM_PFX(ForbidSupervisorAccessToUserMemory) mov rbp, rsp ; Reserve space on stack for 4 CallBootService arguments (NOOPT prerequisite). sub rsp, 8*4 ; Prepare CallBootService arguments. mov rcx, r10 ; Type - mov rdx, [rbp + 8*3] - add rdx, 8 ; User Arguments[] mov rax, [ASM_PFX(SysCallStackTop)] - mov r8, [rax] ; ReturnSP + mov r9, [rax] ; ReturnSP sti call ASM_PFX(CallBootService) diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 26a7fbf235..dd87dd9f3f 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2036,7 +2036,7 @@ typedef enum { SysCallCloseProtocol, SysCallHandleProtocol, SysCallAllocatePages, - SysCallFreePages, + SysCallFreePages = 7, SysCallRaiseTpl, SysCallRestoreTpl, SysCallLocateHandleBuffer, @@ -2049,11 +2049,11 @@ typedef enum { // Protocols // SysCallBlockIoReset, - SysCallBlockIoRead, - SysCallBlockIoWrite, + SysCallBlockIoRead = 14, + SysCallBlockIoWrite = 15, SysCallBlockIoFlush, - SysCallDiskIoRead, - SysCallDiskIoWrite, + SysCallDiskIoRead = 17, + SysCallDiskIoWrite = 18, SysCallUnicodeStriColl, SysCallUnicodeMetaiMatch, SysCallUnicodeStrLwr, @@ -2064,6 +2064,11 @@ typedef enum { } SYS_CALL_TYPE; #define MAX_LIST 32 +#define SC_FREE_PAGES 7 +#define SC_BLOCK_IO_READ 14 +#define SC_BLOCK_IO_WRITE 15 +#define SC_DISK_IO_READ 17 +#define SC_DISK_IO_WRITE 18 /// /// Contains a set of GUID/pointer pairs comprised of the ConfigurationTable field in the From 757a7cd9f3ec57e74acff06fb1d4a5d46fb3cc42 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 21 Jan 2025 23:07:38 +0300 Subject: [PATCH 317/341] Ring3: Refactored out SysCallStackTop. --- MdeModulePkg/Core/Dxe/DxeMain.h | 4 -- .../Core/Dxe/DxeRing3/X64/SysCall.nasm | 6 +-- MdeModulePkg/Core/Dxe/Image/Image.c | 7 --- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 14 ++---- .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 7 +-- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 19 ++------ .../Core/Dxe/SysCall/ARM/InitializeARM.c | 7 +-- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 1 - .../Dxe/SysCall/IA32/CoreBootServices.nasm | 13 ++---- .../Core/Dxe/SysCall/IA32/InitializeIA32.c | 4 +- .../Core/Dxe/SysCall/Initialization.c | 44 ++++++++++++------- .../Core/Dxe/SysCall/SupportedProtocols.c | 8 +--- .../Dxe/SysCall/X64/CoreBootServices.nasm | 16 +++---- 13 files changed, 56 insertions(+), 94 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 245e7be677..d829dd27c4 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -231,7 +231,6 @@ typedef struct { VOID *HiiData; BOOLEAN IsUserImage; UINTN UserPageTable; - UINTN SysCallStackTop; UINTN UserStackTop; } LOADED_IMAGE_PRIVATE_DATA; @@ -240,7 +239,6 @@ typedef struct { VOID *UserSpaceDriver; UINTN UserPageTable; UINTN UserStackTop; - UINTN SysCallStackTop; LIST_ENTRY Link; } USER_SPACE_DRIVER; @@ -2792,8 +2790,6 @@ UINTN EFIAPI InitializeUserPageTable ( IN LOADED_IMAGE_PRIVATE_DATA *Image, - IN UINTN SysCallStackBase, - IN UINTN SysCallStackSize, IN UINTN UserStackBase, IN UINTN UserStackSize ); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm index 6d82942e48..3c826d7d8f 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm @@ -26,15 +26,13 @@ ASM_PFX(SysCall): jg continue push r9 push r8 - mov r8, rsp - sub r8, 8 + lea r8, [rsp - 8] add rsp, 8*2 jmp makecall continue: mov [rsp + 8*4], r9 mov [rsp + 8*3], r8 - mov r8, rsp - add r8, 8*2 + lea r8, [rsp + 8*2] makecall: ; SYSCALL saves RFLAGS into R11 and the RIP of the next instruction into RCX. syscall diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 19c168e9c4..5fe40520d0 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1132,7 +1132,6 @@ CoreLoadImageCommon ( UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UINT8 ImageOrigin; EFI_FV_FILE_ATTRIBUTES FileAttributes; - UINTN SysCallStackBase; UINTN UserStackBase; SecurityStatus = EFI_SUCCESS; @@ -1471,16 +1470,11 @@ CoreLoadImageCommon ( ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, Image->IsUserImage); if ((gRing3Data != NULL) && Image->IsUserImage) { - Image->SysCallStackTop = AllocateStack (STACK_SIZE, &SysCallStackBase); - SetUefiImageMemoryAttributes (SysCallStackBase, STACK_SIZE, EFI_MEMORY_XP); - Image->UserStackTop = AllocateStack (STACK_SIZE, &UserStackBase); SetUefiImageMemoryAttributes (UserStackBase, STACK_SIZE, EFI_MEMORY_XP | EFI_MEMORY_USER); Image->UserPageTable = InitializeUserPageTable ( Image, - SysCallStackBase, - STACK_SIZE, UserStackBase, STACK_SIZE ); @@ -1749,7 +1743,6 @@ CoreStartImage ( UserDriver->UserSpaceDriver = (VOID *)Image->EntryPoint; UserDriver->UserPageTable = Image->UserPageTable; UserDriver->UserStackTop = Image->UserStackTop; - UserDriver->SysCallStackTop = Image->SysCallStackTop; InsertTailList (&gUserSpaceDriversHead, &UserDriver->Link); diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index e5ea1c96a0..0ce4ef3120 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -61,15 +61,13 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) // EFIAPI // CallRing3 ( // IN RING3_CALL_DATA *Data, -// IN UINTN UserStackTop, -// IN UINTN SysCallStackTop +// IN UINTN UserStackTop // ); // // (x0) Data // (x1) UserStackTop // (x2) gRing3EntryPoint -// (x3) SysCallStackTop -// (x4) gUserPageTable +// (x3) gUserPageTable //------------------------------------------------------------------------------ ASM_FUNC(ArmCallRing3) // Save registers. @@ -92,10 +90,6 @@ ASM_FUNC(ArmCallRing3) // Disable interrupts. msr daifset, #0xf isb - // Switch to SysCallStackTop and save ReturnSP on it. - mov x6, sp - mov sp, x3 - stp x6, xzr, [sp, #-0x10]! // Copy PSTATE to SPSR. mrs x6, nzcv mrs x7, pan @@ -105,12 +99,12 @@ ASM_FUNC(ArmCallRing3) EL1_OR_EL2(x1) 1:msr elr_el1, x2 msr spsr_el1, x6 - msr ttbr0_el1, x4 + msr ttbr0_el1, x3 tlbi vmalle1 b 3f 2:msr elr_el2, x2 msr spsr_el2, x6 - msr ttbr0_el2, x4 + msr ttbr0_el2, x3 tlbi alle2 3:dsb sy isb diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index eef01bd07d..f02ab5bbb3 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -20,7 +20,6 @@ ArmCallRing3 ( IN RING3_CALL_DATA *Data, IN UINTN UserStackTop, IN VOID *EntryPoint, - IN UINTN SysCallStackTop, IN UINTN UserPageTable ); @@ -54,7 +53,7 @@ SysCallBootService ( Context.SystemContextAArch64->X0, Context.SystemContextAArch64->X1, (UINTN *)Physical, - *(UINTN *)Context.SystemContextAArch64->SP + Context.SystemContextAArch64->SP ); CoreFreePages (Physical, EFI_SIZE_TO_PAGES (7 * sizeof (UINTN))); @@ -149,15 +148,13 @@ EFI_STATUS EFIAPI CallRing3 ( IN RING3_CALL_DATA *Data, - IN UINTN UserStackTop, - IN UINTN SysCallStackTop + IN UINTN UserStackTop ) { return ArmCallRing3 ( Data, UserStackTop, gRing3EntryPoint, - SysCallStackTop, gUserPageTable ); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index d34b6a8a07..d7741277a0 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -57,22 +57,17 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) // EFIAPI // CallRing3 ( // IN RING3_CALL_DATA *Data, -// IN UINTN UserStackTop, -// IN UINTN SysCallStackTop +// IN UINTN UserStackTop // ); // // (r0) Data // (r1) UserStackTop // (r2) gRing3EntryPoint -// (r3) SysCallStackTop -// -// (On Core Stack) gUserPageTable +// (r3) gUserPageTable //------------------------------------------------------------------------------ ASM_FUNC(ArmCallRing3) // Save registers. push {R4-R12, LR} - // R7 is gUserPageTable - ldr R7, [SP, #0x28] // Save old SP_usr and LR_usr on Core Stack. sub SP, SP, #0x8 stmia SP, {SP, LR}^ @@ -95,17 +90,11 @@ ASM_FUNC(ArmCallRing3) // Set SPSR M[3:0] bits to User mode. and R4, R4, #0xFFFFFFF0 - // Switch to SysCallStackTop and save ReturnSP on it. - mov R5, SP - mov SP, R3 - push {R5} - push {R5} // Align stack on 8 bytes - // Switch to UserPageTable. mrc p15,0,R8,c2,c0,0 // R8 == TTBR0 and R8, R8, #0x7F // Preserve Core TTBR0 attributes. - orr R7, R7, R8 // Assign Core attributes to UserPageTable. - mcr p15,0,R7,c2,c0,0 // TTBR0 == UserPageTable + orr R3, R3, R8 // Assign Core attributes to UserPageTable. + mcr p15,0,R3,c2,c0,0 // TTBR0 == UserPageTable mcr p15,0,r0,c8,c7,0 // TLBIALL, TLB Invalidate All. mcr p15,0,r0,c7,c5,6 // BPIALL, Branch Predictor Invalidate All. dsb diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 2ede13fe8c..55af5fe8cb 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -19,7 +19,6 @@ ArmCallRing3 ( IN RING3_CALL_DATA *Data, IN UINTN UserStackTop, IN VOID *EntryPoint, - IN UINTN SysCallStackTop, IN UINTN UserPageTable ); @@ -94,7 +93,7 @@ SysCallBootService ( Type, NumberOfArguments, (UINTN *)(UINTN)Physical, - *(UINTN *)Context.SystemContextArm->SP_EL1 + Context.SystemContextArm->SP_EL1 ); // // TODO: Fix memory leak for ReturnToCore(). @@ -178,15 +177,13 @@ EFI_STATUS EFIAPI CallRing3 ( IN RING3_CALL_DATA *Data, - IN UINTN UserStackTop, - IN UINTN SysCallStackTop + IN UINTN UserStackTop ) { return ArmCallRing3 ( Data, UserStackTop, gRing3EntryPoint, - SysCallStackTop, gUserPageTable ); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 640143ca27..eff25a470f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -523,7 +523,6 @@ CallBootService ( NewDriver->UserSpaceDriver = UserArgList[Index + 1]; NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserStackTop = UserDriver->UserStackTop; - NewDriver->SysCallStackTop = UserDriver->SysCallStackTop; InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index 8662e53ae0..0590418c4a 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -134,7 +134,7 @@ ASM_PFX(CoreBootServices): ; Prepare CallBootService arguments. mov ebp, esp - mov eax, [esp + 4*3] + lea eax, [esp + 4*3] push eax ; ReturnSP add edx, 4*3 push edx ; User Arguments[] @@ -169,11 +169,10 @@ ASM_PFX(CoreBootServices): ; EFIAPI ; CallRing3 ( ; IN RING3_CALL_DATA *Data, -; IN UINTN UserStackTop, -; IN UINTN SysCallStackTop +; IN UINTN UserStackTop ; ); ; -; (On User Stack) Data, UserStackTop, SysCallStackTop +; (On User Stack) Data, UserStackTop ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): @@ -191,14 +190,10 @@ ASM_PFX(CallRing3): ; Set new SysCallStackTop. mov edx, 0 - mov eax, [esp + 4 * 8] ; SysCallStackTop - sub eax, 4 + mov eax, esp mov ecx, MSR_IA32_SYSENTER_ESP wrmsr - ; Save ReturnSP on SysCallStack. - mov [eax], esp - SetRing3DataSegmentSelectors ; Prepare SYSEXIT arguments. diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c index 84714cdf34..e3c2ab6f68 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c @@ -144,8 +144,8 @@ InitializeMsr ( } // - // Initialize MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_EIP and - // MSR_IA32_SYSENTER_ESP for SYSENTER and SYSEXIT. + // Initialize MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_EIP for SYSENTER and SYSEXIT. + // MSR_IA32_SYSENTER_ESP is set in CallRing3(). // Msr = RING0_CODE32_SEL; AsmWriteMsr64 (MSR_IA32_SYSENTER_CS, Msr); diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 410cf40788..a6e23206e7 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -14,10 +14,12 @@ RING3_DATA *gRing3Data; VOID *gRing3Interfaces; UINTN gUartBaseAddress; -UEFI_IMAGE_RECORD *mDxeRing3; -EXCEPTION_ADDRESSES *mExceptionAddresses; -UINTN mConfigurationTable; -UINTN mConfigurationTableSize; +UEFI_IMAGE_RECORD *mDxeRing3; +EXCEPTION_ADDRESSES *mExceptionAddresses; +UINTN mConfigurationTable; +UINTN mConfigurationTableSize; +EFI_PHYSICAL_ADDRESS mCoreStackBase; +UINT64 mCoreStackSize; extern UINTN SysCallBase; extern UINTN SysCallEnd; @@ -43,12 +45,14 @@ InitializeRing3 ( IN LOADED_IMAGE_PRIVATE_DATA *Image ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Physical; - UINTN Index; - EFI_CONFIGURATION_TABLE *Conf; - EARLY_PL011_BASE_ADDRESS *UartBase; - CONST VOID *Hob; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Physical; + UINTN Index; + EFI_CONFIGURATION_TABLE *Conf; + EARLY_PL011_BASE_ADDRESS *UartBase; + CONST VOID *Hob; + EFI_PEI_HOB_POINTERS PeiHob; + EFI_HOB_MEMORY_ALLOCATION *MemoryHob; // // Set Ring3 EntryPoint and BootServices. @@ -158,6 +162,18 @@ InitializeRing3 ( mExceptionAddresses = GetExceptionAddresses (); + PeiHob.Raw = GetHobList (); + while ((PeiHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, PeiHob.Raw)) != NULL) { + MemoryHob = PeiHob.MemoryAllocation; + if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &MemoryHob->AllocDescriptor.Name)) { + mCoreStackBase = MemoryHob->AllocDescriptor.MemoryBaseAddress; + mCoreStackSize = MemoryHob->AllocDescriptor.MemoryLength; + break; + } + + PeiHob.Raw = GET_NEXT_HOB (PeiHob); + } + return Status; } @@ -165,8 +181,6 @@ UINTN EFIAPI InitializeUserPageTable ( IN LOADED_IMAGE_PRIVATE_DATA *Image, - IN UINTN SysCallStackBase, - IN UINTN SysCallStackSize, IN UINTN UserStackBase, IN UINTN UserStackSize ) @@ -226,7 +240,7 @@ InitializeUserPageTable ( } // - // Map CoreBootServices, SysCallStackBase + // Map CoreBootServices, CoreStackBase // gCpu->SetUserMemoryAttributes ( gCpu, @@ -239,8 +253,8 @@ InitializeUserPageTable ( gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, - SysCallStackBase, - SysCallStackSize, + mCoreStackBase, + mCoreStackSize, EFI_MEMORY_XP ); diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 530f69238f..f388755f0e 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -14,8 +14,7 @@ EFI_STATUS EFIAPI CallRing3 ( IN RING3_CALL_DATA *Data, - IN UINTN UserStackTop, - IN UINTN SysCallStackTop + IN UINTN UserStackTop ); EFI_STATUS @@ -64,8 +63,7 @@ GoToRing3 ( // Status = CallRing3 ( Input, - UserDriver->UserStackTop, - UserDriver->SysCallStackTop + UserDriver->UserStackTop ); CoreFreePages (Ring3Pages, PagesNumber); @@ -755,7 +753,6 @@ CoreFileOpen ( NewDriver->CoreWrapper = NewFile; NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserStackTop = UserDriver->UserStackTop; - NewDriver->SysCallStackTop = UserDriver->SysCallStackTop; AllowSupervisorAccessToUserMemory (); NewDriver->UserSpaceDriver = *Ring3NewHandle; @@ -857,7 +854,6 @@ CoreOpenVolume ( NewDriver->CoreWrapper = File; NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserStackTop = UserDriver->UserStackTop; - NewDriver->SysCallStackTop = UserDriver->SysCallStackTop; AllowSupervisorAccessToUserMemory (); NewDriver->UserSpaceDriver = *Ring3Root; diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index b9d3004163..3c70630591 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -149,9 +149,8 @@ ASM_PFX(CoreBootServices): sub rsp, 8*4 ; Prepare CallBootService arguments. - mov rcx, r10 ; Type - mov rax, [ASM_PFX(SysCallStackTop)] - mov r9, [rax] ; ReturnSP + mov rcx, r10 ; Type + mov r9, [ASM_PFX(SysCallStackTop)] ; ReturnSP sti call ASM_PFX(CallBootService) @@ -184,13 +183,11 @@ o64 sysret ; EFIAPI ; CallRing3 ( ; IN RING3_CALL_DATA *Data, -; IN UINTN UserStackTop, -; IN UINTN SysCallStackTop +; IN UINTN UserStackTop ; ); ; ; (rcx) Data ; (rdx) UserStackTop -; (r8) SysCallStackTop ;------------------------------------------------------------------------------ global ASM_PFX(CallRing3) ASM_PFX(CallRing3): @@ -206,15 +203,12 @@ ASM_PFX(CallRing3): push r13 push r14 push r15 + ; Save old SysCallStackTop, set the new one. push qword [ASM_PFX(SysCallStackTop)] - - ; Save ReturnSP on SysCallStack. - sub r8, 8 - mov [r8], rsp + mov [ASM_PFX(SysCallStackTop)], rsp ; Save input Arguments. mov rbx, rdx - mov [ASM_PFX(SysCallStackTop)], r8 mov r10, rcx SetRing3DataSegmentSelectors From dd9ee30f2be8ecf757db24090a94d5936c1a69d8 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 23 Jan 2025 15:02:23 +0300 Subject: [PATCH 318/341] SysCall: Added FreeUserSpaceDriver(). --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index eff25a470f..3483b07997 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -326,6 +326,27 @@ FindUserInfo ( return NULL; } +STATIC +VOID +EFIAPI +FreeUserSpaceDriver ( + IN VOID *CoreWrapper + ) +{ + LIST_ENTRY *Link; + USER_SPACE_DRIVER *UserDriver; + + for (Link = gUserSpaceDriversHead.ForwardLink; Link != &gUserSpaceDriversHead; Link = Link->ForwardLink) { + UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link); + + if (UserDriver->CoreWrapper == CoreWrapper) { + break; + } + } + + RemoveEntryList (&UserDriver->Link); +} + EFI_STATUS EFIAPI CallBootService ( @@ -498,6 +519,7 @@ CallBootService ( ForbidSupervisorAccessToUserMemory (); while (Index > 0) { + FreeUserSpaceDriver (CoreArgList[Index - 1]); FreePool (CoreArgList[Index - 1]); Index -= 2; } From 3ce2c6bc158aa9e2a33787fa161829a625c0d9a7 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 23 Jan 2025 15:59:36 +0300 Subject: [PATCH 319/341] SysCall: Fixed paddings, renamed CoreOpenVolume as CoreSimpleFileSystemOpenVolume. --- MdeModulePkg/Core/Dxe/DxeMain.h | 2 +- .../Core/Dxe/DxeRing3/AARCH64/SysCall.S | 2 +- MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S | 2 +- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 4 +- .../Core/Dxe/DxeRing3/IA32/SysCall.nasm | 2 +- MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h | 278 +++++++++--------- .../Core/Dxe/DxeRing3/Ring3Protocols.c | 44 +-- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 136 ++++----- .../Dxe/DxeRing3/Ring3UefiRuntimeServices.c | 86 +++--- .../Core/Dxe/DxeRing3/X64/SysCall.nasm | 2 +- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 6 +- .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 14 +- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 6 +- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 16 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 10 +- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 8 +- .../Core/Dxe/SysCall/IA32/InitializeIA32.c | 4 +- .../Core/Dxe/SysCall/SupportedProtocols.c | 122 ++++---- .../Core/Dxe/SysCall/SupportedProtocols.h | 50 ++-- .../Dxe/SysCall/X64/CoreBootServices.nasm | 8 +- .../Core/Dxe/SysCall/X64/InitializeX64.c | 4 +- 21 files changed, 403 insertions(+), 403 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index d829dd27c4..88b3d1a5fd 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2739,7 +2739,7 @@ SetUefiImageProtectionAttributes ( EFI_STATUS EFIAPI CoreBootServices ( - IN UINT8 Type, + IN UINT8 Type, ... ); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S index 4a63ec87e1..47039d2940 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S @@ -24,7 +24,7 @@ ASM_FUNC(SysCall) // VOID // EFIAPI // Ring3EntryPoint ( -// IN RING3_CALL_DATA *Data +// IN RING3_CALL_DATA *Data // ); // // (x0) Data diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S index 2a0a28e32f..dee789fce5 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S @@ -24,7 +24,7 @@ ASM_FUNC(SysCall) // VOID // EFIAPI // Ring3EntryPoint ( -// IN RING3_CALL_DATA *Data +// IN RING3_CALL_DATA *Data // ); // // (r0) Data diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index b024fb5aac..0090023f88 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -94,7 +94,7 @@ EFI_RUNTIME_SERVICES mRuntimeServices = { VOID EFIAPI Ring3EntryPoint ( - IN RING3_CALL_DATA *Data + IN RING3_CALL_DATA *Data ); typedef @@ -182,7 +182,7 @@ EFI_STATUS VOID EFIAPI Ring3Call ( - IN RING3_CALL_DATA *Data + IN RING3_CALL_DATA *Data ) { EFI_STATUS Status; diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm index 7b6ff6d1c4..7c12e57736 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm @@ -50,7 +50,7 @@ userReturnAddress: ; VOID ; EFIAPI ; Ring3EntryPoint ( -; IN RING3_CALL_DATA *Data +; IN RING3_CALL_DATA *Data ; ); ; ; (eax) Data diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h index 44c1938344..20d6fa15c3 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h @@ -68,9 +68,9 @@ Ring3RestoreTpl ( EFI_STATUS EFIAPI Ring3AllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, IN OUT EFI_PHYSICAL_ADDRESS *Memory ); @@ -127,9 +127,9 @@ EFIAPI Ring3GetMemoryMap ( IN OUT UINTN *MemoryMapSize, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion ); /** @@ -153,11 +153,11 @@ Ring3GetMemoryMap ( EFI_STATUS EFIAPI Ring3CreateEvent ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, - IN VOID *NotifyContext OPTIONAL, - OUT EFI_EVENT *Event + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN VOID *NotifyContext OPTIONAL, + OUT EFI_EVENT *Event ); /** @@ -200,9 +200,9 @@ Ring3SetTimer ( EFI_STATUS EFIAPI Ring3WaitForEvent ( - IN UINTN NumberOfEvents, - IN EFI_EVENT *UserEvents, - OUT UINTN *UserIndex + IN UINTN NumberOfEvents, + IN EFI_EVENT *UserEvents, + OUT UINTN *UserIndex ); /** @@ -268,10 +268,10 @@ Ring3CheckEvent ( EFI_STATUS EFIAPI Ring3InstallProtocolInterface ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface + IN OUT EFI_HANDLE *UserHandle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface ); /** @@ -332,9 +332,9 @@ Ring3UninstallProtocolInterface ( EFI_STATUS EFIAPI Ring3HandleProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface ); /** @@ -353,9 +353,9 @@ Ring3HandleProtocol ( EFI_STATUS EFIAPI Ring3RegisterProtocolNotify ( - IN EFI_GUID *Protocol, - IN EFI_EVENT Event, - OUT VOID **Registration + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration ); /** @@ -379,11 +379,11 @@ Ring3RegisterProtocolNotify ( EFI_STATUS EFIAPI Ring3LocateHandle ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *BufferSize, - OUT EFI_HANDLE *Buffer + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer ); /** @@ -404,9 +404,9 @@ Ring3LocateHandle ( EFI_STATUS EFIAPI Ring3LocateDevicePath ( - IN EFI_GUID *Protocol, + IN EFI_GUID *Protocol, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, - OUT EFI_HANDLE *Device + OUT EFI_HANDLE *Device ); /** @@ -468,12 +468,12 @@ Ring3InstallConfigurationTable ( EFI_STATUS EFIAPI Ring3LoadImage ( - IN BOOLEAN BootPolicy, - IN EFI_HANDLE ParentImageHandle, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN VOID *SourceBuffer OPTIONAL, - IN UINTN SourceSize, - OUT EFI_HANDLE *ImageHandle + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle ); /** @@ -498,9 +498,9 @@ Ring3LoadImage ( EFI_STATUS EFIAPI Ring3StartImage ( - IN EFI_HANDLE ImageHandle, - OUT UINTN *ExitDataSize, - OUT CHAR16 **ExitData OPTIONAL + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL ); /** @@ -662,10 +662,10 @@ Ring3SetWatchdogTimer ( EFI_STATUS EFIAPI Ring3ConnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE *DriverImageHandle OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, - IN BOOLEAN Recursive + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE *DriverImageHandle OPTIONAL, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, + IN BOOLEAN Recursive ); /** @@ -703,9 +703,9 @@ Ring3ConnectController ( EFI_STATUS EFIAPI Ring3DisconnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE DriverImageHandle OPTIONAL, - IN EFI_HANDLE ChildHandle OPTIONAL + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverImageHandle OPTIONAL, + IN EFI_HANDLE ChildHandle OPTIONAL ); /** @@ -767,10 +767,10 @@ Ring3OpenProtocol ( EFI_STATUS EFIAPI Ring3CloseProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN EFI_HANDLE AgentHandle, - IN EFI_HANDLE ControllerHandle + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN EFI_HANDLE AgentHandle, + IN EFI_HANDLE ControllerHandle ); /** @@ -819,9 +819,9 @@ Ring3OpenProtocolInformation ( EFI_STATUS EFIAPI Ring3ProtocolsPerHandle ( - IN EFI_HANDLE UserHandle, - OUT EFI_GUID ***ProtocolBuffer, - OUT UINTN *ProtocolBufferCount + IN EFI_HANDLE UserHandle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount ); /** @@ -849,11 +849,11 @@ Ring3ProtocolsPerHandle ( EFI_STATUS EFIAPI Ring3LocateHandleBuffer ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *NumberHandles, - OUT EFI_HANDLE **Buffer + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer ); /** @@ -947,9 +947,9 @@ Ring3UninstallMultipleProtocolInterfaces ( EFI_STATUS EFIAPI Ring3CalculateCrc32 ( - IN VOID *Data, - IN UINTN DataSize, - OUT UINT32 *Crc32 + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 ); /** @@ -975,12 +975,12 @@ Ring3CalculateCrc32 ( EFI_STATUS EFIAPI Ring3CreateEventEx ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, - IN CONST VOID *NotifyContext OPTIONAL, - IN CONST EFI_GUID *EventGroup OPTIONAL, - OUT EFI_EVENT *Event + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN CONST VOID *NotifyContext OPTIONAL, + IN CONST EFI_GUID *EventGroup OPTIONAL, + OUT EFI_EVENT *Event ); /** @@ -1023,11 +1023,11 @@ Ring3BlockIoReset ( EFI_STATUS EFIAPI Ring3BlockIoRead ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer ); /** @@ -1096,11 +1096,11 @@ Ring3BlockIoFlush ( EFI_STATUS EFIAPI Ring3DiskIoRead ( - IN EFI_DISK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Offset, - IN UINTN BufferSize, - OUT VOID *Buffer + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + OUT VOID *Buffer ); /** @@ -1147,8 +1147,8 @@ Ring3DiskIoWrite ( EFI_STATUS EFIAPI Ring3GetTime ( - OUT EFI_TIME *Time, - OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL ); /** @@ -1164,7 +1164,7 @@ Ring3GetTime ( EFI_STATUS EFIAPI Ring3SetTime ( - IN EFI_TIME *Time + IN EFI_TIME *Time ); /** @@ -1185,9 +1185,9 @@ Ring3SetTime ( EFI_STATUS EFIAPI Ring3GetWakeupTime ( - OUT BOOLEAN *Enabled, - OUT BOOLEAN *Pending, - OUT EFI_TIME *Time + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time ); /** @@ -1207,8 +1207,8 @@ Ring3GetWakeupTime ( EFI_STATUS EFIAPI Ring3SetWakeupTime ( - IN BOOLEAN Enable, - IN EFI_TIME *Time OPTIONAL + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL ); /** @@ -1233,10 +1233,10 @@ Ring3SetWakeupTime ( EFI_STATUS EFIAPI Ring3SetVirtualAddressMap ( - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN UINT32 DescriptorVersion, - IN EFI_MEMORY_DESCRIPTOR *VirtualMap + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap ); /** @@ -1257,8 +1257,8 @@ Ring3SetVirtualAddressMap ( EFI_STATUS EFIAPI Ring3ConvertPointer ( - IN UINTN DebugDisposition, - IN OUT VOID **Address + IN UINTN DebugDisposition, + IN OUT VOID **Address ); /** @@ -1288,11 +1288,11 @@ Ring3ConvertPointer ( EFI_STATUS EFIAPI Ring3GetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - OUT UINT32 *Attributes OPTIONAL, - IN OUT UINTN *DataSize, - OUT VOID *Data OPTIONAL + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data OPTIONAL ); /** @@ -1324,9 +1324,9 @@ Ring3GetVariable ( EFI_STATUS EFIAPI Ring3GetNextVariableName ( - IN OUT UINTN *VariableNameSize, - IN OUT CHAR16 *VariableName, - IN OUT EFI_GUID *VendorGuid + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid ); /** @@ -1366,11 +1366,11 @@ Ring3GetNextVariableName ( EFI_STATUS EFIAPI Ring3SetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - IN UINT32 Attributes, - IN UINTN DataSize, - IN VOID *Data + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data ); /** @@ -1386,7 +1386,7 @@ Ring3SetVariable ( EFI_STATUS EFIAPI Ring3GetNextHighMonotonicCount ( - OUT UINT32 *HighCount + OUT UINT32 *HighCount ); /** @@ -1407,10 +1407,10 @@ Ring3GetNextHighMonotonicCount ( VOID EFIAPI Ring3ResetSystem ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL ); /** @@ -1446,9 +1446,9 @@ Ring3ResetSystem ( EFI_STATUS EFIAPI Ring3UpdateCapsule ( - IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, - IN UINTN CapsuleCount, - IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL ); /** @@ -1477,10 +1477,10 @@ Ring3UpdateCapsule ( EFI_STATUS EFIAPI Ring3QueryCapsuleCapabilities ( - IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, - IN UINTN CapsuleCount, - OUT UINT64 *MaximumCapsuleSize, - OUT EFI_RESET_TYPE *ResetType + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + OUT UINT64 *MaximumCapsuleSize, + OUT EFI_RESET_TYPE *ResetType ); /** @@ -1508,10 +1508,10 @@ Ring3QueryCapsuleCapabilities ( EFI_STATUS EFIAPI Ring3QueryVariableInfo ( - IN UINT32 Attributes, - OUT UINT64 *MaximumVariableStorageSize, - OUT UINT64 *RemainingVariableStorageSize, - OUT UINT64 *MaximumVariableSize + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize ); /** @@ -1529,9 +1529,9 @@ Ring3QueryVariableInfo ( INTN EFIAPI Ring3UnicodeStriColl ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *Str1, - IN CHAR16 *Str2 + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *Str1, + IN CHAR16 *Str2 ); /** @@ -1549,9 +1549,9 @@ Ring3UnicodeStriColl ( BOOLEAN EFIAPI Ring3UnicodeMetaiMatch ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN CHAR16 *Pattern + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN CHAR16 *Pattern ); /** @@ -1565,8 +1565,8 @@ Ring3UnicodeMetaiMatch ( VOID EFIAPI Ring3UnicodeStrLwr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str ); /** @@ -1580,8 +1580,8 @@ Ring3UnicodeStrLwr ( VOID EFIAPI Ring3UnicodeStrUpr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str ); /** @@ -1599,10 +1599,10 @@ Ring3UnicodeStrUpr ( VOID EFIAPI Ring3UnicodeFatToStr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN UINTN FatSize, - IN CHAR8 *Fat, - OUT CHAR16 *String + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String ); /** @@ -1622,8 +1622,8 @@ Ring3UnicodeFatToStr ( BOOLEAN EFIAPI Ring3UnicodeStrToFat ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN UINTN FatSize, - OUT CHAR8 *Fat + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat ); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c index 7b7efeb12f..4c4c058df3 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c @@ -25,11 +25,11 @@ Ring3BlockIoReset ( EFI_STATUS EFIAPI Ring3BlockIoRead ( - IN EFI_BLOCK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN EFI_LBA Lba, - IN UINTN BufferSize, - OUT VOID *Buffer + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer ) { return SysCall ( @@ -80,11 +80,11 @@ Ring3BlockIoFlush ( EFI_STATUS EFIAPI Ring3DiskIoRead ( - IN EFI_DISK_IO_PROTOCOL *This, - IN UINT32 MediaId, - IN UINT64 Offset, - IN UINTN BufferSize, - OUT VOID *Buffer + IN EFI_DISK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN UINT64 Offset, + IN UINTN BufferSize, + OUT VOID *Buffer ) { return SysCall ( @@ -156,8 +156,8 @@ Ring3UnicodeMetaiMatch ( VOID EFIAPI Ring3UnicodeStrLwr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str ) { SysCall ( @@ -171,8 +171,8 @@ Ring3UnicodeStrLwr ( VOID EFIAPI Ring3UnicodeStrUpr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str ) { SysCall ( @@ -186,10 +186,10 @@ Ring3UnicodeStrUpr ( VOID EFIAPI Ring3UnicodeFatToStr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN UINTN FatSize, - IN CHAR8 *Fat, - OUT CHAR16 *String + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String ) { SysCall ( @@ -205,10 +205,10 @@ Ring3UnicodeFatToStr ( BOOLEAN EFIAPI Ring3UnicodeStrToFat ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN UINTN FatSize, - OUT CHAR8 *Fat + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat ) { return (BOOLEAN)SysCall ( diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 04ccc7b669..bae3b0036b 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -119,9 +119,9 @@ Ring3RestoreTpl ( EFI_STATUS EFIAPI Ring3AllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, IN OUT EFI_PHYSICAL_ADDRESS *Memory ) { @@ -169,9 +169,9 @@ EFIAPI Ring3GetMemoryMap ( IN OUT UINTN *MemoryMapSize, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion ) { DEBUG ((DEBUG_ERROR, "Ring3: GetMemoryMap is not supported\n")); @@ -182,11 +182,11 @@ Ring3GetMemoryMap ( EFI_STATUS EFIAPI Ring3CreateEvent ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, - IN VOID *NotifyContext OPTIONAL, - OUT EFI_EVENT *Event + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN VOID *NotifyContext OPTIONAL, + OUT EFI_EVENT *Event ) { DEBUG ((DEBUG_ERROR, "Ring3: CreateEvent is not supported\n")); @@ -210,9 +210,9 @@ Ring3SetTimer ( EFI_STATUS EFIAPI Ring3WaitForEvent ( - IN UINTN NumberOfEvents, - IN EFI_EVENT *UserEvents, - OUT UINTN *UserIndex + IN UINTN NumberOfEvents, + IN EFI_EVENT *UserEvents, + OUT UINTN *UserIndex ) { DEBUG ((DEBUG_ERROR, "Ring3: WaitForEvent is not supported\n")); @@ -256,10 +256,10 @@ Ring3CheckEvent ( EFI_STATUS EFIAPI Ring3InstallProtocolInterface ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface + IN OUT EFI_HANDLE *UserHandle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface ) { DEBUG ((DEBUG_ERROR, "Ring3: InstallProtocolInterface is not supported\n")); @@ -297,9 +297,9 @@ Ring3UninstallProtocolInterface ( EFI_STATUS EFIAPI Ring3HandleProtocol ( - IN EFI_HANDLE CoreUserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface + IN EFI_HANDLE CoreUserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface ) { EFI_STATUS Status; @@ -322,9 +322,9 @@ Ring3HandleProtocol ( EFI_STATUS EFIAPI Ring3RegisterProtocolNotify ( - IN EFI_GUID *Protocol, - IN EFI_EVENT Event, - OUT VOID **Registration + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration ) { DEBUG ((DEBUG_ERROR, "Ring3: RegisterProtocolNotify is not supported\n")); @@ -335,11 +335,11 @@ Ring3RegisterProtocolNotify ( EFI_STATUS EFIAPI Ring3LocateHandle ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *BufferSize, - OUT EFI_HANDLE *Buffer + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer ) { DEBUG ((DEBUG_ERROR, "Ring3: LocateHandle is not supported\n")); @@ -350,9 +350,9 @@ Ring3LocateHandle ( EFI_STATUS EFIAPI Ring3LocateDevicePath ( - IN EFI_GUID *Protocol, + IN EFI_GUID *Protocol, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, - OUT EFI_HANDLE *Device + OUT EFI_HANDLE *Device ) { DEBUG ((DEBUG_ERROR, "Ring3: LocateDevicePath is not supported\n")); @@ -375,12 +375,12 @@ Ring3InstallConfigurationTable ( EFI_STATUS EFIAPI Ring3LoadImage ( - IN BOOLEAN BootPolicy, - IN EFI_HANDLE ParentImageHandle, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN VOID *SourceBuffer OPTIONAL, - IN UINTN SourceSize, - OUT EFI_HANDLE *ImageHandle + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle ) { DEBUG ((DEBUG_ERROR, "Ring3: LoadImage is not supported\n")); @@ -391,9 +391,9 @@ Ring3LoadImage ( EFI_STATUS EFIAPI Ring3StartImage ( - IN EFI_HANDLE ImageHandle, - OUT UINTN *ExitDataSize, - OUT CHAR16 **ExitData OPTIONAL + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL ) { DEBUG ((DEBUG_ERROR, "Ring3: StartImage is not supported\n")); @@ -477,10 +477,10 @@ Ring3SetWatchdogTimer ( EFI_STATUS EFIAPI Ring3ConnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE *DriverImageHandle OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, - IN BOOLEAN Recursive + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE *DriverImageHandle OPTIONAL, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, + IN BOOLEAN Recursive ) { DEBUG ((DEBUG_ERROR, "Ring3: ConnectController is not supported\n")); @@ -491,9 +491,9 @@ Ring3ConnectController ( EFI_STATUS EFIAPI Ring3DisconnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE DriverImageHandle OPTIONAL, - IN EFI_HANDLE ChildHandle OPTIONAL + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverImageHandle OPTIONAL, + IN EFI_HANDLE ChildHandle OPTIONAL ) { DEBUG ((DEBUG_ERROR, "Ring3: DisconnectController is not supported\n")); @@ -534,10 +534,10 @@ Ring3OpenProtocol ( EFI_STATUS EFIAPI Ring3CloseProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN EFI_HANDLE AgentHandle, - IN EFI_HANDLE ControllerHandle + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN EFI_HANDLE AgentHandle, + IN EFI_HANDLE ControllerHandle ) { return SysCall ( @@ -567,9 +567,9 @@ Ring3OpenProtocolInformation ( EFI_STATUS EFIAPI Ring3ProtocolsPerHandle ( - IN EFI_HANDLE UserHandle, - OUT EFI_GUID ***ProtocolBuffer, - OUT UINTN *ProtocolBufferCount + IN EFI_HANDLE UserHandle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount ) { DEBUG ((DEBUG_ERROR, "Ring3: ProtocolsPerHandle is not supported\n")); @@ -580,11 +580,11 @@ Ring3ProtocolsPerHandle ( EFI_STATUS EFIAPI Ring3LocateHandleBuffer ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *NumberHandles, - OUT EFI_HANDLE **Buffer + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer ) { EFI_STATUS Status; @@ -703,9 +703,9 @@ Ring3UninstallMultipleProtocolInterfaces ( EFI_STATUS EFIAPI Ring3CalculateCrc32 ( - IN VOID *Data, - IN UINTN DataSize, - OUT UINT32 *Crc32 + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 ) { return SysCall ( @@ -720,12 +720,12 @@ Ring3CalculateCrc32 ( EFI_STATUS EFIAPI Ring3CreateEventEx ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, - IN CONST VOID *NotifyContext OPTIONAL, - IN CONST EFI_GUID *EventGroup OPTIONAL, - OUT EFI_EVENT *Event + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, + IN CONST VOID *NotifyContext OPTIONAL, + IN CONST EFI_GUID *EventGroup OPTIONAL, + OUT EFI_EVENT *Event ) { DEBUG ((DEBUG_ERROR, "Ring3: CreateEventEx is not supported\n")); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c index ed888b9b37..e3e787a536 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c @@ -8,8 +8,8 @@ EFI_STATUS EFIAPI Ring3GetTime ( - OUT EFI_TIME *Time, - OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL ) { DEBUG ((DEBUG_ERROR, "Ring3: GetTime is not supported\n")); @@ -20,7 +20,7 @@ Ring3GetTime ( EFI_STATUS EFIAPI Ring3SetTime ( - IN EFI_TIME *Time + IN EFI_TIME *Time ) { DEBUG ((DEBUG_ERROR, "Ring3: SetTime is not supported\n")); @@ -31,9 +31,9 @@ Ring3SetTime ( EFI_STATUS EFIAPI Ring3GetWakeupTime ( - OUT BOOLEAN *Enabled, - OUT BOOLEAN *Pending, - OUT EFI_TIME *Time + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time ) { DEBUG ((DEBUG_ERROR, "Ring3: GetWakeupTime is not supported\n")); @@ -44,8 +44,8 @@ Ring3GetWakeupTime ( EFI_STATUS EFIAPI Ring3SetWakeupTime ( - IN BOOLEAN Enable, - IN EFI_TIME *Time OPTIONAL + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL ) { DEBUG ((DEBUG_ERROR, "Ring3: SetWakeupTime is not supported\n")); @@ -56,10 +56,10 @@ Ring3SetWakeupTime ( EFI_STATUS EFIAPI Ring3SetVirtualAddressMap ( - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN UINT32 DescriptorVersion, - IN EFI_MEMORY_DESCRIPTOR *VirtualMap + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap ) { DEBUG ((DEBUG_ERROR, "Ring3: SetVirtualAddressMap is not supported\n")); @@ -70,8 +70,8 @@ Ring3SetVirtualAddressMap ( EFI_STATUS EFIAPI Ring3ConvertPointer ( - IN UINTN DebugDisposition, - IN OUT VOID **Address + IN UINTN DebugDisposition, + IN OUT VOID **Address ) { DEBUG ((DEBUG_ERROR, "Ring3: ConvertPointer is not supported\n")); @@ -82,11 +82,11 @@ Ring3ConvertPointer ( EFI_STATUS EFIAPI Ring3GetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - OUT UINT32 *Attributes OPTIONAL, - IN OUT UINTN *DataSize, - OUT VOID *Data OPTIONAL + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data OPTIONAL ) { return SysCall ( @@ -103,9 +103,9 @@ Ring3GetVariable ( EFI_STATUS EFIAPI Ring3GetNextVariableName ( - IN OUT UINTN *VariableNameSize, - IN OUT CHAR16 *VariableName, - IN OUT EFI_GUID *VendorGuid + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid ) { DEBUG ((DEBUG_ERROR, "Ring3: GetNextVariableName is not supported\n")); @@ -116,11 +116,11 @@ Ring3GetNextVariableName ( EFI_STATUS EFIAPI Ring3SetVariable ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - IN UINT32 Attributes, - IN UINTN DataSize, - IN VOID *Data + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data ) { DEBUG ((DEBUG_ERROR, "Ring3: SetVariable is not supported\n")); @@ -131,7 +131,7 @@ Ring3SetVariable ( EFI_STATUS EFIAPI Ring3GetNextHighMonotonicCount ( - OUT UINT32 *HighCount + OUT UINT32 *HighCount ) { DEBUG ((DEBUG_ERROR, "Ring3: GetNextHighMonotonicCount is not supported\n")); @@ -142,10 +142,10 @@ Ring3GetNextHighMonotonicCount ( VOID EFIAPI Ring3ResetSystem ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL ) { DEBUG ((DEBUG_ERROR, "Ring3: ResetSystem is not supported\n")); @@ -156,9 +156,9 @@ Ring3ResetSystem ( EFI_STATUS EFIAPI Ring3UpdateCapsule ( - IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, - IN UINTN CapsuleCount, - IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL ) { DEBUG ((DEBUG_ERROR, "Ring3: UpdateCapsule is not supported\n")); @@ -169,10 +169,10 @@ Ring3UpdateCapsule ( EFI_STATUS EFIAPI Ring3QueryCapsuleCapabilities ( - IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, - IN UINTN CapsuleCount, - OUT UINT64 *MaximumCapsuleSize, - OUT EFI_RESET_TYPE *ResetType + IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, + IN UINTN CapsuleCount, + OUT UINT64 *MaximumCapsuleSize, + OUT EFI_RESET_TYPE *ResetType ) { DEBUG ((DEBUG_ERROR, "Ring3: QueryCapsuleCapabilities is not supported\n")); @@ -183,10 +183,10 @@ Ring3QueryCapsuleCapabilities ( EFI_STATUS EFIAPI Ring3QueryVariableInfo ( - IN UINT32 Attributes, - OUT UINT64 *MaximumVariableStorageSize, - OUT UINT64 *RemainingVariableStorageSize, - OUT UINT64 *MaximumVariableSize + IN UINT32 Attributes, + OUT UINT64 *MaximumVariableStorageSize, + OUT UINT64 *RemainingVariableStorageSize, + OUT UINT64 *MaximumVariableSize ) { DEBUG ((DEBUG_ERROR, "Ring3: QueryVariableInfo is not supported\n")); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm index 3c826d7d8f..b45253cd8f 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm @@ -44,7 +44,7 @@ makecall: ; VOID ; EFIAPI ; Ring3EntryPoint ( -; IN RING3_CALL_DATA *Data +; IN RING3_CALL_DATA *Data ; ); ; ; (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3(). diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 0ce4ef3120..341871147c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -60,7 +60,7 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) // EFI_STATUS // EFIAPI // CallRing3 ( -// IN RING3_CALL_DATA *Data, +// IN RING3_CALL_DATA *Data, // IN UINTN UserStackTop // ); // @@ -115,8 +115,8 @@ ASM_FUNC_ALIGN(SysCallEnd, 4096) // VOID // EFIAPI // ReturnToCore ( -// IN EFI_STATUS Status, -// IN UINTN ReturnSP +// IN EFI_STATUS Status, +// IN UINTN ReturnSP // ); // // (x0) Status diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index f02ab5bbb3..832a44d73d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -17,10 +17,10 @@ UINTN gUserPageTable; EFI_STATUS EFIAPI ArmCallRing3 ( - IN RING3_CALL_DATA *Data, - IN UINTN UserStackTop, - IN VOID *EntryPoint, - IN UINTN UserPageTable + IN RING3_CALL_DATA *Data, + IN UINTN UserStackTop, + IN VOID *EntryPoint, + IN UINTN UserPageTable ); STATIC @@ -94,8 +94,8 @@ MakeUserPageTableTemplate ( VOID EFIAPI InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries ) { UINTN Tcr; @@ -147,7 +147,7 @@ ForbidSupervisorAccessToUserMemory ( EFI_STATUS EFIAPI CallRing3 ( - IN RING3_CALL_DATA *Data, + IN RING3_CALL_DATA *Data, IN UINTN UserStackTop ) { diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index d7741277a0..63adc421b7 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -56,7 +56,7 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) // EFI_STATUS // EFIAPI // CallRing3 ( -// IN RING3_CALL_DATA *Data, +// IN RING3_CALL_DATA *Data, // IN UINTN UserStackTop // ); // @@ -109,8 +109,8 @@ ASM_FUNC_ALIGN(SysCallEnd, 4096) // VOID // EFIAPI // ReturnToCore ( -// IN EFI_STATUS Status, -// IN UINTN ReturnSP +// IN EFI_STATUS Status, +// IN UINTN ReturnSP // ); // // (r0) Status diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 55af5fe8cb..7cdd051817 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -16,10 +16,10 @@ UINTN gUserPageTable; EFI_STATUS EFIAPI ArmCallRing3 ( - IN RING3_CALL_DATA *Data, - IN UINTN UserStackTop, - IN VOID *EntryPoint, - IN UINTN UserPageTable + IN RING3_CALL_DATA *Data, + IN UINTN UserStackTop, + IN VOID *EntryPoint, + IN UINTN UserPageTable ); STATIC @@ -84,7 +84,7 @@ SysCallBootService ( (VOID *)((UINTN)Physical + 3 * sizeof (UINTN)), (VOID *)Context.SystemContextArm->SP, (NumberOfArguments - 2) * sizeof (UINTN) - ); + ); } } ForbidSupervisorAccessToUserMemory (); @@ -136,8 +136,8 @@ MakeUserPageTableTemplate ( VOID EFIAPI InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries ) { if (ArmHasPan ()) { @@ -176,7 +176,7 @@ ForbidSupervisorAccessToUserMemory ( EFI_STATUS EFIAPI CallRing3 ( - IN RING3_CALL_DATA *Data, + IN RING3_CALL_DATA *Data, IN UINTN UserStackTop ) { diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 3483b07997..0b96d43299 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -68,8 +68,8 @@ CallInstallMultipleProtocolInterfaces ( VOID EFIAPI ReturnToCore ( - IN EFI_STATUS Status, - IN UINTN ReturnSP + IN EFI_STATUS Status, + IN UINTN ReturnSP ); VOID @@ -172,8 +172,8 @@ STATIC VOID * EFIAPI FindInterface ( - IN BOOLEAN FindRing3, - IN VOID *Interface + IN BOOLEAN FindRing3, + IN VOID *Interface ) { LIST_ENTRY *Link; @@ -566,7 +566,7 @@ CallBootService ( } else if (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiSimpleFileSystemProtocolGuid)) { CoreSimpleFileSystem = (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *)CoreArgList[Index + 1]; - CoreSimpleFileSystem->OpenVolume = CoreOpenVolume; + CoreSimpleFileSystem->OpenVolume = CoreSimpleFileSystemOpenVolume; } else if ((CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiUnicodeCollationProtocolGuid)) || (CompareGuid ((EFI_GUID *)CoreArgList[Index], &gEfiUnicodeCollation2ProtocolGuid))) { CoreUnicodeCollation = (EFI_UNICODE_COLLATION_PROTOCOL *)CoreArgList[Index + 1]; diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index 0590418c4a..b8ffa3a08b 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -104,7 +104,7 @@ ASM_PFX(SysCallBase): ; EFI_STATUS ; EFIAPI ; CoreBootServices ( -; IN UINT8 Type, +; IN UINT8 Type, ; ... ; ); ; @@ -168,7 +168,7 @@ ASM_PFX(CoreBootServices): ; EFI_STATUS ; EFIAPI ; CallRing3 ( -; IN RING3_CALL_DATA *Data, +; IN RING3_CALL_DATA *Data, ; IN UINTN UserStackTop ; ); ; @@ -219,8 +219,8 @@ ASM_PFX(SysCallEnd): ; VOID ; EFIAPI ; ReturnToCore ( -; IN EFI_STATUS Status, -; IN UINTN ReturnSP +; IN EFI_STATUS Status, +; IN UINTN ReturnSP ; ); ;------------------------------------------------------------------------------ global ASM_PFX(ReturnToCore) diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c index e3c2ab6f68..b2725303d2 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c @@ -90,8 +90,8 @@ MakeUserPageTableTemplate ( VOID EFIAPI InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries ) { UINT64 Msr; diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index f388755f0e..549d12b626 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -75,7 +75,7 @@ STATIC USER_SPACE_DRIVER * EFIAPI FindUserSpaceDriver ( - IN VOID *CoreWrapper, + IN VOID *CoreWrapper, OUT UINTN *OldPageTable ) { @@ -100,9 +100,9 @@ FindUserSpaceDriver ( EFI_STATUS EFIAPI CoreDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ) { EFI_STATUS Status; @@ -136,9 +136,9 @@ CoreDriverBindingSupported ( EFI_STATUS EFIAPI CoreDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ) { EFI_STATUS Status; @@ -172,10 +172,10 @@ CoreDriverBindingStart ( EFI_STATUS EFIAPI CoreDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL ) { EFI_STATUS Status; @@ -257,9 +257,9 @@ STATIC EFI_STATUS EFIAPI CoreFileRead ( - IN EFI_FILE_PROTOCOL *This, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer ) { EFI_STATUS Status; @@ -336,9 +336,9 @@ STATIC EFI_STATUS EFIAPI CoreFileWrite ( - IN EFI_FILE_PROTOCOL *This, - IN OUT UINTN *BufferSize, - IN VOID *Buffer + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer ) { return EFI_UNSUPPORTED; @@ -348,8 +348,8 @@ STATIC EFI_STATUS EFIAPI CoreFileSetPosition ( - IN EFI_FILE_PROTOCOL *This, - IN UINT64 Position + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position ) { EFI_STATUS Status; @@ -410,8 +410,8 @@ STATIC EFI_STATUS EFIAPI CoreFileGetPosition ( - IN EFI_FILE_PROTOCOL *This, - OUT UINT64 *Position + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position ) { EFI_STATUS Status; @@ -468,10 +468,10 @@ STATIC EFI_STATUS EFIAPI CoreFileGetInfo ( - IN EFI_FILE_PROTOCOL *This, - IN EFI_GUID *InformationType, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer ) { EFI_STATUS Status; @@ -558,10 +558,10 @@ STATIC EFI_STATUS EFIAPI CoreFileSetInfo ( - IN EFI_FILE_PROTOCOL *This, - IN EFI_GUID *InformationType, - IN UINTN BufferSize, - IN VOID *Buffer + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer ) { return EFI_UNSUPPORTED; @@ -581,12 +581,12 @@ STATIC EFI_STATUS EFIAPI CoreFileOpenEx ( - IN EFI_FILE_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **NewHandle, - IN CHAR16 *FileName, - IN UINT64 OpenMode, - IN UINT64 Attributes, - IN OUT EFI_FILE_IO_TOKEN *Token + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes, + IN OUT EFI_FILE_IO_TOKEN *Token ) { return EFI_UNSUPPORTED; @@ -596,8 +596,8 @@ STATIC EFI_STATUS EFIAPI CoreFileReadEx ( - IN EFI_FILE_PROTOCOL *This, - IN OUT EFI_FILE_IO_TOKEN *Token + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token ) { return EFI_UNSUPPORTED; @@ -607,8 +607,8 @@ STATIC EFI_STATUS EFIAPI CoreFileWriteEx ( - IN EFI_FILE_PROTOCOL *This, - IN OUT EFI_FILE_IO_TOKEN *Token + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token ) { return EFI_UNSUPPORTED; @@ -618,8 +618,8 @@ STATIC EFI_STATUS EFIAPI CoreFileFlushEx ( - IN EFI_FILE_PROTOCOL *This, - IN OUT EFI_FILE_IO_TOKEN *Token + IN EFI_FILE_PROTOCOL *This, + IN OUT EFI_FILE_IO_TOKEN *Token ) { return EFI_UNSUPPORTED; @@ -629,11 +629,11 @@ STATIC EFI_STATUS EFIAPI CoreFileOpen ( - IN EFI_FILE_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **NewHandle, - IN CHAR16 *FileName, - IN UINT64 OpenMode, - IN UINT64 Attributes + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes ) { EFI_STATUS Status; @@ -787,9 +787,9 @@ CoreFileOpen ( EFI_STATUS EFIAPI -CoreOpenVolume ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **Root +CoreSimpleFileSystemOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root ) { EFI_STATUS Status; @@ -1003,8 +1003,8 @@ CoreUnicodeCollationMetaiMatch ( VOID EFIAPI CoreUnicodeCollationStrLwr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str ) { EFI_STATUS Status; @@ -1057,8 +1057,8 @@ CoreUnicodeCollationStrLwr ( VOID EFIAPI CoreUnicodeCollationStrUpr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str ) { EFI_STATUS Status; @@ -1111,10 +1111,10 @@ CoreUnicodeCollationStrUpr ( VOID EFIAPI CoreUnicodeCollationFatToStr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN UINTN FatSize, - IN CHAR8 *Fat, - OUT CHAR16 *String + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String ) { EFI_STATUS Status; @@ -1166,10 +1166,10 @@ CoreUnicodeCollationFatToStr ( BOOLEAN EFIAPI CoreUnicodeCollationStrToFat ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN UINTN FatSize, - OUT CHAR8 *Fat + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat ) { EFI_STATUS Status; diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h index a6195035f2..478cef992d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.h @@ -14,33 +14,33 @@ EFI_STATUS EFIAPI CoreDriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ); EFI_STATUS EFIAPI CoreDriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ); EFI_STATUS EFIAPI CoreDriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL ); EFI_STATUS EFIAPI -CoreOpenVolume ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **Root +CoreSimpleFileSystemOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root ); INTN @@ -62,31 +62,31 @@ CoreUnicodeCollationMetaiMatch ( VOID EFIAPI CoreUnicodeCollationStrLwr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str ); VOID EFIAPI CoreUnicodeCollationStrUpr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN OUT CHAR16 *Str + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN OUT CHAR16 *Str ); VOID EFIAPI CoreUnicodeCollationFatToStr ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN UINTN FatSize, - IN CHAR8 *Fat, - OUT CHAR16 *String + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN UINTN FatSize, + IN CHAR8 *Fat, + OUT CHAR16 *String ); BOOLEAN EFIAPI CoreUnicodeCollationStrToFat ( - IN EFI_UNICODE_COLLATION_PROTOCOL *This, - IN CHAR16 *String, - IN UINTN FatSize, - OUT CHAR8 *Fat + IN EFI_UNICODE_COLLATION_PROTOCOL *This, + IN CHAR16 *String, + IN UINTN FatSize, + OUT CHAR8 *Fat ); diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 3c70630591..22faab68bd 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -112,7 +112,7 @@ ASM_PFX(SysCallBase): ; EFI_STATUS ; EFIAPI ; CoreBootServices ( -; IN UINT8 Type, +; IN UINT8 Type, ; ... ; ); ; @@ -182,7 +182,7 @@ o64 sysret ; EFI_STATUS ; EFIAPI ; CallRing3 ( -; IN RING3_CALL_DATA *Data, +; IN RING3_CALL_DATA *Data, ; IN UINTN UserStackTop ; ); ; @@ -234,8 +234,8 @@ ASM_PFX(SysCallEnd): ; VOID ; EFIAPI ; ReturnToCore ( -; IN EFI_STATUS Status, -; IN UINTN ReturnSP +; IN EFI_STATUS Status, +; IN UINTN ReturnSP ; ); ; ; (rcx) Status diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c index 662e96b8b9..04325c5b47 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c @@ -287,8 +287,8 @@ MakeUserPageTableTemplate ( VOID EFIAPI InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries + IN OUT EFI_CONFIGURATION_TABLE *Table, + IN UINTN NumberOfEntries ) { UINT64 Msr; From 26ee5e34369753434db3036481ae66e3fa15bee9 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 23 Jan 2025 18:31:22 +0300 Subject: [PATCH 320/341] Ring3: Refactored out MAX_LIST. --- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 53 +++++++++++-------- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 23 ++++---- .../Core/Dxe/SysCall/SupportedProtocols.c | 1 + MdePkg/Include/Uefi/UefiSpec.h | 1 - 4 files changed, 45 insertions(+), 33 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index bae3b0036b..6cb6fd063d 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -659,33 +659,44 @@ Ring3InstallMultipleProtocolInterfaces ( ... ) { - VA_LIST Marker; - VOID *Argument; - VOID *ArgList[MAX_LIST]; - UINTN Index; + EFI_STATUS Status; + VA_LIST Marker; + VOID **Arguments; + UINTN NumberOfArguments; + UINTN Index; VA_START (Marker, Handle); - for (Index = 0; Index < MAX_LIST; ++Index) { - Argument = VA_ARG (Marker, VOID *); - ArgList[Index] = Argument; - - if (Argument == NULL) { - break; - } + NumberOfArguments = 1; + while (VA_ARG (Marker, VOID *) != NULL) { + ++NumberOfArguments; } VA_END (Marker); - if (Index == MAX_LIST) { - DEBUG ((DEBUG_ERROR, "Ring3: Too many arguments\n")); - return EFI_INVALID_PARAMETER; + Status = CoreAllocatePool ( + EfiRing3MemoryType, + NumberOfArguments * sizeof (VOID *), + (VOID **)&Arguments + ); + if (EFI_ERROR (Status)) { + return Status; } - return SysCall ( - SysCallInstallMultipleProtocolInterfaces, - 2, - Handle, - ArgList - ); + VA_START (Marker, Handle); + for (Index = 0; Index < NumberOfArguments; ++Index) { + Arguments[Index] = VA_ARG (Marker, VOID *); + } + VA_END (Marker); + + Status = SysCall ( + SysCallInstallMultipleProtocolInterfaces, + 3, + Handle, + NumberOfArguments, + Arguments + ); + + CoreFreePool (Arguments); + return Status; } EFI_STATUS @@ -796,5 +807,5 @@ CoreFreePoolPagesWithGuard ( IN UINTN NoPages ) { - CoreFreePoolPagesI (PoolType, Memory, NoPages); + CoreFreePoolPagesI (EfiRing3MemoryType, Memory, NoPages); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 0b96d43299..e6dbe42a4d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -345,6 +345,7 @@ FreeUserSpaceDriver ( } RemoveEntryList (&UserDriver->Link); + FreePool (UserDriver); } EFI_STATUS @@ -367,7 +368,7 @@ CallBootService ( UINTN Argument6; UINT32 Index; VOID **UserArgList; - VOID *CoreArgList[MAX_LIST]; + VOID **CoreArgList; EFI_HANDLE CoreHandle; UINT32 PagesNumber; EFI_PHYSICAL_ADDRESS Ring3Pages; @@ -491,24 +492,25 @@ CallBootService ( case SysCallInstallMultipleProtocolInterfaces: // // Argument 1: EFI_HANDLE *Handle - // ... + // Argument 2: UINTN NumberOfArguments + // Argument 3: VOID **UserArgList // gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[1], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[1] + sizeof (EFI_HANDLE *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[2], &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[3], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[2] + sizeof (VOID **) - 1), &Attributes); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[3] + Arguments[2] * sizeof (VOID *) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + CoreArgList = AllocatePool (Arguments[2] * sizeof (VOID *)); + AllowSupervisorAccessToUserMemory (); CoreHandle = *(EFI_HANDLE *)Arguments[1]; - UserArgList = (VOID **)Arguments[2]; + UserArgList = (VOID **)Arguments[3]; for (Index = 0; UserArgList[Index] != NULL; Index += 2) { - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArgList[Index], &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)UserArgList[Index] + sizeof (EFI_GUID) - 1), &Attributes); @@ -524,6 +526,7 @@ CallBootService ( Index -= 2; } + FreePool (CoreArgList); FreePool (Arguments); return Status; } @@ -547,13 +550,10 @@ CallBootService ( NewDriver->UserStackTop = UserDriver->UserStackTop; InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); - - gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)((UINTN)&UserArgList[Index + 2] + sizeof (VOID *) - 1), &Attributes); - ASSERT ((Attributes & EFI_MEMORY_USER) != 0); } ForbidSupervisorAccessToUserMemory (); - ASSERT (Index < MAX_LIST); + ASSERT (Index == (Arguments[2] - 1)); CoreArgList[Index] = NULL; for (Index = 0; CoreArgList[Index] != NULL; Index += 2) { @@ -593,6 +593,7 @@ CallBootService ( (VOID *)gBS->InstallMultipleProtocolInterfaces ); + FreePool (CoreArgList); FreePool (Arguments); return Status; diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 549d12b626..ced0053ae3 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -237,6 +237,7 @@ CoreFileClose ( FreePool (UserDriver->CoreWrapper); RemoveEntryList (&UserDriver->Link); + FreePool (UserDriver); gUserPageTable = OldPageTable; diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index dd87dd9f3f..d793103325 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2063,7 +2063,6 @@ typedef enum { SysCallMax } SYS_CALL_TYPE; -#define MAX_LIST 32 #define SC_FREE_PAGES 7 #define SC_BLOCK_IO_READ 14 #define SC_BLOCK_IO_WRITE 15 From 44676f2577e4fd482a707f418e49f2f601c508ca Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 24 Jan 2025 11:50:46 +0300 Subject: [PATCH 321/341] SysCall: Added NumberOfCalls to USER_SPACE_DRIVER. --- MdeModulePkg/Core/Dxe/DxeMain.h | 1 + MdeModulePkg/Core/Dxe/Image/Image.c | 1 + MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 1 + MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c | 12 ++++++++++++ 4 files changed, 15 insertions(+) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 88b3d1a5fd..9c70a25671 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -239,6 +239,7 @@ typedef struct { VOID *UserSpaceDriver; UINTN UserPageTable; UINTN UserStackTop; + UINT8 NumberOfCalls; LIST_ENTRY Link; } USER_SPACE_DRIVER; diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 5fe40520d0..2f6f66f99a 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1743,6 +1743,7 @@ CoreStartImage ( UserDriver->UserSpaceDriver = (VOID *)Image->EntryPoint; UserDriver->UserPageTable = Image->UserPageTable; UserDriver->UserStackTop = Image->UserStackTop; + UserDriver->NumberOfCalls = 0; InsertTailList (&gUserSpaceDriversHead, &UserDriver->Link); diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index e6dbe42a4d..988fb7c9c9 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -548,6 +548,7 @@ CallBootService ( NewDriver->UserSpaceDriver = UserArgList[Index + 1]; NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserStackTop = UserDriver->UserStackTop; + NewDriver->NumberOfCalls = 0; InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index ced0053ae3..91820e3713 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -8,6 +8,8 @@ #include "DxeMain.h" #include "SupportedProtocols.h" +#define MAX_CALL 1 + LIST_ENTRY gUserSpaceDriversHead = INITIALIZE_LIST_HEAD_VARIABLE (gUserSpaceDriversHead); EFI_STATUS @@ -33,6 +35,10 @@ GoToRing3 ( EFI_PHYSICAL_ADDRESS Ring3Pages; UINT32 PagesNumber; + if (UserDriver->NumberOfCalls > MAX_CALL) { + return EFI_OUT_OF_RESOURCES; + } + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN)); Status = CoreAllocatePages ( @@ -61,11 +67,15 @@ GoToRing3 ( // TODO: Allocate new stacks (only for EFI_FILE_PROTOCOL instances?), // because UserDriver can be interrupted and interrupt handler may call the same UserDriver again. // + ++UserDriver->NumberOfCalls; + Status = CallRing3 ( Input, UserDriver->UserStackTop ); + --UserDriver->NumberOfCalls; + CoreFreePages (Ring3Pages, PagesNumber); return Status; @@ -754,6 +764,7 @@ CoreFileOpen ( NewDriver->CoreWrapper = NewFile; NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserStackTop = UserDriver->UserStackTop; + NewDriver->NumberOfCalls = 0; AllowSupervisorAccessToUserMemory (); NewDriver->UserSpaceDriver = *Ring3NewHandle; @@ -855,6 +866,7 @@ CoreSimpleFileSystemOpenVolume ( NewDriver->CoreWrapper = File; NewDriver->UserPageTable = UserDriver->UserPageTable; NewDriver->UserStackTop = UserDriver->UserStackTop; + NewDriver->NumberOfCalls = 0; AllowSupervisorAccessToUserMemory (); NewDriver->UserSpaceDriver = *Ring3Root; From b6bb0e4a7664ffb3152e704aa634eef6b47cee6a Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 24 Jan 2025 18:44:34 +0300 Subject: [PATCH 322/341] SysCall: Refactored UserStackTop to allocate it anew for each CallRing3. --- MdeModulePkg/Core/Dxe/DxeMain.h | 6 +- MdeModulePkg/Core/Dxe/Image/Image.c | 35 +-------- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 1 - .../Core/Dxe/SysCall/Initialization.c | 14 +--- .../Core/Dxe/SysCall/SupportedProtocols.c | 76 ++++++++++++------- 5 files changed, 53 insertions(+), 79 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index 9c70a25671..cc4570f0b9 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -231,14 +231,12 @@ typedef struct { VOID *HiiData; BOOLEAN IsUserImage; UINTN UserPageTable; - UINTN UserStackTop; } LOADED_IMAGE_PRIVATE_DATA; typedef struct { VOID *CoreWrapper; VOID *UserSpaceDriver; UINTN UserPageTable; - UINTN UserStackTop; UINT8 NumberOfCalls; LIST_ENTRY Link; } USER_SPACE_DRIVER; @@ -2790,9 +2788,7 @@ FreeProtocolsList ( UINTN EFIAPI InitializeUserPageTable ( - IN LOADED_IMAGE_PRIVATE_DATA *Image, - IN UINTN UserStackBase, - IN UINTN UserStackSize + IN LOADED_IMAGE_PRIVATE_DATA *Image ); #endif diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 2f6f66f99a..0305d561fd 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1033,30 +1033,6 @@ CoreUnloadAndCloseImage ( CoreFreePool (Image); } -STATIC -UINTN -EFIAPI -AllocateStack ( - IN UINTN Size, - OUT UINTN *Base - ) -{ - UINTN TopOfStack; - - ASSERT (Base != NULL); - ASSERT (IS_ALIGNED (Size, EFI_PAGE_SIZE)); - - *Base = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (Size)); - ASSERT (*Base != 0); - // - // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. - // - TopOfStack = *Base + Size - CPU_STACK_ALIGNMENT; - TopOfStack = ALIGN_VALUE (TopOfStack, CPU_STACK_ALIGNMENT); - - return TopOfStack; -} - /** Loads an EFI image into memory and returns a handle to the image. @@ -1132,7 +1108,6 @@ CoreLoadImageCommon ( UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; UINT8 ImageOrigin; EFI_FV_FILE_ATTRIBUTES FileAttributes; - UINTN UserStackBase; SecurityStatus = EFI_SUCCESS; @@ -1470,14 +1445,7 @@ CoreLoadImageCommon ( ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, Image->IsUserImage); if ((gRing3Data != NULL) && Image->IsUserImage) { - Image->UserStackTop = AllocateStack (STACK_SIZE, &UserStackBase); - SetUefiImageMemoryAttributes (UserStackBase, STACK_SIZE, EFI_MEMORY_XP | EFI_MEMORY_USER); - - Image->UserPageTable = InitializeUserPageTable ( - Image, - UserStackBase, - STACK_SIZE - ); + Image->UserPageTable = InitializeUserPageTable (Image); } RegisterMemoryProfileImage ( @@ -1742,7 +1710,6 @@ CoreStartImage ( UserDriver->CoreWrapper = NULL; UserDriver->UserSpaceDriver = (VOID *)Image->EntryPoint; UserDriver->UserPageTable = Image->UserPageTable; - UserDriver->UserStackTop = Image->UserStackTop; UserDriver->NumberOfCalls = 0; InsertTailList (&gUserSpaceDriversHead, &UserDriver->Link); diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 988fb7c9c9..32f9f966d1 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -547,7 +547,6 @@ CallBootService ( NewDriver->CoreWrapper = CoreArgList[Index + 1]; NewDriver->UserSpaceDriver = UserArgList[Index + 1]; NewDriver->UserPageTable = UserDriver->UserPageTable; - NewDriver->UserStackTop = UserDriver->UserStackTop; NewDriver->NumberOfCalls = 0; InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index a6e23206e7..20949c0019 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -180,9 +180,7 @@ InitializeRing3 ( UINTN EFIAPI InitializeUserPageTable ( - IN LOADED_IMAGE_PRIVATE_DATA *Image, - IN UINTN UserStackBase, - IN UINTN UserStackSize + IN LOADED_IMAGE_PRIVATE_DATA *Image ) { UINTN UserPageTable; @@ -198,7 +196,7 @@ InitializeUserPageTable ( MakeUserPageTableTemplate (&UserPageTable, &UserPageTableSize); // - // Map gRing3Data, gRing3Interfaces, UserStackBase, DxeRing3 + // Map gRing3Data, gRing3Interfaces, DxeRing3 // gCpu->SetUserMemoryAttributes ( gCpu, @@ -216,14 +214,6 @@ InitializeUserPageTable ( EFI_MEMORY_XP | EFI_MEMORY_USER ); - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - UserStackBase, - UserStackSize, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - SectionAddress = mDxeRing3->StartAddress; for (Index = 0; Index < mDxeRing3->NumSegments; Index++) { ImageRecordSegment = &mDxeRing3->Segments[Index]; diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 91820e3713..c09503d717 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -19,6 +19,30 @@ CallRing3 ( IN UINTN UserStackTop ); +STATIC +UINTN +EFIAPI +AllocateStack ( + IN UINTN Size, + OUT UINTN *Base + ) +{ + UINTN TopOfStack; + + ASSERT (Base != NULL); + ASSERT (IS_ALIGNED (Size, EFI_PAGE_SIZE)); + + *Base = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (Size)); + ASSERT (*Base != 0); + // + // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. + // + TopOfStack = *Base + Size - CPU_STACK_ALIGNMENT; + TopOfStack = ALIGN_VALUE (TopOfStack, CPU_STACK_ALIGNMENT); + + return TopOfStack; +} + EFI_STATUS EFIAPI GoToRing3 ( @@ -28,32 +52,22 @@ GoToRing3 ( ... ) { - EFI_STATUS Status; - RING3_CALL_DATA *Input; - VA_LIST Marker; - UINTN Index; - EFI_PHYSICAL_ADDRESS Ring3Pages; - UINT32 PagesNumber; + EFI_STATUS Status; + RING3_CALL_DATA *Input; + VA_LIST Marker; + UINTN Index; + UINTN UserStackTop; + UINTN UserStackBase; if (UserDriver->NumberOfCalls > MAX_CALL) { return EFI_OUT_OF_RESOURCES; } - PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN)); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - PagesNumber, - &Ring3Pages - ); - if (EFI_ERROR (Status)) { - return Status; - } + UserStackTop = AllocateStack (STACK_SIZE, &UserStackBase); + UserStackTop -= ALIGN_VALUE (sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN), CPU_STACK_ALIGNMENT); - Input = (RING3_CALL_DATA *)(UINTN)Ring3Pages; + Input = (RING3_CALL_DATA *)UserStackTop; - AllowSupervisorAccessToUserMemory (); Input->NumberOfArguments = Number; Input->EntryPoint = EntryPoint; @@ -62,21 +76,31 @@ GoToRing3 ( Input->Arguments[Index] = VA_ARG (Marker, UINTN); } VA_END (Marker); - ForbidSupervisorAccessToUserMemory (); + + SetUefiImageMemoryAttributes (UserStackBase, STACK_SIZE, EFI_MEMORY_XP | EFI_MEMORY_USER); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserDriver->UserPageTable, + UserStackBase, + STACK_SIZE, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + + ++UserDriver->NumberOfCalls; // - // TODO: Allocate new stacks (only for EFI_FILE_PROTOCOL instances?), - // because UserDriver can be interrupted and interrupt handler may call the same UserDriver again. + // Reserve space on stack for 4 arguments (X64 NOOPT prerequisite). // - ++UserDriver->NumberOfCalls; + UserStackTop -= ALIGN_VALUE (8*4, CPU_STACK_ALIGNMENT); Status = CallRing3 ( Input, - UserDriver->UserStackTop + UserStackTop ); --UserDriver->NumberOfCalls; - CoreFreePages (Ring3Pages, PagesNumber); + CoreFreePages (UserStackBase, EFI_SIZE_TO_PAGES (STACK_SIZE)); return Status; } @@ -763,7 +787,6 @@ CoreFileOpen ( NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); NewDriver->CoreWrapper = NewFile; NewDriver->UserPageTable = UserDriver->UserPageTable; - NewDriver->UserStackTop = UserDriver->UserStackTop; NewDriver->NumberOfCalls = 0; AllowSupervisorAccessToUserMemory (); @@ -865,7 +888,6 @@ CoreSimpleFileSystemOpenVolume ( NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); NewDriver->CoreWrapper = File; NewDriver->UserPageTable = UserDriver->UserPageTable; - NewDriver->UserStackTop = UserDriver->UserStackTop; NewDriver->NumberOfCalls = 0; AllowSupervisorAccessToUserMemory (); From 9e13ff1bbd49d5e5b948c64936bd012ce9324085 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Fri, 24 Jan 2025 19:32:15 +0300 Subject: [PATCH 323/341] CpuExceptionHandlerLib: Saved UserPageTable on stack, used CS saved on stack instead of DS for CPL extraction. --- .../CpuExceptionCommon.c | 8 --- .../Ia32/ExceptionHandlerAsm.nasm | 72 +++++++++++-------- .../X64/ExceptionHandlerAsm.nasm | 54 ++++++++------ 3 files changed, 74 insertions(+), 60 deletions(-) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c index 1599fa8e51..82dc2f3101 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c @@ -8,14 +8,6 @@ #include "CpuExceptionCommon.h" -// -// Error code flag indicating whether or not an error code will be -// pushed on the stack if an exception occurs. -// -// 1 means an error code will be pushed, otherwise 0 -// -CONST UINT32 mErrorCodeFlag = 0x20227d00; - // // Define the maximum message length // diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm index 07fef59095..226c7409b5 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.nasm @@ -23,7 +23,6 @@ ; ; CommonExceptionHandler() ; -extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag extern ASM_PFX(CommonExceptionHandler) @@ -32,11 +31,17 @@ ALIGN 4096 global ASM_PFX(CorePageTable) ASM_PFX(CorePageTable): - resq 1 - -global ASM_PFX(UserPageTable) -ASM_PFX(UserPageTable): - resq 1 + resd 1 + +; +; Error code flag indicating whether or not an error code will be +; pushed on the stack if an exception occurs. +; +; 1 means an error code will be pushed, otherwise 0 +; +global ASM_PFX(mErrorCodeFlag) +ASM_PFX(mErrorCodeFlag): + dd 0x20227d00 ALIGN 4096 Padding: @@ -101,16 +106,6 @@ HookAfterStubHeaderEnd: global ASM_PFX(CommonInterruptEntry) ASM_PFX(CommonInterruptEntry): cli - ; Check whether User Space process was interrupted. - mov eax, ds - and eax, 3 - jz NoCr3Switch - mov eax, cr3 - mov [ASM_PFX(UserPageTable)], eax - mov eax, [ASM_PFX(CorePageTable)] - mov cr3, eax - -NoCr3Switch: pop eax ; ; All interrupt handlers are invoked through interrupt gates, so @@ -219,14 +214,30 @@ ErrorCodeAndVectorOnStack: push 0 ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler push 0 ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag + ; Check whether User Space process was interrupted. + push eax + mov eax, [ebp + 4 * 4] ; CS + and eax, 3 + jz NoCr3Switch + mov eax, cr3 + push eax ; UserPageTable + mov eax, [ASM_PFX(CorePageTable)] + mov cr3, eax + mov eax, [esp + 4] ; eax + sub esp, 8 + push eax + +NoCr3Switch: + pop eax + ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; push eax push ecx push edx push ebx lea ecx, [ebp + 6 * 4] - ; Check whether Ring0 process was interrupted. - mov eax, ds + ; Check whether User Space process was interrupted. + mov eax, [ebp + 4 * 4] ; CS and eax, 3 jz sameCPL_0 mov ecx, [ecx] @@ -238,8 +249,8 @@ sameCPL_0: ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; mov eax, ss - ; Check whether Ring0 process was interrupted. - mov ecx, ds + ; Check whether User Space process was interrupted. + mov ecx, [ebp + 4 * 4] ; CS and ecx, 3 jz sameCPL_1 movzx eax, word [ebp + 7 * 4] @@ -412,8 +423,8 @@ sameCPL_1: pop es pop ds pop dword [ebp + 4 * 4] - ; Check whether Ring0 process was interrupted. - mov ecx, ds + ; Check whether User Space process was interrupted. + mov ecx, [ebp + 4 * 4] ; CS and ecx, 3 jz sameCPL_2 pop dword [ebp + 7 * 4] @@ -432,12 +443,12 @@ continue: pop ecx pop eax - ; Check whether Ring3 process was interrupted. - push ecx - mov ecx, ds - and ecx, 3 + ; Check whether User Space process was interrupted. + push eax + mov eax, [ebp + 4 * 4] ; CS + and eax, 3 + pop eax jnz ReturnToRing3 - pop ecx pop dword [ebp - 8] pop dword [ebp - 4] @@ -467,9 +478,10 @@ DoReturn: DoIret: iretd ReturnToRing3: - mov ecx, [ASM_PFX(UserPageTable)] - mov cr3, ecx - pop ecx + add esp, 8 + pop eax ; UserPageTable + mov cr3, eax + pop eax mov esp, ebp pop ebp add esp, 8 diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm index 278ff4f592..78722bd5a9 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm @@ -48,7 +48,6 @@ endstruc %define VC_EXCEPTION 29 -extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag extern ASM_PFX(CommonExceptionHandler) @@ -59,9 +58,15 @@ global ASM_PFX(CorePageTable) ASM_PFX(CorePageTable): resq 1 -global ASM_PFX(UserPageTable) -ASM_PFX(UserPageTable): - resq 1 +; +; Error code flag indicating whether or not an error code will be +; pushed on the stack if an exception occurs. +; +; 1 means an error code will be pushed, otherwise 0 +; +global ASM_PFX(mErrorCodeFlag) +ASM_PFX(mErrorCodeFlag): + dd 0x20227d00 ALIGN 4096 Padding: @@ -136,16 +141,6 @@ HookAfterStubHeaderEnd: global ASM_PFX(CommonInterruptEntry) ASM_PFX(CommonInterruptEntry): cli - ; Check whether User Space process was interrupted. - mov rax, ds - and rax, 3 - jz NoCr3Switch - mov rax, cr3 - mov [ASM_PFX(UserPageTable)], rax - mov rax, [ASM_PFX(CorePageTable)] - mov cr3, rax - -NoCr3Switch: pop rax ; ; All interrupt handlers are invoked through interrupt gates, so @@ -199,6 +194,21 @@ HasErrorCode: ; is 16-byte aligned ; + ; Check whether User Space process was interrupted. + push rax + mov rax, [rbp + 8*4] ; CS + and rax, 3 + jz NoCr3Switch + mov rax, cr3 + push rax ; UserPageTable + mov rax, [ASM_PFX(CorePageTable)] + mov cr3, rax + mov rax, [rsp + 8] ; rax + push rax + +NoCr3Switch: + pop rax + ;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; ;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; push r15 @@ -457,12 +467,12 @@ CetDone: pop r14 pop r15 - ; Check whether Ring3 process was interrupted. - push rcx - mov rcx, ds - and rcx, 3 + ; Check whether User Space process was interrupted. + push rax + mov rax, [rbp + 8*4] ; CS + and rax, 3 + pop rax jnz ReturnToRing3 - pop rcx mov rsp, rbp pop rbp @@ -491,9 +501,9 @@ DoReturn: DoIret: iretq ReturnToRing3: - mov rcx, [ASM_PFX(UserPageTable)] - mov cr3, rcx - pop rcx + pop rax ; UserPageTable + mov cr3, rax + pop rax mov rsp, rbp pop rbp add rsp, 16 From bc9b293f3147b8b4ca4c8511d558b9eea2b9a322 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 27 Jan 2025 11:50:49 +0300 Subject: [PATCH 324/341] Ring3: Fixed memory leaks and passed UserArguments to CallBootService through User stack for ARM, AARCH64. --- .../AArch64/ExceptionSupport.S | 7 +-- .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 28 +++++----- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 53 +++++++------------ MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 11 +++- MdePkg/Include/Protocol/DebugSupport.h | 13 +++-- 5 files changed, 53 insertions(+), 59 deletions(-) diff --git a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S index e914ee0a48..b2c1683920 100644 --- a/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/AArch64/ExceptionSupport.S @@ -91,7 +91,7 @@ UINT64 FAR; 0x320 // Fault Address Register UINT64 Type; 0x328 // Exception Type UINT64 TTBR0; 0x330 // User Page Table - UINT64 Padding;0x338 // Alignment requirement + UINT64 SP_EL0; 0x338 // User Stack Pointer */ GCC_ASM_EXPORT(ExceptionHandlersEnd) @@ -101,7 +101,7 @@ GCC_ASM_EXPORT(CommonCExceptionHandler) #define GP_CONTEXT_SIZE (32 * 8) #define FP_CONTEXT_SIZE (32 * 16) -#define SYS_CONTEXT_SIZE ( 8 * 8) // 7 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10) +#define SYS_CONTEXT_SIZE ( 8 * 8) // 8 SYS regs + Alignment requirement (ie: the stack must be aligned on 0x10) ASM_FUNC_ALIGN(ExceptionHandlerBase, 4096) @@ -253,7 +253,8 @@ ASM_PFX(CommonExceptionEntry): 1:mrs x2, ttbr0_el1 b 3f 2:mrs x2, ttbr0_el2 -3:stp x2, xzr, [x28, #0x30] +3:mrs x3, sp_el0 + stp x2, x3, [x28, #0x30] // Push FP regs to Stack. stp q0, q1, [x28, #-FP_CONTEXT_SIZE]! diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index 832a44d73d..3541667e50 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -30,34 +30,32 @@ SysCallBootService ( IN EFI_SYSTEM_CONTEXT Context ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Physical; + EFI_STATUS Status; + UINTN *UserArguments; ArmEnableInterrupts (); - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (7 * sizeof (UINTN)), - &Physical - ); - if (EFI_ERROR (Status)) { - return Status; - } + UserArguments = (UINTN *)(Context.SystemContextAArch64->SP_EL0 - 7 * sizeof (UINTN)); AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)Physical, (VOID *)&(Context.SystemContextAArch64->X1), 7 * sizeof (UINTN)); + // + // First 6 arguments are passed through X2-X7 and copied to Core stack, + // all the others are on User stack. + // + CopyMem ( + (VOID *)UserArguments, + (VOID *)&(Context.SystemContextAArch64->X1), + 7 * sizeof (UINTN) + ); ForbidSupervisorAccessToUserMemory (); Status = CallBootService ( Context.SystemContextAArch64->X0, Context.SystemContextAArch64->X1, - (UINTN *)Physical, + UserArguments, Context.SystemContextAArch64->SP ); - CoreFreePages (Physical, EFI_SIZE_TO_PAGES (7 * sizeof (UINTN))); - ArmDisableInterrupts (); return Status; diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 7cdd051817..66804b9d71 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -29,10 +29,10 @@ SysCallBootService ( IN EFI_SYSTEM_CONTEXT Context ) { - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Physical; - UINT8 Type; - UINT8 NumberOfArguments; + EFI_STATUS Status; + UINT8 Type; + UINT8 NumberOfArguments; + UINTN *UserArguments; ArmEnableInterrupts (); @@ -47,16 +47,6 @@ SysCallBootService ( ++NumberOfArguments; } - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES ((NumberOfArguments + 1) * sizeof (UINTN)), - &Physical - ); - if (EFI_ERROR (Status)) { - return Status; - } - AllowSupervisorAccessToUserMemory (); if (Type == SysCallFreePages) { // @@ -64,41 +54,34 @@ SysCallBootService ( // [SP] == Memory // Memory is passed as 2 words on stack and aligned on 8 bytes. // - CopyMem ((VOID *)(UINTN)Physical, (VOID *)&(Context.SystemContextArm->R1), 2 * sizeof (UINTN)); + UserArguments = (UINTN *)(Context.SystemContextArm->SP - 2 * sizeof (UINTN)); + CopyMem ( - (VOID *)((UINTN)Physical + 2 * sizeof (UINTN)), - (VOID *)Context.SystemContextArm->SP, + (VOID *)UserArguments, + (VOID *)&(Context.SystemContextArm->R1), 2 * sizeof (UINTN) ); } else { // - // First 2 arguments are passed through R2-R3 and copied to SysCall Stack. + // First 2 arguments are passed through R2-R3 and copied to Core stack, + // all the others are on User stack. // - CopyMem ((VOID *)(UINTN)Physical, (VOID *)&(Context.SystemContextArm->R1), 3 * sizeof (UINTN)); - - if (NumberOfArguments > 2) { - // - // All remaining arguments are on User Stack. - // - CopyMem ( - (VOID *)((UINTN)Physical + 3 * sizeof (UINTN)), - (VOID *)Context.SystemContextArm->SP, - (NumberOfArguments - 2) * sizeof (UINTN) - ); - } + UserArguments = (UINTN *)(Context.SystemContextArm->SP - 3 * sizeof (UINTN)); + + CopyMem ( + (VOID *)UserArguments, + (VOID *)&(Context.SystemContextArm->R1), + 3 * sizeof (UINTN) + ); } ForbidSupervisorAccessToUserMemory (); Status = CallBootService ( Type, NumberOfArguments, - (UINTN *)(UINTN)Physical, + UserArguments, Context.SystemContextArm->SP_EL1 ); - // - // TODO: Fix memory leak for ReturnToCore(). - // - CoreFreePages (Physical, EFI_SIZE_TO_PAGES ((NumberOfArguments + 1) * sizeof (UINTN))); ArmDisableInterrupts (); diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 32f9f966d1..7faf5dfb19 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -396,7 +396,15 @@ CallBootService ( switch (Type) { case SysCallReturnToCore: - ReturnToCore (Arguments[1], ReturnSP); + // + // Argument 1: EFI_STATUS Status + // Argument 2: UINTN ReturnSP + // + Status = (EFI_STATUS)Arguments[1]; + + FreePool (Arguments); + + ReturnToCore (Status, ReturnSP); break; case SysCallLocateProtocol: // @@ -1510,5 +1518,6 @@ CallBootService ( break; } + FreePool (Arguments); return EFI_UNSUPPORTED; } diff --git a/MdePkg/Include/Protocol/DebugSupport.h b/MdePkg/Include/Protocol/DebugSupport.h index d8623d1938..49bacd8f92 100644 --- a/MdePkg/Include/Protocol/DebugSupport.h +++ b/MdePkg/Include/Protocol/DebugSupport.h @@ -594,11 +594,14 @@ typedef struct { UINT64 V30[2]; UINT64 V31[2]; - UINT64 ELR; // Exception Link Register - UINT64 SPSR; // Saved Processor Status Register - UINT64 FPSR; // Floating Point Status Register - UINT64 ESR; // Exception syndrome register - UINT64 FAR; // Fault Address Register + UINT64 ELR; // Exception Link Register + UINT64 SPSR; // Saved Processor Status Register + UINT64 FPSR; // Floating Point Status Register + UINT64 ESR; // Exception syndrome register + UINT64 FAR; // Fault Address Register + UINT64 Type; // Exception Type + UINT64 TTBR0; // User Page Table + UINT64 SP_EL0; // User Stack Pointer } EFI_SYSTEM_CONTEXT_AARCH64; /// From 9c4d58ab327d7df96e7254e86fa6d7293167ae2e Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 27 Jan 2025 15:37:19 +0300 Subject: [PATCH 325/341] Core/Dxe: Added sanity checks. --- MdeModulePkg/Core/Dxe/Image/Image.c | 34 +- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 2 +- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 2 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 332 ++++++++---------- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 2 +- .../Core/Dxe/SysCall/SupportedProtocols.c | 66 ++-- .../Dxe/SysCall/X64/CoreBootServices.nasm | 2 +- 7 files changed, 193 insertions(+), 247 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 0305d561fd..e735b0df40 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1706,21 +1706,25 @@ CoreStartImage ( gUserPageTable = Image->UserPageTable; - UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); - UserDriver->CoreWrapper = NULL; - UserDriver->UserSpaceDriver = (VOID *)Image->EntryPoint; - UserDriver->UserPageTable = Image->UserPageTable; - UserDriver->NumberOfCalls = 0; - - InsertTailList (&gUserSpaceDriversHead, &UserDriver->Link); - - Image->Status = GoToRing3 ( - 2, - (VOID *)Image->EntryPoint, - UserDriver, - ImageHandle, - gRing3Data - ); + UserDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); + if (UserDriver != NULL) { + UserDriver->CoreWrapper = NULL; + UserDriver->UserSpaceDriver = (VOID *)Image->EntryPoint; + UserDriver->UserPageTable = Image->UserPageTable; + UserDriver->NumberOfCalls = 0; + + InsertTailList (&gUserSpaceDriversHead, &UserDriver->Link); + + Image->Status = GoToRing3 ( + 2, + (VOID *)Image->EntryPoint, + UserDriver, + ImageHandle, + gRing3Data + ); + } else { + Image->Status = EFI_OUT_OF_RESOURCES; + } } } else { Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 341871147c..6feacc9fde 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -15,7 +15,7 @@ // CallInstallMultipleProtocolInterfaces ( // IN EFI_HANDLE *Handle, // IN VOID **ArgList, -// IN UINT32 ArgListSize, +// IN UINTN ArgListSize, // IN VOID *Function // ); //------------------------------------------------------------------------------ diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 63adc421b7..a1ffb25271 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -13,7 +13,7 @@ // CallInstallMultipleProtocolInterfaces ( // IN EFI_HANDLE *Handle, // IN VOID **ArgList, -// IN UINT32 ArgListSize, +// IN UINTN ArgListSize, // IN VOID *Function // ); //------------------------------------------------------------------------------ diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 7faf5dfb19..9b4b1f087e 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -61,7 +61,7 @@ EFIAPI CallInstallMultipleProtocolInterfaces ( IN EFI_HANDLE *Handle, IN VOID **ArgList, - IN UINT32 ArgListSize, + IN UINTN ArgListSize, IN VOID *Function ); @@ -300,32 +300,9 @@ CopyUserArguments ( ); ForbidSupervisorAccessToUserMemory (); - ASSERT (Arguments != NULL); - return Arguments; } -STATIC -USER_SPACE_DRIVER * -EFIAPI -FindUserInfo ( - VOID - ) -{ - LIST_ENTRY *Link; - USER_SPACE_DRIVER *UserDriver; - - for (Link = gUserSpaceDriversHead.ForwardLink; Link != &gUserSpaceDriversHead; Link = Link->ForwardLink) { - UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link); - - if (UserDriver->UserPageTable == gUserPageTable) { - return UserDriver; - } - } - - return NULL; -} - STATIC VOID EFIAPI @@ -366,13 +343,12 @@ CallBootService ( UINTN Argument4; UINTN Argument5; UINTN Argument6; - UINT32 Index; + UINTN Index; VOID **UserArgList; VOID **CoreArgList; EFI_HANDLE CoreHandle; UINT32 PagesNumber; EFI_PHYSICAL_ADDRESS Ring3Pages; - USER_SPACE_DRIVER *UserDriver; USER_SPACE_DRIVER *NewDriver; UINTN *Arguments; EFI_PHYSICAL_ADDRESS PhysAddr; @@ -392,18 +368,22 @@ CallBootService ( Interface = NULL; Arguments = CopyUserArguments (NumberOfArguments, UserArguments); + if (Arguments == NULL) { + return EFI_OUT_OF_RESOURCES; + } + DEBUG ((DEBUG_VERBOSE, "Type: %a\n", SysCallNames[Type])); switch (Type) { case SysCallReturnToCore: - // - // Argument 1: EFI_STATUS Status - // Argument 2: UINTN ReturnSP + // + // Argument 1: EFI_STATUS Status + // Argument 2: UINTN ReturnSP // Status = (EFI_STATUS)Arguments[1]; FreePool (Arguments); - + ReturnToCore (Status, ReturnSP); break; case SysCallLocateProtocol: @@ -425,8 +405,7 @@ CallBootService ( Status = FindGuid ((EFI_GUID *)Arguments[1], &CoreProtocol, &MemoryCoreSize); ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { - FreePool (Arguments); - return Status; + break; } Status = gBS->LocateProtocol ( @@ -444,9 +423,7 @@ CallBootService ( } ForbidSupervisorAccessToUserMemory (); - FreePool (Arguments); - return Status; - + break; case SysCallOpenProtocol: // // Argument 1: EFI_HANDLE CoreUserHandle @@ -471,8 +448,7 @@ CallBootService ( Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize); ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { - FreePool (Arguments); - return Status; + break; } Status = gBS->OpenProtocol ( @@ -494,9 +470,7 @@ CallBootService ( ForbidSupervisorAccessToUserMemory (); } - FreePool (Arguments); - return Status; - + break; case SysCallInstallMultipleProtocolInterfaces: // // Argument 1: EFI_HANDLE *Handle @@ -513,6 +487,10 @@ CallBootService ( ASSERT ((Attributes & EFI_MEMORY_USER) != 0); CoreArgList = AllocatePool (Arguments[2] * sizeof (VOID *)); + if (CoreArgList == NULL) { + Status = EFI_OUT_OF_RESOURCES; + break; + } AllowSupervisorAccessToUserMemory (); CoreHandle = *(EFI_HANDLE *)Arguments[1]; @@ -526,17 +504,7 @@ CallBootService ( Status = FindGuid ((EFI_GUID *)UserArgList[Index], (EFI_GUID **)&CoreArgList[Index], &MemoryCoreSize); if (EFI_ERROR (Status)) { - ForbidSupervisorAccessToUserMemory (); - - while (Index > 0) { - FreeUserSpaceDriver (CoreArgList[Index - 1]); - FreePool (CoreArgList[Index - 1]); - Index -= 2; - } - - FreePool (CoreArgList); - FreePool (Arguments); - return Status; + goto Exit; } gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArgList[Index + 1], &Attributes); @@ -545,16 +513,20 @@ CallBootService ( ASSERT ((Attributes & EFI_MEMORY_USER) != 0); CoreArgList[Index + 1] = AllocateCopyPool (MemoryCoreSize, (VOID *)UserArgList[Index + 1]); + if (CoreArgList[Index + 1] == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); + if (NewDriver == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } - UserDriver = FindUserInfo (); - ASSERT (UserDriver != NULL); - // - // TODO: Check everywhere that Allocated != NULL - // - NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); NewDriver->CoreWrapper = CoreArgList[Index + 1]; NewDriver->UserSpaceDriver = UserArgList[Index + 1]; - NewDriver->UserPageTable = UserDriver->UserPageTable; + NewDriver->UserPageTable = gUserPageTable; NewDriver->NumberOfCalls = 0; InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); @@ -591,20 +563,35 @@ CallBootService ( (VOID *)CoreUnicodeCollation->SupportedLanguages ); ForbidSupervisorAccessToUserMemory (); + if (CoreUnicodeCollation->SupportedLanguages == NULL) { + Status = EFI_OUT_OF_RESOURCES; + Index = Arguments[2] - 1; + goto Exit; + } } } Status = CallInstallMultipleProtocolInterfaces ( &CoreHandle, CoreArgList, - Index + 1, + Arguments[2], (VOID *)gBS->InstallMultipleProtocolInterfaces ); FreePool (CoreArgList); - FreePool (Arguments); - return Status; + break; + + Exit: + ForbidSupervisorAccessToUserMemory (); + while (Index > 0) { + FreeUserSpaceDriver (CoreArgList[Index - 1]); + FreePool (CoreArgList[Index - 1]); + Index -= 2; + } + + FreePool (CoreArgList); + break; case SysCallCloseProtocol: // // Argument 1: EFI_HANDLE CoreUserHandle @@ -621,8 +608,7 @@ CallBootService ( Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize); ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { - FreePool (Arguments); - return Status; + break; } Status = gBS->CloseProtocol ( @@ -632,9 +618,7 @@ CallBootService ( (EFI_HANDLE)Arguments[4] ); - FreePool (Arguments); - return Status; - + break; case SysCallHandleProtocol: // // Argument 1: EFI_HANDLE CoreUserHandle @@ -654,8 +638,7 @@ CallBootService ( Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize); ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { - FreePool (Arguments); - return Status; + break; } Status = gBS->HandleProtocol ( @@ -673,9 +656,7 @@ CallBootService ( } ForbidSupervisorAccessToUserMemory (); - FreePool (Arguments); - return Status; - + break; case SysCallAllocatePages: // // Argument 1: EFI_ALLOCATE_TYPE Type @@ -699,9 +680,7 @@ CallBootService ( *(EFI_PHYSICAL_ADDRESS *)Arguments[4] = (EFI_PHYSICAL_ADDRESS)Argument4; ForbidSupervisorAccessToUserMemory (); - FreePool (Arguments); - return Status; - + break; case SysCallFreePages: // // Argument 1: UINTN NumberOfPages @@ -716,27 +695,22 @@ CallBootService ( Status = gBS->FreePages (PhysAddr, Arguments[1]); - FreePool (Arguments); - return Status; - + break; case SysCallRaiseTpl: // // Argument 1: EFI_TPL NewTpl // Status = (EFI_STATUS)gBS->RaiseTPL ((EFI_TPL)Arguments[1]); - FreePool (Arguments); - return Status; - + break; case SysCallRestoreTpl: // // Argument 1: EFI_TPL NewTpl // gBS->RestoreTPL ((EFI_TPL)Arguments[1]); - FreePool (Arguments); - return EFI_SUCCESS; - + Status = EFI_SUCCESS; + break; case SysCallLocateHandleBuffer: // // Argument 1: EFI_LOCATE_SEARCH_TYPE SearchType @@ -755,8 +729,7 @@ CallBootService ( Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize); ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { - FreePool (Arguments); - return Status; + break; } } @@ -794,8 +767,7 @@ CallBootService ( &Ring3Pages ); if (EFI_ERROR (Status)) { - FreePool (Arguments); - return Status; + break; } AllowSupervisorAccessToUserMemory (); @@ -807,9 +779,8 @@ CallBootService ( ForbidSupervisorAccessToUserMemory (); } - FreePool (Arguments); - return StatusBS; - + Status = StatusBS; + break; case SysCallCalculateCrc32: // // Argument 1: VOID *Data @@ -827,8 +798,8 @@ CallBootService ( Argument4 = (UINTN)AllocatePool (Arguments[2]); if ((VOID *)Argument4 == NULL) { - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } AllowSupervisorAccessToUserMemory (); @@ -845,9 +816,7 @@ CallBootService ( *(UINT32 *)Arguments[3] = (UINT32)Argument5; ForbidSupervisorAccessToUserMemory (); - FreePool (Arguments); - return Status; - + break; case SysCallGetVariable: // // Argument 1: CHAR16 *VariableName @@ -876,16 +845,15 @@ CallBootService ( Argument6 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[1]), (CHAR16 *)Arguments[1]); if ((VOID *)Argument6 == NULL) { ForbidSupervisorAccessToUserMemory (); - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } Status = FindGuid ((EFI_GUID *)Arguments[2], &CoreProtocol, &MemoryCoreSize); if (EFI_ERROR (Status)) { ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument6); - FreePool (Arguments); - return Status; + break; } gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes); @@ -905,8 +873,8 @@ CallBootService ( if ((VOID *)Argument5 == NULL) { ForbidSupervisorAccessToUserMemory (); FreePool ((VOID *)Argument6); - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } } ForbidSupervisorAccessToUserMemory (); @@ -937,9 +905,7 @@ CallBootService ( FreePool ((VOID *)Argument5); } - FreePool (Arguments); - return Status; - + break; case SysCallBlockIoReset: // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This @@ -948,8 +914,8 @@ CallBootService ( BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]); if (BlockIo == NULL) { - FreePool (Arguments); - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + break; } Status = BlockIo->Reset ( @@ -957,9 +923,7 @@ CallBootService ( (BOOLEAN)Arguments[2] ); - FreePool (Arguments); - return Status; - + break; case SysCallBlockIoRead: // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This @@ -973,14 +937,14 @@ CallBootService ( BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]); if (BlockIo == NULL) { - FreePool (Arguments); - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + break; } Argument5 = (UINTN)AllocatePool (Arguments[3]); if ((VOID *)Argument5 == NULL) { - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } Status = BlockIo->ReadBlocks ( @@ -1002,9 +966,7 @@ CallBootService ( FreePool ((VOID *)Argument5); - FreePool (Arguments); - return Status; - + break; case SysCallBlockIoWrite: // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This @@ -1018,14 +980,14 @@ CallBootService ( BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]); if (BlockIo == NULL) { - FreePool (Arguments); - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + break; } Argument5 = (UINTN)AllocatePool (Arguments[3]); if ((VOID *)Argument5 == NULL) { - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes); @@ -1047,9 +1009,7 @@ CallBootService ( FreePool ((VOID *)Argument5); - FreePool (Arguments); - return Status; - + break; case SysCallBlockIoFlush: // // Argument 1: EFI_BLOCK_IO_PROTOCOL *This @@ -1057,15 +1017,13 @@ CallBootService ( BlockIo = FindInterface (FALSE, (VOID *)Arguments[1]); if (BlockIo == NULL) { - FreePool (Arguments); - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + break; } Status = BlockIo->FlushBlocks (BlockIo); - FreePool (Arguments); - return Status; - + break; case SysCallDiskIoRead: // // Argument 1: EFI_DISK_IO_PROTOCOL *This @@ -1079,14 +1037,14 @@ CallBootService ( DiskIo = FindInterface (FALSE, (VOID *)Arguments[1]); if (DiskIo == NULL) { - FreePool (Arguments); - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + break; } Argument5 = (UINTN)AllocatePool (Arguments[3]); if ((VOID *)Argument5 == NULL) { - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } Status = DiskIo->ReadDisk ( @@ -1108,9 +1066,7 @@ CallBootService ( FreePool ((VOID *)Argument5); - FreePool (Arguments); - return Status; - + break; case SysCallDiskIoWrite: // // Argument 1: EFI_DISK_IO_PROTOCOL *This @@ -1124,14 +1080,14 @@ CallBootService ( DiskIo = FindInterface (FALSE, (VOID *)Arguments[1]); if (DiskIo == NULL) { - FreePool (Arguments); - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + break; } Argument5 = (UINTN)AllocatePool (Arguments[3]); if ((VOID *)Argument5 == NULL) { - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Arguments[4], &Attributes); @@ -1153,9 +1109,7 @@ CallBootService ( FreePool ((VOID *)Argument5); - FreePool (Arguments); - return Status; - + break; case SysCallUnicodeStriColl: // // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This @@ -1165,8 +1119,8 @@ CallBootService ( Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { - FreePool (Arguments); - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + break; } if ((CHAR16 *)Arguments[2] != NULL) { @@ -1180,8 +1134,8 @@ CallBootService ( Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } } @@ -1200,8 +1154,8 @@ CallBootService ( FreePool ((VOID *)Argument4); } - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } } @@ -1219,9 +1173,7 @@ CallBootService ( FreePool ((VOID *)Argument5); } - FreePool (Arguments); - return Status; - + break; case SysCallUnicodeMetaiMatch: // // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This @@ -1231,8 +1183,8 @@ CallBootService ( Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { - FreePool (Arguments); - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + break; } if ((CHAR16 *)Arguments[2] != NULL) { @@ -1246,8 +1198,8 @@ CallBootService ( Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } } @@ -1266,8 +1218,8 @@ CallBootService ( FreePool ((VOID *)Argument4); } - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } } @@ -1285,9 +1237,7 @@ CallBootService ( FreePool ((VOID *)Argument5); } - FreePool (Arguments); - return Status; - + break; case SysCallUnicodeStrLwr: // // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This @@ -1296,8 +1246,8 @@ CallBootService ( Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { - FreePool (Arguments); - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + break; } if ((CHAR16 *)Arguments[2] != NULL) { @@ -1311,8 +1261,8 @@ CallBootService ( Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } } @@ -1329,9 +1279,8 @@ CallBootService ( FreePool ((VOID *)Argument4); } - FreePool (Arguments); - return EFI_SUCCESS; - + Status = EFI_SUCCESS; + break; case SysCallUnicodeStrUpr: // // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This @@ -1340,8 +1289,8 @@ CallBootService ( Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { - FreePool (Arguments); - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + break; } if ((CHAR16 *)Arguments[2] != NULL) { @@ -1355,8 +1304,8 @@ CallBootService ( Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } } @@ -1373,9 +1322,8 @@ CallBootService ( FreePool ((VOID *)Argument4); } - FreePool (Arguments); - return EFI_SUCCESS; - + Status = EFI_SUCCESS; + break; case SysCallUnicodeFatToStr: // // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This @@ -1386,8 +1334,8 @@ CallBootService ( Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { - FreePool (Arguments); - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + break; } if ((CHAR8 *)Arguments[3] != NULL) { @@ -1400,8 +1348,8 @@ CallBootService ( Argument4 = (UINTN)AllocateCopyPool (Arguments[2], (CHAR8 *)Arguments[3]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } } @@ -1417,8 +1365,8 @@ CallBootService ( FreePool ((VOID *)Argument4); } - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } } @@ -1441,9 +1389,8 @@ CallBootService ( FreePool ((VOID *)Argument5); } - FreePool (Arguments); - return EFI_SUCCESS; - + Status = EFI_SUCCESS; + break; case SysCallUnicodeStrToFat: // // Argument 1: EFI_UNICODE_COLLATION_PROTOCOL *This @@ -1454,8 +1401,8 @@ CallBootService ( Unicode = FindInterface (FALSE, (VOID *)Arguments[1]); if (Unicode == NULL) { - FreePool (Arguments); - return EFI_NOT_FOUND; + Status = EFI_NOT_FOUND; + break; } if ((CHAR16 *)Arguments[2] != NULL) { @@ -1469,8 +1416,8 @@ CallBootService ( Argument4 = (UINTN)AllocateCopyPool (StrSize ((CHAR16 *)Arguments[2]), (CHAR16 *)Arguments[2]); ForbidSupervisorAccessToUserMemory (); if ((VOID *)Argument4 == NULL) { - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } } @@ -1486,8 +1433,8 @@ CallBootService ( FreePool ((VOID *)Argument4); } - FreePool (Arguments); - return EFI_OUT_OF_RESOURCES; + Status = EFI_OUT_OF_RESOURCES; + break; } } @@ -1510,14 +1457,13 @@ CallBootService ( FreePool ((VOID *)Argument5); } - FreePool (Arguments); - return Status; - + break; default: DEBUG ((DEBUG_ERROR, "Ring0: Unknown syscall type.\n")); + Status = EFI_UNSUPPORTED; break; } FreePool (Arguments); - return EFI_UNSUPPORTED; + return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index b8ffa3a08b..dfb3f09185 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -53,7 +53,7 @@ ASM_PFX(ForbidSupervisorAccessToUserMemory): ; CallInstallMultipleProtocolInterfaces ( ; IN EFI_HANDLE *Handle, ; IN VOID **ArgList, -; IN UINT32 ArgListSize, +; IN UINTN ArgListSize, ; IN VOID *Function ; ); ;------------------------------------------------------------------------------ diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index c09503d717..448806aad4 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -19,30 +19,6 @@ CallRing3 ( IN UINTN UserStackTop ); -STATIC -UINTN -EFIAPI -AllocateStack ( - IN UINTN Size, - OUT UINTN *Base - ) -{ - UINTN TopOfStack; - - ASSERT (Base != NULL); - ASSERT (IS_ALIGNED (Size, EFI_PAGE_SIZE)); - - *Base = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (Size)); - ASSERT (*Base != 0); - // - // Compute the top of the allocated stack. Pre-allocate a UINTN for safety. - // - TopOfStack = *Base + Size - CPU_STACK_ALIGNMENT; - TopOfStack = ALIGN_VALUE (TopOfStack, CPU_STACK_ALIGNMENT); - - return TopOfStack; -} - EFI_STATUS EFIAPI GoToRing3 ( @@ -63,8 +39,12 @@ GoToRing3 ( return EFI_OUT_OF_RESOURCES; } - UserStackTop = AllocateStack (STACK_SIZE, &UserStackBase); - UserStackTop -= ALIGN_VALUE (sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN), CPU_STACK_ALIGNMENT); + UserStackBase = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE)); + if (UserStackBase == 0) { + return EFI_OUT_OF_RESOURCES; + } + + UserStackTop = UserStackBase + STACK_SIZE - (sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN)); Input = (RING3_CALL_DATA *)UserStackTop; @@ -91,7 +71,7 @@ GoToRing3 ( // // Reserve space on stack for 4 arguments (X64 NOOPT prerequisite). // - UserStackTop -= ALIGN_VALUE (8*4, CPU_STACK_ALIGNMENT); + UserStackTop = ALIGN_VALUE (UserStackTop - 8*4 - CPU_STACK_ALIGNMENT, CPU_STACK_ALIGNMENT); Status = CallRing3 ( Input, @@ -784,10 +764,18 @@ CoreFileOpen ( return EFI_OUT_OF_RESOURCES; } - NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); - NewDriver->CoreWrapper = NewFile; - NewDriver->UserPageTable = UserDriver->UserPageTable; - NewDriver->NumberOfCalls = 0; + NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); + if (NewDriver == NULL) { + *NewHandle = NULL; + FreePool (NewFile); + CoreFreePages (Ring3Pages, PagesNumber); + gUserPageTable = OldPageTable; + return EFI_OUT_OF_RESOURCES; + } + + NewDriver->CoreWrapper = NewFile; + NewDriver->UserPageTable = UserDriver->UserPageTable; + NewDriver->NumberOfCalls = 0; AllowSupervisorAccessToUserMemory (); NewDriver->UserSpaceDriver = *Ring3NewHandle; @@ -885,10 +873,18 @@ CoreSimpleFileSystemOpenVolume ( return EFI_OUT_OF_RESOURCES; } - NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); - NewDriver->CoreWrapper = File; - NewDriver->UserPageTable = UserDriver->UserPageTable; - NewDriver->NumberOfCalls = 0; + NewDriver = AllocatePool (sizeof (USER_SPACE_DRIVER)); + if (NewDriver == NULL) { + *Root = NULL; + FreePool (File); + CoreFreePages (Physical, 1); + gUserPageTable = OldPageTable; + return EFI_OUT_OF_RESOURCES; + } + + NewDriver->CoreWrapper = File; + NewDriver->UserPageTable = UserDriver->UserPageTable; + NewDriver->NumberOfCalls = 0; AllowSupervisorAccessToUserMemory (); NewDriver->UserSpaceDriver = *Ring3Root; diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 22faab68bd..8d09253158 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -51,7 +51,7 @@ ASM_PFX(ForbidSupervisorAccessToUserMemory): ; CallInstallMultipleProtocolInterfaces ( ; IN EFI_HANDLE *Handle, ; IN VOID **ArgList, -; IN UINT32 ArgListSize, +; IN UINTN ArgListSize, ; IN VOID *Function ; ); ;------------------------------------------------------------------------------ From b6856ccaef00b4b34775f94fdb2cd4339f9819b5 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 27 Jan 2025 18:51:13 +0300 Subject: [PATCH 326/341] Core/Dxe: Placed platform dependent code into separate files. --- MdeModulePkg/Core/Dxe/DxeMain.inf | 5 +- MdeModulePkg/Core/Dxe/Image/Image.c | 3 + .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 84 +++++++++- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 80 +++++++++- .../Core/Dxe/SysCall/IA32/InitializeIA32.c | 59 +++++++- .../Core/Dxe/SysCall/Initialization.c | 143 ++++-------------- .../Core/Dxe/SysCall/X64/InitializeX64.c | 59 +++++++- 7 files changed, 294 insertions(+), 139 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 9dc23efd38..3aa681febb 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -150,10 +150,10 @@ gEfiHobMemoryAllocStackGuid ## SOMETIMES_CONSUMES ## SystemTable gUefiImageLoaderImageContextGuid ## CONSUMES ## HOB gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## SysCall - gEarlyPL011BaseAddressGuid ## CONSUMES [Guids.ARM, Guids.AARCH64] - gArmVirtSystemMemorySizeGuid ## CONSUMES + gArmVirtSystemMemorySizeGuid ## SOMETIMES_CONSUMES ## SysCall + gEarlyPL011BaseAddressGuid ## SOMETIMES_CONSUMES ## SysCall [Ppis] gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB @@ -227,7 +227,6 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES [Pcd.IA32, Pcd.X64] gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index e735b0df40..41b107cf9f 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1700,6 +1700,9 @@ CoreStartImage ( if (PcdGetBool (PcdEnableUserSpace) && (Image->IsUserImage)) { if (gRing3Data == NULL) { Image->Status = InitializeRing3 (ImageHandle, Image); + if (EFI_ERROR (Image->Status)) { + CpuDeadLoop (); + } } else { gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Image->EntryPoint, &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index 3541667e50..854f80301c 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -6,6 +6,7 @@ **/ #include +#include #include #include #include @@ -14,6 +15,10 @@ UINTN gUserPageTable; +STATIC UINTN mConfigurationTable; +STATIC UINTN mConfigurationTableSize; +STATIC UINTN mUartBaseAddress; + EFI_STATUS EFIAPI ArmCallRing3 ( @@ -89,15 +94,55 @@ MakeUserPageTableTemplate ( ); } -VOID +EFI_STATUS EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries +InitializePlatform ( + IN OUT EFI_SYSTEM_TABLE *System ) { - UINTN Tcr; - UINTN Sctlr; + EFI_STATUS Status; + UINTN Tcr; + UINTN Sctlr; + EFI_PHYSICAL_ADDRESS Physical; + UINTN Index; + EFI_CONFIGURATION_TABLE *Conf; + EARLY_PL011_BASE_ADDRESS *UartBase; + CONST VOID *Hob; + + mConfigurationTableSize = (System->NumberOfTableEntries + 1) * sizeof (EFI_CONFIGURATION_TABLE); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (mConfigurationTableSize), + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); + return Status; + } + + Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + + for (Index = 0; Index < System->NumberOfTableEntries; ++Index) { + CopyGuid (&Conf->VendorGuid, &System->ConfigurationTable[Index].VendorGuid); + + Conf->VendorTable = System->ConfigurationTable[Index].VendorTable; + + ++Conf; + } + + Hob = GetFirstGuidHob (&gEarlyPL011BaseAddressGuid); + UartBase = GET_GUID_HOB_DATA (Hob); + mUartBaseAddress = (UINTN)UartBase->DebugAddress; + + CopyGuid (&(Conf->VendorGuid), &gEarlyPL011BaseAddressGuid); + Conf->VendorTable = (VOID *)mUartBaseAddress; + ++System->NumberOfTableEntries; + + System->ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + mConfigurationTable = (UINTN)Physical; + // // Disable Hierarchical permissions just in case. // @@ -118,6 +163,33 @@ InitializeMsr ( InitializeSysCallHandler ((VOID *)SysCallBootService); SetExceptionAddresses (NULL, 0); + + return EFI_SUCCESS; +} + +VOID +EFIAPI +MapPlatform ( + IN OUT UINTN UserPageTable + ) +{ + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mConfigurationTable, + ALIGN_VALUE (mConfigurationTableSize, EFI_PAGE_SIZE), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + // + // Necessary fix for DEBUG printings. + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mUartBaseAddress, + SIZE_4KB, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); } VOID diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 66804b9d71..dd0bc1c51f 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -5,6 +5,7 @@ **/ +#include #include #include #include @@ -13,6 +14,10 @@ UINTN gUserPageTable; +STATIC UINTN mConfigurationTable; +STATIC UINTN mConfigurationTableSize; +STATIC UINTN mUartBaseAddress; + EFI_STATUS EFIAPI ArmCallRing3 ( @@ -116,13 +121,53 @@ MakeUserPageTableTemplate ( ); } -VOID +EFI_STATUS EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries +InitializePlatform ( + IN OUT EFI_SYSTEM_TABLE *System ) { + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Physical; + UINTN Index; + EFI_CONFIGURATION_TABLE *Conf; + EARLY_PL011_BASE_ADDRESS *UartBase; + CONST VOID *Hob; + + mConfigurationTableSize = (System->NumberOfTableEntries + 1) * sizeof (EFI_CONFIGURATION_TABLE); + + Status = CoreAllocatePages ( + AllocateAnyPages, + EfiRing3MemoryType, + EFI_SIZE_TO_PAGES (mConfigurationTableSize), + &Physical + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); + return Status; + } + + Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + + for (Index = 0; Index < System->NumberOfTableEntries; ++Index) { + CopyGuid (&Conf->VendorGuid, &System->ConfigurationTable[Index].VendorGuid); + + Conf->VendorTable = System->ConfigurationTable[Index].VendorTable; + + ++Conf; + } + + Hob = GetFirstGuidHob (&gEarlyPL011BaseAddressGuid); + UartBase = GET_GUID_HOB_DATA (Hob); + mUartBaseAddress = (UINTN)UartBase->DebugAddress; + + CopyGuid (&(Conf->VendorGuid), &gEarlyPL011BaseAddressGuid); + Conf->VendorTable = (VOID *)mUartBaseAddress; + ++System->NumberOfTableEntries; + + System->ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; + mConfigurationTable = (UINTN)Physical; + if (ArmHasPan ()) { // // Enable Privileged Access Never feature. @@ -132,6 +177,33 @@ InitializeMsr ( InitializeSysCallHandler (SysCallBootService); SetExceptionAddresses (NULL, 0); + + return EFI_SUCCESS; +} + +VOID +EFIAPI +MapPlatform ( + IN OUT UINTN UserPageTable + ) +{ + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mConfigurationTable, + ALIGN_VALUE (mConfigurationTableSize, EFI_PAGE_SIZE), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + // + // Necessary fix for DEBUG printings. + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mUartBaseAddress, + SIZE_4KB, + EFI_MEMORY_XP | EFI_MEMORY_USER + ); } VOID diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c index b2725303d2..f9b615914a 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c @@ -10,6 +10,8 @@ #include #include +extern EXCEPTION_ADDRESSES *mExceptionAddresses; + VOID EFIAPI MakeUserPageTableTemplate ( @@ -87,11 +89,10 @@ MakeUserPageTableTemplate ( *UserPageTableTemplateSize = EFI_PAGES_TO_SIZE (TotalPagesNum); } -VOID +EFI_STATUS EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries +InitializePlatform ( + IN OUT EFI_SYSTEM_TABLE *System ) { UINT64 Msr; @@ -140,7 +141,7 @@ InitializeMsr ( AsmCpuidEx (0x01, 0x0, NULL, NULL, NULL, &Edx); if ((Edx & BIT11) == 0) { DEBUG ((DEBUG_ERROR, "Core: SYSENTER and SYSEXIT are not supported.\n")); - CpuDeadLoop (); + return EFI_UNSUPPORTED; } // @@ -154,4 +155,52 @@ InitializeMsr ( AsmWriteMsr64 (MSR_IA32_SYSENTER_EIP, Msr); gCorePageTable = AsmReadCr3 (); + + return EFI_SUCCESS; +} + +VOID +EFIAPI +MapPlatform ( + IN OUT UINTN UserPageTable + ) +{ + IA32_DESCRIPTOR IdtDescriptor; + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)&gCorePageTable, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionStackBase, + mExceptionAddresses->ExceptionStackSize, + EFI_MEMORY_XP + ); + + AsmReadIdtr (&IdtDescriptor); + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + IdtDescriptor.Base, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + + // + // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + } diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 20949c0019..7302ef6e49 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -5,25 +5,20 @@ **/ -#include - #include "DxeMain.h" VOID *gRing3EntryPoint; RING3_DATA *gRing3Data; VOID *gRing3Interfaces; -UINTN gUartBaseAddress; - -UEFI_IMAGE_RECORD *mDxeRing3; -EXCEPTION_ADDRESSES *mExceptionAddresses; -UINTN mConfigurationTable; -UINTN mConfigurationTableSize; -EFI_PHYSICAL_ADDRESS mCoreStackBase; -UINT64 mCoreStackSize; +EXCEPTION_ADDRESSES *mExceptionAddresses; extern UINTN SysCallBase; extern UINTN SysCallEnd; +STATIC UEFI_IMAGE_RECORD *mDxeRing3; +STATIC EFI_PHYSICAL_ADDRESS mCoreStackBase; +STATIC UINT64 mCoreStackSize; + VOID EFIAPI MakeUserPageTableTemplate ( @@ -31,11 +26,16 @@ MakeUserPageTableTemplate ( OUT UINTN *UserPageTableTemplateSize ); +EFI_STATUS +EFIAPI +InitializePlatform ( + IN OUT EFI_SYSTEM_TABLE *System + ); + VOID EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries +MapPlatform ( + IN OUT UINTN UserPageTable ); EFI_STATUS @@ -47,10 +47,6 @@ InitializeRing3 ( { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Physical; - UINTN Index; - EFI_CONFIGURATION_TABLE *Conf; - EARLY_PL011_BASE_ADDRESS *UartBase; - CONST VOID *Hob; EFI_PEI_HOB_POINTERS PeiHob; EFI_HOB_MEMORY_ALLOCATION *MemoryHob; @@ -78,43 +74,6 @@ InitializeRing3 ( EFI_MEMORY_XP | EFI_MEMORY_USER ); - if (PcdGetBool (PcdSerialUseMmio)) { - mConfigurationTableSize = (gRing3Data->SystemTable.NumberOfTableEntries + 1) * sizeof (EFI_CONFIGURATION_TABLE); - - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (mConfigurationTableSize), - &Physical - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); - return Status; - } - - Conf = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; - - for (Index = 0; Index < gRing3Data->SystemTable.NumberOfTableEntries; ++Index) { - CopyGuid (&(Conf->VendorGuid), &gRing3Data->SystemTable.ConfigurationTable[Index].VendorGuid); - - Conf->VendorTable = gRing3Data->SystemTable.ConfigurationTable[Index].VendorTable; - - ++Conf; - } - - Hob = GetFirstGuidHob (&gEarlyPL011BaseAddressGuid); - UartBase = GET_GUID_HOB_DATA (Hob); - gUartBaseAddress = (UINTN)UartBase->DebugAddress; - - CopyGuid (&(Conf->VendorGuid), &gEarlyPL011BaseAddressGuid); - Conf->VendorTable = (VOID *)gUartBaseAddress; - ++gRing3Data->SystemTable.NumberOfTableEntries; - - DEBUG ((DEBUG_ERROR, "Core: gUartBaseAddress = 0x%p\n", gUartBaseAddress)); - - gRing3Data->SystemTable.ConfigurationTable = (EFI_CONFIGURATION_TABLE *)(UINTN)Physical; - mConfigurationTable = (UINTN)Physical; - } // // Initialize DxeRing3 with Supervisor privileges. // @@ -155,10 +114,18 @@ InitializeRing3 ( EFI_MEMORY_XP | EFI_MEMORY_USER ); - InitializeMsr ( - gRing3Data->SystemTable.ConfigurationTable, - gRing3Data->SystemTable.NumberOfTableEntries - ); + Status = InitializePlatform (&gRing3Data->SystemTable); + if (EFI_ERROR (Status)) { + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + ); + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Interfaces, + RING3_INTERFACES_PAGES + ); + return Status; + } mExceptionAddresses = GetExceptionAddresses (); @@ -249,7 +216,7 @@ InitializeUserPageTable ( ); // - // Map ExceptionHandlers, ExceptionStacks, Idt + // Map ExceptionHandlers // gCpu->SetUserMemoryAttributes ( gCpu, @@ -267,63 +234,7 @@ InitializeUserPageTable ( EFI_MEMORY_XP ); -#if defined (MDE_CPU_X64) || defined (MDE_CPU_IA32) - IA32_DESCRIPTOR IdtDescriptor; - - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - (UINTN)&gCorePageTable, - SIZE_4KB, - EFI_MEMORY_RO | EFI_MEMORY_XP - ); - - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - mExceptionAddresses->ExceptionStackBase, - mExceptionAddresses->ExceptionStackSize, - EFI_MEMORY_XP - ); - - AsmReadIdtr (&IdtDescriptor); - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - IdtDescriptor.Base, - SIZE_4KB, - EFI_MEMORY_RO | EFI_MEMORY_XP - ); - - // - // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() - // - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - FixedPcdGet32 (PcdOvmfWorkAreaBase), - FixedPcdGet32 (PcdOvmfWorkAreaSize), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); -#elif defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - mConfigurationTable, - ALIGN_VALUE (mConfigurationTableSize, EFI_PAGE_SIZE), - EFI_MEMORY_XP | EFI_MEMORY_USER - ); - // - // Necessary fix for DEBUG printings. - // - gCpu->SetUserMemoryAttributes ( - gCpu, - UserPageTable, - gUartBaseAddress, - SIZE_4KB, - EFI_MEMORY_XP | EFI_MEMORY_USER - ); -#endif + MapPlatform (UserPageTable); // // Map User Image diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c index 04325c5b47..9428f7fbb9 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c @@ -11,6 +11,8 @@ #include #include +extern EXCEPTION_ADDRESSES *mExceptionAddresses; + VOID EFIAPI MakeUserPageTableTemplate ( @@ -284,11 +286,10 @@ MakeUserPageTableTemplate ( *UserPageTableTemplateSize = EFI_PAGES_TO_SIZE (TotalPagesNum); } -VOID +EFI_STATUS EFIAPI -InitializeMsr ( - IN OUT EFI_CONFIGURATION_TABLE *Table, - IN UINTN NumberOfEntries +InitializePlatform ( + IN OUT EFI_SYSTEM_TABLE *System ) { UINT64 Msr; @@ -342,7 +343,7 @@ InitializeMsr ( AsmWriteMsr64 (MSR_IA32_EFER, MsrEfer.Uint64); } else { DEBUG ((DEBUG_ERROR, "Core: SYSCALL and SYSRET are not supported.\n")); - CpuDeadLoop (); + return EFI_UNSUPPORTED; } // @@ -360,4 +361,52 @@ InitializeMsr ( AsmWriteMsr64 (MSR_IA32_FMASK, Msr); gCorePageTable = AsmReadCr3 (); + + return EFI_SUCCESS; +} + +VOID +EFIAPI +MapPlatform ( + IN OUT UINTN UserPageTable + ) +{ + IA32_DESCRIPTOR IdtDescriptor; + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + (UINTN)&gCorePageTable, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + mExceptionAddresses->ExceptionStackBase, + mExceptionAddresses->ExceptionStackSize, + EFI_MEMORY_XP + ); + + AsmReadIdtr (&IdtDescriptor); + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + IdtDescriptor.Base, + SIZE_4KB, + EFI_MEMORY_RO | EFI_MEMORY_XP + ); + + // + // Necessary fix for ProcessLibraryConstructorList() -> DxeCcProbeLibConstructor() + // + gCpu->SetUserMemoryAttributes ( + gCpu, + UserPageTable, + FixedPcdGet32 (PcdOvmfWorkAreaBase), + FixedPcdGet32 (PcdOvmfWorkAreaSize), + EFI_MEMORY_XP | EFI_MEMORY_USER + ); + } From 473b713f01ae8f292cf57fd713e4ee0859561692 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 27 Jan 2025 19:27:01 +0300 Subject: [PATCH 327/341] Core/Dxe: Added sanity checks. --- MdeModulePkg/Core/Dxe/Image/Image.c | 1 + .../Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c | 16 +++++++--------- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 16 +++++++--------- .../Core/Dxe/SysCall/IA32/InitializeIA32.c | 8 ++++++-- MdeModulePkg/Core/Dxe/SysCall/Initialization.c | 14 +++++++------- .../Core/Dxe/SysCall/X64/InitializeX64.c | 7 ++++--- 6 files changed, 32 insertions(+), 30 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 41b107cf9f..8cc871359b 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1701,6 +1701,7 @@ CoreStartImage ( if (gRing3Data == NULL) { Image->Status = InitializeRing3 (ImageHandle, Image); if (EFI_ERROR (Image->Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to initialize User address space - %r.\n", Image->Status)); CpuDeadLoop (); } } else { diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index 854f80301c..21e5865bc5 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -66,7 +66,7 @@ SysCallBootService ( return Status; } -VOID +EFI_STATUS EFIAPI MakeUserPageTableTemplate ( OUT UINTN *UserPageTableTemplate, @@ -77,9 +77,8 @@ MakeUserPageTableTemplate ( VOID *MemorySizeHob; MemorySizeHob = GetFirstGuidHob (&gArmVirtSystemMemorySizeGuid); - ASSERT (MemorySizeHob != NULL); if (MemorySizeHob == NULL) { - return; + return EFI_NOT_FOUND; } Descriptor.PhysicalBase = PcdGet64 (PcdSystemMemoryBase); @@ -87,11 +86,11 @@ MakeUserPageTableTemplate ( Descriptor.Length = *(UINT64 *)GET_GUID_HOB_DATA (MemorySizeHob); Descriptor.Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK; - ArmMakeUserPageTableTemplate ( - &Descriptor, - UserPageTableTemplate, - UserPageTableTemplateSize - ); + return ArmMakeUserPageTableTemplate ( + &Descriptor, + UserPageTableTemplate, + UserPageTableTemplateSize + ); } EFI_STATUS @@ -118,7 +117,6 @@ InitializePlatform ( &Physical ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index dd0bc1c51f..37c5e55b9a 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -93,7 +93,7 @@ SysCallBootService ( return Status; } -VOID +EFI_STATUS EFIAPI MakeUserPageTableTemplate ( OUT UINTN *UserPageTableTemplate, @@ -104,9 +104,8 @@ MakeUserPageTableTemplate ( VOID *MemorySizeHob; MemorySizeHob = GetFirstGuidHob (&gArmVirtSystemMemorySizeGuid); - ASSERT (MemorySizeHob != NULL); if (MemorySizeHob == NULL) { - return; + return EFI_NOT_FOUND; } Descriptor.PhysicalBase = PcdGet64 (PcdSystemMemoryBase); @@ -114,11 +113,11 @@ MakeUserPageTableTemplate ( Descriptor.Length = *(UINT64 *)GET_GUID_HOB_DATA (MemorySizeHob); Descriptor.Attributes = ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK; - ArmMakeUserPageTableTemplate ( - &Descriptor, - UserPageTableTemplate, - UserPageTableTemplateSize - ); + return ArmMakeUserPageTableTemplate ( + &Descriptor, + UserPageTableTemplate, + UserPageTableTemplateSize + ); } EFI_STATUS @@ -143,7 +142,6 @@ InitializePlatform ( &Physical ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3 ConfigurationTable.\n")); return Status; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c index f9b615914a..dd9b34e284 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c @@ -12,7 +12,7 @@ extern EXCEPTION_ADDRESSES *mExceptionAddresses; -VOID +EFI_STATUS EFIAPI MakeUserPageTableTemplate ( OUT UINTN *UserPageTableTemplate, @@ -45,7 +45,9 @@ MakeUserPageTableTemplate ( TotalPagesNum = NumberOfPdpEntriesNeeded + 1; PageAddress = (UINTN)AllocatePages (TotalPagesNum); - ASSERT (PageAddress != 0); + if (PageAddress == 0) { + return EFI_OUT_OF_RESOURCES; + } PageMap = (VOID *)PageAddress; PageAddress += SIZE_4KB; @@ -87,6 +89,8 @@ MakeUserPageTableTemplate ( *UserPageTableTemplate = (UINTN)PageMap; *UserPageTableTemplateSize = EFI_PAGES_TO_SIZE (TotalPagesNum); + + return EFI_SUCCESS; } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index 7302ef6e49..ee9a256080 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -19,7 +19,7 @@ STATIC UEFI_IMAGE_RECORD *mDxeRing3; STATIC EFI_PHYSICAL_ADDRESS mCoreStackBase; STATIC UINT64 mCoreStackSize; -VOID +EFI_STATUS EFIAPI MakeUserPageTableTemplate ( OUT UINTN *UserPageTableTemplate, @@ -60,7 +60,6 @@ InitializeRing3 ( &Physical ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Data.\n")); return Status; } @@ -98,7 +97,6 @@ InitializeRing3 ( &Physical ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Core: Failed to allocate memory for Ring3Interfaces.\n")); CoreFreePages ( (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) @@ -150,6 +148,7 @@ InitializeUserPageTable ( IN LOADED_IMAGE_PRIVATE_DATA *Image ) { + EFI_STATUS Status; UINTN UserPageTable; UINTN UserPageTableSize; UEFI_IMAGE_RECORD_SEGMENT *ImageRecordSegment; @@ -157,10 +156,11 @@ InitializeUserPageTable ( UINT32 Index; UEFI_IMAGE_RECORD *UserImageRecord; - // - // TODO: Remove ASSERTs, add proper checks and return status. - // - MakeUserPageTableTemplate (&UserPageTable, &UserPageTableSize); + Status = MakeUserPageTableTemplate (&UserPageTable, &UserPageTableSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Core: Failed to initialize User page table - %r.\n", Status)); + CpuDeadLoop (); + } // // Map gRing3Data, gRing3Interfaces, DxeRing3 diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c index 9428f7fbb9..fe87433b83 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c @@ -13,7 +13,7 @@ extern EXCEPTION_ADDRESSES *mExceptionAddresses; -VOID +EFI_STATUS EFIAPI MakeUserPageTableTemplate ( OUT UINTN *UserPageTableTemplate, @@ -159,8 +159,7 @@ MakeUserPageTableTemplate ( BigPageAddress = (UINTN)AllocatePages (TotalPagesNum); if (BigPageAddress == 0) { - DEBUG ((DEBUG_ERROR, "Core: Could not allocate buffer for User page table.\n")); - CpuDeadLoop (); + return EFI_OUT_OF_RESOURCES; } // @@ -284,6 +283,8 @@ MakeUserPageTableTemplate ( *UserPageTableTemplate = (UINTN)PageMap; *UserPageTableTemplateSize = EFI_PAGES_TO_SIZE (TotalPagesNum); + + return EFI_SUCCESS; } EFI_STATUS From 9510702bbff2b12d4166f6f6aed3239e203b294c Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 28 Jan 2025 17:50:18 +0300 Subject: [PATCH 328/341] Ring3: Added Ring3AllocatePool() and Ring3FreePool(). --- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 4 +- MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h | 38 ++++++++++++ .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 62 +++++++++++++++++-- MdeModulePkg/Core/Dxe/Mem/Page.c | 2 + MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 14 +++-- MdePkg/Include/Uefi/UefiSpec.h | 4 ++ 6 files changed, 114 insertions(+), 10 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index 0090023f88..579d86f9df 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -26,8 +26,8 @@ EFI_BOOT_SERVICES mBootServices = { (EFI_ALLOCATE_PAGES)Ring3AllocatePages, // AllocatePages (EFI_FREE_PAGES)Ring3FreePages, // FreePages (EFI_GET_MEMORY_MAP)Ring3GetMemoryMap, // GetMemoryMap - (EFI_ALLOCATE_POOL)CoreAllocatePool, // AllocatePool - (EFI_FREE_POOL)CoreFreePool, // FreePool + (EFI_ALLOCATE_POOL)Ring3AllocatePool, // AllocatePool + (EFI_FREE_POOL)Ring3FreePool, // FreePool (EFI_CREATE_EVENT)Ring3CreateEvent, // CreateEvent (EFI_SET_TIMER)Ring3SetTimer, // SetTimer (EFI_WAIT_FOR_EVENT)Ring3WaitForEvent, // WaitForEvent diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h index 20d6fa15c3..77ba5e4e70 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h @@ -132,6 +132,44 @@ Ring3GetMemoryMap ( OUT UINT32 *DescriptorVersion ); +/** + Allocate pool of a particular type. + + @param PoolType Type of pool to allocate + @param Size The amount of pool to allocate + @param Buffer The address to return a pointer to the allocated + pool + + @retval EFI_INVALID_PARAMETER Buffer is NULL. + PoolType is in the range EfiMaxMemoryType..0x6FFFFFFF. + PoolType is EfiPersistentMemory. + @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. + @retval EFI_SUCCESS Pool successfully allocated. + +**/ +EFI_STATUS +EFIAPI +Ring3AllocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +/** + Frees pool. + + @param Buffer The allocated pool entry to free + + @retval EFI_INVALID_PARAMETER Buffer is not a valid value. + @retval EFI_SUCCESS Pool successfully freed. + +**/ +EFI_STATUS +EFIAPI +Ring3FreePool ( + IN VOID *Buffer + ); + /** Creates an event. diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 6cb6fd063d..8047fa314e 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -18,6 +18,34 @@ BOOLEAN mOnGuarding = FALSE; +STATIC UINTN mMemoryTypes[EfiMaxMemoryType]; +STATIC UINTN mNumberOfUsers = 0; + +STATIC +UINTN +EFIAPI +GetMemoryType ( + IN UINTN UserPageTable + ) +{ + UINTN Index; + + for (Index = 0; Index < mNumberOfUsers; ++Index) { + if (mMemoryTypes[Index] == UserPageTable) { + break; + } + } + + if (Index == mNumberOfUsers) { + ++mNumberOfUsers; + mMemoryTypes[Index] = UserPageTable; + } + + ASSERT (mNumberOfUsers <= EfiMaxMemoryType); + + return Index; +} + STATIC EFI_STATUS EFIAPI @@ -179,6 +207,32 @@ Ring3GetMemoryMap ( return EFI_UNSUPPORTED; } +EFI_STATUS +EFIAPI +Ring3AllocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ) +{ + UINTN CurrentUser; + + CurrentUser = (UINTN)SysCall (SysCallGetUserPageTable, 0); + + PoolType = GetMemoryType (CurrentUser); + + return CoreAllocatePool (PoolType, Size, Buffer); +} + +EFI_STATUS +EFIAPI +Ring3FreePool ( + IN VOID *Buffer + ) +{ + return CoreFreePool (Buffer); +} + EFI_STATUS EFIAPI Ring3CreateEvent ( @@ -606,7 +660,7 @@ Ring3LocateHandleBuffer ( && (Buffer != NULL) && (*Buffer != NULL)) { PoolSize = *NumberHandles * sizeof (EFI_HANDLE *); - Status = CoreAllocatePool (EfiRing3MemoryType, PoolSize, &Pool); + Status = Ring3AllocatePool (EfiRing3MemoryType, PoolSize, &Pool); if (EFI_ERROR (Status)) { return Status; } @@ -672,7 +726,7 @@ Ring3InstallMultipleProtocolInterfaces ( } VA_END (Marker); - Status = CoreAllocatePool ( + Status = Ring3AllocatePool ( EfiRing3MemoryType, NumberOfArguments * sizeof (VOID *), (VOID **)&Arguments @@ -695,8 +749,8 @@ Ring3InstallMultipleProtocolInterfaces ( Arguments ); - CoreFreePool (Arguments); - return Status; + Ring3FreePool (Arguments); + return Status; } EFI_STATUS diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index f479cea6b2..a06fdba62f 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -63,6 +63,7 @@ EFI_MEMORY_TYPE_STATISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = { { 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiPalCode { 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiPersistentMemory { 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiUnacceptedMemoryType + { 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiRing3MemoryType { 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE } // EfiMaxMemoryType }; @@ -86,6 +87,7 @@ EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1] = { { EfiPalCode, 0 }, { EfiPersistentMemory, 0 }, { EfiGcdMemoryTypeUnaccepted, 0 }, + { EfiRing3MemoryType, 0 }, { EfiMaxMemoryType, 0 } }; // diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 9b4b1f087e..7de1460e06 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -317,12 +317,11 @@ FreeUserSpaceDriver ( UserDriver = BASE_CR (Link, USER_SPACE_DRIVER, Link); if (UserDriver->CoreWrapper == CoreWrapper) { - break; + RemoveEntryList (&UserDriver->Link); + FreePool (UserDriver); + return; } } - - RemoveEntryList (&UserDriver->Link); - FreePool (UserDriver); } EFI_STATUS @@ -1457,6 +1456,13 @@ CallBootService ( FreePool ((VOID *)Argument5); } + break; + case SysCallGetUserPageTable: + // + // No Arguments + // + Status = (EFI_STATUS)gUserPageTable; + break; default: DEBUG ((DEBUG_ERROR, "Ring0: Unknown syscall type.\n")); diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index d793103325..26aba3d1a1 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2060,6 +2060,10 @@ typedef enum { SysCallUnicodeStrUpr, SysCallUnicodeFatToStr, SysCallUnicodeStrToFat, + // + // Helper functions + // + SysCallGetUserPageTable, SysCallMax } SYS_CALL_TYPE; From fbe1a16fc724d1be30d2e558125b71703407adc2 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 28 Jan 2025 17:55:57 +0300 Subject: [PATCH 329/341] Ring3: Fixed line endings. --- MdeModulePkg/Core/Dxe/Mem/Page.c | 148 +++---- MdeModulePkg/Include/Library/MemoryPoolLib.h | 402 +++++++++--------- .../Library/MemoryPoolLib/InternalPool.h | 248 +++++------ .../Library/MemoryPoolLib/MemoryPoolLib.inf | 80 ++-- MdeModulePkg/Library/MemoryPoolLib/Pool.c | 174 ++++---- 5 files changed, 526 insertions(+), 526 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index a06fdba62f..64596b9230 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -2183,80 +2183,80 @@ CoreGetMemoryMap ( return Status; } -/** - Internal function. Used by the pool functions to allocate pages - to back pool allocation requests. - - @param PoolType The type of memory for the new pool pages - @param NoPages No of pages to allocate - @param Granularity Bits to align. - @param NeedGuard Flag to indicate Guard page is needed or not - - @return The allocated memory, or NULL - -**/ -VOID * -CoreAllocatePoolPagesI ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN NoPages, - IN UINTN Granularity, - IN BOOLEAN NeedGuard - ) -{ - VOID *Buffer; - EFI_STATUS Status; - - Status = EfiAcquireLockOrFail (&gMemoryLock); - if (EFI_ERROR (Status)) { - return NULL; - } - - Buffer = CoreAllocatePoolPages (PoolType, NoPages, Granularity, NeedGuard); - CoreReleaseMemoryLock (); - - if (Buffer != NULL) { - if (NeedGuard) { - SetGuardForMemory ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, NoPages); - } - - ApplyMemoryProtectionPolicy ( - EfiConventionalMemory, - PoolType, - (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, - EFI_PAGES_TO_SIZE (NoPages) - ); - } - - return Buffer; -} - -/** - Internal function. Frees pool pages allocated via CoreAllocatePoolPagesI(). - - @param PoolType The type of memory for the pool pages - @param Memory The base address to free - @param NoPages The number of pages to free - -**/ -VOID -CoreFreePoolPagesI ( - IN EFI_MEMORY_TYPE PoolType, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages - ) -{ - CoreAcquireMemoryLock (); - CoreFreePoolPages (Memory, NoPages); - CoreReleaseMemoryLock (); - - GuardFreedPagesChecked (Memory, NoPages); - ApplyMemoryProtectionPolicy ( - PoolType, - EfiConventionalMemory, - (EFI_PHYSICAL_ADDRESS)(UINTN)Memory, - EFI_PAGES_TO_SIZE (NoPages) - ); -} +/** + Internal function. Used by the pool functions to allocate pages + to back pool allocation requests. + + @param PoolType The type of memory for the new pool pages + @param NoPages No of pages to allocate + @param Granularity Bits to align. + @param NeedGuard Flag to indicate Guard page is needed or not + + @return The allocated memory, or NULL + +**/ +VOID * +CoreAllocatePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN NoPages, + IN UINTN Granularity, + IN BOOLEAN NeedGuard + ) +{ + VOID *Buffer; + EFI_STATUS Status; + + Status = EfiAcquireLockOrFail (&gMemoryLock); + if (EFI_ERROR (Status)) { + return NULL; + } + + Buffer = CoreAllocatePoolPages (PoolType, NoPages, Granularity, NeedGuard); + CoreReleaseMemoryLock (); + + if (Buffer != NULL) { + if (NeedGuard) { + SetGuardForMemory ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, NoPages); + } + + ApplyMemoryProtectionPolicy ( + EfiConventionalMemory, + PoolType, + (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, + EFI_PAGES_TO_SIZE (NoPages) + ); + } + + return Buffer; +} + +/** + Internal function. Frees pool pages allocated via CoreAllocatePoolPagesI(). + + @param PoolType The type of memory for the pool pages + @param Memory The base address to free + @param NoPages The number of pages to free + +**/ +VOID +CoreFreePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ) +{ + CoreAcquireMemoryLock (); + CoreFreePoolPages (Memory, NoPages); + CoreReleaseMemoryLock (); + + GuardFreedPagesChecked (Memory, NoPages); + ApplyMemoryProtectionPolicy ( + PoolType, + EfiConventionalMemory, + (EFI_PHYSICAL_ADDRESS)(UINTN)Memory, + EFI_PAGES_TO_SIZE (NoPages) + ); +} /** Internal function. Frees guarded pool pages. diff --git a/MdeModulePkg/Include/Library/MemoryPoolLib.h b/MdeModulePkg/Include/Library/MemoryPoolLib.h index 787046f1de..9b3e5b257f 100644 --- a/MdeModulePkg/Include/Library/MemoryPoolLib.h +++ b/MdeModulePkg/Include/Library/MemoryPoolLib.h @@ -1,201 +1,201 @@ -/** @file - UEFI Memory pool management functions. - -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _MEMORY_POOL_LIB_H_ -#define _MEMORY_POOL_LIB_H_ - -#include - -// -// +---------------------------------------------------+ -// | 0..(EfiMaxMemoryType - 1) - Normal memory type | -// +---------------------------------------------------+ -// | EfiMaxMemoryType..0x6FFFFFFF - Invalid | -// +---------------------------------------------------+ -// | 0x70000000..0x7FFFFFFF - OEM reserved | -// +---------------------------------------------------+ -// | 0x80000000..0xFFFFFFFF - OS reserved | -// +---------------------------------------------------+ -// -#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 -#define MEMORY_TYPE_OS_RESERVED_MAX 0xFFFFFFFF -#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 -#define MEMORY_TYPE_OEM_RESERVED_MAX 0x7FFFFFFF - -// -// Memory type to guard (matching the related PCD definition) -// -#define GUARD_HEAP_TYPE_PAGE BIT0 -#define GUARD_HEAP_TYPE_POOL BIT1 -#define GUARD_HEAP_TYPE_FREED BIT4 -#define GUARD_HEAP_TYPE_ALL \ - (GUARD_HEAP_TYPE_PAGE|GUARD_HEAP_TYPE_POOL|GUARD_HEAP_TYPE_FREED) - -/** - Called to initialize the pool. - -**/ -VOID -CoreInitializePool ( - VOID - ); - -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreInternalAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ); - -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ); - -/** - Internal function to allocate pool of a particular type. - Caller must have the memory lock held - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param NeedGuard Flag to indicate Guard page is needed or not - - @return The allocate pool, or NULL - -**/ -VOID * -CoreAllocatePoolI ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - IN BOOLEAN NeedGuard - ); - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - @param PoolType Pointer to pool type - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreInternalFreePool ( - IN VOID *Buffer, - OUT EFI_MEMORY_TYPE *PoolType OPTIONAL - ); - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreFreePool ( - IN VOID *Buffer - ); - -/** - Internal function to free a pool entry. - Caller must have the memory lock held - - @param Buffer The allocated pool entry to free - @param PoolType Pointer to pool type - - @retval EFI_INVALID_PARAMETER Buffer not valid - @retval EFI_SUCCESS Buffer successfully freed. - -**/ -EFI_STATUS -CoreFreePoolI ( - IN VOID *Buffer, - OUT EFI_MEMORY_TYPE *PoolType OPTIONAL - ); - -/** - Check to see if the heap guard is enabled for page and/or pool allocation. - - @param[in] GuardType Specify the sub-type(s) of Heap Guard. - - @return TRUE/FALSE. -**/ -BOOLEAN -IsHeapGuardEnabled ( - UINT8 GuardType - ); - -/** - Check to see if the pool at the given address should be guarded or not. - - @param[in] MemoryType Pool type to check. - - - @return TRUE The given type of pool should be guarded. - @return FALSE The given type of pool should not be guarded. -**/ -BOOLEAN -IsPoolTypeToGuard ( - IN EFI_MEMORY_TYPE MemoryType - ); - -/** - Check to see if the memory at the given address should be guarded or not. - - @param[in] MemoryType Memory type to check. - @param[in] AllocateType Allocation type to check. - @param[in] PageOrPool Indicate a page allocation or pool allocation. - - - @return TRUE The given type of memory should be guarded. - @return FALSE The given type of memory should not be guarded. -**/ -BOOLEAN -IsMemoryTypeToGuard ( - IN EFI_MEMORY_TYPE MemoryType, - IN EFI_ALLOCATE_TYPE AllocateType, - IN UINT8 PageOrPool - ); - -#endif +/** @file + UEFI Memory pool management functions. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _MEMORY_POOL_LIB_H_ +#define _MEMORY_POOL_LIB_H_ + +#include + +// +// +---------------------------------------------------+ +// | 0..(EfiMaxMemoryType - 1) - Normal memory type | +// +---------------------------------------------------+ +// | EfiMaxMemoryType..0x6FFFFFFF - Invalid | +// +---------------------------------------------------+ +// | 0x70000000..0x7FFFFFFF - OEM reserved | +// +---------------------------------------------------+ +// | 0x80000000..0xFFFFFFFF - OS reserved | +// +---------------------------------------------------+ +// +#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 +#define MEMORY_TYPE_OS_RESERVED_MAX 0xFFFFFFFF +#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 +#define MEMORY_TYPE_OEM_RESERVED_MAX 0x7FFFFFFF + +// +// Memory type to guard (matching the related PCD definition) +// +#define GUARD_HEAP_TYPE_PAGE BIT0 +#define GUARD_HEAP_TYPE_POOL BIT1 +#define GUARD_HEAP_TYPE_FREED BIT4 +#define GUARD_HEAP_TYPE_ALL \ + (GUARD_HEAP_TYPE_PAGE|GUARD_HEAP_TYPE_POOL|GUARD_HEAP_TYPE_FREED) + +/** + Called to initialize the pool. + +**/ +VOID +CoreInitializePool ( + VOID + ); + +/** + Allocate pool of a particular type. + + @param PoolType Type of pool to allocate + @param Size The amount of pool to allocate + @param Buffer The address to return a pointer to the allocated + pool + + @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL + @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. + @retval EFI_SUCCESS Pool successfully allocated. + +**/ +EFI_STATUS +EFIAPI +CoreInternalAllocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +/** + Allocate pool of a particular type. + + @param PoolType Type of pool to allocate + @param Size The amount of pool to allocate + @param Buffer The address to return a pointer to the allocated + pool + + @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL + @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. + @retval EFI_SUCCESS Pool successfully allocated. + +**/ +EFI_STATUS +EFIAPI +CoreAllocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +/** + Internal function to allocate pool of a particular type. + Caller must have the memory lock held + + @param PoolType Type of pool to allocate + @param Size The amount of pool to allocate + @param NeedGuard Flag to indicate Guard page is needed or not + + @return The allocate pool, or NULL + +**/ +VOID * +CoreAllocatePoolI ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + IN BOOLEAN NeedGuard + ); + +/** + Frees pool. + + @param Buffer The allocated pool entry to free + @param PoolType Pointer to pool type + + @retval EFI_INVALID_PARAMETER Buffer is not a valid value. + @retval EFI_SUCCESS Pool successfully freed. + +**/ +EFI_STATUS +EFIAPI +CoreInternalFreePool ( + IN VOID *Buffer, + OUT EFI_MEMORY_TYPE *PoolType OPTIONAL + ); + +/** + Frees pool. + + @param Buffer The allocated pool entry to free + + @retval EFI_INVALID_PARAMETER Buffer is not a valid value. + @retval EFI_SUCCESS Pool successfully freed. + +**/ +EFI_STATUS +EFIAPI +CoreFreePool ( + IN VOID *Buffer + ); + +/** + Internal function to free a pool entry. + Caller must have the memory lock held + + @param Buffer The allocated pool entry to free + @param PoolType Pointer to pool type + + @retval EFI_INVALID_PARAMETER Buffer not valid + @retval EFI_SUCCESS Buffer successfully freed. + +**/ +EFI_STATUS +CoreFreePoolI ( + IN VOID *Buffer, + OUT EFI_MEMORY_TYPE *PoolType OPTIONAL + ); + +/** + Check to see if the heap guard is enabled for page and/or pool allocation. + + @param[in] GuardType Specify the sub-type(s) of Heap Guard. + + @return TRUE/FALSE. +**/ +BOOLEAN +IsHeapGuardEnabled ( + UINT8 GuardType + ); + +/** + Check to see if the pool at the given address should be guarded or not. + + @param[in] MemoryType Pool type to check. + + + @return TRUE The given type of pool should be guarded. + @return FALSE The given type of pool should not be guarded. +**/ +BOOLEAN +IsPoolTypeToGuard ( + IN EFI_MEMORY_TYPE MemoryType + ); + +/** + Check to see if the memory at the given address should be guarded or not. + + @param[in] MemoryType Memory type to check. + @param[in] AllocateType Allocation type to check. + @param[in] PageOrPool Indicate a page allocation or pool allocation. + + + @return TRUE The given type of memory should be guarded. + @return FALSE The given type of memory should not be guarded. +**/ +BOOLEAN +IsMemoryTypeToGuard ( + IN EFI_MEMORY_TYPE MemoryType, + IN EFI_ALLOCATE_TYPE AllocateType, + IN UINT8 PageOrPool + ); + +#endif diff --git a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h index e800fd7acb..b69977cd9e 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h +++ b/MdeModulePkg/Library/MemoryPoolLib/InternalPool.h @@ -1,124 +1,124 @@ -/** @file - DXE Core functions necessary for pool management functions. - - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - - Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _INTERNAL_POOL_H_ -#define _INTERNAL_POOL_H_ - -extern BOOLEAN mOnGuarding; - -/** - Update memory profile information. - - @param CallerAddress Address of caller who call Allocate or Free. - @param Action This Allocate or Free action. - @param MemoryType Memory type. - EfiMaxMemoryType means the MemoryType is unknown. - @param Size Buffer size. - @param Buffer Buffer address. - @param ActionString String for memory profile action. - Only needed for user defined allocate action. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required, - or memory profile for the memory type is not required. - @return EFI_ACCESS_DENIED It is during memory profile data getting. - @return EFI_ABORTED Memory profile recording is not enabled. - @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. - @return EFI_NOT_FOUND No matched allocate info found for free action. - -**/ -EFI_STATUS -EFIAPI -CoreUpdateProfile ( - IN EFI_PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool - IN VOID *Buffer, - IN CHAR8 *ActionString OPTIONAL - ); - -/** - Install MemoryAttributesTable on memory allocation. - - @param[in] MemoryType EFI memory type. -**/ -VOID -InstallMemoryAttributesTableOnMemoryAllocation ( - IN EFI_MEMORY_TYPE MemoryType - ); - -/** - Internal function. Frees guarded pool pages. - - @param PoolType The type of memory for the pool pages - @param Memory The base address to free - @param NoPages The number of pages to free - -**/ -VOID -CoreFreePoolPagesWithGuard ( - IN EFI_MEMORY_TYPE PoolType, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages - ); - -/** - Check to see if the page at the given address is guarded or not. - - @param[in] Address The address to check for. - - @return TRUE The page at Address is guarded. - @return FALSE The page at Address is not guarded. -**/ -BOOLEAN -EFIAPI -IsMemoryGuarded ( - IN EFI_PHYSICAL_ADDRESS Address - ); - -/** - Internal function. Used by the pool functions to allocate pages - to back pool allocation requests. - - @param PoolType The type of memory for the new pool pages - @param NoPages No of pages to allocate - @param Granularity Bits to align. - @param NeedGuard Flag to indicate Guard page is needed or not - - @return The allocated memory, or NULL - -**/ -VOID * -CoreAllocatePoolPagesI ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN NoPages, - IN UINTN Granularity, - IN BOOLEAN NeedGuard - ); - -/** - Internal function. Frees pool pages allocated via CoreAllocatePoolPagesI(). - - @param PoolType The type of memory for the pool pages - @param Memory The base address to free - @param NoPages The number of pages to free - -**/ -VOID -CoreFreePoolPagesI ( - IN EFI_MEMORY_TYPE PoolType, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages - ); - -#endif +/** @file + DXE Core functions necessary for pool management functions. + + Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + + Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _INTERNAL_POOL_H_ +#define _INTERNAL_POOL_H_ + +extern BOOLEAN mOnGuarding; + +/** + Update memory profile information. + + @param CallerAddress Address of caller who call Allocate or Free. + @param Action This Allocate or Free action. + @param MemoryType Memory type. + EfiMaxMemoryType means the MemoryType is unknown. + @param Size Buffer size. + @param Buffer Buffer address. + @param ActionString String for memory profile action. + Only needed for user defined allocate action. + + @return EFI_SUCCESS Memory profile is updated. + @return EFI_UNSUPPORTED Memory profile is unsupported, + or memory profile for the image is not required, + or memory profile for the memory type is not required. + @return EFI_ACCESS_DENIED It is during memory profile data getting. + @return EFI_ABORTED Memory profile recording is not enabled. + @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. + @return EFI_NOT_FOUND No matched allocate info found for free action. + +**/ +EFI_STATUS +EFIAPI +CoreUpdateProfile ( + IN EFI_PHYSICAL_ADDRESS CallerAddress, + IN MEMORY_PROFILE_ACTION Action, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool + IN VOID *Buffer, + IN CHAR8 *ActionString OPTIONAL + ); + +/** + Install MemoryAttributesTable on memory allocation. + + @param[in] MemoryType EFI memory type. +**/ +VOID +InstallMemoryAttributesTableOnMemoryAllocation ( + IN EFI_MEMORY_TYPE MemoryType + ); + +/** + Internal function. Frees guarded pool pages. + + @param PoolType The type of memory for the pool pages + @param Memory The base address to free + @param NoPages The number of pages to free + +**/ +VOID +CoreFreePoolPagesWithGuard ( + IN EFI_MEMORY_TYPE PoolType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ); + +/** + Check to see if the page at the given address is guarded or not. + + @param[in] Address The address to check for. + + @return TRUE The page at Address is guarded. + @return FALSE The page at Address is not guarded. +**/ +BOOLEAN +EFIAPI +IsMemoryGuarded ( + IN EFI_PHYSICAL_ADDRESS Address + ); + +/** + Internal function. Used by the pool functions to allocate pages + to back pool allocation requests. + + @param PoolType The type of memory for the new pool pages + @param NoPages No of pages to allocate + @param Granularity Bits to align. + @param NeedGuard Flag to indicate Guard page is needed or not + + @return The allocated memory, or NULL + +**/ +VOID * +CoreAllocatePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN NoPages, + IN UINTN Granularity, + IN BOOLEAN NeedGuard + ); + +/** + Internal function. Frees pool pages allocated via CoreAllocatePoolPagesI(). + + @param PoolType The type of memory for the pool pages + @param Memory The base address to free + @param NoPages The number of pages to free + +**/ +VOID +CoreFreePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ); + +#endif diff --git a/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf b/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf index acc7c606be..4943e6242b 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf +++ b/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf @@ -1,40 +1,40 @@ -## @file -# UEFI Memory pool management functions. -# -# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = MemoryPoolLib - FILE_GUID = 084a3534-da19-435e-8eeb-be08237ed403 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = MemoryPoolLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER - -# -# VALID_ARCHITECTURES = IA32 X64 EBC -# - -[Sources] - InternalPool.h - Pool.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - BaseLib - DebugLib - PcdLib - UefiBootServicesTableLib - UefiLib - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES +## @file +# UEFI Memory pool management functions. +# +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MemoryPoolLib + FILE_GUID = 084a3534-da19-435e-8eeb-be08237ed403 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = MemoryPoolLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + InternalPool.h + Pool.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + PcdLib + UefiBootServicesTableLib + UefiLib + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES diff --git a/MdeModulePkg/Library/MemoryPoolLib/Pool.c b/MdeModulePkg/Library/MemoryPoolLib/Pool.c index 19cb969d51..47d744c052 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/Pool.c +++ b/MdeModulePkg/Library/MemoryPoolLib/Pool.c @@ -841,90 +841,90 @@ CoreFreePoolI ( return EFI_SUCCESS; } -/** - Check to see if the heap guard is enabled for page and/or pool allocation. - - @param[in] GuardType Specify the sub-type(s) of Heap Guard. - - @return TRUE/FALSE. -**/ -BOOLEAN -IsHeapGuardEnabled ( - UINT8 GuardType - ) -{ - return IsMemoryTypeToGuard (EfiMaxMemoryType, AllocateAnyPages, GuardType); -} - -/** - Check to see if the pool at the given address should be guarded or not. - - @param[in] MemoryType Pool type to check. - - - @return TRUE The given type of pool should be guarded. - @return FALSE The given type of pool should not be guarded. -**/ -BOOLEAN -IsPoolTypeToGuard ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - return IsMemoryTypeToGuard ( - MemoryType, - AllocateAnyPages, - GUARD_HEAP_TYPE_POOL - ); -} - -/** - Check to see if the memory at the given address should be guarded or not. - - @param[in] MemoryType Memory type to check. - @param[in] AllocateType Allocation type to check. - @param[in] PageOrPool Indicate a page allocation or pool allocation. - - - @return TRUE The given type of memory should be guarded. - @return FALSE The given type of memory should not be guarded. -**/ -BOOLEAN -IsMemoryTypeToGuard ( - IN EFI_MEMORY_TYPE MemoryType, - IN EFI_ALLOCATE_TYPE AllocateType, - IN UINT8 PageOrPool - ) -{ - UINT64 TestBit; - UINT64 ConfigBit; - - if (AllocateType == AllocateAddress) { - return FALSE; - } - - if ((PcdGet8 (PcdHeapGuardPropertyMask) & PageOrPool) == 0) { - return FALSE; - } - - if (PageOrPool == GUARD_HEAP_TYPE_POOL) { - ConfigBit = PcdGet64 (PcdHeapGuardPoolType); - } else if (PageOrPool == GUARD_HEAP_TYPE_PAGE) { - ConfigBit = PcdGet64 (PcdHeapGuardPageType); - } else { - ConfigBit = (UINT64)-1; - } - - if ((UINT32)MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) { - TestBit = BIT63; - } else if ((UINT32)MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) { - TestBit = BIT62; - } else if (MemoryType < EfiMaxMemoryType) { - TestBit = LShiftU64 (1, MemoryType); - } else if (MemoryType == EfiMaxMemoryType) { - TestBit = (UINT64)-1; - } else { - TestBit = 0; - } - - return ((ConfigBit & TestBit) != 0); -} +/** + Check to see if the heap guard is enabled for page and/or pool allocation. + + @param[in] GuardType Specify the sub-type(s) of Heap Guard. + + @return TRUE/FALSE. +**/ +BOOLEAN +IsHeapGuardEnabled ( + UINT8 GuardType + ) +{ + return IsMemoryTypeToGuard (EfiMaxMemoryType, AllocateAnyPages, GuardType); +} + +/** + Check to see if the pool at the given address should be guarded or not. + + @param[in] MemoryType Pool type to check. + + + @return TRUE The given type of pool should be guarded. + @return FALSE The given type of pool should not be guarded. +**/ +BOOLEAN +IsPoolTypeToGuard ( + IN EFI_MEMORY_TYPE MemoryType + ) +{ + return IsMemoryTypeToGuard ( + MemoryType, + AllocateAnyPages, + GUARD_HEAP_TYPE_POOL + ); +} + +/** + Check to see if the memory at the given address should be guarded or not. + + @param[in] MemoryType Memory type to check. + @param[in] AllocateType Allocation type to check. + @param[in] PageOrPool Indicate a page allocation or pool allocation. + + + @return TRUE The given type of memory should be guarded. + @return FALSE The given type of memory should not be guarded. +**/ +BOOLEAN +IsMemoryTypeToGuard ( + IN EFI_MEMORY_TYPE MemoryType, + IN EFI_ALLOCATE_TYPE AllocateType, + IN UINT8 PageOrPool + ) +{ + UINT64 TestBit; + UINT64 ConfigBit; + + if (AllocateType == AllocateAddress) { + return FALSE; + } + + if ((PcdGet8 (PcdHeapGuardPropertyMask) & PageOrPool) == 0) { + return FALSE; + } + + if (PageOrPool == GUARD_HEAP_TYPE_POOL) { + ConfigBit = PcdGet64 (PcdHeapGuardPoolType); + } else if (PageOrPool == GUARD_HEAP_TYPE_PAGE) { + ConfigBit = PcdGet64 (PcdHeapGuardPageType); + } else { + ConfigBit = (UINT64)-1; + } + + if ((UINT32)MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) { + TestBit = BIT63; + } else if ((UINT32)MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) { + TestBit = BIT62; + } else if (MemoryType < EfiMaxMemoryType) { + TestBit = LShiftU64 (1, MemoryType); + } else if (MemoryType == EfiMaxMemoryType) { + TestBit = (UINT64)-1; + } else { + TestBit = 0; + } + + return ((ConfigBit & TestBit) != 0); +} From 7bc7b80da1c639454ad99b0ed263c6ee3a41f89d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 30 Jan 2025 14:04:09 +0300 Subject: [PATCH 330/341] DefaultExceptionHandlerLib/AArch64: Added selection of the correct stack for DEBUG printings. --- .../AArch64/DefaultExceptionHandler.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index 8f875c9e44..e2a32fe15f 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -208,6 +208,7 @@ DefaultExceptionHandler ( CHAR16 UnicodeBuffer[MAX_PRINT_CHARS]; UINTN CharCount; INT32 Offset; + UINT64 StackPointer; if (AARCH64_ESR_EC (SystemContext.SystemContextAArch64->ESR) == AARCH64_ESR_EC_SVC64) { return mSysCallHandler (SystemContext); @@ -305,6 +306,12 @@ DefaultExceptionHandler ( DEBUG_CODE_END (); + if ((SystemContext.SystemContextAArch64->SPSR & 0xFULL) == 0) { + StackPointer = SystemContext.SystemContextAArch64->SP_EL0; + } else { + StackPointer = SystemContext.SystemContextAArch64->SP; + } + DEBUG ((DEBUG_ERROR, "\n X0 0x%016lx X1 0x%016lx X2 0x%016lx X3 0x%016lx\n", SystemContext.SystemContextAArch64->X0, SystemContext.SystemContextAArch64->X1, SystemContext.SystemContextAArch64->X2, SystemContext.SystemContextAArch64->X3)); DEBUG ((DEBUG_ERROR, " X4 0x%016lx X5 0x%016lx X6 0x%016lx X7 0x%016lx\n", SystemContext.SystemContextAArch64->X4, SystemContext.SystemContextAArch64->X5, SystemContext.SystemContextAArch64->X6, SystemContext.SystemContextAArch64->X7)); DEBUG ((DEBUG_ERROR, " X8 0x%016lx X9 0x%016lx X10 0x%016lx X11 0x%016lx\n", SystemContext.SystemContextAArch64->X8, SystemContext.SystemContextAArch64->X9, SystemContext.SystemContextAArch64->X10, SystemContext.SystemContextAArch64->X11)); @@ -333,7 +340,7 @@ DefaultExceptionHandler ( DEBUG ((DEBUG_ERROR, " V28 0x%016lx %016lx V29 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V28[1], SystemContext.SystemContextAArch64->V28[0], SystemContext.SystemContextAArch64->V29[1], SystemContext.SystemContextAArch64->V29[0])); DEBUG ((DEBUG_ERROR, " V30 0x%016lx %016lx V31 0x%016lx %016lx\n", SystemContext.SystemContextAArch64->V30[1], SystemContext.SystemContextAArch64->V30[0], SystemContext.SystemContextAArch64->V31[1], SystemContext.SystemContextAArch64->V31[0])); - DEBUG ((DEBUG_ERROR, "\n SP 0x%016lx ELR 0x%016lx SPSR 0x%08lx FPSR 0x%08lx\n ESR 0x%08lx FAR 0x%016lx\n", SystemContext.SystemContextAArch64->SP, SystemContext.SystemContextAArch64->ELR, SystemContext.SystemContextAArch64->SPSR, SystemContext.SystemContextAArch64->FPSR, SystemContext.SystemContextAArch64->ESR, SystemContext.SystemContextAArch64->FAR)); + DEBUG ((DEBUG_ERROR, "\n SP 0x%016lx ELR 0x%016lx SPSR 0x%08lx FPSR 0x%08lx\n ESR 0x%08lx FAR 0x%016lx\n", StackPointer, SystemContext.SystemContextAArch64->ELR, SystemContext.SystemContextAArch64->SPSR, SystemContext.SystemContextAArch64->FPSR, SystemContext.SystemContextAArch64->ESR, SystemContext.SystemContextAArch64->FAR)); DEBUG ((DEBUG_ERROR, "\n ESR : EC 0x%02x IL 0x%x ISS 0x%08x\n", (SystemContext.SystemContextAArch64->ESR & 0xFC000000) >> 26, (SystemContext.SystemContextAArch64->ESR >> 25) & 0x1, SystemContext.SystemContextAArch64->ESR & 0x1FFFFFF)); @@ -345,11 +352,11 @@ DefaultExceptionHandler ( DEBUG_ERROR, "%c %013lx: %016lx %016lx %016lx %016lx\n", Offset == 0 ? '>' : ' ', - SystemContext.SystemContextAArch64->SP + Offset, - *(UINT64 *)(SystemContext.SystemContextAArch64->SP + Offset), - *(UINT64 *)(SystemContext.SystemContextAArch64->SP + Offset + 8), - *(UINT64 *)(SystemContext.SystemContextAArch64->SP + Offset + 16), - *(UINT64 *)(SystemContext.SystemContextAArch64->SP + Offset + 24) + StackPointer + Offset, + *(UINT64 *)(StackPointer + Offset), + *(UINT64 *)(StackPointer + Offset + 8), + *(UINT64 *)(StackPointer + Offset + 16), + *(UINT64 *)(StackPointer + Offset + 24) )); } From 6f01e23cbc6161ee70a7a7e3f70c45d8affaec2c Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 30 Jan 2025 14:06:15 +0300 Subject: [PATCH 331/341] Ring3: Fixed bug in Uart initialization. --- .../Library/DebugLibFdtPL011Uart/User.c | 3 +- .../Core/Dxe/SysCall/Initialization.c | 28 +++++++++---------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c index 6e012ee85b..2229cffde0 100644 --- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c @@ -29,10 +29,11 @@ DebugLibFdtPL011UartUserConstructor ( for (Index = 0; Index < SystemTable->NumberOfTableEntries; ++Index) { if (CompareGuid (&gEarlyPL011BaseAddressGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) { mDebugLibFdtPL011UartAddress = (UINTN)SystemTable->ConfigurationTable[Index].VendorTable; + return EFI_SUCCESS; } } - return EFI_SUCCESS; + return EFI_NOT_FOUND; } /** diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index ee9a256080..b3a731ce63 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -73,6 +73,15 @@ InitializeRing3 ( EFI_MEMORY_XP | EFI_MEMORY_USER ); + Status = InitializePlatform (&gRing3Data->SystemTable); + if (EFI_ERROR (Status)) { + CoreFreePages ( + (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, + EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + ); + return Status; + } + // // Initialize DxeRing3 with Supervisor privileges. // @@ -81,14 +90,16 @@ InitializeRing3 ( SetUefiImageProtectionAttributes (mDxeRing3, FALSE); + AllowSupervisorAccessToUserMemory (); Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); - SetUefiImageProtectionAttributes (mDxeRing3, TRUE); - gRing3EntryPoint = gRing3Data->EntryPoint; gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; gRing3Data->SystemTable.RuntimeServices = gRing3Data->RuntimeServices; + ForbidSupervisorAccessToUserMemory (); + + SetUefiImageProtectionAttributes (mDxeRing3, TRUE); Status = CoreAllocatePages ( AllocateAnyPages, @@ -112,19 +123,6 @@ InitializeRing3 ( EFI_MEMORY_XP | EFI_MEMORY_USER ); - Status = InitializePlatform (&gRing3Data->SystemTable); - if (EFI_ERROR (Status)) { - CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, - EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) - ); - CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Interfaces, - RING3_INTERFACES_PAGES - ); - return Status; - } - mExceptionAddresses = GetExceptionAddresses (); PeiHob.Raw = GetHobList (); From 5c1604c7a8cc82ac934b9e8daec9c8b12a8e7d6a Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 30 Jan 2025 15:45:49 +0300 Subject: [PATCH 332/341] Ring3: Properly refactored MemoryPoolLib to support User spaces. --- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 2 +- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 14 ++++---- MdeModulePkg/Core/Dxe/Gcd/Gcd.c | 2 +- MdeModulePkg/Include/Library/MemoryPoolLib.h | 8 ++++- MdeModulePkg/Library/MemoryPoolLib/Pool.c | 34 ++++++++++++++----- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index 579d86f9df..5bbc706bf5 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -259,7 +259,7 @@ Ring3Initialization ( gBS = &mBootServices; gRT = &mRuntimeServices; - CoreInitializePool (); + CoreInitializePool (FALSE); return EFI_SUCCESS; } diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 8047fa314e..5cc2c3dc53 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -18,7 +18,7 @@ BOOLEAN mOnGuarding = FALSE; -STATIC UINTN mMemoryTypes[EfiMaxMemoryType]; +STATIC UINTN mMemoryTypes[MAX_MEMORY_TYPE]; STATIC UINTN mNumberOfUsers = 0; STATIC @@ -32,18 +32,16 @@ GetMemoryType ( for (Index = 0; Index < mNumberOfUsers; ++Index) { if (mMemoryTypes[Index] == UserPageTable) { - break; + return Index; } } - if (Index == mNumberOfUsers) { - ++mNumberOfUsers; - mMemoryTypes[Index] = UserPageTable; - } + ASSERT (mNumberOfUsers < MAX_MEMORY_TYPE); - ASSERT (mNumberOfUsers <= EfiMaxMemoryType); + mMemoryTypes[mNumberOfUsers] = UserPageTable; + ++mNumberOfUsers; - return Index; + return (mNumberOfUsers - 1); } STATIC diff --git a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c index 301e54f5ca..5cc6a0997e 100644 --- a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c +++ b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c @@ -2269,7 +2269,7 @@ CoreInitializeMemoryServices ( // Initialize the spin locks and maps in the memory services. // Also fill in the memory services into the EFI Boot Services Table // - CoreInitializePool (); + CoreInitializePool (TRUE); // // Initialize Local Variables diff --git a/MdeModulePkg/Include/Library/MemoryPoolLib.h b/MdeModulePkg/Include/Library/MemoryPoolLib.h index 9b3e5b257f..c3ee7c8e62 100644 --- a/MdeModulePkg/Include/Library/MemoryPoolLib.h +++ b/MdeModulePkg/Include/Library/MemoryPoolLib.h @@ -36,13 +36,19 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define GUARD_HEAP_TYPE_ALL \ (GUARD_HEAP_TYPE_PAGE|GUARD_HEAP_TYPE_POOL|GUARD_HEAP_TYPE_FREED) +#define MAX_MEMORY_TYPE 100 + /** Called to initialize the pool. + @param IsCore Selects between the purposes of mPoolHead array. + In DxeCore each element describes EFI_MEMORY_TYPE. + In DxeRing3 each element describes User space. + **/ VOID CoreInitializePool ( - VOID + IN BOOLEAN IsCore ); /** diff --git a/MdeModulePkg/Library/MemoryPoolLib/Pool.c b/MdeModulePkg/Library/MemoryPoolLib/Pool.c index 47d744c052..190ea17f55 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/Pool.c +++ b/MdeModulePkg/Library/MemoryPoolLib/Pool.c @@ -80,7 +80,9 @@ typedef struct { // // Pool header for each memory type. // -POOL mPoolHead[EfiMaxMemoryType]; +POOL mPoolHead[MAX_MEMORY_TYPE]; + +STATIC BOOLEAN mIsCore; // // List of pool header to search for the appropriate memory type. @@ -185,12 +187,14 @@ GetPoolIndexFromSize ( **/ VOID CoreInitializePool ( - VOID + IN BOOLEAN IsCore ) { UINTN Type; UINTN Index; + mIsCore = IsCore; + for (Type = 0; Type < EfiMaxMemoryType; Type++) { mPoolHead[Type].Signature = 0; mPoolHead[Type].Used = 0; @@ -219,6 +223,14 @@ LookupPoolHead ( POOL *Pool; UINTN Index; + if (!mIsCore) { + if ((UINT32)MemoryType < MAX_MEMORY_TYPE) { + return &mPoolHead[MemoryType]; + } + + return NULL; + } + if ((UINT32)MemoryType < EfiMaxMemoryType) { return &mPoolHead[MemoryType]; } @@ -285,8 +297,8 @@ CoreInternalAllocatePool ( // // If it's not a valid type, fail it // - if (((PoolType >= EfiMaxMemoryType) && (PoolType < MEMORY_TYPE_OEM_RESERVED_MIN)) || - (PoolType == EfiConventionalMemory) || (PoolType == EfiPersistentMemory) || (PoolType == EfiUnacceptedMemoryType)) + if (mIsCore && (((PoolType >= EfiMaxMemoryType) && (PoolType < MEMORY_TYPE_OEM_RESERVED_MIN)) || + (PoolType == EfiConventionalMemory) || (PoolType == EfiPersistentMemory) || (PoolType == EfiUnacceptedMemoryType))) { return EFI_INVALID_PARAMETER; } @@ -395,10 +407,11 @@ CoreAllocatePoolI ( ASSERT_LOCKED (&mPoolMemoryLock); - if ((PoolType == EfiReservedMemoryType) || + if (mIsCore && + ((PoolType == EfiReservedMemoryType) || (PoolType == EfiACPIMemoryNVS) || (PoolType == EfiRuntimeServicesCode) || - (PoolType == EfiRuntimeServicesData)) + (PoolType == EfiRuntimeServicesData))) { Granularity = RUNTIME_PAGE_ALLOCATION_GRANULARITY; } else { @@ -724,10 +737,11 @@ CoreFreePoolI ( Pool->Used -= Size; DEBUG ((DEBUG_POOL, "FreePool: %p (len %lx) %,ld\n", Head->Data, (UINT64)(Head->Size - POOL_OVERHEAD), (UINT64)Pool->Used)); - if ((Head->Type == EfiReservedMemoryType) || + if (mIsCore && + ((Head->Type == EfiReservedMemoryType) || (Head->Type == EfiACPIMemoryNVS) || (Head->Type == EfiRuntimeServicesCode) || - (Head->Type == EfiRuntimeServicesData)) + (Head->Type == EfiRuntimeServicesData))) { Granularity = RUNTIME_PAGE_ALLOCATION_GRANULARITY; } else { @@ -898,6 +912,10 @@ IsMemoryTypeToGuard ( UINT64 TestBit; UINT64 ConfigBit; + if (!mIsCore) { + return FALSE; + } + if (AllocateType == AllocateAddress) { return FALSE; } From 629fca509866e7b642ee9ed85db4b4b820d1ce68 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Thu, 30 Jan 2025 18:36:01 +0300 Subject: [PATCH 333/341] Ring3: Prevented loading of DxeRing3 driver, when UserSpace is disabled. --- ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c | 3 +-- MdeModulePkg/Core/Dxe/Image/Image.c | 9 ++++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c index 2229cffde0..6e012ee85b 100644 --- a/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c +++ b/ArmVirtPkg/Library/DebugLibFdtPL011Uart/User.c @@ -29,11 +29,10 @@ DebugLibFdtPL011UartUserConstructor ( for (Index = 0; Index < SystemTable->NumberOfTableEntries; ++Index) { if (CompareGuid (&gEarlyPL011BaseAddressGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) { mDebugLibFdtPL011UartAddress = (UINTN)SystemTable->ConfigurationTable[Index].VendorTable; - return EFI_SUCCESS; } } - return EFI_NOT_FOUND; + return EFI_SUCCESS; } /** diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index 8cc871359b..dfb7b3f6de 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -23,6 +23,7 @@ typedef struct { STATIC LIST_ENTRY mAvailableEmulators; STATIC EFI_EVENT mPeCoffEmuProtocolRegistrationEvent; STATIC VOID *mPeCoffEmuProtocolNotifyRegistration; +STATIC BOOLEAN mDxeRing3 = TRUE; extern BOOLEAN gBdsStarted; @@ -1348,6 +1349,12 @@ CoreLoadImageCommon ( Image->Info.ParentHandle = ParentImageHandle; Image->IsUserImage = (FileAttributes & EFI_FV_FILE_ATTRIB_USER) != 0; + if ((!PcdGetBool (PcdEnableUserSpace)) && Image->IsUserImage && mDxeRing3) { + mDxeRing3 = FALSE; + Status = EFI_NOT_STARTED; + goto Done; + } + if (NumberOfPages != NULL) { Image->NumberOfPages = *NumberOfPages; } else { @@ -1444,7 +1451,7 @@ CoreLoadImageCommon ( Status = EFI_SUCCESS; ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, Image->IsUserImage); - if ((gRing3Data != NULL) && Image->IsUserImage) { + if (PcdGetBool (PcdEnableUserSpace) && (gRing3Data != NULL) && Image->IsUserImage) { Image->UserPageTable = InitializeUserPageTable (Image); } From 0317b63e9b8c5ab5f6df119b06179c82457d7807 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 3 Feb 2025 12:26:31 +0300 Subject: [PATCH 334/341] Ring3: Added comments and sanity checks. --- MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 2 -- MdeModulePkg/Core/Dxe/Image/Image.c | 7 +++++++ .../Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c | 7 +++++++ MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c | 10 ++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index 5cc2c3dc53..a68e701aeb 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -67,8 +67,6 @@ FixInterface ( LoadedImage = (EFI_LOADED_IMAGE_PROTOCOL *)*Interface; - // TODO: Copy User changes to Core? Resembles InstallMultipleProtocolInterfaces(). - LoadedImage->Unload = NULL; } else if (CompareGuid (Protocol, &gEfiBlockIoProtocolGuid)) { diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index dfb7b3f6de..bf65545739 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -1350,6 +1350,9 @@ CoreLoadImageCommon ( Image->IsUserImage = (FileAttributes & EFI_FV_FILE_ATTRIB_USER) != 0; if ((!PcdGetBool (PcdEnableUserSpace)) && Image->IsUserImage && mDxeRing3) { + // + // Do not load DxeRing3 driver, if UserSpace is disabled. + // mDxeRing3 = FALSE; Status = EFI_NOT_STARTED; goto Done; @@ -1976,6 +1979,10 @@ CoreUnloadImage ( // Status = EFI_UNSUPPORTED; if (Image->Info.Unload != NULL) { + // + // TODO: If Image->IsUserImage, use FindInterface() to locate UserSpace + // EFI_LOADED_IMAGE_PROTOCOL->Unload() and GoToRing3(). + // Status = Image->Info.Unload (ImageHandle); } } else { diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index 21e5865bc5..dcdc159d78 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -37,11 +37,18 @@ SysCallBootService ( { EFI_STATUS Status; UINTN *UserArguments; + UINT64 Attributes; ArmEnableInterrupts (); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Context.SystemContextAArch64->SP_EL0, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + UserArguments = (UINTN *)(Context.SystemContextAArch64->SP_EL0 - 7 * sizeof (UINTN)); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArguments, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + AllowSupervisorAccessToUserMemory (); // // First 6 arguments are passed through X2-X7 and copied to Core stack, diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 37c5e55b9a..1b762628c6 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -38,6 +38,7 @@ SysCallBootService ( UINT8 Type; UINT8 NumberOfArguments; UINTN *UserArguments; + UINT64 Attributes; ArmEnableInterrupts (); @@ -52,6 +53,9 @@ SysCallBootService ( ++NumberOfArguments; } + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)Context.SystemContextArm->SP, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + AllowSupervisorAccessToUserMemory (); if (Type == SysCallFreePages) { // @@ -61,6 +65,9 @@ SysCallBootService ( // UserArguments = (UINTN *)(Context.SystemContextArm->SP - 2 * sizeof (UINTN)); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArguments, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + CopyMem ( (VOID *)UserArguments, (VOID *)&(Context.SystemContextArm->R1), @@ -73,6 +80,9 @@ SysCallBootService ( // UserArguments = (UINTN *)(Context.SystemContextArm->SP - 3 * sizeof (UINTN)); + gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)UserArguments, &Attributes); + ASSERT ((Attributes & EFI_MEMORY_USER) != 0); + CopyMem ( (VOID *)UserArguments, (VOID *)&(Context.SystemContextArm->R1), From e8a833eea1020a73c6c7e528cccd04529c8258a0 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 3 Feb 2025 13:49:40 +0300 Subject: [PATCH 335/341] Ring3: Renamed Ring3 as UserSpace. --- MdeModulePkg/Core/Dxe/DxeMain.h | 12 +- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 22 +- .../Core/Dxe/DxeRing3/AARCH64/SysCall.S | 12 +- MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S | 12 +- MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c | 160 ++++++------ MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf | 4 +- .../Core/Dxe/DxeRing3/IA32/SysCall.nasm | 14 +- MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h | 138 +++++----- .../Core/Dxe/DxeRing3/Ring3Protocols.c | 27 +- .../Core/Dxe/DxeRing3/Ring3UefiBootServices.c | 192 +++++++------- .../Dxe/DxeRing3/Ring3UefiRuntimeServices.c | 62 +++-- .../Core/Dxe/DxeRing3/X64/SysCall.nasm | 16 +- MdeModulePkg/Core/Dxe/Image/Image.c | 22 +- MdeModulePkg/Core/Dxe/Mem/Page.c | 4 +- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 4 +- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 12 +- .../Dxe/SysCall/AARCH64/InitializeAARCH64.c | 22 +- .../Core/Dxe/SysCall/ARM/CoreBootServices.S | 10 +- .../Core/Dxe/SysCall/ARM/InitializeARM.c | 22 +- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 112 ++++----- .../Dxe/SysCall/IA32/CoreBootServices.nasm | 20 +- .../Core/Dxe/SysCall/IA32/InitializeIA32.c | 4 +- .../Core/Dxe/SysCall/Initialization.c | 78 +++--- .../Core/Dxe/SysCall/SupportedProtocols.c | 238 +++++++++--------- .../Dxe/SysCall/X64/CoreBootServices.nasm | 20 +- .../Core/Dxe/SysCall/X64/InitializeX64.c | 2 +- MdeModulePkg/Include/Library/MemoryPoolLib.h | 2 +- MdePkg/Include/Uefi/UefiMultiPhase.h | 4 +- MdePkg/Include/Uefi/UefiSpec.h | 4 +- 29 files changed, 631 insertions(+), 620 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index cc4570f0b9..a29bde83f7 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -116,7 +116,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define DEPEX_STACK_SIZE_INCREMENT 0x1000 #define STACK_SIZE 0x20000 -#define RING3_INTERFACES_PAGES 20 +#define USER_SPACE_INTERFACES_PAGES 20 typedef struct { EFI_GUID *ProtocolGuid; @@ -280,9 +280,9 @@ extern EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE gLoadModuleAtFixAddressConfig extern BOOLEAN gLoadFixedAddressCodeMemoryReady; extern LOADED_IMAGE_PRIVATE_DATA * mCurrentImage; -extern RING3_DATA *gRing3Data; -extern VOID *gRing3Interfaces; -extern VOID *gRing3EntryPoint; +extern USER_SPACE_DATA *gUserSpaceData; +extern VOID *gUserSpaceInterfaces; +extern VOID *gUserSpaceEntryPoint; extern UINTN gUserPageTable; extern UINTN gCorePageTable; extern LIST_ENTRY gUserSpaceDriversHead; @@ -2765,7 +2765,7 @@ ForbidSupervisorAccessToUserMemory ( EFI_STATUS EFIAPI -GoToRing3 ( +GoToUserSpace ( IN UINT8 Number, IN VOID *EntryPoint, IN USER_SPACE_DRIVER *UserDriver, @@ -2774,7 +2774,7 @@ GoToRing3 ( EFI_STATUS EFIAPI -InitializeRing3 ( +InitializeUserSpace ( IN EFI_HANDLE ImageHandle, IN LOADED_IMAGE_PRIVATE_DATA *Image ); diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c index 18173ae0be..231556b50f 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c @@ -247,7 +247,7 @@ DxeMain ( EFI_VECTOR_HANDOFF_INFO *VectorInfoList; EFI_VECTOR_HANDOFF_INFO *VectorInfo; - gRing3Data = NULL; + gUserSpaceData = NULL; gUserPageTable = 0; // @@ -775,28 +775,28 @@ CoreExitBootServices ( EFI_STATUS Status; // - // Free resources allocated for Ring3. + // Free resources allocated for UserSpace. // - if (gRing3Data != NULL) { + if (gUserSpaceData != NULL) { AllowSupervisorAccessToUserMemory (); - if (gRing3Data->SystemTable.ConfigurationTable != NULL) { + if (gUserSpaceData->SystemTable.ConfigurationTable != NULL) { CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data->SystemTable.ConfigurationTable, - EFI_SIZE_TO_PAGES (gRing3Data->SystemTable.NumberOfTableEntries * sizeof (EFI_CONFIGURATION_TABLE)) + (EFI_PHYSICAL_ADDRESS)(UINTN)gUserSpaceData->SystemTable.ConfigurationTable, + EFI_SIZE_TO_PAGES (gUserSpaceData->SystemTable.NumberOfTableEntries * sizeof (EFI_CONFIGURATION_TABLE)) ); } ForbidSupervisorAccessToUserMemory (); CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, - EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + (EFI_PHYSICAL_ADDRESS)(UINTN)gUserSpaceData, + EFI_SIZE_TO_PAGES (sizeof (USER_SPACE_DATA)) ); - gRing3Data = NULL; + gUserSpaceData = NULL; CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Interfaces, - RING3_INTERFACES_PAGES + (EFI_PHYSICAL_ADDRESS)(UINTN)gUserSpaceInterfaces, + USER_SPACE_INTERFACES_PAGES ); FreeProtocolsList (); diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S index 47039d2940..1940441d71 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S @@ -1,11 +1,11 @@ //------------------------------------------------------------------------------ -// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. // SPDX-License-Identifier: BSD-3-Clause //------------------------------------------------------------------------------ #include -.extern ASM_PFX(Ring3Call) +.extern ASM_PFX(UserSpaceCall) //------------------------------------------------------------------------------ // EFI_STATUS @@ -23,11 +23,11 @@ ASM_FUNC(SysCall) //------------------------------------------------------------------------------ // VOID // EFIAPI -// Ring3EntryPoint ( -// IN RING3_CALL_DATA *Data +// UserSpaceEntryPoint ( +// IN USER_SPACE_CALL_DATA *Data // ); // // (x0) Data //------------------------------------------------------------------------------ -ASM_FUNC(Ring3EntryPoint) - b ASM_PFX(Ring3Call) +ASM_FUNC(UserSpaceEntryPoint) + b ASM_PFX(UserSpaceCall) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S index dee789fce5..e016a71b16 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S @@ -1,11 +1,11 @@ //------------------------------------------------------------------------------ -// Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +// Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. // SPDX-License-Identifier: BSD-3-Clause //------------------------------------------------------------------------------ #include -.extern ASM_PFX(Ring3Call) +.extern ASM_PFX(UserSpaceCall) //------------------------------------------------------------------------------ // EFI_STATUS @@ -23,11 +23,11 @@ ASM_FUNC(SysCall) //------------------------------------------------------------------------------ // VOID // EFIAPI -// Ring3EntryPoint ( -// IN RING3_CALL_DATA *Data +// UserSpaceEntryPoint ( +// IN USER_SPACE_CALL_DATA *Data // ); // // (r0) Data //------------------------------------------------------------------------------ -ASM_FUNC(Ring3EntryPoint) - b ASM_PFX(Ring3Call) +ASM_FUNC(UserSpaceEntryPoint) + b ASM_PFX(UserSpaceCall) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c index 5bbc706bf5..04dfef8d76 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c @@ -1,6 +1,8 @@ /** @file + This driver constructs User space wrappers for the EFI_BOOT_SERVICES, + EFI_RUNTIME_SERVICES and EFI_*_PROTOCOLs. - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause **/ @@ -15,86 +17,86 @@ EFI_BOOT_SERVICES mBootServices = { { - EFI_BOOT_SERVICES_SIGNATURE, // Signature - EFI_BOOT_SERVICES_REVISION, // Revision - sizeof (EFI_BOOT_SERVICES), // HeaderSize - 0, // CRC32 - 0 // Reserved + EFI_BOOT_SERVICES_SIGNATURE, // Signature + EFI_BOOT_SERVICES_REVISION, // Revision + sizeof (EFI_BOOT_SERVICES), // HeaderSize + 0, // CRC32 + 0 // Reserved }, - (EFI_RAISE_TPL)Ring3RaiseTpl, // RaiseTPL - (EFI_RESTORE_TPL)Ring3RestoreTpl, // RestoreTPL - (EFI_ALLOCATE_PAGES)Ring3AllocatePages, // AllocatePages - (EFI_FREE_PAGES)Ring3FreePages, // FreePages - (EFI_GET_MEMORY_MAP)Ring3GetMemoryMap, // GetMemoryMap - (EFI_ALLOCATE_POOL)Ring3AllocatePool, // AllocatePool - (EFI_FREE_POOL)Ring3FreePool, // FreePool - (EFI_CREATE_EVENT)Ring3CreateEvent, // CreateEvent - (EFI_SET_TIMER)Ring3SetTimer, // SetTimer - (EFI_WAIT_FOR_EVENT)Ring3WaitForEvent, // WaitForEvent - (EFI_SIGNAL_EVENT)Ring3SignalEvent, // SignalEvent - (EFI_CLOSE_EVENT)Ring3CloseEvent, // CloseEvent - (EFI_CHECK_EVENT)Ring3CheckEvent, // CheckEvent - (EFI_INSTALL_PROTOCOL_INTERFACE)Ring3InstallProtocolInterface, // InstallProtocolInterface - (EFI_REINSTALL_PROTOCOL_INTERFACE)Ring3ReinstallProtocolInterface, // ReinstallProtocolInterface - (EFI_UNINSTALL_PROTOCOL_INTERFACE)Ring3UninstallProtocolInterface, // UninstallProtocolInterface - (EFI_HANDLE_PROTOCOL)Ring3HandleProtocol, // HandleProtocol - (VOID *)NULL, // Reserved - (EFI_REGISTER_PROTOCOL_NOTIFY)Ring3RegisterProtocolNotify, // RegisterProtocolNotify - (EFI_LOCATE_HANDLE)Ring3LocateHandle, // LocateHandle - (EFI_LOCATE_DEVICE_PATH)Ring3LocateDevicePath, // LocateDevicePath - (EFI_INSTALL_CONFIGURATION_TABLE)Ring3InstallConfigurationTable, // InstallConfigurationTable - (EFI_IMAGE_LOAD)Ring3LoadImage, // LoadImage - (EFI_IMAGE_START)Ring3StartImage, // StartImage - (EFI_EXIT)Ring3Exit, // Exit - (EFI_IMAGE_UNLOAD)Ring3UnloadImage, // UnloadImage - (EFI_EXIT_BOOT_SERVICES)Ring3ExitBootServices, // ExitBootServices - (EFI_GET_NEXT_MONOTONIC_COUNT)Ring3GetNextMonotonicCount, // GetNextMonotonicCount - (EFI_STALL)Ring3Stall, // Stall - (EFI_SET_WATCHDOG_TIMER)Ring3SetWatchdogTimer, // SetWatchdogTimer - (EFI_CONNECT_CONTROLLER)Ring3ConnectController, // ConnectController - (EFI_DISCONNECT_CONTROLLER)Ring3DisconnectController, // DisconnectController - (EFI_OPEN_PROTOCOL)Ring3OpenProtocol, // OpenProtocol - (EFI_CLOSE_PROTOCOL)Ring3CloseProtocol, // CloseProtocol - (EFI_OPEN_PROTOCOL_INFORMATION)Ring3OpenProtocolInformation, // OpenProtocolInformation - (EFI_PROTOCOLS_PER_HANDLE)Ring3ProtocolsPerHandle, // ProtocolsPerHandle - (EFI_LOCATE_HANDLE_BUFFER)Ring3LocateHandleBuffer, // LocateHandleBuffer - (EFI_LOCATE_PROTOCOL)Ring3LocateProtocol, // LocateProtocol - (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3InstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces - (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)Ring3UninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces - (EFI_CALCULATE_CRC32)Ring3CalculateCrc32, // CalculateCrc32 - (EFI_COPY_MEM)CopyMem, // CopyMem - (EFI_SET_MEM)SetMem, // SetMem - (EFI_CREATE_EVENT_EX)Ring3CreateEventEx, // CreateEventEx + (EFI_RAISE_TPL)UserSpaceRaiseTpl, // RaiseTPL + (EFI_RESTORE_TPL)UserSpaceRestoreTpl, // RestoreTPL + (EFI_ALLOCATE_PAGES)UserSpaceAllocatePages, // AllocatePages + (EFI_FREE_PAGES)UserSpaceFreePages, // FreePages + (EFI_GET_MEMORY_MAP)UserSpaceGetMemoryMap, // GetMemoryMap + (EFI_ALLOCATE_POOL)UserSpaceAllocatePool, // AllocatePool + (EFI_FREE_POOL)UserSpaceFreePool, // FreePool + (EFI_CREATE_EVENT)UserSpaceCreateEvent, // CreateEvent + (EFI_SET_TIMER)UserSpaceSetTimer, // SetTimer + (EFI_WAIT_FOR_EVENT)UserSpaceWaitForEvent, // WaitForEvent + (EFI_SIGNAL_EVENT)UserSpaceSignalEvent, // SignalEvent + (EFI_CLOSE_EVENT)UserSpaceCloseEvent, // CloseEvent + (EFI_CHECK_EVENT)UserSpaceCheckEvent, // CheckEvent + (EFI_INSTALL_PROTOCOL_INTERFACE)UserSpaceInstallProtocolInterface, // InstallProtocolInterface + (EFI_REINSTALL_PROTOCOL_INTERFACE)UserSpaceReinstallProtocolInterface, // ReinstallProtocolInterface + (EFI_UNINSTALL_PROTOCOL_INTERFACE)UserSpaceUninstallProtocolInterface, // UninstallProtocolInterface + (EFI_HANDLE_PROTOCOL)UserSpaceHandleProtocol, // HandleProtocol + (VOID *)NULL, // Reserved + (EFI_REGISTER_PROTOCOL_NOTIFY)UserSpaceRegisterProtocolNotify, // RegisterProtocolNotify + (EFI_LOCATE_HANDLE)UserSpaceLocateHandle, // LocateHandle + (EFI_LOCATE_DEVICE_PATH)UserSpaceLocateDevicePath, // LocateDevicePath + (EFI_INSTALL_CONFIGURATION_TABLE)UserSpaceInstallConfigurationTable, // InstallConfigurationTable + (EFI_IMAGE_LOAD)UserSpaceLoadImage, // LoadImage + (EFI_IMAGE_START)UserSpaceStartImage, // StartImage + (EFI_EXIT)UserSpaceExit, // Exit + (EFI_IMAGE_UNLOAD)UserSpaceUnloadImage, // UnloadImage + (EFI_EXIT_BOOT_SERVICES)UserSpaceExitBootServices, // ExitBootServices + (EFI_GET_NEXT_MONOTONIC_COUNT)UserSpaceGetNextMonotonicCount, // GetNextMonotonicCount + (EFI_STALL)UserSpaceStall, // Stall + (EFI_SET_WATCHDOG_TIMER)UserSpaceSetWatchdogTimer, // SetWatchdogTimer + (EFI_CONNECT_CONTROLLER)UserSpaceConnectController, // ConnectController + (EFI_DISCONNECT_CONTROLLER)UserSpaceDisconnectController, // DisconnectController + (EFI_OPEN_PROTOCOL)UserSpaceOpenProtocol, // OpenProtocol + (EFI_CLOSE_PROTOCOL)UserSpaceCloseProtocol, // CloseProtocol + (EFI_OPEN_PROTOCOL_INFORMATION)UserSpaceOpenProtocolInformation, // OpenProtocolInformation + (EFI_PROTOCOLS_PER_HANDLE)UserSpaceProtocolsPerHandle, // ProtocolsPerHandle + (EFI_LOCATE_HANDLE_BUFFER)UserSpaceLocateHandleBuffer, // LocateHandleBuffer + (EFI_LOCATE_PROTOCOL)UserSpaceLocateProtocol, // LocateProtocol + (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)UserSpaceInstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces + (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)UserSpaceUninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces + (EFI_CALCULATE_CRC32)UserSpaceCalculateCrc32, // CalculateCrc32 + (EFI_COPY_MEM)CopyMem, // CopyMem + (EFI_SET_MEM)SetMem, // SetMem + (EFI_CREATE_EVENT_EX)UserSpaceCreateEventEx, // CreateEventEx }; EFI_RUNTIME_SERVICES mRuntimeServices = { { - EFI_RUNTIME_SERVICES_SIGNATURE, // Signature - EFI_RUNTIME_SERVICES_REVISION, // Revision - sizeof (EFI_RUNTIME_SERVICES), // HeaderSize - 0, // CRC32 - 0 // Reserved + EFI_RUNTIME_SERVICES_SIGNATURE, // Signature + EFI_RUNTIME_SERVICES_REVISION, // Revision + sizeof (EFI_RUNTIME_SERVICES), // HeaderSize + 0, // CRC32 + 0 // Reserved }, - (EFI_GET_TIME)Ring3GetTime, // GetTime - (EFI_SET_TIME)Ring3SetTime, // SetTime - (EFI_GET_WAKEUP_TIME)Ring3GetWakeupTime, // GetWakeupTime - (EFI_SET_WAKEUP_TIME)Ring3SetWakeupTime, // SetWakeupTime - (EFI_SET_VIRTUAL_ADDRESS_MAP)Ring3SetVirtualAddressMap, // SetVirtualAddressMap - (EFI_CONVERT_POINTER)Ring3ConvertPointer, // ConvertPointer - (EFI_GET_VARIABLE)Ring3GetVariable, // GetVariable - (EFI_GET_NEXT_VARIABLE_NAME)Ring3GetNextVariableName, // GetNextVariableName - (EFI_SET_VARIABLE)Ring3SetVariable, // SetVariable - (EFI_GET_NEXT_HIGH_MONO_COUNT)Ring3GetNextHighMonotonicCount, // GetNextHighMonotonicCount - (EFI_RESET_SYSTEM)Ring3ResetSystem, // ResetSystem - (EFI_UPDATE_CAPSULE)Ring3UpdateCapsule, // UpdateCapsule - (EFI_QUERY_CAPSULE_CAPABILITIES)Ring3QueryCapsuleCapabilities, // QueryCapsuleCapabilities - (EFI_QUERY_VARIABLE_INFO)Ring3QueryVariableInfo // QueryVariableInfo + (EFI_GET_TIME)UserSpaceGetTime, // GetTime + (EFI_SET_TIME)UserSpaceSetTime, // SetTime + (EFI_GET_WAKEUP_TIME)UserSpaceGetWakeupTime, // GetWakeupTime + (EFI_SET_WAKEUP_TIME)UserSpaceSetWakeupTime, // SetWakeupTime + (EFI_SET_VIRTUAL_ADDRESS_MAP)UserSpaceSetVirtualAddressMap, // SetVirtualAddressMap + (EFI_CONVERT_POINTER)UserSpaceConvertPointer, // ConvertPointer + (EFI_GET_VARIABLE)UserSpaceGetVariable, // GetVariable + (EFI_GET_NEXT_VARIABLE_NAME)UserSpaceGetNextVariableName, // GetNextVariableName + (EFI_SET_VARIABLE)UserSpaceSetVariable, // SetVariable + (EFI_GET_NEXT_HIGH_MONO_COUNT)UserSpaceGetNextHighMonotonicCount, // GetNextHighMonotonicCount + (EFI_RESET_SYSTEM)UserSpaceResetSystem, // ResetSystem + (EFI_UPDATE_CAPSULE)UserSpaceUpdateCapsule, // UpdateCapsule + (EFI_QUERY_CAPSULE_CAPABILITIES)UserSpaceQueryCapsuleCapabilities, // QueryCapsuleCapabilities + (EFI_QUERY_VARIABLE_INFO)UserSpaceQueryVariableInfo // QueryVariableInfo }; VOID EFIAPI -Ring3EntryPoint ( - IN RING3_CALL_DATA *Data +UserSpaceEntryPoint ( + IN USER_SPACE_CALL_DATA *Data ); typedef @@ -181,8 +183,8 @@ EFI_STATUS VOID EFIAPI -Ring3Call ( - IN RING3_CALL_DATA *Data +UserSpaceCall ( + IN USER_SPACE_CALL_DATA *Data ) { EFI_STATUS Status; @@ -243,18 +245,18 @@ Ring3Call ( EFI_STATUS EFIAPI -Ring3Initialization ( +UserSpaceInitialization ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { - RING3_DATA *Ring3Data; + USER_SPACE_DATA *UserSpaceData; - Ring3Data = (RING3_DATA *)SystemTable; + UserSpaceData = (USER_SPACE_DATA *)SystemTable; - Ring3Data->EntryPoint = (VOID *)Ring3EntryPoint; - Ring3Data->BootServices = &mBootServices; - Ring3Data->RuntimeServices = &mRuntimeServices; + UserSpaceData->EntryPoint = (VOID *)UserSpaceEntryPoint; + UserSpaceData->BootServices = &mBootServices; + UserSpaceData->RuntimeServices = &mRuntimeServices; gBS = &mBootServices; gRT = &mRuntimeServices; diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf index c4ba281f51..fd01cf0795 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf @@ -1,6 +1,6 @@ ## @file # -# Ring3 driver for SysCalls. +# UserSpace driver for SysCalls. # # Copyright (c) 2024, Mikhail Krichanov. All rights reserved. # SPDX-License-Identifier: BSD-3-Clause @@ -13,7 +13,7 @@ FILE_GUID = 88EA50C2-0DEA-4F13-B691-B506554E632B MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 - ENTRY_POINT = Ring3Initialization + ENTRY_POINT = UserSpaceInitialization # # The following information is for reference only and not required by the build tools. diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm index 7c12e57736..2618836cd4 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm @@ -1,11 +1,11 @@ ;------------------------------------------------------------------------------ -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. ; SPDX-License-Identifier: BSD-3-Clause ;------------------------------------------------------------------------------ #include -extern ASM_PFX(Ring3Call) +extern ASM_PFX(UserSpaceCall) DEFAULT REL SECTION .text @@ -49,14 +49,14 @@ userReturnAddress: ;------------------------------------------------------------------------------ ; VOID ; EFIAPI -; Ring3EntryPoint ( -; IN RING3_CALL_DATA *Data +; UserSpaceEntryPoint ( +; IN USER_SPACE_CALL_DATA *Data ; ); ; ; (eax) Data ;------------------------------------------------------------------------------ -global ASM_PFX(Ring3EntryPoint) -ASM_PFX(Ring3EntryPoint): +global ASM_PFX(UserSpaceEntryPoint) +ASM_PFX(UserSpaceEntryPoint): push eax - call ASM_PFX(Ring3Call) + call ASM_PFX(UserSpaceCall) diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h index 77ba5e4e70..08fd2c29de 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h @@ -1,6 +1,6 @@ /** @file - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause **/ @@ -30,7 +30,7 @@ SysCall ( **/ EFI_TPL EFIAPI -Ring3RaiseTpl ( +UserSpaceRaiseTpl ( IN EFI_TPL NewTpl ); @@ -43,7 +43,7 @@ Ring3RaiseTpl ( **/ VOID EFIAPI -Ring3RestoreTpl ( +UserSpaceRestoreTpl ( IN EFI_TPL NewTpl ); @@ -67,7 +67,7 @@ Ring3RestoreTpl ( **/ EFI_STATUS EFIAPI -Ring3AllocatePages ( +UserSpaceAllocatePages ( IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN NumberOfPages, @@ -87,7 +87,7 @@ Ring3AllocatePages ( **/ EFI_STATUS EFIAPI -Ring3FreePages ( +UserSpaceFreePages ( IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages ); @@ -124,7 +124,7 @@ Ring3FreePages ( **/ EFI_STATUS EFIAPI -Ring3GetMemoryMap ( +UserSpaceGetMemoryMap ( IN OUT UINTN *MemoryMapSize, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, OUT UINTN *MapKey, @@ -149,7 +149,7 @@ Ring3GetMemoryMap ( **/ EFI_STATUS EFIAPI -Ring3AllocatePool ( +UserSpaceAllocatePool ( IN EFI_MEMORY_TYPE PoolType, IN UINTN Size, OUT VOID **Buffer @@ -166,7 +166,7 @@ Ring3AllocatePool ( **/ EFI_STATUS EFIAPI -Ring3FreePool ( +UserSpaceFreePool ( IN VOID *Buffer ); @@ -190,7 +190,7 @@ Ring3FreePool ( **/ EFI_STATUS EFIAPI -Ring3CreateEvent ( +UserSpaceCreateEvent ( IN UINT32 Type, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, @@ -215,7 +215,7 @@ Ring3CreateEvent ( **/ EFI_STATUS EFIAPI -Ring3SetTimer ( +UserSpaceSetTimer ( IN EFI_EVENT UserEvent, IN EFI_TIMER_DELAY Type, IN UINT64 TriggerTime @@ -237,7 +237,7 @@ Ring3SetTimer ( **/ EFI_STATUS EFIAPI -Ring3WaitForEvent ( +UserSpaceWaitForEvent ( IN UINTN NumberOfEvents, IN EFI_EVENT *UserEvents, OUT UINTN *UserIndex @@ -254,7 +254,7 @@ Ring3WaitForEvent ( **/ EFI_STATUS EFIAPI -Ring3SignalEvent ( +UserSpaceSignalEvent ( IN EFI_EVENT UserEvent ); @@ -269,7 +269,7 @@ Ring3SignalEvent ( **/ EFI_STATUS EFIAPI -Ring3CloseEvent ( +UserSpaceCloseEvent ( IN EFI_EVENT UserEvent ); @@ -285,7 +285,7 @@ Ring3CloseEvent ( **/ EFI_STATUS EFIAPI -Ring3CheckEvent ( +UserSpaceCheckEvent ( IN EFI_EVENT UserEvent ); @@ -305,7 +305,7 @@ Ring3CheckEvent ( **/ EFI_STATUS EFIAPI -Ring3InstallProtocolInterface ( +UserSpaceInstallProtocolInterface ( IN OUT EFI_HANDLE *UserHandle, IN EFI_GUID *Protocol, IN EFI_INTERFACE_TYPE InterfaceType, @@ -328,7 +328,7 @@ Ring3InstallProtocolInterface ( **/ EFI_STATUS EFIAPI -Ring3ReinstallProtocolInterface ( +UserSpaceReinstallProtocolInterface ( IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN VOID *OldInterface, @@ -350,7 +350,7 @@ Ring3ReinstallProtocolInterface ( **/ EFI_STATUS EFIAPI -Ring3UninstallProtocolInterface ( +UserSpaceUninstallProtocolInterface ( IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN VOID *Interface @@ -369,7 +369,7 @@ Ring3UninstallProtocolInterface ( **/ EFI_STATUS EFIAPI -Ring3HandleProtocol ( +UserSpaceHandleProtocol ( IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, OUT VOID **Interface @@ -390,7 +390,7 @@ Ring3HandleProtocol ( **/ EFI_STATUS EFIAPI -Ring3RegisterProtocolNotify ( +UserSpaceRegisterProtocolNotify ( IN EFI_GUID *Protocol, IN EFI_EVENT Event, OUT VOID **Registration @@ -416,7 +416,7 @@ Ring3RegisterProtocolNotify ( **/ EFI_STATUS EFIAPI -Ring3LocateHandle ( +UserSpaceLocateHandle ( IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, @@ -441,7 +441,7 @@ Ring3LocateHandle ( **/ EFI_STATUS EFIAPI -Ring3LocateDevicePath ( +UserSpaceLocateDevicePath ( IN EFI_GUID *Protocol, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, OUT EFI_HANDLE *Device @@ -464,7 +464,7 @@ Ring3LocateDevicePath ( **/ EFI_STATUS EFIAPI -Ring3InstallConfigurationTable ( +UserSpaceInstallConfigurationTable ( IN EFI_GUID *Guid, IN VOID *Table ); @@ -505,7 +505,7 @@ Ring3InstallConfigurationTable ( **/ EFI_STATUS EFIAPI -Ring3LoadImage ( +UserSpaceLoadImage ( IN BOOLEAN BootPolicy, IN EFI_HANDLE ParentImageHandle, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, @@ -535,7 +535,7 @@ Ring3LoadImage ( **/ EFI_STATUS EFIAPI -Ring3StartImage ( +UserSpaceStartImage ( IN EFI_HANDLE ImageHandle, OUT UINTN *ExitDataSize, OUT CHAR16 **ExitData OPTIONAL @@ -566,7 +566,7 @@ Ring3StartImage ( **/ EFI_STATUS EFIAPI -Ring3Exit ( +UserSpaceExit ( IN EFI_HANDLE ImageHandle, IN EFI_STATUS Status, IN UINTN ExitDataSize, @@ -587,7 +587,7 @@ Ring3Exit ( **/ EFI_STATUS EFIAPI -Ring3UnloadImage ( +UserSpaceUnloadImage ( IN EFI_HANDLE ImageHandle ); @@ -603,7 +603,7 @@ Ring3UnloadImage ( **/ EFI_STATUS EFIAPI -Ring3ExitBootServices ( +UserSpaceExitBootServices ( IN EFI_HANDLE ImageHandle, IN UINTN MapKey ); @@ -620,7 +620,7 @@ Ring3ExitBootServices ( **/ EFI_STATUS EFIAPI -Ring3GetNextMonotonicCount ( +UserSpaceGetNextMonotonicCount ( OUT UINT64 *Count ); @@ -636,7 +636,7 @@ Ring3GetNextMonotonicCount ( **/ EFI_STATUS EFIAPI -Ring3Stall ( +UserSpaceStall ( IN UINTN Microseconds ); @@ -664,7 +664,7 @@ Ring3Stall ( **/ EFI_STATUS EFIAPI -Ring3SetWatchdogTimer ( +UserSpaceSetWatchdogTimer ( IN UINTN Timeout, IN UINT64 WatchdogCode, IN UINTN DataSize, @@ -699,7 +699,7 @@ Ring3SetWatchdogTimer ( **/ EFI_STATUS EFIAPI -Ring3ConnectController ( +UserSpaceConnectController ( IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE *DriverImageHandle OPTIONAL, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, @@ -740,7 +740,7 @@ Ring3ConnectController ( **/ EFI_STATUS EFIAPI -Ring3DisconnectController ( +UserSpaceDisconnectController ( IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE DriverImageHandle OPTIONAL, IN EFI_HANDLE ChildHandle OPTIONAL @@ -768,7 +768,7 @@ Ring3DisconnectController ( **/ EFI_STATUS EFIAPI -Ring3OpenProtocol ( +UserSpaceOpenProtocol ( IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, OUT VOID **Interface OPTIONAL, @@ -804,7 +804,7 @@ Ring3OpenProtocol ( **/ EFI_STATUS EFIAPI -Ring3CloseProtocol ( +UserSpaceCloseProtocol ( IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN EFI_HANDLE AgentHandle, @@ -824,7 +824,7 @@ Ring3CloseProtocol ( **/ EFI_STATUS EFIAPI -Ring3OpenProtocolInformation ( +UserSpaceOpenProtocolInformation ( IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, @@ -856,7 +856,7 @@ Ring3OpenProtocolInformation ( **/ EFI_STATUS EFIAPI -Ring3ProtocolsPerHandle ( +UserSpaceProtocolsPerHandle ( IN EFI_HANDLE UserHandle, OUT EFI_GUID ***ProtocolBuffer, OUT UINTN *ProtocolBufferCount @@ -864,7 +864,7 @@ Ring3ProtocolsPerHandle ( /** Function returns an array of handles that support the requested protocol - in a buffer allocated from pool. This is a version of Ring3LocateHandle() + in a buffer allocated from pool. This is a version of UserSpaceLocateHandle() that allocates a buffer for the caller. @param SearchType Specifies which handle(s) are to be returned. @@ -886,7 +886,7 @@ Ring3ProtocolsPerHandle ( **/ EFI_STATUS EFIAPI -Ring3LocateHandleBuffer ( +UserSpaceLocateHandleBuffer ( IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, @@ -912,7 +912,7 @@ Ring3LocateHandleBuffer ( **/ EFI_STATUS EFIAPI -Ring3LocateProtocol ( +UserSpaceLocateProtocol ( IN EFI_GUID *Protocol, IN VOID *Registration OPTIONAL, OUT VOID **Interface @@ -941,7 +941,7 @@ Ring3LocateProtocol ( **/ EFI_STATUS EFIAPI -Ring3InstallMultipleProtocolInterfaces ( +UserSpaceInstallMultipleProtocolInterfaces ( IN OUT EFI_HANDLE *Handle, ... ); @@ -962,7 +962,7 @@ Ring3InstallMultipleProtocolInterfaces ( **/ EFI_STATUS EFIAPI -Ring3UninstallMultipleProtocolInterfaces ( +UserSpaceUninstallMultipleProtocolInterfaces ( IN EFI_HANDLE Handle, ... ); @@ -984,7 +984,7 @@ Ring3UninstallMultipleProtocolInterfaces ( **/ EFI_STATUS EFIAPI -Ring3CalculateCrc32 ( +UserSpaceCalculateCrc32 ( IN VOID *Data, IN UINTN DataSize, OUT UINT32 *Crc32 @@ -1012,7 +1012,7 @@ Ring3CalculateCrc32 ( **/ EFI_STATUS EFIAPI -Ring3CreateEventEx ( +UserSpaceCreateEventEx ( IN UINT32 Type, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, @@ -1034,7 +1034,7 @@ Ring3CreateEventEx ( **/ EFI_STATUS EFIAPI -Ring3BlockIoReset ( +UserSpaceBlockIoReset ( IN EFI_BLOCK_IO_PROTOCOL *This, IN BOOLEAN ExtendedVerification ); @@ -1060,7 +1060,7 @@ Ring3BlockIoReset ( **/ EFI_STATUS EFIAPI -Ring3BlockIoRead ( +UserSpaceBlockIoRead ( IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, @@ -1090,7 +1090,7 @@ Ring3BlockIoRead ( **/ EFI_STATUS EFIAPI -Ring3BlockIoWrite ( +UserSpaceBlockIoWrite ( IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, @@ -1110,7 +1110,7 @@ Ring3BlockIoWrite ( **/ EFI_STATUS EFIAPI -Ring3BlockIoFlush ( +UserSpaceBlockIoFlush ( IN EFI_BLOCK_IO_PROTOCOL *This ); @@ -1133,7 +1133,7 @@ Ring3BlockIoFlush ( **/ EFI_STATUS EFIAPI -Ring3DiskIoRead ( +UserSpaceDiskIoRead ( IN EFI_DISK_IO_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Offset, @@ -1161,7 +1161,7 @@ Ring3DiskIoRead ( **/ EFI_STATUS EFIAPI -Ring3DiskIoWrite ( +UserSpaceDiskIoWrite ( IN EFI_DISK_IO_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Offset, @@ -1184,7 +1184,7 @@ Ring3DiskIoWrite ( **/ EFI_STATUS EFIAPI -Ring3GetTime ( +UserSpaceGetTime ( OUT EFI_TIME *Time, OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL ); @@ -1201,7 +1201,7 @@ Ring3GetTime ( **/ EFI_STATUS EFIAPI -Ring3SetTime ( +UserSpaceSetTime ( IN EFI_TIME *Time ); @@ -1222,7 +1222,7 @@ Ring3SetTime ( **/ EFI_STATUS EFIAPI -Ring3GetWakeupTime ( +UserSpaceGetWakeupTime ( OUT BOOLEAN *Enabled, OUT BOOLEAN *Pending, OUT EFI_TIME *Time @@ -1244,7 +1244,7 @@ Ring3GetWakeupTime ( **/ EFI_STATUS EFIAPI -Ring3SetWakeupTime ( +UserSpaceSetWakeupTime ( IN BOOLEAN Enable, IN EFI_TIME *Time OPTIONAL ); @@ -1270,7 +1270,7 @@ Ring3SetWakeupTime ( **/ EFI_STATUS EFIAPI -Ring3SetVirtualAddressMap ( +UserSpaceSetVirtualAddressMap ( IN UINTN MemoryMapSize, IN UINTN DescriptorSize, IN UINT32 DescriptorVersion, @@ -1294,7 +1294,7 @@ Ring3SetVirtualAddressMap ( **/ EFI_STATUS EFIAPI -Ring3ConvertPointer ( +UserSpaceConvertPointer ( IN UINTN DebugDisposition, IN OUT VOID **Address ); @@ -1325,7 +1325,7 @@ Ring3ConvertPointer ( **/ EFI_STATUS EFIAPI -Ring3GetVariable ( +UserSpaceGetVariable ( IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, OUT UINT32 *Attributes OPTIONAL, @@ -1361,7 +1361,7 @@ Ring3GetVariable ( **/ EFI_STATUS EFIAPI -Ring3GetNextVariableName ( +UserSpaceGetNextVariableName ( IN OUT UINTN *VariableNameSize, IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid @@ -1403,7 +1403,7 @@ Ring3GetNextVariableName ( **/ EFI_STATUS EFIAPI -Ring3SetVariable ( +UserSpaceSetVariable ( IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, @@ -1423,7 +1423,7 @@ Ring3SetVariable ( **/ EFI_STATUS EFIAPI -Ring3GetNextHighMonotonicCount ( +UserSpaceGetNextHighMonotonicCount ( OUT UINT32 *HighCount ); @@ -1444,7 +1444,7 @@ Ring3GetNextHighMonotonicCount ( **/ VOID EFIAPI -Ring3ResetSystem ( +UserSpaceResetSystem ( IN EFI_RESET_TYPE ResetType, IN EFI_STATUS ResetStatus, IN UINTN DataSize, @@ -1483,7 +1483,7 @@ Ring3ResetSystem ( **/ EFI_STATUS EFIAPI -Ring3UpdateCapsule ( +UserSpaceUpdateCapsule ( IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, IN UINTN CapsuleCount, IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL @@ -1514,7 +1514,7 @@ Ring3UpdateCapsule ( **/ EFI_STATUS EFIAPI -Ring3QueryCapsuleCapabilities ( +UserSpaceQueryCapsuleCapabilities ( IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, IN UINTN CapsuleCount, OUT UINT64 *MaximumCapsuleSize, @@ -1545,7 +1545,7 @@ Ring3QueryCapsuleCapabilities ( **/ EFI_STATUS EFIAPI -Ring3QueryVariableInfo ( +UserSpaceQueryVariableInfo ( IN UINT32 Attributes, OUT UINT64 *MaximumVariableStorageSize, OUT UINT64 *RemainingVariableStorageSize, @@ -1566,7 +1566,7 @@ Ring3QueryVariableInfo ( **/ INTN EFIAPI -Ring3UnicodeStriColl ( +UserSpaceUnicodeStriColl ( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN CHAR16 *Str1, IN CHAR16 *Str2 @@ -1586,7 +1586,7 @@ Ring3UnicodeStriColl ( **/ BOOLEAN EFIAPI -Ring3UnicodeMetaiMatch ( +UserSpaceUnicodeMetaiMatch ( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN CHAR16 *String, IN CHAR16 *Pattern @@ -1602,7 +1602,7 @@ Ring3UnicodeMetaiMatch ( **/ VOID EFIAPI -Ring3UnicodeStrLwr ( +UserSpaceUnicodeStrLwr ( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN OUT CHAR16 *Str ); @@ -1617,7 +1617,7 @@ Ring3UnicodeStrLwr ( **/ VOID EFIAPI -Ring3UnicodeStrUpr ( +UserSpaceUnicodeStrUpr ( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN OUT CHAR16 *Str ); @@ -1636,7 +1636,7 @@ Ring3UnicodeStrUpr ( **/ VOID EFIAPI -Ring3UnicodeFatToStr ( +UserSpaceUnicodeFatToStr ( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN UINTN FatSize, IN CHAR8 *Fat, @@ -1659,7 +1659,7 @@ Ring3UnicodeFatToStr ( **/ BOOLEAN EFIAPI -Ring3UnicodeStrToFat ( +UserSpaceUnicodeStrToFat ( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN CHAR16 *String, IN UINTN FatSize, diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c index 4c4c058df3..6408ee1df1 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c @@ -1,6 +1,7 @@ /** @file + This driver constructs User space wrappers for the EFI_*_PROTOCOLs. - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause **/ @@ -9,7 +10,7 @@ EFI_STATUS EFIAPI -Ring3BlockIoReset ( +UserSpaceBlockIoReset ( IN EFI_BLOCK_IO_PROTOCOL *This, IN BOOLEAN ExtendedVerification ) @@ -24,7 +25,7 @@ Ring3BlockIoReset ( EFI_STATUS EFIAPI -Ring3BlockIoRead ( +UserSpaceBlockIoRead ( IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, @@ -45,7 +46,7 @@ Ring3BlockIoRead ( EFI_STATUS EFIAPI -Ring3BlockIoWrite ( +UserSpaceBlockIoWrite ( IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, @@ -66,7 +67,7 @@ Ring3BlockIoWrite ( EFI_STATUS EFIAPI -Ring3BlockIoFlush ( +UserSpaceBlockIoFlush ( IN EFI_BLOCK_IO_PROTOCOL *This ) { @@ -79,7 +80,7 @@ Ring3BlockIoFlush ( EFI_STATUS EFIAPI -Ring3DiskIoRead ( +UserSpaceDiskIoRead ( IN EFI_DISK_IO_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Offset, @@ -100,7 +101,7 @@ Ring3DiskIoRead ( EFI_STATUS EFIAPI -Ring3DiskIoWrite ( +UserSpaceDiskIoWrite ( IN EFI_DISK_IO_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Offset, @@ -121,7 +122,7 @@ Ring3DiskIoWrite ( INTN EFIAPI -Ring3UnicodeStriColl ( +UserSpaceUnicodeStriColl ( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN CHAR16 *Str1, IN CHAR16 *Str2 @@ -138,7 +139,7 @@ Ring3UnicodeStriColl ( BOOLEAN EFIAPI -Ring3UnicodeMetaiMatch ( +UserSpaceUnicodeMetaiMatch ( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN CHAR16 *String, IN CHAR16 *Pattern @@ -155,7 +156,7 @@ Ring3UnicodeMetaiMatch ( VOID EFIAPI -Ring3UnicodeStrLwr ( +UserSpaceUnicodeStrLwr ( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN OUT CHAR16 *Str ) @@ -170,7 +171,7 @@ Ring3UnicodeStrLwr ( VOID EFIAPI -Ring3UnicodeStrUpr ( +UserSpaceUnicodeStrUpr ( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN OUT CHAR16 *Str ) @@ -185,7 +186,7 @@ Ring3UnicodeStrUpr ( VOID EFIAPI -Ring3UnicodeFatToStr ( +UserSpaceUnicodeFatToStr ( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN UINTN FatSize, IN CHAR8 *Fat, @@ -204,7 +205,7 @@ Ring3UnicodeFatToStr ( BOOLEAN EFIAPI -Ring3UnicodeStrToFat ( +UserSpaceUnicodeStrToFat ( IN EFI_UNICODE_COLLATION_PROTOCOL *This, IN CHAR16 *String, IN UINTN FatSize, diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c index a68e701aeb..76d74da393 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c @@ -1,7 +1,7 @@ /** @file - This driver constructs Ring 3 wrappers for the EFI_BOOT_SERVICES. + This driver constructs User space wrappers for the EFI_BOOT_SERVICES. - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause **/ @@ -73,17 +73,17 @@ FixInterface ( BlockIo = (EFI_BLOCK_IO_PROTOCOL *)*Interface; - BlockIo->Reset = Ring3BlockIoReset; - BlockIo->ReadBlocks = Ring3BlockIoRead; - BlockIo->WriteBlocks = Ring3BlockIoWrite; - BlockIo->FlushBlocks = Ring3BlockIoFlush; + BlockIo->Reset = UserSpaceBlockIoReset; + BlockIo->ReadBlocks = UserSpaceBlockIoRead; + BlockIo->WriteBlocks = UserSpaceBlockIoWrite; + BlockIo->FlushBlocks = UserSpaceBlockIoFlush; } else if (CompareGuid (Protocol, &gEfiDiskIoProtocolGuid)) { DiskIo = (EFI_DISK_IO_PROTOCOL *)*Interface; - DiskIo->ReadDisk = Ring3DiskIoRead; - DiskIo->WriteDisk = Ring3DiskIoWrite; + DiskIo->ReadDisk = UserSpaceDiskIoRead; + DiskIo->WriteDisk = UserSpaceDiskIoWrite; } else if (CompareGuid (Protocol, &gEfiDevicePathUtilitiesProtocolGuid)) { DevicePath = (EFI_DEVICE_PATH_UTILITIES_PROTOCOL *)*Interface; @@ -100,12 +100,12 @@ FixInterface ( } else if (CompareGuid (Protocol, &gEfiUnicodeCollationProtocolGuid)) { Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)*Interface; - Unicode->StriColl = Ring3UnicodeStriColl; - Unicode->MetaiMatch = Ring3UnicodeMetaiMatch; - Unicode->StrLwr = Ring3UnicodeStrLwr; - Unicode->StrUpr = Ring3UnicodeStrUpr; - Unicode->FatToStr = Ring3UnicodeFatToStr; - Unicode->StrToFat = Ring3UnicodeStrToFat; + Unicode->StriColl = UserSpaceUnicodeStriColl; + Unicode->MetaiMatch = UserSpaceUnicodeMetaiMatch; + Unicode->StrLwr = UserSpaceUnicodeStrLwr; + Unicode->StrUpr = UserSpaceUnicodeStrUpr; + Unicode->FatToStr = UserSpaceUnicodeFatToStr; + Unicode->StrToFat = UserSpaceUnicodeStrToFat; } else { return EFI_UNSUPPORTED; @@ -116,7 +116,7 @@ FixInterface ( EFI_TPL EFIAPI -Ring3RaiseTpl ( +UserSpaceRaiseTpl ( IN EFI_TPL NewTpl ) { @@ -129,7 +129,7 @@ Ring3RaiseTpl ( VOID EFIAPI -Ring3RestoreTpl ( +UserSpaceRestoreTpl ( IN EFI_TPL NewTpl ) { @@ -142,7 +142,7 @@ Ring3RestoreTpl ( EFI_STATUS EFIAPI -Ring3AllocatePages ( +UserSpaceAllocatePages ( IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN NumberOfPages, @@ -155,12 +155,12 @@ Ring3AllocatePages ( SysCallAllocatePages, 4, Type, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, NumberOfPages, Memory ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to allocate %d pages.\n", NumberOfPages)); + DEBUG ((DEBUG_ERROR, "UserSpace: Failed to allocate %d pages.\n", NumberOfPages)); } return Status; @@ -168,7 +168,7 @@ Ring3AllocatePages ( EFI_STATUS EFIAPI -Ring3FreePages ( +UserSpaceFreePages ( IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages ) @@ -182,7 +182,7 @@ Ring3FreePages ( Memory ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to free %d pages.\n", NumberOfPages)); + DEBUG ((DEBUG_ERROR, "UserSpace: Failed to free %d pages.\n", NumberOfPages)); } return Status; @@ -190,7 +190,7 @@ Ring3FreePages ( EFI_STATUS EFIAPI -Ring3GetMemoryMap ( +UserSpaceGetMemoryMap ( IN OUT UINTN *MemoryMapSize, IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, OUT UINTN *MapKey, @@ -198,14 +198,14 @@ Ring3GetMemoryMap ( OUT UINT32 *DescriptorVersion ) { - DEBUG ((DEBUG_ERROR, "Ring3: GetMemoryMap is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: GetMemoryMap is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3AllocatePool ( +UserSpaceAllocatePool ( IN EFI_MEMORY_TYPE PoolType, IN UINTN Size, OUT VOID **Buffer @@ -222,7 +222,7 @@ Ring3AllocatePool ( EFI_STATUS EFIAPI -Ring3FreePool ( +UserSpaceFreePool ( IN VOID *Buffer ) { @@ -231,7 +231,7 @@ Ring3FreePool ( EFI_STATUS EFIAPI -Ring3CreateEvent ( +UserSpaceCreateEvent ( IN UINT32 Type, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, @@ -239,114 +239,114 @@ Ring3CreateEvent ( OUT EFI_EVENT *Event ) { - DEBUG ((DEBUG_ERROR, "Ring3: CreateEvent is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: CreateEvent is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3SetTimer ( +UserSpaceSetTimer ( IN EFI_EVENT UserEvent, IN EFI_TIMER_DELAY Type, IN UINT64 TriggerTime ) { - DEBUG ((DEBUG_ERROR, "Ring3: SetTimer is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: SetTimer is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3WaitForEvent ( +UserSpaceWaitForEvent ( IN UINTN NumberOfEvents, IN EFI_EVENT *UserEvents, OUT UINTN *UserIndex ) { - DEBUG ((DEBUG_ERROR, "Ring3: WaitForEvent is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: WaitForEvent is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3SignalEvent ( +UserSpaceSignalEvent ( IN EFI_EVENT UserEvent ) { - DEBUG ((DEBUG_ERROR, "Ring3: SignalEvent is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: SignalEvent is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3CloseEvent ( +UserSpaceCloseEvent ( IN EFI_EVENT UserEvent ) { - DEBUG ((DEBUG_ERROR, "Ring3: CloseEvent is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: CloseEvent is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3CheckEvent ( +UserSpaceCheckEvent ( IN EFI_EVENT UserEvent ) { - DEBUG ((DEBUG_ERROR, "Ring3: CheckEvent is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: CheckEvent is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3InstallProtocolInterface ( +UserSpaceInstallProtocolInterface ( IN OUT EFI_HANDLE *UserHandle, IN EFI_GUID *Protocol, IN EFI_INTERFACE_TYPE InterfaceType, IN VOID *Interface ) { - DEBUG ((DEBUG_ERROR, "Ring3: InstallProtocolInterface is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: InstallProtocolInterface is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3ReinstallProtocolInterface ( +UserSpaceReinstallProtocolInterface ( IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN VOID *OldInterface, IN VOID *NewInterface ) { - DEBUG ((DEBUG_ERROR, "Ring3: ReinstallProtocolInterface is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: ReinstallProtocolInterface is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3UninstallProtocolInterface ( +UserSpaceUninstallProtocolInterface ( IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN VOID *Interface ) { - DEBUG ((DEBUG_ERROR, "Ring3: UninstallProtocolInterface is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: UninstallProtocolInterface is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3HandleProtocol ( +UserSpaceHandleProtocol ( IN EFI_HANDLE CoreUserHandle, IN EFI_GUID *Protocol, OUT VOID **Interface @@ -362,7 +362,7 @@ Ring3HandleProtocol ( Interface ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to get handle of protocol %g - %r\n", Protocol, Status)); + DEBUG ((DEBUG_ERROR, "UserSpace: Failed to get handle of protocol %g - %r\n", Protocol, Status)); return Status; } @@ -371,20 +371,20 @@ Ring3HandleProtocol ( EFI_STATUS EFIAPI -Ring3RegisterProtocolNotify ( +UserSpaceRegisterProtocolNotify ( IN EFI_GUID *Protocol, IN EFI_EVENT Event, OUT VOID **Registration ) { - DEBUG ((DEBUG_ERROR, "Ring3: RegisterProtocolNotify is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: RegisterProtocolNotify is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3LocateHandle ( +UserSpaceLocateHandle ( IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, @@ -392,39 +392,39 @@ Ring3LocateHandle ( OUT EFI_HANDLE *Buffer ) { - DEBUG ((DEBUG_ERROR, "Ring3: LocateHandle is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: LocateHandle is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3LocateDevicePath ( +UserSpaceLocateDevicePath ( IN EFI_GUID *Protocol, IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, OUT EFI_HANDLE *Device ) { - DEBUG ((DEBUG_ERROR, "Ring3: LocateDevicePath is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: LocateDevicePath is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3InstallConfigurationTable ( +UserSpaceInstallConfigurationTable ( IN EFI_GUID *Guid, IN VOID *Table ) { - DEBUG ((DEBUG_ERROR, "Ring3: InstallConfigurationTable is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: InstallConfigurationTable is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3LoadImage ( +UserSpaceLoadImage ( IN BOOLEAN BootPolicy, IN EFI_HANDLE ParentImageHandle, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, @@ -433,127 +433,127 @@ Ring3LoadImage ( OUT EFI_HANDLE *ImageHandle ) { - DEBUG ((DEBUG_ERROR, "Ring3: LoadImage is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: LoadImage is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3StartImage ( +UserSpaceStartImage ( IN EFI_HANDLE ImageHandle, OUT UINTN *ExitDataSize, OUT CHAR16 **ExitData OPTIONAL ) { - DEBUG ((DEBUG_ERROR, "Ring3: StartImage is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: StartImage is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3Exit ( +UserSpaceExit ( IN EFI_HANDLE ImageHandle, IN EFI_STATUS Status, IN UINTN ExitDataSize, IN CHAR16 *ExitData OPTIONAL ) { - DEBUG ((DEBUG_ERROR, "Ring3: Exit is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: Exit is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3UnloadImage ( +UserSpaceUnloadImage ( IN EFI_HANDLE ImageHandle ) { - DEBUG ((DEBUG_ERROR, "Ring3: UnloadImage is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: UnloadImage is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3ExitBootServices ( +UserSpaceExitBootServices ( IN EFI_HANDLE ImageHandle, IN UINTN MapKey ) { - DEBUG ((DEBUG_ERROR, "Ring3: ExitBootServices is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: ExitBootServices is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3GetNextMonotonicCount ( +UserSpaceGetNextMonotonicCount ( OUT UINT64 *Count ) { - DEBUG ((DEBUG_ERROR, "Ring3: GetNextMonotonicCount is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: GetNextMonotonicCount is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3Stall ( +UserSpaceStall ( IN UINTN Microseconds ) { - DEBUG ((DEBUG_ERROR, "Ring3: Stall is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: Stall is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3SetWatchdogTimer ( +UserSpaceSetWatchdogTimer ( IN UINTN Timeout, IN UINT64 WatchdogCode, IN UINTN DataSize, IN CHAR16 *WatchdogData OPTIONAL ) { - DEBUG ((DEBUG_ERROR, "Ring3: SetWatchdogTimer is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: SetWatchdogTimer is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3ConnectController ( +UserSpaceConnectController ( IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE *DriverImageHandle OPTIONAL, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, IN BOOLEAN Recursive ) { - DEBUG ((DEBUG_ERROR, "Ring3: ConnectController is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: ConnectController is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3DisconnectController ( +UserSpaceDisconnectController ( IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE DriverImageHandle OPTIONAL, IN EFI_HANDLE ChildHandle OPTIONAL ) { - DEBUG ((DEBUG_ERROR, "Ring3: DisconnectController is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: DisconnectController is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3OpenProtocol ( +UserSpaceOpenProtocol ( IN EFI_HANDLE CoreUserHandle, IN EFI_GUID *Protocol, OUT VOID **Interface OPTIONAL, @@ -583,7 +583,7 @@ Ring3OpenProtocol ( EFI_STATUS EFIAPI -Ring3CloseProtocol ( +UserSpaceCloseProtocol ( IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN EFI_HANDLE AgentHandle, @@ -602,34 +602,34 @@ Ring3CloseProtocol ( EFI_STATUS EFIAPI -Ring3OpenProtocolInformation ( +UserSpaceOpenProtocolInformation ( IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, OUT UINTN *EntryCount ) { - DEBUG ((DEBUG_ERROR, "Ring3: OpenProtocolInformation is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: OpenProtocolInformation is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3ProtocolsPerHandle ( +UserSpaceProtocolsPerHandle ( IN EFI_HANDLE UserHandle, OUT EFI_GUID ***ProtocolBuffer, OUT UINTN *ProtocolBufferCount ) { - DEBUG ((DEBUG_ERROR, "Ring3: ProtocolsPerHandle is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: ProtocolsPerHandle is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3LocateHandleBuffer ( +UserSpaceLocateHandleBuffer ( IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, @@ -656,14 +656,14 @@ Ring3LocateHandleBuffer ( && (Buffer != NULL) && (*Buffer != NULL)) { PoolSize = *NumberHandles * sizeof (EFI_HANDLE *); - Status = Ring3AllocatePool (EfiRing3MemoryType, PoolSize, &Pool); + Status = UserSpaceAllocatePool (EfiUserSpaceMemoryType, PoolSize, &Pool); if (EFI_ERROR (Status)) { return Status; } CopyMem (Pool, *Buffer, PoolSize); - Status = Ring3FreePages ( + Status = UserSpaceFreePages ( (EFI_PHYSICAL_ADDRESS)(UINTN)*Buffer, EFI_SIZE_TO_PAGES (PoolSize) ); @@ -679,7 +679,7 @@ Ring3LocateHandleBuffer ( EFI_STATUS EFIAPI -Ring3LocateProtocol ( +UserSpaceLocateProtocol ( IN EFI_GUID *Protocol, IN VOID *CoreRegistration OPTIONAL, OUT VOID **Interface @@ -695,7 +695,7 @@ Ring3LocateProtocol ( Interface ); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Ring3: Failed to loacate protocol %g\n", Protocol)); + DEBUG ((DEBUG_ERROR, "UserSpace: Failed to loacate protocol %g\n", Protocol)); return Status; } @@ -704,7 +704,7 @@ Ring3LocateProtocol ( EFI_STATUS EFIAPI -Ring3InstallMultipleProtocolInterfaces ( +UserSpaceInstallMultipleProtocolInterfaces ( IN OUT EFI_HANDLE *Handle, ... ) @@ -722,8 +722,8 @@ Ring3InstallMultipleProtocolInterfaces ( } VA_END (Marker); - Status = Ring3AllocatePool ( - EfiRing3MemoryType, + Status = UserSpaceAllocatePool ( + EfiUserSpaceMemoryType, NumberOfArguments * sizeof (VOID *), (VOID **)&Arguments ); @@ -745,25 +745,25 @@ Ring3InstallMultipleProtocolInterfaces ( Arguments ); - Ring3FreePool (Arguments); + UserSpaceFreePool (Arguments); return Status; } EFI_STATUS EFIAPI -Ring3UninstallMultipleProtocolInterfaces ( +UserSpaceUninstallMultipleProtocolInterfaces ( IN EFI_HANDLE Handle, ... ) { - DEBUG ((DEBUG_ERROR, "Ring3: UninstallMultipleProtocolInterfaces is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: UninstallMultipleProtocolInterfaces is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3CalculateCrc32 ( +UserSpaceCalculateCrc32 ( IN VOID *Data, IN UINTN DataSize, OUT UINT32 *Crc32 @@ -780,7 +780,7 @@ Ring3CalculateCrc32 ( EFI_STATUS EFIAPI -Ring3CreateEventEx ( +UserSpaceCreateEventEx ( IN UINT32 Type, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, @@ -789,7 +789,7 @@ Ring3CreateEventEx ( OUT EFI_EVENT *Event ) { - DEBUG ((DEBUG_ERROR, "Ring3: CreateEventEx is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: CreateEventEx is not supported\n")); return EFI_UNSUPPORTED; } @@ -835,7 +835,7 @@ CoreAllocatePoolPagesI ( { EFI_PHYSICAL_ADDRESS Memory; - Ring3AllocatePages (AllocateAnyPages, EfiRing3MemoryType, NoPages, &Memory); + UserSpaceAllocatePages (AllocateAnyPages, EfiUserSpaceMemoryType, NoPages, &Memory); return (VOID *)(UINTN)Memory; } @@ -847,7 +847,7 @@ CoreFreePoolPagesI ( IN UINTN NoPages ) { - Ring3FreePages (Memory, NoPages); + UserSpaceFreePages (Memory, NoPages); } VOID @@ -857,5 +857,5 @@ CoreFreePoolPagesWithGuard ( IN UINTN NoPages ) { - CoreFreePoolPagesI (EfiRing3MemoryType, Memory, NoPages); + CoreFreePoolPagesI (EfiUserSpaceMemoryType, Memory, NoPages); } diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c index e3e787a536..8e86c8511b 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c +++ b/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c @@ -1,3 +1,11 @@ +/** @file + This driver constructs User space wrappers for the EFI_RUNTIME_SERVICES. + + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ + #include #include @@ -7,81 +15,81 @@ EFI_STATUS EFIAPI -Ring3GetTime ( +UserSpaceGetTime ( OUT EFI_TIME *Time, OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL ) { - DEBUG ((DEBUG_ERROR, "Ring3: GetTime is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: GetTime is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3SetTime ( +UserSpaceSetTime ( IN EFI_TIME *Time ) { - DEBUG ((DEBUG_ERROR, "Ring3: SetTime is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: SetTime is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3GetWakeupTime ( +UserSpaceGetWakeupTime ( OUT BOOLEAN *Enabled, OUT BOOLEAN *Pending, OUT EFI_TIME *Time ) { - DEBUG ((DEBUG_ERROR, "Ring3: GetWakeupTime is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: GetWakeupTime is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3SetWakeupTime ( +UserSpaceSetWakeupTime ( IN BOOLEAN Enable, IN EFI_TIME *Time OPTIONAL ) { - DEBUG ((DEBUG_ERROR, "Ring3: SetWakeupTime is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: SetWakeupTime is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3SetVirtualAddressMap ( +UserSpaceSetVirtualAddressMap ( IN UINTN MemoryMapSize, IN UINTN DescriptorSize, IN UINT32 DescriptorVersion, IN EFI_MEMORY_DESCRIPTOR *VirtualMap ) { - DEBUG ((DEBUG_ERROR, "Ring3: SetVirtualAddressMap is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: SetVirtualAddressMap is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3ConvertPointer ( +UserSpaceConvertPointer ( IN UINTN DebugDisposition, IN OUT VOID **Address ) { - DEBUG ((DEBUG_ERROR, "Ring3: ConvertPointer is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: ConvertPointer is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3GetVariable ( +UserSpaceGetVariable ( IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, OUT UINT32 *Attributes OPTIONAL, @@ -102,20 +110,20 @@ Ring3GetVariable ( EFI_STATUS EFIAPI -Ring3GetNextVariableName ( +UserSpaceGetNextVariableName ( IN OUT UINTN *VariableNameSize, IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid ) { - DEBUG ((DEBUG_ERROR, "Ring3: GetNextVariableName is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: GetNextVariableName is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3SetVariable ( +UserSpaceSetVariable ( IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, @@ -123,73 +131,73 @@ Ring3SetVariable ( IN VOID *Data ) { - DEBUG ((DEBUG_ERROR, "Ring3: SetVariable is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: SetVariable is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3GetNextHighMonotonicCount ( +UserSpaceGetNextHighMonotonicCount ( OUT UINT32 *HighCount ) { - DEBUG ((DEBUG_ERROR, "Ring3: GetNextHighMonotonicCount is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: GetNextHighMonotonicCount is not supported\n")); return EFI_UNSUPPORTED; } VOID EFIAPI -Ring3ResetSystem ( +UserSpaceResetSystem ( IN EFI_RESET_TYPE ResetType, IN EFI_STATUS ResetStatus, IN UINTN DataSize, IN VOID *ResetData OPTIONAL ) { - DEBUG ((DEBUG_ERROR, "Ring3: ResetSystem is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: ResetSystem is not supported\n")); return; } EFI_STATUS EFIAPI -Ring3UpdateCapsule ( +UserSpaceUpdateCapsule ( IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, IN UINTN CapsuleCount, IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL ) { - DEBUG ((DEBUG_ERROR, "Ring3: UpdateCapsule is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: UpdateCapsule is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3QueryCapsuleCapabilities ( +UserSpaceQueryCapsuleCapabilities ( IN EFI_CAPSULE_HEADER **CapsuleHeaderArray, IN UINTN CapsuleCount, OUT UINT64 *MaximumCapsuleSize, OUT EFI_RESET_TYPE *ResetType ) { - DEBUG ((DEBUG_ERROR, "Ring3: QueryCapsuleCapabilities is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: QueryCapsuleCapabilities is not supported\n")); return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI -Ring3QueryVariableInfo ( +UserSpaceQueryVariableInfo ( IN UINT32 Attributes, OUT UINT64 *MaximumVariableStorageSize, OUT UINT64 *RemainingVariableStorageSize, OUT UINT64 *MaximumVariableSize ) { - DEBUG ((DEBUG_ERROR, "Ring3: QueryVariableInfo is not supported\n")); + DEBUG ((DEBUG_ERROR, "UserSpace: QueryVariableInfo is not supported\n")); return EFI_UNSUPPORTED; } diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm index b45253cd8f..8b61f1e311 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm +++ b/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm @@ -1,9 +1,9 @@ ;------------------------------------------------------------------------------ -; Copyright (c) 2024, Mikhail Krichanov. All rights reserved. +; Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. ; SPDX-License-Identifier: BSD-3-Clause ;------------------------------------------------------------------------------ -extern ASM_PFX(Ring3Call) +extern ASM_PFX(UserSpaceCall) DEFAULT REL SECTION .text @@ -43,15 +43,15 @@ makecall: ;------------------------------------------------------------------------------ ; VOID ; EFIAPI -; Ring3EntryPoint ( -; IN RING3_CALL_DATA *Data +; UserSpaceEntryPoint ( +; IN USER_SPACE_CALL_DATA *Data ; ); ; -; (rcx) RIP of Ring3EntryPoint saved for SYSRET in CallRing3(). +; (rcx) RIP of UserSpaceEntryPoint saved for SYSRET in CallUserSpace(). ; (rdx) Data ;------------------------------------------------------------------------------ -global ASM_PFX(Ring3EntryPoint) -ASM_PFX(Ring3EntryPoint): +global ASM_PFX(UserSpaceEntryPoint) +ASM_PFX(UserSpaceEntryPoint): mov rcx, rdx - call ASM_PFX(Ring3Call) + call ASM_PFX(UserSpaceCall) diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c index bf65545739..7c55dd62b1 100644 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ b/MdeModulePkg/Core/Dxe/Image/Image.c @@ -23,7 +23,7 @@ typedef struct { STATIC LIST_ENTRY mAvailableEmulators; STATIC EFI_EVENT mPeCoffEmuProtocolRegistrationEvent; STATIC VOID *mPeCoffEmuProtocolNotifyRegistration; -STATIC BOOLEAN mDxeRing3 = TRUE; +STATIC BOOLEAN mDxeUserSpace = TRUE; extern BOOLEAN gBdsStarted; @@ -1349,12 +1349,12 @@ CoreLoadImageCommon ( Image->Info.ParentHandle = ParentImageHandle; Image->IsUserImage = (FileAttributes & EFI_FV_FILE_ATTRIB_USER) != 0; - if ((!PcdGetBool (PcdEnableUserSpace)) && Image->IsUserImage && mDxeRing3) { + if ((!PcdGetBool (PcdEnableUserSpace)) && Image->IsUserImage && mDxeUserSpace) { // - // Do not load DxeRing3 driver, if UserSpace is disabled. + // Do not load DxeUserSpace driver, if UserSpace is disabled. // - mDxeRing3 = FALSE; - Status = EFI_NOT_STARTED; + mDxeUserSpace = FALSE; + Status = EFI_NOT_STARTED; goto Done; } @@ -1454,7 +1454,7 @@ CoreLoadImageCommon ( Status = EFI_SUCCESS; ProtectUefiImage (&Image->Info, ImageOrigin, &ImageContext, Image->IsUserImage); - if (PcdGetBool (PcdEnableUserSpace) && (gRing3Data != NULL) && Image->IsUserImage) { + if (PcdGetBool (PcdEnableUserSpace) && (gUserSpaceData != NULL) && Image->IsUserImage) { Image->UserPageTable = InitializeUserPageTable (Image); } @@ -1708,8 +1708,8 @@ CoreStartImage ( Image->Started = TRUE; if (PcdGetBool (PcdEnableUserSpace) && (Image->IsUserImage)) { - if (gRing3Data == NULL) { - Image->Status = InitializeRing3 (ImageHandle, Image); + if (gUserSpaceData == NULL) { + Image->Status = InitializeUserSpace (ImageHandle, Image); if (EFI_ERROR (Image->Status)) { DEBUG ((DEBUG_ERROR, "Core: Failed to initialize User address space - %r.\n", Image->Status)); CpuDeadLoop (); @@ -1729,12 +1729,12 @@ CoreStartImage ( InsertTailList (&gUserSpaceDriversHead, &UserDriver->Link); - Image->Status = GoToRing3 ( + Image->Status = GoToUserSpace ( 2, (VOID *)Image->EntryPoint, UserDriver, ImageHandle, - gRing3Data + gUserSpaceData ); } else { Image->Status = EFI_OUT_OF_RESOURCES; @@ -1981,7 +1981,7 @@ CoreUnloadImage ( if (Image->Info.Unload != NULL) { // // TODO: If Image->IsUserImage, use FindInterface() to locate UserSpace - // EFI_LOADED_IMAGE_PROTOCOL->Unload() and GoToRing3(). + // EFI_LOADED_IMAGE_PROTOCOL->Unload() and GoToUserSpace(). // Status = Image->Info.Unload (ImageHandle); } diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index 64596b9230..a1ceeae7e1 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -63,7 +63,7 @@ EFI_MEMORY_TYPE_STATISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = { { 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiPalCode { 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiPersistentMemory { 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiUnacceptedMemoryType - { 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiRing3MemoryType + { 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiUserSpaceMemoryType { 0, MAX_ALLOC_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE } // EfiMaxMemoryType }; @@ -87,7 +87,7 @@ EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1] = { { EfiPalCode, 0 }, { EfiPersistentMemory, 0 }, { EfiGcdMemoryTypeUnaccepted, 0 }, - { EfiRing3MemoryType, 0 }, + { EfiUserSpaceMemoryType, 0 }, { EfiMaxMemoryType, 0 } }; // diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index eaa10d62a1..9a02cc7548 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -342,7 +342,7 @@ GetPermissionAttributeForMemoryType ( Attributes |= EFI_MEMORY_XP; } - if (MemoryType == EfiRing3MemoryType) { + if (MemoryType == EfiUserSpaceMemoryType) { Attributes |= EFI_MEMORY_USER; } @@ -974,7 +974,7 @@ ApplyMemoryProtectionPolicy ( return EFI_SUCCESS; } - if ((gUserPageTable != 0) && (NewType == EfiRing3MemoryType)) { + if ((gUserPageTable != 0) && (NewType == EfiUserSpaceMemoryType)) { gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, Memory, Length, NewAttributes); } } else { diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 6feacc9fde..65847f9014 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -59,17 +59,17 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) //------------------------------------------------------------------------------ // EFI_STATUS // EFIAPI -// CallRing3 ( -// IN RING3_CALL_DATA *Data, -// IN UINTN UserStackTop +// CallUserSpace ( +// IN USER_SPACE_CALL_DATA *Data, +// IN UINTN UserStackTop // ); // // (x0) Data // (x1) UserStackTop -// (x2) gRing3EntryPoint +// (x2) gUserSpaceEntryPoint // (x3) gUserPageTable //------------------------------------------------------------------------------ -ASM_FUNC(ArmCallRing3) +ASM_FUNC(ArmCallUserSpace) // Save registers. sub sp, sp, #0x100 @@ -94,7 +94,7 @@ ASM_FUNC(ArmCallRing3) mrs x6, nzcv mrs x7, pan orr x6, x6, x7 - // Prepare Ring3 SP and EntryPoint. + // Prepare UserSpace SP and EntryPoint. msr sp_el0, x1 EL1_OR_EL2(x1) 1:msr elr_el1, x2 diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index dcdc159d78..13a5e2a983 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -21,11 +21,11 @@ STATIC UINTN mUartBaseAddress; EFI_STATUS EFIAPI -ArmCallRing3 ( - IN RING3_CALL_DATA *Data, - IN UINTN UserStackTop, - IN VOID *EntryPoint, - IN UINTN UserPageTable +ArmCallUserSpace ( + IN USER_SPACE_CALL_DATA *Data, + IN UINTN UserStackTop, + IN VOID *EntryPoint, + IN UINTN UserPageTable ); STATIC @@ -119,7 +119,7 @@ InitializePlatform ( Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, EFI_SIZE_TO_PAGES (mConfigurationTableSize), &Physical ); @@ -221,15 +221,15 @@ ForbidSupervisorAccessToUserMemory ( EFI_STATUS EFIAPI -CallRing3 ( - IN RING3_CALL_DATA *Data, - IN UINTN UserStackTop +CallUserSpace ( + IN USER_SPACE_CALL_DATA *Data, + IN UINTN UserStackTop ) { - return ArmCallRing3 ( + return ArmCallUserSpace ( Data, UserStackTop, - gRing3EntryPoint, + gUserSpaceEntryPoint, gUserPageTable ); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index a1ffb25271..9191e3b0ad 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -55,17 +55,17 @@ ASM_FUNC_ALIGN(SysCallBase, 4096) //------------------------------------------------------------------------------ // EFI_STATUS // EFIAPI -// CallRing3 ( -// IN RING3_CALL_DATA *Data, -// IN UINTN UserStackTop +// CallUserSpace ( +// IN USER_SPACE_CALL_DATA *Data, +// IN UINTN UserStackTop // ); // // (r0) Data // (r1) UserStackTop -// (r2) gRing3EntryPoint +// (r2) gUserSpaceEntryPoint // (r3) gUserPageTable //------------------------------------------------------------------------------ -ASM_FUNC(ArmCallRing3) +ASM_FUNC(ArmCallUserSpace) // Save registers. push {R4-R12, LR} // Save old SP_usr and LR_usr on Core Stack. diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c index 1b762628c6..e722693962 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/InitializeARM.c @@ -20,11 +20,11 @@ STATIC UINTN mUartBaseAddress; EFI_STATUS EFIAPI -ArmCallRing3 ( - IN RING3_CALL_DATA *Data, - IN UINTN UserStackTop, - IN VOID *EntryPoint, - IN UINTN UserPageTable +ArmCallUserSpace ( + IN USER_SPACE_CALL_DATA *Data, + IN UINTN UserStackTop, + IN VOID *EntryPoint, + IN UINTN UserPageTable ); STATIC @@ -147,7 +147,7 @@ InitializePlatform ( Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, EFI_SIZE_TO_PAGES (mConfigurationTableSize), &Physical ); @@ -238,15 +238,15 @@ ForbidSupervisorAccessToUserMemory ( EFI_STATUS EFIAPI -CallRing3 ( - IN RING3_CALL_DATA *Data, - IN UINTN UserStackTop +CallUserSpace ( + IN USER_SPACE_CALL_DATA *Data, + IN UINTN UserStackTop ) { - return ArmCallRing3 ( + return ArmCallUserSpace ( Data, UserStackTop, - gRing3EntryPoint, + gUserSpaceEntryPoint, gUserPageTable ); } diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 7de1460e06..6865771d5d 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -12,11 +12,11 @@ LIST_ENTRY mProtocolsHead = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolsHead); typedef struct { VOID *Core; - VOID *Ring3; + VOID *UserSpace; LIST_ENTRY Link; } INTERFACE; -UINTN mRing3InterfacePointer = 0; +UINTN mUserSpaceInterfacePointer = 0; CHAR8 *SysCallNames[] = { // @@ -92,76 +92,76 @@ STATIC EFI_STATUS EFIAPI FindGuid ( - IN EFI_GUID *Ring3, + IN EFI_GUID *UserSpace, OUT EFI_GUID **Core, OUT UINT32 *CoreSize ) { - ASSERT (Ring3 != NULL); + ASSERT (UserSpace != NULL); ASSERT (Core != NULL); ASSERT (CoreSize != NULL); - if (CompareGuid (Ring3, &gEfiDevicePathUtilitiesProtocolGuid)) { + if (CompareGuid (UserSpace, &gEfiDevicePathUtilitiesProtocolGuid)) { *Core = &gEfiDevicePathUtilitiesProtocolGuid; *CoreSize = sizeof (EFI_DEVICE_PATH_UTILITIES_PROTOCOL); - } else if (CompareGuid (Ring3, &gEfiLoadedImageProtocolGuid)) { + } else if (CompareGuid (UserSpace, &gEfiLoadedImageProtocolGuid)) { *Core = &gEfiLoadedImageProtocolGuid; *CoreSize = sizeof (EFI_LOADED_IMAGE_PROTOCOL); - } else if (CompareGuid (Ring3, &gEfiBlockIoProtocolGuid)) { + } else if (CompareGuid (UserSpace, &gEfiBlockIoProtocolGuid)) { *Core = &gEfiBlockIoProtocolGuid; *CoreSize = sizeof (EFI_BLOCK_IO_PROTOCOL); - } else if (CompareGuid (Ring3, &gEfiDiskIoProtocolGuid)) { + } else if (CompareGuid (UserSpace, &gEfiDiskIoProtocolGuid)) { *Core = &gEfiDiskIoProtocolGuid; *CoreSize = sizeof (EFI_DISK_IO_PROTOCOL); - } else if (CompareGuid (Ring3, &gEfiDriverBindingProtocolGuid)) { + } else if (CompareGuid (UserSpace, &gEfiDriverBindingProtocolGuid)) { *Core = &gEfiDriverBindingProtocolGuid; *CoreSize = sizeof (EFI_DRIVER_BINDING_PROTOCOL); - } else if (CompareGuid (Ring3, &gEfiComponentNameProtocolGuid)) { + } else if (CompareGuid (UserSpace, &gEfiComponentNameProtocolGuid)) { *Core = &gEfiComponentNameProtocolGuid; *CoreSize = sizeof (EFI_COMPONENT_NAME_PROTOCOL); - } else if (CompareGuid (Ring3, &gEfiComponentName2ProtocolGuid)) { + } else if (CompareGuid (UserSpace, &gEfiComponentName2ProtocolGuid)) { *Core = &gEfiComponentName2ProtocolGuid; *CoreSize = sizeof (EFI_COMPONENT_NAME2_PROTOCOL); - } else if (CompareGuid (Ring3, &gEfiDevicePathProtocolGuid)) { + } else if (CompareGuid (UserSpace, &gEfiDevicePathProtocolGuid)) { *Core = &gEfiDevicePathProtocolGuid; *CoreSize = sizeof (EFI_DEVICE_PATH_PROTOCOL); - } else if (CompareGuid (Ring3, &gEfiSimpleFileSystemProtocolGuid)) { + } else if (CompareGuid (UserSpace, &gEfiSimpleFileSystemProtocolGuid)) { *Core = &gEfiSimpleFileSystemProtocolGuid; *CoreSize = sizeof (EFI_SIMPLE_FILE_SYSTEM_PROTOCOL); - } else if (CompareGuid (Ring3, &gEfiUnicodeCollationProtocolGuid)) { + } else if (CompareGuid (UserSpace, &gEfiUnicodeCollationProtocolGuid)) { *Core = &gEfiUnicodeCollationProtocolGuid; *CoreSize = sizeof (EFI_UNICODE_COLLATION_PROTOCOL); - } else if (CompareGuid (Ring3, &gEfiGlobalVariableGuid)) { + } else if (CompareGuid (UserSpace, &gEfiGlobalVariableGuid)) { *Core = &gEfiGlobalVariableGuid; - } else if (CompareGuid (Ring3, &gEfiUnicodeCollation2ProtocolGuid)) { + } else if (CompareGuid (UserSpace, &gEfiUnicodeCollation2ProtocolGuid)) { *Core = &gEfiUnicodeCollation2ProtocolGuid; *CoreSize = sizeof (EFI_UNICODE_COLLATION_PROTOCOL); } else { - DEBUG ((DEBUG_ERROR, "Ring0: Unknown protocol - %g.\n", Ring3)); + DEBUG ((DEBUG_ERROR, "Core: Unknown protocol - %g.\n", UserSpace)); return EFI_NOT_FOUND; } @@ -172,7 +172,7 @@ STATIC VOID * EFIAPI FindInterface ( - IN BOOLEAN FindRing3, + IN BOOLEAN FindUserSpace, IN VOID *Interface ) { @@ -182,12 +182,12 @@ FindInterface ( for (Link = mProtocolsHead.ForwardLink; Link != &mProtocolsHead; Link = Link->ForwardLink) { Protocol = BASE_CR (Link, INTERFACE, Link); - if (FindRing3) { + if (FindUserSpace) { if (Protocol->Core == Interface) { - return Protocol->Ring3; + return Protocol->UserSpace; } } else { - if (Protocol->Ring3 == Interface) { + if (Protocol->UserSpace == Interface) { return Protocol->Core; } } @@ -199,15 +199,15 @@ FindInterface ( STATIC VOID * EFIAPI -PrepareRing3Interface ( +PrepareUserSpaceInterface ( IN EFI_GUID *Guid, IN VOID *CoreInterface, IN UINT32 CoreSize ) { EFI_STATUS Status; - UINTN Ring3Limit; - VOID *Ring3Interface; + UINTN UserSpaceLimit; + VOID *UserSpaceInterface; EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_UNICODE_COLLATION_PROTOCOL *Unicode; INTERFACE *Protocol; @@ -215,50 +215,50 @@ PrepareRing3Interface ( ASSERT (Guid != NULL); ASSERT (CoreInterface != NULL); - if (mRing3InterfacePointer == 0) { - mRing3InterfacePointer = (UINTN)gRing3Interfaces; + if (mUserSpaceInterfacePointer == 0) { + mUserSpaceInterfacePointer = (UINTN)gUserSpaceInterfaces; } - Ring3Interface = FindInterface (TRUE, CoreInterface); + UserSpaceInterface = FindInterface (TRUE, CoreInterface); - if (Ring3Interface != NULL) { - return Ring3Interface; + if (UserSpaceInterface != NULL) { + return UserSpaceInterface; } - Ring3Limit = (UINTN)gRing3Interfaces + EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES); + UserSpaceLimit = (UINTN)gUserSpaceInterfaces + EFI_PAGES_TO_SIZE (USER_SPACE_INTERFACES_PAGES); - ASSERT ((mRing3InterfacePointer + CoreSize) <= Ring3Limit); + ASSERT ((mUserSpaceInterfacePointer + CoreSize) <= UserSpaceLimit); - Ring3Interface = (VOID *)mRing3InterfacePointer; + UserSpaceInterface = (VOID *)mUserSpaceInterfacePointer; - CopyMem ((VOID *)mRing3InterfacePointer, CoreInterface, CoreSize); - mRing3InterfacePointer += CoreSize; + CopyMem ((VOID *)mUserSpaceInterfacePointer, CoreInterface, CoreSize); + mUserSpaceInterfacePointer += CoreSize; Protocol = AllocatePool (sizeof (INTERFACE)); - Protocol->Core = CoreInterface; - Protocol->Ring3 = Ring3Interface; + Protocol->Core = CoreInterface; + Protocol->UserSpace = UserSpaceInterface; InsertTailList (&mProtocolsHead, &Protocol->Link); if (CompareGuid (Guid, &gEfiBlockIoProtocolGuid)) { - ASSERT ((mRing3InterfacePointer + sizeof (EFI_BLOCK_IO_MEDIA)) <= Ring3Limit); + ASSERT ((mUserSpaceInterfacePointer + sizeof (EFI_BLOCK_IO_MEDIA)) <= UserSpaceLimit); - BlockIo = (EFI_BLOCK_IO_PROTOCOL *)Ring3Interface; + BlockIo = (EFI_BLOCK_IO_PROTOCOL *)UserSpaceInterface; - CopyMem ((VOID *)mRing3InterfacePointer, (VOID *)BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA)); + CopyMem ((VOID *)mUserSpaceInterfacePointer, (VOID *)BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA)); - BlockIo->Media = (EFI_BLOCK_IO_MEDIA *)mRing3InterfacePointer; + BlockIo->Media = (EFI_BLOCK_IO_MEDIA *)mUserSpaceInterfacePointer; - mRing3InterfacePointer += sizeof (EFI_BLOCK_IO_MEDIA); + mUserSpaceInterfacePointer += sizeof (EFI_BLOCK_IO_MEDIA); } else if (CompareGuid (Guid, &gEfiUnicodeCollationProtocolGuid)) { - Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)Ring3Interface; + Unicode = (EFI_UNICODE_COLLATION_PROTOCOL *)UserSpaceInterface; - ASSERT ((mRing3InterfacePointer + AsciiStrSize (Unicode->SupportedLanguages)) <= Ring3Limit); + ASSERT ((mUserSpaceInterfacePointer + AsciiStrSize (Unicode->SupportedLanguages)) <= UserSpaceLimit); Status = AsciiStrCpyS ( - (CHAR8 *)mRing3InterfacePointer, + (CHAR8 *)mUserSpaceInterfacePointer, AsciiStrSize (Unicode->SupportedLanguages), Unicode->SupportedLanguages ); @@ -267,12 +267,12 @@ PrepareRing3Interface ( return NULL; } - Unicode->SupportedLanguages = (CHAR8 *)mRing3InterfacePointer; + Unicode->SupportedLanguages = (CHAR8 *)mUserSpaceInterfacePointer; - mRing3InterfacePointer += AsciiStrSize (Unicode->SupportedLanguages); + mUserSpaceInterfacePointer += AsciiStrSize (Unicode->SupportedLanguages); } - return Ring3Interface; + return UserSpaceInterface; } STATIC @@ -347,7 +347,7 @@ CallBootService ( VOID **CoreArgList; EFI_HANDLE CoreHandle; UINT32 PagesNumber; - EFI_PHYSICAL_ADDRESS Ring3Pages; + EFI_PHYSICAL_ADDRESS UserSpacePages; USER_SPACE_DRIVER *NewDriver; UINTN *Arguments; EFI_PHYSICAL_ADDRESS PhysAddr; @@ -415,7 +415,7 @@ CallBootService ( AllowSupervisorAccessToUserMemory (); if (Interface != NULL) { - Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); + Interface = PrepareUserSpaceInterface (CoreProtocol, Interface, MemoryCoreSize); ASSERT (Interface != NULL); *(VOID **)Arguments[3] = Interface; @@ -462,7 +462,7 @@ CallBootService ( if ((VOID **)Arguments[3] != NULL) { AllowSupervisorAccessToUserMemory (); if (Interface != NULL) { - Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); + Interface = PrepareUserSpaceInterface (CoreProtocol, Interface, MemoryCoreSize); } *(VOID **)Arguments[3] = Interface; @@ -648,7 +648,7 @@ CallBootService ( AllowSupervisorAccessToUserMemory (); if (Interface != NULL) { - Interface = PrepareRing3Interface (CoreProtocol, Interface, MemoryCoreSize); + Interface = PrepareUserSpaceInterface (CoreProtocol, Interface, MemoryCoreSize); ASSERT (Interface != NULL); *(VOID **)Arguments[3] = Interface; @@ -761,20 +761,20 @@ CallBootService ( Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, PagesNumber, - &Ring3Pages + &UserSpacePages ); if (EFI_ERROR (Status)) { break; } AllowSupervisorAccessToUserMemory (); - CopyMem ((VOID *)(UINTN)Ring3Pages, (VOID *)Argument5, Argument4 * sizeof (EFI_HANDLE *)); + CopyMem ((VOID *)(UINTN)UserSpacePages, (VOID *)Argument5, Argument4 * sizeof (EFI_HANDLE *)); FreePool ((VOID *)Argument5); - *(EFI_HANDLE **)Arguments[5] = (EFI_HANDLE *)(UINTN)Ring3Pages; + *(EFI_HANDLE **)Arguments[5] = (EFI_HANDLE *)(UINTN)UserSpacePages; ForbidSupervisorAccessToUserMemory (); } @@ -1465,7 +1465,7 @@ CallBootService ( break; default: - DEBUG ((DEBUG_ERROR, "Ring0: Unknown syscall type.\n")); + DEBUG ((DEBUG_ERROR, "Core: Unknown syscall type.\n")); Status = EFI_UNSUPPORTED; break; } diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm index dfb3f09185..13ffaa9b29 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/CoreBootServices.nasm @@ -8,7 +8,7 @@ #include extern ASM_PFX(CallBootService) -extern ASM_PFX(gRing3EntryPoint) +extern ASM_PFX(gUserSpaceEntryPoint) extern ASM_PFX(AsmReadMsr64) @@ -81,7 +81,7 @@ copy: ret -%macro SetRing3DataSegmentSelectors 0 +%macro SetUserSpaceDataSegmentSelectors 0 push dword MSR_IA32_SYSENTER_CS call ASM_PFX(AsmReadMsr64) ; eax = RING0_CODE32_SEL @@ -146,7 +146,7 @@ ASM_PFX(CoreBootServices): push eax cli - SetRing3DataSegmentSelectors + SetUserSpaceDataSegmentSelectors mov eax, [ASM_PFX(gUserPageTable)] mov cr3, eax @@ -167,15 +167,15 @@ ASM_PFX(CoreBootServices): ;------------------------------------------------------------------------------ ; EFI_STATUS ; EFIAPI -; CallRing3 ( -; IN RING3_CALL_DATA *Data, -; IN UINTN UserStackTop +; CallUserSpace ( +; IN USER_SPACE_CALL_DATA *Data, +; IN UINTN UserStackTop ; ); ; ; (On User Stack) Data, UserStackTop ;------------------------------------------------------------------------------ -global ASM_PFX(CallRing3) -ASM_PFX(CallRing3): +global ASM_PFX(CallUserSpace) +ASM_PFX(CallUserSpace): cli ; Save nonvolatile registers EBX, EBP, EDI, ESI, ESP. push ebx @@ -194,11 +194,11 @@ ASM_PFX(CallRing3): mov ecx, MSR_IA32_SYSENTER_ESP wrmsr - SetRing3DataSegmentSelectors + SetUserSpaceDataSegmentSelectors ; Prepare SYSEXIT arguments. mov ecx, [esp + 4 * 7] ; UserStackTop - mov edx, [ASM_PFX(gRing3EntryPoint)] + mov edx, [ASM_PFX(gUserSpaceEntryPoint)] mov eax, [esp + 4 * 6] ; Data ; Switch to User Stack. diff --git a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c index dd9b34e284..c8cad76327 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c +++ b/MdeModulePkg/Core/Dxe/SysCall/IA32/InitializeIA32.c @@ -1,6 +1,6 @@ /** @file - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause **/ @@ -150,7 +150,7 @@ InitializePlatform ( // // Initialize MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_EIP for SYSENTER and SYSEXIT. - // MSR_IA32_SYSENTER_ESP is set in CallRing3(). + // MSR_IA32_SYSENTER_ESP is set in CallUserSpace(). // Msr = RING0_CODE32_SEL; AsmWriteMsr64 (MSR_IA32_SYSENTER_CS, Msr); diff --git a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c index b3a731ce63..a4ed2cfed5 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/Initialization.c +++ b/MdeModulePkg/Core/Dxe/SysCall/Initialization.c @@ -7,15 +7,15 @@ #include "DxeMain.h" -VOID *gRing3EntryPoint; -RING3_DATA *gRing3Data; -VOID *gRing3Interfaces; +VOID *gUserSpaceEntryPoint; +USER_SPACE_DATA *gUserSpaceData; +VOID *gUserSpaceInterfaces; EXCEPTION_ADDRESSES *mExceptionAddresses; extern UINTN SysCallBase; extern UINTN SysCallEnd; -STATIC UEFI_IMAGE_RECORD *mDxeRing3; +STATIC UEFI_IMAGE_RECORD *mDxeUserSpace; STATIC EFI_PHYSICAL_ADDRESS mCoreStackBase; STATIC UINT64 mCoreStackSize; @@ -40,7 +40,7 @@ MapPlatform ( EFI_STATUS EFIAPI -InitializeRing3 ( +InitializeUserSpace ( IN EFI_HANDLE ImageHandle, IN LOADED_IMAGE_PRIVATE_DATA *Image ) @@ -51,75 +51,75 @@ InitializeRing3 ( EFI_HOB_MEMORY_ALLOCATION *MemoryHob; // - // Set Ring3 EntryPoint and BootServices. + // Set UserSpace EntryPoint and BootServices. // Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, - EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)), + EfiUserSpaceMemoryType, + EFI_SIZE_TO_PAGES (sizeof (USER_SPACE_DATA)), &Physical ); if (EFI_ERROR (Status)) { return Status; } - gRing3Data = (RING3_DATA *)(UINTN)Physical; + gUserSpaceData = (USER_SPACE_DATA *)(UINTN)Physical; - CopyMem ((VOID *)gRing3Data, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); + CopyMem ((VOID *)gUserSpaceData, (VOID *)Image->Info.SystemTable, sizeof (EFI_SYSTEM_TABLE)); SetUefiImageMemoryAttributes ( - (UINTN)gRing3Data, - ALIGN_VALUE (sizeof (RING3_DATA), EFI_PAGE_SIZE), + (UINTN)gUserSpaceData, + ALIGN_VALUE (sizeof (USER_SPACE_DATA), EFI_PAGE_SIZE), EFI_MEMORY_XP | EFI_MEMORY_USER ); - Status = InitializePlatform (&gRing3Data->SystemTable); + Status = InitializePlatform (&gUserSpaceData->SystemTable); if (EFI_ERROR (Status)) { CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, - EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + (EFI_PHYSICAL_ADDRESS)(UINTN)gUserSpaceData, + EFI_SIZE_TO_PAGES (sizeof (USER_SPACE_DATA)) ); return Status; } // - // Initialize DxeRing3 with Supervisor privileges. + // Initialize DxeUserSpace with Supervisor privileges. // - mDxeRing3 = GetUefiImageRecord (Image); - ASSERT (mDxeRing3 != NULL); + mDxeUserSpace = GetUefiImageRecord (Image); + ASSERT (mDxeUserSpace != NULL); - SetUefiImageProtectionAttributes (mDxeRing3, FALSE); + SetUefiImageProtectionAttributes (mDxeUserSpace, FALSE); AllowSupervisorAccessToUserMemory (); - Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gRing3Data); + Status = Image->EntryPoint (ImageHandle, (EFI_SYSTEM_TABLE *)gUserSpaceData); - gRing3EntryPoint = gRing3Data->EntryPoint; + gUserSpaceEntryPoint = gUserSpaceData->EntryPoint; - gRing3Data->SystemTable.BootServices = gRing3Data->BootServices; - gRing3Data->SystemTable.RuntimeServices = gRing3Data->RuntimeServices; + gUserSpaceData->SystemTable.BootServices = gUserSpaceData->BootServices; + gUserSpaceData->SystemTable.RuntimeServices = gUserSpaceData->RuntimeServices; ForbidSupervisorAccessToUserMemory (); - SetUefiImageProtectionAttributes (mDxeRing3, TRUE); + SetUefiImageProtectionAttributes (mDxeUserSpace, TRUE); Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, - RING3_INTERFACES_PAGES, + EfiUserSpaceMemoryType, + USER_SPACE_INTERFACES_PAGES, &Physical ); if (EFI_ERROR (Status)) { CoreFreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)gRing3Data, - EFI_SIZE_TO_PAGES (sizeof (RING3_DATA)) + (EFI_PHYSICAL_ADDRESS)(UINTN)gUserSpaceData, + EFI_SIZE_TO_PAGES (sizeof (USER_SPACE_DATA)) ); return Status; } - gRing3Interfaces = (VOID *)(UINTN)Physical; + gUserSpaceInterfaces = (VOID *)(UINTN)Physical; SetUefiImageMemoryAttributes ( - (UINTN)gRing3Interfaces, - EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES), + (UINTN)gUserSpaceInterfaces, + EFI_PAGES_TO_SIZE (USER_SPACE_INTERFACES_PAGES), EFI_MEMORY_XP | EFI_MEMORY_USER ); @@ -161,27 +161,27 @@ InitializeUserPageTable ( } // - // Map gRing3Data, gRing3Interfaces, DxeRing3 + // Map gUserSpaceData, gUserSpaceInterfaces, DxeUserSpace // gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, - (UINTN)gRing3Data, - ALIGN_VALUE (sizeof (RING3_DATA), EFI_PAGE_SIZE), + (UINTN)gUserSpaceData, + ALIGN_VALUE (sizeof (USER_SPACE_DATA), EFI_PAGE_SIZE), EFI_MEMORY_XP | EFI_MEMORY_USER ); gCpu->SetUserMemoryAttributes ( gCpu, UserPageTable, - (UINTN)gRing3Interfaces, - EFI_PAGES_TO_SIZE (RING3_INTERFACES_PAGES), + (UINTN)gUserSpaceInterfaces, + EFI_PAGES_TO_SIZE (USER_SPACE_INTERFACES_PAGES), EFI_MEMORY_XP | EFI_MEMORY_USER ); - SectionAddress = mDxeRing3->StartAddress; - for (Index = 0; Index < mDxeRing3->NumSegments; Index++) { - ImageRecordSegment = &mDxeRing3->Segments[Index]; + SectionAddress = mDxeUserSpace->StartAddress; + for (Index = 0; Index < mDxeUserSpace->NumSegments; Index++) { + ImageRecordSegment = &mDxeUserSpace->Segments[Index]; gCpu->SetUserMemoryAttributes ( gCpu, diff --git a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c index 448806aad4..92b6dfafcf 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c +++ b/MdeModulePkg/Core/Dxe/SysCall/SupportedProtocols.c @@ -14,26 +14,26 @@ LIST_ENTRY gUserSpaceDriversHead = INITIALIZE_LIST_HEAD_VARIABLE (gUserSpaceDriv EFI_STATUS EFIAPI -CallRing3 ( - IN RING3_CALL_DATA *Data, - IN UINTN UserStackTop +CallUserSpace ( + IN USER_SPACE_CALL_DATA *Data, + IN UINTN UserStackTop ); EFI_STATUS EFIAPI -GoToRing3 ( +GoToUserSpace ( IN UINT8 Number, IN VOID *EntryPoint, IN USER_SPACE_DRIVER *UserDriver, ... ) { - EFI_STATUS Status; - RING3_CALL_DATA *Input; - VA_LIST Marker; - UINTN Index; - UINTN UserStackTop; - UINTN UserStackBase; + EFI_STATUS Status; + USER_SPACE_CALL_DATA *Input; + VA_LIST Marker; + UINTN Index; + UINTN UserStackTop; + UINTN UserStackBase; if (UserDriver->NumberOfCalls > MAX_CALL) { return EFI_OUT_OF_RESOURCES; @@ -44,9 +44,9 @@ GoToRing3 ( return EFI_OUT_OF_RESOURCES; } - UserStackTop = UserStackBase + STACK_SIZE - (sizeof (RING3_CALL_DATA) + Number * sizeof (UINTN)); + UserStackTop = UserStackBase + STACK_SIZE - (sizeof (USER_SPACE_CALL_DATA) + Number * sizeof (UINTN)); - Input = (RING3_CALL_DATA *)UserStackTop; + Input = (USER_SPACE_CALL_DATA *)UserStackTop; Input->NumberOfArguments = Number; Input->EntryPoint = EntryPoint; @@ -73,7 +73,7 @@ GoToRing3 ( // UserStackTop = ALIGN_VALUE (UserStackTop - 8*4 - CPU_STACK_ALIGNMENT, CPU_STACK_ALIGNMENT); - Status = CallRing3 ( + Status = CallUserSpace ( Input, UserStackTop ); @@ -133,7 +133,7 @@ CoreDriverBindingSupported ( EntryPoint = (VOID *)This->Supported; ForbidSupervisorAccessToUserMemory (); - Status = GoToRing3 ( + Status = GoToUserSpace ( 3, EntryPoint, UserDriver, @@ -169,7 +169,7 @@ CoreDriverBindingStart ( EntryPoint = (VOID *)This->Start; ForbidSupervisorAccessToUserMemory (); - Status = GoToRing3 ( + Status = GoToUserSpace ( 3, EntryPoint, UserDriver, @@ -206,7 +206,7 @@ CoreDriverBindingStop ( EntryPoint = (VOID *)This->Stop; ForbidSupervisorAccessToUserMemory (); - Status = GoToRing3 ( + Status = GoToUserSpace ( 4, EntryPoint, UserDriver, @@ -242,7 +242,7 @@ CoreFileClose ( EntryPoint = (VOID *)This->Close; ForbidSupervisorAccessToUserMemory (); - Status = GoToRing3 ( + Status = GoToUserSpace ( 1, EntryPoint, UserDriver, @@ -278,9 +278,9 @@ CoreFileRead ( ) { EFI_STATUS Status; - UINTN *Ring3BufferSize; - VOID *Ring3Buffer; - EFI_PHYSICAL_ADDRESS Ring3Pages; + UINTN *UserSpaceBufferSize; + VOID *UserSpaceBuffer; + EFI_PHYSICAL_ADDRESS UserSpacePages; UINT32 PagesNumber; USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; @@ -290,57 +290,57 @@ CoreFileRead ( return EFI_INVALID_PARAMETER; } // - // gUserPageTable must be set before alloctation of EfiRing3MemoryType pages. + // gUserPageTable must be set before alloctation of EfiUserSpaceMemoryType pages. // UserDriver = FindUserSpaceDriver (This, &OldPageTable); ASSERT (UserDriver != NULL); This = UserDriver->UserSpaceDriver; - Ring3Buffer = NULL; - Ring3Pages = 0; - PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize); + UserSpaceBuffer = NULL; + UserSpacePages = 0; + PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize); Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, PagesNumber, - &Ring3Pages + &UserSpacePages ); if (EFI_ERROR (Status)) { gUserPageTable = OldPageTable; return Status; } - Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; + UserSpaceBufferSize = (UINTN *)(UINTN)UserSpacePages; AllowSupervisorAccessToUserMemory (); - *Ring3BufferSize = *BufferSize; - EntryPoint = (VOID *)This->Read; + *UserSpaceBufferSize = *BufferSize; + EntryPoint = (VOID *)This->Read; ForbidSupervisorAccessToUserMemory (); if (Buffer != NULL) { - Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); + UserSpaceBuffer = (VOID *)((UINTN *)(UINTN)UserSpacePages + 1); } - Status = GoToRing3 ( + Status = GoToUserSpace ( 3, EntryPoint, UserDriver, This, - Ring3BufferSize, - Ring3Buffer + UserSpaceBufferSize, + UserSpaceBuffer ); AllowSupervisorAccessToUserMemory (); - if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { - CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); + if ((UserSpaceBuffer != NULL) && (Buffer != NULL) && (*BufferSize >= *UserSpaceBufferSize)) { + CopyMem (Buffer, UserSpaceBuffer, *UserSpaceBufferSize); } - *BufferSize = *Ring3BufferSize; + *BufferSize = *UserSpaceBufferSize; ForbidSupervisorAccessToUserMemory (); - CoreFreePages (Ring3Pages, PagesNumber); + CoreFreePages (UserSpacePages, PagesNumber); gUserPageTable = OldPageTable; @@ -382,7 +382,7 @@ CoreFileSetPosition ( ForbidSupervisorAccessToUserMemory (); #if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) - Status = GoToRing3 ( + Status = GoToUserSpace ( 2, EntryPoint, UserDriver, @@ -393,7 +393,7 @@ CoreFileSetPosition ( // // UINT64 Position is passed as 2 double words on stack. // - Status = GoToRing3 ( + Status = GoToUserSpace ( 3, EntryPoint, UserDriver, @@ -405,7 +405,7 @@ CoreFileSetPosition ( // UINT64 Position is passed as 2 words in 2 registers and is aligned on 8 bytes. // R0 == This, R1 == NULL, R2 == Position_Low, R3 == Position_High. // - Status = GoToRing3 ( + Status = GoToUserSpace ( 4, EntryPoint, UserDriver, @@ -430,7 +430,7 @@ CoreFileGetPosition ( ) { EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Ring3Position; + EFI_PHYSICAL_ADDRESS UserSpacePosition; USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; UINTN OldPageTable; @@ -446,9 +446,9 @@ CoreFileGetPosition ( Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, 1, - &Ring3Position + &UserSpacePosition ); if (EFI_ERROR (Status)) { gUserPageTable = OldPageTable; @@ -456,23 +456,23 @@ CoreFileGetPosition ( } AllowSupervisorAccessToUserMemory (); - *(UINT64 *)(UINTN)Ring3Position = *Position; - EntryPoint = (VOID *)This->GetPosition; + *(UINT64 *)(UINTN)UserSpacePosition = *Position; + EntryPoint = (VOID *)This->GetPosition; ForbidSupervisorAccessToUserMemory (); - Status = GoToRing3 ( + Status = GoToUserSpace ( 2, EntryPoint, UserDriver, This, - Ring3Position + UserSpacePosition ); AllowSupervisorAccessToUserMemory (); - *Position = *(UINT64 *)(UINTN)Ring3Position; + *Position = *(UINT64 *)(UINTN)UserSpacePosition; ForbidSupervisorAccessToUserMemory (); - CoreFreePages (Ring3Position, 1); + CoreFreePages (UserSpacePosition, 1); gUserPageTable = OldPageTable; @@ -490,10 +490,10 @@ CoreFileGetInfo ( ) { EFI_STATUS Status; - EFI_GUID *Ring3InformationType; - UINTN *Ring3BufferSize; - VOID *Ring3Buffer; - EFI_PHYSICAL_ADDRESS Ring3Pages; + EFI_GUID *UserSpaceInformationType; + UINTN *UserSpaceBufferSize; + VOID *UserSpaceBuffer; + EFI_PHYSICAL_ADDRESS UserSpacePages; UINT32 PagesNumber; USER_SPACE_DRIVER *UserDriver; VOID *EntryPoint; @@ -508,61 +508,61 @@ CoreFileGetInfo ( This = UserDriver->UserSpaceDriver; - Ring3Buffer = NULL; - Ring3InformationType = NULL; - Ring3Pages = 0; + UserSpaceBuffer = NULL; + UserSpaceInformationType = NULL; + UserSpacePages = 0; PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (UINTN *) + *BufferSize + sizeof (EFI_GUID)); Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, PagesNumber, - &Ring3Pages + &UserSpacePages ); if (EFI_ERROR (Status)) { gUserPageTable = OldPageTable; return Status; } - Ring3BufferSize = (UINTN *)(UINTN)Ring3Pages; + UserSpaceBufferSize = (UINTN *)(UINTN)UserSpacePages; AllowSupervisorAccessToUserMemory (); - *Ring3BufferSize = *BufferSize; - EntryPoint = (VOID *)This->GetInfo; + *UserSpaceBufferSize = *BufferSize; + EntryPoint = (VOID *)This->GetInfo; ForbidSupervisorAccessToUserMemory (); if (Buffer != NULL) { - Ring3Buffer = (VOID *)((UINTN *)(UINTN)Ring3Pages + 1); + UserSpaceBuffer = (VOID *)((UINTN *)(UINTN)UserSpacePages + 1); } if (InformationType != NULL) { - Ring3InformationType = (EFI_GUID *)((UINTN)Ring3Pages + sizeof (UINTN *) + *BufferSize); + UserSpaceInformationType = (EFI_GUID *)((UINTN)UserSpacePages + sizeof (UINTN *) + *BufferSize); AllowSupervisorAccessToUserMemory (); - CopyGuid (Ring3InformationType, InformationType); + CopyGuid (UserSpaceInformationType, InformationType); ForbidSupervisorAccessToUserMemory (); } - Status = GoToRing3 ( + Status = GoToUserSpace ( 4, EntryPoint, UserDriver, This, - Ring3InformationType, - Ring3BufferSize, - Ring3Buffer + UserSpaceInformationType, + UserSpaceBufferSize, + UserSpaceBuffer ); AllowSupervisorAccessToUserMemory (); - if ((Ring3Buffer != NULL) && (Buffer != NULL) && (*BufferSize >= *Ring3BufferSize)) { - CopyMem (Buffer, Ring3Buffer, *Ring3BufferSize); + if ((UserSpaceBuffer != NULL) && (Buffer != NULL) && (*BufferSize >= *UserSpaceBufferSize)) { + CopyMem (Buffer, UserSpaceBuffer, *UserSpaceBufferSize); } - *BufferSize = *Ring3BufferSize; + *BufferSize = *UserSpaceBufferSize; ForbidSupervisorAccessToUserMemory (); - CoreFreePages (Ring3Pages, PagesNumber); + CoreFreePages (UserSpacePages, PagesNumber); gUserPageTable = OldPageTable; @@ -653,9 +653,9 @@ CoreFileOpen ( { EFI_STATUS Status; EFI_FILE_PROTOCOL *NewFile; - EFI_FILE_PROTOCOL **Ring3NewHandle; - CHAR16 *Ring3FileName; - EFI_PHYSICAL_ADDRESS Ring3Pages; + EFI_FILE_PROTOCOL **UserSpaceNewHandle; + CHAR16 *UserSpaceFileName; + EFI_PHYSICAL_ADDRESS UserSpacePages; UINT32 PagesNumber; USER_SPACE_DRIVER *UserDriver; USER_SPACE_DRIVER *NewDriver; @@ -671,17 +671,17 @@ CoreFileOpen ( This = UserDriver->UserSpaceDriver; - Ring3NewHandle = NULL; - Ring3FileName = NULL; - Ring3Pages = 0; + UserSpaceNewHandle = NULL; + UserSpaceFileName = NULL; + UserSpacePages = 0; PagesNumber = (UINT32)EFI_SIZE_TO_PAGES (sizeof (EFI_FILE_PROTOCOL *) + StrSize (FileName)); Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, PagesNumber, - &Ring3Pages + &UserSpacePages ); if (EFI_ERROR (Status)) { *NewHandle = NULL; @@ -689,28 +689,28 @@ CoreFileOpen ( return Status; } - Ring3NewHandle = (EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages; - Ring3FileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)(UINTN)Ring3Pages + 1); + UserSpaceNewHandle = (EFI_FILE_PROTOCOL **)(UINTN)UserSpacePages; + UserSpaceFileName = (CHAR16 *)((EFI_FILE_PROTOCOL **)(UINTN)UserSpacePages + 1); AllowSupervisorAccessToUserMemory (); - Status = StrCpyS (Ring3FileName, StrLen (FileName) + 1, FileName); + Status = StrCpyS (UserSpaceFileName, StrLen (FileName) + 1, FileName); EntryPoint = (VOID *)This->Open; ForbidSupervisorAccessToUserMemory (); if (EFI_ERROR (Status)) { *NewHandle = NULL; - CoreFreePages (Ring3Pages, PagesNumber); + CoreFreePages (UserSpacePages, PagesNumber); gUserPageTable = OldPageTable; return Status; } #if defined (MDE_CPU_X64) || defined (MDE_CPU_AARCH64) - Status = GoToRing3 ( + Status = GoToUserSpace ( 5, EntryPoint, UserDriver, This, - Ring3NewHandle, - Ring3FileName, + UserSpaceNewHandle, + UserSpaceFileName, OpenMode, Attributes ); @@ -718,13 +718,13 @@ CoreFileOpen ( // // UINT64 OpenMode and Attributes are each passed as 2 double words on stack. // - Status = GoToRing3 ( + Status = GoToUserSpace ( 7, EntryPoint, UserDriver, This, - Ring3NewHandle, - Ring3FileName, + UserSpaceNewHandle, + UserSpaceFileName, OpenMode, Attributes ); @@ -732,16 +732,16 @@ CoreFileOpen ( // // UINT64 OpenMode and Attributes are each passed as 2 words on stack. // Each of them is aligned on 8 bytes. - // R0 == This, R1 == Ring3NewHandle, R2 == Ring3FileName, R3 == NULL, + // R0 == This, R1 == UserSpaceNewHandle, R2 == UserSpaceFileName, R3 == NULL, // [SP] == OpenMode, [SP + 8] == Attributes. // - Status = GoToRing3 ( + Status = GoToUserSpace ( 8, EntryPoint, UserDriver, This, - Ring3NewHandle, - Ring3FileName, + UserSpaceNewHandle, + UserSpaceFileName, NULL, (UINT32)OpenMode, (UINT32)(OpenMode >> 32), @@ -751,7 +751,7 @@ CoreFileOpen ( #endif if (EFI_ERROR (Status)) { *NewHandle = NULL; - CoreFreePages (Ring3Pages, PagesNumber); + CoreFreePages (UserSpacePages, PagesNumber); gUserPageTable = OldPageTable; return Status; } @@ -759,7 +759,7 @@ CoreFileOpen ( NewFile = AllocatePool (sizeof (EFI_FILE_PROTOCOL)); if (NewFile == NULL) { *NewHandle = NULL; - CoreFreePages (Ring3Pages, PagesNumber); + CoreFreePages (UserSpacePages, PagesNumber); gUserPageTable = OldPageTable; return EFI_OUT_OF_RESOURCES; } @@ -768,7 +768,7 @@ CoreFileOpen ( if (NewDriver == NULL) { *NewHandle = NULL; FreePool (NewFile); - CoreFreePages (Ring3Pages, PagesNumber); + CoreFreePages (UserSpacePages, PagesNumber); gUserPageTable = OldPageTable; return EFI_OUT_OF_RESOURCES; } @@ -778,8 +778,8 @@ CoreFileOpen ( NewDriver->NumberOfCalls = 0; AllowSupervisorAccessToUserMemory (); - NewDriver->UserSpaceDriver = *Ring3NewHandle; - NewFile->Revision = (*Ring3NewHandle)->Revision; + NewDriver->UserSpaceDriver = *UserSpaceNewHandle; + NewFile->Revision = (*UserSpaceNewHandle)->Revision; ForbidSupervisorAccessToUserMemory (); InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); @@ -801,7 +801,7 @@ CoreFileOpen ( *NewHandle = (EFI_FILE_PROTOCOL *)NewFile; - CoreFreePages (Ring3Pages, PagesNumber); + CoreFreePages (UserSpacePages, PagesNumber); gUserPageTable = OldPageTable; @@ -816,7 +816,7 @@ CoreSimpleFileSystemOpenVolume ( ) { EFI_STATUS Status; - EFI_FILE_PROTOCOL **Ring3Root; + EFI_FILE_PROTOCOL **UserSpaceRoot; EFI_FILE_PROTOCOL *File; EFI_PHYSICAL_ADDRESS Physical; USER_SPACE_DRIVER *UserDriver; @@ -839,7 +839,7 @@ CoreSimpleFileSystemOpenVolume ( Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, 1, &Physical ); @@ -849,14 +849,14 @@ CoreSimpleFileSystemOpenVolume ( return Status; } - Ring3Root = (EFI_FILE_PROTOCOL **)(UINTN)Physical; + UserSpaceRoot = (EFI_FILE_PROTOCOL **)(UINTN)Physical; - Status = GoToRing3 ( + Status = GoToUserSpace ( 2, EntryPoint, UserDriver, This, - Ring3Root + UserSpaceRoot ); if (EFI_ERROR (Status)) { *Root = NULL; @@ -887,8 +887,8 @@ CoreSimpleFileSystemOpenVolume ( NewDriver->NumberOfCalls = 0; AllowSupervisorAccessToUserMemory (); - NewDriver->UserSpaceDriver = *Ring3Root; - File->Revision = (*Ring3Root)->Revision; + NewDriver->UserSpaceDriver = *UserSpaceRoot; + File->Revision = (*UserSpaceRoot)->Revision; ForbidSupervisorAccessToUserMemory (); InsertTailList (&gUserSpaceDriversHead, &NewDriver->Link); @@ -943,7 +943,7 @@ CoreUnicodeCollationStriColl ( Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, EFI_SIZE_TO_PAGES (Size1 + Size2), &UserMem ); @@ -958,7 +958,7 @@ CoreUnicodeCollationStriColl ( EntryPoint = (VOID *)This->StriColl; ForbidSupervisorAccessToUserMemory (); - Status = GoToRing3 ( + Status = GoToUserSpace ( 3, EntryPoint, UserDriver, @@ -1000,7 +1000,7 @@ CoreUnicodeCollationMetaiMatch ( Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, EFI_SIZE_TO_PAGES (Size1 + Size2), &UserMem ); @@ -1015,7 +1015,7 @@ CoreUnicodeCollationMetaiMatch ( EntryPoint = (VOID *)This->MetaiMatch; ForbidSupervisorAccessToUserMemory (); - Status = GoToRing3 ( + Status = GoToUserSpace ( 3, EntryPoint, UserDriver, @@ -1054,7 +1054,7 @@ CoreUnicodeCollationStrLwr ( Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, EFI_SIZE_TO_PAGES (Size1), &UserMem ); @@ -1068,7 +1068,7 @@ CoreUnicodeCollationStrLwr ( EntryPoint = (VOID *)This->StrLwr; ForbidSupervisorAccessToUserMemory (); - Status = GoToRing3 ( + Status = GoToUserSpace ( 2, EntryPoint, UserDriver, @@ -1108,7 +1108,7 @@ CoreUnicodeCollationStrUpr ( Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, EFI_SIZE_TO_PAGES (Size1), &UserMem ); @@ -1122,7 +1122,7 @@ CoreUnicodeCollationStrUpr ( EntryPoint = (VOID *)This->StrUpr; ForbidSupervisorAccessToUserMemory (); - Status = GoToRing3 ( + Status = GoToUserSpace ( 2, EntryPoint, UserDriver, @@ -1161,7 +1161,7 @@ CoreUnicodeCollationFatToStr ( Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, EFI_SIZE_TO_PAGES (FatSize * 3), &UserMem ); @@ -1175,7 +1175,7 @@ CoreUnicodeCollationFatToStr ( EntryPoint = (VOID *)This->FatToStr; ForbidSupervisorAccessToUserMemory (); - Status = GoToRing3 ( + Status = GoToUserSpace ( 4, EntryPoint, UserDriver, @@ -1219,7 +1219,7 @@ CoreUnicodeCollationStrToFat ( Status = CoreAllocatePages ( AllocateAnyPages, - EfiRing3MemoryType, + EfiUserSpaceMemoryType, EFI_SIZE_TO_PAGES (FatSize + Size1), &UserMem ); @@ -1233,7 +1233,7 @@ CoreUnicodeCollationStrToFat ( EntryPoint = (VOID *)This->StrToFat; ForbidSupervisorAccessToUserMemory (); - Status = GoToRing3 ( + Status = GoToUserSpace ( 4, EntryPoint, UserDriver, diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm index 8d09253158..c827f7c7c1 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/CoreBootServices.nasm @@ -8,7 +8,7 @@ #include extern ASM_PFX(CallBootService) -extern ASM_PFX(gRing3EntryPoint) +extern ASM_PFX(gUserSpaceEntryPoint) DEFAULT REL SECTION .text @@ -89,7 +89,7 @@ copy: ret -%macro SetRing3DataSegmentSelectors 0 +%macro SetUserSpaceDataSegmentSelectors 0 mov rcx, MSR_IA32_STAR rdmsr shl rdx, 0x20 @@ -157,7 +157,7 @@ ASM_PFX(CoreBootServices): push rax cli - SetRing3DataSegmentSelectors + SetUserSpaceDataSegmentSelectors pop rax @@ -181,16 +181,16 @@ o64 sysret ;------------------------------------------------------------------------------ ; EFI_STATUS ; EFIAPI -; CallRing3 ( -; IN RING3_CALL_DATA *Data, -; IN UINTN UserStackTop +; CallUserSpace ( +; IN USER_SPACE_CALL_DATA *Data, +; IN UINTN UserStackTop ; ); ; ; (rcx) Data ; (rdx) UserStackTop ;------------------------------------------------------------------------------ -global ASM_PFX(CallRing3) -ASM_PFX(CallRing3): +global ASM_PFX(CallUserSpace) +ASM_PFX(CallUserSpace): pushfq pop r11 cli @@ -211,11 +211,11 @@ ASM_PFX(CallRing3): mov rbx, rdx mov r10, rcx - SetRing3DataSegmentSelectors + SetUserSpaceDataSegmentSelectors ; Prepare SYSRET arguments. mov rdx, r10 - mov rcx, [ASM_PFX(gRing3EntryPoint)] + mov rcx, [ASM_PFX(gUserSpaceEntryPoint)] ; Switch to User Stack. mov rsp, rbx diff --git a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c index fe87433b83..c8fd6884c5 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/X64/InitializeX64.c @@ -1,6 +1,6 @@ /** @file - Copyright (c) 2024, Mikhail Krichanov. All rights reserved. + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. SPDX-License-Identifier: BSD-3-Clause **/ diff --git a/MdeModulePkg/Include/Library/MemoryPoolLib.h b/MdeModulePkg/Include/Library/MemoryPoolLib.h index c3ee7c8e62..bf459cdb13 100644 --- a/MdeModulePkg/Include/Library/MemoryPoolLib.h +++ b/MdeModulePkg/Include/Library/MemoryPoolLib.h @@ -43,7 +43,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent @param IsCore Selects between the purposes of mPoolHead array. In DxeCore each element describes EFI_MEMORY_TYPE. - In DxeRing3 each element describes User space. + In DxeUserSpace each element describes User space. **/ VOID diff --git a/MdePkg/Include/Uefi/UefiMultiPhase.h b/MdePkg/Include/Uefi/UefiMultiPhase.h index f0beb4a23d..c733802fee 100644 --- a/MdePkg/Include/Uefi/UefiMultiPhase.h +++ b/MdePkg/Include/Uefi/UefiMultiPhase.h @@ -109,9 +109,9 @@ typedef enum { /// EfiUnacceptedMemoryType, /// - /// Memory allocated for (by) Ring3 Images. + /// Memory allocated for (by) UserSpace Images. /// - EfiRing3MemoryType, + EfiUserSpaceMemoryType, EfiMaxMemoryType, // // +---------------------------------------------------+ diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h index 26aba3d1a1..42c01cc557 100644 --- a/MdePkg/Include/Uefi/UefiSpec.h +++ b/MdePkg/Include/Uefi/UefiSpec.h @@ -2163,13 +2163,13 @@ typedef struct { VOID *EntryPoint; EFI_BOOT_SERVICES *BootServices; EFI_RUNTIME_SERVICES *RuntimeServices; -} RING3_DATA; +} USER_SPACE_DATA; typedef struct { UINT8 NumberOfArguments; VOID *EntryPoint; UINTN Arguments[]; -} RING3_CALL_DATA; +} USER_SPACE_CALL_DATA; /** This is the declaration of an EFI image entry point. This entry point is From 311f57c5190a49049153fd01286faa8e1107206b Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 3 Feb 2025 14:13:49 +0300 Subject: [PATCH 336/341] Ring3: Renamed Ring3 files as UserSpace. --- ArmVirtPkg/ArmVirtQemu.dsc | 2 +- ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 6 +++--- MdeModulePkg/Core/Dxe/DxeMain.inf | 8 ++++---- .../{DxeRing3 => DxeUserSpace}/AARCH64/SysCall.S | 0 .../Dxe/{DxeRing3 => DxeUserSpace}/ARM/SysCall.S | 0 .../DxeRing3.c => DxeUserSpace/DxeUserSpace.c} | 2 +- .../DxeUserSpace.inf} | 12 ++++++------ .../{DxeRing3 => DxeUserSpace}/IA32/SysCall.nasm | 0 .../Ring3.h => DxeUserSpace/UserSpace.h} | 0 .../UserSpaceProtocols.c} | 2 +- .../UserSpaceUefiBootServices.c} | 2 +- .../UserSpaceUefiRuntimeServices.c} | 16 ++++++++-------- .../{DxeRing3 => DxeUserSpace}/X64/SysCall.nasm | 0 MdeModulePkg/MdeModulePkg.dec | 4 ++-- MdeModulePkg/MdeModulePkg.dsc | 2 +- OvmfPkg/OvmfPkgIa32.dsc | 2 +- OvmfPkg/OvmfPkgIa32.fdf | 8 ++++---- OvmfPkg/OvmfPkgIa32X64.dsc | 2 +- OvmfPkg/OvmfPkgIa32X64.fdf | 8 ++++---- OvmfPkg/OvmfPkgX64.dsc | 2 +- OvmfPkg/OvmfPkgX64.fdf | 6 +++--- UefiPayloadPkg/UefiPayloadPkg.dsc | 2 +- UefiPayloadPkg/UefiPayloadPkg.fdf | 4 ++-- 23 files changed, 45 insertions(+), 45 deletions(-) rename MdeModulePkg/Core/Dxe/{DxeRing3 => DxeUserSpace}/AARCH64/SysCall.S (100%) rename MdeModulePkg/Core/Dxe/{DxeRing3 => DxeUserSpace}/ARM/SysCall.S (100%) rename MdeModulePkg/Core/Dxe/{DxeRing3/DxeRing3.c => DxeUserSpace/DxeUserSpace.c} (97%) rename MdeModulePkg/Core/Dxe/{DxeRing3/DxeRing3.inf => DxeUserSpace/DxeUserSpace.inf} (85%) rename MdeModulePkg/Core/Dxe/{DxeRing3 => DxeUserSpace}/IA32/SysCall.nasm (100%) rename MdeModulePkg/Core/Dxe/{DxeRing3/Ring3.h => DxeUserSpace/UserSpace.h} (100%) rename MdeModulePkg/Core/Dxe/{DxeRing3/Ring3Protocols.c => DxeUserSpace/UserSpaceProtocols.c} (94%) rename MdeModulePkg/Core/Dxe/{DxeRing3/Ring3UefiBootServices.c => DxeUserSpace/UserSpaceUefiBootServices.c} (95%) rename MdeModulePkg/Core/Dxe/{DxeRing3/Ring3UefiRuntimeServices.c => DxeUserSpace/UserSpaceUefiRuntimeServices.c} (94%) rename MdeModulePkg/Core/Dxe/{DxeRing3 => DxeUserSpace}/X64/SysCall.nasm (100%) diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc index f2cfc9620d..f9000a3d86 100644 --- a/ArmVirtPkg/ArmVirtQemu.dsc +++ b/ArmVirtPkg/ArmVirtQemu.dsc @@ -476,7 +476,7 @@ DebugLib|ArmVirtPkg/Library/DebugLibFdtPL011Uart/DebugLibFdtPL011UartUser.inf !endif } - MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { + MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf { MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf !if $(TARGET) != RELEASE diff --git a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc index 9579d1532d..af2ab17088 100644 --- a/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc +++ b/ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc @@ -40,9 +40,9 @@ READ_LOCK_STATUS = TRUE APRIORI DXE { INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf - # The driver responsible for UserSpace initialization (DxeRing3.inf) + # The driver responsible for UserSpace initialization (DxeUserSpace.inf) # must be the first USER driver in APRIORI list. - INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf + INF MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf } INF MdeModulePkg/Core/Dxe/DxeMain.inf @@ -89,7 +89,7 @@ APRIORI DXE { INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf INF USER FatPkg/EnhancedFatDxe/Fat.inf - INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf + INF USER MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf INF USER MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 3aa681febb..287b02a935 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -228,10 +228,10 @@ gEfiMdePkgTokenSpaceGuid.PcdDebugRaisePropertyMask ## CONSUMES gEfiMdePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES -[Pcd.IA32, Pcd.X64] - gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES +[Pcd.IA32, Pcd.X64] + gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdUse5LevelPageTable ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaBase ## CONSUMES gUefiOvmfPkgTokenSpaceGuid.PcdOvmfWorkAreaSize ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S b/MdeModulePkg/Core/Dxe/DxeUserSpace/AARCH64/SysCall.S similarity index 100% rename from MdeModulePkg/Core/Dxe/DxeRing3/AARCH64/SysCall.S rename to MdeModulePkg/Core/Dxe/DxeUserSpace/AARCH64/SysCall.S diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S b/MdeModulePkg/Core/Dxe/DxeUserSpace/ARM/SysCall.S similarity index 100% rename from MdeModulePkg/Core/Dxe/DxeRing3/ARM/SysCall.S rename to MdeModulePkg/Core/Dxe/DxeUserSpace/ARM/SysCall.S diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c b/MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.c similarity index 97% rename from MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c rename to MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.c index 04dfef8d76..457fffb669 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.c +++ b/MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.c @@ -13,7 +13,7 @@ #include #include -#include "Ring3.h" +#include "UserSpace.h" EFI_BOOT_SERVICES mBootServices = { { diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf b/MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf similarity index 85% rename from MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf rename to MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf index fd01cf0795..f008d37436 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +++ b/MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf @@ -9,7 +9,7 @@ [Defines] INF_VERSION = 0x00010005 - BASE_NAME = DxeRing3 + BASE_NAME = DxeUserSpace FILE_GUID = 88EA50C2-0DEA-4F13-B691-B506554E632B MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 @@ -22,11 +22,11 @@ # [Sources] - Ring3.h - DxeRing3.c - Ring3UefiBootServices.c - Ring3UefiRuntimeServices.c - Ring3Protocols.c + UserSpace.h + DxeUserSpace.c + UserSpaceUefiBootServices.c + UserSpaceUefiRuntimeServices.c + UserSpaceProtocols.c [Sources.IA32] IA32/SysCall.nasm diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeUserSpace/IA32/SysCall.nasm similarity index 100% rename from MdeModulePkg/Core/Dxe/DxeRing3/IA32/SysCall.nasm rename to MdeModulePkg/Core/Dxe/DxeUserSpace/IA32/SysCall.nasm diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h b/MdeModulePkg/Core/Dxe/DxeUserSpace/UserSpace.h similarity index 100% rename from MdeModulePkg/Core/Dxe/DxeRing3/Ring3.h rename to MdeModulePkg/Core/Dxe/DxeUserSpace/UserSpace.h diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c b/MdeModulePkg/Core/Dxe/DxeUserSpace/UserSpaceProtocols.c similarity index 94% rename from MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c rename to MdeModulePkg/Core/Dxe/DxeUserSpace/UserSpaceProtocols.c index 6408ee1df1..2f450761ee 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3Protocols.c +++ b/MdeModulePkg/Core/Dxe/DxeUserSpace/UserSpaceProtocols.c @@ -6,7 +6,7 @@ **/ -#include "Ring3.h" +#include "UserSpace.h" EFI_STATUS EFIAPI diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c b/MdeModulePkg/Core/Dxe/DxeUserSpace/UserSpaceUefiBootServices.c similarity index 95% rename from MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c rename to MdeModulePkg/Core/Dxe/DxeUserSpace/UserSpaceUefiBootServices.c index 76d74da393..570fcc76eb 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiBootServices.c +++ b/MdeModulePkg/Core/Dxe/DxeUserSpace/UserSpaceUefiBootServices.c @@ -14,7 +14,7 @@ #include #include -#include "Ring3.h" +#include "UserSpace.h" BOOLEAN mOnGuarding = FALSE; diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c b/MdeModulePkg/Core/Dxe/DxeUserSpace/UserSpaceUefiRuntimeServices.c similarity index 94% rename from MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c rename to MdeModulePkg/Core/Dxe/DxeUserSpace/UserSpaceUefiRuntimeServices.c index 8e86c8511b..e1e5cebc04 100644 --- a/MdeModulePkg/Core/Dxe/DxeRing3/Ring3UefiRuntimeServices.c +++ b/MdeModulePkg/Core/Dxe/DxeUserSpace/UserSpaceUefiRuntimeServices.c @@ -1,17 +1,17 @@ -/** @file - This driver constructs User space wrappers for the EFI_RUNTIME_SERVICES. - - Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. - SPDX-License-Identifier: BSD-3-Clause - -**/ +/** @file + This driver constructs User space wrappers for the EFI_RUNTIME_SERVICES. + + Copyright (c) 2024 - 2025, Mikhail Krichanov. All rights reserved. + SPDX-License-Identifier: BSD-3-Clause + +**/ #include #include #include -#include "Ring3.h" +#include "UserSpace.h" EFI_STATUS EFIAPI diff --git a/MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm b/MdeModulePkg/Core/Dxe/DxeUserSpace/X64/SysCall.nasm similarity index 100% rename from MdeModulePkg/Core/Dxe/DxeRing3/X64/SysCall.nasm rename to MdeModulePkg/Core/Dxe/DxeUserSpace/X64/SysCall.nasm diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 7a303b80a2..cb53d3ab3c 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -1204,8 +1204,8 @@ # @Prompt Defines the page allocation for the MM communication buffer; default is 128 pages (512KB). gEfiMdeModulePkgTokenSpaceGuid.PcdMmCommBufferPages|128|UINT32|0x30001061 - ## Indicates whether DXE drivers marked in .fdf file as USER will be loaded in user memory. - # TRUE - USER DXE drivers will be loaded in user memory.
+ ## Indicates whether DXE drivers marked in .fdf file as USER will be loaded in separate User address spaces. + # TRUE - USER DXE drivers will be loaded in separate User address spaces.
# FALSE - All DXE drivers will be loaded in supervisor memory.
# @Prompt Enable User Space. gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|FALSE|BOOLEAN|0x30001062 diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 059658f533..b71757add6 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -305,7 +305,7 @@ MdeModulePkg/Bus/Spi/SpiHc/SpiHcDxe.inf MdeModulePkg/Bus/Spi/SpiHc/SpiHcSmm.inf - MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { + MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf { MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf } diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index 03b84584cc..8abed1e589 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -830,7 +830,7 @@ MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf FatPkg/EnhancedFatDxe/Fat.inf - MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { + MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf { MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf } diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf index f2580e130b..7d632f6010 100644 --- a/OvmfPkg/OvmfPkgIa32.fdf +++ b/OvmfPkg/OvmfPkgIa32.fdf @@ -203,9 +203,9 @@ APRIORI DXE { !if $(SMM_REQUIRE) == FALSE INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf !endif - # The driver responsible for UserSpace initialization (DxeRing3.inf) - # must be the first USER driver in APRIORI list. - INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf + # The driver responsible for UserSpace initialization (DxeUserSpace.inf) + # must be the first USER driver in APRIORI list. + INF MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf } # @@ -291,7 +291,7 @@ INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf INF USER FatPkg/EnhancedFatDxe/Fat.inf -INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +INF USER MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index d362658e92..6c50f237e6 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -842,7 +842,7 @@ MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf FatPkg/EnhancedFatDxe/Fat.inf - MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { + MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf { MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf } diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf index 97af2a906d..804092dcea 100644 --- a/OvmfPkg/OvmfPkgIa32X64.fdf +++ b/OvmfPkg/OvmfPkgIa32X64.fdf @@ -204,9 +204,9 @@ APRIORI DXE { !if $(SMM_REQUIRE) == FALSE INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf !endif - # The driver responsible for UserSpace initialization (DxeRing3.inf) - # must be the first USER driver in APRIORI list. - INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf + # The driver responsible for UserSpace initialization (DxeUserSpace.inf) + # must be the first USER driver in APRIORI list. + INF MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf } # @@ -293,7 +293,7 @@ INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf INF USER FatPkg/EnhancedFatDxe/Fat.inf -INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +INF USER MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index a20e45a908..468dbce2d3 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -894,7 +894,7 @@ MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf FatPkg/EnhancedFatDxe/Fat.inf - MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { + MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf { MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf } diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 0a95e190a3..66e5e90b95 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -235,9 +235,9 @@ APRIORI DXE { !if $(SMM_REQUIRE) == FALSE INF OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf !endif - # The driver responsible for UserSpace initialization (DxeRing3.inf) + # The driver responsible for UserSpace initialization (DxeUserSpace.inf) # must be the first USER driver in APRIORI list. - INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf + INF MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf } # @@ -325,7 +325,7 @@ INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf INF USER FatPkg/EnhancedFatDxe/Fat.inf -INF USER MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +INF USER MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf INF OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 3e40695b9a..d65e06eec7 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -846,7 +846,7 @@ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf FatPkg/EnhancedFatDxe/Fat.inf - MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf { + MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf { MemoryPoolLib|MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf } diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index af014c73c4..140ca52b45 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -143,7 +143,7 @@ APRIORI DXE { INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf INF UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf - INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf + INF MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf } # @@ -286,7 +286,7 @@ INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf INF MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf !endif INF FatPkg/EnhancedFatDxe/Fat.inf -INF MdeModulePkg/Core/Dxe/DxeRing3/DxeRing3.inf +INF MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf # # SD/eMMC Support From 448b169e582d738ead2e0785c7828c7035298ba3 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 14 Apr 2025 15:14:32 +0300 Subject: [PATCH 337/341] MdeModulePkg: Added PcdMaxMemoryType. --- .../Core/Dxe/DxeUserSpace/DxeUserSpace.inf | 3 +++ MdeModulePkg/Include/Library/MemoryPoolLib.h | 18 +----------------- .../Library/MemoryPoolLib/MemoryPoolLib.inf | 1 + MdeModulePkg/Library/MemoryPoolLib/Pool.c | 2 ++ MdeModulePkg/MdeModulePkg.dec | 6 ++++++ 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf b/MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf index f008d37436..e359cdd05e 100644 --- a/MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf +++ b/MdeModulePkg/Core/Dxe/DxeUserSpace/DxeUserSpace.inf @@ -62,5 +62,8 @@ gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMES gEfiUnicodeCollationProtocolGuid ## SOMETIMES_CONSUMES +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxMemoryType ## CONSUMES + [Depex] TRUE diff --git a/MdeModulePkg/Include/Library/MemoryPoolLib.h b/MdeModulePkg/Include/Library/MemoryPoolLib.h index bf459cdb13..3a0fb68f64 100644 --- a/MdeModulePkg/Include/Library/MemoryPoolLib.h +++ b/MdeModulePkg/Include/Library/MemoryPoolLib.h @@ -11,22 +11,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include -// -// +---------------------------------------------------+ -// | 0..(EfiMaxMemoryType - 1) - Normal memory type | -// +---------------------------------------------------+ -// | EfiMaxMemoryType..0x6FFFFFFF - Invalid | -// +---------------------------------------------------+ -// | 0x70000000..0x7FFFFFFF - OEM reserved | -// +---------------------------------------------------+ -// | 0x80000000..0xFFFFFFFF - OS reserved | -// +---------------------------------------------------+ -// -#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 -#define MEMORY_TYPE_OS_RESERVED_MAX 0xFFFFFFFF -#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 -#define MEMORY_TYPE_OEM_RESERVED_MAX 0x7FFFFFFF - // // Memory type to guard (matching the related PCD definition) // @@ -36,7 +20,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #define GUARD_HEAP_TYPE_ALL \ (GUARD_HEAP_TYPE_PAGE|GUARD_HEAP_TYPE_POOL|GUARD_HEAP_TYPE_FREED) -#define MAX_MEMORY_TYPE 100 +#define MAX_MEMORY_TYPE FixedPcdGet32 (PcdMaxMemoryType) /** Called to initialize the pool. diff --git a/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf b/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf index 4943e6242b..b082b3d0d6 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf +++ b/MdeModulePkg/Library/MemoryPoolLib/MemoryPoolLib.inf @@ -38,3 +38,4 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxMemoryType ## CONSUMES diff --git a/MdeModulePkg/Library/MemoryPoolLib/Pool.c b/MdeModulePkg/Library/MemoryPoolLib/Pool.c index 190ea17f55..45184d81b1 100644 --- a/MdeModulePkg/Library/MemoryPoolLib/Pool.c +++ b/MdeModulePkg/Library/MemoryPoolLib/Pool.c @@ -82,6 +82,8 @@ typedef struct { // POOL mPoolHead[MAX_MEMORY_TYPE]; +STATIC_ASSERT (MAX_MEMORY_TYPE > EfiMaxMemoryType, "PcdMaxMemoryType must be greater than EfiMaxMemoryType"); + STATIC BOOLEAN mIsCore; // diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index cb53d3ab3c..fcb7127cf9 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -1210,6 +1210,12 @@ # @Prompt Enable User Space. gEfiMdeModulePkgTokenSpaceGuid.PcdEnableUserSpace|FALSE|BOOLEAN|0x30001062 + ## Sets the size of mPoolHead array in MemoryPoolLib. It must be greater than EfiMaxMemoryType. + # In DxeMain this array manages Pools of different memory types. + # In DxeUserSpace this array manages Pools in different User address spaces. + # @Prompt Max number of memory types (or User address spaces). + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxMemoryType|100|UINT32|0x30001063 + [PcdsFixedAtBuild, PcdsPatchableInModule] ## Dynamic type PCD can be registered callback function for Pcd setting action. # PcdMaxPeiPcdCallBackNumberPerPcdEntry indicates the maximum number of callback function From 96c2d82b8931ec02529a09f671d7709d600310c7 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 14 Apr 2025 21:58:57 +0300 Subject: [PATCH 338/341] UserSpace: Fixed compilation after rebasing upon edk2-stable202502 tag. --- .../Library/ArmExceptionLib/Arm/ExceptionSupport.S | 2 +- ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S | 6 ++---- .../AArch64/DefaultExceptionHandler.c | 2 -- ArmVirtPkg/ArmVirt.dsc.inc | 12 ++++++++---- MdeModulePkg/Core/Dxe/DxeUserSpace/AARCH64/SysCall.S | 2 +- MdeModulePkg/Core/Dxe/DxeUserSpace/ARM/SysCall.S | 2 +- .../Core/Dxe/SysCall/AARCH64/CoreBootServices.S | 2 +- .../Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c | 1 - MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S | 2 +- OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc | 6 +++--- OvmfPkg/OvmfPkgX64.fdf | 4 ++-- 11 files changed, 20 insertions(+), 21 deletions(-) diff --git a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S index ed6895a0ff..1a674db46d 100644 --- a/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S +++ b/ArmPkg/Library/ArmExceptionLib/Arm/ExceptionSupport.S @@ -11,7 +11,7 @@ #------------------------------------------------------------------------------ #include -#include +#include /* diff --git a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S index 0a25ed5b39..ccb2fce94d 100644 --- a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S +++ b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S @@ -134,12 +134,10 @@ ASM_FUNC(ArmInvalidateTlb) ret ASM_FUNC(ArmWriteCptr) - EL1_OR_EL2_OR_EL3(x1) + EL1_OR_EL2(x1) 1:ret 2:msr cptr_el2, x0 - b 4f -3:msr cptr_el3, x0 // EL3 Coprocessor Trap Reg (CPTR) -4:isb + isb ret ASM_FUNC(ArmCallWFE) diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c index e2a32fe15f..7631c14b54 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/AArch64/DefaultExceptionHandler.c @@ -8,8 +8,6 @@ **/ -#include - #include #include #include diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 87090a5e2a..88a9ed3958 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -37,7 +37,11 @@ !if $(ARCH) == ARM DEFINE CUSTOM_STACK_CHECK_LIB = STATIC !else - DEFINE CUSTOM_STACK_CHECK_LIB = DYNAMIC + !ifdef $(USER_SPACE) + DEFINE CUSTOM_STACK_CHECK_LIB = STATIC + !else + DEFINE CUSTOM_STACK_CHECK_LIB = DYNAMIC + !endif !endif [BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] @@ -71,6 +75,8 @@ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf @@ -224,6 +230,7 @@ [LibraryClasses.common.DXE_CORE] HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf + DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf CpuArchLib|ArmPkg/Library/CpuArchLib/CpuArchLib.inf @@ -266,9 +273,6 @@ BaseCryptLib|CryptoPkg/Library/BaseCryptLibMbedTls/BaseCryptLib.inf MbedTlsLib|CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf - UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf - UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf - DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf [BuildOptions] GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG diff --git a/MdeModulePkg/Core/Dxe/DxeUserSpace/AARCH64/SysCall.S b/MdeModulePkg/Core/Dxe/DxeUserSpace/AARCH64/SysCall.S index 1940441d71..226ebb61d1 100644 --- a/MdeModulePkg/Core/Dxe/DxeUserSpace/AARCH64/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeUserSpace/AARCH64/SysCall.S @@ -3,7 +3,7 @@ // SPDX-License-Identifier: BSD-3-Clause //------------------------------------------------------------------------------ -#include +#include .extern ASM_PFX(UserSpaceCall) diff --git a/MdeModulePkg/Core/Dxe/DxeUserSpace/ARM/SysCall.S b/MdeModulePkg/Core/Dxe/DxeUserSpace/ARM/SysCall.S index e016a71b16..775b5727e1 100644 --- a/MdeModulePkg/Core/Dxe/DxeUserSpace/ARM/SysCall.S +++ b/MdeModulePkg/Core/Dxe/DxeUserSpace/ARM/SysCall.S @@ -3,7 +3,7 @@ // SPDX-License-Identifier: BSD-3-Clause //------------------------------------------------------------------------------ -#include +#include .extern ASM_PFX(UserSpaceCall) diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 65847f9014..c4b38a4bef 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -5,7 +5,7 @@ // //------------------------------------------------------------------------------ -#include +#include .cpu cortex-a76 diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c index 13a5e2a983..44291393fb 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeAARCH64.c @@ -5,7 +5,6 @@ **/ -#include #include #include #include diff --git a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S index 9191e3b0ad..54973efa44 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/ARM/CoreBootServices.S @@ -5,7 +5,7 @@ // //------------------------------------------------------------------------------ -#include +#include //------------------------------------------------------------------------------ // EFI_STATUS diff --git a/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc b/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc index 062a154cda..11a33a8c7a 100644 --- a/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc +++ b/OvmfPkg/Include/Fdf/OvmfPkgDefines.fdf.inc @@ -62,9 +62,9 @@ DEFINE FW_BLOCKS = 0x400 DEFINE CODE_BASE_ADDRESS = 0xFFC84000 DEFINE CODE_SIZE = 0x0037C000 DEFINE CODE_BLOCKS = 0x37C -DEFINE FVMAIN_SIZE = 0x00340000 -DEFINE SECFV_OFFSET = 0x003C4000 -DEFINE SECFV_SIZE = 0x3c000 +DEFINE FVMAIN_SIZE = 0x0033f000 +DEFINE SECFV_OFFSET = 0x003C3000 +DEFINE SECFV_SIZE = 0x3d000 !endif SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress = $(FW_BASE_ADDRESS) diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf index 66e5e90b95..f6095ec570 100644 --- a/OvmfPkg/OvmfPkgX64.fdf +++ b/OvmfPkg/OvmfPkgX64.fdf @@ -103,11 +103,11 @@ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecApicPageTableBase|gUefiOvmfPkgTokenSpaceGui 0x011000|0x00F000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize -0x020000|0x130000 +0x020000|0x150000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize FV = PEIFV -0x150000|0xE30000 +0x170000|0xE10000 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize FV = DXEFV From 845c8283e8005a0ca9248f7bc8d7a0e5d2a62a93 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 15 Apr 2025 11:48:47 +0300 Subject: [PATCH 339/341] BaseTools/Conf/tools_def: Refactored VS2022 DLINK_FLAGS. --- BaseTools/Conf/tools_def.template | 44 +++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/BaseTools/Conf/tools_def.template b/BaseTools/Conf/tools_def.template index d8b544c209..92f7be3a6f 100755 --- a/BaseTools/Conf/tools_def.template +++ b/BaseTools/Conf/tools_def.template @@ -807,12 +807,12 @@ NOOPT_VS2022_IA32_NASM_FLAGS = -O0 -f win32 -g # Linker warning 4210 is disabled globally, because it checks if static initializers are present and the VCRuntime is # linked. We do not link the VCRuntime (except for HOST_APPLICATIONs) so this warning can be generated erroneously # whenever there are static initializers, because we will always fail the VCRuntime linking check - DEBUG_VS2022_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /WX /IGNORE:4210 -RELEASE_VS2022_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data /WX /IGNORE:4210 -NOOPT_VS2022_IA32_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /WX /IGNORE:4210 + DEBUG_VS2022_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /DEBUG /WX /IGNORE:4210 +RELEASE_VS2022_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /WX /IGNORE:4210 +NOOPT_VS2022_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /DEBUG /WX /IGNORE:4210 # BaseTools cannot handle XIP modules with different section and file alignment -*_VS2022_IA32_DLINK_SECPEIFLAGS = /ALIGN:32 +*_VS2022_IA32_DLINK_SECPEIFLAGS = DEF(MSFT_ALIGN) ################## # X64 definitions @@ -843,12 +843,12 @@ NOOPT_VS2022_X64_NASM_FLAGS = -O0 -f win64 -g # Linker warning 4210 is disabled globally, because it checks if static initializers are present and the VCRuntime is # linked. We do not link the VCRuntime (except for HOST_APPLICATIONs) so this warning can be generated erroneously # whenever there are static initializers, because we will always fail the VCRuntime linking check - DEBUG_VS2022_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /ALIGN:4096 /DLL /WX /IGNORE:4210 -RELEASE_VS2022_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data /ALIGN:4096 /DLL /WX /IGNORE:4210 -NOOPT_VS2022_X64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4281 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /ALIGN:4096 /DLL /WX /IGNORE:4210 + DEBUG_VS2022_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4281 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /DEBUG /WX /IGNORE:4210 +RELEASE_VS2022_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4281 /IGNORE:4254 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /WX /IGNORE:4210 +NOOPT_VS2022_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4281 /SECTION:.xdata,D /SECTION:.pdata,D /Machine:X64 /DEBUG /WX /IGNORE:4210 # BaseTools cannot handle XIP modules with different section and file alignment -*_VS2022_X64_DLINK_SECPEIFLAGS = /ALIGN:32 +*_VS2022_X64_DLINK_SECPEIFLAGS = DEF(MSFT_ALIGN) ################# # ARM definitions @@ -876,12 +876,12 @@ NOOPT_VS2022_ARM_ASM_FLAGS = /nologo # Linker warning 4210 is disabled globally, because it checks if static initializers are present and the VCRuntime is # linked. We do not link the VCRuntime (except for HOST_APPLICATIONs) so this warning can be generated erroneously # whenever there are static initializers, because we will always fail the VCRuntime linking check - DEBUG_VS2022_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /WX /IGNORE:4210 -RELEASE_VS2022_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data /WX /IGNORE:4210 -NOOPT_VS2022_ARM_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /DEBUG /WX /IGNORE:4210 + DEBUG_VS2022_ARM_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /DEBUG /WX /IGNORE:4210 +RELEASE_VS2022_ARM_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /WX /IGNORE:4210 +NOOPT_VS2022_ARM_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM /DEBUG /WX /IGNORE:4210 # BaseTools cannot handle XIP modules with different section and file alignment -*_VS2022_ARM_DLINK_SECPEIFLAGS = /ALIGN:32 +*_VS2022_ARM_DLINK_SECPEIFLAGS = DEF(MSFT_ALIGN) ##################### # AARCH64 definitions @@ -909,12 +909,12 @@ NOOPT_VS2022_AARCH64_ASM_FLAGS = /nologo # Linker warning 4210 is disabled globally, because it checks if static initializers are present and the VCRuntime is # linked. We do not link the VCRuntime (except for HOST_APPLICATIONs) so this warning can be generated erroneously # whenever there are static initializers, because we will always fail the VCRuntime linking check - DEBUG_VS2022_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /DEBUG /WX /IGNORE:4210 -RELEASE_VS2022_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /MERGE:.rdata=.data /WX /IGNORE:4210 -NOOPT_VS2022_AARCH64_DLINK_FLAGS = /NOLOGO /NODEFAULTLIB /IGNORE:4001 /OPT:REF /OPT:ICF=10 /MAP /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /LTCG /DLL /ENTRY:$(IMAGE_ENTRY_POINT) /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /DRIVER /DEBUG /WX /IGNORE:4210 + DEBUG_VS2022_AARCH64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /DEBUG /WX /IGNORE:4210 +RELEASE_VS2022_AARCH64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /WX /IGNORE:4210 +NOOPT_VS2022_AARCH64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:ARM64 /DEBUG /WX /IGNORE:4210 # BaseTools cannot handle XIP modules with different section and file alignment -*_VS2022_AARCH64_DLINK_SECPEIFLAGS = /ALIGN:32 +*_VS2022_AARCH64_DLINK_SECPEIFLAGS = DEF(MSFT_ALIGN) #################################################################################### # GCC Common @@ -1252,15 +1252,15 @@ DEFINE CLANGPDB_ALL_CC_FLAGS = DEF(GCC5_ALL_CC_FLAGS) DEF(CLANGPDB_WARNI *_CLANGPDB_IA32_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGPDB_IA32_TARGET) DEBUG_CLANGPDB_IA32_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m32 -Oz -flto -march=i586 DEF(CLANGPDB_IA32_TARGET) -gcodeview -malign-double -DEBUG_CLANGPDB_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /DRIVER /MACHINE:X86 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap +DEBUG_CLANGPDB_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X86 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap DEBUG_CLANGPDB_IA32_DLINK2_FLAGS = RELEASE_CLANGPDB_IA32_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m32 -Oz -flto -march=i586 DEF(CLANGPDB_IA32_TARGET) -malign-double -RELEASE_CLANGPDB_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /DRIVER /IGNORE:4254 /MACHINE:X86 /MLLVM:-exception-model=wineh /lldmap +RELEASE_CLANGPDB_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /MACHINE:X86 /MLLVM:-exception-model=wineh /lldmap RELEASE_CLANGPDB_IA32_DLINK2_FLAGS = NOOPT_CLANGPDB_IA32_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m32 -O0 -march=i586 DEF(CLANGPDB_IA32_TARGET) -gcodeview -malign-double -NOOPT_CLANGPDB_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /DRIVER /MACHINE:X86 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap +NOOPT_CLANGPDB_IA32_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X86 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap NOOPT_CLANGPDB_IA32_DLINK2_FLAGS = ########################## @@ -1285,15 +1285,15 @@ NOOPT_CLANGPDB_IA32_DLINK2_FLAGS = *_CLANGPDB_X64_VFRPP_FLAGS = DEF(GCC_VFRPP_FLAGS) DEF(CLANGPDB_X64_TARGET) DEBUG_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -Oz -flto DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables -DEBUG_CLANGPDB_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /DRIVER /MACHINE:X64 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap +DEBUG_CLANGPDB_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X64 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap DEBUG_CLANGPDB_X64_DLINK2_FLAGS = RELEASE_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -Oz -flto DEF(CLANGPDB_X64_TARGET) -fno-unwind-tables -RELEASE_CLANGPDB_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /DRIVER /IGNORE:4254 /MACHINE:X64 /MLLVM:-exception-model=wineh /lldmap +RELEASE_CLANGPDB_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /IGNORE:4254 /MACHINE:X64 /MLLVM:-exception-model=wineh /lldmap RELEASE_CLANGPDB_X64_DLINK2_FLAGS = NOOPT_CLANGPDB_X64_CC_FLAGS = DEF(CLANGPDB_ALL_CC_FLAGS) -m64 "-DEFIAPI=__attribute__((ms_abi))" -mno-red-zone -mcmodel=small -O0 DEF(CLANGPDB_X64_TARGET) -gcodeview -funwind-tables -NOOPT_CLANGPDB_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /DRIVER /MACHINE:X64 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap +NOOPT_CLANGPDB_X64_DLINK_FLAGS = DEF(MSFT_DLINK_COMMON) /MACHINE:X64 /DEBUG:GHASH /MLLVM:-exception-model=wineh /lldmap NOOPT_CLANGPDB_X64_DLINK2_FLAGS = #################################################################################### From bb8a9861caf2224ef46aeac616d5fb690b268de9 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 6 Oct 2025 18:43:20 +0300 Subject: [PATCH 340/341] UserSpace: Fixed bug so as not to call new CPU_ARCH_PROTOCOL functions, when UserSpace feature is disabled. --- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 9a02cc7548..bb2d5f2dc3 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -981,10 +981,12 @@ ApplyMemoryProtectionPolicy ( // // FreePages // - gCpu->GetMemoryAttributes (gCpu, Memory, &CurrentAttributes); + if (gUserPageTable != 0) { + gCpu->GetMemoryAttributes (gCpu, Memory, &CurrentAttributes); - if ((gUserPageTable != 0) && ((CurrentAttributes & EFI_MEMORY_USER) != 0)) { - gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, Memory, Length, EFI_MEMORY_RP); + if ((CurrentAttributes & EFI_MEMORY_USER) != 0) { + gCpu->SetUserMemoryAttributes (gCpu, gUserPageTable, Memory, Length, EFI_MEMORY_RP); + } } } From d38723a83f694e2cccd0f9875d9164804059f62d Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Tue, 7 Oct 2025 18:55:36 +0300 Subject: [PATCH 341/341] UserSpace: Fixed 2 bugs. --- MdeModulePkg/Core/Dxe/SysCall/BootServices.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c index 6865771d5d..85069d42f3 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/BootServices.c +++ b/MdeModulePkg/Core/Dxe/SysCall/BootServices.c @@ -53,6 +53,10 @@ CHAR8 *SysCallNames[] = { "SysCallUnicodeStrUpr", "SysCallUnicodeFatToStr", "SysCallUnicodeStrToFat", + // + // Helper functions + // + "SysCallGetUserPageTable", "SysCallMax" }; @@ -1358,7 +1362,7 @@ CallBootService ( gCpu->GetMemoryAttributes (gCpu, (EFI_PHYSICAL_ADDRESS)(Arguments[4] + 2 * (Arguments[2] + 1) - 1), &Attributes); ASSERT ((Attributes & EFI_MEMORY_USER) != 0); - Argument5 = (UINTN)AllocatePool (2 * (Arguments[2] + 1)); + Argument5 = (UINTN)AllocateZeroPool (2 * (Arguments[2] + 1)); if ((VOID *)Argument5 == NULL) { if ((VOID *)Argument4 != NULL) { FreePool ((VOID *)Argument4);