[PATCH 3/4] ntdll: Add CFI expressions for __wine_syscall_dispatcher.
Jinoh Kang
jinoh.kang.kr at gmail.com
Wed Feb 9 07:29:18 CST 2022
On 2/8/22 04:05, Rémi Bernon wrote:
> Making sure stack pointer points to previous syscall / exit frame before
> entering a syscall, and restoring the PE frame information on return.
Would this unwind into the PE side?
I don't thunk libunwind would be able to handle SEH unwind infos; perhaps what we want to do instead is to unwind into exit_frame?
If what we indeed want is to unwind to PE, I have a much accurate (albeit ugly) version for the CFI expressions.
It supports:
- dual fxsave / xsave handling (the bulk of the complexity)
- can unwind from every point inside the syscall dispatcher
- works with GDB (attach to wine via normal GDB, and it will trace through the PE up to the initial frame)
---
dlls/ntdll/unix/inline_dwarf.h | 59 +++++++++
dlls/ntdll/unix/signal_i386.c | 213 +++++++++++++++++++++++++++++++--
2 files changed, 260 insertions(+), 12 deletions(-)
create mode 100644 dlls/ntdll/unix/inline_dwarf.h
diff --git a/dlls/ntdll/unix/inline_dwarf.h b/dlls/ntdll/unix/inline_dwarf.h
new file mode 100644
index 00000000000..0027164a9f3
--- /dev/null
+++ b/dlls/ntdll/unix/inline_dwarf.h
@@ -0,0 +1,59 @@
+#ifndef __WINE_INLINE_DWARF_H
+#define __WINE_INLINE_DWARF_H
+
+#define PP_ARG_64TH( \
+ _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
+ _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
+ _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
+ _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
+ _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
+ _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
+ _61, _62, _63, N, ...) N
+
+#define PP_NARG(...) PP_ARG_64TH(__VA_ARGS__, \
+ 63, 62, 61, 60, \
+ 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \
+ 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \
+ 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \
+ 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
+ 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
+ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+
+#define IDW_STRINGIFY_(...) #__VA_ARGS__
+#define IDW_STRINGIFY(...) IDW_STRINGIFY_(__VA_ARGS__)
+#define IDW_EXPAND(...) __VA_ARGS__
+
+#define I_DW_CFA_expression 0x10
+#define I_DW_CFA_val_expression 0x16
+
+#define I_DW_OP_deref 0x06
+#define I_DW_OP_const1u 0x08
+#define I_DW_OP_dup 0x12
+#define I_DW_OP_swap 0x16
+#define I_DW_OP_and 0x1a
+#define I_DW_OP_neg 0x1f
+#define I_DW_OP_not 0x20
+#define I_DW_OP_or 0x21
+#define I_DW_OP_plus 0x22
+#define I_DW_OP_plus_uconst 0x23
+#define I_DW_OP_bra 0x28
+#define I_DW_OP_eq 0x29
+#define I_DW_OP_lit0 0x30
+#define I_DW_OP_reg0 0x50
+#define I_DW_OP_deref_size 0x94
+#define I_DW_OP_call_frame_cfa 0x9c
+
+#define I_MAX_DW_OP_LITERAL 0x1f
+
+#define IDW_const1u(x) I_DW_OP_const1u, x
+
+#define I_DW_BLOCK(...) \
+ IDW_STRINGIFY(PP_NARG(__VA_ARGS__)) ", " IDW_STRINGIFY(__VA_ARGS__)
+
+#define I_DW_then_else(t, f) \
+ I_DW_OP_lit0, I_DW_OP_eq, I_DW_OP_neg, \
+ I_DW_OP_dup, IDW_EXPAND f, \
+ I_DW_OP_and, I_DW_OP_swap, I_DW_OP_not, IDW_EXPAND t, \
+ I_DW_OP_and, I_DW_OP_or
+
+#endif
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index 6bb5649e2b5..3bda41de0c6 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -2466,6 +2466,133 @@ __ASM_GLOBAL_FUNC( signal_exit_thread,
"pushl %eax\n\t"
"call *%ecx" )
+#define SYSCALL_FRAME_SYSCALL_FLAGS_OFFSET 0
+#define SYSCALL_FRAME_RESTORE_FLAGS_OFFSET 2
+#define I_SYSCALL_HAVE_FXSAVE_OR_LATER 7
+#define I_CONTEXT_INTEGER 2
+
+typedef char syscall_frame_syscall_flags_offset[(
+ offsetof(struct syscall_frame, syscall_flags) == SYSCALL_FRAME_SYSCALL_FLAGS_OFFSET ? 1 : -1
+)];
+typedef char syscall_frame_restore_flags_offset[(
+ offsetof(struct syscall_frame, restore_flags) == SYSCALL_FRAME_RESTORE_FLAGS_OFFSET
+)];
+typedef char syscall_have_fxsave_or_later[(
+ I_SYSCALL_HAVE_FXSAVE_OR_LATER == (SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC |
+ SYSCALL_HAVE_FXSAVE) ? 1 : -1
+)];
+typedef char i_context_integer[(CONTEXT_i386 | I_CONTEXT_INTEGER) == CONTEXT_INTEGER ? 1 : -1];
+
+#include "inline_dwarf.h"
+
+#if SYSCALL_FRAME_SYSCALL_FLAGS_OFFSET != 0
+#error please modify ASM_CFI_XSAVE_OR_FSAVE to add offset before dup
+#endif
+
+#if SYSCALL_FRAME_RESTORE_FLAGS_OFFSET <= 0x7f
+#define I_DW_OP_plus_off_restore_flags \
+ I_DW_OP_plus_uconst, SYSCALL_FRAME_RESTORE_FLAGS_OFFSET
+#else
+#error please define I_DW_OP_plus_off_restore_flags to hold syscall_frame::restore_flags offset
+#endif
+
+#if I_SYSCALL_HAVE_FXSAVE_OR_LATER <= I_MAX_DW_OP_LITERAL
+#define I_DW_OP_lit_SYSCALL_HAVE_FXSAVE_OR_LATER I_DW_OP_lit0 + I_SYSCALL_HAVE_FXSAVE_OR_LATER
+#else
+#error please define I_DW_OP_lit_SYSCALL_HAVE_FXSAVE_OR_LATER to hold I_SYSCALL_HAVE_FXSAVE_OR_LATER value
+#endif
+
+#if I_CONTEXT_INTEGER <= I_MAX_DW_OP_LITERAL
+#define I_DW_OP_lit_CONTEXT_INTEGER I_DW_OP_lit0 + I_CONTEXT_INTEGER
+#else
+#error please define I_DW_OP_lit_CONTEXT_INTEGER to hold I_CONTEXT_INTEGER value
+#endif
+
+#define ASM_CFI_XSAVE_OR_FSAVE(reg_seq, off_xsave, off_fsave) \
+ ".cfi_escape " IDW_STRINGIFY(I_DW_CFA_expression) ", " reg_seq ", " \
+ I_DW_BLOCK( \
+ I_DW_OP_dup, I_DW_OP_deref_size, 0x02, \
+ I_DW_OP_lit_SYSCALL_HAVE_FXSAVE_OR_LATER, I_DW_OP_and, \
+ I_DW_then_else((off_xsave), (off_fsave)), \
+ I_DW_OP_plus \
+ )
+
+#define ASM_CFI_SYSCALL_FRAME_FLTSAVE() \
+ ASM_CFI_XSAVE_OR_FSAVE("11" /* ST0 */, IDW_const1u(0x60), IDW_const1u(0x5c)) "\n\t" \
+ ASM_CFI_XSAVE_OR_FSAVE("12" /* ST1 */, IDW_const1u(0x70), IDW_const1u(0x66)) "\n\t" \
+ ASM_CFI_XSAVE_OR_FSAVE("13" /* ST2 */, IDW_const1u(0x80), IDW_const1u(0x70)) "\n\t" \
+ ASM_CFI_XSAVE_OR_FSAVE("14" /* ST3 */, IDW_const1u(0x90), IDW_const1u(0x7a)) "\n\t" \
+ ASM_CFI_XSAVE_OR_FSAVE("15" /* ST4 */, IDW_const1u(0xa0), IDW_const1u(0x84)) "\n\t" \
+ ASM_CFI_XSAVE_OR_FSAVE("16" /* ST5 */, IDW_const1u(0xb0), IDW_const1u(0x8e)) "\n\t" \
+ ASM_CFI_XSAVE_OR_FSAVE("17" /* ST6 */, IDW_const1u(0xc0), IDW_const1u(0x98)) "\n\t" \
+ ASM_CFI_XSAVE_OR_FSAVE("18" /* ST7 */, IDW_const1u(0xd0), IDW_const1u(0xa2)) "\n\t" \
+ ".cfi_offset %xmm0,0xe0\n\t" \
+ ".cfi_offset %xmm1,0xf0\n\t" \
+ ".cfi_offset %xmm2,0x100\n\t" \
+ ".cfi_offset %xmm3,0x110\n\t" \
+ ".cfi_offset %xmm4,0x120\n\t" \
+ ".cfi_offset %xmm5,0x130\n\t" \
+ ".cfi_offset %xmm6,0x140\n\t" \
+ ".cfi_offset %xmm7,0x150\n\t" \
+ ".cfi_offset 39,0x18" /* MXCSR */
+
+#define ASM_CFI_FLT_SAME_VALUE() \
+ ".cfi_same_value 11\n\t" /* ST0 */ \
+ ".cfi_same_value 12\n\t" /* ST1 */ \
+ ".cfi_same_value 13\n\t" /* ST2 */ \
+ ".cfi_same_value 14\n\t" /* ST3 */ \
+ ".cfi_same_value 15\n\t" /* ST4 */ \
+ ".cfi_same_value 16\n\t" /* ST5 */ \
+ ".cfi_same_value 17\n\t" /* ST6 */ \
+ ".cfi_same_value 18\n\t" /* ST7 */ \
+ ".cfi_same_value %xmm0\n\t" \
+ ".cfi_same_value %xmm1\n\t" \
+ ".cfi_same_value %xmm2\n\t" \
+ ".cfi_same_value %xmm3\n\t" \
+ ".cfi_same_value %xmm4\n\t" \
+ ".cfi_same_value %xmm5\n\t" \
+ ".cfi_same_value %xmm6\n\t" \
+ ".cfi_same_value %xmm7\n\t" \
+ ".cfi_same_value 39" /* MXCSR */
+
+#define SYSCALL_DISPATCHER_POSTPROLOG_CFI(basereg) \
+ ".cfi_signal_frame\n\t" \
+ ".cfi_def_cfa " basereg ",0\n\t" \
+ ".cfi_offset %eip,0x08\n\t" \
+ ".cfi_offset %eflags,0x04\n\t"
+
+#define SYSCALL_DISPATCHER_FOREACH_SAVE_REG(func, basereg) \
+ func(l, "%esp", 4, 0x0c, basereg) /* frame->esp */ \
+ func(w, "%cs" , 41, 0x10, basereg) \
+ func(w, "%ss" , 42, 0x12, basereg) \
+ func(w, "%ds" , 43, 0x14, basereg) \
+ func(w, "%es" , 40, 0x16, basereg) \
+ func(w, "%fs" , 44, 0x18, basereg) \
+ func(w, "%gs" , 45, 0x1a, basereg) \
+ func(l, "%eax", 0, 0x1c, basereg) \
+ func(l, "%ebx", 3, 0x20, basereg) \
+ func(l, "%edi", 7, 0x2c, basereg) \
+ func(l, "%esi", 6, 0x30, basereg) \
+ func(l, "%ebp", 5, 0x34, basereg) \
+
+#define SAVE_REG_CFI_l(reg, regno, off, basereg) \
+ __ASM_CFI(".cfi_offset " #regno "," #off "\n\t")
+
+#define SAVE_REG_CFI_w(reg, regno, off, basereg) \
+ __ASM_CFI(".cfi_escape " IDW_STRINGIFY(I_DW_CFA_val_expression) ", " #regno ", " \
+ I_DW_BLOCK(I_DW_OP_plus_uconst, off, I_DW_OP_deref_size, 0x02) "\n\t") \
+
+#define SAVE_REG_AND_CFI(prefix, reg, regno, off, basereg) \
+ "mov" #prefix " " reg "," #off "(" basereg ")\n\t" \
+ SAVE_REG_CFI_##prefix(reg, regno, off, basereg)
+
+#define SAVE_REG_CFI_ONLY(prefix, reg, regno, off, basereg) \
+ SAVE_REG_CFI_##prefix(reg, regno, off, basereg)
+
+#define SYSCALL_DISPATCHER_OTHER_START(basereg) \
+ __ASM_CFI(SYSCALL_DISPATCHER_POSTPROLOG_CFI(basereg)) \
+ SYSCALL_DISPATCHER_FOREACH_SAVE_REG(SAVE_REG_CFI_ONLY, basereg) \
+ __ASM_CFI(ASM_CFI_SYSCALL_FRAME_FLTSAVE())
/***********************************************************************
* __wine_syscall_dispatcher
@@ -2474,22 +2601,20 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
"movl %fs:0x1f8,%ecx\n\t" /* x86_thread_data()->syscall_frame */
"movw $0,0x02(%ecx)\n\t" /* frame->restore_flags */
"popl 0x08(%ecx)\n\t" /* frame->eip */
+ __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")
+ __ASM_CFI(".cfi_escape 0x10,0x08,0x02,0x71,0x08\n\t") /* eip, DW_op_breg1 + 0x08 */
"pushfl\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ __ASM_CFI(".cfi_rel_offset %eflags,0\n\t")
"popl 0x04(%ecx)\n" /* frame->eflags */
+ __ASM_CFI("\t.cfi_endproc\n")
__ASM_NAME("__wine_syscall_dispatcher_prolog_end") ":\n\t"
- "movl %esp,0x0c(%ecx)\n\t" /* frame->esp */
- "movw %cs,0x10(%ecx)\n\t"
- "movw %ss,0x12(%ecx)\n\t"
- "movw %ds,0x14(%ecx)\n\t"
- "movw %es,0x16(%ecx)\n\t"
- "movw %fs,0x18(%ecx)\n\t"
- "movw %gs,0x1a(%ecx)\n\t"
- "movl %eax,0x1c(%ecx)\n\t"
- "movl %ebx,0x20(%ecx)\n\t"
- "movl %edi,0x2c(%ecx)\n\t"
- "movl %esi,0x30(%ecx)\n\t"
- "movl %ebp,0x34(%ecx)\n\t"
+ __ASM_CFI(".cfi_startproc simple\n\t") /* don't emit default frame instructions */
+ __ASM_CFI(SYSCALL_DISPATCHER_POSTPROLOG_CFI("%ecx"))
+ __ASM_CFI(".cfi_same_value %esp\n\t")
+ SYSCALL_DISPATCHER_FOREACH_SAVE_REG(SAVE_REG_AND_CFI, "%ecx")
"leal 0x34(%ecx),%ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa %ebp, -0x34\n\t")
"leal 4(%esp),%esi\n\t" /* first argument */
"movl %eax,%ebx\n\t"
"shrl $8,%ebx\n\t"
@@ -2518,14 +2643,24 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
"movl %edx,0x278(%ecx)\n\t"
"movl %edx,0x27c(%ecx)\n\t"
"xsavec 0x40(%ecx)\n\t"
+ __ASM_CFI(ASM_CFI_SYSCALL_FRAME_FLTSAVE() "\n\t")
"jmp 4f\n"
+ __ASM_CFI("\t.cfi_remember_state\n")
+ __ASM_CFI("\t" ASM_CFI_FLT_SAME_VALUE() "\n")
"1:\txsave 0x40(%ecx)\n\t"
+ __ASM_CFI(".cfi_restore_state\n\t")
"jmp 4f\n"
+ __ASM_CFI("\t.cfi_remember_state\n")
+ __ASM_CFI("\t" ASM_CFI_FLT_SAME_VALUE() "\n")
"2:\ttestl $4,(%ecx)\n\t" /* frame->syscall_flags & SYSCALL_HAVE_FXSAVE */
"jz 3f\n\t"
"fxsave 0x40(%ecx)\n\t"
+ __ASM_CFI(".cfi_restore_state\n\t")
"jmp 4f\n"
+ __ASM_CFI("\t.cfi_remember_state\n")
+ __ASM_CFI("\t" ASM_CFI_FLT_SAME_VALUE() "\n")
"3:\tfnsave 0x40(%ecx)\n\t"
+ __ASM_CFI(".cfi_restore_state\n\t")
"fwait\n"
"4:\tmovl %ecx,%esp\n\t"
"movl 0x1c(%esp),%edx\n\t" /* frame->eax */
@@ -2543,6 +2678,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
"rep; movsl\n\t"
"call *(%eax,%edx,4)\n\t"
"leal -0x34(%ebp),%esp\n"
+ __ASM_CFI("\t.cfi_def_cfa %esp, 0\n")
"5:\tmovl 0(%esp),%ecx\n\t" /* frame->syscall_flags + (frame->restore_flags << 16) */
"testl $0x68 << 16,%ecx\n\t" /* CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS | CONTEXT_XSAVE */
"jz 3f\n\t"
@@ -2552,46 +2688,99 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
"movl $7,%eax\n\t"
"xorl %edx,%edx\n\t"
"xrstor 0x40(%esp)\n\t"
+ __ASM_CFI(".cfi_remember_state\n\t")
+ __ASM_CFI(ASM_CFI_FLT_SAME_VALUE() "\n\t")
"movl %esi,%eax\n\t"
"jmp 3f\n"
+ __ASM_CFI("\t.cfi_restore_state\n")
"1:\ttestl $4,%ecx\n\t" /* SYSCALL_HAVE_FXSAVE */
"jz 2f\n\t"
"fxrstor 0x40(%esp)\n\t"
+ __ASM_CFI(".cfi_remember_state\n\t")
+ __ASM_CFI(ASM_CFI_FLT_SAME_VALUE() "\n\t")
"jmp 3f\n"
+ __ASM_CFI("\t.cfi_restore_state\n")
"2:\tfrstor 0x40(%esp)\n\t"
+ __ASM_CFI(ASM_CFI_FLT_SAME_VALUE() "\n\t")
"fwait\n"
"3:\tmovl 0x2c(%esp),%edi\n\t"
+ __ASM_CFI(".cfi_same_value %edi\n\t")
"movl 0x30(%esp),%esi\n\t"
+ __ASM_CFI(".cfi_same_value %esi\n\t")
"movl 0x34(%esp),%ebp\n\t"
+ __ASM_CFI(".cfi_same_value %ebp\n\t")
"testl $0x7 << 16,%ecx\n\t" /* CONTEXT_CONTROL | CONTEXT_SEGMENTS | CONTEXT_INTEGER */
"jnz 1f\n\t"
"movl 0x20(%esp),%ebx\n\t"
+ __ASM_CFI(".cfi_remember_state\n\t")
+ __ASM_CFI(".cfi_same_value %ebx\n\t")
"movl 0x08(%esp),%ecx\n\t" /* frame->eip */
+ __ASM_CFI(".cfi_register %eip, %ecx\n\t")
"movl 0x0c(%esp),%esp\n\t" /* frame->esp */
+ __ASM_CFI(".cfi_same_value %esp\n\t")
"jmpl *%ecx\n"
+ __ASM_CFI("\t.cfi_restore_state\n")
"1:\ttestl $0x2 << 16,%ecx\n\t" /* CONTEXT_INTEGER */
"jz 1f\n\t"
"movl 0x1c(%esp),%eax\n\t"
+ __ASM_CFI(".cfi_same_value %eax\n\t")
"movl 0x24(%esp),%ecx\n\t"
+ __ASM_CFI(".cfi_same_value %ecx\n\t")
"movl 0x28(%esp),%edx\n"
+ __ASM_CFI("\t.cfi_same_value %edx\n")
"1:\tmovl 0x0c(%esp),%ebx\n\t" /* frame->esp */
+ __ASM_CFI(".cfi_register %esp, %ebx\n\t")
"movw 0x12(%esp),%ss\n\t"
+ __ASM_CFI(".cfi_same_value %ss\n\t")
"xchgl %ebx,%esp\n\t"
+ __ASM_CFI(".cfi_endproc\n\t")
+ __ASM_CFI(".cfi_startproc simple\n\t")
+ __ASM_CFI(".cfi_def_cfa %esp,0\n\t")
+ __ASM_CFI(".cfi_escape 0x10,0x09,0x02,0x71,0x04\n\t") /* eflags, DW_op_breg1 + 0x04 */
+ __ASM_CFI(".cfi_escape 0x10,0x29,0x02,0x71,0x10\n\t") /* cs, DW_op_breg1 + 0x10 */
+ __ASM_CFI(".cfi_escape 0x10,0x08,0x02,0x71,0x08\n\t") /* eip, DW_op_breg1 + 0x08 */
+ __ASM_CFI(".cfi_escape 0x10,0x2b,0x02,0x71,0x14\n\t") /* ds, DW_op_breg1 + 0x14 */
+ __ASM_CFI(".cfi_escape 0x10,0x28,0x02,0x71,0x16\n\t") /* es, DW_op_breg1 + 0x16 */
+ __ASM_CFI(".cfi_escape 0x10,0x2c,0x02,0x71,0x18\n\t") /* fs, DW_op_breg1 + 0x18 */
+ __ASM_CFI(".cfi_escape 0x10,0x2d,0x02,0x71,0x1a\n\t") /* gs, DW_op_breg1 + 0x1a */
+ __ASM_CFI(".cfi_escape 0x10,0x03,0x02,0x71,0x20\n\t") /* ebx, DW_op_breg1 + 0x20 */
"pushl 0x04(%ebx)\n\t" /* frame->eflags */
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ __ASM_CFI(".cfi_rel_offset %eflags, 0\n\t")
"pushl 0x10(%ebx)\n\t" /* frame->cs */
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ __ASM_CFI(".cfi_rel_offset %cs, 0\n\t")
"pushl 0x08(%ebx)\n\t" /* frame->eip */
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ __ASM_CFI(".cfi_rel_offset %eip, 0\n\t")
"pushl 0x14(%ebx)\n\t" /* frame->ds */
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ __ASM_CFI(".cfi_rel_offset %ds, 0\n\t")
"movw 0x16(%ebx),%es\n\t"
+ __ASM_CFI(".cfi_same_value %es\n\t")
"movw 0x18(%ebx),%fs\n\t"
+ __ASM_CFI(".cfi_same_value %fs\n\t")
"movw 0x1a(%ebx),%gs\n\t"
+ __ASM_CFI(".cfi_same_value %gs\n\t")
"movl 0x20(%ebx),%ebx\n\t"
+ __ASM_CFI(".cfi_same_value %ebx\n\t")
"popl %ds\n\t"
+ __ASM_CFI(".cfi_same_value %ds\n\t")
+ __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")
"iret\n"
+ __ASM_CFI("\t.cfi_endproc\n")
+ __ASM_CFI("\t.cfi_startproc simple\n")
+ "\t" SYSCALL_DISPATCHER_OTHER_START("%esp") "\n"
"6:\tmovl $0xc000000d,%eax\n\t" /* STATUS_INVALID_PARAMETER */
"jmp 5b\n"
+ __ASM_CFI("\t.cfi_endproc\n")
__ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t"
+ __ASM_CFI(".cfi_startproc\n\t")
"movl 8(%esp),%eax\n\t"
"movl 4(%esp),%esp\n\t"
+ __ASM_CFI(".cfi_endproc\n\t")
+ __ASM_CFI(".cfi_startproc simple\n\t")
+ SYSCALL_DISPATCHER_OTHER_START("%esp") "\n\t"
"jmp 5b" )
--
2.34.1
--
Sincerely,
Jinoh Kang
More information about the wine-devel
mailing list