Release 941210
[wine/multimedia.git] / tools / build.c
blob958995d662401835a1af2cc1cf91adcd52ca91b8
1 static char RCSId[] = "$Id: build.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
2 static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <ctype.h>
8 #include "wine.h"
10 #ifdef linux
11 #define UTEXTSEL 0x23
12 #endif
13 #if defined(__NetBSD__) || defined(__FreeBSD__)
14 #define UTEXTSEL 0x1f
15 #endif
17 /* ELF symbols do not have an underscore in front */
18 #ifdef __ELF__
19 #define PREFIX
20 #else
21 #define PREFIX "_"
22 #endif
24 #define VARTYPE_BYTE 0
25 #define VARTYPE_SIGNEDWORD 0
26 #define VARTYPE_WORD 1
27 #define VARTYPE_LONG 2
28 #define VARTYPE_FARPTR 3
30 #define FUNCTYPE_PASCAL_16 15
31 #define FUNCTYPE_PASCAL 16
32 #define FUNCTYPE_C 17
33 #define FUNCTYPE_REG 19
35 #define EQUATETYPE_ABS 18
36 #define TYPE_RETURN 20
38 /*#define MAX_ORDINALS 1024*/
39 #define MAX_ORDINALS 1299
41 #define PUSH_0 "\tpushl\t$0\n"
42 #define PUSH_SS "\tpushw\t$0\n\tpushw\t%%ss\n"
43 #define PUSH_ESP "\tpushl\t%%esp\n"
44 #define PUSH_EFL "\tpushfl\n"
45 #define PUSH_CS "\tpushw\t$0\n\tpushw\t%%cs\n"
46 #define PUSH_EIP "\tpushl\t$0\n"
47 #define PUSH_DS "\tpushw\t$0\n\tpushw\t%%ds\n"
48 #define PUSH_ES "\tpushw\t$0\n\tpushw\t%%es\n"
49 #define PUSH_FS "\tpushw\t$0\n\tpushw\t%%fs\n"
50 #define PUSH_GS "\tpushw\t$0\n\tpushw\t%%gs\n"
51 #define PUSH_EAX "\tpushl\t%%eax\n"
52 #define PUSH_ECX "\tpushl\t%%ecx\n"
53 #define PUSH_EDX "\tpushl\t%%edx\n"
54 #define PUSH_EBX "\tpushl\t%%ebx\n"
55 #define PUSH_EBP "\tpushl\t%%ebp\n"
56 #define PUSH_ESI "\tpushl\t%%esi\n"
57 #define PUSH_EDI "\tpushl\t%%edi\n"
59 #define POP_0 "\tadd\t$4,%%esp\n"
60 #define POP_SS "\tpopw\t%%ss\n\tadd\t$2,%%esp\n"
61 #define POP_ESP "\tpopl\t%%esp\n"
62 #define POP_EFL "\tpopl\t%%gs:return_value\n"
63 #define POP_CS "\tpopw\t%%cs\n\tadd\t$2,%%esp\n"
64 #define POP_EIP "\tpopl\t$0\n"
65 #define POP_DS "\tpopw\t%%ds\n\tadd\t$2,%%esp\n"
66 #define POP_ES "\tpopw\t%%es\n\tadd\t$2,%%esp\n"
67 #define POP_FS "\tpopw\t%%fs\n\tadd\t$2,%%esp\n"
68 #define POP_GS "\tpopw\t%%gs\n\tadd\t$2,%%esp\n"
69 #define POP_EAX "\tpopl\t%%eax\n"
70 #define POP_ECX "\tpopl\t%%ecx\n"
71 #define POP_EDX "\tpopl\t%%edx\n"
72 #define POP_EBX "\tpopl\t%%ebx\n"
73 #define POP_EBP "\tpopl\t%%ebp\n"
74 #define POP_ESI "\tpopl\t%%esi\n"
75 #define POP_EDI "\tpopl\t%%edi\n"
77 char **context_strings;
78 char **pop_strings;
79 int n_context_strings;
81 typedef struct ordinal_definition_s
83 int valid;
84 int type;
85 char export_name[80];
86 void *additional_data;
87 } ORDDEF;
89 typedef struct ordinal_variable_definition_s
91 int n_values;
92 int *values;
93 } ORDVARDEF;
95 typedef struct ordinal_function_definition_s
97 int n_args_16;
98 int arg_types_16[16];
99 int arg_16_offsets[16];
100 int arg_16_size;
101 char internal_name[80];
102 int n_args_32;
103 int arg_indices_32[16];
104 } ORDFUNCDEF;
106 typedef struct ordinal_return_definition_s
108 int arg_size;
109 int ret_value;
110 } ORDRETDEF;
112 ORDDEF OrdinalDefinitions[MAX_ORDINALS];
114 char LowerDLLName[80];
115 char UpperDLLName[80];
116 int Limit;
117 int DLLId;
118 FILE *SpecFp;
120 char *ParseBuffer = NULL;
121 char *ParseNext;
122 char ParseSaveChar;
123 int Line;
125 int IsNumberString(char *s)
127 while (*s != '\0')
128 if (!isdigit(*s++))
129 return 0;
131 return 1;
134 char *strlower(char *s)
136 char *p;
138 for(p = s; *p != '\0'; p++)
139 *p = tolower(*p);
141 return s;
144 char *strupper(char *s)
146 char *p;
148 for(p = s; *p != '\0'; p++)
149 *p = toupper(*p);
151 return s;
154 int stricmp(char *s1, char *s2)
156 if (strlen(s1) != strlen(s2))
157 return -1;
159 while (*s1 != '\0')
160 if (*s1++ != *s2++)
161 return -1;
163 return 0;
166 char *
167 GetTokenInLine(void)
169 char *p;
170 char *token;
172 if (ParseNext != ParseBuffer)
174 if (ParseSaveChar == '\0')
175 return NULL;
176 *ParseNext = ParseSaveChar;
180 * Remove initial white space.
182 for (p = ParseNext; isspace(*p); p++)
185 if (*p == '\0')
186 return NULL;
189 * Find end of token.
191 token = p++;
192 if (*token != '(' && *token != ')')
193 while (*p != '\0' && *p != '(' && *p != ')' && !isspace(*p))
194 p++;
196 ParseSaveChar = *p;
197 ParseNext = p;
198 *p = '\0';
200 return token;
203 char *
204 GetToken(void)
206 char *token;
208 if (ParseBuffer == NULL)
210 ParseBuffer = malloc(512);
211 ParseNext = ParseBuffer;
212 Line++;
213 while (1)
215 if (fgets(ParseBuffer, 511, SpecFp) == NULL)
216 return NULL;
217 if (ParseBuffer[0] != '#')
218 break;
222 while ((token = GetTokenInLine()) == NULL)
224 ParseNext = ParseBuffer;
225 Line++;
226 while (1)
228 if (fgets(ParseBuffer, 511, SpecFp) == NULL)
229 return NULL;
230 if (ParseBuffer[0] != '#')
231 break;
235 return token;
239 ParseVariable(int ordinal, int type)
241 ORDDEF *odp;
242 ORDVARDEF *vdp;
243 char export_name[80];
244 char *token;
245 char *endptr;
246 int *value_array;
247 int n_values;
248 int value_array_size;
250 strcpy(export_name, GetToken());
252 token = GetToken();
253 if (*token != '(')
255 fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
256 exit(1);
259 n_values = 0;
260 value_array_size = 25;
261 value_array = malloc(sizeof(*value_array) * value_array_size);
263 while ((token = GetToken()) != NULL)
265 if (*token == ')')
266 break;
268 value_array[n_values++] = strtol(token, &endptr, 0);
269 if (n_values == value_array_size)
271 value_array_size += 25;
272 value_array = realloc(value_array,
273 sizeof(*value_array) * value_array_size);
276 if (endptr == NULL || *endptr != '\0')
278 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
279 token);
280 exit(1);
284 if (token == NULL)
286 fprintf(stderr, "%d: End of file in variable declaration\n", Line);
287 exit(1);
290 if (ordinal >= MAX_ORDINALS)
292 fprintf(stderr, "%d: Ordinal number too large\n", Line);
293 exit(1);
296 odp = &OrdinalDefinitions[ordinal];
297 odp->valid = 1;
298 odp->type = type;
299 strcpy(odp->export_name, export_name);
301 vdp = malloc(sizeof(*vdp));
302 odp->additional_data = vdp;
304 vdp->n_values = n_values;
305 vdp->values = realloc(value_array, sizeof(*value_array) * n_values);
307 return 0;
311 ParseExportFunction(int ordinal, int type)
313 char *token;
314 ORDDEF *odp;
315 ORDFUNCDEF *fdp;
316 int i;
317 int current_offset;
318 int arg_size;
321 if (ordinal >= MAX_ORDINALS)
323 fprintf(stderr, "%d: Ordinal number too large\n", Line);
324 exit(1);
327 odp = &OrdinalDefinitions[ordinal];
328 strcpy(odp->export_name, GetToken());
329 odp->valid = 1;
330 odp->type = type;
331 fdp = malloc(sizeof(*fdp));
332 odp->additional_data = fdp;
334 token = GetToken();
335 if (*token != '(')
337 fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
338 exit(1);
341 fdp->arg_16_size = 0;
342 for (i = 0; i < 16; i++)
344 token = GetToken();
345 if (*token == ')')
346 break;
348 if (stricmp(token, "byte") == 0 || stricmp(token, "word") == 0)
350 fdp->arg_types_16[i] = VARTYPE_WORD;
351 fdp->arg_16_size += 2;
352 fdp->arg_16_offsets[i] = 2;
354 else if (stricmp(token, "s_byte") == 0 ||
355 stricmp(token, "s_word") == 0)
357 fdp->arg_types_16[i] = VARTYPE_SIGNEDWORD;
358 fdp->arg_16_size += 2;
359 fdp->arg_16_offsets[i] = 2;
361 else if (stricmp(token, "long") == 0 || stricmp(token, "s_long") == 0)
363 fdp->arg_types_16[i] = VARTYPE_LONG;
364 fdp->arg_16_size += 4;
365 fdp->arg_16_offsets[i] = 4;
367 else if (stricmp(token, "ptr") == 0)
369 fdp->arg_types_16[i] = VARTYPE_FARPTR;
370 fdp->arg_16_size += 4;
371 fdp->arg_16_offsets[i] = 4;
373 else
375 fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token);
376 exit(1);
379 fdp->n_args_16 = i;
381 if (type == FUNCTYPE_PASCAL_16 || type == FUNCTYPE_PASCAL ||
382 type == FUNCTYPE_REG )
384 current_offset = 0;
385 for (i--; i >= 0; i--)
387 arg_size = fdp->arg_16_offsets[i];
388 fdp->arg_16_offsets[i] = current_offset;
389 current_offset += arg_size;
392 else
394 current_offset = 0;
395 for (i = 0; i < fdp->n_args_16; i++)
397 arg_size = fdp->arg_16_offsets[i];
398 fdp->arg_16_offsets[i] = current_offset;
399 current_offset += arg_size;
403 strcpy(fdp->internal_name, GetToken());
404 token = GetToken();
405 if (*token != '(')
407 fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
408 exit(1);
410 for (i = 0; i < 16; i++)
412 token = GetToken();
413 if (*token == ')')
414 break;
416 fdp->arg_indices_32[i] = atoi(token);
417 if (fdp->arg_indices_32[i] < 1 ||
418 fdp->arg_indices_32[i] > fdp->n_args_16)
420 fprintf(stderr, "%d: Bad argument index %d\n", Line,
421 fdp->arg_indices_32[i]);
422 exit(1);
425 fdp->n_args_32 = i;
427 return 0;
431 ParseEquate(int ordinal)
433 ORDDEF *odp;
434 char *token;
435 char *endptr;
436 int value;
438 if (ordinal >= MAX_ORDINALS)
440 fprintf(stderr, "%d: Ordinal number too large\n", Line);
441 exit(1);
444 odp = &OrdinalDefinitions[ordinal];
445 strcpy(odp->export_name, GetToken());
447 token = GetToken();
448 value = strtol(token, &endptr, 0);
449 if (endptr == NULL || *endptr != '\0')
451 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
452 token);
453 exit(1);
456 odp->valid = 1;
457 odp->type = EQUATETYPE_ABS;
458 odp->additional_data = (void *) value;
460 return 0;
464 ParseReturn(int ordinal)
466 ORDDEF *odp;
467 ORDRETDEF *rdp;
468 char *token;
469 char *endptr;
471 if (ordinal >= MAX_ORDINALS)
473 fprintf(stderr, "%d: Ordinal number too large\n", Line);
474 exit(1);
477 rdp = malloc(sizeof(*rdp));
479 odp = &OrdinalDefinitions[ordinal];
480 strcpy(odp->export_name, GetToken());
481 odp->valid = 1;
482 odp->type = TYPE_RETURN;
483 odp->additional_data = rdp;
485 token = GetToken();
486 rdp->arg_size = strtol(token, &endptr, 0);
487 if (endptr == NULL || *endptr != '\0')
489 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
490 token);
491 exit(1);
494 token = GetToken();
495 rdp->ret_value = strtol(token, &endptr, 0);
496 if (endptr == NULL || *endptr != '\0')
498 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
499 token);
500 exit(1);
503 return 0;
507 ParseOrdinal(int ordinal)
509 char *token;
511 token = GetToken();
512 if (token == NULL)
514 fprintf(stderr, "%d: Expected type after ordinal\n", Line);
515 exit(1);
518 if (stricmp(token, "byte") == 0)
519 return ParseVariable(ordinal, VARTYPE_BYTE);
520 else if (stricmp(token, "word") == 0)
521 return ParseVariable(ordinal, VARTYPE_WORD);
522 else if (stricmp(token, "long") == 0)
523 return ParseVariable(ordinal, VARTYPE_LONG);
524 else if (stricmp(token, "c") == 0)
525 return ParseExportFunction(ordinal, FUNCTYPE_C);
526 else if (stricmp(token, "p") == 0)
527 return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
528 else if (stricmp(token, "pascal") == 0)
529 return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
530 else if (stricmp(token, "pascal16") == 0)
531 return ParseExportFunction(ordinal, FUNCTYPE_PASCAL_16);
532 else if (stricmp(token, "register") == 0)
533 return ParseExportFunction(ordinal, FUNCTYPE_REG);
534 else if (stricmp(token, "equate") == 0)
535 return ParseEquate(ordinal);
536 else if (stricmp(token, "return") == 0)
537 return ParseReturn(ordinal);
538 else
540 fprintf(stderr,
541 "%d: Expected type after ordinal, found '%s' instead\n",
542 Line, token);
543 exit(1);
548 ParseTopLevel(void)
550 char *token;
552 while ((token = GetToken()) != NULL)
554 if (stricmp(token, "name") == 0)
556 strcpy(LowerDLLName, GetToken());
557 strlower(LowerDLLName);
559 strcpy(UpperDLLName, LowerDLLName);
560 strupper(UpperDLLName);
562 else if (stricmp(token, "id") == 0)
564 token = GetToken();
565 if (!IsNumberString(token))
567 fprintf(stderr, "%d: Expected number after id\n", Line);
568 exit(1);
571 DLLId = atoi(token);
573 else if (stricmp(token, "length") == 0)
575 token = GetToken();
576 if (!IsNumberString(token))
578 fprintf(stderr, "%d: Expected number after length\n", Line);
579 exit(1);
582 Limit = atoi(token);
584 else if (IsNumberString(token))
586 int ordinal;
587 int rv;
589 ordinal = atoi(token);
590 if ((rv = ParseOrdinal(ordinal)) < 0)
591 return rv;
593 else
595 fprintf(stderr,
596 "%d: Expected name, id, length or ordinal\n", Line);
597 exit(1);
601 return 0;
604 void
605 InitContext(void)
607 struct sigcontext_struct context;
608 int i;
610 n_context_strings = sizeof(context) / 4;
611 context_strings = (char **) malloc(n_context_strings * sizeof(char **));
612 pop_strings = (char **) malloc(n_context_strings * sizeof(char **));
613 for (i = 0; i < n_context_strings; i++)
615 context_strings[i] = PUSH_0;
616 pop_strings[i] = POP_0;
619 i = n_context_strings - 1 + ((int) &context - (int) &context.sc_esp) / 4;
620 context_strings[i] = PUSH_ESP;
622 i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ebp) / 4;
623 context_strings[i] = PUSH_EBP;
624 pop_strings[n_context_strings - 1 - i] = POP_EBP;
626 i = n_context_strings - 1 + ((int) &context - (int) &context.sc_eip) / 4;
627 context_strings[i] = PUSH_EIP;
629 #ifndef __FreeBSD__
630 i = n_context_strings - 1 + ((int) &context - (int)&context.sc_eflags) / 4;
631 #else
632 i = n_context_strings - 1 + ((int) &context - (int)&context.sc_efl) / 4;
633 #endif
634 context_strings[i] = PUSH_EFL;
635 pop_strings[n_context_strings - 1 - i] = POP_EFL;
637 i = n_context_strings - 1 + ((int) &context - (int) &context.sc_es) / 4;
638 context_strings[i] = PUSH_ES;
639 pop_strings[n_context_strings - 1 - i] = POP_ES;
641 i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ds) / 4;
642 context_strings[i] = PUSH_DS;
643 pop_strings[n_context_strings - 1 - i] = POP_DS;
645 i = n_context_strings - 1 + ((int) &context - (int) &context.sc_cs) / 4;
646 context_strings[i] = PUSH_CS;
648 i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ss) / 4;
649 context_strings[i] = PUSH_SS;
651 i = n_context_strings - 1 + ((int) &context - (int) &context.sc_edi) / 4;
652 context_strings[i] = PUSH_EDI;
653 pop_strings[n_context_strings - 1 - i] = POP_EDI;
655 i = n_context_strings - 1 + ((int) &context - (int) &context.sc_esi) / 4;
656 context_strings[i] = PUSH_ESI;
657 pop_strings[n_context_strings - 1 - i] = POP_ESI;
659 i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ebx) / 4;
660 context_strings[i] = PUSH_EBX;
661 pop_strings[n_context_strings - 1 - i] = POP_EBX;
663 i = n_context_strings - 1 + ((int) &context - (int) &context.sc_edx) / 4;
664 context_strings[i] = PUSH_EDX;
665 pop_strings[n_context_strings - 1 - i] = POP_EDX;
667 i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ecx) / 4;
668 context_strings[i] = PUSH_ECX;
669 pop_strings[n_context_strings - 1 - i] = POP_ECX;
671 i = n_context_strings - 1 + ((int) &context - (int) &context.sc_eax) / 4;
672 context_strings[i] = PUSH_EAX;
673 pop_strings[n_context_strings - 1 - i] = POP_EAX;
676 void
677 OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp)
679 ORDVARDEF *vdp;
680 int i;
682 fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i);
684 vdp = odp->additional_data;
685 for (i = 0; i < vdp->n_values; i++)
687 if ((i & 7) == 0)
688 fprintf(fp, "\t%s\t", storage);
690 fprintf(fp, "%d", vdp->values[i]);
692 if ((i & 7) == 7 || i == vdp->n_values - 1)
693 fprintf(fp, "\n");
694 else
695 fprintf(fp, ", ");
697 fprintf(fp, "\n");
700 main(int argc, char **argv)
702 ORDDEF *odp;
703 ORDFUNCDEF *fdp;
704 ORDRETDEF *rdp;
705 FILE *fp;
706 char filename[80];
707 int i, ci, add_count;
709 if (argc < 2)
711 fprintf(stderr, "usage: build SPECNAME\n build -p\n");
712 exit(1);
715 InitContext();
717 if (strcmp("-p", argv[1]) == 0)
719 fp = fopen("pop.h", "w");
720 add_count = 0;
721 for (i = 0; i < n_context_strings; i++)
723 if (strncmp(pop_strings[i], "\tadd\t", 5) == 0)
725 add_count += atoi(pop_strings[i] + 6);
727 else
729 if (add_count > 0)
731 fprintf(fp, "\tadd\t$%d,%%esp\n", add_count);
732 add_count = 0;
735 fprintf(fp, pop_strings[i]);
739 if (add_count > 0)
740 fprintf(fp, "\tadd\t$%d,%%esp\n", add_count);
742 fprintf(fp, "\tpushl\t%%gs:return_value\n\tpopfl\n");
744 fclose(fp);
745 exit(0);
748 SpecFp = fopen(argv[1], "r");
749 if (SpecFp == NULL)
751 fprintf(stderr, "Could not open specification file, '%s'\n", argv[1]);
752 exit(1);
755 ParseTopLevel();
757 sprintf(filename, "dll_%s.S", LowerDLLName);
758 fp = fopen(filename, "w");
760 fprintf(fp, "\t.globl " PREFIX "%s_Dispatch\n", UpperDLLName);
761 fprintf(fp, PREFIX "%s_Dispatch:\n", UpperDLLName);
762 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
763 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
764 fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
765 fprintf(fp, "\tjmp\t" PREFIX "CallTo32\n\n");
767 fprintf(fp, "\t.globl " PREFIX "%s_Dispatch_16\n", UpperDLLName);
768 fprintf(fp, PREFIX "%s_Dispatch_16:\n", UpperDLLName);
769 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
770 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
771 fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
772 fprintf(fp, "\tjmp\t" PREFIX "CallTo32_16\n\n");
774 odp = OrdinalDefinitions;
775 for (i = 0; i <= Limit; i++, odp++)
777 fprintf(fp, "\t.globl " PREFIX "%s_Ordinal_%d\n", UpperDLLName, i);
779 if (!odp->valid)
781 fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i);
782 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
783 fprintf(fp, "\tpushw\t$0\n");
784 fprintf(fp, "\tjmp\t" PREFIX "%s_Dispatch\n\n", UpperDLLName);
786 else
788 fdp = odp->additional_data;
789 rdp = odp->additional_data;
791 switch (odp->type)
793 case EQUATETYPE_ABS:
794 fprintf(fp, PREFIX "%s_Ordinal_%d = %d\n\n",
795 UpperDLLName, i, (int) odp->additional_data);
796 break;
798 case VARTYPE_BYTE:
799 OutputVariableCode(fp, ".byte", odp);
800 break;
802 case VARTYPE_WORD:
803 OutputVariableCode(fp, ".word", odp);
804 break;
806 case VARTYPE_LONG:
807 OutputVariableCode(fp, ".long", odp);
808 break;
810 case TYPE_RETURN:
811 fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i);
812 fprintf(fp, "\tmovw\t$%d,%%ax\n", rdp->ret_value & 0xffff);
813 fprintf(fp, "\tmovw\t$%d,%%dx\n",
814 (rdp->ret_value >> 16) & 0xffff);
815 fprintf(fp, "\t.byte\t0x66\n");
816 if (rdp->arg_size != 0)
817 fprintf(fp, "\tlret\t$%d\n", rdp->arg_size);
818 else
819 fprintf(fp, "\tlret\n");
820 break;
822 case FUNCTYPE_REG:
823 fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i);
824 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
825 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
827 for (ci = 0; ci < n_context_strings; ci++)
828 fprintf(fp, context_strings[ci]);
830 fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
831 fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
832 fprintf(fp, "\tpushl\t%d(%%ebp)\n",
833 sizeof(struct sigcontext_struct));
834 fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
835 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
836 fprintf(fp, "\tpushw\t$%d\n",
837 sizeof(struct sigcontext_struct) + 4);
838 fprintf(fp, "\tjmp\t" PREFIX "%s_Dispatch\n\n", UpperDLLName);
839 break;
841 case FUNCTYPE_PASCAL:
842 fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i);
843 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
844 fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
845 fprintf(fp, "\tjmp\t" PREFIX "%s_Dispatch\n\n", UpperDLLName);
846 break;
848 case FUNCTYPE_PASCAL_16:
849 fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i);
850 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
851 fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
852 fprintf(fp, "\tjmp\t" PREFIX "%s_Dispatch_16\n\n", UpperDLLName);
853 break;
855 case FUNCTYPE_C:
856 default:
857 fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i);
858 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
859 fprintf(fp, "\tpushw\t$0\n");
860 fprintf(fp, "\tjmp\t" PREFIX "%s_Dispatch\n\n", UpperDLLName);
861 break;
866 fclose(fp);
868 #ifndef SHORTNAMES
869 sprintf(filename, "dll_%s_tab.c", LowerDLLName);
870 #else
871 sprintf(filename, "dtb_%s.c", LowerDLLName);
872 #endif
873 fp = fopen(filename, "w");
875 fprintf(fp, "#include <stdio.h>\n");
876 fprintf(fp, "#include <stdlib.h>\n");
877 fprintf(fp, "#include \042dlls.h\042\n\n");
879 for (i = 0; i <= Limit; i++)
881 fprintf(fp, "extern void %s_Ordinal_%d();\n", UpperDLLName, i);
884 odp = OrdinalDefinitions;
885 for (i = 0; i <= Limit; i++, odp++)
887 if (odp->valid &&
888 (odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_PASCAL_16 ||
889 odp->type == FUNCTYPE_REG || odp->type == FUNCTYPE_C ))
891 fdp = odp->additional_data;
892 fprintf(fp, "extern int %s();\n", fdp->internal_name);
896 fprintf(fp, "\nstruct dll_table_entry_s %s_table[%d] =\n",
897 UpperDLLName, Limit + 1);
898 fprintf(fp, "{\n");
899 odp = OrdinalDefinitions;
900 for (i = 0; i <= Limit; i++, odp++)
902 fdp = odp->additional_data;
904 if (!odp->valid)
905 odp->type = -1;
907 switch (odp->type)
909 case FUNCTYPE_PASCAL:
910 case FUNCTYPE_PASCAL_16:
911 case FUNCTYPE_REG:
912 fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
913 fprintf(fp, "\042%s\042, ", odp->export_name);
914 fprintf(fp, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp->internal_name);
915 #ifdef WINESTAT
916 fprintf(fp, "0, ");
917 #endif
918 fprintf(fp, "%d, ", fdp->n_args_32);
919 if (fdp->n_args_32 > 0)
921 int argnum;
923 fprintf(fp, "\n {\n");
924 for (argnum = 0; argnum < fdp->n_args_32; argnum++)
926 fprintf(fp, " { %d, %d },\n",
927 fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
928 fdp->arg_types_16[argnum]);
930 fprintf(fp, " }\n ");
932 fprintf(fp, "}, \n");
933 break;
935 case FUNCTYPE_C:
936 fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
937 fprintf(fp, "\042%s\042, ", odp->export_name);
938 fprintf(fp, "%s, DLL_HANDLERTYPE_C, ", fdp->internal_name);
939 #ifdef WINESTAT
940 fprintf(fp, "0, ");
941 #endif
942 fprintf(fp, "%d, ", fdp->n_args_32);
943 if (fdp->n_args_32 > 0)
945 int argnum;
947 fprintf(fp, "\n {\n");
948 for (argnum = 0; argnum < fdp->n_args_32; argnum++)
950 fprintf(fp, " { %d, %d },\n",
951 fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
952 fdp->arg_types_16[argnum]);
954 fprintf(fp, " }\n ");
956 fprintf(fp, "}, \n");
957 break;
959 default:
960 fprintf(fp, " { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n",
961 UTEXTSEL, UpperDLLName, i);
962 break;
965 fprintf(fp, "};\n");
967 fclose(fp);
968 return 0;