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
c722353c
Commit
c722353c
authored
May 09, 2023
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Support the ARM64EC code map.
parent
0a3a1d2b
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
97 additions
and
4 deletions
+97
-4
env.c
dlls/ntdll/unix/env.c
+10
-2
unix_private.h
dlls/ntdll/unix/unix_private.h
+1
-0
virtual.c
dlls/ntdll/unix/virtual.c
+85
-1
winternl.h
include/winternl.h
+1
-1
No files found.
dlls/ntdll/unix/env.c
View file @
c722353c
...
...
@@ -1857,13 +1857,21 @@ static void init_peb( RTL_USER_PROCESS_PARAMETERS *params, void *module )
peb
->
ImageSubSystemMinorVersion
=
main_image_info
.
MinorSubsystemVersion
;
#ifdef _WIN64
if
(
main_image_info
.
Machine
!=
current_m
achine
)
switch
(
main_image_info
.
M
achine
)
{
case
IMAGE_FILE_MACHINE_I386
:
case
IMAGE_FILE_MACHINE_ARMNT
:
NtCurrentTeb
()
->
WowTebOffset
=
teb_offset
;
NtCurrentTeb
()
->
Tib
.
ExceptionList
=
(
void
*
)((
char
*
)
NtCurrentTeb
()
+
teb_offset
);
wow_peb
=
(
PEB32
*
)((
char
*
)
peb
+
page_size
);
set_thread_id
(
NtCurrentTeb
(),
GetCurrentProcessId
(),
GetCurrentThreadId
()
);
set_thread_id
(
NtCurrentTeb
(),
GetCurrentProcessId
(),
GetCurrentThreadId
()
);
ERR
(
"starting %s in experimental wow64 mode
\n
"
,
debugstr_us
(
&
params
->
ImagePathName
)
);
break
;
case
IMAGE_FILE_MACHINE_AMD64
:
if
(
main_image_info
.
Machine
==
current_machine
)
break
;
peb
->
EcCodeBitMap
=
virtual_alloc_arm64ec_map
();
ERR
(
"starting %s in experimental ARM64EC mode
\n
"
,
debugstr_us
(
&
params
->
ImagePathName
)
);
break
;
}
#endif
...
...
dlls/ntdll/unix/unix_private.h
View file @
c722353c
...
...
@@ -234,6 +234,7 @@ extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN;
extern
NTSTATUS
virtual_clear_tls_index
(
ULONG
index
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
virtual_alloc_thread_stack
(
INITIAL_TEB
*
stack
,
ULONG_PTR
zero_bits
,
SIZE_T
reserve_size
,
SIZE_T
commit_size
,
BOOL
guard_page
)
DECLSPEC_HIDDEN
;
extern
void
*
virtual_alloc_arm64ec_map
(
void
)
DECLSPEC_HIDDEN
;
extern
void
virtual_map_user_shared_data
(
void
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
virtual_handle_fault
(
void
*
addr
,
DWORD
err
,
void
*
stack
)
DECLSPEC_HIDDEN
;
extern
unsigned
int
virtual_locked_server_call
(
void
*
req_ptr
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/unix/virtual.c
View file @
c722353c
...
...
@@ -175,6 +175,8 @@ static void *user_space_limit = (void *)0x7fff0000;
static
void
*
working_set_limit
=
(
void
*
)
0x7fff0000
;
#endif
static
UINT64
*
arm64ec_map
;
struct
_KUSER_SHARED_DATA
*
user_shared_data
=
(
void
*
)
0x7ffe0000
;
/* TEB allocation blocks */
...
...
@@ -998,6 +1000,52 @@ static BOOL alloc_pages_vprot( const void *addr, size_t size )
}
static
inline
UINT64
maskbits
(
size_t
idx
)
{
return
~
(
UINT64
)
0
<<
(
idx
&
63
);
}
/***********************************************************************
* set_arm64ec_range
*/
#ifdef __aarch64__
static
void
set_arm64ec_range
(
const
void
*
addr
,
size_t
size
)
{
size_t
idx
=
(
size_t
)
addr
>>
page_shift
;
size_t
end
=
((
size_t
)
addr
+
size
+
page_mask
)
>>
page_shift
;
size_t
pos
=
idx
/
64
;
size_t
end_pos
=
end
/
64
;
if
(
end_pos
>
pos
)
{
arm64ec_map
[
pos
++
]
|=
maskbits
(
idx
);
while
(
pos
<
end_pos
)
arm64ec_map
[
pos
++
]
=
~
(
UINT64
)
0
;
if
(
end
&
63
)
arm64ec_map
[
pos
]
|=
~
maskbits
(
end
);
}
else
arm64ec_map
[
pos
]
|=
maskbits
(
idx
)
&
~
maskbits
(
end
);
}
#endif
/***********************************************************************
* clear_arm64ec_range
*/
static
void
clear_arm64ec_range
(
const
void
*
addr
,
size_t
size
)
{
size_t
idx
=
(
size_t
)
addr
>>
page_shift
;
size_t
end
=
((
size_t
)
addr
+
size
+
page_mask
)
>>
page_shift
;
size_t
pos
=
idx
/
64
;
size_t
end_pos
=
end
/
64
;
if
(
end_pos
>
pos
)
{
arm64ec_map
[
pos
++
]
&=
~
maskbits
(
idx
);
while
(
pos
<
end_pos
)
arm64ec_map
[
pos
++
]
=
0
;
if
(
end
&
63
)
arm64ec_map
[
pos
]
&=
maskbits
(
end
);
}
else
arm64ec_map
[
pos
]
&=
~
maskbits
(
idx
)
|
maskbits
(
end
);
}
/***********************************************************************
* compare_view
*
...
...
@@ -1526,6 +1574,7 @@ static void delete_view( struct file_view *view ) /* [in] View */
{
if
(
!
(
view
->
protect
&
VPROT_SYSTEM
))
unmap_area
(
view
->
base
,
view
->
size
);
set_page_vprot
(
view
->
base
,
view
->
size
,
0
);
if
(
arm64ec_map
)
clear_arm64ec_range
(
view
->
base
,
view
->
size
);
if
(
mmap_is_in_reserved_area
(
view
->
base
,
view
->
size
))
free_ranges_remove_view
(
view
);
wine_rb_remove
(
&
views_tree
,
&
view
->
entry
);
...
...
@@ -2225,9 +2274,10 @@ static void apply_arm64x_relocations( char *base, const IMAGE_BASE_RELOCATION *r
*/
static
void
update_arm64x_mapping
(
char
*
base
,
IMAGE_NT_HEADERS
*
nt
,
IMAGE_SECTION_HEADER
*
sections
)
{
ULONG
size
,
sec
,
offset
;
ULONG
i
,
size
,
sec
,
offset
;
const
IMAGE_DATA_DIRECTORY
*
dir
;
const
IMAGE_LOAD_CONFIG_DIRECTORY
*
cfg
;
const
IMAGE_ARM64EC_METADATA
*
metadata
;
const
IMAGE_DYNAMIC_RELOCATION_TABLE
*
table
;
const
char
*
ptr
,
*
end
;
...
...
@@ -2239,6 +2289,21 @@ static void update_arm64x_mapping( char *base, IMAGE_NT_HEADERS *nt, IMAGE_SECTI
cfg
=
(
void
*
)(
base
+
dir
->
VirtualAddress
);
size
=
min
(
dir
->
Size
,
cfg
->
Size
);
/* update code ranges */
if
(
size
<=
offsetof
(
IMAGE_LOAD_CONFIG_DIRECTORY
,
CHPEMetadataPointer
))
return
;
metadata
=
(
void
*
)(
base
+
(
cfg
->
CHPEMetadataPointer
-
nt
->
OptionalHeader
.
ImageBase
));
if
(
metadata
->
CodeMap
&&
arm64ec_map
)
{
const
IMAGE_CHPE_RANGE_ENTRY
*
map
=
(
void
*
)(
base
+
metadata
->
CodeMap
);
for
(
i
=
0
;
i
<
metadata
->
CodeMapCount
;
i
++
)
{
if
((
map
[
i
].
StartOffset
&
0x3
)
!=
1
/* arm64ec */
)
continue
;
set_arm64ec_range
(
base
+
(
map
[
i
].
StartOffset
&
~
3
),
map
[
i
].
Length
);
}
}
/* apply dynamic relocations */
if
(
size
<=
offsetof
(
IMAGE_LOAD_CONFIG_DIRECTORY
,
DynamicValueRelocTableSection
))
return
;
...
...
@@ -3265,6 +3330,25 @@ done:
/***********************************************************************
* virtual_alloc_arm64ec_map
*/
void
*
virtual_alloc_arm64ec_map
(
void
)
{
#ifdef __aarch64__
SIZE_T
size
=
((
ULONG_PTR
)
user_space_limit
+
page_size
)
>>
(
page_shift
+
3
);
/* one bit per page */
unsigned
int
status
=
NtAllocateVirtualMemory
(
NtCurrentProcess
(),
(
void
**
)
&
arm64ec_map
,
0
,
&
size
,
MEM_COMMIT
,
PAGE_READWRITE
);
if
(
status
)
{
ERR
(
"failed to allocate ARM64EC map: %08x
\n
"
,
status
);
exit
(
1
);
}
#endif
return
arm64ec_map
;
}
/***********************************************************************
* virtual_map_user_shared_data
*/
void
virtual_map_user_shared_data
(
void
)
...
...
include/winternl.h
View file @
c722353c
...
...
@@ -394,7 +394,7 @@ typedef struct _PEB
ULONG
FlsHighIndex
;
/* 22c/350 */
PVOID
WerRegistrationData
;
/* 230/358 */
PVOID
WerShipAssertPtr
;
/* 234/360 */
PVOID
pUnused
;
/* 238/368 */
PVOID
EcCodeBitMap
;
/* 238/368 */
PVOID
pImageHeaderHash
;
/* 23c/370 */
ULONG
HeapTracingEnabled
:
1
;
/* 240/378 */
ULONG
CritSecTracingEnabled
:
1
;
...
...
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