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
aaa654ab
Commit
aaa654ab
authored
May 17, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Store reserved areas in the Unix library.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
62520943
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
151 additions
and
17 deletions
+151
-17
loader.c
dlls/ntdll/unix/loader.c
+8
-0
virtual.c
dlls/ntdll/unix/virtual.c
+143
-17
No files found.
dlls/ntdll/unix/loader.c
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
;
}
...
...
dlls/ntdll/unix/virtual.c
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
)
...
...
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