source: trunk/tools/pebuild/spec32.c@ 10366

Last change on this file since 10366 was 10298, checked in by sandervl, 22 years ago

added

File size: 23.9 KB
Line 
1/*
2 * 32-bit spec files
3 *
4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Martin von Loewis
6 * Copyright 1995, 1996, 1997 Alexandre Julliard
7 * Copyright 1997 Eric Youngdale
8 * Copyright 1999 Ulrich Weigand
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include "config.h"
26#include "port.h"
27
28#include <assert.h>
29#include <ctype.h>
30#include <stdarg.h>
31#include <string.h>
32
33#include "windef.h"
34#include "winbase.h"
35//#include "wine/exception.h"
36#include "build.h"
37
38static int string_compare( const void *ptr1, const void *ptr2 )
39{
40 const char * const *str1 = ptr1;
41 const char * const *str2 = ptr2;
42 return strcmp( *str1, *str2 );
43}
44
45
46/*******************************************************************
47 * make_internal_name
48 *
49 * Generate an internal name for an entry point. Used for stubs etc.
50 */
51static const char *make_internal_name( const ORDDEF *odp, const char *prefix )
52{
53 static char buffer[256];
54 if (odp->name || odp->export_name)
55 {
56 char *p;
57 sprintf( buffer, "__wine_%s_%s_%s", prefix, dll_file_name,
58 odp->name ? odp->name : odp->export_name );
59 /* make sure name is a legal C identifier */
60 for (p = buffer; *p; p++) if (!isalnum(*p) && *p != '_') break;
61 if (!*p) return buffer;
62 }
63 sprintf( buffer, "__wine_%s_%s_%d", prefix, make_c_identifier(dll_file_name), odp->ordinal );
64 return buffer;
65}
66
67/*******************************************************************
68 * AssignOrdinals
69 *
70 * Assign ordinals to all entry points.
71 */
72static void AssignOrdinals(void)
73{
74 int i, ordinal;
75
76 if ( !nb_names ) return;
77
78 /* start assigning from Base, or from 1 if no ordinal defined yet */
79 if (Base == MAX_ORDINALS) Base = 1;
80 for (i = 0, ordinal = Base; i < nb_names; i++)
81 {
82 if (Names[i]->ordinal != -1) continue; /* already has an ordinal */
83 while (Ordinals[ordinal]) ordinal++;
84 if (ordinal >= MAX_ORDINALS)
85 {
86 current_line = Names[i]->lineno;
87 fatal_error( "Too many functions defined (max %d)\n", MAX_ORDINALS );
88 }
89 Names[i]->ordinal = ordinal;
90 Ordinals[ordinal] = Names[i];
91 }
92 if (ordinal > Limit) Limit = ordinal;
93}
94
95
96
97
98/*******************************************************************
99 * output_exports
100 *
101 * Output the export table for a Win32 module.
102 */
103static int output_exports( FILE *outfile, int nr_exports)
104{
105 int i, fwd_size = 0, total_size = 0;
106
107 if (!nr_exports) return 0;
108
109 /* export directory header */
110 if(outfile) fprintf( outfile, "dll_file_name db \"%s\"\n\n", dll_file_name);
111 if(outfile) fprintf( outfile, "__wine_spec_exports:\n");
112 if(outfile) fprintf( outfile, " dd 0 ; Characteristics\n" ); /* Characteristics */
113 if(outfile) fprintf( outfile, " dd 0 ; TimeDateStamp\n" ); /* TimeDateStamp */
114 if(outfile) fprintf( outfile, " dw 0 ; MajorVersion\n" ); /* MajorVersion */
115 if(outfile) fprintf( outfile, " dw 0 ; MinorVersion\n" ); /* MinorVersion */
116 if(outfile) fprintf( outfile, " dd FLAT:dll_file_name ; Name\n", dll_file_name); /* Name */
117 if(outfile) fprintf( outfile, " dd %d ; Base\n", Base ); /* Base */
118 if(outfile) fprintf( outfile, " dd %d ; NumberOfFunctions\n", nr_exports ); /* NumberOfFunctions */
119 if(outfile) fprintf( outfile, " dd %d ; NumberOfNames\n", nb_names ); /* NumberOfNames */
120 if(outfile) fprintf( outfile, " dd FLAT:__wine_spec_exports_funcs ;AddressOfFunctions\n" ); /* AddressOfFunctions */
121 if (nb_names)
122 {
123 if(outfile) fprintf( outfile, " dd FLAT:__wine_spec_exp_name_ptrs ; AddressOfNames\n" ); /* AddressOfNames */
124 if(outfile) fprintf( outfile, " dd FLAT:__wine_spec_exp_ordinals ; AddressOfNameOrdinals\n" ); /* AddressOfNameOrdinals */
125 }
126 else
127 {
128 if(outfile) fprintf( outfile, " dd 0 ; AddressOfNames\n" ); /* AddressOfNames */
129 if(outfile) fprintf( outfile, " dd 0 ; AddressOfNameOrdinals\n" ); /* AddressOfNameOrdinals */
130 }
131 if(outfile) fprintf( outfile, "\n\n" );
132
133 total_size += 10 * sizeof(int);
134
135 /* output the function pointers */
136
137 if(outfile) fprintf( outfile, "__wine_spec_exports_funcs:\n" );
138 for (i = Base; i <= Limit; i++)
139 {
140 ORDDEF *odp = Ordinals[i];
141 if (!odp || !odp->link_name) { if(outfile) fprintf( outfile, " dd 0\n" ); }
142 else switch(odp->type)
143 {
144 case TYPE_EXTERN:
145 case TYPE_STDCALL:
146 case TYPE_VARARGS:
147 case TYPE_CDECL:
148 if(outfile) fprintf( outfile, " dd FLAT:%s\n",
149 (odp->flags & FLAG_REGISTER) ? make_internal_name(odp,"regs") : odp->link_name );
150 break;
151 case TYPE_STUB:
152// if(outfile) fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n", make_internal_name( odp, "stub" ) );
153 break;
154 default:
155 assert(0);
156 }
157 }
158 if(outfile) fprintf( outfile, "\n" );
159 total_size += (Limit - Base + 1) * sizeof(int);
160
161 if (nb_names)
162 {
163 /* output the function name pointers */
164
165 int namepos = 0;
166
167 if(outfile) fprintf( outfile, "__wine_spec_exp_name_ptrs:\n" );
168 for (i = 0; i < nb_names; i++)
169 {
170 if(outfile) fprintf( outfile, " dd FLAT:__wine_spec_exp_names+%d\n", namepos );
171 namepos += strlen(Names[i]->name) + 1;
172 }
173 if(outfile) fprintf( outfile, "\n" );
174 total_size += nb_names * sizeof(int);
175
176 /* output the function names */
177
178 if(outfile) fprintf( outfile, "__wine_spec_exp_names:\n" );
179 for (i = 0; i < nb_names; i++)
180 if(outfile) fprintf( outfile, " db \"%s\", 0\n", Names[i]->name );
181 if(outfile) fprintf( outfile, "\n" );
182
183
184 /* output the function ordinals */
185 if(outfile) fprintf( outfile, "__wine_spec_exp_ordinals: \n" );
186
187 for (i = 0; i < nb_names; i++)
188 {
189 if(outfile) fprintf( outfile, " dw %d\n", Names[i]->ordinal - Base );
190 }
191 total_size += nb_names * sizeof(short);
192 if (nb_names % 2)
193 {
194 if(outfile) fprintf( outfile, " dw 0\n" );
195 total_size += sizeof(short);
196 }
197 if(outfile) fprintf( outfile, "\n" );
198 }
199
200#if 0
201 /* output forward strings */
202
203 if (fwd_size)
204 {
205 if(outfile) fprintf( outfile, " \"__wine_spec_forwards:\\n\"\n" );
206 for (i = Base; i <= Limit; i++)
207 {
208 ORDDEF *odp = Ordinals[i];
209 if (odp && (odp->flags & FLAG_FORWARD))
210 if(outfile) fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", odp->link_name );
211 }
212 if(outfile) fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) );
213 total_size += (fwd_size + 3) & ~3;
214 }
215
216 /* output relays */
217
218 if (debugging)
219 {
220 for (i = Base; i <= Limit; i++)
221 {
222 ORDDEF *odp = Ordinals[i];
223 unsigned int j, args, mask = 0;
224 const char *name;
225
226 /* skip non-existent entry points */
227 if (!odp) goto ignore;
228 /* skip non-functions */
229 if ((odp->type != TYPE_STDCALL) && (odp->type != TYPE_CDECL)) goto ignore;
230 /* skip norelay and forward entry points */
231 if (odp->flags & (FLAG_NORELAY|FLAG_FORWARD)) goto ignore;
232
233 for (j = 0; odp->u.func.arg_types[j]; j++)
234 {
235 if (odp->u.func.arg_types[j] == 't') mask |= 1<< (j*2);
236 if (odp->u.func.arg_types[j] == 'W') mask |= 2<< (j*2);
237 }
238 if ((odp->flags & FLAG_RET64) && (j < 16)) mask |= 0x80000000;
239
240 name = odp->link_name;
241 args = strlen(odp->u.func.arg_types) * sizeof(int);
242 if (odp->flags & FLAG_REGISTER) name = make_internal_name( odp, "regs" );
243
244 switch(odp->type)
245 {
246 case TYPE_STDCALL:
247 fprintf( outfile, " \"\\tjmp " __ASM_NAME("%s") "\\n\"\n", name );
248 fprintf( outfile, " \"\\tret $%d\\n\"\n", args );
249 fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") ",0x%08x\\n\"\n", name, mask );
250 break;
251 case TYPE_CDECL:
252 fprintf( outfile, " \"\\tjmp " __ASM_NAME("%s") "\\n\"\n", name );
253 fprintf( outfile, " \"\\tret\\n\"\n" );
254 fprintf( outfile, " \"\\t" __ASM_SHORT " %d\\n\"\n", args );
255 fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") ",0x%08x\\n\"\n", name, mask );
256 break;
257 default:
258 assert(0);
259 }
260 continue;
261
262 ignore:
263 fprintf( outfile, " \"\\t.long 0,0,0,0\\n\"\n" );
264 }
265 }
266
267 fprintf( outfile, " \"\\t.text\\n\"\n" );
268 fprintf( outfile, " \"\\t.align %d\\n\"\n", get_alignment(4) );
269 fprintf( outfile, ");\n\n" );
270#endif
271
272 return total_size;
273}
274
275
276
277
278/*******************************************************************
279 * output_register_funcs
280 *
281 * Output the functions for register entry points
282 */
283static void output_register_funcs( FILE *outfile )
284{
285 const char *name;
286 int i;
287
288 for (i = 0; i < nb_entry_points; i++)
289 {
290 ORDDEF *odp = EntryPoints[i];
291 if (odp->type != TYPE_STDCALL && odp->type != TYPE_CDECL) continue;
292
293#if 1
294 if(odp->link_name)
295 fprintf (outfile, " extrn %s : near\n", odp->link_name);
296#else
297 if (!(odp->flags & FLAG_REGISTER)) continue;
298 if (odp->flags & FLAG_FORWARD) continue;
299 name = make_internal_name( odp, "regs" );
300 fprintf( outfile,
301 "asm(\".align %d\\n\\t\"\n"
302 " \"" __ASM_FUNC("%s") "\\n\\t\"\n"
303 " \"" __ASM_NAME("%s") ":\\n\\t\"\n"
304 " \"call " __ASM_NAME("__wine_call_from_32_regs") "\\n\\t\"\n"
305 " \".long " __ASM_NAME("%s") "\\n\\t\"\n"
306 " \".byte %d,%d\");\n",
307 get_alignment(4),
308 name, name, odp->link_name,
309 strlen(odp->u.func.arg_types) * sizeof(int),
310 (odp->type == TYPE_CDECL) ? 0 : (strlen(odp->u.func.arg_types) * sizeof(int)) );
311#endif
312 }
313}
314
315
316/*******************************************************************
317 * output_dll_init
318 *
319 * Output code for calling a dll constructor and destructor.
320 */
321void output_dll_init( FILE *outfile, const char *constructor, const char *destructor )
322{
323#if 0
324 fprintf( outfile, "#ifndef __GNUC__\n" );
325 fprintf( outfile, "static void __asm__dummy_dll_init(void) {\n" );
326 fprintf( outfile, "#endif\n" );
327#endif
328#if defined(__i386__)
329 if (constructor)
330 {
331 fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
332 fprintf( outfile, " \"\\tcall " __ASM_NAME("%s") "\\n\"\n", constructor );
333 fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
334 }
335 if (destructor)
336 {
337 fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
338 fprintf( outfile, " \"\\tcall " __ASM_NAME("%s") "\\n\"\n", destructor );
339 fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
340 }
341#elif defined(__sparc__)
342 if (constructor)
343 {
344 fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
345 fprintf( outfile, " \"\\tcall " __ASM_NAME("%s") "\\n\"\n", constructor );
346 fprintf( outfile, " \"\\tnop\\n\"\n" );
347 fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
348 }
349 if (destructor)
350 {
351 fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
352 fprintf( outfile, " \"\\tcall " __ASM_NAME("%s") "\\n\"\n", destructor );
353 fprintf( outfile, " \"\\tnop\\n\"\n" );
354 fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
355 }
356#elif defined(__PPC__)
357 if (constructor)
358 {
359 fprintf( outfile, "asm(\"\\t.section\\t\\\".init\\\" ,\\\"ax\\\"\\n\"\n" );
360 fprintf( outfile, " \"\\tbl " __ASM_NAME("%s") "\\n\"\n", constructor );
361 fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
362 }
363 if (destructor)
364 {
365 fprintf( outfile, "asm(\"\\t.section\\t\\\".fini\\\" ,\\\"ax\\\"\\n\"\n" );
366 fprintf( outfile, " \"\\tbl " __ASM_NAME("%s") "\\n\"\n", destructor );
367 fprintf( outfile, " \"\\t.section\\t\\\".text\\\"\\n\");\n" );
368 }
369#else
370#error You need to define the DLL constructor for your architecture
371#endif
372#if 0
373 fprintf( outfile, "#ifndef __GNUC__\n" );
374 fprintf( outfile, "}\n" );
375 fprintf( outfile, "#endif\n" );
376#endif
377}
378
379
380/*******************************************************************
381 * BuildSpec32File
382 *
383 * Build a Win32 C file from a spec file.
384 */
385void BuildSpec32File( FILE *outfile )
386{
387 int exports_size = 0, i;
388 int nr_exports, nr_imports, nr_resources;
389 int characteristics, subsystem;
390 DWORD page_size;
391 char constructor[100];
392
393#ifdef HAVE_GETPAGESIZE
394 page_size = getpagesize();
395#elif defined(__svr4__)
396 page_size = sysconf(_SC_PAGESIZE);
397#elif defined(_WINDOWS)
398 {
399 SYSTEM_INFO si;
400 GetSystemInfo(&si);
401 page_size = si.dwPageSize;
402 }
403#else
404# error Cannot get the page size on this platform
405#endif
406
407 AssignOrdinals();
408 nr_exports = Base <= Limit ? Limit - Base + 1 : 0;
409 output_standard_file_header( outfile );
410
411 fprintf( outfile, ".386p\n\n");
412 fprintf( outfile, "DATA32 segment dword use32 public 'DATA'\n");
413 fprintf( outfile, "DATA32 ends\n");
414 fprintf( outfile, "CONST32_RO segment dword use32 public 'CONST'\n");
415 fprintf( outfile, "CONST32_RO ends\n");
416 fprintf( outfile, "BSS32 segment dword use32 public 'BSS'\n");
417 fprintf( outfile, "BSS32 ends\n");
418 fprintf( outfile, "DGROUP group BSS32, DATA32\n");
419 fprintf( outfile, " assume cs:FLAT, ds:FLAT, ss:FLAT, es:FLAT\n\n");
420
421 if (nr_exports)
422 {
423 /* Output the stub functions */
424 /* Output code for all register functions */
425
426 fprintf( outfile, "CODE32 SEGMENT DWORD PUBLIC USE32 'CODE'\n");
427 output_register_funcs( outfile );
428 fprintf( outfile, "CODE32 ENDS\n\n");
429
430 /* Calc size of the exports and relay entry points */
431 exports_size = output_exports( NULL, nr_exports );
432
433 }
434
435 characteristics = subsystem = 0;
436 characteristics = IMAGE_FILE_DLL;
437
438 /* Output the NT header */
439 fprintf( outfile, "DATA32 segment dword use32 public 'DATA'\n\n");
440
441 /* this is the IMAGE_NT_HEADERS structure, but we cannot include winnt.h here */
442 fprintf( outfile, ";;struct image_nt_headers\n;;{\n" );
443 fprintf( outfile, ";; char dosHeader[16*15];\n");
444 fprintf( outfile, ";; int Signature;\n" );
445 fprintf( outfile, ";; struct file_header {\n" );
446 fprintf( outfile, ";; short Machine;\n" );
447 fprintf( outfile, ";; short NumberOfSections;\n" );
448 fprintf( outfile, ";; int TimeDateStamp;\n" );
449 fprintf( outfile, ";; void *PointerToSymbolTable;\n" );
450 fprintf( outfile, ";; int NumberOfSymbols;\n" );
451 fprintf( outfile, ";; short SizeOfOptionalHeader;\n" );
452 fprintf( outfile, ";; short Characteristics;\n" );
453 fprintf( outfile, ";; } FileHeader;\n" );
454 fprintf( outfile, ";; struct opt_header {\n" );
455 fprintf( outfile, ";; short Magic;\n" );
456 fprintf( outfile, ";; char MajorLinkerVersion, MinorLinkerVersion;\n" );
457 fprintf( outfile, ";; int SizeOfCode;\n" );
458 fprintf( outfile, ";; int SizeOfInitializedData;\n" );
459 fprintf( outfile, ";; int SizeOfUninitializedData;\n" );
460 fprintf( outfile, ";; void *AddressOfEntryPoint;\n" );
461 fprintf( outfile, ";; void *BaseOfCode;\n" );
462 fprintf( outfile, ";; void *BaseOfData;\n" );
463 fprintf( outfile, ";; void *ImageBase;\n" );
464 fprintf( outfile, ";; int SectionAlignment;\n" );
465 fprintf( outfile, ";; int FileAlignment;\n" );
466 fprintf( outfile, ";; short MajorOperatingSystemVersion;\n" );
467 fprintf( outfile, ";; short MinorOperatingSystemVersion;\n" );
468 fprintf( outfile, ";; short MajorImageVersion;\n" );
469 fprintf( outfile, ";; short MinorImageVersion;\n" );
470 fprintf( outfile, ";; short MajorSubsystemVersion;\n" );
471 fprintf( outfile, ";; short MinorSubsystemVersion;\n" );
472 fprintf( outfile, ";; int Win32VersionValue;\n" );
473 fprintf( outfile, ";; int SizeOfImage;\n" );
474 fprintf( outfile, ";; int SizeOfHeaders;\n" );
475 fprintf( outfile, ";; int CheckSum;\n" );
476 fprintf( outfile, ";; short Subsystem;\n" );
477 fprintf( outfile, ";; short DllCharacteristics;\n" );
478 fprintf( outfile, ";; int SizeOfStackReserve;\n" );
479 fprintf( outfile, ";; int SizeOfStackCommit;\n" );
480 fprintf( outfile, ";; int SizeOfHeapReserve;\n" );
481 fprintf( outfile, ";; int SizeOfHeapCommit;\n" );
482 fprintf( outfile, ";; int LoaderFlags;\n" );
483 fprintf( outfile, ";; int NumberOfRvaAndSizes;\n" );
484 fprintf( outfile, ";; struct { const void *VirtualAddress; int Size; } DataDirectory[%d];\n",
485 IMAGE_NUMBEROF_DIRECTORY_ENTRIES );
486 fprintf( outfile, ";; } OptionalHeader;\n" );
487 fprintf( outfile, " PUBLIC nt_%s_header\n", dll_name);
488 fprintf( outfile, " nt_%s_header:\n", dll_name);
489 fprintf( outfile, " db 04Dh, 05Ah, 000h, 000h, 001h, 000h, 000h, 000h, 004h, 000h, 000h, 000h, 0FFh, 0FFh, 00Bh, 000h\n");
490 fprintf( outfile, " db 000h, 001h, 000h, 000h, 000h, 000h, 000h, 000h, 040h, 000h, 000h, 000h, 001h, 000h, 000h, 000h\n");
491 fprintf( outfile, " db 06Ah, 072h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h\n");
492 fprintf( outfile, " db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0F0h, 000h, 000h, 000h\n");
493 fprintf( outfile, " db 0B4h, 030h, 0CDh, 021h, 086h, 0C4h, 03Dh, 00Ah, 014h, 072h, 042h, 0BEh, 080h, 000h, 08Ah, 01Ch\n");
494 fprintf( outfile, " db 032h, 0FFh, 046h, 088h, 038h, 02Eh, 08Ch, 01Eh, 06Eh, 000h, 08Eh, 006h, 02Ch, 000h, 033h, 0C0h\n");
495 fprintf( outfile, " db 08Bh, 0F8h, 0B9h, 000h, 080h, 0FCh, 0F2h, 0AEh, 075h, 023h, 049h, 078h, 020h, 0AEh, 075h, 0F6h\n");
496 fprintf( outfile, " db 047h, 047h, 00Eh, 01Fh, 02Eh, 089h, 03Eh, 068h, 000h, 02Eh, 08Ch, 006h, 06Ah, 000h, 0BEh, 05Ch\n");
497 fprintf( outfile, " db 000h, 0B9h, 06Ch, 063h, 0BBh, 025h, 000h, 0B4h, 064h, 0CDh, 021h, 073h, 00Bh, 0BAh, 07Ch, 000h\n");
498 fprintf( outfile, " db 00Eh, 01Fh, 0B4h, 009h, 0CDh, 021h, 0B0h, 001h, 0B4h, 04Ch, 0CDh, 021h, 020h, 000h, 001h, 000h\n");
499 fprintf( outfile, " db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 081h, 000h, 000h, 000h\n");
500 fprintf( outfile, " db 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 000h, 054h, 068h, 069h, 073h\n");
501 fprintf( outfile, " db 020h, 070h, 072h, 06Fh, 067h, 072h, 061h, 06Dh, 020h, 06Dh, 075h, 073h, 074h, 020h, 062h, 065h\n");
502 fprintf( outfile, " db 020h, 072h, 075h, 06Eh, 020h, 075h, 06Eh, 064h, 065h, 072h, 020h, 057h, 069h, 06Eh, 033h, 032h\n");
503 fprintf( outfile, " db 02Eh, 00Dh, 00Ah, 024h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h\n");
504 fprintf( outfile, " dd %04xh\n", IMAGE_NT_SIGNATURE ); /* Signature */
505
506 fprintf( outfile, " dw %04xh\n", IMAGE_FILE_MACHINE_I386 ); /* Machine */
507 fprintf( outfile, " dw 1\n"); /* NumberOfSections */
508 fprintf( outfile, " dd 0, 0, 0\n" );
509 fprintf( outfile, " dw %d\n", sizeof(IMAGE_OPTIONAL_HEADER) ); /* SizeOfOptionalHeader */
510 fprintf( outfile, " dw %04xh\n", characteristics ); /* Characteristics */
511
512 fprintf( outfile, " dw %04xh\n", IMAGE_NT_OPTIONAL_HDR_MAGIC ); /* Magic */
513 fprintf( outfile, " db 0, 0\n" ); /* Major/MinorLinkerVersion */
514 fprintf( outfile, " dd 0, 0, 0\n" ); /* SizeOfCode/Data */
515 fprintf( outfile, " dd 0\n" ); /* AddressOfEntryPoint */
516 fprintf( outfile, " dd 0, 0\n" ); /* BaseOfCode/Data */
517 fprintf( outfile, " dd FLAT:nt_%s_header\n" , dll_name); /* ImageBase */
518 fprintf( outfile, " dd %ld\n", page_size ); /* SectionAlignment */
519 fprintf( outfile, " dd %ld\n", page_size ); /* FileAlignment */
520 fprintf( outfile, " dw 1, 0\n" ); /* Major/MinorOperatingSystemVersion */
521 fprintf( outfile, " dw 0, 0\n" ); /* Major/MinorImageVersion */
522 fprintf( outfile, " dw 4, 0\n" ); /* Major/MinorSubsystemVersion */
523 fprintf( outfile, " dd 0\n" ); /* Win32VersionValue */
524 fprintf( outfile, " dd %ld\n", page_size ); /* SizeOfImage */
525 fprintf( outfile, " dd %ld\n", page_size ); /* SizeOfHeaders */
526 fprintf( outfile, " dd 0\n" ); /* CheckSum */
527 fprintf( outfile, " dw %04xh\n", subsystem ); /* Subsystem */
528 fprintf( outfile, " dw 0\n" ); /* DllCharacteristics */
529 fprintf( outfile, " dd %d, 0\n", stack_size*1024 ); /* SizeOfStackReserve/Commit */
530 fprintf( outfile, " dd %d, 0\n", DLLHeapSize*1024 );/* SizeOfHeapReserve/Commit */
531 fprintf( outfile, " dd 0\n" ); /* LoaderFlags */
532// fprintf( outfile, " dd %d\n", IMAGE_NUMBEROF_DIRECTORY_ENTRIES ); /* NumberOfRvaAndSizes */
533 fprintf( outfile, " dd %d\n", 1 ); /* NumberOfRvaAndSizes */
534 fprintf( outfile, " dd %s, %d \n", /* IMAGE_DIRECTORY_ENTRY_EXPORT */
535 exports_size ? "FLAT:__wine_spec_exports" : "0", exports_size );
536 for(i=0;i<15;i++)
537 fprintf( outfile, " dd 0, 0\n");
538 fprintf( outfile, "\n");
539
540 if(exports_size) {
541 fprintf( outfile, " ;;#define IMAGE_SIZEOF_SHORT_NAME 8\n");
542 fprintf( outfile, " ;;typedef struct _IMAGE_SECTION_HEADER {\n");
543 fprintf( outfile, " ;; BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; \n");
544 fprintf( outfile, " ;; union {\n");
545 fprintf( outfile, " ;; DWORD PhysicalAddress; \n");
546 fprintf( outfile, " ;; DWORD VirtualSize; \n");
547 fprintf( outfile, " ;; } Misc;\n");
548 fprintf( outfile, " ;; DWORD VirtualAddress; \n");
549 fprintf( outfile, " ;; DWORD SizeOfRawData; \n");
550 fprintf( outfile, " ;; DWORD PointerToRawData; \n");
551 fprintf( outfile, " ;; DWORD PointerToRelocations; \n");
552 fprintf( outfile, " ;; DWORD PointerToLinenumbers; \n");
553 fprintf( outfile, " ;; WORD NumberOfRelocations; \n");
554 fprintf( outfile, " ;; WORD NumberOfLinenumbers; \n");
555 fprintf( outfile, " ;; DWORD Characteristics; \n");
556 fprintf( outfile, " ;; \n");
557 fprintf( outfile, " ;;} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;\n");
558 fprintf( outfile, "__wine_export_section:\n");
559 fprintf( outfile, " db \".edata\", 0, 0\n");
560 fprintf( outfile, " dd %d\n", exports_size);
561 fprintf( outfile, " dd FLAT:__wine_spec_exports\n");
562 fprintf( outfile, " dd 0\n");
563 fprintf( outfile, " dd 0\n");
564 fprintf( outfile, " dd 0\n");
565 fprintf( outfile, " dd 0\n");
566 fprintf( outfile, " dw 0\n");
567 fprintf( outfile, " dw 0\n");
568 fprintf( outfile, " dd 0\n");
569 }
570
571 if (nr_exports)
572 {
573 /* Output the exports and relay entry points */
574 exports_size = output_exports( outfile, nr_exports );
575 }
576
577 fprintf( outfile, "DATA32 ends\n");
578 fprintf( outfile, " END\n");
579
580}
581
582
Note: See TracBrowser for help on using the repository browser.