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
47404fb3
Commit
47404fb3
authored
Jun 07, 2023
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Reimplement allocation inside a reserved area without using a callback.
And make the allocation limits more explicit.
parent
33240c54
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
74 additions
and
44 deletions
+74
-44
virtual.c
dlls/ntdll/unix/virtual.c
+74
-44
No files found.
dlls/ntdll/unix/virtual.c
View file @
47404fb3
...
...
@@ -1390,7 +1390,7 @@ static void *map_free_area( void *base, void *end, size_t size, int top_down, in
*
* Find a free area between views inside the specified range.
* virtual_mutex must be held by caller.
* The range must be inside
the preloader reserved range
.
* The range must be inside
a reserved area
.
*/
static
void
*
find_reserved_free_area
(
void
*
base
,
void
*
end
,
size_t
size
,
int
top_down
,
size_t
align_mask
)
{
...
...
@@ -1831,52 +1831,88 @@ static inline void *unmap_extra_space( void *ptr, size_t total_size, size_t want
}
struct
alloc_area
{
size_t
size
;
int
top_down
;
void
*
limit
;
void
*
result
;
size_t
align_mask
;
};
/***********************************************************************
*
alloc_reserved_area_callback
*
find_reserved_free_area_outside_preloader
*
* Try to map some space inside a reserved area. Callback for mmap_enum_reserved_areas.
* Find a free area inside a reserved area, skipping the preloader reserved range.
* virtual_mutex must be held by caller.
*/
static
int
alloc_reserved_area_callback
(
void
*
start
,
SIZE_T
size
,
void
*
arg
)
static
void
*
find_reserved_free_area_outside_preloader
(
void
*
start
,
void
*
end
,
size_t
size
,
int
top_down
,
size_t
align_mask
)
{
struct
alloc_area
*
alloc
=
arg
;
void
*
end
=
(
char
*
)
start
+
size
;
if
(
start
<
address_space_start
)
start
=
address_space_start
;
if
(
is_beyond_limit
(
start
,
size
,
alloc
->
limit
))
end
=
alloc
->
limit
;
if
(
start
>=
end
)
return
0
;
void
*
ret
;
/* make sure we don't touch the preloader reserved range */
if
(
preload_reserve_end
>=
start
)
if
(
preload_reserve_end
>=
end
)
{
if
(
preload_reserve_start
<=
start
)
return
NULL
;
/* no space in that area */
if
(
preload_reserve_start
<
end
)
end
=
preload_reserve_start
;
}
else
if
(
preload_reserve_start
<=
start
)
{
if
(
preload_reserve_end
>=
end
)
if
(
preload_reserve_end
>
start
)
start
=
preload_reserve_end
;
}
else
/* range is split in two by the preloader reservation, try both parts */
{
if
(
top_down
)
{
if
(
preload_reserve_start
<=
start
)
return
0
;
/* no space in that area */
if
(
preload_reserve_start
<
end
)
end
=
preload_reserve_start
;
ret
=
find_reserved_free_area
(
preload_reserve_end
,
end
,
size
,
top_down
,
align_mask
);
if
(
ret
)
return
ret
;
end
=
preload_reserve_start
;
}
else
if
(
preload_reserve_start
<=
start
)
start
=
preload_reserve_end
;
else
{
/* range is split in two by the preloader reservation, try first part */
if
((
alloc
->
result
=
find_reserved_free_area
(
start
,
preload_reserve_start
,
alloc
->
size
,
alloc
->
top_down
,
alloc
->
align_mask
)))
return
1
;
/* then fall through to try second part */
ret
=
find_reserved_free_area
(
start
,
preload_reserve_start
,
size
,
top_down
,
align_mask
);
if
(
ret
)
return
ret
;
start
=
preload_reserve_end
;
}
}
if
((
alloc
->
result
=
find_reserved_free_area
(
start
,
end
,
alloc
->
size
,
alloc
->
top_down
,
alloc
->
align_mask
)))
return
1
;
return
find_reserved_free_area
(
start
,
end
,
size
,
top_down
,
align_mask
);
}
return
0
;
/***********************************************************************
* map_reserved_area
*
* Try to map some space inside a reserved area.
* virtual_mutex must be held by caller.
*/
static
void
*
map_reserved_area
(
void
*
limit_low
,
void
*
limit_high
,
size_t
size
,
int
top_down
,
int
unix_prot
,
size_t
align_mask
)
{
void
*
ptr
=
NULL
;
struct
reserved_area
*
area
=
LIST_ENTRY
(
ptr
,
struct
reserved_area
,
entry
);
if
(
top_down
)
{
LIST_FOR_EACH_ENTRY_REV
(
area
,
&
reserved_areas
,
struct
reserved_area
,
entry
)
{
void
*
start
=
area
->
base
;
void
*
end
=
(
char
*
)
start
+
area
->
size
;
if
(
start
>=
limit_high
)
continue
;
if
(
end
<=
limit_low
)
return
NULL
;
if
(
start
<
limit_low
)
start
=
limit_low
;
if
(
end
>
limit_high
)
end
=
limit_high
;
ptr
=
find_reserved_free_area_outside_preloader
(
start
,
end
,
size
,
top_down
,
align_mask
);
if
(
ptr
)
break
;
}
}
else
{
LIST_FOR_EACH_ENTRY
(
area
,
&
reserved_areas
,
struct
reserved_area
,
entry
)
{
void
*
start
=
area
->
base
;
void
*
end
=
(
char
*
)
start
+
area
->
size
;
if
(
start
>=
limit_high
)
return
NULL
;
if
(
end
<=
limit_low
)
continue
;
if
(
start
<
limit_low
)
start
=
limit_low
;
if
(
end
>
limit_high
)
end
=
limit_high
;
ptr
=
find_reserved_free_area_outside_preloader
(
start
,
end
,
size
,
top_down
,
align_mask
);
if
(
ptr
)
break
;
}
}
if
(
ptr
&&
anon_mmap_fixed
(
ptr
,
size
,
unix_prot
,
0
)
!=
ptr
)
ptr
=
NULL
;
return
ptr
;
}
/***********************************************************************
...
...
@@ -1966,30 +2002,24 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
}
else
{
struct
alloc_area
alloc
;
void
*
start
=
address_space_start
;
void
*
end
=
user_space_limit
;
size_t
view_size
,
unmap_size
;
if
(
!
align_mask
)
align_mask
=
granularity_mask
;
view_size
=
size
+
align_mask
+
1
;
alloc
.
size
=
size
;
alloc
.
top_down
=
top_down
;
alloc
.
limit
=
limit
?
min
(
(
void
*
)(
limit
+
1
),
user_space_limit
)
:
user_space_limit
;
alloc
.
align_mask
=
align_mask
;
if
(
limit
&&
(
void
*
)
limit
<
end
)
end
=
(
char
*
)
limit
+
1
;
if
(
mmap_enum_reserved_areas
(
alloc_reserved_area_callback
,
&
alloc
,
top_down
))
if
(
(
ptr
=
map_reserved_area
(
start
,
end
,
size
,
top_down
,
get_unix_prot
(
vprot
),
align_mask
)
))
{
ptr
=
alloc
.
result
;
TRACE
(
"got mem in reserved area %p-%p
\n
"
,
ptr
,
(
char
*
)
ptr
+
size
);
if
(
anon_mmap_fixed
(
ptr
,
size
,
get_unix_prot
(
vprot
),
0
)
!=
ptr
)
return
STATUS_INVALID_PARAMETER
;
goto
done
;
}
if
(
limit
)
{
if
(
!
(
ptr
=
map_free_area
(
address_space_start
,
alloc
.
limit
,
size
,
top_down
,
get_unix_prot
(
vprot
),
align_mask
)))
if
(
!
(
ptr
=
map_free_area
(
start
,
end
,
size
,
top_down
,
get_unix_prot
(
vprot
),
align_mask
)))
return
STATUS_NO_MEMORY
;
TRACE
(
"got mem with map_free_area %p-%p
\n
"
,
ptr
,
(
char
*
)
ptr
+
size
);
goto
done
;
...
...
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