source: trunk/emx/src/emximp/emximp.c@ 3669

Last change on this file since 3669 was 2272, checked in by bird, 20 years ago

o Fixed bad done string allocation.

  • Property cvs2svn:cvs-rev set to 1.16
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 50.6 KB
Line 
1/* emximp.c -- Manage import libraries
2 Copyright (c) 1992-1998 Eberhard Mattes
3 Copyright (c) 2004 knut st. osmundsen
4
5This file is part of emximp.
6
7emximp is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12emximp is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with emximp; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <stdarg.h>
26#include <string.h>
27#include <ctype.h>
28#include <getopt.h>
29#include <process.h>
30#include <ar.h>
31#include <time.h>
32#include <sys/moddef.h>
33#include <sys/types.h>
34#include <a_out.h>
35#include "defs.h"
36#include <sys/omflib.h>
37
38#define NORETURN2 __attribute__ ((noreturn))
39
40#define MOD_PREDEF 0
41#define MOD_DEF 1
42#define MOD_REF 2
43
44#define PARMS_REG (-1)
45#define PARMS_FAR16 (-2)
46
47struct lib
48{
49 struct lib *next;
50 char *name;
51 int lbl;
52};
53
54struct predef
55{
56 struct predef *next;
57 char *name;
58};
59
60enum modes
61{
62 M_NONE, /* No mode selected */
63 M_LIB_TO_IMP, /* .lib -> .imp */
64 M_IMP_TO_S, /* .imp -> .s or .o */
65 M_IMP_TO_DEF, /* .imp -> .def */
66 M_LIB_TO_A, /* .lib -> .a */
67 M_IMP_TO_A, /* .imp -> .a */
68 M_IMP_TO_LIB, /* .imp -> .lib */
69 M_DEF_TO_IMP, /* .def -> .imp */
70 M_DEF_TO_A, /* .def -> .a */
71 M_DEF_TO_LIB, /* .def -> .lib */
72 M_DLL_TO_IMP, /* .dll -> .imp */
73 M_DLL_TO_A, /* .dll -> .a */
74 M_DLL_TO_LIB, /* .dll -> .lib */
75 M_DLL_TO_DEF /* .dll -> .def */
76};
77
78static FILE *out_file = NULL;
79static char out_fname[128];
80static struct lib *libs;
81static struct predef *predefs;
82static char *out_base;
83static int base_len;
84static char *as_name;
85static int pipe_flag;
86static int profile_flag;
87static int opt_b;
88static int opt_q;
89static int opt_s;
90static int opt_lazy;
91static enum modes mode = M_NONE;
92static long mod_lbl;
93static long seq_no = 1;
94static char *first_module = NULL;
95static int warnings = 0;
96static struct omflib *out_lib;
97static char lib_errmsg[512];
98static char *module_name = NULL;
99static char *description;
100
101
102static void error (const char *fmt, ...) NORETURN2;
103static void write_error (const char *fname) NORETURN2;
104static void lib_error (void) NORETURN2;
105static void write_a_import (const char *func_name, const char *mod_name,
106 int ordinal, const char *proc_name);
107
108
109static void usage (void)
110{
111 puts ("emximp " VERSION INNOTEK_VERSION " -- Copyright (c) 1992-1996 by Eberhard Mattes\n");
112 puts ("Usage:");
113 puts (" emximp [-a[<assembler>]] [-b <base_name>|<prefix_length>] "
114 "[-p <module>] ...");
115 puts (" [-s] <input_file>.imp");
116 puts (" emximp [-m] -o <output_file>.a <input_file>.def ...");
117 puts (" emximp [-m] -o <output_file>.a <input_file>.imp ...");
118 puts (" emximp [-m] -o <output_file>.a <input_file>.lib ...");
119 puts (" emximp [-m] -o <output_file>.a <input_file>.dll ...");
120 puts (" emximp -o <output_file>.imp <input_file>.def ...");
121 puts (" emximp -o <output_file>.imp <input_file>.lib ...");
122 puts (" emximp -o <output_file>.imp <input_file>.dll ...");
123 puts (" emximp [-p#] -o <output_file>.lib <input_file>.def ...");
124 puts (" emximp [-p#] -o <output_file>.lib <input_file>.imp...");
125 puts (" emximp [-p#] -o <output_file>.lib <input_file>.dll ...");
126 puts (" emximp -o <output_file>.def <input_file>.imp ...");
127 puts (" emximp -o <output_file>.def <input_file>.dll ...");
128 puts ("Options:");
129 puts (" -p# Set page size");
130 puts (" -q Be quiet");
131 puts (" -m Call _mcount for profiling");
132 puts (" -l Lazy loading and resolving");
133 exit (1);
134}
135
136
137static void error (const char *fmt, ...)
138{
139 va_list arg_ptr;
140
141 va_start (arg_ptr, fmt);
142 fprintf (stderr, "emximp: ");
143 vfprintf (stderr, fmt, arg_ptr);
144 fputc ('\n', stderr);
145 exit (2);
146}
147
148
149static void warning (const char *fmt, ...)
150{
151 va_list arg_ptr;
152
153 va_start (arg_ptr, fmt);
154 fprintf (stderr, "emximp: ");
155 vfprintf (stderr, fmt, arg_ptr);
156 fputc ('\n', stderr);
157 ++warnings;
158}
159
160
161/* Like warning(), but don't increment `warnings'. */
162
163static void information (const char *fmt, ...)
164{
165 va_list arg_ptr;
166
167 va_start (arg_ptr, fmt);
168 fprintf (stderr, "emximp: ");
169 vfprintf (stderr, fmt, arg_ptr);
170 fputc ('\n', stderr);
171}
172
173
174static void *xmalloc (size_t n)
175{
176 void *p;
177
178 p = malloc (n);
179 if (p == NULL)
180 error ("Out of memory");
181 return p;
182}
183
184
185static void *xrealloc (void *p, size_t n)
186{
187 void *q;
188
189 q = realloc (p, n);
190 if (q == NULL)
191 error ("Out of memory");
192 return q;
193}
194
195
196static char *xstrdup (const char *s)
197{
198 char *p;
199
200 p = xmalloc (strlen (s) + 1);
201 strcpy (p, s);
202 return p;
203}
204
205
206static void write_error (const char *fname)
207{
208 error ("Write error on output file `%s'", fname);
209}
210
211
212static void lib_error (void)
213{
214 error ("%s", lib_errmsg);
215}
216
217
218static void out_flush (void)
219{
220 char name[512];
221 char *nargv[5];
222 int rc;
223
224 if (out_file != NULL)
225 {
226 if (fflush (out_file) != 0)
227 write_error (out_fname);
228 if (pipe_flag)
229 {
230 rc = pclose (out_file);
231 if (rc == -1)
232 error ("Error while closing pipe");
233 if (rc > 0)
234 error ("Assembly failed, return code = %d", rc);
235 }
236 else
237 {
238 if (fclose (out_file) != 0)
239 error ("Cannot close output file `%s'", out_fname);
240 if (as_name != NULL)
241 {
242 _splitpath (out_fname, NULL, NULL, name, NULL);
243 strcat (name, ".o");
244 nargv[0] = as_name;
245 nargv[1] = "-o";
246 nargv[2] = name;
247 nargv[3] = out_fname;
248 nargv[4] = NULL;
249 rc = spawnvp (P_WAIT, as_name, nargv);
250 if (rc < 0)
251 error ("Cannot run `%s'", as_name);
252 if (rc > 0)
253 error ("Assembly of `%s' failed, return code = %d",
254 out_fname, rc);
255 remove (out_fname);
256 }
257 }
258 out_file = NULL;
259 }
260}
261
262
263static void out_start (void)
264{
265 struct lib *lp1, *lp2;
266 char name[512], cmd[512];
267
268 if (pipe_flag)
269 {
270 _splitpath (out_fname, NULL, NULL, name, NULL);
271 strcat (name, ".o");
272 sprintf (cmd, "%s -o %s", as_name, name);
273 out_file = popen (cmd, "wt");
274 if (out_file == NULL)
275 error ("Cannot open pipe to `%s'", as_name);
276 }
277 else
278 {
279 out_file = fopen (out_fname, "wt");
280 if (out_file == NULL)
281 error ("Cannot open output file `%s'", out_fname);
282 }
283 fprintf (out_file, "/ %s (emx+gcc)\n\n", out_fname);
284 fprintf (out_file, "\t.text\n");
285 for (lp1 = libs; lp1 != NULL; lp1 = lp2)
286 {
287 lp2 = lp1->next;
288 free (lp1->name);
289 free (lp1);
290 }
291 libs = NULL; mod_lbl = 1;
292}
293
294
295static void write_lib_import (const char *func, const char *module, long ord,
296 const char *name)
297{
298 byte omfbuf[1024];
299 int i, len;
300 word page;
301
302 if (omflib_write_module (out_lib, func, &page, lib_errmsg) != 0)
303 lib_error ();
304 if (omflib_add_pub (out_lib, func, page, lib_errmsg) != 0)
305 lib_error ();
306 i = 0;
307 omfbuf[i++] = 0x00;
308 omfbuf[i++] = IMPDEF_CLASS;
309 omfbuf[i++] = IMPDEF_SUBTYPE;
310 omfbuf[i++] = (ord < 1 ? 0x00 : 0x01);
311 len = strlen (func);
312 omfbuf[i++] = (byte)len;
313 memcpy (omfbuf+i, func, len); i += len;
314 len = strlen (module);
315 omfbuf[i++] = (byte)len;
316 memcpy (omfbuf+i, module, len); i += len;
317 if (ord < 1)
318 {
319 if (strcmp (func, name) == 0)
320 len = 0;
321 else
322 len = strlen (name);
323 omfbuf[i++] = (byte)len;
324 memcpy (omfbuf+i, name, len); i += len;
325 }
326 else
327 {
328 omfbuf[i++] = (byte)ord;
329 omfbuf[i++] = (byte)(ord >> 8);
330 }
331 if (omflib_write_record (out_lib, COMENT, i, omfbuf, TRUE,
332 lib_errmsg) != 0)
333 lib_error ();
334 omfbuf[0] = 0x00;
335 if (omflib_write_record (out_lib, MODEND, 1, omfbuf, TRUE,
336 lib_errmsg) != 0)
337 lib_error ();
338}
339
340
341#define DELIM(c) ((c) == 0 || isspace ((unsigned char)c))
342
343
344static void read_imp (const char *fname)
345{
346 FILE *inp_file;
347 char buf[512], func[256], name[256], module[256], mod_ref[256], *p, *q;
348 char tmp[512];
349 long line_no, ord, parms, file_no;
350 int mod_type;
351 struct lib *lp1;
352 struct predef *pp1;
353
354 libs = NULL; mod_lbl = 1;
355 inp_file = fopen (fname, "rt");
356 if (inp_file == NULL)
357 error ("Cannot open input file `%s'", fname);
358 line_no = 0;
359 while (fgets (buf, sizeof (buf), inp_file) != NULL)
360 {
361 ++line_no;
362 p = strchr (buf, '\n');
363 if (p != NULL) *p = 0;
364 p = buf;
365 while (isspace ((unsigned char)*p)) ++p;
366 if (*p == '+')
367 {
368 if (mode == M_IMP_TO_S)
369 {
370 if (opt_b)
371 error ("Output file name in line %ld of %s not allowed "
372 "as -b is used", line_no, fname);
373 ++p;
374 while (isspace ((unsigned char)*p)) ++p;
375 out_flush ();
376 q = out_fname;
377 while (!DELIM (*p))
378 *q++ = *p++;
379 *q = 0;
380 while (isspace ((unsigned char)*p)) ++p;
381 if (*p != 0 && *p != ';')
382 error ("Invalid file name in line %ld of %s", line_no, fname);
383 out_start ();
384 }
385 }
386 else if (*p == 0 || *p == ';')
387 ; /* empty line */
388 else
389 {
390 if (!opt_b && out_file == NULL && mode != M_IMP_TO_LIB)
391 error ("No output file selected in line %ld of %s",
392 line_no, fname);
393 if (DELIM (*p))
394 error ("Function name expected in line %ld of %s", line_no, fname);
395 q = func;
396 while (!DELIM (*p))
397 *q++ = *p++;
398 *q = 0;
399 while (isspace ((unsigned char)*p)) ++p;
400 if (DELIM (*p))
401 error ("Module name expected in line %ld of %s", line_no, fname);
402 q = module;
403 while (!DELIM (*p))
404 *q++ = *p++;
405 *q = 0;
406 while (isspace ((unsigned char)*p)) ++p;
407 if (DELIM (*p))
408 error ("External name or ordinal expected in line %ld of %s",
409 line_no, fname);
410 if (isdigit ((unsigned char)*p))
411 {
412 name[0] = 0;
413 ord = strtol (p, &p, 10);
414 if (ord < 1 || ord > 65535 || !DELIM (*p))
415 error ("Invalid ordinal in line %ld of %s", line_no, fname);
416 }
417 else
418 {
419 if (opt_b && !opt_s)
420 error ("External name in line %ld of %s cannot be used "
421 "as -b is given", line_no, fname);
422 ord = -1;
423 q = name;
424 while (!DELIM (*p))
425 *q++ = *p++;
426 *q = 0;
427 }
428 while (isspace ((unsigned char)*p)) ++p;
429 if (DELIM (*p))
430 error ("Number of arguments expected in line %ld of %s",
431 line_no, fname);
432 if (*p == '?')
433 {
434 ++p;
435 parms = 0;
436 if (mode == M_IMP_TO_S)
437 warning ("Unknown number of arguments in line %ld of %s",
438 line_no, fname);
439 }
440 else if (*p == 'R')
441 {
442 ++p;
443 parms = PARMS_REG;
444 }
445 else if (*p == 'F')
446 {
447 ++p;
448 parms = PARMS_FAR16;
449 if (mode == M_IMP_TO_S)
450 warning ("16-bit function not supported (line %ld of %s)",
451 line_no, fname);
452 if (strlen (func) + 4 >= sizeof (func))
453 error ("Function name too long in line %ld of %s",
454 line_no, fname);
455 strcpy (tmp, func);
456 strcpy (func, "_16_");
457 strcat (func, tmp);
458 }
459 else
460 {
461 parms = strtol (p, &p, 10);
462 if (parms < 0 || parms > 255 || !DELIM (*p))
463 error ("Invalid number of parameters in line %ld of %s",
464 line_no, fname);
465 }
466 while (isspace ((unsigned char)*p)) ++p;
467 if (*p != 0 && *p != ';')
468 error ("Unexpected characters at end of line %ld of %s",
469 line_no, fname);
470 switch (mode)
471 {
472 case M_IMP_TO_DEF:
473 if (first_module == NULL)
474 {
475 first_module = xstrdup (module);
476 fprintf (out_file, "LIBRARY %s\n", module);
477 fprintf (out_file, "EXPORTS\n");
478 }
479 else if (strcmp (first_module, module) != 0)
480 error ("All functions must be in the same module "
481 "(input file %s)", fname);
482 if (ord >= 0)
483 fprintf (out_file, " %-32s @%ld\n", func, ord);
484 else if (strcmp (func, name) == 0)
485 fprintf (out_file, " %-32s\n", func);
486 else
487 fprintf (out_file, " %-32s = %s\n", name, func);
488 break;
489 case M_IMP_TO_A:
490 if (ord < 1)
491 write_a_import (func, module, ord, name);
492 else
493 write_a_import (func, module, ord, NULL);
494 break;
495 case M_IMP_TO_LIB:
496 write_lib_import (func, module, ord, name);
497 break;
498 case M_IMP_TO_S:
499 if (opt_b)
500 {
501 out_flush ();
502 if (opt_s)
503 file_no = seq_no++;
504 else
505 file_no = ord;
506 if (out_base != NULL)
507 sprintf (out_fname, "%s%ld.s", out_base, file_no);
508 else
509 sprintf (out_fname, "%.*s%ld.s",
510 base_len, module, file_no);
511 out_start ();
512 }
513 for (pp1 = predefs; pp1 != NULL; pp1 = pp1->next)
514 if (stricmp (module, pp1->name) == 0)
515 break;
516 if (pp1 != NULL)
517 {
518 mod_type = MOD_PREDEF;
519 sprintf (mod_ref, "__os2_%s", pp1->name);
520 }
521 else
522 {
523 for (lp1 = libs; lp1 != NULL; lp1 = lp1->next)
524 if (stricmp (module, lp1->name) == 0)
525 break;
526 if (lp1 == NULL)
527 {
528 mod_type = MOD_DEF;
529 lp1 = xmalloc (sizeof (struct lib));
530 lp1->name = xstrdup (module);
531 lp1->lbl = mod_lbl++;
532 lp1->next = libs;
533 libs = lp1;
534 }
535 else
536 mod_type = MOD_REF;
537 sprintf (mod_ref, "L%d", lp1->lbl);
538 }
539 fprintf (out_file, "\n\t.globl\t_%s\n", func);
540 fprintf (out_file, "\t.align\t2, %d\n", 0x90);
541 fprintf (out_file, "_%s:\n", func);
542 if (parms >= 0)
543 fprintf (out_file, "\tmovb\t$%d, %%al\n", (int)parms);
544 fprintf (out_file, "1:\tjmp\t__os2_bad\n");
545 if (ord >= 0)
546 fprintf (out_file, "2:\t.long\t1, 1b+1, %s, %d\n",
547 mod_ref, (int)ord);
548 else
549 fprintf (out_file, "2:\t.long\t0, 1b+1, %s, 4f\n", mod_ref);
550 if (mod_type == MOD_DEF)
551 fprintf (out_file, "%s:\t.asciz\t\"%s\"\n", mod_ref, module);
552 if (ord < 0)
553 fprintf (out_file, "4:\t.asciz\t\"%s\"\n", name);
554 fprintf (out_file, "\t.stabs \"__os2dll\", 23, 0, 0, 2b\n");
555 break;
556 default:
557 abort ();
558 }
559 }
560 }
561 if (mode == M_IMP_TO_S)
562 out_flush ();
563 if (ferror (inp_file))
564 error ("Read error on input file `%s'", fname);
565 fclose (inp_file);
566}
567
568
569static unsigned hash (const char *name)
570{
571 unsigned h = 0;
572 for (; *name; name++)
573 h = (h << 2) ^ (unsigned char)*name;
574 return h;
575}
576
577static void set_ar (char *dst, const char *src, int size)
578{
579 while (*src != 0 && size > 0)
580 {
581 *dst++ = *src++;
582 --size;
583 }
584 while (size > 0)
585 {
586 *dst++ = ' ';
587 --size;
588 }
589}
590
591
592static long ar_member_size;
593
594static void write_ar (const char *name, long size)
595{
596 struct ar_hdr ar;
597 char tmp[20];
598
599 ar_member_size = size;
600 set_ar (ar.ar_name, name, sizeof (ar.ar_name));
601 sprintf (tmp, "%ld", (long)time (NULL));
602 set_ar (ar.ar_date, tmp, sizeof (ar.ar_date));
603 set_ar (ar.ar_uid, "0", sizeof (ar.ar_uid));
604 set_ar (ar.ar_gid, "0", sizeof (ar.ar_gid));
605 set_ar (ar.ar_mode, "100666", sizeof (ar.ar_gid));
606 sprintf (tmp, "%ld", size);
607 set_ar (ar.ar_size, tmp, sizeof (ar.ar_size));
608 set_ar (ar.ar_fmag, ARFMAG, sizeof (ar.ar_fmag));
609 fwrite (&ar, 1, sizeof (ar), out_file);
610}
611
612
613static void finish_ar (void)
614{
615 if (ar_member_size & 1)
616 fputc (0, out_file);
617}
618
619
620static dword aout_str_size;
621static char aout_str_tab[2048];
622static int aout_sym_count;
623static struct nlist aout_sym_tab[6];
624
625static byte aout_text[300];
626static int aout_text_size;
627
628static byte aout_data[300];
629static int aout_data_size;
630
631static struct relocation_info aout_treloc_tab[7];
632static int aout_treloc_count;
633
634static struct relocation_info aout_dreloc_tab[7];
635static int aout_dreloc_count;
636
637static int aout_size;
638
639
640static void aout_init (void)
641{
642 aout_str_size = sizeof (dword);
643 aout_sym_count = 0;
644 aout_text_size = 0;
645 aout_data_size = 0;
646 aout_treloc_count = 0;
647 aout_dreloc_count = 0;
648}
649
650static int aout_sym (const char *name, byte type, byte other,
651 word desc, dword value)
652{
653 int len;
654
655 len = strlen (name);
656 if (aout_str_size + len + 1 > sizeof (aout_str_tab))
657 error ("a.out string table overflow");
658 if (aout_sym_count >= sizeof (aout_sym_tab) / sizeof (aout_sym_tab[0]))
659 error ("a.out symbol table overflow");
660 aout_sym_tab[aout_sym_count].n_un.n_strx = aout_str_size;
661 aout_sym_tab[aout_sym_count].n_type = type;
662 aout_sym_tab[aout_sym_count].n_other = other;
663 aout_sym_tab[aout_sym_count].n_desc = desc;
664 aout_sym_tab[aout_sym_count].n_value = value;
665 strcpy (aout_str_tab + aout_str_size, name);
666 aout_str_size += len + 1;
667 return aout_sym_count++;
668}
669
670
671static void aout_text_byte (byte b)
672{
673 if (aout_text_size >= sizeof (aout_text))
674 error ("a.out text segment overflow");
675 aout_text[aout_text_size++] = b;
676}
677
678
679static void aout_text_dword (dword d)
680{
681 aout_text_byte ((d >> 0) & 0xff);
682 aout_text_byte ((d >> 8) & 0xff);
683 aout_text_byte ((d >> 16) & 0xff);
684 aout_text_byte ((d >> 24) & 0xff);
685}
686
687
688static void aout_treloc (dword address, int symbolnum, int pcrel, int length,
689 int ext)
690{
691 if (aout_treloc_count >= sizeof (aout_treloc_tab) / sizeof (struct relocation_info))
692 error ("a.out text relocation buffer overflow");
693 aout_treloc_tab[aout_treloc_count].r_address = address;
694 aout_treloc_tab[aout_treloc_count].r_symbolnum = symbolnum;
695 aout_treloc_tab[aout_treloc_count].r_pcrel = pcrel;
696 aout_treloc_tab[aout_treloc_count].r_length = length;
697 aout_treloc_tab[aout_treloc_count].r_extern = ext;
698 aout_treloc_tab[aout_treloc_count].r_pad = 0;
699 ++aout_treloc_count;
700}
701
702static void aout_data_byte (byte b)
703{
704 if (aout_data_size >= sizeof (aout_data))
705 error ("a.out data segment overflow");
706 aout_data[aout_data_size++] = b;
707}
708
709static void aout_data_dword (dword d)
710{
711 aout_data_byte ((d >> 0) & 0xff);
712 aout_data_byte ((d >> 8) & 0xff);
713 aout_data_byte ((d >> 16) & 0xff);
714 aout_data_byte ((d >> 24) & 0xff);
715}
716
717static void aout_dreloc (dword address, int symbolnum, int pcrel, int length,
718 int ext)
719{
720 if (aout_dreloc_count >= sizeof (aout_dreloc_tab) / sizeof (struct relocation_info))
721 error ("a.out data relocation buffer overflow");
722 aout_dreloc_tab[aout_dreloc_count].r_address = address;
723 aout_dreloc_tab[aout_dreloc_count].r_symbolnum = symbolnum;
724 aout_dreloc_tab[aout_dreloc_count].r_pcrel = pcrel;
725 aout_dreloc_tab[aout_dreloc_count].r_length = length;
726 aout_dreloc_tab[aout_dreloc_count].r_extern = ext;
727 aout_dreloc_tab[aout_dreloc_count].r_pad = 0;
728 ++aout_dreloc_count;
729}
730
731static void aout_finish (void)
732{
733 while (aout_text_size & 3)
734 aout_text_byte (0x90);
735 while (aout_data_size & 3)
736 aout_data_byte (0);
737 aout_size = (sizeof (struct exec) + aout_text_size + aout_data_size
738 + aout_treloc_count * sizeof (struct relocation_info)
739 + aout_dreloc_count * sizeof (struct relocation_info)
740 + aout_sym_count * sizeof (aout_sym_tab[0])
741 + aout_str_size);
742}
743
744
745static void aout_write (void)
746{
747 struct exec ao;
748
749 N_SET_MAGIC (ao, OMAGIC);
750 N_SET_MACHTYPE (ao, 0);
751 N_SET_FLAGS (ao, 0);
752 ao.a_text = aout_text_size;
753 ao.a_data = aout_data_size;
754 ao.a_bss = 0;
755 ao.a_syms = aout_sym_count * sizeof (aout_sym_tab[0]);
756 ao.a_entry = 0;
757 ao.a_trsize = aout_treloc_count * sizeof (struct relocation_info);
758 ao.a_drsize = aout_dreloc_count * sizeof (struct relocation_info);;
759 fwrite (&ao, 1, sizeof (ao), out_file);
760 fwrite (aout_text, aout_text_size, 1, out_file);
761 fwrite (aout_data, aout_data_size, 1, out_file);
762 fwrite (aout_treloc_tab, aout_treloc_count, sizeof (struct relocation_info), out_file);
763 fwrite (aout_dreloc_tab, aout_dreloc_count, sizeof (struct relocation_info), out_file);
764 fwrite (aout_sym_tab, aout_sym_count, sizeof (aout_sym_tab[0]), out_file);
765 *(dword *)aout_str_tab = aout_str_size;
766 fwrite (aout_str_tab, 1, aout_str_size, out_file);
767}
768
769
770static void write_a_lazyldr (const char *resolver_sym, const char *mod_name)
771{
772 char tmp[257];
773 dword *ptr_hmod_fixup, *ptr_name_fixup;
774 const char *p;
775 int len;
776 static char *done = NULL;
777 static size_t done_len = 0;
778 if (done && strstr (done, resolver_sym))
779 return;
780 len = strlen (resolver_sym);
781 done = xrealloc (done, done_len + len + 2);
782 memcpy (done + done_len, resolver_sym, len);
783 len += done_len;
784 memcpy (done + len, "\b", 2);
785 done_len = len + 1;
786
787 /* Write module resolver object
788 .text
789 .globl ___lazyimp_doscalls_resolver
790 ___lazyimp_doscalls_resolver:
791 push name
792 push hmod
793 jmp ___lazyimp_resolver
794 name:
795 .asciiz "DOSCALLS"
796 .byte 0
797
798 .data
799 hmod:
800 .long 0
801 */
802 aout_init ();
803 aout_sym (resolver_sym, N_TEXT|N_EXT, 0, 0, aout_text_size); /* .globl DosRead */
804 aout_text_byte (0x68); /* push name */
805 aout_treloc (aout_text_size, N_TEXT, 0, 2, 0);
806 ptr_name_fixup = (dword *)&aout_text[aout_text_size];
807 aout_text_dword (0);
808
809 aout_text_byte (0x68); /* push pfn */
810 aout_treloc (aout_text_size, N_DATA, 0, 2, 0);
811 ptr_hmod_fixup = (dword *)&aout_text[aout_text_size];
812 aout_text_dword (0);
813
814 aout_text_byte (0xe9); /* jmp ___lazyimp_resolver */
815 aout_treloc (aout_text_size, aout_sym ("___lazyimp_resolver", N_EXT, 0, 0, 0), 1, 2, 1);
816 aout_text_dword (0 - (aout_text_size + 4));
817
818 *ptr_name_fixup = aout_text_size; /* name: .ascii */
819 strcpy (tmp, mod_name);
820 strupr (tmp);
821 for (p = tmp; *p; p++)
822 aout_text_byte(*p);
823 aout_text_byte(0);
824
825 while (aout_text_size & 3)
826 aout_text_byte (0xcc);
827
828 *ptr_hmod_fixup = aout_text_size; /* hmod: .long 0 */
829 aout_data_dword (0);
830
831
832 aout_finish ();
833 sprintf (tmp, "LAZYMOD#%ld", seq_no);
834 write_ar (tmp, aout_size);
835 aout_write ();
836 finish_ar ();
837 seq_no++;
838 if (ferror (out_file))
839 write_error (out_fname);
840}
841
842
843static void write_a_import (const char *func_name, const char *mod_name,
844 int ordinal, const char *proc_name)
845{
846 char tmp1[256], tmp2[257], tmp3[1024];
847 int sym_mcount, sym_entry, sym_import;
848 dword fixup_mcount, fixup_import;
849
850 /* #425: Underscore is gone. (was "_%s") */
851 sprintf (tmp2, "%s", func_name);
852 /*
853 * Lazily resolved dynamic import.
854 */
855 if (opt_lazy && strncmp (func_name, "_16_", 4) != 0)
856 {
857 int off_name, off_resolver;
858 dword *fixup_ptr1, *fixup_ptr2;
859 char *p;
860
861 /* create module resolver object first. */
862 sprintf (tmp1, "___lazyldr_%s_resolver", mod_name);
863 write_a_lazyldr (tmp1, mod_name);
864
865 /* Write import object
866 .data
867 pfn:
868 .long resolve
869 .text
870 .globl DosRead
871 DosRead:
872 jmp *(pfn)
873 name:
874 .asciiz "DosRead"
875 .byte 0
876 resolve:
877 push name
878 push pfn
879 jmp ___lazyimp_doscalls_resolver
880 */
881 aout_init ();
882 aout_sym (tmp2, N_TEXT|N_EXT, 0, 0, aout_text_size); /* .globl DosRead */
883 strlwr (tmp1);
884 aout_text_byte (0xff); /* jmp *(pfn) */
885 aout_text_byte (0x25);
886 aout_treloc (aout_text_size, N_DATA, 0, 2, 0);
887 fixup_ptr1 = (dword *)&aout_text[aout_text_size];
888 aout_text_dword (aout_data_size);
889
890 if (proc_name)
891 {
892 off_name = aout_text_size; /* name: .ascii */
893 for (p = tmp2; *p; p++)
894 aout_text_byte(*p);
895 aout_text_byte(0);
896 aout_text_byte (0xcc);
897 }
898
899 off_resolver = aout_text_size; /* resolve: push name / ordinal */
900 aout_text_byte (0x68);
901 if (proc_name)
902 {
903 aout_treloc (aout_text_size, N_TEXT, 0, 2, 0);
904 aout_text_dword (off_name);
905 }
906 else
907 aout_text_dword (ordinal);
908
909 aout_text_byte (0x68); /* resolve: push pfn */
910 aout_treloc (aout_text_size, N_DATA, 0, 2, 0);
911 fixup_ptr2 = (dword *)&aout_text[aout_text_size];
912 aout_text_dword (0);
913
914 aout_text_byte (0xe9); /* jmp ___lazyimp_????_resolver */
915 aout_treloc (aout_text_size, aout_sym (tmp1, N_EXT, 0, 0, 0), 1, 2, 1);
916 aout_text_dword (0 - (aout_text_size + 4));
917 while (aout_text_size & 3)
918 aout_text_byte (0xcc);
919
920 *fixup_ptr1 = aout_text_size;
921 *fixup_ptr2 = aout_text_size;
922 aout_dreloc (aout_data_size, N_TEXT, 0, 2, 0); /* pfn: .long resolve */
923 aout_data_dword (off_resolver);
924 sprintf (tmp1, "LAZY#%ld#%x", seq_no, hash (func_name));
925 }
926 /*
927 * Static load time import.
928 */
929 else
930 {
931 aout_init ();
932 if (profile_flag && strncmp (func_name, "_16_", 4) != 0)
933 {
934 sym_entry = aout_sym (tmp2, N_TEXT|N_EXT, 0, 0, aout_text_size);
935 sym_mcount = aout_sym ("__mcount", N_EXT, 0, 0, 0);
936
937 /* Use, say, "_$U_DosRead" for "DosRead" to import the
938 non-profiled function. */
939 sprintf (tmp2, "__$U_%s", func_name);
940 sym_import = aout_sym (tmp2, N_EXT, 0, 0, 0);
941
942 aout_text_byte (0x55); /* push ebp */
943 aout_text_byte (0x89); /* mov ebp, esp */
944 aout_text_byte (0xe5);
945 aout_text_byte (0xe8); /* call _mcount*/
946 fixup_mcount = aout_text_size;
947 aout_text_dword (0 - (aout_text_size + 4));
948 aout_text_byte (0x5d); /* pop ebp */
949 aout_text_byte (0xe9); /* jmp _$U_DosRead*/
950 fixup_import = aout_text_size;
951 aout_text_dword (0 - (aout_text_size + 4));
952
953 aout_treloc (fixup_mcount, sym_mcount, 1, 2, 1);
954 aout_treloc (fixup_import, sym_import, 1, 2, 1);
955 }
956 if (proc_name == NULL)
957 sprintf (tmp3, "%s=%s.%d", tmp2, mod_name, ordinal);
958 else
959 sprintf (tmp3, "%s=%s.%s", tmp2, mod_name, proc_name);
960 aout_sym (tmp2, N_IMP1|N_EXT, 0, 0, 0);
961 aout_sym (tmp3, N_IMP2|N_EXT, 0, 0, 0);
962 sprintf (tmp1, "IMPORT#%ld#%x", seq_no, hash (func_name));
963 }
964
965 aout_finish ();
966 write_ar (tmp1, aout_size);
967 aout_write ();
968 finish_ar ();
969 seq_no++;
970 if (ferror (out_file))
971 write_error (out_fname);
972}
973
974
975static void read_lib (const char *fname)
976{
977 FILE *inp_file;
978 int n, i, next, more, impure_warned, ord_flag;
979 unsigned char *buf;
980#pragma pack(1)
981 struct record
982 {
983 unsigned char type;
984 unsigned short length;
985 } record, *rec_ptr;
986#pragma pack()
987 unsigned char func_name[256];
988 unsigned char mod_name[256];
989 unsigned char proc_name[256];
990 unsigned char theadr_name[256];
991 int ordinal;
992 long pos, size;
993 int page_size;
994
995 if (mode == M_LIB_TO_IMP)
996 fprintf (out_file, "; -------- %s --------\n", fname);
997 if (ferror (out_file))
998 write_error (out_fname);
999 inp_file = fopen (fname, "rb");
1000 if (inp_file == NULL)
1001 error ("Cannot open input file `%s'", fname);
1002 if (fread (&record, sizeof (record), 1, inp_file) != 1)
1003 goto read_error;
1004 if (record.type != LIBHDR || record.length < 5)
1005 error ("`%s' is not a library file", fname);
1006 page_size = record.length + 3;
1007 if (fread (&pos, sizeof (pos), 1, inp_file) != 1)
1008 goto read_error;
1009 if (fseek (inp_file, 0L, SEEK_END) != 0)
1010 goto read_error;
1011 size = ftell (inp_file);
1012 if (pos < size)
1013 size = pos;
1014 buf = xmalloc (size);
1015 if (fseek (inp_file, 0L, SEEK_SET) != 0)
1016 goto read_error;
1017 size = fread (buf, 1, size, inp_file);
1018 if (size == 0 || ferror (inp_file))
1019 goto read_error;
1020 i = 0; more = TRUE; impure_warned = FALSE; theadr_name[0] = 0;
1021 while (more)
1022 {
1023 rec_ptr = (struct record *)(buf + i);
1024 i += sizeof (struct record);
1025 if (i > size) goto bad;
1026 next = i + rec_ptr->length;
1027 if (next > size) goto bad;
1028 switch (rec_ptr->type)
1029 {
1030 case MODEND:
1031 case MODEND|REC32:
1032 if ((next & (page_size-1)) != 0)
1033 next = (next | (page_size-1)) + 1;
1034 break;
1035
1036 case THEADR:
1037 n = buf[i++];
1038 if (i + n > next) goto bad;
1039 memcpy (theadr_name, buf+i, n);
1040 theadr_name[n] = 0;
1041 impure_warned = FALSE;
1042 break;
1043
1044 case COMENT:
1045 if (record.length >= 11 && buf[i+0] == 0x00 && buf[i+1] == 0xa0 &&
1046 buf[i+2] == 0x01)
1047 {
1048 ord_flag = buf[i+3];
1049 i += 4;
1050 if (i + 1 > next) goto bad;
1051 n = buf[i++];
1052 if (i + n > next) goto bad;
1053 memcpy (func_name, buf+i, n);
1054 func_name[n] = 0;
1055 i += n;
1056 if (i + 1 > next) goto bad;
1057 n = buf[i++];
1058 if (i + n > next) goto bad;
1059 memcpy (mod_name, buf+i, n);
1060 mod_name[n] = 0;
1061 i += n;
1062
1063 if (ord_flag == 0)
1064 {
1065 ordinal = -1;
1066 if (i + 1 > next) goto bad;
1067 n = buf[i++];
1068 if (i + n > next) goto bad;
1069 if (n == 0)
1070 strcpy (proc_name, func_name);
1071 else
1072 {
1073 memcpy (proc_name, buf+i, n);
1074 proc_name[n] = 0;
1075 i += n;
1076 }
1077 }
1078 else
1079 {
1080 if (i + 2 > next) goto bad;
1081 ordinal = *(unsigned short *)(buf + i);
1082 i += 2;
1083 proc_name[0] = 0;
1084 }
1085 ++i; /* Skip checksum */
1086 if (i != next) goto bad;
1087 switch (mode)
1088 {
1089 case M_LIB_TO_IMP:
1090 if (ordinal != -1)
1091 sprintf (proc_name, "%3d", ordinal);
1092 if (strncmp (func_name, "_16_", 4) != 0)
1093 fprintf (out_file, "%-23s %-8s %s ?\n",
1094 func_name, mod_name, proc_name);
1095 else
1096 fprintf (out_file, "%-23s %-8s %s F\n",
1097 func_name+4, mod_name, proc_name);
1098 if (ferror (out_file))
1099 write_error (out_fname);
1100 break;
1101 case M_LIB_TO_A:
1102 if (ordinal == -1)
1103 write_a_import (func_name, mod_name, ordinal, proc_name);
1104 else
1105 write_a_import (func_name, mod_name, ordinal, NULL);
1106 break;
1107 default:
1108 abort ();
1109 }
1110 }
1111 break;
1112
1113 case EXTDEF:
1114 case PUBDEF:
1115 case PUBDEF|REC32:
1116 case SEGDEF:
1117 case SEGDEF|REC32:
1118 case COMDEF:
1119 case COMDAT:
1120 case COMDAT|REC32:
1121 if (!opt_q && !impure_warned)
1122 {
1123 impure_warned = TRUE;
1124 information ("%s (%s) is not a pure import library",
1125 fname, theadr_name);
1126 }
1127 break;
1128
1129 case LIBEND:
1130 more = FALSE;
1131 break;
1132 }
1133 i = next;
1134 }
1135 free (buf);
1136 fclose (inp_file);
1137 return;
1138
1139read_error:
1140 error ("Read error on file `%s'", fname);
1141
1142bad:
1143 error ("Malformed import library file `%s'", fname);
1144}
1145
1146
1147static void create_output_file (int bin)
1148{
1149 out_file = fopen (out_fname, (bin ? "wb" : "wt"));
1150 if (out_file == NULL)
1151 error ("Cannot open output file `%s'", out_fname);
1152 if (!bin)
1153 fprintf (out_file, ";\n; %s (created by emximp)\n;\n", out_fname);
1154}
1155
1156
1157static void close_output_file (void)
1158{
1159 if (fflush (out_file) != 0)
1160 error ("Write error on output file `%s'", out_fname);
1161 if (fclose (out_file) != 0)
1162 error ("Cannot close output file `%s'", out_fname);
1163}
1164
1165
1166static void init_archive (void)
1167{
1168 static char ar_magic[SARMAG+1] = ARMAG;
1169
1170 fwrite (ar_magic, 1, SARMAG, out_file);
1171}
1172
1173
1174static int md_export (struct _md *md, const _md_stmt *stmt, _md_token token,
1175 void *arg)
1176{
1177 const char *internal;
1178
1179 switch (token)
1180 {
1181 case _MD_LIBRARY:
1182 module_name = xstrdup (stmt->library.name);
1183 break;
1184 case _MD_EXPORTS:
1185 if (module_name == NULL)
1186 error ("No module name given in module definition file");
1187 if (stmt->export.internalname[0] != 0)
1188 internal = stmt->export.internalname;
1189 else
1190 internal = stmt->export.entryname;
1191 switch (mode)
1192 {
1193 case M_DEF_TO_IMP:
1194 if (stmt->export.flags & _MDEP_ORDINAL)
1195 fprintf (out_file, "%-23s %-8s %3u ?\n",
1196 stmt->export.entryname, module_name,
1197 (unsigned)stmt->export.ordinal);
1198 else
1199 fprintf (out_file, "%-23s %-8s %-23s ?\n",
1200 stmt->export.entryname, module_name, internal);
1201 if (ferror (out_file))
1202 write_error (out_fname);
1203 break;
1204 case M_DEF_TO_A:
1205 if (stmt->export.flags & _MDEP_ORDINAL)
1206 write_a_import (stmt->export.entryname, module_name,
1207 stmt->export.ordinal, NULL);
1208 else
1209 write_a_import (stmt->export.entryname, module_name,
1210 0, internal);
1211 break;
1212 case M_DEF_TO_LIB:
1213 write_lib_import (stmt->export.entryname, module_name,
1214 stmt->export.ordinal, internal);
1215 break;
1216 default:
1217 abort ();
1218 }
1219 break;
1220 case _MD_parseerror:
1221 error ("%s (line %ld of %s)", _md_errmsg (stmt->error.code),
1222 _md_get_linenumber (md), (const char *)arg);
1223 break;
1224 default:
1225 break;
1226 }
1227 return 0;
1228}
1229
1230
1231static void read_def (const char *fname)
1232{
1233 struct _md *md;
1234
1235 module_name = NULL;
1236 md = _md_open (fname);
1237 if (md == NULL)
1238 error ("Cannot open input file `%s'", fname);
1239 if (mode == M_DEF_TO_IMP)
1240 {
1241 fprintf (out_file, "; -------- %s --------\n", fname);
1242 if (ferror (out_file))
1243 write_error (out_fname);
1244 }
1245 _md_next_token (md);
1246 _md_parse (md, md_export, (void *)fname);
1247 _md_close (md);
1248}
1249
1250/**
1251 * Reads a LX nametable.
1252 */
1253static void dll_read_names(FILE *phFile, off_t off, int cb, int fResident, int fOrdinal0Only, const char *pszFilename)
1254{
1255 char szName[256];
1256 unsigned cchName;
1257 unsigned iOrd = 0;
1258
1259 if (fseek(phFile, off, SEEK_SET))
1260 error("`%s': Bad LX format\n", pszFilename);
1261
1262 if (fResident)
1263 module_name = NULL;
1264 else
1265 description = NULL;
1266
1267 /* The names doesn't have to be in order, so we'll have to read
1268 * until we find the 0 ordinal if that's what we require. */
1269 while (cb > 0)
1270 {
1271 cchName = (unsigned)fgetc(phFile);
1272 if (!cchName || cb < cchName + 2)
1273 break;
1274 iOrd = 0;
1275 if ( fread(szName, 1, cchName, phFile) != cchName
1276 || fread(&iOrd, 1, 2, phFile) != 2)
1277 error("`%s': Bad LX format\n", pszFilename);
1278 szName[cchName] = '\0';
1279 cb -= 1 + cchName + 2;
1280
1281 if (iOrd == 0)
1282 {
1283 if (fResident)
1284 module_name = xstrdup(szName);
1285 else
1286 description = xstrdup(szName);
1287 if (fOrdinal0Only)
1288 return;
1289 }
1290 else if (!fOrdinal0Only)
1291 {
1292 switch (mode)
1293 {
1294 case M_DLL_TO_IMP:
1295 if (!fResident)
1296 fprintf(out_file, "%-23s %-8s %3u ?\n", szName, module_name, iOrd);
1297 else
1298 fprintf(out_file, "%-23s %-8s %-23s ?\n", szName, module_name, szName);
1299 if (ferror(out_file))
1300 write_error(out_fname);
1301 break;
1302 case M_DLL_TO_A:
1303 if (!fResident)
1304 write_a_import(szName, module_name, iOrd, NULL);
1305 else
1306 write_a_import(szName, module_name, 0, szName);
1307 break;
1308 case M_DLL_TO_LIB:
1309 if (!fResident)
1310 write_lib_import(szName, module_name, iOrd, NULL);
1311 else
1312 write_lib_import(szName, module_name, 0, szName);
1313 break;
1314 case M_DLL_TO_DEF:
1315 if (!fResident)
1316 fprintf(out_file, " \"%s\" @%d\n", szName, iOrd);
1317 else
1318 fprintf(out_file, " \"%s\"\n", szName);
1319 if (ferror(out_file))
1320 write_error(out_fname);
1321 break;
1322 default:
1323 abort ();
1324 }
1325 }
1326 } /* read restable loop */
1327}
1328
1329/** reads a dll */
1330static void read_dll(const char *pszFilename)
1331{
1332#pragma pack(1)
1333#define EMAGIC 0x5A4D
1334 struct
1335 {
1336 unsigned short e_magic;
1337 unsigned short e_cblp;
1338 unsigned short e_cp;
1339 unsigned short e_crlc;
1340 unsigned short e_cparhdr;
1341 unsigned short e_minalloc;
1342 unsigned short e_maxalloc;
1343 unsigned short e_ss;
1344 unsigned short e_sp;
1345 unsigned short e_csum;
1346 unsigned short e_ip;
1347 unsigned short e_cs;
1348 unsigned short e_lfarlc;
1349 unsigned short e_ovno;
1350 unsigned long e_sym_tab;
1351 unsigned short e_flags;
1352 unsigned short e_res;
1353 unsigned short e_oemid;
1354 unsigned short e_oeminfo;
1355 unsigned short e_res2[10];
1356 unsigned long e_lfanew;
1357 } doshdr;
1358
1359#define E32MAGIC 0x584c /* LX */
1360#define E32MODDLL 0x08000L
1361#define E32MODPROTDLL 0x18000L
1362#define E32MODMASK 0x38000L
1363#define E32LIBINIT 0x0004L
1364#define E32LIBTERM 0x40000000L
1365 struct
1366 {
1367 unsigned char e32_magic[2];
1368 unsigned char e32_border;
1369 unsigned char e32_worder;
1370 unsigned long e32_level;
1371 unsigned short e32_cpu;
1372 unsigned short e32_os;
1373 unsigned long e32_ver;
1374 unsigned long e32_mflags;
1375 unsigned long e32_mpages;
1376 unsigned long e32_startobj;
1377 unsigned long e32_eip;
1378 unsigned long e32_stackobj;
1379 unsigned long e32_esp;
1380 unsigned long e32_pagesize;
1381 unsigned long e32_pageshift;
1382 unsigned long e32_fixupsize;
1383 unsigned long e32_fixupsum;
1384 unsigned long e32_ldrsize;
1385 unsigned long e32_ldrsum;
1386 unsigned long e32_objtab;
1387 unsigned long e32_objcnt;
1388 unsigned long e32_objmap;
1389 unsigned long e32_itermap;
1390 unsigned long e32_rsrctab;
1391 unsigned long e32_rsrccnt;
1392 unsigned long e32_restab;
1393 unsigned long e32_enttab;
1394 unsigned long e32_dirtab;
1395 unsigned long e32_dircnt;
1396 unsigned long e32_fpagetab;
1397 unsigned long e32_frectab;
1398 unsigned long e32_impmod;
1399 unsigned long e32_impmodcnt;
1400 unsigned long e32_impproc;
1401 unsigned long e32_pagesum;
1402 unsigned long e32_datapage;
1403 unsigned long e32_preload;
1404 unsigned long e32_nrestab;
1405 unsigned long e32_cbnrestab;
1406 unsigned long e32_nressum;
1407 unsigned long e32_autodata;
1408 unsigned long e32_debuginfo;
1409 unsigned long e32_debuglen;
1410 unsigned long e32_instpreload;
1411 unsigned long e32_instdemand;
1412 unsigned long e32_heapsize;
1413 unsigned long e32_stacksize;
1414 unsigned char e32_res3[20];
1415 } os2hdr;
1416#pragma pack()
1417 off_t offLX;
1418 FILE *phFile = fopen(pszFilename, "rb");
1419
1420 if (!phFile)
1421 error("Cannot open input file `%s'", pszFilename);
1422
1423 /* stub header */
1424 if (fread(&doshdr, 1, sizeof(doshdr), phFile) != sizeof(doshdr))
1425 error("Error read error while reading `%s'\n", pszFilename);
1426 if (doshdr.e_magic != EMAGIC && doshdr.e_magic != E32MAGIC)
1427 error("`%s' is not a LX DLL\n", pszFilename);
1428 offLX = doshdr.e_magic == EMAGIC ? doshdr.e_lfanew : 0;
1429
1430 /* LX header */
1431 if (fseek(phFile, offLX, SEEK_SET))
1432 error("Bad LX .DLL `%s'\n", pszFilename);
1433 if (fread(&os2hdr, 1, sizeof(os2hdr), phFile) != sizeof(os2hdr))
1434 error("Error read error while reading `%s'\n", pszFilename);
1435 if (*(unsigned short*)os2hdr.e32_magic != E32MAGIC || !os2hdr.e32_restab)
1436 error("`%s': Bad LX format\n", pszFilename);
1437 if ( (os2hdr.e32_mflags & E32MODMASK) != E32MODDLL
1438 && (os2hdr.e32_mflags & E32MODMASK) != E32MODPROTDLL)
1439 error("`%s': Not a LX DLL\n", pszFilename);
1440
1441 /* Read the tables. */
1442 if (mode == M_DLL_TO_DEF && !first_module)
1443 {
1444 dll_read_names(phFile, os2hdr.e32_restab + offLX, 0x7ffffff, 1, 1, pszFilename);
1445 dll_read_names(phFile, os2hdr.e32_nrestab, os2hdr.e32_cbnrestab, 0, 1, pszFilename);
1446
1447 first_module = xstrdup(module_name);
1448 fprintf(out_file, "LIBRARY %s", first_module);
1449 fprintf(out_file, (os2hdr.e32_mflags & E32LIBINIT) ? " INITINSTANCE" : " INITGLOBAL");
1450 fprintf(out_file, (os2hdr.e32_mflags & E32LIBTERM) ? " TERMINSTANCE" : " TERMGLOBAL");
1451 fprintf(out_file, "\n");
1452 if (description)
1453 fprintf(out_file, "DESCRIPTION '%s'\n", description);
1454 fprintf(out_file, "EXPORTS\n");
1455 if (ferror(out_file))
1456 write_error(out_fname);
1457 }
1458 dll_read_names(phFile, os2hdr.e32_restab + offLX, 0x7ffffff, 1, 0, pszFilename);
1459 if (os2hdr.e32_nrestab)
1460 dll_read_names(phFile, os2hdr.e32_nrestab, os2hdr.e32_cbnrestab, 0, 0, pszFilename);
1461
1462 fclose(phFile);
1463}
1464
1465
1466int main (int argc, char *argv[])
1467{
1468 int i, c;
1469 int imp_count, lib_count, def_count, dll_count, page_size;
1470 struct predef *pp1;
1471 char *q, *ext, *opt_o;
1472
1473 _response (&argc, &argv);
1474 predefs = NULL; out_base = NULL; as_name = NULL; pipe_flag = FALSE;
1475 profile_flag = FALSE; page_size = 16;
1476 opt_b = FALSE; opt_q = FALSE; opt_s = FALSE; base_len = 0; opt_o = NULL;
1477 opterr = 0;
1478 optind = 1;
1479 while ((c = getopt (argc, argv, "a::b:lmo:p:qsP:")) != EOF)
1480 {
1481 switch (c)
1482 {
1483 case 'a':
1484 as_name = (optarg != NULL ? optarg : "as");
1485 pipe_flag = (_osmode != DOS_MODE);
1486 break;
1487 case 'b':
1488 opt_b = TRUE;
1489 base_len = strtol (optarg, &q, 10);
1490 if (base_len > 1 && *q == 0)
1491 out_base = NULL;
1492 else
1493 {
1494 out_base = optarg;
1495 base_len = 0;
1496 }
1497 break;
1498 case 'l':
1499 opt_lazy = TRUE;
1500 break;
1501 case 'm':
1502 profile_flag = TRUE;
1503 break;
1504 case 'o':
1505 if (opt_o != NULL)
1506 usage ();
1507 opt_o = optarg;
1508 break;
1509 case 'p':
1510 pp1 = xmalloc (sizeof (struct predef));
1511 pp1->name = xstrdup (optarg);
1512 pp1->next = predefs;
1513 predefs = pp1;
1514 break;
1515 case 'q':
1516 opt_q = TRUE;
1517 break;
1518 case 's':
1519 opt_s = TRUE;
1520 break;
1521 default:
1522 error ("Invalid option");
1523 }
1524 }
1525 imp_count = 0; lib_count = 0; def_count = 0; dll_count = 0;
1526 for (i = optind; i < argc; ++i)
1527 {
1528 ext = _getext (argv[i]);
1529 if (ext != NULL && stricmp (ext, ".lib") == 0)
1530 ++lib_count;
1531 else if (ext != NULL && stricmp (ext, ".imp") == 0)
1532 ++imp_count;
1533 else if (ext != NULL && stricmp (ext, ".def") == 0)
1534 ++def_count;
1535 else if (ext != NULL && stricmp (ext, ".dll") == 0)
1536 ++dll_count;
1537 else
1538 error ("Input file `%s' has unknown file name extension", argv[i]);
1539 }
1540 if (imp_count == 0 && lib_count == 0 && def_count == 0 && dll_count == 0)
1541 usage ();
1542 if ((imp_count != 0) + (lib_count != 0) + (def_count != 0) + (dll_count != 0) > 1)
1543 error ("More than one type of input files");
1544 if (opt_o == NULL)
1545 {
1546 if (lib_count != 0)
1547 error ("Cannot convert .lib files to %s files",
1548 (as_name == NULL ? ".s" : ".o"));
1549 if (def_count != 0)
1550 error ("Cannot convert .def files to %s files",
1551 (as_name == NULL ? ".s" : ".o"));
1552 if (dll_count != 0)
1553 error ("Cannot convert .dll files to %s files",
1554 (as_name == NULL ? ".s" : ".o"));
1555 mode = M_IMP_TO_S;
1556 }
1557 else
1558 {
1559 ext = _getext (opt_o);
1560 if (ext != NULL && stricmp (ext, ".imp") == 0)
1561 {
1562 if (imp_count != 0)
1563 error ("Cannot convert .imp files to .imp file");
1564 if (dll_count != 0)
1565 mode = M_DLL_TO_IMP;
1566 else if (lib_count != 0)
1567 mode = M_LIB_TO_IMP;
1568 else
1569 mode = M_DEF_TO_IMP;
1570 }
1571 else if (ext != NULL && stricmp (ext, ".a") == 0)
1572 {
1573 if (dll_count != 0)
1574 mode = M_DLL_TO_A;
1575 else if (def_count != 0)
1576 mode = M_DEF_TO_A;
1577 else if (imp_count != 0)
1578 mode = M_IMP_TO_A;
1579 else
1580 mode = M_LIB_TO_A;
1581 }
1582 else if (ext != NULL && stricmp (ext, ".def") == 0)
1583 {
1584 if (def_count != 0)
1585 error ("Cannot convert .def files to .def file");
1586 if (lib_count != 0)
1587 error ("Cannot convert .lib files to .def file");
1588 if (dll_count != 0)
1589 mode = M_DLL_TO_DEF;
1590 else
1591 mode = M_IMP_TO_DEF;
1592 }
1593 else if (ext != NULL && stricmp (ext, ".lib") == 0)
1594 {
1595 if (lib_count != 0)
1596 error ("Cannot convert .lib files to .lib file");
1597 if (dll_count != 0)
1598 mode = M_DLL_TO_LIB;
1599 else if (def_count != 0)
1600 mode = M_DEF_TO_LIB;
1601 else
1602 mode = M_IMP_TO_LIB;
1603 if (predefs != NULL)
1604 {
1605 if (predefs->next != NULL)
1606 usage ();
1607 page_size = strtol (predefs->name, &q, 10);
1608 if (page_size < 1 || *q != 0)
1609 usage ();
1610 predefs = NULL; /* See below */
1611 }
1612 }
1613 else
1614 error ("File name extension of output file not supported");
1615 _strncpy (out_fname, opt_o, sizeof (out_fname));
1616 }
1617 if (mode != M_IMP_TO_S)
1618 if (as_name != NULL || opt_b || opt_s || predefs != NULL)
1619 usage ();
1620 if (profile_flag && mode != M_DEF_TO_A && mode != M_IMP_TO_A
1621 && mode != M_LIB_TO_A && mode != M_DEF_TO_A)
1622 usage ();
1623 switch (mode)
1624 {
1625 case M_LIB_TO_IMP:
1626 create_output_file (FALSE);
1627 for (i = optind; i < argc; ++i)
1628 read_lib (argv[i]);
1629 close_output_file ();
1630 break;
1631 case M_LIB_TO_A:
1632 create_output_file (TRUE);
1633 init_archive ();
1634 for (i = optind; i < argc; ++i)
1635 read_lib (argv[i]);
1636 close_output_file ();
1637 break;
1638 case M_IMP_TO_S:
1639 for (i = optind; i < argc; ++i)
1640 read_imp (argv[i]);
1641 break;
1642 case M_IMP_TO_DEF:
1643 create_output_file (FALSE);
1644 for (i = optind; i < argc; ++i)
1645 read_imp (argv[i]);
1646 close_output_file ();
1647 break;
1648 case M_IMP_TO_LIB:
1649 out_lib = omflib_create (out_fname, page_size, lib_errmsg);
1650 if (out_lib == NULL)
1651 lib_error ();
1652 if (omflib_header (out_lib, lib_errmsg) != 0)
1653 lib_error ();
1654 for (i = optind; i < argc; ++i)
1655 read_imp (argv[i]);
1656 if (omflib_finish (out_lib, lib_errmsg) != 0
1657 || omflib_close (out_lib, lib_errmsg) != 0)
1658 lib_error ();
1659 break;
1660 case M_IMP_TO_A:
1661 create_output_file (TRUE);
1662 init_archive ();
1663 for (i = optind; i < argc; ++i)
1664 read_imp (argv[i]);
1665 close_output_file ();
1666 break;
1667 case M_DEF_TO_A:
1668 create_output_file (TRUE);
1669 init_archive ();
1670 for (i = optind; i < argc; ++i)
1671 read_def (argv[i]);
1672 close_output_file ();
1673 break;
1674 case M_DEF_TO_IMP:
1675 create_output_file (FALSE);
1676 for (i = optind; i < argc; ++i)
1677 read_def (argv[i]);
1678 close_output_file ();
1679 break;
1680 case M_DEF_TO_LIB:
1681 out_lib = omflib_create (out_fname, page_size, lib_errmsg);
1682 if (out_lib == NULL)
1683 lib_error ();
1684 if (omflib_header (out_lib, lib_errmsg) != 0)
1685 lib_error ();
1686 for (i = optind; i < argc; ++i)
1687 read_def (argv[i]);
1688 if (omflib_finish (out_lib, lib_errmsg) != 0
1689 || omflib_close (out_lib, lib_errmsg) != 0)
1690 lib_error ();
1691 break;
1692 case M_DLL_TO_A:
1693 create_output_file (TRUE);
1694 init_archive ();
1695 for (i = optind; i < argc; ++i)
1696 read_dll (argv[i]);
1697 close_output_file ();
1698 break;
1699 case M_DLL_TO_IMP:
1700 create_output_file (FALSE);
1701 for (i = optind; i < argc; ++i)
1702 read_dll (argv[i]);
1703 close_output_file ();
1704 break;
1705 case M_DLL_TO_LIB:
1706 out_lib = omflib_create (out_fname, page_size, lib_errmsg);
1707 if (out_lib == NULL)
1708 lib_error ();
1709 if (omflib_header (out_lib, lib_errmsg) != 0)
1710 lib_error ();
1711 for (i = optind; i < argc; ++i)
1712 read_dll (argv[i]);
1713 if (omflib_finish (out_lib, lib_errmsg) != 0
1714 || omflib_close (out_lib, lib_errmsg) != 0)
1715 lib_error ();
1716 break;
1717
1718 case M_DLL_TO_DEF:
1719 create_output_file (FALSE);
1720 for (i = optind; i < argc; ++i)
1721 read_dll (argv[i]);
1722 close_output_file ();
1723 break;
1724
1725 default:
1726 usage ();
1727 }
1728 return (warnings == 0 ? 0 : 1);
1729}
Note: See TracBrowser for help on using the repository browser.