* debug.c (debug_make_undefined_tagged_type): Make sure we are
[deliverable/binutils-gdb.git] / binutils / dlltool.c
CommitLineData
f051e1b0
SC
1#define show_allnames 0
2
765e60a9
SC
3/* dlltool.c -- tool to generate stuff for PE style DLLs
4 Copyright (C) 1995 Free Software Foundation, Inc.
5
6 This file is part of GNU Binutils.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
fb257042 20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
765e60a9
SC
21
22
23/*
24 This program allows you to build the files necessary to create
25 DLLs to run on a system which understands PE format image files.
26 (eg, Windows NT)
27
28 A DLL contains an export table which contains the information
29 which the runtime loader needs to tie up references from a
30 referencing program.
31
32 The export table is generated by this program by reading
33 in a .DEF file or scanning the .a and .o files which will be in the
199f5217 34 DLL. A .o file can contain information in special ".drectve" sections
765e60a9
SC
35 with export information.
36
37 A DEF file contains any number of the following commands:
38
39
40 NAME <name> [ , <base> ]
6f2d3212 41 The result is going to be <name>.EXE
765e60a9
SC
42
43 LIBRARY <name> [ , <base> ]
6f2d3212 44 The result is going to be <name>.DLL
765e60a9
SC
45
46 EXPORTS ( <name1> [ = <name2> ] [ @ <integer> ] [ NONAME ] [CONSTANT] ) *
6f2d3212
SC
47 Declares name1 as an exported symbol from the
48 DLL, with optional ordinal number <integer>
765e60a9
SC
49
50 IMPORTS ( [ <name> = ] <name> . <name> ) *
6f2d3212 51 Ignored for compatibility
765e60a9
SC
52
53 DESCRIPTION <string>
6f2d3212 54 Puts <string> into output .exp file in the .rdata section
765e60a9
SC
55
56 [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
6f2d3212 57 Generates --stack|--heap <number-reserve>,<number-commit>
199f5217 58 in the output .drectve section. The linker will
6f2d3212 59 see this and act upon it.
765e60a9
SC
60
61 [CODE|DATA] <attr>+
62 SECTIONS ( <sectionname> <attr>+ )*
6f2d3212
SC
63 <attr> = READ | WRITE | EXECUTE | SHARED
64 Generates --attr <sectionname> <attr> in the output
199f5217 65 .drectve section. The linker will see this and act
6f2d3212 66 upon it.
765e60a9
SC
67
68
199f5217 69 A -export:<name> in a .drectve section in an input .o or .a
765e60a9
SC
70 file to this program is equivalent to a EXPORTS <name>
71 in a .DEF file.
72
73
74
6f2d3212
SC
75 The program generates output files with the prefix supplied
76 on the command line, or in the def file, or taken from the first
77 supplied argument.
765e60a9 78
6f2d3212
SC
79 The .exp.s file contains the information necessary to export
80 the routines in the DLL. The .lib.s file contains the information
81 necessary to use the DLL's routines from a referencing program.
765e60a9
SC
82
83
84
6f2d3212 85 Example:
765e60a9 86
6f2d3212
SC
87 file1.c:
88 asm (".section .drectve");
89 asm (".ascii \"-export:adef\"");
765e60a9 90
6f2d3212
SC
91 adef(char *s)
92 {
93 printf("hello from the dll %s\n",s);
94 }
765e60a9 95
6f2d3212
SC
96 bdef(char *s)
97 {
98 printf("hello from the dll and the other entry point %s\n",s);
99 }
765e60a9 100
6f2d3212
SC
101 file2.c:
102 asm (".section .drectve");
103 asm (".ascii \"-export:cdef\"");
104 asm (".ascii \"-export:ddef\"");
105 cdef(char *s)
106 {
107 printf("hello from the dll %s\n",s);
108 }
765e60a9 109
6f2d3212
SC
110 ddef(char *s)
111 {
112 printf("hello from the dll and the other entry point %s\n",s);
113 }
765e60a9 114
6f2d3212
SC
115 printf()
116 {
117 return 9;
118 }
765e60a9 119
6f2d3212 120 main.c
765e60a9 121
6f2d3212
SC
122 main()
123 {
124 cdef();
125 }
765e60a9 126
6f2d3212 127 thedll.def
765e60a9 128
6f2d3212
SC
129 LIBRARY thedll
130 HEAPSIZE 0x40000, 0x2000
131 EXPORTS bdef @ 20
132 cdef @ 30 NONAME
765e60a9 133
6f2d3212
SC
134 SECTIONS donkey READ WRITE
135 aardvark EXECUTE
765e60a9
SC
136
137
6f2d3212 138 # compile up the parts of the dll
765e60a9 139
6f2d3212
SC
140 gcc -c file1.c
141 gcc -c file2.c
765e60a9 142
6f2d3212
SC
143 # put them in a library (you don't have to, you
144 # could name all the .os on the dlltool line)
765e60a9 145
6f2d3212
SC
146 ar qcv thedll.in file1.o file2.o
147 ranlib thedll.in
765e60a9 148
6f2d3212 149 # run this tool over the library and the def file
2757dc25 150 ./dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
765e60a9 151
6f2d3212 152 # build the dll with the library with file1.o, file2.o and the export table
2757dc25 153 ld -o thedll.dll thedll.o thedll.in
765e60a9 154
6f2d3212
SC
155 # build the mainline
156 gcc -c themain.c
765e60a9 157
6f2d3212 158 # link the executable with the import library
2757dc25 159 ld -e main -Tthemain.ld -o themain.exe themain.o thedll.a
765e60a9 160
6f2d3212 161 */
765e60a9 162
e503032e
DE
163/* .idata section description
164
165 The .idata section is the import table. It is a collection of several
166 subsections used to keep the pieces for each dll together: .idata$[234567].
167 IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc.
168
169 .idata$2 = Import Directory Table
170 = array of IMAGE_IMPORT_DESCRIPTOR's.
e503032e
DE
171
172 DWORD Characteristics; - pointer to .idata$4
173 DWORD TimeDateStamp; - currently always 0
174 DWORD ForwarderChain; - currently always 0
175 DWORD Name; - pointer to dll's name
176 PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5
177
eedc864a 178 .idata$3 = null terminating entry for .idata$2.
e503032e
DE
179
180 .idata$4 = Import Lookup Table
181 = array of array of pointers to hint name table.
182 There is one for each dll being imported from, and each dll's set is
183 terminated by a trailing NULL.
184
185 .idata$5 = Import Address Table
186 = array of array of pointers to hint name table.
187 There is one for each dll being imported from, and each dll's set is
188 terminated by a trailing NULL.
189 Initially, this table is identical to the Import Lookup Table. However,
190 at load time, the loader overwrites the entries with the address of the
191 function.
192
193 .idata$6 = Hint Name Table
194 = Array of { short, asciz } entries, one for each imported function.
195 The `short' is the function's ordinal number.
196
197 .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc)
198*/
199
6f2d3212
SC
200#define PAGE_SIZE 4096
201#define PAGE_MASK (-PAGE_SIZE)
765e60a9 202#include "bfd.h"
27fca56f
ILT
203#include "libiberty.h"
204#include "bucomm.h"
205#include "getopt.h"
531f86b4 206#include "demangle.h"
356c68ff 207#include <ctype.h>
27fca56f
ILT
208#ifdef HAVE_SYS_WAIT_H
209#include <sys/wait.h>
210#else
211#ifndef WIFEXITED
212#define WIFEXITED(w) (((w)&0377) == 0)
213#endif
214#ifndef WIFSIGNALED
215#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
216#endif
217#ifndef WTERMSIG
218#define WTERMSIG(w) ((w) & 0177)
219#endif
220#ifndef WEXITSTATUS
221#define WEXITSTATUS(w) (((w) >> 8) & 0377)
222#endif
223#endif
2757dc25 224
531f86b4 225
356c68ff 226
2757dc25 227char *as_name = "as";
fb257042 228
356c68ff
SC
229static int no_idata4;
230static int no_idata5;
231static char *exp_name;
232static char *imp_name;
233static char *head_label;
234static char *imp_name_lab;
235static char *dll_name;
2757dc25 236
356c68ff
SC
237static int add_indirect = 0;
238static int add_underscore = 0;
239static int dontdeltemps = 0;
fb257042 240
356c68ff 241int yyparse();
765e60a9 242int yydebug;
356c68ff 243static char *def_file;
2757dc25 244
356c68ff 245static char *program_name;
765e60a9 246char *strrchr ();
765e60a9
SC
247char *strdup ();
248
249static int machine;
00289839 250int killat;
6f2d3212 251static int verbose;
531f86b4 252FILE *output_def;
6f2d3212 253FILE *base_file;
6d93c360 254
765e60a9 255#ifdef DLLTOOL_ARM
6f2d3212 256static char *mname = "arm";
765e60a9
SC
257#endif
258
259#ifdef DLLTOOL_I386
6f2d3212 260static char *mname = "i386";
765e60a9 261#endif
6d93c360
ILT
262
263#ifdef DLLTOOL_PPC
264static char *mname = "ppc";
265#endif
266
6f2d3212 267#define PATHMAX 250 /* What's the right name for this ? */
765e60a9 268
356c68ff
SC
269/* This bit of assemly does jmp * ....
270s set how_jtab_roff to mark where the 32bit abs branch should go */
271unsigned char i386_jtab[] = { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90};
272
273
274unsigned char arm_jtab[] = { 0x00, 0xc0, 0x9f, 0xe5,
275 0x00, 0xf0, 0x9c, 0xe5,
276 0, 0, 0, 0};
6d93c360 277
b10f8e5e
KK
278/* This is the glue sequence for PowerPC PE. There is a */
279/* tocrel16-tocdefn reloc against the first instruction. */
280/* We also need a IMGLUE reloc against the glue function */
281/* to restore the toc saved by the third instruction in */
282/* the glue. */
283unsigned char ppc_jtab[] =
284{
285 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
286 /* Reloc TOCREL16 __imp_xxx */
287 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
288 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
289 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
290 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
291 0x20, 0x04, 0x80, 0x4E /* bctr */
292};
293
294/* the glue instruction, picks up the toc from the stw in */
295/* the above code: "lwz r2,4(r1)" */
296bfd_vma ppc_glue_insn = 0x80410004;
297
6d93c360 298
6f2d3212 299char outfile[PATHMAX];
765e60a9 300struct mac
6f2d3212
SC
301 {
302 char *type;
303 char *how_byte;
304 char *how_short;
305 char *how_long;
306 char *how_asciz;
307 char *how_comment;
308 char *how_jump;
309 char *how_global;
310 char *how_space;
fb257042 311 char *how_align_short;
f051e1b0 312 char *how_align_long;
356c68ff
SC
313 char *how_bfd_target;
314 enum bfd_architecture how_bfd_arch;
315 unsigned char *how_jtab;
316 int how_jtab_size; /* size of the jtab entry */
317 int how_jtab_roff; /* offset into it for the ind 32 reloc into idata 5 */
6f2d3212
SC
318 }
319mtable[]
320=
765e60a9 321{
6f2d3212 322 {
f88ebc68 323#define MARM 0
356c68ff
SC
324 "arm", ".byte", ".short", ".long", ".asciz", "@",
325 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
326 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
327 arm_jtab, sizeof(arm_jtab),8
6f2d3212
SC
328 }
329 ,
330 {
f88ebc68 331#define M386 1
356c68ff
SC
332 "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-i386",bfd_arch_i386,
333 i386_jtab,sizeof(i386_jtab),2,
6f2d3212
SC
334 }
335 ,
6d93c360
ILT
336 {
337#define MPPC 2
338 "ppc", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-powerpcle",bfd_arch_powerpc,
b10f8e5e 339 ppc_jtab,sizeof(ppc_jtab),0,
6d93c360
ILT
340 }
341 ,
356c68ff 342{ 0}
6f2d3212 343};
765e60a9 344
2757dc25 345
531f86b4
SC
346char *
347rvaafter (machine)
348 int machine;
2757dc25 349{
f88ebc68
SC
350 switch (machine)
351 {
352 case MARM:
353 return "";
354 case M386:
531f86b4 355 return "";
6d93c360
ILT
356 case MPPC:
357 return "";
f88ebc68 358 }
356c68ff 359return "";
2757dc25
SC
360}
361
531f86b4
SC
362char *
363rvabefore (machine)
364 int machine;
2757dc25 365{
f88ebc68
SC
366 switch (machine)
367 {
368 case MARM:
369 return ".rva\t";
370 case M386:
371 return ".rva\t";
6d93c360
ILT
372 case MPPC:
373 return ".rva\t";
f88ebc68 374 }
356c68ff 375return "";
2757dc25 376}
199f5217 377
531f86b4
SC
378char *
379asm_prefix (machine)
356c68ff 380int machine;
199f5217
DE
381{
382 switch (machine)
383 {
384 case MARM:
385 return "";
386 case M386:
387 return "_";
6d93c360
ILT
388 case MPPC:
389 return "";
199f5217 390 }
356c68ff 391return "";
199f5217 392}
765e60a9
SC
393#define ASM_BYTE mtable[machine].how_byte
394#define ASM_SHORT mtable[machine].how_short
395#define ASM_LONG mtable[machine].how_long
396#define ASM_TEXT mtable[machine].how_asciz
397#define ASM_C mtable[machine].how_comment
398#define ASM_JUMP mtable[machine].how_jump
399#define ASM_GLOBAL mtable[machine].how_global
400#define ASM_SPACE mtable[machine].how_space
fb257042 401#define ASM_ALIGN_SHORT mtable[machine].how_align_short
2757dc25
SC
402#define ASM_RVA_BEFORE rvabefore(machine)
403#define ASM_RVA_AFTER rvaafter(machine)
199f5217 404#define ASM_PREFIX asm_prefix(machine)
f051e1b0 405#define ASM_ALIGN_LONG mtable[machine].how_align_long
356c68ff
SC
406#define HOW_BFD_TARGET 0 /* always default*/
407#define HOW_BFD_ARCH mtable[machine].how_bfd_arch
408#define HOW_JTAB mtable[machine].how_jtab
409#define HOW_JTAB_SIZE mtable[machine].how_jtab_size
410#define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
765e60a9
SC
411static char **oav;
412
765e60a9
SC
413
414FILE *yyin; /* communications with flex */
415extern int linenumber;
416void
417process_def_file (name)
418 char *name;
419{
20dec772 420 FILE *f = fopen (name, FOPEN_RT);
765e60a9
SC
421 if (!f)
422 {
6f2d3212 423 fprintf (stderr, "%s: Can't open def file %s\n", program_name, name);
765e60a9
SC
424 exit (1);
425 }
426
427 yyin = f;
428
429 yyparse ();
430}
431
432/**********************************************************************/
433
434/* Communications with the parser */
435
436
437typedef struct dlist
438{
439 char *text;
440 struct dlist *next;
6f2d3212
SC
441}
442dlist_type;
765e60a9
SC
443
444typedef struct export
6f2d3212
SC
445 {
446 char *name;
447 char *internal_name;
448 int ordinal;
449 int constant;
450 int noname;
f051e1b0 451 int hint;
6f2d3212
SC
452 struct export *next;
453 }
765e60a9
SC
454export_type;
455
456static char *d_name; /* Arg to NAME or LIBRARY */
457static int d_nfuncs; /* Number of functions exported */
f051e1b0
SC
458static int d_named_nfuncs; /* Number of named functions exported */
459static int d_low_ord; /* Lowest ordinal index */
460static int d_high_ord; /* Highest ordinal index */
765e60a9 461static export_type *d_exports; /*list of exported functions */
f051e1b0 462static export_type **d_exports_lexically; /* vector of exported functions in alpha order */
6f2d3212
SC
463static dlist_type *d_list; /* Descriptions */
464static dlist_type *a_list; /* Stuff to go in directives */
765e60a9
SC
465
466static int d_is_dll;
467static int d_is_exe;
468
356c68ff 469int
765e60a9
SC
470yyerror ()
471{
6f2d3212
SC
472 fprintf (stderr, "%s: Syntax error in def file %s:%d\n",
473 program_name, def_file, linenumber);
356c68ff 474 return 0;
765e60a9
SC
475}
476
477void
b990c244 478def_exports (name, internal_name, ordinal, noname, constant)
765e60a9 479 char *name;
b990c244 480 char *internal_name;
765e60a9
SC
481 int ordinal;
482 int noname;
483 int constant;
484{
485 struct export *p = (struct export *) xmalloc (sizeof (*p));
486
487 p->name = name;
b990c244 488 p->internal_name = internal_name ? internal_name : name;
765e60a9
SC
489 p->ordinal = ordinal;
490 p->constant = constant;
491 p->noname = noname;
492 p->next = d_exports;
493 d_exports = p;
494 d_nfuncs++;
765e60a9
SC
495}
496
6f2d3212 497
765e60a9
SC
498void
499def_name (name, base)
500 char *name;
501 int base;
502{
6f2d3212
SC
503 if (verbose)
504 fprintf (stderr, "%s NAME %s base %x\n", program_name, name, base);
765e60a9
SC
505 if (d_is_dll)
506 {
507 fprintf (stderr, "Can't have LIBRARY and NAME\n");
508 }
509 d_name = name;
765e60a9
SC
510 d_is_exe = 1;
511}
512
513void
514def_library (name, base)
515 char *name;
516 int base;
517{
6f2d3212
SC
518 if (verbose)
519 printf ("%s: LIBRARY %s base %x\n", program_name, name, base);
765e60a9
SC
520 if (d_is_exe)
521 {
6f2d3212 522 fprintf (stderr, "%s: Can't have LIBRARY and NAME\n", program_name);
765e60a9
SC
523 }
524 d_name = name;
765e60a9
SC
525 d_is_dll = 1;
526}
527
528void
529def_description (desc)
530 char *desc;
531{
6f2d3212 532 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
765e60a9
SC
533 d->text = strdup (desc);
534 d->next = d_list;
535 d_list = d;
536}
537
2757dc25 538void
6f2d3212
SC
539new_directive (dir)
540 char *dir;
765e60a9 541{
6f2d3212 542 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
765e60a9
SC
543 d->text = strdup (dir);
544 d->next = a_list;
545 a_list = d;
546}
547
548void
549def_stacksize (reserve, commit)
550 int reserve;
551 int commit;
552{
553 char b[200];
6f2d3212
SC
554 if (commit > 0)
555 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
556 else
557 sprintf (b, "-stack 0x%x ", reserve);
558 new_directive (strdup (b));
765e60a9
SC
559}
560
561void
562def_heapsize (reserve, commit)
563 int reserve;
564 int commit;
565{
566 char b[200];
6f2d3212
SC
567 if (commit > 0)
568 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
569 else
570 sprintf (b, "-heap 0x%x ", reserve);
571 new_directive (strdup (b));
765e60a9
SC
572}
573
574
575void
576def_import (internal, module, entry)
577 char *internal;
578 char *module;
579 char *entry;
580{
6f2d3212
SC
581 if (verbose)
582 fprintf (stderr, "%s: IMPORTS are ignored", program_name);
765e60a9
SC
583}
584
585void
586def_version (major, minor)
356c68ff
SC
587int major;
588int minor;
765e60a9
SC
589{
590 printf ("VERSION %d.%d\n", major, minor);
591}
592
593
594void
595def_section (name, attr)
596 char *name;
597 int attr;
598{
599 char buf[200];
6f2d3212 600 char atts[5];
765e60a9
SC
601 char *d = atts;
602 if (attr & 1)
6f2d3212 603 *d++ = 'R';
765e60a9
SC
604
605 if (attr & 2)
606 *d++ = 'W';
607 if (attr & 4)
608 *d++ = 'X';
609 if (attr & 8)
610 *d++ = 'S';
611 *d++ = 0;
612 sprintf (buf, "-attr %s %s", name, atts);
6f2d3212 613 new_directive (strdup (buf));
765e60a9
SC
614}
615void
616def_code (attr)
617 int attr;
618{
619
6f2d3212 620 def_section ("CODE", attr);
765e60a9
SC
621}
622
623void
624def_data (attr)
625 int attr;
626{
6f2d3212 627 def_section ("DATA", attr);
765e60a9
SC
628}
629
630
631/**********************************************************************/
632
531f86b4 633void
2757dc25
SC
634run (what, args)
635 char *what;
636 char *args;
637{
638 char *s;
639 int pid;
640 int i;
641 char **argv;
642 extern char **environ;
643 if (verbose)
644 fprintf (stderr, "%s %s\n", what, args);
645
646 /* Count the args */
647 i = 0;
531f86b4 648 for (s = args; *s; s++)
2757dc25
SC
649 if (*s == ' ')
650 i++;
651 i++;
531f86b4 652 argv = alloca (sizeof (char *) * (i + 3));
2757dc25
SC
653 i = 0;
654 argv[i++] = what;
655 s = args;
531f86b4
SC
656 while (1)
657 {
658 argv[i++] = s;
659 while (*s != ' ' && *s != 0)
660 s++;
661 if (*s == 0)
662 break;
663 *s++ = 0;
664 }
2757dc25
SC
665 argv[i++] = 0;
666
667
668 pid = vfork ();
356c68ff 669
2757dc25
SC
670 if (pid == 0)
671 {
672 execvp (what, argv);
673 fprintf (stderr, "%s: can't exec %s\n", program_name, what);
674 exit (1);
675 }
531f86b4 676 else if (pid == -1)
2757dc25
SC
677 {
678 extern int errno;
679 fprintf (stderr, "%s: vfork failed, %d\n", program_name, errno);
680 exit (1);
681 }
531f86b4 682 else
2757dc25
SC
683 {
684 int status;
4828cdba 685 waitpid (pid, &status, 0);
531f86b4 686 if (status)
2757dc25 687 {
531f86b4 688 if (WIFSIGNALED (status))
2757dc25
SC
689 {
690 fprintf (stderr, "%s: %s %s terminated with signal %d\n",
531f86b4 691 program_name, what, args, WTERMSIG (status));
2757dc25
SC
692 exit (1);
693 }
694
531f86b4 695 if (WIFEXITED (status))
2757dc25
SC
696 {
697 fprintf (stderr, "%s: %s %s terminated with exit status %d\n",
698 program_name, what, args, WEXITSTATUS (status));
699 exit (1);
700 }
701 }
702 }
703}
704
6f2d3212 705/* read in and block out the base relocations */
2757dc25 706static void
6f2d3212
SC
707basenames (abfd)
708 bfd *abfd;
709{
710
711
712
713
714}
715
765e60a9
SC
716void
717scan_open_obj_file (abfd)
718 bfd *abfd;
719{
199f5217 720 /* Look for .drectve's */
765e60a9
SC
721 asection *s = bfd_get_section_by_name (abfd, ".drectve");
722 if (s)
723 {
724 int size = bfd_get_section_size_before_reloc (s);
725 char *buf = xmalloc (size);
726 char *p;
727 char *e;
728 bfd_get_section_contents (abfd, s, buf, 0, size);
6f2d3212
SC
729 if (verbose)
730 fprintf (stderr, "%s: Sucking in info from %s\n",
731 program_name,
732 bfd_get_filename (abfd));
765e60a9
SC
733
734 /* Search for -export: strings */
735 p = buf;
736 e = buf + size;
737 while (p < e)
738 {
739 if (p[0] == '-'
740 && strncmp (p, "-export:", 8) == 0)
741 {
742 char *name;
743 char *c;
744 p += 8;
745 name = p;
746 while (*p != ' ' && *p != '-' && p < e)
747 p++;
748 c = xmalloc (p - name + 1);
749 memcpy (c, name, p - name);
750 c[p - name] = 0;
751 def_exports (c, 0, -1, 0);
752 }
753 else
754 p++;
755 }
756 free (buf);
757 }
6f2d3212
SC
758
759 basenames (abfd);
760
761 if (verbose)
762 fprintf (stderr, "%s: Done readin\n",
763 program_name);
764
765e60a9
SC
765}
766
767
768void
769scan_obj_file (filename)
770 char *filename;
771{
772 bfd *f = bfd_openr (filename, 0);
773
774 if (!f)
775 {
2757dc25
SC
776 fprintf (stderr, "%s: Unable to open object file %s\n",
777 program_name,
6f2d3212 778 filename);
765e60a9
SC
779 exit (1);
780 }
781 if (bfd_check_format (f, bfd_archive))
782 {
783 bfd *arfile = bfd_openr_next_archived_file (f, 0);
784 while (arfile)
785 {
786 if (bfd_check_format (arfile, bfd_object))
787 scan_open_obj_file (arfile);
788 bfd_close (arfile);
789 arfile = bfd_openr_next_archived_file (f, arfile);
790 }
791 }
356c68ff 792 else if (bfd_check_format (f, bfd_object))
765e60a9
SC
793 {
794 scan_open_obj_file (f);
795 }
796
797 bfd_close (f);
798}
799
800/**********************************************************************/
801
802
765e60a9
SC
803
804void
805dump_def_info (f)
6f2d3212 806 FILE *f;
765e60a9
SC
807{
808 int i;
809 export_type *exp;
6f2d3212
SC
810 fprintf (f, "%s ", ASM_C);
811 for (i = 0; oav[i]; i++)
812 fprintf (f, "%s ", oav[i]);
813 fprintf (f, "\n");
765e60a9
SC
814 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
815 {
b990c244 816 fprintf (f, "%s %d = %s %s @ %d %s%s\n",
765e60a9
SC
817 ASM_C,
818 i,
6f2d3212
SC
819 exp->name,
820 exp->internal_name,
b990c244 821 exp->ordinal,
765e60a9
SC
822 exp->noname ? "NONAME " : "",
823 exp->constant ? "CONSTANT" : "");
824 }
825}
826/* Generate the .exp file */
827
6f2d3212
SC
828int
829sfunc (a, b)
830 long *a;
831 long *b;
832{
833 return *a - *b;
834}
835
fb257042 836
fb257042 837
2757dc25 838static void
6f2d3212
SC
839flush_page (f, need, page_addr, on_page)
840 FILE *f;
356c68ff
SC
841 int *need;
842 int page_addr;
6f2d3212
SC
843 int on_page;
844{
845 int i;
f051e1b0 846
6f2d3212 847 /* Flush this page */
4828cdba
DE
848 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
849 ASM_LONG,
ee473c97 850 page_addr,
6f2d3212
SC
851 ASM_C);
852 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
853 ASM_LONG,
854 (on_page * 2) + (on_page & 1) * 2 + 8,
855 ASM_C);
856 for (i = 0; i < on_page; i++)
857 {
356c68ff 858 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, (need[i] - page_addr) | 0x3000);
6f2d3212
SC
859 }
860 /* And padding */
861 if (on_page & 1)
862 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
863
864}
865
765e60a9 866
531f86b4
SC
867void
868gen_def_file ()
869{
870 int i;
871 export_type *exp;
356c68ff 872
531f86b4
SC
873 fprintf (output_def, ";");
874 for (i = 0; oav[i]; i++)
875 fprintf (output_def, " %s", oav[i]);
876
877 fprintf (output_def, "\nEXPORTS\n");
356c68ff 878
531f86b4
SC
879 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
880 {
356c68ff
SC
881 char *quote = strchr (exp->name, '.') ? "\"" : "";
882 fprintf (output_def, "\t%s%s%s @ %d%s ; %s\n",
883 quote,
531f86b4 884 exp->name,
356c68ff 885 quote,
531f86b4 886 exp->ordinal,
356c68ff 887 exp->noname ? " NONAME" : "",
531f86b4
SC
888 cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS));
889 }
890}
765e60a9
SC
891void
892gen_exp_file ()
893{
894 FILE *f;
765e60a9
SC
895 int i;
896 export_type *exp;
897 dlist_type *dl;
356c68ff 898
6f2d3212 899
2757dc25 900 sprintf (outfile, "t%s", exp_name);
6f2d3212
SC
901
902 if (verbose)
903 fprintf (stderr, "%s: Generate exp file %s\n",
2757dc25 904 program_name, exp_name);
765e60a9 905
20dec772 906 f = fopen (outfile, FOPEN_WT);
765e60a9
SC
907 if (!f)
908 {
6f2d3212 909 fprintf (stderr, "%s: Unable to open output file %s\n", program_name, outfile);
765e60a9
SC
910 exit (1);
911 }
6f2d3212
SC
912 if (verbose)
913 {
914 fprintf (stderr, "%s: Opened file %s\n",
915 program_name, outfile);
916 }
917
765e60a9 918 dump_def_info (f);
531f86b4
SC
919 if (d_exports)
920 {
921 fprintf (f, "\t.section .edata\n\n");
922 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
356c68ff 923 fprintf (f, "\t%s 0x%x %s Time and date\n", ASM_LONG, time(0),ASM_C);
531f86b4
SC
924 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
925 fprintf (f, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
f051e1b0
SC
926 fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
927
928
929 fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
930 fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
931 ASM_C,
932 d_named_nfuncs, d_low_ord, d_high_ord);
933 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG,
934 show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
531f86b4 935 fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
f051e1b0
SC
936
937 fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
938 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
939
531f86b4
SC
940 fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
941
942 fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
943
f051e1b0
SC
944
945 fprintf(f,"%s Export address Table\n", ASM_C);
946 fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
531f86b4 947 fprintf (f, "afuncs:\n");
f051e1b0
SC
948 i = d_low_ord;
949
531f86b4
SC
950 for (exp = d_exports; exp; exp = exp->next)
951 {
531f86b4
SC
952 if (exp->ordinal != i)
953 {
f051e1b0
SC
954#if 0
955 fprintf (f, "\t%s\t%d\t%s %d..%d missing\n",
956 ASM_SPACE,
531f86b4 957 (exp->ordinal - i) * 4,
f051e1b0 958 ASM_C,
531f86b4
SC
959 i, exp->ordinal - 1);
960 i = exp->ordinal;
6f2d3212 961#endif
f051e1b0
SC
962 while (i < exp->ordinal)
963 {
964 fprintf(f,"\t%s\t0\n", ASM_LONG);
965 i++;
966 }
967 }
531f86b4
SC
968 fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
969 ASM_PREFIX,
970 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
971 i++;
972 }
f88ebc68 973
f051e1b0 974 fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
531f86b4 975 fprintf (f, "anames:\n");
f051e1b0 976
356c68ff 977 for (i = 0; (exp = d_exports_lexically[i]); i++)
531f86b4 978 {
f051e1b0
SC
979 if (!exp->noname || show_allnames)
980 fprintf (f, "\t%sn%d%s\n", ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
531f86b4 981 }
f88ebc68 982
f051e1b0 983 fprintf (f,"%s Export Oridinal Table\n", ASM_C);
531f86b4 984 fprintf (f, "anords:\n");
356c68ff 985 for (i = 0; (exp = d_exports_lexically[i]); i++)
f051e1b0
SC
986 {
987 if (!exp->noname || show_allnames)
988 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
989 }
f88ebc68 990
f051e1b0 991 fprintf(f,"%s Export Name Table\n", ASM_C);
356c68ff 992 for (i = 0; (exp = d_exports_lexically[i]); i++)
f051e1b0
SC
993 if (!exp->noname || show_allnames)
994 fprintf (f, "n%d: %s \"%s\"\n", exp->ordinal, ASM_TEXT, exp->name);
f88ebc68 995
531f86b4
SC
996 if (a_list)
997 {
998 fprintf (f, "\t.section .drectve\n");
999 for (dl = a_list; dl; dl = dl->next)
1000 {
1001 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
1002 }
1003 }
1004 if (d_list)
1005 {
1006 fprintf (f, "\t.section .rdata\n");
1007 for (dl = d_list; dl; dl = dl->next)
1008 {
1009 char *p;
1010 int l;
1011 /* We dont output as ascii 'cause there can
1012 be quote characters in the string */
f88ebc68 1013
531f86b4
SC
1014 l = 0;
1015 for (p = dl->text; *p; p++)
1016 {
1017 if (l == 0)
1018 fprintf (f, "\t%s\t", ASM_BYTE);
1019 else
1020 fprintf (f, ",");
1021 fprintf (f, "%d", *p);
1022 if (p[1] == 0)
1023 {
1024 fprintf (f, ",0\n");
1025 break;
1026 }
1027 if (++l == 10)
1028 {
1029 fprintf (f, "\n");
1030 l = 0;
1031 }
1032 }
1033 }
1034 }
1035 }
199f5217
DE
1036
1037
1038 /* Add to the output file a way of getting to the exported names
1039 without using the import library. */
1040 if (add_indirect)
1041 {
531f86b4 1042 fprintf (f, "\t.section\t.rdata\n");
199f5217 1043 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
f051e1b0 1044 if (!exp->noname || show_allnames)
531f86b4
SC
1045 {
1046 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1047 fprintf (f, "__imp_%s:\n", exp->name);
1048 fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
1049 }
199f5217
DE
1050 }
1051
6f2d3212
SC
1052 /* Dump the reloc section if a base file is provided */
1053 if (base_file)
1054 {
1055 int addr;
1056 long need[PAGE_SIZE];
1057 long page_addr;
1058 int numbytes;
1059 int num_entries;
1060 long *copy;
1061 int j;
1062 int on_page;
531f86b4
SC
1063 fprintf (f, "\t.section\t.init\n");
1064 fprintf (f, "lab:\n");
199f5217 1065
6f2d3212
SC
1066 fseek (base_file, 0, SEEK_END);
1067 numbytes = ftell (base_file);
1068 fseek (base_file, 0, SEEK_SET);
1069 copy = malloc (numbytes);
1070 fread (copy, 1, numbytes, base_file);
1071 num_entries = numbytes / sizeof (long);
1072
6f2d3212 1073
531f86b4
SC
1074 fprintf (f, "\t.section\t.reloc\n");
1075 if (num_entries)
1076 {
ee473c97 1077
f051e1b0 1078 int src;
356c68ff 1079 int dst = 0;
f051e1b0
SC
1080 int last = -1;
1081 qsort (copy, num_entries, sizeof (long), sfunc);
1082 /* Delete duplcates */
1083 for (src = 0; src < num_entries; src++)
1084 {
1085 if (last != copy[src])
1086 last = copy[dst++] = copy[src];
1087 }
1088 num_entries = dst;
531f86b4
SC
1089 addr = copy[0];
1090 page_addr = addr & PAGE_MASK; /* work out the page addr */
1091 on_page = 0;
1092 for (j = 0; j < num_entries; j++)
1093 {
1094 addr = copy[j];
1095 if ((addr & PAGE_MASK) != page_addr)
1096 {
1097 flush_page (f, need, page_addr, on_page);
1098 on_page = 0;
1099 page_addr = addr & PAGE_MASK;
1100 }
1101 need[on_page++] = addr;
1102 }
1103 flush_page (f, need, page_addr, on_page);
1104
356c68ff 1105/* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
531f86b4 1106 }
765e60a9 1107 }
6f2d3212 1108
765e60a9 1109 fclose (f);
2757dc25
SC
1110
1111 /* assemble the file */
531f86b4 1112 sprintf (outfile, "-o %s t%s", exp_name, exp_name);
2757dc25 1113 run (as_name, outfile);
531f86b4 1114 if (dontdeltemps == 0)
2757dc25 1115 {
531f86b4 1116 sprintf (outfile, "t%s", exp_name);
2757dc25
SC
1117 unlink (outfile);
1118 }
765e60a9
SC
1119}
1120
6f2d3212
SC
1121static char *
1122xlate (char *name)
1123{
531f86b4
SC
1124 if (add_underscore)
1125 {
1126 char *copy = malloc (strlen (name) + 2);
1127 copy[0] = '_';
1128 strcpy (copy + 1, name);
1129 name = copy;
1130 }
00289839 1131
2757dc25
SC
1132 if (killat)
1133 {
1134 char *p;
1135 p = strchr (name, '@');
1136 if (p)
1137 *p = 0;
1138 }
6f2d3212
SC
1139 return name;
1140}
1141
765e60a9 1142/**********************************************************************/
f051e1b0
SC
1143
1144static void dump_iat (f, exp)
1145FILE *f;
1146export_type *exp;
1147{
1148 if (exp->noname && !show_allnames )
1149 {
1150 fprintf (f, "\t%s\t0x%08x\n",
1151 ASM_LONG,
1152 exp->ordinal | 0x80000000); /* hint or orindal ?? */
1153 }
1154 else
1155 {
1156 fprintf (f, "\t%sID%d%s\n", ASM_RVA_BEFORE,
1157 exp->ordinal,
1158 ASM_RVA_AFTER);
1159 }
1160}
765e60a9
SC
1161
1162
765e60a9 1163
356c68ff
SC
1164typedef struct
1165{
1166 int id;
1167 const char *name;
1168 int flags;
b10f8e5e 1169 int align;
356c68ff
SC
1170 asection *sec;
1171 asymbol *sym;
1172 asymbol **sympp;
1173 int size;
1174 unsigned char *data;
1175} sinfo;
1176
1177
b10f8e5e
KK
1178#ifndef DLLTOOL_PPC
1179
356c68ff
SC
1180#define TEXT 0
1181#define DATA 1
1182#define BSS 2
1183#define IDATA7 3
1184#define IDATA5 4
1185#define IDATA4 5
1186#define IDATA6 6
b10f8e5e
KK
1187#define PDATA 7
1188#define RDATA 8
1189
356c68ff
SC
1190#define NSECS 7
1191
b10f8e5e 1192
356c68ff
SC
1193static sinfo secdata[NSECS] =
1194{
b10f8e5e
KK
1195 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3},
1196 { DATA, ".data", SEC_DATA, 2},
1197 { BSS, ".bss", 0, 2},
1198 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
1199 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
1200 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
1201 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1}
1202};
1203
1204#else
1205
1206/* Sections numbered to make the order the same as other PowerPC NT */
1207/* compilers. This also keeps funny alignment thingies from happening. */
1208#define TEXT 0
1209#define PDATA 1
1210#define RDATA 2
1211#define IDATA5 3
1212#define IDATA4 4
1213#define IDATA6 5
1214#define IDATA7 6
1215#define DATA 7
1216#define BSS 8
2757dc25 1217
b10f8e5e 1218#define NSECS 9
6f2d3212 1219
b10f8e5e
KK
1220static sinfo secdata[NSECS] =
1221{
1222 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3},
1223 { PDATA, ".pdata", SEC_HAS_CONTENTS, 2},
1224 { RDATA, ".rdata", SEC_HAS_CONTENTS, 2},
1225 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
1226 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
1227 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1},
1228 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
1229 { DATA, ".data", SEC_DATA, 2},
1230 { BSS, ".bss", 0, 2}
356c68ff 1231};
b10f8e5e
KK
1232
1233#endif
1234
356c68ff
SC
1235/*
1236This is what we're trying to make
1237
1238 .text
1239 .global _GetFileVersionInfoSizeW@8
1240 .global __imp_GetFileVersionInfoSizeW@8
1241_GetFileVersionInfoSizeW@8:
1242 jmp * __imp_GetFileVersionInfoSizeW@8
1243 .section .idata$7 # To force loading of head
1244 .long __version_a_head
1245# Import Address Table
1246 .section .idata$5
1247__imp_GetFileVersionInfoSizeW@8:
1248 .rva ID2
1249
1250# Import Lookup Table
1251 .section .idata$4
1252 .rva ID2
1253# Hint/Name table
1254 .section .idata$6
1255ID2: .short 2
1256 .asciz "GetFileVersionInfoSizeW"
1257
b10f8e5e
KK
1258
1259For the PowerPC, here's the variation on the above scheme:
1260
1261# Rather than a simple "jmp *", the code to get to the dll function
1262# looks like:
1263 .text
1264 lwz r11,[tocv]__imp_function_name(r2)
1265# RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
1266 lwz r12,0(r11)
1267 stw r2,4(r1)
1268 mtctr r12
1269 lwz r2,4(r11)
1270 bctr
356c68ff
SC
1271*/
1272
b10f8e5e
KK
1273static char *
1274make_label (prefix, name)
1275 const char *prefix;
1276 const char *name;
356c68ff
SC
1277{
1278 int len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name);
1279 char *copy = xmalloc (len +1 );
1280 strcpy (copy, ASM_PREFIX);
1281 strcat (copy, prefix);
1282 strcat (copy, name);
1283 return copy;
1284}
b10f8e5e 1285
356c68ff
SC
1286static bfd *
1287make_one_lib_file (exp, i)
b10f8e5e
KK
1288 export_type *exp;
1289 int i;
356c68ff
SC
1290{
1291 if (0)
765e60a9 1292 {
356c68ff
SC
1293 FILE *f;
1294 char *prefix="d";
2757dc25 1295 sprintf (outfile, "%ss%d.s", prefix, i);
20dec772 1296 f = fopen (outfile, FOPEN_WT);
2757dc25 1297 fprintf (f, "\t.text\n");
199f5217 1298 fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX, exp->name);
f88ebc68 1299 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
199f5217
DE
1300 fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX,
1301 exp->name, ASM_JUMP, exp->name);
2757dc25 1302
f88ebc68 1303 fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C);
356c68ff 1304 fprintf (f, "\t%s\t%s\n", ASM_LONG, head_label);
2757dc25
SC
1305
1306
f051e1b0
SC
1307 fprintf (f,"%s Import Address Table\n", ASM_C);
1308
1309 fprintf (f, "\t.section .idata$5\n");
6f2d3212 1310 fprintf (f, "__imp_%s:\n", exp->name);
2757dc25 1311
f051e1b0
SC
1312 dump_iat (f, exp);
1313
1314 fprintf (f, "\n%s Import Lookup Table\n", ASM_C);
2757dc25 1315 fprintf (f, "\t.section .idata$4\n");
2757dc25 1316
f051e1b0
SC
1317 dump_iat (f, exp);
1318
1319 if(!exp->noname || show_allnames)
1320 {
1321 fprintf (f, "%s Hint/Name table\n", ASM_C);
1322 fprintf (f, "\t.section .idata$6\n");
1323 fprintf (f, "ID%d:\t%s\t%d\n", exp->ordinal, ASM_SHORT, exp->hint);
1324 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
1325 }
2757dc25 1326
2757dc25
SC
1327 fclose (f);
1328
1329
531f86b4 1330 sprintf (outfile, "-o %ss%d.o %ss%d.s", prefix, i, prefix, i);
356c68ff 1331
2757dc25 1332 run (as_name, outfile);
356c68ff 1333
765e60a9 1334 }
356c68ff
SC
1335 else
1336 {
2757dc25 1337
356c68ff
SC
1338 bfd *abfd;
1339
1340 asymbol *exp_label;
1341 asymbol *iname;
1342 asymbol *iname_lab;
1343 asymbol **iname_lab_pp;
b10f8e5e
KK
1344 asymbol **iname_pp;
1345
1346 /* Extra Symbols for PPC */
1347#ifdef DLLTOOL_PPC
1348#define EXTRA 2
1349#else
1350#define EXTRA 0
1351#endif
1352
1353 asymbol *function_name; /* ".." functionName */
1354 asymbol **fn_pp;
1355 asymbol *toc_symbol; /* The .toc symbol */
1356 asymbol **toc_pp;
1357
1358 /* one symbol for each section, 2 extra + a null */
1359 asymbol *ptrs[NSECS+3+EXTRA+1];
356c68ff
SC
1360
1361 char *outname = xmalloc (10);
1362 int oidx = 0;
1363 sprintf (outname, "ds%d.o", i);
1364 abfd = bfd_openw (outname, HOW_BFD_TARGET);
1365 if (!abfd)
1366 {
b10f8e5e
KK
1367 fprintf (stderr, "%s: bfd_open failed open output file %s\n",
1368 program_name, outname);
356c68ff
SC
1369 exit (1);
1370 }
1371
1372 bfd_set_format (abfd, bfd_object);
1373 bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
1374
1375
b10f8e5e 1376 /* First make symbols for the sections */
356c68ff
SC
1377 for (i = 0; i < NSECS; i++)
1378 {
1379 sinfo *si = secdata + i;
1380 if (si->id != i)
1381 abort();
1382 si->sec = bfd_make_section_old_way (abfd, si->name);
1383 bfd_set_section_flags (abfd,
1384 si->sec,
1385 si->flags);
b10f8e5e
KK
1386
1387 bfd_set_section_alignment(abfd, si->sec, si->align);
356c68ff 1388 si->sec->output_section = si->sec;
b10f8e5e 1389 si->sym = bfd_make_empty_symbol(abfd);
356c68ff
SC
1390 si->sym->name = si->sec->name;
1391 si->sym->section = si->sec;
1392 si->sym->flags = BSF_LOCAL;
1393 si->sym->value = 0;
1394 ptrs[oidx] = si->sym;
1395 si->sympp = ptrs + oidx;
1396
1397 oidx++;
1398 }
1399
1400 exp_label = bfd_make_empty_symbol(abfd);
1401 exp_label->name = make_label ("",exp->name);
b10f8e5e
KK
1402
1403 /* On PowerPC, the function name points to a descriptor in the
1404 rdata section, the first element of which is a pointer to the
1405 code (..function_name), and the second points to the .toc
1406 */
1407 if (machine == MPPC)
1408 exp_label->section = secdata[RDATA].sec;
1409 else
1410 exp_label->section = secdata[TEXT].sec;
1411
356c68ff
SC
1412 exp_label->flags = BSF_GLOBAL;
1413 exp_label->value = 0;
1414
1415 ptrs[oidx++] = exp_label;
1416
1417 iname = bfd_make_empty_symbol(abfd);
356c68ff 1418 iname->name = make_label ("__imp_", exp->name);
356c68ff
SC
1419 iname->section = secdata[IDATA5].sec;
1420 iname->flags = BSF_GLOBAL;
1421 iname->value = 0;
1422
1423
1424 iname_lab = bfd_make_empty_symbol(abfd);
1425
1426 iname_lab->name = head_label;
1427 iname_lab->section = (asection *)&bfd_und_section;
1428 iname_lab->flags = 0;
1429 iname_lab->value = 0;
1430
1431
b10f8e5e 1432 iname_pp = ptrs + oidx;
356c68ff 1433 ptrs[oidx++] = iname;
b10f8e5e 1434
356c68ff
SC
1435 iname_lab_pp = ptrs + oidx;
1436 ptrs[oidx++] = iname_lab;
b10f8e5e
KK
1437
1438#ifdef DLLTOOL_PPC
1439 /* The symbol refering to the code (.text) */
1440 function_name = bfd_make_empty_symbol(abfd);
1441 function_name->name = make_label ("..", exp->name);
1442 function_name->section = secdata[TEXT].sec;
1443 function_name->flags = BSF_GLOBAL;
1444 function_name->value = 0;
1445
1446 fn_pp = ptrs + oidx;
1447 ptrs[oidx++] = function_name;
1448
1449 /* The .toc symbol */
1450 toc_symbol = bfd_make_empty_symbol(abfd);
1451 toc_symbol->name = make_label (".", "toc");
1452 toc_symbol->section = (asection *)&bfd_und_section;
1453 toc_symbol->flags = BSF_GLOBAL;
1454 toc_symbol->value = 0;
1455
1456 toc_pp = ptrs + oidx;
1457 ptrs[oidx++] = toc_symbol;
1458#endif
1459
356c68ff
SC
1460 ptrs[oidx] = 0;
1461
1462 for (i = 0; i < NSECS; i++)
1463 {
1464 sinfo *si = secdata + i;
1465 asection *sec = si->sec;
1466 arelent *rel;
1467 arelent **rpp;
1468
1469 switch (i)
1470 {
1471 case TEXT:
1472 si->size = HOW_JTAB_SIZE;
1473 si->data = xmalloc (HOW_JTAB_SIZE);
1474 memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
1475
1476 /* add the reloc into idata$5 */
1477 rel = xmalloc (sizeof (arelent));
1478 rpp = xmalloc (sizeof (arelent *) * 2);
1479 rpp[0] = rel;
1480 rpp[1] = 0;
1481 rel->address = HOW_JTAB_ROFF;
1482 rel->addend = 0;
b10f8e5e
KK
1483
1484 if (machine == MPPC)
1485 {
1486 rel->howto = bfd_reloc_type_lookup (abfd,
1487 BFD_RELOC_16_GOTOFF);
1488 rel->sym_ptr_ptr = iname_pp;
1489 }
1490 else
1491 {
1492 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1493 rel->sym_ptr_ptr = secdata[IDATA5].sympp;
1494 }
356c68ff
SC
1495 sec->orelocation = rpp;
1496 sec->reloc_count = 1;
1497 break;
1498 case IDATA4:
1499 case IDATA5:
1500 /* An idata$4 or idata$5 is one word long, and has an
1501 rva to idata$6 */
1502
356c68ff
SC
1503 si->data = xmalloc (4);
1504 si->size = 4;
1505
1506 if (exp->noname)
1507 {
1508 si->data[0] = exp->ordinal ;
1509 si->data[1] = exp->ordinal >> 8;
1510 si->data[2] = exp->ordinal >> 16;
1511 si->data[3] = 0x80;
1512 }
1513 else
1514 {
1515 sec->reloc_count = 1;
1516 memset (si->data, 0, si->size);
1517 rel = xmalloc (sizeof (arelent));
1518 rpp = xmalloc (sizeof (arelent *) * 2);
1519 rpp[0] = rel;
1520 rpp[1] = 0;
1521 rel->address = 0;
1522 rel->addend = 0;
1523 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
1524 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
1525 sec->orelocation = rpp;
1526 }
1527
1528 break;
1529
1530 case IDATA6:
1531 if (!exp->noname)
1532 {
1533 int idx = exp->hint + 1;
1534 si->size = strlen (xlate (exp->name)) + 3;
1535 si->data = xmalloc (si->size);
1536 si->data[0] = idx & 0xff;
1537 si->data[1] = idx >> 8;
1538 strcpy (si->data + 2, xlate (exp->name));
1539 }
1540 break;
1541 case IDATA7:
1542 si->size = 4;
1543 si->data =xmalloc(4);
1544 memset (si->data, 0, si->size);
1545 rel = xmalloc (sizeof (arelent));
1546 rpp = xmalloc (sizeof (arelent *) * 2);
1547 rpp[0] = rel;
1548 rel->address = 0;
1549 rel->addend = 0;
1550 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1551 rel->sym_ptr_ptr = iname_lab_pp;
1552 sec->orelocation = rpp;
1553 sec->reloc_count = 1;
1554 break;
b10f8e5e
KK
1555
1556 case PDATA:
1557 {
1558 /* The .pdata section is 5 words long. */
1559 /* Think of it as: */
1560 /* struct */
1561 /* { */
1562 /* bfd_vma BeginAddress, [0x00] */
1563 /* EndAddress, [0x04] */
1564 /* ExceptionHandler, [0x08] */
1565 /* HandlerData, [0x0c] */
1566 /* PrologEndAddress; [0x10] */
1567 /* }; */
1568
1569 /* So this pdata section setups up this as a glue linkage to
1570 a dll routine. There are a number of house keeping things
1571 we need to do:
1572
1573 1. In the name of glue trickery, the ADDR32 relocs for 0,
1574 4, and 0x10 are set to point to the same place:
1575 "..function_name".
1576 2. There is one more reloc needed in the pdata section.
1577 The actual glue instruction to restore the toc on
1578 return is saved as the offset in an IMGLUE reloc.
1579 So we need a total of four relocs for this section.
1580
1581 3. Lastly, the HandlerData field is set to 0x03, to indicate
1582 that this is a glue routine.
1583 */
1584 arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
1585
1586 /* alignment must be set to 2**2 or you get extra stuff */
1587 bfd_set_section_alignment(abfd, sec, 2);
1588
1589 si->size = 4 * 5;
1590 si->data =xmalloc(4 * 5);
1591 memset (si->data, 0, si->size);
1592 rpp = xmalloc (sizeof (arelent *) * 5);
1593 rpp[0] = imglue = xmalloc (sizeof (arelent));
1594 rpp[1] = ba_rel = xmalloc (sizeof (arelent));
1595 rpp[2] = ea_rel = xmalloc (sizeof (arelent));
1596 rpp[3] = pea_rel = xmalloc (sizeof (arelent));
1597 rpp[4] = 0;
1598
1599 /* stick the toc reload instruction in the glue reloc */
1600 bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
1601
1602 imglue->addend = 0;
1603 imglue->howto = bfd_reloc_type_lookup (abfd,
1604 BFD_RELOC_32_GOTOFF);
1605 imglue->sym_ptr_ptr = fn_pp;
1606
1607 ba_rel->address = 0;
1608 ba_rel->addend = 0;
1609 ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1610 ba_rel->sym_ptr_ptr = fn_pp;
1611
1612 bfd_put_32(abfd, 0x18, si->data + 0x04);
1613 ea_rel->address = 4;
1614 ea_rel->addend = 0;
1615 ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1616 ea_rel->sym_ptr_ptr = fn_pp;
1617
1618 /* mark it as glue */
1619 bfd_put_32(abfd, 0x03, si->data + 0x0c);
1620
1621 /* mark the prolog end address */
1622 bfd_put_32(abfd, 0x0D, si->data + 0x10);
1623 pea_rel->address = 0x10;
1624 pea_rel->addend = 0;
1625 pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1626 pea_rel->sym_ptr_ptr = fn_pp;
1627
1628 sec->orelocation = rpp;
1629 sec->reloc_count = 4;
1630 break;
1631 }
1632 case RDATA:
1633 /* Each external function in a PowerPC PE file has a two word
1634 descriptor consisting of:
1635 1. The address of the code.
1636 2. The address of the appropriate .toc
1637 We use relocs to build this.
1638 */
1639
1640 si->size = 8;
1641 si->data =xmalloc(8);
1642 memset (si->data, 0, si->size);
1643
1644 rpp = xmalloc (sizeof (arelent *) * 3);
1645 rpp[0] = rel = xmalloc (sizeof (arelent));
1646 rpp[1] = xmalloc (sizeof (arelent));
1647 rpp[2] = 0;
1648
1649 rel->address = 0;
1650 rel->addend = 0;
1651 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1652 rel->sym_ptr_ptr = fn_pp;
1653
1654 rel = rpp[1];
1655
1656 rel->address = 4;
1657 rel->addend = 0;
1658 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1659 rel->sym_ptr_ptr = toc_pp;
1660
1661 sec->orelocation = rpp;
1662 sec->reloc_count = 2;
1663 break;
356c68ff
SC
1664 }
1665 }
1666
1667 {
1668 bfd_vma vma = 0;
1669 /* Size up all the sections */
1670 for (i = 0; i < NSECS; i++)
1671 {
1672 sinfo *si = secdata + i;
b10f8e5e 1673
356c68ff
SC
1674 bfd_set_section_size (abfd, si->sec, si->size);
1675 bfd_set_section_vma (abfd, si->sec, vma);
b10f8e5e 1676
356c68ff
SC
1677/* vma += si->size;*/
1678 }
1679 }
1680 /* Write them out */
1681 for (i = 0; i < NSECS; i++)
1682 {
1683 sinfo *si = secdata + i;
b10f8e5e 1684
356c68ff
SC
1685 if (i == IDATA5 && no_idata5)
1686 continue;
1687
1688 if (i == IDATA4 && no_idata4)
1689 continue;
1690
1691 bfd_set_section_contents (abfd, si->sec,
1692 si->data, 0,
1693 si->size);
1694 }
1695
1696 bfd_set_symtab (abfd, ptrs, oidx);
1697 bfd_close (abfd);
1698 abfd = bfd_openr (outname, HOW_BFD_TARGET);
1699 return abfd;
1700 }
1701
1702}
1703
1704
b10f8e5e 1705static bfd *
356c68ff
SC
1706make_head()
1707{
20dec772 1708 FILE * f = fopen ("dh.s", FOPEN_WT);
356c68ff
SC
1709
1710 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
1711 fprintf (f, "\t.section .idata$2\n");
1712
1713 fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
1714
1715 fprintf (f, "%s:\n", head_label);
1716
1717 fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
1718 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1719
1720 fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
1721 fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
1722 fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
1723 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
1724 fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
1725 ASM_RVA_BEFORE,
1726 imp_name_lab,
1727 ASM_RVA_AFTER,
1728 ASM_C);
1729 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
1730 ASM_RVA_BEFORE,
1731 ASM_RVA_AFTER, ASM_C);
1732
1733 fprintf (f, "%sStuff for compatibility\n", ASM_C);
1734
1735 if (!no_idata5)
1736 {
1737 fprintf (f, "\t.section\t.idata$5\n");
1738 fprintf (f, "\t%s\t0\n", ASM_LONG);
1739 fprintf (f, "fthunk:\n");
1740 }
1741 if (!no_idata4)
1742 {
1743 fprintf (f, "\t.section\t.idata$4\n");
1744
1745 fprintf (f, "\t%s\t0\n", ASM_LONG);
1746 fprintf (f, "\t.section .idata$4\n");
1747 fprintf (f, "hname:\n");
1748 }
1749 fclose (f);
1750
1751 sprintf (outfile, "-o dh.o dh.s");
1752 run (as_name, outfile);
1753
1754 return bfd_openr ("dh.o", HOW_BFD_TARGET);
1755}
1756
b10f8e5e
KK
1757static bfd *
1758make_tail()
356c68ff 1759{
20dec772 1760 FILE * f = fopen ("dt.s", FOPEN_WT);
b10f8e5e
KK
1761
1762#ifdef DLLTOOL_PPC
1763 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
1764 do too. Original, huh? */
1765 fprintf (f, "\t.section .idata$6\n");
1766#else
56297cc6 1767 fprintf (f, "\t.section .idata$7\n");
b10f8e5e
KK
1768#endif
1769
531f86b4 1770 fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
2757dc25 1771 fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
531f86b4 1772 imp_name_lab, ASM_TEXT, dll_name);
2757dc25 1773
356c68ff
SC
1774 if (!no_idata4)
1775 {
1776 fprintf (f, "\t.section .idata$4\n");
1777 fprintf (f, "\t%s\t0\n", ASM_LONG);
1778 }
1779 if (!no_idata5)
1780 {
1781 fprintf (f, "\t.section .idata$5\n");
1782 fprintf (f, "\t%s\t0\n", ASM_LONG);
1783 }
b10f8e5e
KK
1784
1785
1786#ifdef DLLTOOL_PPC
1787 /* Normally, we need to see a null descriptor built in idata$3 to
1788 act as the terminator for the list. The ideal way, I suppose,
1789 would be to mark this section as a comdat type 2 section, so
1790 only one would appear in the final .exe (if our linker supported
1791 comdat, that is) or cause it to be inserted by something else (say
1792 crt0)
1793 */
1794
1795 fprintf (f, "\t.section .idata$3\n");
1796 fprintf (f, "\t%s\t0\n", ASM_LONG);
1797 fprintf (f, "\t%s\t0\n", ASM_LONG);
1798 fprintf (f, "\t%s\t0\n", ASM_LONG);
1799 fprintf (f, "\t%s\t0\n", ASM_LONG);
1800 fprintf (f, "\t%s\t0\n", ASM_LONG);
1801#endif
1802
2757dc25
SC
1803 fclose (f);
1804
356c68ff 1805 sprintf (outfile, "-o dt.o dt.s");
2757dc25 1806 run (as_name, outfile);
356c68ff
SC
1807 return bfd_openr ("dt.o", HOW_BFD_TARGET);
1808}
2757dc25 1809
356c68ff
SC
1810static void
1811gen_lib_file ()
1812{
1813 int i;
1814 export_type *exp;
1815 bfd *ar_head;
1816 bfd *ar_tail;
1817 bfd *outarch;
1818 bfd * head = 0;
2757dc25 1819
356c68ff 1820 unlink (imp_name);
2757dc25 1821
356c68ff 1822 outarch = bfd_openw (imp_name, HOW_BFD_TARGET);
2757dc25 1823
356c68ff 1824 if (!outarch)
765e60a9 1825 {
356c68ff
SC
1826 fprintf (stderr, "%s: Can't open .lib file %s\n", program_name, imp_name);
1827 exit (1);
1828 }
1829 bfd_set_format (outarch, bfd_archive);
1830 outarch->has_armap = 1;
1831
1832 /* Work out a reasonable size of things to put onto one line. */
2757dc25 1833
2757dc25 1834
2757dc25 1835
356c68ff
SC
1836 ar_head = make_head ();
1837 ar_tail = make_tail();
1838
1839 for (i = 0; (exp = d_exports_lexically[i]); i++)
1840 {
1841 bfd *n = make_one_lib_file (exp, i);
1842 n->next = head;
1843 head = n;
765e60a9 1844 }
356c68ff
SC
1845
1846
1847 /* Now stick them all into the archive */
1848
1849 ar_head->next = head;
1850 ar_tail->next = ar_head;
1851 head = ar_tail;
1852
1853 bfd_set_archive_head (outarch, head);
1854 bfd_close (outarch);
765e60a9 1855
2757dc25 1856 /* Delete all the temp files */
765e60a9 1857
f88ebc68 1858 if (dontdeltemps == 0)
2757dc25 1859 {
356c68ff 1860 sprintf (outfile, "dh.o");
2757dc25 1861 unlink (outfile);
356c68ff 1862 sprintf (outfile, "dh.s");
2757dc25 1863 unlink (outfile);
356c68ff 1864 sprintf (outfile, "dt.o");
2757dc25 1865 unlink (outfile);
356c68ff 1866 sprintf (outfile, "dt.s");
2757dc25
SC
1867 unlink (outfile);
1868 }
f88ebc68 1869
199f5217
DE
1870 if (dontdeltemps < 2)
1871 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1872 {
356c68ff 1873 sprintf (outfile, "ds%d.o",i);
199f5217
DE
1874 unlink (outfile);
1875 }
2757dc25 1876
765e60a9
SC
1877}
1878/**********************************************************************/
1879
1880/* Run through the information gathered from the .o files and the
1881 .def file and work out the best stuff */
1882int
1883pfunc (a, b)
1884 void *a;
1885 void *b;
1886{
1887 export_type *ap = *(export_type **) a;
1888 export_type *bp = *(export_type **) b;
1889 if (ap->ordinal == bp->ordinal)
1890 return 0;
1891
1892 /* unset ordinals go to the bottom */
1893 if (ap->ordinal == -1)
1894 return 1;
1895 if (bp->ordinal == -1)
1896 return -1;
1897 return (ap->ordinal - bp->ordinal);
1898}
1899
1900
1901int
1902nfunc (a, b)
1903 void *a;
1904 void *b;
1905{
1906 export_type *ap = *(export_type **) a;
1907 export_type *bp = *(export_type **) b;
1908
1909 return (strcmp (ap->name, bp->name));
1910}
1911
1912static
1913void
1914remove_null_names (ptr)
1915 export_type **ptr;
1916{
1917 int src;
1918 int dst;
1919 for (dst = src = 0; src < d_nfuncs; src++)
1920 {
1921 if (ptr[src])
1922 {
1923 ptr[dst] = ptr[src];
1924 dst++;
1925 }
1926 }
1927 d_nfuncs = dst;
1928}
1929
1930static void
1931dtab (ptr)
1932 export_type **ptr;
1933{
1934#ifdef SACDEBUG
1935 int i;
1936 for (i = 0; i < d_nfuncs; i++)
1937 {
1938 if (ptr[i])
1939 {
1940 printf ("%d %s @ %d %s%s\n",
1941 i, ptr[i]->name, ptr[i]->ordinal,
1942 ptr[i]->noname ? "NONAME " : "",
1943 ptr[i]->constant ? "CONSTANT" : "");
1944 }
1945 else
1946 printf ("empty\n");
1947 }
1948#endif
1949}
1950
1951static void
1952process_duplicates (d_export_vec)
1953 export_type **d_export_vec;
1954{
1955 int more = 1;
f051e1b0 1956 int i;
765e60a9
SC
1957 while (more)
1958 {
f051e1b0 1959
765e60a9
SC
1960 more = 0;
1961 /* Remove duplicates */
1962 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
1963
1964 dtab (d_export_vec);
1965 for (i = 0; i < d_nfuncs - 1; i++)
1966 {
1967 if (strcmp (d_export_vec[i]->name,
1968 d_export_vec[i + 1]->name) == 0)
1969 {
1970
1971 export_type *a = d_export_vec[i];
1972 export_type *b = d_export_vec[i + 1];
1973
1974 more = 1;
6f2d3212
SC
1975 if (verbose)
1976 fprintf (stderr, "Warning, ignoring duplicate EXPORT %s %d,%d\n",
1977 a->name,
1978 a->ordinal,
1979 b->ordinal);
765e60a9
SC
1980 if (a->ordinal != -1
1981 && b->ordinal != -1)
1982 {
1983
1984 fprintf (stderr, "Error, duplicate EXPORT with oridinals %s\n",
1985 a->name);
1986 exit (1);
1987 }
1988 /* Merge attributes */
1989 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
1990 b->constant |= a->constant;
1991 b->noname |= a->noname;
1992 d_export_vec[i] = 0;
1993 }
1994
1995 dtab (d_export_vec);
1996 remove_null_names (d_export_vec);
1997 dtab (d_export_vec);
1998 }
1999 }
f051e1b0
SC
2000
2001
2002 /* Count the names */
2003 for (i = 0; i < d_nfuncs; i++)
2004 {
2005 if (!d_export_vec[i]->noname)
2006 d_named_nfuncs++;
2007 }
765e60a9
SC
2008}
2009
2010static void
2011fill_ordinals (d_export_vec)
2012 export_type **d_export_vec;
2013{
2014 int lowest = 0;
356c68ff 2015
f051e1b0 2016 int i;
6f2d3212 2017 char *ptr;
765e60a9
SC
2018 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2019
6f2d3212
SC
2020 /* fill in the unset ordinals with ones from our range */
2021
2022 ptr = (char *) malloc (65536);
2023
6d93c360 2024 memset (ptr, 0, 65536);
6f2d3212
SC
2025
2026 /* Mark in our large vector all the numbers that are taken */
765e60a9
SC
2027 for (i = 0; i < d_nfuncs; i++)
2028 {
6f2d3212 2029 if (d_export_vec[i]->ordinal != -1)
765e60a9 2030 {
6f2d3212
SC
2031 ptr[d_export_vec[i]->ordinal] = 1;
2032 if (lowest == 0)
2033 lowest = d_export_vec[i]->ordinal;
765e60a9 2034 }
6f2d3212
SC
2035 }
2036
20dec772
ILT
2037 /* Start at 1 for compatibility with MS toolchain. */
2038 if (lowest == 0)
2039 lowest = 1;
2040
6f2d3212
SC
2041 for (i = 0; i < d_nfuncs; i++)
2042 {
2043 if (d_export_vec[i]->ordinal == -1)
765e60a9 2044 {
6f2d3212
SC
2045 int j;
2046 for (j = lowest; j < 65536; j++)
2047 if (ptr[j] == 0)
2048 {
2049 ptr[j] = 1;
2050 d_export_vec[i]->ordinal = j;
2051 goto done;
2052 }
2053
2054 for (j = 1; j < lowest; j++)
2055 if (ptr[j] == 0)
2056 {
2057 ptr[j] = 1;
2058 d_export_vec[i]->ordinal = j;
2059 goto done;
2060 }
2061 done:;
2062
765e60a9
SC
2063 }
2064 }
2065
6f2d3212
SC
2066 free (ptr);
2067
2068 /* And resort */
2069
2070 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2071
799de4c4 2072 /* Work out the lowest and highest ordinal numbers. */
356c68ff
SC
2073 if (d_nfuncs)
2074 {
799de4c4
DE
2075 if (d_export_vec[0])
2076 d_low_ord = d_export_vec[0]->ordinal;
356c68ff
SC
2077 if (d_export_vec[d_nfuncs-1])
2078 d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
2079 }
f051e1b0
SC
2080}
2081
2082int alphafunc(av,bv)
2083void *av;
2084void *bv;
2085{
2086 export_type **a = av;
2087 export_type **b = bv;
2088
2089 return strcmp ((*a)->name, (*b)->name);
765e60a9 2090}
f051e1b0 2091
765e60a9
SC
2092void
2093mangle_defs ()
2094{
2095 /* First work out the minimum ordinal chosen */
2096
2097 export_type *exp;
356c68ff 2098
765e60a9 2099 int i;
f051e1b0 2100 int hint = 0;
765e60a9
SC
2101 export_type **d_export_vec
2102 = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
2103
2104 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2105 {
2106 d_export_vec[i] = exp;
2107 }
2108
2109 process_duplicates (d_export_vec);
2110 fill_ordinals (d_export_vec);
2111
2112 /* Put back the list in the new order */
2113 d_exports = 0;
2114 for (i = d_nfuncs - 1; i >= 0; i--)
2115 {
2116 d_export_vec[i]->next = d_exports;
2117 d_exports = d_export_vec[i];
2118 }
f051e1b0
SC
2119
2120 /* Build list in alpha order */
2121 d_exports_lexically = (export_type **)xmalloc (sizeof(export_type *)*(d_nfuncs+1));
2122
2123 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2124 {
2125 d_exports_lexically[i] = exp;
2126 }
2127 d_exports_lexically[i] = 0;
2128
2129 qsort (d_exports_lexically, i, sizeof (export_type *), alphafunc);
2130
2131 /* Fill exp entries with their hint values */
2132
2133 for (i = 0; i < d_nfuncs; i++)
2134 {
2135 if (!d_exports_lexically[i]->noname || show_allnames)
2136 d_exports_lexically[i]->hint = hint++;
2137 }
2138
765e60a9
SC
2139}
2140
2141
2757dc25 2142
2757dc25 2143
2757dc25
SC
2144
2145
765e60a9
SC
2146/**********************************************************************/
2147
2148void
2149usage (file, status)
2150 FILE *file;
2151 int status;
2152{
6f2d3212 2153 fprintf (file, "Usage %s <options> <object-files>\n", program_name);
f88ebc68
SC
2154 fprintf (file, " --machine <machine>\n");
2155 fprintf (file, " --output-exp <outname> Generate export file.\n");
2156 fprintf (file, " --output-lib <outname> Generate input library.\n");
199f5217 2157 fprintf (file, " --add-indirect Add dll indirects to export file.\n");
f88ebc68
SC
2158 fprintf (file, " --dllname <name> Name of input dll to put into output lib.\n");
2159 fprintf (file, " --def <deffile> Name input .def file\n");
531f86b4 2160 fprintf (file, " --output-def <deffile> Name output .def file\n");
f88ebc68 2161 fprintf (file, " --base-file <basefile> Read linker generated base file\n");
356c68ff
SC
2162 fprintf (file, " --no-idata4 Don't generate idata$4 section\n");
2163 fprintf (file, " --no-idata5 Don't generate idata$5 section\n");
f88ebc68 2164 fprintf (file, " -v Verbose\n");
531f86b4 2165 fprintf (file, " -U Add underscores to .lib\n");
f88ebc68 2166 fprintf (file, " -k Kill @<n> from exported names\n");
356c68ff 2167 fprintf (file, " --as <name> Use <name> for assembler\n");
f88ebc68 2168 fprintf (file, " --nodelete Keep temp files.\n");
765e60a9
SC
2169 exit (status);
2170}
2171
356c68ff
SC
2172#define OPTION_NO_IDATA4 'x'
2173#define OPTION_NO_IDATA5 'c'
765e60a9
SC
2174static struct option long_options[] =
2175{
531f86b4
SC
2176 {"nodelete", no_argument, NULL, 'n'},
2177 {"dllname", required_argument, NULL, 'D'},
356c68ff
SC
2178 {"no-idata4", no_argument, NULL, OPTION_NO_IDATA4},
2179 {"no-idata5", no_argument, NULL, OPTION_NO_IDATA5},
2757dc25 2180 {"output-exp", required_argument, NULL, 'e'},
531f86b4 2181 {"output-def", required_argument, NULL, 'z'},
2757dc25 2182 {"output-lib", required_argument, NULL, 'l'},
765e60a9 2183 {"def", required_argument, NULL, 'd'},
531f86b4 2184 {"add-underscore", no_argument, NULL, 'U'},
00289839 2185 {"killat", no_argument, NULL, 'k'},
765e60a9
SC
2186 {"help", no_argument, NULL, 'h'},
2187 {"machine", required_argument, NULL, 'm'},
199f5217 2188 {"add-indirect", no_argument, NULL, 'a'},
6f2d3212 2189 {"base-file", required_argument, NULL, 'b'},
356c68ff
SC
2190 {"as", required_argument, NULL, 'S'},
2191 {0}
765e60a9
SC
2192};
2193
2757dc25
SC
2194
2195
765e60a9
SC
2196int
2197main (ac, av)
2198 int ac;
2199 char **av;
2200{
2201 int c;
f051e1b0 2202 int i;
765e60a9
SC
2203 char *firstarg = 0;
2204 program_name = av[0];
2205 oav = av;
6f2d3212 2206
356c68ff
SC
2207 while ((c = getopt_long (ac, av, "xcz:S:R:A:puaD:l:e:nkvbUh?m:yd:", long_options, 0))
2208 != EOF)
765e60a9
SC
2209 {
2210 switch (c)
2211 {
356c68ff
SC
2212 case OPTION_NO_IDATA4:
2213 no_idata4 = 1;
2214 break;
2215 case OPTION_NO_IDATA5:
2216 no_idata5 = 1;
2217 break;
2218 case 'S':
2219 as_name = optarg;
2220 break;
2221
531f86b4
SC
2222 /* ignored for compatibility */
2223 case 'u':
2224 break;
199f5217
DE
2225 case 'a':
2226 add_indirect = 1;
2227 break;
531f86b4 2228 case 'z':
20dec772 2229 output_def = fopen (optarg, FOPEN_WT);
531f86b4 2230 break;
2757dc25
SC
2231 case 'D':
2232 dll_name = optarg;
2233 break;
2234 case 'l':
2235 imp_name = optarg;
2236 break;
2237 case 'e':
2238 exp_name = optarg;
2239 break;
765e60a9
SC
2240 case 'h':
2241 case '?':
6f2d3212 2242 usage (stderr, 0);
765e60a9
SC
2243 break;
2244 case 'm':
2245 mname = optarg;
2246 break;
6f2d3212
SC
2247 case 'v':
2248 verbose = 1;
2249 break;
2757dc25 2250 case 'y':
765e60a9
SC
2251 yydebug = 1;
2252 break;
531f86b4
SC
2253 case 'U':
2254 add_underscore = 1;
6f2d3212 2255 break;
00289839
SC
2256 case 'k':
2257 killat = 1;
2258 break;
765e60a9
SC
2259 case 'd':
2260 def_file = optarg;
2261 break;
2757dc25 2262 case 'n':
f88ebc68 2263 dontdeltemps++;
2757dc25 2264 break;
6f2d3212 2265 case 'b':
20dec772 2266 base_file = fopen (optarg, FOPEN_RB);
6f2d3212
SC
2267 if (!base_file)
2268 {
2269 fprintf (stderr, "%s: Unable to open base-file %s\n",
2270 av[0],
2271 optarg);
2272 exit (1);
2273 }
2274 break;
765e60a9
SC
2275 default:
2276 usage (stderr, 1);
2277 }
2278 }
2279
2280
6f2d3212 2281 for (i = 0; mtable[i].type; i++)
765e60a9
SC
2282 {
2283 if (strcmp (mtable[i].type, mname) == 0)
2284 break;
2285 }
2286
6f2d3212 2287 if (!mtable[i].type)
765e60a9 2288 {
6f2d3212
SC
2289 fprintf (stderr, "Machine not supported\n");
2290 exit (1);
765e60a9
SC
2291 }
2292 machine = i;
2293
2294
2757dc25
SC
2295 if (!dll_name && exp_name)
2296 {
2297 char len = strlen (exp_name) + 5;
2298 dll_name = xmalloc (len);
2299 strcpy (dll_name, exp_name);
2300 strcat (dll_name, ".dll");
2301 }
2757dc25 2302
765e60a9
SC
2303 if (def_file)
2304 {
765e60a9
SC
2305 process_def_file (def_file);
2306 }
2307 while (optind < ac)
2308 {
2309 if (!firstarg)
2310 firstarg = av[optind];
2311 scan_obj_file (av[optind]);
2312 optind++;
2313 }
2314
765e60a9
SC
2315
2316 mangle_defs ();
6f2d3212 2317
2757dc25
SC
2318 if (exp_name)
2319 gen_exp_file ();
2320 if (imp_name)
531f86b4
SC
2321 {
2322 /* Make imp_name safe for use as a label. */
2323 char *p;
2324 imp_name_lab = strdup (imp_name);
2325 for (p = imp_name_lab; *p; *p++)
2326 {
2327 if (!isalpha (*p) && !isdigit (*p))
2328 *p = '_';
2329 }
356c68ff 2330 head_label = make_label("_head_", imp_name_lab);
531f86b4
SC
2331 gen_lib_file ();
2332 }
2333 if (output_def)
2334 gen_def_file ();
6f2d3212 2335
765e60a9
SC
2336 return 0;
2337}
This page took 0.17528 seconds and 4 git commands to generate.