2 * Copyright Robert J. Amstadt, 1993
10 #define VARTYPE_SIGNEDWORD 0
11 #define VARTYPE_WORD 1
12 #define VARTYPE_LONG 2
13 #define VARTYPE_FARPTR 3
15 #define FUNCTYPE_PASCAL 16
17 #define FUNCTYPE_REG 19
19 #define EQUATETYPE_ABS 18
21 #define MAX_ORDINALS 1024
23 typedef struct ordinal_definition_s
28 void *additional_data;
31 typedef struct ordinal_variable_definition_s
37 typedef struct ordinal_function_definition_s
41 int arg_16_offsets[16];
43 char internal_name[80];
45 int arg_indices_32[16];
48 ORDDEF OrdinalDefinitions[MAX_ORDINALS];
50 char LowerDLLName[80];
51 char UpperDLLName[80];
56 char *ParseBuffer = NULL;
61 int IsNumberString(char *s)
70 char *strlower(char *s)
74 for(p = s; *p != '\0'; p++)
80 char *strupper(char *s)
84 for(p = s; *p != '\0'; p++)
90 int stricmp(char *s1, char *s2)
92 if (strlen(s1) != strlen(s2))
108 if (ParseNext != ParseBuffer)
110 if (ParseSaveChar == '\0')
112 *ParseNext = ParseSaveChar;
116 * Remove initial white space.
118 for (p = ParseNext; isspace(*p); p++)
128 if (*token != '(' && *token != ')')
129 while (*p != '\0' && *p != '(' && *p != ')' && !isspace(*p))
144 if (ParseBuffer == NULL)
146 ParseBuffer = malloc(512);
147 ParseNext = ParseBuffer;
149 if (fgets(ParseBuffer, 511, SpecFp) == NULL)
153 while ((token = GetTokenInLine()) == NULL)
155 ParseNext = ParseBuffer;
157 if (fgets(ParseBuffer, 511, SpecFp) == NULL)
165 ParseVariable(int ordinal, int type)
169 char export_name[80];
174 int value_array_size;
176 strcpy(export_name, GetToken());
181 fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
186 value_array_size = 25;
187 value_array = malloc(sizeof(*value_array) * value_array_size);
189 while ((token = GetToken()) != NULL)
194 value_array[n_values++] = strtol(token, &endptr, 0);
195 if (n_values == value_array_size)
197 value_array_size += 25;
198 value_array = realloc(value_array,
199 sizeof(*value_array) * value_array_size);
202 if (endptr == NULL || *endptr != '\0')
204 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
212 fprintf(stderr, "%d: End of file in variable declaration\n", Line);
216 if (ordinal >= MAX_ORDINALS)
218 fprintf(stderr, "%d: Ordinal number too large\n", Line);
222 odp = &OrdinalDefinitions[ordinal];
225 strcpy(odp->export_name, export_name);
227 vdp = malloc(sizeof(*vdp));
228 odp->additional_data = vdp;
230 vdp->n_values = n_values;
231 vdp->values = realloc(value_array, sizeof(*value_array) * n_values);
237 ParseExportFunction(int ordinal, int type)
249 if (ordinal >= MAX_ORDINALS)
251 fprintf(stderr, "%d: Ordinal number too large\n", Line);
255 odp = &OrdinalDefinitions[ordinal];
256 strcpy(odp->export_name, GetToken());
259 fdp = malloc(sizeof(*fdp));
260 odp->additional_data = fdp;
265 fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
269 fdp->arg_16_size = 0;
270 for (i = 0; i < 16; i++)
276 if (stricmp(token, "byte") == 0 || stricmp(token, "word") == 0)
278 fdp->arg_types_16[i] = VARTYPE_WORD;
279 fdp->arg_16_size += 2;
280 fdp->arg_16_offsets[i] = 2;
282 else if (stricmp(token, "s_byte") == 0 ||
283 stricmp(token, "s_word") == 0)
285 fdp->arg_types_16[i] = VARTYPE_SIGNEDWORD;
286 fdp->arg_16_size += 2;
287 fdp->arg_16_offsets[i] = 2;
289 else if (stricmp(token, "long") == 0 || stricmp(token, "s_long") == 0)
291 fdp->arg_types_16[i] = VARTYPE_LONG;
292 fdp->arg_16_size += 4;
293 fdp->arg_16_offsets[i] = 4;
295 else if (stricmp(token, "ptr") == 0)
297 fdp->arg_types_16[i] = VARTYPE_FARPTR;
298 fdp->arg_16_size += 4;
299 fdp->arg_16_offsets[i] = 4;
303 fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token);
309 if (type == FUNCTYPE_PASCAL || type == FUNCTYPE_REG)
312 for (i--; i >= 0; i--)
314 arg_size = fdp->arg_16_offsets[i];
315 fdp->arg_16_offsets[i] = current_offset;
316 current_offset += arg_size;
322 for (i = 0; i < fdp->n_args_16; i++)
324 arg_size = fdp->arg_16_offsets[i];
325 fdp->arg_16_offsets[i] = current_offset;
326 current_offset += arg_size;
330 strcpy(fdp->internal_name, GetToken());
334 fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
337 for (i = 0; i < 16; i++)
343 fdp->arg_indices_32[i] = atoi(token);
344 if (fdp->arg_indices_32[i] < 1 ||
345 fdp->arg_indices_32[i] > fdp->n_args_16)
347 fprintf(stderr, "%d: Bad argument index %d\n", Line,
348 fdp->arg_indices_32[i]);
358 ParseEquate(int ordinal)
365 if (ordinal >= MAX_ORDINALS)
367 fprintf(stderr, "%d: Ordinal number too large\n", Line);
371 odp = &OrdinalDefinitions[ordinal];
372 strcpy(odp->export_name, GetToken());
375 value = strtol(token, &endptr, 0);
376 if (endptr == NULL || *endptr != '\0')
378 fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
384 odp->type = EQUATETYPE_ABS;
385 odp->additional_data = (void *) value;
391 ParseOrdinal(int ordinal)
398 fprintf(stderr, "%d: Expected type after ordinal\n", Line);
402 if (stricmp(token, "byte") == 0)
403 return ParseVariable(ordinal, VARTYPE_BYTE);
404 else if (stricmp(token, "word") == 0)
405 return ParseVariable(ordinal, VARTYPE_WORD);
406 else if (stricmp(token, "long") == 0)
407 return ParseVariable(ordinal, VARTYPE_LONG);
408 else if (stricmp(token, "c") == 0)
409 return ParseExportFunction(ordinal, FUNCTYPE_C);
410 else if (stricmp(token, "p") == 0)
411 return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
412 else if (stricmp(token, "pascal") == 0)
413 return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
414 else if (stricmp(token, "register") == 0)
415 return ParseExportFunction(ordinal, FUNCTYPE_REG);
416 else if (stricmp(token, "equate") == 0)
417 return ParseEquate(ordinal);
421 "%d: Expected type after ordinal, found '%s' instead\n",
432 while ((token = GetToken()) != NULL)
434 if (stricmp(token, "name") == 0)
436 strcpy(LowerDLLName, GetToken());
437 strlower(LowerDLLName);
439 strcpy(UpperDLLName, LowerDLLName);
440 strupper(UpperDLLName);
442 else if (stricmp(token, "id") == 0)
445 if (!IsNumberString(token))
447 fprintf(stderr, "%d: Expected number after id\n", Line);
453 else if (stricmp(token, "length") == 0)
456 if (!IsNumberString(token))
458 fprintf(stderr, "%d: Expected number after length\n", Line);
464 else if (IsNumberString(token))
469 ordinal = atoi(token);
470 if ((rv = ParseOrdinal(ordinal)) < 0)
476 "%d: Expected name, id, length or ordinal\n", Line);
485 OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp)
490 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
492 vdp = odp->additional_data;
493 for (i = 0; i < vdp->n_values; i++)
496 fprintf(fp, "\t%s\t", storage);
498 fprintf(fp, "%d", vdp->values[i]);
500 if ((i & 7) == 7 || i == vdp->n_values - 1)
508 main(int argc, char **argv)
520 fprintf(stderr, "usage: build SPECNAME\n");
524 SpecFp = fopen(argv[1], "r");
527 fprintf(stderr, "Could not open specification file, '%s'\n", argv[1]);
533 sprintf(filename, "dll_%s.S", LowerDLLName);
534 fp = fopen(filename, "w");
536 fprintf(fp, "\t.globl _%s_Dispatch\n", UpperDLLName);
537 fprintf(fp, "_%s_Dispatch:\n", UpperDLLName);
538 fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
539 fprintf(fp, "\tjmp\t_CallTo32\n\n");
541 odp = OrdinalDefinitions;
542 for (i = 0; i <= Limit; i++, odp++)
544 fprintf(fp, "\t.globl _%s_Ordinal_%d\n", UpperDLLName, i);
548 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
549 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
550 fprintf(fp, "\tpushw\t$0\n");
551 fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
555 fdp = odp->additional_data;
560 fprintf(fp, "_%s_Ordinal_%d = %d\n\n",
561 UpperDLLName, i, (int) odp->additional_data);
565 OutputVariableCode(fp, ".byte", odp);
569 OutputVariableCode(fp, ".word", odp);
573 OutputVariableCode(fp, ".long", odp);
577 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
578 fprintf(fp, "\tpushw\t%%ax\n");
579 fprintf(fp, "\tpushw\t%%cx\n");
580 fprintf(fp, "\tpushw\t%%dx\n");
581 fprintf(fp, "\tpushw\t%%bx\n");
582 fprintf(fp, "\tpushw\t%%sp\n");
583 fprintf(fp, "\tpushw\t%%bp\n");
584 fprintf(fp, "\tpushw\t%%si\n");
585 fprintf(fp, "\tpushw\t%%di\n");
586 fprintf(fp, "\tpushw\t%%ds\n");
587 fprintf(fp, "\tpushw\t%%es\n");
588 fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
589 fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
590 fprintf(fp, "\tpushl\t20(%%ebp)\n");
591 fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
592 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
593 fprintf(fp, "\tpushw\t$24\n");
594 fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
597 case FUNCTYPE_PASCAL:
598 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
599 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
600 fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
601 fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
606 fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
607 fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
608 fprintf(fp, "\tpushw\t$0\n");
609 fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
617 sprintf(filename, "dll_%s_tab.c", LowerDLLName);
618 fp = fopen(filename, "w");
620 fprintf(fp, "#include <stdio.h>\n");
621 fprintf(fp, "#include <stdlib.h>\n");
622 fprintf(fp, "#include \042dlls.h\042\n\n");
624 for (i = 0; i <= Limit; i++)
626 fprintf(fp, "extern void %s_Ordinal_%d();\n", UpperDLLName, i);
629 odp = OrdinalDefinitions;
630 for (i = 0; i <= Limit; i++, odp++)
633 (odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_C ||
634 odp->type == FUNCTYPE_REG))
636 fdp = odp->additional_data;
637 fprintf(fp, "extern int %s();\n", fdp->internal_name);
641 fprintf(fp, "\nstruct dll_table_entry_s %s_table[%d] =\n",
642 UpperDLLName, Limit + 1);
644 odp = OrdinalDefinitions;
645 for (i = 0; i <= Limit; i++, odp++)
647 fdp = odp->additional_data;
654 case FUNCTYPE_PASCAL:
656 fprintf(fp, " { 0x23, %s_Ordinal_%d, ", UpperDLLName, i);
657 fprintf(fp, "\042%s\042, ", odp->export_name);
658 fprintf(fp, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp->internal_name);
659 fprintf(fp, "%d, ", fdp->n_args_32);
660 if (fdp->n_args_32 > 0)
664 fprintf(fp, "\n {\n");
665 for (argnum = 0; argnum < fdp->n_args_32; argnum++)
667 fprintf(fp, " { %d, %d },\n",
668 fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
669 fdp->arg_types_16[argnum]);
671 fprintf(fp, " }\n ");
673 fprintf(fp, "}, \n");
677 fprintf(fp, " { 0x23, %s_Ordinal_%d, ", UpperDLLName, i);
678 fprintf(fp, "\042%s\042, ", odp->export_name);
679 fprintf(fp, "%s, DLL_HANDLERTYPE_C, ", fdp->internal_name);
680 fprintf(fp, "%d, ", fdp->n_args_32);
681 if (fdp->n_args_32 > 0)
685 fprintf(fp, "\n {\n");
686 for (argnum = 0; argnum < fdp->n_args_32; argnum++)
688 fprintf(fp, " { %d, %d },\n",
689 fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
690 fdp->arg_types_16[argnum]);
692 fprintf(fp, " }\n ");
694 fprintf(fp, "}, \n");
698 fprintf(fp, " { 0x23, %s_Ordinal_%d, \042\042, NULL },\n",