Alexandre Julliard | b67b1dc | 1995-02-16 16:47:09 +0000 | [diff] [blame] | 1 | /* |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 2 | * 16-bit and 32-bit mode stack frame layout |
Alexandre Julliard | b67b1dc | 1995-02-16 16:47:09 +0000 | [diff] [blame] | 3 | * |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 4 | * Copyright 1995, 1998 Alexandre Julliard |
Alexandre Julliard | b67b1dc | 1995-02-16 16:47:09 +0000 | [diff] [blame] | 5 | */ |
| 6 | |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 7 | #ifndef __WINE_STACKFRAME_H |
| 8 | #define __WINE_STACKFRAME_H |
Alexandre Julliard | b67b1dc | 1995-02-16 16:47:09 +0000 | [diff] [blame] | 9 | |
Alexandre Julliard | a1089c5 | 1999-08-01 12:51:55 +0000 | [diff] [blame] | 10 | #include <string.h> |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 11 | #include "ldt.h" |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 12 | #include "thread.h" |
Alexandre Julliard | b67b1dc | 1995-02-16 16:47:09 +0000 | [diff] [blame] | 13 | |
Patrik Stridvall | c7a8dde | 1999-04-25 12:36:53 +0000 | [diff] [blame] | 14 | #include "pshpack1.h" |
Alexandre Julliard | fa68b75 | 1995-04-03 16:55:37 +0000 | [diff] [blame] | 15 | |
Alexandre Julliard | 0623a6f | 1998-01-18 18:01:49 +0000 | [diff] [blame] | 16 | /* 32-bit stack layout after CallTo16() */ |
| 17 | typedef struct _STACK32FRAME |
| 18 | { |
| 19 | SEGPTR frame16; /* 00 16-bit frame from last CallFrom16() */ |
Alexandre Julliard | 767e6f6 | 1998-08-09 12:47:43 +0000 | [diff] [blame] | 20 | DWORD restore_addr; /* 04 return address for restoring code selector */ |
| 21 | DWORD codeselector; /* 08 code selector to restore */ |
| 22 | DWORD edi; /* 0c saved registers */ |
| 23 | DWORD esi; /* 10 */ |
| 24 | DWORD edx; /* 14 */ |
| 25 | DWORD ecx; /* 18 */ |
| 26 | DWORD ebx; /* 1c */ |
Alexandre Julliard | 0623a6f | 1998-01-18 18:01:49 +0000 | [diff] [blame] | 27 | DWORD ebp; /* 20 saved 32-bit frame pointer */ |
Ulrich Weigand | 6ab0fb1 | 1999-08-15 12:43:17 +0000 | [diff] [blame] | 28 | DWORD retaddr; /* 24 return address */ |
| 29 | DWORD target; /* 28 target address / CONTEXT86 pointer */ |
| 30 | DWORD nb_args; /* 2c number of 16-bit argument bytes */ |
Alexandre Julliard | 0623a6f | 1998-01-18 18:01:49 +0000 | [diff] [blame] | 31 | } STACK32FRAME; |
| 32 | |
Alexandre Julliard | 8664b89 | 1996-04-05 14:58:24 +0000 | [diff] [blame] | 33 | /* 16-bit stack layout after CallFrom16() */ |
Ulrich Weigand | 6ab0fb1 | 1999-08-15 12:43:17 +0000 | [diff] [blame] | 34 | typedef struct _STACK16FRAME |
Alexandre Julliard | b67b1dc | 1995-02-16 16:47:09 +0000 | [diff] [blame] | 35 | { |
Alexandre Julliard | 0623a6f | 1998-01-18 18:01:49 +0000 | [diff] [blame] | 36 | STACK32FRAME *frame32; /* 00 32-bit frame from last CallTo16() */ |
Ulrich Weigand | 3dff7bb | 1999-07-11 13:58:31 +0000 | [diff] [blame] | 37 | DWORD edx; /* 04 saved registers */ |
| 38 | DWORD ecx; /* 08 */ |
| 39 | DWORD ebp; /* 0c */ |
| 40 | WORD ds; /* 10 */ |
| 41 | WORD es; /* 12 */ |
| 42 | WORD fs; /* 14 */ |
| 43 | WORD gs; /* 16 */ |
Ulrich Weigand | 6ab0fb1 | 1999-08-15 12:43:17 +0000 | [diff] [blame] | 44 | DWORD callfrom_ip; /* 18 callfrom tail IP */ |
| 45 | DWORD module_cs; /* 1c module code segment */ |
| 46 | DWORD relay; /* 20 relay function address */ |
| 47 | WORD entry_ip; /* 22 entry point IP */ |
| 48 | DWORD entry_point; /* 26 API entry point to call, reused as mutex count */ |
| 49 | WORD bp; /* 2a 16-bit stack frame chain */ |
| 50 | WORD ip; /* 2c return address */ |
| 51 | WORD cs; /* 2e */ |
Alexandre Julliard | b67b1dc | 1995-02-16 16:47:09 +0000 | [diff] [blame] | 52 | } STACK16FRAME; |
| 53 | |
Patrik Stridvall | c7a8dde | 1999-04-25 12:36:53 +0000 | [diff] [blame] | 54 | #include "poppack.h" |
Alexandre Julliard | fa68b75 | 1995-04-03 16:55:37 +0000 | [diff] [blame] | 55 | |
Alexandre Julliard | 0a860a0 | 1999-06-22 11:43:42 +0000 | [diff] [blame] | 56 | #define THREAD_STACK16(teb) ((STACK16FRAME*)PTR_SEG_TO_LIN((teb)->cur_stack)) |
| 57 | #define CURRENT_STACK16 (THREAD_STACK16(NtCurrentTeb())) |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 58 | #define CURRENT_DS (CURRENT_STACK16->ds) |
Alexandre Julliard | 8664b89 | 1996-04-05 14:58:24 +0000 | [diff] [blame] | 59 | |
Alexandre Julliard | 17216f5 | 1997-10-12 16:30:17 +0000 | [diff] [blame] | 60 | /* varargs lists on the 16-bit stack */ |
Alexandre Julliard | b67b1dc | 1995-02-16 16:47:09 +0000 | [diff] [blame] | 61 | |
Alexandre Julliard | 17216f5 | 1997-10-12 16:30:17 +0000 | [diff] [blame] | 62 | typedef void *VA_LIST16; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 63 | |
Alexandre Julliard | 17216f5 | 1997-10-12 16:30:17 +0000 | [diff] [blame] | 64 | #define __VA_ROUNDED16(type) \ |
| 65 | ((sizeof(type) + sizeof(WORD) - 1) / sizeof(WORD) * sizeof(WORD)) |
| 66 | #define VA_START16(list) ((list) = (VA_LIST16)(CURRENT_STACK16 + 1)) |
| 67 | #define VA_ARG16(list,type) \ |
| 68 | (((list) = (VA_LIST16)((char *)(list) + __VA_ROUNDED16(type))), \ |
| 69 | *((type *)(void *)((char *)(list) - __VA_ROUNDED16(type)))) |
| 70 | #define VA_END16(list) ((void)0) |
| 71 | |
Alexandre Julliard | a1089c5 | 1999-08-01 12:51:55 +0000 | [diff] [blame] | 72 | |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 73 | /* Push bytes on the 16-bit stack of a thread; |
| 74 | * return a segptr to the first pushed byte |
| 75 | */ |
Alexandre Julliard | a1089c5 | 1999-08-01 12:51:55 +0000 | [diff] [blame] | 76 | static inline SEGPTR WINE_UNUSED stack16_push( int size ) |
| 77 | { |
| 78 | TEB *teb = NtCurrentTeb(); |
| 79 | STACK16FRAME *frame = THREAD_STACK16(teb); |
| 80 | memmove( (char*)frame - size, frame, sizeof(*frame) ); |
| 81 | teb->cur_stack -= size; |
| 82 | return (SEGPTR)(teb->cur_stack + sizeof(*frame)); |
| 83 | } |
Alexandre Julliard | 17216f5 | 1997-10-12 16:30:17 +0000 | [diff] [blame] | 84 | |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 85 | /* Pop bytes from the 16-bit stack of a thread */ |
Alexandre Julliard | a1089c5 | 1999-08-01 12:51:55 +0000 | [diff] [blame] | 86 | static inline void WINE_UNUSED stack16_pop( int size ) |
| 87 | { |
| 88 | TEB *teb = NtCurrentTeb(); |
| 89 | STACK16FRAME *frame = THREAD_STACK16(teb); |
| 90 | memmove( (char*)frame + size, frame, sizeof(*frame) ); |
| 91 | teb->cur_stack += size; |
| 92 | } |
Alexandre Julliard | b67b1dc | 1995-02-16 16:47:09 +0000 | [diff] [blame] | 93 | |
Alexandre Julliard | a1089c5 | 1999-08-01 12:51:55 +0000 | [diff] [blame] | 94 | #ifdef __i386__ |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 95 | /* Push a DWORD on the 32-bit stack */ |
Alexandre Julliard | a1089c5 | 1999-08-01 12:51:55 +0000 | [diff] [blame] | 96 | static inline void WINE_UNUSED stack32_push( CONTEXT *context, DWORD val ) |
| 97 | { |
| 98 | ESP_reg(context) -= sizeof(DWORD); |
| 99 | *(DWORD *)ESP_reg(context) = val; |
| 100 | } |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 101 | |
| 102 | /* Pop a DWORD from the 32-bit stack */ |
Alexandre Julliard | a1089c5 | 1999-08-01 12:51:55 +0000 | [diff] [blame] | 103 | static inline DWORD WINE_UNUSED stack32_pop( CONTEXT *context ) |
| 104 | { |
| 105 | DWORD ret = *(DWORD *)ESP_reg(context); |
| 106 | ESP_reg(context) += sizeof(DWORD); |
| 107 | return ret; |
| 108 | } |
| 109 | #endif /* __i386__ */ |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 110 | |
| 111 | /* Win32 register functions */ |
Alexandre Julliard | 0a277b6 | 1999-05-13 16:21:37 +0000 | [diff] [blame] | 112 | #define REGS_FUNC(name) __regs_##name |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 113 | |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 114 | #endif /* __WINE_STACKFRAME_H */ |