blob: 41fac08dee09f670a82a218992782855da06e4c8 [file] [log] [blame]
Alexandre Julliardb67b1dc1995-02-16 16:47:09 +00001/*
Alexandre Julliarda845b881998-06-01 10:44:35 +00002 * 16-bit and 32-bit mode stack frame layout
Alexandre Julliardb67b1dc1995-02-16 16:47:09 +00003 *
Alexandre Julliarda845b881998-06-01 10:44:35 +00004 * Copyright 1995, 1998 Alexandre Julliard
Alexandre Julliardb67b1dc1995-02-16 16:47:09 +00005 */
6
Alexandre Julliardca22b331996-07-12 19:02:39 +00007#ifndef __WINE_STACKFRAME_H
8#define __WINE_STACKFRAME_H
Alexandre Julliardb67b1dc1995-02-16 16:47:09 +00009
Alexandre Julliarda1089c51999-08-01 12:51:55 +000010#include <string.h>
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000011#include "ldt.h"
Alexandre Julliard60ce85c1998-02-01 18:33:27 +000012#include "thread.h"
Alexandre Julliardb67b1dc1995-02-16 16:47:09 +000013
Patrik Stridvallc7a8dde1999-04-25 12:36:53 +000014#include "pshpack1.h"
Alexandre Julliardfa68b751995-04-03 16:55:37 +000015
Alexandre Julliard0623a6f1998-01-18 18:01:49 +000016 /* 32-bit stack layout after CallTo16() */
17typedef struct _STACK32FRAME
18{
19 SEGPTR frame16; /* 00 16-bit frame from last CallFrom16() */
Alexandre Julliard767e6f61998-08-09 12:47:43 +000020 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 Julliard0623a6f1998-01-18 18:01:49 +000027 DWORD ebp; /* 20 saved 32-bit frame pointer */
Ulrich Weigand6ab0fb11999-08-15 12:43:17 +000028 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 Julliard0623a6f1998-01-18 18:01:49 +000031} STACK32FRAME;
32
Alexandre Julliard8664b891996-04-05 14:58:24 +000033 /* 16-bit stack layout after CallFrom16() */
Ulrich Weigand6ab0fb11999-08-15 12:43:17 +000034typedef struct _STACK16FRAME
Alexandre Julliardb67b1dc1995-02-16 16:47:09 +000035{
Alexandre Julliard0623a6f1998-01-18 18:01:49 +000036 STACK32FRAME *frame32; /* 00 32-bit frame from last CallTo16() */
Ulrich Weigand3dff7bb1999-07-11 13:58:31 +000037 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 Weigand6ab0fb11999-08-15 12:43:17 +000044 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 Julliardb67b1dc1995-02-16 16:47:09 +000052} STACK16FRAME;
53
Patrik Stridvallc7a8dde1999-04-25 12:36:53 +000054#include "poppack.h"
Alexandre Julliardfa68b751995-04-03 16:55:37 +000055
Alexandre Julliard0a860a01999-06-22 11:43:42 +000056#define THREAD_STACK16(teb) ((STACK16FRAME*)PTR_SEG_TO_LIN((teb)->cur_stack))
57#define CURRENT_STACK16 (THREAD_STACK16(NtCurrentTeb()))
Alexandre Julliard60ce85c1998-02-01 18:33:27 +000058#define CURRENT_DS (CURRENT_STACK16->ds)
Alexandre Julliard8664b891996-04-05 14:58:24 +000059
Alexandre Julliard17216f51997-10-12 16:30:17 +000060/* varargs lists on the 16-bit stack */
Alexandre Julliardb67b1dc1995-02-16 16:47:09 +000061
Alexandre Julliard17216f51997-10-12 16:30:17 +000062typedef void *VA_LIST16;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000063
Alexandre Julliard17216f51997-10-12 16:30:17 +000064#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 Julliarda1089c51999-08-01 12:51:55 +000072
Alexandre Julliard60ce85c1998-02-01 18:33:27 +000073/* Push bytes on the 16-bit stack of a thread;
74 * return a segptr to the first pushed byte
75 */
Alexandre Julliarda1089c51999-08-01 12:51:55 +000076static 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 Julliard17216f51997-10-12 16:30:17 +000084
Alexandre Julliard60ce85c1998-02-01 18:33:27 +000085/* Pop bytes from the 16-bit stack of a thread */
Alexandre Julliarda1089c51999-08-01 12:51:55 +000086static 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 Julliardb67b1dc1995-02-16 16:47:09 +000093
Alexandre Julliarda1089c51999-08-01 12:51:55 +000094#ifdef __i386__
Alexandre Julliarda845b881998-06-01 10:44:35 +000095/* Push a DWORD on the 32-bit stack */
Alexandre Julliarda1089c51999-08-01 12:51:55 +000096static 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 Julliarda845b881998-06-01 10:44:35 +0000101
102/* Pop a DWORD from the 32-bit stack */
Alexandre Julliarda1089c51999-08-01 12:51:55 +0000103static 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 Julliarda845b881998-06-01 10:44:35 +0000110
111/* Win32 register functions */
Alexandre Julliard0a277b61999-05-13 16:21:37 +0000112#define REGS_FUNC(name) __regs_##name
Alexandre Julliarda845b881998-06-01 10:44:35 +0000113
Alexandre Julliardca22b331996-07-12 19:02:39 +0000114#endif /* __WINE_STACKFRAME_H */