Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
James Carthew
wine
Commits
aaa654ab
Commit
aaa654ab
authored
4 years ago
by
Alexandre Julliard
Browse files
Options
Downloads
Patches
Plain Diff
ntdll: Store reserved areas in the Unix library.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
62520943
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
dlls/ntdll/unix/loader.c
+8
-0
8 additions, 0 deletions
dlls/ntdll/unix/loader.c
dlls/ntdll/unix/virtual.c
+143
-17
143 additions, 17 deletions
dlls/ntdll/unix/virtual.c
with
151 additions
and
17 deletions
dlls/ntdll/unix/loader.c
+
8
−
0
View file @
aaa654ab
...
...
@@ -528,6 +528,13 @@ void __wine_main( int argc, char *argv[], char *envp[] )
__wine_set_unix_funcs
(
NTDLL_UNIXLIB_VERSION
,
&
unix_funcs
);
}
static
int
add_area
(
void
*
base
,
size_t
size
,
void
*
arg
)
{
mmap_add_reserved_area
(
base
,
size
);
return
0
;
}
/***********************************************************************
* __wine_init_unix_lib
*
...
...
@@ -540,6 +547,7 @@ NTSTATUS __cdecl __wine_init_unix_lib( HMODULE module, const void *ptr_in, void
map_so_dll
(
nt
,
module
);
fixup_ntdll_imports
(
&
__wine_spec_nt_header
,
module
);
*
(
struct
unix_funcs
**
)
ptr_out
=
&
unix_funcs
;
wine_mmap_enum_reserved_areas
(
add_area
,
NULL
,
0
);
return
STATUS_SUCCESS
;
}
...
...
This diff is collapsed.
Click to expand it.
dlls/ntdll/unix/virtual.c
+
143
−
17
View file @
aaa654ab
...
...
@@ -45,7 +45,7 @@
#include
"winnt.h"
#include
"winternl.h"
#include
"unix_private.h"
#include
"wine/li
brary
.h"
#include
"wine/li
st
.h"
struct
preload_info
{
...
...
@@ -53,6 +53,15 @@ struct preload_info
size_t
size
;
};
struct
reserved_area
{
struct
list
entry
;
void
*
base
;
size_t
size
;
};
static
struct
list
reserved_areas
=
LIST_INIT
(
reserved_areas
);
static
const
unsigned
int
granularity_mask
=
0xffff
;
/* reserved areas have 64k granularity */
extern
IMAGE_NT_HEADERS
__wine_spec_nt_header
;
...
...
@@ -202,36 +211,153 @@ static void mmap_init( const struct preload_info *preload_info )
void
CDECL
mmap_add_reserved_area
(
void
*
addr
,
SIZE_T
size
)
{
wine_mmap_add_reserved_area
(
addr
,
size
);
struct
reserved_area
*
area
;
struct
list
*
ptr
;
if
(
!
((
char
*
)
addr
+
size
))
size
--
;
/* avoid wrap-around */
LIST_FOR_EACH
(
ptr
,
&
reserved_areas
)
{
area
=
LIST_ENTRY
(
ptr
,
struct
reserved_area
,
entry
);
if
(
area
->
base
>
addr
)
{
/* try to merge with the next one */
if
((
char
*
)
addr
+
size
==
(
char
*
)
area
->
base
)
{
area
->
base
=
addr
;
area
->
size
+=
size
;
return
;
}
break
;
}
else
if
((
char
*
)
area
->
base
+
area
->
size
==
(
char
*
)
addr
)
{
/* merge with the previous one */
area
->
size
+=
size
;
/* try to merge with the next one too */
if
((
ptr
=
list_next
(
&
reserved_areas
,
ptr
)))
{
struct
reserved_area
*
next
=
LIST_ENTRY
(
ptr
,
struct
reserved_area
,
entry
);
if
((
char
*
)
addr
+
size
==
(
char
*
)
next
->
base
)
{
area
->
size
+=
next
->
size
;
list_remove
(
&
next
->
entry
);
free
(
next
);
}
}
return
;
}
}
if
((
area
=
malloc
(
sizeof
(
*
area
)
)))
{
area
->
base
=
addr
;
area
->
size
=
size
;
list_add_before
(
ptr
,
&
area
->
entry
);
}
}
void
CDECL
mmap_remove_reserved_area
(
void
*
addr
,
SIZE_T
size
)
{
wine_mmap_remove_reserved_area
(
addr
,
size
,
0
)
;
}
struct
reserved_area
*
area
;
struct
list
*
ptr
;
int
CDECL
mmap_is_in_reserved_area
(
void
*
addr
,
SIZE_T
size
)
{
return
wine_mmap_is_in_reserved_area
(
addr
,
size
);
if
(
!
((
char
*
)
addr
+
size
))
size
--
;
/* avoid wrap-around */
ptr
=
list_head
(
&
reserved_areas
);
/* find the first area covering address */
while
(
ptr
)
{
area
=
LIST_ENTRY
(
ptr
,
struct
reserved_area
,
entry
);
if
((
char
*
)
area
->
base
>=
(
char
*
)
addr
+
size
)
break
;
/* outside the range */
if
((
char
*
)
area
->
base
+
area
->
size
>
(
char
*
)
addr
)
/* overlaps range */
{
if
(
area
->
base
>=
addr
)
{
if
((
char
*
)
area
->
base
+
area
->
size
>
(
char
*
)
addr
+
size
)
{
/* range overlaps beginning of area only -> shrink area */
area
->
size
-=
(
char
*
)
addr
+
size
-
(
char
*
)
area
->
base
;
area
->
base
=
(
char
*
)
addr
+
size
;
break
;
}
else
{
/* range contains the whole area -> remove area completely */
ptr
=
list_next
(
&
reserved_areas
,
ptr
);
list_remove
(
&
area
->
entry
);
free
(
area
);
continue
;
}
}
else
{
if
((
char
*
)
area
->
base
+
area
->
size
>
(
char
*
)
addr
+
size
)
{
/* range is in the middle of area -> split area in two */
struct
reserved_area
*
new_area
=
malloc
(
sizeof
(
*
new_area
)
);
if
(
new_area
)
{
new_area
->
base
=
(
char
*
)
addr
+
size
;
new_area
->
size
=
(
char
*
)
area
->
base
+
area
->
size
-
(
char
*
)
new_area
->
base
;
list_add_after
(
ptr
,
&
new_area
->
entry
);
}
else
size
=
(
char
*
)
area
->
base
+
area
->
size
-
(
char
*
)
addr
;
area
->
size
=
(
char
*
)
addr
-
(
char
*
)
area
->
base
;
break
;
}
else
{
/* range overlaps end of area only -> shrink area */
area
->
size
=
(
char
*
)
addr
-
(
char
*
)
area
->
base
;
}
}
}
ptr
=
list_next
(
&
reserved_areas
,
ptr
);
}
}
struct
enum_data
int
CDECL
mmap_is_in_reserved_area
(
void
*
addr
,
SIZE_T
size
)
{
int
(
CDECL
*
enum_func
)(
void
*
base
,
SIZE_T
size
,
void
*
arg
);
void
*
arg
;
};
struct
reserved_area
*
area
;
struct
list
*
ptr
;
static
int
enum_wrapper
(
void
*
base
,
size_t
size
,
void
*
arg
)
{
struct
enum_data
*
data
=
arg
;
return
data
->
enum_func
(
base
,
size
,
data
->
arg
);
LIST_FOR_EACH
(
ptr
,
&
reserved_areas
)
{
area
=
LIST_ENTRY
(
ptr
,
struct
reserved_area
,
entry
);
if
(
area
->
base
>
addr
)
break
;
if
((
char
*
)
area
->
base
+
area
->
size
<=
(
char
*
)
addr
)
continue
;
/* area must contain block completely */
if
((
char
*
)
area
->
base
+
area
->
size
<
(
char
*
)
addr
+
size
)
return
-
1
;
return
1
;
}
return
0
;
}
int
CDECL
mmap_enum_reserved_areas
(
int
(
CDECL
*
enum_func
)(
void
*
base
,
SIZE_T
size
,
void
*
arg
),
void
*
arg
,
int
top_down
)
{
struct
enum_data
data
=
{
enum_func
,
arg
};
return
wine_mmap_enum_reserved_areas
(
enum_wrapper
,
&
data
,
top_down
);
int
ret
=
0
;
struct
list
*
ptr
;
if
(
top_down
)
{
for
(
ptr
=
reserved_areas
.
prev
;
ptr
!=
&
reserved_areas
;
ptr
=
ptr
->
prev
)
{
struct
reserved_area
*
area
=
LIST_ENTRY
(
ptr
,
struct
reserved_area
,
entry
);
if
((
ret
=
enum_func
(
area
->
base
,
area
->
size
,
arg
)))
break
;
}
}
else
{
for
(
ptr
=
reserved_areas
.
next
;
ptr
!=
&
reserved_areas
;
ptr
=
ptr
->
next
)
{
struct
reserved_area
*
area
=
LIST_ENTRY
(
ptr
,
struct
reserved_area
,
entry
);
if
((
ret
=
enum_func
(
area
->
base
,
area
->
size
,
arg
)))
break
;
}
}
return
ret
;
}
void
virtual_init
(
void
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment