diff --git a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c index 08a0add340..fa81cc9d59 100644 --- a/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c +++ b/EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c @@ -269,3 +269,60 @@ FreePool ( { // 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; +}