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 */
23 /***********************************************************************
26 BOOL32
RELAY_Init(void)
30 /* Allocate the code selector for CallTo16 routines */
32 extern void CALLTO16_Start(), CALLTO16_End();
33 extern void CALLTO16_Ret_word(), CALLTO16_Ret_long();
34 extern DWORD CALLTO16_RetAddr_word
, CALLTO16_RetAddr_long
;
36 codesel
= GLOBAL_CreateBlock( GMEM_FIXED
, (void *)CALLTO16_Start
,
37 (int)CALLTO16_End
- (int)CALLTO16_Start
,
38 0, TRUE
, TRUE
, FALSE
, NULL
);
39 if (!codesel
) return FALSE
;
41 /* Patch the return addresses for CallTo16 routines */
43 CALLTO16_RetAddr_word
=MAKELONG( (int)CALLTO16_Ret_word
-(int)CALLTO16_Start
,
45 CALLTO16_RetAddr_long
=MAKELONG( (int)CALLTO16_Ret_long
-(int)CALLTO16_Start
,
52 /***********************************************************************
53 * RELAY_DebugCallFrom16
55 void RELAY_DebugCallFrom16( int func_type
, char *args
,
56 void *entry_point
, SIGCONTEXT
*context
)
63 if (!debugging_relay
) return;
65 frame
= CURRENT_STACK16
;
66 printf( "Call %s(", BUILTIN_GetEntryPoint16( frame
->entry_cs
,
69 args16
= (char *)frame
->args
;
70 for (i
= 0; i
< strlen(args
); i
++)
92 printf( "0x%04x", *(WORD
*)args16
);
96 printf( "0x%08x", *(int *)args16
);
100 printf( "%04x:%04x", *(WORD
*)(args16
+2), *(WORD
*)args16
);
104 if (*args
) printf( "," );
106 printf( ") ret=%04x:%04x ds=%04x\n", frame
->cs
, frame
->ip
, frame
->ds
);
108 if (func_type
== 2) /* register function */
109 printf( " AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
110 AX_reg(context
), BX_reg(context
), CX_reg(context
),
111 DX_reg(context
), SI_reg(context
), DI_reg(context
),
112 ES_reg(context
), EFL_reg(context
) );
116 /***********************************************************************
117 * RELAY_DebugCallFrom16Ret
119 void RELAY_DebugCallFrom16Ret( int func_type
, int ret_val
, SIGCONTEXT
*context
)
124 if (*(DWORD
*)PTR_SEG_TO_LIN(IF1632_Stack32_base
) != 0xDEADBEEF)
126 fprintf(stderr
, "Wine wrote past the end of the 32 bit stack. Please report this.\n");
127 exit(1); /* There's probably no point in going on */
129 if (!debugging_relay
) return;
131 frame
= CURRENT_STACK16
;
132 printf( "Ret %s() ", BUILTIN_GetEntryPoint16( frame
->entry_cs
,
138 printf( "retval=0x%08x ret=%04x:%04x ds=%04x\n",
139 ret_val
, frame
->cs
, frame
->ip
, frame
->ds
);
142 printf( "retval=0x%04x ret=%04x:%04x ds=%04x\n",
143 ret_val
& 0xffff, frame
->cs
, frame
->ip
, frame
->ds
);
146 printf( "retval=none ret=%04x:%04x ds=%04x\n",
147 frame
->cs
, frame
->ip
, frame
->ds
);
148 printf( " AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
149 AX_reg(context
), BX_reg(context
), CX_reg(context
),
150 DX_reg(context
), SI_reg(context
), DI_reg(context
),
151 ES_reg(context
), EFL_reg(context
) );
157 /***********************************************************************
158 * RELAY_Unimplemented16
160 * This function is called for unimplemented 16-bit entry points (declared
161 * as 'stub' in the spec file).
163 void RELAY_Unimplemented16(void)
166 STACK16FRAME
*frame
= CURRENT_STACK16
;
167 fprintf(stderr
,"No handler for Win16 routine %s (called from %04x:%04x)\n",
168 BUILTIN_GetEntryPoint16(frame
->entry_cs
,frame
->entry_ip
,&ordinal
),
169 frame
->cs
, frame
->ip
);
170 TASK_KillCurrentTask(1);
174 /***********************************************************************
175 * RELAY_Unimplemented32
177 * This function is called for unimplemented 32-bit entry points (declared
178 * as 'stub' in the spec file).
179 * (The args are the same than for RELAY_DebugCallFrom32).
181 void RELAY_Unimplemented32( int nb_args
, void *relay_addr
,
182 void *entry_point
, int ebp
, int ret_addr
)
184 fprintf( stderr
, "No handler for Win32 routine %s (called from %08x)\n",
185 BUILTIN_GetEntryPoint32( relay_addr
), ret_addr
);
186 TASK_KillCurrentTask(1);
190 /***********************************************************************
191 * RELAY_DebugCallTo16
193 * 'stack' points to the called function address on the 32-bit stack.
198 * (stack+4) 16-bit ds
199 * (stack) func to call
201 void RELAY_DebugCallTo16( int* stack
, int nbargs
)
203 if (!debugging_relay
) return;
205 printf( "CallTo16(func=%04x:%04x,ds=%04x",
206 HIWORD(stack
[0]), LOWORD(stack
[0]), LOWORD(stack
[1]) );
208 while (nbargs
--) printf( ",0x%04x", *stack
++ );
213 /***********************************************************************
214 * RELAY_DebugCallFrom32
216 void RELAY_DebugCallFrom32( int nb_args
, void *relay_addr
,
217 void *entry_point
, int ebp
, int ret_addr
, int arg1
)
221 if (!debugging_relay
) return;
222 printf( "Call %s(", BUILTIN_GetEntryPoint32( relay_addr
));
223 for (parg
= &arg1
; nb_args
; parg
++, nb_args
--)
225 printf( "%08x", *parg
);
226 if (nb_args
> 1) printf( "," );
228 printf( ") ret=%08x\n", ret_addr
);
232 /***********************************************************************
233 * RELAY_DebugCallFrom32Ret
235 void RELAY_DebugCallFrom32Ret( int ret_val
, void *relay_addr
,
236 void *entry_point
, int ebp
, int ret_addr
)
238 if (!debugging_relay
) return;
239 printf( "Ret %s() retval=0x%08x ret=%08x\n",
240 BUILTIN_GetEntryPoint32( relay_addr
), ret_val
, ret_addr
);
244 /***********************************************************************
245 * RELAY_DebugCallTo32
247 void RELAY_DebugCallTo32( unsigned int func
, int nbargs
, unsigned int arg1
)
249 unsigned int *argptr
;
251 if (!debugging_relay
) return;
253 printf( "CallTo32(func=%08x", func
);
254 for (argptr
= &arg1
; nbargs
; nbargs
--, argptr
++)
255 printf( ",%08x", *argptr
);
260 /**********************************************************************
263 INT16
Catch( LPCATCHBUF lpbuf
)
265 STACK16FRAME
*pFrame
= CURRENT_STACK16
;
267 /* Note: we don't save the current ss, as the catch buffer is */
268 /* only 9 words long. Hopefully no one will have the silly */
269 /* idea to change the current stack before calling Throw()... */
271 lpbuf
[0] = IF1632_Saved16_sp
;
272 lpbuf
[1] = LOWORD(IF1632_Saved32_esp
);
273 lpbuf
[2] = HIWORD(IF1632_Saved32_esp
);
274 lpbuf
[3] = pFrame
->saved_ss
;
275 lpbuf
[4] = pFrame
->saved_sp
;
276 lpbuf
[5] = pFrame
->ds
;
277 lpbuf
[6] = pFrame
->bp
;
278 lpbuf
[7] = pFrame
->ip
;
279 lpbuf
[8] = pFrame
->cs
;
284 /**********************************************************************
287 INT16
Throw( LPCATCHBUF lpbuf
, INT16 retval
)
289 STACK16FRAME
*pFrame
;
291 IF1632_Saved16_sp
= lpbuf
[0] - sizeof(WORD
);
292 IF1632_Saved32_esp
= MAKELONG( lpbuf
[1], lpbuf
[2] );
293 pFrame
= CURRENT_STACK16
;
294 pFrame
->saved_ss
= lpbuf
[3];
295 pFrame
->saved_sp
= lpbuf
[4];
296 pFrame
->ds
= lpbuf
[5];
297 pFrame
->bp
= lpbuf
[6];
298 pFrame
->ip
= lpbuf
[7];
299 pFrame
->cs
= lpbuf
[8];