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";
12 #if defined(__NetBSD__) || defined(__FreeBSD__)
16 #define VARTYPE_BYTE 0
17 #define VARTYPE_SIGNEDWORD 0
18 #define VARTYPE_WORD 1
19 #define VARTYPE_LONG 2
20 #define VARTYPE_FARPTR 3
22 #define FUNCTYPE_PASCAL 16
24 #define FUNCTYPE_REG 19
26 #define EQUATETYPE_ABS 18
27 #define TYPE_RETURN 20
29 #define MAX_ORDINALS 1024
31 typedef struct ordinal_definition_s
36 void *additional_data
;
39 typedef struct ordinal_variable_definition_s
45 typedef struct ordinal_function_definition_s
49 int arg_16_offsets
[16];
51 char internal_name
[80];
53 int arg_indices_32
[16];
56 typedef struct ordinal_return_definition_s
62 ORDDEF OrdinalDefinitions
[MAX_ORDINALS
];
64 char LowerDLLName
[80];
65 char UpperDLLName
[80];
70 char *ParseBuffer
= NULL
;
75 int IsNumberString(char *s
)
84 char *strlower(char *s
)
88 for(p
= s
; *p
!= '\0'; p
++)
94 char *strupper(char *s
)
98 for(p
= s
; *p
!= '\0'; p
++)
104 int stricmp(char *s1
, char *s2
)
106 if (strlen(s1
) != strlen(s2
))
122 if (ParseNext
!= ParseBuffer
)
124 if (ParseSaveChar
== '\0')
126 *ParseNext
= ParseSaveChar
;
130 * Remove initial white space.
132 for (p
= ParseNext
; isspace(*p
); p
++)
142 if (*token
!= '(' && *token
!= ')')
143 while (*p
!= '\0' && *p
!= '(' && *p
!= ')' && !isspace(*p
))
158 if (ParseBuffer
== NULL
)
160 ParseBuffer
= malloc(512);
161 ParseNext
= ParseBuffer
;
165 if (fgets(ParseBuffer
, 511, SpecFp
) == NULL
)
167 if (ParseBuffer
[0] != '#')
172 while ((token
= GetTokenInLine()) == NULL
)
174 ParseNext
= ParseBuffer
;
178 if (fgets(ParseBuffer
, 511, SpecFp
) == NULL
)
180 if (ParseBuffer
[0] != '#')
189 ParseVariable(int ordinal
, int type
)
193 char export_name
[80];
198 int value_array_size
;
200 strcpy(export_name
, GetToken());
205 fprintf(stderr
, "%d: Expected '(' got '%s'\n", Line
, token
);
210 value_array_size
= 25;
211 value_array
= malloc(sizeof(*value_array
) * value_array_size
);
213 while ((token
= GetToken()) != NULL
)
218 value_array
[n_values
++] = strtol(token
, &endptr
, 0);
219 if (n_values
== value_array_size
)
221 value_array_size
+= 25;
222 value_array
= realloc(value_array
,
223 sizeof(*value_array
) * value_array_size
);
226 if (endptr
== NULL
|| *endptr
!= '\0')
228 fprintf(stderr
, "%d: Expected number value, got '%s'\n", Line
,
236 fprintf(stderr
, "%d: End of file in variable declaration\n", Line
);
240 if (ordinal
>= MAX_ORDINALS
)
242 fprintf(stderr
, "%d: Ordinal number too large\n", Line
);
246 odp
= &OrdinalDefinitions
[ordinal
];
249 strcpy(odp
->export_name
, export_name
);
251 vdp
= malloc(sizeof(*vdp
));
252 odp
->additional_data
= vdp
;
254 vdp
->n_values
= n_values
;
255 vdp
->values
= realloc(value_array
, sizeof(*value_array
) * n_values
);
261 ParseExportFunction(int ordinal
, int type
)
273 if (ordinal
>= MAX_ORDINALS
)
275 fprintf(stderr
, "%d: Ordinal number too large\n", Line
);
279 odp
= &OrdinalDefinitions
[ordinal
];
280 strcpy(odp
->export_name
, GetToken());
283 fdp
= malloc(sizeof(*fdp
));
284 odp
->additional_data
= fdp
;
289 fprintf(stderr
, "%d: Expected '(' got '%s'\n", Line
, token
);
293 fdp
->arg_16_size
= 0;
294 for (i
= 0; i
< 16; i
++)
300 if (stricmp(token
, "byte") == 0 || stricmp(token
, "word") == 0)
302 fdp
->arg_types_16
[i
] = VARTYPE_WORD
;
303 fdp
->arg_16_size
+= 2;
304 fdp
->arg_16_offsets
[i
] = 2;
306 else if (stricmp(token
, "s_byte") == 0 ||
307 stricmp(token
, "s_word") == 0)
309 fdp
->arg_types_16
[i
] = VARTYPE_SIGNEDWORD
;
310 fdp
->arg_16_size
+= 2;
311 fdp
->arg_16_offsets
[i
] = 2;
313 else if (stricmp(token
, "long") == 0 || stricmp(token
, "s_long") == 0)
315 fdp
->arg_types_16
[i
] = VARTYPE_LONG
;
316 fdp
->arg_16_size
+= 4;
317 fdp
->arg_16_offsets
[i
] = 4;
319 else if (stricmp(token
, "ptr") == 0)
321 fdp
->arg_types_16
[i
] = VARTYPE_FARPTR
;
322 fdp
->arg_16_size
+= 4;
323 fdp
->arg_16_offsets
[i
] = 4;
327 fprintf(stderr
, "%d: Unknown variable type '%s'\n", Line
, token
);
333 if (type
== FUNCTYPE_PASCAL
|| type
== FUNCTYPE_REG
)
336 for (i
--; i
>= 0; i
--)
338 arg_size
= fdp
->arg_16_offsets
[i
];
339 fdp
->arg_16_offsets
[i
] = current_offset
;
340 current_offset
+= arg_size
;
346 for (i
= 0; i
< fdp
->n_args_16
; i
++)
348 arg_size
= fdp
->arg_16_offsets
[i
];
349 fdp
->arg_16_offsets
[i
] = current_offset
;
350 current_offset
+= arg_size
;
354 strcpy(fdp
->internal_name
, GetToken());
358 fprintf(stderr
, "%d: Expected '(' got '%s'\n", Line
, token
);
361 for (i
= 0; i
< 16; i
++)
367 fdp
->arg_indices_32
[i
] = atoi(token
);
368 if (fdp
->arg_indices_32
[i
] < 1 ||
369 fdp
->arg_indices_32
[i
] > fdp
->n_args_16
)
371 fprintf(stderr
, "%d: Bad argument index %d\n", Line
,
372 fdp
->arg_indices_32
[i
]);
382 ParseEquate(int ordinal
)
389 if (ordinal
>= MAX_ORDINALS
)
391 fprintf(stderr
, "%d: Ordinal number too large\n", Line
);
395 odp
= &OrdinalDefinitions
[ordinal
];
396 strcpy(odp
->export_name
, GetToken());
399 value
= strtol(token
, &endptr
, 0);
400 if (endptr
== NULL
|| *endptr
!= '\0')
402 fprintf(stderr
, "%d: Expected number value, got '%s'\n", Line
,
408 odp
->type
= EQUATETYPE_ABS
;
409 odp
->additional_data
= (void *) value
;
415 ParseReturn(int ordinal
)
423 if (ordinal
>= MAX_ORDINALS
)
425 fprintf(stderr
, "%d: Ordinal number too large\n", Line
);
429 rdp
= malloc(sizeof(*rdp
));
431 odp
= &OrdinalDefinitions
[ordinal
];
432 strcpy(odp
->export_name
, GetToken());
434 odp
->type
= TYPE_RETURN
;
435 odp
->additional_data
= rdp
;
438 rdp
->arg_size
= strtol(token
, &endptr
, 0);
439 if (endptr
== NULL
|| *endptr
!= '\0')
441 fprintf(stderr
, "%d: Expected number value, got '%s'\n", Line
,
447 rdp
->ret_value
= strtol(token
, &endptr
, 0);
448 if (endptr
== NULL
|| *endptr
!= '\0')
450 fprintf(stderr
, "%d: Expected number value, got '%s'\n", Line
,
459 ParseOrdinal(int ordinal
)
466 fprintf(stderr
, "%d: Expected type after ordinal\n", Line
);
470 if (stricmp(token
, "byte") == 0)
471 return ParseVariable(ordinal
, VARTYPE_BYTE
);
472 else if (stricmp(token
, "word") == 0)
473 return ParseVariable(ordinal
, VARTYPE_WORD
);
474 else if (stricmp(token
, "long") == 0)
475 return ParseVariable(ordinal
, VARTYPE_LONG
);
476 else if (stricmp(token
, "c") == 0)
477 return ParseExportFunction(ordinal
, FUNCTYPE_C
);
478 else if (stricmp(token
, "p") == 0)
479 return ParseExportFunction(ordinal
, FUNCTYPE_PASCAL
);
480 else if (stricmp(token
, "pascal") == 0)
481 return ParseExportFunction(ordinal
, FUNCTYPE_PASCAL
);
482 else if (stricmp(token
, "register") == 0)
483 return ParseExportFunction(ordinal
, FUNCTYPE_REG
);
484 else if (stricmp(token
, "equate") == 0)
485 return ParseEquate(ordinal
);
486 else if (stricmp(token
, "return") == 0)
487 return ParseReturn(ordinal
);
491 "%d: Expected type after ordinal, found '%s' instead\n",
502 while ((token
= GetToken()) != NULL
)
504 if (stricmp(token
, "name") == 0)
506 strcpy(LowerDLLName
, GetToken());
507 strlower(LowerDLLName
);
509 strcpy(UpperDLLName
, LowerDLLName
);
510 strupper(UpperDLLName
);
512 else if (stricmp(token
, "id") == 0)
515 if (!IsNumberString(token
))
517 fprintf(stderr
, "%d: Expected number after id\n", Line
);
523 else if (stricmp(token
, "length") == 0)
526 if (!IsNumberString(token
))
528 fprintf(stderr
, "%d: Expected number after length\n", Line
);
534 else if (IsNumberString(token
))
539 ordinal
= atoi(token
);
540 if ((rv
= ParseOrdinal(ordinal
)) < 0)
546 "%d: Expected name, id, length or ordinal\n", Line
);
555 OutputVariableCode(FILE *fp
, char *storage
, ORDDEF
*odp
)
560 fprintf(fp
, "_%s_Ordinal_%d:\n", UpperDLLName
, i
);
562 vdp
= odp
->additional_data
;
563 for (i
= 0; i
< vdp
->n_values
; i
++)
566 fprintf(fp
, "\t%s\t", storage
);
568 fprintf(fp
, "%d", vdp
->values
[i
]);
570 if ((i
& 7) == 7 || i
== vdp
->n_values
- 1)
578 main(int argc
, char **argv
)
591 fprintf(stderr
, "usage: build SPECNAME\n");
595 SpecFp
= fopen(argv
[1], "r");
598 fprintf(stderr
, "Could not open specification file, '%s'\n", argv
[1]);
604 sprintf(filename
, "dll_%s.S", LowerDLLName
);
605 fp
= fopen(filename
, "w");
607 fprintf(fp
, "\t.globl _%s_Dispatch\n", UpperDLLName
);
608 fprintf(fp
, "_%s_Dispatch:\n", UpperDLLName
);
609 fprintf(fp
, "\tandl\t$0x0000ffff,%%esp\n");
610 fprintf(fp
, "\tandl\t$0x0000ffff,%%ebp\n");
611 fprintf(fp
, "\torl\t$0x%08x,%%eax\n", DLLId
<< 16);
612 fprintf(fp
, "\tjmp\t_CallTo32\n\n");
614 odp
= OrdinalDefinitions
;
615 for (i
= 0; i
<= Limit
; i
++, odp
++)
617 fprintf(fp
, "\t.globl _%s_Ordinal_%d\n", UpperDLLName
, i
);
621 fprintf(fp
, "_%s_Ordinal_%d:\n", UpperDLLName
, i
);
623 fprintf(fp
, "\tandl\t$0x0000ffff,%%esp\n");
624 fprintf(fp
, "\tandl\t$0x0000ffff,%%ebp\n");
626 fprintf(fp
, "\tmovl\t$%d,%%eax\n", i
);
627 fprintf(fp
, "\tpushw\t$0\n");
628 fprintf(fp
, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName
);
632 fdp
= odp
->additional_data
;
633 rdp
= odp
->additional_data
;
638 fprintf(fp
, "_%s_Ordinal_%d = %d\n\n",
639 UpperDLLName
, i
, (int) odp
->additional_data
);
643 OutputVariableCode(fp
, ".byte", odp
);
647 OutputVariableCode(fp
, ".word", odp
);
651 OutputVariableCode(fp
, ".long", odp
);
655 fprintf(fp
, "_%s_Ordinal_%d:\n", UpperDLLName
, i
);
656 fprintf(fp
, "\tmovw\t$%d,%%ax\n", rdp
->ret_value
& 0xffff);
657 fprintf(fp
, "\tmovw\t$%d,%%dx\n",
658 (rdp
->ret_value
>> 16) & 0xffff);
659 fprintf(fp
, "\t.byte\t0x66\n");
660 if (rdp
->arg_size
!= 0)
661 fprintf(fp
, "\tlret\t$%d\n", rdp
->arg_size
);
663 fprintf(fp
, "\tlret\n");
667 fprintf(fp
, "_%s_Ordinal_%d:\n", UpperDLLName
, i
);
668 fprintf(fp
, "\tandl\t$0x0000ffff,%%esp\n");
669 fprintf(fp
, "\tandl\t$0x0000ffff,%%ebp\n");
670 fprintf(fp
, "\tpushl\t$0\n"); /* cr2 */
671 fprintf(fp
, "\tpushl\t$0\n"); /* oldmask */
672 fprintf(fp
, "\tpushl\t$0\n"); /* i387 */
673 fprintf(fp
, "\tpushw\t$0\n"); /* __ssh */
674 fprintf(fp
, "\tpushw\t%%ss\n"); /* ss */
675 fprintf(fp
, "\tpushl\t%%esp\n"); /* esp */
676 fprintf(fp
, "\tpushfl\n"); /* eflags */
677 fprintf(fp
, "\tpushw\t$0\n"); /* __csh */
678 fprintf(fp
, "\tpushw\t%%cs\n"); /* cs */
679 fprintf(fp
, "\tpushl\t$0\n"); /* eip */
680 fprintf(fp
, "\tpushl\t$0\n"); /* err */
681 fprintf(fp
, "\tpushl\t$0\n"); /* trapno */
682 fprintf(fp
, "\tpushal\n"); /* AX, ... */
683 fprintf(fp
, "\tpushw\t$0\n"); /* __dsh */
684 fprintf(fp
, "\tpushw\t%%ds\n"); /* ds */
685 fprintf(fp
, "\tpushw\t$0\n"); /* __esh */
686 fprintf(fp
, "\tpushw\t%%es\n"); /* es */
687 fprintf(fp
, "\tpushw\t$0\n"); /* __fsh */
688 fprintf(fp
, "\tpushw\t%%fs\n"); /* fs */
689 fprintf(fp
, "\tpushw\t$0\n"); /* __gsh */
690 fprintf(fp
, "\tpushw\t%%gs\n"); /* gs */
691 fprintf(fp
, "\tmovl\t%%ebp,%%eax\n");
692 fprintf(fp
, "\tmovw\t%%esp,%%ebp\n");
693 fprintf(fp
, "\tpushl\t88(%%ebp)\n");
694 fprintf(fp
, "\tmovl\t%%eax,%%ebp\n");
695 fprintf(fp
, "\tmovl\t$%d,%%eax\n", i
);
696 fprintf(fp
, "\tpushw\t$92\n");
697 fprintf(fp
, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName
);
699 fprintf(fp
, "\tpushw\t%%ax\n");
700 fprintf(fp
, "\tpushw\t%%cx\n");
701 fprintf(fp
, "\tpushw\t%%dx\n");
702 fprintf(fp
, "\tpushw\t%%bx\n");
703 fprintf(fp
, "\tpushw\t%%sp\n");
704 fprintf(fp
, "\tpushw\t%%bp\n");
705 fprintf(fp
, "\tpushw\t%%si\n");
706 fprintf(fp
, "\tpushw\t%%di\n");
707 fprintf(fp
, "\tpushw\t%%ds\n");
708 fprintf(fp
, "\tpushw\t%%es\n");
709 fprintf(fp
, "\tmovl\t%%ebp,%%eax\n");
710 fprintf(fp
, "\tmovw\t%%esp,%%ebp\n");
711 fprintf(fp
, "\tpushl\t20(%%ebp)\n");
712 fprintf(fp
, "\tmovl\t%%eax,%%ebp\n");
713 fprintf(fp
, "\tmovl\t$%d,%%eax\n", i
);
714 fprintf(fp
, "\tpushw\t$24\n");
715 fprintf(fp
, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName
);
719 case FUNCTYPE_PASCAL
:
720 fprintf(fp
, "_%s_Ordinal_%d:\n", UpperDLLName
, i
);
722 fprintf(fp
, "\tandl\t$0x0000ffff,%%esp\n");
723 fprintf(fp
, "\tandl\t$0x0000ffff,%%ebp\n");
725 fprintf(fp
, "\tmovl\t$%d,%%eax\n", i
);
726 fprintf(fp
, "\tpushw\t$%d\n", fdp
->arg_16_size
);
727 fprintf(fp
, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName
);
732 fprintf(fp
, "_%s_Ordinal_%d:\n", UpperDLLName
, i
);
734 fprintf(fp
, "\tandl\t$0x0000ffff,%%esp\n");
735 fprintf(fp
, "\tandl\t$0x0000ffff,%%ebp\n");
737 fprintf(fp
, "\tmovl\t$%d,%%eax\n", i
);
738 fprintf(fp
, "\tpushw\t$0\n");
739 fprintf(fp
, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName
);
747 sprintf(filename
, "dll_%s_tab.c", LowerDLLName
);
748 fp
= fopen(filename
, "w");
750 fprintf(fp
, "#include <stdio.h>\n");
751 fprintf(fp
, "#include <stdlib.h>\n");
752 fprintf(fp
, "#include \042dlls.h\042\n\n");
754 for (i
= 0; i
<= Limit
; i
++)
756 fprintf(fp
, "extern void %s_Ordinal_%d();\n", UpperDLLName
, i
);
759 odp
= OrdinalDefinitions
;
760 for (i
= 0; i
<= Limit
; i
++, odp
++)
763 (odp
->type
== FUNCTYPE_PASCAL
|| odp
->type
== FUNCTYPE_C
||
764 odp
->type
== FUNCTYPE_REG
))
766 fdp
= odp
->additional_data
;
767 fprintf(fp
, "extern int %s();\n", fdp
->internal_name
);
771 fprintf(fp
, "\nstruct dll_table_entry_s %s_table[%d] =\n",
772 UpperDLLName
, Limit
+ 1);
774 odp
= OrdinalDefinitions
;
775 for (i
= 0; i
<= Limit
; i
++, odp
++)
777 fdp
= odp
->additional_data
;
784 case FUNCTYPE_PASCAL
:
786 fprintf(fp
, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL
, UpperDLLName
, i
);
787 fprintf(fp
, "\042%s\042, ", odp
->export_name
);
788 fprintf(fp
, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp
->internal_name
);
792 fprintf(fp
, "%d, ", fdp
->n_args_32
);
793 if (fdp
->n_args_32
> 0)
797 fprintf(fp
, "\n {\n");
798 for (argnum
= 0; argnum
< fdp
->n_args_32
; argnum
++)
800 fprintf(fp
, " { %d, %d },\n",
801 fdp
->arg_16_offsets
[fdp
->arg_indices_32
[argnum
]-1],
802 fdp
->arg_types_16
[argnum
]);
804 fprintf(fp
, " }\n ");
806 fprintf(fp
, "}, \n");
810 fprintf(fp
, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL
, UpperDLLName
, i
);
811 fprintf(fp
, "\042%s\042, ", odp
->export_name
);
812 fprintf(fp
, "%s, DLL_HANDLERTYPE_C, ", fdp
->internal_name
);
816 fprintf(fp
, "%d, ", fdp
->n_args_32
);
817 if (fdp
->n_args_32
> 0)
821 fprintf(fp
, "\n {\n");
822 for (argnum
= 0; argnum
< fdp
->n_args_32
; argnum
++)
824 fprintf(fp
, " { %d, %d },\n",
825 fdp
->arg_16_offsets
[fdp
->arg_indices_32
[argnum
]-1],
826 fdp
->arg_types_16
[argnum
]);
828 fprintf(fp
, " }\n ");
830 fprintf(fp
, "}, \n");
834 fprintf(fp
, " { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n",
835 UTEXTSEL
, UpperDLLName
, i
);