2 * 386-specific Win32 relay functions
4 * Copyright 1997 Alexandre Julliard
12 #include "builtin32.h"
13 #include "selectors.h"
16 static void _dumpstr(unsigned char *s
) {
20 printf("\\0x%02x",*s
++);
33 /***********************************************************************
36 * Stack layout on entry to this function:
41 * (esp) return addr to relay code
43 int RELAY_CallFrom32( int ret_addr
, ... )
48 unsigned int mask
, typemask
;
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,
59 printf( "Call %s(", buffer
);
61 for (i
= 0, mask
= 3; i
< nb_args
; i
++, mask
<<= 2)
64 if ((typemask
& mask
) && HIWORD(args
[i
]))
66 if (typemask
& (2<<(2*i
)))
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
);
75 printf( "%08x ", args
[i
] );
76 _dumpstr((unsigned char*)args
[i
]);
79 else printf( "%08x", args
[i
] );
82 printf( ") ret=%08x fs=%04x\n", ret_addr
, fs
);
83 if (*relay_addr
== 0xc3) /* cdecl */
85 LRESULT (*cfunc
)() = (LRESULT(*)())func
;
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],
96 case 7: ret
= cfunc(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
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],
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],
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;
119 fprintf( stderr
, "RELAY_CallFrom32: Unsupported nb args %d\n",
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],
136 case 7: ret
= func(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
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],
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],
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;
159 fprintf( stderr
, "RELAY_CallFrom32: Unsupported nb args %d\n",
164 printf( "Ret %s() retval=%08x ret=%08x fs=%04x\n",
165 buffer
, ret
, ret_addr
, fs
);
170 /***********************************************************************
171 * RELAY_CallFrom32Regs
173 * 'stack' points to the relay addr on the stack.
177 * (esp+212) return to relay debugging code (only when debugging(relay))
178 * (esp+208) entry point to call
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
);
194 unsigned int typemask
;
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__ */