2 * Copyright 1993 Robert J. Amstadt
3 * Copyright 1995 Alexandre Julliard
10 #include "registers.h"
11 #include "stackframe.h"
13 /* #define DEBUG_RELAY */
17 /* Make make_debug think these were really used */
21 /* Saved 16-bit stack for current process (Win16 only) */
22 WORD IF1632_Saved16_ss
= 0;
23 WORD IF1632_Saved16_sp
= 0;
25 /* Saved 32-bit stack for current process (Win16 only) */
26 DWORD IF1632_Saved32_esp
= 0;
27 SEGPTR IF1632_Stack32_base
= 0;
29 /* Original Unix stack */
30 DWORD IF1632_Original32_esp
;
33 /***********************************************************************
40 /* Allocate the code selector for CallTo16 routines */
42 extern void CALLTO16_Start(), CALLTO16_End();
43 extern void CALLTO16_Ret_word(), CALLTO16_Ret_long();
44 extern DWORD CALLTO16_RetAddr_word
, CALLTO16_RetAddr_long
;
46 codesel
= GLOBAL_CreateBlock( GMEM_FIXED
, (void *)CALLTO16_Start
,
47 (int)CALLTO16_End
- (int)CALLTO16_Start
,
48 0, TRUE
, TRUE
, FALSE
, NULL
);
49 if (!codesel
) return FALSE
;
51 /* Patch the return addresses for CallTo16 routines */
53 CALLTO16_RetAddr_word
=MAKELONG( (int)CALLTO16_Ret_word
-(int)CALLTO16_Start
,
55 CALLTO16_RetAddr_long
=MAKELONG( (int)CALLTO16_Ret_long
-(int)CALLTO16_Start
,
62 /***********************************************************************
63 * RELAY_DebugCallFrom16
65 void RELAY_DebugCallFrom16( int func_type
, char *args
,
66 void *entry_point
, int args32
)
74 if (!debugging_relay
) return;
76 frame
= CURRENT_STACK16
;
77 pModule
= BUILTIN_GetEntryPoint( frame
->entry_cs
, frame
->entry_ip
,
79 printf( "Call %.*s.%d: %.*s(",
80 *((BYTE
*)pModule
+ pModule
->name_table
),
81 (char *)pModule
+ pModule
->name_table
+ 1,
82 ordinal
, *name
, name
+ 1 );
84 args16
= (char *)frame
->args
;
85 for (i
= 0; i
< strlen(args
); i
++)
107 printf( "0x%04x", *(WORD
*)args16
);
111 printf( "0x%08x", *(int *)args16
);
115 printf( "%04x:%04x", *(WORD
*)(args16
+2), *(WORD
*)args16
);
119 if (*args
) printf( "," );
121 printf( ") ret=%04x:%04x ds=%04x\n", frame
->cs
, frame
->ip
, frame
->ds
);
123 if (func_type
== 2) /* register function */
125 struct sigcontext_struct
*context
= (struct sigcontext_struct
*)&args32
;
126 printf( " AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
127 AX_reg(context
), BX_reg(context
), CX_reg(context
),
128 DX_reg(context
), SI_reg(context
), DI_reg(context
),
129 ES_reg(context
), EFL_reg(context
) );
134 /***********************************************************************
135 * RELAY_DebugCallFrom16Ret
137 void RELAY_DebugCallFrom16Ret( int func_type
, int ret_val
, int args32
)
144 if (*(DWORD
*)PTR_SEG_TO_LIN(IF1632_Stack32_base
) != 0xDEADBEEF)
146 fprintf(stderr
, "Wine wrote past the end of the 32 bit stack. Please report this.\n");
147 exit(1); /* There's probably no point in going on */
149 if (!debugging_relay
) return;
151 frame
= CURRENT_STACK16
;
152 pModule
= BUILTIN_GetEntryPoint( frame
->entry_cs
, frame
->entry_ip
,
154 printf( "Ret %.*s.%d: %.*s() ",
155 *((BYTE
*)pModule
+ pModule
->name_table
),
156 (char *)pModule
+ pModule
->name_table
+ 1,
157 ordinal
, *name
, name
+ 1 );
162 printf( "retval=0x%08x ret=%04x:%04x ds=%04x\n",
163 ret_val
, frame
->cs
, frame
->ip
, frame
->ds
);
166 printf( "retval=0x%04x ret=%04x:%04x ds=%04x\n",
167 ret_val
& 0xffff, frame
->cs
, frame
->ip
, frame
->ds
);
170 printf( "retval=none ret=%04x:%04x ds=%04x\n",
171 frame
->cs
, frame
->ip
, frame
->ds
);
173 struct sigcontext_struct
*context
= (struct sigcontext_struct
*)&args32
;
174 printf( " AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
175 AX_reg(context
), BX_reg(context
), CX_reg(context
),
176 DX_reg(context
), SI_reg(context
), DI_reg(context
),
177 ES_reg(context
), EFL_reg(context
) );
184 /***********************************************************************
185 * RELAY_Unimplemented16
187 * This function is called for unimplemented 16-bit entry points (declared
188 * as 'stub' in the spec file).
190 void RELAY_Unimplemented16(void)
194 STACK16FRAME
*frame
= CURRENT_STACK16
;
195 NE_MODULE
*pModule
= BUILTIN_GetEntryPoint( frame
->entry_cs
,
198 fprintf( stderr
, "No handler for routine %.*s.%d (%.*s)\n",
199 *((BYTE
*)pModule
+ pModule
->name_table
),
200 (char *)pModule
+ pModule
->name_table
+ 1,
201 ordinal
, *name
, name
+ 1 );
206 /***********************************************************************
207 * RELAY_Unimplemented32
209 * This function is called for unimplemented 32-bit entry points (declared
210 * as 'stub' in the spec file).
211 * (The args are the same than for RELAY_DebugCallFrom32).
213 void RELAY_Unimplemented32( int nb_args
, void *entry_point
,
214 const char *func_name
)
216 fprintf( stderr
, "No handler for Win32 routine %s\n", func_name
);
221 /***********************************************************************
222 * RELAY_DebugCallTo16
224 * 'stack' points to the called function address on the 32-bit stack.
229 * (stack+4) 16-bit ds
230 * (stack) func to call
232 void RELAY_DebugCallTo16( int* stack
, int nbargs
)
234 if (!debugging_relay
) return;
236 printf( "CallTo16(func=%04x:%04x,ds=%04x",
237 HIWORD(stack
[0]), LOWORD(stack
[0]), LOWORD(stack
[1]) );
239 while (nbargs
--) printf( ",0x%04x", *stack
++ );
244 /***********************************************************************
245 * RELAY_DebugCallFrom32
247 void RELAY_DebugCallFrom32( int nb_args
, void *entry_point
,
248 const char *func_name
, int ebp
, int ret_addr
,
252 if (!debugging_relay
) return;
253 printf( "Call %s(", func_name
);
254 for (parg
= &arg1
; nb_args
; parg
++, nb_args
--)
256 printf( "%08x", *parg
);
257 if (nb_args
> 1) printf( "," );
259 printf( ") ret=%08x\n", ret_addr
);
263 /***********************************************************************
264 * RELAY_DebugCallFrom32Ret
266 void RELAY_DebugCallFrom32Ret( int ret_val
, void *entry_point
,
267 const char *func_name
, int ebp
, int ret_addr
)
269 if (!debugging_relay
) return;
270 printf( "Ret %s() retval=0x%08x ret=%08x\n",
271 func_name
, ret_val
, ret_addr
);
275 /***********************************************************************
276 * RELAY_DebugCallTo32
278 void RELAY_DebugCallTo32( unsigned int func
, int nbargs
, unsigned int arg1
)
280 unsigned int *argptr
;
282 if (!debugging_relay
) return;
284 printf( "CallTo32(func=%08x", func
);
285 for (argptr
= &arg1
; nbargs
; nbargs
--, argptr
++)
286 printf( ",%08x", *argptr
);
291 /**********************************************************************
294 INT
Catch( LPCATCHBUF lpbuf
)
296 STACK16FRAME
*pFrame
= CURRENT_STACK16
;
298 /* Note: we don't save the current ss, as the catch buffer is */
299 /* only 9 words long. Hopefully no one will have the silly */
300 /* idea to change the current stack before calling Throw()... */
302 lpbuf
[0] = IF1632_Saved16_sp
;
303 lpbuf
[1] = LOWORD(IF1632_Saved32_esp
);
304 lpbuf
[2] = HIWORD(IF1632_Saved32_esp
);
305 lpbuf
[3] = pFrame
->saved_ss
;
306 lpbuf
[4] = pFrame
->saved_sp
;
307 lpbuf
[5] = pFrame
->ds
;
308 lpbuf
[6] = pFrame
->bp
;
309 lpbuf
[7] = pFrame
->ip
;
310 lpbuf
[8] = pFrame
->cs
;
315 /**********************************************************************
318 int Throw( LPCATCHBUF lpbuf
, int retval
)
320 STACK16FRAME
*pFrame
;
322 IF1632_Saved16_sp
= lpbuf
[0] - sizeof(WORD
);
323 IF1632_Saved32_esp
= MAKELONG( lpbuf
[1], lpbuf
[2] );
324 pFrame
= CURRENT_STACK16
;
325 pFrame
->saved_ss
= lpbuf
[3];
326 pFrame
->saved_sp
= lpbuf
[4];
327 pFrame
->ds
= lpbuf
[5];
328 pFrame
->bp
= lpbuf
[6];
329 pFrame
->ip
= lpbuf
[7];
330 pFrame
->cs
= lpbuf
[8];