MdeModulePkg: Add NULL checks and Return Status to ImagePropertiesRecordLib

Update function headers to clarify the contract of each function and
improve readability. Add NULL checks to all functions that take a
pointer as an argument. Add return status to functions that
may need to return early due to invalid input.

Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
Signed-off-by: Taylor Beebe <taylor.d.beebe@gmail.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
This commit is contained in:
Taylor Beebe 2023-11-03 08:29:43 -07:00 committed by mergify[bot]
parent 7ae0516dd9
commit cf78580a34
2 changed files with 246 additions and 181 deletions

View File

@ -32,56 +32,47 @@ typedef struct {
} IMAGE_PROPERTIES_RECORD; } IMAGE_PROPERTIES_RECORD;
/** /**
Split the original memory map, and add more entries to describe PE code section and data section. Split the original memory map and add more entries to describe PE code
This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP. and data sections for each image in the input ImageRecordList.
This function will merge entries with same attributes finally.
NOTE: It assumes PE code/data section are page aligned. NOTE: This function assumes PE code/data section are page aligned.
NOTE: It assumes enough entry is prepared for new memory map. NOTE: This function assumes there are enough entries for the new memory map.
Split table: | | | | | | | |
+---------------+ | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE |
| Record X | | | | | | | | |
+---------------+ Assume the above memory region is the result of one split memory map descriptor. It's unlikely
| Record RtCode | 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
| Record Y | 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.
| Record X |
+---------------+ ----
| Record RtData | |
+---------------+ |
| Record RtCode | |-> PE/COFF1
+---------------+ |
| Record RtData | |
+---------------+ ----
| Record RtData | |
+---------------+ |
| Record RtCode | |-> PE/COFF2
+---------------+ |
| Record RtData | |
+---------------+ ----
| Record Y |
+---------------+
@param MemoryMapSize A pointer to the size, in bytes, of the Given an image record list, the caller should use the following formula when allocating extra descriptors:
MemoryMap buffer. On input, this is the size of NumberOfAdditionalDescriptors = (MemoryMapSize / DescriptorSize) +
old MemoryMap before split. The actual buffer ((2 * <Most Code Segments in a Single Image> + 3) * <Number of Images>)
size of MemoryMap is MemoryMapSize +
(AdditionalRecordCount * DescriptorSize) calculated @param[in, out] MemoryMapSize IN: The size, in bytes, of the old memory map before the split.
below. On output, it is the size of new MemoryMap OUT: The size, in bytes, of the used descriptors of the split
after split. memory map
@param MemoryMap A pointer to the buffer in which firmware places @param[in, out] MemoryMap IN: A pointer to the buffer containing the current memory map.
the current memory map. This buffer must have enough space to accomodate the "worst case"
@param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. scenario where every image in ImageRecordList needs a new descriptor
@param ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries used when searching to describe its code and data sections.
for an image record contained by the memory range described in OUT: A pointer to the updated memory map with separated image section
EFI memory map descriptors. descriptors.
@param NumberOfAdditionalDescriptors The number of unused descriptors at the end of the input MemoryMap. @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.
**/ **/
VOID EFI_STATUS
EFIAPI EFIAPI
SplitTable ( SplitTable (
IN OUT UINTN *MemoryMapSize, IN OUT UINTN *MemoryMapSize,
@ -92,23 +83,30 @@ SplitTable (
); );
/** /**
Sort code section in image record, based upon CodeSegmentBase from low to high. Sort the code sections in the input ImageRecord based upon CodeSegmentBase from low to high.
@param ImageRecord image record to be sorted @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
**/ **/
VOID EFI_STATUS
EFIAPI EFIAPI
SortImageRecordCodeSection ( SortImageRecordCodeSection (
IN IMAGE_PROPERTIES_RECORD *ImageRecord IN IMAGE_PROPERTIES_RECORD *ImageRecord
); );
/** /**
Check if code section in image record is valid. 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 ImageRecord image record to be checked @param[in] ImageRecord IMAGE_PROPERTIES_RECORD to be checked
@retval TRUE image record is valid @retval TRUE The code sections in the input ImageRecord are valid
@retval FALSE image record is invalid @retval FALSE The code sections in the input ImageRecord are invalid
**/ **/
BOOLEAN BOOLEAN
EFIAPI EFIAPI
@ -117,11 +115,15 @@ IsImageRecordCodeSectionValid (
); );
/** /**
Sort image record based upon the ImageBase from low to high. Sort the input ImageRecordList based upon the ImageBase from low to high.
@param ImageRecordList Image record list to be sorted @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
**/ **/
VOID EFI_STATUS
EFIAPI EFIAPI
SortImageRecord ( SortImageRecord (
IN LIST_ENTRY *ImageRecordList IN LIST_ENTRY *ImageRecordList
@ -132,8 +134,11 @@ SortImageRecord (
@param[in] FirstImageRecord The first image record. @param[in] FirstImageRecord The first image record.
@param[in] SecondImageRecord The second 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
**/ **/
VOID EFI_STATUS
EFIAPI EFIAPI
SwapImageRecord ( SwapImageRecord (
IN IMAGE_PROPERTIES_RECORD *FirstImageRecord, IN IMAGE_PROPERTIES_RECORD *FirstImageRecord,
@ -145,8 +150,11 @@ SwapImageRecord (
@param[in] FirstImageRecordCodeSection The first code section @param[in] FirstImageRecordCodeSection The first code section
@param[in] SecondImageRecordCodeSection The second 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
**/ **/
VOID EFI_STATUS
EFIAPI EFIAPI
SwapImageRecordCodeSection ( SwapImageRecordCodeSection (
IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *FirstImageRecordCodeSection, IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *FirstImageRecordCodeSection,
@ -154,13 +162,16 @@ SwapImageRecordCodeSection (
); );
/** /**
Find image record according to image base and size. Find image properties record according to image base and size in the
input ImageRecordList.
@param ImageBase Base of PE image @param[in] ImageBase Base of PE image
@param ImageSize Size of PE image @param[in] ImageSize Size of PE image
@param ImageRecordList Image record list to be searched @param[in] ImageRecordList Image record list to be searched
@return image record @retval NULL No IMAGE_PROPERTIES_RECORD matches ImageBase
and ImageSize in the input ImageRecordList
@retval Other The found IMAGE_PROPERTIES_RECORD
**/ **/
IMAGE_PROPERTIES_RECORD * IMAGE_PROPERTIES_RECORD *
EFIAPI EFIAPI

View File

@ -22,14 +22,13 @@
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size))) ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size)))
/** /**
Converts a number of EFI_PAGEs to a size in bytes. Converts a number of pages to a size in bytes.
NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only. NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only.
@param Pages The number of EFI_PAGES. @param[in] Pages The number of EFI_PAGES.
@return The number of bytes associated with the number of EFI_PAGEs specified @retval The number of bytes associated with the input number of pages.
by Pages.
**/ **/
STATIC STATIC
UINT64 UINT64
@ -45,10 +44,9 @@ EfiPagesToSize (
NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only. NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only.
@param Size A size in bytes. @param[in] Size A size in bytes.
@return The number of EFI_PAGESs associated with the number of bytes specified @retval The number of pages associated with the input number of bytes.
by Size.
**/ **/
STATIC STATIC
@ -61,12 +59,12 @@ EfiSizeToPages (
} }
/** /**
Sort memory map entries based upon PhysicalStart, from low to high. Sort memory map entries based upon PhysicalStart from low to high.
@param MemoryMap A pointer to the buffer in which firmware places @param[in, out] MemoryMap A pointer to the buffer in which firmware places
the current memory map. the current memory map.
@param MemoryMapSize Size, in bytes, of the MemoryMap buffer. @param[in] MemoryMapSize Size, in bytes, of the MemoryMap buffer.
@param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
**/ **/
STATIC STATIC
VOID VOID
@ -105,11 +103,12 @@ SortMemoryMap (
/** /**
Return the first image record, whose [ImageBase, ImageSize] covered by [Buffer, Length]. Return the first image record, whose [ImageBase, ImageSize] covered by [Buffer, Length].
@param Buffer Start Address @param[in] Buffer Starting Address
@param Length Address length @param[in] Length Length to check
@param ImageRecordList Image record list @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries to check against
the memory range Buffer -> Buffer + Length
@return first image record covered by [buffer, length] @retval The first image record covered by [Buffer, Length]
**/ **/
STATIC STATIC
IMAGE_PROPERTIES_RECORD * IMAGE_PROPERTIES_RECORD *
@ -144,17 +143,19 @@ GetImageRecordByAddress (
} }
/** /**
Set the memory map to new entries, according to one old entry, Break up the input OldRecord into multiple new records based on the code
based upon PE code section and data section in image record and data sections in the input ImageRecord.
@param ImageRecord An image record whose [ImageBase, ImageSize] covered @param[in] ImageRecord An IMAGE_PROPERTIES_RECORD whose ImageBase and
by old memory map entry. ImageSize is covered by by OldRecord.
@param NewRecord A pointer to several new memory map entries. @param[in, out] NewRecord A pointer to several new memory map entries.
The caller gurantee the buffer size be 1 + The caller gurantee the buffer size be 1 +
(SplitRecordCount * DescriptorSize) calculated (SplitRecordCount * DescriptorSize) calculated
below. below.
@param OldRecord A pointer to one old memory map entry. @param[in] OldRecord A pointer to one old memory map entry.
@param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. @param[in] DescriptorSize The size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
@retval The number of new descriptors created.
**/ **/
STATIC STATIC
UINTN UINTN
@ -244,16 +245,16 @@ SetNewRecord (
} }
/** /**
Return the max number of new splitted entries, according to one old entry, Return the maximum number of new entries required to describe the code and data sections
based upon PE code section and data section. of all images covered by the input OldRecord.
@param OldRecord A pointer to one old memory map entry. @param[in] OldRecord A pointer to one old memory map entry.
@param ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries used when searching @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries used when searching
for an image record contained by the memory range described in for an image record contained by the memory range described by
the existing EFI memory map descriptor OldRecord OldRecord
@retval 0 no entry need to be splitted. @retval The maximum number of new descriptors required to describe the code and data sections
@return the max number of new splitted entries of all images covered by OldRecord.
**/ **/
STATIC STATIC
UINTN UINTN
@ -289,22 +290,20 @@ GetMaxSplitRecordCount (
} }
/** /**
Split the memory map to new entries, according to one old entry, Split the memory map into new entries based upon the PE code and data sections
based upon PE code section and data section. in ImageRecordList covered by the input OldRecord.
@param OldRecord A pointer to one old memory map entry. @param[in] OldRecord A pointer to one old memory map entry.
@param NewRecord A pointer to several new memory map entries. @param[in, out] NewRecord A pointer to several new memory map entries.
The caller gurantee the buffer size be 1 + The caller gurantee the buffer size be
(SplitRecordCount * DescriptorSize) calculated (SplitRecordCount * DescriptorSize).
below. @param[in] MaxSplitRecordCount The maximum number of entries post-split.
@param MaxSplitRecordCount The max number of splitted entries @param[in] DescriptorSize The size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
@param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. @param[in] ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries used when searching
@param ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries used when searching for an image record contained by the memory range described in
for an image record contained by the memory range described in the existing EFI memory map descriptor OldRecord
the existing EFI memory map descriptor OldRecord
@retval 0 no entry is splitted. @retval The number of split entries.
@return the real number of splitted record.
**/ **/
STATIC STATIC
UINTN UINTN
@ -402,56 +401,47 @@ SplitRecord (
} }
/** /**
Split the original memory map, and add more entries to describe PE code section and data section. Split the original memory map and add more entries to describe PE code
This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP. and data sections for each image in the input ImageRecordList.
This function will merge entries with same attributes finally.
NOTE: It assumes PE code/data section are page aligned. NOTE: This function assumes PE code/data section are page aligned.
NOTE: It assumes enough entry is prepared for new memory map. NOTE: This function assumes there are enough entries for the new memory map.
Split table: | | | | | | | |
+---------------+ | 4K PAGE | DATA | CODE | DATA | CODE | DATA | 4K PAGE |
| Record X | | | | | | | | |
+---------------+ Assume the above memory region is the result of one split memory map descriptor. It's unlikely
| Record RtCode | 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
| Record Y | 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.
| Record X |
+---------------+ ----
| Record RtData | |
+---------------+ |
| Record RtCode | |-> PE/COFF1
+---------------+ |
| Record RtData | |
+---------------+ ----
| Record RtData | |
+---------------+ |
| Record RtCode | |-> PE/COFF2
+---------------+ |
| Record RtData | |
+---------------+ ----
| Record Y |
+---------------+
@param MemoryMapSize A pointer to the size, in bytes, of the Given an image record list, the caller should use the following formula when allocating extra descriptors:
MemoryMap buffer. On input, this is the size of NumberOfAdditionalDescriptors = (MemoryMapSize / DescriptorSize) +
old MemoryMap before split. The actual buffer ((2 * <Most Code Segments in a Single Image> + 3) * <Number of Images>)
size of MemoryMap is MemoryMapSize +
(AdditionalRecordCount * DescriptorSize) calculated @param[in, out] MemoryMapSize IN: The size, in bytes, of the old memory map before the split.
below. On output, it is the size of new MemoryMap OUT: The size, in bytes, of the used descriptors of the split
after split. memory map
@param MemoryMap A pointer to the buffer in which firmware places @param[in, out] MemoryMap IN: A pointer to the buffer containing the current memory map.
the current memory map. This buffer must have enough space to accomodate the "worst case"
@param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. scenario where every image in ImageRecordList needs a new descriptor
@param ImageRecordList A list of IMAGE_PROPERTIES_RECORD entries used when searching to describe its code and data sections.
for an image record contained by the memory range described in OUT: A pointer to the updated memory map with separated image section
EFI memory map descriptors. descriptors.
@param NumberOfAdditionalDescriptors The number of unused descriptors at the end of the input MemoryMap. @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.
**/ **/
VOID EFI_STATUS
EFIAPI EFIAPI
SplitTable ( SplitTable (
IN OUT UINTN *MemoryMapSize, IN OUT UINTN *MemoryMapSize,
@ -468,6 +458,10 @@ SplitTable (
UINTN RealSplitRecordCount; UINTN RealSplitRecordCount;
UINTN TotalSkippedRecords; UINTN TotalSkippedRecords;
if ((MemoryMapSize == NULL) || (MemoryMap == NULL) || (ImageRecordList == NULL)) {
return EFI_INVALID_PARAMETER;
}
TotalSkippedRecords = 0; TotalSkippedRecords = 0;
// //
// Let old record point to end of valid MemoryMap buffer. // Let old record point to end of valid MemoryMap buffer.
@ -518,16 +512,19 @@ SplitTable (
*MemoryMapSize = (IndexNewStarting - IndexNew - TotalSkippedRecords) * DescriptorSize; *MemoryMapSize = (IndexNewStarting - IndexNew - TotalSkippedRecords) * DescriptorSize;
return; return EFI_SUCCESS;
} }
/** /**
Swap two code sections in image record. Swap two code sections in a single IMAGE_PROPERTIES_RECORD.
@param FirstImageRecordCodeSection first code section in image record @param[in] FirstImageRecordCodeSection The first code section
@param SecondImageRecordCodeSection second code section in image record @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
**/ **/
VOID EFI_STATUS
EFIAPI EFIAPI
SwapImageRecordCodeSection ( SwapImageRecordCodeSection (
IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *FirstImageRecordCodeSection, IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *FirstImageRecordCodeSection,
@ -536,6 +533,10 @@ SwapImageRecordCodeSection (
{ {
IMAGE_PROPERTIES_RECORD_CODE_SECTION TempImageRecordCodeSection; IMAGE_PROPERTIES_RECORD_CODE_SECTION TempImageRecordCodeSection;
if ((FirstImageRecordCodeSection == NULL) || (SecondImageRecordCodeSection == NULL)) {
return EFI_INVALID_PARAMETER;
}
TempImageRecordCodeSection.CodeSegmentBase = FirstImageRecordCodeSection->CodeSegmentBase; TempImageRecordCodeSection.CodeSegmentBase = FirstImageRecordCodeSection->CodeSegmentBase;
TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize; TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize;
@ -544,19 +545,26 @@ SwapImageRecordCodeSection (
SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase; SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase;
SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize; SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize;
return EFI_SUCCESS;
} }
/** /**
Sort code section in image record, based upon CodeSegmentBase from low to high. Sort the code sections in the input ImageRecord based upon CodeSegmentBase from low to high.
@param ImageRecord image record to be sorted @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
**/ **/
VOID EFI_STATUS
EFIAPI EFIAPI
SortImageRecordCodeSection ( SortImageRecordCodeSection (
IN IMAGE_PROPERTIES_RECORD *ImageRecord IN IMAGE_PROPERTIES_RECORD *ImageRecord
) )
{ {
EFI_STATUS Status;
IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;
IMAGE_PROPERTIES_RECORD_CODE_SECTION *NextImageRecordCodeSection; IMAGE_PROPERTIES_RECORD_CODE_SECTION *NextImageRecordCodeSection;
LIST_ENTRY *ImageRecordCodeSectionLink; LIST_ENTRY *ImageRecordCodeSectionLink;
@ -564,6 +572,10 @@ SortImageRecordCodeSection (
LIST_ENTRY *ImageRecordCodeSectionEndLink; LIST_ENTRY *ImageRecordCodeSectionEndLink;
LIST_ENTRY *ImageRecordCodeSectionList; LIST_ENTRY *ImageRecordCodeSectionList;
if (ImageRecord == NULL) {
return EFI_INVALID_PARAMETER;
}
ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink; ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;
@ -584,7 +596,11 @@ SortImageRecordCodeSection (
IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
); );
if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) { if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) {
SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection); Status = SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return EFI_ABORTED;
}
} }
NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink; NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink;
@ -593,15 +609,20 @@ SortImageRecordCodeSection (
ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;
} }
return EFI_SUCCESS;
} }
/** /**
Check if code section in image record is valid. 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 ImageRecord image record to be checked @param[in] ImageRecord IMAGE_PROPERTIES_RECORD to be checked
@retval TRUE image record is valid @retval TRUE The code sections in the input ImageRecord are valid
@retval FALSE image record is invalid @retval FALSE The code sections in the input ImageRecord are invalid
**/ **/
BOOLEAN BOOLEAN
EFIAPI EFIAPI
@ -615,6 +636,10 @@ IsImageRecordCodeSectionValid (
LIST_ENTRY *ImageRecordCodeSectionEndLink; LIST_ENTRY *ImageRecordCodeSectionEndLink;
LIST_ENTRY *ImageRecordCodeSectionList; LIST_ENTRY *ImageRecordCodeSectionList;
if (ImageRecord == NULL) {
return FALSE;
}
DEBUG ((DEBUG_VERBOSE, "ImageCode SegmentCount - 0x%x\n", ImageRecord->CodeSegmentCount)); DEBUG ((DEBUG_VERBOSE, "ImageCode SegmentCount - 0x%x\n", ImageRecord->CodeSegmentCount));
ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;
@ -661,10 +686,13 @@ IsImageRecordCodeSectionValid (
/** /**
Swap two image records. Swap two image records.
@param FirstImageRecord first image record. @param[in] FirstImageRecord The first image record.
@param SecondImageRecord second 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
**/ **/
VOID EFI_STATUS
EFIAPI EFIAPI
SwapImageRecord ( SwapImageRecord (
IN IMAGE_PROPERTIES_RECORD *FirstImageRecord, IN IMAGE_PROPERTIES_RECORD *FirstImageRecord,
@ -673,6 +701,10 @@ SwapImageRecord (
{ {
IMAGE_PROPERTIES_RECORD TempImageRecord; IMAGE_PROPERTIES_RECORD TempImageRecord;
if ((FirstImageRecord == NULL) || (SecondImageRecord == NULL)) {
return EFI_INVALID_PARAMETER;
}
TempImageRecord.ImageBase = FirstImageRecord->ImageBase; TempImageRecord.ImageBase = FirstImageRecord->ImageBase;
TempImageRecord.ImageSize = FirstImageRecord->ImageSize; TempImageRecord.ImageSize = FirstImageRecord->ImageSize;
TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount; TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount;
@ -686,14 +718,19 @@ SwapImageRecord (
SecondImageRecord->CodeSegmentCount = TempImageRecord.CodeSegmentCount; SecondImageRecord->CodeSegmentCount = TempImageRecord.CodeSegmentCount;
SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord->CodeSegmentList); SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord->CodeSegmentList);
return EFI_SUCCESS;
} }
/** /**
Sort image record based upon the ImageBase from low to high. Sort the input ImageRecordList based upon the ImageBase from low to high.
@param ImageRecordList Image record list to be sorted @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
**/ **/
VOID EFI_STATUS
EFIAPI EFIAPI
SortImageRecord ( SortImageRecord (
IN LIST_ENTRY *ImageRecordList IN LIST_ENTRY *ImageRecordList
@ -704,6 +741,11 @@ SortImageRecord (
LIST_ENTRY *ImageRecordLink; LIST_ENTRY *ImageRecordLink;
LIST_ENTRY *NextImageRecordLink; LIST_ENTRY *NextImageRecordLink;
LIST_ENTRY *ImageRecordEndLink; LIST_ENTRY *ImageRecordEndLink;
EFI_STATUS Status;
if (ImageRecordList == NULL) {
return EFI_INVALID_PARAMETER;
}
ImageRecordLink = ImageRecordList->ForwardLink; ImageRecordLink = ImageRecordList->ForwardLink;
NextImageRecordLink = ImageRecordLink->ForwardLink; NextImageRecordLink = ImageRecordLink->ForwardLink;
@ -724,7 +766,11 @@ SortImageRecord (
); );
if (ImageRecord->ImageBase > NextImageRecord->ImageBase) { if (ImageRecord->ImageBase > NextImageRecord->ImageBase) {
SwapImageRecord (ImageRecord, NextImageRecord); Status = SwapImageRecord (ImageRecord, NextImageRecord);
if (EFI_ERROR (Status)) {
ASSERT_EFI_ERROR (Status);
return EFI_ABORTED;
}
} }
NextImageRecordLink = NextImageRecordLink->ForwardLink; NextImageRecordLink = NextImageRecordLink->ForwardLink;
@ -733,16 +779,20 @@ SortImageRecord (
ImageRecordLink = ImageRecordLink->ForwardLink; ImageRecordLink = ImageRecordLink->ForwardLink;
NextImageRecordLink = ImageRecordLink->ForwardLink; NextImageRecordLink = ImageRecordLink->ForwardLink;
} }
return EFI_SUCCESS;
} }
/** /**
Find image record according to image base and size. Find image record according to image base and size.
@param ImageBase Base of PE image @param[in] ImageBase Base of PE image
@param ImageSize Size of PE image @param[in] ImageSize Size of PE image
@param ImageRecordList Image record list to be searched @param[in] ImageRecordList Image record list to be searched
@return image record @retval NULL No IMAGE_PROPERTIES_RECORD matches ImageBase
and ImageSize in the input ImageRecordList
@retval Other The found IMAGE_PROPERTIES_RECORD
**/ **/
IMAGE_PROPERTIES_RECORD * IMAGE_PROPERTIES_RECORD *
EFIAPI EFIAPI
@ -755,6 +805,10 @@ FindImageRecord (
IMAGE_PROPERTIES_RECORD *ImageRecord; IMAGE_PROPERTIES_RECORD *ImageRecord;
LIST_ENTRY *ImageRecordLink; LIST_ENTRY *ImageRecordLink;
if (ImageRecordList == NULL) {
return NULL;
}
for (ImageRecordLink = ImageRecordList->ForwardLink; for (ImageRecordLink = ImageRecordList->ForwardLink;
ImageRecordLink != ImageRecordList; ImageRecordLink != ImageRecordList;
ImageRecordLink = ImageRecordLink->ForwardLink) ImageRecordLink = ImageRecordLink->ForwardLink)