Skip to content

Commit

Permalink
Move string allocation APIs to cxplat library
Browse files Browse the repository at this point in the history
Signed-off-by: Dave Thaler <[email protected]>
  • Loading branch information
dthaler committed Aug 19, 2023
1 parent bb99536 commit b8852cd
Show file tree
Hide file tree
Showing 13 changed files with 189 additions and 84 deletions.
26 changes: 25 additions & 1 deletion cxplat/cxplat_test/cxplat_memory_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,28 @@ TEST_CASE("reallocate aligned", "[memory]")
cxplat_free(new_buffer);
}

TEST_CASE("cxplat_free null", "[ex]") { cxplat_free(nullptr); }
TEST_CASE("cxplat_free null", "[memory]") { cxplat_free(nullptr); }

TEST_CASE("cxplat_duplicate_string", "[memory]")
{
char* string = cxplat_duplicate_string("test");
REQUIRE(string != nullptr);
REQUIRE(strcmp(string, "test") == 0);

cxplat_free(string);
}

TEST_CASE("cxplat_duplicate_utf8_string", "[memory]")
{
const char string[] = "test";
cxplat_utf8_string_t source = CXPLAT_UTF8_STRING_FROM_CONST_STRING(string);
REQUIRE(source.length == strlen(string));

cxplat_utf8_string_t destination;
cxplat_status_t status = cxplat_duplicate_utf8_string(&destination, &source);
REQUIRE(status == CXPLAT_STATUS_SUCCESS);
REQUIRE(destination.length == source.length);
REQUIRE(memcmp(destination.value, source.value, source.length) == 0);

cxplat_utf8_string_free(&destination);
}
49 changes: 49 additions & 0 deletions cxplat/inc/cxplat_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,25 @@ extern "C"
CxPlatNonPagedPoolNxCacheAligned = CxPlatNonPagedPoolNx + 4,
} cxplat_pool_type_t;

/**
* @brief A UTF-8 encoded string.
* Notes:
* 1) This string is not NULL terminated, instead relies on length.
* 2) A single UTF-8 code point (aka character) could be 1-4 bytes in
* length.
*
*/
typedef struct _cxplat_utf8_string
{
uint8_t* value;
size_t length;
} cxplat_utf8_string_t;

#define CXPLAT_UTF8_STRING_FROM_CONST_STRING(x) \
{ \
((uint8_t*)(x)), sizeof((x)) - 1 \
}

/**
* @brief Allocate memory.
* @param[in] size Size of memory to allocate.
Expand Down Expand Up @@ -91,6 +110,36 @@ extern "C"
void
cxplat_free_cache_aligned(_Frees_ptr_opt_ void* memory);

/**
* @brief Allocate and copy a UTF-8 string.
*
* @param[out] destination Pointer to memory where the new UTF-8 character
* sequence will be allocated.
* @param[in] source UTF-8 string that will be copied.
* @retval CXPLAT_STATUS_SUCCESS The operation was successful.
* @retval CXPLAT_STATUS_NO_MEMORY Unable to allocate resources for this
* UTF-8 string.
*/
_Must_inspect_result_ cxplat_status_t
cxplat_duplicate_utf8_string(_Out_ cxplat_utf8_string_t* destination, _In_ const cxplat_utf8_string_t* source);

/**
* @brief Free a UTF-8 string allocated by cxplat_duplicate_utf8_string.
*
* @param[in,out] string The string to free.
*/
void
cxplat_utf8_string_free(_Inout_ cxplat_utf8_string_t* string);

/**
* @brief Duplicate a null-terminated string.
*
* @param[in] source String to duplicate.
* @return Pointer to the duplicated string or NULL if out of memory.
*/
_Must_inspect_result_ char*
cxplat_duplicate_string(_In_z_ const char* source);

#ifdef __cplusplus
}
#endif
5 changes: 4 additions & 1 deletion cxplat/inc/winkernel/cxplat_winkernel.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT
#pragma once
#include <ntdef.h>
#if !defined(_AMD64_) && defined(_M_AMD64)
#define _AMD64_
#endif
#include <ntdef.h> // for NTSTATUS
#include <ntstatus.h>

// Map specific cxplat_status_t values to HRESULT values.
Expand Down
12 changes: 11 additions & 1 deletion cxplat/src/cxplat_winkernel/cxplat_winkernel.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common.h" />
<ClCompile Include="..\memory.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\inc\cxplat.h" />
<ClInclude Include="..\..\inc\cxplat_common.h" />
<ClInclude Include="..\..\inc\cxplat_fault_injection.h" />
<ClInclude Include="..\..\inc\cxplat_memory.h" />
<ClInclude Include="..\..\inc\winkernel\cxplat_platform.h" />
<ClInclude Include="..\..\inc\winkernel\cxplat_winkernel.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
Expand Down Expand Up @@ -113,6 +121,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)../../inc;$(ProjectDir)../../inc/winkernel</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>
Expand All @@ -130,6 +139,7 @@
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>$(ProjectDir)../../inc;$(ProjectDir)../../inc/winkernel</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>
Expand Down
22 changes: 21 additions & 1 deletion cxplat/src/cxplat_winkernel/cxplat_winkernel.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,27 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common.h">
<ClCompile Include="..\memory.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\inc\cxplat.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\cxplat_common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\cxplat_fault_injection.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\cxplat_memory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\winkernel\cxplat_platform.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\winkernel\cxplat_winkernel.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
Expand Down
3 changes: 2 additions & 1 deletion cxplat/src/cxplat_winuser/cxplat_winuser.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,11 @@
<ClInclude Include="winuser_internal.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\memory.c" />
<ClCompile Include="cxplat_winuser.cpp" />
<ClCompile Include="fault_injection.cpp" />
<ClCompile Include="leak_detector.cpp" />
<ClCompile Include="memory.cpp" />
<ClCompile Include="memory_winuser.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
Expand Down
5 changes: 4 additions & 1 deletion cxplat/src/cxplat_winuser/cxplat_winuser.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@
<ClCompile Include="cxplat_winuser.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="memory.cpp">
<ClCompile Include="memory_winuser.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\memory.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ extern cxplat_leak_detector_ptr _cxplat_leak_detector_ptr;

