mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-08 22:34:24 +02:00
Add HostMemoryAllocationBelowAddressLib class and implementation that uses OS specific services to perform pool and page allocations below a specified address in a host based unit test application execution environment. This library class is only required for mocking buffers that are assumed to be below a specific address by code under test. Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
655 lines
17 KiB
C++
655 lines
17 KiB
C++
/** @file
|
|
This is a sample to demonstrates the use of GoogleTest that supports host
|
|
execution environments.
|
|
|
|
Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include <Library/GoogleTestLib.h>
|
|
extern "C" {
|
|
#include <Uefi.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/HostMemoryAllocationBelowAddressLib.h>
|
|
}
|
|
|
|
/**
|
|
Sample unit test that verifies the expected result of an unsigned integer
|
|
addition operation.
|
|
**/
|
|
TEST (SimpleMathTests, OnePlusOneShouldEqualTwo) {
|
|
UINTN A;
|
|
UINTN B;
|
|
UINTN C;
|
|
|
|
A = 1;
|
|
B = 1;
|
|
C = A + B;
|
|
|
|
ASSERT_EQ (C, (UINTN)2);
|
|
}
|
|
|
|
/**
|
|
Sample unit test that verifies that a global BOOLEAN is updatable.
|
|
**/
|
|
class GlobalBooleanVarTests : public ::testing::Test {
|
|
public:
|
|
BOOLEAN SampleGlobalTestBoolean = FALSE;
|
|
};
|
|
|
|
TEST_F (GlobalBooleanVarTests, GlobalBooleanShouldBeChangeable) {
|
|
SampleGlobalTestBoolean = TRUE;
|
|
ASSERT_TRUE (SampleGlobalTestBoolean);
|
|
|
|
SampleGlobalTestBoolean = FALSE;
|
|
ASSERT_FALSE (SampleGlobalTestBoolean);
|
|
}
|
|
|
|
/**
|
|
Sample unit test that logs a warning message and verifies that a global
|
|
pointer is updatable.
|
|
**/
|
|
class GlobalVarTests : public ::testing::Test {
|
|
public:
|
|
VOID *SampleGlobalTestPointer = NULL;
|
|
|
|
protected:
|
|
void
|
|
SetUp (
|
|
) override
|
|
{
|
|
ASSERT_EQ ((UINTN)SampleGlobalTestPointer, (UINTN)NULL);
|
|
}
|
|
|
|
void
|
|
TearDown (
|
|
)
|
|
{
|
|
SampleGlobalTestPointer = NULL;
|
|
}
|
|
};
|
|
|
|
TEST_F (GlobalVarTests, GlobalPointerShouldBeChangeable) {
|
|
SampleGlobalTestPointer = (VOID *)-1;
|
|
ASSERT_EQ ((UINTN)SampleGlobalTestPointer, (UINTN)((VOID *)-1));
|
|
}
|
|
|
|
/**
|
|
Set PcdDebugPropertyMask for each MacroTestsAssertsEnabledDisabled test
|
|
**/
|
|
class MacroTestsAssertsEnabledDisabled : public testing::TestWithParam<UINT8> {
|
|
void
|
|
SetUp (
|
|
)
|
|
{
|
|
PatchPcdSet8 (PcdDebugPropertyMask, GetParam ());
|
|
}
|
|
};
|
|
|
|
/**
|
|
Sample unit test using the ASSERT_TRUE() macro.
|
|
**/
|
|
TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertTrue) {
|
|
UINT64 Result;
|
|
|
|
//
|
|
// This test passes because expression always evaluated to TRUE.
|
|
//
|
|
ASSERT_TRUE (TRUE);
|
|
|
|
//
|
|
// This test passes because expression always evaluates to TRUE.
|
|
//
|
|
Result = LShiftU64 (BIT0, 1);
|
|
ASSERT_TRUE (Result == BIT1);
|
|
}
|
|
|
|
/**
|
|
Sample unit test using the ASSERT_FALSE() macro.
|
|
**/
|
|
TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertFalse) {
|
|
UINT64 Result;
|
|
|
|
//
|
|
// This test passes because expression always evaluated to FALSE.
|
|
//
|
|
ASSERT_FALSE (FALSE);
|
|
|
|
//
|
|
// This test passes because expression always evaluates to FALSE.
|
|
//
|
|
Result = LShiftU64 (BIT0, 1);
|
|
ASSERT_FALSE (Result == BIT0);
|
|
}
|
|
|
|
/**
|
|
Sample unit test using the ASSERT_EQ() macro.
|
|
**/
|
|
TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertEqual) {
|
|
UINT64 Result;
|
|
|
|
//
|
|
// This test passes because both values are always equal.
|
|
//
|
|
ASSERT_EQ (1, 1);
|
|
|
|
//
|
|
// This test passes because both values are always equal.
|
|
//
|
|
Result = LShiftU64 (BIT0, 1);
|
|
ASSERT_EQ (Result, (UINT64)BIT1);
|
|
}
|
|
|
|
/**
|
|
Sample unit test using the ASSERT_STREQ() macro.
|
|
**/
|
|
TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertMemEqual) {
|
|
CHAR8 *String1;
|
|
CHAR8 *String2;
|
|
|
|
//
|
|
// This test passes because String1 and String2 are the same.
|
|
//
|
|
String1 = (CHAR8 *)"Hello";
|
|
String2 = (CHAR8 *)"Hello";
|
|
ASSERT_STREQ (String1, String2);
|
|
}
|
|
|
|
/**
|
|
Sample unit test using the ASSERT_NE() macro.
|
|
**/
|
|
TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertNotEqual) {
|
|
UINT64 Result;
|
|
|
|
//
|
|
// This test passes because both values are never equal.
|
|
//
|
|
ASSERT_NE (0, 1);
|
|
|
|
//
|
|
// This test passes because both values are never equal.
|
|
//
|
|
Result = LShiftU64 (BIT0, 1);
|
|
ASSERT_NE (Result, (UINT64)BIT0);
|
|
}
|
|
|
|
/**
|
|
Sample unit test using the ASSERT_TRUE() and ASSERT(FALSE)
|
|
and EFI_EFFOR() macros to check status
|
|
**/
|
|
TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertNotEfiError) {
|
|
//
|
|
// This test passes because the status is not an EFI error.
|
|
//
|
|
ASSERT_FALSE (EFI_ERROR (EFI_SUCCESS));
|
|
|
|
//
|
|
// This test passes because the status is not an EFI error.
|
|
//
|
|
ASSERT_FALSE (EFI_ERROR (EFI_WARN_BUFFER_TOO_SMALL));
|
|
}
|
|
|
|
/**
|
|
Sample unit test using the ASSERT_EQ() macro to compare EFI_STATUS values.
|
|
**/
|
|
TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertStatusEqual) {
|
|
//
|
|
// This test passes because the status value are always equal.
|
|
//
|
|
ASSERT_EQ (EFI_SUCCESS, EFI_SUCCESS);
|
|
}
|
|
|
|
/**
|
|
Sample unit test using ASSERT_NE() macro to make sure a pointer is not NULL.
|
|
**/
|
|
TEST_P (MacroTestsAssertsEnabledDisabled, MacroAssertNotNull) {
|
|
UINT64 Result;
|
|
|
|
//
|
|
// This test passes because the pointer is never NULL.
|
|
//
|
|
ASSERT_NE (&Result, (UINT64 *)NULL);
|
|
}
|
|
|
|
/**
|
|
Sample unit test using that should not generate any ASSERTs()
|
|
**/
|
|
TEST_P (MacroTestsAssertsEnabledDisabled, MacroExpectNoAssertFailure) {
|
|
//
|
|
// This test passes because it never triggers an ASSERT().
|
|
//
|
|
ASSERT (TRUE);
|
|
|
|
//
|
|
// This test passes because DecimalToBcd() does not ASSERT() if the
|
|
// value passed in is <= 99.
|
|
//
|
|
DecimalToBcd8 (99);
|
|
}
|
|
|
|
/**
|
|
Sample unit test using the EXPECT_ANY_THROW() macro to test expected ASSERT()s.
|
|
**/
|
|
TEST_P (MacroTestsAssertsEnabledDisabled, MacroExpectAssertFailure) {
|
|
//
|
|
// Skip tests that verify an ASSERT() is triggered if ASSERT()s are disabled.
|
|
//
|
|
if ((PcdGet8 (PcdDebugPropertyMask) & BIT0) == 0x00) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// This test passes because it directly triggers an ASSERT().
|
|
//
|
|
EXPECT_ANY_THROW (ASSERT (FALSE));
|
|
|
|
//
|
|
// This test passes because DecimalToBcd() generates an ASSERT() if the
|
|
// value passed in is >= 100. The expected ASSERT() is caught by the unit
|
|
// test framework and EXPECT_ANY_THROW() returns without an error.
|
|
//
|
|
EXPECT_ANY_THROW (DecimalToBcd8 (101));
|
|
|
|
//
|
|
// This test passes because DecimalToBcd() generates an ASSERT() if the
|
|
// value passed in is >= 100. The expected ASSERT() is caught by the unit
|
|
// test framework and throws the C++ exception of type std::runtime_error.
|
|
// EXPECT_THROW() returns without an error.
|
|
//
|
|
EXPECT_THROW (DecimalToBcd8 (101), std::runtime_error);
|
|
|
|
//
|
|
// This test passes because DecimalToBcd() generates an ASSERT() if the
|
|
// value passed in is >= 100. The expected ASSERT() is caught by the unit
|
|
// test framework and throws the C++ exception of type std::runtime_error with
|
|
// a message that includes the filename, linenumber, and the expression that
|
|
// triggered the ASSERT().
|
|
//
|
|
// EXPECT_THROW_MESSAGE() calls DecimalToBcd() expecting DecimalToBds() to
|
|
// throw a C++ exception of type std::runtime_error with a message that
|
|
// includes the expression of "Value < 100" that triggered the ASSERT().
|
|
//
|
|
EXPECT_THROW_MESSAGE (DecimalToBcd8 (101), "Value < 100");
|
|
}
|
|
|
|
INSTANTIATE_TEST_SUITE_P (
|
|
ValidInput,
|
|
MacroTestsAssertsEnabledDisabled,
|
|
::testing::Values (PcdGet8 (PcdDebugPropertyMask) | BIT0, PcdGet8 (PcdDebugPropertyMask) & (~BIT0))
|
|
);
|
|
|
|
/**
|
|
Sample unit test using the SCOPED_TRACE() macro for trace messages.
|
|
**/
|
|
TEST (MacroTestsMessages, MacroTraceMessage) {
|
|
//
|
|
// Example of logging.
|
|
//
|
|
SCOPED_TRACE ("SCOPED_TRACE message\n");
|
|
|
|
//
|
|
// Always pass
|
|
//
|
|
ASSERT_TRUE (TRUE);
|
|
}
|
|
|
|
/**
|
|
Sample unit test that performs double free
|
|
**/
|
|
TEST (SanitizerTests, DoubleFreeDeathTest) {
|
|
UINT8 *Pointer;
|
|
|
|
Pointer = (UINT8 *)AllocatePool (100);
|
|
ASSERT_NE (Pointer, (UINT8 *)NULL);
|
|
FreePool (Pointer);
|
|
//
|
|
// Second free that should be caught by address sanitizer, log details, and exit
|
|
//
|
|
EXPECT_DEATH (FreePool (Pointer), "ERROR: AddressSanitizer: heap-use-after-free");
|
|
}
|
|
|
|
/**
|
|
Sample unit test that performs read past end of allocated buffer
|
|
**/
|
|
TEST (SanitizerTests, BufferOverflowReadDeathTest) {
|
|
UINT8 *Pointer;
|
|
UINT8 Value;
|
|
|
|
Pointer = (UINT8 *)AllocatePool (100);
|
|
ASSERT_NE (Pointer, (UINT8 *)NULL);
|
|
|
|
//
|
|
// Read past end of allocated buffer that should be caught by address sanitizer, log details, and exit
|
|
//
|
|
EXPECT_DEATH (Value = Pointer[110], "ERROR: AddressSanitizer: heap-buffer-overflow");
|
|
ASSERT_EQ (Value, Value);
|
|
|
|
FreePool (Pointer);
|
|
}
|
|
|
|
/**
|
|
Sample unit test that performs write past end of allocated buffer
|
|
**/
|
|
TEST (SanitizerTests, BufferOverflowWriteDeathTest) {
|
|
UINT8 *Pointer;
|
|
|
|
Pointer = (UINT8 *)AllocatePool (100);
|
|
ASSERT_NE (Pointer, (UINT8 *)NULL);
|
|
|
|
//
|
|
// Write past end of allocated buffer that should be caught by address sanitizer, log details, and exit
|
|
//
|
|
EXPECT_DEATH (Pointer[110] = 0, "ERROR: AddressSanitizer: heap-buffer-overflow");
|
|
|
|
FreePool (Pointer);
|
|
}
|
|
|
|
/**
|
|
Sample unit test that performs read before beginning of allocated buffer
|
|
**/
|
|
TEST (SanitizerTests, BufferUnderflowReadDeathTest) {
|
|
UINT8 *Pointer;
|
|
UINT8 Value;
|
|
|
|
Pointer = (UINT8 *)AllocatePool (100);
|
|
ASSERT_NE (Pointer, (UINT8 *)NULL);
|
|
|
|
//
|
|
// Read past end of allocated buffer that should be caught by address sanitizer, log details, and exit
|
|
//
|
|
EXPECT_DEATH (Value = Pointer[-10], "ERROR: AddressSanitizer: heap-buffer-overflow");
|
|
ASSERT_EQ (Value, Value);
|
|
|
|
FreePool (Pointer);
|
|
}
|
|
|
|
/**
|
|
Sample unit test that performs read from address 0 (NULL)
|
|
**/
|
|
TEST (SanitizerTests, NullPointerReadDeathTest) {
|
|
UINT8 Value;
|
|
|
|
//
|
|
// Read from address 0 should be caught by address sanitizer, log details, and exit
|
|
//
|
|
EXPECT_DEATH (Value = *(volatile UINT8 *)(NULL), "ERROR: AddressSanitizer: ");
|
|
ASSERT_EQ (Value, Value);
|
|
}
|
|
|
|
/**
|
|
Sample unit test that performs write to address 0 (NULL)
|
|
**/
|
|
TEST (SanitizerTests, NullPointerWriteDeathTest) {
|
|
//
|
|
// Write to address 0 should be caught by address sanitizer, log details, and exit
|
|
//
|
|
EXPECT_DEATH (*(volatile UINT8 *)(NULL) = 0, "ERROR: AddressSanitizer: ");
|
|
}
|
|
|
|
/**
|
|
Sample unit test that performs read from invalid address -1
|
|
**/
|
|
TEST (SanitizerTests, InvalidPointerReadDeathTest) {
|
|
UINT8 Value;
|
|
|
|
//
|
|
// Read from address -1 should be caught by address sanitizer, log details, and exit
|
|
//
|
|
EXPECT_DEATH (Value = *(volatile UINT8 *)(-1), "ERROR: AddressSanitizer: ");
|
|
ASSERT_EQ (Value, Value);
|
|
}
|
|
|
|
/**
|
|
Sample unit test that performs write to invalid address -1
|
|
**/
|
|
TEST (SanitizerTests, InvalidPointerWriteDeathTest) {
|
|
//
|
|
// Write to address -1 should be caught by address sanitizer, log details, and exit
|
|
//
|
|
EXPECT_DEATH (*(volatile UINT8 *)(-1) = 0, "ERROR: AddressSanitizer: ");
|
|
}
|
|
|
|
UINTN
|
|
DivideWithNoParameterChecking (
|
|
UINTN Dividend,
|
|
UINTN Divisor
|
|
)
|
|
{
|
|
//
|
|
// Perform integer division with no check for divide by zero
|
|
//
|
|
return (Dividend / Divisor);
|
|
}
|
|
|
|
/**
|
|
Sample unit test that performs a divide by 0
|
|
**/
|
|
TEST (SanitizerTests, DivideByZeroDeathTest) {
|
|
//
|
|
// Divide by 0 should be caught by address sanitizer, log details, and exit
|
|
//
|
|
EXPECT_DEATH (DivideWithNoParameterChecking (10, 0), "ERROR: AddressSanitizer: ");
|
|
}
|
|
|
|
/**
|
|
Sample unit test that allocates and frees buffers below 4GB
|
|
**/
|
|
TEST (MemoryAllocationTests, Below4GB) {
|
|
VOID *Buffer1;
|
|
VOID *Buffer2;
|
|
UINT8 EmptyBuffer[0x100];
|
|
|
|
//
|
|
// Length 0 always fails
|
|
//
|
|
Buffer1 = HostAllocatePoolBelowAddress (BASE_4GB - 1, 0);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Length == Maximum Address always fails
|
|
//
|
|
Buffer1 = HostAllocatePoolBelowAddress (BASE_4GB - 1, SIZE_4GB);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Length > Maximum Address always fails
|
|
//
|
|
Buffer1 = HostAllocatePoolBelowAddress (BASE_4GB - 1, SIZE_8GB);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Maximum Address 0 always fails
|
|
//
|
|
Buffer1 = HostAllocatePoolBelowAddress (0, SIZE_4KB);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Maximum Address < 64KB always fails
|
|
//
|
|
Buffer1 = HostAllocatePoolBelowAddress (BASE_64KB - 1, SIZE_4KB);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Not enough memory available always fails
|
|
//
|
|
Buffer1 = HostAllocatePoolBelowAddress (BASE_128KB - 1, SIZE_64KB);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Allocation of 4KB buffer below 4GB must succeed
|
|
//
|
|
Buffer1 = HostAllocatePoolBelowAddress (BASE_4GB - 1, SIZE_4KB);
|
|
ASSERT_NE (Buffer1, (VOID *)NULL);
|
|
ASSERT_LT ((UINTN)Buffer1, BASE_4GB);
|
|
|
|
//
|
|
// Allocated buffer must support read and write
|
|
//
|
|
*(UINT8 *)Buffer1 = 0x5A;
|
|
ASSERT_EQ (*(UINT8 *)Buffer1, 0x5A);
|
|
|
|
//
|
|
// Allocation of 1MB buffer below 4GB must succeed
|
|
//
|
|
Buffer2 = HostAllocatePoolBelowAddress (BASE_4GB - 1, SIZE_1MB);
|
|
ASSERT_NE (Buffer2, (VOID *)NULL);
|
|
ASSERT_LT ((UINTN)Buffer2, BASE_4GB);
|
|
|
|
//
|
|
// Allocated buffer must support read and write
|
|
//
|
|
*(UINT8 *)Buffer2 = 0x5A;
|
|
ASSERT_EQ (*(UINT8 *)Buffer2, 0x5A);
|
|
|
|
//
|
|
// Allocations must return different values
|
|
//
|
|
ASSERT_NE (Buffer1, Buffer2);
|
|
|
|
//
|
|
// Free buffers below 4GB must not ASSERT
|
|
//
|
|
HostFreePoolBelowAddress (Buffer1);
|
|
HostFreePoolBelowAddress (Buffer2);
|
|
|
|
//
|
|
// Expect ASSERT() tests
|
|
//
|
|
EXPECT_ANY_THROW (HostFreePoolBelowAddress (NULL));
|
|
EXPECT_ANY_THROW (HostFreePoolBelowAddress (EmptyBuffer + 0x80));
|
|
Buffer1 = AllocatePool (0x100);
|
|
EXPECT_ANY_THROW (HostFreePoolBelowAddress ((UINT8 *)Buffer1 + 0x80));
|
|
FreePool (Buffer1);
|
|
}
|
|
|
|
/**
|
|
Sample unit test that allocates and frees aligned pages below 4GB
|
|
**/
|
|
TEST (MemoryAllocationTests, AlignedBelow4GB) {
|
|
VOID *Buffer1;
|
|
VOID *Buffer2;
|
|
UINT8 EmptyBuffer[0x100];
|
|
|
|
//
|
|
// Pages 0 always fails
|
|
//
|
|
Buffer1 = HostAllocateAlignedPagesBelowAddress (BASE_4GB - 1, 0, SIZE_4KB);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Alignment not a power of 2 always fails
|
|
//
|
|
Buffer1 = HostAllocateAlignedPagesBelowAddress (BASE_4GB - 1, SIZE_4KB, 5);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Alignment not a power of 2 always fails
|
|
//
|
|
Buffer1 = HostAllocateAlignedPagesBelowAddress (BASE_4GB - 1, SIZE_4KB, SIZE_16KB + 1);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Alignment larger than largest supported virtual address always fails
|
|
// Only applies to 32-bit architectures
|
|
//
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
Buffer1 = HostAllocateAlignedPagesBelowAddress (BASE_4GB - 1, SIZE_4KB, SIZE_4GB);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
}
|
|
|
|
//
|
|
// Length == Maximum Address always fails
|
|
//
|
|
Buffer1 = HostAllocateAlignedPagesBelowAddress (BASE_4GB - 1, EFI_SIZE_TO_PAGES (SIZE_4GB), SIZE_4KB);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Length > Maximum Address always fails
|
|
//
|
|
Buffer1 = HostAllocateAlignedPagesBelowAddress (BASE_4GB - 1, EFI_SIZE_TO_PAGES (SIZE_8GB), SIZE_4KB);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Alignment >= Maximum Address always fails
|
|
//
|
|
Buffer1 = HostAllocateAlignedPagesBelowAddress (BASE_4GB - 1, EFI_SIZE_TO_PAGES (SIZE_4GB), SIZE_4GB);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Maximum Address 0 always fails
|
|
//
|
|
Buffer1 = HostAllocateAlignedPagesBelowAddress (0, EFI_SIZE_TO_PAGES (SIZE_4KB), SIZE_4KB);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Maximum Address <= 64KB always fails
|
|
//
|
|
Buffer1 = HostAllocateAlignedPagesBelowAddress (BASE_64KB - 1, EFI_SIZE_TO_PAGES (SIZE_4KB), SIZE_4KB);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Not enough memory available always fails
|
|
//
|
|
Buffer1 = HostAllocateAlignedPagesBelowAddress (BASE_128KB - 1, EFI_SIZE_TO_PAGES (SIZE_64KB), SIZE_4KB);
|
|
ASSERT_EQ (Buffer1, (VOID *)NULL);
|
|
|
|
//
|
|
// Allocation of 4KB buffer below 4GB must succeed
|
|
//
|
|
Buffer1 = HostAllocateAlignedPagesBelowAddress (BASE_4GB - 1, EFI_SIZE_TO_PAGES (SIZE_4KB), SIZE_4KB);
|
|
ASSERT_NE (Buffer1, (VOID *)NULL);
|
|
ASSERT_LT ((UINTN)Buffer1, BASE_4GB);
|
|
|
|
//
|
|
// Allocated buffer must support read and write
|
|
//
|
|
*(UINT8 *)Buffer1 = 0x5A;
|
|
ASSERT_EQ (*(UINT8 *)Buffer1, 0x5A);
|
|
|
|
//
|
|
// Allocation of 1MB buffer below 4GB must succeed
|
|
//
|
|
Buffer2 = HostAllocateAlignedPagesBelowAddress (BASE_4GB - 1, EFI_SIZE_TO_PAGES (SIZE_1MB), SIZE_1MB);
|
|
ASSERT_NE (Buffer2, (VOID *)NULL);
|
|
ASSERT_LT ((UINTN)Buffer2, BASE_4GB);
|
|
|
|
//
|
|
// Allocated buffer must support read and write
|
|
//
|
|
*(UINT8 *)Buffer2 = 0x5A;
|
|
ASSERT_EQ (*(UINT8 *)Buffer2, 0x5A);
|
|
|
|
//
|
|
// Allocations must return different values
|
|
//
|
|
ASSERT_NE (Buffer1, Buffer2);
|
|
|
|
//
|
|
// Free buffers below 4GB must not ASSERT
|
|
//
|
|
HostFreeAlignedPagesBelowAddress (Buffer1, EFI_SIZE_TO_PAGES (SIZE_4KB));
|
|
HostFreeAlignedPagesBelowAddress (Buffer2, EFI_SIZE_TO_PAGES (SIZE_1MB));
|
|
|
|
//
|
|
// Expect ASSERT() tests
|
|
//
|
|
EXPECT_ANY_THROW (HostFreeAlignedPagesBelowAddress (NULL, 0));
|
|
EXPECT_ANY_THROW (HostFreeAlignedPagesBelowAddress (EmptyBuffer + 0x80, 1));
|
|
Buffer1 = AllocatePool (0x100);
|
|
EXPECT_ANY_THROW (HostFreeAlignedPagesBelowAddress ((UINT8 *)Buffer1 + 0x80, 1));
|
|
FreePool (Buffer1);
|
|
}
|
|
|
|
int
|
|
main (
|
|
int argc,
|
|
char *argv[]
|
|
)
|
|
{
|
|
testing::InitGoogleTest (&argc, argv);
|
|
return RUN_ALL_TESTS ();
|
|
}
|