mirror of https://github.com/acidanthera/audk.git
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
|