Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
439ce3a3
Commit
439ce3a3
authored
Nov 09, 2023
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rpcrt4: Generate stubless thunks at compile time.
parent
533823ed
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
134 additions
and
116 deletions
+134
-116
cproxy.c
dlls/rpcrt4/cproxy.c
+33
-116
cpsf.h
dlls/rpcrt4/cpsf.h
+101
-0
No files found.
dlls/rpcrt4/cproxy.c
View file @
439ce3a3
...
...
@@ -82,23 +82,13 @@ __ASM_GLOBAL_FUNC(call_stubless_func,
"addl %edx,%esp
\n\t
"
"jmp *%ecx"
);
#include "pshpack1.h"
struct
thunk
{
BYTE
mov_eax
;
DWORD
index
;
BYTE
jmp
;
LONG
handler
;
};
#include "poppack.h"
static
inline
void
init_thunk
(
struct
thunk
*
thunk
,
unsigned
int
index
)
{
thunk
->
mov_eax
=
0xb8
;
/* movl $n,%eax */
thunk
->
index
=
index
;
thunk
->
jmp
=
0xe9
;
/* jmp */
thunk
->
handler
=
(
char
*
)
call_stubless_func
-
(
char
*
)(
&
thunk
->
handler
+
1
);
}
#define THUNK_ENTRY_SIZE 12
#define THUNK_ENTRY(num) \
".balign 4\n\t" \
"movl $("#num"),%eax\n\t" \
".byte 0xe9\n\t"
/* jmp */
\
".long " __ASM_NAME("call_stubless_func") "-1f\n" \
"1:\n\t"
#elif defined(__x86_64__)
...
...
@@ -128,30 +118,13 @@ __ASM_GLOBAL_FUNC(call_stubless_func,
__ASM_CFI
(
".cfi_adjust_cfa_offset -0x38
\n\t
"
)
"ret"
);
#include "pshpack1.h"
struct
thunk
{
BYTE
mov_r10
[
3
];
DWORD
index
;
BYTE
mov_rax
[
2
];
void
*
call_stubless
;
BYTE
jmp_rax
[
2
];
};
#include "poppack.h"
static
const
struct
thunk
thunk_template
=
{
{
0x49
,
0xc7
,
0xc2
},
0
,
/* movq $index,%r10 */
{
0x48
,
0xb8
},
0
,
/* movq $call_stubless_func,%rax */
{
0xff
,
0xe0
}
/* jmp *%rax */
};
static
inline
void
init_thunk
(
struct
thunk
*
thunk
,
unsigned
int
index
)
{
*
thunk
=
thunk_template
;
thunk
->
index
=
index
;
thunk
->
call_stubless
=
call_stubless_func
;
}
#define THUNK_ENTRY_SIZE 12
#define THUNK_ENTRY(num) \
".balign 4\n\t" \
"movl $("#num"),%r10d\n\t" \
".byte 0xe9\n\t"
/* jmp */
\
".long " __ASM_NAME("call_stubless_func") "-1f\n" \
"1:\n\t"
#elif defined(__arm__)
...
...
@@ -180,21 +153,11 @@ __ASM_GLOBAL_FUNC(call_stubless_func,
"add sp, #16
\n\t
"
"bx lr"
);
struct
thunk
{
DWORD
ldr_ip
;
/* ldr ip,[pc] */
DWORD
ldr_pc
;
/* ldr pc,[pc] */
DWORD
index
;
void
*
func
;
};
static
inline
void
init_thunk
(
struct
thunk
*
thunk
,
unsigned
int
index
)
{
thunk
->
ldr_ip
=
0xe59fc000
;
/* ldr ip,[pc] */
thunk
->
ldr_pc
=
0xe59ff000
;
/* ldr pc,[pc] */
thunk
->
index
=
index
*
sizeof
(
unsigned
short
);
thunk
->
func
=
call_stubless_func
;
}
#define THUNK_ENTRY_SIZE 12
#define THUNK_ENTRY(num) \
"ldr ip,1f\n\t" \
"b.w " __ASM_NAME("call_stubless_func") "\n" \
"1:\t.long "#num"\n\t"
#elif defined(__aarch64__)
...
...
@@ -225,83 +188,37 @@ __ASM_GLOBAL_FUNC( call_stubless_func,
"ldp x29, x30, [sp], #0x90
\n\t
"
"ret"
)
struct
thunk
{
DWORD
ldr_index
;
/* ldr w16, index */
DWORD
ldr_func
;
/* ldr x17, func */
DWORD
br
;
/* br x17 */
DWORD
index
;
void
*
func
;
};
static
inline
void
init_thunk
(
struct
thunk
*
thunk
,
unsigned
int
index
)
{
thunk
->
ldr_index
=
0x18000070
;
/* ldr w16,index */
thunk
->
ldr_func
=
0x58000071
;
/* ldr x17,func */
thunk
->
br
=
0xd61f0220
;
/* br x17 */
thunk
->
index
=
index
;
thunk
->
func
=
call_stubless_func
;
}
#define THUNK_ENTRY_SIZE 8
#define THUNK_ENTRY(num) \
"mov w16,#("#num")\n\t" \
"b " __ASM_NAME("call_stubless_func") "\n\t"
#else
/* __i386__ */
#warning You must implement stubless proxies for your CPU
struct
thunk
{
DWORD
index
;
};
static
inline
void
init_thunk
(
struct
thunk
*
thunk
,
unsigned
int
index
)
{
thunk
->
index
=
index
;
}
#define THUNK_ENTRY_SIZE 0
#define THUNK_ENTRY(num) ""
#endif
/* __i386__ */
#define BLOCK_SIZE 1024
#define MAX_BLOCKS 64
/* 64k methods should be enough for anybody */
static
const
struct
thunk
*
method_blocks
[
MAX_BLOCKS
];
static
const
struct
thunk
*
allocate_block
(
unsigned
int
num
)
{
unsigned
int
i
;
struct
thunk
*
prev
,
*
block
;
DWORD
oldprot
;
block
=
VirtualAlloc
(
NULL
,
BLOCK_SIZE
*
sizeof
(
*
block
),
MEM_COMMIT
|
MEM_RESERVE
,
PAGE_EXECUTE_READWRITE
);
if
(
!
block
)
return
NULL
;
for
(
i
=
0
;
i
<
BLOCK_SIZE
;
i
++
)
init_thunk
(
&
block
[
i
],
BLOCK_SIZE
*
num
+
i
+
3
);
VirtualProtect
(
block
,
BLOCK_SIZE
*
sizeof
(
*
block
),
PAGE_EXECUTE_READ
,
&
oldprot
);
prev
=
InterlockedCompareExchangePointer
(
(
void
**
)
&
method_blocks
[
num
],
block
,
NULL
);
if
(
prev
)
/* someone beat us to it */
{
VirtualFree
(
block
,
0
,
MEM_RELEASE
);
block
=
prev
;
}
return
block
;
}
extern
void
stubless_thunks
(
void
);
__ASM_GLOBAL_FUNC
(
stubless_thunks
,
ALL_THUNK_ENTRIES
)
#undef THUNK_ENTRY
BOOL
fill_stubless_table
(
IUnknownVtbl
*
vtbl
,
DWORD
num
)
{
const
void
**
entry
=
(
const
void
**
)(
vtbl
+
1
);
DWORD
i
,
j
;
DWORD
i
;
if
(
num
-
3
>
BLOCK_SIZE
*
MAX_BLOCK
S
)
if
(
num
>=
NB_THUNK_ENTRIE
S
)
{
FIXME
(
"%lu methods not supported
\n
"
,
num
);
return
FALSE
;
}
for
(
i
=
0
;
i
<
(
num
-
3
+
BLOCK_SIZE
-
1
)
/
BLOCK_SIZE
;
i
++
)
{
const
struct
thunk
*
block
=
method_blocks
[
i
];
if
(
!
block
&&
!
(
block
=
allocate_block
(
i
)))
return
FALSE
;
for
(
j
=
0
;
j
<
BLOCK_SIZE
&&
j
<
num
-
3
-
i
*
BLOCK_SIZE
;
j
++
,
entry
++
)
if
(
*
entry
==
(
LPVOID
)
-
1
)
*
entry
=
&
block
[
j
];
}
for
(
i
=
0
;
i
<
num
-
3
;
i
++
,
entry
++
)
if
(
*
entry
==
(
void
*
)
-
1
)
*
entry
=
(
char
*
)
stubless_thunks
+
i
*
THUNK_ENTRY_SIZE
;
return
TRUE
;
}
...
...
dlls/rpcrt4/cpsf.h
View file @
439ce3a3
...
...
@@ -72,4 +72,105 @@ BOOL fill_stubless_table(IUnknownVtbl *vtbl, DWORD num) DECLSPEC_HIDDEN;
IUnknownVtbl
*
get_delegating_vtbl
(
DWORD
num_methods
)
DECLSPEC_HIDDEN
;
void
release_delegating_vtbl
(
IUnknownVtbl
*
vtbl
)
DECLSPEC_HIDDEN
;
#define THUNK_ENTRY_FIRST_BLOCK() \
THUNK_ENTRY(3) \
THUNK_ENTRY(4) \
THUNK_ENTRY(5) \
THUNK_ENTRY(6) \
THUNK_ENTRY(7) \
THUNK_ENTRY(8) \
THUNK_ENTRY(9) \
THUNK_ENTRY(10) \
THUNK_ENTRY(11) \
THUNK_ENTRY(12) \
THUNK_ENTRY(13) \
THUNK_ENTRY(14) \
THUNK_ENTRY(15) \
THUNK_ENTRY(16) \
THUNK_ENTRY(17) \
THUNK_ENTRY(18) \
THUNK_ENTRY(19) \
THUNK_ENTRY(20) \
THUNK_ENTRY(21) \
THUNK_ENTRY(22) \
THUNK_ENTRY(23) \
THUNK_ENTRY(24) \
THUNK_ENTRY(25) \
THUNK_ENTRY(26) \
THUNK_ENTRY(27) \
THUNK_ENTRY(28) \
THUNK_ENTRY(29) \
THUNK_ENTRY(30) \
THUNK_ENTRY(31)
#define THUNK_ENTRY_BLOCK(block) \
THUNK_ENTRY(32 * (block) + 0) \
THUNK_ENTRY(32 * (block) + 1) \
THUNK_ENTRY(32 * (block) + 2) \
THUNK_ENTRY(32 * (block) + 3) \
THUNK_ENTRY(32 * (block) + 4) \
THUNK_ENTRY(32 * (block) + 5) \
THUNK_ENTRY(32 * (block) + 6) \
THUNK_ENTRY(32 * (block) + 7) \
THUNK_ENTRY(32 * (block) + 8) \
THUNK_ENTRY(32 * (block) + 9) \
THUNK_ENTRY(32 * (block) + 10) \
THUNK_ENTRY(32 * (block) + 11) \
THUNK_ENTRY(32 * (block) + 12) \
THUNK_ENTRY(32 * (block) + 13) \
THUNK_ENTRY(32 * (block) + 14) \
THUNK_ENTRY(32 * (block) + 15) \
THUNK_ENTRY(32 * (block) + 16) \
THUNK_ENTRY(32 * (block) + 17) \
THUNK_ENTRY(32 * (block) + 18) \
THUNK_ENTRY(32 * (block) + 19) \
THUNK_ENTRY(32 * (block) + 20) \
THUNK_ENTRY(32 * (block) + 21) \
THUNK_ENTRY(32 * (block) + 22) \
THUNK_ENTRY(32 * (block) + 23) \
THUNK_ENTRY(32 * (block) + 24) \
THUNK_ENTRY(32 * (block) + 25) \
THUNK_ENTRY(32 * (block) + 26) \
THUNK_ENTRY(32 * (block) + 27) \
THUNK_ENTRY(32 * (block) + 28) \
THUNK_ENTRY(32 * (block) + 29) \
THUNK_ENTRY(32 * (block) + 30) \
THUNK_ENTRY(32 * (block) + 31)
#define ALL_THUNK_ENTRIES \
THUNK_ENTRY_FIRST_BLOCK() \
THUNK_ENTRY_BLOCK(1) \
THUNK_ENTRY_BLOCK(2) \
THUNK_ENTRY_BLOCK(3) \
THUNK_ENTRY_BLOCK(4) \
THUNK_ENTRY_BLOCK(5) \
THUNK_ENTRY_BLOCK(6) \
THUNK_ENTRY_BLOCK(7) \
THUNK_ENTRY_BLOCK(8) \
THUNK_ENTRY_BLOCK(9) \
THUNK_ENTRY_BLOCK(10) \
THUNK_ENTRY_BLOCK(11) \
THUNK_ENTRY_BLOCK(12) \
THUNK_ENTRY_BLOCK(13) \
THUNK_ENTRY_BLOCK(14) \
THUNK_ENTRY_BLOCK(15) \
THUNK_ENTRY_BLOCK(16) \
THUNK_ENTRY_BLOCK(17) \
THUNK_ENTRY_BLOCK(18) \
THUNK_ENTRY_BLOCK(19) \
THUNK_ENTRY_BLOCK(20) \
THUNK_ENTRY_BLOCK(21) \
THUNK_ENTRY_BLOCK(22) \
THUNK_ENTRY_BLOCK(23) \
THUNK_ENTRY_BLOCK(24) \
THUNK_ENTRY_BLOCK(25) \
THUNK_ENTRY_BLOCK(26) \
THUNK_ENTRY_BLOCK(27) \
THUNK_ENTRY_BLOCK(28) \
THUNK_ENTRY_BLOCK(29) \
THUNK_ENTRY_BLOCK(30) \
THUNK_ENTRY_BLOCK(31)
#define NB_THUNK_ENTRIES (32 * 32)
#endif
/* __WINE_CPSF_H */
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