blob: 9cc0389b8f8e86183708e10820dc5017f4d2d9fb [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>
Patrik Stridvall6cc47d42000-03-08 18:26:56 +000011
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000012#include "ldt.h"
Alexandre Julliard60ce85c1998-02-01 18:33:27 +000013#include "thread.h"
Patrik Stridvall6cc47d42000-03-08 18:26:56 +000014#include "winnt.h"
Alexandre Julliardb67b1dc1995-02-16 16:47:09 +000015
Patrik Stridvallc7a8dde1999-04-25 12:36:53 +000016#include "pshpack1.h"
Alexandre Julliardfa68b751995-04-03 16:55:37 +000017
Alexandre Julliard0623a6f1998-01-18 18:01:49 +000018 /* 32-bit stack layout after CallTo16() */
19typedef struct _STACK32FRAME
20{
21 SEGPTR frame16; /* 00 16-bit frame from last CallFrom16() */
Alexandre Julliard767e6f61998-08-09 12:47:43 +000022 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 Julliard0623a6f1998-01-18 18:01:49 +000029 DWORD ebp; /* 20 saved 32-bit frame pointer */
Ulrich Weigand6ab0fb11999-08-15 12:43:17 +000030 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 Julliard0623a6f1998-01-18 18:01:49 +000033} STACK32FRAME;
34
Alexandre Julliard8664b891996-04-05 14:58:24 +000035 /* 16-bit stack layout after CallFrom16() */
Ulrich Weigand6ab0fb11999-08-15 12:43:17 +000036typedef struct _STACK16FRAME
Alexandre Julliardb67b1dc1995-02-16 16:47:09 +000037{
Alexandre Julliard0623a6f1998-01-18 18:01:49 +000038 STACK32FRAME *frame32; /* 00 32-bit frame from last CallTo16() */
Ulrich Weigand3dff7bb1999-07-11 13:58:31 +000039 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 Weigand6ab0fb11999-08-15 12:43:17 +000046 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 Julliardb67b1dc1995-02-16 16:47:09 +000054} STACK16FRAME;
55
Patrik Stridvallc7a8dde1999-04-25 12:36:53 +000056#include "poppack.h"
Alexandre Julliardfa68b751995-04-03 16:55:37 +000057
Alexandre Julliard0a860a01999-06-22 11:43:42 +000058#define THREAD_STACK16(teb) ((STACK16FRAME*)PTR_SEG_TO_LIN((teb)->cur_stack))
59#define CURRENT_STACK16 (THREAD_STACK16(NtCurrentTeb()))
Alexandre Julliard60ce85c1998-02-01 18:33:27 +000060#define CURRENT_DS (CURRENT_STACK16->ds)
Alexandre Julliard8664b891996-04-05 14:58:24 +000061
Alexandre Julliard17216f51997-10-12 16:30:17 +000062/* varargs lists on the 16-bit stack */
Alexandre Julliardb67b1dc1995-02-16 16:47:09 +000063
Alexandre Julliard17216f51997-10-12 16:30:17 +000064typedef void *VA_LIST16;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000065
Alexandre Julliard17216f51997-10-12 16:30:17 +000066#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 Julliarda1089c51999-08-01 12:51:55 +000074
Alexandre Julliard60ce85c1998-02-01 18:33:27 +000075/* Push bytes on the 16-bit stack of a thread;
76 * return a segptr to the first pushed byte
77 */
Alexandre Julliarda1089c51999-08-01 12:51:55 +000078static 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 Julliard17216f51997-10-12 16:30:17 +000086
Alexandre Julliard60ce85c1998-02-01 18:33:27 +000087/* Pop bytes from the 16-bit stack of a thread */
Alexandre Julliarda1089c51999-08-01 12:51:55 +000088static 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 Julliardb67b1dc1995-02-16 16:47:09 +000095
Alexandre Julliarda845b881998-06-01 10:44:35 +000096/* Push a DWORD on the 32-bit stack */
Ulrich Weigand9b233bd1999-11-13 23:51:13 +000097static inline void WINE_UNUSED stack32_push( CONTEXT86 *context, DWORD val )
Alexandre Julliarda1089c51999-08-01 12:51:55 +000098{
Eric Poueche5efa0c2000-04-13 19:31:58 +000099 context->Esp -= sizeof(DWORD);
100 *(DWORD *)context->Esp = val;
Alexandre Julliarda1089c51999-08-01 12:51:55 +0000101}
Alexandre Julliarda845b881998-06-01 10:44:35 +0000102
103/* Pop a DWORD from the 32-bit stack */
Ulrich Weigand9b233bd1999-11-13 23:51:13 +0000104static inline DWORD WINE_UNUSED stack32_pop( CONTEXT86 *context )
Alexandre Julliarda1089c51999-08-01 12:51:55 +0000105{
Eric Poueche5efa0c2000-04-13 19:31:58 +0000106 DWORD ret = *(DWORD *)context->Esp;
107 context->Esp += sizeof(DWORD);
Alexandre Julliarda1089c51999-08-01 12:51:55 +0000108 return ret;
109}
Alexandre Julliarda845b881998-06-01 10:44:35 +0000110
Alexandre Julliardca22b331996-07-12 19:02:39 +0000111#endif /* __WINE_STACKFRAME_H */