Release 950122
[wine/multimedia.git] / tools / newbuild.c
blobf9f8e42cf54f16979685f2983535ba74c5c67094
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>
9 #ifdef linux
10 #ifdef __ELF__
11 #define UTEXTSEL 0x0f
12 #else
13 #define UTEXTSEL 0x23
14 #endif
15 #define UDATASEL 0x2b
16 #endif
17 #if defined(__NetBSD__) || defined(__FreeBSD__)
18 #define UTEXTSEL 0x1f
19 #define UDATASEL 0x27
20 #endif
22 #define VARTYPE_BYTE 0
23 #define VARTYPE_SIGNEDWORD 0
24 #define VARTYPE_WORD 1
25 #define VARTYPE_LONG 2
26 #define VARTYPE_FARPTR 3
28 #define FUNCTYPE_PASCAL 16
29 #define FUNCTYPE_C 17
30 #define FUNCTYPE_REG 19
32 #define EQUATETYPE_ABS 18
33 #define TYPE_RETURN 20
35 #define MAX_ORDINALS 1024
37 typedef struct ordinal_definition_s
39 int valid;
40 int type;
41 char export_name[80];
42 void *additional_data;
43 } ORDDEF;
45 typedef struct ordinal_variable_definition_s
47 int n_values;
48 int *values;
49 } ORDVARDEF;
51 typedef struct ordinal_function_definition_s
53 int n_args_16;
54 int arg_types_16[16];
55 int arg_16_offsets[16];
56 int arg_16_size;
57 char internal_name[80];
58 int n_args_32;
59 int arg_indices_32[16];
60 } ORDFUNCDEF;
62 typedef struct ordinal_return_definition_s
64 int arg_size;
65 int ret_value;
66 } ORDRETDEF;
68 ORDDEF OrdinalDefinitions[MAX_ORDINALS];
70 char LowerDLLName[80];
71 char UpperDLLName[80];
72 int Limit;
73 int DLLId;
74 FILE *SpecFp;
76 char *ParseBuffer = NULL;
77 char *ParseNext;
78 char ParseSaveChar;
79 int Line;
81 int IsNumberString(char *s)
83 while (*s != '\0')
84 if (!isdigit(*s++))
85 return 0;
87 return 1;
90 char *strlower(char *s)
92 char *p;
94 for(p = s; *p != '\0'; p++)
95 *p = tolower(*p);
97 return s;
100 char *strupper(char *s)
102 char *p;
104 for(p = s; *p != '\0'; p++)
105 *p = toupper(*p);
107 return s;
110 int stricmp(char *s1, char *s2)
112 if (strlen(s1) != strlen(s2))
113 return -1;
115 while (*s1 != '\0')
116 if (*s1++ != *s2++)
117 return -1;
119 return 0;
122 char *
123 GetTokenInLine(void)
125 char *p;
126 char *token;
128 if (ParseNext != ParseBuffer)
130 if (ParseSaveChar == '\0')
131 return NULL;
132 *ParseNext = ParseSaveChar;
136 * Remove initial white space.
138 for (p = ParseNext; isspace(*p); p++)
141 if (*p == '\0')
142 return NULL;
145 * Find end of token.
147 token = p++;
148 if (*token != '(' && *token != ')')
149 while (*p != '\0' && *p != '(' && *p != ')' && !isspace(*p))
150 p++;
152 ParseSaveChar = *p;
153 ParseNext = p;
154 *p = '\0';
156 return token;
159 char *
160 GetToken(void)
162 char *token;
164 if (ParseBuffer == NULL)
166 ParseBuffer = malloc(512);
167 ParseNext = ParseBuffer;
168 Line++;
169 while (1)
171 if (fgets(ParseBuffer, 511, SpecFp) == NULL)
172 return NULL;
173 if (ParseBuffer[0] != '#')
174 break;
178 while ((token = GetTokenInLine()) == NULL)
180 ParseNext = ParseBuffer;
181 Line++;
182 while (1)
184 if (fgets(ParseBuffer, 511, SpecFp) == NULL)
185 return NULL;
186 if (ParseBuffer[0] != '#')
187 break;
191 return token;
195 ParseVariable(int ordinal, int type)
197 ORDDEF *odp;
198 ORDVARDEF *vdp;
199 char export_name[80];
200 char *token;
201 char *endptr;
202 int *value_array;
203 int n_values;
204 int value_array_size;
206 strcpy(export_name, GetToken());
208 token = GetToken();
209 if (*token != '(')
211 fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
212 exit(1);
215 n_values = 0;
216 value_array_size = 25;
217 value_array = malloc(sizeof(*value_array) * value_array_size);
219 while ((token = GetToken()) != NULL)
221 if (*token == ')')
222 break;
224 value_array[n_values++] = strtol(token, &endptr, 0);
225 if (n_values == value_array_size)
227 value_array_size += 25;
228 value_array = realloc(value_array,
229 sizeof(*value_array) * value_array_size);
232 if (endptr == NULL || *endptr != '\0')
234 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
235 token);
236 exit(1);
240 if (token == NULL)
242 fprintf(stderr, "%d: End of file in variable declaration\n", Line);
243 exit(1);
246 if (ordinal >= MAX_ORDINALS)
248 fprintf(stderr, "%d: Ordinal number too large\n", Line);
249 exit(1);
252 odp = &OrdinalDefinitions[ordinal];
253 odp->valid = 1;
254 odp->type = type;
255 strcpy(odp->export_name, export_name);
257 vdp = malloc(sizeof(*vdp));
258 odp->additional_data = vdp;
260 vdp->n_values = n_values;
261 vdp->values = realloc(value_array, sizeof(*value_array) * n_values);
263 return 0;
267 ParseExportFunction(int ordinal, int type)
269 char *token;
270 ORDDEF *odp;
271 ORDFUNCDEF *fdp;
272 int arg_types[16];
273 int i;
274 int arg_num;
275 int current_offset;
276 int arg_size;
279 if (ordinal >= MAX_ORDINALS)
281 fprintf(stderr, "%d: Ordinal number too large\n", Line);
282 exit(1);
285 odp = &OrdinalDefinitions[ordinal];
286 strcpy(odp->export_name, GetToken());
287 odp->valid = 1;
288 odp->type = type;
289 fdp = malloc(sizeof(*fdp));
290 odp->additional_data = fdp;
292 token = GetToken();
293 if (*token != '(')
295 fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
296 exit(1);
299 fdp->arg_16_size = 0;
300 for (i = 0; i < 16; i++)
302 token = GetToken();
303 if (*token == ')')
304 break;
306 if (stricmp(token, "byte") == 0 || stricmp(token, "word") == 0)
308 fdp->arg_types_16[i] = VARTYPE_WORD;
309 fdp->arg_16_size += 2;
310 fdp->arg_16_offsets[i] = 2;
312 else if (stricmp(token, "s_byte") == 0 ||
313 stricmp(token, "s_word") == 0)
315 fdp->arg_types_16[i] = VARTYPE_SIGNEDWORD;
316 fdp->arg_16_size += 2;
317 fdp->arg_16_offsets[i] = 2;
319 else if (stricmp(token, "long") == 0 || stricmp(token, "s_long") == 0)
321 fdp->arg_types_16[i] = VARTYPE_LONG;
322 fdp->arg_16_size += 4;
323 fdp->arg_16_offsets[i] = 4;
325 else if (stricmp(token, "ptr") == 0)
327 fdp->arg_types_16[i] = VARTYPE_FARPTR;
328 fdp->arg_16_size += 4;
329 fdp->arg_16_offsets[i] = 4;
331 else
333 fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token);
334 exit(1);
337 fdp->n_args_16 = i;
339 if (type == FUNCTYPE_PASCAL || type == FUNCTYPE_REG)
341 current_offset = 0;
342 for (i--; i >= 0; i--)
344 arg_size = fdp->arg_16_offsets[i];
345 fdp->arg_16_offsets[i] = current_offset;
346 current_offset += arg_size;
349 else
351 current_offset = 0;
352 for (i = 0; i < fdp->n_args_16; i++)
354 arg_size = fdp->arg_16_offsets[i];
355 fdp->arg_16_offsets[i] = current_offset;
356 current_offset += arg_size;
360 strcpy(fdp->internal_name, GetToken());
361 token = GetToken();
362 if (*token != '(')
364 fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
365 exit(1);
367 for (i = 0; i < 16; i++)
369 token = GetToken();
370 if (*token == ')')
371 break;
373 fdp->arg_indices_32[i] = atoi(token);
374 if (fdp->arg_indices_32[i] < 1 ||
375 fdp->arg_indices_32[i] > fdp->n_args_16)
377 fprintf(stderr, "%d: Bad argument index %d\n", Line,
378 fdp->arg_indices_32[i]);
379 exit(1);
382 fdp->n_args_32 = i;
384 return 0;
388 ParseEquate(int ordinal)
390 ORDDEF *odp;
391 char *token;
392 char *endptr;
393 int value;
395 if (ordinal >= MAX_ORDINALS)
397 fprintf(stderr, "%d: Ordinal number too large\n", Line);
398 exit(1);
401 odp = &OrdinalDefinitions[ordinal];
402 strcpy(odp->export_name, GetToken());
404 token = GetToken();
405 value = strtol(token, &endptr, 0);
406 if (endptr == NULL || *endptr != '\0')
408 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
409 token);
410 exit(1);
413 odp->valid = 1;
414 odp->type = EQUATETYPE_ABS;
415 odp->additional_data = (void *) value;
417 return 0;
421 ParseReturn(int ordinal)
423 ORDDEF *odp;
424 ORDRETDEF *rdp;
425 char *token;
426 char *endptr;
427 int value;
429 if (ordinal >= MAX_ORDINALS)
431 fprintf(stderr, "%d: Ordinal number too large\n", Line);
432 exit(1);
435 rdp = malloc(sizeof(*rdp));
437 odp = &OrdinalDefinitions[ordinal];
438 strcpy(odp->export_name, GetToken());
439 odp->valid = 1;
440 odp->type = TYPE_RETURN;
441 odp->additional_data = rdp;
443 token = GetToken();
444 rdp->arg_size = strtol(token, &endptr, 0);
445 if (endptr == NULL || *endptr != '\0')
447 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
448 token);
449 exit(1);
452 token = GetToken();
453 rdp->ret_value = strtol(token, &endptr, 0);
454 if (endptr == NULL || *endptr != '\0')
456 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
457 token);
458 exit(1);
461 return 0;
465 ParseOrdinal(int ordinal)
467 char *token;
469 token = GetToken();
470 if (token == NULL)
472 fprintf(stderr, "%d: Expected type after ordinal\n", Line);
473 exit(1);
476 if (stricmp(token, "byte") == 0)
477 return ParseVariable(ordinal, VARTYPE_BYTE);
478 else if (stricmp(token, "word") == 0)
479 return ParseVariable(ordinal, VARTYPE_WORD);
480 else if (stricmp(token, "long") == 0)
481 return ParseVariable(ordinal, VARTYPE_LONG);
482 else if (stricmp(token, "c") == 0)
483 return ParseExportFunction(ordinal, FUNCTYPE_C);
484 else if (stricmp(token, "p") == 0)
485 return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
486 else if (stricmp(token, "pascal") == 0)
487 return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
488 else if (stricmp(token, "register") == 0)
489 return ParseExportFunction(ordinal, FUNCTYPE_REG);
490 else if (stricmp(token, "equate") == 0)
491 return ParseEquate(ordinal);
492 else if (stricmp(token, "return") == 0)
493 return ParseReturn(ordinal);
494 else
496 fprintf(stderr,
497 "%d: Expected type after ordinal, found '%s' instead\n",
498 Line, token);
499 exit(1);
504 ParseTopLevel(void)
506 char *token;
508 while ((token = GetToken()) != NULL)
510 if (stricmp(token, "name") == 0)
512 strcpy(LowerDLLName, GetToken());
513 strlower(LowerDLLName);
515 strcpy(UpperDLLName, LowerDLLName);
516 strupper(UpperDLLName);
518 else if (stricmp(token, "id") == 0)
520 token = GetToken();
521 if (!IsNumberString(token))
523 fprintf(stderr, "%d: Expected number after id\n", Line);
524 exit(1);
527 DLLId = atoi(token);
529 else if (stricmp(token, "length") == 0)
531 token = GetToken();
532 if (!IsNumberString(token))
534 fprintf(stderr, "%d: Expected number after length\n", Line);
535 exit(1);
538 Limit = atoi(token);
540 else if (IsNumberString(token))
542 int ordinal;
543 int rv;
545 ordinal = atoi(token);
546 if ((rv = ParseOrdinal(ordinal)) < 0)
547 return rv;
549 else
551 fprintf(stderr,
552 "%d: Expected name, id, length or ordinal\n", Line);
553 exit(1);
557 return 0;
560 void
561 OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp)
563 ORDVARDEF *vdp;
564 int i;
566 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
568 vdp = odp->additional_data;
569 for (i = 0; i < vdp->n_values; i++)
571 if ((i & 7) == 0)
572 fprintf(fp, "\t%s\t", storage);
574 fprintf(fp, "%d", vdp->values[i]);
576 if ((i & 7) == 7 || i == vdp->n_values - 1)
577 fprintf(fp, "\n");
578 else
579 fprintf(fp, ", ");
581 fprintf(fp, "\n");
584 main(int argc, char **argv)
586 ORDDEF *odp;
587 ORDFUNCDEF *fdp;
588 ORDRETDEF *rdp;
589 FILE *fp;
590 char filename[80];
591 char buffer[80];
592 char *p;
593 int i;
595 if (argc < 2)
597 fprintf(stderr, "usage: build SPECNAME\n");
598 exit(1);
601 SpecFp = fopen(argv[1], "r");
602 if (SpecFp == NULL)
604 fprintf(stderr, "Could not open specification file, '%s'\n", argv[1]);
605 exit(1);
608 ParseTopLevel();
610 /**********************************************************************
611 * DLL ENTRY POINTS
613 sprintf(filename, "dll_%s.S", LowerDLLName);
614 fp = fopen(filename, "w");
616 fprintf(fp, "\t.globl _%s_Dispatch\n", UpperDLLName);
617 fprintf(fp, "_%s_Dispatch:\n", UpperDLLName);
618 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
619 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
620 fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
621 fprintf(fp, "\tjmp\t_CallTo32\n\n");
623 odp = OrdinalDefinitions;
624 for (i = 0; i <= Limit; i++, odp++)
626 fprintf(fp, "\t.globl _%s_Ordinal_%d\n", UpperDLLName, i);
628 if (!odp->valid)
630 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
631 #ifdef BOB_SAYS_NO
632 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
633 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
634 #endif
635 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
636 fprintf(fp, "\tpushw\t$0\n");
637 fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
639 else
641 fdp = odp->additional_data;
642 rdp = odp->additional_data;
644 switch (odp->type)
646 case EQUATETYPE_ABS:
647 fprintf(fp, "_%s_Ordinal_%d = %d\n\n",
648 UpperDLLName, i, (int) odp->additional_data);
649 break;
651 case VARTYPE_BYTE:
652 OutputVariableCode(fp, ".byte", odp);
653 break;
655 case VARTYPE_WORD:
656 OutputVariableCode(fp, ".word", odp);
657 break;
659 case VARTYPE_LONG:
660 OutputVariableCode(fp, ".long", odp);
661 break;
663 case TYPE_RETURN:
664 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
665 fprintf(fp, "\tmovw\t$%d,%%ax\n", rdp->ret_value & 0xffff);
666 fprintf(fp, "\tmovw\t$%d,%%dx\n",
667 (rdp->ret_value >> 16) & 0xffff);
668 fprintf(fp, "\t.byte\t0x66\n");
669 if (rdp->arg_size != 0)
670 fprintf(fp, "\tlret\t$%d\n", rdp->arg_size);
671 else
672 fprintf(fp, "\tlret\n");
673 break;
675 case FUNCTYPE_REG:
676 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
677 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
678 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
679 fprintf(fp, "\tpushl\t$0\n"); /* cr2 */
680 fprintf(fp, "\tpushl\t$0\n"); /* oldmask */
681 fprintf(fp, "\tpushl\t$0\n"); /* i387 */
682 fprintf(fp, "\tpushw\t$0\n"); /* __ssh */
683 fprintf(fp, "\tpushw\t%%ss\n"); /* ss */
684 fprintf(fp, "\tpushl\t%%esp\n"); /* esp */
685 fprintf(fp, "\tpushfl\n"); /* eflags */
686 fprintf(fp, "\tpushw\t$0\n"); /* __csh */
687 fprintf(fp, "\tpushw\t%%cs\n"); /* cs */
688 fprintf(fp, "\tpushl\t$0\n"); /* eip */
689 fprintf(fp, "\tpushl\t$0\n"); /* err */
690 fprintf(fp, "\tpushl\t$0\n"); /* trapno */
691 fprintf(fp, "\tpushal\n"); /* AX, ... */
692 fprintf(fp, "\tpushw\t$0\n"); /* __dsh */
693 fprintf(fp, "\tpushw\t%%ds\n"); /* ds */
694 fprintf(fp, "\tpushw\t$0\n"); /* __esh */
695 fprintf(fp, "\tpushw\t%%es\n"); /* es */
696 fprintf(fp, "\tpushw\t$0\n"); /* __fsh */
697 fprintf(fp, "\tpushw\t%%fs\n"); /* fs */
698 fprintf(fp, "\tpushw\t$0\n"); /* __gsh */
699 fprintf(fp, "\tpushw\t%%gs\n"); /* gs */
700 fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
701 fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
702 fprintf(fp, "\tpushl\t88(%%ebp)\n");
703 fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
704 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
705 fprintf(fp, "\tpushw\t$92\n");
706 fprintf(fp, "\tjmp\t_%s_Relay_%d:\n", UpperDLLName, i);
707 break;
709 case FUNCTYPE_PASCAL:
710 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
711 #ifdef BOB_SAYS_NO
712 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
713 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
714 #endif
715 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
716 fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
717 fprintf(fp, "\tjmp\t_%s_Relay_%d:\n", UpperDLLName, i);
718 break;
720 case FUNCTYPE_C:
721 default:
722 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
723 #ifdef BOB_SAYS_NO
724 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
725 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
726 #endif
727 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
728 fprintf(fp, "\tpushw\t$0\n");
729 fprintf(fp, "\tjmp\t_%s_Relay_%d:\n", UpperDLLName, i);
730 break;
735 fclose(fp);
737 /**********************************************************************
738 * RELAY CODE
740 sprintf(filename, "rly_%s.S", LowerDLLName);
741 fp = fopen(filename, "w");
743 odp = OrdinalDefinitions;
744 for (i = 0; i <= Limit; i++, odp++)
746 if (!odp->valid)
747 continue;
749 fdp = odp->additional_data;
751 fprintf(fp, "\t.globl _%s_Relay_%d\n", UpperDLLName, i);
752 fprintf(fp, "_%s_Relay_%d:\n", UpperDLLName, i);
753 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
754 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
756 fprintf(fp, "\tpushl\t%%ebp\n");
757 fprintf(fp, "\tmovl\t%%esp,%%ebp\n");
760 * Save registers. 286 mode does not have fs or gs.
762 fprintf(fp, "\tpushw\t%%ds\n");
763 fprintf(fp, "\tpushw\t%%es\n");
766 * Restore segment registers.
768 fprintf(fp, "\tmovw\t%d,%%ax\n", UDATASEL);
769 fprintf(fp, "\tmovw\t%%ax,%%ds\n");
770 fprintf(fp, "\tmovw\t%%ax,%%es\n");
773 * Save old stack save variables, save stack registers, reload
774 * stack registers.
776 fprintf(fp, "\tpushl\t_IF1632_Saved16_esp\n");
777 fprintf(fp, "\tpushl\t_IF1632_Saved16_ebp\n");
778 fprintf(fp, "\tpushw\t_IF1632_Saved16_ss\n");
780 fprintf(fp, "\tmovw\t%%ss,_IF1632_Saved16_ss\n");
781 fprintf(fp, "\tmovl\t%%esp,_IF1632_Saved16_esp\n");
782 fprintf(fp, "\tmovl\t%%ebp,_IF1632_Saved16_ebp\n");
784 fprintf(fp, "\tmovw\t%%ss,%%ax\n");
785 fprintf(fp, "\tshll\t16,%%eax\n");
786 fprintf(fp, "\torl\t%%esp,%%eax\n");
788 fprintf(fp, "\tmovw\t_IF1632_Saved32_ss,%%ss\n");
789 fprintf(fp, "\tmovl\t_IF1632_Saved32_esp,%%esp\n");
790 fprintf(fp, "\tmovl\t_IF1632_Saved32_ebp,%%ebp\n");
792 fprintf(fp, "\tpushl\t_Stack16Frame\n");
793 fprintf(fp, "\tmovl\t%%eax,_Stack16Frame\n");
796 * Move arguments.
801 * Call entry point
803 fprintf(fp, "\tcall\t%s\n", fdp->internal_name);
806 * Restore registers, but do not destroy return value.
808 fprintf(fp, "\tmovw\t_IF1632_Saved16_ss,%%ss\n");
809 fprintf(fp, "\tmovl\t_IF1632_Saved16_esp,%%esp\n");
810 fprintf(fp, "\tmovl\t_IF1632_Saved16_ebp,%%ebp\n");
812 fprintf(fp, "\tpopw\t_IF1632_Saved16_ss\n");
813 fprintf(fp, "\tpopl\t_IF1632_Saved16_ebp\n");
814 fprintf(fp, "\tpopl\t_IF1632_Saved16_esp\n");
816 fprintf(fp, "\tpopw\t%%es\n");
817 fprintf(fp, "\tpopw\t%%ds\n");
819 fprintf(fp, "\t.align\t2,0x90\n");
820 fprintf(fp, "\tleave\n");
823 * Now we need to ditch the parameter bytes that were left on the
824 * stack. We do this by effectively popping the number of bytes,
825 * and the return address, removing the parameters and then putting
826 * the return address back on the stack.
827 * Normally this field is filled in by the relevant function in
828 * the emulation library, since it should know how many bytes to
829 * expect.
831 fprintf(fp, "\tpopw\t%%gs:nbytes\n");
832 fprintf(fp, "\tcmpw\t$0,%%gs:nbytes\n");
833 fprintf(fp, "\tje\tnoargs\n");
834 fprintf(fp, "\tpopw\t%%gs:offset\n");
835 fprintf(fp, "\tpopw\t%%gs:selector\n");
836 fprintf(fp, "\taddw\t%%gs:nbytes,%%esp\n");
837 fprintf(fp, "\tpushw\t%%gs:selector\n");
838 fprintf(fp, "\tpushw\t%%gs:offset\n");
839 fprintf(fp, "noargs:\n");
842 * Last, but not least we need to move the high word from eax to dx
844 fprintf(fp, "\t pushl\t%%eax\n");
845 fprintf(fp, "\tpopw\t%%dx\n");
846 fprintf(fp, "\tpopw\t%%dx\n");
848 fprintf(fp, "\t.byte\t0x66\n");
849 fprintf(fp, "\tlret\n");
853 fclose(fp);
855 /**********************************************************************
856 * DLL ENTRY TABLE
858 #ifndef SHORTNAMES
859 sprintf(filename, "dll_%s_tab.c", LowerDLLName);
860 #else
861 sprintf(filename, "dtb_%s.c", LowerDLLName);
862 #endif
863 fp = fopen(filename, "w");
865 fprintf(fp, "#include <stdio.h>\n");
866 fprintf(fp, "#include <stdlib.h>\n");
867 fprintf(fp, "#include \042dlls.h\042\n\n");
869 for (i = 0; i <= Limit; i++)
871 fprintf(fp, "extern void %s_Ordinal_%d();\n", UpperDLLName, i);
874 odp = OrdinalDefinitions;
875 for (i = 0; i <= Limit; i++, odp++)
877 if (odp->valid &&
878 (odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_C ||
879 odp->type == FUNCTYPE_REG))
881 fdp = odp->additional_data;
882 fprintf(fp, "extern int %s();\n", fdp->internal_name);
886 fprintf(fp, "\nstruct dll_table_entry_s %s_table[%d] =\n",
887 UpperDLLName, Limit + 1);
888 fprintf(fp, "{\n");
889 odp = OrdinalDefinitions;
890 for (i = 0; i <= Limit; i++, odp++)
892 fdp = odp->additional_data;
894 if (!odp->valid)
895 odp->type = -1;
897 switch (odp->type)
899 case FUNCTYPE_PASCAL:
900 case FUNCTYPE_REG:
901 fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
902 fprintf(fp, "\042%s\042, ", odp->export_name);
903 fprintf(fp, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp->internal_name);
904 #ifdef WINESTAT
905 fprintf(fp, "0, ");
906 #endif
907 fprintf(fp, "%d, ", fdp->n_args_32);
908 if (fdp->n_args_32 > 0)
910 int argnum;
912 fprintf(fp, "\n {\n");
913 for (argnum = 0; argnum < fdp->n_args_32; argnum++)
915 fprintf(fp, " { %d, %d },\n",
916 fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
917 fdp->arg_types_16[argnum]);
919 fprintf(fp, " }\n ");
921 fprintf(fp, "}, \n");
922 break;
924 case FUNCTYPE_C:
925 fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
926 fprintf(fp, "\042%s\042, ", odp->export_name);
927 fprintf(fp, "%s, DLL_HANDLERTYPE_C, ", fdp->internal_name);
928 #ifdef WINESTAT
929 fprintf(fp, "0, ");
930 #endif
931 fprintf(fp, "%d, ", fdp->n_args_32);
932 if (fdp->n_args_32 > 0)
934 int argnum;
936 fprintf(fp, "\n {\n");
937 for (argnum = 0; argnum < fdp->n_args_32; argnum++)
939 fprintf(fp, " { %d, %d },\n",
940 fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
941 fdp->arg_types_16[argnum]);
943 fprintf(fp, " }\n ");
945 fprintf(fp, "}, \n");
946 break;
948 default:
949 fprintf(fp, " { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n",
950 UTEXTSEL, UpperDLLName, i);
951 break;
954 fprintf(fp, "};\n");
956 fclose(fp);