2 * Copyright 1993 Robert J. Amstadt
3 * Copyright 1995 Alexandre Julliard
10 #include "registers.h"
11 #include "stackframe.h"
14 /* #define DEBUG_RELAY */
18 /* Make make_debug think these were really used */
22 /* Saved 16-bit stack for current process (Win16 only) */
23 WORD IF1632_Saved16_ss
= 0;
24 WORD IF1632_Saved16_sp
= 0;
26 /* Saved 32-bit stack for current process (Win16 only) */
27 DWORD IF1632_Saved32_esp
= 0;
28 SEGPTR IF1632_Stack32_base
= 0;
30 /* Original Unix stack */
31 DWORD IF1632_Original32_esp
;
34 /***********************************************************************
41 /* Allocate the code selector for CallTo16 routines */
43 extern void CALLTO16_Start(), CALLTO16_End();
44 extern void CALLTO16_Ret_word(), CALLTO16_Ret_long();
45 extern DWORD CALLTO16_RetAddr_word
, CALLTO16_RetAddr_long
;
47 codesel
= GLOBAL_CreateBlock( GMEM_FIXED
, (void *)CALLTO16_Start
,
48 (int)CALLTO16_End
- (int)CALLTO16_Start
,
49 0, TRUE
, TRUE
, FALSE
, NULL
);
50 if (!codesel
) return FALSE
;
52 /* Patch the return addresses for CallTo16 routines */
54 CALLTO16_RetAddr_word
=MAKELONG( (int)CALLTO16_Ret_word
-(int)CALLTO16_Start
,
56 CALLTO16_RetAddr_long
=MAKELONG( (int)CALLTO16_Ret_long
-(int)CALLTO16_Start
,
63 /***********************************************************************
64 * RELAY_DebugCallFrom16
66 void RELAY_DebugCallFrom16( int func_type
, char *args
,
67 void *entry_point
, SIGCONTEXT
*context
)
74 if (!debugging_relay
) return;
76 frame
= CURRENT_STACK16
;
77 printf( "Call %s(", BUILTIN_GetEntryPoint16( frame
->entry_cs
,
80 args16
= (char *)frame
->args
;
81 for (i
= 0; i
< strlen(args
); i
++)
103 printf( "0x%04x", *(WORD
*)args16
);
107 printf( "0x%08x", *(int *)args16
);
111 printf( "%04x:%04x", *(WORD
*)(args16
+2), *(WORD
*)args16
);
115 if (*args
) printf( "," );
117 printf( ") ret=%04x:%04x ds=%04x\n", frame
->cs
, frame
->ip
, frame
->ds
);
119 if (func_type
== 2) /* register function */
120 printf( " AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
121 AX_reg(context
), BX_reg(context
), CX_reg(context
),
122 DX_reg(context
), SI_reg(context
), DI_reg(context
),
123 ES_reg(context
), EFL_reg(context
) );
127 /***********************************************************************
128 * RELAY_DebugCallFrom16Ret
130 void RELAY_DebugCallFrom16Ret( int func_type
, int ret_val
, int args32
)
135 if (*(DWORD
*)PTR_SEG_TO_LIN(IF1632_Stack32_base
) != 0xDEADBEEF)
137 fprintf(stderr
, "Wine wrote past the end of the 32 bit stack. Please report this.\n");
138 exit(1); /* There's probably no point in going on */
140 if (!debugging_relay
) return;
142 frame
= CURRENT_STACK16
;
143 printf( "Ret %s() ", BUILTIN_GetEntryPoint16( frame
->entry_cs
,
149 printf( "retval=0x%08x ret=%04x:%04x ds=%04x\n",
150 ret_val
, frame
->cs
, frame
->ip
, frame
->ds
);
153 printf( "retval=0x%04x ret=%04x:%04x ds=%04x\n",
154 ret_val
& 0xffff, frame
->cs
, frame
->ip
, frame
->ds
);
157 printf( "retval=none ret=%04x:%04x ds=%04x\n",
158 frame
->cs
, frame
->ip
, frame
->ds
);
160 SIGCONTEXT
*context
= (SIGCONTEXT
*)&args32
;
161 printf( " AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
162 AX_reg(context
), BX_reg(context
), CX_reg(context
),
163 DX_reg(context
), SI_reg(context
), DI_reg(context
),
164 ES_reg(context
), EFL_reg(context
) );
171 /***********************************************************************
172 * RELAY_Unimplemented16
174 * This function is called for unimplemented 16-bit entry points (declared
175 * as 'stub' in the spec file).
177 void RELAY_Unimplemented16(void)
180 STACK16FRAME
*frame
= CURRENT_STACK16
;
181 fprintf(stderr
,"No handler for Win16 routine %s (called from %04x:%04x)\n",
182 BUILTIN_GetEntryPoint16(frame
->entry_cs
,frame
->entry_ip
,&ordinal
),
183 frame
->cs
, frame
->ip
);
184 TASK_KillCurrentTask(1);
188 /***********************************************************************
189 * RELAY_Unimplemented32
191 * This function is called for unimplemented 32-bit entry points (declared
192 * as 'stub' in the spec file).
193 * (The args are the same than for RELAY_DebugCallFrom32).
195 void RELAY_Unimplemented32( int nb_args
, void *relay_addr
,
196 void *entry_point
, int ebp
, int ret_addr
)
198 fprintf( stderr
, "No handler for Win32 routine %s (called from %08x)\n",
199 BUILTIN_GetEntryPoint32( relay_addr
), ret_addr
);
200 TASK_KillCurrentTask(1);
204 /***********************************************************************
205 * RELAY_DebugCallTo16
207 * 'stack' points to the called function address on the 32-bit stack.
212 * (stack+4) 16-bit ds
213 * (stack) func to call
215 void RELAY_DebugCallTo16( int* stack
, int nbargs
)
217 if (!debugging_relay
) return;
219 printf( "CallTo16(func=%04x:%04x,ds=%04x",
220 HIWORD(stack
[0]), LOWORD(stack
[0]), LOWORD(stack
[1]) );
222 while (nbargs
--) printf( ",0x%04x", *stack
++ );
227 /***********************************************************************
228 * RELAY_DebugCallFrom32
230 void RELAY_DebugCallFrom32( int nb_args
, void *relay_addr
,
231 void *entry_point
, int ebp
, int ret_addr
, int arg1
)
235 if (!debugging_relay
) return;
236 printf( "Call %s(", BUILTIN_GetEntryPoint32( relay_addr
));
237 for (parg
= &arg1
; nb_args
; parg
++, nb_args
--)
239 printf( "%08x", *parg
);
240 if (nb_args
> 1) printf( "," );
242 printf( ") ret=%08x\n", ret_addr
);
246 /***********************************************************************
247 * RELAY_DebugCallFrom32Ret
249 void RELAY_DebugCallFrom32Ret( int ret_val
, void *relay_addr
,
250 void *entry_point
, int ebp
, int ret_addr
)
252 if (!debugging_relay
) return;
253 printf( "Ret %s() retval=0x%08x ret=%08x\n",
254 BUILTIN_GetEntryPoint32( relay_addr
), ret_val
, ret_addr
);
258 /***********************************************************************
259 * RELAY_DebugCallTo32
261 void RELAY_DebugCallTo32( unsigned int func
, int nbargs
, unsigned int arg1
)
263 unsigned int *argptr
;
265 if (!debugging_relay
) return;
267 printf( "CallTo32(func=%08x", func
);
268 for (argptr
= &arg1
; nbargs
; nbargs
--, argptr
++)
269 printf( ",%08x", *argptr
);
274 /**********************************************************************
277 INT
Catch( LPCATCHBUF lpbuf
)
279 STACK16FRAME
*pFrame
= CURRENT_STACK16
;
281 /* Note: we don't save the current ss, as the catch buffer is */
282 /* only 9 words long. Hopefully no one will have the silly */
283 /* idea to change the current stack before calling Throw()... */
285 lpbuf
[0] = IF1632_Saved16_sp
;
286 lpbuf
[1] = LOWORD(IF1632_Saved32_esp
);
287 lpbuf
[2] = HIWORD(IF1632_Saved32_esp
);
288 lpbuf
[3] = pFrame
->saved_ss
;
289 lpbuf
[4] = pFrame
->saved_sp
;
290 lpbuf
[5] = pFrame
->ds
;
291 lpbuf
[6] = pFrame
->bp
;
292 lpbuf
[7] = pFrame
->ip
;
293 lpbuf
[8] = pFrame
->cs
;
298 /**********************************************************************
301 int Throw( LPCATCHBUF lpbuf
, int retval
)
303 STACK16FRAME
*pFrame
;
305 IF1632_Saved16_sp
= lpbuf
[0] - sizeof(WORD
);
306 IF1632_Saved32_esp
= MAKELONG( lpbuf
[1], lpbuf
[2] );
307 pFrame
= CURRENT_STACK16
;
308 pFrame
->saved_ss
= lpbuf
[3];
309 pFrame
->saved_sp
= lpbuf
[4];
310 pFrame
->ds
= lpbuf
[5];
311 pFrame
->bp
= lpbuf
[6];
312 pFrame
->ip
= lpbuf
[7];
313 pFrame
->cs
= lpbuf
[8];