extern "C" size_t cxplat_fuzzing_memory_limit = MAXSIZE_T;

#define CXPLAT_DEFAULT_TAG 'lpxc'

typedef struct
{
cxplat_pool_type_t pool_type;
Expand Down Expand Up @@ -117,11 +115,6 @@ __drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_writes_maybenull_(size) void*
return memory;
}

__drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_writes_maybenull_(size) void* cxplat_allocate(size_t size)
{
return cxplat_allocate_with_tag(CxPlatNonPagedPoolNx, size, CXPLAT_DEFAULT_TAG, true);
}

__drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_writes_maybenull_(new_size) void* cxplat_reallocate_with_tag(
_In_ _Post_invalid_ void* pointer, size_t old_size, size_t new_size, uint32_t tag)
{
Expand Down Expand Up @@ -166,12 +159,6 @@ __drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_writes_maybenull_(new_size) v
return p;
}

__drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_writes_maybenull_(new_size) void* cxplat_reallocate(
_In_ _Post_invalid_ void* memory, size_t old_size, size_t new_size)
{
return cxplat_reallocate_with_tag(memory, old_size, new_size, CXPLAT_DEFAULT_TAG);
}

void
cxplat_free(_Frees_ptr_opt_ void* pointer)
{
Expand All @@ -195,10 +182,11 @@ cxplat_free(_Frees_ptr_opt_ void* pointer)
}
}

__drv_allocatesMem(Mem) _Must_inspect_result_
_Ret_writes_maybenull_(size) void*
cxplat_allocate_cache_aligned(size_t size)
_Must_inspect_result_
_Ret_writes_maybenull_(size) void* cxplat_allocate_cache_aligned_with_tag(size_t size, uint32_t tag)
{
UNREFERENCED_PARAMETER(tag);

if (size > cxplat_fuzzing_memory_limit) {
return nullptr;
}
Expand All @@ -214,14 +202,6 @@ cxplat_allocate_cache_aligned(size_t size)
return memory;
}

_Must_inspect_result_
_Ret_writes_maybenull_(size) void* cxplat_allocate_cache_aligned_with_tag(size_t size, uint32_t tag)
{
UNREFERENCED_PARAMETER(tag);

return cxplat_allocate_cache_aligned(size);
}

void
cxplat_free_cache_aligned(_Pre_maybenull_ _Post_ptr_invalid_ void* memory)
{
Expand Down
64 changes: 64 additions & 0 deletions cxplat/src/memory.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) Microsoft Corporation
// SPDX-License-Identifier: MIT

#include "cxplat.h"
#include <memory.h>
#include <string.h>
#include "cxplat.h"
cxplat_status_t dummy;

#define CXPLAT_DEFAULT_TAG 'lpxc'

__drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_writes_maybenull_(size) void* cxplat_allocate(size_t size)
{
return cxplat_allocate_with_tag(CxPlatNonPagedPoolNx, size, CXPLAT_DEFAULT_TAG, true);
}

__drv_allocatesMem(Mem) _Must_inspect_result_ _Ret_writes_maybenull_(new_size) void* cxplat_reallocate(
_In_ _Post_invalid_ void* memory, size_t old_size, size_t new_size)
{
return cxplat_reallocate_with_tag(memory, old_size, new_size, CXPLAT_DEFAULT_TAG);
}

__drv_allocatesMem(Mem) _Must_inspect_result_
_Ret_writes_maybenull_(size) void* cxplat_allocate_cache_aligned(size_t size)
{
return cxplat_allocate_cache_aligned_with_tag(size, CXPLAT_DEFAULT_TAG);
}

_Must_inspect_result_ _Ret_maybenull_z_ char*
cxplat_duplicate_string(_In_z_ const char* source)
{
size_t size = strlen(source) + 1;
char* destination = (char*)cxplat_allocate(size);
if (destination) {
memcpy(destination, source, size);
}
return destination;
}

_Must_inspect_result_ cxplat_status_t
cxplat_duplicate_utf8_string(_Out_ cxplat_utf8_string_t* destination, _In_ const cxplat_utf8_string_t* source)
{
if (!source->value || !source->length) {
destination->value = NULL;
destination->length = 0;
return CXPLAT_STATUS_SUCCESS;
} else {
destination->value = (uint8_t*)cxplat_allocate(source->length);
if (!destination->value) {
return CXPLAT_STATUS_NO_MEMORY;
}
memcpy(destination->value, source->value, source->length);
destination->length = source->length;
return CXPLAT_STATUS_SUCCESS;
}
}

void
cxplat_utf8_string_free(_Inout_ cxplat_utf8_string_t* string)
{
cxplat_free(string->value);
string->value = NULL;
string->length = 0;
}
Loading

0 comments on commit b8852cd

Please sign in to comment.