Update DumpImageRecord() to be DumpImageRecords(), and improve the debug output. The function will output at DEBUG_INFO instead, and the function will be run in DXE and SMM MAT logic when the MAT is installed at EndOfDxe on DEBUG builds. Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Dandan Bi <dandan.bi@intel.com> Cc: Jiaxin Wu <jiaxin.wu@intel.com> Cc: Ray Ni <ray.ni@intel.com> Signed-off-by: Taylor Beebe <taylor.d.beebe@gmail.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			235 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			235 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| 
 | |
|   Provides definitions and functionality for manipulating IMAGE_PROPERTIES_RECORD.
 | |
| 
 | |
|   Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
 | |
|   Copyright (c) Microsoft Corporation.
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #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;
 | |
| 
 | |
| /**
 | |
|   Split the original memory map and add more entries to describe PE code
 | |
|   and data sections for each image in the input ImageRecordList.
 | |
| 
 | |
|   NOTE: This function assumes PE code/data section are page aligned.
 | |
|   NOTE: This function assumes there are enough entries for the new memory map.
 | |
| 
 | |
|   |         |      |      |      |      |      |         |
 | |
|   | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE |
 | |
|   |         |      |      |      |      |      |         |
 | |
|   Assume the above memory region is the result of one split memory map descriptor. It's unlikely
 | |
|   that a linker will orient an image this way, but the caller must assume the worst case scenario.
 | |
|   This image layout example contains code sections oriented in a way that maximizes the number of
 | |
|   descriptors which would be required to describe each section. To ensure we have enough space
 | |
|   for every descriptor of the broken up memory map, the caller must assume that every image will
 | |
|   have the maximum number of code sections oriented in a way which maximizes the number of data
 | |
|   sections with unrelated memory regions flanking each image within a single descriptor.
 | |
| 
 | |
|   Given an image record list, the caller should use the following formula when allocating extra descriptors:
 | |
|   NumberOfAdditionalDescriptors = (MemoryMapSize / DescriptorSize) +
 | |
|                                     ((2 * <Most Code Segments in a Single Image> + 3) * <Number of Images>)
 | |
| 
 | |
|   @param[in, out] MemoryMapSize                   IN:   The size, in bytes, of the old memory map before the split.
 | |
|                                                   OUT:  The size, in bytes, of the used descriptors of the split
 | |
|                                                         memory map
 | |
|   @param[in, out] MemoryMap                       IN:   A pointer to the buffer containing the current memory map.
 | |
|                                                         This buffer must have enough space to accomodate the "worst case"
 | |
|                                                         scenario where every image in ImageRecordList needs a new descriptor
 | |
|                                                         to describe its code and data sections.
 | |
|                                                   OUT:  A pointer to the updated memory map with separated image section
 | |
|                                                         descriptors.
 | |
|   @param[in]      DescriptorSize                  The size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
 | |
|   @param[in]      ImageRecordList                 A list of IMAGE_PROPERTIES_RECORD entries used when searching
 | |
|                                                   for an image record contained by the memory range described in
 | |
|                                                   EFI memory map descriptors.
 | |
|   @param[in]      NumberOfAdditionalDescriptors   The number of unused descriptors at the end of the input MemoryMap.
 | |
|                                                   The formula in the description should be used to calculate this value.
 | |
| 
 | |
|   @retval EFI_SUCCESS                             The memory map was successfully split.
 | |
|   @retval EFI_INVALID_PARAMETER                   MemoryMapSize, MemoryMap, or ImageRecordList was NULL.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| SplitTable (
 | |
|   IN OUT UINTN                  *MemoryMapSize,
 | |
|   IN OUT EFI_MEMORY_DESCRIPTOR  *MemoryMap,
 | |
|   IN     UINTN                  DescriptorSize,
 | |
|   IN     LIST_ENTRY             *ImageRecordList,
 | |
|   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
 | |
|   freeing each pool.
 | |
| 
 | |
|   @param[in]      ImageRecord             The IMAGE_PROPERTIES_RECORD to delete
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| DeleteImagePropertiesRecord (
 | |
|   IN  IMAGE_PROPERTIES_RECORD  *ImageRecord
 | |
|   );
 | |
| 
 | |
| #endif
 |