Release 980315
[wine/gsoc_dplay.git] / relay32 / relay386.c
blob4115c7b6eb3d01b6048a3e900011dc81a7c3395a
1 /*
2 * 386-specific Win32 relay functions
4 * Copyright 1997 Alexandre Julliard
5 */
7 #ifdef __i386__
9 #include <assert.h>
10 #include "winnt.h"
11 #include "windows.h"
12 #include "builtin32.h"
13 #include "selectors.h"
14 #include "debug.h"
16 static void _dumpstr(unsigned char *s) {
17 fputs("\"",stdout);
18 while (*s) {
19 if (*s<' ') {
20 printf("\\0x%02x",*s++);
21 continue;
23 if (*s=='\\') {
24 fputs("\\\\",stdout);
25 s++;
26 continue;
28 fputc(*s++,stdout);
30 fputs("\"",stdout);
33 /***********************************************************************
34 * RELAY_CallFrom32
36 * Stack layout on entry to this function:
37 * ... ...
38 * (esp+12) arg2
39 * (esp+8) arg1
40 * (esp+4) ret_addr
41 * (esp) return addr to relay code
43 int RELAY_CallFrom32( int ret_addr, ... )
45 int i, ret;
46 char buffer[80];
47 FARPROC32 func;
48 unsigned int mask, typemask;
49 WORD fs;
51 int *args = &ret_addr;
52 /* Relay addr is the return address for this function */
53 BYTE *relay_addr = (BYTE *)args[-1];
54 WORD nb_args = *(WORD *)(relay_addr + 1) / sizeof(int);
56 assert(TRACE_ON(relay));
57 func = (FARPROC32)BUILTIN32_GetEntryPoint( buffer, relay_addr - 5,
58 &typemask );
59 printf( "Call %s(", buffer );
60 args++;
61 for (i = 0, mask = 3; i < nb_args; i++, mask <<= 2)
63 if (i) printf( "," );
64 if ((typemask & mask) && HIWORD(args[i]))
66 if (typemask & (2<<(2*i)))
68 char buff[80];
69 lstrcpynWtoA( buff, (LPWSTR)args[i], sizeof(buff) );
70 buff[sizeof(buff)-1]='\0';
71 printf( "%08x L", args[i] );
72 _dumpstr((unsigned char*)buff);
74 else {
75 printf( "%08x ", args[i] );
76 _dumpstr((unsigned char*)args[i]);
79 else printf( "%08x", args[i] );
81 GET_FS( fs );
82 printf( ") ret=%08x fs=%04x\n", ret_addr, fs );
83 if (*relay_addr == 0xc3) /* cdecl */
85 LRESULT (*cfunc)() = (LRESULT(*)())func;
86 switch(nb_args)
88 case 0: ret = cfunc(); break;
89 case 1: ret = cfunc(args[0]); break;
90 case 2: ret = cfunc(args[0],args[1]); break;
91 case 3: ret = cfunc(args[0],args[1],args[2]); break;
92 case 4: ret = cfunc(args[0],args[1],args[2],args[3]); break;
93 case 5: ret = cfunc(args[0],args[1],args[2],args[3],args[4]); break;
94 case 6: ret = cfunc(args[0],args[1],args[2],args[3],args[4],
95 args[5]); break;
96 case 7: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
97 args[6]); break;
98 case 8: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
99 args[6],args[7]); break;
100 case 9: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
101 args[6],args[7],args[8]); break;
102 case 10: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
103 args[6],args[7],args[8],args[9]); break;
104 case 11: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
105 args[6],args[7],args[8],args[9],args[10]); break;
106 case 12: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
107 args[6],args[7],args[8],args[9],args[10],
108 args[11]); break;
109 case 13: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
110 args[6],args[7],args[8],args[9],args[10],args[11],
111 args[12]); break;
112 case 14: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
113 args[6],args[7],args[8],args[9],args[10],args[11],
114 args[12],args[13]); break;
115 case 15: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
116 args[6],args[7],args[8],args[9],args[10],args[11],
117 args[12],args[13],args[14]); break;
118 default:
119 fprintf( stderr, "RELAY_CallFrom32: Unsupported nb args %d\n",
120 nb_args );
121 assert(FALSE);
124 else /* stdcall */
126 switch(nb_args)
128 case 0: ret = func(); break;
129 case 1: ret = func(args[0]); break;
130 case 2: ret = func(args[0],args[1]); break;
131 case 3: ret = func(args[0],args[1],args[2]); break;
132 case 4: ret = func(args[0],args[1],args[2],args[3]); break;
133 case 5: ret = func(args[0],args[1],args[2],args[3],args[4]); break;
134 case 6: ret = func(args[0],args[1],args[2],args[3],args[4],
135 args[5]); break;
136 case 7: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
137 args[6]); break;
138 case 8: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
139 args[6],args[7]); break;
140 case 9: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
141 args[6],args[7],args[8]); break;
142 case 10: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
143 args[6],args[7],args[8],args[9]); break;
144 case 11: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
145 args[6],args[7],args[8],args[9],args[10]); break;
146 case 12: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
147 args[6],args[7],args[8],args[9],args[10],
148 args[11]); break;
149 case 13: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
150 args[6],args[7],args[8],args[9],args[10],args[11],
151 args[12]); break;
152 case 14: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
153 args[6],args[7],args[8],args[9],args[10],args[11],
154 args[12],args[13]); break;
155 case 15: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
156 args[6],args[7],args[8],args[9],args[10],args[11],
157 args[12],args[13],args[14]); break;
158 default:
159 fprintf( stderr, "RELAY_CallFrom32: Unsupported nb args %d\n",
160 nb_args );
161 assert(FALSE);
164 printf( "Ret %s() retval=%08x ret=%08x fs=%04x\n",
165 buffer, ret, ret_addr, fs );
166 return ret;
170 /***********************************************************************
171 * RELAY_CallFrom32Regs
173 * 'stack' points to the relay addr on the stack.
174 * Stack layout:
175 * ... ...
176 * (esp+216) ret_addr
177 * (esp+212) return to relay debugging code (only when debugging(relay))
178 * (esp+208) entry point to call
179 * (esp+4) CONTEXT
180 * (esp) return addr to relay code
182 void RELAY_CallFrom32Regs( CONTEXT context,
183 void (CALLBACK *entry_point)(CONTEXT *),
184 BYTE *relay_addr, int ret_addr )
186 if (!TRACE_ON(relay))
188 /* Simply call the entry point */
189 entry_point( &context );
191 else
193 char buffer[80];
194 unsigned int typemask;
196 __RESTORE_ES;
197 /* Fixup the context structure because of the extra parameter */
198 /* pushed by the relay debugging code */
200 EIP_reg(&context) = ret_addr;
201 ESP_reg(&context) += sizeof(int);
203 BUILTIN32_GetEntryPoint( buffer, relay_addr - 5, &typemask );
204 printf("Call %s(regs) ret=%08x\n", buffer, ret_addr );
205 printf(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
206 EAX_reg(&context), EBX_reg(&context), ECX_reg(&context),
207 EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
208 printf(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
209 EBP_reg(&context), ESP_reg(&context), EIP_reg(&context),
210 DS_reg(&context), ES_reg(&context), FS_reg(&context),
211 GS_reg(&context), EFL_reg(&context) );
213 /* Now call the real function */
214 entry_point( &context );
216 printf("Ret %s() retval=regs ret=%08x\n", buffer, ret_addr );
217 printf(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
218 EAX_reg(&context), EBX_reg(&context), ECX_reg(&context),
219 EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
220 printf(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
221 EBP_reg(&context), ESP_reg(&context), EIP_reg(&context),
222 DS_reg(&context), ES_reg(&context), FS_reg(&context),
223 GS_reg(&context), EFL_reg(&context) );
227 #endif /* __i386__ */