2 * 386-specific Win32 relay functions
4 * Copyright 1997 Alexandre Julliard
12 #include "builtin32.h"
17 /***********************************************************************
20 * Stack layout on entry to this function:
25 * (esp) return addr to relay code
27 int RELAY_CallFrom32( int ret_addr
, ... )
32 unsigned int mask
, typemask
;
34 int *args
= &ret_addr
;
35 /* Relay addr is the return address for this function */
36 BYTE
*relay_addr
= (BYTE
*)args
[-1];
37 WORD nb_args
= *(WORD
*)(relay_addr
+ 1) / sizeof(int);
39 assert(debugging_relay
);
40 func
= (FARPROC32
)BUILTIN32_GetEntryPoint( buffer
, relay_addr
- 5,
42 printf( "Call %s(", buffer
);
44 for (i
= 0, mask
= 3; i
< nb_args
; i
++, mask
<<= 2)
47 if ((typemask
& mask
) && HIWORD(args
[i
]))
49 if (typemask
& (2<<(2*i
)))
52 lstrcpynWtoA( buff
, (LPWSTR
)args
[i
], sizeof(buff
) );
53 printf( "%08x L\"%s\"", args
[i
], buff
);
55 else printf( "%08x \"%s\"", args
[i
], (char *)args
[i
] );
57 else printf( "%08x", args
[i
] );
59 printf( ") ret=%08x\n", ret_addr
);
60 if (*relay_addr
== 0xc3) /* cdecl */
62 LRESULT (*cfunc
)() = (LRESULT(*)())func
;
65 case 0: ret
= cfunc(); break;
66 case 1: ret
= cfunc(args
[0]); break;
67 case 2: ret
= cfunc(args
[0],args
[1]); break;
68 case 3: ret
= cfunc(args
[0],args
[1],args
[2]); break;
69 case 4: ret
= cfunc(args
[0],args
[1],args
[2],args
[3]); break;
70 case 5: ret
= cfunc(args
[0],args
[1],args
[2],args
[3],args
[4]); break;
71 case 6: ret
= cfunc(args
[0],args
[1],args
[2],args
[3],args
[4],
73 case 7: ret
= cfunc(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
75 case 8: ret
= cfunc(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
76 args
[6],args
[7]); break;
77 case 9: ret
= cfunc(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
78 args
[6],args
[7],args
[8]); break;
79 case 10: ret
= cfunc(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
80 args
[6],args
[7],args
[8],args
[9]); break;
81 case 11: ret
= cfunc(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
82 args
[6],args
[7],args
[8],args
[9],args
[10]); break;
83 case 12: ret
= cfunc(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
84 args
[6],args
[7],args
[8],args
[9],args
[10],
86 case 13: ret
= cfunc(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
87 args
[6],args
[7],args
[8],args
[9],args
[10],args
[11],
89 case 14: ret
= cfunc(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
90 args
[6],args
[7],args
[8],args
[9],args
[10],args
[11],
91 args
[12],args
[13]); break;
92 case 15: ret
= cfunc(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
93 args
[6],args
[7],args
[8],args
[9],args
[10],args
[11],
94 args
[12],args
[13],args
[14]); break;
96 fprintf( stderr
, "RELAY_CallFrom32: Unsupported nb args %d\n",
105 case 0: ret
= func(); break;
106 case 1: ret
= func(args
[0]); break;
107 case 2: ret
= func(args
[0],args
[1]); break;
108 case 3: ret
= func(args
[0],args
[1],args
[2]); break;
109 case 4: ret
= func(args
[0],args
[1],args
[2],args
[3]); break;
110 case 5: ret
= func(args
[0],args
[1],args
[2],args
[3],args
[4]); break;
111 case 6: ret
= func(args
[0],args
[1],args
[2],args
[3],args
[4],
113 case 7: ret
= func(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
115 case 8: ret
= func(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
116 args
[6],args
[7]); break;
117 case 9: ret
= func(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
118 args
[6],args
[7],args
[8]); break;
119 case 10: ret
= func(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
120 args
[6],args
[7],args
[8],args
[9]); break;
121 case 11: ret
= func(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
122 args
[6],args
[7],args
[8],args
[9],args
[10]); break;
123 case 12: ret
= func(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
124 args
[6],args
[7],args
[8],args
[9],args
[10],
126 case 13: ret
= func(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
127 args
[6],args
[7],args
[8],args
[9],args
[10],args
[11],
129 case 14: ret
= func(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
130 args
[6],args
[7],args
[8],args
[9],args
[10],args
[11],
131 args
[12],args
[13]); break;
132 case 15: ret
= func(args
[0],args
[1],args
[2],args
[3],args
[4],args
[5],
133 args
[6],args
[7],args
[8],args
[9],args
[10],args
[11],
134 args
[12],args
[13],args
[14]); break;
136 fprintf( stderr
, "RELAY_CallFrom32: Unsupported nb args %d\n",
141 printf( "Ret %s() retval=%08x ret=%08x\n", buffer
, ret
, ret_addr
);
146 /***********************************************************************
147 * RELAY_CallFrom32Regs
149 * 'stack' points to the relay addr on the stack.
153 * (esp+212) return to relay debugging code (only when debugging_relay)
154 * (esp+208) entry point to call
156 * (esp) return addr to relay code
158 void RELAY_CallFrom32Regs( CONTEXT context
,
159 void (CALLBACK
*entry_point
)(CONTEXT
*),
160 BYTE
*relay_addr
, int ret_addr
)
162 if (!debugging_relay
)
164 /* Simply call the entry point */
165 entry_point( &context
);
170 unsigned int typemask
;
173 /* Fixup the context structure because of the extra parameter */
174 /* pushed by the relay debugging code */
176 EIP_reg(&context
) = ret_addr
;
177 ESP_reg(&context
) += sizeof(int);
179 BUILTIN32_GetEntryPoint( buffer
, relay_addr
- 5, &typemask
);
180 printf("Call %s(regs) ret=%08x\n", buffer
, ret_addr
);
181 printf(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
182 EAX_reg(&context
), EBX_reg(&context
), ECX_reg(&context
),
183 EDX_reg(&context
), ESI_reg(&context
), EDI_reg(&context
) );
184 printf(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
185 EBP_reg(&context
), ESP_reg(&context
), EIP_reg(&context
),
186 DS_reg(&context
), ES_reg(&context
), FS_reg(&context
),
187 GS_reg(&context
), EFL_reg(&context
) );
189 /* Now call the real function */
190 entry_point( &context
);
192 printf("Ret %s() retval=regs ret=%08x\n", buffer
, ret_addr
);
193 printf(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
194 EAX_reg(&context
), EBX_reg(&context
), ECX_reg(&context
),
195 EDX_reg(&context
), ESI_reg(&context
), EDI_reg(&context
) );
196 printf(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
197 EBP_reg(&context
), ESP_reg(&context
), EIP_reg(&context
),
198 DS_reg(&context
), ES_reg(&context
), FS_reg(&context
),
199 GS_reg(&context
), EFL_reg(&context
) );
203 #endif /* __i386__ */