Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
4142d1e0
Commit
4142d1e0
authored
Nov 10, 2022
by
Paul Gofman
Committed by
Alexandre Julliard
May 25, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Support MEM_PRESERVE_PLACEHOLDER in NtFreeVirtualMemory().
parent
04e2b02a
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
63 additions
and
36 deletions
+63
-36
process.c
dlls/kernelbase/tests/process.c
+15
-20
virtual.c
dlls/ntdll/tests/virtual.c
+7
-12
virtual.c
dlls/ntdll/unix/virtual.c
+41
-4
No files found.
dlls/kernelbase/tests/process.c
View file @
4142d1e0
...
...
@@ -178,14 +178,14 @@ static void test_VirtualAlloc2(void)
ok
(
info
.
RegionSize
==
2
*
size
,
"Unexpected size.
\n
"
);
ret
=
VirtualFree
(
placeholder1
,
size
,
MEM_RELEASE
|
MEM_PRESERVE_PLACEHOLDER
);
todo_wine
ok
(
ret
,
"Failed to split placeholder.
\n
"
);
ok
(
ret
,
"Failed to split placeholder.
\n
"
);
memset
(
&
info
,
0
,
sizeof
(
info
));
VirtualQuery
(
placeholder1
,
&
info
,
sizeof
(
info
));
ok
(
info
.
AllocationProtect
==
PAGE_NOACCESS
,
"Unexpected protection %#lx.
\n
"
,
info
.
AllocationProtect
);
ok
(
info
.
State
==
MEM_RESERVE
,
"Unexpected state %#lx.
\n
"
,
info
.
State
);
ok
(
info
.
Type
==
MEM_PRIVATE
,
"Unexpected type %#lx.
\n
"
,
info
.
Type
);
todo_wine
ok
(
info
.
RegionSize
==
size
,
"Unexpected size.
\n
"
);
ok
(
info
.
RegionSize
==
size
,
"Unexpected size.
\n
"
);
placeholder2
=
(
void
*
)((
BYTE
*
)
placeholder1
+
size
);
memset
(
&
info
,
0
,
sizeof
(
info
));
...
...
@@ -199,10 +199,10 @@ static void test_VirtualAlloc2(void)
ok
(
!!
section
,
"Failed to create a section.
\n
"
);
view1
=
pMapViewOfFile3
(
section
,
NULL
,
placeholder1
,
0
,
size
,
MEM_REPLACE_PLACEHOLDER
,
PAGE_READWRITE
,
NULL
,
0
);
todo_wine
ok
(
!!
view1
,
"Failed to map a section.
\n
"
);
ok
(
!!
view1
,
"Failed to map a section.
\n
"
);
view2
=
pMapViewOfFile3
(
section
,
NULL
,
placeholder2
,
0
,
size
,
MEM_REPLACE_PLACEHOLDER
,
PAGE_READWRITE
,
NULL
,
0
);
todo_wine
ok
(
!!
view2
,
"Failed to map a section.
\n
"
);
ok
(
!!
view2
,
"Failed to map a section.
\n
"
);
CloseHandle
(
section
);
UnmapViewOfFile
(
view1
);
...
...
@@ -218,19 +218,16 @@ static void test_VirtualAlloc2(void)
p1
=
p
+
size
/
2
;
p2
=
p1
+
size
/
4
;
ret
=
VirtualFree
(
p1
,
size
/
4
,
MEM_RELEASE
|
MEM_PRESERVE_PLACEHOLDER
);
todo_wine
ok
(
ret
,
"Failed to split a placeholder.
\n
"
);
if
(
ret
)
{
check_region_size
(
p
,
size
/
2
);
check_region_size
(
p1
,
size
/
4
);
}
ok
(
ret
,
"Failed to split a placeholder.
\n
"
);
check_region_size
(
p
,
size
/
2
);
check_region_size
(
p1
,
size
/
4
);
check_region_size
(
p2
,
2
*
size
-
size
/
2
-
size
/
4
);
ret
=
VirtualFree
(
p
,
0
,
MEM_RELEASE
);
ok
(
ret
,
"Failed to release a region.
\n
"
);
ret
=
VirtualFree
(
p1
,
0
,
MEM_RELEASE
);
todo_wine
ok
(
ret
,
"Failed to release a region.
\n
"
);
ok
(
ret
,
"Failed to release a region.
\n
"
);
ret
=
VirtualFree
(
p2
,
0
,
MEM_RELEASE
);
todo_wine
ok
(
ret
,
"Failed to release a region.
\n
"
);
ok
(
ret
,
"Failed to release a region.
\n
"
);
/* Split in two regions, specifying lower part. */
p
=
pVirtualAlloc2
(
NULL
,
NULL
,
2
*
size
,
MEM_RESERVE_PLACEHOLDER
|
MEM_RESERVE
,
PAGE_NOACCESS
,
NULL
,
0
);
...
...
@@ -239,14 +236,13 @@ static void test_VirtualAlloc2(void)
p1
=
p
;
p2
=
p
+
size
/
2
;
ret
=
VirtualFree
(
p1
,
size
/
2
,
MEM_RELEASE
|
MEM_PRESERVE_PLACEHOLDER
);
todo_wine
ok
(
ret
,
"Failed to split a placeholder.
\n
"
);
if
(
ret
)
check_region_size
(
p1
,
size
/
2
);
ok
(
ret
,
"Failed to split a placeholder.
\n
"
);
check_region_size
(
p1
,
size
/
2
);
check_region_size
(
p2
,
2
*
size
-
size
/
2
);
ret
=
VirtualFree
(
p1
,
0
,
MEM_RELEASE
);
ok
(
ret
,
"Failed to release a region.
\n
"
);
ret
=
VirtualFree
(
p2
,
0
,
MEM_RELEASE
);
todo_wine
ok
(
ret
,
"Failed to release a region.
\n
"
);
ok
(
ret
,
"Failed to release a region.
\n
"
);
/* Split in two regions, specifying second half. */
p
=
pVirtualAlloc2
(
NULL
,
NULL
,
2
*
size
,
MEM_RESERVE_PLACEHOLDER
|
MEM_RESERVE
,
PAGE_NOACCESS
,
NULL
,
0
);
...
...
@@ -255,14 +251,13 @@ static void test_VirtualAlloc2(void)
p1
=
p
;
p2
=
p
+
size
;
ret
=
VirtualFree
(
p2
,
size
,
MEM_RELEASE
|
MEM_PRESERVE_PLACEHOLDER
);
todo_wine
ok
(
ret
,
"Failed to split a placeholder.
\n
"
);
if
(
ret
)
check_region_size
(
p1
,
size
);
ok
(
ret
,
"Failed to split a placeholder.
\n
"
);
check_region_size
(
p1
,
size
);
check_region_size
(
p2
,
size
);
ret
=
VirtualFree
(
p1
,
0
,
MEM_RELEASE
);
ok
(
ret
,
"Failed to release a region.
\n
"
);
ret
=
VirtualFree
(
p2
,
0
,
MEM_RELEASE
);
todo_wine
ok
(
ret
,
"Failed to release a region.
\n
"
);
ok
(
ret
,
"Failed to release a region.
\n
"
);
}
static
void
test_VirtualAllocFromApp
(
void
)
...
...
dlls/ntdll/tests/virtual.c
View file @
4142d1e0
...
...
@@ -354,13 +354,10 @@ static void test_NtAllocateVirtualMemoryEx(void)
p2
=
p1
+
size
/
4
;
size2
=
size
/
4
;
status
=
NtFreeVirtualMemory
(
NtCurrentProcess
(),
(
void
**
)
&
p1
,
&
size2
,
MEM_RELEASE
|
MEM_PRESERVE_PLACEHOLDER
);
todo_wine
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
if
(
status
==
STATUS_SUCCESS
)
{
check_region_size
(
p
,
size
/
2
);
check_region_size
(
p1
,
size
/
4
);
}
check_region_size
(
p
,
size
/
2
);
check_region_size
(
p1
,
size
/
4
);
check_region_size
(
p2
,
size
-
size
/
2
-
size
/
4
);
status
=
NtFreeVirtualMemory
(
NtCurrentProcess
(),
(
void
**
)
&
p
,
&
size2
,
MEM_RELEASE
);
...
...
@@ -381,11 +378,10 @@ static void test_NtAllocateVirtualMemoryEx(void)
p2
=
p1
+
size
/
4
;
size2
=
size
/
4
;
status
=
NtFreeVirtualMemory
(
NtCurrentProcess
(),
(
void
**
)
&
p1
,
&
size2
,
MEM_RELEASE
|
MEM_PRESERVE_PLACEHOLDER
);
todo_wine
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
ok
(
p1
==
addr1
,
"Unexpected address.
\n
"
);
if
(
status
==
STATUS_SUCCESS
)
check_region_size
(
p1
,
size
/
4
);
check_region_size
(
p1
,
size
/
4
);
check_region_size
(
p2
,
size
-
size
/
4
);
status
=
NtFreeVirtualMemory
(
NtCurrentProcess
(),
(
void
**
)
&
p1
,
&
size2
,
MEM_RELEASE
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
...
...
@@ -404,10 +400,9 @@ static void test_NtAllocateVirtualMemoryEx(void)
size2
=
size
/
2
;
status
=
NtFreeVirtualMemory
(
NtCurrentProcess
(),
(
void
**
)
&
p2
,
&
size2
,
MEM_RELEASE
|
MEM_PRESERVE_PLACEHOLDER
);
todo_wine
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
ok
(
p2
==
p1
+
size
/
2
,
"Unexpected address.
\n
"
);
if
(
status
==
STATUS_SUCCESS
)
check_region_size
(
p1
,
size
/
2
);
check_region_size
(
p1
,
size
/
2
);
check_region_size
(
p2
,
size
/
2
);
status
=
NtFreeVirtualMemory
(
NtCurrentProcess
(),
(
void
**
)
&
p1
,
&
size2
,
MEM_RELEASE
);
ok
(
status
==
STATUS_SUCCESS
,
"Unexpected status %08lx.
\n
"
,
status
);
...
...
dlls/ntdll/unix/virtual.c
View file @
4142d1e0
...
...
@@ -2189,17 +2189,40 @@ static NTSTATUS decommit_pages( struct file_view *view, size_t start, size_t siz
/***********************************************************************
* view_make_placeholder
*
* Setup placeholder view.
* virtual_mutex must be held by caller.
*/
static
void
view_make_placeholder
(
struct
file_view
*
view
)
{
view
->
protect
=
VPROT_PLACEHOLDER
|
VPROT_FREE_PLACEHOLDER
;
set_page_vprot
(
view
->
base
,
view
->
size
,
0
);
anon_mmap_fixed
(
view
->
base
,
view
->
size
,
PROT_NONE
,
0
);
}
/***********************************************************************
* free_pages
*
* Free some pages of a given view.
* virtual_mutex must be held by caller.
*/
static
NTSTATUS
free_pages
(
struct
file_view
*
view
,
char
*
base
,
size_t
size
)
static
NTSTATUS
free_pages
(
struct
file_view
*
view
,
char
*
base
,
size_t
size
,
BOOL
preserve_placeholder
)
{
if
(
preserve_placeholder
)
{
if
(
!
size
)
return
STATUS_INVALID_PARAMETER_3
;
if
(
!
(
view
->
protect
&
VPROT_PLACEHOLDER
))
return
STATUS_CONFLICTING_ADDRESSES
;
if
(
view
->
protect
&
VPROT_FREE_PLACEHOLDER
&&
size
==
view
->
size
)
return
STATUS_CONFLICTING_ADDRESSES
;
}
else
if
(
!
size
)
size
=
view
->
size
;
if
(
size
==
view
->
size
)
{
assert
(
base
==
view
->
base
);
delete_view
(
view
);
if
(
preserve_placeholder
)
view_make_placeholder
(
view
);
else
delete_view
(
view
);
return
STATUS_SUCCESS
;
}
if
(
view
->
base
!=
base
&&
base
+
size
!=
(
char
*
)
view
->
base
+
view
->
size
)
...
...
@@ -2237,6 +2260,20 @@ static NTSTATUS free_pages( struct file_view *view, char *base, size_t size )
VIRTUAL_DEBUG_DUMP_VIEW
(
view
);
}
if
(
preserve_placeholder
)
{
if
(
!
(
view
=
alloc_view
()))
{
ERR
(
"Out of memory for %p-%p
\n
"
,
base
,
base
+
size
);
return
STATUS_NO_MEMORY
;
}
view
->
base
=
base
;
view
->
size
=
size
;
view_make_placeholder
(
view
);
register_view
(
view
);
return
STATUS_SUCCESS
;
}
set_page_vprot
(
base
,
size
,
0
);
if
(
arm64ec_map
)
clear_arm64ec_range
(
base
,
size
);
unmap_area
(
base
,
size
);
...
...
@@ -4395,10 +4432,10 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
else
if
(
!
size
&&
base
!=
view
->
base
)
status
=
STATUS_FREE_VM_NOT_AT_BASE
;
else
if
((
char
*
)
view
->
base
+
view
->
size
-
base
<
size
)
status
=
STATUS_UNABLE_TO_FREE_VM
;
else
if
(
type
==
MEM_DECOMMIT
)
status
=
decommit_pages
(
view
,
base
-
(
char
*
)
view
->
base
,
size
);
else
if
(
type
==
MEM_RELEASE
)
else
if
(
type
==
MEM_RELEASE
||
(
type
==
(
MEM_RELEASE
|
MEM_PRESERVE_PLACEHOLDER
))
)
{
status
=
free_pages
(
view
,
base
,
size
,
type
&
MEM_PRESERVE_PLACEHOLDER
);
if
(
!
size
)
size
=
view
->
size
;
status
=
free_pages
(
view
,
base
,
size
);
}
else
status
=
STATUS_INVALID_PARAMETER
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment