Release 940405
[wine.git] / tools / newbuild.c
blob647594f239ce39111b8947465f3d96872c8dfddf
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 #define UTEXTSEL 0x23
11 #define UDATASEL 0x2b
12 #endif
13 #if defined(__NetBSD__) || defined(__FreeBSD__)
14 #define UTEXTSEL 0x1f
15 #define UDATASEL 0x27
16 #endif
18 #define VARTYPE_BYTE 0
19 #define VARTYPE_SIGNEDWORD 0
20 #define VARTYPE_WORD 1
21 #define VARTYPE_LONG 2
22 #define VARTYPE_FARPTR 3
24 #define FUNCTYPE_PASCAL 16
25 #define FUNCTYPE_C 17
26 #define FUNCTYPE_REG 19
28 #define EQUATETYPE_ABS 18
29 #define TYPE_RETURN 20
31 #define MAX_ORDINALS 1024
33 typedef struct ordinal_definition_s
35 int valid;
36 int type;
37 char export_name[80];
38 void *additional_data;
39 } ORDDEF;
41 typedef struct ordinal_variable_definition_s
43 int n_values;
44 int *values;
45 } ORDVARDEF;
47 typedef struct ordinal_function_definition_s
49 int n_args_16;
50 int arg_types_16[16];
51 int arg_16_offsets[16];
52 int arg_16_size;
53 char internal_name[80];
54 int n_args_32;
55 int arg_indices_32[16];
56 } ORDFUNCDEF;
58 typedef struct ordinal_return_definition_s
60 int arg_size;
61 int ret_value;
62 } ORDRETDEF;
64 ORDDEF OrdinalDefinitions[MAX_ORDINALS];
66 char LowerDLLName[80];
67 char UpperDLLName[80];
68 int Limit;
69 int DLLId;
70 FILE *SpecFp;
72 char *ParseBuffer = NULL;
73 char *ParseNext;
74 char ParseSaveChar;
75 int Line;
77 int IsNumberString(char *s)
79 while (*s != '\0')
80 if (!isdigit(*s++))
81 return 0;
83 return 1;
86 char *strlower(char *s)
88 char *p;
90 for(p = s; *p != '\0'; p++)
91 *p = tolower(*p);
93 return s;
96 char *strupper(char *s)
98 char *p;
100 for(p = s; *p != '\0'; p++)
101 *p = toupper(*p);
103 return s;
106 int stricmp(char *s1, char *s2)
108 if (strlen(s1) != strlen(s2))
109 return -1;
111 while (*s1 != '\0')
112 if (*s1++ != *s2++)
113 return -1;
115 return 0;
118 char *
119 GetTokenInLine(void)
121 char *p;
122 char *token;
124 if (ParseNext != ParseBuffer)
126 if (ParseSaveChar == '\0')
127 return NULL;
128 *ParseNext = ParseSaveChar;
132 * Remove initial white space.
134 for (p = ParseNext; isspace(*p); p++)
137 if (*p == '\0')
138 return NULL;
141 * Find end of token.
143 token = p++;
144 if (*token != '(' && *token != ')')
145 while (*p != '\0' && *p != '(' && *p != ')' && !isspace(*p))
146 p++;
148 ParseSaveChar = *p;
149 ParseNext = p;
150 *p = '\0';
152 return token;
155 char *
156 GetToken(void)
158 char *token;
160 if (ParseBuffer == NULL)
162 ParseBuffer = malloc(512);
163 ParseNext = ParseBuffer;
164 Line++;
165 while (1)
167 if (fgets(ParseBuffer, 511, SpecFp) == NULL)
168 return NULL;
169 if (ParseBuffer[0] != '#')
170 break;
174 while ((token = GetTokenInLine()) == NULL)
176 ParseNext = ParseBuffer;
177 Line++;
178 while (1)
180 if (fgets(ParseBuffer, 511, SpecFp) == NULL)
181 return NULL;
182 if (ParseBuffer[0] != '#')
183 break;
187 return token;
191 ParseVariable(int ordinal, int type)
193 ORDDEF *odp;
194 ORDVARDEF *vdp;
195 char export_name[80];
196 char *token;
197 char *endptr;
198 int *value_array;
199 int n_values;
200 int value_array_size;
202 strcpy(export_name, GetToken());
204 token = GetToken();
205 if (*token != '(')
207 fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
208 exit(1);
211 n_values = 0;
212 value_array_size = 25;
213 value_array = malloc(sizeof(*value_array) * value_array_size);
215 while ((token = GetToken()) != NULL)
217 if (*token == ')')
218 break;
220 value_array[n_values++] = strtol(token, &endptr, 0);
221 if (n_values == value_array_size)
223 value_array_size += 25;
224 value_array = realloc(value_array,
225 sizeof(*value_array) * value_array_size);
228 if (endptr == NULL || *endptr != '\0')
230 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
231 token);
232 exit(1);
236 if (token == NULL)
238 fprintf(stderr, "%d: End of file in variable declaration\n", Line);
239 exit(1);
242 if (ordinal >= MAX_ORDINALS)
244 fprintf(stderr, "%d: Ordinal number too large\n", Line);
245 exit(1);
248 odp = &OrdinalDefinitions[ordinal];
249 odp->valid = 1;
250 odp->type = type;
251 strcpy(odp->export_name, export_name);
253 vdp = malloc(sizeof(*vdp));
254 odp->additional_data = vdp;
256 vdp->n_values = n_values;
257 vdp->values = realloc(value_array, sizeof(*value_array) * n_values);
259 return 0;
263 ParseExportFunction(int ordinal, int type)
265 char *token;
266 ORDDEF *odp;
267 ORDFUNCDEF *fdp;
268 int arg_types[16];
269 int i;
270 int arg_num;
271 int current_offset;
272 int arg_size;
275 if (ordinal >= MAX_ORDINALS)
277 fprintf(stderr, "%d: Ordinal number too large\n", Line);
278 exit(1);
281 odp = &OrdinalDefinitions[ordinal];
282 strcpy(odp->export_name, GetToken());
283 odp->valid = 1;
284 odp->type = type;
285 fdp = malloc(sizeof(*fdp));
286 odp->additional_data = fdp;
288 token = GetToken();
289 if (*token != '(')
291 fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
292 exit(1);
295 fdp->arg_16_size = 0;
296 for (i = 0; i < 16; i++)
298 token = GetToken();
299 if (*token == ')')
300 break;
302 if (stricmp(token, "byte") == 0 || stricmp(token, "word") == 0)
304 fdp->arg_types_16[i] = VARTYPE_WORD;
305 fdp->arg_16_size += 2;
306 fdp->arg_16_offsets[i] = 2;
308 else if (stricmp(token, "s_byte") == 0 ||
309 stricmp(token, "s_word") == 0)
311 fdp->arg_types_16[i] = VARTYPE_SIGNEDWORD;
312 fdp->arg_16_size += 2;
313 fdp->arg_16_offsets[i] = 2;
315 else if (stricmp(token, "long") == 0 || stricmp(token, "s_long") == 0)
317 fdp->arg_types_16[i] = VARTYPE_LONG;
318 fdp->arg_16_size += 4;
319 fdp->arg_16_offsets[i] = 4;
321 else if (stricmp(token, "ptr") == 0)
323 fdp->arg_types_16[i] = VARTYPE_FARPTR;
324 fdp->arg_16_size += 4;
325 fdp->arg_16_offsets[i] = 4;
327 else
329 fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token);
330 exit(1);
333 fdp->n_args_16 = i;
335 if (type == FUNCTYPE_PASCAL || type == FUNCTYPE_REG)
337 current_offset = 0;
338 for (i--; i >= 0; i--)
340 arg_size = fdp->arg_16_offsets[i];
341 fdp->arg_16_offsets[i] = current_offset;
342 current_offset += arg_size;
345 else
347 current_offset = 0;
348 for (i = 0; i < fdp->n_args_16; i++)
350 arg_size = fdp->arg_16_offsets[i];
351 fdp->arg_16_offsets[i] = current_offset;
352 current_offset += arg_size;
356 strcpy(fdp->internal_name, GetToken());
357 token = GetToken();
358 if (*token != '(')
360 fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
361 exit(1);
363 for (i = 0; i < 16; i++)
365 token = GetToken();
366 if (*token == ')')
367 break;
369 fdp->arg_indices_32[i] = atoi(token);
370 if (fdp->arg_indices_32[i] < 1 ||
371 fdp->arg_indices_32[i] > fdp->n_args_16)
373 fprintf(stderr, "%d: Bad argument index %d\n", Line,
374 fdp->arg_indices_32[i]);
375 exit(1);
378 fdp->n_args_32 = i;
380 return 0;
384 ParseEquate(int ordinal)
386 ORDDEF *odp;
387 char *token;
388 char *endptr;
389 int value;
391 if (ordinal >= MAX_ORDINALS)
393 fprintf(stderr, "%d: Ordinal number too large\n", Line);
394 exit(1);
397 odp = &OrdinalDefinitions[ordinal];
398 strcpy(odp->export_name, GetToken());
400 token = GetToken();
401 value = strtol(token, &endptr, 0);
402 if (endptr == NULL || *endptr != '\0')
404 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
405 token);
406 exit(1);
409 odp->valid = 1;
410 odp->type = EQUATETYPE_ABS;
411 odp->additional_data = (void *) value;
413 return 0;
417 ParseReturn(int ordinal)
419 ORDDEF *odp;
420 ORDRETDEF *rdp;
421 char *token;
422 char *endptr;
423 int value;
425 if (ordinal >= MAX_ORDINALS)
427 fprintf(stderr, "%d: Ordinal number too large\n", Line);
428 exit(1);
431 rdp = malloc(sizeof(*rdp));
433 odp = &OrdinalDefinitions[ordinal];
434 strcpy(odp->export_name, GetToken());
435 odp->valid = 1;
436 odp->type = TYPE_RETURN;
437 odp->additional_data = rdp;
439 token = GetToken();
440 rdp->arg_size = strtol(token, &endptr, 0);
441 if (endptr == NULL || *endptr != '\0')
443 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
444 token);
445 exit(1);
448 token = GetToken();
449 rdp->ret_value = strtol(token, &endptr, 0);
450 if (endptr == NULL || *endptr != '\0')
452 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
453 token);
454 exit(1);
457 return 0;
461 ParseOrdinal(int ordinal)
463 char *token;
465 token = GetToken();
466 if (token == NULL)
468 fprintf(stderr, "%d: Expected type after ordinal\n", Line);
469 exit(1);
472 if (stricmp(token, "byte") == 0)
473 return ParseVariable(ordinal, VARTYPE_BYTE);
474 else if (stricmp(token, "word") == 0)
475 return ParseVariable(ordinal, VARTYPE_WORD);
476 else if (stricmp(token, "long") == 0)
477 return ParseVariable(ordinal, VARTYPE_LONG);
478 else if (stricmp(token, "c") == 0)
479 return ParseExportFunction(ordinal, FUNCTYPE_C);
480 else if (stricmp(token, "p") == 0)
481 return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
482 else if (stricmp(token, "pascal") == 0)
483 return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
484 else if (stricmp(token, "register") == 0)
485 return ParseExportFunction(ordinal, FUNCTYPE_REG);
486 else if (stricmp(token, "equate") == 0)
487 return ParseEquate(ordinal);
488 else if (stricmp(token, "return") == 0)
489 return ParseReturn(ordinal);
490 else
492 fprintf(stderr,
493 "%d: Expected type after ordinal, found '%s' instead\n",
494 Line, token);
495 exit(1);
500 ParseTopLevel(void)
502 char *token;
504 while ((token = GetToken()) != NULL)
506 if (stricmp(token, "name") == 0)
508 strcpy(LowerDLLName, GetToken());
509 strlower(LowerDLLName);
511 strcpy(UpperDLLName, LowerDLLName);
512 strupper(UpperDLLName);
514 else if (stricmp(token, "id") == 0)
516 token = GetToken();
517 if (!IsNumberString(token))
519 fprintf(stderr, "%d: Expected number after id\n", Line);
520 exit(1);
523 DLLId = atoi(token);
525 else if (stricmp(token, "length") == 0)
527 token = GetToken();
528 if (!IsNumberString(token))
530 fprintf(stderr, "%d: Expected number after length\n", Line);
531 exit(1);
534 Limit = atoi(token);
536 else if (IsNumberString(token))
538 int ordinal;
539 int rv;
541 ordinal = atoi(token);
542 if ((rv = ParseOrdinal(ordinal)) < 0)
543 return rv;
545 else
547 fprintf(stderr,
548 "%d: Expected name, id, length or ordinal\n", Line);
549 exit(1);
553 return 0;
556 void
557 OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp)
559 ORDVARDEF *vdp;
560 int i;
562 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
564 vdp = odp->additional_data;
565 for (i = 0; i < vdp->n_values; i++)
567 if ((i & 7) == 0)
568 fprintf(fp, "\t%s\t", storage);
570 fprintf(fp, "%d", vdp->values[i]);
572 if ((i & 7) == 7 || i == vdp->n_values - 1)
573 fprintf(fp, "\n");
574 else
575 fprintf(fp, ", ");
577 fprintf(fp, "\n");
580 main(int argc, char **argv)
582 ORDDEF *odp;
583 ORDFUNCDEF *fdp;
584 ORDRETDEF *rdp;
585 FILE *fp;
586 char filename[80];
587 char buffer[80];
588 char *p;
589 int i;
591 if (argc < 2)
593 fprintf(stderr, "usage: build SPECNAME\n");
594 exit(1);
597 SpecFp = fopen(argv[1], "r");
598 if (SpecFp == NULL)
600 fprintf(stderr, "Could not open specification file, '%s'\n", argv[1]);
601 exit(1);
604 ParseTopLevel();
606 /**********************************************************************
607 * DLL ENTRY POINTS
609 sprintf(filename, "dll_%s.S", LowerDLLName);
610 fp = fopen(filename, "w");
612 fprintf(fp, "\t.globl _%s_Dispatch\n", UpperDLLName);
613 fprintf(fp, "_%s_Dispatch:\n", UpperDLLName);
614 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
615 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
616 fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
617 fprintf(fp, "\tjmp\t_CallTo32\n\n");
619 odp = OrdinalDefinitions;
620 for (i = 0; i <= Limit; i++, odp++)
622 fprintf(fp, "\t.globl _%s_Ordinal_%d\n", UpperDLLName, i);
624 if (!odp->valid)
626 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
627 #ifdef BOB_SAYS_NO
628 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
629 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
630 #endif
631 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
632 fprintf(fp, "\tpushw\t$0\n");
633 fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
635 else
637 fdp = odp->additional_data;
638 rdp = odp->additional_data;
640 switch (odp->type)
642 case EQUATETYPE_ABS:
643 fprintf(fp, "_%s_Ordinal_%d = %d\n\n",
644 UpperDLLName, i, (int) odp->additional_data);
645 break;
647 case VARTYPE_BYTE:
648 OutputVariableCode(fp, ".byte", odp);
649 break;
651 case VARTYPE_WORD:
652 OutputVariableCode(fp, ".word", odp);
653 break;
655 case VARTYPE_LONG:
656 OutputVariableCode(fp, ".long", odp);
657 break;
659 case TYPE_RETURN:
660 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
661 fprintf(fp, "\tmovw\t$%d,%%ax\n", rdp->ret_value & 0xffff);
662 fprintf(fp, "\tmovw\t$%d,%%dx\n",
663 (rdp->ret_value >> 16) & 0xffff);
664 fprintf(fp, "\t.byte\t0x66\n");
665 if (rdp->arg_size != 0)
666 fprintf(fp, "\tlret\t$%d\n", rdp->arg_size);
667 else
668 fprintf(fp, "\tlret\n");
669 break;
671 case FUNCTYPE_REG:
672 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
673 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
674 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
675 fprintf(fp, "\tpushl\t$0\n"); /* cr2 */
676 fprintf(fp, "\tpushl\t$0\n"); /* oldmask */
677 fprintf(fp, "\tpushl\t$0\n"); /* i387 */
678 fprintf(fp, "\tpushw\t$0\n"); /* __ssh */
679 fprintf(fp, "\tpushw\t%%ss\n"); /* ss */
680 fprintf(fp, "\tpushl\t%%esp\n"); /* esp */
681 fprintf(fp, "\tpushfl\n"); /* eflags */
682 fprintf(fp, "\tpushw\t$0\n"); /* __csh */
683 fprintf(fp, "\tpushw\t%%cs\n"); /* cs */
684 fprintf(fp, "\tpushl\t$0\n"); /* eip */
685 fprintf(fp, "\tpushl\t$0\n"); /* err */
686 fprintf(fp, "\tpushl\t$0\n"); /* trapno */
687 fprintf(fp, "\tpushal\n"); /* AX, ... */
688 fprintf(fp, "\tpushw\t$0\n"); /* __dsh */
689 fprintf(fp, "\tpushw\t%%ds\n"); /* ds */
690 fprintf(fp, "\tpushw\t$0\n"); /* __esh */
691 fprintf(fp, "\tpushw\t%%es\n"); /* es */
692 fprintf(fp, "\tpushw\t$0\n"); /* __fsh */
693 fprintf(fp, "\tpushw\t%%fs\n"); /* fs */
694 fprintf(fp, "\tpushw\t$0\n"); /* __gsh */
695 fprintf(fp, "\tpushw\t%%gs\n"); /* gs */
696 fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
697 fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
698 fprintf(fp, "\tpushl\t88(%%ebp)\n");
699 fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
700 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
701 fprintf(fp, "\tpushw\t$92\n");
702 fprintf(fp, "\tjmp\t_%s_Relay_%d:\n", UpperDLLName, i);
703 break;
705 case FUNCTYPE_PASCAL:
706 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
707 #ifdef BOB_SAYS_NO
708 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
709 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
710 #endif
711 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
712 fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
713 fprintf(fp, "\tjmp\t_%s_Relay_%d:\n", UpperDLLName, i);
714 break;
716 case FUNCTYPE_C:
717 default:
718 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
719 #ifdef BOB_SAYS_NO
720 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
721 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
722 #endif
723 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
724 fprintf(fp, "\tpushw\t$0\n");
725 fprintf(fp, "\tjmp\t_%s_Relay_%d:\n", UpperDLLName, i);
726 break;
731 fclose(fp);
733 /**********************************************************************
734 * RELAY CODE
736 sprintf(filename, "rly_%s.S", LowerDLLName);
737 fp = fopen(filename, "w");
739 odp = OrdinalDefinitions;
740 for (i = 0; i <= Limit; i++, odp++)
742 if (!odp->valid)
743 continue;
745 fdp = odp->additional_data;
747 fprintf(fp, "\t.globl _%s_Relay_%d\n", UpperDLLName, i);
748 fprintf(fp, "_%s_Relay_%d:\n", UpperDLLName, i);
749 fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
750 fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
752 fprintf(fp, "\tpushl\t%%ebp\n");
753 fprintf(fp, "\tmovl\t%%esp,%%ebp\n");
756 * Save registers. 286 mode does not have fs or gs.
758 fprintf(fp, "\tpushw\t%%ds\n");
759 fprintf(fp, "\tpushw\t%%es\n");
762 * Restore segment registers.
764 fprintf(fp, "\tmovw\t%d,%%ax\n", UDATASEL);
765 fprintf(fp, "\tmovw\t%%ax,%%ds\n");
766 fprintf(fp, "\tmovw\t%%ax,%%es\n");
769 * Save old stack save variables, save stack registers, reload
770 * stack registers.
772 fprintf(fp, "\tpushl\t_IF1632_Saved16_esp\n");
773 fprintf(fp, "\tpushl\t_IF1632_Saved16_ebp\n");
774 fprintf(fp, "\tpushw\t_IF1632_Saved16_ss\n");
776 fprintf(fp, "\tmovw\t%%ss,_IF1632_Saved16_ss\n");
777 fprintf(fp, "\tmovl\t%%esp,_IF1632_Saved16_esp\n");
778 fprintf(fp, "\tmovl\t%%ebp,_IF1632_Saved16_ebp\n");
780 fprintf(fp, "\tmovw\t%%ss,%%ax\n");
781 fprintf(fp, "\tshll\t16,%%eax\n");
782 fprintf(fp, "\torl\t%%esp,%%eax\n");
784 fprintf(fp, "\tmovw\t_IF1632_Saved32_ss,%%ss\n");
785 fprintf(fp, "\tmovl\t_IF1632_Saved32_esp,%%esp\n");
786 fprintf(fp, "\tmovl\t_IF1632_Saved32_ebp,%%ebp\n");
788 fprintf(fp, "\tpushl\t_Stack16Frame\n");
789 fprintf(fp, "\tmovl\t%%eax,_Stack16Frame\n");
792 * Move arguments.
797 * Call entry point
799 fprintf(fp, "\tcall\t%s\n", fdp->internal_name);
802 * Restore registers, but do not destroy return value.
804 fprintf(fp, "\tmovw\t_IF1632_Saved16_ss,%%ss\n");
805 fprintf(fp, "\tmovl\t_IF1632_Saved16_esp,%%esp\n");
806 fprintf(fp, "\tmovl\t_IF1632_Saved16_ebp,%%ebp\n");
808 fprintf(fp, "\tpopw\t_IF1632_Saved16_ss\n");
809 fprintf(fp, "\tpopl\t_IF1632_Saved16_ebp\n");
810 fprintf(fp, "\tpopl\t_IF1632_Saved16_esp\n");
812 fprintf(fp, "\tpopw\t%%es\n");
813 fprintf(fp, "\tpopw\t%%ds\n");
815 fprintf(fp, "\t.align\t2,0x90\n");
816 fprintf(fp, "\tleave\n");
819 * Now we need to ditch the parameter bytes that were left on the
820 * stack. We do this by effectively popping the number of bytes,
821 * and the return address, removing the parameters and then putting
822 * the return address back on the stack.
823 * Normally this field is filled in by the relevant function in
824 * the emulation library, since it should know how many bytes to
825 * expect.
827 fprintf(fp, "\tpopw\t%%gs:nbytes\n");
828 fprintf(fp, "\tcmpw\t$0,%%gs:nbytes\n");
829 fprintf(fp, "\tje\tnoargs\n");
830 fprintf(fp, "\tpopw\t%%gs:offset\n");
831 fprintf(fp, "\tpopw\t%%gs:selector\n");
832 fprintf(fp, "\taddw\t%%gs:nbytes,%%esp\n");
833 fprintf(fp, "\tpushw\t%%gs:selector\n");
834 fprintf(fp, "\tpushw\t%%gs:offset\n");
835 fprintf(fp, "noargs:\n");
838 * Last, but not least we need to move the high word from eax to dx
840 fprintf(fp, "\t pushl\t%%eax\n");
841 fprintf(fp, "\tpopw\t%%dx\n");
842 fprintf(fp, "\tpopw\t%%dx\n");
844 fprintf(fp, "\t.byte\t0x66\n");
845 fprintf(fp, "\tlret\n");
849 fclose(fp);
851 /**********************************************************************
852 * DLL ENTRY TABLE
854 #ifndef SHORTNAMES
855 sprintf(filename, "dll_%s_tab.c", LowerDLLName);
856 #else
857 sprintf(filename, "dtb_%s.c", LowerDLLName);
858 #endif
859 fp = fopen(filename, "w");
861 fprintf(fp, "#include <stdio.h>\n");
862 fprintf(fp, "#include <stdlib.h>\n");
863 fprintf(fp, "#include \042dlls.h\042\n\n");
865 for (i = 0; i <= Limit; i++)
867 fprintf(fp, "extern void %s_Ordinal_%d();\n", UpperDLLName, i);
870 odp = OrdinalDefinitions;
871 for (i = 0; i <= Limit; i++, odp++)
873 if (odp->valid &&
874 (odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_C ||
875 odp->type == FUNCTYPE_REG))
877 fdp = odp->additional_data;
878 fprintf(fp, "extern int %s();\n", fdp->internal_name);
882 fprintf(fp, "\nstruct dll_table_entry_s %s_table[%d] =\n",
883 UpperDLLName, Limit + 1);
884 fprintf(fp, "{\n");
885 odp = OrdinalDefinitions;
886 for (i = 0; i <= Limit; i++, odp++)
888 fdp = odp->additional_data;
890 if (!odp->valid)
891 odp->type = -1;
893 switch (odp->type)
895 case FUNCTYPE_PASCAL:
896 case FUNCTYPE_REG:
897 fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
898 fprintf(fp, "\042%s\042, ", odp->export_name);
899 fprintf(fp, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp->internal_name);
900 #ifdef WINESTAT
901 fprintf(fp, "0, ");
902 #endif
903 fprintf(fp, "%d, ", fdp->n_args_32);
904 if (fdp->n_args_32 > 0)
906 int argnum;
908 fprintf(fp, "\n {\n");
909 for (argnum = 0; argnum < fdp->n_args_32; argnum++)
911 fprintf(fp, " { %d, %d },\n",
912 fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
913 fdp->arg_types_16[argnum]);
915 fprintf(fp, " }\n ");
917 fprintf(fp, "}, \n");
918 break;
920 case FUNCTYPE_C:
921 fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
922 fprintf(fp, "\042%s\042, ", odp->export_name);
923 fprintf(fp, "%s, DLL_HANDLERTYPE_C, ", fdp->internal_name);
924 #ifdef WINESTAT
925 fprintf(fp, "0, ");
926 #endif
927 fprintf(fp, "%d, ", fdp->n_args_32);
928 if (fdp->n_args_32 > 0)
930 int argnum;
932 fprintf(fp, "\n {\n");
933 for (argnum = 0; argnum < fdp->n_args_32; argnum++)
935 fprintf(fp, " { %d, %d },\n",
936 fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
937 fdp->arg_types_16[argnum]);
939 fprintf(fp, " }\n ");
941 fprintf(fp, "}, \n");
942 break;
944 default:
945 fprintf(fp, " { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n",
946 UTEXTSEL, UpperDLLName, i);
947 break;
950 fprintf(fp, "};\n");
952 fclose(fp);