This change is adding DWARF (CFI) unwind information to the hand-written assembly of the `__wine_syscall_dispatcher` function. This enables unwinding through the dispatcher from the Linux stack into (and through) the Windows stack.
The general idea is that the `syscall_frame` struct contains the content of the callee-save registers before the function call (in particular the stack pointer and the return address). At any point of the execution, we have a pointer into the `syscall_frame` in $ebx, $ecx, $ebp, or $esp.
For the CFI codes the general idea is that we are defining the computations of the callee-save registers based on the `syscall_frame` using DWARF’s `breg` instruction, rather than relative to CFA.
cc/ @florian-kuebler
-- v2: ntdll: Add CFI unwind info to __wine_syscall_dispatcher (i386).
From: Jinoh Kang jinoh.kang.kr@gmail.com
--- dlls/ntdll/unix/dwarf_cfi.h | 200 ++++++++++++++++++++++++++++++++ dlls/ntdll/unix/signal_x86_64.c | 198 +------------------------------ 2 files changed, 201 insertions(+), 197 deletions(-) create mode 100644 dlls/ntdll/unix/dwarf_cfi.h
diff --git a/dlls/ntdll/unix/dwarf_cfi.h b/dlls/ntdll/unix/dwarf_cfi.h new file mode 100644 index 00000000000..c5311cfc852 --- /dev/null +++ b/dlls/ntdll/unix/dwarf_cfi.h @@ -0,0 +1,200 @@ +/*********************************************************************** + * Definitions for Dwarf opcodes and CFI + */ + +#define DW_CFA_advance_loc 0x40 +#define DW_CFA_offset 0x80 +#define DW_CFA_restore 0xc0 +#define DW_CFA_nop 0x00 +#define DW_CFA_set_loc 0x01 +#define DW_CFA_advance_loc1 0x02 +#define DW_CFA_advance_loc2 0x03 +#define DW_CFA_advance_loc4 0x04 +#define DW_CFA_offset_extended 0x05 +#define DW_CFA_restore_extended 0x06 +#define DW_CFA_undefined 0x07 +#define DW_CFA_same_value 0x08 +#define DW_CFA_register 0x09 +#define DW_CFA_remember_state 0x0a +#define DW_CFA_restore_state 0x0b +#define DW_CFA_def_cfa 0x0c +#define DW_CFA_def_cfa_register 0x0d +#define DW_CFA_def_cfa_offset 0x0e +#define DW_CFA_def_cfa_expression 0x0f +#define DW_CFA_expression 0x10 +#define DW_CFA_offset_extended_sf 0x11 +#define DW_CFA_def_cfa_sf 0x12 +#define DW_CFA_def_cfa_offset_sf 0x13 +#define DW_CFA_val_offset 0x14 +#define DW_CFA_val_offset_sf 0x15 +#define DW_CFA_val_expression 0x16 + +#define DW_OP_addr 0x03 +#define DW_OP_deref 0x06 +#define DW_OP_const1u 0x08 +#define DW_OP_const1s 0x09 +#define DW_OP_const2u 0x0a +#define DW_OP_const2s 0x0b +#define DW_OP_const4u 0x0c +#define DW_OP_const4s 0x0d +#define DW_OP_const8u 0x0e +#define DW_OP_const8s 0x0f +#define DW_OP_constu 0x10 +#define DW_OP_consts 0x11 +#define DW_OP_dup 0x12 +#define DW_OP_drop 0x13 +#define DW_OP_over 0x14 +#define DW_OP_pick 0x15 +#define DW_OP_swap 0x16 +#define DW_OP_rot 0x17 +#define DW_OP_xderef 0x18 +#define DW_OP_abs 0x19 +#define DW_OP_and 0x1a +#define DW_OP_div 0x1b +#define DW_OP_minus 0x1c +#define DW_OP_mod 0x1d +#define DW_OP_mul 0x1e +#define DW_OP_neg 0x1f +#define DW_OP_not 0x20 +#define DW_OP_or 0x21 +#define DW_OP_plus 0x22 +#define DW_OP_plus_uconst 0x23 +#define DW_OP_shl 0x24 +#define DW_OP_shr 0x25 +#define DW_OP_shra 0x26 +#define DW_OP_xor 0x27 +#define DW_OP_bra 0x28 +#define DW_OP_eq 0x29 +#define DW_OP_ge 0x2a +#define DW_OP_gt 0x2b +#define DW_OP_le 0x2c +#define DW_OP_lt 0x2d +#define DW_OP_ne 0x2e +#define DW_OP_skip 0x2f +#define DW_OP_lit0 0x30 +#define DW_OP_lit1 0x31 +#define DW_OP_lit2 0x32 +#define DW_OP_lit3 0x33 +#define DW_OP_lit4 0x34 +#define DW_OP_lit5 0x35 +#define DW_OP_lit6 0x36 +#define DW_OP_lit7 0x37 +#define DW_OP_lit8 0x38 +#define DW_OP_lit9 0x39 +#define DW_OP_lit10 0x3a +#define DW_OP_lit11 0x3b +#define DW_OP_lit12 0x3c +#define DW_OP_lit13 0x3d +#define DW_OP_lit14 0x3e +#define DW_OP_lit15 0x3f +#define DW_OP_lit16 0x40 +#define DW_OP_lit17 0x41 +#define DW_OP_lit18 0x42 +#define DW_OP_lit19 0x43 +#define DW_OP_lit20 0x44 +#define DW_OP_lit21 0x45 +#define DW_OP_lit22 0x46 +#define DW_OP_lit23 0x47 +#define DW_OP_lit24 0x48 +#define DW_OP_lit25 0x49 +#define DW_OP_lit26 0x4a +#define DW_OP_lit27 0x4b +#define DW_OP_lit28 0x4c +#define DW_OP_lit29 0x4d +#define DW_OP_lit30 0x4e +#define DW_OP_lit31 0x4f +#define DW_OP_reg0 0x50 +#define DW_OP_reg1 0x51 +#define DW_OP_reg2 0x52 +#define DW_OP_reg3 0x53 +#define DW_OP_reg4 0x54 +#define DW_OP_reg5 0x55 +#define DW_OP_reg6 0x56 +#define DW_OP_reg7 0x57 +#define DW_OP_reg8 0x58 +#define DW_OP_reg9 0x59 +#define DW_OP_reg10 0x5a +#define DW_OP_reg11 0x5b +#define DW_OP_reg12 0x5c +#define DW_OP_reg13 0x5d +#define DW_OP_reg14 0x5e +#define DW_OP_reg15 0x5f +#define DW_OP_reg16 0x60 +#define DW_OP_reg17 0x61 +#define DW_OP_reg18 0x62 +#define DW_OP_reg19 0x63 +#define DW_OP_reg20 0x64 +#define DW_OP_reg21 0x65 +#define DW_OP_reg22 0x66 +#define DW_OP_reg23 0x67 +#define DW_OP_reg24 0x68 +#define DW_OP_reg25 0x69 +#define DW_OP_reg26 0x6a +#define DW_OP_reg27 0x6b +#define DW_OP_reg28 0x6c +#define DW_OP_reg29 0x6d +#define DW_OP_reg30 0x6e +#define DW_OP_reg31 0x6f +#define DW_OP_breg0 0x70 +#define DW_OP_breg1 0x71 +#define DW_OP_breg2 0x72 +#define DW_OP_breg3 0x73 +#define DW_OP_breg4 0x74 +#define DW_OP_breg5 0x75 +#define DW_OP_breg6 0x76 +#define DW_OP_breg7 0x77 +#define DW_OP_breg8 0x78 +#define DW_OP_breg9 0x79 +#define DW_OP_breg10 0x7a +#define DW_OP_breg11 0x7b +#define DW_OP_breg12 0x7c +#define DW_OP_breg13 0x7d +#define DW_OP_breg14 0x7e +#define DW_OP_breg15 0x7f +#define DW_OP_breg16 0x80 +#define DW_OP_breg17 0x81 +#define DW_OP_breg18 0x82 +#define DW_OP_breg19 0x83 +#define DW_OP_breg20 0x84 +#define DW_OP_breg21 0x85 +#define DW_OP_breg22 0x86 +#define DW_OP_breg23 0x87 +#define DW_OP_breg24 0x88 +#define DW_OP_breg25 0x89 +#define DW_OP_breg26 0x8a +#define DW_OP_breg27 0x8b +#define DW_OP_breg28 0x8c +#define DW_OP_breg29 0x8d +#define DW_OP_breg30 0x8e +#define DW_OP_breg31 0x8f +#define DW_OP_regx 0x90 +#define DW_OP_fbreg 0x91 +#define DW_OP_bregx 0x92 +#define DW_OP_piece 0x93 +#define DW_OP_deref_size 0x94 +#define DW_OP_xderef_size 0x95 +#define DW_OP_nop 0x96 +#define DW_OP_push_object_address 0x97 +#define DW_OP_call2 0x98 +#define DW_OP_call4 0x99 +#define DW_OP_call_ref 0x9a +#define DW_OP_form_tls_address 0x9b +#define DW_OP_call_frame_cfa 0x9c +#define DW_OP_bit_piece 0x9d +#define DW_OP_lo_user 0xe0 +#define DW_OP_hi_user 0xff +#define DW_OP_GNU_push_tls_address 0xe0 +#define DW_OP_GNU_uninit 0xf0 +#define DW_OP_GNU_encoded_addr 0xf1 + +#define __ASM_CFI_STR(...) #__VA_ARGS__ +#define __ASM_CFI_ESC(...) \ + __ASM_CFI(".cfi_escape " __ASM_CFI_STR(__VA_ARGS__) "\n\t") +#define __ASM_CFI_CFA_IS_AT1(base, offset) \ + __ASM_CFI_ESC(DW_CFA_def_cfa_expression, 0x03, DW_OP_ ## base, offset, DW_OP_deref) +#define __ASM_CFI_REG_IS_AT1(reg, base, offset) \ + __ASM_CFI_ESC(DW_CFA_expression, DW_REG_ ## reg, 0x02, DW_OP_ ## base, offset) +#define __ASM_CFI_CFA_IS_AT2(base, lo, hi) \ + __ASM_CFI_ESC(DW_CFA_def_cfa_expression, 0x04, DW_OP_ ## base, lo, hi, DW_OP_deref) +#define __ASM_CFI_REG_IS_AT2(reg, base, lo, hi) \ + __ASM_CFI_ESC(DW_CFA_expression, DW_REG_ ## reg, 0x03, DW_OP_ ## base, lo, hi) diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 5787f1dc6f9..42951976873 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -76,6 +76,7 @@ #include "wine/asm.h" #include "unix_private.h" #include "wine/debug.h" +#include "dwarf_cfi.h"
WINE_DEFAULT_DEBUG_CHANNEL(unwind); WINE_DECLARE_DEBUG_CHANNEL(seh); @@ -494,191 +495,6 @@ static USHORT fs32_sel; /* selector for %fs in 32-bit mode */ * Definitions for Dwarf unwind tables */
-#define DW_CFA_advance_loc 0x40 -#define DW_CFA_offset 0x80 -#define DW_CFA_restore 0xc0 -#define DW_CFA_nop 0x00 -#define DW_CFA_set_loc 0x01 -#define DW_CFA_advance_loc1 0x02 -#define DW_CFA_advance_loc2 0x03 -#define DW_CFA_advance_loc4 0x04 -#define DW_CFA_offset_extended 0x05 -#define DW_CFA_restore_extended 0x06 -#define DW_CFA_undefined 0x07 -#define DW_CFA_same_value 0x08 -#define DW_CFA_register 0x09 -#define DW_CFA_remember_state 0x0a -#define DW_CFA_restore_state 0x0b -#define DW_CFA_def_cfa 0x0c -#define DW_CFA_def_cfa_register 0x0d -#define DW_CFA_def_cfa_offset 0x0e -#define DW_CFA_def_cfa_expression 0x0f -#define DW_CFA_expression 0x10 -#define DW_CFA_offset_extended_sf 0x11 -#define DW_CFA_def_cfa_sf 0x12 -#define DW_CFA_def_cfa_offset_sf 0x13 -#define DW_CFA_val_offset 0x14 -#define DW_CFA_val_offset_sf 0x15 -#define DW_CFA_val_expression 0x16 - -#define DW_OP_addr 0x03 -#define DW_OP_deref 0x06 -#define DW_OP_const1u 0x08 -#define DW_OP_const1s 0x09 -#define DW_OP_const2u 0x0a -#define DW_OP_const2s 0x0b -#define DW_OP_const4u 0x0c -#define DW_OP_const4s 0x0d -#define DW_OP_const8u 0x0e -#define DW_OP_const8s 0x0f -#define DW_OP_constu 0x10 -#define DW_OP_consts 0x11 -#define DW_OP_dup 0x12 -#define DW_OP_drop 0x13 -#define DW_OP_over 0x14 -#define DW_OP_pick 0x15 -#define DW_OP_swap 0x16 -#define DW_OP_rot 0x17 -#define DW_OP_xderef 0x18 -#define DW_OP_abs 0x19 -#define DW_OP_and 0x1a -#define DW_OP_div 0x1b -#define DW_OP_minus 0x1c -#define DW_OP_mod 0x1d -#define DW_OP_mul 0x1e -#define DW_OP_neg 0x1f -#define DW_OP_not 0x20 -#define DW_OP_or 0x21 -#define DW_OP_plus 0x22 -#define DW_OP_plus_uconst 0x23 -#define DW_OP_shl 0x24 -#define DW_OP_shr 0x25 -#define DW_OP_shra 0x26 -#define DW_OP_xor 0x27 -#define DW_OP_bra 0x28 -#define DW_OP_eq 0x29 -#define DW_OP_ge 0x2a -#define DW_OP_gt 0x2b -#define DW_OP_le 0x2c -#define DW_OP_lt 0x2d -#define DW_OP_ne 0x2e -#define DW_OP_skip 0x2f -#define DW_OP_lit0 0x30 -#define DW_OP_lit1 0x31 -#define DW_OP_lit2 0x32 -#define DW_OP_lit3 0x33 -#define DW_OP_lit4 0x34 -#define DW_OP_lit5 0x35 -#define DW_OP_lit6 0x36 -#define DW_OP_lit7 0x37 -#define DW_OP_lit8 0x38 -#define DW_OP_lit9 0x39 -#define DW_OP_lit10 0x3a -#define DW_OP_lit11 0x3b -#define DW_OP_lit12 0x3c -#define DW_OP_lit13 0x3d -#define DW_OP_lit14 0x3e -#define DW_OP_lit15 0x3f -#define DW_OP_lit16 0x40 -#define DW_OP_lit17 0x41 -#define DW_OP_lit18 0x42 -#define DW_OP_lit19 0x43 -#define DW_OP_lit20 0x44 -#define DW_OP_lit21 0x45 -#define DW_OP_lit22 0x46 -#define DW_OP_lit23 0x47 -#define DW_OP_lit24 0x48 -#define DW_OP_lit25 0x49 -#define DW_OP_lit26 0x4a -#define DW_OP_lit27 0x4b -#define DW_OP_lit28 0x4c -#define DW_OP_lit29 0x4d -#define DW_OP_lit30 0x4e -#define DW_OP_lit31 0x4f -#define DW_OP_reg0 0x50 -#define DW_OP_reg1 0x51 -#define DW_OP_reg2 0x52 -#define DW_OP_reg3 0x53 -#define DW_OP_reg4 0x54 -#define DW_OP_reg5 0x55 -#define DW_OP_reg6 0x56 -#define DW_OP_reg7 0x57 -#define DW_OP_reg8 0x58 -#define DW_OP_reg9 0x59 -#define DW_OP_reg10 0x5a -#define DW_OP_reg11 0x5b -#define DW_OP_reg12 0x5c -#define DW_OP_reg13 0x5d -#define DW_OP_reg14 0x5e -#define DW_OP_reg15 0x5f -#define DW_OP_reg16 0x60 -#define DW_OP_reg17 0x61 -#define DW_OP_reg18 0x62 -#define DW_OP_reg19 0x63 -#define DW_OP_reg20 0x64 -#define DW_OP_reg21 0x65 -#define DW_OP_reg22 0x66 -#define DW_OP_reg23 0x67 -#define DW_OP_reg24 0x68 -#define DW_OP_reg25 0x69 -#define DW_OP_reg26 0x6a -#define DW_OP_reg27 0x6b -#define DW_OP_reg28 0x6c -#define DW_OP_reg29 0x6d -#define DW_OP_reg30 0x6e -#define DW_OP_reg31 0x6f -#define DW_OP_breg0 0x70 -#define DW_OP_breg1 0x71 -#define DW_OP_breg2 0x72 -#define DW_OP_breg3 0x73 -#define DW_OP_breg4 0x74 -#define DW_OP_breg5 0x75 -#define DW_OP_breg6 0x76 -#define DW_OP_breg7 0x77 -#define DW_OP_breg8 0x78 -#define DW_OP_breg9 0x79 -#define DW_OP_breg10 0x7a -#define DW_OP_breg11 0x7b -#define DW_OP_breg12 0x7c -#define DW_OP_breg13 0x7d -#define DW_OP_breg14 0x7e -#define DW_OP_breg15 0x7f -#define DW_OP_breg16 0x80 -#define DW_OP_breg17 0x81 -#define DW_OP_breg18 0x82 -#define DW_OP_breg19 0x83 -#define DW_OP_breg20 0x84 -#define DW_OP_breg21 0x85 -#define DW_OP_breg22 0x86 -#define DW_OP_breg23 0x87 -#define DW_OP_breg24 0x88 -#define DW_OP_breg25 0x89 -#define DW_OP_breg26 0x8a -#define DW_OP_breg27 0x8b -#define DW_OP_breg28 0x8c -#define DW_OP_breg29 0x8d -#define DW_OP_breg30 0x8e -#define DW_OP_breg31 0x8f -#define DW_OP_regx 0x90 -#define DW_OP_fbreg 0x91 -#define DW_OP_bregx 0x92 -#define DW_OP_piece 0x93 -#define DW_OP_deref_size 0x94 -#define DW_OP_xderef_size 0x95 -#define DW_OP_nop 0x96 -#define DW_OP_push_object_address 0x97 -#define DW_OP_call2 0x98 -#define DW_OP_call4 0x99 -#define DW_OP_call_ref 0x9a -#define DW_OP_form_tls_address 0x9b -#define DW_OP_call_frame_cfa 0x9c -#define DW_OP_bit_piece 0x9d -#define DW_OP_lo_user 0xe0 -#define DW_OP_hi_user 0xff -#define DW_OP_GNU_push_tls_address 0xe0 -#define DW_OP_GNU_uninit 0xf0 -#define DW_OP_GNU_encoded_addr 0xf1 - #define DW_EH_PE_native 0x00 #define DW_EH_PE_uleb128 0x01 #define DW_EH_PE_udata2 0x02 @@ -3354,18 +3170,6 @@ __ASM_GLOBAL_FUNC( signal_exit_thread, #define DW_REG_r15 0x0f #define DW_REG_rip 0x10
-#define __ASM_CFI_STR(...) #__VA_ARGS__ -#define __ASM_CFI_ESC(...) \ - __ASM_CFI(".cfi_escape " __ASM_CFI_STR(__VA_ARGS__) "\n\t") -#define __ASM_CFI_CFA_IS_AT1(base, offset) \ - __ASM_CFI_ESC(DW_CFA_def_cfa_expression, 0x03, DW_OP_ ## base, offset, DW_OP_deref) -#define __ASM_CFI_REG_IS_AT1(reg, base, offset) \ - __ASM_CFI_ESC(DW_CFA_expression, DW_REG_ ## reg, 0x02, DW_OP_ ## base, offset) -#define __ASM_CFI_CFA_IS_AT2(base, lo, hi) \ - __ASM_CFI_ESC(DW_CFA_def_cfa_expression, 0x04, DW_OP_ ## base, lo, hi, DW_OP_deref) -#define __ASM_CFI_REG_IS_AT2(reg, base, lo, hi) \ - __ASM_CFI_ESC(DW_CFA_expression, DW_REG_ ## reg, 0x03, DW_OP_ ## base, lo, hi) - /*********************************************************************** * __wine_syscall_dispatcher */
From: Jinoh Kang jinoh.kang.kr@gmail.com
This change is adding DWARF (CFI) unwind information to the hand-written assembly of the `__wine_syscall_dispatcher` function. This enables unwinding through the dispatcher from the Linux stack into (and through) the Windows stack.
The general idea is that the `syscall_frame` struct contains the content of the callee-save registers before the function call (in particular the stack pointer and the return address). At any point of the execution, we have a pointer into the `syscall_frame` in $ebx, $ecx, $ebp, or $esp.
For the CFI codes the general idea is that we are defining the computations of the callee-save registers based on the `syscall_frame` using DWARF’s `breg` instruction, rather than relative to CFA. --- dlls/ntdll/unix/signal_i386.c | 75 ++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 2dfce706394..dc468dc877d 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -59,6 +59,7 @@ #include "wine/asm.h" #include "unix_private.h" #include "wine/debug.h" +#include "dwarf_cfi.h"
WINE_DEFAULT_DEBUG_CHANNEL(seh);
@@ -2493,18 +2494,40 @@ __ASM_GLOBAL_FUNC( signal_exit_thread, "call *%ecx" )
+#define DW_OP_ecx DW_OP_breg1 +#define DW_OP_ebx DW_OP_breg3 +#define DW_OP_esp DW_OP_breg4 +#define DW_OP_ebp DW_OP_breg5 + +#define DW_REG_eax 0x00 +#define DW_REG_ecx 0x01 +#define DW_REG_edx 0x02 +#define DW_REG_ebx 0x03 +#define DW_REG_esp 0x04 +#define DW_REG_ebp 0x05 +#define DW_REG_esi 0x06 +#define DW_REG_edi 0x07 +#define DW_REG_eip 0x08 + /*********************************************************************** * __wine_syscall_dispatcher */ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, + __ASM_CFI(".cfi_signal_frame\n\t") "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_REG_IS_AT1(eip, ecx, 0x08) "pushfl\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") "popl 0x04(%ecx)\n\t" /* frame->eflags */ + __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t") ".globl " __ASM_NAME("__wine_syscall_dispatcher_prolog_end") "\n" __ASM_NAME("__wine_syscall_dispatcher_prolog_end") ":\n\t" "movl %esp,0x0c(%ecx)\n\t" /* frame->esp */ + __ASM_CFI_CFA_IS_AT1(ecx, 0x0c) + __ASM_CFI_REG_IS_AT1(esp, ecx, 0x0c) "movw %cs,0x10(%ecx)\n\t" "movw %ss,0x12(%ecx)\n\t" "movw %ds,0x14(%ecx)\n\t" @@ -2513,10 +2536,21 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "movw %gs,0x1a(%ecx)\n\t" "movl %eax,0x1c(%ecx)\n\t" "movl %ebx,0x20(%ecx)\n\t" + __ASM_CFI_REG_IS_AT1(ebx, ecx, 0x20) "movl %edi,0x2c(%ecx)\n\t" + __ASM_CFI_REG_IS_AT1(edi, ecx, 0x2c) "movl %esi,0x30(%ecx)\n\t" + __ASM_CFI_REG_IS_AT1(esi, ecx, 0x30) "movl %ebp,0x34(%ecx)\n\t" + __ASM_CFI_REG_IS_AT1(ebp, ecx, 0x34) "leal 0x34(%ecx),%ebp\n\t" + __ASM_CFI_CFA_IS_AT1(ebp, 0x58) + __ASM_CFI_REG_IS_AT1(esp, ebp, 0x58) + __ASM_CFI_REG_IS_AT1(eip, ebp, 0x54) + __ASM_CFI_REG_IS_AT1(ebx, ebp, 0x6c) + __ASM_CFI_REG_IS_AT1(edi, ebp, 0x78) + __ASM_CFI_REG_IS_AT1(esi, ebp, 0x7c) + __ASM_CFI_REG_IS_AT1(ebp, ebp, 0x00) "leal 4(%esp),%esi\n\t" /* first argument */ "movl %eax,%ebx\n\t" "shrl $8,%ebx\n\t" @@ -2570,7 +2604,15 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "rep; movsl\n\t" "call *(%eax,%edx,4)\n\t" "leal -0x34(%ebp),%esp\n" - "5:\tmovl 0(%esp),%ecx\n\t" /* frame->syscall_flags + (frame->restore_flags << 16) */ + "5:\t" + __ASM_CFI_CFA_IS_AT1(esp, 0x0c) + __ASM_CFI_REG_IS_AT1(esp, esp, 0x0c) + __ASM_CFI_REG_IS_AT1(eip, esp, 0x08) + __ASM_CFI_REG_IS_AT1(ebx, esp, 0x20) + __ASM_CFI_REG_IS_AT1(edi, esp, 0x2c) + __ASM_CFI_REG_IS_AT1(esi, esp, 0x30) + __ASM_CFI_REG_IS_AT1(ebp, esp, 0x34) + "movl 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" "testl $3,%ecx\n\t" /* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */ @@ -2588,38 +2630,69 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "2:\tfrstor 0x40(%esp)\n\t" "fwait\n" "3:\tmovl 0x2c(%esp),%edi\n\t" + __ASM_CFI(".cfi_remember_state\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" "movl 0x24(%esp),%ecx\n\t" "movl 0x28(%esp),%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" "xchgl %ebx,%esp\n\t" + __ASM_CFI(".cfi_def_cfa %esp, 0\n\t") + __ASM_CFI(".cfi_same_value %esp\n\t") + __ASM_CFI_REG_IS_AT1(eip, ebx, 0x08) + __ASM_CFI_REG_IS_AT1(ebx, ebx, 0x20) "pushl 0x04(%ebx)\n\t" /* frame->eflags */ + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") "pushl 0x10(%ebx)\n\t" /* frame->cs */ + __ASM_CFI(".cfi_adjust_cfa_offset 4\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") "movw 0x16(%ebx),%es\n\t" "movw 0x18(%ebx),%fs\n\t" "movw 0x1a(%ebx),%gs\n\t" "movl 0x20(%ebx),%ebx\n\t" + __ASM_CFI(".cfi_same_value %ebx\n\t") "popl %ds\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t") "iret\n" + __ASM_CFI("\t.cfi_restore_state\n") "6:\tmovl $0xc000000d,%eax\n\t" /* STATUS_INVALID_PARAMETER */ "jmp 5b\n\t" ".globl " __ASM_NAME("__wine_syscall_dispatcher_return") "\n" __ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t" + __ASM_CFI(".cfi_remember_state\n\t") + __ASM_CFI(".cfi_def_cfa %esp, 4\n\t") + __ASM_CFI(".cfi_restore %esp\n\t") + __ASM_CFI(".cfi_restore %eip\n\t") + __ASM_CFI(".cfi_restore %ebx\n\t") + __ASM_CFI(".cfi_restore %edi\n\t") + __ASM_CFI(".cfi_restore %esi\n\t") + __ASM_CFI(".cfi_restore %ebp\n\t") "movl 8(%esp),%eax\n\t" "movl 4(%esp),%esp\n\t" + __ASM_CFI(".cfi_restore_state\n\t") "jmp 5b" )
Fwiw there's some overlap with https://gitlab.winehq.org/wine/wine/-/merge_requests/1134 for the move of dwarf definitions.
On Fri Oct 28 15:52:37 2022 +0000, Rémi Bernon wrote:
Fwiw there's some overlap with https://gitlab.winehq.org/wine/wine/-/merge_requests/1134 for the move of dwarf definitions.
If I cherry-pick the dwarf header from !1134, can I get it to avoid rebase conflicts?
On Fri Oct 28 15:52:37 2022 +0000, Jinoh Kang wrote:
If I cherry-pick the dwarf header from !1134, can I get it to avoid rebase conflicts?
It's now been merged so you could rebase this one.
Rémi Bernon (@rbernon) commented about dlls/ntdll/unix/signal_i386.c:
+#define DW_REG_eax 0x00 +#define DW_REG_ecx 0x01 +#define DW_REG_edx 0x02 +#define DW_REG_ebx 0x03 +#define DW_REG_esp 0x04 +#define DW_REG_ebp 0x05 +#define DW_REG_esi 0x06 +#define DW_REG_edi 0x07 +#define DW_REG_eip 0x08
/***********************************************************************
__wine_syscall_dispatcher
*/ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
__ASM_CFI(".cfi_signal_frame\n\t")
Would you mind having a separate commit adding `.cfi_signal_frame` to every syscall dispatcher implementations?
Rémi Bernon (@rbernon) commented about dlls/ntdll/unix/signal_i386.c:
"rep; movsl\n\t" "call *(%eax,%edx,4)\n\t" "leal -0x34(%ebp),%esp\n"
"5:\tmovl 0(%esp),%ecx\n\t" /* frame->syscall_flags + (frame->restore_flags << 16) */
"5:\t"
__ASM_CFI_CFA_IS_AT1(esp, 0x0c)
__ASM_CFI_REG_IS_AT1(esp, esp, 0x0c)
__ASM_CFI_REG_IS_AT1(eip, esp, 0x08)
__ASM_CFI_REG_IS_AT1(ebx, esp, 0x20)
__ASM_CFI_REG_IS_AT1(edi, esp, 0x2c)
__ASM_CFI_REG_IS_AT1(esi, esp, 0x30)
__ASM_CFI_REG_IS_AT1(ebp, esp, 0x34)
Could this go above the label? No sure to see why it's been split there.