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