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