| /** @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 |