- Don't prepend fastcall forward's target with @. Fixes binding issues in videoprt...
[reactos.git] / reactos / tools / winebuild / ros_diff.patch
1 Index: build.h
2 ===================================================================
3 --- build.h (Revision 4)
4 +++ build.h (Arbeitskopie)
5 @@ -38,6 +38,8 @@
6 #define min(a,b) (((a) < (b)) ? (a) : (b))
7 #endif
8
9 +#define EXEEXT ".exe"
10 +
11 typedef enum
12 {
13 TYPE_VARIABLE, /* variable */
14 @@ -47,6 +49,7 @@
15 TYPE_STDCALL, /* stdcall function (Win32) */
16 TYPE_CDECL, /* cdecl function (Win32) */
17 TYPE_VARARGS, /* varargs function (Win32) */
18 + TYPE_FASTCALL, /* fastcall function (Win32) */
19 TYPE_EXTERN, /* external symbol (Win32) */
20 TYPE_NBTYPES
21 } ORD_TYPE;
22 @@ -269,6 +272,7 @@
23 extern void BuildSpec16File( DLLSPEC *spec );
24 extern void BuildSpec32File( DLLSPEC *spec );
25 extern void BuildDef32File( DLLSPEC *spec );
26 +extern void BuildPedllFile( DLLSPEC *spec );
27
28 extern void add_16bit_exports( DLLSPEC *spec32, DLLSPEC *spec16 );
29 extern int parse_spec_file( FILE *file, DLLSPEC *spec );
30 Index: main.c
31 ===================================================================
32 --- main.c (Revision 4)
33 +++ main.c (Arbeitskopie)
34 @@ -48,9 +48,9 @@
35 int link_ext_symbols = 0;
36 int force_pointer_size = 0;
37
38 -#ifdef __i386__
39 +#if defined(TARGET_i386)
40 enum target_cpu target_cpu = CPU_x86;
41 -#elif defined(__x86_64__)
42 +#elif defined(TARGET_amd64)
43 enum target_cpu target_cpu = CPU_x86_64;
44 #elif defined(__sparc__)
45 enum target_cpu target_cpu = CPU_SPARC;
46 @@ -58,7 +58,7 @@
47 enum target_cpu target_cpu = CPU_ALPHA;
48 #elif defined(__powerpc__)
49 enum target_cpu target_cpu = CPU_POWERPC;
50 -#elif defined(__arm__)
51 +#elif defined(TARGET_arm)
52 enum target_cpu target_cpu = CPU_ARM;
53 #else
54 #error Unsupported CPU
55 @@ -102,7 +102,8 @@
56 MODE_DEF,
57 MODE_RELAY16,
58 MODE_RELAY32,
59 - MODE_RESOURCES
60 + MODE_RESOURCES,
61 + MODE_PEDLL
62 };
63
64 static enum exec_mode_values exec_mode = MODE_NONE;
65 @@ -253,6 +254,7 @@
66 " --relay16 Build the 16-bit relay assembly routines\n"
67 " --relay32 Build the 32-bit relay assembly routines\n"
68 " --resources Build a .o file for the resource files\n\n"
69 +" --pedll Build a .c file for PE dll\n\n"
70 "The mode options are mutually exclusive; you must specify one and only one.\n\n";
71
72 enum long_options_values
73 @@ -272,7 +274,8 @@
74 LONG_OPT_RESOURCES,
75 LONG_OPT_SAVE_TEMPS,
76 LONG_OPT_SUBSYSTEM,
77 - LONG_OPT_VERSION
78 + LONG_OPT_VERSION,
79 + LONG_OPT_PEDLL
80 };
81
82 static const char short_options[] = "C:D:E:F:H:I:K:L:M:N:b:d:e:f:hi:kl:m:o:r:u:vw";
83 @@ -295,6 +298,7 @@
84 { "save-temps", 0, 0, LONG_OPT_SAVE_TEMPS },
85 { "subsystem", 1, 0, LONG_OPT_SUBSYSTEM },
86 { "version", 0, 0, LONG_OPT_VERSION },
87 + { "pedll", 1, 0, LONG_OPT_PEDLL },
88 /* aliases for short options */
89 { "target", 1, 0, 'b' },
90 { "delay-lib", 1, 0, 'd' },
91 @@ -497,6 +501,11 @@
92 case LONG_OPT_VERSION:
93 printf( "winebuild version " PACKAGE_VERSION "\n" );
94 exit(0);
95 + case LONG_OPT_PEDLL:
96 + set_exec_mode( MODE_PEDLL );
97 + spec_file_name = xstrdup( optarg );
98 + set_dll_file_name( optarg, spec );
99 + break;
100 case '?':
101 usage(1);
102 break;
103 @@ -652,6 +661,11 @@
104 if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
105 BuildRelays32();
106 break;
107 + case MODE_PEDLL:
108 + if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
109 + if (!parse_input_file( spec )) break;
110 + BuildPedllFile( spec );
111 + break;
112 case MODE_RESOURCES:
113 load_resources( argv, spec );
114 output_res_o_file( spec );
115 Index: parser.c
116 ===================================================================
117 --- parser.c (Revision 4)
118 +++ parser.c (Arbeitskopie)
119 @@ -56,6 +56,7 @@
120 "stdcall", /* TYPE_STDCALL */
121 "cdecl", /* TYPE_CDECL */
122 "varargs", /* TYPE_VARARGS */
123 + "fastcall", /* TYPE_FASTCALL */
124 "extern" /* TYPE_EXTERN */
125 };
126
127 @@ -521,6 +522,7 @@
128 case TYPE_STDCALL:
129 case TYPE_VARARGS:
130 case TYPE_CDECL:
131 + case TYPE_FASTCALL:
132 if (!parse_spec_export( odp, spec )) goto error;
133 break;
134 case TYPE_ABS:
135 Index: res32.c
136 ===================================================================
137 --- res32.c (Revision 4)
138 +++ res32.c (Arbeitskopie)
139 @@ -35,12 +35,14 @@
140 #include "build.h"
141
142 typedef unsigned short WCHAR;
143 +typedef unsigned short WORD;
144 +typedef unsigned int DWORD;
145
146 /* Unicode string or integer id */
147 struct string_id
148 {
149 WCHAR *str; /* ptr to Unicode string */
150 - unsigned short id; /* integer id if str is NULL */
151 + WORD id; /* integer id if str is NULL */
152 };
153
154 /* descriptor for a resource */
155 @@ -195,7 +197,7 @@
156 /* all values must be zero except header size */
157 static int check_header(void)
158 {
159 - unsigned int size;
160 + DWORD size;
161
162 if (get_dword()) return 0; /* data size */
163 size = get_dword(); /* header size */
164 @@ -214,14 +216,14 @@
165 /* load the next resource from the current file */
166 static void load_next_resource( DLLSPEC *spec )
167 {
168 - unsigned int hdr_size;
169 + DWORD hdr_size;
170 struct resource *res = add_resource( spec );
171
172 res->data_size = get_dword();
173 hdr_size = get_dword();
174 if (hdr_size & 3) fatal_error( "%s header size not aligned\n", input_buffer_filename );
175
176 - res->data = input_buffer + input_buffer_pos - 2*sizeof(unsigned int) + hdr_size;
177 + res->data = input_buffer + input_buffer_pos - 2*sizeof(DWORD) + hdr_size;
178 get_string( &res->type );
179 get_string( &res->name );
180 if (input_buffer_pos & 2) get_word(); /* align to dword boundary */
181 Index: spec32.c
182 ===================================================================
183 --- spec32.c (Revision 4)
184 +++ spec32.c (Arbeitskopie)
185 @@ -74,6 +74,28 @@
186 }
187
188 /*******************************************************************
189 + * make_internal_name
190 + *
191 + * Generate an internal name for an entry point. Used for stubs etc.
192 + */
193 +static const char *make_internal_name( const ORDDEF *odp, DLLSPEC *spec, const char *prefix )
194 +{
195 + static char buffer[256];
196 + if (odp->name || odp->export_name)
197 + {
198 + char *p;
199 + sprintf( buffer, "__wine_%s_%s_%s", prefix, spec->file_name,
200 + odp->name ? odp->name : odp->export_name );
201 + /* make sure name is a legal C identifier */
202 + for (p = buffer; *p; p++) if (!isalnum(*p) && *p != '_') break;
203 + if (!*p) return buffer;
204 + }
205 + sprintf( buffer, "__wine_%s_%s_%d", prefix, make_c_identifier(spec->file_name), odp->ordinal );
206 + return buffer;
207 +}
208 +
209 +
210 +/*******************************************************************
211 * output_relay_debug
212 *
213 * Output entry points for relay debugging
214 @@ -341,6 +363,44 @@
215
216
217 /*******************************************************************
218 + * output_stub_funcs
219 + *
220 + * Output the functions for stub entry points
221 + */
222 +static void output_stub_funcs( DLLSPEC *spec )
223 +{
224 + int i;
225 +
226 +#if 0
227 + for (i = 0; i < spec->nb_entry_points; i++)
228 + {
229 + ORDDEF *odp = &spec->entry_points[i];
230 + if (odp->type != TYPE_STUB) continue;
231 + fprintf( outfile, "#ifdef __GNUC__\n" );
232 + fprintf( outfile, "extern void __wine_spec_unimplemented_stub( const char *module, const char *func ) __attribute__((noreturn));\n" );
233 + fprintf( outfile, "#else\n" );
234 + fprintf( outfile, "extern void __wine_spec_unimplemented_stub( const char *module, const char *func );\n" );
235 + fprintf( outfile, "#endif\n\n" );
236 + break;
237 + }
238 +#endif
239 +
240 + for (i = 0; i < spec->nb_entry_points; i++)
241 + {
242 + const ORDDEF *odp = &spec->entry_points[i];
243 + if (odp->type != TYPE_STUB) continue;
244 + output( "void %s(void) ", make_internal_name( odp, spec, "stub" ) );
245 + if (odp->name)
246 + output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->name );
247 + else if (odp->export_name)
248 + output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%s\"); }\n", odp->export_name );
249 + else
250 + output( "{ __wine_spec_unimplemented_stub(__wine_spec_file_name, \"%d\"); }\n", odp->ordinal );
251 + }
252 +}
253 +
254 +
255 +/*******************************************************************
256 * output_asm_constructor
257 *
258 * Output code for calling a dll constructor.
259 @@ -795,10 +855,6 @@
260
261 if (!(odp->flags & FLAG_PRIVATE)) total++;
262
263 - if (odp->type == TYPE_STUB) continue;
264 -
265 - output( " %s", name );
266 -
267 switch(odp->type)
268 {
269 case TYPE_EXTERN:
270 @@ -807,12 +863,14 @@
271 case TYPE_VARARGS:
272 case TYPE_CDECL:
273 /* try to reduce output */
274 + output( " %s", name );
275 if(strcmp(name, odp->link_name) || (odp->flags & FLAG_FORWARD))
276 output( "=%s", odp->link_name );
277 break;
278 case TYPE_STDCALL:
279 {
280 int at_param = strlen(odp->u.func.arg_types) * get_ptr_size();
281 + output( " %s", name );
282 if (!kill_at && target_cpu == CPU_x86) output( "@%d", at_param );
283 if (odp->flags & FLAG_FORWARD)
284 {
285 @@ -825,6 +883,50 @@
286 }
287 break;
288 }
289 + case TYPE_FASTCALL:
290 + {
291 + int at_param = strlen(odp->u.func.arg_types) * get_ptr_size();
292 + output( " " );
293 + if (!kill_at) output( "@" );
294 + output( "%s", name );
295 + if (!kill_at) output( "@%d", at_param );
296 + if (odp->flags & FLAG_FORWARD)
297 + {
298 + output( "=" );
299 + output( "%s", odp->link_name );
300 + }
301 + else if (strcmp(name, odp->link_name)) /* try to reduce output */
302 + {
303 + output( "=" );
304 + if (!kill_at) output( "@" );
305 + output( "%s", odp->link_name );
306 + if (!kill_at) output( "@%d", at_param );
307 + }
308 + break;
309 + }
310 + case TYPE_STUB:
311 + {
312 + output( " %s", name );
313 + if (!kill_at)
314 + {
315 + const char *check = name + strlen(name);
316 + while (name != check &&
317 + '0' <= check[-1] && check[-1] <= '9')
318 + {
319 + check--;
320 + }
321 + if (name != check && check != name + strlen(name) &&
322 + '@' == check[-1])
323 + {
324 + output("%s", check - 1);
325 + }
326 + }
327 + if (odp->name || odp->export_name)
328 + {
329 + output("=%s", make_internal_name( odp, spec, "stub" ));
330 + }
331 + break;
332 + }
333 default:
334 assert(0);
335 }
336 @@ -836,3 +939,52 @@
337 }
338 if (!total) warning( "%s: Import library doesn't export anything\n", spec->file_name );
339 }
340 +
341 +
342 +/*******************************************************************
343 + * BuildPedllFile
344 + *
345 + * Build a PE DLL C file from a spec file.
346 + */
347 +void BuildPedllFile( DLLSPEC *spec )
348 +{
349 + int i, has_stubs = 0;
350 +
351 + output_standard_file_header();
352 +
353 + for (i = 0; i < spec->nb_entry_points; i++)
354 + {
355 + const ORDDEF *odp = &spec->entry_points[i];
356 + if (odp->type == TYPE_STUB)
357 + {
358 + has_stubs = 1;
359 + break;
360 + }
361 + }
362 +
363 + if (!has_stubs)
364 + {
365 + output( "/* This file is intentionally left blank */\n");
366 + return;
367 + }
368 +
369 + output( "#include <stdarg.h>\n");
370 + output( "#include \"windef.h\"\n");
371 + output( "#include \"winbase.h\"\n");
372 + output( "#include \"wine/config.h\"\n");
373 + output( "#include \"wine/exception.h\"\n\n");
374 +
375 + output( "void __wine_spec_unimplemented_stub( const char *module, const char *function )\n");
376 + output( "{\n");
377 + output( " ULONG_PTR args[2];\n");
378 + output( "\n");
379 + output( " args[0] = (ULONG_PTR)module;\n");
380 + output( " args[1] = (ULONG_PTR)function;\n");
381 + output( " RaiseException( EXCEPTION_WINE_STUB, EH_NONCONTINUABLE, 2, args );\n");
382 + output( "}\n\n");
383 +
384 + output( "static const char __wine_spec_file_name[] = \"%s\";\n\n", spec->file_name );
385 +
386 + /* Output the stub functions */
387 + output_stub_funcs( spec );
388 +}